From adfeedd876396c6bb597e9591c9d0e33d9098aee Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Fri, 8 Dec 2023 13:21:19 +1100 Subject: [PATCH] Updated vkd3d to 45679a966c73669bdb7fa371569dcc34a448d8d4. --- libs/vkd3d/include/private/vkd3d_common.h | 4 +- libs/vkd3d/libs/vkd3d-common/blob.c | 1 + libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 4 +- libs/vkd3d/libs/vkd3d-shader/dxil.c | 423 +++++++++++++++++- libs/vkd3d/libs/vkd3d-shader/hlsl.y | 20 +- libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 12 +- libs/vkd3d/libs/vkd3d-shader/ir.c | 5 +- libs/vkd3d/libs/vkd3d-shader/spirv.c | 127 ++++-- libs/vkd3d/libs/vkd3d-shader/tpf.c | 11 + .../libs/vkd3d-shader/vkd3d_shader_main.c | 45 +- .../libs/vkd3d-shader/vkd3d_shader_private.h | 3 + 11 files changed, 564 insertions(+), 91 deletions(-) diff --git a/libs/vkd3d/include/private/vkd3d_common.h b/libs/vkd3d/include/private/vkd3d_common.h index 34fde1a2aa0..e9bff2fbba3 100644 --- a/libs/vkd3d/include/private/vkd3d_common.h +++ b/libs/vkd3d/include/private/vkd3d_common.h @@ -80,7 +80,7 @@ static inline size_t align(size_t addr, size_t alignment) # ifdef __MINGW_PRINTF_FORMAT # define VKD3D_PRINTF_FUNC(fmt, args) __attribute__((format(__MINGW_PRINTF_FORMAT, fmt, args))) # else -# define VKD3D_PRINTF_FUNC(fmt, args) /* __attribute__((format(printf, fmt, args))) */ +# define VKD3D_PRINTF_FUNC(fmt, args) __attribute__((format(printf, fmt, args))) # endif # define VKD3D_UNUSED __attribute__((unused)) # define VKD3D_UNREACHABLE __builtin_unreachable() @@ -107,7 +107,7 @@ static inline unsigned int vkd3d_popcount(unsigned int v) { #ifdef _MSC_VER return __popcnt(v); -#elif defined(__MINGW32__) +#elif defined(HAVE_BUILTIN_POPCOUNT) return __builtin_popcount(v); #else v -= (v >> 1) & 0x55555555; diff --git a/libs/vkd3d/libs/vkd3d-common/blob.c b/libs/vkd3d/libs/vkd3d-common/blob.c index 71ab9a2c51e..fa2812619ac 100644 --- a/libs/vkd3d/libs/vkd3d-common/blob.c +++ b/libs/vkd3d/libs/vkd3d-common/blob.c @@ -17,6 +17,7 @@ */ #define COBJMACROS + #define CONST_VTABLE #include "vkd3d.h" #include "vkd3d_blob.h" diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c index 3d139416b61..c78ffebac69 100644 --- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c +++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c @@ -2253,7 +2253,7 @@ static void write_sm1_jump(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b { struct hlsl_reg *reg = &jump->condition.node->reg; - struct sm1_instruction instr = + struct sm1_instruction sm1_instr = { .opcode = D3DSIO_TEXKILL, @@ -2263,7 +2263,7 @@ static void write_sm1_jump(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b .has_dst = 1, }; - write_sm1_instruction(ctx, buffer, &instr); + write_sm1_instruction(ctx, buffer, &sm1_instr); break; } diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c index beb9ae574dc..a1065c8bc45 100644 --- a/libs/vkd3d/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c @@ -296,8 +296,28 @@ enum dx_intrinsic_opcode { DX_LOAD_INPUT = 4, DX_STORE_OUTPUT = 5, + DX_EXP = 21, + DX_FRC = 22, + DX_LOG = 23, + DX_SQRT = 24, + DX_RSQRT = 25, + DX_ROUND_NE = 26, + DX_ROUND_NI = 27, + DX_ROUND_PI = 28, + DX_ROUND_Z = 29, + DX_BFREV = 30, + DX_COUNT_BITS = 31, + DX_FIRST_BIT_LO = 32, + DX_FIRST_BIT_HI = 33, + DX_FIRST_BIT_SHI = 34, DX_CREATE_HANDLE = 57, DX_CBUFFER_LOAD_LEGACY = 59, + DX_DERIV_COARSEX = 83, + DX_DERIV_COARSEY = 84, + DX_DERIV_FINEX = 85, + DX_DERIV_FINEY = 86, + DX_LEGACY_F32TOF16 = 130, + DX_LEGACY_F16TOF32 = 131, }; enum dxil_cast_code @@ -439,6 +459,7 @@ struct dxil_record { unsigned int code; unsigned int operand_count; + const struct dxil_record *attachment; uint64_t operands[]; }; @@ -581,6 +602,7 @@ struct sm6_parser size_t descriptor_count; unsigned int indexable_temp_count; + unsigned int icb_count; struct sm6_value *values; size_t value_count; @@ -796,6 +818,7 @@ static enum vkd3d_result sm6_parser_read_unabbrev_record(struct sm6_parser *sm6) record->code = code; record->operand_count = count; + record->attachment = NULL; for (i = 0; i < count; ++i) record->operands[i] = sm6_parser_read_vbr(sm6, 6); @@ -1012,6 +1035,7 @@ static enum vkd3d_result sm6_parser_read_abbrev_record(struct sm6_parser *sm6, u if (!abbrev->operands[i + 1].read_operand(sm6, abbrev->operands[i + 1].context, &record->operands[i])) goto fail; record->operand_count = count; + record->attachment = NULL; /* An array can occur only as the last operand. */ if (abbrev->is_array) @@ -1572,6 +1596,11 @@ static bool sm6_type_is_bool_i16_i32_i64(const struct sm6_type *type) return type->class == TYPE_CLASS_INTEGER && (type->u.width == 1 || type->u.width >= 16); } +static bool sm6_type_is_i16_i32_i64(const struct sm6_type *type) +{ + return type->class == TYPE_CLASS_INTEGER && 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; @@ -1587,6 +1616,16 @@ static inline bool sm6_type_is_i32(const struct sm6_type *type) return type->class == TYPE_CLASS_INTEGER && type->u.width == 32; } +static bool sm6_type_is_float(const struct sm6_type *type) +{ + return type->class == TYPE_CLASS_FLOAT && type->u.width == 32; +} + +static bool sm6_type_is_f16_f32(const struct sm6_type *type) +{ + return type->class == TYPE_CLASS_FLOAT && (type->u.width == 16 || type->u.width == 32); +} + static inline bool sm6_type_is_floating_point(const struct sm6_type *type) { return type->class == TYPE_CLASS_FLOAT; @@ -2412,7 +2451,7 @@ static enum vkd3d_result value_allocate_constant_array(struct sm6_value *dst, co return VKD3D_ERROR_INVALID_SHADER; } size = max(size, sizeof(icb->data[0])); - count = type->u.array.count * size / sizeof(icb->data[0]); + count = operands ? type->u.array.count * size / sizeof(icb->data[0]) : 0; if (!(icb = vkd3d_malloc(offsetof(struct vkd3d_shader_immediate_constant_buffer, data[count])))) { @@ -2433,9 +2472,14 @@ static enum vkd3d_result value_allocate_constant_array(struct sm6_value *dst, co dst->value_type = VALUE_TYPE_ICB; dst->u.icb = icb; + icb->register_idx = sm6->icb_count++; icb->data_type = vkd3d_data_type_from_sm6_type(elem_type); icb->element_count = type->u.array.count; icb->component_count = 1; + icb->is_null = !operands; + + if (!operands) + return VKD3D_OK; count = type->u.array.count; if (size > sizeof(icb->data[0])) @@ -2510,12 +2554,10 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const switch (record->code) { case CST_CODE_NULL: - if (sm6_type_is_array(type)) + if (sm6_type_is_array(type) + && (ret = value_allocate_constant_array(dst, type, NULL, sm6)) < 0) { - FIXME("Constant null arrays are not supported.\n"); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, - "Constant null arrays are not supported."); - return VKD3D_ERROR_INVALID_SHADER; + return ret; } /* For non-aggregates, register constant data is already zero-filled. */ break; @@ -2588,6 +2630,13 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const break; } + if (record->attachment) + { + WARN("Ignoring metadata attachment.\n"); + vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_ATTACHMENT, + "Ignoring a metadata attachment for a constant."); + } + ++sm6->value_count; } @@ -2626,6 +2675,18 @@ static struct vkd3d_shader_instruction *sm6_parser_add_instruction(struct sm6_pa return ins; } +static void sm6_parser_declare_icb(struct sm6_parser *sm6, const struct sm6_type *elem_type, unsigned int count, + unsigned int alignment, unsigned int init, struct sm6_value *dst) +{ + enum vkd3d_data_type data_type = vkd3d_data_type_from_sm6_type(elem_type); + struct vkd3d_shader_instruction *ins; + + ins = sm6_parser_add_instruction(sm6, VKD3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER); + /* The icb value index will be resolved later so forward references can be handled. */ + ins->declaration.icb = (void *)(intptr_t)init; + register_init_with_id(&dst->u.reg, VKD3DSPR_IMMCONSTBUFFER, data_type, init); +} + static void sm6_parser_declare_indexable_temp(struct sm6_parser *sm6, const struct sm6_type *elem_type, unsigned int count, unsigned int alignment, unsigned int init, struct sm6_value *dst) { @@ -2762,7 +2823,10 @@ static bool sm6_parser_declare_global(struct sm6_parser *sm6, const struct dxil_ if (address_space == ADDRESS_SPACE_DEFAULT) { - sm6_parser_declare_indexable_temp(sm6, scalar_type, count, alignment, init, dst); + if (is_constant) + sm6_parser_declare_icb(sm6, scalar_type, count, alignment, init, dst); + else + sm6_parser_declare_indexable_temp(sm6, scalar_type, count, alignment, init, dst); } else if (address_space == ADDRESS_SPACE_GROUPSHARED) { @@ -2806,11 +2870,11 @@ static const struct vkd3d_shader_immediate_constant_buffer *resolve_forward_init static enum vkd3d_result sm6_parser_globals_init(struct sm6_parser *sm6) { const struct dxil_block *block = &sm6->root_block; + size_t i, base_value_idx = sm6->value_count; struct vkd3d_shader_instruction *ins; const struct dxil_record *record; enum vkd3d_result ret; uint64_t version; - size_t i; sm6->p.location.line = block->id; sm6->p.location.column = 0; @@ -2868,6 +2932,21 @@ static enum vkd3d_result sm6_parser_globals_init(struct sm6_parser *sm6) ins->declaration.indexable_temp.initialiser = resolve_forward_initialiser( (uintptr_t)ins->declaration.indexable_temp.initialiser, sm6); } + else if (ins->handler_idx == VKD3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER) + { + ins->declaration.icb = resolve_forward_initialiser((uintptr_t)ins->declaration.icb, sm6); + } + } + for (i = base_value_idx; i < sm6->value_count; ++i) + { + const struct vkd3d_shader_immediate_constant_buffer *icb; + struct sm6_value *value = &sm6->values[i]; + + if (!sm6_value_is_register(value) || value->u.reg.type != VKD3DSPR_IMMCONSTBUFFER) + continue; + + if ((icb = resolve_forward_initialiser(value->u.reg.idx[0].offset, sm6))) + value->u.reg.idx[0].offset = icb->register_idx; } return VKD3D_OK; @@ -3171,6 +3250,67 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco } } +static enum vkd3d_shader_opcode map_dx_unary_op(enum dx_intrinsic_opcode op) +{ + switch (op) + { + case DX_EXP: + return VKD3DSIH_EXP; + case DX_FRC: + return VKD3DSIH_FRC; + case DX_LOG: + return VKD3DSIH_LOG; + case DX_SQRT: + return VKD3DSIH_SQRT; + case DX_RSQRT: + return VKD3DSIH_RSQ; + case DX_ROUND_NE: + return VKD3DSIH_ROUND_NE; + case DX_ROUND_NI: + return VKD3DSIH_ROUND_NI; + case DX_ROUND_PI: + return VKD3DSIH_ROUND_PI; + case DX_ROUND_Z: + return VKD3DSIH_ROUND_Z; + case DX_BFREV: + return VKD3DSIH_BFREV; + case DX_COUNT_BITS: + return VKD3DSIH_COUNTBITS; + case DX_FIRST_BIT_LO: + return VKD3DSIH_FIRSTBIT_LO; + case DX_FIRST_BIT_HI: + return VKD3DSIH_FIRSTBIT_HI; + case DX_FIRST_BIT_SHI: + return VKD3DSIH_FIRSTBIT_SHI; + case DX_DERIV_COARSEX: + return VKD3DSIH_DSX_COARSE; + case DX_DERIV_COARSEY: + return VKD3DSIH_DSY_COARSE; + case DX_DERIV_FINEX: + return VKD3DSIH_DSX_FINE; + case DX_DERIV_FINEY: + return VKD3DSIH_DSY_FINE; + case DX_LEGACY_F32TOF16: + return VKD3DSIH_F32TOF16; + case DX_LEGACY_F16TOF32: + return VKD3DSIH_F16TOF32; + default: + vkd3d_unreachable(); + } +} + +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) +{ + struct vkd3d_shader_src_param *src_param; + + vsir_instruction_init(ins, &sm6->p.location, map_dx_unary_op(op)); + src_param = instruction_src_params_alloc(ins, 1, sm6); + src_param_init_from_value(src_param, operands[0]); + + 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) { @@ -3344,7 +3484,7 @@ static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, struct sm6_b struct sm6_dx_opcode_info { - const char ret_type; + 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 *); @@ -3355,16 +3495,40 @@ struct sm6_dx_opcode_info b -> constant int1 c -> constant int8/16/32 i -> int32 + m -> int16/32/64 + f -> float + e -> half/float + g -> half/float/double H -> handle v -> void o -> overloaded */ static const struct sm6_dx_opcode_info sm6_dx_op_table[] = { - [DX_CBUFFER_LOAD_LEGACY ] = {'o', "Hi", sm6_parser_emit_dx_cbuffer_load}, - [DX_CREATE_HANDLE ] = {'H', "ccib", sm6_parser_emit_dx_create_handle}, - [DX_LOAD_INPUT ] = {'o', "ii8i", sm6_parser_emit_dx_load_input}, - [DX_STORE_OUTPUT ] = {'v', "ii8o", sm6_parser_emit_dx_store_output}, + [DX_BFREV ] = {"m0", "m", sm6_parser_emit_dx_unary}, + [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}, + [DX_DERIV_COARSEX ] = {"e0", "e", sm6_parser_emit_dx_unary}, + [DX_DERIV_COARSEY ] = {"e0", "e", sm6_parser_emit_dx_unary}, + [DX_DERIV_FINEX ] = {"e0", "e", sm6_parser_emit_dx_unary}, + [DX_DERIV_FINEY ] = {"e0", "e", sm6_parser_emit_dx_unary}, + [DX_EXP ] = {"g0", "g", sm6_parser_emit_dx_unary}, + [DX_FIRST_BIT_HI ] = {"i", "m", sm6_parser_emit_dx_unary}, + [DX_FIRST_BIT_LO ] = {"i", "m", sm6_parser_emit_dx_unary}, + [DX_FIRST_BIT_SHI ] = {"i", "m", sm6_parser_emit_dx_unary}, + [DX_FRC ] = {"g0", "g", sm6_parser_emit_dx_unary}, + [DX_LEGACY_F16TOF32 ] = {"f", "i", sm6_parser_emit_dx_unary}, + [DX_LEGACY_F32TOF16 ] = {"i", "f", sm6_parser_emit_dx_unary}, + [DX_LOAD_INPUT ] = {"o", "ii8i", sm6_parser_emit_dx_load_input}, + [DX_LOG ] = {"g0", "g", sm6_parser_emit_dx_unary}, + [DX_ROUND_NE ] = {"g0", "g", sm6_parser_emit_dx_unary}, + [DX_ROUND_NI ] = {"g0", "g", sm6_parser_emit_dx_unary}, + [DX_ROUND_PI ] = {"g0", "g", sm6_parser_emit_dx_unary}, + [DX_ROUND_Z ] = {"g0", "g", sm6_parser_emit_dx_unary}, + [DX_RSQRT ] = {"g0", "g", sm6_parser_emit_dx_unary}, + [DX_SQRT ] = {"g0", "g", sm6_parser_emit_dx_unary}, + [DX_STORE_OUTPUT ] = {"v", "ii8o", sm6_parser_emit_dx_store_output}, }; static bool sm6_parser_validate_operand_type(struct sm6_parser *sm6, const struct sm6_value *value, char info_type, @@ -3389,6 +3553,14 @@ static bool sm6_parser_validate_operand_type(struct sm6_parser *sm6, const struc && type->u.width <= 32; case 'i': return sm6_type_is_i32(type); + case 'm': + return sm6_type_is_i16_i32_i64(type); + case 'f': + return sm6_type_is_float(type); + case 'e': + return sm6_type_is_f16_f32(type); + case 'g': + return sm6_type_is_floating_point(type); case 'H': return (is_return || sm6_value_is_handle(value)) && type == sm6->handle_type; case 'v': @@ -3402,6 +3574,17 @@ static bool sm6_parser_validate_operand_type(struct sm6_parser *sm6, const struc } } +static bool operand_types_match(struct sm6_value *dst, const struct sm6_value **operands, unsigned int operand_count, + char index_char) +{ + unsigned int i = index_char - '0'; + + assert(i < 10); + if (i >= operand_count) + return false; + return dst->type == operands[i]->type; +} + static bool sm6_parser_validate_dx_op(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const char *name, const struct sm6_value **operands, unsigned int operand_count, struct sm6_value *dst) { @@ -3410,7 +3593,9 @@ 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, info->ret_type, true)) + assert(info->ret_type[0]); + if (!sm6_parser_validate_operand_type(sm6, dst, info->ret_type[0], true) + || (info->ret_type[1] && !operand_types_match(dst, operands, operand_count, info->ret_type[1]))) { 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 @@ -3700,6 +3885,9 @@ static void sm6_parser_emit_cast(struct sm6_parser *sm6, const struct dxil_recor if (handler_idx == VKD3DSIH_NOP) { dst->u.reg = value->u.reg; + /* Set the result type for casts from 16-bit min precision. */ + if (type->u.width != 16) + dst->u.reg.data_type = vkd3d_data_type_from_sm6_type(type); return; } @@ -4153,6 +4341,208 @@ static bool sm6_metadata_get_uint64_value(const struct sm6_parser *sm6, return true; } +static void sm6_parser_metadata_attachment_block_init(struct sm6_parser *sm6, const struct dxil_block *target_block, + const struct dxil_block *block) +{ + struct dxil_record *target_record; + const struct dxil_record *record; + unsigned int i; + uint64_t index; + + for (i = 0; i < block->record_count; ++i) + { + record = block->records[i]; + if (record->code != METADATA_ATTACHMENT) + { + WARN("Ignoring record with code %u.\n", record->code); + vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_ATTACHMENT, + "Ignoring a metadata attachment record with code %u.", record->code); + continue; + } + if (!(record->operand_count & 1)) + { + WARN("Ignoring function attachment.\n"); + vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_ATTACHMENT, + "Ignoring a metadata function attachment."); + continue; + } + + index = record->operands[0]; + if (!target_block->record_count || index >= target_block->record_count - 1) + { + WARN("Invalid record index %"PRIu64".\n", index); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, + "Invalid record index %"PRIu64" for a metadata attachment.", index); + continue; + } + /* 'index' is an instruction index, but records[0] is DECLAREBLOCKS, not an instruction. */ + target_record = target_block->records[index + 1]; + if (target_record->attachment) + { + WARN("Overwriting record attachment.\n"); + vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_ATTACHMENT, + "The target record for a metadata attachment already has an attachment."); + } + target_record->attachment = record; + } +} + +static void sm6_parser_metadata_attachments_init(struct sm6_parser *sm6, const struct dxil_block *block) +{ + unsigned int i; + + for (i = 0; i < block->child_block_count; ++i) + { + if (block->child_blocks[i]->id == METADATA_ATTACHMENT_BLOCK) + sm6_parser_metadata_attachment_block_init(sm6, block, block->child_blocks[i]); + } +} + +static const struct sm6_metadata_value *sm6_parser_find_metadata_kind(const struct sm6_parser *sm6, uint64_t id) +{ + unsigned int i, j; + + for (i = 0; i < ARRAY_SIZE(sm6->metadata_tables); ++i) + { + for (j = 0; j < sm6->metadata_tables[i].count; ++j) + { + if (sm6->metadata_tables[i].values[j].type == VKD3D_METADATA_KIND + && sm6->metadata_tables[i].values[j].u.kind.id == id) + return &sm6->metadata_tables[i].values[j]; + } + } + + return NULL; +} + +static const struct sm6_metadata_value *sm6_parser_metadata_get_value(const struct sm6_parser *sm6, uint64_t index) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(sm6->metadata_tables); ++i) + { + if (sm6->metadata_tables[i].count > index) + break; + index -= sm6->metadata_tables[i].count; + } + + return (index < sm6->metadata_tables[i].count) ? &sm6->metadata_tables[i].values[index] : NULL; +} + +static bool metadata_node_get_unary_uint(const struct sm6_metadata_node *node, unsigned int *operand, + struct sm6_parser *sm6) +{ + if (node->operand_count != 1) + { + FIXME("Ignoring node with %u operands.\n", node->operand_count); + vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_ATTACHMENT, + "Ignoring metadata attachment node with %u operands; expected unary.", node->operand_count); + return false; + } + if (!sm6_metadata_value_is_value(node->operands[0]) + || !sm6_metadata_get_uint_value(sm6, node->operands[0], operand)) + { + WARN("Failed to get operand value.\n"); + vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_ATTACHMENT, + "Failed to get a metadata attachment operand value; ignoring the attachment."); + return false; + } + + return true; +} + +static void metadata_attachment_record_apply(const struct dxil_record *record, enum bitcode_function_code func_code, + struct vkd3d_shader_instruction *ins, struct sm6_value *dst, struct sm6_parser *sm6) +{ + static const char *ignored_names[] = + { + "alias.scope", + "dx.controlflow.hints", + "llvm.loop", + "noalias", + "tbaa", + "range", + }; + const struct sm6_metadata_node *node; + const struct sm6_metadata_value *m; + unsigned int i, j, operand; + bool ignored = false; + const char *name; + + if (record->attachment) + { + WARN("Ignoring nested metadata attachment.\n"); + vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_ATTACHMENT, + "Ignoring a nested metadata attachment."); + } + + assert(record->operand_count & 1); + for (i = 1; i < record->operand_count; i += 2) + { + if (!(m = sm6_parser_find_metadata_kind(sm6, record->operands[i]))) + { + WARN("Failed to find metadata kind %"PRIx64".\n", record->operands[i]); + vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_ATTACHMENT, + "Failed to find metadata kind %"PRIx64" for an attachment.", record->operands[i]); + continue; + } + name = m->u.kind.name; + + m = sm6_parser_metadata_get_value(sm6, record->operands[i + 1]); + if (!m || !sm6_metadata_value_is_node(m)) + { + WARN("Failed to retrieve metadata attachment node.\n"); + vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_ATTACHMENT, + "Failed to retrieve a metadata attachment node."); + continue; + } + node = m->u.node; + + if (!strcmp(name, "dx.precise")) + { + if (!sm6_value_is_register(dst)) + { + WARN("Precise value is not a register.\n"); + vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_ATTACHMENT, + "A value marked as precise is not a register."); + } + else if (metadata_node_get_unary_uint(node, &operand, sm6) && operand) + { + ins->flags |= sm6_type_is_scalar(dst->type) ? VKD3DSI_PRECISE_X : VKD3DSI_PRECISE_XYZW; + } + } + else if (!strcmp(name, "dx.nonuniform")) + { + if (!sm6_value_is_register(dst)) + { + WARN("Non-uniform value is not a register.\n"); + vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_ATTACHMENT, + "A value marked as non-uniform is not a register."); + } + else if (metadata_node_get_unary_uint(node, &operand, sm6)) + { + dst->u.reg.non_uniform = !!operand; + } + } + else + { + for (j = 0; j < ARRAY_SIZE(ignored_names); ++j) + if (!strcmp(name, ignored_names[j])) + break; + if (j == ARRAY_SIZE(ignored_names)) + { + WARN("Ignoring metadata attachment '%s'.\n", name); + vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_ATTACHMENT, + "Ignoring a metadata attachment named '%s'.", name); + } + ignored = true; + } + + if (func_code != FUNC_CODE_INST_CALL && !ignored) + WARN("Metadata attachment target is not a function call.\n"); + } +} + static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const struct dxil_block *block, struct sm6_function *function) { @@ -4278,6 +4668,9 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const return VKD3D_ERROR; assert(ins->handler_idx != VKD3DSIH_INVALID); + if (record->attachment) + metadata_attachment_record_apply(record->attachment, record->code, ins, dst, sm6); + if (is_terminator) { ++block_idx; @@ -4331,6 +4724,8 @@ static enum vkd3d_result sm6_parser_module_init(struct sm6_parser *sm6, const st sm6->p.location.line = block->id; sm6->p.location.column = 0; + sm6_parser_metadata_attachments_init(sm6, block); + switch (block->id) { case CONSTANTS_BLOCK: diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y index 0dde4c18587..ed053f16312 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y @@ -487,27 +487,27 @@ static void resolve_loop_continue(struct hlsl_ctx *ctx, struct hlsl_block *block else if (instr->type == HLSL_IR_JUMP) { struct hlsl_ir_jump *jump = hlsl_ir_jump(instr); - struct hlsl_block block; + struct hlsl_block cond_block; if (jump->type != HLSL_IR_JUMP_UNRESOLVED_CONTINUE) continue; if (type == LOOP_DO_WHILE) { - if (!hlsl_clone_block(ctx, &block, cond)) + if (!hlsl_clone_block(ctx, &cond_block, cond)) return; - if (!append_conditional_break(ctx, &block)) + if (!append_conditional_break(ctx, &cond_block)) { - hlsl_block_cleanup(&block); + hlsl_block_cleanup(&cond_block); return; } - list_move_before(&instr->entry, &block.instrs); + list_move_before(&instr->entry, &cond_block.instrs); } else if (type == LOOP_FOR) { - if (!hlsl_clone_block(ctx, &block, iter)) + if (!hlsl_clone_block(ctx, &cond_block, iter)) return; - list_move_before(&instr->entry, &block.instrs); + list_move_before(&instr->entry, &cond_block.instrs); } jump->type = HLSL_IR_JUMP_CONTINUE; } @@ -3553,7 +3553,7 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer * { struct hlsl_resource_load_params load_params = { 0 }; const struct hlsl_type *sampler_type; - struct hlsl_ir_node *coords, *load; + struct hlsl_ir_node *coords, *sample; if (params->args_count != 2 && params->args_count != 4) { @@ -3688,9 +3688,9 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer * load_params.format = hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, 4); load_params.sampling_dim = dim; - if (!(load = hlsl_new_resource_load(ctx, &load_params, loc))) + if (!(sample = hlsl_new_resource_load(ctx, &load_params, loc))) return false; - hlsl_block_add_instr(params->instrs, load); + hlsl_block_add_instr(params->instrs, sample); return true; } diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c index 4a622185741..88cbef61d5f 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c @@ -1090,7 +1090,7 @@ static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, unsigned int dim_count = hlsl_sampler_dim_count(val->data_type->sampler_dim); struct hlsl_ir_node *coords = index->idx.node; struct hlsl_resource_load_params params = {0}; - struct hlsl_ir_node *load; + struct hlsl_ir_node *resource_load; assert(coords->data_type->class == HLSL_CLASS_VECTOR); assert(coords->data_type->base_type == HLSL_TYPE_UINT); @@ -1104,9 +1104,9 @@ static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, params.coords = coords; params.format = val->data_type->e.resource_format; - if (!(load = hlsl_new_resource_load(ctx, ¶ms, &instr->loc))) + if (!(resource_load = hlsl_new_resource_load(ctx, ¶ms, &instr->loc))) return false; - hlsl_block_add_instr(block, load); + hlsl_block_add_instr(block, resource_load); return true; } @@ -2301,7 +2301,6 @@ static bool normalize_switch_cases(struct hlsl_ctx *ctx, struct hlsl_ir_node *in struct hlsl_ir_switch_case *c, *def = NULL; bool missing_terminal_break = false; struct hlsl_ir_node *node; - struct hlsl_ir_jump *jump; struct hlsl_ir_switch *s; if (instr->type != HLSL_IR_SWITCH) @@ -2320,10 +2319,7 @@ static bool normalize_switch_cases(struct hlsl_ctx *ctx, struct hlsl_ir_node *in { node = LIST_ENTRY(list_tail(&c->body.instrs), struct hlsl_ir_node, entry); if (node->type == HLSL_IR_JUMP) - { - jump = hlsl_ir_jump(node); - terminal_break = jump->type == HLSL_IR_JUMP_BREAK; - } + terminal_break = (hlsl_ir_jump(node)->type == HLSL_IR_JUMP_BREAK); } missing_terminal_break |= !terminal_break; diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c index 710811c6761..a35ef862096 100644 --- a/libs/vkd3d/libs/vkd3d-shader/ir.c +++ b/libs/vkd3d/libs/vkd3d-shader/ir.c @@ -463,6 +463,7 @@ static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_i struct vkd3d_shader_instruction_array *instructions; struct control_point_normaliser normaliser; unsigned int input_control_point_count; + struct vkd3d_shader_location location; struct vkd3d_shader_instruction *ins; enum vkd3d_result ret; unsigned int i, j; @@ -513,8 +514,10 @@ static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_i return VKD3D_OK; case VKD3DSIH_HS_FORK_PHASE: case VKD3DSIH_HS_JOIN_PHASE: + /* ins may be relocated if the instruction array expands. */ + location = ins->location; ret = control_point_normaliser_emit_hs_input(&normaliser, input_signature, - input_control_point_count, i, &ins->location); + input_control_point_count, i, &location); *src_instructions = normaliser.instructions; return ret; default: diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c index c8a43adbe03..a22c59577ac 100644 --- a/libs/vkd3d/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c @@ -1194,6 +1194,16 @@ static uint32_t vkd3d_spirv_get_op_constant64(struct vkd3d_spirv_builder *builde (const uint32_t *)&value, 2, vkd3d_spirv_build_op_constant64); } +static uint32_t vkd3d_spirv_build_op_constant_null(struct vkd3d_spirv_builder *builder, uint32_t result_type) +{ + return vkd3d_spirv_build_op_tr(builder, &builder->global_stream, SpvOpConstantNull, result_type); +} + +static uint32_t vkd3d_spirv_get_op_constant_null(struct vkd3d_spirv_builder *builder, uint32_t result_type) +{ + return vkd3d_spirv_build_once1(builder, SpvOpConstantNull, result_type, vkd3d_spirv_build_op_constant_null); +} + static uint32_t vkd3d_spirv_build_op_constant_composite(struct vkd3d_spirv_builder *builder, uint32_t result_type, const uint32_t *constituents, unsigned int constituent_count) { @@ -2152,6 +2162,7 @@ static void vkd3d_symbol_make_register(struct vkd3d_symbol *symbol, break; case VKD3DSPR_IMMCONSTBUFFER: + symbol->key.reg.idx = reg->idx_count > 1 ? reg->idx[0].offset : 0; break; default: @@ -3498,7 +3509,7 @@ static void spirv_compiler_emit_dereference_register(struct spirv_compiler *comp } else if (reg->type == VKD3DSPR_IMMCONSTBUFFER) { - indexes[index_count++] = spirv_compiler_emit_register_addressing(compiler, ®->idx[0]); + indexes[index_count++] = spirv_compiler_emit_register_addressing(compiler, ®->idx[reg->idx_count - 1]); } else if (reg->type == VKD3DSPR_IDXTEMP) { @@ -3756,6 +3767,69 @@ static uint32_t spirv_compiler_emit_load_scalar(struct spirv_compiler *compiler, return val_id; } +static uint32_t spirv_compiler_emit_constant_array(struct spirv_compiler *compiler, + const struct vkd3d_shader_immediate_constant_buffer *icb, uint32_t *type_id_out) +{ + uint32_t *elements, elem_type_id, length_id, type_id, const_id; + struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; + enum vkd3d_shader_component_type component_type; + unsigned int i, element_count, component_count; + + element_count = icb->element_count; + + component_type = vkd3d_component_type_from_data_type(icb->data_type); + component_count = icb->component_count; + elem_type_id = vkd3d_spirv_get_type_id_for_data_type(builder, icb->data_type, component_count); + length_id = spirv_compiler_get_constant_uint(compiler, element_count); + type_id = vkd3d_spirv_get_op_type_array(builder, elem_type_id, length_id); + + if (type_id_out) + *type_id_out = type_id; + + if (icb->is_null) + { + /* All values are null. Workgroup memory initialisers require OpConstantNull. */ + return vkd3d_spirv_get_op_constant_null(builder, type_id); + } + + if (!(elements = vkd3d_calloc(element_count, sizeof(*elements)))) + { + ERR("Failed to allocate %u elements.", element_count); + spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_OUT_OF_MEMORY, + "Failed to allocate %u constant array elements.", element_count); + return 0; + } + + switch (icb->data_type) + { + case VKD3D_DATA_FLOAT: + case VKD3D_DATA_INT: + case VKD3D_DATA_UINT: + for (i = 0; i < element_count; ++i) + elements[i] = spirv_compiler_get_constant(compiler, component_type, component_count, + &icb->data[component_count * i]); + break; + case VKD3D_DATA_DOUBLE: + case VKD3D_DATA_UINT64: + { + uint64_t *data = (uint64_t *)icb->data; + for (i = 0; i < element_count; ++i) + elements[i] = spirv_compiler_get_constant64(compiler, component_type, component_count, + &data[component_count * i]); + break; + } + default: + FIXME("Unhandled data type %u.\n", icb->data_type); + spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_INVALID_TYPE, + "Immediate constant buffer data type %u is unhandled.", icb->data_type); + break; + } + + const_id = vkd3d_spirv_build_op_constant_composite(builder, type_id, elements, element_count); + vkd3d_free(elements); + return const_id; +} + static const struct ssa_register_info *spirv_compiler_get_ssa_register_info(const struct spirv_compiler *compiler, const struct vkd3d_shader_register *reg) { @@ -5493,39 +5567,40 @@ static void spirv_compiler_emit_dcl_indexable_temp(struct spirv_compiler *compil { const struct vkd3d_shader_indexable_temp *temp = &instruction->declaration.indexable_temp; struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; + uint32_t id, type_id, length_id, ptr_type_id, init_id = 0; + enum vkd3d_shader_component_type component_type; struct vkd3d_shader_register reg; struct vkd3d_symbol reg_symbol; + SpvStorageClass storage_class; size_t function_location; - uint32_t id; - if (temp->component_count != 4) - FIXME("Unhandled component count %u.\n", temp->component_count); + storage_class = SpvStorageClassFunction; vsir_register_init(®, VKD3DSPR_IDXTEMP, VKD3D_DATA_FLOAT, 1); reg.idx[0].offset = temp->register_idx; if (temp->alignment) WARN("Ignoring alignment %u.\n", temp->alignment); - if (temp->initialiser) - { - FIXME("Initialisers are not supported.\n"); - spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, - "Initialisers for indexable temps are not supported."); - } function_location = spirv_compiler_get_current_function_location(compiler); vkd3d_spirv_begin_function_stream_insertion(builder, function_location); - id = spirv_compiler_emit_array_variable(compiler, &builder->function_stream, - SpvStorageClassFunction, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE, &temp->register_size, 1); + component_type = vkd3d_component_type_from_data_type(temp->data_type); + type_id = vkd3d_spirv_get_type_id(builder, component_type, temp->component_count); + length_id = spirv_compiler_get_constant_uint(compiler, temp->register_size); + type_id = vkd3d_spirv_get_op_type_array(builder, type_id, length_id); + ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, storage_class, type_id); + if (temp->initialiser) + init_id = spirv_compiler_emit_constant_array(compiler, temp->initialiser, NULL); + id = vkd3d_spirv_build_op_variable(builder, &builder->function_stream, ptr_type_id, storage_class, init_id); spirv_compiler_emit_register_debug_name(builder, id, ®); vkd3d_spirv_end_function_stream_insertion(builder); vkd3d_symbol_make_register(®_symbol, ®); - vkd3d_symbol_set_register_info(®_symbol, id, - SpvStorageClassFunction, VKD3D_SHADER_COMPONENT_FLOAT, VKD3DSP_WRITEMASK_ALL); + vkd3d_symbol_set_register_info(®_symbol, id, storage_class, + component_type, vkd3d_write_mask_from_component_count(temp->component_count)); spirv_compiler_put_symbol(compiler, ®_symbol); } @@ -5743,34 +5818,24 @@ static void spirv_compiler_emit_dcl_immediate_constant_buffer(struct spirv_compi const struct vkd3d_shader_instruction *instruction) { const struct vkd3d_shader_immediate_constant_buffer *icb = instruction->declaration.icb; - uint32_t *elements, length_id, type_id, const_id, ptr_type_id, icb_id; struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; + uint32_t type_id, const_id, ptr_type_id, icb_id; struct vkd3d_shader_register reg; struct vkd3d_symbol reg_symbol; - unsigned int i; - assert(icb->data_type == VKD3D_DATA_FLOAT); - assert(icb->component_count == VKD3D_VEC4_SIZE); - - if (!(elements = vkd3d_calloc(icb->element_count, sizeof(*elements)))) - return; - for (i = 0; i < icb->element_count; ++i) - elements[i] = spirv_compiler_get_constant(compiler, - VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE, &icb->data[4 * i]); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE); - length_id = spirv_compiler_get_constant_uint(compiler, icb->element_count); - type_id = vkd3d_spirv_get_op_type_array(builder, type_id, length_id); - const_id = vkd3d_spirv_build_op_constant_composite(builder, type_id, elements, icb->element_count); + const_id = spirv_compiler_emit_constant_array(compiler, icb, &type_id); ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassPrivate, type_id); icb_id = vkd3d_spirv_build_op_variable(builder, &builder->global_stream, ptr_type_id, SpvStorageClassPrivate, const_id); vkd3d_spirv_build_op_name(builder, icb_id, "icb"); - vkd3d_free(elements); - vsir_register_init(®, VKD3DSPR_IMMCONSTBUFFER, VKD3D_DATA_FLOAT, 0); + /* Set an index count of 2 so vkd3d_symbol_make_register() uses idx[0] as a buffer id. */ + vsir_register_init(®, VKD3DSPR_IMMCONSTBUFFER, VKD3D_DATA_FLOAT, 2); + reg.idx[0].offset = icb->register_idx; vkd3d_symbol_make_register(®_symbol, ®); vkd3d_symbol_set_register_info(®_symbol, icb_id, SpvStorageClassPrivate, - VKD3D_SHADER_COMPONENT_FLOAT, VKD3DSP_WRITEMASK_ALL); + vkd3d_component_type_from_data_type(icb->data_type), + vkd3d_write_mask_from_component_count(icb->component_count)); spirv_compiler_put_symbol(compiler, ®_symbol); } diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c index 80f8ab98c08..163cd90ee13 100644 --- a/libs/vkd3d/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c @@ -792,9 +792,11 @@ static void shader_sm4_read_shader_data(struct vkd3d_shader_instruction *ins, ui ins->handler_idx = VKD3DSIH_INVALID; return; } + icb->register_idx = 0; icb->data_type = VKD3D_DATA_FLOAT; icb->component_count = VKD3D_VEC4_SIZE; icb->element_count = icb_size / VKD3D_VEC4_SIZE; + icb->is_null = false; memcpy(icb->data, tokens, sizeof(*tokens) * icb_size); shader_instruction_array_add_icb(&priv->p.instructions, icb); ins->declaration.icb = icb; @@ -1930,6 +1932,15 @@ static bool shader_sm4_read_param(struct vkd3d_shader_sm4_parser *priv, const ui break; } } + else if (register_type == VKD3D_SM4_RT_IMMCONSTBUFFER) + { + if (param->idx_count != 1) + { + WARN("Unexpected idx count %u.\n", param->idx_count); + vkd3d_shader_parser_error(&priv->p, VKD3D_SHADER_ERROR_TPF_INVALID_REGISTER_INDEX_COUNT, + "Invalid index count %u for immediate const buffer register; expected count 1.", param->idx_count); + } + } else if (!shader_is_sm_5_1(priv) && vsir_register_is_descriptor(param)) { /* SM5.1 places a symbol identifier in idx[0] and moves diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c index 8fd8945151f..d4a9d391477 100644 --- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c +++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c @@ -23,6 +23,8 @@ #include #include +/* VKD3D_DEBUG_ENV_NAME("VKD3D_SHADER_DEBUG"); */ + static inline int char_to_int(char c) { if ('0' <= c && c <= '9') @@ -888,6 +890,21 @@ static void vkd3d_shader_scan_combined_sampler_declaration( &semantic->resource.range, semantic->resource_type, VKD3D_SHADER_RESOURCE_DATA_FLOAT); } +static const struct vkd3d_shader_descriptor_info1 *find_descriptor( + const struct vkd3d_shader_scan_descriptor_info1 *info, + enum vkd3d_shader_descriptor_type type, unsigned int register_id) +{ + for (unsigned int i = 0; i < info->descriptor_count; ++i) + { + const struct vkd3d_shader_descriptor_info1 *d = &info->descriptors[i]; + + if (d->type == type && d->register_id == register_id) + return d; + } + + return NULL; +} + static void vkd3d_shader_scan_combined_sampler_usage(struct vkd3d_shader_scan_context *context, const struct vkd3d_shader_register *resource, const struct vkd3d_shader_register *sampler) { @@ -913,7 +930,6 @@ static void vkd3d_shader_scan_combined_sampler_usage(struct vkd3d_shader_scan_co if (vkd3d_shader_ver_ge(context->version, 5, 1)) { - const struct vkd3d_shader_scan_descriptor_info1 *info = context->scan_descriptor_info; const struct vkd3d_shader_descriptor_info1 *d; bool dynamic_resource, dynamic_sampler; @@ -928,30 +944,13 @@ static void vkd3d_shader_scan_combined_sampler_usage(struct vkd3d_shader_scan_co if (dynamic_resource || dynamic_sampler) return; - for (i = 0; i < info->descriptor_count; ++i) - { - d = &info->descriptors[i]; - if (d->type != VKD3D_SHADER_DESCRIPTOR_TYPE_SRV) - continue; - if (d->register_id != resource->idx[0].offset) - continue; + if ((d = find_descriptor(context->scan_descriptor_info, + VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, resource->idx[0].offset))) resource_space = d->register_space; - break; - } - if (sampler) - { - for (i = 0; i < info->descriptor_count; ++i) - { - d = &info->descriptors[i]; - if (d->type != VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER) - continue; - if (d->register_id != sampler->idx[0].offset) - continue; - sampler_space = d->register_space; - break; - } - } + if (sampler && (d = find_descriptor(context->scan_descriptor_info, + VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, sampler->idx[0].offset))) + sampler_space = d->register_space; } for (i = 0; i < info->combined_sampler_count; ++i) diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h index a93fa7160f7..4944b8a1c53 100644 --- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h @@ -196,6 +196,7 @@ enum vkd3d_shader_error VKD3D_SHADER_WARNING_DXIL_ENTRY_POINT_MISMATCH = 8306, VKD3D_SHADER_WARNING_DXIL_INVALID_MASK = 8307, VKD3D_SHADER_WARNING_DXIL_INVALID_OPERATION = 8308, + VKD3D_SHADER_WARNING_DXIL_IGNORING_ATTACHMENT = 8309, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED = 9000, VKD3D_SHADER_ERROR_VSIR_INVALID_HANDLER = 9001, @@ -793,10 +794,12 @@ struct vkd3d_shader_version struct vkd3d_shader_immediate_constant_buffer { + unsigned int register_idx; enum vkd3d_data_type data_type; /* total count is element_count * component_count */ unsigned int element_count; unsigned int component_count; + bool is_null; uint32_t data[]; }; -- 2.43.0