r600: better tracking for vertex buffer emission
authorMike Blumenkrantz <michael.blumenkrantz@gmail.com>
Thu, 17 Aug 2023 15:22:12 +0000 (11:22 -0400)
committerMarge Bot <emma+marge@anholt.net>
Fri, 18 Aug 2023 18:58:08 +0000 (18:58 +0000)
Fixes: 76725452 (gallium: move vertex stride to CSO)

Reviewed-by: Gert Wollny <gert.wollny@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24754>

src/gallium/drivers/r600/evergreen_state.c
src/gallium/drivers/r600/r600_state.c
src/gallium/drivers/r600/r600_state_common.c

index 4ae1208..9661530 100644 (file)
@@ -2132,14 +2132,14 @@ static void evergreen_emit_vertex_buffers(struct r600_context *rctx,
                                          unsigned pkt_flags)
 {
        struct radeon_cmdbuf *cs = &rctx->b.gfx.cs;
-       uint32_t dirty_mask = state->dirty_mask;
+       struct r600_fetch_shader *shader = (struct r600_fetch_shader*)rctx->vertex_fetch_shader.cso;
+       uint32_t dirty_mask = state->dirty_mask & shader->buffer_mask;
 
        while (dirty_mask) {
                struct pipe_vertex_buffer *vb;
                struct r600_resource *rbuffer;
                uint64_t va;
                unsigned buffer_index = u_bit_scan(&dirty_mask);
-               struct r600_fetch_shader *shader = (struct r600_fetch_shader*)rctx->vertex_fetch_shader.cso;
                unsigned stride = pkt_flags == RADEON_CP_PACKET3_COMPUTE_MODE ?
                                  1 : shader->strides[buffer_index];
 
@@ -2172,7 +2172,7 @@ static void evergreen_emit_vertex_buffers(struct r600_context *rctx,
                radeon_emit(cs, radeon_add_to_buffer_list(&rctx->b, &rctx->b.gfx, rbuffer,
                                                      RADEON_USAGE_READ | RADEON_PRIO_VERTEX_BUFFER));
        }
-       state->dirty_mask = 0;
+       state->dirty_mask &= ~shader->buffer_mask;
 }
 
 static void evergreen_fs_emit_vertex_buffers(struct r600_context *rctx, struct r600_atom * atom)
index df1514c..cef61df 100644 (file)
@@ -1663,14 +1663,14 @@ static void r600_emit_config_state(struct r600_context *rctx, struct r600_atom *
 static void r600_emit_vertex_buffers(struct r600_context *rctx, struct r600_atom *atom)
 {
        struct radeon_cmdbuf *cs = &rctx->b.gfx.cs;
-       uint32_t dirty_mask = rctx->vertex_buffer_state.dirty_mask;
+       struct r600_fetch_shader *shader = (struct r600_fetch_shader*)rctx->vertex_fetch_shader.cso;
+       uint32_t dirty_mask = rctx->vertex_buffer_state.dirty_mask & shader->buffer_mask;
 
        while (dirty_mask) {
                struct pipe_vertex_buffer *vb;
                struct r600_resource *rbuffer;
                unsigned offset;
                unsigned buffer_index = u_bit_scan(&dirty_mask);
-               struct r600_fetch_shader *shader = (struct r600_fetch_shader*)rctx->vertex_fetch_shader.cso;
                unsigned stride = shader->strides[buffer_index];
 
                vb = &rctx->vertex_buffer_state.vb[buffer_index];
index bad1e48..dab51a5 100644 (file)
@@ -543,13 +543,6 @@ static void r600_delete_dsa_state(struct pipe_context *ctx, void *state)
        free(dsa);
 }
 
-static void r600_bind_vertex_elements(struct pipe_context *ctx, void *state)
-{
-       struct r600_context *rctx = (struct r600_context *)ctx;
-
-       r600_set_cso_state(rctx, &rctx->vertex_fetch_shader, state);
-}
-
 static void r600_delete_vertex_elements(struct pipe_context *ctx, void *state)
 {
        struct r600_fetch_shader *shader = (struct r600_fetch_shader*)state;
@@ -560,13 +553,28 @@ static void r600_delete_vertex_elements(struct pipe_context *ctx, void *state)
 
 void r600_vertex_buffers_dirty(struct r600_context *rctx)
 {
-       if (rctx->vertex_buffer_state.dirty_mask) {
+       struct r600_fetch_shader *shader = (struct r600_fetch_shader*)rctx->vertex_fetch_shader.cso;
+       if (shader && (rctx->vertex_buffer_state.dirty_mask & shader->buffer_mask)) {
                rctx->vertex_buffer_state.atom.num_dw = (rctx->b.gfx_level >= EVERGREEN ? 12 : 11) *
-                                              util_bitcount(rctx->vertex_buffer_state.dirty_mask);
+                                              util_bitcount(rctx->vertex_buffer_state.dirty_mask & shader->buffer_mask);
                r600_mark_atom_dirty(rctx, &rctx->vertex_buffer_state.atom);
        }
 }
 
+static void r600_bind_vertex_elements(struct pipe_context *ctx, void *state)
+{
+       struct r600_context *rctx = (struct r600_context *)ctx;
+       struct r600_fetch_shader *prev = (struct r600_fetch_shader*)rctx->vertex_fetch_shader.cso;
+       struct r600_fetch_shader *cso = state;
+
+       r600_set_cso_state(rctx, &rctx->vertex_fetch_shader, state);
+       if (!prev || (cso && cso->buffer_mask &&
+                     (prev->buffer_mask != cso->buffer_mask || memcmp(cso->strides, prev->strides, util_last_bit(cso->buffer_mask))))) {
+               rctx->vertex_buffer_state.dirty_mask |= cso ? cso->buffer_mask : 0;
+               r600_vertex_buffers_dirty(rctx);
+       }
+}
+
 static void r600_set_vertex_buffers(struct pipe_context *ctx,
                                    unsigned count,
                                    unsigned unbind_num_trailing_slots,