Support for clearing Framebuffer attachments
This is the implementation for vkCmdClearAttachments.
It includes the new command along with the plumbing to
get the information to the Image clear function.
The only non trivial behavior here is that the provided
baseArrayLayer for the clear command is to be offset by
the ImageView's subresourceRange's baseArrayLayer so
that it clears the correct layers.
Bug b/119621736
Passes all tests in:
api.image_clearing.dedicated_allocation.clear_color_attachment.*
Change-Id: I19f86b63239ca2fb4d53f2c6c9cb75185794f061
Reviewed-on: https://swiftshader-review.googlesource.com/c/23748
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Chris Forbes <chrisforbes@google.com>
diff --git a/src/Vulkan/VkCommandBuffer.cpp b/src/Vulkan/VkCommandBuffer.cpp
index b4ece01..59f77fc 100644
--- a/src/Vulkan/VkCommandBuffer.cpp
+++ b/src/Vulkan/VkCommandBuffer.cpp
@@ -36,10 +36,10 @@
class BeginRenderPass : public CommandBuffer::Command
{
public:
- BeginRenderPass(VkRenderPass pRenderPass, VkFramebuffer pFramebuffer, VkRect2D pRenderArea,
- uint32_t pClearValueCount, const VkClearValue* pClearValues) :
- renderPass(pRenderPass), framebuffer(pFramebuffer), renderArea(pRenderArea),
- clearValueCount(pClearValueCount)
+ BeginRenderPass(VkRenderPass renderPass, VkFramebuffer framebuffer, VkRect2D renderArea,
+ uint32_t clearValueCount, const VkClearValue* pClearValues) :
+ renderPass(Cast(renderPass)), framebuffer(Cast(framebuffer)), renderArea(renderArea),
+ clearValueCount(clearValueCount)
{
// FIXME (b/119409619): use an allocator here so we can control all memory allocations
clearValues = new VkClearValue[clearValueCount];
@@ -54,18 +54,36 @@
protected:
void play(CommandBuffer::ExecutionState& executionState)
{
- Cast(renderPass)->begin();
- Cast(framebuffer)->clear(clearValueCount, clearValues, renderArea);
+ executionState.renderPass = renderPass;
+ executionState.renderPassFramebuffer = framebuffer;
+ renderPass->begin();
+ framebuffer->clear(clearValueCount, clearValues, renderArea);
}
private:
- VkRenderPass renderPass;
- VkFramebuffer framebuffer;
+ RenderPass* renderPass;
+ Framebuffer* framebuffer;
VkRect2D renderArea;
uint32_t clearValueCount;
VkClearValue* clearValues;
};
+class NextSubpass : public CommandBuffer::Command
+{
+public:
+ NextSubpass()
+ {
+ }
+
+protected:
+ void play(CommandBuffer::ExecutionState& executionState)
+ {
+ executionState.renderPass->nextSubpass();
+ }
+
+private:
+};
+
class EndRenderPass : public CommandBuffer::Command
{
public:
@@ -76,7 +94,9 @@
protected:
void play(CommandBuffer::ExecutionState& executionState)
{
- Cast(executionState.renderpass)->end();
+ executionState.renderPass->end();
+ executionState.renderPass = nullptr;
+ executionState.renderPassFramebuffer = nullptr;
}
private:
@@ -93,7 +113,7 @@
protected:
void play(CommandBuffer::ExecutionState& executionState)
{
- executionState.pipelines[pipelineBindPoint] = pipeline;
+ executionState.pipelines[pipelineBindPoint] = Cast(pipeline);
}
private:
@@ -127,7 +147,7 @@
void play(CommandBuffer::ExecutionState& executionState)
{
GraphicsPipeline* pipeline = static_cast<GraphicsPipeline*>(
- Cast(executionState.pipelines[VK_PIPELINE_BIND_POINT_GRAPHICS]));
+ executionState.pipelines[VK_PIPELINE_BIND_POINT_GRAPHICS]);
sw::Context context = pipeline->getContext();
for(uint32_t i = 0; i < MAX_VERTEX_INPUT_BINDINGS; i++)
@@ -256,6 +276,23 @@
const VkImageSubresourceRange range;
};
+struct ClearAttachment : public CommandBuffer::Command
+{
+ ClearAttachment(const VkClearAttachment& attachment, const VkClearRect& rect) :
+ attachment(attachment), rect(rect)
+ {
+ }
+
+ void play(CommandBuffer::ExecutionState& executionState)
+ {
+ executionState.renderPassFramebuffer->clear(attachment, rect);
+ }
+
+private:
+ const VkClearAttachment attachment;
+ const VkClearRect rect;
+};
+
struct BlitImage : public CommandBuffer::Command
{
BlitImage(VkImage srcImage, VkImage dstImage, const VkImageBlit& region, VkFilter filter) :
@@ -374,7 +411,9 @@
void CommandBuffer::nextSubpass(VkSubpassContents contents)
{
- UNIMPLEMENTED();
+ ASSERT(state == RECORDING);
+
+ addCommand<NextSubpass>();
}
void CommandBuffer::endRenderPass()
@@ -661,7 +700,15 @@
void CommandBuffer::clearAttachments(uint32_t attachmentCount, const VkClearAttachment* pAttachments,
uint32_t rectCount, const VkClearRect* pRects)
{
- UNIMPLEMENTED();
+ ASSERT(state == RECORDING);
+
+ for(uint32_t i = 0; i < attachmentCount; i++)
+ {
+ for(uint32_t j = 0; j < rectCount; j++)
+ {
+ addCommand<ClearAttachment>(pAttachments[i], pRects[j]);
+ }
+ }
}
void CommandBuffer::resolveImage(VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout,