From 247f12620c3febbb8af0f8554ec19a4bdce64011 Mon Sep 17 00:00:00 2001 From: Ben Clayton Date: Wed, 6 Dec 2017 14:01:04 +0000 Subject: [PATCH] gapii: Work around tracing issue with PCS on S7. Fixes: #1456 --- gapii/cc/spy_disable_precompiled_shaders.cpp | 61 ++++++++++++++++++-- 1 file changed, 57 insertions(+), 4 deletions(-) diff --git a/gapii/cc/spy_disable_precompiled_shaders.cpp b/gapii/cc/spy_disable_precompiled_shaders.cpp index e77af6fdb8..cb696ac0b0 100644 --- a/gapii/cc/spy_disable_precompiled_shaders.cpp +++ b/gapii/cc/spy_disable_precompiled_shaders.cpp @@ -19,6 +19,8 @@ #include "gapis/api/gfxtrace.pb.h" +#include + // This file contains a number of GLES method 'overrides' to optionally lie to the // application about the driver not supporting precompiled shaders or programs. @@ -27,6 +29,39 @@ namespace { const char* kOESGetProgramBinary = "OES_get_program_binary"; const char* kReplacementExtension = "__GAPID_PCS_DISABLED__"; // Must be the same length as kOESGetProgramBinary +#define NELEM(x) (sizeof(x) / sizeof(x[0])) + +// HACK: Workaround for devices that do not check the error status after calling +// glProgramBinary() or glProgramBinaryOES(). As the error is not checked, this +// can cause logic later on in the application to fail, sometimes leading to +// application termination. +// See https://github.com/google/gapid/issues/1456#issuecomment-349611106 for +// more information. +const core::Id kProgramHashesForNoError[] = { + // 0xe14cc04bd723f9c2c46eeef948b08a379f090235 + {0xe1, 0x4c, 0xc0, 0x4b, 0xd7, 0x23, 0xf9, 0xc2, 0xc4, 0x6e, + 0xee, 0xf9, 0x48, 0xb0, 0x8a, 0x37, 0x9f, 0x09, 0x02, 0x35}, + + // 0xc231a3a4b597f45244a4745fecdcba918bb8eacc + {0xc2, 0x31, 0xa3, 0xa4, 0xb5, 0x97, 0xf4, 0x52, 0x44, 0xa4, + 0x74, 0x5f, 0xec, 0xdc, 0xba, 0x91, 0x8b, 0xb8, 0xea, 0xcc}, + + // 0x55626b9bc73964f52fd5bcf6710659df97997d83 + {0x55, 0x62, 0x6b, 0x9b, 0xc7, 0x39, 0x64, 0xf5, 0x2f, 0xd5, + 0xbc, 0xf6, 0x71, 0x06, 0x59, 0xdf, 0x97, 0x99, 0x7d, 0x83}, +}; + +bool shouldErrorForProgram(const core::Id& id) { + for (int i = 0; i < NELEM(kProgramHashesForNoError); i++) { + if (id == kProgramHashesForNoError[i]) { + GAPID_WARNING("Not setting error for program with ID (blacklisted): %s", id.string().c_str()); + return false; + } + } + GAPID_INFO("Program ID: %s", id.string().c_str()); + return true; +} + } // anonymous namespace using namespace gapii::GLenum; @@ -36,9 +71,16 @@ namespace gapii { void Spy::glProgramBinary(CallObserver* observer, uint32_t program, uint32_t binary_format, void* binary, int32_t binary_size) { if (mDisablePrecompiledShaders) { + GAPID_WARNING("glProgramBinary(%" PRIu32 ", 0x%X, %p, %" PRId32 ") " + "called when precompiled shaders are disabled", + program, binary_format, binary, binary_size); + // GL_INVALID_ENUM is generated if binaryformat is not a supported format returned in // GL_SHADER_BINARY_FORMATS. - setFakeGlError(observer, GL_INVALID_ENUM); + auto id = core::Id::Hash(binary, binary_size); + if (shouldErrorForProgram(id)) { + setFakeGlError(observer, GL_INVALID_ENUM); + } observer->encode(cmd::glProgramBinary{ observer->getCurrentThread(), program, binary_format, binary, binary_size @@ -56,9 +98,16 @@ void Spy::glProgramBinary(CallObserver* observer, uint32_t program, uint32_t bin void Spy::glProgramBinaryOES(CallObserver* observer, uint32_t program, uint32_t binary_format, void* binary, int32_t binary_size) { if (mDisablePrecompiledShaders) { + GAPID_WARNING("glProgramBinaryOES(%" PRIu32 ", 0x%X, %p, %" PRId32 ") " + "called when precompiled shaders are disabled", + program, binary_format, binary, binary_size); + // GL_INVALID_ENUM is generated if binaryformat is not a supported format returned in // GL_SHADER_BINARY_FORMATS. - setFakeGlError(observer, GL_INVALID_ENUM); + auto id = core::Id::Hash(binary, binary_size); + if (shouldErrorForProgram(id)) { + setFakeGlError(observer, GL_INVALID_ENUM); + } observer->encode(cmd::glProgramBinaryOES{ observer->getCurrentThread(), program, binary_format, binary, binary_size @@ -76,6 +125,10 @@ void Spy::glProgramBinaryOES(CallObserver* observer, uint32_t program, uint32_t void Spy::glShaderBinary(CallObserver* observer, int32_t count, uint32_t* shaders, uint32_t binary_format, void* binary, int32_t binary_size) { if (mDisablePrecompiledShaders) { + GAPID_WARNING("glShaderBinary(%" PRId32 ", %p, 0x%X, %p, %" PRId32 ") " + "called when precompiled shaders are disabled", + count, shaders, binary_format, binary, binary_size); + // GL_INVALID_ENUM is generated if binaryFormat is not a value recognized by the implementation. setFakeGlError(observer, GL_INVALID_ENUM); @@ -136,7 +189,7 @@ GLubyte* Spy::glGetString(CallObserver* observer, uint32_t name) { if (start != std::string::npos) { static std::string copy = list; copy.replace(start, strlen(kOESGetProgramBinary), kReplacementExtension); - // TODO: write atom. + // TODO: write command. return reinterpret_cast(const_cast(copy.c_str())); } } @@ -147,7 +200,7 @@ GLubyte* Spy::glGetStringi(CallObserver* observer, uint32_t name, GLuint index) if (mDisablePrecompiledShaders && (name == GL_EXTENSIONS)) { const char* extension = reinterpret_cast(GlesSpy::mImports.glGetStringi(name, index)); if (strcmp(extension, kOESGetProgramBinary) == 0) { - // TODO: write atom. + // TODO: write command. return reinterpret_cast(const_cast(kReplacementExtension)); } }