* SWRast Loader extension.
*/
#define __DRI_SWRAST_LOADER "DRI_SWRastLoader"
-#define __DRI_SWRAST_LOADER_VERSION 2
+#define __DRI_SWRAST_LOADER_VERSION 3
struct __DRIswrastLoaderExtensionRec {
__DRIextension base;
void (*putImage2)(__DRIdrawable *drawable, int op,
int x, int y, int width, int height, int stride,
char *data, void *loaderPrivate);
+
+ /**
+ * Put image to drawable
+ *
+ * \since 3
+ */
+ void (*getImage2)(__DRIdrawable *readable,
+ int x, int y, int width, int height, int stride,
+ char *data, void *loaderPrivate);
};
/**
static boolean
llvmpipe_displaytarget_layout(struct llvmpipe_screen *screen,
- struct llvmpipe_resource *lpr)
+ struct llvmpipe_resource *lpr,
+ const void *map_front_private)
{
struct sw_winsys *winsys = screen->winsys;
lpr->base.format,
width, height,
64,
+ map_front_private,
&lpr->row_stride[0] );
if (lpr->dt == NULL)
return FALSE;
- {
+ if (!map_front_private) {
void *map = winsys->displaytarget_map(winsys, lpr->dt,
PIPE_TRANSFER_WRITE);
static struct pipe_resource *
-llvmpipe_resource_create(struct pipe_screen *_screen,
- const struct pipe_resource *templat)
+llvmpipe_resource_create_front(struct pipe_screen *_screen,
+ const struct pipe_resource *templat,
+ const void *map_front_private)
{
struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
struct llvmpipe_resource *lpr = CALLOC_STRUCT(llvmpipe_resource);
PIPE_BIND_SCANOUT |
PIPE_BIND_SHARED)) {
/* displayable surface */
- if (!llvmpipe_displaytarget_layout(screen, lpr))
+ if (!llvmpipe_displaytarget_layout(screen, lpr, map_front_private))
goto fail;
}
else {
FREE(lpr);
return NULL;
}
-
+static struct pipe_resource *
+llvmpipe_resource_create(struct pipe_screen *_screen,
+ const struct pipe_resource *templat)
+{
+ return llvmpipe_resource_create_front(_screen, templat, NULL);
+}
static void
llvmpipe_resource_destroy(struct pipe_screen *pscreen,
#endif
screen->resource_create = llvmpipe_resource_create;
+ screen->resource_create_front = llvmpipe_resource_create_front;
screen->resource_destroy = llvmpipe_resource_destroy;
screen->resource_from_handle = llvmpipe_resource_from_handle;
screen->resource_get_handle = llvmpipe_resource_get_handle;
*/
static boolean
softpipe_displaytarget_layout(struct pipe_screen *screen,
- struct softpipe_resource *spr)
+ struct softpipe_resource *spr,
+ const void *map_front_private)
{
struct sw_winsys *winsys = softpipe_screen(screen)->winsys;
spr->base.width0,
spr->base.height0,
64,
+ map_front_private,
&spr->stride[0] );
return spr->dt != NULL;
* Create new pipe_resource given the template information.
*/
static struct pipe_resource *
-softpipe_resource_create(struct pipe_screen *screen,
- const struct pipe_resource *templat)
+softpipe_resource_create_front(struct pipe_screen *screen,
+ const struct pipe_resource *templat,
+ const void *map_front_private)
{
struct softpipe_resource *spr = CALLOC_STRUCT(softpipe_resource);
if (!spr)
if (spr->base.bind & (PIPE_BIND_DISPLAY_TARGET |
PIPE_BIND_SCANOUT |
PIPE_BIND_SHARED)) {
- if (!softpipe_displaytarget_layout(screen, spr))
+ if (!softpipe_displaytarget_layout(screen, spr, map_front_private))
goto fail;
}
else {
return NULL;
}
+static struct pipe_resource *
+softpipe_resource_create(struct pipe_screen *screen,
+ const struct pipe_resource *templat)
+{
+ return softpipe_resource_create_front(screen, templat, NULL);
+}
static void
softpipe_resource_destroy(struct pipe_screen *pscreen,
softpipe_init_screen_texture_funcs(struct pipe_screen *screen)
{
screen->resource_create = softpipe_resource_create;
+ screen->resource_create_front = softpipe_resource_create_front;
screen->resource_destroy = softpipe_resource_destroy;
screen->resource_from_handle = softpipe_resource_from_handle;
screen->resource_get_handle = softpipe_resource_get_handle;
struct pipe_resource * (*resource_create)(struct pipe_screen *,
const struct pipe_resource *templat);
+ struct pipe_resource * (*resource_create_front)(struct pipe_screen *,
+ const struct pipe_resource *templat,
+ const void *map_front_private);
+
/**
* Create a texture from a winsys_handle. The handle is often created in
* another process by first creating a pipe texture and then calling
*/
struct drisw_loader_funcs
{
+ void (*get_image) (struct dri_drawable *dri_drawable,
+ int x, int y, unsigned width, unsigned height, unsigned stride,
+ void *data);
void (*put_image) (struct dri_drawable *dri_drawable,
void *data, unsigned width, unsigned height);
void (*put_image2) (struct dri_drawable *dri_drawable,
enum pipe_format format,
unsigned width, unsigned height,
unsigned alignment,
+ const void *front_private,
unsigned *stride );
/**
data, dPriv->loaderPrivate);
}
+static inline void
+get_image2(__DRIdrawable *dPriv, int x, int y, int width, int height, int stride, void *data)
+{
+ __DRIscreen *sPriv = dPriv->driScreenPriv;
+ const __DRIswrastLoaderExtension *loader = sPriv->swrast_loader;
+
+ /* getImage2 support is only in version 3 or newer */
+ if (loader->base.version < 3)
+ return;
+
+ loader->getImage2(dPriv,
+ x, y, width, height, stride,
+ data, dPriv->loaderPrivate);
+}
+
static void
drisw_update_drawable_info(struct dri_drawable *drawable)
{
get_drawable_info(dPriv, &x, &y, &dPriv->w, &dPriv->h);
}
+static void
+drisw_get_image(struct dri_drawable *drawable,
+ int x, int y, unsigned width, unsigned height, unsigned stride,
+ void *data)
+{
+ __DRIdrawable *dPriv = drawable->dPriv;
+ int draw_x, draw_y, draw_w, draw_h;
+
+ get_drawable_info(dPriv, &draw_x, &draw_y, &draw_w, &draw_h);
+ get_image2(dPriv, x, y, draw_w, draw_h, stride, data);
+}
+
static void
drisw_put_image(struct dri_drawable *drawable,
void *data, unsigned width, unsigned height)
unsigned count)
{
struct dri_screen *screen = dri_screen(drawable->sPriv);
+ const __DRIswrastLoaderExtension *loader = drawable->dPriv->driScreenPriv->swrast_loader;
struct pipe_resource templ;
unsigned width, height;
boolean resized;
templ.format = format;
templ.bind = bind;
- drawable->textures[statts[i]] =
- screen->base.screen->resource_create(screen->base.screen, &templ);
+ if (statts[i] == ST_ATTACHMENT_FRONT_LEFT &&
+ screen->base.screen->resource_create_front &&
+ loader->base.version >= 3) {
+ drawable->textures[statts[i]] =
+ screen->base.screen->resource_create_front(screen->base.screen, &templ, (const void *)drawable);
+ } else
+ drawable->textures[statts[i]] =
+ screen->base.screen->resource_create(screen->base.screen, &templ);
}
drawable->old_w = width;
};
static struct drisw_loader_funcs drisw_lf = {
+ .get_image = drisw_get_image,
.put_image = drisw_put_image,
.put_image2 = drisw_put_image2
};
unsigned height;
unsigned stride;
+ unsigned map_flags;
void *data;
void *mapped;
+ const void *front_private;
};
struct dri_sw_winsys
enum pipe_format format,
unsigned width, unsigned height,
unsigned alignment,
+ const void *front_private,
unsigned *stride)
{
struct dri_sw_displaytarget *dri_sw_dt;
dri_sw_dt->format = format;
dri_sw_dt->width = width;
dri_sw_dt->height = height;
+ dri_sw_dt->front_private = front_private;
format_stride = util_format_get_stride(format, width);
dri_sw_dt->stride = align(format_stride, alignment);
{
struct dri_sw_displaytarget *dri_sw_dt = dri_sw_displaytarget(dt);
dri_sw_dt->mapped = dri_sw_dt->data;
+
+ if (dri_sw_dt->front_private && (flags & PIPE_TRANSFER_READ)) {
+ struct dri_sw_winsys *dri_sw_ws = dri_sw_winsys(ws);
+ dri_sw_ws->lf->get_image((void *)dri_sw_dt->front_private, 0, 0, dri_sw_dt->width, dri_sw_dt->height, dri_sw_dt->stride, dri_sw_dt->data);
+ }
+ dri_sw_dt->map_flags = flags;
return dri_sw_dt->mapped;
}
struct sw_displaytarget *dt)
{
struct dri_sw_displaytarget *dri_sw_dt = dri_sw_displaytarget(dt);
+ if (dri_sw_dt->front_private && (dri_sw_dt->map_flags & PIPE_TRANSFER_WRITE)) {
+ struct dri_sw_winsys *dri_sw_ws = dri_sw_winsys(ws);
+ dri_sw_ws->lf->put_image2((void *)dri_sw_dt->front_private, dri_sw_dt->data, 0, 0, dri_sw_dt->width, dri_sw_dt->height, dri_sw_dt->stride);
+ }
+ dri_sw_dt->map_flags = 0;
dri_sw_dt->mapped = NULL;
}
}
static void
-swrastGetImage(__DRIdrawable * read,
- int x, int y, int w, int h,
- char *data, void *loaderPrivate)
+swrastGetImage2(__DRIdrawable * read,
+ int x, int y, int w, int h, int stride,
+ char *data, void *loaderPrivate)
{
struct drisw_drawable *prp = loaderPrivate;
__GLXDRIdrawable *pread = &(prp->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);
XGetSubImage(dpy, readable, x, y, w, h, ~0L, ZPixmap, ximage, 0, 0);
ximage->data = NULL;
}
+static void
+swrastGetImage(__DRIdrawable * read,
+ int x, int y, int w, int h,
+ char *data, void *loaderPrivate)
+{
+ swrastGetImage2(read, x, y, w, h, 0, data, loaderPrivate);
+}
+
static const __DRIswrastLoaderExtension swrastLoaderExtension = {
- .base = {__DRI_SWRAST_LOADER, 2 },
+ .base = {__DRI_SWRAST_LOADER, 3 },
.getDrawableInfo = swrastGetDrawableInfo,
.putImage = swrastPutImage,
.getImage = swrastGetImage,
.putImage2 = swrastPutImage2,
+ .getImage2 = swrastGetImage2,
};
static const __DRIextension *loader_extensions[] = {