[PATCH vkd3d 1/6] vkd3d-shader: Parse SM5.1 register ranges.

Conor McCarthy cmccarthy at codeweavers.com
Wed May 26 03:10:50 CDT 2021


Based on register loading code from Henri Verbeet <hverbeet at codeweavers.com>

Signed-off-by: Conor McCarthy <cmccarthy at codeweavers.com>
---
 libs/vkd3d-shader/dxbc.c                 | 121 ++++++++++++++++-------
 libs/vkd3d-shader/spirv.c                |  86 +++++++++++-----
 libs/vkd3d-shader/vkd3d_shader_main.c    |  17 ++--
 libs/vkd3d-shader/vkd3d_shader_private.h |   8 +-
 4 files changed, 157 insertions(+), 75 deletions(-)

diff --git a/libs/vkd3d-shader/dxbc.c b/libs/vkd3d-shader/dxbc.c
index d2cf87e3..ad1db82a 100644
--- a/libs/vkd3d-shader/dxbc.c
+++ b/libs/vkd3d-shader/dxbc.c
@@ -622,12 +622,24 @@ static void shader_sm4_read_shader_data(struct vkd3d_shader_instruction *ins,
     ins->declaration.icb = &priv->icb;
 }
 
-static unsigned int shader_sm4_map_resource_idx(struct vkd3d_shader_register *reg, const struct vkd3d_sm4_data *priv)
+static void shader_sm4_read_register_indices(struct vkd3d_shader_resource *resource,
+        struct vkd3d_shader_instruction *ins, struct vkd3d_sm4_data *priv)
 {
     if (shader_is_sm_5_1(priv))
-        return reg->idx[1].offset;
+    {
+        resource->register_first = resource->reg.reg.idx[1].offset;
+        resource->register_last = resource->reg.reg.idx[2].offset;
+        if (resource->register_last < resource->register_first)
+        {
+            FIXME("Invalid register range [%u:%u].\n", resource->register_first, resource->register_last);
+            ins->handler_idx = VKD3DSIH_INVALID;
+        }
+    }
     else
-        return reg->idx[0].offset;
+    {
+        resource->register_first = resource->reg.reg.idx[0].offset;
+        resource->register_last = resource->register_first;
+    }
 }
 
 static void shader_sm4_read_dcl_resource(struct vkd3d_shader_instruction *ins,
@@ -635,6 +647,7 @@ static void shader_sm4_read_dcl_resource(struct vkd3d_shader_instruction *ins,
         struct vkd3d_sm4_data *priv)
 {
     struct vkd3d_shader_semantic *semantic = &ins->declaration.semantic;
+    struct vkd3d_shader_resource *resource = &semantic->resource;
     enum vkd3d_sm4_resource_type resource_type;
     const DWORD *end = &tokens[token_count];
     enum vkd3d_sm4_data_type data_type;
@@ -653,8 +666,7 @@ static void shader_sm4_read_dcl_resource(struct vkd3d_shader_instruction *ins,
         semantic->resource_type = resource_type_table[resource_type];
     }
     reg_data_type = opcode == VKD3D_SM4_OP_DCL_RESOURCE ? VKD3D_DATA_RESOURCE : VKD3D_DATA_UAV;
-    shader_sm4_read_dst_param(priv, &tokens, end, reg_data_type, &semantic->resource.reg);
-    semantic->resource.register_index = shader_sm4_map_resource_idx(&semantic->resource.reg.reg, priv);
+    shader_sm4_read_dst_param(priv, &tokens, end, reg_data_type, &resource->reg);
 
     components = *tokens++;
     for (i = 0; i < VKD3D_VEC4_SIZE; i++)
@@ -675,23 +687,21 @@ static void shader_sm4_read_dcl_resource(struct vkd3d_shader_instruction *ins,
     if (reg_data_type == VKD3D_DATA_UAV)
         ins->flags = (opcode_token & VKD3D_SM5_UAV_FLAGS_MASK) >> VKD3D_SM5_UAV_FLAGS_SHIFT;
 
-    shader_sm4_read_register_space(priv, &tokens, end, &semantic->resource.register_space);
+    shader_sm4_read_register_space(priv, &tokens, end, &resource->register_space);
+    shader_sm4_read_register_indices(resource, ins, priv);
 }
 
 static void shader_sm4_read_dcl_constant_buffer(struct vkd3d_shader_instruction *ins,
         DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count,
         struct vkd3d_sm4_data *priv)
 {
+    struct vkd3d_shader_constant_buffer *cb = &ins->declaration.cb;
     const DWORD *end = &tokens[token_count];
 
-    shader_sm4_read_src_param(priv, &tokens, end, VKD3D_DATA_FLOAT, &ins->declaration.cb.src);
-    ins->declaration.cb.register_index = shader_sm4_map_resource_idx(&ins->declaration.cb.src.reg, priv);
     if (opcode_token & VKD3D_SM4_INDEX_TYPE_MASK)
         ins->flags |= VKD3DSI_INDEXED_DYNAMIC;
 
-    ins->declaration.cb.size = ins->declaration.cb.src.reg.idx[2].offset;
-    ins->declaration.cb.register_space = 0;
-
+    shader_sm4_read_src_param(priv, &tokens, end, VKD3D_DATA_FLOAT, &cb->src);
     if (shader_is_sm_5_1(priv))
     {
         if (tokens >= end)
@@ -700,8 +710,22 @@ static void shader_sm4_read_dcl_constant_buffer(struct vkd3d_shader_instruction
             return;
         }
 
-        ins->declaration.cb.size = *tokens++;
-        shader_sm4_read_register_space(priv, &tokens, end, &ins->declaration.cb.register_space);
+        cb->size = *tokens++;
+        shader_sm4_read_register_space(priv, &tokens, end, &cb->register_space);
+        cb->register_first = cb->src.reg.idx[1].offset;
+        cb->register_last = cb->src.reg.idx[2].offset;
+        if (cb->register_last < cb->register_first)
+        {
+            FIXME("Invalid register range [%u:%u].\n", cb->register_first, cb->register_last);
+            ins->handler_idx = VKD3DSIH_INVALID;
+        }
+    }
+    else
+    {
+        cb->size = cb->src.reg.idx[2].offset;
+        cb->register_space = 0;
+        cb->register_first = cb->src.reg.idx[0].offset;
+        cb->register_last = cb->register_first;
     }
 }
 
@@ -709,14 +733,31 @@ static void shader_sm4_read_dcl_sampler(struct vkd3d_shader_instruction *ins,
         DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count,
         struct vkd3d_sm4_data *priv)
 {
+    struct vkd3d_shader_sampler *sampler = &ins->declaration.sampler;
     const DWORD *end = &tokens[token_count];
 
     ins->flags = (opcode_token & VKD3D_SM4_SAMPLER_MODE_MASK) >> VKD3D_SM4_SAMPLER_MODE_SHIFT;
     if (ins->flags & ~VKD3D_SM4_SAMPLER_COMPARISON)
         FIXME("Unhandled sampler mode %#x.\n", ins->flags);
-    shader_sm4_read_src_param(priv, &tokens, end, VKD3D_DATA_SAMPLER, &ins->declaration.sampler.src);
-    ins->declaration.sampler.register_index = shader_sm4_map_resource_idx(&ins->declaration.sampler.src.reg, priv);
-    shader_sm4_read_register_space(priv, &tokens, end, &ins->declaration.sampler.register_space);
+
+    shader_sm4_read_src_param(priv, &tokens, end, VKD3D_DATA_SAMPLER, &sampler->src);
+    if (shader_is_sm_5_1(priv))
+    {
+        shader_sm4_read_register_space(priv, &tokens, end, &sampler->register_space);
+        sampler->register_first = sampler->src.reg.idx[1].offset;
+        sampler->register_last = sampler->src.reg.idx[2].offset;
+        if (sampler->register_last < sampler->register_first)
+        {
+            FIXME("Invalid register range [%u:%u].\n", sampler->register_first, sampler->register_last);
+            ins->handler_idx = VKD3DSIH_INVALID;
+        }
+    }
+    else
+    {
+        sampler->register_space = 0;
+        sampler->register_first = sampler->src.reg.idx[0].offset;
+        sampler->register_last = sampler->register_first;
+    }
 }
 
 static void shader_sm4_read_dcl_index_range(struct vkd3d_shader_instruction *ins,
@@ -912,29 +953,32 @@ static void shader_sm5_read_dcl_uav_raw(struct vkd3d_shader_instruction *ins,
         DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count,
         struct vkd3d_sm4_data *priv)
 {
-    struct vkd3d_shader_raw_resource *resource = &ins->declaration.raw_resource;
+    struct vkd3d_shader_resource *resource = &ins->declaration.raw_resource.resource;
     const DWORD *end = &tokens[token_count];
 
-    shader_sm4_read_dst_param(priv, &tokens, end, VKD3D_DATA_UAV, &resource->resource.reg);
-    resource->resource.register_index = shader_sm4_map_resource_idx(&resource->resource.reg.reg, priv);
     ins->flags = (opcode_token & VKD3D_SM5_UAV_FLAGS_MASK) >> VKD3D_SM5_UAV_FLAGS_SHIFT;
-    shader_sm4_read_register_space(priv, &tokens, end, &resource->resource.register_space);
+
+    shader_sm4_read_dst_param(priv, &tokens, end, VKD3D_DATA_UAV, &resource->reg);
+    shader_sm4_read_register_space(priv, &tokens, end, &resource->register_space);
+    shader_sm4_read_register_indices(resource, ins, priv);
 }
 
 static void shader_sm5_read_dcl_uav_structured(struct vkd3d_shader_instruction *ins,
         DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count,
         struct vkd3d_sm4_data *priv)
 {
-    struct vkd3d_shader_structured_resource *resource = &ins->declaration.structured_resource;
+    struct vkd3d_shader_structured_resource *structured = &ins->declaration.structured_resource;
+    struct vkd3d_shader_resource *resource = &structured->resource;
     const DWORD *end = &tokens[token_count];
 
-    shader_sm4_read_dst_param(priv, &tokens, end, VKD3D_DATA_UAV, &resource->resource.reg);
-    resource->resource.register_index = shader_sm4_map_resource_idx(&resource->resource.reg.reg, priv);
     ins->flags = (opcode_token & VKD3D_SM5_UAV_FLAGS_MASK) >> VKD3D_SM5_UAV_FLAGS_SHIFT;
-    resource->byte_stride = *tokens++;
-    if (resource->byte_stride % 4)
-        FIXME("Byte stride %u is not multiple of 4.\n", resource->byte_stride);
-    shader_sm4_read_register_space(priv, &tokens, end, &resource->resource.register_space);
+
+    shader_sm4_read_dst_param(priv, &tokens, end, VKD3D_DATA_UAV, &resource->reg);
+    structured->byte_stride = *tokens++;
+    if (structured->byte_stride % 4)
+        FIXME("Byte stride %u is not multiple of 4.\n", structured->byte_stride);
+    shader_sm4_read_register_space(priv, &tokens, end, &resource->register_space);
+    shader_sm4_read_register_indices(resource, ins, priv);
 }
 
 static void shader_sm5_read_dcl_tgsm_raw(struct vkd3d_shader_instruction *ins,
@@ -963,27 +1007,28 @@ static void shader_sm5_read_dcl_resource_structured(struct vkd3d_shader_instruct
         DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count,
         struct vkd3d_sm4_data *priv)
 {
-    struct vkd3d_shader_structured_resource *resource = &ins->declaration.structured_resource;
+    struct vkd3d_shader_structured_resource *structured = &ins->declaration.structured_resource;
+    struct vkd3d_shader_resource *resource = &structured->resource;
     const DWORD *end = &tokens[token_count];
 
-    shader_sm4_read_dst_param(priv, &tokens, end, VKD3D_DATA_RESOURCE, &resource->resource.reg);
-    resource->resource.register_index = shader_sm4_map_resource_idx(&resource->resource.reg.reg, priv);
-    resource->byte_stride = *tokens++;
-    if (resource->byte_stride % 4)
-        FIXME("Byte stride %u is not multiple of 4.\n", resource->byte_stride);
-    shader_sm4_read_register_space(priv, &tokens, end, &resource->resource.register_space);
+    shader_sm4_read_dst_param(priv, &tokens, end, VKD3D_DATA_RESOURCE, &resource->reg);
+    structured->byte_stride = *tokens++;
+    if (structured->byte_stride % 4)
+        FIXME("Byte stride %u is not multiple of 4.\n", structured->byte_stride);
+    shader_sm4_read_register_space(priv, &tokens, end, &resource->register_space);
+    shader_sm4_read_register_indices(resource, ins, priv);
 }
 
 static void shader_sm5_read_dcl_resource_raw(struct vkd3d_shader_instruction *ins,
         DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count,
         struct vkd3d_sm4_data *priv)
 {
-    struct vkd3d_shader_raw_resource *resource = &ins->declaration.raw_resource;
+    struct vkd3d_shader_resource *resource = &ins->declaration.raw_resource.resource;
     const DWORD *end = &tokens[token_count];
 
-    shader_sm4_read_dst_param(priv, &tokens, end, VKD3D_DATA_RESOURCE, &resource->resource.reg);
-    resource->resource.register_index = shader_sm4_map_resource_idx(&resource->resource.reg.reg, priv);
-    shader_sm4_read_register_space(priv, &tokens, end, &resource->resource.register_space);
+    shader_sm4_read_dst_param(priv, &tokens, end, VKD3D_DATA_RESOURCE, &resource->reg);
+    shader_sm4_read_register_space(priv, &tokens, end, &resource->register_space);
+    shader_sm4_read_register_indices(resource, ins, priv);
 }
 
 static void shader_sm5_read_sync(struct vkd3d_shader_instruction *ins,
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index d477b384..0342efa3 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -2077,6 +2077,14 @@ static const char *debug_vkd3d_symbol(const struct vkd3d_symbol *symbol)
     }
 }
 
+static const char *debug_register_range(unsigned int register_first, unsigned int register_last, bool bounded)
+{
+    if (bounded)
+        return vkd3d_dbg_sprintf("[%u:%u]", register_first, register_last);
+    else
+        return vkd3d_dbg_sprintf("[%u:*]", register_first);
+}
+
 struct vkd3d_if_cf_info
 {
     size_t stream_location;
@@ -2404,9 +2412,12 @@ static struct vkd3d_push_constant_buffer_binding *vkd3d_dxbc_compiler_find_push_
         const struct vkd3d_dxbc_compiler *compiler, const struct vkd3d_shader_constant_buffer *cb)
 {
     unsigned int register_space = cb->register_space;
-    unsigned int reg_idx = cb->register_index;
+    unsigned int reg_idx = cb->register_first;
     unsigned int i;
 
+    if (cb->register_first != cb->register_last)
+        return NULL;
+
     for (i = 0; i < compiler->shader_interface.push_constant_buffer_count; ++i)
     {
         struct vkd3d_push_constant_buffer_binding *current = &compiler->push_constants[i];
@@ -2431,7 +2442,10 @@ static bool vkd3d_dxbc_compiler_has_combined_sampler(const struct vkd3d_dxbc_com
     if (!shader_interface->combined_sampler_count)
         return false;
 
-    if (resource && resource->reg.reg.type == VKD3DSPR_UAV)
+    if (resource && (resource->reg.reg.type == VKD3DSPR_UAV || resource->register_last != resource->register_first))
+        return false;
+
+    if (sampler && sampler->register_first != sampler->register_last)
         return false;
 
     for (i = 0; i < shader_interface->combined_sampler_count; ++i)
@@ -2442,9 +2456,9 @@ static bool vkd3d_dxbc_compiler_has_combined_sampler(const struct vkd3d_dxbc_com
             continue;
 
         if ((!resource || (combined_sampler->resource_space == resource->register_space
-                && combined_sampler->resource_index == resource->register_index))
+                && combined_sampler->resource_index == resource->register_first))
                 && (!sampler || (combined_sampler->sampler_space == sampler->register_space
-                && combined_sampler->sampler_index == sampler->register_index)))
+                && combined_sampler->sampler_index == sampler->register_first)))
             return true;
     }
 
@@ -2464,12 +2478,14 @@ static void VKD3D_PRINTF_FUNC(3, 4) vkd3d_dxbc_compiler_error(struct vkd3d_dxbc_
 
 static struct vkd3d_shader_descriptor_binding vkd3d_dxbc_compiler_get_descriptor_binding(
         struct vkd3d_dxbc_compiler *compiler, const struct vkd3d_shader_register *reg, unsigned int register_space,
-        unsigned int reg_idx, enum vkd3d_shader_resource_type resource_type, bool is_uav_counter)
+        unsigned int register_first, unsigned int register_last, enum vkd3d_shader_resource_type resource_type,
+        bool is_uav_counter)
 {
     const struct vkd3d_shader_interface_info *shader_interface = &compiler->shader_interface;
     enum vkd3d_shader_descriptor_type descriptor_type;
     enum vkd3d_shader_binding_flag resource_type_flag;
     struct vkd3d_shader_descriptor_binding binding;
+    bool bounded = true;
     unsigned int i;
 
     if (reg->type == VKD3DSPR_CONSTBUFFER)
@@ -2491,6 +2507,12 @@ static struct vkd3d_shader_descriptor_binding vkd3d_dxbc_compiler_get_descriptor
     resource_type_flag = resource_type == VKD3D_SHADER_RESOURCE_BUFFER
             ? VKD3D_SHADER_BINDING_FLAG_BUFFER : VKD3D_SHADER_BINDING_FLAG_IMAGE;
 
+    if (register_last == ~0u)
+    {
+        bounded = false;
+        register_last = register_first;
+    }
+
     if (is_uav_counter)
     {
         assert(descriptor_type == VKD3D_SHADER_DESCRIPTOR_TYPE_UAV);
@@ -2501,15 +2523,17 @@ static struct vkd3d_shader_descriptor_binding vkd3d_dxbc_compiler_get_descriptor
             if (!vkd3d_dxbc_compiler_check_shader_visibility(compiler, current->shader_visibility))
                 continue;
 
-            if (current->register_space != register_space || current->register_index != reg_idx)
+            if (current->register_space != register_space || current->register_index > register_first
+                    || current->register_index + current->binding.count <= register_last)
                 continue;
 
             if (current->offset)
             {
                 FIXME("Atomic counter offsets are not supported yet.\n");
                 vkd3d_dxbc_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_INVALID_DESCRIPTOR_BINDING,
-                        "Descriptor binding for UAV counter %u, space %u has unsupported ‘offset’ %u.",
-                        reg_idx, register_space, current->offset);
+                        "Descriptor binding for UAV counter %s, space %u has unsupported ‘offset’ %u.",
+                        debug_register_range(register_first, register_last, bounded),
+                        register_space, current->offset);
             }
 
             if (current->binding.count != 1)
@@ -2517,16 +2541,18 @@ static struct vkd3d_shader_descriptor_binding vkd3d_dxbc_compiler_get_descriptor
                 FIXME("Descriptor arrays are not supported.\n");
                 vkd3d_dxbc_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_INVALID_DESCRIPTOR_BINDING,
                         "Descriptor binding for UAV counter %u, space %u has unsupported ‘count’ %u.",
-                        reg_idx, register_space, current->binding.count);
+                        register_first, register_space, current->binding.count);
             }
 
             return current->binding;
         }
         if (shader_interface->uav_counter_count)
         {
-            FIXME("Could not find descriptor binding for UAV counter %u, space %u.\n", reg_idx, register_space);
+            FIXME("Could not find descriptor binding for UAV counters %s, space %u.\n",
+                    debug_register_range(register_first, register_last, bounded), register_space);
             vkd3d_dxbc_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_DESCRIPTOR_BINDING_NOT_FOUND,
-                    "Could not find descriptor binding for UAV counter %u, space %u.", reg_idx, register_space);
+                    "Could not find descriptor binding for UAV counters %s, space %u.",
+                    debug_register_range(register_first, register_last, bounded), register_space);
         }
     }
     else
@@ -2542,7 +2568,8 @@ static struct vkd3d_shader_descriptor_binding vkd3d_dxbc_compiler_get_descriptor
                 continue;
 
             if (current->type != descriptor_type || current->register_space != register_space
-                    || current->register_index != reg_idx)
+                    || current->register_index > register_first
+                    || current->register_index + current->binding.count <= register_last)
                 continue;
 
             if (current->binding.count != 1)
@@ -2558,11 +2585,13 @@ static struct vkd3d_shader_descriptor_binding vkd3d_dxbc_compiler_get_descriptor
         }
         if (shader_interface->binding_count)
         {
-            FIXME("Could not find binding for type %#x, space %u, register %u, shader type %#x.\n",
-                    descriptor_type, register_space, reg_idx, compiler->shader_type);
+            FIXME("Could not find binding for type %#x, space %u, registers %s, shader type %#x.\n",
+                    descriptor_type, register_space, debug_register_range(register_first, register_last, bounded),
+                    compiler->shader_type);
             vkd3d_dxbc_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_DESCRIPTOR_BINDING_NOT_FOUND,
-                    "Could not find descriptor binding for type %#x, space %u, register %u, shader type %#x.",
-                    descriptor_type, register_space, reg_idx, compiler->shader_type);
+                    "Could not find descriptor binding for type %#x, space %u, registers %s, shader type %#x.",
+                    descriptor_type, register_space, debug_register_range(register_first, register_last, bounded),
+                    compiler->shader_type);
         }
     }
 
@@ -2585,12 +2614,13 @@ static void vkd3d_dxbc_compiler_emit_descriptor_binding(struct vkd3d_dxbc_compil
 
 static void vkd3d_dxbc_compiler_emit_descriptor_binding_for_reg(struct vkd3d_dxbc_compiler *compiler,
         uint32_t variable_id, const struct vkd3d_shader_register *reg, unsigned int register_space,
-        unsigned int register_index, enum vkd3d_shader_resource_type resource_type, bool is_uav_counter)
+        unsigned int register_first, unsigned int register_last, enum vkd3d_shader_resource_type resource_type,
+        bool is_uav_counter)
 {
     struct vkd3d_shader_descriptor_binding binding;
 
     binding = vkd3d_dxbc_compiler_get_descriptor_binding(compiler, reg, register_space,
-            register_index, resource_type, is_uav_counter);
+            register_first, register_last, resource_type, is_uav_counter);
     vkd3d_dxbc_compiler_emit_descriptor_binding(compiler, variable_id, &binding);
 }
 
@@ -5365,7 +5395,7 @@ static void vkd3d_dxbc_compiler_emit_dcl_sampler(struct vkd3d_dxbc_compiler *com
 
     vkd3d_symbol_make_sampler(&reg_symbol, reg);
     reg_symbol.info.sampler.register_space = sampler->register_space;
-    reg_symbol.info.sampler.register_index = sampler->register_index;
+    reg_symbol.info.sampler.register_index = sampler->register_first;
     vkd3d_dxbc_compiler_put_symbol(compiler, &reg_symbol);
 
     if (vkd3d_dxbc_compiler_has_combined_sampler(compiler, NULL, sampler))
@@ -5435,7 +5465,8 @@ static const struct vkd3d_shader_descriptor_info *vkd3d_dxbc_compiler_get_descri
     for (i = 0; i < descriptor_info->descriptor_count; ++i)
     {
         d = &descriptor_info->descriptors[i];
-        if (d->type == type && d->register_space == register_space && d->register_index == register_index)
+        if (d->type == type && d->register_space == register_space && d->register_index <= register_index
+                    && (d->count == ~0u || d->register_index + d->count > register_index))
             return d;
     }
 
@@ -5556,7 +5587,9 @@ static void vkd3d_dxbc_compiler_emit_resource_declaration(struct vkd3d_dxbc_comp
     const struct vkd3d_shader_register *reg = &resource->reg.reg;
     const struct vkd3d_spirv_resource_type *resource_type_info;
     unsigned int register_space = resource->register_space;
-    unsigned int register_index = resource->register_index;
+    unsigned int register_first = resource->register_first;
+    unsigned int register_last = resource->register_last;
+    struct vkd3d_shader_descriptor_binding binding;
     enum vkd3d_shader_component_type sampled_type;
     struct vkd3d_symbol resource_symbol;
     bool is_uav;
@@ -5574,7 +5607,7 @@ static void vkd3d_dxbc_compiler_emit_resource_declaration(struct vkd3d_dxbc_comp
     if (vkd3d_dxbc_compiler_has_combined_sampler(compiler, resource, NULL))
     {
         vkd3d_dxbc_compiler_emit_combined_sampler_declarations(compiler, reg, register_space,
-                register_index, resource_type, sampled_type, structure_stride, raw, resource_type_info);
+                register_first, resource_type, sampled_type, structure_stride, raw, resource_type_info);
         return;
     }
 
@@ -5597,7 +5630,7 @@ static void vkd3d_dxbc_compiler_emit_resource_declaration(struct vkd3d_dxbc_comp
     else
     {
         type_id = vkd3d_dxbc_compiler_get_image_type_id(compiler, reg, register_space,
-                register_index, resource_type_info, sampled_type, structure_stride || raw, 0);
+                register_first, resource_type_info, sampled_type, structure_stride || raw, 0);
     }
 
     ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, storage_class, type_id);
@@ -5614,7 +5647,7 @@ static void vkd3d_dxbc_compiler_emit_resource_declaration(struct vkd3d_dxbc_comp
         const struct vkd3d_shader_descriptor_info *d;
 
         d = vkd3d_dxbc_compiler_get_descriptor_info(compiler,
-                VKD3D_SHADER_DESCRIPTOR_TYPE_UAV, register_space, register_index);
+                VKD3D_SHADER_DESCRIPTOR_TYPE_UAV, register_space, register_first);
 
         if (!(d->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_READ))
             vkd3d_spirv_build_op_decorate(builder, var_id, SpvDecorationNonReadable, NULL, 0);
@@ -5650,7 +5683,8 @@ static void vkd3d_dxbc_compiler_emit_resource_declaration(struct vkd3d_dxbc_comp
                     ptr_type_id, storage_class, 0);
 
             vkd3d_dxbc_compiler_emit_descriptor_binding_for_reg(compiler,
-                    counter_var_id, reg, register_space, register_index, resource_type, true);
+                    counter_var_id, reg, register_space, register_first, register_last,
+                    resource_type, true);
 
             vkd3d_spirv_build_op_name(builder, counter_var_id, "u%u_counter", reg->idx[0].offset);
         }
@@ -5659,7 +5693,7 @@ static void vkd3d_dxbc_compiler_emit_resource_declaration(struct vkd3d_dxbc_comp
     vkd3d_symbol_make_resource(&resource_symbol, reg);
     resource_symbol.id = var_id;
     resource_symbol.info.resource.register_space = register_space;
-    resource_symbol.info.resource.register_index = register_index;
+    resource_symbol.info.resource.register_index = register_first;
     resource_symbol.info.resource.sampled_type = sampled_type;
     resource_symbol.info.resource.type_id = type_id;
     resource_symbol.info.resource.resource_type_info = resource_type_info;
diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c
index 2308b894..31029ad9 100644
--- a/libs/vkd3d-shader/vkd3d_shader_main.c
+++ b/libs/vkd3d-shader/vkd3d_shader_main.c
@@ -580,9 +580,9 @@ static void vkd3d_shader_scan_record_uav_counter(struct vkd3d_shader_scan_contex
 }
 
 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,
-        enum vkd3d_shader_resource_type resource_type, enum vkd3d_shader_resource_data_type resource_data_type,
-        unsigned int flags)
+        enum vkd3d_shader_descriptor_type type, unsigned int register_space, unsigned int register_first,
+        unsigned int register_last, enum vkd3d_shader_resource_type resource_type,
+        enum vkd3d_shader_resource_data_type resource_data_type, unsigned int flags)
 {
     struct vkd3d_shader_scan_descriptor_info *info = context->scan_descriptor_info;
     struct vkd3d_shader_descriptor_info *d;
@@ -597,11 +597,11 @@ static bool vkd3d_shader_scan_add_descriptor(struct vkd3d_shader_scan_context *c
     d = &info->descriptors[info->descriptor_count];
     d->type = type;
     d->register_space = register_space;
-    d->register_index = register_index;
+    d->register_index = register_first;
     d->resource_type = resource_type;
     d->resource_data_type = resource_data_type;
     d->flags = flags;
-    d->count = 1;
+    d->count = (register_last == ~0u) ? ~0u : register_last - register_first + 1;
     ++info->descriptor_count;
 
     return true;
@@ -633,7 +633,7 @@ static void vkd3d_shader_scan_constant_buffer_declaration(struct vkd3d_shader_sc
         return;
 
     vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, cb->register_space,
-            cb->register_index, VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_SHADER_RESOURCE_DATA_UINT, 0);
+            cb->register_first, cb->register_last, VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_SHADER_RESOURCE_DATA_UINT, 0);
 }
 
 static void vkd3d_shader_scan_sampler_declaration(struct vkd3d_shader_scan_context *context,
@@ -650,7 +650,8 @@ static void vkd3d_shader_scan_sampler_declaration(struct vkd3d_shader_scan_conte
     else
         flags = 0;
     vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, sampler->register_space,
-            sampler->register_index, VKD3D_SHADER_RESOURCE_NONE, VKD3D_SHADER_RESOURCE_DATA_UINT, flags);
+            sampler->register_first, sampler->register_last, VKD3D_SHADER_RESOURCE_NONE,
+            VKD3D_SHADER_RESOURCE_DATA_UINT, flags);
 }
 
 static void vkd3d_shader_scan_resource_declaration(struct vkd3d_shader_scan_context *context,
@@ -667,7 +668,7 @@ static void vkd3d_shader_scan_resource_declaration(struct vkd3d_shader_scan_cont
     else
         type = VKD3D_SHADER_DESCRIPTOR_TYPE_SRV;
     vkd3d_shader_scan_add_descriptor(context, type, resource->register_space,
-            resource->register_index, resource_type, resource_data_type, 0);
+            resource->register_first, resource->register_last, resource_type, resource_data_type, 0);
     if (type == VKD3D_SHADER_DESCRIPTOR_TYPE_UAV)
         vkd3d_shader_scan_add_uav_range(context, resource->reg.reg.idx[0].offset,
                 context->scan_descriptor_info->descriptor_count - 1);
diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h
index 6d756e40..54930fa2 100644
--- a/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -640,7 +640,7 @@ struct vkd3d_shader_resource
 {
     struct vkd3d_shader_dst_param reg;
     unsigned int register_space;
-    unsigned int register_index;
+    unsigned int register_first, register_last;
 };
 
 enum vkd3d_decl_usage
@@ -715,14 +715,16 @@ struct vkd3d_shader_register_semantic
 struct vkd3d_shader_sampler
 {
     struct vkd3d_shader_src_param src;
-    unsigned int register_space, register_index;
+    unsigned int register_space;
+    unsigned int register_first, register_last;
 };
 
 struct vkd3d_shader_constant_buffer
 {
     struct vkd3d_shader_src_param src;
     unsigned int size;
-    unsigned int register_space, register_index;
+    unsigned int register_space;
+    unsigned int register_first, register_last;
 };
 
 struct vkd3d_shader_structured_resource
-- 
2.31.1




More information about the wine-devel mailing list