mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-31 22:50:08 +01:00
anv: Only flush render target cache when detecting RT changes
We setup an empty render target when there are no color attachments,
which effectively makes it a different surface state. In most cases
the compiler will insert a null-rt bit in the extended descriptor
which means the RT isn't even accessed. But in some cases like
alpha-to-coverage output + depth/stencil write, we will access the
render target because using the null-rt will prevent alpha-to-coverage
from happening.
Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Fixes: 2bd304bc8f ("anv: Skip the RT flush when doing depth-only rendering.")
Reviewed-by: Ivan Briano <ivan.briano@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/31196>
This commit is contained in:
parent
fb3ae17d96
commit
badb3f6301
3 changed files with 84 additions and 18 deletions
|
|
@ -3822,6 +3822,12 @@ struct anv_cmd_graphics_state {
|
|||
struct anv_attachment stencil_att;
|
||||
struct anv_state null_surface_state;
|
||||
|
||||
/* Bitfield of color attachments disabled by a pipeline (pointing a null
|
||||
* surface state in the last emitted binding table for the fragment
|
||||
* stage)
|
||||
*/
|
||||
uint8_t disabled_color_atts;
|
||||
|
||||
anv_cmd_dirty_mask_t dirty;
|
||||
uint32_t vb_dirty;
|
||||
|
||||
|
|
|
|||
|
|
@ -5176,15 +5176,24 @@ void genX(CmdBeginRendering)(
|
|||
};
|
||||
|
||||
const uint32_t color_att_count = pRenderingInfo->colorAttachmentCount;
|
||||
|
||||
result = anv_cmd_buffer_init_attachments(cmd_buffer, color_att_count);
|
||||
if (result != VK_SUCCESS)
|
||||
return;
|
||||
|
||||
genX(flush_pipeline_select_3d)(cmd_buffer);
|
||||
|
||||
UNUSED bool render_target_change = false;
|
||||
for (uint32_t i = 0; i < gfx->color_att_count; i++) {
|
||||
if (pRenderingInfo->pColorAttachments[i].imageView == VK_NULL_HANDLE)
|
||||
if (pRenderingInfo->pColorAttachments[i].imageView == VK_NULL_HANDLE) {
|
||||
render_target_change |= gfx->color_att[i].iview != NULL;
|
||||
|
||||
gfx->color_att[i].vk_format = VK_FORMAT_UNDEFINED;
|
||||
gfx->color_att[i].iview = NULL;
|
||||
gfx->color_att[i].layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
gfx->color_att[i].aux_usage = ISL_AUX_USAGE_NONE;
|
||||
continue;
|
||||
}
|
||||
|
||||
const VkRenderingAttachmentInfo *att =
|
||||
&pRenderingInfo->pColorAttachments[i];
|
||||
|
|
@ -5211,6 +5220,13 @@ void genX(CmdBeginRendering)(
|
|||
att->imageLayout,
|
||||
cmd_buffer->queue_family->queueFlags);
|
||||
|
||||
render_target_change |= gfx->color_att[i].iview != iview;
|
||||
|
||||
gfx->color_att[i].vk_format = iview->vk.format;
|
||||
gfx->color_att[i].iview = iview;
|
||||
gfx->color_att[i].layout = att->imageLayout;
|
||||
gfx->color_att[i].aux_usage = aux_usage;
|
||||
|
||||
union isl_color_value fast_clear_color = { .u32 = { 0, } };
|
||||
|
||||
if (att->loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR &&
|
||||
|
|
@ -5325,11 +5341,6 @@ void genX(CmdBeginRendering)(
|
|||
assert(att->imageLayout == initial_layout);
|
||||
}
|
||||
|
||||
gfx->color_att[i].vk_format = iview->vk.format;
|
||||
gfx->color_att[i].iview = iview;
|
||||
gfx->color_att[i].layout = att->imageLayout;
|
||||
gfx->color_att[i].aux_usage = aux_usage;
|
||||
|
||||
struct isl_view isl_view = iview->planes[0].isl;
|
||||
if (pRenderingInfo->viewMask) {
|
||||
assert(isl_view.array_len >= util_last_bit(pRenderingInfo->viewMask));
|
||||
|
|
@ -5606,14 +5617,7 @@ void genX(CmdBeginRendering)(
|
|||
gfx->dirty |= ANV_CMD_DIRTY_PIPELINE;
|
||||
|
||||
#if GFX_VER >= 11
|
||||
bool has_color_att = false;
|
||||
for (uint32_t i = 0; i < gfx->color_att_count; i++) {
|
||||
if (pRenderingInfo->pColorAttachments[i].imageView != VK_NULL_HANDLE) {
|
||||
has_color_att = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (has_color_att) {
|
||||
if (render_target_change) {
|
||||
/* The PIPE_CONTROL command description says:
|
||||
*
|
||||
* "Whenever a Binding Table Index (BTI) used by a Render Target Message
|
||||
|
|
|
|||
|
|
@ -687,6 +687,60 @@ genX(emit_ds)(struct anv_cmd_buffer *cmd_buffer)
|
|||
#endif
|
||||
}
|
||||
|
||||
ALWAYS_INLINE static void
|
||||
cmd_buffer_maybe_flush_rt_writes(struct anv_cmd_buffer *cmd_buffer,
|
||||
struct anv_graphics_pipeline *pipeline)
|
||||
{
|
||||
#if GFX_VER >= 11
|
||||
if (!anv_pipeline_has_stage(pipeline, MESA_SHADER_FRAGMENT))
|
||||
return;
|
||||
|
||||
const struct anv_shader_bin *shader =
|
||||
pipeline->base.shaders[MESA_SHADER_FRAGMENT];
|
||||
const struct anv_pipeline_bind_map *bind_map = &shader->bind_map;
|
||||
|
||||
unsigned s;
|
||||
uint8_t disabled_mask = 0;
|
||||
for (s = 0; s < bind_map->surface_count; s++) {
|
||||
const struct anv_pipeline_binding *binding =
|
||||
&bind_map->surface_to_descriptor[s];
|
||||
|
||||
if (binding->set != ANV_DESCRIPTOR_SET_COLOR_ATTACHMENTS)
|
||||
break;
|
||||
|
||||
if (binding->index >= cmd_buffer->state.gfx.color_att_count)
|
||||
disabled_mask |= BITFIELD_BIT(s);
|
||||
}
|
||||
|
||||
const uint8_t diff_mask = (1u << s) - 1;
|
||||
|
||||
if ((cmd_buffer->state.gfx.disabled_color_atts & diff_mask) != disabled_mask) {
|
||||
cmd_buffer->state.gfx.disabled_color_atts = disabled_mask |
|
||||
(cmd_buffer->state.gfx.disabled_color_atts & ~diff_mask);
|
||||
|
||||
/* The PIPE_CONTROL command description says:
|
||||
*
|
||||
* "Whenever a Binding Table Index (BTI) used by a Render Target Message
|
||||
* points to a different RENDER_SURFACE_STATE, SW must issue a Render
|
||||
* Target Cache Flush by enabling this bit. When render target flush
|
||||
* is set due to new association of BTI, PS Scoreboard Stall bit must
|
||||
* be set in this packet."
|
||||
*
|
||||
* Within a renderpass, the render target entries in the binding tables
|
||||
* remain the same as what was setup at CmdBeginRendering() with one
|
||||
* exception where have to setup a null render target because a fragment
|
||||
* writes only depth/stencil yet the renderpass has been setup with at
|
||||
* least one color attachment. This is because our render target messages
|
||||
* in the shader always send the color.
|
||||
*/
|
||||
anv_add_pending_pipe_bits(cmd_buffer,
|
||||
ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT |
|
||||
ANV_PIPE_STALL_AT_SCOREBOARD_BIT,
|
||||
"change RT due to shader outputs");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
ALWAYS_INLINE static void
|
||||
genX(cmd_buffer_flush_gfx_state)(struct anv_cmd_buffer *cmd_buffer)
|
||||
{
|
||||
|
|
@ -708,16 +762,18 @@ genX(cmd_buffer_flush_gfx_state)(struct anv_cmd_buffer *cmd_buffer)
|
|||
|
||||
genX(flush_pipeline_select_3d)(cmd_buffer);
|
||||
|
||||
/* Wa_14015814527
|
||||
*
|
||||
* Apply task URB workaround when switching from task to primitive.
|
||||
*/
|
||||
if (cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_PIPELINE) {
|
||||
/* Wa_14015814527
|
||||
*
|
||||
* Apply task URB workaround when switching from task to primitive.
|
||||
*/
|
||||
if (anv_pipeline_is_primitive(pipeline)) {
|
||||
genX(apply_task_urb_workaround)(cmd_buffer);
|
||||
} else if (anv_pipeline_has_stage(pipeline, MESA_SHADER_TASK)) {
|
||||
cmd_buffer->state.gfx.used_task_shader = true;
|
||||
}
|
||||
|
||||
cmd_buffer_maybe_flush_rt_writes(cmd_buffer, pipeline);
|
||||
}
|
||||
|
||||
/* Apply any pending pipeline flushes we may have. We want to apply them
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue