From a1b5d7e1eb10cdcda6ee173a4a40f9225e318633 Mon Sep 17 00:00:00 2001 From: Greg Daniel Date: Thu, 17 Dec 2020 10:36:58 -0500 Subject: [PATCH] Update creating GrProgramDesc for vulkan resolve loading. Bug: skia:10979 Change-Id: If17e91886ebaaa74ea312e046d05b0623000e0bd Reviewed-on: https://skia-review.googlesource.com/c/skia/+/341380 Commit-Queue: Greg Daniel Reviewed-by: Robert Phillips --- src/gpu/vk/GrVkCaps.cpp | 10 +++- src/gpu/vk/GrVkCaps.h | 82 +++++++++++++++++++++------------ src/gpu/vk/GrVkGpu.cpp | 5 +- src/gpu/vk/GrVkRenderTarget.cpp | 7 +++ 4 files changed, 72 insertions(+), 32 deletions(-) diff --git a/src/gpu/vk/GrVkCaps.cpp b/src/gpu/vk/GrVkCaps.cpp index 1ee181ee31..5072b76a96 100644 --- a/src/gpu/vk/GrVkCaps.cpp +++ b/src/gpu/vk/GrVkCaps.cpp @@ -1729,12 +1729,20 @@ GrProgramDesc GrVkCaps::makeDesc(GrRenderTarget* rt, const GrProgramInfo& progra selfDepFlags |= GrVkRenderPass::SelfDependencyFlags::kForInputAttachment; } + bool needsResolve = programInfo.targetSupportsVkResolveLoad() && + this->preferDiscardableMSAAAttachment(); + GrVkRenderPass::LoadFromResolve loadFromResolve = GrVkRenderPass::LoadFromResolve::kNo; + if (needsResolve && programInfo.colorLoadOp() == GrLoadOp::kLoad) { + loadFromResolve = GrVkRenderPass::LoadFromResolve::kLoad; + } if (rt) { GrVkRenderTarget* vkRT = (GrVkRenderTarget*) rt; - bool needsResolve = false; + SkASSERT(!needsResolve || + (vkRT->resolveAttachmentView() && vkRT->supportsInputAttachmentUsage())); + bool needsStencil = programInfo.numStencilSamples() || programInfo.isStencilEnabled(); // TODO: support failure in getSimpleRenderPass const GrVkRenderPass* rp = vkRT->getSimpleRenderPass(needsResolve, needsStencil, diff --git a/src/gpu/vk/GrVkCaps.h b/src/gpu/vk/GrVkCaps.h index 2f32cb7d4d..1a0f556d47 100644 --- a/src/gpu/vk/GrVkCaps.h +++ b/src/gpu/vk/GrVkCaps.h @@ -25,10 +25,14 @@ public: * Creates a GrVkCaps that is set such that nothing is supported. The init function should * be called to fill out the caps. */ - GrVkCaps(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface, - VkPhysicalDevice device, const VkPhysicalDeviceFeatures2& features, - uint32_t instanceVersion, uint32_t physicalDeviceVersion, - const GrVkExtensions& extensions, GrProtected isProtected = GrProtected::kNo); + GrVkCaps(const GrContextOptions& contextOptions, + const GrVkInterface* vkInterface, + VkPhysicalDevice device, + const VkPhysicalDeviceFeatures2& features, + uint32_t instanceVersion, + uint32_t physicalDeviceVersion, + const GrVkExtensions& extensions, + GrProtected isProtected = GrProtected::kNo); bool isFormatSRGB(const GrBackendFormat&) const override; @@ -37,7 +41,8 @@ public: bool isFormatCopyable(const GrBackendFormat&) const override { return true; } - bool isFormatAsColorTypeRenderable(GrColorType ct, const GrBackendFormat& format, + bool isFormatAsColorTypeRenderable(GrColorType ct, + const GrBackendFormat& format, int sampleCount = 1) const override; bool isFormatRenderable(const GrBackendFormat& format, int sampleCount) const override; bool isFormatRenderable(VkFormat, int sampleCount) const; @@ -73,9 +78,7 @@ public: // Sometimes calls to QueueWaitIdle return before actually signalling the fences // on the command buffers even though they have completed. This causes an assert to fire when // destroying the command buffers. Therefore we add a sleep to make sure the fence signals. - bool mustSleepOnTearDown() const { - return fMustSleepOnTearDown; - } + bool mustSleepOnTearDown() const { return fMustSleepOnTearDown; } // Returns true if we should always make dedicated allocations for VkImages. bool shouldAlwaysUseDedicatedImageMemory() const { @@ -83,30 +86,26 @@ public: } // Always use a transfer buffer instead of vkCmdUpdateBuffer to upload data to a VkBuffer. - bool avoidUpdateBuffers() const { - return fAvoidUpdateBuffers; - } + bool avoidUpdateBuffers() const { return fAvoidUpdateBuffers; } /** * Returns both a supported and most preferred stencil format to use in draws. */ - VkFormat preferredStencilFormat() const { - return fPreferredStencilFormat; - } + VkFormat preferredStencilFormat() const { return fPreferredStencilFormat; } // Returns total number of bits used by stencil + depth + padding static int GetStencilFormatTotalBitCount(VkFormat format) { switch (format) { - case VK_FORMAT_S8_UINT: - return 8; - case VK_FORMAT_D24_UNORM_S8_UINT: - return 32; - case VK_FORMAT_D32_SFLOAT_S8_UINT: - // can optionally have 24 unused bits at the end so we assume the total bits is 64. - return 64; - default: - SkASSERT(false); - return 0; + case VK_FORMAT_S8_UINT: + return 8; + case VK_FORMAT_D24_UNORM_S8_UINT: + return 32; + case VK_FORMAT_D32_SFLOAT_S8_UINT: + // can optionally have 24 unused bits at the end so we assume the total bits is 64. + return 64; + default: + SkASSERT(false); + return 0; } } @@ -168,15 +167,28 @@ public: * the surface is not a render target, otherwise it is the number of samples in the render * target. */ - bool canCopyImage(VkFormat dstFormat, int dstSampleCnt, bool dstHasYcbcr, - VkFormat srcFormat, int srcSamplecnt, bool srcHasYcbcr) const; + bool canCopyImage(VkFormat dstFormat, + int dstSampleCnt, + bool dstHasYcbcr, + VkFormat srcFormat, + int srcSamplecnt, + bool srcHasYcbcr) const; - bool canCopyAsBlit(VkFormat dstConfig, int dstSampleCnt, bool dstIsLinear, bool dstHasYcbcr, - VkFormat srcConfig, int srcSampleCnt, bool srcIsLinear, + bool canCopyAsBlit(VkFormat dstConfig, + int dstSampleCnt, + bool dstIsLinear, + bool dstHasYcbcr, + VkFormat srcConfig, + int srcSampleCnt, + bool srcIsLinear, bool srcHasYcbcr) const; - bool canCopyAsResolve(VkFormat dstConfig, int dstSampleCnt, bool dstHasYcbcr, - VkFormat srcConfig, int srcSamplecnt, bool srcHasYcbcr) const; + bool canCopyAsResolve(VkFormat dstConfig, + int dstSampleCnt, + bool dstHasYcbcr, + VkFormat srcConfig, + int srcSamplecnt, + bool srcHasYcbcr) const; GrBackendFormat getBackendFormatFromCompressionType(SkImage::CompressionType) const override; @@ -200,6 +212,14 @@ public: GrInternalSurfaceFlags getExtraSurfaceFlagsForDeferredRT() const override; + // If true then when doing MSAA draws, we will prefer to discard the msaa attachment on load + // and stores. The use of this feature for specific draws depends on the render target having a + // resolve attachment, and if we need to load previous data the resolve attachment must be + // usable as an input attachment. Otherwise we will just write out and store the msaa attachment + // like normal. + // This flag is similar to enabling gl render to texture for msaa rendering. + bool preferDiscardableMSAAAttachment() const { return fPreferDiscardableMSAAAttachment; } + #if GR_TEST_UTILS std::vector getTestingCombinations() const override; #endif @@ -340,6 +360,8 @@ private: bool fPreferCachedCpuMemory = true; + bool fPreferDiscardableMSAAAttachment = false; + using INHERITED = GrCaps; }; diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp index 21bb4ce697..9b7234cf7e 100644 --- a/src/gpu/vk/GrVkGpu.cpp +++ b/src/gpu/vk/GrVkGpu.cpp @@ -1955,7 +1955,10 @@ bool GrVkGpu::compile(const GrProgramDesc& desc, const GrProgramInfo& programInf } GrVkRenderPass::LoadFromResolve loadFromResolve = GrVkRenderPass::LoadFromResolve::kNo; - + if (programInfo.targetSupportsVkResolveLoad() && programInfo.colorLoadOp() == GrLoadOp::kLoad && + this->vkCaps().preferDiscardableMSAAAttachment()) { + loadFromResolve = GrVkRenderPass::LoadFromResolve::kLoad; + } sk_sp renderPass(this->resourceProvider().findCompatibleRenderPass( &attachmentsDescriptor, attachmentFlags, selfDepFlags, loadFromResolve)); if (!renderPass) { diff --git a/src/gpu/vk/GrVkRenderTarget.cpp b/src/gpu/vk/GrVkRenderTarget.cpp index 62c806d12c..32dbb3f026 100644 --- a/src/gpu/vk/GrVkRenderTarget.cpp +++ b/src/gpu/vk/GrVkRenderTarget.cpp @@ -422,6 +422,13 @@ void GrVkRenderTarget::ReconstructAttachmentsDescriptor(const GrVkCaps& vkCaps, *flags = GrVkRenderPass::kColor_AttachmentFlag; uint32_t attachmentCount = 1; + if (programInfo.targetSupportsVkResolveLoad() && vkCaps.preferDiscardableMSAAAttachment()) { + desc->fResolve.fFormat = desc->fColor.fFormat; + desc->fResolve.fSamples = 1; + *flags |= GrVkRenderPass::kResolve_AttachmentFlag; + ++attachmentCount; + } + SkASSERT(!programInfo.isStencilEnabled() || programInfo.numStencilSamples()); if (programInfo.numStencilSamples()) { VkFormat stencilFormat = vkCaps.preferredStencilFormat();