From: Conor McCarthy cmccarthy@codeweavers.com
--- libs/vkd3d-shader/dxil.c | 96 +++++++++++++++++++++++- libs/vkd3d-shader/vkd3d_shader_private.h | 6 ++ 2 files changed, 98 insertions(+), 4 deletions(-)
diff --git a/libs/vkd3d-shader/dxil.c b/libs/vkd3d-shader/dxil.c index 283bcfa27..9abf91a77 100644 --- a/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d-shader/dxil.c @@ -247,6 +247,7 @@ enum dx_intrinsic_opcode DX_LOAD_INPUT = 4, DX_STORE_OUTPUT = 5, DX_CREATE_HANDLE = 57, + DX_CBUFFER_LOAD_LEGACY = 59, };
struct sm6_pointer_info @@ -1575,6 +1576,11 @@ static const struct sm6_type *sm6_type_get_scalar_type(const struct sm6_type *ty } }
+static unsigned int sm6_type_max_vector_size(const struct sm6_type *type) +{ + return min((VKD3D_VEC4_SIZE * sizeof(uint32_t) * CHAR_BIT) / type->u.width, VKD3D_VEC4_SIZE); +} + static const struct sm6_type *sm6_parser_get_type(struct sm6_parser *sm6, uint64_t type_id) { if (type_id >= sm6->type_count) @@ -1679,7 +1685,7 @@ static const char *sm6_parser_get_global_symbol_name(const struct sm6_parser *sm
static unsigned int register_get_uint_value(const struct vkd3d_shader_register *reg) { - if (!register_is_constant(reg) || !data_type_is_integer(reg->data_type)) + if (!register_is_constant(reg) || (!data_type_is_integer(reg->data_type) && !data_type_is_bool(reg->data_type))) return UINT_MAX;
if (reg->dimension == VSIR_DIMENSION_VEC4) @@ -1728,6 +1734,11 @@ static inline bool sm6_value_is_register(const struct sm6_value *value) return value->value_type == VALUE_TYPE_REG; }
+static bool sm6_value_is_handle(const struct sm6_value *value) +{ + return value->value_type == VALUE_TYPE_HANDLE; +} + static inline bool sm6_value_is_constant(const struct sm6_value *value) { return sm6_value_is_register(value) && register_is_constant(&value->u.reg); @@ -1831,8 +1842,8 @@ static enum vkd3d_data_type vkd3d_data_type_from_sm6_type(const struct sm6_type return VKD3D_DATA_UINT; }
-static void register_init_ssa_scalar(struct vkd3d_shader_register *reg, const struct sm6_type *type, - struct sm6_parser *sm6) +static void register_init_ssa_vector(struct vkd3d_shader_register *reg, const struct sm6_type *type, + unsigned int component_count, struct sm6_parser *sm6) { enum vkd3d_data_type data_type; unsigned int id; @@ -1840,6 +1851,13 @@ static void register_init_ssa_scalar(struct vkd3d_shader_register *reg, const st id = sm6_parser_alloc_ssa_id(sm6); data_type = vkd3d_data_type_from_sm6_type(sm6_type_get_scalar_type(type, 0)); register_init_with_id(reg, VKD3DSPR_SSA, data_type, id); + reg->dimension = component_count > 1 ? VSIR_DIMENSION_VEC4 : VSIR_DIMENSION_SCALAR; +} + +static void register_init_ssa_scalar(struct vkd3d_shader_register *reg, const struct sm6_type *type, + struct sm6_parser *sm6) +{ + register_init_ssa_vector(reg, type, 1, sm6); }
static void dst_param_init(struct vkd3d_shader_dst_param *param) @@ -1856,6 +1874,13 @@ static inline void dst_param_init_scalar(struct vkd3d_shader_dst_param *param, u param->shift = 0; }
+static void dst_param_init_vector(struct vkd3d_shader_dst_param *param, unsigned int component_count) +{ + param->write_mask = (1u << component_count) - 1; + param->modifiers = 0; + param->shift = 0; +} + static void dst_param_init_ssa_scalar(struct vkd3d_shader_dst_param *param, const struct sm6_type *type, struct sm6_parser *sm6) { @@ -1881,6 +1906,14 @@ static void src_param_init_from_value(struct vkd3d_shader_src_param *param, cons param->reg = src->u.reg; }
+static void src_param_init_vector_from_reg(struct vkd3d_shader_src_param *param, + const struct vkd3d_shader_register *reg) +{ + param->swizzle = VKD3D_SHADER_NO_SWIZZLE; + param->modifiers = VKD3DSPSM_NONE; + param->reg = *reg; +} + static void register_address_init(struct vkd3d_shader_register *reg, unsigned int idx, const struct sm6_value *address, struct sm6_parser *sm6) { @@ -1913,6 +1946,17 @@ static void instruction_dst_param_init_ssa_scalar(struct vkd3d_shader_instructio dst->u.reg = param->reg; }
+static void instruction_dst_param_init_ssa_vector(struct vkd3d_shader_instruction *ins, + unsigned int component_count, struct sm6_parser *sm6) +{ + struct vkd3d_shader_dst_param *param = instruction_dst_params_alloc(ins, 1, sm6); + struct sm6_value *dst = sm6_parser_get_current_value(sm6); + + dst_param_init_vector(param, component_count); + register_init_ssa_vector(¶m->reg, sm6_type_get_scalar_type(dst->type, 0), component_count, sm6); + dst->u.reg = param->reg; +} + /* Recurse through the block tree while maintaining a current value count. The current * count is the sum of the global count plus all declarations within the current function. * Store into value_capacity the highest count seen. */ @@ -1977,6 +2021,18 @@ static size_t sm6_parser_get_value_index(struct sm6_parser *sm6, uint64_t idx) return i; }
+static bool sm6_value_validate_is_handle(const struct sm6_value *value, struct sm6_parser *sm6) +{ + if (!sm6_value_is_handle(value)) + { + WARN("Handle parameter of type %u is not a handle.\n", value->value_type); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCE_HANDLE, + "A handle parameter passed to a DX intrinsic function is not a handle."); + return false; + } + return true; +} + static const struct sm6_value *sm6_parser_get_value_safe(struct sm6_parser *sm6, unsigned int idx) { if (idx < sm6->value_count) @@ -2555,6 +2611,35 @@ static const struct vkd3d_shader_descriptor_info1 *parser_get_descriptor(struct return NULL; }
+static void sm6_parser_emit_dx_cbuffer_load(struct sm6_parser *sm6, struct sm6_block *code_block, + enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct vkd3d_shader_instruction *ins) +{ + struct sm6_value *dst = sm6_parser_get_current_value(sm6); + unsigned int component_count = VKD3D_VEC4_SIZE; + struct vkd3d_shader_src_param *src_param; + const struct sm6_value *buffer; + const struct sm6_type *type; + + buffer = operands[0]; + if (!sm6_value_validate_is_handle(buffer, sm6)) + return; + + vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV); + + src_param = instruction_src_params_alloc(ins, 1, sm6); + src_param_init_vector_from_reg(src_param, &buffer->u.handle.reg); + + type = sm6_type_get_scalar_type(dst->type, 0); + assert(type); + src_param->reg.data_type = vkd3d_data_type_from_sm6_type(type); + component_count = sm6_type_max_vector_size(type); + + register_address_init(&src_param->reg, 2, operands[1], sm6); + src_param->reg.idx_count = 3; + + instruction_dst_param_init_ssa_vector(ins, component_count, sm6); +} + static void sm6_parser_emit_dx_create_handle(struct sm6_parser *sm6, struct sm6_block *code_block, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct vkd3d_shader_instruction *ins) { @@ -2700,6 +2785,7 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] = { [DX_LOAD_INPUT ] = {'o', "ii8i", sm6_parser_emit_dx_load_input}, [DX_STORE_OUTPUT ] = {'v', "ii8o", sm6_parser_emit_dx_store_output}, + [DX_CBUFFER_LOAD_LEGACY ] = {'o', "Hi", sm6_parser_emit_dx_cbuffer_load}, [DX_CREATE_HANDLE ] = {'H', "8ii1", sm6_parser_emit_dx_create_handle}, };
@@ -2747,7 +2833,9 @@ static bool sm6_parser_validate_dx_op(struct sm6_parser *sm6, enum dx_intrinsic_ for (i = 0; i < operand_count; ++i) { const struct sm6_value *value = operands[i]; - if (!sm6_value_is_register(value) || !sm6_parser_validate_operand_type(sm6, value->type, info->operand_info[i])) + char info_type = info->operand_info[i]; + bool value_is_valid = (info_type == 'H') ? sm6_value_is_handle(value) : sm6_value_is_register(value); + if (!value_is_valid || !sm6_parser_validate_operand_type(sm6, value->type, info_type)) { WARN("Failed to validate operand %u for dx intrinsic id %u, '%s'.\n", i + 1, op, name); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 71731b632..b67c0190b 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -181,6 +181,7 @@ enum vkd3d_shader_error VKD3D_SHADER_ERROR_DXIL_INVALID_SIGNATURE = 8016, VKD3D_SHADER_ERROR_DXIL_INVALID_PROPERTIES = 8017, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES = 8018, + VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCE_HANDLE = 8019,
VKD3D_SHADER_WARNING_DXIL_UNKNOWN_MAGIC_NUMBER = 8300, VKD3D_SHADER_WARNING_DXIL_UNKNOWN_SHADER_TYPE = 8301, @@ -583,6 +584,11 @@ static inline bool data_type_is_integer(enum vkd3d_data_type data_type) || data_type == VKD3D_DATA_UINT64; }
+static inline bool data_type_is_bool(enum vkd3d_data_type data_type) +{ + return data_type == VKD3D_DATA_BOOL; +} + enum vsir_dimension { VSIR_DIMENSION_NONE,