diff --git a/src/gallium/drivers/d3d12/d3d12_cmd_signature.cpp b/src/gallium/drivers/d3d12/d3d12_cmd_signature.cpp new file mode 100644 index 00000000000..e5436b3c573 --- /dev/null +++ b/src/gallium/drivers/d3d12/d3d12_cmd_signature.cpp @@ -0,0 +1,111 @@ +/* + * Copyright © Microsoft Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "d3d12_cmd_signature.h" +#include "d3d12_compiler.h" +#include "d3d12_screen.h" + +#include "util/u_memory.h" + +struct d3d12_cmd_signature { + struct d3d12_cmd_signature_key key; + ID3D12CommandSignature *sig; +}; + +static ID3D12CommandSignature * +create_cmd_signature(struct d3d12_context *ctx, const struct d3d12_cmd_signature_key *key) +{ + D3D12_COMMAND_SIGNATURE_DESC cmd_sig_desc = {}; + D3D12_INDIRECT_ARGUMENT_DESC indirect_arg = {}; + indirect_arg.Type = key->compute ? D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH : + key->indexed ? D3D12_INDIRECT_ARGUMENT_TYPE_DRAW_INDEXED : + D3D12_INDIRECT_ARGUMENT_TYPE_DRAW; + cmd_sig_desc.ByteStride = key->multi_draw_stride; + cmd_sig_desc.NumArgumentDescs = 1; + cmd_sig_desc.pArgumentDescs = &indirect_arg; + + ID3D12CommandSignature *ret = nullptr; + d3d12_screen(ctx->base.screen)->dev->CreateCommandSignature(&cmd_sig_desc, nullptr, + IID_PPV_ARGS(&ret)); + return ret; +} + +ID3D12CommandSignature * +d3d12_get_gfx_cmd_signature(struct d3d12_context *ctx, + const struct d3d12_cmd_signature_key *key) +{ + struct hash_entry *entry = _mesa_hash_table_search(ctx->cmd_signature_cache, &key); + + if (!entry) { + struct d3d12_cmd_signature *data = + (struct d3d12_cmd_signature *)MALLOC(sizeof(struct d3d12_cmd_signature)); + if (!data) + return NULL; + + memcpy(&data->key, key, sizeof(*key)); + data->sig = create_cmd_signature(ctx, key); + if (!data->sig) { + FREE(data); + return NULL; + } + + entry = _mesa_hash_table_insert(ctx->cmd_signature_cache, &data->key, data); + assert(entry); + } + + return ((struct d3d12_cmd_signature *)entry->data)->sig; +} + +static uint32_t +hash_cmd_signature_key(const void *key) +{ + return _mesa_hash_data(key, sizeof(struct d3d12_cmd_signature_key)); +} + +static bool +equals_cmd_signature_key(const void *a, const void *b) +{ + return memcmp(a, b, sizeof(struct d3d12_cmd_signature_key)) == 0; +} + +void +d3d12_cmd_signature_cache_init(struct d3d12_context *ctx) +{ + ctx->cmd_signature_cache = _mesa_hash_table_create(NULL, + hash_cmd_signature_key, + equals_cmd_signature_key); +} + +static void +delete_entry(struct hash_entry *entry) +{ + struct d3d12_cmd_signature *data = (struct d3d12_cmd_signature *)entry->data; + data->sig->Release(); + FREE(data); +} + +void +d3d12_cmd_signature_cache_destroy(struct d3d12_context *ctx) +{ + _mesa_hash_table_destroy(ctx->cmd_signature_cache, delete_entry); +} diff --git a/src/gallium/drivers/d3d12/d3d12_cmd_signature.h b/src/gallium/drivers/d3d12/d3d12_cmd_signature.h new file mode 100644 index 00000000000..f62d22361ec --- /dev/null +++ b/src/gallium/drivers/d3d12/d3d12_cmd_signature.h @@ -0,0 +1,47 @@ +/* + * Copyright © Microsoft Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef D3D12_CMD_SIGNATURE_H +#define D3D12_CMD_SIGNATURE_H + +#include "d3d12_context.h" + +struct d3d12_cmd_signature_key { + uint8_t compute:1; + uint8_t indexed:1; + /* 30 bits padding */ + + unsigned multi_draw_stride; +}; + +void +d3d12_cmd_signature_cache_init(struct d3d12_context *ctx); + +void +d3d12_cmd_signature_cache_destroy(struct d3d12_context *ctx); + +ID3D12CommandSignature * +d3d12_get_gfx_cmd_signature(struct d3d12_context *ctx, + const struct d3d12_cmd_signature_key *key); + +#endif diff --git a/src/gallium/drivers/d3d12/d3d12_context.cpp b/src/gallium/drivers/d3d12/d3d12_context.cpp index c2689168462..1bd8e631a76 100644 --- a/src/gallium/drivers/d3d12/d3d12_context.cpp +++ b/src/gallium/drivers/d3d12/d3d12_context.cpp @@ -22,6 +22,7 @@ */ #include "d3d12_blit.h" +#include "d3d12_cmd_signature.h" #include "d3d12_context.h" #include "d3d12_compiler.h" #include "d3d12_debug.h" @@ -79,6 +80,7 @@ d3d12_context_destroy(struct pipe_context *pctx) d3d12_gfx_pipeline_state_cache_destroy(ctx); d3d12_compute_pipeline_state_cache_destroy(ctx); d3d12_root_signature_cache_destroy(ctx); + d3d12_cmd_signature_cache_destroy(ctx); u_suballocator_destroy(&ctx->query_allocator); @@ -2261,6 +2263,7 @@ d3d12_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags) d3d12_gfx_pipeline_state_cache_init(ctx); d3d12_compute_pipeline_state_cache_init(ctx); d3d12_root_signature_cache_init(ctx); + d3d12_cmd_signature_cache_init(ctx); d3d12_gs_variant_cache_init(ctx); util_dl_library *d3d12_mod = util_dl_open(UTIL_DL_PREFIX "d3d12" UTIL_DL_EXT); diff --git a/src/gallium/drivers/d3d12/d3d12_context.h b/src/gallium/drivers/d3d12/d3d12_context.h index 10e826f88fb..c6f4d359fa1 100644 --- a/src/gallium/drivers/d3d12/d3d12_context.h +++ b/src/gallium/drivers/d3d12/d3d12_context.h @@ -171,6 +171,7 @@ struct d3d12_context { struct hash_table *pso_cache; struct hash_table *compute_pso_cache; struct hash_table *root_signature_cache; + struct hash_table *cmd_signature_cache; struct hash_table *gs_variant_cache; struct d3d12_batch batches[4]; diff --git a/src/gallium/drivers/d3d12/meson.build b/src/gallium/drivers/d3d12/meson.build index 2dc44a082cd..1beeb28d48c 100644 --- a/src/gallium/drivers/d3d12/meson.build +++ b/src/gallium/drivers/d3d12/meson.build @@ -23,6 +23,7 @@ files_libd3d12 = files( 'd3d12_batch.cpp', 'd3d12_blit.cpp', 'd3d12_bufmgr.cpp', + 'd3d12_cmd_signature.cpp', 'd3d12_compiler.cpp', 'd3d12_context.cpp', 'd3d12_descriptor_pool.cpp',