[PATCH vkd3d 1/5] vkd3d-shader: Report descriptor usage information in vkd3d_shader_scan_dxbc().

Henri Verbeet hverbeet at codeweavers.com
Thu Jun 25 01:18:24 CDT 2020


Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
---
 include/vkd3d_shader.h                |  13 ++++
 libs/vkd3d-shader/vkd3d_shader.map    |   1 +
 libs/vkd3d-shader/vkd3d_shader_main.c | 130 +++++++++++++++++++++++++++++++---
 libs/vkd3d/state.c                    |   2 +
 4 files changed, 137 insertions(+), 9 deletions(-)

diff --git a/include/vkd3d_shader.h b/include/vkd3d_shader.h
index 358e90d..b2fa499 100644
--- a/include/vkd3d_shader.h
+++ b/include/vkd3d_shader.h
@@ -585,11 +585,22 @@ struct vkd3d_versioned_root_signature_desc
 /* FIXME: Add support for 64 UAV bind slots. */
 #define VKD3D_SHADER_MAX_UNORDERED_ACCESS_VIEWS 8
 
+struct vkd3d_shader_descriptor_info
+{
+    enum vkd3d_shader_descriptor_type type;
+    unsigned int register_space;
+    unsigned int register_index;
+    unsigned int count;
+};
+
 struct vkd3d_shader_scan_info
 {
     enum vkd3d_shader_structure_type type;
     void *next;
 
+    struct vkd3d_shader_descriptor_info *descriptors;
+    unsigned int descriptor_count;
+
     unsigned int uav_read_mask;    /* VKD3D_SHADER_MAX_UNORDERED_ACCESS_VIEWS */
     unsigned int uav_counter_mask; /* VKD3D_SHADER_MAX_UNORDERED_ACCESS_VIEWS */
     unsigned int sampler_comparison_mode_mask; /* 16 */
@@ -694,6 +705,7 @@ int vkd3d_shader_convert_root_signature(struct vkd3d_versioned_root_signature_de
 
 int vkd3d_shader_scan_dxbc(const struct vkd3d_shader_code *dxbc,
         struct vkd3d_shader_scan_info *scan_info);
+void vkd3d_shader_free_scan_info(struct vkd3d_shader_scan_info *scan_info);
 
 int vkd3d_shader_parse_input_signature(const struct vkd3d_shader_code *dxbc,
         struct vkd3d_shader_signature *signature);
@@ -723,6 +735,7 @@ typedef int (*PFN_vkd3d_shader_convert_root_signature)(struct vkd3d_versioned_ro
 
 typedef int (*PFN_vkd3d_shader_scan_dxbc)(const struct vkd3d_shader_code *dxbc,
         struct vkd3d_shader_scan_info *scan_info);
+typedef void (*PFN_vkd3d_shader_free_scan_info)(struct vkd3d_shader_scan_info *scan_info);
 
 typedef int (*PFN_vkd3d_shader_parse_input_signature)(const struct vkd3d_shader_code *dxbc,
         struct vkd3d_shader_signature *signature);
diff --git a/libs/vkd3d-shader/vkd3d_shader.map b/libs/vkd3d-shader/vkd3d_shader.map
index a8c73b6..13bebde 100644
--- a/libs/vkd3d-shader/vkd3d_shader.map
+++ b/libs/vkd3d-shader/vkd3d_shader.map
@@ -5,6 +5,7 @@ global:
     vkd3d_shader_convert_root_signature;
     vkd3d_shader_find_signature_element;
     vkd3d_shader_free_root_signature;
+    vkd3d_shader_free_scan_info;
     vkd3d_shader_free_shader_code;
     vkd3d_shader_free_shader_signature;
     vkd3d_shader_parse_input_signature;
diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c
index 3255094..45a7a80 100644
--- a/libs/vkd3d-shader/vkd3d_shader_main.c
+++ b/libs/vkd3d-shader/vkd3d_shader_main.c
@@ -187,9 +187,16 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info, s
 
     vkd3d_dxbc_compiler_destroy(spirv_compiler);
     vkd3d_shader_parser_destroy(&parser);
+    vkd3d_shader_free_scan_info(&scan_info);
     return ret;
 }
 
+struct vkd3d_shader_scan_context
+{
+    struct vkd3d_shader_scan_info *scan_info;
+    size_t descriptors_size;
+};
+
 static bool vkd3d_shader_instruction_is_uav_read(const struct vkd3d_shader_instruction *instruction)
 {
     enum VKD3D_SHADER_INSTRUCTION_HANDLER handler_idx = instruction->handler_idx;
@@ -221,6 +228,38 @@ static void vkd3d_shader_scan_record_uav_counter(struct vkd3d_shader_scan_info *
     scan_info->uav_counter_mask |= 1u << reg->idx[0].offset;
 }
 
+static bool vkd3d_shader_scan_add_descriptor(struct vkd3d_shader_scan_context *context,
+        enum vkd3d_shader_descriptor_type type, unsigned int register_space, unsigned int register_index)
+{
+    struct vkd3d_shader_scan_info *scan_info = context->scan_info;
+    struct vkd3d_shader_descriptor_info *d;
+
+    if (!vkd3d_array_reserve((void **)&scan_info->descriptors, &context->descriptors_size,
+            scan_info->descriptor_count + 1, sizeof(*scan_info->descriptors)))
+    {
+        ERR("Failed to allocate descriptor info.\n");
+        return false;
+    }
+
+    d = &scan_info->descriptors[scan_info->descriptor_count];
+    d->type = type;
+    d->register_space = register_space;
+    d->register_index = register_index;
+    d->count = 1;
+    ++scan_info->descriptor_count;
+
+    return true;
+}
+
+static void vkd3d_shader_scan_constant_buffer_declaration(struct vkd3d_shader_scan_context *context,
+        const struct vkd3d_shader_instruction *instruction)
+{
+    const struct vkd3d_shader_constant_buffer *cb = &instruction->declaration.cb;
+
+    vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV,
+            cb->register_space, cb->register_index);
+}
+
 static void vkd3d_shader_scan_input_declaration(struct vkd3d_shader_scan_info *scan_info,
         const struct vkd3d_shader_instruction *instruction)
 {
@@ -230,29 +269,89 @@ static void vkd3d_shader_scan_input_declaration(struct vkd3d_shader_scan_info *s
         scan_info->use_vocp = true;
 }
 
-static void vkd3d_shader_scan_sampler_declaration(struct vkd3d_shader_scan_info *scan_info,
+static void vkd3d_shader_scan_sampler_declaration(struct vkd3d_shader_scan_context *context,
         const struct vkd3d_shader_instruction *instruction)
 {
-    unsigned int sampler_index = instruction->declaration.dst.reg.idx[0].offset;
+    const struct vkd3d_shader_sampler *sampler = &instruction->declaration.sampler;
+    struct vkd3d_shader_scan_info *scan_info = context->scan_info;
+    unsigned int sampler_index = sampler->register_index;
+
     if (instruction->flags & VKD3DSI_SAMPLER_COMPARISON_MODE)
     {
         assert(sampler_index < CHAR_BIT * sizeof(scan_info->sampler_comparison_mode_mask));
         scan_info->sampler_comparison_mode_mask |= 1u << sampler_index;
     }
+
+    vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER,
+            sampler->register_space, sampler->register_index);
+}
+
+static void vkd3d_shader_scan_resource_declaration(struct vkd3d_shader_scan_context *context,
+        const struct vkd3d_shader_instruction *instruction)
+{
+    const struct vkd3d_shader_semantic *semantic = &instruction->declaration.semantic;
+    enum vkd3d_shader_descriptor_type type;
+
+    if (semantic->reg.reg.type == VKD3DSPR_UAV)
+        type = VKD3D_SHADER_DESCRIPTOR_TYPE_UAV;
+    else
+        type = VKD3D_SHADER_DESCRIPTOR_TYPE_SRV;
+    vkd3d_shader_scan_add_descriptor(context, type, semantic->register_space, semantic->register_index);
+}
+
+static void vkd3d_shader_scan_resource_declaration_raw(struct vkd3d_shader_scan_context *context,
+        const struct vkd3d_shader_instruction *instruction)
+{
+    const struct vkd3d_shader_raw_resource *resource = &instruction->declaration.raw_resource;
+    enum vkd3d_shader_descriptor_type type;
+
+    if (resource->dst.reg.type == VKD3DSPR_UAV)
+        type = VKD3D_SHADER_DESCRIPTOR_TYPE_UAV;
+    else
+        type = VKD3D_SHADER_DESCRIPTOR_TYPE_SRV;
+    vkd3d_shader_scan_add_descriptor(context, type, resource->register_space, resource->register_index);
 }
 
-static void vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_info *scan_info,
+static void vkd3d_shader_scan_resource_declaration_structured(struct vkd3d_shader_scan_context *context,
+        const struct vkd3d_shader_instruction *instruction)
+{
+    const struct vkd3d_shader_structured_resource *resource = &instruction->declaration.structured_resource;
+    enum vkd3d_shader_descriptor_type type;
+
+    if (resource->reg.reg.type == VKD3DSPR_UAV)
+        type = VKD3D_SHADER_DESCRIPTOR_TYPE_UAV;
+    else
+        type = VKD3D_SHADER_DESCRIPTOR_TYPE_SRV;
+    vkd3d_shader_scan_add_descriptor(context, type, resource->register_space, resource->register_index);
+}
+
+static void vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *context,
         const struct vkd3d_shader_instruction *instruction)
 {
     unsigned int i;
 
     switch (instruction->handler_idx)
     {
+        case VKD3DSIH_DCL_CONSTANT_BUFFER:
+            vkd3d_shader_scan_constant_buffer_declaration(context, instruction);
+            break;
         case VKD3DSIH_DCL_INPUT:
-            vkd3d_shader_scan_input_declaration(scan_info, instruction);
+            vkd3d_shader_scan_input_declaration(context->scan_info, instruction);
             break;
         case VKD3DSIH_DCL_SAMPLER:
-            vkd3d_shader_scan_sampler_declaration(scan_info, instruction);
+            vkd3d_shader_scan_sampler_declaration(context, instruction);
+            break;
+        case VKD3DSIH_DCL:
+        case VKD3DSIH_DCL_UAV_TYPED:
+            vkd3d_shader_scan_resource_declaration(context, instruction);
+            break;
+        case VKD3DSIH_DCL_RESOURCE_RAW:
+        case VKD3DSIH_DCL_UAV_RAW:
+            vkd3d_shader_scan_resource_declaration_raw(context, instruction);
+            break;
+        case VKD3DSIH_DCL_RESOURCE_STRUCTURED:
+        case VKD3DSIH_DCL_UAV_STRUCTURED:
+            vkd3d_shader_scan_resource_declaration_structured(context, instruction);
             break;
         default:
             break;
@@ -263,23 +362,24 @@ static void vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_info *scan_in
         for (i = 0; i < instruction->dst_count; ++i)
         {
             if (instruction->dst[i].reg.type == VKD3DSPR_UAV)
-                vkd3d_shader_scan_record_uav_read(scan_info, &instruction->dst[i].reg);
+                vkd3d_shader_scan_record_uav_read(context->scan_info, &instruction->dst[i].reg);
         }
         for (i = 0; i < instruction->src_count; ++i)
         {
             if (instruction->src[i].reg.type == VKD3DSPR_UAV)
-                vkd3d_shader_scan_record_uav_read(scan_info, &instruction->src[i].reg);
+                vkd3d_shader_scan_record_uav_read(context->scan_info, &instruction->src[i].reg);
         }
     }
 
     if (vkd3d_shader_instruction_is_uav_counter(instruction))
-        vkd3d_shader_scan_record_uav_counter(scan_info, &instruction->src[0].reg);
+        vkd3d_shader_scan_record_uav_counter(context->scan_info, &instruction->src[0].reg);
 }
 
 int vkd3d_shader_scan_dxbc(const struct vkd3d_shader_code *dxbc,
         struct vkd3d_shader_scan_info *scan_info)
 {
     struct vkd3d_shader_instruction instruction;
+    struct vkd3d_shader_scan_context context;
     struct vkd3d_shader_parser parser;
     int ret;
 
@@ -296,6 +396,9 @@ int vkd3d_shader_scan_dxbc(const struct vkd3d_shader_code *dxbc,
 
     memset(scan_info, 0, sizeof(*scan_info));
 
+    memset(&context, 0, sizeof(context));
+    context.scan_info = scan_info;
+
     while (!shader_sm4_is_end(parser.data, &parser.ptr))
     {
         shader_sm4_read_instruction(parser.data, &parser.ptr, &instruction);
@@ -303,17 +406,26 @@ int vkd3d_shader_scan_dxbc(const struct vkd3d_shader_code *dxbc,
         if (instruction.handler_idx == VKD3DSIH_INVALID)
         {
             WARN("Encountered unrecognized or invalid instruction.\n");
+            vkd3d_shader_free_scan_info(scan_info);
             vkd3d_shader_parser_destroy(&parser);
             return VKD3D_ERROR_INVALID_ARGUMENT;
         }
 
-        vkd3d_shader_scan_instruction(scan_info, &instruction);
+        vkd3d_shader_scan_instruction(&context, &instruction);
     }
 
     vkd3d_shader_parser_destroy(&parser);
     return VKD3D_OK;
 }
 
+void vkd3d_shader_free_scan_info(struct vkd3d_shader_scan_info *scan_info)
+{
+    if (!scan_info)
+        return;
+
+    vkd3d_free(scan_info->descriptors);
+}
+
 void vkd3d_shader_free_shader_code(struct vkd3d_shader_code *shader_code)
 {
     if (!shader_code)
diff --git a/libs/vkd3d/state.c b/libs/vkd3d/state.c
index db342df..501afc6 100644
--- a/libs/vkd3d/state.c
+++ b/libs/vkd3d/state.c
@@ -1528,6 +1528,7 @@ static HRESULT d3d12_pipeline_state_init_compute(struct d3d12_pipeline_state *st
         WARN("Failed to create descriptor set layout for UAV counters, hr %#x.\n", hr);
         return hr;
     }
+    vkd3d_shader_free_scan_info(&shader_info);
 
     shader_interface.type = VKD3D_SHADER_STRUCTURE_TYPE_INTERFACE_INFO;
     shader_interface.next = NULL;
@@ -2267,6 +2268,7 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
         }
         if (shader_info.uav_counter_mask)
             FIXME("UAV counters not implemented for graphics pipelines.\n");
+        vkd3d_shader_free_scan_info(&shader_info);
 
         target_info = NULL;
         switch (shader_stages[i].stage)
-- 
2.11.0




More information about the wine-devel mailing list