diff options
41 files changed, 227 insertions, 59 deletions
diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h index b012570ae13..81f7e60e55f 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 7aec3fee685..e747a66f0d6 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 16a5ff1ceae..5a910779948 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 abb97966c66..8b29fc2e57d 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 26df7f6f7ce..28cfa1f62b1 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 742e7f296ce..c8eb3babde5 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 889e95ee76f..27197a50454 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 2471fdb4661..8576e2f0897 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 0c8c94d0e19..69cb09fd84d 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 c6745af09f2..debd031084f 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 3ed7f269e4f..bdd727d8cb4 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 944a649257e..328440cf5ff 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 0b11fe3beb9..d08ddd6c397 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 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" @@ -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 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) { diff --git a/src/gallium/targets/haiku-softpipe/GalliumContext.cpp b/src/gallium/targets/haiku-softpipe/GalliumContext.cpp index b750f6578f4..1078cb7b380 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 77c59db8a3f..f38da47407f 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 4d38e084b80..0560e31723e 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 8557285e0ea..1856f0d7df4 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 3ada18a30ee..879bf3e8324 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 b4a29e101e4..2e248a8a6f4 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 4ef752b412f..754ada6cf10 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 37323aa0864..24de12b723c 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 f84463d8ce7..55bc3a551da 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 f7d4d7342ec..0e9fc53e1b8 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 cb91aade0a8..4b1040cb6ee 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 edb3a381a74..6fed22bbd7c 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 a2809854710..cc3ce1a78d2 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 2e12f6e6cc8..aae3ec55a25 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 b09584c39a4..27eca2ba280 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 44849da1403..9c8b3ec4396 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 f432de98fef..e4286136fe4 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 6e71530e635..99da2ae991c 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 cb1d650b5c1..13a4b96a1fb 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 0bce77ea9c7..fd2eca715c3 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 79a8564ad51..4cfa75dd3e4 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 0e1c530b39d..7eed5a418cb 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 }; |