radeonsi: don't export ClipVertex and ClipDistance[] if clipping is disabled
authorMarek Olšák <marek.olsak@amd.com>
Sun, 13 Nov 2016 17:41:43 +0000 (18:41 +0100)
committerMarek Olšák <marek.olsak@amd.com>
Mon, 21 Nov 2016 20:44:35 +0000 (21:44 +0100)
This is the first user of optimized monolithic shader variants.

Cull distances can't be disabled by states.

Tested-by: Edmondo Tommasina <edmondo.tommasina@gmail.com>
Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
src/gallium/drivers/radeonsi/si_shader.c
src/gallium/drivers/radeonsi/si_shader.h
src/gallium/drivers/radeonsi/si_state.c
src/gallium/drivers/radeonsi/si_state_shaders.c

index 5e57bb3..a80d9c3 100644 (file)
@@ -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:
index 38aa361..4cbd1c2 100644 (file)
@@ -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;
 };
 
index 096c641..b3299a9 100644 (file)
@@ -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) |
index 00ccbbd..1d116f6 100644 (file)
@@ -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;