d3d12: Don't wait for GPU reads to do CPU reads
Reviewed By: Bill Kristiansen <billkris@microsoft.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13669>
This commit is contained in:
@@ -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
|
||||
|
@@ -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,
|
||||
|
@@ -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;
|
||||
|
@@ -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) {
|
||||
|
@@ -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);
|
||||
|
@@ -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++;
|
||||
|
@@ -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)
|
||||
|
@@ -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,
|
||||
|
Reference in New Issue
Block a user