Bind FBO before timer query on Mali GL driver.

glBeginQuery(GL_TIME_ELAPSED/GL_TIMESTAMP) on Mali implementation
assumes a complete FrameBuffer. Without it glGetQueryObject will return
a meaningless value, causing some applications to misbehave.

This workaround caches and binds a default FBO in this case.

Bug: chromium:1356053,b/269068358
Change-Id: I756ded948c2c5aada744f9dd428ad77c37a009c6
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4359032
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Commit-Queue: Kramer Ge <fangzhoug@chromium.org>
This commit is contained in:
Kramer Ge
2023-03-21 18:56:56 -04:00
committed by Angle LUCI CQ
parent ad52f12e59
commit 888ca8d9e3
8 changed files with 48 additions and 4 deletions

View File

@@ -474,6 +474,12 @@ struct FeaturesGL : FeatureSetBase
&members,
};
FeatureInfo bindFramebufferForTimerQueries = {
"bindFramebufferForTimerQueries", FeatureCategory::OpenGLWorkarounds,
"Some drivers require a non-zero framebuffer when beginQuery for TimeElapsed or"
"Timestampis called.",
&members, "https://crbug.com/1356053"};
FeatureInfo supportsFragmentShaderInterlockNV = {
"supportsFragmentShaderInterlockNV", FeatureCategory::OpenGLFeatures,
"Backend GL context supports NV_fragment_shader_interlock extension", &members,

View File

@@ -651,6 +651,15 @@
"Some drivers ignore GL_CLIP_DISTANCEi_EXT state."
]
},
{
"name": "bind_framebuffer_for_timer_queries",
"category": "Workarounds",
"description": [
"Some drivers require a non-zero framebuffer when beginQuery for TimeElapsed or",
"Timestampis called."
],
"issue": "https://crbug.com/1356053"
},
{
"name": "supports_fragment_shader_interlock_NV",
"category": "Features",

View File

@@ -2,7 +2,7 @@
"include/platform/FeaturesD3D_autogen.h":
"bdce5cac5c70e04fd39e9cf8c6969292",
"include/platform/FeaturesGL_autogen.h":
"38325ab28fca006d06f46d1ad4ad2d63",
"331b1660b3982f6540e362764df26021",
"include/platform/FeaturesMtl_autogen.h":
"d67e2035dabd6e495737da385d5dbe94",
"include/platform/FeaturesVk_autogen.h":
@@ -16,13 +16,13 @@
"include/platform/gen_features.py":
"062989f7a8f3ff3b383f98fc8908dc33",
"include/platform/gl_features.json":
"83005189979f62258c7799ec6a6a7572",
"cef92e7ede4c824b8bae37123401d354",
"include/platform/mtl_features.json":
"cd4de616ed3d18620f8c5b16cb076e66",
"include/platform/vk_features.json":
"f871458b67decd588bcfed4b0381bdcb",
"util/angle_features_autogen.cpp":
"2eac5da5a58249c9ad201c26666a0ff7",
"99892e8229c4ff449d5497711b5442a8",
"util/angle_features_autogen.h":
"3da81e7b0093659f06fc1cc0137ed977"
"e037ccc8832726feecb9e9c098fce32f"
}

View File

@@ -102,6 +102,7 @@ StateManagerGL::StateManagerGL(const FunctionsGL *functions,
mPackSkipPixels(0),
mFramebuffers(angle::FramebufferBindingSingletonMax, 0),
mRenderbuffer(0),
mPlaceholderFbo(0),
mScissorTestEnabled(false),
mScissor(0, 0, 0, 0),
mViewport(0, 0, 0, 0),
@@ -215,6 +216,10 @@ StateManagerGL::StateManagerGL(const FunctionsGL *functions,
StateManagerGL::~StateManagerGL()
{
if (mPlaceholderFbo != 0)
{
deleteFramebuffer(mPlaceholderFbo);
}
if (mDefaultVAO != 0)
{
mFunctions->deleteVertexArrays(1, &mDefaultVAO);
@@ -759,6 +764,17 @@ void StateManagerGL::beginQuery(gl::QueryType type, QueryGL *queryObject, GLuint
ASSERT(mQueries[type] == nullptr);
ASSERT(queryId != 0);
if (mFeatures.bindFramebufferForTimerQueries.enabled &&
mFramebuffers[angle::FramebufferBindingDraw] == 0 &&
(type == gl::QueryType::TimeElapsed || type == gl::QueryType::Timestamp))
{
if (!mPlaceholderFbo)
{
mFunctions->genFramebuffers(1, &mPlaceholderFbo);
}
bindFramebuffer(GL_FRAMEBUFFER, mPlaceholderFbo);
}
mQueries[type] = queryObject;
mFunctions->beginQuery(ToGLenum(type), queryId);
}

View File

@@ -454,6 +454,7 @@ class StateManagerGL final : angle::NonCopyable
// TODO(jmadill): Convert to std::array when available
std::vector<GLenum> mFramebuffers;
GLuint mRenderbuffer;
GLuint mPlaceholderFbo;
bool mScissorTestEnabled;
gl::Rectangle mScissor;

View File

@@ -136,6 +136,13 @@ bool IsAdreno5xx(const FunctionsGL *functions)
return number != 0 && number >= 500 && number < 600;
}
bool IsMali(const FunctionsGL *functions)
{
constexpr char Mali[] = "Mali";
const char *nativeGLRenderer = GetString(functions, GL_RENDERER);
return angle::BeginsWith(nativeGLRenderer, Mali);
}
bool IsMaliT8xxOrOlder(const FunctionsGL *functions)
{
int number = getMaliTNumber(functions);
@@ -2513,6 +2520,9 @@ void InitializeFeatures(const FunctionsGL *functions, angle::FeaturesGL *feature
// EXT_shader_pixel_local_storage
ANGLE_FEATURE_CONDITION(features, supportsShaderPixelLocalStorageEXT,
functions->hasGLESExtension("GL_EXT_shader_pixel_local_storage"));
// https://crbug.com/1356053
ANGLE_FEATURE_CONDITION(features, bindFramebufferForTimerQueries, IsMali(functions));
}
void InitializeFrontendFeatures(const FunctionsGL *functions, angle::FrontendFeatures *features)

View File

@@ -43,6 +43,7 @@ constexpr PackedEnumMap<Feature, const char *> kFeatureNames = {{
{Feature::AsyncCommandQueue, "asyncCommandQueue"},
{Feature::Avoid1BitAlphaTextureFormats, "avoid1BitAlphaTextureFormats"},
{Feature::AvoidStencilTextureSwizzle, "avoidStencilTextureSwizzle"},
{Feature::BindFramebufferForTimerQueries, "bindFramebufferForTimerQueries"},
{Feature::BindTransformFeedbackBufferBeforeBindBufferRange,
"bindTransformFeedbackBufferBeforeBindBufferRange"},
{Feature::BorderColorSrgb, "borderColorSrgb"},

View File

@@ -42,6 +42,7 @@ enum class Feature
AsyncCommandQueue,
Avoid1BitAlphaTextureFormats,
AvoidStencilTextureSwizzle,
BindFramebufferForTimerQueries,
BindTransformFeedbackBufferBeforeBindBufferRange,
BorderColorSrgb,
BottomLeftOriginPresentRegionRectangles,