st/glx: Add support for GLX_MESA_copy_sub_buffer.
authorChia-I Wu <olv@lunarg.com>
Sun, 14 Mar 2010 03:34:16 +0000 (11:34 +0800)
committerChia-I Wu <olv@lunarg.com>
Sun, 14 Mar 2010 05:16:21 +0000 (13:16 +0800)
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.

src/gallium/state_trackers/glx/xlib/xm_api.c
src/gallium/state_trackers/glx/xlib/xm_api.h
src/gallium/state_trackers/glx/xlib/xm_st.c
src/gallium/state_trackers/glx/xlib/xm_st.h

index e7c1979b4243723be2fb6a31624f2b5bc0f4c80f..62a2bfcfa070be73105f26cc44af63251c56a7e7 100644 (file)
@@ -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;
index 11a08962b74e50fe86b68821573c18127ddeb753..4f2c8a6e6a9a8ddf25d9a1db3e159d99f421e56e 100644 (file)
@@ -79,6 +79,8 @@ struct xmesa_display {
    Display *display;
    struct pipe_screen *screen;
    struct st_manager *smapi;
+
+   struct pipe_context *pipe;
 };
 
 
index 8714da8b346474c34bc55dfdfe66c31c2199cfee..de5a35edca4ea1e5854c27e2fe7ccce7fe98153d 100644 (file)
@@ -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);
 }
index b22a8373801b01a1e5d60f385739abea51c1e206..396495c18938f6c8863ae12cb0854aac9a05ad74 100644 (file)
@@ -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);