[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