Add a second stencil attachment to GrRenderTarget for dmsaa
As we move toward dmsaa, we need stencil attachments on the single and multisample attachments both. This is only a temporary solution until the new surface world is finished. Bug: skia:11396 Change-Id: I48928343e1fc9fd2e00362a534be9eb3ade92656 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/399838 Commit-Queue: Chris Dalton <csmartdalton@google.com> Reviewed-by: Greg Daniel <egdaniel@google.com>
This commit is contained in:
parent
9a0da785a5
commit
e0fe23a65e
@ -605,8 +605,9 @@ public:
|
||||
// width and height may be larger than rt (if underlying API allows it).
|
||||
// Returns nullptr if compatible sb could not be created, otherwise the caller owns the ref on
|
||||
// the GrAttachment.
|
||||
virtual sk_sp<GrAttachment> makeStencilAttachmentForRenderTarget(const GrRenderTarget*,
|
||||
SkISize dimensions) = 0;
|
||||
virtual sk_sp<GrAttachment> makeStencilAttachment(const GrBackendFormat& colorFormat,
|
||||
SkISize dimensions,
|
||||
int numStencilSamples) = 0;
|
||||
|
||||
virtual GrBackendFormat getPreferredStencilFormat(const GrBackendFormat&) = 0;
|
||||
|
||||
|
@ -563,11 +563,12 @@ bool GrOpsTask::onExecute(GrOpFlushState* flushState) {
|
||||
|
||||
GrAttachment* stencil = nullptr;
|
||||
if (proxy->needsStencil()) {
|
||||
if (!flushState->resourceProvider()->attachStencilAttachment(renderTarget)) {
|
||||
if (!flushState->resourceProvider()->attachStencilAttachment(renderTarget,
|
||||
fUsesMSAASurface)) {
|
||||
SkDebugf("WARNING: failed to attach a stencil buffer. Rendering will be skipped.\n");
|
||||
return false;
|
||||
}
|
||||
stencil = renderTarget->getStencilAttachment();
|
||||
stencil = renderTarget->getStencilAttachment(fUsesMSAASurface);
|
||||
}
|
||||
|
||||
GrLoadOp stencilLoadOp;
|
||||
|
@ -21,39 +21,46 @@ GrRenderTarget::GrRenderTarget(GrGpu* gpu,
|
||||
GrProtected isProtected,
|
||||
GrAttachment* stencil)
|
||||
: INHERITED(gpu, dimensions, isProtected)
|
||||
, fStencilAttachment(stencil)
|
||||
, fSampleCnt(sampleCount) {
|
||||
if (this->numSamples() > 1) {
|
||||
fMSAAStencilAttachment.reset(stencil);
|
||||
} else {
|
||||
fStencilAttachment.reset(stencil);
|
||||
}
|
||||
}
|
||||
|
||||
GrRenderTarget::~GrRenderTarget() = default;
|
||||
|
||||
void GrRenderTarget::onRelease() {
|
||||
fStencilAttachment = nullptr;
|
||||
fMSAAStencilAttachment = nullptr;
|
||||
|
||||
INHERITED::onRelease();
|
||||
}
|
||||
|
||||
void GrRenderTarget::onAbandon() {
|
||||
fStencilAttachment = nullptr;
|
||||
fMSAAStencilAttachment = nullptr;
|
||||
|
||||
INHERITED::onAbandon();
|
||||
}
|
||||
|
||||
void GrRenderTarget::attachStencilAttachment(sk_sp<GrAttachment> stencil) {
|
||||
if (!stencil && !fStencilAttachment) {
|
||||
void GrRenderTarget::attachStencilAttachment(sk_sp<GrAttachment> stencil, bool useMSAASurface) {
|
||||
auto stencilAttachment = (useMSAASurface) ? &GrRenderTarget::fMSAAStencilAttachment
|
||||
: &GrRenderTarget::fStencilAttachment;
|
||||
if (!stencil && !(this->*stencilAttachment)) {
|
||||
// No need to do any work since we currently don't have a stencil attachment and
|
||||
// we're not actually adding one.
|
||||
return;
|
||||
}
|
||||
|
||||
fStencilAttachment = std::move(stencil);
|
||||
if (!this->completeStencilAttachment()) {
|
||||
fStencilAttachment = nullptr;
|
||||
if (!this->completeStencilAttachment(stencil.get(), useMSAASurface)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this->*stencilAttachment = std::move(stencil);
|
||||
}
|
||||
|
||||
int GrRenderTarget::numStencilBits() const {
|
||||
SkASSERT(this->getStencilAttachment());
|
||||
return GrBackendFormatStencilBits(this->getStencilAttachment()->backendFormat());
|
||||
int GrRenderTarget::numStencilBits(bool useMSAASurface) const {
|
||||
return GrBackendFormatStencilBits(this->getStencilAttachment(useMSAASurface)->backendFormat());
|
||||
}
|
||||
|
||||
|
@ -41,13 +41,20 @@ public:
|
||||
|
||||
virtual GrBackendRenderTarget getBackendRenderTarget() const = 0;
|
||||
|
||||
GrAttachment* getStencilAttachment() const { return fStencilAttachment.get(); }
|
||||
GrAttachment* getStencilAttachment(bool useMSAASurface) const {
|
||||
return (useMSAASurface) ? fMSAAStencilAttachment.get() : fStencilAttachment.get();
|
||||
}
|
||||
|
||||
GrAttachment* getStencilAttachment() const {
|
||||
return getStencilAttachment(this->numSamples() > 1);
|
||||
}
|
||||
|
||||
// Checked when this object is asked to attach a stencil buffer.
|
||||
virtual bool canAttemptStencilAttachment() const = 0;
|
||||
virtual bool canAttemptStencilAttachment(bool useMSAASurface) const = 0;
|
||||
|
||||
void attachStencilAttachment(sk_sp<GrAttachment> stencil);
|
||||
void attachStencilAttachment(sk_sp<GrAttachment> stencil, bool useMSAASurface);
|
||||
|
||||
int numStencilBits() const;
|
||||
int numStencilBits(bool useMSAASurface) const;
|
||||
|
||||
/**
|
||||
* Returns a unique key that identifies this render target's sample pattern. (Must be
|
||||
@ -75,9 +82,10 @@ private:
|
||||
// GrAttachment. When this is called, the GrAttachment has already been put onto
|
||||
// the GrRenderTarget. This function must return false if any failures occur when completing the
|
||||
// stencil attachment.
|
||||
virtual bool completeStencilAttachment() = 0;
|
||||
virtual bool completeStencilAttachment(GrAttachment* stencil, bool useMSAASurface) = 0;
|
||||
|
||||
sk_sp<GrAttachment> fStencilAttachment;
|
||||
sk_sp<GrAttachment> fMSAAStencilAttachment;
|
||||
int fSampleCnt;
|
||||
|
||||
using INHERITED = GrSurface;
|
||||
|
@ -89,15 +89,6 @@ bool GrRenderTargetProxy::instantiate(GrResourceProvider* resourceProvider) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GrRenderTargetProxy::canChangeStencilAttachment() const {
|
||||
if (!fTarget) {
|
||||
// If we aren't instantiated, then we definitely are an internal render target. Ganesh is
|
||||
// free to change stencil attachments on internal render targets.
|
||||
return true;
|
||||
}
|
||||
return fTarget->asRenderTarget()->canAttemptStencilAttachment();
|
||||
}
|
||||
|
||||
sk_sp<GrSurface> GrRenderTargetProxy::createSurface(GrResourceProvider* resourceProvider) const {
|
||||
sk_sp<GrSurface> surface = this->createSurfaceImpl(resourceProvider, fSampleCnt,
|
||||
GrRenderable::kYes, GrMipmapped::kNo);
|
||||
|
@ -157,8 +157,6 @@ protected:
|
||||
sk_sp<GrSurface> createSurface(GrResourceProvider*) const override;
|
||||
|
||||
private:
|
||||
bool canChangeStencilAttachment() const;
|
||||
|
||||
size_t onUninstantiatedGpuMemorySize() const override;
|
||||
SkDEBUGCODE(void onValidateSurface(const GrSurface*) override;)
|
||||
|
||||
|
@ -493,15 +493,15 @@ sk_sp<GrGpuBuffer> GrResourceProvider::createBuffer(size_t size, GrGpuBufferType
|
||||
return buffer;
|
||||
}
|
||||
|
||||
bool GrResourceProvider::attachStencilAttachment(GrRenderTarget* rt) {
|
||||
bool GrResourceProvider::attachStencilAttachment(GrRenderTarget* rt, bool useMSAASurface) {
|
||||
SkASSERT(rt);
|
||||
GrAttachment* stencil = rt->getStencilAttachment();
|
||||
GrAttachment* stencil = rt->getStencilAttachment(useMSAASurface);
|
||||
if (stencil) {
|
||||
SkASSERT(stencil->numSamples() == rt->numSamples());
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!rt->wasDestroyed() && rt->canAttemptStencilAttachment()) {
|
||||
if (!rt->wasDestroyed() && rt->canAttemptStencilAttachment(useMSAASurface)) {
|
||||
GrUniqueKey sbKey;
|
||||
|
||||
#if 0
|
||||
@ -510,8 +510,7 @@ bool GrResourceProvider::attachStencilAttachment(GrRenderTarget* rt) {
|
||||
height = SkNextPow2(height);
|
||||
}
|
||||
#endif
|
||||
GrBackendFormat stencilFormat =
|
||||
this->gpu()->getPreferredStencilFormat(rt->backendFormat());
|
||||
GrBackendFormat stencilFormat = this->gpu()->getPreferredStencilFormat(rt->backendFormat());
|
||||
if (!stencilFormat.isValid()) {
|
||||
return false;
|
||||
}
|
||||
@ -523,15 +522,16 @@ bool GrResourceProvider::attachStencilAttachment(GrRenderTarget* rt) {
|
||||
auto stencil = this->findByUniqueKey<GrAttachment>(sbKey);
|
||||
if (!stencil) {
|
||||
// Need to try and create a new stencil
|
||||
stencil = this->gpu()->makeStencilAttachmentForRenderTarget(rt, rt->dimensions());
|
||||
stencil = this->gpu()->makeStencilAttachment(rt->backendFormat(), rt->dimensions(),
|
||||
rt->numSamples());
|
||||
if (!stencil) {
|
||||
return false;
|
||||
}
|
||||
this->assignUniqueKeyToResource(sbKey, stencil.get());
|
||||
}
|
||||
rt->attachStencilAttachment(std::move(stencil));
|
||||
rt->attachStencilAttachment(std::move(stencil), useMSAASurface);
|
||||
}
|
||||
stencil = rt->getStencilAttachment();
|
||||
stencil = rt->getStencilAttachment(useMSAASurface);
|
||||
SkASSERT(!stencil || stencil->numSamples() == rt->numSamples());
|
||||
return stencil != nullptr;
|
||||
}
|
||||
|
@ -267,10 +267,10 @@ public:
|
||||
const void* data = nullptr);
|
||||
|
||||
/**
|
||||
* If passed in render target already has a stencil buffer with at least "numSamples" samples,
|
||||
* return true. Otherwise attempt to attach one and return true on success.
|
||||
* If passed in render target already has a stencil buffer on the specified surface, return
|
||||
* true. Otherwise attempt to attach one and return true on success.
|
||||
*/
|
||||
bool attachStencilAttachment(GrRenderTarget* rt);
|
||||
bool attachStencilAttachment(GrRenderTarget* rt, bool useMSAASurface);
|
||||
|
||||
sk_sp<GrAttachment> makeMSAAAttachment(SkISize dimensions,
|
||||
const GrBackendFormat& format,
|
||||
|
@ -865,7 +865,7 @@ sk_sp<GrRenderTarget> GrD3DGpu::onWrapBackendRenderTarget(const GrBackendRenderT
|
||||
// We don't allow the client to supply a premade stencil buffer. We always create one if needed.
|
||||
SkASSERT(!rt.stencilBits());
|
||||
if (tgt) {
|
||||
SkASSERT(tgt->canAttemptStencilAttachment());
|
||||
SkASSERT(tgt->canAttemptStencilAttachment(tgt->numSamples() > 1));
|
||||
}
|
||||
|
||||
return std::move(tgt);
|
||||
@ -881,15 +881,12 @@ sk_sp<GrGpuBuffer> GrD3DGpu::onCreateBuffer(size_t sizeInBytes, GrGpuBufferType
|
||||
return std::move(buffer);
|
||||
}
|
||||
|
||||
sk_sp<GrAttachment> GrD3DGpu::makeStencilAttachmentForRenderTarget(const GrRenderTarget* rt,
|
||||
SkISize dimensions) {
|
||||
SkASSERT(dimensions.width() >= rt->width());
|
||||
SkASSERT(dimensions.height() >= rt->height());
|
||||
|
||||
sk_sp<GrAttachment> GrD3DGpu::makeStencilAttachment(const GrBackendFormat& /*colorFormat*/,
|
||||
SkISize dimensions, int numStencilSamples) {
|
||||
DXGI_FORMAT sFmt = this->d3dCaps().preferredStencilFormat();
|
||||
|
||||
fStats.incStencilAttachmentCreates();
|
||||
return GrD3DAttachment::MakeStencil(this, dimensions, rt->numSamples(), sFmt);
|
||||
return GrD3DAttachment::MakeStencil(this, dimensions, numStencilSamples, sFmt);
|
||||
}
|
||||
|
||||
bool GrD3DGpu::createTextureResourceForBackendSurface(DXGI_FORMAT dxgiFormat,
|
||||
|
@ -76,8 +76,8 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
sk_sp<GrAttachment> makeStencilAttachmentForRenderTarget(const GrRenderTarget*,
|
||||
SkISize dimensions) override;
|
||||
sk_sp<GrAttachment> makeStencilAttachment(const GrBackendFormat& /*colorFormat*/,
|
||||
SkISize dimensions, int numStencilSamples) override;
|
||||
|
||||
GrBackendFormat getPreferredStencilFormat(const GrBackendFormat&) override {
|
||||
return GrBackendFormat::MakeDxgi(this->d3dCaps().preferredStencilFormat());
|
||||
|
@ -39,7 +39,8 @@ public:
|
||||
const GrD3DTextureResource* msaaTextureResource() const;
|
||||
GrD3DTextureResource* msaaTextureResource();
|
||||
|
||||
bool canAttemptStencilAttachment() const override {
|
||||
bool canAttemptStencilAttachment(bool useMSAASurface) const override {
|
||||
SkASSERT(useMSAASurface == (this->numSamples() > 1));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -106,7 +107,10 @@ private:
|
||||
|
||||
GrD3DGpu* getD3DGpu() const;
|
||||
|
||||
bool completeStencilAttachment() override { return true; }
|
||||
bool completeStencilAttachment(GrAttachment* stencil, bool useMSAASurface) override {
|
||||
SkASSERT(useMSAASurface == (this->numSamples() > 1));
|
||||
return true;
|
||||
}
|
||||
|
||||
// In Direct3D we call the release proc after we are finished with the underlying
|
||||
// GrD3DTextureResource::Resource object (which occurs after the GPU finishes all work on it).
|
||||
|
@ -293,10 +293,10 @@ sk_sp<GrRenderTarget> GrDawnGpu::onWrapBackendRenderTarget(const GrBackendRender
|
||||
return GrDawnRenderTarget::MakeWrapped(this, dimensions, sampleCnt, info);
|
||||
}
|
||||
|
||||
sk_sp<GrAttachment> GrDawnGpu::makeStencilAttachmentForRenderTarget(const GrRenderTarget* rt,
|
||||
SkISize dimensions) {
|
||||
sk_sp<GrAttachment> GrDawnGpu::makeStencilAttachment(const GrBackendFormat& /*colorFormat*/,
|
||||
SkISize dimensions, int numStencilSamples) {
|
||||
fStats.incStencilAttachmentCreates();
|
||||
return GrDawnAttachment::MakeStencil(this, dimensions, rt->numSamples());
|
||||
return GrDawnAttachment::MakeStencil(this, dimensions, numStencilSamples);
|
||||
}
|
||||
|
||||
GrBackendTexture GrDawnGpu::onCreateBackendTexture(SkISize dimensions,
|
||||
|
@ -59,8 +59,8 @@ public:
|
||||
void deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget&) override;
|
||||
#endif
|
||||
|
||||
sk_sp<GrAttachment> makeStencilAttachmentForRenderTarget(const GrRenderTarget*,
|
||||
SkISize dimensions) override;
|
||||
sk_sp<GrAttachment> makeStencilAttachment(const GrBackendFormat& /*colorFormat*/,
|
||||
SkISize dimensions, int numStencilSamples) override;
|
||||
|
||||
GrBackendFormat getPreferredStencilFormat(const GrBackendFormat&) override {
|
||||
return GrBackendFormat::MakeDawn(wgpu::TextureFormat::Depth24PlusStencil8);
|
||||
|
@ -331,7 +331,7 @@ sk_sp<GrDawnProgram> GrDawnProgramBuilder::Build(GrDawnGpu* gpu,
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
if (programInfo.isStencilEnabled()) {
|
||||
SkASSERT(renderTarget->numStencilBits() == 8);
|
||||
SkASSERT(renderTarget->numStencilBits(renderTarget->numSamples() > 1) == 8);
|
||||
}
|
||||
#endif
|
||||
depthStencilState = create_depth_stencil_state(programInfo, depthStencilFormat);
|
||||
|
@ -35,7 +35,8 @@ size_t GrDawnRenderTarget::onGpuMemorySize() const {
|
||||
GrMipmapped::kNo);
|
||||
}
|
||||
|
||||
bool GrDawnRenderTarget::completeStencilAttachment() {
|
||||
bool GrDawnRenderTarget::completeStencilAttachment(GrAttachment* stencil, bool useMSAASurface) {
|
||||
SkASSERT(useMSAASurface == (this->numSamples() > 1));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,8 @@ public:
|
||||
|
||||
~GrDawnRenderTarget() override;
|
||||
|
||||
bool canAttemptStencilAttachment() const override {
|
||||
bool canAttemptStencilAttachment(bool useMSAASurface) const override {
|
||||
SkASSERT(useMSAASurface == (this->numSamples() > 1));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -43,7 +44,7 @@ protected:
|
||||
// This accounts for the texture's memory and any MSAA renderbuffer's memory.
|
||||
size_t onGpuMemorySize() const override;
|
||||
|
||||
bool completeStencilAttachment() override;
|
||||
bool completeStencilAttachment(GrAttachment* stencil, bool useMSAASurface) override;
|
||||
GrDawnRenderTargetInfo fInfo;
|
||||
using INHERITED = GrRenderTarget;
|
||||
};
|
||||
|
@ -21,7 +21,8 @@ GrDawnTextureRenderTarget::GrDawnTextureRenderTarget(GrDawnGpu* gpu,
|
||||
, GrDawnRenderTarget(gpu, dimensions, sampleCnt,
|
||||
GrDawnRenderTargetInfo(textureInfo)) {}
|
||||
|
||||
bool GrDawnTextureRenderTarget::canAttemptStencilAttachment() const {
|
||||
bool GrDawnTextureRenderTarget::canAttemptStencilAttachment(bool useMSAASurface) const {
|
||||
SkASSERT(useMSAASurface == (this->numSamples() > 1));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,7 @@ public:
|
||||
const GrDawnTextureInfo& textureInfo,
|
||||
GrMipmapStatus mipmapStatus);
|
||||
|
||||
bool canAttemptStencilAttachment() const override;
|
||||
bool canAttemptStencilAttachment(bool useMSAASurface) const override;
|
||||
|
||||
GrBackendFormat backendFormat() const override { return GrDawnTexture::backendFormat(); }
|
||||
|
||||
|
@ -1686,14 +1686,11 @@ GrGLuint GrGLGpu::createTexture(SkISize dimensions,
|
||||
return 0;
|
||||
}
|
||||
|
||||
sk_sp<GrAttachment> GrGLGpu::makeStencilAttachmentForRenderTarget(const GrRenderTarget* rt,
|
||||
SkISize dimensions) {
|
||||
SkASSERT(dimensions.width() >= rt->width());
|
||||
SkASSERT(dimensions.height() >= rt->height());
|
||||
|
||||
sk_sp<GrAttachment> GrGLGpu::makeStencilAttachment(const GrBackendFormat& colorFormat,
|
||||
SkISize dimensions, int numStencilSamples) {
|
||||
GrGLAttachment::IDDesc sbDesc;
|
||||
|
||||
int sIdx = this->getCompatibleStencilIndex(rt->backendFormat().asGLFormat());
|
||||
int sIdx = this->getCompatibleStencilIndex(colorFormat.asGLFormat());
|
||||
if (sIdx < 0) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -1709,8 +1706,8 @@ sk_sp<GrAttachment> GrGLGpu::makeStencilAttachmentForRenderTarget(const GrRender
|
||||
GrGLenum glFmt = GrGLFormatToEnum(sFmt);
|
||||
// we do this "if" so that we don't call the multisample
|
||||
// version on a GL that doesn't have an MSAA extension.
|
||||
if (rt->numSamples() > 1) {
|
||||
if (!this->renderbufferStorageMSAA(*fGLContext, rt->numSamples(), glFmt,
|
||||
if (numStencilSamples > 1) {
|
||||
if (!this->renderbufferStorageMSAA(*fGLContext, numStencilSamples, glFmt,
|
||||
dimensions.width(), dimensions.height())) {
|
||||
GL_CALL(DeleteRenderbuffers(1, &sbDesc.fRenderbufferID));
|
||||
return nullptr;
|
||||
@ -1728,7 +1725,7 @@ sk_sp<GrAttachment> GrGLGpu::makeStencilAttachmentForRenderTarget(const GrRender
|
||||
|
||||
return sk_sp<GrAttachment>(new GrGLAttachment(
|
||||
this, sbDesc, dimensions, GrAttachment::UsageFlags::kStencilAttachment,
|
||||
rt->numSamples(), sFmt));
|
||||
numStencilSamples, sFmt));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -1838,10 +1835,10 @@ bool GrGLGpu::flushGLState(GrRenderTarget* renderTarget, bool useMultisampleFBO,
|
||||
GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(renderTarget);
|
||||
GrStencilSettings stencil;
|
||||
if (programInfo.isStencilEnabled()) {
|
||||
SkASSERT(glRT->getStencilAttachment());
|
||||
SkASSERT(glRT->getStencilAttachment(useMultisampleFBO));
|
||||
stencil.reset(*programInfo.userStencilSettings(),
|
||||
programInfo.pipeline().hasStencilClip(),
|
||||
glRT->numStencilBits());
|
||||
glRT->numStencilBits(useMultisampleFBO));
|
||||
}
|
||||
this->flushStencil(stencil, programInfo.origin());
|
||||
this->flushScissorTest(GrScissorTest(programInfo.pipeline().isScissorTestEnabled()));
|
||||
@ -2040,13 +2037,14 @@ void GrGLGpu::endCommandBuffer(GrRenderTarget* rt, bool useMultisampleFBO,
|
||||
}
|
||||
|
||||
void GrGLGpu::clearStencilClip(const GrScissorState& scissor, bool insideStencilMask,
|
||||
GrRenderTarget* target, GrSurfaceOrigin origin) {
|
||||
GrRenderTarget* target, bool useMultisampleFBO,
|
||||
GrSurfaceOrigin origin) {
|
||||
SkASSERT(target);
|
||||
SkASSERT(!this->caps()->performStencilClearsAsDraws());
|
||||
SkASSERT(!scissor.enabled() || !this->caps()->performPartialClearsAsDraws());
|
||||
this->handleDirtyContext();
|
||||
|
||||
GrAttachment* sb = target->getStencilAttachment();
|
||||
GrAttachment* sb = target->getStencilAttachment(useMultisampleFBO);
|
||||
if (!sb) {
|
||||
// We should only get here if we marked a proxy as requiring a SB. However,
|
||||
// the SB creation could later fail. Likely clipping is going to go awry now.
|
||||
@ -2072,7 +2070,7 @@ void GrGLGpu::clearStencilClip(const GrScissorState& scissor, bool insideStencil
|
||||
value = 0;
|
||||
}
|
||||
GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target);
|
||||
this->flushRenderTargetNoColorWrites(glRT, glRT->stencilIsOnMultisampleFBO());
|
||||
this->flushRenderTargetNoColorWrites(glRT, useMultisampleFBO);
|
||||
|
||||
this->flushScissor(scissor, glRT->height(), origin);
|
||||
this->disableWindowRectangles();
|
||||
@ -2164,7 +2162,7 @@ bool GrGLGpu::onReadPixels(GrSurface* surface, int left, int top, int width, int
|
||||
|
||||
GrOpsRenderPass* GrGLGpu::onGetOpsRenderPass(
|
||||
GrRenderTarget* rt,
|
||||
bool useMSAASurface,
|
||||
bool useMultisampleFBO,
|
||||
GrAttachment*,
|
||||
GrSurfaceOrigin origin,
|
||||
const SkIRect& bounds,
|
||||
@ -2176,7 +2174,7 @@ GrOpsRenderPass* GrGLGpu::onGetOpsRenderPass(
|
||||
fCachedOpsRenderPass = std::make_unique<GrGLOpsRenderPass>(this);
|
||||
}
|
||||
|
||||
fCachedOpsRenderPass->set(rt, useMSAASurface, bounds, origin, colorInfo, stencilInfo);
|
||||
fCachedOpsRenderPass->set(rt, useMultisampleFBO, bounds, origin, colorInfo, stencilInfo);
|
||||
return fCachedOpsRenderPass.get();
|
||||
}
|
||||
|
||||
|
@ -113,7 +113,7 @@ public:
|
||||
// Thus this is the implementation of the clearStencil call for the corresponding passthrough
|
||||
// function on GrGLOpsrenderPass.
|
||||
void clearStencilClip(const GrScissorState&, bool insideStencilMask,
|
||||
GrRenderTarget*, GrSurfaceOrigin);
|
||||
GrRenderTarget*, bool useMultisampleFBO, GrSurfaceOrigin);
|
||||
|
||||
void beginCommandBuffer(GrRenderTarget*, bool useMultisampleFBO,
|
||||
const SkIRect& bounds, GrSurfaceOrigin,
|
||||
@ -128,8 +128,8 @@ public:
|
||||
fHWBoundRenderTargetUniqueID.makeInvalid();
|
||||
}
|
||||
|
||||
sk_sp<GrAttachment> makeStencilAttachmentForRenderTarget(const GrRenderTarget* rt,
|
||||
SkISize dimensions) override;
|
||||
sk_sp<GrAttachment> makeStencilAttachment(const GrBackendFormat& colorFormat,
|
||||
SkISize dimensions, int numStencilSamples) override;
|
||||
|
||||
sk_sp<GrAttachment> makeMSAAAttachment(SkISize dimensions,
|
||||
const GrBackendFormat& format,
|
||||
@ -332,7 +332,7 @@ private:
|
||||
GrGpuFinishedContext finishedContext) override;
|
||||
|
||||
GrOpsRenderPass* onGetOpsRenderPass(GrRenderTarget*,
|
||||
bool useMSAASurface,
|
||||
bool useMultisampleFBO,
|
||||
GrAttachment*,
|
||||
GrSurfaceOrigin,
|
||||
const SkIRect&,
|
||||
|
@ -390,5 +390,5 @@ void GrGLOpsRenderPass::onClear(const GrScissorState& scissor, std::array<float,
|
||||
}
|
||||
|
||||
void GrGLOpsRenderPass::onClearStencilClip(const GrScissorState& scissor, bool insideStencilMask) {
|
||||
fGpu->clearStencilClip(scissor, insideStencilMask, fRenderTarget, fOrigin);
|
||||
fGpu->clearStencilClip(scissor, insideStencilMask, fRenderTarget, fUseMultisampleFBO, fOrigin);
|
||||
}
|
||||
|
@ -100,11 +100,12 @@ sk_sp<GrGLRenderTarget> GrGLRenderTarget::MakeWrapped(GrGLGpu* gpu,
|
||||
}
|
||||
|
||||
GrBackendRenderTarget GrGLRenderTarget::getBackendRenderTarget() const {
|
||||
bool useMultisampleFBO = (this->numSamples() > 1);
|
||||
GrGLFramebufferInfo fbi;
|
||||
fbi.fFBOID = (this->numSamples() > 1) ? fMultisampleFBOID : fSingleSampleFBOID;
|
||||
fbi.fFBOID = (useMultisampleFBO) ? fMultisampleFBOID : fSingleSampleFBOID;
|
||||
fbi.fFormat = GrGLFormatToEnum(this->format());
|
||||
int numStencilBits = 0;
|
||||
if (GrAttachment* stencil = this->getStencilAttachment()) {
|
||||
if (GrAttachment* stencil = this->getStencilAttachment(useMultisampleFBO)) {
|
||||
numStencilBits = GrBackendFormatStencilBits(stencil->backendFormat());
|
||||
}
|
||||
|
||||
@ -123,13 +124,12 @@ size_t GrGLRenderTarget::onGpuMemorySize() const {
|
||||
fTotalMemorySamplesPerPixel, GrMipmapped::kNo);
|
||||
}
|
||||
|
||||
bool GrGLRenderTarget::completeStencilAttachment() {
|
||||
bool GrGLRenderTarget::completeStencilAttachment(GrAttachment* stencil, bool useMultisampleFBO) {
|
||||
SkASSERT(useMultisampleFBO == (this->numSamples() > 1));
|
||||
GrGLGpu* gpu = this->getGLGpu();
|
||||
const GrGLInterface* interface = gpu->glInterface();
|
||||
GrAttachment* stencil = this->getStencilAttachment();
|
||||
GrGLuint stencilFBOID = (useMultisampleFBO) ? fMultisampleFBOID : fSingleSampleFBOID;
|
||||
|
||||
GrGLuint stencilFBOID = (this->stencilIsOnMultisampleFBO()) ? fMultisampleFBOID
|
||||
: fSingleSampleFBOID;
|
||||
gpu->invalidateBoundRenderTarget();
|
||||
gpu->bindFramebuffer(GR_GL_FRAMEBUFFER, stencilFBOID);
|
||||
|
||||
@ -203,7 +203,8 @@ GrGLGpu* GrGLRenderTarget::getGLGpu() const {
|
||||
return static_cast<GrGLGpu*>(this->getGpu());
|
||||
}
|
||||
|
||||
bool GrGLRenderTarget::canAttemptStencilAttachment() const {
|
||||
bool GrGLRenderTarget::canAttemptStencilAttachment(bool useMultisampleFBO) const {
|
||||
SkASSERT(useMultisampleFBO == (this->numSamples() > 1));
|
||||
if (this->getGpu()->getContext()->priv().caps()->avoidStencilBuffers()) {
|
||||
return false;
|
||||
}
|
||||
|
@ -44,17 +44,11 @@ public:
|
||||
GrGLuint singleSampleFBOID() const { return fSingleSampleFBOID; }
|
||||
GrGLuint multisampleFBOID() const { return fMultisampleFBOID; }
|
||||
|
||||
// If we have a multisample FBO, that is always where the stencil goes. With dynamic MSAA there
|
||||
// will be a multisample FBO even if numSamples is 1.
|
||||
bool stencilIsOnMultisampleFBO() const {
|
||||
return this->numSamples() > 1 || fMultisampleFBOID != 0;
|
||||
}
|
||||
|
||||
GrBackendRenderTarget getBackendRenderTarget() const override;
|
||||
|
||||
GrBackendFormat backendFormat() const override;
|
||||
|
||||
bool canAttemptStencilAttachment() const override;
|
||||
bool canAttemptStencilAttachment(bool useMultisampleFBO) const override;
|
||||
|
||||
// GrGLRenderTarget overrides dumpMemoryStatistics so it can log its texture and renderbuffer
|
||||
// components separately.
|
||||
@ -85,7 +79,7 @@ private:
|
||||
void setFlags(const GrGLCaps&, const IDs&);
|
||||
|
||||
GrGLGpu* getGLGpu() const;
|
||||
bool completeStencilAttachment() override;
|
||||
bool completeStencilAttachment(GrAttachment* stencil, bool useMultisampleFBO) override;
|
||||
|
||||
size_t onGpuMemorySize() const override;
|
||||
|
||||
|
@ -53,7 +53,7 @@ void GrGLTextureRenderTarget::dumpMemoryStatistics(
|
||||
#endif
|
||||
}
|
||||
|
||||
bool GrGLTextureRenderTarget::canAttemptStencilAttachment() const {
|
||||
bool GrGLTextureRenderTarget::canAttemptStencilAttachment(bool useMultisampleFBO) const {
|
||||
// The RT FBO of GrGLTextureRenderTarget is never created from a
|
||||
// wrapped FBO, so we only care about the flag.
|
||||
return !this->getGpu()->getContext()->priv().caps()->avoidStencilBuffers();
|
||||
|
@ -31,7 +31,7 @@ public:
|
||||
const GrGLRenderTarget::IDs&,
|
||||
GrMipmapStatus);
|
||||
|
||||
bool canAttemptStencilAttachment() const override;
|
||||
bool canAttemptStencilAttachment(bool useMultisampleFBO) const override;
|
||||
|
||||
void dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const override;
|
||||
|
||||
|
@ -210,12 +210,12 @@ sk_sp<GrGpuBuffer> GrMockGpu::onCreateBuffer(size_t sizeInBytes, GrGpuBufferType
|
||||
return sk_sp<GrGpuBuffer>(new GrMockBuffer(this, sizeInBytes, type, accessPattern));
|
||||
}
|
||||
|
||||
sk_sp<GrAttachment> GrMockGpu::makeStencilAttachmentForRenderTarget(const GrRenderTarget* rt,
|
||||
SkISize dimensions) {
|
||||
sk_sp<GrAttachment> GrMockGpu::makeStencilAttachment(const GrBackendFormat& /*colorFormat*/,
|
||||
SkISize dimensions, int numStencilSamples) {
|
||||
fStats.incStencilAttachmentCreates();
|
||||
return sk_sp<GrAttachment>(
|
||||
new GrMockAttachment(this, dimensions, GrAttachment::UsageFlags::kStencilAttachment,
|
||||
rt->numSamples()));
|
||||
numStencilSamples));
|
||||
}
|
||||
|
||||
GrBackendTexture GrMockGpu::onCreateBackendTexture(SkISize dimensions,
|
||||
|
@ -143,8 +143,8 @@ private:
|
||||
return true;
|
||||
}
|
||||
|
||||
sk_sp<GrAttachment> makeStencilAttachmentForRenderTarget(const GrRenderTarget*,
|
||||
SkISize dimensions) override;
|
||||
sk_sp<GrAttachment> makeStencilAttachment(const GrBackendFormat& /*colorFormat*/,
|
||||
SkISize dimensions, int numStencilSamples) override;
|
||||
|
||||
GrBackendFormat getPreferredStencilFormat(const GrBackendFormat&) override {
|
||||
return GrBackendFormat::MakeMock(GrColorType::kUnknown, SkImage::CompressionType::kNone,
|
||||
|
@ -100,8 +100,15 @@ public:
|
||||
this->registerWithCacheWrapped(GrWrapCacheable::kNo);
|
||||
}
|
||||
|
||||
bool canAttemptStencilAttachment() const override { return true; }
|
||||
bool completeStencilAttachment() override { return true; }
|
||||
bool canAttemptStencilAttachment(bool useMSAASurface) const override {
|
||||
SkASSERT(useMSAASurface == (this->numSamples() > 1));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool completeStencilAttachment(GrAttachment*, bool useMSAASurface) override {
|
||||
SkASSERT(useMSAASurface == (this->numSamples() > 1));
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t onGpuMemorySize() const override {
|
||||
int numColorSamples = this->numSamples();
|
||||
|
@ -233,8 +233,8 @@ private:
|
||||
GrColorType dstColorType, id<MTLBuffer> transferBuffer, size_t offset,
|
||||
size_t imageBytes, size_t rowBytes);
|
||||
|
||||
sk_sp<GrAttachment> makeStencilAttachmentForRenderTarget(
|
||||
const GrRenderTarget*, SkISize dimensions) override;
|
||||
sk_sp<GrAttachment> makeStencilAttachment(const GrBackendFormat& /*colorFormat*/,
|
||||
SkISize dimensions, int numStencilSamples) override;
|
||||
|
||||
GrBackendFormat getPreferredStencilFormat(const GrBackendFormat&) override {
|
||||
return GrBackendFormat::MakeMtl(this->mtlCaps().preferredStencilFormat());
|
||||
|
@ -532,17 +532,12 @@ bool GrMtlGpu::clearTexture(GrMtlTexture* tex, size_t bpp, uint32_t levelMask) {
|
||||
return true;
|
||||
}
|
||||
|
||||
sk_sp<GrAttachment> GrMtlGpu::makeStencilAttachmentForRenderTarget(const GrRenderTarget* rt,
|
||||
SkISize dimensions) {
|
||||
SkASSERT(dimensions.width() >= rt->width());
|
||||
SkASSERT(dimensions.height() >= rt->height());
|
||||
|
||||
int samples = rt->numSamples();
|
||||
|
||||
sk_sp<GrAttachment> GrMtlGpu::makeStencilAttachment(const GrBackendFormat& /*colorFormat*/,
|
||||
SkISize dimensions, int numStencilSamples) {
|
||||
MTLPixelFormat sFmt = this->mtlCaps().preferredStencilFormat();
|
||||
|
||||
fStats.incStencilAttachmentCreates();
|
||||
return GrMtlAttachment::GrMtlAttachment::MakeStencil(this, dimensions, samples, sFmt);
|
||||
return GrMtlAttachment::GrMtlAttachment::MakeStencil(this, dimensions, numStencilSamples, sFmt);
|
||||
}
|
||||
|
||||
sk_sp<GrTexture> GrMtlGpu::onCreateTexture(SkISize dimensions,
|
||||
|
@ -77,7 +77,7 @@ void GrMtlPipelineState::setData(const GrRenderTarget* renderTarget,
|
||||
#ifdef SK_DEBUG
|
||||
if (programInfo.isStencilEnabled()) {
|
||||
SkASSERT(renderTarget->getStencilAttachment());
|
||||
SkASSERT(renderTarget->numStencilBits() == 8);
|
||||
SkASSERT(renderTarget->numStencilBits(renderTarget->numSamples() > 1) == 8);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -28,7 +28,8 @@ public:
|
||||
|
||||
~GrMtlRenderTarget() override;
|
||||
|
||||
bool canAttemptStencilAttachment() const override {
|
||||
bool canAttemptStencilAttachment(bool useMSAASurface) const override {
|
||||
SkASSERT(useMSAASurface == (this->numSamples() > 1));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -80,7 +81,7 @@ private:
|
||||
Wrapped);
|
||||
GrMtlRenderTarget(GrMtlGpu* gpu, SkISize, id<MTLTexture> colorTexture, Wrapped);
|
||||
|
||||
bool completeStencilAttachment() override;
|
||||
bool completeStencilAttachment(GrAttachment* stencil, bool useMSAASurface) override;
|
||||
|
||||
using INHERITED = GrRenderTarget;
|
||||
};
|
||||
|
@ -145,7 +145,8 @@ void GrMtlRenderTarget::onRelease() {
|
||||
INHERITED::onRelease();
|
||||
}
|
||||
|
||||
bool GrMtlRenderTarget::completeStencilAttachment() {
|
||||
bool GrMtlRenderTarget::completeStencilAttachment(GrAttachment* stencil, bool useMSAASurface) {
|
||||
SkASSERT(useMSAASurface == (this->numSamples() > 1));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1342,7 +1342,7 @@ sk_sp<GrRenderTarget> GrVkGpu::onWrapBackendRenderTarget(const GrBackendRenderTa
|
||||
// We don't allow the client to supply a premade stencil buffer. We always create one if needed.
|
||||
SkASSERT(!backendRT.stencilBits());
|
||||
if (tgt) {
|
||||
SkASSERT(tgt->canAttemptStencilAttachment());
|
||||
SkASSERT(tgt->canAttemptStencilAttachment(tgt->numSamples() > 1));
|
||||
}
|
||||
|
||||
return std::move(tgt);
|
||||
@ -1468,15 +1468,12 @@ bool GrVkGpu::onRegenerateMipMapLevels(GrTexture* tex) {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
sk_sp<GrAttachment> GrVkGpu::makeStencilAttachmentForRenderTarget(const GrRenderTarget* rt,
|
||||
SkISize dimensions) {
|
||||
SkASSERT(dimensions.width() >= rt->width());
|
||||
SkASSERT(dimensions.height() >= rt->height());
|
||||
|
||||
sk_sp<GrAttachment> GrVkGpu::makeStencilAttachment(const GrBackendFormat& /*colorFormat*/,
|
||||
SkISize dimensions, int numStencilSamples) {
|
||||
VkFormat sFmt = this->vkCaps().preferredStencilFormat();
|
||||
|
||||
fStats.incStencilAttachmentCreates();
|
||||
return GrVkAttachment::MakeStencil(this, dimensions, rt->numSamples(), sFmt);
|
||||
return GrVkAttachment::MakeStencil(this, dimensions, numStencilSamples, sFmt);
|
||||
}
|
||||
|
||||
sk_sp<GrAttachment> GrVkGpu::makeMSAAAttachment(SkISize dimensions,
|
||||
|
@ -108,8 +108,8 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
sk_sp<GrAttachment> makeStencilAttachmentForRenderTarget(const GrRenderTarget*,
|
||||
SkISize dimensions) override;
|
||||
sk_sp<GrAttachment> makeStencilAttachment(const GrBackendFormat& /*colorFormat*/,
|
||||
SkISize dimensions, int numStencilSamples) override;
|
||||
|
||||
GrBackendFormat getPreferredStencilFormat(const GrBackendFormat&) override {
|
||||
return GrBackendFormat::MakeVk(this->vkCaps().preferredStencilFormat());
|
||||
|
@ -78,7 +78,7 @@ GrVkPipelineState* GrVkResourceProvider::PipelineStateCache::findOrCreatePipelin
|
||||
#ifdef SK_DEBUG
|
||||
if (programInfo.isStencilEnabled()) {
|
||||
SkASSERT(renderTarget->getStencilAttachment());
|
||||
SkASSERT(renderTarget->numStencilBits() == 8);
|
||||
SkASSERT(renderTarget->numStencilBits(renderTarget->numSamples() > 1) == 8);
|
||||
SkASSERT(renderTarget->getStencilAttachment()->numSamples() == programInfo.numSamples());
|
||||
}
|
||||
#endif
|
||||
|
@ -227,8 +227,9 @@ GrVkAttachment* GrVkRenderTarget::msaaAttachment() {
|
||||
: this->colorAttachment();
|
||||
}
|
||||
|
||||
bool GrVkRenderTarget::completeStencilAttachment() {
|
||||
bool GrVkRenderTarget::completeStencilAttachment(GrAttachment* stencil, bool useMSAASurface) {
|
||||
SkASSERT(!this->wrapsSecondaryCommandBuffer());
|
||||
SkASSERT(useMSAASurface == (this->numSamples() > 1));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -100,7 +100,8 @@ public:
|
||||
bool wrapsSecondaryCommandBuffer() const { return SkToBool(fExternalFramebuffer); }
|
||||
sk_sp<GrVkFramebuffer> externalFramebuffer() const;
|
||||
|
||||
bool canAttemptStencilAttachment() const override {
|
||||
bool canAttemptStencilAttachment(bool useMSAASurface) const override {
|
||||
SkASSERT(useMSAASurface == (this->numSamples() > 1));
|
||||
// We don't know the status of the stencil attachment for wrapped external secondary command
|
||||
// buffers so we just assume we don't have one.
|
||||
return !this->wrapsSecondaryCommandBuffer();
|
||||
@ -168,7 +169,7 @@ private:
|
||||
SelfDependencyFlags selfDepFlags,
|
||||
LoadFromResolve);
|
||||
|
||||
bool completeStencilAttachment() override;
|
||||
bool completeStencilAttachment(GrAttachment* stencil, bool useMSAASurface) override;
|
||||
|
||||
// In Vulkan we call the release proc after we are finished with the underlying
|
||||
// GrVkImage::Resource object (which occurs after the GPU has finished all work on it).
|
||||
|
@ -96,7 +96,7 @@ static sk_sp<GrRenderTarget> create_RT_with_SB(GrResourceProvider* provider,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!provider->attachStencilAttachment(tex->asRenderTarget())) {
|
||||
if (!provider->attachStencilAttachment(tex->asRenderTarget(), sampleCount > 1)) {
|
||||
return nullptr;
|
||||
}
|
||||
SkASSERT(get_SB(tex->asRenderTarget()));
|
||||
|
@ -1007,7 +1007,8 @@ DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(SurfaceAttachStencil_Gpu, reporter, ctxInf
|
||||
// our surface functions.
|
||||
auto sdc = SkCanvasPriv::TopDeviceSurfaceDrawContext(surface->getCanvas());
|
||||
GrRenderTarget* rt = sdc->accessRenderTarget();
|
||||
REPORTER_ASSERT(reporter, resourceProvider->attachStencilAttachment(rt));
|
||||
REPORTER_ASSERT(reporter,
|
||||
resourceProvider->attachStencilAttachment(rt, rt->numSamples() > 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user