From ba00f2f6f54cbc5ffdb0f0b94bcd672d147cdc36 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 28 Nov 2013 11:08:11 +1000 Subject: swrast* (gallium, classic): add MESA_copy_sub_buffer support (v3) This patches add MESA_copy_sub_buffer support to the dri sw loader and then to gallium state tracker, llvmpipe, softpipe and other bits. It reuses the dri1 driver extension interface, and it updates the swrast loader interface for a new putimage which can take a stride. I've tested this with gnome-shell with a cogl hacked to reenable sub copies for llvmpipe and the one piglit test. I could probably split this patch up as well. v2: pass a pipe_box, to reduce the entrypoints, as per Jose's review, add to p_screen doc comments. v3: finish off winsys interfaces, add swrast classic support as well. Reviewed-by: Jose Fonseca Signed-off-by: Dave Airlie swrast: add support for copy_sub_buffer --- src/gallium/state_trackers/dri/sw/drisw.c | 58 ++++++++++++++++++++-- .../state_trackers/egl/common/native_helper.c | 2 +- src/gallium/state_trackers/egl/x11/native_ximage.c | 2 +- src/gallium/state_trackers/glx/xlib/xm_st.c | 2 +- src/gallium/state_trackers/vdpau/presentation.c | 2 +- src/gallium/state_trackers/xvmc/surface.c | 2 +- 6 files changed, 59 insertions(+), 9 deletions(-) (limited to 'src/gallium/state_trackers') diff --git a/src/gallium/state_trackers/dri/sw/drisw.c b/src/gallium/state_trackers/dri/sw/drisw.c index 9f00a53152e..64a64af14ec 100644 --- a/src/gallium/state_trackers/dri/sw/drisw.c +++ b/src/gallium/state_trackers/dri/sw/drisw.c @@ -37,6 +37,7 @@ #include "util/u_format.h" #include "util/u_memory.h" #include "util/u_inlines.h" +#include "util/u_box.h" #include "pipe/p_context.h" #include "state_tracker/drisw_api.h" #include "state_tracker/st_context.h" @@ -70,6 +71,18 @@ put_image(__DRIdrawable *dPriv, void *data, unsigned width, unsigned height) data, dPriv->loaderPrivate); } +static INLINE void +put_image2(__DRIdrawable *dPriv, void *data, int x, int y, + unsigned width, unsigned height, unsigned stride) +{ + __DRIscreen *sPriv = dPriv->driScreenPriv; + const __DRIswrastLoaderExtension *loader = sPriv->swrast_loader; + + loader->putImage2(dPriv, __DRI_SWRAST_IMAGE_OP_SWAP, + x, y, width, height, stride, + data, dPriv->loaderPrivate); +} + static INLINE void get_image(__DRIdrawable *dPriv, int x, int y, int width, int height, void *data) { @@ -99,9 +112,19 @@ drisw_put_image(struct dri_drawable *drawable, put_image(dPriv, data, width, height); } +static void +drisw_put_image2(struct dri_drawable *drawable, + void *data, int x, int y, unsigned width, unsigned height, + unsigned stride) +{ + __DRIdrawable *dPriv = drawable->dPriv; + + put_image2(dPriv, data, x, y, width, height, stride); +} + static INLINE void drisw_present_texture(__DRIdrawable *dPriv, - struct pipe_resource *ptex) + struct pipe_resource *ptex, struct pipe_box *sub_box) { struct dri_drawable *drawable = dri_drawable(dPriv); struct dri_screen *screen = dri_screen(drawable->sPriv); @@ -109,7 +132,7 @@ drisw_present_texture(__DRIdrawable *dPriv, if (swrast_no_present) return; - screen->base.screen->flush_frontbuffer(screen->base.screen, ptex, 0, 0, drawable); + screen->base.screen->flush_frontbuffer(screen->base.screen, ptex, 0, 0, drawable, sub_box); } static INLINE void @@ -126,7 +149,7 @@ static INLINE void drisw_copy_to_front(__DRIdrawable * dPriv, struct pipe_resource *ptex) { - drisw_present_texture(dPriv, ptex); + drisw_present_texture(dPriv, ptex, NULL); drisw_invalidate_drawable(dPriv); } @@ -157,6 +180,30 @@ drisw_swap_buffers(__DRIdrawable *dPriv) } } +static void +drisw_copy_sub_buffer(__DRIdrawable *dPriv, int x, int y, + int w, int h) +{ + struct dri_context *ctx = dri_get_current(dPriv->driScreenPriv); + struct dri_drawable *drawable = dri_drawable(dPriv); + struct pipe_resource *ptex; + struct pipe_box box; + if (!ctx) + return; + + ptex = drawable->textures[ST_ATTACHMENT_BACK_LEFT]; + + if (ptex) { + if (ctx->pp && drawable->textures[ST_ATTACHMENT_DEPTH_STENCIL]) + pp_run(ctx->pp, ptex, ptex, drawable->textures[ST_ATTACHMENT_DEPTH_STENCIL]); + + ctx->st->flush(ctx->st, ST_FLUSH_FRONT, NULL); + + u_box_2d(x, dPriv->h - y - h, w, h, &box); + drisw_present_texture(dPriv, ptex, &box); + } +} + static void drisw_flush_frontbuffer(struct dri_context *ctx, struct dri_drawable *drawable, @@ -288,7 +335,8 @@ static const __DRIextension *drisw_screen_extensions[] = { }; static struct drisw_loader_funcs drisw_lf = { - .put_image = drisw_put_image + .put_image = drisw_put_image, + .put_image2 = drisw_put_image2 }; static const __DRIconfig ** @@ -359,12 +407,14 @@ const struct __DriverAPIRec driDriverAPI = { .SwapBuffers = drisw_swap_buffers, .MakeCurrent = dri_make_current, .UnbindContext = dri_unbind_context, + .CopySubBuffer = drisw_copy_sub_buffer, }; /* This is the table of extensions that the loader will dlsym() for. */ PUBLIC const __DRIextension *__driDriverExtensions[] = { &driCoreExtension.base, &driSWRastExtension.base, + &driCopySubBufferExtension, &gallium_config_options.base, NULL }; diff --git a/src/gallium/state_trackers/egl/common/native_helper.c b/src/gallium/state_trackers/egl/common/native_helper.c index d1e1acdab4c..4a77a502e87 100644 --- a/src/gallium/state_trackers/egl/common/native_helper.c +++ b/src/gallium/state_trackers/egl/common/native_helper.c @@ -244,7 +244,7 @@ resource_surface_present(struct resource_surface *rsurf, return TRUE; rsurf->screen->flush_frontbuffer(rsurf->screen, - pres, 0, 0, winsys_drawable_handle); + pres, 0, 0, winsys_drawable_handle, NULL); return TRUE; } diff --git a/src/gallium/state_trackers/egl/x11/native_ximage.c b/src/gallium/state_trackers/egl/x11/native_ximage.c index 28c6442d821..019e5355128 100644 --- a/src/gallium/state_trackers/egl/x11/native_ximage.c +++ b/src/gallium/state_trackers/egl/x11/native_ximage.c @@ -476,7 +476,7 @@ ximage_display_copy_to_pixmap(struct native_display *ndpy, xdraw.drawable = (Drawable) pix; xdpy->base.screen->flush_frontbuffer(xdpy->base.screen, - src, 0, 0, &xdraw); + src, 0, 0, &xdraw, NULL); return TRUE; } diff --git a/src/gallium/state_trackers/glx/xlib/xm_st.c b/src/gallium/state_trackers/glx/xlib/xm_st.c index fb6999826a9..7f73a3a44fe 100644 --- a/src/gallium/state_trackers/glx/xlib/xm_st.c +++ b/src/gallium/state_trackers/glx/xlib/xm_st.c @@ -74,7 +74,7 @@ xmesa_st_framebuffer_display(struct st_framebuffer_iface *stfbi, pres = xstfb->display_resource; } - xstfb->screen->flush_frontbuffer(xstfb->screen, pres, 0, 0, &xstfb->buffer->ws); + xstfb->screen->flush_frontbuffer(xstfb->screen, pres, 0, 0, &xstfb->buffer->ws, NULL); return TRUE; } diff --git a/src/gallium/state_trackers/vdpau/presentation.c b/src/gallium/state_trackers/vdpau/presentation.c index 81e0328a096..b574ddd2cd5 100644 --- a/src/gallium/state_trackers/vdpau/presentation.c +++ b/src/gallium/state_trackers/vdpau/presentation.c @@ -269,7 +269,7 @@ vlVdpPresentationQueueDisplay(VdpPresentationQueue presentation_queue, pipe->screen->flush_frontbuffer ( pipe->screen, tex, 0, 0, - vl_screen_get_private(pq->device->vscreen) + vl_screen_get_private(pq->device->vscreen), NULL ); pipe->screen->fence_reference(pipe->screen, &surf->fence, NULL); diff --git a/src/gallium/state_trackers/xvmc/surface.c b/src/gallium/state_trackers/xvmc/surface.c index 13f337c61cd..f6876be943b 100644 --- a/src/gallium/state_trackers/xvmc/surface.c +++ b/src/gallium/state_trackers/xvmc/surface.c @@ -447,7 +447,7 @@ Status XvMCPutSurface(Display *dpy, XvMCSurface *surface, Drawable drawable, pipe->screen->flush_frontbuffer ( pipe->screen, tex, 0, 0, - vl_screen_get_private(context_priv->vscreen) + vl_screen_get_private(context_priv->vscreen), NULL ); if(dump_window == -1) { -- cgit v1.2.3