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(
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()
{
if (mRenderer->isDeviceLost())
......
......@@ -187,35 +187,41 @@ class RenderPassCommandBuffer final : public CommandBufferHelper
void clearRenderPassColorAttachment(size_t attachmentIndex, const VkClearColorValue &clearValue)
{
mAttachmentOps[attachmentIndex].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
mClearValues[attachmentIndex].color = clearValue;
SetBitField(mAttachmentOps[attachmentIndex].loadOp, VK_ATTACHMENT_LOAD_OP_CLEAR);
mClearValues[attachmentIndex].color = clearValue;
}
void clearRenderPassDepthAttachment(size_t attachmentIndex, float depth)
{
mAttachmentOps[attachmentIndex].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
mClearValues[attachmentIndex].depthStencil.depth = depth;
SetBitField(mAttachmentOps[attachmentIndex].loadOp, VK_ATTACHMENT_LOAD_OP_CLEAR);
SetBitField(mClearValues[attachmentIndex].depthStencil.depth, depth);
}
void clearRenderPassStencilAttachment(size_t attachmentIndex, uint32_t stencil)
{
mAttachmentOps[attachmentIndex].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
mClearValues[attachmentIndex].depthStencil.stencil = stencil;
SetBitField(mAttachmentOps[attachmentIndex].stencilLoadOp, VK_ATTACHMENT_LOAD_OP_CLEAR);
SetBitField(mClearValues[attachmentIndex].depthStencil.stencil, stencil);
}
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)
{
mAttachmentOps[attachmentIndex].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
SetBitField(mAttachmentOps[attachmentIndex].storeOp, VK_ATTACHMENT_STORE_OP_DONT_CARE);
}
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; }
......@@ -236,6 +242,8 @@ class RenderPassCommandBuffer final : public CommandBufferHelper
return count;
}
VkFramebuffer getFramebufferHandle() const { return mFramebuffer.getHandle(); }
private:
void addRenderPassCommandDiagnostics(ContextVk *contextVk);
......@@ -497,6 +505,8 @@ class ContextVk : public ContextImpl, public vk::Context
void invalidateGraphicsDescriptorSet(uint32_t usedDescriptorSet);
void invalidateComputeDescriptorSet(uint32_t usedDescriptorSet);
void optimizeRenderPassForPresent(VkFramebuffer framebufferHandle);
vk::DynamicQueryPool *getQueryPool(gl::QueryType queryType);
const VkClearValue &getClearColorValue() const;
......
......@@ -11,6 +11,7 @@
#define LIBANGLE_RENDERER_VULKAN_OVERLAYVK_H_
#include "common/angleutils.h"
#include "libANGLE/Overlay.h"
#include "libANGLE/renderer/OverlayImpl.h"
#include "libANGLE/renderer/vulkan/vk_helpers.h"
......@@ -31,6 +32,8 @@ class OverlayVk : public OverlayImpl
vk::ImageHelper *imageToPresent,
const vk::ImageView *imageToPresentView);
uint32_t getEnabledWidgetCount() const { return mState.getEnabledWidgetCount(); }
private:
angle::Result createFont(ContextVk *contextVk);
angle::Result cullWidgets(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;
ANGLE_TRY(contextVk->endRenderPassAndGetCommandBuffer(&commandBuffer));
......@@ -1158,8 +1169,12 @@ angle::Result WindowSurfaceVk::present(ContextVk *contextVk,
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);
// 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,
return angle::Result::Continue;
}
angle::Result WindowSurfaceVk::updateAndDrawOverlay(ContextVk *contextVk,
SwapchainImage *image) const
void WindowSurfaceVk::updateOverlay(ContextVk *contextVk) const
{
const gl::OverlayType *overlay = contextVk->getOverlay();
OverlayVk *overlayVk = vk::GetImpl(overlay);
......@@ -1541,7 +1555,7 @@ angle::Result WindowSurfaceVk::updateAndDrawOverlay(ContextVk *contextVk,
// If overlay is disabled, nothing to do.
if (overlayVk == nullptr)
{
return angle::Result::Continue;
return;
}
RendererVk *rendererVk = contextVk->getRenderer();
......@@ -1556,6 +1570,19 @@ angle::Result WindowSurfaceVk::updateAndDrawOverlay(ContextVk *contextVk,
overlay->getCountWidget(gl::WidgetId::VulkanValidationMessageCount)
->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
const vk::ImageView *imageView = nullptr;
......
......@@ -264,7 +264,9 @@ class WindowSurfaceVk : public SurfaceVk
const void *pNextChain,
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);
......
......@@ -820,6 +820,7 @@ class ImageHelper final : public Resource, public angle::Subject
const Format &getFormat() const { return *mFormat; }
GLint getSamples() const { return mSamples; }
void setCurrentImageLayout(ImageLayout newLayout) { mCurrentLayout = newLayout; }
ImageLayout getCurrentImageLayout() const { return mCurrentLayout; }
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