mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-25 04:20:08 +01:00
anv/cmd_buffer: Move the color portion of clear_subpass into begin_subpass
This doesn't really change much now but it will give us more/better control over clears in the future. The one interesting functional change here is that we are now re-emitting 3DSTATE_DEPTH_BUFFERS and friends for each clear. However, this only happens at begin_subpass time so it shouldn't be substantially more expensive. Reviewed-by: Nanley Chery <nanley.g.chery@intel.com>
This commit is contained in:
parent
6fb9d6c6f5
commit
1900dd76d0
3 changed files with 94 additions and 92 deletions
|
|
@ -1145,17 +1145,6 @@ subpass_needs_clear(const struct anv_cmd_buffer *cmd_buffer)
|
|||
const struct anv_cmd_state *cmd_state = &cmd_buffer->state;
|
||||
uint32_t ds = cmd_state->subpass->depth_stencil_attachment.attachment;
|
||||
|
||||
for (uint32_t i = 0; i < cmd_state->subpass->color_count; ++i) {
|
||||
uint32_t a = cmd_state->subpass->color_attachments[i].attachment;
|
||||
if (a == VK_ATTACHMENT_UNUSED)
|
||||
continue;
|
||||
|
||||
assert(a < cmd_state->pass->attachment_count);
|
||||
if (cmd_state->attachments[a].pending_clear_aspects) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (ds != VK_ATTACHMENT_UNUSED) {
|
||||
assert(ds < cmd_state->pass->attachment_count);
|
||||
if (cmd_state->attachments[ds].pending_clear_aspects)
|
||||
|
|
@ -1189,86 +1178,6 @@ anv_cmd_buffer_clear_subpass(struct anv_cmd_buffer *cmd_buffer)
|
|||
};
|
||||
|
||||
struct anv_framebuffer *fb = cmd_buffer->state.framebuffer;
|
||||
for (uint32_t i = 0; i < cmd_state->subpass->color_count; ++i) {
|
||||
const uint32_t a = cmd_state->subpass->color_attachments[i].attachment;
|
||||
if (a == VK_ATTACHMENT_UNUSED)
|
||||
continue;
|
||||
|
||||
assert(a < cmd_state->pass->attachment_count);
|
||||
struct anv_attachment_state *att_state = &cmd_state->attachments[a];
|
||||
|
||||
if (!att_state->pending_clear_aspects)
|
||||
continue;
|
||||
|
||||
assert(att_state->pending_clear_aspects == VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
|
||||
struct anv_image_view *iview = fb->attachments[a];
|
||||
const struct anv_image *image = iview->image;
|
||||
struct blorp_surf surf;
|
||||
get_blorp_surf_for_anv_image(cmd_buffer->device,
|
||||
image, VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
att_state->aux_usage, &surf);
|
||||
|
||||
uint32_t base_layer = iview->planes[0].isl.base_array_layer;
|
||||
uint32_t layer_count = fb->layers;
|
||||
|
||||
if (att_state->fast_clear) {
|
||||
surf.clear_color = vk_to_isl_color(att_state->clear_value.color);
|
||||
|
||||
/* From the Sky Lake PRM Vol. 7, "Render Target Fast Clear":
|
||||
*
|
||||
* "After Render target fast clear, pipe-control with color cache
|
||||
* write-flush must be issued before sending any DRAW commands on
|
||||
* that render target."
|
||||
*
|
||||
* This comment is a bit cryptic and doesn't really tell you what's
|
||||
* going or what's really needed. It appears that fast clear ops are
|
||||
* not properly synchronized with other drawing. This means that we
|
||||
* cannot have a fast clear operation in the pipe at the same time as
|
||||
* other regular drawing operations. We need to use a PIPE_CONTROL
|
||||
* to ensure that the contents of the previous draw hit the render
|
||||
* target before we resolve and then use a second PIPE_CONTROL after
|
||||
* the resolve to ensure that it is completed before any additional
|
||||
* drawing occurs.
|
||||
*/
|
||||
cmd_buffer->state.pending_pipe_bits |=
|
||||
ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT | ANV_PIPE_CS_STALL_BIT;
|
||||
|
||||
/* We only support fast-clears on the first layer */
|
||||
assert(iview->planes[0].isl.base_level == 0);
|
||||
assert(iview->planes[0].isl.base_array_layer == 0);
|
||||
|
||||
assert(image->n_planes == 1);
|
||||
blorp_fast_clear(&batch, &surf, iview->planes[0].isl.format, 0, 0, 1,
|
||||
render_area.offset.x, render_area.offset.y,
|
||||
render_area.offset.x + render_area.extent.width,
|
||||
render_area.offset.y + render_area.extent.height);
|
||||
base_layer++;
|
||||
layer_count--;
|
||||
|
||||
cmd_buffer->state.pending_pipe_bits |=
|
||||
ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT | ANV_PIPE_CS_STALL_BIT;
|
||||
}
|
||||
|
||||
if (layer_count > 0) {
|
||||
assert(image->n_planes == 1);
|
||||
anv_cmd_buffer_mark_image_written(cmd_buffer, image,
|
||||
VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
att_state->aux_usage,
|
||||
iview->planes[0].isl.base_level,
|
||||
base_layer, layer_count);
|
||||
|
||||
blorp_clear(&batch, &surf, iview->planes[0].isl.format,
|
||||
anv_swizzle_for_render(iview->planes[0].isl.swizzle),
|
||||
iview->planes[0].isl.base_level, base_layer, layer_count,
|
||||
render_area.offset.x, render_area.offset.y,
|
||||
render_area.offset.x + render_area.extent.width,
|
||||
render_area.offset.y + render_area.extent.height,
|
||||
vk_to_isl_color(att_state->clear_value.color), NULL);
|
||||
}
|
||||
|
||||
att_state->pending_clear_aspects = 0;
|
||||
}
|
||||
|
||||
const uint32_t ds = cmd_state->subpass->depth_stencil_attachment.attachment;
|
||||
assert(ds == VK_ATTACHMENT_UNUSED || ds < cmd_state->pass->attachment_count);
|
||||
|
|
@ -1621,6 +1530,39 @@ anv_image_copy_to_shadow(struct anv_cmd_buffer *cmd_buffer,
|
|||
blorp_batch_finish(&batch);
|
||||
}
|
||||
|
||||
void
|
||||
anv_image_clear_color(struct anv_cmd_buffer *cmd_buffer,
|
||||
const struct anv_image *image,
|
||||
VkImageAspectFlagBits aspect,
|
||||
enum isl_aux_usage aux_usage,
|
||||
enum isl_format format, struct isl_swizzle swizzle,
|
||||
uint32_t level, uint32_t base_layer, uint32_t layer_count,
|
||||
VkRect2D area, union isl_color_value clear_color)
|
||||
{
|
||||
assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
|
||||
/* We don't support planar images with multisampling yet */
|
||||
assert(image->n_planes == 1);
|
||||
|
||||
struct blorp_batch batch;
|
||||
blorp_batch_init(&cmd_buffer->device->blorp, &batch, cmd_buffer, 0);
|
||||
|
||||
struct blorp_surf surf;
|
||||
get_blorp_surf_for_anv_image(cmd_buffer->device, image, aspect,
|
||||
aux_usage, &surf);
|
||||
anv_cmd_buffer_mark_image_written(cmd_buffer, image, aspect, aux_usage,
|
||||
level, base_layer, layer_count);
|
||||
|
||||
blorp_clear(&batch, &surf, format, anv_swizzle_for_render(swizzle),
|
||||
level, base_layer, layer_count,
|
||||
area.offset.x, area.offset.y,
|
||||
area.offset.x + area.extent.width,
|
||||
area.offset.y + area.extent.height,
|
||||
clear_color, NULL);
|
||||
|
||||
blorp_batch_finish(&batch);
|
||||
}
|
||||
|
||||
void
|
||||
anv_image_hiz_op(struct anv_cmd_buffer *cmd_buffer,
|
||||
const struct anv_image *image,
|
||||
|
|
|
|||
|
|
@ -2620,6 +2620,14 @@ anv_cmd_buffer_mark_image_written(struct anv_cmd_buffer *cmd_buffer,
|
|||
uint32_t layer_count);
|
||||
|
||||
void
|
||||
anv_image_clear_color(struct anv_cmd_buffer *cmd_buffer,
|
||||
const struct anv_image *image,
|
||||
VkImageAspectFlagBits aspect,
|
||||
enum isl_aux_usage aux_usage,
|
||||
enum isl_format format, struct isl_swizzle swizzle,
|
||||
uint32_t level, uint32_t base_layer, uint32_t layer_count,
|
||||
VkRect2D area, union isl_color_value clear_color);
|
||||
void
|
||||
anv_image_hiz_op(struct anv_cmd_buffer *cmd_buffer,
|
||||
const struct anv_image *image,
|
||||
VkImageAspectFlagBits aspect, uint32_t level,
|
||||
|
|
|
|||
|
|
@ -3452,7 +3452,9 @@ static void
|
|||
cmd_buffer_begin_subpass(struct anv_cmd_buffer *cmd_buffer,
|
||||
uint32_t subpass_id)
|
||||
{
|
||||
cmd_buffer->state.subpass = &cmd_buffer->state.pass->subpasses[subpass_id];
|
||||
struct anv_cmd_state *cmd_state = &cmd_buffer->state;
|
||||
struct anv_subpass *subpass = &cmd_state->pass->subpasses[subpass_id];
|
||||
cmd_state->subpass = subpass;
|
||||
|
||||
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_RENDER_TARGETS;
|
||||
|
||||
|
|
@ -3495,6 +3497,56 @@ cmd_buffer_begin_subpass(struct anv_cmd_buffer *cmd_buffer,
|
|||
*/
|
||||
cmd_buffer_subpass_sync_fast_clear_values(cmd_buffer);
|
||||
|
||||
VkRect2D render_area = cmd_buffer->state.render_area;
|
||||
struct anv_framebuffer *fb = cmd_buffer->state.framebuffer;
|
||||
for (uint32_t i = 0; i < subpass->color_count; ++i) {
|
||||
const uint32_t a = subpass->color_attachments[i].attachment;
|
||||
if (a == VK_ATTACHMENT_UNUSED)
|
||||
continue;
|
||||
|
||||
assert(a < cmd_state->pass->attachment_count);
|
||||
struct anv_attachment_state *att_state = &cmd_state->attachments[a];
|
||||
|
||||
if (!att_state->pending_clear_aspects)
|
||||
continue;
|
||||
|
||||
assert(att_state->pending_clear_aspects == VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
|
||||
struct anv_image_view *iview = fb->attachments[a];
|
||||
const struct anv_image *image = iview->image;
|
||||
|
||||
/* Multi-planar images are not supported as attachments */
|
||||
assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
assert(image->n_planes == 1);
|
||||
|
||||
uint32_t base_clear_layer = iview->planes[0].isl.base_array_layer;
|
||||
uint32_t clear_layer_count = fb->layers;
|
||||
|
||||
if (att_state->fast_clear) {
|
||||
/* We only support fast-clears on the first layer */
|
||||
assert(iview->planes[0].isl.base_level == 0);
|
||||
assert(iview->planes[0].isl.base_array_layer == 0);
|
||||
|
||||
anv_image_ccs_op(cmd_buffer, image, VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
0, 0, 1, ISL_AUX_OP_FAST_CLEAR, false);
|
||||
base_clear_layer++;
|
||||
clear_layer_count--;
|
||||
}
|
||||
|
||||
if (clear_layer_count > 0) {
|
||||
assert(image->n_planes == 1);
|
||||
anv_image_clear_color(cmd_buffer, image, VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
att_state->aux_usage,
|
||||
iview->planes[0].isl.format,
|
||||
iview->planes[0].isl.swizzle,
|
||||
iview->planes[0].isl.base_level,
|
||||
base_clear_layer, clear_layer_count, render_area,
|
||||
vk_to_isl_color(att_state->clear_value.color));
|
||||
}
|
||||
|
||||
att_state->pending_clear_aspects = 0;
|
||||
}
|
||||
|
||||
cmd_buffer_emit_depth_stencil(cmd_buffer);
|
||||
|
||||
anv_cmd_buffer_clear_subpass(cmd_buffer);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue