Commit 6f38f823 by Jamie Madill

Fix up some validation bugs in Texture functions.

In several places we weren't handling certain errors, or were returning the wrong error code. Several dEQP negative API tests are affected in functional.negative_api.texture. BUG=angle:571 Change-Id: I19d7250aab2c15d709fd591b8df90ce883f9ac60 Reviewed-on: https://chromium-review.googlesource.com/201250Reviewed-by: 's avatarShannon Woods <shannonwoods@chromium.org> Tested-by: 's avatarJamie Madill <jmadill@chromium.org>
parent bfa91f47
...@@ -844,14 +844,14 @@ void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum interna ...@@ -844,14 +844,14 @@ void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum interna
{ {
if (context->getClientVersion() < 3 && if (context->getClientVersion() < 3 &&
!ValidateES2TexImageParameters(context, target, level, internalformat, true, false, !ValidateES2TexImageParameters(context, target, level, internalformat, true, false,
0, 0, width, height, 0, GL_NONE, GL_NONE, data)) 0, 0, width, height, border, GL_NONE, GL_NONE, data))
{ {
return; return;
} }
if (context->getClientVersion() >= 3 && if (context->getClientVersion() >= 3 &&
!ValidateES3TexImageParameters(context, target, level, internalformat, true, false, !ValidateES3TexImageParameters(context, target, level, internalformat, true, false,
0, 0, 0, width, height, 1, 0, GL_NONE, GL_NONE, data)) 0, 0, 0, width, height, 1, border, GL_NONE, GL_NONE, data))
{ {
return; return;
} }
...@@ -6118,7 +6118,7 @@ void __stdcall glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GL ...@@ -6118,7 +6118,7 @@ void __stdcall glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GL
return gl::error(GL_INVALID_OPERATION); return gl::error(GL_INVALID_OPERATION);
} }
if (!ValidateES3CopyTexImageParameters(context, target, level, GL_NONE, false, xoffset, yoffset, zoffset, if (!ValidateES3CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset, yoffset, zoffset,
x, y, width, height, 0)) x, y, width, height, 0))
{ {
return; return;
......
...@@ -1147,6 +1147,7 @@ bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLi ...@@ -1147,6 +1147,7 @@ bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLi
GLint textureLevelWidth = 0; GLint textureLevelWidth = 0;
GLint textureLevelHeight = 0; GLint textureLevelHeight = 0;
GLint textureLevelDepth = 0; GLint textureLevelDepth = 0;
int maxDimension = 0;
switch (target) switch (target)
{ {
...@@ -1162,6 +1163,7 @@ bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLi ...@@ -1162,6 +1163,7 @@ bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLi
textureLevelHeight = texture2d->getHeight(level); textureLevelHeight = texture2d->getHeight(level);
textureLevelDepth = 1; textureLevelDepth = 1;
texture = texture2d; texture = texture2d;
maxDimension = context->getMaximum2DTextureDimension();
} }
} }
break; break;
...@@ -1183,6 +1185,7 @@ bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLi ...@@ -1183,6 +1185,7 @@ bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLi
textureLevelHeight = textureCube->getHeight(target, level); textureLevelHeight = textureCube->getHeight(target, level);
textureLevelDepth = 1; textureLevelDepth = 1;
texture = textureCube; texture = textureCube;
maxDimension = context->getMaximumCubeTextureDimension();
} }
} }
break; break;
...@@ -1199,6 +1202,7 @@ bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLi ...@@ -1199,6 +1202,7 @@ bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLi
textureLevelHeight = texture2dArray->getHeight(level); textureLevelHeight = texture2dArray->getHeight(level);
textureLevelDepth = texture2dArray->getLayers(level); textureLevelDepth = texture2dArray->getLayers(level);
texture = texture2dArray; texture = texture2dArray;
maxDimension = context->getMaximum2DTextureDimension();
} }
} }
break; break;
...@@ -1215,6 +1219,7 @@ bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLi ...@@ -1215,6 +1219,7 @@ bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLi
textureLevelHeight = texture3d->getHeight(level); textureLevelHeight = texture3d->getHeight(level);
textureLevelDepth = texture3d->getDepth(level); textureLevelDepth = texture3d->getDepth(level);
texture = texture3d; texture = texture3d;
maxDimension = context->getMaximum3DTextureDimension();
} }
} }
break; break;
...@@ -1260,6 +1265,24 @@ bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLi ...@@ -1260,6 +1265,24 @@ bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLi
return gl::error(GL_INVALID_VALUE, false); return gl::error(GL_INVALID_VALUE, false);
} }
} }
else
{
if (IsCubemapTextureTarget(target) && width != height)
{
return gl::error(GL_INVALID_VALUE, false);
}
if (!IsValidInternalFormat(internalformat, context))
{
return gl::error(GL_INVALID_ENUM, false);
}
int maxLevelDimension = (maxDimension >> level);
if (static_cast<int>(width) > maxLevelDimension || static_cast<int>(height) > maxLevelDimension)
{
return gl::error(GL_INVALID_VALUE, false);
}
}
*textureFormatOut = textureInternalFormat; *textureFormatOut = textureInternalFormat;
return true; return true;
......
...@@ -108,6 +108,11 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le ...@@ -108,6 +108,11 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le
GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
GLint border, GLenum format, GLenum type, const GLvoid *pixels) GLint border, GLenum format, GLenum type, const GLvoid *pixels)
{ {
if (!ValidTexture2DDestinationTarget(context, target))
{
return gl::error(GL_INVALID_ENUM, false);
}
if (!ValidImageSize(context, target, level, width, height, 1)) if (!ValidImageSize(context, target, level, width, height, 1))
{ {
return gl::error(GL_INVALID_VALUE, false); return gl::error(GL_INVALID_VALUE, false);
......
...@@ -25,6 +25,11 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le ...@@ -25,6 +25,11 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le
GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
GLint border, GLenum format, GLenum type, const GLvoid *pixels) GLint border, GLenum format, GLenum type, const GLvoid *pixels)
{ {
if (!ValidTexture2DDestinationTarget(context, target))
{
return gl::error(GL_INVALID_ENUM, false);
}
// Validate image size // Validate image size
if (!ValidImageSize(context, target, level, width, height, depth)) if (!ValidImageSize(context, target, level, width, height, depth))
{ {
...@@ -37,6 +42,14 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le ...@@ -37,6 +42,14 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le
return gl::error(GL_INVALID_VALUE, false); return gl::error(GL_INVALID_VALUE, false);
} }
if (xoffset < 0 || yoffset < 0 || zoffset < 0 ||
std::numeric_limits<GLsizei>::max() - xoffset < width ||
std::numeric_limits<GLsizei>::max() - yoffset < height ||
std::numeric_limits<GLsizei>::max() - zoffset < depth)
{
return gl::error(GL_INVALID_VALUE, false);
}
gl::Texture *texture = NULL; gl::Texture *texture = NULL;
bool textureCompressed = false; bool textureCompressed = false;
GLenum textureInternalFormat = GL_NONE; GLenum textureInternalFormat = GL_NONE;
...@@ -156,6 +169,7 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le ...@@ -156,6 +169,7 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le
// Validate texture formats // Validate texture formats
GLenum actualInternalFormat = isSubImage ? textureInternalFormat : internalformat; GLenum actualInternalFormat = isSubImage ? textureInternalFormat : internalformat;
int clientVersion = context->getClientVersion();
if (isCompressed) if (isCompressed)
{ {
if (!ValidCompressedImageSize(context, actualInternalFormat, width, height)) if (!ValidCompressedImageSize(context, actualInternalFormat, width, height))
...@@ -163,7 +177,7 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le ...@@ -163,7 +177,7 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le
return gl::error(GL_INVALID_OPERATION, false); return gl::error(GL_INVALID_OPERATION, false);
} }
if (!gl::IsFormatCompressed(actualInternalFormat, context->getClientVersion())) if (!gl::IsFormatCompressed(actualInternalFormat, clientVersion))
{ {
return gl::error(GL_INVALID_ENUM, false); return gl::error(GL_INVALID_ENUM, false);
} }
...@@ -175,14 +189,16 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le ...@@ -175,14 +189,16 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le
} }
else else
{ {
// Note: dEQP 2013.4 expects an INVALID_VALUE error for TexImage3D with an invalid
// internal format. (dEQP-GLES3.functional.negative_api.texture.teximage3d)
if (!gl::IsValidInternalFormat(actualInternalFormat, context) || if (!gl::IsValidInternalFormat(actualInternalFormat, context) ||
!gl::IsValidFormat(format, context->getClientVersion()) || !gl::IsValidFormat(format, clientVersion) ||
!gl::IsValidType(type, context->getClientVersion())) !gl::IsValidType(type, clientVersion))
{ {
return gl::error(GL_INVALID_ENUM, false); return gl::error(GL_INVALID_ENUM, false);
} }
if (!gl::IsValidFormatCombination(actualInternalFormat, format, type, context->getClientVersion())) if (!gl::IsValidFormatCombination(actualInternalFormat, format, type, clientVersion))
{ {
return gl::error(GL_INVALID_OPERATION, false); return gl::error(GL_INVALID_OPERATION, false);
} }
...@@ -244,7 +260,11 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le ...@@ -244,7 +260,11 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le
size_t widthSize = static_cast<size_t>(width); size_t widthSize = static_cast<size_t>(width);
size_t heightSize = static_cast<size_t>(height); size_t heightSize = static_cast<size_t>(height);
size_t depthSize = static_cast<size_t>(depth); size_t depthSize = static_cast<size_t>(depth);
size_t pixelBytes = static_cast<size_t>(gl::GetPixelBytes(actualInternalFormat, context->getClientVersion())); GLenum sizedFormat = gl::IsSizedInternalFormat(actualInternalFormat, clientVersion) ?
actualInternalFormat :
gl::GetSizedInternalFormat(actualInternalFormat, type, clientVersion);
size_t pixelBytes = static_cast<size_t>(gl::GetPixelBytes(sizedFormat, clientVersion));
if (!rx::IsUnsignedMultiplicationSafe(widthSize, heightSize) || if (!rx::IsUnsignedMultiplicationSafe(widthSize, heightSize) ||
!rx::IsUnsignedMultiplicationSafe(widthSize * heightSize, depthSize) || !rx::IsUnsignedMultiplicationSafe(widthSize * heightSize, depthSize) ||
...@@ -257,7 +277,8 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le ...@@ -257,7 +277,8 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le
size_t copyBytes = widthSize * heightSize * depthSize * pixelBytes; size_t copyBytes = widthSize * heightSize * depthSize * pixelBytes;
size_t offset = reinterpret_cast<size_t>(pixels); size_t offset = reinterpret_cast<size_t>(pixels);
if (!rx::IsUnsignedAdditionSafe(offset, copyBytes) || ((offset + copyBytes) > static_cast<size_t>(pixelUnpackBuffer->size()))) if (!rx::IsUnsignedAdditionSafe(offset, copyBytes) ||
((offset + copyBytes) > static_cast<size_t>(pixelUnpackBuffer->size())))
{ {
// Overflow past the end of the buffer // Overflow past the end of the buffer
return gl::error(GL_INVALID_OPERATION, false); return gl::error(GL_INVALID_OPERATION, false);
...@@ -283,12 +304,13 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le ...@@ -283,12 +304,13 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le
} }
bool ValidateES3CopyTexImageParameters(gl::Context *context, GLenum target, GLint level, GLenum internalformat, bool ValidateES3CopyTexImageParameters(gl::Context *context, GLenum target, GLint level, GLenum internalformat,
bool isSubImage, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, bool isSubImage, GLint xoffset, GLint yoffset, GLint zoffset,
GLsizei width, GLsizei height, GLint border) GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
{ {
GLenum textureInternalFormat; GLenum textureInternalFormat;
if (!ValidateCopyTexImageParametersBase(context, target, level, internalformat, isSubImage, if (!ValidateCopyTexImageParametersBase(context, target, level, internalformat, isSubImage,
xoffset, yoffset, zoffset, x, y, width, height, border, &textureInternalFormat)) xoffset, yoffset, zoffset, x, y, width, height,
border, &textureInternalFormat))
{ {
return false; return false;
} }
...@@ -299,7 +321,8 @@ bool ValidateES3CopyTexImageParameters(gl::Context *context, GLenum target, GLin ...@@ -299,7 +321,8 @@ bool ValidateES3CopyTexImageParameters(gl::Context *context, GLenum target, GLin
if (isSubImage) if (isSubImage)
{ {
if (!gl::IsValidCopyTexImageCombination(textureInternalFormat, colorbufferInternalFormat, context->getReadFramebufferHandle(), if (!gl::IsValidCopyTexImageCombination(textureInternalFormat, colorbufferInternalFormat,
context->getReadFramebufferHandle(),
context->getClientVersion())) context->getClientVersion()))
{ {
return gl::error(GL_INVALID_OPERATION, false); return gl::error(GL_INVALID_OPERATION, false);
...@@ -307,7 +330,8 @@ bool ValidateES3CopyTexImageParameters(gl::Context *context, GLenum target, GLin ...@@ -307,7 +330,8 @@ bool ValidateES3CopyTexImageParameters(gl::Context *context, GLenum target, GLin
} }
else else
{ {
if (!gl::IsValidCopyTexImageCombination(internalformat, colorbufferInternalFormat, context->getReadFramebufferHandle(), if (!gl::IsValidCopyTexImageCombination(internalformat, colorbufferInternalFormat,
context->getReadFramebufferHandle(),
context->getClientVersion())) context->getClientVersion()))
{ {
return gl::error(GL_INVALID_OPERATION, false); return gl::error(GL_INVALID_OPERATION, false);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment