anv/meta: Use anv_cmd_state::attachments for clears

Rewrite anv_cmd_buffer_clear_attachments, which emits the top-of-pass
clears, to use the data provided in anv_cmd_state::attachments. This
prepares for deferring each attachment clear to the first subpass that
uses the attachment.
This commit is contained in:
Chad Versace 2016-01-13 11:52:23 -08:00
parent a4b045ca44
commit 356f952f87
4 changed files with 46 additions and 58 deletions

View file

@ -642,69 +642,62 @@ anv_device_finish_meta_clear_state(struct anv_device *device)
NULL);
}
void
anv_cmd_buffer_clear_attachments(struct anv_cmd_buffer *cmd_buffer,
struct anv_render_pass *pass,
const VkClearValue *clear_values)
/**
* At least one aspect must be specified.
*/
static void
emit_clear(struct anv_cmd_buffer *cmd_buffer,
uint32_t attachment,
VkImageAspectFlags aspects,
const VkClearValue *value)
{
struct anv_meta_saved_state saved_state;
if (aspects & VK_IMAGE_ASPECT_COLOR_BIT) {
emit_load_color_clear(cmd_buffer, attachment, value->color);
} else {
assert(aspects & (VK_IMAGE_ASPECT_DEPTH_BIT |
VK_IMAGE_ASPECT_STENCIL_BIT));
emit_load_depthstencil_clear(cmd_buffer, attachment, aspects,
value->depthStencil);
}
}
/* Figure out whether or not we actually need to clear anything to avoid
* trashing state when clearing is a no-op.
*/
bool needs_clear = false;
for (uint32_t a = 0; a < pass->attachment_count; ++a) {
struct anv_render_pass_attachment *att = &pass->attachments[a];
static bool
pass_needs_clear(const struct anv_cmd_buffer *cmd_buffer)
{
const struct anv_cmd_state *cmd_state = &cmd_buffer->state;
if (anv_format_is_color(att->format)) {
if (att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
needs_clear = true;
break;
}
} else {
if ((att->format->depth_format &&
att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) ||
(att->format->has_stencil &&
att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR)) {
needs_clear = true;
break;
}
for (uint32_t i = 0; i < cmd_state->pass->attachment_count; ++i) {
if (cmd_state->attachments[i].pending_clear_aspects) {
return true;
}
}
if (!needs_clear)
return false;
}
void
anv_cmd_buffer_clear_attachments(struct anv_cmd_buffer *cmd_buffer)
{
struct anv_cmd_state *cmd_state = &cmd_buffer->state;
struct anv_meta_saved_state saved_state;
if (!pass_needs_clear(cmd_buffer))
return;
meta_clear_begin(&saved_state, cmd_buffer);
if (cmd_buffer->state.framebuffer->layers > 1)
if (cmd_state->framebuffer->layers > 1)
anv_finishme("clearing multi-layer framebuffer");
for (uint32_t a = 0; a < pass->attachment_count; ++a) {
struct anv_render_pass_attachment *att = &pass->attachments[a];
for (uint32_t a = 0; a < cmd_state->pass->attachment_count; ++a) {
if (!cmd_state->attachments[a].pending_clear_aspects)
continue;
if (anv_format_is_color(att->format)) {
if (att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
emit_load_color_clear(cmd_buffer, a, clear_values[a].color);
}
} else {
VkImageAspectFlags clear_aspects = 0;
emit_clear(cmd_buffer, a,
cmd_state->attachments[a].pending_clear_aspects,
&cmd_state->attachments[a].clear_value);
if (att->format->depth_format &&
att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
clear_aspects |= VK_IMAGE_ASPECT_DEPTH_BIT;
}
if (att->format->has_stencil &&
att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
clear_aspects |= VK_IMAGE_ASPECT_STENCIL_BIT;
}
if (clear_aspects) {
emit_load_depthstencil_clear(cmd_buffer, a, clear_aspects,
clear_values[a].depthStencil);
}
}
cmd_state->attachments[a].pending_clear_aspects = 0;
}
meta_clear_end(&saved_state, cmd_buffer);

View file

@ -1249,9 +1249,8 @@ anv_cmd_buffer_push_constants(struct anv_cmd_buffer *cmd_buffer,
struct anv_state
anv_cmd_buffer_cs_push_constants(struct anv_cmd_buffer *cmd_buffer);
void anv_cmd_buffer_clear_attachments(struct anv_cmd_buffer *cmd_buffer,
struct anv_render_pass *pass,
const VkClearValue *clear_values);
void anv_cmd_buffer_clear_attachments(struct anv_cmd_buffer *cmd_buffer);
const struct anv_image_view *
anv_cmd_buffer_get_depth_stencil_view(const struct anv_cmd_buffer *cmd_buffer);

View file

@ -830,9 +830,7 @@ void genX(CmdBeginRenderPass)(
.DrawingRectangleOriginY = 0,
.DrawingRectangleOriginX = 0);
anv_cmd_buffer_clear_attachments(cmd_buffer, pass,
pRenderPassBegin->pClearValues);
anv_cmd_buffer_clear_attachments(cmd_buffer);
gen7_cmd_buffer_begin_subpass(cmd_buffer, pass->subpasses);
}

View file

@ -829,9 +829,7 @@ void genX(CmdBeginRenderPass)(
.DrawingRectangleOriginY = 0,
.DrawingRectangleOriginX = 0);
anv_cmd_buffer_clear_attachments(cmd_buffer, pass,
pRenderPassBegin->pClearValues);
anv_cmd_buffer_clear_attachments(cmd_buffer);
genX(cmd_buffer_begin_subpass)(cmd_buffer, pass->subpasses);
}