From: Benjamin Franzke Date: Fri, 9 Sep 2011 08:12:23 +0000 (+0200) Subject: st/dri/sw: Implement texture_from_pixmap X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=98aa2a8f725e44aec8bd998fe436a134e94f13bb;p=mesa.git st/dri/sw: Implement texture_from_pixmap 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: Stuart Abercrombie CC: Stéphane Marchesin --- 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; }