diff options
author | bsalomon@google.com <bsalomon@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-07-12 14:13:16 +0000 |
---|---|---|
committer | bsalomon@google.com <bsalomon@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-07-12 14:13:16 +0000 |
commit | 7d3c36e12d2aaee9c18372de2bc2d800a575e12e (patch) | |
tree | dc0fd7fbb6c9a23293d9a3bffb78df89534a7712 /gpu | |
parent | 96af629d79595bdf32a3047aa012a5b0dd627c56 (diff) | |
download | chromium_src-7d3c36e12d2aaee9c18372de2bc2d800a575e12e.zip chromium_src-7d3c36e12d2aaee9c18372de2bc2d800a575e12e.tar.gz chromium_src-7d3c36e12d2aaee9c18372de2bc2d800a575e12e.tar.bz2 |
Add GL_EXT_multisampled_render_to_texture support to command buffer.
BUG=257113
R=apatrick@chromium.org, piman@chromium.org
Review URL: https://codereview.chromium.org/18492005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@211393 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu')
30 files changed, 463 insertions, 100 deletions
diff --git a/gpu/GLES2/gl2chromium_autogen.h b/gpu/GLES2/gl2chromium_autogen.h index 137eee3..e2e1c1f 100644 --- a/gpu/GLES2/gl2chromium_autogen.h +++ b/gpu/GLES2/gl2chromium_autogen.h @@ -159,6 +159,8 @@ #define glBlitFramebufferEXT GLES2_GET_FUN(BlitFramebufferEXT) #define glRenderbufferStorageMultisampleEXT GLES2_GET_FUN( \ RenderbufferStorageMultisampleEXT) +#define glFramebufferTexture2DMultisampleEXT GLES2_GET_FUN( \ + FramebufferTexture2DMultisampleEXT) #define glTexStorage2DEXT GLES2_GET_FUN(TexStorage2DEXT) #define glGenQueriesEXT GLES2_GET_FUN(GenQueriesEXT) #define glDeleteQueriesEXT GLES2_GET_FUN(DeleteQueriesEXT) diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py index d3fa65a..e7c3e30 100755 --- a/gpu/command_buffer/build_gles2_cmd_buffer.py +++ b/gpu/command_buffer/build_gles2_cmd_buffer.py @@ -1534,6 +1534,13 @@ _FUNCTION_INFO = { 'decoder_func': 'DoFramebufferTexture2D', 'gl_test_func': 'glFramebufferTexture2DEXT', }, + 'FramebufferTexture2DMultisampleEXT': { + 'decoder_func': 'DoFramebufferTexture2DMultisample', + 'gl_test_func': 'glFramebufferTexture2DMultisampleEXT', + 'expectation': False, + 'unit_test': False, + 'extension': True, + }, 'GenerateMipmap': { 'decoder_func': 'DoGenerateMipmap', 'gl_test_func': 'glGenerateMipmapEXT', diff --git a/gpu/command_buffer/client/gles2_c_lib_autogen.h b/gpu/command_buffer/client/gles2_c_lib_autogen.h index 0230673c..afbf489 100644 --- a/gpu/command_buffer/client/gles2_c_lib_autogen.h +++ b/gpu/command_buffer/client/gles2_c_lib_autogen.h @@ -521,6 +521,12 @@ void GLES2RenderbufferStorageMultisampleEXT( gles2::GetGLContext()->RenderbufferStorageMultisampleEXT( target, samples, internalformat, width, height); } +void GLES2FramebufferTexture2DMultisampleEXT( + GLenum target, GLenum attachment, GLenum textarget, GLuint texture, + GLint level, GLsizei samples) { + gles2::GetGLContext()->FramebufferTexture2DMultisampleEXT( + target, attachment, textarget, texture, level, samples); +} void GLES2TexStorage2DEXT( GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height) { @@ -986,6 +992,7 @@ NameToFunc g_gles2_function_table[] = { { "glBlitFramebufferEXT", reinterpret_cast<GLES2FunctionPointer>( glBlitFramebufferEXT), }, { "glRenderbufferStorageMultisampleEXT", reinterpret_cast<GLES2FunctionPointer>(glRenderbufferStorageMultisampleEXT), }, // NOLINT + { "glFramebufferTexture2DMultisampleEXT", reinterpret_cast<GLES2FunctionPointer>(glFramebufferTexture2DMultisampleEXT), }, // NOLINT { "glTexStorage2DEXT", reinterpret_cast<GLES2FunctionPointer>( glTexStorage2DEXT), }, { "glGenQueriesEXT", reinterpret_cast<GLES2FunctionPointer>( diff --git a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h index a290365..742c97e 100644 --- a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h +++ b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h @@ -1577,6 +1577,16 @@ } } + void FramebufferTexture2DMultisampleEXT( + GLenum target, GLenum attachment, GLenum textarget, GLuint texture, + GLint level, GLsizei samples) { + gles2::cmds::FramebufferTexture2DMultisampleEXT* c = + GetCmdSpace<gles2::cmds::FramebufferTexture2DMultisampleEXT>(); + if (c) { + c->Init(target, attachment, textarget, texture, level, samples); + } + } + void TexStorage2DEXT( GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height) { diff --git a/gpu/command_buffer/client/gles2_implementation_autogen.h b/gpu/command_buffer/client/gles2_implementation_autogen.h index e05768c..c4ed499 100644 --- a/gpu/command_buffer/client/gles2_implementation_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_autogen.h @@ -385,6 +385,10 @@ virtual void RenderbufferStorageMultisampleEXT( GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) OVERRIDE; +virtual void FramebufferTexture2DMultisampleEXT( + GLenum target, GLenum attachment, GLenum textarget, GLuint texture, + GLint level, GLsizei samples) OVERRIDE; + virtual void TexStorage2DEXT( GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height) OVERRIDE; diff --git a/gpu/command_buffer/client/gles2_implementation_impl_autogen.h b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h index 743f5e9..82e0ce0 100644 --- a/gpu/command_buffer/client/gles2_implementation_impl_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h @@ -1445,6 +1445,21 @@ void GLES2Implementation::RenderbufferStorageMultisampleEXT( CheckGLError(); } +void GLES2Implementation::FramebufferTexture2DMultisampleEXT( + GLenum target, GLenum attachment, GLenum textarget, GLuint texture, + GLint level, GLsizei samples) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glFramebufferTexture2DMultisampleEXT(" << GLES2Util::GetStringFrameBufferTarget(target) << ", " << GLES2Util::GetStringAttachment(attachment) << ", " << GLES2Util::GetStringTextureTarget(textarget) << ", " << texture << ", " << level << ", " << samples << ")"); // NOLINT + if (samples < 0) { + SetGLError( + GL_INVALID_VALUE, "glFramebufferTexture2DMultisampleEXT", "samples < 0"); // NOLINT + return; + } + helper_->FramebufferTexture2DMultisampleEXT( + target, attachment, textarget, texture, level, samples); + CheckGLError(); +} + void GLES2Implementation::TexStorage2DEXT( GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height) { diff --git a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h index a93f8eb..24d03dc 100644 --- a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h @@ -1529,6 +1529,19 @@ TEST_F(GLES2ImplementationTest, RenderbufferStorageMultisampleEXT) { EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } +TEST_F(GLES2ImplementationTest, FramebufferTexture2DMultisampleEXT) { + struct Cmds { + cmds::FramebufferTexture2DMultisampleEXT cmd; + }; + Cmds expected; + expected.cmd.Init( + GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 4, 0, 6); + + gl_->FramebufferTexture2DMultisampleEXT( + GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 4, 0, 6); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + TEST_F(GLES2ImplementationTest, TexStorage2DEXT) { struct Cmds { cmds::TexStorage2DEXT cmd; diff --git a/gpu/command_buffer/client/gles2_interface_autogen.h b/gpu/command_buffer/client/gles2_interface_autogen.h index 78c5002..24ce83b 100644 --- a/gpu/command_buffer/client/gles2_interface_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_autogen.h @@ -223,6 +223,9 @@ virtual void BlitFramebufferEXT( virtual void RenderbufferStorageMultisampleEXT( GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) = 0; +virtual void FramebufferTexture2DMultisampleEXT( + GLenum target, GLenum attachment, GLenum textarget, GLuint texture, + GLint level, GLsizei samples) = 0; virtual void TexStorage2DEXT( GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height) = 0; diff --git a/gpu/command_buffer/client/gles2_interface_stub_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_autogen.h index 84704ed..7650cd6 100644 --- a/gpu/command_buffer/client/gles2_interface_stub_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_stub_autogen.h @@ -248,6 +248,9 @@ virtual void BlitFramebufferEXT( virtual void RenderbufferStorageMultisampleEXT( GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) OVERRIDE; +virtual void FramebufferTexture2DMultisampleEXT( + GLenum target, GLenum attachment, GLenum textarget, GLuint texture, + GLint level, GLsizei samples) OVERRIDE; virtual void TexStorage2DEXT( GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height) OVERRIDE; diff --git a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h index b03ef8a..6778fcf 100644 --- a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h @@ -459,6 +459,10 @@ void GLES2InterfaceStub::RenderbufferStorageMultisampleEXT( GLenum /* target */, GLsizei /* samples */, GLenum /* internalformat */, GLsizei /* width */, GLsizei /* height */) { } +void GLES2InterfaceStub::FramebufferTexture2DMultisampleEXT( + GLenum /* target */, GLenum /* attachment */, GLenum /* textarget */, + GLuint /* texture */, GLint /* level */, GLsizei /* samples */) { +} void GLES2InterfaceStub::TexStorage2DEXT( GLenum /* target */, GLsizei /* levels */, GLenum /* internalFormat */, GLsizei /* width */, GLsizei /* height */) { diff --git a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h index 414ddf5..4f3ce31 100644 --- a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h +++ b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h @@ -248,6 +248,9 @@ virtual void BlitFramebufferEXT( virtual void RenderbufferStorageMultisampleEXT( GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) OVERRIDE; +virtual void FramebufferTexture2DMultisampleEXT( + GLenum target, GLenum attachment, GLenum textarget, GLuint texture, + GLint level, GLsizei samples) OVERRIDE; virtual void TexStorage2DEXT( GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height) OVERRIDE; diff --git a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h index 512b02c..1a2604a 100644 --- a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h +++ b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h @@ -854,6 +854,14 @@ void GLES2TraceImplementation::RenderbufferStorageMultisampleEXT( target, samples, internalformat, width, height); } +void GLES2TraceImplementation::FramebufferTexture2DMultisampleEXT( + GLenum target, GLenum attachment, GLenum textarget, GLuint texture, + GLint level, GLsizei samples) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::FramebufferTexture2DMultisampleEXT"); // NOLINT + gl_->FramebufferTexture2DMultisampleEXT( + target, attachment, textarget, texture, level, samples); +} + void GLES2TraceImplementation::TexStorage2DEXT( GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height) { diff --git a/gpu/command_buffer/cmd_buffer_functions.txt b/gpu/command_buffer/cmd_buffer_functions.txt index c414371..f7b9a5b 100644 --- a/gpu/command_buffer/cmd_buffer_functions.txt +++ b/gpu/command_buffer/cmd_buffer_functions.txt @@ -150,6 +150,7 @@ GL_APICALL void GL_APIENTRY glVertexAttribPointer (GLuint indx, GLintVer GL_APICALL void GL_APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height); GL_APICALL void GL_APIENTRY glBlitFramebufferEXT (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenumBlitFilter filter); GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleEXT (GLenumRenderBufferTarget target, GLsizei samples, GLenumRenderBufferFormat internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glFramebufferTexture2DMultisampleEXT (GLenumFrameBufferTarget target, GLenumAttachment attachment, GLenumTextureTarget textarget, GLidTexture texture, GLintZeroOnly level, GLsizei samples); GL_APICALL void GL_APIENTRY glTexStorage2DEXT (GLenumTextureTarget target, GLsizei levels, GLenumTextureInternalFormatStorage internalFormat, GLsizei width, GLsizei height); GL_APICALL void GL_APIENTRY glGenQueriesEXT (GLsizeiNotNegative n, GLuint* queries); GL_APICALL void GL_APIENTRY glDeleteQueriesEXT (GLsizeiNotNegative n, const GLuint* queries); diff --git a/gpu/command_buffer/common/gles2_cmd_format_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_autogen.h index 12fc743..c84a363 100644 --- a/gpu/command_buffer/common/gles2_cmd_format_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_format_autogen.h @@ -8468,6 +8468,66 @@ COMPILE_ASSERT(offsetof(RenderbufferStorageMultisampleEXT, width) == 16, COMPILE_ASSERT(offsetof(RenderbufferStorageMultisampleEXT, height) == 20, OffsetOf_RenderbufferStorageMultisampleEXT_height_not_20); +struct FramebufferTexture2DMultisampleEXT { + typedef FramebufferTexture2DMultisampleEXT ValueType; + static const CommandId kCmdId = kFramebufferTexture2DMultisampleEXT; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLenum _target, GLenum _attachment, GLenum _textarget, GLuint _texture, + GLint _level, GLsizei _samples) { + SetHeader(); + target = _target; + attachment = _attachment; + textarget = _textarget; + texture = _texture; + level = _level; + samples = _samples; + } + + void* Set( + void* cmd, GLenum _target, GLenum _attachment, GLenum _textarget, + GLuint _texture, GLint _level, GLsizei _samples) { + static_cast<ValueType*>( + cmd)->Init( + _target, _attachment, _textarget, _texture, _level, _samples); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32 target; + uint32 attachment; + uint32 textarget; + uint32 texture; + int32 level; + int32 samples; +}; + +COMPILE_ASSERT(sizeof(FramebufferTexture2DMultisampleEXT) == 28, + Sizeof_FramebufferTexture2DMultisampleEXT_is_not_28); +COMPILE_ASSERT(offsetof(FramebufferTexture2DMultisampleEXT, header) == 0, + OffsetOf_FramebufferTexture2DMultisampleEXT_header_not_0); +COMPILE_ASSERT(offsetof(FramebufferTexture2DMultisampleEXT, target) == 4, + OffsetOf_FramebufferTexture2DMultisampleEXT_target_not_4); +COMPILE_ASSERT(offsetof(FramebufferTexture2DMultisampleEXT, attachment) == 8, + OffsetOf_FramebufferTexture2DMultisampleEXT_attachment_not_8); +COMPILE_ASSERT(offsetof(FramebufferTexture2DMultisampleEXT, textarget) == 12, + OffsetOf_FramebufferTexture2DMultisampleEXT_textarget_not_12); +COMPILE_ASSERT(offsetof(FramebufferTexture2DMultisampleEXT, texture) == 16, + OffsetOf_FramebufferTexture2DMultisampleEXT_texture_not_16); +COMPILE_ASSERT(offsetof(FramebufferTexture2DMultisampleEXT, level) == 20, + OffsetOf_FramebufferTexture2DMultisampleEXT_level_not_20); +COMPILE_ASSERT(offsetof(FramebufferTexture2DMultisampleEXT, samples) == 24, + OffsetOf_FramebufferTexture2DMultisampleEXT_samples_not_24); + struct TexStorage2DEXT { typedef TexStorage2DEXT ValueType; static const CommandId kCmdId = kTexStorage2DEXT; diff --git a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h index b23b569..87e426f 100644 --- a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h @@ -3324,6 +3324,31 @@ TEST_F(GLES2FormatTest, RenderbufferStorageMultisampleEXT) { next_cmd, sizeof(cmd)); } +TEST_F(GLES2FormatTest, FramebufferTexture2DMultisampleEXT) { + cmds::FramebufferTexture2DMultisampleEXT& cmd = + *GetBufferAs<cmds::FramebufferTexture2DMultisampleEXT>(); + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11), + static_cast<GLenum>(12), + static_cast<GLenum>(13), + static_cast<GLuint>(14), + static_cast<GLint>(15), + static_cast<GLsizei>(16)); + EXPECT_EQ( + static_cast<uint32>(cmds::FramebufferTexture2DMultisampleEXT::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLenum>(11), cmd.target); + EXPECT_EQ(static_cast<GLenum>(12), cmd.attachment); + EXPECT_EQ(static_cast<GLenum>(13), cmd.textarget); + EXPECT_EQ(static_cast<GLuint>(14), cmd.texture); + EXPECT_EQ(static_cast<GLint>(15), cmd.level); + EXPECT_EQ(static_cast<GLsizei>(16), cmd.samples); + CheckBytesWrittenMatchesExpectedSize( + next_cmd, sizeof(cmd)); +} + TEST_F(GLES2FormatTest, TexStorage2DEXT) { cmds::TexStorage2DEXT& cmd = *GetBufferAs<cmds::TexStorage2DEXT>(); void* next_cmd = cmd.Set( diff --git a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h index e998be6..6fd0709 100644 --- a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h @@ -195,64 +195,65 @@ OP(Viewport) /* 438 */ \ OP(BlitFramebufferEXT) /* 439 */ \ OP(RenderbufferStorageMultisampleEXT) /* 440 */ \ - OP(TexStorage2DEXT) /* 441 */ \ - OP(GenQueriesEXT) /* 442 */ \ - OP(GenQueriesEXTImmediate) /* 443 */ \ - OP(DeleteQueriesEXT) /* 444 */ \ - OP(DeleteQueriesEXTImmediate) /* 445 */ \ - OP(BeginQueryEXT) /* 446 */ \ - OP(EndQueryEXT) /* 447 */ \ - OP(InsertEventMarkerEXT) /* 448 */ \ - OP(PushGroupMarkerEXT) /* 449 */ \ - OP(PopGroupMarkerEXT) /* 450 */ \ - OP(GenVertexArraysOES) /* 451 */ \ - OP(GenVertexArraysOESImmediate) /* 452 */ \ - OP(DeleteVertexArraysOES) /* 453 */ \ - OP(DeleteVertexArraysOESImmediate) /* 454 */ \ - OP(IsVertexArrayOES) /* 455 */ \ - OP(BindVertexArrayOES) /* 456 */ \ - OP(SwapBuffers) /* 457 */ \ - OP(GetMaxValueInBufferCHROMIUM) /* 458 */ \ - OP(GenSharedIdsCHROMIUM) /* 459 */ \ - OP(DeleteSharedIdsCHROMIUM) /* 460 */ \ - OP(RegisterSharedIdsCHROMIUM) /* 461 */ \ - OP(EnableFeatureCHROMIUM) /* 462 */ \ - OP(ResizeCHROMIUM) /* 463 */ \ - OP(GetRequestableExtensionsCHROMIUM) /* 464 */ \ - OP(RequestExtensionCHROMIUM) /* 465 */ \ - OP(GetMultipleIntegervCHROMIUM) /* 466 */ \ - OP(GetProgramInfoCHROMIUM) /* 467 */ \ - OP(CreateStreamTextureCHROMIUM) /* 468 */ \ - OP(DestroyStreamTextureCHROMIUM) /* 469 */ \ - OP(GetTranslatedShaderSourceANGLE) /* 470 */ \ - OP(PostSubBufferCHROMIUM) /* 471 */ \ - OP(TexImageIOSurface2DCHROMIUM) /* 472 */ \ - OP(CopyTextureCHROMIUM) /* 473 */ \ - OP(DrawArraysInstancedANGLE) /* 474 */ \ - OP(DrawElementsInstancedANGLE) /* 475 */ \ - OP(VertexAttribDivisorANGLE) /* 476 */ \ - OP(GenMailboxCHROMIUM) /* 477 */ \ - OP(ProduceTextureCHROMIUM) /* 478 */ \ - OP(ProduceTextureCHROMIUMImmediate) /* 479 */ \ - OP(ConsumeTextureCHROMIUM) /* 480 */ \ - OP(ConsumeTextureCHROMIUMImmediate) /* 481 */ \ - OP(BindUniformLocationCHROMIUM) /* 482 */ \ - OP(BindUniformLocationCHROMIUMImmediate) /* 483 */ \ - OP(BindUniformLocationCHROMIUMBucket) /* 484 */ \ - OP(BindTexImage2DCHROMIUM) /* 485 */ \ - OP(ReleaseTexImage2DCHROMIUM) /* 486 */ \ - OP(TraceBeginCHROMIUM) /* 487 */ \ - OP(TraceEndCHROMIUM) /* 488 */ \ - OP(AsyncTexSubImage2DCHROMIUM) /* 489 */ \ - OP(AsyncTexImage2DCHROMIUM) /* 490 */ \ - OP(WaitAsyncTexImage2DCHROMIUM) /* 491 */ \ - OP(DiscardFramebufferEXT) /* 492 */ \ - OP(DiscardFramebufferEXTImmediate) /* 493 */ \ - OP(LoseContextCHROMIUM) /* 494 */ \ - OP(InsertSyncPointCHROMIUM) /* 495 */ \ - OP(WaitSyncPointCHROMIUM) /* 496 */ \ - OP(DrawBuffersEXT) /* 497 */ \ - OP(DrawBuffersEXTImmediate) /* 498 */ \ + OP(FramebufferTexture2DMultisampleEXT) /* 441 */ \ + OP(TexStorage2DEXT) /* 442 */ \ + OP(GenQueriesEXT) /* 443 */ \ + OP(GenQueriesEXTImmediate) /* 444 */ \ + OP(DeleteQueriesEXT) /* 445 */ \ + OP(DeleteQueriesEXTImmediate) /* 446 */ \ + OP(BeginQueryEXT) /* 447 */ \ + OP(EndQueryEXT) /* 448 */ \ + OP(InsertEventMarkerEXT) /* 449 */ \ + OP(PushGroupMarkerEXT) /* 450 */ \ + OP(PopGroupMarkerEXT) /* 451 */ \ + OP(GenVertexArraysOES) /* 452 */ \ + OP(GenVertexArraysOESImmediate) /* 453 */ \ + OP(DeleteVertexArraysOES) /* 454 */ \ + OP(DeleteVertexArraysOESImmediate) /* 455 */ \ + OP(IsVertexArrayOES) /* 456 */ \ + OP(BindVertexArrayOES) /* 457 */ \ + OP(SwapBuffers) /* 458 */ \ + OP(GetMaxValueInBufferCHROMIUM) /* 459 */ \ + OP(GenSharedIdsCHROMIUM) /* 460 */ \ + OP(DeleteSharedIdsCHROMIUM) /* 461 */ \ + OP(RegisterSharedIdsCHROMIUM) /* 462 */ \ + OP(EnableFeatureCHROMIUM) /* 463 */ \ + OP(ResizeCHROMIUM) /* 464 */ \ + OP(GetRequestableExtensionsCHROMIUM) /* 465 */ \ + OP(RequestExtensionCHROMIUM) /* 466 */ \ + OP(GetMultipleIntegervCHROMIUM) /* 467 */ \ + OP(GetProgramInfoCHROMIUM) /* 468 */ \ + OP(CreateStreamTextureCHROMIUM) /* 469 */ \ + OP(DestroyStreamTextureCHROMIUM) /* 470 */ \ + OP(GetTranslatedShaderSourceANGLE) /* 471 */ \ + OP(PostSubBufferCHROMIUM) /* 472 */ \ + OP(TexImageIOSurface2DCHROMIUM) /* 473 */ \ + OP(CopyTextureCHROMIUM) /* 474 */ \ + OP(DrawArraysInstancedANGLE) /* 475 */ \ + OP(DrawElementsInstancedANGLE) /* 476 */ \ + OP(VertexAttribDivisorANGLE) /* 477 */ \ + OP(GenMailboxCHROMIUM) /* 478 */ \ + OP(ProduceTextureCHROMIUM) /* 479 */ \ + OP(ProduceTextureCHROMIUMImmediate) /* 480 */ \ + OP(ConsumeTextureCHROMIUM) /* 481 */ \ + OP(ConsumeTextureCHROMIUMImmediate) /* 482 */ \ + OP(BindUniformLocationCHROMIUM) /* 483 */ \ + OP(BindUniformLocationCHROMIUMImmediate) /* 484 */ \ + OP(BindUniformLocationCHROMIUMBucket) /* 485 */ \ + OP(BindTexImage2DCHROMIUM) /* 486 */ \ + OP(ReleaseTexImage2DCHROMIUM) /* 487 */ \ + OP(TraceBeginCHROMIUM) /* 488 */ \ + OP(TraceEndCHROMIUM) /* 489 */ \ + OP(AsyncTexSubImage2DCHROMIUM) /* 490 */ \ + OP(AsyncTexImage2DCHROMIUM) /* 491 */ \ + OP(WaitAsyncTexImage2DCHROMIUM) /* 492 */ \ + OP(DiscardFramebufferEXT) /* 493 */ \ + OP(DiscardFramebufferEXTImmediate) /* 494 */ \ + OP(LoseContextCHROMIUM) /* 495 */ \ + OP(InsertSyncPointCHROMIUM) /* 496 */ \ + OP(WaitSyncPointCHROMIUM) /* 497 */ \ + OP(DrawBuffersEXT) /* 498 */ \ + OP(DrawBuffersEXTImmediate) /* 499 */ \ enum CommandId { kStartPoint = cmd::kLastCommonId, // All GLES2 commands start after this. diff --git a/gpu/command_buffer/common/gles2_cmd_utils.cc b/gpu/command_buffer/common/gles2_cmd_utils.cc index ef0f3ea..25eafcd 100644 --- a/gpu/command_buffer/common/gles2_cmd_utils.cc +++ b/gpu/command_buffer/common/gles2_cmd_utils.cc @@ -228,8 +228,12 @@ int GLES2Util::GLGetNumValuesReturned(int id) const { return 1; case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: return 1; + // -- glGetFramebufferAttachmentParameteriv with + // GL_EXT_multisampled_render_to_texture + case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT: + return 1; - // -- glGetFramebufferAttachmentParameteriv + // -- glGetProgramiv case GL_DELETE_STATUS: return 1; case GL_LINK_STATUS: @@ -269,6 +273,10 @@ int GLES2Util::GLGetNumValuesReturned(int id) const { return 1; case GL_RENDERBUFFER_STENCIL_SIZE: return 1; + // -- glGetRenderbufferAttachmentParameteriv with + // GL_EXT_multisampled_render_to_texture + case GL_RENDERBUFFER_SAMPLES_EXT: + return 1; // -- glGetShaderiv case GL_SHADER_TYPE: diff --git a/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h b/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h index 36975dd..f043d68 100644 --- a/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h @@ -86,6 +86,7 @@ static GLES2Util::EnumToString enum_to_string_table[] = { { 0x2601, "GL_LINEAR", }, { 0x8C03, "GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG", }, { 0x9242, "GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM", }, + { 0x88BA, "GL_READ_WRITE", }, { 0x88BB, "GL_BUFFER_ACCESS_OES", }, { 0x88BC, "GL_BUFFER_MAPPED_OES", }, { 0x88BD, "GL_BUFFER_MAP_POINTER_OES", }, diff --git a/gpu/command_buffer/service/context_group.cc b/gpu/command_buffer/service/context_group.cc index bbacc71..90932fb 100644 --- a/gpu/command_buffer/service/context_group.cc +++ b/gpu/command_buffer/service/context_group.cc @@ -101,8 +101,14 @@ bool ContextGroup::Initialize( return false; } GLint max_samples = 0; - if (feature_info_->feature_flags().chromium_framebuffer_multisample) { - glGetIntegerv(GL_MAX_SAMPLES, &max_samples); + if (feature_info_->feature_flags().chromium_framebuffer_multisample || + feature_info_->feature_flags().multisampled_render_to_texture) { + if (feature_info_->feature_flags( + ).use_img_for_multisampled_render_to_texture) { + glGetIntegerv(GL_MAX_SAMPLES_IMG, &max_samples); + } else { + glGetIntegerv(GL_MAX_SAMPLES, &max_samples); + } } if (feature_info_->feature_flags().ext_draw_buffers) { diff --git a/gpu/command_buffer/service/feature_info.cc b/gpu/command_buffer/service/feature_info.cc index 5d95848..f759bef 100644 --- a/gpu/command_buffer/service/feature_info.cc +++ b/gpu/command_buffer/service/feature_info.cc @@ -100,6 +100,8 @@ void StringToWorkarounds( FeatureInfo::FeatureFlags::FeatureFlags() : chromium_framebuffer_multisample(false), + multisampled_render_to_texture(false), + use_img_for_multisampled_render_to_texture(false), oes_standard_derivatives(false), oes_egl_image_external(false), npot_ok(false), @@ -452,20 +454,37 @@ void FeatureInfo::AddFeatures(const CommandLine& command_line) { } // Check for multisample support - bool ext_has_multisample = - extensions.Contains("GL_EXT_framebuffer_multisample"); - if (!workarounds_.disable_angle_framebuffer_multisample) { - ext_has_multisample |= - extensions.Contains("GL_ANGLE_framebuffer_multisample"); - } - if (!disallowed_features_.multisampling && ext_has_multisample) { - feature_flags_.chromium_framebuffer_multisample = true; - validators_.frame_buffer_target.AddValue(GL_READ_FRAMEBUFFER_EXT); - validators_.frame_buffer_target.AddValue(GL_DRAW_FRAMEBUFFER_EXT); - validators_.g_l_state.AddValue(GL_READ_FRAMEBUFFER_BINDING_EXT); - validators_.g_l_state.AddValue(GL_MAX_SAMPLES_EXT); - validators_.render_buffer_parameter.AddValue(GL_RENDERBUFFER_SAMPLES_EXT); - AddExtensionString("GL_CHROMIUM_framebuffer_multisample"); + if (!disallowed_features_.multisampling) { + bool ext_has_multisample = + extensions.Contains("GL_EXT_framebuffer_multisample"); + if (!workarounds_.disable_angle_framebuffer_multisample) { + ext_has_multisample |= + extensions.Contains("GL_ANGLE_framebuffer_multisample"); + } + if (ext_has_multisample) { + feature_flags_.chromium_framebuffer_multisample = true; + validators_.frame_buffer_target.AddValue(GL_READ_FRAMEBUFFER_EXT); + validators_.frame_buffer_target.AddValue(GL_DRAW_FRAMEBUFFER_EXT); + validators_.g_l_state.AddValue(GL_READ_FRAMEBUFFER_BINDING_EXT); + validators_.g_l_state.AddValue(GL_MAX_SAMPLES_EXT); + validators_.render_buffer_parameter.AddValue(GL_RENDERBUFFER_SAMPLES_EXT); + AddExtensionString("GL_CHROMIUM_framebuffer_multisample"); + } else { + if (extensions.Contains("GL_EXT_multisampled_render_to_texture")) { + feature_flags_.multisampled_render_to_texture = true; + } else if (extensions.Contains("GL_IMG_multisampled_render_to_texture")) { + feature_flags_.multisampled_render_to_texture = true; + feature_flags_.use_img_for_multisampled_render_to_texture = true; + } + if (feature_flags_.multisampled_render_to_texture) { + validators_.render_buffer_parameter.AddValue( + GL_RENDERBUFFER_SAMPLES_EXT); + validators_.g_l_state.AddValue(GL_MAX_SAMPLES_EXT); + validators_.frame_buffer_parameter.AddValue( + GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT); + AddExtensionString("GL_EXT_multisampled_render_to_texture"); + } + } } if (extensions.Contains("GL_OES_depth24") || gfx::HasDesktopGLFeatures()) { diff --git a/gpu/command_buffer/service/feature_info.h b/gpu/command_buffer/service/feature_info.h index 3754a3c..de52159 100644 --- a/gpu/command_buffer/service/feature_info.h +++ b/gpu/command_buffer/service/feature_info.h @@ -27,6 +27,9 @@ class GPU_EXPORT FeatureInfo : public base::RefCounted<FeatureInfo> { FeatureFlags(); bool chromium_framebuffer_multisample; + bool multisampled_render_to_texture; + // Use the IMG GLenum values and functions rather than EXT. + bool use_img_for_multisampled_render_to_texture; bool oes_standard_derivatives; bool oes_egl_image_external; bool npot_ok; diff --git a/gpu/command_buffer/service/feature_info_unittest.cc b/gpu/command_buffer/service/feature_info_unittest.cc index 81bf43f..0dc1685 100644 --- a/gpu/command_buffer/service/feature_info_unittest.cc +++ b/gpu/command_buffer/service/feature_info_unittest.cc @@ -77,6 +77,9 @@ struct FormatInfo { TEST_F(FeatureInfoTest, Basic) { // Test it starts off uninitialized. EXPECT_FALSE(info_->feature_flags().chromium_framebuffer_multisample); + EXPECT_FALSE(info_->feature_flags().multisampled_render_to_texture); + EXPECT_FALSE(info_->feature_flags( + ).use_img_for_multisampled_render_to_texture); EXPECT_FALSE(info_->feature_flags().oes_standard_derivatives); EXPECT_FALSE(info_->feature_flags().npot_ok); EXPECT_FALSE(info_->feature_flags().enable_texture_float_linear); @@ -527,6 +530,40 @@ TEST_F(FeatureInfoTest, InitializeEXT_framebuffer_multisample) { GL_RENDERBUFFER_SAMPLES_EXT)); } +TEST_F(FeatureInfoTest, InitializeEXT_multisampled_render_to_texture) { + SetupInitExpectations("GL_EXT_multisampled_render_to_texture"); + info_->Initialize(NULL); + EXPECT_TRUE(info_->feature_flags( + ).multisampled_render_to_texture); + EXPECT_FALSE(info_->feature_flags( + ).use_img_for_multisampled_render_to_texture); + EXPECT_THAT(info_->extensions(), + HasSubstr("GL_EXT_multisampled_render_to_texture")); + EXPECT_TRUE(info_->validators()->g_l_state.IsValid( + GL_MAX_SAMPLES_EXT)); + EXPECT_TRUE(info_->validators()->render_buffer_parameter.IsValid( + GL_RENDERBUFFER_SAMPLES_EXT)); + EXPECT_TRUE(info_->validators()->frame_buffer_parameter.IsValid( + GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT)); +} + +TEST_F(FeatureInfoTest, InitializeIMG_multisampled_render_to_texture) { + SetupInitExpectations("GL_IMG_multisampled_render_to_texture"); + info_->Initialize(NULL); + EXPECT_TRUE(info_->feature_flags( + ).use_img_for_multisampled_render_to_texture); + EXPECT_TRUE(info_->feature_flags( + ).use_img_for_multisampled_render_to_texture); + EXPECT_THAT(info_->extensions(), + HasSubstr("GL_EXT_multisampled_render_to_texture")); + EXPECT_TRUE(info_->validators()->g_l_state.IsValid( + GL_MAX_SAMPLES_EXT)); + EXPECT_TRUE(info_->validators()->render_buffer_parameter.IsValid( + GL_RENDERBUFFER_SAMPLES_EXT)); + EXPECT_TRUE(info_->validators()->frame_buffer_parameter.IsValid( + GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT)); +} + TEST_F(FeatureInfoTest, InitializeEXT_texture_filter_anisotropic) { SetupInitExpectations("GL_EXT_texture_filter_anisotropic"); info_->Initialize(NULL); diff --git a/gpu/command_buffer/service/framebuffer_manager.cc b/gpu/command_buffer/service/framebuffer_manager.cc index 9a0276e..b468262 100644 --- a/gpu/command_buffer/service/framebuffer_manager.cc +++ b/gpu/command_buffer/service/framebuffer_manager.cc @@ -119,10 +119,11 @@ class TextureAttachment : public Framebuffer::Attachment { public: TextureAttachment( - TextureRef* texture_ref, GLenum target, GLint level) + TextureRef* texture_ref, GLenum target, GLint level, GLsizei samples) : texture_ref_(texture_ref), target_(target), - level_(level) { + level_(level), + samples_(samples) { } virtual GLsizei width() const OVERRIDE { @@ -150,7 +151,7 @@ class TextureAttachment } virtual GLsizei samples() const OVERRIDE { - return 0; + return samples_; } virtual GLuint object_name() const OVERRIDE { @@ -219,6 +220,7 @@ class TextureAttachment scoped_refptr<TextureRef> texture_ref_; GLenum target_; GLint level_; + GLsizei samples_; DISALLOW_COPY_AND_ASSIGN(TextureAttachment); }; @@ -504,7 +506,7 @@ void Framebuffer::UnbindTexture( if (attachment->IsTexture(texture_ref)) { // TODO(gman): manually detach texture. // glFramebufferTexture2DEXT(target, it->first, GL_TEXTURE_2D, 0, 0); - AttachTexture(it->first, NULL, GL_TEXTURE_2D, 0); + AttachTexture(it->first, NULL, GL_TEXTURE_2D, 0, 0); done = false; break; } @@ -542,13 +544,13 @@ void Framebuffer::AttachRenderbuffer( void Framebuffer::AttachTexture( GLenum attachment, TextureRef* texture_ref, GLenum target, - GLint level) { + GLint level, GLsizei samples) { const Attachment* a = GetAttachment(attachment); if (a) a->DetachFromFramebuffer(); if (texture_ref) { attachments_[attachment] = scoped_refptr<Attachment>( - new TextureAttachment(texture_ref, target, level)); + new TextureAttachment(texture_ref, target, level, samples)); texture_ref->texture()->AttachToFramebuffer(); } else { attachments_.erase(attachment); diff --git a/gpu/command_buffer/service/framebuffer_manager.h b/gpu/command_buffer/service/framebuffer_manager.h index 5fe5a79..176e3e2 100644 --- a/gpu/command_buffer/service/framebuffer_manager.h +++ b/gpu/command_buffer/service/framebuffer_manager.h @@ -74,7 +74,7 @@ class GPU_EXPORT Framebuffer : public base::RefCounted<Framebuffer> { // Attaches a texture to a particlar attachment. Pass null to detach. void AttachTexture( GLenum attachment, TextureRef* texture_ref, GLenum target, - GLint level); + GLint level, GLsizei samples); // Unbinds the given renderbuffer if it is bound. void UnbindRenderbuffer( diff --git a/gpu/command_buffer/service/framebuffer_manager_unittest.cc b/gpu/command_buffer/service/framebuffer_manager_unittest.cc index 8f9fcbb..a2c8aeb 100644 --- a/gpu/command_buffer/service/framebuffer_manager_unittest.cc +++ b/gpu/command_buffer/service/framebuffer_manager_unittest.cc @@ -435,7 +435,7 @@ TEST_F(FramebufferInfoTest, AttachTexture) { // check adding one attachment framebuffer_->AttachTexture( - GL_COLOR_ATTACHMENT0, texture1.get(), kTarget1, kLevel1); + GL_COLOR_ATTACHMENT0, texture1.get(), kTarget1, kLevel1, kSamples1); EXPECT_FALSE(framebuffer_->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0)); EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT), framebuffer_->IsPossiblyComplete()); @@ -518,7 +518,7 @@ TEST_F(FramebufferInfoTest, AttachTexture) { true); framebuffer_->AttachTexture( - GL_COLOR_ATTACHMENT0, texture2.get(), kTarget2, kLevel2); + GL_COLOR_ATTACHMENT0, texture2.get(), kTarget2, kLevel2, kSamples2); EXPECT_EQ(static_cast<GLenum>(kFormat2), framebuffer_->GetColorAttachmentFormat()); EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE), @@ -574,7 +574,7 @@ TEST_F(FramebufferInfoTest, AttachTexture) { framebuffer_->IsPossiblyComplete()); // Check removing it. - framebuffer_->AttachTexture(GL_COLOR_ATTACHMENT0, NULL, 0, 0); + framebuffer_->AttachTexture(GL_COLOR_ATTACHMENT0, NULL, 0, 0, 0); EXPECT_TRUE(framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0) == NULL); EXPECT_EQ(static_cast<GLenum>(0), framebuffer_->GetColorAttachmentFormat()); @@ -625,6 +625,7 @@ TEST_F(FramebufferInfoTest, UnbindTexture) { const GLuint kTextureService2Id = 334; const GLenum kTarget1 = GL_TEXTURE_2D; const GLint kLevel1 = 0; + const GLint kSamples1 = 0; texture_manager_.CreateTexture(kTextureClient1Id, kTextureService1Id); scoped_refptr<TextureRef> texture1( @@ -637,9 +638,9 @@ TEST_F(FramebufferInfoTest, UnbindTexture) { // Attach to 2 attachment points. framebuffer_->AttachTexture( - GL_COLOR_ATTACHMENT0, texture1.get(), kTarget1, kLevel1); + GL_COLOR_ATTACHMENT0, texture1.get(), kTarget1, kLevel1, kSamples1); framebuffer_->AttachTexture( - GL_DEPTH_ATTACHMENT, texture1.get(), kTarget1, kLevel1); + GL_DEPTH_ATTACHMENT, texture1.get(), kTarget1, kLevel1, kSamples1); // Check they were attached. EXPECT_TRUE(framebuffer_->GetAttachment(GL_COLOR_ATTACHMENT0) != NULL); EXPECT_TRUE(framebuffer_->GetAttachment(GL_DEPTH_ATTACHMENT) != NULL); @@ -662,6 +663,7 @@ TEST_F(FramebufferInfoTest, IsCompleteMarkAsComplete) { const GLuint kTextureService2Id = 334; const GLenum kTarget1 = GL_TEXTURE_2D; const GLint kLevel1 = 0; + const GLint kSamples1 = 0; renderbuffer_manager_.CreateRenderbuffer( kRenderbufferClient1Id, kRenderbufferService1Id); @@ -679,7 +681,7 @@ TEST_F(FramebufferInfoTest, IsCompleteMarkAsComplete) { // Check at attaching marks as not complete. framebuffer_->AttachTexture( - GL_COLOR_ATTACHMENT0, texture2.get(), kTarget1, kLevel1); + GL_COLOR_ATTACHMENT0, texture2.get(), kTarget1, kLevel1, kSamples1); EXPECT_FALSE(manager_.IsComplete(framebuffer_)); manager_.MarkAsComplete(framebuffer_); EXPECT_TRUE(manager_.IsComplete(framebuffer_)); @@ -707,6 +709,7 @@ TEST_F(FramebufferInfoTest, GetStatus) { const GLuint kTextureService2Id = 334; const GLenum kTarget1 = GL_TEXTURE_2D; const GLint kLevel1 = 0; + const GLint kSamples1 = 0; renderbuffer_manager_.CreateRenderbuffer( kRenderbufferClient1Id, kRenderbufferService1Id); @@ -734,7 +737,7 @@ TEST_F(FramebufferInfoTest, GetStatus) { // Check changing the attachments calls CheckFramebufferStatus. framebuffer_->AttachTexture( - GL_COLOR_ATTACHMENT0, texture2.get(), kTarget1, kLevel1); + GL_COLOR_ATTACHMENT0, texture2.get(), kTarget1, kLevel1, kSamples1); EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_FRAMEBUFFER)) .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE)).RetiresOnSaturation(); framebuffer_->GetStatus(&texture_manager_, GL_FRAMEBUFFER); diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index 3470340..f1f024c 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -1231,6 +1231,16 @@ class GLES2DecoderImpl : public GLES2Decoder { GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); + // Wrapper for glFramebufferTexture2DMultisampleEXT. + void DoFramebufferTexture2DMultisample( + GLenum target, GLenum attachment, GLenum textarget, + GLuint texture, GLint level, GLsizei samples); + + // Common implementation for both DoFramebufferTexture2D wrappers. + void DoFramebufferTexture2DCommon(const char* name, + GLenum target, GLenum attachment, GLenum textarget, + GLuint texture, GLint level, GLsizei samples); + // Wrapper for glGenerateMipmap void DoGenerateMipmap(GLenum target); @@ -1238,6 +1248,11 @@ class GLES2DecoderImpl : public GLES2Decoder { void DoGenSharedIdsCHROMIUM( GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids); + // Helper for DoGetBooleanv, Floatv, and Intergerv to adjust pname + // to account for different pname values defined in different extension + // variants. + GLenum AdjustGetPname(GLenum pname); + // Wrapper for DoGetBooleanv. void DoGetBooleanv(GLenum pname, GLboolean* params); @@ -4338,6 +4353,14 @@ bool GLES2DecoderImpl::GetNumValuesReturnedForGLGet( return GetHelper(pname, NULL, num_values); } +GLenum GLES2DecoderImpl::AdjustGetPname(GLenum pname) { + if (GL_MAX_SAMPLES == pname && + features().use_img_for_multisampled_render_to_texture) { + return GL_MAX_SAMPLES_IMG; + } + return pname; +} + void GLES2DecoderImpl::DoGetBooleanv(GLenum pname, GLboolean* params) { DCHECK(params); GLsizei num_written = 0; @@ -4350,6 +4373,7 @@ void GLES2DecoderImpl::DoGetBooleanv(GLenum pname, GLboolean* params) { params[ii] = static_cast<GLboolean>(values[ii]); } } else { + pname = AdjustGetPname(pname); glGetBooleanv(pname, params); } } @@ -4365,6 +4389,7 @@ void GLES2DecoderImpl::DoGetFloatv(GLenum pname, GLfloat* params) { params[ii] = static_cast<GLfloat>(values[ii]); } } else { + pname = AdjustGetPname(pname); glGetFloatv(pname, params); } } @@ -4375,6 +4400,7 @@ void GLES2DecoderImpl::DoGetIntegerv(GLenum pname, GLint* params) { GLsizei num_written; if (!state_.GetStateAsGLint(pname, params, &num_written) && !GetHelper(pname, params, &num_written)) { + pname = AdjustGetPname(pname); glGetIntegerv(pname, params); } } @@ -4850,11 +4876,39 @@ GLenum GLES2DecoderImpl::DoCheckFramebufferStatus(GLenum target) { void GLES2DecoderImpl::DoFramebufferTexture2D( GLenum target, GLenum attachment, GLenum textarget, GLuint client_texture_id, GLint level) { + DoFramebufferTexture2DCommon( + "glFramebufferTexture2D", target, attachment, + textarget, client_texture_id, level, 0); +} + +void GLES2DecoderImpl::DoFramebufferTexture2DMultisample( + GLenum target, GLenum attachment, GLenum textarget, + GLuint client_texture_id, GLint level, GLsizei samples) { + if (!features().multisampled_render_to_texture) { + LOCAL_SET_GL_ERROR( + GL_INVALID_OPERATION, + "glFramebufferTexture2DMultisample", "function not available"); + return; + } + DoFramebufferTexture2DCommon( + "glFramebufferTexture2DMultisample", target, attachment, + textarget, client_texture_id, level, samples); +} + +void GLES2DecoderImpl::DoFramebufferTexture2DCommon( + const char* name, GLenum target, GLenum attachment, GLenum textarget, + GLuint client_texture_id, GLint level, GLsizei samples) { + if (samples > renderbuffer_manager()->max_samples()) { + LOCAL_SET_GL_ERROR( + GL_INVALID_VALUE, + "glFramebufferTexture2DMultisample", "samples too large"); + return; + } Framebuffer* framebuffer = GetFramebufferInfoForTarget(target); if (!framebuffer) { LOCAL_SET_GL_ERROR( GL_INVALID_OPERATION, - "glFramebufferTexture2D", "no framebuffer bound."); + name, "no framebuffer bound."); return; } GLuint service_id = 0; @@ -4864,7 +4918,7 @@ void GLES2DecoderImpl::DoFramebufferTexture2D( if (!texture_ref) { LOCAL_SET_GL_ERROR( GL_INVALID_OPERATION, - "glFramebufferTexture2D", "unknown texture_ref"); + name, "unknown texture_ref"); return; } service_id = texture_ref->service_id(); @@ -4873,15 +4927,26 @@ void GLES2DecoderImpl::DoFramebufferTexture2D( if (!texture_manager()->ValidForTarget(textarget, level, 0, 0, 1)) { LOCAL_SET_GL_ERROR( GL_INVALID_VALUE, - "glFramebufferTexture2D", "level out of range"); + name, "level out of range"); return; } - LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glFramebufferTexture2D"); - glFramebufferTexture2DEXT(target, attachment, textarget, service_id, level); - GLenum error = LOCAL_PEEK_GL_ERROR("glFramebufferTexture2D"); + LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(name); + if (0 == samples) { + glFramebufferTexture2DEXT(target, attachment, textarget, service_id, level); + } else { + if (features().use_img_for_multisampled_render_to_texture) { + glFramebufferTexture2DMultisampleIMG(target, attachment, textarget, + service_id, level, samples); + } else { + glFramebufferTexture2DMultisampleEXT(target, attachment, textarget, + service_id, level, samples); + } + } + GLenum error = LOCAL_PEEK_GL_ERROR(name); if (error == GL_NO_ERROR) { - framebuffer->AttachTexture(attachment, texture_ref, textarget, level); + framebuffer->AttachTexture(attachment, texture_ref, textarget, level, + samples); } if (framebuffer == state_.bound_draw_framebuffer.get()) { clear_state_dirty_ = true; @@ -4903,6 +4968,10 @@ void GLES2DecoderImpl::DoGetFramebufferAttachmentParameteriv( framebuffer->GetAttachment(attachment); *params = attachment_object ? attachment_object->object_name() : 0; } else { + if (pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT && + features().use_img_for_multisampled_render_to_texture) { + pname = GL_TEXTURE_SAMPLES_IMG; + } glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, params); } } @@ -4927,6 +4996,14 @@ void GLES2DecoderImpl::DoGetRenderbufferParameteriv( case GL_RENDERBUFFER_HEIGHT: *params = renderbuffer->height(); break; + case GL_RENDERBUFFER_SAMPLES_EXT: + if (features().use_img_for_multisampled_render_to_texture) { + glGetRenderbufferParameterivEXT(target, GL_RENDERBUFFER_SAMPLES_IMG, + params); + } else { + glGetRenderbufferParameterivEXT(target, GL_RENDERBUFFER_SAMPLES_EXT, + params); + } default: glGetRenderbufferParameterivEXT(target, pname, params); break; @@ -4962,7 +5039,8 @@ void GLES2DecoderImpl::DoBlitFramebufferEXT( void GLES2DecoderImpl::DoRenderbufferStorageMultisample( GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) { - if (!features().chromium_framebuffer_multisample) { + if (!features().chromium_framebuffer_multisample && + !features().multisampled_render_to_texture) { LOCAL_SET_GL_ERROR( GL_INVALID_OPERATION, "glRenderbufferStorageMultisample", "function not available"); @@ -5015,6 +5093,9 @@ void GLES2DecoderImpl::DoRenderbufferStorageMultisample( if (IsAngle()) { glRenderbufferStorageMultisampleANGLE( target, samples, impl_format, width, height); + } else if (features().use_img_for_multisampled_render_to_texture) { + glRenderbufferStorageMultisampleIMG( + target, samples, impl_format, width, height); } else { glRenderbufferStorageMultisampleEXT( target, samples, impl_format, width, height); diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h index 56cf3e2..a992e34 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h @@ -2757,6 +2757,42 @@ error::Error GLES2DecoderImpl::HandleRenderbufferStorageMultisampleEXT( return error::kNoError; } +error::Error GLES2DecoderImpl::HandleFramebufferTexture2DMultisampleEXT( + uint32 immediate_data_size, + const gles2::cmds::FramebufferTexture2DMultisampleEXT& c) { + GLenum target = static_cast<GLenum>(c.target); + GLenum attachment = static_cast<GLenum>(c.attachment); + GLenum textarget = static_cast<GLenum>(c.textarget); + GLuint texture = c.texture; + GLint level = static_cast<GLint>(c.level); + GLsizei samples = static_cast<GLsizei>(c.samples); + if (!validators_->frame_buffer_target.IsValid(target)) { + LOCAL_SET_GL_ERROR_INVALID_ENUM("glFramebufferTexture2DMultisampleEXT", target, "target"); // NOLINT + return error::kNoError; + } + if (!validators_->attachment.IsValid(attachment)) { + LOCAL_SET_GL_ERROR_INVALID_ENUM("glFramebufferTexture2DMultisampleEXT", attachment, "attachment"); // NOLINT + return error::kNoError; + } + if (!validators_->texture_target.IsValid(textarget)) { + LOCAL_SET_GL_ERROR_INVALID_ENUM("glFramebufferTexture2DMultisampleEXT", textarget, "textarget"); // NOLINT + return error::kNoError; + } + if (!validators_->zero_only.IsValid(level)) { + LOCAL_SET_GL_ERROR( + GL_INVALID_VALUE, "glFramebufferTexture2DMultisampleEXT", "level GL_INVALID_VALUE"); // NOLINT + return error::kNoError; + } + if (samples < 0) { + LOCAL_SET_GL_ERROR( + GL_INVALID_VALUE, "glFramebufferTexture2DMultisampleEXT", "samples < 0"); // NOLINT + return error::kNoError; + } + DoFramebufferTexture2DMultisample( + target, attachment, textarget, texture, level, samples); + return error::kNoError; +} + error::Error GLES2DecoderImpl::HandleTexStorage2DEXT( uint32 immediate_data_size, const gles2::cmds::TexStorage2DEXT& c) { GLenum target = static_cast<GLenum>(c.target); diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h index c10a61b..caff2eb 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h @@ -1741,6 +1741,7 @@ TEST_F(GLES2DecoderTest2, ViewportInvalidArgs3_0) { } // TODO(gman): BlitFramebufferEXT // TODO(gman): RenderbufferStorageMultisampleEXT +// TODO(gman): FramebufferTexture2DMultisampleEXT // TODO(gman): TexStorage2DEXT // TODO(gman): GenQueriesEXT // TODO(gman): GenQueriesEXTImmediate @@ -1762,6 +1763,5 @@ TEST_F(GLES2DecoderTest2, PopGroupMarkerEXTValidArgs) { EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_NO_ERROR, GetGLError()); } -// TODO(gman): GenVertexArraysOES #endif // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_2_AUTOGEN_H_ diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h index ff078ef..58611bf 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h @@ -10,6 +10,7 @@ #ifndef GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_3_AUTOGEN_H_ #define GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_3_AUTOGEN_H_ +// TODO(gman): GenVertexArraysOES // TODO(gman): GenVertexArraysOESImmediate // TODO(gman): DeleteVertexArraysOES // TODO(gman): DeleteVertexArraysOESImmediate diff --git a/gpu/command_buffer/service/texture_manager_unittest.cc b/gpu/command_buffer/service/texture_manager_unittest.cc index f8a3f6b..402cc8d 100644 --- a/gpu/command_buffer/service/texture_manager_unittest.cc +++ b/gpu/command_buffer/service/texture_manager_unittest.cc @@ -2233,7 +2233,7 @@ TEST_F(SharedTextureTest, FBOCompletenessCheck) { scoped_refptr<Framebuffer> framebuffer1 = framebuffer_manager1.GetFramebuffer(10); framebuffer1->AttachTexture( - GL_COLOR_ATTACHMENT0, ref1.get(), GL_TEXTURE_2D, 0); + GL_COLOR_ATTACHMENT0, ref1.get(), GL_TEXTURE_2D, 0, 0); EXPECT_FALSE(framebuffer_manager1.IsComplete(framebuffer1.get())); EXPECT_NE(kCompleteValue, framebuffer1->IsPossiblyComplete()); @@ -2261,7 +2261,7 @@ TEST_F(SharedTextureTest, FBOCompletenessCheck) { scoped_refptr<Framebuffer> framebuffer2 = framebuffer_manager2.GetFramebuffer(20); framebuffer2->AttachTexture( - GL_COLOR_ATTACHMENT0, ref2.get(), GL_TEXTURE_2D, 0); + GL_COLOR_ATTACHMENT0, ref2.get(), GL_TEXTURE_2D, 0, 0); EXPECT_FALSE(framebuffer_manager2.IsComplete(framebuffer2.get())); EXPECT_EQ(kCompleteValue, framebuffer2->IsPossiblyComplete()); framebuffer_manager2.MarkAsComplete(framebuffer2.get()); |