Commit cd8eb564 by Geoff Lang Committed by Commit Bot

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: 's avatarJamie Madill <jmadill@chromium.org>
parent 36f0464a
...@@ -475,6 +475,15 @@ struct FeaturesGL : FeatureSetBase ...@@ -475,6 +475,15 @@ struct FeaturesGL : FeatureSetBase
"clamp_msc_rate", FeatureCategory::OpenGLWorkarounds, "clamp_msc_rate", FeatureCategory::OpenGLWorkarounds,
"Some drivers return bogus values for GetMscRate, so we clamp it to 30Hz", &members, "Some drivers return bogus values for GetMscRate, so we clamp it to 30Hz", &members,
"https://crbug.com/1042393"}; "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; inline FeaturesGL::FeaturesGL() = default;
......
...@@ -75,27 +75,40 @@ angle::Result TransformFeedbackGL::bindIndexedBuffer( ...@@ -75,27 +75,40 @@ angle::Result TransformFeedbackGL::bindIndexedBuffer(
size_t index, size_t index,
const gl::OffsetBindingPointer<gl::Buffer> &binding) 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 // Directly bind buffer (not through the StateManager methods) because the buffer bindings are
// tracked per transform feedback object // tracked per transform feedback object
mStateManager->bindTransformFeedback(GL_TRANSFORM_FEEDBACK, mTransformFeedbackID); mStateManager->bindTransformFeedback(GL_TRANSFORM_FEEDBACK, mTransformFeedbackID);
if (binding.get() != nullptr) if (binding.get() != nullptr)
{ {
const BufferGL *bufferGL = GetImplAs<BufferGL>(binding.get()); 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) if (binding.getSize() != 0)
{ {
mFunctions->bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, static_cast<GLuint>(index), ANGLE_GL_TRY(context,
bufferGL->getBufferID(), binding.getOffset(), mFunctions->bindBufferRange(
binding.getSize()); GL_TRANSFORM_FEEDBACK_BUFFER, static_cast<GLuint>(index),
bufferGL->getBufferID(), binding.getOffset(), binding.getSize()));
} }
else else
{ {
mFunctions->bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, static_cast<GLuint>(index), ANGLE_GL_TRY(context, mFunctions->bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER,
bufferGL->getBufferID()); static_cast<GLuint>(index),
bufferGL->getBufferID()));
} }
} }
else 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; return angle::Result::Continue;
} }
......
...@@ -1828,6 +1828,8 @@ void InitializeFeatures(const FunctionsGL *functions, angle::FeaturesGL *feature ...@@ -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 // causes issues in Chrome. To get around this, default to a 30Hz refresh rate if we see bogus
// from the driver. // from the driver.
ANGLE_FEATURE_CONDITION(features, clampMscRate, IsLinux() && IsWayland()); ANGLE_FEATURE_CONDITION(features, clampMscRate, IsLinux() && IsWayland());
ANGLE_FEATURE_CONDITION(features, bindTransformFeedbackBufferBeforeBindBufferRange, IsApple());
} }
void InitializeFrontendFeatures(const FunctionsGL *functions, angle::FrontendFeatures *features) void InitializeFrontendFeatures(const FunctionsGL *functions, angle::FrontendFeatures *features)
......
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