Changing dst sample type to flags.
Instead of having an enum that says how to sample the dst in the shader (or lack of dst sampling), we now rely on whether or not we have a valid proxy in the GrDstProxyView to know whether we are sampling the dst at all. Then if so we additionally have GrDstSampleFlags to say whether we need to use a texture barrier and whether we are sampling from an input attachment. Change-Id: Id0390a8ad57ec52674922807f6c050d59b7e75a2 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/416416 Reviewed-by: Brian Salomon <bsalomon@google.com> Reviewed-by: Chris Dalton <csmartdalton@google.com> Commit-Queue: Greg Daniel <egdaniel@google.com>
This commit is contained in:
parent
5b5a4c6bf5
commit
87fab9f72a
@ -1307,39 +1307,12 @@ private:
|
||||
Context fReleaseCtx;
|
||||
};
|
||||
|
||||
enum class GrDstSampleType {
|
||||
kNone, // The dst value will not be sampled in the shader
|
||||
kAsTextureCopy, // The dst value will be sampled from a copy of the dst
|
||||
// The types below require a texture barrier
|
||||
kAsSelfTexture, // The dst value is sampled directly from the dst itself as a texture.
|
||||
kAsInputAttachment, // The dst value is sampled directly from the dst as an input attachment.
|
||||
enum class GrDstSampleFlags {
|
||||
kNone = 0,
|
||||
kRequiresTextureBarrier = 1 << 0,
|
||||
kAsInputAttachment = 1 << 1,
|
||||
};
|
||||
|
||||
// Returns true if the sampling of the dst color in the shader is done by reading the dst directly.
|
||||
// Anything that directly reads the dst will need a barrier between draws.
|
||||
static constexpr bool GrDstSampleTypeDirectlySamplesDst(GrDstSampleType type) {
|
||||
switch (type) {
|
||||
case GrDstSampleType::kAsSelfTexture: // fall through
|
||||
case GrDstSampleType::kAsInputAttachment:
|
||||
return true;
|
||||
case GrDstSampleType::kNone: // fall through
|
||||
case GrDstSampleType::kAsTextureCopy:
|
||||
return false;
|
||||
}
|
||||
SkUNREACHABLE;
|
||||
}
|
||||
|
||||
static constexpr bool GrDstSampleTypeUsesTexture(GrDstSampleType type) {
|
||||
switch (type) {
|
||||
case GrDstSampleType::kAsSelfTexture: // fall through
|
||||
case GrDstSampleType::kAsTextureCopy:
|
||||
return true;
|
||||
case GrDstSampleType::kNone: // fall through
|
||||
case GrDstSampleType::kAsInputAttachment:
|
||||
return false;
|
||||
}
|
||||
SkUNREACHABLE;
|
||||
}
|
||||
GR_MAKE_BITFIELD_CLASS_OPS(GrDstSampleFlags)
|
||||
|
||||
#if defined(SK_DEBUG) || GR_TEST_UTILS || defined(SK_ENABLE_DUMP_GPU)
|
||||
static constexpr const char* GrBackendApiToStr(GrBackendApi api) {
|
||||
|
@ -437,12 +437,12 @@ bool GrCaps::isFormatCompressed(const GrBackendFormat& format) const {
|
||||
return GrBackendFormatToCompressionType(format) != SkImage::CompressionType::kNone;
|
||||
}
|
||||
|
||||
GrDstSampleType GrCaps::getDstSampleTypeForProxy(const GrRenderTargetProxy* rt) const {
|
||||
GrDstSampleFlags GrCaps::getDstSampleFlagsForProxy(const GrRenderTargetProxy* rt) const {
|
||||
SkASSERT(rt);
|
||||
if (this->textureBarrierSupport() && !rt->requiresManualMSAAResolve()) {
|
||||
return this->onGetDstSampleTypeForProxy(rt);
|
||||
return this->onGetDstSampleFlagsForProxy(rt);
|
||||
}
|
||||
return GrDstSampleType::kAsTextureCopy;
|
||||
return GrDstSampleFlags::kNone;
|
||||
}
|
||||
|
||||
bool GrCaps::supportsDynamicMSAA(const GrRenderTargetProxy* rtProxy) const {
|
||||
|
@ -397,7 +397,7 @@ public:
|
||||
bool disableTessellationPathRenderer() const { return fDisableTessellationPathRenderer; }
|
||||
|
||||
// Returns how to sample the dst values for the passed in GrRenderTargetProxy.
|
||||
GrDstSampleType getDstSampleTypeForProxy(const GrRenderTargetProxy*) const;
|
||||
GrDstSampleFlags getDstSampleFlagsForProxy(const GrRenderTargetProxy*) const;
|
||||
|
||||
/**
|
||||
* This is used to try to ensure a successful copy a dst in order to perform shader-based
|
||||
@ -613,8 +613,8 @@ private:
|
||||
|
||||
virtual GrSwizzle onGetReadSwizzle(const GrBackendFormat&, GrColorType) const = 0;
|
||||
|
||||
virtual GrDstSampleType onGetDstSampleTypeForProxy(const GrRenderTargetProxy*) const {
|
||||
return GrDstSampleType::kAsTextureCopy;
|
||||
virtual GrDstSampleFlags onGetDstSampleFlagsForProxy(const GrRenderTargetProxy*) const {
|
||||
return GrDstSampleFlags::kNone;
|
||||
}
|
||||
|
||||
bool fSuppressPrints : 1;
|
||||
|
@ -28,14 +28,14 @@ public:
|
||||
GrDstProxyView& operator=(const GrDstProxyView& other) {
|
||||
fProxyView = other.fProxyView;
|
||||
fOffset = other.fOffset;
|
||||
fDstSampleType = other.fDstSampleType;
|
||||
fDstSampleFlags = other.fDstSampleFlags;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const GrDstProxyView& that) const {
|
||||
return fProxyView == that.fProxyView &&
|
||||
fOffset == that.fOffset &&
|
||||
fDstSampleType == that.fDstSampleType;
|
||||
fDstSampleFlags == that.fDstSampleFlags;
|
||||
}
|
||||
bool operator!=(const GrDstProxyView& that) const { return !(*this == that); }
|
||||
|
||||
@ -54,14 +54,14 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
GrDstSampleType dstSampleType() const { return fDstSampleType; }
|
||||
GrDstSampleFlags dstSampleFlags() const { return fDstSampleFlags; }
|
||||
|
||||
void setDstSampleType(GrDstSampleType dstSampleType) { fDstSampleType = dstSampleType; }
|
||||
void setDstSampleFlags(GrDstSampleFlags dstSampleFlags) { fDstSampleFlags = dstSampleFlags; }
|
||||
|
||||
private:
|
||||
GrSurfaceProxyView fProxyView;
|
||||
SkIPoint fOffset = {0, 0};
|
||||
GrDstSampleType fDstSampleType = GrDstSampleType::kNone;
|
||||
GrDstSampleFlags fDstSampleFlags = GrDstSampleFlags::kNone;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -397,17 +397,14 @@ void GrOpsTask::addDrawOp(GrDrawingManager* drawingMgr, GrOp::Owner op, bool use
|
||||
op->visitProxies(addDependency);
|
||||
clip.visitProxies(addDependency);
|
||||
if (dstProxyView.proxy()) {
|
||||
if (GrDstSampleTypeUsesTexture(dstProxyView.dstSampleType())) {
|
||||
if (!(dstProxyView.dstSampleFlags() & GrDstSampleFlags::kAsInputAttachment)) {
|
||||
this->addSampledTexture(dstProxyView.proxy());
|
||||
}
|
||||
addDependency(dstProxyView.proxy(), GrMipmapped::kNo);
|
||||
if (this->target(0) == dstProxyView.proxy()) {
|
||||
// Since we are sampling and drawing to the same surface we will need to use
|
||||
// texture barriers.
|
||||
SkASSERT(GrDstSampleTypeDirectlySamplesDst(dstProxyView.dstSampleType()));
|
||||
if (dstProxyView.dstSampleFlags() & GrDstSampleFlags::kRequiresTextureBarrier) {
|
||||
fRenderPassXferBarriers |= GrXferBarrierFlags::kTexture;
|
||||
}
|
||||
SkASSERT(dstProxyView.dstSampleType() != GrDstSampleType::kAsInputAttachment ||
|
||||
addDependency(dstProxyView.proxy(), GrMipmapped::kNo);
|
||||
SkASSERT(!(dstProxyView.dstSampleFlags() & GrDstSampleFlags::kAsInputAttachment) ||
|
||||
dstProxyView.offset().isZero());
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,10 @@
|
||||
GrPipeline::GrPipeline(const InitArgs& args,
|
||||
sk_sp<const GrXferProcessor> xferProcessor,
|
||||
const GrAppliedHardClip& hardClip)
|
||||
: fWriteSwizzle(args.fWriteSwizzle) {
|
||||
: fDstProxy(args.fDstProxyView)
|
||||
, fWindowRectsState(hardClip.windowRectsState())
|
||||
, fXferProcessor(std::move(xferProcessor))
|
||||
, fWriteSwizzle(args.fWriteSwizzle) {
|
||||
fFlags = (Flags)args.fInputFlags;
|
||||
if (hardClip.hasStencilClip()) {
|
||||
fFlags |= Flags::kHasStencilClip;
|
||||
@ -28,14 +31,8 @@ GrPipeline::GrPipeline(const InitArgs& args,
|
||||
if (hardClip.scissorState().enabled()) {
|
||||
fFlags |= Flags::kScissorTestEnabled;
|
||||
}
|
||||
|
||||
fWindowRectsState = hardClip.windowRectsState();
|
||||
|
||||
fXferProcessor = std::move(xferProcessor);
|
||||
|
||||
SkASSERT((args.fDstProxyView.dstSampleType() != GrDstSampleType::kNone) ==
|
||||
SkToBool(args.fDstProxyView.proxy()));
|
||||
fDstProxy = args.fDstProxyView;
|
||||
// If we have any special dst sample flags we better also have a dst proxy
|
||||
SkASSERT(this->dstSampleFlags() == GrDstSampleFlags::kNone || this->dstProxyView());
|
||||
}
|
||||
|
||||
GrPipeline::GrPipeline(const InitArgs& args, GrProcessorSet&& processors,
|
||||
@ -62,7 +59,7 @@ GrPipeline::GrPipeline(const InitArgs& args, GrProcessorSet&& processors,
|
||||
}
|
||||
|
||||
GrXferBarrierType GrPipeline::xferBarrierType(const GrCaps& caps) const {
|
||||
if (this->dstProxyView().proxy() && GrDstSampleTypeDirectlySamplesDst(this->dstSampleType())) {
|
||||
if (this->dstSampleFlags() & GrDstSampleFlags::kRequiresTextureBarrier) {
|
||||
return kTexture_GrXferBarrierType;
|
||||
}
|
||||
return this->getXferProcessor().xferBarrierType(caps);
|
||||
@ -101,7 +98,7 @@ void GrPipeline::genKey(GrProcessorKeyBuilder* b, const GrCaps& caps) const {
|
||||
b->addBits(kBlendCoeffSize, blendInfo.fSrcBlend, "srcBlend");
|
||||
b->addBits(kBlendCoeffSize, blendInfo.fDstBlend, "dstBlend");
|
||||
b->addBits(kBlendEquationSize, blendInfo.fEquation, "equation");
|
||||
b->addBool(this->usesInputAttachment(), "inputAttach");
|
||||
b->addBool(this->usesDstInputAttachment(), "inputAttach");
|
||||
}
|
||||
|
||||
void GrPipeline::visitTextureEffects(
|
||||
|
@ -124,11 +124,9 @@ public:
|
||||
|
||||
// Helper functions to quickly know if this GrPipeline will access the dst as a texture or an
|
||||
// input attachment.
|
||||
bool usesDstTexture() const {
|
||||
return GrDstSampleTypeUsesTexture(this->dstSampleType());
|
||||
}
|
||||
bool usesInputAttachment() const {
|
||||
return this->dstSampleType() == GrDstSampleType::kAsInputAttachment;
|
||||
bool usesDstTexture() const { return this->dstProxyView() && !this->usesDstInputAttachment(); }
|
||||
bool usesDstInputAttachment() const {
|
||||
return this->dstSampleFlags()& GrDstSampleFlags::kAsInputAttachment;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -140,7 +138,7 @@ public:
|
||||
|
||||
SkIPoint dstTextureOffset() const { return fDstProxy.offset(); }
|
||||
|
||||
GrDstSampleType dstSampleType() const { return fDstProxy.dstSampleType(); }
|
||||
GrDstSampleFlags dstSampleFlags() const { return fDstProxy.dstSampleFlags(); }
|
||||
|
||||
/** If this GrXferProcessor uses a texture to access the dst color, returns that texture. */
|
||||
GrTexture* peekDstTexture() const {
|
||||
|
@ -104,7 +104,9 @@ static void gen_xp_key(const GrXferProcessor& xp,
|
||||
origin = pipeline.dstProxyView().origin();
|
||||
originIfDstTexture = &origin;
|
||||
}
|
||||
xp.getGLSLProcessorKey(*caps.shaderCaps(), b, originIfDstTexture, pipeline.dstSampleType());
|
||||
|
||||
xp.getGLSLProcessorKey(*caps.shaderCaps(), b, originIfDstTexture,
|
||||
pipeline.dstSampleFlags() & GrDstSampleFlags::kAsInputAttachment);
|
||||
}
|
||||
|
||||
static void gen_fp_key(const GrFragmentProcessor& fp,
|
||||
|
@ -1950,21 +1950,16 @@ bool GrSurfaceDrawContext::setupDstProxyView(const GrOp& op, GrDstProxyView* dst
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fDstSampleType == GrDstSampleType::kNone) {
|
||||
fDstSampleType = this->caps()->getDstSampleTypeForProxy(this->asRenderTargetProxy());
|
||||
}
|
||||
SkASSERT(fDstSampleType != GrDstSampleType::kNone);
|
||||
auto dstSampleFlags = this->caps()->getDstSampleFlagsForProxy(this->asRenderTargetProxy());
|
||||
|
||||
if (GrDstSampleTypeDirectlySamplesDst(fDstSampleType)) {
|
||||
// The render target is a texture or input attachment, so we can read from it directly in
|
||||
// the shader. The XP will be responsible to detect this situation and request a texture
|
||||
// barrier.
|
||||
if (dstSampleFlags & GrDstSampleFlags::kRequiresTextureBarrier) {
|
||||
// If we require a barrier to sample the dst it means we are sampling the RT itself either
|
||||
// as a texture or input attachment.
|
||||
dstProxyView->setProxyView(this->readSurfaceView());
|
||||
dstProxyView->setOffset(0, 0);
|
||||
dstProxyView->setDstSampleType(fDstSampleType);
|
||||
dstProxyView->setDstSampleFlags(dstSampleFlags);
|
||||
return true;
|
||||
}
|
||||
SkASSERT(fDstSampleType == GrDstSampleType::kAsTextureCopy);
|
||||
|
||||
GrColorType colorType = this->colorInfo().colorType();
|
||||
// MSAA consideration: When there is support for reading MSAA samples in the shader we could
|
||||
@ -2003,6 +1998,6 @@ bool GrSurfaceDrawContext::setupDstProxyView(const GrOp& op, GrDstProxyView* dst
|
||||
|
||||
dstProxyView->setProxyView({std::move(copy), this->origin(), this->readSwizzle()});
|
||||
dstProxyView->setOffset(dstOffset);
|
||||
dstProxyView->setDstSampleType(fDstSampleType);
|
||||
dstProxyView->setDstSampleFlags(dstSampleFlags);
|
||||
return true;
|
||||
}
|
||||
|
@ -721,8 +721,6 @@ private:
|
||||
|
||||
bool fNeedsStencil = false;
|
||||
|
||||
GrDstSampleType fDstSampleType = GrDstSampleType::kNone;
|
||||
|
||||
#if GR_TEST_UTILS
|
||||
bool fPreserveOpsOnFullClear_TestingOnly = false;
|
||||
#endif
|
||||
|
@ -30,7 +30,7 @@ bool GrXferProcessor::hasSecondaryOutput() const {
|
||||
|
||||
void GrXferProcessor::getGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b,
|
||||
const GrSurfaceOrigin* originIfDstTexture,
|
||||
GrDstSampleType dstSampleType) const {
|
||||
bool usesInputAttachmentForDstRead) const {
|
||||
uint32_t key = this->willReadDstColor() ? 0x1 : 0x0;
|
||||
if (key) {
|
||||
if (originIfDstTexture) {
|
||||
@ -38,9 +38,7 @@ void GrXferProcessor::getGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorK
|
||||
if (kTopLeft_GrSurfaceOrigin == *originIfDstTexture) {
|
||||
key |= 0x4;
|
||||
}
|
||||
// We don't just add the whole dstSampleType to the key because sampling a copy or the
|
||||
// rt directly produces the same shader code.
|
||||
if (dstSampleType == GrDstSampleType::kAsInputAttachment) {
|
||||
if (usesInputAttachmentForDstRead) {
|
||||
key |= 0x8;
|
||||
}
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ public:
|
||||
void getGLSLProcessorKey(const GrShaderCaps&,
|
||||
GrProcessorKeyBuilder*,
|
||||
const GrSurfaceOrigin* originIfDstTexture,
|
||||
GrDstSampleType dstSampleType) const;
|
||||
bool usesInputAttachmentForDstRead) const;
|
||||
|
||||
/** Returns a new instance of the appropriate *GL* implementation class
|
||||
for the given GrXferProcessor; caller is responsible for deleting
|
||||
|
@ -4543,11 +4543,11 @@ GrSwizzle GrGLCaps::getWriteSwizzle(const GrBackendFormat& format, GrColorType c
|
||||
return {};
|
||||
}
|
||||
|
||||
GrDstSampleType GrGLCaps::onGetDstSampleTypeForProxy(const GrRenderTargetProxy* rt) const {
|
||||
GrDstSampleFlags GrGLCaps::onGetDstSampleFlagsForProxy(const GrRenderTargetProxy* rt) const {
|
||||
if (rt->asTextureProxy()) {
|
||||
return GrDstSampleType::kAsSelfTexture;
|
||||
return GrDstSampleFlags::kRequiresTextureBarrier;
|
||||
}
|
||||
return GrDstSampleType::kAsTextureCopy;
|
||||
return GrDstSampleFlags::kNone;
|
||||
}
|
||||
|
||||
uint64_t GrGLCaps::computeFormatKey(const GrBackendFormat& format) const {
|
||||
|
@ -503,7 +503,7 @@ private:
|
||||
|
||||
GrSwizzle onGetReadSwizzle(const GrBackendFormat&, GrColorType) const override;
|
||||
|
||||
GrDstSampleType onGetDstSampleTypeForProxy(const GrRenderTargetProxy*) const override;
|
||||
GrDstSampleFlags onGetDstSampleFlagsForProxy(const GrRenderTargetProxy*) const override;
|
||||
|
||||
bool onSupportsDynamicMSAA(const GrRenderTargetProxy*) const override {
|
||||
switch (fMSFBOType) {
|
||||
|
@ -248,7 +248,7 @@ bool GrGLSLProgramBuilder::emitAndInstallDstTexture() {
|
||||
fFS.codeAppendf("%s = ", dstColor);
|
||||
fFS.appendTextureLookup(fDstTextureSamplerHandle, "_dstTexCoord");
|
||||
fFS.codeAppend(";\n");
|
||||
} else if (this->pipeline().usesInputAttachment()) {
|
||||
} else if (this->pipeline().usesDstInputAttachment()) {
|
||||
// Set up an input attachment for the destination texture.
|
||||
const GrSwizzle& swizzle = dstView.swizzle();
|
||||
fDstTextureSamplerHandle = this->emitInputSampler(swizzle, "DstTextureInput");
|
||||
@ -302,7 +302,6 @@ bool GrGLSLProgramBuilder::emitAndInstallXferProc(const SkString& colorIn,
|
||||
coverageIn.size() ? coverageIn.c_str() : "float4(1)",
|
||||
fFS.getPrimaryColorOutputName(),
|
||||
fFS.getSecondaryColorOutputName(),
|
||||
this->pipeline().dstSampleType(),
|
||||
fDstTextureSamplerHandle,
|
||||
fDstTextureOrigin,
|
||||
this->pipeline().writeSwizzle());
|
||||
|
@ -34,7 +34,6 @@ public:
|
||||
const char* inputCoverage,
|
||||
const char* outputPrimary,
|
||||
const char* outputSecondary,
|
||||
GrDstSampleType dstSampleType,
|
||||
const SamplerHandle dstTextureSamplerHandle,
|
||||
GrSurfaceOrigin dstTextureOrigin,
|
||||
const GrSwizzle& writeSwizzle)
|
||||
@ -46,7 +45,6 @@ public:
|
||||
, fInputCoverage(inputCoverage)
|
||||
, fOutputPrimary(outputPrimary)
|
||||
, fOutputSecondary(outputSecondary)
|
||||
, fDstSampleType(dstSampleType)
|
||||
, fDstTextureSamplerHandle(dstTextureSamplerHandle)
|
||||
, fDstTextureOrigin(dstTextureOrigin)
|
||||
, fWriteSwizzle(writeSwizzle) {}
|
||||
@ -58,7 +56,6 @@ public:
|
||||
const char* fInputCoverage;
|
||||
const char* fOutputPrimary;
|
||||
const char* fOutputSecondary;
|
||||
GrDstSampleType fDstSampleType;
|
||||
const SamplerHandle fDstTextureSamplerHandle;
|
||||
GrSurfaceOrigin fDstTextureOrigin;
|
||||
GrSwizzle fWriteSwizzle;
|
||||
|
@ -1690,15 +1690,15 @@ GrSwizzle GrVkCaps::getWriteSwizzle(const GrBackendFormat& format, GrColorType c
|
||||
return {};
|
||||
}
|
||||
|
||||
GrDstSampleType GrVkCaps::onGetDstSampleTypeForProxy(const GrRenderTargetProxy* rt) const {
|
||||
GrDstSampleFlags GrVkCaps::onGetDstSampleFlagsForProxy(const GrRenderTargetProxy* rt) const {
|
||||
bool isMSAAWithResolve = rt->numSamples() > 1 && rt->asTextureProxy();
|
||||
// TODO: Currently if we have an msaa rt with a resolve, the supportsVkInputAttachment call
|
||||
// references whether the resolve is supported as an input attachment. We need to add a check to
|
||||
// allow checking the color attachment (msaa or not) supports input attachment specifically.
|
||||
if (!isMSAAWithResolve && rt->supportsVkInputAttachment()) {
|
||||
return GrDstSampleType::kAsInputAttachment;
|
||||
return GrDstSampleFlags::kRequiresTextureBarrier | GrDstSampleFlags::kAsInputAttachment;
|
||||
}
|
||||
return GrDstSampleType::kAsTextureCopy;
|
||||
return GrDstSampleFlags::kNone;
|
||||
}
|
||||
|
||||
uint64_t GrVkCaps::computeFormatKey(const GrBackendFormat& format) const {
|
||||
|
@ -293,7 +293,7 @@ private:
|
||||
|
||||
GrSwizzle onGetReadSwizzle(const GrBackendFormat&, GrColorType) const override;
|
||||
|
||||
GrDstSampleType onGetDstSampleTypeForProxy(const GrRenderTargetProxy*) const override;
|
||||
GrDstSampleFlags onGetDstSampleFlagsForProxy(const GrRenderTargetProxy*) const override;
|
||||
|
||||
// ColorTypeInfo for a specific format
|
||||
struct ColorTypeInfo {
|
||||
|
Loading…
Reference in New Issue
Block a user