diff options
Diffstat (limited to 'src/gallium')
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_texture.c | 21 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_texture.c | 18 | ||||
-rw-r--r-- | src/gallium/include/pipe/p_screen.h | 4 | ||||
-rw-r--r-- | src/gallium/include/state_tracker/drisw_api.h | 3 | ||||
-rw-r--r-- | src/gallium/include/state_tracker/sw_winsys.h | 1 | ||||
-rw-r--r-- | src/gallium/state_trackers/dri/drisw.c | 39 | ||||
-rw-r--r-- | src/gallium/winsys/sw/dri/dri_sw_winsys.c | 15 |
7 files changed, 89 insertions, 12 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c index af46342fdf2..7862ac8f217 100644 --- a/src/gallium/drivers/llvmpipe/lp_texture.c +++ b/src/gallium/drivers/llvmpipe/lp_texture.c @@ -200,7 +200,8 @@ llvmpipe_can_create_resource(struct pipe_screen *screen, 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; @@ -215,12 +216,13 @@ llvmpipe_displaytarget_layout(struct llvmpipe_screen *screen, 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); @@ -235,8 +237,9 @@ llvmpipe_displaytarget_layout(struct llvmpipe_screen *screen, 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); @@ -254,7 +257,7 @@ llvmpipe_resource_create(struct pipe_screen *_screen, 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 { @@ -300,7 +303,12 @@ llvmpipe_resource_create(struct pipe_screen *_screen, 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, @@ -797,6 +805,7 @@ llvmpipe_init_screen_resource_funcs(struct pipe_screen *screen) #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; diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index e1ea5df24ca..3347f5f1883 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -127,7 +127,8 @@ softpipe_can_create_resource(struct pipe_screen *screen, */ 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; @@ -139,6 +140,7 @@ softpipe_displaytarget_layout(struct pipe_screen *screen, spr->base.width0, spr->base.height0, 64, + map_front_private, &spr->stride[0] ); return spr->dt != NULL; @@ -149,8 +151,9 @@ softpipe_displaytarget_layout(struct pipe_screen *screen, * 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) @@ -169,7 +172,7 @@ softpipe_resource_create(struct pipe_screen *screen, 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 { @@ -184,6 +187,12 @@ softpipe_resource_create(struct pipe_screen *screen, 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, @@ -514,6 +523,7 @@ void 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; diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h index a22fb938dbb..f868d71db23 100644 --- a/src/gallium/include/pipe/p_screen.h +++ b/src/gallium/include/pipe/p_screen.h @@ -169,6 +169,10 @@ struct pipe_screen { 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 diff --git a/src/gallium/include/state_tracker/drisw_api.h b/src/gallium/include/state_tracker/drisw_api.h index 328440cf5ff..cd5a27e2482 100644 --- a/src/gallium/include/state_tracker/drisw_api.h +++ b/src/gallium/include/state_tracker/drisw_api.h @@ -11,6 +11,9 @@ struct dri_drawable; */ 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, diff --git a/src/gallium/include/state_tracker/sw_winsys.h b/src/gallium/include/state_tracker/sw_winsys.h index a3479eb0bc3..0b792cd0ce4 100644 --- a/src/gallium/include/state_tracker/sw_winsys.h +++ b/src/gallium/include/state_tracker/sw_winsys.h @@ -90,6 +90,7 @@ struct sw_winsys enum pipe_format format, unsigned width, unsigned height, unsigned alignment, + const void *front_private, unsigned *stride ); /** diff --git a/src/gallium/state_trackers/dri/drisw.c b/src/gallium/state_trackers/dri/drisw.c index 4ec6992643a..753c59d696a 100644 --- a/src/gallium/state_trackers/dri/drisw.c +++ b/src/gallium/state_trackers/dri/drisw.c @@ -95,6 +95,21 @@ get_image(__DRIdrawable *dPriv, int x, int y, int width, int height, void *data) 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) { @@ -105,6 +120,18 @@ drisw_update_drawable_info(struct dri_drawable *drawable) } 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) { @@ -236,6 +263,7 @@ drisw_allocate_textures(struct dri_context *stctx, 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; @@ -281,8 +309,14 @@ drisw_allocate_textures(struct dri_context *stctx, 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; @@ -338,6 +372,7 @@ static const __DRIextension *drisw_screen_extensions[] = { }; static struct drisw_loader_funcs drisw_lf = { + .get_image = drisw_get_image, .put_image = drisw_put_image, .put_image2 = drisw_put_image2 }; diff --git a/src/gallium/winsys/sw/dri/dri_sw_winsys.c b/src/gallium/winsys/sw/dri/dri_sw_winsys.c index 8451d832806..5c98f2603c7 100644 --- a/src/gallium/winsys/sw/dri/dri_sw_winsys.c +++ b/src/gallium/winsys/sw/dri/dri_sw_winsys.c @@ -44,8 +44,10 @@ struct dri_sw_displaytarget unsigned height; unsigned stride; + unsigned map_flags; void *data; void *mapped; + const void *front_private; }; struct dri_sw_winsys @@ -83,6 +85,7 @@ dri_sw_displaytarget_create(struct sw_winsys *winsys, enum pipe_format format, unsigned width, unsigned height, unsigned alignment, + const void *front_private, unsigned *stride) { struct dri_sw_displaytarget *dri_sw_dt; @@ -95,6 +98,7 @@ dri_sw_displaytarget_create(struct sw_winsys *winsys, 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); @@ -133,6 +137,12 @@ dri_sw_displaytarget_map(struct sw_winsys *ws, { 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; } @@ -141,6 +151,11 @@ dri_sw_displaytarget_unmap(struct sw_winsys *ws, 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; } |