From 762d5e7e1ce918ce3dd7652cc7becdcbc69f47d5 Mon Sep 17 00:00:00 2001 From: Brian Salomon Date: Fri, 1 Dec 2017 10:25:08 -0500 Subject: [PATCH] Revert "Revert "Use a dst size threshold for multitexturing images."" This reverts commit be85ef25111ac59275b1642350ffb608141c404f. Change-Id: Icc22eb5841fabc53232b360efaac2d6ebf72e358 Reviewed-on: https://skia-review.googlesource.com/79081 Reviewed-by: Robert Phillips Commit-Queue: Brian Salomon --- include/gpu/GrCaps.h | 3 --- include/gpu/GrShaderCaps.h | 12 ++++++++++-- src/gpu/GrShaderCaps.cpp | 14 ++++++++------ src/gpu/ops/GrTextureOp.cpp | 25 +++++++++++++++++++++---- 4 files changed, 39 insertions(+), 15 deletions(-) diff --git a/include/gpu/GrCaps.h b/include/gpu/GrCaps.h index b19281b00d..86b27b066a 100644 --- a/include/gpu/GrCaps.h +++ b/include/gpu/GrCaps.h @@ -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; diff --git a/include/gpu/GrShaderCaps.h b/include/gpu/GrShaderCaps.h index 4c847ac8b0..15377ff0b1 100644 --- a/include/gpu/GrShaderCaps.h +++ b/include/gpu/GrShaderCaps.h @@ -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]; diff --git a/src/gpu/GrShaderCaps.cpp b/src/gpu/GrShaderCaps.cpp index 2d9cd0a39b..65721ee897 100644 --- a/src/gpu/GrShaderCaps.cpp +++ b/src/gpu/GrShaderCaps.cpp @@ -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::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 } diff --git a/src/gpu/ops/GrTextureOp.cpp b/src/gpu/ops/GrTextureOp.cpp index 410257cb7c..be37bd303d 100644 --- a/src/gpu/ops/GrTextureOp.cpp +++ b/src/gpu/ops/GrTextureOp.cpp @@ -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 Make(sk_sp 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(SkTMax(rect.width(), 1.f) * SkTMax(rect.height(), 1.f)); + } + static constexpr int kMaxTextures = TextureGeometryProcessor::kMaxTextures; TextureOp(sk_sp 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(); + 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; };