radeonsi: separate out shader key bits for prologs & epilogs
authorMarek Olšák <marek.olsak@amd.com>
Tue, 26 Jan 2016 17:46:31 +0000 (18:46 +0100)
committerMarek Olšák <marek.olsak@amd.com>
Sun, 21 Feb 2016 20:08:57 +0000 (21:08 +0100)
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 655894146fdbfc780241fb13157e52871575037d..4f4243306d8a7247d750811e72f0414d64c36394 100644 (file)
@@ -403,7 +403,8 @@ static void declare_input_vs(
        struct gallivm_state *gallivm = base->gallivm;
        struct si_shader_context *ctx =
                si_shader_context(&radeon_bld->soa.bld_base);
-       unsigned divisor = ctx->shader->key.vs.instance_divisors[input_index];
+       unsigned divisor =
+               ctx->shader->key.vs.prolog.instance_divisors[input_index];
 
        unsigned chan;
 
@@ -854,7 +855,7 @@ static int lookup_interp_param_index(unsigned interpolate, unsigned location)
 static unsigned select_interp_param(struct si_shader_context *ctx,
                                    unsigned param)
 {
-       if (!ctx->shader->key.ps.force_persample_interp)
+       if (!ctx->shader->key.ps.prolog.force_persample_interp)
                return param;
 
        /* If the shader doesn't use center/centroid, just return the parameter.
@@ -924,7 +925,7 @@ static void interp_fs_input(struct si_shader_context *ctx,
        intr_name = interp_param ? "llvm.SI.fs.interp" : "llvm.SI.fs.constant";
 
        if (semantic_name == TGSI_SEMANTIC_COLOR &&
-           ctx->shader->key.ps.color_two_side) {
+           ctx->shader->key.ps.prolog.color_two_side) {
                LLVMValueRef args[4];
                LLVMValueRef is_face_positive;
                LLVMValueRef back_attr_number;
@@ -1331,12 +1332,12 @@ static void si_llvm_init_export_args(struct lp_build_tgsi_context *bld_base,
 
        if (ctx->type == TGSI_PROCESSOR_FRAGMENT) {
                const union si_shader_key *key = &ctx->shader->key;
-               unsigned col_formats = key->ps.spi_shader_col_format;
+               unsigned col_formats = key->ps.epilog.spi_shader_col_format;
                int cbuf = target - V_008DFC_SQ_EXP_MRT;
 
                assert(cbuf >= 0 && cbuf < 8);
                spi_shader_col_format = (col_formats >> (cbuf * 4)) & 0xf;
-               is_int8 = (key->ps.color_is_int8 >> cbuf) & 0x1;
+               is_int8 = (key->ps.epilog.color_is_int8 >> cbuf) & 0x1;
        }
 
        args[4] = uint->zero; /* COMPR flag */
@@ -1489,13 +1490,13 @@ static void si_alpha_test(struct lp_build_tgsi_context *bld_base,
        struct si_shader_context *ctx = si_shader_context(bld_base);
        struct gallivm_state *gallivm = bld_base->base.gallivm;
 
-       if (ctx->shader->key.ps.alpha_func != PIPE_FUNC_NEVER) {
+       if (ctx->shader->key.ps.epilog.alpha_func != PIPE_FUNC_NEVER) {
                LLVMValueRef alpha_ref = LLVMGetParam(ctx->radeon_bld.main_fn,
                                SI_PARAM_ALPHA_REF);
 
                LLVMValueRef alpha_pass =
                        lp_build_cmp(&bld_base->base,
-                                    ctx->shader->key.ps.alpha_func,
+                                    ctx->shader->key.ps.epilog.alpha_func,
                                     alpha, alpha_ref);
                LLVMValueRef arg =
                        lp_build_select(&bld_base->base,
@@ -1990,7 +1991,7 @@ static void si_write_tess_factors(struct lp_build_tgsi_context *bld_base,
                                  invocation_id, bld_base->uint_bld.zero, ""));
 
        /* Determine the layout of one tess factor element in the buffer. */
-       switch (shader->key.tcs.prim_mode) {
+       switch (shader->key.tcs.epilog.prim_mode) {
        case PIPE_PRIM_LINES:
                stride = 2; /* 2 dwords, 1 vec2 store */
                outer_comps = 2;
@@ -2292,30 +2293,30 @@ static void si_export_mrt_color(struct lp_build_tgsi_context *bld_base,
        int i;
 
        /* Clamp color */
-       if (ctx->shader->key.ps.clamp_color)
+       if (ctx->shader->key.ps.epilog.clamp_color)
                for (i = 0; i < 4; i++)
                        color[i] = radeon_llvm_saturate(bld_base, color[i]);
 
        /* Alpha to one */
-       if (ctx->shader->key.ps.alpha_to_one)
+       if (ctx->shader->key.ps.epilog.alpha_to_one)
                color[3] = base->one;
 
        /* Alpha test */
        if (index == 0 &&
-           ctx->shader->key.ps.alpha_func != PIPE_FUNC_ALWAYS)
+           ctx->shader->key.ps.epilog.alpha_func != PIPE_FUNC_ALWAYS)
                si_alpha_test(bld_base, color[3]);
 
        /* Line & polygon smoothing */
-       if (ctx->shader->key.ps.poly_line_smoothing)
+       if (ctx->shader->key.ps.epilog.poly_line_smoothing)
                color[3] = si_scale_alpha_by_sample_mask(bld_base, color[3]);
 
        /* If last_cbuf > 0, FS_COLOR0_WRITES_ALL_CBUFS is true. */
-       if (ctx->shader->key.ps.last_cbuf > 0) {
+       if (ctx->shader->key.ps.epilog.last_cbuf > 0) {
                LLVMValueRef args[8][9];
                int c, last = -1;
 
                /* Get the export arguments, also find out what the last one is. */
-               for (c = 0; c <= ctx->shader->key.ps.last_cbuf; c++) {
+               for (c = 0; c <= ctx->shader->key.ps.epilog.last_cbuf; c++) {
                        si_llvm_init_export_args(bld_base, color,
                                                 V_008DFC_SQ_EXP_MRT + c, args[c]);
                        if (args[c][0] != bld_base->uint_bld.zero)
@@ -2323,7 +2324,7 @@ static void si_export_mrt_color(struct lp_build_tgsi_context *bld_base,
                }
 
                /* Emit all exports. */
-               for (c = 0; c <= ctx->shader->key.ps.last_cbuf; c++) {
+               for (c = 0; c <= ctx->shader->key.ps.epilog.last_cbuf; c++) {
                        if (is_last && last == c) {
                                args[c][1] = bld_base->uint_bld.one; /* whether the EXEC mask is valid */
                                args[c][2] = bld_base->uint_bld.one; /* DONE bit */
@@ -2386,11 +2387,11 @@ static void si_llvm_emit_fs_epilogue(struct lp_build_tgsi_context *bld_base)
         * Otherwise, find the last color export.
         */
        if (!info->writes_z && !info->writes_stencil && !info->writes_samplemask) {
-               unsigned spi_format = shader->key.ps.spi_shader_col_format;
+               unsigned spi_format = shader->key.ps.epilog.spi_shader_col_format;
 
                /* Don't export NULL and return if alpha-test is enabled. */
-               if (shader->key.ps.alpha_func != PIPE_FUNC_ALWAYS &&
-                   shader->key.ps.alpha_func != PIPE_FUNC_NEVER &&
+               if (shader->key.ps.epilog.alpha_func != PIPE_FUNC_ALWAYS &&
+                   shader->key.ps.epilog.alpha_func != PIPE_FUNC_NEVER &&
                    (spi_format & 0xf) == 0)
                        spi_format |= V_028714_SPI_SHADER_32_AR;
 
@@ -2401,10 +2402,10 @@ static void si_llvm_emit_fs_epilogue(struct lp_build_tgsi_context *bld_base)
                                continue;
 
                        /* If last_cbuf > 0, FS_COLOR0_WRITES_ALL_CBUFS is true. */
-                       if (shader->key.ps.last_cbuf > 0) {
+                       if (shader->key.ps.epilog.last_cbuf > 0) {
                                /* Just set this if any of the colorbuffers are enabled. */
                                if (spi_format &
-                                   ((1llu << (4 * (shader->key.ps.last_cbuf + 1))) - 1))
+                                   ((1llu << (4 * (shader->key.ps.epilog.last_cbuf + 1))) - 1))
                                        last_color_export = i;
                                continue;
                        }
@@ -4313,35 +4314,38 @@ void si_dump_shader_key(unsigned shader, union si_shader_key *key, FILE *f)
        switch (shader) {
        case PIPE_SHADER_VERTEX:
                fprintf(f, "  instance_divisors = {");
-               for (i = 0; i < Elements(key->vs.instance_divisors); i++)
+               for (i = 0; i < Elements(key->vs.prolog.instance_divisors); i++)
                        fprintf(f, !i ? "%u" : ", %u",
-                               key->vs.instance_divisors[i]);
+                               key->vs.prolog.instance_divisors[i]);
                fprintf(f, "}\n");
                fprintf(f, "  as_es = %u\n", key->vs.as_es);
                fprintf(f, "  as_ls = %u\n", key->vs.as_ls);
-               fprintf(f, "  export_prim_id = %u\n", key->vs.export_prim_id);
+               fprintf(f, "  export_prim_id = %u\n", key->vs.epilog.export_prim_id);
                break;
 
        case PIPE_SHADER_TESS_CTRL:
-               fprintf(f, "  prim_mode = %u\n", key->tcs.prim_mode);
+               fprintf(f, "  prim_mode = %u\n", key->tcs.epilog.prim_mode);
                break;
 
        case PIPE_SHADER_TESS_EVAL:
                fprintf(f, "  as_es = %u\n", key->tes.as_es);
-               fprintf(f, "  export_prim_id = %u\n", key->tes.export_prim_id);
+               fprintf(f, "  export_prim_id = %u\n", key->tes.epilog.export_prim_id);
                break;
 
        case PIPE_SHADER_GEOMETRY:
                break;
 
        case PIPE_SHADER_FRAGMENT:
-               fprintf(f, "  spi_shader_col_format = 0x%x\n", key->ps.spi_shader_col_format);
-               fprintf(f, "  last_cbuf = %u\n", key->ps.last_cbuf);
-               fprintf(f, "  color_two_side = %u\n", key->ps.color_two_side);
-               fprintf(f, "  alpha_func = %u\n", key->ps.alpha_func);
-               fprintf(f, "  alpha_to_one = %u\n", key->ps.alpha_to_one);
-               fprintf(f, "  poly_stipple = %u\n", key->ps.poly_stipple);
-               fprintf(f, "  clamp_color = %u\n", key->ps.clamp_color);
+               fprintf(f, "  prolog.color_two_side = %u\n", key->ps.prolog.color_two_side);
+               fprintf(f, "  prolog.poly_stipple = %u\n", key->ps.prolog.poly_stipple);
+               fprintf(f, "  prolog.force_persample_interp = %u\n", key->ps.prolog.force_persample_interp);
+               fprintf(f, "  epilog.spi_shader_col_format = 0x%x\n", key->ps.epilog.spi_shader_col_format);
+               fprintf(f, "  epilog.color_is_int8 = 0x%X\n", key->ps.epilog.color_is_int8);
+               fprintf(f, "  epilog.last_cbuf = %u\n", key->ps.epilog.last_cbuf);
+               fprintf(f, "  epilog.alpha_func = %u\n", key->ps.epilog.alpha_func);
+               fprintf(f, "  epilog.alpha_to_one = %u\n", key->ps.epilog.alpha_to_one);
+               fprintf(f, "  epilog.poly_line_smoothing = %u\n", key->ps.epilog.poly_line_smoothing);
+               fprintf(f, "  epilog.clamp_color = %u\n", key->ps.epilog.clamp_color);
                break;
 
        default:
@@ -4427,7 +4431,7 @@ int si_shader_create(struct si_screen *sscreen, LLVMTargetMachineRef tm,
        LLVMModuleRef mod;
        int r = 0;
        bool poly_stipple = sel->type == PIPE_SHADER_FRAGMENT &&
-                           shader->key.ps.poly_stipple;
+                           shader->key.ps.prolog.poly_stipple;
 
        if (poly_stipple) {
                tokens = util_pstipple_create_fragment_shader(tokens, NULL,
index 3be24f34391088b776291f178115e572ae99e467..9331156b0025a7ede0a9c5e5bdc8e77c9cd0dac4 100644 (file)
@@ -221,37 +221,70 @@ struct si_shader_selector {
  * With both:        LS | HS  | ES  | GS | VS | PS
  */
 
+/* Common VS bits between the shader key and the prolog key. */
+struct si_vs_prolog_bits {
+       unsigned        instance_divisors[SI_NUM_VERTEX_BUFFERS];
+};
+
+/* Common VS bits between the shader key and the epilog key. */
+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
+        */
+};
+
+/* Common TCS bits between the shader key and the epilog key. */
+struct si_tcs_epilog_bits {
+       unsigned        prim_mode:3;
+};
+
+/* Common PS bits between the shader key and the prolog key. */
+struct si_ps_prolog_bits {
+       unsigned        color_two_side:1;
+       /* TODO: add a flatshade bit that skips interpolation for colors */
+       unsigned        poly_stipple:1;
+       unsigned        force_persample_interp:1;
+       /* TODO:
+        * - add force_center_interp if MSAA is disabled and centroid or
+        *   sample are present
+        * - add force_center_interp_bc_optimize to force center interpolation
+        *   based on the bc_optimize SGPR bit if MSAA is enabled, centroid is
+        *   present and sample isn't present.
+        */
+};
+
+/* Common PS bits between the shader key and the epilog key. */
+struct si_ps_epilog_bits {
+       unsigned        spi_shader_col_format;
+       unsigned        color_is_int8:8;
+       unsigned        last_cbuf:3;
+       unsigned        alpha_func:3;
+       unsigned        alpha_to_one:1;
+       unsigned        poly_line_smoothing:1;
+       unsigned        clamp_color:1;
+};
+
 union si_shader_key {
        struct {
-               unsigned        spi_shader_col_format;
-               unsigned        color_is_int8:8;
-               unsigned        last_cbuf:3;
-               unsigned        color_two_side:1;
-               unsigned        alpha_func:3;
-               unsigned        alpha_to_one:1;
-               unsigned        poly_stipple:1;
-               unsigned        poly_line_smoothing:1;
-               unsigned        clamp_color:1;
-               unsigned        force_persample_interp:1;
+               struct si_ps_prolog_bits prolog;
+               struct si_ps_epilog_bits epilog;
        } ps;
        struct {
-               unsigned        instance_divisors[SI_NUM_VERTEX_BUFFERS];
-               /* Mask of "get_unique_index" bits - which outputs are read
-                * by the next stage (needed by ES).
-                * This describes how outputs are laid out in memory. */
+               struct si_vs_prolog_bits prolog;
+               struct si_vs_epilog_bits epilog;
                unsigned        as_es:1; /* export shader */
                unsigned        as_ls:1; /* local shader */
-               unsigned        export_prim_id:1; /* when PS needs it and GS is disabled */
        } vs;
        struct {
-               unsigned        prim_mode:3;
+               struct si_tcs_epilog_bits epilog;
        } tcs; /* tessellation control shader */
        struct {
-               /* Mask of "get_unique_index" bits - which outputs are read
-                * by the next stage (needed by ES).
-                * This describes how outputs are laid out in memory. */
+               struct si_vs_epilog_bits epilog; /* same as VS */
                unsigned        as_es:1; /* export shader */
-               unsigned        export_prim_id:1; /* when PS needs it and GS is disabled */
        } tes; /* tessellation evaluation shader */
 };
 
@@ -314,9 +347,9 @@ static inline struct si_shader* si_get_vs_state(struct si_context *sctx)
 static inline bool si_vs_exports_prim_id(struct si_shader *shader)
 {
        if (shader->selector->type == PIPE_SHADER_VERTEX)
-               return shader->key.vs.export_prim_id;
+               return shader->key.vs.epilog.export_prim_id;
        else if (shader->selector->type == PIPE_SHADER_TESS_EVAL)
-               return shader->key.tes.export_prim_id;
+               return shader->key.tes.epilog.export_prim_id;
        else
                return false;
 }
index bf780777b50c021830607bc51b3a3e5d1093f48d..2dfdbeb8d8f895172cbd18110ad8dc947420ea8b 100644 (file)
@@ -277,7 +277,7 @@ static void si_emit_cb_render_state(struct si_context *sctx, struct r600_atom *a
        if (sctx->b.family == CHIP_STONEY) {
                unsigned spi_shader_col_format =
                        sctx->ps_shader.cso ?
-                       sctx->ps_shader.current->key.ps.spi_shader_col_format : 0;
+                       sctx->ps_shader.current->key.ps.epilog.spi_shader_col_format : 0;
                unsigned sx_ps_downconvert = 0;
                unsigned sx_blend_opt_epsilon = 0;
                unsigned sx_blend_opt_control = 0;
index 77a4e47c809fd60b941d40e02a60f6ba737f92f6..08f5d88e8dc714ae96e712d75e9516c4aad3e074 100644 (file)
@@ -415,7 +415,7 @@ static unsigned si_get_ps_num_interp(struct si_shader *ps)
        unsigned num_colors = !!(info->colors_read & 0x0f) +
                              !!(info->colors_read & 0xf0);
        unsigned num_interp = ps->selector->info.num_inputs +
-                             (ps->key.ps.color_two_side ? num_colors : 0);
+                             (ps->key.ps.prolog.color_two_side ? num_colors : 0);
 
        assert(num_interp <= 32);
        return MIN2(num_interp, 32);
@@ -423,7 +423,7 @@ static unsigned si_get_ps_num_interp(struct si_shader *ps)
 
 static unsigned si_get_spi_shader_col_format(struct si_shader *shader)
 {
-       unsigned value = shader->key.ps.spi_shader_col_format;
+       unsigned value = shader->key.ps.epilog.spi_shader_col_format;
        unsigned i, num_targets = (util_last_bit(value) + 3) / 4;
 
        /* If the i-th target format is set, all previous target formats must
@@ -528,7 +528,7 @@ static void si_shader_ps(struct si_shader *shader)
        if (!spi_shader_col_format &&
            !info->writes_z && !info->writes_stencil && !info->writes_samplemask &&
            (shader->selector->info.uses_kill ||
-            shader->key.ps.alpha_func != PIPE_FUNC_ALWAYS))
+            shader->key.ps.epilog.alpha_func != PIPE_FUNC_ALWAYS))
                spi_shader_col_format = V_028714_SPI_SHADER_32_R;
 
        si_pm4_set_reg(pm4, R_0286CC_SPI_PS_INPUT_ENA, input_ena);
@@ -638,11 +638,13 @@ static inline void si_shader_selector_key(struct pipe_context *ctx,
 
        switch (sel->type) {
        case PIPE_SHADER_VERTEX:
-               if (sctx->vertex_elements)
-                       for (i = 0; i < sctx->vertex_elements->count; ++i)
-                               key->vs.instance_divisors[i] =
+               if (sctx->vertex_elements) {
+                       unsigned count = MIN2(sel->info.num_inputs,
+                                             sctx->vertex_elements->count);
+                       for (i = 0; i < count; ++i)
+                               key->vs.prolog.instance_divisors[i] =
                                        sctx->vertex_elements->elements[i].instance_divisor;
-
+               }
                if (sctx->tes_shader.cso)
                        key->vs.as_ls = 1;
                else if (sctx->gs_shader.cso)
@@ -650,17 +652,17 @@ static inline void si_shader_selector_key(struct pipe_context *ctx,
 
                if (!sctx->gs_shader.cso && sctx->ps_shader.cso &&
                    sctx->ps_shader.cso->info.uses_primid)
-                       key->vs.export_prim_id = 1;
+                       key->vs.epilog.export_prim_id = 1;
                break;
        case PIPE_SHADER_TESS_CTRL:
-               key->tcs.prim_mode =
+               key->tcs.epilog.prim_mode =
                        sctx->tes_shader.cso->info.properties[TGSI_PROPERTY_TES_PRIM_MODE];
                break;
        case PIPE_SHADER_TESS_EVAL:
                if (sctx->gs_shader.cso)
                        key->tes.as_es = 1;
                else if (sctx->ps_shader.cso && sctx->ps_shader.cso->info.uses_primid)
-                       key->tes.export_prim_id = 1;
+                       key->tes.epilog.export_prim_id = 1;
                break;
        case PIPE_SHADER_GEOMETRY:
                break;
@@ -670,13 +672,13 @@ static inline void si_shader_selector_key(struct pipe_context *ctx,
 
                if (sel->info.properties[TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS] &&
                    sel->info.colors_written == 0x1)
-                       key->ps.last_cbuf = MAX2(sctx->framebuffer.state.nr_cbufs, 1) - 1;
+                       key->ps.epilog.last_cbuf = MAX2(sctx->framebuffer.state.nr_cbufs, 1) - 1;
 
                if (blend) {
                        /* Select the shader color format based on whether
                         * blending or alpha are needed.
                         */
-                       key->ps.spi_shader_col_format =
+                       key->ps.epilog.spi_shader_col_format =
                                (blend->blend_enable_4bit & blend->need_src_alpha_4bit &
                                 sctx->framebuffer.spi_shader_col_format_blend_alpha) |
                                (blend->blend_enable_4bit & ~blend->need_src_alpha_4bit &
@@ -686,26 +688,26 @@ static inline void si_shader_selector_key(struct pipe_context *ctx,
                                (~blend->blend_enable_4bit & ~blend->need_src_alpha_4bit &
                                 sctx->framebuffer.spi_shader_col_format);
                } else
-                       key->ps.spi_shader_col_format = sctx->framebuffer.spi_shader_col_format;
+                       key->ps.epilog.spi_shader_col_format = sctx->framebuffer.spi_shader_col_format;
 
                /* If alpha-to-coverage is enabled, we have to export alpha
                 * even if there is no color buffer.
                 */
-               if (!(key->ps.spi_shader_col_format & 0xf) &&
+               if (!(key->ps.epilog.spi_shader_col_format & 0xf) &&
                    blend && blend->alpha_to_coverage)
-                       key->ps.spi_shader_col_format |= V_028710_SPI_SHADER_32_AR;
+                       key->ps.epilog.spi_shader_col_format |= V_028710_SPI_SHADER_32_AR;
 
                /* On SI and CIK except Hawaii, the CB doesn't clamp outputs
                 * to the range supported by the type if a channel has less
                 * than 16 bits and the export format is 16_ABGR.
                 */
                if (sctx->b.chip_class <= CIK && sctx->b.family != CHIP_HAWAII)
-                       key->ps.color_is_int8 = sctx->framebuffer.color_is_int8;
+                       key->ps.epilog.color_is_int8 = sctx->framebuffer.color_is_int8;
 
                /* Disable unwritten outputs (if WRITE_ALL_CBUFS isn't enabled). */
-               if (!key->ps.last_cbuf) {
-                       key->ps.spi_shader_col_format &= sel->colors_written_4bit;
-                       key->ps.color_is_int8 &= sel->info.colors_written;
+               if (!key->ps.epilog.last_cbuf) {
+                       key->ps.epilog.spi_shader_col_format &= sel->colors_written_4bit;
+                       key->ps.epilog.color_is_int8 &= sel->info.colors_written;
                }
 
                if (rs) {
@@ -714,31 +716,32 @@ static inline void si_shader_selector_key(struct pipe_context *ctx,
                                       sctx->current_rast_prim >= PIPE_PRIM_TRIANGLES_ADJACENCY;
                        bool is_line = !is_poly && sctx->current_rast_prim != PIPE_PRIM_POINTS;
 
-                       key->ps.color_two_side = rs->two_side && sel->info.colors_read;
+                       key->ps.prolog.color_two_side = rs->two_side && sel->info.colors_read;
 
                        if (sctx->queued.named.blend) {
-                               key->ps.alpha_to_one = sctx->queued.named.blend->alpha_to_one &&
-                                                      rs->multisample_enable &&
-                                                      !sctx->framebuffer.cb0_is_integer;
+                               key->ps.epilog.alpha_to_one = sctx->queued.named.blend->alpha_to_one &&
+                                                             rs->multisample_enable &&
+                                                             !sctx->framebuffer.cb0_is_integer;
                        }
 
-                       key->ps.poly_stipple = rs->poly_stipple_enable && is_poly;
-                       key->ps.poly_line_smoothing = ((is_poly && rs->poly_smooth) ||
-                                                      (is_line && rs->line_smooth)) &&
-                                                     sctx->framebuffer.nr_samples <= 1;
-                       key->ps.clamp_color = rs->clamp_fragment_color;
-
-                       key->ps.force_persample_interp = rs->force_persample_interp &&
-                                                        rs->multisample_enable &&
-                                                        sctx->framebuffer.nr_samples > 1 &&
-                                                        sctx->ps_iter_samples > 1 &&
-                                                        (sel->info.uses_persp_center ||
-                                                         sel->info.uses_persp_centroid ||
-                                                         sel->info.uses_linear_center ||
-                                                         sel->info.uses_linear_centroid);
+                       key->ps.prolog.poly_stipple = rs->poly_stipple_enable && is_poly;
+                       key->ps.epilog.poly_line_smoothing = ((is_poly && rs->poly_smooth) ||
+                                                             (is_line && rs->line_smooth)) &&
+                                                            sctx->framebuffer.nr_samples <= 1;
+                       key->ps.epilog.clamp_color = rs->clamp_fragment_color;
+
+                       key->ps.prolog.force_persample_interp =
+                               rs->force_persample_interp &&
+                               rs->multisample_enable &&
+                               sctx->framebuffer.nr_samples > 1 &&
+                               sctx->ps_iter_samples > 1 &&
+                               (sel->info.uses_persp_center ||
+                                sel->info.uses_persp_centroid ||
+                                sel->info.uses_linear_center ||
+                                sel->info.uses_linear_centroid);
                }
 
-               key->ps.alpha_func = si_get_alpha_test_func(sctx);
+               key->ps.epilog.alpha_func = si_get_alpha_test_func(sctx);
                break;
        }
        default:
@@ -934,13 +937,13 @@ static void *si_create_shader_selector(struct pipe_context *ctx,
                 */
                switch (sel->type) {
                case PIPE_SHADER_TESS_CTRL:
-                       key.tcs.prim_mode = PIPE_PRIM_TRIANGLES;
+                       key.tcs.epilog.prim_mode = PIPE_PRIM_TRIANGLES;
                        break;
                case PIPE_SHADER_FRAGMENT:
-                       key.ps.alpha_func = PIPE_FUNC_ALWAYS;
+                       key.ps.epilog.alpha_func = PIPE_FUNC_ALWAYS;
                        for (i = 0; i < 8; i++)
                                if (sel->info.colors_written & (1 << i))
-                                       key.ps.spi_shader_col_format |=
+                                       key.ps.epilog.spi_shader_col_format |=
                                                V_028710_SPI_SHADER_FP16_ABGR << (i * 4);
                        break;
                }
@@ -1191,7 +1194,7 @@ static void si_emit_spi_map(struct si_context *sctx, struct r600_atom *atom)
                }
        }
 
-       if (ps->key.ps.color_two_side) {
+       if (ps->key.ps.prolog.color_two_side) {
                unsigned bcol = TGSI_SEMANTIC_BCOLOR;
 
                for (i = 0; i < 2; i++) {
@@ -1745,8 +1748,8 @@ bool si_update_shaders(struct si_context *sctx)
                        si_mark_atom_dirty(sctx, &sctx->db_render_state);
                }
 
-               if (sctx->smoothing_enabled != sctx->ps_shader.current->key.ps.poly_line_smoothing) {
-                       sctx->smoothing_enabled = sctx->ps_shader.current->key.ps.poly_line_smoothing;
+               if (sctx->smoothing_enabled != sctx->ps_shader.current->key.ps.epilog.poly_line_smoothing) {
+                       sctx->smoothing_enabled = sctx->ps_shader.current->key.ps.epilog.poly_line_smoothing;
                        si_mark_atom_dirty(sctx, &sctx->msaa_config);
 
                        if (sctx->b.chip_class == SI)