d3d12: When mapping a non-directly-mappable resource for write, readback first
authorJesse Natalie <jenatali@microsoft.com>
Mon, 17 Jan 2022 18:29:45 +0000 (10:29 -0800)
committerMarge Bot <emma+marge@anholt.net>
Fri, 21 Jan 2022 23:08:26 +0000 (23:08 +0000)
For non-discard writes, we need to make sure that the resource has valid contents
so they can be *updated*, not overwritten.

We have to skip this when doing asynchronous maps, but that should be okay, because
the threading context should only do asynchronous map-write when the resource is
known to be idle/empty.

Reviewed-by: Sil Vilerino <sivileri@microsoft.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14624>

src/gallium/drivers/d3d12/d3d12_resource.cpp

index 9c646e4..b067d11 100644 (file)
@@ -1308,8 +1308,8 @@ d3d12_transfer_map(struct pipe_context *pctx,
          range.Begin = aligned_x;
       }
 
-      pipe_resource_usage staging_usage = (usage & (PIPE_MAP_READ | PIPE_MAP_READ_WRITE)) ?
-         PIPE_USAGE_STAGING : PIPE_USAGE_STREAM;
+      pipe_resource_usage staging_usage = (usage & (PIPE_MAP_DISCARD_RANGE | PIPE_MAP_DISCARD_WHOLE_RESOURCE)) ?
+         PIPE_USAGE_STREAM : PIPE_USAGE_STAGING;
 
       trans->staging_res = pipe_buffer_create(pctx->screen, 0,
                                               staging_usage,
@@ -1319,7 +1319,7 @@ d3d12_transfer_map(struct pipe_context *pctx,
 
       struct d3d12_resource *staging_res = d3d12_resource(trans->staging_res);
 
-      if (usage & PIPE_MAP_READ) {
+      if ((usage & (PIPE_MAP_DISCARD_RANGE | PIPE_MAP_DISCARD_WHOLE_RESOURCE | TC_TRANSFER_MAP_THREADED_UNSYNC)) == 0) {
          bool ret = true;
          if (pres->target == PIPE_BUFFER) {
             uint64_t src_offset = box->x;