1848b8605Smrg/* Display a cleared blue window.  This demo has no dependencies on
2848b8605Smrg * any utility code, just the graw interface and gallium.
3848b8605Smrg */
4848b8605Smrg
5848b8605Smrg#include "state_tracker/graw.h"
6848b8605Smrg#include "pipe/p_screen.h"
7848b8605Smrg#include "pipe/p_context.h"
8848b8605Smrg#include "pipe/p_shader_tokens.h"
9848b8605Smrg#include "pipe/p_state.h"
10848b8605Smrg#include "pipe/p_defines.h"
11848b8605Smrg#include <stdio.h>              /* for fread(), etc */
12848b8605Smrg
13848b8605Smrg#include "util/u_inlines.h"
14848b8605Smrg#include "util/u_memory.h"      /* Offset() */
15848b8605Smrg#include "util/u_draw_quad.h"
16848b8605Smrg#include "util/u_box.h"
17848b8605Smrg
18848b8605Smrgstatic const char *filename = NULL;
19848b8605Smrgunsigned show_fps = 0;
20848b8605Smrgunsigned draw_strip = 0;
21848b8605Smrg
22848b8605Smrg
23848b8605Smrgstatic void usage(char *name)
24848b8605Smrg{
25848b8605Smrg   fprintf(stderr, "usage: %s [ options ] shader_filename\n", name);
26848b8605Smrg#ifndef _WIN32
27848b8605Smrg   fprintf(stderr, "\n" );
28848b8605Smrg   fprintf(stderr, "options:\n");
29848b8605Smrg   fprintf(stderr, "    -fps  show frames per second\n");
30848b8605Smrg   fprintf(stderr, "    -strip renders a triangle strip\n");
31848b8605Smrg#endif
32848b8605Smrg}
33848b8605Smrg
34848b8605Smrg
35848b8605Smrgenum pipe_format formats[] = {
36848b8605Smrg   PIPE_FORMAT_R8G8B8A8_UNORM,
37848b8605Smrg   PIPE_FORMAT_B8G8R8A8_UNORM,
38848b8605Smrg   PIPE_FORMAT_NONE
39848b8605Smrg};
40848b8605Smrg
41848b8605Smrgstatic const int WIDTH = 250;
42848b8605Smrgstatic const int HEIGHT = 250;
43848b8605Smrg
44848b8605Smrgstatic struct pipe_screen *screen = NULL;
45848b8605Smrgstatic struct pipe_context *ctx = NULL;
46848b8605Smrgstatic struct pipe_resource *rttex = NULL;
47848b8605Smrgstatic struct pipe_resource *constbuf1 = NULL;
48848b8605Smrgstatic struct pipe_resource *constbuf2 = NULL;
49848b8605Smrgstatic struct pipe_surface *surf = NULL;
50848b8605Smrgstatic struct pipe_sampler_view *sv = NULL;
51848b8605Smrgstatic void *sampler = NULL;
52848b8605Smrgstatic void *window = NULL;
53848b8605Smrgstatic struct pipe_resource *samptex = NULL;
54848b8605Smrg
55848b8605Smrgstruct vertex {
56848b8605Smrg   float position[4];
57848b8605Smrg   float color[4];
58848b8605Smrg   float texcoord[4];
59848b8605Smrg   float generic[4];
60848b8605Smrg};
61848b8605Smrg
62848b8605Smrg/* Vertex data matches progs/fp/fp-tri.c, but flipped in Y dimension
63848b8605Smrg * so that the final images are the same.
64848b8605Smrg */
65848b8605Smrgstatic struct vertex vertices[] =
66848b8605Smrg{
67848b8605Smrg   { { 0.9, 0.9, 0.0, 1.0 },
68848b8605Smrg     { 0, 0, 1, 1 },
69848b8605Smrg     { 1, 1, 0, 1 },
70848b8605Smrg     { 1, 0, 1, 0 }
71848b8605Smrg   },
72848b8605Smrg
73848b8605Smrg   { { 0.9,  -0.9, 0.0, 1.0 },
74848b8605Smrg     { 1, 0, 0, 1 },
75848b8605Smrg     { 1, -1, 0, 1 },
76848b8605Smrg     { 0, 1, 0, 1 }
77848b8605Smrg   },
78848b8605Smrg
79848b8605Smrg   { {-0.9,  0.0, 0.0, 1.0 },
80848b8605Smrg     { 0, 1, 0, 1 },
81848b8605Smrg     { -1, 0, 0, 1 },
82848b8605Smrg     { 0, 0, 1, 1 }
83848b8605Smrg   },
84848b8605Smrg};
85848b8605Smrg
86848b8605Smrgstatic struct vertex vertices_strip[] =
87848b8605Smrg{
88848b8605Smrg   { { 0.9, 0.9, 0.0, 1.0 },
89848b8605Smrg     { 0, 0, 1, 1 },
90848b8605Smrg     { 1, 1, 0, 1 },
91848b8605Smrg     { 1, 0, 0, 1 }
92848b8605Smrg   },
93848b8605Smrg
94848b8605Smrg   { { 0.9,  -0.9, 0.0, 1.0 },
95848b8605Smrg     { 1, 0, 0, 1 },
96848b8605Smrg     { 1, -1, 0, 1 },
97848b8605Smrg     { 0, 1, 0, 1 }
98848b8605Smrg   },
99848b8605Smrg
100848b8605Smrg   { {-0.9,  0.9, 0.0, 1.0 },
101848b8605Smrg     { 0, 1, 0, 1 },
102848b8605Smrg     { -1, 1, 0, 1 },
103848b8605Smrg     { 0, 0, 1, 1 }
104848b8605Smrg   },
105848b8605Smrg
106848b8605Smrg   { {-0.9,  -0.9, 0.0, 1.0 },
107848b8605Smrg     { 1, 1, 0, 1 },
108848b8605Smrg     { -1, -1, 0, 1 },
109848b8605Smrg     { 1, 1, 0, 1 }
110848b8605Smrg   },
111848b8605Smrg};
112848b8605Smrg
113848b8605Smrgstatic float constants1[] =
114848b8605Smrg{  0.4, 0, 0,  1,
115848b8605Smrg   1,   1, 1,  1,
116848b8605Smrg   2,   2, 2,  2,
117848b8605Smrg   4,   8, 16, 32,
118848b8605Smrg
119848b8605Smrg   3,  0, 0, 0,
120848b8605Smrg   0, .5, 0, 0,
121848b8605Smrg   0,  0, 1, 0,
122848b8605Smrg   0,  0, 0, 1,
123848b8605Smrg
124848b8605Smrg   1, 0, 0, 0.5,
125848b8605Smrg   0, 1, 0, 0.5,
126848b8605Smrg   0, 0, 1, 0,
127848b8605Smrg   0, 0, 0, 1,
128848b8605Smrg};
129848b8605Smrg
130848b8605Smrg
131848b8605Smrgstatic float constants2[] =
132848b8605Smrg{  1, 0, 0,  1,
133848b8605Smrg   0, 1, 0,  1,
134848b8605Smrg   0, 0, 1,  1,
135848b8605Smrg   0, 0, 0,  1,
136848b8605Smrg
137848b8605Smrg   1,  1, 0, 1,
138848b8605Smrg   1, .5, 0, 1,
139848b8605Smrg   0,  1, 1, 1,
140848b8605Smrg   1,  0, 1, 1,
141848b8605Smrg
142848b8605Smrg   1, 0, 0, 0.5,
143848b8605Smrg   0, 1, 0, 0.5,
144848b8605Smrg   0, 0, 1, 0,
145848b8605Smrg   0, 0, 0, 1,
146848b8605Smrg};
147848b8605Smrg
148848b8605Smrg
149848b8605Smrgstatic void init_fs_constbuf( void )
150848b8605Smrg{
151848b8605Smrg   struct pipe_resource templat;
152848b8605Smrg
153b8e80941Smrg   memset(&templat, 0, sizeof(templat));
154848b8605Smrg   templat.target = PIPE_BUFFER;
155848b8605Smrg   templat.format = PIPE_FORMAT_R8_UNORM;
156848b8605Smrg   templat.width0 = sizeof(constants1);
157848b8605Smrg   templat.height0 = 1;
158848b8605Smrg   templat.depth0 = 1;
159848b8605Smrg   templat.array_size = 1;
160848b8605Smrg   templat.last_level = 0;
161848b8605Smrg   templat.bind = PIPE_BIND_CONSTANT_BUFFER;
162848b8605Smrg
163848b8605Smrg   constbuf1 = screen->resource_create(screen, &templat);
164848b8605Smrg   if (constbuf1 == NULL)
165848b8605Smrg      exit(4);
166848b8605Smrg   constbuf2 = screen->resource_create(screen, &templat);
167848b8605Smrg   if (constbuf2 == NULL)
168848b8605Smrg      exit(4);
169848b8605Smrg
170848b8605Smrg   {
171b8e80941Smrg      ctx->buffer_subdata(ctx, constbuf1,
172b8e80941Smrg                          PIPE_TRANSFER_WRITE,
173b8e80941Smrg                          0, sizeof(constants1), constants1);
174848b8605Smrg
175848b8605Smrg      pipe_set_constant_buffer(ctx,
176848b8605Smrg                               PIPE_SHADER_GEOMETRY, 0,
177848b8605Smrg                               constbuf1);
178848b8605Smrg   }
179848b8605Smrg   {
180b8e80941Smrg      ctx->buffer_subdata(ctx, constbuf2,
181b8e80941Smrg                          PIPE_TRANSFER_WRITE,
182b8e80941Smrg                          0, sizeof(constants2), constants2);
183848b8605Smrg
184848b8605Smrg      pipe_set_constant_buffer(ctx,
185848b8605Smrg                               PIPE_SHADER_GEOMETRY, 1,
186848b8605Smrg                               constbuf2);
187848b8605Smrg   }
188848b8605Smrg}
189848b8605Smrg
190848b8605Smrg
191848b8605Smrgstatic void set_viewport( float x, float y,
192848b8605Smrg                          float width, float height,
193b8e80941Smrg                          float zNear, float zFar)
194848b8605Smrg{
195b8e80941Smrg   float z = zFar;
196848b8605Smrg   float half_width = (float)width / 2.0f;
197848b8605Smrg   float half_height = (float)height / 2.0f;
198b8e80941Smrg   float half_depth = ((float)zFar - (float)zNear) / 2.0f;
199848b8605Smrg   struct pipe_viewport_state vp;
200848b8605Smrg
201848b8605Smrg   vp.scale[0] = half_width;
202848b8605Smrg   vp.scale[1] = half_height;
203848b8605Smrg   vp.scale[2] = half_depth;
204848b8605Smrg
205848b8605Smrg   vp.translate[0] = half_width + x;
206848b8605Smrg   vp.translate[1] = half_height + y;
207848b8605Smrg   vp.translate[2] = half_depth + z;
208848b8605Smrg
209848b8605Smrg   ctx->set_viewport_states( ctx, 0, 1, &vp );
210848b8605Smrg}
211848b8605Smrg
212848b8605Smrgstatic void set_vertices( void )
213848b8605Smrg{
214848b8605Smrg   struct pipe_vertex_element ve[4];
215848b8605Smrg   struct pipe_vertex_buffer vbuf;
216848b8605Smrg   void *handle;
217848b8605Smrg
218848b8605Smrg   memset(ve, 0, sizeof ve);
219848b8605Smrg
220848b8605Smrg   ve[0].src_offset = Offset(struct vertex, position);
221848b8605Smrg   ve[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
222848b8605Smrg   ve[1].src_offset = Offset(struct vertex, color);
223848b8605Smrg   ve[1].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
224848b8605Smrg   ve[2].src_offset = Offset(struct vertex, texcoord);
225848b8605Smrg   ve[2].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
226848b8605Smrg   ve[3].src_offset = Offset(struct vertex, generic);
227848b8605Smrg   ve[3].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
228848b8605Smrg
229848b8605Smrg   handle = ctx->create_vertex_elements_state(ctx, 4, ve);
230848b8605Smrg   ctx->bind_vertex_elements_state(ctx, handle);
231848b8605Smrg
232848b8605Smrg   memset(&vbuf, 0, sizeof vbuf);
233848b8605Smrg
234848b8605Smrg   vbuf.stride = sizeof( struct vertex );
235848b8605Smrg   vbuf.buffer_offset = 0;
236848b8605Smrg   if (draw_strip) {
237b8e80941Smrg      vbuf.buffer.resource = pipe_buffer_create_with_data(ctx,
238848b8605Smrg                                                 PIPE_BIND_VERTEX_BUFFER,
239848b8605Smrg                                                 PIPE_USAGE_DEFAULT,
240848b8605Smrg                                                 sizeof(vertices_strip),
241848b8605Smrg                                                 vertices_strip);
242848b8605Smrg   } else {
243b8e80941Smrg      vbuf.buffer.resource = pipe_buffer_create_with_data(ctx,
244848b8605Smrg                                                 PIPE_BIND_VERTEX_BUFFER,
245848b8605Smrg                                                 PIPE_USAGE_DEFAULT,
246848b8605Smrg                                                 sizeof(vertices),
247848b8605Smrg                                                 vertices);
248848b8605Smrg   }
249848b8605Smrg
250848b8605Smrg   ctx->set_vertex_buffers(ctx, 0, 1, &vbuf);
251848b8605Smrg}
252848b8605Smrg
253848b8605Smrgstatic void set_vertex_shader( void )
254848b8605Smrg{
255848b8605Smrg   void *handle;
256848b8605Smrg   const char *text =
257848b8605Smrg      "VERT\n"
258848b8605Smrg      "DCL IN[0]\n"
259848b8605Smrg      "DCL IN[1]\n"
260848b8605Smrg      "DCL IN[2]\n"
261848b8605Smrg      "DCL IN[3]\n"
262848b8605Smrg      "DCL OUT[0], POSITION\n"
263848b8605Smrg      "DCL OUT[1], COLOR[0]\n"
264848b8605Smrg      "DCL OUT[2], GENERIC[0]\n"
265848b8605Smrg      "DCL OUT[3], GENERIC[1]\n"
266848b8605Smrg      "  MOV OUT[0], IN[0]\n"
267848b8605Smrg      "  MOV OUT[1], IN[1]\n"
268848b8605Smrg      "  MOV OUT[2], IN[2]\n"
269848b8605Smrg      "  MOV OUT[3], IN[3]\n"
270848b8605Smrg      "  END\n";
271848b8605Smrg
272848b8605Smrg   handle = graw_parse_vertex_shader(ctx, text);
273848b8605Smrg   ctx->bind_vs_state(ctx, handle);
274848b8605Smrg}
275848b8605Smrg
276848b8605Smrgstatic void set_fragment_shader( void )
277848b8605Smrg{
278848b8605Smrg   void *handle;
279848b8605Smrg   const char *text =
280848b8605Smrg      "FRAG\n"
281848b8605Smrg      "DCL IN[0], COLOR, LINEAR\n"
282848b8605Smrg      "DCL OUT[0], COLOR\n"
283848b8605Smrg      "  0: MOV OUT[0], IN[0]\n"
284848b8605Smrg      "  1: END\n";
285848b8605Smrg
286848b8605Smrg   handle = graw_parse_fragment_shader(ctx, text);
287848b8605Smrg   ctx->bind_fs_state(ctx, handle);
288848b8605Smrg}
289848b8605Smrg
290848b8605Smrg
291848b8605Smrgstatic void set_geometry_shader( void )
292848b8605Smrg{
293848b8605Smrg   FILE *f;
294848b8605Smrg   char buf[50000];
295848b8605Smrg   void *handle;
296848b8605Smrg   int sz;
297848b8605Smrg
298848b8605Smrg   if ((f = fopen(filename, "r")) == NULL) {
299848b8605Smrg      fprintf(stderr, "Couldn't open %s\n", filename);
300848b8605Smrg      exit(1);
301848b8605Smrg   }
302848b8605Smrg
303848b8605Smrg   sz = fread(buf, 1, sizeof(buf), f);
304848b8605Smrg   if (!feof(f)) {
305848b8605Smrg      printf("file too long\n");
306848b8605Smrg      exit(1);
307848b8605Smrg   }
308848b8605Smrg   printf("%.*s\n", sz, buf);
309848b8605Smrg   buf[sz] = 0;
310848b8605Smrg
311848b8605Smrg   handle = graw_parse_geometry_shader(ctx, buf);
312848b8605Smrg   ctx->bind_gs_state(ctx, handle);
313848b8605Smrg   fclose(f);
314848b8605Smrg}
315848b8605Smrg
316848b8605Smrg
317848b8605Smrgstatic void draw( void )
318848b8605Smrg{
319848b8605Smrg   union pipe_color_union clear_color = { {.1,.3,.5,0} };
320848b8605Smrg
321848b8605Smrg   ctx->clear(ctx, PIPE_CLEAR_COLOR, &clear_color, 0, 0);
322848b8605Smrg   if (draw_strip)
323848b8605Smrg      util_draw_arrays(ctx, PIPE_PRIM_TRIANGLE_STRIP, 0, 4);
324848b8605Smrg   else
325848b8605Smrg      util_draw_arrays(ctx, PIPE_PRIM_TRIANGLES, 0, 3);
326848b8605Smrg
327848b8605Smrg   ctx->flush(ctx, NULL, 0);
328848b8605Smrg
329848b8605Smrg   graw_save_surface_to_file(ctx, surf, NULL);
330848b8605Smrg
331848b8605Smrg   screen->flush_frontbuffer(screen, rttex, 0, 0, window, NULL);
332848b8605Smrg}
333848b8605Smrg
334848b8605Smrg#define SIZE 16
335848b8605Smrg
336848b8605Smrgstatic void init_tex( void )
337848b8605Smrg{
338848b8605Smrg   struct pipe_sampler_view sv_template;
339848b8605Smrg   struct pipe_sampler_state sampler_desc;
340848b8605Smrg   struct pipe_resource templat;
341848b8605Smrg   struct pipe_box box;
342848b8605Smrg   ubyte tex2d[SIZE][SIZE][4];
343848b8605Smrg   int s, t;
344848b8605Smrg
345848b8605Smrg#if (SIZE != 2)
346848b8605Smrg   for (s = 0; s < SIZE; s++) {
347848b8605Smrg      for (t = 0; t < SIZE; t++) {
348848b8605Smrg         if (0) {
349848b8605Smrg            int x = (s ^ t) & 1;
350848b8605Smrg	    tex2d[t][s][0] = (x) ? 0 : 63;
351848b8605Smrg	    tex2d[t][s][1] = (x) ? 0 : 128;
352848b8605Smrg	    tex2d[t][s][2] = 0;
353848b8605Smrg	    tex2d[t][s][3] = 0xff;
354848b8605Smrg         }
355848b8605Smrg         else {
356848b8605Smrg            int x = ((s ^ t) >> 2) & 1;
357848b8605Smrg	    tex2d[t][s][0] = s*255/(SIZE-1);
358848b8605Smrg	    tex2d[t][s][1] = t*255/(SIZE-1);
359848b8605Smrg	    tex2d[t][s][2] = (x) ? 0 : 128;
360848b8605Smrg	    tex2d[t][s][3] = 0xff;
361848b8605Smrg         }
362848b8605Smrg      }
363848b8605Smrg   }
364848b8605Smrg#else
365848b8605Smrg   tex2d[0][0][0] = 0;
366848b8605Smrg   tex2d[0][0][1] = 255;
367848b8605Smrg   tex2d[0][0][2] = 255;
368848b8605Smrg   tex2d[0][0][3] = 0;
369848b8605Smrg
370848b8605Smrg   tex2d[0][1][0] = 0;
371848b8605Smrg   tex2d[0][1][1] = 0;
372848b8605Smrg   tex2d[0][1][2] = 255;
373848b8605Smrg   tex2d[0][1][3] = 255;
374848b8605Smrg
375848b8605Smrg   tex2d[1][0][0] = 255;
376848b8605Smrg   tex2d[1][0][1] = 255;
377848b8605Smrg   tex2d[1][0][2] = 0;
378848b8605Smrg   tex2d[1][0][3] = 255;
379848b8605Smrg
380848b8605Smrg   tex2d[1][1][0] = 255;
381848b8605Smrg   tex2d[1][1][1] = 0;
382848b8605Smrg   tex2d[1][1][2] = 0;
383848b8605Smrg   tex2d[1][1][3] = 255;
384848b8605Smrg#endif
385848b8605Smrg
386b8e80941Smrg   memset(&templat, 0, sizeof(templat));
387848b8605Smrg   templat.target = PIPE_TEXTURE_2D;
388848b8605Smrg   templat.format = PIPE_FORMAT_B8G8R8A8_UNORM;
389848b8605Smrg   templat.width0 = SIZE;
390848b8605Smrg   templat.height0 = SIZE;
391848b8605Smrg   templat.depth0 = 1;
392848b8605Smrg   templat.array_size = 1;
393848b8605Smrg   templat.last_level = 0;
394848b8605Smrg   templat.bind = PIPE_BIND_SAMPLER_VIEW;
395848b8605Smrg
396848b8605Smrg
397848b8605Smrg   samptex = screen->resource_create(screen,
398848b8605Smrg                                 &templat);
399848b8605Smrg   if (samptex == NULL)
400848b8605Smrg      exit(4);
401848b8605Smrg
402848b8605Smrg   u_box_2d(0,0,SIZE,SIZE, &box);
403848b8605Smrg
404b8e80941Smrg   ctx->texture_subdata(ctx,
405b8e80941Smrg                        samptex,
406b8e80941Smrg                        0,
407b8e80941Smrg                        PIPE_TRANSFER_WRITE,
408b8e80941Smrg                        &box,
409b8e80941Smrg                        tex2d,
410b8e80941Smrg                        sizeof tex2d[0],
411b8e80941Smrg         sizeof tex2d);
412848b8605Smrg
413848b8605Smrg   /* Possibly read back & compare against original data:
414848b8605Smrg    */
415848b8605Smrg   if (0)
416848b8605Smrg   {
417848b8605Smrg      struct pipe_transfer *t;
418848b8605Smrg      uint32_t *ptr;
419848b8605Smrg      ptr = pipe_transfer_map(ctx, samptex,
420848b8605Smrg                              0, 0, /* level, layer */
421848b8605Smrg                              PIPE_TRANSFER_READ,
422848b8605Smrg                              0, 0, SIZE, SIZE, &t); /* x, y, width, height */
423848b8605Smrg
424848b8605Smrg      if (memcmp(ptr, tex2d, sizeof tex2d) != 0) {
425848b8605Smrg         assert(0);
426848b8605Smrg         exit(9);
427848b8605Smrg      }
428848b8605Smrg
429848b8605Smrg      ctx->transfer_unmap(ctx, t);
430848b8605Smrg   }
431848b8605Smrg
432848b8605Smrg   memset(&sv_template, 0, sizeof sv_template);
433848b8605Smrg   sv_template.format = samptex->format;
434848b8605Smrg   sv_template.texture = samptex;
435848b8605Smrg   sv_template.swizzle_r = 0;
436848b8605Smrg   sv_template.swizzle_g = 1;
437848b8605Smrg   sv_template.swizzle_b = 2;
438848b8605Smrg   sv_template.swizzle_a = 3;
439848b8605Smrg   sv = ctx->create_sampler_view(ctx, samptex, &sv_template);
440848b8605Smrg   if (sv == NULL)
441848b8605Smrg      exit(5);
442848b8605Smrg
443848b8605Smrg   ctx->set_sampler_views(ctx, PIPE_SHADER_FRAGMENT, 0, 1, &sv);
444848b8605Smrg
445848b8605Smrg
446848b8605Smrg   memset(&sampler_desc, 0, sizeof sampler_desc);
447848b8605Smrg   sampler_desc.wrap_s = PIPE_TEX_WRAP_REPEAT;
448848b8605Smrg   sampler_desc.wrap_t = PIPE_TEX_WRAP_REPEAT;
449848b8605Smrg   sampler_desc.wrap_r = PIPE_TEX_WRAP_REPEAT;
450848b8605Smrg   sampler_desc.min_img_filter = PIPE_TEX_FILTER_NEAREST;
451848b8605Smrg   sampler_desc.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
452848b8605Smrg   sampler_desc.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
453848b8605Smrg   sampler_desc.compare_mode = PIPE_TEX_COMPARE_NONE;
454848b8605Smrg   sampler_desc.compare_func = 0;
455848b8605Smrg   sampler_desc.normalized_coords = 1;
456848b8605Smrg   sampler_desc.max_anisotropy = 0;
457848b8605Smrg
458848b8605Smrg   sampler = ctx->create_sampler_state(ctx, &sampler_desc);
459848b8605Smrg   if (sampler == NULL)
460848b8605Smrg      exit(6);
461848b8605Smrg
462848b8605Smrg   ctx->bind_sampler_states(ctx, PIPE_SHADER_FRAGMENT, 0, 1, &sampler);
463848b8605Smrg
464848b8605Smrg}
465848b8605Smrg
466848b8605Smrgstatic void init( void )
467848b8605Smrg{
468848b8605Smrg   struct pipe_framebuffer_state fb;
469848b8605Smrg   struct pipe_resource templat;
470848b8605Smrg   struct pipe_surface surf_tmpl;
471848b8605Smrg   int i;
472848b8605Smrg
473848b8605Smrg   /* It's hard to say whether window or screen should be created
474848b8605Smrg    * first.  Different environments would prefer one or the other.
475848b8605Smrg    *
476848b8605Smrg    * Also, no easy way of querying supported formats if the screen
477848b8605Smrg    * cannot be created first.
478848b8605Smrg    */
479848b8605Smrg   for (i = 0; formats[i] != PIPE_FORMAT_NONE; i++) {
480848b8605Smrg      screen = graw_create_window_and_screen(0, 0, 300, 300,
481848b8605Smrg                                             formats[i],
482848b8605Smrg                                             &window);
483848b8605Smrg      if (window && screen)
484848b8605Smrg         break;
485848b8605Smrg   }
486848b8605Smrg   if (!screen || !window) {
487848b8605Smrg      fprintf(stderr, "Unable to create window\n");
488848b8605Smrg      exit(1);
489848b8605Smrg   }
490848b8605Smrg
491b8e80941Smrg   ctx = screen->context_create(screen, NULL, 0);
492848b8605Smrg   if (ctx == NULL)
493848b8605Smrg      exit(3);
494848b8605Smrg
495b8e80941Smrg   memset(&templat, 0, sizeof(templat));
496848b8605Smrg   templat.target = PIPE_TEXTURE_2D;
497848b8605Smrg   templat.format = formats[i];
498848b8605Smrg   templat.width0 = WIDTH;
499848b8605Smrg   templat.height0 = HEIGHT;
500848b8605Smrg   templat.depth0 = 1;
501848b8605Smrg   templat.array_size = 1;
502848b8605Smrg   templat.last_level = 0;
503848b8605Smrg   templat.bind = (PIPE_BIND_RENDER_TARGET |
504848b8605Smrg                   PIPE_BIND_DISPLAY_TARGET);
505848b8605Smrg
506848b8605Smrg   rttex = screen->resource_create(screen,
507848b8605Smrg                                 &templat);
508848b8605Smrg   if (rttex == NULL)
509848b8605Smrg      exit(4);
510848b8605Smrg
511848b8605Smrg   surf_tmpl.format = templat.format;
512848b8605Smrg   surf_tmpl.u.tex.level = 0;
513848b8605Smrg   surf_tmpl.u.tex.first_layer = 0;
514848b8605Smrg   surf_tmpl.u.tex.last_layer = 0;
515848b8605Smrg   surf = ctx->create_surface(ctx, rttex, &surf_tmpl);
516848b8605Smrg   if (surf == NULL)
517848b8605Smrg      exit(5);
518848b8605Smrg
519848b8605Smrg   memset(&fb, 0, sizeof fb);
520848b8605Smrg   fb.nr_cbufs = 1;
521848b8605Smrg   fb.width = WIDTH;
522848b8605Smrg   fb.height = HEIGHT;
523848b8605Smrg   fb.cbufs[0] = surf;
524848b8605Smrg
525848b8605Smrg   ctx->set_framebuffer_state(ctx, &fb);
526848b8605Smrg
527848b8605Smrg   {
528848b8605Smrg      struct pipe_blend_state blend;
529848b8605Smrg      void *handle;
530848b8605Smrg      memset(&blend, 0, sizeof blend);
531848b8605Smrg      blend.rt[0].colormask = PIPE_MASK_RGBA;
532848b8605Smrg      handle = ctx->create_blend_state(ctx, &blend);
533848b8605Smrg      ctx->bind_blend_state(ctx, handle);
534848b8605Smrg   }
535848b8605Smrg
536848b8605Smrg   {
537848b8605Smrg      struct pipe_depth_stencil_alpha_state depthstencil;
538848b8605Smrg      void *handle;
539848b8605Smrg      memset(&depthstencil, 0, sizeof depthstencil);
540848b8605Smrg      handle = ctx->create_depth_stencil_alpha_state(ctx, &depthstencil);
541848b8605Smrg      ctx->bind_depth_stencil_alpha_state(ctx, handle);
542848b8605Smrg   }
543848b8605Smrg
544848b8605Smrg   {
545848b8605Smrg      struct pipe_rasterizer_state rasterizer;
546848b8605Smrg      void *handle;
547848b8605Smrg      memset(&rasterizer, 0, sizeof rasterizer);
548848b8605Smrg      rasterizer.cull_face = PIPE_FACE_NONE;
549848b8605Smrg      rasterizer.half_pixel_center = 1;
550848b8605Smrg      rasterizer.bottom_edge_rule = 1;
551b8e80941Smrg      rasterizer.depth_clip_near = 1;
552b8e80941Smrg      rasterizer.depth_clip_far = 1;
553848b8605Smrg      handle = ctx->create_rasterizer_state(ctx, &rasterizer);
554848b8605Smrg      ctx->bind_rasterizer_state(ctx, handle);
555848b8605Smrg   }
556848b8605Smrg
557848b8605Smrg   set_viewport(0, 0, WIDTH, HEIGHT, 30, 1000);
558848b8605Smrg
559848b8605Smrg   init_tex();
560848b8605Smrg   init_fs_constbuf();
561848b8605Smrg
562848b8605Smrg   set_vertices();
563848b8605Smrg   set_vertex_shader();
564848b8605Smrg   set_fragment_shader();
565848b8605Smrg   set_geometry_shader();
566848b8605Smrg}
567848b8605Smrg
568848b8605Smrgstatic void args(int argc, char *argv[])
569848b8605Smrg{
570848b8605Smrg   int i;
571848b8605Smrg
572848b8605Smrg   for (i = 1; i < argc;) {
573848b8605Smrg      if (graw_parse_args(&i, argc, argv)) {
574848b8605Smrg         continue;
575848b8605Smrg      }
576848b8605Smrg      if (strcmp(argv[i], "-fps") == 0) {
577848b8605Smrg         show_fps = 1;
578848b8605Smrg         i++;
579848b8605Smrg      }
580848b8605Smrg      else if (strcmp(argv[i], "-strip") == 0) {
581848b8605Smrg         draw_strip = 1;
582848b8605Smrg         i++;
583848b8605Smrg      }
584848b8605Smrg      else if (i == argc - 1) {
585848b8605Smrg         filename = argv[i];
586848b8605Smrg         i++;
587848b8605Smrg      }
588848b8605Smrg      else {
589848b8605Smrg         usage(argv[0]);
590848b8605Smrg         exit(1);
591848b8605Smrg      }
592848b8605Smrg   }
593848b8605Smrg
594848b8605Smrg   if (!filename) {
595848b8605Smrg      usage(argv[0]);
596848b8605Smrg      exit(1);
597848b8605Smrg   }
598848b8605Smrg}
599848b8605Smrg
600848b8605Smrgint main( int argc, char *argv[] )
601848b8605Smrg{
602848b8605Smrg   args(argc,argv);
603848b8605Smrg   init();
604848b8605Smrg
605848b8605Smrg   graw_set_display_func( draw );
606848b8605Smrg   graw_main_loop();
607848b8605Smrg   return 0;
608848b8605Smrg}
609