From 292830fa822b76fa160a8fc8d1ac145adabd1b1e Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Thu, 17 Apr 2025 08:55:47 +1000 Subject: [PATCH] Updated vkd3d-latest patchset --- ...-f576ecc9929dd98c900bb8bc0335b91a1a0.patch | 5 +- ...-cbce3a8631116ec10895e6c9c4a00b89b05.patch | 5 +- ...-f02ea94c428f6b2f662f78fc78eae7f3342.patch | 1765 +++++++++++++++++ ...-c764f71cf58e3a8327b44c588ad3696b422.patch | 304 +++ 4 files changed, 2073 insertions(+), 6 deletions(-) create mode 100644 patches/vkd3d-latest/0003-Updated-vkd3d-to-f02ea94c428f6b2f662f78fc78eae7f3342.patch create mode 100644 patches/vkd3d-latest/0004-Updated-vkd3d-to-c764f71cf58e3a8327b44c588ad3696b422.patch diff --git a/patches/vkd3d-latest/0001-Updated-vkd3d-to-f576ecc9929dd98c900bb8bc0335b91a1a0.patch b/patches/vkd3d-latest/0001-Updated-vkd3d-to-f576ecc9929dd98c900bb8bc0335b91a1a0.patch index c98bcdf8..e2b50ea9 100644 --- a/patches/vkd3d-latest/0001-Updated-vkd3d-to-f576ecc9929dd98c900bb8bc0335b91a1a0.patch +++ b/patches/vkd3d-latest/0001-Updated-vkd3d-to-f576ecc9929dd98c900bb8bc0335b91a1a0.patch @@ -1,8 +1,7 @@ -From 8e84e1a5750fac027178bb160050030e2786680b Mon Sep 17 00:00:00 2001 +From 7e86c25d99b4ebaa196bb0cfe1053d9d9a4cc9f8 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Fri, 21 Feb 2025 09:15:01 +1100 -Subject: [PATCH 1/2] Updated vkd3d to - f576ecc9929dd98c900bb8bc0335b91a1a0d3bff. +Subject: [PATCH] Updated vkd3d to f576ecc9929dd98c900bb8bc0335b91a1a0d3bff. --- libs/vkd3d/include/private/spirv_grammar.h | 10103 ++++++++++++++++ diff --git a/patches/vkd3d-latest/0002-Updated-vkd3d-to-cbce3a8631116ec10895e6c9c4a00b89b05.patch b/patches/vkd3d-latest/0002-Updated-vkd3d-to-cbce3a8631116ec10895e6c9c4a00b89b05.patch index 68e3bf36..9216fb58 100644 --- a/patches/vkd3d-latest/0002-Updated-vkd3d-to-cbce3a8631116ec10895e6c9c4a00b89b05.patch +++ b/patches/vkd3d-latest/0002-Updated-vkd3d-to-cbce3a8631116ec10895e6c9c4a00b89b05.patch @@ -1,8 +1,7 @@ -From d682beb0dff9eff34d01f2e517145d17d561ef01 Mon Sep 17 00:00:00 2001 +From 32c6084506f963100eb55be8df149437b5e8d4f0 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Thu, 10 Apr 2025 07:44:42 +1000 -Subject: [PATCH 2/2] Updated vkd3d to - cbce3a8631116ec10895e6c9c4a00b89b051f6b0. +Subject: [PATCH] Updated vkd3d to cbce3a8631116ec10895e6c9c4a00b89b051f6b0. --- libs/vkd3d/libs/vkd3d-shader/fx.c | 44 ++++++++++++++++----- diff --git a/patches/vkd3d-latest/0003-Updated-vkd3d-to-f02ea94c428f6b2f662f78fc78eae7f3342.patch b/patches/vkd3d-latest/0003-Updated-vkd3d-to-f02ea94c428f6b2f662f78fc78eae7f3342.patch new file mode 100644 index 00000000..d303514d --- /dev/null +++ b/patches/vkd3d-latest/0003-Updated-vkd3d-to-f02ea94c428f6b2f662f78fc78eae7f3342.patch @@ -0,0 +1,1765 @@ +From 8684d82a0d27ada846a357d0fec558fbb23334c2 Mon Sep 17 00:00:00 2001 +From: Alistair Leslie-Hughes +Date: Tue, 15 Apr 2025 08:45:19 +1000 +Subject: [PATCH] Updated vkd3d to f02ea94c428f6b2f662f78fc78eae7f33428e9de. + +--- + libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 205 ++++++-- + libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 70 +-- + libs/vkd3d/libs/vkd3d-shader/dxil.c | 4 +- + libs/vkd3d/libs/vkd3d-shader/glsl.c | 68 ++- + libs/vkd3d/libs/vkd3d-shader/hlsl.y | 63 +++ + libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 23 +- + libs/vkd3d/libs/vkd3d-shader/ir.c | 21 +- + libs/vkd3d/libs/vkd3d-shader/msl.c | 463 ++++++++++++------ + libs/vkd3d/libs/vkd3d-shader/spirv.c | 2 +- + .../libs/vkd3d-shader/vkd3d_shader_main.c | 121 +++-- + .../libs/vkd3d-shader/vkd3d_shader_private.h | 33 +- + 11 files changed, 714 insertions(+), 359 deletions(-) + +diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c +index 764f0888490..4521bfabd8e 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c ++++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c +@@ -687,7 +687,7 @@ static void shader_print_input_sysval_semantic(struct vkd3d_d3d_asm_compiler *co + prefix, compiler->colours.error, semantic, compiler->colours.reset, suffix); + } + +-static void shader_dump_resource_type(struct vkd3d_d3d_asm_compiler *compiler, enum vkd3d_shader_resource_type type) ++static void shader_print_resource_type(struct vkd3d_d3d_asm_compiler *compiler, enum vkd3d_shader_resource_type type) + { + static const char *const resource_type_names[] = + { +@@ -707,10 +707,11 @@ static void shader_dump_resource_type(struct vkd3d_d3d_asm_compiler *compiler, e + if (type < ARRAY_SIZE(resource_type_names)) + vkd3d_string_buffer_printf(&compiler->buffer, "%s", resource_type_names[type]); + else +- vkd3d_string_buffer_printf(&compiler->buffer, "unknown"); ++ vkd3d_string_buffer_printf(&compiler->buffer, "%s%s", ++ compiler->colours.error, type, compiler->colours.reset); + } + +-static void shader_dump_data_type(struct vkd3d_d3d_asm_compiler *compiler, enum vkd3d_data_type type) ++static void shader_print_data_type(struct vkd3d_d3d_asm_compiler *compiler, enum vkd3d_data_type type) + { + static const char *const data_type_names[] = + { +@@ -731,14 +732,11 @@ static void shader_dump_data_type(struct vkd3d_d3d_asm_compiler *compiler, enum + [VKD3D_DATA_HALF ] = "half", + }; + +- const char *name; +- + if (type < ARRAY_SIZE(data_type_names)) +- name = data_type_names[type]; ++ vkd3d_string_buffer_printf(&compiler->buffer, "%s", data_type_names[type]); + else +- name = ""; +- +- vkd3d_string_buffer_printf(&compiler->buffer, "%s", name); ++ vkd3d_string_buffer_printf(&compiler->buffer, "%s%s", ++ compiler->colours.error, type, compiler->colours.reset); + } + + static void shader_dump_resource_data_type(struct vkd3d_d3d_asm_compiler *compiler, const enum vkd3d_data_type *type) +@@ -750,7 +748,7 @@ static void shader_dump_resource_data_type(struct vkd3d_d3d_asm_compiler *compil + for (i = 0; i < 4; i++) + { + vkd3d_string_buffer_printf(&compiler->buffer, "%s", i == 0 ? "" : ","); +- shader_dump_data_type(compiler, type[i]); ++ shader_print_data_type(compiler, type[i]); + } + + vkd3d_string_buffer_printf(&compiler->buffer, ")"); +@@ -793,7 +791,7 @@ static void shader_print_dcl_usage(struct vkd3d_d3d_asm_compiler *compiler, + if (semantic->resource.reg.reg.type == VKD3DSPR_RESOURCE) + vkd3d_string_buffer_printf(buffer, "resource_"); + +- shader_dump_resource_type(compiler, semantic->resource_type); ++ shader_print_resource_type(compiler, semantic->resource_type); + if (semantic->resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMS + || semantic->resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY) + { +@@ -1294,7 +1292,7 @@ static void shader_print_reg_type(struct vkd3d_d3d_asm_compiler *compiler, + dimension = "??"; + + vkd3d_string_buffer_printf(buffer, "%s <%s", prefix, dimension); +- shader_dump_data_type(compiler, reg->data_type); ++ shader_print_data_type(compiler, reg->data_type); + vkd3d_string_buffer_printf(buffer, ">%s", suffix); + } + +@@ -1998,7 +1996,7 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler, + vkd3d_string_buffer_printf(buffer, "raw_"); + if (ins->structured) + vkd3d_string_buffer_printf(buffer, "structured_"); +- shader_dump_resource_type(compiler, ins->resource_type); ++ shader_print_resource_type(compiler, ins->resource_type); + if (ins->resource_stride) + shader_print_uint_literal(compiler, ", stride=", ins->resource_stride, ""); + vkd3d_string_buffer_printf(buffer, ")"); +@@ -2202,10 +2200,80 @@ static enum vkd3d_result dump_dxbc_signatures(struct vkd3d_d3d_asm_compiler *com + &program->patch_constant_signature)) < 0) + return ret; + +- vkd3d_string_buffer_printf(&compiler->buffer, "%s.text%s\n", ++ return VKD3D_OK; ++} ++ ++static void shader_print_descriptor_name(struct vkd3d_d3d_asm_compiler *compiler, ++ enum vkd3d_shader_descriptor_type t, unsigned int id) ++{ ++ const char *type = NULL; ++ ++ switch (t) ++ { ++ case VKD3D_SHADER_DESCRIPTOR_TYPE_SRV: ++ type = shader_register_names[VKD3DSPR_RESOURCE]; ++ break; ++ case VKD3D_SHADER_DESCRIPTOR_TYPE_UAV: ++ type = shader_register_names[VKD3DSPR_UAV]; ++ break; ++ case VKD3D_SHADER_DESCRIPTOR_TYPE_CBV: ++ type = shader_register_names[VKD3DSPR_CONSTBUFFER]; ++ break; ++ case VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER: ++ type = shader_register_names[VKD3DSPR_SAMPLER]; ++ break; ++ case VKD3D_SHADER_DESCRIPTOR_TYPE_FORCE_32BIT: ++ break; ++ } ++ ++ if (type) ++ vkd3d_string_buffer_printf(&compiler->buffer, "%s%s%u%s", ++ compiler->colours.reg, type, id, compiler->colours.reset); ++ else ++ vkd3d_string_buffer_printf(&compiler->buffer, "%s%u%s", ++ compiler->colours.error, t, id, compiler->colours.reset); ++} ++ ++static void shader_print_descriptors(struct vkd3d_d3d_asm_compiler *compiler, ++ const struct vkd3d_shader_scan_descriptor_info1 *descriptors) ++{ ++ struct vkd3d_string_buffer *buffer = &compiler->buffer; ++ unsigned int i; ++ ++ vkd3d_string_buffer_printf(buffer, "%s.descriptors%s\n", + compiler->colours.opcode, compiler->colours.reset); ++ for (i = 0; i < descriptors->descriptor_count; ++i) ++ { ++ const struct vkd3d_shader_descriptor_info1 *d = &descriptors->descriptors[i]; + +- return VKD3D_OK; ++ vkd3d_string_buffer_printf(buffer, "%s.descriptor%s ", compiler->colours.opcode, compiler->colours.reset); ++ shader_print_descriptor_name(compiler, d->type, d->register_id); ++ shader_print_subscript_range(compiler, d->register_index, ++ d->count == ~0u ? ~0u : d->register_index + d->count - 1); ++ shader_dump_register_space(compiler, d->register_space); ++ ++ if (d->type == VKD3D_SHADER_DESCRIPTOR_TYPE_SRV || d->type == VKD3D_SHADER_DESCRIPTOR_TYPE_UAV) ++ { ++ vkd3d_string_buffer_printf(buffer, ", "); ++ shader_print_resource_type(compiler, d->resource_type); ++ vkd3d_string_buffer_printf(buffer, " resource_data_type); ++ if (d->resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMS ++ || d->resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY) ++ shader_print_uint_literal(compiler, ", ", d->sample_count, ""); ++ vkd3d_string_buffer_printf(buffer, ">"); ++ } ++ ++ if (d->buffer_size) ++ shader_print_hex_literal(compiler, ", size=", d->buffer_size, ""); ++ if (d->structure_stride) ++ shader_print_hex_literal(compiler, ", stride=", d->structure_stride, ""); ++ if (d->flags) ++ shader_print_hex_literal(compiler, ", flags=", d->flags, ""); ++ if (d->uav_flags) ++ shader_print_hex_literal(compiler, ", uav_flags=", d->uav_flags, ""); ++ vkd3d_string_buffer_printf(buffer, "\n"); ++ } + } + + enum vkd3d_result d3d_asm_compile(const struct vsir_program *program, +@@ -2271,6 +2339,10 @@ enum vkd3d_result d3d_asm_compile(const struct vsir_program *program, + indent_str = " "; + else + indent_str = ""; ++ /* The signatures we emit only make sense for DXBC shaders. d3dbc doesn't ++ * even have an explicit concept of signature. */ ++ if (formatting & VKD3D_SHADER_COMPILE_OPTION_FORMATTING_IO_SIGNATURES && shader_version->major >= 4) ++ compiler.flags |= VSIR_ASM_FLAG_DUMP_SIGNATURES; + + buffer = &compiler.buffer; + vkd3d_string_buffer_init(buffer); +@@ -2281,17 +2353,19 @@ enum vkd3d_result d3d_asm_compile(const struct vsir_program *program, + shader_get_type_prefix(shader_version->type), shader_version->major, + shader_version->minor, compiler.colours.reset); + +- /* The signatures we emit only make sense for DXBC shaders. D3DBC +- * doesn't even have an explicit concept of signature. */ +- if (formatting & VKD3D_SHADER_COMPILE_OPTION_FORMATTING_IO_SIGNATURES && shader_version->major >= 4) ++ if (compiler.flags & VSIR_ASM_FLAG_DUMP_SIGNATURES ++ && (result = dump_dxbc_signatures(&compiler, program)) < 0) + { +- if ((result = dump_dxbc_signatures(&compiler, program)) < 0) +- { +- vkd3d_string_buffer_cleanup(buffer); +- return result; +- } ++ vkd3d_string_buffer_cleanup(buffer); ++ return result; + } + ++ if (compiler.flags & VSIR_ASM_FLAG_DUMP_DESCRIPTORS) ++ shader_print_descriptors(&compiler, &program->descriptors); ++ ++ if (compiler.flags & (VSIR_ASM_FLAG_DUMP_SIGNATURES | VSIR_ASM_FLAG_DUMP_DESCRIPTORS)) ++ vkd3d_string_buffer_printf(buffer, "%s.text%s\n", compiler.colours.opcode, compiler.colours.reset); ++ + indent = 0; + for (i = 0; i < program->instructions.count; ++i) + { +@@ -2388,6 +2462,77 @@ static void trace_signature(const struct shader_signature *signature, const char + vkd3d_string_buffer_cleanup(&buffer); + } + ++static void shader_print_io_declaration(struct vkd3d_string_buffer *buffer, enum vkd3d_shader_register_type type) ++{ ++ switch (type) ++ { ++#define X(x) case VKD3DSPR_ ## x: vkd3d_string_buffer_printf(buffer, #x); return; ++ X(TEMP) ++ X(INPUT) ++ X(CONST) ++ X(ADDR) ++ X(TEXTURE) ++ X(RASTOUT) ++ X(ATTROUT) ++ X(TEXCRDOUT) ++ X(OUTPUT) ++ X(CONSTINT) ++ X(COLOROUT) ++ X(DEPTHOUT) ++ X(COMBINED_SAMPLER) ++ X(CONSTBOOL) ++ X(LOOP) ++ X(TEMPFLOAT16) ++ X(MISCTYPE) ++ X(LABEL) ++ X(PREDICATE) ++ X(IMMCONST) ++ X(IMMCONST64) ++ X(CONSTBUFFER) ++ X(IMMCONSTBUFFER) ++ X(PRIMID) ++ X(NULL) ++ X(SAMPLER) ++ X(RESOURCE) ++ X(UAV) ++ X(OUTPOINTID) ++ X(FORKINSTID) ++ X(JOININSTID) ++ X(INCONTROLPOINT) ++ X(OUTCONTROLPOINT) ++ X(PATCHCONST) ++ X(TESSCOORD) ++ X(GROUPSHAREDMEM) ++ X(THREADID) ++ X(THREADGROUPID) ++ X(LOCALTHREADID) ++ X(LOCALTHREADINDEX) ++ X(IDXTEMP) ++ X(STREAM) ++ X(FUNCTIONBODY) ++ X(FUNCTIONPOINTER) ++ X(COVERAGE) ++ X(SAMPLEMASK) ++ X(GSINSTID) ++ X(DEPTHOUTGE) ++ X(DEPTHOUTLE) ++ X(RASTERIZER) ++ X(OUTSTENCILREF) ++ X(UNDEF) ++ X(SSA) ++ X(WAVELANECOUNT) ++ X(WAVELANEINDEX) ++ X(PARAMETER) ++ X(POINT_COORD) ++#undef X ++ case VKD3DSPR_INVALID: ++ case VKD3DSPR_COUNT: ++ break; ++ } ++ ++ vkd3d_string_buffer_printf(buffer, "", type); ++} ++ + static void trace_io_declarations(const struct vsir_program *program) + { + struct vkd3d_string_buffer buffer; +@@ -2400,11 +2545,12 @@ static void trace_io_declarations(const struct vsir_program *program) + + for (i = 0; i < sizeof(program->io_dcls) * CHAR_BIT; ++i) + { +- if (bitmap_is_set(program->io_dcls, i)) +- { +- empty = false; +- vkd3d_string_buffer_printf(&buffer, " %u", i); +- } ++ if (!bitmap_is_set(program->io_dcls, i)) ++ continue; ++ ++ vkd3d_string_buffer_printf(&buffer, empty ? " " : " | "); ++ shader_print_io_declaration(&buffer, i); ++ empty = false; + } + + if (empty) +@@ -2417,7 +2563,8 @@ static void trace_io_declarations(const struct vsir_program *program) + + void vsir_program_trace(const struct vsir_program *program) + { +- const unsigned int flags = VSIR_ASM_FLAG_DUMP_TYPES | VSIR_ASM_FLAG_DUMP_ALL_INDICES; ++ const unsigned int flags = VSIR_ASM_FLAG_DUMP_TYPES | VSIR_ASM_FLAG_DUMP_ALL_INDICES ++ | VSIR_ASM_FLAG_DUMP_SIGNATURES | VSIR_ASM_FLAG_DUMP_DESCRIPTORS; + struct vkd3d_shader_code code; + const char *p, *q, *end; + +diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c +index b49ef9865db..77498f26c7f 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c ++++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c +@@ -1491,7 +1491,8 @@ int d3dbc_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t c + } + + bool sm1_register_from_semantic_name(const struct vkd3d_shader_version *version, const char *semantic_name, +- unsigned int semantic_index, bool output, enum vkd3d_shader_register_type *type, unsigned int *reg) ++ unsigned int semantic_index, bool output, enum vkd3d_shader_sysval_semantic *sysval, ++ enum vkd3d_shader_register_type *type, unsigned int *reg) + { + unsigned int i; + +@@ -1501,42 +1502,43 @@ bool sm1_register_from_semantic_name(const struct vkd3d_shader_version *version, + bool output; + enum vkd3d_shader_type shader_type; + unsigned int major_version; ++ enum vkd3d_shader_sysval_semantic sysval; + enum vkd3d_shader_register_type type; + unsigned int offset; + } + register_table[] = + { +- {"color", false, VKD3D_SHADER_TYPE_PIXEL, 1, VKD3DSPR_INPUT}, +- {"texcoord", false, VKD3D_SHADER_TYPE_PIXEL, 1, VKD3DSPR_TEXTURE}, +- +- {"color", true, VKD3D_SHADER_TYPE_PIXEL, 2, VKD3DSPR_COLOROUT}, +- {"depth", true, VKD3D_SHADER_TYPE_PIXEL, 2, VKD3DSPR_DEPTHOUT}, +- {"sv_depth", true, VKD3D_SHADER_TYPE_PIXEL, 2, VKD3DSPR_DEPTHOUT}, +- {"sv_target", true, VKD3D_SHADER_TYPE_PIXEL, 2, VKD3DSPR_COLOROUT}, +- {"color", false, VKD3D_SHADER_TYPE_PIXEL, 2, VKD3DSPR_INPUT}, +- {"texcoord", false, VKD3D_SHADER_TYPE_PIXEL, 2, VKD3DSPR_TEXTURE}, +- +- {"color", true, VKD3D_SHADER_TYPE_PIXEL, 3, VKD3DSPR_COLOROUT}, +- {"depth", true, VKD3D_SHADER_TYPE_PIXEL, 3, VKD3DSPR_DEPTHOUT}, +- {"sv_depth", true, VKD3D_SHADER_TYPE_PIXEL, 3, VKD3DSPR_DEPTHOUT}, +- {"sv_target", true, VKD3D_SHADER_TYPE_PIXEL, 3, VKD3DSPR_COLOROUT}, +- {"sv_position", false, VKD3D_SHADER_TYPE_PIXEL, 3, VKD3DSPR_MISCTYPE, VKD3D_SM1_MISC_POSITION}, +- {"vface", false, VKD3D_SHADER_TYPE_PIXEL, 3, VKD3DSPR_MISCTYPE, VKD3D_SM1_MISC_FACE}, +- {"vpos", false, VKD3D_SHADER_TYPE_PIXEL, 3, VKD3DSPR_MISCTYPE, VKD3D_SM1_MISC_POSITION}, +- +- {"color", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3DSPR_ATTROUT}, +- {"fog", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3DSPR_RASTOUT, VSIR_RASTOUT_FOG}, +- {"position", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3DSPR_RASTOUT, VSIR_RASTOUT_POSITION}, +- {"psize", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3DSPR_RASTOUT, VSIR_RASTOUT_POINT_SIZE}, +- {"sv_position", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3DSPR_RASTOUT, VSIR_RASTOUT_POSITION}, +- {"texcoord", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3DSPR_TEXCRDOUT}, +- +- {"color", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3DSPR_ATTROUT}, +- {"fog", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3DSPR_RASTOUT, VSIR_RASTOUT_FOG}, +- {"position", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3DSPR_RASTOUT, VSIR_RASTOUT_POSITION}, +- {"psize", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3DSPR_RASTOUT, VSIR_RASTOUT_POINT_SIZE}, +- {"sv_position", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3DSPR_RASTOUT, VSIR_RASTOUT_POSITION}, +- {"texcoord", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3DSPR_TEXCRDOUT}, ++ {"color", false, VKD3D_SHADER_TYPE_PIXEL, 1, VKD3D_SHADER_SV_NONE, VKD3DSPR_INPUT}, ++ {"texcoord", false, VKD3D_SHADER_TYPE_PIXEL, 1, VKD3D_SHADER_SV_NONE, VKD3DSPR_TEXTURE}, ++ ++ {"color", true, VKD3D_SHADER_TYPE_PIXEL, 2, VKD3D_SHADER_SV_TARGET, VKD3DSPR_COLOROUT}, ++ {"depth", true, VKD3D_SHADER_TYPE_PIXEL, 2, VKD3D_SHADER_SV_DEPTH, VKD3DSPR_DEPTHOUT}, ++ {"sv_depth", true, VKD3D_SHADER_TYPE_PIXEL, 2, VKD3D_SHADER_SV_DEPTH, VKD3DSPR_DEPTHOUT}, ++ {"sv_target", true, VKD3D_SHADER_TYPE_PIXEL, 2, VKD3D_SHADER_SV_TARGET, VKD3DSPR_COLOROUT}, ++ {"color", false, VKD3D_SHADER_TYPE_PIXEL, 2, VKD3D_SHADER_SV_NONE, VKD3DSPR_INPUT}, ++ {"texcoord", false, VKD3D_SHADER_TYPE_PIXEL, 2, VKD3D_SHADER_SV_NONE, VKD3DSPR_TEXTURE}, ++ ++ {"color", true, VKD3D_SHADER_TYPE_PIXEL, 3, VKD3D_SHADER_SV_TARGET, VKD3DSPR_COLOROUT}, ++ {"depth", true, VKD3D_SHADER_TYPE_PIXEL, 3, VKD3D_SHADER_SV_DEPTH, VKD3DSPR_DEPTHOUT}, ++ {"sv_depth", true, VKD3D_SHADER_TYPE_PIXEL, 3, VKD3D_SHADER_SV_DEPTH, VKD3DSPR_DEPTHOUT}, ++ {"sv_target", true, VKD3D_SHADER_TYPE_PIXEL, 3, VKD3D_SHADER_SV_TARGET, VKD3DSPR_COLOROUT}, ++ {"sv_position", false, VKD3D_SHADER_TYPE_PIXEL, 3, VKD3D_SHADER_SV_POSITION, VKD3DSPR_MISCTYPE, VKD3D_SM1_MISC_POSITION}, ++ {"vface", false, VKD3D_SHADER_TYPE_PIXEL, 3, VKD3D_SHADER_SV_IS_FRONT_FACE, VKD3DSPR_MISCTYPE, VKD3D_SM1_MISC_FACE}, ++ {"vpos", false, VKD3D_SHADER_TYPE_PIXEL, 3, VKD3D_SHADER_SV_POSITION, VKD3DSPR_MISCTYPE, VKD3D_SM1_MISC_POSITION}, ++ ++ {"color", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3D_SHADER_SV_NONE, VKD3DSPR_ATTROUT}, ++ {"fog", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3D_SHADER_SV_NONE, VKD3DSPR_RASTOUT, VSIR_RASTOUT_FOG}, ++ {"position", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3D_SHADER_SV_POSITION, VKD3DSPR_RASTOUT, VSIR_RASTOUT_POSITION}, ++ {"psize", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3D_SHADER_SV_NONE, VKD3DSPR_RASTOUT, VSIR_RASTOUT_POINT_SIZE}, ++ {"sv_position", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3D_SHADER_SV_POSITION, VKD3DSPR_RASTOUT, VSIR_RASTOUT_POSITION}, ++ {"texcoord", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3D_SHADER_SV_NONE, VKD3DSPR_TEXCRDOUT}, ++ ++ {"color", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3D_SHADER_SV_NONE, VKD3DSPR_ATTROUT}, ++ {"fog", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3D_SHADER_SV_NONE, VKD3DSPR_RASTOUT, VSIR_RASTOUT_FOG}, ++ {"position", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3D_SHADER_SV_POSITION, VKD3DSPR_RASTOUT, VSIR_RASTOUT_POSITION}, ++ {"psize", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3D_SHADER_SV_NONE, VKD3DSPR_RASTOUT, VSIR_RASTOUT_POINT_SIZE}, ++ {"sv_position", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3D_SHADER_SV_POSITION, VKD3DSPR_RASTOUT, VSIR_RASTOUT_POSITION}, ++ {"texcoord", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3D_SHADER_SV_NONE, VKD3DSPR_TEXCRDOUT}, + }; + + for (i = 0; i < ARRAY_SIZE(register_table); ++i) +@@ -1546,6 +1548,8 @@ bool sm1_register_from_semantic_name(const struct vkd3d_shader_version *version, + && version->type == register_table[i].shader_type + && version->major == register_table[i].major_version) + { ++ if (sysval) ++ *sysval = register_table[i].sysval; + *type = register_table[i].type; + if (register_table[i].type == VKD3DSPR_MISCTYPE || register_table[i].type == VKD3DSPR_RASTOUT) + *reg = register_table[i].offset; +@@ -1997,7 +2001,7 @@ static void d3dbc_write_semantic_dcl(struct d3dbc_compiler *d3dbc, + + reg.reg.idx_count = 1; + if (sm1_register_from_semantic_name(version, element->semantic_name, +- element->semantic_index, output, ®.reg.type, ®.reg.idx[0].offset)) ++ element->semantic_index, output, NULL, ®.reg.type, ®.reg.idx[0].offset)) + { + usage = 0; + usage_idx = 0; +diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c +index ac4828d6f59..a3813c39bf0 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/dxil.c ++++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c +@@ -4382,7 +4382,7 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco + dst_param_init(&dst_params[0]); + dst_param_init(&dst_params[1]); + register_init_ssa_scalar(&dst_params[index].reg, a->type, dst, sm6); +- vsir_register_init(&dst_params[index ^ 1].reg, VKD3DSPR_NULL, VKD3D_DATA_UNUSED, 0); ++ vsir_dst_param_init_null(&dst_params[index ^ 1]); + dst->u.reg = dst_params[index].reg; + } + else +@@ -5942,7 +5942,7 @@ static void sm6_parser_emit_dx_sincos(struct sm6_parser *sm6, enum dx_intrinsic_ + dst_param_init(&dst_params[0]); + dst_param_init(&dst_params[1]); + register_init_ssa_scalar(&dst_params[index].reg, dst->type, dst, sm6); +- vsir_register_init(&dst_params[index ^ 1].reg, VKD3DSPR_NULL, VKD3D_DATA_UNUSED, 0); ++ vsir_dst_param_init_null(&dst_params[index ^ 1]); + dst->u.reg = dst_params[index].reg; + } + +diff --git a/libs/vkd3d/libs/vkd3d-shader/glsl.c b/libs/vkd3d/libs/vkd3d-shader/glsl.c +index a87ade5e467..e4497b9ac5b 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/glsl.c ++++ b/libs/vkd3d/libs/vkd3d-shader/glsl.c +@@ -787,7 +787,6 @@ static void shader_glsl_ld(struct vkd3d_glsl_generator *gen, const struct vkd3d_ + unsigned int resource_id, resource_idx, resource_space, sample_count; + const struct glsl_resource_type_info *resource_type_info; + const struct vkd3d_shader_descriptor_info1 *d; +- enum vkd3d_shader_component_type sampled_type; + enum vkd3d_shader_resource_type resource_type; + struct vkd3d_string_buffer *fetch; + enum vkd3d_data_type data_type; +@@ -810,8 +809,7 @@ static void shader_glsl_ld(struct vkd3d_glsl_generator *gen, const struct vkd3d_ + resource_type = d->resource_type; + resource_space = d->register_space; + sample_count = d->sample_count; +- sampled_type = vkd3d_component_type_from_resource_data_type(d->resource_data_type); +- data_type = vkd3d_data_type_from_component_type(sampled_type); ++ data_type = d->resource_data_type; + } + else + { +@@ -903,7 +901,6 @@ static void shader_glsl_sample(struct vkd3d_glsl_generator *gen, const struct vk + unsigned int resource_id, resource_idx, resource_space; + unsigned int sampler_id, sampler_idx, sampler_space; + const struct vkd3d_shader_descriptor_info1 *d; +- enum vkd3d_shader_component_type sampled_type; + enum vkd3d_shader_resource_type resource_type; + unsigned int component_idx, coord_size; + struct vkd3d_string_buffer *sample; +@@ -933,8 +930,7 @@ static void shader_glsl_sample(struct vkd3d_glsl_generator *gen, const struct vk + { + resource_type = d->resource_type; + resource_space = d->register_space; +- sampled_type = vkd3d_component_type_from_resource_data_type(d->resource_data_type); +- data_type = vkd3d_data_type_from_component_type(sampled_type); ++ data_type = d->resource_data_type; + } + else + { +@@ -1053,11 +1049,11 @@ static void shader_glsl_sample(struct vkd3d_glsl_generator *gen, const struct vk + static void shader_glsl_load_uav_typed(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins) + { + const struct glsl_resource_type_info *resource_type_info; +- enum vkd3d_shader_component_type component_type; + const struct vkd3d_shader_descriptor_info1 *d; + enum vkd3d_shader_resource_type resource_type; + unsigned int uav_id, uav_idx, uav_space; + struct vkd3d_string_buffer *load; ++ enum vkd3d_data_type data_type; + struct glsl_src coord; + struct glsl_dst dst; + uint32_t coord_mask; +@@ -1072,7 +1068,7 @@ static void shader_glsl_load_uav_typed(struct vkd3d_glsl_generator *gen, const s + { + resource_type = d->resource_type; + uav_space = d->register_space; +- component_type = vkd3d_component_type_from_resource_data_type(d->resource_data_type); ++ data_type = d->resource_data_type; + } + else + { +@@ -1080,7 +1076,7 @@ static void shader_glsl_load_uav_typed(struct vkd3d_glsl_generator *gen, const s + "Internal compiler error: Undeclared UAV descriptor %u.", uav_id); + uav_space = 0; + resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D; +- component_type = VKD3D_SHADER_COMPONENT_FLOAT; ++ data_type = VKD3D_DATA_FLOAT; + } + + if ((resource_type_info = shader_glsl_get_resource_type_info(resource_type))) +@@ -1103,8 +1099,7 @@ static void shader_glsl_load_uav_typed(struct vkd3d_glsl_generator *gen, const s + vkd3d_string_buffer_printf(load, ", %s)", coord.str->buffer); + shader_glsl_print_swizzle(load, ins->src[1].swizzle, ins->dst[0].write_mask); + +- shader_glsl_print_assignment_ext(gen, &dst, +- vkd3d_data_type_from_component_type(component_type), "%s", load->buffer); ++ shader_glsl_print_assignment_ext(gen, &dst, data_type, "%s", load->buffer); + + vkd3d_string_buffer_release(&gen->string_buffers, load); + glsl_src_cleanup(&coord, &gen->string_buffers); +@@ -1114,11 +1109,11 @@ static void shader_glsl_load_uav_typed(struct vkd3d_glsl_generator *gen, const s + static void shader_glsl_store_uav_typed(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins) + { + const struct glsl_resource_type_info *resource_type_info; +- enum vkd3d_shader_component_type component_type; + const struct vkd3d_shader_descriptor_info1 *d; + enum vkd3d_shader_resource_type resource_type; + unsigned int uav_id, uav_idx, uav_space; + struct vkd3d_string_buffer *image_data; ++ enum vkd3d_data_type data_type; + struct glsl_src image_coord; + uint32_t coord_mask; + +@@ -1132,7 +1127,7 @@ static void shader_glsl_store_uav_typed(struct vkd3d_glsl_generator *gen, const + { + resource_type = d->resource_type; + uav_space = d->register_space; +- component_type = vkd3d_component_type_from_resource_data_type(d->resource_data_type); ++ data_type = d->resource_data_type; + } + else + { +@@ -1140,7 +1135,7 @@ static void shader_glsl_store_uav_typed(struct vkd3d_glsl_generator *gen, const + "Internal compiler error: Undeclared UAV descriptor %u.", uav_id); + uav_space = 0; + resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D; +- component_type = VKD3D_SHADER_COMPONENT_FLOAT; ++ data_type = VKD3D_DATA_FLOAT; + } + + if ((resource_type_info = shader_glsl_get_resource_type_info(resource_type))) +@@ -1159,25 +1154,26 @@ static void shader_glsl_store_uav_typed(struct vkd3d_glsl_generator *gen, const + + if (ins->src[1].reg.dimension == VSIR_DIMENSION_SCALAR) + { +- switch (component_type) ++ switch (data_type) + { +- case VKD3D_SHADER_COMPONENT_UINT: ++ case VKD3D_DATA_UINT: + vkd3d_string_buffer_printf(image_data, "uvec4("); + break; +- case VKD3D_SHADER_COMPONENT_INT: ++ case VKD3D_DATA_INT: + vkd3d_string_buffer_printf(image_data, "ivec4("); + break; + default: + vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, +- "Internal compiler error: Unhandled component type %#x.", component_type); ++ "Internal compiler error: Unhandled data type %#x.", data_type); + /* fall through */ +- case VKD3D_SHADER_COMPONENT_FLOAT: ++ case VKD3D_DATA_FLOAT: ++ case VKD3D_DATA_UNORM: ++ case VKD3D_DATA_SNORM: + vkd3d_string_buffer_printf(image_data, "vec4("); + break; + } + } +- shader_glsl_print_src(image_data, gen, &ins->src[1], VKD3DSP_WRITEMASK_ALL, +- vkd3d_data_type_from_component_type(component_type)); ++ shader_glsl_print_src(image_data, gen, &ins->src[1], VKD3DSP_WRITEMASK_ALL, data_type); + if (ins->src[1].reg.dimension == VSIR_DIMENSION_SCALAR) + vkd3d_string_buffer_printf(image_data, ", 0, 0, 0)"); + +@@ -1735,7 +1731,6 @@ static void shader_glsl_generate_uav_declaration(struct vkd3d_glsl_generator *ge + const struct vkd3d_shader_descriptor_binding *binding; + const struct vkd3d_shader_descriptor_offset *offset; + struct vkd3d_string_buffer *buffer = gen->buffer; +- enum vkd3d_shader_component_type component_type; + unsigned int binding_idx; + + if (uav->count != 1) +@@ -1792,22 +1787,24 @@ static void shader_glsl_generate_uav_declaration(struct vkd3d_glsl_generator *ge + image_type = ""; + } + +- switch ((component_type = vkd3d_component_type_from_resource_data_type(uav->resource_data_type))) ++ switch (uav->resource_data_type) + { +- case VKD3D_SHADER_COMPONENT_UINT: ++ case VKD3D_DATA_UINT: + image_type_prefix = "u"; + read_format = "r32ui"; + break; +- case VKD3D_SHADER_COMPONENT_INT: ++ case VKD3D_DATA_INT: + image_type_prefix = "i"; + read_format = "r32i"; + break; + default: + vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, +- "Internal compiler error: Unhandled component type %#x for UAV %u.", +- component_type, uav->register_id); ++ "Internal compiler error: Unhandled data type %#x for UAV %u.", ++ uav->resource_data_type, uav->register_id); + /* fall through */ +- case VKD3D_SHADER_COMPONENT_FLOAT: ++ case VKD3D_DATA_FLOAT: ++ case VKD3D_DATA_UNORM: ++ case VKD3D_DATA_SNORM: + image_type_prefix = ""; + read_format = "r32f"; + break; +@@ -1962,7 +1959,6 @@ static void shader_glsl_generate_sampler_declaration(struct vkd3d_glsl_generator + const struct glsl_resource_type_info *resource_type_info; + const struct vkd3d_shader_descriptor_binding *binding; + struct vkd3d_string_buffer *buffer = gen->buffer; +- enum vkd3d_shader_component_type component_type; + const char *sampler_type, *sampler_type_prefix; + enum vkd3d_shader_resource_type resource_type; + unsigned int binding_idx; +@@ -2020,21 +2016,23 @@ static void shader_glsl_generate_sampler_declaration(struct vkd3d_glsl_generator + sampler_type = ""; + } + +- switch ((component_type = vkd3d_component_type_from_resource_data_type(srv->resource_data_type))) ++ switch (srv->resource_data_type) + { +- case VKD3D_SHADER_COMPONENT_UINT: ++ case VKD3D_DATA_UINT: + sampler_type_prefix = "u"; + break; +- case VKD3D_SHADER_COMPONENT_INT: ++ case VKD3D_DATA_INT: + sampler_type_prefix = "i"; + break; +- case VKD3D_SHADER_COMPONENT_FLOAT: ++ case VKD3D_DATA_FLOAT: ++ case VKD3D_DATA_UNORM: ++ case VKD3D_DATA_SNORM: + sampler_type_prefix = ""; + break; + default: + vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, +- "Internal compiler error: Unhandled component type %#x for combined resource/sampler " +- "for resource %u, space %u and sampler %u, space %u.", component_type, ++ "Internal compiler error: Unhandled data type %#x for combined resource/sampler " ++ "for resource %u, space %u and sampler %u, space %u.", srv->resource_data_type, + crs->resource_index, crs->resource_space, crs->sampler_index, crs->sampler_space); + sampler_type_prefix = ""; + break; +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y +index ff3d58da8f4..6086d018fdc 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y +@@ -6322,6 +6322,66 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, stru + } + } + ++static bool add_object_property_access(struct hlsl_ctx *ctx, ++ struct hlsl_block *block, struct hlsl_ir_node *object, const char *name, ++ const struct vkd3d_shader_location *loc) ++{ ++ const struct hlsl_type *object_type = object->data_type; ++ struct hlsl_resource_load_params load_params; ++ struct hlsl_ir_node *zero; ++ unsigned int sampler_dim; ++ ++ if (!strcmp(name, "Length")) ++ { ++ if (object_type->class != HLSL_CLASS_TEXTURE && object_type->class != HLSL_CLASS_UAV) ++ return false; ++ ++ sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim); ++ ++ switch (object_type->sampler_dim) ++ { ++ case HLSL_SAMPLER_DIM_1D: ++ case HLSL_SAMPLER_DIM_2D: ++ case HLSL_SAMPLER_DIM_3D: ++ case HLSL_SAMPLER_DIM_1DARRAY: ++ case HLSL_SAMPLER_DIM_2DARRAY: ++ case HLSL_SAMPLER_DIM_2DMS: ++ case HLSL_SAMPLER_DIM_2DMSARRAY: ++ break; ++ ++ case HLSL_SAMPLER_DIM_BUFFER: ++ case HLSL_SAMPLER_DIM_STRUCTURED_BUFFER: ++ hlsl_fixme(ctx, loc, "'Length' property for buffers."); ++ block->value = ctx->error_instr; ++ return true; ++ ++ default: ++ return false; ++ } ++ ++ if (hlsl_version_lt(ctx, 4, 0)) ++ { ++ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE, ++ "'Length' property can only be used on profiles 4.0 or higher."); ++ block->value = ctx->error_instr; ++ return true; ++ } ++ ++ zero = hlsl_block_add_uint_constant(ctx, block, 0, loc); ++ ++ memset(&load_params, 0, sizeof(load_params)); ++ load_params.type = HLSL_RESOURCE_RESINFO; ++ load_params.resource = object; ++ load_params.lod = zero; ++ load_params.format = hlsl_get_vector_type(ctx, HLSL_TYPE_UINT, sampler_dim); ++ hlsl_block_add_resource_load(ctx, block, &load_params, loc); ++ ++ return true; ++ } ++ ++ return false; ++} ++ + static void validate_texture_format_type(struct hlsl_ctx *ctx, struct hlsl_type *format, + const struct vkd3d_shader_location *loc) + { +@@ -9122,6 +9182,9 @@ postfix_expr: + $1->value = ctx->error_instr; + } + } ++ else if (add_object_property_access(ctx, $1, node, $3, &@2)) ++ { ++ } + else if (node->data_type->class != HLSL_CLASS_ERROR) + { + hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "Invalid subscript \"%s\".", $3); +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +index dc7607a1393..1c684e7b9c1 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +@@ -6368,7 +6368,7 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var + return; + + builtin = sm1_register_from_semantic_name(&version, +- var->semantic.name, var->semantic.index, output, &type, ®); ++ var->semantic.name, var->semantic.index, output, NULL, &type, ®); + if (!builtin && !sm1_usage_from_semantic_name(var->semantic.name, var->semantic.index, &usage, &usage_idx)) + { + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SEMANTIC, +@@ -7763,7 +7763,7 @@ static void generate_vsir_signature_entry(struct hlsl_ctx *ctx, struct vsir_prog + return; + + if (!sm1_register_from_semantic_name(&program->shader_version, +- var->semantic.name, var->semantic.index, output, &type, ®ister_index)) ++ var->semantic.name, var->semantic.index, output, &sysval, &type, ®ister_index)) + { + enum vkd3d_decl_usage usage; + unsigned int usage_idx; +@@ -7780,6 +7780,8 @@ static void generate_vsir_signature_entry(struct hlsl_ctx *ctx, struct vsir_prog + if (program->shader_version.type == VKD3D_SHADER_TYPE_VERTEX + && output && usage == VKD3D_DECL_USAGE_POSITION) + sysval = VKD3D_SHADER_SV_POSITION; ++ else ++ sysval = VKD3D_SHADER_SV_NONE; + } + + mask = (1 << var->data_type->e.numeric.dimx) - 1; +@@ -7826,7 +7828,12 @@ static void generate_vsir_signature_entry(struct hlsl_ctx *ctx, struct vsir_prog + element->mask = mask; + element->used_mask = use_mask; + if (program->shader_version.type == VKD3D_SHADER_TYPE_PIXEL && !output) +- element->interpolation_mode = VKD3DSIM_LINEAR; ++ { ++ if (program->shader_version.major >= 4) ++ element->interpolation_mode = sm4_get_interpolation_mode(var->data_type, var->storage_modifiers); ++ else ++ element->interpolation_mode = VKD3DSIM_LINEAR; ++ } + + switch (var->data_type->e.numeric.type) + { +@@ -8880,7 +8887,7 @@ static void sm1_generate_vsir_init_dst_param_from_deref(struct hlsl_ctx *ctx, + register_index = 0; + } + else if (!sm1_register_from_semantic_name(&version, semantic_name, +- deref->var->semantic.index, true, &type, ®ister_index)) ++ deref->var->semantic.index, true, NULL, &type, ®ister_index)) + { + VKD3D_ASSERT(reg.allocated); + type = VKD3DSPR_OUTPUT; +@@ -9006,7 +9013,7 @@ static void sm1_generate_vsir_init_src_param_from_deref(struct hlsl_ctx *ctx, + version.minor = ctx->profile->minor_version; + version.type = ctx->profile->type; + if (sm1_register_from_semantic_name(&version, deref->var->semantic.name, +- deref->var->semantic.index, false, &type, ®ister_index)) ++ deref->var->semantic.index, false, NULL, &type, ®ister_index)) + { + writemask = (1 << deref->var->data_type->e.numeric.dimx) - 1; + } +@@ -10012,8 +10019,8 @@ static bool sm4_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx, + static void sm4_generate_vsir_expr_with_two_destinations(struct hlsl_ctx *ctx, struct vsir_program *program, + enum vkd3d_shader_opcode opcode, const struct hlsl_ir_expr *expr, unsigned int dst_idx) + { +- struct vkd3d_shader_dst_param *dst_param, *null_param; + const struct hlsl_ir_node *instr = &expr->node; ++ struct vkd3d_shader_dst_param *dst_param; + struct vkd3d_shader_instruction *ins; + unsigned int i, src_count; + +@@ -10031,9 +10038,7 @@ static void sm4_generate_vsir_expr_with_two_destinations(struct hlsl_ctx *ctx, s + dst_param = &ins->dst[dst_idx]; + vsir_dst_from_hlsl_node(dst_param, ctx, instr); + +- null_param = &ins->dst[1 - dst_idx]; +- vsir_dst_param_init(null_param, VKD3DSPR_NULL, VKD3D_DATA_FLOAT, 0); +- null_param->reg.dimension = VSIR_DIMENSION_NONE; ++ vsir_dst_param_init_null(&ins->dst[1 - dst_idx]); + + for (i = 0; i < src_count; ++i) + vsir_src_from_hlsl_node(&ins->src[i], ctx, expr->operands[i].node, dst_param->write_mask); +diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c +index 72cf53761e4..d25485ab004 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/ir.c ++++ b/libs/vkd3d/libs/vkd3d-shader/ir.c +@@ -312,6 +312,13 @@ static void vsir_dst_param_init_io(struct vkd3d_shader_dst_param *dst, enum vkd3 + dst->write_mask = e->mask; + } + ++void vsir_dst_param_init_null(struct vkd3d_shader_dst_param *dst) ++{ ++ vsir_dst_param_init(dst, VKD3DSPR_NULL, VKD3D_DATA_UNUSED, 0); ++ dst->reg.dimension = VSIR_DIMENSION_NONE; ++ dst->write_mask = 0; ++} ++ + static void dst_param_init_ssa_bool(struct vkd3d_shader_dst_param *dst, unsigned int idx) + { + vsir_dst_param_init(dst, VKD3DSPR_SSA, VKD3D_DATA_BOOL, 1); +@@ -763,7 +770,7 @@ static enum vkd3d_result vsir_program_lower_sm1_sincos(struct vsir_program *prog + } + else + { +- vsir_dst_param_init(&ins->dst[0], VKD3DSPR_NULL, VKD3D_DATA_UNUSED, 0); ++ vsir_dst_param_init_null(&ins->dst[0]); + } + + if (sincos->dst->write_mask & VKD3DSP_WRITEMASK_0) +@@ -773,7 +780,7 @@ static enum vkd3d_result vsir_program_lower_sm1_sincos(struct vsir_program *prog + } + else + { +- vsir_dst_param_init(&ins->dst[1], VKD3DSPR_NULL, VKD3D_DATA_UNUSED, 0); ++ vsir_dst_param_init_null(&ins->dst[1]); + } + + /* Make the original instruction no-op */ +@@ -1299,7 +1306,7 @@ static void remove_unread_output_components(const struct shader_signature *signa + if (ins->dst_count == 1) + vkd3d_shader_instruction_make_nop(ins); + else +- vsir_dst_param_init(dst, VKD3DSPR_NULL, VKD3D_DATA_UNUSED, 0); ++ vsir_dst_param_init_null(dst); + } + } + +@@ -8248,6 +8255,14 @@ static void vsir_validate_dst_param(struct validation_context *ctx, + switch (dst->reg.type) + { + case VKD3DSPR_SSA: ++ if (dst->reg.dimension == VSIR_DIMENSION_VEC4 ++ && dst->write_mask != VKD3DSP_WRITEMASK_0 ++ && dst->write_mask != (VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1) ++ && dst->write_mask != (VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1 | VKD3DSP_WRITEMASK_2) ++ && dst->write_mask != VKD3DSP_WRITEMASK_ALL) ++ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_WRITE_MASK, ++ "SSA register has invalid write mask %#x.", dst->write_mask); ++ + if (dst->reg.idx[0].offset < ctx->program->ssa_count) + { + struct validation_context_ssa_data *data = &ctx->ssas[dst->reg.idx[0].offset]; +diff --git a/libs/vkd3d/libs/vkd3d-shader/msl.c b/libs/vkd3d/libs/vkd3d-shader/msl.c +index d477bfa1c1b..def6f459f69 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/msl.c ++++ b/libs/vkd3d/libs/vkd3d-shader/msl.c +@@ -46,6 +46,14 @@ struct msl_generator + const struct vkd3d_shader_interface_info *interface_info; + }; + ++struct msl_resource_type_info ++{ ++ size_t read_coord_size; ++ bool array; ++ bool lod; ++ const char *type_suffix; ++}; ++ + static void VKD3D_PRINTF_FUNC(3, 4) msl_compiler_error(struct msl_generator *gen, + enum vkd3d_shader_error error, const char *fmt, ...) + { +@@ -57,6 +65,30 @@ static void VKD3D_PRINTF_FUNC(3, 4) msl_compiler_error(struct msl_generator *gen + gen->failed = true; + } + ++static const struct msl_resource_type_info *msl_get_resource_type_info(enum vkd3d_shader_resource_type t) ++{ ++ static const struct msl_resource_type_info info[] = ++ { ++ [VKD3D_SHADER_RESOURCE_NONE] = {0, false, false, "none"}, ++ [VKD3D_SHADER_RESOURCE_BUFFER] = {1, false, false, "_buffer"}, ++ [VKD3D_SHADER_RESOURCE_TEXTURE_1D] = {1, false, false, "1d"}, ++ [VKD3D_SHADER_RESOURCE_TEXTURE_2D] = {2, false, true, "2d"}, ++ [VKD3D_SHADER_RESOURCE_TEXTURE_2DMS] = {2, false, false, "2d_ms"}, ++ [VKD3D_SHADER_RESOURCE_TEXTURE_3D] = {3, false, true, "3d"}, ++ [VKD3D_SHADER_RESOURCE_TEXTURE_CUBE] = {2, false, true, "cube"}, ++ [VKD3D_SHADER_RESOURCE_TEXTURE_1DARRAY] = {1, true, false, "1d_array"}, ++ [VKD3D_SHADER_RESOURCE_TEXTURE_2DARRAY] = {2, true, true, "2d_array"}, ++ [VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY] = {2, true, false, "2d_ms_array"}, ++ [VKD3D_SHADER_RESOURCE_TEXTURE_CUBEARRAY] = {2, true, true, "cube_array"}, ++ }; ++ ++ if (!t || t >= ARRAY_SIZE(info)) ++ return NULL; ++ ++ return &info[t]; ++} ++ ++ + static const char *msl_get_prefix(enum vkd3d_shader_type type) + { + switch (type) +@@ -83,6 +115,30 @@ static void msl_print_indent(struct vkd3d_string_buffer *buffer, unsigned int in + vkd3d_string_buffer_printf(buffer, "%*s", 4 * indent, ""); + } + ++static void msl_print_resource_datatype(struct msl_generator *gen, ++ struct vkd3d_string_buffer *buffer, enum vkd3d_data_type data_type) ++{ ++ switch (data_type) ++ { ++ case VKD3D_DATA_FLOAT: ++ case VKD3D_DATA_UNORM: ++ case VKD3D_DATA_SNORM: ++ vkd3d_string_buffer_printf(buffer, "float"); ++ break; ++ case VKD3D_DATA_INT: ++ vkd3d_string_buffer_printf(buffer, "int"); ++ break; ++ case VKD3D_DATA_UINT: ++ vkd3d_string_buffer_printf(buffer, "uint"); ++ break; ++ default: ++ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, ++ "Internal compiler error: Unhandled resource datatype %#x.", data_type); ++ vkd3d_string_buffer_printf(buffer, "", data_type); ++ break; ++ } ++} ++ + static void msl_print_register_datatype(struct vkd3d_string_buffer *buffer, + struct msl_generator *gen, enum vkd3d_data_type data_type) + { +@@ -106,6 +162,111 @@ static void msl_print_register_datatype(struct vkd3d_string_buffer *buffer, + } + } + ++static bool msl_check_shader_visibility(const struct msl_generator *gen, ++ enum vkd3d_shader_visibility visibility) ++{ ++ enum vkd3d_shader_type t = gen->program->shader_version.type; ++ ++ switch (visibility) ++ { ++ case VKD3D_SHADER_VISIBILITY_ALL: ++ return true; ++ case VKD3D_SHADER_VISIBILITY_VERTEX: ++ return t == VKD3D_SHADER_TYPE_VERTEX; ++ case VKD3D_SHADER_VISIBILITY_HULL: ++ return t == VKD3D_SHADER_TYPE_HULL; ++ case VKD3D_SHADER_VISIBILITY_DOMAIN: ++ return t == VKD3D_SHADER_TYPE_DOMAIN; ++ case VKD3D_SHADER_VISIBILITY_GEOMETRY: ++ return t == VKD3D_SHADER_TYPE_GEOMETRY; ++ case VKD3D_SHADER_VISIBILITY_PIXEL: ++ return t == VKD3D_SHADER_TYPE_PIXEL; ++ case VKD3D_SHADER_VISIBILITY_COMPUTE: ++ return t == VKD3D_SHADER_TYPE_COMPUTE; ++ default: ++ WARN("Invalid shader visibility %#x.\n", visibility); ++ return false; ++ } ++} ++ ++static const struct vkd3d_shader_descriptor_binding *msl_get_cbv_binding(const struct msl_generator *gen, ++ unsigned int register_space, unsigned int register_idx) ++{ ++ const struct vkd3d_shader_interface_info *interface_info = gen->interface_info; ++ unsigned int i; ++ ++ if (!interface_info) ++ return NULL; ++ ++ for (i = 0; i < interface_info->binding_count; ++i) ++ { ++ const struct vkd3d_shader_resource_binding *binding = &interface_info->bindings[i]; ++ ++ if (binding->type != VKD3D_SHADER_DESCRIPTOR_TYPE_CBV) ++ continue; ++ if (binding->register_space != register_space) ++ continue; ++ if (binding->register_index != register_idx) ++ continue; ++ if (!msl_check_shader_visibility(gen, binding->shader_visibility)) ++ continue; ++ if (!(binding->flags & VKD3D_SHADER_BINDING_FLAG_BUFFER)) ++ continue; ++ ++ return &binding->binding; ++ } ++ ++ return NULL; ++} ++ ++static const struct vkd3d_shader_descriptor_binding *msl_get_srv_binding(const struct msl_generator *gen, ++ unsigned int register_space, unsigned int register_idx, enum vkd3d_shader_resource_type resource_type) ++{ ++ const struct vkd3d_shader_interface_info *interface_info = gen->interface_info; ++ enum vkd3d_shader_binding_flag resource_type_flag; ++ unsigned int i; ++ ++ if (!interface_info) ++ return NULL; ++ ++ resource_type_flag = resource_type == VKD3D_SHADER_RESOURCE_BUFFER ++ ? VKD3D_SHADER_BINDING_FLAG_BUFFER : VKD3D_SHADER_BINDING_FLAG_IMAGE; ++ ++ for (i = 0; i < interface_info->binding_count; ++i) ++ { ++ const struct vkd3d_shader_resource_binding *binding = &interface_info->bindings[i]; ++ ++ if (binding->type != VKD3D_SHADER_DESCRIPTOR_TYPE_SRV) ++ continue; ++ if (binding->register_space != register_space) ++ continue; ++ if (binding->register_index != register_idx) ++ continue; ++ if (!msl_check_shader_visibility(gen, binding->shader_visibility)) ++ continue; ++ if (!(binding->flags & resource_type_flag)) ++ continue; ++ ++ return &binding->binding; ++ } ++ ++ return NULL; ++} ++ ++static void msl_print_cbv_name(struct vkd3d_string_buffer *buffer, unsigned int binding) ++{ ++ vkd3d_string_buffer_printf(buffer, "descriptors[%u].buf()", binding); ++} ++ ++static void msl_print_srv_name(struct vkd3d_string_buffer *buffer, struct msl_generator *gen, unsigned int binding, ++ const struct msl_resource_type_info *resource_type_info, enum vkd3d_data_type resource_data_type) ++{ ++ vkd3d_string_buffer_printf(buffer, "descriptors[%u].textype_suffix); ++ msl_print_resource_datatype(gen, buffer, resource_data_type); ++ vkd3d_string_buffer_printf(buffer, ">>()"); ++} ++ + static void msl_print_register_name(struct vkd3d_string_buffer *buffer, + struct msl_generator *gen, const struct vkd3d_shader_register *reg) + { +@@ -220,23 +381,36 @@ static void msl_print_register_name(struct vkd3d_string_buffer *buffer, + break; + + case VKD3DSPR_CONSTBUFFER: +- if (reg->idx_count != 3) +- { +- msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, +- "Internal compiler error: Unhandled constant buffer register index count %u.", reg->idx_count); +- vkd3d_string_buffer_printf(buffer, "", reg->type); +- break; +- } +- if (reg->idx[0].rel_addr || reg->idx[2].rel_addr) + { +- msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, +- "Internal compiler error: Unhandled constant buffer register indirect addressing."); +- vkd3d_string_buffer_printf(buffer, "", reg->type); ++ const struct vkd3d_shader_descriptor_binding *binding; ++ ++ if (reg->idx_count != 3) ++ { ++ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, ++ "Internal compiler error: Unhandled constant buffer register index count %u.", ++ reg->idx_count); ++ vkd3d_string_buffer_printf(buffer, "", reg->type); ++ break; ++ } ++ if (reg->idx[0].rel_addr || reg->idx[1].rel_addr || reg->idx[2].rel_addr) ++ { ++ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, ++ "Internal compiler error: Unhandled constant buffer register indirect addressing."); ++ vkd3d_string_buffer_printf(buffer, "", reg->type); ++ break; ++ } ++ if (!(binding = msl_get_cbv_binding(gen, 0, reg->idx[1].offset))) ++ { ++ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND, ++ "Cannot finding binding for CBV register %u.", reg->idx[0].offset); ++ vkd3d_string_buffer_printf(buffer, "", reg->type); ++ break; ++ } ++ msl_print_cbv_name(buffer, binding->binding); ++ vkd3d_string_buffer_printf(buffer, "[%u]", reg->idx[2].offset); ++ msl_print_register_datatype(buffer, gen, reg->data_type); + break; + } +- vkd3d_string_buffer_printf(buffer, "descriptors.cb_%u[%u]", reg->idx[0].offset, reg->idx[2].offset); +- msl_print_register_datatype(buffer, gen, reg->data_type); +- break; + + default: + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, +@@ -529,6 +703,96 @@ static void msl_else(struct msl_generator *gen) + msl_begin_block(gen); + } + ++static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) ++{ ++ const struct msl_resource_type_info *resource_type_info; ++ unsigned int resource_id, resource_idx, resource_space; ++ const struct vkd3d_shader_descriptor_info1 *descriptor; ++ const struct vkd3d_shader_descriptor_binding *binding; ++ enum vkd3d_shader_resource_type resource_type; ++ struct msl_src coord, array_index, lod; ++ struct vkd3d_string_buffer *read; ++ enum vkd3d_data_type data_type; ++ uint32_t coord_mask; ++ struct msl_dst dst; ++ ++ if (vkd3d_shader_instruction_has_texel_offset(ins)) ++ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, ++ "Internal compiler error: Unhandled texel fetch offset."); ++ ++ if (ins->src[1].reg.idx[0].rel_addr || ins->src[1].reg.idx[1].rel_addr) ++ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_UNSUPPORTED, ++ "Descriptor indexing is not supported."); ++ ++ resource_id = ins->src[1].reg.idx[0].offset; ++ resource_idx = ins->src[1].reg.idx[1].offset; ++ if ((descriptor = vkd3d_shader_find_descriptor(&gen->program->descriptors, ++ VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, resource_id))) ++ { ++ resource_type = descriptor->resource_type; ++ resource_space = descriptor->register_space; ++ data_type = descriptor->resource_data_type; ++ } ++ else ++ { ++ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, ++ "Internal compiler error: Undeclared resource descriptor %u.", resource_id); ++ resource_space = 0; ++ resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D; ++ data_type = VKD3D_DATA_FLOAT; ++ } ++ ++ if ((resource_type_info = msl_get_resource_type_info(resource_type))) ++ { ++ coord_mask = vkd3d_write_mask_from_component_count(resource_type_info->read_coord_size); ++ } ++ else ++ { ++ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, ++ "Internal compiler error: Unhandled resource type %#x.", resource_type); ++ coord_mask = vkd3d_write_mask_from_component_count(2); ++ } ++ ++ if (!(binding = msl_get_srv_binding(gen, resource_space, resource_idx, resource_type))) ++ { ++ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND, ++ "Cannot finding binding for SRV register %u index %u space %u.", ++ resource_id, resource_idx, resource_space); ++ return; ++ } ++ ++ msl_dst_init(&dst, gen, ins, &ins->dst[0]); ++ msl_src_init(&coord, gen, &ins->src[0], coord_mask); ++ /* `coord_mask + 1` gives exactly the array index component mask if it is an array resource */ ++ /* Or it's simply unused, saving some branches */ ++ msl_src_init(&array_index, gen, &ins->src[0], coord_mask + 1); ++ msl_src_init(&lod, gen, &ins->src[0], VKD3DSP_WRITEMASK_3); ++ read = vkd3d_string_buffer_get(&gen->string_buffers); ++ ++ vkd3d_string_buffer_printf(read, "as_type("); ++ msl_print_srv_name(read, gen, binding->binding, resource_type_info, data_type); ++ vkd3d_string_buffer_printf(read, ".read("); ++ if (resource_type_info->read_coord_size > 1) ++ vkd3d_string_buffer_printf(read, "as_type(%s)", ++ resource_type_info->read_coord_size, coord.str->buffer); ++ else ++ vkd3d_string_buffer_printf(read, "as_type(%s)", coord.str->buffer); ++ if (resource_type_info->array) ++ vkd3d_string_buffer_printf(read, ", as_type(%s)", array_index.str->buffer); ++ if (resource_type_info->lod) ++ vkd3d_string_buffer_printf(read, ", as_type(%s)", lod.str->buffer); ++ vkd3d_string_buffer_printf(read, "))"); ++ msl_print_swizzle(read, ins->src[1].swizzle, ins->dst[0].write_mask); ++ ++ msl_print_assignment(gen, &dst, "%s", read->buffer); ++ ++ vkd3d_string_buffer_release(&gen->string_buffers, read); ++ msl_src_cleanup(&lod, &gen->string_buffers); ++ msl_src_cleanup(&array_index, &gen->string_buffers); ++ msl_src_cleanup(&coord, &gen->string_buffers); ++ msl_dst_cleanup(&dst, &gen->string_buffers); ++} ++ + static void msl_unary_op(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins, const char *op) + { + struct msl_src src; +@@ -670,6 +934,9 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d + case VKD3DSIH_UTOF: + msl_cast(gen, ins, "float"); + break; ++ case VKD3DSIH_LD: ++ msl_ld(gen, ins); ++ break; + case VKD3DSIH_LOG: + msl_intrinsic(gen, ins, "log2"); + break; +@@ -715,144 +982,6 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d + } + } + +-static bool msl_check_shader_visibility(const struct msl_generator *gen, +- enum vkd3d_shader_visibility visibility) +-{ +- enum vkd3d_shader_type t = gen->program->shader_version.type; +- +- switch (visibility) +- { +- case VKD3D_SHADER_VISIBILITY_ALL: +- return true; +- case VKD3D_SHADER_VISIBILITY_VERTEX: +- return t == VKD3D_SHADER_TYPE_VERTEX; +- case VKD3D_SHADER_VISIBILITY_HULL: +- return t == VKD3D_SHADER_TYPE_HULL; +- case VKD3D_SHADER_VISIBILITY_DOMAIN: +- return t == VKD3D_SHADER_TYPE_DOMAIN; +- case VKD3D_SHADER_VISIBILITY_GEOMETRY: +- return t == VKD3D_SHADER_TYPE_GEOMETRY; +- case VKD3D_SHADER_VISIBILITY_PIXEL: +- return t == VKD3D_SHADER_TYPE_PIXEL; +- case VKD3D_SHADER_VISIBILITY_COMPUTE: +- return t == VKD3D_SHADER_TYPE_COMPUTE; +- default: +- WARN("Invalid shader visibility %#x.\n", visibility); +- return false; +- } +-} +- +-static bool msl_get_cbv_binding(const struct msl_generator *gen, +- unsigned int register_space, unsigned int register_idx, unsigned int *binding_idx) +-{ +- const struct vkd3d_shader_interface_info *interface_info = gen->interface_info; +- const struct vkd3d_shader_resource_binding *binding; +- unsigned int i; +- +- if (!interface_info) +- return false; +- +- for (i = 0; i < interface_info->binding_count; ++i) +- { +- binding = &interface_info->bindings[i]; +- +- if (binding->type != VKD3D_SHADER_DESCRIPTOR_TYPE_CBV) +- continue; +- if (binding->register_space != register_space) +- continue; +- if (binding->register_index != register_idx) +- continue; +- if (!msl_check_shader_visibility(gen, binding->shader_visibility)) +- continue; +- if (!(binding->flags & VKD3D_SHADER_BINDING_FLAG_BUFFER)) +- continue; +- *binding_idx = i; +- return true; +- } +- +- return false; +-} +- +-static void msl_generate_cbv_declaration(struct msl_generator *gen, +- const struct vkd3d_shader_descriptor_info1 *cbv) +-{ +- const struct vkd3d_shader_descriptor_binding *binding; +- struct vkd3d_string_buffer *buffer = gen->buffer; +- unsigned int binding_idx; +- size_t size; +- +- if (cbv->count != 1) +- { +- msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND, +- "Constant buffer %u has unsupported descriptor array size %u.", cbv->register_id, cbv->count); +- return; +- } +- +- if (!msl_get_cbv_binding(gen, cbv->register_space, cbv->register_index, &binding_idx)) +- { +- msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND, +- "No descriptor binding specified for constant buffer %u.", cbv->register_id); +- return; +- } +- +- binding = &gen->interface_info->bindings[binding_idx].binding; +- +- if (binding->set != 0) +- { +- msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND, +- "Unsupported binding set %u specified for constant buffer %u.", binding->set, cbv->register_id); +- return; +- } +- +- if (binding->count != 1) +- { +- msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND, +- "Unsupported binding count %u specified for constant buffer %u.", binding->count, cbv->register_id); +- return; +- } +- +- size = align(cbv->buffer_size, VKD3D_VEC4_SIZE * sizeof(uint32_t)); +- size /= VKD3D_VEC4_SIZE * sizeof(uint32_t); +- +- vkd3d_string_buffer_printf(buffer, +- "constant vkd3d_vec4 *cb_%u [[id(%u)]];", cbv->register_id, binding->binding); +-}; +- +-static void msl_generate_descriptor_struct_declarations(struct msl_generator *gen) +-{ +- const struct vkd3d_shader_scan_descriptor_info1 *info = &gen->program->descriptors; +- const struct vkd3d_shader_descriptor_info1 *descriptor; +- struct vkd3d_string_buffer *buffer = gen->buffer; +- unsigned int i; +- +- if (!info->descriptor_count) +- return; +- +- vkd3d_string_buffer_printf(buffer, "struct vkd3d_%s_descriptors\n{\n", gen->prefix); +- +- for (i = 0; i < info->descriptor_count; ++i) +- { +- descriptor = &info->descriptors[i]; +- +- msl_print_indent(buffer, 1); +- switch (descriptor->type) +- { +- case VKD3D_SHADER_DESCRIPTOR_TYPE_CBV: +- msl_generate_cbv_declaration(gen, descriptor); +- break; +- +- default: +- vkd3d_string_buffer_printf(buffer, "/* */", descriptor->type); +- msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, +- "Internal compiler error: Unhandled descriptor type %#x.", descriptor->type); +- break; +- } +- vkd3d_string_buffer_printf(buffer, "\n"); +- } +- +- vkd3d_string_buffer_printf(buffer, "};\n\n"); +-} +- + static void msl_generate_input_struct_declarations(struct msl_generator *gen) + { + const struct shader_signature *signature = &gen->program->input_signature; +@@ -1175,7 +1304,7 @@ static void msl_generate_entrypoint(struct msl_generator *gen) + msl_print_indent(gen->buffer, 2); + /* TODO: Configurable argument buffer binding location. */ + vkd3d_string_buffer_printf(gen->buffer, +- "constant vkd3d_%s_descriptors& descriptors [[buffer(0)]],\n", gen->prefix); ++ "constant descriptor *descriptors [[buffer(0)]],\n"); + } + + msl_print_indent(gen->buffer, 2); +@@ -1211,7 +1340,8 @@ static int msl_generator_generate(struct msl_generator *gen, struct vkd3d_shader + MESSAGE("Generating a MSL shader. This is unsupported; you get to keep all the pieces if it breaks.\n"); + + vkd3d_string_buffer_printf(gen->buffer, "/* Generated by %s. */\n\n", vkd3d_shader_get_version(NULL, NULL)); +- vkd3d_string_buffer_printf(gen->buffer, "#include \n\n"); ++ vkd3d_string_buffer_printf(gen->buffer, "#include \n"); ++ vkd3d_string_buffer_printf(gen->buffer, "#include \n\n"); + vkd3d_string_buffer_printf(gen->buffer, "using namespace metal;\n\n"); + + if (gen->program->global_flags) +@@ -1223,7 +1353,28 @@ static int msl_generator_generate(struct msl_generator *gen, struct vkd3d_shader + vkd3d_string_buffer_printf(gen->buffer, " int4 i;\n"); + vkd3d_string_buffer_printf(gen->buffer, " float4 f;\n};\n\n"); + +- msl_generate_descriptor_struct_declarations(gen); ++ if (gen->program->descriptors.descriptor_count > 0) ++ { ++ vkd3d_string_buffer_printf(gen->buffer, ++ "struct descriptor\n" ++ "{\n" ++ " const device void *ptr;\n" ++ "\n" ++ " template\n" ++ " constant T &tex() constant\n" ++ " {\n" ++ " return reinterpret_cast(this->ptr);\n" ++ " }\n" ++ "\n" ++ " template\n" ++ " const device T * constant &buf() constant\n" ++ " {\n" ++ " return reinterpret_cast(this->ptr);\n" ++ " }\n" ++ "};\n" ++ "\n"); ++ } ++ + msl_generate_input_struct_declarations(gen); + msl_generate_output_struct_declarations(gen); + +@@ -1234,7 +1385,7 @@ static int msl_generator_generate(struct msl_generator *gen, struct vkd3d_shader + if (gen->write_depth) + vkd3d_string_buffer_printf(gen->buffer, ", thread float& o_depth"); + if (gen->program->descriptors.descriptor_count) +- vkd3d_string_buffer_printf(gen->buffer, ", constant vkd3d_%s_descriptors& descriptors", gen->prefix); ++ vkd3d_string_buffer_printf(gen->buffer, ", constant descriptor *descriptors"); + vkd3d_string_buffer_printf(gen->buffer, ")\n{\n"); + + ++gen->indent; +diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c +index 91a6686eb0d..05cc0b9a55e 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/spirv.c ++++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c +@@ -7124,7 +7124,7 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp + return; + } + +- sampled_type = vkd3d_component_type_from_resource_data_type(descriptor->resource_data_type); ++ sampled_type = vkd3d_component_type_from_data_type(descriptor->resource_data_type); + + if (!is_uav && spirv_compiler_has_combined_sampler_for_resource(compiler, range)) + { +diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c +index 9191429c439..a0c24eaf18a 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c ++++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c +@@ -1063,7 +1063,7 @@ static void vkd3d_shader_scan_record_uav_atomic_op(struct vkd3d_shader_scan_cont + static struct vkd3d_shader_descriptor_info1 *vkd3d_shader_scan_add_descriptor(struct vkd3d_shader_scan_context *context, + enum vkd3d_shader_descriptor_type type, const struct vkd3d_shader_register *reg, + const struct vkd3d_shader_register_range *range, enum vkd3d_shader_resource_type resource_type, +- enum vkd3d_shader_resource_data_type resource_data_type) ++ enum vkd3d_data_type resource_data_type) + { + struct vkd3d_shader_scan_descriptor_info1 *info = context->scan_descriptor_info; + struct vkd3d_shader_descriptor_info1 *d; +@@ -1099,7 +1099,7 @@ static void vkd3d_shader_scan_constant_buffer_declaration(struct vkd3d_shader_sc + struct vkd3d_shader_descriptor_info1 *d; + + if (!(d = vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, +- &cb->src.reg, &cb->range, VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_SHADER_RESOURCE_DATA_UINT))) ++ &cb->src.reg, &cb->range, VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_DATA_UINT))) + return; + d->buffer_size = cb->size; + } +@@ -1111,7 +1111,7 @@ static void vkd3d_shader_scan_sampler_declaration(struct vkd3d_shader_scan_conte + struct vkd3d_shader_descriptor_info1 *d; + + if (!(d = vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, +- &sampler->src.reg, &sampler->range, VKD3D_SHADER_RESOURCE_NONE, VKD3D_SHADER_RESOURCE_DATA_UINT))) ++ &sampler->src.reg, &sampler->range, VKD3D_SHADER_RESOURCE_NONE, VKD3D_DATA_UINT))) + return; + + if (instruction->flags & VKD3DSI_SAMPLER_COMPARISON_MODE) +@@ -1122,9 +1122,9 @@ static void vkd3d_shader_scan_combined_sampler_declaration( + struct vkd3d_shader_scan_context *context, const struct vkd3d_shader_semantic *semantic) + { + vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, &semantic->resource.reg.reg, +- &semantic->resource.range, VKD3D_SHADER_RESOURCE_NONE, VKD3D_SHADER_RESOURCE_DATA_UINT); ++ &semantic->resource.range, VKD3D_SHADER_RESOURCE_NONE, VKD3D_DATA_UINT); + vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, &semantic->resource.reg.reg, +- &semantic->resource.range, semantic->resource_type, VKD3D_SHADER_RESOURCE_DATA_FLOAT); ++ &semantic->resource.range, semantic->resource_type, VKD3D_DATA_FLOAT); + } + + const struct vkd3d_shader_descriptor_info1 *vkd3d_shader_find_descriptor( +@@ -1214,8 +1214,8 @@ static void vkd3d_shader_scan_combined_sampler_usage(struct vkd3d_shader_scan_co + + static void vkd3d_shader_scan_resource_declaration(struct vkd3d_shader_scan_context *context, + const struct vkd3d_shader_resource *resource, enum vkd3d_shader_resource_type resource_type, +- enum vkd3d_shader_resource_data_type resource_data_type, +- unsigned int sample_count, unsigned int structure_stride, bool raw, uint32_t flags) ++ enum vkd3d_data_type resource_data_type, unsigned int sample_count, ++ unsigned int structure_stride, bool raw, uint32_t flags) + { + struct vkd3d_shader_descriptor_info1 *d; + enum vkd3d_shader_descriptor_type type; +@@ -1239,59 +1239,16 @@ static void vkd3d_shader_scan_typed_resource_declaration(struct vkd3d_shader_sca + const struct vkd3d_shader_instruction *instruction) + { + const struct vkd3d_shader_semantic *semantic = &instruction->declaration.semantic; +- enum vkd3d_shader_resource_data_type resource_data_type; + +- if (semantic->resource_data_type[0] != semantic->resource_data_type[1] || +- semantic->resource_data_type[0] != semantic->resource_data_type[2] || +- semantic->resource_data_type[0] != semantic->resource_data_type[3]) +- FIXME("Resource data types are different (%d, %d, %d, %d).\n", +- semantic->resource_data_type[0], +- semantic->resource_data_type[1], +- semantic->resource_data_type[2], +- semantic->resource_data_type[3]); ++ if (semantic->resource_data_type[0] != semantic->resource_data_type[1] ++ || semantic->resource_data_type[0] != semantic->resource_data_type[2] ++ || semantic->resource_data_type[0] != semantic->resource_data_type[3]) ++ FIXME("Resource data types are different (%#x, %#x, %#x, %#x).\n", ++ semantic->resource_data_type[0], semantic->resource_data_type[1], ++ semantic->resource_data_type[2], semantic->resource_data_type[3]); + +- switch (semantic->resource_data_type[0]) +- { +- case VKD3D_DATA_UNORM: +- resource_data_type = VKD3D_SHADER_RESOURCE_DATA_UNORM; +- break; +- case VKD3D_DATA_SNORM: +- resource_data_type = VKD3D_SHADER_RESOURCE_DATA_SNORM; +- break; +- case VKD3D_DATA_INT: +- resource_data_type = VKD3D_SHADER_RESOURCE_DATA_INT; +- break; +- case VKD3D_DATA_UINT: +- resource_data_type = VKD3D_SHADER_RESOURCE_DATA_UINT; +- break; +- case VKD3D_DATA_FLOAT: +- resource_data_type = VKD3D_SHADER_RESOURCE_DATA_FLOAT; +- break; +- case VKD3D_DATA_MIXED: +- resource_data_type = VKD3D_SHADER_RESOURCE_DATA_MIXED; +- break; +- case VKD3D_DATA_DOUBLE: +- resource_data_type = VKD3D_SHADER_RESOURCE_DATA_DOUBLE; +- break; +- case VKD3D_DATA_CONTINUED: +- resource_data_type = VKD3D_SHADER_RESOURCE_DATA_CONTINUED; +- break; +- default: +- ERR("Invalid resource data type %#x.\n", semantic->resource_data_type[0]); +- resource_data_type = VKD3D_SHADER_RESOURCE_DATA_FLOAT; +- break; +- } +- +- if (context->api_version < VKD3D_SHADER_API_VERSION_1_3 +- && resource_data_type >= VKD3D_SHADER_RESOURCE_DATA_MIXED) +- { +- ERR("Invalid resource data type %#x for API version %#x.\n", +- semantic->resource_data_type[0], context->api_version); +- resource_data_type = VKD3D_SHADER_RESOURCE_DATA_FLOAT; +- } +- +- vkd3d_shader_scan_resource_declaration(context, &semantic->resource, +- semantic->resource_type, resource_data_type, semantic->sample_count, 0, false, instruction->flags); ++ vkd3d_shader_scan_resource_declaration(context, &semantic->resource, semantic->resource_type, ++ semantic->resource_data_type[0], semantic->sample_count, 0, false, instruction->flags); + } + + static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *context, +@@ -1327,12 +1284,12 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte + case VKD3DSIH_DCL_RESOURCE_RAW: + case VKD3DSIH_DCL_UAV_RAW: + vkd3d_shader_scan_resource_declaration(context, &instruction->declaration.raw_resource.resource, +- VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_SHADER_RESOURCE_DATA_UINT, 0, 0, true, instruction->flags); ++ VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_DATA_UINT, 0, 0, true, instruction->flags); + break; + case VKD3DSIH_DCL_RESOURCE_STRUCTURED: + case VKD3DSIH_DCL_UAV_STRUCTURED: + vkd3d_shader_scan_resource_declaration(context, &instruction->declaration.structured_resource.resource, +- VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_SHADER_RESOURCE_DATA_UINT, 0, ++ VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_DATA_UINT, 0, + instruction->declaration.structured_resource.byte_stride, false, instruction->flags); + break; + case VKD3DSIH_DCL_TESSELLATOR_OUTPUT_PRIMITIVE: +@@ -1543,8 +1500,34 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte + return VKD3D_OK; + } + +-static enum vkd3d_result convert_descriptor_info(struct vkd3d_shader_scan_descriptor_info *info, +- const struct vkd3d_shader_scan_descriptor_info1 *info1) ++static enum vkd3d_shader_resource_data_type vkd3d_resource_data_type_from_data_type(enum vkd3d_data_type data_type) ++{ ++ switch (data_type) ++ { ++ case VKD3D_DATA_UNORM: ++ return VKD3D_SHADER_RESOURCE_DATA_UNORM; ++ case VKD3D_DATA_SNORM: ++ return VKD3D_SHADER_RESOURCE_DATA_SNORM; ++ case VKD3D_DATA_INT: ++ return VKD3D_SHADER_RESOURCE_DATA_INT; ++ case VKD3D_DATA_UINT: ++ return VKD3D_SHADER_RESOURCE_DATA_UINT; ++ case VKD3D_DATA_FLOAT: ++ return VKD3D_SHADER_RESOURCE_DATA_FLOAT; ++ case VKD3D_DATA_MIXED: ++ return VKD3D_SHADER_RESOURCE_DATA_MIXED; ++ case VKD3D_DATA_DOUBLE: ++ return VKD3D_SHADER_RESOURCE_DATA_DOUBLE; ++ case VKD3D_DATA_CONTINUED: ++ return VKD3D_SHADER_RESOURCE_DATA_CONTINUED; ++ default: ++ ERR("Invalid resource data type %#x.\n", data_type); ++ return VKD3D_SHADER_RESOURCE_DATA_FLOAT; ++ } ++} ++ ++static enum vkd3d_result convert_descriptor_info(struct vkd3d_shader_scan_context *context, ++ struct vkd3d_shader_scan_descriptor_info *info, const struct vkd3d_shader_scan_descriptor_info1 *info1) + { + unsigned int i; + +@@ -1560,9 +1543,17 @@ static enum vkd3d_result convert_descriptor_info(struct vkd3d_shader_scan_descri + dst->register_space = src->register_space; + dst->register_index = src->register_index; + dst->resource_type = src->resource_type; +- dst->resource_data_type = src->resource_data_type; ++ dst->resource_data_type = vkd3d_resource_data_type_from_data_type(src->resource_data_type); + dst->flags = src->flags; + dst->count = src->count; ++ ++ if (context->api_version < VKD3D_SHADER_API_VERSION_1_3 ++ && dst->resource_data_type >= VKD3D_SHADER_RESOURCE_DATA_MIXED) ++ { ++ ERR("Invalid resource data type %#x for API version %#x.\n", ++ src->resource_data_type, context->api_version); ++ dst->resource_data_type = VKD3D_SHADER_RESOURCE_DATA_FLOAT; ++ } + } + info->descriptor_count = info1->descriptor_count; + +@@ -1629,7 +1620,7 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh + if (size) + { + if ((d = vkd3d_shader_scan_add_descriptor(&context, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, ®, +- &range, VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_SHADER_RESOURCE_DATA_UINT))) ++ &range, VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_DATA_UINT))) + d->buffer_size = size * 16; + } + } +@@ -1647,7 +1638,7 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh + } + + if (!ret && descriptor_info) +- ret = convert_descriptor_info(descriptor_info, &program->descriptors); ++ ret = convert_descriptor_info(&context, descriptor_info, &program->descriptors); + + if (!ret && tessellation_info) + { +diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +index bf794d5e936..05ef8beeb9c 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h ++++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +@@ -262,6 +262,7 @@ enum vkd3d_shader_error + + VKD3D_SHADER_ERROR_MSL_INTERNAL = 10000, + VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND = 10001, ++ VKD3D_SHADER_ERROR_MSL_UNSUPPORTED = 10002, + + VKD3D_SHADER_ERROR_FX_NOT_IMPLEMENTED = 11000, + VKD3D_SHADER_ERROR_FX_INVALID_VERSION = 11001, +@@ -1005,6 +1006,7 @@ void vsir_src_param_init(struct vkd3d_shader_src_param *param, enum vkd3d_shader + enum vkd3d_data_type data_type, unsigned int idx_count); + void vsir_dst_param_init(struct vkd3d_shader_dst_param *param, enum vkd3d_shader_register_type reg_type, + enum vkd3d_data_type data_type, unsigned int idx_count); ++void vsir_dst_param_init_null(struct vkd3d_shader_dst_param *dst); + void vsir_src_param_init_label(struct vkd3d_shader_src_param *param, unsigned int label_id); + + struct vkd3d_shader_index_range +@@ -1429,7 +1431,7 @@ struct vkd3d_shader_descriptor_info1 + unsigned int register_index; + unsigned int register_id; + enum vkd3d_shader_resource_type resource_type; +- enum vkd3d_shader_resource_data_type resource_data_type; ++ enum vkd3d_data_type resource_data_type; + unsigned int flags; + unsigned int sample_count; + unsigned int buffer_size; +@@ -1562,6 +1564,8 @@ enum vsir_asm_flags + VSIR_ASM_FLAG_NONE = 0, + VSIR_ASM_FLAG_DUMP_TYPES = 0x1, + VSIR_ASM_FLAG_DUMP_ALL_INDICES = 0x2, ++ VSIR_ASM_FLAG_DUMP_SIGNATURES = 0x4, ++ VSIR_ASM_FLAG_DUMP_DESCRIPTORS = 0x8, + }; + + enum vkd3d_result d3d_asm_compile(const struct vsir_program *program, +@@ -1653,7 +1657,8 @@ void vkd3d_shader_trace_text_(const char *text, size_t size, const char *functio + vkd3d_shader_trace_text_(text, size, __FUNCTION__) + + bool sm1_register_from_semantic_name(const struct vkd3d_shader_version *version, const char *semantic_name, +- unsigned int semantic_index, bool output, enum vkd3d_shader_register_type *type, unsigned int *reg); ++ unsigned int semantic_index, bool output, enum vkd3d_shader_sysval_semantic *sysval, ++ enum vkd3d_shader_register_type *type, unsigned int *reg); + bool sm1_usage_from_semantic_name(const char *semantic_name, + uint32_t semantic_index, enum vkd3d_decl_usage *usage, uint32_t *usage_idx); + bool sm4_register_from_semantic_name(const struct vkd3d_shader_version *version, +@@ -1764,30 +1769,6 @@ static inline enum vkd3d_data_type vkd3d_data_type_from_component_type( + } + } + +-static inline enum vkd3d_shader_component_type vkd3d_component_type_from_resource_data_type( +- enum vkd3d_shader_resource_data_type data_type) +-{ +- switch (data_type) +- { +- case VKD3D_SHADER_RESOURCE_DATA_FLOAT: +- case VKD3D_SHADER_RESOURCE_DATA_UNORM: +- case VKD3D_SHADER_RESOURCE_DATA_SNORM: +- return VKD3D_SHADER_COMPONENT_FLOAT; +- case VKD3D_SHADER_RESOURCE_DATA_UINT: +- return VKD3D_SHADER_COMPONENT_UINT; +- case VKD3D_SHADER_RESOURCE_DATA_INT: +- return VKD3D_SHADER_COMPONENT_INT; +- case VKD3D_SHADER_RESOURCE_DATA_DOUBLE: +- case VKD3D_SHADER_RESOURCE_DATA_CONTINUED: +- return VKD3D_SHADER_COMPONENT_DOUBLE; +- default: +- FIXME("Unhandled data type %#x.\n", data_type); +- /* fall-through */ +- case VKD3D_SHADER_RESOURCE_DATA_MIXED: +- return VKD3D_SHADER_COMPONENT_UINT; +- } +-} +- + static inline bool component_type_is_64_bit(enum vkd3d_shader_component_type component_type) + { + return component_type == VKD3D_SHADER_COMPONENT_DOUBLE || component_type == VKD3D_SHADER_COMPONENT_UINT64; +-- +2.47.2 + diff --git a/patches/vkd3d-latest/0004-Updated-vkd3d-to-c764f71cf58e3a8327b44c588ad3696b422.patch b/patches/vkd3d-latest/0004-Updated-vkd3d-to-c764f71cf58e3a8327b44c588ad3696b422.patch new file mode 100644 index 00000000..1709237b --- /dev/null +++ b/patches/vkd3d-latest/0004-Updated-vkd3d-to-c764f71cf58e3a8327b44c588ad3696b422.patch @@ -0,0 +1,304 @@ +From 98ac96121b2336a832083bfdd833e93265291739 Mon Sep 17 00:00:00 2001 +From: Alistair Leslie-Hughes +Date: Thu, 17 Apr 2025 08:02:13 +1000 +Subject: [PATCH] Updated vkd3d to c764f71cf58e3a8327b44c588ad3696b422cf8a3. + +--- + libs/vkd3d/include/vkd3d_shader.h | 5 ++ + libs/vkd3d/libs/vkd3d-shader/hlsl.y | 44 ++++++++++++------ + libs/vkd3d/libs/vkd3d-shader/ir.c | 46 ++++++++++++++++++- + .../libs/vkd3d-shader/vkd3d_shader_main.c | 10 +++- + .../libs/vkd3d-shader/vkd3d_shader_private.h | 5 ++ + 5 files changed, 92 insertions(+), 18 deletions(-) + +diff --git a/libs/vkd3d/include/vkd3d_shader.h b/libs/vkd3d/include/vkd3d_shader.h +index 2e1f37f12e6..6b2805e8759 100644 +--- a/libs/vkd3d/include/vkd3d_shader.h ++++ b/libs/vkd3d/include/vkd3d_shader.h +@@ -2076,6 +2076,11 @@ enum vkd3d_shader_resource_type + */ + enum vkd3d_shader_resource_data_type + { ++ /** ++ * The descriptor has no relevant data type. This value is returned for ++ * samplers. \since 1.16 ++ */ ++ VKD3D_SHADER_RESOURCE_DATA_NONE = 0x0, + /** Unsigned normalized integer. */ + VKD3D_SHADER_RESOURCE_DATA_UNORM = 0x1, + /** Signed normalized integer. */ +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y +index 6086d018fdc..40fd142f58d 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y +@@ -997,10 +997,24 @@ static void free_parse_variable_def(struct parse_variable_def *v) + vkd3d_free(v->arrays.sizes); + vkd3d_free(v->name); + hlsl_cleanup_semantic(&v->semantic); +- VKD3D_ASSERT(!v->state_blocks); ++ if (v->state_block_count) ++ { ++ for (unsigned int i = 0; i < v->state_block_count; ++i) ++ hlsl_free_state_block(v->state_blocks[i]); ++ vkd3d_free(v->state_blocks); ++ } + vkd3d_free(v); + } + ++static void destroy_parse_variable_defs(struct list *defs) ++{ ++ struct parse_variable_def *v, *v_next; ++ ++ LIST_FOR_EACH_ENTRY_SAFE(v, v_next, defs, struct parse_variable_def, entry) ++ free_parse_variable_def(v); ++ vkd3d_free(defs); ++} ++ + static bool gen_struct_fields(struct hlsl_ctx *ctx, struct parse_fields *fields, + struct hlsl_type *type, uint32_t modifiers, struct list *defs) + { +@@ -2618,11 +2632,7 @@ static struct hlsl_block *initialize_vars(struct hlsl_ctx *ctx, struct list *var + + if (!(initializers = make_empty_block(ctx))) + { +- LIST_FOR_EACH_ENTRY_SAFE(v, v_next, var_list, struct parse_variable_def, entry) +- { +- free_parse_variable_def(v); +- } +- vkd3d_free(var_list); ++ destroy_parse_variable_defs(var_list); + return NULL; + } + +@@ -6551,7 +6561,6 @@ static void validate_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim, + bool boolval; + char *name; + uint32_t modifiers; +- struct hlsl_ir_node *instr; + struct hlsl_block *block; + struct list *list; + struct parse_fields fields; +@@ -6723,6 +6732,8 @@ static void validate_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim, + %type variables_def + %type variables_def_typed + %type switch_cases ++%destructor { destroy_parse_variable_defs($$); } type_specs variables_def variables_def_typed; ++%destructor { destroy_switch_cases($$); } switch_cases; + + %token VAR_IDENTIFIER + %token NEW_IDENTIFIER +@@ -6766,9 +6777,9 @@ static void validate_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim, + %type selection_statement + %type statement + %type statement_list +-%type struct_declaration_without_vars + %type switch_statement + %type unary_expr ++%destructor { destroy_block($$); } + + %type boolean + +@@ -6819,6 +6830,7 @@ static void validate_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim, + %type state_block_index_opt + + %type switch_case ++%destructor { hlsl_free_ir_switch_case($$); } + + %type base_optional + %type field_type +@@ -6835,6 +6847,7 @@ static void validate_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim, + %type variable_decl + %type variable_def + %type variable_def_typed ++%destructor { free_parse_variable_def($$); } + + %% + +@@ -6988,6 +7001,9 @@ buffer_type: + declaration_statement_list: + %empty + | declaration_statement_list declaration_statement ++ { ++ destroy_block($2); ++ } + + preproc_directive: + PRE_LINE STRING +@@ -7021,9 +7037,6 @@ struct_declaration_without_vars: + if ($1) + hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, + "Modifiers are not allowed on struct type declarations."); +- +- if (!($$ = make_empty_block(ctx))) +- YYABORT; + } + + struct_spec: +@@ -8144,6 +8157,10 @@ type: + declaration_statement: + declaration + | struct_declaration_without_vars ++ { ++ if (!($$ = make_empty_block(ctx))) ++ YYABORT; ++ } + | typedef + { + if (!($$ = make_empty_block(ctx))) +@@ -8157,15 +8174,12 @@ typedef_type: + typedef: + KW_TYPEDEF var_modifiers typedef_type type_specs ';' + { +- struct parse_variable_def *v, *v_next; + uint32_t modifiers = $2; + struct hlsl_type *type; + + if (!(type = apply_type_modifiers(ctx, $3, &modifiers, false, &@2))) + { +- LIST_FOR_EACH_ENTRY_SAFE(v, v_next, $4, struct parse_variable_def, entry) +- free_parse_variable_def(v); +- vkd3d_free($4); ++ destroy_parse_variable_defs($4); + YYABORT; + } + +diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c +index d25485ab004..95093102552 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/ir.c ++++ b/libs/vkd3d/libs/vkd3d-shader/ir.c +@@ -8357,8 +8357,11 @@ static void vsir_validate_src_param(struct validation_context *ctx, + break; + + case VKD3DSPR_NULL: ++ case VKD3DSPR_DEPTHOUT: ++ case VKD3DSPR_DEPTHOUTGE: ++ case VKD3DSPR_DEPTHOUTLE: + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE, +- "Invalid NULL register used as source parameter."); ++ "Invalid register of type %#x used as source parameter.", src->reg.type); + break; + + case VKD3DSPR_INPUT: +@@ -8857,6 +8860,45 @@ static void vsir_validate_signature(struct validation_context *ctx, const struct + } + } + ++static void vsir_validate_descriptors(struct validation_context *ctx) ++{ ++ const struct vkd3d_shader_scan_descriptor_info1 *descriptors = &ctx->program->descriptors; ++ unsigned int i; ++ ++ for (i = 0; i < descriptors->descriptor_count; ++i) ++ { ++ const struct vkd3d_shader_descriptor_info1 *descriptor = &descriptors->descriptors[i]; ++ ++ if (descriptor->type >= VKD3D_SHADER_DESCRIPTOR_TYPE_COUNT) ++ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DESCRIPTOR_TYPE, ++ "Descriptor %u has invalid type %#x.", i, descriptor->type); ++ ++ if (descriptor->resource_type >= VKD3D_SHADER_RESOURCE_TYPE_COUNT) ++ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_RESOURCE_TYPE, ++ "Descriptor %u has invalid resource type %#x.", i, descriptor->resource_type); ++ else if ((descriptor->resource_type == VKD3D_SHADER_RESOURCE_NONE) ++ != (descriptor->type == VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER)) ++ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_RESOURCE_TYPE, ++ "Descriptor %u has invalid resource type %#x for descriptor type %#x.", ++ i, descriptor->resource_type, descriptor->type); ++ ++ if (descriptor->resource_data_type >= VKD3D_DATA_COUNT) ++ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, ++ "Descriptor %u has invalid resource data type %#x.", i, descriptor->resource_data_type); ++ else if ((descriptor->resource_data_type == VKD3D_DATA_UNUSED) ++ != (descriptor->type == VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER)) ++ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, ++ "Descriptor %u has invalid resource data type %#x for descriptor type %#x.", ++ i, descriptor->resource_data_type, descriptor->type); ++ ++ if (!descriptor->count || (descriptor->count > UINT_MAX - descriptor->register_index ++ && descriptor->count != UINT_MAX)) ++ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DESCRIPTOR_COUNT, ++ "Descriptor %u has invalid descriptor count %u starting at index %u.", ++ i, descriptor->count, descriptor->register_index); ++ } ++} ++ + static const char *name_from_cf_type(enum vsir_control_flow_type type) + { + switch (type) +@@ -9823,6 +9865,8 @@ enum vkd3d_result vsir_program_validate(struct vsir_program *program, uint64_t c + } + } + ++ vsir_validate_descriptors(&ctx); ++ + if (!(ctx.temps = vkd3d_calloc(ctx.program->temp_count, sizeof(*ctx.temps)))) + goto fail; + +diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c +index a0c24eaf18a..4103cdc1ef9 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c ++++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c +@@ -1111,7 +1111,7 @@ static void vkd3d_shader_scan_sampler_declaration(struct vkd3d_shader_scan_conte + struct vkd3d_shader_descriptor_info1 *d; + + if (!(d = vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, +- &sampler->src.reg, &sampler->range, VKD3D_SHADER_RESOURCE_NONE, VKD3D_DATA_UINT))) ++ &sampler->src.reg, &sampler->range, VKD3D_SHADER_RESOURCE_NONE, VKD3D_DATA_UNUSED))) + return; + + if (instruction->flags & VKD3DSI_SAMPLER_COMPARISON_MODE) +@@ -1122,7 +1122,7 @@ static void vkd3d_shader_scan_combined_sampler_declaration( + struct vkd3d_shader_scan_context *context, const struct vkd3d_shader_semantic *semantic) + { + vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, &semantic->resource.reg.reg, +- &semantic->resource.range, VKD3D_SHADER_RESOURCE_NONE, VKD3D_DATA_UINT); ++ &semantic->resource.range, VKD3D_SHADER_RESOURCE_NONE, VKD3D_DATA_UNUSED); + vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, &semantic->resource.reg.reg, + &semantic->resource.range, semantic->resource_type, VKD3D_DATA_FLOAT); + } +@@ -1520,6 +1520,8 @@ static enum vkd3d_shader_resource_data_type vkd3d_resource_data_type_from_data_t + return VKD3D_SHADER_RESOURCE_DATA_DOUBLE; + case VKD3D_DATA_CONTINUED: + return VKD3D_SHADER_RESOURCE_DATA_CONTINUED; ++ case VKD3D_DATA_UNUSED: ++ return VKD3D_SHADER_RESOURCE_DATA_NONE; + default: + ERR("Invalid resource data type %#x.\n", data_type); + return VKD3D_SHADER_RESOURCE_DATA_FLOAT; +@@ -1547,6 +1549,10 @@ static enum vkd3d_result convert_descriptor_info(struct vkd3d_shader_scan_contex + dst->flags = src->flags; + dst->count = src->count; + ++ if (context->api_version <= VKD3D_SHADER_API_VERSION_1_15 ++ && dst->type == VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER) ++ dst->resource_data_type = VKD3D_SHADER_RESOURCE_DATA_UINT; ++ + if (context->api_version < VKD3D_SHADER_API_VERSION_1_3 + && dst->resource_data_type >= VKD3D_SHADER_RESOURCE_DATA_MIXED) + { +diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +index 05ef8beeb9c..3b4fb626fcc 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h ++++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +@@ -61,6 +61,8 @@ + + #define VKD3D_SHADER_COMPONENT_TYPE_COUNT (VKD3D_SHADER_COMPONENT_INT16 + 1) + #define VKD3D_SHADER_MINIMUM_PRECISION_COUNT (VKD3D_SHADER_MINIMUM_PRECISION_UINT_16 + 1) ++#define VKD3D_SHADER_DESCRIPTOR_TYPE_COUNT (VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER + 1) ++#define VKD3D_SHADER_RESOURCE_TYPE_COUNT (VKD3D_SHADER_RESOURCE_TEXTURE_CUBEARRAY + 1) + + #define VKD3D_MAX_STREAM_COUNT 4 + +@@ -257,6 +259,9 @@ enum vkd3d_shader_error + VKD3D_SHADER_ERROR_VSIR_MISSING_SEMANTIC = 9021, + VKD3D_SHADER_ERROR_VSIR_INVALID_SIGNATURE = 9022, + VKD3D_SHADER_ERROR_VSIR_INVALID_RANGE = 9023, ++ VKD3D_SHADER_ERROR_VSIR_INVALID_DESCRIPTOR_TYPE = 9024, ++ VKD3D_SHADER_ERROR_VSIR_INVALID_RESOURCE_TYPE = 9025, ++ VKD3D_SHADER_ERROR_VSIR_INVALID_DESCRIPTOR_COUNT = 9026, + + VKD3D_SHADER_WARNING_VSIR_DYNAMIC_DESCRIPTOR_ARRAY = 9300, + +-- +2.47.2 +