[PATCH vkd3d v2 2/3] vkd3d-shader: Parse SM5.1 register ranges.

Conor McCarthy cmccarthy at codeweavers.com
Thu Jun 3 00:01:23 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/vkd3d_shader_main.c    |  17 ++--
 libs/vkd3d-shader/vkd3d_shader_private.h |   8 +-
 3 files changed, 97 insertions(+), 49 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/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