Sorry for the delay. Thanks for the update. Please update the other sw_winsys implementations in src/gallium/winsys/sw too. I think that updating the prototype and ignoring the new parameter should be fine.
Otherwise looks good. Jose ----- Original Message ----- > 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. > > Signed-off-by: Dave Airlie <[email protected]> > --- > include/GL/internal/dri_interface.h | 9 +++- > src/gallium/auxiliary/vl/vl_winsys_dri.c | 2 +- > src/gallium/drivers/galahad/glhd_screen.c | 5 +- > src/gallium/drivers/i915/i915_screen.c | 4 +- > src/gallium/drivers/identity/id_screen.c | 5 +- > src/gallium/drivers/llvmpipe/lp_screen.c | 6 +-- > src/gallium/drivers/noop/noop_pipe.c | 2 +- > src/gallium/drivers/rbug/rbug_screen.c | 4 +- > src/gallium/drivers/softpipe/sp_screen.c | 5 +- > src/gallium/drivers/trace/tr_screen.c | 5 +- > src/gallium/include/pipe/p_screen.h | 7 +-- > src/gallium/include/state_tracker/drisw_api.h | 2 + > src/gallium/include/state_tracker/sw_winsys.h | 5 +- > 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 +- > .../targets/haiku-softpipe/GalliumContext.cpp | 4 +- > src/gallium/tests/graw/clear.c | 2 +- > src/gallium/tests/graw/fs-test.c | 2 +- > src/gallium/tests/graw/graw_util.h | 2 +- > src/gallium/tests/graw/gs-test.c | 2 +- > src/gallium/tests/graw/quad-sample.c | 2 +- > src/gallium/tests/graw/shader-leak.c | 2 +- > src/gallium/tests/graw/tri-gs.c | 2 +- > src/gallium/tests/graw/tri-instanced.c | 2 +- > src/gallium/tests/graw/vs-test.c | 2 +- > src/gallium/winsys/sw/dri/dri_sw_winsys.c | 17 +++++-- > src/glx/drisw_glx.c | 43 ++++++++++++++-- > src/mesa/drivers/dri/common/dri_util.c | 15 ++++++ > src/mesa/drivers/dri/common/dri_util.h | 5 +- > 33 files changed, 178 insertions(+), 53 deletions(-) > > diff --git a/include/GL/internal/dri_interface.h > b/include/GL/internal/dri_interface.h > index b012570..81f7e60 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 7aec3fe..e747a66 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 16a5ff1..5a91077 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 77607d0..7e35d84 100644 > --- a/src/gallium/drivers/i915/i915_screen.c > +++ b/src/gallium/drivers/i915/i915_screen.c > @@ -420,7 +420,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; > @@ -428,6 +429,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 26df7f6..28cfa1f6 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 f61df98..3501387 100644 > --- a/src/gallium/drivers/llvmpipe/lp_screen.c > +++ b/src/gallium/drivers/llvmpipe/lp_screen.c > @@ -404,7 +404,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; > @@ -412,10 +413,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 889e95e..27197a5 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 2471fdb..8576e2f 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 47ef20e..358b552 100644 > --- a/src/gallium/drivers/softpipe/sp_screen.c > +++ b/src/gallium/drivers/softpipe/sp_screen.c > @@ -366,7 +366,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; > @@ -374,7 +375,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 5281ba8..b71ebbe 100644 > --- a/src/gallium/drivers/trace/tr_screen.c > +++ b/src/gallium/drivers/trace/tr_screen.c > @@ -210,7 +210,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); > @@ -227,7 +228,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 3ed7f26..bdd727d 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 944a649..328440c 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 0b11fe3..d08ddd6 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 9f00a53..64a64af 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 b578a8a..5c2be19 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 28c6442..019e535 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 fb69998..7f73a3a 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 81e0328..b574ddd 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 13f337c..f6876be 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 b750f65..1078cb7 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 77c59db..f38da47 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 4d38e08..0560e31 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 8557285..1856f0d 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 3ada18a..879bf3e 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 b4a29e1..2e248a8 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 4ef752b..754ada6 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 37323aa..24de12b 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 f84463d..55bc3a5 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 f7d4d73..0e9fc53 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/dri/dri_sw_winsys.c > b/src/gallium/winsys/sw/dri/dri_sw_winsys.c > index edb3a38..cc3b4a1 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) > { > @@ -216,7 +224,6 @@ dri_create_sw_winsys(struct drisw_loader_funcs *lf) > ws->base.displaytarget_unmap = dri_sw_displaytarget_unmap; > > ws->base.displaytarget_display = dri_sw_displaytarget_display; > - > return &ws->base; > } > > diff --git a/src/glx/drisw_glx.c b/src/glx/drisw_glx.c > index cb1d650..13a4b96 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 0bce77e..fd2eca7 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 79a8564..4cfa75d 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; > -- > 1.8.3.1 > > _______________________________________________ > mesa-dev mailing list > [email protected] > https://urldefense.proofpoint.com/v1/url?u=http://lists.freedesktop.org/mailman/listinfo/mesa-dev&k=oIvRg1%2BdGAgOoM1BIlLLqw%3D%3D%0A&r=NMr9uy2iTjWVixC0wOcYCWEIYhfo80qKwRgdodpoDzA%3D%0A&m=PHP1BdGxAuEdcENkoQ%2B%2BXlDEXMYDu5rLFjO6X6QcDT0%3D%0A&s=4de8284e02612630341b3ad329b14aa430b5e4affaf15273cd5d77b4aae6d8ae > _______________________________________________ mesa-dev mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/mesa-dev
