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