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;
20848b8605Smrg
21848b8605Smrg
22848b8605Smrgstatic void usage(char *name)
23848b8605Smrg{
24848b8605Smrg   fprintf(stderr, "usage: %s [ options ] shader_filename\n", name);
25848b8605Smrg#ifndef _WIN32
26848b8605Smrg   fprintf(stderr, "\n" );
27848b8605Smrg   fprintf(stderr, "options:\n");
28848b8605Smrg   fprintf(stderr, "    -fps  show frames per second\n");
29848b8605Smrg#endif
30848b8605Smrg}
31848b8605Smrg
32848b8605Smrg
33848b8605Smrgenum pipe_format formats[] = {
34848b8605Smrg   PIPE_FORMAT_RGBA8888_UNORM,
35848b8605Smrg   PIPE_FORMAT_BGRA8888_UNORM,
36848b8605Smrg   PIPE_FORMAT_NONE
37848b8605Smrg};
38848b8605Smrg
39848b8605Smrgstatic const int WIDTH = 250;
40848b8605Smrgstatic const int HEIGHT = 250;
41848b8605Smrg
42848b8605Smrgstatic struct pipe_screen *screen = NULL;
43848b8605Smrgstatic struct pipe_context *ctx = NULL;
44848b8605Smrgstatic struct pipe_resource *rttex = NULL;
45848b8605Smrgstatic struct pipe_surface *surf = NULL;
46848b8605Smrgstatic struct pipe_sampler_view *sv = NULL;
47848b8605Smrgstatic void *sampler = NULL;
48848b8605Smrgstatic void *window = NULL;
49848b8605Smrgstatic struct pipe_resource *samptex = NULL;
50848b8605Smrg
51848b8605Smrgstruct vertex {
52848b8605Smrg   float position[4];
53848b8605Smrg   float color[4];
54848b8605Smrg   float texcoord[4];
55848b8605Smrg};
56848b8605Smrg
57848b8605Smrg/* Vertex data matches progs/fp/fp-tri.c, but flipped in Y dimension
58848b8605Smrg * so that the final images are the same.
59848b8605Smrg */
60848b8605Smrgstatic struct vertex vertices[] =
61848b8605Smrg{
62848b8605Smrg   { { 0.9, 0.9, 0.0, 1.0 },
63848b8605Smrg     { 0, 0, 1, 1 },
64848b8605Smrg     { 1, 1, 0, 1 } },
65848b8605Smrg
66848b8605Smrg   { { 0.9,  -0.9, 0.0, 1.0 },
67848b8605Smrg     { 1, 0, 0, 1 },
68848b8605Smrg     { 1, -1, 0, 1 } },
69848b8605Smrg
70848b8605Smrg   { {-0.9,  0.0, 0.0, 1.0 },
71848b8605Smrg     { 0, 1, 0, 1 },
72848b8605Smrg     { -1, 0, 0, 1 } },
73848b8605Smrg};
74848b8605Smrg
75848b8605Smrgstatic float constants1[] =
76848b8605Smrg{  0.4, 0, 0,  1,
77848b8605Smrg   1,   1, 1,  1,
78848b8605Smrg   2,   2, 2,  2,
79848b8605Smrg   4,   8, 16, 32,
80848b8605Smrg
81848b8605Smrg   3,  0, 0, 0,
82848b8605Smrg   0, .5, 0, 0,
83848b8605Smrg   1,  0, 0, 1,
84848b8605Smrg   0,  0, 0, 1,
85848b8605Smrg
86848b8605Smrg   1, 0, 0, 0.5,
87848b8605Smrg   0, 1, 0, 0.5,
88848b8605Smrg   0, 0, 1, 0,
89848b8605Smrg   0, 0, 0, 1,
90848b8605Smrg};
91848b8605Smrg
92848b8605Smrg
93848b8605Smrgstatic float constants2[] =
94848b8605Smrg{  1, 0, 0,  1,
95848b8605Smrg   0, 1, 0,  1,
96848b8605Smrg   0, 0, 1,  1,
97848b8605Smrg   0, 0, 0,  0,
98848b8605Smrg
99848b8605Smrg   1,  1, 0, 1,
100848b8605Smrg   1, .5, 0, 1,
101848b8605Smrg   1,  0, 0, 1,
102848b8605Smrg   0,  0, 0, 1,
103848b8605Smrg
104848b8605Smrg   1, 0, 0, 0.5,
105848b8605Smrg   0, 1, 0, 0.5,
106848b8605Smrg   0, 0, 1, 0,
107848b8605Smrg   0, 0, 0, 1,
108848b8605Smrg};
109848b8605Smrg
110848b8605Smrgstatic void init_fs_constbuf( void )
111848b8605Smrg{
112848b8605Smrg   struct pipe_constant_buffer cb1;
113848b8605Smrg   struct pipe_constant_buffer cb2;
114848b8605Smrg
115848b8605Smrg   memset(&cb1, 0, sizeof cb1);
116848b8605Smrg   cb1.buffer_size = sizeof constants1;
117848b8605Smrg   cb1.user_buffer = constants1;
118848b8605Smrg
119848b8605Smrg   ctx->set_constant_buffer(ctx,
120848b8605Smrg                            PIPE_SHADER_FRAGMENT, 0,
121848b8605Smrg                            &cb1);
122848b8605Smrg
123848b8605Smrg   memset(&cb2, 0, sizeof cb2);
124848b8605Smrg   cb2.buffer_size = sizeof constants2;
125848b8605Smrg   cb2.user_buffer = constants2;
126848b8605Smrg
127848b8605Smrg   ctx->set_constant_buffer(ctx,
128848b8605Smrg                            PIPE_SHADER_FRAGMENT, 1,
129848b8605Smrg                            &cb2);
130848b8605Smrg}
131848b8605Smrg
132848b8605Smrg
133848b8605Smrgstatic void set_viewport( float x, float y,
134848b8605Smrg                          float width, float height,
135b8e80941Smrg                          float zNear, float zFar)
136848b8605Smrg{
137b8e80941Smrg   float z = zFar;
138848b8605Smrg   float half_width = (float)width / 2.0f;
139848b8605Smrg   float half_height = (float)height / 2.0f;
140b8e80941Smrg   float half_depth = ((float)zFar - (float)zNear) / 2.0f;
141848b8605Smrg   struct pipe_viewport_state vp;
142848b8605Smrg
143848b8605Smrg   vp.scale[0] = half_width;
144848b8605Smrg   vp.scale[1] = half_height;
145848b8605Smrg   vp.scale[2] = half_depth;
146848b8605Smrg
147848b8605Smrg   vp.translate[0] = half_width + x;
148848b8605Smrg   vp.translate[1] = half_height + y;
149848b8605Smrg   vp.translate[2] = half_depth + z;
150848b8605Smrg
151848b8605Smrg   ctx->set_viewport_states( ctx, 0, 1, &vp );
152848b8605Smrg}
153848b8605Smrg
154848b8605Smrgstatic void set_vertices( void )
155848b8605Smrg{
156848b8605Smrg   struct pipe_vertex_element ve[3];
157848b8605Smrg   struct pipe_vertex_buffer vbuf;
158848b8605Smrg   void *handle;
159848b8605Smrg
160848b8605Smrg   memset(ve, 0, sizeof ve);
161848b8605Smrg
162848b8605Smrg   ve[0].src_offset = Offset(struct vertex, position);
163848b8605Smrg   ve[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
164848b8605Smrg   ve[1].src_offset = Offset(struct vertex, color);
165848b8605Smrg   ve[1].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
166848b8605Smrg   ve[2].src_offset = Offset(struct vertex, texcoord);
167848b8605Smrg   ve[2].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
168848b8605Smrg
169848b8605Smrg   handle = ctx->create_vertex_elements_state(ctx, 3, ve);
170848b8605Smrg   ctx->bind_vertex_elements_state(ctx, handle);
171848b8605Smrg
172848b8605Smrg   memset(&vbuf, 0, sizeof vbuf);
173848b8605Smrg
174848b8605Smrg   vbuf.stride = sizeof( struct vertex );
175848b8605Smrg   vbuf.buffer_offset = 0;
176b8e80941Smrg   vbuf.buffer.resource = pipe_buffer_create_with_data(ctx,
177848b8605Smrg                                              PIPE_BIND_VERTEX_BUFFER,
178848b8605Smrg                                              PIPE_USAGE_DEFAULT,
179848b8605Smrg                                              sizeof(vertices),
180848b8605Smrg                                              vertices);
181848b8605Smrg
182848b8605Smrg   ctx->set_vertex_buffers(ctx, 0, 1, &vbuf);
183848b8605Smrg}
184848b8605Smrg
185848b8605Smrgstatic void set_vertex_shader( void )
186848b8605Smrg{
187848b8605Smrg   void *handle;
188848b8605Smrg   const char *text =
189848b8605Smrg      "VERT\n"
190848b8605Smrg      "DCL IN[0]\n"
191848b8605Smrg      "DCL IN[1]\n"
192848b8605Smrg      "DCL IN[2]\n"
193848b8605Smrg      "DCL OUT[0], POSITION\n"
194848b8605Smrg      "DCL OUT[1], COLOR[0]\n"
195848b8605Smrg      "DCL OUT[2], GENERIC[0]\n"
196848b8605Smrg      "  MOV OUT[0], IN[0]\n"
197848b8605Smrg      "  MOV OUT[1], IN[1]\n"
198848b8605Smrg      "  MOV OUT[2], IN[2]\n"
199848b8605Smrg      "  END\n";
200848b8605Smrg
201848b8605Smrg   handle = graw_parse_vertex_shader(ctx, text);
202848b8605Smrg   ctx->bind_vs_state(ctx, handle);
203848b8605Smrg}
204848b8605Smrg
205848b8605Smrgstatic void set_fragment_shader( const char *filename )
206848b8605Smrg{
207848b8605Smrg   FILE *f;
208848b8605Smrg   char buf[50000];
209848b8605Smrg   void *handle;
210848b8605Smrg   int sz;
211848b8605Smrg
212848b8605Smrg   if ((f = fopen(filename, "r")) == NULL) {
213848b8605Smrg      fprintf(stderr, "Couldn't open %s\n", filename);
214848b8605Smrg      exit(1);
215848b8605Smrg   }
216848b8605Smrg
217848b8605Smrg   sz = fread(buf, 1, sizeof(buf), f);
218848b8605Smrg   if (!feof(f)) {
219848b8605Smrg      printf("file too long\n");
220848b8605Smrg      exit(1);
221848b8605Smrg   }
222848b8605Smrg   printf("%.*s\n", sz, buf);
223848b8605Smrg   buf[sz] = 0;
224848b8605Smrg
225848b8605Smrg   handle = graw_parse_fragment_shader(ctx, buf);
226848b8605Smrg   ctx->bind_fs_state(ctx, handle);
227848b8605Smrg   fclose(f);
228848b8605Smrg}
229848b8605Smrg
230848b8605Smrg
231848b8605Smrgstatic void draw( void )
232848b8605Smrg{
233848b8605Smrg   union pipe_color_union clear_color = { {.1,.3,.5,0} };
234848b8605Smrg
235848b8605Smrg   ctx->clear(ctx, PIPE_CLEAR_COLOR, &clear_color, 0, 0);
236848b8605Smrg   util_draw_arrays(ctx, PIPE_PRIM_TRIANGLES, 0, 3);
237848b8605Smrg   ctx->flush(ctx, NULL, 0);
238848b8605Smrg
239848b8605Smrg   graw_save_surface_to_file(ctx, surf, NULL);
240848b8605Smrg
241848b8605Smrg   screen->flush_frontbuffer(screen, rttex, 0, 0, window, NULL);
242848b8605Smrg}
243848b8605Smrg
244848b8605Smrg#define SIZE 16
245848b8605Smrg
246848b8605Smrgstatic void init_tex( void )
247848b8605Smrg{
248848b8605Smrg   struct pipe_sampler_view sv_template;
249848b8605Smrg   struct pipe_sampler_state sampler_desc;
250848b8605Smrg   struct pipe_resource templat;
251848b8605Smrg   struct pipe_box box;
252848b8605Smrg   ubyte tex2d[SIZE][SIZE][4];
253848b8605Smrg   int s, t;
254848b8605Smrg
255848b8605Smrg#if (SIZE != 2)
256848b8605Smrg   for (s = 0; s < SIZE; s++) {
257848b8605Smrg      for (t = 0; t < SIZE; t++) {
258848b8605Smrg         if (0) {
259848b8605Smrg            int x = (s ^ t) & 1;
260848b8605Smrg	    tex2d[t][s][0] = (x) ? 0 : 63;
261848b8605Smrg	    tex2d[t][s][1] = (x) ? 0 : 128;
262848b8605Smrg	    tex2d[t][s][2] = 0;
263848b8605Smrg	    tex2d[t][s][3] = 0xff;
264848b8605Smrg         }
265848b8605Smrg         else {
266848b8605Smrg            int x = ((s ^ t) >> 2) & 1;
267848b8605Smrg	    tex2d[t][s][0] = s*255/(SIZE-1);
268848b8605Smrg	    tex2d[t][s][1] = t*255/(SIZE-1);
269848b8605Smrg	    tex2d[t][s][2] = (x) ? 0 : 128;
270848b8605Smrg	    tex2d[t][s][3] = 0xff;
271848b8605Smrg         }
272848b8605Smrg      }
273848b8605Smrg   }
274848b8605Smrg#else
275848b8605Smrg   tex2d[0][0][0] = 0;
276848b8605Smrg   tex2d[0][0][1] = 255;
277848b8605Smrg   tex2d[0][0][2] = 255;
278848b8605Smrg   tex2d[0][0][3] = 0;
279848b8605Smrg
280848b8605Smrg   tex2d[0][1][0] = 0;
281848b8605Smrg   tex2d[0][1][1] = 0;
282848b8605Smrg   tex2d[0][1][2] = 255;
283848b8605Smrg   tex2d[0][1][3] = 255;
284848b8605Smrg
285848b8605Smrg   tex2d[1][0][0] = 255;
286848b8605Smrg   tex2d[1][0][1] = 255;
287848b8605Smrg   tex2d[1][0][2] = 0;
288848b8605Smrg   tex2d[1][0][3] = 255;
289848b8605Smrg
290848b8605Smrg   tex2d[1][1][0] = 255;
291848b8605Smrg   tex2d[1][1][1] = 0;
292848b8605Smrg   tex2d[1][1][2] = 0;
293848b8605Smrg   tex2d[1][1][3] = 255;
294848b8605Smrg#endif
295848b8605Smrg
296b8e80941Smrg   memset(&templat, 0, sizeof(templat));
297848b8605Smrg   templat.target = PIPE_TEXTURE_2D;
298848b8605Smrg   templat.format = PIPE_FORMAT_B8G8R8A8_UNORM;
299848b8605Smrg   templat.width0 = SIZE;
300848b8605Smrg   templat.height0 = SIZE;
301848b8605Smrg   templat.depth0 = 1;
302848b8605Smrg   templat.array_size = 1;
303848b8605Smrg   templat.last_level = 0;
304848b8605Smrg   templat.bind = PIPE_BIND_SAMPLER_VIEW;
305848b8605Smrg
306848b8605Smrg
307848b8605Smrg   samptex = screen->resource_create(screen,
308848b8605Smrg                                 &templat);
309848b8605Smrg   if (samptex == NULL)
310848b8605Smrg      exit(4);
311848b8605Smrg
312848b8605Smrg   u_box_2d(0,0,SIZE,SIZE, &box);
313848b8605Smrg
314b8e80941Smrg   ctx->texture_subdata(ctx,
315b8e80941Smrg                        samptex,
316b8e80941Smrg                        0,
317b8e80941Smrg                        PIPE_TRANSFER_WRITE,
318b8e80941Smrg                        &box,
319b8e80941Smrg                        tex2d,
320b8e80941Smrg                        sizeof tex2d[0],
321b8e80941Smrg                        sizeof tex2d);
322848b8605Smrg
323848b8605Smrg   /* Possibly read back & compare against original data:
324848b8605Smrg    */
325848b8605Smrg   if (0)
326848b8605Smrg   {
327848b8605Smrg      struct pipe_transfer *t;
328848b8605Smrg      uint32_t *ptr;
329848b8605Smrg      ptr = pipe_transfer_map(ctx, samptex,
330848b8605Smrg                              0, 0, /* level, layer */
331848b8605Smrg                              PIPE_TRANSFER_READ,
332848b8605Smrg                              0, 0, SIZE, SIZE, &t); /* x, y, width, height */
333848b8605Smrg
334848b8605Smrg      if (memcmp(ptr, tex2d, sizeof tex2d) != 0) {
335848b8605Smrg         assert(0);
336848b8605Smrg         exit(9);
337848b8605Smrg      }
338848b8605Smrg
339848b8605Smrg      ctx->transfer_unmap(ctx, t);
340848b8605Smrg   }
341848b8605Smrg
342848b8605Smrg   memset(&sv_template, 0, sizeof sv_template);
343848b8605Smrg   sv_template.format = samptex->format;
344848b8605Smrg   sv_template.texture = samptex;
345848b8605Smrg   sv_template.swizzle_r = 0;
346848b8605Smrg   sv_template.swizzle_g = 1;
347848b8605Smrg   sv_template.swizzle_b = 2;
348848b8605Smrg   sv_template.swizzle_a = 3;
349848b8605Smrg   sv = ctx->create_sampler_view(ctx, samptex, &sv_template);
350848b8605Smrg   if (sv == NULL)
351848b8605Smrg      exit(5);
352848b8605Smrg
353848b8605Smrg   ctx->set_sampler_views(ctx, PIPE_SHADER_FRAGMENT, 0, 1, &sv);
354848b8605Smrg
355848b8605Smrg
356848b8605Smrg   memset(&sampler_desc, 0, sizeof sampler_desc);
357848b8605Smrg   sampler_desc.wrap_s = PIPE_TEX_WRAP_REPEAT;
358848b8605Smrg   sampler_desc.wrap_t = PIPE_TEX_WRAP_REPEAT;
359848b8605Smrg   sampler_desc.wrap_r = PIPE_TEX_WRAP_REPEAT;
360848b8605Smrg   sampler_desc.min_img_filter = PIPE_TEX_FILTER_NEAREST;
361848b8605Smrg   sampler_desc.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
362848b8605Smrg   sampler_desc.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
363848b8605Smrg   sampler_desc.compare_mode = PIPE_TEX_COMPARE_NONE;
364848b8605Smrg   sampler_desc.compare_func = 0;
365848b8605Smrg   sampler_desc.normalized_coords = 1;
366848b8605Smrg   sampler_desc.max_anisotropy = 0;
367848b8605Smrg
368848b8605Smrg   sampler = ctx->create_sampler_state(ctx, &sampler_desc);
369848b8605Smrg   if (sampler == NULL)
370848b8605Smrg      exit(6);
371848b8605Smrg
372848b8605Smrg   ctx->bind_sampler_states(ctx, PIPE_SHADER_FRAGMENT, 0, 1, &sampler);
373848b8605Smrg
374848b8605Smrg}
375848b8605Smrg
376848b8605Smrgstatic void init( void )
377848b8605Smrg{
378848b8605Smrg   struct pipe_framebuffer_state fb;
379848b8605Smrg   struct pipe_resource templat;
380848b8605Smrg   struct pipe_surface surf_tmpl;
381848b8605Smrg   int i;
382848b8605Smrg
383848b8605Smrg   /* It's hard to say whether window or screen should be created
384848b8605Smrg    * first.  Different environments would prefer one or the other.
385848b8605Smrg    *
386848b8605Smrg    * Also, no easy way of querying supported formats if the screen
387848b8605Smrg    * cannot be created first.
388848b8605Smrg    */
389848b8605Smrg   for (i = 0; formats[i] != PIPE_FORMAT_NONE; i++) {
390848b8605Smrg      screen = graw_create_window_and_screen(0, 0, 300, 300,
391848b8605Smrg                                             formats[i],
392848b8605Smrg                                             &window);
393848b8605Smrg      if (window && screen)
394848b8605Smrg         break;
395848b8605Smrg   }
396848b8605Smrg   if (!screen || !window) {
397848b8605Smrg      fprintf(stderr, "Unable to create window\n");
398848b8605Smrg      exit(1);
399848b8605Smrg   }
400848b8605Smrg
401b8e80941Smrg   ctx = screen->context_create(screen, NULL, 0);
402848b8605Smrg   if (ctx == NULL)
403848b8605Smrg      exit(3);
404848b8605Smrg
405b8e80941Smrg   memset(&templat, 0, sizeof(templat));
406848b8605Smrg   templat.target = PIPE_TEXTURE_2D;
407848b8605Smrg   templat.format = formats[i];
408848b8605Smrg   templat.width0 = WIDTH;
409848b8605Smrg   templat.height0 = HEIGHT;
410848b8605Smrg   templat.depth0 = 1;
411848b8605Smrg   templat.array_size = 1;
412848b8605Smrg   templat.last_level = 0;
413848b8605Smrg   templat.bind = (PIPE_BIND_RENDER_TARGET |
414848b8605Smrg                   PIPE_BIND_DISPLAY_TARGET);
415848b8605Smrg
416848b8605Smrg   rttex = screen->resource_create(screen,
417848b8605Smrg                                 &templat);
418848b8605Smrg   if (rttex == NULL)
419848b8605Smrg      exit(4);
420848b8605Smrg
421848b8605Smrg   surf_tmpl.format = templat.format;
422848b8605Smrg   surf_tmpl.u.tex.level = 0;
423848b8605Smrg   surf_tmpl.u.tex.first_layer = 0;
424848b8605Smrg   surf_tmpl.u.tex.last_layer = 0;
425848b8605Smrg   surf = ctx->create_surface(ctx, rttex, &surf_tmpl);
426848b8605Smrg   if (surf == NULL)
427848b8605Smrg      exit(5);
428848b8605Smrg
429848b8605Smrg   memset(&fb, 0, sizeof fb);
430848b8605Smrg   fb.nr_cbufs = 1;
431848b8605Smrg   fb.width = WIDTH;
432848b8605Smrg   fb.height = HEIGHT;
433848b8605Smrg   fb.cbufs[0] = surf;
434848b8605Smrg
435848b8605Smrg   ctx->set_framebuffer_state(ctx, &fb);
436848b8605Smrg
437848b8605Smrg   {
438848b8605Smrg      struct pipe_blend_state blend;
439848b8605Smrg      void *handle;
440848b8605Smrg      memset(&blend, 0, sizeof blend);
441848b8605Smrg      blend.rt[0].colormask = PIPE_MASK_RGBA;
442848b8605Smrg      handle = ctx->create_blend_state(ctx, &blend);
443848b8605Smrg      ctx->bind_blend_state(ctx, handle);
444848b8605Smrg   }
445848b8605Smrg
446848b8605Smrg   {
447848b8605Smrg      struct pipe_depth_stencil_alpha_state depthstencil;
448848b8605Smrg      void *handle;
449848b8605Smrg      memset(&depthstencil, 0, sizeof depthstencil);
450848b8605Smrg      handle = ctx->create_depth_stencil_alpha_state(ctx, &depthstencil);
451848b8605Smrg      ctx->bind_depth_stencil_alpha_state(ctx, handle);
452848b8605Smrg   }
453848b8605Smrg
454848b8605Smrg   {
455848b8605Smrg      struct pipe_rasterizer_state rasterizer;
456848b8605Smrg      void *handle;
457848b8605Smrg      memset(&rasterizer, 0, sizeof rasterizer);
458848b8605Smrg      rasterizer.cull_face = PIPE_FACE_NONE;
459848b8605Smrg      rasterizer.half_pixel_center = 1;
460848b8605Smrg      rasterizer.bottom_edge_rule = 1;
461b8e80941Smrg      rasterizer.depth_clip_near = 1;
462b8e80941Smrg      rasterizer.depth_clip_far = 1;
463848b8605Smrg      handle = ctx->create_rasterizer_state(ctx, &rasterizer);
464848b8605Smrg      ctx->bind_rasterizer_state(ctx, handle);
465848b8605Smrg   }
466848b8605Smrg
467848b8605Smrg   set_viewport(0, 0, WIDTH, HEIGHT, 30, 1000);
468848b8605Smrg
469848b8605Smrg   init_tex();
470848b8605Smrg   init_fs_constbuf();
471848b8605Smrg
472848b8605Smrg   set_vertices();
473848b8605Smrg   set_vertex_shader();
474848b8605Smrg   set_fragment_shader(filename);
475848b8605Smrg}
476848b8605Smrg
477848b8605Smrgstatic void args(int argc, char *argv[])
478848b8605Smrg{
479848b8605Smrg   int i;
480848b8605Smrg
481848b8605Smrg   for (i = 1; i < argc;) {
482848b8605Smrg      if (graw_parse_args(&i, argc, argv)) {
483848b8605Smrg         continue;
484848b8605Smrg      }
485848b8605Smrg      if (strcmp(argv[i], "-fps") == 0) {
486848b8605Smrg         show_fps = 1;
487848b8605Smrg         i++;
488848b8605Smrg      }
489848b8605Smrg      else if (i == argc - 1) {
490848b8605Smrg         filename = argv[i];
491848b8605Smrg         i++;
492848b8605Smrg      }
493848b8605Smrg      else {
494848b8605Smrg         usage(argv[0]);
495848b8605Smrg         exit(1);
496848b8605Smrg      }
497848b8605Smrg   }
498848b8605Smrg
499848b8605Smrg   if (!filename) {
500848b8605Smrg      usage(argv[0]);
501848b8605Smrg      exit(1);
502848b8605Smrg   }
503848b8605Smrg}
504848b8605Smrg
505848b8605Smrgint main( int argc, char *argv[] )
506848b8605Smrg{
507848b8605Smrg   args(argc,argv);
508848b8605Smrg   init();
509848b8605Smrg
510848b8605Smrg   graw_set_display_func( draw );
511848b8605Smrg   graw_main_loop();
512848b8605Smrg   return 0;
513848b8605Smrg}
514