r300g: emit 3D_LOAD_VBPNTR only when necessary
authorMarek Olšák <maraeo@gmail.com>
Mon, 14 Feb 2011 05:45:55 +0000 (06:45 +0100)
committerMarek Olšák <maraeo@gmail.com>
Mon, 14 Feb 2011 06:45:14 +0000 (07:45 +0100)
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
src/gallium/drivers/r300/r300_emit.c
src/gallium/drivers/r300/r300_flush.c
src/gallium/drivers/r300/r300_render.c

index 9335c680bf692af7b5fc6ea3fa3b332a0f603f1d..6e940b46fa41403b98ab6772e3dd842d5ee3d962 100644 (file)
@@ -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. */
index be5768a3e5d41347d8e3d4106ecc7deed14e0839..027cd5b7ea0797483992b01d0e944de8c990fe0b 100644 (file)
@@ -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++) {
index 986ea5ff35ab9b6ea685e3d9acd5402c2c7bbfa5..1e80f802f568e1a79fa02dc72fa216d05770a0dd 100644 (file)
@@ -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) {
index 0d50de5e7f9d1bab9c9f7ccafe6c295bb9005369..abe7b506d78ce47d746a07149d9f045c276e0598 100644 (file)
@@ -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);
     }