* 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;
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);
};
/**
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;
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);
screen->flush_frontbuffer(screen,
resource,
level, layer,
- context_private);
+ context_private, sub_box);
}
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;
(void)level;
(void)layer;
(void)winsys_drawable_handle;
+ (void)sub_box;
}
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);
screen->flush_frontbuffer(screen,
resource,
level, layer,
- context_private);
+ context_private, sub_box);
}
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;
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 )
{
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)
{
}
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);
screen->flush_frontbuffer(screen,
resource,
level, layer,
- context_private);
+ context_private, sub_box);
}
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;
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
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);
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();
}
struct pipe_resource;
struct pipe_surface;
struct pipe_transfer;
+struct pipe_box;
/**
* 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,
{
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);
};
/**
struct pipe_screen;
struct pipe_context;
struct pipe_resource;
-
+struct pipe_box;
/**
* Opaque pointer.
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,
#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"
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)
{
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);
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
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);
}
}
}
+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,
};
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 **
.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
};
return TRUE;
rsurf->screen->flush_frontbuffer(rsurf->screen,
- pres, 0, 0, winsys_drawable_handle);
+ pres, 0, 0, winsys_drawable_handle, NULL);
return TRUE;
}
xdraw.drawable = (Drawable) pix;
xdpy->base.screen->flush_frontbuffer(xdpy->base.screen,
- src, 0, 0, &xdraw);
+ src, 0, 0, &xdraw, NULL);
return TRUE;
}
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;
}
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);
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) {
// 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;
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 )
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
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);
}
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
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
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);
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);
}
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);
}
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
static void
android_displaytarget_display(struct sw_winsys *ws,
struct sw_displaytarget *dt,
- void *context_private)
+ void *context_private,
+ struct pipe_box *box)
{
}
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)
{
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);
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:
*/
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);
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);
}
static void
wayland_displaytarget_display(struct sw_winsys *ws,
struct sw_displaytarget *dt,
- void *context_private)
+ void *context_private,
+ struct pipe_box *box)
{
}
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);
const __DRIcoreExtension *core;
const __DRIswrastExtension *swrast;
const __DRItexBufferExtension *texBuffer;
+ const __DRIcopySubBufferExtension *copySubBuffer;
const __DRIconfig **driver_configs;
}
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);
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,
{__DRI_SWRAST_LOADER, __DRI_SWRAST_LOADER_VERSION},
swrastGetDrawableInfo,
swrastPutImage,
- swrastGetImage
+ swrastGetImage,
+ swrastPutImage2,
};
static const __DRIextension *loader_extensions[] = {
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)
{
"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)) {
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) {
psp->createDrawable = driswCreateDrawable;
psp->swapBuffers = driswSwapBuffers;
+ if (psc->copySubBuffer)
+ psp->copySubBuffer = driswCopySubBuffer;
+
return &psc->base;
handle_error:
.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,
+};
extern const __DRIswrastExtension driSWRastExtension;
extern const __DRIdri2Extension driDRI2Extension;
extern const __DRI2configQueryExtension dri2ConfigQueryExtension;
-
+extern const __DRIcopySubBufferExtension driCopySubBufferExtension;
/**
* Driver callback functions.
*
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;
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,
.SwapBuffers = dri_swap_buffers,
.MakeCurrent = dri_make_current,
.UnbindContext = dri_unbind_context,
+ .CopySubBuffer = dri_copy_sub_buffer,
};
static const struct __DRIDriverVtableExtensionRec swrast_vtable = {
static const __DRIextension *swrast_driver_extensions[] = {
&driCoreExtension.base,
&driSWRastExtension.base,
+ &driCopySubBufferExtension.base,
&swrast_vtable.base,
NULL
};