mesa/0001-swrast-gallium-classic-add-MESA_copy_sub_buffer-supp.patch

1021 lines
39 KiB
Diff

From 31d3205208bced090f790e530d861c75615d14d0 Mon Sep 17 00:00:00 2001
From: Dave Airlie <airlied@gmail.com>
Date: Thu, 28 Nov 2013 11:08:11 +1000
Subject: [PATCH] swrast* (gallium, classic): add MESA_copy_sub_buffer support
(v3-backport)
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.
backport to 9.2: old dri bits.
Reviewed-by: Jose Fonseca <jfonseca@vmware.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Conflicts:
src/gallium/state_trackers/dri/sw/drisw.c
src/gallium/targets/haiku-softpipe/GalliumContext.cpp
src/mesa/drivers/dri/common/dri_util.c
src/mesa/drivers/dri/swrast/swrast.c
---
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 +-
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 +-
.../winsys/sw/android/android_sw_winsys.cpp | 3 +-
src/gallium/winsys/sw/dri/dri_sw_winsys.c | 16 ++++--
src/gallium/winsys/sw/fbdev/fbdev_sw_winsys.c | 3 +-
src/gallium/winsys/sw/gdi/gdi_sw_winsys.c | 3 +-
src/gallium/winsys/sw/hgl/hgl_sw_winsys.c | 3 +-
src/gallium/winsys/sw/null/null_sw_winsys.c | 3 +-
src/gallium/winsys/sw/wayland/wayland_sw_winsys.c | 3 +-
src/gallium/winsys/sw/xlib/xlib_sw_winsys.c | 3 +-
src/glx/drisw_glx.c | 43 ++++++++++++++--
src/mesa/drivers/dri/common/dri_util.h | 5 +-
src/mesa/drivers/dri/common/drisw_util.c | 15 ++++++
src/mesa/drivers/dri/swrast/swrast.c | 35 +++++++++++++
40 files changed, 225 insertions(+), 57 deletions(-)
diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
index 5c99d55..09c1406 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -439,7 +439,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;
@@ -463,6 +463,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 556dda8..0ff2640 100644
--- a/src/gallium/drivers/i915/i915_screen.c
+++ b/src/gallium/drivers/i915/i915_screen.c
@@ -419,7 +419,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;
@@ -427,6 +428,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 b3cd77f..f488d6d 100644
--- a/src/gallium/drivers/llvmpipe/lp_screen.c
+++ b/src/gallium/drivers/llvmpipe/lp_screen.c
@@ -403,7 +403,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;
@@ -411,10 +412,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 ac837b1..849a4d1 100644
--- a/src/gallium/drivers/noop/noop_pipe.c
+++ b/src/gallium/drivers/noop/noop_pipe.c
@@ -288,7 +288,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 f6acdc8..3e3f366 100644
--- a/src/gallium/drivers/softpipe/sp_screen.c
+++ b/src/gallium/drivers/softpipe/sp_screen.c
@@ -364,7 +364,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;
@@ -372,7 +373,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 c487e8e..c0f4fd1 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;
/**
@@ -179,13 +180,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 121a205..aa0d3e0 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.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 c9f8ea7..e68e25f 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 6a895aa..ea778a3 100644
--- a/src/gallium/state_trackers/xvmc/surface.c
+++ b/src/gallium/state_trackers/xvmc/surface.c
@@ -441,7 +441,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/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 38a2c4b..a01c014 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 e4e4f61..1745c84 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 969ffa7..9960c30 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 5a7d0a0..ce1941d 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 cb91aad..4b1040c 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 edb3a38..6fed22b 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 a280985..cc3ce1a 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 2e12f6e..aae3ec5 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 1d51dd6..f09272a 100644
--- a/src/gallium/winsys/sw/hgl/hgl_sw_winsys.c
+++ b/src/gallium/winsys/sw/hgl/hgl_sw_winsys.c
@@ -147,7 +147,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 44849da..9c8b3ec 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 f432de9..e428613 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 6e71530..99da2ae 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 393be20..f903b2d 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)) {
@@ -675,6 +703,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) {
@@ -713,6 +743,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.h b/src/mesa/drivers/dri/common/dri_util.h
index 900f048..4c71fe4 100644
--- a/src/mesa/drivers/dri/common/dri_util.h
+++ b/src/mesa/drivers/dri/common/dri_util.h
@@ -65,7 +65,7 @@ extern const __DRIcoreExtension driCoreExtension;
extern const __DRIswrastExtension driSWRastExtension;
extern const __DRIdri2Extension driDRI2Extension;
extern const __DRI2configQueryExtension dri2ConfigQueryExtension;
-
+extern const __DRIcopySubBufferExtension driCopySubBufferExtension;
/**
* Driver callback functions.
*
@@ -113,6 +113,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/common/drisw_util.c b/src/mesa/drivers/dri/common/drisw_util.c
index 89f03c3..0da4142 100644
--- a/src/mesa/drivers/dri/common/drisw_util.c
+++ b/src/mesa/drivers/dri/common/drisw_util.c
@@ -373,3 +373,18 @@ const __DRIswrastExtension driSWRastExtension = {
driCreateNewContextForAPI,
driCreateContextAttribs
};
+
+/* swrast copy sub buffer entrypoint. */
+static void driCopySubBuffer(__DRIdrawable *pdp, int x, int y,
+ int w, int h)
+{
+ assert(pdp->driScreenPriv->swrast_loader);
+
+ driDriverAPI.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/swrast/swrast.c b/src/mesa/drivers/dri/swrast/swrast.c
index 3870673..eb6d23b 100644
--- a/src/mesa/drivers/dri/swrast/swrast.c
+++ b/src/mesa/drivers/dri/swrast/swrast.c
@@ -830,6 +830,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);
+}
+
const struct __DriverAPIRec driDriverAPI = {
.InitScreen = dri_init_screen,
@@ -841,11 +874,13 @@ const struct __DriverAPIRec driDriverAPI = {
.SwapBuffers = dri_swap_buffers,
.MakeCurrent = dri_make_current,
.UnbindContext = dri_unbind_context,
+ .CopySubBuffer = dri_copy_sub_buffer,
};
/* This is the table of extensions that the loader will dlsym() for. */
PUBLIC const __DRIextension *__driDriverExtensions[] = {
&driCoreExtension.base,
&driSWRastExtension.base,
+ &driCopySubBufferExtension.base,
NULL
};
--
1.8.3.1