-- v2: vkd3d-shader/dxil: Implement DX intrinsic BufferLoad for typed buffers. vkd3d-shader/dxil: Load typed UAV descriptors. vkd3d-shader/dxil: Load typed SRV descriptors. vkd3d-shader/spirv: Do not assert VKD3D_DATA_UINT in spirv_compiler_emit_ld_raw_structured_srv_uav(). vkd3d-shader/dxil: Pass the code block and instruction in a struct to intrinsic handlers.
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 c744dfced..4708ac9ee 100644 --- a/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d-shader/dxil.c @@ -3031,6 +3031,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) { @@ -3342,9 +3348,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)); @@ -3354,10 +3361,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; @@ -3405,9 +3413,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; @@ -3441,9 +3450,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; @@ -3473,9 +3483,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; @@ -3530,8 +3541,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 *); };
/* @@ -3683,27 +3694,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; @@ -3785,8 +3796,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, @@ -4734,8 +4745,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 aa8ceaa67..2e3c53416 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -8570,7 +8570,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 4708ac9ee..08dafeab1 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; @@ -3438,9 +3478,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->dimension = VSIR_DIMENSION_VEC4; reg->idx[0].offset = id; register_index_address_init(®->idx[1], operands[2], sm6); @@ -4411,6 +4450,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) { @@ -5239,6 +5284,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) { @@ -5281,6 +5552,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; }
@@ -5352,6 +5627,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 199a47a76..228d9d9d3 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -1184,6 +1184,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_u64[0] : !reg->u.immconst_u32[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 08dafeab1..1054e7b1a 100644 --- a/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d-shader/dxil.c @@ -3478,7 +3478,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->dimension = VSIR_DIMENSION_VEC4; reg->idx[0].offset = id; @@ -5348,7 +5348,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; @@ -5412,7 +5412,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; @@ -5476,7 +5476,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; @@ -5510,6 +5510,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) { @@ -5631,6 +5687,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 1054e7b1a..5514e47a9 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) { @@ -3522,6 +3530,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) { @@ -3600,6 +3643,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},