• 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_draw_quad.h"
13 #include "util/u_format.h"
14 #include "util/u_inlines.h"
15 #include "util/u_memory.h"
16 
17 
18 struct graw_info
19 {
20    struct pipe_screen *screen;
21    struct pipe_context *ctx;
22    struct pipe_resource *color_buf[PIPE_MAX_COLOR_BUFS], *zs_buf;
23    struct pipe_surface *color_surf[PIPE_MAX_COLOR_BUFS], *zs_surf;
24    void *window;
25 };
26 
27 
28 
29 static INLINE boolean
graw_util_create_window(struct graw_info * info,int width,int height,int num_cbufs,bool zstencil_buf)30 graw_util_create_window(struct graw_info *info,
31                         int width, int height,
32                         int num_cbufs, bool zstencil_buf)
33 {
34    static const enum pipe_format formats[] = {
35       PIPE_FORMAT_R8G8B8A8_UNORM,
36       PIPE_FORMAT_B8G8R8A8_UNORM,
37       PIPE_FORMAT_NONE
38    };
39    enum pipe_format format;
40    struct pipe_resource resource_temp;
41    struct pipe_surface surface_temp;
42    int i;
43 
44    memset(info, 0, sizeof(*info));
45 
46    /* It's hard to say whether window or screen should be created
47     * first.  Different environments would prefer one or the other.
48     *
49     * Also, no easy way of querying supported formats if the screen
50     * cannot be created first.
51     */
52    for (i = 0; info->window == NULL && formats[i] != PIPE_FORMAT_NONE; i++) {
53       info->screen = graw_create_window_and_screen(0, 0, width, height,
54                                                    formats[i],
55                                                    &info->window);
56       format = formats[i];
57    }
58    if (!info->screen || !info->window) {
59       debug_printf("graw: Failed to create screen/window\n");
60       return FALSE;
61    }
62 
63    info->ctx = info->screen->context_create(info->screen, NULL);
64    if (info->ctx == NULL) {
65       debug_printf("graw: Failed to create context\n");
66       return FALSE;
67    }
68 
69    for (i = 0; i < num_cbufs; i++) {
70       /* create color texture */
71       resource_temp.target = PIPE_TEXTURE_2D;
72       resource_temp.format = format;
73       resource_temp.width0 = width;
74       resource_temp.height0 = height;
75       resource_temp.depth0 = 1;
76       resource_temp.array_size = 1;
77       resource_temp.last_level = 0;
78       resource_temp.nr_samples = 1;
79       resource_temp.bind = (PIPE_BIND_RENDER_TARGET |
80                             PIPE_BIND_DISPLAY_TARGET);
81       info->color_buf[i] = info->screen->resource_create(info->screen,
82                                                          &resource_temp);
83       if (info->color_buf[i] == NULL) {
84          debug_printf("graw: Failed to create color texture\n");
85          return FALSE;
86       }
87 
88       /* create color surface */
89       surface_temp.format = resource_temp.format;
90       surface_temp.usage = PIPE_BIND_RENDER_TARGET;
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.nr_samples = 1;
112    resource_temp.bind = PIPE_BIND_DEPTH_STENCIL;
113    info->zs_buf = info->screen->resource_create(info->screen, &resource_temp);
114    if (!info->zs_buf) {
115       debug_printf("graw: Failed to create Z texture\n");
116       return FALSE;
117    }
118 
119    /* create z surface */
120    surface_temp.format = resource_temp.format;
121    surface_temp.usage = PIPE_BIND_DEPTH_STENCIL;
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.gl_rasterization_rules = 1;
179       handle = info->ctx->create_rasterizer_state(info->ctx, &rasterizer);
180       info->ctx->bind_rasterizer_state(info->ctx, handle);
181    }
182 }
183 
184 
185 static INLINE void
graw_util_viewport(struct graw_info * info,float x,float y,float width,float height,float near,float far)186 graw_util_viewport(struct graw_info *info,
187                    float x, float y,
188                    float width, float height,
189                    float near, float far)
190 {
191    float z = near;
192    float half_width = width / 2.0f;
193    float half_height = height / 2.0f;
194    float half_depth = (far - near) / 2.0f;
195    struct pipe_viewport_state vp;
196 
197    vp.scale[0] = half_width;
198    vp.scale[1] = half_height;
199    vp.scale[2] = half_depth;
200    vp.scale[3] = 1.0f;
201 
202    vp.translate[0] = half_width + x;
203    vp.translate[1] = half_height + y;
204    vp.translate[2] = half_depth + z;
205    vp.translate[3] = 0.0f;
206 
207    info->ctx->set_viewport_state(info->ctx, &vp);
208 }
209 
210 
211 static INLINE void
graw_util_flush_front(const struct graw_info * info)212 graw_util_flush_front(const struct graw_info *info)
213 {
214    info->screen->flush_frontbuffer(info->screen, info->color_buf[0],
215                                    0, 0, info->window);
216 }
217 
218 
219 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)220 graw_util_create_tex2d(const struct graw_info *info,
221                        int width, int height, enum pipe_format format,
222                        const void *data)
223 {
224    const int row_stride = width * util_format_get_blocksize(format);
225    const int image_bytes = row_stride * height;
226    struct pipe_resource temp, *tex;
227    struct pipe_box box;
228 
229    temp.target = PIPE_TEXTURE_2D;
230    temp.format = PIPE_FORMAT_B8G8R8A8_UNORM;
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->transfer_inline_write(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_get_transfer(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_RED;
321    sv_temp.swizzle_g = PIPE_SWIZZLE_GREEN;
322    sv_temp.swizzle_b = PIPE_SWIZZLE_BLUE;
323    sv_temp.swizzle_a = PIPE_SWIZZLE_ALPHA;
324 
325    sv = info->ctx->create_sampler_view(info->ctx, texture, &sv_temp);
326 
327    return sv;
328 }
329 
330