d3d12: Add a command signature cache for indirect draws
authorJesse Natalie <jenatali@microsoft.com>
Sat, 8 Jan 2022 01:06:41 +0000 (17:06 -0800)
committerMarge Bot <emma+marge@anholt.net>
Fri, 14 Jan 2022 15:54:33 +0000 (15:54 +0000)
Reviewed-by: Sil Vilerino <sivileri@microsoft.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14486>

src/gallium/drivers/d3d12/d3d12_cmd_signature.cpp [new file with mode: 0644]
src/gallium/drivers/d3d12/d3d12_cmd_signature.h [new file with mode: 0644]
src/gallium/drivers/d3d12/d3d12_context.cpp
src/gallium/drivers/d3d12/d3d12_context.h
src/gallium/drivers/d3d12/meson.build

diff --git a/src/gallium/drivers/d3d12/d3d12_cmd_signature.cpp b/src/gallium/drivers/d3d12/d3d12_cmd_signature.cpp
new file mode 100644 (file)
index 0000000..e5436b3
--- /dev/null
@@ -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 (file)
index 0000000..f62d223
--- /dev/null
@@ -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
index c268916..1bd8e63 100644 (file)
@@ -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);
index 10e826f..c6f4d35 100644 (file)
@@ -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];
index 2dc44a0..1beeb28 100644 (file)
@@ -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',