• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Display a cleared blue window.  This demo has no dependencies on
2  * any utility code, just the graw interface and gallium.
3  */
4 
5 #include "frontend/graw.h"
6 #include "pipe/p_screen.h"
7 #include "pipe/p_context.h"
8 #include "pipe/p_shader_tokens.h"
9 #include "pipe/p_state.h"
10 #include "pipe/p_defines.h"
11 #include <stdio.h>              /* for fread(), etc */
12 
13 #include "util/u_inlines.h"
14 #include "util/u_memory.h"      /* Offset() */
15 #include "util/u_draw_quad.h"
16 #include "util/u_box.h"
17 
18 static const char *filename = NULL;
19 unsigned show_fps = 0;
20 
21 
usage(char * name)22 static void usage(char *name)
23 {
24    fprintf(stderr, "usage: %s [ options ] shader_filename\n", name);
25 #ifndef _WIN32
26    fprintf(stderr, "\n" );
27    fprintf(stderr, "options:\n");
28    fprintf(stderr, "    -fps  show frames per second\n");
29 #endif
30 }
31 
32 
33 enum pipe_format formats[] = {
34    PIPE_FORMAT_RGBA8888_UNORM,
35    PIPE_FORMAT_BGRA8888_UNORM,
36    PIPE_FORMAT_NONE
37 };
38 
39 static const int WIDTH = 250;
40 static const int HEIGHT = 250;
41 
42 static struct pipe_screen *screen = NULL;
43 static struct pipe_context *ctx = NULL;
44 static struct pipe_resource *rttex = NULL;
45 static struct pipe_surface *surf = NULL;
46 static struct pipe_sampler_view *sv = NULL;
47 static void *sampler = NULL;
48 static void *window = NULL;
49 static struct pipe_resource *samptex = NULL;
50 
51 struct vertex {
52    float position[4];
53    float color[4];
54    float texcoord[4];
55 };
56 
57 /* Vertex data matches progs/fp/fp-tri.c, but flipped in Y dimension
58  * so that the final images are the same.
59  */
60 static struct vertex vertices[] =
61 {
62    { { 0.9, 0.9, 0.0, 1.0 },
63      { 0, 0, 1, 1 },
64      { 1, 1, 0, 1 } },
65 
66    { { 0.9,  -0.9, 0.0, 1.0 },
67      { 1, 0, 0, 1 },
68      { 1, -1, 0, 1 } },
69 
70    { {-0.9,  0.0, 0.0, 1.0 },
71      { 0, 1, 0, 1 },
72      { -1, 0, 0, 1 } },
73 };
74 
75 static float constants1[] =
76 {  0.4, 0, 0,  1,
77    1,   1, 1,  1,
78    2,   2, 2,  2,
79    4,   8, 16, 32,
80 
81    3,  0, 0, 0,
82    0, .5, 0, 0,
83    1,  0, 0, 1,
84    0,  0, 0, 1,
85 
86    1, 0, 0, 0.5,
87    0, 1, 0, 0.5,
88    0, 0, 1, 0,
89    0, 0, 0, 1,
90 };
91 
92 
93 static float constants2[] =
94 {  1, 0, 0,  1,
95    0, 1, 0,  1,
96    0, 0, 1,  1,
97    0, 0, 0,  0,
98 
99    1,  1, 0, 1,
100    1, .5, 0, 1,
101    1,  0, 0, 1,
102    0,  0, 0, 1,
103 
104    1, 0, 0, 0.5,
105    0, 1, 0, 0.5,
106    0, 0, 1, 0,
107    0, 0, 0, 1,
108 };
109 
init_fs_constbuf(void)110 static void init_fs_constbuf( void )
111 {
112    struct pipe_constant_buffer cb1;
113    struct pipe_constant_buffer cb2;
114 
115    memset(&cb1, 0, sizeof cb1);
116    cb1.buffer_size = sizeof constants1;
117    cb1.user_buffer = constants1;
118 
119    ctx->set_constant_buffer(ctx,
120                             PIPE_SHADER_FRAGMENT, 0, false,
121                             &cb1);
122 
123    memset(&cb2, 0, sizeof cb2);
124    cb2.buffer_size = sizeof constants2;
125    cb2.user_buffer = constants2;
126 
127    ctx->set_constant_buffer(ctx,
128                             PIPE_SHADER_FRAGMENT, 1, false,
129                             &cb2);
130 }
131 
132 
set_viewport(float x,float y,float width,float height,float zNear,float zFar)133 static void set_viewport( float x, float y,
134                           float width, float height,
135                           float zNear, float zFar)
136 {
137    float z = zFar;
138    float half_width = (float)width / 2.0f;
139    float half_height = (float)height / 2.0f;
140    float half_depth = ((float)zFar - (float)zNear) / 2.0f;
141    struct pipe_viewport_state vp;
142 
143    vp.scale[0] = half_width;
144    vp.scale[1] = half_height;
145    vp.scale[2] = half_depth;
146 
147    vp.translate[0] = half_width + x;
148    vp.translate[1] = half_height + y;
149    vp.translate[2] = half_depth + z;
150 
151    vp.swizzle_x = PIPE_VIEWPORT_SWIZZLE_POSITIVE_X;
152    vp.swizzle_y = PIPE_VIEWPORT_SWIZZLE_POSITIVE_Y;
153    vp.swizzle_z = PIPE_VIEWPORT_SWIZZLE_POSITIVE_Z;
154    vp.swizzle_w = PIPE_VIEWPORT_SWIZZLE_POSITIVE_W;
155 
156    ctx->set_viewport_states( ctx, 0, 1, &vp );
157 }
158 
set_vertices(void)159 static void set_vertices( void )
160 {
161    struct pipe_vertex_element ve[3];
162    struct pipe_vertex_buffer vbuf;
163    void *handle;
164 
165    memset(ve, 0, sizeof ve);
166 
167    ve[0].src_offset = Offset(struct vertex, position);
168    ve[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
169    ve[1].src_offset = Offset(struct vertex, color);
170    ve[1].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
171    ve[2].src_offset = Offset(struct vertex, texcoord);
172    ve[2].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
173 
174    handle = ctx->create_vertex_elements_state(ctx, 3, ve);
175    ctx->bind_vertex_elements_state(ctx, handle);
176 
177    memset(&vbuf, 0, sizeof vbuf);
178 
179    vbuf.stride = sizeof( struct vertex );
180    vbuf.buffer_offset = 0;
181    vbuf.buffer.resource = pipe_buffer_create_with_data(ctx,
182                                               PIPE_BIND_VERTEX_BUFFER,
183                                               PIPE_USAGE_DEFAULT,
184                                               sizeof(vertices),
185                                               vertices);
186 
187    ctx->set_vertex_buffers(ctx, 0, 1, 0, false, &vbuf);
188 }
189 
set_vertex_shader(void)190 static void set_vertex_shader( void )
191 {
192    void *handle;
193    const char *text =
194       "VERT\n"
195       "DCL IN[0]\n"
196       "DCL IN[1]\n"
197       "DCL IN[2]\n"
198       "DCL OUT[0], POSITION\n"
199       "DCL OUT[1], COLOR[0]\n"
200       "DCL OUT[2], GENERIC[0]\n"
201       "  MOV OUT[0], IN[0]\n"
202       "  MOV OUT[1], IN[1]\n"
203       "  MOV OUT[2], IN[2]\n"
204       "  END\n";
205 
206    handle = graw_parse_vertex_shader(ctx, text);
207    ctx->bind_vs_state(ctx, handle);
208 }
209 
set_fragment_shader(const char * filename)210 static void set_fragment_shader( const char *filename )
211 {
212    FILE *f;
213    char buf[50000];
214    void *handle;
215    int sz;
216 
217    if ((f = fopen(filename, "r")) == NULL) {
218       fprintf(stderr, "Couldn't open %s\n", filename);
219       exit(1);
220    }
221 
222    sz = fread(buf, 1, sizeof(buf), f);
223    if (!feof(f)) {
224       printf("file too long\n");
225       exit(1);
226    }
227    printf("%.*s\n", sz, buf);
228    buf[sz] = 0;
229 
230    handle = graw_parse_fragment_shader(ctx, buf);
231    ctx->bind_fs_state(ctx, handle);
232    fclose(f);
233 }
234 
235 
draw(void)236 static void draw( void )
237 {
238    union pipe_color_union clear_color = { {.1,.3,.5,0} };
239 
240    ctx->clear(ctx, PIPE_CLEAR_COLOR, NULL, &clear_color, 0, 0);
241    util_draw_arrays(ctx, PIPE_PRIM_TRIANGLES, 0, 3);
242    ctx->flush(ctx, NULL, 0);
243 
244    graw_save_surface_to_file(ctx, surf, NULL);
245 
246    screen->flush_frontbuffer(screen, ctx, rttex, 0, 0, window, NULL);
247 }
248 
249 #define SIZE 16
250 
init_tex(void)251 static void init_tex( void )
252 {
253    struct pipe_sampler_view sv_template;
254    struct pipe_sampler_state sampler_desc;
255    struct pipe_resource templat;
256    struct pipe_box box;
257    ubyte tex2d[SIZE][SIZE][4];
258    int s, t;
259 
260 #if (SIZE != 2)
261    for (s = 0; s < SIZE; s++) {
262       for (t = 0; t < SIZE; t++) {
263          if (0) {
264             int x = (s ^ t) & 1;
265 	    tex2d[t][s][0] = (x) ? 0 : 63;
266 	    tex2d[t][s][1] = (x) ? 0 : 128;
267 	    tex2d[t][s][2] = 0;
268 	    tex2d[t][s][3] = 0xff;
269          }
270          else {
271             int x = ((s ^ t) >> 2) & 1;
272 	    tex2d[t][s][0] = s*255/(SIZE-1);
273 	    tex2d[t][s][1] = t*255/(SIZE-1);
274 	    tex2d[t][s][2] = (x) ? 0 : 128;
275 	    tex2d[t][s][3] = 0xff;
276          }
277       }
278    }
279 #else
280    tex2d[0][0][0] = 0;
281    tex2d[0][0][1] = 255;
282    tex2d[0][0][2] = 255;
283    tex2d[0][0][3] = 0;
284 
285    tex2d[0][1][0] = 0;
286    tex2d[0][1][1] = 0;
287    tex2d[0][1][2] = 255;
288    tex2d[0][1][3] = 255;
289 
290    tex2d[1][0][0] = 255;
291    tex2d[1][0][1] = 255;
292    tex2d[1][0][2] = 0;
293    tex2d[1][0][3] = 255;
294 
295    tex2d[1][1][0] = 255;
296    tex2d[1][1][1] = 0;
297    tex2d[1][1][2] = 0;
298    tex2d[1][1][3] = 255;
299 #endif
300 
301    memset(&templat, 0, sizeof(templat));
302    templat.target = PIPE_TEXTURE_2D;
303    templat.format = PIPE_FORMAT_B8G8R8A8_UNORM;
304    templat.width0 = SIZE;
305    templat.height0 = SIZE;
306    templat.depth0 = 1;
307    templat.array_size = 1;
308    templat.last_level = 0;
309    templat.bind = PIPE_BIND_SAMPLER_VIEW;
310 
311 
312    samptex = screen->resource_create(screen,
313                                  &templat);
314    if (samptex == NULL)
315       exit(4);
316 
317    u_box_2d(0,0,SIZE,SIZE, &box);
318 
319    ctx->texture_subdata(ctx,
320                         samptex,
321                         0,
322                         PIPE_MAP_WRITE,
323                         &box,
324                         tex2d,
325                         sizeof tex2d[0],
326                         sizeof tex2d);
327 
328    /* Possibly read back & compare against original data:
329     */
330    if (0)
331    {
332       struct pipe_transfer *t;
333       uint32_t *ptr;
334       ptr = pipe_texture_map(ctx, samptex,
335                               0, 0, /* level, layer */
336                               PIPE_MAP_READ,
337                               0, 0, SIZE, SIZE, &t); /* x, y, width, height */
338 
339       if (memcmp(ptr, tex2d, sizeof tex2d) != 0) {
340          assert(0);
341          exit(9);
342       }
343 
344       ctx->texture_unmap(ctx, t);
345    }
346 
347    memset(&sv_template, 0, sizeof sv_template);
348    sv_template.format = samptex->format;
349    sv_template.texture = samptex;
350    sv_template.swizzle_r = 0;
351    sv_template.swizzle_g = 1;
352    sv_template.swizzle_b = 2;
353    sv_template.swizzle_a = 3;
354    sv = ctx->create_sampler_view(ctx, samptex, &sv_template);
355    if (sv == NULL)
356       exit(5);
357 
358    ctx->set_sampler_views(ctx, PIPE_SHADER_FRAGMENT, 0, 1, 0, false, &sv);
359 
360 
361    memset(&sampler_desc, 0, sizeof sampler_desc);
362    sampler_desc.wrap_s = PIPE_TEX_WRAP_REPEAT;
363    sampler_desc.wrap_t = PIPE_TEX_WRAP_REPEAT;
364    sampler_desc.wrap_r = PIPE_TEX_WRAP_REPEAT;
365    sampler_desc.min_img_filter = PIPE_TEX_FILTER_NEAREST;
366    sampler_desc.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
367    sampler_desc.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
368    sampler_desc.compare_mode = PIPE_TEX_COMPARE_NONE;
369    sampler_desc.compare_func = 0;
370    sampler_desc.normalized_coords = 1;
371    sampler_desc.max_anisotropy = 0;
372 
373    sampler = ctx->create_sampler_state(ctx, &sampler_desc);
374    if (sampler == NULL)
375       exit(6);
376 
377    ctx->bind_sampler_states(ctx, PIPE_SHADER_FRAGMENT, 0, 1, &sampler);
378 
379 }
380 
init(void)381 static void init( void )
382 {
383    struct pipe_framebuffer_state fb;
384    struct pipe_resource templat;
385    struct pipe_surface surf_tmpl;
386    int i;
387 
388    /* It's hard to say whether window or screen should be created
389     * first.  Different environments would prefer one or the other.
390     *
391     * Also, no easy way of querying supported formats if the screen
392     * cannot be created first.
393     */
394    for (i = 0; formats[i] != PIPE_FORMAT_NONE; i++) {
395       screen = graw_create_window_and_screen(0, 0, 300, 300,
396                                              formats[i],
397                                              &window);
398       if (window && screen)
399          break;
400    }
401    if (!screen || !window) {
402       fprintf(stderr, "Unable to create window\n");
403       exit(1);
404    }
405 
406    ctx = screen->context_create(screen, NULL, 0);
407    if (ctx == NULL)
408       exit(3);
409 
410    memset(&templat, 0, sizeof(templat));
411    templat.target = PIPE_TEXTURE_2D;
412    templat.format = formats[i];
413    templat.width0 = WIDTH;
414    templat.height0 = HEIGHT;
415    templat.depth0 = 1;
416    templat.array_size = 1;
417    templat.last_level = 0;
418    templat.bind = (PIPE_BIND_RENDER_TARGET |
419                    PIPE_BIND_DISPLAY_TARGET);
420 
421    rttex = screen->resource_create(screen,
422                                  &templat);
423    if (rttex == NULL)
424       exit(4);
425 
426    surf_tmpl.format = templat.format;
427    surf_tmpl.u.tex.level = 0;
428    surf_tmpl.u.tex.first_layer = 0;
429    surf_tmpl.u.tex.last_layer = 0;
430    surf = ctx->create_surface(ctx, rttex, &surf_tmpl);
431    if (surf == NULL)
432       exit(5);
433 
434    memset(&fb, 0, sizeof fb);
435    fb.nr_cbufs = 1;
436    fb.width = WIDTH;
437    fb.height = HEIGHT;
438    fb.cbufs[0] = surf;
439 
440    ctx->set_framebuffer_state(ctx, &fb);
441 
442    {
443       struct pipe_blend_state blend;
444       void *handle;
445       memset(&blend, 0, sizeof blend);
446       blend.rt[0].colormask = PIPE_MASK_RGBA;
447       handle = ctx->create_blend_state(ctx, &blend);
448       ctx->bind_blend_state(ctx, handle);
449    }
450 
451    {
452       struct pipe_depth_stencil_alpha_state depthstencil;
453       void *handle;
454       memset(&depthstencil, 0, sizeof depthstencil);
455       handle = ctx->create_depth_stencil_alpha_state(ctx, &depthstencil);
456       ctx->bind_depth_stencil_alpha_state(ctx, handle);
457    }
458 
459    {
460       struct pipe_rasterizer_state rasterizer;
461       void *handle;
462       memset(&rasterizer, 0, sizeof rasterizer);
463       rasterizer.cull_face = PIPE_FACE_NONE;
464       rasterizer.half_pixel_center = 1;
465       rasterizer.bottom_edge_rule = 1;
466       rasterizer.depth_clip_near = 1;
467       rasterizer.depth_clip_far = 1;
468       handle = ctx->create_rasterizer_state(ctx, &rasterizer);
469       ctx->bind_rasterizer_state(ctx, handle);
470    }
471 
472    set_viewport(0, 0, WIDTH, HEIGHT, 30, 1000);
473 
474    init_tex();
475    init_fs_constbuf();
476 
477    set_vertices();
478    set_vertex_shader();
479    set_fragment_shader(filename);
480 }
481 
args(int argc,char * argv[])482 static void args(int argc, char *argv[])
483 {
484    int i;
485 
486    for (i = 1; i < argc;) {
487       if (graw_parse_args(&i, argc, argv)) {
488          continue;
489       }
490       if (strcmp(argv[i], "-fps") == 0) {
491          show_fps = 1;
492          i++;
493       }
494       else if (i == argc - 1) {
495          filename = argv[i];
496          i++;
497       }
498       else {
499          usage(argv[0]);
500          exit(1);
501       }
502    }
503 
504    if (!filename) {
505       usage(argv[0]);
506       exit(1);
507    }
508 }
509 
main(int argc,char * argv[])510 int main( int argc, char *argv[] )
511 {
512    args(argc,argv);
513    init();
514 
515    graw_set_display_func( draw );
516    graw_main_loop();
517    return 0;
518 }
519