Support render area instead of extent in Renderer::draw() Some Vulkan 1.3 features related to dynamic rendering expect the render area to support an offset, as opposed to only requiring a width and height, so this CL adds support for a render area in Renderer::draw(). Note: This may be related to b/177842474, but since we're missing test coverage for it, we can't test it yet, but this CL might be a step in the right direction. Bug: b/204502119 Bug: b/177842474 Change-Id: I6d27f353279ef6d46f86c8c65c8e0d1fa76ff927 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/62970 Tested-by: Alexis Hétu <sugoi@google.com> Reviewed-by: Nicolas Capens <nicolascapens@google.com> Commit-Queue: Alexis Hétu <sugoi@google.com> Kokoro-Result: kokoro <noreply+kokoro@google.com>
diff --git a/src/Device/Renderer.cpp b/src/Device/Renderer.cpp index 1fa8b8c..2b13deb 100644 --- a/src/Device/Renderer.cpp +++ b/src/Device/Renderer.cpp
@@ -181,7 +181,7 @@ } void Renderer::draw(const vk::GraphicsPipeline *pipeline, const vk::DynamicState &dynamicState, unsigned int count, int baseVertex, - CountedEvent *events, int instanceID, int viewID, void *indexBuffer, const VkExtent3D &framebufferExtent, + CountedEvent *events, int instanceID, int viewID, void *indexBuffer, const VkRect2D &renderArea, vk::Pipeline::PushConstantStorage const &pushConstants, bool update) { if(count == 0) { return; } @@ -413,10 +413,14 @@ { const VkRect2D &scissor = pipelineState.getScissor(); - data->scissorX0 = clamp<int>(scissor.offset.x, 0, framebufferExtent.width); - data->scissorX1 = clamp<int>(scissor.offset.x + scissor.extent.width, 0, framebufferExtent.width); - data->scissorY0 = clamp<int>(scissor.offset.y, 0, framebufferExtent.height); - data->scissorY1 = clamp<int>(scissor.offset.y + scissor.extent.height, 0, framebufferExtent.height); + int x0 = renderArea.offset.x; + int y0 = renderArea.offset.y; + int x1 = x0 + renderArea.extent.width; + int y1 = y0 + renderArea.extent.height; + data->scissorX0 = clamp<int>(scissor.offset.x, x0, x1); + data->scissorX1 = clamp<int>(scissor.offset.x + scissor.extent.width, x0, x1); + data->scissorY0 = clamp<int>(scissor.offset.y, y0, y1); + data->scissorY1 = clamp<int>(scissor.offset.y + scissor.extent.height, y0, y1); } // Push constants
diff --git a/src/Device/Renderer.hpp b/src/Device/Renderer.hpp index be0bb94..610c592 100644 --- a/src/Device/Renderer.hpp +++ b/src/Device/Renderer.hpp
@@ -206,7 +206,7 @@ bool hasOcclusionQuery() const { return occlusionQuery != nullptr; } void draw(const vk::GraphicsPipeline *pipeline, const vk::DynamicState &dynamicState, unsigned int count, int baseVertex, - CountedEvent *events, int instanceID, int viewID, void *indexBuffer, const VkExtent3D &framebufferExtent, + CountedEvent *events, int instanceID, int viewID, void *indexBuffer, const VkRect2D &renderArea, vk::Pipeline::PushConstantStorage const &pushConstants, bool update = true); void addQuery(vk::Query *query);
diff --git a/src/Vulkan/VkCommandBuffer.cpp b/src/Vulkan/VkCommandBuffer.cpp index a890b06..93f7ab3 100644 --- a/src/Vulkan/VkCommandBuffer.cpp +++ b/src/Vulkan/VkCommandBuffer.cpp
@@ -787,6 +787,8 @@ std::vector<std::pair<uint32_t, void *>> indexBuffers; pipeline->getIndexBuffers(executionState.dynamicState, count, first, indexed, &indexBuffers); + VkRect2D renderArea = executionState.getRenderArea(); + for(uint32_t instance = firstInstance; instance != firstInstance + instanceCount; instance++) { // FIXME: reconsider instances/views nesting. @@ -800,8 +802,7 @@ { executionState.renderer->draw(pipeline, executionState.dynamicState, indexBuffer.first, vertexOffset, executionState.events, instance, viewID, indexBuffer.second, - executionState.renderPassFramebuffer->getExtent(), - executionState.pushConstants); + renderArea, executionState.pushConstants); } } @@ -2161,6 +2162,18 @@ } } +VkRect2D CommandBuffer::ExecutionState::getRenderArea() const +{ + VkRect2D renderArea = {}; + + if(renderPassFramebuffer) + { + renderArea.extent = renderPassFramebuffer->getExtent(); + } + + return renderArea; +} + // Returns the number of bits set in the view mask, or 1 if multiview is disabled. uint32_t CommandBuffer::ExecutionState::viewCount() const {
diff --git a/src/Vulkan/VkCommandBuffer.hpp b/src/Vulkan/VkCommandBuffer.hpp index f66d38c..28699ff 100644 --- a/src/Vulkan/VkCommandBuffer.hpp +++ b/src/Vulkan/VkCommandBuffer.hpp
@@ -173,6 +173,7 @@ void bindAttachments(Attachments *attachments); + VkRect2D getRenderArea() const; uint32_t viewCount() const; };
diff --git a/src/Vulkan/VkFramebuffer.cpp b/src/Vulkan/VkFramebuffer.cpp index 77eb295..4d34cc2 100644 --- a/src/Vulkan/VkFramebuffer.cpp +++ b/src/Vulkan/VkFramebuffer.cpp
@@ -25,7 +25,7 @@ Framebuffer::Framebuffer(const VkFramebufferCreateInfo *pCreateInfo, void *mem) : attachments(reinterpret_cast<ImageView **>(mem)) - , extent{ pCreateInfo->width, pCreateInfo->height, pCreateInfo->layers } + , extent{ pCreateInfo->width, pCreateInfo->height } { const VkBaseInStructure *curInfo = reinterpret_cast<const VkBaseInStructure *>(pCreateInfo->pNext); const VkFramebufferAttachmentsCreateInfo *attachmentsCreateInfo = nullptr;
diff --git a/src/Vulkan/VkFramebuffer.hpp b/src/Vulkan/VkFramebuffer.hpp index 63c02f7..51a8406 100644 --- a/src/Vulkan/VkFramebuffer.hpp +++ b/src/Vulkan/VkFramebuffer.hpp
@@ -36,12 +36,12 @@ ImageView *getAttachment(uint32_t index) const; void resolve(const RenderPass *renderPass, uint32_t subpassIndex); - const VkExtent3D &getExtent() const { return extent; } + const VkExtent2D &getExtent() const { return extent; } private: uint32_t attachmentCount = 0; ImageView **attachments = nullptr; - const VkExtent3D extent = {}; + const VkExtent2D extent = {}; }; static inline Framebuffer *Cast(VkFramebuffer object)