[PATCH vkd3d 4/5] vkd3d-shader: Return the register space of each used UAV and UAV counter in vkd3d_shader_scan_info.

Zebediah Figura zfigura at codeweavers.com
Wed Jun 3 20:49:14 CDT 2020


Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
---
 include/vkd3d_shader.h                | 10 ++++-
 libs/vkd3d-shader/spirv.c             | 24 +++++++---
 libs/vkd3d-shader/vkd3d_shader_main.c | 65 ++++++++++++++++++++++++---
 libs/vkd3d/state.c                    | 26 +++++++----
 4 files changed, 102 insertions(+), 23 deletions(-)

diff --git a/include/vkd3d_shader.h b/include/vkd3d_shader.h
index 67d4562..23c2cb7 100644
--- a/include/vkd3d_shader.h
+++ b/include/vkd3d_shader.h
@@ -539,13 +539,19 @@ struct vkd3d_versioned_root_signature_desc
 /* FIXME: Add support for 64 UAV bind slots. */
 #define VKD3D_SHADER_MAX_UNORDERED_ACCESS_VIEWS 8
 
+struct vkd3d_uav_scan_info
+{
+    unsigned int register_space, register_index, id;
+    bool counter, read;
+};
+
 struct vkd3d_shader_scan_info
 {
     enum vkd3d_shader_structure_type type;
     void *next;
 
-    unsigned int uav_read_mask;    /* VKD3D_SHADER_MAX_UNORDERED_ACCESS_VIEWS */
-    unsigned int uav_counter_mask; /* VKD3D_SHADER_MAX_UNORDERED_ACCESS_VIEWS */
+    struct vkd3d_uav_scan_info uavs[VKD3D_SHADER_MAX_UNORDERED_ACCESS_VIEWS];
+    unsigned int uav_count;
     unsigned int sampler_comparison_mode_mask; /* 16 */
     bool use_vocp;
 };
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index 5a37b8f..ecca74c 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -5106,6 +5106,19 @@ static const struct vkd3d_spirv_resource_type *vkd3d_dxbc_compiler_enable_resour
     return resource_type_info;
 }
 
+static const struct vkd3d_uav_scan_info *find_uav_scan_info(
+        const struct vkd3d_shader_scan_info *scan_info, unsigned int id)
+{
+    unsigned int i;
+
+    for (i = 0; i < scan_info->uav_count; ++i)
+    {
+        if (scan_info->uavs[i].id == id)
+            return &scan_info->uavs[i];
+    }
+    return NULL;
+}
+
 static SpvImageFormat image_format_for_image_read(enum vkd3d_component_type data_type)
 {
     /* The following formats are supported by Direct3D 11 hardware for UAV
@@ -5130,14 +5143,13 @@ static uint32_t vkd3d_dxbc_compiler_get_image_type_id(struct vkd3d_dxbc_compiler
         const struct vkd3d_shader_register *reg, const struct vkd3d_spirv_resource_type *resource_type_info,
         enum vkd3d_component_type data_type, bool raw_structured, uint32_t depth)
 {
-    const struct vkd3d_shader_scan_info *scan_info = compiler->scan_info;
+    const struct vkd3d_uav_scan_info *uav_info = find_uav_scan_info(compiler->scan_info, reg->idx[0].offset);
     struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
     uint32_t sampled_type_id;
     SpvImageFormat format;
 
     format = SpvImageFormatUnknown;
-    if (reg->type == VKD3DSPR_UAV
-            && (raw_structured || (scan_info->uav_read_mask & (1u << reg->idx[0].offset))))
+    if (reg->type == VKD3DSPR_UAV && (raw_structured || uav_info->read))
         format = image_format_for_image_read(data_type);
 
     sampled_type_id = vkd3d_spirv_get_type_id(builder, data_type, 1);
@@ -5214,8 +5226,8 @@ static void vkd3d_dxbc_compiler_emit_resource_declaration(struct vkd3d_dxbc_comp
         enum vkd3d_shader_resource_type resource_type, enum vkd3d_data_type resource_data_type,
         unsigned int structure_stride, bool raw)
 {
+    const struct vkd3d_uav_scan_info *uav_info = find_uav_scan_info(compiler->scan_info, reg->idx[0].offset);
     uint32_t counter_type_id, type_id, ptr_type_id, var_id, counter_var_id = 0;
-    const struct vkd3d_shader_scan_info *scan_info = compiler->scan_info;
     struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
     SpvStorageClass storage_class = SpvStorageClassUniformConstant;
     const struct vkd3d_spirv_resource_type *resource_type_info;
@@ -5251,10 +5263,10 @@ static void vkd3d_dxbc_compiler_emit_resource_declaration(struct vkd3d_dxbc_comp
 
     vkd3d_dxbc_compiler_emit_register_debug_name(builder, var_id, reg);
 
-    if (is_uav && !(scan_info->uav_read_mask & (1u << reg->idx[0].offset)))
+    if (is_uav && !uav_info->read)
         vkd3d_spirv_build_op_decorate(builder, var_id, SpvDecorationNonReadable, NULL, 0);
 
-    if (is_uav && (scan_info->uav_counter_mask & (1u << reg->idx[0].offset)))
+    if (is_uav && uav_info->counter)
     {
         assert(structure_stride); /* counters are valid only for structured buffers */
 
diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c
index aa486cc..9ef84d4 100644
--- a/libs/vkd3d-shader/vkd3d_shader_main.c
+++ b/libs/vkd3d-shader/vkd3d_shader_main.c
@@ -22,9 +22,6 @@
 
 VKD3D_DEBUG_ENV_NAME("VKD3D_SHADER_DEBUG");
 
-STATIC_ASSERT(MEMBER_SIZE(struct vkd3d_shader_scan_info, uav_counter_mask) * CHAR_BIT >= VKD3D_SHADER_MAX_UNORDERED_ACCESS_VIEWS);
-STATIC_ASSERT(MEMBER_SIZE(struct vkd3d_shader_scan_info, uav_read_mask) * CHAR_BIT >= VKD3D_SHADER_MAX_UNORDERED_ACCESS_VIEWS);
-
 static void vkd3d_shader_dump_blob(const char *path, const char *prefix, const void *data, size_t size)
 {
     static int shader_id = 0;
@@ -205,11 +202,25 @@ static bool vkd3d_shader_instruction_is_uav_read(const struct vkd3d_shader_instr
             || (handler_idx == VKD3DSIH_LD_STRUCTURED && instruction->src[2].reg.type == VKD3DSPR_UAV);
 }
 
+static struct vkd3d_uav_scan_info *find_uav_scan_info(struct vkd3d_shader_scan_info *scan_info, unsigned int id)
+{
+    unsigned int i;
+
+    for (i = 0; i < scan_info->uav_count; ++i)
+    {
+        if (scan_info->uavs[i].id == id)
+            return &scan_info->uavs[i];
+    }
+    return NULL;
+}
+
 static void vkd3d_shader_scan_record_uav_read(struct vkd3d_shader_scan_info *scan_info,
         const struct vkd3d_shader_register *reg)
 {
-    assert(reg->idx[0].offset < VKD3D_SHADER_MAX_UNORDERED_ACCESS_VIEWS);
-    scan_info->uav_read_mask |= 1u << reg->idx[0].offset;
+    struct vkd3d_uav_scan_info *uav_info = find_uav_scan_info(scan_info, reg->idx[0].offset);
+
+    assert(uav_info);
+    uav_info->read = true;
 }
 
 static bool vkd3d_shader_instruction_is_uav_counter(const struct vkd3d_shader_instruction *instruction)
@@ -222,8 +233,10 @@ static bool vkd3d_shader_instruction_is_uav_counter(const struct vkd3d_shader_in
 static void vkd3d_shader_scan_record_uav_counter(struct vkd3d_shader_scan_info *scan_info,
         const struct vkd3d_shader_register *reg)
 {
-    assert(reg->idx[0].offset < VKD3D_SHADER_MAX_UNORDERED_ACCESS_VIEWS);
-    scan_info->uav_counter_mask |= 1u << reg->idx[0].offset;
+    struct vkd3d_uav_scan_info *uav_info = find_uav_scan_info(scan_info, reg->idx[0].offset);
+
+    assert(uav_info);
+    uav_info->counter = true;
 }
 
 static void vkd3d_shader_scan_input_declaration(struct vkd3d_shader_scan_info *scan_info,
@@ -246,6 +259,39 @@ static void vkd3d_shader_scan_sampler_declaration(struct vkd3d_shader_scan_info
     }
 }
 
+static void vkd3d_shader_scan_uav_declaration(struct vkd3d_shader_scan_info *scan_info,
+        const struct vkd3d_shader_instruction *instruction)
+{
+    unsigned int register_space, register_index, id;
+    struct vkd3d_uav_scan_info *uav_info;
+
+    assert(scan_info->uav_count < VKD3D_SHADER_MAX_UNORDERED_ACCESS_VIEWS);
+
+    if (instruction->handler_idx == VKD3DSIH_DCL_UAV_RAW)
+    {
+        register_space = instruction->declaration.raw_resource.register_space;
+        register_index = instruction->declaration.raw_resource.register_index;
+        id = instruction->declaration.raw_resource.dst.reg.idx[0].offset;
+    }
+    else if (instruction->handler_idx == VKD3DSIH_DCL_UAV_STRUCTURED)
+    {
+        register_space = instruction->declaration.structured_resource.register_space;
+        register_index = instruction->declaration.structured_resource.register_index;
+        id = instruction->declaration.structured_resource.reg.reg.idx[0].offset;
+    }
+    else /* VKD3DSIH_DCL_UAV_TYPED */
+    {
+        register_space = instruction->declaration.semantic.register_space;
+        register_index = instruction->declaration.semantic.register_index;
+        id = instruction->declaration.semantic.reg.reg.idx[0].offset;
+    }
+
+    uav_info = &scan_info->uavs[scan_info->uav_count++];
+    uav_info->register_space = register_space;
+    uav_info->register_index = register_index;
+    uav_info->id = id;
+}
+
 static void vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_info *scan_info,
         const struct vkd3d_shader_instruction *instruction)
 {
@@ -259,6 +305,11 @@ static void vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_info *scan_in
         case VKD3DSIH_DCL_SAMPLER:
             vkd3d_shader_scan_sampler_declaration(scan_info, instruction);
             break;
+        case VKD3DSIH_DCL_UAV_RAW:
+        case VKD3DSIH_DCL_UAV_STRUCTURED:
+        case VKD3DSIH_DCL_UAV_TYPED:
+            vkd3d_shader_scan_uav_declaration(scan_info, instruction);
+            break;
         default:
             break;
     }
diff --git a/libs/vkd3d/state.c b/libs/vkd3d/state.c
index 11db8b5..4bd4ef7 100644
--- a/libs/vkd3d/state.c
+++ b/libs/vkd3d/state.c
@@ -1405,11 +1405,17 @@ static HRESULT d3d12_pipeline_state_init_compute_uav_counters(struct d3d12_pipel
     struct vkd3d_descriptor_set_context context;
     VkDescriptorSetLayoutBinding *binding_desc;
     VkDescriptorSetLayout set_layouts[3];
-    unsigned int uav_counter_count;
+    unsigned int uav_counter_count = 0;
     unsigned int i, j;
     HRESULT hr;
 
-    if (!(uav_counter_count = vkd3d_popcount(shader_info->uav_counter_mask)))
+    for (i = 0; i < shader_info->uav_count; ++i)
+    {
+        if (shader_info->uavs[i].counter)
+            ++uav_counter_count;
+    }
+
+    if (!uav_counter_count)
         return S_OK;
 
     if (!(binding_desc = vkd3d_calloc(uav_counter_count, sizeof(*binding_desc))))
@@ -1427,13 +1433,13 @@ static HRESULT d3d12_pipeline_state_init_compute_uav_counters(struct d3d12_pipel
     if (root_signature->vk_set_layout)
         set_layouts[context.set_index++] = root_signature->vk_set_layout;
 
-    for (i = 0, j = 0; i < VKD3D_SHADER_MAX_UNORDERED_ACCESS_VIEWS; ++i)
+    for (i = 0, j = 0; i < shader_info->uav_count; ++i)
     {
-        if (!(shader_info->uav_counter_mask & (1u << i)))
+        if (!shader_info->uavs[i].counter)
             continue;
 
-        state->uav_counters[j].register_space = 0;
-        state->uav_counters[j].register_index = i;
+        state->uav_counters[j].register_space = shader_info->uavs[i].register_space;
+        state->uav_counters[j].register_index = shader_info->uavs[i].register_index;
         state->uav_counters[j].shader_visibility = VKD3D_SHADER_VISIBILITY_COMPUTE;
         state->uav_counters[j].binding.set = context.set_index;
         state->uav_counters[j].binding.binding = context.descriptor_binding;
@@ -2256,8 +2262,12 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
             hr = hresult_from_vkd3d_result(ret);
             goto fail;
         }
-        if (shader_info.uav_counter_mask)
-            FIXME("UAV counters not implemented for graphics pipelines.\n");
+
+        for (j = 0; j < shader_info.uav_count; ++j)
+        {
+            if (shader_info.uavs[j].counter)
+                FIXME("UAV counters not implemented for graphics pipelines.\n");
+        }
 
         compile_args = NULL;
         switch (shader_stages[i].stage)
-- 
2.26.2




More information about the wine-devel mailing list