summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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.c49
4 files changed, 60 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..f336fe075f8 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);
}
@@ -74,8 +74,9 @@ 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 +229,43 @@ 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)
+{
+ struct pipe_context *pipe = ((struct st_context *) ctx)->st->pipe;
+ __DRIdrawable *dPriv = drawable->dPriv;
+ __DRIscreen *sPriv = dPriv->driScreenPriv;
+ int x, y, w, h;
+ struct pipe_transfer *transfer;
+ char *map;
+ 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 */
+ sPriv->swrast_loader->getImage(dPriv, x, y, w, h, map, dPriv->loaderPrivate);
+
+ /* 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 +327,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;
}