}
break;
case GL_BGRA_EXT:
+ case GL_BGRA8_EXT:
switch(type)
{
case GL_UNSIGNED_BYTE: return sw::FORMAT_A8R8G8B8;
case GL_RGBA_INTEGER:
return sw::FORMAT_A8B8G8R8UI;
case GL_BGRA_EXT:
+ case GL_BGRA8_EXT:
return sw::FORMAT_A8R8G8B8;
case GL_ALPHA:
case GL_ALPHA8_EXT:
case GL_SRGB8_ALPHA8:
case GL_RGBA: return sizeof(unsigned char) * 4;
case GL_RGBA_INTEGER: return sizeof(unsigned char) * 4;
- case GL_BGRA_EXT: return sizeof(unsigned char) * 4;
+ case GL_BGRA_EXT:
+ case GL_BGRA8_EXT: return sizeof(unsigned char)* 4;
default: UNREACHABLE(format);
}
break;
case GL_RGBA:
case GL_RGBA_INTEGER:
case GL_BGRA_EXT:
+ case GL_BGRA8_EXT:
LoadImageData<Bytes_4>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
break;
default: UNREACHABLE(format);
case GL_RGBA:
case GL_RGBA_INTEGER:
case GL_BGRA_EXT:
+ case GL_BGRA8_EXT:
LoadImageData<Bytes_4>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
break;
case GL_SRGB8:
case GL_RGBA:
case GL_RGBA_INTEGER:
case GL_BGRA_EXT:
+ case GL_BGRA8_EXT:
LoadImageData<Bytes_8>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
break;
default: UNREACHABLE(format);
case GL_RGBA:
case GL_RGBA_INTEGER:
case GL_BGRA_EXT:
+ case GL_BGRA8_EXT:
LoadImageData<Bytes_8>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
break;
case GL_DEPTH_COMPONENT:
case GL_RGBA:
case GL_RGBA_INTEGER:
case GL_BGRA_EXT:
+ case GL_BGRA8_EXT:
LoadImageData<Bytes_16>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
break;
default: UNREACHABLE(format);
case GL_RGBA:
case GL_RGBA_INTEGER:
case GL_BGRA_EXT:
+ case GL_BGRA8_EXT:
LoadImageData<Bytes_8>(xoffset, yoffset, zoffset, width, height, depth, inputPitch, inputHeight, getPitch(), getHeight(), input, buffer);
break;
case GL_DEPTH_COMPONENT16:
GLenum Texture2D::getFormat(GLenum target, GLint level) const\r
{\r
ASSERT(target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D);\r
- return image[level] ? image[level]->getFormat() : 0;\r
+ return image[level] ? image[level]->getFormat() : GL_NONE;\r
}\r
\r
GLenum Texture2D::getType(GLenum target, GLint level) const\r
{\r
ASSERT(target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D);\r
- return image[level] ? image[level]->getType() : 0;\r
+ return image[level] ? image[level]->getType() : GL_NONE;\r
}\r
\r
sw::Format Texture2D::getInternalFormat(GLenum target, GLint level) const\r
GLenum TextureCubeMap::getFormat(GLenum target, GLint level) const\r
{\r
int face = CubeFaceIndex(target);\r
- return image[face][level] ? image[face][level]->getFormat() : 0;\r
+ return image[face][level] ? image[face][level]->getFormat() : GL_NONE;\r
}\r
\r
GLenum TextureCubeMap::getType(GLenum target, GLint level) const\r
{\r
int face = CubeFaceIndex(target);\r
- return image[face][level] ? image[face][level]->getType() : 0;\r
+ return image[face][level] ? image[face][level]->getType() : GL_NONE;\r
}\r
\r
sw::Format TextureCubeMap::getInternalFormat(GLenum target, GLint level) const\r
GLenum Texture2D::getFormat(GLenum target, GLint level) const\r
{\r
ASSERT(target == GL_TEXTURE_2D);\r
- return image[level] ? image[level]->getFormat() : 0;\r
+ return image[level] ? image[level]->getFormat() : GL_NONE;\r
}\r
\r
GLenum Texture2D::getType(GLenum target, GLint level) const\r
{\r
ASSERT(target == GL_TEXTURE_2D);\r
- return image[level] ? image[level]->getType() : 0;\r
+ return image[level] ? image[level]->getType() : GL_NONE;\r
}\r
\r
sw::Format Texture2D::getInternalFormat(GLenum target, GLint level) const\r
GLenum Texture2D::getFormat(GLenum target, GLint level) const\r
{\r
ASSERT(target == GL_TEXTURE_2D);\r
- return image[level] ? image[level]->getFormat() : 0;\r
+ return image[level] ? image[level]->getFormat() : GL_NONE;\r
}\r
\r
GLenum Texture2D::getType(GLenum target, GLint level) const\r
{\r
ASSERT(target == GL_TEXTURE_2D);\r
- return image[level] ? image[level]->getType() : 0;\r
+ return image[level] ? image[level]->getType() : GL_NONE;\r
}\r
\r
sw::Format Texture2D::getInternalFormat(GLenum target, GLint level) const\r
image[level]->unbind(this);\r
}\r
\r
- image[level] = new egl::Image(this, width, height, format, GL_UNSIGNED_BYTE);\r
+ GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_UNSIGNED_BYTE);\r
+ image[level] = new egl::Image(this, width, height, sizedInternalFormat, GL_UNSIGNED_BYTE);\r
\r
if(!image[level])\r
{\r
image[level]->unbind(this);\r
}\r
\r
- image[level] = new egl::Image(this, width, height, format, GL_UNSIGNED_BYTE);\r
+ GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_UNSIGNED_BYTE);\r
+ image[level] = new egl::Image(this, width, height, sizedInternalFormat, GL_UNSIGNED_BYTE);\r
\r
if(!image[level])\r
{\r
sw::SliceRect sourceRect(x, y, x + width, y + height, 0);\r
sourceRect.clip(0, 0, renderbuffer->getWidth(), renderbuffer->getHeight());\r
\r
- copy(renderTarget, sourceRect, format, 0, 0, 0, image[level]);\r
+ copy(renderTarget, sourceRect, sizedInternalFormat, 0, 0, 0, image[level]);\r
}\r
\r
renderTarget->release();\r
image[face][level]->unbind(this);\r
}\r
\r
- image[face][level] = new egl::Image(this, width, height, format, GL_UNSIGNED_BYTE);\r
+ GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_UNSIGNED_BYTE);\r
+ image[face][level] = new egl::Image(this, width, height, sizedInternalFormat, GL_UNSIGNED_BYTE);\r
\r
if(!image[face][level])\r
{\r
image[face][level]->unbind(this);\r
}\r
\r
- image[face][level] = new egl::Image(this, width, height, format, GL_UNSIGNED_BYTE);\r
+ GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_UNSIGNED_BYTE);\r
+ image[face][level] = new egl::Image(this, width, height, sizedInternalFormat, GL_UNSIGNED_BYTE);\r
\r
if(!image[face][level])\r
{\r
sw::SliceRect sourceRect(x, y, x + width, y + height, 0);\r
sourceRect.clip(0, 0, renderbuffer->getWidth(), renderbuffer->getHeight());\r
\r
- copy(renderTarget, sourceRect, format, 0, 0, 0, image[face][level]);\r
+ copy(renderTarget, sourceRect, sizedInternalFormat, 0, 0, 0, image[face][level]);\r
}\r
\r
renderTarget->release();\r
GLenum Texture3D::getFormat(GLenum target, GLint level) const\r
{\r
ASSERT(target == getTarget());\r
- return image[level] ? image[level]->getFormat() : 0;\r
+ return image[level] ? image[level]->getFormat() : GL_NONE;\r
}\r
\r
GLenum Texture3D::getType(GLenum target, GLint level) const\r
{\r
ASSERT(target == getTarget());\r
- return image[level] ? image[level]->getType() : 0;\r
+ return image[level] ? image[level]->getType() : GL_NONE;\r
}\r
\r
sw::Format Texture3D::getInternalFormat(GLenum target, GLint level) const\r
image[level]->unbind(this);\r
}\r
\r
- image[level] = new egl::Image(this, width, height, depth, format, GL_UNSIGNED_BYTE);\r
+ GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_UNSIGNED_BYTE);\r
+ image[level] = new egl::Image(this, width, height, depth, sizedInternalFormat, GL_UNSIGNED_BYTE);\r
\r
if(!image[level])\r
{\r
\r
void Texture3D::subImage(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels)\r
{\r
- Texture::subImage(xoffset, yoffset, zoffset, width, height, format, depth, type, unpackInfo, pixels, image[level]);\r
+ Texture::subImage(xoffset, yoffset, zoffset, width, height, depth, format, type, unpackInfo, pixels, image[level]);\r
}\r
\r
void Texture3D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels)\r
image[level]->unbind(this);\r
}\r
\r
- image[level] = new egl::Image(this, width, height, depth, format, GL_UNSIGNED_BYTE);\r
+ GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_UNSIGNED_BYTE);\r
+ image[level] = new egl::Image(this, width, height, depth, sizedInternalFormat, GL_UNSIGNED_BYTE);\r
\r
if(!image[level])\r
{\r
sourceRect.clip(0, 0, renderbuffer->getWidth(), renderbuffer->getHeight());\r
for(GLint sliceZ = 0; sliceZ < depth; ++sliceZ, ++sourceRect.slice)\r
{\r
- copy(renderTarget, sourceRect, format, 0, 0, sliceZ, image[level]);\r
+ copy(renderTarget, sourceRect, sizedInternalFormat, 0, 0, sliceZ, image[level]);\r
}\r
}\r
\r
return true;\r
}\r
\r
-static bool validateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum format, es2::Texture *texture)\r
-{\r
- if(!texture)\r
- {\r
- return error(GL_INVALID_OPERATION, false);\r
- }\r
-\r
- if(compressed != texture->isCompressed(target, level))\r
- {\r
- return error(GL_INVALID_OPERATION, false);\r
- }\r
-\r
- if(format != GL_NONE && format != texture->getFormat(target, level))\r
- {\r
- return error(GL_INVALID_OPERATION, false);\r
- }\r
-\r
- if(compressed)\r
- {\r
- if((width % 4 != 0 && width != texture->getWidth(target, 0)) ||\r
- (height % 4 != 0 && height != texture->getHeight(target, 0)))\r
- {\r
- return error(GL_INVALID_OPERATION, false);\r
- }\r
- }\r
-\r
- if(xoffset + width > texture->getWidth(target, level) ||\r
- yoffset + height > texture->getHeight(target, level))\r
- {\r
- return error(GL_INVALID_VALUE, false);\r
- }\r
-\r
- return true;\r
-}\r
-\r
-static bool validateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLsizei depth, GLint xoffset, GLint yoffset, GLint zoffset, GLenum target, GLint level, GLenum format, es2::Texture *texture)\r
-{\r
- if(!texture)\r
- {\r
- return error(GL_INVALID_OPERATION, false);\r
- }\r
-\r
- if(compressed != texture->isCompressed(target, level))\r
- {\r
- return error(GL_INVALID_OPERATION, false);\r
- }\r
-\r
- if(format != GL_NONE && format != texture->getFormat(target, level))\r
- {\r
- return error(GL_INVALID_OPERATION, false);\r
- }\r
-\r
- if(compressed)\r
- {\r
- if((width % 4 != 0 && width != texture->getWidth(target, 0)) ||\r
- (height % 4 != 0 && height != texture->getHeight(target, 0)) ||\r
- (depth % 4 != 0 && depth != texture->getDepth(target, 0)))\r
- {\r
- return error(GL_INVALID_OPERATION, false);\r
- }\r
- }\r
-\r
- if(xoffset + width > texture->getWidth(target, level) ||\r
- yoffset + height > texture->getHeight(target, level) ||\r
- zoffset + depth > texture->getDepth(target, level))\r
- {\r
- return error(GL_INVALID_VALUE, false);\r
- }\r
-\r
- return true;\r
-}\r
-\r
static bool validateColorBufferFormat(GLenum textureFormat, GLenum colorbufferFormat)\r
{\r
- GLenum formatError = ValidateCompressedFormat(textureFormat, egl::getClientVersion(), false);\r
- if(formatError != GL_NONE)\r
+ GLenum validationError = ValidateCompressedFormat(textureFormat, egl::getClientVersion(), false);\r
+ if(validationError != GL_NONE)\r
{\r
- return error(formatError, false);\r
+ return error(validationError, false);\r
}\r
\r
// [OpenGL ES 2.0.24] table 3.9\r
return error(GL_INVALID_OPERATION);\r
default:\r
{\r
- GLenum formatError = ValidateCompressedFormat(internalformat, egl::getClientVersion(), true);\r
- if(formatError != GL_NONE)\r
+ GLenum validationError = ValidateCompressedFormat(internalformat, egl::getClientVersion(), true);\r
+ if(validationError != GL_NONE)\r
{\r
- return error(formatError);\r
+ return error(validationError);\r
}\r
}\r
break;\r
return error(GL_INVALID_VALUE);\r
}\r
\r
- GLenum formatError = ValidateCompressedFormat(format, egl::getClientVersion(), true);\r
- if(formatError != GL_NONE)\r
+ GLenum validationError = ValidateCompressedFormat(format, egl::getClientVersion(), true);\r
+ if(validationError != GL_NONE)\r
{\r
- return error(formatError);\r
+ return error(validationError);\r
}\r
\r
if(width == 0 || height == 0 || data == NULL)\r
return error(GL_INVALID_OPERATION);\r
}\r
\r
+ GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_NONE);\r
+\r
if(target == GL_TEXTURE_2D)\r
{\r
es2::Texture2D *texture = context->getTexture2D();\r
\r
- if(validateSubImageParams(true, width, height, xoffset, yoffset, target, level, format, texture))\r
+ GLenum validationError = ValidateSubImageParams(true, width, height, xoffset, yoffset, target, level, sizedInternalFormat, texture);\r
+\r
+ if(validationError == GL_NONE)\r
{\r
- texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data);\r
+ texture->subImageCompressed(level, xoffset, yoffset, width, height, sizedInternalFormat, imageSize, data);\r
+ }\r
+ else\r
+ {\r
+ return error(validationError);\r
}\r
}\r
else if(es2::IsCubemapTextureTarget(target))\r
{\r
es2::TextureCubeMap *texture = context->getTextureCubeMap();\r
\r
- if(validateSubImageParams(true, width, height, xoffset, yoffset, target, level, format, texture))\r
+ GLenum validationError = ValidateSubImageParams(true, width, height, xoffset, yoffset, target, level, sizedInternalFormat, texture);\r
+\r
+ if(validationError == GL_NONE)\r
+ {\r
+ texture->subImageCompressed(target, level, xoffset, yoffset, width, height, sizedInternalFormat, imageSize, data);\r
+ }\r
+ else\r
{\r
- texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data);\r
+ return error(validationError);\r
}\r
}\r
else UNREACHABLE(target);\r
}\r
else UNREACHABLE(target);\r
\r
- if(!validateSubImageParams(false, width, height, xoffset, yoffset, target, level, GL_NONE, texture))\r
+ GLenum validationError = ValidateSubImageParams(false, width, height, xoffset, yoffset, target, level, GL_NONE, texture);\r
+ if(validationError != GL_NONE)\r
{\r
- return;\r
+ return error(validationError);\r
}\r
\r
texture->copySubImage(target, level, xoffset, yoffset, 0, x, y, width, height, framebuffer);\r
}\r
}\r
\r
- GLenum formatError = ValidateCompressedFormat(format, clientVersion, false);\r
- if(formatError != GL_NONE)\r
+ GLenum validationError = ValidateCompressedFormat(format, clientVersion, false);\r
+ if(validationError != GL_NONE)\r
{\r
- return error(formatError);\r
+ return error(validationError);\r
}\r
\r
switch(format)\r
return error(GL_INVALID_ENUM);\r
}\r
\r
+ GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);\r
+\r
if(target == GL_TEXTURE_2D)\r
{\r
es2::Texture2D *texture = context->getTexture2D();\r
return error(GL_INVALID_OPERATION);\r
}\r
\r
- texture->setImage(level, width, height, format, type, context->getUnpackInfo(), pixels);\r
+ texture->setImage(level, width, height, sizedInternalFormat, type, context->getUnpackInfo(), pixels);\r
}\r
else\r
{\r
return error(GL_INVALID_OPERATION);\r
}\r
\r
- texture->setImage(target, level, width, height, format, type, context->getUnpackInfo(), pixels);\r
+ texture->setImage(target, level, width, height, sizedInternalFormat, type, context->getUnpackInfo(), pixels);\r
}\r
}\r
}\r
return error(GL_INVALID_VALUE);\r
}\r
\r
+ GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);\r
+\r
if(target == GL_TEXTURE_2D)\r
{\r
es2::Texture2D *texture = context->getTexture2D();\r
\r
- if(validateSubImageParams(false, width, height, xoffset, yoffset, target, level, format, texture))\r
+ GLenum validationError = ValidateSubImageParams(false, width, height, xoffset, yoffset, target, level, sizedInternalFormat, texture);\r
+\r
+ if(validationError == GL_NONE)\r
{\r
- texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackInfo(), pixels);\r
+ texture->subImage(level, xoffset, yoffset, width, height, sizedInternalFormat, type, context->getUnpackInfo(), pixels);\r
+ }\r
+ else\r
+ {\r
+ return error(validationError);\r
}\r
}\r
else if(es2::IsCubemapTextureTarget(target))\r
{\r
es2::TextureCubeMap *texture = context->getTextureCubeMap();\r
\r
- if(validateSubImageParams(false, width, height, xoffset, yoffset, target, level, format, texture))\r
+ GLenum validationError = ValidateSubImageParams(false, width, height, xoffset, yoffset, target, level, sizedInternalFormat, texture);\r
+\r
+ if(validationError == GL_NONE)\r
{\r
- texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackInfo(), pixels);\r
+ texture->subImage(target, level, xoffset, yoffset, width, height, sizedInternalFormat, type, context->getUnpackInfo(), pixels);\r
+ }\r
+ else\r
+ {\r
+ return error(validationError);\r
}\r
}\r
else UNREACHABLE(target);\r
return error(GL_INVALID_OPERATION);\r
}\r
\r
- texture->setImage(level, width, height, depth, internalformat, type, context->getUnpackInfo(), pixels);\r
+ texture->setImage(level, width, height, depth, GetSizedInternalFormat(internalformat, type), type, context->getUnpackInfo(), pixels);\r
}\r
}\r
\r
{\r
es2::Texture3D *texture = context->getTexture3D();\r
\r
- if(validateSubImageParams(false, width, height, depth, xoffset, yoffset, zoffset, target, level, format, texture))\r
+ GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);\r
+\r
+ GLenum validationError = ValidateSubImageParams(false, width, height, depth, xoffset, yoffset, zoffset, target, level, sizedInternalFormat, texture);\r
+ if(validationError == GL_NONE)\r
{\r
- texture->subImage(level, xoffset, yoffset, zoffset, width, height, depth, format, type, context->getUnpackInfo(), pixels);\r
+ texture->subImage(level, xoffset, yoffset, zoffset, width, height, depth, sizedInternalFormat, type, context->getUnpackInfo(), pixels);\r
+ }\r
+ else\r
+ {\r
+ return error(validationError);\r
}\r
}\r
}\r
\r
es2::Texture3D *texture = context->getTexture3D();\r
\r
- if(!validateSubImageParams(false, width, height, 1, xoffset, yoffset, zoffset, target, level, GL_NONE, texture))\r
+ GLenum validationError = ValidateSubImageParams(false, width, height, 1, xoffset, yoffset, zoffset, target, level, GL_NONE, texture);\r
+\r
+ if(validationError != GL_NONE)\r
{\r
- return;\r
+ return error(validationError);\r
}\r
\r
texture->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, framebuffer);\r
return error(GL_INVALID_OPERATION);\r
default:\r
{\r
- GLenum formatError = ValidateCompressedFormat(internalformat, egl::getClientVersion(), true);\r
- if(formatError != GL_NONE)\r
+ GLenum validationError = ValidateCompressedFormat(internalformat, egl::getClientVersion(), true);\r
+ if(validationError != GL_NONE)\r
{\r
- return error(formatError);\r
+ return error(validationError);\r
}\r
}\r
}\r
return error(GL_INVALID_VALUE);\r
}\r
\r
- GLenum formatError = ValidateCompressedFormat(format, egl::getClientVersion(), true);\r
- if(formatError != GL_NONE)\r
+ GLenum validationError = ValidateCompressedFormat(format, egl::getClientVersion(), true);\r
+ if(validationError != GL_NONE)\r
{\r
- return error(formatError);\r
+ return error(validationError);\r
}\r
\r
if(width == 0 || height == 0 || depth == 0 || data == NULL)\r
return true;\r
}\r
\r
-static bool validateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLsizei depth, GLint xoffset, GLint yoffset, GLint zoffset, GLenum target, GLint level, GLenum format, es2::Texture *texture)\r
-{\r
- if(!texture)\r
- {\r
- return error(GL_INVALID_OPERATION, false);\r
- }\r
-\r
- if(compressed != texture->isCompressed(target, level))\r
- {\r
- return error(GL_INVALID_OPERATION, false);\r
- }\r
-\r
- if(format != GL_NONE && format != texture->getFormat(target, level))\r
- {\r
- return error(GL_INVALID_OPERATION, false);\r
- }\r
-\r
- if(compressed)\r
- {\r
- if((width % 4 != 0 && width != texture->getWidth(target, 0)) ||\r
- (height % 4 != 0 && height != texture->getHeight(target, 0)) ||\r
- (depth % 4 != 0 && depth != texture->getDepth(target, 0)))\r
- {\r
- return error(GL_INVALID_OPERATION, false);\r
- }\r
- }\r
-\r
- if(xoffset + width > texture->getWidth(target, level) ||\r
- yoffset + height > texture->getHeight(target, level) ||\r
- zoffset + depth > texture->getDepth(target, level))\r
- {\r
- return error(GL_INVALID_VALUE, false);\r
- }\r
-\r
- return true;\r
-}\r
\r
static bool validateColorBufferFormat(GLenum textureFormat, GLenum colorbufferFormat)\r
{\r
- GLenum formatError = ValidateCompressedFormat(textureFormat, egl::getClientVersion(), false);\r
- if(formatError != GL_NONE)\r
+ GLenum validationError = ValidateCompressedFormat(textureFormat, egl::getClientVersion(), false);\r
+ if(validationError != GL_NONE)\r
{\r
- return error(formatError, false);\r
+ return error(validationError, false);\r
}\r
\r
switch(textureFormat)\r
return error(GL_INVALID_OPERATION);\r
}\r
\r
- texture->setImage(level, width, height, depth, internalformat, type, context->getUnpackInfo(), pixels);\r
+ texture->setImage(level, width, height, depth, GetSizedInternalFormat(internalformat, type), type, context->getUnpackInfo(), pixels);\r
}\r
}\r
\r
{\r
es2::Texture3D *texture = (target == GL_TEXTURE_3D) ? context->getTexture3D() : context->getTexture2DArray();\r
\r
- if(validateSubImageParams(false, width, height, depth, xoffset, yoffset, zoffset, target, level, format, texture))\r
+ GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);\r
+\r
+ GLenum validationError = ValidateSubImageParams(false, width, height, depth, xoffset, yoffset, zoffset, target, level, sizedInternalFormat, texture);\r
+ if(validationError == GL_NONE)\r
{\r
- texture->subImage(level, xoffset, yoffset, zoffset, width, height, depth, format, type, context->getUnpackInfo(), pixels);\r
+ texture->subImage(level, xoffset, yoffset, zoffset, width, height, depth, sizedInternalFormat, type, context->getUnpackInfo(), pixels);\r
+ }\r
+ else\r
+ {\r
+ return error(validationError);\r
}\r
}\r
}\r
GLenum colorbufferFormat = source->getFormat();\r
es2::Texture3D *texture = (target == GL_TEXTURE_3D) ? context->getTexture3D() : context->getTexture2DArray();\r
\r
- if(!validateSubImageParams(false, width, height, 1, xoffset, yoffset, zoffset, target, level, GL_NONE, texture))\r
+ GLenum validationError = ValidateSubImageParams(false, width, height, 1, xoffset, yoffset, zoffset, target, level, GL_NONE, texture);\r
+ if(validationError != GL_NONE)\r
{\r
- return;\r
+ return error(validationError);\r
}\r
\r
GLenum textureFormat = texture->getFormat(target, level);\r
return error(GL_INVALID_OPERATION);\r
default:\r
{\r
- GLenum formatError = ValidateCompressedFormat(internalformat, egl::getClientVersion(), true);\r
- if(formatError != GL_NONE)\r
+ GLenum validationError = ValidateCompressedFormat(internalformat, egl::getClientVersion(), true);\r
+ if(validationError != GL_NONE)\r
{\r
- return error(formatError);\r
+ return error(validationError);\r
}\r
}\r
}\r
return error(GL_INVALID_VALUE);\r
}\r
\r
- GLenum formatError = ValidateCompressedFormat(format, egl::getClientVersion(), true);\r
- if(formatError != GL_NONE)\r
+ GLenum validationError = ValidateCompressedFormat(format, egl::getClientVersion(), true);\r
+ if(validationError != GL_NONE)\r
{\r
- return error(formatError);\r
+ return error(validationError);\r
}\r
\r
if(width == 0 || height == 0 || depth == 0 || data == NULL)\r
\r
for(int level = 0; level < levels; ++level)\r
{\r
- texture->setImage(level, width, height, internalformat, type, context->getUnpackInfo(), NULL);\r
+ texture->setImage(level, width, height, GetSizedInternalFormat(internalformat, type), type, context->getUnpackInfo(), NULL);\r
width = std::max(1, (width / 2));\r
height = std::max(1, (height / 2));\r
}\r
{\r
for(int face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; ++face)\r
{\r
- texture->setImage(face, level, width, height, internalformat, type, context->getUnpackInfo(), NULL);\r
+ texture->setImage(face, level, width, height, GetSizedInternalFormat(internalformat, type), type, context->getUnpackInfo(), NULL);\r
}\r
width = std::max(1, (width / 2));\r
height = std::max(1, (height / 2));\r
\r
for(int level = 0; level < levels; ++level)\r
{\r
- texture->setImage(level, width, height, depth, internalformat, type, context->getUnpackInfo(), NULL);\r
+ texture->setImage(level, width, height, depth, GetSizedInternalFormat(internalformat, type), type, context->getUnpackInfo(), NULL);\r
width = std::max(1, (width / 2));\r
height = std::max(1, (height / 2));\r
depth = std::max(1, (depth / 2));\r
{\r
for(int face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; ++face)\r
{\r
- texture->setImage(level, width, height, depth, internalformat, type, context->getUnpackInfo(), NULL);\r
+ texture->setImage(level, width, height, depth, GetSizedInternalFormat(internalformat, type), type, context->getUnpackInfo(), NULL);\r
}\r
width = std::max(1, (width / 2));\r
height = std::max(1, (height / 2));\r
\r
namespace es2\r
{\r
+ // ES2 requires that format is equal to internal format at all glTex*Image2D entry points and the implementation\r
+ // can decide the true, sized, internal format. The ES2FormatMap determines the internal format for all valid\r
+ // format and type combinations.\r
+\r
+ typedef std::pair<GLenum, GLenum> FormatTypePair;\r
+ typedef std::pair<FormatTypePair, GLenum> FormatPair;\r
+ typedef std::map<FormatTypePair, GLenum> FormatMap;\r
+\r
+ // A helper function to insert data into the format map with fewer characters.\r
+ static inline void InsertFormatMapping(FormatMap *map, GLenum format, GLenum type, GLenum internalFormat)\r
+ {\r
+ map->insert(FormatPair(FormatTypePair(format, type), internalFormat));\r
+ }\r
+\r
+ FormatMap BuildFormatMap()\r
+ {\r
+ static const GLenum GL_BGRA4_ANGLEX = 0x6ABC;\r
+ static const GLenum GL_BGR5_A1_ANGLEX = 0x6ABD;\r
+\r
+ FormatMap map;\r
+\r
+ // | Format | Type | Internal format |\r
+ InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA8);\r
+ InsertFormatMapping(&map, GL_RGBA, GL_BYTE, GL_RGBA8_SNORM);\r
+ InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4);\r
+ InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1);\r
+ InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, GL_RGB10_A2);\r
+ InsertFormatMapping(&map, GL_RGBA, GL_FLOAT, GL_RGBA32F);\r
+ InsertFormatMapping(&map, GL_RGBA, GL_HALF_FLOAT, GL_RGBA16F);\r
+ InsertFormatMapping(&map, GL_RGBA, GL_HALF_FLOAT_OES, GL_RGBA16F);\r
+\r
+ InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, GL_RGBA8UI);\r
+ InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_BYTE, GL_RGBA8I);\r
+ InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, GL_RGBA16UI);\r
+ InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_SHORT, GL_RGBA16I);\r
+ InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_INT, GL_RGBA32UI);\r
+ InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_INT, GL_RGBA32I);\r
+ InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV, GL_RGB10_A2UI);\r
+\r
+ InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_BYTE, GL_RGB8);\r
+ InsertFormatMapping(&map, GL_RGB, GL_BYTE, GL_RGB8_SNORM);\r
+ InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, GL_RGB565);\r
+ InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, GL_R11F_G11F_B10F);\r
+ InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV, GL_RGB9_E5);\r
+ InsertFormatMapping(&map, GL_RGB, GL_FLOAT, GL_RGB32F);\r
+ InsertFormatMapping(&map, GL_RGB, GL_HALF_FLOAT, GL_RGB16F);\r
+ InsertFormatMapping(&map, GL_RGB, GL_HALF_FLOAT_OES, GL_RGB16F);\r
+\r
+ InsertFormatMapping(&map, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, GL_RGB8UI);\r
+ InsertFormatMapping(&map, GL_RGB_INTEGER, GL_BYTE, GL_RGB8I);\r
+ InsertFormatMapping(&map, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, GL_RGB16UI);\r
+ InsertFormatMapping(&map, GL_RGB_INTEGER, GL_SHORT, GL_RGB16I);\r
+ InsertFormatMapping(&map, GL_RGB_INTEGER, GL_UNSIGNED_INT, GL_RGB32UI);\r
+ InsertFormatMapping(&map, GL_RGB_INTEGER, GL_INT, GL_RGB32I);\r
+\r
+ InsertFormatMapping(&map, GL_RG, GL_UNSIGNED_BYTE, GL_RG8);\r
+ InsertFormatMapping(&map, GL_RG, GL_BYTE, GL_RG8_SNORM);\r
+ InsertFormatMapping(&map, GL_RG, GL_FLOAT, GL_RG32F);\r
+ InsertFormatMapping(&map, GL_RG, GL_HALF_FLOAT, GL_RG16F);\r
+ InsertFormatMapping(&map, GL_RG, GL_HALF_FLOAT_OES, GL_RG16F);\r
+\r
+ InsertFormatMapping(&map, GL_RG_INTEGER, GL_UNSIGNED_BYTE, GL_RG8UI);\r
+ InsertFormatMapping(&map, GL_RG_INTEGER, GL_BYTE, GL_RG8I);\r
+ InsertFormatMapping(&map, GL_RG_INTEGER, GL_UNSIGNED_SHORT, GL_RG16UI);\r
+ InsertFormatMapping(&map, GL_RG_INTEGER, GL_SHORT, GL_RG16I);\r
+ InsertFormatMapping(&map, GL_RG_INTEGER, GL_UNSIGNED_INT, GL_RG32UI);\r
+ InsertFormatMapping(&map, GL_RG_INTEGER, GL_INT, GL_RG32I);\r
+\r
+ InsertFormatMapping(&map, GL_RED, GL_UNSIGNED_BYTE, GL_R8);\r
+ InsertFormatMapping(&map, GL_RED, GL_BYTE, GL_R8_SNORM);\r
+ InsertFormatMapping(&map, GL_RED, GL_FLOAT, GL_R32F);\r
+ InsertFormatMapping(&map, GL_RED, GL_HALF_FLOAT, GL_R16F);\r
+ InsertFormatMapping(&map, GL_RED, GL_HALF_FLOAT_OES, GL_R16F);\r
+\r
+ InsertFormatMapping(&map, GL_RED_INTEGER, GL_UNSIGNED_BYTE, GL_R8UI);\r
+ InsertFormatMapping(&map, GL_RED_INTEGER, GL_BYTE, GL_R8I);\r
+ InsertFormatMapping(&map, GL_RED_INTEGER, GL_UNSIGNED_SHORT, GL_R16UI);\r
+ InsertFormatMapping(&map, GL_RED_INTEGER, GL_SHORT, GL_R16I);\r
+ InsertFormatMapping(&map, GL_RED_INTEGER, GL_UNSIGNED_INT, GL_R32UI);\r
+ InsertFormatMapping(&map, GL_RED_INTEGER, GL_INT, GL_R32I);\r
+\r
+ InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, GL_LUMINANCE8_ALPHA8_EXT);\r
+ InsertFormatMapping(&map, GL_LUMINANCE, GL_UNSIGNED_BYTE, GL_LUMINANCE8_EXT);\r
+ InsertFormatMapping(&map, GL_ALPHA, GL_UNSIGNED_BYTE, GL_ALPHA8_EXT);\r
+ InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_FLOAT, GL_LUMINANCE_ALPHA32F_EXT);\r
+ InsertFormatMapping(&map, GL_LUMINANCE, GL_FLOAT, GL_LUMINANCE32F_EXT);\r
+ InsertFormatMapping(&map, GL_ALPHA, GL_FLOAT, GL_ALPHA32F_EXT);\r
+ InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT, GL_LUMINANCE_ALPHA16F_EXT);\r
+ InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES, GL_LUMINANCE_ALPHA16F_EXT);\r
+ InsertFormatMapping(&map, GL_LUMINANCE, GL_HALF_FLOAT, GL_LUMINANCE16F_EXT);\r
+ InsertFormatMapping(&map, GL_LUMINANCE, GL_HALF_FLOAT_OES, GL_LUMINANCE16F_EXT);\r
+ InsertFormatMapping(&map, GL_ALPHA, GL_HALF_FLOAT, GL_ALPHA16F_EXT);\r
+ InsertFormatMapping(&map, GL_ALPHA, GL_HALF_FLOAT_OES, GL_ALPHA16F_EXT);\r
+\r
+ InsertFormatMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_BYTE, GL_BGRA8_EXT);\r
+ InsertFormatMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, GL_BGRA4_ANGLEX);\r
+ InsertFormatMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, GL_BGR5_A1_ANGLEX);\r
+\r
+ InsertFormatMapping(&map, GL_SRGB_EXT, GL_UNSIGNED_BYTE, GL_SRGB8);\r
+ InsertFormatMapping(&map, GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE, GL_SRGB8_ALPHA8);\r
+\r
+ InsertFormatMapping(&map, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGB_S3TC_DXT1_EXT);\r
+ InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT);\r
+ InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE);\r
+ InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE);\r
+\r
+ InsertFormatMapping(&map, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, GL_DEPTH_COMPONENT16);\r
+ InsertFormatMapping(&map, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_DEPTH_COMPONENT32_OES);\r
+ InsertFormatMapping(&map, GL_DEPTH_COMPONENT, GL_FLOAT, GL_DEPTH_COMPONENT32F);\r
+\r
+ InsertFormatMapping(&map, GL_STENCIL, GL_UNSIGNED_BYTE, GL_STENCIL_INDEX8);\r
+\r
+ InsertFormatMapping(&map, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_DEPTH24_STENCIL8);\r
+ InsertFormatMapping(&map, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, GL_DEPTH32F_STENCIL8);\r
+\r
+ return map;\r
+ }\r
+\r
+ GLenum GetSizedInternalFormat(GLenum internalFormat, GLenum type)\r
+ {\r
+ switch(internalFormat)\r
+ {\r
+ case GL_ALPHA:\r
+ case GL_LUMINANCE:\r
+ case GL_LUMINANCE_ALPHA:\r
+ case GL_RED:\r
+ case GL_RG:\r
+ case GL_RGB:\r
+ case GL_RGBA:\r
+ case GL_RED_INTEGER:\r
+ case GL_RG_INTEGER:\r
+ case GL_RGB_INTEGER:\r
+ case GL_RGBA_INTEGER:\r
+ case GL_BGRA_EXT:\r
+ case GL_DEPTH_COMPONENT:\r
+ case GL_DEPTH_STENCIL:\r
+ case GL_SRGB_EXT:\r
+ case GL_SRGB_ALPHA_EXT:\r
+ {\r
+ static const FormatMap formatMap = BuildFormatMap();\r
+ FormatMap::const_iterator iter = formatMap.find(FormatTypePair(internalFormat, type));\r
+ return (iter != formatMap.end()) ? iter->second : GL_NONE;\r
+ }\r
+ default:\r
+ return internalFormat;\r
+ }\r
+ }\r
+\r
unsigned int UniformComponentCount(GLenum type)\r
{\r
switch(type)\r
}\r
}\r
\r
+ GLenum ValidateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum sizedInternalFormat, Texture *texture)\r
+ {\r
+ if(!texture)\r
+ {\r
+ return GL_INVALID_OPERATION;\r
+ }\r
+\r
+ if(compressed != texture->isCompressed(target, level))\r
+ {\r
+ return GL_INVALID_OPERATION;\r
+ }\r
+\r
+ if(sizedInternalFormat != GL_NONE && sizedInternalFormat != texture->getFormat(target, level))\r
+ {\r
+ return GL_INVALID_OPERATION;\r
+ }\r
+\r
+ if(compressed)\r
+ {\r
+ if((width % 4 != 0 && width != texture->getWidth(target, 0)) ||\r
+ (height % 4 != 0 && height != texture->getHeight(target, 0)))\r
+ {\r
+ return GL_INVALID_OPERATION;\r
+ }\r
+ }\r
+\r
+ if(xoffset + width > texture->getWidth(target, level) ||\r
+ yoffset + height > texture->getHeight(target, level))\r
+ {\r
+ return GL_INVALID_VALUE;\r
+ }\r
+\r
+ return GL_NONE;\r
+ }\r
+\r
+ GLenum ValidateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLsizei depth, GLint xoffset, GLint yoffset, GLint zoffset, GLenum target, GLint level, GLenum sizedInternalFormat, Texture *texture)\r
+ {\r
+ if(!texture)\r
+ {\r
+ return GL_INVALID_OPERATION;\r
+ }\r
+\r
+ if(compressed != texture->isCompressed(target, level))\r
+ {\r
+ return GL_INVALID_OPERATION;\r
+ }\r
+\r
+ if(sizedInternalFormat != GL_NONE && sizedInternalFormat != GetSizedInternalFormat(texture->getFormat(target, level), texture->getType(target, level)))\r
+ {\r
+ return GL_INVALID_OPERATION;\r
+ }\r
+\r
+ if(compressed)\r
+ {\r
+ if((width % 4 != 0 && width != texture->getWidth(target, 0)) ||\r
+ (height % 4 != 0 && height != texture->getHeight(target, 0)) ||\r
+ (depth % 4 != 0 && depth != texture->getDepth(target, 0)))\r
+ {\r
+ return GL_INVALID_OPERATION;\r
+ }\r
+ }\r
+\r
+ if(xoffset + width > texture->getWidth(target, level) ||\r
+ yoffset + height > texture->getHeight(target, level) ||\r
+ zoffset + depth > texture->getDepth(target, level))\r
+ {\r
+ return GL_INVALID_VALUE;\r
+ }\r
+\r
+ return GL_NONE;\r
+ }\r
+\r
bool ValidReadPixelsFormatType(GLenum internalFormat, GLenum internalType, GLenum format, GLenum type, egl::GLint clientVersion)\r
{\r
switch(format)\r
bool IsStencilTexture(GLenum format)\r
{\r
return format == GL_STENCIL_INDEX_OES ||\r
- format == GL_DEPTH_STENCIL_OES;\r
+ format == GL_DEPTH_STENCIL_OES ||\r
+ format == GL_DEPTH24_STENCIL8 ||\r
+ format == GL_DEPTH32F_STENCIL8;\r
}\r
\r
bool IsCubemapTextureTarget(GLenum target)\r
GLint floatToInt(GLfloat value);\r
\r
bool IsCompressed(GLenum format, egl::GLint clientVersion);\r
+ GLenum GetSizedInternalFormat(GLenum internalFormat, GLenum type);\r
GLenum ValidateCompressedFormat(GLenum format, egl::GLint clientVersion, bool expectCompressedFormats);\r
+ GLenum ValidateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum sizedInternalFormat, Texture *texture);\r
+ GLenum ValidateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLsizei depth, GLint xoffset, GLint yoffset, GLint zoffset, GLenum target, GLint level, GLenum sizedInternalFormat, Texture *texture);\r
bool ValidReadPixelsFormatType(GLenum internalFormat, GLenum internalType, GLenum format, GLenum type, egl::GLint clientVersion);\r
bool IsDepthTexture(GLenum format);\r
bool IsStencilTexture(GLenum format);\r