diff options
author | Dave Airlie <airlied@gmail.com> | 2013-11-28 11:08:11 +1000 |
---|---|---|
committer | Dave Airlie <airlied@gmail.com> | 2013-12-13 14:37:01 +1000 |
commit | ba00f2f6f54cbc5ffdb0f0b94bcd672d147cdc36 (patch) | |
tree | 93cec2b58156f3fb87cbc425a7680253bb1fe82f | |
parent | 40070e72d4f27797d03986a68b1540339eb2b496 (diff) |
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 <jfonseca@vmware.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
swrast: add support for copy_sub_buffer
41 files changed, 227 insertions, 59 deletions
diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h index b012570ae1..81f7e60e55 100644 --- a/include/GL/internal/dri_interface.h +++ b/include/GL/internal/dri_interface.h @@ -437,7 +437,7 @@ struct __DRIdamageExtensionRec { * SWRast Loader extension. */ #define __DRI_SWRAST_LOADER "DRI_SWRastLoader" -#define __DRI_SWRAST_LOADER_VERSION 1 +#define __DRI_SWRAST_LOADER_VERSION 2 struct __DRIswrastLoaderExtensionRec { __DRIextension base; @@ -461,6 +461,13 @@ struct __DRIswrastLoaderExtensionRec { void (*getImage)(__DRIdrawable *readable, int x, int y, int width, int height, char *data, void *loaderPrivate); + + /** + * Put image to drawable + */ + void (*putImage2)(__DRIdrawable *drawable, int op, + int x, int y, int width, int height, int stride, + char *data, void *loaderPrivate); }; /** diff --git a/src/gallium/auxiliary/vl/vl_winsys_dri.c b/src/gallium/auxiliary/vl/vl_winsys_dri.c index 7aec3fee68..e747a66f0d 100644 --- a/src/gallium/auxiliary/vl/vl_winsys_dri.c +++ b/src/gallium/auxiliary/vl/vl_winsys_dri.c @@ -115,7 +115,7 @@ static void vl_dri2_flush_frontbuffer(struct pipe_screen *screen, struct pipe_resource *resource, unsigned level, unsigned layer, - void *context_private) + void *context_private, struct pipe_box *sub_box) { struct vl_dri_screen *scrn = (struct vl_dri_screen*)context_private; uint32_t msc_hi, msc_lo; diff --git a/src/gallium/drivers/galahad/glhd_screen.c b/src/gallium/drivers/galahad/glhd_screen.c index 16a5ff1cea..5a91077994 100644 --- a/src/gallium/drivers/galahad/glhd_screen.c +++ b/src/gallium/drivers/galahad/glhd_screen.c @@ -275,7 +275,8 @@ static void galahad_screen_flush_frontbuffer(struct pipe_screen *_screen, struct pipe_resource *_resource, unsigned level, unsigned layer, - void *context_private) + void *context_private, + struct pipe_box *sub_box) { struct galahad_screen *glhd_screen = galahad_screen(_screen); struct galahad_resource *glhd_resource = galahad_resource(_resource); @@ -285,7 +286,7 @@ galahad_screen_flush_frontbuffer(struct pipe_screen *_screen, screen->flush_frontbuffer(screen, resource, level, layer, - context_private); + context_private, sub_box); } static void diff --git a/src/gallium/drivers/i915/i915_screen.c b/src/gallium/drivers/i915/i915_screen.c index abb97966c6..8b29fc2e57 100644 --- a/src/gallium/drivers/i915/i915_screen.c +++ b/src/gallium/drivers/i915/i915_screen.c @@ -423,7 +423,8 @@ static void i915_flush_frontbuffer(struct pipe_screen *screen, struct pipe_resource *resource, unsigned level, unsigned layer, - void *winsys_drawable_handle) + void *winsys_drawable_handle, + struct pipe_box *sub_box) { /* XXX: Dummy right now. */ (void)screen; @@ -431,6 +432,7 @@ i915_flush_frontbuffer(struct pipe_screen *screen, (void)level; (void)layer; (void)winsys_drawable_handle; + (void)sub_box; } static void diff --git a/src/gallium/drivers/identity/id_screen.c b/src/gallium/drivers/identity/id_screen.c index 26df7f6f7c..28cfa1f62b 100644 --- a/src/gallium/drivers/identity/id_screen.c +++ b/src/gallium/drivers/identity/id_screen.c @@ -192,7 +192,8 @@ static void identity_screen_flush_frontbuffer(struct pipe_screen *_screen, struct pipe_resource *_resource, unsigned level, unsigned layer, - void *context_private) + void *context_private, + struct pipe_box *sub_box) { struct identity_screen *id_screen = identity_screen(_screen); struct identity_resource *id_resource = identity_resource(_resource); @@ -202,7 +203,7 @@ identity_screen_flush_frontbuffer(struct pipe_screen *_screen, screen->flush_frontbuffer(screen, resource, level, layer, - context_private); + context_private, sub_box); } static void diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c index 742e7f296c..c8eb3babde 100644 --- a/src/gallium/drivers/llvmpipe/lp_screen.c +++ b/src/gallium/drivers/llvmpipe/lp_screen.c @@ -411,7 +411,8 @@ static void llvmpipe_flush_frontbuffer(struct pipe_screen *_screen, struct pipe_resource *resource, unsigned level, unsigned layer, - void *context_private) + void *context_private, + struct pipe_box *sub_box) { struct llvmpipe_screen *screen = llvmpipe_screen(_screen); struct sw_winsys *winsys = screen->winsys; @@ -419,10 +420,9 @@ llvmpipe_flush_frontbuffer(struct pipe_screen *_screen, assert(texture->dt); if (texture->dt) - winsys->displaytarget_display(winsys, texture->dt, context_private); + winsys->displaytarget_display(winsys, texture->dt, context_private, sub_box); } - static void llvmpipe_destroy_screen( struct pipe_screen *_screen ) { diff --git a/src/gallium/drivers/noop/noop_pipe.c b/src/gallium/drivers/noop/noop_pipe.c index 889e95ee76..27197a5045 100644 --- a/src/gallium/drivers/noop/noop_pipe.c +++ b/src/gallium/drivers/noop/noop_pipe.c @@ -296,7 +296,7 @@ static struct pipe_context *noop_create_context(struct pipe_screen *screen, void static void noop_flush_frontbuffer(struct pipe_screen *_screen, struct pipe_resource *resource, unsigned level, unsigned layer, - void *context_private) + void *context_private, struct pipe_box *box) { } diff --git a/src/gallium/drivers/rbug/rbug_screen.c b/src/gallium/drivers/rbug/rbug_screen.c index 2471fdb466..8576e2f089 100644 --- a/src/gallium/drivers/rbug/rbug_screen.c +++ b/src/gallium/drivers/rbug/rbug_screen.c @@ -190,7 +190,7 @@ static void rbug_screen_flush_frontbuffer(struct pipe_screen *_screen, struct pipe_resource *_resource, unsigned level, unsigned layer, - void *context_private) + void *context_private, struct pipe_box *sub_box) { struct rbug_screen *rb_screen = rbug_screen(_screen); struct rbug_resource *rb_resource = rbug_resource(_resource); @@ -200,7 +200,7 @@ rbug_screen_flush_frontbuffer(struct pipe_screen *_screen, screen->flush_frontbuffer(screen, resource, level, layer, - context_private); + context_private, sub_box); } static void diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c index 0c8c94d0e1..69cb09fd84 100644 --- a/src/gallium/drivers/softpipe/sp_screen.c +++ b/src/gallium/drivers/softpipe/sp_screen.c @@ -369,7 +369,8 @@ static void softpipe_flush_frontbuffer(struct pipe_screen *_screen, struct pipe_resource *resource, unsigned level, unsigned layer, - void *context_private) + void *context_private, + struct pipe_box *sub_box) { struct softpipe_screen *screen = softpipe_screen(_screen); struct sw_winsys *winsys = screen->winsys; @@ -377,7 +378,7 @@ softpipe_flush_frontbuffer(struct pipe_screen *_screen, assert(texture->dt); if (texture->dt) - winsys->displaytarget_display(winsys, texture->dt, context_private); + winsys->displaytarget_display(winsys, texture->dt, context_private, sub_box); } static uint64_t diff --git a/src/gallium/drivers/trace/tr_screen.c b/src/gallium/drivers/trace/tr_screen.c index c6745af09f..debd031084 100644 --- a/src/gallium/drivers/trace/tr_screen.c +++ b/src/gallium/drivers/trace/tr_screen.c @@ -209,7 +209,8 @@ static void trace_screen_flush_frontbuffer(struct pipe_screen *_screen, struct pipe_resource *_resource, unsigned level, unsigned layer, - void *context_private) + void *context_private, + struct pipe_box *sub_box) { struct trace_screen *tr_scr = trace_screen(_screen); struct trace_resource *tr_res = trace_resource(_resource); @@ -226,7 +227,7 @@ trace_screen_flush_frontbuffer(struct pipe_screen *_screen, trace_dump_arg(ptr, context_private); */ - screen->flush_frontbuffer(screen, resource, level, layer, context_private); + screen->flush_frontbuffer(screen, resource, level, layer, context_private, sub_box); trace_dump_call_end(); } diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h index 3ed7f269e4..bdd727d8cb 100644 --- a/src/gallium/include/pipe/p_screen.h +++ b/src/gallium/include/pipe/p_screen.h @@ -56,6 +56,7 @@ struct pipe_fence_handle; struct pipe_resource; struct pipe_surface; struct pipe_transfer; +struct pipe_box; /** @@ -181,13 +182,13 @@ struct pipe_screen { * displayed, eg copy fake frontbuffer. * \param winsys_drawable_handle an opaque handle that the calling context * gets out-of-band + * \param subbox an optional sub region to flush */ void (*flush_frontbuffer)( struct pipe_screen *screen, struct pipe_resource *resource, unsigned level, unsigned layer, - void *winsys_drawable_handle ); - - + void *winsys_drawable_handle, + struct pipe_box *subbox ); /** Set ptr = fence, with reference counting */ void (*fence_reference)( struct pipe_screen *screen, diff --git a/src/gallium/include/state_tracker/drisw_api.h b/src/gallium/include/state_tracker/drisw_api.h index 944a649257..328440cf5f 100644 --- a/src/gallium/include/state_tracker/drisw_api.h +++ b/src/gallium/include/state_tracker/drisw_api.h @@ -13,6 +13,8 @@ struct drisw_loader_funcs { void (*put_image) (struct dri_drawable *dri_drawable, void *data, unsigned width, unsigned height); + void (*put_image2) (struct dri_drawable *dri_drawable, + void *data, int x, int y, unsigned width, unsigned height, unsigned stride); }; /** diff --git a/src/gallium/include/state_tracker/sw_winsys.h b/src/gallium/include/state_tracker/sw_winsys.h index 0b11fe3beb..d08ddd6c39 100644 --- a/src/gallium/include/state_tracker/sw_winsys.h +++ b/src/gallium/include/state_tracker/sw_winsys.h @@ -48,7 +48,7 @@ struct winsys_handle; struct pipe_screen; struct pipe_context; struct pipe_resource; - +struct pipe_box; /** * Opaque pointer. @@ -129,7 +129,8 @@ struct sw_winsys void (*displaytarget_display)( struct sw_winsys *ws, struct sw_displaytarget *dt, - void *context_private ); + void *context_private, + struct pipe_box *box ); void (*displaytarget_destroy)( struct sw_winsys *ws, diff --git a/src/gallium/state_trackers/dri/sw/drisw.c b/src/gallium/state_trackers/dri/sw/drisw.c index 9f00a53152..64a64af14e 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" @@ -71,6 +72,18 @@ put_image(__DRIdrawable *dPriv, void *data, unsigned width, unsigned height) } 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) { __DRIscreen *sPriv = dPriv->driScreenPriv; @@ -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); } @@ -158,6 +181,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, enum st_attachment_type statt) @@ -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 d1e1acdab4..4a77a502e8 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 28c6442d82..019e535512 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 fb6999826a..7f73a3a44f 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 81e0328a09..b574ddd2cd 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 13f337c61c..f6876be943 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) { diff --git a/src/gallium/targets/haiku-softpipe/GalliumContext.cpp b/src/gallium/targets/haiku-softpipe/GalliumContext.cpp index b750f6578f..1078cb7b38 100644 --- a/src/gallium/targets/haiku-softpipe/GalliumContext.cpp +++ b/src/gallium/targets/haiku-softpipe/GalliumContext.cpp @@ -504,14 +504,14 @@ GalliumContext::SwapBuffers(context_id contextID) // We pass our destination bitmap to flush_fronbuffer which passes it // to the private winsys display call. fScreen->flush_frontbuffer(fScreen, surface->texture, 0, 0, - context->bitmap); + context->bitmap, NULL); } #if 0 // TODO... should we flush the z stencil buffer? pipe_surface* zSurface = stContext->state.framebuffer.zsbuf; fScreen->flush_frontbuffer(fScreen, zSurface->texture, 0, 0, - context->bitmap); + context->bitmap, NULL); #endif return B_OK; diff --git a/src/gallium/tests/graw/clear.c b/src/gallium/tests/graw/clear.c index 77c59db8a3..f38da47407 100644 --- a/src/gallium/tests/graw/clear.c +++ b/src/gallium/tests/graw/clear.c @@ -33,7 +33,7 @@ static void draw( void ) graw_save_surface_to_file(ctx, surf, NULL); - screen->flush_frontbuffer(screen, tex, 0, 0, window); + screen->flush_frontbuffer(screen, tex, 0, 0, window, NULL); } static void init( void ) diff --git a/src/gallium/tests/graw/fs-test.c b/src/gallium/tests/graw/fs-test.c index 4d38e084b8..0560e31723 100644 --- a/src/gallium/tests/graw/fs-test.c +++ b/src/gallium/tests/graw/fs-test.c @@ -240,7 +240,7 @@ static void draw( void ) graw_save_surface_to_file(ctx, surf, NULL); - screen->flush_frontbuffer(screen, rttex, 0, 0, window); + screen->flush_frontbuffer(screen, rttex, 0, 0, window, NULL); } #define SIZE 16 diff --git a/src/gallium/tests/graw/graw_util.h b/src/gallium/tests/graw/graw_util.h index 8557285e0e..1856f0d7df 100644 --- a/src/gallium/tests/graw/graw_util.h +++ b/src/gallium/tests/graw/graw_util.h @@ -211,7 +211,7 @@ static INLINE void graw_util_flush_front(const struct graw_info *info) { info->screen->flush_frontbuffer(info->screen, info->color_buf[0], - 0, 0, info->window); + 0, 0, info->window, NULL); } diff --git a/src/gallium/tests/graw/gs-test.c b/src/gallium/tests/graw/gs-test.c index 3ada18a30e..879bf3e832 100644 --- a/src/gallium/tests/graw/gs-test.c +++ b/src/gallium/tests/graw/gs-test.c @@ -347,7 +347,7 @@ static void draw( void ) graw_save_surface_to_file(ctx, surf, NULL); - screen->flush_frontbuffer(screen, rttex, 0, 0, window); + screen->flush_frontbuffer(screen, rttex, 0, 0, window, NULL); } #define SIZE 16 diff --git a/src/gallium/tests/graw/quad-sample.c b/src/gallium/tests/graw/quad-sample.c index b4a29e101e..2e248a8a6f 100644 --- a/src/gallium/tests/graw/quad-sample.c +++ b/src/gallium/tests/graw/quad-sample.c @@ -156,7 +156,7 @@ static void draw( void ) graw_save_surface_to_file(ctx, surf, NULL); - screen->flush_frontbuffer(screen, rttex, 0, 0, window); + screen->flush_frontbuffer(screen, rttex, 0, 0, window, NULL); } #define SIZE 16 diff --git a/src/gallium/tests/graw/shader-leak.c b/src/gallium/tests/graw/shader-leak.c index 4ef752b412..754ada6cf1 100644 --- a/src/gallium/tests/graw/shader-leak.c +++ b/src/gallium/tests/graw/shader-leak.c @@ -158,7 +158,7 @@ static void draw( void ) ctx->delete_fs_state(ctx, fs); } - screen->flush_frontbuffer(screen, tex, 0, 0, window); + screen->flush_frontbuffer(screen, tex, 0, 0, window, NULL); ctx->destroy(ctx); exit(0); diff --git a/src/gallium/tests/graw/tri-gs.c b/src/gallium/tests/graw/tri-gs.c index 37323aa086..24de12b723 100644 --- a/src/gallium/tests/graw/tri-gs.c +++ b/src/gallium/tests/graw/tri-gs.c @@ -168,7 +168,7 @@ static void draw( void ) util_draw_arrays(ctx, PIPE_PRIM_TRIANGLES, 0, 3); ctx->flush(ctx, NULL, 0); - screen->flush_frontbuffer(screen, tex, 0, 0, window); + screen->flush_frontbuffer(screen, tex, 0, 0, window, NULL); } diff --git a/src/gallium/tests/graw/tri-instanced.c b/src/gallium/tests/graw/tri-instanced.c index f84463d8ce..55bc3a551d 100644 --- a/src/gallium/tests/graw/tri-instanced.c +++ b/src/gallium/tests/graw/tri-instanced.c @@ -219,7 +219,7 @@ static void draw( void ) graw_save_surface_to_file(ctx, surf, NULL); - screen->flush_frontbuffer(screen, tex, 0, 0, window); + screen->flush_frontbuffer(screen, tex, 0, 0, window, NULL); } diff --git a/src/gallium/tests/graw/vs-test.c b/src/gallium/tests/graw/vs-test.c index f7d4d7342e..0e9fc53e1b 100644 --- a/src/gallium/tests/graw/vs-test.c +++ b/src/gallium/tests/graw/vs-test.c @@ -234,7 +234,7 @@ static void draw( void ) graw_save_surface_to_file(ctx, surf, NULL); - screen->flush_frontbuffer(screen, rttex, 0, 0, window); + screen->flush_frontbuffer(screen, rttex, 0, 0, window, NULL); } #define SIZE 16 diff --git a/src/gallium/winsys/sw/android/android_sw_winsys.cpp b/src/gallium/winsys/sw/android/android_sw_winsys.cpp index cb91aade0a..4b1040cb6e 100644 --- a/src/gallium/winsys/sw/android/android_sw_winsys.cpp +++ b/src/gallium/winsys/sw/android/android_sw_winsys.cpp @@ -74,7 +74,8 @@ namespace android { static void android_displaytarget_display(struct sw_winsys *ws, struct sw_displaytarget *dt, - void *context_private) + void *context_private, + struct pipe_box *box) { } diff --git a/src/gallium/winsys/sw/dri/dri_sw_winsys.c b/src/gallium/winsys/sw/dri/dri_sw_winsys.c index edb3a381a7..6fed22bbd7 100644 --- a/src/gallium/winsys/sw/dri/dri_sw_winsys.c +++ b/src/gallium/winsys/sw/dri/dri_sw_winsys.c @@ -166,25 +166,33 @@ dri_sw_displaytarget_get_handle(struct sw_winsys *winsys, static void dri_sw_displaytarget_display(struct sw_winsys *ws, struct sw_displaytarget *dt, - void *context_private) + void *context_private, + struct pipe_box *box) { struct dri_sw_winsys *dri_sw_ws = dri_sw_winsys(ws); struct dri_sw_displaytarget *dri_sw_dt = dri_sw_displaytarget(dt); struct dri_drawable *dri_drawable = (struct dri_drawable *)context_private; unsigned width, height; + unsigned blsize = util_format_get_blocksize(dri_sw_dt->format); /* Set the width to 'stride / cpp'. * * PutImage correctly clips to the width of the dst drawable. */ - width = dri_sw_dt->stride / util_format_get_blocksize(dri_sw_dt->format); + width = dri_sw_dt->stride / blsize; height = dri_sw_dt->height; - dri_sw_ws->lf->put_image(dri_drawable, dri_sw_dt->data, width, height); + if (box) { + void *data; + data = dri_sw_dt->data + (dri_sw_dt->stride * box->y) + box->x * blsize; + dri_sw_ws->lf->put_image2(dri_drawable, data, + box->x, box->y, box->width, box->height, dri_sw_dt->stride); + } else { + dri_sw_ws->lf->put_image(dri_drawable, dri_sw_dt->data, width, height); + } } - static void dri_destroy_sw_winsys(struct sw_winsys *winsys) { diff --git a/src/gallium/winsys/sw/fbdev/fbdev_sw_winsys.c b/src/gallium/winsys/sw/fbdev/fbdev_sw_winsys.c index a280985471..cc3ce1a78d 100644 --- a/src/gallium/winsys/sw/fbdev/fbdev_sw_winsys.c +++ b/src/gallium/winsys/sw/fbdev/fbdev_sw_winsys.c @@ -74,7 +74,8 @@ fbdev_sw_winsys(struct sw_winsys *ws) static void fbdev_displaytarget_display(struct sw_winsys *ws, struct sw_displaytarget *dt, - void *winsys_private) + void *winsys_private, + struct pipe_box *box) { struct fbdev_sw_winsys *fbdev = fbdev_sw_winsys(ws); struct fbdev_sw_displaytarget *src = fbdev_sw_displaytarget(dt); diff --git a/src/gallium/winsys/sw/gdi/gdi_sw_winsys.c b/src/gallium/winsys/sw/gdi/gdi_sw_winsys.c index 2e12f6e6cc..aae3ec55a2 100644 --- a/src/gallium/winsys/sw/gdi/gdi_sw_winsys.c +++ b/src/gallium/winsys/sw/gdi/gdi_sw_winsys.c @@ -207,7 +207,8 @@ gdi_sw_display( struct sw_winsys *winsys, static void gdi_sw_displaytarget_display(struct sw_winsys *winsys, struct sw_displaytarget *dt, - void *context_private) + void *context_private, + struct pipe_box *box) { /* nasty: */ diff --git a/src/gallium/winsys/sw/hgl/hgl_sw_winsys.c b/src/gallium/winsys/sw/hgl/hgl_sw_winsys.c index b09584c39a..27eca2ba28 100644 --- a/src/gallium/winsys/sw/hgl/hgl_sw_winsys.c +++ b/src/gallium/winsys/sw/hgl/hgl_sw_winsys.c @@ -160,7 +160,8 @@ hgl_winsys_displaytarget_unmap(struct sw_winsys* winsys, static void hgl_winsys_displaytarget_display(struct sw_winsys* winsys, - struct sw_displaytarget* displayTarget, void* contextPrivate) + struct sw_displaytarget* displayTarget, void* contextPrivate, + struct pipe_box *box) { assert(contextPrivate); diff --git a/src/gallium/winsys/sw/null/null_sw_winsys.c b/src/gallium/winsys/sw/null/null_sw_winsys.c index 44849da140..9c8b3ec439 100644 --- a/src/gallium/winsys/sw/null/null_sw_winsys.c +++ b/src/gallium/winsys/sw/null/null_sw_winsys.c @@ -114,7 +114,8 @@ null_sw_displaytarget_get_handle(struct sw_winsys *winsys, static void null_sw_displaytarget_display(struct sw_winsys *winsys, struct sw_displaytarget *dt, - void *context_private) + void *context_private, + struct pipe_box *box) { assert(0); } diff --git a/src/gallium/winsys/sw/wayland/wayland_sw_winsys.c b/src/gallium/winsys/sw/wayland/wayland_sw_winsys.c index f432de98fe..e4286136fe 100644 --- a/src/gallium/winsys/sw/wayland/wayland_sw_winsys.c +++ b/src/gallium/winsys/sw/wayland/wayland_sw_winsys.c @@ -75,7 +75,8 @@ wayland_sw_winsys(struct sw_winsys *ws) static void wayland_displaytarget_display(struct sw_winsys *ws, struct sw_displaytarget *dt, - void *context_private) + void *context_private, + struct pipe_box *box) { } diff --git a/src/gallium/winsys/sw/xlib/xlib_sw_winsys.c b/src/gallium/winsys/sw/xlib/xlib_sw_winsys.c index 6e71530e63..99da2ae991 100644 --- a/src/gallium/winsys/sw/xlib/xlib_sw_winsys.c +++ b/src/gallium/winsys/sw/xlib/xlib_sw_winsys.c @@ -376,7 +376,8 @@ xlib_sw_display(struct xlib_drawable *xlib_drawable, static void xlib_displaytarget_display(struct sw_winsys *ws, struct sw_displaytarget *dt, - void *context_private) + void *context_private, + struct pipe_box *box) { struct xlib_drawable *xlib_drawable = (struct xlib_drawable *)context_private; xlib_sw_display(xlib_drawable, dt); diff --git a/src/glx/drisw_glx.c b/src/glx/drisw_glx.c index cb1d650b5c..13a4b96a1f 100644 --- a/src/glx/drisw_glx.c +++ b/src/glx/drisw_glx.c @@ -49,6 +49,7 @@ struct drisw_screen const __DRIcoreExtension *core; const __DRIswrastExtension *swrast; const __DRItexBufferExtension *texBuffer; + const __DRIcopySubBufferExtension *copySubBuffer; const __DRIconfig **driver_configs; @@ -171,9 +172,9 @@ bytes_per_line(unsigned pitch_bits, unsigned mul) } static void -swrastPutImage(__DRIdrawable * draw, int op, - int x, int y, int w, int h, - char *data, void *loaderPrivate) +swrastPutImage2(__DRIdrawable * draw, int op, + int x, int y, int w, int h, int stride, + char *data, void *loaderPrivate) { struct drisw_drawable *pdp = loaderPrivate; __GLXDRIdrawable *pdraw = &(pdp->base); @@ -199,7 +200,7 @@ swrastPutImage(__DRIdrawable * draw, int op, ximage->data = data; ximage->width = w; ximage->height = h; - ximage->bytes_per_line = bytes_per_line(w * ximage->bits_per_pixel, 32); + ximage->bytes_per_line = stride ? stride : bytes_per_line(w * ximage->bits_per_pixel, 32); XPutImage(dpy, drawable, gc, ximage, 0, 0, x, y, w, h); @@ -207,6 +208,14 @@ swrastPutImage(__DRIdrawable * draw, int op, } static void +swrastPutImage(__DRIdrawable * draw, int op, + int x, int y, int w, int h, + char *data, void *loaderPrivate) +{ + swrastPutImage2(draw, op, x, y, w, h, 0, data, loaderPrivate); +} + +static void swrastGetImage(__DRIdrawable * read, int x, int y, int w, int h, char *data, void *loaderPrivate) @@ -234,7 +243,8 @@ static const __DRIswrastLoaderExtension swrastLoaderExtension = { {__DRI_SWRAST_LOADER, __DRI_SWRAST_LOADER_VERSION}, swrastGetDrawableInfo, swrastPutImage, - swrastGetImage + swrastGetImage, + swrastPutImage2, }; static const __DRIextension *loader_extensions[] = { @@ -585,6 +595,21 @@ driswSwapBuffers(__GLXDRIdrawable * pdraw, } static void +driswCopySubBuffer(__GLXDRIdrawable * pdraw, + int x, int y, int width, int height, Bool flush) +{ + struct drisw_drawable *pdp = (struct drisw_drawable *) pdraw; + struct drisw_screen *psc = (struct drisw_screen *) pdp->base.psc; + + if (flush) { + glFlush(); + } + + (*psc->copySubBuffer->copySubBuffer) (pdp->driDrawable, + x, y, width, height); +} + +static void driswDestroyScreen(struct glx_screen *base) { struct drisw_screen *psc = (struct drisw_screen *) base; @@ -632,6 +657,9 @@ driswBindExtensions(struct drisw_screen *psc, const __DRIextension **extensions) "GLX_EXT_create_context_es2_profile"); } + if (psc->copySubBuffer) + __glXEnableDirectExtension(&psc->base, "GLX_MESA_copy_sub_buffer"); + /* FIXME: Figure out what other extensions can be ported here from dri2. */ for (i = 0; extensions[i]; i++) { if ((strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0)) { @@ -673,6 +701,8 @@ driswCreateScreen(int screen, struct glx_display *priv) psc->core = (__DRIcoreExtension *) extensions[i]; if (strcmp(extensions[i]->name, __DRI_SWRAST) == 0) psc->swrast = (__DRIswrastExtension *) extensions[i]; + if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0) + psc->copySubBuffer = (__DRIcopySubBufferExtension *) extensions[i]; } if (psc->core == NULL || psc->swrast == NULL) { @@ -718,6 +748,9 @@ driswCreateScreen(int screen, struct glx_display *priv) psp->createDrawable = driswCreateDrawable; psp->swapBuffers = driswSwapBuffers; + if (psc->copySubBuffer) + psp->copySubBuffer = driswCopySubBuffer; + return &psc->base; handle_error: diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c index 0bce77ea9c..fd2eca715c 100644 --- a/src/mesa/drivers/dri/common/dri_util.c +++ b/src/mesa/drivers/dri/common/dri_util.c @@ -873,3 +873,18 @@ const __DRIimageDriverExtension driImageDriverExtension = { .getAPIMask = driGetAPIMask, .createContextAttribs = driCreateContextAttribs, }; + +/* swrast copy sub buffer entrypoint. */ +static void driCopySubBuffer(__DRIdrawable *pdp, int x, int y, + int w, int h) +{ + assert(pdp->driScreenPriv->swrast_loader); + + pdp->driScreenPriv->driver->CopySubBuffer(pdp, x, y, w, h); +} + +/* for swrast only */ +const __DRIcopySubBufferExtension driCopySubBufferExtension = { + { __DRI_COPY_SUB_BUFFER, 1 }, + .copySubBuffer = driCopySubBuffer, +}; diff --git a/src/mesa/drivers/dri/common/dri_util.h b/src/mesa/drivers/dri/common/dri_util.h index 79a8564ad5..4cfa75dd3e 100644 --- a/src/mesa/drivers/dri/common/dri_util.h +++ b/src/mesa/drivers/dri/common/dri_util.h @@ -66,7 +66,7 @@ extern const __DRIcoreExtension driCoreExtension; extern const __DRIswrastExtension driSWRastExtension; extern const __DRIdri2Extension driDRI2Extension; extern const __DRI2configQueryExtension dri2ConfigQueryExtension; - +extern const __DRIcopySubBufferExtension driCopySubBufferExtension; /** * Driver callback functions. * @@ -115,6 +115,9 @@ struct __DriverAPIRec { int width, int height); void (*ReleaseBuffer) (__DRIscreen *screenPrivate, __DRIbuffer *buffer); + + void (*CopySubBuffer)(__DRIdrawable *driDrawPriv, int x, int y, + int w, int h); }; extern const struct __DriverAPIRec driDriverAPI; diff --git a/src/mesa/drivers/dri/swrast/swrast.c b/src/mesa/drivers/dri/swrast/swrast.c index 0e1c530b39..7eed5a418c 100644 --- a/src/mesa/drivers/dri/swrast/swrast.c +++ b/src/mesa/drivers/dri/swrast/swrast.c @@ -820,6 +820,39 @@ dri_unbind_context(__DRIcontext * cPriv) return GL_TRUE; } +static void +dri_copy_sub_buffer(__DRIdrawable *dPriv, int x, int y, + int w, int h) +{ + __DRIscreen *sPriv = dPriv->driScreenPriv; + void *data; + int iy; + struct dri_drawable *drawable = dri_drawable(dPriv); + struct gl_framebuffer *fb; + struct dri_swrast_renderbuffer *frontrb, *backrb; + + TRACE; + + fb = &drawable->Base; + + frontrb = + dri_swrast_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer); + backrb = + dri_swrast_renderbuffer(fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer); + + /* check for signle-buffered */ + if (backrb == NULL) + return; + + iy = frontrb->Base.Base.Height - y - h; + data = (char *)backrb->Base.Buffer + (iy * backrb->pitch) + (x * ((backrb->bpp + 7) / 8)); + sPriv->swrast_loader->putImage2(dPriv, __DRI_SWRAST_IMAGE_OP_SWAP, + x, iy, w, h, + frontrb->pitch, + data, + dPriv->loaderPrivate); +} + static const struct __DriverAPIRec swrast_driver_api = { .InitScreen = dri_init_screen, @@ -831,6 +864,7 @@ static const struct __DriverAPIRec swrast_driver_api = { .SwapBuffers = dri_swap_buffers, .MakeCurrent = dri_make_current, .UnbindContext = dri_unbind_context, + .CopySubBuffer = dri_copy_sub_buffer, }; static const struct __DRIDriverVtableExtensionRec swrast_vtable = { @@ -841,6 +875,7 @@ static const struct __DRIDriverVtableExtensionRec swrast_vtable = { static const __DRIextension *swrast_driver_extensions[] = { &driCoreExtension.base, &driSWRastExtension.base, + &driCopySubBufferExtension.base, &swrast_vtable.base, NULL }; |