diff options
author | Marek Olšák <[email protected]> | 2016-11-13 18:41:43 +0100 |
---|---|---|
committer | Marek Olšák <[email protected]> | 2016-11-21 21:44:35 +0100 |
commit | ed3190b3f3a776fc8c75b1e6130a88079166d115 (patch) | |
tree | d91eb6553426550e1488f36445c83b143b7162f1 | |
parent | d984a324bf8702adde68c006f1c3454233871e1c (diff) |
radeonsi: don't export ClipVertex and ClipDistance[] if clipping is disabled
This is the first user of optimized monolithic shader variants.
Cull distances can't be disabled by states.
Tested-by: Edmondo Tommasina <[email protected]>
Reviewed-by: Nicolai Hähnle <[email protected]>
-rw-r--r-- | src/gallium/drivers/radeonsi/si_shader.c | 6 | ||||
-rw-r--r-- | src/gallium/drivers/radeonsi/si_shader.h | 5 | ||||
-rw-r--r-- | src/gallium/drivers/radeonsi/si_state.c | 10 | ||||
-rw-r--r-- | src/gallium/drivers/radeonsi/si_state_shaders.c | 21 |
4 files changed, 37 insertions, 5 deletions
diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c index 5e57bb3b664..a80d9c375b0 100644 --- a/src/gallium/drivers/radeonsi/si_shader.c +++ b/src/gallium/drivers/radeonsi/si_shader.c @@ -2294,9 +2294,15 @@ handle_semantic: param_count++; break; case TGSI_SEMANTIC_CLIPDIST: + if (shader->key.opt.hw_vs.clip_disable) { + semantic_name = TGSI_SEMANTIC_GENERIC; + goto handle_semantic; + } target = V_008DFC_SQ_EXP_POS + 2 + semantic_index; break; case TGSI_SEMANTIC_CLIPVERTEX: + if (shader->key.opt.hw_vs.clip_disable) + continue; si_llvm_emit_clipvertex(bld_base, pos_args, outputs[i].values); continue; case TGSI_SEMANTIC_PRIMID: diff --git a/src/gallium/drivers/radeonsi/si_shader.h b/src/gallium/drivers/radeonsi/si_shader.h index 38aa361d496..4cbd1c24742 100644 --- a/src/gallium/drivers/radeonsi/si_shader.h +++ b/src/gallium/drivers/radeonsi/si_shader.h @@ -320,8 +320,6 @@ struct si_vs_prolog_bits { struct si_vs_epilog_bits { unsigned export_prim_id:1; /* when PS needs it and GS is disabled */ /* TODO: - * - skip clipdist, culldist (including clipvertex code) exports based - * on which clip_plane_enable bits are set * - skip layer, viewport, clipdist, and culldist parameter exports * if PS doesn't read them */ @@ -438,6 +436,9 @@ struct si_shader_key { /* Optimization flags for asynchronous compilation only. */ union { + struct { + unsigned clip_disable:1; + } hw_vs; /* HW VS (it can be VS, TES, GS) */ } opt; }; diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c index 096c641818e..b3299a95b78 100644 --- a/src/gallium/drivers/radeonsi/si_state.c +++ b/src/gallium/drivers/radeonsi/si_state.c @@ -644,6 +644,7 @@ static void si_emit_clip_state(struct si_context *sctx, struct r600_atom *atom) static void si_emit_clip_regs(struct si_context *sctx, struct r600_atom *atom) { struct radeon_winsys_cs *cs = sctx->b.gfx.cs; + struct si_shader *vs = si_get_vs_state(sctx); struct tgsi_shader_info *info = si_get_vs_info(sctx); struct si_state_rasterizer *rs = sctx->queued.named.rasterizer; unsigned window_space = @@ -652,7 +653,14 @@ static void si_emit_clip_regs(struct si_context *sctx, struct r600_atom *atom) info->writes_clipvertex ? SIX_BITS : info->clipdist_writemask; unsigned ucp_mask = clipdist_mask ? 0 : rs->clip_plane_enable & SIX_BITS; unsigned culldist_mask = info->culldist_writemask << info->num_written_clipdistance; - unsigned total_mask = clipdist_mask | culldist_mask; + unsigned total_mask; + + if (vs->key.opt.hw_vs.clip_disable) { + assert(!info->culldist_writemask); + clipdist_mask = 0; + culldist_mask = 0; + } + total_mask = clipdist_mask | culldist_mask; radeon_set_context_reg(cs, R_02881C_PA_CL_VS_OUT_CNTL, S_02881C_USE_VTX_POINT_SIZE(info->writes_psize) | diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.c b/src/gallium/drivers/radeonsi/si_state_shaders.c index 00ccbbd53ab..1d116f6b00b 100644 --- a/src/gallium/drivers/radeonsi/si_state_shaders.c +++ b/src/gallium/drivers/radeonsi/si_state_shaders.c @@ -854,6 +854,17 @@ static unsigned si_get_alpha_test_func(struct si_context *sctx) return PIPE_FUNC_ALWAYS; } +static void si_shader_selector_key_hw_vs(struct si_context *sctx, + struct si_shader_selector *vs, + struct si_shader_key *key) +{ + key->opt.hw_vs.clip_disable = + sctx->queued.named.rasterizer->clip_plane_enable == 0 && + (vs->info.clipdist_writemask || + vs->info.writes_clipvertex) && + !vs->info.culldist_writemask; +} + /* Compute the key for the hw shader variant */ static inline void si_shader_selector_key(struct pipe_context *ctx, struct si_shader_selector *sel, @@ -882,6 +893,8 @@ static inline void si_shader_selector_key(struct pipe_context *ctx, else if (sctx->gs_shader.cso) key->as_es = 1; else { + si_shader_selector_key_hw_vs(sctx, sel, key); + if (sctx->ps_shader.cso && sctx->ps_shader.cso->info.uses_primid) key->part.vs.epilog.export_prim_id = 1; } @@ -896,8 +909,12 @@ static inline void si_shader_selector_key(struct pipe_context *ctx, case PIPE_SHADER_TESS_EVAL: if (sctx->gs_shader.cso) key->as_es = 1; - else if (sctx->ps_shader.cso && sctx->ps_shader.cso->info.uses_primid) - key->part.tes.epilog.export_prim_id = 1; + else { + si_shader_selector_key_hw_vs(sctx, sel, key); + + if (sctx->ps_shader.cso && sctx->ps_shader.cso->info.uses_primid) + key->part.tes.epilog.export_prim_id = 1; + } break; case PIPE_SHADER_GEOMETRY: key->part.gs.prolog.tri_strip_adj_fix = sctx->gs_tri_strip_adj_fix; |