118
118
return color_control;
121
/* Check if the requested number of dwords is available in the CS and
122
* if not, flush. Return TRUE if the flush occured. */
123
static boolean r300_reserve_cs_space(struct r300_context *r300,
126
if (!r300->winsys->check_cs(r300->winsys, dwords)) {
121
boolean r500_index_bias_supported(struct r300_context *r300)
123
return r300->screen->caps.is_r500 &&
124
r300->rws->get_value(r300->rws, R300_VID_DRM_2_3_0);
127
void r500_emit_index_bias(struct r300_context *r300, int index_bias)
132
OUT_CS_REG(R500_VAP_INDEX_OFFSET,
133
(index_bias & 0xFFFFFF) | (index_bias < 0 ? 1<<24 : 0));
137
/* This function splits the index bias value into two parts:
138
* - buffer_offset: the value that can be safely added to buffer offsets
139
* in r300_emit_aos (it must yield a positive offset when added to
140
* a vertex buffer offset)
141
* - index_offset: the value that must be manually subtracted from indices
142
* in an index buffer to achieve negative offsets. */
143
static void r300_split_index_bias(struct r300_context *r300, int index_bias,
144
int *buffer_offset, int *index_offset)
146
struct pipe_vertex_buffer *vb, *vbufs = r300->vertex_buffer;
147
struct pipe_vertex_element *velem = r300->velems->velem;
151
if (index_bias < 0) {
152
/* See how large index bias we may subtract. We must be careful
153
* here because negative buffer offsets are not allowed
155
max_neg_bias = INT_MAX;
156
for (i = 0; i < r300->velems->count; i++) {
157
vb = &vbufs[velem[i].vertex_buffer_index];
158
size = (vb->buffer_offset + velem[i].src_offset) / vb->stride;
159
max_neg_bias = MIN2(max_neg_bias, size);
162
/* Now set the minimum allowed value. */
163
*buffer_offset = MAX2(-max_neg_bias, index_bias);
165
/* A positive index bias is OK. */
166
*buffer_offset = index_bias;
169
*index_offset = index_bias - *buffer_offset;
172
enum r300_prepare_flags {
173
PREP_FIRST_DRAW = (1 << 0), /* call emit_dirty_state and friends? */
174
PREP_VALIDATE_VBOS = (1 << 1), /* validate VBOs? */
175
PREP_EMIT_AOS = (1 << 2), /* call emit_aos? */
176
PREP_EMIT_AOS_SWTCL = (1 << 3), /* call emit_aos_swtcl? */
177
PREP_INDEXED = (1 << 4) /* is this draw_elements? */
181
* Check if the requested number of dwords is available in the CS and
182
* if not, flush. Then validate buffers and emit dirty state.
183
* \param r300 The context.
184
* \param flags See r300_prepare_flags.
185
* \param index_buffer The index buffer to validate. The parameter may be NULL.
186
* \param cs_dwords The number of dwords to reserve in CS.
187
* \param aos_offset The offset passed to emit_aos.
188
* \param index_bias The index bias to emit.
190
static void r300_prepare_for_rendering(struct r300_context *r300,
191
enum r300_prepare_flags flags,
192
struct pipe_resource *index_buffer,
197
boolean flushed = FALSE;
198
boolean first_draw = flags & PREP_FIRST_DRAW;
199
boolean emit_aos = flags & PREP_EMIT_AOS;
200
boolean emit_aos_swtcl = flags & PREP_EMIT_AOS_SWTCL;
201
boolean indexed = flags & PREP_INDEXED;
202
boolean hw_index_bias = r500_index_bias_supported(r300);
204
/* Add dirty state, index offset, and AOS. */
206
cs_dwords += r300_get_num_dirty_dwords(r300);
209
cs_dwords += 2; /* emit_index_offset */
212
cs_dwords += 55; /* emit_aos */
215
cs_dwords += 7; /* emit_aos_swtcl */
218
cs_dwords += r300_get_num_cs_end_dwords(r300);
220
/* Reserve requested CS space. */
221
if (cs_dwords > (r300->cs->ndw - r300->cs->cdw)) {
127
222
r300->context.flush(&r300->context, 0, NULL);
226
/* Validate buffers and emit dirty state if needed. */
227
if (first_draw || flushed) {
228
r300_emit_buffer_validate(r300, flags & PREP_VALIDATE_VBOS, index_buffer);
229
r300_emit_dirty_state(r300);
231
if (r300->screen->caps.has_tcl)
232
r500_emit_index_bias(r300, index_bias);
234
r500_emit_index_bias(r300, 0);
238
r300_emit_aos(r300, aos_offset, indexed);
241
r300_emit_aos_swtcl(r300, indexed);
133
245
static boolean immd_is_good_idea(struct r300_context *r300,
248
struct pipe_vertex_element* velem;
249
struct pipe_vertex_buffer* vbuf;
250
boolean checked[PIPE_MAX_ATTRIBS] = {0};
251
unsigned vertex_element_count = r300->velems->count;
254
if (DBG_ON(r300, DBG_NO_IMMD)) {
262
if (count * r300->velems->vertex_size_dwords > IMMD_DWORDS) {
266
/* We shouldn't map buffers referenced by CS, busy buffers,
267
* and ones placed in VRAM. */
268
for (i = 0; i < vertex_element_count; i++) {
269
velem = &r300->velems->velem[i];
270
vbi = velem->vertex_buffer_index;
273
vbuf = &r300->vertex_buffer[vbi];
275
if (!(r300_buffer(vbuf->buffer)->domain & R300_DOMAIN_GTT)) {
279
if (r300_buffer_is_referenced(&r300->context,
281
R300_REF_CS | R300_REF_HW)) {
282
/* It's a very bad idea to map it... */
291
/*****************************************************************************
292
* The HWTCL draw functions. *
293
****************************************************************************/
139
295
static void r300_emit_draw_arrays_immediate(struct r300_context *r300,
144
300
struct pipe_vertex_element* velem;
145
301
struct pipe_vertex_buffer* vbuf;
146
unsigned vertex_element_count = r300->vertex_element_count;
147
unsigned i, v, vbi, dw, elem_offset, dwords;
302
unsigned vertex_element_count = r300->velems->count;
303
unsigned i, v, vbi, dwords;
149
305
/* Size of the vertex, in dwords. */
150
unsigned vertex_size = 0;
152
/* Offsets of the attribute, in dwords, from the start of the vertex. */
153
unsigned offset[PIPE_MAX_ATTRIBS];
306
unsigned vertex_size = r300->velems->vertex_size_dwords;
155
308
/* Size of the vertex element, in dwords. */
156
309
unsigned size[PIPE_MAX_ATTRIBS];
158
311
/* Stride to the same attrib in the next vertex in the vertex buffer,
160
unsigned stride[PIPE_MAX_ATTRIBS] = {0};
313
unsigned stride[PIPE_MAX_ATTRIBS];
162
315
/* Mapped vertex buffers. */
163
uint32_t* map[PIPE_MAX_ATTRIBS] = {0};
316
uint32_t* map[PIPE_MAX_ATTRIBS];
317
uint32_t* mapelem[PIPE_MAX_ATTRIBS];
318
struct pipe_transfer* transfer[PIPE_MAX_ATTRIBS] = {0};
167
322
/* Calculate the vertex size, offsets, strides etc. and map the buffers. */
168
323
for (i = 0; i < vertex_element_count; i++) {
169
velem = &r300->vertex_element[i];
170
offset[i] = velem->src_offset / 4;
171
size[i] = util_format_get_blocksize(velem->src_format) / 4;
172
vertex_size += size[i];
324
velem = &r300->velems->velem[i];
325
size[i] = r300->velems->hw_format_size[i] / 4;
173
326
vbi = velem->vertex_buffer_index;
327
vbuf = &r300->vertex_buffer[vbi];
328
stride[i] = vbuf->stride / 4;
175
330
/* Map the buffer. */
177
vbuf = &r300->vertex_buffer[vbi];
178
map[vbi] = (uint32_t*)pipe_buffer_map(r300->context.screen,
331
if (!transfer[vbi]) {
332
map[vbi] = (uint32_t*)pipe_buffer_map(&r300->context,
180
PIPE_BUFFER_USAGE_CPU_READ);
181
map[vbi] += vbuf->buffer_offset / 4;
182
stride[vbi] = vbuf->stride / 4;
336
map[vbi] += (vbuf->buffer_offset / 4) + stride[i] * start;
338
mapelem[i] = map[vbi] + (velem->src_offset / 4);
186
dwords = 10 + count * vertex_size;
341
dwords = 9 + count * vertex_size;
188
r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + dwords);
189
r300_emit_buffer_validate(r300, FALSE, 0);
190
r300_emit_dirty_state(r300);
343
r300_prepare_for_rendering(r300, PREP_FIRST_DRAW, NULL, dwords, 0, 0);
192
345
BEGIN_CS(dwords);
193
346
OUT_CS_REG(R300_GA_COLOR_CONTROL,
194
347
r300_provoking_vertex_fixes(r300, mode));
195
348
OUT_CS_REG(R300_VAP_VTX_SIZE, vertex_size);
196
OUT_CS_REG(R300_VAP_VF_MIN_VTX_INDX, 0);
197
OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, count - 1);
349
OUT_CS_REG_SEQ(R300_VAP_VF_MAX_VTX_INDX, 2);
198
352
OUT_CS_PKT3(R300_PACKET3_3D_DRAW_IMMD_2, count * vertex_size);
199
353
OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_EMBEDDED | (count << 16) |
200
354
r300_translate_primitive(mode));
313
459
OUT_CS(R300_INDX_BUFFER_ONE_REG_WR | (R300_VAP_PORT_IDX0 >> 2) |
314
460
(0 << R300_INDX_BUFFER_SKIP_SHIFT));
315
461
OUT_CS(offset_dwords << 2);
316
OUT_CS_RELOC(indexBuffer, count_dwords,
317
RADEON_GEM_DOMAIN_GTT, 0, 0);
462
OUT_CS_BUF_RELOC(indexBuffer, count_dwords,
463
r300_buffer(indexBuffer)->domain, 0);
322
static void r300_shorten_ubyte_elts(struct r300_context* r300,
323
struct pipe_buffer** elts,
326
struct pipe_screen* screen = r300->context.screen;
327
struct pipe_buffer* new_elts;
328
unsigned char *in_map;
329
unsigned short *out_map;
332
new_elts = screen->buffer_create(screen, 32,
333
PIPE_BUFFER_USAGE_INDEX |
334
PIPE_BUFFER_USAGE_CPU_WRITE |
335
PIPE_BUFFER_USAGE_GPU_READ,
338
in_map = pipe_buffer_map(screen, *elts, PIPE_BUFFER_USAGE_CPU_READ);
339
out_map = pipe_buffer_map(screen, new_elts, PIPE_BUFFER_USAGE_CPU_WRITE);
341
for (i = 0; i < count; i++) {
342
*out_map = (unsigned short)*in_map;
347
pipe_buffer_unmap(screen, *elts);
348
pipe_buffer_unmap(screen, new_elts);
353
468
/* This is the fast-path drawing & emission for HW TCL. */
354
void r300_draw_range_elements(struct pipe_context* pipe,
355
struct pipe_buffer* indexBuffer,
469
static void r300_draw_range_elements(struct pipe_context* pipe,
470
struct pipe_resource* indexBuffer,
363
479
struct r300_context* r300 = r300_context(pipe);
364
struct pipe_buffer* orgIndexBuffer = indexBuffer;
365
#if defined(ENABLE_ALT_NUM_VERTS)
366
boolean alt_num_verts = r300_screen(pipe->screen)->caps->is_r500 &&
369
boolean alt_num_verts = FALSE;
480
struct pipe_resource* orgIndexBuffer = indexBuffer;
481
boolean alt_num_verts = r300->screen->caps.is_r500 &&
483
r300->rws->get_value(r300->rws, R300_VID_DRM_2_3_0);
371
484
unsigned short_count;
485
int buffer_offset = 0, index_offset = 0; /* for index bias emulation */
486
boolean translate = FALSE;
489
if (r300->skip_rendering) {
373
493
if (!u_trim_pipe_prim(mode, &count)) {
377
if (indexSize == 1) {
378
r300_shorten_ubyte_elts(r300, &indexBuffer, count);
497
/* Index buffer range checking. */
498
if ((start + count) * indexSize > indexBuffer->width0) {
499
fprintf(stderr, "r300: Invalid index buffer range. Skipping rendering.\n");
503
/* Set up fallback for incompatible vertex layout if needed. */
504
if (r300->incompatible_vb_layout || r300->velems->incompatible_layout) {
505
r300_begin_vertex_translate(r300);
509
if (indexBias && !r500_index_bias_supported(r300)) {
510
r300_split_index_bias(r300, indexBias, &buffer_offset, &index_offset);
513
r300_translate_index_buffer(r300, &indexBuffer, &indexSize, index_offset,
382
516
r300_update_derived_state(r300);
517
r300_upload_index_buffer(r300, &indexBuffer, indexSize, start, count, &new_offset);
384
/* 128 dwords for emit_aos and emit_draw_elements */
385
r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + 128);
386
r300_emit_buffer_validate(r300, TRUE, indexBuffer);
387
r300_emit_dirty_state(r300);
388
r300_emit_aos(r300, 0);
520
/* 15 dwords for emit_draw_elements */
521
r300_prepare_for_rendering(r300,
522
PREP_FIRST_DRAW | PREP_VALIDATE_VBOS | PREP_EMIT_AOS | PREP_INDEXED,
523
indexBuffer, 15, buffer_offset, indexBias);
390
525
if (alt_num_verts || count <= 65535) {
391
r300_emit_draw_elements(r300, indexBuffer, indexSize, minIndex,
392
maxIndex, mode, start, count);
526
r300_emit_draw_elements(r300, indexBuffer, indexSize,
527
minIndex, maxIndex, mode, start, count);
395
530
short_count = MIN2(count, 65534);
396
r300_emit_draw_elements(r300, indexBuffer, indexSize, minIndex,
397
maxIndex, mode, start, short_count);
531
r300_emit_draw_elements(r300, indexBuffer, indexSize,
533
mode, start, short_count);
399
535
start += short_count;
400
536
count -= short_count;
402
/* 16 spare dwords are enough for emit_draw_elements. */
403
if (count && r300_reserve_cs_space(r300, 16)) {
404
r300_emit_buffer_validate(r300, TRUE, indexBuffer);
405
r300_emit_dirty_state(r300);
406
r300_emit_aos(r300, 0);
538
/* 15 dwords for emit_draw_elements */
540
r300_prepare_for_rendering(r300,
541
PREP_VALIDATE_VBOS | PREP_EMIT_AOS | PREP_INDEXED,
542
indexBuffer, 15, buffer_offset, indexBias);
411
547
if (indexBuffer != orgIndexBuffer) {
412
pipe->screen->buffer_destroy(indexBuffer);
416
/* Simple helpers for context setup. Should probably be moved to util. */
417
void r300_draw_elements(struct pipe_context* pipe,
418
struct pipe_buffer* indexBuffer,
419
unsigned indexSize, unsigned mode,
420
unsigned start, unsigned count)
422
struct r300_context *r300 = r300_context(pipe);
424
pipe->draw_range_elements(pipe, indexBuffer, indexSize, 0,
425
r300->vertex_buffer_max_index,
429
void r300_draw_arrays(struct pipe_context* pipe, unsigned mode,
430
unsigned start, unsigned count)
548
pipe_resource_reference( &indexBuffer, NULL );
552
r300_end_vertex_translate(r300);
556
static void r300_draw_arrays(struct pipe_context* pipe, unsigned mode,
557
unsigned start, unsigned count)
432
559
struct r300_context* r300 = r300_context(pipe);
433
#if defined(ENABLE_ALT_NUM_VERTS)
434
boolean alt_num_verts = r300_screen(pipe->screen)->caps->is_r500 &&
437
boolean alt_num_verts = FALSE;
560
boolean alt_num_verts = r300->screen->caps.is_r500 &&
562
r300->rws->get_value(r300->rws, R300_VID_DRM_2_3_0);
439
563
unsigned short_count;
564
boolean translate = FALSE;
566
if (r300->skip_rendering) {
441
570
if (!u_trim_pipe_prim(mode, &count)) {
574
/* Set up fallback for incompatible vertex layout if needed. */
575
if (r300->incompatible_vb_layout || r300->velems->incompatible_layout) {
576
r300_begin_vertex_translate(r300);
445
580
r300_update_derived_state(r300);
447
582
if (immd_is_good_idea(r300, count)) {
448
583
r300_emit_draw_arrays_immediate(r300, mode, start, count);
450
/* Make sure there are at least 128 spare dwords in the command buffer.
451
* (most of it being consumed by emit_aos) */
452
r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + 128);
453
r300_emit_buffer_validate(r300, TRUE, 0);
454
r300_emit_dirty_state(r300);
585
/* 9 spare dwords for emit_draw_arrays. */
586
r300_prepare_for_rendering(r300, PREP_FIRST_DRAW | PREP_VALIDATE_VBOS | PREP_EMIT_AOS,
456
589
if (alt_num_verts || count <= 65535) {
457
r300_emit_aos(r300, start);
458
590
r300_emit_draw_arrays(r300, mode, count);
461
593
short_count = MIN2(count, 65535);
462
r300_emit_aos(r300, start);
463
594
r300_emit_draw_arrays(r300, mode, short_count);
465
596
start += short_count;
466
597
count -= short_count;
468
/* Again, we emit both AOS and draw_arrays so there should be
469
* at least 128 spare dwords. */
470
if (count && r300_reserve_cs_space(r300, 128)) {
471
r300_emit_buffer_validate(r300, TRUE, 0);
472
r300_emit_dirty_state(r300);
599
/* 9 spare dwords for emit_draw_arrays. */
601
r300_prepare_for_rendering(r300,
602
PREP_VALIDATE_VBOS | PREP_EMIT_AOS, NULL, 9,
607
u_upload_flush(r300->upload_vb);
611
r300_end_vertex_translate(r300);
615
static void r300_draw_vbo(struct pipe_context* pipe,
616
const struct pipe_draw_info *info)
618
struct r300_context* r300 = r300_context(pipe);
620
if (!r300->velems->count || !r300->vertex_buffer_count)
623
if (info->indexed && r300->index_buffer.buffer) {
626
assert(r300->index_buffer.offset % r300->index_buffer.index_size == 0);
627
offset = r300->index_buffer.offset / r300->index_buffer.index_size;
629
r300_draw_range_elements(pipe,
630
r300->index_buffer.buffer,
631
r300->index_buffer.index_size,
636
info->start + offset,
640
r300_draw_arrays(pipe,
481
649
* keep these functions separated so that they are easier to locate. ~C. *
482
650
***************************************************************************/
484
/* SW TCL arrays, using Draw. */
485
void r300_swtcl_draw_arrays(struct pipe_context* pipe,
490
struct r300_context* r300 = r300_context(pipe);
493
if (!u_trim_pipe_prim(mode, &count)) {
497
for (i = 0; i < r300->vertex_buffer_count; i++) {
498
void* buf = pipe_buffer_map(pipe->screen,
499
r300->vertex_buffer[i].buffer,
500
PIPE_BUFFER_USAGE_CPU_READ);
501
draw_set_mapped_vertex_buffer(r300->draw, i, buf);
504
draw_set_mapped_element_buffer(r300->draw, 0, NULL);
506
draw_set_mapped_constant_buffer(r300->draw,
509
r300->shader_constants[PIPE_SHADER_VERTEX].constants,
510
r300->shader_constants[PIPE_SHADER_VERTEX].count *
511
(sizeof(float) * 4));
513
draw_arrays(r300->draw, mode, start, count);
515
for (i = 0; i < r300->vertex_buffer_count; i++) {
516
pipe_buffer_unmap(pipe->screen, r300->vertex_buffer[i].buffer);
517
draw_set_mapped_vertex_buffer(r300->draw, i, NULL);
521
652
/* SW TCL elements, using Draw. */
522
void r300_swtcl_draw_range_elements(struct pipe_context* pipe,
523
struct pipe_buffer* indexBuffer,
653
static void r300_swtcl_draw_vbo(struct pipe_context* pipe,
654
const struct pipe_draw_info *info)
531
656
struct r300_context* r300 = r300_context(pipe);
657
struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS];
658
struct pipe_transfer *ib_transfer = NULL;
659
unsigned count = info->count;
535
if (!u_trim_pipe_prim(mode, &count)) {
539
for (i = 0; i < r300->vertex_buffer_count; i++) {
540
void* buf = pipe_buffer_map(pipe->screen,
541
r300->vertex_buffer[i].buffer,
542
PIPE_BUFFER_USAGE_CPU_READ);
543
draw_set_mapped_vertex_buffer(r300->draw, i, buf);
546
indices = pipe_buffer_map(pipe->screen, indexBuffer,
547
PIPE_BUFFER_USAGE_CPU_READ);
548
draw_set_mapped_element_buffer_range(r300->draw, indexSize,
549
minIndex, maxIndex, indices);
551
draw_set_mapped_constant_buffer(r300->draw,
554
r300->shader_constants[PIPE_SHADER_VERTEX].constants,
555
r300->shader_constants[PIPE_SHADER_VERTEX].count *
556
(sizeof(float) * 4));
558
draw_arrays(r300->draw, mode, start, count);
560
for (i = 0; i < r300->vertex_buffer_count; i++) {
561
pipe_buffer_unmap(pipe->screen, r300->vertex_buffer[i].buffer);
562
draw_set_mapped_vertex_buffer(r300->draw, i, NULL);
565
pipe_buffer_unmap(pipe->screen, indexBuffer);
566
draw_set_mapped_element_buffer_range(r300->draw, 0, start,
567
start + count - 1, NULL);
661
void* indices = NULL;
663
if (r300->skip_rendering) {
667
if (!u_trim_pipe_prim(info->mode, &count)) {
671
r300_update_derived_state(r300);
673
for (i = 0; i < r300->vertex_buffer_count; i++) {
674
if (r300->vertex_buffer[i].buffer) {
675
void *buf = pipe_buffer_map(pipe,
676
r300->vertex_buffer[i].buffer,
679
draw_set_mapped_vertex_buffer(r300->draw, i, buf);
683
if (info->indexed && r300->index_buffer.buffer) {
684
indices = pipe_buffer_map(pipe, r300->index_buffer.buffer,
685
PIPE_TRANSFER_READ, &ib_transfer);
688
draw_set_mapped_index_buffer(r300->draw, indices);
690
draw_vbo(r300->draw, info);
692
/* XXX Not sure whether this is the best fix.
693
* It prevents CS from being rejected and weird assertion failures. */
694
draw_flush(r300->draw);
696
for (i = 0; i < r300->vertex_buffer_count; i++) {
697
if (r300->vertex_buffer[i].buffer) {
698
pipe_buffer_unmap(pipe, r300->vertex_buffer[i].buffer,
700
draw_set_mapped_vertex_buffer(r300->draw, i, NULL);
705
pipe_buffer_unmap(pipe, r300->index_buffer.buffer, ib_transfer);
706
draw_set_mapped_index_buffer(r300->draw, NULL);
570
710
/* Object for rendering using Draw. */
681
824
static void r300_render_draw_arrays(struct vbuf_render* render,
685
828
struct r300_render* r300render = r300_render(render);
686
829
struct r300_context* r300 = r300render->r300;
690
r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + 2);
691
r300_emit_dirty_state(r300);
693
DBG(r300, DBG_DRAW, "r300: Doing vbuf render, count %d\n", count);
835
(void) i; (void) ptr;
837
r300_prepare_for_rendering(r300, PREP_FIRST_DRAW | PREP_EMIT_AOS_SWTCL,
840
DBG(r300, DBG_DRAW, "r300: render_draw_arrays (count: %d)\n", count);
842
/* Uncomment to dump all VBOs rendered through this interface.
844
ptr = pipe_buffer_map(&r300render->r300->context,
845
r300render->vbo, PIPE_TRANSFER_READ,
846
&r300render->vbo_transfer);
848
for (i = 0; i < count; i++) {
849
printf("r300: Vertex %d\n", i);
850
draw_dump_emitted_vertex(&r300->vertex_info, ptr);
851
ptr += r300->vertex_info.size * 4;
855
pipe_buffer_unmap(&r300render->r300->context, r300render->vbo,
856
r300render->vbo_transfer);
860
OUT_CS_REG(R300_GA_COLOR_CONTROL,
861
r300_provoking_vertex_fixes(r300, r300render->prim));
862
OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, count - 1);
696
863
OUT_CS_PKT3(R300_PACKET3_3D_DRAW_VBUF_2, 0);
697
864
OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (count << 16) |
698
865
r300render->hwprim);
702
static void r300_render_draw(struct vbuf_render* render,
703
const ushort* indices,
869
static void r300_render_draw_elements(struct vbuf_render* render,
870
const ushort* indices,
706
873
struct r300_render* r300render = r300_render(render);
707
874
struct r300_context* r300 = r300render->r300;
709
unsigned dwords = 2 + (count+1)/2;
876
unsigned end_cs_dwords;
877
unsigned max_index = (r300->draw_vbo_size - r300render->vbo_offset) /
878
(r300render->r300->vertex_info.size * 4) - 1;
879
unsigned short_count;
880
unsigned free_dwords;
713
r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + dwords);
714
r300_emit_dirty_state(r300);
717
OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, (count+1)/2);
718
OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) |
720
for (i = 0; i < count-1; i += 2) {
721
OUT_CS(indices[i+1] << 16 | indices[i]);
724
OUT_CS(indices[count-1]);
883
DBG(r300, DBG_DRAW, "r300: render_draw_elements (count: %d)\n", count);
885
/* Reserve at least 256 dwords.
887
* Below we manage the CS space manually because there may be more
888
* indices than it can fit in CS. */
889
r300_prepare_for_rendering(r300,
890
PREP_FIRST_DRAW | PREP_EMIT_AOS_SWTCL | PREP_INDEXED,
892
end_cs_dwords = r300_get_num_cs_end_dwords(r300);
895
free_dwords = r300->cs->ndw - r300->cs->cdw;
897
short_count = MIN2(count, (free_dwords - end_cs_dwords - 6) * 2);
899
BEGIN_CS(6 + (short_count+1)/2);
900
OUT_CS_REG(R300_GA_COLOR_CONTROL,
901
r300_provoking_vertex_fixes(r300, r300render->prim));
902
OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, max_index);
903
OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, (short_count+1)/2);
904
OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (short_count << 16) |
906
for (i = 0; i < short_count-1; i += 2) {
907
OUT_CS(indices[i+1] << 16 | indices[i]);
909
if (short_count % 2) {
910
OUT_CS(indices[short_count-1]);
914
/* OK now subtract the emitted indices and see if we need to emit
915
* another draw packet. */
916
indices += short_count;
917
count -= short_count;
920
r300_prepare_for_rendering(r300,
921
PREP_EMIT_AOS_SWTCL | PREP_INDEXED,
923
end_cs_dwords = r300_get_num_cs_end_dwords(r300);
729
928
static void r300_render_destroy(struct vbuf_render* render)
981
void r300_draw_flush_vbuf(struct r300_context *r300)
983
pipe_resource_reference(&r300->vbo, NULL);
984
r300->draw_vbo_size = 0;
987
/****************************************************************************
988
* End of SW TCL functions *
989
***************************************************************************/
991
/* If we used a quad to draw a rectangle, the pixels on the main diagonal
992
* would be computed and stored twice, which makes the clear/copy codepaths
993
* somewhat inefficient. Instead we use a rectangular point sprite. */
994
static void r300_blitter_draw_rectangle(struct blitter_context *blitter,
995
unsigned x1, unsigned y1,
996
unsigned x2, unsigned y2,
998
enum blitter_attrib_type type,
999
const float attrib[4])
1001
struct r300_context *r300 = r300_context(util_blitter_get_pipe(blitter));
1002
unsigned last_sprite_coord_enable = r300->sprite_coord_enable;
1003
unsigned width = x2 - x1;
1004
unsigned height = y2 - y1;
1005
unsigned vertex_size =
1006
type == UTIL_BLITTER_ATTRIB_COLOR || !r300->draw ? 8 : 4;
1007
unsigned dwords = 13 + vertex_size +
1008
(type == UTIL_BLITTER_ATTRIB_TEXCOORD ? 7 : 0);
1009
const float zeros[4] = {0, 0, 0, 0};
1012
if (type == UTIL_BLITTER_ATTRIB_TEXCOORD)
1013
r300->sprite_coord_enable = 1;
1015
r300_update_derived_state(r300);
1017
/* Mark some states we don't care about as non-dirty. */
1018
r300->clip_state.dirty = FALSE;
1019
r300->viewport_state.dirty = FALSE;
1021
r300_prepare_for_rendering(r300, PREP_FIRST_DRAW, NULL, dwords, 0, 0);
1023
DBG(r300, DBG_DRAW, "r300: draw_rectangle\n");
1027
OUT_CS_REG(R300_GA_POINT_SIZE, (height * 6) | ((width * 6) << 16));
1029
if (type == UTIL_BLITTER_ATTRIB_TEXCOORD) {
1030
/* Set up the GA to generate texcoords. */
1031
OUT_CS_REG(R300_GB_ENABLE, R300_GB_POINT_STUFF_ENABLE |
1032
(R300_GB_TEX_STR << R300_GB_TEX0_SOURCE_SHIFT));
1033
OUT_CS_REG_SEQ(R300_GA_POINT_S0, 4);
1034
OUT_CS_32F(attrib[0]);
1035
OUT_CS_32F(attrib[3]);
1036
OUT_CS_32F(attrib[2]);
1037
OUT_CS_32F(attrib[1]);
1040
/* Set up VAP controls. */
1041
OUT_CS_REG(R300_VAP_CLIP_CNTL, R300_CLIP_DISABLE);
1042
OUT_CS_REG(R300_VAP_VTE_CNTL, R300_VTX_XY_FMT | R300_VTX_Z_FMT);
1043
OUT_CS_REG(R300_VAP_VTX_SIZE, vertex_size);
1044
OUT_CS_REG_SEQ(R300_VAP_VF_MAX_VTX_INDX, 2);
1049
OUT_CS_PKT3(R300_PACKET3_3D_DRAW_IMMD_2, vertex_size);
1050
OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_EMBEDDED | (1 << 16) |
1051
R300_VAP_VF_CNTL__PRIM_POINTS);
1053
OUT_CS_32F(x1 + width * 0.5f);
1054
OUT_CS_32F(y1 + height * 0.5f);
1058
if (vertex_size == 8) {
1061
OUT_CS_TABLE(attrib, 4);
1065
/* Restore the state. */
1066
r300->clip_state.dirty = TRUE;
1067
r300->rs_state.dirty = TRUE;
1068
r300->viewport_state.dirty = TRUE;
1070
r300->sprite_coord_enable = last_sprite_coord_enable;
1073
static void r300_resource_resolve(struct pipe_context* pipe,
1074
struct pipe_resource* dest,
1075
struct pipe_subresource subdest,
1076
struct pipe_resource* src,
1077
struct pipe_subresource subsrc)
1079
struct r300_context* r300 = r300_context(pipe);
1080
struct r300_aa_state *aa = (struct r300_aa_state*)r300->aa_state.state;
1081
struct pipe_surface* srcsurf = src->screen->get_tex_surface(src->screen,
1082
src, subsrc.face, subsrc.level, 0, 0);
1083
float color[] = {0, 0, 0, 0};
1085
DBG(r300, DBG_DRAW, "r300: Resolving resource...\n");
1087
/* Enable AA resolve. */
1088
aa->dest = r300_surface(
1089
dest->screen->get_tex_surface(dest->screen, dest, subdest.face,
1090
subdest.level, 0, 0));
1093
R300_RB3D_AARESOLVE_CTL_AARESOLVE_MODE_RESOLVE |
1094
R300_RB3D_AARESOLVE_CTL_AARESOLVE_ALPHA_AVERAGE;
1095
r300->aa_state.size = 12;
1096
r300->aa_state.dirty = TRUE;
1098
/* Resolve the surface. */
1099
r300->context.clear_render_target(pipe,
1100
srcsurf, color, 0, 0, src->width0, src->height0);
1102
/* Disable AA resolve. */
1103
aa->aaresolve_ctl = 0;
1104
r300->aa_state.size = 4;
1105
r300->aa_state.dirty = TRUE;
1107
pipe_surface_reference((struct pipe_surface**)&srcsurf, NULL);
1108
pipe_surface_reference((struct pipe_surface**)&aa->dest, NULL);
1111
void r300_init_render_functions(struct r300_context *r300)
1113
/* Set draw functions based on presence of HW TCL. */
1114
if (r300->screen->caps.has_tcl) {
1115
r300->context.draw_vbo = r300_draw_vbo;
1117
r300->context.draw_vbo = r300_swtcl_draw_vbo;
1120
r300->context.resource_resolve = r300_resource_resolve;
1121
r300->blitter->draw_rectangle = r300_blitter_draw_rectangle;
1123
/* Plug in the two-sided stencil reference value fallback if needed. */
1124
if (!r300->screen->caps.is_r500)
1125
r300_plug_in_stencil_ref_fallback(r300);