• 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,
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,
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    ctx->set_viewport_states( ctx, 0, 1, &vp );
152 }
153 
set_vertices(void)154 static void set_vertices( void )
155 {
156    struct pipe_vertex_element ve[3];
157    struct pipe_vertex_buffer vbuf;
158    void *handle;
159 
160    memset(ve, 0, sizeof ve);
161 
162    ve[0].src_offset = Offset(struct vertex, position);
163    ve[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
164    ve[1].src_offset = Offset(struct vertex, color);
165    ve[1].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
166    ve[2].src_offset = Offset(struct vertex, texcoord);
167    ve[2].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
168 
169    handle = ctx->create_vertex_elements_state(ctx, 3, ve);
170    ctx->bind_vertex_elements_state(ctx, handle);
171 
172    memset(&vbuf, 0, sizeof vbuf);
173 
174    vbuf.stride = sizeof( struct vertex );
175    vbuf.buffer_offset = 0;
176    vbuf.buffer.resource = pipe_buffer_create_with_data(ctx,
177                                               PIPE_BIND_VERTEX_BUFFER,
178                                               PIPE_USAGE_DEFAULT,
179                                               sizeof(vertices),
180                                               vertices);
181 
182    ctx->set_vertex_buffers(ctx, 0, 1, &vbuf);
183 }
184 
set_vertex_shader(void)185 static void set_vertex_shader( void )
186 {
187    void *handle;
188    const char *text =
189       "VERT\n"
190       "DCL IN[0]\n"
191       "DCL IN[1]\n"
192       "DCL IN[2]\n"
193       "DCL OUT[0], POSITION\n"
194       "DCL OUT[1], COLOR[0]\n"
195       "DCL OUT[2], GENERIC[0]\n"
196       "  MOV OUT[0], IN[0]\n"
197       "  MOV OUT[1], IN[1]\n"
198       "  MOV OUT[2], IN[2]\n"
199       "  END\n";
200 
201    handle = graw_parse_vertex_shader(ctx, text);
202    ctx->bind_vs_state(ctx, handle);
203 }
204 
set_fragment_shader(const char * filename)205 static void set_fragment_shader( const char *filename )
206 {
207    FILE *f;
208    char buf[50000];
209    void *handle;
210    int sz;
211 
212    if ((f = fopen(filename, "r")) == NULL) {
213       fprintf(stderr, "Couldn't open %s\n", filename);
214       exit(1);
215    }
216 
217    sz = fread(buf, 1, sizeof(buf), f);
218    if (!feof(f)) {
219       printf("file too long\n");
220       exit(1);
221    }
222    printf("%.*s\n", sz, buf);
223    buf[sz] = 0;
224 
225    handle = graw_parse_fragment_shader(ctx, buf);
226    ctx->bind_fs_state(ctx, handle);
227    fclose(f);
228 }
229 
230 
draw(void)231 static void draw( void )
232 {
233    union pipe_color_union clear_color = { {.1,.3,.5,0} };
234 
235    ctx->clear(ctx, PIPE_CLEAR_COLOR, NULL, &clear_color, 0, 0);
236    util_draw_arrays(ctx, PIPE_PRIM_TRIANGLES, 0, 3);
237    ctx->flush(ctx, NULL, 0);
238 
239    graw_save_surface_to_file(ctx, surf, NULL);
240 
241    screen->flush_frontbuffer(screen, rttex, 0, 0, window, NULL);
242 }
243 
244 #define SIZE 16
245 
init_tex(void)246 static void init_tex( void )
247 {
248    struct pipe_sampler_view sv_template;
249    struct pipe_sampler_state sampler_desc;
250    struct pipe_resource templat;
251    struct pipe_box box;
252    ubyte tex2d[SIZE][SIZE][4];
253    int s, t;
254 
255 #if (SIZE != 2)
256    for (s = 0; s < SIZE; s++) {
257       for (t = 0; t < SIZE; t++) {
258          if (0) {
259             int x = (s ^ t) & 1;
260 	    tex2d[t][s][0] = (x) ? 0 : 63;
261 	    tex2d[t][s][1] = (x) ? 0 : 128;
262 	    tex2d[t][s][2] = 0;
263 	    tex2d[t][s][3] = 0xff;
264          }
265          else {
266             int x = ((s ^ t) >> 2) & 1;
267 	    tex2d[t][s][0] = s*255/(SIZE-1);
268 	    tex2d[t][s][1] = t*255/(SIZE-1);
269 	    tex2d[t][s][2] = (x) ? 0 : 128;
270 	    tex2d[t][s][3] = 0xff;
271          }
272       }
273    }
274 #else
275    tex2d[0][0][0] = 0;
276    tex2d[0][0][1] = 255;
277    tex2d[0][0][2] = 255;
278    tex2d[0][0][3] = 0;
279 
280    tex2d[0][1][0] = 0;
281    tex2d[0][1][1] = 0;
282    tex2d[0][1][2] = 255;
283    tex2d[0][1][3] = 255;
284 
285    tex2d[1][0][0] = 255;
286    tex2d[1][0][1] = 255;
287    tex2d[1][0][2] = 0;
288    tex2d[1][0][3] = 255;
289 
290    tex2d[1][1][0] = 255;
291    tex2d[1][1][1] = 0;
292    tex2d[1][1][2] = 0;
293    tex2d[1][1][3] = 255;
294 #endif
295 
296    memset(&templat, 0, sizeof(templat));
297    templat.target = PIPE_TEXTURE_2D;
298    templat.format = PIPE_FORMAT_B8G8R8A8_UNORM;
299    templat.width0 = SIZE;
300    templat.height0 = SIZE;
301    templat.depth0 = 1;
302    templat.array_size = 1;
303    templat.last_level = 0;
304    templat.bind = PIPE_BIND_SAMPLER_VIEW;
305 
306 
307    samptex = screen->resource_create(screen,
308                                  &templat);
309    if (samptex == NULL)
310       exit(4);
311 
312    u_box_2d(0,0,SIZE,SIZE, &box);
313 
314    ctx->texture_subdata(ctx,
315                         samptex,
316                         0,
317                         PIPE_MAP_WRITE,
318                         &box,
319                         tex2d,
320                         sizeof tex2d[0],
321                         sizeof tex2d);
322 
323    /* Possibly read back & compare against original data:
324     */
325    if (0)
326    {
327       struct pipe_transfer *t;
328       uint32_t *ptr;
329       ptr = pipe_transfer_map(ctx, samptex,
330                               0, 0, /* level, layer */
331                               PIPE_MAP_READ,
332                               0, 0, SIZE, SIZE, &t); /* x, y, width, height */
333 
334       if (memcmp(ptr, tex2d, sizeof tex2d) != 0) {
335          assert(0);
336          exit(9);
337       }
338 
339       ctx->transfer_unmap(ctx, t);
340    }
341 
342    memset(&sv_template, 0, sizeof sv_template);
343    sv_template.format = samptex->format;
344    sv_template.texture = samptex;
345    sv_template.swizzle_r = 0;
346    sv_template.swizzle_g = 1;
347    sv_template.swizzle_b = 2;
348    sv_template.swizzle_a = 3;
349    sv = ctx->create_sampler_view(ctx, samptex, &sv_template);
350    if (sv == NULL)
351       exit(5);
352 
353    ctx->set_sampler_views(ctx, PIPE_SHADER_FRAGMENT, 0, 1, &sv);
354 
355 
356    memset(&sampler_desc, 0, sizeof sampler_desc);
357    sampler_desc.wrap_s = PIPE_TEX_WRAP_REPEAT;
358    sampler_desc.wrap_t = PIPE_TEX_WRAP_REPEAT;
359    sampler_desc.wrap_r = PIPE_TEX_WRAP_REPEAT;
360    sampler_desc.min_img_filter = PIPE_TEX_FILTER_NEAREST;
361    sampler_desc.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
362    sampler_desc.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
363    sampler_desc.compare_mode = PIPE_TEX_COMPARE_NONE;
364    sampler_desc.compare_func = 0;
365    sampler_desc.normalized_coords = 1;
366    sampler_desc.max_anisotropy = 0;
367 
368    sampler = ctx->create_sampler_state(ctx, &sampler_desc);
369    if (sampler == NULL)
370       exit(6);
371 
372    ctx->bind_sampler_states(ctx, PIPE_SHADER_FRAGMENT, 0, 1, &sampler);
373 
374 }
375 
init(void)376 static void init( void )
377 {
378    struct pipe_framebuffer_state fb;
379    struct pipe_resource templat;
380    struct pipe_surface surf_tmpl;
381    int i;
382 
383    /* It's hard to say whether window or screen should be created
384     * first.  Different environments would prefer one or the other.
385     *
386     * Also, no easy way of querying supported formats if the screen
387     * cannot be created first.
388     */
389    for (i = 0; formats[i] != PIPE_FORMAT_NONE; i++) {
390       screen = graw_create_window_and_screen(0, 0, 300, 300,
391                                              formats[i],
392                                              &window);
393       if (window && screen)
394          break;
395    }
396    if (!screen || !window) {
397       fprintf(stderr, "Unable to create window\n");
398       exit(1);
399    }
400 
401    ctx = screen->context_create(screen, NULL, 0);
402    if (ctx == NULL)
403       exit(3);
404 
405    memset(&templat, 0, sizeof(templat));
406    templat.target = PIPE_TEXTURE_2D;
407    templat.format = formats[i];
408    templat.width0 = WIDTH;
409    templat.height0 = HEIGHT;
410    templat.depth0 = 1;
411    templat.array_size = 1;
412    templat.last_level = 0;
413    templat.bind = (PIPE_BIND_RENDER_TARGET |
414                    PIPE_BIND_DISPLAY_TARGET);
415 
416    rttex = screen->resource_create(screen,
417                                  &templat);
418    if (rttex == NULL)
419       exit(4);
420 
421    surf_tmpl.format = templat.format;
422    surf_tmpl.u.tex.level = 0;
423    surf_tmpl.u.tex.first_layer = 0;
424    surf_tmpl.u.tex.last_layer = 0;
425    surf = ctx->create_surface(ctx, rttex, &surf_tmpl);
426    if (surf == NULL)
427       exit(5);
428 
429    memset(&fb, 0, sizeof fb);
430    fb.nr_cbufs = 1;
431    fb.width = WIDTH;
432    fb.height = HEIGHT;
433    fb.cbufs[0] = surf;
434 
435    ctx->set_framebuffer_state(ctx, &fb);
436 
437    {
438       struct pipe_blend_state blend;
439       void *handle;
440       memset(&blend, 0, sizeof blend);
441       blend.rt[0].colormask = PIPE_MASK_RGBA;
442       handle = ctx->create_blend_state(ctx, &blend);
443       ctx->bind_blend_state(ctx, handle);
444    }
445 
446    {
447       struct pipe_depth_stencil_alpha_state depthstencil;
448       void *handle;
449       memset(&depthstencil, 0, sizeof depthstencil);
450       handle = ctx->create_depth_stencil_alpha_state(ctx, &depthstencil);
451       ctx->bind_depth_stencil_alpha_state(ctx, handle);
452    }
453 
454    {
455       struct pipe_rasterizer_state rasterizer;
456       void *handle;
457       memset(&rasterizer, 0, sizeof rasterizer);
458       rasterizer.cull_face = PIPE_FACE_NONE;
459       rasterizer.half_pixel_center = 1;
460       rasterizer.bottom_edge_rule = 1;
461       rasterizer.depth_clip_near = 1;
462       rasterizer.depth_clip_far = 1;
463       handle = ctx->create_rasterizer_state(ctx, &rasterizer);
464       ctx->bind_rasterizer_state(ctx, handle);
465    }
466 
467    set_viewport(0, 0, WIDTH, HEIGHT, 30, 1000);
468 
469    init_tex();
470    init_fs_constbuf();
471 
472    set_vertices();
473    set_vertex_shader();
474    set_fragment_shader(filename);
475 }
476 
args(int argc,char * argv[])477 static void args(int argc, char *argv[])
478 {
479    int i;
480 
481    for (i = 1; i < argc;) {
482       if (graw_parse_args(&i, argc, argv)) {
483          continue;
484       }
485       if (strcmp(argv[i], "-fps") == 0) {
486          show_fps = 1;
487          i++;
488       }
489       else if (i == argc - 1) {
490          filename = argv[i];
491          i++;
492       }
493       else {
494          usage(argv[0]);
495          exit(1);
496       }
497    }
498 
499    if (!filename) {
500       usage(argv[0]);
501       exit(1);
502    }
503 }
504 
main(int argc,char * argv[])505 int main( int argc, char *argv[] )
506 {
507    args(argc,argv);
508    init();
509 
510    graw_set_display_func( draw );
511    graw_main_loop();
512    return 0;
513 }
514