meta: Allow GL_UN/PACK_IMAGE_HEIGHT in _mesa_meta_pbo_Get/TexSubImage
authorNeil Roberts <neil@linux.intel.com>
Thu, 26 Feb 2015 12:53:50 +0000 (12:53 +0000)
committerNeil Roberts <neil@linux.intel.com>
Thu, 5 Mar 2015 13:24:45 +0000 (13:24 +0000)
Now that a layered source PBO is interpreted as a single tall 2D image
it's quite easy to accept the image height packing option by just
creating an image that is tall enough to include the image padding.

I'm not sure whether the image height property should affect 1D_ARRAY
textures. My intuition and interpretation of the GL spec (which is a
bit vague) would be that it shouldn't. However the software fallback
path in Mesa uses the property for packing but not for unpacking. The
binary NVidia driver uses it for both. This patch doesn't use it for
either case so it is different from the software fallback. There is
some discussion about this here:

http://lists.freedesktop.org/archives/mesa-dev/2015-February/077925.html

This is tested by the texsubimage Piglit test with the array and pbo
arguments. Previously this test was skipping this code path because it
always sets the image height.

I've also tested it by modifying the getteximage-targets test. It
wasn't using this code path before because it was using the default
texture object so this code couldn't successfully create a frame
buffer. I also modified it to add some image padding with the image
height in the PBO.

Reviewed-by: Jason Ekstrand <jason.ekstrand@intel.com>
Cc: "10.5" <mesa-stable@lists.freedesktop.org>
src/mesa/drivers/common/meta_tex_subimage.c

index 1fef79db7b8a79aa106deb8e545bb6953468fe76..f360d649d1679a9d26ea119a81a4175b2bc4def9 100644 (file)
@@ -144,6 +144,7 @@ _mesa_meta_pbo_TexSubImage(struct gl_context *ctx, GLuint dims,
                            const struct gl_pixelstore_attrib *packing)
 {
    GLuint pbo = 0, pbo_tex = 0, fbos[2] = { 0, 0 };
+   int full_height, image_height;
    struct gl_texture_image *pbo_tex_image;
    GLenum status;
    bool success = false;
@@ -177,14 +178,16 @@ _mesa_meta_pbo_TexSubImage(struct gl_context *ctx, GLuint dims,
       return true;
    }
 
-   /* Only accept tightly packed pixels from the user. */
-   if (packing->ImageHeight != 0 && packing->ImageHeight != height)
-      return false;
+   /* For arrays, use a tall (height * depth) 2D texture but taking into
+    * account the inter-image padding specified with the image height packing
+    * property.
+    */
+   image_height = packing->ImageHeight == 0 ? height : packing->ImageHeight;
+   full_height = image_height * (depth - 1) + height;
 
-   /* For arrays, use a tall (height * depth) 2D texture. */
    pbo_tex_image = create_texture_for_pbo(ctx, create_pbo,
                                           GL_PIXEL_UNPACK_BUFFER,
-                                          width, height * depth,
+                                          width, full_height,
                                           format, type, pixels, packing,
                                           &pbo, &pbo_tex);
    if (!pbo_tex_image)
@@ -236,7 +239,8 @@ _mesa_meta_pbo_TexSubImage(struct gl_context *ctx, GLuint dims,
       _mesa_update_state(ctx);
 
       _mesa_meta_BlitFramebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer,
-                                 0, z * height, width, (z + 1) * height,
+                                 0, z * image_height,
+                                 width, z * image_height + height,
                                  xoffset, yoffset,
                                  xoffset + width, yoffset + height,
                                  GL_COLOR_BUFFER_BIT, GL_NEAREST);
@@ -263,6 +267,7 @@ _mesa_meta_pbo_GetTexSubImage(struct gl_context *ctx, GLuint dims,
                               const struct gl_pixelstore_attrib *packing)
 {
    GLuint pbo = 0, pbo_tex = 0, fbos[2] = { 0, 0 };
+   int full_height, image_height;
    struct gl_texture_image *pbo_tex_image;
    GLenum status;
    bool success = false;
@@ -296,13 +301,15 @@ _mesa_meta_pbo_GetTexSubImage(struct gl_context *ctx, GLuint dims,
       return true;
    }
 
-   /* Only accept tightly packed pixels from the user. */
-   if (packing->ImageHeight != 0 && packing->ImageHeight != height)
-      return false;
+   /* For arrays, use a tall (height * depth) 2D texture but taking into
+    * account the inter-image padding specified with the image height packing
+    * property.
+    */
+   image_height = packing->ImageHeight == 0 ? height : packing->ImageHeight;
+   full_height = image_height * (depth - 1) + height;
 
-   /* For arrays, use a tall (height * depth) 2D texture. */
    pbo_tex_image = create_texture_for_pbo(ctx, false, GL_PIXEL_PACK_BUFFER,
-                                          width, height * depth,
+                                          width, full_height * depth,
                                           format, type, pixels, packing,
                                           &pbo, &pbo_tex);
    if (!pbo_tex_image)
@@ -361,7 +368,8 @@ _mesa_meta_pbo_GetTexSubImage(struct gl_context *ctx, GLuint dims,
       _mesa_meta_BlitFramebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer,
                                  xoffset, yoffset,
                                  xoffset + width, yoffset + height,
-                                 0, z * height, width, (z + 1) * height,
+                                 0, z * image_height,
+                                 width, z * image_height + height,
                                  GL_COLOR_BUFFER_BIT, GL_NEAREST);
    }