Support making a VkRenderPasses with self dependencies.

The self dependencies allow us to use xfer barriers for advanced blends.
If we don't have the advanced blend extension the self dependency render
passes will also have an input attachment on them which can be used to
read the dst value in the shader.

Also has some renaming of previously plumbed values to better match what
we are doing.

Bug: skia:10409
Change-Id: I3b343064627921b8dc3debeeb6869b0f4b2dcc42
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/310337
Commit-Queue: Greg Daniel <egdaniel@google.com>
Reviewed-by: Jim Van Verth <jvanverth@google.com>
This commit is contained in:
Greg Daniel 2020-08-14 13:11:18 -04:00 committed by Skia Commit-Bot
parent 8b07b9f55a
commit ed629c191d
12 changed files with 206 additions and 152 deletions

View File

@ -371,6 +371,8 @@ void GrVkCaps::init(const GrContextOptions& contextOptions, const GrVkInterface*
fShouldAlwaysUseDedicatedImageMemory = true; fShouldAlwaysUseDedicatedImageMemory = true;
} }
fMaxInputAttachmentDescriptors = properties.limits.maxDescriptorSetInputAttachments;
this->initGrCaps(vkInterface, physDev, properties, memoryProperties, features, extensions); this->initGrCaps(vkInterface, physDev, properties, memoryProperties, features, extensions);
this->initShaderCaps(properties, features); this->initShaderCaps(properties, features);
@ -1707,14 +1709,14 @@ GrProgramDesc GrVkCaps::makeDesc(GrRenderTarget* rt, const GrProgramInfo& progra
// GrVkPipelineStateBuilder.cpp). // GrVkPipelineStateBuilder.cpp).
b.add32(GrVkGpu::kShader_PersistentCacheKeyType); b.add32(GrVkGpu::kShader_PersistentCacheKeyType);
bool willReadDst = false; // TODO: get this from GrProgramInfo bool usesXferBarrier = false; // TODO: get this from GrProgramInfo
if (rt) { if (rt) {
GrVkRenderTarget* vkRT = (GrVkRenderTarget*) rt; GrVkRenderTarget* vkRT = (GrVkRenderTarget*) rt;
bool needsStencil = programInfo.numStencilSamples() || programInfo.isStencilEnabled(); bool needsStencil = programInfo.numStencilSamples() || programInfo.isStencilEnabled();
// TODO: support failure in getSimpleRenderPass // TODO: support failure in getSimpleRenderPass
const GrVkRenderPass* rp = vkRT->getSimpleRenderPass(needsStencil, willReadDst); const GrVkRenderPass* rp = vkRT->getSimpleRenderPass(needsStencil, usesXferBarrier);
SkASSERT(rp); SkASSERT(rp);
rp->genKey(&b); rp->genKey(&b);
@ -1727,7 +1729,7 @@ GrProgramDesc GrVkCaps::makeDesc(GrRenderTarget* rt, const GrProgramInfo& progra
GrVkRenderTarget::ReconstructAttachmentsDescriptor(*this, programInfo, GrVkRenderTarget::ReconstructAttachmentsDescriptor(*this, programInfo,
&attachmentsDescriptor, &attachmentsDescriptor,
&attachmentFlags); &attachmentFlags);
SkASSERT(rp->isCompatible(attachmentsDescriptor, attachmentFlags, willReadDst)); SkASSERT(rp->isCompatible(attachmentsDescriptor, attachmentFlags, usesXferBarrier));
} }
#endif #endif
} else { } else {
@ -1740,7 +1742,7 @@ GrProgramDesc GrVkCaps::makeDesc(GrRenderTarget* rt, const GrProgramInfo& progra
// kExternal_AttachmentFlag is only set for wrapped secondary command buffers - which // 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 // will always go through the above 'rt' path (i.e., we can always pass 0 as the final
// parameter to GenKey). // parameter to GenKey).
GrVkRenderPass::GenKey(&b, attachmentFlags, attachmentsDescriptor, willReadDst, 0); GrVkRenderPass::GenKey(&b, attachmentFlags, attachmentsDescriptor, usesXferBarrier, 0);
} }
GrStencilSettings stencil = programInfo.nonGLStencilSettings(); GrStencilSettings stencil = programInfo.nonGLStencilSettings();

View File

@ -160,6 +160,8 @@ public:
return fMaxPerPoolCachedSecondaryCommandBuffers; return fMaxPerPoolCachedSecondaryCommandBuffers;
} }
uint32_t maxInputAttachmentDescriptors() const { return fMaxInputAttachmentDescriptors; }
bool mustInvalidatePrimaryCmdBufferStateAfterClearAttachments() const { bool mustInvalidatePrimaryCmdBufferStateAfterClearAttachments() const {
return fMustInvalidatePrimaryCmdBufferStateAfterClearAttachments; return fMustInvalidatePrimaryCmdBufferStateAfterClearAttachments;
} }
@ -336,6 +338,8 @@ private:
// buffers per primary anyways. // buffers per primary anyways.
int fMaxPerPoolCachedSecondaryCommandBuffers = 100; int fMaxPerPoolCachedSecondaryCommandBuffers = 100;
uint32_t fMaxInputAttachmentDescriptors = 0;
typedef GrCaps INHERITED; typedef GrCaps INHERITED;
}; };

View File

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

View File

@ -322,10 +322,10 @@ GrOpsRenderPass* GrVkGpu::getOpsRenderPass(
fCachedOpsRenderPass = std::make_unique<GrVkOpsRenderPass>(this); fCachedOpsRenderPass = std::make_unique<GrVkOpsRenderPass>(this);
} }
bool willReadDst = false; // TODO: we should be passing this value bool usesXferBarrier = false; // TODO: we should be passing this value
if (!fCachedOpsRenderPass->set(rt, stencil, origin, bounds, if (!fCachedOpsRenderPass->set(rt, stencil, origin, bounds, colorInfo, stencilInfo,
colorInfo, stencilInfo, sampledProxies, willReadDst)) { sampledProxies, usesXferBarrier)) {
return nullptr; return nullptr;
} }
return fCachedOpsRenderPass.get(); return fCachedOpsRenderPass.get();

View File

@ -105,7 +105,7 @@ bool GrVkOpsRenderPass::init(const GrOpsRenderPass::LoadAndStoreInfo& colorInfo,
} }
const GrVkResourceProvider::CompatibleRPHandle& rpHandle = const GrVkResourceProvider::CompatibleRPHandle& rpHandle =
vkRT->compatibleRenderPassHandle(withStencil, fWillReadDst); vkRT->compatibleRenderPassHandle(withStencil, fUsesXferBarriers);
if (rpHandle.isValid()) { if (rpHandle.isValid()) {
fCurrentRenderPass = fGpu->resourceProvider().findRenderPass(rpHandle, fCurrentRenderPass = fGpu->resourceProvider().findRenderPass(rpHandle,
vkColorOps, vkColorOps,
@ -116,7 +116,7 @@ bool GrVkOpsRenderPass::init(const GrOpsRenderPass::LoadAndStoreInfo& colorInfo,
vkStencilOps, vkStencilOps,
nullptr, nullptr,
withStencil, withStencil,
fWillReadDst); fUsesXferBarriers);
} }
if (!fCurrentRenderPass) { if (!fCurrentRenderPass) {
return false; return false;
@ -135,8 +135,8 @@ bool GrVkOpsRenderPass::init(const GrOpsRenderPass::LoadAndStoreInfo& colorInfo,
fCurrentRenderPass = nullptr; fCurrentRenderPass = nullptr;
return false; return false;
} }
fCurrentSecondaryCommandBuffer->begin(fGpu, vkRT->getFramebuffer(withStencil, fWillReadDst), fCurrentSecondaryCommandBuffer->begin(
fCurrentRenderPass); fGpu, vkRT->getFramebuffer(withStencil, fUsesXferBarriers), fCurrentRenderPass);
} }
if (!fGpu->beginRenderPass(fCurrentRenderPass, &vkClearColor, vkRT, fOrigin, fBounds, 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::LoadAndStoreInfo& colorInfo,
const GrOpsRenderPass::StencilLoadAndStoreInfo& stencilInfo, const GrOpsRenderPass::StencilLoadAndStoreInfo& stencilInfo,
const SkTArray<GrSurfaceProxy*, true>& sampledProxies, const SkTArray<GrSurfaceProxy*, true>& sampledProxies,
bool willReadDst) { bool usesXferBarrier) {
SkASSERT(!fRenderTarget); SkASSERT(!fRenderTarget);
SkASSERT(fGpu == rt->getContext()->priv().getGpu()); SkASSERT(fGpu == rt->getContext()->priv().getGpu());
@ -243,7 +243,7 @@ bool GrVkOpsRenderPass::set(GrRenderTarget* rt, GrStencilAttachment* stencil,
SkASSERT(bounds.isEmpty() || SkIRect::MakeWH(rt->width(), rt->height()).contains(bounds)); SkASSERT(bounds.isEmpty() || SkIRect::MakeWH(rt->width(), rt->height()).contains(bounds));
fBounds = bounds; fBounds = bounds;
fWillReadDst = willReadDst; fUsesXferBarriers = usesXferBarrier;
if (this->wrapsSecondaryCommandBuffer()) { if (this->wrapsSecondaryCommandBuffer()) {
return this->initWrapped(); return this->initWrapped();
@ -392,7 +392,7 @@ void GrVkOpsRenderPass::addAdditionalRenderPass(bool mustUseSecondaryCommandBuff
bool withStencil = fCurrentRenderPass->hasStencilAttachment(); bool withStencil = fCurrentRenderPass->hasStencilAttachment();
const GrVkResourceProvider::CompatibleRPHandle& rpHandle = const GrVkResourceProvider::CompatibleRPHandle& rpHandle =
vkRT->compatibleRenderPassHandle(withStencil, fWillReadDst); vkRT->compatibleRenderPassHandle(withStencil, fUsesXferBarriers);
SkASSERT(fCurrentRenderPass); SkASSERT(fCurrentRenderPass);
fCurrentRenderPass->unref(); fCurrentRenderPass->unref();
if (rpHandle.isValid()) { if (rpHandle.isValid()) {
@ -405,7 +405,7 @@ void GrVkOpsRenderPass::addAdditionalRenderPass(bool mustUseSecondaryCommandBuff
vkStencilOps, vkStencilOps,
nullptr, nullptr,
withStencil, withStencil,
fWillReadDst); fUsesXferBarriers);
} }
if (!fCurrentRenderPass) { if (!fCurrentRenderPass) {
return; return;
@ -422,8 +422,8 @@ void GrVkOpsRenderPass::addAdditionalRenderPass(bool mustUseSecondaryCommandBuff
fCurrentRenderPass = nullptr; fCurrentRenderPass = nullptr;
return; return;
} }
fCurrentSecondaryCommandBuffer->begin(fGpu, vkRT->getFramebuffer(withStencil, fWillReadDst), fCurrentSecondaryCommandBuffer->begin(
fCurrentRenderPass); fGpu, vkRT->getFramebuffer(withStencil, fUsesXferBarriers), fCurrentRenderPass);
} }
// We use the same fBounds as the whole GrVkOpsRenderPass since we have no way of tracking the // We use the same fBounds as the whole GrVkOpsRenderPass since we have no way of tracking the

View File

@ -36,7 +36,7 @@ public:
const GrOpsRenderPass::LoadAndStoreInfo&, const GrOpsRenderPass::LoadAndStoreInfo&,
const GrOpsRenderPass::StencilLoadAndStoreInfo&, const GrOpsRenderPass::StencilLoadAndStoreInfo&,
const SkTArray<GrSurfaceProxy*, true>& sampledProxies, const SkTArray<GrSurfaceProxy*, true>& sampledProxies,
bool willReadDst); bool usesXferBarrier);
void reset(); void reset();
void submit(); void submit();
@ -96,7 +96,7 @@ private:
GrVkPipelineState* fCurrentPipelineState = nullptr; GrVkPipelineState* fCurrentPipelineState = nullptr;
bool fCurrentCBIsEmpty = true; bool fCurrentCBIsEmpty = true;
SkIRect fBounds; SkIRect fBounds;
bool fWillReadDst = false; bool fUsesXferBarriers = false;
GrVkGpu* fGpu; GrVkGpu* fGpu;
#ifdef SK_DEBUG #ifdef SK_DEBUG

View File

@ -45,12 +45,12 @@ void setup_vk_attachment_description(VkAttachmentDescription* attachment,
GrVkRenderPass* GrVkRenderPass::CreateSimple(GrVkGpu* gpu, GrVkRenderPass* GrVkRenderPass::CreateSimple(GrVkGpu* gpu,
AttachmentsDescriptor* attachmentsDescriptor, AttachmentsDescriptor* attachmentsDescriptor,
AttachmentFlags attachmentFlags, AttachmentFlags attachmentFlags,
bool needsInputSelfDependency) { bool needsSelfDependency) {
static const GrVkRenderPass::LoadStoreOps kBasicLoadStoreOps(VK_ATTACHMENT_LOAD_OP_LOAD, static const GrVkRenderPass::LoadStoreOps kBasicLoadStoreOps(VK_ATTACHMENT_LOAD_OP_LOAD,
VK_ATTACHMENT_STORE_OP_STORE); VK_ATTACHMENT_STORE_OP_STORE);
return Create(gpu, attachmentFlags, attachmentsDescriptor, kBasicLoadStoreOps, return Create(gpu, attachmentFlags, attachmentsDescriptor, kBasicLoadStoreOps,
kBasicLoadStoreOps, needsInputSelfDependency); kBasicLoadStoreOps, needsSelfDependency);
} }
GrVkRenderPass* GrVkRenderPass::Create(GrVkGpu* gpu, GrVkRenderPass* GrVkRenderPass::Create(GrVkGpu* gpu,
@ -59,9 +59,9 @@ GrVkRenderPass* GrVkRenderPass::Create(GrVkGpu* gpu,
const LoadStoreOps& stencilOp) { const LoadStoreOps& stencilOp) {
AttachmentFlags attachmentFlags = compatibleRenderPass.fAttachmentFlags; AttachmentFlags attachmentFlags = compatibleRenderPass.fAttachmentFlags;
AttachmentsDescriptor attachmentsDescriptor = compatibleRenderPass.fAttachmentsDescriptor; AttachmentsDescriptor attachmentsDescriptor = compatibleRenderPass.fAttachmentsDescriptor;
bool needsInputSelfDependency = compatibleRenderPass.fHasInputSelfDependency; bool needsSelfDependency = compatibleRenderPass.fHasSelfDependency;
return Create(gpu, attachmentFlags, &attachmentsDescriptor, colorOp, stencilOp, return Create(gpu, attachmentFlags, &attachmentsDescriptor, colorOp, stencilOp,
needsInputSelfDependency); needsSelfDependency);
} }
GrVkRenderPass* GrVkRenderPass::Create(GrVkGpu* gpu, GrVkRenderPass* GrVkRenderPass::Create(GrVkGpu* gpu,
@ -69,13 +69,13 @@ GrVkRenderPass* GrVkRenderPass::Create(GrVkGpu* gpu,
AttachmentsDescriptor* attachmentsDescriptor, AttachmentsDescriptor* attachmentsDescriptor,
const LoadStoreOps& colorOp, const LoadStoreOps& colorOp,
const LoadStoreOps& stencilOp, const LoadStoreOps& stencilOp,
bool needsInputSelfDependency) { bool needsSelfDependency) {
// TODO: We need to create a subpass where we have a color attachment ref and an input // 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 // 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 // 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 // color attachment will need to be set to the GENERAL layout since it will be used for reading
// and writing here. // and writing here.
SkASSERT(!needsInputSelfDependency); SkASSERT(!needsSelfDependency);
uint32_t numAttachments = attachmentsDescriptor->fAttachmentCount; uint32_t numAttachments = attachmentsDescriptor->fAttachmentCount;
// Attachment descriptions to be set on the render pass // Attachment descriptions to be set on the render pass
@ -101,27 +101,66 @@ GrVkRenderPass* GrVkRenderPass::Create(GrVkGpu* gpu,
uint32_t clearValueCount = 0; uint32_t clearValueCount = 0;
VkSubpassDependency dependency;
int numDependecies = 0;
if (attachmentFlags & kColor_AttachmentFlag) { if (attachmentFlags & kColor_AttachmentFlag) {
// set up color attachment // set up color attachment
bool needsGeneralLayout =
needsSelfDependency && !gpu->caps()->advancedBlendEquationSupport();
VkImageLayout layout = needsGeneralLayout ? VK_IMAGE_LAYOUT_GENERAL
: VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
attachmentsDescriptor->fColor.fLoadStoreOps = colorOp; attachmentsDescriptor->fColor.fLoadStoreOps = colorOp;
setup_vk_attachment_description(&attachments[currentAttachment], setup_vk_attachment_description(&attachments[currentAttachment],
attachmentsDescriptor->fColor, attachmentsDescriptor->fColor,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); layout);
// setup subpass use of attachment // setup subpass use of attachment
colorRef.attachment = currentAttachment++; colorRef.attachment = currentAttachment++;
colorRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; colorRef.layout = layout;
subpassDesc.colorAttachmentCount = 1; subpassDesc.colorAttachmentCount = 1;
if (needsSelfDependency) {
numDependecies = 1;
dependency.srcSubpass = 0;
dependency.dstSubpass = 0;
dependency.dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
if (gpu->caps()->advancedBlendEquationSupport()) {
// 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 {
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;
}
}
if (VK_ATTACHMENT_LOAD_OP_CLEAR == colorOp.fLoadOp) { if (VK_ATTACHMENT_LOAD_OP_CLEAR == colorOp.fLoadOp) {
clearValueCount = colorRef.attachment + 1; clearValueCount = colorRef.attachment + 1;
} }
} else { } else {
// I don't think there should ever be a time where we don't have a color attachment // I don't think there should ever be a time where we don't have a color attachment
SkASSERT(false); SkASSERT(false);
SkASSERT(!needsSelfDependency);
colorRef.attachment = VK_ATTACHMENT_UNUSED; colorRef.attachment = VK_ATTACHMENT_UNUSED;
colorRef.layout = VK_IMAGE_LAYOUT_UNDEFINED; colorRef.layout = VK_IMAGE_LAYOUT_UNDEFINED;
subpassDesc.colorAttachmentCount = 0; subpassDesc.colorAttachmentCount = 0;
} }
subpassDesc.pColorAttachments = &colorRef; subpassDesc.pColorAttachments = &colorRef;
if (attachmentFlags & kStencil_AttachmentFlag) { if (attachmentFlags & kStencil_AttachmentFlag) {
@ -157,8 +196,8 @@ GrVkRenderPass* GrVkRenderPass::Create(GrVkGpu* gpu,
createInfo.pAttachments = attachments.begin(); createInfo.pAttachments = attachments.begin();
createInfo.subpassCount = 1; createInfo.subpassCount = 1;
createInfo.pSubpasses = &subpassDesc; createInfo.pSubpasses = &subpassDesc;
createInfo.dependencyCount = 0; createInfo.dependencyCount = numDependecies;
createInfo.pDependencies = nullptr; createInfo.pDependencies = &dependency;
VkResult result; VkResult result;
VkRenderPass renderPass; VkRenderPass renderPass;
@ -177,18 +216,18 @@ GrVkRenderPass* GrVkRenderPass::Create(GrVkGpu* gpu,
&granularity)); &granularity));
return new GrVkRenderPass(gpu, renderPass, attachmentFlags, *attachmentsDescriptor, return new GrVkRenderPass(gpu, renderPass, attachmentFlags, *attachmentsDescriptor,
needsInputSelfDependency, granularity, clearValueCount); needsSelfDependency, granularity, clearValueCount);
} }
GrVkRenderPass::GrVkRenderPass(const GrVkGpu* gpu, VkRenderPass renderPass, AttachmentFlags flags, GrVkRenderPass::GrVkRenderPass(const GrVkGpu* gpu, VkRenderPass renderPass, AttachmentFlags flags,
const AttachmentsDescriptor& descriptor, const AttachmentsDescriptor& descriptor,
bool hasInputSelfDependency, bool hasSelfDependency,
const VkExtent2D& granularity, uint32_t clearValueCount) const VkExtent2D& granularity, uint32_t clearValueCount)
: INHERITED(gpu) : INHERITED(gpu)
, fRenderPass(renderPass) , fRenderPass(renderPass)
, fAttachmentFlags(flags) , fAttachmentFlags(flags)
, fAttachmentsDescriptor(descriptor) , fAttachmentsDescriptor(descriptor)
, fHasInputSelfDependency(hasInputSelfDependency) , fHasSelfDependency(hasSelfDependency)
, fGranularity(granularity) , fGranularity(granularity)
, fClearValueCount(clearValueCount) { , fClearValueCount(clearValueCount) {
} }
@ -223,7 +262,7 @@ bool GrVkRenderPass::stencilAttachmentIndex(uint32_t* index) const {
bool GrVkRenderPass::isCompatible(const AttachmentsDescriptor& desc, bool GrVkRenderPass::isCompatible(const AttachmentsDescriptor& desc,
const AttachmentFlags& flags, const AttachmentFlags& flags,
bool hasInputSelfDependency) const { bool hasSelfDependency) const {
SkASSERT(!(fAttachmentFlags & kExternal_AttachmentFlag)); SkASSERT(!(fAttachmentFlags & kExternal_AttachmentFlag));
if (flags != fAttachmentFlags) { if (flags != fAttachmentFlags) {
return false; return false;
@ -240,7 +279,7 @@ bool GrVkRenderPass::isCompatible(const AttachmentsDescriptor& desc,
} }
} }
if (fHasInputSelfDependency != hasInputSelfDependency) { if (fHasSelfDependency != hasSelfDependency) {
return false; return false;
} }
@ -248,20 +287,20 @@ bool GrVkRenderPass::isCompatible(const AttachmentsDescriptor& desc,
} }
bool GrVkRenderPass::isCompatible(const GrVkRenderTarget& target, bool GrVkRenderPass::isCompatible(const GrVkRenderTarget& target,
bool hasInputSelfDependency) const { bool hasSelfDependency) const {
SkASSERT(!(fAttachmentFlags & kExternal_AttachmentFlag)); SkASSERT(!(fAttachmentFlags & kExternal_AttachmentFlag));
AttachmentsDescriptor desc; AttachmentsDescriptor desc;
AttachmentFlags flags; AttachmentFlags flags;
target.getAttachmentsDescriptor(&desc, &flags, this->hasStencilAttachment()); target.getAttachmentsDescriptor(&desc, &flags, this->hasStencilAttachment());
return this->isCompatible(desc, flags, hasInputSelfDependency); return this->isCompatible(desc, flags, hasSelfDependency);
} }
bool GrVkRenderPass::isCompatible(const GrVkRenderPass& renderPass) const { bool GrVkRenderPass::isCompatible(const GrVkRenderPass& renderPass) const {
SkASSERT(!(fAttachmentFlags & kExternal_AttachmentFlag)); SkASSERT(!(fAttachmentFlags & kExternal_AttachmentFlag));
return this->isCompatible(renderPass.fAttachmentsDescriptor, renderPass.fAttachmentFlags, return this->isCompatible(renderPass.fAttachmentsDescriptor, renderPass.fAttachmentFlags,
renderPass.fHasInputSelfDependency); renderPass.fHasSelfDependency);
} }
bool GrVkRenderPass::isCompatibleExternalRP(VkRenderPass renderPass) const { bool GrVkRenderPass::isCompatibleExternalRP(VkRenderPass renderPass) const {
@ -286,14 +325,14 @@ bool GrVkRenderPass::equalLoadStoreOps(const LoadStoreOps& colorOps,
} }
void GrVkRenderPass::genKey(GrProcessorKeyBuilder* b) const { void GrVkRenderPass::genKey(GrProcessorKeyBuilder* b) const {
GenKey(b, fAttachmentFlags, fAttachmentsDescriptor, fHasInputSelfDependency, GenKey(b, fAttachmentFlags, fAttachmentsDescriptor, fHasSelfDependency,
(uint64_t)fRenderPass); (uint64_t)fRenderPass);
} }
void GrVkRenderPass::GenKey(GrProcessorKeyBuilder* b, void GrVkRenderPass::GenKey(GrProcessorKeyBuilder* b,
AttachmentFlags attachmentFlags, AttachmentFlags attachmentFlags,
const AttachmentsDescriptor& attachmentsDescriptor, const AttachmentsDescriptor& attachmentsDescriptor,
bool hasInputSelfDependency, bool hasSelfDependency,
uint64_t externalRenderPass) { uint64_t externalRenderPass) {
b->add32(attachmentFlags); b->add32(attachmentFlags);
if (attachmentFlags & kColor_AttachmentFlag) { if (attachmentFlags & kColor_AttachmentFlag) {
@ -305,7 +344,7 @@ void GrVkRenderPass::GenKey(GrProcessorKeyBuilder* b,
b->add32(attachmentsDescriptor.fStencil.fSamples); b->add32(attachmentsDescriptor.fStencil.fSamples);
} }
b->add32(hasInputSelfDependency); b->add32(hasSelfDependency);
if (attachmentFlags & kExternal_AttachmentFlag) { if (attachmentFlags & kExternal_AttachmentFlag) {
SkASSERT(!(attachmentFlags & ~kExternal_AttachmentFlag)); SkASSERT(!(attachmentFlags & ~kExternal_AttachmentFlag));

View File

@ -42,7 +42,7 @@ public:
: INHERITED(gpu) : INHERITED(gpu)
, fRenderPass(renderPass) , fRenderPass(renderPass)
, fAttachmentFlags(kExternal_AttachmentFlag) , fAttachmentFlags(kExternal_AttachmentFlag)
, fHasInputSelfDependency(false) , fHasSelfDependency(false)
, fClearValueCount(0) , fClearValueCount(0)
, fColorAttachmentIndex(colorAttachmentIndex) {} , fColorAttachmentIndex(colorAttachmentIndex) {}
@ -87,7 +87,7 @@ public:
static GrVkRenderPass* CreateSimple(GrVkGpu*, static GrVkRenderPass* CreateSimple(GrVkGpu*,
AttachmentsDescriptor*, AttachmentsDescriptor*,
AttachmentFlags, AttachmentFlags,
bool needsInputSelfDependency); bool needsSelfDependency);
static GrVkRenderPass* Create(GrVkGpu*, static GrVkRenderPass* Create(GrVkGpu*,
const GrVkRenderPass& compatibleRenderPass, const GrVkRenderPass& compatibleRenderPass,
const LoadStoreOps& colorOp, const LoadStoreOps& colorOp,
@ -100,7 +100,7 @@ public:
bool stencilAttachmentIndex(uint32_t* index) const; bool stencilAttachmentIndex(uint32_t* index) const;
bool hasStencilAttachment() const { return fAttachmentFlags & kStencil_AttachmentFlag; } bool hasStencilAttachment() const { return fAttachmentFlags & kStencil_AttachmentFlag; }
bool hasInputSelfDependency() const { return fHasInputSelfDependency; } bool hasSelfDependency() const { return fHasSelfDependency; }
// Returns whether or not the structure of a RenderTarget matches that of the VkRenderPass in // 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 // this object. Specifically this compares that the number of attachments, format of
@ -135,7 +135,7 @@ public:
static void GenKey(GrProcessorKeyBuilder*, static void GenKey(GrProcessorKeyBuilder*,
AttachmentFlags, AttachmentFlags,
const AttachmentsDescriptor&, const AttachmentsDescriptor&,
bool hasInputSelfDependency, bool hasSelfDependency,
uint64_t externalRenderPass); uint64_t externalRenderPass);
#ifdef SK_TRACE_MANAGED_RESOURCES #ifdef SK_TRACE_MANAGED_RESOURCES
@ -154,14 +154,14 @@ private:
AttachmentsDescriptor*, AttachmentsDescriptor*,
const LoadStoreOps& colorOps, const LoadStoreOps& colorOps,
const LoadStoreOps& stencilOps, const LoadStoreOps& stencilOps,
bool needsInputSelfDependency); bool needsSelfDependency);
void freeGPUData() const override; void freeGPUData() const override;
VkRenderPass fRenderPass; VkRenderPass fRenderPass;
AttachmentFlags fAttachmentFlags; AttachmentFlags fAttachmentFlags;
AttachmentsDescriptor fAttachmentsDescriptor; AttachmentsDescriptor fAttachmentsDescriptor;
bool fHasInputSelfDependency; bool fHasSelfDependency;
VkExtent2D fGranularity; VkExtent2D fGranularity;
uint32_t fClearValueCount; uint32_t fClearValueCount;
// For internally created render passes we assume the color attachment index is always 0. // For internally created render passes we assume the color attachment index is always 0.

View File

@ -225,11 +225,12 @@ bool GrVkRenderTarget::completeStencilAttachment() {
return true; return true;
} }
const GrVkRenderPass* GrVkRenderTarget::getSimpleRenderPass(bool withStencil, bool willReadDst) { const GrVkRenderPass* GrVkRenderTarget::getSimpleRenderPass(bool withStencil,
bool needsXferBarrier) {
if (withStencil) { if (withStencil) {
if (willReadDst) { if (needsXferBarrier) {
if (fCachedStencilDstReadRenderPass) { if (fCachedStencilSelfDepRenderPass) {
return fCachedStencilDstReadRenderPass; return fCachedStencilSelfDepRenderPass;
} }
} else { } else {
if (fCachedStencilRenderPass) { if (fCachedStencilRenderPass) {
@ -237,9 +238,9 @@ const GrVkRenderPass* GrVkRenderTarget::getSimpleRenderPass(bool withStencil, bo
} }
} }
} else { } else {
if (willReadDst) { if (needsXferBarrier) {
if (fCachedDstReadRenderPass) { if (fCachedSelfDepRenderPass) {
return fCachedDstReadRenderPass; return fCachedSelfDepRenderPass;
} }
} else { } else {
if (fCachedSimpleRenderPass) { if (fCachedSimpleRenderPass) {
@ -248,45 +249,46 @@ const GrVkRenderPass* GrVkRenderTarget::getSimpleRenderPass(bool withStencil, bo
} }
} }
return this->createSimpleRenderPass(withStencil, willReadDst); return this->createSimpleRenderPass(withStencil, needsXferBarrier);
} }
const GrVkRenderPass* GrVkRenderTarget::createSimpleRenderPass(bool withStencil, bool willReadDst) { const GrVkRenderPass* GrVkRenderTarget::createSimpleRenderPass(bool withStencil,
bool needsXferBarrier) {
SkASSERT(!this->wrapsSecondaryCommandBuffer()); SkASSERT(!this->wrapsSecondaryCommandBuffer());
GrVkResourceProvider& rp = this->getVkGpu()->resourceProvider(); GrVkResourceProvider& rp = this->getVkGpu()->resourceProvider();
if (withStencil) { if (withStencil) {
if (willReadDst) { if (needsXferBarrier) {
SkASSERT(!fCachedStencilDstReadRenderPass); SkASSERT(!fCachedStencilSelfDepRenderPass);
fCachedStencilDstReadRenderPass = rp.findCompatibleRenderPass( fCachedStencilSelfDepRenderPass = rp.findCompatibleRenderPass(
*this, &fCompatibleStencilDstReadRPHandle, withStencil, willReadDst); *this, &fCompatibleStencilSelfDepRPHandle, withStencil, needsXferBarrier);
return fCachedStencilDstReadRenderPass; return fCachedStencilSelfDepRenderPass;
} else { } else {
SkASSERT(!fCachedStencilRenderPass); SkASSERT(!fCachedStencilRenderPass);
fCachedStencilRenderPass = rp.findCompatibleRenderPass( fCachedStencilRenderPass = rp.findCompatibleRenderPass(
*this, &fCompatibleStencilRPHandle, withStencil, willReadDst); *this, &fCompatibleStencilRPHandle, withStencil, needsXferBarrier);
return fCachedStencilRenderPass; return fCachedStencilRenderPass;
} }
} else { } else {
if (willReadDst) { if (needsXferBarrier) {
SkASSERT(!fCachedDstReadRenderPass); SkASSERT(!fCachedSelfDepRenderPass);
fCachedDstReadRenderPass = rp.findCompatibleRenderPass( fCachedSelfDepRenderPass = rp.findCompatibleRenderPass(
*this, &fCompatibleDstReadRPHandle, withStencil, willReadDst); *this, &fCompatibleSelfDepRPHandle, withStencil, needsXferBarrier);
return fCachedDstReadRenderPass; return fCachedSelfDepRenderPass;
} else { } else {
SkASSERT(!fCachedSimpleRenderPass); SkASSERT(!fCachedSimpleRenderPass);
fCachedSimpleRenderPass = rp.findCompatibleRenderPass(* fCachedSimpleRenderPass = rp.findCompatibleRenderPass(
this, &fCompatibleRPHandle, withStencil, willReadDst); *this, &fCompatibleRPHandle, withStencil, needsXferBarrier);
return fCachedSimpleRenderPass; return fCachedSimpleRenderPass;
} }
} }
} }
const GrVkFramebuffer* GrVkRenderTarget::getFramebuffer(bool withStencil, bool willReadDst) { const GrVkFramebuffer* GrVkRenderTarget::getFramebuffer(bool withStencil, bool needsXferBarrier) {
if (withStencil) { if (withStencil) {
if (willReadDst) { if (needsXferBarrier) {
if (fCachedStencilDstReadFramebuffer) { if (fCachedStencilSelfDepFramebuffer) {
return fCachedStencilDstReadFramebuffer; return fCachedStencilSelfDepFramebuffer;
} }
} else { } else {
if (fCachedStencilFramebuffer) { if (fCachedStencilFramebuffer) {
@ -294,9 +296,9 @@ const GrVkFramebuffer* GrVkRenderTarget::getFramebuffer(bool withStencil, bool w
} }
} }
} else { } else {
if (willReadDst) { if (needsXferBarrier) {
if (fCachedDstReadFramebuffer) { if (fCachedSelfDepFramebuffer) {
return fCachedDstReadFramebuffer; return fCachedSelfDepFramebuffer;
} }
} else { } else {
if (fCachedFramebuffer) { if (fCachedFramebuffer) {
@ -304,14 +306,15 @@ const GrVkFramebuffer* GrVkRenderTarget::getFramebuffer(bool withStencil, bool w
} }
} }
} }
return this->createFramebuffer(withStencil, willReadDst); return this->createFramebuffer(withStencil, needsXferBarrier);
} }
const GrVkFramebuffer* GrVkRenderTarget::createFramebuffer(bool withStencil, bool willReadDst) { const GrVkFramebuffer* GrVkRenderTarget::createFramebuffer(bool withStencil,
bool needsXferBarrier) {
SkASSERT(!this->wrapsSecondaryCommandBuffer()); SkASSERT(!this->wrapsSecondaryCommandBuffer());
GrVkGpu* gpu = this->getVkGpu(); GrVkGpu* gpu = this->getVkGpu();
const GrVkRenderPass* renderPass = this->getSimpleRenderPass(withStencil, willReadDst); const GrVkRenderPass* renderPass = this->getSimpleRenderPass(withStencil, needsXferBarrier);
if (!renderPass) { if (!renderPass) {
return nullptr; return nullptr;
} }
@ -323,17 +326,17 @@ const GrVkFramebuffer* GrVkRenderTarget::createFramebuffer(bool withStencil, boo
stencilView); stencilView);
if (withStencil) { if (withStencil) {
if (willReadDst) { if (needsXferBarrier) {
SkASSERT(!fCachedStencilDstReadFramebuffer); SkASSERT(!fCachedStencilSelfDepFramebuffer);
fCachedStencilDstReadFramebuffer = frameBuffer; fCachedStencilSelfDepFramebuffer = frameBuffer;
} else { } else {
SkASSERT(!fCachedStencilFramebuffer); SkASSERT(!fCachedStencilFramebuffer);
fCachedStencilFramebuffer = frameBuffer; fCachedStencilFramebuffer = frameBuffer;
} }
} else { } else {
if (willReadDst) { if (needsXferBarrier) {
SkASSERT(!fCachedDstReadFramebuffer); SkASSERT(!fCachedSelfDepFramebuffer);
fCachedDstReadFramebuffer = frameBuffer; fCachedSelfDepFramebuffer = frameBuffer;
} else { } else {
SkASSERT(!fCachedFramebuffer); SkASSERT(!fCachedFramebuffer);
fCachedFramebuffer = frameBuffer; fCachedFramebuffer = frameBuffer;
@ -408,17 +411,17 @@ GrVkRenderTarget::~GrVkRenderTarget() {
SkASSERT(!fColorAttachmentView); SkASSERT(!fColorAttachmentView);
SkASSERT(!fCachedFramebuffer); SkASSERT(!fCachedFramebuffer);
SkASSERT(!fCachedStencilFramebuffer); SkASSERT(!fCachedStencilFramebuffer);
SkASSERT(!fCachedDstReadFramebuffer); SkASSERT(!fCachedSelfDepFramebuffer);
SkASSERT(!fCachedStencilDstReadFramebuffer); SkASSERT(!fCachedStencilSelfDepFramebuffer);
SkASSERT(!fCachedSimpleRenderPass); SkASSERT(!fCachedSimpleRenderPass);
SkASSERT(!fCachedStencilRenderPass); SkASSERT(!fCachedStencilRenderPass);
SkASSERT(!fCachedDstReadRenderPass); SkASSERT(!fCachedSelfDepRenderPass);
SkASSERT(!fCachedStencilDstReadRenderPass); SkASSERT(!fCachedStencilSelfDepRenderPass);
} }
void GrVkRenderTarget::addResources(GrVkCommandBuffer& commandBuffer, bool withStencil, void GrVkRenderTarget::addResources(GrVkCommandBuffer& commandBuffer, bool withStencil,
bool willReadDst) { bool needsXferBarrier) {
commandBuffer.addResource(this->getFramebuffer(withStencil, willReadDst)); commandBuffer.addResource(this->getFramebuffer(withStencil, needsXferBarrier));
commandBuffer.addResource(this->colorAttachmentView()); commandBuffer.addResource(this->colorAttachmentView());
commandBuffer.addResource(this->msaaImageResource() ? this->msaaImageResource() commandBuffer.addResource(this->msaaImageResource() ? this->msaaImageResource()
: this->resource()); : this->resource());
@ -450,13 +453,13 @@ void GrVkRenderTarget::releaseInternalObjects() {
fCachedStencilFramebuffer->unref(); fCachedStencilFramebuffer->unref();
fCachedStencilFramebuffer = nullptr; fCachedStencilFramebuffer = nullptr;
} }
if (fCachedDstReadFramebuffer) { if (fCachedSelfDepFramebuffer) {
fCachedDstReadFramebuffer->unref(); fCachedSelfDepFramebuffer->unref();
fCachedDstReadFramebuffer = nullptr; fCachedSelfDepFramebuffer = nullptr;
} }
if (fCachedStencilDstReadFramebuffer) { if (fCachedStencilSelfDepFramebuffer) {
fCachedStencilDstReadFramebuffer->unref(); fCachedStencilSelfDepFramebuffer->unref();
fCachedStencilDstReadFramebuffer = nullptr; fCachedStencilSelfDepFramebuffer = nullptr;
} }
if (fCachedSimpleRenderPass) { if (fCachedSimpleRenderPass) {
fCachedSimpleRenderPass->unref(); fCachedSimpleRenderPass->unref();
@ -466,13 +469,13 @@ void GrVkRenderTarget::releaseInternalObjects() {
fCachedStencilRenderPass->unref(); fCachedStencilRenderPass->unref();
fCachedStencilRenderPass = nullptr; fCachedStencilRenderPass = nullptr;
} }
if (fCachedDstReadRenderPass) { if (fCachedSelfDepRenderPass) {
fCachedDstReadRenderPass->unref(); fCachedSelfDepRenderPass->unref();
fCachedDstReadRenderPass = nullptr; fCachedSelfDepRenderPass = nullptr;
} }
if (fCachedStencilDstReadRenderPass) { if (fCachedStencilSelfDepRenderPass) {
fCachedStencilDstReadRenderPass->unref(); fCachedStencilSelfDepRenderPass->unref();
fCachedStencilDstReadRenderPass = nullptr; fCachedStencilSelfDepRenderPass = nullptr;
} }
for (int i = 0; i < fGrSecondaryCommandBuffers.count(); ++i) { for (int i = 0; i < fGrSecondaryCommandBuffers.count(); ++i) {
SkASSERT(fGrSecondaryCommandBuffers[i]); SkASSERT(fGrSecondaryCommandBuffers[i]);

View File

@ -43,7 +43,7 @@ public:
GrBackendFormat backendFormat() const override { return this->getBackendFormat(); } GrBackendFormat backendFormat() const override { return this->getBackendFormat(); }
const GrVkFramebuffer* getFramebuffer(bool withStencil, bool willReadDst); const GrVkFramebuffer* getFramebuffer(bool withStencil, bool needsXferBarrier);
const GrVkImageView* colorAttachmentView() const { return fColorAttachmentView; } const GrVkImageView* colorAttachmentView() const { return fColorAttachmentView; }
const GrManagedResource* msaaImageResource() const { const GrManagedResource* msaaImageResource() const {
if (fMSAAImage) { if (fMSAAImage) {
@ -56,49 +56,49 @@ public:
const GrManagedResource* stencilImageResource() const; const GrManagedResource* stencilImageResource() const;
const GrVkImageView* stencilAttachmentView() const; const GrVkImageView* stencilAttachmentView() const;
const GrVkRenderPass* getSimpleRenderPass(bool withStencil, bool willReadDst); const GrVkRenderPass* getSimpleRenderPass(bool withStencil, bool needsXferBarrier);
GrVkResourceProvider::CompatibleRPHandle compatibleRenderPassHandle(bool withStencil, GrVkResourceProvider::CompatibleRPHandle compatibleRenderPassHandle(bool withStencil,
bool willReadDst) { bool needsXferBarrier) {
SkASSERT(!this->wrapsSecondaryCommandBuffer()); SkASSERT(!this->wrapsSecondaryCommandBuffer());
GrVkResourceProvider::CompatibleRPHandle* pRPHandle; GrVkResourceProvider::CompatibleRPHandle* pRPHandle;
if (withStencil) { if (withStencil) {
if (willReadDst) { if (needsXferBarrier) {
pRPHandle = &fCompatibleStencilDstReadRPHandle; pRPHandle = &fCompatibleStencilSelfDepRPHandle;
} else { } else {
pRPHandle = &fCompatibleStencilRPHandle; pRPHandle = &fCompatibleStencilRPHandle;
} }
} else { } else {
if (willReadDst) { if (needsXferBarrier) {
pRPHandle = &fCompatibleDstReadRPHandle; pRPHandle = &fCompatibleSelfDepRPHandle;
} else { } else {
pRPHandle = &fCompatibleRPHandle; pRPHandle = &fCompatibleRPHandle;
} }
} }
if (!pRPHandle->isValid()) { if (!pRPHandle->isValid()) {
this->createSimpleRenderPass(withStencil, willReadDst); this->createSimpleRenderPass(withStencil, needsXferBarrier);
} }
#ifdef SK_DEBUG #ifdef SK_DEBUG
if (withStencil) { if (withStencil) {
if (willReadDst) { if (needsXferBarrier) {
SkASSERT(pRPHandle->isValid() == SkToBool(fCachedStencilDstReadRenderPass)); SkASSERT(pRPHandle->isValid() == SkToBool(fCachedStencilSelfDepRenderPass));
SkASSERT(fCachedStencilDstReadRenderPass->hasStencilAttachment()); SkASSERT(fCachedStencilSelfDepRenderPass->hasStencilAttachment());
SkASSERT(fCachedStencilDstReadRenderPass->hasInputSelfDependency()); SkASSERT(fCachedStencilSelfDepRenderPass->hasSelfDependency());
} else { } else {
SkASSERT(pRPHandle->isValid() == SkToBool(fCachedStencilRenderPass)); SkASSERT(pRPHandle->isValid() == SkToBool(fCachedStencilRenderPass));
SkASSERT(fCachedStencilRenderPass->hasStencilAttachment()); SkASSERT(fCachedStencilRenderPass->hasStencilAttachment());
SkASSERT(!fCachedStencilRenderPass->hasInputSelfDependency()); SkASSERT(!fCachedStencilRenderPass->hasSelfDependency());
} }
} else { } else {
if (willReadDst) { if (needsXferBarrier) {
SkASSERT(pRPHandle->isValid() == SkToBool(fCachedDstReadRenderPass)); SkASSERT(pRPHandle->isValid() == SkToBool(fCachedSelfDepRenderPass));
SkASSERT(!fCachedDstReadRenderPass->hasStencilAttachment()); SkASSERT(!fCachedSelfDepRenderPass->hasStencilAttachment());
SkASSERT(fCachedDstReadRenderPass->hasInputSelfDependency()); SkASSERT(fCachedSelfDepRenderPass->hasSelfDependency());
} else { } else {
SkASSERT(pRPHandle->isValid() == SkToBool(fCachedSimpleRenderPass)); SkASSERT(pRPHandle->isValid() == SkToBool(fCachedSimpleRenderPass));
SkASSERT(!fCachedSimpleRenderPass->hasStencilAttachment()); SkASSERT(!fCachedSimpleRenderPass->hasStencilAttachment());
SkASSERT(!fCachedSimpleRenderPass->hasInputSelfDependency()); SkASSERT(!fCachedSimpleRenderPass->hasSelfDependency());
} }
} }
#endif #endif
@ -136,7 +136,7 @@ public:
GrVkRenderPass::AttachmentsDescriptor* desc, GrVkRenderPass::AttachmentsDescriptor* desc,
GrVkRenderPass::AttachmentFlags* flags); GrVkRenderPass::AttachmentFlags* flags);
void addResources(GrVkCommandBuffer& commandBuffer, bool withStencil, bool willReadDst); void addResources(GrVkCommandBuffer& commandBuffer, bool withStencil, bool needsXferBarrier);
void addWrappedGrSecondaryCommandBuffer(std::unique_ptr<GrVkSecondaryCommandBuffer> cmdBuffer) { void addWrappedGrSecondaryCommandBuffer(std::unique_ptr<GrVkSecondaryCommandBuffer> cmdBuffer) {
fGrSecondaryCommandBuffers.push_back(std::move(cmdBuffer)); fGrSecondaryCommandBuffers.push_back(std::move(cmdBuffer));
@ -202,8 +202,8 @@ private:
GrVkGpu* getVkGpu() const; GrVkGpu* getVkGpu() const;
const GrVkRenderPass* createSimpleRenderPass(bool withStencil, bool willReadDst); const GrVkRenderPass* createSimpleRenderPass(bool withStencil, bool needsXferBarrier);
const GrVkFramebuffer* createFramebuffer(bool withStencil, bool willReadDst); const GrVkFramebuffer* createFramebuffer(bool withStencil, bool needsXferBarrier);
bool completeStencilAttachment() override; bool completeStencilAttachment() override;
@ -222,25 +222,27 @@ private:
const GrVkFramebuffer* fCachedFramebuffer = nullptr; const GrVkFramebuffer* fCachedFramebuffer = nullptr;
const GrVkFramebuffer* fCachedStencilFramebuffer = nullptr; const GrVkFramebuffer* fCachedStencilFramebuffer = nullptr;
const GrVkFramebuffer* fCachedDstReadFramebuffer = nullptr; const GrVkFramebuffer* fCachedSelfDepFramebuffer = nullptr;
const GrVkFramebuffer* fCachedStencilDstReadFramebuffer = nullptr; const GrVkFramebuffer* fCachedStencilSelfDepFramebuffer = nullptr;
// Cached pointers to a simple, stencil, and dst read render passes. The render target should // Cached pointers to a simple, stencil, and self dependency render passes. The render target
// unref them once it is done with them. // should unref them once it is done with them.
const GrVkRenderPass* fCachedSimpleRenderPass = nullptr; const GrVkRenderPass* fCachedSimpleRenderPass = nullptr;
const GrVkRenderPass* fCachedStencilRenderPass = nullptr; const GrVkRenderPass* fCachedStencilRenderPass = nullptr;
const GrVkRenderPass* fCachedDstReadRenderPass = nullptr; const GrVkRenderPass* fCachedSelfDepRenderPass = nullptr;
const GrVkRenderPass* fCachedStencilDstReadRenderPass = nullptr; const GrVkRenderPass* fCachedStencilSelfDepRenderPass = nullptr;
// This is a handle to be used to quickly get a GrVkRenderPass that is compatible with // 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. // this render target if its stencil buffer is ignored.
GrVkResourceProvider::CompatibleRPHandle fCompatibleRPHandle; GrVkResourceProvider::CompatibleRPHandle fCompatibleRPHandle;
// Same as above but taking the render target's stencil buffer into account // Same as above but taking the render target's stencil buffer into account
GrVkResourceProvider::CompatibleRPHandle fCompatibleStencilRPHandle; GrVkResourceProvider::CompatibleRPHandle fCompatibleStencilRPHandle;
// RenderPass where the render target is also read as an input attachment // RenderPass where there is also a self dependency to be used for advanced blending barriers.
GrVkResourceProvider::CompatibleRPHandle fCompatibleDstReadRPHandle; // 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 // Same as above but taking the render target's stencil buffer into account
GrVkResourceProvider::CompatibleRPHandle fCompatibleStencilDstReadRPHandle; GrVkResourceProvider::CompatibleRPHandle fCompatibleStencilSelfDepRPHandle;
// If this render target wraps an external VkCommandBuffer, then this handle will be that // 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 // VkCommandBuffer and not VK_NULL_HANDLE. In this case the render target will not be backed by

View File

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

View File

@ -59,10 +59,10 @@ public:
// compatible GrVkRenderPasses without the need inspecting a GrVkRenderTarget. // compatible GrVkRenderPasses without the need inspecting a GrVkRenderTarget.
const GrVkRenderPass* findCompatibleRenderPass(const GrVkRenderTarget& target, const GrVkRenderPass* findCompatibleRenderPass(const GrVkRenderTarget& target,
CompatibleRPHandle* compatibleHandle, CompatibleRPHandle* compatibleHandle,
bool withStencil, bool willReadDst); bool withStencil, bool needsSelfDependency);
const GrVkRenderPass* findCompatibleRenderPass(GrVkRenderPass::AttachmentsDescriptor*, const GrVkRenderPass* findCompatibleRenderPass(GrVkRenderPass::AttachmentsDescriptor*,
GrVkRenderPass::AttachmentFlags, GrVkRenderPass::AttachmentFlags,
bool willReadDst, bool needsSelfDependency,
CompatibleRPHandle* compatibleHandle = nullptr); CompatibleRPHandle* compatibleHandle = nullptr);
const GrVkRenderPass* findCompatibleExternalRenderPass(VkRenderPass, const GrVkRenderPass* findCompatibleExternalRenderPass(VkRenderPass,
@ -77,7 +77,8 @@ public:
const GrVkRenderPass::LoadStoreOps& colorOps, const GrVkRenderPass::LoadStoreOps& colorOps,
const GrVkRenderPass::LoadStoreOps& stencilOps, const GrVkRenderPass::LoadStoreOps& stencilOps,
CompatibleRPHandle* compatibleHandle, CompatibleRPHandle* compatibleHandle,
bool withStencil, bool willReadDst); bool withStencil,
bool needsSelfDependency);
// The CompatibleRPHandle must be a valid handle previously set by a call to findRenderPass or // The CompatibleRPHandle must be a valid handle previously set by a call to findRenderPass or
// findCompatibleRenderPass. // findCompatibleRenderPass.
@ -230,7 +231,7 @@ private:
bool isCompatible(const GrVkRenderPass::AttachmentsDescriptor&, bool isCompatible(const GrVkRenderPass::AttachmentsDescriptor&,
GrVkRenderPass::AttachmentFlags, GrVkRenderPass::AttachmentFlags,
bool willReadDst) const; bool needsSelfDependency) const;
const GrVkRenderPass* getCompatibleRenderPass() const { const GrVkRenderPass* getCompatibleRenderPass() const {
// The first GrVkRenderpass should always exist since we create the basic load store // The first GrVkRenderpass should always exist since we create the basic load store