[Glamor] [PATCH 1/2] glamor: Add in support for the stride parameter when uploading texture data

Anthony Waters awaters1 at gmail.com
Wed Jan 29 08:21:13 PST 2014


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.

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

Signed-off-by: Anthony Waters <awaters1 at gmail.com>
---
 src/glamor_pixmap.c   | 18 ++++++++++++++----
 src/glamor_putimage.c |  8 ++++----
 src/glamor_utils.h    | 20 ++++++++++++++++++++
 3 files changed, 38 insertions(+), 8 deletions(-)

diff --git a/src/glamor_pixmap.c b/src/glamor_pixmap.c
index 84694ec..b34cf5b 100644
--- a/src/glamor_pixmap.c
+++ b/src/glamor_pixmap.c
@@ -387,7 +387,7 @@ 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 =
@@ -395,6 +395,12 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, unsigned int *tex,
 	glamor_gl_dispatch *dispatch;
 	int non_sub = 0;
 	unsigned int iformat = 0;
+	int bpp = depth_for_type(type);
+	int alignment = bpp / 8;
+	if (stride == 0) {
+		alignment = 4;
+	}
+
 
 	dispatch = glamor_get_dispatch(glamor_priv);
 	if (*tex == 0) {
@@ -412,11 +418,13 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, unsigned int *tex,
 				  GL_NEAREST);
 	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
 				  GL_NEAREST);
-	dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+	dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, alignment);
 
 	if (bits == NULL)
 		dispatch->glBindBuffer(GL_PIXEL_UNPACK_BUFFER,
 				       pbo);
+
+	dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, stride / alignment);
 	if (non_sub)
 		dispatch->glTexImage2D(GL_TEXTURE_2D,
 				       0, iformat, w, h, 0,
@@ -428,6 +436,8 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, unsigned int *tex,
 					  format, type,
 					  bits);
 
+	dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+
 	if (bits == NULL)
 		dispatch->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
 	glamor_put_dispatch(glamor_priv);
@@ -511,7 +521,7 @@ ready_to_upload:
 		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;
 	}
@@ -542,7 +552,7 @@ ready_to_upload:
 	glamor_set_destination_pixmap_priv_nc(pixmap_priv);
 	__glamor_upload_pixmap_to_texture(pixmap, &tex,
 					  format, type,
-					  0, 0, w, h,
+					  0, 0, w, h, stride,
 					  bits, pbo);
 	dispatch->glActiveTexture(GL_TEXTURE0);
 	dispatch->glBindTexture(GL_TEXTURE_2D, tex);
diff --git a/src/glamor_putimage.c b/src/glamor_putimage.c
index 99f7ac6..8b36f45 100644
--- a/src/glamor_putimage.c
+++ b/src/glamor_putimage.c
@@ -300,13 +300,13 @@ _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);
-
+	    		                            0, bits, 0);
 		glamor_copy_area(&temp_pixmap->drawable, drawable, gc, 0, 0, w, h, x, y);
 		glamor_destroy_pixmap(temp_pixmap);
-	} else
+	} 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);
+	    		                            w, h, 0, bits, 0);
+	}
 	ret = TRUE;
 	goto done;
 
diff --git a/src/glamor_utils.h b/src/glamor_utils.h
index d307838..cf0f1eb 100644
--- a/src/glamor_utils.h
+++ b/src/glamor_utils.h
@@ -880,6 +880,26 @@ format_for_depth(int depth)
 	}
 }
 
+static inline int
+depth_for_type(GLenum type)
+{
+	switch (type) {
+	case GL_UNSIGNED_BYTE:
+		return 8;
+	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:
+		return 32;
+	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:
+		return 16;
+	default:
+		return 0;
+	}
+}
+
 static inline void
 gl_iformat_for_depth(int depth, GLenum * format)
 {
-- 
1.8.5.3



More information about the Glamor mailing list