From 0090ef6a837f339ecc8b1d5e1e50697fbcd2e76a Mon Sep 17 00:00:00 2001 From: Chris Dalton Date: Wed, 28 Mar 2018 17:35:00 -0600 Subject: [PATCH] Don't use gl_FragCoord on legacy Tegra hardware Bug: skia:7413 Bug: skia:7757 Change-Id: I588c49409fd630f4c15546d8be64fb46c87db3c3 Reviewed-on: https://skia-review.googlesource.com/117007 Reviewed-by: Brian Osman Commit-Queue: Chris Dalton --- src/gpu/gl/GrGLCaps.cpp | 9 +++++++-- src/gpu/gl/GrGLContext.cpp | 6 +++++- src/gpu/gl/GrGLUtil.cpp | 23 +++++++++++++++-------- src/gpu/gl/GrGLUtil.h | 6 +++--- 4 files changed, 30 insertions(+), 14 deletions(-) diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp index 9af54b1dec..e22133cff4 100644 --- a/src/gpu/gl/GrGLCaps.cpp +++ b/src/gpu/gl/GrGLCaps.cpp @@ -2271,7 +2271,7 @@ void GrGLCaps::applyDriverCorrectnessWorkarounds(const GrGLContextInfo& ctxInfo, } // Texture uploads sometimes seem to be ignored to textures bound to FBOS on Tegra3. - if (kTegra3_GrGLRenderer == ctxInfo.renderer()) { + if (kTegra_PreK1_GrGLRenderer == ctxInfo.renderer()) { fDisallowTexSubImageForUnormConfigTexturesEverBoundToFBO = true; fUseDrawInsteadOfAllRenderTargetWrites = true; } @@ -2342,7 +2342,7 @@ void GrGLCaps::applyDriverCorrectnessWorkarounds(const GrGLContextInfo& ctxInfo, shaderCaps->fFragCoordConventionsExtensionString = nullptr; } - if (kTegra3_GrGLRenderer == ctxInfo.renderer()) { + if (kTegra_PreK1_GrGLRenderer == ctxInfo.renderer()) { // The Tegra3 compiler will sometimes never return if we have min(abs(x), 1.0), // so we must do the abs first in a separate expression. shaderCaps->fCanUseMinAndAbsTogether = false; @@ -2407,6 +2407,11 @@ void GrGLCaps::applyDriverCorrectnessWorkarounds(const GrGLContextInfo& ctxInfo, shaderCaps->fInterpolantsAreInaccurate = true; } + // gl_FragCoord has an incorrect subpixel offset on legacy Tegra hardware. + if (kTegra_PreK1_GrGLRenderer == ctxInfo.renderer()) { + shaderCaps->fCanUseFragCoord = false; + } + // On Mali G71, mediump ints don't appear capable of representing every integer beyond +/-2048. // (Are they implemented with fp16?) if (kARM_GrGLVendor == ctxInfo.vendor()) { diff --git a/src/gpu/gl/GrGLContext.cpp b/src/gpu/gl/GrGLContext.cpp index dd774cd76d..2ae47101e6 100644 --- a/src/gpu/gl/GrGLContext.cpp +++ b/src/gpu/gl/GrGLContext.cpp @@ -25,6 +25,10 @@ std::unique_ptr GrGLContext::Make(sk_sp interf GR_GL_CALL_RET(interface.get(), rendererUByte, GetString(GR_GL_RENDERER)); const char* renderer = reinterpret_cast(rendererUByte); + const GrGLubyte* extensionsUByte; + GR_GL_CALL_RET(interface.get(), extensionsUByte, GetString(GR_GL_EXTENSIONS)); + const char* extensions = reinterpret_cast(extensionsUByte); + ConstructorArgs args; args.fGLVersion = GrGLGetVersionFromString(ver); if (GR_GL_INVALID_VER == args.fGLVersion) { @@ -37,7 +41,7 @@ std::unique_ptr GrGLContext::Make(sk_sp interf args.fVendor = GrGLGetVendor(interface.get()); - args.fRenderer = GrGLGetRendererFromString(renderer); + args.fRenderer = GrGLGetRendererFromStrings(renderer, extensions); GrGLGetANGLEInfoFromString(renderer, &args.fANGLEBackend, &args.fANGLEVendor, &args.fANGLERenderer); diff --git a/src/gpu/gl/GrGLUtil.cpp b/src/gpu/gl/GrGLUtil.cpp index 3de894db82..985bd4e304 100644 --- a/src/gpu/gl/GrGLUtil.cpp +++ b/src/gpu/gl/GrGLUtil.cpp @@ -284,12 +284,15 @@ static bool is_renderer_angle(const char* rendererString) { return 0 == strncmp(rendererString, kHeader, kHeaderLength); } -GrGLRenderer GrGLGetRendererFromString(const char* rendererString) { +GrGLRenderer GrGLGetRendererFromStrings(const char* rendererString, const char* extensionString) { if (rendererString) { - if (0 == strcmp(rendererString, "NVIDIA Tegra 3")) { - return kTegra3_GrGLRenderer; - } else if (0 == strcmp(rendererString, "NVIDIA Tegra")) { - return kTegra2_GrGLRenderer; + static const char kTegraStr[] = "NVIDIA Tegra"; + if (0 == strncmp(rendererString, kTegraStr, SK_ARRAY_COUNT(kTegraStr) - 1)) { + // Tegra strings are not very descriptive. We distinguish between the modern and legacy + // architectures by the presence of NV_path_rendering. + return (extensionString && strstr(extensionString, "GL_NV_path_rendering")) + ? kTegra_GrGLRenderer + : kTegra_PreK1_GrGLRenderer; } int lastDigit; int n = sscanf(rendererString, "PowerVR SGX 54%d", &lastDigit); @@ -462,9 +465,13 @@ GrGLVendor GrGLGetVendor(const GrGLInterface* gl) { } GrGLRenderer GrGLGetRenderer(const GrGLInterface* gl) { - const GrGLubyte* v; - GR_GL_CALL_RET(gl, v, GetString(GR_GL_RENDERER)); - return GrGLGetRendererFromString((const char*) v); + const GrGLubyte* rendererString; + GR_GL_CALL_RET(gl, rendererString, GetString(GR_GL_RENDERER)); + + const GrGLubyte* extensionString; + GR_GL_CALL_RET(gl, extensionString, GetString(GR_GL_EXTENSIONS)); + + return GrGLGetRendererFromStrings((const char*) rendererString, (const char*) extensionString); } GrGLenum GrToGLStencilFunc(GrStencilTest test) { diff --git a/src/gpu/gl/GrGLUtil.h b/src/gpu/gl/GrGLUtil.h index 8062a0dbce..8b98854e5c 100644 --- a/src/gpu/gl/GrGLUtil.h +++ b/src/gpu/gl/GrGLUtil.h @@ -47,8 +47,8 @@ enum GrGLVendor { }; enum GrGLRenderer { - kTegra2_GrGLRenderer, - kTegra3_GrGLRenderer, + kTegra_PreK1_GrGLRenderer, // Legacy Tegra architecture (pre-K1). + kTegra_GrGLRenderer, // Tegra with the same architecture as NVIDIA desktop GPUs (K1+). kPowerVR54x_GrGLRenderer, kPowerVRRogue_GrGLRenderer, kAdreno3xx_GrGLRenderer, @@ -161,7 +161,7 @@ GrGLVersion GrGLGetVersionFromString(const char* versionString); GrGLStandard GrGLGetStandardInUseFromString(const char* versionString); GrGLSLVersion GrGLGetGLSLVersionFromString(const char* versionString); GrGLVendor GrGLGetVendorFromString(const char* vendorString); -GrGLRenderer GrGLGetRendererFromString(const char* rendererString); +GrGLRenderer GrGLGetRendererFromStrings(const char* rendererString, const char* extensionString); void GrGLGetANGLEInfoFromString(const char* rendererString, GrGLANGLEBackend*, GrGLANGLEVendor*, GrGLANGLERenderer*);