mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 09:38:07 +02:00
tu: Disable LRZ writes after most stencil-write operations.
As explained in the comment, stencil can have a similar dependency on later LRZ writes to how blending does. Fixes dEQP-VK.imageless_framebuffer.depth_stencil with TU_DEBUG=gmem,forcebin (so you get LRZ filled during binning of the single draw call that happened) Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/13533 Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36660>
This commit is contained in:
parent
07cee75c39
commit
071a7e5f8f
3 changed files with 49 additions and 0 deletions
|
|
@ -6225,6 +6225,31 @@ tu6_stencil_written_on_depth_fail(
|
|||
}
|
||||
}
|
||||
|
||||
/* Returns true if the stencil write result may change based on the result of a
|
||||
* depth test.
|
||||
*/
|
||||
static bool
|
||||
tu6_stencil_written_based_on_depth_test(
|
||||
const struct vk_stencil_test_face_state *face)
|
||||
{
|
||||
switch (face->op.compare) {
|
||||
case VK_COMPARE_OP_ALWAYS:
|
||||
/* The stencil op always passes, no need to worry about failOp. */
|
||||
return face->op.depth_fail != VK_STENCIL_OP_KEEP ||
|
||||
face->op.pass != VK_STENCIL_OP_KEEP;
|
||||
case VK_COMPARE_OP_NEVER:
|
||||
/* The stencil op always fails, so failOp will always be used. */
|
||||
return face->op.fail != VK_STENCIL_OP_KEEP;
|
||||
default:
|
||||
/* If the stencil test fails, depth may fail as well, so we can write
|
||||
* stencil when the depth fails if failOp is not VK_STENCIL_OP_KEEP.
|
||||
*/
|
||||
return face->op.fail != VK_STENCIL_OP_KEEP ||
|
||||
face->op.pass != VK_STENCIL_OP_KEEP ||
|
||||
face->op.depth_fail != VK_STENCIL_OP_KEEP;
|
||||
}
|
||||
}
|
||||
|
||||
/* Various frontends (ANGLE, zink at least) will enable stencil testing with
|
||||
* what works out to be no-op writes. Simplify what they give us into flags
|
||||
* that LRZ can use.
|
||||
|
|
@ -6240,6 +6265,7 @@ tu6_update_simplified_stencil_state(struct tu_cmd_buffer *cmd)
|
|||
cmd->state.stencil_front_write = false;
|
||||
cmd->state.stencil_back_write = false;
|
||||
cmd->state.stencil_written_on_depth_fail = false;
|
||||
cmd->state.stencil_written_based_on_depth_test = false;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -6272,6 +6298,11 @@ tu6_update_simplified_stencil_state(struct tu_cmd_buffer *cmd)
|
|||
tu6_stencil_written_on_depth_fail(&ds->stencil.front)) ||
|
||||
(cmd->state.stencil_back_write &&
|
||||
tu6_stencil_written_on_depth_fail(&ds->stencil.back));
|
||||
cmd->state.stencil_written_based_on_depth_test =
|
||||
(cmd->state.stencil_front_write &&
|
||||
tu6_stencil_written_based_on_depth_test(&ds->stencil.front)) ||
|
||||
(cmd->state.stencil_back_write &&
|
||||
tu6_stencil_written_based_on_depth_test(&ds->stencil.back));
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
|
|||
|
|
@ -549,6 +549,7 @@ struct tu_cmd_state
|
|||
bool stencil_front_write;
|
||||
bool stencil_back_write;
|
||||
bool stencil_written_on_depth_fail;
|
||||
bool stencil_written_based_on_depth_test;
|
||||
bool pipeline_sysmem_single_prim_mode;
|
||||
bool pipeline_has_tess;
|
||||
bool pipeline_disable_gmem;
|
||||
|
|
|
|||
|
|
@ -964,6 +964,23 @@ tu6_calculate_lrz_state(struct tu_cmd_buffer *cmd,
|
|||
}
|
||||
}
|
||||
|
||||
/* If the stencil test behavior depends on the result of the depth test, we
|
||||
* have to skip LRZ for the rest of the RP for basically the same reason as
|
||||
* the blending case above (LRZ testing enabled on previous draws may result
|
||||
* in skipping their Z changes which feed into this draw, so we can't let
|
||||
* later Z writes affect any of them).
|
||||
*
|
||||
* Because the LRZ test runs first, failing the LRZ test may result in
|
||||
* skipping the stencil test and subsequent stencil write. This is ok if
|
||||
* stencil is only written when the depth test passes, because then the LRZ
|
||||
* test will also pass, but if it may be written when the depth or stencil
|
||||
* test fails then we need to disable the LRZ test for the draw as well.
|
||||
*/
|
||||
if (cmd->state.stencil_written_based_on_depth_test) {
|
||||
tu_lrz_write_disable_reason(cmd, "stencil write based on depth test");
|
||||
cmd->state.lrz.disable_write_for_rp = true;
|
||||
}
|
||||
|
||||
if (disable_lrz)
|
||||
cmd->state.lrz.valid = false;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue