[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