diff options
author | qiankun.miao <qiankun.miao@intel.com> | 2016-03-11 04:33:31 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-03-11 12:34:33 +0000 |
commit | 4c10b3e03cdf3028c9e66aaa4d4e9236c856cf68 (patch) | |
tree | 96678990e8a5e28c0d6660f111772a3cc4ac0bbb /gpu | |
parent | 283d18607e366095c377ddf72d196a8c4e256429 (diff) | |
download | chromium_src-4c10b3e03cdf3028c9e66aaa4d4e9236c856cf68.zip chromium_src-4c10b3e03cdf3028c9e66aaa4d4e9236c856cf68.tar.gz chromium_src-4c10b3e03cdf3028c9e66aaa4d4e9236c856cf68.tar.bz2 |
Fix transform feedback bugs
This CL fixes two bugs:
1. Deleting an active transform feedback object will generate
INVALID_OPERATION error (page 86, ES spec 3.0.4).
2. bindBufferBase bind the buffer object to both the general binding
point and the binding point in the array givien by index (page 35, ES
spec 3.0.4).
BUG=295792, 591258
TEST=deqp/functional/gles3/lifetime.html
CQ_INCLUDE_TRYBOTS=tryserver.chromium.win:win_optional_gpu_tests_rel
Review URL: https://codereview.chromium.org/1752703003
Cr-Commit-Position: refs/heads/master@{#380610}
Diffstat (limited to 'gpu')
5 files changed, 94 insertions, 29 deletions
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py index 81d796a..8381f63 100755 --- a/gpu/command_buffer/build_gles2_cmd_buffer.py +++ b/gpu/command_buffer/build_gles2_cmd_buffer.py @@ -2406,6 +2406,7 @@ _FUNCTION_INFO = { 'type': 'Bind', 'decoder_func': 'DoBindBufferBase', 'gen_func': 'GenBuffersARB', + 'unit_test': False, 'unsafe': True, }, 'BindBufferRange': { diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc index 5bad58f..4c1194c 100644 --- a/gpu/command_buffer/client/gles2_implementation.cc +++ b/gpu/command_buffer/client/gles2_implementation.cc @@ -3904,6 +3904,34 @@ void GLES2Implementation::BindBufferBaseHelper( GLenum target, GLuint index, GLuint buffer_id) { // TODO(zmo): See note #1 above. // TODO(zmo): See note #2 above. + switch (target) { + case GL_TRANSFORM_FEEDBACK_BUFFER: + if (index >= + static_cast<GLuint>( + capabilities_.max_transform_feedback_separate_attribs)) { + SetGLError(GL_INVALID_VALUE, + "glBindBufferBase", "index out of range"); + return; + } + if (bound_transform_feedback_buffer_ != buffer_id) { + bound_transform_feedback_buffer_ = buffer_id; + } + break; + case GL_UNIFORM_BUFFER: + if (index >= + static_cast<GLuint>(capabilities_.max_uniform_buffer_bindings)) { + SetGLError(GL_INVALID_VALUE, + "glBindBufferBase", "index out of range"); + return; + } + if (bound_uniform_buffer_ != buffer_id) { + bound_uniform_buffer_ = buffer_id; + } + break; + default: + SetGLError(GL_INVALID_ENUM, "glBindBufferBase", "invalid target"); + return; + } GetIdHandler(id_namespaces::kBuffers)->MarkAsUsedForBind( this, target, index, buffer_id, &GLES2Implementation::BindBufferBaseStub); } diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index 4979c1d..09b171d 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -4558,6 +4558,36 @@ void GLES2DecoderImpl::DoBindBufferBase(GLenum target, GLuint index, // TODO(kbr): track indexed bound buffers. service_id = buffer->service_id(); } + switch (target) { + case GL_TRANSFORM_FEEDBACK_BUFFER: { + GLint max_transform_feedback_separate_attribs = 0; + DoGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, + &max_transform_feedback_separate_attribs); + if (index >= + static_cast<GLuint>(max_transform_feedback_separate_attribs)) { + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, + "glBindBufferBase", "index out of range"); + return; + } + break; + } + case GL_UNIFORM_BUFFER: { + GLint max_uniform_buffer_bindings = 0; + DoGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, + &max_uniform_buffer_bindings); + if (index >= static_cast<GLuint>(max_uniform_buffer_bindings)) { + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, + "glBindBufferBase", "index out of range"); + return; + } + break; + } + default: + LOCAL_SET_GL_ERROR_INVALID_ENUM( + "glBindBufferBase", target, "invalid target"); + return; + } + state_.SetBoundBuffer(target, buffer); glBindBufferBase(target, index, service_id); } diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h index 0c6f1a6..06d220a 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h @@ -51,35 +51,6 @@ TEST_P(GLES2DecoderTest1, BindBufferInvalidArgs0_0) { EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); } -TEST_P(GLES2DecoderTest1, BindBufferBaseValidArgs) { - EXPECT_CALL( - *gl_, BindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 2, kServiceBufferId)); - SpecializedSetup<cmds::BindBufferBase, 0>(true); - cmds::BindBufferBase cmd; - cmd.Init(GL_TRANSFORM_FEEDBACK_BUFFER, 2, client_buffer_id_); - decoder_->set_unsafe_es3_apis_enabled(true); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); - decoder_->set_unsafe_es3_apis_enabled(false); - EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); -} - -TEST_P(GLES2DecoderTest1, BindBufferBaseValidArgsNewId) { - EXPECT_CALL(*gl_, - BindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 2, kNewServiceId)); - EXPECT_CALL(*gl_, GenBuffersARB(1, _)) - .WillOnce(SetArgumentPointee<1>(kNewServiceId)); - SpecializedSetup<cmds::BindBufferBase, 0>(true); - cmds::BindBufferBase cmd; - cmd.Init(GL_TRANSFORM_FEEDBACK_BUFFER, 2, kNewClientId); - decoder_->set_unsafe_es3_apis_enabled(true); - EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); - EXPECT_EQ(GL_NO_ERROR, GetGLError()); - EXPECT_TRUE(GetBuffer(kNewClientId) != NULL); - decoder_->set_unsafe_es3_apis_enabled(false); - EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); -} - TEST_P(GLES2DecoderTest1, BindBufferRangeValidArgs) { EXPECT_CALL(*gl_, BindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 2, kServiceBufferId, 4, 4)); diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_buffers.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_buffers.cc index 5af242b..b6c0162 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_buffers.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_buffers.cc @@ -21,6 +21,41 @@ namespace { } // namespace anonymous +TEST_P(GLES2DecoderTest, BindBufferBaseValidArgs) { + EXPECT_CALL( + *gl_, BindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 2, kServiceBufferId)); + EXPECT_CALL(*gl_, GetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, _)) + .WillOnce(SetArgPointee<1>(4)) + .RetiresOnSaturation(); + SpecializedSetup<cmds::BindBufferBase, 0>(true); + cmds::BindBufferBase cmd; + cmd.Init(GL_TRANSFORM_FEEDBACK_BUFFER, 2, client_buffer_id_); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} + +TEST_P(GLES2DecoderTest, BindBufferBaseValidArgsNewId) { + EXPECT_CALL(*gl_, + BindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 2, kNewServiceId)); + EXPECT_CALL(*gl_, GetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, _)) + .WillOnce(SetArgPointee<1>(4)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, GenBuffersARB(1, _)) + .WillOnce(SetArgPointee<1>(kNewServiceId)); + SpecializedSetup<cmds::BindBufferBase, 0>(true); + cmds::BindBufferBase cmd; + cmd.Init(GL_TRANSFORM_FEEDBACK_BUFFER, 2, kNewClientId); + decoder_->set_unsafe_es3_apis_enabled(true); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + EXPECT_TRUE(GetBuffer(kNewClientId) != NULL); + decoder_->set_unsafe_es3_apis_enabled(false); + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd)); +} + TEST_P(GLES2DecoderTest, MapBufferRangeUnmapBufferReadSucceeds) { const GLenum kTarget = GL_ARRAY_BUFFER; const GLintptr kOffset = 10; |