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
{
if (context->getClientVersion() < 3 &&
!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;
}
if (context->getClientVersion() >= 3 &&
!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;
}
......@@ -6118,7 +6118,7 @@ void __stdcall glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GL
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))
{
return;
......
......@@ -1147,6 +1147,7 @@ bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLi
GLint textureLevelWidth = 0;
GLint textureLevelHeight = 0;
GLint textureLevelDepth = 0;
int maxDimension = 0;
switch (target)
{
......@@ -1162,6 +1163,7 @@ bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLi
textureLevelHeight = texture2d->getHeight(level);
textureLevelDepth = 1;
texture = texture2d;
maxDimension = context->getMaximum2DTextureDimension();
}
}
break;
......@@ -1183,6 +1185,7 @@ bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLi
textureLevelHeight = textureCube->getHeight(target, level);
textureLevelDepth = 1;
texture = textureCube;
maxDimension = context->getMaximumCubeTextureDimension();
}
}
break;
......@@ -1199,6 +1202,7 @@ bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLi
textureLevelHeight = texture2dArray->getHeight(level);
textureLevelDepth = texture2dArray->getLayers(level);
texture = texture2dArray;
maxDimension = context->getMaximum2DTextureDimension();
}
}
break;
......@@ -1215,6 +1219,7 @@ bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLi
textureLevelHeight = texture3d->getHeight(level);
textureLevelDepth = texture3d->getDepth(level);
texture = texture3d;
maxDimension = context->getMaximum3DTextureDimension();
}
}
break;
......@@ -1260,6 +1265,24 @@ bool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLi
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;
return true;
......
......@@ -108,6 +108,11 @@ bool ValidateES2TexImageParameters(gl::Context *context, GLenum target, GLint le
GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
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))
{
return gl::error(GL_INVALID_VALUE, false);
......
......@@ -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 border, GLenum format, GLenum type, const GLvoid *pixels)
{
if (!ValidTexture2DDestinationTarget(context, target))
{
return gl::error(GL_INVALID_ENUM, false);
}
// Validate image size
if (!ValidImageSize(context, target, level, width, height, depth))
{
......@@ -37,6 +42,14 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le
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;
bool textureCompressed = false;
GLenum textureInternalFormat = GL_NONE;
......@@ -156,6 +169,7 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le
// Validate texture formats
GLenum actualInternalFormat = isSubImage ? textureInternalFormat : internalformat;
int clientVersion = context->getClientVersion();
if (isCompressed)
{
if (!ValidCompressedImageSize(context, actualInternalFormat, width, height))
......@@ -163,7 +177,7 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le
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);
}
......@@ -175,14 +189,16 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le
}
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) ||
!gl::IsValidFormat(format, context->getClientVersion()) ||
!gl::IsValidType(type, context->getClientVersion()))
!gl::IsValidFormat(format, clientVersion) ||
!gl::IsValidType(type, clientVersion))
{
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);
}
......@@ -244,7 +260,11 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le
size_t widthSize = static_cast<size_t>(width);
size_t heightSize = static_cast<size_t>(height);
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) ||
!rx::IsUnsignedMultiplicationSafe(widthSize * heightSize, depthSize) ||
......@@ -257,7 +277,8 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le
size_t copyBytes = widthSize * heightSize * depthSize * pixelBytes;
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
return gl::error(GL_INVALID_OPERATION, false);
......@@ -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 isSubImage, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y,
GLsizei width, GLsizei height, GLint border)
bool isSubImage, GLint xoffset, GLint yoffset, GLint zoffset,
GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
{
GLenum textureInternalFormat;
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;
}
......@@ -299,7 +321,8 @@ bool ValidateES3CopyTexImageParameters(gl::Context *context, GLenum target, GLin
if (isSubImage)
{
if (!gl::IsValidCopyTexImageCombination(textureInternalFormat, colorbufferInternalFormat, context->getReadFramebufferHandle(),
if (!gl::IsValidCopyTexImageCombination(textureInternalFormat, colorbufferInternalFormat,
context->getReadFramebufferHandle(),
context->getClientVersion()))
{
return gl::error(GL_INVALID_OPERATION, false);
......@@ -307,7 +330,8 @@ bool ValidateES3CopyTexImageParameters(gl::Context *context, GLenum target, GLin
}
else
{
if (!gl::IsValidCopyTexImageCombination(internalformat, colorbufferInternalFormat, context->getReadFramebufferHandle(),
if (!gl::IsValidCopyTexImageCombination(internalformat, colorbufferInternalFormat,
context->getReadFramebufferHandle(),
context->getClientVersion()))
{
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