Mesa (master): r300g: validate buffers only if any of bound buffers is changed

Marek Olšák mareko at kemper.freedesktop.org
Tue Dec 7 08:13:01 UTC 2010


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

Author: Marek Olšák <maraeo at gmail.com>
Date:   Tue Dec  7 07:54:31 2010 +0100

r300g: validate buffers only if any of bound buffers is changed

This prevents needless buffer validation (CS space checking).

---

 src/gallium/drivers/r300/r300_context.h          |    4 +++
 src/gallium/drivers/r300/r300_emit.c             |    8 +-----
 src/gallium/drivers/r300/r300_flush.c            |    2 +
 src/gallium/drivers/r300/r300_render.c           |   26 +++++++++++++++++----
 src/gallium/drivers/r300/r300_render_translate.c |    4 +++
 src/gallium/drivers/r300/r300_screen_buffer.c    |    1 +
 src/gallium/drivers/r300/r300_state.c            |    7 ++++-
 7 files changed, 39 insertions(+), 13 deletions(-)

diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index 8d50ea3..39dcde0 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -614,6 +614,10 @@ struct r300_context {
     /* AOS (PACKET3_3D_LOAD_VBPNTR) command buffer for the case offset=0. */
     uint32_t aos_cb[(16 * 3 + 1) / 2];
     boolean aos_dirty;
+
+    /* Whether any buffer (FB, textures, VBOs) has been set, but buffers
+     * haven't been validated yet. */
+    boolean validate_buffers;
 };
 
 #define foreach_atom(r300, atom) \
diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
index 82391e1..04a5bd9 100644
--- a/src/gallium/drivers/r300/r300_emit.c
+++ b/src/gallium/drivers/r300/r300_emit.c
@@ -1219,12 +1219,6 @@ boolean r300_emit_buffer_validate(struct r300_context *r300,
     struct pipe_resource *pbuf;
     unsigned i;
 
-    /* upload buffers first */
-    if (r300->screen->caps.has_tcl && r300->any_user_vbs) {
-        r300_upload_user_buffers(r300);
-        r300->any_user_vbs = false;
-    }
-
     /* Clean out BOs. */
     r300->rws->cs_reset_buffers(r300->cs);
 
@@ -1263,6 +1257,8 @@ boolean r300_emit_buffer_validate(struct r300_context *r300,
     if (do_validate_vertex_buffers) {
         for (i = 0; i < r300->velems->count; i++) {
             pbuf = vbuf[velem[i].vertex_buffer_index].buffer;
+            if (!pbuf)
+                continue;
 
             r300->rws->cs_add_buffer(r300->cs, r300_buffer(pbuf)->cs_buf,
                                      r300_buffer(pbuf)->domain, 0);
diff --git a/src/gallium/drivers/r300/r300_flush.c b/src/gallium/drivers/r300/r300_flush.c
index 074c5c8..451fe52 100644
--- a/src/gallium/drivers/r300/r300_flush.c
+++ b/src/gallium/drivers/r300/r300_flush.c
@@ -68,6 +68,8 @@ static void r300_flush(struct pipe_context* pipe,
             r300->vs_state.dirty = FALSE;
             r300->vs_constants.dirty = FALSE;
         }
+
+        r300->validate_buffers = TRUE;
     }
 
     /* reset flushed query */
diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c
index fa55e4f..7bb5eaa 100644
--- a/src/gallium/drivers/r300/r300_render.c
+++ b/src/gallium/drivers/r300/r300_render.c
@@ -232,14 +232,28 @@ static boolean r300_emit_states(struct r300_context *r300,
     boolean emit_aos       = flags & PREP_EMIT_AOS;
     boolean emit_aos_swtcl = flags & PREP_EMIT_AOS_SWTCL;
     boolean indexed        = flags & PREP_INDEXED;
+    boolean validate_vbos  = flags & PREP_VALIDATE_VBOS;
 
     /* Validate buffers and emit dirty state if needed. */
     if (first_draw) {
-        if (!r300_emit_buffer_validate(r300, flags & PREP_VALIDATE_VBOS,
-                                       index_buffer)) {
-            fprintf(stderr, "r300: CS space validation failed. "
-                    "(not enough memory?) Skipping rendering.\n");
-            return FALSE;
+        /* upload buffers first */
+        if (r300->screen->caps.has_tcl && r300->any_user_vbs) {
+            r300_upload_user_buffers(r300);
+            r300->any_user_vbs = false;
+        }
+
+        if (r300->validate_buffers) {
+            if (!r300_emit_buffer_validate(r300, validate_vbos,
+                                           index_buffer)) {
+                fprintf(stderr, "r300: CS space validation failed. "
+                        "(not enough memory?) Skipping rendering.\n");
+                return FALSE;
+            }
+
+            /* Consider the validation done only if everything was validated. */
+            if (validate_vbos) {
+                r300->validate_buffers = FALSE;
+            }
         }
 
         r300_emit_dirty_state(r300);
@@ -1080,6 +1094,8 @@ static void r300_blitter_draw_rectangle(struct blitter_context *blitter,
     const float zeros[4] = {0, 0, 0, 0};
     CS_LOCALS(r300);
 
+    r300->context.set_vertex_buffers(&r300->context, 0, NULL);
+
     if (type == UTIL_BLITTER_ATTRIB_TEXCOORD)
         r300->sprite_coord_enable = 1;
 
diff --git a/src/gallium/drivers/r300/r300_render_translate.c b/src/gallium/drivers/r300/r300_render_translate.c
index 9247064..41a43b0 100644
--- a/src/gallium/drivers/r300/r300_render_translate.c
+++ b/src/gallium/drivers/r300/r300_render_translate.c
@@ -145,6 +145,7 @@ void r300_begin_vertex_translate(struct r300_context *r300)
             vb->max_index = num_verts - 1;
             vb->stride = key.output_stride;
             r300->tran.vb_slot = i;
+            r300->validate_buffers = TRUE;
             break;
         }
     }
@@ -199,12 +200,14 @@ void r300_translate_index_buffer(struct r300_context *r300,
             util_shorten_ubyte_elts(&r300->context, index_buffer, index_offset, *start, count);
             *index_size = 2;
             *start = 0;
+            r300->validate_buffers = TRUE;
             break;
 
         case 2:
             if (*start % 2 != 0 || index_offset) {
                 util_rebuild_ushort_elts(&r300->context, index_buffer, index_offset, *start, count);
                 *start = 0;
+                r300->validate_buffers = TRUE;
             }
             break;
 
@@ -212,6 +215,7 @@ void r300_translate_index_buffer(struct r300_context *r300,
             if (index_offset) {
                 util_rebuild_uint_elts(&r300->context, index_buffer, index_offset, *start, count);
                 *start = 0;
+                r300->validate_buffers = TRUE;
             }
             break;
     }
diff --git a/src/gallium/drivers/r300/r300_screen_buffer.c b/src/gallium/drivers/r300/r300_screen_buffer.c
index bbb91d1..4436443 100644
--- a/src/gallium/drivers/r300/r300_screen_buffer.c
+++ b/src/gallium/drivers/r300/r300_screen_buffer.c
@@ -118,6 +118,7 @@ int r300_upload_user_buffers(struct r300_context *r300)
             pipe_resource_reference(&vb->buffer, NULL);
             vb->buffer = upload_buffer;
             vb->buffer_offset = upload_offset;
+            r300->validate_buffers = TRUE;
         }
     }
     return ret;
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index c4945fb..7529253 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -751,6 +751,7 @@ static void
     util_copy_framebuffer_state(r300->fb_state.state, state);
 
     r300_mark_fb_state_dirty(r300, R300_CHANGED_FB_STATE);
+    r300->validate_buffers = TRUE;
 
     r300->z_compression = false;
     
@@ -1333,6 +1334,7 @@ static void r300_set_fragment_sampler_views(struct pipe_context* pipe,
     state->sampler_view_count = count;
 
     r300_mark_atom_dirty(r300, &r300->textures_state);
+    r300->validate_buffers = TRUE;
 
     if (dirty_tex) {
         r300_mark_atom_dirty(r300, &r300->texture_cache_inval);
@@ -1510,6 +1512,7 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe,
         r300->any_user_vbs = any_user_buffer;
         r300->vertex_buffer_max_index = max_index;
         r300->aos_dirty = TRUE;
+        r300->validate_buffers = TRUE;
     } else {
         /* SW TCL. */
         draw_set_vertex_buffers(r300->draw, count, buffers);
@@ -1545,10 +1548,10 @@ static void r300_set_index_buffer(struct pipe_context* pipe,
     }
 
     if (r300->screen->caps.has_tcl) {
-       /* TODO make this more like a state */
+        r300->validate_buffers = TRUE;
     }
     else {
-       draw_set_index_buffer(r300->draw, ib);
+        draw_set_index_buffer(r300->draw, ib);
     }
 }
 




More information about the mesa-commit mailing list