зеркало из https://github.com/AvaloniaUI/angle.git
GL: Unbind buffers after mapping them.
Qualcomm drivers generate errors if a bound array buffer is mapped during a draw call even if it is not used by the draw. Bug: chromium:1345777 Change-Id: I0639caf5d74c8cbdc7245324fdcb136bd3d51b86 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3871333 Reviewed-by: Peng Huang <penghuang@chromium.org> Commit-Queue: Geoff Lang <geofflang@chromium.org> Reviewed-by: Vasiliy Telezhnikov <vasilyt@chromium.org>
This commit is contained in:
Родитель
b9df95ffdf
Коммит
f99e255b46
|
@ -152,19 +152,26 @@ angle::Result BufferGL::map(const gl::Context *context, GLenum access, void **ma
|
|||
{
|
||||
*mapPtr = mShadowCopy.data();
|
||||
}
|
||||
else if (functions->mapBuffer)
|
||||
{
|
||||
stateManager->bindBuffer(DestBufferOperationTarget, mBufferID);
|
||||
*mapPtr = ANGLE_GL_TRY(
|
||||
context, functions->mapBuffer(gl::ToGLenum(DestBufferOperationTarget), access));
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(functions->mapBufferRange && access == GL_WRITE_ONLY_OES);
|
||||
stateManager->bindBuffer(DestBufferOperationTarget, mBufferID);
|
||||
*mapPtr =
|
||||
ANGLE_GL_TRY(context, functions->mapBufferRange(gl::ToGLenum(DestBufferOperationTarget),
|
||||
0, mBufferSize, GL_MAP_WRITE_BIT));
|
||||
if (functions->mapBuffer)
|
||||
{
|
||||
*mapPtr = ANGLE_GL_TRY(
|
||||
context, functions->mapBuffer(gl::ToGLenum(DestBufferOperationTarget), access));
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(functions->mapBufferRange && access == GL_WRITE_ONLY_OES);
|
||||
*mapPtr = ANGLE_GL_TRY(
|
||||
context, functions->mapBufferRange(gl::ToGLenum(DestBufferOperationTarget), 0,
|
||||
mBufferSize, GL_MAP_WRITE_BIT));
|
||||
}
|
||||
|
||||
// Unbind the mapped buffer from the array buffer binding. Some drivers generate errors if
|
||||
// any mapped buffer is bound to array buffer bindings.
|
||||
// crbug.com/1345777
|
||||
stateManager->bindBuffer(DestBufferOperationTarget, 0);
|
||||
}
|
||||
|
||||
mIsMapped = true;
|
||||
|
@ -197,6 +204,11 @@ angle::Result BufferGL::mapRange(const gl::Context *context,
|
|||
*mapPtr =
|
||||
ANGLE_GL_TRY(context, functions->mapBufferRange(gl::ToGLenum(DestBufferOperationTarget),
|
||||
offset, length, access));
|
||||
|
||||
// Unbind the mapped buffer from the array buffer binding. Some drivers generate errors if
|
||||
// any mapped buffer is bound to array buffer bindings.
|
||||
// crbug.com/1345777
|
||||
stateManager->bindBuffer(DestBufferOperationTarget, 0);
|
||||
}
|
||||
|
||||
mIsMapped = true;
|
||||
|
|
|
@ -979,6 +979,40 @@ TEST_P(BufferDataTest, BufferSizeValidation32Bit)
|
|||
EXPECT_GL_ERROR(GL_INVALID_VALUE);
|
||||
}
|
||||
|
||||
// Some drivers generate errors when array buffer bindings are left mapped during draw calls.
|
||||
// crbug.com/1345777
|
||||
TEST_P(BufferDataTestES3, GLDriverErrorWhenMappingArrayBuffersDuringDraw)
|
||||
{
|
||||
ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
|
||||
ASSERT_NE(program, 0u);
|
||||
|
||||
glUseProgram(program);
|
||||
|
||||
auto quadVertices = GetQuadVertices();
|
||||
|
||||
GLBuffer vb;
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vb.get());
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * quadVertices.size(), quadVertices.data(),
|
||||
GL_STATIC_DRAW);
|
||||
|
||||
GLint positionLocation = glGetAttribLocation(program, essl3_shaders::PositionAttrib());
|
||||
ASSERT_NE(-1, positionLocation);
|
||||
glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
|
||||
glEnableVertexAttribArray(positionLocation);
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
EXPECT_GL_NO_ERROR();
|
||||
|
||||
GLBuffer pb;
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pb);
|
||||
glBufferData(GL_PIXEL_UNPACK_BUFFER, 1024, nullptr, GL_STREAM_DRAW);
|
||||
glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, 1024, GL_MAP_WRITE_BIT);
|
||||
EXPECT_GL_NO_ERROR();
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
EXPECT_GL_NO_ERROR();
|
||||
}
|
||||
|
||||
// Tests a null crash bug caused by copying from null back-end buffer pointer
|
||||
// when calling bufferData again after drawing without calling bufferData in D3D11.
|
||||
TEST_P(BufferDataTestES3, DrawWithNotCallingBufferData)
|
||||
|
|
Загрузка…
Ссылка в новой задаче