summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKenneth Graunke <[email protected]>2019-02-11 12:07:51 -0800
committerKenneth Graunke <[email protected]>2019-02-21 10:26:12 -0800
commitbf23e7962979ecd7bcc27e4442e36e8e5fc5814e (patch)
tree87579bc07fc71f72d5dc8164e58ae82c369f606a
parentd612cd1bf80f36023f0918beb74df08f9bca8abd (diff)
iris: Set HasWriteableRT correctly
A bit of irritating state cross dependency here, but nothing too hard
-rw-r--r--src/gallium/drivers/iris/iris_program.c15
-rw-r--r--src/gallium/drivers/iris/iris_state.c31
2 files changed, 45 insertions, 1 deletions
diff --git a/src/gallium/drivers/iris/iris_program.c b/src/gallium/drivers/iris/iris_program.c
index 4eb2b676a7d..8b1fa56659a 100644
--- a/src/gallium/drivers/iris/iris_program.c
+++ b/src/gallium/drivers/iris/iris_program.c
@@ -516,6 +516,21 @@ iris_bind_gs_state(struct pipe_context *ctx, void *state)
static void
iris_bind_fs_state(struct pipe_context *ctx, void *state)
{
+ struct iris_context *ice = (struct iris_context *) ctx;
+ struct iris_uncompiled_shader *old_ish =
+ ice->shaders.uncompiled[MESA_SHADER_FRAGMENT];
+ struct iris_uncompiled_shader *new_ish = state;
+
+ const unsigned color_bits =
+ BITFIELD64_BIT(FRAG_RESULT_COLOR) |
+ BITFIELD64_RANGE(FRAG_RESULT_DATA0, BRW_MAX_DRAW_BUFFERS);
+
+ /* Fragment shader outputs influence HasWriteableRT */
+ if (!old_ish || !new_ish ||
+ (old_ish->nir->info.outputs_written & color_bits) !=
+ (new_ish->nir->info.outputs_written & color_bits))
+ ice->state.dirty |= IRIS_DIRTY_PS_BLEND;
+
bind_state((void *) ctx, state, MESA_SHADER_FRAGMENT);
}
diff --git a/src/gallium/drivers/iris/iris_state.c b/src/gallium/drivers/iris/iris_state.c
index 6d75d255eac..bc9071d86f0 100644
--- a/src/gallium/drivers/iris/iris_state.c
+++ b/src/gallium/drivers/iris/iris_state.c
@@ -821,6 +821,9 @@ struct iris_blend_state {
/** Bitfield of whether blending is enabled for RT[i] - for aux resolves */
uint8_t blend_enables;
+
+ /** Bitfield of whether color writes are enabled for RT[i] */
+ uint8_t color_write_enables;
};
static enum pipe_blendfactor
@@ -850,6 +853,7 @@ iris_create_blend_state(struct pipe_context *ctx,
uint32_t *blend_entry = cso->blend_state + GENX(BLEND_STATE_length);
cso->blend_enables = 0;
+ cso->color_write_enables = 0;
STATIC_ASSERT(BRW_MAX_DRAW_BUFFERS <= 8);
cso->alpha_to_coverage = state->alpha_to_coverage;
@@ -876,6 +880,9 @@ iris_create_blend_state(struct pipe_context *ctx,
if (rt->blend_enable)
cso->blend_enables |= 1u << i;
+ if (rt->colormask)
+ cso->color_write_enables |= 1u << i;
+
iris_pack_state(GENX(BLEND_STATE_ENTRY), blend_entry, be) {
be.LogicOpEnable = state->logicop_enable;
be.LogicOpFunction = state->logicop_func;
@@ -953,6 +960,25 @@ iris_bind_blend_state(struct pipe_context *ctx, void *state)
}
/**
+ * Return true if the FS writes to any color outputs which are not disabled
+ * via color masking.
+ */
+static bool
+has_writeable_rt(const struct iris_blend_state *cso_blend,
+ const struct shader_info *fs_info)
+{
+ if (!fs_info)
+ return false;
+
+ unsigned rt_outputs = fs_info->outputs_written >> FRAG_RESULT_DATA0;
+
+ if (fs_info->outputs_written & BITFIELD64_BIT(FRAG_RESULT_COLOR))
+ rt_outputs = (1 << BRW_MAX_DRAW_BUFFERS) - 1;
+
+ return cso_blend->color_write_enables & rt_outputs;
+}
+
+/**
* Gallium CSO for depth, stencil, and alpha testing state.
*/
struct iris_depth_stencil_alpha_state {
@@ -4422,9 +4448,12 @@ iris_upload_dirty_render_state(struct iris_context *ice,
if (dirty & IRIS_DIRTY_PS_BLEND) {
struct iris_blend_state *cso_blend = ice->state.cso_blend;
struct iris_depth_stencil_alpha_state *cso_zsa = ice->state.cso_zsa;
+ const struct shader_info *fs_info =
+ iris_get_shader_info(ice, MESA_SHADER_FRAGMENT);
+
uint32_t dynamic_pb[GENX(3DSTATE_PS_BLEND_length)];
iris_pack_command(GENX(3DSTATE_PS_BLEND), &dynamic_pb, pb) {
- pb.HasWriteableRT = true; // XXX: comes from somewhere :(
+ pb.HasWriteableRT = has_writeable_rt(cso_blend, fs_info);
pb.AlphaTestEnable = cso_zsa->alpha.enabled;
}