[Mesa-dev] [PATCH 6/6] radeonsi: fix gl_BaseVertex in non-indexed draws
Marek Olšák
maraeo at gmail.com
Wed Apr 12 15:43:50 UTC 2017
For the series:
Reviewed-by: Marek Olšák <marek.olsak at amd.com>
Marek
On Wed, Apr 12, 2017 at 11:20 AM, Nicolai Hähnle <nhaehnle at gmail.com> wrote:
> From: Nicolai Hähnle <nicolai.haehnle at amd.com>
>
> gl_BaseVertex is supposed to be 0 in non-indexed draws. Unfortunately, the
> way they're implemented, the VGT always generates indices starting at 0,
> and the VS prolog adds the start index.
>
> There's a VGT_INDX_OFFSET register which causes the VGT to start at a
> driver-defined index. However, this register cannot be written from
> indirect draws.
>
> So fix this unlikely case by setting a bit to tell the VS whether the
> draw is indexed or not, so that gl_BaseVertex can be adjusted accordingly
> when used.
>
> Fixes a bug in
> KHR-GL45.shader_draw_parameters_tests.ShaderMultiDrawArraysParameters.*
> ---
> src/gallium/drivers/radeonsi/si_shader.c | 17 +++++++++++++++--
> src/gallium/drivers/radeonsi/si_shader.h | 2 ++
> src/gallium/drivers/radeonsi/si_state_draw.c | 8 ++++++--
> 3 files changed, 23 insertions(+), 4 deletions(-)
>
> diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c
> index 02447dd..f1daebe 100644
> --- a/src/gallium/drivers/radeonsi/si_shader.c
> +++ b/src/gallium/drivers/radeonsi/si_shader.c
> @@ -1394,23 +1394,36 @@ static void declare_system_value(struct si_shader_context *ctx,
> SI_PARAM_BASE_VERTEX), "");
> break;
>
> case TGSI_SEMANTIC_VERTEXID_NOBASE:
> /* Unused. Clarify the meaning in indexed vs. non-indexed
> * draws if this is ever used again. */
> assert(false);
> break;
>
> case TGSI_SEMANTIC_BASEVERTEX:
> - value = LLVMGetParam(ctx->main_fn,
> - SI_PARAM_BASE_VERTEX);
> + {
> + /* For non-indexed draws, the base vertex set by the driver
> + * (for direct draws) or the CP (for indirect draws) is the
> + * first vertex ID, but GLSL expects 0 to be returned.
> + */
> + LLVMValueRef vs_state = LLVMGetParam(ctx->main_fn, SI_PARAM_VS_STATE_BITS);
> + LLVMValueRef indexed;
> +
> + indexed = LLVMBuildLShr(gallivm->builder, vs_state, ctx->i32_1, "");
> + indexed = LLVMBuildTrunc(gallivm->builder, indexed, ctx->i1, "");
> +
> + value = LLVMBuildSelect(gallivm->builder, indexed,
> + LLVMGetParam(ctx->main_fn, SI_PARAM_BASE_VERTEX),
> + ctx->i32_0, "");
> break;
> + }
>
> case TGSI_SEMANTIC_BASEINSTANCE:
> value = LLVMGetParam(ctx->main_fn,
> SI_PARAM_START_INSTANCE);
> break;
>
> case TGSI_SEMANTIC_DRAWID:
> value = LLVMGetParam(ctx->main_fn,
> SI_PARAM_DRAWID);
> break;
> diff --git a/src/gallium/drivers/radeonsi/si_shader.h b/src/gallium/drivers/radeonsi/si_shader.h
> index fdb0dd4..f145eab 100644
> --- a/src/gallium/drivers/radeonsi/si_shader.h
> +++ b/src/gallium/drivers/radeonsi/si_shader.h
> @@ -213,20 +213,22 @@ enum {
> SI_PARAM_BLOCK_ID,
> SI_PARAM_THREAD_ID,
>
> SI_NUM_PARAMS = SI_PARAM_POS_FIXED_PT + 9, /* +8 for COLOR[0..1] */
> };
>
> /* Fields of driver-defined VS state SGPR. */
> /* Clamp vertex color output (only used in VS as VS). */
> #define S_VS_STATE_CLAMP_VERTEX_COLOR(x) (((unsigned)(x) & 0x1) << 0)
> #define C_VS_STATE_CLAMP_VERTEX_COLOR 0xFFFFFFFE
> +#define S_VS_STATE_INDEXED(x) (((unsigned)(x) & 0x1) << 1)
> +#define C_VS_STATE_INDEXED 0xFFFFFFFD
> #define S_VS_STATE_LS_OUT_PATCH_SIZE(x) (((unsigned)(x) & 0x1FFF) << 8)
> #define C_VS_STATE_LS_OUT_PATCH_SIZE 0xFFE000FF
> #define S_VS_STATE_LS_OUT_VERTEX_SIZE(x) (((unsigned)(x) & 0xFF) << 24)
> #define C_VS_STATE_LS_OUT_VERTEX_SIZE 0x00FFFFFF
>
> /* SI-specific system values. */
> enum {
> TGSI_SEMANTIC_DEFAULT_TESSOUTER_SI = TGSI_SEMANTIC_COUNT,
> TGSI_SEMANTIC_DEFAULT_TESSINNER_SI,
> };
> diff --git a/src/gallium/drivers/radeonsi/si_state_draw.c b/src/gallium/drivers/radeonsi/si_state_draw.c
> index 0d70ea9..aa528ce 100644
> --- a/src/gallium/drivers/radeonsi/si_state_draw.c
> +++ b/src/gallium/drivers/radeonsi/si_state_draw.c
> @@ -487,22 +487,26 @@ static void si_emit_rasterizer_prim_state(struct si_context *sctx)
> * reset the stipple pattern at each packet (line strips, line loops).
> */
> radeon_set_context_reg(cs, R_028A0C_PA_SC_LINE_STIPPLE,
> rs->pa_sc_line_stipple |
> S_028A0C_AUTO_RESET_CNTL(rast_prim == PIPE_PRIM_LINES ? 1 : 2));
>
> sctx->last_rast_prim = rast_prim;
> sctx->last_sc_line_stipple = rs->pa_sc_line_stipple;
> }
>
> -static void si_emit_vs_state(struct si_context *sctx)
> +static void si_emit_vs_state(struct si_context *sctx,
> + const struct pipe_draw_info *info)
> {
> + sctx->current_vs_state &= C_VS_STATE_INDEXED;
> + sctx->current_vs_state |= S_VS_STATE_INDEXED(!!info->indexed);
> +
> if (sctx->current_vs_state != sctx->last_vs_state) {
> struct radeon_winsys_cs *cs = sctx->b.gfx.cs;
>
> radeon_set_sh_reg(cs,
> sctx->shader_userdata.sh_base[PIPE_SHADER_VERTEX] +
> SI_SGPR_VS_STATE_BITS * 4,
> sctx->current_vs_state);
>
> sctx->last_vs_state = sctx->current_vs_state;
> }
> @@ -1298,21 +1302,21 @@ void si_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info)
> continue;
>
> si_pm4_emit(sctx, state);
> sctx->emitted.array[i] = state;
> }
> sctx->dirty_states = 0;
>
> si_emit_rasterizer_prim_state(sctx);
> if (sctx->tes_shader.cso)
> si_emit_derived_tess_state(sctx, info, &num_patches);
> - si_emit_vs_state(sctx);
> + si_emit_vs_state(sctx, info);
> si_emit_draw_registers(sctx, info, num_patches);
>
> si_ce_pre_draw_synchronization(sctx);
> si_emit_draw_packets(sctx, info, ib);
> si_ce_post_draw_synchronization(sctx);
>
> if (sctx->trace_buf)
> si_trace_emit(sctx);
>
> /* Workaround for a VGT hang when streamout is enabled.
> --
> 2.9.3
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
More information about the mesa-dev
mailing list