Add support for multiview rendering This is a mandatory feature for 1.1, but Vulkan CTS 1.1.3 doesn't enforce that -- it only tests the feature if it is present. Highlights: - Multiple views implemented by running each draw multiple times. We could do something more efficient, but this is a fringe feature so far. - Render targets and input attachments are adjusted to use the layer corresponding to the current view. - Explicit attachment clears and end-of-subpass resolves are broadcast to the layers corresponding to the current subpass's view mask. - Renderpass attachment load ops are executed for the layers corresponding to the union of the subpass view masks for all subpasses which use the attachment. The actual load ops are still performed together at the beginning of the renderpass. - ViewIndex builtin variable is exposed to the shaders. In a non-multiview draw call, ViewIndex is still available, but is always zero. Bug: b/139862810 Test: dEQP-VK.*multiview* Change-Id: Iaf40cfdb2f5afa61253cc756f97c0db30fb4d813 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/35408 Kokoro-Presubmit: kokoro <noreply+kokoro@google.com> Reviewed-by: Nicolas Capens <nicolascapens@google.com> Tested-by: Chris Forbes <chrisforbes@google.com>
diff --git a/src/Vulkan/VkRenderPass.hpp b/src/Vulkan/VkRenderPass.hpp index 0fe9e22..2d0841f 100644 --- a/src/Vulkan/VkRenderPass.hpp +++ b/src/Vulkan/VkRenderPass.hpp
@@ -76,6 +76,21 @@ return attachmentFirstUse[i] >= 0; } + uint32_t getViewMask() const + { + return viewMasks ? viewMasks[currentSubpass] : 1; + } + + bool isMultiView() const + { + return viewMasks != nullptr; + } + + uint32_t getAttachmentViewMask(uint32_t i) const + { + return attachmentViewMasks[i]; + } + private: uint32_t attachmentCount = 0; VkAttachmentDescription* attachments = nullptr; @@ -85,6 +100,10 @@ VkSubpassDependency* dependencies = nullptr; uint32_t currentSubpass = 0; int* attachmentFirstUse = nullptr; + uint32_t* viewMasks = nullptr; + uint32_t* attachmentViewMasks = nullptr; + + void MarkFirstUse(int attachment, int subpass); }; static inline RenderPass* Cast(VkRenderPass object)