Goes atop MR 403, 401 and 408. The last four commits belong to this MR.
-- v2: vkd3d-shader/dxil: Implement the DXIL BINOP instruction. vkd3d-shader/spirv: Handle the UMUL instruction. vkd3d-shader/spirv: Introduce an IDIV instruction. vkd3d-shader/spirv: Introduce an FREM instruction. vkd3d-shader/dxil: Implement the DXIL EXTRACTVAL instruction. vkd3d-shader/spirv: Support scalar swizzle of vector SSA registers. vkd3d-shader/dxil: Implement DX instruction CBufferLoadLegacy. vkd3d-shader/dxil: Implement DX instruction CreateHandle. vkd3d-shader/dxil: Replace register_address_init() with register_index_address_init().
From: Conor McCarthy cmccarthy@codeweavers.com
Makes it much clearer which register index is being written. --- libs/vkd3d-shader/dxil.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-)
diff --git a/libs/vkd3d-shader/dxil.c b/libs/vkd3d-shader/dxil.c index 19ce2936..30d3dff0 100644 --- a/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d-shader/dxil.c @@ -1861,25 +1861,24 @@ static void src_param_init_from_value(struct vkd3d_shader_src_param *param, cons param->reg = src->u.reg; }
-static void register_address_init(struct vkd3d_shader_register *reg, const struct sm6_value *address, - unsigned int idx, struct sm6_parser *sm6) +static void register_index_address_init(struct vkd3d_shader_register_index *idx, const struct sm6_value *address, + struct sm6_parser *sm6) { - assert(idx < ARRAY_SIZE(reg->idx)); if (sm6_value_is_constant(address)) { - reg->idx[idx].offset = sm6_value_get_constant_uint(address); + idx->offset = sm6_value_get_constant_uint(address); } else if (sm6_value_is_undef(address)) { - reg->idx[idx].offset = 0; + idx->offset = 0; } else { struct vkd3d_shader_src_param *rel_addr = shader_parser_get_src_params(&sm6->p, 1); if (rel_addr) src_param_init_from_value(rel_addr, address); - reg->idx[idx].offset = 0; - reg->idx[idx].rel_addr = rel_addr; + idx->offset = 0; + idx->rel_addr = rel_addr; } }
@@ -2546,7 +2545,7 @@ static void sm6_parser_emit_dx_load_input(struct sm6_parser *sm6, struct sm6_blo src_param->reg = sm6->input_params[row_index].reg; src_param_init_scalar(src_param, column_index); if (e->register_count > 1) - register_address_init(&src_param->reg, operands[1], 0, sm6); + register_index_address_init(&src_param->reg.idx[0], operands[1], sm6);
instruction_dst_param_init_ssa_scalar(ins, sm6); } @@ -2598,7 +2597,7 @@ static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, struct sm6_b dst_param_init_scalar(dst_param, column_index); dst_param->reg = sm6->output_params[row_index].reg; if (e->register_count > 1) - register_address_init(&dst_param->reg, operands[1], 0, sm6); + register_index_address_init(&dst_param->reg.idx[0], operands[1], sm6);
if ((src_param = instruction_src_params_alloc(ins, 1, sm6))) src_param_init_from_value(src_param, value);
From: Conor McCarthy cmccarthy@codeweavers.com
--- libs/vkd3d-shader/dxil.c | 153 ++++++++++++++++++++--- libs/vkd3d-shader/vkd3d_shader_private.h | 1 + 2 files changed, 140 insertions(+), 14 deletions(-)
diff --git a/libs/vkd3d-shader/dxil.c b/libs/vkd3d-shader/dxil.c index 30d3dff0..f065411c 100644 --- a/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d-shader/dxil.c @@ -246,6 +246,7 @@ enum dx_intrinsic_opcode { DX_LOAD_INPUT = 4, DX_STORE_OUTPUT = 5, + DX_CREATE_HANDLE = 57, };
struct sm6_pointer_info @@ -305,6 +306,7 @@ enum sm6_value_type { VALUE_TYPE_FUNCTION, VALUE_TYPE_REG, + VALUE_TYPE_HANDLE, };
struct sm6_function_data @@ -314,6 +316,12 @@ struct sm6_function_data unsigned int attribs_id; };
+struct sm6_handle_data +{ + const struct sm6_descriptor_info *d; + struct vkd3d_shader_register reg; +}; + struct sm6_value { const struct sm6_type *type; @@ -323,6 +331,7 @@ struct sm6_value { struct sm6_function_data function; struct vkd3d_shader_register reg; + struct sm6_handle_data handle; } u; };
@@ -427,6 +436,13 @@ struct sm6_named_metadata struct sm6_metadata_value value; };
+struct sm6_descriptor_info +{ + enum vkd3d_shader_descriptor_type type; + unsigned int id; + struct vkd3d_shader_register_range range; +}; + struct sm6_parser { const uint32_t *ptr, *start, *end; @@ -442,6 +458,7 @@ struct sm6_parser struct sm6_type *types; size_t type_count; struct sm6_type *metadata_type; + struct sm6_type *handle_type;
struct sm6_symbol *global_symbols; size_t global_symbol_count; @@ -458,6 +475,10 @@ struct sm6_parser struct sm6_named_metadata *named_metadata; unsigned int named_metadata_count;
+ struct sm6_descriptor_info *descriptors; + size_t descriptor_capacity; + size_t descriptor_count; + struct sm6_value *values; size_t value_count; size_t value_capacity; @@ -1391,6 +1412,9 @@ static enum vkd3d_result sm6_parser_type_table_init(struct sm6_parser *sm6) break; }
+ if (!ascii_strcasecmp(struct_name, "dx.types.Handle")) + sm6->handle_type = type; + type->u.struc->name = struct_name; struct_name = NULL; break; @@ -1438,6 +1462,11 @@ static inline bool sm6_type_is_integer(const struct sm6_type *type) return type->class == TYPE_CLASS_INTEGER; }
+static bool sm6_type_is_bool(const struct sm6_type *type) +{ + return type->class == TYPE_CLASS_INTEGER && type->u.width == 1; +} + static inline bool sm6_type_is_i8(const struct sm6_type *type) { return type->class == TYPE_CLASS_INTEGER && type->u.width == 8; @@ -1710,6 +1739,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); @@ -1782,6 +1816,8 @@ static enum vkd3d_data_type vkd3d_data_type_from_sm6_type(const struct sm6_type { switch (type->u.width) { + case 1: + return VKD3D_DATA_BOOL; case 8: return VKD3D_DATA_UINT8; case 32: @@ -2518,6 +2554,66 @@ static struct sm6_block *sm6_block_create() return block; }
+static const struct sm6_descriptor_info *sm6_parser_get_descriptor(struct sm6_parser *sm6, + enum vkd3d_shader_descriptor_type type, unsigned int id, const struct sm6_value *address) +{ + const struct sm6_descriptor_info *d; + unsigned int register_index; + size_t i; + + for (i = 0; i < sm6->descriptor_count; ++i) + { + d = &sm6->descriptors[i]; + + if (d->type != type || d->id != id) + continue; + + if (!sm6_value_is_constant(address)) + return d; + + register_index = sm6_value_get_constant_uint(address); + if (register_index >= d->range.first && register_index <= d->range.last) + return d; + } + + return NULL; +} + +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) +{ + enum vkd3d_shader_descriptor_type type; + const struct sm6_descriptor_info *d; + struct vkd3d_shader_register *reg; + struct sm6_value *dst; + unsigned int id; + + type = sm6_value_get_constant_uint(operands[0]); + id = sm6_value_get_constant_uint(operands[1]); + if (!(d = sm6_parser_get_descriptor(sm6, type, id, operands[2]))) + { + WARN("Failed to find resource type %#x, id %#x.\n", type, id); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, + "Descriptor for resource type %#x, id %#x was not found.", type, id); + return; + } + + dst = sm6_parser_get_current_value(sm6); + dst->value_type = VALUE_TYPE_HANDLE; + dst->u.handle.d = d; + + reg = &dst->u.handle.reg; + /* Set idx_count to 3 for use with load/store instructions. + * TODO: set register type from resource type when other types are supported. */ + vsir_register_init(reg, VKD3DSPR_CONSTBUFFER, VKD3D_DATA_FLOAT, 3); + reg->idx[0].offset = id; + register_index_address_init(®->idx[1], operands[2], sm6); + reg->non_uniform = !!sm6_value_get_constant_uint(operands[3]); + + /* NOP is used to flag no instruction emitted. */ + ins->handler_idx = VKD3DSIH_NOP; +} + static void sm6_parser_emit_dx_load_input(struct sm6_parser *sm6, struct sm6_block *code_block, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct vkd3d_shader_instruction *ins) { @@ -2613,7 +2709,10 @@ struct sm6_dx_opcode_info
/* 8 -> int8 + b -> constant int1 + c -> constant int8/16/32 i -> int32 + H -> handle v -> void o -> overloaded */ @@ -2621,10 +2720,17 @@ 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_CREATE_HANDLE ] = {'H', "ccib", sm6_parser_emit_dx_create_handle}, };
-static bool sm6_parser_validate_operand_type(struct sm6_parser *sm6, const struct sm6_type *type, char info_type) +static bool sm6_parser_validate_operand_type(struct sm6_parser *sm6, const struct sm6_value *value, char info_type, + bool is_return) { + const struct sm6_type *type = value->type; + + if (info_type != 'H' && !sm6_value_is_register(value)) + return false; + switch (info_type) { case 0: @@ -2632,8 +2738,15 @@ static bool sm6_parser_validate_operand_type(struct sm6_parser *sm6, const struc return false; case '8': return sm6_type_is_i8(type); + case 'b': + return sm6_value_is_constant(value) && sm6_type_is_bool(type); + case 'c': + return sm6_value_is_constant(value) && sm6_type_is_integer(type) && type->u.width >= 8 + && type->u.width <= 32; case 'i': return sm6_type_is_i32(type); + case 'H': + return (is_return || sm6_value_is_handle(value)) && type == sm6->handle_type; case 'v': return !type; case 'o': @@ -2653,7 +2766,7 @@ static bool sm6_parser_validate_dx_op(struct sm6_parser *sm6, enum dx_intrinsic_
info = &sm6_dx_op_table[op];
- if (!sm6_parser_validate_operand_type(sm6, dst->type, info->ret_type)) + if (!sm6_parser_validate_operand_type(sm6, dst, info->ret_type, true)) { WARN("Failed to validate return type for dx intrinsic id %u, '%s'.\n", op, name); /* Return type validation failure is not so critical. We only need to set @@ -2663,7 +2776,7 @@ 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])) + if (!sm6_parser_validate_operand_type(sm6, value, info->operand_info[i], false)) { 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, @@ -3422,8 +3535,7 @@ static bool sm6_parser_resources_load_register_range(struct sm6_parser *sm6, }
static enum vkd3d_result sm6_parser_resources_load_cbv(struct sm6_parser *sm6, - const struct sm6_metadata_node *node, const struct vkd3d_shader_register_range *range, - unsigned int register_id, struct vkd3d_shader_instruction *ins) + const struct sm6_metadata_node *node, struct sm6_descriptor_info *d, struct vkd3d_shader_instruction *ins) { struct vkd3d_shader_register *reg; unsigned int buffer_size; @@ -3458,11 +3570,11 @@ static enum vkd3d_result sm6_parser_resources_load_cbv(struct sm6_parser *sm6,
reg = &ins->declaration.cb.src.reg; vsir_register_init(reg, VKD3DSPR_CONSTBUFFER, VKD3D_DATA_FLOAT, 3); - reg->idx[0].offset = register_id; - reg->idx[1].offset = range->first; - reg->idx[2].offset = range->last; + reg->idx[0].offset = d->id; + reg->idx[1].offset = d->range.first; + reg->idx[2].offset = d->range.last;
- ins->declaration.cb.range = *range; + ins->declaration.cb.range = d->range;
return VKD3D_OK; } @@ -3470,12 +3582,12 @@ static enum vkd3d_result sm6_parser_resources_load_cbv(struct sm6_parser *sm6, static enum vkd3d_result sm6_parser_descriptor_type_init(struct sm6_parser *sm6, enum vkd3d_shader_descriptor_type type, const struct sm6_metadata_node *descriptor_node) { - struct vkd3d_shader_register_range range; struct vkd3d_shader_instruction *ins; const struct sm6_metadata_node *node; const struct sm6_metadata_value *m; - unsigned int i, register_id; + struct sm6_descriptor_info *d; enum vkd3d_result ret; + unsigned int i;
for (i = 0; i < descriptor_node->operand_count; ++i) { @@ -3497,7 +3609,18 @@ static enum vkd3d_result sm6_parser_descriptor_type_init(struct sm6_parser *sm6, return VKD3D_ERROR_INVALID_SHADER; }
- if (!sm6_metadata_get_uint_value(sm6, node->operands[0], ®ister_id)) + if (!vkd3d_array_reserve((void **)&sm6->descriptors, &sm6->descriptor_capacity, + sm6->descriptor_count + 1, sizeof(*sm6->descriptors))) + { + ERR("Failed to allocate descriptor array.\n"); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, + "Out of memory allocating the descriptor array."); + return VKD3D_ERROR_OUT_OF_MEMORY; + } + d = &sm6->descriptors[sm6->descriptor_count]; + d->type = type; + + if (!sm6_metadata_get_uint_value(sm6, node->operands[0], &d->id)) { WARN("Failed to load resource id.\n"); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES, @@ -3505,7 +3628,7 @@ static enum vkd3d_result sm6_parser_descriptor_type_init(struct sm6_parser *sm6, return VKD3D_ERROR_INVALID_SHADER; }
- if (!sm6_parser_resources_load_register_range(sm6, node, &range)) + if (!sm6_parser_resources_load_register_range(sm6, node, &d->range)) { vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES, "Resource register range is invalid."); @@ -3521,7 +3644,7 @@ static enum vkd3d_result sm6_parser_descriptor_type_init(struct sm6_parser *sm6, switch (type) { case VKD3D_SHADER_DESCRIPTOR_TYPE_CBV: - if ((ret = sm6_parser_resources_load_cbv(sm6, node, &range, register_id, ins)) < 0) + if ((ret = sm6_parser_resources_load_cbv(sm6, node, d, ins)) < 0) return ret; break; default: @@ -3531,6 +3654,7 @@ static enum vkd3d_result sm6_parser_descriptor_type_init(struct sm6_parser *sm6, return VKD3D_ERROR_INVALID_SHADER; }
+ ++sm6->descriptor_count; ++sm6->p.instructions.count; }
@@ -4131,6 +4255,7 @@ static void sm6_parser_destroy(struct vkd3d_shader_parser *parser) sm6_symtab_cleanup(sm6->global_symbols, sm6->global_symbol_count); sm6_functions_cleanup(sm6->functions, sm6->function_count); sm6_parser_metadata_cleanup(sm6); + vkd3d_free(sm6->descriptors); vkd3d_free(sm6->values); free_shader_desc(&parser->shader_desc); vkd3d_free(sm6); diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index c9d2dec8..b90c5be0 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -574,6 +574,7 @@ enum vkd3d_data_type VKD3D_DATA_UNUSED, VKD3D_DATA_UINT8, VKD3D_DATA_UINT64, + VKD3D_DATA_BOOL, };
static inline bool data_type_is_integer(enum vkd3d_data_type data_type)
From: Conor McCarthy cmccarthy@codeweavers.com
--- libs/vkd3d-shader/dxil.c | 84 +++++++++++++++++++++++- libs/vkd3d-shader/vkd3d_shader_private.h | 6 ++ 2 files changed, 87 insertions(+), 3 deletions(-)
diff --git a/libs/vkd3d-shader/dxil.c b/libs/vkd3d-shader/dxil.c index f065411c..dec63650 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 @@ -1586,6 +1587,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) @@ -1690,7 +1696,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) @@ -1847,8 +1853,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; @@ -1856,6 +1862,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) @@ -1872,6 +1885,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) { @@ -1897,6 +1917,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_index_address_init(struct vkd3d_shader_register_index *idx, const struct sm6_value *address, struct sm6_parser *sm6) { @@ -1928,6 +1956,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. */ @@ -1992,6 +2031,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) @@ -2554,6 +2605,32 @@ static struct sm6_block *sm6_block_create() return block; }
+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); + 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); + register_index_address_init(&src_param->reg.idx[2], operands[1], sm6); + assert(src_param->reg.idx_count == 3); + + type = sm6_type_get_scalar_type(dst->type, 0); + assert(type); + src_param->reg.data_type = vkd3d_data_type_from_sm6_type(type); + + instruction_dst_param_init_ssa_vector(ins, sm6_type_max_vector_size(type), sm6); +} + static const struct sm6_descriptor_info *sm6_parser_get_descriptor(struct sm6_parser *sm6, enum vkd3d_shader_descriptor_type type, unsigned int id, const struct sm6_value *address) { @@ -2720,6 +2797,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', "ccib", sm6_parser_emit_dx_create_handle}, };
diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index b90c5be0..e79a9f3c 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,
From: Conor McCarthy cmccarthy@codeweavers.com
--- libs/vkd3d-shader/spirv.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index 2dab97cc..6e456f2b 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -3523,6 +3523,11 @@ static bool vkd3d_swizzle_is_equal(unsigned int dst_write_mask, return vkd3d_compact_swizzle(VKD3D_SHADER_NO_SWIZZLE, dst_write_mask) == vkd3d_compact_swizzle(swizzle, write_mask); }
+static bool vkd3d_swizzle_is_scalar(unsigned int swizzle) +{ + return swizzle == (swizzle | (swizzle << VKD3D_SHADER_SWIZZLE_SHIFT(1))); +} + static uint32_t spirv_compiler_emit_swizzle(struct spirv_compiler *compiler, uint32_t val_id, unsigned int val_write_mask, enum vkd3d_shader_component_type component_type, unsigned int swizzle, unsigned int write_mask) @@ -3725,6 +3730,26 @@ static void spirv_compiler_set_ssa_register_id(const struct spirv_compiler *comp compiler->ssa_register_ids[i] = val_id; }
+static uint32_t spirv_compiler_emit_load_ssa_reg(struct spirv_compiler *compiler, + const struct vkd3d_shader_register *reg, enum vkd3d_shader_component_type component_type, + unsigned int swizzle) +{ + struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; + unsigned int component_idx; + uint32_t type_id, val_id; + + val_id = spirv_compiler_get_ssa_register_id(compiler, reg); + assert(val_id); + assert(vkd3d_swizzle_is_scalar(swizzle)); + + if (reg->dimension == VSIR_DIMENSION_SCALAR) + return val_id; + + type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); + component_idx = vkd3d_swizzle_get_component(swizzle, 0); + return vkd3d_spirv_build_op_composite_extract1(builder, type_id, val_id, component_idx); +} + static uint32_t spirv_compiler_emit_load_reg(struct spirv_compiler *compiler, const struct vkd3d_shader_register *reg, DWORD swizzle, DWORD write_mask) { @@ -3746,7 +3771,7 @@ static uint32_t spirv_compiler_emit_load_reg(struct spirv_compiler *compiler, component_type = vkd3d_component_type_from_data_type(reg->data_type);
if (reg->type == VKD3DSPR_SSA) - return spirv_compiler_get_ssa_register_id(compiler, reg); + return spirv_compiler_emit_load_ssa_reg(compiler, reg, component_type, swizzle);
if (!spirv_compiler_get_register_info(compiler, reg, ®_info)) {
From: Conor McCarthy cmccarthy@codeweavers.com
--- libs/vkd3d-shader/dxil.c | 92 +++++++++++++++++++++ tests/hlsl/asfloat.shader_test | 2 +- tests/hlsl/cbuffer.shader_test | 16 ++-- tests/hlsl/expr-indexing.shader_test | 4 +- tests/hlsl/half.shader_test | 2 +- tests/hlsl/majority-pragma.shader_test | 26 +++--- tests/hlsl/majority-syntax.shader_test | 2 +- tests/hlsl/matrix-indexing.shader_test | 8 +- tests/hlsl/nested-arrays.shader_test | 2 +- tests/hlsl/object-field-offsets.shader_test | 4 +- tests/hlsl/storage-qualifiers.shader_test | 2 +- tests/hlsl/struct-array.shader_test | 2 +- tests/hlsl/swizzle-matrix.shader_test | 14 ++-- tests/hlsl/swizzles.shader_test | 6 +- tests/hlsl/uniform-semantics.shader_test | 4 +- tests/hlsl/vector-indexing.shader_test | 2 +- 16 files changed, 140 insertions(+), 48 deletions(-)
diff --git a/libs/vkd3d-shader/dxil.c b/libs/vkd3d-shader/dxil.c index dec63650..4bf7addc 100644 --- a/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d-shader/dxil.c @@ -1483,6 +1483,11 @@ static inline bool sm6_type_is_floating_point(const struct sm6_type *type) return type->class == TYPE_CLASS_FLOAT; }
+static bool sm6_type_is_scalar(const struct sm6_type *type) +{ + return type->class == TYPE_CLASS_INTEGER || type->class == TYPE_CLASS_FLOAT || type->class == TYPE_CLASS_POINTER; +} + static inline bool sm6_type_is_numeric(const struct sm6_type *type) { return type->class == TYPE_CLASS_INTEGER || type->class == TYPE_CLASS_FLOAT; @@ -1493,6 +1498,11 @@ static inline bool sm6_type_is_pointer(const struct sm6_type *type) return type->class == TYPE_CLASS_POINTER; }
+static bool sm6_type_is_aggregate(const struct sm6_type *type) +{ + return type->class == TYPE_CLASS_STRUCT || type->class == TYPE_CLASS_VECTOR || type->class == TYPE_CLASS_ARRAY; +} + static bool sm6_type_is_numeric_aggregate(const struct sm6_type *type) { unsigned int i; @@ -1563,6 +1573,27 @@ static const struct sm6_type *sm6_type_get_pointer_to_type(const struct sm6_type return NULL; }
+/* Call for aggregate types only. */ +static const struct sm6_type *sm6_type_get_element_type_at_index(const struct sm6_type *type, uint64_t elem_idx) +{ + switch (type->class) + { + case TYPE_CLASS_ARRAY: + case TYPE_CLASS_VECTOR: + if (elem_idx >= type->u.array.count) + return NULL; + return type->u.array.elem_type; + + case TYPE_CLASS_STRUCT: + if (elem_idx >= type->u.struc->elem_count) + return NULL; + return type->u.struc->elem_types[elem_idx]; + + default: + vkd3d_unreachable(); + } +} + /* Never returns null for elem_idx 0. */ static const struct sm6_type *sm6_type_get_scalar_type(const struct sm6_type *type, unsigned int elem_idx) { @@ -2994,6 +3025,64 @@ static void sm6_parser_emit_call(struct sm6_parser *sm6, const struct dxil_recor fn_value->u.function.name, &operands[1], operand_count - 1, ins, dst); }
+static void sm6_parser_emit_extractval(struct sm6_parser *sm6, const struct dxil_record *record, + struct vkd3d_shader_instruction *ins, struct sm6_value *dst) +{ + struct vkd3d_shader_src_param *src_param; + const struct sm6_type *type; + const struct sm6_value *src; + unsigned int i = 0; + uint64_t elem_idx; + + if (!(src = sm6_parser_get_value_by_ref(sm6, record, NULL, &i))) + return; + + if (!dxil_record_validate_operand_min_count(record, i + 1, sm6)) + return; + + if (record->operand_count > i + 1) + { + FIXME("Unhandled multiple indices.\n"); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, + "Multiple extractval indices are not supported."); + return; + } + + type = src->type; + if (!sm6_type_is_aggregate(type)) + { + WARN("Invalid extraction from non-aggregate.\n"); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, + "Source type of an extractval instruction is not an aggregate."); + return; + } + + elem_idx = record->operands[i]; + if (!(type = sm6_type_get_element_type_at_index(type, elem_idx))) + { + WARN("Invalid element index %"PRIu64".\n", elem_idx); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, + "Element index %"PRIu64" for an extractval instruction is out of bounds.", elem_idx); + return; + } + if (!sm6_type_is_scalar(type)) + { + FIXME("Nested extraction is not supported.\n"); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, + "Extraction from nested aggregates is not supported."); + return; + } + dst->type = type; + + ins->handler_idx = VKD3DSIH_MOV; + + src_param = instruction_src_params_alloc(ins, 1, sm6); + src_param_init_from_value(src_param, src); + src_param->swizzle = vkd3d_shader_create_swizzle(elem_idx, elem_idx, elem_idx, elem_idx); + + instruction_dst_param_init_ssa_scalar(ins, sm6); +} + static void sm6_parser_emit_ret(struct sm6_parser *sm6, const struct dxil_record *record, struct sm6_block *code_block, struct vkd3d_shader_instruction *ins) { @@ -3149,6 +3238,9 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const case FUNC_CODE_INST_CALL: sm6_parser_emit_call(sm6, record, code_block, ins, dst); break; + case FUNC_CODE_INST_EXTRACTVAL: + sm6_parser_emit_extractval(sm6, record, ins, dst); + break; case FUNC_CODE_INST_RET: sm6_parser_emit_ret(sm6, record, code_block, ins); is_terminator = true; diff --git a/tests/hlsl/asfloat.shader_test b/tests/hlsl/asfloat.shader_test index d2c0f9aa..f43f2fdf 100644 --- a/tests/hlsl/asfloat.shader_test +++ b/tests/hlsl/asfloat.shader_test @@ -36,7 +36,7 @@ float4 main() : sv_target uniform 0 float4 11 12 0 0 uniform 4 float4 13 14 0 0 uniform 8 float4 20 21 22 23 -todo(sm>=6) draw quad +draw quad probe (320,240) rgba (13.0, 21.0, 0.0, 0.0)
[pixel shader fail] diff --git a/tests/hlsl/cbuffer.shader_test b/tests/hlsl/cbuffer.shader_test index 59dda97a..dbb49ea7 100644 --- a/tests/hlsl/cbuffer.shader_test +++ b/tests/hlsl/cbuffer.shader_test @@ -13,7 +13,7 @@ float4 main() : sv_target
[test] uniform 0 float4 1.0 2.0 3.0 4.0 -todo(sm>=6) draw quad +draw quad probe all rgba (1.0, 2.0, 3.0, 4.0)
[pixel shader] @@ -31,7 +31,7 @@ float4 main() : sv_target
[test] uniform 0 float4 1.0 2.0 3.0 4.0 -todo(sm>=6) draw quad +draw quad probe all rgba (1.0, 2.0, 3.0, 4.0)
% SM1 buffer offset allocation follows different rules than SM4. @@ -72,7 +72,7 @@ uniform 0 float4 0.0 1.0 2.0 3.0 uniform 4 float4 4.0 5.0 6.0 7.0 uniform 8 float4 8.0 9.0 10.0 11.0 uniform 12 float4 12.0 13.0 14.0 15.0 -todo(sm>=6) draw quad +draw quad probe all rgba (0.0, 2.0, 4.0, 8.0)
@@ -93,7 +93,7 @@ float4 main() : sv_target uniform 0 float4 0.0 1.0 2.0 3.0 uniform 4 float4 4.0 5.0 6.0 7.0 uniform 8 float4 8.0 9.0 10.0 11.0 -todo(sm>=6) draw quad +draw quad probe all rgba (0.0, 4.0, 8.0, 9.0)
@@ -119,7 +119,7 @@ uniform 0 float4 0.0 1.0 2.0 3.0 uniform 4 float4 4.0 5.0 6.0 7.0 uniform 8 float4 8.0 9.0 10.0 11.0 uniform 12 float4 12.0 13.0 14.0 15.0 -todo(sm>=6) draw quad +draw quad probe all rgba (0.0, 4.0, 5.0, 6.0)
@@ -142,7 +142,7 @@ uniform 0 float4 1.0 0.0 0.0 0.0 uniform 4 float4 2.0 0.0 0.0 0.0 uniform 8 float4 3.0 0.0 0.0 0.0 uniform 12 float4 4.0 0.0 0.0 0.0 -todo draw quad +todo(sm<6) draw quad probe all rgba (1.0, 3.0, 3.0, 4.0)
@@ -221,7 +221,7 @@ float4 main() : sv_target
[test] uniform 0 float4 1.0 2.0 3.0 4.0 -todo(sm>=6) draw quad +draw quad probe all rgba (2.0, 3.0, 2.0, 3.0)
@@ -357,7 +357,7 @@ float4 main() : sv_target
[test] uniform 0 float4 1.0 2.0 3.0 4.0 -todo(sm>=6) draw quad +draw quad probe all rgba (3.0, 4.0, 3.0, 4.0)
diff --git a/tests/hlsl/expr-indexing.shader_test b/tests/hlsl/expr-indexing.shader_test index 1816c6eb..1c598816 100644 --- a/tests/hlsl/expr-indexing.shader_test +++ b/tests/hlsl/expr-indexing.shader_test @@ -40,7 +40,7 @@ float4 main() : sv_target
[test] uniform 0 float4 1.0 2.0 3.0 4.0 -todo(sm>=6) draw quad +draw quad probe all rgba (3.0, 3.0, 3.0, 3.0)
@@ -78,7 +78,7 @@ float4 main() : sv_target
[test] uniform 0 float4 1.0 2.0 3.0 4.0 -todo(sm>=6) draw quad +draw quad probe all rgba (4.0, 4.0, 4.0, 4.0)
diff --git a/tests/hlsl/half.shader_test b/tests/hlsl/half.shader_test index 95610235..fe7074e4 100644 --- a/tests/hlsl/half.shader_test +++ b/tests/hlsl/half.shader_test @@ -19,5 +19,5 @@ float4 main() : sv_target
[test] uniform 0 float 10.0 -todo(sm>=6) draw quad +draw quad probe all rgba (10.0, 10.0, 10.0, 10.0) diff --git a/tests/hlsl/majority-pragma.shader_test b/tests/hlsl/majority-pragma.shader_test index f7baa90b..84dff63e 100644 --- a/tests/hlsl/majority-pragma.shader_test +++ b/tests/hlsl/majority-pragma.shader_test @@ -40,7 +40,7 @@ float4 main() : sv_target [test] uniform 0 float4 0.1 0.2 0.0 0.0 uniform 4 float4 0.3 0.4 0.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (0.1, 0.2, 0.3, 0.4)
@@ -61,7 +61,7 @@ uniform 0 float4 0.0 0.0 0.0 0.0 uniform 4 float4 0.0 0.0 0.0 0.0 uniform 8 float4 0.5 0.6 0.0 0.0 uniform 12 float4 0.7 0.8 0.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (0.5, 0.6, 0.7, 0.8)
@@ -111,7 +111,7 @@ float4 main() : sv_target [test] uniform 0 float4 0.1 0.2 0.0 0.0 uniform 4 float4 0.3 0.4 0.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (0.1, 0.2, 0.3, 0.4)
@@ -149,7 +149,7 @@ uniform 0 float4 0.3 0.4 0.0 0.0 uniform 4 float4 0.0 0.0 0.0 0.0 uniform 8 float4 0.0 0.0 0.0 0.0 uniform 12 float4 0.5 0.6 0.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (0.3, 0.4, 0.5, 0.6)
@@ -173,7 +173,7 @@ float4 main() : sv_target [test] uniform 0 float4 0.1 0.2 0.0 0.0 uniform 4 float4 0.3 0.4 0.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (0.1, 0.2, 0.3, 0.4)
@@ -201,7 +201,7 @@ float4 main() : sv_target [test] uniform 0 float4 0.2 0.4 0.0 0.0 uniform 4 float4 0.3 0.5 0.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (0.2, 0.3, 0.4, 0.5)
@@ -221,7 +221,7 @@ uniform 0 float4 0.3 0.0 0.0 0.0 uniform 4 float4 0.4 0.0 0.0 0.0 uniform 8 float4 0.0 0.5 0.0 0.0 uniform 12 float4 0.0 0.6 0.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (0.3, 0.4, 0.5, 0.6)
% Compiler options @@ -245,7 +245,7 @@ uniform 0 float4 0.1 0.5 0.9 1.3 uniform 4 float4 0.2 0.6 1.0 1.4 uniform 8 float4 0.3 0.7 1.1 1.5 uniform 12 float4 0.4 0.8 1.2 1.6 -todo(sm>=6) draw quad +draw quad probe all rgba (0.2, 0.3, 0.6, 0.7) 1
[require] @@ -267,7 +267,7 @@ uniform 0 float4 0.1 0.5 0.9 1.3 uniform 4 float4 0.2 0.6 1.0 1.4 uniform 8 float4 0.3 0.7 1.1 1.5 uniform 12 float4 0.4 0.8 1.2 1.6 -todo(sm>=6) draw quad +draw quad probe all rgba (0.2, 0.3, 0.6, 0.7) 1
[require] @@ -289,7 +289,7 @@ uniform 0 float4 0.1 0.5 0.9 1.3 uniform 4 float4 0.2 0.6 1.0 1.4 uniform 8 float4 0.3 0.7 1.1 1.5 uniform 12 float4 0.4 0.8 1.2 1.6 -todo(sm>=6) draw quad +draw quad probe all rgba (0.5, 0.9, 0.6, 1.0) 1
[require] @@ -317,7 +317,7 @@ uniform 16 float4 1.7 2.1 2.5 2.9 uniform 20 float4 1.8 2.2 2.6 3.0 uniform 24 float4 1.9 2.3 2.7 3.1 uniform 28 float4 2.0 2.4 2.8 3.2 -todo(sm>=6) draw quad +draw quad probe all rgba (0.3, 0.4, 2.5, 2.9) 1
[require] @@ -345,7 +345,7 @@ uniform 16 float4 1.7 2.1 2.5 2.9 uniform 20 float4 1.8 2.2 2.6 3.0 uniform 24 float4 1.9 2.3 2.7 3.1 uniform 28 float4 2.0 2.4 2.8 3.2 -todo(sm>=6) draw quad +draw quad probe all rgba (1.2, 1.6, 3.1, 3.2) 1
[require] @@ -365,5 +365,5 @@ float4 main() : sv_target [test] uniform 0 float4 0.1 0.2 0.0 0.0 uniform 4 float4 0.3 0.4 0.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (0.1, 0.3, 0.2, 0.4) 1 diff --git a/tests/hlsl/majority-syntax.shader_test b/tests/hlsl/majority-syntax.shader_test index 63e5d298..f1f5291f 100644 --- a/tests/hlsl/majority-syntax.shader_test +++ b/tests/hlsl/majority-syntax.shader_test @@ -11,7 +11,7 @@ float4 main() : sv_target [test] uniform 0 float4 0.1 0.3 0.0 0.0 uniform 4 float4 0.2 0.4 0.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (0.1, 0.3, 0.2, 0.4)
[pixel shader fail(sm<6)] diff --git a/tests/hlsl/matrix-indexing.shader_test b/tests/hlsl/matrix-indexing.shader_test index a61983ee..17003647 100644 --- a/tests/hlsl/matrix-indexing.shader_test +++ b/tests/hlsl/matrix-indexing.shader_test @@ -11,7 +11,7 @@ uniform 0 float4 1.0 2.0 3.0 4.0 uniform 4 float4 5.0 6.0 7.0 8.0 uniform 8 float4 9.0 10.0 11.0 12.0 uniform 12 float4 13.0 14.0 15.0 16.0 -todo(sm>=6) draw quad +draw quad probe all rgba (1.0, 2.0, 10.0, 15.0)
[pixel shader] @@ -27,7 +27,7 @@ uniform 0 float4 1.0 2.0 3.0 4.0 uniform 4 float4 5.0 6.0 7.0 8.0 uniform 8 float4 9.0 10.0 11.0 12.0 uniform 12 float4 13.0 14.0 15.0 16.0 -todo(sm>=6) draw quad +draw quad probe all rgba (1.0, 2.0, 10.0, 15.0)
[pixel shader] @@ -43,7 +43,7 @@ uniform 0 float4 1.0 2.0 3.0 4.0 uniform 4 float4 5.0 6.0 7.0 8.0 uniform 8 float4 9.0 10.0 11.0 12.0 uniform 12 float4 13.0 14.0 15.0 16.0 -todo(sm>=6) draw quad +draw quad probe all rgba (1.0, 5.0, 7.0, 12.0)
[pixel shader] @@ -58,7 +58,7 @@ float4 main() : SV_TARGET [test] uniform 0 float4 1.0 2.0 3.0 0.0 uniform 4 float4 5.0 6.0 7.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (1.0, 3.0, 6.0, 7.0)
[pixel shader] diff --git a/tests/hlsl/nested-arrays.shader_test b/tests/hlsl/nested-arrays.shader_test index b7aeec44..c9ba186b 100644 --- a/tests/hlsl/nested-arrays.shader_test +++ b/tests/hlsl/nested-arrays.shader_test @@ -21,5 +21,5 @@ uniform 8 float4 0.3 0.0 0.0 0.0 uniform 12 float4 0.4 0.0 0.0 0.0 uniform 16 float4 0.5 0.0 0.0 0.0 uniform 20 float4 0.6 0.0 0.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (0.4, 0.1, 0.6, 0.3) diff --git a/tests/hlsl/object-field-offsets.shader_test b/tests/hlsl/object-field-offsets.shader_test index d1741c3e..9cc4581b 100644 --- a/tests/hlsl/object-field-offsets.shader_test +++ b/tests/hlsl/object-field-offsets.shader_test @@ -19,7 +19,7 @@ float4 main() : sv_target [test] uniform 0 float4 1.0 2.0 3.0 4.0 uniform 4 float4 5.0 6.0 7.0 8.0 -todo(sm>=6) draw quad +draw quad probe all rgba (1.0, 2.0, 3.0, 0.0)
@@ -66,5 +66,5 @@ float4 main() : sv_target [test] uniform 0 float4 1.0 2.0 3.0 4.0 uniform 4 float4 5.0 6.0 7.0 8.0 -todo(sm>=6) draw quad +draw quad probe all rgba (1.0, 2.0, 5.0, 0.0) diff --git a/tests/hlsl/storage-qualifiers.shader_test b/tests/hlsl/storage-qualifiers.shader_test index 09385e3e..86cea471 100644 --- a/tests/hlsl/storage-qualifiers.shader_test +++ b/tests/hlsl/storage-qualifiers.shader_test @@ -42,5 +42,5 @@ void main(out float4 o : sv_target) [test] uniform 0 float4 0.1 0.0 0.0 0.0 uniform 4 float4 0.2 0.0 0.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (0.1, 0.2, 0.3, 0.4) diff --git a/tests/hlsl/struct-array.shader_test b/tests/hlsl/struct-array.shader_test index 4097f383..aff0a677 100644 --- a/tests/hlsl/struct-array.shader_test +++ b/tests/hlsl/struct-array.shader_test @@ -18,5 +18,5 @@ float4 main() : sv_target uniform 0 float4 0.1 0.2 0.0 0.0 uniform 4 float4 0.3 0.4 0.0 0.0 uniform 8 float4 0.5 0.6 0.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (0.2, 0.3, 0.6, 0.5) diff --git a/tests/hlsl/swizzle-matrix.shader_test b/tests/hlsl/swizzle-matrix.shader_test index 00552275..740d4d90 100644 --- a/tests/hlsl/swizzle-matrix.shader_test +++ b/tests/hlsl/swizzle-matrix.shader_test @@ -9,7 +9,7 @@ float4 main() : sv_target [test] uniform 0 float4 11 21 31 -1 uniform 4 float4 12 22 32 -1 -todo(sm>=6) draw quad +draw quad probe all rgba (21.0, 31.0, 11.0, 12.0)
@@ -24,7 +24,7 @@ float4 main() : sv_target [test] uniform 0 float4 11 21 31 -1 uniform 4 float4 12 22 32 -1 -todo(sm>=6) draw quad +draw quad probe all rgba (11.0, 31.0, 12.0, 32.0)
@@ -40,7 +40,7 @@ float4 main() : sv_target uniform 0 float4 11 12 -1 -1 uniform 4 float4 21 22 -1 -1 uniform 8 float4 31 32 -1 -1 -todo(sm>=6) draw quad +draw quad probe all rgba (11.0, 31.0, 12.0, 32.0)
@@ -169,8 +169,8 @@ float4 main() : sv_target
[test] uniform 0 float4 20 30 40 -1 -todo draw quad -todo probe all rgba (10.0, 20.0, 30.0, 40.0) +todo(sm<6) draw quad +todo(sm<6) probe all rgba (10.0, 20.0, 30.0, 40.0)
[pixel shader todo] @@ -187,8 +187,8 @@ float4 main() : sv_target
[test] uniform 0 float4 20 30 80 -1 -todo draw quad -todo probe all rgba (80.0, 30.0, 20.0, 10.0) +todo(sm<6) draw quad +todo(sm<6) probe all rgba (80.0, 30.0, 20.0, 10.0)
% Cannot repeat components when assigning to a swizzle. diff --git a/tests/hlsl/swizzles.shader_test b/tests/hlsl/swizzles.shader_test index ddfc09fc..c3d3343f 100644 --- a/tests/hlsl/swizzles.shader_test +++ b/tests/hlsl/swizzles.shader_test @@ -11,7 +11,7 @@ float4 main() : sv_target
[test] uniform 0 float4 0.0303 0.08 0.07 0.0202 -todo(sm>=6) draw quad +draw quad probe all rgba (0.0101, 0.0303, 0.0202, 0.0404)
@@ -149,7 +149,7 @@ float4 main() : sv_target
[test] uniform 0 float4 1.0 2.0 3.0 4.0 -todo(sm>=6) draw quad +draw quad probe all rgba (1.0, 2.0, 3.0, 4.0)
@@ -166,5 +166,5 @@ float4 main() : sv_target
[test] uniform 0 float4 1.0 2.0 3.0 4.0 -todo(sm>=6) draw quad +draw quad probe all rgba (1.0, 4.0, 2.0, 3.0) diff --git a/tests/hlsl/uniform-semantics.shader_test b/tests/hlsl/uniform-semantics.shader_test index 86e3b83f..1125117f 100644 --- a/tests/hlsl/uniform-semantics.shader_test +++ b/tests/hlsl/uniform-semantics.shader_test @@ -10,7 +10,7 @@ float4 main() : sv_target
[test] uniform 0 float 3.5 -todo(sm>=6) draw quad +draw quad probe all rgba (3.5, 3.5, 3.5, 3.5)
@@ -24,5 +24,5 @@ float4 main() : sv_target
[test] uniform 0 float4 4.0 5.0 6.0 7.0 -todo(sm>=6) draw quad +draw quad probe all rgba (4.0, 5.0, 4.0, 5.0) diff --git a/tests/hlsl/vector-indexing.shader_test b/tests/hlsl/vector-indexing.shader_test index 71a4ca26..9f6f9a2c 100644 --- a/tests/hlsl/vector-indexing.shader_test +++ b/tests/hlsl/vector-indexing.shader_test @@ -23,7 +23,7 @@ float4 main() : SV_TARGET
[test] uniform 0 float4 1.0 2.0 3.0 4.0 -todo(sm>=6) draw quad +draw quad probe all rgba (1.0, 2.0, 2.0, 3.0)
From: Conor McCarthy cmccarthy@codeweavers.com
--- libs/vkd3d-shader/d3d_asm.c | 1 + libs/vkd3d-shader/spirv.c | 2 ++ libs/vkd3d-shader/vkd3d_shader_private.h | 1 + 3 files changed, 4 insertions(+)
diff --git a/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d-shader/d3d_asm.c index 40daa535..210511e4 100644 --- a/libs/vkd3d-shader/d3d_asm.c +++ b/libs/vkd3d-shader/d3d_asm.c @@ -152,6 +152,7 @@ static const char * const shader_opcode_names[] = [VKD3DSIH_FIRSTBIT_LO ] = "firstbit_lo", [VKD3DSIH_FIRSTBIT_SHI ] = "firstbit_shi", [VKD3DSIH_FRC ] = "frc", + [VKD3DSIH_FREM ] = "frem", [VKD3DSIH_FTOD ] = "ftod", [VKD3DSIH_FTOI ] = "ftoi", [VKD3DSIH_FTOU ] = "ftou", diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index 6e456f2b..c9ce1c2a 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -6594,6 +6594,7 @@ static SpvOp spirv_compiler_map_alu_instruction(const struct vkd3d_shader_instru {VKD3DSIH_DTOF, SpvOpFConvert}, {VKD3DSIH_DTOI, SpvOpConvertFToS}, {VKD3DSIH_DTOU, SpvOpConvertFToU}, + {VKD3DSIH_FREM, SpvOpFRem}, {VKD3DSIH_FTOD, SpvOpFConvert}, {VKD3DSIH_IADD, SpvOpIAdd}, {VKD3DSIH_INEG, SpvOpSNegate}, @@ -9409,6 +9410,7 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, case VKD3DSIH_DTOF: case VKD3DSIH_DTOI: case VKD3DSIH_DTOU: + case VKD3DSIH_FREM: case VKD3DSIH_FTOD: case VKD3DSIH_IADD: case VKD3DSIH_INEG: diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index e79a9f3c..ead334ae 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -326,6 +326,7 @@ enum vkd3d_shader_opcode VKD3DSIH_FIRSTBIT_LO, VKD3DSIH_FIRSTBIT_SHI, VKD3DSIH_FRC, + VKD3DSIH_FREM, VKD3DSIH_FTOD, VKD3DSIH_FTOI, VKD3DSIH_FTOU,
From: Conor McCarthy cmccarthy@codeweavers.com
--- libs/vkd3d-shader/d3d_asm.c | 1 + libs/vkd3d-shader/spirv.c | 20 +++++++++----------- libs/vkd3d-shader/vkd3d_shader_private.h | 1 + 3 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d-shader/d3d_asm.c index 210511e4..645d9983 100644 --- a/libs/vkd3d-shader/d3d_asm.c +++ b/libs/vkd3d-shader/d3d_asm.c @@ -171,6 +171,7 @@ static const char * const shader_opcode_names[] = [VKD3DSIH_HS_JOIN_PHASE ] = "hs_join_phase", [VKD3DSIH_IADD ] = "iadd", [VKD3DSIH_IBFE ] = "ibfe", + [VKD3DSIH_IDIV ] = "idiv", [VKD3DSIH_IEQ ] = "ieq", [VKD3DSIH_IF ] = "if", [VKD3DSIH_IFC ] = "ifc", diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index c9ce1c2a..beffea22 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -1411,13 +1411,6 @@ static uint32_t vkd3d_spirv_build_op_udiv(struct vkd3d_spirv_builder *builder, SpvOpUDiv, result_type, operand0, operand1); }
-static uint32_t vkd3d_spirv_build_op_umod(struct vkd3d_spirv_builder *builder, - uint32_t result_type, uint32_t operand0, uint32_t operand1) -{ - return vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, - SpvOpUMod, result_type, operand0, operand1); -} - static uint32_t vkd3d_spirv_build_op_isub(struct vkd3d_spirv_builder *builder, uint32_t result_type, uint32_t operand0, uint32_t operand1) { @@ -7009,7 +7002,7 @@ static void spirv_compiler_emit_imad(struct spirv_compiler *compiler, spirv_compiler_emit_store_dst(compiler, dst, val_id); }
-static void spirv_compiler_emit_udiv(struct spirv_compiler *compiler, +static void spirv_compiler_emit_int_div(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { uint32_t type_id, val_id, src0_id, src1_id, condition_id, uint_max_id; @@ -7017,6 +7010,10 @@ static void spirv_compiler_emit_udiv(struct spirv_compiler *compiler, const struct vkd3d_shader_dst_param *dst = instruction->dst; const struct vkd3d_shader_src_param *src = instruction->src; unsigned int component_count = 0; + SpvOp div_op, mod_op; + + div_op = instruction->handler_idx == VKD3DSIH_IDIV ? SpvOpSDiv : SpvOpUDiv; + mod_op = instruction->handler_idx == VKD3DSIH_IDIV ? SpvOpSRem : SpvOpUMod;
if (dst[0].reg.type != VKD3DSPR_NULL) { @@ -7031,7 +7028,7 @@ static void spirv_compiler_emit_udiv(struct spirv_compiler *compiler, uint_max_id = spirv_compiler_get_constant_uint_vector(compiler, 0xffffffff, component_count);
- val_id = vkd3d_spirv_build_op_udiv(builder, type_id, src0_id, src1_id); + val_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, div_op, type_id, src0_id, src1_id); /* The SPIR-V spec says: "The resulting value is undefined if Operand 2 is 0." */ val_id = vkd3d_spirv_build_op_select(builder, type_id, condition_id, val_id, uint_max_id);
@@ -7054,7 +7051,7 @@ static void spirv_compiler_emit_udiv(struct spirv_compiler *compiler, 0xffffffff, component_count); }
- val_id = vkd3d_spirv_build_op_umod(builder, type_id, src0_id, src1_id); + val_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, mod_op, type_id, src0_id, src1_id); /* The SPIR-V spec says: "The resulting value is undefined if Operand 2 is 0." */ val_id = vkd3d_spirv_build_op_select(builder, type_id, condition_id, val_id, uint_max_id);
@@ -9469,8 +9466,9 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, case VKD3DSIH_IMAD: spirv_compiler_emit_imad(compiler, instruction); break; + case VKD3DSIH_IDIV: case VKD3DSIH_UDIV: - spirv_compiler_emit_udiv(compiler, instruction); + spirv_compiler_emit_int_div(compiler, instruction); break; case VKD3DSIH_FTOI: spirv_compiler_emit_ftoi(compiler, instruction); diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index ead334ae..1560edbe 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -345,6 +345,7 @@ enum vkd3d_shader_opcode VKD3DSIH_HS_JOIN_PHASE, VKD3DSIH_IADD, VKD3DSIH_IBFE, + VKD3DSIH_IDIV, VKD3DSIH_IEQ, VKD3DSIH_IF, VKD3DSIH_IFC,
From: Conor McCarthy cmccarthy@codeweavers.com
--- libs/vkd3d-shader/spirv.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index beffea22..35434b57 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -9461,6 +9461,7 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, spirv_compiler_emit_sincos(compiler, instruction); break; case VKD3DSIH_IMUL: + case VKD3DSIH_UMUL: spirv_compiler_emit_imul(compiler, instruction); break; case VKD3DSIH_IMAD:
From: Conor McCarthy cmccarthy@codeweavers.com
--- libs/vkd3d-shader/dxil.c | 221 ++++++++++++++++++ libs/vkd3d-shader/vkd3d_shader_private.h | 1 + .../hlsl/arithmetic-float-uniform.shader_test | 14 +- tests/hlsl/cbuffer.shader_test | 6 +- tests/hlsl/const.shader_test | 2 +- tests/hlsl/cross.shader_test | 4 +- tests/hlsl/dot.shader_test | 2 +- tests/hlsl/expr-indexing.shader_test | 2 +- tests/hlsl/lerp.shader_test | 2 +- tests/hlsl/loop.shader_test | 10 +- tests/hlsl/math.shader_test | 2 +- tests/hlsl/object-references.shader_test | 2 +- tests/hlsl/reflect.shader_test | 2 +- tests/hlsl/writemask-assignop-0.shader_test | 2 +- tests/hlsl/writemask-assignop-1.shader_test | 2 +- 15 files changed, 249 insertions(+), 25 deletions(-)
diff --git a/libs/vkd3d-shader/dxil.c b/libs/vkd3d-shader/dxil.c index 4bf7addc..2e8779de 100644 --- a/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d-shader/dxil.c @@ -242,6 +242,45 @@ enum dxil_shader_properties_tag SHADER_PROPERTIES_ENTRY_ROOT_SIG = 12, };
+enum dxil_binop_code +{ + BINOP_ADD = 0, + BINOP_SUB = 1, + BINOP_MUL = 2, + BINOP_UDIV = 3, + BINOP_SDIV = 4, + BINOP_UREM = 5, + BINOP_SREM = 6, + BINOP_SHL = 7, + BINOP_LSHR = 8, + BINOP_ASHR = 9, + BINOP_AND = 10, + BINOP_OR = 11, + BINOP_XOR = 12 +}; + +enum dxil_fast_fp_flags +{ + FP_ALLOW_UNSAFE_ALGEBRA = 0x1, + FP_NO_NAN = 0x2, + FP_NO_INF = 0x4, + FP_NO_SIGNED_ZEROS = 0x8, + FP_ALLOW_RECIPROCAL = 0x10, +}; + +enum dxil_overflowing_binop_flags +{ + /* Operation is known to never overflow. */ + OB_NO_UNSIGNED_WRAP = 0x1, + OB_NO_SIGNED_WRAP = 0x2, +}; + +enum dxil_possibly_exact_binop_flags +{ + /* "A udiv or sdiv instruction, which can be marked as "exact", indicating that no bits are destroyed." */ + PEB_EXACT = 0x1, +}; + enum dx_intrinsic_opcode { DX_LOAD_INPUT = 4, @@ -1463,6 +1502,11 @@ static inline bool sm6_type_is_integer(const struct sm6_type *type) return type->class == TYPE_CLASS_INTEGER; }
+static bool sm6_type_is_1wil(const struct sm6_type *type) +{ + return type->class == TYPE_CLASS_INTEGER && (type->u.width == 1 || type->u.width >= 16); +} + static bool sm6_type_is_bool(const struct sm6_type *type) { return type->class == TYPE_CLASS_INTEGER && type->u.width == 1; @@ -2636,6 +2680,180 @@ static struct sm6_block *sm6_block_create() return block; }
+static enum vkd3d_shader_opcode sm6_parser_decode_binary_op(struct sm6_parser *sm6, + uint64_t code, const struct sm6_type *type_a, const struct sm6_type *type_b) +{ + bool is_bool = sm6_type_is_bool(type_a); + bool is_int = sm6_type_is_1wil(type_a); + enum vkd3d_shader_opcode op; + bool is_valid; + + if (!is_int && !sm6_type_is_floating_point(type_a)) + { + WARN("Argument type %u is not bool, int16/32/64 or floating point.\n", type_a->class); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, + "An argument to a binary operation is not bool, int16/32/64 or floating point."); + return VKD3DSIH_INVALID; + } + if (type_a != type_b) + { + WARN("Type mismatch, type %u width %u vs type %u width %u.\n", type_a->class, + type_a->u.width, type_b->class, type_b->u.width); + vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_TYPE_MISMATCH, + "Type mismatch in binary operation arguments."); + } + + switch (code) + { + case BINOP_ADD: + case BINOP_SUB: + op = is_int ? VKD3DSIH_IADD : VKD3DSIH_ADD; + is_valid = !is_bool; + break; + case BINOP_AND: + op = VKD3DSIH_AND; + is_valid = is_int; + break; + case BINOP_ASHR: + op = VKD3DSIH_ISHR; + is_valid = is_int && !is_bool; + break; + case BINOP_LSHR: + op = VKD3DSIH_USHR; + is_valid = is_int && !is_bool; + break; + case BINOP_MUL: + op = is_int ? VKD3DSIH_UMUL : VKD3DSIH_MUL; + is_valid = !is_bool; + break; + case BINOP_OR: + op = VKD3DSIH_OR; + is_valid = is_int; + break; + case BINOP_SDIV: + op = is_int ? VKD3DSIH_IDIV : VKD3DSIH_DIV; + is_valid = !is_bool; + break; + case BINOP_SREM: + op = is_int ? VKD3DSIH_IDIV : VKD3DSIH_FREM; + is_valid = !is_bool; + break; + case BINOP_SHL: + op = VKD3DSIH_ISHL; + is_valid = is_int && !is_bool; + break; + case BINOP_UDIV: + case BINOP_UREM: + op = VKD3DSIH_UDIV; + is_valid = is_int && !is_bool; + break; + case BINOP_XOR: + op = VKD3DSIH_XOR; + is_valid = is_int; + break; + default: + FIXME("Unhandled binary op %#"PRIx64".\n", code); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, + "Binary operation %#"PRIx64" is unhandled.", code); + return VKD3DSIH_INVALID; + } + + if (!is_valid) + { + WARN("Invalid operation %u for type %u, width %u.\n", op, type_a->class, type_a->u.width); + vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_INVALID_OPERATION, + "Binary operation %u is invalid on type class %u.", op, type_a->class); + } + + return op; +} + +static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_record *record, + struct vkd3d_shader_instruction *ins, struct sm6_value *dst) +{ + struct vkd3d_shader_src_param *src_params; + enum vkd3d_shader_opcode handler_idx; + const struct sm6_value *a, *b; + unsigned int i = 0; + uint64_t code; + + a = sm6_parser_get_value_by_ref(sm6, record, NULL, &i); + b = sm6_parser_get_value_by_ref(sm6, record, a->type, &i); + if (!a || !b) + return; + + if (!dxil_record_validate_operand_count(record, i + 1, i + 2, sm6)) + return; + + code = record->operands[i++]; + if ((handler_idx = sm6_parser_decode_binary_op(sm6, code, a->type, b->type)) == VKD3DSIH_INVALID) + return; + + vsir_instruction_init(ins, &sm6->p.location, handler_idx); + + if (record->operand_count > i && record->operands[i]) + { + uint64_t flags = record->operands[i]; + bool silence_warning = false; + + switch (handler_idx) + { + case VKD3DSIH_ADD: + case VKD3DSIH_MUL: + case VKD3DSIH_DIV: + case VKD3DSIH_FREM: + if (!(flags & FP_ALLOW_UNSAFE_ALGEBRA)) + ins->flags |= VKD3DSI_PRECISE_X; + flags &= ~FP_ALLOW_UNSAFE_ALGEBRA; + /* SPIR-V FPFastMathMode is only available in the Kernel executon model. */ + silence_warning = !(flags & ~(FP_NO_NAN | FP_NO_INF | FP_NO_SIGNED_ZEROS | FP_ALLOW_RECIPROCAL)); + break; + case VKD3DSIH_IADD: + case VKD3DSIH_UMUL: + case VKD3DSIH_ISHL: + silence_warning = !(flags & ~(OB_NO_UNSIGNED_WRAP | OB_NO_SIGNED_WRAP)); + break; + case VKD3DSIH_ISHR: + case VKD3DSIH_USHR: + case VKD3DSIH_IDIV: + case VKD3DSIH_UDIV: + silence_warning = !(flags & ~PEB_EXACT); + break; + default: + break; + } + /* The above flags are very common and cause warning spam. */ + if (silence_warning) + TRACE("Ignoring flags %#"PRIx64".\n", flags); + else + WARN("Ignoring flags %#"PRIx64".\n", flags); + } + + src_params = instruction_src_params_alloc(ins, 2, sm6); + src_param_init_from_value(&src_params[0], a); + src_param_init_from_value(&src_params[1], b); + if (code == BINOP_SUB) + src_params[1].modifiers = VKD3DSPSM_NEG; + + dst->type = a->type; + + if (handler_idx == VKD3DSIH_UMUL || handler_idx == VKD3DSIH_UDIV || handler_idx == VKD3DSIH_IDIV) + { + struct vkd3d_shader_dst_param *dst_params = instruction_dst_params_alloc(ins, 2, sm6); + unsigned int index = code != BINOP_UDIV && code != BINOP_SDIV; + + dst_param_init(&dst_params[0]); + dst_param_init(&dst_params[1]); + register_init_ssa_scalar(&dst_params[index].reg, a->type, sm6); + dst_params[index ^ 1].reg.type = VKD3DSPR_NULL; + dst->u.reg = dst_params[index].reg; + } + else + { + instruction_dst_param_init_ssa_scalar(ins, sm6); + } +} + 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) { @@ -3235,6 +3453,9 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const record = block->records[i]; switch (record->code) { + case FUNC_CODE_INST_BINOP: + sm6_parser_emit_binop(sm6, record, ins, dst); + break; case FUNC_CODE_INST_CALL: sm6_parser_emit_call(sm6, record, code_block, ins, dst); break; diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 1560edbe..b79a8ed9 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -191,6 +191,7 @@ enum vkd3d_shader_error VKD3D_SHADER_WARNING_DXIL_TYPE_MISMATCH = 8305, VKD3D_SHADER_WARNING_DXIL_ENTRY_POINT_MISMATCH = 8306, VKD3D_SHADER_WARNING_DXIL_INVALID_MASK = 8307, + VKD3D_SHADER_WARNING_DXIL_INVALID_OPERATION = 8308,
VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED = 9000, VKD3D_SHADER_ERROR_VSIR_INVALID_HANDLER = 9001, diff --git a/tests/hlsl/arithmetic-float-uniform.shader_test b/tests/hlsl/arithmetic-float-uniform.shader_test index 8aaca621..4812d053 100644 --- a/tests/hlsl/arithmetic-float-uniform.shader_test +++ b/tests/hlsl/arithmetic-float-uniform.shader_test @@ -10,7 +10,7 @@ float4 main() : SV_TARGET
[test] uniform 0 float4 5.0 15.0 0.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (20.0, -10.0, 75.0, 0.33333333) 1
[pixel shader] @@ -25,7 +25,7 @@ float4 main() : SV_TARGET
[test] uniform 0 float4 5.0 15.0 0.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (5.0, 5.0, -5.0, 3.0) 1
[pixel shader] @@ -40,7 +40,7 @@ float4 main() : SV_TARGET
[test] uniform 0 float4 42.0 5.0 0.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (2.0, -2.0, 2.0, -2.0) 16
[pixel shader] @@ -55,7 +55,7 @@ float4 main() : SV_TARGET
[test] uniform 0 float4 45.0 5.0 0.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (0.0, 0.0, 0.0, 0.0)
[pixel shader] @@ -69,8 +69,8 @@ float4 main() : sv_target [test] uniform 0 float4 5.0 -42.1 4.0 45.0 uniform 4 float4 15.0 -5.0 4.1 5.0 -todo(sm>=6) draw quad -probe all rgba (5.0, -2.1, 4.0, 0.0) 4 +draw quad +probe all rgba (5.0, -2.1, 4.0, 0.0) 6
[require] % Infinities are not allowed in SM1 @@ -88,5 +88,5 @@ float4 main() : SV_TARGET
[test] uniform 0 float4 1.0 0.0 0.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (1e99, 1e99, 1e99, 1e99) diff --git a/tests/hlsl/cbuffer.shader_test b/tests/hlsl/cbuffer.shader_test index dbb49ea7..b4dc01ed 100644 --- a/tests/hlsl/cbuffer.shader_test +++ b/tests/hlsl/cbuffer.shader_test @@ -176,7 +176,7 @@ float4 main() : sv_target uniform 0 float4 1.0 2.0 3.0 4.0 uniform 4 float4 5.0 6.0 7.0 8.0 uniform 8 float4 9.0 10.0 11.0 12.0 -todo(sm>=6) draw quad +draw quad probe all rgba (509, 610, 711, 812)
@@ -204,7 +204,7 @@ uniform 0 float4 0.0 1.0 2.0 3.0 uniform 4 float4 4.0 5.0 6.0 7.0 uniform 8 float4 8.0 9.0 10.0 11.0 uniform 12 float4 12.0 13.0 14.0 15.0 -todo(sm>=6) draw quad +draw quad probe all rgba (12468.0, 13509.0, 14010.0, 15011.0)
@@ -326,7 +326,7 @@ float4 main() : sv_target uniform 0 float 1.0 uniform 1 float 2.0 uniform 4 float4 5.0 6.0 7.0 8.0 -todo(sm>=6) draw quad +draw quad probe all rgba (512.0, 612.0, 712.0, 812.0)
diff --git a/tests/hlsl/const.shader_test b/tests/hlsl/const.shader_test index 17427c38..9541203d 100644 --- a/tests/hlsl/const.shader_test +++ b/tests/hlsl/const.shader_test @@ -10,7 +10,7 @@ float4 main() : sv_target [test] uniform 0 float4 1.0 2.0 3.0 4.0 uniform 4 float4 0.1 0.2 0.3 0.4 -todo(sm>=6) draw quad +draw quad probe all rgba (1.1, 2.2, 3.3, 4.4)
[pixel shader fail(sm<6)] diff --git a/tests/hlsl/cross.shader_test b/tests/hlsl/cross.shader_test index b84e2eac..22f373a6 100644 --- a/tests/hlsl/cross.shader_test +++ b/tests/hlsl/cross.shader_test @@ -12,7 +12,7 @@ float4 main() : sv_target [test] uniform 0 float4 1 -2 3 4 uniform 4 float4 10 100 1000 10000 -todo(sm>=6) draw quad +draw quad probe all rgba (-2300, -970, 120, 0)
@@ -29,5 +29,5 @@ float4 main() : sv_target
[test] uniform 0 float4 1 -2 3 4 -todo(sm>=6) draw quad +draw quad probe all rgba (-20, 8, 12, 3.5) diff --git a/tests/hlsl/dot.shader_test b/tests/hlsl/dot.shader_test index bb71919c..c620e5fa 100644 --- a/tests/hlsl/dot.shader_test +++ b/tests/hlsl/dot.shader_test @@ -71,7 +71,7 @@ float4 main() : SV_TARGET % Account for both the SM1 and SM4 uniform layout uniform 0 float4 2.0 3.0 0.0 0.0 uniform 4 float4 3.0 0.0 0.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (6.0, 6.0, 6.0, 6.0)
[pixel shader] diff --git a/tests/hlsl/expr-indexing.shader_test b/tests/hlsl/expr-indexing.shader_test index 1c598816..c11fa654 100644 --- a/tests/hlsl/expr-indexing.shader_test +++ b/tests/hlsl/expr-indexing.shader_test @@ -9,7 +9,7 @@ float4 main() : sv_target [test] uniform 0 float4 1.0 2.0 3.0 4.0 uniform 4 float4 5.0 6.0 7.0 8.0 -todo(sm>=6) draw quad +draw quad probe all rgba (8.0, 8.0, 8.0, 8.0)
diff --git a/tests/hlsl/lerp.shader_test b/tests/hlsl/lerp.shader_test index 27c45fe7..413bfe83 100644 --- a/tests/hlsl/lerp.shader_test +++ b/tests/hlsl/lerp.shader_test @@ -12,7 +12,7 @@ float4 main() : SV_TARGET uniform 0 float4 2.0 3.0 4.0 5.0 uniform 4 float4 0.0 -10.0 10.0 100.0 uniform 8 float4 0.0 1.0 -1.0 0.75 -todo(sm>=6) draw quad +draw quad probe all rgba (2.0, -10.0, -2.0, 76.25)
[require] diff --git a/tests/hlsl/loop.shader_test b/tests/hlsl/loop.shader_test index 4fbf14d8..1d868230 100644 --- a/tests/hlsl/loop.shader_test +++ b/tests/hlsl/loop.shader_test @@ -1,3 +1,5 @@ +% TODO: dxcompiler emits no loops for any of these test shaders. + [pixel shader] float a;
@@ -16,7 +18,7 @@ float4 main() : sv_target
[test] uniform 0 float 5.0 -todo(sm>=6) draw quad +draw quad probe all rgba (50.0, 50.0, 50.0, 50.0)
@@ -39,7 +41,7 @@ float4 main() : sv_target
[test] uniform 0 float 4.0 -todo(sm>=6) draw quad +draw quad probe all rgba (20.0, 20.0, 20.0, 20.0)
[pixel shader] @@ -68,7 +70,7 @@ float4 main() : sv_target
[test] uniform 0 float 4.0 -todo(sm>=6) draw quad +draw quad probe all rgba (409.1, 409.1, 409.1, 409.1)
[pixel shader] @@ -98,5 +100,5 @@ float4 main() : sv_target
[test] uniform 0 float 4.0 -todo(sm>=6) draw quad +draw quad probe all rgba (410.1, 410.1, 410.1, 410.1) diff --git a/tests/hlsl/math.shader_test b/tests/hlsl/math.shader_test index 8f059227..15f57933 100644 --- a/tests/hlsl/math.shader_test +++ b/tests/hlsl/math.shader_test @@ -14,5 +14,5 @@ float4 main() : SV_TARGET [test] uniform 0 float4 2.5 0.3 0.2 0.7 uniform 4 float4 0.1 1.5 0.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (-12.43, 9.833333, 1.6, 35.0) 1 diff --git a/tests/hlsl/object-references.shader_test b/tests/hlsl/object-references.shader_test index ff405559..c857f388 100644 --- a/tests/hlsl/object-references.shader_test +++ b/tests/hlsl/object-references.shader_test @@ -202,7 +202,7 @@ float4 main() : sv_target
[test] uniform 0 float 10.0 -todo(sm>=6) draw quad +draw quad probe (0, 0) rgba (11.0, 12.0, 13.0, 11.0)
diff --git a/tests/hlsl/reflect.shader_test b/tests/hlsl/reflect.shader_test index 808b4b77..25890086 100644 --- a/tests/hlsl/reflect.shader_test +++ b/tests/hlsl/reflect.shader_test @@ -62,7 +62,7 @@ float4 main() : sv_target [test] uniform 0 float4 0.5 0.0 0.0 0.0 uniform 4 float4 0.6 0.0 0.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (0.14, 0.14, 0.14, 0.14) 4
[pixel shader] diff --git a/tests/hlsl/writemask-assignop-0.shader_test b/tests/hlsl/writemask-assignop-0.shader_test index fa8ecc2e..374a38bb 100644 --- a/tests/hlsl/writemask-assignop-0.shader_test +++ b/tests/hlsl/writemask-assignop-0.shader_test @@ -11,5 +11,5 @@ float4 main() : SV_target
[test] uniform 0 float4 0.0303 0.08 0.07 0.0202 -todo(sm>=6) draw quad +draw quad probe all rgba (-0.4697, -0.02, 0.57, 0.3202) 2 diff --git a/tests/hlsl/writemask-assignop-1.shader_test b/tests/hlsl/writemask-assignop-1.shader_test index 3bebcce6..61993257 100644 --- a/tests/hlsl/writemask-assignop-1.shader_test +++ b/tests/hlsl/writemask-assignop-1.shader_test @@ -12,5 +12,5 @@ float4 main() : SV_target
[test] uniform 0 float4 0.0303 0.08 0.07 0.0202 -todo(sm>=6) draw quad +draw quad probe all rgba (0.5697, -0.08, -0.27, -0.4202)