XXX: glamor: Fix glamor_upload_boxes and glamor_download_boxes for ES2
Maarten Lankhorst
maarten.lankhorst at canonical.com
Mon Jan 26 06:39:34 PST 2015
Some GLES2 implementations don't support GL_UNSIGNED_8888_REV and only
guarantee less fancy things to work. Use the infrastructure from glamor_pixmap.c
to implement glamor_upload_boxes, and use the glamor_es2_pixmap_read_prepare function
to implement glamor_download_boxes.
Contains a small hack in _glamor_upload_bits_to_pixmap_texture to take fastpath more often
and not regress previous users. Needs some input on how to fix this..
---
SetSpans and GetSpans are still using glamor_format_for_pixmap, so I guess they're buggy on es2 too.
Is there any testcase I could use to trigger those?
--- a/glamor/glamor_transfer.c
+++ b/glamor/glamor_transfer.c
@@ -52,30 +52,49 @@
}
/*
- * Write a region of bits into a pixmap
+ * Upload a region of data
*/
+
void
-glamor_upload_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
- int dx_src, int dy_src,
- int dx_dst, int dy_dst,
- uint8_t *bits, uint32_t byte_stride)
-{
- ScreenPtr screen = pixmap->drawable.pScreen;
- glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
- glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap);
- int box_x, box_y;
- int bytes_per_pixel = pixmap->drawable.bitsPerPixel >> 3;
- GLenum type;
- GLenum format;
+glamor_upload_region(PixmapPtr pixmap, RegionPtr region,
+ int region_x, int region_y,
+ uint8_t *bits, uint32_t byte_stride)
+{
+ glamor_upload_boxes(pixmap, RegionRects(region), RegionNumRects(region),
+ -region_x, -region_y,
+ 0, 0,
+ bits, byte_stride);
+}
- glamor_format_for_pixmap(pixmap, &format, &type);
+/*
+ * Take the data in the pixmap and stuff it back into the FBO
+ */
+void
+glamor_upload_pixmap(PixmapPtr pixmap)
+{
+ BoxRec box;
- glamor_make_current(glamor_priv);
+ box.x1 = 0;
+ box.x2 = pixmap->drawable.width;
+ box.y1 = 0;
+ box.y2 = pixmap->drawable.height;
+ glamor_upload_boxes(pixmap, &box, 1, 0, 0, 0, 0,
+ pixmap->devPrivate.ptr, pixmap->devKind);
+}
- glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+static void
+__glamor_download_boxes_noconv(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
+ int dx_src, int dy_src, int dx_dst, int dy_dst,
+ uint8_t *bits, uint32_t byte_stride, GLenum format, GLenum type)
+{
+ ScreenPtr screen = pixmap->drawable.pScreen;
+ int bytes_per_pixel = pixmap->drawable.bitsPerPixel >> 3;
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+ glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap);
+ int box_x, box_y;
- if (glamor_priv->has_unpack_subimage)
- glPixelStorei(GL_UNPACK_ROW_LENGTH, byte_stride / bytes_per_pixel);
+ if (glamor_priv->has_pack_subimage)
+ glPixelStorei(GL_PACK_ROW_LENGTH, byte_stride / bytes_per_pixel);
glamor_pixmap_loop(priv, box_x, box_y) {
BoxPtr box = glamor_pixmap_box_at(priv, box_x, box_y);
@@ -83,100 +102,115 @@
BoxPtr boxes = in_boxes;
int nbox = in_nbox;
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, fbo->tex);
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo->fb);
while (nbox--) {
/* compute drawable coordinates */
- int x1 = MAX(boxes->x1 + dx_dst, box->x1);
- int x2 = MIN(boxes->x2 + dx_dst, box->x2);
- int y1 = MAX(boxes->y1 + dy_dst, box->y1);
- int y2 = MIN(boxes->y2 + dy_dst, box->y2);
+ int x1 = MAX(boxes->x1 + dx_src, box->x1);
+ int x2 = MIN(boxes->x2 + dx_src, box->x2);
+ int y1 = MAX(boxes->y1 + dy_src, box->y1);
+ int y2 = MIN(boxes->y2 + dy_src, box->y2);
- size_t ofs = (y1 - dy_dst + dy_src) * byte_stride;
- ofs += (x1 - dx_dst + dx_src) * bytes_per_pixel;
+ size_t ofs = (y1 - dy_src + dy_dst) * byte_stride;
+ ofs += (x1 - dx_src + dx_dst) * bytes_per_pixel;
boxes++;
if (x2 <= x1 || y2 <= y1)
continue;
- if (glamor_priv->has_unpack_subimage ||
+ if (glamor_priv->has_pack_subimage ||
x2 - x1 == byte_stride / bytes_per_pixel) {
- glTexSubImage2D(GL_TEXTURE_2D, 0,
- x1 - box->x1, y1 - box->y1,
- x2 - x1, y2 - y1,
- format, type,
- bits + ofs);
+ glReadPixels(x1 - box->x1, y1 - box->y1, x2 - x1, y2 - y1, format, type, bits + ofs);
} else {
for (; y1 < y2; y1++, ofs += byte_stride)
- glTexSubImage2D(GL_TEXTURE_2D, 0,
- x1 - box->x1, y1 - box->y1,
- x2 - x1, 1,
- format, type,
- bits + ofs);
+ glReadPixels(x1 - box->x1, y1 - box->y1, x2 - x1, 1, format, type, bits + ofs);
}
}
}
- if (glamor_priv->has_unpack_subimage)
- glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
-}
-
-/*
- * Upload a region of data
- */
-
-void
-glamor_upload_region(PixmapPtr pixmap, RegionPtr region,
- int region_x, int region_y,
- uint8_t *bits, uint32_t byte_stride)
-{
- glamor_upload_boxes(pixmap, RegionRects(region), RegionNumRects(region),
- -region_x, -region_y,
- 0, 0,
- bits, byte_stride);
+ if (glamor_priv->has_pack_subimage)
+ glPixelStorei(GL_PACK_ROW_LENGTH, 0);
}
/*
- * Take the data in the pixmap and stuff it back into the FBO
- */
-void
-glamor_upload_pixmap(PixmapPtr pixmap)
+ * as gles2 only support a very small set of color format and
+ * type when do glReadPixel,
+ * Before we use glReadPixels to get back a textured pixmap,
+ * Use shader to convert it to a supported format and thus
+ * get a new temporary pixmap returned.
+ * */
+
+static glamor_pixmap_fbo *
+glamor_es2_pixmap_read_prepare(ScreenPtr screen, glamor_screen_private *glamor_priv,
+ glamor_pixmap_fbo *fbo, int x, int y, int w, int h,
+ GLenum format, GLenum type, int no_alpha,
+ int revert, int swap_rb)
{
- BoxRec box;
-
- box.x1 = 0;
- box.x2 = pixmap->drawable.width;
- box.y1 = 0;
- box.y2 = pixmap->drawable.height;
- glamor_upload_boxes(pixmap, &box, 1, 0, 0, 0, 0,
- pixmap->devPrivate.ptr, pixmap->devKind);
+ glamor_pixmap_fbo *temp_fbo;
+ float temp_xscale, temp_yscale, source_xscale, source_yscale;
+ static float vertices[8];
+ static float texcoords[8];
+
+ temp_fbo = glamor_create_fbo(glamor_priv, w, h, format, 0);
+ if (temp_fbo == NULL)
+ return NULL;
+
+ temp_xscale = 1.0 / w;
+ temp_yscale = 1.0 / h;
+
+ source_xscale = 1.0 / fbo->width;
+ source_yscale = 1.0 / fbo->height;
+
+ glamor_set_normalize_vcoords((struct glamor_pixmap_private *) NULL,
+ temp_xscale, temp_yscale, 0, 0, w, h,
+ vertices);
+
+ glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
+ 2 * sizeof(float), vertices);
+ glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
+
+ _glamor_set_normalize_tcoords(source_xscale,
+ source_yscale,
+ x, y,
+ x + w, y + h,
+ texcoords, 2);
+
+ glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE,
+ 2 * sizeof(float), texcoords);
+ glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, fbo->tex);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+ glamor_set_destination_pixmap_fbo(temp_fbo, 0, 0, w, h);
+ glamor_set_alu(screen, GXcopy);
+ glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
+ glUniform1i(glamor_priv->finish_access_revert[no_alpha], revert);
+ glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha], swap_rb);
+
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+ glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
+ glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
+ return temp_fbo;
}
-/*
- * Read stuff from the pixmap FBOs and write to memory
- */
-void
-glamor_download_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
- int dx_src, int dy_src,
- int dx_dst, int dy_dst,
- uint8_t *bits, uint32_t byte_stride)
+static void
+__glamor_download_boxes_revert(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
+ int dx_src, int dy_src, int dx_dst, int dy_dst,
+ uint8_t *bits, uint32_t byte_stride, GLenum format, GLenum type,
+ int no_alpha, int revert, int swap_rb)
{
ScreenPtr screen = pixmap->drawable.pScreen;
+ int bytes_per_pixel = pixmap->drawable.bitsPerPixel >> 3;
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap);
int box_x, box_y;
- int bytes_per_pixel = pixmap->drawable.bitsPerPixel >> 3;
- GLenum type;
- GLenum format;
- glamor_format_for_pixmap(pixmap, &format, &type);
-
- glamor_make_current(glamor_priv);
-
- glPixelStorei(GL_PACK_ALIGNMENT, 4);
if (glamor_priv->has_pack_subimage)
glPixelStorei(GL_PACK_ROW_LENGTH, byte_stride / bytes_per_pixel);
@@ -186,15 +220,15 @@
BoxPtr boxes = in_boxes;
int nbox = in_nbox;
- glBindFramebuffer(GL_FRAMEBUFFER, fbo->fb);
-
while (nbox--) {
+ glamor_pixmap_fbo *temp;
/* compute drawable coordinates */
- int x1 = MAX(boxes->x1 + dx_src, box->x1);
- int x2 = MIN(boxes->x2 + dx_src, box->x2);
- int y1 = MAX(boxes->y1 + dy_src, box->y1);
- int y2 = MIN(boxes->y2 + dy_src, box->y2);
+ int x1 = MAX(boxes->x1 + dx_src, box->x1);
+ int x2 = MIN(boxes->x2 + dx_src, box->x2);
+ int y1 = MAX(boxes->y1 + dy_src, box->y1);
+ int y2 = MIN(boxes->y2 + dy_src, box->y2);
+
size_t ofs = (y1 - dy_src + dy_dst) * byte_stride;
ofs += (x1 - dx_src + dx_dst) * bytes_per_pixel;
@@ -203,19 +237,60 @@
if (x2 <= x1 || y2 <= y1)
continue;
+ temp = glamor_es2_pixmap_read_prepare(screen, glamor_priv, fbo,
+ x1 - box->x1, y1 - box->y1,
+ x2 - x1, y2 - y1,
+ format, type, no_alpha,
+ revert, swap_rb);
+
if (glamor_priv->has_pack_subimage ||
x2 - x1 == byte_stride / bytes_per_pixel) {
- glReadPixels(x1 - box->x1, y1 - box->y1, x2 - x1, y2 - y1, format, type, bits + ofs);
+ glReadPixels(0, 0, x2 - x1, y2 - y1, format, type, bits + ofs);
} else {
- for (; y1 < y2; y1++, ofs += byte_stride)
- glReadPixels(x1 - box->x1, y1 - box->y1, x2 - x1, 1, format, type, bits + ofs);
+ for (y2 -= y1, y1 = 0; y1 < y2; y1++, ofs += byte_stride)
+ glReadPixels(0, y1, x2 - x1, 1, format, type, bits + ofs);
}
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ glamor_destroy_fbo(temp);
}
}
+
if (glamor_priv->has_pack_subimage)
glPixelStorei(GL_PACK_ROW_LENGTH, 0);
}
+
+/*
+ * Read stuff from the pixmap FBOs and write to memory
+ */
+void
+glamor_download_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
+ int dx_src, int dy_src,
+ int dx_dst, int dy_dst,
+ uint8_t *bits, uint32_t byte_stride)
+{
+ ScreenPtr screen = pixmap->drawable.pScreen;
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+ GLenum type, format;
+ int no_alpha, revert, swap_rb;
+
+ glamor_make_current(glamor_priv);
+
+ glamor_get_tex_format_type_from_pixmap(pixmap, &format, &type, &no_alpha, &revert, &swap_rb, 0);
+
+ glPixelStorei(GL_PACK_ALIGNMENT, 4);
+
+ if (revert == REVERT_NONE && swap_rb == SWAP_NONE_DOWNLOADING)
+ __glamor_download_boxes_noconv(pixmap, in_boxes, in_nbox,
+ dx_src, dy_src, dx_dst, dy_dst,
+ bits, byte_stride, format, type);
+ else
+ __glamor_download_boxes_revert(pixmap, in_boxes, in_nbox,
+ dx_src, dy_src, dx_dst, dy_dst,
+ bits, byte_stride, format, type,
+ no_alpha, revert, swap_rb);
+}
+
/*
* Read data from the pixmap FBO
*/
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -30,6 +30,8 @@
#include <stdlib.h>
#include "glamor_priv.h"
+#include "glamor_transfer.h"
+
/**
* Sets the offsets to add to coordinates to make them address the same bits in
* the backing drawable. These coordinates are nonzero only for redirected
@@ -457,7 +459,7 @@
return 0;
}
-static int
+int
glamor_get_tex_format_type_from_pixmap(PixmapPtr pixmap,
GLenum *format,
GLenum *type,
@@ -698,12 +700,13 @@
GLenum format,
GLenum type,
int x, int y, int w, int h,
- void *bits, int pbo)
+ void *bits, int stride, int bytes_per_pixel, int pbo)
{
glamor_screen_private *glamor_priv =
glamor_get_screen_private(pixmap->drawable.pScreen);
int non_sub = 0;
unsigned int iformat = 0;
+ int direct;
glamor_make_current(glamor_priv);
if (*tex == 0) {
@@ -723,10 +726,22 @@
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
}
- if (non_sub)
+
+ direct = glamor_priv->has_unpack_subimage || (w * bytes_per_pixel == stride);
+ if (non_sub && direct)
glTexImage2D(GL_TEXTURE_2D, 0, iformat, w, h, 0, format, type, bits);
- else
+ else if (!non_sub && direct)
glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, format, type, bits);
+ else {
+ if (non_sub)
+ glTexImage2D(GL_TEXTURE_2D, 0, iformat, w, h, 0, format, type, NULL);
+
+ while (h--) {
+ glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, 1, format, type, bits);
+ y--;
+ bits += stride;
+ }
+ }
if (bits == NULL)
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
@@ -743,7 +758,6 @@
glamor_screen_private *glamor_priv =
glamor_get_screen_private(pixmap->drawable.pScreen);
static float vertices[8];
-
static float texcoords_inv[8] = { 0, 0,
1, 0,
1, 1,
@@ -753,6 +767,7 @@
float dst_xscale, dst_yscale;
GLuint tex = 0;
int need_free_bits = 0;
+ int bytes_per_pixel = pixmap->drawable.bitsPerPixel >> 3;
if (bits == NULL)
goto ready_to_upload;
@@ -787,12 +802,7 @@
/* Try fast path firstly, upload the pixmap to the texture attached
* to the fbo directly. */
- if (no_alpha == 0
- && revert == REVERT_NONE && swap_rb == SWAP_NONE_UPLOADING
-#ifdef WALKAROUND_LARGE_TEXTURE_MAP
- && pixmap_priv->type != GLAMOR_TEXTURE_LARGE
-#endif
- ) {
+ if (revert == REVERT_NONE && swap_rb == SWAP_NONE_UPLOADING) {
int fbo_x_off, fbo_y_off;
assert(pixmap_priv->base.fbo->tex);
@@ -804,7 +814,7 @@
__glamor_upload_pixmap_to_texture(pixmap, &pixmap_priv->base.fbo->tex,
format, type,
x + fbo_x_off, y + fbo_y_off, w, h,
- bits, pbo);
+ bits, stride, bytes_per_pixel, pbo);
} else {
ptexcoords = texcoords_inv;
@@ -826,7 +836,7 @@
glamor_set_destination_pixmap_priv_nc(pixmap_priv);
glamor_set_alu(screen, GXcopy);
__glamor_upload_pixmap_to_texture(pixmap, &tex,
- format, type, 0, 0, w, h, bits, pbo);
+ format, type, 0, 0, w, h, bits, stride, bytes_per_pixel, pbo);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, tex);
@@ -1060,76 +1070,6 @@
return ret;
}
-/*
- * as gles2 only support a very small set of color format and
- * type when do glReadPixel,
- * Before we use glReadPixels to get back a textured pixmap,
- * Use shader to convert it to a supported format and thus
- * get a new temporary pixmap returned.
- * */
-
-glamor_pixmap_fbo *
-glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h,
- GLenum format, GLenum type, int no_alpha,
- int revert, int swap_rb)
-{
- glamor_pixmap_private *source_priv;
- glamor_screen_private *glamor_priv;
- ScreenPtr screen;
- glamor_pixmap_fbo *temp_fbo;
- float temp_xscale, temp_yscale, source_xscale, source_yscale;
- static float vertices[8];
- static float texcoords[8];
-
- screen = source->drawable.pScreen;
-
- glamor_priv = glamor_get_screen_private(screen);
- source_priv = glamor_get_pixmap_private(source);
- temp_fbo = glamor_create_fbo(glamor_priv, w, h, format, 0);
- if (temp_fbo == NULL)
- return NULL;
-
- glamor_make_current(glamor_priv);
- temp_xscale = 1.0 / w;
- temp_yscale = 1.0 / h;
-
- glamor_set_normalize_vcoords((struct glamor_pixmap_private *) NULL,
- temp_xscale, temp_yscale, 0, 0, w, h,
- vertices);
-
- glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
- 2 * sizeof(float), vertices);
- glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
-
- pixmap_priv_get_scale(source_priv, &source_xscale, &source_yscale);
- glamor_set_normalize_tcoords(source_priv, source_xscale,
- source_yscale,
- x, y,
- x + w, y + h,
- texcoords);
-
- glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE,
- 2 * sizeof(float), texcoords);
- glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, source_priv->base.fbo->tex);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-
- glamor_set_destination_pixmap_fbo(temp_fbo, 0, 0, w, h);
- glamor_set_alu(screen, GXcopy);
- glUseProgram(glamor_priv->finish_access_prog[no_alpha]);
- glUniform1i(glamor_priv->finish_access_revert[no_alpha], revert);
- glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha], swap_rb);
-
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-
- glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
- glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
- return temp_fbo;
-}
-
/* fixup a fbo to the exact size as the pixmap. */
/* XXX LARGE pixmap? */
Bool
@@ -1188,3 +1128,67 @@
return ret;
}
+
+
+/*
+ * Write a region of bits into a pixmap
+ */
+void
+glamor_upload_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
+ int dx_src, int dy_src,
+ int dx_dst, int dy_dst,
+ uint8_t *bits, uint32_t byte_stride)
+{
+ ScreenPtr screen = pixmap->drawable.pScreen;
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+ glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap);
+ int box_x, box_y;
+ int bytes_per_pixel = pixmap->drawable.bitsPerPixel >> 3;
+ GLenum type;
+ GLenum format;
+ int no_alpha, revert, swap_rb;
+
+ glamor_get_tex_format_type_from_pixmap(pixmap, &format, &type, &no_alpha, &revert, &swap_rb, 1);
+
+ glamor_make_current(glamor_priv);
+
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+
+ if (glamor_priv->has_unpack_subimage)
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, byte_stride / bytes_per_pixel);
+
+ glamor_pixmap_loop(priv, box_x, box_y) {
+ BoxPtr box = glamor_pixmap_box_at(priv, box_x, box_y);
+ glamor_pixmap_fbo *fbo = glamor_pixmap_fbo_at(priv, box_x, box_y);
+ BoxPtr boxes = in_boxes;
+ int nbox = in_nbox;
+
+ while (nbox--) {
+
+ /* compute drawable coordinates */
+ int x1 = MAX(boxes->x1 + dx_dst, box->x1);
+ int x2 = MIN(boxes->x2 + dx_dst, box->x2);
+ int y1 = MAX(boxes->y1 + dy_dst, box->y1);
+ int y2 = MIN(boxes->y2 + dy_dst, box->y2);
+
+ size_t ofs = (y1 - dy_dst + dy_src) * byte_stride;
+ ofs += (x1 - dx_dst + dx_src) * bytes_per_pixel;
+
+ boxes++;
+
+ if (x2 <= x1 || y2 <= y1)
+ continue;
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, fbo->tex);
+ _glamor_upload_bits_to_pixmap_texture(pixmap, format, type,
+ no_alpha, revert, swap_rb,
+ x1, y1, x2 - x1, y2 - y1,
+ byte_stride, bits + ofs, 0);
+ }
+ }
+
+ if (glamor_priv->has_unpack_subimage)
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+}
+
More information about the xorg-devel
mailing list