iris: implement Wa_14018912822
When MSAA is enabled, instead of using BLENDFACTOR_ZERO use CONST_COLOR, CONST_ALPHA and supply zero by using blend constants. We need info on blend state entries in the CSO so that we can set them up properly. Signed-off-by: Tapani Pälli <tapani.palli@intel.com> Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24714>
This commit is contained in:
@@ -825,6 +825,10 @@ struct iris_context {
|
|||||||
/** Current/upcoming ds_write_state for Wa_18019816803. */
|
/** Current/upcoming ds_write_state for Wa_18019816803. */
|
||||||
bool ds_write_state;
|
bool ds_write_state;
|
||||||
|
|
||||||
|
/** State tracking for Wa_14018912822. */
|
||||||
|
bool color_blend_zero;
|
||||||
|
bool alpha_blend_zero;
|
||||||
|
|
||||||
/** Do we have integer RT in current framebuffer state? */
|
/** Do we have integer RT in current framebuffer state? */
|
||||||
bool has_integer_rt;
|
bool has_integer_rt;
|
||||||
|
|
||||||
|
|||||||
@@ -1499,6 +1499,9 @@ struct iris_blend_state {
|
|||||||
|
|
||||||
/** Does RT[0] use dual color blending? */
|
/** Does RT[0] use dual color blending? */
|
||||||
bool dual_color_blending;
|
bool dual_color_blending;
|
||||||
|
|
||||||
|
int ps_dst_blend_factor[BRW_MAX_DRAW_BUFFERS];
|
||||||
|
int ps_dst_alpha_blend_factor[BRW_MAX_DRAW_BUFFERS];
|
||||||
};
|
};
|
||||||
|
|
||||||
static enum pipe_blendfactor
|
static enum pipe_blendfactor
|
||||||
@@ -1548,6 +1551,10 @@ iris_create_blend_state(struct pipe_context *ctx,
|
|||||||
enum pipe_blendfactor dst_alpha =
|
enum pipe_blendfactor dst_alpha =
|
||||||
fix_blendfactor(rt->alpha_dst_factor, state->alpha_to_one);
|
fix_blendfactor(rt->alpha_dst_factor, state->alpha_to_one);
|
||||||
|
|
||||||
|
/* Stored separately in cso for dynamic emission. */
|
||||||
|
cso->ps_dst_blend_factor[i] = (int) dst_rgb;
|
||||||
|
cso->ps_dst_alpha_blend_factor[i] = (int) dst_alpha;
|
||||||
|
|
||||||
if (rt->rgb_func != rt->alpha_func ||
|
if (rt->rgb_func != rt->alpha_func ||
|
||||||
src_rgb != src_alpha || dst_rgb != dst_alpha)
|
src_rgb != src_alpha || dst_rgb != dst_alpha)
|
||||||
indep_alpha_blend = true;
|
indep_alpha_blend = true;
|
||||||
@@ -1575,8 +1582,6 @@ iris_create_blend_state(struct pipe_context *ctx,
|
|||||||
/* The casts prevent warnings about implicit enum type conversions. */
|
/* The casts prevent warnings about implicit enum type conversions. */
|
||||||
be.SourceBlendFactor = (int) src_rgb;
|
be.SourceBlendFactor = (int) src_rgb;
|
||||||
be.SourceAlphaBlendFactor = (int) src_alpha;
|
be.SourceAlphaBlendFactor = (int) src_alpha;
|
||||||
be.DestinationBlendFactor = (int) dst_rgb;
|
|
||||||
be.DestinationAlphaBlendFactor = (int) dst_alpha;
|
|
||||||
|
|
||||||
be.WriteDisableRed = !(rt->colormask & PIPE_MASK_R);
|
be.WriteDisableRed = !(rt->colormask & PIPE_MASK_R);
|
||||||
be.WriteDisableGreen = !(rt->colormask & PIPE_MASK_G);
|
be.WriteDisableGreen = !(rt->colormask & PIPE_MASK_G);
|
||||||
@@ -1602,10 +1607,6 @@ iris_create_blend_state(struct pipe_context *ctx,
|
|||||||
(int) fix_blendfactor(state->rt[0].rgb_src_factor, state->alpha_to_one);
|
(int) fix_blendfactor(state->rt[0].rgb_src_factor, state->alpha_to_one);
|
||||||
pb.SourceAlphaBlendFactor =
|
pb.SourceAlphaBlendFactor =
|
||||||
(int) fix_blendfactor(state->rt[0].alpha_src_factor, state->alpha_to_one);
|
(int) fix_blendfactor(state->rt[0].alpha_src_factor, state->alpha_to_one);
|
||||||
pb.DestinationBlendFactor =
|
|
||||||
(int) fix_blendfactor(state->rt[0].rgb_dst_factor, state->alpha_to_one);
|
|
||||||
pb.DestinationAlphaBlendFactor =
|
|
||||||
(int) fix_blendfactor(state->rt[0].alpha_dst_factor, state->alpha_to_one);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
iris_pack_state(GENX(BLEND_STATE), cso->blend_state, bs) {
|
iris_pack_state(GENX(BLEND_STATE), cso->blend_state, bs) {
|
||||||
@@ -3594,6 +3595,13 @@ iris_set_framebuffer_state(struct pipe_context *ctx,
|
|||||||
/* We need to toggle 3DSTATE_PS::32 Pixel Dispatch Enable */
|
/* We need to toggle 3DSTATE_PS::32 Pixel Dispatch Enable */
|
||||||
if (GFX_VER >= 9 && (cso->samples == 16 || samples == 16))
|
if (GFX_VER >= 9 && (cso->samples == 16 || samples == 16))
|
||||||
ice->state.stage_dirty |= IRIS_STAGE_DIRTY_FS;
|
ice->state.stage_dirty |= IRIS_STAGE_DIRTY_FS;
|
||||||
|
|
||||||
|
/* We may need to emit blend state for Wa_14018912822. */
|
||||||
|
if ((cso->samples > 1) != (samples > 1) &&
|
||||||
|
intel_needs_workaround(devinfo, 14018912822)) {
|
||||||
|
ice->state.dirty |= IRIS_DIRTY_BLEND_STATE;
|
||||||
|
ice->state.dirty |= IRIS_DIRTY_PS_BLEND;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cso->nr_cbufs != state->nr_cbufs) {
|
if (cso->nr_cbufs != state->nr_cbufs) {
|
||||||
@@ -6405,6 +6413,13 @@ iris_upload_dirty_render_state(struct iris_context *ice,
|
|||||||
struct brw_wm_prog_data *wm_prog_data = (void *)
|
struct brw_wm_prog_data *wm_prog_data = (void *)
|
||||||
ice->shaders.prog[MESA_SHADER_FRAGMENT]->prog_data;
|
ice->shaders.prog[MESA_SHADER_FRAGMENT]->prog_data;
|
||||||
|
|
||||||
|
/* When MSAA is enabled, instead of using BLENDFACTOR_ZERO use
|
||||||
|
* CONST_COLOR, CONST_ALPHA and supply zero by using blend constants.
|
||||||
|
*/
|
||||||
|
bool needs_wa_14018912822 =
|
||||||
|
intel_needs_workaround(batch->screen->devinfo, 14018912822) &&
|
||||||
|
util_framebuffer_get_num_samples(&ice->state.framebuffer) > 1;
|
||||||
|
|
||||||
if (dirty & IRIS_DIRTY_CC_VIEWPORT) {
|
if (dirty & IRIS_DIRTY_CC_VIEWPORT) {
|
||||||
const struct iris_rasterizer_state *cso_rast = ice->state.cso_rast;
|
const struct iris_rasterizer_state *cso_rast = ice->state.cso_rast;
|
||||||
uint32_t cc_vp_address;
|
uint32_t cc_vp_address;
|
||||||
@@ -6524,6 +6539,9 @@ iris_upload_dirty_render_state(struct iris_context *ice,
|
|||||||
struct iris_depth_stencil_alpha_state *cso_zsa = ice->state.cso_zsa;
|
struct iris_depth_stencil_alpha_state *cso_zsa = ice->state.cso_zsa;
|
||||||
const int header_dwords = GENX(BLEND_STATE_length);
|
const int header_dwords = GENX(BLEND_STATE_length);
|
||||||
|
|
||||||
|
bool color_blend_zero = false;
|
||||||
|
bool alpha_blend_zero = false;
|
||||||
|
|
||||||
/* Always write at least one BLEND_STATE - the final RT message will
|
/* Always write at least one BLEND_STATE - the final RT message will
|
||||||
* reference BLEND_STATE[0] even if there aren't color writes. There
|
* reference BLEND_STATE[0] even if there aren't color writes. There
|
||||||
* may still be alpha testing, computed depth, and so on.
|
* may still be alpha testing, computed depth, and so on.
|
||||||
@@ -6537,6 +6555,51 @@ iris_upload_dirty_render_state(struct iris_context *ice,
|
|||||||
&ice->state.last_res.blend,
|
&ice->state.last_res.blend,
|
||||||
4 * (header_dwords + rt_dwords), 64, &blend_offset);
|
4 * (header_dwords + rt_dwords), 64, &blend_offset);
|
||||||
|
|
||||||
|
/* Copy of blend entries for merging dynamic changes. */
|
||||||
|
uint32_t blend_entries[4 * rt_dwords];
|
||||||
|
memcpy(blend_entries, &cso_blend->blend_state[1], sizeof(blend_entries));
|
||||||
|
|
||||||
|
unsigned cbufs = MAX2(cso_fb->nr_cbufs, 1);
|
||||||
|
|
||||||
|
uint32_t *blend_entry = blend_entries;
|
||||||
|
for (unsigned i = 0; i < cbufs; i++) {
|
||||||
|
int dst_blend_factor = cso_blend->ps_dst_blend_factor[i];
|
||||||
|
int dst_alpha_blend_factor = cso_blend->ps_dst_alpha_blend_factor[i];
|
||||||
|
uint32_t entry[GENX(BLEND_STATE_ENTRY_length)];
|
||||||
|
iris_pack_state(GENX(BLEND_STATE_ENTRY), entry, be) {
|
||||||
|
if (needs_wa_14018912822) {
|
||||||
|
if (dst_blend_factor == BLENDFACTOR_ZERO) {
|
||||||
|
dst_blend_factor = BLENDFACTOR_CONST_COLOR;
|
||||||
|
color_blend_zero = true;
|
||||||
|
}
|
||||||
|
if (dst_alpha_blend_factor == BLENDFACTOR_ZERO) {
|
||||||
|
dst_alpha_blend_factor = BLENDFACTOR_CONST_COLOR;
|
||||||
|
alpha_blend_zero = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
be.DestinationBlendFactor = dst_blend_factor;
|
||||||
|
be.DestinationAlphaBlendFactor = dst_alpha_blend_factor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Merge entry. */
|
||||||
|
uint32_t *dst = blend_entry;
|
||||||
|
uint32_t *src = entry;
|
||||||
|
for (unsigned j = 0; j < GENX(BLEND_STATE_ENTRY_length); j++)
|
||||||
|
*dst |= *src;
|
||||||
|
|
||||||
|
blend_entry += GENX(BLEND_STATE_ENTRY_length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Blend constants modified for Wa_14018912822. */
|
||||||
|
if (ice->state.color_blend_zero != color_blend_zero) {
|
||||||
|
ice->state.color_blend_zero = color_blend_zero;
|
||||||
|
ice->state.dirty |= IRIS_DIRTY_COLOR_CALC_STATE;
|
||||||
|
}
|
||||||
|
if (ice->state.alpha_blend_zero != alpha_blend_zero) {
|
||||||
|
ice->state.alpha_blend_zero = alpha_blend_zero;
|
||||||
|
ice->state.dirty |= IRIS_DIRTY_COLOR_CALC_STATE;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t blend_state_header;
|
uint32_t blend_state_header;
|
||||||
iris_pack_state(GENX(BLEND_STATE), &blend_state_header, bs) {
|
iris_pack_state(GENX(BLEND_STATE), &blend_state_header, bs) {
|
||||||
bs.AlphaTestEnable = cso_zsa->alpha_enabled;
|
bs.AlphaTestEnable = cso_zsa->alpha_enabled;
|
||||||
@@ -6544,7 +6607,7 @@ iris_upload_dirty_render_state(struct iris_context *ice,
|
|||||||
}
|
}
|
||||||
|
|
||||||
blend_map[0] = blend_state_header | cso_blend->blend_state[0];
|
blend_map[0] = blend_state_header | cso_blend->blend_state[0];
|
||||||
memcpy(&blend_map[1], &cso_blend->blend_state[1], 4 * rt_dwords);
|
memcpy(&blend_map[1], blend_entries, 4 * rt_dwords);
|
||||||
|
|
||||||
iris_emit_cmd(batch, GENX(3DSTATE_BLEND_STATE_POINTERS), ptr) {
|
iris_emit_cmd(batch, GENX(3DSTATE_BLEND_STATE_POINTERS), ptr) {
|
||||||
ptr.BlendStatePointer = blend_offset;
|
ptr.BlendStatePointer = blend_offset;
|
||||||
@@ -6566,10 +6629,14 @@ iris_upload_dirty_render_state(struct iris_context *ice,
|
|||||||
iris_pack_state(GENX(COLOR_CALC_STATE), cc_map, cc) {
|
iris_pack_state(GENX(COLOR_CALC_STATE), cc_map, cc) {
|
||||||
cc.AlphaTestFormat = ALPHATEST_FLOAT32;
|
cc.AlphaTestFormat = ALPHATEST_FLOAT32;
|
||||||
cc.AlphaReferenceValueAsFLOAT32 = cso->alpha_ref_value;
|
cc.AlphaReferenceValueAsFLOAT32 = cso->alpha_ref_value;
|
||||||
cc.BlendConstantColorRed = ice->state.blend_color.color[0];
|
cc.BlendConstantColorRed = ice->state.color_blend_zero ?
|
||||||
cc.BlendConstantColorGreen = ice->state.blend_color.color[1];
|
0.0 : ice->state.blend_color.color[0];
|
||||||
cc.BlendConstantColorBlue = ice->state.blend_color.color[2];
|
cc.BlendConstantColorGreen = ice->state.color_blend_zero ?
|
||||||
cc.BlendConstantColorAlpha = ice->state.blend_color.color[3];
|
0.0 : ice->state.blend_color.color[1];
|
||||||
|
cc.BlendConstantColorBlue = ice->state.color_blend_zero ?
|
||||||
|
0.0 : ice->state.blend_color.color[2];
|
||||||
|
cc.BlendConstantColorAlpha = ice->state.alpha_blend_zero ?
|
||||||
|
0.0 : ice->state.blend_color.color[3];
|
||||||
#if GFX_VER == 8
|
#if GFX_VER == 8
|
||||||
cc.StencilReferenceValue = p_stencil_refs->ref_value[0];
|
cc.StencilReferenceValue = p_stencil_refs->ref_value[0];
|
||||||
cc.BackfaceStencilReferenceValue = p_stencil_refs->ref_value[1];
|
cc.BackfaceStencilReferenceValue = p_stencil_refs->ref_value[1];
|
||||||
@@ -7112,11 +7179,27 @@ iris_upload_dirty_render_state(struct iris_context *ice,
|
|||||||
const struct shader_info *fs_info =
|
const struct shader_info *fs_info =
|
||||||
iris_get_shader_info(ice, MESA_SHADER_FRAGMENT);
|
iris_get_shader_info(ice, MESA_SHADER_FRAGMENT);
|
||||||
|
|
||||||
|
int dst_blend_factor = cso_blend->ps_dst_blend_factor[0];
|
||||||
|
int dst_alpha_blend_factor = cso_blend->ps_dst_alpha_blend_factor[0];
|
||||||
|
|
||||||
|
/* When MSAA is enabled, instead of using BLENDFACTOR_ZERO use
|
||||||
|
* CONST_COLOR, CONST_ALPHA and supply zero by using blend constants.
|
||||||
|
*/
|
||||||
|
if (needs_wa_14018912822) {
|
||||||
|
if (ice->state.color_blend_zero)
|
||||||
|
dst_blend_factor = BLENDFACTOR_CONST_COLOR;
|
||||||
|
if (ice->state.alpha_blend_zero)
|
||||||
|
dst_alpha_blend_factor = BLENDFACTOR_CONST_COLOR;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t dynamic_pb[GENX(3DSTATE_PS_BLEND_length)];
|
uint32_t dynamic_pb[GENX(3DSTATE_PS_BLEND_length)];
|
||||||
iris_pack_command(GENX(3DSTATE_PS_BLEND), &dynamic_pb, pb) {
|
iris_pack_command(GENX(3DSTATE_PS_BLEND), &dynamic_pb, pb) {
|
||||||
pb.HasWriteableRT = has_writeable_rt(cso_blend, fs_info);
|
pb.HasWriteableRT = has_writeable_rt(cso_blend, fs_info);
|
||||||
pb.AlphaTestEnable = cso_zsa->alpha_enabled;
|
pb.AlphaTestEnable = cso_zsa->alpha_enabled;
|
||||||
|
|
||||||
|
pb.DestinationBlendFactor = dst_blend_factor;
|
||||||
|
pb.DestinationAlphaBlendFactor = dst_alpha_blend_factor;
|
||||||
|
|
||||||
/* The dual source blending docs caution against using SRC1 factors
|
/* The dual source blending docs caution against using SRC1 factors
|
||||||
* when the shader doesn't use a dual source render target write.
|
* when the shader doesn't use a dual source render target write.
|
||||||
* Empirically, this can lead to GPU hangs, and the results are
|
* Empirically, this can lead to GPU hangs, and the results are
|
||||||
|
|||||||
Reference in New Issue
Block a user