Commit 1cd31ea1 by Alexis Hetu Committed by Alexis Hétu

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/23748Tested-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarChris Forbes <chrisforbes@google.com>
parent 238af155
......@@ -36,10 +36,10 @@ public:
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 @@ public:
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 @@ public:
protected:
void play(CommandBuffer::ExecutionState& executionState)
{
Cast(executionState.renderpass)->end();
executionState.renderPass->end();
executionState.renderPass = nullptr;
executionState.renderPassFramebuffer = nullptr;
}
private:
......@@ -93,7 +113,7 @@ public:
protected:
void play(CommandBuffer::ExecutionState& executionState)
{
executionState.pipelines[pipelineBindPoint] = pipeline;
executionState.pipelines[pipelineBindPoint] = Cast(pipeline);
}
private:
......@@ -127,7 +147,7 @@ struct Draw : public CommandBuffer::Command
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 @@ private:
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::beginRenderPass(VkRenderPass renderPass, VkFramebuffer frame
void CommandBuffer::nextSubpass(VkSubpassContents contents)
{
UNIMPLEMENTED();
ASSERT(state == RECORDING);
addCommand<NextSubpass>();
}
void CommandBuffer::endRenderPass()
......@@ -661,7 +700,15 @@ void CommandBuffer::clearDepthStencilImage(VkImage image, VkImageLayout imageLay
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,
......
......@@ -28,6 +28,10 @@ namespace sw
namespace vk
{
class Framebuffer;
class Pipeline;
class RenderPass;
class CommandBuffer
{
public:
......@@ -118,8 +122,9 @@ public:
struct ExecutionState
{
sw::Renderer* renderer = nullptr;
VkRenderPass renderpass = VK_NULL_HANDLE;
VkPipeline pipelines[VK_PIPELINE_BIND_POINT_RANGE_SIZE] = {};
RenderPass* renderPass = nullptr;
Framebuffer* renderPassFramebuffer = nullptr;
Pipeline* pipelines[VK_PIPELINE_BIND_POINT_RANGE_SIZE] = {};
struct VertexInputBinding
{
......
......@@ -14,12 +14,14 @@
#include "VkFramebuffer.hpp"
#include "VkImageView.hpp"
#include "VkRenderPass.hpp"
#include <memory.h>
namespace vk
{
Framebuffer::Framebuffer(const VkFramebufferCreateInfo* pCreateInfo, void* mem) :
renderPass(Cast(pCreateInfo->renderPass)),
attachmentCount(pCreateInfo->attachmentCount),
attachments(reinterpret_cast<ImageView**>(mem))
{
......@@ -44,6 +46,31 @@ void Framebuffer::clear(uint32_t clearValueCount, const VkClearValue* pClearValu
}
}
void Framebuffer::clear(const VkClearAttachment& attachment, const VkClearRect& rect)
{
if(attachment.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT)
{
if(attachment.colorAttachment != VK_ATTACHMENT_UNUSED)
{
VkSubpassDescription subpass = renderPass->getCurrentSubpass();
ASSERT(attachment.colorAttachment < subpass.colorAttachmentCount);
ASSERT(subpass.pColorAttachments[attachment.colorAttachment].attachment < attachmentCount);
attachments[subpass.pColorAttachments[attachment.colorAttachment].attachment]->clear(
attachment.clearValue, attachment.aspectMask, rect);
}
}
else if(attachment.aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))
{
VkSubpassDescription subpass = renderPass->getCurrentSubpass();
ASSERT(subpass.pDepthStencilAttachment->attachment < attachmentCount);
attachments[subpass.pDepthStencilAttachment->attachment]->clear(attachment.clearValue, attachment.aspectMask, rect);
}
}
size_t Framebuffer::ComputeRequiredAllocationSize(const VkFramebufferCreateInfo* pCreateInfo)
{
return pCreateInfo->attachmentCount * sizeof(void*);
......
......@@ -21,6 +21,7 @@ namespace vk
{
class ImageView;
class RenderPass;
class Framebuffer : public Object<Framebuffer, VkFramebuffer>
{
......@@ -30,10 +31,12 @@ public:
void destroy(const VkAllocationCallbacks* pAllocator);
void clear(uint32_t clearValueCount, const VkClearValue* pClearValues, const VkRect2D& renderArea);
void clear(const VkClearAttachment& attachment, const VkClearRect& rect);
static size_t ComputeRequiredAllocationSize(const VkFramebufferCreateInfo* pCreateInfo);
private:
RenderPass* renderPass;
uint32_t attachmentCount = 0;
ImageView** attachments = nullptr;
};
......
......@@ -89,4 +89,28 @@ void ImageView::clear(const VkClearValue& clearValue, const VkRect2D& renderArea
image->clear(clearValue, renderArea, subresourceRange);
}
void ImageView::clear(const VkClearValue& clearValue, const VkImageAspectFlags aspectMask, const VkClearRect& renderArea)
{
// Note: clearing ignores swizzling, so components is ignored.
if(!imageTypesMatch(image->getImageType()))
{
UNIMPLEMENTED();
}
if(image->getFormat() != format)
{
UNIMPLEMENTED();
}
VkImageSubresourceRange sr;
sr.aspectMask = aspectMask;
sr.baseMipLevel = subresourceRange.baseMipLevel;
sr.levelCount = subresourceRange.levelCount;
sr.baseArrayLayer = renderArea.baseArrayLayer + subresourceRange.baseArrayLayer;
sr.layerCount = renderArea.layerCount;
image->clear(clearValue, renderArea.rect, sr);
}
}
\ No newline at end of file
......@@ -32,6 +32,7 @@ public:
static size_t ComputeRequiredAllocationSize(const VkImageViewCreateInfo* pCreateInfo);
void clear(const VkClearValue& clearValues, const VkRect2D& renderArea);
void clear(const VkClearValue& clearValue, const VkImageAspectFlags aspectMask, const VkClearRect& renderArea);
private:
bool imageTypesMatch(VkImageType imageType) const;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment