Mesa (master): st/glx: Implement texture_from_pixmap without DRI.
Stephane Marchesin
marcheu at kemper.freedesktop.org
Tue Oct 25 21:37:43 UTC 2011
Module: Mesa
Branch: master
Commit: 00ddc7ea47fdae09ca154d8b3a15c6f9a4926d68
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=00ddc7ea47fdae09ca154d8b3a15c6f9a4926d68
Author: Stéphane Marchesin <marcheu at chromium.org>
Date: Mon Oct 24 12:03:16 2011 -0700
st/glx: Implement texture_from_pixmap without DRI.
Makes texture_from_pixmap work with non-DRI llvmpipe.
---
src/gallium/state_trackers/glx/xlib/xm_api.c | 96 +++++++++++++++++++++++++-
src/gallium/state_trackers/glx/xlib/xm_st.c | 38 ++++++++--
src/gallium/state_trackers/glx/xlib/xm_st.h | 11 +++
3 files changed, 136 insertions(+), 9 deletions(-)
diff --git a/src/gallium/state_trackers/glx/xlib/xm_api.c b/src/gallium/state_trackers/glx/xlib/xm_api.c
index ed786ca..d80e7c8 100644
--- a/src/gallium/state_trackers/glx/xlib/xm_api.c
+++ b/src/gallium/state_trackers/glx/xlib/xm_api.c
@@ -56,10 +56,13 @@
#include "xm_api.h"
#include "xm_st.h"
+#include "pipe/p_context.h"
#include "pipe/p_defines.h"
#include "pipe/p_screen.h"
-#include "pipe/p_context.h"
+#include "pipe/p_state.h"
+
#include "util/u_atomic.h"
+#include "util/u_inlines.h"
#include "xm_public.h"
#include <GL/glx.h>
@@ -1306,12 +1309,103 @@ void XMesaGarbageCollect( void )
}
+static enum st_attachment_type xmesa_attachment_type(int glx_attachment)
+{
+ switch(glx_attachment) {
+ case GLX_FRONT_LEFT_EXT:
+ return ST_ATTACHMENT_FRONT_LEFT;
+ case GLX_FRONT_RIGHT_EXT:
+ return ST_ATTACHMENT_FRONT_RIGHT;
+ case GLX_BACK_LEFT_EXT:
+ return ST_ATTACHMENT_BACK_LEFT;
+ case GLX_BACK_RIGHT_EXT:
+ return ST_ATTACHMENT_BACK_RIGHT;
+ default:
+ assert(0);
+ return ST_ATTACHMENT_FRONT_LEFT;
+ }
+}
PUBLIC void
XMesaBindTexImage(Display *dpy, XMesaBuffer drawable, int buffer,
const int *attrib_list)
{
+ struct st_context_iface *st = stapi->get_current(stapi);
+ struct st_framebuffer_iface* stfbi = drawable->stfb;
+ struct pipe_resource *res;
+ int x, y, w, h;
+ XMesaContext xmesa = XMesaGetCurrentContext();
+ enum st_attachment_type st_attachment = xmesa_attachment_type(buffer);
+
+ x = 0;
+ y = 0;
+ w = drawable->width;
+ h = drawable->height;
+
+ /* We need to validate our attachments before using them,
+ * in case the texture doesn't exist yet. */
+ xmesa_st_framebuffer_validate_textures(stfbi, w, h, 1 << st_attachment);
+ res = xmesa_get_attachment(stfbi, st_attachment);
+
+ if (res) {
+ struct pipe_context* pipe = xmesa_get_context(stfbi);
+ enum pipe_format internal_format = res->format;
+ struct pipe_transfer *tex_xfer;
+ char *map;
+ int line, ximage_stride;
+
+ internal_format = choose_pixel_format(drawable->xm_visual);
+
+ tex_xfer = pipe_get_transfer(pipe, res,
+ 0, 0, /* level, layer */
+ PIPE_TRANSFER_WRITE,
+ x, y,
+ w, h);
+ if (!tex_xfer)
+ return;
+
+ /* Grab the XImage that we want to turn into a texture. */
+ XImage *img = XGetImage(dpy,
+ drawable->ws.drawable,
+ x, y,
+ w, h,
+ AllPlanes,
+ ZPixmap);
+
+ if (!img) {
+ pipe_transfer_destroy(pipe, tex_xfer);
+ return;
+ }
+
+ map = pipe_transfer_map(pipe, tex_xfer);
+
+ if (!map) {
+ pipe_transfer_destroy(pipe, tex_xfer);
+ return;
+ }
+
+ /* The pipe transfer has a pitch rounded up to the nearest 64 pixels.
+ We assume 32 bit pixels. */
+ ximage_stride = w * 4;
+
+ for (line = 0; line < h; line++)
+ memcpy(&map[line * tex_xfer->stride],
+ &img->data[line * ximage_stride],
+ ximage_stride);
+
+ pipe_transfer_unmap(pipe, tex_xfer);
+
+ pipe_transfer_destroy(pipe, tex_xfer);
+
+ st->teximage(st,
+ ST_TEXTURE_2D,
+ 0, /* level */
+ internal_format,
+ res,
+ FALSE /* no mipmap */);
+
+ }
}
diff --git a/src/gallium/state_trackers/glx/xlib/xm_st.c b/src/gallium/state_trackers/glx/xlib/xm_st.c
index ec3f531..f6439dc 100644
--- a/src/gallium/state_trackers/glx/xlib/xm_st.c
+++ b/src/gallium/state_trackers/glx/xlib/xm_st.c
@@ -97,13 +97,7 @@ xmesa_st_framebuffer_copy_textures(struct st_framebuffer_iface *stfbi,
if (!src_ptex || !dst_ptex)
return;
- pipe = xstfb->display->pipe;
- if (!pipe) {
- pipe = xstfb->screen->context_create(xstfb->screen, NULL);
- if (!pipe)
- return;
- xstfb->display->pipe = pipe;
- }
+ pipe = xmesa_get_context(stfbi);
u_box_2d(x, y, width, height, &src_box);
@@ -116,7 +110,7 @@ xmesa_st_framebuffer_copy_textures(struct st_framebuffer_iface *stfbi,
* Remove outdated textures and create the requested ones.
* This is a helper used during framebuffer validation.
*/
-static boolean
+boolean
xmesa_st_framebuffer_validate_textures(struct st_framebuffer_iface *stfbi,
unsigned width, unsigned height,
unsigned mask)
@@ -362,3 +356,31 @@ xmesa_copy_st_framebuffer(struct st_framebuffer_iface *stfbi,
if (dst == ST_ATTACHMENT_FRONT_LEFT)
xmesa_st_framebuffer_display(stfbi, dst);
}
+
+struct pipe_resource*
+xmesa_get_attachment(struct st_framebuffer_iface *stfbi,
+ enum st_attachment_type st_attachment)
+{
+ struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
+ struct pipe_resource* res;
+
+ res = xstfb->textures[st_attachment];
+ return res;
+}
+
+struct pipe_context*
+xmesa_get_context(struct st_framebuffer_iface* stfbi)
+{
+ struct pipe_context *pipe;
+ struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
+
+ pipe = xstfb->display->pipe;
+ if (!pipe) {
+ pipe = xstfb->screen->context_create(xstfb->screen, NULL);
+ if (!pipe)
+ return NULL;
+ xstfb->display->pipe = pipe;
+ }
+ return pipe;
+}
+
diff --git a/src/gallium/state_trackers/glx/xlib/xm_st.h b/src/gallium/state_trackers/glx/xlib/xm_st.h
index 8625976..a293728 100644
--- a/src/gallium/state_trackers/glx/xlib/xm_st.h
+++ b/src/gallium/state_trackers/glx/xlib/xm_st.h
@@ -49,4 +49,15 @@ xmesa_copy_st_framebuffer(struct st_framebuffer_iface *stfbi,
enum st_attachment_type dst,
int x, int y, int w, int h);
+struct pipe_resource*
+xmesa_get_attachment(struct st_framebuffer_iface *stfbi,
+ enum st_attachment_type st_attachment);
+
+struct pipe_context*
+xmesa_get_context(struct st_framebuffer_iface* stfbi);
+
+boolean
+xmesa_st_framebuffer_validate_textures(struct st_framebuffer_iface *stfbi,
+ unsigned width, unsigned height,
+ unsigned mask);
#endif /* _XM_ST_H_ */
More information about the mesa-commit
mailing list