Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5564 serge 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
#include               /* 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
   struct pipe_box box;
153
 
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.nr_samples = 1;
162
   templat.bind = PIPE_BIND_CONSTANT_BUFFER;
163
 
164
   constbuf1 = screen->resource_create(screen, &templat);
165
   if (constbuf1 == NULL)
166
      exit(4);
167
   constbuf2 = screen->resource_create(screen, &templat);
168
   if (constbuf2 == NULL)
169
      exit(4);
170
 
171
   {
172
      u_box_2d(0,0,sizeof(constants1),1, &box);
173
 
174
      ctx->transfer_inline_write(ctx,
175
                                 constbuf1,
176
                                 0,
177
                                 PIPE_TRANSFER_WRITE,
178
                                 &box,
179
                                 constants1,
180
                                 sizeof constants1,
181
                                 sizeof constants1);
182
 
183
 
184
      pipe_set_constant_buffer(ctx,
185
                               PIPE_SHADER_GEOMETRY, 0,
186
                               constbuf1);
187
   }
188
   {
189
      u_box_2d(0,0,sizeof(constants2),1, &box);
190
 
191
      ctx->transfer_inline_write(ctx,
192
                                 constbuf2,
193
                                 0,
194
                                 PIPE_TRANSFER_WRITE,
195
                                 &box,
196
                                 constants2,
197
                                 sizeof constants2,
198
                                 sizeof constants2);
199
 
200
 
201
      pipe_set_constant_buffer(ctx,
202
                               PIPE_SHADER_GEOMETRY, 1,
203
                               constbuf2);
204
   }
205
}
206
 
207
 
208
static void set_viewport( float x, float y,
209
                          float width, float height,
210
                          float zNear, float zFar)
211
{
212
   float z = zFar;
213
   float half_width = (float)width / 2.0f;
214
   float half_height = (float)height / 2.0f;
215
   float half_depth = ((float)zFar - (float)zNear) / 2.0f;
216
   struct pipe_viewport_state vp;
217
 
218
   vp.scale[0] = half_width;
219
   vp.scale[1] = half_height;
220
   vp.scale[2] = half_depth;
221
 
222
   vp.translate[0] = half_width + x;
223
   vp.translate[1] = half_height + y;
224
   vp.translate[2] = half_depth + z;
225
 
226
   ctx->set_viewport_states( ctx, 0, 1, &vp );
227
}
228
 
229
static void set_vertices( void )
230
{
231
   struct pipe_vertex_element ve[4];
232
   struct pipe_vertex_buffer vbuf;
233
   void *handle;
234
 
235
   memset(ve, 0, sizeof ve);
236
 
237
   ve[0].src_offset = Offset(struct vertex, position);
238
   ve[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
239
   ve[1].src_offset = Offset(struct vertex, color);
240
   ve[1].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
241
   ve[2].src_offset = Offset(struct vertex, texcoord);
242
   ve[2].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
243
   ve[3].src_offset = Offset(struct vertex, generic);
244
   ve[3].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
245
 
246
   handle = ctx->create_vertex_elements_state(ctx, 4, ve);
247
   ctx->bind_vertex_elements_state(ctx, handle);
248
 
249
   memset(&vbuf, 0, sizeof vbuf);
250
 
251
   vbuf.stride = sizeof( struct vertex );
252
   vbuf.buffer_offset = 0;
253
   if (draw_strip) {
254
      vbuf.buffer = pipe_buffer_create_with_data(ctx,
255
                                                 PIPE_BIND_VERTEX_BUFFER,
256
                                                 PIPE_USAGE_DEFAULT,
257
                                                 sizeof(vertices_strip),
258
                                                 vertices_strip);
259
   } else {
260
      vbuf.buffer = pipe_buffer_create_with_data(ctx,
261
                                                 PIPE_BIND_VERTEX_BUFFER,
262
                                                 PIPE_USAGE_DEFAULT,
263
                                                 sizeof(vertices),
264
                                                 vertices);
265
   }
266
 
267
   ctx->set_vertex_buffers(ctx, 0, 1, &vbuf);
268
}
269
 
270
static void set_vertex_shader( void )
271
{
272
   void *handle;
273
   const char *text =
274
      "VERT\n"
275
      "DCL IN[0]\n"
276
      "DCL IN[1]\n"
277
      "DCL IN[2]\n"
278
      "DCL IN[3]\n"
279
      "DCL OUT[0], POSITION\n"
280
      "DCL OUT[1], COLOR[0]\n"
281
      "DCL OUT[2], GENERIC[0]\n"
282
      "DCL OUT[3], GENERIC[1]\n"
283
      "  MOV OUT[0], IN[0]\n"
284
      "  MOV OUT[1], IN[1]\n"
285
      "  MOV OUT[2], IN[2]\n"
286
      "  MOV OUT[3], IN[3]\n"
287
      "  END\n";
288
 
289
   handle = graw_parse_vertex_shader(ctx, text);
290
   ctx->bind_vs_state(ctx, handle);
291
}
292
 
293
static void set_fragment_shader( void )
294
{
295
   void *handle;
296
   const char *text =
297
      "FRAG\n"
298
      "DCL IN[0], COLOR, LINEAR\n"
299
      "DCL OUT[0], COLOR\n"
300
      "  0: MOV OUT[0], IN[0]\n"
301
      "  1: END\n";
302
 
303
   handle = graw_parse_fragment_shader(ctx, text);
304
   ctx->bind_fs_state(ctx, handle);
305
}
306
 
307
 
308
static void set_geometry_shader( void )
309
{
310
   FILE *f;
311
   char buf[50000];
312
   void *handle;
313
   int sz;
314
 
315
   if ((f = fopen(filename, "r")) == NULL) {
316
      fprintf(stderr, "Couldn't open %s\n", filename);
317
      exit(1);
318
   }
319
 
320
   sz = fread(buf, 1, sizeof(buf), f);
321
   if (!feof(f)) {
322
      printf("file too long\n");
323
      exit(1);
324
   }
325
   printf("%.*s\n", sz, buf);
326
   buf[sz] = 0;
327
 
328
   handle = graw_parse_geometry_shader(ctx, buf);
329
   ctx->bind_gs_state(ctx, handle);
330
   fclose(f);
331
}
332
 
333
 
334
static void draw( void )
335
{
336
   union pipe_color_union clear_color = { {.1,.3,.5,0} };
337
 
338
   ctx->clear(ctx, PIPE_CLEAR_COLOR, &clear_color, 0, 0);
339
   if (draw_strip)
340
      util_draw_arrays(ctx, PIPE_PRIM_TRIANGLE_STRIP, 0, 4);
341
   else
342
      util_draw_arrays(ctx, PIPE_PRIM_TRIANGLES, 0, 3);
343
 
344
   ctx->flush(ctx, NULL, 0);
345
 
346
   graw_save_surface_to_file(ctx, surf, NULL);
347
 
348
   screen->flush_frontbuffer(screen, rttex, 0, 0, window, NULL);
349
}
350
 
351
#define SIZE 16
352
 
353
static void init_tex( void )
354
{
355
   struct pipe_sampler_view sv_template;
356
   struct pipe_sampler_state sampler_desc;
357
   struct pipe_resource templat;
358
   struct pipe_box box;
359
   ubyte tex2d[SIZE][SIZE][4];
360
   int s, t;
361
 
362
#if (SIZE != 2)
363
   for (s = 0; s < SIZE; s++) {
364
      for (t = 0; t < SIZE; t++) {
365
         if (0) {
366
            int x = (s ^ t) & 1;
367
	    tex2d[t][s][0] = (x) ? 0 : 63;
368
	    tex2d[t][s][1] = (x) ? 0 : 128;
369
	    tex2d[t][s][2] = 0;
370
	    tex2d[t][s][3] = 0xff;
371
         }
372
         else {
373
            int x = ((s ^ t) >> 2) & 1;
374
	    tex2d[t][s][0] = s*255/(SIZE-1);
375
	    tex2d[t][s][1] = t*255/(SIZE-1);
376
	    tex2d[t][s][2] = (x) ? 0 : 128;
377
	    tex2d[t][s][3] = 0xff;
378
         }
379
      }
380
   }
381
#else
382
   tex2d[0][0][0] = 0;
383
   tex2d[0][0][1] = 255;
384
   tex2d[0][0][2] = 255;
385
   tex2d[0][0][3] = 0;
386
 
387
   tex2d[0][1][0] = 0;
388
   tex2d[0][1][1] = 0;
389
   tex2d[0][1][2] = 255;
390
   tex2d[0][1][3] = 255;
391
 
392
   tex2d[1][0][0] = 255;
393
   tex2d[1][0][1] = 255;
394
   tex2d[1][0][2] = 0;
395
   tex2d[1][0][3] = 255;
396
 
397
   tex2d[1][1][0] = 255;
398
   tex2d[1][1][1] = 0;
399
   tex2d[1][1][2] = 0;
400
   tex2d[1][1][3] = 255;
401
#endif
402
 
403
   templat.target = PIPE_TEXTURE_2D;
404
   templat.format = PIPE_FORMAT_B8G8R8A8_UNORM;
405
   templat.width0 = SIZE;
406
   templat.height0 = SIZE;
407
   templat.depth0 = 1;
408
   templat.array_size = 1;
409
   templat.last_level = 0;
410
   templat.nr_samples = 1;
411
   templat.bind = PIPE_BIND_SAMPLER_VIEW;
412
 
413
 
414
   samptex = screen->resource_create(screen,
415
                                 &templat);
416
   if (samptex == NULL)
417
      exit(4);
418
 
419
   u_box_2d(0,0,SIZE,SIZE, &box);
420
 
421
   ctx->transfer_inline_write(ctx,
422
                              samptex,
423
                              0,
424
                              PIPE_TRANSFER_WRITE,
425
                              &box,
426
                              tex2d,
427
                              sizeof tex2d[0],
428
                              sizeof tex2d);
429
 
430
   /* Possibly read back & compare against original data:
431
    */
432
   if (0)
433
   {
434
      struct pipe_transfer *t;
435
      uint32_t *ptr;
436
      ptr = pipe_transfer_map(ctx, samptex,
437
                              0, 0, /* level, layer */
438
                              PIPE_TRANSFER_READ,
439
                              0, 0, SIZE, SIZE, &t); /* x, y, width, height */
440
 
441
      if (memcmp(ptr, tex2d, sizeof tex2d) != 0) {
442
         assert(0);
443
         exit(9);
444
      }
445
 
446
      ctx->transfer_unmap(ctx, t);
447
   }
448
 
449
   memset(&sv_template, 0, sizeof sv_template);
450
   sv_template.format = samptex->format;
451
   sv_template.texture = samptex;
452
   sv_template.swizzle_r = 0;
453
   sv_template.swizzle_g = 1;
454
   sv_template.swizzle_b = 2;
455
   sv_template.swizzle_a = 3;
456
   sv = ctx->create_sampler_view(ctx, samptex, &sv_template);
457
   if (sv == NULL)
458
      exit(5);
459
 
460
   ctx->set_sampler_views(ctx, PIPE_SHADER_FRAGMENT, 0, 1, &sv);
461
 
462
 
463
   memset(&sampler_desc, 0, sizeof sampler_desc);
464
   sampler_desc.wrap_s = PIPE_TEX_WRAP_REPEAT;
465
   sampler_desc.wrap_t = PIPE_TEX_WRAP_REPEAT;
466
   sampler_desc.wrap_r = PIPE_TEX_WRAP_REPEAT;
467
   sampler_desc.min_img_filter = PIPE_TEX_FILTER_NEAREST;
468
   sampler_desc.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
469
   sampler_desc.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
470
   sampler_desc.compare_mode = PIPE_TEX_COMPARE_NONE;
471
   sampler_desc.compare_func = 0;
472
   sampler_desc.normalized_coords = 1;
473
   sampler_desc.max_anisotropy = 0;
474
 
475
   sampler = ctx->create_sampler_state(ctx, &sampler_desc);
476
   if (sampler == NULL)
477
      exit(6);
478
 
479
   ctx->bind_sampler_states(ctx, PIPE_SHADER_FRAGMENT, 0, 1, &sampler);
480
 
481
}
482
 
483
static void init( void )
484
{
485
   struct pipe_framebuffer_state fb;
486
   struct pipe_resource templat;
487
   struct pipe_surface surf_tmpl;
488
   int i;
489
 
490
   /* It's hard to say whether window or screen should be created
491
    * first.  Different environments would prefer one or the other.
492
    *
493
    * Also, no easy way of querying supported formats if the screen
494
    * cannot be created first.
495
    */
496
   for (i = 0; formats[i] != PIPE_FORMAT_NONE; i++) {
497
      screen = graw_create_window_and_screen(0, 0, 300, 300,
498
                                             formats[i],
499
                                             &window);
500
      if (window && screen)
501
         break;
502
   }
503
   if (!screen || !window) {
504
      fprintf(stderr, "Unable to create window\n");
505
      exit(1);
506
   }
507
 
508
   ctx = screen->context_create(screen, NULL);
509
   if (ctx == NULL)
510
      exit(3);
511
 
512
   templat.target = PIPE_TEXTURE_2D;
513
   templat.format = formats[i];
514
   templat.width0 = WIDTH;
515
   templat.height0 = HEIGHT;
516
   templat.depth0 = 1;
517
   templat.array_size = 1;
518
   templat.last_level = 0;
519
   templat.nr_samples = 1;
520
   templat.bind = (PIPE_BIND_RENDER_TARGET |
521
                   PIPE_BIND_DISPLAY_TARGET);
522
 
523
   rttex = screen->resource_create(screen,
524
                                 &templat);
525
   if (rttex == NULL)
526
      exit(4);
527
 
528
   surf_tmpl.format = templat.format;
529
   surf_tmpl.u.tex.level = 0;
530
   surf_tmpl.u.tex.first_layer = 0;
531
   surf_tmpl.u.tex.last_layer = 0;
532
   surf = ctx->create_surface(ctx, rttex, &surf_tmpl);
533
   if (surf == NULL)
534
      exit(5);
535
 
536
   memset(&fb, 0, sizeof fb);
537
   fb.nr_cbufs = 1;
538
   fb.width = WIDTH;
539
   fb.height = HEIGHT;
540
   fb.cbufs[0] = surf;
541
 
542
   ctx->set_framebuffer_state(ctx, &fb);
543
 
544
   {
545
      struct pipe_blend_state blend;
546
      void *handle;
547
      memset(&blend, 0, sizeof blend);
548
      blend.rt[0].colormask = PIPE_MASK_RGBA;
549
      handle = ctx->create_blend_state(ctx, &blend);
550
      ctx->bind_blend_state(ctx, handle);
551
   }
552
 
553
   {
554
      struct pipe_depth_stencil_alpha_state depthstencil;
555
      void *handle;
556
      memset(&depthstencil, 0, sizeof depthstencil);
557
      handle = ctx->create_depth_stencil_alpha_state(ctx, &depthstencil);
558
      ctx->bind_depth_stencil_alpha_state(ctx, handle);
559
   }
560
 
561
   {
562
      struct pipe_rasterizer_state rasterizer;
563
      void *handle;
564
      memset(&rasterizer, 0, sizeof rasterizer);
565
      rasterizer.cull_face = PIPE_FACE_NONE;
566
      rasterizer.half_pixel_center = 1;
567
      rasterizer.bottom_edge_rule = 1;
568
      rasterizer.depth_clip = 1;
569
      handle = ctx->create_rasterizer_state(ctx, &rasterizer);
570
      ctx->bind_rasterizer_state(ctx, handle);
571
   }
572
 
573
   set_viewport(0, 0, WIDTH, HEIGHT, 30, 1000);
574
 
575
   init_tex();
576
   init_fs_constbuf();
577
 
578
   set_vertices();
579
   set_vertex_shader();
580
   set_fragment_shader();
581
   set_geometry_shader();
582
}
583
 
584
static void args(int argc, char *argv[])
585
{
586
   int i;
587
 
588
   for (i = 1; i < argc;) {
589
      if (graw_parse_args(&i, argc, argv)) {
590
         continue;
591
      }
592
      if (strcmp(argv[i], "-fps") == 0) {
593
         show_fps = 1;
594
         i++;
595
      }
596
      else if (strcmp(argv[i], "-strip") == 0) {
597
         draw_strip = 1;
598
         i++;
599
      }
600
      else if (i == argc - 1) {
601
         filename = argv[i];
602
         i++;
603
      }
604
      else {
605
         usage(argv[0]);
606
         exit(1);
607
      }
608
   }
609
 
610
   if (!filename) {
611
      usage(argv[0]);
612
      exit(1);
613
   }
614
}
615
 
616
int main( int argc, char *argv[] )
617
{
618
   args(argc,argv);
619
   init();
620
 
621
   graw_set_display_func( draw );
622
   graw_main_loop();
623
   return 0;
624
}