<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Mar 10, 2015 at 11:36 AM, Eduardo Lima Mitev <span dir="ltr"><<a href="mailto:elima@igalia.com" target="_blank">elima@igalia.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">This patch adds two types of checks to the gl(Compressed)Tex(Sub)Imgage family<br>
of functions when a pixel buffer object is bound to GL_PIXEL_UNPACK_BUFFER:<br>
<br>
- That the buffer is not mapped.<br>
- The total data size is within the boundaries of the buffer size.<br>
<br>
It does so by calling auxiliary validations functions from PBO API:<br>
_mesa_validate_pbo_source() for non-compressed texture calls, and<br>
_mesa_validate_pbo_source_compressed() for compressed texture calls.<br>
<br>
The first check is defined in Section 6.3.2 'Effects of Mapping Buffers<br>
on Other GL Commands' of the GLES 3.1 spec, page 57:<br>
<br>
"Any GL command which attempts to read from, write to, or change the<br>
state of a buffer object may generate an INVALID_OPERATION error if all<br>
or part of the buffer object is mapped. However, only commands which<br>
explicitly describe this error are required to do so. If an error is not<br>
generated, using such commands to perform invalid reads, writes, or<br>
state changes will have undefined results and may result in GL<br>
interruption or termination."<br>
<br>
Similar wording exists in GL 4.5 spec, page 76.<br>
<br>
In the case of gl(Compressed)Tex(Sub)Image(2,3)D, the specification doesn't force<br>
implemtations to throw an error. However since Mesa don't currently implement<br>
checks to determine when it is safe to read/write from/to a mapped PBO, we<br>
should always return the error if all or parts of it are mapped.<br>
<br>
The 2nd check is defined in Section 8.5 'Texture Image Specification' of the<br>
OpenGL 4.5 spec, page 203:<br>
<br>
"An INVALID_OPERATION error is generated if a pixel unpack buffer object<br>
is bound and storing texture data would access memory beyond the end of<br>
the pixel unpack buffer."<br>
<br>
Fixes 4 dEQP tests:<br>
* dEQP-GLES3.functional.negative_api.texture.compressedteximage2d_invalid_buffer_target<br>
* dEQP-GLES3.functional.negative_api.texture.compressedtexsubimage2d_invalid_buffer_target<br>
* dEQP-GLES3.functional.negative_api.texture.compressedteximage3d_invalid_buffer_target<br>
* dEQP-GLES3.functional.negative_api.texture.compressedtexsubimage3d_invalid_buffer_target<br>
---<br>
</div></div> src/mesa/main/teximage.c | 97 +++++++++++++++++++++++++++++++++---------------<br>
1 file changed, 67 insertions(+), 30 deletions(-)<br>
<br>
diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c<br>
index 7b1a0e6..aae7c00 100644<br>
<span class="">--- a/src/mesa/main/teximage.c<br>
+++ b/src/mesa/main/teximage.c<br>
@@ -53,6 +53,7 @@<br>
#include "mtypes.h"<br>
#include "glformats.h"<br>
#include "texstore.h"<br>
+#include "pbo.h"<br>
<br>
<br>
/**<br>
</span>@@ -2113,7 +2114,8 @@ texture_error_check( struct gl_context *ctx,<br>
<span class=""> GLint level, GLint internalFormat,<br>
GLenum format, GLenum type,<br>
GLint width, GLint height,<br>
- GLint depth, GLint border )<br>
+ GLint depth, GLint border,<br>
+ const GLvoid *pixels )<br>
{<br>
GLenum err;<br>
<br>
</span>@@ -2198,6 +2200,13 @@ texture_error_check( struct gl_context *ctx,<br>
<span class=""> return GL_TRUE;<br>
}<br>
+ /* validate the bound PBO, if any */<br>
+ if (!_mesa_validate_pbo_source(ctx, dimensions, &ctx->Unpack,<br>
+ width, height, depth, format, type,<br>
+ INT_MAX, pixels, "glTexImage")) {<br>
+ return GL_TRUE;<br>
+ }<br>
+<br>
/* make sure internal format and format basically agree */<br>
if (!texture_formats_agree(internalFormat, format)) {<br>
_mesa_error(ctx, GL_INVALID_OPERATION,<br>
</span>@@ -2294,7 +2303,7 @@ compressed_texture_error_check(struct gl_context *ctx, GLint dimensions,<br>
<span class=""> GLenum target, GLint level,<br>
GLenum internalFormat, GLsizei width,<br>
GLsizei height, GLsizei depth, GLint border,<br>
- GLsizei imageSize)<br>
+ GLsizei imageSize, const GLvoid *data)<br>
{<br>
const GLint maxLevels = _mesa_max_texture_levels(ctx, target);<br>
GLint expectedSize;<br>
</span>@@ -2322,6 +2331,13 @@ compressed_texture_error_check(struct gl_context *ctx, GLint dimensions,<br>
<span class=""> return GL_TRUE;<br>
}<br>
<br>
+ /* validate the bound PBO, if any */<br>
+ if (!_mesa_validate_pbo_source_compressed(ctx, dimensions, &ctx->Unpack,<br>
+ imageSize, data,<br>
+ "glCompressedTexImage")) {<br>
+ return GL_TRUE;<br>
+ }<br>
+<br>
switch (internalFormat) {<br>
case GL_PALETTE4_RGB8_OES:<br>
case GL_PALETTE4_RGBA8_OES:<br>
</span>@@ -2454,7 +2470,8 @@ texsubimage_error_check(struct gl_context *ctx, GLuint dimensions,<br>
<span class=""> GLenum target, GLint level,<br>
GLint xoffset, GLint yoffset, GLint zoffset,<br>
GLint width, GLint height, GLint depth,<br>
- GLenum format, GLenum type, bool dsa)<br>
+ GLenum format, GLenum type, const GLvoid *pixels,<br>
+ bool dsa)<br>
{<br>
struct gl_texture_image *texImage;<br>
GLenum err;<br>
</span>@@ -2506,6 +2523,13 @@ texsubimage_error_check(struct gl_context *ctx, GLuint dimensions,<br>
<span class=""> return GL_TRUE;<br>
}<br></span></blockquote><div>It would be more correct to plumb the calling function name through this function (like for compressed_subtexture_error_check) since texsubimage_error_check is called by glTex[ture]SubImage*D. <br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">
+ /* validate the bound PBO, if any */<br>
+ if (!_mesa_validate_pbo_source(ctx, dimensions, &ctx->Unpack,<br>
+ width, height, depth, format, type,<br>
+ INT_MAX, pixels, "glTexSubImage")) {<br>
+ return GL_TRUE;<br>
+ }<br>
+<br>
texImage = _mesa_select_tex_image(texObj, target, level);<br>
if (!texImage) {<br>
/* non-existant texture level */<br>
</span>@@ -3218,12 +3242,13 @@ teximage(struct gl_context *ctx, GLboolean compressed, GLuint dims,<br>
<span class=""> if (compressed_texture_error_check(ctx, dims, target, level,<br>
internalFormat,<br>
width, height, depth,<br>
- border, imageSize))<br>
+ border, imageSize, pixels))<br>
return;<br>
}<br>
else {<br>
if (texture_error_check(ctx, dims, target, level, internalFormat,<br>
- format, type, width, height, depth, border))<br>
+ format, type, width, height, depth, border,<br>
+ pixels))<br>
return;<br>
}<br>
<br>
</span>@@ -3573,7 +3598,8 @@ texsubimage(struct gl_context *ctx, GLuint dims, GLenum target, GLint level,<br>
<span class=""><br>
if (texsubimage_error_check(ctx, dims, texObj, target, level,<br>
xoffset, yoffset, zoffset,<br>
- width, height, depth, format, type, false)) {<br>
+ width, height, depth, format, type,<br>
+ pixels, false)) {<br>
return; /* error was detected */<br>
}<br>
<br>
</span>@@ -3627,7 +3653,8 @@ texturesubimage(struct gl_context *ctx, GLuint dims,<br>
<span class=""><br>
if (texsubimage_error_check(ctx, dims, texObj, texObj->Target, level,<br>
xoffset, yoffset, zoffset,<br>
- width, height, depth, format, type, true)) {<br>
+ width, height, depth, format, type,<br>
+ pixels, true)) {<br>
return; /* error was detected */<br>
}<br>
<br>
</span>@@ -4623,68 +4650,72 @@ compressed_subtexture_error_check(struct gl_context *ctx, GLint dims,<br>
<span class=""> GLenum target, GLint level,<br>
GLint xoffset, GLint yoffset, GLint zoffset,<br>
GLsizei width, GLsizei height, GLsizei depth,<br>
- GLenum format, GLsizei imageSize, bool dsa)<br>
+ GLenum format, GLsizei imageSize,<br>
</span>+ const GLvoid *data, const char *callerName)<br>
<span class=""> {<br>
struct gl_texture_image *texImage;<br>
GLint expectedSize;<br>
</span>- const char *suffix = dsa ? "ture" : "";<br>
<br>
/* this will catch any invalid compressed format token */<br>
if (!_mesa_is_compressed_format(ctx, format)) {<br>
_mesa_error(ctx, GL_INVALID_ENUM,<br>
- "glCompressedTex%sSubImage%uD(format)", suffix, dims);<br>
+ "%s(format)", callerName);<br>
return GL_TRUE;<br>
}<br>
<br>
if (level < 0 || level >= _mesa_max_texture_levels(ctx, target)) {<br>
_mesa_error(ctx, GL_INVALID_VALUE,<br>
- "glCompressedTex%sSubImage%uD(level=%d)",<br>
- suffix, dims, level);<br>
+ "%s(level=%d)",<br>
+ callerName, level);<br>
<span class="">+ return GL_TRUE;<br>
+ }<br>
+<br>
</span><span class="">+ /* validate the bound PBO, if any */<br>
+ if (!_mesa_validate_pbo_source_compressed(ctx, dims, &ctx->Unpack,<br>
</span>+ imageSize, data, callerName)) {<br>
return GL_TRUE;<br>
<span class=""> }<br>
<br>
/* Check for invalid pixel storage modes */<br>
if (!_mesa_compressed_pixel_storage_error_check(ctx, dims,<br>
</span>- &ctx->Unpack,<br>
- dsa ? "glCompressedTextureSubImage" :<br>
- "glCompressedTexSubImage")) {<br>
+ &ctx->Unpack, callerName)) {<br>
return GL_TRUE;<br>
}<br>
<br>
expectedSize = compressed_tex_size(width, height, depth, format);<br>
if (expectedSize != imageSize) {<br>
_mesa_error(ctx, GL_INVALID_VALUE,<br>
- "glCompressedTex%sSubImage%uD(size=%d)",<br>
- suffix, dims, imageSize);<br>
+ "%s(size=%d)",<br>
+ callerName, imageSize);<br>
return GL_TRUE;<br>
<span class=""> }<br>
<br>
texImage = _mesa_select_tex_image(texObj, target, level);<br>
if (!texImage) {<br>
</span> _mesa_error(ctx, GL_INVALID_OPERATION,<br>
- "glCompressedTex%sSubImage%uD(invalid texture image)",<br>
- suffix, dims);<br>
+ "%s(invalid texture image)",<br>
+ callerName);<br>
return GL_TRUE;<br>
}<br>
<br>
if ((GLint) format != texImage->InternalFormat) {<br>
_mesa_error(ctx, GL_INVALID_OPERATION,<br>
- "glCompressedTex%sSubImage%uD(format=0x%x)",<br>
- suffix, dims, format);<br>
+ "%s(format=0x%x)",<br>
+ callerName, format);<br>
return GL_TRUE;<br>
}<br>
<br>
if (compressedteximage_only_format(ctx, format)) {<br>
_mesa_error(ctx, GL_INVALID_OPERATION,<br>
- "glCompressedTex%sSubImage%uD(format=0x%x cannot be updated)",<br>
- suffix, dims, format);<br>
+ "%s(format=0x%x cannot be updated)",<br>
+ callerName, format);<br>
return GL_TRUE;<br>
}<br>
<br>
if (error_check_subtexture_dimensions(ctx, dims,<br>
texImage, xoffset, yoffset, zoffset,<br>
width, height, depth,<br>
- "glCompressedTexSubImage")) {<br>
+ callerName)) {<br>
return GL_TRUE;<br>
}<br>
<br>
@@ -4787,7 +4818,8 @@ _mesa_CompressedTexSubImage1D(GLenum target, GLint level, GLint xoffset,<br>
if (compressed_subtexture_error_check(ctx, 1, texObj, target,<br>
level, xoffset, 0, 0,<br>
width, 1, 1,<br>
- format, imageSize, false)) {<br>
+ format, imageSize, data,<br>
+ "glCompressedTexSubImage1D")) {<br>
return;<br>
}<br>
<br>
@@ -4823,7 +4855,8 @@ _mesa_CompressedTextureSubImage1D(GLuint texture, GLint level, GLint xoffset,<br>
if (compressed_subtexture_error_check(ctx, 1, texObj, texObj->Target,<br>
level, xoffset, 0, 0,<br>
width, 1, 1,<br>
- format, imageSize, true)) {<br>
+ format, imageSize, data,<br>
+ "glCompressedTextureSubImage1D")) {<br>
return;<br>
}<br>
<br>
@@ -4860,7 +4893,8 @@ _mesa_CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset,<br>
if (compressed_subtexture_error_check(ctx, 2, texObj, target,<br>
level, xoffset, yoffset, 0,<br>
width, height, 1,<br>
- format, imageSize, false)) {<br>
+ format, imageSize, data,<br>
+ "glCompressedTexSubImage2D")) {<br>
return;<br>
}<br>
<br>
@@ -4899,7 +4933,8 @@ _mesa_CompressedTextureSubImage2D(GLuint texture, GLint level, GLint xoffset,<br>
if (compressed_subtexture_error_check(ctx, 2, texObj, texObj->Target,<br>
level, xoffset, yoffset, 0,<br>
width, height, 1,<br>
- format, imageSize, true)) {<br>
+ format, imageSize, data,<br>
+ "glCompressedTextureSubImage2D")) {<br>
return;<br>
}<br>
<br>
@@ -4935,7 +4970,8 @@ _mesa_CompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset,<br>
if (compressed_subtexture_error_check(ctx, 3, texObj, target,<br>
<span class=""> level, xoffset, yoffset, zoffset,<br>
width, height, depth,<br>
</span>- format, imageSize, false)) {<br>
+ format, imageSize, data,<br>
+ "glCompressedTexSubImage3D")) {<br>
return;<br>
}<br>
<br>
@@ -4975,7 +5011,8 @@ _mesa_CompressedTextureSubImage3D(GLuint texture, GLint level, GLint xoffset,<br>
if (compressed_subtexture_error_check(ctx, 3, texObj, texObj->Target,<br>
level, xoffset, yoffset, zoffset,<br>
width, height, depth,<br>
- format, imageSize, true)) {<br>
+ format, imageSize, data,<br>
+ "glCompressedTextureSubImage3D")) {<br>
return;<br>
}<br>
<span class="HOEnZb"><font color="#888888"><br>
--<br>
2.1.3<br>
<br>
</font></span></blockquote></div><br></div></div>