Mesa (master): tu: Detect invalid-for-binning renderpass dependencies
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Fri Jul 24 18:58:59 UTC 2020
Module: Mesa
Branch: master
Commit: f7f29a04b48393b44d08d94afe0d4dab3ba75335
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=f7f29a04b48393b44d08d94afe0d4dab3ba75335
Author: Connor Abbott <cwabbott0 at gmail.com>
Date: Fri Jul 3 18:41:42 2020 +0200
tu: Detect invalid-for-binning renderpass dependencies
This is all that was missing for stores & atomics.
Closes: #3196
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5738>
---
src/freedreno/vulkan/tu_pass.c | 53 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 53 insertions(+)
diff --git a/src/freedreno/vulkan/tu_pass.c b/src/freedreno/vulkan/tu_pass.c
index 4b1ec4c80b6..af5a190f80a 100644
--- a/src/freedreno/vulkan/tu_pass.c
+++ b/src/freedreno/vulkan/tu_pass.c
@@ -29,6 +29,56 @@
#include "vk_util.h"
#include "vk_format.h"
+/* Return true if we have to fallback to sysmem rendering because the
+ * dependency can't be satisfied with tiled rendering.
+ */
+
+static bool
+dep_invalid_for_gmem(const VkSubpassDependency2 *dep)
+{
+ /* External dependencies don't matter here. */
+ if (dep->srcSubpass == VK_SUBPASS_EXTERNAL ||
+ dep->dstSubpass == VK_SUBPASS_EXTERNAL)
+ return false;
+
+ /* We can conceptually break down the process of rewriting a sysmem
+ * renderpass into a gmem one into two parts:
+ *
+ * 1. Split each draw and multisample resolve into N copies, one for each
+ * bin. (If hardware binning, add one more copy where the FS is disabled
+ * for the binning pass). This is always allowed because the vertex stage
+ * is allowed to run an arbitrary number of times and there are no extra
+ * ordering constraints within a draw.
+ * 2. Take the last copy of the second-to-last draw and slide it down to
+ * before the last copy of the last draw. Repeat for each earlier draw
+ * until the draw pass for the last bin is complete, then repeat for each
+ * earlier bin until we finish with the first bin.
+ *
+ * During this rearranging process, we can't slide draws past each other in
+ * a way that breaks the subpass dependencies. For each draw, we must slide
+ * it past (copies of) the rest of the draws in the renderpass. We can
+ * slide a draw past another if there isn't a dependency between them, or
+ * if the dependenc(ies) are dependencies between framebuffer-space stages
+ * only with the BY_REGION bit set. Note that this includes
+ * self-dependencies, since these may result in pipeline barriers that also
+ * break the rearranging process.
+ */
+
+ /* This is straight from the Vulkan 1.2 spec, section 6.1.4 "Framebuffer
+ * Region Dependencies":
+ */
+ const VkPipelineStageFlags framebuffer_space_stages =
+ VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
+ VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
+ VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT |
+ VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
+
+ return
+ (dep->srcStageMask & ~framebuffer_space_stages) ||
+ (dep->dstStageMask & ~framebuffer_space_stages) ||
+ !(dep->dependencyFlags & VK_DEPENDENCY_BY_REGION_BIT);
+}
+
static void
tu_render_pass_add_subpass_dep(struct tu_render_pass *pass,
const VkSubpassDependency2 *dep)
@@ -36,6 +86,9 @@ tu_render_pass_add_subpass_dep(struct tu_render_pass *pass,
uint32_t src = dep->srcSubpass;
uint32_t dst = dep->dstSubpass;
+ if (dep_invalid_for_gmem(dep))
+ pass->gmem_pixels = 0;
+
/* Ignore subpass self-dependencies as they allow the app to call
* vkCmdPipelineBarrier() inside the render pass and the driver should only
* do the barrier when called, not when starting the render pass.
More information about the mesa-commit
mailing list