Commit 0b684ce3 by Jamie Madill Committed by Commit Bot

Vulkan: Move RenderPass init into a helper function.

Here it can be more easily accessed for command re-ordering, which will use a RenderPass cache instead of having RenderPasses be owned by the Framebuffer. Bug: angleproject:2264 Change-Id: I9b06cff43e536a526d44e7e0c04027bc450051cf Reviewed-on: https://chromium-review.googlesource.com/789533Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Reviewed-by: 's avatarFrank Henigman <fjhenigman@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent afa02a2f
...@@ -304,6 +304,12 @@ constexpr size_t CUBE_FACE_COUNT = 6; ...@@ -304,6 +304,12 @@ constexpr size_t CUBE_FACE_COUNT = 6;
using TextureMap = std::map<GLenum, BindingPointer<Texture>>; using TextureMap = std::map<GLenum, BindingPointer<Texture>>;
template <typename T>
using AttachmentArray = std::array<T, IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS>;
template <typename T>
using DrawBuffersArray = std::array<T, IMPLEMENTATION_MAX_DRAW_BUFFERS>;
} // namespace gl } // namespace gl
namespace rx namespace rx
......
...@@ -379,9 +379,7 @@ gl::ErrorOrResult<vk::RenderPass *> FramebufferVk::getRenderPass(const gl::Conte ...@@ -379,9 +379,7 @@ gl::ErrorOrResult<vk::RenderPass *> FramebufferVk::getRenderPass(const gl::Conte
return &mRenderPass; return &mRenderPass;
} }
// TODO(jmadill): Can we use stack-only memory? vk::RenderPassDesc desc;
std::vector<VkAttachmentDescription> attachmentDescs;
std::vector<VkAttachmentReference> colorAttachmentRefs;
const auto &colorAttachments = mState.getColorAttachments(); const auto &colorAttachments = mState.getColorAttachments();
for (size_t attachmentIndex = 0; attachmentIndex < colorAttachments.size(); ++attachmentIndex) for (size_t attachmentIndex = 0; attachmentIndex < colorAttachments.size(); ++attachmentIndex)
...@@ -389,91 +387,50 @@ gl::ErrorOrResult<vk::RenderPass *> FramebufferVk::getRenderPass(const gl::Conte ...@@ -389,91 +387,50 @@ gl::ErrorOrResult<vk::RenderPass *> FramebufferVk::getRenderPass(const gl::Conte
const auto &colorAttachment = colorAttachments[attachmentIndex]; const auto &colorAttachment = colorAttachments[attachmentIndex];
if (colorAttachment.isAttached()) if (colorAttachment.isAttached())
{ {
VkAttachmentDescription colorDesc;
VkAttachmentReference colorRef;
RenderTargetVk *renderTarget = nullptr; RenderTargetVk *renderTarget = nullptr;
ANGLE_TRY(colorAttachment.getRenderTarget(context, &renderTarget)); ANGLE_TRY(colorAttachment.getRenderTarget(context, &renderTarget));
VkAttachmentDescription *colorDesc = desc.nextColorAttachment();
// TODO(jmadill): We would only need this flag for duplicated attachments. // TODO(jmadill): We would only need this flag for duplicated attachments.
colorDesc.flags = VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT; colorDesc->flags = VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT;
colorDesc.format = renderTarget->format->vkTextureFormat; colorDesc->format = renderTarget->format->vkTextureFormat;
colorDesc.samples = ConvertSamples(colorAttachment.getSamples()); colorDesc->samples = ConvertSamples(colorAttachment.getSamples());
// The load op controls the prior existing depth/color attachment data. // The load op controls the prior existing depth/color attachment data.
// TODO(jmadill): Proper load ops. Should not be hard coded to clear. // TODO(jmadill): Proper load ops. Should not be hard coded to clear.
colorDesc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; colorDesc->loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
colorDesc.storeOp = VK_ATTACHMENT_STORE_OP_STORE; colorDesc->storeOp = VK_ATTACHMENT_STORE_OP_STORE;
colorDesc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; colorDesc->stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
colorDesc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; colorDesc->stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
colorDesc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; colorDesc->initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
// We might want to transition directly to PRESENT_SRC for Surface attachments. // We might want to transition directly to PRESENT_SRC for Surface attachments.
colorDesc.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; colorDesc->finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
colorRef.attachment = static_cast<uint32_t>(colorAttachments.size()) - 1u;
colorRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
attachmentDescs.push_back(colorDesc);
colorAttachmentRefs.push_back(colorRef);
} }
} }
const auto *depthStencilAttachment = mState.getDepthStencilAttachment(); const auto *depthStencilAttachment = mState.getDepthStencilAttachment();
VkAttachmentReference depthStencilAttachmentRef;
bool useDepth = depthStencilAttachment && depthStencilAttachment->isAttached();
if (useDepth) if (depthStencilAttachment && depthStencilAttachment->isAttached())
{ {
VkAttachmentDescription depthStencilDesc;
RenderTargetVk *renderTarget = nullptr; RenderTargetVk *renderTarget = nullptr;
ANGLE_TRY(depthStencilAttachment->getRenderTarget(context, &renderTarget)); ANGLE_TRY(depthStencilAttachment->getRenderTarget(context, &renderTarget));
depthStencilDesc.flags = 0; VkAttachmentDescription *depthStencilDesc = desc.nextDepthStencilAttachment();
depthStencilDesc.format = renderTarget->format->vkTextureFormat;
depthStencilDesc.samples = ConvertSamples(depthStencilAttachment->getSamples()); depthStencilDesc->flags = 0;
depthStencilDesc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; depthStencilDesc->format = renderTarget->format->vkTextureFormat;
depthStencilDesc.storeOp = VK_ATTACHMENT_STORE_OP_STORE; depthStencilDesc->samples = ConvertSamples(depthStencilAttachment->getSamples());
depthStencilDesc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; depthStencilDesc->loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
depthStencilDesc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; depthStencilDesc->storeOp = VK_ATTACHMENT_STORE_OP_STORE;
depthStencilDesc.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; depthStencilDesc->stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
depthStencilDesc.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; depthStencilDesc->stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
depthStencilDesc->initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
depthStencilAttachmentRef.attachment = static_cast<uint32_t>(attachmentDescs.size()); depthStencilDesc->finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
depthStencilAttachmentRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
attachmentDescs.push_back(depthStencilDesc);
} }
ASSERT(!attachmentDescs.empty()); ANGLE_TRY(vk::InitializeRenderPassFromDesc(device, desc, &mRenderPass));
VkSubpassDescription subpassDesc;
subpassDesc.flags = 0;
subpassDesc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
subpassDesc.inputAttachmentCount = 0;
subpassDesc.pInputAttachments = nullptr;
subpassDesc.colorAttachmentCount = static_cast<uint32_t>(colorAttachmentRefs.size());
subpassDesc.pColorAttachments = colorAttachmentRefs.data();
subpassDesc.pResolveAttachments = nullptr;
subpassDesc.pDepthStencilAttachment = (useDepth ? &depthStencilAttachmentRef : nullptr);
subpassDesc.preserveAttachmentCount = 0;
subpassDesc.pPreserveAttachments = nullptr;
VkRenderPassCreateInfo renderPassInfo;
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
renderPassInfo.pNext = nullptr;
renderPassInfo.flags = 0;
renderPassInfo.attachmentCount = static_cast<uint32_t>(attachmentDescs.size());
renderPassInfo.pAttachments = attachmentDescs.data();
renderPassInfo.subpassCount = 1;
renderPassInfo.pSubpasses = &subpassDesc;
renderPassInfo.dependencyCount = 0;
renderPassInfo.pDependencies = nullptr;
ANGLE_TRY(mRenderPass.init(device, renderPassInfo));
return &mRenderPass; return &mRenderPass;
} }
......
...@@ -1253,6 +1253,98 @@ Error CommandBufferAndState::ensureFinished() ...@@ -1253,6 +1253,98 @@ Error CommandBufferAndState::ensureFinished()
return NoError(); return NoError();
} }
// RenderPassDesc implementation.
RenderPassDesc::RenderPassDesc()
: colorAttachmentCount(0), depthStencilAttachmentCount(0), attachmentDescs{}
{
memset(attachmentDescs.data(), 0, sizeof(VkAttachmentDescription) * attachmentDescs.size());
}
RenderPassDesc::~RenderPassDesc()
{
}
RenderPassDesc::RenderPassDesc(const RenderPassDesc &other)
{
memcpy(this, &other, sizeof(RenderPassDesc));
}
RenderPassDesc &RenderPassDesc::operator=(const RenderPassDesc &other)
{
memcpy(this, &other, sizeof(RenderPassDesc));
return *this;
}
VkAttachmentDescription *RenderPassDesc::nextColorAttachment()
{
ASSERT(colorAttachmentCount < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS);
return &attachmentDescs[colorAttachmentCount++];
}
VkAttachmentDescription *RenderPassDesc::nextDepthStencilAttachment()
{
ASSERT(depthStencilAttachmentCount == 0);
return &attachmentDescs[depthStencilAttachmentCount++];
}
uint32_t RenderPassDesc::attachmentCount() const
{
return (colorAttachmentCount + depthStencilAttachmentCount);
}
Error InitializeRenderPassFromDesc(VkDevice device,
const RenderPassDesc &desc,
RenderPass *renderPass)
{
uint32_t attachmentCount = desc.attachmentCount();
ASSERT(attachmentCount > 0);
gl::DrawBuffersArray<VkAttachmentReference> colorAttachmentRefs;
for (uint32_t colorIndex = 0; colorIndex < desc.colorAttachmentCount; ++colorIndex)
{
VkAttachmentReference &colorRef = colorAttachmentRefs[colorIndex];
colorRef.attachment = colorIndex;
colorRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
}
VkAttachmentReference depthStencilAttachmentRef;
if (desc.depthStencilAttachmentCount > 0)
{
ASSERT(desc.depthStencilAttachmentCount == 1);
depthStencilAttachmentRef.attachment = desc.colorAttachmentCount;
depthStencilAttachmentRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
}
VkSubpassDescription subpassDesc;
subpassDesc.flags = 0;
subpassDesc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
subpassDesc.inputAttachmentCount = 0;
subpassDesc.pInputAttachments = nullptr;
subpassDesc.colorAttachmentCount = desc.colorAttachmentCount;
subpassDesc.pColorAttachments = colorAttachmentRefs.data();
subpassDesc.pResolveAttachments = nullptr;
subpassDesc.pDepthStencilAttachment =
(desc.depthStencilAttachmentCount > 0 ? &depthStencilAttachmentRef : nullptr);
subpassDesc.preserveAttachmentCount = 0;
subpassDesc.pPreserveAttachments = nullptr;
VkRenderPassCreateInfo createInfo;
createInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
createInfo.pNext = nullptr;
createInfo.flags = 0;
createInfo.attachmentCount = attachmentCount;
createInfo.pAttachments = desc.attachmentDescs.data();
createInfo.subpassCount = 1;
createInfo.pSubpasses = &subpassDesc;
createInfo.dependencyCount = 0;
createInfo.pDependencies = nullptr;
ANGLE_TRY(renderPass->init(device, createInfo));
return vk::NoError();
}
} // namespace vk } // namespace vk
namespace gl_vk namespace gl_vk
......
...@@ -667,6 +667,30 @@ class CommandBufferAndState : public vk::CommandBuffer ...@@ -667,6 +667,30 @@ class CommandBufferAndState : public vk::CommandBuffer
using CommandBufferAndSerial = ObjectAndSerial<CommandBufferAndState>; using CommandBufferAndSerial = ObjectAndSerial<CommandBufferAndState>;
using FenceAndSerial = ObjectAndSerial<Fence>; using FenceAndSerial = ObjectAndSerial<Fence>;
struct RenderPassDesc final
{
RenderPassDesc();
~RenderPassDesc();
RenderPassDesc(const RenderPassDesc &other);
RenderPassDesc &operator=(const RenderPassDesc &other);
// These also increment the attachment counts. DS attachments are limited to a count of 1.
VkAttachmentDescription *nextColorAttachment();
VkAttachmentDescription *nextDepthStencilAttachment();
uint32_t attachmentCount() const;
// Fully padded out, with no bools, to avoid any undefined behaviour.
uint32_t colorAttachmentCount;
uint32_t depthStencilAttachmentCount;
// The last element in this array is the depth/stencil attachment, if present.
gl::AttachmentArray<VkAttachmentDescription> attachmentDescs;
};
Error InitializeRenderPassFromDesc(VkDevice device,
const RenderPassDesc &desc,
RenderPass *renderPass);
} // namespace vk } // namespace vk
namespace gl_vk namespace gl_vk
......
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