mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-07 09:18:04 +02: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_attachment stencil_att;
|
||||||
struct anv_state null_surface_state;
|
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;
|
anv_cmd_dirty_mask_t dirty;
|
||||||
uint32_t vb_dirty;
|
uint32_t vb_dirty;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5176,15 +5176,24 @@ void genX(CmdBeginRendering)(
|
||||||
};
|
};
|
||||||
|
|
||||||
const uint32_t color_att_count = pRenderingInfo->colorAttachmentCount;
|
const uint32_t color_att_count = pRenderingInfo->colorAttachmentCount;
|
||||||
|
|
||||||
result = anv_cmd_buffer_init_attachments(cmd_buffer, color_att_count);
|
result = anv_cmd_buffer_init_attachments(cmd_buffer, color_att_count);
|
||||||
if (result != VK_SUCCESS)
|
if (result != VK_SUCCESS)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
genX(flush_pipeline_select_3d)(cmd_buffer);
|
genX(flush_pipeline_select_3d)(cmd_buffer);
|
||||||
|
|
||||||
|
UNUSED bool render_target_change = false;
|
||||||
for (uint32_t i = 0; i < gfx->color_att_count; i++) {
|
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;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const VkRenderingAttachmentInfo *att =
|
const VkRenderingAttachmentInfo *att =
|
||||||
&pRenderingInfo->pColorAttachments[i];
|
&pRenderingInfo->pColorAttachments[i];
|
||||||
|
|
@ -5211,6 +5220,13 @@ void genX(CmdBeginRendering)(
|
||||||
att->imageLayout,
|
att->imageLayout,
|
||||||
cmd_buffer->queue_family->queueFlags);
|
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, } };
|
union isl_color_value fast_clear_color = { .u32 = { 0, } };
|
||||||
|
|
||||||
if (att->loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR &&
|
if (att->loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR &&
|
||||||
|
|
@ -5325,11 +5341,6 @@ void genX(CmdBeginRendering)(
|
||||||
assert(att->imageLayout == initial_layout);
|
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;
|
struct isl_view isl_view = iview->planes[0].isl;
|
||||||
if (pRenderingInfo->viewMask) {
|
if (pRenderingInfo->viewMask) {
|
||||||
assert(isl_view.array_len >= util_last_bit(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;
|
gfx->dirty |= ANV_CMD_DIRTY_PIPELINE;
|
||||||
|
|
||||||
#if GFX_VER >= 11
|
#if GFX_VER >= 11
|
||||||
bool has_color_att = false;
|
if (render_target_change) {
|
||||||
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) {
|
|
||||||
/* The PIPE_CONTROL command description says:
|
/* The PIPE_CONTROL command description says:
|
||||||
*
|
*
|
||||||
* "Whenever a Binding Table Index (BTI) used by a Render Target Message
|
* "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
|
#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
|
ALWAYS_INLINE static void
|
||||||
genX(cmd_buffer_flush_gfx_state)(struct anv_cmd_buffer *cmd_buffer)
|
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);
|
genX(flush_pipeline_select_3d)(cmd_buffer);
|
||||||
|
|
||||||
|
if (cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_PIPELINE) {
|
||||||
/* Wa_14015814527
|
/* Wa_14015814527
|
||||||
*
|
*
|
||||||
* Apply task URB workaround when switching from task to primitive.
|
* Apply task URB workaround when switching from task to primitive.
|
||||||
*/
|
*/
|
||||||
if (cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_PIPELINE) {
|
|
||||||
if (anv_pipeline_is_primitive(pipeline)) {
|
if (anv_pipeline_is_primitive(pipeline)) {
|
||||||
genX(apply_task_urb_workaround)(cmd_buffer);
|
genX(apply_task_urb_workaround)(cmd_buffer);
|
||||||
} else if (anv_pipeline_has_stage(pipeline, MESA_SHADER_TASK)) {
|
} else if (anv_pipeline_has_stage(pipeline, MESA_SHADER_TASK)) {
|
||||||
cmd_buffer->state.gfx.used_task_shader = true;
|
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
|
/* Apply any pending pipeline flushes we may have. We want to apply them
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue