GL: Work around Mac glBindBufferRange issue.

Mac GL drivers generat errors when binding transform feedback buffers
with glBindBufferBase/glBindBufferRange when the buffer has not been
bound to any binding point before. Work around this by simply binding
the buffer first.

Bug: angleproject:5140
Change-Id: I1895f8367412135c100a5072117c929be8a8e90b
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2461826
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
This commit is contained in:
Geoff Lang 2020-10-08 09:59:10 -04:00 коммит произвёл Commit Bot
Родитель 36f0464a50
Коммит cd8eb56468
3 изменённых файлов: 30 добавлений и 6 удалений

Просмотреть файл

@ -475,6 +475,15 @@ struct FeaturesGL : FeatureSetBase
"clamp_msc_rate", FeatureCategory::OpenGLWorkarounds,
"Some drivers return bogus values for GetMscRate, so we clamp it to 30Hz", &members,
"https://crbug.com/1042393"};
// Mac drivers generate GL_INVALID_VALUE when binding a transform feedback buffer with
// glBindBufferRange before first binding it to some generic binding point.
Feature bindTransformFeedbackBufferBeforeBindBufferRange = {
"bind_transform_feedback_buffer_before_bind_buffer_range",
FeatureCategory::OpenGLWorkarounds,
"Bind transform feedback buffers to the generic binding point before calling "
"glBindBufferBase or glBindBufferRange.",
&members, "https://anglebug.com/5140"};
};
inline FeaturesGL::FeaturesGL() = default;

Просмотреть файл

@ -75,27 +75,40 @@ angle::Result TransformFeedbackGL::bindIndexedBuffer(
size_t index,
const gl::OffsetBindingPointer<gl::Buffer> &binding)
{
const angle::FeaturesGL &features = GetFeaturesGL(context);
// Directly bind buffer (not through the StateManager methods) because the buffer bindings are
// tracked per transform feedback object
mStateManager->bindTransformFeedback(GL_TRANSFORM_FEEDBACK, mTransformFeedbackID);
if (binding.get() != nullptr)
{
const BufferGL *bufferGL = GetImplAs<BufferGL>(binding.get());
if (features.bindTransformFeedbackBufferBeforeBindBufferRange.enabled)
{
// Generic binding will be overwritten by the bindRange/bindBase below.
ANGLE_GL_TRY(context, mFunctions->bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER,
bufferGL->getBufferID()));
}
if (binding.getSize() != 0)
{
mFunctions->bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, static_cast<GLuint>(index),
bufferGL->getBufferID(), binding.getOffset(),
binding.getSize());
ANGLE_GL_TRY(context,
mFunctions->bindBufferRange(
GL_TRANSFORM_FEEDBACK_BUFFER, static_cast<GLuint>(index),
bufferGL->getBufferID(), binding.getOffset(), binding.getSize()));
}
else
{
mFunctions->bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, static_cast<GLuint>(index),
bufferGL->getBufferID());
ANGLE_GL_TRY(context, mFunctions->bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER,
static_cast<GLuint>(index),
bufferGL->getBufferID()));
}
}
else
{
mFunctions->bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, static_cast<GLuint>(index), 0);
ANGLE_GL_TRY(context, mFunctions->bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER,
static_cast<GLuint>(index), 0));
}
return angle::Result::Continue;
}

Просмотреть файл

@ -1828,6 +1828,8 @@ void InitializeFeatures(const FunctionsGL *functions, angle::FeaturesGL *feature
// causes issues in Chrome. To get around this, default to a 30Hz refresh rate if we see bogus
// from the driver.
ANGLE_FEATURE_CONDITION(features, clampMscRate, IsLinux() && IsWayland());
ANGLE_FEATURE_CONDITION(features, bindTransformFeedbackBufferBeforeBindBufferRange, IsApple());
}
void InitializeFrontendFeatures(const FunctionsGL *functions, angle::FrontendFeatures *features)