• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 #include "state_tracker/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/u_format.h"
15 #include "util/u_inlines.h"
16 #include "util/u_memory.h"
17 
18 
19 struct 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 
30 static inline boolean
graw_util_create_window(struct graw_info * info,int width,int height,int num_cbufs,bool zstencil_buf)31 graw_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.nr_samples = 1;
81       resource_temp.bind = (PIPE_BIND_RENDER_TARGET |
82                             PIPE_BIND_DISPLAY_TARGET);
83       info->color_buf[i] = info->screen->resource_create(info->screen,
84                                                          &resource_temp);
85       if (info->color_buf[i] == NULL) {
86          debug_printf("graw: Failed to create color texture\n");
87          return FALSE;
88       }
89 
90       /* create color surface */
91       surface_temp.format = resource_temp.format;
92       surface_temp.u.tex.level = 0;
93       surface_temp.u.tex.first_layer = 0;
94       surface_temp.u.tex.last_layer = 0;
95       info->color_surf[i] = info->ctx->create_surface(info->ctx,
96                                                       info->color_buf[i],
97                                                       &surface_temp);
98       if (info->color_surf[i] == NULL) {
99          debug_printf("graw: Failed to get color surface\n");
100          return FALSE;
101       }
102    }
103 
104    /* create Z texture (XXX try other Z/S formats if needed) */
105    resource_temp.target = PIPE_TEXTURE_2D;
106    resource_temp.format = PIPE_FORMAT_S8_UINT_Z24_UNORM;
107    resource_temp.width0 = width;
108    resource_temp.height0 = height;
109    resource_temp.depth0 = 1;
110    resource_temp.array_size = 1;
111    resource_temp.last_level = 0;
112    resource_temp.nr_samples = 1;
113    resource_temp.bind = PIPE_BIND_DEPTH_STENCIL;
114    info->zs_buf = info->screen->resource_create(info->screen, &resource_temp);
115    if (!info->zs_buf) {
116       debug_printf("graw: Failed to create Z texture\n");
117       return FALSE;
118    }
119 
120    /* create z surface */
121    surface_temp.format = resource_temp.format;
122    surface_temp.u.tex.level = 0;
123    surface_temp.u.tex.first_layer = 0;
124    surface_temp.u.tex.last_layer = 0;
125    info->zs_surf = info->ctx->create_surface(info->ctx,
126                                              info->zs_buf,
127                                              &surface_temp);
128    if (info->zs_surf == NULL) {
129       debug_printf("graw: Failed to get Z surface\n");
130       return FALSE;
131    }
132 
133    {
134       struct pipe_framebuffer_state fb;
135       memset(&fb, 0, sizeof fb);
136       fb.nr_cbufs = num_cbufs;
137       fb.width = width;
138       fb.height = height;
139       for (i = 0; i < num_cbufs; i++)
140          fb.cbufs[i] = info->color_surf[i];
141       fb.zsbuf = info->zs_surf;
142       info->ctx->set_framebuffer_state(info->ctx, &fb);
143    }
144 
145    return TRUE;
146 }
147 
148 
149 static inline void
graw_util_default_state(struct graw_info * info,boolean depth_test)150 graw_util_default_state(struct graw_info *info, boolean depth_test)
151 {
152    {
153       struct pipe_blend_state blend;
154       void *handle;
155       memset(&blend, 0, sizeof blend);
156       blend.rt[0].colormask = PIPE_MASK_RGBA;
157       handle = info->ctx->create_blend_state(info->ctx, &blend);
158       info->ctx->bind_blend_state(info->ctx, handle);
159    }
160 
161    {
162       struct pipe_depth_stencil_alpha_state depthStencilAlpha;
163       void *handle;
164       memset(&depthStencilAlpha, 0, sizeof depthStencilAlpha);
165       depthStencilAlpha.depth.enabled = depth_test;
166       depthStencilAlpha.depth.writemask = 1;
167       depthStencilAlpha.depth.func = PIPE_FUNC_LESS;
168       handle = info->ctx->create_depth_stencil_alpha_state(info->ctx,
169                                                            &depthStencilAlpha);
170       info->ctx->bind_depth_stencil_alpha_state(info->ctx, handle);
171    }
172 
173    {
174       struct pipe_rasterizer_state rasterizer;
175       void *handle;
176       memset(&rasterizer, 0, sizeof rasterizer);
177       rasterizer.cull_face = PIPE_FACE_NONE;
178       rasterizer.half_pixel_center = 1;
179       rasterizer.bottom_edge_rule = 1;
180       handle = info->ctx->create_rasterizer_state(info->ctx, &rasterizer);
181       info->ctx->bind_rasterizer_state(info->ctx, handle);
182    }
183 }
184 
185 
186 static inline void
graw_util_viewport(struct graw_info * info,float x,float y,float width,float height,float zNear,float zFar)187 graw_util_viewport(struct graw_info *info,
188                    float x, float y,
189                    float width, float height,
190                    float zNear, float zFar)
191 {
192    float z = zNear;
193    float half_width = width / 2.0f;
194    float half_height = height / 2.0f;
195    float half_depth = (zFar - zNear) / 2.0f;
196    struct pipe_viewport_state vp;
197 
198    vp.scale[0] = half_width;
199    vp.scale[1] = half_height;
200    vp.scale[2] = half_depth;
201 
202    vp.translate[0] = half_width + x;
203    vp.translate[1] = half_height + y;
204    vp.translate[2] = half_depth + z;
205 
206    info->ctx->set_viewport_states(info->ctx, 0, 1, &vp);
207 }
208 
209 
210 static inline void
graw_util_flush_front(const struct graw_info * info)211 graw_util_flush_front(const struct graw_info *info)
212 {
213    info->screen->flush_frontbuffer(info->screen, info->color_buf[0],
214                                    0, 0, info->window, NULL);
215 }
216 
217 
218 static inline struct pipe_resource *
graw_util_create_tex2d(const struct graw_info * info,int width,int height,enum pipe_format format,const void * data)219 graw_util_create_tex2d(const struct graw_info *info,
220                        int width, int height, enum pipe_format format,
221                        const void *data)
222 {
223    const int row_stride = width * util_format_get_blocksize(format);
224    const int image_bytes = row_stride * height;
225    struct pipe_resource temp, *tex;
226    struct pipe_box box;
227 
228    memset(&temp, 0, sizeof(temp));
229    temp.target = PIPE_TEXTURE_2D;
230    temp.format = format;
231    temp.width0 = width;
232    temp.height0 = height;
233    temp.depth0 = 1;
234    temp.last_level = 0;
235    temp.array_size = 1;
236    temp.nr_samples = 1;
237    temp.bind = PIPE_BIND_SAMPLER_VIEW;
238 
239    tex = info->screen->resource_create(info->screen, &temp);
240    if (!tex) {
241       debug_printf("graw: failed to create texture\n");
242       return NULL;
243    }
244 
245    u_box_2d(0, 0, width, height, &box);
246 
247    info->ctx->texture_subdata(info->ctx,
248                               tex,
249                               0,
250                               PIPE_TRANSFER_WRITE,
251                               &box,
252                               data,
253                               row_stride,
254                               image_bytes);
255 
256    /* Possibly read back & compare against original data:
257     */
258 #if 0
259    {
260       struct pipe_transfer *t;
261       uint32_t *ptr;
262       t = pipe_transfer_map(info->ctx, samptex,
263                             0, 0, /* level, layer */
264                             PIPE_TRANSFER_READ,
265                             0, 0, SIZE, SIZE); /* x, y, width, height */
266 
267       ptr = info->ctx->transfer_map(info->ctx, t);
268 
269       if (memcmp(ptr, tex2d, sizeof tex2d) != 0) {
270          assert(0);
271          exit(9);
272       }
273 
274       info->ctx->transfer_unmap(info->ctx, t);
275 
276       info->ctx->transfer_destroy(info->ctx, t);
277    }
278 #endif
279 
280    return tex;
281 }
282 
283 
284 static inline void *
graw_util_create_simple_sampler(const struct graw_info * info,unsigned wrap_mode,unsigned img_filter)285 graw_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 
310 static inline struct pipe_sampler_view *
graw_util_create_simple_sampler_view(const struct graw_info * info,struct pipe_resource * texture)311 graw_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