13464ebd5Sriastradh/* Display a cleared blue window.  This demo has no dependencies on
23464ebd5Sriastradh * any utility code, just the graw interface and gallium.
33464ebd5Sriastradh */
43464ebd5Sriastradh
57ec681f3Smrg#include "frontend/graw.h"
63464ebd5Sriastradh#include "pipe/p_screen.h"
73464ebd5Sriastradh#include "pipe/p_context.h"
83464ebd5Sriastradh#include "pipe/p_shader_tokens.h"
93464ebd5Sriastradh#include "pipe/p_state.h"
103464ebd5Sriastradh#include "pipe/p_defines.h"
113464ebd5Sriastradh#include <stdio.h>              /* for fread(), etc */
123464ebd5Sriastradh
133464ebd5Sriastradh#include "util/u_inlines.h"
143464ebd5Sriastradh#include "util/u_memory.h"      /* Offset() */
153464ebd5Sriastradh#include "util/u_draw_quad.h"
163464ebd5Sriastradh#include "util/u_box.h"
173464ebd5Sriastradh
183464ebd5Sriastradhstatic const char *filename = NULL;
193464ebd5Sriastradhunsigned show_fps = 0;
203464ebd5Sriastradhunsigned draw_strip = 0;
213464ebd5Sriastradh
223464ebd5Sriastradh
233464ebd5Sriastradhstatic void usage(char *name)
243464ebd5Sriastradh{
253464ebd5Sriastradh   fprintf(stderr, "usage: %s [ options ] shader_filename\n", name);
26af69d88dSmrg#ifndef _WIN32
273464ebd5Sriastradh   fprintf(stderr, "\n" );
283464ebd5Sriastradh   fprintf(stderr, "options:\n");
293464ebd5Sriastradh   fprintf(stderr, "    -fps  show frames per second\n");
303464ebd5Sriastradh   fprintf(stderr, "    -strip renders a triangle strip\n");
313464ebd5Sriastradh#endif
323464ebd5Sriastradh}
333464ebd5Sriastradh
343464ebd5Sriastradh
353464ebd5Sriastradhenum pipe_format formats[] = {
363464ebd5Sriastradh   PIPE_FORMAT_R8G8B8A8_UNORM,
373464ebd5Sriastradh   PIPE_FORMAT_B8G8R8A8_UNORM,
383464ebd5Sriastradh   PIPE_FORMAT_NONE
393464ebd5Sriastradh};
403464ebd5Sriastradh
413464ebd5Sriastradhstatic const int WIDTH = 250;
423464ebd5Sriastradhstatic const int HEIGHT = 250;
433464ebd5Sriastradh
443464ebd5Sriastradhstatic struct pipe_screen *screen = NULL;
453464ebd5Sriastradhstatic struct pipe_context *ctx = NULL;
463464ebd5Sriastradhstatic struct pipe_resource *rttex = NULL;
473464ebd5Sriastradhstatic struct pipe_resource *constbuf1 = NULL;
483464ebd5Sriastradhstatic struct pipe_resource *constbuf2 = NULL;
493464ebd5Sriastradhstatic struct pipe_surface *surf = NULL;
503464ebd5Sriastradhstatic struct pipe_sampler_view *sv = NULL;
513464ebd5Sriastradhstatic void *sampler = NULL;
523464ebd5Sriastradhstatic void *window = NULL;
533464ebd5Sriastradhstatic struct pipe_resource *samptex = NULL;
543464ebd5Sriastradh
553464ebd5Sriastradhstruct vertex {
563464ebd5Sriastradh   float position[4];
573464ebd5Sriastradh   float color[4];
583464ebd5Sriastradh   float texcoord[4];
593464ebd5Sriastradh   float generic[4];
603464ebd5Sriastradh};
613464ebd5Sriastradh
623464ebd5Sriastradh/* Vertex data matches progs/fp/fp-tri.c, but flipped in Y dimension
633464ebd5Sriastradh * so that the final images are the same.
643464ebd5Sriastradh */
653464ebd5Sriastradhstatic struct vertex vertices[] =
663464ebd5Sriastradh{
673464ebd5Sriastradh   { { 0.9, 0.9, 0.0, 1.0 },
683464ebd5Sriastradh     { 0, 0, 1, 1 },
693464ebd5Sriastradh     { 1, 1, 0, 1 },
703464ebd5Sriastradh     { 1, 0, 1, 0 }
713464ebd5Sriastradh   },
723464ebd5Sriastradh
733464ebd5Sriastradh   { { 0.9,  -0.9, 0.0, 1.0 },
743464ebd5Sriastradh     { 1, 0, 0, 1 },
753464ebd5Sriastradh     { 1, -1, 0, 1 },
763464ebd5Sriastradh     { 0, 1, 0, 1 }
773464ebd5Sriastradh   },
783464ebd5Sriastradh
793464ebd5Sriastradh   { {-0.9,  0.0, 0.0, 1.0 },
803464ebd5Sriastradh     { 0, 1, 0, 1 },
813464ebd5Sriastradh     { -1, 0, 0, 1 },
823464ebd5Sriastradh     { 0, 0, 1, 1 }
833464ebd5Sriastradh   },
843464ebd5Sriastradh};
853464ebd5Sriastradh
863464ebd5Sriastradhstatic struct vertex vertices_strip[] =
873464ebd5Sriastradh{
883464ebd5Sriastradh   { { 0.9, 0.9, 0.0, 1.0 },
893464ebd5Sriastradh     { 0, 0, 1, 1 },
903464ebd5Sriastradh     { 1, 1, 0, 1 },
913464ebd5Sriastradh     { 1, 0, 0, 1 }
923464ebd5Sriastradh   },
933464ebd5Sriastradh
943464ebd5Sriastradh   { { 0.9,  -0.9, 0.0, 1.0 },
953464ebd5Sriastradh     { 1, 0, 0, 1 },
963464ebd5Sriastradh     { 1, -1, 0, 1 },
973464ebd5Sriastradh     { 0, 1, 0, 1 }
983464ebd5Sriastradh   },
993464ebd5Sriastradh
1003464ebd5Sriastradh   { {-0.9,  0.9, 0.0, 1.0 },
1013464ebd5Sriastradh     { 0, 1, 0, 1 },
1023464ebd5Sriastradh     { -1, 1, 0, 1 },
1033464ebd5Sriastradh     { 0, 0, 1, 1 }
1043464ebd5Sriastradh   },
1053464ebd5Sriastradh
1063464ebd5Sriastradh   { {-0.9,  -0.9, 0.0, 1.0 },
1073464ebd5Sriastradh     { 1, 1, 0, 1 },
1083464ebd5Sriastradh     { -1, -1, 0, 1 },
1093464ebd5Sriastradh     { 1, 1, 0, 1 }
1103464ebd5Sriastradh   },
1113464ebd5Sriastradh};
1123464ebd5Sriastradh
1133464ebd5Sriastradhstatic float constants1[] =
1143464ebd5Sriastradh{  0.4, 0, 0,  1,
1153464ebd5Sriastradh   1,   1, 1,  1,
1163464ebd5Sriastradh   2,   2, 2,  2,
1173464ebd5Sriastradh   4,   8, 16, 32,
1183464ebd5Sriastradh
1193464ebd5Sriastradh   3,  0, 0, 0,
1203464ebd5Sriastradh   0, .5, 0, 0,
1213464ebd5Sriastradh   0,  0, 1, 0,
1223464ebd5Sriastradh   0,  0, 0, 1,
1233464ebd5Sriastradh
1243464ebd5Sriastradh   1, 0, 0, 0.5,
1253464ebd5Sriastradh   0, 1, 0, 0.5,
1263464ebd5Sriastradh   0, 0, 1, 0,
1273464ebd5Sriastradh   0, 0, 0, 1,
1283464ebd5Sriastradh};
1293464ebd5Sriastradh
1303464ebd5Sriastradh
1313464ebd5Sriastradhstatic float constants2[] =
1323464ebd5Sriastradh{  1, 0, 0,  1,
1333464ebd5Sriastradh   0, 1, 0,  1,
1343464ebd5Sriastradh   0, 0, 1,  1,
1353464ebd5Sriastradh   0, 0, 0,  1,
1363464ebd5Sriastradh
1373464ebd5Sriastradh   1,  1, 0, 1,
1383464ebd5Sriastradh   1, .5, 0, 1,
1393464ebd5Sriastradh   0,  1, 1, 1,
1403464ebd5Sriastradh   1,  0, 1, 1,
1413464ebd5Sriastradh
1423464ebd5Sriastradh   1, 0, 0, 0.5,
1433464ebd5Sriastradh   0, 1, 0, 0.5,
1443464ebd5Sriastradh   0, 0, 1, 0,
1453464ebd5Sriastradh   0, 0, 0, 1,
1463464ebd5Sriastradh};
1473464ebd5Sriastradh
1483464ebd5Sriastradh
1493464ebd5Sriastradhstatic void init_fs_constbuf( void )
1503464ebd5Sriastradh{
1513464ebd5Sriastradh   struct pipe_resource templat;
1523464ebd5Sriastradh
15301e04c3fSmrg   memset(&templat, 0, sizeof(templat));
1543464ebd5Sriastradh   templat.target = PIPE_BUFFER;
1553464ebd5Sriastradh   templat.format = PIPE_FORMAT_R8_UNORM;
1563464ebd5Sriastradh   templat.width0 = sizeof(constants1);
1573464ebd5Sriastradh   templat.height0 = 1;
1583464ebd5Sriastradh   templat.depth0 = 1;
1593464ebd5Sriastradh   templat.array_size = 1;
1603464ebd5Sriastradh   templat.last_level = 0;
1613464ebd5Sriastradh   templat.bind = PIPE_BIND_CONSTANT_BUFFER;
1623464ebd5Sriastradh
1633464ebd5Sriastradh   constbuf1 = screen->resource_create(screen, &templat);
1643464ebd5Sriastradh   if (constbuf1 == NULL)
1653464ebd5Sriastradh      exit(4);
1663464ebd5Sriastradh   constbuf2 = screen->resource_create(screen, &templat);
1673464ebd5Sriastradh   if (constbuf2 == NULL)
1683464ebd5Sriastradh      exit(4);
1693464ebd5Sriastradh
1703464ebd5Sriastradh   {
17101e04c3fSmrg      ctx->buffer_subdata(ctx, constbuf1,
1727ec681f3Smrg                          PIPE_MAP_WRITE,
17301e04c3fSmrg                          0, sizeof(constants1), constants1);
1743464ebd5Sriastradh
175af69d88dSmrg      pipe_set_constant_buffer(ctx,
1763464ebd5Sriastradh                               PIPE_SHADER_GEOMETRY, 0,
1773464ebd5Sriastradh                               constbuf1);
1783464ebd5Sriastradh   }
1793464ebd5Sriastradh   {
18001e04c3fSmrg      ctx->buffer_subdata(ctx, constbuf2,
1817ec681f3Smrg                          PIPE_MAP_WRITE,
18201e04c3fSmrg                          0, sizeof(constants2), constants2);
1833464ebd5Sriastradh
184af69d88dSmrg      pipe_set_constant_buffer(ctx,
1853464ebd5Sriastradh                               PIPE_SHADER_GEOMETRY, 1,
1863464ebd5Sriastradh                               constbuf2);
1873464ebd5Sriastradh   }
1883464ebd5Sriastradh}
1893464ebd5Sriastradh
1903464ebd5Sriastradh
1913464ebd5Sriastradhstatic void set_viewport( float x, float y,
1923464ebd5Sriastradh                          float width, float height,
19301e04c3fSmrg                          float zNear, float zFar)
1943464ebd5Sriastradh{
19501e04c3fSmrg   float z = zFar;
1963464ebd5Sriastradh   float half_width = (float)width / 2.0f;
1973464ebd5Sriastradh   float half_height = (float)height / 2.0f;
19801e04c3fSmrg   float half_depth = ((float)zFar - (float)zNear) / 2.0f;
1993464ebd5Sriastradh   struct pipe_viewport_state vp;
2003464ebd5Sriastradh
2013464ebd5Sriastradh   vp.scale[0] = half_width;
2023464ebd5Sriastradh   vp.scale[1] = half_height;
2033464ebd5Sriastradh   vp.scale[2] = half_depth;
2043464ebd5Sriastradh
2053464ebd5Sriastradh   vp.translate[0] = half_width + x;
2063464ebd5Sriastradh   vp.translate[1] = half_height + y;
2073464ebd5Sriastradh   vp.translate[2] = half_depth + z;
2083464ebd5Sriastradh
2097ec681f3Smrg   vp.swizzle_x = PIPE_VIEWPORT_SWIZZLE_POSITIVE_X;
2107ec681f3Smrg   vp.swizzle_y = PIPE_VIEWPORT_SWIZZLE_POSITIVE_Y;
2117ec681f3Smrg   vp.swizzle_z = PIPE_VIEWPORT_SWIZZLE_POSITIVE_Z;
2127ec681f3Smrg   vp.swizzle_w = PIPE_VIEWPORT_SWIZZLE_POSITIVE_W;
2137ec681f3Smrg
214af69d88dSmrg   ctx->set_viewport_states( ctx, 0, 1, &vp );
2153464ebd5Sriastradh}
2163464ebd5Sriastradh
2173464ebd5Sriastradhstatic void set_vertices( void )
2183464ebd5Sriastradh{
2193464ebd5Sriastradh   struct pipe_vertex_element ve[4];
2203464ebd5Sriastradh   struct pipe_vertex_buffer vbuf;
2213464ebd5Sriastradh   void *handle;
2223464ebd5Sriastradh
2233464ebd5Sriastradh   memset(ve, 0, sizeof ve);
2243464ebd5Sriastradh
2253464ebd5Sriastradh   ve[0].src_offset = Offset(struct vertex, position);
2263464ebd5Sriastradh   ve[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
2273464ebd5Sriastradh   ve[1].src_offset = Offset(struct vertex, color);
2283464ebd5Sriastradh   ve[1].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
2293464ebd5Sriastradh   ve[2].src_offset = Offset(struct vertex, texcoord);
2303464ebd5Sriastradh   ve[2].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
2313464ebd5Sriastradh   ve[3].src_offset = Offset(struct vertex, generic);
2323464ebd5Sriastradh   ve[3].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
2333464ebd5Sriastradh
2343464ebd5Sriastradh   handle = ctx->create_vertex_elements_state(ctx, 4, ve);
2353464ebd5Sriastradh   ctx->bind_vertex_elements_state(ctx, handle);
2363464ebd5Sriastradh
237af69d88dSmrg   memset(&vbuf, 0, sizeof vbuf);
238af69d88dSmrg
2393464ebd5Sriastradh   vbuf.stride = sizeof( struct vertex );
2403464ebd5Sriastradh   vbuf.buffer_offset = 0;
2413464ebd5Sriastradh   if (draw_strip) {
24201e04c3fSmrg      vbuf.buffer.resource = pipe_buffer_create_with_data(ctx,
243af69d88dSmrg                                                 PIPE_BIND_VERTEX_BUFFER,
244af69d88dSmrg                                                 PIPE_USAGE_DEFAULT,
245af69d88dSmrg                                                 sizeof(vertices_strip),
246af69d88dSmrg                                                 vertices_strip);
2473464ebd5Sriastradh   } else {
24801e04c3fSmrg      vbuf.buffer.resource = pipe_buffer_create_with_data(ctx,
249af69d88dSmrg                                                 PIPE_BIND_VERTEX_BUFFER,
250af69d88dSmrg                                                 PIPE_USAGE_DEFAULT,
251af69d88dSmrg                                                 sizeof(vertices),
252af69d88dSmrg                                                 vertices);
2533464ebd5Sriastradh   }
2543464ebd5Sriastradh
2557ec681f3Smrg   ctx->set_vertex_buffers(ctx, 0, 1, 0, false, &vbuf);
2563464ebd5Sriastradh}
2573464ebd5Sriastradh
2583464ebd5Sriastradhstatic void set_vertex_shader( void )
2593464ebd5Sriastradh{
2603464ebd5Sriastradh   void *handle;
2613464ebd5Sriastradh   const char *text =
2623464ebd5Sriastradh      "VERT\n"
2633464ebd5Sriastradh      "DCL IN[0]\n"
2643464ebd5Sriastradh      "DCL IN[1]\n"
2653464ebd5Sriastradh      "DCL IN[2]\n"
2663464ebd5Sriastradh      "DCL IN[3]\n"
2673464ebd5Sriastradh      "DCL OUT[0], POSITION\n"
2683464ebd5Sriastradh      "DCL OUT[1], COLOR[0]\n"
2693464ebd5Sriastradh      "DCL OUT[2], GENERIC[0]\n"
2703464ebd5Sriastradh      "DCL OUT[3], GENERIC[1]\n"
2713464ebd5Sriastradh      "  MOV OUT[0], IN[0]\n"
2723464ebd5Sriastradh      "  MOV OUT[1], IN[1]\n"
2733464ebd5Sriastradh      "  MOV OUT[2], IN[2]\n"
2743464ebd5Sriastradh      "  MOV OUT[3], IN[3]\n"
2753464ebd5Sriastradh      "  END\n";
2763464ebd5Sriastradh
2773464ebd5Sriastradh   handle = graw_parse_vertex_shader(ctx, text);
2783464ebd5Sriastradh   ctx->bind_vs_state(ctx, handle);
2793464ebd5Sriastradh}
2803464ebd5Sriastradh
2813464ebd5Sriastradhstatic void set_fragment_shader( void )
2823464ebd5Sriastradh{
2833464ebd5Sriastradh   void *handle;
2843464ebd5Sriastradh   const char *text =
2853464ebd5Sriastradh      "FRAG\n"
2863464ebd5Sriastradh      "DCL IN[0], COLOR, LINEAR\n"
2873464ebd5Sriastradh      "DCL OUT[0], COLOR\n"
2883464ebd5Sriastradh      "  0: MOV OUT[0], IN[0]\n"
2893464ebd5Sriastradh      "  1: END\n";
2903464ebd5Sriastradh
2913464ebd5Sriastradh   handle = graw_parse_fragment_shader(ctx, text);
2923464ebd5Sriastradh   ctx->bind_fs_state(ctx, handle);
2933464ebd5Sriastradh}
2943464ebd5Sriastradh
2953464ebd5Sriastradh
2963464ebd5Sriastradhstatic void set_geometry_shader( void )
2973464ebd5Sriastradh{
2983464ebd5Sriastradh   FILE *f;
2993464ebd5Sriastradh   char buf[50000];
3003464ebd5Sriastradh   void *handle;
3013464ebd5Sriastradh   int sz;
3023464ebd5Sriastradh
3033464ebd5Sriastradh   if ((f = fopen(filename, "r")) == NULL) {
3043464ebd5Sriastradh      fprintf(stderr, "Couldn't open %s\n", filename);
3053464ebd5Sriastradh      exit(1);
3063464ebd5Sriastradh   }
3073464ebd5Sriastradh
3083464ebd5Sriastradh   sz = fread(buf, 1, sizeof(buf), f);
3093464ebd5Sriastradh   if (!feof(f)) {
3103464ebd5Sriastradh      printf("file too long\n");
3113464ebd5Sriastradh      exit(1);
3123464ebd5Sriastradh   }
3133464ebd5Sriastradh   printf("%.*s\n", sz, buf);
3143464ebd5Sriastradh   buf[sz] = 0;
3153464ebd5Sriastradh
3163464ebd5Sriastradh   handle = graw_parse_geometry_shader(ctx, buf);
3173464ebd5Sriastradh   ctx->bind_gs_state(ctx, handle);
3183464ebd5Sriastradh   fclose(f);
3193464ebd5Sriastradh}
3203464ebd5Sriastradh
3213464ebd5Sriastradh
3223464ebd5Sriastradhstatic void draw( void )
3233464ebd5Sriastradh{
324af69d88dSmrg   union pipe_color_union clear_color = { {.1,.3,.5,0} };
3253464ebd5Sriastradh
3267ec681f3Smrg   ctx->clear(ctx, PIPE_CLEAR_COLOR, NULL, &clear_color, 0, 0);
3273464ebd5Sriastradh   if (draw_strip)
3283464ebd5Sriastradh      util_draw_arrays(ctx, PIPE_PRIM_TRIANGLE_STRIP, 0, 4);
3293464ebd5Sriastradh   else
3303464ebd5Sriastradh      util_draw_arrays(ctx, PIPE_PRIM_TRIANGLES, 0, 3);
3313464ebd5Sriastradh
332af69d88dSmrg   ctx->flush(ctx, NULL, 0);
3333464ebd5Sriastradh
3343464ebd5Sriastradh   graw_save_surface_to_file(ctx, surf, NULL);
3353464ebd5Sriastradh
3367ec681f3Smrg   screen->flush_frontbuffer(screen, ctx, rttex, 0, 0, window, NULL);
3373464ebd5Sriastradh}
3383464ebd5Sriastradh
3393464ebd5Sriastradh#define SIZE 16
3403464ebd5Sriastradh
3413464ebd5Sriastradhstatic void init_tex( void )
3423464ebd5Sriastradh{
3433464ebd5Sriastradh   struct pipe_sampler_view sv_template;
3443464ebd5Sriastradh   struct pipe_sampler_state sampler_desc;
3453464ebd5Sriastradh   struct pipe_resource templat;
3463464ebd5Sriastradh   struct pipe_box box;
3473464ebd5Sriastradh   ubyte tex2d[SIZE][SIZE][4];
3483464ebd5Sriastradh   int s, t;
3493464ebd5Sriastradh
3503464ebd5Sriastradh#if (SIZE != 2)
3513464ebd5Sriastradh   for (s = 0; s < SIZE; s++) {
3523464ebd5Sriastradh      for (t = 0; t < SIZE; t++) {
3533464ebd5Sriastradh         if (0) {
3543464ebd5Sriastradh            int x = (s ^ t) & 1;
3553464ebd5Sriastradh	    tex2d[t][s][0] = (x) ? 0 : 63;
3563464ebd5Sriastradh	    tex2d[t][s][1] = (x) ? 0 : 128;
3573464ebd5Sriastradh	    tex2d[t][s][2] = 0;
3583464ebd5Sriastradh	    tex2d[t][s][3] = 0xff;
3593464ebd5Sriastradh         }
3603464ebd5Sriastradh         else {
3613464ebd5Sriastradh            int x = ((s ^ t) >> 2) & 1;
3623464ebd5Sriastradh	    tex2d[t][s][0] = s*255/(SIZE-1);
3633464ebd5Sriastradh	    tex2d[t][s][1] = t*255/(SIZE-1);
3643464ebd5Sriastradh	    tex2d[t][s][2] = (x) ? 0 : 128;
3653464ebd5Sriastradh	    tex2d[t][s][3] = 0xff;
3663464ebd5Sriastradh         }
3673464ebd5Sriastradh      }
3683464ebd5Sriastradh   }
3693464ebd5Sriastradh#else
3703464ebd5Sriastradh   tex2d[0][0][0] = 0;
3713464ebd5Sriastradh   tex2d[0][0][1] = 255;
3723464ebd5Sriastradh   tex2d[0][0][2] = 255;
3733464ebd5Sriastradh   tex2d[0][0][3] = 0;
3743464ebd5Sriastradh
3753464ebd5Sriastradh   tex2d[0][1][0] = 0;
3763464ebd5Sriastradh   tex2d[0][1][1] = 0;
3773464ebd5Sriastradh   tex2d[0][1][2] = 255;
3783464ebd5Sriastradh   tex2d[0][1][3] = 255;
3793464ebd5Sriastradh
3803464ebd5Sriastradh   tex2d[1][0][0] = 255;
3813464ebd5Sriastradh   tex2d[1][0][1] = 255;
3823464ebd5Sriastradh   tex2d[1][0][2] = 0;
3833464ebd5Sriastradh   tex2d[1][0][3] = 255;
3843464ebd5Sriastradh
3853464ebd5Sriastradh   tex2d[1][1][0] = 255;
3863464ebd5Sriastradh   tex2d[1][1][1] = 0;
3873464ebd5Sriastradh   tex2d[1][1][2] = 0;
3883464ebd5Sriastradh   tex2d[1][1][3] = 255;
3893464ebd5Sriastradh#endif
3903464ebd5Sriastradh
39101e04c3fSmrg   memset(&templat, 0, sizeof(templat));
3923464ebd5Sriastradh   templat.target = PIPE_TEXTURE_2D;
3933464ebd5Sriastradh   templat.format = PIPE_FORMAT_B8G8R8A8_UNORM;
3943464ebd5Sriastradh   templat.width0 = SIZE;
3953464ebd5Sriastradh   templat.height0 = SIZE;
3963464ebd5Sriastradh   templat.depth0 = 1;
3973464ebd5Sriastradh   templat.array_size = 1;
3983464ebd5Sriastradh   templat.last_level = 0;
3993464ebd5Sriastradh   templat.bind = PIPE_BIND_SAMPLER_VIEW;
4003464ebd5Sriastradh
4013464ebd5Sriastradh
4023464ebd5Sriastradh   samptex = screen->resource_create(screen,
4033464ebd5Sriastradh                                 &templat);
4043464ebd5Sriastradh   if (samptex == NULL)
4053464ebd5Sriastradh      exit(4);
4063464ebd5Sriastradh
4073464ebd5Sriastradh   u_box_2d(0,0,SIZE,SIZE, &box);
4083464ebd5Sriastradh
40901e04c3fSmrg   ctx->texture_subdata(ctx,
41001e04c3fSmrg                        samptex,
41101e04c3fSmrg                        0,
4127ec681f3Smrg                        PIPE_MAP_WRITE,
41301e04c3fSmrg                        &box,
41401e04c3fSmrg                        tex2d,
41501e04c3fSmrg                        sizeof tex2d[0],
41601e04c3fSmrg         sizeof tex2d);
4173464ebd5Sriastradh
4183464ebd5Sriastradh   /* Possibly read back & compare against original data:
4193464ebd5Sriastradh    */
4203464ebd5Sriastradh   if (0)
4213464ebd5Sriastradh   {
4223464ebd5Sriastradh      struct pipe_transfer *t;
4233464ebd5Sriastradh      uint32_t *ptr;
4247ec681f3Smrg      ptr = pipe_texture_map(ctx, samptex,
425af69d88dSmrg                              0, 0, /* level, layer */
4267ec681f3Smrg                              PIPE_MAP_READ,
427af69d88dSmrg                              0, 0, SIZE, SIZE, &t); /* x, y, width, height */
4283464ebd5Sriastradh
4293464ebd5Sriastradh      if (memcmp(ptr, tex2d, sizeof tex2d) != 0) {
4303464ebd5Sriastradh         assert(0);
4313464ebd5Sriastradh         exit(9);
4323464ebd5Sriastradh      }
4333464ebd5Sriastradh
4347ec681f3Smrg      ctx->texture_unmap(ctx, t);
4353464ebd5Sriastradh   }
4363464ebd5Sriastradh
4373464ebd5Sriastradh   memset(&sv_template, 0, sizeof sv_template);
4383464ebd5Sriastradh   sv_template.format = samptex->format;
4393464ebd5Sriastradh   sv_template.texture = samptex;
4403464ebd5Sriastradh   sv_template.swizzle_r = 0;
4413464ebd5Sriastradh   sv_template.swizzle_g = 1;
4423464ebd5Sriastradh   sv_template.swizzle_b = 2;
4433464ebd5Sriastradh   sv_template.swizzle_a = 3;
4443464ebd5Sriastradh   sv = ctx->create_sampler_view(ctx, samptex, &sv_template);
4453464ebd5Sriastradh   if (sv == NULL)
4463464ebd5Sriastradh      exit(5);
4473464ebd5Sriastradh
4487ec681f3Smrg   ctx->set_sampler_views(ctx, PIPE_SHADER_FRAGMENT, 0, 1, 0, false, &sv);
4493464ebd5Sriastradh
4503464ebd5Sriastradh
4513464ebd5Sriastradh   memset(&sampler_desc, 0, sizeof sampler_desc);
4523464ebd5Sriastradh   sampler_desc.wrap_s = PIPE_TEX_WRAP_REPEAT;
4533464ebd5Sriastradh   sampler_desc.wrap_t = PIPE_TEX_WRAP_REPEAT;
4543464ebd5Sriastradh   sampler_desc.wrap_r = PIPE_TEX_WRAP_REPEAT;
4553464ebd5Sriastradh   sampler_desc.min_img_filter = PIPE_TEX_FILTER_NEAREST;
4563464ebd5Sriastradh   sampler_desc.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
4573464ebd5Sriastradh   sampler_desc.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
4583464ebd5Sriastradh   sampler_desc.compare_mode = PIPE_TEX_COMPARE_NONE;
4593464ebd5Sriastradh   sampler_desc.compare_func = 0;
4603464ebd5Sriastradh   sampler_desc.normalized_coords = 1;
4613464ebd5Sriastradh   sampler_desc.max_anisotropy = 0;
4623464ebd5Sriastradh
4633464ebd5Sriastradh   sampler = ctx->create_sampler_state(ctx, &sampler_desc);
4643464ebd5Sriastradh   if (sampler == NULL)
4653464ebd5Sriastradh      exit(6);
4663464ebd5Sriastradh
467af69d88dSmrg   ctx->bind_sampler_states(ctx, PIPE_SHADER_FRAGMENT, 0, 1, &sampler);
4683464ebd5Sriastradh
4693464ebd5Sriastradh}
4703464ebd5Sriastradh
4713464ebd5Sriastradhstatic void init( void )
4723464ebd5Sriastradh{
4733464ebd5Sriastradh   struct pipe_framebuffer_state fb;
4743464ebd5Sriastradh   struct pipe_resource templat;
4753464ebd5Sriastradh   struct pipe_surface surf_tmpl;
4763464ebd5Sriastradh   int i;
4773464ebd5Sriastradh
4783464ebd5Sriastradh   /* It's hard to say whether window or screen should be created
4793464ebd5Sriastradh    * first.  Different environments would prefer one or the other.
4803464ebd5Sriastradh    *
4813464ebd5Sriastradh    * Also, no easy way of querying supported formats if the screen
4823464ebd5Sriastradh    * cannot be created first.
4833464ebd5Sriastradh    */
4843464ebd5Sriastradh   for (i = 0; formats[i] != PIPE_FORMAT_NONE; i++) {
4853464ebd5Sriastradh      screen = graw_create_window_and_screen(0, 0, 300, 300,
4863464ebd5Sriastradh                                             formats[i],
4873464ebd5Sriastradh                                             &window);
4883464ebd5Sriastradh      if (window && screen)
4893464ebd5Sriastradh         break;
4903464ebd5Sriastradh   }
4913464ebd5Sriastradh   if (!screen || !window) {
4923464ebd5Sriastradh      fprintf(stderr, "Unable to create window\n");
4933464ebd5Sriastradh      exit(1);
4943464ebd5Sriastradh   }
4953464ebd5Sriastradh
49601e04c3fSmrg   ctx = screen->context_create(screen, NULL, 0);
4973464ebd5Sriastradh   if (ctx == NULL)
4983464ebd5Sriastradh      exit(3);
4993464ebd5Sriastradh
50001e04c3fSmrg   memset(&templat, 0, sizeof(templat));
5013464ebd5Sriastradh   templat.target = PIPE_TEXTURE_2D;
5023464ebd5Sriastradh   templat.format = formats[i];
5033464ebd5Sriastradh   templat.width0 = WIDTH;
5043464ebd5Sriastradh   templat.height0 = HEIGHT;
5053464ebd5Sriastradh   templat.depth0 = 1;
5063464ebd5Sriastradh   templat.array_size = 1;
5073464ebd5Sriastradh   templat.last_level = 0;
5083464ebd5Sriastradh   templat.bind = (PIPE_BIND_RENDER_TARGET |
5093464ebd5Sriastradh                   PIPE_BIND_DISPLAY_TARGET);
5103464ebd5Sriastradh
5113464ebd5Sriastradh   rttex = screen->resource_create(screen,
5123464ebd5Sriastradh                                 &templat);
5133464ebd5Sriastradh   if (rttex == NULL)
5143464ebd5Sriastradh      exit(4);
5153464ebd5Sriastradh
5163464ebd5Sriastradh   surf_tmpl.format = templat.format;
5173464ebd5Sriastradh   surf_tmpl.u.tex.level = 0;
5183464ebd5Sriastradh   surf_tmpl.u.tex.first_layer = 0;
5193464ebd5Sriastradh   surf_tmpl.u.tex.last_layer = 0;
5203464ebd5Sriastradh   surf = ctx->create_surface(ctx, rttex, &surf_tmpl);
5213464ebd5Sriastradh   if (surf == NULL)
5223464ebd5Sriastradh      exit(5);
5233464ebd5Sriastradh
5243464ebd5Sriastradh   memset(&fb, 0, sizeof fb);
5253464ebd5Sriastradh   fb.nr_cbufs = 1;
5263464ebd5Sriastradh   fb.width = WIDTH;
5273464ebd5Sriastradh   fb.height = HEIGHT;
5283464ebd5Sriastradh   fb.cbufs[0] = surf;
5293464ebd5Sriastradh
5303464ebd5Sriastradh   ctx->set_framebuffer_state(ctx, &fb);
5313464ebd5Sriastradh
5323464ebd5Sriastradh   {
5333464ebd5Sriastradh      struct pipe_blend_state blend;
5343464ebd5Sriastradh      void *handle;
5353464ebd5Sriastradh      memset(&blend, 0, sizeof blend);
5363464ebd5Sriastradh      blend.rt[0].colormask = PIPE_MASK_RGBA;
5373464ebd5Sriastradh      handle = ctx->create_blend_state(ctx, &blend);
5383464ebd5Sriastradh      ctx->bind_blend_state(ctx, handle);
5393464ebd5Sriastradh   }
5403464ebd5Sriastradh
5413464ebd5Sriastradh   {
5423464ebd5Sriastradh      struct pipe_depth_stencil_alpha_state depthstencil;
5433464ebd5Sriastradh      void *handle;
5443464ebd5Sriastradh      memset(&depthstencil, 0, sizeof depthstencil);
5453464ebd5Sriastradh      handle = ctx->create_depth_stencil_alpha_state(ctx, &depthstencil);
5463464ebd5Sriastradh      ctx->bind_depth_stencil_alpha_state(ctx, handle);
5473464ebd5Sriastradh   }
5483464ebd5Sriastradh
5493464ebd5Sriastradh   {
5503464ebd5Sriastradh      struct pipe_rasterizer_state rasterizer;
5513464ebd5Sriastradh      void *handle;
5523464ebd5Sriastradh      memset(&rasterizer, 0, sizeof rasterizer);
5533464ebd5Sriastradh      rasterizer.cull_face = PIPE_FACE_NONE;
554af69d88dSmrg      rasterizer.half_pixel_center = 1;
555af69d88dSmrg      rasterizer.bottom_edge_rule = 1;
55601e04c3fSmrg      rasterizer.depth_clip_near = 1;
55701e04c3fSmrg      rasterizer.depth_clip_far = 1;
5583464ebd5Sriastradh      handle = ctx->create_rasterizer_state(ctx, &rasterizer);
5593464ebd5Sriastradh      ctx->bind_rasterizer_state(ctx, handle);
5603464ebd5Sriastradh   }
5613464ebd5Sriastradh
5623464ebd5Sriastradh   set_viewport(0, 0, WIDTH, HEIGHT, 30, 1000);
5633464ebd5Sriastradh
5643464ebd5Sriastradh   init_tex();
5653464ebd5Sriastradh   init_fs_constbuf();
5663464ebd5Sriastradh
5673464ebd5Sriastradh   set_vertices();
5683464ebd5Sriastradh   set_vertex_shader();
5693464ebd5Sriastradh   set_fragment_shader();
5703464ebd5Sriastradh   set_geometry_shader();
5713464ebd5Sriastradh}
5723464ebd5Sriastradh
5733464ebd5Sriastradhstatic void args(int argc, char *argv[])
5743464ebd5Sriastradh{
5753464ebd5Sriastradh   int i;
5763464ebd5Sriastradh
5773464ebd5Sriastradh   for (i = 1; i < argc;) {
5783464ebd5Sriastradh      if (graw_parse_args(&i, argc, argv)) {
5793464ebd5Sriastradh         continue;
5803464ebd5Sriastradh      }
5813464ebd5Sriastradh      if (strcmp(argv[i], "-fps") == 0) {
5823464ebd5Sriastradh         show_fps = 1;
5833464ebd5Sriastradh         i++;
5843464ebd5Sriastradh      }
5853464ebd5Sriastradh      else if (strcmp(argv[i], "-strip") == 0) {
5863464ebd5Sriastradh         draw_strip = 1;
5873464ebd5Sriastradh         i++;
5883464ebd5Sriastradh      }
5893464ebd5Sriastradh      else if (i == argc - 1) {
5903464ebd5Sriastradh         filename = argv[i];
5913464ebd5Sriastradh         i++;
5923464ebd5Sriastradh      }
5933464ebd5Sriastradh      else {
5943464ebd5Sriastradh         usage(argv[0]);
5953464ebd5Sriastradh         exit(1);
5963464ebd5Sriastradh      }
5973464ebd5Sriastradh   }
5983464ebd5Sriastradh
5993464ebd5Sriastradh   if (!filename) {
6003464ebd5Sriastradh      usage(argv[0]);
6013464ebd5Sriastradh      exit(1);
6023464ebd5Sriastradh   }
6033464ebd5Sriastradh}
6043464ebd5Sriastradh
6053464ebd5Sriastradhint main( int argc, char *argv[] )
6063464ebd5Sriastradh{
6073464ebd5Sriastradh   args(argc,argv);
6083464ebd5Sriastradh   init();
6093464ebd5Sriastradh
6103464ebd5Sriastradh   graw_set_display_func( draw );
6113464ebd5Sriastradh   graw_main_loop();
6123464ebd5Sriastradh   return 0;
6133464ebd5Sriastradh}
614