diff options
author | oetuaho@nvidia.com <oetuaho@nvidia.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-20 16:56:25 +0000 |
---|---|---|
committer | oetuaho@nvidia.com <oetuaho@nvidia.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-20 16:56:25 +0000 |
commit | d8e6c924b1bb23056f02d9c6e6363cfc43c38c7d (patch) | |
tree | fb995c004adc2bb8e20cd96f5e603f7bfd3b29d7 | |
parent | 8357da40eb30d9c734b4b8c18d4633760d94c1e5 (diff) | |
download | chromium_src-d8e6c924b1bb23056f02d9c6e6363cfc43c38c7d.zip chromium_src-d8e6c924b1bb23056f02d9c6e6363cfc43c38c7d.tar.gz chromium_src-d8e6c924b1bb23056f02d9c6e6363cfc43c38c7d.tar.bz2 |
Do not rely on a texture's internalformat matching format
After recently implemented support for rendering to 32-bit floating point
textures on ES3, texture's internal format and format do not necessarily
always match. Fix the command decoder code that relied on them matching.
BUG=329605
TEST=gpu_unittests, WebGL conformance tests
Review URL: https://codereview.chromium.org/168983005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@252268 0039d316-1c4b-4281-b951-d872f2087c98
8 files changed, 107 insertions, 36 deletions
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index 816c172..7e8cb8d 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -1065,6 +1065,7 @@ class GLES2DecoderImpl : public GLES2Decoder, unsigned bind_target, unsigned target, int level, + unsigned internal_format, unsigned format, unsigned type, int width, @@ -7672,6 +7673,7 @@ bool GLES2DecoderImpl::ClearLevel( unsigned bind_target, unsigned target, int level, + unsigned internal_format, unsigned format, unsigned type, int width, @@ -7758,7 +7760,8 @@ bool GLES2DecoderImpl::ClearLevel( glTexSubImage2D(target, level, 0, y, width, h, format, type, zero.get()); } else { glTexImage2D( - target, level, format, width, h, 0, format, type, zero.get()); + target, level, internal_format, width, h, 0, format, type, + zero.get()); } y += tile_height; } @@ -8293,8 +8296,8 @@ void GLES2DecoderImpl::DoCopyTexImage2D( // some part was clipped so clear the texture. if (!ClearLevel( texture->service_id(), texture->target(), - target, level, internal_format, GL_UNSIGNED_BYTE, width, height, - texture->IsImmutable())) { + target, level, internal_format, internal_format, GL_UNSIGNED_BYTE, + width, height, texture->IsImmutable())) { LOCAL_SET_GL_ERROR( GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too big"); return; @@ -8539,10 +8542,13 @@ error::Error GLES2DecoderImpl::DoTexSubImage2D( if (!texture_state_.texsubimage2d_faster_than_teximage2d && !texture->IsImmutable()) { ScopedTextureUploadTimer timer(&texture_state_); - // NOTE: In OpenGL ES 2.0 border is always zero and format is always the - // same as internal_foramt. If that changes we'll need to look them up. + GLenum internal_format; + GLenum tex_type; + texture->GetLevelType(target, level, &tex_type, &internal_format); + // NOTE: In OpenGL ES 2.0 border is always zero. If that changes we'll need + // to look it up. glTexImage2D( - target, level, format, width, height, 0, format, type, data); + target, level, internal_format, width, height, 0, format, type, data); } else { ScopedTextureUploadTimer timer(&texture_state_); glTexSubImage2D( diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.h b/gpu/command_buffer/service/gles2_cmd_decoder.h index 2d16a5a..409ae7b 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder.h @@ -192,6 +192,7 @@ class GPU_EXPORT GLES2Decoder : public base::SupportsWeakPtr<GLES2Decoder>, unsigned bind_target, unsigned target, int level, + unsigned internal_format, unsigned format, unsigned type, int width, diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_mock.h b/gpu/command_buffer/service/gles2_cmd_decoder_mock.h index 78e7f2a..f22ade0 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_mock.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_mock.h @@ -87,11 +87,12 @@ class MockGLES2Decoder : public GLES2Decoder { uint32* service_texture_id)); MOCK_METHOD0(GetContextLostReason, error::ContextLostReason()); MOCK_CONST_METHOD1(GetCommandName, const char*(unsigned int command_id)); - MOCK_METHOD9(ClearLevel, bool( + MOCK_METHOD10(ClearLevel, bool( unsigned service_id, unsigned bind_target, unsigned target, int level, + unsigned internal_format, unsigned format, unsigned type, int width, diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc index e7187d0..297e0c7 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc @@ -1873,9 +1873,9 @@ TEST_F(GLES2DecoderTest, GenerateMipmapClearsUnclearedTexture) { DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0); - SetupClearTextureExpections( + SetupClearTextureExpectations( kServiceTextureId, kServiceTextureId, GL_TEXTURE_2D, GL_TEXTURE_2D, - 0, GL_RGBA, GL_UNSIGNED_BYTE, 2, 2); + 0, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, 2, 2); EXPECT_CALL(*gl_, TexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST)) .Times(1) @@ -4596,9 +4596,9 @@ TEST_F(GLES2DecoderTest, TexImage2DRedefinitionSucceeds) { GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, kSharedMemoryId, kSharedMemoryOffset); } else { - SetupClearTextureExpections( + SetupClearTextureExpectations( kServiceTextureId, kServiceTextureId, GL_TEXTURE_2D, GL_TEXTURE_2D, - 0, GL_RGBA, GL_UNSIGNED_BYTE, kWidth, kHeight); + 0, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, kWidth, kHeight); cmd.Init( GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0); @@ -5914,9 +5914,9 @@ TEST_F(GLES2DecoderTest, TexSubImage2DClearsAfterTexImage2DNULL) { DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0); - SetupClearTextureExpections( + SetupClearTextureExpectations( kServiceTextureId, kServiceTextureId, GL_TEXTURE_2D, GL_TEXTURE_2D, - 0, GL_RGBA, GL_UNSIGNED_BYTE, 2, 2); + 0, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, 2, 2); EXPECT_CALL(*gl_, TexSubImage2D( GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, shared_memory_address_)) @@ -6037,9 +6037,9 @@ TEST_F(GLES2DecoderTest, TexSubImage2DClearsAfterTexImage2DWithDataThenNULL) { // It won't actually call TexImage2D, just mark it as uncleared. EXPECT_EQ(error::kNoError, ExecuteCmd(tex_cmd)); // Next call to TexSubImage2d should clear. - SetupClearTextureExpections( + SetupClearTextureExpectations( kServiceTextureId, kServiceTextureId, GL_TEXTURE_2D, GL_TEXTURE_2D, - 0, GL_RGBA, GL_UNSIGNED_BYTE, 2, 2); + 0, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, 2, 2); EXPECT_CALL(*gl_, TexSubImage2D( GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, shared_memory_address_)) @@ -6061,12 +6061,12 @@ TEST_F(GLES2DecoderWithShaderTest, DrawArraysClearsAfterTexImage2DNULL) { DoTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0); // Expect 2 levels will be cleared. - SetupClearTextureExpections( + SetupClearTextureExpectations( kServiceTextureId, kServiceTextureId, GL_TEXTURE_2D, GL_TEXTURE_2D, - 0, GL_RGBA, GL_UNSIGNED_BYTE, 2, 2); - SetupClearTextureExpections( + 0, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, 2, 2); + SetupClearTextureExpectations( kServiceTextureId, kServiceTextureId, GL_TEXTURE_2D, GL_TEXTURE_2D, - 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, 1); + 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, 1, 1); SetupExpectationsForApplyingDefaultDirtyState(); EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices)) .Times(1) @@ -6094,12 +6094,12 @@ TEST_F(GLES2DecoderWithShaderTest, DrawElementsClearsAfterTexImage2DNULL) { DoTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0); // Expect 2 levels will be cleared. - SetupClearTextureExpections( + SetupClearTextureExpectations( kServiceTextureId, kServiceTextureId, GL_TEXTURE_2D, GL_TEXTURE_2D, - 0, GL_RGBA, GL_UNSIGNED_BYTE, 2, 2); - SetupClearTextureExpections( + 0, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, 2, 2); + SetupClearTextureExpectations( kServiceTextureId, kServiceTextureId, GL_TEXTURE_2D, GL_TEXTURE_2D, - 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, 1); + 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, 1, 1); SetupExpectationsForApplyingDefaultDirtyState(); EXPECT_CALL(*gl_, DrawElements(GL_TRIANGLES, kValidIndexRangeCount, @@ -6249,9 +6249,9 @@ TEST_F(GLES2DecoderTest, CopyTexSubImage2DClearsUnclearedTexture) { DoTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0); - SetupClearTextureExpections( + SetupClearTextureExpectations( kServiceTextureId, kServiceTextureId, GL_TEXTURE_2D, GL_TEXTURE_2D, - 0, GL_RGBA, GL_UNSIGNED_BYTE, 2, 2); + 0, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, 2, 2); EXPECT_CALL(*gl_, CopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1)) .Times(1) .RetiresOnSaturation(); @@ -6529,12 +6529,14 @@ TEST_F(GLES2DecoderTest, DrawArraysClearsAfterTexImage2DNULLCubemap) { GL_UNSIGNED_BYTE, shm_id, shm_offset); } // Expect 2 levels will be cleared. - SetupClearTextureExpections( + SetupClearTextureExpectations( kServiceTextureId, kServiceTextureId, GL_TEXTURE_CUBE_MAP, - GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, GL_UNSIGNED_BYTE, 2, 2); - SetupClearTextureExpections( + GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, + 2, 2); + SetupClearTextureExpectations( kServiceTextureId, kServiceTextureId, GL_TEXTURE_CUBE_MAP, - GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, 1); + GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, + 1, 1); AddExpectationsForSimulatedAttrib0(kNumVertices, 0); SetupExpectationsForApplyingDefaultDirtyState(); EXPECT_CALL(*gl_, DrawArrays(GL_TRIANGLES, 0, kNumVertices)) @@ -8946,6 +8948,65 @@ TEST_F(GLES2DecoderManualInitTest, TexImage2DFloatOnGLES3) { GL_LUMINANCE_ALPHA, GL_FLOAT, 0, 0); } +TEST_F(GLES2DecoderManualInitTest, TexSubImage2DFloatOnGLES3) { + InitDecoder("GL_OES_texture_float GL_EXT_color_buffer_float", // extensions + "opengl es 3.0", // gl version + false, // has alpha + false, // has depth + false, // has stencil + false, // request alpha + false, // request depth + false, // request stencil + false); // bind generates resource + const int kWidth = 8; + const int kHeight = 4; + DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); + DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, kWidth, kHeight, 0, GL_RGBA, + GL_FLOAT, 0, 0); + EXPECT_CALL(*gl_, TexImage2D( + GL_TEXTURE_2D, 0, GL_RGBA32F, kWidth, kHeight, 0, GL_RGBA, GL_FLOAT, + shared_memory_address_)) + .Times(1) + .RetiresOnSaturation(); + TexSubImage2D cmd; + cmd.Init( + GL_TEXTURE_2D, 0, 0, 0, kWidth, kHeight, GL_RGBA, GL_FLOAT, + kSharedMemoryId, kSharedMemoryOffset, GL_FALSE); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_F(GLES2DecoderManualInitTest, TexSubImage2DFloatDoesClearOnGLES3) { + InitDecoder("GL_OES_texture_float GL_EXT_color_buffer_float", // extensions + "opengl es 3.0", // gl version + false, // has alpha + false, // has depth + false, // has stencil + false, // request alpha + false, // request depth + false, // request stencil + false); // bind generates resource + const int kWidth = 8; + const int kHeight = 4; + DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); + DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, kWidth, kHeight, 0, GL_RGBA, + GL_FLOAT, 0, 0); + SetupClearTextureExpectations( + kServiceTextureId, kServiceTextureId, GL_TEXTURE_2D, GL_TEXTURE_2D, + 0, GL_RGBA32F, GL_RGBA, GL_FLOAT, kWidth, kHeight); + EXPECT_CALL(*gl_, TexSubImage2D( + GL_TEXTURE_2D, 0, 1, 0, kWidth - 1, kHeight, GL_RGBA, GL_FLOAT, + shared_memory_address_)) + .Times(1) + .RetiresOnSaturation(); + TexSubImage2D cmd; + cmd.Init( + GL_TEXTURE_2D, 0, 1, 0, kWidth - 1, kHeight, GL_RGBA, GL_FLOAT, + kSharedMemoryId, kSharedMemoryOffset, GL_FALSE); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + TEST_F(GLES2DecoderManualInitTest, TexImage2DFloatConvertsFormatDesktop) { InitDecoder("GL_ARB_texture_float", // extensions "2.1", // gl version diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc index 0b35b39..d2e1da5 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc @@ -442,12 +442,13 @@ void GLES2DecoderTestBase::SetBucketAsCString( } } -void GLES2DecoderTestBase::SetupClearTextureExpections( +void GLES2DecoderTestBase::SetupClearTextureExpectations( GLuint service_id, GLuint old_service_id, GLenum bind_target, GLenum target, GLint level, + GLenum internal_format, GLenum format, GLenum type, GLsizei width, @@ -456,7 +457,7 @@ void GLES2DecoderTestBase::SetupClearTextureExpections( .Times(1) .RetiresOnSaturation(); EXPECT_CALL(*gl_, TexImage2D( - target, level, format, width, height, 0, format, type, _)) + target, level, internal_format, width, height, 0, format, type, _)) .Times(1) .RetiresOnSaturation(); EXPECT_CALL(*gl_, BindTexture(bind_target, old_service_id)) diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h index 62ca07c..f8aea41 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h @@ -284,12 +284,13 @@ class GLES2DecoderTestBase : public testing::Test { void DeleteIndexBuffer(); - void SetupClearTextureExpections( + void SetupClearTextureExpectations( GLuint service_id, GLuint old_service_id, GLenum bind_target, GLenum target, GLint level, + GLenum internal_format, GLenum format, GLenum type, GLsizei width, diff --git a/gpu/command_buffer/service/texture_manager.cc b/gpu/command_buffer/service/texture_manager.cc index a0a60c1..38516e7 100644 --- a/gpu/command_buffer/service/texture_manager.cc +++ b/gpu/command_buffer/service/texture_manager.cc @@ -780,8 +780,8 @@ bool Texture::ClearLevel( // but only the decoder knows all the state (like unpack_alignment_) that's // needed to be able to call GL correctly. bool cleared = decoder->ClearLevel( - service_id_, target_, info.target, info.level, info.format, info.type, - info.width, info.height, immutable_); + service_id_, target_, info.target, info.level, info.internal_format, + info.format, info.type, info.width, info.height, immutable_); UpdateMipCleared(&info, cleared); return info.cleared; } diff --git a/gpu/command_buffer/service/texture_manager_unittest.cc b/gpu/command_buffer/service/texture_manager_unittest.cc index ada24a8..168a4fd 100644 --- a/gpu/command_buffer/service/texture_manager_unittest.cc +++ b/gpu/command_buffer/service/texture_manager_unittest.cc @@ -1425,7 +1425,7 @@ TEST_F(TextureTest, SafeUnsafe) { } TEST_F(TextureTest, ClearTexture) { - EXPECT_CALL(*decoder_, ClearLevel(_, _, _, _, _, _, _, _, _)) + EXPECT_CALL(*decoder_, ClearLevel(_, _, _, _, _, _, _, _, _, _)) .WillRepeatedly(Return(true)); manager_->SetTarget(texture_ref_.get(), GL_TEXTURE_2D); manager_->SetLevelInfo(texture_ref_.get(), @@ -1992,7 +1992,7 @@ TEST_F(ProduceConsumeTextureTest, ProduceConsumeClearRectangle) { // See if we can clear the previously uncleared level now. EXPECT_EQ(level0, GetLevelInfo(restored_texture.get(), GL_TEXTURE_RECTANGLE_ARB, 0)); - EXPECT_CALL(*decoder_, ClearLevel(_, _, _, _, _, _, _, _, _)) + EXPECT_CALL(*decoder_, ClearLevel(_, _, _, _, _, _, _, _, _, _)) .WillRepeatedly(Return(true)); EXPECT_TRUE(manager_->ClearTextureLevel( decoder_.get(), restored_texture.get(), GL_TEXTURE_RECTANGLE_ARB, 0)); |