Commit f13689b6 by Charlie Lao Committed by Commit Bot

Vulkan: Use renderpass' finalLayout to transit to ImageLayout::Present

This detects the last renderpass is actually rendering to the image we are going to present and this is the very last renderpass to that image. We use finalLayout of the renderpass to do layout transition to VK_IMAGE_LAYOUT_PRESENT_SRC_KHR instead of a standalone barrier call. Bug: b/153885625 Change-Id: Ifc17c77a1ba12f22c9d6038775f3e254c35655ca Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2155250 Commit-Queue: Charlie Lao <cclao@google.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent ebc4846d
...@@ -2362,6 +2362,30 @@ angle::Result ContextVk::clearWithRenderPassOp( ...@@ -2362,6 +2362,30 @@ angle::Result ContextVk::clearWithRenderPassOp(
return angle::Result::Continue; return angle::Result::Continue;
} }
void ContextVk::optimizeRenderPassForPresent(VkFramebuffer framebufferHandle)
{
if (!mRenderPassCommands.started())
{
return;
}
if (framebufferHandle != mRenderPassCommands.getFramebufferHandle())
{
return;
}
RenderTargetVk *color0RenderTarget = mDrawFramebuffer->getColorDrawRenderTarget(0);
if (!color0RenderTarget)
{
return;
}
// Use finalLayout instead of extra barrier for layout change to present
vk::ImageHelper &image = color0RenderTarget->getImage();
image.setCurrentImageLayout(vk::ImageLayout::Present);
mRenderPassCommands.updateRenderPassAttachmentFinalLayout(0, image.getCurrentImageLayout());
}
gl::GraphicsResetStatus ContextVk::getResetStatus() gl::GraphicsResetStatus ContextVk::getResetStatus()
{ {
if (mRenderer->isDeviceLost()) if (mRenderer->isDeviceLost())
......
...@@ -187,35 +187,41 @@ class RenderPassCommandBuffer final : public CommandBufferHelper ...@@ -187,35 +187,41 @@ class RenderPassCommandBuffer final : public CommandBufferHelper
void clearRenderPassColorAttachment(size_t attachmentIndex, const VkClearColorValue &clearValue) void clearRenderPassColorAttachment(size_t attachmentIndex, const VkClearColorValue &clearValue)
{ {
mAttachmentOps[attachmentIndex].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; SetBitField(mAttachmentOps[attachmentIndex].loadOp, VK_ATTACHMENT_LOAD_OP_CLEAR);
mClearValues[attachmentIndex].color = clearValue; mClearValues[attachmentIndex].color = clearValue;
} }
void clearRenderPassDepthAttachment(size_t attachmentIndex, float depth) void clearRenderPassDepthAttachment(size_t attachmentIndex, float depth)
{ {
mAttachmentOps[attachmentIndex].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; SetBitField(mAttachmentOps[attachmentIndex].loadOp, VK_ATTACHMENT_LOAD_OP_CLEAR);
mClearValues[attachmentIndex].depthStencil.depth = depth; SetBitField(mClearValues[attachmentIndex].depthStencil.depth, depth);
} }
void clearRenderPassStencilAttachment(size_t attachmentIndex, uint32_t stencil) void clearRenderPassStencilAttachment(size_t attachmentIndex, uint32_t stencil)
{ {
mAttachmentOps[attachmentIndex].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; SetBitField(mAttachmentOps[attachmentIndex].stencilLoadOp, VK_ATTACHMENT_LOAD_OP_CLEAR);
mClearValues[attachmentIndex].depthStencil.stencil = stencil; SetBitField(mClearValues[attachmentIndex].depthStencil.stencil, stencil);
} }
void invalidateRenderPassColorAttachment(size_t attachmentIndex) void invalidateRenderPassColorAttachment(size_t attachmentIndex)
{ {
mAttachmentOps[attachmentIndex].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; SetBitField(mAttachmentOps[attachmentIndex].storeOp, VK_ATTACHMENT_STORE_OP_DONT_CARE);
} }
void invalidateRenderPassDepthAttachment(size_t attachmentIndex) void invalidateRenderPassDepthAttachment(size_t attachmentIndex)
{ {
mAttachmentOps[attachmentIndex].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; SetBitField(mAttachmentOps[attachmentIndex].storeOp, VK_ATTACHMENT_STORE_OP_DONT_CARE);
} }
void invalidateRenderPassStencilAttachment(size_t attachmentIndex) void invalidateRenderPassStencilAttachment(size_t attachmentIndex)
{ {
mAttachmentOps[attachmentIndex].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; SetBitField(mAttachmentOps[attachmentIndex].stencilStoreOp,
VK_ATTACHMENT_STORE_OP_DONT_CARE);
}
void updateRenderPassAttachmentFinalLayout(size_t attachmentIndex, vk::ImageLayout finalLayout)
{
SetBitField(mAttachmentOps[attachmentIndex].finalLayout, finalLayout);
} }
const gl::Rectangle &getRenderArea() const { return mRenderArea; } const gl::Rectangle &getRenderArea() const { return mRenderArea; }
...@@ -236,6 +242,8 @@ class RenderPassCommandBuffer final : public CommandBufferHelper ...@@ -236,6 +242,8 @@ class RenderPassCommandBuffer final : public CommandBufferHelper
return count; return count;
} }
VkFramebuffer getFramebufferHandle() const { return mFramebuffer.getHandle(); }
private: private:
void addRenderPassCommandDiagnostics(ContextVk *contextVk); void addRenderPassCommandDiagnostics(ContextVk *contextVk);
...@@ -497,6 +505,8 @@ class ContextVk : public ContextImpl, public vk::Context ...@@ -497,6 +505,8 @@ class ContextVk : public ContextImpl, public vk::Context
void invalidateGraphicsDescriptorSet(uint32_t usedDescriptorSet); void invalidateGraphicsDescriptorSet(uint32_t usedDescriptorSet);
void invalidateComputeDescriptorSet(uint32_t usedDescriptorSet); void invalidateComputeDescriptorSet(uint32_t usedDescriptorSet);
void optimizeRenderPassForPresent(VkFramebuffer framebufferHandle);
vk::DynamicQueryPool *getQueryPool(gl::QueryType queryType); vk::DynamicQueryPool *getQueryPool(gl::QueryType queryType);
const VkClearValue &getClearColorValue() const; const VkClearValue &getClearColorValue() const;
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#define LIBANGLE_RENDERER_VULKAN_OVERLAYVK_H_ #define LIBANGLE_RENDERER_VULKAN_OVERLAYVK_H_
#include "common/angleutils.h" #include "common/angleutils.h"
#include "libANGLE/Overlay.h"
#include "libANGLE/renderer/OverlayImpl.h" #include "libANGLE/renderer/OverlayImpl.h"
#include "libANGLE/renderer/vulkan/vk_helpers.h" #include "libANGLE/renderer/vulkan/vk_helpers.h"
...@@ -31,6 +32,8 @@ class OverlayVk : public OverlayImpl ...@@ -31,6 +32,8 @@ class OverlayVk : public OverlayImpl
vk::ImageHelper *imageToPresent, vk::ImageHelper *imageToPresent,
const vk::ImageView *imageToPresentView); const vk::ImageView *imageToPresentView);
uint32_t getEnabledWidgetCount() const { return mState.getEnabledWidgetCount(); }
private: private:
angle::Result createFont(ContextVk *contextVk); angle::Result createFont(ContextVk *contextVk);
angle::Result cullWidgets(ContextVk *contextVk); angle::Result cullWidgets(ContextVk *contextVk);
......
...@@ -1131,7 +1131,18 @@ angle::Result WindowSurfaceVk::present(ContextVk *contextVk, ...@@ -1131,7 +1131,18 @@ angle::Result WindowSurfaceVk::present(ContextVk *contextVk,
} }
} }
SwapchainImage &image = mSwapchainImages[mCurrentSwapchainImageIndex]; SwapchainImage &image = mSwapchainImages[mCurrentSwapchainImageIndex];
vk::Framebuffer &currentFramebuffer = mSwapchainImages[mCurrentSwapchainImageIndex].framebuffer;
updateOverlay(contextVk);
bool overlayHasWidget = overlayHasEnabledWidget(contextVk);
// We can only do present related optimization if this is the last renderpass that touches the
// swapchain image. MSAA resolve and overlay will insert another renderpass which disqualifies
// the optimization.
if (!mColorImageMS.valid() && !overlayHasWidget && currentFramebuffer.valid())
{
contextVk->optimizeRenderPassForPresent(currentFramebuffer.getHandle());
}
vk::CommandBuffer *commandBuffer = nullptr; vk::CommandBuffer *commandBuffer = nullptr;
ANGLE_TRY(contextVk->endRenderPassAndGetCommandBuffer(&commandBuffer)); ANGLE_TRY(contextVk->endRenderPassAndGetCommandBuffer(&commandBuffer));
...@@ -1158,8 +1169,12 @@ angle::Result WindowSurfaceVk::present(ContextVk *contextVk, ...@@ -1158,8 +1169,12 @@ angle::Result WindowSurfaceVk::present(ContextVk *contextVk,
mColorImageMS.resolve(&image.image, resolveRegion, commandBuffer); mColorImageMS.resolve(&image.image, resolveRegion, commandBuffer);
} }
ANGLE_TRY(updateAndDrawOverlay(contextVk, &image)); if (overlayHasWidget)
{
ANGLE_TRY(drawOverlay(contextVk, &image));
}
// This does nothing if it already in the requested layout
image.image.changeLayout(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::Present, commandBuffer); image.image.changeLayout(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::Present, commandBuffer);
// Knowing that the kSwapHistorySize'th submission ago has finished, we can know that the // Knowing that the kSwapHistorySize'th submission ago has finished, we can know that the
...@@ -1532,8 +1547,7 @@ angle::Result WindowSurfaceVk::initializeContents(const gl::Context *context, ...@@ -1532,8 +1547,7 @@ angle::Result WindowSurfaceVk::initializeContents(const gl::Context *context,
return angle::Result::Continue; return angle::Result::Continue;
} }
angle::Result WindowSurfaceVk::updateAndDrawOverlay(ContextVk *contextVk, void WindowSurfaceVk::updateOverlay(ContextVk *contextVk) const
SwapchainImage *image) const
{ {
const gl::OverlayType *overlay = contextVk->getOverlay(); const gl::OverlayType *overlay = contextVk->getOverlay();
OverlayVk *overlayVk = vk::GetImpl(overlay); OverlayVk *overlayVk = vk::GetImpl(overlay);
...@@ -1541,7 +1555,7 @@ angle::Result WindowSurfaceVk::updateAndDrawOverlay(ContextVk *contextVk, ...@@ -1541,7 +1555,7 @@ angle::Result WindowSurfaceVk::updateAndDrawOverlay(ContextVk *contextVk,
// If overlay is disabled, nothing to do. // If overlay is disabled, nothing to do.
if (overlayVk == nullptr) if (overlayVk == nullptr)
{ {
return angle::Result::Continue; return;
} }
RendererVk *rendererVk = contextVk->getRenderer(); RendererVk *rendererVk = contextVk->getRenderer();
...@@ -1556,6 +1570,19 @@ angle::Result WindowSurfaceVk::updateAndDrawOverlay(ContextVk *contextVk, ...@@ -1556,6 +1570,19 @@ angle::Result WindowSurfaceVk::updateAndDrawOverlay(ContextVk *contextVk,
overlay->getCountWidget(gl::WidgetId::VulkanValidationMessageCount) overlay->getCountWidget(gl::WidgetId::VulkanValidationMessageCount)
->add(validationMessageCount); ->add(validationMessageCount);
} }
}
ANGLE_INLINE bool WindowSurfaceVk::overlayHasEnabledWidget(ContextVk *contextVk) const
{
const gl::OverlayType *overlay = contextVk->getOverlay();
OverlayVk *overlayVk = vk::GetImpl(overlay);
return overlayVk && overlayVk->getEnabledWidgetCount() > 0;
}
angle::Result WindowSurfaceVk::drawOverlay(ContextVk *contextVk, SwapchainImage *image) const
{
const gl::OverlayType *overlay = contextVk->getOverlay();
OverlayVk *overlayVk = vk::GetImpl(overlay);
// Draw overlay // Draw overlay
const vk::ImageView *imageView = nullptr; const vk::ImageView *imageView = nullptr;
......
...@@ -264,7 +264,9 @@ class WindowSurfaceVk : public SurfaceVk ...@@ -264,7 +264,9 @@ class WindowSurfaceVk : public SurfaceVk
const void *pNextChain, const void *pNextChain,
bool *presentOutOfDate); bool *presentOutOfDate);
angle::Result updateAndDrawOverlay(ContextVk *contextVk, impl::SwapchainImage *image) const; void updateOverlay(ContextVk *contextVk) const;
bool overlayHasEnabledWidget(ContextVk *contextVk) const;
angle::Result drawOverlay(ContextVk *contextVk, impl::SwapchainImage *image) const;
angle::Result newPresentSemaphore(vk::Context *context, vk::Semaphore *semaphoreOut); angle::Result newPresentSemaphore(vk::Context *context, vk::Semaphore *semaphoreOut);
......
...@@ -820,6 +820,7 @@ class ImageHelper final : public Resource, public angle::Subject ...@@ -820,6 +820,7 @@ class ImageHelper final : public Resource, public angle::Subject
const Format &getFormat() const { return *mFormat; } const Format &getFormat() const { return *mFormat; }
GLint getSamples() const { return mSamples; } GLint getSamples() const { return mSamples; }
void setCurrentImageLayout(ImageLayout newLayout) { mCurrentLayout = newLayout; }
ImageLayout getCurrentImageLayout() const { return mCurrentLayout; } ImageLayout getCurrentImageLayout() const { return mCurrentLayout; }
VkImageLayout getCurrentLayout() const; VkImageLayout getCurrentLayout() 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