Add handling of failed framebuffer creation in vulkan.
Bug: skia:9603
Change-Id: I264d1387f319cbe3bb27982ccc6e01fb530abbd5
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/253238
Commit-Queue: Greg Daniel <egdaniel@google.com>
Reviewed-by: Chris Dalton <csmartdalton@google.com>
diff --git a/src/gpu/GrOpsTask.cpp b/src/gpu/GrOpsTask.cpp
index ed4aba5..62a94cd 100644
--- a/src/gpu/GrOpsTask.cpp
+++ b/src/gpu/GrOpsTask.cpp
@@ -543,6 +543,9 @@
flushState->gpu(), proxy->peekRenderTarget(), fTargetView.origin(),
fClippedContentBounds, fColorLoadOp, fLoadClearColor, stencilLoadOp, stencilStoreOp,
fSampledProxies);
+ if (!renderPass) {
+ return false;
+ }
flushState->setOpsRenderPass(renderPass);
renderPass->begin();
diff --git a/src/gpu/vk/GrVkCommandBuffer.cpp b/src/gpu/vk/GrVkCommandBuffer.cpp
index 4177102..2aed1b5 100644
--- a/src/gpu/vk/GrVkCommandBuffer.cpp
+++ b/src/gpu/vk/GrVkCommandBuffer.cpp
@@ -421,15 +421,20 @@
fHasWork = false;
}
-void GrVkPrimaryCommandBuffer::beginRenderPass(const GrVkGpu* gpu,
+bool GrVkPrimaryCommandBuffer::beginRenderPass(GrVkGpu* gpu,
const GrVkRenderPass* renderPass,
const VkClearValue clearValues[],
- const GrVkRenderTarget& target,
+ GrVkRenderTarget* target,
const SkIRect& bounds,
bool forSecondaryCB) {
SkASSERT(fIsActive);
SkASSERT(!fActiveRenderPass);
- SkASSERT(renderPass->isCompatible(target));
+ SkASSERT(renderPass->isCompatible(*target));
+
+ const GrVkFramebuffer* framebuffer = target->getFramebuffer();
+ if (!framebuffer) {
+ return false;
+ }
this->addingWork(gpu);
@@ -442,7 +447,7 @@
beginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
beginInfo.pNext = nullptr;
beginInfo.renderPass = renderPass->vkRenderPass();
- beginInfo.framebuffer = target.framebuffer()->framebuffer();
+ beginInfo.framebuffer = framebuffer->framebuffer();
beginInfo.renderArea = renderArea;
beginInfo.clearValueCount = renderPass->clearValueCount();
beginInfo.pClearValues = clearValues;
@@ -453,7 +458,8 @@
GR_VK_CALL(gpu->vkInterface(), CmdBeginRenderPass(fCmdBuffer, &beginInfo, contents));
fActiveRenderPass = renderPass;
this->addResource(renderPass);
- target.addResources(*this);
+ target->addResources(*this);
+ return true;
}
void GrVkPrimaryCommandBuffer::endRenderPass(const GrVkGpu* gpu) {
diff --git a/src/gpu/vk/GrVkCommandBuffer.h b/src/gpu/vk/GrVkCommandBuffer.h
index 7b34e2b..cb603f6 100644
--- a/src/gpu/vk/GrVkCommandBuffer.h
+++ b/src/gpu/vk/GrVkCommandBuffer.h
@@ -99,6 +99,7 @@
// Add ref-counted resource that will be tracked and released when this command buffer finishes
// execution
void addResource(const GrVkResource* resource) {
+ SkASSERT(resource);
resource->ref();
resource->notifyAddedToCommandBuffer();
fTrackedResources.append(1, &resource);
@@ -205,10 +206,10 @@
// Begins render pass on this command buffer. The framebuffer from GrVkRenderTarget will be used
// in the render pass.
- void beginRenderPass(const GrVkGpu* gpu,
+ bool beginRenderPass(GrVkGpu* gpu,
const GrVkRenderPass* renderPass,
const VkClearValue clearValues[],
- const GrVkRenderTarget& target,
+ GrVkRenderTarget* target,
const SkIRect& bounds,
bool forSecondaryCB);
void endRenderPass(const GrVkGpu* gpu);
diff --git a/src/gpu/vk/GrVkFramebuffer.cpp b/src/gpu/vk/GrVkFramebuffer.cpp
index a06d792..f256999 100644
--- a/src/gpu/vk/GrVkFramebuffer.cpp
+++ b/src/gpu/vk/GrVkFramebuffer.cpp
@@ -40,10 +40,9 @@
createInfo.layers = 1;
VkFramebuffer framebuffer;
- VkResult err = GR_VK_CALL(gpu->vkInterface(), CreateFramebuffer(gpu->device(),
- &createInfo,
- nullptr,
- &framebuffer));
+ VkResult err;
+ GR_VK_CALL_RESULT(gpu, err, CreateFramebuffer(gpu->device(), &createInfo, nullptr,
+ &framebuffer));
if (err) {
return nullptr;
}
diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp
index 99e6afd..cb48930 100644
--- a/src/gpu/vk/GrVkGpu.cpp
+++ b/src/gpu/vk/GrVkGpu.cpp
@@ -328,7 +328,9 @@
fCachedOpsRenderPass.reset(new GrVkOpsRenderPass(this));
}
- fCachedOpsRenderPass->set(rt, origin, bounds, colorInfo, stencilInfo, sampledProxies);
+ if (!fCachedOpsRenderPass->set(rt, origin, bounds, colorInfo, stencilInfo, sampledProxies)) {
+ return nullptr;
+ }
return fCachedOpsRenderPass.get();
}
@@ -2390,7 +2392,7 @@
}
}
-void GrVkGpu::beginRenderPass(const GrVkRenderPass* renderPass,
+bool GrVkGpu::beginRenderPass(const GrVkRenderPass* renderPass,
const VkClearValue* colorClear,
GrVkRenderTarget* target, GrSurfaceOrigin origin,
const SkIRect& bounds, bool forSecondaryCB) {
@@ -2423,8 +2425,8 @@
clears[1].depthStencil.depth = 0.0f;
clears[1].depthStencil.stencil = 0;
- fCurrentCmdBuffer->beginRenderPass(this, renderPass, clears, *target, adjustedBounds,
- forSecondaryCB);
+ return fCurrentCmdBuffer->beginRenderPass(this, renderPass, clears, target, adjustedBounds,
+ forSecondaryCB);
}
void GrVkGpu::endRenderPass(GrRenderTarget* target, GrSurfaceOrigin origin,
diff --git a/src/gpu/vk/GrVkGpu.h b/src/gpu/vk/GrVkGpu.h
index ebccc19..d835521 100644
--- a/src/gpu/vk/GrVkGpu.h
+++ b/src/gpu/vk/GrVkGpu.h
@@ -166,7 +166,7 @@
void storeVkPipelineCacheData() override;
- void beginRenderPass(const GrVkRenderPass*,
+ bool beginRenderPass(const GrVkRenderPass*,
const VkClearValue* colorClear,
GrVkRenderTarget*, GrSurfaceOrigin,
const SkIRect& bounds, bool forSecondaryCB);
diff --git a/src/gpu/vk/GrVkOpsRenderPass.cpp b/src/gpu/vk/GrVkOpsRenderPass.cpp
index 6b61980..fe811c3 100644
--- a/src/gpu/vk/GrVkOpsRenderPass.cpp
+++ b/src/gpu/vk/GrVkOpsRenderPass.cpp
@@ -60,7 +60,7 @@
GrVkOpsRenderPass::GrVkOpsRenderPass(GrVkGpu* gpu) : fGpu(gpu) {}
-void GrVkOpsRenderPass::init(const GrOpsRenderPass::LoadAndStoreInfo& colorInfo,
+bool GrVkOpsRenderPass::init(const GrOpsRenderPass::LoadAndStoreInfo& colorInfo,
const GrOpsRenderPass::StencilLoadAndStoreInfo& stencilInfo,
const SkPMColor4f& clearColor) {
@@ -101,13 +101,14 @@
false);
}
- const GrVkResourceProvider::CompatibleRPHandle& rpHandle = vkRT->compatibleRenderPassHandle();
+ const GrVkResourceProvider::CompatibleRPHandle& rpHandle =
+ vkRT->compatibleRenderPassHandle();
if (rpHandle.isValid()) {
fCurrentRenderPass = fGpu->resourceProvider().findRenderPass(rpHandle,
vkColorOps,
vkStencilOps);
} else {
- fCurrentRenderPass = fGpu->resourceProvider().findRenderPass(*vkRT,
+ fCurrentRenderPass = fGpu->resourceProvider().findRenderPass(vkRT,
vkColorOps,
vkStencilOps);
}
@@ -121,11 +122,19 @@
if (!fGpu->vkCaps().preferPrimaryOverSecondaryCommandBuffers()) {
fCurrentSecondaryCommandBuffer = fGpu->cmdPool()->findOrCreateSecondaryCommandBuffer(fGpu);
- fCurrentSecondaryCommandBuffer->begin(fGpu, vkRT->framebuffer(), fCurrentRenderPass);
+ fCurrentSecondaryCommandBuffer->begin(fGpu, vkRT->getFramebuffer(), fCurrentRenderPass);
}
- fGpu->beginRenderPass(fCurrentRenderPass, &vkClearColor, vkRT, fOrigin, fBounds,
- SkToBool(fCurrentSecondaryCommandBuffer));
+ if (!fGpu->beginRenderPass(fCurrentRenderPass, &vkClearColor, vkRT, fOrigin, fBounds,
+ SkToBool(fCurrentSecondaryCommandBuffer))) {
+ if (fCurrentSecondaryCommandBuffer) {
+ fCurrentSecondaryCommandBuffer->end(fGpu);
+ }
+ fGpu->endRenderPass(fRenderTarget, fOrigin, fBounds);
+ fCurrentRenderPass = nullptr;
+ return false;
+ }
+ return true;
}
void GrVkOpsRenderPass::initWrapped() {
@@ -163,6 +172,10 @@
if (!fRenderTarget) {
return;
}
+ if (!fCurrentRenderPass) {
+ SkASSERT(fGpu->isDeviceLost());
+ return;
+ }
// We don't want to actually submit the secondary command buffer if it is wrapped.
if (this->wrapsSecondaryCommandBuffer()) {
@@ -175,7 +188,7 @@
fGpu->endRenderPass(fRenderTarget, fOrigin, fBounds);
}
-void GrVkOpsRenderPass::set(GrRenderTarget* rt, GrSurfaceOrigin origin, const SkIRect& bounds,
+bool GrVkOpsRenderPass::set(GrRenderTarget* rt, GrSurfaceOrigin origin, const SkIRect& bounds,
const GrOpsRenderPass::LoadAndStoreInfo& colorInfo,
const GrOpsRenderPass::StencilLoadAndStoreInfo& stencilInfo,
const SkTArray<GrTextureProxy*, true>& sampledProxies) {
@@ -203,10 +216,10 @@
if (this->wrapsSecondaryCommandBuffer()) {
this->initWrapped();
- return;
+ return true;
}
- this->init(colorInfo, stencilInfo, colorInfo.fClearColor);
+ return this->init(colorInfo, stencilInfo, colorInfo.fClearColor);
}
void GrVkOpsRenderPass::reset() {
@@ -238,6 +251,11 @@
}
void GrVkOpsRenderPass::onClearStencilClip(const GrFixedClip& clip, bool insideStencilMask) {
+ if (!fCurrentRenderPass) {
+ SkASSERT(fGpu->isDeviceLost());
+ return;
+ }
+
SkASSERT(!clip.hasWindowRectangles());
GrStencilAttachment* sb = fRenderTarget->renderTargetPriv().getStencilAttachment();
@@ -289,6 +307,11 @@
}
void GrVkOpsRenderPass::onClear(const GrFixedClip& clip, const SkPMColor4f& color) {
+ if (!fCurrentRenderPass) {
+ SkASSERT(fGpu->isDeviceLost());
+ return;
+ }
+
// parent class should never let us get here with no RT
SkASSERT(!clip.hasWindowRectangles());
@@ -353,7 +376,7 @@
vkColorOps,
vkStencilOps);
} else {
- fCurrentRenderPass = fGpu->resourceProvider().findRenderPass(*vkRT,
+ fCurrentRenderPass = fGpu->resourceProvider().findRenderPass(vkRT,
vkColorOps,
vkStencilOps);
}
@@ -365,16 +388,26 @@
if (!fGpu->vkCaps().preferPrimaryOverSecondaryCommandBuffers() ||
mustUseSecondaryCommandBuffer) {
fCurrentSecondaryCommandBuffer = fGpu->cmdPool()->findOrCreateSecondaryCommandBuffer(fGpu);
- fCurrentSecondaryCommandBuffer->begin(fGpu, vkRT->framebuffer(), fCurrentRenderPass);
+ fCurrentSecondaryCommandBuffer->begin(fGpu, vkRT->getFramebuffer(), fCurrentRenderPass);
}
// We use the same fBounds as the whole GrVkOpsRenderPass since we have no way of tracking the
// bounds in GrOpsTask for parts before and after inline uploads separately.
- fGpu->beginRenderPass(fCurrentRenderPass, &vkClearColor, vkRT, fOrigin, fBounds,
- SkToBool(fCurrentSecondaryCommandBuffer));
+ if (!fGpu->beginRenderPass(fCurrentRenderPass, &vkClearColor, vkRT, fOrigin, fBounds,
+ SkToBool(fCurrentSecondaryCommandBuffer))) {
+ if (fCurrentSecondaryCommandBuffer) {
+ fCurrentSecondaryCommandBuffer->end(fGpu);
+ }
+ fGpu->endRenderPass(fRenderTarget, fOrigin, fBounds);
+ fCurrentRenderPass = nullptr;
+ }
}
void GrVkOpsRenderPass::inlineUpload(GrOpFlushState* state, GrDeferredTextureUploadFn& upload) {
+ if (!fCurrentRenderPass) {
+ SkASSERT(fGpu->isDeviceLost());
+ return;
+ }
if (fCurrentSecondaryCommandBuffer) {
fCurrentSecondaryCommandBuffer->end(fGpu);
fGpu->submitSecondaryCommandBuffer(std::move(fCurrentSecondaryCommandBuffer));
@@ -493,6 +526,10 @@
void GrVkOpsRenderPass::onDraw(const GrProgramInfo& programInfo,
const GrMesh meshes[], int meshCount,
const SkRect& bounds) {
+ if (!fCurrentRenderPass) {
+ SkASSERT(fGpu->isDeviceLost());
+ return;
+ }
SkASSERT(meshCount); // guaranteed by GrOpsRenderPass::draw
@@ -616,6 +653,10 @@
////////////////////////////////////////////////////////////////////////////////
void GrVkOpsRenderPass::executeDrawable(std::unique_ptr<SkDrawable::GpuDrawHandler> drawable) {
+ if (!fCurrentRenderPass) {
+ SkASSERT(fGpu->isDeviceLost());
+ return;
+ }
GrVkRenderTarget* target = static_cast<GrVkRenderTarget*>(fRenderTarget);
GrVkImage* targetImage = target->msaaImage() ? target->msaaImage() : target;
@@ -627,6 +668,11 @@
if (!fCurrentSecondaryCommandBuffer) {
fGpu->endRenderPass(fRenderTarget, fOrigin, fBounds);
this->addAdditionalRenderPass(true);
+ // We may have failed to start a new render pass
+ if (!fCurrentRenderPass) {
+ SkASSERT(fGpu->isDeviceLost());
+ return;
+ }
}
SkASSERT(fCurrentSecondaryCommandBuffer);
diff --git a/src/gpu/vk/GrVkOpsRenderPass.h b/src/gpu/vk/GrVkOpsRenderPass.h
index 65d6b5b..784bc04 100644
--- a/src/gpu/vk/GrVkOpsRenderPass.h
+++ b/src/gpu/vk/GrVkOpsRenderPass.h
@@ -38,7 +38,7 @@
void executeDrawable(std::unique_ptr<SkDrawable::GpuDrawHandler>) override;
- void set(GrRenderTarget*, GrSurfaceOrigin, const SkIRect& bounds,
+ bool set(GrRenderTarget*, GrSurfaceOrigin, const SkIRect& bounds,
const GrOpsRenderPass::LoadAndStoreInfo&,
const GrOpsRenderPass::StencilLoadAndStoreInfo&,
const SkTArray<GrTextureProxy*, true>& sampledProxies);
@@ -51,7 +51,7 @@
#endif
private:
- void init(const GrOpsRenderPass::LoadAndStoreInfo&,
+ bool init(const GrOpsRenderPass::LoadAndStoreInfo&,
const GrOpsRenderPass::StencilLoadAndStoreInfo&,
const SkPMColor4f& clearColor);
diff --git a/src/gpu/vk/GrVkPipelineStateBuilder.cpp b/src/gpu/vk/GrVkPipelineStateBuilder.cpp
index 52c7c52..bb3647d 100644
--- a/src/gpu/vk/GrVkPipelineStateBuilder.cpp
+++ b/src/gpu/vk/GrVkPipelineStateBuilder.cpp
@@ -343,7 +343,9 @@
desc->fShaderKeyLength = SkToU32(keyLength);
GrVkRenderTarget* vkRT = (GrVkRenderTarget*)renderTarget;
- vkRT->simpleRenderPass()->genKey(&b);
+ // TODO: support failure in getSimpleRenderPass
+ SkASSERT(vkRT->getSimpleRenderPass());
+ vkRT->getSimpleRenderPass()->genKey(&b);
stencil.genKey(&b);
diff --git a/src/gpu/vk/GrVkRenderTarget.cpp b/src/gpu/vk/GrVkRenderTarget.cpp
index d7d53fb..ff42b58 100644
--- a/src/gpu/vk/GrVkRenderTarget.cpp
+++ b/src/gpu/vk/GrVkRenderTarget.cpp
@@ -39,11 +39,10 @@
, fMSAAImage(new GrVkImage(msaaInfo, std::move(msaaLayout),
GrBackendObjectOwnership::kOwned))
, fResolveAttachmentView(resolveAttachmentView)
- , fFramebuffer(nullptr)
+ , fCachedFramebuffer(nullptr)
, fCachedSimpleRenderPass(nullptr) {
SkASSERT(info.fProtected == msaaInfo.fProtected);
SkASSERT(sampleCnt > 1);
- this->createFramebuffer(gpu);
this->registerWithCacheWrapped(GrWrapCacheable::kNo);
}
@@ -67,11 +66,10 @@
, fMSAAImage(
new GrVkImage(msaaInfo, std::move(msaaLayout), GrBackendObjectOwnership::kOwned))
, fResolveAttachmentView(resolveAttachmentView)
- , fFramebuffer(nullptr)
+ , fCachedFramebuffer(nullptr)
, fCachedSimpleRenderPass(nullptr) {
SkASSERT(info.fProtected == msaaInfo.fProtected);
SkASSERT(sampleCnt > 1);
- this->createFramebuffer(gpu);
}
// We're virtually derived from GrSurface (via GrRenderTarget) so its
@@ -87,9 +85,8 @@
, fColorAttachmentView(colorAttachmentView)
, fMSAAImage(nullptr)
, fResolveAttachmentView(nullptr)
- , fFramebuffer(nullptr)
+ , fCachedFramebuffer(nullptr)
, fCachedSimpleRenderPass(nullptr) {
- this->createFramebuffer(gpu);
this->registerWithCacheWrapped(GrWrapCacheable::kNo);
}
@@ -107,9 +104,8 @@
, fColorAttachmentView(colorAttachmentView)
, fMSAAImage(nullptr)
, fResolveAttachmentView(nullptr)
- , fFramebuffer(nullptr)
+ , fCachedFramebuffer(nullptr)
, fCachedSimpleRenderPass(nullptr) {
- this->createFramebuffer(gpu);
}
GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu,
@@ -124,7 +120,7 @@
, fColorAttachmentView(nullptr)
, fMSAAImage(nullptr)
, fResolveAttachmentView(nullptr)
- , fFramebuffer(nullptr)
+ , fCachedFramebuffer(nullptr)
, fCachedSimpleRenderPass(renderPass)
, fSecondaryCommandBuffer(secondaryCommandBuffer) {
SkASSERT(fSecondaryCommandBuffer != VK_NULL_HANDLE);
@@ -236,30 +232,56 @@
bool GrVkRenderTarget::completeStencilAttachment() {
SkASSERT(!this->wrapsSecondaryCommandBuffer());
- this->createFramebuffer(this->getVkGpu());
+ // If we have a previous renderpass or framebuffer it will have been made without stencil, so
+ // we set it to null to trigger creating a new one the next time we need it.
+ if (fCachedSimpleRenderPass) {
+ fCachedSimpleRenderPass->unref(this->getVkGpu());
+ fCachedSimpleRenderPass = nullptr;
+ }
+ if (fCachedFramebuffer) {
+ fCachedFramebuffer->unref(this->getVkGpu());
+ fCachedFramebuffer = nullptr;
+ }
+ fCompatibleRPHandle = GrVkResourceProvider::CompatibleRPHandle();
return true;
}
-void GrVkRenderTarget::createFramebuffer(GrVkGpu* gpu) {
- SkASSERT(!this->wrapsSecondaryCommandBuffer());
- if (fFramebuffer) {
- fFramebuffer->unref(gpu);
- }
+const GrVkRenderPass* GrVkRenderTarget::getSimpleRenderPass() {
if (fCachedSimpleRenderPass) {
- fCachedSimpleRenderPass->unref(gpu);
+ return fCachedSimpleRenderPass;
}
+ return this->createSimpleRenderPass();
+}
- // Vulkan requires us to create a compatible renderpass before we can create our framebuffer,
- // so we use this to get a (cached) basic renderpass, only for creation.
+const GrVkRenderPass* GrVkRenderTarget::createSimpleRenderPass() {
+ SkASSERT(!this->wrapsSecondaryCommandBuffer());
+ SkASSERT(!fCachedSimpleRenderPass);
+
fCachedSimpleRenderPass =
- gpu->resourceProvider().findCompatibleRenderPass(*this, &fCompatibleRPHandle);
+ this->getVkGpu()->resourceProvider().findCompatibleRenderPass(*this, &fCompatibleRPHandle);
+ // TODO: allow for the above call to fail and handle returning null from getSimpleRenderPass
+ SkASSERT(fCachedSimpleRenderPass);
+ return fCachedSimpleRenderPass;
+}
+const GrVkFramebuffer* GrVkRenderTarget::getFramebuffer() {
+ if (fCachedFramebuffer) {
+ return fCachedFramebuffer;
+ }
+ return this->createFramebuffer();
+}
+
+const GrVkFramebuffer* GrVkRenderTarget::createFramebuffer() {
+ SkASSERT(!this->wrapsSecondaryCommandBuffer());
+ SkASSERT(!fCachedFramebuffer);
+
+ GrVkGpu* gpu = this->getVkGpu();
// Stencil attachment view is stored in the base RT stencil attachment
const GrVkImageView* stencilView = this->stencilAttachmentView();
- fFramebuffer = GrVkFramebuffer::Create(gpu, this->width(), this->height(),
- fCachedSimpleRenderPass, fColorAttachmentView,
- stencilView);
- SkASSERT(fFramebuffer);
+ fCachedFramebuffer = GrVkFramebuffer::Create(gpu, this->width(), this->height(),
+ this->getSimpleRenderPass(),
+ fColorAttachmentView, stencilView);
+ return fCachedFramebuffer;
}
void GrVkRenderTarget::getAttachmentsDescriptor(
@@ -289,12 +311,12 @@
SkASSERT(!fMSAAImage);
SkASSERT(!fResolveAttachmentView);
SkASSERT(!fColorAttachmentView);
- SkASSERT(!fFramebuffer);
+ SkASSERT(!fCachedFramebuffer);
SkASSERT(!fCachedSimpleRenderPass);
}
-void GrVkRenderTarget::addResources(GrVkCommandBuffer& commandBuffer) const {
- commandBuffer.addResource(this->framebuffer());
+void GrVkRenderTarget::addResources(GrVkCommandBuffer& commandBuffer) {
+ commandBuffer.addResource(this->getFramebuffer());
commandBuffer.addResource(this->colorAttachmentView());
commandBuffer.addResource(this->msaaImageResource() ? this->msaaImageResource()
: this->resource());
@@ -320,9 +342,9 @@
fColorAttachmentView->unref(gpu);
fColorAttachmentView = nullptr;
}
- if (fFramebuffer) {
- fFramebuffer->unref(gpu);
- fFramebuffer = nullptr;
+ if (fCachedFramebuffer) {
+ fCachedFramebuffer->unref(gpu);
+ fCachedFramebuffer = nullptr;
}
if (fCachedSimpleRenderPass) {
fCachedSimpleRenderPass->unref(gpu);
@@ -344,9 +366,9 @@
fColorAttachmentView->unrefAndAbandon();
fColorAttachmentView = nullptr;
}
- if (fFramebuffer) {
- fFramebuffer->unrefAndAbandon();
- fFramebuffer = nullptr;
+ if (fCachedFramebuffer) {
+ fCachedFramebuffer->unrefAndAbandon();
+ fCachedFramebuffer = nullptr;
}
if (fCachedSimpleRenderPass) {
fCachedSimpleRenderPass->unrefAndAbandon();
diff --git a/src/gpu/vk/GrVkRenderTarget.h b/src/gpu/vk/GrVkRenderTarget.h
index 9372aa1..2f7ec83 100644
--- a/src/gpu/vk/GrVkRenderTarget.h
+++ b/src/gpu/vk/GrVkRenderTarget.h
@@ -44,7 +44,7 @@
GrBackendFormat backendFormat() const override { return this->getBackendFormat(); }
- const GrVkFramebuffer* framebuffer() const { return fFramebuffer; }
+ const GrVkFramebuffer* getFramebuffer();
const GrVkImageView* colorAttachmentView() const { return fColorAttachmentView; }
const GrVkResource* msaaImageResource() const {
if (fMSAAImage) {
@@ -57,9 +57,13 @@
const GrVkResource* stencilImageResource() const;
const GrVkImageView* stencilAttachmentView() const;
- const GrVkRenderPass* simpleRenderPass() const { return fCachedSimpleRenderPass; }
- GrVkResourceProvider::CompatibleRPHandle compatibleRenderPassHandle() const {
+ const GrVkRenderPass* getSimpleRenderPass();
+ GrVkResourceProvider::CompatibleRPHandle compatibleRenderPassHandle() {
SkASSERT(!this->wrapsSecondaryCommandBuffer());
+ if (!fCompatibleRPHandle.isValid()) {
+ SkASSERT(!fCachedSimpleRenderPass);
+ this->createSimpleRenderPass();
+ }
return fCompatibleRPHandle;
}
const GrVkRenderPass* externalRenderPass() const {
@@ -84,7 +88,7 @@
void getAttachmentsDescriptor(GrVkRenderPass::AttachmentsDescriptor* desc,
GrVkRenderPass::AttachmentFlags* flags) const;
- void addResources(GrVkCommandBuffer& commandBuffer) const;
+ void addResources(GrVkCommandBuffer& commandBuffer);
protected:
GrVkRenderTarget(GrVkGpu* gpu,
@@ -105,8 +109,6 @@
const GrVkImageView* colorAttachmentView,
GrBackendObjectOwnership);
- GrVkGpu* getVkGpu() const;
-
void onAbandon() override;
void onRelease() override;
@@ -122,12 +124,6 @@
numColorSamples, GrMipMapped::kNo);
}
- void createFramebuffer(GrVkGpu* gpu);
-
- const GrVkImageView* fColorAttachmentView;
- std::unique_ptr<GrVkImage> fMSAAImage;
- const GrVkImageView* fResolveAttachmentView;
-
private:
GrVkRenderTarget(GrVkGpu* gpu,
const GrSurfaceDesc& desc,
@@ -153,6 +149,11 @@
const GrVkRenderPass* renderPass,
VkCommandBuffer secondaryCommandBuffer);
+ GrVkGpu* getVkGpu() const;
+
+ const GrVkRenderPass* createSimpleRenderPass();
+ const GrVkFramebuffer* createFramebuffer();
+
bool completeStencilAttachment() override;
// In Vulkan we call the release proc after we are finished with the underlying
@@ -165,7 +166,11 @@
void releaseInternalObjects();
void abandonInternalObjects();
- const GrVkFramebuffer* fFramebuffer;
+ const GrVkImageView* fColorAttachmentView;
+ std::unique_ptr<GrVkImage> fMSAAImage;
+ const GrVkImageView* fResolveAttachmentView;
+
+ const GrVkFramebuffer* fCachedFramebuffer;
// This is a cached pointer to a simple render pass. The render target should unref it
// once it is done with it.
diff --git a/src/gpu/vk/GrVkResourceProvider.cpp b/src/gpu/vk/GrVkResourceProvider.cpp
index 6fb8788..c869029 100644
--- a/src/gpu/vk/GrVkResourceProvider.cpp
+++ b/src/gpu/vk/GrVkResourceProvider.cpp
@@ -160,18 +160,18 @@
}
const GrVkRenderPass* GrVkResourceProvider::findRenderPass(
- const GrVkRenderTarget& target,
+ GrVkRenderTarget* target,
const GrVkRenderPass::LoadStoreOps& colorOps,
const GrVkRenderPass::LoadStoreOps& stencilOps,
CompatibleRPHandle* compatibleHandle) {
GrVkResourceProvider::CompatibleRPHandle tempRPHandle;
GrVkResourceProvider::CompatibleRPHandle* pRPHandle = compatibleHandle ? compatibleHandle
: &tempRPHandle;
- *pRPHandle = target.compatibleRenderPassHandle();
+ *pRPHandle = target->compatibleRenderPassHandle();
// This will get us the handle to (and possible create) the compatible set for the specific
// GrVkRenderPass we are looking for.
- this->findCompatibleRenderPass(target, compatibleHandle);
+ this->findCompatibleRenderPass(*target, compatibleHandle);
return this->findRenderPass(*pRPHandle, colorOps, stencilOps);
}
diff --git a/src/gpu/vk/GrVkResourceProvider.h b/src/gpu/vk/GrVkResourceProvider.h
index e07de2b..9cafcb4 100644
--- a/src/gpu/vk/GrVkResourceProvider.h
+++ b/src/gpu/vk/GrVkResourceProvider.h
@@ -70,7 +70,7 @@
// 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 GrVkRenderPasses without the need inspecting a GrVkRenderTarget.
- const GrVkRenderPass* findRenderPass(const GrVkRenderTarget& target,
+ const GrVkRenderPass* findRenderPass(GrVkRenderTarget* target,
const GrVkRenderPass::LoadStoreOps& colorOps,
const GrVkRenderPass::LoadStoreOps& stencilOps,
CompatibleRPHandle* compatibleHandle = nullptr);