160
158
* draw elements / indexed primitives
163
sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr)
161
sp_vbuf_draw_elements(struct vbuf_render *vbr, const ushort *indices, uint nr)
165
163
struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
166
164
struct softpipe_context *softpipe = cvbr->softpipe;
167
165
const unsigned stride = softpipe->vertex_info_vbuf.size * sizeof(float);
168
166
const void *vertex_buffer = cvbr->vertex_buffer;
169
struct setup_context *setup_ctx = cvbr->setup;
167
struct setup_context *setup = cvbr->setup;
168
const boolean flatshade_first = softpipe->rasterizer->flatshade_first;
172
171
switch (cvbr->prim) {
173
172
case PIPE_PRIM_POINTS:
174
173
for (i = 0; i < nr; i++) {
175
sp_setup_point( setup_ctx,
176
get_vert(vertex_buffer, indices[i-0], stride) );
174
sp_setup_point( setup,
175
get_vert(vertex_buffer, indices[i-0], stride) );
180
179
case PIPE_PRIM_LINES:
181
180
for (i = 1; i < nr; i += 2) {
182
sp_setup_line( setup_ctx,
183
get_vert(vertex_buffer, indices[i-1], stride),
184
get_vert(vertex_buffer, indices[i-0], stride) );
181
sp_setup_line( setup,
182
get_vert(vertex_buffer, indices[i-1], stride),
183
get_vert(vertex_buffer, indices[i-0], stride) );
188
187
case PIPE_PRIM_LINE_STRIP:
189
188
for (i = 1; i < nr; i ++) {
190
sp_setup_line( setup_ctx,
191
get_vert(vertex_buffer, indices[i-1], stride),
192
get_vert(vertex_buffer, indices[i-0], stride) );
189
sp_setup_line( setup,
190
get_vert(vertex_buffer, indices[i-1], stride),
191
get_vert(vertex_buffer, indices[i-0], stride) );
196
195
case PIPE_PRIM_LINE_LOOP:
197
196
for (i = 1; i < nr; i ++) {
198
sp_setup_line( setup_ctx,
199
get_vert(vertex_buffer, indices[i-1], stride),
200
get_vert(vertex_buffer, indices[i-0], stride) );
197
sp_setup_line( setup,
198
get_vert(vertex_buffer, indices[i-1], stride),
199
get_vert(vertex_buffer, indices[i-0], stride) );
203
sp_setup_line( setup_ctx,
204
get_vert(vertex_buffer, indices[nr-1], stride),
205
get_vert(vertex_buffer, indices[0], stride) );
202
sp_setup_line( setup,
203
get_vert(vertex_buffer, indices[nr-1], stride),
204
get_vert(vertex_buffer, indices[0], stride) );
209
208
case PIPE_PRIM_TRIANGLES:
210
if (softpipe->rasterizer->flatshade_first) {
211
for (i = 2; i < nr; i += 3) {
212
sp_setup_tri( setup_ctx,
213
get_vert(vertex_buffer, indices[i-1], stride),
214
get_vert(vertex_buffer, indices[i-0], stride),
215
get_vert(vertex_buffer, indices[i-2], stride) );
219
for (i = 2; i < nr; i += 3) {
220
sp_setup_tri( setup_ctx,
209
for (i = 2; i < nr; i += 3) {
221
211
get_vert(vertex_buffer, indices[i-2], stride),
222
212
get_vert(vertex_buffer, indices[i-1], stride),
223
213
get_vert(vertex_buffer, indices[i-0], stride) );
228
217
case PIPE_PRIM_TRIANGLE_STRIP:
229
if (softpipe->rasterizer->flatshade_first) {
218
if (flatshade_first) {
230
219
for (i = 2; i < nr; i += 1) {
231
sp_setup_tri( setup_ctx,
232
get_vert(vertex_buffer, indices[i+(i&1)-1], stride),
233
get_vert(vertex_buffer, indices[i-(i&1)], stride),
234
get_vert(vertex_buffer, indices[i-2], stride) );
220
/* emit first triangle vertex as first triangle vertex */
222
get_vert(vertex_buffer, indices[i-2], stride),
223
get_vert(vertex_buffer, indices[i+(i&1)-1], stride),
224
get_vert(vertex_buffer, indices[i-(i&1)], stride) );
238
229
for (i = 2; i < nr; i += 1) {
239
sp_setup_tri( setup_ctx,
240
get_vert(vertex_buffer, indices[i+(i&1)-2], stride),
241
get_vert(vertex_buffer, indices[i-(i&1)-1], stride),
242
get_vert(vertex_buffer, indices[i-0], stride) );
230
/* emit last triangle vertex as last triangle vertex */
232
get_vert(vertex_buffer, indices[i+(i&1)-2], stride),
233
get_vert(vertex_buffer, indices[i-(i&1)-1], stride),
234
get_vert(vertex_buffer, indices[i-0], stride) );
247
239
case PIPE_PRIM_TRIANGLE_FAN:
248
if (softpipe->rasterizer->flatshade_first) {
240
if (flatshade_first) {
249
241
for (i = 2; i < nr; i += 1) {
250
sp_setup_tri( setup_ctx,
251
get_vert(vertex_buffer, indices[i-0], stride),
252
get_vert(vertex_buffer, indices[0], stride),
253
get_vert(vertex_buffer, indices[i-1], stride) );
242
/* emit first non-spoke vertex as first vertex */
244
get_vert(vertex_buffer, indices[i-1], stride),
245
get_vert(vertex_buffer, indices[i-0], stride),
246
get_vert(vertex_buffer, indices[0], stride) );
257
250
for (i = 2; i < nr; i += 1) {
258
sp_setup_tri( setup_ctx,
259
get_vert(vertex_buffer, indices[0], stride),
260
get_vert(vertex_buffer, indices[i-1], stride),
261
get_vert(vertex_buffer, indices[i-0], stride) );
251
/* emit last non-spoke vertex as last vertex */
253
get_vert(vertex_buffer, indices[0], stride),
254
get_vert(vertex_buffer, indices[i-1], stride),
255
get_vert(vertex_buffer, indices[i-0], stride) );
266
260
case PIPE_PRIM_QUADS:
267
if (softpipe->rasterizer->flatshade_first) {
261
/* GL quads don't follow provoking vertex convention */
262
if (flatshade_first) {
263
/* emit last quad vertex as first triangle vertex */
268
264
for (i = 3; i < nr; i += 4) {
269
sp_setup_tri( setup_ctx,
270
get_vert(vertex_buffer, indices[i-2], stride),
271
get_vert(vertex_buffer, indices[i-1], stride),
272
get_vert(vertex_buffer, indices[i-3], stride) );
273
sp_setup_tri( setup_ctx,
274
get_vert(vertex_buffer, indices[i-1], stride),
275
get_vert(vertex_buffer, indices[i-0], stride),
276
get_vert(vertex_buffer, indices[i-3], stride) );
266
get_vert(vertex_buffer, indices[i-0], stride),
267
get_vert(vertex_buffer, indices[i-3], stride),
268
get_vert(vertex_buffer, indices[i-2], stride) );
271
get_vert(vertex_buffer, indices[i-0], stride),
272
get_vert(vertex_buffer, indices[i-2], stride),
273
get_vert(vertex_buffer, indices[i-1], stride) );
277
/* emit last quad vertex as last triangle vertex */
280
278
for (i = 3; i < nr; i += 4) {
281
sp_setup_tri( setup_ctx,
282
get_vert(vertex_buffer, indices[i-3], stride),
283
get_vert(vertex_buffer, indices[i-2], stride),
284
get_vert(vertex_buffer, indices[i-0], stride) );
280
get_vert(vertex_buffer, indices[i-3], stride),
281
get_vert(vertex_buffer, indices[i-2], stride),
282
get_vert(vertex_buffer, indices[i-0], stride) );
286
sp_setup_tri( setup_ctx,
287
get_vert(vertex_buffer, indices[i-2], stride),
288
get_vert(vertex_buffer, indices[i-1], stride),
289
get_vert(vertex_buffer, indices[i-0], stride) );
285
get_vert(vertex_buffer, indices[i-2], stride),
286
get_vert(vertex_buffer, indices[i-1], stride),
287
get_vert(vertex_buffer, indices[i-0], stride) );
294
292
case PIPE_PRIM_QUAD_STRIP:
295
if (softpipe->rasterizer->flatshade_first) {
293
/* GL quad strips don't follow provoking vertex convention */
294
if (flatshade_first) {
295
/* emit last quad vertex as first triangle vertex */
296
296
for (i = 3; i < nr; i += 2) {
297
sp_setup_tri( setup_ctx,
298
get_vert(vertex_buffer, indices[i-0], stride),
299
get_vert(vertex_buffer, indices[i-1], stride),
300
get_vert(vertex_buffer, indices[i-3], stride));
301
sp_setup_tri( setup_ctx,
302
get_vert(vertex_buffer, indices[i-2], stride),
303
get_vert(vertex_buffer, indices[i-0], stride),
304
get_vert(vertex_buffer, indices[i-3], stride) );
298
get_vert(vertex_buffer, indices[i-0], stride),
299
get_vert(vertex_buffer, indices[i-3], stride),
300
get_vert(vertex_buffer, indices[i-2], stride) );
302
get_vert(vertex_buffer, indices[i-0], stride),
303
get_vert(vertex_buffer, indices[i-1], stride),
304
get_vert(vertex_buffer, indices[i-3], stride) );
308
/* emit last quad vertex as last triangle vertex */
308
309
for (i = 3; i < nr; i += 2) {
309
sp_setup_tri( setup_ctx,
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_ctx,
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) );
311
get_vert(vertex_buffer, indices[i-3], stride),
312
get_vert(vertex_buffer, indices[i-2], stride),
313
get_vert(vertex_buffer, indices[i-0], stride) );
315
get_vert(vertex_buffer, indices[i-1], stride),
316
get_vert(vertex_buffer, indices[i-3], stride),
317
get_vert(vertex_buffer, indices[i-0], stride) );
321
322
case PIPE_PRIM_POLYGON:
322
323
/* Almost same as tri fan but the _first_ vertex specifies the flat
323
* shading color. Note that the first polygon vertex is passed as
324
* the last triangle vertex here.
325
* flatshade_first state makes no difference.
327
for (i = 2; i < nr; i += 1) {
328
sp_setup_tri( setup_ctx,
329
get_vert(vertex_buffer, indices[i-0], stride),
330
get_vert(vertex_buffer, indices[i-1], stride),
331
get_vert(vertex_buffer, indices[0], stride) );
326
if (flatshade_first) {
327
/* emit first polygon vertex as first triangle vertex */
328
for (i = 2; i < nr; i += 1) {
330
get_vert(vertex_buffer, indices[0], stride),
331
get_vert(vertex_buffer, indices[i-1], stride),
332
get_vert(vertex_buffer, indices[i-0], stride) );
336
/* emit first polygon vertex as last triangle vertex */
337
for (i = 2; i < nr; i += 1) {
339
get_vert(vertex_buffer, indices[i-1], stride),
340
get_vert(vertex_buffer, indices[i-0], stride),
341
get_vert(vertex_buffer, indices[0], stride) );
380
392
case PIPE_PRIM_LINE_LOOP:
381
393
for (i = 1; i < nr; i ++) {
382
sp_setup_line( setup_ctx,
383
get_vert(vertex_buffer, i-1, stride),
384
get_vert(vertex_buffer, i-0, stride) );
394
sp_setup_line( setup,
395
get_vert(vertex_buffer, i-1, stride),
396
get_vert(vertex_buffer, i-0, stride) );
387
sp_setup_line( setup_ctx,
388
get_vert(vertex_buffer, nr-1, stride),
389
get_vert(vertex_buffer, 0, stride) );
399
sp_setup_line( setup,
400
get_vert(vertex_buffer, nr-1, stride),
401
get_vert(vertex_buffer, 0, stride) );
393
405
case PIPE_PRIM_TRIANGLES:
394
if (softpipe->rasterizer->flatshade_first) {
395
for (i = 2; i < nr; i += 3) {
396
sp_setup_tri( setup_ctx,
397
get_vert(vertex_buffer, i-1, stride),
398
get_vert(vertex_buffer, i-0, stride),
399
get_vert(vertex_buffer, i-2, stride) );
403
for (i = 2; i < nr; i += 3) {
404
sp_setup_tri( setup_ctx,
406
for (i = 2; i < nr; i += 3) {
405
408
get_vert(vertex_buffer, i-2, stride),
406
409
get_vert(vertex_buffer, i-1, stride),
407
410
get_vert(vertex_buffer, i-0, stride) );
412
414
case PIPE_PRIM_TRIANGLE_STRIP:
413
if (softpipe->rasterizer->flatshade_first) {
415
if (flatshade_first) {
414
416
for (i = 2; i < nr; i++) {
415
sp_setup_tri( setup_ctx,
416
get_vert(vertex_buffer, i+(i&1)-1, stride),
417
get_vert(vertex_buffer, i-(i&1), stride),
418
get_vert(vertex_buffer, i-2, stride) );
417
/* emit first triangle vertex as first triangle vertex */
419
get_vert(vertex_buffer, i-2, stride),
420
get_vert(vertex_buffer, i+(i&1)-1, stride),
421
get_vert(vertex_buffer, i-(i&1), stride) );
422
425
for (i = 2; i < nr; i++) {
423
sp_setup_tri( setup_ctx,
424
get_vert(vertex_buffer, i+(i&1)-2, stride),
425
get_vert(vertex_buffer, i-(i&1)-1, stride),
426
get_vert(vertex_buffer, i-0, stride) );
426
/* emit last triangle vertex as last triangle vertex */
428
get_vert(vertex_buffer, i+(i&1)-2, stride),
429
get_vert(vertex_buffer, i-(i&1)-1, stride),
430
get_vert(vertex_buffer, i-0, stride) );
431
435
case PIPE_PRIM_TRIANGLE_FAN:
432
if (softpipe->rasterizer->flatshade_first) {
436
if (flatshade_first) {
433
437
for (i = 2; i < nr; i += 1) {
434
sp_setup_tri( setup_ctx,
435
get_vert(vertex_buffer, i-0, stride),
436
get_vert(vertex_buffer, 0, stride),
437
get_vert(vertex_buffer, i-1, stride) );
438
/* emit first non-spoke vertex as first vertex */
440
get_vert(vertex_buffer, i-1, stride),
441
get_vert(vertex_buffer, i-0, stride),
442
get_vert(vertex_buffer, 0, stride) );
441
446
for (i = 2; i < nr; i += 1) {
442
sp_setup_tri( setup_ctx,
443
get_vert(vertex_buffer, 0, stride),
444
get_vert(vertex_buffer, i-1, stride),
445
get_vert(vertex_buffer, i-0, stride) );
447
/* emit last non-spoke vertex as last vertex */
449
get_vert(vertex_buffer, 0, stride),
450
get_vert(vertex_buffer, i-1, stride),
451
get_vert(vertex_buffer, i-0, stride) );
450
456
case PIPE_PRIM_QUADS:
451
if (softpipe->rasterizer->flatshade_first) {
457
/* GL quads don't follow provoking vertex convention */
458
if (flatshade_first) {
459
/* emit last quad vertex as first triangle vertex */
452
460
for (i = 3; i < nr; i += 4) {
453
sp_setup_tri( setup_ctx,
454
get_vert(vertex_buffer, i-2, stride),
455
get_vert(vertex_buffer, i-1, stride),
456
get_vert(vertex_buffer, i-3, stride) );
457
sp_setup_tri( setup_ctx,
458
get_vert(vertex_buffer, i-1, stride),
459
get_vert(vertex_buffer, i-0, stride),
460
get_vert(vertex_buffer, i-3, stride) );
462
get_vert(vertex_buffer, i-0, stride),
463
get_vert(vertex_buffer, i-3, stride),
464
get_vert(vertex_buffer, i-2, stride) );
466
get_vert(vertex_buffer, i-0, stride),
467
get_vert(vertex_buffer, i-2, stride),
468
get_vert(vertex_buffer, i-1, stride) );
472
/* emit last quad vertex as last triangle vertex */
464
473
for (i = 3; i < nr; i += 4) {
465
sp_setup_tri( setup_ctx,
466
get_vert(vertex_buffer, i-3, stride),
467
get_vert(vertex_buffer, i-2, stride),
468
get_vert(vertex_buffer, i-0, stride) );
469
sp_setup_tri( setup_ctx,
470
get_vert(vertex_buffer, i-2, stride),
471
get_vert(vertex_buffer, i-1, stride),
472
get_vert(vertex_buffer, i-0, stride) );
475
get_vert(vertex_buffer, i-3, stride),
476
get_vert(vertex_buffer, i-2, stride),
477
get_vert(vertex_buffer, i-0, stride) );
479
get_vert(vertex_buffer, i-2, stride),
480
get_vert(vertex_buffer, i-1, stride),
481
get_vert(vertex_buffer, i-0, stride) );
477
486
case PIPE_PRIM_QUAD_STRIP:
478
if (softpipe->rasterizer->flatshade_first) {
487
/* GL quad strips don't follow provoking vertex convention */
488
if (flatshade_first) {
489
/* emit last quad vertex as first triangle vertex */
479
490
for (i = 3; i < nr; i += 2) {
480
sp_setup_tri( setup_ctx,
481
get_vert(vertex_buffer, i-0, stride),
482
get_vert(vertex_buffer, i-1, stride),
483
get_vert(vertex_buffer, i-3, stride) );
484
sp_setup_tri( setup_ctx,
485
get_vert(vertex_buffer, i-2, stride),
486
get_vert(vertex_buffer, i-0, stride),
487
get_vert(vertex_buffer, i-3, stride) );
492
get_vert(vertex_buffer, i-0, stride),
493
get_vert(vertex_buffer, i-3, stride),
494
get_vert(vertex_buffer, i-2, stride) );
496
get_vert(vertex_buffer, i-0, stride),
497
get_vert(vertex_buffer, i-1, stride),
498
get_vert(vertex_buffer, i-3, stride) );
502
/* emit last quad vertex as last triangle vertex */
491
503
for (i = 3; i < nr; i += 2) {
492
sp_setup_tri( setup_ctx,
493
get_vert(vertex_buffer, i-3, stride),
494
get_vert(vertex_buffer, i-2, stride),
495
get_vert(vertex_buffer, i-0, stride) );
496
sp_setup_tri( setup_ctx,
497
get_vert(vertex_buffer, i-1, stride),
498
get_vert(vertex_buffer, i-3, stride),
499
get_vert(vertex_buffer, i-0, stride) );
505
get_vert(vertex_buffer, i-3, stride),
506
get_vert(vertex_buffer, i-2, stride),
507
get_vert(vertex_buffer, i-0, stride) );
509
get_vert(vertex_buffer, i-1, stride),
510
get_vert(vertex_buffer, i-3, stride),
511
get_vert(vertex_buffer, i-0, stride) );
504
516
case PIPE_PRIM_POLYGON:
505
517
/* Almost same as tri fan but the _first_ vertex specifies the flat
506
* shading color. Note that the first polygon vertex is passed as
507
* the last triangle vertex here.
508
* flatshade_first state makes no difference.
510
for (i = 2; i < nr; i += 1) {
511
sp_setup_tri( setup_ctx,
512
get_vert(vertex_buffer, i-1, stride),
513
get_vert(vertex_buffer, i-0, stride),
514
get_vert(vertex_buffer, 0, stride) );
520
if (flatshade_first) {
521
/* emit first polygon vertex as first triangle vertex */
522
for (i = 2; i < nr; i += 1) {
524
get_vert(vertex_buffer, 0, stride),
525
get_vert(vertex_buffer, i-1, stride),
526
get_vert(vertex_buffer, i-0, stride) );
530
/* emit first polygon vertex as last triangle vertex */
531
for (i = 2; i < nr; i += 1) {
533
get_vert(vertex_buffer, i-1, stride),
534
get_vert(vertex_buffer, i-0, stride),
535
get_vert(vertex_buffer, 0, stride) );