From bf23e7962979ecd7bcc27e4442e36e8e5fc5814e Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Mon, 11 Feb 2019 12:07:51 -0800 Subject: [PATCH] iris: Set HasWriteableRT correctly A bit of irritating state cross dependency here, but nothing too hard --- src/gallium/drivers/iris/iris_program.c | 15 ++++++++++++ src/gallium/drivers/iris/iris_state.c | 31 ++++++++++++++++++++++++- 2 files changed, 45 insertions(+), 1 deletion(-) 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; @@ -952,6 +959,25 @@ iris_bind_blend_state(struct pipe_context *ctx, void *state) ice->state.dirty |= ice->state.dirty_for_nos[IRIS_NOS_BLEND]; } +/** + * 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. */ @@ -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; } -- 2.30.2