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