Commit 65b1e97d by Chris Forbes

Only perform attachment load/store ops for used attachments

Tracks the first subpass to touch an attachment. Test: dEQP-VK.renderpass.suballocation.unused* Change-Id: Idc0998da022fd4c0b1785f6020c795916ba475f7 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/31308Tested-by: 's avatarChris Forbes <chrisforbes@google.com> Presubmit-Ready: Chris Forbes <chrisforbes@google.com> Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com>
parent 628604ee
...@@ -43,6 +43,11 @@ void Framebuffer::clear(const RenderPass* renderPass, uint32_t clearValueCount, ...@@ -43,6 +43,11 @@ void Framebuffer::clear(const RenderPass* renderPass, uint32_t clearValueCount,
const uint32_t count = std::min(clearValueCount, attachmentCount); const uint32_t count = std::min(clearValueCount, attachmentCount);
for(uint32_t i = 0; i < count; i++) for(uint32_t i = 0; i < count; i++)
{ {
if (!renderPass->isAttachmentUsed(i))
{
continue;
}
const VkAttachmentDescription attachment = renderPass->getAttachment(i); const VkAttachmentDescription attachment = renderPass->getAttachment(i);
const Format format(attachment.format); const Format format(attachment.format);
bool isDepth = format.isDepth(); bool isDepth = format.isDepth();
......
...@@ -15,6 +15,15 @@ ...@@ -15,6 +15,15 @@
#include "VkRenderPass.hpp" #include "VkRenderPass.hpp"
#include <cstring> #include <cstring>
namespace
{
void MarkFirstUse(int& attachment, int subpass)
{
if (attachment == -1)
attachment = subpass;
}
}
namespace vk namespace vk
{ {
...@@ -39,6 +48,12 @@ RenderPass::RenderPass(const VkRenderPassCreateInfo* pCreateInfo, void* mem) : ...@@ -39,6 +48,12 @@ RenderPass::RenderPass(const VkRenderPassCreateInfo* pCreateInfo, void* mem) :
attachments = reinterpret_cast<VkAttachmentDescription*>(hostMemory); attachments = reinterpret_cast<VkAttachmentDescription*>(hostMemory);
memcpy(attachments, pCreateInfo->pAttachments, attachmentSize); memcpy(attachments, pCreateInfo->pAttachments, attachmentSize);
hostMemory += attachmentSize; hostMemory += attachmentSize;
size_t firstUseSize = pCreateInfo->attachmentCount * sizeof(int);
attachmentFirstUse = reinterpret_cast<int*>(hostMemory);
for (auto i = 0u; i < pCreateInfo->attachmentCount; i++)
attachmentFirstUse[i] = -1;
hostMemory += firstUseSize;
} }
// Deep copy subpasses // Deep copy subpasses
...@@ -58,6 +73,12 @@ RenderPass::RenderPass(const VkRenderPassCreateInfo* pCreateInfo, void* mem) : ...@@ -58,6 +73,12 @@ RenderPass::RenderPass(const VkRenderPassCreateInfo* pCreateInfo, void* mem) :
memcpy(const_cast<VkAttachmentReference*>(subpasses[i].pInputAttachments), memcpy(const_cast<VkAttachmentReference*>(subpasses[i].pInputAttachments),
pCreateInfo->pSubpasses[i].pInputAttachments, inputAttachmentsSize); pCreateInfo->pSubpasses[i].pInputAttachments, inputAttachmentsSize);
hostMemory += inputAttachmentsSize; hostMemory += inputAttachmentsSize;
for (auto j = 0u; j < subpasses[i].inputAttachmentCount; j++)
{
if (subpass.pInputAttachments[j].attachment != VK_ATTACHMENT_UNUSED)
MarkFirstUse(attachmentFirstUse[subpass.pInputAttachments[j].attachment], i);
}
} }
if(subpass.colorAttachmentCount > 0) if(subpass.colorAttachmentCount > 0)
...@@ -65,24 +86,36 @@ RenderPass::RenderPass(const VkRenderPassCreateInfo* pCreateInfo, void* mem) : ...@@ -65,24 +86,36 @@ RenderPass::RenderPass(const VkRenderPassCreateInfo* pCreateInfo, void* mem) :
size_t colorAttachmentsSize = subpass.colorAttachmentCount * sizeof(VkAttachmentReference); size_t colorAttachmentsSize = subpass.colorAttachmentCount * sizeof(VkAttachmentReference);
subpasses[i].pColorAttachments = reinterpret_cast<VkAttachmentReference*>(hostMemory); subpasses[i].pColorAttachments = reinterpret_cast<VkAttachmentReference*>(hostMemory);
memcpy(const_cast<VkAttachmentReference*>(subpasses[i].pColorAttachments), memcpy(const_cast<VkAttachmentReference*>(subpasses[i].pColorAttachments),
pCreateInfo->pSubpasses[i].pColorAttachments, colorAttachmentsSize); subpass.pColorAttachments, colorAttachmentsSize);
hostMemory += colorAttachmentsSize; hostMemory += colorAttachmentsSize;
if(subpass.pResolveAttachments != nullptr) if(subpass.pResolveAttachments != nullptr)
{ {
subpasses[i].pResolveAttachments = reinterpret_cast<VkAttachmentReference*>(hostMemory); subpasses[i].pResolveAttachments = reinterpret_cast<VkAttachmentReference*>(hostMemory);
memcpy(const_cast<VkAttachmentReference*>(subpasses[i].pResolveAttachments), memcpy(const_cast<VkAttachmentReference*>(subpasses[i].pResolveAttachments),
pCreateInfo->pSubpasses[i].pResolveAttachments, colorAttachmentsSize); subpass.pResolveAttachments, colorAttachmentsSize);
hostMemory += colorAttachmentsSize; hostMemory += colorAttachmentsSize;
} }
for (auto j = 0u; j < subpasses[i].colorAttachmentCount; j++)
{
if (subpass.pColorAttachments[j].attachment != VK_ATTACHMENT_UNUSED)
MarkFirstUse(attachmentFirstUse[subpass.pColorAttachments[j].attachment], i);
if (subpass.pResolveAttachments &&
subpass.pResolveAttachments[j].attachment != VK_ATTACHMENT_UNUSED)
MarkFirstUse(attachmentFirstUse[subpass.pResolveAttachments[j].attachment], i);
}
} }
if(subpass.pDepthStencilAttachment != nullptr) if(subpass.pDepthStencilAttachment != nullptr)
{ {
subpasses[i].pDepthStencilAttachment = reinterpret_cast<VkAttachmentReference*>(hostMemory); subpasses[i].pDepthStencilAttachment = reinterpret_cast<VkAttachmentReference*>(hostMemory);
memcpy(const_cast<VkAttachmentReference*>(subpasses[i].pDepthStencilAttachment), memcpy(const_cast<VkAttachmentReference*>(subpasses[i].pDepthStencilAttachment),
pCreateInfo->pSubpasses[i].pDepthStencilAttachment, sizeof(VkAttachmentReference)); subpass.pDepthStencilAttachment, sizeof(VkAttachmentReference));
hostMemory += sizeof(VkAttachmentReference); hostMemory += sizeof(VkAttachmentReference);
if (subpass.pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED)
MarkFirstUse(attachmentFirstUse[subpass.pDepthStencilAttachment->attachment], i);
} }
if(subpass.preserveAttachmentCount > 0) if(subpass.preserveAttachmentCount > 0)
...@@ -92,6 +125,12 @@ RenderPass::RenderPass(const VkRenderPassCreateInfo* pCreateInfo, void* mem) : ...@@ -92,6 +125,12 @@ RenderPass::RenderPass(const VkRenderPassCreateInfo* pCreateInfo, void* mem) :
memcpy(const_cast<uint32_t*>(subpasses[i].pPreserveAttachments), memcpy(const_cast<uint32_t*>(subpasses[i].pPreserveAttachments),
pCreateInfo->pSubpasses[i].pPreserveAttachments, preserveAttachmentSize); pCreateInfo->pSubpasses[i].pPreserveAttachments, preserveAttachmentSize);
hostMemory += preserveAttachmentSize; hostMemory += preserveAttachmentSize;
for (auto j = 0u; j < subpasses[i].preserveAttachmentCount; j++)
{
if (subpass.pPreserveAttachments[j] != VK_ATTACHMENT_UNUSED)
MarkFirstUse(attachmentFirstUse[subpass.pPreserveAttachments[j]], i);
}
} }
} }
...@@ -110,7 +149,8 @@ void RenderPass::destroy(const VkAllocationCallbacks* pAllocator) ...@@ -110,7 +149,8 @@ void RenderPass::destroy(const VkAllocationCallbacks* pAllocator)
size_t RenderPass::ComputeRequiredAllocationSize(const VkRenderPassCreateInfo* pCreateInfo) size_t RenderPass::ComputeRequiredAllocationSize(const VkRenderPassCreateInfo* pCreateInfo)
{ {
size_t attachmentSize = pCreateInfo->attachmentCount * sizeof(VkAttachmentDescription); size_t attachmentSize = pCreateInfo->attachmentCount * sizeof(VkAttachmentDescription)
+ pCreateInfo->attachmentCount * sizeof(int);
size_t subpassesSize = 0; size_t subpassesSize = 0;
for(uint32_t i = 0; i < pCreateInfo->subpassCount; ++i) for(uint32_t i = 0; i < pCreateInfo->subpassCount; ++i)
{ {
...@@ -133,11 +173,11 @@ size_t RenderPass::ComputeRequiredAllocationSize(const VkRenderPassCreateInfo* p ...@@ -133,11 +173,11 @@ size_t RenderPass::ComputeRequiredAllocationSize(const VkRenderPassCreateInfo* p
return attachmentSize + subpassesSize + dependenciesSize; return attachmentSize + subpassesSize + dependenciesSize;
} }
void RenderPass::getRenderAreaGranularity(VkExtent2D* pGranularity) const void RenderPass::getRenderAreaGranularity(VkExtent2D* pGranularity) const
{ {
pGranularity->width = 1; pGranularity->width = 1;
pGranularity->height = 1; pGranularity->height = 1;
} }
void RenderPass::begin() void RenderPass::begin()
{ {
......
...@@ -17,6 +17,8 @@ ...@@ -17,6 +17,8 @@
#include "VkObject.hpp" #include "VkObject.hpp"
#include <vector>
namespace vk namespace vk
{ {
...@@ -29,7 +31,7 @@ public: ...@@ -29,7 +31,7 @@ public:
static size_t ComputeRequiredAllocationSize(const VkRenderPassCreateInfo* pCreateInfo); static size_t ComputeRequiredAllocationSize(const VkRenderPassCreateInfo* pCreateInfo);
void getRenderAreaGranularity(VkExtent2D* pGranularity) const; void getRenderAreaGranularity(VkExtent2D* pGranularity) const;
void begin(); void begin();
void nextSubpass(); void nextSubpass();
...@@ -70,6 +72,11 @@ public: ...@@ -70,6 +72,11 @@ public:
return dependencies[i]; return dependencies[i];
} }
bool isAttachmentUsed(uint32_t i) const
{
return attachmentFirstUse[i] >= 0;
}
private: private:
uint32_t attachmentCount = 0; uint32_t attachmentCount = 0;
VkAttachmentDescription* attachments = nullptr; VkAttachmentDescription* attachments = nullptr;
...@@ -78,6 +85,7 @@ private: ...@@ -78,6 +85,7 @@ private:
uint32_t dependencyCount = 0; uint32_t dependencyCount = 0;
VkSubpassDependency* dependencies = nullptr; VkSubpassDependency* dependencies = nullptr;
uint32_t currentSubpass = 0; uint32_t currentSubpass = 0;
int* attachmentFirstUse = nullptr;
}; };
static inline RenderPass* Cast(VkRenderPass object) static inline RenderPass* Cast(VkRenderPass object)
......
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