Update GrVkRenderPasses to be created to support both input attachments and adv blend.

Bug: skia:10409
Change-Id: I90c83e03616b76adb887c087f7f22941bd776d8c
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/316356
Reviewed-by: Jim Van Verth <jvanverth@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
Commit-Queue: Greg Daniel <egdaniel@google.com>
This commit is contained in:
Greg Daniel 2020-09-14 10:36:43 -04:00 committed by Skia Commit-Bot
parent c1cc1d85ab
commit 2177436cf8
24 changed files with 263 additions and 334 deletions

View File

@ -360,7 +360,7 @@ public:
const GrOpsRenderPass::LoadAndStoreInfo&,
const GrOpsRenderPass::StencilLoadAndStoreInfo&,
const SkTArray<GrSurfaceProxy*, true>& sampledProxies,
bool usesXferBarriers) = 0;
GrXferBarrierFlags renderPassXferBarriers) = 0;
// Called by GrDrawingManager when flushing.
// Provides a hook for post-flush actions (e.g. Vulkan command buffer submits). This will also

View File

@ -469,7 +469,7 @@ static GrOpsRenderPass* create_render_pass(
const SkIRect& bounds, GrLoadOp colorLoadOp, const SkPMColor4f& loadClearColor,
GrLoadOp stencilLoadOp, GrStoreOp stencilStoreOp,
const SkTArray<GrSurfaceProxy*, true>& sampledProxies,
bool usesXferBarriers) {
GrXferBarrierFlags renderPassXferBarriers) {
const GrOpsRenderPass::LoadAndStoreInfo kColorLoadStoreInfo {
colorLoadOp,
GrStoreOp::kStore,
@ -488,7 +488,7 @@ static GrOpsRenderPass* create_render_pass(
return gpu->getOpsRenderPass(rt, stencil, origin, bounds,
kColorLoadStoreInfo, stencilLoadAndStoreInfo, sampledProxies,
usesXferBarriers);
renderPassXferBarriers);
}
// TODO: this is where GrOp::renderTarget is used (which is fine since it
@ -573,7 +573,8 @@ bool GrOpsTask::onExecute(GrOpFlushState* flushState) {
GrOpsRenderPass* renderPass = create_render_pass(
flushState->gpu(), proxy->peekRenderTarget(), stencil, this->target(0).origin(),
fClippedContentBounds, fColorLoadOp, fLoadClearColor, stencilLoadOp, stencilStoreOp,
fSampledProxies, fRenderPassXferBarriers != GrXferBarrierFlags::kNone);
fSampledProxies, fRenderPassXferBarriers);
if (!renderPass) {
return false;
}

View File

@ -107,7 +107,7 @@ GrOpsRenderPass* GrD3DGpu::getOpsRenderPass(
const GrOpsRenderPass::LoadAndStoreInfo& colorInfo,
const GrOpsRenderPass::StencilLoadAndStoreInfo& stencilInfo,
const SkTArray<GrSurfaceProxy*, true>& sampledProxies,
bool usesXferBarriers) {
GrXferBarrierFlags renderPassXferBarriers) {
if (!fCachedOpsRenderPass) {
fCachedOpsRenderPass.reset(new GrD3DOpsRenderPass(this));
}

View File

@ -85,7 +85,7 @@ public:
const GrOpsRenderPass::LoadAndStoreInfo&,
const GrOpsRenderPass::StencilLoadAndStoreInfo&,
const SkTArray<GrSurfaceProxy*, true>& sampledProxies,
bool usesXferBarriers) override;
GrXferBarrierFlags renderPassXferBarriers) override;
void addResourceBarriers(sk_sp<GrManagedResource> resource,
int numBarriers,

View File

@ -136,12 +136,12 @@ void GrDawnGpu::disconnect(DisconnectType type) {
///////////////////////////////////////////////////////////////////////////////
GrOpsRenderPass* GrDawnGpu::getOpsRenderPass(
GrRenderTarget* rt, GrStencilAttachment*,
GrSurfaceOrigin origin, const SkIRect& bounds,
const GrOpsRenderPass::LoadAndStoreInfo& colorInfo,
const GrOpsRenderPass::StencilLoadAndStoreInfo& stencilInfo,
const SkTArray<GrSurfaceProxy*, true>& sampledProxies,
bool usesXferBarriers) {
GrRenderTarget* rt, GrStencilAttachment*,
GrSurfaceOrigin origin, const SkIRect& bounds,
const GrOpsRenderPass::LoadAndStoreInfo& colorInfo,
const GrOpsRenderPass::StencilLoadAndStoreInfo& stencilInfo,
const SkTArray<GrSurfaceProxy*, true>& sampledProxies,
GrXferBarrierFlags renderPassXferBarriers) {
fOpsRenderPass.reset(new GrDawnOpsRenderPass(this, rt, origin, colorInfo, stencilInfo));
return fOpsRenderPass.get();
}

View File

@ -69,7 +69,7 @@ public:
const GrOpsRenderPass::LoadAndStoreInfo&,
const GrOpsRenderPass::StencilLoadAndStoreInfo&,
const SkTArray<GrSurfaceProxy*, true>& sampledProxies,
bool usesXferBarriers) override;
GrXferBarrierFlags renderPassXferBarriers) override;
SkSL::Compiler* shaderCompiler() const {
return fCompiler.get();

View File

@ -2211,7 +2211,7 @@ GrOpsRenderPass* GrGLGpu::getOpsRenderPass(
const GrOpsRenderPass::LoadAndStoreInfo& colorInfo,
const GrOpsRenderPass::StencilLoadAndStoreInfo& stencilInfo,
const SkTArray<GrSurfaceProxy*, true>& sampledProxies,
bool usesXferBarriers) {
GrXferBarrierFlags renderPassXferBarriers) {
if (!fCachedOpsRenderPass) {
fCachedOpsRenderPass = std::make_unique<GrGLOpsRenderPass>(this);
}

View File

@ -125,7 +125,7 @@ public:
const GrOpsRenderPass::LoadAndStoreInfo&,
const GrOpsRenderPass::StencilLoadAndStoreInfo&,
const SkTArray<GrSurfaceProxy*, true>& sampledProxies,
bool usesXferBarriers) override;
GrXferBarrierFlags renderPassXferBarriers) override;
void invalidateBoundRenderTarget() {
fHWBoundRenderTargetUniqueID.makeInvalid();

View File

@ -58,7 +58,7 @@ GrOpsRenderPass* GrMockGpu::getOpsRenderPass(
const GrOpsRenderPass::LoadAndStoreInfo& colorInfo,
const GrOpsRenderPass::StencilLoadAndStoreInfo&,
const SkTArray<GrSurfaceProxy*, true>& sampledProxies,
bool usesXferBarriers) {
GrXferBarrierFlags renderPassXferBarriers) {
return new GrMockOpsRenderPass(this, rt, origin, colorInfo);
}

View File

@ -32,7 +32,7 @@ public:
const GrOpsRenderPass::LoadAndStoreInfo&,
const GrOpsRenderPass::StencilLoadAndStoreInfo&,
const SkTArray<GrSurfaceProxy*, true>& sampledProxies,
bool usesXferBarriers) override;
GrXferBarrierFlags renderPassXferBarriers) override;
GrFence SK_WARN_UNUSED_RESULT insertFence() override { return 0; }
bool waitFence(GrFence) override { return true; }

View File

@ -89,7 +89,7 @@ public:
const GrOpsRenderPass::LoadAndStoreInfo&,
const GrOpsRenderPass::StencilLoadAndStoreInfo&,
const SkTArray<GrSurfaceProxy*, true>& sampledProxies,
bool usesXferBarriers) override;
GrXferBarrierFlags renderPassXferBarriers) override;
SkSL::Compiler* shaderCompiler() const { return fCompiler.get(); }

View File

@ -176,7 +176,7 @@ GrOpsRenderPass* GrMtlGpu::getOpsRenderPass(
const GrOpsRenderPass::LoadAndStoreInfo& colorInfo,
const GrOpsRenderPass::StencilLoadAndStoreInfo& stencilInfo,
const SkTArray<GrSurfaceProxy*, true>& sampledProxies,
bool usesXferBarriers) {
GrXferBarrierFlags renderPassXferBarriers) {
return new GrMtlOpsRenderPass(this, renderTarget, origin, colorInfo, stencilInfo);
}

View File

@ -1735,16 +1735,20 @@ GrProgramDesc GrVkCaps::makeDesc(GrRenderTarget* rt, const GrProgramInfo& progra
// GrVkPipelineStateBuilder.cpp).
b.add32(GrVkGpu::kShader_PersistentCacheKeyType);
auto barrierType = programInfo.pipeline().xferBarrierType(*this);
bool usesXferBarriers = barrierType == kBlend_GrXferBarrierType ||
barrierType == kTexture_GrXferBarrierType;
GrVkRenderPass::SelfDependencyFlags selfDepFlags = GrVkRenderPass::SelfDependencyFlags::kNone;
if (programInfo.renderPassBarriers() & GrXferBarrierFlags::kBlend) {
selfDepFlags |= GrVkRenderPass::SelfDependencyFlags::kForNonCoherentAdvBlend;
}
if (programInfo.renderPassBarriers() & GrXferBarrierFlags::kTexture) {
selfDepFlags |= GrVkRenderPass::SelfDependencyFlags::kForInputAttachment;
}
if (rt) {
GrVkRenderTarget* vkRT = (GrVkRenderTarget*) rt;
bool needsStencil = programInfo.numStencilSamples() || programInfo.isStencilEnabled();
// TODO: support failure in getSimpleRenderPass
const GrVkRenderPass* rp = vkRT->getSimpleRenderPass(needsStencil, usesXferBarriers);
const GrVkRenderPass* rp = vkRT->getSimpleRenderPass(needsStencil, selfDepFlags);
SkASSERT(rp);
rp->genKey(&b);
@ -1757,7 +1761,7 @@ GrProgramDesc GrVkCaps::makeDesc(GrRenderTarget* rt, const GrProgramInfo& progra
GrVkRenderTarget::ReconstructAttachmentsDescriptor(*this, programInfo,
&attachmentsDescriptor,
&attachmentFlags);
SkASSERT(rp->isCompatible(attachmentsDescriptor, attachmentFlags, usesXferBarriers));
SkASSERT(rp->isCompatible(attachmentsDescriptor, attachmentFlags, selfDepFlags));
}
#endif
} else {
@ -1770,7 +1774,7 @@ GrProgramDesc GrVkCaps::makeDesc(GrRenderTarget* rt, const GrProgramInfo& progra
// kExternal_AttachmentFlag is only set for wrapped secondary command buffers - which
// will always go through the above 'rt' path (i.e., we can always pass 0 as the final
// parameter to GenKey).
GrVkRenderPass::GenKey(&b, attachmentFlags, attachmentsDescriptor, usesXferBarriers, 0);
GrVkRenderPass::GenKey(&b, attachmentFlags, attachmentsDescriptor, selfDepFlags, 0);
}
GrStencilSettings stencil = programInfo.nonGLStencilSettings();

View File

@ -455,10 +455,10 @@ bool GrVkPrimaryCommandBuffer::beginRenderPass(GrVkGpu* gpu,
bool forSecondaryCB) {
SkASSERT(fIsActive);
SkASSERT(!fActiveRenderPass);
SkASSERT(renderPass->isCompatible(*target, renderPass->hasSelfDependency()));
SkASSERT(renderPass->isCompatible(*target, renderPass->selfDependencyFlags()));
const GrVkFramebuffer* framebuffer = target->getFramebuffer(
renderPass->hasStencilAttachment(), renderPass->hasSelfDependency());
const GrVkFramebuffer* framebuffer = target->getFramebuffer(renderPass->hasStencilAttachment(),
renderPass->selfDependencyFlags());
if (!framebuffer) {
return false;
}
@ -486,7 +486,7 @@ bool GrVkPrimaryCommandBuffer::beginRenderPass(GrVkGpu* gpu,
fActiveRenderPass = renderPass;
this->addResource(renderPass);
target->addResources(*this, renderPass->hasStencilAttachment(),
renderPass->hasSelfDependency());
renderPass->selfDependencyFlags());
return true;
}

View File

@ -326,13 +326,13 @@ GrOpsRenderPass* GrVkGpu::getOpsRenderPass(
const GrOpsRenderPass::LoadAndStoreInfo& colorInfo,
const GrOpsRenderPass::StencilLoadAndStoreInfo& stencilInfo,
const SkTArray<GrSurfaceProxy*, true>& sampledProxies,
bool usesXferBarriers) {
GrXferBarrierFlags renderPassXferBarriers) {
if (!fCachedOpsRenderPass) {
fCachedOpsRenderPass = std::make_unique<GrVkOpsRenderPass>(this);
}
if (!fCachedOpsRenderPass->set(rt, stencil, origin, bounds, colorInfo, stencilInfo,
sampledProxies, usesXferBarriers)) {
sampledProxies, renderPassXferBarriers)) {
return nullptr;
}
return fCachedOpsRenderPass.get();
@ -1939,13 +1939,16 @@ bool GrVkGpu::compile(const GrProgramDesc& desc, const GrProgramInfo& programInf
GrVkRenderTarget::ReconstructAttachmentsDescriptor(this->vkCaps(), programInfo,
&attachmentsDescriptor, &attachmentFlags);
auto barrierType = programInfo.pipeline().xferBarrierType(*this->caps());
bool willReadDst = barrierType == kBlend_GrXferBarrierType ||
barrierType == kTexture_GrXferBarrierType;
GrVkRenderPass::SelfDependencyFlags selfDepFlags = GrVkRenderPass::SelfDependencyFlags::kNone;
if (programInfo.renderPassBarriers() & GrXferBarrierFlags::kBlend) {
selfDepFlags |= GrVkRenderPass::SelfDependencyFlags::kForNonCoherentAdvBlend;
}
if (programInfo.renderPassBarriers() & GrXferBarrierFlags::kTexture) {
selfDepFlags |= GrVkRenderPass::SelfDependencyFlags::kForInputAttachment;
}
sk_sp<const GrVkRenderPass> renderPass(this->resourceProvider().findCompatibleRenderPass(
&attachmentsDescriptor,
attachmentFlags,
willReadDst));
&attachmentsDescriptor, attachmentFlags, selfDepFlags));
if (!renderPass) {
return false;
}

View File

@ -111,7 +111,7 @@ public:
const GrOpsRenderPass::LoadAndStoreInfo&,
const GrOpsRenderPass::StencilLoadAndStoreInfo&,
const SkTArray<GrSurfaceProxy*, true>& sampledProxies,
bool usesXferBarriers) override;
GrXferBarrierFlags renderPassXferBarriers) override;
void addBufferMemoryBarrier(const GrManagedResource*,
VkPipelineStageFlags srcStageMask,

View File

@ -105,7 +105,7 @@ bool GrVkOpsRenderPass::init(const GrOpsRenderPass::LoadAndStoreInfo& colorInfo,
}
const GrVkResourceProvider::CompatibleRPHandle& rpHandle =
vkRT->compatibleRenderPassHandle(withStencil, fUsesXferBarriers);
vkRT->compatibleRenderPassHandle(withStencil, fSelfDependencyFlags);
if (rpHandle.isValid()) {
fCurrentRenderPass = fGpu->resourceProvider().findRenderPass(rpHandle,
vkColorOps,
@ -116,7 +116,7 @@ bool GrVkOpsRenderPass::init(const GrOpsRenderPass::LoadAndStoreInfo& colorInfo,
vkStencilOps,
nullptr,
withStencil,
fUsesXferBarriers);
fSelfDependencyFlags);
}
if (!fCurrentRenderPass) {
return false;
@ -136,7 +136,7 @@ bool GrVkOpsRenderPass::init(const GrOpsRenderPass::LoadAndStoreInfo& colorInfo,
return false;
}
fCurrentSecondaryCommandBuffer->begin(
fGpu, vkRT->getFramebuffer(withStencil, fUsesXferBarriers), fCurrentRenderPass);
fGpu, vkRT->getFramebuffer(withStencil, fSelfDependencyFlags), fCurrentRenderPass);
}
if (!fGpu->beginRenderPass(fCurrentRenderPass, &vkClearColor, vkRT, fOrigin, fBounds,
@ -212,7 +212,7 @@ bool GrVkOpsRenderPass::set(GrRenderTarget* rt, GrStencilAttachment* stencil,
const GrOpsRenderPass::LoadAndStoreInfo& colorInfo,
const GrOpsRenderPass::StencilLoadAndStoreInfo& stencilInfo,
const SkTArray<GrSurfaceProxy*, true>& sampledProxies,
bool usesXferBarriers) {
GrXferBarrierFlags renderPassXferBarriers) {
SkASSERT(!fRenderTarget);
SkASSERT(fGpu == rt->getContext()->priv().getGpu());
@ -243,7 +243,12 @@ bool GrVkOpsRenderPass::set(GrRenderTarget* rt, GrStencilAttachment* stencil,
SkASSERT(bounds.isEmpty() || SkIRect::MakeWH(rt->width(), rt->height()).contains(bounds));
fBounds = bounds;
fUsesXferBarriers = usesXferBarriers;
if (renderPassXferBarriers & GrXferBarrierFlags::kBlend) {
fSelfDependencyFlags |= GrVkRenderPass::SelfDependencyFlags::kForNonCoherentAdvBlend;
}
if (renderPassXferBarriers & GrXferBarrierFlags::kTexture) {
fSelfDependencyFlags |= GrVkRenderPass::SelfDependencyFlags::kForInputAttachment;
}
if (this->wrapsSecondaryCommandBuffer()) {
return this->initWrapped();
@ -267,6 +272,8 @@ void GrVkOpsRenderPass::reset() {
fRenderTarget = nullptr;
fSelfDependencyFlags = GrVkRenderPass::SelfDependencyFlags::kNone;
#ifdef SK_DEBUG
fIsActive = false;
#endif
@ -392,7 +399,7 @@ void GrVkOpsRenderPass::addAdditionalRenderPass(bool mustUseSecondaryCommandBuff
bool withStencil = fCurrentRenderPass->hasStencilAttachment();
const GrVkResourceProvider::CompatibleRPHandle& rpHandle =
vkRT->compatibleRenderPassHandle(withStencil, fUsesXferBarriers);
vkRT->compatibleRenderPassHandle(withStencil, fSelfDependencyFlags);
SkASSERT(fCurrentRenderPass);
fCurrentRenderPass->unref();
if (rpHandle.isValid()) {
@ -405,7 +412,7 @@ void GrVkOpsRenderPass::addAdditionalRenderPass(bool mustUseSecondaryCommandBuff
vkStencilOps,
nullptr,
withStencil,
fUsesXferBarriers);
fSelfDependencyFlags);
}
if (!fCurrentRenderPass) {
return;
@ -423,7 +430,7 @@ void GrVkOpsRenderPass::addAdditionalRenderPass(bool mustUseSecondaryCommandBuff
return;
}
fCurrentSecondaryCommandBuffer->begin(
fGpu, vkRT->getFramebuffer(withStencil, fUsesXferBarriers), fCurrentRenderPass);
fGpu, vkRT->getFramebuffer(withStencil, fSelfDependencyFlags), fCurrentRenderPass);
}
// We use the same fBounds as the whole GrVkOpsRenderPass since we have no way of tracking the

View File

@ -14,10 +14,10 @@
#include "include/gpu/vk/GrVkTypes.h"
#include "src/gpu/GrColor.h"
#include "src/gpu/vk/GrVkPipelineState.h"
#include "src/gpu/vk/GrVkRenderPass.h"
class GrVkGpu;
class GrVkImage;
class GrVkRenderPass;
class GrVkRenderTarget;
class GrVkSecondaryCommandBuffer;
@ -31,12 +31,14 @@ public:
void onExecuteDrawable(std::unique_ptr<SkDrawable::GpuDrawHandler>) override;
using SelfDependencyFlags = GrVkRenderPass::SelfDependencyFlags;
bool set(GrRenderTarget*, GrStencilAttachment*,
GrSurfaceOrigin, const SkIRect& bounds,
const GrOpsRenderPass::LoadAndStoreInfo&,
const GrOpsRenderPass::StencilLoadAndStoreInfo&,
const SkTArray<GrSurfaceProxy*, true>& sampledProxies,
bool usesXferBarriers);
GrXferBarrierFlags renderPassXferBarriers);
void reset();
void submit();
@ -96,7 +98,7 @@ private:
GrVkPipelineState* fCurrentPipelineState = nullptr;
bool fCurrentCBIsEmpty = true;
SkIRect fBounds;
bool fUsesXferBarriers = false;
SelfDependencyFlags fSelfDependencyFlags = SelfDependencyFlags::kNone;
GrVkGpu* fGpu;
#ifdef SK_DEBUG

View File

@ -46,12 +46,12 @@ void setup_vk_attachment_description(VkAttachmentDescription* attachment,
GrVkRenderPass* GrVkRenderPass::CreateSimple(GrVkGpu* gpu,
AttachmentsDescriptor* attachmentsDescriptor,
AttachmentFlags attachmentFlags,
bool needsSelfDependency) {
SelfDependencyFlags selfDepFlags) {
static const GrVkRenderPass::LoadStoreOps kBasicLoadStoreOps(VK_ATTACHMENT_LOAD_OP_LOAD,
VK_ATTACHMENT_STORE_OP_STORE);
return Create(gpu, attachmentFlags, attachmentsDescriptor, kBasicLoadStoreOps,
kBasicLoadStoreOps, needsSelfDependency);
kBasicLoadStoreOps, selfDepFlags);
}
GrVkRenderPass* GrVkRenderPass::Create(GrVkGpu* gpu,
@ -60,9 +60,8 @@ GrVkRenderPass* GrVkRenderPass::Create(GrVkGpu* gpu,
const LoadStoreOps& stencilOp) {
AttachmentFlags attachmentFlags = compatibleRenderPass.fAttachmentFlags;
AttachmentsDescriptor attachmentsDescriptor = compatibleRenderPass.fAttachmentsDescriptor;
bool needsSelfDependency = compatibleRenderPass.fHasSelfDependency;
return Create(gpu, attachmentFlags, &attachmentsDescriptor, colorOp, stencilOp,
needsSelfDependency);
SelfDependencyFlags selfDepFlags = compatibleRenderPass.fSelfDepFlags;
return Create(gpu, attachmentFlags, &attachmentsDescriptor, colorOp, stencilOp, selfDepFlags);
}
GrVkRenderPass* GrVkRenderPass::Create(GrVkGpu* gpu,
@ -70,13 +69,11 @@ GrVkRenderPass* GrVkRenderPass::Create(GrVkGpu* gpu,
AttachmentsDescriptor* attachmentsDescriptor,
const LoadStoreOps& colorOp,
const LoadStoreOps& stencilOp,
bool needsSelfDependency) {
// TODO: We need to create a subpass where we have a color attachment ref and an input
// attachment ref. Both refs will point to the same color attachment on the render pass. We also
// need to create a self dependency for that subpass so that we can use barriers. Finally, the
// color attachment will need to be set to the GENERAL layout since it will be used for reading
// and writing here.
SkASSERT(!needsSelfDependency || gpu->caps()->advancedBlendEquationSupport());
SelfDependencyFlags selfDepFlags) {
SkASSERT(!SkToBool(selfDepFlags & SelfDependencyFlags::kForNonCoherentAdvBlend) ||
gpu->caps()->advancedBlendEquationSupport());
SkASSERT(!SkToBool(selfDepFlags & SelfDependencyFlags::kForInputAttachment) ||
gpu->caps()->textureBarrierSupport());
uint32_t numAttachments = attachmentsDescriptor->fAttachmentCount;
// Attachment descriptions to be set on the render pass
@ -107,8 +104,7 @@ GrVkRenderPass* GrVkRenderPass::Create(GrVkGpu* gpu,
if (attachmentFlags & kColor_AttachmentFlag) {
// set up color attachment
bool needsGeneralLayout =
needsSelfDependency && !gpu->caps()->advancedBlendEquationSupport();
bool needsGeneralLayout = SkToBool(selfDepFlags & SelfDependencyFlags::kForInputAttachment);
VkImageLayout layout = needsGeneralLayout ? VK_IMAGE_LAYOUT_GENERAL
: VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
@ -121,32 +117,30 @@ GrVkRenderPass* GrVkRenderPass::Create(GrVkGpu* gpu,
colorRef.layout = layout;
subpassDesc.colorAttachmentCount = 1;
if (needsSelfDependency) {
if (selfDepFlags != SelfDependencyFlags::kNone) {
numDependecies = 1;
dependency.srcSubpass = 0;
dependency.dstSubpass = 0;
dependency.dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
if (gpu->caps()->advancedBlendEquationSupport()) {
dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dependency.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
dependency.dstStageMask = 0;
dependency.dstAccessMask = 0;
if (selfDepFlags & SelfDependencyFlags::kForNonCoherentAdvBlend) {
// If we have coherent support we shouldn't be needing a self dependency
SkASSERT(!gpu->caps()->advancedCoherentBlendEquationSupport());
dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dependency.srcAccessMask =
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
VK_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT;
dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT;
} else {
dependency.dstStageMask |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dependency.dstAccessMask |= VK_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT;
}
if (selfDepFlags & SelfDependencyFlags::kForInputAttachment) {
SkASSERT(gpu->vkCaps().maxInputAttachmentDescriptors());
subpassDesc.inputAttachmentCount = 1;
subpassDesc.pInputAttachments = &colorRef;
dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dependency.dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
dependency.srcAccessMask =
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT;
dependency.dstAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
dependency.dstStageMask |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
dependency.dstAccessMask |= VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
}
}
@ -156,7 +150,7 @@ GrVkRenderPass* GrVkRenderPass::Create(GrVkGpu* gpu,
} else {
// I don't think there should ever be a time where we don't have a color attachment
SkASSERT(false);
SkASSERT(!needsSelfDependency);
SkASSERT(selfDepFlags == SelfDependencyFlags::kNone);
colorRef.attachment = VK_ATTACHMENT_UNUSED;
colorRef.layout = VK_IMAGE_LAYOUT_UNDEFINED;
subpassDesc.colorAttachmentCount = 0;
@ -217,18 +211,18 @@ GrVkRenderPass* GrVkRenderPass::Create(GrVkGpu* gpu,
&granularity));
return new GrVkRenderPass(gpu, renderPass, attachmentFlags, *attachmentsDescriptor,
needsSelfDependency, granularity, clearValueCount);
selfDepFlags, granularity, clearValueCount);
}
GrVkRenderPass::GrVkRenderPass(const GrVkGpu* gpu, VkRenderPass renderPass, AttachmentFlags flags,
const AttachmentsDescriptor& descriptor,
bool hasSelfDependency,
SelfDependencyFlags selfDepFlags,
const VkExtent2D& granularity, uint32_t clearValueCount)
: INHERITED(gpu)
, fRenderPass(renderPass)
, fAttachmentFlags(flags)
, fAttachmentsDescriptor(descriptor)
, fHasSelfDependency(hasSelfDependency)
, fSelfDepFlags(selfDepFlags)
, fGranularity(granularity)
, fClearValueCount(clearValueCount) {
}
@ -263,7 +257,7 @@ bool GrVkRenderPass::stencilAttachmentIndex(uint32_t* index) const {
bool GrVkRenderPass::isCompatible(const AttachmentsDescriptor& desc,
const AttachmentFlags& flags,
bool hasSelfDependency) const {
SelfDependencyFlags selfDepFlags) const {
SkASSERT(!(fAttachmentFlags & kExternal_AttachmentFlag));
if (flags != fAttachmentFlags) {
return false;
@ -280,7 +274,7 @@ bool GrVkRenderPass::isCompatible(const AttachmentsDescriptor& desc,
}
}
if (fHasSelfDependency != hasSelfDependency) {
if (fSelfDepFlags != selfDepFlags) {
return false;
}
@ -288,20 +282,20 @@ bool GrVkRenderPass::isCompatible(const AttachmentsDescriptor& desc,
}
bool GrVkRenderPass::isCompatible(const GrVkRenderTarget& target,
bool hasSelfDependency) const {
SelfDependencyFlags selfDepFlags) const {
SkASSERT(!(fAttachmentFlags & kExternal_AttachmentFlag));
AttachmentsDescriptor desc;
AttachmentFlags flags;
target.getAttachmentsDescriptor(&desc, &flags, this->hasStencilAttachment());
return this->isCompatible(desc, flags, hasSelfDependency);
return this->isCompatible(desc, flags, selfDepFlags);
}
bool GrVkRenderPass::isCompatible(const GrVkRenderPass& renderPass) const {
SkASSERT(!(fAttachmentFlags & kExternal_AttachmentFlag));
return this->isCompatible(renderPass.fAttachmentsDescriptor, renderPass.fAttachmentFlags,
renderPass.fHasSelfDependency);
renderPass.fSelfDepFlags);
}
bool GrVkRenderPass::isCompatibleExternalRP(VkRenderPass renderPass) const {
@ -326,14 +320,13 @@ bool GrVkRenderPass::equalLoadStoreOps(const LoadStoreOps& colorOps,
}
void GrVkRenderPass::genKey(GrProcessorKeyBuilder* b) const {
GenKey(b, fAttachmentFlags, fAttachmentsDescriptor, fHasSelfDependency,
(uint64_t)fRenderPass);
GenKey(b, fAttachmentFlags, fAttachmentsDescriptor, fSelfDepFlags, (uint64_t)fRenderPass);
}
void GrVkRenderPass::GenKey(GrProcessorKeyBuilder* b,
AttachmentFlags attachmentFlags,
const AttachmentsDescriptor& attachmentsDescriptor,
bool hasSelfDependency,
SelfDependencyFlags selfDepFlags,
uint64_t externalRenderPass) {
b->add32(attachmentFlags);
if (attachmentFlags & kColor_AttachmentFlag) {
@ -345,7 +338,7 @@ void GrVkRenderPass::GenKey(GrProcessorKeyBuilder* b,
b->add32(attachmentsDescriptor.fStencil.fSamples);
}
b->add32(hasSelfDependency);
b->add32((uint32_t)selfDepFlags);
if (attachmentFlags & kExternal_AttachmentFlag) {
SkASSERT(!(attachmentFlags & ~kExternal_AttachmentFlag));

View File

@ -42,7 +42,7 @@ public:
: INHERITED(gpu)
, fRenderPass(renderPass)
, fAttachmentFlags(kExternal_AttachmentFlag)
, fHasSelfDependency(false)
, fSelfDepFlags(SelfDependencyFlags::kNone)
, fClearValueCount(0)
, fColorAttachmentIndex(colorAttachmentIndex) {}
@ -84,10 +84,17 @@ public:
};
GR_DECL_BITFIELD_OPS_FRIENDS(AttachmentFlags);
enum class SelfDependencyFlags {
kNone = 0,
kForInputAttachment = 1 << 0,
kForNonCoherentAdvBlend = 1 << 1,
};
GR_DECL_BITFIELD_CLASS_OPS_FRIENDS(SelfDependencyFlags);
static GrVkRenderPass* CreateSimple(GrVkGpu*,
AttachmentsDescriptor*,
AttachmentFlags,
bool needsSelfDependency);
SelfDependencyFlags selfDepFlags);
static GrVkRenderPass* Create(GrVkGpu*,
const GrVkRenderPass& compatibleRenderPass,
const LoadStoreOps& colorOp,
@ -100,19 +107,19 @@ public:
bool stencilAttachmentIndex(uint32_t* index) const;
bool hasStencilAttachment() const { return fAttachmentFlags & kStencil_AttachmentFlag; }
bool hasSelfDependency() const { return fHasSelfDependency; }
SelfDependencyFlags selfDependencyFlags() const { return fSelfDepFlags; }
// Returns whether or not the structure of a RenderTarget matches that of the VkRenderPass in
// this object. Specifically this compares that the number of attachments, format of
// attachments, and sample counts are all the same. This function is used in the creation of
// basic RenderPasses that can be used when creating a VkFrameBuffer object.
bool isCompatible(const GrVkRenderTarget& target, bool hasInputSelfDependency) const;
bool isCompatible(const GrVkRenderTarget& target, SelfDependencyFlags selfDepFlags) const;
bool isCompatible(const GrVkRenderPass& renderPass) const;
bool isCompatible(const AttachmentsDescriptor&,
const AttachmentFlags&,
bool hasInputSelfDependency) const;
SelfDependencyFlags selfDepFlags) const;
bool isCompatibleExternalRP(VkRenderPass) const;
@ -135,7 +142,7 @@ public:
static void GenKey(GrProcessorKeyBuilder*,
AttachmentFlags,
const AttachmentsDescriptor&,
bool hasSelfDependency,
SelfDependencyFlags selfDepFlags,
uint64_t externalRenderPass);
#ifdef SK_TRACE_MANAGED_RESOURCES
@ -146,7 +153,7 @@ public:
private:
GrVkRenderPass(const GrVkGpu*, VkRenderPass, AttachmentFlags, const AttachmentsDescriptor&,
bool hasInputSelfDependency, const VkExtent2D& granularity,
SelfDependencyFlags selfDepFlags, const VkExtent2D& granularity,
uint32_t clearValueCount);
static GrVkRenderPass* Create(GrVkGpu* gpu,
@ -154,14 +161,14 @@ private:
AttachmentsDescriptor*,
const LoadStoreOps& colorOps,
const LoadStoreOps& stencilOps,
bool needsSelfDependency);
SelfDependencyFlags selfDepFlags);
void freeGPUData() const override;
VkRenderPass fRenderPass;
AttachmentFlags fAttachmentFlags;
AttachmentsDescriptor fAttachmentsDescriptor;
bool fHasSelfDependency;
SelfDependencyFlags fSelfDepFlags;
VkExtent2D fGranularity;
uint32_t fClearValueCount;
// For internally created render passes we assume the color attachment index is always 0.
@ -171,5 +178,6 @@ private:
};
GR_MAKE_BITFIELD_OPS(GrVkRenderPass::AttachmentFlags);
GR_MAKE_BITFIELD_CLASS_OPS(GrVkRenderPass::SelfDependencyFlags);
#endif

View File

@ -19,6 +19,18 @@
#define VK_CALL(GPU, X) GR_VK_CALL(GPU->vkInterface(), X)
static int renderpass_features_to_index(
bool hasStencil, GrVkRenderPass::SelfDependencyFlags selfDepFlags) {
int index = hasStencil ? 1 : 0;
if (selfDepFlags & GrVkRenderPass::SelfDependencyFlags::kForInputAttachment) {
index += 2;
}
if (selfDepFlags & GrVkRenderPass::SelfDependencyFlags::kForNonCoherentAdvBlend) {
index += 4;
}
return index;
}
// We're virtually derived from GrSurface (via GrRenderTarget) so its
// constructor must be explicitly called.
GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu,
@ -37,7 +49,9 @@ GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu,
, fColorAttachmentView(colorAttachmentView)
, fMSAAImage(new GrVkImage(gpu, msaaInfo, std::move(msaaMutableState),
GrBackendObjectOwnership::kOwned))
, fResolveAttachmentView(resolveAttachmentView) {
, fResolveAttachmentView(resolveAttachmentView)
, fCachedFramebuffers()
, fCachedRenderPasses() {
SkASSERT(info.fProtected == msaaInfo.fProtected);
SkASSERT(sampleCnt > 1);
SkASSERT(SkToBool(info.fImageUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT));
@ -64,7 +78,9 @@ GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu,
, fColorAttachmentView(colorAttachmentView)
, fMSAAImage(new GrVkImage(gpu, msaaInfo, std::move(msaaMutableState),
GrBackendObjectOwnership::kOwned))
, fResolveAttachmentView(resolveAttachmentView) {
, fResolveAttachmentView(resolveAttachmentView)
, fCachedFramebuffers()
, fCachedRenderPasses() {
SkASSERT(info.fProtected == msaaInfo.fProtected);
SkASSERT(sampleCnt > 1);
SkASSERT(SkToBool(info.fImageUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT));
@ -83,7 +99,9 @@ GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu,
, GrRenderTarget(gpu, dimensions, 1, info.fProtected)
, fColorAttachmentView(colorAttachmentView)
, fMSAAImage(nullptr)
, fResolveAttachmentView(nullptr) {
, fResolveAttachmentView(nullptr)
, fCachedFramebuffers()
, fCachedRenderPasses() {
SkASSERT(SkToBool(info.fImageUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT));
this->setFlags(info);
this->registerWithCacheWrapped(GrWrapCacheable::kNo);
@ -102,7 +120,9 @@ GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu,
, GrRenderTarget(gpu, dimensions, 1, info.fProtected)
, fColorAttachmentView(colorAttachmentView)
, fMSAAImage(nullptr)
, fResolveAttachmentView(nullptr) {
, fResolveAttachmentView(nullptr)
, fCachedFramebuffers()
, fCachedRenderPasses() {
SkASSERT(SkToBool(info.fImageUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT));
this->setFlags(info);
}
@ -119,12 +139,17 @@ GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu,
, fColorAttachmentView(nullptr)
, fMSAAImage(nullptr)
, fResolveAttachmentView(nullptr)
, fCachedSimpleRenderPass(renderPass)
, fCachedFramebuffers()
, fCachedRenderPasses()
, fSecondaryCommandBuffer(secondaryCommandBuffer) {
SkASSERT(fSecondaryCommandBuffer != VK_NULL_HANDLE);
SkASSERT(SkToBool(info.fImageUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT));
this->setFlags(info);
this->registerWithCacheWrapped(GrWrapCacheable::kNo);
// We use the cached renderpass with no stencil and no extra dependencies to hold the external
// render pass.
int exteralRPIndex = renderpass_features_to_index(false, SelfDependencyFlags::kNone);
fCachedRenderPasses[exteralRPIndex] = renderPass;
}
void GrVkRenderTarget::setFlags(const GrVkImageInfo& info) {
@ -244,125 +269,94 @@ bool GrVkRenderTarget::completeStencilAttachment() {
return true;
}
const GrVkRenderPass* GrVkRenderTarget::getSimpleRenderPass(bool withStencil,
bool needsXferBarrier) {
if (withStencil) {
if (needsXferBarrier) {
if (fCachedStencilSelfDepRenderPass) {
return fCachedStencilSelfDepRenderPass;
}
} else {
if (fCachedStencilRenderPass) {
return fCachedStencilRenderPass;
}
}
} else {
if (needsXferBarrier) {
if (fCachedSelfDepRenderPass) {
return fCachedSelfDepRenderPass;
}
} else {
if (fCachedSimpleRenderPass) {
return fCachedSimpleRenderPass;
}
}
const GrVkRenderPass* GrVkRenderTarget::externalRenderPass() const {
SkASSERT(this->wrapsSecondaryCommandBuffer());
// We use the cached render pass with no attachments or self dependencies to hold the
// external render pass.
int exteralRPIndex = renderpass_features_to_index(false, SelfDependencyFlags::kNone);
return fCachedRenderPasses[exteralRPIndex];
}
GrVkResourceProvider::CompatibleRPHandle GrVkRenderTarget::compatibleRenderPassHandle(
bool withStencil, SelfDependencyFlags selfDepFlags) {
SkASSERT(!this->wrapsSecondaryCommandBuffer());
int cacheIndex = renderpass_features_to_index(withStencil, selfDepFlags);
SkASSERT(cacheIndex < GrVkRenderTarget::kNumCachedRenderPasses);
GrVkResourceProvider::CompatibleRPHandle* pRPHandle;
pRPHandle = &fCompatibleRPHandles[cacheIndex];
if (!pRPHandle->isValid()) {
this->createSimpleRenderPass(withStencil, selfDepFlags);
}
return this->createSimpleRenderPass(withStencil, needsXferBarrier);
#ifdef SK_DEBUG
const GrVkRenderPass* rp = fCachedRenderPasses[cacheIndex];
SkASSERT(pRPHandle->isValid() == SkToBool(rp));
if (rp) {
SkASSERT(selfDepFlags == rp->selfDependencyFlags());
}
#endif
return *pRPHandle;
}
const GrVkRenderPass* GrVkRenderTarget::getSimpleRenderPass(bool withStencil,
SelfDependencyFlags selfDepFlags) {
int cacheIndex = renderpass_features_to_index(withStencil, selfDepFlags);
SkASSERT(cacheIndex < GrVkRenderTarget::kNumCachedRenderPasses);
if (const GrVkRenderPass* rp = fCachedRenderPasses[cacheIndex]) {
return rp;
}
return this->createSimpleRenderPass(withStencil, selfDepFlags);
}
const GrVkRenderPass* GrVkRenderTarget::createSimpleRenderPass(bool withStencil,
bool needsXferBarrier) {
SelfDependencyFlags selfDepFlags) {
SkASSERT(!this->wrapsSecondaryCommandBuffer());
GrVkResourceProvider& rp = this->getVkGpu()->resourceProvider();
if (withStencil) {
if (needsXferBarrier) {
SkASSERT(!fCachedStencilSelfDepRenderPass);
fCachedStencilSelfDepRenderPass = rp.findCompatibleRenderPass(
*this, &fCompatibleStencilSelfDepRPHandle, withStencil, needsXferBarrier);
return fCachedStencilSelfDepRenderPass;
} else {
SkASSERT(!fCachedStencilRenderPass);
fCachedStencilRenderPass = rp.findCompatibleRenderPass(
*this, &fCompatibleStencilRPHandle, withStencil, needsXferBarrier);
return fCachedStencilRenderPass;
}
} else {
if (needsXferBarrier) {
SkASSERT(!fCachedSelfDepRenderPass);
fCachedSelfDepRenderPass = rp.findCompatibleRenderPass(
*this, &fCompatibleSelfDepRPHandle, withStencil, needsXferBarrier);
return fCachedSelfDepRenderPass;
} else {
SkASSERT(!fCachedSimpleRenderPass);
fCachedSimpleRenderPass = rp.findCompatibleRenderPass(
*this, &fCompatibleRPHandle, withStencil, needsXferBarrier);
return fCachedSimpleRenderPass;
}
}
int cacheIndex = renderpass_features_to_index(withStencil, selfDepFlags);
SkASSERT(cacheIndex < GrVkRenderTarget::kNumCachedRenderPasses);
SkASSERT(!fCachedRenderPasses[cacheIndex]);
fCachedRenderPasses[cacheIndex] = rp.findCompatibleRenderPass(
*this, &fCompatibleRPHandles[cacheIndex], withStencil, selfDepFlags);
return fCachedRenderPasses[cacheIndex];
}
const GrVkFramebuffer* GrVkRenderTarget::getFramebuffer(bool withStencil, bool needsXferBarrier) {
if (withStencil) {
if (needsXferBarrier) {
if (fCachedStencilSelfDepFramebuffer) {
return fCachedStencilSelfDepFramebuffer;
}
} else {
if (fCachedStencilFramebuffer) {
return fCachedStencilFramebuffer;
}
}
} else {
if (needsXferBarrier) {
if (fCachedSelfDepFramebuffer) {
return fCachedSelfDepFramebuffer;
}
} else {
if (fCachedFramebuffer) {
return fCachedFramebuffer;
}
}
const GrVkFramebuffer* GrVkRenderTarget::getFramebuffer(bool withStencil,
SelfDependencyFlags selfDepFlags) {
int cacheIndex = renderpass_features_to_index(withStencil, selfDepFlags);
SkASSERT(cacheIndex < GrVkRenderTarget::kNumCachedRenderPasses);
if (auto fb = fCachedFramebuffers[cacheIndex]) {
return fb;
}
return this->createFramebuffer(withStencil, needsXferBarrier);
return this->createFramebuffer(withStencil, selfDepFlags);
}
const GrVkFramebuffer* GrVkRenderTarget::createFramebuffer(bool withStencil,
bool needsXferBarrier) {
SelfDependencyFlags selfDepFlags) {
SkASSERT(!this->wrapsSecondaryCommandBuffer());
GrVkGpu* gpu = this->getVkGpu();
const GrVkRenderPass* renderPass = this->getSimpleRenderPass(withStencil, needsXferBarrier);
const GrVkRenderPass* renderPass = this->getSimpleRenderPass(withStencil, selfDepFlags);
if (!renderPass) {
return nullptr;
}
int cacheIndex = renderpass_features_to_index(withStencil, selfDepFlags);
SkASSERT(cacheIndex < GrVkRenderTarget::kNumCachedRenderPasses);
// Stencil attachment view is stored in the base RT stencil attachment
const GrVkImageView* stencilView = withStencil ? this->stencilAttachmentView() : nullptr;
GrVkFramebuffer* frameBuffer = GrVkFramebuffer::Create(gpu, this->width(), this->height(),
renderPass, fColorAttachmentView,
stencilView);
fCachedFramebuffers[cacheIndex] = GrVkFramebuffer::Create(gpu, this->width(), this->height(),
renderPass, fColorAttachmentView,
stencilView);
if (withStencil) {
if (needsXferBarrier) {
SkASSERT(!fCachedStencilSelfDepFramebuffer);
fCachedStencilSelfDepFramebuffer = frameBuffer;
} else {
SkASSERT(!fCachedStencilFramebuffer);
fCachedStencilFramebuffer = frameBuffer;
}
} else {
if (needsXferBarrier) {
SkASSERT(!fCachedSelfDepFramebuffer);
fCachedSelfDepFramebuffer = frameBuffer;
} else {
SkASSERT(!fCachedFramebuffer);
fCachedFramebuffer = frameBuffer;
}
}
return frameBuffer;
return fCachedFramebuffers[cacheIndex];
}
void GrVkRenderTarget::getAttachmentsDescriptor(GrVkRenderPass::AttachmentsDescriptor* desc,
@ -428,19 +422,16 @@ GrVkRenderTarget::~GrVkRenderTarget() {
SkASSERT(!fMSAAImage);
SkASSERT(!fResolveAttachmentView);
SkASSERT(!fColorAttachmentView);
SkASSERT(!fCachedFramebuffer);
SkASSERT(!fCachedStencilFramebuffer);
SkASSERT(!fCachedSelfDepFramebuffer);
SkASSERT(!fCachedStencilSelfDepFramebuffer);
SkASSERT(!fCachedSimpleRenderPass);
SkASSERT(!fCachedStencilRenderPass);
SkASSERT(!fCachedSelfDepRenderPass);
SkASSERT(!fCachedStencilSelfDepRenderPass);
for (int i = 0; i < kNumCachedRenderPasses; ++i) {
SkASSERT(!fCachedFramebuffers[i]);
SkASSERT(!fCachedRenderPasses[i]);
}
}
void GrVkRenderTarget::addResources(GrVkCommandBuffer& commandBuffer, bool withStencil,
bool needsXferBarrier) {
commandBuffer.addResource(this->getFramebuffer(withStencil, needsXferBarrier));
SelfDependencyFlags selfDepFlags) {
commandBuffer.addResource(this->getFramebuffer(withStencil, selfDepFlags));
commandBuffer.addResource(this->colorAttachmentView());
commandBuffer.addResource(this->msaaImageResource() ? this->msaaImageResource()
: this->resource());
@ -464,38 +455,18 @@ void GrVkRenderTarget::releaseInternalObjects() {
fColorAttachmentView->unref();
fColorAttachmentView = nullptr;
}
if (fCachedFramebuffer) {
fCachedFramebuffer->unref();
fCachedFramebuffer = nullptr;
}
if (fCachedStencilFramebuffer) {
fCachedStencilFramebuffer->unref();
fCachedStencilFramebuffer = nullptr;
}
if (fCachedSelfDepFramebuffer) {
fCachedSelfDepFramebuffer->unref();
fCachedSelfDepFramebuffer = nullptr;
}
if (fCachedStencilSelfDepFramebuffer) {
fCachedStencilSelfDepFramebuffer->unref();
fCachedStencilSelfDepFramebuffer = nullptr;
}
if (fCachedSimpleRenderPass) {
fCachedSimpleRenderPass->unref();
fCachedSimpleRenderPass = nullptr;
}
if (fCachedStencilRenderPass) {
fCachedStencilRenderPass->unref();
fCachedStencilRenderPass = nullptr;
}
if (fCachedSelfDepRenderPass) {
fCachedSelfDepRenderPass->unref();
fCachedSelfDepRenderPass = nullptr;
}
if (fCachedStencilSelfDepRenderPass) {
fCachedStencilSelfDepRenderPass->unref();
fCachedStencilSelfDepRenderPass = nullptr;
for (int i = 0; i < kNumCachedRenderPasses; ++i) {
if (fCachedFramebuffers[i]) {
fCachedFramebuffers[i]->unref();
fCachedFramebuffers[i] = nullptr;
}
if (fCachedRenderPasses[i]) {
fCachedRenderPasses[i]->unref();
fCachedRenderPasses[i] = nullptr;
}
}
for (int i = 0; i < fGrSecondaryCommandBuffers.count(); ++i) {
SkASSERT(fGrSecondaryCommandBuffers[i]);
fGrSecondaryCommandBuffers[i]->releaseResources();

View File

@ -37,7 +37,9 @@ public:
GrBackendFormat backendFormat() const override { return this->getBackendFormat(); }
const GrVkFramebuffer* getFramebuffer(bool withStencil, bool needsXferBarrier);
using SelfDependencyFlags = GrVkRenderPass::SelfDependencyFlags;
const GrVkFramebuffer* getFramebuffer(bool withStencil, SelfDependencyFlags);
const GrVkImageView* colorAttachmentView() const { return fColorAttachmentView; }
const GrManagedResource* msaaImageResource() const {
if (fMSAAImage) {
@ -50,60 +52,10 @@ public:
const GrManagedResource* stencilImageResource() const;
const GrVkImageView* stencilAttachmentView() const;
const GrVkRenderPass* getSimpleRenderPass(bool withStencil, bool needsXferBarrier);
const GrVkRenderPass* getSimpleRenderPass(bool withStencil, SelfDependencyFlags);
GrVkResourceProvider::CompatibleRPHandle compatibleRenderPassHandle(bool withStencil,
bool needsXferBarrier) {
SkASSERT(!this->wrapsSecondaryCommandBuffer());
GrVkResourceProvider::CompatibleRPHandle* pRPHandle;
if (withStencil) {
if (needsXferBarrier) {
pRPHandle = &fCompatibleStencilSelfDepRPHandle;
} else {
pRPHandle = &fCompatibleStencilRPHandle;
}
} else {
if (needsXferBarrier) {
pRPHandle = &fCompatibleSelfDepRPHandle;
} else {
pRPHandle = &fCompatibleRPHandle;
}
}
if (!pRPHandle->isValid()) {
this->createSimpleRenderPass(withStencil, needsXferBarrier);
}
#ifdef SK_DEBUG
if (withStencil) {
if (needsXferBarrier) {
SkASSERT(pRPHandle->isValid() == SkToBool(fCachedStencilSelfDepRenderPass));
SkASSERT(fCachedStencilSelfDepRenderPass->hasStencilAttachment());
SkASSERT(fCachedStencilSelfDepRenderPass->hasSelfDependency());
} else {
SkASSERT(pRPHandle->isValid() == SkToBool(fCachedStencilRenderPass));
SkASSERT(fCachedStencilRenderPass->hasStencilAttachment());
SkASSERT(!fCachedStencilRenderPass->hasSelfDependency());
}
} else {
if (needsXferBarrier) {
SkASSERT(pRPHandle->isValid() == SkToBool(fCachedSelfDepRenderPass));
SkASSERT(!fCachedSelfDepRenderPass->hasStencilAttachment());
SkASSERT(fCachedSelfDepRenderPass->hasSelfDependency());
} else {
SkASSERT(pRPHandle->isValid() == SkToBool(fCachedSimpleRenderPass));
SkASSERT(!fCachedSimpleRenderPass->hasStencilAttachment());
SkASSERT(!fCachedSimpleRenderPass->hasSelfDependency());
}
}
#endif
return *pRPHandle;
}
const GrVkRenderPass* externalRenderPass() const {
SkASSERT(this->wrapsSecondaryCommandBuffer());
// We use the cached simple render pass to hold the external render pass.
return fCachedSimpleRenderPass;
}
SelfDependencyFlags);
const GrVkRenderPass* externalRenderPass() const;
bool wrapsSecondaryCommandBuffer() const { return fSecondaryCommandBuffer != VK_NULL_HANDLE; }
VkCommandBuffer getExternalSecondaryCommandBuffer() const {
@ -130,7 +82,7 @@ public:
GrVkRenderPass::AttachmentsDescriptor* desc,
GrVkRenderPass::AttachmentFlags* flags);
void addResources(GrVkCommandBuffer& commandBuffer, bool withStencil, bool needsXferBarrier);
void addResources(GrVkCommandBuffer& commandBuffer, bool withStencil, SelfDependencyFlags);
void addWrappedGrSecondaryCommandBuffer(std::unique_ptr<GrVkSecondaryCommandBuffer> cmdBuffer) {
fGrSecondaryCommandBuffers.push_back(std::move(cmdBuffer));
@ -198,8 +150,8 @@ private:
GrVkGpu* getVkGpu() const;
const GrVkRenderPass* createSimpleRenderPass(bool withStencil, bool needsXferBarrier);
const GrVkFramebuffer* createFramebuffer(bool withStencil, bool needsXferBarrier);
const GrVkRenderPass* createSimpleRenderPass(bool withStencil, SelfDependencyFlags);
const GrVkFramebuffer* createFramebuffer(bool withStencil, SelfDependencyFlags);
bool completeStencilAttachment() override;
@ -216,29 +168,14 @@ private:
std::unique_ptr<GrVkImage> fMSAAImage;
const GrVkImageView* fResolveAttachmentView;
const GrVkFramebuffer* fCachedFramebuffer = nullptr;
const GrVkFramebuffer* fCachedStencilFramebuffer = nullptr;
const GrVkFramebuffer* fCachedSelfDepFramebuffer = nullptr;
const GrVkFramebuffer* fCachedStencilSelfDepFramebuffer = nullptr;
// We can have a renderpass with and without stencil, input attachment dependency, and advanced
// blend dependency. All three being completely orthogonal. Thus we have a total of 8 types of
// render passes.
static constexpr int kNumCachedRenderPasses = 8;
// Cached pointers to a simple, stencil, and self dependency render passes. The render target
// should unref them once it is done with them.
const GrVkRenderPass* fCachedSimpleRenderPass = nullptr;
const GrVkRenderPass* fCachedStencilRenderPass = nullptr;
const GrVkRenderPass* fCachedSelfDepRenderPass = nullptr;
const GrVkRenderPass* fCachedStencilSelfDepRenderPass = nullptr;
// This is a handle to be used to quickly get a GrVkRenderPass that is compatible with
// this render target if its stencil buffer is ignored.
GrVkResourceProvider::CompatibleRPHandle fCompatibleRPHandle;
// Same as above but taking the render target's stencil buffer into account
GrVkResourceProvider::CompatibleRPHandle fCompatibleStencilRPHandle;
// RenderPass where there is also a self dependency to be used for advanced blending barriers.
// If the the gpu doesn't support VK_EXT_blend_operation_advanced the render pass will also have
// an input attachment to be used for dst reads.
GrVkResourceProvider::CompatibleRPHandle fCompatibleSelfDepRPHandle;
// Same as above but taking the render target's stencil buffer into account
GrVkResourceProvider::CompatibleRPHandle fCompatibleStencilSelfDepRPHandle;
const GrVkFramebuffer* fCachedFramebuffers[kNumCachedRenderPasses];
const GrVkRenderPass* fCachedRenderPasses[kNumCachedRenderPasses];
GrVkResourceProvider::CompatibleRPHandle fCompatibleRPHandles[kNumCachedRenderPasses];
// If this render target wraps an external VkCommandBuffer, then this handle will be that
// VkCommandBuffer and not VK_NULL_HANDLE. In this case the render target will not be backed by

View File

@ -109,24 +109,24 @@ const GrVkRenderPass*
GrVkResourceProvider::findCompatibleRenderPass(const GrVkRenderTarget& target,
CompatibleRPHandle* compatibleHandle,
bool withStencil,
bool needsSelfDependency) {
SelfDependencyFlags selfDepFlags) {
// Get attachment information from render target. This includes which attachments the render
// target has (color, stencil) and the attachments format and sample count.
GrVkRenderPass::AttachmentFlags attachmentFlags;
GrVkRenderPass::AttachmentsDescriptor attachmentsDesc;
target.getAttachmentsDescriptor(&attachmentsDesc, &attachmentFlags, withStencil);
return this->findCompatibleRenderPass(&attachmentsDesc, attachmentFlags, needsSelfDependency,
return this->findCompatibleRenderPass(&attachmentsDesc, attachmentFlags, selfDepFlags,
compatibleHandle);
}
const GrVkRenderPass*
GrVkResourceProvider::findCompatibleRenderPass(GrVkRenderPass::AttachmentsDescriptor* desc,
GrVkRenderPass::AttachmentFlags attachmentFlags,
bool needsSelfDependency,
SelfDependencyFlags selfDepFlags,
CompatibleRPHandle* compatibleHandle) {
for (int i = 0; i < fRenderPassArray.count(); ++i) {
if (fRenderPassArray[i].isCompatible(*desc, attachmentFlags, needsSelfDependency)) {
if (fRenderPassArray[i].isCompatible(*desc, attachmentFlags, selfDepFlags)) {
const GrVkRenderPass* renderPass = fRenderPassArray[i].getCompatibleRenderPass();
renderPass->ref();
if (compatibleHandle) {
@ -137,7 +137,7 @@ GrVkResourceProvider::findCompatibleRenderPass(GrVkRenderPass::AttachmentsDescri
}
GrVkRenderPass* renderPass = GrVkRenderPass::CreateSimple(fGpu, desc, attachmentFlags,
needsSelfDependency);
selfDepFlags);
if (!renderPass) {
return nullptr;
}
@ -176,11 +176,11 @@ const GrVkRenderPass* GrVkResourceProvider::findRenderPass(
const GrVkRenderPass::LoadStoreOps& stencilOps,
CompatibleRPHandle* compatibleHandle,
bool withStencil,
bool needsSelfDependency) {
SelfDependencyFlags selfDepFlags) {
GrVkResourceProvider::CompatibleRPHandle tempRPHandle;
GrVkResourceProvider::CompatibleRPHandle* pRPHandle = compatibleHandle ? compatibleHandle
: &tempRPHandle;
*pRPHandle = target->compatibleRenderPassHandle(withStencil, needsSelfDependency);
*pRPHandle = target->compatibleRenderPassHandle(withStencil, selfDepFlags);
if (!pRPHandle->isValid()) {
return nullptr;
}
@ -508,12 +508,11 @@ GrVkResourceProvider::CompatibleRenderPassSet::CompatibleRenderPassSet(GrVkRende
bool GrVkResourceProvider::CompatibleRenderPassSet::isCompatible(
const GrVkRenderPass::AttachmentsDescriptor& attachmentsDescriptor,
GrVkRenderPass::AttachmentFlags attachmentFlags,
bool needsSelfDependency) const {
SelfDependencyFlags selfDepFlags) const {
// The first GrVkRenderpass should always exists since we create the basic load store
// render pass on create
SkASSERT(fRenderPasses[0]);
return fRenderPasses[0]->isCompatible(attachmentsDescriptor, attachmentFlags,
needsSelfDependency);
return fRenderPasses[0]->isCompatible(attachmentsDescriptor, attachmentFlags,selfDepFlags);
}
GrVkRenderPass* GrVkResourceProvider::CompatibleRenderPassSet::getRenderPass(

View File

@ -53,21 +53,25 @@ public:
GR_DEFINE_RESOURCE_HANDLE_CLASS(CompatibleRPHandle);
using SelfDependencyFlags = GrVkRenderPass::SelfDependencyFlags;
// Finds or creates a simple render pass that matches the target, increments the refcount,
// and returns. The caller can optionally pass in a pointer to a CompatibleRPHandle. If this is
// non null it will be set to a handle that can be used in the furutre to quickly return a
// compatible GrVkRenderPasses without the need inspecting a GrVkRenderTarget.
const GrVkRenderPass* findCompatibleRenderPass(const GrVkRenderTarget& target,
CompatibleRPHandle* compatibleHandle,
bool withStencil, bool needsSelfDependency);
bool withStencil,
SelfDependencyFlags selfDepFlags);
const GrVkRenderPass* findCompatibleRenderPass(GrVkRenderPass::AttachmentsDescriptor*,
GrVkRenderPass::AttachmentFlags,
bool needsSelfDependency,
SelfDependencyFlags selfDepFlags,
CompatibleRPHandle* compatibleHandle = nullptr);
const GrVkRenderPass* findCompatibleExternalRenderPass(VkRenderPass,
uint32_t colorAttachmentIndex);
// Finds or creates a render pass that matches the target and LoadStoreOps, increments the
// refcount, and returns. The caller can optionally pass in a pointer to a CompatibleRPHandle.
// If this is non null it will be set to a handle that can be used in the future to quickly
@ -78,7 +82,7 @@ public:
const GrVkRenderPass::LoadStoreOps& stencilOps,
CompatibleRPHandle* compatibleHandle,
bool withStencil,
bool needsSelfDependency);
SelfDependencyFlags selfDepFlags);
// The CompatibleRPHandle must be a valid handle previously set by a call to findRenderPass or
// findCompatibleRenderPass.
@ -236,7 +240,7 @@ private:
bool isCompatible(const GrVkRenderPass::AttachmentsDescriptor&,
GrVkRenderPass::AttachmentFlags,
bool needsSelfDependency) const;
SelfDependencyFlags selfDepFlags) const;
const GrVkRenderPass* getCompatibleRenderPass() const {
// The first GrVkRenderpass should always exist since we create the basic load store