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) <<
// VK_EXT_transform_feedback extension.
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.
enum ShArrayIndexClampingStrategy
{
......
......@@ -516,6 +516,12 @@ struct FeaturesGL : FeatureSetBase
"promote_packed_formats_to_8_bit_per_channel", FeatureCategory::OpenGLWorkarounds,
"Packed color formats are buggy on Macs with AMD GPUs", &members,
"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;
......
......@@ -879,7 +879,12 @@ bool TCompiler::checkAndSimplifyAST(TIntermBlock *root,
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))
{
......@@ -1490,11 +1495,9 @@ bool TCompiler::wereVariablesCollected() const
bool TCompiler::initializeGLPosition(TIntermBlock *root)
{
InitVariableList list;
sh::ShaderVariable var(GL_FLOAT_VEC4);
var.name = "gl_Position";
list.push_back(var);
return InitializeVariables(this, root, list, &mSymbolTable, mShaderVersion, mExtensionBehavior,
return InitializeVariables(this, root, {var}, &mSymbolTable, mShaderVersion, mExtensionBehavior,
false, false);
}
......@@ -1517,6 +1520,7 @@ bool TCompiler::useAllMembersInUnusedStandardAndSharedBlocks(TIntermBlock *root)
bool TCompiler::initializeOutputVariables(TIntermBlock *root)
{
InitVariableList list;
list.reserve(mOutputVaryings.size());
if (mShaderType == GL_VERTEX_SHADER || mShaderType == GL_GEOMETRY_SHADER_EXT)
{
for (const sh::ShaderVariable &var : mOutputVaryings)
......
......@@ -247,7 +247,7 @@ std::shared_ptr<WaitableCompileEvent> ShaderGL::compile(const gl::Context *conte
ShCompileOptions additionalOptions = SH_INIT_GL_POSITION;
bool isWebGL = context->getExtensions().webglCompatibility;
if (isWebGL && (mState.getShaderType() != gl::ShaderType::Compute))
if (isWebGL && mState.getShaderType() != gl::ShaderType::Compute)
{
additionalOptions |= SH_INIT_OUTPUT_VARIABLES;
}
......@@ -259,6 +259,11 @@ std::shared_ptr<WaitableCompileEvent> ShaderGL::compile(const gl::Context *conte
const angle::FeaturesGL &features = GetFeaturesGL(context);
if (features.initFragmentOutputVariables.enabled)
{
additionalOptions |= SH_INIT_FRAGMENT_OUTPUT_VARIABLES;
}
if (features.doWhileGLSLCausesGPUHang.enabled)
{
additionalOptions |= SH_REWRITE_DO_WHILE_LOOPS;
......
......@@ -37,17 +37,67 @@ using angle::CheckedNumeric;
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()
: targetSwapInterval(0), maxSwapInterval(-1), currentSwapInterval(-1)
{}
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
// GL_RENDERER
nativeVendorString +=
" " + std::string(reinterpret_cast<const char *>(functions->getString(GL_RENDERER)));
nativeVendorString += " ";
nativeVendorString += GetString(functions, GL_RENDERER);
if (nativeVendorString.find("NVIDIA") != std::string::npos)
{
return VENDOR_ID_NVIDIA;
......@@ -82,8 +132,7 @@ VendorID GetVendorID(const FunctionsGL *functions)
uint32_t GetDeviceID(const FunctionsGL *functions)
{
std::string nativeRendererString(
reinterpret_cast<const char *>(functions->getString(GL_RENDERER)));
std::string nativeRendererString(GetString(functions, GL_RENDERER));
constexpr std::pair<const char *, uint32_t> kKnownDeviceIDs[] = {
{"Adreno (TM) 418", ANDROID_DEVICE_ID_NEXUS5X},
{"Adreno (TM) 530", ANDROID_DEVICE_ID_PIXEL1XL},
......@@ -101,30 +150,6 @@ uint32_t GetDeviceID(const FunctionsGL *functions)
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
{
......@@ -1901,6 +1926,12 @@ void InitializeFeatures(const FunctionsGL *functions, angle::FeaturesGL *feature
ANGLE_FEATURE_CONDITION(features, setZeroLevelBeforeGenerateMipmap, IsApple());
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)
......@@ -2349,18 +2380,17 @@ std::vector<ContextCreationTry> GenerateContextCreationToTry(EGLint requestedTyp
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)
{
return std::string(reinterpret_cast<const char *>(functions->getString(GL_VENDOR)));
return GetString(functions, GL_VENDOR);
}
std::string GetVersionString(const FunctionsGL *functions)
{
std::string versionString =
std::string(reinterpret_cast<const char *>(functions->getString(GL_VERSION)));
std::string versionString = GetString(functions, GL_VERSION);
if (versionString.find("OpenGL") == std::string::npos)
{
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