summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2016-11-13 18:41:43 +0100
committerMarek Olšák <[email protected]>2016-11-21 21:44:35 +0100
commited3190b3f3a776fc8c75b1e6130a88079166d115 (patch)
treed91eb6553426550e1488f36445c83b143b7162f1
parentd984a324bf8702adde68c006f1c3454233871e1c (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.c6
-rw-r--r--src/gallium/drivers/radeonsi/si_shader.h5
-rw-r--r--src/gallium/drivers/radeonsi/si_state.c10
-rw-r--r--src/gallium/drivers/radeonsi/si_state_shaders.c21
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;