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