Revert "Revert "Use a dst size threshold for multitexturing images.""

This reverts commit be85ef2511.

Change-Id: Icc22eb5841fabc53232b360efaac2d6ebf72e358
Reviewed-on: https://skia-review.googlesource.com/79081
Reviewed-by: Robert Phillips <robertphillips@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
This commit is contained in:
Brian Salomon 2017-12-01 10:25:08 -05:00 committed by Skia Commit-Bot
parent 028c0e14d0
commit 762d5e7e1c
4 changed files with 39 additions and 15 deletions

View File

@ -225,9 +225,6 @@ protected:
// Vulkan doesn't support this (yet) and some drivers have issues, too
bool fCrossContextTextureSupport : 1;
// Disables using multiple texture units to batch multiple SkImages at once.
bool fDisableImageMultitexturingSupport : 1;
InstancedSupport fInstancedSupport;
BlendEquationSupport fBlendEquationSupport;

View File

@ -196,7 +196,14 @@ public:
int maxCombinedSamplers() const { return fMaxCombinedSamplers; }
bool disableImageMultitexturingSupport() const { return fDisableImageMultitexturing; }
/**
* In general using multiple texture units for image rendering seems to be a win at smaller
* sizes of dst rects and a loss at larger sizes. Dst rects above this pixel area threshold will
* not use multitexturing.
*/
size_t disableImageMultitexturingDstRectAreaThreshold() const {
return fDisableImageMultitexturingDstRectAreaThreshold;
}
/**
* Given a texture's config, this determines what swizzle must be appended to accesses to the
@ -245,7 +252,6 @@ private:
bool fVertexIDSupport : 1;
bool fFloatIs32Bits : 1;
bool fHalfIs32Bits : 1;
bool fDisableImageMultitexturing : 1;
// Used for specific driver bug work arounds
bool fCanUseMinAndAbsTogether : 1;
@ -277,6 +283,8 @@ private:
int fMaxFragmentSamplers;
int fMaxCombinedSamplers;
size_t fDisableImageMultitexturingDstRectAreaThreshold;
AdvBlendEqInteraction fAdvBlendEqInteraction;
GrSwizzle fConfigTextureSwizzle[kGrPixelConfigCnt];

View File

@ -68,11 +68,9 @@ GrShaderCaps::GrShaderCaps(const GrContextOptions& options) {
fMaxCombinedSamplers = 0;
fAdvBlendEqInteraction = kNotSupported_AdvBlendEqInteraction;
#if GR_TEST_UTILS
fDisableImageMultitexturing = options.fDisableImageMultitexturing;
#else
fDisableImageMultitexturing = false;
#endif
// TODO: Default this to 0 and only enable image multitexturing when a "safe" threshold is
// known for a GPU class.
fDisableImageMultitexturingDstRectAreaThreshold = std::numeric_limits<size_t>::max();
}
void GrShaderCaps::dumpJSON(SkJSONWriter* writer) const {
@ -130,7 +128,8 @@ void GrShaderCaps::dumpJSON(SkJSONWriter* writer) const {
writer->appendS32("Max Combined Samplers", fMaxFragmentSamplers);
writer->appendString("Advanced blend equation interaction",
kAdvBlendEqInteractionStr[fAdvBlendEqInteraction]);
writer->appendBool("Disable image multitexturing", fDisableImageMultitexturing);
writer->appendU64("Disable image multitexturing dst area threshold",
fDisableImageMultitexturingDstRectAreaThreshold);
writer->endObject();
}
@ -138,5 +137,8 @@ void GrShaderCaps::dumpJSON(SkJSONWriter* writer) const {
void GrShaderCaps::applyOptionsOverrides(const GrContextOptions& options) {
#if GR_TEST_UTILS
fDualSourceBlendingSupport = fDualSourceBlendingSupport && !options.fSuppressDualSourceBlending;
if (options.fDisableImageMultitexturing) {
fDisableImageMultitexturingDstRectAreaThreshold = 0;
}
#endif
}

View File

@ -55,7 +55,7 @@ public:
#endif
static int SupportsMultitexture(const GrShaderCaps& caps) {
return caps.integerSupport() && !caps.disableImageMultitexturingSupport();
return caps.integerSupport() && caps.maxFragmentSamplers() > 1;
}
static sk_sp<GrGeometryProcessor> Make(sk_sp<GrTextureProxy> proxies[], int proxyCnt,
@ -293,6 +293,16 @@ public:
DEFINE_OP_CLASS_ID
private:
// This is used in a heursitic for choosing a code path. We don't care what happens with
// really large rects, infs, nans, etc.
#if defined(__clang__) && (__clang_major__ * 1000 + __clang_minor__) >= 3007
__attribute__((no_sanitize("float-cast-overflow")))
#endif
size_t RectSizeAsSizeT(const SkRect &rect) {;
return static_cast<size_t>(SkTMax(rect.width(), 1.f) * SkTMax(rect.height(), 1.f));
}
static constexpr int kMaxTextures = TextureGeometryProcessor::kMaxTextures;
TextureOp(sk_sp<GrTextureProxy> proxy, GrSamplerState::Filter filter, GrColor color,
@ -313,6 +323,8 @@ private:
SkRect bounds;
bounds.setBounds(draw.fQuad.points(), 4);
this->setBounds(bounds, HasAABloat::kNo, IsZeroArea::kNo);
fMaxApproxDstPixelArea = RectSizeAsSizeT(bounds);
}
void onPrepareDraws(Target* target) override {
@ -431,15 +443,18 @@ private:
bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override {
const auto* that = t->cast<TextureOp>();
const auto& shaderCaps = *caps.shaderCaps();
if (!GrColorSpaceXform::Equals(fColorSpaceXform.get(), that->fColorSpaceXform.get())) {
return false;
}
// Because of an issue where GrColorSpaceXform adds the same function every time it is used
// in a texture lookup, we only allow multiple textures when there is no transform.
if (TextureGeometryProcessor::SupportsMultitexture(*caps.shaderCaps()) &&
!fColorSpaceXform) {
if (TextureGeometryProcessor::SupportsMultitexture(shaderCaps) && !fColorSpaceXform &&
fMaxApproxDstPixelArea <= shaderCaps.disableImageMultitexturingDstRectAreaThreshold() &&
that->fMaxApproxDstPixelArea <=
shaderCaps.disableImageMultitexturingDstRectAreaThreshold()) {
int map[kMaxTextures];
int numNewProxies = this->mergeProxies(that, map, *caps.shaderCaps());
int numNewProxies = this->mergeProxies(that, map, shaderCaps);
if (numNewProxies < 0) {
return false;
}
@ -479,6 +494,7 @@ private:
fDraws.push_back_n(that->fDraws.count(), that->fDraws.begin());
}
this->joinBounds(*that);
fMaxApproxDstPixelArea = SkTMax(that->fMaxApproxDstPixelArea, fMaxApproxDstPixelArea);
return true;
}
@ -570,6 +586,7 @@ private:
// Used to track whether fProxy is ref'ed or has a pending IO after finalize() is called.
uint8_t fFinalized;
uint8_t fAllowSRGBInputs;
size_t fMaxApproxDstPixelArea;
typedef GrMeshDrawOp INHERITED;
};