summaryrefslogtreecommitdiffstats
path: root/gpu
diff options
context:
space:
mode:
authorbsalomon@google.com <bsalomon@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2013-07-12 14:13:16 +0000
committerbsalomon@google.com <bsalomon@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2013-07-12 14:13:16 +0000
commit7d3c36e12d2aaee9c18372de2bc2d800a575e12e (patch)
treedc0fd7fbb6c9a23293d9a3bffb78df89534a7712 /gpu
parent96af629d79595bdf32a3047aa012a5b0dd627c56 (diff)
downloadchromium_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')
-rw-r--r--gpu/GLES2/gl2chromium_autogen.h2
-rwxr-xr-xgpu/command_buffer/build_gles2_cmd_buffer.py7
-rw-r--r--gpu/command_buffer/client/gles2_c_lib_autogen.h7
-rw-r--r--gpu/command_buffer/client/gles2_cmd_helper_autogen.h10
-rw-r--r--gpu/command_buffer/client/gles2_implementation_autogen.h4
-rw-r--r--gpu/command_buffer/client/gles2_implementation_impl_autogen.h15
-rw-r--r--gpu/command_buffer/client/gles2_implementation_unittest_autogen.h13
-rw-r--r--gpu/command_buffer/client/gles2_interface_autogen.h3
-rw-r--r--gpu/command_buffer/client/gles2_interface_stub_autogen.h3
-rw-r--r--gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h4
-rw-r--r--gpu/command_buffer/client/gles2_trace_implementation_autogen.h3
-rw-r--r--gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h8
-rw-r--r--gpu/command_buffer/cmd_buffer_functions.txt1
-rw-r--r--gpu/command_buffer/common/gles2_cmd_format_autogen.h60
-rw-r--r--gpu/command_buffer/common/gles2_cmd_format_test_autogen.h25
-rw-r--r--gpu/command_buffer/common/gles2_cmd_ids_autogen.h117
-rw-r--r--gpu/command_buffer/common/gles2_cmd_utils.cc10
-rw-r--r--gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h1
-rw-r--r--gpu/command_buffer/service/context_group.cc10
-rw-r--r--gpu/command_buffer/service/feature_info.cc47
-rw-r--r--gpu/command_buffer/service/feature_info.h3
-rw-r--r--gpu/command_buffer/service/feature_info_unittest.cc37
-rw-r--r--gpu/command_buffer/service/framebuffer_manager.cc14
-rw-r--r--gpu/command_buffer/service/framebuffer_manager.h2
-rw-r--r--gpu/command_buffer/service/framebuffer_manager_unittest.cc17
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc97
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_autogen.h36
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h2
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h1
-rw-r--r--gpu/command_buffer/service/texture_manager_unittest.cc4
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());