anv: Do resolves at end of subpass
This commit is contained in:
@@ -802,3 +802,64 @@ void anv_CmdResolveImage(
|
||||
|
||||
meta_resolve_restore(&state, cmd_buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Emit any needed resolves for the current subpass.
|
||||
*/
|
||||
void
|
||||
anv_cmd_buffer_resolve_subpass(struct anv_cmd_buffer *cmd_buffer)
|
||||
{
|
||||
struct anv_framebuffer *fb = cmd_buffer->state.framebuffer;
|
||||
struct anv_subpass *subpass = cmd_buffer->state.subpass;
|
||||
struct anv_meta_saved_state saved_state;
|
||||
|
||||
/* FINISHME(perf): Skip clears for resolve attachments.
|
||||
*
|
||||
* From the Vulkan 1.0 spec:
|
||||
*
|
||||
* If the first use of an attachment in a render pass is as a resolve
|
||||
* attachment, then the loadOp is effectively ignored as the resolve is
|
||||
* guaranteed to overwrite all pixels in the render area.
|
||||
*/
|
||||
|
||||
if (!subpass->has_resolve)
|
||||
return;
|
||||
|
||||
meta_resolve_save(&saved_state, cmd_buffer);
|
||||
|
||||
for (uint32_t i = 0; i < subpass->color_count; ++i) {
|
||||
uint32_t src_att = subpass->color_attachments[i];
|
||||
uint32_t dest_att = subpass->resolve_attachments[i];
|
||||
|
||||
if (dest_att == VK_ATTACHMENT_UNUSED)
|
||||
continue;
|
||||
|
||||
struct anv_image_view *src_iview = fb->attachments[src_att];
|
||||
struct anv_image_view *dest_iview = fb->attachments[dest_att];
|
||||
|
||||
struct anv_subpass resolve_subpass = {
|
||||
.color_count = 1,
|
||||
.color_attachments = (uint32_t[]) { dest_att },
|
||||
.depth_stencil_attachment = VK_ATTACHMENT_UNUSED,
|
||||
};
|
||||
|
||||
anv_cmd_buffer_set_subpass(cmd_buffer, &resolve_subpass);
|
||||
|
||||
/* Subpass resolves must respect the render area. We can ignore the
|
||||
* render area here because vkCmdBeginRenderPass set the render area
|
||||
* with 3DSTATE_DRAWING_RECTANGLE.
|
||||
*
|
||||
* XXX(chadv): Does the hardware really respect
|
||||
* 3DSTATE_DRAWING_RECTANGLE when draing a 3DPRIM_RECTLIST?
|
||||
*/
|
||||
emit_resolve(cmd_buffer,
|
||||
src_iview,
|
||||
&(VkOffset2D) { 0, 0 },
|
||||
dest_iview,
|
||||
&(VkOffset2D) { 0, 0 },
|
||||
&(VkExtent2D) { fb->width, fb->height });
|
||||
}
|
||||
|
||||
cmd_buffer->state.subpass = subpass;
|
||||
meta_resolve_restore(&saved_state, cmd_buffer);
|
||||
}
|
||||
|
||||
@@ -1277,6 +1277,7 @@ struct anv_state
|
||||
anv_cmd_buffer_cs_push_constants(struct anv_cmd_buffer *cmd_buffer);
|
||||
|
||||
void anv_cmd_buffer_clear_subpass(struct anv_cmd_buffer *cmd_buffer);
|
||||
void anv_cmd_buffer_resolve_subpass(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);
|
||||
|
||||
@@ -896,6 +896,7 @@ void genX(CmdNextSubpass)(
|
||||
|
||||
assert(cmd_buffer->level == VK_COMMAND_BUFFER_LEVEL_PRIMARY);
|
||||
|
||||
anv_cmd_buffer_resolve_subpass(cmd_buffer);
|
||||
gen7_cmd_buffer_set_subpass(cmd_buffer, cmd_buffer->state.subpass + 1);
|
||||
anv_cmd_buffer_clear_subpass(cmd_buffer);
|
||||
}
|
||||
@@ -905,6 +906,8 @@ void genX(CmdEndRenderPass)(
|
||||
{
|
||||
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
|
||||
|
||||
anv_cmd_buffer_resolve_subpass(cmd_buffer);
|
||||
|
||||
/* Emit a flushing pipe control at the end of a pass. This is kind of a
|
||||
* hack but it ensures that render targets always actually get written.
|
||||
* Eventually, we should do flushing based on image format transitions
|
||||
|
||||
@@ -972,6 +972,7 @@ void genX(CmdNextSubpass)(
|
||||
|
||||
assert(cmd_buffer->level == VK_COMMAND_BUFFER_LEVEL_PRIMARY);
|
||||
|
||||
anv_cmd_buffer_resolve_subpass(cmd_buffer);
|
||||
genX(cmd_buffer_set_subpass)(cmd_buffer, cmd_buffer->state.subpass + 1);
|
||||
anv_cmd_buffer_clear_subpass(cmd_buffer);
|
||||
}
|
||||
@@ -981,6 +982,8 @@ void genX(CmdEndRenderPass)(
|
||||
{
|
||||
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
|
||||
|
||||
anv_cmd_buffer_resolve_subpass(cmd_buffer);
|
||||
|
||||
/* Emit a flushing pipe control at the end of a pass. This is kind of a
|
||||
* hack but it ensures that render targets always actually get written.
|
||||
* Eventually, we should do flushing based on image format transitions
|
||||
|
||||
Reference in New Issue
Block a user