graw/tests: pass -e option to test draw_elements_instanced()
[mesa.git] / src / gallium / tests / graw / quad-tex.c
1 /* Display a cleared blue window. This demo has no dependencies on
2 * any utility code, just the graw interface and gallium.
3 */
4
5 #include "state_tracker/graw.h"
6 #include "pipe/p_screen.h"
7 #include "pipe/p_context.h"
8 #include "pipe/p_shader_tokens.h"
9 #include "pipe/p_state.h"
10 #include "pipe/p_defines.h"
11
12 #include "util/u_debug.h" /* debug_dump_surface_bmp() */
13 #include "util/u_inlines.h"
14 #include "util/u_memory.h" /* Offset() */
15 #include "util/u_box.h"
16
17 enum pipe_format formats[] = {
18 PIPE_FORMAT_R8G8B8A8_UNORM,
19 PIPE_FORMAT_B8G8R8A8_UNORM,
20 PIPE_FORMAT_NONE
21 };
22
23 static const int WIDTH = 300;
24 static const int HEIGHT = 300;
25
26 static struct pipe_screen *screen = NULL;
27 static struct pipe_context *ctx = NULL;
28 static struct pipe_resource *rttex = NULL;
29 static struct pipe_resource *samptex = NULL;
30 static struct pipe_surface *surf = NULL;
31 static struct pipe_sampler_view *sv = NULL;
32 static void *sampler = NULL;
33 static void *window = NULL;
34
35 struct vertex {
36 float position[4];
37 float color[4];
38 };
39
40 static struct vertex vertices[] =
41 {
42 { { 0.9, -0.9, 0.0, 1.0 },
43 { 1, 0, 0, 1 } },
44
45 { { 0.9, 0.9, 0.0, 1.0 },
46 { 1, 1, 0, 1 } },
47
48 { {-0.9, 0.9, 0.0, 1.0 },
49 { 0, 1, 0, 1 } },
50
51 { {-0.9, -0.9, 0.0, 1.0 },
52 { 0, 0, 0, 1 } },
53 };
54
55
56
57
58 static void set_viewport( float x, float y,
59 float width, float height,
60 float near, float far)
61 {
62 float z = far;
63 float half_width = (float)width / 2.0f;
64 float half_height = (float)height / 2.0f;
65 float half_depth = ((float)far - (float)near) / 2.0f;
66 struct pipe_viewport_state vp;
67
68 vp.scale[0] = half_width;
69 vp.scale[1] = half_height;
70 vp.scale[2] = half_depth;
71 vp.scale[3] = 1.0f;
72
73 vp.translate[0] = half_width + x;
74 vp.translate[1] = half_height + y;
75 vp.translate[2] = half_depth + z;
76 vp.translate[3] = 0.0f;
77
78 ctx->set_viewport_state( ctx, &vp );
79 }
80
81 static void set_vertices( void )
82 {
83 struct pipe_vertex_element ve[2];
84 struct pipe_vertex_buffer vbuf;
85 void *handle;
86
87 memset(ve, 0, sizeof ve);
88
89 ve[0].src_offset = Offset(struct vertex, position);
90 ve[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
91 ve[1].src_offset = Offset(struct vertex, color);
92 ve[1].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
93
94 handle = ctx->create_vertex_elements_state(ctx, 2, ve);
95 ctx->bind_vertex_elements_state(ctx, handle);
96
97
98 vbuf.stride = sizeof( struct vertex );
99 vbuf.max_index = sizeof(vertices) / vbuf.stride;
100 vbuf.buffer_offset = 0;
101 vbuf.buffer = screen->user_buffer_create(screen,
102 vertices,
103 sizeof(vertices),
104 PIPE_BIND_VERTEX_BUFFER);
105
106 ctx->set_vertex_buffers(ctx, 1, &vbuf);
107 }
108
109 static void set_vertex_shader( void )
110 {
111 void *handle;
112 const char *text =
113 "VERT\n"
114 "DCL IN[0]\n"
115 "DCL IN[1]\n"
116 "DCL OUT[0], POSITION\n"
117 "DCL OUT[1], GENERIC[0]\n"
118 " 0: MOV OUT[1], IN[1]\n"
119 " 1: MOV OUT[0], IN[0]\n"
120 " 2: END\n";
121
122 handle = graw_parse_vertex_shader(ctx, text);
123 ctx->bind_vs_state(ctx, handle);
124 }
125
126 static void set_fragment_shader( void )
127 {
128 void *handle;
129 const char *text =
130 "FRAG\n"
131 "DCL IN[0], GENERIC[0], PERSPECTIVE\n"
132 "DCL OUT[0], COLOR\n"
133 "DCL TEMP[0]\n"
134 "DCL SAMP[0]\n"
135 " 0: TXP TEMP[0], IN[0], SAMP[0], 2D\n"
136 " 1: MOV OUT[0], TEMP[0]\n"
137 " 2: END\n";
138
139 handle = graw_parse_fragment_shader(ctx, text);
140 ctx->bind_fs_state(ctx, handle);
141 }
142
143
144 static void draw( void )
145 {
146 float clear_color[4] = {.5,.5,.5,1};
147
148 ctx->clear(ctx, PIPE_CLEAR_COLOR, clear_color, 0, 0);
149 ctx->draw_arrays(ctx, PIPE_PRIM_QUADS, 0, 4);
150 ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL);
151
152 #if 0
153 /* At the moment, libgraw leaks out/makes available some of the
154 * symbols from gallium/auxiliary, including these debug helpers.
155 * Will eventually want to bless some of these paths, and lock the
156 * others down so they aren't accessible from test programs.
157 *
158 * This currently just happens to work on debug builds - a release
159 * build will probably fail to link here:
160 */
161 debug_dump_surface_bmp(ctx, "result.bmp", surf);
162 #endif
163
164 screen->flush_frontbuffer(screen, surf, window);
165 }
166
167 #define SIZE 16
168
169 static void init_tex( void )
170 {
171 struct pipe_sampler_view sv_template;
172 struct pipe_sampler_state sampler_desc;
173 struct pipe_resource templat;
174 struct pipe_box box;
175 ubyte tex2d[SIZE][SIZE][4];
176 int s, t;
177
178 #if (SIZE != 2)
179 for (s = 0; s < SIZE; s++) {
180 for (t = 0; t < SIZE; t++) {
181 if (0) {
182 int x = (s ^ t) & 1;
183 tex2d[t][s][0] = (x) ? 0 : 63;
184 tex2d[t][s][1] = (x) ? 0 : 128;
185 tex2d[t][s][2] = 0;
186 tex2d[t][s][3] = 0xff;
187 }
188 else {
189 int x = ((s ^ t) >> 2) & 1;
190 tex2d[t][s][0] = s*255/(SIZE-1);
191 tex2d[t][s][1] = t*255/(SIZE-1);
192 tex2d[t][s][2] = (x) ? 0 : 128;
193 tex2d[t][s][3] = 0xff;
194 }
195 }
196 }
197 #else
198 tex2d[0][0][0] = 0;
199 tex2d[0][0][1] = 255;
200 tex2d[0][0][2] = 255;
201 tex2d[0][0][3] = 0;
202
203 tex2d[0][1][0] = 0;
204 tex2d[0][1][1] = 0;
205 tex2d[0][1][2] = 255;
206 tex2d[0][1][3] = 255;
207
208 tex2d[1][0][0] = 255;
209 tex2d[1][0][1] = 255;
210 tex2d[1][0][2] = 0;
211 tex2d[1][0][3] = 255;
212
213 tex2d[1][1][0] = 255;
214 tex2d[1][1][1] = 0;
215 tex2d[1][1][2] = 0;
216 tex2d[1][1][3] = 255;
217 #endif
218
219 templat.target = PIPE_TEXTURE_2D;
220 templat.format = PIPE_FORMAT_B8G8R8A8_UNORM;
221 templat.width0 = SIZE;
222 templat.height0 = SIZE;
223 templat.depth0 = 1;
224 templat.last_level = 0;
225 templat.nr_samples = 1;
226 templat.bind = PIPE_BIND_SAMPLER_VIEW;
227
228
229 samptex = screen->resource_create(screen,
230 &templat);
231 if (samptex == NULL)
232 exit(4);
233
234 u_box_2d(0,0,SIZE,SIZE, &box);
235
236 ctx->transfer_inline_write(ctx,
237 samptex,
238 u_subresource(0,0),
239 PIPE_TRANSFER_WRITE,
240 &box,
241 tex2d,
242 sizeof tex2d[0],
243 sizeof tex2d);
244
245 /* Possibly read back & compare against original data:
246 */
247 if (0)
248 {
249 struct pipe_transfer *t;
250 uint32_t *ptr;
251 t = pipe_get_transfer(ctx, samptex,
252 0, 0, 0, /* face, level, zslice */
253 PIPE_TRANSFER_READ,
254 0, 0, SIZE, SIZE); /* x, y, width, height */
255
256 ptr = ctx->transfer_map(ctx, t);
257
258 if (memcmp(ptr, tex2d, sizeof tex2d) != 0) {
259 assert(0);
260 exit(9);
261 }
262
263 ctx->transfer_unmap(ctx, t);
264
265 ctx->transfer_destroy(ctx, t);
266 }
267
268 memset(&sv_template, 0, sizeof sv_template);
269 sv_template.format = samptex->format;
270 sv_template.texture = samptex;
271 sv_template.first_level = 0;
272 sv_template.last_level = 0;
273 sv_template.swizzle_r = 0;
274 sv_template.swizzle_g = 1;
275 sv_template.swizzle_b = 2;
276 sv_template.swizzle_a = 3;
277 sv = ctx->create_sampler_view(ctx, samptex, &sv_template);
278 if (sv == NULL)
279 exit(5);
280
281 ctx->set_fragment_sampler_views(ctx, 1, &sv);
282
283
284 memset(&sampler_desc, 0, sizeof sampler_desc);
285 sampler_desc.wrap_s = PIPE_TEX_WRAP_REPEAT;
286 sampler_desc.wrap_t = PIPE_TEX_WRAP_REPEAT;
287 sampler_desc.wrap_r = PIPE_TEX_WRAP_REPEAT;
288 sampler_desc.min_img_filter = PIPE_TEX_FILTER_NEAREST;
289 sampler_desc.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
290 sampler_desc.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
291 sampler_desc.compare_mode = PIPE_TEX_COMPARE_NONE;
292 sampler_desc.compare_func = 0;
293 sampler_desc.normalized_coords = 1;
294 sampler_desc.max_anisotropy = 0;
295
296 sampler = ctx->create_sampler_state(ctx, &sampler_desc);
297 if (sampler == NULL)
298 exit(6);
299
300 ctx->bind_fragment_sampler_states(ctx, 1, &sampler);
301
302 }
303
304 static void init( void )
305 {
306 struct pipe_framebuffer_state fb;
307 struct pipe_resource templat;
308 int i;
309
310 /* It's hard to say whether window or screen should be created
311 * first. Different environments would prefer one or the other.
312 *
313 * Also, no easy way of querying supported formats if the screen
314 * cannot be created first.
315 */
316 for (i = 0;
317 window == NULL && formats[i] != PIPE_FORMAT_NONE;
318 i++) {
319
320 screen = graw_create_window_and_screen(0,0,300,300,
321 formats[i],
322 &window);
323 }
324
325 ctx = screen->context_create(screen, NULL);
326 if (ctx == NULL)
327 exit(3);
328
329 templat.target = PIPE_TEXTURE_2D;
330 templat.format = formats[i];
331 templat.width0 = WIDTH;
332 templat.height0 = HEIGHT;
333 templat.depth0 = 1;
334 templat.last_level = 0;
335 templat.nr_samples = 1;
336 templat.bind = (PIPE_BIND_RENDER_TARGET |
337 PIPE_BIND_DISPLAY_TARGET);
338
339 rttex = screen->resource_create(screen,
340 &templat);
341 if (rttex == NULL)
342 exit(4);
343
344 surf = screen->get_tex_surface(screen, rttex, 0, 0, 0,
345 PIPE_BIND_RENDER_TARGET |
346 PIPE_BIND_DISPLAY_TARGET);
347 if (surf == NULL)
348 exit(5);
349
350 memset(&fb, 0, sizeof fb);
351 fb.nr_cbufs = 1;
352 fb.width = WIDTH;
353 fb.height = HEIGHT;
354 fb.cbufs[0] = surf;
355
356 ctx->set_framebuffer_state(ctx, &fb);
357
358 {
359 struct pipe_blend_state blend;
360 void *handle;
361 memset(&blend, 0, sizeof blend);
362 blend.rt[0].colormask = PIPE_MASK_RGBA;
363 handle = ctx->create_blend_state(ctx, &blend);
364 ctx->bind_blend_state(ctx, handle);
365 }
366
367 {
368 struct pipe_depth_stencil_alpha_state depthstencil;
369 void *handle;
370 memset(&depthstencil, 0, sizeof depthstencil);
371 handle = ctx->create_depth_stencil_alpha_state(ctx, &depthstencil);
372 ctx->bind_depth_stencil_alpha_state(ctx, handle);
373 }
374
375 {
376 struct pipe_rasterizer_state rasterizer;
377 void *handle;
378 memset(&rasterizer, 0, sizeof rasterizer);
379 rasterizer.cull_face = PIPE_FACE_NONE;
380 rasterizer.gl_rasterization_rules = 1;
381 handle = ctx->create_rasterizer_state(ctx, &rasterizer);
382 ctx->bind_rasterizer_state(ctx, handle);
383 }
384
385 set_viewport(0, 0, WIDTH, HEIGHT, 30, 1000);
386
387 init_tex();
388
389 set_vertices();
390 set_vertex_shader();
391 set_fragment_shader();
392 }
393
394
395 int main( int argc, char *argv[] )
396 {
397 init();
398
399 graw_set_display_func( draw );
400 graw_main_loop();
401 return 0;
402 }