<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>