For the series: Reviewed-by: Marek Olšák <[email protected]>
Marek On Wed, Apr 12, 2017 at 11:20 AM, Nicolai Hähnle <[email protected]> wrote: > From: Nicolai Hähnle <[email protected]> > > 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 > [email protected] > https://lists.freedesktop.org/mailman/listinfo/mesa-dev _______________________________________________ mesa-dev mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/mesa-dev
