Move cached render passes onto GrVkFramebuffer.

This moves them off of GrVkRenderTarget so that they can be directly
accessed with just a GrVkFramebuffer.

Bug: skia:11809
Change-Id: I5e5024779dc106642de9035400df2b04d35ad753
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/398657
Commit-Queue: Greg Daniel <egdaniel@google.com>
Reviewed-by: Jim Van Verth <jvanverth@google.com>
This commit is contained in:
Greg Daniel 2021-04-20 12:44:48 -04:00 committed by Skia Commit-Bot
parent 3036defd9e
commit 805c62200d
5 changed files with 88 additions and 106 deletions

View File

@ -1842,8 +1842,8 @@ GrProgramDesc GrVkCaps::makeDesc(GrRenderTarget* rt,
bool needsStencil = programInfo.numStencilSamples() || programInfo.isStencilEnabled(); bool needsStencil = programInfo.numStencilSamples() || programInfo.isStencilEnabled();
// TODO: support failure in getSimpleRenderPass // TODO: support failure in getSimpleRenderPass
auto[rp, compatibleHandle] = vkRT->getSimpleRenderPass(needsResolve, needsStencil, auto rp = vkRT->getSimpleRenderPass(needsResolve, needsStencil, selfDepFlags,
selfDepFlags, loadFromResolve); loadFromResolve);
SkASSERT(rp); SkASSERT(rp);
rp->genKey(&b); rp->genKey(&b);

View File

@ -13,16 +13,16 @@
#include "src/gpu/vk/GrVkImageView.h" #include "src/gpu/vk/GrVkImageView.h"
#include "src/gpu/vk/GrVkRenderPass.h" #include "src/gpu/vk/GrVkRenderPass.h"
GrVkFramebuffer* GrVkFramebuffer::Create( sk_sp<const GrVkFramebuffer> GrVkFramebuffer::Make(
GrVkGpu* gpu, GrVkGpu* gpu,
SkISize dimensions, SkISize dimensions,
const GrVkRenderPass* renderPass, sk_sp<const GrVkRenderPass> compatibleRenderPass,
GrVkAttachment* colorAttachment, GrVkAttachment* colorAttachment,
GrVkAttachment* resolveAttachment, GrVkAttachment* resolveAttachment,
GrVkAttachment* stencilAttachment, GrVkAttachment* stencilAttachment,
GrVkResourceProvider::CompatibleRPHandle compatibleRenderPassHandle) { GrVkResourceProvider::CompatibleRPHandle compatibleRenderPassHandle) {
// At the very least we need a renderPass and a colorAttachment // At the very least we need a renderPass and a colorAttachment
SkASSERT(renderPass); SkASSERT(compatibleRenderPass);
SkASSERT(colorAttachment); SkASSERT(colorAttachment);
VkImageView attachments[3]; VkImageView attachments[3];
@ -40,7 +40,7 @@ GrVkFramebuffer* GrVkFramebuffer::Create(
createInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; createInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
createInfo.pNext = nullptr; createInfo.pNext = nullptr;
createInfo.flags = 0; createInfo.flags = 0;
createInfo.renderPass = renderPass->vkRenderPass(); createInfo.renderPass = compatibleRenderPass->vkRenderPass();
createInfo.attachmentCount = numAttachments; createInfo.attachmentCount = numAttachments;
createInfo.pAttachments = attachments; createInfo.pAttachments = attachments;
createInfo.width = dimensions.width(); createInfo.width = dimensions.width();
@ -55,9 +55,10 @@ GrVkFramebuffer* GrVkFramebuffer::Create(
return nullptr; return nullptr;
} }
return new GrVkFramebuffer(gpu, framebuffer, sk_ref_sp(colorAttachment), auto fb = new GrVkFramebuffer(gpu, framebuffer, sk_ref_sp(colorAttachment),
sk_ref_sp(resolveAttachment), sk_ref_sp(stencilAttachment), sk_ref_sp(resolveAttachment), sk_ref_sp(stencilAttachment),
compatibleRenderPassHandle); std::move(compatibleRenderPass), compatibleRenderPassHandle);
return sk_sp<const GrVkFramebuffer>(fb);
} }
GrVkFramebuffer::GrVkFramebuffer(const GrVkGpu* gpu, GrVkFramebuffer::GrVkFramebuffer(const GrVkGpu* gpu,
@ -65,12 +66,14 @@ GrVkFramebuffer::GrVkFramebuffer(const GrVkGpu* gpu,
sk_sp<GrVkAttachment> colorAttachment, sk_sp<GrVkAttachment> colorAttachment,
sk_sp<GrVkAttachment> resolveAttachment, sk_sp<GrVkAttachment> resolveAttachment,
sk_sp<GrVkAttachment> stencilAttachment, sk_sp<GrVkAttachment> stencilAttachment,
sk_sp<const GrVkRenderPass> compatibleRenderPass,
GrVkResourceProvider::CompatibleRPHandle compatibleRPHandle) GrVkResourceProvider::CompatibleRPHandle compatibleRPHandle)
: GrVkManagedResource(gpu) : GrVkManagedResource(gpu)
, fFramebuffer(framebuffer) , fFramebuffer(framebuffer)
, fColorAttachment(std::move(colorAttachment)) , fColorAttachment(std::move(colorAttachment))
, fResolveAttachment(std::move(resolveAttachment)) , fResolveAttachment(std::move(resolveAttachment))
, fStencilAttachment(std::move(stencilAttachment)) , fStencilAttachment(std::move(stencilAttachment))
, fCompatibleRenderPass(std::move(compatibleRenderPass))
, fCompatibleRenderPassHandle(compatibleRPHandle) { , fCompatibleRenderPassHandle(compatibleRPHandle) {
SkASSERT(fCompatibleRenderPassHandle.isValid()); SkASSERT(fCompatibleRenderPassHandle.isValid());
} }

View File

@ -20,13 +20,13 @@ class GrVkRenderPass;
class GrVkFramebuffer : public GrVkManagedResource { class GrVkFramebuffer : public GrVkManagedResource {
public: public:
static GrVkFramebuffer* Create(GrVkGpu* gpu, static sk_sp<const GrVkFramebuffer> Make(GrVkGpu* gpu,
SkISize dimensions, SkISize dimensions,
const GrVkRenderPass* renderPass, sk_sp<const GrVkRenderPass> compatibleRenderPass,
GrVkAttachment* colorAttachment, GrVkAttachment* colorAttachment,
GrVkAttachment* resolveAttachment, GrVkAttachment* resolveAttachment,
GrVkAttachment* stencilAttachment, GrVkAttachment* stencilAttachment,
GrVkResourceProvider::CompatibleRPHandle); GrVkResourceProvider::CompatibleRPHandle);
// Used for wrapped external secondary command buffers // Used for wrapped external secondary command buffers
GrVkFramebuffer(const GrVkGpu* gpu, GrVkFramebuffer(const GrVkGpu* gpu,
@ -61,6 +61,8 @@ public:
} }
#endif #endif
const GrVkRenderPass* compatibleRenderPass() const { return fCompatibleRenderPass.get(); }
GrVkResourceProvider::CompatibleRPHandle compatibleRenderPassHandle() const { GrVkResourceProvider::CompatibleRPHandle compatibleRenderPassHandle() const {
return fCompatibleRenderPassHandle; return fCompatibleRenderPassHandle;
} }
@ -75,6 +77,7 @@ private:
sk_sp<GrVkAttachment> colorAttachment, sk_sp<GrVkAttachment> colorAttachment,
sk_sp<GrVkAttachment> resolveAttachment, sk_sp<GrVkAttachment> resolveAttachment,
sk_sp<GrVkAttachment> stencilAttachment, sk_sp<GrVkAttachment> stencilAttachment,
sk_sp<const GrVkRenderPass> compatibleRenderPass,
GrVkResourceProvider::CompatibleRPHandle); GrVkResourceProvider::CompatibleRPHandle);
~GrVkFramebuffer() override; ~GrVkFramebuffer() override;
@ -88,6 +91,7 @@ private:
sk_sp<GrVkAttachment> fResolveAttachment; sk_sp<GrVkAttachment> fResolveAttachment;
sk_sp<GrVkAttachment> fStencilAttachment; sk_sp<GrVkAttachment> fStencilAttachment;
sk_sp<const GrVkRenderPass> fCompatibleRenderPass;
GrVkResourceProvider::CompatibleRPHandle fCompatibleRenderPassHandle; GrVkResourceProvider::CompatibleRPHandle fCompatibleRenderPassHandle;
sk_sp<const GrVkRenderPass> fExternalRenderPass; sk_sp<const GrVkRenderPass> fExternalRenderPass;

View File

@ -61,8 +61,7 @@ GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu,
colorAttachment->isProtected() ? GrProtected::kYes : GrProtected::kNo) colorAttachment->isProtected() ? GrProtected::kYes : GrProtected::kNo)
, fColorAttachment(std::move(colorAttachment)) , fColorAttachment(std::move(colorAttachment))
, fResolveAttachment(std::move(resolveAttachment)) , fResolveAttachment(std::move(resolveAttachment))
, fCachedFramebuffers() , fCachedFramebuffers() {
, fCachedRenderPasses() {
SkASSERT(fColorAttachment); SkASSERT(fColorAttachment);
SkASSERT(!resolveAttachment || SkASSERT(!resolveAttachment ||
(fResolveAttachment->isProtected() == fColorAttachment->isProtected())); (fResolveAttachment->isProtected() == fColorAttachment->isProtected()));
@ -83,7 +82,6 @@ GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu,
externalFramebuffer->colorAttachment()->isProtected() ? GrProtected::kYes externalFramebuffer->colorAttachment()->isProtected() ? GrProtected::kYes
: GrProtected::kNo) : GrProtected::kNo)
, fCachedFramebuffers() , fCachedFramebuffers()
, fCachedRenderPasses()
, fExternalFramebuffer(externalFramebuffer) { , fExternalFramebuffer(externalFramebuffer) {
SkASSERT(fExternalFramebuffer); SkASSERT(fExternalFramebuffer);
SkASSERT(!fColorAttachment); SkASSERT(!fColorAttachment);
@ -245,66 +243,47 @@ GrVkResourceProvider::CompatibleRPHandle GrVkRenderTarget::compatibleRenderPassH
LoadFromResolve loadFromResolve) { LoadFromResolve loadFromResolve) {
SkASSERT(!this->wrapsSecondaryCommandBuffer()); SkASSERT(!this->wrapsSecondaryCommandBuffer());
int cacheIndex = const GrVkFramebuffer* fb =
renderpass_features_to_index(withResolve, withStencil, selfDepFlags, loadFromResolve); this->getFramebuffer(withResolve, withStencil, selfDepFlags, loadFromResolve);
SkASSERT(cacheIndex < GrVkRenderTarget::kNumCachedRenderPasses); if (!fb) {
return {};
GrVkResourceProvider::CompatibleRPHandle* pRPHandle;
pRPHandle = &fCompatibleRPHandles[cacheIndex];
if (!pRPHandle->isValid()) {
this->createSimpleRenderPass(withResolve, withStencil, selfDepFlags, loadFromResolve);
} }
#ifdef SK_DEBUG return fb->compatibleRenderPassHandle();
const GrVkRenderPass* rp = fCachedRenderPasses[cacheIndex]; }
SkASSERT(pRPHandle->isValid() == SkToBool(rp));
if (rp) {
SkASSERT(selfDepFlags == rp->selfDependencyFlags());
}
#endif
return *pRPHandle; const GrVkRenderPass* GrVkRenderTarget::getSimpleRenderPass(bool withResolve,
bool withStencil,
SelfDependencyFlags selfDepFlags,
LoadFromResolve loadFromResolve) {
if (this->wrapsSecondaryCommandBuffer()) {
return fExternalFramebuffer->externalRenderPass();
}
const GrVkFramebuffer* fb =
this->getFramebuffer(withResolve, withStencil, selfDepFlags, loadFromResolve);
if (!fb) {
return nullptr;
}
return fb->compatibleRenderPass();
} }
std::pair<const GrVkRenderPass*, GrVkResourceProvider::CompatibleRPHandle> std::pair<const GrVkRenderPass*, GrVkResourceProvider::CompatibleRPHandle>
GrVkRenderTarget::getSimpleRenderPass(bool withResolve, GrVkRenderTarget::createSimpleRenderPass(bool withResolve,
bool withStencil, bool withStencil,
SelfDependencyFlags selfDepFlags, SelfDependencyFlags selfDepFlags,
LoadFromResolve loadFromResolve) { LoadFromResolve loadFromResolve) {
if (this->wrapsSecondaryCommandBuffer()) {
// The compatible handle is invalid for external render passes used in wrapped secondary
// command buffers. However, this should not be called by code using external render passes
// that needs to use the handle.
return {fExternalFramebuffer->externalRenderPass(),
GrVkResourceProvider::CompatibleRPHandle()};
}
int cacheIndex =
renderpass_features_to_index(withResolve, withStencil, selfDepFlags, loadFromResolve);
SkASSERT(cacheIndex < GrVkRenderTarget::kNumCachedRenderPasses);
const GrVkRenderPass* rp = fCachedRenderPasses[cacheIndex];
if (!rp) {
rp = this->createSimpleRenderPass(withResolve, withStencil, selfDepFlags, loadFromResolve);
}
SkASSERT(!rp || fCompatibleRPHandles[cacheIndex].isValid());
return {rp, fCompatibleRPHandles[cacheIndex]};
}
const GrVkRenderPass* GrVkRenderTarget::createSimpleRenderPass(bool withResolve,
bool withStencil,
SelfDependencyFlags selfDepFlags,
LoadFromResolve loadFromResolve) {
SkASSERT(!this->wrapsSecondaryCommandBuffer()); SkASSERT(!this->wrapsSecondaryCommandBuffer());
GrVkResourceProvider& rp = this->getVkGpu()->resourceProvider(); GrVkResourceProvider& rp = this->getVkGpu()->resourceProvider();
int cacheIndex = renderpass_features_to_index(withResolve, withStencil, selfDepFlags,
loadFromResolve); GrVkResourceProvider::CompatibleRPHandle handle;
SkASSERT(cacheIndex < GrVkRenderTarget::kNumCachedRenderPasses); const GrVkRenderPass* renderPass = rp.findCompatibleRenderPass(
SkASSERT(!fCachedRenderPasses[cacheIndex]); this, &handle, withResolve, withStencil, selfDepFlags,
fCachedRenderPasses[cacheIndex] = rp.findCompatibleRenderPass(
this, &fCompatibleRPHandles[cacheIndex], withResolve, withStencil, selfDepFlags,
loadFromResolve); loadFromResolve);
return fCachedRenderPasses[cacheIndex]; SkASSERT(!renderPass || handle.isValid());
return {renderPass, handle};
} }
const GrVkFramebuffer* GrVkRenderTarget::getFramebuffer(bool withResolve, const GrVkFramebuffer* GrVkRenderTarget::getFramebuffer(bool withResolve,
@ -313,31 +292,32 @@ const GrVkFramebuffer* GrVkRenderTarget::getFramebuffer(bool withResolve,
LoadFromResolve loadFromResolve) { LoadFromResolve loadFromResolve) {
int cacheIndex = int cacheIndex =
renderpass_features_to_index(withResolve, withStencil, selfDepFlags, loadFromResolve); renderpass_features_to_index(withResolve, withStencil, selfDepFlags, loadFromResolve);
SkASSERT(cacheIndex < GrVkRenderTarget::kNumCachedRenderPasses); SkASSERT(cacheIndex < GrVkRenderTarget::kNumCachedFramebuffers);
if (auto fb = fCachedFramebuffers[cacheIndex]) { if (auto fb = fCachedFramebuffers[cacheIndex]) {
return fb; return fb.get();
} }
return this->createFramebuffer(withResolve, withStencil, selfDepFlags, loadFromResolve); this->createFramebuffer(withResolve, withStencil, selfDepFlags, loadFromResolve);
return fCachedFramebuffers[cacheIndex].get();
} }
const GrVkFramebuffer* GrVkRenderTarget::createFramebuffer(bool withResolve, void GrVkRenderTarget::createFramebuffer(bool withResolve,
bool withStencil, bool withStencil,
SelfDependencyFlags selfDepFlags, SelfDependencyFlags selfDepFlags,
LoadFromResolve loadFromResolve) { LoadFromResolve loadFromResolve) {
SkASSERT(!this->wrapsSecondaryCommandBuffer()); SkASSERT(!this->wrapsSecondaryCommandBuffer());
GrVkGpu* gpu = this->getVkGpu(); GrVkGpu* gpu = this->getVkGpu();
auto[renderPass, compatibleHandle] = auto[renderPass, compatibleHandle] =
this->getSimpleRenderPass(withResolve, withStencil, selfDepFlags, loadFromResolve); this->createSimpleRenderPass(withResolve, withStencil, selfDepFlags, loadFromResolve);
if (!renderPass) { if (!renderPass) {
return nullptr; return;
} }
SkASSERT(compatibleHandle.isValid()); SkASSERT(compatibleHandle.isValid());
int cacheIndex = int cacheIndex =
renderpass_features_to_index(withResolve, withStencil, selfDepFlags, loadFromResolve); renderpass_features_to_index(withResolve, withStencil, selfDepFlags, loadFromResolve);
SkASSERT(cacheIndex < GrVkRenderTarget::kNumCachedRenderPasses); SkASSERT(cacheIndex < GrVkRenderTarget::kNumCachedFramebuffers);
GrVkAttachment* resolve = withResolve ? this->resolveAttachment() : nullptr; GrVkAttachment* resolve = withResolve ? this->resolveAttachment() : nullptr;
GrVkAttachment* colorAttachment = GrVkAttachment* colorAttachment =
@ -348,10 +328,9 @@ const GrVkFramebuffer* GrVkRenderTarget::createFramebuffer(bool withResolve,
withStencil ? static_cast<GrVkAttachment*>(this->getStencilAttachment()) withStencil ? static_cast<GrVkAttachment*>(this->getStencilAttachment())
: nullptr; : nullptr;
fCachedFramebuffers[cacheIndex] = fCachedFramebuffers[cacheIndex] =
GrVkFramebuffer::Create(gpu, this->dimensions(), renderPass, GrVkFramebuffer::Make(gpu, this->dimensions(),
colorAttachment, resolve, stencil, compatibleHandle); sk_sp<const GrVkRenderPass>(renderPass),
colorAttachment, resolve, stencil, compatibleHandle);
return fCachedFramebuffers[cacheIndex];
} }
void GrVkRenderTarget::getAttachmentsDescriptor(GrVkRenderPass::AttachmentsDescriptor* desc, void GrVkRenderTarget::getAttachmentsDescriptor(GrVkRenderPass::AttachmentsDescriptor* desc,
@ -474,10 +453,10 @@ GrVkRenderTarget::~GrVkRenderTarget() {
// either release or abandon should have been called by the owner of this object. // either release or abandon should have been called by the owner of this object.
SkASSERT(!fColorAttachment); SkASSERT(!fColorAttachment);
SkASSERT(!fResolveAttachment); SkASSERT(!fResolveAttachment);
SkASSERT(!fDynamicMSAAAttachment);
for (int i = 0; i < kNumCachedRenderPasses; ++i) { for (int i = 0; i < kNumCachedFramebuffers; ++i) {
SkASSERT(!fCachedFramebuffers[i]); SkASSERT(!fCachedFramebuffers[i]);
SkASSERT(!fCachedRenderPasses[i]);
} }
SkASSERT(!fCachedInputDescriptorSet); SkASSERT(!fCachedInputDescriptorSet);
@ -486,15 +465,11 @@ GrVkRenderTarget::~GrVkRenderTarget() {
void GrVkRenderTarget::releaseInternalObjects() { void GrVkRenderTarget::releaseInternalObjects() {
fColorAttachment.reset(); fColorAttachment.reset();
fResolveAttachment.reset(); fResolveAttachment.reset();
fDynamicMSAAAttachment.reset();
for (int i = 0; i < kNumCachedRenderPasses; ++i) { for (int i = 0; i < kNumCachedFramebuffers; ++i) {
if (fCachedFramebuffers[i]) { if (fCachedFramebuffers[i]) {
fCachedFramebuffers[i]->unref(); fCachedFramebuffers[i].reset();
fCachedFramebuffers[i] = nullptr;
}
if (fCachedRenderPasses[i]) {
fCachedRenderPasses[i]->unref();
fCachedRenderPasses[i] = nullptr;
} }
} }

View File

@ -86,7 +86,7 @@ public:
return fResolveAttachment ? fResolveAttachment.get() : fColorAttachment.get(); return fResolveAttachment ? fResolveAttachment.get() : fColorAttachment.get();
} }
std::pair<const GrVkRenderPass*, GrVkResourceProvider::CompatibleRPHandle> getSimpleRenderPass( const GrVkRenderPass* getSimpleRenderPass(
bool withResolve, bool withResolve,
bool withStencil, bool withStencil,
SelfDependencyFlags selfDepFlags, SelfDependencyFlags selfDepFlags,
@ -158,14 +158,15 @@ private:
GrVkAttachment* dynamicMSAAAttachment(); GrVkAttachment* dynamicMSAAAttachment();
GrVkAttachment* msaaAttachment(); GrVkAttachment* msaaAttachment();
const GrVkRenderPass* createSimpleRenderPass(bool withResolve, std::pair<const GrVkRenderPass*, GrVkResourceProvider::CompatibleRPHandle>
bool withStencil, createSimpleRenderPass(bool withResolve,
SelfDependencyFlags selfDepFlags, bool withStencil,
LoadFromResolve); SelfDependencyFlags selfDepFlags,
const GrVkFramebuffer* createFramebuffer(bool withResolve, LoadFromResolve);
bool withStencil, void createFramebuffer(bool withResolve,
SelfDependencyFlags selfDepFlags, bool withStencil,
LoadFromResolve); SelfDependencyFlags selfDepFlags,
LoadFromResolve);
bool completeStencilAttachment() override; bool completeStencilAttachment() override;
@ -187,12 +188,11 @@ private:
// We can have a renderpass with and without resolve attachment, stencil attachment, // We can have a renderpass with and without resolve attachment, stencil attachment,
// input attachment dependency, advanced blend dependency, and loading from resolve. All 5 of // input attachment dependency, advanced blend dependency, and loading from resolve. All 5 of
// these being completely orthogonal. Thus we have a total of 32 types of render passes. // these being completely orthogonal. Thus we have a total of 32 types of render passes. We then
static constexpr int kNumCachedRenderPasses = 32; // cache a framebuffer for each type of these render passes.
static constexpr int kNumCachedFramebuffers = 32;
const GrVkFramebuffer* fCachedFramebuffers[kNumCachedRenderPasses]; sk_sp<const GrVkFramebuffer> fCachedFramebuffers[kNumCachedFramebuffers];
const GrVkRenderPass* fCachedRenderPasses[kNumCachedRenderPasses];
GrVkResourceProvider::CompatibleRPHandle fCompatibleRPHandles[kNumCachedRenderPasses];
const GrVkDescriptorSet* fCachedInputDescriptorSet = nullptr; const GrVkDescriptorSet* fCachedInputDescriptorSet = nullptr;