Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/tests/graw/gs-test.c
4565 views
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 "frontend/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
#include <stdio.h> /* for fread(), etc */
12
13
#include "util/u_inlines.h"
14
#include "util/u_memory.h" /* Offset() */
15
#include "util/u_draw_quad.h"
16
#include "util/u_box.h"
17
18
static const char *filename = NULL;
19
unsigned show_fps = 0;
20
unsigned draw_strip = 0;
21
22
23
static void usage(char *name)
24
{
25
fprintf(stderr, "usage: %s [ options ] shader_filename\n", name);
26
#ifndef _WIN32
27
fprintf(stderr, "\n" );
28
fprintf(stderr, "options:\n");
29
fprintf(stderr, " -fps show frames per second\n");
30
fprintf(stderr, " -strip renders a triangle strip\n");
31
#endif
32
}
33
34
35
enum pipe_format formats[] = {
36
PIPE_FORMAT_R8G8B8A8_UNORM,
37
PIPE_FORMAT_B8G8R8A8_UNORM,
38
PIPE_FORMAT_NONE
39
};
40
41
static const int WIDTH = 250;
42
static const int HEIGHT = 250;
43
44
static struct pipe_screen *screen = NULL;
45
static struct pipe_context *ctx = NULL;
46
static struct pipe_resource *rttex = NULL;
47
static struct pipe_resource *constbuf1 = NULL;
48
static struct pipe_resource *constbuf2 = NULL;
49
static struct pipe_surface *surf = NULL;
50
static struct pipe_sampler_view *sv = NULL;
51
static void *sampler = NULL;
52
static void *window = NULL;
53
static struct pipe_resource *samptex = NULL;
54
55
struct vertex {
56
float position[4];
57
float color[4];
58
float texcoord[4];
59
float generic[4];
60
};
61
62
/* Vertex data matches progs/fp/fp-tri.c, but flipped in Y dimension
63
* so that the final images are the same.
64
*/
65
static struct vertex vertices[] =
66
{
67
{ { 0.9, 0.9, 0.0, 1.0 },
68
{ 0, 0, 1, 1 },
69
{ 1, 1, 0, 1 },
70
{ 1, 0, 1, 0 }
71
},
72
73
{ { 0.9, -0.9, 0.0, 1.0 },
74
{ 1, 0, 0, 1 },
75
{ 1, -1, 0, 1 },
76
{ 0, 1, 0, 1 }
77
},
78
79
{ {-0.9, 0.0, 0.0, 1.0 },
80
{ 0, 1, 0, 1 },
81
{ -1, 0, 0, 1 },
82
{ 0, 0, 1, 1 }
83
},
84
};
85
86
static struct vertex vertices_strip[] =
87
{
88
{ { 0.9, 0.9, 0.0, 1.0 },
89
{ 0, 0, 1, 1 },
90
{ 1, 1, 0, 1 },
91
{ 1, 0, 0, 1 }
92
},
93
94
{ { 0.9, -0.9, 0.0, 1.0 },
95
{ 1, 0, 0, 1 },
96
{ 1, -1, 0, 1 },
97
{ 0, 1, 0, 1 }
98
},
99
100
{ {-0.9, 0.9, 0.0, 1.0 },
101
{ 0, 1, 0, 1 },
102
{ -1, 1, 0, 1 },
103
{ 0, 0, 1, 1 }
104
},
105
106
{ {-0.9, -0.9, 0.0, 1.0 },
107
{ 1, 1, 0, 1 },
108
{ -1, -1, 0, 1 },
109
{ 1, 1, 0, 1 }
110
},
111
};
112
113
static float constants1[] =
114
{ 0.4, 0, 0, 1,
115
1, 1, 1, 1,
116
2, 2, 2, 2,
117
4, 8, 16, 32,
118
119
3, 0, 0, 0,
120
0, .5, 0, 0,
121
0, 0, 1, 0,
122
0, 0, 0, 1,
123
124
1, 0, 0, 0.5,
125
0, 1, 0, 0.5,
126
0, 0, 1, 0,
127
0, 0, 0, 1,
128
};
129
130
131
static float constants2[] =
132
{ 1, 0, 0, 1,
133
0, 1, 0, 1,
134
0, 0, 1, 1,
135
0, 0, 0, 1,
136
137
1, 1, 0, 1,
138
1, .5, 0, 1,
139
0, 1, 1, 1,
140
1, 0, 1, 1,
141
142
1, 0, 0, 0.5,
143
0, 1, 0, 0.5,
144
0, 0, 1, 0,
145
0, 0, 0, 1,
146
};
147
148
149
static void init_fs_constbuf( void )
150
{
151
struct pipe_resource templat;
152
153
memset(&templat, 0, sizeof(templat));
154
templat.target = PIPE_BUFFER;
155
templat.format = PIPE_FORMAT_R8_UNORM;
156
templat.width0 = sizeof(constants1);
157
templat.height0 = 1;
158
templat.depth0 = 1;
159
templat.array_size = 1;
160
templat.last_level = 0;
161
templat.bind = PIPE_BIND_CONSTANT_BUFFER;
162
163
constbuf1 = screen->resource_create(screen, &templat);
164
if (constbuf1 == NULL)
165
exit(4);
166
constbuf2 = screen->resource_create(screen, &templat);
167
if (constbuf2 == NULL)
168
exit(4);
169
170
{
171
ctx->buffer_subdata(ctx, constbuf1,
172
PIPE_MAP_WRITE,
173
0, sizeof(constants1), constants1);
174
175
pipe_set_constant_buffer(ctx,
176
PIPE_SHADER_GEOMETRY, 0,
177
constbuf1);
178
}
179
{
180
ctx->buffer_subdata(ctx, constbuf2,
181
PIPE_MAP_WRITE,
182
0, sizeof(constants2), constants2);
183
184
pipe_set_constant_buffer(ctx,
185
PIPE_SHADER_GEOMETRY, 1,
186
constbuf2);
187
}
188
}
189
190
191
static void set_viewport( float x, float y,
192
float width, float height,
193
float zNear, float zFar)
194
{
195
float z = zFar;
196
float half_width = (float)width / 2.0f;
197
float half_height = (float)height / 2.0f;
198
float half_depth = ((float)zFar - (float)zNear) / 2.0f;
199
struct pipe_viewport_state vp;
200
201
vp.scale[0] = half_width;
202
vp.scale[1] = half_height;
203
vp.scale[2] = half_depth;
204
205
vp.translate[0] = half_width + x;
206
vp.translate[1] = half_height + y;
207
vp.translate[2] = half_depth + z;
208
209
vp.swizzle_x = PIPE_VIEWPORT_SWIZZLE_POSITIVE_X;
210
vp.swizzle_y = PIPE_VIEWPORT_SWIZZLE_POSITIVE_Y;
211
vp.swizzle_z = PIPE_VIEWPORT_SWIZZLE_POSITIVE_Z;
212
vp.swizzle_w = PIPE_VIEWPORT_SWIZZLE_POSITIVE_W;
213
214
ctx->set_viewport_states( ctx, 0, 1, &vp );
215
}
216
217
static void set_vertices( void )
218
{
219
struct pipe_vertex_element ve[4];
220
struct pipe_vertex_buffer vbuf;
221
void *handle;
222
223
memset(ve, 0, sizeof ve);
224
225
ve[0].src_offset = Offset(struct vertex, position);
226
ve[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
227
ve[1].src_offset = Offset(struct vertex, color);
228
ve[1].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
229
ve[2].src_offset = Offset(struct vertex, texcoord);
230
ve[2].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
231
ve[3].src_offset = Offset(struct vertex, generic);
232
ve[3].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
233
234
handle = ctx->create_vertex_elements_state(ctx, 4, ve);
235
ctx->bind_vertex_elements_state(ctx, handle);
236
237
memset(&vbuf, 0, sizeof vbuf);
238
239
vbuf.stride = sizeof( struct vertex );
240
vbuf.buffer_offset = 0;
241
if (draw_strip) {
242
vbuf.buffer.resource = pipe_buffer_create_with_data(ctx,
243
PIPE_BIND_VERTEX_BUFFER,
244
PIPE_USAGE_DEFAULT,
245
sizeof(vertices_strip),
246
vertices_strip);
247
} else {
248
vbuf.buffer.resource = pipe_buffer_create_with_data(ctx,
249
PIPE_BIND_VERTEX_BUFFER,
250
PIPE_USAGE_DEFAULT,
251
sizeof(vertices),
252
vertices);
253
}
254
255
ctx->set_vertex_buffers(ctx, 0, 1, 0, false, &vbuf);
256
}
257
258
static void set_vertex_shader( void )
259
{
260
void *handle;
261
const char *text =
262
"VERT\n"
263
"DCL IN[0]\n"
264
"DCL IN[1]\n"
265
"DCL IN[2]\n"
266
"DCL IN[3]\n"
267
"DCL OUT[0], POSITION\n"
268
"DCL OUT[1], COLOR[0]\n"
269
"DCL OUT[2], GENERIC[0]\n"
270
"DCL OUT[3], GENERIC[1]\n"
271
" MOV OUT[0], IN[0]\n"
272
" MOV OUT[1], IN[1]\n"
273
" MOV OUT[2], IN[2]\n"
274
" MOV OUT[3], IN[3]\n"
275
" END\n";
276
277
handle = graw_parse_vertex_shader(ctx, text);
278
ctx->bind_vs_state(ctx, handle);
279
}
280
281
static void set_fragment_shader( void )
282
{
283
void *handle;
284
const char *text =
285
"FRAG\n"
286
"DCL IN[0], COLOR, LINEAR\n"
287
"DCL OUT[0], COLOR\n"
288
" 0: MOV OUT[0], IN[0]\n"
289
" 1: END\n";
290
291
handle = graw_parse_fragment_shader(ctx, text);
292
ctx->bind_fs_state(ctx, handle);
293
}
294
295
296
static void set_geometry_shader( void )
297
{
298
FILE *f;
299
char buf[50000];
300
void *handle;
301
int sz;
302
303
if ((f = fopen(filename, "r")) == NULL) {
304
fprintf(stderr, "Couldn't open %s\n", filename);
305
exit(1);
306
}
307
308
sz = fread(buf, 1, sizeof(buf), f);
309
if (!feof(f)) {
310
printf("file too long\n");
311
exit(1);
312
}
313
printf("%.*s\n", sz, buf);
314
buf[sz] = 0;
315
316
handle = graw_parse_geometry_shader(ctx, buf);
317
ctx->bind_gs_state(ctx, handle);
318
fclose(f);
319
}
320
321
322
static void draw( void )
323
{
324
union pipe_color_union clear_color = { {.1,.3,.5,0} };
325
326
ctx->clear(ctx, PIPE_CLEAR_COLOR, NULL, &clear_color, 0, 0);
327
if (draw_strip)
328
util_draw_arrays(ctx, PIPE_PRIM_TRIANGLE_STRIP, 0, 4);
329
else
330
util_draw_arrays(ctx, PIPE_PRIM_TRIANGLES, 0, 3);
331
332
ctx->flush(ctx, NULL, 0);
333
334
graw_save_surface_to_file(ctx, surf, NULL);
335
336
screen->flush_frontbuffer(screen, ctx, rttex, 0, 0, window, NULL);
337
}
338
339
#define SIZE 16
340
341
static void init_tex( void )
342
{
343
struct pipe_sampler_view sv_template;
344
struct pipe_sampler_state sampler_desc;
345
struct pipe_resource templat;
346
struct pipe_box box;
347
ubyte tex2d[SIZE][SIZE][4];
348
int s, t;
349
350
#if (SIZE != 2)
351
for (s = 0; s < SIZE; s++) {
352
for (t = 0; t < SIZE; t++) {
353
if (0) {
354
int x = (s ^ t) & 1;
355
tex2d[t][s][0] = (x) ? 0 : 63;
356
tex2d[t][s][1] = (x) ? 0 : 128;
357
tex2d[t][s][2] = 0;
358
tex2d[t][s][3] = 0xff;
359
}
360
else {
361
int x = ((s ^ t) >> 2) & 1;
362
tex2d[t][s][0] = s*255/(SIZE-1);
363
tex2d[t][s][1] = t*255/(SIZE-1);
364
tex2d[t][s][2] = (x) ? 0 : 128;
365
tex2d[t][s][3] = 0xff;
366
}
367
}
368
}
369
#else
370
tex2d[0][0][0] = 0;
371
tex2d[0][0][1] = 255;
372
tex2d[0][0][2] = 255;
373
tex2d[0][0][3] = 0;
374
375
tex2d[0][1][0] = 0;
376
tex2d[0][1][1] = 0;
377
tex2d[0][1][2] = 255;
378
tex2d[0][1][3] = 255;
379
380
tex2d[1][0][0] = 255;
381
tex2d[1][0][1] = 255;
382
tex2d[1][0][2] = 0;
383
tex2d[1][0][3] = 255;
384
385
tex2d[1][1][0] = 255;
386
tex2d[1][1][1] = 0;
387
tex2d[1][1][2] = 0;
388
tex2d[1][1][3] = 255;
389
#endif
390
391
memset(&templat, 0, sizeof(templat));
392
templat.target = PIPE_TEXTURE_2D;
393
templat.format = PIPE_FORMAT_B8G8R8A8_UNORM;
394
templat.width0 = SIZE;
395
templat.height0 = SIZE;
396
templat.depth0 = 1;
397
templat.array_size = 1;
398
templat.last_level = 0;
399
templat.bind = PIPE_BIND_SAMPLER_VIEW;
400
401
402
samptex = screen->resource_create(screen,
403
&templat);
404
if (samptex == NULL)
405
exit(4);
406
407
u_box_2d(0,0,SIZE,SIZE, &box);
408
409
ctx->texture_subdata(ctx,
410
samptex,
411
0,
412
PIPE_MAP_WRITE,
413
&box,
414
tex2d,
415
sizeof tex2d[0],
416
sizeof tex2d);
417
418
/* Possibly read back & compare against original data:
419
*/
420
if (0)
421
{
422
struct pipe_transfer *t;
423
uint32_t *ptr;
424
ptr = pipe_texture_map(ctx, samptex,
425
0, 0, /* level, layer */
426
PIPE_MAP_READ,
427
0, 0, SIZE, SIZE, &t); /* x, y, width, height */
428
429
if (memcmp(ptr, tex2d, sizeof tex2d) != 0) {
430
assert(0);
431
exit(9);
432
}
433
434
ctx->texture_unmap(ctx, t);
435
}
436
437
memset(&sv_template, 0, sizeof sv_template);
438
sv_template.format = samptex->format;
439
sv_template.texture = samptex;
440
sv_template.swizzle_r = 0;
441
sv_template.swizzle_g = 1;
442
sv_template.swizzle_b = 2;
443
sv_template.swizzle_a = 3;
444
sv = ctx->create_sampler_view(ctx, samptex, &sv_template);
445
if (sv == NULL)
446
exit(5);
447
448
ctx->set_sampler_views(ctx, PIPE_SHADER_FRAGMENT, 0, 1, 0, &sv);
449
450
451
memset(&sampler_desc, 0, sizeof sampler_desc);
452
sampler_desc.wrap_s = PIPE_TEX_WRAP_REPEAT;
453
sampler_desc.wrap_t = PIPE_TEX_WRAP_REPEAT;
454
sampler_desc.wrap_r = PIPE_TEX_WRAP_REPEAT;
455
sampler_desc.min_img_filter = PIPE_TEX_FILTER_NEAREST;
456
sampler_desc.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
457
sampler_desc.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
458
sampler_desc.compare_mode = PIPE_TEX_COMPARE_NONE;
459
sampler_desc.compare_func = 0;
460
sampler_desc.normalized_coords = 1;
461
sampler_desc.max_anisotropy = 0;
462
463
sampler = ctx->create_sampler_state(ctx, &sampler_desc);
464
if (sampler == NULL)
465
exit(6);
466
467
ctx->bind_sampler_states(ctx, PIPE_SHADER_FRAGMENT, 0, 1, &sampler);
468
469
}
470
471
static void init( void )
472
{
473
struct pipe_framebuffer_state fb;
474
struct pipe_resource templat;
475
struct pipe_surface surf_tmpl;
476
int i;
477
478
/* It's hard to say whether window or screen should be created
479
* first. Different environments would prefer one or the other.
480
*
481
* Also, no easy way of querying supported formats if the screen
482
* cannot be created first.
483
*/
484
for (i = 0; formats[i] != PIPE_FORMAT_NONE; i++) {
485
screen = graw_create_window_and_screen(0, 0, 300, 300,
486
formats[i],
487
&window);
488
if (window && screen)
489
break;
490
}
491
if (!screen || !window) {
492
fprintf(stderr, "Unable to create window\n");
493
exit(1);
494
}
495
496
ctx = screen->context_create(screen, NULL, 0);
497
if (ctx == NULL)
498
exit(3);
499
500
memset(&templat, 0, sizeof(templat));
501
templat.target = PIPE_TEXTURE_2D;
502
templat.format = formats[i];
503
templat.width0 = WIDTH;
504
templat.height0 = HEIGHT;
505
templat.depth0 = 1;
506
templat.array_size = 1;
507
templat.last_level = 0;
508
templat.bind = (PIPE_BIND_RENDER_TARGET |
509
PIPE_BIND_DISPLAY_TARGET);
510
511
rttex = screen->resource_create(screen,
512
&templat);
513
if (rttex == NULL)
514
exit(4);
515
516
surf_tmpl.format = templat.format;
517
surf_tmpl.u.tex.level = 0;
518
surf_tmpl.u.tex.first_layer = 0;
519
surf_tmpl.u.tex.last_layer = 0;
520
surf = ctx->create_surface(ctx, rttex, &surf_tmpl);
521
if (surf == NULL)
522
exit(5);
523
524
memset(&fb, 0, sizeof fb);
525
fb.nr_cbufs = 1;
526
fb.width = WIDTH;
527
fb.height = HEIGHT;
528
fb.cbufs[0] = surf;
529
530
ctx->set_framebuffer_state(ctx, &fb);
531
532
{
533
struct pipe_blend_state blend;
534
void *handle;
535
memset(&blend, 0, sizeof blend);
536
blend.rt[0].colormask = PIPE_MASK_RGBA;
537
handle = ctx->create_blend_state(ctx, &blend);
538
ctx->bind_blend_state(ctx, handle);
539
}
540
541
{
542
struct pipe_depth_stencil_alpha_state depthstencil;
543
void *handle;
544
memset(&depthstencil, 0, sizeof depthstencil);
545
handle = ctx->create_depth_stencil_alpha_state(ctx, &depthstencil);
546
ctx->bind_depth_stencil_alpha_state(ctx, handle);
547
}
548
549
{
550
struct pipe_rasterizer_state rasterizer;
551
void *handle;
552
memset(&rasterizer, 0, sizeof rasterizer);
553
rasterizer.cull_face = PIPE_FACE_NONE;
554
rasterizer.half_pixel_center = 1;
555
rasterizer.bottom_edge_rule = 1;
556
rasterizer.depth_clip_near = 1;
557
rasterizer.depth_clip_far = 1;
558
handle = ctx->create_rasterizer_state(ctx, &rasterizer);
559
ctx->bind_rasterizer_state(ctx, handle);
560
}
561
562
set_viewport(0, 0, WIDTH, HEIGHT, 30, 1000);
563
564
init_tex();
565
init_fs_constbuf();
566
567
set_vertices();
568
set_vertex_shader();
569
set_fragment_shader();
570
set_geometry_shader();
571
}
572
573
static void args(int argc, char *argv[])
574
{
575
int i;
576
577
for (i = 1; i < argc;) {
578
if (graw_parse_args(&i, argc, argv)) {
579
continue;
580
}
581
if (strcmp(argv[i], "-fps") == 0) {
582
show_fps = 1;
583
i++;
584
}
585
else if (strcmp(argv[i], "-strip") == 0) {
586
draw_strip = 1;
587
i++;
588
}
589
else if (i == argc - 1) {
590
filename = argv[i];
591
i++;
592
}
593
else {
594
usage(argv[0]);
595
exit(1);
596
}
597
}
598
599
if (!filename) {
600
usage(argv[0]);
601
exit(1);
602
}
603
}
604
605
int main( int argc, char *argv[] )
606
{
607
args(argc,argv);
608
init();
609
610
graw_set_display_func( draw );
611
graw_main_loop();
612
return 0;
613
}
614
615