Commit 46203e32 by Peng Huang Committed by Commit Bot

Workaround context lost for Adreno 42x and 3xx

Bug: chromium:1171371 Change-Id: I8c2e13f3f35bf1f780526ad1d9d483226ce5ea34 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2688901 Commit-Queue: Peng Huang <penghuang@chromium.org> Reviewed-by: 's avatarJonah Ryan-Davis <jonahr@google.com> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 0a99bc39
...@@ -353,6 +353,11 @@ const ShCompileOptions SH_ADD_VULKAN_XFB_EMULATION_SUPPORT_CODE = UINT64_C(1) << ...@@ -353,6 +353,11 @@ const ShCompileOptions SH_ADD_VULKAN_XFB_EMULATION_SUPPORT_CODE = UINT64_C(1) <<
// VK_EXT_transform_feedback extension. // VK_EXT_transform_feedback extension.
const ShCompileOptions SH_ADD_VULKAN_XFB_EXTENSION_SUPPORT_CODE = UINT64_C(1) << 60; const ShCompileOptions SH_ADD_VULKAN_XFB_EXTENSION_SUPPORT_CODE = UINT64_C(1) << 60;
// This flag initializes fragment shader's output variables to zero at the beginning of the fragment
// shader's main(). It is intended as a workaround for drivers which get context lost if
// gl_FragColor is not written.
const ShCompileOptions SH_INIT_FRAGMENT_OUTPUT_VARIABLES = UINT64_C(1) << 61;
// Defines alternate strategies for implementing array index clamping. // Defines alternate strategies for implementing array index clamping.
enum ShArrayIndexClampingStrategy enum ShArrayIndexClampingStrategy
{ {
......
...@@ -516,6 +516,12 @@ struct FeaturesGL : FeatureSetBase ...@@ -516,6 +516,12 @@ struct FeaturesGL : FeatureSetBase
"promote_packed_formats_to_8_bit_per_channel", FeatureCategory::OpenGLWorkarounds, "promote_packed_formats_to_8_bit_per_channel", FeatureCategory::OpenGLWorkarounds,
"Packed color formats are buggy on Macs with AMD GPUs", &members, "Packed color formats are buggy on Macs with AMD GPUs", &members,
"http://anglebug.com/5469"}; "http://anglebug.com/5469"};
// If gl_FragColor is not written by fragment shader, it may cause context lost with Adreno 42x
// and 3xx.
Feature initFragmentOutputVariables = {
"init_fragment_output_variables", FeatureCategory::OpenGLWorkarounds,
"No init gl_FragColor causes context lost", &members, "http://crbug.com/1171371"};
}; };
inline FeaturesGL::FeaturesGL() = default; inline FeaturesGL::FeaturesGL() = default;
......
...@@ -879,7 +879,12 @@ bool TCompiler::checkAndSimplifyAST(TIntermBlock *root, ...@@ -879,7 +879,12 @@ bool TCompiler::checkAndSimplifyAST(TIntermBlock *root,
return false; return false;
} }
} }
if ((compileOptions & SH_INIT_OUTPUT_VARIABLES) != 0 && mShaderType != GL_COMPUTE_SHADER) bool needInitializeOutputVariables =
(compileOptions & SH_INIT_OUTPUT_VARIABLES) != 0 && mShaderType != GL_COMPUTE_SHADER;
needInitializeOutputVariables |=
(compileOptions & SH_INIT_FRAGMENT_OUTPUT_VARIABLES) != 0 &&
mShaderType == GL_FRAGMENT_SHADER;
if (needInitializeOutputVariables)
{ {
if (!initializeOutputVariables(root)) if (!initializeOutputVariables(root))
{ {
...@@ -1490,11 +1495,9 @@ bool TCompiler::wereVariablesCollected() const ...@@ -1490,11 +1495,9 @@ bool TCompiler::wereVariablesCollected() const
bool TCompiler::initializeGLPosition(TIntermBlock *root) bool TCompiler::initializeGLPosition(TIntermBlock *root)
{ {
InitVariableList list;
sh::ShaderVariable var(GL_FLOAT_VEC4); sh::ShaderVariable var(GL_FLOAT_VEC4);
var.name = "gl_Position"; var.name = "gl_Position";
list.push_back(var); return InitializeVariables(this, root, {var}, &mSymbolTable, mShaderVersion, mExtensionBehavior,
return InitializeVariables(this, root, list, &mSymbolTable, mShaderVersion, mExtensionBehavior,
false, false); false, false);
} }
...@@ -1517,6 +1520,7 @@ bool TCompiler::useAllMembersInUnusedStandardAndSharedBlocks(TIntermBlock *root) ...@@ -1517,6 +1520,7 @@ bool TCompiler::useAllMembersInUnusedStandardAndSharedBlocks(TIntermBlock *root)
bool TCompiler::initializeOutputVariables(TIntermBlock *root) bool TCompiler::initializeOutputVariables(TIntermBlock *root)
{ {
InitVariableList list; InitVariableList list;
list.reserve(mOutputVaryings.size());
if (mShaderType == GL_VERTEX_SHADER || mShaderType == GL_GEOMETRY_SHADER_EXT) if (mShaderType == GL_VERTEX_SHADER || mShaderType == GL_GEOMETRY_SHADER_EXT)
{ {
for (const sh::ShaderVariable &var : mOutputVaryings) for (const sh::ShaderVariable &var : mOutputVaryings)
......
...@@ -247,7 +247,7 @@ std::shared_ptr<WaitableCompileEvent> ShaderGL::compile(const gl::Context *conte ...@@ -247,7 +247,7 @@ std::shared_ptr<WaitableCompileEvent> ShaderGL::compile(const gl::Context *conte
ShCompileOptions additionalOptions = SH_INIT_GL_POSITION; ShCompileOptions additionalOptions = SH_INIT_GL_POSITION;
bool isWebGL = context->getExtensions().webglCompatibility; bool isWebGL = context->getExtensions().webglCompatibility;
if (isWebGL && (mState.getShaderType() != gl::ShaderType::Compute)) if (isWebGL && mState.getShaderType() != gl::ShaderType::Compute)
{ {
additionalOptions |= SH_INIT_OUTPUT_VARIABLES; additionalOptions |= SH_INIT_OUTPUT_VARIABLES;
} }
...@@ -259,6 +259,11 @@ std::shared_ptr<WaitableCompileEvent> ShaderGL::compile(const gl::Context *conte ...@@ -259,6 +259,11 @@ std::shared_ptr<WaitableCompileEvent> ShaderGL::compile(const gl::Context *conte
const angle::FeaturesGL &features = GetFeaturesGL(context); const angle::FeaturesGL &features = GetFeaturesGL(context);
if (features.initFragmentOutputVariables.enabled)
{
additionalOptions |= SH_INIT_FRAGMENT_OUTPUT_VARIABLES;
}
if (features.doWhileGLSLCausesGPUHang.enabled) if (features.doWhileGLSLCausesGPUHang.enabled)
{ {
additionalOptions |= SH_REWRITE_DO_WHILE_LOOPS; additionalOptions |= SH_REWRITE_DO_WHILE_LOOPS;
......
...@@ -37,17 +37,67 @@ using angle::CheckedNumeric; ...@@ -37,17 +37,67 @@ using angle::CheckedNumeric;
namespace rx namespace rx
{ {
namespace
{
const char *GetString(const FunctionsGL *functions, GLenum name)
{
return reinterpret_cast<const char *>(functions->getString(name));
}
bool IsMesa(const FunctionsGL *functions, std::array<int, 3> *version)
{
ASSERT(version);
if (functions->standard != STANDARD_GL_DESKTOP)
{
return false;
}
std::string nativeVersionString(GetString(functions, GL_VERSION));
size_t pos = nativeVersionString.find("Mesa");
if (pos == std::string::npos)
{
return false;
}
int *data = version->data();
data[0] = data[1] = data[2] = 0;
std::sscanf(nativeVersionString.c_str() + pos, "Mesa %d.%d.%d", data, data + 1, data + 2);
return true;
}
bool IsAdreno42xOr3xx(const FunctionsGL *functions)
{
const char *nativeGLRenderer = GetString(functions, GL_RENDERER);
int adrenoNumber = 0;
if (std::sscanf(nativeGLRenderer, "Adreno (TM) %d", &adrenoNumber) < 1)
{
// retry for freedreno driver
if (std::sscanf(nativeGLRenderer, "FD%d", &adrenoNumber) < 1)
{
return false;
}
}
return adrenoNumber < 430;
}
} // namespace
SwapControlData::SwapControlData() SwapControlData::SwapControlData()
: targetSwapInterval(0), maxSwapInterval(-1), currentSwapInterval(-1) : targetSwapInterval(0), maxSwapInterval(-1), currentSwapInterval(-1)
{} {}
VendorID GetVendorID(const FunctionsGL *functions) VendorID GetVendorID(const FunctionsGL *functions)
{ {
std::string nativeVendorString(reinterpret_cast<const char *>(functions->getString(GL_VENDOR))); std::string nativeVendorString(GetString(functions, GL_VENDOR));
// Concatenate GL_RENDERER to the string being checked because some vendors put their names in // Concatenate GL_RENDERER to the string being checked because some vendors put their names in
// GL_RENDERER // GL_RENDERER
nativeVendorString += nativeVendorString += " ";
" " + std::string(reinterpret_cast<const char *>(functions->getString(GL_RENDERER))); nativeVendorString += GetString(functions, GL_RENDERER);
if (nativeVendorString.find("NVIDIA") != std::string::npos) if (nativeVendorString.find("NVIDIA") != std::string::npos)
{ {
return VENDOR_ID_NVIDIA; return VENDOR_ID_NVIDIA;
...@@ -82,8 +132,7 @@ VendorID GetVendorID(const FunctionsGL *functions) ...@@ -82,8 +132,7 @@ VendorID GetVendorID(const FunctionsGL *functions)
uint32_t GetDeviceID(const FunctionsGL *functions) uint32_t GetDeviceID(const FunctionsGL *functions)
{ {
std::string nativeRendererString( std::string nativeRendererString(GetString(functions, GL_RENDERER));
reinterpret_cast<const char *>(functions->getString(GL_RENDERER)));
constexpr std::pair<const char *, uint32_t> kKnownDeviceIDs[] = { constexpr std::pair<const char *, uint32_t> kKnownDeviceIDs[] = {
{"Adreno (TM) 418", ANDROID_DEVICE_ID_NEXUS5X}, {"Adreno (TM) 418", ANDROID_DEVICE_ID_NEXUS5X},
{"Adreno (TM) 530", ANDROID_DEVICE_ID_PIXEL1XL}, {"Adreno (TM) 530", ANDROID_DEVICE_ID_PIXEL1XL},
...@@ -101,30 +150,6 @@ uint32_t GetDeviceID(const FunctionsGL *functions) ...@@ -101,30 +150,6 @@ uint32_t GetDeviceID(const FunctionsGL *functions)
return 0; return 0;
} }
bool IsMesa(const FunctionsGL *functions, std::array<int, 3> *version)
{
ASSERT(version);
if (functions->standard != STANDARD_GL_DESKTOP)
{
return false;
}
std::string nativeVersionString(
reinterpret_cast<const char *>(functions->getString(GL_VERSION)));
size_t pos = nativeVersionString.find("Mesa");
if (pos == std::string::npos)
{
return false;
}
int *data = version->data();
data[0] = data[1] = data[2] = 0;
std::sscanf(nativeVersionString.c_str() + pos, "Mesa %d.%d.%d", data, data + 1, data + 2);
return true;
}
namespace nativegl_gl namespace nativegl_gl
{ {
...@@ -1901,6 +1926,12 @@ void InitializeFeatures(const FunctionsGL *functions, angle::FeaturesGL *feature ...@@ -1901,6 +1926,12 @@ void InitializeFeatures(const FunctionsGL *functions, angle::FeaturesGL *feature
ANGLE_FEATURE_CONDITION(features, setZeroLevelBeforeGenerateMipmap, IsApple()); ANGLE_FEATURE_CONDITION(features, setZeroLevelBeforeGenerateMipmap, IsApple());
ANGLE_FEATURE_CONDITION(features, promotePackedFormatsTo8BitPerChannel, IsApple() && hasAMD); ANGLE_FEATURE_CONDITION(features, promotePackedFormatsTo8BitPerChannel, IsApple() && hasAMD);
// crbug.com/1171371
// If output variable gl_FragColor is written by fragment shader, it may cause context lost with
// Adreno 42x and 3xx.
ANGLE_FEATURE_CONDITION(features, initFragmentOutputVariables,
IsAdreno42xOr3xx(functions) || true);
} }
void InitializeFrontendFeatures(const FunctionsGL *functions, angle::FrontendFeatures *features) void InitializeFrontendFeatures(const FunctionsGL *functions, angle::FrontendFeatures *features)
...@@ -2349,18 +2380,17 @@ std::vector<ContextCreationTry> GenerateContextCreationToTry(EGLint requestedTyp ...@@ -2349,18 +2380,17 @@ std::vector<ContextCreationTry> GenerateContextCreationToTry(EGLint requestedTyp
std::string GetRendererString(const FunctionsGL *functions) std::string GetRendererString(const FunctionsGL *functions)
{ {
return std::string(reinterpret_cast<const char *>(functions->getString(GL_RENDERER))); return GetString(functions, GL_RENDERER);
} }
std::string GetVendorString(const FunctionsGL *functions) std::string GetVendorString(const FunctionsGL *functions)
{ {
return std::string(reinterpret_cast<const char *>(functions->getString(GL_VENDOR))); return GetString(functions, GL_VENDOR);
} }
std::string GetVersionString(const FunctionsGL *functions) std::string GetVersionString(const FunctionsGL *functions)
{ {
std::string versionString = std::string versionString = GetString(functions, GL_VERSION);
std::string(reinterpret_cast<const char *>(functions->getString(GL_VERSION)));
if (versionString.find("OpenGL") == std::string::npos) if (versionString.find("OpenGL") == std::string::npos)
{ {
std::string prefix = "OpenGL "; std::string prefix = "OpenGL ";
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment