summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
authorAlexandros Frantzis <[email protected]>2019-07-05 14:22:16 +0300
committerChia-I Wu <[email protected]>2019-07-06 19:30:22 -0700
commitbb0a38d8197e1480dc5aedb3520741c840d01e91 (patch)
treee9feeffb9edca2396585b88470ce72a21291da1d /src/gallium
parent4633298fd62121a466884998cb64d7a5b5976fcd (diff)
virgl: Introduce virgl_resource_transfer_map
Normal mapping of buffers and textures uses almost identical logic. This commit extracts the this logic in the form of the virgl_resource_transfer_map() helper function. Signed-off-by: Alexandros Frantzis <[email protected]> Reviewed-by: Chia-I Wu <[email protected]>
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/drivers/virgl/virgl_resource.c84
-rw-r--r--src/gallium/drivers/virgl/virgl_resource.h8
2 files changed, 92 insertions, 0 deletions
diff --git a/src/gallium/drivers/virgl/virgl_resource.c b/src/gallium/drivers/virgl/virgl_resource.c
index c47a154f400..953ec9824c3 100644
--- a/src/gallium/drivers/virgl/virgl_resource.c
+++ b/src/gallium/drivers/virgl/virgl_resource.c
@@ -213,6 +213,90 @@ virgl_resource_transfer_prepare(struct virgl_context *vctx,
return map_type;
}
+void *
+virgl_resource_transfer_map(struct pipe_context *ctx,
+ struct pipe_resource *resource,
+ unsigned level,
+ unsigned usage,
+ const struct pipe_box *box,
+ struct pipe_transfer **transfer)
+{
+ struct virgl_context *vctx = virgl_context(ctx);
+ struct virgl_winsys *vws = virgl_screen(ctx->screen)->vws;
+ struct virgl_resource *vres = virgl_resource(resource);
+ struct virgl_transfer *trans;
+ enum virgl_transfer_map_type map_type;
+ void *map_addr;
+
+ /* Multisampled resources require resolve before mapping. */
+ assert(resource->nr_samples <= 1);
+
+ trans = virgl_resource_create_transfer(vctx, resource,
+ &vres->metadata, level, usage, box);
+
+ map_type = virgl_resource_transfer_prepare(vctx, trans);
+ switch (map_type) {
+ case VIRGL_TRANSFER_MAP_REALLOC:
+ if (!virgl_resource_realloc(vctx, vres)) {
+ map_addr = NULL;
+ break;
+ }
+ vws->resource_reference(vws, &trans->hw_res, vres->hw_res);
+ /* fall through */
+ case VIRGL_TRANSFER_MAP_HW_RES:
+ trans->hw_res_map = vws->resource_map(vws, vres->hw_res);
+ if (trans->hw_res_map)
+ map_addr = trans->hw_res_map + trans->offset;
+ else
+ map_addr = NULL;
+ break;
+ case VIRGL_TRANSFER_MAP_STAGING:
+ map_addr = virgl_staging_map(vctx, trans);
+ /* Copy transfers don't make use of hw_res_map at the moment. */
+ trans->hw_res_map = NULL;
+ break;
+ case VIRGL_TRANSFER_MAP_ERROR:
+ default:
+ trans->hw_res_map = NULL;
+ map_addr = NULL;
+ break;
+ }
+
+ if (!map_addr) {
+ virgl_resource_destroy_transfer(vctx, trans);
+ return NULL;
+ }
+
+ if (vres->u.b.target == PIPE_BUFFER) {
+ /* For the checks below to be able to use 'usage', we assume that
+ * transfer preparation doesn't affect the usage.
+ */
+ assert(usage == trans->base.usage);
+
+ /* If we are doing a whole resource discard with a hw_res map, the buffer
+ * storage can now be considered unused and we don't care about previous
+ * contents. We can thus mark the storage as uninitialized, but only if
+ * the buffer is not host writable (in which case we can't clear the
+ * valid range, since that would result in missed readbacks in future
+ * transfers). We only do this for VIRGL_TRANSFER_MAP_HW_RES, since for
+ * VIRGL_TRANSFER_MAP_REALLOC we already take care of the buffer range
+ * when reallocating and rebinding, and VIRGL_TRANSFER_MAP_STAGING is not
+ * currently used for whole resource discards.
+ */
+ if (map_type == VIRGL_TRANSFER_MAP_HW_RES &&
+ (usage & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE) &&
+ (vres->clean_mask & 1)) {
+ util_range_set_empty(&vres->valid_buffer_range);
+ }
+
+ if (usage & PIPE_TRANSFER_WRITE)
+ util_range_add(&vres->valid_buffer_range, box->x, box->x + box->width);
+ }
+
+ *transfer = &trans->base;
+ return map_addr;
+}
+
static struct pipe_resource *virgl_resource_create(struct pipe_screen *screen,
const struct pipe_resource *templ)
{
diff --git a/src/gallium/drivers/virgl/virgl_resource.h b/src/gallium/drivers/virgl/virgl_resource.h
index f41c1ce98b3..1e8eb4068b9 100644
--- a/src/gallium/drivers/virgl/virgl_resource.h
+++ b/src/gallium/drivers/virgl/virgl_resource.h
@@ -164,6 +164,14 @@ enum virgl_transfer_map_type
virgl_resource_transfer_prepare(struct virgl_context *vctx,
struct virgl_transfer *xfer);
+void *
+virgl_resource_transfer_map(struct pipe_context *ctx,
+ struct pipe_resource *resource,
+ unsigned level,
+ unsigned usage,
+ const struct pipe_box *box,
+ struct pipe_transfer **transfer);
+
void virgl_resource_layout(struct pipe_resource *pt,
struct virgl_resource_metadata *metadata);