From f2a514870155bbd08c28cd2a00dc720cb7490cc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Sat, 9 Jan 2021 05:27:57 -0500 Subject: [PATCH] radeonsi: make sctx->vertex_elements always non-NULL Bind a state with 0 vertex elements there. Reviewed-by: Pierre-Eric Pelloux-Prayer Part-of: --- 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 ++++++++++--------- .../drivers/radeonsi/si_state_draw.cpp | 2 +- .../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;