[PATCH 4/5] glamor: Add in support for the stride parameter when uploading texture data

Michel Dänzer michel at daenzer.net
Wed Apr 23 02:54:44 PDT 2014


From: Anthony Waters <awaters1 at gmail.com>

The method __glamor_upload_pixmap_to_texture was updated to support a
stride parameter for the data being uploaded to a texture.  This
required correctly setting the alignment from 4 to a value based on the
depth of the data and also required setting GL_UNPACK_ROW_LENGTH based
on both the stride and the alignment.

The stride parameter was also updated in glamor_put_image to be
correctly specified, the old values would cause the xserver to crash.
[ Michel Dänzer: squashed in follow-up fix for the stride ]

Part of bug: https://bugs.freedesktop.org/show_bug.cgi?id=71813

Signed-off-by: Anthony Waters <awaters1 at gmail.com>
Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
---
 glamor/glamor_pixmap.c   | 38 +++++++++++++++++++++++++++++++++-----
 glamor/glamor_putimage.c |  6 ++++--
 2 files changed, 37 insertions(+), 7 deletions(-)

diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 54b414b..8846741 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -697,13 +697,38 @@ static void
 __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, unsigned int *tex,
                                   GLenum format,
                                   GLenum type,
-                                  int x, int y, int w, int h,
+                                  int x, int y, int w, int h, int stride,
                                   void *bits, int pbo)
 {
     glamor_screen_private *glamor_priv =
         glamor_get_screen_private(pixmap->drawable.pScreen);
     int non_sub = 0;
     unsigned int iformat = 0;
+    int bpp, alignment;
+
+    switch (type) {
+    case GL_UNSIGNED_BYTE:
+	bpp = 8;
+	break;
+    case GL_UNSIGNED_INT_8_8_8_8:
+    case GL_UNSIGNED_INT_8_8_8_8_REV:
+    case GL_UNSIGNED_INT_2_10_10_10_REV:
+	bpp = 32;
+	break;
+    case GL_UNSIGNED_SHORT_5_6_5:
+    case GL_UNSIGNED_SHORT_5_6_5_REV:
+    case GL_UNSIGNED_SHORT_1_5_5_5_REV:
+    case GL_UNSIGNED_SHORT_4_4_4_4_REV:
+	bpp = 16;
+	break;
+    default:
+        bpp = 0;
+    }
+    alignment = bpp / 8;
+
+    if (stride == 0) {
+        alignment = 4;
+    }
 
     glamor_make_current(glamor_priv);
     if (*tex == 0) {
@@ -719,17 +744,20 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, unsigned int *tex,
     glBindTexture(GL_TEXTURE_2D, *tex);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+    glPixelStorei(GL_UNPACK_ALIGNMENT, alignment);
 
     assert(pbo || bits != 0);
     if (bits == NULL) {
         glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
         glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
     }
+
+    glPixelStorei(GL_UNPACK_ROW_LENGTH, stride / alignment);
     if (non_sub)
         glTexImage2D(GL_TEXTURE_2D, 0, iformat, w, h, 0, format, type, bits);
     else
         glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, format, type, bits);
+    glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
 
     if (bits == NULL)
         glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
@@ -812,7 +840,7 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
         assert(y + fbo_y_off + h <= pixmap_priv->base.fbo->height);
         __glamor_upload_pixmap_to_texture(pixmap, &pixmap_priv->base.fbo->tex,
                                           format, type,
-                                          x + fbo_x_off, y + fbo_y_off, w, h,
+                                          x + fbo_x_off, y + fbo_y_off, w, h, stride,
                                           bits, pbo);
         return TRUE;
     }
@@ -838,8 +866,8 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
     glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 
     glamor_set_destination_pixmap_priv_nc(pixmap_priv);
-    __glamor_upload_pixmap_to_texture(pixmap, &tex,
-                                      format, type, 0, 0, w, h, bits, pbo);
+    __glamor_upload_pixmap_to_texture(pixmap, &tex, format, type,
+                                      0, 0, w, h, stride, bits, pbo);
     glActiveTexture(GL_TEXTURE0);
     glBindTexture(GL_TEXTURE_2D, tex);
 
diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c
index cf7197b..79e3e13 100644
--- a/glamor/glamor_putimage.c
+++ b/glamor/glamor_putimage.c
@@ -55,6 +55,7 @@ _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
     PixmapPtr temp_pixmap, sub_pixmap;
     glamor_pixmap_private *temp_pixmap_priv;
     BoxRec box;
+    int stride;
 
     glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off);
     clip = fbGetCompositeClip(gc);
@@ -78,6 +79,7 @@ _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
     }
     /* create a temporary pixmap and upload the bits to that
      * pixmap, then apply clip copy it to the destination pixmap.*/
+    stride = PixmapBytePad(w, depth);
     box.x1 = x + drawable->x;
     box.y1 = y + drawable->y;
     box.x2 = x + w + drawable->x;
@@ -97,7 +99,7 @@ _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
         }
 
         glamor_upload_sub_pixmap_to_texture(temp_pixmap, 0, 0, w, h,
-                                            pixmap->devKind, bits, 0);
+                                            stride, bits, 0);
 
         glamor_copy_area(&temp_pixmap->drawable, drawable, gc, 0, 0, w, h, x,
                          y);
@@ -106,7 +108,7 @@ _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
     else
         glamor_upload_sub_pixmap_to_texture(pixmap, x + drawable->x + x_off,
                                             y + drawable->y + y_off, w, h,
-                                            PixmapBytePad(w, depth), bits, 0);
+                                            stride, bits, 0);
     ret = TRUE;
     goto done;
 
-- 
1.9.2



More information about the xorg-devel mailing list