Mesa (main): d3d12: Don't wait for GPU reads to do CPU reads

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Nov 9 18:44:52 UTC 2021


Module: Mesa
Branch: main
Commit: fde36d79920dee4c0ec399d44b4071d6b3f5b8c1
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=fde36d79920dee4c0ec399d44b4071d6b3f5b8c1

Author: Jesse Natalie <jenatali at microsoft.com>
Date:   Wed Nov  3 17:05:05 2021 -0700

d3d12: Don't wait for GPU reads to do CPU reads

Reviewed By: Bill Kristiansen <billkris at microsoft.com>

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13669>

---

 src/gallium/drivers/d3d12/d3d12_batch.cpp    | 38 +++++++++++++++++++---------
 src/gallium/drivers/d3d12/d3d12_batch.h      |  9 ++++---
 src/gallium/drivers/d3d12/d3d12_blit.cpp     | 12 ++++-----
 src/gallium/drivers/d3d12/d3d12_context.cpp  |  2 +-
 src/gallium/drivers/d3d12/d3d12_draw.cpp     | 10 ++++----
 src/gallium/drivers/d3d12/d3d12_query.cpp    |  2 +-
 src/gallium/drivers/d3d12/d3d12_resource.cpp | 26 ++++++++++---------
 src/gallium/drivers/d3d12/d3d12_resource.h   |  3 ++-
 8 files changed, 61 insertions(+), 41 deletions(-)

diff --git a/src/gallium/drivers/d3d12/d3d12_batch.cpp b/src/gallium/drivers/d3d12/d3d12_batch.cpp
index d9bd3187337..d45ba6e6b2d 100644
--- a/src/gallium/drivers/d3d12/d3d12_batch.cpp
+++ b/src/gallium/drivers/d3d12/d3d12_batch.cpp
@@ -40,8 +40,8 @@ d3d12_init_batch(struct d3d12_context *ctx, struct d3d12_batch *batch)
 {
    struct d3d12_screen *screen = d3d12_screen(ctx->base.screen);
 
-   batch->bos = _mesa_set_create(NULL, _mesa_hash_pointer,
-                                 _mesa_key_pointer_equal);
+   batch->bos = _mesa_hash_table_create(NULL, _mesa_hash_pointer,
+                                        _mesa_key_pointer_equal);
    batch->sampler_views = _mesa_set_create(NULL, _mesa_hash_pointer,
                                            _mesa_key_pointer_equal);
    batch->surfaces = _mesa_set_create(NULL, _mesa_hash_pointer,
@@ -79,7 +79,7 @@ d3d12_init_batch(struct d3d12_context *ctx, struct d3d12_batch *batch)
 }
 
 static void
-delete_bo(set_entry *entry)
+delete_bo(hash_entry *entry)
 {
    struct d3d12_bo *bo = (struct d3d12_bo *)entry->key;
    d3d12_bo_unreference(bo);
@@ -119,7 +119,7 @@ d3d12_reset_batch(struct d3d12_context *ctx, struct d3d12_batch *batch, uint64_t
       d3d12_fence_reference(&batch->fence, NULL);
    }
 
-   _mesa_set_clear(batch->bos, delete_bo);
+   _mesa_hash_table_clear(batch->bos, delete_bo);
    _mesa_set_clear(batch->sampler_views, delete_sampler_view);
    _mesa_set_clear(batch->surfaces, delete_surface);
    _mesa_set_clear(batch->objects, delete_object);
@@ -146,7 +146,7 @@ d3d12_destroy_batch(struct d3d12_context *ctx, struct d3d12_batch *batch)
    batch->cmdalloc->Release();
    d3d12_descriptor_heap_free(batch->sampler_heap);
    d3d12_descriptor_heap_free(batch->view_heap);
-   _mesa_set_destroy(batch->bos, NULL);
+   _mesa_hash_table_destroy(batch->bos, NULL);
    _mesa_set_destroy(batch->sampler_views, NULL);
    _mesa_set_destroy(batch->surfaces, NULL);
    _mesa_set_destroy(batch->objects, NULL);
@@ -207,21 +207,35 @@ d3d12_end_batch(struct d3d12_context *ctx, struct d3d12_batch *batch)
    batch->fence = d3d12_create_fence(screen, ctx);
 }
 
+enum batch_bo_reference_state
+{
+   batch_bo_reference_read = (1 << 0),
+   batch_bo_reference_written = (1 << 1),
+};
+
 bool
 d3d12_batch_has_references(struct d3d12_batch *batch,
-                           struct d3d12_bo *bo)
+                           struct d3d12_bo *bo,
+                           bool want_to_write)
 {
-   return (_mesa_set_search(batch->bos, bo) != NULL);
+   hash_entry *entry = _mesa_hash_table_search(batch->bos, bo);
+   if (entry == NULL)
+      return false;
+   bool resource_was_written = ((batch_bo_reference_state)(size_t)entry->data & batch_bo_reference_written) != 0;
+   return want_to_write || resource_was_written;
 }
 
 void
 d3d12_batch_reference_resource(struct d3d12_batch *batch,
-                               struct d3d12_resource *res)
+                               struct d3d12_resource *res,
+                               bool write)
 {
-   bool found = false;
-   _mesa_set_search_and_add(batch->bos, res->bo, &found);
-   if (!found)
+   hash_entry *entry = _mesa_hash_table_insert(batch->bos, res->bo, NULL);
+   if (entry->data == NULL)
       d3d12_bo_reference(res->bo);
+   size_t new_data = write ? batch_bo_reference_written : batch_bo_reference_read;
+   size_t old_data = (size_t)entry->data;
+   entry->data = (void*)(old_data | new_data);
 }
 
 void
@@ -239,7 +253,7 @@ void
 d3d12_batch_reference_surface_texture(struct d3d12_batch *batch,
                                       struct d3d12_surface *surf)
 {
-   d3d12_batch_reference_resource(batch, d3d12_resource(surf->base.texture));
+   d3d12_batch_reference_resource(batch, d3d12_resource(surf->base.texture), true);
 }
 
 void
diff --git a/src/gallium/drivers/d3d12/d3d12_batch.h b/src/gallium/drivers/d3d12/d3d12_batch.h
index 05039eb9be0..f49fe61179a 100644
--- a/src/gallium/drivers/d3d12/d3d12_batch.h
+++ b/src/gallium/drivers/d3d12/d3d12_batch.h
@@ -25,6 +25,7 @@
 #define D3D12_BATCH_H
 
 #include "util/u_dynarray.h"
+#include "util/hash_table.h"
 #include <stdint.h>
 
 #ifndef _WIN32
@@ -41,7 +42,7 @@ struct d3d12_fence;
 struct d3d12_batch {
    struct d3d12_fence *fence;
 
-   struct set *bos;
+   struct hash_table *bos;
    struct set *sampler_views;
    struct set *surfaces;
    struct set *objects;
@@ -71,11 +72,13 @@ d3d12_reset_batch(struct d3d12_context *ctx, struct d3d12_batch *batch, uint64_t
 
 bool
 d3d12_batch_has_references(struct d3d12_batch *batch,
-                           struct d3d12_bo *bo);
+                           struct d3d12_bo *bo,
+                           bool want_to_write);
 
 void
 d3d12_batch_reference_resource(struct d3d12_batch *batch,
-                               struct d3d12_resource *res);
+                               struct d3d12_resource *res,
+                               bool write);
 
 void
 d3d12_batch_reference_sampler_view(struct d3d12_batch *batch,
diff --git a/src/gallium/drivers/d3d12/d3d12_blit.cpp b/src/gallium/drivers/d3d12/d3d12_blit.cpp
index ad54e340b47..55a741a6bce 100644
--- a/src/gallium/drivers/d3d12/d3d12_blit.cpp
+++ b/src/gallium/drivers/d3d12/d3d12_blit.cpp
@@ -123,8 +123,8 @@ blit_resolve(struct d3d12_context *ctx, const struct pipe_blit_info *info)
 
    d3d12_apply_resource_states(ctx);
 
-   d3d12_batch_reference_resource(batch, src);
-   d3d12_batch_reference_resource(batch, dst);
+   d3d12_batch_reference_resource(batch, src, false);
+   d3d12_batch_reference_resource(batch, dst, true);
 
    DXGI_FORMAT dxgi_format = d3d12_get_resource_srv_format(src->base.b.format, src->base.b.target);
 
@@ -434,8 +434,8 @@ d3d12_direct_copy(struct d3d12_context *ctx,
 
    d3d12_apply_resource_states(ctx);
 
-   d3d12_batch_reference_resource(batch, src);
-   d3d12_batch_reference_resource(batch, dst);
+   d3d12_batch_reference_resource(batch, src, false);
+   d3d12_batch_reference_resource(batch, dst, true);
 
    if (src->base.b.target == PIPE_BUFFER) {
       copy_buffer_region_no_barriers(ctx, dst, pdst_box->x,
@@ -827,8 +827,8 @@ blit_resolve_stencil(struct d3d12_context *ctx,
    d3d12_apply_resource_states(ctx);
 
    struct d3d12_batch *batch = d3d12_current_batch(ctx);
-   d3d12_batch_reference_resource(batch, d3d12_resource(tmp));
-   d3d12_batch_reference_resource(batch, dst);
+   d3d12_batch_reference_resource(batch, d3d12_resource(tmp), false);
+   d3d12_batch_reference_resource(batch, dst, true);
 
    D3D12_BOX src_box;
    src_box.left = src_box.top = src_box.front = 0;
diff --git a/src/gallium/drivers/d3d12/d3d12_context.cpp b/src/gallium/drivers/d3d12/d3d12_context.cpp
index 53a0d4b6cf7..d09315a5093 100644
--- a/src/gallium/drivers/d3d12/d3d12_context.cpp
+++ b/src/gallium/drivers/d3d12/d3d12_context.cpp
@@ -1493,7 +1493,7 @@ d3d12_enable_fake_so_buffers(struct d3d12_context *ctx, unsigned factor)
       pipe_reference_init(&fake_target->base.reference, 1);
       fake_target->base.context = &ctx->base;
 
-      d3d12_resource_wait_idle(ctx, d3d12_resource(target->base.buffer));
+      d3d12_resource_wait_idle(ctx, d3d12_resource(target->base.buffer), false);
 
       /* Check if another target is using the same buffer */
       for (unsigned j = 0; j < i; ++j) {
diff --git a/src/gallium/drivers/d3d12/d3d12_draw.cpp b/src/gallium/drivers/d3d12/d3d12_draw.cpp
index a7512f55001..77372b79cc0 100644
--- a/src/gallium/drivers/d3d12/d3d12_draw.cpp
+++ b/src/gallium/drivers/d3d12/d3d12_draw.cpp
@@ -67,7 +67,7 @@ fill_cbv_descriptors(struct d3d12_context *ctx,
          cbv_desc.BufferLocation = d3d12_resource_gpu_virtual_address(res) + buffer->buffer_offset;
          cbv_desc.SizeInBytes = MIN2(D3D12_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * 16,
             align(buffer->buffer_size, 256));
-         d3d12_batch_reference_resource(batch, res);
+         d3d12_batch_reference_resource(batch, res, false);
       }
 
       struct d3d12_descriptor_handle handle;
@@ -654,7 +654,7 @@ d3d12_draw_vbo(struct pipe_context *pctx,
          struct d3d12_resource *res = d3d12_resource(ctx->vbs[i].buffer.resource);
          d3d12_transition_resource_state(ctx, res, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER, D3D12_BIND_INVALIDATE_NONE);
          if (ctx->cmdlist_dirty & D3D12_DIRTY_VERTEX_BUFFERS)
-            d3d12_batch_reference_resource(batch, res);
+            d3d12_batch_reference_resource(batch, res, false);
       }
    }
    if (ctx->cmdlist_dirty & D3D12_DIRTY_VERTEX_BUFFERS)
@@ -670,7 +670,7 @@ d3d12_draw_vbo(struct pipe_context *pctx,
       if (ctx->cmdlist_dirty & D3D12_DIRTY_INDEX_BUFFER ||
           memcmp(&ctx->ibv, &ibv, sizeof(D3D12_INDEX_BUFFER_VIEW)) != 0) {
          ctx->ibv = ibv;
-         d3d12_batch_reference_resource(batch, res);
+         d3d12_batch_reference_resource(batch, res, false);
          ctx->cmdlist->IASetIndexBuffer(&ibv);
       }
 
@@ -714,8 +714,8 @@ d3d12_draw_vbo(struct pipe_context *pctx,
       d3d12_resource_make_writeable(pctx, target->base.buffer);
 
       if (ctx->cmdlist_dirty & D3D12_DIRTY_STREAM_OUTPUT) {
-         d3d12_batch_reference_resource(batch, so_buffer);
-         d3d12_batch_reference_resource(batch, fill_buffer);
+         d3d12_batch_reference_resource(batch, so_buffer, true);
+         d3d12_batch_reference_resource(batch, fill_buffer, true);
       }
 
       d3d12_transition_resource_state(ctx, so_buffer, D3D12_RESOURCE_STATE_STREAM_OUT, D3D12_BIND_INVALIDATE_NONE);
diff --git a/src/gallium/drivers/d3d12/d3d12_query.cpp b/src/gallium/drivers/d3d12/d3d12_query.cpp
index 29d66bde8e5..5b279d8a36f 100644
--- a/src/gallium/drivers/d3d12/d3d12_query.cpp
+++ b/src/gallium/drivers/d3d12/d3d12_query.cpp
@@ -382,7 +382,7 @@ end_query(struct d3d12_context *ctx, struct d3d12_query *q)
                                   resolve_count, d3d12_res, offset);
 
    d3d12_batch_reference_object(batch, q->query_heap);
-   d3d12_batch_reference_resource(batch, res);
+   d3d12_batch_reference_resource(batch, res, true);
 
    assert(q->curr_query < q->num_queries);
    q->curr_query++;
diff --git a/src/gallium/drivers/d3d12/d3d12_resource.cpp b/src/gallium/drivers/d3d12/d3d12_resource.cpp
index 4246001e698..dc32a18602b 100644
--- a/src/gallium/drivers/d3d12/d3d12_resource.cpp
+++ b/src/gallium/drivers/d3d12/d3d12_resource.cpp
@@ -72,27 +72,29 @@ d3d12_resource_destroy(struct pipe_screen *pscreen,
 
 static bool
 resource_is_busy(struct d3d12_context *ctx,
-                 struct d3d12_resource *res)
+                 struct d3d12_resource *res,
+                 bool want_to_write)
 {
    bool busy = false;
 
    for (unsigned i = 0; i < ARRAY_SIZE(ctx->batches); i++)
-      busy |= d3d12_batch_has_references(&ctx->batches[i], res->bo);
+      busy |= d3d12_batch_has_references(&ctx->batches[i], res->bo, want_to_write);
 
    return busy;
 }
 
 void
 d3d12_resource_wait_idle(struct d3d12_context *ctx,
-                         struct d3d12_resource *res)
+                         struct d3d12_resource *res,
+                         bool want_to_write)
 {
-   if (d3d12_batch_has_references(d3d12_current_batch(ctx), res->bo)) {
+   if (d3d12_batch_has_references(d3d12_current_batch(ctx), res->bo, want_to_write)) {
       d3d12_flush_cmdlist_and_wait(ctx);
    } else {
       d3d12_foreach_submitted_batch(ctx, batch) {
-         if (d3d12_batch_has_references(batch, res->bo)) {
+         if (d3d12_batch_has_references(batch, res->bo, want_to_write)) {
             d3d12_reset_batch(ctx, batch, PIPE_TIMEOUT_INFINITE);
-            if (!resource_is_busy(ctx, res))
+            if (!resource_is_busy(ctx, res, want_to_write))
                break;
          }
       }
@@ -418,8 +420,8 @@ copy_texture_region(struct d3d12_context *ctx,
 {
    auto batch = d3d12_current_batch(ctx);
 
-   d3d12_batch_reference_resource(batch, info.src);
-   d3d12_batch_reference_resource(batch, info.dst);
+   d3d12_batch_reference_resource(batch, info.src, false);
+   d3d12_batch_reference_resource(batch, info.dst, true);
    d3d12_transition_resource_state(ctx, info.src, D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_BIND_INVALIDATE_FULL);
    d3d12_transition_resource_state(ctx, info.dst, D3D12_RESOURCE_STATE_COPY_DEST, D3D12_BIND_INVALIDATE_FULL);
    d3d12_apply_resource_states(ctx);
@@ -587,8 +589,8 @@ transfer_buf_to_buf(struct d3d12_context *ctx,
 {
    auto batch = d3d12_current_batch(ctx);
 
-   d3d12_batch_reference_resource(batch, src);
-   d3d12_batch_reference_resource(batch, dst);
+   d3d12_batch_reference_resource(batch, src, false);
+   d3d12_batch_reference_resource(batch, dst, true);
 
    uint64_t src_offset_suballoc = 0;
    uint64_t dst_offset_suballoc = 0;
@@ -645,11 +647,11 @@ synchronize(struct d3d12_context *ctx,
       usage |= PIPE_MAP_UNSYNCHRONIZED;
    }
 
-   if (!(usage & PIPE_MAP_UNSYNCHRONIZED) && resource_is_busy(ctx, res)) {
+   if (!(usage & PIPE_MAP_UNSYNCHRONIZED) && resource_is_busy(ctx, res, usage & PIPE_MAP_WRITE)) {
       if (usage & PIPE_MAP_DONTBLOCK)
          return false;
 
-      d3d12_resource_wait_idle(ctx, res);
+      d3d12_resource_wait_idle(ctx, res, usage & PIPE_MAP_WRITE);
    }
 
    if (usage & PIPE_MAP_WRITE)
diff --git a/src/gallium/drivers/d3d12/d3d12_resource.h b/src/gallium/drivers/d3d12/d3d12_resource.h
index a6df8be215d..57f5a0f08b0 100644
--- a/src/gallium/drivers/d3d12/d3d12_resource.h
+++ b/src/gallium/drivers/d3d12/d3d12_resource.h
@@ -112,7 +112,8 @@ d3d12_resource_release(struct d3d12_resource *res);
 
 void
 d3d12_resource_wait_idle(struct d3d12_context *ctx,
-                         struct d3d12_resource *res);
+                         struct d3d12_resource *res,
+                         bool want_to_write);
 
 void
 d3d12_resource_make_writeable(struct pipe_context *pctx,



More information about the mesa-commit mailing list