Mesa (master): r300g: emit 3D_LOAD_VBPNTR only when necessary

Marek Olšák mareko at kemper.freedesktop.org
Mon Feb 14 06:45:43 UTC 2011


Module: Mesa
Branch: master
Commit: 5a6ba08c21f24b14458a2084a170ddfbe8f5d793
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=5a6ba08c21f24b14458a2084a170ddfbe8f5d793

Author: Marek Olšák <maraeo at gmail.com>
Date:   Mon Feb 14 06:45:55 2011 +0100

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.

---

 src/gallium/drivers/r300/r300_context.h |    5 +-
 src/gallium/drivers/r300/r300_emit.c    |   81 ++++++++-----------------------
 src/gallium/drivers/r300/r300_flush.c   |    1 +
 src/gallium/drivers/r300/r300_render.c  |   10 ++++-
 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 9335c68..6e940b4 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 be5768a..027cd5b 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 986ea5f..1e80f80 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 0d50de5..abe7b50 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);
     }




More information about the mesa-commit mailing list