summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2011-02-14 06:45:55 +0100
committerMarek Olšák <[email protected]>2011-02-14 07:45:14 +0100
commit5a6ba08c21f24b14458a2084a170ddfbe8f5d793 (patch)
treefc13659a370e3e5298dcaa6daa97de3571548437
parent004dd015839dfb77b9d66fb2df6514feefb87d9e (diff)
r300g: emit 3D_LOAD_VBPNTR only when necessary
I thought I couldn't skip emitting this packet in some cases. Well it looks like I can.
-rw-r--r--src/gallium/drivers/r300/r300_context.h5
-rw-r--r--src/gallium/drivers/r300/r300_emit.c81
-rw-r--r--src/gallium/drivers/r300/r300_flush.c1
-rw-r--r--src/gallium/drivers/r300/r300_render.c10
4 files changed, 33 insertions, 64 deletions
diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index 9335c680bf6..6e940b46fa4 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -589,9 +589,10 @@ struct r300_context {
/* const tracking for VS */
int vs_const_base;
- /* AOS (PACKET3_3D_LOAD_VBPNTR) command buffer for the case offset=0. */
- uint32_t vertex_arrays_cb[(16 * 3 + 1) / 2];
+ /* Vertex array state info */
boolean vertex_arrays_dirty;
+ boolean vertex_arrays_indexed;
+ int vertex_arrays_offset;
/* Whether any buffer (FB, textures, VBOs) has been set, but buffers
* haven't been validated yet. */
diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
index be5768a3e5d..027cd5b7ea0 100644
--- a/src/gallium/drivers/r300/r300_emit.c
+++ b/src/gallium/drivers/r300/r300_emit.c
@@ -805,40 +805,6 @@ void r300_emit_textures_state(struct r300_context *r300,
END_CS;
}
-static void r300_update_vertex_arrays_cb(struct r300_context *r300, unsigned packet_size)
-{
- struct pipe_vertex_buffer *vb1, *vb2, *vbuf = r300->vbuf_mgr->vertex_buffer;
- struct pipe_vertex_element *velem = r300->velems->velem;
- unsigned *hw_format_size = r300->velems->format_size;
- unsigned size1, size2, vertex_array_count = r300->velems->count;
- int i;
- CB_LOCALS;
-
- BEGIN_CB(r300->vertex_arrays_cb, packet_size);
- for (i = 0; i < vertex_array_count - 1; i += 2) {
- vb1 = &vbuf[velem[i].vertex_buffer_index];
- vb2 = &vbuf[velem[i+1].vertex_buffer_index];
- size1 = hw_format_size[i];
- size2 = hw_format_size[i+1];
-
- OUT_CB(R300_VBPNTR_SIZE0(size1) | R300_VBPNTR_STRIDE0(vb1->stride) |
- R300_VBPNTR_SIZE1(size2) | R300_VBPNTR_STRIDE1(vb2->stride));
- OUT_CB(vb1->buffer_offset + velem[i].src_offset);
- OUT_CB(vb2->buffer_offset + velem[i+1].src_offset);
- }
-
- if (vertex_array_count & 1) {
- vb1 = &vbuf[velem[i].vertex_buffer_index];
- size1 = hw_format_size[i];
-
- OUT_CB(R300_VBPNTR_SIZE0(size1) | R300_VBPNTR_STRIDE0(vb1->stride));
- OUT_CB(vb1->buffer_offset + velem[i].src_offset);
- }
- END_CB;
-
- r300->vertex_arrays_dirty = FALSE;
-}
-
void r300_emit_vertex_arrays(struct r300_context* r300, int offset, boolean indexed)
{
struct pipe_vertex_buffer *vbuf = r300->vbuf_mgr->vertex_buffer;
@@ -854,35 +820,28 @@ void r300_emit_vertex_arrays(struct r300_context* r300, int offset, boolean inde
OUT_CS_PKT3(R300_PACKET3_3D_LOAD_VBPNTR, packet_size);
OUT_CS(vertex_array_count | (!indexed ? R300_VC_FORCE_PREFETCH : 0));
- if (!offset) {
- if (r300->vertex_arrays_dirty) {
- r300_update_vertex_arrays_cb(r300, packet_size);
- }
- OUT_CS_TABLE(r300->vertex_arrays_cb, packet_size);
- } else {
- struct pipe_vertex_buffer *vb1, *vb2;
- unsigned *hw_format_size = r300->velems->format_size;
- unsigned size1, size2;
-
- for (i = 0; i < vertex_array_count - 1; i += 2) {
- vb1 = &vbuf[velem[i].vertex_buffer_index];
- vb2 = &vbuf[velem[i+1].vertex_buffer_index];
- size1 = hw_format_size[i];
- size2 = hw_format_size[i+1];
-
- OUT_CS(R300_VBPNTR_SIZE0(size1) | R300_VBPNTR_STRIDE0(vb1->stride) |
- R300_VBPNTR_SIZE1(size2) | R300_VBPNTR_STRIDE1(vb2->stride));
- OUT_CS(vb1->buffer_offset + velem[i].src_offset + offset * vb1->stride);
- OUT_CS(vb2->buffer_offset + velem[i+1].src_offset + offset * vb2->stride);
- }
+ struct pipe_vertex_buffer *vb1, *vb2;
+ unsigned *hw_format_size = r300->velems->format_size;
+ unsigned size1, size2;
- if (vertex_array_count & 1) {
- vb1 = &vbuf[velem[i].vertex_buffer_index];
- size1 = hw_format_size[i];
+ for (i = 0; i < vertex_array_count - 1; i += 2) {
+ vb1 = &vbuf[velem[i].vertex_buffer_index];
+ vb2 = &vbuf[velem[i+1].vertex_buffer_index];
+ size1 = hw_format_size[i];
+ size2 = hw_format_size[i+1];
- OUT_CS(R300_VBPNTR_SIZE0(size1) | R300_VBPNTR_STRIDE0(vb1->stride));
- OUT_CS(vb1->buffer_offset + velem[i].src_offset + offset * vb1->stride);
- }
+ OUT_CS(R300_VBPNTR_SIZE0(size1) | R300_VBPNTR_STRIDE0(vb1->stride) |
+ R300_VBPNTR_SIZE1(size2) | R300_VBPNTR_STRIDE1(vb2->stride));
+ OUT_CS(vb1->buffer_offset + velem[i].src_offset + offset * vb1->stride);
+ OUT_CS(vb2->buffer_offset + velem[i+1].src_offset + offset * vb2->stride);
+ }
+
+ if (vertex_array_count & 1) {
+ vb1 = &vbuf[velem[i].vertex_buffer_index];
+ size1 = hw_format_size[i];
+
+ OUT_CS(R300_VBPNTR_SIZE0(size1) | R300_VBPNTR_STRIDE0(vb1->stride));
+ OUT_CS(vb1->buffer_offset + velem[i].src_offset + offset * vb1->stride);
}
for (i = 0; i < vertex_array_count; i++) {
diff --git a/src/gallium/drivers/r300/r300_flush.c b/src/gallium/drivers/r300/r300_flush.c
index 986ea5ff35a..1e80f802f56 100644
--- a/src/gallium/drivers/r300/r300_flush.c
+++ b/src/gallium/drivers/r300/r300_flush.c
@@ -59,6 +59,7 @@ static void r300_flush(struct pipe_context* pipe,
r300_mark_atom_dirty(r300, atom);
}
}
+ r300->vertex_arrays_dirty = TRUE;
/* Unmark HWTCL state for SWTCL. */
if (!r300->screen->caps.has_tcl) {
diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c
index 0d50de5e7f9..abe7b506d78 100644
--- a/src/gallium/drivers/r300/r300_render.c
+++ b/src/gallium/drivers/r300/r300_render.c
@@ -264,9 +264,17 @@ static boolean r300_emit_states(struct r300_context *r300,
r500_emit_index_bias(r300, 0);
}
- if (emit_vertex_arrays)
+ if (emit_vertex_arrays &&
+ (r300->vertex_arrays_dirty ||
+ r300->vertex_arrays_indexed != indexed ||
+ r300->vertex_arrays_offset != buffer_offset)) {
r300_emit_vertex_arrays(r300, buffer_offset, indexed);
+ r300->vertex_arrays_dirty = FALSE;
+ r300->vertex_arrays_indexed = indexed;
+ r300->vertex_arrays_offset = buffer_offset;
+ }
+
if (emit_vertex_arrays_swtcl)
r300_emit_vertex_arrays_swtcl(r300, indexed);
}