swrast* (gallium, classic): add MESA_copy_sub_buffer support (v3)
This patches add MESA_copy_sub_buffer support to the dri sw loader and then to gallium state tracker, llvmpipe, softpipe and other bits. It reuses the dri1 driver extension interface, and it updates the swrast loader interface for a new putimage which can take a stride. I've tested this with gnome-shell with a cogl hacked to reenable sub copies for llvmpipe and the one piglit test. I could probably split this patch up as well. v2: pass a pipe_box, to reduce the entrypoints, as per Jose's review, add to p_screen doc comments. v3: finish off winsys interfaces, add swrast classic support as well. Reviewed-by: Jose Fonseca <jfonseca@vmware.com> Signed-off-by: Dave Airlie <airlied@redhat.com> swrast: add support for copy_sub_buffer
This commit is contained in:
parent
40070e72d4
commit
ba00f2f6f5
|
@ -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);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 )
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "util/u_format.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "util/u_inlines.h"
|
||||
#include "util/u_box.h"
|
||||
#include "pipe/p_context.h"
|
||||
#include "state_tracker/drisw_api.h"
|
||||
#include "state_tracker/st_context.h"
|
||||
|
@ -70,6 +71,18 @@ put_image(__DRIdrawable *dPriv, void *data, unsigned width, unsigned height)
|
|||
data, dPriv->loaderPrivate);
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
put_image2(__DRIdrawable *dPriv, void *data, int x, int y,
|
||||
unsigned width, unsigned height, unsigned stride)
|
||||
{
|
||||
__DRIscreen *sPriv = dPriv->driScreenPriv;
|
||||
const __DRIswrastLoaderExtension *loader = sPriv->swrast_loader;
|
||||
|
||||
loader->putImage2(dPriv, __DRI_SWRAST_IMAGE_OP_SWAP,
|
||||
x, y, width, height, stride,
|
||||
data, dPriv->loaderPrivate);
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
get_image(__DRIdrawable *dPriv, int x, int y, int width, int height, void *data)
|
||||
{
|
||||
|
@ -99,9 +112,19 @@ drisw_put_image(struct dri_drawable *drawable,
|
|||
put_image(dPriv, data, width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
drisw_put_image2(struct dri_drawable *drawable,
|
||||
void *data, int x, int y, unsigned width, unsigned height,
|
||||
unsigned stride)
|
||||
{
|
||||
__DRIdrawable *dPriv = drawable->dPriv;
|
||||
|
||||
put_image2(dPriv, data, x, y, width, height, stride);
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
drisw_present_texture(__DRIdrawable *dPriv,
|
||||
struct pipe_resource *ptex)
|
||||
struct pipe_resource *ptex, struct pipe_box *sub_box)
|
||||
{
|
||||
struct dri_drawable *drawable = dri_drawable(dPriv);
|
||||
struct dri_screen *screen = dri_screen(drawable->sPriv);
|
||||
|
@ -109,7 +132,7 @@ drisw_present_texture(__DRIdrawable *dPriv,
|
|||
if (swrast_no_present)
|
||||
return;
|
||||
|
||||
screen->base.screen->flush_frontbuffer(screen->base.screen, ptex, 0, 0, drawable);
|
||||
screen->base.screen->flush_frontbuffer(screen->base.screen, ptex, 0, 0, drawable, sub_box);
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
|
@ -126,7 +149,7 @@ static INLINE void
|
|||
drisw_copy_to_front(__DRIdrawable * dPriv,
|
||||
struct pipe_resource *ptex)
|
||||
{
|
||||
drisw_present_texture(dPriv, ptex);
|
||||
drisw_present_texture(dPriv, ptex, NULL);
|
||||
|
||||
drisw_invalidate_drawable(dPriv);
|
||||
}
|
||||
|
@ -157,6 +180,30 @@ drisw_swap_buffers(__DRIdrawable *dPriv)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
drisw_copy_sub_buffer(__DRIdrawable *dPriv, int x, int y,
|
||||
int w, int h)
|
||||
{
|
||||
struct dri_context *ctx = dri_get_current(dPriv->driScreenPriv);
|
||||
struct dri_drawable *drawable = dri_drawable(dPriv);
|
||||
struct pipe_resource *ptex;
|
||||
struct pipe_box box;
|
||||
if (!ctx)
|
||||
return;
|
||||
|
||||
ptex = drawable->textures[ST_ATTACHMENT_BACK_LEFT];
|
||||
|
||||
if (ptex) {
|
||||
if (ctx->pp && drawable->textures[ST_ATTACHMENT_DEPTH_STENCIL])
|
||||
pp_run(ctx->pp, ptex, ptex, drawable->textures[ST_ATTACHMENT_DEPTH_STENCIL]);
|
||||
|
||||
ctx->st->flush(ctx->st, ST_FLUSH_FRONT, NULL);
|
||||
|
||||
u_box_2d(x, dPriv->h - y - h, w, h, &box);
|
||||
drisw_present_texture(dPriv, ptex, &box);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
drisw_flush_frontbuffer(struct dri_context *ctx,
|
||||
struct dri_drawable *drawable,
|
||||
|
@ -288,7 +335,8 @@ static const __DRIextension *drisw_screen_extensions[] = {
|
|||
};
|
||||
|
||||
static struct drisw_loader_funcs drisw_lf = {
|
||||
.put_image = drisw_put_image
|
||||
.put_image = drisw_put_image,
|
||||
.put_image2 = drisw_put_image2
|
||||
};
|
||||
|
||||
static const __DRIconfig **
|
||||
|
@ -359,12 +407,14 @@ const struct __DriverAPIRec driDriverAPI = {
|
|||
.SwapBuffers = drisw_swap_buffers,
|
||||
.MakeCurrent = dri_make_current,
|
||||
.UnbindContext = dri_unbind_context,
|
||||
.CopySubBuffer = drisw_copy_sub_buffer,
|
||||
};
|
||||
|
||||
/* This is the table of extensions that the loader will dlsym() for. */
|
||||
PUBLIC const __DRIextension *__driDriverExtensions[] = {
|
||||
&driCoreExtension.base,
|
||||
&driSWRastExtension.base,
|
||||
&driCopySubBufferExtension,
|
||||
&gallium_config_options.base,
|
||||
NULL
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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:
|
||||
*/
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,13 +200,21 @@ 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);
|
||||
|
||||
ximage->data = NULL;
|
||||
}
|
||||
|
||||
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,
|
||||
|
@ -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[] = {
|
||||
|
@ -584,6 +594,21 @@ driswSwapBuffers(__GLXDRIdrawable * pdraw,
|
|||
return 0;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -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:
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue