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