Mesa (master): radeonsi: make sctx->vertex_elements always non-NULL

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon Jan 18 01:33:14 UTC 2021


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

Author: Marek Olšák <marek.olsak at amd.com>
Date:   Sat Jan  9 05:27:57 2021 -0500

radeonsi: make sctx->vertex_elements always non-NULL

Bind a state with 0 vertex elements there.

Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer at amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8548>

---

 src/gallium/drivers/radeonsi/si_debug.c         |  2 +-
 src/gallium/drivers/radeonsi/si_gfx_cs.c        |  2 +-
 src/gallium/drivers/radeonsi/si_pipe.c          |  5 +++
 src/gallium/drivers/radeonsi/si_pipe.h          |  1 +
 src/gallium/drivers/radeonsi/si_state.c         | 48 +++++++++++++------------
 src/gallium/drivers/radeonsi/si_state_draw.cpp  |  2 +-
 src/gallium/drivers/radeonsi/si_state_shaders.c |  2 +-
 7 files changed, 35 insertions(+), 27 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/si_debug.c b/src/gallium/drivers/radeonsi/si_debug.c
index 71db7f81271..4c1dd5491a2 100644
--- a/src/gallium/drivers/radeonsi/si_debug.c
+++ b/src/gallium/drivers/radeonsi/si_debug.c
@@ -807,7 +807,7 @@ static void si_dump_descriptors(struct si_context *sctx, gl_shader_stage stage,
    }
 
    if (stage == MESA_SHADER_VERTEX && sctx->vb_descriptors_buffer &&
-       sctx->vb_descriptors_gpu_list && sctx->vertex_elements) {
+       sctx->vb_descriptors_gpu_list) {
       assert(info); /* only CS may not have an info struct */
       struct si_descriptors desc = {};
 
diff --git a/src/gallium/drivers/radeonsi/si_gfx_cs.c b/src/gallium/drivers/radeonsi/si_gfx_cs.c
index a72062d15f0..16b6a10986c 100644
--- a/src/gallium/drivers/radeonsi/si_gfx_cs.c
+++ b/src/gallium/drivers/radeonsi/si_gfx_cs.c
@@ -443,7 +443,7 @@ void si_begin_new_gfx_cs(struct si_context *ctx, bool first_cs)
       ctx->prefetch_L2_mask |= SI_PREFETCH_VS;
    if (ctx->queued.named.ps)
       ctx->prefetch_L2_mask |= SI_PREFETCH_PS;
-   if (ctx->vb_descriptors_buffer && ctx->vertex_elements)
+   if (ctx->vb_descriptors_buffer)
       ctx->prefetch_L2_mask |= SI_PREFETCH_VBO_DESCRIPTORS;
 
    /* CLEAR_STATE disables all colorbuffers, so only enable bound ones. */
diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c
index fdee2c509a2..120b32e97f2 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.c
+++ b/src/gallium/drivers/radeonsi/si_pipe.c
@@ -255,6 +255,8 @@ static void si_destroy_context(struct pipe_context *context)
       sctx->b.delete_compute_state(&sctx->b, sctx->cs_dcc_decompress);
    if (sctx->cs_dcc_retile)
       sctx->b.delete_compute_state(&sctx->b, sctx->cs_dcc_retile);
+   if (sctx->no_velems_state)
+      sctx->b.delete_vertex_elements_state(&sctx->b, sctx->no_velems_state);
 
    for (unsigned i = 0; i < ARRAY_SIZE(sctx->cs_fmask_expand); i++) {
       for (unsigned j = 0; j < ARRAY_SIZE(sctx->cs_fmask_expand[i]); j++) {
@@ -580,6 +582,9 @@ static struct pipe_context *si_create_context(struct pipe_screen *screen, unsign
       sctx->noop_dsa = util_blitter_get_noop_dsa_state(sctx->blitter);
       sctx->queued.named.dsa = sctx->noop_dsa;
 
+      sctx->no_velems_state = sctx->b.create_vertex_elements_state(&sctx->b, 0, NULL);
+      sctx->vertex_elements = sctx->no_velems_state;
+
       sctx->discard_rasterizer_state = util_blitter_get_discard_rasterizer_state(sctx->blitter);
       sctx->queued.named.rasterizer = sctx->discard_rasterizer_state;
 
diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h
index 0623ad31b9d..e3f3ebc43d4 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.h
+++ b/src/gallium/drivers/radeonsi/si_pipe.h
@@ -941,6 +941,7 @@ struct si_context {
    struct blitter_context *blitter;
    void *noop_blend;
    void *noop_dsa;
+   void *no_velems_state;
    void *discard_rasterizer_state;
    void *custom_dsa_flush;
    void *custom_blend_resolve;
diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c
index 6e9ca6de66e..c2e752ef790 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -4770,8 +4770,11 @@ static void si_bind_vertex_elements(struct pipe_context *ctx, void *state)
    struct si_vertex_elements *old = sctx->vertex_elements;
    struct si_vertex_elements *v = (struct si_vertex_elements *)state;
 
+   if (!v)
+      v = sctx->no_velems_state;
+
    sctx->vertex_elements = v;
-   sctx->num_vertex_elements = v ? v->count : 0;
+   sctx->num_vertex_elements = v->count;
 
    if (sctx->num_vertex_elements) {
       sctx->vertex_buffers_dirty = true;
@@ -4780,24 +4783,24 @@ static void si_bind_vertex_elements(struct pipe_context *ctx, void *state)
       sctx->vertex_buffer_user_sgprs_dirty = false;
    }
 
-   if (v && (!old || old->count != v->count ||
-             old->uses_instance_divisors != v->uses_instance_divisors ||
-             /* we don't check which divisors changed */
-             v->uses_instance_divisors ||
-             (old->vb_alignment_check_mask ^ v->vb_alignment_check_mask) &
-                sctx->vertex_buffer_unaligned ||
-             ((v->vb_alignment_check_mask & sctx->vertex_buffer_unaligned) &&
-              memcmp(old->vertex_buffer_index, v->vertex_buffer_index,
-                     sizeof(v->vertex_buffer_index[0]) * v->count)) ||
-             /* fix_fetch_{always,opencode,unaligned} and hw_load_is_dword are
-              * functions of fix_fetch and the src_offset alignment.
-              * If they change and fix_fetch doesn't, it must be due to different
-              * src_offset alignment, which is reflected in fix_fetch_opencode. */
-             old->fix_fetch_opencode != v->fix_fetch_opencode ||
-             memcmp(old->fix_fetch, v->fix_fetch, sizeof(v->fix_fetch[0]) * v->count)))
+   if (old->count != v->count ||
+       old->uses_instance_divisors != v->uses_instance_divisors ||
+       /* we don't check which divisors changed */
+       v->uses_instance_divisors ||
+       (old->vb_alignment_check_mask ^ v->vb_alignment_check_mask) &
+       sctx->vertex_buffer_unaligned ||
+       ((v->vb_alignment_check_mask & sctx->vertex_buffer_unaligned) &&
+        memcmp(old->vertex_buffer_index, v->vertex_buffer_index,
+               sizeof(v->vertex_buffer_index[0]) * v->count)) ||
+       /* fix_fetch_{always,opencode,unaligned} and hw_load_is_dword are
+        * functions of fix_fetch and the src_offset alignment.
+        * If they change and fix_fetch doesn't, it must be due to different
+        * src_offset alignment, which is reflected in fix_fetch_opencode. */
+       old->fix_fetch_opencode != v->fix_fetch_opencode ||
+       memcmp(old->fix_fetch, v->fix_fetch, sizeof(v->fix_fetch[0]) * v->count))
       sctx->do_update_shaders = true;
 
-   if (v && v->instance_divisor_is_fetched) {
+   if (v->instance_divisor_is_fetched) {
       struct pipe_constant_buffer cb;
 
       cb.buffer = &v->instance_divisor_factor_buffer->b.b;
@@ -4813,10 +4816,9 @@ static void si_delete_vertex_element(struct pipe_context *ctx, void *state)
    struct si_context *sctx = (struct si_context *)ctx;
    struct si_vertex_elements *v = (struct si_vertex_elements *)state;
 
-   if (sctx->vertex_elements == state) {
-      sctx->vertex_elements = NULL;
-      sctx->num_vertex_elements = 0;
-   }
+   if (sctx->vertex_elements == state)
+      si_bind_vertex_elements(ctx, sctx->no_velems_state);
+
    si_resource_reference(&v->instance_divisor_factor_buffer, NULL);
    FREE(state);
 }
@@ -4865,8 +4867,8 @@ static void si_set_vertex_buffers(struct pipe_context *ctx, unsigned start_slot,
     * whether buffers are at least dword-aligned, since that should always
     * be the case in well-behaved applications anyway.
     */
-   if (sctx->vertex_elements && (sctx->vertex_elements->vb_alignment_check_mask &
-                                 (unaligned | orig_unaligned) & updated_mask))
+   if ((sctx->vertex_elements->vb_alignment_check_mask &
+        (unaligned | orig_unaligned) & updated_mask))
       sctx->do_update_shaders = true;
 }
 
diff --git a/src/gallium/drivers/radeonsi/si_state_draw.cpp b/src/gallium/drivers/radeonsi/si_state_draw.cpp
index 9731780bcb7..aa56e3d067f 100644
--- a/src/gallium/drivers/radeonsi/si_state_draw.cpp
+++ b/src/gallium/drivers/radeonsi/si_state_draw.cpp
@@ -68,7 +68,7 @@ static void si_prefetch_shader_async(struct si_context *sctx, struct si_pm4_stat
 
 static void si_prefetch_VBO_descriptors(struct si_context *sctx)
 {
-   if (!sctx->vertex_elements || !sctx->vertex_elements->vb_desc_list_alloc_size)
+   if (!sctx->vertex_elements->vb_desc_list_alloc_size)
       return;
 
    si_cp_dma_prefetch(sctx, &sctx->vb_descriptors_buffer->b.b, sctx->vb_descriptors_offset,
diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.c b/src/gallium/drivers/radeonsi/si_state_shaders.c
index 344296be09f..2ab6971c581 100644
--- a/src/gallium/drivers/radeonsi/si_state_shaders.c
+++ b/src/gallium/drivers/radeonsi/si_state_shaders.c
@@ -1744,7 +1744,7 @@ static unsigned si_get_alpha_test_func(struct si_context *sctx)
 void si_shader_selector_key_vs(struct si_context *sctx, struct si_shader_selector *vs,
                                struct si_shader_key *key, struct si_vs_prolog_bits *prolog_key)
 {
-   if (!sctx->vertex_elements || vs->info.base.vs.blit_sgprs_amd)
+   if (vs->info.base.vs.blit_sgprs_amd)
       return;
 
    struct si_vertex_elements *elts = sctx->vertex_elements;



More information about the mesa-commit mailing list