Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/drivers/softpipe/sp_prim_vbuf.c
4570 views
1
/**************************************************************************
2
*
3
* Copyright 2007 VMware, Inc.
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 VMWARE 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
enum pipe_prim_type 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, enum pipe_prim_type 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.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.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
/*
591
* FIXME: it is unclear if primitives_storage_needed (which is generally
592
* the same as pipe query num_primitives_generated) should increase
593
* if SO is disabled for d3d10, but for GL we definitely need to
594
* increase num_primitives_generated and this is only called for active
595
* SO. If it must not increase for d3d10 need to disambiguate the counters
596
* in the driver and do some work for getting correct values, if it should
597
* increase too should call this from outside streamout code.
598
*/
599
static void
600
sp_vbuf_so_info(struct vbuf_render *vbr, uint stream, uint primitives, uint prim_generated)
601
{
602
struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
603
struct softpipe_context *softpipe = cvbr->softpipe;
604
605
softpipe->so_stats[stream].num_primitives_written += primitives;
606
softpipe->so_stats[stream].primitives_storage_needed += prim_generated;
607
}
608
609
static void
610
sp_vbuf_pipeline_statistics(
611
struct vbuf_render *vbr,
612
const struct pipe_query_data_pipeline_statistics *stats)
613
{
614
struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
615
struct softpipe_context *softpipe = cvbr->softpipe;
616
617
softpipe->pipeline_statistics.ia_vertices +=
618
stats->ia_vertices;
619
softpipe->pipeline_statistics.ia_primitives +=
620
stats->ia_primitives;
621
softpipe->pipeline_statistics.vs_invocations +=
622
stats->vs_invocations;
623
softpipe->pipeline_statistics.gs_invocations +=
624
stats->gs_invocations;
625
softpipe->pipeline_statistics.gs_primitives +=
626
stats->gs_primitives;
627
softpipe->pipeline_statistics.c_invocations +=
628
stats->c_invocations;
629
}
630
631
632
static void
633
sp_vbuf_destroy(struct vbuf_render *vbr)
634
{
635
struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
636
if (cvbr->vertex_buffer)
637
align_free(cvbr->vertex_buffer);
638
sp_setup_destroy_context(cvbr->setup);
639
FREE(cvbr);
640
}
641
642
643
/**
644
* Create the post-transform vertex handler for the given context.
645
*/
646
struct vbuf_render *
647
sp_create_vbuf_backend(struct softpipe_context *sp)
648
{
649
struct softpipe_vbuf_render *cvbr = CALLOC_STRUCT(softpipe_vbuf_render);
650
651
assert(sp->draw);
652
653
cvbr->base.max_indices = SP_MAX_VBUF_INDEXES;
654
cvbr->base.max_vertex_buffer_bytes = SP_MAX_VBUF_SIZE;
655
656
cvbr->base.get_vertex_info = sp_vbuf_get_vertex_info;
657
cvbr->base.allocate_vertices = sp_vbuf_allocate_vertices;
658
cvbr->base.map_vertices = sp_vbuf_map_vertices;
659
cvbr->base.unmap_vertices = sp_vbuf_unmap_vertices;
660
cvbr->base.set_primitive = sp_vbuf_set_primitive;
661
cvbr->base.draw_elements = sp_vbuf_draw_elements;
662
cvbr->base.draw_arrays = sp_vbuf_draw_arrays;
663
cvbr->base.release_vertices = sp_vbuf_release_vertices;
664
cvbr->base.set_stream_output_info = sp_vbuf_so_info;
665
cvbr->base.pipeline_statistics = sp_vbuf_pipeline_statistics;
666
cvbr->base.destroy = sp_vbuf_destroy;
667
668
cvbr->softpipe = sp;
669
670
cvbr->setup = sp_setup_create_context(cvbr->softpipe);
671
672
return &cvbr->base;
673
}
674
675