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
/**************************************************************************
2
 *
3
 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
4
 * All Rights Reserved.
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a
7
 * copy of this software and associated documentation files (the
8
 * "Software"), to deal in the Software without restriction, including
9
 * without limitation the rights to use, copy, modify, merge, publish,
10
 * distribute, sub license, and/or sell copies of the Software, and to
11
 * permit persons to whom the Software is furnished to do so, subject to
12
 * the following conditions:
13
 *
14
 * The above copyright notice and this permission notice (including the
15
 * next paragraph) shall be included in all copies or substantial portions
16
 * of the Software.
17
 *
18
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21
 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
 *
26
 **************************************************************************/
27
 
28
/**
29
 * Interface between 'draw' module's output and the softpipe rasterizer/setup
30
 * code.  When the 'draw' module has finished filling a vertex buffer, the
31
 * draw_arrays() functions below will be called.  Loop over the vertices and
32
 * call the point/line/tri setup functions.
33
 *
34
 * Authors
35
 *  Brian Paul
36
 */
37
 
38
 
39
#include "sp_context.h"
40
#include "sp_setup.h"
41
#include "sp_state.h"
42
#include "sp_prim_vbuf.h"
43
#include "draw/draw_context.h"
44
#include "draw/draw_vbuf.h"
45
#include "util/u_memory.h"
46
#include "util/u_prim.h"
47
 
48
 
49
#define SP_MAX_VBUF_INDEXES 1024
50
#define SP_MAX_VBUF_SIZE    4096
51
 
52
typedef const float (*cptrf4)[4];
53
 
54
/**
55
 * Subclass of vbuf_render.
56
 */
57
struct softpipe_vbuf_render
58
{
59
   struct vbuf_render base;
60
   struct softpipe_context *softpipe;
61
   struct setup_context *setup;
62
 
63
   uint prim;
64
   uint vertex_size;
65
   uint nr_vertices;
66
   uint vertex_buffer_size;
67
   void *vertex_buffer;
68
};
69
 
70
 
71
/** cast wrapper */
72
static struct softpipe_vbuf_render *
73
softpipe_vbuf_render(struct vbuf_render *vbr)
74
{
75
   return (struct softpipe_vbuf_render *) vbr;
76
}
77
 
78
 
79
/** This tells the draw module about our desired vertex layout */
80
static const struct vertex_info *
81
sp_vbuf_get_vertex_info(struct vbuf_render *vbr)
82
{
83
   struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
84
   return softpipe_get_vbuf_vertex_info(cvbr->softpipe);
85
}
86
 
87
 
88
static boolean
89
sp_vbuf_allocate_vertices(struct vbuf_render *vbr,
90
                          ushort vertex_size, ushort nr_vertices)
91
{
92
   struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
93
   unsigned size = vertex_size * nr_vertices;
94
 
95
   if (cvbr->vertex_buffer_size < size) {
96
      align_free(cvbr->vertex_buffer);
97
      cvbr->vertex_buffer = align_malloc(size, 16);
98
      cvbr->vertex_buffer_size = size;
99
   }
100
 
101
   cvbr->vertex_size = vertex_size;
102
   cvbr->nr_vertices = nr_vertices;
103
 
104
   return cvbr->vertex_buffer != NULL;
105
}
106
 
107
 
108
static void
109
sp_vbuf_release_vertices(struct vbuf_render *vbr)
110
{
111
   /* keep the old allocation for next time */
112
}
113
 
114
 
115
static void *
116
sp_vbuf_map_vertices(struct vbuf_render *vbr)
117
{
118
   struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
119
   return cvbr->vertex_buffer;
120
}
121
 
122
 
123
static void
124
sp_vbuf_unmap_vertices(struct vbuf_render *vbr,
125
                       ushort min_index,
126
                       ushort max_index )
127
{
128
   struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
129
   assert( cvbr->vertex_buffer_size >= (max_index+1) * cvbr->vertex_size );
130
   (void) cvbr;
131
   /* do nothing */
132
}
133
 
134
 
135
static void
136
sp_vbuf_set_primitive(struct vbuf_render *vbr, unsigned prim)
137
{
138
   struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
139
   struct setup_context *setup_ctx = cvbr->setup;
140
 
141
   sp_setup_prepare( setup_ctx );
142
 
143
   cvbr->softpipe->reduced_prim = u_reduced_prim(prim);
144
   cvbr->prim = prim;
145
}
146
 
147
 
148
static INLINE cptrf4 get_vert( const void *vertex_buffer,
149
                               int index,
150
                               int stride )
151
{
152
   return (cptrf4)((char *)vertex_buffer + index * stride);
153
}
154
 
155
 
156
/**
157
 * draw elements / indexed primitives
158
 */
159
static void
160
sp_vbuf_draw_elements(struct vbuf_render *vbr, const ushort *indices, uint nr)
161
{
162
   struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
163
   struct softpipe_context *softpipe = cvbr->softpipe;
164
   const unsigned stride = softpipe->vertex_info_vbuf.size * sizeof(float);
165
   const void *vertex_buffer = cvbr->vertex_buffer;
166
   struct setup_context *setup = cvbr->setup;
167
   const boolean flatshade_first = softpipe->rasterizer->flatshade_first;
168
   unsigned i;
169
 
170
   switch (cvbr->prim) {
171
   case PIPE_PRIM_POINTS:
172
      for (i = 0; i < nr; i++) {
173
         sp_setup_point( setup,
174
                         get_vert(vertex_buffer, indices[i-0], stride) );
175
      }
176
      break;
177
 
178
   case PIPE_PRIM_LINES:
179
      for (i = 1; i < nr; i += 2) {
180
         sp_setup_line( setup,
181
                        get_vert(vertex_buffer, indices[i-1], stride),
182
                        get_vert(vertex_buffer, indices[i-0], stride) );
183
      }
184
      break;
185
 
186
   case PIPE_PRIM_LINE_STRIP:
187
      for (i = 1; i < nr; i ++) {
188
         sp_setup_line( setup,
189
                        get_vert(vertex_buffer, indices[i-1], stride),
190
                        get_vert(vertex_buffer, indices[i-0], stride) );
191
      }
192
      break;
193
 
194
   case PIPE_PRIM_LINE_LOOP:
195
      for (i = 1; i < nr; i ++) {
196
         sp_setup_line( setup,
197
                        get_vert(vertex_buffer, indices[i-1], stride),
198
                        get_vert(vertex_buffer, indices[i-0], stride) );
199
      }
200
      if (nr) {
201
         sp_setup_line( setup,
202
                        get_vert(vertex_buffer, indices[nr-1], stride),
203
                        get_vert(vertex_buffer, indices[0], stride) );
204
      }
205
      break;
206
 
207
   case PIPE_PRIM_TRIANGLES:
208
      for (i = 2; i < nr; i += 3) {
209
         sp_setup_tri( setup,
210
                       get_vert(vertex_buffer, indices[i-2], stride),
211
                       get_vert(vertex_buffer, indices[i-1], stride),
212
                       get_vert(vertex_buffer, indices[i-0], stride) );
213
      }
214
      break;
215
 
216
   case PIPE_PRIM_TRIANGLE_STRIP:
217
      if (flatshade_first) {
218
         for (i = 2; i < nr; i += 1) {
219
            /* emit first triangle vertex as first triangle vertex */
220
            sp_setup_tri( setup,
221
                          get_vert(vertex_buffer, indices[i-2], stride),
222
                          get_vert(vertex_buffer, indices[i+(i&1)-1], stride),
223
                          get_vert(vertex_buffer, indices[i-(i&1)], stride) );
224
 
225
         }
226
      }
227
      else {
228
         for (i = 2; i < nr; i += 1) {
229
            /* emit last triangle vertex as last triangle vertex */
230
            sp_setup_tri( setup,
231
                          get_vert(vertex_buffer, indices[i+(i&1)-2], stride),
232
                          get_vert(vertex_buffer, indices[i-(i&1)-1], stride),
233
                          get_vert(vertex_buffer, indices[i-0], stride) );
234
         }
235
      }
236
      break;
237
 
238
   case PIPE_PRIM_TRIANGLE_FAN:
239
      if (flatshade_first) {
240
         for (i = 2; i < nr; i += 1) {
241
            /* emit first non-spoke vertex as first vertex */
242
            sp_setup_tri( setup,
243
                          get_vert(vertex_buffer, indices[i-1], stride),
244
                          get_vert(vertex_buffer, indices[i-0], stride),
245
                          get_vert(vertex_buffer, indices[0], stride) );
246
         }
247
      }
248
      else {
249
         for (i = 2; i < nr; i += 1) {
250
            /* emit last non-spoke vertex as last vertex */
251
            sp_setup_tri( setup,
252
                          get_vert(vertex_buffer, indices[0], stride),
253
                          get_vert(vertex_buffer, indices[i-1], stride),
254
                          get_vert(vertex_buffer, indices[i-0], stride) );
255
         }
256
      }
257
      break;
258
 
259
   case PIPE_PRIM_QUADS:
260
      /* GL quads don't follow provoking vertex convention */
261
      if (flatshade_first) {
262
         /* emit last quad vertex as first triangle vertex */
263
         for (i = 3; i < nr; i += 4) {
264
            sp_setup_tri( setup,
265
                          get_vert(vertex_buffer, indices[i-0], stride),
266
                          get_vert(vertex_buffer, indices[i-3], stride),
267
                          get_vert(vertex_buffer, indices[i-2], stride) );
268
 
269
            sp_setup_tri( setup,
270
                          get_vert(vertex_buffer, indices[i-0], stride),
271
                          get_vert(vertex_buffer, indices[i-2], stride),
272
                          get_vert(vertex_buffer, indices[i-1], stride) );
273
         }
274
      }
275
      else {
276
         /* emit last quad vertex as last triangle vertex */
277
         for (i = 3; i < nr; i += 4) {
278
            sp_setup_tri( setup,
279
                          get_vert(vertex_buffer, indices[i-3], stride),
280
                          get_vert(vertex_buffer, indices[i-2], stride),
281
                          get_vert(vertex_buffer, indices[i-0], stride) );
282
 
283
            sp_setup_tri( setup,
284
                          get_vert(vertex_buffer, indices[i-2], stride),
285
                          get_vert(vertex_buffer, indices[i-1], stride),
286
                          get_vert(vertex_buffer, indices[i-0], stride) );
287
         }
288
      }
289
      break;
290
 
291
   case PIPE_PRIM_QUAD_STRIP:
292
      /* GL quad strips don't follow provoking vertex convention */
293
      if (flatshade_first) {
294
         /* emit last quad vertex as first triangle vertex */
295
         for (i = 3; i < nr; i += 2) {
296
            sp_setup_tri( setup,
297
                          get_vert(vertex_buffer, indices[i-0], stride),
298
                          get_vert(vertex_buffer, indices[i-3], stride),
299
                          get_vert(vertex_buffer, indices[i-2], stride) );
300
            sp_setup_tri( setup,
301
                          get_vert(vertex_buffer, indices[i-0], stride),
302
                          get_vert(vertex_buffer, indices[i-1], stride),
303
                          get_vert(vertex_buffer, indices[i-3], stride) );
304
         }
305
      }
306
      else {
307
         /* emit last quad vertex as last triangle vertex */
308
         for (i = 3; i < nr; i += 2) {
309
            sp_setup_tri( setup,
310
                          get_vert(vertex_buffer, indices[i-3], stride),
311
                          get_vert(vertex_buffer, indices[i-2], stride),
312
                          get_vert(vertex_buffer, indices[i-0], stride) );
313
            sp_setup_tri( setup,
314
                          get_vert(vertex_buffer, indices[i-1], stride),
315
                          get_vert(vertex_buffer, indices[i-3], stride),
316
                          get_vert(vertex_buffer, indices[i-0], stride) );
317
         }
318
      }
319
      break;
320
 
321
   case PIPE_PRIM_POLYGON:
322
      /* Almost same as tri fan but the _first_ vertex specifies the flat
323
       * shading color.
324
       */
325
      if (flatshade_first) {
326
         /* emit first polygon  vertex as first triangle vertex */
327
         for (i = 2; i < nr; i += 1) {
328
            sp_setup_tri( setup,
329
                          get_vert(vertex_buffer, indices[0], stride),
330
                          get_vert(vertex_buffer, indices[i-1], stride),
331
                          get_vert(vertex_buffer, indices[i-0], stride) );
332
         }
333
      }
334
      else {
335
         /* emit first polygon  vertex as last triangle vertex */
336
         for (i = 2; i < nr; i += 1) {
337
            sp_setup_tri( setup,
338
                          get_vert(vertex_buffer, indices[i-1], stride),
339
                          get_vert(vertex_buffer, indices[i-0], stride),
340
                          get_vert(vertex_buffer, indices[0], stride) );
341
         }
342
      }
343
      break;
344
 
345
   default:
346
      assert(0);
347
   }
348
}
349
 
350
 
351
/**
352
 * This function is hit when the draw module is working in pass-through mode.
353
 * It's up to us to convert the vertex array into point/line/tri prims.
354
 */
355
static void
356
sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr)
357
{
358
   struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
359
   struct softpipe_context *softpipe = cvbr->softpipe;
360
   struct setup_context *setup = cvbr->setup;
361
   const unsigned stride = softpipe->vertex_info_vbuf.size * sizeof(float);
362
   const void *vertex_buffer =
363
      (void *) get_vert(cvbr->vertex_buffer, start, stride);
364
   const boolean flatshade_first = softpipe->rasterizer->flatshade_first;
365
   unsigned i;
366
 
367
   switch (cvbr->prim) {
368
   case PIPE_PRIM_POINTS:
369
      for (i = 0; i < nr; i++) {
370
         sp_setup_point( setup,
371
                         get_vert(vertex_buffer, i-0, stride) );
372
      }
373
      break;
374
 
375
   case PIPE_PRIM_LINES:
376
      for (i = 1; i < nr; i += 2) {
377
         sp_setup_line( setup,
378
                        get_vert(vertex_buffer, i-1, stride),
379
                        get_vert(vertex_buffer, i-0, stride) );
380
      }
381
      break;
382
 
383
   case PIPE_PRIM_LINES_ADJACENCY:
384
      for (i = 3; i < nr; i += 4) {
385
         sp_setup_line( setup,
386
                        get_vert(vertex_buffer, i-2, stride),
387
                        get_vert(vertex_buffer, i-1, stride) );
388
      }
389
      break;
390
 
391
   case PIPE_PRIM_LINE_STRIP:
392
      for (i = 1; i < nr; i ++) {
393
         sp_setup_line( setup,
394
                     get_vert(vertex_buffer, i-1, stride),
395
                     get_vert(vertex_buffer, i-0, stride) );
396
      }
397
      break;
398
 
399
   case PIPE_PRIM_LINE_STRIP_ADJACENCY:
400
      for (i = 3; i < nr; i++) {
401
         sp_setup_line( setup,
402
                     get_vert(vertex_buffer, i-2, stride),
403
                     get_vert(vertex_buffer, i-1, stride) );
404
      }
405
      break;
406
 
407
   case PIPE_PRIM_LINE_LOOP:
408
      for (i = 1; i < nr; i ++) {
409
         sp_setup_line( setup,
410
                        get_vert(vertex_buffer, i-1, stride),
411
                        get_vert(vertex_buffer, i-0, stride) );
412
      }
413
      if (nr) {
414
         sp_setup_line( setup,
415
                        get_vert(vertex_buffer, nr-1, stride),
416
                        get_vert(vertex_buffer, 0, stride) );
417
      }
418
      break;
419
 
420
   case PIPE_PRIM_TRIANGLES:
421
      for (i = 2; i < nr; i += 3) {
422
         sp_setup_tri( setup,
423
                       get_vert(vertex_buffer, i-2, stride),
424
                       get_vert(vertex_buffer, i-1, stride),
425
                       get_vert(vertex_buffer, i-0, stride) );
426
      }
427
      break;
428
 
429
   case PIPE_PRIM_TRIANGLES_ADJACENCY:
430
      for (i = 5; i < nr; i += 6) {
431
         sp_setup_tri( setup,
432
                       get_vert(vertex_buffer, i-5, stride),
433
                       get_vert(vertex_buffer, i-3, stride),
434
                       get_vert(vertex_buffer, i-1, stride) );
435
      }
436
      break;
437
 
438
   case PIPE_PRIM_TRIANGLE_STRIP:
439
      if (flatshade_first) {
440
         for (i = 2; i < nr; i++) {
441
            /* emit first triangle vertex as first triangle vertex */
442
            sp_setup_tri( setup,
443
                          get_vert(vertex_buffer, i-2, stride),
444
                          get_vert(vertex_buffer, i+(i&1)-1, stride),
445
                          get_vert(vertex_buffer, i-(i&1), stride) );
446
         }
447
      }
448
      else {
449
         for (i = 2; i < nr; i++) {
450
            /* emit last triangle vertex as last triangle vertex */
451
            sp_setup_tri( setup,
452
                          get_vert(vertex_buffer, i+(i&1)-2, stride),
453
                          get_vert(vertex_buffer, i-(i&1)-1, stride),
454
                          get_vert(vertex_buffer, i-0, stride) );
455
         }
456
      }
457
      break;
458
 
459
   case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
460
      if (flatshade_first) {
461
         for (i = 5; i < nr; i += 2) {
462
            /* emit first triangle vertex as first triangle vertex */
463
            sp_setup_tri( setup,
464
                          get_vert(vertex_buffer, i-5, stride),
465
                          get_vert(vertex_buffer, i+(i&1)*2-3, stride),
466
                          get_vert(vertex_buffer, i-(i&1)*2-1, stride) );
467
         }
468
      }
469
      else {
470
         for (i = 5; i < nr; i += 2) {
471
            /* emit last triangle vertex as last triangle vertex */
472
            sp_setup_tri( setup,
473
                          get_vert(vertex_buffer, i+(i&1)*2-5, stride),
474
                          get_vert(vertex_buffer, i-(i&1)*2-3, stride),
475
                          get_vert(vertex_buffer, i-1, stride) );
476
         }
477
      }
478
      break;
479
 
480
   case PIPE_PRIM_TRIANGLE_FAN:
481
      if (flatshade_first) {
482
         for (i = 2; i < nr; i += 1) {
483
            /* emit first non-spoke vertex as first vertex */
484
            sp_setup_tri( setup,
485
                          get_vert(vertex_buffer, i-1, stride),
486
                          get_vert(vertex_buffer, i-0, stride),
487
                          get_vert(vertex_buffer, 0, stride)  );
488
         }
489
      }
490
      else {
491
         for (i = 2; i < nr; i += 1) {
492
            /* emit last non-spoke vertex as last vertex */
493
            sp_setup_tri( setup,
494
                          get_vert(vertex_buffer, 0, stride),
495
                          get_vert(vertex_buffer, i-1, stride),
496
                          get_vert(vertex_buffer, i-0, stride) );
497
         }
498
      }
499
      break;
500
 
501
   case PIPE_PRIM_QUADS:
502
      /* GL quads don't follow provoking vertex convention */
503
      if (flatshade_first) {
504
         /* emit last quad vertex as first triangle vertex */
505
         for (i = 3; i < nr; i += 4) {
506
            sp_setup_tri( setup,
507
                          get_vert(vertex_buffer, i-0, stride),
508
                          get_vert(vertex_buffer, i-3, stride),
509
                          get_vert(vertex_buffer, i-2, stride) );
510
            sp_setup_tri( setup,
511
                          get_vert(vertex_buffer, i-0, stride),
512
                          get_vert(vertex_buffer, i-2, stride),
513
                          get_vert(vertex_buffer, i-1, stride) );
514
         }
515
      }
516
      else {
517
         /* emit last quad vertex as last triangle vertex */
518
         for (i = 3; i < nr; i += 4) {
519
            sp_setup_tri( setup,
520
                          get_vert(vertex_buffer, i-3, stride),
521
                          get_vert(vertex_buffer, i-2, stride),
522
                          get_vert(vertex_buffer, i-0, stride) );
523
            sp_setup_tri( setup,
524
                          get_vert(vertex_buffer, i-2, stride),
525
                          get_vert(vertex_buffer, i-1, stride),
526
                          get_vert(vertex_buffer, i-0, stride) );
527
         }
528
      }
529
      break;
530
 
531
   case PIPE_PRIM_QUAD_STRIP:
532
      /* GL quad strips don't follow provoking vertex convention */
533
      if (flatshade_first) {
534
         /* emit last quad vertex as first triangle vertex */
535
         for (i = 3; i < nr; i += 2) {
536
            sp_setup_tri( setup,
537
                          get_vert(vertex_buffer, i-0, stride),
538
                          get_vert(vertex_buffer, i-3, stride),
539
                          get_vert(vertex_buffer, i-2, stride) );
540
            sp_setup_tri( setup,
541
                          get_vert(vertex_buffer, i-0, stride),
542
                          get_vert(vertex_buffer, i-1, stride),
543
                          get_vert(vertex_buffer, i-3, stride) );
544
         }
545
      }
546
      else {
547
         /* emit last quad vertex as last triangle vertex */
548
         for (i = 3; i < nr; i += 2) {
549
            sp_setup_tri( setup,
550
                          get_vert(vertex_buffer, i-3, stride),
551
                          get_vert(vertex_buffer, i-2, stride),
552
                          get_vert(vertex_buffer, i-0, stride) );
553
            sp_setup_tri( setup,
554
                          get_vert(vertex_buffer, i-1, stride),
555
                          get_vert(vertex_buffer, i-3, stride),
556
                          get_vert(vertex_buffer, i-0, stride) );
557
         }
558
      }
559
      break;
560
 
561
   case PIPE_PRIM_POLYGON:
562
      /* Almost same as tri fan but the _first_ vertex specifies the flat
563
       * shading color.
564
       */
565
      if (flatshade_first) {
566
         /* emit first polygon  vertex as first triangle vertex */
567
         for (i = 2; i < nr; i += 1) {
568
            sp_setup_tri( setup,
569
                          get_vert(vertex_buffer, 0, stride),
570
                          get_vert(vertex_buffer, i-1, stride),
571
                          get_vert(vertex_buffer, i-0, stride) );
572
         }
573
      }
574
      else {
575
         /* emit first polygon  vertex as last triangle vertex */
576
         for (i = 2; i < nr; i += 1) {
577
            sp_setup_tri( setup,
578
                          get_vert(vertex_buffer, i-1, stride),
579
                          get_vert(vertex_buffer, i-0, stride),
580
                          get_vert(vertex_buffer, 0, stride) );
581
         }
582
      }
583
      break;
584
 
585
   default:
586
      assert(0);
587
   }
588
}
589
 
590
static void
591
sp_vbuf_so_info(struct vbuf_render *vbr, uint primitives, uint vertices,
592
                uint prim_generated)
593
{
594
   struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
595
   struct softpipe_context *softpipe = cvbr->softpipe;
596
 
597
   softpipe->so_stats.num_primitives_written += primitives;
598
   softpipe->so_stats.primitives_storage_needed =
599
      vertices * 4 /*sizeof(float|int32)*/ * 4 /*x,y,z,w*/;
600
   softpipe->num_primitives_generated += prim_generated;
601
}
602
 
603
static void
604
sp_vbuf_pipeline_statistics(
605
   struct vbuf_render *vbr,
606
   const struct pipe_query_data_pipeline_statistics *stats)
607
{
608
   struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
609
   struct softpipe_context *softpipe = cvbr->softpipe;
610
 
611
   softpipe->pipeline_statistics.ia_vertices +=
612
      stats->ia_vertices;
613
   softpipe->pipeline_statistics.ia_primitives +=
614
      stats->ia_primitives;
615
   softpipe->pipeline_statistics.vs_invocations +=
616
      stats->vs_invocations;
617
   softpipe->pipeline_statistics.gs_invocations +=
618
      stats->gs_invocations;
619
   softpipe->pipeline_statistics.gs_primitives +=
620
      stats->gs_primitives;
621
   softpipe->pipeline_statistics.c_invocations +=
622
      stats->c_invocations;
623
}
624
 
625
 
626
static void
627
sp_vbuf_destroy(struct vbuf_render *vbr)
628
{
629
   struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
630
   if (cvbr->vertex_buffer)
631
      align_free(cvbr->vertex_buffer);
632
   sp_setup_destroy_context(cvbr->setup);
633
   FREE(cvbr);
634
}
635
 
636
 
637
/**
638
 * Create the post-transform vertex handler for the given context.
639
 */
640
struct vbuf_render *
641
sp_create_vbuf_backend(struct softpipe_context *sp)
642
{
643
   struct softpipe_vbuf_render *cvbr = CALLOC_STRUCT(softpipe_vbuf_render);
644
 
645
   assert(sp->draw);
646
 
647
   cvbr->base.max_indices = SP_MAX_VBUF_INDEXES;
648
   cvbr->base.max_vertex_buffer_bytes = SP_MAX_VBUF_SIZE;
649
 
650
   cvbr->base.get_vertex_info = sp_vbuf_get_vertex_info;
651
   cvbr->base.allocate_vertices = sp_vbuf_allocate_vertices;
652
   cvbr->base.map_vertices = sp_vbuf_map_vertices;
653
   cvbr->base.unmap_vertices = sp_vbuf_unmap_vertices;
654
   cvbr->base.set_primitive = sp_vbuf_set_primitive;
655
   cvbr->base.draw_elements = sp_vbuf_draw_elements;
656
   cvbr->base.draw_arrays = sp_vbuf_draw_arrays;
657
   cvbr->base.release_vertices = sp_vbuf_release_vertices;
658
   cvbr->base.set_stream_output_info = sp_vbuf_so_info;
659
   cvbr->base.pipeline_statistics = sp_vbuf_pipeline_statistics;
660
   cvbr->base.destroy = sp_vbuf_destroy;
661
 
662
   cvbr->softpipe = sp;
663
 
664
   cvbr->setup = sp_setup_create_context(cvbr->softpipe);
665
 
666
   return &cvbr->base;
667
}