[Mesa-dev] [PATCH 04/10] gallium: add user_stride parameter to pipe_context::transfer_map
Marek Olšák
maraeo at gmail.com
Wed Apr 25 21:16:25 UTC 2018
From: Nicolai Hähnle <nicolai.haehnle at amd.com>
Allow callers to prescribe a desired stride for a transfer. Drivers
are free to ignore this new parameter.
There is no new capability because it's unclear how strict requirements
on this feature should be expressed.
---
src/gallium/auxiliary/driver_ddebug/dd_draw.c | 3 ++-
src/gallium/auxiliary/driver_noop/noop_pipe.c | 1 +
src/gallium/auxiliary/driver_rbug/rbug_context.c | 5 ++++-
src/gallium/auxiliary/driver_trace/tr_context.c | 3 ++-
src/gallium/auxiliary/util/u_inlines.h | 8 ++++----
src/gallium/auxiliary/util/u_threaded_context.c | 5 +++--
src/gallium/auxiliary/util/u_transfer.c | 3 ++-
src/gallium/auxiliary/util/u_transfer.h | 2 ++
src/gallium/auxiliary/util/u_transfer_helper.c | 1 +
src/gallium/auxiliary/util/u_transfer_helper.h | 1 +
src/gallium/drivers/etnaviv/etnaviv_transfer.c | 1 +
src/gallium/drivers/i915/i915_resource_buffer.c | 1 +
src/gallium/drivers/i915/i915_resource_texture.c | 1 +
src/gallium/drivers/llvmpipe/lp_texture.c | 1 +
src/gallium/drivers/nouveau/nouveau_buffer.c | 1 +
src/gallium/drivers/nouveau/nv30/nv30_miptree.c | 1 +
src/gallium/drivers/nouveau/nv50/nv50_transfer.c | 1 +
src/gallium/drivers/nouveau/nvc0/nvc0_transfer.c | 1 +
src/gallium/drivers/r300/r300_screen_buffer.c | 1 +
src/gallium/drivers/r300/r300_transfer.c | 1 +
src/gallium/drivers/r300/r300_transfer.h | 1 +
src/gallium/drivers/r600/evergreen_compute.c | 1 +
src/gallium/drivers/r600/r600_buffer_common.c | 3 ++-
src/gallium/drivers/r600/r600_texture.c | 1 +
src/gallium/drivers/radeonsi/si_buffer.c | 3 ++-
src/gallium/drivers/radeonsi/si_texture.c | 1 +
src/gallium/drivers/softpipe/sp_texture.c | 1 +
src/gallium/drivers/svga/svga_resource_buffer.c | 1 +
src/gallium/drivers/svga/svga_resource_texture.c | 1 +
src/gallium/drivers/vc4/vc4_resource.c | 1 +
src/gallium/drivers/virgl/virgl_buffer.c | 1 +
src/gallium/drivers/virgl/virgl_texture.c | 1 +
src/gallium/include/pipe/p_context.h | 7 +++++++
33 files changed, 53 insertions(+), 12 deletions(-)
diff --git a/src/gallium/auxiliary/driver_ddebug/dd_draw.c b/src/gallium/auxiliary/driver_ddebug/dd_draw.c
index cb5db8ab83b..125f6041324 100644
--- a/src/gallium/auxiliary/driver_ddebug/dd_draw.c
+++ b/src/gallium/auxiliary/driver_ddebug/dd_draw.c
@@ -1478,33 +1478,34 @@ dd_context_clear_texture(struct pipe_context *_pipe,
}
/********************************************************************
* transfer
*/
static void *
dd_context_transfer_map(struct pipe_context *_pipe,
struct pipe_resource *resource, unsigned level,
unsigned usage, const struct pipe_box *box,
+ unsigned user_stride,
struct pipe_transfer **transfer)
{
struct dd_context *dctx = dd_context(_pipe);
struct pipe_context *pipe = dctx->pipe;
struct dd_draw_record *record =
dd_screen(dctx->base.screen)->transfers ? dd_create_record(dctx) : NULL;
if (record) {
record->call.type = CALL_TRANSFER_MAP;
dd_before_draw(dctx, record);
}
- void *ptr = pipe->transfer_map(pipe, resource, level, usage, box, transfer);
+ void *ptr = pipe->transfer_map(pipe, resource, level, usage, box, user_stride, transfer);
if (record) {
record->call.info.transfer_map.transfer_ptr = *transfer;
record->call.info.transfer_map.ptr = ptr;
if (*transfer) {
record->call.info.transfer_map.transfer = **transfer;
record->call.info.transfer_map.transfer.resource = NULL;
pipe_resource_reference(&record->call.info.transfer_map.transfer.resource,
(*transfer)->resource);
} else {
memset(&record->call.info.transfer_map.transfer, 0, sizeof(struct pipe_transfer));
diff --git a/src/gallium/auxiliary/driver_noop/noop_pipe.c b/src/gallium/auxiliary/driver_noop/noop_pipe.c
index d1e795dab16..cc74fcbd5df 100644
--- a/src/gallium/auxiliary/driver_noop/noop_pipe.c
+++ b/src/gallium/auxiliary/driver_noop/noop_pipe.c
@@ -167,20 +167,21 @@ static void noop_resource_destroy(struct pipe_screen *screen,
/*
* transfer
*/
static void *noop_transfer_map(struct pipe_context *pipe,
struct pipe_resource *resource,
unsigned level,
enum pipe_transfer_usage usage,
const struct pipe_box *box,
+ unsigned user_stride,
struct pipe_transfer **ptransfer)
{
struct pipe_transfer *transfer;
struct noop_resource *nresource = (struct noop_resource *)resource;
transfer = CALLOC_STRUCT(pipe_transfer);
if (!transfer)
return NULL;
pipe_resource_reference(&transfer->resource, resource);
transfer->level = level;
diff --git a/src/gallium/auxiliary/driver_rbug/rbug_context.c b/src/gallium/auxiliary/driver_rbug/rbug_context.c
index e1f3c4f2844..a03f4a79b46 100644
--- a/src/gallium/auxiliary/driver_rbug/rbug_context.c
+++ b/src/gallium/auxiliary/driver_rbug/rbug_context.c
@@ -1065,35 +1065,38 @@ rbug_context_surface_destroy(struct pipe_context *_pipe,
}
static void *
rbug_context_transfer_map(struct pipe_context *_context,
struct pipe_resource *_resource,
unsigned level,
unsigned usage,
const struct pipe_box *box,
+ unsigned user_stride,
struct pipe_transfer **transfer)
{
struct rbug_context *rb_pipe = rbug_context(_context);
struct rbug_resource *rb_resource = rbug_resource(_resource);
struct pipe_context *context = rb_pipe->pipe;
struct pipe_resource *resource = rb_resource->resource;
struct pipe_transfer *result;
void *map;
mtx_lock(&rb_pipe->call_mutex);
map = context->transfer_map(context,
resource,
level,
usage,
- box, &result);
+ box,
+ user_stride,
+ &result);
mtx_unlock(&rb_pipe->call_mutex);
*transfer = rbug_transfer_create(rb_pipe, rb_resource, result);
return *transfer ? map : NULL;
}
static void
rbug_context_transfer_flush_region(struct pipe_context *_context,
struct pipe_transfer *_transfer,
const struct pipe_box *box)
diff --git a/src/gallium/auxiliary/driver_trace/tr_context.c b/src/gallium/auxiliary/driver_trace/tr_context.c
index 6d918d42a38..ff8b556b596 100644
--- a/src/gallium/auxiliary/driver_trace/tr_context.c
+++ b/src/gallium/auxiliary/driver_trace/tr_context.c
@@ -1368,33 +1368,34 @@ trace_context_destroy(struct pipe_context *_pipe)
* transfer
*/
static void *
trace_context_transfer_map(struct pipe_context *_context,
struct pipe_resource *resource,
unsigned level,
unsigned usage,
const struct pipe_box *box,
+ unsigned user_stride,
struct pipe_transfer **transfer)
{
struct trace_context *tr_context = trace_context(_context);
struct pipe_context *context = tr_context->pipe;
struct pipe_transfer *result = NULL;
void *map;
/*
* Map and transfers can't be serialized so we convert all write transfers
* to texture/buffer_subdata and ignore read transfers.
*/
- map = context->transfer_map(context, resource, level, usage, box, &result);
+ map = context->transfer_map(context, resource, level, usage, box, user_stride, &result);
if (!map)
return NULL;
*transfer = trace_transfer_create(tr_context, resource, result);
if (map) {
if (usage & PIPE_TRANSFER_WRITE) {
trace_transfer(*transfer)->map = map;
}
}
diff --git a/src/gallium/auxiliary/util/u_inlines.h b/src/gallium/auxiliary/util/u_inlines.h
index b7a28568807..3baa00f518d 100644
--- a/src/gallium/auxiliary/util/u_inlines.h
+++ b/src/gallium/auxiliary/util/u_inlines.h
@@ -322,21 +322,21 @@ pipe_buffer_map_range(struct pipe_context *pipe,
{
struct pipe_box box;
void *map;
assert(offset < buffer->width0);
assert(offset + length <= buffer->width0);
assert(length);
u_box_1d(offset, length, &box);
- map = pipe->transfer_map(pipe, buffer, 0, access, &box, transfer);
+ map = pipe->transfer_map(pipe, buffer, 0, access, &box, 0, transfer);
if (!map) {
return NULL;
}
return map;
}
/**
* Map whole resource.
@@ -459,21 +459,21 @@ pipe_buffer_read(struct pipe_context *pipe,
* Map a resource for reading/writing.
*/
static inline void *
pipe_transfer_map_box(struct pipe_context *context,
struct pipe_resource *resource,
unsigned level,
enum pipe_transfer_usage usage,
const struct pipe_box *box,
struct pipe_transfer **out_transfer)
{
- return context->transfer_map(context, resource, level, usage, box,
+ return context->transfer_map(context, resource, level, usage, box, 0,
out_transfer);
}
/**
* Map a resource for reading/writing.
* \param access bitmask of PIPE_TRANSFER_x flags
*/
static inline void *
pipe_transfer_map(struct pipe_context *context,
@@ -483,21 +483,21 @@ pipe_transfer_map(struct pipe_context *context,
unsigned x, unsigned y,
unsigned w, unsigned h,
struct pipe_transfer **transfer)
{
struct pipe_box box;
u_box_2d_zslice(x, y, layer, w, h, &box);
return context->transfer_map(context,
resource,
level,
access,
- &box, transfer);
+ &box, 0, transfer);
}
/**
* Map a 3D (texture) resource for reading/writing.
* \param access bitmask of PIPE_TRANSFER_x flags
*/
static inline void *
pipe_transfer_map_3d(struct pipe_context *context,
struct pipe_resource *resource,
@@ -506,21 +506,21 @@ pipe_transfer_map_3d(struct pipe_context *context,
unsigned x, unsigned y, unsigned z,
unsigned w, unsigned h, unsigned d,
struct pipe_transfer **transfer)
{
struct pipe_box box;
u_box_3d(x, y, z, w, h, d, &box);
return context->transfer_map(context,
resource,
level,
access,
- &box, transfer);
+ &box, 0, transfer);
}
static inline void
pipe_transfer_unmap( struct pipe_context *context,
struct pipe_transfer *transfer )
{
context->transfer_unmap( context, transfer );
}
static inline void
diff --git a/src/gallium/auxiliary/util/u_threaded_context.c b/src/gallium/auxiliary/util/u_threaded_context.c
index 1c647a3efd0..0c41f5582a9 100644
--- a/src/gallium/auxiliary/util/u_threaded_context.c
+++ b/src/gallium/auxiliary/util/u_threaded_context.c
@@ -1429,20 +1429,21 @@ tc_improve_map_buffer_flags(struct threaded_context *tc,
usage |= TC_TRANSFER_MAP_THREADED_UNSYNC; /* notify the driver */
}
return usage;
}
static void *
tc_transfer_map(struct pipe_context *_pipe,
struct pipe_resource *resource, unsigned level,
unsigned usage, const struct pipe_box *box,
+ unsigned user_stride,
struct pipe_transfer **transfer)
{
struct threaded_context *tc = threaded_context(_pipe);
struct threaded_resource *tres = threaded_resource(resource);
struct pipe_context *pipe = tc->pipe;
if (resource->target == PIPE_BUFFER) {
usage = tc_improve_map_buffer_flags(tc, tres, usage, box->x, box->width);
/* Do a staging transfer within the threaded context. The driver should
@@ -1473,21 +1474,21 @@ tc_transfer_map(struct pipe_context *_pipe,
}
}
/* Unsychronized buffer mappings don't have to synchronize the thread. */
if (!(usage & TC_TRANSFER_MAP_THREADED_UNSYNC))
tc_sync_msg(tc, resource->target != PIPE_BUFFER ? " texture" :
usage & PIPE_TRANSFER_DISCARD_RANGE ? " discard_range" :
usage & PIPE_TRANSFER_READ ? " read" : " ??");
return pipe->transfer_map(pipe, tres->latest ? tres->latest : resource,
- level, usage, box, transfer);
+ level, usage, box, user_stride, transfer);
}
struct tc_transfer_flush_region {
struct pipe_transfer *transfer;
struct pipe_box box;
};
static void
tc_call_transfer_flush_region(struct pipe_context *pipe,
union tc_payload *payload)
@@ -1634,21 +1635,21 @@ tc_buffer_subdata(struct pipe_context *_pipe,
*/
if (usage & (PIPE_TRANSFER_UNSYNCHRONIZED |
PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE) ||
size > TC_MAX_SUBDATA_BYTES) {
struct pipe_transfer *transfer;
struct pipe_box box;
uint8_t *map = NULL;
u_box_1d(offset, size, &box);
- map = tc_transfer_map(_pipe, resource, 0, usage, &box, &transfer);
+ map = tc_transfer_map(_pipe, resource, 0, usage, &box, 0, &transfer);
if (map) {
memcpy(map, data, size);
tc_transfer_unmap(_pipe, transfer);
}
return;
}
util_range_add(&tres->valid_buffer_range, offset, offset + size);
/* The upload is small. Enqueue it. */
diff --git a/src/gallium/auxiliary/util/u_transfer.c b/src/gallium/auxiliary/util/u_transfer.c
index 0e0c4cc91cd..5f07ea067fd 100644
--- a/src/gallium/auxiliary/util/u_transfer.c
+++ b/src/gallium/auxiliary/util/u_transfer.c
@@ -125,25 +125,26 @@ void u_resource_destroy_vtbl(struct pipe_screen *screen,
{
struct u_resource *ur = u_resource(resource);
ur->vtbl->resource_destroy(screen, resource);
}
void *u_transfer_map_vtbl(struct pipe_context *context,
struct pipe_resource *resource,
unsigned level,
unsigned usage,
const struct pipe_box *box,
+ unsigned user_stride,
struct pipe_transfer **transfer)
{
struct u_resource *ur = u_resource(resource);
return ur->vtbl->transfer_map(context, resource, level, usage, box,
- transfer);
+ user_stride, transfer);
}
void u_transfer_flush_region_vtbl( struct pipe_context *pipe,
struct pipe_transfer *transfer,
const struct pipe_box *box)
{
struct u_resource *ur = u_resource(transfer->resource);
ur->vtbl->transfer_flush_region(pipe, transfer, box);
}
diff --git a/src/gallium/auxiliary/util/u_transfer.h b/src/gallium/auxiliary/util/u_transfer.h
index 14084983daf..9f1fcb626f3 100644
--- a/src/gallium/auxiliary/util/u_transfer.h
+++ b/src/gallium/auxiliary/util/u_transfer.h
@@ -51,20 +51,21 @@ struct u_resource_vtbl {
struct winsys_handle *handle);
void (*resource_destroy)(struct pipe_screen *,
struct pipe_resource *pt);
void *(*transfer_map)(struct pipe_context *,
struct pipe_resource *resource,
unsigned level,
unsigned usage,
const struct pipe_box *,
+ unsigned user_stride,
struct pipe_transfer **);
void (*transfer_flush_region)( struct pipe_context *,
struct pipe_transfer *transfer,
const struct pipe_box *);
void (*transfer_unmap)( struct pipe_context *,
struct pipe_transfer *transfer );
};
@@ -83,20 +84,21 @@ boolean u_resource_get_handle_vtbl(struct pipe_screen *screen,
unsigned usage);
void u_resource_destroy_vtbl(struct pipe_screen *screen,
struct pipe_resource *resource);
void *u_transfer_map_vtbl(struct pipe_context *context,
struct pipe_resource *resource,
unsigned level,
unsigned usage,
const struct pipe_box *box,
+ unsigned user_stride,
struct pipe_transfer **transfer);
void u_transfer_flush_region_vtbl( struct pipe_context *pipe,
struct pipe_transfer *transfer,
const struct pipe_box *box);
void u_transfer_unmap_vtbl( struct pipe_context *rm_ctx,
struct pipe_transfer *transfer );
#ifdef __cplusplus
diff --git a/src/gallium/auxiliary/util/u_transfer_helper.c b/src/gallium/auxiliary/util/u_transfer_helper.c
index f69015af519..b5ad30c522d 100644
--- a/src/gallium/auxiliary/util/u_transfer_helper.c
+++ b/src/gallium/auxiliary/util/u_transfer_helper.c
@@ -217,20 +217,21 @@ transfer_map_msaa(struct pipe_context *pctx,
*pptrans = ptrans;
return ss_map;
}
void *
u_transfer_helper_transfer_map(struct pipe_context *pctx,
struct pipe_resource *prsc,
unsigned level, unsigned usage,
const struct pipe_box *box,
+ unsigned user_stride,
struct pipe_transfer **pptrans)
{
struct u_transfer_helper *helper = pctx->screen->transfer_helper;
struct u_transfer *trans;
struct pipe_transfer *ptrans;
enum pipe_format format = prsc->format;
unsigned width = box->width;
unsigned height = box->height;
if (!handle_transfer(prsc))
diff --git a/src/gallium/auxiliary/util/u_transfer_helper.h b/src/gallium/auxiliary/util/u_transfer_helper.h
index b13a1ec06c1..351efa894da 100644
--- a/src/gallium/auxiliary/util/u_transfer_helper.h
+++ b/src/gallium/auxiliary/util/u_transfer_helper.h
@@ -102,20 +102,21 @@ struct pipe_resource *u_transfer_helper_resource_create(
struct pipe_screen *pscreen, const struct pipe_resource *templ);
void u_transfer_helper_resource_destroy(struct pipe_screen *pscreen,
struct pipe_resource *prsc);
void *u_transfer_helper_transfer_map(struct pipe_context *pctx,
struct pipe_resource *prsc,
unsigned level,
unsigned usage,
const struct pipe_box *box,
+ unsigned user_stride,
struct pipe_transfer **pptrans);
void u_transfer_helper_transfer_flush_region(struct pipe_context *pctx,
struct pipe_transfer *ptrans,
const struct pipe_box *box);
void u_transfer_helper_transfer_unmap(struct pipe_context *pctx,
struct pipe_transfer *ptrans);
diff --git a/src/gallium/drivers/etnaviv/etnaviv_transfer.c b/src/gallium/drivers/etnaviv/etnaviv_transfer.c
index 30ae3bfc39d..8d079ad4e29 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_transfer.c
+++ b/src/gallium/drivers/etnaviv/etnaviv_transfer.c
@@ -131,20 +131,21 @@ etna_transfer_unmap(struct pipe_context *pctx, struct pipe_transfer *ptrans)
pipe_resource_reference(&trans->rsc, NULL);
pipe_resource_reference(&ptrans->resource, NULL);
slab_free(&ctx->transfer_pool, trans);
}
static void *
etna_transfer_map(struct pipe_context *pctx, struct pipe_resource *prsc,
unsigned level,
unsigned usage,
const struct pipe_box *box,
+ unsigned user_stride,
struct pipe_transfer **out_transfer)
{
struct etna_context *ctx = etna_context(pctx);
struct etna_resource *rsc = etna_resource(prsc);
struct etna_transfer *trans;
struct pipe_transfer *ptrans;
enum pipe_format format = prsc->format;
trans = slab_alloc(&ctx->transfer_pool);
if (!trans)
diff --git a/src/gallium/drivers/i915/i915_resource_buffer.c b/src/gallium/drivers/i915/i915_resource_buffer.c
index 2572fc40b2c..88a3181ee68 100644
--- a/src/gallium/drivers/i915/i915_resource_buffer.c
+++ b/src/gallium/drivers/i915/i915_resource_buffer.c
@@ -59,20 +59,21 @@ i915_buffer_destroy(struct pipe_screen *screen,
FREE(buffer);
}
static void *
i915_buffer_transfer_map(struct pipe_context *pipe,
struct pipe_resource *resource,
unsigned level,
unsigned usage,
const struct pipe_box *box,
+ unsigned user_stride,
struct pipe_transfer **ptransfer)
{
struct i915_context *i915 = i915_context(pipe);
struct i915_buffer *buffer = i915_buffer(resource);
struct pipe_transfer *transfer = slab_alloc_st(&i915->transfer_pool);
if (!transfer)
return NULL;
transfer->resource = resource;
diff --git a/src/gallium/drivers/i915/i915_resource_texture.c b/src/gallium/drivers/i915/i915_resource_texture.c
index 4ade04f223c..fbf83624275 100644
--- a/src/gallium/drivers/i915/i915_resource_texture.c
+++ b/src/gallium/drivers/i915/i915_resource_texture.c
@@ -710,20 +710,21 @@ i915_texture_destroy(struct pipe_screen *screen,
FREE(tex);
}
static void *
i915_texture_transfer_map(struct pipe_context *pipe,
struct pipe_resource *resource,
unsigned level,
unsigned usage,
const struct pipe_box *box,
+ unsigned user_stride,
struct pipe_transfer **ptransfer)
{
struct i915_context *i915 = i915_context(pipe);
struct i915_texture *tex = i915_texture(resource);
struct i915_transfer *transfer = slab_alloc_st(&i915->texture_transfer_pool);
boolean use_staging_texture = FALSE;
struct i915_winsys *iws = i915_screen(pipe->screen)->iws;
enum pipe_format format = resource->format;
unsigned offset;
char *map;
diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c
index 89852cc95c3..8d2ec6dc0e6 100644
--- a/src/gallium/drivers/llvmpipe/lp_texture.c
+++ b/src/gallium/drivers/llvmpipe/lp_texture.c
@@ -503,20 +503,21 @@ llvmpipe_resource_get_handle(struct pipe_screen *screen,
return winsys->displaytarget_get_handle(winsys, lpr->dt, whandle);
}
static void *
llvmpipe_transfer_map( struct pipe_context *pipe,
struct pipe_resource *resource,
unsigned level,
unsigned usage,
const struct pipe_box *box,
+ unsigned user_stride,
struct pipe_transfer **transfer )
{
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
struct llvmpipe_screen *screen = llvmpipe_screen(pipe->screen);
struct llvmpipe_resource *lpr = llvmpipe_resource(resource);
struct llvmpipe_transfer *lpt;
struct pipe_transfer *pt;
ubyte *map;
enum pipe_format format;
enum lp_texture_usage tex_usage;
diff --git a/src/gallium/drivers/nouveau/nouveau_buffer.c b/src/gallium/drivers/nouveau/nouveau_buffer.c
index 2c604419ce0..c5be45cadbd 100644
--- a/src/gallium/drivers/nouveau/nouveau_buffer.c
+++ b/src/gallium/drivers/nouveau/nouveau_buffer.c
@@ -370,20 +370,21 @@ nouveau_buffer_should_discard(struct nv04_resource *buf, unsigned usage)
* be overwritten.
*
* The strategy for determining what kind of memory area to return is complex,
* see comments inside of the function.
*/
static void *
nouveau_buffer_transfer_map(struct pipe_context *pipe,
struct pipe_resource *resource,
unsigned level, unsigned usage,
const struct pipe_box *box,
+ unsigned user_stride,
struct pipe_transfer **ptransfer)
{
struct nouveau_context *nv = nouveau_context(pipe);
struct nv04_resource *buf = nv04_resource(resource);
struct nouveau_transfer *tx = MALLOC_STRUCT(nouveau_transfer);
uint8_t *map;
int ret;
if (!tx)
return NULL;
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_miptree.c b/src/gallium/drivers/nouveau/nv30/nv30_miptree.c
index 4f991776323..6832289e2cb 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_miptree.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_miptree.c
@@ -254,20 +254,21 @@ nv30_blit(struct pipe_context *pipe,
void
nv30_flush_resource(struct pipe_context *pipe,
struct pipe_resource *resource)
{
}
static void *
nv30_miptree_transfer_map(struct pipe_context *pipe, struct pipe_resource *pt,
unsigned level, unsigned usage,
const struct pipe_box *box,
+ unsigned user_stride,
struct pipe_transfer **ptransfer)
{
struct nv30_context *nv30 = nv30_context(pipe);
struct nouveau_device *dev = nv30->screen->base.device;
struct nv30_transfer *tx;
unsigned access = 0;
int ret;
tx = CALLOC_STRUCT(nv30_transfer);
if (!tx)
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_transfer.c b/src/gallium/drivers/nouveau/nv50/nv50_transfer.c
index 8209f1f1e82..debc01e8fba 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_transfer.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_transfer.c
@@ -240,20 +240,21 @@ nv50_m2mf_copy_linear(struct nouveau_context *nv,
nouveau_bufctx_reset(bctx, 0);
}
void *
nv50_miptree_transfer_map(struct pipe_context *pctx,
struct pipe_resource *res,
unsigned level,
unsigned usage,
const struct pipe_box *box,
+ unsigned user_stride,
struct pipe_transfer **ptransfer)
{
struct nv50_screen *screen = nv50_screen(pctx->screen);
struct nv50_context *nv50 = nv50_context(pctx);
struct nouveau_device *dev = nv50->screen->base.device;
const struct nv50_miptree *mt = nv50_miptree(res);
struct nv50_transfer *tx;
uint32_t size;
int ret;
unsigned flags = 0;
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_transfer.c b/src/gallium/drivers/nouveau/nvc0/nvc0_transfer.c
index 225b8947171..69a031a46f0 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_transfer.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_transfer.c
@@ -365,20 +365,21 @@ nvc0_mt_sync(struct nvc0_context *nvc0, struct nv50_miptree *mt, unsigned usage)
return !mt->base.fence || nouveau_fence_wait(mt->base.fence, &nvc0->base.debug);
return !mt->base.fence_wr || nouveau_fence_wait(mt->base.fence_wr, &nvc0->base.debug);
}
void *
nvc0_miptree_transfer_map(struct pipe_context *pctx,
struct pipe_resource *res,
unsigned level,
unsigned usage,
const struct pipe_box *box,
+ unsigned user_stride,
struct pipe_transfer **ptransfer)
{
struct nvc0_context *nvc0 = nvc0_context(pctx);
struct nouveau_device *dev = nvc0->screen->base.device;
struct nv50_miptree *mt = nv50_miptree(res);
struct nvc0_transfer *tx;
uint32_t size;
int ret;
unsigned flags = 0;
diff --git a/src/gallium/drivers/r300/r300_screen_buffer.c b/src/gallium/drivers/r300/r300_screen_buffer.c
index 4af1c46856e..5b761fdd5b9 100644
--- a/src/gallium/drivers/r300/r300_screen_buffer.c
+++ b/src/gallium/drivers/r300/r300_screen_buffer.c
@@ -62,20 +62,21 @@ static void r300_buffer_destroy(struct pipe_screen *screen,
FREE(rbuf);
}
static void *
r300_buffer_transfer_map( struct pipe_context *context,
struct pipe_resource *resource,
unsigned level,
unsigned usage,
const struct pipe_box *box,
+ unsigned user_stride,
struct pipe_transfer **ptransfer )
{
struct r300_context *r300 = r300_context(context);
struct radeon_winsys *rws = r300->screen->rws;
struct r300_resource *rbuf = r300_resource(resource);
struct pipe_transfer *transfer;
uint8_t *map;
transfer = slab_alloc(&r300->pool_transfers);
transfer->resource = resource;
diff --git a/src/gallium/drivers/r300/r300_transfer.c b/src/gallium/drivers/r300/r300_transfer.c
index 9d00f4d9373..35361b5b7b4 100644
--- a/src/gallium/drivers/r300/r300_transfer.c
+++ b/src/gallium/drivers/r300/r300_transfer.c
@@ -98,20 +98,21 @@ static void r300_copy_into_tiled_texture(struct pipe_context *ctx,
/* XXX remove this. */
r300_flush(ctx, 0, NULL);
}
void *
r300_texture_transfer_map(struct pipe_context *ctx,
struct pipe_resource *texture,
unsigned level,
unsigned usage,
const struct pipe_box *box,
+ unsigned user_stride,
struct pipe_transfer **transfer)
{
struct r300_context *r300 = r300_context(ctx);
struct r300_resource *tex = r300_resource(texture);
struct r300_transfer *trans;
boolean referenced_cs, referenced_hw;
enum pipe_format format = tex->b.b.format;
char *map;
referenced_cs =
diff --git a/src/gallium/drivers/r300/r300_transfer.h b/src/gallium/drivers/r300/r300_transfer.h
index 45477ae6d0d..54cc5aa7042 100644
--- a/src/gallium/drivers/r300/r300_transfer.h
+++ b/src/gallium/drivers/r300/r300_transfer.h
@@ -27,18 +27,19 @@
#include "pipe/p_context.h"
struct r300_context;
void *
r300_texture_transfer_map(struct pipe_context *ctx,
struct pipe_resource *texture,
unsigned level,
unsigned usage,
const struct pipe_box *box,
+ unsigned user_stride,
struct pipe_transfer **transfer);
void
r300_texture_transfer_unmap(struct pipe_context *ctx,
struct pipe_transfer *transfer);
#endif
diff --git a/src/gallium/drivers/r600/evergreen_compute.c b/src/gallium/drivers/r600/evergreen_compute.c
index 866837dfa6e..0338f25b881 100644
--- a/src/gallium/drivers/r600/evergreen_compute.c
+++ b/src/gallium/drivers/r600/evergreen_compute.c
@@ -1189,20 +1189,21 @@ void evergreen_init_compute_state_functions(struct r600_context *rctx)
rctx->b.b.set_global_binding = evergreen_set_global_binding;
rctx->b.b.launch_grid = evergreen_launch_grid;
}
static void *r600_compute_global_transfer_map(struct pipe_context *ctx,
struct pipe_resource *resource,
unsigned level,
unsigned usage,
const struct pipe_box *box,
+ unsigned user_stride,
struct pipe_transfer **ptransfer)
{
struct r600_context *rctx = (struct r600_context*)ctx;
struct compute_memory_pool *pool = rctx->screen->global_pool;
struct r600_resource_global* buffer =
(struct r600_resource_global*)resource;
struct compute_memory_item *item = buffer->chunk;
struct pipe_resource *dst = NULL;
unsigned offset = box->x;
diff --git a/src/gallium/drivers/r600/r600_buffer_common.c b/src/gallium/drivers/r600/r600_buffer_common.c
index 17a8c3a596f..b460bdb05f1 100644
--- a/src/gallium/drivers/r600/r600_buffer_common.c
+++ b/src/gallium/drivers/r600/r600_buffer_common.c
@@ -339,20 +339,21 @@ static bool r600_can_dma_copy_buffer(struct r600_common_context *rctx,
(dword_aligned && (rctx->dma.cs ||
rctx->screen->has_streamout));
}
static void *r600_buffer_transfer_map(struct pipe_context *ctx,
struct pipe_resource *resource,
unsigned level,
unsigned usage,
const struct pipe_box *box,
+ unsigned user_stride,
struct pipe_transfer **ptransfer)
{
struct r600_common_context *rctx = (struct r600_common_context*)ctx;
struct r600_common_screen *rscreen = (struct r600_common_screen*)ctx->screen;
struct r600_resource *rbuffer = r600_resource(resource);
uint8_t *data;
assert(box->x + box->width <= resource->width0);
/* From GL_AMD_pinned_memory issues:
@@ -545,21 +546,21 @@ void r600_buffer_subdata(struct pipe_context *ctx,
{
struct pipe_transfer *transfer = NULL;
struct pipe_box box;
uint8_t *map = NULL;
u_box_1d(offset, size, &box);
map = r600_buffer_transfer_map(ctx, buffer, 0,
PIPE_TRANSFER_WRITE |
PIPE_TRANSFER_DISCARD_RANGE |
usage,
- &box, &transfer);
+ &box, 0, &transfer);
if (!map)
return;
memcpy(map, data, size);
r600_buffer_transfer_unmap(ctx, transfer);
}
static const struct u_resource_vtbl r600_buffer_vtbl =
{
NULL, /* get_handle */
diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c
index c39c00c2e3e..b889e27b5dd 100644
--- a/src/gallium/drivers/r600/r600_texture.c
+++ b/src/gallium/drivers/r600/r600_texture.c
@@ -1268,20 +1268,21 @@ static void r600_texture_invalidate_storage(struct r600_common_context *rctx,
p_atomic_inc(&rscreen->dirty_tex_counter);
rctx->num_alloc_tex_transfer_bytes += rtex->size;
}
static void *r600_texture_transfer_map(struct pipe_context *ctx,
struct pipe_resource *texture,
unsigned level,
unsigned usage,
const struct pipe_box *box,
+ unsigned user_stride,
struct pipe_transfer **ptransfer)
{
struct r600_common_context *rctx = (struct r600_common_context*)ctx;
struct r600_texture *rtex = (struct r600_texture*)texture;
struct r600_transfer *trans;
struct r600_resource *buf;
unsigned offset = 0;
char *map;
bool use_staging_texture = false;
diff --git a/src/gallium/drivers/radeonsi/si_buffer.c b/src/gallium/drivers/radeonsi/si_buffer.c
index d17b2c6a831..2cfc3c7ca4e 100644
--- a/src/gallium/drivers/radeonsi/si_buffer.c
+++ b/src/gallium/drivers/radeonsi/si_buffer.c
@@ -358,20 +358,21 @@ static void *si_buffer_get_transfer(struct pipe_context *ctx,
transfer->staging = staging;
*ptransfer = &transfer->b.b;
return data;
}
static void *si_buffer_transfer_map(struct pipe_context *ctx,
struct pipe_resource *resource,
unsigned level,
unsigned usage,
const struct pipe_box *box,
+ unsigned user_stride,
struct pipe_transfer **ptransfer)
{
struct si_context *sctx = (struct si_context*)ctx;
struct r600_resource *rbuffer = r600_resource(resource);
uint8_t *data;
assert(box->x + box->width <= resource->width0);
/* From GL_AMD_pinned_memory issues:
*
@@ -578,21 +579,21 @@ static void si_buffer_subdata(struct pipe_context *ctx,
{
struct pipe_transfer *transfer = NULL;
struct pipe_box box;
uint8_t *map = NULL;
u_box_1d(offset, size, &box);
map = si_buffer_transfer_map(ctx, buffer, 0,
PIPE_TRANSFER_WRITE |
PIPE_TRANSFER_DISCARD_RANGE |
usage,
- &box, &transfer);
+ &box, 0, &transfer);
if (!map)
return;
memcpy(map, data, size);
si_buffer_transfer_unmap(ctx, transfer);
}
static const struct u_resource_vtbl si_buffer_vtbl =
{
NULL, /* get_handle */
diff --git a/src/gallium/drivers/radeonsi/si_texture.c b/src/gallium/drivers/radeonsi/si_texture.c
index 0a2939bdd16..43f1560ec3e 100644
--- a/src/gallium/drivers/radeonsi/si_texture.c
+++ b/src/gallium/drivers/radeonsi/si_texture.c
@@ -1644,20 +1644,21 @@ static void si_texture_invalidate_storage(struct si_context *sctx,
p_atomic_inc(&sscreen->dirty_tex_counter);
sctx->num_alloc_tex_transfer_bytes += rtex->size;
}
static void *si_texture_transfer_map(struct pipe_context *ctx,
struct pipe_resource *texture,
unsigned level,
unsigned usage,
const struct pipe_box *box,
+ unsigned user_stride,
struct pipe_transfer **ptransfer)
{
struct si_context *sctx = (struct si_context*)ctx;
struct r600_texture *rtex = (struct r600_texture*)texture;
struct r600_transfer *trans;
struct r600_resource *buf;
unsigned offset = 0;
char *map;
bool use_staging_texture = false;
diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c
index c49bfcaba55..8ab85dff8d8 100644
--- a/src/gallium/drivers/softpipe/sp_texture.c
+++ b/src/gallium/drivers/softpipe/sp_texture.c
@@ -350,20 +350,21 @@ softpipe_surface_destroy(struct pipe_context *pipe,
* \param level which mipmap level
* \param usage bitmask of PIPE_TRANSFER_x flags
* \param box the 1D/2D/3D region of interest
*/
static void *
softpipe_transfer_map(struct pipe_context *pipe,
struct pipe_resource *resource,
unsigned level,
unsigned usage,
const struct pipe_box *box,
+ unsigned user_stride,
struct pipe_transfer **transfer)
{
struct sw_winsys *winsys = softpipe_screen(pipe->screen)->winsys;
struct softpipe_resource *spr = softpipe_resource(resource);
struct softpipe_transfer *spt;
struct pipe_transfer *pt;
enum pipe_format format = resource->format;
uint8_t *map;
assert(resource);
diff --git a/src/gallium/drivers/svga/svga_resource_buffer.c b/src/gallium/drivers/svga/svga_resource_buffer.c
index e9d31de6166..dc706cccced 100644
--- a/src/gallium/drivers/svga/svga_resource_buffer.c
+++ b/src/gallium/drivers/svga/svga_resource_buffer.c
@@ -63,20 +63,21 @@ svga_buffer_needs_hw_storage(unsigned usage)
* processing. This means we need to exercise extra care here to ensure that
* the end result is exactly the same as if one DMA was used for every mapped
* range.
*/
static void *
svga_buffer_transfer_map(struct pipe_context *pipe,
struct pipe_resource *resource,
unsigned level,
unsigned usage,
const struct pipe_box *box,
+ unsigned user_stride,
struct pipe_transfer **ptransfer)
{
struct svga_context *svga = svga_context(pipe);
struct svga_screen *ss = svga_screen(pipe->screen);
struct svga_buffer *sbuf = svga_buffer(resource);
struct pipe_transfer *transfer;
uint8_t *map = NULL;
int64_t begin = svga_get_time(svga);
SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_BUFFERTRANSFERMAP);
diff --git a/src/gallium/drivers/svga/svga_resource_texture.c b/src/gallium/drivers/svga/svga_resource_texture.c
index 71b8ebe7d42..5a0141316b1 100644
--- a/src/gallium/drivers/svga/svga_resource_texture.c
+++ b/src/gallium/drivers/svga/svga_resource_texture.c
@@ -533,20 +533,21 @@ svga_texture_transfer_map_direct(struct svga_context *svga,
/**
* Request a transfer map to the texture resource
*/
static void *
svga_texture_transfer_map(struct pipe_context *pipe,
struct pipe_resource *texture,
unsigned level,
unsigned usage,
const struct pipe_box *box,
+ unsigned user_stride,
struct pipe_transfer **ptransfer)
{
struct svga_context *svga = svga_context(pipe);
struct svga_winsys_screen *sws = svga_screen(pipe->screen)->sws;
struct svga_texture *tex = svga_texture(texture);
struct svga_transfer *st;
struct svga_winsys_surface *surf = tex->handle;
boolean use_direct_map = svga_have_gb_objects(svga) &&
!svga_have_gb_dma(svga);
void *map = NULL;
diff --git a/src/gallium/drivers/vc4/vc4_resource.c b/src/gallium/drivers/vc4/vc4_resource.c
index a86bd814d20..12f0c433972 100644
--- a/src/gallium/drivers/vc4/vc4_resource.c
+++ b/src/gallium/drivers/vc4/vc4_resource.c
@@ -140,20 +140,21 @@ vc4_get_temp_resource(struct pipe_context *pctx,
temp_setup.array_size = 1;
return pctx->screen->resource_create(pctx->screen, &temp_setup);
}
static void *
vc4_resource_transfer_map(struct pipe_context *pctx,
struct pipe_resource *prsc,
unsigned level, unsigned usage,
const struct pipe_box *box,
+ unsigned user_stride,
struct pipe_transfer **pptrans)
{
struct vc4_context *vc4 = vc4_context(pctx);
struct vc4_resource *rsc = vc4_resource(prsc);
struct vc4_transfer *trans;
struct pipe_transfer *ptrans;
enum pipe_format format = prsc->format;
char *buf;
/* Upgrade DISCARD_RANGE to WHOLE_RESOURCE if the whole resource is
diff --git a/src/gallium/drivers/virgl/virgl_buffer.c b/src/gallium/drivers/virgl/virgl_buffer.c
index 2e63aebc72c..d6af398b101 100644
--- a/src/gallium/drivers/virgl/virgl_buffer.c
+++ b/src/gallium/drivers/virgl/virgl_buffer.c
@@ -36,20 +36,21 @@ static void virgl_buffer_destroy(struct pipe_screen *screen,
util_range_destroy(&vbuf->valid_buffer_range);
vs->vws->resource_unref(vs->vws, vbuf->base.hw_res);
FREE(vbuf);
}
static void *virgl_buffer_transfer_map(struct pipe_context *ctx,
struct pipe_resource *resource,
unsigned level,
unsigned usage,
const struct pipe_box *box,
+ unsigned user_stride,
struct pipe_transfer **transfer)
{
struct virgl_context *vctx = virgl_context(ctx);
struct virgl_screen *vs = virgl_screen(ctx->screen);
struct virgl_buffer *vbuf = virgl_buffer(resource);
struct virgl_transfer *trans;
void *ptr;
bool readback;
uint32_t offset;
bool doflushwait = false;
diff --git a/src/gallium/drivers/virgl/virgl_texture.c b/src/gallium/drivers/virgl/virgl_texture.c
index 150a5ebd8c7..903418f97a6 100644
--- a/src/gallium/drivers/virgl/virgl_texture.c
+++ b/src/gallium/drivers/virgl/virgl_texture.c
@@ -117,20 +117,21 @@ vrend_get_tex_image_offset(const struct virgl_texture *res,
}
return offset;
}
static void *virgl_texture_transfer_map(struct pipe_context *ctx,
struct pipe_resource *resource,
unsigned level,
unsigned usage,
const struct pipe_box *box,
+ unsigned user_stride,
struct pipe_transfer **transfer)
{
struct virgl_context *vctx = virgl_context(ctx);
struct virgl_screen *vs = virgl_screen(ctx->screen);
struct virgl_texture *vtex = virgl_texture(resource);
enum pipe_format format = resource->format;
struct virgl_transfer *trans;
void *ptr;
boolean readback = TRUE;
uint32_t offset;
diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h
index c3dc5edf57d..6d99479e4b7 100644
--- a/src/gallium/include/pipe/p_context.h
+++ b/src/gallium/include/pipe/p_context.h
@@ -566,26 +566,33 @@ struct pipe_context {
/**
* Map a resource.
*
* Transfers are (by default) context-private and allow uploads to be
* interleaved with rendering.
*
* out_transfer will contain the transfer object that must be passed
* to all the other transfer functions. It also contains useful
* information (like texture strides).
+ *
+ * If \p user_stride is non-zero, the driver should attempt to provide
+ * a transfer with stride == user_stride. However, the resulting stride
+ * may be different, e.g. if user_stride is not sufficiently aligned.
+ * The map may also fail if user_stride is insufficiently aligned or too
+ * large, and the behavior is undefined if user_stride is too small.
*/
void *(*transfer_map)(struct pipe_context *,
struct pipe_resource *resource,
unsigned level,
unsigned usage, /* a combination of PIPE_TRANSFER_x */
const struct pipe_box *,
+ unsigned user_stride,
struct pipe_transfer **out_transfer);
/* If transfer was created with WRITE|FLUSH_EXPLICIT, only the
* regions specified with this call are guaranteed to be written to
* the resource.
*/
void (*transfer_flush_region)( struct pipe_context *,
struct pipe_transfer *transfer,
const struct pipe_box *);
--
2.17.0
More information about the mesa-dev
mailing list