anv: fix VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT state

First, there is a problem if you do the following

 vkCmdSetColorWriteEnableEXT(attachmentCount = 8)
 vkCmdBindPipeline(GFX, with attachmentCount = 4)
 vkCmdDraw()
 vkCmdBindPipeline(GFX, with attachmentCount = 8)
 vkCmdDraw()

Because in the dynamic state emission code we rely on the first
pipeline to figure the number of BLEND_STATE entries to prepare. This
is wrong, we should fill all entries so that the dynamic state works
regardless of the number of attachments in the pipeline. With regard
to the dynamic values, we should retain enable/disable values that do
not concern the current pipeline.

Second, 3DSTATE_WM was not always reemitted when the pipeline changed.
But since it is not emitted as part of the pipeline, this results in
inconsistent state being programmed.

Third, we end up disabling the fragment stage completely in some
cases. And that is programming the pipeline inconsistently and
triggering a hang on TGL.

v2: Fix comment (Tapani)

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Fixes: b15bfe92f7 ("anv: implement VK_EXT_color_write_enable")
Reviewed-by: Tapani Pälli <tapani.palli@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15310>
This commit is contained in:
Lionel Landwerlin
2021-10-11 18:31:26 +03:00
committed by Marge Bot
parent f348103fce
commit a4f502de32
5 changed files with 91 additions and 152 deletions

View File

@@ -1600,9 +1600,16 @@ void anv_CmdSetColorWriteEnableEXT(
assert(attachmentCount <= MAX_RTS);
uint8_t color_writes = 0;
for (uint32_t i = 0; i < attachmentCount; i++)
color_writes |= pColorWriteEnables[i] ? (1 << i) : 0;
/* Keep the existing values outside the color attachments count of the
* current pipeline.
*/
uint8_t color_writes = cmd_buffer->state.gfx.dynamic.color_writes;
for (uint32_t i = 0; i < attachmentCount; i++) {
if (pColorWriteEnables[i])
color_writes |= BITFIELD_BIT(i);
else
color_writes &= ~BITFIELD_BIT(i);
}
if (cmd_buffer->state.gfx.dynamic.color_writes != color_writes) {
cmd_buffer->state.gfx.dynamic.color_writes = color_writes;