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