From: Chia-I Wu Date: Sun, 14 Mar 2010 03:34:16 +0000 (+0800) Subject: st/glx: Add support for GLX_MESA_copy_sub_buffer. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=48bc3cca89f7aecc40d1661e695796113df6e583;p=mesa.git st/glx: Add support for GLX_MESA_copy_sub_buffer. Create a per-display pipe_context as needed to copy the contents between framebuffer attachments. This allows us to support GLX_MESA_copy_sub_buffer. --- diff --git a/src/gallium/state_trackers/glx/xlib/xm_api.c b/src/gallium/state_trackers/glx/xlib/xm_api.c index e7c1979b424..62a2bfcfa07 100644 --- a/src/gallium/state_trackers/glx/xlib/xm_api.c +++ b/src/gallium/state_trackers/glx/xlib/xm_api.c @@ -398,7 +398,7 @@ create_xmesa_buffer(Drawable d, BufferType type, /* * Create framebuffer, but we'll plug in our own renderbuffers below. */ - b->stfb = xmesa_create_st_framebuffer(xmdpy->screen, b); + b->stfb = xmesa_create_st_framebuffer(xmdpy, b); /* GLX_EXT_texture_from_pixmap */ b->TextureTarget = 0; diff --git a/src/gallium/state_trackers/glx/xlib/xm_api.h b/src/gallium/state_trackers/glx/xlib/xm_api.h index 11a08962b74..4f2c8a6e6a9 100644 --- a/src/gallium/state_trackers/glx/xlib/xm_api.h +++ b/src/gallium/state_trackers/glx/xlib/xm_api.h @@ -79,6 +79,8 @@ struct xmesa_display { Display *display; struct pipe_screen *screen; struct st_manager *smapi; + + struct pipe_context *pipe; }; diff --git a/src/gallium/state_trackers/glx/xlib/xm_st.c b/src/gallium/state_trackers/glx/xlib/xm_st.c index 8714da8b346..de5a35edca4 100644 --- a/src/gallium/state_trackers/glx/xlib/xm_st.c +++ b/src/gallium/state_trackers/glx/xlib/xm_st.c @@ -32,8 +32,9 @@ #include "xm_st.h" struct xmesa_st_framebuffer { - struct pipe_screen *screen; + XMesaDisplay display; XMesaBuffer buffer; + struct pipe_screen *screen; struct st_visual stvis; @@ -81,6 +82,45 @@ xmesa_st_framebuffer_display(struct st_framebuffer_iface *stfbi, return TRUE; } +/** + * Copy the contents between the attachments. + */ +static void +xmesa_st_framebuffer_copy_textures(struct st_framebuffer_iface *stfbi, + enum st_attachment_type src_statt, + enum st_attachment_type dst_statt, + unsigned x, unsigned y, + unsigned width, unsigned height) +{ + struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi); + struct pipe_texture *src_ptex = xstfb->textures[src_statt]; + struct pipe_texture *dst_ptex = xstfb->textures[dst_statt]; + struct pipe_surface *src, *dst; + struct pipe_context *pipe; + + 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; + } + + src = xstfb->screen->get_tex_surface(xstfb->screen, + src_ptex, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ); + dst = xstfb->screen->get_tex_surface(xstfb->screen, + dst_ptex, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_WRITE); + + if (src && dst) + pipe->surface_copy(pipe, dst, 0, 0, src, 0, 0, src->width, src->height); + + pipe_surface_reference(&src, NULL); + pipe_surface_reference(&dst, NULL); +} + /** * Remove outdated textures and create the requested ones. */ @@ -194,11 +234,13 @@ xmesa_st_framebuffer_flush_front(struct st_framebuffer_iface *stfbi, } struct st_framebuffer_iface * -xmesa_create_st_framebuffer(struct pipe_screen *screen, XMesaBuffer b) +xmesa_create_st_framebuffer(XMesaDisplay xmdpy, XMesaBuffer b) { struct st_framebuffer_iface *stfbi; struct xmesa_st_framebuffer *xstfb; + assert(xmdpy->display == b->xm_visual->display); + stfbi = CALLOC_STRUCT(st_framebuffer_iface); xstfb = CALLOC_STRUCT(xmesa_st_framebuffer); if (!stfbi || !xstfb) { @@ -209,8 +251,9 @@ xmesa_create_st_framebuffer(struct pipe_screen *screen, XMesaBuffer b) return NULL; } - xstfb->screen = screen; + xstfb->display = xmdpy; xstfb->buffer = b; + xstfb->screen = xmdpy->screen; xstfb->stvis = b->xm_visual->stvis; stfbi->visual = &xstfb->stvis; @@ -265,5 +308,7 @@ xmesa_copy_st_framebuffer(struct st_framebuffer_iface *stfbi, enum st_attachment_type dst, int x, int y, int w, int h) { - /* TODO */ + xmesa_st_framebuffer_copy_textures(stfbi, src, dst, x, y, w, h); + if (dst == ST_ATTACHMENT_FRONT_LEFT) + xmesa_st_framebuffer_display(stfbi, dst); } diff --git a/src/gallium/state_trackers/glx/xlib/xm_st.h b/src/gallium/state_trackers/glx/xlib/xm_st.h index b22a8373801..396495c1893 100644 --- a/src/gallium/state_trackers/glx/xlib/xm_st.h +++ b/src/gallium/state_trackers/glx/xlib/xm_st.h @@ -34,7 +34,7 @@ #include "xm_api.h" struct st_framebuffer_iface * -xmesa_create_st_framebuffer(struct pipe_screen *screen, XMesaBuffer b); +xmesa_create_st_framebuffer(XMesaDisplay xmdpy, XMesaBuffer b); void xmesa_destroy_st_framebuffer(struct st_framebuffer_iface *stfbi);