1/* Test the TGSI_SEMANTIC_POSITION fragment shader input.
2 * Plus properties for upper-left vs. lower-left origin and
3 * center integer vs. half-integer;
4 */
5
6#include <stdio.h>
7
8#include "graw_util.h"
9
10
11static int width = 300;
12static int height = 300;
13
14static struct graw_info info;
15
16struct vertex {
17   float position[4];
18   float color[4];
19};
20
21/* Note: the upper-left vertex is pushed to the left a bit to
22 * make sure we can spot upside-down rendering.
23 */
24static struct vertex vertices[] =
25{
26   {
27      {-0.95, -0.95, 0.5, 1.0 },
28      { 0, 0, 0, 1 }
29   },
30
31   {
32      { 0.85, -0.95, 0.5, 1.0 },
33      { 0, 0, 0, 1 }
34   },
35
36   {
37      { 0.95,  0.95, 0.5, 1.0 },
38      { 0, 0, 0, 1 }
39   },
40
41   {
42      {-0.95,  0.95, 0.5, 1.0 },
43      { 0, 0, 0, 1 }
44   }
45};
46
47#define NUM_VERTS (sizeof(vertices) / sizeof(vertices[0]))
48
49
50static void
51set_vertices(void)
52{
53   struct pipe_vertex_element ve[2];
54   struct pipe_vertex_buffer vbuf;
55   void *handle;
56
57   memset(ve, 0, sizeof ve);
58
59   ve[0].src_offset = Offset(struct vertex, position);
60   ve[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
61   ve[1].src_offset = Offset(struct vertex, color);
62   ve[1].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
63
64   handle = info.ctx->create_vertex_elements_state(info.ctx, 2, ve);
65   info.ctx->bind_vertex_elements_state(info.ctx, handle);
66
67
68   vbuf.stride = sizeof(struct vertex);
69   vbuf.buffer_offset = 0;
70   vbuf.buffer = pipe_buffer_create_with_data(info.ctx,
71                                              PIPE_BIND_VERTEX_BUFFER,
72                                              PIPE_USAGE_STATIC,
73                                              sizeof(vertices),
74                                              vertices);
75
76   info.ctx->set_vertex_buffers(info.ctx, 1, &vbuf);
77}
78
79
80static void
81set_vertex_shader(void)
82{
83   void *handle;
84   const char *text =
85      "VERT\n"
86      "DCL IN[0]\n"
87      "DCL IN[1]\n"
88      "DCL OUT[0], POSITION\n"
89      "DCL OUT[1], GENERIC[0]\n"
90      "  0: MOV OUT[0], IN[0]\n"
91      "  1: MOV OUT[1], IN[1]\n"
92      "  2: END\n";
93
94   handle = graw_parse_vertex_shader(info.ctx, text);
95   info.ctx->bind_vs_state(info.ctx, handle);
96}
97
98
99static void
100set_fragment_shader(int mode)
101{
102   void *handle;
103
104   const char *origin_upper_left_text =
105      "FRAG\n"
106      "PROPERTY FS_COORD_ORIGIN UPPER_LEFT\n"  /* upper-left = black corner */
107      "DCL IN[0], POSITION, LINEAR\n"
108      "DCL OUT[0], COLOR\n"
109      "DCL TEMP[0]\n"
110      "IMM FLT32 { 0.003333, 0.003333, 1.0, 1.0 }\n"
111      "IMM FLT32 { 0.0, 300.0, 0.0, 0.0 }\n"
112      " 0: MOV TEMP[0], IN[0] \n"
113      " 1: MOV TEMP[0].zw, IMM[1].xxxx \n"
114      " 2: MUL OUT[0], TEMP[0], IMM[0] \n"
115      " 3: END\n";
116
117   const char *origin_lower_left_text =
118      "FRAG\n"
119      "PROPERTY FS_COORD_ORIGIN LOWER_LEFT\n"  /* lower-left = black corner */
120      "DCL IN[0], POSITION, LINEAR\n"
121      "DCL OUT[0], COLOR\n"
122      "DCL TEMP[0]\n"
123      "IMM FLT32 { 0.003333, 0.003333, 1.0, 1.0 }\n"
124      "IMM FLT32 { 0.0, 300.0, 0.0, 0.0 }\n"
125      " 0: MOV TEMP[0], IN[0] \n"
126      " 1: MOV TEMP[0].zw, IMM[1].xxxx \n"
127      " 2: MUL OUT[0], TEMP[0], IMM[0] \n"
128      " 3: END\n";
129
130   /* Test fragcoord center integer vs. half integer */
131   const char *center_integer_text =
132      "FRAG\n"
133      "PROPERTY FS_COORD_PIXEL_CENTER INTEGER \n"       /* pixels are black */
134      "DCL IN[0], POSITION, LINEAR \n"
135      "DCL OUT[0], COLOR \n"
136      "DCL TEMP[0] \n"
137      "IMM FLT32 { 0.003333, 0.003333, 1.0, 1.0 } \n"
138      "IMM FLT32 { 0.0, 300.0, 0.0, 0.0 } \n"
139      "0: FRC TEMP[0], IN[0]  \n"
140      "1: MOV TEMP[0].zw, IMM[1].xxxx \n"
141      "2: MOV OUT[0], TEMP[0] \n"
142      "3: END \n";
143
144   const char *center_half_integer_text =
145      "FRAG\n"
146      "PROPERTY FS_COORD_PIXEL_CENTER HALF_INTEGER \n"  /* pixels are olive colored */
147      "DCL IN[0], POSITION, LINEAR \n"
148      "DCL OUT[0], COLOR \n"
149      "DCL TEMP[0] \n"
150      "IMM FLT32 { 0.003333, 0.003333, 1.0, 1.0 } \n"
151      "IMM FLT32 { 0.0, 300.0, 0.0, 0.0 } \n"
152      "0: FRC TEMP[0], IN[0]  \n"
153      "1: MOV TEMP[0].zw, IMM[1].xxxx \n"
154      "2: MOV OUT[0], TEMP[0] \n"
155      "3: END \n";
156
157   const char *text;
158
159   if (mode == 0)
160      text = origin_upper_left_text;
161   else if (mode == 1)
162      text = origin_lower_left_text;
163   else if (mode == 2)
164      text = center_integer_text;
165   else
166      text = center_half_integer_text;
167
168   handle = graw_parse_fragment_shader(info.ctx, text);
169   info.ctx->bind_fs_state(info.ctx, handle);
170}
171
172
173static void
174draw(void)
175{
176   union pipe_color_union clear_color;
177
178   clear_color.f[0] = 0.25;
179   clear_color.f[1] = 0.25;
180   clear_color.f[2] = 0.25;
181   clear_color.f[3] = 1.0;
182
183   info.ctx->clear(info.ctx,
184              PIPE_CLEAR_COLOR | PIPE_CLEAR_DEPTHSTENCIL,
185              &clear_color, 1.0, 0);
186   util_draw_arrays(info.ctx, PIPE_PRIM_QUADS, 0, NUM_VERTS);
187   info.ctx->flush(info.ctx, NULL);
188
189#if 0
190   /* At the moment, libgraw leaks out/makes available some of the
191    * symbols from gallium/auxiliary, including these debug helpers.
192    * Will eventually want to bless some of these paths, and lock the
193    * others down so they aren't accessible from test programs.
194    *
195    * This currently just happens to work on debug builds - a release
196    * build will probably fail to link here:
197    */
198   debug_dump_surface_bmp(info.ctx, "result.bmp", surf);
199#endif
200
201   graw_util_flush_front(&info);
202}
203
204
205#if 0
206static void
207resize(int w, int h)
208{
209   width = w;
210   height = h;
211
212   set_viewport(0, 0, width, height, 30, 1000);
213}
214#endif
215
216
217static void
218init(int mode)
219{
220   if (!graw_util_create_window(&info, width, height, 1, TRUE))
221      exit(1);
222
223   graw_util_default_state(&info, TRUE);
224
225   graw_util_viewport(&info, 0, 0, width, height, -1.0, 1.0);
226
227   set_vertices();
228   set_vertex_shader();
229   set_fragment_shader(mode);
230}
231
232
233int
234main(int argc, char *argv[])
235{
236   int mode = argc > 1 ? atoi(argv[1]) : 0;
237
238   switch (mode) {
239   default:
240   case 0:
241      printf("frag coord origin upper-left (lower-left = black)\n");
242      break;
243   case 1:
244      printf("frag coord origin lower-left (upper-left = black)\n");
245      break;
246   case 2:
247      printf("frag coord center integer (all pixels black)\n");
248      break;
249   case 3:
250      printf("frag coord center half-integer (all pixels olive color)\n");
251      break;
252   }
253
254   init(mode);
255
256   graw_set_display_func(draw);
257   /*graw_set_reshape_func(resize);*/
258   graw_main_loop();
259   return 0;
260}
261