From: Conor McCarthy cmccarthy@codeweavers.com
Simplifies handling of intrinsics which need to emit more than one instruction. --- libs/vkd3d-shader/dxil.c | 56 +++++++++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 21 deletions(-)
diff --git a/libs/vkd3d-shader/dxil.c b/libs/vkd3d-shader/dxil.c index 602056e25..427461ccb 100644 --- a/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d-shader/dxil.c @@ -3027,6 +3027,12 @@ static struct sm6_block *sm6_block_create() return block; }
+struct function_emission_state +{ + struct sm6_block *code_block; + struct vkd3d_shader_instruction *ins; +}; + static void sm6_parser_emit_alloca(struct sm6_parser *sm6, const struct dxil_record *record, struct vkd3d_shader_instruction *ins, struct sm6_value *dst) { @@ -3338,9 +3344,10 @@ static enum vkd3d_shader_opcode map_dx_unary_op(enum dx_intrinsic_opcode op) } }
-static void sm6_parser_emit_dx_unary(struct sm6_parser *sm6, struct sm6_block *code_block, - enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct vkd3d_shader_instruction *ins) +static void sm6_parser_emit_dx_unary(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, + const struct sm6_value **operands, struct function_emission_state *state) { + struct vkd3d_shader_instruction *ins = state->ins; struct vkd3d_shader_src_param *src_param;
vsir_instruction_init(ins, &sm6->p.location, map_dx_unary_op(op)); @@ -3350,10 +3357,11 @@ static void sm6_parser_emit_dx_unary(struct sm6_parser *sm6, struct sm6_block *c 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) +static void sm6_parser_emit_dx_cbuffer_load(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, + const struct sm6_value **operands, struct function_emission_state *state) { struct sm6_value *dst = sm6_parser_get_current_value(sm6); + struct vkd3d_shader_instruction *ins = state->ins; struct vkd3d_shader_src_param *src_param; const struct sm6_value *buffer; const struct sm6_type *type; @@ -3401,9 +3409,10 @@ static const struct sm6_descriptor_info *sm6_parser_get_descriptor(struct sm6_pa 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) +static void sm6_parser_emit_dx_create_handle(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, + const struct sm6_value **operands, struct function_emission_state *state) { + struct vkd3d_shader_instruction *ins = state->ins; enum vkd3d_shader_descriptor_type type; const struct sm6_descriptor_info *d; struct vkd3d_shader_register *reg; @@ -3436,9 +3445,10 @@ static void sm6_parser_emit_dx_create_handle(struct sm6_parser *sm6, struct sm6_ 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) +static void sm6_parser_emit_dx_load_input(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, + const struct sm6_value **operands, struct function_emission_state *state) { + struct vkd3d_shader_instruction *ins = state->ins; struct vkd3d_shader_src_param *src_param; const struct shader_signature *signature; unsigned int row_index, column_index; @@ -3468,9 +3478,10 @@ static void sm6_parser_emit_dx_load_input(struct sm6_parser *sm6, struct sm6_blo instruction_dst_param_init_ssa_scalar(ins, sm6); }
-static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, struct sm6_block *code_block, - enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct vkd3d_shader_instruction *ins) +static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, + const struct sm6_value **operands, struct function_emission_state *state) { + struct vkd3d_shader_instruction *ins = state->ins; struct vkd3d_shader_src_param *src_param; struct vkd3d_shader_dst_param *dst_param; const struct shader_signature *signature; @@ -3525,8 +3536,8 @@ struct sm6_dx_opcode_info { const char *ret_type; const char *operand_info; - void (*handler)(struct sm6_parser *, struct sm6_block *, enum dx_intrinsic_opcode, - const struct sm6_value **, struct vkd3d_shader_instruction *); + void (*handler)(struct sm6_parser *, enum dx_intrinsic_opcode, const struct sm6_value **, + struct function_emission_state *); };
/* @@ -3678,27 +3689,27 @@ static void sm6_parser_emit_unhandled(struct sm6_parser *sm6, struct vkd3d_shade /* dst->is_undefined is not set here because it flags only explicitly undefined values. */ }
-static void sm6_parser_decode_dx_op(struct sm6_parser *sm6, struct sm6_block *code_block, enum dx_intrinsic_opcode op, +static void sm6_parser_decode_dx_op(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const char *name, const struct sm6_value **operands, unsigned int operand_count, - struct vkd3d_shader_instruction *ins, struct sm6_value *dst) + struct function_emission_state *state, struct sm6_value *dst) { if (op >= ARRAY_SIZE(sm6_dx_op_table) || !sm6_dx_op_table[op].operand_info) { FIXME("Unhandled dx intrinsic function id %u, '%s'.\n", op, name); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_UNHANDLED_INTRINSIC, "Call to intrinsic function %s is unhandled.", name); - sm6_parser_emit_unhandled(sm6, ins, dst); + sm6_parser_emit_unhandled(sm6, state->ins, dst); return; }
if (sm6_parser_validate_dx_op(sm6, op, name, operands, operand_count, dst)) - sm6_dx_op_table[op].handler(sm6, code_block, op, operands, ins); + sm6_dx_op_table[op].handler(sm6, op, operands, state); else - sm6_parser_emit_unhandled(sm6, ins, dst); + sm6_parser_emit_unhandled(sm6, state->ins, dst); }
static void sm6_parser_emit_call(struct sm6_parser *sm6, const struct dxil_record *record, - struct sm6_block *code_block, struct vkd3d_shader_instruction *ins, struct sm6_value *dst) + struct function_emission_state *state, struct sm6_value *dst) { const struct sm6_value *operands[DXIL_OP_MAX_OPERANDS]; const struct sm6_value *fn_value, *op_value; @@ -3780,8 +3791,8 @@ static void sm6_parser_emit_call(struct sm6_parser *sm6, const struct dxil_recor "Expected a constant integer dx intrinsic function id."); return; } - sm6_parser_decode_dx_op(sm6, code_block, register_get_uint_value(&op_value->u.reg), - fn_value->u.function.name, &operands[1], operand_count - 1, ins, dst); + sm6_parser_decode_dx_op(sm6, register_get_uint_value(&op_value->u.reg), + fn_value->u.function.name, &operands[1], operand_count - 1, state, dst); }
static enum vkd3d_shader_opcode sm6_map_cast_op(uint64_t code, const struct sm6_type *from, @@ -4729,8 +4740,11 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const sm6_parser_emit_binop(sm6, record, ins, dst); break; case FUNC_CODE_INST_CALL: - sm6_parser_emit_call(sm6, record, code_block, ins, dst); + { + struct function_emission_state state = {code_block, ins}; + sm6_parser_emit_call(sm6, record, &state, dst); break; + } case FUNC_CODE_INST_CAST: sm6_parser_emit_cast(sm6, record, ins, dst); break;
From: Conor McCarthy cmccarthy@codeweavers.com
--- libs/vkd3d-shader/spirv.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index 7bc9bc470..14b21fd9c 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -8571,7 +8571,6 @@ static void spirv_compiler_emit_ld_raw_structured_srv_uav(struct spirv_compiler type_id, val_id, 0); } } - assert(dst->reg.data_type == VKD3D_DATA_UINT); spirv_compiler_emit_store_dst_components(compiler, dst, VKD3D_SHADER_COMPONENT_UINT, constituents); }
From: Conor McCarthy cmccarthy@codeweavers.com
--- libs/vkd3d-shader/dxil.c | 285 ++++++++++++++++++++++- libs/vkd3d-shader/vkd3d_shader_private.h | 6 + 2 files changed, 288 insertions(+), 3 deletions(-)
diff --git a/libs/vkd3d-shader/dxil.c b/libs/vkd3d-shader/dxil.c index 427461ccb..448d51944 100644 --- a/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d-shader/dxil.c @@ -171,6 +171,35 @@ enum bitcode_linkage LINKAGE_INTERNAL = 3, };
+enum dxil_resource_kind +{ + RESOURCE_KIND_INVALID = 0, + RESOURCE_KIND_TEXTURE1D = 1, + RESOURCE_KIND_TEXTURE2D = 2, + RESOURCE_KIND_TEXTURE2DMS = 3, + RESOURCE_KIND_TEXTURE3D = 4, + RESOURCE_KIND_TEXTURECUBE = 5, + RESOURCE_KIND_TEXTURE1DARRAY = 6, + RESOURCE_KIND_TEXTURE2DARRAY = 7, + RESOURCE_KIND_TEXTURE2DMSARRAY = 8, + RESOURCE_KIND_TEXTURECUBEARRAY = 9, + RESOURCE_KIND_TYPEDBUFFER = 10, + RESOURCE_KIND_RAWBUFFER = 11, + RESOURCE_KIND_STRUCTUREDBUFFER = 12, + RESOURCE_KIND_CBUFFER = 13, + RESOURCE_KIND_SAMPLER = 14, + RESOURCE_KIND_TBUFFER = 15, + RESOURCE_KIND_RTACCELERATIONSTRUCTURE = 16, + RESOURCE_KIND_FEEDBACKTEXTURE2D = 17, + RESOURCE_KIND_FEEDBACKTEXTURE2DARRAY = 18, +}; + +enum dxil_resource_type +{ + RESOURCE_TYPE_NON_RAW_STRUCTURED = 0, + RESOURCE_TYPE_RAW_STRUCTURED = 1, +}; + enum dxil_component_type { COMPONENT_TYPE_INVALID = 0, @@ -565,6 +594,11 @@ struct sm6_descriptor_info enum vkd3d_shader_descriptor_type type; unsigned int id; struct vkd3d_shader_register_range range; + enum vkd3d_shader_resource_type resource_type; + enum dxil_resource_kind kind; + enum vkd3d_data_type resource_data_type; + enum vkd3d_shader_register_type reg_type; + enum vkd3d_data_type reg_data_type; };
struct sm6_parser @@ -1937,6 +1971,12 @@ static inline bool sm6_value_is_constant(const struct sm6_value *value) return sm6_value_is_register(value) && register_is_constant(&value->u.reg); }
+static bool sm6_value_is_constant_zero(const struct sm6_value *value) +{ + /* Constant vectors do not occur. */ + return sm6_value_is_register(value) && register_is_scalar_constant_zero(&value->u.reg); +} + static inline bool sm6_value_is_undef(const struct sm6_value *value) { return sm6_value_is_register(value) && value->u.reg.type == VKD3DSPR_UNDEF; @@ -3434,9 +3474,8 @@ static void sm6_parser_emit_dx_create_handle(struct sm6_parser *sm6, enum dx_int dst->u.handle.d = d;
reg = &dst->u.handle.reg; - /* Set idx_count to 3 for use with load instructions. - * TODO: set register type from resource type when other types are supported. */ - vsir_register_init(reg, VKD3DSPR_CONSTBUFFER, VKD3D_DATA_FLOAT, 3); + /* Set idx_count to 3 for use with load instructions. */ + vsir_register_init(reg, d->reg_type, d->reg_data_type, 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]); @@ -4406,6 +4445,12 @@ static bool sm6_metadata_value_is_string(const struct sm6_metadata_value *m) return m && m->type == VKD3D_METADATA_STRING; }
+static bool sm6_metadata_value_is_zero_or_undef(const struct sm6_metadata_value *m) +{ + return sm6_metadata_value_is_value(m) + && (sm6_value_is_undef(m->u.value) || sm6_value_is_constant_zero(m->u.value)); +} + static bool sm6_metadata_get_uint_value(const struct sm6_parser *sm6, const struct sm6_metadata_value *m, unsigned int *u) { @@ -5234,6 +5279,232 @@ static bool sm6_parser_resources_load_register_range(struct sm6_parser *sm6, return true; }
+static bool resource_kind_is_texture(enum dxil_resource_kind kind) +{ + return kind >= RESOURCE_KIND_TEXTURE1D && kind <= RESOURCE_KIND_TEXTURECUBEARRAY; +} + +static bool resource_kind_is_multisampled(enum dxil_resource_kind kind) +{ + return kind == RESOURCE_KIND_TEXTURE2DMS || kind == RESOURCE_KIND_TEXTURE2DMSARRAY; +} + +static enum vkd3d_shader_resource_type shader_resource_type_from_dxil_resource_kind(enum dxil_resource_kind kind) +{ + if (resource_kind_is_texture(kind)) + return kind + 1; + + switch (kind) + { + case RESOURCE_KIND_TYPEDBUFFER: + return VKD3D_SHADER_RESOURCE_BUFFER; + default: + return VKD3D_SHADER_RESOURCE_NONE; + } +} + +static const enum vkd3d_data_type data_type_table[] = +{ + [COMPONENT_TYPE_INVALID] = VKD3D_DATA_UNUSED, + [COMPONENT_TYPE_I1] = VKD3D_DATA_UNUSED, + [COMPONENT_TYPE_I16] = VKD3D_DATA_INT, + [COMPONENT_TYPE_U16] = VKD3D_DATA_UINT, + [COMPONENT_TYPE_I32] = VKD3D_DATA_INT, + [COMPONENT_TYPE_U32] = VKD3D_DATA_UINT, + [COMPONENT_TYPE_I64] = VKD3D_DATA_UNUSED, + [COMPONENT_TYPE_U64] = VKD3D_DATA_UNUSED, + [COMPONENT_TYPE_F16] = VKD3D_DATA_FLOAT, + [COMPONENT_TYPE_F32] = VKD3D_DATA_FLOAT, + [COMPONENT_TYPE_F64] = VKD3D_DATA_DOUBLE, + [COMPONENT_TYPE_SNORMF16] = VKD3D_DATA_SNORM, + [COMPONENT_TYPE_UNORMF16] = VKD3D_DATA_UNORM, + [COMPONENT_TYPE_SNORMF32] = VKD3D_DATA_SNORM, + [COMPONENT_TYPE_UNORMF32] = VKD3D_DATA_UNORM, + [COMPONENT_TYPE_SNORMF64] = VKD3D_DATA_DOUBLE, + [COMPONENT_TYPE_UNORMF64] = VKD3D_DATA_DOUBLE, + [COMPONENT_TYPE_PACKEDS8X32] = VKD3D_DATA_UNUSED, + [COMPONENT_TYPE_PACKEDU8X32] = VKD3D_DATA_UNUSED, +}; + +static enum vkd3d_data_type vkd3d_data_type_from_dxil_component_type(enum dxil_component_type type, + struct sm6_parser *sm6) +{ + enum vkd3d_data_type data_type; + + if (type >= ARRAY_SIZE(data_type_table) || (data_type = data_type_table[type]) == VKD3D_DATA_UNUSED) + { + FIXME("Unhandled component type %u.\n", type); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES, + "Resource descriptor component type %u is unhandled.", type); + return VKD3D_DATA_FLOAT; + } + + return data_type; +} + +static struct vkd3d_shader_resource *sm6_parser_resources_load_common_info(struct sm6_parser *sm6, + const struct sm6_metadata_value *type_value, enum dxil_resource_kind kind, + const struct sm6_metadata_value *m, struct vkd3d_shader_instruction *ins) +{ + enum vkd3d_shader_resource_type resource_type; + enum dxil_resource_type dxil_resource_type; + const struct sm6_metadata_node *node; + enum vkd3d_data_type data_type; + unsigned int i, values[2]; + + if (!(resource_type = shader_resource_type_from_dxil_resource_kind(kind))) + { + FIXME("Unhandled resource kind %u.\n", kind); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES, + "Resource kind %u is unhandled.", kind); + return NULL; + } + ins->resource_type = resource_type; + + if (!sm6_metadata_value_is_node(m)) + { + WARN("Resource metadata list is not a node.\n"); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES, + "Resource descriptor metadata list is not a node."); + return NULL; + } + + node = m->u.node; + + if (node->operand_count < 2) + { + WARN("Invalid operand count %u.\n", node->operand_count); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND_COUNT, + "Invalid operand count %u for a resource descriptor.", node->operand_count); + return NULL; + } + if (node->operand_count > 2) + { + WARN("Ignoring %u extra operands.\n", node->operand_count - 2); + vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_OPERANDS, + "Ignoring %u extra operands for a resource descriptor.", node->operand_count - 2); + } + + for (i = 0; i < 2; ++i) + { + if (!sm6_metadata_get_uint_value(sm6, node->operands[i], &values[i])) + { + WARN("Failed to load uint value at index %u.\n", i); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES, + "A resource descriptor operand metadata value is not an integer."); + return NULL; + } + } + + if ((dxil_resource_type = values[0]) == RESOURCE_TYPE_NON_RAW_STRUCTURED) + { + if (kind != RESOURCE_KIND_TYPEDBUFFER && !resource_kind_is_texture(kind)) + { + WARN("Unhandled resource kind %u.\n", kind); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES, + "Resource kind %u for a typed resource is unhandled.", kind); + return NULL; + } + + data_type = vkd3d_data_type_from_dxil_component_type(values[1], sm6); + ins->handler_idx = VKD3DSIH_DCL; + for (i = 0; i < VKD3D_VEC4_SIZE; ++i) + ins->declaration.semantic.resource_data_type[i] = data_type; + ins->declaration.semantic.resource_type = resource_type; + ins->declaration.semantic.resource.reg.write_mask = VKD3DSP_WRITEMASK_ALL; + + return &ins->declaration.semantic.resource; + } + else + { + FIXME("Unhandled resource type %u.\n", dxil_resource_type); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES, + "Resource type %u is unhandled.", dxil_resource_type); + } + + return NULL; +} + +static void init_resource_declaration(struct vkd3d_shader_resource *resource, + enum vkd3d_shader_register_type reg_type, enum vkd3d_data_type data_type, unsigned int id, + const struct vkd3d_shader_register_range *range) +{ + struct vkd3d_shader_dst_param *param = &resource->reg; + + param->modifiers = 0; + param->shift = 0; + vsir_register_init(¶m->reg, reg_type, data_type, 3); + param->reg.idx[0].offset = id; + param->reg.idx[1].offset = range->first; + param->reg.idx[2].offset = range->last; + + resource->range = *range; +} + +static enum vkd3d_result sm6_parser_resources_load_srv(struct sm6_parser *sm6, + const struct sm6_metadata_node *node, struct sm6_descriptor_info *d, struct vkd3d_shader_instruction *ins) +{ + struct vkd3d_shader_resource *resource; + unsigned int kind; + + if (node->operand_count < 9) + { + WARN("Invalid operand count %u.\n", node->operand_count); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND_COUNT, + "Invalid operand count %u for an SRV descriptor.", node->operand_count); + return VKD3D_ERROR_INVALID_SHADER; + } + if (node->operand_count > 9) + { + WARN("Ignoring %u extra operands.\n", node->operand_count - 9); + vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_OPERANDS, + "Ignoring %u extra operands for an SRV descriptor.", node->operand_count - 9); + } + + if (!sm6_metadata_get_uint_value(sm6, node->operands[6], &kind)) + { + WARN("Failed to load resource type.\n"); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES, + "SRV resource type metadata value is not an integer."); + return VKD3D_ERROR_INVALID_SHADER; + } + + vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_INVALID); + + if (!(resource = sm6_parser_resources_load_common_info(sm6, node->operands[1], kind, + node->operands[8], ins))) + { + return VKD3D_ERROR_INVALID_SHADER; + } + + d->resource_type = ins->resource_type; + d->kind = kind; + d->reg_type = VKD3DSPR_RESOURCE; + d->reg_data_type = (ins->resource_type == VKD3D_SHADER_RESOURCE_BUFFER) ? VKD3D_DATA_UINT : VKD3D_DATA_RESOURCE; + d->resource_data_type = ins->declaration.semantic.resource_data_type[0]; + + init_resource_declaration(resource, VKD3DSPR_RESOURCE, d->reg_data_type, d->id, &d->range); + + if (resource_kind_is_multisampled(kind)) + { + if (!sm6_metadata_get_uint_value(sm6, node->operands[7], &ins->declaration.semantic.sample_count)) + { + WARN("Failed to load sample count.\n"); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES, + "SRV sample count metadata value is not an integer."); + return VKD3D_ERROR_INVALID_SHADER; + } + } + else if (!sm6_metadata_value_is_zero_or_undef(node->operands[7])) + { + WARN("Ignoring sample count value.\n"); + vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_OPERANDS, + "Ignoring an SRV descriptor sample count metadata value which is not constant zero or undefined."); + } + + return VKD3D_OK; +} + static enum vkd3d_result sm6_parser_resources_load_cbv(struct sm6_parser *sm6, const struct sm6_metadata_node *node, struct sm6_descriptor_info *d, struct vkd3d_shader_instruction *ins) { @@ -5276,6 +5547,10 @@ static enum vkd3d_result sm6_parser_resources_load_cbv(struct sm6_parser *sm6,
ins->declaration.cb.range = d->range;
+ d->reg_type = VKD3DSPR_CONSTBUFFER; + d->reg_data_type = VKD3D_DATA_FLOAT; + d->resource_data_type = VKD3D_DATA_FLOAT; + return VKD3D_OK; }
@@ -5347,6 +5622,10 @@ static enum vkd3d_result sm6_parser_descriptor_type_init(struct sm6_parser *sm6, if ((ret = sm6_parser_resources_load_cbv(sm6, node, d, ins)) < 0) return ret; break; + case VKD3D_SHADER_DESCRIPTOR_TYPE_SRV: + if ((ret = sm6_parser_resources_load_srv(sm6, node, d, ins)) < 0) + return ret; + break; default: FIXME("Unsupported descriptor type %u.\n", type); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES, diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index bd6aa0869..237841563 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -1181,6 +1181,12 @@ static inline bool register_is_constant(const struct vkd3d_shader_register *reg) return (reg->type == VKD3DSPR_IMMCONST || reg->type == VKD3DSPR_IMMCONST64); }
+static inline bool register_is_scalar_constant_zero(const struct vkd3d_shader_register *reg) +{ + return register_is_constant(reg) && reg->dimension == VSIR_DIMENSION_SCALAR + && (data_type_is_64_bit(reg->data_type) ? !reg->u.immconst_uint64[0] : !reg->u.immconst_uint[0]); +} + struct vkd3d_shader_param_node { struct vkd3d_shader_param_node *next;
From: Conor McCarthy cmccarthy@codeweavers.com
--- libs/vkd3d-shader/dxil.c | 68 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 64 insertions(+), 4 deletions(-)
diff --git a/libs/vkd3d-shader/dxil.c b/libs/vkd3d-shader/dxil.c index 448d51944..9eed319ed 100644 --- a/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d-shader/dxil.c @@ -3474,7 +3474,7 @@ static void sm6_parser_emit_dx_create_handle(struct sm6_parser *sm6, enum dx_int dst->u.handle.d = d;
reg = &dst->u.handle.reg; - /* Set idx_count to 3 for use with load instructions. */ + /* Set idx_count to 3 for use with load/store instructions. */ vsir_register_init(reg, d->reg_type, d->reg_data_type, 3); reg->idx[0].offset = id; register_index_address_init(®->idx[1], operands[2], sm6); @@ -5343,7 +5343,7 @@ static enum vkd3d_data_type vkd3d_data_type_from_dxil_component_type(enum dxil_c }
static struct vkd3d_shader_resource *sm6_parser_resources_load_common_info(struct sm6_parser *sm6, - const struct sm6_metadata_value *type_value, enum dxil_resource_kind kind, + const struct sm6_metadata_value *type_value, bool is_uav, enum dxil_resource_kind kind, const struct sm6_metadata_value *m, struct vkd3d_shader_instruction *ins) { enum vkd3d_shader_resource_type resource_type; @@ -5407,7 +5407,7 @@ static struct vkd3d_shader_resource *sm6_parser_resources_load_common_info(struc }
data_type = vkd3d_data_type_from_dxil_component_type(values[1], sm6); - ins->handler_idx = VKD3DSIH_DCL; + ins->handler_idx = is_uav ? VKD3DSIH_DCL_UAV_TYPED : VKD3DSIH_DCL; for (i = 0; i < VKD3D_VEC4_SIZE; ++i) ins->declaration.semantic.resource_data_type[i] = data_type; ins->declaration.semantic.resource_type = resource_type; @@ -5471,7 +5471,7 @@ static enum vkd3d_result sm6_parser_resources_load_srv(struct sm6_parser *sm6,
vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_INVALID);
- if (!(resource = sm6_parser_resources_load_common_info(sm6, node->operands[1], kind, + if (!(resource = sm6_parser_resources_load_common_info(sm6, node->operands[1], false, kind, node->operands[8], ins))) { return VKD3D_ERROR_INVALID_SHADER; @@ -5505,6 +5505,62 @@ static enum vkd3d_result sm6_parser_resources_load_srv(struct sm6_parser *sm6, return VKD3D_OK; }
+static enum vkd3d_result sm6_parser_resources_load_uav(struct sm6_parser *sm6, + const struct sm6_metadata_node *node, struct sm6_descriptor_info *d, struct vkd3d_shader_instruction *ins) +{ + struct vkd3d_shader_resource *resource; + unsigned int i, values[4]; + + if (node->operand_count < 11) + { + WARN("Invalid operand count %u.\n", node->operand_count); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND_COUNT, + "Invalid operand count %u for a UAV descriptor.", node->operand_count); + return VKD3D_ERROR_INVALID_SHADER; + } + if (node->operand_count > 11) + { + WARN("Ignoring %u extra operands.\n", node->operand_count - 11); + vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_OPERANDS, + "Ignoring %u extra operands for a UAV descriptor.", node->operand_count - 11); + } + + for (i = 6; i < 10; ++i) + { + if (!sm6_metadata_get_uint_value(sm6, node->operands[i], &values[i - 6])) + { + WARN("Failed to load uint value at index %u.\n", i); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES, + "A UAV descriptor operand metadata value is not an integer."); + return VKD3D_ERROR_INVALID_SHADER; + } + } + + vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_INVALID); + if (values[1]) + ins->flags = VKD3DSUF_GLOBALLY_COHERENT; + if (values[2]) + ins->flags |= VKD3DSUF_ORDER_PRESERVING_COUNTER; + if (values[3]) + ins->flags |= VKD3DSUF_RASTERISER_ORDERED_VIEW; + + if (!(resource = sm6_parser_resources_load_common_info(sm6, node->operands[1], true, values[0], + node->operands[10], ins))) + { + return VKD3D_ERROR_INVALID_SHADER; + } + + d->resource_type = ins->resource_type; + d->kind = values[0]; + d->reg_type = VKD3DSPR_UAV; + d->reg_data_type = (ins->resource_type == VKD3D_SHADER_RESOURCE_BUFFER) ? VKD3D_DATA_UINT : VKD3D_DATA_UAV; + d->resource_data_type = ins->declaration.semantic.resource_data_type[0]; + + init_resource_declaration(resource, VKD3DSPR_UAV, d->reg_data_type, d->id, &d->range); + + return VKD3D_OK; +} + static enum vkd3d_result sm6_parser_resources_load_cbv(struct sm6_parser *sm6, const struct sm6_metadata_node *node, struct sm6_descriptor_info *d, struct vkd3d_shader_instruction *ins) { @@ -5626,6 +5682,10 @@ static enum vkd3d_result sm6_parser_descriptor_type_init(struct sm6_parser *sm6, if ((ret = sm6_parser_resources_load_srv(sm6, node, d, ins)) < 0) return ret; break; + case VKD3D_SHADER_DESCRIPTOR_TYPE_UAV: + if ((ret = sm6_parser_resources_load_uav(sm6, node, d, ins)) < 0) + return ret; + break; default: FIXME("Unsupported descriptor type %u.\n", type); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES,
From: Conor McCarthy cmccarthy@codeweavers.com
--- libs/vkd3d-shader/dxil.c | 44 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+)
diff --git a/libs/vkd3d-shader/dxil.c b/libs/vkd3d-shader/dxil.c index 9eed319ed..70fbaebe8 100644 --- a/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d-shader/dxil.c @@ -344,6 +344,7 @@ enum dx_intrinsic_opcode DX_FIRST_BIT_SHI = 34, DX_CREATE_HANDLE = 57, DX_CBUFFER_LOAD_LEGACY = 59, + DX_BUFFER_LOAD = 68, DX_DERIV_COARSEX = 83, DX_DERIV_COARSEY = 84, DX_DERIV_FINEX = 85, @@ -1999,6 +2000,13 @@ static unsigned int sm6_parser_alloc_ssa_id(struct sm6_parser *sm6) return sm6->ssa_next_id++; }
+static void instruction_init_with_resource(struct vkd3d_shader_instruction *ins, + enum vkd3d_shader_opcode handler_idx, const struct sm6_value *resource, struct sm6_parser *sm6) +{ + vsir_instruction_init(ins, &sm6->p.location, handler_idx); + ins->resource_type = resource->u.handle.d->resource_type; +} + static struct vkd3d_shader_src_param *instruction_src_params_alloc(struct vkd3d_shader_instruction *ins, unsigned int count, struct sm6_parser *sm6) { @@ -3517,6 +3525,41 @@ static void sm6_parser_emit_dx_load_input(struct sm6_parser *sm6, enum dx_intrin instruction_dst_param_init_ssa_scalar(ins, sm6); }
+static void sm6_parser_emit_dx_buffer_load(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, + const struct sm6_value **operands, struct function_emission_state *state) +{ + struct vkd3d_shader_instruction *ins = state->ins; + struct vkd3d_shader_src_param *src_params; + const struct sm6_value *resource; + + resource = operands[0]; + if (!sm6_value_validate_is_handle(resource, sm6)) + return; + + if (resource->u.handle.d->kind != RESOURCE_KIND_TYPEDBUFFER) + { + WARN("Resource is not a typed buffer.\n"); + vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_INVALID_OPERATION, + "Resource for a typed buffer load is not a typed buffer."); + } + + instruction_init_with_resource(ins, (resource->u.handle.d->type == VKD3D_SHADER_DESCRIPTOR_TYPE_UAV) + ? VKD3DSIH_LD_UAV_TYPED : VKD3DSIH_LD, resource, sm6); + + src_params = instruction_src_params_alloc(ins, 2, sm6); + src_param_init_from_value(&src_params[0], operands[1]); + if (!sm6_value_is_undef(operands[2])) + { + /* Constant zero would be ok, but is not worth checking for unless it shows up. */ + WARN("Ignoring structure offset.\n"); + vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_OPERANDS, + "Ignoring structure offset for a typed buffer load."); + } + src_param_init_vector_from_reg(&src_params[1], &resource->u.handle.reg); + + instruction_dst_param_init_ssa_vector(ins, VKD3D_VEC4_SIZE, sm6); +} + static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state) { @@ -3595,6 +3638,7 @@ struct sm6_dx_opcode_info static const struct sm6_dx_opcode_info sm6_dx_op_table[] = { [DX_BFREV ] = {"m0", "m", sm6_parser_emit_dx_unary}, + [DX_BUFFER_LOAD ] = {"o", "Hii", sm6_parser_emit_dx_buffer_load}, [DX_CBUFFER_LOAD_LEGACY ] = {"o", "Hi", sm6_parser_emit_dx_cbuffer_load}, [DX_COUNT_BITS ] = {"i", "m", sm6_parser_emit_dx_unary}, [DX_CREATE_HANDLE ] = {"H", "ccib", sm6_parser_emit_dx_create_handle},