Vulkan: Use RenderTargetCache in FramebufferVk.
The RenderTargetCache avoids many multiple calls to getRenderTarget,
and should speed up the code somewhat on state changes. Also as a
side benefit removes a bunch of swallowed ANGLE errors.
Bug: angleproject:2372
Change-Id: I072481856aae8607f17a116e25c71acf04b4cc68
Reviewed-on: https://chromium-review.googlesource.com/948785
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Commit-Queue: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/renderer/vulkan/FramebufferVk.cpp b/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
index 72167da..2bd6920 100644
--- a/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
+++ b/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
@@ -31,15 +31,11 @@
namespace
{
-gl::ErrorOrResult<const gl::InternalFormat *> GetReadAttachmentInfo(
- const gl::Context *context,
- const gl::FramebufferAttachment *readAttachment)
+const gl::InternalFormat &GetReadAttachmentInfo(const gl::Context *context,
+ RenderTargetVk *renderTarget)
{
- RenderTargetVk *renderTarget = nullptr;
- ANGLE_TRY(readAttachment->getRenderTarget(context, &renderTarget));
-
GLenum implFormat = renderTarget->format->textureFormat().fboImplementationInternalFormat;
- return &gl::GetSizedInternalFormatInfo(implFormat);
+ return gl::GetSizedInternalFormatInfo(implFormat);
}
} // anonymous namespace
@@ -158,23 +154,21 @@
Serial currentSerial = renderer->getCurrentQueueSerial();
- for (const auto &colorAttachment : mState.getColorAttachments())
+ // TODO(jmadill): Support gaps in RenderTargets. http://anglebug.com/2394
+ const auto &colorRenderTargets = mRenderTargetCache.getColors();
+ for (size_t colorIndex : mState.getEnabledDrawBuffers())
{
- if (colorAttachment.isAttached())
- {
- RenderTargetVk *renderTarget = nullptr;
- ANGLE_TRY(colorAttachment.getRenderTarget(context, &renderTarget));
+ RenderTargetVk *colorRenderTarget = colorRenderTargets[colorIndex];
+ ASSERT(colorRenderTarget);
+ colorRenderTarget->resource->onWriteResource(getCurrentWritingNode(currentSerial),
+ currentSerial);
- renderTarget->resource->onWriteResource(getCurrentWritingNode(currentSerial),
- currentSerial);
+ colorRenderTarget->image->changeLayoutWithStages(
+ VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+ VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, commandBuffer);
- renderTarget->image->changeLayoutWithStages(
- VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
- VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, commandBuffer);
-
- commandBuffer->clearSingleColorImage(*renderTarget->image,
- contextVk->getClearColorValue().color);
- }
+ commandBuffer->clearSingleColorImage(*colorRenderTarget->image,
+ contextVk->getClearColorValue().color);
}
// TODO(jmadill): Depth/stencil clear.
@@ -221,30 +215,12 @@
GLenum FramebufferVk::getImplementationColorReadFormat(const gl::Context *context) const
{
- auto errOrResult = GetReadAttachmentInfo(context, mState.getReadAttachment());
-
- // TODO(jmadill): Handle getRenderTarget error.
- if (errOrResult.isError())
- {
- ERR() << "Internal error in FramebufferVk::getImplementationColorReadFormat.";
- return GL_NONE;
- }
-
- return errOrResult.getResult()->format;
+ return GetReadAttachmentInfo(context, mRenderTargetCache.getColorRead(mState)).format;
}
GLenum FramebufferVk::getImplementationColorReadType(const gl::Context *context) const
{
- auto errOrResult = GetReadAttachmentInfo(context, mState.getReadAttachment());
-
- // TODO(jmadill): Handle getRenderTarget error.
- if (errOrResult.isError())
- {
- ERR() << "Internal error in FramebufferVk::getImplementationColorReadFormat.";
- return GL_NONE;
- }
-
- return errOrResult.getResult()->type;
+ return GetReadAttachmentInfo(context, mRenderTargetCache.getColorRead(mState)).type;
}
gl::Error FramebufferVk::readPixels(const gl::Context *context,
@@ -253,17 +229,14 @@
GLenum type,
void *pixels)
{
- const auto &glState = context->getGLState();
- const auto *readFramebuffer = glState.getReadFramebuffer();
- const auto *readAttachment = readFramebuffer->getReadColorbuffer();
-
- RenderTargetVk *renderTarget = nullptr;
- ANGLE_TRY(readAttachment->getRenderTarget(context, &renderTarget));
-
+ const gl::State &glState = context->getGLState();
ContextVk *contextVk = vk::GetImpl(context);
RendererVk *renderer = contextVk->getRenderer();
VkDevice device = renderer->getDevice();
+ RenderTargetVk *renderTarget = mRenderTargetCache.getColorRead(mState);
+ ASSERT(renderTarget);
+
vk::Image *readImage = renderTarget->image;
vk::StagingImage stagingImage;
ANGLE_TRY(stagingImage.init(contextVk, TextureDimension::TEX_2D, *renderTarget->format,
@@ -354,7 +327,8 @@
ASSERT(dirtyBits.any());
- // TODO(jmadill): Smarter update.
+ mRenderTargetCache.update(context, mState, dirtyBits);
+
mRenderPassDesc.reset();
renderer->releaseResource(*this, &mFramebuffer);
@@ -373,26 +347,20 @@
vk::RenderPassDesc desc;
- const auto &colorAttachments = mState.getColorAttachments();
- for (size_t attachmentIndex = 0; attachmentIndex < colorAttachments.size(); ++attachmentIndex)
+ // TODO(jmadill): Support gaps in RenderTargets. http://anglebug.com/2394
+ const auto &colorRenderTargets = mRenderTargetCache.getColors();
+ for (size_t colorIndex : mState.getEnabledDrawBuffers())
{
- const auto &colorAttachment = colorAttachments[attachmentIndex];
- if (colorAttachment.isAttached())
- {
- RenderTargetVk *renderTarget = nullptr;
- ANGLE_SWALLOW_ERR(colorAttachment.getRenderTarget(context, &renderTarget));
- desc.packColorAttachment(*renderTarget->format, colorAttachment.getSamples());
- }
+ RenderTargetVk *colorRenderTarget = colorRenderTargets[colorIndex];
+ ASSERT(colorRenderTarget);
+ desc.packColorAttachment(*colorRenderTarget->format, colorRenderTarget->samples);
}
- const auto *depthStencilAttachment = mState.getDepthStencilAttachment();
-
- if (depthStencilAttachment && depthStencilAttachment->isAttached())
+ RenderTargetVk *depthStencilRenderTarget = mRenderTargetCache.getDepthStencil();
+ if (depthStencilRenderTarget)
{
- RenderTargetVk *renderTarget = nullptr;
- ANGLE_SWALLOW_ERR(depthStencilAttachment->getRenderTarget(context, &renderTarget));
- desc.packDepthStencilAttachment(*renderTarget->format,
- depthStencilAttachment->getSamples());
+ desc.packDepthStencilAttachment(*depthStencilRenderTarget->format,
+ depthStencilRenderTarget->samples);
}
mRenderPassDesc = desc;
@@ -424,30 +392,25 @@
std::vector<VkImageView> attachments;
gl::Extents attachmentsSize;
- const auto &colorAttachments = mState.getColorAttachments();
- for (size_t attachmentIndex = 0; attachmentIndex < colorAttachments.size(); ++attachmentIndex)
+ // TODO(jmadill): Support gaps in RenderTargets. http://anglebug.com/2394
+ const auto &colorRenderTargets = mRenderTargetCache.getColors();
+ for (size_t colorIndex : mState.getEnabledDrawBuffers())
{
- const auto &colorAttachment = colorAttachments[attachmentIndex];
- if (colorAttachment.isAttached())
- {
- RenderTargetVk *renderTarget = nullptr;
- ANGLE_TRY(colorAttachment.getRenderTarget(context, &renderTarget));
- attachments.push_back(renderTarget->imageView->getHandle());
+ RenderTargetVk *colorRenderTarget = colorRenderTargets[colorIndex];
+ ASSERT(colorRenderTarget);
+ attachments.push_back(colorRenderTarget->imageView->getHandle());
- ASSERT(attachmentsSize.empty() || attachmentsSize == colorAttachment.getSize());
- attachmentsSize = colorAttachment.getSize();
- }
+ ASSERT(attachmentsSize.empty() || attachmentsSize == colorRenderTarget->extents);
+ attachmentsSize = colorRenderTarget->extents;
}
- const auto *depthStencilAttachment = mState.getDepthStencilAttachment();
- if (depthStencilAttachment && depthStencilAttachment->isAttached())
+ RenderTargetVk *depthStencilRenderTarget = mRenderTargetCache.getDepthStencil();
+ if (depthStencilRenderTarget)
{
- RenderTargetVk *renderTarget = nullptr;
- ANGLE_TRY(depthStencilAttachment->getRenderTarget(context, &renderTarget));
- attachments.push_back(renderTarget->imageView->getHandle());
+ attachments.push_back(depthStencilRenderTarget->imageView->getHandle());
- ASSERT(attachmentsSize.empty() || attachmentsSize == depthStencilAttachment->getSize());
- attachmentsSize = depthStencilAttachment->getSize();
+ ASSERT(attachmentsSize.empty() || attachmentsSize == depthStencilRenderTarget->extents);
+ attachmentsSize = depthStencilRenderTarget->extents;
}
ASSERT(!attachments.empty());
@@ -545,42 +508,35 @@
renderer->getCommandPool(), &commandBuffer));
// Initialize RenderPass info.
- // TODO(jmadill): Could cache this info, would require dependent state change messaging.
- const auto &colorAttachments = mState.getColorAttachments();
- for (size_t attachmentIndex = 0; attachmentIndex < colorAttachments.size(); ++attachmentIndex)
+ // TODO(jmadill): Support gaps in RenderTargets. http://anglebug.com/2394
+ const auto &colorRenderTargets = mRenderTargetCache.getColors();
+ for (size_t colorIndex : mState.getEnabledDrawBuffers())
{
- const auto &colorAttachment = colorAttachments[attachmentIndex];
- if (colorAttachment.isAttached())
- {
- RenderTargetVk *renderTarget = nullptr;
- ANGLE_SWALLOW_ERR(colorAttachment.getRenderTarget(context, &renderTarget));
-
- // TODO(jmadill): Use automatic layout transition. http://anglebug.com/2361
- renderTarget->image->changeLayoutWithStages(
- VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
- VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
- commandBuffer);
- node->appendColorRenderTarget(currentSerial, renderTarget);
- attachmentClearValues.emplace_back(contextVk->getClearColorValue());
- }
- }
-
- const gl::FramebufferAttachment *depthStencilAttachment = mState.getDepthOrStencilAttachment();
- if (depthStencilAttachment && depthStencilAttachment->isAttached())
- {
- RenderTargetVk *renderTarget = nullptr;
- ANGLE_SWALLOW_ERR(depthStencilAttachment->getRenderTarget(context, &renderTarget));
+ RenderTargetVk *colorRenderTarget = colorRenderTargets[colorIndex];
+ ASSERT(colorRenderTarget);
// TODO(jmadill): Use automatic layout transition. http://anglebug.com/2361
- const angle::Format &format = renderTarget->format->textureFormat();
+ colorRenderTarget->image->changeLayoutWithStages(
+ VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+ VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+ commandBuffer);
+ node->appendColorRenderTarget(currentSerial, colorRenderTarget);
+ attachmentClearValues.emplace_back(contextVk->getClearColorValue());
+ }
+
+ RenderTargetVk *depthStencilRenderTarget = mRenderTargetCache.getDepthStencil();
+ if (depthStencilRenderTarget)
+ {
+ // TODO(jmadill): Use automatic layout transition. http://anglebug.com/2361
+ const angle::Format &format = depthStencilRenderTarget->format->textureFormat();
VkImageAspectFlags aspectFlags = (format.depthBits > 0 ? VK_IMAGE_ASPECT_DEPTH_BIT : 0) |
(format.stencilBits > 0 ? VK_IMAGE_ASPECT_STENCIL_BIT : 0);
- renderTarget->image->changeLayoutWithStages(
+ depthStencilRenderTarget->image->changeLayoutWithStages(
aspectFlags, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
commandBuffer);
- node->appendDepthStencilRenderTarget(currentSerial, renderTarget);
+ node->appendDepthStencilRenderTarget(currentSerial, depthStencilRenderTarget);
attachmentClearValues.emplace_back(contextVk->getClearDepthStencilValue());
}