summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Sapountzis <gsapountzis@gmail.com>2011-11-02 15:02:10 +0200
committerGeorge Sapountzis <gsapountzis@gmail.com>2011-11-02 15:33:28 +0200
commit645dc52bca3a5164e88a7159c3f082bd7d642feb (patch)
treecad91296f7577b0dd160282688ffc11c1df9aee2
parent821999a1ea4f849296dbde43c049eaea73c80236 (diff)
st/dri/sw: Implement texture_from_pixmaptfp
This is a cleanup of commit 02f1b50987c0d24da3dcc36dbb44821c20d0660c. Update tex buffer using a dri_drawable hook from implemented in sw/drisw.c. This saves us the duplication of dri_drawable.c. CC: Benjamin Franzke <benjaminfranzke@googlemail.com> CC: Stuart Abercrombie <sabercrombie at chromium.org> CC: Stéphane Marchesin <marcheu at chromium.org> see: http://lists.freedesktop.org/archives/mesa-dev/2011-September/011890.html TODO: check if GetImage works with different pitch, similar to PutImage, to avoid the extra copy, ala dri_sw_displaytarget_display() in src/gallium/winsys/sw/dri/dri_sw_winsys.c
-rw-r--r--src/gallium/state_trackers/dri/common/dri_drawable.c3
-rw-r--r--src/gallium/state_trackers/dri/common/dri_drawable.h4
-rw-r--r--src/gallium/state_trackers/dri/drm/dri2.c9
-rw-r--r--src/gallium/state_trackers/dri/sw/drisw.c61
4 files changed, 72 insertions, 5 deletions
diff --git a/src/gallium/state_trackers/dri/common/dri_drawable.c b/src/gallium/state_trackers/dri/common/dri_drawable.c
index 340404e6aa4..485616fde6c 100644
--- a/src/gallium/state_trackers/dri/common/dri_drawable.c
+++ b/src/gallium/state_trackers/dri/common/dri_drawable.c
@@ -207,6 +207,7 @@ dri_set_tex_buffer2(__DRIcontext *pDRICtx, GLint target,
dri_drawable_validate_att(drawable, ST_ATTACHMENT_FRONT_LEFT);
+ /* Use the pipe resource associated with the X drawable */
pt = drawable->textures[ST_ATTACHMENT_FRONT_LEFT];
if (pt) {
@@ -226,6 +227,8 @@ dri_set_tex_buffer2(__DRIcontext *pDRICtx, GLint target,
}
}
+ drawable->update_tex_buffer(drawable, ctx, pt);
+
ctx->st->teximage(ctx->st,
(target == GL_TEXTURE_2D) ? ST_TEXTURE_2D : ST_TEXTURE_RECT,
0, internal_format, pt, FALSE);
diff --git a/src/gallium/state_trackers/dri/common/dri_drawable.h b/src/gallium/state_trackers/dri/common/dri_drawable.h
index 007421ebe18..3e3876e74a5 100644
--- a/src/gallium/state_trackers/dri/common/dri_drawable.h
+++ b/src/gallium/state_trackers/dri/common/dri_drawable.h
@@ -77,6 +77,10 @@ struct dri_drawable
void (*flush_frontbuffer)(struct dri_drawable *drawable,
enum st_attachment_type statt);
+
+ void (*update_tex_buffer)(struct dri_drawable *drawable,
+ struct dri_context *ctx,
+ struct pipe_resource *res);
};
static INLINE struct dri_drawable *
diff --git a/src/gallium/state_trackers/dri/drm/dri2.c b/src/gallium/state_trackers/dri/drm/dri2.c
index f3c9e1053cb..2e0bb7eecf1 100644
--- a/src/gallium/state_trackers/dri/drm/dri2.c
+++ b/src/gallium/state_trackers/dri/drm/dri2.c
@@ -380,6 +380,14 @@ dri2_flush_frontbuffer(struct dri_drawable *drawable,
}
}
+static void
+dri2_update_tex_buffer(struct dri_drawable *drawable,
+ struct dri_context *ctx,
+ struct pipe_resource *res)
+{
+ /* no-op */
+}
+
static __DRIimage *
dri2_lookup_egl_image(struct dri_screen *screen, void *handle)
{
@@ -707,6 +715,7 @@ dri2_create_buffer(__DRIscreen * sPriv,
drawable->allocate_textures = dri2_allocate_textures;
drawable->flush_frontbuffer = dri2_flush_frontbuffer;
+ drawable->update_tex_buffer = dri2_update_tex_buffer;
return TRUE;
}
diff --git a/src/gallium/state_trackers/dri/sw/drisw.c b/src/gallium/state_trackers/dri/sw/drisw.c
index 082df55e8ea..48916a60da9 100644
--- a/src/gallium/state_trackers/dri/sw/drisw.c
+++ b/src/gallium/state_trackers/dri/sw/drisw.c
@@ -28,7 +28,7 @@
/* TODO:
*
- * xshm / texture_from_pixmap / EGLImage:
+ * xshm / EGLImage:
*
* Allow the loaders to use the XSHM extension. It probably requires callbacks
* for createImage/destroyImage similar to DRI2 getBuffers.
@@ -39,6 +39,7 @@
#include "util/u_inlines.h"
#include "pipe/p_context.h"
#include "state_tracker/drisw_api.h"
+#include "state_tracker/st_context.h"
#include "dri_screen.h"
#include "dri_context.h"
@@ -48,14 +49,13 @@ DEBUG_GET_ONCE_BOOL_OPTION(swrast_no_present, "SWRAST_NO_PRESENT", FALSE);
static boolean swrast_no_present = FALSE;
static INLINE void
-get_drawable_info(__DRIdrawable *dPriv, int *w, int *h)
+get_drawable_info(__DRIdrawable *dPriv, int *x, int *y, int *w, int *h)
{
__DRIscreen *sPriv = dPriv->driScreenPriv;
const __DRIswrastLoaderExtension *loader = sPriv->swrast_loader;
- int x, y;
loader->getDrawableInfo(dPriv,
- &x, &y, w, h,
+ x, y, w, h,
dPriv->loaderPrivate);
}
@@ -70,12 +70,24 @@ put_image(__DRIdrawable *dPriv, void *data, unsigned width, unsigned height)
data, dPriv->loaderPrivate);
}
+static INLINE void
+get_image(__DRIdrawable *dPriv, void *data, int x, int y, int width, int height)
+{
+ __DRIscreen *sPriv = dPriv->driScreenPriv;
+ const __DRIswrastLoaderExtension *loader = sPriv->swrast_loader;
+
+ loader->getImage(dPriv,
+ x, y, width, height,
+ data, dPriv->loaderPrivate);
+}
+
static void
drisw_update_drawable_info(struct dri_drawable *drawable)
{
__DRIdrawable *dPriv = drawable->dPriv;
+ int x, y;
- get_drawable_info(dPriv, &dPriv->w, &dPriv->h);
+ get_drawable_info(dPriv, &x, &y, &dPriv->w, &dPriv->h);
}
static void
@@ -228,6 +240,44 @@ drisw_allocate_textures(struct dri_drawable *drawable,
drawable->old_h = height;
}
+static void
+drisw_update_tex_buffer(struct dri_drawable *drawable,
+ struct dri_context *ctx,
+ struct pipe_resource *res)
+{
+ __DRIdrawable *dPriv = drawable->dPriv;
+
+ struct st_context *st_ctx = (struct st_context *)ctx->st;
+ struct pipe_context *pipe = st_ctx->pipe;
+ struct pipe_transfer *transfer;
+ char *map;
+ int x, y, w, h;
+ int ximage_stride, line;
+
+ get_drawable_info(dPriv, &x, &y, &w, &h);
+
+ transfer = pipe_get_transfer(pipe, res,
+ 0, 0, // level, layer,
+ PIPE_TRANSFER_WRITE,
+ x, y, w, h);
+ map = pipe_transfer_map(pipe, transfer);
+
+ /* Copy the Drawable content to the mapped texture buffer */
+ get_image(dPriv, map, x, y, w, h);
+
+ /* The pipe transfer has a pitch rounded up to the nearest 64 pixels.
+ We assume 32 bit pixels. */
+ ximage_stride = w * 4;
+ for (line = h-1; line; --line) {
+ memmove(&map[line * transfer->stride],
+ &map[line * ximage_stride],
+ ximage_stride);
+ }
+
+ pipe_transfer_unmap(pipe, transfer);
+ pipe_transfer_destroy(pipe, transfer);
+}
+
/*
* Backend function for init_screen.
*/
@@ -289,6 +339,7 @@ drisw_create_buffer(__DRIscreen * sPriv,
drawable->allocate_textures = drisw_allocate_textures;
drawable->update_drawable_info = drisw_update_drawable_info;
drawable->flush_frontbuffer = drisw_flush_frontbuffer;
+ drawable->update_tex_buffer = drisw_update_tex_buffer;
return TRUE;
}