graw_util.h revision 7ec681f3
1 2#include "frontend/graw.h" 3 4#include "pipe/p_context.h" 5#include "pipe/p_defines.h" 6#include "pipe/p_screen.h" 7#include "pipe/p_shader_tokens.h" 8#include "pipe/p_state.h" 9 10#include "util/u_box.h" 11#include "util/u_debug.h" 12#include "util/u_debug_image.h" 13#include "util/u_draw_quad.h" 14#include "util/format/u_format.h" 15#include "util/u_inlines.h" 16#include "util/u_memory.h" 17 18 19struct graw_info 20{ 21 struct pipe_screen *screen; 22 struct pipe_context *ctx; 23 struct pipe_resource *color_buf[PIPE_MAX_COLOR_BUFS], *zs_buf; 24 struct pipe_surface *color_surf[PIPE_MAX_COLOR_BUFS], *zs_surf; 25 void *window; 26}; 27 28 29 30static inline boolean 31graw_util_create_window(struct graw_info *info, 32 int width, int height, 33 int num_cbufs, bool zstencil_buf) 34{ 35 static const enum pipe_format formats[] = { 36 PIPE_FORMAT_RGBA8888_UNORM, 37 PIPE_FORMAT_BGRA8888_UNORM, 38 PIPE_FORMAT_NONE 39 }; 40 enum pipe_format format; 41 struct pipe_resource resource_temp; 42 struct pipe_surface surface_temp; 43 int i; 44 45 memset(info, 0, sizeof(*info)); 46 memset(&resource_temp, 0, sizeof(resource_temp)); 47 48 /* It's hard to say whether window or screen should be created 49 * first. Different environments would prefer one or the other. 50 * 51 * Also, no easy way of querying supported formats if the screen 52 * cannot be created first. 53 */ 54 for (i = 0; info->window == NULL && formats[i] != PIPE_FORMAT_NONE; i++) { 55 info->screen = graw_create_window_and_screen(0, 0, width, height, 56 formats[i], 57 &info->window); 58 format = formats[i]; 59 } 60 if (!info->screen || !info->window) { 61 debug_printf("graw: Failed to create screen/window\n"); 62 return FALSE; 63 } 64 65 info->ctx = info->screen->context_create(info->screen, NULL, 0); 66 if (info->ctx == NULL) { 67 debug_printf("graw: Failed to create context\n"); 68 return FALSE; 69 } 70 71 for (i = 0; i < num_cbufs; i++) { 72 /* create color texture */ 73 resource_temp.target = PIPE_TEXTURE_2D; 74 resource_temp.format = format; 75 resource_temp.width0 = width; 76 resource_temp.height0 = height; 77 resource_temp.depth0 = 1; 78 resource_temp.array_size = 1; 79 resource_temp.last_level = 0; 80 resource_temp.bind = (PIPE_BIND_RENDER_TARGET | 81 PIPE_BIND_DISPLAY_TARGET); 82 info->color_buf[i] = info->screen->resource_create(info->screen, 83 &resource_temp); 84 if (info->color_buf[i] == NULL) { 85 debug_printf("graw: Failed to create color texture\n"); 86 return FALSE; 87 } 88 89 /* create color surface */ 90 surface_temp.format = resource_temp.format; 91 surface_temp.u.tex.level = 0; 92 surface_temp.u.tex.first_layer = 0; 93 surface_temp.u.tex.last_layer = 0; 94 info->color_surf[i] = info->ctx->create_surface(info->ctx, 95 info->color_buf[i], 96 &surface_temp); 97 if (info->color_surf[i] == NULL) { 98 debug_printf("graw: Failed to get color surface\n"); 99 return FALSE; 100 } 101 } 102 103 /* create Z texture (XXX try other Z/S formats if needed) */ 104 resource_temp.target = PIPE_TEXTURE_2D; 105 resource_temp.format = PIPE_FORMAT_S8_UINT_Z24_UNORM; 106 resource_temp.width0 = width; 107 resource_temp.height0 = height; 108 resource_temp.depth0 = 1; 109 resource_temp.array_size = 1; 110 resource_temp.last_level = 0; 111 resource_temp.bind = PIPE_BIND_DEPTH_STENCIL; 112 info->zs_buf = info->screen->resource_create(info->screen, &resource_temp); 113 if (!info->zs_buf) { 114 debug_printf("graw: Failed to create Z texture\n"); 115 return FALSE; 116 } 117 118 /* create z surface */ 119 surface_temp.format = resource_temp.format; 120 surface_temp.u.tex.level = 0; 121 surface_temp.u.tex.first_layer = 0; 122 surface_temp.u.tex.last_layer = 0; 123 info->zs_surf = info->ctx->create_surface(info->ctx, 124 info->zs_buf, 125 &surface_temp); 126 if (info->zs_surf == NULL) { 127 debug_printf("graw: Failed to get Z surface\n"); 128 return FALSE; 129 } 130 131 { 132 struct pipe_framebuffer_state fb; 133 memset(&fb, 0, sizeof fb); 134 fb.nr_cbufs = num_cbufs; 135 fb.width = width; 136 fb.height = height; 137 for (i = 0; i < num_cbufs; i++) 138 fb.cbufs[i] = info->color_surf[i]; 139 fb.zsbuf = info->zs_surf; 140 info->ctx->set_framebuffer_state(info->ctx, &fb); 141 } 142 143 return TRUE; 144} 145 146 147static inline void 148graw_util_default_state(struct graw_info *info, boolean depth_test) 149{ 150 { 151 struct pipe_blend_state blend; 152 void *handle; 153 memset(&blend, 0, sizeof blend); 154 blend.rt[0].colormask = PIPE_MASK_RGBA; 155 handle = info->ctx->create_blend_state(info->ctx, &blend); 156 info->ctx->bind_blend_state(info->ctx, handle); 157 } 158 159 { 160 struct pipe_depth_stencil_alpha_state depthStencilAlpha; 161 void *handle; 162 memset(&depthStencilAlpha, 0, sizeof depthStencilAlpha); 163 depthStencilAlpha.depth_enabled = depth_test; 164 depthStencilAlpha.depth_writemask = 1; 165 depthStencilAlpha.depth_func = PIPE_FUNC_LESS; 166 handle = info->ctx->create_depth_stencil_alpha_state(info->ctx, 167 &depthStencilAlpha); 168 info->ctx->bind_depth_stencil_alpha_state(info->ctx, handle); 169 } 170 171 { 172 struct pipe_rasterizer_state rasterizer; 173 void *handle; 174 memset(&rasterizer, 0, sizeof rasterizer); 175 rasterizer.cull_face = PIPE_FACE_NONE; 176 rasterizer.half_pixel_center = 1; 177 rasterizer.bottom_edge_rule = 1; 178 handle = info->ctx->create_rasterizer_state(info->ctx, &rasterizer); 179 info->ctx->bind_rasterizer_state(info->ctx, handle); 180 } 181} 182 183 184static inline void 185graw_util_viewport(struct graw_info *info, 186 float x, float y, 187 float width, float height, 188 float zNear, float zFar) 189{ 190 float z = zNear; 191 float half_width = width / 2.0f; 192 float half_height = height / 2.0f; 193 float half_depth = (zFar - zNear) / 2.0f; 194 struct pipe_viewport_state vp; 195 196 vp.scale[0] = half_width; 197 vp.scale[1] = half_height; 198 vp.scale[2] = half_depth; 199 200 vp.translate[0] = half_width + x; 201 vp.translate[1] = half_height + y; 202 vp.translate[2] = half_depth + z; 203 204 vp.swizzle_x = PIPE_VIEWPORT_SWIZZLE_POSITIVE_X; 205 vp.swizzle_y = PIPE_VIEWPORT_SWIZZLE_POSITIVE_Y; 206 vp.swizzle_z = PIPE_VIEWPORT_SWIZZLE_POSITIVE_Z; 207 vp.swizzle_w = PIPE_VIEWPORT_SWIZZLE_POSITIVE_W; 208 209 info->ctx->set_viewport_states(info->ctx, 0, 1, &vp); 210} 211 212 213static inline void 214graw_util_flush_front(const struct graw_info *info) 215{ 216 info->screen->flush_frontbuffer(info->screen, info->ctx, info->color_buf[0], 217 0, 0, info->window, NULL); 218} 219 220 221static inline struct pipe_resource * 222graw_util_create_tex2d(const struct graw_info *info, 223 int width, int height, enum pipe_format format, 224 const void *data) 225{ 226 const int row_stride = width * util_format_get_blocksize(format); 227 const int image_bytes = row_stride * height; 228 struct pipe_resource temp, *tex; 229 struct pipe_box box; 230 231 memset(&temp, 0, sizeof(temp)); 232 temp.target = PIPE_TEXTURE_2D; 233 temp.format = format; 234 temp.width0 = width; 235 temp.height0 = height; 236 temp.depth0 = 1; 237 temp.last_level = 0; 238 temp.array_size = 1; 239 temp.bind = PIPE_BIND_SAMPLER_VIEW; 240 241 tex = info->screen->resource_create(info->screen, &temp); 242 if (!tex) { 243 debug_printf("graw: failed to create texture\n"); 244 return NULL; 245 } 246 247 u_box_2d(0, 0, width, height, &box); 248 249 info->ctx->texture_subdata(info->ctx, 250 tex, 251 0, 252 PIPE_MAP_WRITE, 253 &box, 254 data, 255 row_stride, 256 image_bytes); 257 258 /* Possibly read back & compare against original data: 259 */ 260#if 0 261 { 262 struct pipe_transfer *t; 263 uint32_t *ptr; 264 t = pipe_texture_map(info->ctx, samptex, 265 0, 0, /* level, layer */ 266 PIPE_MAP_READ, 267 0, 0, SIZE, SIZE); /* x, y, width, height */ 268 269 ptr = info->ctx->texture_map(info->ctx, t); 270 271 if (memcmp(ptr, tex2d, sizeof tex2d) != 0) { 272 assert(0); 273 exit(9); 274 } 275 276 info->ctx->texture_unmap(info->ctx, t); 277 } 278#endif 279 280 return tex; 281} 282 283 284static inline void * 285graw_util_create_simple_sampler(const struct graw_info *info, 286 unsigned wrap_mode, 287 unsigned img_filter) 288{ 289 struct pipe_sampler_state sampler_desc; 290 void *sampler; 291 292 memset(&sampler_desc, 0, sizeof sampler_desc); 293 sampler_desc.wrap_s = 294 sampler_desc.wrap_t = 295 sampler_desc.wrap_r = wrap_mode; 296 sampler_desc.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; 297 sampler_desc.min_img_filter = 298 sampler_desc.mag_img_filter = img_filter; 299 sampler_desc.compare_mode = PIPE_TEX_COMPARE_NONE; 300 sampler_desc.compare_func = 0; 301 sampler_desc.normalized_coords = 1; 302 sampler_desc.max_anisotropy = 0; 303 304 sampler = info->ctx->create_sampler_state(info->ctx, &sampler_desc); 305 306 return sampler; 307} 308 309 310static inline struct pipe_sampler_view * 311graw_util_create_simple_sampler_view(const struct graw_info *info, 312 struct pipe_resource *texture) 313{ 314 struct pipe_sampler_view sv_temp; 315 struct pipe_sampler_view *sv; 316 317 memset(&sv_temp, 0, sizeof(sv_temp)); 318 sv_temp.format = texture->format; 319 sv_temp.texture = texture; 320 sv_temp.swizzle_r = PIPE_SWIZZLE_X; 321 sv_temp.swizzle_g = PIPE_SWIZZLE_Y; 322 sv_temp.swizzle_b = PIPE_SWIZZLE_Z; 323 sv_temp.swizzle_a = PIPE_SWIZZLE_W; 324 325 sv = info->ctx->create_sampler_view(info->ctx, texture, &sv_temp); 326 327 return sv; 328} 329 330