Commit 66546be2 by Jamie Madill Committed by Commit Bot

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/948785Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent 5242d5bf
...@@ -133,7 +133,7 @@ class FramebufferState final : angle::NonCopyable ...@@ -133,7 +133,7 @@ class FramebufferState final : angle::NonCopyable
angle::BitSet<IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS + 2> mResourceNeedsInit; angle::BitSet<IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS + 2> mResourceNeedsInit;
}; };
class Framebuffer final : public LabeledObject, public angle::ObserverInterface class Framebuffer final : public angle::ObserverInterface, public LabeledObject
{ {
public: public:
// Constructor to build application-defined framebuffers // Constructor to build application-defined framebuffers
......
...@@ -35,6 +35,8 @@ class RenderTargetCache final : angle::NonCopyable ...@@ -35,6 +35,8 @@ class RenderTargetCache final : angle::NonCopyable
const RenderTargetArray &getColors() const; const RenderTargetArray &getColors() const;
RenderTargetT *getDepthStencil() const; RenderTargetT *getDepthStencil() const;
RenderTargetT *getColorRead(const gl::FramebufferState &state) const;
private: private:
void updateCachedRenderTarget(const gl::Context *context, void updateCachedRenderTarget(const gl::Context *context,
const gl::FramebufferAttachment *attachment, const gl::FramebufferAttachment *attachment,
...@@ -142,6 +144,15 @@ void RenderTargetCache<RenderTargetT>::updateCachedRenderTarget( ...@@ -142,6 +144,15 @@ void RenderTargetCache<RenderTargetT>::updateCachedRenderTarget(
*cachedRenderTarget = newRenderTarget; *cachedRenderTarget = newRenderTarget;
} }
template <typename RenderTargetT>
RenderTargetT *RenderTargetCache<RenderTargetT>::getColorRead(
const gl::FramebufferState &state) const
{
ASSERT(mColorRenderTargets[state.getReadIndex()] &&
state.getReadIndex() < mColorRenderTargets.size());
return mColorRenderTargets[state.getReadIndex()];
}
} // namespace rx } // namespace rx
#endif // LIBANGLE_RENDERER_RENDER_TARGET_CACHE_H_ #endif // LIBANGLE_RENDERER_RENDER_TARGET_CACHE_H_
...@@ -19,7 +19,7 @@ namespace rx ...@@ -19,7 +19,7 @@ namespace rx
{ {
class Renderer11; class Renderer11;
class VertexArray11 : public VertexArrayImpl, public angle::ObserverInterface class VertexArray11 : public angle::ObserverInterface, public VertexArrayImpl
{ {
public: public:
VertexArray11(const gl::VertexArrayState &data); VertexArray11(const gl::VertexArrayState &data);
......
...@@ -31,15 +31,11 @@ namespace rx ...@@ -31,15 +31,11 @@ namespace rx
namespace namespace
{ {
gl::ErrorOrResult<const gl::InternalFormat *> GetReadAttachmentInfo( const gl::InternalFormat &GetReadAttachmentInfo(const gl::Context *context,
const gl::Context *context, RenderTargetVk *renderTarget)
const gl::FramebufferAttachment *readAttachment)
{ {
RenderTargetVk *renderTarget = nullptr;
ANGLE_TRY(readAttachment->getRenderTarget(context, &renderTarget));
GLenum implFormat = renderTarget->format->textureFormat().fboImplementationInternalFormat; GLenum implFormat = renderTarget->format->textureFormat().fboImplementationInternalFormat;
return &gl::GetSizedInternalFormatInfo(implFormat); return gl::GetSizedInternalFormatInfo(implFormat);
} }
} // anonymous namespace } // anonymous namespace
...@@ -158,23 +154,21 @@ gl::Error FramebufferVk::clear(const gl::Context *context, GLbitfield mask) ...@@ -158,23 +154,21 @@ gl::Error FramebufferVk::clear(const gl::Context *context, GLbitfield mask)
Serial currentSerial = renderer->getCurrentQueueSerial(); 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 *colorRenderTarget = colorRenderTargets[colorIndex];
{ ASSERT(colorRenderTarget);
RenderTargetVk *renderTarget = nullptr; colorRenderTarget->resource->onWriteResource(getCurrentWritingNode(currentSerial),
ANGLE_TRY(colorAttachment.getRenderTarget(context, &renderTarget)); currentSerial);
renderTarget->resource->onWriteResource(getCurrentWritingNode(currentSerial),
currentSerial);
renderTarget->image->changeLayoutWithStages( colorRenderTarget->image->changeLayoutWithStages(
VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, commandBuffer); VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, commandBuffer);
commandBuffer->clearSingleColorImage(*renderTarget->image, commandBuffer->clearSingleColorImage(*colorRenderTarget->image,
contextVk->getClearColorValue().color); contextVk->getClearColorValue().color);
}
} }
// TODO(jmadill): Depth/stencil clear. // TODO(jmadill): Depth/stencil clear.
...@@ -221,30 +215,12 @@ gl::Error FramebufferVk::clearBufferfi(const gl::Context *context, ...@@ -221,30 +215,12 @@ gl::Error FramebufferVk::clearBufferfi(const gl::Context *context,
GLenum FramebufferVk::getImplementationColorReadFormat(const gl::Context *context) const GLenum FramebufferVk::getImplementationColorReadFormat(const gl::Context *context) const
{ {
auto errOrResult = GetReadAttachmentInfo(context, mState.getReadAttachment()); return GetReadAttachmentInfo(context, mRenderTargetCache.getColorRead(mState)).format;
// TODO(jmadill): Handle getRenderTarget error.
if (errOrResult.isError())
{
ERR() << "Internal error in FramebufferVk::getImplementationColorReadFormat.";
return GL_NONE;
}
return errOrResult.getResult()->format;
} }
GLenum FramebufferVk::getImplementationColorReadType(const gl::Context *context) const GLenum FramebufferVk::getImplementationColorReadType(const gl::Context *context) const
{ {
auto errOrResult = GetReadAttachmentInfo(context, mState.getReadAttachment()); return GetReadAttachmentInfo(context, mRenderTargetCache.getColorRead(mState)).type;
// TODO(jmadill): Handle getRenderTarget error.
if (errOrResult.isError())
{
ERR() << "Internal error in FramebufferVk::getImplementationColorReadFormat.";
return GL_NONE;
}
return errOrResult.getResult()->type;
} }
gl::Error FramebufferVk::readPixels(const gl::Context *context, gl::Error FramebufferVk::readPixels(const gl::Context *context,
...@@ -253,17 +229,14 @@ gl::Error FramebufferVk::readPixels(const gl::Context *context, ...@@ -253,17 +229,14 @@ gl::Error FramebufferVk::readPixels(const gl::Context *context,
GLenum type, GLenum type,
void *pixels) void *pixels)
{ {
const auto &glState = context->getGLState(); const gl::State &glState = context->getGLState();
const auto *readFramebuffer = glState.getReadFramebuffer();
const auto *readAttachment = readFramebuffer->getReadColorbuffer();
RenderTargetVk *renderTarget = nullptr;
ANGLE_TRY(readAttachment->getRenderTarget(context, &renderTarget));
ContextVk *contextVk = vk::GetImpl(context); ContextVk *contextVk = vk::GetImpl(context);
RendererVk *renderer = contextVk->getRenderer(); RendererVk *renderer = contextVk->getRenderer();
VkDevice device = renderer->getDevice(); VkDevice device = renderer->getDevice();
RenderTargetVk *renderTarget = mRenderTargetCache.getColorRead(mState);
ASSERT(renderTarget);
vk::Image *readImage = renderTarget->image; vk::Image *readImage = renderTarget->image;
vk::StagingImage stagingImage; vk::StagingImage stagingImage;
ANGLE_TRY(stagingImage.init(contextVk, TextureDimension::TEX_2D, *renderTarget->format, ANGLE_TRY(stagingImage.init(contextVk, TextureDimension::TEX_2D, *renderTarget->format,
...@@ -354,7 +327,8 @@ void FramebufferVk::syncState(const gl::Context *context, ...@@ -354,7 +327,8 @@ void FramebufferVk::syncState(const gl::Context *context,
ASSERT(dirtyBits.any()); ASSERT(dirtyBits.any());
// TODO(jmadill): Smarter update. mRenderTargetCache.update(context, mState, dirtyBits);
mRenderPassDesc.reset(); mRenderPassDesc.reset();
renderer->releaseResource(*this, &mFramebuffer); renderer->releaseResource(*this, &mFramebuffer);
...@@ -373,26 +347,20 @@ const vk::RenderPassDesc &FramebufferVk::getRenderPassDesc(const gl::Context *co ...@@ -373,26 +347,20 @@ const vk::RenderPassDesc &FramebufferVk::getRenderPassDesc(const gl::Context *co
vk::RenderPassDesc desc; vk::RenderPassDesc desc;
const auto &colorAttachments = mState.getColorAttachments(); // TODO(jmadill): Support gaps in RenderTargets. http://anglebug.com/2394
for (size_t attachmentIndex = 0; attachmentIndex < colorAttachments.size(); ++attachmentIndex) const auto &colorRenderTargets = mRenderTargetCache.getColors();
for (size_t colorIndex : mState.getEnabledDrawBuffers())
{ {
const auto &colorAttachment = colorAttachments[attachmentIndex]; RenderTargetVk *colorRenderTarget = colorRenderTargets[colorIndex];
if (colorAttachment.isAttached()) ASSERT(colorRenderTarget);
{ desc.packColorAttachment(*colorRenderTarget->format, colorRenderTarget->samples);
RenderTargetVk *renderTarget = nullptr;
ANGLE_SWALLOW_ERR(colorAttachment.getRenderTarget(context, &renderTarget));
desc.packColorAttachment(*renderTarget->format, colorAttachment.getSamples());
}
} }
const auto *depthStencilAttachment = mState.getDepthStencilAttachment(); RenderTargetVk *depthStencilRenderTarget = mRenderTargetCache.getDepthStencil();
if (depthStencilRenderTarget)
if (depthStencilAttachment && depthStencilAttachment->isAttached())
{ {
RenderTargetVk *renderTarget = nullptr; desc.packDepthStencilAttachment(*depthStencilRenderTarget->format,
ANGLE_SWALLOW_ERR(depthStencilAttachment->getRenderTarget(context, &renderTarget)); depthStencilRenderTarget->samples);
desc.packDepthStencilAttachment(*renderTarget->format,
depthStencilAttachment->getSamples());
} }
mRenderPassDesc = desc; mRenderPassDesc = desc;
...@@ -424,30 +392,25 @@ gl::ErrorOrResult<vk::Framebuffer *> FramebufferVk::getFramebuffer(const gl::Con ...@@ -424,30 +392,25 @@ gl::ErrorOrResult<vk::Framebuffer *> FramebufferVk::getFramebuffer(const gl::Con
std::vector<VkImageView> attachments; std::vector<VkImageView> attachments;
gl::Extents attachmentsSize; gl::Extents attachmentsSize;
const auto &colorAttachments = mState.getColorAttachments(); // TODO(jmadill): Support gaps in RenderTargets. http://anglebug.com/2394
for (size_t attachmentIndex = 0; attachmentIndex < colorAttachments.size(); ++attachmentIndex) const auto &colorRenderTargets = mRenderTargetCache.getColors();
for (size_t colorIndex : mState.getEnabledDrawBuffers())
{ {
const auto &colorAttachment = colorAttachments[attachmentIndex]; RenderTargetVk *colorRenderTarget = colorRenderTargets[colorIndex];
if (colorAttachment.isAttached()) ASSERT(colorRenderTarget);
{ attachments.push_back(colorRenderTarget->imageView->getHandle());
RenderTargetVk *renderTarget = nullptr;
ANGLE_TRY(colorAttachment.getRenderTarget(context, &renderTarget)); ASSERT(attachmentsSize.empty() || attachmentsSize == colorRenderTarget->extents);
attachments.push_back(renderTarget->imageView->getHandle()); attachmentsSize = colorRenderTarget->extents;
ASSERT(attachmentsSize.empty() || attachmentsSize == colorAttachment.getSize());
attachmentsSize = colorAttachment.getSize();
}
} }
const auto *depthStencilAttachment = mState.getDepthStencilAttachment(); RenderTargetVk *depthStencilRenderTarget = mRenderTargetCache.getDepthStencil();
if (depthStencilAttachment && depthStencilAttachment->isAttached()) if (depthStencilRenderTarget)
{ {
RenderTargetVk *renderTarget = nullptr; attachments.push_back(depthStencilRenderTarget->imageView->getHandle());
ANGLE_TRY(depthStencilAttachment->getRenderTarget(context, &renderTarget));
attachments.push_back(renderTarget->imageView->getHandle());
ASSERT(attachmentsSize.empty() || attachmentsSize == depthStencilAttachment->getSize()); ASSERT(attachmentsSize.empty() || attachmentsSize == depthStencilRenderTarget->extents);
attachmentsSize = depthStencilAttachment->getSize(); attachmentsSize = depthStencilRenderTarget->extents;
} }
ASSERT(!attachments.empty()); ASSERT(!attachments.empty());
...@@ -545,42 +508,35 @@ gl::Error FramebufferVk::getCommandGraphNodeForDraw(const gl::Context *context, ...@@ -545,42 +508,35 @@ gl::Error FramebufferVk::getCommandGraphNodeForDraw(const gl::Context *context,
renderer->getCommandPool(), &commandBuffer)); renderer->getCommandPool(), &commandBuffer));
// Initialize RenderPass info. // Initialize RenderPass info.
// TODO(jmadill): Could cache this info, would require dependent state change messaging. // TODO(jmadill): Support gaps in RenderTargets. http://anglebug.com/2394
const auto &colorAttachments = mState.getColorAttachments(); const auto &colorRenderTargets = mRenderTargetCache.getColors();
for (size_t attachmentIndex = 0; attachmentIndex < colorAttachments.size(); ++attachmentIndex) for (size_t colorIndex : mState.getEnabledDrawBuffers())
{ {
const auto &colorAttachment = colorAttachments[attachmentIndex]; RenderTargetVk *colorRenderTarget = colorRenderTargets[colorIndex];
if (colorAttachment.isAttached()) ASSERT(colorRenderTarget);
{
RenderTargetVk *renderTarget = nullptr; // TODO(jmadill): Use automatic layout transition. http://anglebug.com/2361
ANGLE_SWALLOW_ERR(colorAttachment.getRenderTarget(context, &renderTarget)); colorRenderTarget->image->changeLayoutWithStages(
VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
// TODO(jmadill): Use automatic layout transition. http://anglebug.com/2361 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
renderTarget->image->changeLayoutWithStages( commandBuffer);
VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, node->appendColorRenderTarget(currentSerial, colorRenderTarget);
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, attachmentClearValues.emplace_back(contextVk->getClearColorValue());
commandBuffer);
node->appendColorRenderTarget(currentSerial, renderTarget);
attachmentClearValues.emplace_back(contextVk->getClearColorValue());
}
} }
const gl::FramebufferAttachment *depthStencilAttachment = mState.getDepthOrStencilAttachment(); RenderTargetVk *depthStencilRenderTarget = mRenderTargetCache.getDepthStencil();
if (depthStencilAttachment && depthStencilAttachment->isAttached()) if (depthStencilRenderTarget)
{ {
RenderTargetVk *renderTarget = nullptr;
ANGLE_SWALLOW_ERR(depthStencilAttachment->getRenderTarget(context, &renderTarget));
// TODO(jmadill): Use automatic layout transition. http://anglebug.com/2361 // TODO(jmadill): Use automatic layout transition. http://anglebug.com/2361
const angle::Format &format = renderTarget->format->textureFormat(); const angle::Format &format = depthStencilRenderTarget->format->textureFormat();
VkImageAspectFlags aspectFlags = (format.depthBits > 0 ? VK_IMAGE_ASPECT_DEPTH_BIT : 0) | VkImageAspectFlags aspectFlags = (format.depthBits > 0 ? VK_IMAGE_ASPECT_DEPTH_BIT : 0) |
(format.stencilBits > 0 ? VK_IMAGE_ASPECT_STENCIL_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, aspectFlags, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
commandBuffer); commandBuffer);
node->appendDepthStencilRenderTarget(currentSerial, renderTarget); node->appendDepthStencilRenderTarget(currentSerial, depthStencilRenderTarget);
attachmentClearValues.emplace_back(contextVk->getClearDepthStencilValue()); attachmentClearValues.emplace_back(contextVk->getClearDepthStencilValue());
} }
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#define LIBANGLE_RENDERER_VULKAN_FRAMEBUFFERVK_H_ #define LIBANGLE_RENDERER_VULKAN_FRAMEBUFFERVK_H_
#include "libANGLE/renderer/FramebufferImpl.h" #include "libANGLE/renderer/FramebufferImpl.h"
#include "libANGLE/renderer/RenderTargetCache.h"
#include "libANGLE/renderer/vulkan/vk_cache_utils.h" #include "libANGLE/renderer/vulkan/vk_cache_utils.h"
namespace rx namespace rx
...@@ -102,6 +103,7 @@ class FramebufferVk : public FramebufferImpl, public ResourceVk ...@@ -102,6 +103,7 @@ class FramebufferVk : public FramebufferImpl, public ResourceVk
Optional<vk::RenderPassDesc> mRenderPassDesc; Optional<vk::RenderPassDesc> mRenderPassDesc;
vk::Framebuffer mFramebuffer; vk::Framebuffer mFramebuffer;
Serial mLastRenderNodeSerial; Serial mLastRenderNodeSerial;
RenderTargetCache<RenderTargetVk> mRenderTargetCache;
}; };
} // namespace rx } // namespace rx
......
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