summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChia-I Wu <olv@lunarg.com>2010-03-14 11:34:16 +0800
committerChia-I Wu <olv@lunarg.com>2010-03-14 13:16:21 +0800
commit48bc3cca89f7aecc40d1661e695796113df6e583 (patch)
tree668376a26e8bd889475e0f123f3ad0b7a99f93b7
parent6632915e957149c153a3f793c400a532b4995b18 (diff)
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.
-rw-r--r--src/gallium/state_trackers/glx/xlib/xm_api.c2
-rw-r--r--src/gallium/state_trackers/glx/xlib/xm_api.h2
-rw-r--r--src/gallium/state_trackers/glx/xlib/xm_st.c53
-rw-r--r--src/gallium/state_trackers/glx/xlib/xm_st.h2
4 files changed, 53 insertions, 6 deletions
diff --git a/src/gallium/state_trackers/glx/xlib/xm_api.c b/src/gallium/state_trackers/glx/xlib/xm_api.c
index e7c1979b42..62a2bfcfa0 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 11a08962b7..4f2c8a6e6a 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 8714da8b34..de5a35edca 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;
@@ -82,6 +83,45 @@ xmesa_st_framebuffer_display(struct st_framebuffer_iface *stfbi,
}
/**
+ * 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.
*/
static void
@@ -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 b22a837380..396495c189 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);