Commit efb2a6ff by Jamie Madill

Add the proper API errors for pixel unpack buffers.

1. For overflowing the currently bound pixel unpack buffer in TexImage and TexSubImage calls. 2. Enforce unpack buffer offset alignment for TexImage and TexSubImage calls. We'll have to check for currently mapped buffers when we implement map. TRAC #23842 Signed-off-by: Geoff Lang Signed-off-by: Shannon Woods
parent 4f1a8639
...@@ -979,7 +979,7 @@ void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum interna ...@@ -979,7 +979,7 @@ void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum interna
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)) 0, 0, 0, width, height, 1, 0, GL_NONE, GL_NONE, data))
{ {
return; return;
} }
...@@ -1044,7 +1044,7 @@ void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffs ...@@ -1044,7 +1044,7 @@ void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffs
if (context->getClientVersion() >= 3 && if (context->getClientVersion() >= 3 &&
!ValidateES3TexImageParameters(context, target, level, GL_NONE, true, true, !ValidateES3TexImageParameters(context, target, level, GL_NONE, true, true,
xoffset, yoffset, 0, width, height, 1, 0, GL_NONE, GL_NONE)) xoffset, yoffset, 0, width, height, 1, 0, GL_NONE, GL_NONE, data))
{ {
return; return;
} }
...@@ -5142,7 +5142,7 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL ...@@ -5142,7 +5142,7 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL
if (context->getClientVersion() >= 3 && if (context->getClientVersion() >= 3 &&
!ValidateES3TexImageParameters(context, target, level, internalformat, false, false, !ValidateES3TexImageParameters(context, target, level, internalformat, false, false,
0, 0, 0, width, height, 1, border, format, type)) 0, 0, 0, width, height, 1, border, format, type, pixels))
{ {
return; return;
} }
...@@ -5399,7 +5399,7 @@ void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint ...@@ -5399,7 +5399,7 @@ void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint
if (context->getClientVersion() >= 3 && if (context->getClientVersion() >= 3 &&
!ValidateES3TexImageParameters(context, target, level, GL_NONE, false, true, !ValidateES3TexImageParameters(context, target, level, GL_NONE, false, true,
0, 0, 0, width, height, 1, 0, format, type)) 0, 0, 0, width, height, 1, 0, format, type, pixels))
{ {
return; return;
} }
...@@ -6392,7 +6392,7 @@ void __stdcall glTexImage3D(GLenum target, GLint level, GLint internalformat, GL ...@@ -6392,7 +6392,7 @@ void __stdcall glTexImage3D(GLenum target, GLint level, GLint internalformat, GL
// validateES3TexImageFormat sets the error code if there is an error // validateES3TexImageFormat sets the error code if there is an error
if (!ValidateES3TexImageParameters(context, target, level, internalformat, false, false, if (!ValidateES3TexImageParameters(context, target, level, internalformat, false, false,
0, 0, 0, width, height, depth, border, format, type)) 0, 0, 0, width, height, depth, border, format, type, pixels))
{ {
return; return;
} }
...@@ -6450,7 +6450,7 @@ void __stdcall glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint ...@@ -6450,7 +6450,7 @@ void __stdcall glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint
// validateES3TexImageFormat sets the error code if there is an error // validateES3TexImageFormat sets the error code if there is an error
if (!ValidateES3TexImageParameters(context, target, level, GL_NONE, false, true, if (!ValidateES3TexImageParameters(context, target, level, GL_NONE, false, true,
xoffset, yoffset, zoffset, width, height, depth, 0, xoffset, yoffset, zoffset, width, height, depth, 0,
format, type)) format, type, pixels))
{ {
return; return;
} }
...@@ -6555,7 +6555,7 @@ void __stdcall glCompressedTexImage3D(GLenum target, GLint level, GLenum interna ...@@ -6555,7 +6555,7 @@ void __stdcall glCompressedTexImage3D(GLenum target, GLint level, GLenum interna
// validateES3TexImageFormat sets the error code if there is an error // validateES3TexImageFormat sets the error code if there is an error
if (!ValidateES3TexImageParameters(context, target, level, internalformat, true, false, if (!ValidateES3TexImageParameters(context, target, level, internalformat, true, false,
0, 0, 0, width, height, depth, border, GL_NONE, GL_NONE)) 0, 0, 0, width, height, depth, border, GL_NONE, GL_NONE, data))
{ {
return; return;
} }
...@@ -6617,7 +6617,7 @@ void __stdcall glCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffs ...@@ -6617,7 +6617,7 @@ void __stdcall glCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffs
// validateES3TexImageFormat sets the error code if there is an error // validateES3TexImageFormat sets the error code if there is an error
if (!ValidateES3TexImageParameters(context, target, level, GL_NONE, true, true, if (!ValidateES3TexImageParameters(context, target, level, GL_NONE, true, true,
0, 0, 0, width, height, depth, 0, GL_NONE, GL_NONE)) 0, 0, 0, width, height, depth, 0, GL_NONE, GL_NONE, data))
{ {
return; return;
} }
......
...@@ -62,7 +62,7 @@ static bool validCompressedImageSize(GLsizei width, GLsizei height) ...@@ -62,7 +62,7 @@ static bool validCompressedImageSize(GLsizei width, GLsizei height)
bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint level, GLint internalformat, bool isCompressed, bool isSubImage, bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint level, GLint internalformat, bool isCompressed, bool isSubImage,
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) GLint border, GLenum format, GLenum type, const GLvoid *pixels)
{ {
// Validate image size // Validate image size
if (!validImageSize(context, level, width, height, depth)) if (!validImageSize(context, level, width, height, depth))
...@@ -280,6 +280,46 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le ...@@ -280,6 +280,46 @@ bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint le
} }
} }
// Check for pixel unpack buffer related API errors
gl::Buffer *pixelUnpackBuffer = context->getPixelUnpackBuffer();
if (pixelUnpackBuffer != NULL)
{
// ...the data would be unpacked from the buffer object such that the memory reads required
// would exceed the data store size.
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()));
if (!rx::IsUnsignedMultiplicationSafe(widthSize, heightSize) ||
!rx::IsUnsignedMultiplicationSafe(widthSize * heightSize, depthSize) ||
!rx::IsUnsignedMultiplicationSafe(widthSize * heightSize * depthSize, pixelBytes))
{
// Overflow past the end of the buffer
return gl::error(GL_INVALID_OPERATION, false);
}
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())))
{
// Overflow past the end of the buffer
return gl::error(GL_INVALID_OPERATION, false);
}
// ...data is not evenly divisible into the number of bytes needed to store in memory a datum
// indicated by type.
size_t dataBytesPerPixel = static_cast<size_t>(gl::GetTypeBytes(type));
if ((offset % dataBytesPerPixel) != 0)
{
return gl::error(GL_INVALID_OPERATION, false);
}
// TODO: ...the buffer object's data store is currently mapped.
}
return true; return true;
} }
......
...@@ -16,7 +16,7 @@ class Context; ...@@ -16,7 +16,7 @@ class Context;
bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint level, GLint internalformat, bool isCompressed, bool isSubImage, bool ValidateES3TexImageParameters(gl::Context *context, GLenum target, GLint level, GLint internalformat, bool isCompressed, bool isSubImage,
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); GLint border, GLenum format, GLenum type, const GLvoid *pixels);
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, GLint x, GLint y,
......
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