Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
4358 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
 
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,
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,
129
                            &cb2);
130
}
131
 
132
 
133
static void set_viewport( float x, float y,
134
                          float width, float height,
135
                          float near, float far)
136
{
137
   float z = far;
138
   float half_width = (float)width / 2.0f;
139
   float half_height = (float)height / 2.0f;
140
   float half_depth = ((float)far - (float)near) / 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
   vp.scale[3] = 1.0f;
147
 
148
   vp.translate[0] = half_width + x;
149
   vp.translate[1] = half_height + y;
150
   vp.translate[2] = half_depth + z;
151
   vp.translate[3] = 0.0f;
152
 
153
   ctx->set_viewport_states( ctx, 0, 1, &vp );
154
}
155
 
156
static void set_vertices( void )
157
{
158
   struct pipe_vertex_element ve[3];
159
   struct pipe_vertex_buffer vbuf;
160
   void *handle;
161
 
162
   memset(ve, 0, sizeof ve);
163
 
164
   ve[0].src_offset = Offset(struct vertex, position);
165
   ve[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
166
   ve[1].src_offset = Offset(struct vertex, color);
167
   ve[1].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
168
   ve[2].src_offset = Offset(struct vertex, texcoord);
169
   ve[2].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
170
 
171
   handle = ctx->create_vertex_elements_state(ctx, 3, ve);
172
   ctx->bind_vertex_elements_state(ctx, handle);
173
 
174
   memset(&vbuf, 0, sizeof vbuf);
175
 
176
   vbuf.stride = sizeof( struct vertex );
177
   vbuf.buffer_offset = 0;
178
   vbuf.buffer = pipe_buffer_create_with_data(ctx,
179
                                              PIPE_BIND_VERTEX_BUFFER,
180
                                              PIPE_USAGE_STATIC,
181
                                              sizeof(vertices),
182
                                              vertices);
183
 
184
   ctx->set_vertex_buffers(ctx, 0, 1, &vbuf);
185
}
186
 
187
static void set_vertex_shader( void )
188
{
189
   void *handle;
190
   const char *text =
191
      "VERT\n"
192
      "DCL IN[0]\n"
193
      "DCL IN[1]\n"
194
      "DCL IN[2]\n"
195
      "DCL OUT[0], POSITION\n"
196
      "DCL OUT[1], COLOR[0]\n"
197
      "DCL OUT[2], GENERIC[0]\n"
198
      "  MOV OUT[0], IN[0]\n"
199
      "  MOV OUT[1], IN[1]\n"
200
      "  MOV OUT[2], IN[2]\n"
201
      "  END\n";
202
 
203
   handle = graw_parse_vertex_shader(ctx, text);
204
   ctx->bind_vs_state(ctx, handle);
205
}
206
 
207
static void set_fragment_shader( const char *filename )
208
{
209
   FILE *f;
210
   char buf[50000];
211
   void *handle;
212
   int sz;
213
 
214
   if ((f = fopen(filename, "r")) == NULL) {
215
      fprintf(stderr, "Couldn't open %s\n", filename);
216
      exit(1);
217
   }
218
 
219
   sz = fread(buf, 1, sizeof(buf), f);
220
   if (!feof(f)) {
221
      printf("file too long\n");
222
      exit(1);
223
   }
224
   printf("%.*s\n", sz, buf);
225
   buf[sz] = 0;
226
 
227
   handle = graw_parse_fragment_shader(ctx, buf);
228
   ctx->bind_fs_state(ctx, handle);
229
   fclose(f);
230
}
231
 
232
 
233
static void draw( void )
234
{
235
   union pipe_color_union clear_color = { {.1,.3,.5,0} };
236
 
237
   ctx->clear(ctx, PIPE_CLEAR_COLOR, &clear_color, 0, 0);
238
   util_draw_arrays(ctx, PIPE_PRIM_TRIANGLES, 0, 3);
239
   ctx->flush(ctx, NULL, 0);
240
 
241
   graw_save_surface_to_file(ctx, surf, NULL);
242
 
243
   screen->flush_frontbuffer(screen, rttex, 0, 0, window);
244
}
245
 
246
#define SIZE 16
247
 
248
static void init_tex( void )
249
{
250
   struct pipe_sampler_view sv_template;
251
   struct pipe_sampler_state sampler_desc;
252
   struct pipe_resource templat;
253
   struct pipe_box box;
254
   ubyte tex2d[SIZE][SIZE][4];
255
   int s, t;
256
 
257
#if (SIZE != 2)
258
   for (s = 0; s < SIZE; s++) {
259
      for (t = 0; t < SIZE; t++) {
260
         if (0) {
261
            int x = (s ^ t) & 1;
262
	    tex2d[t][s][0] = (x) ? 0 : 63;
263
	    tex2d[t][s][1] = (x) ? 0 : 128;
264
	    tex2d[t][s][2] = 0;
265
	    tex2d[t][s][3] = 0xff;
266
         }
267
         else {
268
            int x = ((s ^ t) >> 2) & 1;
269
	    tex2d[t][s][0] = s*255/(SIZE-1);
270
	    tex2d[t][s][1] = t*255/(SIZE-1);
271
	    tex2d[t][s][2] = (x) ? 0 : 128;
272
	    tex2d[t][s][3] = 0xff;
273
         }
274
      }
275
   }
276
#else
277
   tex2d[0][0][0] = 0;
278
   tex2d[0][0][1] = 255;
279
   tex2d[0][0][2] = 255;
280
   tex2d[0][0][3] = 0;
281
 
282
   tex2d[0][1][0] = 0;
283
   tex2d[0][1][1] = 0;
284
   tex2d[0][1][2] = 255;
285
   tex2d[0][1][3] = 255;
286
 
287
   tex2d[1][0][0] = 255;
288
   tex2d[1][0][1] = 255;
289
   tex2d[1][0][2] = 0;
290
   tex2d[1][0][3] = 255;
291
 
292
   tex2d[1][1][0] = 255;
293
   tex2d[1][1][1] = 0;
294
   tex2d[1][1][2] = 0;
295
   tex2d[1][1][3] = 255;
296
#endif
297
 
298
   templat.target = PIPE_TEXTURE_2D;
299
   templat.format = PIPE_FORMAT_B8G8R8A8_UNORM;
300
   templat.width0 = SIZE;
301
   templat.height0 = SIZE;
302
   templat.depth0 = 1;
303
   templat.array_size = 1;
304
   templat.last_level = 0;
305
   templat.nr_samples = 1;
306
   templat.bind = PIPE_BIND_SAMPLER_VIEW;
307
 
308
 
309
   samptex = screen->resource_create(screen,
310
                                 &templat);
311
   if (samptex == NULL)
312
      exit(4);
313
 
314
   u_box_2d(0,0,SIZE,SIZE, &box);
315
 
316
   ctx->transfer_inline_write(ctx,
317
                              samptex,
318
                              0,
319
                              PIPE_TRANSFER_WRITE,
320
                              &box,
321
                              tex2d,
322
                              sizeof tex2d[0],
323
                              sizeof tex2d);
324
 
325
   /* Possibly read back & compare against original data:
326
    */
327
   if (0)
328
   {
329
      struct pipe_transfer *t;
330
      uint32_t *ptr;
331
      ptr = pipe_transfer_map(ctx, samptex,
332
                              0, 0, /* level, layer */
333
                              PIPE_TRANSFER_READ,
334
                              0, 0, SIZE, SIZE, &t); /* x, y, width, height */
335
 
336
      if (memcmp(ptr, tex2d, sizeof tex2d) != 0) {
337
         assert(0);
338
         exit(9);
339
      }
340
 
341
      ctx->transfer_unmap(ctx, t);
342
   }
343
 
344
   memset(&sv_template, 0, sizeof sv_template);
345
   sv_template.format = samptex->format;
346
   sv_template.texture = samptex;
347
   sv_template.swizzle_r = 0;
348
   sv_template.swizzle_g = 1;
349
   sv_template.swizzle_b = 2;
350
   sv_template.swizzle_a = 3;
351
   sv = ctx->create_sampler_view(ctx, samptex, &sv_template);
352
   if (sv == NULL)
353
      exit(5);
354
 
355
   ctx->set_fragment_sampler_views(ctx, 1, &sv);
356
 
357
 
358
   memset(&sampler_desc, 0, sizeof sampler_desc);
359
   sampler_desc.wrap_s = PIPE_TEX_WRAP_REPEAT;
360
   sampler_desc.wrap_t = PIPE_TEX_WRAP_REPEAT;
361
   sampler_desc.wrap_r = PIPE_TEX_WRAP_REPEAT;
362
   sampler_desc.min_img_filter = PIPE_TEX_FILTER_NEAREST;
363
   sampler_desc.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
364
   sampler_desc.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
365
   sampler_desc.compare_mode = PIPE_TEX_COMPARE_NONE;
366
   sampler_desc.compare_func = 0;
367
   sampler_desc.normalized_coords = 1;
368
   sampler_desc.max_anisotropy = 0;
369
 
370
   sampler = ctx->create_sampler_state(ctx, &sampler_desc);
371
   if (sampler == NULL)
372
      exit(6);
373
 
374
   ctx->bind_fragment_sampler_states(ctx, 1, &sampler);
375
 
376
}
377
 
378
static void init( void )
379
{
380
   struct pipe_framebuffer_state fb;
381
   struct pipe_resource templat;
382
   struct pipe_surface surf_tmpl;
383
   int i;
384
 
385
   /* It's hard to say whether window or screen should be created
386
    * first.  Different environments would prefer one or the other.
387
    *
388
    * Also, no easy way of querying supported formats if the screen
389
    * cannot be created first.
390
    */
391
   for (i = 0; formats[i] != PIPE_FORMAT_NONE; i++) {
392
      screen = graw_create_window_and_screen(0, 0, 300, 300,
393
                                             formats[i],
394
                                             &window);
395
      if (window && screen)
396
         break;
397
   }
398
   if (!screen || !window) {
399
      fprintf(stderr, "Unable to create window\n");
400
      exit(1);
401
   }
402
 
403
   ctx = screen->context_create(screen, NULL);
404
   if (ctx == NULL)
405
      exit(3);
406
 
407
   templat.target = PIPE_TEXTURE_2D;
408
   templat.format = formats[i];
409
   templat.width0 = WIDTH;
410
   templat.height0 = HEIGHT;
411
   templat.depth0 = 1;
412
   templat.array_size = 1;
413
   templat.last_level = 0;
414
   templat.nr_samples = 1;
415
   templat.bind = (PIPE_BIND_RENDER_TARGET |
416
                   PIPE_BIND_DISPLAY_TARGET);
417
 
418
   rttex = screen->resource_create(screen,
419
                                 &templat);
420
   if (rttex == NULL)
421
      exit(4);
422
 
423
   surf_tmpl.format = templat.format;
424
   surf_tmpl.u.tex.level = 0;
425
   surf_tmpl.u.tex.first_layer = 0;
426
   surf_tmpl.u.tex.last_layer = 0;
427
   surf = ctx->create_surface(ctx, rttex, &surf_tmpl);
428
   if (surf == NULL)
429
      exit(5);
430
 
431
   memset(&fb, 0, sizeof fb);
432
   fb.nr_cbufs = 1;
433
   fb.width = WIDTH;
434
   fb.height = HEIGHT;
435
   fb.cbufs[0] = surf;
436
 
437
   ctx->set_framebuffer_state(ctx, &fb);
438
 
439
   {
440
      struct pipe_blend_state blend;
441
      void *handle;
442
      memset(&blend, 0, sizeof blend);
443
      blend.rt[0].colormask = PIPE_MASK_RGBA;
444
      handle = ctx->create_blend_state(ctx, &blend);
445
      ctx->bind_blend_state(ctx, handle);
446
   }
447
 
448
   {
449
      struct pipe_depth_stencil_alpha_state depthstencil;
450
      void *handle;
451
      memset(&depthstencil, 0, sizeof depthstencil);
452
      handle = ctx->create_depth_stencil_alpha_state(ctx, &depthstencil);
453
      ctx->bind_depth_stencil_alpha_state(ctx, handle);
454
   }
455
 
456
   {
457
      struct pipe_rasterizer_state rasterizer;
458
      void *handle;
459
      memset(&rasterizer, 0, sizeof rasterizer);
460
      rasterizer.cull_face = PIPE_FACE_NONE;
461
      rasterizer.half_pixel_center = 1;
462
      rasterizer.bottom_edge_rule = 1;
463
      rasterizer.depth_clip = 1;
464
      handle = ctx->create_rasterizer_state(ctx, &rasterizer);
465
      ctx->bind_rasterizer_state(ctx, handle);
466
   }
467
 
468
   set_viewport(0, 0, WIDTH, HEIGHT, 30, 1000);
469
 
470
   init_tex();
471
   init_fs_constbuf();
472
 
473
   set_vertices();
474
   set_vertex_shader();
475
   set_fragment_shader(filename);
476
}
477
 
478
static void args(int argc, char *argv[])
479
{
480
   int i;
481
 
482
   for (i = 1; i < argc;) {
483
      if (graw_parse_args(&i, argc, argv)) {
484
         continue;
485
      }
486
      if (strcmp(argv[i], "-fps") == 0) {
487
         show_fps = 1;
488
         i++;
489
      }
490
      else if (i == argc - 1) {
491
         filename = argv[i];
492
         i++;
493
      }
494
      else {
495
         usage(argv[0]);
496
         exit(1);
497
      }
498
   }
499
 
500
   if (!filename) {
501
      usage(argv[0]);
502
      exit(1);
503
   }
504
}
505
 
506
int main( int argc, char *argv[] )
507
{
508
   args(argc,argv);
509
   init();
510
 
511
   graw_set_display_func( draw );
512
   graw_main_loop();
513
   return 0;
514
}