Update GrVkRenderTarget to store both stencil & non-stencil render passes (for real)
This is to allow reuse of a Vk render target in both stencil and non-stencil use cases.
Change-Id: Ic35285e66c173db7c0bf6440d95549cf1371ed43
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/291077
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h
index 58723df..f20e6ba 100644
--- a/src/gpu/GrGpu.h
+++ b/src/gpu/GrGpu.h
@@ -350,8 +350,14 @@
// Returns a GrOpsRenderPass which GrOpsTasks send draw commands to instead of directly
// to the Gpu object. The 'bounds' rect is the content rect of the renderTarget.
+ // If a 'stencil' is provided it will be the one bound to 'renderTarget'. If one is not
+ // provided but 'renderTarget' has a stencil buffer then that is a signal that the
+ // render target's stencil buffer should be ignored.
virtual GrOpsRenderPass* getOpsRenderPass(
- GrRenderTarget* renderTarget, GrSurfaceOrigin, const SkIRect& bounds,
+ GrRenderTarget* renderTarget,
+ GrStencilAttachment* stencil,
+ GrSurfaceOrigin,
+ const SkIRect& bounds,
const GrOpsRenderPass::LoadAndStoreInfo&,
const GrOpsRenderPass::StencilLoadAndStoreInfo&,
const SkTArray<GrSurfaceProxy*, true>& sampledProxies) = 0;
diff --git a/src/gpu/GrOpsTask.cpp b/src/gpu/GrOpsTask.cpp
index c811883..4537242 100644
--- a/src/gpu/GrOpsTask.cpp
+++ b/src/gpu/GrOpsTask.cpp
@@ -469,9 +469,10 @@
}
static GrOpsRenderPass* create_render_pass(
- GrGpu* gpu, GrRenderTarget* rt, GrSurfaceOrigin origin, const SkIRect& bounds,
- GrLoadOp colorLoadOp, const SkPMColor4f& loadClearColor, GrLoadOp stencilLoadOp,
- GrStoreOp stencilStoreOp, const SkTArray<GrSurfaceProxy*, true>& sampledProxies) {
+ GrGpu* gpu, GrRenderTarget* rt, GrStencilAttachment* stencil, GrSurfaceOrigin origin,
+ const SkIRect& bounds, GrLoadOp colorLoadOp, const SkPMColor4f& loadClearColor,
+ GrLoadOp stencilLoadOp, GrStoreOp stencilStoreOp,
+ const SkTArray<GrSurfaceProxy*, true>& sampledProxies) {
const GrOpsRenderPass::LoadAndStoreInfo kColorLoadStoreInfo {
colorLoadOp,
GrStoreOp::kStore,
@@ -488,8 +489,8 @@
stencilStoreOp,
};
- return gpu->getOpsRenderPass(rt, origin, bounds, kColorLoadStoreInfo, stencilLoadAndStoreInfo,
- sampledProxies);
+ return gpu->getOpsRenderPass(rt, stencil, origin, bounds,
+ kColorLoadStoreInfo, stencilLoadAndStoreInfo, sampledProxies);
}
// TODO: this is where GrOp::renderTarget is used (which is fine since it
@@ -571,7 +572,7 @@
: GrStoreOp::kStore;
GrOpsRenderPass* renderPass = create_render_pass(
- flushState->gpu(), proxy->peekRenderTarget(), fTargetView.origin(),
+ flushState->gpu(), proxy->peekRenderTarget(), stencil, fTargetView.origin(),
fClippedContentBounds, fColorLoadOp, fLoadClearColor, stencilLoadOp, stencilStoreOp,
fSampledProxies);
if (!renderPass) {
diff --git a/src/gpu/GrProgramInfo.h b/src/gpu/GrProgramInfo.h
index 373b3bb..f8ce3fc 100644
--- a/src/gpu/GrProgramInfo.h
+++ b/src/gpu/GrProgramInfo.h
@@ -49,6 +49,7 @@
int numSamples() const { return fNumSamples; }
int numStencilSamples() const { return fNumStencilSamples; }
+ bool isStencilEnabled() const { return fPipeline->isStencilEnabled(); }
int numRasterSamples() const {
return fPipeline->isStencilEnabled() ? fNumStencilSamples : fNumSamples;
diff --git a/src/gpu/d3d/GrD3DGpu.cpp b/src/gpu/d3d/GrD3DGpu.cpp
index 3cc4112..e722b37 100644
--- a/src/gpu/d3d/GrD3DGpu.cpp
+++ b/src/gpu/d3d/GrD3DGpu.cpp
@@ -93,7 +93,8 @@
}
GrOpsRenderPass* GrD3DGpu::getOpsRenderPass(
- GrRenderTarget* rt, GrSurfaceOrigin origin, const SkIRect& bounds,
+ GrRenderTarget* rt, GrStencilAttachment*,
+ GrSurfaceOrigin origin, const SkIRect& bounds,
const GrOpsRenderPass::LoadAndStoreInfo& colorInfo,
const GrOpsRenderPass::StencilLoadAndStoreInfo& stencilInfo,
const SkTArray<GrSurfaceProxy*, true>& sampledProxies) {
diff --git a/src/gpu/d3d/GrD3DGpu.h b/src/gpu/d3d/GrD3DGpu.h
index 3ffff98..be8fbc5 100644
--- a/src/gpu/d3d/GrD3DGpu.h
+++ b/src/gpu/d3d/GrD3DGpu.h
@@ -70,7 +70,8 @@
const GrRenderTarget*, int width, int height, int numStencilSamples) override;
GrOpsRenderPass* getOpsRenderPass(
- GrRenderTarget*, GrSurfaceOrigin, const SkIRect&,
+ GrRenderTarget*, GrStencilAttachment*,
+ GrSurfaceOrigin, const SkIRect&,
const GrOpsRenderPass::LoadAndStoreInfo&,
const GrOpsRenderPass::StencilLoadAndStoreInfo&,
const SkTArray<GrSurfaceProxy*, true>& sampledProxies) override;
diff --git a/src/gpu/dawn/GrDawnGpu.cpp b/src/gpu/dawn/GrDawnGpu.cpp
index f21c17d..f4756e7 100644
--- a/src/gpu/dawn/GrDawnGpu.cpp
+++ b/src/gpu/dawn/GrDawnGpu.cpp
@@ -137,7 +137,8 @@
///////////////////////////////////////////////////////////////////////////////
GrOpsRenderPass* GrDawnGpu::getOpsRenderPass(
- GrRenderTarget* rt, GrSurfaceOrigin origin, const SkIRect& bounds,
+ GrRenderTarget* rt, GrStencilAttachment*,
+ GrSurfaceOrigin origin, const SkIRect& bounds,
const GrOpsRenderPass::LoadAndStoreInfo& colorInfo,
const GrOpsRenderPass::StencilLoadAndStoreInfo& stencilInfo,
const SkTArray<GrSurfaceProxy*, true>& sampledProxies) {
diff --git a/src/gpu/dawn/GrDawnGpu.h b/src/gpu/dawn/GrDawnGpu.h
index ac4f983..fd09f9e 100644
--- a/src/gpu/dawn/GrDawnGpu.h
+++ b/src/gpu/dawn/GrDawnGpu.h
@@ -61,7 +61,8 @@
int numStencilSamples) override;
GrOpsRenderPass* getOpsRenderPass(
- GrRenderTarget*, GrSurfaceOrigin, const SkIRect& bounds,
+ GrRenderTarget*, GrStencilAttachment*,
+ GrSurfaceOrigin, const SkIRect& bounds,
const GrOpsRenderPass::LoadAndStoreInfo&,
const GrOpsRenderPass::StencilLoadAndStoreInfo&,
const SkTArray<GrSurfaceProxy*, true>& sampledProxies) override;
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index 2ca42ac..ef000ad 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -2158,7 +2158,8 @@
}
GrOpsRenderPass* GrGLGpu::getOpsRenderPass(
- GrRenderTarget* rt, GrSurfaceOrigin origin, const SkIRect& bounds,
+ GrRenderTarget* rt, GrStencilAttachment*,
+ GrSurfaceOrigin origin, const SkIRect& bounds,
const GrOpsRenderPass::LoadAndStoreInfo& colorInfo,
const GrOpsRenderPass::StencilLoadAndStoreInfo& stencilInfo,
const SkTArray<GrSurfaceProxy*, true>& sampledProxies) {
diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h
index 164d057..3f22309 100644
--- a/src/gpu/gl/GrGLGpu.h
+++ b/src/gpu/gl/GrGLGpu.h
@@ -124,7 +124,8 @@
const GrOpsRenderPass::StencilLoadAndStoreInfo& stencilLoadStore);
GrOpsRenderPass* getOpsRenderPass(
- GrRenderTarget*, GrSurfaceOrigin, const SkIRect&,
+ GrRenderTarget*, GrStencilAttachment*,
+ GrSurfaceOrigin, const SkIRect&,
const GrOpsRenderPass::LoadAndStoreInfo&,
const GrOpsRenderPass::StencilLoadAndStoreInfo&,
const SkTArray<GrSurfaceProxy*, true>& sampledProxies) override;
diff --git a/src/gpu/mock/GrMockGpu.cpp b/src/gpu/mock/GrMockGpu.cpp
index 3348c4b..ccd1157 100644
--- a/src/gpu/mock/GrMockGpu.cpp
+++ b/src/gpu/mock/GrMockGpu.cpp
@@ -53,7 +53,8 @@
}
GrOpsRenderPass* GrMockGpu::getOpsRenderPass(
- GrRenderTarget* rt, GrSurfaceOrigin origin, const SkIRect& bounds,
+ GrRenderTarget* rt, GrStencilAttachment*,
+ GrSurfaceOrigin origin, const SkIRect& bounds,
const GrOpsRenderPass::LoadAndStoreInfo& colorInfo,
const GrOpsRenderPass::StencilLoadAndStoreInfo&,
const SkTArray<GrSurfaceProxy*, true>& sampledProxies) {
diff --git a/src/gpu/mock/GrMockGpu.h b/src/gpu/mock/GrMockGpu.h
index 05fdda7..29dda81 100644
--- a/src/gpu/mock/GrMockGpu.h
+++ b/src/gpu/mock/GrMockGpu.h
@@ -25,7 +25,10 @@
~GrMockGpu() override {}
GrOpsRenderPass* getOpsRenderPass(
- GrRenderTarget*, GrSurfaceOrigin, const SkIRect&,
+ GrRenderTarget*,
+ GrStencilAttachment*,
+ GrSurfaceOrigin,
+ const SkIRect&,
const GrOpsRenderPass::LoadAndStoreInfo&,
const GrOpsRenderPass::StencilLoadAndStoreInfo&,
const SkTArray<GrSurfaceProxy*, true>& sampledProxies) override;
diff --git a/src/gpu/mtl/GrMtlGpu.h b/src/gpu/mtl/GrMtlGpu.h
index 191c0ba..431a04d 100644
--- a/src/gpu/mtl/GrMtlGpu.h
+++ b/src/gpu/mtl/GrMtlGpu.h
@@ -79,7 +79,8 @@
const SkIPoint& dstPoint) override;
GrOpsRenderPass* getOpsRenderPass(
- GrRenderTarget*, GrSurfaceOrigin, const SkIRect& bounds,
+ GrRenderTarget*, GrStencilAttachment*,
+ GrSurfaceOrigin, const SkIRect& bounds,
const GrOpsRenderPass::LoadAndStoreInfo&,
const GrOpsRenderPass::StencilLoadAndStoreInfo&,
const SkTArray<GrSurfaceProxy*, true>& sampledProxies) override;
diff --git a/src/gpu/mtl/GrMtlGpu.mm b/src/gpu/mtl/GrMtlGpu.mm
index 420bb89..af90ffc 100644
--- a/src/gpu/mtl/GrMtlGpu.mm
+++ b/src/gpu/mtl/GrMtlGpu.mm
@@ -159,7 +159,8 @@
}
GrOpsRenderPass* GrMtlGpu::getOpsRenderPass(
- GrRenderTarget* renderTarget, GrSurfaceOrigin origin, const SkIRect& bounds,
+ GrRenderTarget* renderTarget, GrStencilAttachment*,
+ GrSurfaceOrigin origin, const SkIRect& bounds,
const GrOpsRenderPass::LoadAndStoreInfo& colorInfo,
const GrOpsRenderPass::StencilLoadAndStoreInfo& stencilInfo,
const SkTArray<GrSurfaceProxy*, true>& sampledProxies) {
diff --git a/src/gpu/vk/GrVkCaps.cpp b/src/gpu/vk/GrVkCaps.cpp
index eacce98..028c0dc 100644
--- a/src/gpu/vk/GrVkCaps.cpp
+++ b/src/gpu/vk/GrVkCaps.cpp
@@ -1716,9 +1716,12 @@
b.add32(GrVkGpu::kShader_PersistentCacheKeyType);
GrVkRenderTarget* vkRT = (GrVkRenderTarget*) rt;
+
+ bool needsStencil = programInfo.numStencilSamples() || programInfo.isStencilEnabled();
// TODO: support failure in getSimpleRenderPass
- SkASSERT(vkRT->getSimpleRenderPass());
- vkRT->getSimpleRenderPass()->genKey(&b);
+ const GrVkRenderPass* rp = vkRT->getSimpleRenderPass(needsStencil);
+ SkASSERT(rp);
+ rp->genKey(&b);
GrStencilSettings stencil = programInfo.nonGLStencilSettings();
stencil.genKey(&b, true);
diff --git a/src/gpu/vk/GrVkCommandBuffer.cpp b/src/gpu/vk/GrVkCommandBuffer.cpp
index e23459b..953b8da 100644
--- a/src/gpu/vk/GrVkCommandBuffer.cpp
+++ b/src/gpu/vk/GrVkCommandBuffer.cpp
@@ -472,7 +472,7 @@
SkASSERT(!fActiveRenderPass);
SkASSERT(renderPass->isCompatible(*target));
- const GrVkFramebuffer* framebuffer = target->getFramebuffer();
+ const GrVkFramebuffer* framebuffer = target->getFramebuffer(renderPass->hasStencilAttachment());
if (!framebuffer) {
return false;
}
@@ -499,7 +499,7 @@
GR_VK_CALL(gpu->vkInterface(), CmdBeginRenderPass(fCmdBuffer, &beginInfo, contents));
fActiveRenderPass = renderPass;
this->addResource(renderPass);
- target->addResources(*this);
+ target->addResources(*this, renderPass->hasStencilAttachment());
return true;
}
diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp
index f2ab810..e4f4fa0 100644
--- a/src/gpu/vk/GrVkGpu.cpp
+++ b/src/gpu/vk/GrVkGpu.cpp
@@ -309,7 +309,8 @@
///////////////////////////////////////////////////////////////////////////////
GrOpsRenderPass* GrVkGpu::getOpsRenderPass(
- GrRenderTarget* rt, GrSurfaceOrigin origin, const SkIRect& bounds,
+ GrRenderTarget* rt, GrStencilAttachment* stencil,
+ GrSurfaceOrigin origin, const SkIRect& bounds,
const GrOpsRenderPass::LoadAndStoreInfo& colorInfo,
const GrOpsRenderPass::StencilLoadAndStoreInfo& stencilInfo,
const SkTArray<GrSurfaceProxy*, true>& sampledProxies) {
@@ -317,7 +318,8 @@
fCachedOpsRenderPass.reset(new GrVkOpsRenderPass(this));
}
- if (!fCachedOpsRenderPass->set(rt, origin, bounds, colorInfo, stencilInfo, sampledProxies)) {
+ if (!fCachedOpsRenderPass->set(rt, stencil, origin, bounds,
+ colorInfo, stencilInfo, sampledProxies)) {
return nullptr;
}
return fCachedOpsRenderPass.get();
diff --git a/src/gpu/vk/GrVkGpu.h b/src/gpu/vk/GrVkGpu.h
index be7a03c..af10a22 100644
--- a/src/gpu/vk/GrVkGpu.h
+++ b/src/gpu/vk/GrVkGpu.h
@@ -98,7 +98,8 @@
const GrRenderTarget*, int width, int height, int numStencilSamples) override;
GrOpsRenderPass* getOpsRenderPass(
- GrRenderTarget*, GrSurfaceOrigin, const SkIRect&,
+ GrRenderTarget*, GrStencilAttachment*,
+ GrSurfaceOrigin, const SkIRect&,
const GrOpsRenderPass::LoadAndStoreInfo&,
const GrOpsRenderPass::StencilLoadAndStoreInfo&,
const SkTArray<GrSurfaceProxy*, true>& sampledProxies) override;
diff --git a/src/gpu/vk/GrVkOpsRenderPass.cpp b/src/gpu/vk/GrVkOpsRenderPass.cpp
index 3327cf8..5eef9cc 100644
--- a/src/gpu/vk/GrVkOpsRenderPass.cpp
+++ b/src/gpu/vk/GrVkOpsRenderPass.cpp
@@ -61,7 +61,8 @@
bool GrVkOpsRenderPass::init(const GrOpsRenderPass::LoadAndStoreInfo& colorInfo,
const GrOpsRenderPass::StencilLoadAndStoreInfo& stencilInfo,
- const SkPMColor4f& clearColor) {
+ const SkPMColor4f& clearColor,
+ bool withStencil) {
VkAttachmentLoadOp loadOp;
VkAttachmentStoreOp storeOp;
@@ -87,8 +88,11 @@
false);
// If we are using a stencil attachment we also need to update its layout
- if (GrStencilAttachment* stencil = fRenderTarget->renderTargetPriv().getStencilAttachment()) {
- GrVkStencilAttachment* vkStencil = (GrVkStencilAttachment*)stencil;
+ if (withStencil) {
+ GrVkStencilAttachment* vkStencil =
+ (GrVkStencilAttachment*) fRenderTarget->renderTargetPriv().getStencilAttachment();
+ SkASSERT(vkStencil);
+
// We need the write and read access bits since we may load and store the stencil.
// The initial load happens in the VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT so we
// wait there.
@@ -101,7 +105,7 @@
}
const GrVkResourceProvider::CompatibleRPHandle& rpHandle =
- vkRT->compatibleRenderPassHandle();
+ vkRT->compatibleRenderPassHandle(withStencil);
if (rpHandle.isValid()) {
fCurrentRenderPass = fGpu->resourceProvider().findRenderPass(rpHandle,
vkColorOps,
@@ -109,7 +113,9 @@
} else {
fCurrentRenderPass = fGpu->resourceProvider().findRenderPass(vkRT,
vkColorOps,
- vkStencilOps);
+ vkStencilOps,
+ nullptr,
+ withStencil);
}
if (!fCurrentRenderPass) {
return false;
@@ -128,7 +134,8 @@
fCurrentRenderPass = nullptr;
return false;
}
- fCurrentSecondaryCommandBuffer->begin(fGpu, vkRT->getFramebuffer(), fCurrentRenderPass);
+ fCurrentSecondaryCommandBuffer->begin(fGpu, vkRT->getFramebuffer(withStencil),
+ fCurrentRenderPass);
}
if (!fGpu->beginRenderPass(fCurrentRenderPass, &vkClearColor, vkRT, fOrigin, fBounds,
@@ -196,7 +203,8 @@
fGpu->endRenderPass(fRenderTarget, fOrigin, fBounds);
}
-bool GrVkOpsRenderPass::set(GrRenderTarget* rt, GrSurfaceOrigin origin, const SkIRect& bounds,
+bool GrVkOpsRenderPass::set(GrRenderTarget* rt, GrStencilAttachment* stencil,
+ GrSurfaceOrigin origin, const SkIRect& bounds,
const GrOpsRenderPass::LoadAndStoreInfo& colorInfo,
const GrOpsRenderPass::StencilLoadAndStoreInfo& stencilInfo,
const SkTArray<GrSurfaceProxy*, true>& sampledProxies) {
@@ -227,7 +235,7 @@
return this->initWrapped();
}
- return this->init(colorInfo, stencilInfo, colorInfo.fClearColor);
+ return this->init(colorInfo, stencilInfo, colorInfo.fClearColor, SkToBool(stencil));
}
void GrVkOpsRenderPass::reset() {
@@ -374,8 +382,10 @@
GrVkRenderPass::LoadStoreOps vkStencilOps(VK_ATTACHMENT_LOAD_OP_LOAD,
VK_ATTACHMENT_STORE_OP_STORE);
+ bool withStencil = fCurrentRenderPass->hasStencilAttachment();
+
const GrVkResourceProvider::CompatibleRPHandle& rpHandle =
- vkRT->compatibleRenderPassHandle();
+ vkRT->compatibleRenderPassHandle(withStencil);
SkASSERT(fCurrentRenderPass);
fCurrentRenderPass->unref();
if (rpHandle.isValid()) {
@@ -385,7 +395,9 @@
} else {
fCurrentRenderPass = fGpu->resourceProvider().findRenderPass(vkRT,
vkColorOps,
- vkStencilOps);
+ vkStencilOps,
+ nullptr,
+ withStencil);
}
if (!fCurrentRenderPass) {
return;
@@ -402,7 +414,8 @@
fCurrentRenderPass = nullptr;
return;
}
- fCurrentSecondaryCommandBuffer->begin(fGpu, vkRT->getFramebuffer(), fCurrentRenderPass);
+ fCurrentSecondaryCommandBuffer->begin(fGpu, vkRT->getFramebuffer(withStencil),
+ fCurrentRenderPass);
}
// We use the same fBounds as the whole GrVkOpsRenderPass since we have no way of tracking the
diff --git a/src/gpu/vk/GrVkOpsRenderPass.h b/src/gpu/vk/GrVkOpsRenderPass.h
index 195bb92..53bb07e 100644
--- a/src/gpu/vk/GrVkOpsRenderPass.h
+++ b/src/gpu/vk/GrVkOpsRenderPass.h
@@ -32,7 +32,8 @@
void onExecuteDrawable(std::unique_ptr<SkDrawable::GpuDrawHandler>) override;
- bool set(GrRenderTarget*, GrSurfaceOrigin, const SkIRect& bounds,
+ bool set(GrRenderTarget*, GrStencilAttachment*,
+ GrSurfaceOrigin, const SkIRect& bounds,
const GrOpsRenderPass::LoadAndStoreInfo&,
const GrOpsRenderPass::StencilLoadAndStoreInfo&,
const SkTArray<GrSurfaceProxy*, true>& sampledProxies);
@@ -47,7 +48,8 @@
private:
bool init(const GrOpsRenderPass::LoadAndStoreInfo&,
const GrOpsRenderPass::StencilLoadAndStoreInfo&,
- const SkPMColor4f& clearColor);
+ const SkPMColor4f& clearColor,
+ bool withStencil);
// Called instead of init when we are drawing to a render target that already wraps a secondary
// command buffer.
diff --git a/src/gpu/vk/GrVkRenderPass.cpp b/src/gpu/vk/GrVkRenderPass.cpp
index 627eb22..281983f 100644
--- a/src/gpu/vk/GrVkRenderPass.cpp
+++ b/src/gpu/vk/GrVkRenderPass.cpp
@@ -234,7 +234,7 @@
AttachmentsDescriptor desc;
AttachmentFlags flags;
- target.getAttachmentsDescriptor(&desc, &flags);
+ target.getAttachmentsDescriptor(&desc, &flags, this->hasStencilAttachment());
return this->isCompatible(desc, flags);
}
diff --git a/src/gpu/vk/GrVkRenderPass.h b/src/gpu/vk/GrVkRenderPass.h
index 8b8c641..5009e1e 100644
--- a/src/gpu/vk/GrVkRenderPass.h
+++ b/src/gpu/vk/GrVkRenderPass.h
@@ -94,6 +94,7 @@
// index value.
bool colorAttachmentIndex(uint32_t* index) const;
bool stencilAttachmentIndex(uint32_t* index) const;
+ bool hasStencilAttachment() const { return fAttachmentFlags & kStencil_AttachmentFlag; }
// 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
diff --git a/src/gpu/vk/GrVkRenderTarget.cpp b/src/gpu/vk/GrVkRenderTarget.cpp
index 3021298..761dd97 100644
--- a/src/gpu/vk/GrVkRenderTarget.cpp
+++ b/src/gpu/vk/GrVkRenderTarget.cpp
@@ -40,7 +40,9 @@
GrBackendObjectOwnership::kOwned))
, fResolveAttachmentView(resolveAttachmentView)
, fCachedFramebuffer(nullptr)
- , fCachedSimpleRenderPass(nullptr) {
+ , fCachedStencilFramebuffer(nullptr)
+ , fCachedSimpleRenderPass(nullptr)
+ , fCachedStencilRenderPass(nullptr) {
SkASSERT(info.fProtected == msaaInfo.fProtected);
SkASSERT(sampleCnt > 1);
this->registerWithCacheWrapped(GrWrapCacheable::kNo);
@@ -67,7 +69,9 @@
GrBackendObjectOwnership::kOwned))
, fResolveAttachmentView(resolveAttachmentView)
, fCachedFramebuffer(nullptr)
- , fCachedSimpleRenderPass(nullptr) {
+ , fCachedStencilFramebuffer(nullptr)
+ , fCachedSimpleRenderPass(nullptr)
+ , fCachedStencilRenderPass(nullptr) {
SkASSERT(info.fProtected == msaaInfo.fProtected);
SkASSERT(sampleCnt > 1);
}
@@ -86,7 +90,9 @@
, fMSAAImage(nullptr)
, fResolveAttachmentView(nullptr)
, fCachedFramebuffer(nullptr)
- , fCachedSimpleRenderPass(nullptr) {
+ , fCachedStencilFramebuffer(nullptr)
+ , fCachedSimpleRenderPass(nullptr)
+ , fCachedStencilRenderPass(nullptr) {
this->registerWithCacheWrapped(GrWrapCacheable::kNo);
}
@@ -105,7 +111,9 @@
, fMSAAImage(nullptr)
, fResolveAttachmentView(nullptr)
, fCachedFramebuffer(nullptr)
- , fCachedSimpleRenderPass(nullptr) {}
+ , fCachedStencilFramebuffer(nullptr)
+ , fCachedSimpleRenderPass(nullptr)
+ , fCachedStencilRenderPass(nullptr) {}
GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu,
SkISize dimensions,
@@ -120,7 +128,9 @@
, fMSAAImage(nullptr)
, fResolveAttachmentView(nullptr)
, fCachedFramebuffer(nullptr)
+ , fCachedStencilFramebuffer(nullptr)
, fCachedSimpleRenderPass(renderPass)
+ , fCachedStencilRenderPass(nullptr)
, fSecondaryCommandBuffer(secondaryCommandBuffer) {
SkASSERT(fSecondaryCommandBuffer != VK_NULL_HANDLE);
this->registerWithCacheWrapped(GrWrapCacheable::kNo);
@@ -231,70 +241,91 @@
bool GrVkRenderTarget::completeStencilAttachment() {
SkASSERT(!this->wrapsSecondaryCommandBuffer());
- // 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();
- fCachedSimpleRenderPass = nullptr;
- }
- if (fCachedFramebuffer) {
- fCachedFramebuffer->unref();
- fCachedFramebuffer = nullptr;
- }
- fCompatibleRPHandle = GrVkResourceProvider::CompatibleRPHandle();
return true;
}
-const GrVkRenderPass* GrVkRenderTarget::getSimpleRenderPass() {
- if (fCachedSimpleRenderPass) {
+const GrVkRenderPass* GrVkRenderTarget::getSimpleRenderPass(bool withStencil) {
+ if (withStencil) {
+ if (fCachedStencilRenderPass) {
+ return fCachedStencilRenderPass;
+ }
+ } else {
+ if (fCachedSimpleRenderPass) {
+ return fCachedSimpleRenderPass;
+ }
+ }
+
+ return this->createSimpleRenderPass(withStencil);
+}
+
+const GrVkRenderPass* GrVkRenderTarget::createSimpleRenderPass(bool withStencil) {
+ SkASSERT(!this->wrapsSecondaryCommandBuffer());
+
+ GrVkResourceProvider& rp = this->getVkGpu()->resourceProvider();
+ if (withStencil) {
+ SkASSERT(!fCachedStencilRenderPass);
+ fCachedStencilRenderPass = rp.findCompatibleRenderPass(*this, &fCompatibleStencilRPHandle,
+ withStencil);
+ return fCachedStencilRenderPass;
+ } else {
+ SkASSERT(!fCachedSimpleRenderPass);
+ fCachedSimpleRenderPass = rp.findCompatibleRenderPass(*this, &fCompatibleRPHandle,
+ withStencil);
return fCachedSimpleRenderPass;
}
- return this->createSimpleRenderPass();
}
-const GrVkRenderPass* GrVkRenderTarget::createSimpleRenderPass() {
- SkASSERT(!this->wrapsSecondaryCommandBuffer());
- SkASSERT(!fCachedSimpleRenderPass);
-
- fCachedSimpleRenderPass =
- this->getVkGpu()->resourceProvider().findCompatibleRenderPass(*this, &fCompatibleRPHandle);
- return fCachedSimpleRenderPass;
-}
-
-const GrVkFramebuffer* GrVkRenderTarget::getFramebuffer() {
- if (fCachedFramebuffer) {
- return fCachedFramebuffer;
+const GrVkFramebuffer* GrVkRenderTarget::getFramebuffer(bool withStencil) {
+ if (withStencil) {
+ if (fCachedStencilFramebuffer) {
+ return fCachedStencilFramebuffer;
+ }
+ } else {
+ if (fCachedFramebuffer) {
+ return fCachedFramebuffer;
+ }
}
- return this->createFramebuffer();
+ return this->createFramebuffer(withStencil);
}
-const GrVkFramebuffer* GrVkRenderTarget::createFramebuffer() {
+const GrVkFramebuffer* GrVkRenderTarget::createFramebuffer(bool withStencil) {
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();
- const GrVkRenderPass* renderPass = this->getSimpleRenderPass();
+
+ const GrVkRenderPass* renderPass = this->getSimpleRenderPass(withStencil);
if (!renderPass) {
return nullptr;
}
- fCachedFramebuffer = GrVkFramebuffer::Create(gpu, this->width(), this->height(), renderPass,
- fColorAttachmentView, stencilView);
- return fCachedFramebuffer;
+
+ // Stencil attachment view is stored in the base RT stencil attachment
+ const GrVkImageView* stencilView = withStencil ? this->stencilAttachmentView() : nullptr;
+ GrVkFramebuffer* frameBuffer = GrVkFramebuffer::Create(gpu, this->width(), this->height(),
+ renderPass, fColorAttachmentView,
+ stencilView);
+
+ if (withStencil) {
+ SkASSERT(!fCachedStencilFramebuffer);
+ fCachedStencilFramebuffer = frameBuffer;
+ } else {
+ SkASSERT(!fCachedFramebuffer);
+ fCachedFramebuffer = frameBuffer;
+ }
+
+ return frameBuffer;
}
-void GrVkRenderTarget::getAttachmentsDescriptor(
- GrVkRenderPass::AttachmentsDescriptor* desc,
- GrVkRenderPass::AttachmentFlags* attachmentFlags) const {
+void GrVkRenderTarget::getAttachmentsDescriptor(GrVkRenderPass::AttachmentsDescriptor* desc,
+ GrVkRenderPass::AttachmentFlags* attachmentFlags,
+ bool withStencil) const {
SkASSERT(!this->wrapsSecondaryCommandBuffer());
desc->fColor.fFormat = this->imageFormat();
desc->fColor.fSamples = this->numSamples();
*attachmentFlags = GrVkRenderPass::kColor_AttachmentFlag;
uint32_t attachmentCount = 1;
- const GrStencilAttachment* stencil = this->renderTargetPriv().getStencilAttachment();
- if (stencil) {
+ if (withStencil) {
+ const GrStencilAttachment* stencil = this->renderTargetPriv().getStencilAttachment();
+ SkASSERT(stencil);
const GrVkStencilAttachment* vkStencil = static_cast<const GrVkStencilAttachment*>(stencil);
desc->fStencil.fFormat = vkStencil->imageFormat();
desc->fStencil.fSamples = vkStencil->numSamples();
@@ -317,11 +348,13 @@
SkASSERT(!fResolveAttachmentView);
SkASSERT(!fColorAttachmentView);
SkASSERT(!fCachedFramebuffer);
+ SkASSERT(!fCachedStencilFramebuffer);
SkASSERT(!fCachedSimpleRenderPass);
+ SkASSERT(!fCachedStencilRenderPass);
}
-void GrVkRenderTarget::addResources(GrVkCommandBuffer& commandBuffer) {
- commandBuffer.addResource(this->getFramebuffer());
+void GrVkRenderTarget::addResources(GrVkCommandBuffer& commandBuffer, bool withStencil) {
+ commandBuffer.addResource(this->getFramebuffer(withStencil));
commandBuffer.addResource(this->colorAttachmentView());
commandBuffer.addResource(this->msaaImageResource() ? this->msaaImageResource()
: this->resource());
@@ -351,10 +384,18 @@
fCachedFramebuffer->unref();
fCachedFramebuffer = nullptr;
}
+ if (fCachedStencilFramebuffer) {
+ fCachedStencilFramebuffer->unref();
+ fCachedStencilFramebuffer = nullptr;
+ }
if (fCachedSimpleRenderPass) {
fCachedSimpleRenderPass->unref();
fCachedSimpleRenderPass = nullptr;
}
+ if (fCachedStencilRenderPass) {
+ fCachedStencilRenderPass->unref();
+ fCachedStencilRenderPass = nullptr;
+ }
for (int i = 0; i < fGrSecondaryCommandBuffers.count(); ++i) {
SkASSERT(fGrSecondaryCommandBuffers[i]);
fGrSecondaryCommandBuffers[i]->releaseResources();
diff --git a/src/gpu/vk/GrVkRenderTarget.h b/src/gpu/vk/GrVkRenderTarget.h
index daae1a0..da6f084 100644
--- a/src/gpu/vk/GrVkRenderTarget.h
+++ b/src/gpu/vk/GrVkRenderTarget.h
@@ -43,7 +43,7 @@
GrBackendFormat backendFormat() const override { return this->getBackendFormat(); }
- const GrVkFramebuffer* getFramebuffer();
+ const GrVkFramebuffer* getFramebuffer(bool withStencil);
const GrVkImageView* colorAttachmentView() const { return fColorAttachmentView; }
const GrManagedResource* msaaImageResource() const {
if (fMSAAImage) {
@@ -56,15 +56,26 @@
const GrManagedResource* stencilImageResource() const;
const GrVkImageView* stencilAttachmentView() const;
- const GrVkRenderPass* getSimpleRenderPass();
- GrVkResourceProvider::CompatibleRPHandle compatibleRenderPassHandle() {
+ const GrVkRenderPass* getSimpleRenderPass(bool withStencil);
+ GrVkResourceProvider::CompatibleRPHandle compatibleRenderPassHandle(bool withStencil) {
SkASSERT(!this->wrapsSecondaryCommandBuffer());
- if (!fCompatibleRPHandle.isValid()) {
- SkASSERT(!fCachedSimpleRenderPass);
- this->createSimpleRenderPass();
+
+ auto pRPHandle = withStencil ? &fCompatibleStencilRPHandle : &fCompatibleRPHandle;
+ if (!pRPHandle->isValid()) {
+ this->createSimpleRenderPass(withStencil);
}
- SkASSERT(fCompatibleRPHandle.isValid() == SkToBool(fCachedSimpleRenderPass));
- return fCompatibleRPHandle;
+
+#ifdef SK_DEBUG
+ if (withStencil) {
+ SkASSERT(pRPHandle->isValid() == SkToBool(fCachedStencilRenderPass));
+ SkASSERT(fCachedStencilRenderPass->hasStencilAttachment());
+ } else {
+ SkASSERT(pRPHandle->isValid() == SkToBool(fCachedSimpleRenderPass));
+ SkASSERT(!fCachedSimpleRenderPass->hasStencilAttachment());
+ }
+#endif
+
+ return *pRPHandle;
}
const GrVkRenderPass* externalRenderPass() const {
SkASSERT(this->wrapsSecondaryCommandBuffer());
@@ -86,9 +97,10 @@
GrBackendRenderTarget getBackendRenderTarget() const override;
void getAttachmentsDescriptor(GrVkRenderPass::AttachmentsDescriptor* desc,
- GrVkRenderPass::AttachmentFlags* flags) const;
+ GrVkRenderPass::AttachmentFlags* flags,
+ bool withStencil) const;
- void addResources(GrVkCommandBuffer& commandBuffer);
+ void addResources(GrVkCommandBuffer& commandBuffer, bool withStencil);
void addWrappedGrSecondaryCommandBuffer(std::unique_ptr<GrVkSecondaryCommandBuffer> cmdBuffer) {
fGrSecondaryCommandBuffers.push_back(std::move(cmdBuffer));
@@ -154,8 +166,8 @@
GrVkGpu* getVkGpu() const;
- const GrVkRenderPass* createSimpleRenderPass();
- const GrVkFramebuffer* createFramebuffer();
+ const GrVkRenderPass* createSimpleRenderPass(bool withStencil);
+ const GrVkFramebuffer* createFramebuffer(bool withStencil);
bool completeStencilAttachment() override;
@@ -173,12 +185,18 @@
const GrVkImageView* fResolveAttachmentView;
const GrVkFramebuffer* fCachedFramebuffer;
+ const GrVkFramebuffer* fCachedStencilFramebuffer;
- // This is a cached pointer to a simple render pass. The render target should unref it
- // once it is done with it.
+ // Cached pointers to a simple and stencil render passes. The render target should unref them
+ // once it is done with them.
const GrVkRenderPass* fCachedSimpleRenderPass;
- // This is a handle to be used to quickly get compatible GrVkRenderPasses for this render target
+ const GrVkRenderPass* fCachedStencilRenderPass;
+
+ // This is a handle to be used to quickly get a GrVkRenderPass that is compatible with
+ // this render target if its stencil buffer is ignored.
GrVkResourceProvider::CompatibleRPHandle fCompatibleRPHandle;
+ // Same as above but taking the render target's stencil buffer into account
+ GrVkResourceProvider::CompatibleRPHandle fCompatibleStencilRPHandle;
// 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
diff --git a/src/gpu/vk/GrVkResourceProvider.cpp b/src/gpu/vk/GrVkResourceProvider.cpp
index 017310a..b6a058c 100644
--- a/src/gpu/vk/GrVkResourceProvider.cpp
+++ b/src/gpu/vk/GrVkResourceProvider.cpp
@@ -102,12 +102,13 @@
// RenderPasses as needed that are compatible with the framebuffer.
const GrVkRenderPass*
GrVkResourceProvider::findCompatibleRenderPass(const GrVkRenderTarget& target,
- CompatibleRPHandle* compatibleHandle) {
+ CompatibleRPHandle* compatibleHandle,
+ bool withStencil) {
// Get attachment information from render target. This includes which attachments the render
// target has (color, stencil) and the attachments format and sample count.
GrVkRenderPass::AttachmentFlags attachmentFlags;
GrVkRenderPass::AttachmentsDescriptor attachmentsDesc;
- target.getAttachmentsDescriptor(&attachmentsDesc, &attachmentFlags);
+ target.getAttachmentsDescriptor(&attachmentsDesc, &attachmentFlags, withStencil);
return this->findCompatibleRenderPass(&attachmentsDesc, attachmentFlags, compatibleHandle);
}
@@ -164,11 +165,12 @@
GrVkRenderTarget* target,
const GrVkRenderPass::LoadStoreOps& colorOps,
const GrVkRenderPass::LoadStoreOps& stencilOps,
- CompatibleRPHandle* compatibleHandle) {
+ CompatibleRPHandle* compatibleHandle,
+ bool withStencil) {
GrVkResourceProvider::CompatibleRPHandle tempRPHandle;
GrVkResourceProvider::CompatibleRPHandle* pRPHandle = compatibleHandle ? compatibleHandle
: &tempRPHandle;
- *pRPHandle = target->compatibleRenderPassHandle();
+ *pRPHandle = target->compatibleRenderPassHandle(withStencil);
if (!pRPHandle->isValid()) {
return nullptr;
}
diff --git a/src/gpu/vk/GrVkResourceProvider.h b/src/gpu/vk/GrVkResourceProvider.h
index d4ef863..0ba90e7 100644
--- a/src/gpu/vk/GrVkResourceProvider.h
+++ b/src/gpu/vk/GrVkResourceProvider.h
@@ -57,7 +57,8 @@
// non null it will be set to a handle that can be used in the furutre to quickly return a
// compatible GrVkRenderPasses without the need inspecting a GrVkRenderTarget.
const GrVkRenderPass* findCompatibleRenderPass(const GrVkRenderTarget& target,
- CompatibleRPHandle* compatibleHandle = nullptr);
+ CompatibleRPHandle* compatibleHandle,
+ bool withStencil);
const GrVkRenderPass* findCompatibleRenderPass(GrVkRenderPass::AttachmentsDescriptor*,
GrVkRenderPass::AttachmentFlags,
CompatibleRPHandle* compatibleHandle = nullptr);
@@ -73,7 +74,8 @@
const GrVkRenderPass* findRenderPass(GrVkRenderTarget* target,
const GrVkRenderPass::LoadStoreOps& colorOps,
const GrVkRenderPass::LoadStoreOps& stencilOps,
- CompatibleRPHandle* compatibleHandle = nullptr);
+ CompatibleRPHandle* compatibleHandle,
+ bool withStencil);
// The CompatibleRPHandle must be a valid handle previously set by a call to findRenderPass or
// findCompatibleRenderPass.