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, 0, false, &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              NULL,
189              &clear_color, 1.0, 0);
190   util_draw_arrays(info.ctx, PIPE_PRIM_QUADS, 0, NUM_VERTS);
191   info.ctx->flush(info.ctx, NULL, 0);
192
193#if 0
194   /* At the moment, libgraw leaks out/makes available some of the
195    * symbols from gallium/auxiliary, including these debug helpers.
196    * Will eventually want to bless some of these paths, and lock the
197    * others down so they aren't accessible from test programs.
198    *
199    * This currently just happens to work on debug builds - a release
200    * build will probably fail to link here:
201    */
202   debug_dump_surface_bmp(info.ctx, "result.bmp", surf);
203#endif
204
205   graw_util_flush_front(&info);
206}
207
208
209#if 0
210static void
211resize(int w, int h)
212{
213   width = w;
214   height = h;
215
216   set_viewport(0, 0, width, height, 30, 1000);
217}
218#endif
219
220
221static void
222init(int mode)
223{
224   if (!graw_util_create_window(&info, width, height, 1, TRUE))
225      exit(1);
226
227   graw_util_default_state(&info, TRUE);
228
229   graw_util_viewport(&info, 0, 0, width, height, -1.0, 1.0);
230
231   set_vertices();
232   set_vertex_shader();
233   set_fragment_shader(mode);
234}
235
236
237int
238main(int argc, char *argv[])
239{
240   int mode = argc > 1 ? atoi(argv[1]) : 0;
241
242   switch (mode) {
243   default:
244   case 0:
245      printf("frag coord origin upper-left (lower-left = black)\n");
246      break;
247   case 1:
248      printf("frag coord origin lower-left (upper-left = black)\n");
249      break;
250   case 2:
251      printf("frag coord center integer (all pixels black)\n");
252      break;
253   case 3:
254      printf("frag coord center half-integer (all pixels olive color)\n");
255      break;
256   }
257
258   init(mode);
259
260   graw_set_display_func(draw);
261   /*graw_set_reshape_func(resize);*/
262   graw_main_loop();
263   return 0;
264}
265