radeonsi: only update vertex buffers when they need updating
authorMarek Olšák <marek.olsak@amd.com>
Fri, 11 Jul 2014 21:17:07 +0000 (23:17 +0200)
committerMarek Olšák <marek.olsak@amd.com>
Thu, 17 Jul 2014 23:58:59 +0000 (01:58 +0200)
Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
src/gallium/drivers/radeonsi/si_descriptors.c
src/gallium/drivers/radeonsi/si_state.c
src/gallium/drivers/radeonsi/si_state_draw.c

index bd7695c8cd0294564f063135e4f24e3a8f7ef9a4..4751b8b8f4f332d036a09039ee19d5acefdee09b 100644 (file)
@@ -933,6 +933,8 @@ static void si_invalidate_buffer(struct pipe_context *ctx, struct pipe_resource
        struct r600_resource *rbuffer = r600_resource(buf);
        unsigned i, shader, alignment = rbuffer->buf->alignment;
        uint64_t old_va = r600_resource_va(ctx->screen, buf);
+       unsigned num_elems = sctx->vertex_elements ?
+                                      sctx->vertex_elements->count : 0;
 
        /* Reallocate the buffer in the same pipe_resource. */
        r600_init_resource(&sctx->screen->b, rbuffer, rbuffer->b.b.width0,
@@ -945,7 +947,19 @@ static void si_invalidate_buffer(struct pipe_context *ctx, struct pipe_resource
         */
 
        /* Vertex buffers. */
-       /* Nothing to do. Vertex buffer bindings are updated before every draw call. */
+       for (i = 0; i < num_elems; i++) {
+               int vb = sctx->vertex_elements->elements[i].vertex_buffer_index;
+
+               if (vb >= Elements(sctx->vertex_buffer))
+                       continue;
+               if (!sctx->vertex_buffer[vb].buffer)
+                       continue;
+
+               if (sctx->vertex_buffer[vb].buffer == buf) {
+                       sctx->vertex_buffers_dirty = true;
+                       break;
+               }
+       }
 
        /* Read/Write buffers. */
        for (shader = 0; shader < SI_NUM_SHADERS; shader++) {
index c6918721f617c7646c92e0e6638f0b43b9692971..fde06fcd6a2415f91c8c679b25d1979fd4f08a95 100644 (file)
@@ -2813,6 +2813,7 @@ static void si_bind_vertex_elements(struct pipe_context *ctx, void *state)
        struct si_vertex_element *v = (struct si_vertex_element*)state;
 
        sctx->vertex_elements = v;
+       sctx->vertex_buffers_dirty = true;
 }
 
 static void si_delete_vertex_element(struct pipe_context *ctx, void *state)
@@ -2848,6 +2849,7 @@ static void si_set_vertex_buffers(struct pipe_context *ctx,
                        pipe_resource_reference(&dst[i].buffer, NULL);
                }
        }
+       sctx->vertex_buffers_dirty = true;
 }
 
 static void si_set_index_buffer(struct pipe_context *ctx,
index a0078c0c355e1285c836dd6770da4d2c9e5189c6..f829d0363a4c04fc58c5a22485f8754d6df3009d 100644 (file)
@@ -892,7 +892,11 @@ void si_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info)
                return;
 
        si_update_derived_state(sctx);
-       si_update_vertex_buffers(sctx);
+
+       if (sctx->vertex_buffers_dirty) {
+               si_update_vertex_buffers(sctx);
+               sctx->vertex_buffers_dirty = false;
+       }
 
        if (info->indexed) {
                /* Initialize the index buffer struct. */