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