Based on register loading code from Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Conor McCarthy cmccarthy@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