diff options
author | gman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-05-17 14:47:16 +0000 |
---|---|---|
committer | gman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-05-17 14:47:16 +0000 |
commit | b6140d086d71667131111b1c85090e7023311942 (patch) | |
tree | 16a2889f424d11ef6f15cdb4eded7cad5923761b /gpu | |
parent | 1e0887fb4c08fbfb9421aede24a627e7bb903276 (diff) | |
download | chromium_src-b6140d086d71667131111b1c85090e7023311942.zip chromium_src-b6140d086d71667131111b1c85090e7023311942.tar.gz chromium_src-b6140d086d71667131111b1c85090e7023311942.tar.bz2 |
Adds support for compressed textures. DXT1 only.
This is a temporary implementation. The real implementation
will require
*) glGetString to return "GL_EXT_texture_compression_dxt1"
*) CommandBufferEnable("GL_EXT_texture_compression_dxt1")
to dynamically modify the validation after it has made
sure the "GL_EXT_texture_compression_dxt1" is returned
from the system level GL
TEST=none
BUG=none
Review URL: http://codereview.chromium.org/2136003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@47417 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu')
16 files changed, 443 insertions, 36 deletions
diff --git a/gpu/GLES2/gl2ext.h b/gpu/GLES2/gl2ext.h index 80a6820..b348e22 100644 --- a/gpu/GLES2/gl2ext.h +++ b/gpu/GLES2/gl2ext.h @@ -1,7 +1,7 @@ #ifndef __gl2ext_h_ #define __gl2ext_h_ -/* $Revision: 10798 $ on $Date:: 2010-03-19 17:34:30 -0700 #$ */ +/* $Revision: 10969 $ on $Date:: 2010-04-09 02:27:15 -0700 #$ */ #ifdef __cplusplus extern "C" { @@ -222,6 +222,12 @@ typedef void* GLeglImageOES; #define GL_UNSIGNED_INT_2_10_10_10_REV_EXT 0x8368 #endif +/* GL_EXT_texture_compression_dxt1 */ +#ifndef GL_EXT_texture_compression_dxt1 +#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 +#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 +#endif + /*------------------------------------------------------------------------* * IMG extension tokens *------------------------------------------------------------------------*/ @@ -250,6 +256,14 @@ typedef void* GLeglImageOES; #define GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG 0x8C03 #endif +/* GL_IMG_multisampled_render_to_texture */ +#ifndef GL_IMG_multisampled_render_to_texture +#define GL_RENDERBUFFER_SAMPLES_IMG 0x9133 +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_IMG 0x9134 +#define GL_MAX_SAMPLES_IMG 0x9135 +#define GL_TEXTURE_SAMPLES_IMG 0x9136 +#endif + /*------------------------------------------------------------------------* * NV extension tokens *------------------------------------------------------------------------*/ @@ -623,6 +637,11 @@ typedef void (GL_APIENTRYP PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, const GL #define GL_EXT_texture_type_2_10_10_10_REV 1 #endif +/* GL_EXT_texture_compression_dxt1 */ +#ifndef GL_EXT_texture_compression_dxt1 +#define GL_EXT_texture_compression_dxt1 1 +#endif + /*------------------------------------------------------------------------* * IMG extension functions *------------------------------------------------------------------------*/ @@ -647,6 +666,17 @@ typedef void (GL_APIENTRYP PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, const GL #define GL_IMG_texture_compression_pvrtc 1 #endif +/* GL_IMG_multisampled_render_to_texture */ +#ifndef GL_IMG_multisampled_render_to_texture +#define GL_IMG_multisampled_render_to_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleIMG (GLenum, GLsizei, GLenum, GLsizei, GLsizei); +GL_APICALL void GL_APIENTRY glFramebufferTexture2DMultisampleIMG (GLenum, GLenum, GLenum, GLuint, GLint, GLsizei); +#endif +typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEIMG) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLCLIPPLANEXIMG) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples); +#endif + /*------------------------------------------------------------------------* * NV extension functions *------------------------------------------------------------------------*/ @@ -771,3 +801,4 @@ typedef void (GL_APIENTRYP PFNGLENDTILINGQCOMPROC) (GLbitfield preserveMask); #endif #endif /* __gl2ext_h_ */ + diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py index 9c7f358..89b943f 100755 --- a/gpu/command_buffer/build_gles2_cmd_buffer.py +++ b/gpu/command_buffer/build_gles2_cmd_buffer.py @@ -54,8 +54,8 @@ GL_APICALL void GL_APIENTRY glClearDepthf (GLclampf depth); GL_APICALL void GL_APIENTRY glClearStencil (GLint s); GL_APICALL void GL_APIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); GL_APICALL void GL_APIENTRY glCompileShader (GLidShader shader); -GL_APICALL void GL_APIENTRY glCompressedTexImage2D (GLenumTextureTarget target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data); -GL_APICALL void GL_APIENTRY glCompressedTexSubImage2D (GLenumTextureTarget target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data); +GL_APICALL void GL_APIENTRY glCompressedTexImage2D (GLenumTextureTarget target, GLint level, GLenumCompressedTextureFormat internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data); +GL_APICALL void GL_APIENTRY glCompressedTexSubImage2D (GLenumTextureTarget target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenumCompressedTextureFormat format, GLsizei imageSize, const void* data); GL_APICALL void GL_APIENTRY glCopyTexImage2D (GLenumTextureTarget target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); GL_APICALL void GL_APIENTRY glCopyTexSubImage2D (GLenumTextureTarget target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); GL_APICALL GLuint GL_APIENTRY glCreateProgram (void); @@ -376,6 +376,8 @@ _CMD_ID_TABLE = { 'DeleteSharedIds': 440, 'RegisterSharedIds': 441, 'CommandBufferEnable': 442, + 'CompressedTexImage2DBucket': 443, + 'CompressedTexSubImage2DBucket': 444, } # This is a list of enum names and their valid values. It is used to map @@ -420,6 +422,14 @@ _ENUM_LISTS = { 'GL_STATIC_READ', ], }, + 'CompressedTextureFormat': { + 'type': 'GLenum', + # TODO(gman): Refactor validation code so these can be added at runtime + 'valid': [ + 'GL_COMPRESSED_RGB_S3TC_DXT1_EXT', + 'GL_COMPRESSED_RGBA_S3TC_DXT1_EXT', + ], + }, 'GLState': { 'type': 'GLenum', 'valid': [ @@ -1021,8 +1031,15 @@ _FUNCTION_INFO = { 'expectation': False, }, 'CompileShader': {'decoder_func': 'DoCompileShader', 'unit_test': False}, - 'CompressedTexImage2D': {'type': 'Manual','immediate': True}, - 'CompressedTexSubImage2D': {'type': 'Data'}, + 'CompressedTexImage2D': { + 'type': 'Manual', + 'immediate': True, + 'bucket': True, + }, + 'CompressedTexSubImage2D': { + 'type': 'Data', + 'bucket': True, + }, 'CreateProgram': {'type': 'Create'}, 'CreateShader': {'type': 'Create'}, 'DeleteBuffers': { @@ -1518,7 +1535,7 @@ class TypeHandler(object): def InitFunction(self, func): """Add or adjust anything type specific for this function.""" - if func.GetInfo('needs_size'): + if func.GetInfo('needs_size') and not func.name.endswith('Bucket'): func.AddCmdArg(DataSizeArgument('data_size')) def AddImmediateFunction(self, generator, func): @@ -1962,6 +1979,10 @@ class CustomHandler(TypeHandler): """Overrriden from TypeHandler.""" pass + def WriteBucketServiceImplementation(self, func, file): + """Overrriden from TypeHandler.""" + pass + def WriteServiceUnitTest(self, func, file): """Overrriden from TypeHandler.""" file.Write("// TODO(gman): %s\n\n" % func.name) @@ -2078,10 +2099,22 @@ class ManualHandler(CustomHandler): def __init__(self): CustomHandler.__init__(self) + def InitFunction(self, func): + """Overrriden from TypeHandler.""" + if (func.name == 'CompressedTexImage2DBucket'): + func.cmd_args = func.cmd_args[:-1] + func.AddCmdArg(Argument('bucket_id', 'GLuint')) + else: + CustomHandler.InitFunction(self, func) + def WriteServiceImplementation(self, func, file): """Overrriden from TypeHandler.""" pass + def WriteBucketServiceImplementation(self, func, file): + """Overrriden from TypeHandler.""" + pass + def WriteServiceUnitTest(self, func, file): """Overrriden from TypeHandler.""" file.Write("// TODO(gman): %s\n\n" % func.name) @@ -2120,6 +2153,12 @@ class DataHandler(TypeHandler): def __init__(self): TypeHandler.__init__(self) + def InitFunction(self, func): + """Overrriden from TypeHandler.""" + if func.name == 'CompressedTexSubImage2DBucket': + func.cmd_args = func.cmd_args[:-1] + func.AddCmdArg(Argument('bucket_id', 'GLuint')) + def WriteGetDataSizeCode(self, func, file): """Overrriden from TypeHandler.""" # TODO(gman): Move this data to _FUNCTION_INFO? @@ -2131,6 +2170,10 @@ class DataHandler(TypeHandler): elif (name == 'CompressedTexImage2D' or name == 'CompressedTexSubImage2D'): file.Write(" uint32 data_size = imageSize;\n") + elif (name == 'CompressedTexSubImage2DBucket'): + file.Write(" Bucket* bucket = GetBucket(c.bucket_id);\n") + file.Write(" uint32 data_size = bucket->size();\n") + file.Write(" GLsizei imageSize = data_size;\n") elif name == 'TexImage2D' or name == 'TexSubImage2D': code = """ uint32 data_size; if (!GLES2Util::ComputeImageDataSize( @@ -2216,6 +2259,11 @@ class DataHandler(TypeHandler): """Overrriden from TypeHandler.""" file.Write("// TODO(gman): %s\n\n" % func.name) + def WriteBucketServiceImplementation(self, func, file): + """Overrriden from TypeHandler.""" + if not func.name == 'CompressedTexSubImage2DBucket': + TypeHandler.WriteBucketServiceImplemenation(self, func, file) + class BindHandler(TypeHandler): """Handler for glBind___ type functions.""" @@ -3927,6 +3975,31 @@ class ImmediatePointerArgument(Argument): return None +class BucketPointerArgument(Argument): + """A class that represents an bucket argument to a function.""" + + def __init__(self, name, type): + Argument.__init__(self, name, type) + + def AddCmdArgs(self, args): + """Overridden from Argument.""" + pass + + def WriteGetCode(self, file): + """Overridden from Argument.""" + file.Write( + " %s %s = bucket->GetData(0, data_size);\n" % + (self.type, self.name)) + + def WriteValidationCode(self, file, func): + """Overridden from Argument.""" + pass + + def GetImmediateVersion(self): + """Overridden from Argument.""" + return None + + class PointerArgument(Argument): """A class that represents a pointer argument to a function.""" @@ -3994,7 +4067,7 @@ class PointerArgument(Argument): """Overridden from Argument.""" if self.type == "const char*": return InputStringBucketArgument(self.name, self.type) - return self + return BucketPointerArgument(self.name, self.type) class InputStringBucketArgument(Argument): @@ -4441,9 +4514,9 @@ class BucketFunction(Function): new_init_args, 0) - def InitFunction(self): - """Overridden from Function""" - pass +# def InitFunction(self): +# """Overridden from Function""" +# pass def WriteCommandDescription(self, file): """Overridden from Function""" @@ -4452,7 +4525,7 @@ class BucketFunction(Function): def WriteServiceImplementation(self, file): """Overridden from Function""" - pass + self.type_handler.WriteBucketServiceImplementation(self, file) def WriteHandlerImplementation(self, file): """Overridden from Function""" diff --git a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h index 1cbc45f..25394d0 100644 --- a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h +++ b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h @@ -175,6 +175,14 @@ c.Init(target, level, internalformat, width, height, border, imageSize); } + void CompressedTexImage2DBucket( + GLenum target, GLint level, GLenum internalformat, GLsizei width, + GLsizei height, GLint border, GLuint bucket_id) { + gles2::CompressedTexImage2DBucket& c = + GetCmdSpace<gles2::CompressedTexImage2DBucket>(); + c.Init(target, level, internalformat, width, height, border, bucket_id); + } + void CompressedTexSubImage2D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, uint32 data_shm_id, @@ -196,6 +204,14 @@ c.Init(target, level, xoffset, yoffset, width, height, format, imageSize); } + void CompressedTexSubImage2DBucket( + GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, + GLsizei height, GLenum format, GLuint bucket_id) { + gles2::CompressedTexSubImage2DBucket& c = + GetCmdSpace<gles2::CompressedTexSubImage2DBucket>(); + c.Init(target, level, xoffset, yoffset, width, height, format, bucket_id); + } + void CopyTexImage2D( GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) { diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc index f460329..a74d2982 100644 --- a/gpu/command_buffer/client/gles2_implementation.cc +++ b/gpu/command_buffer/client/gles2_implementation.cc @@ -892,17 +892,13 @@ void GLES2Implementation::CompressedTexImage2D( if (height == 0 || width == 0) { return; } - // TODO(gman): Switch to use buckets always or at least if no room in shared - // memory. - DCHECK_LE(image_size, - static_cast<GLsizei>( - transfer_buffer_.GetLargestFreeOrPendingSize())); - void* buffer = transfer_buffer_.Alloc(image_size); - memcpy(buffer, data, image_size); - helper_->CompressedTexImage2D( - target, level, internalformat, width, height, border, image_size, - transfer_buffer_id_, transfer_buffer_.GetOffset(buffer)); - transfer_buffer_.FreePendingToken(buffer, helper_->InsertToken()); + SetBucketContents(kResultBucketId, data, image_size); + helper_->CompressedTexImage2DBucket( + target, level, internalformat, width, height, border, kResultBucketId); + // Free the bucket. This is not required but it does free up the memory. + // and we don't have to wait for the result so from the client's perspective + // it's cheap. + helper_->SetBucketSize(kResultBucketId, 0); } void GLES2Implementation::CompressedTexSubImage2D( @@ -912,17 +908,13 @@ void GLES2Implementation::CompressedTexSubImage2D( SetGLError(GL_INVALID_VALUE, "glCompressedTexSubImage2D dimension < 0"); return; } - // TODO(gman): Switch to use buckets always or at least if no room in shared - // memory. - DCHECK_LE(image_size, - static_cast<GLsizei>( - transfer_buffer_.GetLargestFreeOrPendingSize())); - void* buffer = transfer_buffer_.Alloc(image_size); - memcpy(buffer, data, image_size); - helper_->CompressedTexSubImage2D( - target, level, xoffset, yoffset, width, height, format, image_size, - transfer_buffer_id_, transfer_buffer_.GetOffset(buffer)); - transfer_buffer_.FreePendingToken(buffer, helper_->InsertToken()); + SetBucketContents(kResultBucketId, data, image_size); + helper_->CompressedTexSubImage2DBucket( + target, level, xoffset, yoffset, width, height, format, kResultBucketId); + // Free the bucket. This is not required but it does free up the memory. + // and we don't have to wait for the result so from the client's perspective + // it's cheap. + helper_->SetBucketSize(kResultBucketId, 0); } void GLES2Implementation::TexImage2D( diff --git a/gpu/command_buffer/common/gles2_cmd_format_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_autogen.h index 46e04aa..785265b 100644 --- a/gpu/command_buffer/common/gles2_cmd_format_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_format_autogen.h @@ -1210,6 +1210,71 @@ COMPILE_ASSERT(offsetof(CompressedTexImage2DImmediate, border) == 24, COMPILE_ASSERT(offsetof(CompressedTexImage2DImmediate, imageSize) == 28, OffsetOf_CompressedTexImage2DImmediate_imageSize_not_28); +struct CompressedTexImage2DBucket { + typedef CompressedTexImage2DBucket ValueType; + static const CommandId kCmdId = kCompressedTexImage2DBucket; + 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, GLint _level, GLenum _internalformat, GLsizei _width, + GLsizei _height, GLint _border, GLuint _bucket_id) { + SetHeader(); + target = _target; + level = _level; + internalformat = _internalformat; + width = _width; + height = _height; + border = _border; + bucket_id = _bucket_id; + } + + void* Set( + void* cmd, GLenum _target, GLint _level, GLenum _internalformat, + GLsizei _width, GLsizei _height, GLint _border, GLuint _bucket_id) { + static_cast<ValueType*>( + cmd)->Init( + _target, _level, _internalformat, _width, _height, _border, + _bucket_id); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32 target; + int32 level; + uint32 internalformat; + int32 width; + int32 height; + int32 border; + uint32 bucket_id; +}; + +COMPILE_ASSERT(sizeof(CompressedTexImage2DBucket) == 32, + Sizeof_CompressedTexImage2DBucket_is_not_32); +COMPILE_ASSERT(offsetof(CompressedTexImage2DBucket, header) == 0, + OffsetOf_CompressedTexImage2DBucket_header_not_0); +COMPILE_ASSERT(offsetof(CompressedTexImage2DBucket, target) == 4, + OffsetOf_CompressedTexImage2DBucket_target_not_4); +COMPILE_ASSERT(offsetof(CompressedTexImage2DBucket, level) == 8, + OffsetOf_CompressedTexImage2DBucket_level_not_8); +COMPILE_ASSERT(offsetof(CompressedTexImage2DBucket, internalformat) == 12, + OffsetOf_CompressedTexImage2DBucket_internalformat_not_12); +COMPILE_ASSERT(offsetof(CompressedTexImage2DBucket, width) == 16, + OffsetOf_CompressedTexImage2DBucket_width_not_16); +COMPILE_ASSERT(offsetof(CompressedTexImage2DBucket, height) == 20, + OffsetOf_CompressedTexImage2DBucket_height_not_20); +COMPILE_ASSERT(offsetof(CompressedTexImage2DBucket, border) == 24, + OffsetOf_CompressedTexImage2DBucket_border_not_24); +COMPILE_ASSERT(offsetof(CompressedTexImage2DBucket, bucket_id) == 28, + OffsetOf_CompressedTexImage2DBucket_bucket_id_not_28); + struct CompressedTexSubImage2D { typedef CompressedTexSubImage2D ValueType; static const CommandId kCmdId = kCompressedTexSubImage2D; @@ -1362,6 +1427,75 @@ COMPILE_ASSERT(offsetof(CompressedTexSubImage2DImmediate, format) == 28, COMPILE_ASSERT(offsetof(CompressedTexSubImage2DImmediate, imageSize) == 32, OffsetOf_CompressedTexSubImage2DImmediate_imageSize_not_32); +struct CompressedTexSubImage2DBucket { + typedef CompressedTexSubImage2DBucket ValueType; + static const CommandId kCmdId = kCompressedTexSubImage2DBucket; + 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, GLint _level, GLint _xoffset, GLint _yoffset, + GLsizei _width, GLsizei _height, GLenum _format, GLuint _bucket_id) { + SetHeader(); + target = _target; + level = _level; + xoffset = _xoffset; + yoffset = _yoffset; + width = _width; + height = _height; + format = _format; + bucket_id = _bucket_id; + } + + void* Set( + void* cmd, GLenum _target, GLint _level, GLint _xoffset, GLint _yoffset, + GLsizei _width, GLsizei _height, GLenum _format, GLuint _bucket_id) { + static_cast<ValueType*>( + cmd)->Init( + _target, _level, _xoffset, _yoffset, _width, _height, _format, + _bucket_id); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32 target; + int32 level; + int32 xoffset; + int32 yoffset; + int32 width; + int32 height; + uint32 format; + uint32 bucket_id; +}; + +COMPILE_ASSERT(sizeof(CompressedTexSubImage2DBucket) == 36, + Sizeof_CompressedTexSubImage2DBucket_is_not_36); +COMPILE_ASSERT(offsetof(CompressedTexSubImage2DBucket, header) == 0, + OffsetOf_CompressedTexSubImage2DBucket_header_not_0); +COMPILE_ASSERT(offsetof(CompressedTexSubImage2DBucket, target) == 4, + OffsetOf_CompressedTexSubImage2DBucket_target_not_4); +COMPILE_ASSERT(offsetof(CompressedTexSubImage2DBucket, level) == 8, + OffsetOf_CompressedTexSubImage2DBucket_level_not_8); +COMPILE_ASSERT(offsetof(CompressedTexSubImage2DBucket, xoffset) == 12, + OffsetOf_CompressedTexSubImage2DBucket_xoffset_not_12); +COMPILE_ASSERT(offsetof(CompressedTexSubImage2DBucket, yoffset) == 16, + OffsetOf_CompressedTexSubImage2DBucket_yoffset_not_16); +COMPILE_ASSERT(offsetof(CompressedTexSubImage2DBucket, width) == 20, + OffsetOf_CompressedTexSubImage2DBucket_width_not_20); +COMPILE_ASSERT(offsetof(CompressedTexSubImage2DBucket, height) == 24, + OffsetOf_CompressedTexSubImage2DBucket_height_not_24); +COMPILE_ASSERT(offsetof(CompressedTexSubImage2DBucket, format) == 28, + OffsetOf_CompressedTexSubImage2DBucket_format_not_28); +COMPILE_ASSERT(offsetof(CompressedTexSubImage2DBucket, bucket_id) == 32, + OffsetOf_CompressedTexSubImage2DBucket_bucket_id_not_32); + struct CopyTexImage2D { typedef CopyTexImage2D ValueType; static const CommandId kCmdId = kCopyTexImage2D; 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 c2a1a0e..3a64424 100644 --- a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h @@ -424,6 +424,31 @@ TEST(GLES2FormatTest, CompressedTexImage2D) { } // TODO(gman): Implement test for CompressedTexImage2DImmediate +TEST(GLES2FormatTest, CompressedTexImage2DBucket) { + CompressedTexImage2DBucket cmd = { { 0 } }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11), + static_cast<GLint>(12), + static_cast<GLenum>(13), + static_cast<GLsizei>(14), + static_cast<GLsizei>(15), + static_cast<GLint>(16), + static_cast<GLuint>(17)); + EXPECT_EQ(static_cast<uint32>(CompressedTexImage2DBucket::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<char*>(next_cmd), + reinterpret_cast<char*>(&cmd) + sizeof(cmd)); + EXPECT_EQ(static_cast<GLenum>(11), cmd.target); + EXPECT_EQ(static_cast<GLint>(12), cmd.level); + EXPECT_EQ(static_cast<GLenum>(13), cmd.internalformat); + EXPECT_EQ(static_cast<GLsizei>(14), cmd.width); + EXPECT_EQ(static_cast<GLsizei>(15), cmd.height); + EXPECT_EQ(static_cast<GLint>(16), cmd.border); + EXPECT_EQ(static_cast<GLuint>(17), cmd.bucket_id); +} + TEST(GLES2FormatTest, CompressedTexSubImage2D) { CompressedTexSubImage2D cmd = { { 0 } }; void* next_cmd = cmd.Set( @@ -456,6 +481,33 @@ TEST(GLES2FormatTest, CompressedTexSubImage2D) { } // TODO(gman): Implement test for CompressedTexSubImage2DImmediate +TEST(GLES2FormatTest, CompressedTexSubImage2DBucket) { + CompressedTexSubImage2DBucket cmd = { { 0 } }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11), + static_cast<GLint>(12), + static_cast<GLint>(13), + static_cast<GLint>(14), + static_cast<GLsizei>(15), + static_cast<GLsizei>(16), + static_cast<GLenum>(17), + static_cast<GLuint>(18)); + EXPECT_EQ(static_cast<uint32>(CompressedTexSubImage2DBucket::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<char*>(next_cmd), + reinterpret_cast<char*>(&cmd) + sizeof(cmd)); + EXPECT_EQ(static_cast<GLenum>(11), cmd.target); + EXPECT_EQ(static_cast<GLint>(12), cmd.level); + EXPECT_EQ(static_cast<GLint>(13), cmd.xoffset); + EXPECT_EQ(static_cast<GLint>(14), cmd.yoffset); + EXPECT_EQ(static_cast<GLsizei>(15), cmd.width); + EXPECT_EQ(static_cast<GLsizei>(16), cmd.height); + EXPECT_EQ(static_cast<GLenum>(17), cmd.format); + EXPECT_EQ(static_cast<GLuint>(18), cmd.bucket_id); +} + TEST(GLES2FormatTest, CopyTexImage2D) { CopyTexImage2D cmd = { { 0 } }; void* next_cmd = cmd.Set( diff --git a/gpu/command_buffer/common/gles2_cmd_id_test_autogen.h b/gpu/command_buffer/common/gles2_cmd_id_test_autogen.h index 7610364..a2890cc 100644 --- a/gpu/command_buffer/common/gles2_cmd_id_test_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_id_test_autogen.h @@ -65,10 +65,14 @@ TEST(GLES2CommandIdTest, CommandIdsMatch) { GLES2_CompressedTexImage2D_kCmdId_mismatch); COMPILE_ASSERT(CompressedTexImage2DImmediate::kCmdId == 281, GLES2_CompressedTexImage2DImmediate_kCmdId_mismatch); + COMPILE_ASSERT(CompressedTexImage2DBucket::kCmdId == 443, + GLES2_CompressedTexImage2DBucket_kCmdId_mismatch); COMPILE_ASSERT(CompressedTexSubImage2D::kCmdId == 282, GLES2_CompressedTexSubImage2D_kCmdId_mismatch); COMPILE_ASSERT(CompressedTexSubImage2DImmediate::kCmdId == 283, GLES2_CompressedTexSubImage2DImmediate_kCmdId_mismatch); + COMPILE_ASSERT(CompressedTexSubImage2DBucket::kCmdId == 444, + GLES2_CompressedTexSubImage2DBucket_kCmdId_mismatch); COMPILE_ASSERT(CopyTexImage2D::kCmdId == 284, GLES2_CopyTexImage2D_kCmdId_mismatch); COMPILE_ASSERT(CopyTexSubImage2D::kCmdId == 285, diff --git a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h index 2ffe5c6..9308fe0 100644 --- a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h @@ -195,6 +195,8 @@ OP(DeleteSharedIds) /* 440 */ \ OP(RegisterSharedIds) /* 441 */ \ OP(CommandBufferEnable) /* 442 */ \ + OP(CompressedTexImage2DBucket) /* 443 */ \ + OP(CompressedTexSubImage2DBucket) /* 444 */ \ enum CommandId { kStartPoint = cmd::kLastCommonId, // All GLES2 commands start after this. diff --git a/gpu/command_buffer/docs/gles2_cmd_format_docs.txt b/gpu/command_buffer/docs/gles2_cmd_format_docs.txt index bb0d7ed..ee6eb98 100644 --- a/gpu/command_buffer/docs/gles2_cmd_format_docs.txt +++ b/gpu/command_buffer/docs/gles2_cmd_format_docs.txt @@ -48,7 +48,7 @@ //! - A shared memory offset is out of range for the given shared memory //! - The size of the data a command would access in shared memory is out of //! range for the given shared memory buffer. -//! - A result (in the transfer buffer) is not initialized to the +//! - A result (in the transfer buffer) is not initialized to the //! failure case. For example, any command that returns a SizedResult //! will take a shared memory id and offset to where to store the result. //! That size field of the result must be set to 0 before issuing the @@ -507,6 +507,20 @@ struct CompressedTexImage2DImmediate { int32 imageSize; //!< GLsizei }; +//! Bucket version of command that corresponds to glCompressedTexImage2D. +struct CompressedTexImage2DBucket { + static const CommandId kCmdId = 443; + + CommandHeader header; + uint32 target; //!< GLenum + int32 level; //!< GLint + uint32 internalformat; //!< GLenum + int32 width; //!< GLsizei + int32 height; //!< GLsizei + int32 border; //!< GLint + uint32 bucket_id; //!< GLuint +}; + //! Command that corresponds to glCompressedTexSubImage2D. struct CompressedTexSubImage2D { static const CommandId kCmdId = 282; @@ -539,6 +553,21 @@ struct CompressedTexSubImage2DImmediate { int32 imageSize; //!< GLsizei }; +//! Bucket version of command that corresponds to glCompressedTexSubImage2D. +struct CompressedTexSubImage2DBucket { + static const CommandId kCmdId = 444; + + CommandHeader header; + uint32 target; //!< GLenum + int32 level; //!< GLint + int32 xoffset; //!< GLint + int32 yoffset; //!< GLint + int32 width; //!< GLsizei + int32 height; //!< GLsizei + uint32 format; //!< GLenum + uint32 bucket_id; //!< GLuint +}; + //! Command that corresponds to glCopyTexImage2D. struct CopyTexImage2D { static const CommandId kCmdId = 284; diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index d193c1e..9146c9a 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -3761,6 +3761,56 @@ error::Error GLES2DecoderImpl::HandleCompressedTexImage2DImmediate( target, level, internal_format, width, height, border, image_size, data); } +error::Error GLES2DecoderImpl::HandleCompressedTexImage2DBucket( + uint32 immediate_data_size, const gles2::CompressedTexImage2DBucket& c) { + GLenum target = static_cast<GLenum>(c.target); + GLint level = static_cast<GLint>(c.level); + GLenum internal_format = static_cast<GLenum>(c.internalformat); + GLsizei width = static_cast<GLsizei>(c.width); + GLsizei height = static_cast<GLsizei>(c.height); + GLint border = static_cast<GLint>(c.border); + Bucket* bucket = GetBucket(c.bucket_id); + return DoCompressedTexImage2D( + target, level, internal_format, width, height, border, + bucket->size(), bucket->GetData(0, bucket->size())); +} + +error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2DBucket( + uint32 immediate_data_size, + const gles2::CompressedTexSubImage2DBucket& c) { + GLenum target = static_cast<GLenum>(c.target); + GLint level = static_cast<GLint>(c.level); + GLint xoffset = static_cast<GLint>(c.xoffset); + GLint yoffset = static_cast<GLint>(c.yoffset); + GLsizei width = static_cast<GLsizei>(c.width); + GLsizei height = static_cast<GLsizei>(c.height); + GLenum format = static_cast<GLenum>(c.format); + Bucket* bucket = GetBucket(c.bucket_id); + uint32 data_size = bucket->size(); + GLsizei imageSize = data_size; + const void* data = bucket->GetData(0, data_size); + if (!ValidateGLenumTextureTarget(target)) { + SetGLError( + GL_INVALID_ENUM, "glCompressedTexSubImage2D: target GL_INVALID_ENUM"); + return error::kNoError; + } + if (width < 0) { + SetGLError(GL_INVALID_VALUE, "glCompressedTexSubImage2D: width < 0"); + return error::kNoError; + } + if (height < 0) { + SetGLError(GL_INVALID_VALUE, "glCompressedTexSubImage2D: height < 0"); + return error::kNoError; + } + if (imageSize < 0) { + SetGLError(GL_INVALID_VALUE, "glCompressedTexSubImage2D: imageSize < 0"); + return error::kNoError; + } + glCompressedTexSubImage2D( + target, level, xoffset, yoffset, width, height, format, imageSize, data); + return error::kNoError; +} + error::Error GLES2DecoderImpl::DoTexImage2D( GLenum target, GLint level, diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h index 1db0b6a..ef78ba5 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h @@ -292,6 +292,11 @@ error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2D( SetGLError(GL_INVALID_VALUE, "glCompressedTexSubImage2D: height < 0"); return error::kNoError; } + if (!ValidateGLenumCompressedTextureFormat(format)) { + SetGLError( + GL_INVALID_ENUM, "glCompressedTexSubImage2D: format GL_INVALID_ENUM"); + return error::kNoError; + } if (imageSize < 0) { SetGLError(GL_INVALID_VALUE, "glCompressedTexSubImage2D: imageSize < 0"); return error::kNoError; @@ -331,6 +336,11 @@ error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2DImmediate( SetGLError(GL_INVALID_VALUE, "glCompressedTexSubImage2D: height < 0"); return error::kNoError; } + if (!ValidateGLenumCompressedTextureFormat(format)) { + SetGLError( + GL_INVALID_ENUM, "glCompressedTexSubImage2D: format GL_INVALID_ENUM"); + return error::kNoError; + } if (imageSize < 0) { SetGLError(GL_INVALID_VALUE, "glCompressedTexSubImage2D: imageSize < 0"); return error::kNoError; diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h index 2fd1b54..4379a10 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h @@ -338,10 +338,12 @@ TEST_F(GLES2DecoderTest1, ColorMaskValidArgs) { // TODO(gman): CompressedTexImage2DImmediate +// TODO(gman): CompressedTexImage2DBucket // TODO(gman): CompressedTexSubImage2D // TODO(gman): CompressedTexSubImage2DImmediate +// TODO(gman): CompressedTexSubImage2DBucket TEST_F(GLES2DecoderTest1, CopyTexImage2DValidArgs) { EXPECT_CALL(*gl_, CopyTexImage2D(GL_TEXTURE_2D, 2, 3, 4, 5, 6, 7, 8)); @@ -1821,7 +1823,5 @@ TEST_F(GLES2DecoderTest1, GetTexParameterivInvalidArgs2_1) { // TODO(gman): GetUniformLocation -// TODO(gman): GetUniformLocationImmediate - #endif // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_1_AUTOGEN_H_ 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 456acdc..9e4fbdc 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 @@ -8,6 +8,8 @@ #ifndef GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_2_AUTOGEN_H_ #define GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_2_AUTOGEN_H_ +// TODO(gman): GetUniformLocationImmediate + // TODO(gman): GetUniformLocationBucket diff --git a/gpu/command_buffer/service/gles2_cmd_validation.cc b/gpu/command_buffer/service/gles2_cmd_validation.cc index 19af905..84e8a4b 100644 --- a/gpu/command_buffer/service/gles2_cmd_validation.cc +++ b/gpu/command_buffer/service/gles2_cmd_validation.cc @@ -9,6 +9,7 @@ // some of the GLenum definitions exist only in GLES2 and not in Desktop // GL. #include <GLES2/gl2types.h> +#include <GLES2/gl2ext.h> #include <GLES2/gles2_command_buffer.h> namespace gpu { diff --git a/gpu/command_buffer/service/gles2_cmd_validation_autogen.h b/gpu/command_buffer/service/gles2_cmd_validation_autogen.h index c7ec2aa..aea171b 100644 --- a/gpu/command_buffer/service/gles2_cmd_validation_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_validation_autogen.h @@ -14,6 +14,7 @@ bool ValidateGLenumBufferUsage(GLenum value); bool ValidateGLenumCapability(GLenum value); bool ValidateGLenumCmpFunction(GLenum value); bool ValidateGLenumCommandBufferState(GLenum value); +bool ValidateGLenumCompressedTextureFormat(GLenum value); bool ValidateGLenumDrawMode(GLenum value); bool ValidateGLenumDstBlendFactor(GLenum value); bool ValidateGLenumEquation(GLenum value); diff --git a/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h b/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h index 6f3b56c..0964c56 100644 --- a/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h @@ -91,6 +91,16 @@ bool ValidateGLenumCommandBufferState(GLenum value) { } } +bool ValidateGLenumCompressedTextureFormat(GLenum value) { + switch (value) { + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + return true; + default: + return false; + } +} + bool ValidateGLenumDrawMode(GLenum value) { switch (value) { case GL_POINTS: |