Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5564 serge 1
/*
2
 * Test draw instancing.
3
 */
4
 
5
#include 
6
#include 
7
 
8
#include "state_tracker/graw.h"
9
#include "pipe/p_screen.h"
10
#include "pipe/p_context.h"
11
#include "pipe/p_state.h"
12
#include "pipe/p_defines.h"
13
 
14
#include "util/u_memory.h"      /* Offset() */
15
#include "util/u_draw_quad.h"
16
#include "util/u_inlines.h"
17
 
18
 
19
enum pipe_format formats[] = {
20
   PIPE_FORMAT_RGBA8888_UNORM,
21
   PIPE_FORMAT_BGRA8888_UNORM,
22
   PIPE_FORMAT_NONE
23
};
24
 
25
static const int WIDTH = 300;
26
static const int HEIGHT = 300;
27
 
28
static struct pipe_screen *screen = NULL;
29
static struct pipe_context *ctx = NULL;
30
static struct pipe_surface *surf = NULL;
31
static struct pipe_resource *tex = NULL;
32
static void *window = NULL;
33
 
34
struct vertex {
35
   float position[4];
36
   float color[4];
37
};
38
 
39
 
40
static int draw_elements = 0;
41
 
42
 
43
/**
44
 * Vertex data.
45
 * Each vertex has three attributes: position, color and translation.
46
 * The translation attribute is a per-instance attribute.  See
47
 * "instance_divisor" below.
48
 */
49
static struct vertex vertices[4] =
50
{
51
   {
52
      { 0.0f, -0.3f, 0.0f, 1.0f },  /* pos */
53
      { 1.0f, 0.0f, 0.0f, 1.0f }    /* color */
54
   },
55
   {
56
      { -0.2f, 0.3f, 0.0f, 1.0f },
57
      { 0.0f, 1.0f, 0.0f, 1.0f }
58
   },
59
   {
60
      { 0.2f, 0.3f, 0.0f, 1.0f },
61
      { 0.0f, 0.0f, 1.0f, 1.0f }
62
   }
63
};
64
 
65
 
66
#define NUM_INST 5
67
 
68
static float inst_data[NUM_INST][4] =
69
{
70
   { -0.50f, 0.4f, 0.0f, 0.0f },
71
   { -0.25f, 0.1f, 0.0f, 0.0f },
72
   { 0.00f, 0.2f, 0.0f, 0.0f },
73
   { 0.25f, 0.1f, 0.0f, 0.0f },
74
   { 0.50f, 0.3f, 0.0f, 0.0f }
75
};
76
 
77
 
78
static ushort indices[3] = { 0, 2, 1 };
79
 
80
 
81
static void set_viewport( float x, float y,
82
                          float width, float height,
83
                          float zNear, float zFar)
84
{
85
   float z = zFar;
86
   float half_width = (float)width / 2.0f;
87
   float half_height = (float)height / 2.0f;
88
   float half_depth = ((float)zFar - (float)zNear) / 2.0f;
89
   struct pipe_viewport_state vp;
90
 
91
   vp.scale[0] = half_width;
92
   vp.scale[1] = half_height;
93
   vp.scale[2] = half_depth;
94
 
95
   vp.translate[0] = half_width + x;
96
   vp.translate[1] = half_height + y;
97
   vp.translate[2] = half_depth + z;
98
 
99
   ctx->set_viewport_states( ctx, 0, 1, &vp );
100
}
101
 
102
 
103
static void set_vertices( void )
104
{
105
   struct pipe_vertex_element ve[3];
106
   struct pipe_vertex_buffer vbuf[2];
107
   struct pipe_index_buffer ibuf;
108
   void *handle;
109
 
110
   memset(ve, 0, sizeof ve);
111
 
112
   /* pos */
113
   ve[0].src_offset = Offset(struct vertex, position);
114
   ve[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
115
   ve[0].vertex_buffer_index = 0;
116
 
117
   /* color */
118
   ve[1].src_offset = Offset(struct vertex, color);
119
   ve[1].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
120
   ve[1].vertex_buffer_index = 0;
121
 
122
   /* per-instance info */
123
   ve[2].src_offset = 0;
124
   ve[2].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
125
   ve[2].vertex_buffer_index = 1;
126
   ve[2].instance_divisor = 1;
127
 
128
   handle = ctx->create_vertex_elements_state(ctx, 3, ve);
129
   ctx->bind_vertex_elements_state(ctx, handle);
130
 
131
   memset(&vbuf, 0, sizeof vbuf);
132
 
133
   /* vertex data */
134
   vbuf[0].stride = sizeof( struct vertex );
135
   vbuf[0].buffer_offset = 0;
136
   vbuf[0].buffer = pipe_buffer_create_with_data(ctx,
137
                                                 PIPE_BIND_VERTEX_BUFFER,
138
                                                 PIPE_USAGE_DEFAULT,
139
                                                 sizeof(vertices),
140
                                                 vertices);
141
 
142
   /* instance data */
143
   vbuf[1].stride = sizeof( inst_data[0] );
144
   vbuf[1].buffer_offset = 0;
145
   vbuf[1].buffer = pipe_buffer_create_with_data(ctx,
146
                                                 PIPE_BIND_VERTEX_BUFFER,
147
                                                 PIPE_USAGE_DEFAULT,
148
                                                 sizeof(inst_data),
149
                                                 inst_data);
150
 
151
   ctx->set_vertex_buffers(ctx, 0, 2, vbuf);
152
 
153
   /* index data */
154
   ibuf.buffer = pipe_buffer_create_with_data(ctx,
155
                                              PIPE_BIND_INDEX_BUFFER,
156
                                              PIPE_USAGE_DEFAULT,
157
                                              sizeof(indices),
158
                                              indices);
159
   ibuf.offset = 0;
160
   ibuf.index_size = 2;
161
 
162
   ctx->set_index_buffer(ctx, &ibuf);
163
 
164
}
165
 
166
static void set_vertex_shader( void )
167
{
168
   void *handle;
169
   const char *text =
170
      "VERT\n"
171
      "DCL IN[0]\n"
172
      "DCL IN[1]\n"
173
      "DCL IN[2]\n"
174
      "DCL OUT[0], POSITION\n"
175
      "DCL OUT[1], COLOR\n"
176
      "  0: MOV OUT[1], IN[1]\n"
177
      "  1: ADD OUT[0], IN[0], IN[2]\n"  /* add instance pos to vertex pos */
178
      "  2: END\n";
179
 
180
   handle = graw_parse_vertex_shader(ctx, text);
181
   ctx->bind_vs_state(ctx, handle);
182
}
183
 
184
static void set_fragment_shader( void )
185
{
186
   void *handle;
187
   const char *text =
188
      "FRAG\n"
189
      "DCL IN[0], COLOR, LINEAR\n"
190
      "DCL OUT[0], COLOR\n"
191
      "  0: MOV OUT[0], IN[0]\n"
192
      "  1: END\n";
193
 
194
   handle = graw_parse_fragment_shader(ctx, text);
195
   ctx->bind_fs_state(ctx, handle);
196
}
197
 
198
 
199
static void draw( void )
200
{
201
   union pipe_color_union clear_color = { {1,0,1,1} };
202
   struct pipe_draw_info info;
203
 
204
   ctx->clear(ctx, PIPE_CLEAR_COLOR, &clear_color, 0, 0);
205
 
206
   util_draw_init_info(&info);
207
   info.indexed = (draw_elements != 0);
208
   info.mode = PIPE_PRIM_TRIANGLES;
209
   info.start = 0;
210
   info.count = 3;
211
   /* draw NUM_INST triangles */
212
   info.instance_count = NUM_INST;
213
 
214
   ctx->draw_vbo(ctx, &info);
215
 
216
   ctx->flush(ctx, NULL, 0);
217
 
218
   graw_save_surface_to_file(ctx, surf, NULL);
219
 
220
   screen->flush_frontbuffer(screen, tex, 0, 0, window, NULL);
221
}
222
 
223
 
224
static void init( void )
225
{
226
   struct pipe_framebuffer_state fb;
227
   struct pipe_resource templat;
228
   struct pipe_surface surf_tmpl;
229
   int i;
230
 
231
   /* It's hard to say whether window or screen should be created
232
    * first.  Different environments would prefer one or the other.
233
    *
234
    * Also, no easy way of querying supported formats if the screen
235
    * cannot be created first.
236
    */
237
   for (i = 0; formats[i] != PIPE_FORMAT_NONE; i++) {
238
      screen = graw_create_window_and_screen(0, 0, 300, 300,
239
                                             formats[i],
240
                                             &window);
241
      if (window && screen)
242
         break;
243
   }
244
   if (!screen || !window) {
245
      fprintf(stderr, "Unable to create window\n");
246
      exit(1);
247
   }
248
 
249
   ctx = screen->context_create(screen, NULL);
250
   if (ctx == NULL)
251
      exit(3);
252
 
253
   templat.target = PIPE_TEXTURE_2D;
254
   templat.format = formats[i];
255
   templat.width0 = WIDTH;
256
   templat.height0 = HEIGHT;
257
   templat.depth0 = 1;
258
   templat.array_size = 1;
259
   templat.last_level = 0;
260
   templat.nr_samples = 1;
261
   templat.bind = (PIPE_BIND_RENDER_TARGET |
262
                   PIPE_BIND_DISPLAY_TARGET);
263
 
264
   tex = screen->resource_create(screen,
265
                                 &templat);
266
   if (tex == NULL)
267
      exit(4);
268
 
269
   surf_tmpl.format = templat.format;
270
   surf_tmpl.u.tex.level = 0;
271
   surf_tmpl.u.tex.first_layer = 0;
272
   surf_tmpl.u.tex.last_layer = 0;
273
   surf = ctx->create_surface(ctx, tex, &surf_tmpl);
274
   if (surf == NULL)
275
      exit(5);
276
 
277
   memset(&fb, 0, sizeof fb);
278
   fb.nr_cbufs = 1;
279
   fb.width = WIDTH;
280
   fb.height = HEIGHT;
281
   fb.cbufs[0] = surf;
282
 
283
   ctx->set_framebuffer_state(ctx, &fb);
284
 
285
   {
286
      struct pipe_blend_state blend;
287
      void *handle;
288
      memset(&blend, 0, sizeof blend);
289
      blend.rt[0].colormask = PIPE_MASK_RGBA;
290
      handle = ctx->create_blend_state(ctx, &blend);
291
      ctx->bind_blend_state(ctx, handle);
292
   }
293
 
294
   {
295
      struct pipe_depth_stencil_alpha_state depthstencil;
296
      void *handle;
297
      memset(&depthstencil, 0, sizeof depthstencil);
298
      handle = ctx->create_depth_stencil_alpha_state(ctx, &depthstencil);
299
      ctx->bind_depth_stencil_alpha_state(ctx, handle);
300
   }
301
 
302
   {
303
      struct pipe_rasterizer_state rasterizer;
304
      void *handle;
305
      memset(&rasterizer, 0, sizeof rasterizer);
306
      rasterizer.cull_face = PIPE_FACE_NONE;
307
      rasterizer.half_pixel_center = 1;
308
      rasterizer.bottom_edge_rule = 1;
309
      rasterizer.depth_clip = 1;
310
      handle = ctx->create_rasterizer_state(ctx, &rasterizer);
311
      ctx->bind_rasterizer_state(ctx, handle);
312
   }
313
 
314
   set_viewport(0, 0, WIDTH, HEIGHT, 30, 1000);
315
   set_vertices();
316
   set_vertex_shader();
317
   set_fragment_shader();
318
}
319
 
320
 
321
static void options(int argc, char *argv[])
322
{
323
   int i;
324
 
325
   for (i = 1; i < argc;) {
326
      if (graw_parse_args(&i, argc, argv)) {
327
         continue;
328
      }
329
      if (strcmp(argv[i], "-e") == 0) {
330
         draw_elements = 1;
331
         i++;
332
      }
333
      else {
334
         i++;
335
      }
336
   }
337
   if (draw_elements)
338
      printf("Using pipe_context::draw_elements_instanced()\n");
339
   else
340
      printf("Using pipe_context::draw_arrays_instanced()\n");
341
}
342
 
343
 
344
int main( int argc, char *argv[] )
345
{
346
   options(argc, argv);
347
 
348
   init();
349
 
350
   graw_set_display_func( draw );
351
   graw_main_loop();
352
   return 0;
353
}