summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChad Versace <[email protected]>2016-01-27 20:42:54 -0800
committerChad Versace <[email protected]>2016-01-28 10:49:50 -0800
commitf8a4abcd15d9e27afd6be12c67bec7ccaf179e54 (patch)
treef2fd612c3f1e17f2d526021408565c81c7c1d47c
parentbef8456ede5815598fef48215d2e7d1e3c98dc29 (diff)
anv: Do resolves at end of subpass
-rw-r--r--src/vulkan/anv_meta_resolve.c61
-rw-r--r--src/vulkan/anv_private.h1
-rw-r--r--src/vulkan/gen7_cmd_buffer.c3
-rw-r--r--src/vulkan/gen8_cmd_buffer.c3
4 files changed, 68 insertions, 0 deletions
diff --git a/src/vulkan/anv_meta_resolve.c b/src/vulkan/anv_meta_resolve.c
index 9969a0e5d88..ffd41857f13 100644
--- a/src/vulkan/anv_meta_resolve.c
+++ b/src/vulkan/anv_meta_resolve.c
@@ -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);
+}
diff --git a/src/vulkan/anv_private.h b/src/vulkan/anv_private.h
index 6a670190ab9..b1d4577f93e 100644
--- a/src/vulkan/anv_private.h
+++ b/src/vulkan/anv_private.h
@@ -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);
diff --git a/src/vulkan/gen7_cmd_buffer.c b/src/vulkan/gen7_cmd_buffer.c
index f201c151acb..609606bdf6a 100644
--- a/src/vulkan/gen7_cmd_buffer.c
+++ b/src/vulkan/gen7_cmd_buffer.c
@@ -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
diff --git a/src/vulkan/gen8_cmd_buffer.c b/src/vulkan/gen8_cmd_buffer.c
index daa049e98e0..4b1c51a8c59 100644
--- a/src/vulkan/gen8_cmd_buffer.c
+++ b/src/vulkan/gen8_cmd_buffer.c
@@ -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