From e855d43a6021c349f5f01f9c48f4f955d1249125 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Tue, 6 May 2025 06:58:53 +1000 Subject: [PATCH] Updated vkd3d-latest patchset Squash and Update. --- ...541060215e338a419a5a6fe6ae156fecf1c.patch} | 4526 ++++++++++++++--- ...-4289ec60a1f79f68ea9bd3624141b5657b8.patch | 1718 +++++++ ...-cbce3a8631116ec10895e6c9c4a00b89b05.patch | 213 - ...-f02ea94c428f6b2f662f78fc78eae7f3342.patch | 1765 ------- ...-c764f71cf58e3a8327b44c588ad3696b422.patch | 304 -- ...-ceb2787d466713096ea9746d2b63a4608fd.patch | 638 --- ...-8882d324a6e91654b4ea2908506e400986a.patch | 39 - ...-541060215e338a419a5a6fe6ae156fecf1c.patch | 745 --- 8 files changed, 5486 insertions(+), 4462 deletions(-) rename patches/vkd3d-latest/{0001-Updated-vkd3d-to-f576ecc9929dd98c900bb8bc0335b91a1a0.patch => 0001-Updated-vkd3d-to-541060215e338a419a5a6fe6ae156fecf1c.patch} (85%) create mode 100644 patches/vkd3d-latest/0002-Updated-vkd3d-to-4289ec60a1f79f68ea9bd3624141b5657b8.patch delete mode 100644 patches/vkd3d-latest/0002-Updated-vkd3d-to-cbce3a8631116ec10895e6c9c4a00b89b05.patch delete mode 100644 patches/vkd3d-latest/0003-Updated-vkd3d-to-f02ea94c428f6b2f662f78fc78eae7f3342.patch delete mode 100644 patches/vkd3d-latest/0004-Updated-vkd3d-to-c764f71cf58e3a8327b44c588ad3696b422.patch delete mode 100644 patches/vkd3d-latest/0005-Updated-vkd3d-to-ceb2787d466713096ea9746d2b63a4608fd.patch delete mode 100644 patches/vkd3d-latest/0006-Updated-vkd3d-to-8882d324a6e91654b4ea2908506e400986a.patch delete mode 100644 patches/vkd3d-latest/0007-Updated-vkd3d-to-541060215e338a419a5a6fe6ae156fecf1c.patch diff --git a/patches/vkd3d-latest/0001-Updated-vkd3d-to-f576ecc9929dd98c900bb8bc0335b91a1a0.patch b/patches/vkd3d-latest/0001-Updated-vkd3d-to-541060215e338a419a5a6fe6ae156fecf1c.patch similarity index 85% rename from patches/vkd3d-latest/0001-Updated-vkd3d-to-f576ecc9929dd98c900bb8bc0335b91a1a0.patch rename to patches/vkd3d-latest/0001-Updated-vkd3d-to-541060215e338a419a5a6fe6ae156fecf1c.patch index bb2675f6..72e8ea07 100644 --- a/patches/vkd3d-latest/0001-Updated-vkd3d-to-f576ecc9929dd98c900bb8bc0335b91a1a0.patch +++ b/patches/vkd3d-latest/0001-Updated-vkd3d-to-541060215e338a419a5a6fe6ae156fecf1c.patch @@ -1,42 +1,42 @@ -From 11b1f07cfad213e1e17bc2ae609fa0d9c1628ddb Mon Sep 17 00:00:00 2001 +From 76cffe1f955bbc144897fcc36d2f68d7f34dec29 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Fri, 21 Feb 2025 09:15:01 +1100 -Subject: [PATCH] Updated vkd3d to f576ecc9929dd98c900bb8bc0335b91a1a0d3bff. +Subject: [PATCH] Updated vkd3d to 541060215e338a419a5a6fe6ae156fecf1c4b89f. --- libs/vkd3d/include/private/spirv_grammar.h | 10103 ++++++++++++++++ libs/vkd3d/include/private/vkd3d_common.h | 5 +- .../include/private/vkd3d_shader_utils.h | 4 - libs/vkd3d/include/private/vkd3d_version.h | 2 +- - libs/vkd3d/include/vkd3d_shader.h | 15 +- + libs/vkd3d/include/vkd3d_shader.h | 20 +- libs/vkd3d/libs/vkd3d-common/blob.c | 1 + - libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 24 +- - libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 32 +- + libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 229 +- + libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 163 +- libs/vkd3d/libs/vkd3d-shader/dxbc.c | 34 +- - libs/vkd3d/libs/vkd3d-shader/dxil.c | 99 +- - libs/vkd3d/libs/vkd3d-shader/fx.c | 1862 ++- - libs/vkd3d/libs/vkd3d-shader/glsl.c | 27 +- - libs/vkd3d/libs/vkd3d-shader/hlsl.c | 377 +- - libs/vkd3d/libs/vkd3d-shader/hlsl.h | 104 +- + libs/vkd3d/libs/vkd3d-shader/dxil.c | 171 +- + libs/vkd3d/libs/vkd3d-shader/fx.c | 1864 ++- + libs/vkd3d/libs/vkd3d-shader/glsl.c | 95 +- + libs/vkd3d/libs/vkd3d-shader/hlsl.c | 426 +- + libs/vkd3d/libs/vkd3d-shader/hlsl.h | 118 +- libs/vkd3d/libs/vkd3d-shader/hlsl.l | 5 + - libs/vkd3d/libs/vkd3d-shader/hlsl.y | 1309 +- - libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 3568 +++--- + libs/vkd3d/libs/vkd3d-shader/hlsl.y | 1487 +-- + libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 3665 +++--- .../libs/vkd3d-shader/hlsl_constant_ops.c | 81 +- - libs/vkd3d/libs/vkd3d-shader/ir.c | 433 +- - libs/vkd3d/libs/vkd3d-shader/msl.c | 15 +- + libs/vkd3d/libs/vkd3d-shader/ir.c | 504 +- + libs/vkd3d/libs/vkd3d-shader/msl.c | 625 +- libs/vkd3d/libs/vkd3d-shader/preproc.l | 1 + libs/vkd3d/libs/vkd3d-shader/preproc.y | 10 + - libs/vkd3d/libs/vkd3d-shader/spirv.c | 464 +- - libs/vkd3d/libs/vkd3d-shader/tpf.c | 128 +- - .../libs/vkd3d-shader/vkd3d_shader_main.c | 198 +- - .../libs/vkd3d-shader/vkd3d_shader_private.h | 71 +- + libs/vkd3d/libs/vkd3d-shader/spirv.c | 468 +- + libs/vkd3d/libs/vkd3d-shader/tpf.c | 184 +- + .../libs/vkd3d-shader/vkd3d_shader_main.c | 323 +- + .../libs/vkd3d-shader/vkd3d_shader_private.h | 107 +- .../vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c | 2 + libs/vkd3d/libs/vkd3d/command.c | 50 +- libs/vkd3d/libs/vkd3d/device.c | 37 +- libs/vkd3d/libs/vkd3d/resource.c | 14 +- libs/vkd3d/libs/vkd3d/state.c | 118 +- libs/vkd3d/libs/vkd3d/vkd3d_private.h | 2 +- - 32 files changed, 16168 insertions(+), 3027 deletions(-) + 32 files changed, 17404 insertions(+), 3514 deletions(-) create mode 100644 libs/vkd3d/include/private/spirv_grammar.h diff --git a/libs/vkd3d/include/private/spirv_grammar.h b/libs/vkd3d/include/private/spirv_grammar.h @@ -10203,7 +10203,7 @@ index 0edc4428022..795bc2dc490 100644 -#define VKD3D_VCS_ID " (Wine bundled)" +#define VKD3D_VCS_ID " (git a4f58be0)" diff --git a/libs/vkd3d/include/vkd3d_shader.h b/libs/vkd3d/include/vkd3d_shader.h -index 058166aa2f9..2e1f37f12e6 100644 +index 058166aa2f9..6b2805e8759 100644 --- a/libs/vkd3d/include/vkd3d_shader.h +++ b/libs/vkd3d/include/vkd3d_shader.h @@ -249,6 +249,10 @@ enum vkd3d_shader_compile_option_feature_flags @@ -10217,7 +10217,19 @@ index 058166aa2f9..2e1f37f12e6 100644 VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_FEATURE_FLAGS), }; -@@ -2286,6 +2290,14 @@ enum vkd3d_shader_component_type +@@ -2072,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. */ +@@ -2286,6 +2295,14 @@ enum vkd3d_shader_component_type VKD3D_SHADER_COMPONENT_DOUBLE = 0x5, /** 64-bit unsigned integer. \since 1.11 */ VKD3D_SHADER_COMPONENT_UINT64 = 0x6, @@ -10232,7 +10244,7 @@ index 058166aa2f9..2e1f37f12e6 100644 VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPONENT_TYPE), }; -@@ -2991,7 +3003,8 @@ VKD3D_SHADER_API void vkd3d_shader_free_scan_descriptor_info( +@@ -2991,7 +3008,8 @@ VKD3D_SHADER_API void vkd3d_shader_free_scan_descriptor_info( * signature. To retrieve signatures from other shader types, or other signature * types, use vkd3d_shader_scan() and struct vkd3d_shader_scan_signature_info. * This function returns the same input signature that is returned in @@ -10255,10 +10267,87 @@ index f60ef7db769..c2c6ad67804 100644 #include "vkd3d.h" #include "vkd3d_blob.h" diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c -index 0639da83aa6..764f0888490 100644 +index 0639da83aa6..4521bfabd8e 100644 --- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c +++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c -@@ -2069,15 +2069,22 @@ static const char *get_component_type_name(enum vkd3d_shader_component_type type +@@ -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, ")"); +@@ -2069,15 +2067,22 @@ static const char *get_component_type_name(enum vkd3d_shader_component_type type { switch (type) { @@ -10289,7 +10378,7 @@ index 0639da83aa6..764f0888490 100644 } static const char *get_minimum_precision_name(enum vkd3d_shader_minimum_precision prec) -@@ -2097,6 +2104,7 @@ static const char *get_semantic_register_name(enum vkd3d_shader_sysval_semantic +@@ -2097,6 +2102,7 @@ static const char *get_semantic_register_name(enum vkd3d_shader_sysval_semantic { switch (semantic) { @@ -10297,11 +10386,397 @@ index 0639da83aa6..764f0888490 100644 case VKD3D_SHADER_SV_DEPTH: return "oDepth"; case VKD3D_SHADER_SV_DEPTH_GREATER_EQUAL: return "oDepthGE"; case VKD3D_SHADER_SV_DEPTH_LESS_EQUAL: return "oDepthLE"; +@@ -2194,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, +@@ -2263,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); +@@ -2273,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) + { +@@ -2380,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; +@@ -2392,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) +@@ -2409,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 58e35cf22e8..b49ef9865db 100644 +index 58e35cf22e8..57d874efe37 100644 --- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c +++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c -@@ -1759,27 +1759,40 @@ static bool is_inconsequential_instr(const struct vkd3d_shader_instruction *ins) +@@ -1215,6 +1215,7 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str + struct vkd3d_shader_src_param *src_params, *predicate; + const struct vkd3d_sm1_opcode_info *opcode_info; + struct vsir_program *program = sm1->p.program; ++ unsigned int vsir_dst_count, vsir_src_count; + struct vkd3d_shader_dst_param *dst_param; + const uint32_t **ptr = &sm1->ptr; + uint32_t opcode_token; +@@ -1241,6 +1242,17 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str + goto fail; + } + ++ if (opcode_info->vkd3d_opcode == VKD3DSIH_TEXKILL) ++ { ++ vsir_src_count = 1; ++ vsir_dst_count = 0; ++ } ++ else ++ { ++ vsir_src_count = opcode_info->src_count; ++ vsir_dst_count = opcode_info->dst_count; ++ } ++ + vsir_instruction_init(ins, &sm1->p.location, opcode_info->vkd3d_opcode); + ins->flags = (opcode_token & VKD3D_SM1_INSTRUCTION_FLAGS_MASK) >> VKD3D_SM1_INSTRUCTION_FLAGS_SHIFT; + ins->coissue = opcode_token & VKD3D_SM1_COISSUE; +@@ -1248,9 +1260,9 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str + ins->structured = false; + predicated = !!(opcode_token & VKD3D_SM1_INSTRUCTION_PREDICATED); + ins->predicate = predicate = predicated ? vsir_program_get_src_params(program, 1) : NULL; +- ins->dst_count = opcode_info->dst_count; ++ ins->dst_count = vsir_dst_count; + ins->dst = dst_param = vsir_program_get_dst_params(program, ins->dst_count); +- ins->src_count = opcode_info->src_count; ++ ins->src_count = vsir_src_count; + ins->src = src_params = vsir_program_get_src_params(program, ins->src_count); + if ((!predicate && predicated) || (!src_params && ins->src_count) || (!dst_param && ins->dst_count)) + { +@@ -1298,6 +1310,25 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str + shader_sm1_read_immconst(sm1, &p, &src_params[0], VSIR_DIMENSION_VEC4, VKD3D_DATA_INT); + shader_sm1_scan_register(sm1, &dst_param->reg, dst_param->write_mask, true); + } ++ else if (ins->opcode == VKD3DSIH_TEXKILL) ++ { ++ /* TEXKILL, uniquely, encodes its argument as a destination, when it is ++ * semantically a source. Since we have multiple passes which operate ++ * generically on sources or destinations, normalize that. */ ++ const struct vkd3d_shader_register *reg; ++ struct vkd3d_shader_dst_param tmp_dst; ++ ++ reg = &tmp_dst.reg; ++ shader_sm1_read_dst_param(sm1, &p, &tmp_dst); ++ shader_sm1_scan_register(sm1, reg, tmp_dst.write_mask, false); ++ ++ vsir_src_param_init(&src_params[0], reg->type, reg->data_type, reg->idx_count); ++ src_params[0].reg = *reg; ++ src_params[0].swizzle = vsir_swizzle_from_writemask(tmp_dst.write_mask); ++ ++ if (ins->predicate) ++ shader_sm1_read_src_param(sm1, &p, predicate); ++ } + else + { + /* Destination token */ +@@ -1491,7 +1522,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 +1533,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 +1579,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; +@@ -1759,27 +1794,40 @@ static bool is_inconsequential_instr(const struct vkd3d_shader_instruction *ins) static void write_sm1_dst_register(struct vkd3d_bytecode_buffer *buffer, const struct vkd3d_shader_dst_param *reg) { @@ -10344,7 +10819,7 @@ index 58e35cf22e8..b49ef9865db 100644 const struct vkd3d_sm1_opcode_info *info; unsigned int i; uint32_t token; -@@ -1810,13 +1823,10 @@ static void d3dbc_write_instruction(struct d3dbc_compiler *d3dbc, const struct v +@@ -1810,16 +1858,34 @@ static void d3dbc_write_instruction(struct d3dbc_compiler *d3dbc, const struct v for (i = 0; i < ins->src_count; ++i) { @@ -10362,7 +10837,31 @@ index 58e35cf22e8..b49ef9865db 100644 } }; -@@ -1831,6 +1841,7 @@ static void d3dbc_write_vsir_def(struct d3dbc_compiler *d3dbc, const struct vkd3 ++static void d3dbc_write_texkill(struct d3dbc_compiler *d3dbc, const struct vkd3d_shader_instruction *ins) ++{ ++ const struct vkd3d_shader_register *reg = &ins->src[0].reg; ++ struct vkd3d_shader_instruction tmp; ++ struct vkd3d_shader_dst_param dst; ++ ++ /* TEXKILL, uniquely, encodes its argument as a destination, when it is ++ * semantically a source. We store it as a source in vsir, so convert it. */ ++ ++ vsir_dst_param_init(&dst, reg->type, reg->data_type, reg->idx_count); ++ dst.reg = *reg; ++ dst.write_mask = mask_from_swizzle(ins->src[0].swizzle); ++ ++ tmp = *ins; ++ tmp.dst_count = 1; ++ tmp.dst = &dst; ++ tmp.src_count = 0; ++ ++ d3dbc_write_instruction(d3dbc, &tmp); ++} ++ + static void d3dbc_write_vsir_def(struct d3dbc_compiler *d3dbc, const struct vkd3d_shader_instruction *ins) + { + const struct vkd3d_shader_version *version = &d3dbc->program->shader_version; +@@ -1831,6 +1897,7 @@ static void d3dbc_write_vsir_def(struct d3dbc_compiler *d3dbc, const struct vkd3 .reg.type = VKD3DSPR_CONST, .write_mask = VKD3DSP_WRITEMASK_ALL, .reg.idx[0].offset = ins->dst[0].reg.idx[0].offset, @@ -10370,7 +10869,7 @@ index 58e35cf22e8..b49ef9865db 100644 }; token = VKD3D_SM1_OP_DEF; -@@ -1863,6 +1874,7 @@ static void d3dbc_write_vsir_sampler_dcl(struct d3dbc_compiler *d3dbc, +@@ -1863,6 +1930,7 @@ static void d3dbc_write_vsir_sampler_dcl(struct d3dbc_compiler *d3dbc, reg.reg.type = VKD3DSPR_COMBINED_SAMPLER; reg.write_mask = VKD3DSP_WRITEMASK_ALL; reg.reg.idx[0].offset = reg_id; @@ -10378,7 +10877,18 @@ index 58e35cf22e8..b49ef9865db 100644 write_sm1_dst_register(buffer, ®); } -@@ -1938,6 +1950,7 @@ static void d3dbc_write_vsir_instruction(struct d3dbc_compiler *d3dbc, const str +@@ -1922,6 +1990,10 @@ static void d3dbc_write_vsir_instruction(struct d3dbc_compiler *d3dbc, const str + d3dbc_write_vsir_dcl(d3dbc, ins); + break; + ++ case VKD3DSIH_TEXKILL: ++ d3dbc_write_texkill(d3dbc, ins); ++ break; ++ + case VKD3DSIH_ABS: + case VKD3DSIH_ADD: + case VKD3DSIH_CMP: +@@ -1938,11 +2010,11 @@ static void d3dbc_write_vsir_instruction(struct d3dbc_compiler *d3dbc, const str case VKD3DSIH_MAX: case VKD3DSIH_MIN: case VKD3DSIH_MOV: @@ -10386,14 +10896,22 @@ index 58e35cf22e8..b49ef9865db 100644 case VKD3DSIH_MUL: case VKD3DSIH_SINCOS: case VKD3DSIH_SLT: -@@ -1982,6 +1995,7 @@ static void d3dbc_write_semantic_dcl(struct d3dbc_compiler *d3dbc, + case VKD3DSIH_TEX: +- case VKD3DSIH_TEXKILL: + case VKD3DSIH_TEXLDD: + d3dbc_write_instruction(d3dbc, ins); + break; +@@ -1982,8 +2054,9 @@ static void d3dbc_write_semantic_dcl(struct d3dbc_compiler *d3dbc, uint32_t token, usage_idx; bool ret; + 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, ®.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/dxbc.c b/libs/vkd3d/libs/vkd3d-shader/dxbc.c index 81af62f7810..9e3a57132a1 100644 --- a/libs/vkd3d/libs/vkd3d-shader/dxbc.c @@ -10480,10 +10998,46 @@ index 81af62f7810..9e3a57132a1 100644 { FIXME("Multiple patch constant signatures.\n"); diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c -index a10de68008a..ac4828d6f59 100644 +index a10de68008a..775be85334e 100644 --- a/libs/vkd3d/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c -@@ -3911,23 +3911,51 @@ static void sm6_parser_init_signature(struct sm6_parser *sm6, const struct shade +@@ -659,7 +659,8 @@ struct sm6_function_data + struct sm6_handle_data + { + const struct sm6_descriptor_info *d; +- struct vkd3d_shader_register reg; ++ const struct sm6_value *index; ++ bool non_uniform; + }; + + struct sm6_value +@@ -2519,6 +2520,25 @@ static void register_index_address_init(struct vkd3d_shader_register_index *idx, + } + } + ++static void sm6_register_from_handle(struct sm6_parser *sm6, ++ const struct sm6_handle_data *handle, struct vkd3d_shader_register *reg) ++{ ++ vsir_register_init(reg, handle->d->reg_type, handle->d->reg_data_type, 2); ++ reg->dimension = VSIR_DIMENSION_VEC4; ++ reg->idx[0].offset = handle->d->id; ++ register_index_address_init(®->idx[1], handle->index, sm6); ++ reg->non_uniform = handle->non_uniform; ++} ++ ++static void src_param_init_vector_from_handle(struct sm6_parser *sm6, ++ struct vkd3d_shader_src_param *param, const struct sm6_handle_data *handle) ++{ ++ struct vkd3d_shader_register reg; ++ ++ sm6_register_from_handle(sm6, handle, ®); ++ src_param_init_vector_from_reg(param, ®); ++} ++ + static bool instruction_dst_param_init_ssa_scalar(struct vkd3d_shader_instruction *ins, struct sm6_parser *sm6) + { + struct sm6_value *dst = sm6_parser_get_current_value(sm6); +@@ -3911,23 +3931,51 @@ static void sm6_parser_init_signature(struct sm6_parser *sm6, const struct shade } } @@ -10538,7 +11092,191 @@ index a10de68008a..ac4828d6f59 100644 } static const struct sm6_value *sm6_parser_next_function_definition(struct sm6_parser *sm6) -@@ -8550,19 +8578,29 @@ static enum vkd3d_result sm6_parser_metadata_init(struct sm6_parser *sm6, const +@@ -4354,7 +4402,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 +@@ -4760,7 +4808,7 @@ static void sm6_parser_emit_dx_atomic_binop(struct sm6_parser *sm6, enum dx_intr + dst_param_init(&dst_params[0]); + register_init_ssa_scalar(&dst_params[0].reg, dst->type, dst, sm6); + dst_param_init(&dst_params[1]); +- dst_params[1].reg = resource->u.handle.reg; ++ sm6_register_from_handle(sm6, &resource->u.handle, &dst_params[1].reg); + + dst->u.reg = dst_params[0].reg; + } +@@ -4818,7 +4866,7 @@ static void sm6_parser_emit_dx_buffer_update_counter(struct sm6_parser *sm6, enu + vsir_instruction_init(ins, &sm6->p.location, (inc < 0) ? VKD3DSIH_IMM_ATOMIC_CONSUME : VKD3DSIH_IMM_ATOMIC_ALLOC); + if (!(src_params = instruction_src_params_alloc(ins, 1, sm6))) + return; +- src_param_init_vector_from_reg(&src_params[0], &resource->u.handle.reg); ++ src_param_init_vector_from_handle(sm6, &src_params[0], &resource->u.handle); + + instruction_dst_param_init_ssa_scalar(ins, sm6); + } +@@ -4850,9 +4898,9 @@ static void sm6_parser_emit_dx_calculate_lod(struct sm6_parser *sm6, enum dx_int + if (!(src_params = instruction_src_params_alloc(ins, 3, sm6))) + return; + src_param_init_vector_from_reg(&src_params[0], &coord); +- src_params[1].reg = resource->u.handle.reg; ++ sm6_register_from_handle(sm6, &resource->u.handle, &src_params[1].reg); + src_param_init_scalar(&src_params[1], !clamp); +- src_param_init_vector_from_reg(&src_params[2], &sampler->u.handle.reg); ++ src_param_init_vector_from_handle(sm6, &src_params[2], &sampler->u.handle); + + instruction_dst_param_init_ssa_scalar(ins, sm6); + } +@@ -4874,7 +4922,7 @@ static void sm6_parser_emit_dx_cbuffer_load(struct sm6_parser *sm6, enum dx_intr + + if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) + return; +- src_param_init_vector_from_reg(src_param, &buffer->u.handle.reg); ++ src_param_init_vector_from_handle(sm6, src_param, &buffer->u.handle); + /* Differently from other descriptors, constant buffers require an + * additional index, used to index within the constant buffer itself. */ + src_param->reg.idx_count = 3; +@@ -4958,7 +5006,6 @@ static void sm6_parser_emit_dx_create_handle(struct sm6_parser *sm6, enum dx_int + struct vkd3d_shader_instruction *ins = state->ins; + enum vkd3d_shader_descriptor_type type; + const struct sm6_descriptor_info *d; +- struct vkd3d_shader_register *reg; + struct sm6_value *dst; + unsigned int id; + +@@ -4975,13 +5022,8 @@ static void sm6_parser_emit_dx_create_handle(struct sm6_parser *sm6, enum dx_int + dst = sm6_parser_get_current_value(sm6); + dst->value_type = VALUE_TYPE_HANDLE; + dst->u.handle.d = d; +- +- reg = &dst->u.handle.reg; +- vsir_register_init(reg, d->reg_type, d->reg_data_type, 2); +- reg->dimension = VSIR_DIMENSION_VEC4; +- reg->idx[0].offset = id; +- register_index_address_init(®->idx[1], operands[2], sm6); +- reg->non_uniform = !!sm6_value_get_constant_uint(operands[3]); ++ dst->u.handle.index = operands[2]; ++ dst->u.handle.non_uniform = !!sm6_value_get_constant_uint(operands[3]); + + /* NOP is used to flag no instruction emitted. */ + ins->opcode = VKD3DSIH_NOP; +@@ -5256,7 +5298,7 @@ static void sm6_parser_emit_dx_get_dimensions(struct sm6_parser *sm6, enum dx_in + + if (!(src_params = instruction_src_params_alloc(ins, 1 + is_texture, sm6))) + return; +- src_param_init_vector_from_reg(&src_params[is_texture], &resource->u.handle.reg); ++ src_param_init_vector_from_handle(sm6, &src_params[is_texture], &resource->u.handle); + + if (is_texture) + { +@@ -5276,7 +5318,7 @@ static void sm6_parser_emit_dx_get_dimensions(struct sm6_parser *sm6, enum dx_in + + if (!(src_params = instruction_src_params_alloc(ins, 1, sm6))) + return; +- src_param_init_vector_from_reg(&src_params[0], &resource->u.handle.reg); ++ src_param_init_vector_from_handle(sm6, &src_params[0], &resource->u.handle); + src_params[0].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); + + if (!instruction_dst_param_init_temp_vector(ins, sm6)) +@@ -5518,7 +5560,7 @@ static void sm6_parser_emit_dx_raw_buffer_load(struct sm6_parser *sm6, enum dx_i + if (!(src_params = instruction_src_params_alloc(ins, operand_count, sm6))) + return; + src_params_init_from_operands(src_params, &operands[1], operand_count - 1); +- src_param_init_vector_from_reg(&src_params[operand_count - 1], &resource->u.handle.reg); ++ src_param_init_vector_from_handle(sm6, &src_params[operand_count - 1], &resource->u.handle); + + instruction_dst_param_init_ssa_vector(ins, component_count, sm6); + } +@@ -5589,7 +5631,7 @@ static void sm6_parser_emit_dx_raw_buffer_store(struct sm6_parser *sm6, enum dx_ + + dst_param = instruction_dst_params_alloc(ins, 1, sm6); + dst_param_init_with_mask(dst_param, write_mask); +- dst_param->reg = resource->u.handle.reg; ++ sm6_register_from_handle(sm6, &resource->u.handle, &dst_param->reg); + dst_param->reg.alignment = alignment; + } + +@@ -5630,7 +5672,7 @@ static void sm6_parser_emit_dx_buffer_load(struct sm6_parser *sm6, enum dx_intri + vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_OPERANDS, + "Ignoring structure offset for a typed buffer load."); + } +- src_param_init_vector_from_reg(&src_params[1], &resource->u.handle.reg); ++ src_param_init_vector_from_handle(sm6, &src_params[1], &resource->u.handle); + + instruction_dst_param_init_ssa_vector(ins, VKD3D_VEC4_SIZE, sm6); + } +@@ -5699,7 +5741,7 @@ static void sm6_parser_emit_dx_buffer_store(struct sm6_parser *sm6, enum dx_intr + + dst_param = instruction_dst_params_alloc(ins, 1, sm6); + dst_param_init_with_mask(dst_param, write_mask); +- dst_param->reg = resource->u.handle.reg; ++ sm6_register_from_handle(sm6, &resource->u.handle, &dst_param->reg); + } + + static void sm6_parser_emit_dx_get_sample_count(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, +@@ -5741,7 +5783,7 @@ static void sm6_parser_emit_dx_get_sample_pos(struct sm6_parser *sm6, enum dx_in + return; + if (op == DX_TEX2DMS_GET_SAMPLE_POS) + { +- src_param_init_vector_from_reg(&src_params[0], &resource->u.handle.reg); ++ src_param_init_vector_from_handle(sm6, &src_params[0], &resource->u.handle); + src_param_init_from_value(&src_params[1], operands[1]); + } + else +@@ -5845,8 +5887,8 @@ static void sm6_parser_emit_dx_sample(struct sm6_parser *sm6, enum dx_intrinsic_ + } + + src_param_init_vector_from_reg(&src_params[0], &coord); +- src_param_init_vector_from_reg(&src_params[1], &resource->u.handle.reg); +- src_param_init_vector_from_reg(&src_params[2], &sampler->u.handle.reg); ++ src_param_init_vector_from_handle(sm6, &src_params[1], &resource->u.handle); ++ src_param_init_vector_from_handle(sm6, &src_params[2], &sampler->u.handle); + instruction_set_texel_offset(ins, &operands[6], sm6); + + instruction_dst_param_init_ssa_vector(ins, component_count, sm6); +@@ -5914,7 +5956,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; + } + +@@ -6043,8 +6085,8 @@ static void sm6_parser_emit_dx_texture_gather(struct sm6_parser *sm6, enum dx_in + src_param_init_vector_from_reg(&src_params[1], &offset); + else + instruction_set_texel_offset(ins, &operands[6], sm6); +- src_param_init_vector_from_reg(&src_params[1 + extended_offset], &resource->u.handle.reg); +- src_param_init_vector_from_reg(&src_params[2 + extended_offset], &sampler->u.handle.reg); ++ src_param_init_vector_from_handle(sm6, &src_params[1 + extended_offset], &resource->u.handle); ++ src_param_init_vector_from_handle(sm6, &src_params[2 + extended_offset], &sampler->u.handle); + /* Swizzle stored in the sampler parameter is the scalar component index to be gathered. */ + swizzle = sm6_value_get_constant_uint(operands[8]); + if (swizzle >= VKD3D_VEC4_SIZE) +@@ -6096,7 +6138,7 @@ static void sm6_parser_emit_dx_texture_load(struct sm6_parser *sm6, enum dx_intr + if (!(src_params = instruction_src_params_alloc(ins, 2 + is_multisample, sm6))) + return; + src_param_init_vector_from_reg(&src_params[0], &coord); +- src_param_init_vector_from_reg(&src_params[1], &resource->u.handle.reg); ++ src_param_init_vector_from_handle(sm6, &src_params[1], &resource->u.handle); + if (is_multisample) + src_param_init_from_value(&src_params[2], mip_level_or_sample_count); + +@@ -6149,7 +6191,7 @@ static void sm6_parser_emit_dx_texture_store(struct sm6_parser *sm6, enum dx_int + src_param_init_vector_from_reg(&src_params[1], &texel); + + dst_param = instruction_dst_params_alloc(ins, 1, sm6); +- dst_param->reg = resource->u.handle.reg; ++ sm6_register_from_handle(sm6, &resource->u.handle, &dst_param->reg); + dst_param_init_with_mask(dst_param, write_mask); + } + +@@ -8550,19 +8592,29 @@ static enum vkd3d_result sm6_parser_metadata_init(struct sm6_parser *sm6, const return VKD3D_OK; } @@ -10569,7 +11307,7 @@ index a10de68008a..ac4828d6f59 100644 case COMPONENT_TYPE_F32: case COMPONENT_TYPE_SNORMF32: case COMPONENT_TYPE_UNORMF32: -@@ -8577,8 +8615,12 @@ static enum vkd3d_shader_component_type vkd3d_component_type_from_dxil_component +@@ -8577,8 +8629,12 @@ static enum vkd3d_shader_component_type vkd3d_component_type_from_dxil_component } } @@ -10583,7 +11321,7 @@ index a10de68008a..ac4828d6f59 100644 switch (type) { case COMPONENT_TYPE_F16: -@@ -9404,8 +9446,10 @@ static enum vkd3d_result sm6_parser_read_signature(struct sm6_parser *sm6, const +@@ -9404,8 +9460,10 @@ static enum vkd3d_result sm6_parser_read_signature(struct sm6_parser *sm6, const { unsigned int i, j, column_count, operand_count, index; const struct sm6_metadata_node *node, *element_node; @@ -10594,7 +11332,7 @@ index a10de68008a..ac4828d6f59 100644 bool is_register; if (!m) -@@ -9430,6 +9474,7 @@ static enum vkd3d_result sm6_parser_read_signature(struct sm6_parser *sm6, const +@@ -9430,6 +9488,7 @@ static enum vkd3d_result sm6_parser_read_signature(struct sm6_parser *sm6, const return VKD3D_ERROR_OUT_OF_MEMORY; } @@ -10602,7 +11340,7 @@ index a10de68008a..ac4828d6f59 100644 for (i = 0; i < operand_count; ++i) { m = node->operands[i]; -@@ -9490,8 +9535,8 @@ static enum vkd3d_result sm6_parser_read_signature(struct sm6_parser *sm6, const +@@ -9490,8 +9549,8 @@ static enum vkd3d_result sm6_parser_read_signature(struct sm6_parser *sm6, const } e->semantic_name = element_node->operands[1]->u.string_value; @@ -10613,7 +11351,7 @@ index a10de68008a..ac4828d6f59 100644 j = values[3]; e->sysval_semantic = sysval_semantic_from_dxil_semantic_kind(j, tessellator_domain); -@@ -9631,23 +9676,24 @@ static enum vkd3d_result sm6_parser_signatures_init(struct sm6_parser *sm6, cons +@@ -9631,23 +9690,24 @@ static enum vkd3d_result sm6_parser_signatures_init(struct sm6_parser *sm6, cons if (m->u.node->operand_count && (ret = sm6_parser_read_signature(sm6, m->u.node->operands[0], &program->input_signature, tessellator_domain, true)) < 0) @@ -10639,7 +11377,7 @@ index a10de68008a..ac4828d6f59 100644 + if ((ret = sm6_parser_init_input_signature(sm6, &program->input_signature)) < 0) + return ret; + -+ if ((ret = sm6_parser_init_output_signature(sm6, &program->output_signature) < 0)) ++ if ((ret = sm6_parser_init_output_signature(sm6, &program->output_signature)) < 0) + return ret; + + if ((ret = sm6_parser_init_patch_constant_signature(sm6, &program->patch_constant_signature)) < 0) @@ -10647,7 +11385,7 @@ index a10de68008a..ac4828d6f59 100644 return VKD3D_OK; } -@@ -9917,6 +9963,7 @@ static void sm6_parser_gs_properties_init(struct sm6_parser *sm6, const struct s +@@ -9917,6 +9977,7 @@ static void sm6_parser_gs_properties_init(struct sm6_parser *sm6, const struct s { input_primitive = VKD3D_PT_PATCH; patch_vertex_count = i - INPUT_PRIMITIVE_PATCH1 + 1; @@ -10655,7 +11393,7 @@ index a10de68008a..ac4828d6f59 100644 break; } -@@ -9927,6 +9974,7 @@ static void sm6_parser_gs_properties_init(struct sm6_parser *sm6, const struct s +@@ -9927,6 +9988,7 @@ static void sm6_parser_gs_properties_init(struct sm6_parser *sm6, const struct s } sm6_parser_emit_dcl_primitive_topology(sm6, VKD3DSIH_DCL_INPUT_PRIMITIVE, input_primitive, patch_vertex_count); @@ -10663,7 +11401,7 @@ index a10de68008a..ac4828d6f59 100644 sm6->p.program->input_control_point_count = input_control_point_count; i = operands[1]; -@@ -9938,6 +9986,7 @@ static void sm6_parser_gs_properties_init(struct sm6_parser *sm6, const struct s +@@ -9938,6 +10000,7 @@ static void sm6_parser_gs_properties_init(struct sm6_parser *sm6, const struct s "Geometry shader output vertex count %u is invalid.", i); } sm6_parser_emit_dcl_count(sm6, VKD3DSIH_DCL_VERTICES_OUT, i); @@ -10671,7 +11409,7 @@ index a10de68008a..ac4828d6f59 100644 if (operands[2] > 1) { -@@ -9955,6 +10004,7 @@ static void sm6_parser_gs_properties_init(struct sm6_parser *sm6, const struct s +@@ -9955,6 +10018,7 @@ static void sm6_parser_gs_properties_init(struct sm6_parser *sm6, const struct s output_primitive = VKD3D_PT_TRIANGLELIST; } sm6_parser_emit_dcl_primitive_topology(sm6, VKD3DSIH_DCL_OUTPUT_TOPOLOGY, output_primitive, 0); @@ -10679,7 +11417,7 @@ index a10de68008a..ac4828d6f59 100644 i = operands[4]; if (!i || i > MAX_GS_INSTANCE_COUNT) -@@ -10432,9 +10482,6 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, struct vsir_pro +@@ -10432,9 +10496,6 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, struct vsir_pro input_signature = &program->input_signature; output_signature = &program->output_signature; patch_constant_signature = &program->patch_constant_signature; @@ -10689,7 +11427,7 @@ index a10de68008a..ac4828d6f59 100644 program->features = dxbc_desc->features; memset(dxbc_desc, 0, sizeof(*dxbc_desc)); -@@ -10498,18 +10545,6 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, struct vsir_pro +@@ -10498,18 +10559,6 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, struct vsir_pro goto fail; } @@ -10708,7 +11446,7 @@ index a10de68008a..ac4828d6f59 100644 function_count = dxil_block_compute_function_count(&sm6->root_block); if (!(sm6->functions = vkd3d_calloc(function_count, sizeof(*sm6->functions)))) { -@@ -10669,8 +10704,6 @@ int dxil_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t co +@@ -10669,8 +10718,6 @@ int dxil_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t co uint32_t *byte_code = NULL; int ret; @@ -10718,7 +11456,7 @@ index a10de68008a..ac4828d6f59 100644 if ((ret = shader_extract_from_dxbc(&compile_info->source, message_context, compile_info->source_name, &dxbc_desc)) < 0) diff --git a/libs/vkd3d/libs/vkd3d-shader/fx.c b/libs/vkd3d/libs/vkd3d-shader/fx.c -index bd7e7b420db..debcb261811 100644 +index bd7e7b420db..c93f01039ef 100644 --- a/libs/vkd3d/libs/vkd3d-shader/fx.c +++ b/libs/vkd3d/libs/vkd3d-shader/fx.c @@ -25,6 +25,49 @@ static inline size_t put_u32_unaligned(struct vkd3d_bytecode_buffer *buffer, uin @@ -11334,7 +12072,42 @@ index bd7e7b420db..debcb261811 100644 return true; default: return false; -@@ -2262,7 +2762,8 @@ static void resolve_fx_4_state_block_values(struct hlsl_ir_var *var, struct hlsl +@@ -1920,6 +2420,23 @@ static inline enum hlsl_base_type hlsl_type_from_fx_type(enum state_property_com + } + } + ++static inline bool hlsl_type_state_compatible(struct hlsl_type *lhs, enum hlsl_base_type rhs) ++{ ++ if (!hlsl_is_numeric_type(lhs)) ++ return false; ++ switch (lhs->e.numeric.type) ++ { ++ case HLSL_TYPE_INT: ++ case HLSL_TYPE_UINT: ++ return rhs == HLSL_TYPE_INT || rhs == HLSL_TYPE_UINT; ++ ++ default: ++ return lhs->e.numeric.type == rhs; ++ } ++ ++ vkd3d_unreachable(); ++} ++ + static const struct rhs_named_value filter_values[] = + { + { "MIN_MAG_MIP_POINT", 0x00 }, +@@ -2164,9 +2681,9 @@ static void resolve_fx_4_state_block_values(struct hlsl_ir_var *var, struct hlsl + struct replace_state_context replace_context; + const struct fx_4_state *state = NULL; + struct hlsl_type *state_type = NULL; +- struct hlsl_ir_node *node, *cast; + struct hlsl_ctx *ctx = fx->ctx; + enum hlsl_base_type base_type; ++ struct hlsl_ir_node *node; + unsigned int i; + + if (type->class == HLSL_CLASS_BLEND_STATE && ctx->profile->major_version == 5) +@@ -2262,7 +2779,8 @@ static void resolve_fx_4_state_block_values(struct hlsl_ir_var *var, struct hlsl struct hlsl_ir_constant *c = hlsl_ir_constant(node); struct hlsl_type *data_type = c->node.data_type; @@ -11344,7 +12117,50 @@ index bd7e7b420db..debcb261811 100644 { if (c->value.u[0].u != 0) hlsl_error(ctx, &ctx->location, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, -@@ -2395,7 +2896,15 @@ static unsigned int decompose_fx_4_state_function_call(struct hlsl_ir_var *var, +@@ -2302,9 +2820,15 @@ static void resolve_fx_4_state_block_values(struct hlsl_ir_var *var, struct hlsl + if (state_type) + { + node = entry->args->node; +- if (!(cast = hlsl_new_cast(ctx, node, state_type, &var->loc))) +- return; +- list_add_after(&node->entry, &cast->entry); ++ if (state->type == FX_UINT8 || !hlsl_type_state_compatible(node->data_type, base_type)) ++ { ++ struct hlsl_ir_node *cast; ++ ++ if (!(cast = hlsl_new_cast(ctx, node, state_type, &var->loc))) ++ return; ++ list_add_after(&node->entry, &cast->entry); ++ node = cast; ++ } + + /* FX_UINT8 values are using 32-bits in the binary. Mask higher 24 bits for those. */ + if (state->type == FX_UINT8) +@@ -2313,15 +2837,18 @@ static void resolve_fx_4_state_block_values(struct hlsl_ir_var *var, struct hlsl + + if (!(mask = hlsl_new_uint_constant(ctx, 0xff, &var->loc))) + return; +- list_add_after(&cast->entry, &mask->entry); ++ list_add_after(&node->entry, &mask->entry); + +- if (!(cast = hlsl_new_binary_expr(ctx, HLSL_OP2_BIT_AND, cast, mask))) ++ if (!(node = hlsl_new_binary_expr(ctx, HLSL_OP2_BIT_AND, node, mask))) + return; +- list_add_after(&mask->entry, &cast->entry); ++ list_add_after(&mask->entry, &node->entry); + } + +- hlsl_src_remove(entry->args); +- hlsl_src_from_node(entry->args, cast); ++ if (node != entry->args->node) ++ { ++ hlsl_src_remove(entry->args); ++ hlsl_src_from_node(entry->args, node); ++ } + + hlsl_run_const_passes(ctx, entry->instrs); + } +@@ -2395,7 +2922,15 @@ static unsigned int decompose_fx_4_state_function_call(struct hlsl_ir_var *var, static unsigned int decompose_fx_4_state_block_expand_array(struct hlsl_ir_var *var, struct hlsl_state_block *block, unsigned int entry_index, struct fx_write_context *fx) { @@ -11361,7 +12177,7 @@ index bd7e7b420db..debcb261811 100644 const struct hlsl_type *type = hlsl_get_multiarray_element_type(var->data_type); struct hlsl_state_block_entry *entry = block->entries[entry_index]; static const unsigned int array_size = 8; -@@ -2914,6 +3423,11 @@ struct fx_parser +@@ -2914,6 +3449,11 @@ struct fx_parser uint32_t buffer_count; uint32_t object_count; uint32_t group_count; @@ -11373,7 +12189,7 @@ index bd7e7b420db..debcb261811 100644 bool failed; }; -@@ -2965,13 +3479,6 @@ static void VKD3D_PRINTF_FUNC(3, 4) fx_parser_error(struct fx_parser *parser, en +@@ -2965,13 +3505,6 @@ static void VKD3D_PRINTF_FUNC(3, 4) fx_parser_error(struct fx_parser *parser, en parser->failed = true; } @@ -11387,7 +12203,7 @@ index bd7e7b420db..debcb261811 100644 static const void *fx_parser_get_unstructured_ptr(struct fx_parser *parser, uint32_t offset, size_t size) { const uint8_t *ptr = parser->unstructured.ptr; -@@ -2986,40 +3493,27 @@ static const void *fx_parser_get_unstructured_ptr(struct fx_parser *parser, uint +@@ -2986,40 +3519,27 @@ static const void *fx_parser_get_unstructured_ptr(struct fx_parser *parser, uint return &ptr[offset]; } @@ -11441,7 +12257,7 @@ index bd7e7b420db..debcb261811 100644 } static void parse_fx_start_indent(struct fx_parser *parser) -@@ -3037,46 +3531,787 @@ static void parse_fx_print_indent(struct fx_parser *parser) +@@ -3037,23 +3557,764 @@ static void parse_fx_print_indent(struct fx_parser *parser) vkd3d_string_buffer_printf(&parser->buffer, "%*s", 4 * parser->indent, ""); } @@ -11462,37 +12278,16 @@ index bd7e7b420db..debcb261811 100644 + if (!ptr) { - union hlsl_constant_value_component value; -- -- fx_parser_read_unstructured(parser, &value, offset, sizeof(uint32_t)); -- -- if (base_type == FX_4_NUMERIC_TYPE_FLOAT) -- vkd3d_string_buffer_printf(&parser->buffer, "%f", value.f); -- else if (base_type == FX_4_NUMERIC_TYPE_INT) -- vkd3d_string_buffer_printf(&parser->buffer, "%d", value.i); -- else if (base_type == FX_4_NUMERIC_TYPE_UINT) -- vkd3d_string_buffer_printf(&parser->buffer, "%u", value.u); -- else if (base_type == FX_4_NUMERIC_TYPE_BOOL) -- vkd3d_string_buffer_printf(&parser->buffer, "%s", value.u ? "true" : "false" ); -- else -- vkd3d_string_buffer_printf(&parser->buffer, "%#x", value.u); -- -- if (i < comp_count - 1) -- vkd3d_string_buffer_printf(&parser->buffer, ", "); -- -- offset += sizeof(uint32_t); + parser->failed = true; + return ""; - } --} ++ } --static void fx_4_parse_string_initializer(struct fx_parser *parser, uint32_t offset) --{ -- const char *str = fx_4_get_string(parser, offset); -- vkd3d_string_buffer_printf(&parser->buffer, "\"%s\"", str); +- fx_parser_read_unstructured(parser, &value, offset, sizeof(uint32_t)); + return ptr; - } ++} --static void fx_parse_fx_4_annotations(struct fx_parser *parser) +- if (base_type == FX_4_NUMERIC_TYPE_FLOAT) +- vkd3d_string_buffer_printf(&parser->buffer, "%f", value.f); +static unsigned int fx_get_fx_2_type_size(struct fx_parser *parser, uint32_t *offset) +{ + uint32_t element_count, member_count, class, columns, rows; @@ -12235,33 +13030,10 @@ index bd7e7b420db..debcb261811 100644 + + if (base_type == FX_4_NUMERIC_TYPE_FLOAT) + vkd3d_string_buffer_print_f32(&parser->buffer, value.f); -+ else if (base_type == FX_4_NUMERIC_TYPE_INT) -+ vkd3d_string_buffer_printf(&parser->buffer, "%d", value.i); -+ else if (base_type == FX_4_NUMERIC_TYPE_UINT) -+ vkd3d_string_buffer_printf(&parser->buffer, "%u", value.u); -+ else if (base_type == FX_4_NUMERIC_TYPE_BOOL) -+ vkd3d_string_buffer_printf(&parser->buffer, "%s", value.u ? "true" : "false" ); -+ else -+ vkd3d_string_buffer_printf(&parser->buffer, "%#x", value.u); -+ -+ if (i < comp_count - 1) -+ vkd3d_string_buffer_printf(&parser->buffer, ", "); -+ -+ offset += sizeof(uint32_t); -+ } -+} -+ -+static void fx_4_parse_string_initializer(struct fx_parser *parser, uint32_t offset) -+{ -+ const char *str = fx_4_get_string(parser, offset); -+ vkd3d_string_buffer_printf(&parser->buffer, "\"%s\"", str); -+} -+ -+static void fx_parse_fx_4_annotations(struct fx_parser *parser) - { - struct fx_4_annotation - { -@@ -3228,17 +4463,15 @@ static void fx_parse_buffers(struct fx_parser *parser) + else if (base_type == FX_4_NUMERIC_TYPE_INT) + vkd3d_string_buffer_printf(&parser->buffer, "%d", value.i); + else if (base_type == FX_4_NUMERIC_TYPE_UINT) +@@ -3228,17 +4489,15 @@ static void fx_parse_buffers(struct fx_parser *parser) static void fx_4_parse_shader_blob(struct fx_parser *parser, unsigned int object_type, const struct fx_5_shader *shader) { @@ -12284,7 +13056,7 @@ index bd7e7b420db..debcb261811 100644 fx_parser_read_unstructured(parser, &data_size, shader->offset, sizeof(data_size)); if (data_size) -@@ -3247,42 +4480,8 @@ static void fx_4_parse_shader_blob(struct fx_parser *parser, unsigned int object +@@ -3247,42 +4506,8 @@ static void fx_4_parse_shader_blob(struct fx_parser *parser, unsigned int object if (!data) return; @@ -12328,7 +13100,7 @@ index bd7e7b420db..debcb261811 100644 if (object_type == FX_4_OBJECT_TYPE_GEOMETRY_SHADER_SO && shader->sodecl[0]) { vkd3d_string_buffer_printf(&parser->buffer, "\n/* Stream output declaration: \"%s\" */", -@@ -3299,8 +4498,6 @@ static void fx_4_parse_shader_blob(struct fx_parser *parser, unsigned int object +@@ -3299,8 +4524,6 @@ static void fx_4_parse_shader_blob(struct fx_parser *parser, unsigned int object if (shader->sodecl_count) vkd3d_string_buffer_printf(&parser->buffer, "\n/* Rasterized stream %u */", shader->rast_stream); } @@ -12337,7 +13109,7 @@ index bd7e7b420db..debcb261811 100644 } static void fx_4_parse_shader_initializer(struct fx_parser *parser, unsigned int object_type) -@@ -3366,16 +4563,298 @@ static int fx_4_state_id_compare(const void *a, const void *b) +@@ -3366,16 +4589,298 @@ static int fx_4_state_id_compare(const void *a, const void *b) return id - state->id; } @@ -12643,7 +13415,7 @@ index bd7e7b420db..debcb261811 100644 struct { uint32_t name; -@@ -3390,7 +4869,7 @@ static void fx_4_parse_state_object_initializer(struct fx_parser *parser, uint32 +@@ -3390,7 +4895,7 @@ static void fx_4_parse_state_object_initializer(struct fx_parser *parser, uint32 float f; }; } value; @@ -12652,7 +13424,7 @@ index bd7e7b420db..debcb261811 100644 { [FX_BOOL] = "bool", [FX_FLOAT] = "float", -@@ -3496,6 +4975,19 @@ static void fx_4_parse_state_object_initializer(struct fx_parser *parser, uint32 +@@ -3496,6 +5001,19 @@ static void fx_4_parse_state_object_initializer(struct fx_parser *parser, uint32 vkd3d_string_buffer_printf(&parser->buffer, "%s[%s]", fx_4_get_string(parser, index.name), fx_4_get_string(parser, index.index)); break; @@ -12672,7 +13444,7 @@ index bd7e7b420db..debcb261811 100644 case FX_4_ASSIGNMENT_INLINE_SHADER: case FX_5_ASSIGNMENT_INLINE_SHADER: { -@@ -3544,12 +5036,14 @@ static void fx_4_parse_object_initializer(struct fx_parser *parser, const struct +@@ -3544,12 +5062,14 @@ static void fx_4_parse_object_initializer(struct fx_parser *parser, const struct }; unsigned int i, element_count, count; uint32_t value; @@ -12687,7 +13459,7 @@ index bd7e7b420db..debcb261811 100644 for (i = 0; i < element_count; ++i) { switch (type->typeinfo) -@@ -3565,9 +5059,21 @@ static void fx_4_parse_object_initializer(struct fx_parser *parser, const struct +@@ -3565,9 +5085,21 @@ static void fx_4_parse_object_initializer(struct fx_parser *parser, const struct case FX_4_OBJECT_TYPE_SAMPLER_STATE: count = fx_parser_read_u32(parser); @@ -12709,7 +13481,7 @@ index bd7e7b420db..debcb261811 100644 break; case FX_4_OBJECT_TYPE_PIXEL_SHADER: case FX_4_OBJECT_TYPE_VERTEX_SHADER: -@@ -3586,7 +5092,7 @@ static void fx_4_parse_object_initializer(struct fx_parser *parser, const struct +@@ -3586,7 +5118,7 @@ static void fx_4_parse_object_initializer(struct fx_parser *parser, const struct "Parsing object type %u is not implemented.", type->typeinfo); return; } @@ -12718,7 +13490,7 @@ index bd7e7b420db..debcb261811 100644 } vkd3d_string_buffer_printf(&parser->buffer, "}"); } -@@ -3719,7 +5225,7 @@ static void fx_parse_groups(struct fx_parser *parser) +@@ -3719,7 +5251,7 @@ static void fx_parse_groups(struct fx_parser *parser) } } @@ -12727,7 +13499,7 @@ index bd7e7b420db..debcb261811 100644 { struct fx_4_header { -@@ -3752,8 +5258,9 @@ static int fx_4_parse(struct fx_parser *parser) +@@ -3752,8 +5284,9 @@ static int fx_4_parse(struct fx_parser *parser) if (parser->end - parser->ptr < header.unstructured_size) { @@ -12739,7 +13511,7 @@ index bd7e7b420db..debcb261811 100644 } parser->unstructured.ptr = parser->ptr; -@@ -3766,11 +5273,9 @@ static int fx_4_parse(struct fx_parser *parser) +@@ -3766,11 +5299,9 @@ static int fx_4_parse(struct fx_parser *parser) for (i = 0; i < header.technique_count; ++i) fx_parse_fx_4_technique(parser); @@ -12752,7 +13524,7 @@ index bd7e7b420db..debcb261811 100644 { struct fx_5_header { -@@ -3808,8 +5313,9 @@ static int fx_5_parse(struct fx_parser *parser) +@@ -3808,8 +5339,9 @@ static int fx_5_parse(struct fx_parser *parser) if (parser->end - parser->ptr < header.unstructured_size) { @@ -12764,7 +13536,7 @@ index bd7e7b420db..debcb261811 100644 } parser->unstructured.ptr = parser->ptr; -@@ -3821,48 +5327,62 @@ static int fx_5_parse(struct fx_parser *parser) +@@ -3821,48 +5353,62 @@ static int fx_5_parse(struct fx_parser *parser) fx_4_parse_objects(parser); fx_parse_groups(parser); @@ -12844,7 +13616,7 @@ index bd7e7b420db..debcb261811 100644 + return VKD3D_OK; } diff --git a/libs/vkd3d/libs/vkd3d-shader/glsl.c b/libs/vkd3d/libs/vkd3d-shader/glsl.c -index ab6604bd703..a87ade5e467 100644 +index ab6604bd703..e4497b9ac5b 100644 --- a/libs/vkd3d/libs/vkd3d-shader/glsl.c +++ b/libs/vkd3d/libs/vkd3d-shader/glsl.c @@ -64,7 +64,6 @@ struct vkd3d_glsl_generator @@ -12902,7 +13674,149 @@ index ab6604bd703..a87ade5e467 100644 glsl_src_cleanup(&r, &gen->string_buffers); } -@@ -1298,7 +1296,7 @@ static void shader_glsl_print_sysval_name(struct vkd3d_string_buffer *buffer, st +@@ -789,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; +@@ -812,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 + { +@@ -905,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; +@@ -935,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 + { +@@ -1055,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; +@@ -1074,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 + { +@@ -1082,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))) +@@ -1105,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); +@@ -1116,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; + +@@ -1134,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 + { +@@ -1142,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))) +@@ -1161,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)"); + +@@ -1298,7 +1292,7 @@ static void shader_glsl_print_sysval_name(struct vkd3d_string_buffer *buffer, st vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, "Internal compiler error: Unhandled SV_POSITION index %u.", idx); if (version->type == VKD3D_SHADER_TYPE_PIXEL) @@ -12911,7 +13825,7 @@ index ab6604bd703..a87ade5e467 100644 else vkd3d_string_buffer_printf(buffer, "gl_Position"); break; -@@ -1658,6 +1656,9 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen, +@@ -1658,6 +1652,9 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen, case VKD3DSIH_SWITCH: shader_glsl_switch(gen, ins); break; @@ -12921,7 +13835,84 @@ index ab6604bd703..a87ade5e467 100644 default: shader_glsl_unhandled(gen, ins); break; -@@ -2078,7 +2079,7 @@ static void shader_glsl_generate_sampler_declaration(struct vkd3d_glsl_generator +@@ -1734,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) +@@ -1791,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; +@@ -1961,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; +@@ -2019,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; +@@ -2078,7 +2077,7 @@ static void shader_glsl_generate_sampler_declaration(struct vkd3d_glsl_generator static void shader_glsl_generate_descriptor_declarations(struct vkd3d_glsl_generator *gen) { const struct vkd3d_shader_scan_combined_resource_sampler_info *sampler_info = gen->combined_sampler_info; @@ -12930,7 +13921,7 @@ index ab6604bd703..a87ade5e467 100644 const struct vkd3d_shader_descriptor_info1 *descriptor; unsigned int i; -@@ -2429,7 +2430,6 @@ static void shader_glsl_init_limits(struct vkd3d_glsl_generator *gen, const stru +@@ -2429,7 +2428,6 @@ static void shader_glsl_init_limits(struct vkd3d_glsl_generator *gen, const stru static void vkd3d_glsl_generator_init(struct vkd3d_glsl_generator *gen, struct vsir_program *program, const struct vkd3d_shader_compile_info *compile_info, @@ -12938,7 +13929,7 @@ index ab6604bd703..a87ade5e467 100644 const struct vkd3d_shader_scan_combined_resource_sampler_info *combined_sampler_info, struct vkd3d_shader_message_context *message_context) { -@@ -2453,12 +2453,10 @@ static void vkd3d_glsl_generator_init(struct vkd3d_glsl_generator *gen, +@@ -2453,12 +2451,10 @@ static void vkd3d_glsl_generator_init(struct vkd3d_glsl_generator *gen, gen->interface_info = vkd3d_find_struct(compile_info->next, INTERFACE_INFO); gen->offset_info = vkd3d_find_struct(compile_info->next, DESCRIPTOR_OFFSET_INFO); @@ -12951,7 +13942,7 @@ index ab6604bd703..a87ade5e467 100644 const struct vkd3d_shader_scan_combined_resource_sampler_info *combined_sampler_info, const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context) -@@ -2470,9 +2468,10 @@ int glsl_compile(struct vsir_program *program, uint64_t config_flags, +@@ -2470,9 +2466,10 @@ int glsl_compile(struct vsir_program *program, uint64_t config_flags, return ret; VKD3D_ASSERT(program->normalisation_level == VSIR_NORMALISED_SM6); @@ -12964,7 +13955,7 @@ index ab6604bd703..a87ade5e467 100644 vkd3d_glsl_generator_cleanup(&generator); diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c -index 41586550203..d1d20b7384c 100644 +index 41586550203..a6b46474812 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c @@ -234,6 +234,33 @@ unsigned int hlsl_get_multiarray_size(const struct hlsl_type *type) @@ -13047,7 +14038,36 @@ index 41586550203..d1d20b7384c 100644 /* Only intended to be used for derefs (after copies have been lowered to components or vectors) or * resources, since for both their data types span across a single regset. */ static enum hlsl_regset type_get_regset(const struct hlsl_type *type) -@@ -484,6 +550,8 @@ static struct hlsl_type *hlsl_new_type(struct hlsl_ctx *ctx, const char *name, e +@@ -321,6 +387,9 @@ static enum hlsl_regset type_get_regset(const struct hlsl_type *type) + case HLSL_CLASS_UAV: + return HLSL_REGSET_UAVS; + ++ case HLSL_CLASS_STREAM_OUTPUT: ++ return HLSL_REGSET_STREAM_OUTPUTS; ++ + default: + break; + } +@@ -427,6 +496,10 @@ static void hlsl_type_calculate_reg_size(struct hlsl_ctx *ctx, struct hlsl_type + type->reg_size[HLSL_REGSET_UAVS] = 1; + break; + ++ case HLSL_CLASS_STREAM_OUTPUT: ++ type->reg_size[HLSL_REGSET_STREAM_OUTPUTS] = 1; ++ break; ++ + case HLSL_CLASS_DEPTH_STENCIL_STATE: + case HLSL_CLASS_DEPTH_STENCIL_VIEW: + case HLSL_CLASS_EFFECT_GROUP: +@@ -445,7 +518,6 @@ static void hlsl_type_calculate_reg_size(struct hlsl_ctx *ctx, struct hlsl_type + case HLSL_CLASS_HULL_SHADER: + case HLSL_CLASS_GEOMETRY_SHADER: + case HLSL_CLASS_BLEND_STATE: +- case HLSL_CLASS_STREAM_OUTPUT: + case HLSL_CLASS_NULL: + break; + } +@@ -484,6 +556,8 @@ static struct hlsl_type *hlsl_new_type(struct hlsl_ctx *ctx, const char *name, e { struct hlsl_type *type; @@ -13056,7 +14076,39 @@ index 41586550203..d1d20b7384c 100644 if (!(type = hlsl_alloc(ctx, sizeof(*type)))) return NULL; if (!(type->name = hlsl_strdup(ctx, name))) -@@ -704,8 +772,7 @@ unsigned int hlsl_type_get_component_offset(struct hlsl_ctx *ctx, struct hlsl_ty +@@ -523,6 +597,7 @@ static bool type_is_single_component(const struct hlsl_type *type) + case HLSL_CLASS_HULL_SHADER: + case HLSL_CLASS_GEOMETRY_SHADER: + case HLSL_CLASS_BLEND_STATE: ++ case HLSL_CLASS_STREAM_OUTPUT: + case HLSL_CLASS_NULL: + return true; + +@@ -537,7 +612,6 @@ static bool type_is_single_component(const struct hlsl_type *type) + case HLSL_CLASS_PASS: + case HLSL_CLASS_TECHNIQUE: + case HLSL_CLASS_VOID: +- case HLSL_CLASS_STREAM_OUTPUT: + break; + } + vkd3d_unreachable(); +@@ -683,6 +757,7 @@ unsigned int hlsl_type_get_component_offset(struct hlsl_ctx *ctx, struct hlsl_ty + case HLSL_CLASS_HULL_SHADER: + case HLSL_CLASS_GEOMETRY_SHADER: + case HLSL_CLASS_BLEND_STATE: ++ case HLSL_CLASS_STREAM_OUTPUT: + VKD3D_ASSERT(idx == 0); + break; + +@@ -694,7 +769,6 @@ unsigned int hlsl_type_get_component_offset(struct hlsl_ctx *ctx, struct hlsl_ty + case HLSL_CLASS_SCALAR: + case HLSL_CLASS_CONSTANT_BUFFER: + case HLSL_CLASS_NULL: +- case HLSL_CLASS_STREAM_OUTPUT: + vkd3d_unreachable(); + } + type = next_type; +@@ -704,8 +778,7 @@ unsigned int hlsl_type_get_component_offset(struct hlsl_ctx *ctx, struct hlsl_ty return offset[*regset]; } @@ -13066,7 +14118,7 @@ index 41586550203..d1d20b7384c 100644 { deref->var = var; deref->path_len = path_len; -@@ -763,7 +830,7 @@ bool hlsl_init_deref_from_index_chain(struct hlsl_ctx *ctx, struct hlsl_deref *d +@@ -763,7 +836,7 @@ bool hlsl_init_deref_from_index_chain(struct hlsl_ctx *ctx, struct hlsl_deref *d } load = hlsl_ir_load(ptr); @@ -13075,7 +14127,7 @@ index 41586550203..d1d20b7384c 100644 return false; for (i = 0; i < load->src.path_len; ++i) -@@ -832,7 +899,7 @@ static bool init_deref_from_component_index(struct hlsl_ctx *ctx, struct hlsl_bl +@@ -832,7 +905,7 @@ static bool init_deref_from_component_index(struct hlsl_ctx *ctx, struct hlsl_bl ++path_len; } @@ -13084,7 +14136,7 @@ index 41586550203..d1d20b7384c 100644 return false; deref_path_len = 0; -@@ -845,13 +912,7 @@ static bool init_deref_from_component_index(struct hlsl_ctx *ctx, struct hlsl_bl +@@ -845,13 +918,7 @@ static bool init_deref_from_component_index(struct hlsl_ctx *ctx, struct hlsl_bl { unsigned int next_index = traverse_path_from_component_index(ctx, &path_type, &path_index); @@ -13099,7 +14151,15 @@ index 41586550203..d1d20b7384c 100644 hlsl_src_from_node(&deref->path[deref_path_len++], c); } -@@ -1104,6 +1165,7 @@ unsigned int hlsl_type_component_count(const struct hlsl_type *type) +@@ -923,6 +990,7 @@ struct hlsl_type *hlsl_new_stream_output_type(struct hlsl_ctx *ctx, + type->class = HLSL_CLASS_STREAM_OUTPUT; + type->e.so.so_type = so_type; + type->e.so.type = data_type; ++ hlsl_type_calculate_reg_size(ctx, type); + + list_add_tail(&ctx->types, &type->entry); + +@@ -1104,6 +1172,7 @@ unsigned int hlsl_type_component_count(const struct hlsl_type *type) case HLSL_CLASS_HULL_SHADER: case HLSL_CLASS_GEOMETRY_SHADER: case HLSL_CLASS_BLEND_STATE: @@ -13107,7 +14167,7 @@ index 41586550203..d1d20b7384c 100644 case HLSL_CLASS_NULL: return 1; -@@ -1111,7 +1173,6 @@ unsigned int hlsl_type_component_count(const struct hlsl_type *type) +@@ -1111,7 +1180,6 @@ unsigned int hlsl_type_component_count(const struct hlsl_type *type) case HLSL_CLASS_PASS: case HLSL_CLASS_TECHNIQUE: case HLSL_CLASS_VOID: @@ -13115,7 +14175,18 @@ index 41586550203..d1d20b7384c 100644 break; } -@@ -1324,15 +1385,16 @@ bool hlsl_scope_add_type(struct hlsl_scope *scope, struct hlsl_type *type) +@@ -1305,6 +1373,10 @@ struct hlsl_type *hlsl_type_clone(struct hlsl_ctx *ctx, struct hlsl_type *old, + type->e.version = old->e.version; + break; + ++ case HLSL_CLASS_STREAM_OUTPUT: ++ type->e.so.so_type = old->e.so.so_type; ++ break; ++ + default: + break; + } +@@ -1324,15 +1396,16 @@ bool hlsl_scope_add_type(struct hlsl_scope *scope, struct hlsl_type *type) return true; } @@ -13139,7 +14210,7 @@ index 41586550203..d1d20b7384c 100644 } struct hlsl_ir_node *hlsl_new_copy(struct hlsl_ctx *ctx, struct hlsl_ir_node *node) -@@ -1429,7 +1491,7 @@ bool hlsl_copy_deref(struct hlsl_ctx *ctx, struct hlsl_deref *deref, const struc +@@ -1429,7 +1502,7 @@ bool hlsl_copy_deref(struct hlsl_ctx *ctx, struct hlsl_deref *deref, const struc VKD3D_ASSERT(!hlsl_deref_is_lowered(other)); @@ -13148,7 +14219,7 @@ index 41586550203..d1d20b7384c 100644 return false; for (i = 0; i < deref->path_len; ++i) -@@ -1491,7 +1553,7 @@ struct hlsl_ir_node *hlsl_new_store_index(struct hlsl_ctx *ctx, const struct hls +@@ -1491,7 +1564,7 @@ struct hlsl_ir_node *hlsl_new_store_index(struct hlsl_ctx *ctx, const struct hls return NULL; init_node(&store->node, HLSL_IR_STORE, NULL, loc); @@ -13157,7 +14228,7 @@ index 41586550203..d1d20b7384c 100644 { vkd3d_free(store); return NULL; -@@ -1510,22 +1572,73 @@ struct hlsl_ir_node *hlsl_new_store_index(struct hlsl_ctx *ctx, const struct hls +@@ -1510,22 +1583,73 @@ struct hlsl_ir_node *hlsl_new_store_index(struct hlsl_ctx *ctx, const struct hls return &store->node; } @@ -13236,7 +14307,7 @@ index 41586550203..d1d20b7384c 100644 } hlsl_block_add_block(block, &comp_path_block); hlsl_src_from_node(&store->rhs, rhs); -@@ -1534,8 +1647,6 @@ bool hlsl_new_store_component(struct hlsl_ctx *ctx, struct hlsl_block *block, +@@ -1534,8 +1658,6 @@ bool hlsl_new_store_component(struct hlsl_ctx *ctx, struct hlsl_block *block, store->writemask = (1 << rhs->data_type->e.numeric.dimx) - 1; hlsl_block_add_instr(block, &store->node); @@ -13245,7 +14316,7 @@ index 41586550203..d1d20b7384c 100644 } struct hlsl_ir_node *hlsl_new_call(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *decl, -@@ -1575,7 +1686,7 @@ struct hlsl_ir_node *hlsl_new_bool_constant(struct hlsl_ctx *ctx, bool b, const +@@ -1575,7 +1697,7 @@ struct hlsl_ir_node *hlsl_new_bool_constant(struct hlsl_ctx *ctx, bool b, const return hlsl_new_constant(ctx, hlsl_get_scalar_type(ctx, HLSL_TYPE_BOOL), &value, loc); } @@ -13254,7 +14325,7 @@ index 41586550203..d1d20b7384c 100644 const struct vkd3d_shader_location *loc) { struct hlsl_constant_value value; -@@ -1584,7 +1695,14 @@ struct hlsl_ir_node *hlsl_new_float_constant(struct hlsl_ctx *ctx, float f, +@@ -1584,7 +1706,14 @@ struct hlsl_ir_node *hlsl_new_float_constant(struct hlsl_ctx *ctx, float f, return hlsl_new_constant(ctx, hlsl_get_scalar_type(ctx, HLSL_TYPE_FLOAT), &value, loc); } @@ -13270,7 +14341,7 @@ index 41586550203..d1d20b7384c 100644 { struct hlsl_constant_value value; -@@ -1592,6 +1710,12 @@ struct hlsl_ir_node *hlsl_new_int_constant(struct hlsl_ctx *ctx, int32_t n, cons +@@ -1592,6 +1721,12 @@ struct hlsl_ir_node *hlsl_new_int_constant(struct hlsl_ctx *ctx, int32_t n, cons return hlsl_new_constant(ctx, hlsl_get_scalar_type(ctx, HLSL_TYPE_INT), &value, loc); } @@ -13283,7 +14354,7 @@ index 41586550203..d1d20b7384c 100644 struct hlsl_ir_node *hlsl_new_uint_constant(struct hlsl_ctx *ctx, unsigned int n, const struct vkd3d_shader_location *loc) { -@@ -1601,6 +1725,12 @@ struct hlsl_ir_node *hlsl_new_uint_constant(struct hlsl_ctx *ctx, unsigned int n +@@ -1601,6 +1736,12 @@ struct hlsl_ir_node *hlsl_new_uint_constant(struct hlsl_ctx *ctx, unsigned int n return hlsl_new_constant(ctx, hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), &value, loc); } @@ -13296,7 +14367,7 @@ index 41586550203..d1d20b7384c 100644 struct hlsl_ir_node *hlsl_new_string_constant(struct hlsl_ctx *ctx, const char *str, const struct vkd3d_shader_location *loc) { -@@ -1625,7 +1755,7 @@ struct hlsl_ir_node *hlsl_new_null_constant(struct hlsl_ctx *ctx, const struct v +@@ -1625,7 +1766,7 @@ struct hlsl_ir_node *hlsl_new_null_constant(struct hlsl_ctx *ctx, const struct v return hlsl_new_constant(ctx, ctx->builtin_types.null, &value, loc); } @@ -13305,7 +14376,7 @@ index 41586550203..d1d20b7384c 100644 struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS], struct hlsl_type *data_type, const struct vkd3d_shader_location *loc) { -@@ -1641,7 +1771,14 @@ struct hlsl_ir_node *hlsl_new_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op +@@ -1641,7 +1782,14 @@ struct hlsl_ir_node *hlsl_new_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op return &expr->node; } @@ -13321,7 +14392,7 @@ index 41586550203..d1d20b7384c 100644 struct hlsl_ir_node *arg, const struct vkd3d_shader_location *loc) { struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {arg}; -@@ -1649,6 +1786,12 @@ struct hlsl_ir_node *hlsl_new_unary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr +@@ -1649,6 +1797,12 @@ struct hlsl_ir_node *hlsl_new_unary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr return hlsl_new_expr(ctx, op, operands, arg->data_type, loc); } @@ -13334,7 +14405,7 @@ index 41586550203..d1d20b7384c 100644 struct hlsl_ir_node *hlsl_new_binary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2) { -@@ -1657,16 +1800,37 @@ struct hlsl_ir_node *hlsl_new_binary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_exp +@@ -1657,16 +1811,37 @@ struct hlsl_ir_node *hlsl_new_binary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_exp return hlsl_new_expr(ctx, op, operands, arg1->data_type, &arg1->loc); } @@ -13374,7 +14445,7 @@ index 41586550203..d1d20b7384c 100644 static struct hlsl_ir_node *hlsl_new_error_expr(struct hlsl_ctx *ctx) { static const struct vkd3d_shader_location loc = {.source_name = ""}; -@@ -1694,6 +1858,23 @@ struct hlsl_ir_node *hlsl_new_if(struct hlsl_ctx *ctx, struct hlsl_ir_node *cond +@@ -1694,6 +1869,23 @@ struct hlsl_ir_node *hlsl_new_if(struct hlsl_ctx *ctx, struct hlsl_ir_node *cond return &iff->node; } @@ -13398,7 +14469,7 @@ index 41586550203..d1d20b7384c 100644 struct hlsl_ir_switch_case *hlsl_new_switch_case(struct hlsl_ctx *ctx, unsigned int value, bool is_default, struct hlsl_block *body, const struct vkd3d_shader_location *loc) { -@@ -1745,7 +1926,7 @@ struct hlsl_ir_load *hlsl_new_load_index(struct hlsl_ctx *ctx, const struct hlsl +@@ -1745,7 +1937,7 @@ struct hlsl_ir_load *hlsl_new_load_index(struct hlsl_ctx *ctx, const struct hlsl return NULL; init_node(&load->node, HLSL_IR_LOAD, type, loc); @@ -13407,7 +14478,7 @@ index 41586550203..d1d20b7384c 100644 { vkd3d_free(load); return NULL; -@@ -1758,6 +1939,14 @@ struct hlsl_ir_load *hlsl_new_load_index(struct hlsl_ctx *ctx, const struct hlsl +@@ -1758,6 +1950,14 @@ struct hlsl_ir_load *hlsl_new_load_index(struct hlsl_ctx *ctx, const struct hlsl return load; } @@ -13422,7 +14493,7 @@ index 41586550203..d1d20b7384c 100644 struct hlsl_ir_load *hlsl_new_load_parent(struct hlsl_ctx *ctx, const struct hlsl_deref *deref, const struct vkd3d_shader_location *loc) { -@@ -1780,17 +1969,27 @@ struct hlsl_ir_load *hlsl_new_var_load(struct hlsl_ctx *ctx, struct hlsl_ir_var +@@ -1780,17 +1980,27 @@ struct hlsl_ir_load *hlsl_new_var_load(struct hlsl_ctx *ctx, struct hlsl_ir_var return hlsl_new_load_index(ctx, &var_deref, NULL, loc); } @@ -13454,7 +14525,7 @@ index 41586550203..d1d20b7384c 100644 type = hlsl_deref_get_type(ctx, deref); comp_type = hlsl_type_get_component_type(ctx, type, comp); -@@ -1799,7 +1998,8 @@ struct hlsl_ir_node *hlsl_new_load_component(struct hlsl_ctx *ctx, struct hlsl_b +@@ -1799,7 +2009,8 @@ struct hlsl_ir_node *hlsl_new_load_component(struct hlsl_ctx *ctx, struct hlsl_b if (!init_deref_from_component_index(ctx, &comp_path_block, &load->src, deref, comp, loc)) { vkd3d_free(load); @@ -13464,7 +14535,7 @@ index 41586550203..d1d20b7384c 100644 } hlsl_block_add_block(block, &comp_path_block); -@@ -1808,7 +2008,7 @@ struct hlsl_ir_node *hlsl_new_load_component(struct hlsl_ctx *ctx, struct hlsl_b +@@ -1808,7 +2019,7 @@ struct hlsl_ir_node *hlsl_new_load_component(struct hlsl_ctx *ctx, struct hlsl_b return &load->node; } @@ -13473,29 +14544,40 @@ index 41586550203..d1d20b7384c 100644 const struct hlsl_resource_load_params *params, const struct vkd3d_shader_location *loc) { struct hlsl_ir_resource_load *load; -@@ -1847,7 +2047,13 @@ struct hlsl_ir_node *hlsl_new_resource_load(struct hlsl_ctx *ctx, +@@ -1847,26 +2058,45 @@ struct hlsl_ir_node *hlsl_new_resource_load(struct hlsl_ctx *ctx, return &load->node; } -struct hlsl_ir_node *hlsl_new_resource_store(struct hlsl_ctx *ctx, const struct hlsl_deref *resource, +- struct hlsl_ir_node *coords, struct hlsl_ir_node *value, const struct vkd3d_shader_location *loc) +struct hlsl_ir_node *hlsl_block_add_resource_load(struct hlsl_ctx *ctx, struct hlsl_block *block, + const struct hlsl_resource_load_params *params, const struct vkd3d_shader_location *loc) +{ + return append_new_instr(ctx, block, hlsl_new_resource_load(ctx, params, loc)); +} + -+static struct hlsl_ir_node *hlsl_new_resource_store(struct hlsl_ctx *ctx, const struct hlsl_deref *resource, - struct hlsl_ir_node *coords, struct hlsl_ir_node *value, const struct vkd3d_shader_location *loc) ++static struct hlsl_ir_node *hlsl_new_resource_store(struct hlsl_ctx *ctx, enum hlsl_resource_store_type type, ++ const struct hlsl_deref *resource, struct hlsl_ir_node *coords, struct hlsl_ir_node *value, ++ const struct vkd3d_shader_location *loc) { struct hlsl_ir_resource_store *store; -@@ -1861,12 +2067,21 @@ struct hlsl_ir_node *hlsl_new_resource_store(struct hlsl_ctx *ctx, const struct + + if (!(store = hlsl_alloc(ctx, sizeof(*store)))) + return NULL; + init_node(&store->node, HLSL_IR_RESOURCE_STORE, NULL, loc); ++ store->store_type = type; ++ + hlsl_copy_deref(ctx, &store->resource, resource); + hlsl_src_from_node(&store->coords, coords); + hlsl_src_from_node(&store->value, value); return &store->node; } -+void hlsl_block_add_resource_store(struct hlsl_ctx *ctx, struct hlsl_block *block, const struct hlsl_deref *resource, -+ struct hlsl_ir_node *coords, struct hlsl_ir_node *value, const struct vkd3d_shader_location *loc) ++void hlsl_block_add_resource_store(struct hlsl_ctx *ctx, struct hlsl_block *block, ++ enum hlsl_resource_store_type type, const struct hlsl_deref *resource, struct hlsl_ir_node *coords, ++ struct hlsl_ir_node *value, const struct vkd3d_shader_location *loc) +{ -+ append_new_instr(ctx, block, hlsl_new_resource_store(ctx, resource, coords, value, loc)); ++ append_new_instr(ctx, block, hlsl_new_resource_store(ctx, type, resource, coords, value, loc)); +} + struct hlsl_ir_node *hlsl_new_swizzle(struct hlsl_ctx *ctx, uint32_t s, unsigned int component_count, @@ -13510,7 +14592,7 @@ index 41586550203..d1d20b7384c 100644 VKD3D_ASSERT(val->data_type->class <= HLSL_CLASS_VECTOR); if (!(swizzle = hlsl_alloc(ctx, sizeof(*swizzle)))) -@@ -1882,6 +2097,12 @@ struct hlsl_ir_node *hlsl_new_swizzle(struct hlsl_ctx *ctx, uint32_t s, unsigned +@@ -1882,6 +2112,12 @@ struct hlsl_ir_node *hlsl_new_swizzle(struct hlsl_ctx *ctx, uint32_t s, unsigned return &swizzle->node; } @@ -13523,7 +14605,7 @@ index 41586550203..d1d20b7384c 100644 struct hlsl_ir_node *hlsl_new_matrix_swizzle(struct hlsl_ctx *ctx, struct hlsl_matrix_swizzle s, unsigned int component_count, struct hlsl_ir_node *val, const struct vkd3d_shader_location *loc) { -@@ -2078,7 +2299,7 @@ bool hlsl_index_chain_has_resource_access(struct hlsl_ir_index *index) +@@ -2078,7 +2314,7 @@ bool hlsl_index_chain_has_resource_access(struct hlsl_ir_index *index) return false; } @@ -13532,7 +14614,7 @@ index 41586550203..d1d20b7384c 100644 struct hlsl_ir_node *idx, const struct vkd3d_shader_location *loc) { struct hlsl_type *type = val->data_type; -@@ -2100,7 +2321,13 @@ struct hlsl_ir_node *hlsl_new_index(struct hlsl_ctx *ctx, struct hlsl_ir_node *v +@@ -2100,7 +2336,13 @@ struct hlsl_ir_node *hlsl_new_index(struct hlsl_ctx *ctx, struct hlsl_ir_node *v return &index->node; } @@ -13547,7 +14629,7 @@ index 41586550203..d1d20b7384c 100644 struct hlsl_ir_node *condition, const struct vkd3d_shader_location *loc) { struct hlsl_ir_jump *jump; -@@ -2113,7 +2340,13 @@ struct hlsl_ir_node *hlsl_new_jump(struct hlsl_ctx *ctx, enum hlsl_ir_jump_type +@@ -2113,7 +2355,13 @@ struct hlsl_ir_node *hlsl_new_jump(struct hlsl_ctx *ctx, enum hlsl_ir_jump_type return &jump->node; } @@ -13562,7 +14644,7 @@ index 41586550203..d1d20b7384c 100644 struct hlsl_block *block, enum hlsl_loop_unroll_type unroll_type, unsigned int unroll_limit, const struct vkd3d_shader_location *loc) { -@@ -2134,6 +2367,18 @@ struct hlsl_ir_node *hlsl_new_loop(struct hlsl_ctx *ctx, struct hlsl_block *iter +@@ -2134,6 +2382,18 @@ struct hlsl_ir_node *hlsl_new_loop(struct hlsl_ctx *ctx, struct hlsl_block *iter return &loop->node; } @@ -13581,7 +14663,7 @@ index 41586550203..d1d20b7384c 100644 struct clone_instr_map { struct -@@ -2203,7 +2448,7 @@ static bool clone_deref(struct hlsl_ctx *ctx, struct clone_instr_map *map, +@@ -2203,7 +2463,7 @@ static bool clone_deref(struct hlsl_ctx *ctx, struct clone_instr_map *map, VKD3D_ASSERT(!hlsl_deref_is_lowered(src)); @@ -13590,7 +14672,15 @@ index 41586550203..d1d20b7384c 100644 return false; for (i = 0; i < src->path_len; ++i) -@@ -2650,8 +2895,8 @@ struct hlsl_ir_function_decl *hlsl_new_func_decl(struct hlsl_ctx *ctx, +@@ -2344,6 +2604,7 @@ static struct hlsl_ir_node *clone_resource_store(struct hlsl_ctx *ctx, + if (!(dst = hlsl_alloc(ctx, sizeof(*dst)))) + return NULL; + init_node(&dst->node, HLSL_IR_RESOURCE_STORE, NULL, &src->node.loc); ++ dst->store_type = src->store_type; + if (!clone_deref(ctx, map, &dst->resource, &src->resource)) + { + vkd3d_free(dst); +@@ -2650,8 +2911,8 @@ struct hlsl_ir_function_decl *hlsl_new_func_decl(struct hlsl_ctx *ctx, struct hlsl_type *return_type, const struct hlsl_func_parameters *parameters, const struct hlsl_semantic *semantic, const struct vkd3d_shader_location *loc) { @@ -13600,7 +14690,7 @@ index 41586550203..d1d20b7384c 100644 if (!(decl = hlsl_alloc(ctx, sizeof(*decl)))) return NULL; -@@ -2679,9 +2924,7 @@ struct hlsl_ir_function_decl *hlsl_new_func_decl(struct hlsl_ctx *ctx, +@@ -2679,9 +2940,7 @@ struct hlsl_ir_function_decl *hlsl_new_func_decl(struct hlsl_ctx *ctx, return decl; hlsl_block_add_instr(&decl->body, constant); @@ -13611,7 +14701,7 @@ index 41586550203..d1d20b7384c 100644 return decl; } -@@ -2796,6 +3039,7 @@ static void hlsl_dump_type(struct vkd3d_string_buffer *buffer, const struct hlsl +@@ -2796,6 +3055,7 @@ static void hlsl_dump_type(struct vkd3d_string_buffer *buffer, const struct hlsl [HLSL_TYPE_HALF] = "half", [HLSL_TYPE_DOUBLE] = "double", [HLSL_TYPE_INT] = "int", @@ -13619,7 +14709,7 @@ index 41586550203..d1d20b7384c 100644 [HLSL_TYPE_UINT] = "uint", [HLSL_TYPE_BOOL] = "bool", }; -@@ -3040,6 +3284,16 @@ struct vkd3d_string_buffer *hlsl_modifiers_to_string(struct hlsl_ctx *ctx, uint3 +@@ -3040,6 +3300,16 @@ struct vkd3d_string_buffer *hlsl_modifiers_to_string(struct hlsl_ctx *ctx, uint3 vkd3d_string_buffer_printf(string, "row_major "); if (modifiers & HLSL_MODIFIER_COLUMN_MAJOR) vkd3d_string_buffer_printf(string, "column_major "); @@ -13636,7 +14726,7 @@ index 41586550203..d1d20b7384c 100644 if ((modifiers & (HLSL_STORAGE_IN | HLSL_STORAGE_OUT)) == (HLSL_STORAGE_IN | HLSL_STORAGE_OUT)) vkd3d_string_buffer_printf(string, "inout "); else if (modifiers & HLSL_STORAGE_IN) -@@ -3263,6 +3517,7 @@ static void dump_ir_constant(struct vkd3d_string_buffer *buffer, const struct hl +@@ -3263,6 +3533,7 @@ static void dump_ir_constant(struct vkd3d_string_buffer *buffer, const struct hl vkd3d_string_buffer_printf(buffer, "%d ", value->i); break; @@ -13644,7 +14734,39 @@ index 41586550203..d1d20b7384c 100644 case HLSL_TYPE_UINT: vkd3d_string_buffer_printf(buffer, "%u ", value->u); break; -@@ -4289,17 +4544,17 @@ static void declare_predefined_types(struct hlsl_ctx *ctx) +@@ -3465,12 +3736,26 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru + + static void dump_ir_resource_store(struct vkd3d_string_buffer *buffer, const struct hlsl_ir_resource_store *store) + { +- vkd3d_string_buffer_printf(buffer, "store_resource(resource = "); ++ static const char *const type_names[] = ++ { ++ [HLSL_RESOURCE_STORE] = "store_resource", ++ [HLSL_RESOURCE_STREAM_APPEND] = "stream_append", ++ [HLSL_RESOURCE_STREAM_RESTART] = "stream_restart", ++ }; ++ ++ VKD3D_ASSERT(store->store_type < ARRAY_SIZE(type_names)); ++ vkd3d_string_buffer_printf(buffer, "%s(resource = ", type_names[store->store_type]); + dump_deref(buffer, &store->resource); +- vkd3d_string_buffer_printf(buffer, ", coords = "); +- dump_src(buffer, &store->coords); +- vkd3d_string_buffer_printf(buffer, ", value = "); +- dump_src(buffer, &store->value); ++ if (store->coords.node) ++ { ++ vkd3d_string_buffer_printf(buffer, ", coords = "); ++ dump_src(buffer, &store->coords); ++ } ++ if (store->value.node) ++ { ++ vkd3d_string_buffer_printf(buffer, ", value = "); ++ dump_src(buffer, &store->value); ++ } + vkd3d_string_buffer_printf(buffer, ")"); + } + +@@ -4289,17 +4574,17 @@ static void declare_predefined_types(struct hlsl_ctx *ctx) static const char * const names[] = { @@ -13669,7 +14791,7 @@ index 41586550203..d1d20b7384c 100644 static const char *const sampler_names[] = { -@@ -4390,11 +4645,6 @@ static void declare_predefined_types(struct hlsl_ctx *ctx) +@@ -4390,11 +4675,6 @@ static void declare_predefined_types(struct hlsl_ctx *ctx) n_variants = ARRAY_SIZE(variants_int); break; @@ -13681,16 +14803,17 @@ index 41586550203..d1d20b7384c 100644 default: n_variants = 0; variants = NULL; -@@ -4577,6 +4827,8 @@ static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const struct vkd3d_shader_compil +@@ -4577,6 +4857,9 @@ static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const struct vkd3d_shader_compil ctx->output_primitive = 0; ctx->partitioning = 0; ctx->input_control_point_count = UINT_MAX; + ctx->max_vertex_count = 0; + ctx->input_primitive_type = VKD3D_PT_UNDEFINED; ++ ctx->output_topology_type = VKD3D_PT_UNDEFINED; return true; } -@@ -4742,6 +4994,7 @@ int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d +@@ -4742,6 +5025,7 @@ int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d if (target_type == VKD3D_SHADER_TARGET_SPIRV_BINARY || target_type == VKD3D_SHADER_TARGET_SPIRV_TEXT @@ -13699,7 +14822,7 @@ index 41586550203..d1d20b7384c 100644 { uint64_t config_flags = vkd3d_shader_init_config_flags(); diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h -index f614e12036e..fafa5740963 100644 +index f614e12036e..8cb805a2e66 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h @@ -103,6 +103,7 @@ enum hlsl_base_type @@ -13710,7 +14833,17 @@ index f614e12036e..fafa5740963 100644 HLSL_TYPE_BOOL, HLSL_TYPE_LAST_SCALAR = HLSL_TYPE_BOOL, }; -@@ -416,6 +417,11 @@ struct hlsl_attribute +@@ -140,7 +141,8 @@ enum hlsl_regset + HLSL_REGSET_SAMPLERS, + HLSL_REGSET_TEXTURES, + HLSL_REGSET_UAVS, +- HLSL_REGSET_LAST_OBJECT = HLSL_REGSET_UAVS, ++ HLSL_REGSET_STREAM_OUTPUTS, ++ HLSL_REGSET_LAST_OBJECT = HLSL_REGSET_STREAM_OUTPUTS, + HLSL_REGSET_NUMERIC, + HLSL_REGSET_LAST = HLSL_REGSET_NUMERIC, + }; +@@ -416,6 +418,11 @@ struct hlsl_attribute #define HLSL_STORAGE_ANNOTATION 0x00080000 #define HLSL_MODIFIER_UNORM 0x00100000 #define HLSL_MODIFIER_SNORM 0x00200000 @@ -13722,7 +14855,7 @@ index f614e12036e..fafa5740963 100644 #define HLSL_TYPE_MODIFIERS_MASK (HLSL_MODIFIER_PRECISE | HLSL_MODIFIER_VOLATILE | \ HLSL_MODIFIER_CONST | HLSL_MODIFIER_ROW_MAJOR | \ -@@ -426,6 +432,9 @@ struct hlsl_attribute +@@ -426,6 +433,9 @@ struct hlsl_attribute #define HLSL_MODIFIERS_MAJORITY_MASK (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR) @@ -13732,7 +14865,7 @@ index f614e12036e..fafa5740963 100644 #define HLSL_ARRAY_ELEMENTS_COUNT_IMPLICIT 0 /* Reservation of a register and/or an offset for objects inside constant buffers, to be used as a -@@ -482,6 +491,9 @@ struct hlsl_ir_var +@@ -482,6 +492,9 @@ struct hlsl_ir_var union hlsl_constant_value_component number; } *default_values; @@ -13742,7 +14875,25 @@ index f614e12036e..fafa5740963 100644 /* A dynamic array containing the state block on the variable's declaration, if any. * An array variable may contain multiple state blocks. * A technique pass will always contain one. -@@ -1143,6 +1155,7 @@ struct hlsl_ctx +@@ -882,9 +895,17 @@ struct hlsl_ir_resource_load + enum hlsl_sampler_dim sampling_dim; + }; + ++enum hlsl_resource_store_type ++{ ++ HLSL_RESOURCE_STORE, ++ HLSL_RESOURCE_STREAM_APPEND, ++ HLSL_RESOURCE_STREAM_RESTART, ++}; ++ + struct hlsl_ir_resource_store + { + struct hlsl_ir_node node; ++ enum hlsl_resource_store_type store_type; + struct hlsl_deref resource; + struct hlsl_src coords, value; + }; +@@ -1143,6 +1164,7 @@ struct hlsl_ctx struct hlsl_constant_register { uint32_t index; @@ -13750,7 +14901,7 @@ index f614e12036e..fafa5740963 100644 struct hlsl_vec4 value; struct vkd3d_shader_location loc; } *regs; -@@ -1180,10 +1193,18 @@ struct hlsl_ctx +@@ -1180,10 +1202,20 @@ struct hlsl_ctx unsigned int input_control_point_count; struct hlsl_type *input_control_point_type; @@ -13765,11 +14916,13 @@ index f614e12036e..fafa5740963 100644 + unsigned int max_vertex_count; + /* The input primitive type of a geometry shader. */ + enum vkd3d_primitive_type input_primitive_type; ++ /* The output topology type of a geometry shader. */ ++ enum vkd3d_primitive_type output_topology_type; + /* In some cases we generate opcodes by parsing an HLSL function and then * invoking it. If not NULL, this field is the name of the function that we * are currently parsing, "mangled" with an internal prefix to avoid -@@ -1454,6 +1475,11 @@ static inline bool hlsl_is_numeric_type(const struct hlsl_type *type) +@@ -1454,6 +1486,11 @@ static inline bool hlsl_is_numeric_type(const struct hlsl_type *type) return type->class <= HLSL_CLASS_LAST_NUMERIC; } @@ -13781,7 +14934,7 @@ index f614e12036e..fafa5740963 100644 static inline unsigned int hlsl_sampler_dim_count(enum hlsl_sampler_dim dim) { switch (dim) -@@ -1502,6 +1528,52 @@ struct hlsl_ir_node *hlsl_add_conditional(struct hlsl_ctx *ctx, struct hlsl_bloc +@@ -1502,6 +1539,53 @@ struct hlsl_ir_node *hlsl_add_conditional(struct hlsl_ctx *ctx, struct hlsl_bloc void hlsl_add_function(struct hlsl_ctx *ctx, char *name, struct hlsl_ir_function_decl *decl); void hlsl_add_var(struct hlsl_ctx *ctx, struct hlsl_ir_var *decl); @@ -13811,8 +14964,9 @@ index f614e12036e..fafa5740963 100644 + unsigned int unroll_limit, const struct vkd3d_shader_location *loc); +struct hlsl_ir_node *hlsl_block_add_resource_load(struct hlsl_ctx *ctx, struct hlsl_block *block, + const struct hlsl_resource_load_params *params, const struct vkd3d_shader_location *loc); -+void hlsl_block_add_resource_store(struct hlsl_ctx *ctx, struct hlsl_block *block, const struct hlsl_deref *resource, -+ struct hlsl_ir_node *coords, struct hlsl_ir_node *value, const struct vkd3d_shader_location *loc); ++void hlsl_block_add_resource_store(struct hlsl_ctx *ctx, struct hlsl_block *block, ++ enum hlsl_resource_store_type type, const struct hlsl_deref *resource, struct hlsl_ir_node *coords, ++ struct hlsl_ir_node *value, const struct vkd3d_shader_location *loc); +struct hlsl_ir_node *hlsl_block_add_simple_load(struct hlsl_ctx *ctx, struct hlsl_block *block, + struct hlsl_ir_var *var, const struct vkd3d_shader_location *loc); +void hlsl_block_add_simple_store(struct hlsl_ctx *ctx, struct hlsl_block *block, @@ -13834,7 +14988,7 @@ index f614e12036e..fafa5740963 100644 void hlsl_block_cleanup(struct hlsl_block *block); bool hlsl_clone_block(struct hlsl_ctx *ctx, struct hlsl_block *dst_block, const struct hlsl_block *src_block); -@@ -1524,6 +1596,7 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry +@@ -1524,6 +1608,7 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry enum vkd3d_shader_target_type target_type, struct vkd3d_shader_code *out); int hlsl_emit_effect_binary(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out); @@ -13842,7 +14996,7 @@ index f614e12036e..fafa5740963 100644 bool hlsl_init_deref_from_index_chain(struct hlsl_ctx *ctx, struct hlsl_deref *deref, struct hlsl_ir_node *chain); bool hlsl_copy_deref(struct hlsl_ctx *ctx, struct hlsl_deref *deref, const struct hlsl_deref *other); -@@ -1573,19 +1646,11 @@ struct hlsl_ir_node *hlsl_new_cast(struct hlsl_ctx *ctx, struct hlsl_ir_node *no +@@ -1573,19 +1658,11 @@ struct hlsl_ir_node *hlsl_new_cast(struct hlsl_ctx *ctx, struct hlsl_ir_node *no struct hlsl_ir_node *hlsl_new_constant(struct hlsl_ctx *ctx, struct hlsl_type *type, const struct hlsl_constant_value *value, const struct vkd3d_shader_location *loc); struct hlsl_ir_node *hlsl_new_copy(struct hlsl_ctx *ctx, struct hlsl_ir_node *node); @@ -13862,7 +15016,7 @@ index f614e12036e..fafa5740963 100644 struct hlsl_type *hlsl_new_stream_output_type(struct hlsl_ctx *ctx, enum hlsl_so_object_type so_type, struct hlsl_type *type); struct hlsl_ir_node *hlsl_new_ternary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, -@@ -1599,16 +1664,12 @@ struct hlsl_ir_load *hlsl_new_load_index(struct hlsl_ctx *ctx, const struct hlsl +@@ -1599,16 +1676,12 @@ struct hlsl_ir_load *hlsl_new_load_index(struct hlsl_ctx *ctx, const struct hlsl struct hlsl_ir_node *idx, const struct vkd3d_shader_location *loc); struct hlsl_ir_load *hlsl_new_load_parent(struct hlsl_ctx *ctx, const struct hlsl_deref *deref, const struct vkd3d_shader_location *loc); @@ -13879,7 +15033,7 @@ index f614e12036e..fafa5740963 100644 bool hlsl_index_is_noncontiguous(struct hlsl_ir_index *index); bool hlsl_index_is_resource_access(struct hlsl_ir_index *index); -@@ -1617,20 +1678,11 @@ bool hlsl_index_chain_has_resource_access(struct hlsl_ir_index *index); +@@ -1617,20 +1690,11 @@ bool hlsl_index_chain_has_resource_access(struct hlsl_ir_index *index); struct hlsl_ir_node *hlsl_new_compile(struct hlsl_ctx *ctx, enum hlsl_compile_type compile_type, const char *profile_name, struct hlsl_ir_node **args, unsigned int args_count, struct hlsl_block *args_instrs, const struct vkd3d_shader_location *loc); @@ -13900,7 +15054,7 @@ index f614e12036e..fafa5740963 100644 struct hlsl_type *hlsl_new_struct_type(struct hlsl_ctx *ctx, const char *name, struct hlsl_struct_field *fields, size_t field_count); struct hlsl_ir_node *hlsl_new_swizzle(struct hlsl_ctx *ctx, uint32_t s, unsigned int components, -@@ -1653,8 +1705,6 @@ struct hlsl_type *hlsl_new_cb_type(struct hlsl_ctx *ctx, struct hlsl_type *forma +@@ -1653,8 +1717,6 @@ struct hlsl_type *hlsl_new_cb_type(struct hlsl_ctx *ctx, struct hlsl_type *forma struct hlsl_ir_node *hlsl_new_uint_constant(struct hlsl_ctx *ctx, unsigned int n, const struct vkd3d_shader_location *loc); struct hlsl_ir_node *hlsl_new_null_constant(struct hlsl_ctx *ctx, const struct vkd3d_shader_location *loc); @@ -13909,7 +15063,7 @@ index f614e12036e..fafa5740963 100644 struct hlsl_ir_var *hlsl_new_var(struct hlsl_ctx *ctx, const char *name, struct hlsl_type *type, const struct vkd3d_shader_location *loc, const struct hlsl_semantic *semantic, uint32_t modifiers, const struct hlsl_reg_reservation *reg_reservation); -@@ -1677,6 +1727,8 @@ void hlsl_pop_scope(struct hlsl_ctx *ctx); +@@ -1677,6 +1739,8 @@ void hlsl_pop_scope(struct hlsl_ctx *ctx); bool hlsl_scope_add_type(struct hlsl_scope *scope, struct hlsl_type *type); @@ -13918,7 +15072,7 @@ index f614e12036e..fafa5740963 100644 struct hlsl_type *hlsl_type_clone(struct hlsl_ctx *ctx, struct hlsl_type *old, unsigned int default_majority, uint32_t modifiers); unsigned int hlsl_type_component_count(const struct hlsl_type *type); -@@ -1685,13 +1737,17 @@ struct hlsl_type *hlsl_type_get_component_type(struct hlsl_ctx *ctx, struct hlsl +@@ -1685,13 +1749,17 @@ struct hlsl_type *hlsl_type_get_component_type(struct hlsl_ctx *ctx, struct hlsl unsigned int index); unsigned int hlsl_type_get_component_offset(struct hlsl_ctx *ctx, struct hlsl_type *type, unsigned int index, enum hlsl_regset *regset); @@ -13936,7 +15090,7 @@ index f614e12036e..fafa5740963 100644 unsigned int hlsl_type_get_sm4_offset(const struct hlsl_type *type, unsigned int offset); bool hlsl_types_are_equal(const struct hlsl_type *t1, const struct hlsl_type *t2); -@@ -1700,6 +1756,8 @@ void hlsl_calculate_buffer_offsets(struct hlsl_ctx *ctx); +@@ -1700,6 +1768,8 @@ void hlsl_calculate_buffer_offsets(struct hlsl_ctx *ctx); const struct hlsl_type *hlsl_get_multiarray_element_type(const struct hlsl_type *type); unsigned int hlsl_get_multiarray_size(const struct hlsl_type *type); @@ -13976,7 +15130,7 @@ index 605a9abaa93..d9fd43b5e78 100644 typedef {return KW_TYPEDEF; } unsigned {return KW_UNSIGNED; } diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y -index 7afc9274c2e..ff3d58da8f4 100644 +index 7afc9274c2e..702fd30bda3 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y @@ -351,7 +351,6 @@ static struct hlsl_ir_node *add_cast(struct hlsl_ctx *ctx, struct hlsl_block *bl @@ -14300,7 +15454,33 @@ index 7afc9274c2e..ff3d58da8f4 100644 return true; } -@@ -1144,31 +1082,34 @@ static bool gen_struct_fields(struct hlsl_ctx *ctx, struct parse_fields *fields, +@@ -1059,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) + { +@@ -1144,31 +1096,34 @@ static bool gen_struct_fields(struct hlsl_ctx *ctx, struct parse_fields *fields, return true; } @@ -14344,7 +15524,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 } static bool add_typedef(struct hlsl_ctx *ctx, struct hlsl_type *const orig_type, struct list *list) -@@ -1239,6 +1180,14 @@ static bool add_typedef(struct hlsl_ctx *ctx, struct hlsl_type *const orig_type, +@@ -1239,6 +1194,14 @@ static bool add_typedef(struct hlsl_ctx *ctx, struct hlsl_type *const orig_type, return true; } @@ -14359,7 +15539,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 static void initialize_var_components(struct hlsl_ctx *ctx, struct hlsl_block *instrs, struct hlsl_ir_var *dst, unsigned int *store_index, struct hlsl_ir_node *src, bool is_default_values_initializer); -@@ -1273,6 +1222,9 @@ static bool add_func_parameter(struct hlsl_ctx *ctx, struct hlsl_func_parameters +@@ -1273,6 +1236,9 @@ static bool add_func_parameter(struct hlsl_ctx *ctx, struct hlsl_func_parameters hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, "Output parameter '%s' has a default value.", param->name); @@ -14369,7 +15549,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 if (!(var = hlsl_new_var(ctx, param->name, param->type, loc, ¶m->semantic, param->modifiers, ¶m->reg_reservation))) return false; -@@ -1289,9 +1241,7 @@ static bool add_func_parameter(struct hlsl_ctx *ctx, struct hlsl_func_parameters +@@ -1289,9 +1255,7 @@ static bool add_func_parameter(struct hlsl_ctx *ctx, struct hlsl_func_parameters if (!param->initializer.braces) { @@ -14380,7 +15560,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 param->initializer.args[0] = node_from_block(param->initializer.instrs); } -@@ -1517,7 +1467,11 @@ static enum hlsl_base_type expr_common_base_type(enum hlsl_base_type t1, enum hl +@@ -1517,7 +1481,11 @@ static enum hlsl_base_type expr_common_base_type(enum hlsl_base_type t1, enum hl return HLSL_TYPE_FLOAT; if (t1 == HLSL_TYPE_UINT || t2 == HLSL_TYPE_UINT) return HLSL_TYPE_UINT; @@ -14393,7 +15573,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 } static bool expr_common_shape(struct hlsl_ctx *ctx, struct hlsl_type *t1, struct hlsl_type *t2, -@@ -1600,15 +1554,12 @@ static struct hlsl_ir_node *add_expr(struct hlsl_ctx *ctx, struct hlsl_block *bl +@@ -1600,15 +1568,12 @@ static struct hlsl_ir_node *add_expr(struct hlsl_ctx *ctx, struct hlsl_block *bl enum hlsl_ir_expr_op op, struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS], struct hlsl_type *type, const struct vkd3d_shader_location *loc) { @@ -14409,7 +15589,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 struct hlsl_ir_var *var; scalar_type = hlsl_get_scalar_type(ctx, type->e.numeric.type); -@@ -1620,58 +1571,24 @@ static struct hlsl_ir_node *add_expr(struct hlsl_ctx *ctx, struct hlsl_block *bl +@@ -1620,58 +1585,24 @@ static struct hlsl_ir_node *add_expr(struct hlsl_ctx *ctx, struct hlsl_block *bl for (i = 0; i < type->e.numeric.dimy * type->e.numeric.dimx; ++i) { struct hlsl_ir_node *value, *cell_operands[HLSL_MAX_OPERANDS] = { NULL }; @@ -14472,7 +15652,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 } static void check_integer_type(struct hlsl_ctx *ctx, const struct hlsl_ir_node *instr) -@@ -1679,7 +1596,7 @@ static void check_integer_type(struct hlsl_ctx *ctx, const struct hlsl_ir_node * +@@ -1679,7 +1610,7 @@ static void check_integer_type(struct hlsl_ctx *ctx, const struct hlsl_ir_node * const struct hlsl_type *type = instr->data_type; struct vkd3d_string_buffer *string; @@ -14481,7 +15661,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 return; if ((string = hlsl_type_to_string(ctx, type))) -@@ -1721,10 +1638,7 @@ static struct hlsl_ir_node *add_unary_logical_expr(struct hlsl_ctx *ctx, struct +@@ -1721,10 +1652,7 @@ static struct hlsl_ir_node *add_unary_logical_expr(struct hlsl_ctx *ctx, struct bool_type = hlsl_get_numeric_type(ctx, arg->data_type->class, HLSL_TYPE_BOOL, arg->data_type->e.numeric.dimx, arg->data_type->e.numeric.dimy); @@ -14493,7 +15673,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 return add_expr(ctx, block, op, args, bool_type, loc); } -@@ -1754,12 +1668,8 @@ static struct hlsl_ir_node *add_binary_arithmetic_expr(struct hlsl_ctx *ctx, str +@@ -1754,12 +1682,8 @@ static struct hlsl_ir_node *add_binary_arithmetic_expr(struct hlsl_ctx *ctx, str return block->value; } @@ -14508,7 +15688,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 return add_expr(ctx, block, op, args, common_type, loc); } -@@ -1790,12 +1700,8 @@ static struct hlsl_ir_node *add_binary_comparison_expr(struct hlsl_ctx *ctx, str +@@ -1790,12 +1714,8 @@ static struct hlsl_ir_node *add_binary_comparison_expr(struct hlsl_ctx *ctx, str common_type = hlsl_get_numeric_type(ctx, type, base, dimx, dimy); return_type = hlsl_get_numeric_type(ctx, type, HLSL_TYPE_BOOL, dimx, dimy); @@ -14523,7 +15703,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 return add_expr(ctx, block, op, args, return_type, loc); } -@@ -1813,12 +1719,8 @@ static struct hlsl_ir_node *add_binary_logical_expr(struct hlsl_ctx *ctx, struct +@@ -1813,12 +1733,8 @@ static struct hlsl_ir_node *add_binary_logical_expr(struct hlsl_ctx *ctx, struct common_type = hlsl_get_numeric_type(ctx, type, HLSL_TYPE_BOOL, dimx, dimy); @@ -14538,7 +15718,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 return add_expr(ctx, block, op, args, common_type, loc); } -@@ -1844,12 +1746,8 @@ static struct hlsl_ir_node *add_binary_shift_expr(struct hlsl_ctx *ctx, struct h +@@ -1844,12 +1760,8 @@ static struct hlsl_ir_node *add_binary_shift_expr(struct hlsl_ctx *ctx, struct h return_type = hlsl_get_numeric_type(ctx, type, base, dimx, dimy); integer_type = hlsl_get_numeric_type(ctx, type, HLSL_TYPE_INT, dimx, dimy); @@ -14553,7 +15733,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 return add_expr(ctx, block, op, args, return_type, loc); } -@@ -1897,12 +1795,8 @@ static struct hlsl_ir_node *add_binary_dot_expr(struct hlsl_ctx *ctx, struct hls +@@ -1897,12 +1809,8 @@ static struct hlsl_ir_node *add_binary_dot_expr(struct hlsl_ctx *ctx, struct hls common_type = hlsl_get_vector_type(ctx, base, dim); ret_type = hlsl_get_scalar_type(ctx, base); @@ -14568,7 +15748,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 return add_expr(ctx, instrs, op, args, ret_type, loc); } -@@ -2098,8 +1992,7 @@ static bool add_assignment(struct hlsl_ctx *ctx, struct hlsl_block *block, struc +@@ -2098,8 +2006,7 @@ static bool add_assignment(struct hlsl_ctx *ctx, struct hlsl_block *block, struc width = size; } @@ -14578,7 +15758,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 while (lhs->type != HLSL_IR_LOAD && lhs->type != HLSL_IR_INDEX) { -@@ -2129,7 +2022,6 @@ static bool add_assignment(struct hlsl_ctx *ctx, struct hlsl_block *block, struc +@@ -2129,7 +2036,6 @@ static bool add_assignment(struct hlsl_ctx *ctx, struct hlsl_block *block, struc else if (lhs->type == HLSL_IR_SWIZZLE) { struct hlsl_ir_swizzle *swizzle = hlsl_ir_swizzle(lhs); @@ -14586,7 +15766,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 uint32_t s; VKD3D_ASSERT(!matrix_writemask); -@@ -2160,13 +2052,9 @@ static bool add_assignment(struct hlsl_ctx *ctx, struct hlsl_block *block, struc +@@ -2160,13 +2066,9 @@ static bool add_assignment(struct hlsl_ctx *ctx, struct hlsl_block *block, struc } } @@ -14601,7 +15781,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 } else { -@@ -2178,15 +2066,13 @@ static bool add_assignment(struct hlsl_ctx *ctx, struct hlsl_block *block, struc +@@ -2178,15 +2080,13 @@ static bool add_assignment(struct hlsl_ctx *ctx, struct hlsl_block *block, struc /* lhs casts could have resulted in a discrepancy between the * rhs->data_type and the type of the variable that will be ulimately * stored to. This is corrected. */ @@ -14618,7 +15798,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 unsigned int dim_count; if (!hlsl_index_is_resource_access(hlsl_ir_index(lhs))) -@@ -2215,12 +2101,7 @@ static bool add_assignment(struct hlsl_ctx *ctx, struct hlsl_block *block, struc +@@ -2215,12 +2115,7 @@ static bool add_assignment(struct hlsl_ctx *ctx, struct hlsl_block *block, struc VKD3D_ASSERT(coords->data_type->e.numeric.type == HLSL_TYPE_UINT); VKD3D_ASSERT(coords->data_type->e.numeric.dimx == dim_count); @@ -14628,11 +15808,11 @@ index 7afc9274c2e..ff3d58da8f4 100644 - return false; - } - hlsl_block_add_instr(block, store); -+ hlsl_block_add_resource_store(ctx, block, &resource_deref, coords, rhs, &lhs->loc); ++ hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STORE, &resource_deref, coords, rhs, &lhs->loc); hlsl_cleanup_deref(&resource_deref); } else if (matrix_writemask) -@@ -2235,25 +2116,14 @@ static bool add_assignment(struct hlsl_ctx *ctx, struct hlsl_block *block, struc +@@ -2235,25 +2130,14 @@ static bool add_assignment(struct hlsl_ctx *ctx, struct hlsl_block *block, struc for (j = 0; j < lhs->data_type->e.numeric.dimx; ++j) { struct hlsl_ir_node *load; @@ -14660,7 +15840,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 } } -@@ -2269,49 +2139,32 @@ static bool add_assignment(struct hlsl_ctx *ctx, struct hlsl_block *block, struc +@@ -2269,49 +2153,32 @@ static bool add_assignment(struct hlsl_ctx *ctx, struct hlsl_block *block, struc for (i = 0; i < mat->data_type->e.numeric.dimx; ++i) { @@ -14716,7 +15896,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 hlsl_cleanup_deref(&deref); } -@@ -2332,9 +2185,7 @@ static bool add_increment(struct hlsl_ctx *ctx, struct hlsl_block *block, bool d +@@ -2332,9 +2199,7 @@ static bool add_increment(struct hlsl_ctx *ctx, struct hlsl_block *block, bool d hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_MODIFIES_CONST, "Argument to %s%screment operator is const.", post ? "post" : "pre", decrement ? "de" : "in"); @@ -14727,7 +15907,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 if (!add_assignment(ctx, block, lhs, decrement ? ASSIGN_OP_SUB : ASSIGN_OP_ADD, one, false)) return false; -@@ -2371,8 +2222,7 @@ static void initialize_var_components(struct hlsl_ctx *ctx, struct hlsl_block *i +@@ -2371,8 +2236,7 @@ static void initialize_var_components(struct hlsl_ctx *ctx, struct hlsl_block *i struct hlsl_type *dst_comp_type; struct hlsl_block block; @@ -14737,7 +15917,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 dst_comp_type = hlsl_type_get_component_type(ctx, dst->data_type, *store_index); -@@ -2438,12 +2288,8 @@ static void initialize_var_components(struct hlsl_ctx *ctx, struct hlsl_block *i +@@ -2438,12 +2302,8 @@ static void initialize_var_components(struct hlsl_ctx *ctx, struct hlsl_block *i } else { @@ -14752,7 +15932,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 } } -@@ -2516,10 +2362,10 @@ static bool type_has_numeric_components(struct hlsl_type *type) +@@ -2516,10 +2376,10 @@ static bool type_has_numeric_components(struct hlsl_type *type) return false; } @@ -14765,7 +15945,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 if (modifiers) { struct vkd3d_string_buffer *string; -@@ -2553,6 +2399,7 @@ static void declare_var(struct hlsl_ctx *ctx, struct parse_variable_def *v) +@@ -2553,6 +2413,7 @@ static void declare_var(struct hlsl_ctx *ctx, struct parse_variable_def *v) bool constant_buffer = false; struct hlsl_ir_var *var; struct hlsl_type *type; @@ -14773,7 +15953,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 char *var_name; unsigned int i; -@@ -2644,6 +2491,10 @@ static void declare_var(struct hlsl_ctx *ctx, struct parse_variable_def *v) +@@ -2644,6 +2505,10 @@ static void declare_var(struct hlsl_ctx *ctx, struct parse_variable_def *v) hlsl_fixme(ctx, &v->loc, "Shader model 5.1+ resource array."); } @@ -14784,7 +15964,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 if (!(var_name = vkd3d_strdup(v->name))) return; -@@ -2698,6 +2549,10 @@ static void declare_var(struct hlsl_ctx *ctx, struct parse_variable_def *v) +@@ -2698,6 +2563,10 @@ static void declare_var(struct hlsl_ctx *ctx, struct parse_variable_def *v) if (!(modifiers & HLSL_STORAGE_STATIC)) var->storage_modifiers |= HLSL_STORAGE_UNIFORM; @@ -14795,7 +15975,20 @@ index 7afc9274c2e..ff3d58da8f4 100644 if ((ctx->profile->major_version < 5 || ctx->profile->type == VKD3D_SHADER_TYPE_EFFECT) && (var->storage_modifiers & HLSL_STORAGE_UNIFORM)) { -@@ -2828,15 +2683,8 @@ static struct hlsl_block *initialize_vars(struct hlsl_ctx *ctx, struct list *var +@@ -2763,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; + } + +@@ -2828,15 +2693,8 @@ static struct hlsl_block *initialize_vars(struct hlsl_ctx *ctx, struct list *var } if (!v->initializer.braces) @@ -14813,7 +16006,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 if (var->data_type->class != HLSL_CLASS_ERROR) initialize_var(ctx, var, &v->initializer, is_default_values_initializer); -@@ -2859,7 +2707,7 @@ static struct hlsl_block *initialize_vars(struct hlsl_ctx *ctx, struct list *var +@@ -2859,7 +2717,7 @@ static struct hlsl_block *initialize_vars(struct hlsl_ctx *ctx, struct list *var } else if (var->storage_modifiers & HLSL_STORAGE_STATIC) { @@ -14822,7 +16015,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 /* Initialize statics to zero by default. */ -@@ -2869,25 +2717,9 @@ static struct hlsl_block *initialize_vars(struct hlsl_ctx *ctx, struct list *var +@@ -2869,25 +2727,9 @@ static struct hlsl_block *initialize_vars(struct hlsl_ctx *ctx, struct list *var continue; } @@ -14851,7 +16044,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 } free_parse_variable_def(v); } -@@ -2934,6 +2766,7 @@ static enum hlsl_base_type hlsl_base_type_class(enum hlsl_base_type t) +@@ -2934,6 +2776,7 @@ static enum hlsl_base_type hlsl_base_type_class(enum hlsl_base_type t) return HLSL_TYPE_FLOAT; case HLSL_TYPE_INT: @@ -14859,7 +16052,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 case HLSL_TYPE_UINT: return HLSL_TYPE_INT; -@@ -2949,6 +2782,7 @@ static unsigned int hlsl_base_type_width(enum hlsl_base_type t) +@@ -2949,6 +2792,7 @@ static unsigned int hlsl_base_type_width(enum hlsl_base_type t) switch (t) { case HLSL_TYPE_HALF: @@ -14867,7 +16060,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 return 16; case HLSL_TYPE_FLOAT: -@@ -3123,11 +2957,12 @@ static struct hlsl_ir_function_decl *find_function_call(struct hlsl_ctx *ctx, +@@ -3123,11 +2967,12 @@ static struct hlsl_ir_function_decl *find_function_call(struct hlsl_ctx *ctx, return decl; } @@ -14882,7 +16075,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 } static struct hlsl_ir_node *add_user_call(struct hlsl_ctx *ctx, -@@ -3154,20 +2989,10 @@ static struct hlsl_ir_node *add_user_call(struct hlsl_ctx *ctx, +@@ -3154,20 +2999,10 @@ static struct hlsl_ir_node *add_user_call(struct hlsl_ctx *ctx, if (param->storage_modifiers & HLSL_STORAGE_IN) { @@ -14905,7 +16098,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 } ++k; -@@ -3192,7 +3017,6 @@ static struct hlsl_ir_node *add_user_call(struct hlsl_ctx *ctx, +@@ -3192,7 +3027,6 @@ static struct hlsl_ir_node *add_user_call(struct hlsl_ctx *ctx, struct hlsl_type *type = hlsl_type_get_component_type(ctx, param->data_type, j); struct hlsl_constant_value value; struct hlsl_ir_node *comp; @@ -14913,7 +16106,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 if (!param->default_values[j].string) { -@@ -3201,9 +3025,7 @@ static struct hlsl_ir_node *add_user_call(struct hlsl_ctx *ctx, +@@ -3201,9 +3035,7 @@ static struct hlsl_ir_node *add_user_call(struct hlsl_ctx *ctx, return NULL; hlsl_block_add_instr(args->instrs, comp); @@ -14924,7 +16117,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 } } } -@@ -3222,37 +3044,22 @@ static struct hlsl_ir_node *add_user_call(struct hlsl_ctx *ctx, +@@ -3222,37 +3054,22 @@ static struct hlsl_ir_node *add_user_call(struct hlsl_ctx *ctx, if (param->storage_modifiers & HLSL_STORAGE_OUT) { @@ -14967,7 +16160,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 return call; } -@@ -3262,28 +3069,20 @@ static struct hlsl_ir_node *intrinsic_float_convert_arg(struct hlsl_ctx *ctx, +@@ -3262,28 +3079,20 @@ static struct hlsl_ir_node *intrinsic_float_convert_arg(struct hlsl_ctx *ctx, { struct hlsl_type *type = arg->data_type; @@ -14999,7 +16192,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 } static struct hlsl_type *elementwise_intrinsic_get_common_type(struct hlsl_ctx *ctx, -@@ -3344,7 +3143,8 @@ static bool elementwise_intrinsic_convert_args(struct hlsl_ctx *ctx, +@@ -3344,7 +3153,8 @@ static bool elementwise_intrinsic_convert_args(struct hlsl_ctx *ctx, if (!(common_type = elementwise_intrinsic_get_common_type(ctx, params, loc))) return false; @@ -15009,7 +16202,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 } static bool elementwise_intrinsic_float_convert_args(struct hlsl_ctx *ctx, -@@ -3354,10 +3154,11 @@ static bool elementwise_intrinsic_float_convert_args(struct hlsl_ctx *ctx, +@@ -3354,10 +3164,11 @@ static bool elementwise_intrinsic_float_convert_args(struct hlsl_ctx *ctx, if (!(type = elementwise_intrinsic_get_common_type(ctx, params, loc))) return false; @@ -15023,7 +16216,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 } static bool elementwise_intrinsic_uint_convert_args(struct hlsl_ctx *ctx, -@@ -3370,7 +3171,8 @@ static bool elementwise_intrinsic_uint_convert_args(struct hlsl_ctx *ctx, +@@ -3370,7 +3181,8 @@ static bool elementwise_intrinsic_uint_convert_args(struct hlsl_ctx *ctx, type = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_UINT, type->e.numeric.dimx, type->e.numeric.dimy); @@ -15033,7 +16226,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 } static bool intrinsic_abs(struct hlsl_ctx *ctx, -@@ -3407,8 +3209,7 @@ static bool write_acos_or_asin(struct hlsl_ctx *ctx, +@@ -3407,8 +3219,7 @@ static bool write_acos_or_asin(struct hlsl_ctx *ctx, const char *fn_name = asin_mode ? fn_name_asin : fn_name_acos; @@ -15043,7 +16236,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 type = arg->data_type; if (!(body = hlsl_sprintf_alloc(ctx, template, -@@ -3438,7 +3239,7 @@ static struct hlsl_type *convert_numeric_type(const struct hlsl_ctx *ctx, +@@ -3438,7 +3249,7 @@ static struct hlsl_type *convert_numeric_type(const struct hlsl_ctx *ctx, return hlsl_get_numeric_type(ctx, type->class, base_type, type->e.numeric.dimx, type->e.numeric.dimy); } @@ -15052,7 +16245,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 struct hlsl_ir_node *arg, enum hlsl_ir_expr_op op, const struct vkd3d_shader_location *loc) { struct hlsl_ir_node *res, *load; -@@ -3446,20 +3247,13 @@ static bool add_combine_components(struct hlsl_ctx *ctx, const struct parse_init +@@ -3446,20 +3257,13 @@ static bool add_combine_components(struct hlsl_ctx *ctx, const struct parse_init count = hlsl_type_component_count(arg->data_type); @@ -15076,7 +16269,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 } static bool intrinsic_all(struct hlsl_ctx *ctx, -@@ -3469,10 +3263,9 @@ static bool intrinsic_all(struct hlsl_ctx *ctx, +@@ -3469,10 +3273,9 @@ static bool intrinsic_all(struct hlsl_ctx *ctx, struct hlsl_type *bool_type; bool_type = convert_numeric_type(ctx, arg->data_type, HLSL_TYPE_BOOL); @@ -15090,7 +16283,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 } static bool intrinsic_any(struct hlsl_ctx *ctx, const struct parse_initializer *params, -@@ -3482,10 +3275,9 @@ static bool intrinsic_any(struct hlsl_ctx *ctx, const struct parse_initializer * +@@ -3482,10 +3285,9 @@ static bool intrinsic_any(struct hlsl_ctx *ctx, const struct parse_initializer * struct hlsl_type *bool_type; bool_type = convert_numeric_type(ctx, arg->data_type, HLSL_TYPE_BOOL); @@ -15104,7 +16297,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 } static bool intrinsic_asin(struct hlsl_ctx *ctx, -@@ -3671,10 +3463,7 @@ static bool intrinsic_asuint(struct hlsl_ctx *ctx, +@@ -3671,10 +3473,7 @@ static bool intrinsic_asuint(struct hlsl_ctx *ctx, static bool intrinsic_ceil(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { @@ -15116,7 +16309,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_CEIL, arg, loc); } -@@ -3696,7 +3485,7 @@ static bool intrinsic_clamp(struct hlsl_ctx *ctx, +@@ -3696,7 +3495,7 @@ static bool intrinsic_clamp(struct hlsl_ctx *ctx, static bool intrinsic_clip(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { @@ -15125,7 +16318,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 if (!elementwise_intrinsic_float_convert_args(ctx, params, loc)) return false; -@@ -3714,20 +3503,14 @@ static bool intrinsic_clip(struct hlsl_ctx *ctx, +@@ -3714,20 +3513,14 @@ static bool intrinsic_clip(struct hlsl_ctx *ctx, return false; } @@ -15148,7 +16341,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_COS, arg, loc); } -@@ -3748,8 +3531,7 @@ static bool write_cosh_or_sinh(struct hlsl_ctx *ctx, +@@ -3748,8 +3541,7 @@ static bool write_cosh_or_sinh(struct hlsl_ctx *ctx, static const char fn_name_sinh[] = "sinh"; static const char fn_name_cosh[] = "cosh"; @@ -15158,7 +16351,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 type_name = arg->data_type->name; fn_name = sinh_mode ? fn_name_sinh : fn_name_cosh; -@@ -3782,39 +3564,23 @@ static bool intrinsic_cross(struct hlsl_ctx *ctx, +@@ -3782,39 +3574,23 @@ static bool intrinsic_cross(struct hlsl_ctx *ctx, enum hlsl_base_type base; base = expr_common_base_type(arg1->data_type->e.numeric.type, arg2->data_type->e.numeric.type); @@ -15192,12 +16385,12 @@ index 7afc9274c2e..ff3d58da8f4 100644 - if (!(mul1_neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, mul1, loc))) - return false; - hlsl_block_add_instr(params->instrs, mul1_neg); -+ mul1_neg = hlsl_block_add_unary_expr(ctx, params->instrs, HLSL_OP1_NEG, mul1, loc); - +- - if (!(arg1_swzl2 = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(Y, Z, X, Y), 3, arg1_cast, loc))) - return false; - hlsl_block_add_instr(params->instrs, arg1_swzl2); -- ++ mul1_neg = hlsl_block_add_unary_expr(ctx, params->instrs, HLSL_OP1_NEG, mul1, loc); + - if (!(arg2_swzl2 = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(Z, X, Y, Z), 3, arg2_cast, loc))) - return false; - hlsl_block_add_instr(params->instrs, arg2_swzl2); @@ -15206,7 +16399,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 if (!(mul2 = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, arg1_swzl2, arg2_swzl2, loc))) return false; -@@ -3827,8 +3593,7 @@ static bool intrinsic_ddx(struct hlsl_ctx *ctx, +@@ -3827,8 +3603,7 @@ static bool intrinsic_ddx(struct hlsl_ctx *ctx, { struct hlsl_ir_node *arg; @@ -15216,7 +16409,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_DSX, arg, loc); } -@@ -3838,8 +3603,7 @@ static bool intrinsic_ddx_coarse(struct hlsl_ctx *ctx, +@@ -3838,8 +3613,7 @@ static bool intrinsic_ddx_coarse(struct hlsl_ctx *ctx, { struct hlsl_ir_node *arg; @@ -15226,7 +16419,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_DSX_COARSE, arg, loc); } -@@ -3849,8 +3613,7 @@ static bool intrinsic_ddx_fine(struct hlsl_ctx *ctx, +@@ -3849,8 +3623,7 @@ static bool intrinsic_ddx_fine(struct hlsl_ctx *ctx, { struct hlsl_ir_node *arg; @@ -15236,7 +16429,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_DSX_FINE, arg, loc); } -@@ -3860,8 +3623,7 @@ static bool intrinsic_ddy(struct hlsl_ctx *ctx, +@@ -3860,8 +3633,7 @@ static bool intrinsic_ddy(struct hlsl_ctx *ctx, { struct hlsl_ir_node *arg; @@ -15246,7 +16439,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_DSY, arg, loc); } -@@ -3871,8 +3633,7 @@ static bool intrinsic_ddy_coarse(struct hlsl_ctx *ctx, +@@ -3871,8 +3643,7 @@ static bool intrinsic_ddy_coarse(struct hlsl_ctx *ctx, { struct hlsl_ir_node *arg; @@ -15256,7 +16449,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_DSY_COARSE, arg, loc); } -@@ -3882,14 +3643,10 @@ static bool intrinsic_degrees(struct hlsl_ctx *ctx, +@@ -3882,14 +3653,10 @@ static bool intrinsic_degrees(struct hlsl_ctx *ctx, { struct hlsl_ir_node *arg, *deg; @@ -15273,7 +16466,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, arg, deg, loc); } -@@ -3898,8 +3655,7 @@ static bool intrinsic_ddy_fine(struct hlsl_ctx *ctx, +@@ -3898,8 +3665,7 @@ static bool intrinsic_ddy_fine(struct hlsl_ctx *ctx, { struct hlsl_ir_node *arg; @@ -15283,7 +16476,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_DSY_FINE, arg, loc); } -@@ -3953,8 +3709,7 @@ static bool intrinsic_determinant(struct hlsl_ctx *ctx, +@@ -3953,8 +3719,7 @@ static bool intrinsic_determinant(struct hlsl_ctx *ctx, return false; } @@ -15293,7 +16486,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 dim = min(type->e.numeric.dimx, type->e.numeric.dimy); if (dim == 1) -@@ -3996,11 +3751,8 @@ static bool intrinsic_distance(struct hlsl_ctx *ctx, +@@ -3996,11 +3761,8 @@ static bool intrinsic_distance(struct hlsl_ctx *ctx, { struct hlsl_ir_node *arg1, *arg2, *neg, *add, *dot; @@ -15307,7 +16500,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 if (!(neg = add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_NEG, arg2, loc))) return false; -@@ -4069,13 +3821,10 @@ static bool intrinsic_exp(struct hlsl_ctx *ctx, +@@ -4069,13 +3831,10 @@ static bool intrinsic_exp(struct hlsl_ctx *ctx, { struct hlsl_ir_node *arg, *mul, *coeff; @@ -15323,7 +16516,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 if (!(mul = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, coeff, arg, loc))) return false; -@@ -4088,8 +3837,7 @@ static bool intrinsic_exp2(struct hlsl_ctx *ctx, +@@ -4088,8 +3847,7 @@ static bool intrinsic_exp2(struct hlsl_ctx *ctx, { struct hlsl_ir_node *arg; @@ -15333,7 +16526,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_EXP2, arg, loc); } -@@ -4157,8 +3905,7 @@ static bool intrinsic_floor(struct hlsl_ctx *ctx, +@@ -4157,8 +3915,7 @@ static bool intrinsic_floor(struct hlsl_ctx *ctx, { struct hlsl_ir_node *arg; @@ -15343,7 +16536,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_FLOOR, arg, loc); } -@@ -4170,11 +3917,8 @@ static bool intrinsic_fmod(struct hlsl_ctx *ctx, const struct parse_initializer +@@ -4170,11 +3927,8 @@ static bool intrinsic_fmod(struct hlsl_ctx *ctx, const struct parse_initializer struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = { 0 }; static const struct hlsl_constant_value zero_value; @@ -15357,7 +16550,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 if (!(div = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_DIV, x, y, loc))) return false; -@@ -4209,8 +3953,7 @@ static bool intrinsic_frac(struct hlsl_ctx *ctx, +@@ -4209,8 +3963,7 @@ static bool intrinsic_frac(struct hlsl_ctx *ctx, { struct hlsl_ir_node *arg; @@ -15367,7 +16560,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_FRACT, arg, loc); } -@@ -4285,8 +4028,7 @@ static bool intrinsic_length(struct hlsl_ctx *ctx, +@@ -4285,8 +4038,7 @@ static bool intrinsic_length(struct hlsl_ctx *ctx, hlsl_release_string_buffer(ctx, string); } @@ -15377,7 +16570,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 if (!(dot = add_binary_dot_expr(ctx, params->instrs, arg, arg, loc))) return false; -@@ -4314,21 +4056,6 @@ static bool intrinsic_lerp(struct hlsl_ctx *ctx, +@@ -4314,21 +4066,6 @@ static bool intrinsic_lerp(struct hlsl_ctx *ctx, return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_ADD, params->args[0], mul, loc); } @@ -15399,7 +16592,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 static bool intrinsic_lit(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { -@@ -4363,17 +4090,13 @@ static bool intrinsic_log(struct hlsl_ctx *ctx, +@@ -4363,17 +4100,13 @@ static bool intrinsic_log(struct hlsl_ctx *ctx, { struct hlsl_ir_node *log, *arg, *coeff; @@ -15419,7 +16612,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, log, coeff, loc); } -@@ -4382,17 +4105,13 @@ static bool intrinsic_log10(struct hlsl_ctx *ctx, +@@ -4382,17 +4115,13 @@ static bool intrinsic_log10(struct hlsl_ctx *ctx, { struct hlsl_ir_node *log, *arg, *coeff; @@ -15439,7 +16632,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, log, coeff, loc); } -@@ -4401,8 +4120,7 @@ static bool intrinsic_log2(struct hlsl_ctx *ctx, +@@ -4401,8 +4130,7 @@ static bool intrinsic_log2(struct hlsl_ctx *ctx, { struct hlsl_ir_node *arg; @@ -15449,7 +16642,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_LOG2, arg, loc); } -@@ -4476,7 +4194,7 @@ static bool intrinsic_mul(struct hlsl_ctx *ctx, +@@ -4476,7 +4204,7 @@ static bool intrinsic_mul(struct hlsl_ctx *ctx, struct hlsl_type *cast_type1 = arg1->data_type, *cast_type2 = arg2->data_type, *matrix_type, *ret_type; unsigned int i, j, k, vect_count = 0; struct hlsl_deref var_deref; @@ -15458,7 +16651,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 struct hlsl_ir_var *var; if (arg1->data_type->class == HLSL_CLASS_SCALAR || arg2->data_type->class == HLSL_CLASS_SCALAR) -@@ -4510,11 +4228,8 @@ static bool intrinsic_mul(struct hlsl_ctx *ctx, +@@ -4510,11 +4238,8 @@ static bool intrinsic_mul(struct hlsl_ctx *ctx, ret_type = hlsl_get_scalar_type(ctx, base); } @@ -15472,7 +16665,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 if (!(var = hlsl_new_synthetic_var(ctx, "mul", matrix_type, loc))) return false; -@@ -4525,19 +4240,15 @@ static bool intrinsic_mul(struct hlsl_ctx *ctx, +@@ -4525,19 +4250,15 @@ static bool intrinsic_mul(struct hlsl_ctx *ctx, for (j = 0; j < matrix_type->e.numeric.dimy; ++j) { struct hlsl_ir_node *instr = NULL; @@ -15496,7 +16689,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 if (!(mul = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, value1, value2, loc))) return false; -@@ -4553,17 +4264,14 @@ static bool intrinsic_mul(struct hlsl_ctx *ctx, +@@ -4553,17 +4274,14 @@ static bool intrinsic_mul(struct hlsl_ctx *ctx, } } @@ -15519,7 +16712,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 } static bool intrinsic_normalize(struct hlsl_ctx *ctx, -@@ -4582,8 +4290,7 @@ static bool intrinsic_normalize(struct hlsl_ctx *ctx, +@@ -4582,8 +4300,7 @@ static bool intrinsic_normalize(struct hlsl_ctx *ctx, hlsl_release_string_buffer(ctx, string); } @@ -15529,7 +16722,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 if (!(dot = add_binary_dot_expr(ctx, params->instrs, arg, arg, loc))) return false; -@@ -4597,10 +4304,18 @@ static bool intrinsic_normalize(struct hlsl_ctx *ctx, +@@ -4597,10 +4314,18 @@ static bool intrinsic_normalize(struct hlsl_ctx *ctx, static bool intrinsic_pow(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { @@ -15549,7 +16742,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 } static bool intrinsic_radians(struct hlsl_ctx *ctx, -@@ -4608,14 +4323,10 @@ static bool intrinsic_radians(struct hlsl_ctx *ctx, +@@ -4608,14 +4333,10 @@ static bool intrinsic_radians(struct hlsl_ctx *ctx, { struct hlsl_ir_node *arg, *rad; @@ -15566,7 +16759,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, arg, rad, loc); } -@@ -4624,8 +4335,7 @@ static bool intrinsic_rcp(struct hlsl_ctx *ctx, +@@ -4624,8 +4345,7 @@ static bool intrinsic_rcp(struct hlsl_ctx *ctx, { struct hlsl_ir_node *arg; @@ -15576,7 +16769,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_RCP, arg, loc); } -@@ -4656,7 +4366,6 @@ static bool intrinsic_refract(struct hlsl_ctx *ctx, +@@ -4656,7 +4376,6 @@ static bool intrinsic_refract(struct hlsl_ctx *ctx, { struct hlsl_type *type, *scalar_type; struct hlsl_ir_function_decl *func; @@ -15584,7 +16777,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 char *body; static const char template[] = -@@ -4686,9 +4395,7 @@ static bool intrinsic_refract(struct hlsl_ctx *ctx, +@@ -4686,9 +4405,7 @@ static bool intrinsic_refract(struct hlsl_ctx *ctx, * which we will only use the first component of. */ scalar_type = hlsl_get_scalar_type(ctx, params->args[2]->data_type->e.numeric.type); @@ -15595,7 +16788,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 if (!elementwise_intrinsic_float_convert_args(ctx, params, loc)) return false; -@@ -4711,8 +4418,7 @@ static bool intrinsic_round(struct hlsl_ctx *ctx, +@@ -4711,8 +4428,7 @@ static bool intrinsic_round(struct hlsl_ctx *ctx, { struct hlsl_ir_node *arg; @@ -15605,7 +16798,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_ROUND, arg, loc); } -@@ -4722,8 +4428,7 @@ static bool intrinsic_rsqrt(struct hlsl_ctx *ctx, +@@ -4722,8 +4438,7 @@ static bool intrinsic_rsqrt(struct hlsl_ctx *ctx, { struct hlsl_ir_node *arg; @@ -15615,7 +16808,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_RSQ, arg, loc); } -@@ -4733,8 +4438,7 @@ static bool intrinsic_saturate(struct hlsl_ctx *ctx, +@@ -4733,8 +4448,7 @@ static bool intrinsic_saturate(struct hlsl_ctx *ctx, { struct hlsl_ir_node *arg; @@ -15625,7 +16818,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_SAT, arg, loc); } -@@ -4757,16 +4461,14 @@ static bool intrinsic_sign(struct hlsl_ctx *ctx, +@@ -4757,16 +4471,14 @@ static bool intrinsic_sign(struct hlsl_ctx *ctx, if (!(lt = add_binary_comparison_expr(ctx, params->instrs, HLSL_OP2_LESS, zero, arg, loc))) return false; @@ -15644,7 +16837,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 if (!(neg = add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_NEG, op2, loc))) return false; -@@ -4780,8 +4482,7 @@ static bool intrinsic_sin(struct hlsl_ctx *ctx, +@@ -4780,8 +4492,7 @@ static bool intrinsic_sin(struct hlsl_ctx *ctx, { struct hlsl_ir_node *arg; @@ -15654,7 +16847,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_SIN, arg, loc); } -@@ -4855,8 +4556,7 @@ static bool intrinsic_sqrt(struct hlsl_ctx *ctx, +@@ -4855,8 +4566,7 @@ static bool intrinsic_sqrt(struct hlsl_ctx *ctx, { struct hlsl_ir_node *arg; @@ -15664,7 +16857,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_SQRT, arg, loc); } -@@ -4875,7 +4575,8 @@ static bool intrinsic_step(struct hlsl_ctx *ctx, +@@ -4875,7 +4585,8 @@ static bool intrinsic_step(struct hlsl_ctx *ctx, params->args[1], params->args[0], loc))) return false; @@ -15674,7 +16867,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 } static bool intrinsic_tan(struct hlsl_ctx *ctx, -@@ -4909,8 +4610,7 @@ static bool intrinsic_tanh(struct hlsl_ctx *ctx, +@@ -4909,8 +4620,7 @@ static bool intrinsic_tanh(struct hlsl_ctx *ctx, " return (exp_pos - exp_neg) / (exp_pos + exp_neg);\n" "}\n"; @@ -15684,7 +16877,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 type = arg->data_type; if (!(body = hlsl_sprintf_alloc(ctx, template, -@@ -4931,7 +4631,7 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer * +@@ -4931,7 +4641,7 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer * unsigned int sampler_dim = hlsl_sampler_dim_count(dim); struct hlsl_resource_load_params load_params = { 0 }; const struct hlsl_type *sampler_type; @@ -15693,14 +16886,17 @@ index 7afc9274c2e..ff3d58da8f4 100644 if (params->args_count != 2 && params->args_count != 4) { -@@ -4963,47 +4663,27 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer * +@@ -4963,47 +4673,27 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer * else load_params.type = HLSL_RESOURCE_SAMPLE_LOD_BIAS; - if (!(c = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(X, Y, Z, W), sampler_dim, params->args[1], loc))) - return false; - hlsl_block_add_instr(params->instrs, c); -- ++ c = hlsl_block_add_swizzle(ctx, params->instrs, HLSL_SWIZZLE(X, Y, Z, W), sampler_dim, params->args[1], loc); ++ coords = add_implicit_conversion(ctx, params->instrs, c, ++ hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc); + - if (!(coords = add_implicit_conversion(ctx, params->instrs, c, - hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) - { @@ -15710,10 +16906,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 - if (!(lod = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(W, W, W, W), 1, params->args[1], loc))) - return false; - hlsl_block_add_instr(params->instrs, lod); -+ c = hlsl_block_add_swizzle(ctx, params->instrs, HLSL_SWIZZLE(X, Y, Z, W), sampler_dim, params->args[1], loc); -+ coords = add_implicit_conversion(ctx, params->instrs, c, -+ hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc); - +- - if (!(load_params.lod = add_implicit_conversion(ctx, params->instrs, lod, - hlsl_get_scalar_type(ctx, HLSL_TYPE_FLOAT), loc))) - { @@ -15751,7 +16944,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 if (!(coords = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_DIV, coords, divisor, loc))) return false; -@@ -5017,43 +4697,25 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer * +@@ -5017,43 +4707,25 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer * } else if (params->args_count == 4) /* Gradient sampling. */ { @@ -15803,7 +16996,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 struct hlsl_ir_var *var; unsigned int idx = 0; -@@ -5062,22 +4724,10 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer * +@@ -5062,22 +4734,10 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer * initialize_var_components(ctx, params->instrs, var, &idx, coords, false); if (hlsl_version_ge(ctx, 4, 0)) @@ -15829,7 +17022,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 dim = HLSL_SAMPLER_DIM_2D; } -@@ -5086,9 +4736,7 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer * +@@ -5086,9 +4746,7 @@ 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; @@ -15840,7 +17033,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 return true; } -@@ -5175,7 +4823,6 @@ static bool intrinsic_transpose(struct hlsl_ctx *ctx, +@@ -5175,7 +4833,6 @@ static bool intrinsic_transpose(struct hlsl_ctx *ctx, { struct hlsl_ir_node *arg = params->args[0]; struct hlsl_type *arg_type = arg->data_type; @@ -15848,7 +17041,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 struct hlsl_deref var_deref; struct hlsl_type *mat_type; struct hlsl_ir_node *load; -@@ -5210,32 +4857,21 @@ static bool intrinsic_transpose(struct hlsl_ctx *ctx, +@@ -5210,32 +4867,21 @@ static bool intrinsic_transpose(struct hlsl_ctx *ctx, { for (j = 0; j < arg_type->e.numeric.dimy; ++j) { @@ -15887,7 +17080,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_TRUNC, arg, loc); } -@@ -5243,7 +4879,7 @@ static bool intrinsic_trunc(struct hlsl_ctx *ctx, +@@ -5243,7 +4889,7 @@ static bool intrinsic_trunc(struct hlsl_ctx *ctx, static bool intrinsic_d3dcolor_to_ubyte4(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { @@ -15896,7 +17089,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 struct hlsl_type *arg_type = arg->data_type; if (arg_type->class != HLSL_CLASS_SCALAR && !(arg_type->class == HLSL_CLASS_VECTOR -@@ -5260,21 +4896,11 @@ static bool intrinsic_d3dcolor_to_ubyte4(struct hlsl_ctx *ctx, +@@ -5260,21 +4906,11 @@ static bool intrinsic_d3dcolor_to_ubyte4(struct hlsl_ctx *ctx, return false; } @@ -15921,7 +17114,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 if (!(ret = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, arg, c, loc))) return false; -@@ -5289,25 +4915,20 @@ static bool intrinsic_GetRenderTargetSampleCount(struct hlsl_ctx *ctx, +@@ -5289,25 +4925,20 @@ static bool intrinsic_GetRenderTargetSampleCount(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {0}; @@ -15950,7 +17143,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 struct hlsl_type *lhs_type, *val_type; struct vkd3d_string_buffer *string; struct hlsl_deref dst_deref; -@@ -5421,10 +5042,7 @@ static bool intrinsic_interlocked(struct hlsl_ctx *ctx, enum hlsl_interlocked_op +@@ -5421,10 +5052,7 @@ static bool intrinsic_interlocked(struct hlsl_ctx *ctx, enum hlsl_interlocked_op return false; } @@ -15962,7 +17155,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 return true; } -@@ -5759,7 +5377,6 @@ static struct hlsl_block *add_compile_variant(struct hlsl_ctx *ctx, enum hlsl_co +@@ -5759,7 +5387,6 @@ static struct hlsl_block *add_compile_variant(struct hlsl_ctx *ctx, enum hlsl_co static struct hlsl_block *add_constructor(struct hlsl_ctx *ctx, struct hlsl_type *type, struct parse_initializer *params, const struct vkd3d_shader_location *loc) { @@ -15970,7 +17163,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 struct hlsl_ir_var *var; if (!hlsl_is_numeric_type(type)) -@@ -5778,9 +5395,7 @@ static struct hlsl_block *add_constructor(struct hlsl_ctx *ctx, struct hlsl_type +@@ -5778,9 +5405,7 @@ static struct hlsl_block *add_constructor(struct hlsl_ctx *ctx, struct hlsl_type initialize_var(ctx, var, params, false); @@ -15981,7 +17174,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 vkd3d_free(params->args); return params->instrs; -@@ -5822,8 +5437,7 @@ static bool add_ternary(struct hlsl_ctx *ctx, struct hlsl_block *block, +@@ -5822,8 +5447,7 @@ static bool add_ternary(struct hlsl_ctx *ctx, struct hlsl_block *block, { cond_type = hlsl_get_numeric_type(ctx, common_type->class, HLSL_TYPE_BOOL, common_type->e.numeric.dimx, common_type->e.numeric.dimy); @@ -15991,7 +17184,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 } else { -@@ -5852,15 +5466,11 @@ static bool add_ternary(struct hlsl_ctx *ctx, struct hlsl_block *block, +@@ -5852,15 +5476,11 @@ static bool add_ternary(struct hlsl_ctx *ctx, struct hlsl_block *block, cond_type = hlsl_get_numeric_type(ctx, common_type->class, HLSL_TYPE_BOOL, common_type->e.numeric.dimx, common_type->e.numeric.dimy); @@ -16010,7 +17203,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 } else { -@@ -5880,9 +5490,7 @@ static bool add_ternary(struct hlsl_ctx *ctx, struct hlsl_block *block, +@@ -5880,9 +5500,7 @@ static bool add_ternary(struct hlsl_ctx *ctx, struct hlsl_block *block, cond_type = hlsl_get_numeric_type(ctx, cond_type->class, HLSL_TYPE_BOOL, cond_type->e.numeric.dimx, cond_type->e.numeric.dimy); @@ -16021,7 +17214,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 common_type = first->data_type; } -@@ -5935,7 +5543,6 @@ static bool add_raw_load_method_call(struct hlsl_ctx *ctx, struct hlsl_block *bl +@@ -5935,7 +5553,6 @@ static bool add_raw_load_method_call(struct hlsl_ctx *ctx, struct hlsl_block *bl const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { struct hlsl_resource_load_params load_params = {.type = HLSL_RESOURCE_LOAD}; @@ -16029,7 +17222,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 unsigned int value_dim; if (params->args_count != 1 && params->args_count != 2) -@@ -5967,16 +5574,11 @@ static bool add_raw_load_method_call(struct hlsl_ctx *ctx, struct hlsl_block *bl +@@ -5967,16 +5584,11 @@ static bool add_raw_load_method_call(struct hlsl_ctx *ctx, struct hlsl_block *bl else value_dim = 4; @@ -16049,7 +17242,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 return true; } -@@ -5986,7 +5588,6 @@ static bool add_load_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, +@@ -5986,7 +5598,6 @@ static bool add_load_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, const struct hlsl_type *object_type = object->data_type; struct hlsl_resource_load_params load_params = {.type = HLSL_RESOURCE_LOAD}; unsigned int sampler_dim, offset_dim; @@ -16057,7 +17250,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 bool multisampled; if (object_type->sampler_dim == HLSL_SAMPLER_DIM_RAW_BUFFER) -@@ -6013,18 +5614,12 @@ static bool add_load_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, +@@ -6013,18 +5624,12 @@ static bool add_load_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, } if (multisampled) @@ -16080,7 +17273,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 if (params->args_count > 1 + multisampled + !!offset_dim) { -@@ -6032,16 +5627,11 @@ static bool add_load_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, +@@ -6032,16 +5637,11 @@ static bool add_load_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, } /* +1 for the mipmap level for non-multisampled textures */ @@ -16100,7 +17293,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 return true; } -@@ -6052,7 +5642,6 @@ static bool add_sample_method_call(struct hlsl_ctx *ctx, struct hlsl_block *bloc +@@ -6052,7 +5652,6 @@ static bool add_sample_method_call(struct hlsl_ctx *ctx, struct hlsl_block *bloc struct hlsl_resource_load_params load_params = {.type = HLSL_RESOURCE_SAMPLE}; unsigned int sampler_dim, offset_dim; const struct hlsl_type *sampler_type; @@ -16108,7 +17301,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim); offset_dim = hlsl_offset_dim_count(object_type->sampler_dim); -@@ -6077,16 +5666,12 @@ static bool add_sample_method_call(struct hlsl_ctx *ctx, struct hlsl_block *bloc +@@ -6077,16 +5676,12 @@ static bool add_sample_method_call(struct hlsl_ctx *ctx, struct hlsl_block *bloc return false; } @@ -16129,7 +17322,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 if (params->args_count > 2 + !!offset_dim) hlsl_fixme(ctx, loc, "Sample() clamp parameter."); -@@ -6096,11 +5681,7 @@ static bool add_sample_method_call(struct hlsl_ctx *ctx, struct hlsl_block *bloc +@@ -6096,11 +5691,7 @@ static bool add_sample_method_call(struct hlsl_ctx *ctx, struct hlsl_block *bloc load_params.format = object_type->e.resource.format; load_params.resource = object; load_params.sampler = params->args[0]; @@ -16142,7 +17335,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 return true; } -@@ -6111,7 +5692,6 @@ static bool add_sample_cmp_method_call(struct hlsl_ctx *ctx, struct hlsl_block * +@@ -6111,7 +5702,6 @@ static bool add_sample_cmp_method_call(struct hlsl_ctx *ctx, struct hlsl_block * struct hlsl_resource_load_params load_params = { 0 }; unsigned int sampler_dim, offset_dim; const struct hlsl_type *sampler_type; @@ -16150,7 +17343,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim); offset_dim = hlsl_offset_dim_count(object_type->sampler_dim); -@@ -6142,20 +5722,14 @@ static bool add_sample_cmp_method_call(struct hlsl_ctx *ctx, struct hlsl_block * +@@ -6142,20 +5732,14 @@ static bool add_sample_cmp_method_call(struct hlsl_ctx *ctx, struct hlsl_block * return false; } @@ -16177,7 +17370,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 if (params->args_count > 3 + !!offset_dim) hlsl_fixme(ctx, loc, "%s() clamp parameter.", name); -@@ -6165,11 +5739,7 @@ static bool add_sample_cmp_method_call(struct hlsl_ctx *ctx, struct hlsl_block * +@@ -6165,11 +5749,7 @@ static bool add_sample_cmp_method_call(struct hlsl_ctx *ctx, struct hlsl_block * load_params.format = object_type->e.resource.format; load_params.resource = object; load_params.sampler = params->args[0]; @@ -16190,7 +17383,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 return true; } -@@ -6180,7 +5750,6 @@ static bool add_gather_method_call(struct hlsl_ctx *ctx, struct hlsl_block *bloc +@@ -6180,7 +5760,6 @@ static bool add_gather_method_call(struct hlsl_ctx *ctx, struct hlsl_block *bloc struct hlsl_resource_load_params load_params = {0}; unsigned int sampler_dim, offset_dim; const struct hlsl_type *sampler_type; @@ -16198,7 +17391,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 unsigned int read_channel; sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim); -@@ -6234,9 +5803,8 @@ static bool add_gather_method_call(struct hlsl_ctx *ctx, struct hlsl_block *bloc +@@ -6234,9 +5813,8 @@ static bool add_gather_method_call(struct hlsl_ctx *ctx, struct hlsl_block *bloc } else if (offset_dim && params->args_count > 2) { @@ -16210,7 +17403,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 } sampler_type = params->args[0]->data_type; -@@ -6258,17 +5826,12 @@ static bool add_gather_method_call(struct hlsl_ctx *ctx, struct hlsl_block *bloc +@@ -6258,17 +5836,12 @@ static bool add_gather_method_call(struct hlsl_ctx *ctx, struct hlsl_block *bloc return false; } @@ -16231,7 +17424,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 return true; } -@@ -6279,7 +5842,6 @@ static bool add_gather_cmp_method_call(struct hlsl_ctx *ctx, struct hlsl_block * +@@ -6279,7 +5852,6 @@ static bool add_gather_cmp_method_call(struct hlsl_ctx *ctx, struct hlsl_block * struct hlsl_resource_load_params load_params = {0}; unsigned int sampler_dim, offset_dim; const struct hlsl_type *sampler_type; @@ -16239,7 +17432,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim); offset_dim = hlsl_offset_dim_count(object_type->sampler_dim); -@@ -6346,10 +5908,7 @@ static bool add_gather_cmp_method_call(struct hlsl_ctx *ctx, struct hlsl_block * +@@ -6346,10 +5918,7 @@ static bool add_gather_cmp_method_call(struct hlsl_ctx *ctx, struct hlsl_block * load_params.format = hlsl_get_vector_type(ctx, object_type->e.resource.format->e.numeric.type, 4); load_params.resource = object; load_params.sampler = params->args[0]; @@ -16251,7 +17444,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 return true; } -@@ -6361,9 +5920,7 @@ static bool add_assignment_from_component(struct hlsl_ctx *ctx, struct hlsl_bloc +@@ -6361,9 +5930,7 @@ static bool add_assignment_from_component(struct hlsl_ctx *ctx, struct hlsl_bloc if (!dest) return true; @@ -16262,7 +17455,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 if (!add_assignment(ctx, instrs, dest, ASSIGN_OP_ASSIGN, load, false)) return false; -@@ -6377,7 +5934,6 @@ static bool add_getdimensions_method_call(struct hlsl_ctx *ctx, struct hlsl_bloc +@@ -6377,7 +5944,6 @@ static bool add_getdimensions_method_call(struct hlsl_ctx *ctx, struct hlsl_bloc bool uint_resinfo, has_uint_arg, has_float_arg; struct hlsl_resource_load_params load_params; struct hlsl_ir_node *sample_info, *res_info; @@ -16270,7 +17463,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 struct hlsl_type *uint_type, *float_type; unsigned int i, j; enum func_argument -@@ -6441,12 +5997,8 @@ static bool add_getdimensions_method_call(struct hlsl_ctx *ctx, struct hlsl_bloc +@@ -6441,12 +6007,8 @@ static bool add_getdimensions_method_call(struct hlsl_ctx *ctx, struct hlsl_bloc /* Input parameter. */ if (iter->args[j] == ARG_MIP_LEVEL) { @@ -16285,7 +17478,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 continue; } -@@ -6478,22 +6030,14 @@ static bool add_getdimensions_method_call(struct hlsl_ctx *ctx, struct hlsl_bloc +@@ -6478,22 +6040,14 @@ static bool add_getdimensions_method_call(struct hlsl_ctx *ctx, struct hlsl_bloc } if (!args[ARG_MIP_LEVEL]) @@ -16310,7 +17503,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 if (!add_assignment_from_component(ctx, block, args[ARG_WIDTH], res_info, 0, loc)) return false; -@@ -6516,18 +6060,13 @@ static bool add_getdimensions_method_call(struct hlsl_ctx *ctx, struct hlsl_bloc +@@ -6516,18 +6070,13 @@ static bool add_getdimensions_method_call(struct hlsl_ctx *ctx, struct hlsl_bloc load_params.type = HLSL_RESOURCE_SAMPLE_INFO; load_params.resource = object; load_params.format = args[ARG_SAMPLE_COUNT]->data_type; @@ -16331,7 +17524,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 return true; } -@@ -6538,7 +6077,6 @@ static bool add_sample_lod_method_call(struct hlsl_ctx *ctx, struct hlsl_block * +@@ -6538,7 +6087,6 @@ static bool add_sample_lod_method_call(struct hlsl_ctx *ctx, struct hlsl_block * struct hlsl_resource_load_params load_params = { 0 }; unsigned int sampler_dim, offset_dim; const struct hlsl_type *sampler_type; @@ -16339,7 +17532,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim); offset_dim = hlsl_offset_dim_count(object_type->sampler_dim); -@@ -6568,20 +6106,14 @@ static bool add_sample_lod_method_call(struct hlsl_ctx *ctx, struct hlsl_block * +@@ -6568,20 +6116,14 @@ static bool add_sample_lod_method_call(struct hlsl_ctx *ctx, struct hlsl_block * return false; } @@ -16366,7 +17559,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 if (params->args_count > 3 + !!offset_dim) hlsl_fixme(ctx, loc, "Tiled resource status argument."); -@@ -6589,10 +6121,7 @@ static bool add_sample_lod_method_call(struct hlsl_ctx *ctx, struct hlsl_block * +@@ -6589,10 +6131,7 @@ static bool add_sample_lod_method_call(struct hlsl_ctx *ctx, struct hlsl_block * load_params.format = object_type->e.resource.format; load_params.resource = object; load_params.sampler = params->args[0]; @@ -16378,7 +17571,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 return true; } -@@ -6603,7 +6132,6 @@ static bool add_sample_grad_method_call(struct hlsl_ctx *ctx, struct hlsl_block +@@ -6603,7 +6142,6 @@ static bool add_sample_grad_method_call(struct hlsl_ctx *ctx, struct hlsl_block struct hlsl_resource_load_params load_params = { 0 }; unsigned int sampler_dim, offset_dim; const struct hlsl_type *sampler_type; @@ -16386,7 +17579,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim); offset_dim = hlsl_offset_dim_count(object_type->sampler_dim); -@@ -6630,24 +6158,16 @@ static bool add_sample_grad_method_call(struct hlsl_ctx *ctx, struct hlsl_block +@@ -6630,24 +6168,16 @@ static bool add_sample_grad_method_call(struct hlsl_ctx *ctx, struct hlsl_block return false; } @@ -16419,7 +17612,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 if (params->args_count > 4 + !!offset_dim) hlsl_fixme(ctx, loc, "Tiled resource status argument."); -@@ -6655,17 +6175,14 @@ static bool add_sample_grad_method_call(struct hlsl_ctx *ctx, struct hlsl_block +@@ -6655,17 +6185,14 @@ static bool add_sample_grad_method_call(struct hlsl_ctx *ctx, struct hlsl_block load_params.format = object_type->e.resource.format; load_params.resource = object; load_params.sampler = params->args[0]; @@ -16439,37 +17632,209 @@ index 7afc9274c2e..ff3d58da8f4 100644 struct hlsl_deref resource_deref; unsigned int value_dim; -@@ -6685,24 +6202,15 @@ static bool add_store_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block +@@ -6685,25 +6212,62 @@ static bool add_store_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block else value_dim = 4; - if (!(offset = add_implicit_conversion(ctx, block, params->args[0], - hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), loc))) -- return false; -- -- if (!(rhs = add_implicit_conversion(ctx, block, params->args[1], -- hlsl_get_vector_type(ctx, HLSL_TYPE_UINT, value_dim), loc))) -- return false; + offset = add_implicit_conversion(ctx, block, params->args[0], + hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), loc); + rhs = add_implicit_conversion(ctx, block, params->args[1], + hlsl_get_vector_type(ctx, HLSL_TYPE_UINT, value_dim), loc); ++ ++ if (!hlsl_init_deref_from_index_chain(ctx, &resource_deref, object)) ++ return false; ++ ++ hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STORE, &resource_deref, offset, rhs, loc); ++ hlsl_cleanup_deref(&resource_deref); ++ ++ return true; ++} ++ ++static bool add_so_append_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_node *object, ++ const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) ++{ ++ struct hlsl_deref so_deref; ++ struct hlsl_ir_node *rhs; ++ ++ if (params->args_count != 1) ++ { ++ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, ++ "Wrong number of arguments to method '%s': expected 1.", name); + return false; ++ } - if (!hlsl_init_deref_from_index_chain(ctx, &resource_deref, object)) +- if (!(rhs = add_implicit_conversion(ctx, block, params->args[1], +- hlsl_get_vector_type(ctx, HLSL_TYPE_UINT, value_dim), loc))) ++ if (!hlsl_init_deref_from_index_chain(ctx, &so_deref, object)) + return false; + +- if (!hlsl_init_deref_from_index_chain(ctx, &resource_deref, object)) ++ if (!(rhs = add_implicit_conversion(ctx, block, params->args[0], object->data_type->e.so.type, loc))) return false; - if (!(store = hlsl_new_resource_store(ctx, &resource_deref, offset, rhs, loc))) -- { ++ hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STREAM_APPEND, &so_deref, NULL, rhs, loc); ++ hlsl_cleanup_deref(&so_deref); ++ ++ return true; ++} ++ ++static bool add_so_restartstrip_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_node *object, ++ const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) ++{ ++ struct hlsl_deref so_deref; ++ ++ if (params->args_count) + { - hlsl_cleanup_deref(&resource_deref); -- return false; -- } -- ++ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, ++ "Wrong number of arguments to method '%s': expected 0.", name); + return false; + } + - hlsl_block_add_instr(block, store); -+ hlsl_block_add_resource_store(ctx, block, &resource_deref, offset, rhs, loc); - hlsl_cleanup_deref(&resource_deref); +- hlsl_cleanup_deref(&resource_deref); ++ if (!hlsl_init_deref_from_index_chain(ctx, &so_deref, object)) ++ return false; ++ ++ hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STREAM_RESTART, &so_deref, NULL, NULL, loc); ++ hlsl_cleanup_deref(&so_deref); return true; -@@ -6903,15 +6411,8 @@ static bool add_switch(struct hlsl_ctx *ctx, struct hlsl_block *block, + } +@@ -6751,6 +6315,12 @@ static const struct method_function uav_methods[] = + { "Store4", add_store_method_call, "00000000000001" }, + }; + ++static const struct method_function so_methods[] = ++{ ++ { "Append", add_so_append_method_call, "" }, ++ { "RestartStrip", add_so_restartstrip_method_call, "" }, ++}; ++ + static int object_method_function_name_compare(const void *a, const void *b) + { + const struct method_function *func = b; +@@ -6762,8 +6332,7 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, stru + const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) + { + const struct hlsl_type *object_type = object->data_type; +- const struct method_function *method, *methods; +- unsigned int count; ++ const struct method_function *method; + + if (object_type->class == HLSL_CLASS_ERROR) + { +@@ -6782,13 +6351,24 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, stru + + if (object_type->class == HLSL_CLASS_TEXTURE) + { +- count = ARRAY_SIZE(texture_methods); +- methods = texture_methods; ++ method = bsearch(name, texture_methods, ARRAY_SIZE(texture_methods), sizeof(*method), ++ object_method_function_name_compare); ++ ++ if (method && method->valid_dims[object_type->sampler_dim] != '1') ++ method = NULL; + } + else if (object_type->class == HLSL_CLASS_UAV) + { +- count = ARRAY_SIZE(uav_methods); +- methods = uav_methods; ++ method = bsearch(name, uav_methods, ARRAY_SIZE(uav_methods), sizeof(*method), ++ object_method_function_name_compare); ++ ++ if (method && method->valid_dims[object_type->sampler_dim] != '1') ++ method = NULL; ++ } ++ else if (object_type->class == HLSL_CLASS_STREAM_OUTPUT) ++ { ++ method = bsearch(name, so_methods, ARRAY_SIZE(so_methods), sizeof(*method), ++ object_method_function_name_compare); + } + else + { +@@ -6801,17 +6381,70 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, stru + return false; + } + +- method = bsearch(name, methods, count, sizeof(*method), +- object_method_function_name_compare); +- +- if (method && method->valid_dims[object_type->sampler_dim] == '1') +- { ++ if (method) + return method->handler(ctx, block, object, name, params, loc); +- } + else +- { + return raise_invalid_method_object_type(ctx, object_type, name, loc); ++} ++ ++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, +@@ -6903,15 +6536,8 @@ static bool add_switch(struct hlsl_ctx *ctx, struct hlsl_block *block, return true; } @@ -16487,7 +17852,15 @@ index 7afc9274c2e..ff3d58da8f4 100644 s = hlsl_new_switch(ctx, selector, cases, loc); destroy_switch_cases(cases); -@@ -7052,6 +6553,8 @@ static void validate_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim, +@@ -6990,7 +6616,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; +@@ -7052,6 +6677,8 @@ static void validate_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim, %token KW_INLINE %token KW_INOUT %token KW_INPUTPATCH @@ -16496,7 +17869,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 %token KW_LINEAR %token KW_LINESTREAM %token KW_MATRIX -@@ -7064,6 +6567,7 @@ static void validate_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim, +@@ -7064,6 +6691,7 @@ static void validate_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim, %token KW_PACKOFFSET %token KW_PASS %token KW_PIXELSHADER @@ -16504,7 +17877,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 %token KW_POINTSTREAM %token KW_RASTERIZERORDEREDBUFFER %token KW_RASTERIZERORDEREDSTRUCTUREDBUFFER -@@ -7114,6 +6618,8 @@ static void validate_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim, +@@ -7114,6 +6742,8 @@ static void validate_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim, %token KW_TEXTURE3D %token KW_TEXTURECUBE %token KW_TEXTURECUBEARRAY @@ -16513,7 +17886,63 @@ index 7afc9274c2e..ff3d58da8f4 100644 %token KW_TRIANGLESTREAM %token KW_TRUE %token KW_TYPEDEF -@@ -8121,7 +7627,8 @@ parameter: +@@ -7157,6 +6787,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 +@@ -7200,9 +6832,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 + +@@ -7253,6 +6885,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 +@@ -7269,6 +6902,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($$); } + + %% + +@@ -7422,6 +7056,9 @@ buffer_type: + declaration_statement_list: + %empty + | declaration_statement_list declaration_statement ++ { ++ destroy_block($2); ++ } + + preproc_directive: + PRE_LINE STRING +@@ -7455,9 +7092,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: +@@ -8121,7 +7755,8 @@ parameter: parameter_decl: var_modifiers type_no_void any_identifier arrays colon_attributes { @@ -16523,7 +17952,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 struct hlsl_type *type; unsigned int i; -@@ -8146,6 +7653,22 @@ parameter_decl: +@@ -8146,6 +7781,22 @@ parameter_decl: } vkd3d_free($4.sizes); @@ -16546,7 +17975,35 @@ index 7afc9274c2e..ff3d58da8f4 100644 $$.type = type; if (hlsl_version_ge(ctx, 5, 1) && type->class == HLSL_CLASS_ARRAY && hlsl_type_is_resource(type)) -@@ -8752,6 +8275,26 @@ state_block: +@@ -8561,6 +8212,10 @@ type: + declaration_statement: + declaration + | struct_declaration_without_vars ++ { ++ if (!($$ = make_empty_block(ctx))) ++ YYABORT; ++ } + | typedef + { + if (!($$ = make_empty_block(ctx))) +@@ -8574,15 +8229,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; + } + +@@ -8752,6 +8404,26 @@ state_block: hlsl_src_from_node(&entry->args[i], $5.args[i]); vkd3d_free($5.args); @@ -16573,7 +18030,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 $$ = $1; hlsl_state_block_add_entry($$, entry); } -@@ -8845,7 +8388,7 @@ variable_def_typed: +@@ -8845,7 +8517,7 @@ variable_def_typed: if (!(type = apply_type_modifiers(ctx, $2, &modifiers, true, &@1))) YYABORT; @@ -16582,7 +18039,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 $$ = $3; $$->basic_type = type; -@@ -8860,7 +8403,7 @@ variable_def_typed: +@@ -8860,7 +8532,7 @@ variable_def_typed: if (!(type = apply_type_modifiers(ctx, $2, &modifiers, true, &@1))) YYABORT; @@ -16591,7 +18048,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 $$ = $3; $$->basic_type = type; -@@ -9001,6 +8544,26 @@ var_modifiers: +@@ -9001,6 +8673,26 @@ var_modifiers: { $$ = add_modifiers(ctx, $2, HLSL_MODIFIER_SNORM, &@1); } @@ -16618,7 +18075,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 | var_identifier var_modifiers { $$ = $2; -@@ -9130,8 +8693,6 @@ statement: +@@ -9130,8 +8822,6 @@ statement: jump_statement: KW_BREAK ';' { @@ -16627,7 +18084,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 if (!is_break_allowed(ctx->cur_scope)) { hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, -@@ -9140,22 +8701,15 @@ jump_statement: +@@ -9140,22 +8830,15 @@ jump_statement: if (!($$ = make_empty_block(ctx))) YYABORT; @@ -16652,7 +18109,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 } | KW_RETURN expr ';' { -@@ -9172,18 +8726,12 @@ jump_statement: +@@ -9172,18 +8855,12 @@ jump_statement: } | KW_DISCARD ';' { @@ -16674,7 +18131,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 } selection_statement: -@@ -9191,7 +8739,6 @@ selection_statement: +@@ -9191,7 +8868,6 @@ selection_statement: { struct hlsl_ir_node *condition = node_from_block($4); const struct parse_attribute_list *attributes = &$1; @@ -16682,7 +18139,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 unsigned int i; check_attribute_list_for_duplicates(ctx, attributes); -@@ -9213,27 +8760,14 @@ selection_statement: +@@ -9213,27 +8889,14 @@ selection_statement: check_condition_type(ctx, condition); @@ -16712,7 +18169,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 } if_body: -@@ -9383,30 +8917,21 @@ func_arguments: +@@ -9383,30 +9046,21 @@ func_arguments: primary_expr: C_FLOAT { @@ -16749,7 +18206,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 } | boolean { -@@ -9451,17 +8976,15 @@ primary_expr: +@@ -9451,17 +9105,15 @@ primary_expr: } | VAR_IDENTIFIER { @@ -16769,7 +18226,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 } else { -@@ -9583,12 +9106,7 @@ postfix_expr: +@@ -9583,12 +9235,7 @@ postfix_expr: if (node->data_type->class == HLSL_CLASS_STRUCT) { @@ -16783,7 +18240,17 @@ index 7afc9274c2e..ff3d58da8f4 100644 } else if (hlsl_is_numeric_type(node->data_type)) { -@@ -9703,12 +9221,7 @@ unary_expr: +@@ -9604,6 +9251,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); +@@ -9703,12 +9353,7 @@ unary_expr: hlsl_error(ctx, &@2, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, "Modifiers are not allowed on casts."); @@ -16798,7 +18265,7 @@ index 7afc9274c2e..ff3d58da8f4 100644 $$ = $6; } diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -index 2afd3e1e1e5..ba56ba90403 100644 +index 2afd3e1e1e5..bc14885af2b 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c @@ -62,14 +62,9 @@ static struct hlsl_ir_node *new_offset_from_path_index(struct hlsl_ctx *ctx, str @@ -18161,6 +19628,9 @@ index 2afd3e1e1e5..ba56ba90403 100644 - default: - break; +- } +- } +-} + default: + break; + } @@ -18540,18 +20010,16 @@ index 2afd3e1e1e5..ba56ba90403 100644 + component_count += expr->node.data_type->e.numeric.dimx; + list_add_before(&expr->node.entry, &replacement->entry); + hlsl_replace_node(&expr->node, replacement); - } ++ } + + progress = true; - } ++ } + +out: + vkd3d_free(state.groups); + return progress; - } - --static bool copy_propagation_transform_block(struct hlsl_ctx *ctx, struct hlsl_block *block, -- struct copy_propagation_state *state); ++} ++ +struct vectorize_stores_state +{ + struct vectorizable_stores_group @@ -18574,35 +20042,53 @@ index 2afd3e1e1e5..ba56ba90403 100644 + } *groups; + size_t count, capacity; +}; - --static bool copy_propagation_process_if(struct hlsl_ctx *ctx, struct hlsl_ir_if *iff, -- struct copy_propagation_state *state) ++ +/* This must be a store to a subsection of a vector. + * In theory we can also vectorize stores to packed struct fields, + * but this requires target-specific knowledge and is probably best left + * to a VSIR pass. */ +static bool can_vectorize_store(struct hlsl_ctx *ctx, struct hlsl_ir_store *store, + unsigned int *path_len, uint8_t *writemask) - { -- bool progress = false; ++{ + struct hlsl_type *type = store->lhs.var->data_type; + unsigned int i; ++ ++ if (store->rhs.node->data_type->class > HLSL_CLASS_VECTOR) ++ return false; ++ ++ if (type->class == HLSL_CLASS_SCALAR) ++ return false; ++ ++ for (i = 0; type->class != HLSL_CLASS_VECTOR && i < store->lhs.path_len; ++i) ++ type = hlsl_get_element_type_from_path_index(ctx, type, store->lhs.path[i].node); + +-static bool copy_propagation_transform_block(struct hlsl_ctx *ctx, struct hlsl_block *block, +- struct copy_propagation_state *state); ++ if (type->class != HLSL_CLASS_VECTOR) ++ return false; + +-static bool copy_propagation_process_if(struct hlsl_ctx *ctx, struct hlsl_ir_if *iff, +- struct copy_propagation_state *state) +-{ +- bool progress = false; ++ *path_len = i; - copy_propagation_push_scope(state, ctx); - progress |= copy_propagation_transform_block(ctx, &iff->then_block, state); - if (state->stopped) - return progress; - copy_propagation_pop_scope(state); -+ if (store->rhs.node->data_type->class > HLSL_CLASS_VECTOR) -+ return false; ++ if (i < store->lhs.path_len) ++ { ++ struct hlsl_ir_constant *c; - copy_propagation_push_scope(state, ctx); - progress |= copy_propagation_transform_block(ctx, &iff->else_block, state); - if (state->stopped) - return progress; - copy_propagation_pop_scope(state); -+ if (type->class == HLSL_CLASS_SCALAR) -+ return false; ++ /* This is a store to a scalar component of a vector, achieved via ++ * indexing. */ - /* Ideally we'd invalidate the outer state looking at what was - * touched in the two inner states, but this doesn't work for @@ -18610,22 +20096,6 @@ index 2afd3e1e1e5..ba56ba90403 100644 - * so we need copy_propagation_invalidate_from_block() anyway. */ - copy_propagation_invalidate_from_block(ctx, state, &iff->then_block, iff->node.index); - copy_propagation_invalidate_from_block(ctx, state, &iff->else_block, iff->node.index); -+ for (i = 0; type->class != HLSL_CLASS_VECTOR && i < store->lhs.path_len; ++i) -+ type = hlsl_get_element_type_from_path_index(ctx, type, store->lhs.path[i].node); - -- return progress; -+ if (type->class != HLSL_CLASS_VECTOR) -+ return false; -+ -+ *path_len = i; -+ -+ if (i < store->lhs.path_len) -+ { -+ struct hlsl_ir_constant *c; -+ -+ /* This is a store to a scalar component of a vector, achieved via -+ * indexing. */ -+ + if (store->lhs.path[i].node->type != HLSL_IR_CONSTANT) + return false; + c = hlsl_ir_constant(store->lhs.path[i].node); @@ -18635,7 +20105,8 @@ index 2afd3e1e1e5..ba56ba90403 100644 + { + *writemask = store->writemask; + } -+ + +- return progress; + return true; } @@ -19305,10 +20776,11 @@ index 2afd3e1e1e5..ba56ba90403 100644 if (!(has_fract = hlsl_new_ternary_expr(ctx, HLSL_OP3_CMP, neg_fract, zero, one))) return false; -@@ -3344,52 +4124,63 @@ static bool lower_casts_to_int(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, +@@ -3343,53 +4123,64 @@ static bool lower_casts_to_int(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, + if (!(extra = hlsl_new_ternary_expr(ctx, HLSL_OP3_CMP, arg, zero, has_fract))) return false; hlsl_block_add_instr(block, extra); - +- - if (!(floor = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, arg, neg_fract))) - return false; - hlsl_block_add_instr(block, floor); @@ -19316,6 +20788,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 - if (!(res = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, floor, extra))) - return false; - hlsl_block_add_instr(block, res); ++ + floor = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, arg, neg_fract); + res = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, floor, extra); } @@ -20198,7 +21671,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 return true; } -@@ -4393,125 +4966,45 @@ static bool lower_int_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, stru +@@ -4393,7 +4966,7 @@ static bool lower_int_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, stru static bool lower_float_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { @@ -20206,22 +21679,11 @@ index 2afd3e1e1e5..ba56ba90403 100644 + struct hlsl_ir_node *arg1, *arg2, *mul1, *neg1, *ge, *neg2, *div, *mul2, *frc, *cond, *one; struct hlsl_type *type = instr->data_type, *btype; struct hlsl_constant_value one_value; -- struct hlsl_ir_expr *expr; -- unsigned int i; -- -- if (instr->type != HLSL_IR_EXPR) -- return false; -- expr = hlsl_ir_expr(instr); -- arg1 = expr->operands[0].node; -- arg2 = expr->operands[1].node; -- if (expr->op != HLSL_OP2_MOD) -- return false; -- if (type->class != HLSL_CLASS_SCALAR && type->class != HLSL_CLASS_VECTOR) -- return false; -- if (type->e.numeric.type != HLSL_TYPE_FLOAT) -- return false; -- btype = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_BOOL, type->e.numeric.dimx, type->e.numeric.dimy); -- + struct hlsl_ir_expr *expr; +@@ -4412,25 +4985,14 @@ static bool lower_float_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr + return false; + btype = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_BOOL, type->e.numeric.dimx, type->e.numeric.dimy); + - if (!(mul1 = hlsl_new_binary_expr(ctx, HLSL_OP2_MUL, arg2, arg1))) - return false; - hlsl_block_add_instr(block, mul1); @@ -20229,25 +21691,30 @@ index 2afd3e1e1e5..ba56ba90403 100644 - if (!(neg1 = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, mul1, &instr->loc))) - return false; - hlsl_block_add_instr(block, neg1); -- ++ mul1 = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, arg2, arg1); ++ neg1 = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, mul1, &instr->loc); + - if (!(ge = hlsl_new_binary_expr(ctx, HLSL_OP2_GEQUAL, mul1, neg1))) - return false; -- ge->data_type = btype; ++ ge = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_GEQUAL, mul1, neg1); + ge->data_type = btype; - hlsl_block_add_instr(block, ge); - - if (!(neg2 = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, arg2, &instr->loc))) - return false; - hlsl_block_add_instr(block, neg2); -- + - if (!(cond = hlsl_add_conditional(ctx, block, ge, arg2, neg2))) - return false; -- -- for (i = 0; i < type->e.numeric.dimx; ++i) -- one_value.u[i].f = 1.0f; -- if (!(one = hlsl_new_constant(ctx, type, &one_value, &instr->loc))) -- return false; -- hlsl_block_add_instr(block, one); -- ++ neg2 = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, arg2, &instr->loc); ++ cond = hlsl_add_conditional(ctx, block, ge, arg2, neg2); + + for (i = 0; i < type->e.numeric.dimx; ++i) + one_value.u[i].f = 1.0f; +@@ -4438,82 +5000,13 @@ static bool lower_float_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr + return false; + hlsl_block_add_instr(block, one); + - if (!(div = hlsl_new_binary_expr(ctx, HLSL_OP2_DIV, one, cond))) - return false; - hlsl_block_add_instr(block, div); @@ -20264,9 +21731,13 @@ index 2afd3e1e1e5..ba56ba90403 100644 - return false; - hlsl_block_add_instr(block, mul3); - -- return true; --} -- ++ div = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_DIV, one, cond); ++ mul2 = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, div, arg1); ++ frc = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_FRACT, mul2, &instr->loc); ++ hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, frc, cond); + return true; + } + -static bool lower_nonfloat_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) -{ - struct hlsl_ir_expr *expr; @@ -20293,68 +21764,40 @@ index 2afd3e1e1e5..ba56ba90403 100644 - struct hlsl_ir_node *arg, *arg_cast, *float_expr, *ret; - struct hlsl_type *float_type; - unsigned int i; -+ struct hlsl_ir_expr *expr; -+ unsigned int i; - +- - for (i = 0; i < HLSL_MAX_OPERANDS; ++i) - { - arg = expr->operands[i].node; - if (!arg) - continue; -+ if (instr->type != HLSL_IR_EXPR) -+ return false; -+ expr = hlsl_ir_expr(instr); -+ arg1 = expr->operands[0].node; -+ arg2 = expr->operands[1].node; -+ if (expr->op != HLSL_OP2_MOD) -+ return false; -+ if (type->class != HLSL_CLASS_SCALAR && type->class != HLSL_CLASS_VECTOR) -+ return false; -+ if (type->e.numeric.type != HLSL_TYPE_FLOAT) -+ return false; -+ btype = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_BOOL, type->e.numeric.dimx, type->e.numeric.dimy); - +- - float_type = hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, arg->data_type->e.numeric.dimx); - if (!(arg_cast = hlsl_new_cast(ctx, arg, float_type, &instr->loc))) - return false; - hlsl_block_add_instr(block, arg_cast); -+ mul1 = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, arg2, arg1); -+ neg1 = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, mul1, &instr->loc); - +- - operands[i] = arg_cast; - } -+ ge = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_GEQUAL, mul1, neg1); -+ ge->data_type = btype; - +- - float_type = hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, instr->data_type->e.numeric.dimx); - if (!(float_expr = hlsl_new_expr(ctx, expr->op, operands, float_type, &instr->loc))) - return false; - hlsl_block_add_instr(block, float_expr); -+ neg2 = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, arg2, &instr->loc); -+ cond = hlsl_add_conditional(ctx, block, ge, arg2, neg2); - +- - if (!(ret = hlsl_new_cast(ctx, float_expr, instr->data_type, &instr->loc))) - return false; - hlsl_block_add_instr(block, ret); -+ for (i = 0; i < type->e.numeric.dimx; ++i) -+ one_value.u[i].f = 1.0f; -+ if (!(one = hlsl_new_constant(ctx, type, &one_value, &instr->loc))) -+ return false; -+ hlsl_block_add_instr(block, one); - +- - return true; - } - default: - return false; - } -+ div = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_DIV, one, cond); -+ mul2 = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, div, arg1); -+ frc = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_FRACT, mul2, &instr->loc); -+ hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, frc, cond); -+ return true; - } - +-} +- static bool lower_discard_neg(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) + { + struct hlsl_ir_node *zero, *bool_false, *or, *cmp, *load; @@ -4541,9 +5034,7 @@ static bool lower_discard_neg(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, operands[1] = zero; cmp_type = hlsl_get_numeric_type(ctx, arg_type->class, HLSL_TYPE_BOOL, @@ -20412,20 +21855,48 @@ index 2afd3e1e1e5..ba56ba90403 100644 if (var->last_read < instr->index) { list_remove(&instr->entry); -@@ -4938,20 +5420,15 @@ static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop +@@ -4709,6 +5191,8 @@ static char get_regset_name(enum hlsl_regset regset) + return 't'; + case HLSL_REGSET_UAVS: + return 'u'; ++ case HLSL_REGSET_STREAM_OUTPUTS: ++ return 'm'; + case HLSL_REGSET_NUMERIC: + vkd3d_unreachable(); } - } - +@@ -4877,8 +5361,10 @@ static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop + var = store->resource.var; + var->last_read = max(var->last_read, last_read); + deref_mark_last_read(&store->resource, last_read); +- store->coords.node->last_read = last_read; +- store->value.node->last_read = last_read; ++ if (store->coords.node) ++ store->coords.node->last_read = last_read; ++ if (store->value.node) ++ store->value.node->last_read = last_read; + break; + } + case HLSL_IR_SWIZZLE: +@@ -4934,16 +5420,8 @@ static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop + case HLSL_IR_SAMPLER_STATE: + /* These types are skipped as they are only relevant to effects. */ + break; +- } +- } +-} +- -static void init_var_liveness(struct hlsl_ir_var *var) -{ - if (var->is_uniform || var->is_input_semantic) - var->first_write = 1; - else if (var->is_output_semantic) - var->last_read = UINT_MAX; --} -- ++ } ++ } + } + static void compute_liveness(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func) - { +@@ -4951,7 +5429,10 @@ static void compute_liveness(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl struct hlsl_scope *scope; struct hlsl_ir_var *var; @@ -20437,7 +21908,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 LIST_FOR_EACH_ENTRY(scope, &ctx->scopes, struct hlsl_scope, entry) { -@@ -4959,12 +5436,6 @@ static void compute_liveness(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl +@@ -4959,12 +5440,6 @@ static void compute_liveness(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl var->first_write = var->last_read = 0; } @@ -20450,7 +21921,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 compute_liveness_recurse(&entry_func->body, 0, 0); } -@@ -5001,7 +5472,7 @@ struct register_allocator +@@ -5001,7 +5476,7 @@ struct register_allocator /* Indexable temps are allocated separately and always keep their index regardless of their * lifetime. */ @@ -20459,7 +21930,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 /* Total number of registers allocated so far. Used to declare sm4 temp count. */ uint32_t reg_count; -@@ -5269,8 +5740,7 @@ static void register_deref_usage(struct hlsl_ctx *ctx, struct hlsl_deref *deref) +@@ -5269,8 +5744,7 @@ static void register_deref_usage(struct hlsl_ctx *ctx, struct hlsl_deref *deref) struct hlsl_type *type; unsigned int index; @@ -20469,7 +21940,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 if (regset <= HLSL_REGSET_LAST_OBJECT) { -@@ -5281,7 +5751,6 @@ static void register_deref_usage(struct hlsl_ctx *ctx, struct hlsl_deref *deref) +@@ -5281,7 +5755,6 @@ static void register_deref_usage(struct hlsl_ctx *ctx, struct hlsl_deref *deref) { type = hlsl_deref_get_type(ctx, deref); @@ -20477,7 +21948,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 required_bind_count = align(index + type->reg_size[regset], 4) / 4; var->bind_count[regset] = max(var->bind_count[regset], required_bind_count); } -@@ -5481,6 +5950,33 @@ static void allocate_temp_registers_recurse(struct hlsl_ctx *ctx, +@@ -5481,6 +5954,33 @@ static void allocate_temp_registers_recurse(struct hlsl_ctx *ctx, } } @@ -20511,7 +21982,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 static void record_constant(struct hlsl_ctx *ctx, unsigned int component_index, float f, const struct vkd3d_shader_location *loc) { -@@ -5494,6 +5990,7 @@ static void record_constant(struct hlsl_ctx *ctx, unsigned int component_index, +@@ -5494,6 +5994,7 @@ static void record_constant(struct hlsl_ctx *ctx, unsigned int component_index, if (reg->index == (component_index / 4)) { reg->value.f[component_index % 4] = f; @@ -20519,7 +21990,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 return; } } -@@ -5504,6 +6001,7 @@ static void record_constant(struct hlsl_ctx *ctx, unsigned int component_index, +@@ -5504,6 +6005,7 @@ static void record_constant(struct hlsl_ctx *ctx, unsigned int component_index, memset(reg, 0, sizeof(*reg)); reg->index = component_index / 4; reg->value.f[component_index % 4] = f; @@ -20527,7 +21998,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 reg->loc = *loc; } -@@ -5520,49 +6018,57 @@ static void allocate_const_registers_recurse(struct hlsl_ctx *ctx, +@@ -5520,49 +6022,57 @@ static void allocate_const_registers_recurse(struct hlsl_ctx *ctx, { struct hlsl_ir_constant *constant = hlsl_ir_constant(instr); const struct hlsl_type *type = instr->data_type; @@ -20581,7 +22052,8 @@ index 2afd3e1e1e5..ba56ba90403 100644 return; } + } -+ + +- record_constant(ctx, constant->reg.id * 4 + x, f, &constant->node.loc); + if (find_constant(ctx, f, type->e.numeric.dimx, &constant->reg)) + { + TRACE("Reusing already allocated constant %s for @%u.\n", @@ -20591,8 +22063,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 + + constant->reg = allocate_numeric_registers_for_type(ctx, allocator, 1, UINT_MAX, type); + TRACE("Allocated constant @%u to %s.\n", instr->index, debug_register('c', constant->reg, type)); - -- record_constant(ctx, constant->reg.id * 4 + x, f, &constant->node.loc); ++ + for (unsigned int x = 0, i = 0; x < 4; ++x) + { + if ((constant->reg.writemask & (1u << x))) @@ -20600,7 +22071,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 } break; -@@ -5765,15 +6271,12 @@ static uint32_t allocate_temp_registers(struct hlsl_ctx *ctx, struct hlsl_ir_fun +@@ -5765,15 +6275,12 @@ static uint32_t allocate_temp_registers(struct hlsl_ctx *ctx, struct hlsl_ir_fun /* ps_1_* outputs are special and go in temp register 0. */ if (ctx->profile->major_version == 1 && ctx->profile->type == VKD3D_SHADER_TYPE_PIXEL) { @@ -20618,7 +22089,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 break; } } -@@ -5782,6 +6285,13 @@ static uint32_t allocate_temp_registers(struct hlsl_ctx *ctx, struct hlsl_ir_fun +@@ -5782,6 +6289,13 @@ static uint32_t allocate_temp_registers(struct hlsl_ctx *ctx, struct hlsl_ir_fun allocate_temp_registers_recurse(ctx, &entry_func->body, &allocator); vkd3d_free(allocator.allocations); @@ -20632,7 +22103,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 return allocator.reg_count; } -@@ -5803,6 +6313,11 @@ static enum vkd3d_shader_interpolation_mode sm4_get_interpolation_mode(struct hl +@@ -5803,6 +6317,11 @@ static enum vkd3d_shader_interpolation_mode sm4_get_interpolation_mode(struct hl {HLSL_STORAGE_CENTROID | HLSL_STORAGE_LINEAR, VKD3DSIM_LINEAR_CENTROID}, }; @@ -20644,7 +22115,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 if ((storage_modifiers & HLSL_STORAGE_NOINTERPOLATION) || base_type_get_semantic_equivalent(type->e.numeric.type) == HLSL_TYPE_UINT) return VKD3DSIM_CONSTANT; -@@ -5829,7 +6344,7 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var +@@ -5829,7 +6348,7 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var [VKD3D_SHADER_TYPE_COMPUTE] = "Compute", }; @@ -20653,7 +22124,16 @@ index 2afd3e1e1e5..ba56ba90403 100644 enum vkd3d_shader_register_type type; struct vkd3d_shader_version version; bool special_interpolation = false; -@@ -5870,7 +6385,7 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var +@@ -5853,7 +6372,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, +@@ -5870,7 +6389,7 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var bool has_idx; if (!sm4_sysval_semantic_from_semantic_name(&semantic, &version, ctx->semantic_compat_mapping, ctx->domain, @@ -20662,7 +22142,18 @@ index 2afd3e1e1e5..ba56ba90403 100644 { hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SEMANTIC, "Invalid semantic '%s'.", var->semantic.name); -@@ -5903,7 +6418,7 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var +@@ -5892,7 +6411,9 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var + || semantic == VKD3D_SHADER_SV_PRIMITIVE_ID) + vip_allocation = true; + +- if (semantic == VKD3D_SHADER_SV_IS_FRONT_FACE || semantic == VKD3D_SHADER_SV_SAMPLE_INDEX) ++ if (semantic == VKD3D_SHADER_SV_IS_FRONT_FACE || semantic == VKD3D_SHADER_SV_SAMPLE_INDEX ++ || (version.type == VKD3D_SHADER_TYPE_DOMAIN && !output && !is_primitive) ++ || (ctx->is_patch_constant_func && output)) + special_interpolation = true; + } + +@@ -5903,7 +6424,7 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var } else { @@ -20671,7 +22162,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 ? var->data_type->e.array.type->e.numeric.dimx : var->data_type->e.numeric.dimx; int mode = (ctx->profile->major_version < 4) ? 0 : sm4_get_interpolation_mode(var->data_type, var->storage_modifiers); -@@ -5922,7 +6437,7 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var +@@ -5922,12 +6443,14 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var static void allocate_semantic_registers(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func) { @@ -20680,7 +22171,14 @@ index 2afd3e1e1e5..ba56ba90403 100644 struct register_allocator input_allocator = {0}, output_allocator = {0}; bool is_vertex_shader = ctx->profile->type == VKD3D_SHADER_TYPE_VERTEX; bool is_pixel_shader = ctx->profile->type == VKD3D_SHADER_TYPE_PIXEL; -@@ -5935,7 +6450,7 @@ static void allocate_semantic_registers(struct hlsl_ctx *ctx, struct hlsl_ir_fun + struct hlsl_ir_var *var; + ++ in_prim_allocator.prioritize_smaller_writemasks = true; ++ patch_constant_out_patch_allocator.prioritize_smaller_writemasks = true; + input_allocator.prioritize_smaller_writemasks = true; + output_allocator.prioritize_smaller_writemasks = true; + +@@ -5935,7 +6458,7 @@ static void allocate_semantic_registers(struct hlsl_ctx *ctx, struct hlsl_ir_fun { if (var->is_input_semantic) { @@ -20689,7 +22187,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 { bool is_patch_constant_output_patch = ctx->is_patch_constant_func && var->data_type->e.array.array_type == HLSL_ARRAY_PATCH_OUTPUT; -@@ -5944,7 +6459,7 @@ static void allocate_semantic_registers(struct hlsl_ctx *ctx, struct hlsl_ir_fun +@@ -5944,7 +6467,7 @@ static void allocate_semantic_registers(struct hlsl_ctx *ctx, struct hlsl_ir_fun allocate_semantic_register(ctx, var, &patch_constant_out_patch_allocator, false, !is_vertex_shader); else @@ -20698,7 +22196,42 @@ index 2afd3e1e1e5..ba56ba90403 100644 !is_vertex_shader); } else -@@ -6360,7 +6875,7 @@ bool hlsl_component_index_range_from_deref(struct hlsl_ctx *ctx, const struct hl +@@ -5955,6 +6478,8 @@ static void allocate_semantic_registers(struct hlsl_ctx *ctx, struct hlsl_ir_fun + allocate_semantic_register(ctx, var, &output_allocator, true, !is_pixel_shader); + } + ++ vkd3d_free(in_prim_allocator.allocations); ++ vkd3d_free(patch_constant_out_patch_allocator.allocations); + vkd3d_free(input_allocator.allocations); + vkd3d_free(output_allocator.allocations); + } +@@ -6356,11 +6881,33 @@ static void allocate_objects(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl + } + } + ++static void allocate_stream_outputs(struct hlsl_ctx *ctx) ++{ ++ struct hlsl_ir_var *var; ++ uint32_t index = 0; ++ ++ LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) ++ { ++ if (!var->data_type->reg_size[HLSL_REGSET_STREAM_OUTPUTS]) ++ continue; ++ ++ /* We should have ensured that all stream output objects are single-element. */ ++ VKD3D_ASSERT(var->data_type->reg_size[HLSL_REGSET_STREAM_OUTPUTS] == 1); ++ ++ var->regs[HLSL_REGSET_STREAM_OUTPUTS].space = 0; ++ var->regs[HLSL_REGSET_STREAM_OUTPUTS].index = index; ++ var->regs[HLSL_REGSET_STREAM_OUTPUTS].id = index; ++ var->regs[HLSL_REGSET_STREAM_OUTPUTS].allocated = true; ++ ++ ++index; ++ } ++} ++ + bool hlsl_component_index_range_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref, unsigned int *start, unsigned int *count) { struct hlsl_type *type = deref->var->data_type; @@ -20707,7 +22240,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 *start = 0; *count = 0; -@@ -6368,49 +6883,18 @@ bool hlsl_component_index_range_from_deref(struct hlsl_ctx *ctx, const struct hl +@@ -6368,49 +6915,18 @@ bool hlsl_component_index_range_from_deref(struct hlsl_ctx *ctx, const struct hl for (i = 0; i < deref->path_len; ++i) { struct hlsl_ir_node *path_node = deref->path[i].node; @@ -20723,8 +22256,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 - && path_node->data_type->e.numeric.type == HLSL_TYPE_UINT); - - idx = hlsl_ir_constant(path_node)->value.u[0].u; -+ VKD3D_ASSERT(hlsl_is_vec1(path_node->data_type) && path_node->data_type->e.numeric.type == HLSL_TYPE_UINT); - +- - switch (type->class) - { - case HLSL_CLASS_VECTOR: @@ -20747,7 +22279,8 @@ index 2afd3e1e1e5..ba56ba90403 100644 - return false; - *start += idx * hlsl_type_component_count(type->e.array.type); - break; -- ++ VKD3D_ASSERT(hlsl_is_vec1(path_node->data_type) && path_node->data_type->e.numeric.type == HLSL_TYPE_UINT); + - case HLSL_CLASS_STRUCT: - for (k = 0; k < idx; ++k) - *start += hlsl_type_component_count(type->e.record.fields[k].type); @@ -20762,7 +22295,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 type = hlsl_get_element_type_from_path_index(ctx, type, path_node); } -@@ -6439,8 +6923,7 @@ bool hlsl_regset_index_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref +@@ -6439,8 +6955,7 @@ bool hlsl_regset_index_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref if (path_node->type == HLSL_IR_CONSTANT) { /* We should always have generated a cast to UINT. */ @@ -20772,7 +22305,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 idx = hlsl_ir_constant(path_node)->value.u[0].u; -@@ -6502,14 +6985,13 @@ bool hlsl_offset_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref +@@ -6502,14 +7017,13 @@ bool hlsl_offset_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref *offset = deref->const_offset; @@ -20789,7 +22322,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 VKD3D_ASSERT(offset_node->type != HLSL_IR_CONSTANT); return false; } -@@ -6544,11 +7026,14 @@ struct hlsl_reg hlsl_reg_from_deref(struct hlsl_ctx *ctx, const struct hlsl_dere +@@ -6544,11 +7058,14 @@ struct hlsl_reg hlsl_reg_from_deref(struct hlsl_ctx *ctx, const struct hlsl_dere { const struct hlsl_ir_var *var = deref->var; struct hlsl_reg ret = var->regs[HLSL_REGSET_NUMERIC]; @@ -20805,7 +22338,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 ret.index += offset / 4; ret.id += offset / 4; -@@ -6559,6 +7044,36 @@ struct hlsl_reg hlsl_reg_from_deref(struct hlsl_ctx *ctx, const struct hlsl_dere +@@ -6559,6 +7076,36 @@ struct hlsl_reg hlsl_reg_from_deref(struct hlsl_ctx *ctx, const struct hlsl_dere return ret; } @@ -20842,14 +22375,16 @@ index 2afd3e1e1e5..ba56ba90403 100644 static const char *get_string_argument_value(struct hlsl_ctx *ctx, const struct hlsl_attribute *attr, unsigned int i) { const struct hlsl_ir_node *instr = attr->args[i].node; -@@ -6594,36 +7109,17 @@ static void parse_numthreads_attribute(struct hlsl_ctx *ctx, const struct hlsl_a +@@ -6594,36 +7141,17 @@ static void parse_numthreads_attribute(struct hlsl_ctx *ctx, const struct hlsl_a for (i = 0; i < attr->args_count; ++i) { - const struct hlsl_ir_node *instr = attr->args[i].node; - const struct hlsl_type *type = instr->data_type; - const struct hlsl_ir_constant *constant; -- ++ enum hlsl_base_type base_type; ++ int value; + - if (type->class != HLSL_CLASS_SCALAR - || (type->e.numeric.type != HLSL_TYPE_INT && type->e.numeric.type != HLSL_TYPE_UINT)) - { @@ -20862,9 +22397,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 - hlsl_release_string_buffer(ctx, string); - break; - } -+ enum hlsl_base_type base_type; -+ int value; - +- - if (instr->type != HLSL_IR_CONSTANT) - { - hlsl_fixme(ctx, &instr->loc, "Non-constant expression in [numthreads] initializer."); @@ -20886,7 +22419,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 } } -@@ -6655,9 +7151,8 @@ static void parse_domain_attribute(struct hlsl_ctx *ctx, const struct hlsl_attri +@@ -6655,9 +7183,8 @@ static void parse_domain_attribute(struct hlsl_ctx *ctx, const struct hlsl_attri static void parse_outputcontrolpoints_attribute(struct hlsl_ctx *ctx, const struct hlsl_attribute *attr) { @@ -20898,7 +22431,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 if (attr->args_count != 1) { -@@ -6666,35 +7161,14 @@ static void parse_outputcontrolpoints_attribute(struct hlsl_ctx *ctx, const stru +@@ -6666,35 +7193,14 @@ static void parse_outputcontrolpoints_attribute(struct hlsl_ctx *ctx, const stru return; } @@ -20938,7 +22471,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 } static void parse_outputtopology_attribute(struct hlsl_ctx *ctx, const struct hlsl_attribute *attr) -@@ -6788,6 +7262,28 @@ static void parse_patchconstantfunc_attribute(struct hlsl_ctx *ctx, const struct +@@ -6788,6 +7294,28 @@ static void parse_patchconstantfunc_attribute(struct hlsl_ctx *ctx, const struct "Patch constant function \"%s\" is not defined.", name); } @@ -20967,7 +22500,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 static void parse_entry_function_attributes(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func) { const struct hlsl_profile_info *profile = ctx->profile; -@@ -6812,6 +7308,8 @@ static void parse_entry_function_attributes(struct hlsl_ctx *ctx, struct hlsl_ir +@@ -6812,6 +7340,8 @@ static void parse_entry_function_attributes(struct hlsl_ctx *ctx, struct hlsl_ir parse_patchconstantfunc_attribute(ctx, attr); else if (!strcmp(attr->name, "earlydepthstencil") && profile->type == VKD3D_SHADER_TYPE_PIXEL) entry_func->early_depth_test = true; @@ -20976,7 +22509,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 else hlsl_warning(ctx, &entry_func->attrs[i]->loc, VKD3D_SHADER_WARNING_HLSL_UNKNOWN_ATTRIBUTE, "Ignoring unknown attribute \"%s\".", entry_func->attrs[i]->name); -@@ -6884,7 +7382,71 @@ static void validate_hull_shader_attributes(struct hlsl_ctx *ctx, const struct h +@@ -6884,7 +7414,71 @@ static void validate_hull_shader_attributes(struct hlsl_ctx *ctx, const struct h } } @@ -21049,7 +22582,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 { unsigned int control_point_count = var->data_type->e.array.elements_count; enum hlsl_array_type array_type = var->data_type->e.array.array_type; -@@ -6902,7 +7464,7 @@ static void validate_and_record_patch_type(struct hlsl_ctx *ctx, struct hlsl_ir_ +@@ -6902,7 +7496,7 @@ static void validate_and_record_patch_type(struct hlsl_ctx *ctx, struct hlsl_ir_ return; } } @@ -21058,7 +22591,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 { if (!ctx->is_patch_constant_func && profile->type != VKD3D_SHADER_TYPE_DOMAIN) { -@@ -6913,6 +7475,30 @@ static void validate_and_record_patch_type(struct hlsl_ctx *ctx, struct hlsl_ir_ +@@ -6913,6 +7507,30 @@ static void validate_and_record_patch_type(struct hlsl_ctx *ctx, struct hlsl_ir_ } } @@ -21089,7 +22622,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 if (control_point_count > 32) { hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_CONTROL_POINT_COUNT, -@@ -6925,7 +7511,7 @@ static void validate_and_record_patch_type(struct hlsl_ctx *ctx, struct hlsl_ir_ +@@ -6925,7 +7543,7 @@ static void validate_and_record_patch_type(struct hlsl_ctx *ctx, struct hlsl_ir_ { if (control_point_count != ctx->output_control_point_count) hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_CONTROL_POINT_COUNT, @@ -21098,7 +22631,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 control_point_count, ctx->output_control_point_count); if (!hlsl_types_are_equal(control_point_type, ctx->output_control_point_type)) -@@ -6937,22 +7523,32 @@ static void validate_and_record_patch_type(struct hlsl_ctx *ctx, struct hlsl_ir_ +@@ -6937,22 +7555,90 @@ static void validate_and_record_patch_type(struct hlsl_ctx *ctx, struct hlsl_ir_ if (ctx->input_control_point_count != UINT_MAX) { @@ -21132,24 +22665,71 @@ index 2afd3e1e1e5..ba56ba90403 100644 ctx->input_control_point_count = control_point_count; ctx->input_control_point_type = control_point_type; + ctx->input_primitive_param = var; ++} ++ ++static void validate_and_record_stream_outputs(struct hlsl_ctx *ctx) ++{ ++ static const enum vkd3d_primitive_type prim_types[] = ++ { ++ [HLSL_STREAM_OUTPUT_POINT_STREAM] = VKD3D_PT_POINTLIST, ++ [HLSL_STREAM_OUTPUT_LINE_STREAM] = VKD3D_PT_LINESTRIP, ++ [HLSL_STREAM_OUTPUT_TRIANGLE_STREAM] = VKD3D_PT_TRIANGLESTRIP, ++ }; ++ ++ bool reported_non_point_multistream = false, reported_nonzero_index = false, reported_invalid_index = false; ++ enum hlsl_so_object_type so_type; ++ const struct hlsl_type *type; ++ struct hlsl_ir_var *var; ++ ++ LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) ++ { ++ if (!var->bind_count[HLSL_REGSET_STREAM_OUTPUTS]) ++ continue; ++ ++ type = hlsl_get_stream_output_type(var->data_type); ++ so_type = type->e.so.so_type; ++ ++ VKD3D_ASSERT(so_type < ARRAY_SIZE(prim_types)); ++ ++ if (ctx->output_topology_type == VKD3D_PT_UNDEFINED) ++ { ++ ctx->output_topology_type = prim_types[so_type]; ++ } ++ else ++ { ++ if ((so_type != HLSL_STREAM_OUTPUT_POINT_STREAM || ctx->output_topology_type != VKD3D_PT_POINTLIST) ++ && !reported_non_point_multistream) ++ { ++ hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, ++ "Multiple output streams are only allowed with PointStream objects."); ++ reported_non_point_multistream = true; ++ } ++ } ++ ++ if (var->regs[HLSL_REGSET_STREAM_OUTPUTS].index && hlsl_version_lt(ctx, 5, 0) && !reported_nonzero_index) ++ { ++ hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE, ++ "Multiple output streams are only supported in shader model 5.0 or higher."); ++ reported_nonzero_index = true; ++ } ++ ++ if (var->regs[HLSL_REGSET_STREAM_OUTPUTS].index >= VKD3D_MAX_STREAM_COUNT && !reported_invalid_index) ++ { ++ hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SIZE, ++ "Output stream index %u exceeds the maximum index %u.", ++ var->regs[HLSL_REGSET_STREAM_OUTPUTS].index, VKD3D_MAX_STREAM_COUNT - 1); ++ reported_invalid_index = true; ++ } ++ } ++ ++ /* TODO: check that maxvertexcount * outputdatasize <= 1024. */ } static void remove_unreachable_code(struct hlsl_ctx *ctx, struct hlsl_block *body) -@@ -7007,13 +7603,47 @@ static void remove_unreachable_code(struct hlsl_ctx *ctx, struct hlsl_block *bod - list_move_slice_tail(&block.instrs, start, list_tail(&body->instrs)); - hlsl_block_cleanup(&block); +@@ -7016,6 +7702,40 @@ void hlsl_lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_block *body) + lower_ir(ctx, lower_index_loads, body); + } -- break; -- } -+ break; -+ } -+} -+ -+void hlsl_lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_block *body) -+{ -+ lower_ir(ctx, lower_index_loads, body); -+} -+ + +static bool simplify_exprs(struct hlsl_ctx *ctx, struct hlsl_block *block) +{ @@ -21166,12 +22746,10 @@ index 2afd3e1e1e5..ba56ba90403 100644 + } while (progress); + + return any_progress; - } - --void hlsl_lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_block *body) ++} ++ +static void hlsl_run_folding_passes(struct hlsl_ctx *ctx, struct hlsl_block *body) - { -- lower_ir(ctx, lower_index_loads, body); ++{ + bool progress; + + hlsl_transform_ir(ctx, fold_redundant_casts, body, NULL); @@ -21184,10 +22762,12 @@ index 2afd3e1e1e5..ba56ba90403 100644 + progress |= hlsl_transform_ir(ctx, remove_trivial_conditional_branches, body, NULL); + } while (progress); + hlsl_transform_ir(ctx, fold_redundant_casts, body, NULL); - } - ++} ++ void hlsl_run_const_passes(struct hlsl_ctx *ctx, struct hlsl_block *body) -@@ -7035,32 +7665,24 @@ void hlsl_run_const_passes(struct hlsl_ctx *ctx, struct hlsl_block *body) + { + bool progress; +@@ -7035,32 +7755,24 @@ void hlsl_run_const_passes(struct hlsl_ctx *ctx, struct hlsl_block *body) lower_ir(ctx, lower_narrowing_casts, body); lower_ir(ctx, lower_int_dot, body); @@ -21227,7 +22807,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 unsigned int register_index, mask, use_mask; const char *name = var->semantic.name; enum vkd3d_shader_register_type type; -@@ -7073,7 +7695,7 @@ static void generate_vsir_signature_entry(struct hlsl_ctx *ctx, struct vsir_prog +@@ -7073,7 +7785,7 @@ static void generate_vsir_signature_entry(struct hlsl_ctx *ctx, struct vsir_prog bool has_idx, ret; ret = sm4_sysval_semantic_from_semantic_name(&sysval, &program->shader_version, ctx->semantic_compat_mapping, @@ -21236,7 +22816,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 VKD3D_ASSERT(ret); if (sysval == ~0u) return; -@@ -7109,6 +7731,7 @@ static void generate_vsir_signature_entry(struct hlsl_ctx *ctx, struct vsir_prog +@@ -7109,6 +7821,7 @@ static void generate_vsir_signature_entry(struct hlsl_ctx *ctx, struct vsir_prog break; case HLSL_TYPE_BOOL: @@ -21244,10 +22824,35 @@ index 2afd3e1e1e5..ba56ba90403 100644 case HLSL_TYPE_UINT: component_type = VKD3D_SHADER_COMPONENT_UINT; break; -@@ -7198,6 +7821,22 @@ static void generate_vsir_signature_entry(struct hlsl_ctx *ctx, struct vsir_prog +@@ -7134,7 +7847,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; +@@ -7151,6 +7864,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; +@@ -7197,7 +7912,28 @@ 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; +- 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) + { @@ -21267,7 +22872,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 } static void generate_vsir_signature(struct hlsl_ctx *ctx, -@@ -7265,6 +7904,7 @@ static enum vkd3d_data_type vsir_data_type_from_hlsl_type(struct hlsl_ctx *ctx, +@@ -7265,6 +8001,7 @@ static enum vkd3d_data_type vsir_data_type_from_hlsl_type(struct hlsl_ctx *ctx, return VKD3D_DATA_INT; case HLSL_TYPE_UINT: case HLSL_TYPE_BOOL: @@ -21275,7 +22880,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 return VKD3D_DATA_UINT; } } -@@ -7416,7 +8056,7 @@ static void sm1_generate_vsir_sampler_dcls(struct hlsl_ctx *ctx, +@@ -7416,7 +8153,7 @@ static void sm1_generate_vsir_sampler_dcls(struct hlsl_ctx *ctx, static enum vkd3d_shader_register_type sm4_get_semantic_register_type(enum vkd3d_shader_type shader_type, bool is_patch_constant_func, const struct hlsl_ir_var *var) { @@ -21284,7 +22889,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 { VKD3D_ASSERT(var->is_input_semantic); -@@ -7636,7 +8276,7 @@ static bool sm4_generate_vsir_reg_from_deref(struct hlsl_ctx *ctx, struct vsir_p +@@ -7636,7 +8373,7 @@ static bool sm4_generate_vsir_reg_from_deref(struct hlsl_ctx *ctx, struct vsir_p } else { @@ -21293,7 +22898,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 VKD3D_ASSERT(data_type->class <= HLSL_CLASS_VECTOR); reg->type = VKD3DSPR_CONSTBUFFER; -@@ -7654,19 +8294,27 @@ static bool sm4_generate_vsir_reg_from_deref(struct hlsl_ctx *ctx, struct vsir_p +@@ -7654,19 +8391,27 @@ static bool sm4_generate_vsir_reg_from_deref(struct hlsl_ctx *ctx, struct vsir_p reg->idx[1].offset = offset / 4; reg->idx_count = 2; } @@ -21323,7 +22928,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 if (has_idx) { -@@ -7688,12 +8336,12 @@ static bool sm4_generate_vsir_reg_from_deref(struct hlsl_ctx *ctx, struct vsir_p +@@ -7688,12 +8433,12 @@ static bool sm4_generate_vsir_reg_from_deref(struct hlsl_ctx *ctx, struct vsir_p reg->type = sm4_get_semantic_register_type(version->type, ctx->is_patch_constant_func, var); reg->dimension = VSIR_DIMENSION_VEC4; @@ -21339,7 +22944,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 { reg->idx[0].offset = deref->const_offset / 4; if (deref->rel_offset.node) -@@ -7750,7 +8398,8 @@ static bool sm4_generate_vsir_init_src_param_from_deref(struct hlsl_ctx *ctx, st +@@ -7750,7 +8495,8 @@ static bool sm4_generate_vsir_init_src_param_from_deref(struct hlsl_ctx *ctx, st if (!sm4_generate_vsir_reg_from_deref(ctx, program, &src_param->reg, &writemask, deref)) return false; @@ -21349,7 +22954,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 return true; } -@@ -7780,7 +8429,6 @@ static void sm1_generate_vsir_instr_constant(struct hlsl_ctx *ctx, +@@ -7780,7 +8526,6 @@ static void sm1_generate_vsir_instr_constant(struct hlsl_ctx *ctx, struct vsir_program *program, struct hlsl_ir_constant *constant) { struct hlsl_ir_node *instr = &constant->node; @@ -21357,7 +22962,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 struct vkd3d_shader_src_param *src_param; struct vkd3d_shader_instruction *ins; -@@ -7792,13 +8440,11 @@ static void sm1_generate_vsir_instr_constant(struct hlsl_ctx *ctx, +@@ -7792,13 +8537,11 @@ static void sm1_generate_vsir_instr_constant(struct hlsl_ctx *ctx, src_param = &ins->src[0]; vsir_register_init(&src_param->reg, VKD3DSPR_CONST, VKD3D_DATA_FLOAT, 1); @@ -21373,7 +22978,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 } static void sm4_generate_vsir_rasterizer_sample_count(struct hlsl_ctx *ctx, -@@ -7885,11 +8531,13 @@ static void sm1_generate_vsir_instr_expr_per_component_instr_op(struct hlsl_ctx +@@ -7885,11 +8628,13 @@ static void sm1_generate_vsir_instr_expr_per_component_instr_op(struct hlsl_ctx dst_param = &ins->dst[0]; vsir_register_init(&dst_param->reg, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1); dst_param->reg.idx[0].offset = instr->reg.id; @@ -21387,7 +22992,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 c = vsir_swizzle_get_component(src_swizzle, i); src_param->swizzle = vsir_swizzle_from_writemask(1u << c); } -@@ -7901,7 +8549,6 @@ static void sm1_generate_vsir_instr_expr_sincos(struct hlsl_ctx *ctx, struct vsi +@@ -7901,7 +8646,6 @@ static void sm1_generate_vsir_instr_expr_sincos(struct hlsl_ctx *ctx, struct vsi { struct hlsl_ir_node *operand = expr->operands[0].node; struct hlsl_ir_node *instr = &expr->node; @@ -21395,7 +23000,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 struct vkd3d_shader_src_param *src_param; struct vkd3d_shader_instruction *ins; unsigned int src_count = 0; -@@ -7912,25 +8559,20 @@ static void sm1_generate_vsir_instr_expr_sincos(struct hlsl_ctx *ctx, struct vsi +@@ -7912,25 +8656,20 @@ static void sm1_generate_vsir_instr_expr_sincos(struct hlsl_ctx *ctx, struct vsi if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_SINCOS, 1, src_count))) return; @@ -21426,7 +23031,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 src_param->reg.idx[0].offset = ctx->d3dsincosconst2.id; src_param->swizzle = VKD3D_SHADER_NO_SWIZZLE; } -@@ -7957,6 +8599,7 @@ static bool sm1_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx, +@@ -7957,6 +8696,7 @@ static bool sm1_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx, switch (src_type->e.numeric.type) { case HLSL_TYPE_INT: @@ -21434,7 +23039,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 case HLSL_TYPE_UINT: case HLSL_TYPE_BOOL: /* Integrals are internally represented as floats, so no change is necessary.*/ -@@ -7978,8 +8621,9 @@ static bool sm1_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx, +@@ -7978,8 +8718,9 @@ static bool sm1_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx, break; case HLSL_TYPE_INT: @@ -21445,7 +23050,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 { case HLSL_TYPE_HALF: case HLSL_TYPE_FLOAT: -@@ -7989,6 +8633,7 @@ static bool sm1_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx, +@@ -7989,6 +8730,7 @@ static bool sm1_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx, break; case HLSL_TYPE_INT: @@ -21453,7 +23058,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 case HLSL_TYPE_UINT: case HLSL_TYPE_BOOL: generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, 0, 0, true); -@@ -8004,13 +8649,8 @@ static bool sm1_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx, +@@ -8004,13 +8746,8 @@ static bool sm1_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx, switch (src_type->e.numeric.type) { case HLSL_TYPE_FLOAT: @@ -21469,17 +23074,17 @@ index 2afd3e1e1e5..ba56ba90403 100644 break; default: -@@ -8033,12 +8673,15 @@ static bool sm1_generate_vsir_instr_expr(struct hlsl_ctx *ctx, struct vsir_progr +@@ -8033,12 +8770,15 @@ static bool sm1_generate_vsir_instr_expr(struct hlsl_ctx *ctx, struct vsir_progr struct hlsl_ir_expr *expr) { struct hlsl_ir_node *instr = &expr->node; + struct hlsl_type *type = instr->data_type; ++ ++ if (!hlsl_is_numeric_type(type)) ++ goto err; - if (expr->op != HLSL_OP1_REINTERPRET && expr->op != HLSL_OP1_CAST - && instr->data_type->e.numeric.type != HLSL_TYPE_FLOAT) -+ if (!hlsl_is_numeric_type(type)) -+ goto err; -+ + if (type->e.numeric.type == HLSL_TYPE_DOUBLE && !ctx->double_as_float_alias) { - /* These need to be lowered. */ @@ -21489,7 +23094,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 return false; } -@@ -8053,30 +8696,44 @@ static bool sm1_generate_vsir_instr_expr(struct hlsl_ctx *ctx, struct vsir_progr +@@ -8053,30 +8793,44 @@ static bool sm1_generate_vsir_instr_expr(struct hlsl_ctx *ctx, struct vsir_progr case HLSL_OP1_COS_REDUCED: VKD3D_ASSERT(expr->node.reg.writemask == VKD3DSP_WRITEMASK_0); @@ -21534,7 +23139,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 sm1_generate_vsir_instr_expr_per_component_instr_op(ctx, program, expr, VKD3DSIH_RCP); break; -@@ -8085,23 +8742,33 @@ static bool sm1_generate_vsir_instr_expr(struct hlsl_ctx *ctx, struct vsir_progr +@@ -8085,23 +8839,33 @@ static bool sm1_generate_vsir_instr_expr(struct hlsl_ctx *ctx, struct vsir_progr break; case HLSL_OP1_RSQ: @@ -21568,7 +23173,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 switch (expr->operands[0].node->data_type->e.numeric.dimx) { case 3: -@@ -8135,35 +8802,49 @@ static bool sm1_generate_vsir_instr_expr(struct hlsl_ctx *ctx, struct vsir_progr +@@ -8135,35 +8899,49 @@ static bool sm1_generate_vsir_instr_expr(struct hlsl_ctx *ctx, struct vsir_progr break; case HLSL_OP2_LOGIC_AND: @@ -21621,7 +23226,16 @@ index 2afd3e1e1e5..ba56ba90403 100644 } static void sm1_generate_vsir_init_dst_param_from_deref(struct hlsl_ctx *ctx, -@@ -8213,19 +8894,68 @@ static void sm1_generate_vsir_init_dst_param_from_deref(struct hlsl_ctx *ctx, +@@ -8193,7 +8971,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; +@@ -8213,19 +8991,68 @@ static void sm1_generate_vsir_init_dst_param_from_deref(struct hlsl_ctx *ctx, else VKD3D_ASSERT(reg.allocated); @@ -21694,7 +23308,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 struct vkd3d_shader_version version; uint32_t register_index; unsigned int writemask; -@@ -8243,12 +8973,26 @@ static void sm1_generate_vsir_init_src_param_from_deref(struct hlsl_ctx *ctx, +@@ -8243,12 +9070,26 @@ static void sm1_generate_vsir_init_src_param_from_deref(struct hlsl_ctx *ctx, } else if (deref->var->is_uniform) { @@ -21725,7 +23339,16 @@ index 2afd3e1e1e5..ba56ba90403 100644 } else if (deref->var->is_input_semantic) { -@@ -8280,32 +9024,30 @@ static void sm1_generate_vsir_init_src_param_from_deref(struct hlsl_ctx *ctx, +@@ -8256,7 +9097,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; + } +@@ -8280,32 +9121,30 @@ static void sm1_generate_vsir_init_src_param_from_deref(struct hlsl_ctx *ctx, } vsir_register_init(&src_param->reg, type, VKD3D_DATA_FLOAT, 1); @@ -21766,7 +23389,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 } static void sm1_generate_vsir_instr_resource_load(struct hlsl_ctx *ctx, -@@ -8315,7 +9057,6 @@ static void sm1_generate_vsir_instr_resource_load(struct hlsl_ctx *ctx, +@@ -8315,7 +9154,6 @@ static void sm1_generate_vsir_instr_resource_load(struct hlsl_ctx *ctx, struct hlsl_ir_node *ddx = load->ddx.node; struct hlsl_ir_node *ddy = load->ddy.node; struct hlsl_ir_node *instr = &load->node; @@ -21774,7 +23397,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 struct vkd3d_shader_src_param *src_param; struct vkd3d_shader_instruction *ins; enum vkd3d_shader_opcode opcode; -@@ -8354,15 +9095,12 @@ static void sm1_generate_vsir_instr_resource_load(struct hlsl_ctx *ctx, +@@ -8354,15 +9192,12 @@ static void sm1_generate_vsir_instr_resource_load(struct hlsl_ctx *ctx, return; ins->flags = flags; @@ -21792,7 +23415,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 VKD3DSP_WRITEMASK_ALL, &ins->location); if (load->load_type == HLSL_RESOURCE_SAMPLE_GRAD) -@@ -8379,7 +9117,6 @@ static void generate_vsir_instr_swizzle(struct hlsl_ctx *ctx, +@@ -8379,7 +9214,6 @@ static void generate_vsir_instr_swizzle(struct hlsl_ctx *ctx, struct vsir_program *program, struct hlsl_ir_swizzle *swizzle_instr) { struct hlsl_ir_node *instr = &swizzle_instr->node, *val = swizzle_instr->val.node; @@ -21800,7 +23423,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 struct vkd3d_shader_src_param *src_param; struct vkd3d_shader_instruction *ins; uint32_t swizzle; -@@ -8389,11 +9126,7 @@ static void generate_vsir_instr_swizzle(struct hlsl_ctx *ctx, +@@ -8389,11 +9223,7 @@ static void generate_vsir_instr_swizzle(struct hlsl_ctx *ctx, if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_MOV, 1, 1))) return; @@ -21813,7 +23436,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 swizzle = hlsl_swizzle_from_writemask(val->reg.writemask); swizzle = hlsl_combine_swizzles(swizzle, swizzle_instr->u.vector, instr->data_type->e.numeric.dimx); -@@ -8429,7 +9162,6 @@ static void sm1_generate_vsir_instr_jump(struct hlsl_ctx *ctx, +@@ -8429,18 +9259,14 @@ static void sm1_generate_vsir_instr_jump(struct hlsl_ctx *ctx, { struct hlsl_ir_node *condition = jump->condition.node; struct hlsl_ir_node *instr = &jump->node; @@ -21821,19 +23444,20 @@ index 2afd3e1e1e5..ba56ba90403 100644 struct vkd3d_shader_instruction *ins; if (jump->type == HLSL_IR_JUMP_DISCARD_NEG) -@@ -8437,10 +9169,7 @@ static void sm1_generate_vsir_instr_jump(struct hlsl_ctx *ctx, - if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_TEXKILL, 1, 0))) + { +- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_TEXKILL, 1, 0))) ++ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_TEXKILL, 0, 1))) return; - dst_param = &ins->dst[0]; - vsir_register_init(&dst_param->reg, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1); - dst_param->reg.idx[0].offset = condition->reg.id; - dst_param->write_mask = condition->reg.writemask; -+ vsir_dst_from_hlsl_node(&ins->dst[0], ctx, condition); ++ vsir_src_from_hlsl_node(&ins->src[0], ctx, condition, VKD3DSP_WRITEMASK_ALL); } else { -@@ -8561,6 +9290,10 @@ static void sm1_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl +@@ -8561,6 +9387,10 @@ static void sm1_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl return; } @@ -21844,7 +23468,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 generate_vsir_signature(ctx, program, entry_func); hlsl_block_init(&block); -@@ -8650,6 +9383,10 @@ D3DXPARAMETER_TYPE hlsl_sm1_base_type(const struct hlsl_type *type, bool is_comb +@@ -8650,6 +9480,10 @@ D3DXPARAMETER_TYPE hlsl_sm1_base_type(const struct hlsl_type *type, bool is_comb case HLSL_TYPE_INT: case HLSL_TYPE_UINT: return D3DXPT_INT; @@ -21855,7 +23479,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 } break; -@@ -8934,6 +9671,7 @@ static void write_sm1_uniforms(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffe +@@ -8934,6 +9768,7 @@ static void write_sm1_uniforms(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffe uni.f = var->default_values[k].number.i; break; @@ -21863,7 +23487,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 case HLSL_TYPE_UINT: case HLSL_TYPE_BOOL: uni.f = var->default_values[k].number.u; -@@ -8977,7 +9715,7 @@ static void sm4_generate_vsir_instr_dcl_semantic(struct hlsl_ctx *ctx, struct vs +@@ -8977,7 +9812,7 @@ static void sm4_generate_vsir_instr_dcl_semantic(struct hlsl_ctx *ctx, struct vs const struct hlsl_ir_var *var, struct hlsl_block *block, const struct vkd3d_shader_location *loc) { const struct vkd3d_shader_version *version = &program->shader_version; @@ -21872,7 +23496,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 const bool output = var->is_output_semantic; enum vkd3d_shader_sysval_semantic semantic; struct vkd3d_shader_dst_param *dst_param; -@@ -8989,7 +9727,7 @@ static void sm4_generate_vsir_instr_dcl_semantic(struct hlsl_ctx *ctx, struct vs +@@ -8989,7 +9824,7 @@ static void sm4_generate_vsir_instr_dcl_semantic(struct hlsl_ctx *ctx, struct vs bool has_idx; sm4_sysval_semantic_from_semantic_name(&semantic, version, ctx->semantic_compat_mapping, ctx->domain, @@ -21881,7 +23505,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 if (semantic == ~0u) semantic = VKD3D_SHADER_SV_NONE; -@@ -9002,9 +9740,17 @@ static void sm4_generate_vsir_instr_dcl_semantic(struct hlsl_ctx *ctx, struct vs +@@ -9002,9 +9837,17 @@ static void sm4_generate_vsir_instr_dcl_semantic(struct hlsl_ctx *ctx, struct vs ? VKD3DSIH_DCL_INPUT_PS : VKD3DSIH_DCL_INPUT; break; @@ -21900,7 +23524,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 case VKD3D_SHADER_SV_SAMPLE_INDEX: case VKD3D_SHADER_SV_VERTEX_ID: opcode = (version->type == VKD3D_SHADER_TYPE_PIXEL) -@@ -9014,7 +9760,7 @@ static void sm4_generate_vsir_instr_dcl_semantic(struct hlsl_ctx *ctx, struct vs +@@ -9014,7 +9857,7 @@ static void sm4_generate_vsir_instr_dcl_semantic(struct hlsl_ctx *ctx, struct vs default: if (version->type == VKD3D_SHADER_TYPE_PIXEL) opcode = VKD3DSIH_DCL_INPUT_PS_SIV; @@ -21909,7 +23533,16 @@ index 2afd3e1e1e5..ba56ba90403 100644 opcode = VKD3DSIH_DCL_INPUT; else opcode = VKD3DSIH_DCL_INPUT_SIV; -@@ -9055,7 +9801,7 @@ static void sm4_generate_vsir_instr_dcl_semantic(struct hlsl_ctx *ctx, struct vs +@@ -9024,7 +9867,7 @@ static void sm4_generate_vsir_instr_dcl_semantic(struct hlsl_ctx *ctx, struct vs + else + { + if (semantic == VKD3D_SHADER_SV_NONE || version->type == VKD3D_SHADER_TYPE_PIXEL +- || version->type == VKD3D_SHADER_TYPE_HULL) ++ || (version->type == VKD3D_SHADER_TYPE_HULL && !ctx->is_patch_constant_func)) + opcode = VKD3DSIH_DCL_OUTPUT; + else + opcode = VKD3DSIH_DCL_OUTPUT_SIV; +@@ -9055,7 +9898,7 @@ static void sm4_generate_vsir_instr_dcl_semantic(struct hlsl_ctx *ctx, struct vs } else if (opcode == VKD3DSIH_DCL_INPUT || opcode == VKD3DSIH_DCL_INPUT_PS) { @@ -21918,7 +23551,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 dst_param = &ins->declaration.dst; } else -@@ -9066,7 +9812,7 @@ static void sm4_generate_vsir_instr_dcl_semantic(struct hlsl_ctx *ctx, struct vs +@@ -9066,7 +9909,7 @@ static void sm4_generate_vsir_instr_dcl_semantic(struct hlsl_ctx *ctx, struct vs dst_param = &ins->declaration.register_semantic.reg; } @@ -21927,7 +23560,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 { VKD3D_ASSERT(has_idx); vsir_register_init(&dst_param->reg, type, VKD3D_DATA_FLOAT, 2); -@@ -9127,13 +9873,6 @@ static bool type_is_float(const struct hlsl_type *type) +@@ -9127,13 +9970,6 @@ static bool type_is_float(const struct hlsl_type *type) return type->e.numeric.type == HLSL_TYPE_FLOAT || type->e.numeric.type == HLSL_TYPE_HALF; } @@ -21941,7 +23574,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 static void sm4_generate_vsir_cast_from_bool(struct hlsl_ctx *ctx, struct vsir_program *program, const struct hlsl_ir_expr *expr, uint32_t bits) { -@@ -9188,6 +9927,7 @@ static bool sm4_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx, +@@ -9188,6 +10024,7 @@ static bool sm4_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx, generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_ITOF, 0, 0, true); return true; @@ -21949,7 +23582,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 case HLSL_TYPE_UINT: generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_UTOF, 0, 0, true); return true; -@@ -9211,6 +9951,7 @@ static bool sm4_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx, +@@ -9211,6 +10048,7 @@ static bool sm4_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx, return true; case HLSL_TYPE_INT: @@ -21957,7 +23590,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 case HLSL_TYPE_UINT: generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, 0, 0, true); return true; -@@ -9225,6 +9966,7 @@ static bool sm4_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx, +@@ -9225,6 +10063,7 @@ static bool sm4_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx, } break; @@ -21965,7 +23598,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 case HLSL_TYPE_UINT: switch (src_type->e.numeric.type) { -@@ -9234,6 +9976,7 @@ static bool sm4_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx, +@@ -9234,6 +10073,7 @@ static bool sm4_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx, return true; case HLSL_TYPE_INT: @@ -21973,7 +23606,28 @@ index 2afd3e1e1e5..ba56ba90403 100644 case HLSL_TYPE_UINT: generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, 0, 0, true); return true; -@@ -9339,7 +10082,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, +@@ -9263,8 +10103,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; + +@@ -9282,9 +10122,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); +@@ -9339,7 +10177,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, return true; case HLSL_OP1_BIT_NOT: @@ -21982,7 +23636,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_NOT, 0, 0, true); return true; -@@ -9431,6 +10174,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, +@@ -9431,6 +10269,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, return true; case HLSL_TYPE_INT: @@ -21990,7 +23644,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 case HLSL_TYPE_UINT: generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_INEG, 0, 0, true); return true; -@@ -9498,6 +10242,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, +@@ -9498,6 +10337,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, return true; case HLSL_TYPE_INT: @@ -21998,7 +23652,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 case HLSL_TYPE_UINT: generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_IADD, 0, 0, true); return true; -@@ -9508,17 +10253,17 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, +@@ -9508,17 +10348,17 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, } case HLSL_OP2_BIT_AND: @@ -22019,7 +23673,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_XOR, 0, 0, true); return true; -@@ -9529,6 +10274,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, +@@ -9529,6 +10369,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DIV, 0, 0, true); return true; @@ -22027,7 +23681,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 case HLSL_TYPE_UINT: sm4_generate_vsir_expr_with_two_destinations(ctx, program, VKD3DSIH_UDIV, expr, 0); return true; -@@ -9577,6 +10323,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, +@@ -9577,6 +10418,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, case HLSL_TYPE_BOOL: case HLSL_TYPE_INT: @@ -22035,7 +23689,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 case HLSL_TYPE_UINT: generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_IEQ, 0, 0, true); return true; -@@ -9601,6 +10348,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, +@@ -9601,6 +10443,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, return true; case HLSL_TYPE_BOOL: @@ -22043,7 +23697,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 case HLSL_TYPE_UINT: generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_UGE, 0, 0, true); return true; -@@ -9625,6 +10373,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, +@@ -9625,6 +10468,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, return true; case HLSL_TYPE_BOOL: @@ -22051,7 +23705,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 case HLSL_TYPE_UINT: generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_ULT, 0, 0, true); return true; -@@ -9646,7 +10395,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, +@@ -9646,7 +10490,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, return true; case HLSL_OP2_LSHIFT: @@ -22060,7 +23714,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 VKD3D_ASSERT(dst_type->e.numeric.type != HLSL_TYPE_BOOL); generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_ISHL, 0, 0, true); return true; -@@ -9659,6 +10408,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, +@@ -9659,6 +10503,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, return true; case HLSL_TYPE_INT: @@ -22068,7 +23722,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 case HLSL_TYPE_UINT: generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_IMAD, 0, 0, true); return true; -@@ -9679,6 +10429,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, +@@ -9679,6 +10524,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_IMAX, 0, 0, true); return true; @@ -22076,7 +23730,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 case HLSL_TYPE_UINT: generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_UMAX, 0, 0, true); return true; -@@ -9699,6 +10450,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, +@@ -9699,6 +10545,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_IMIN, 0, 0, true); return true; @@ -22084,7 +23738,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 case HLSL_TYPE_UINT: generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_UMIN, 0, 0, true); return true; -@@ -9711,6 +10463,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, +@@ -9711,6 +10558,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, case HLSL_OP2_MOD: switch (dst_type->e.numeric.type) { @@ -22092,7 +23746,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 case HLSL_TYPE_UINT: sm4_generate_vsir_expr_with_two_destinations(ctx, program, VKD3DSIH_UDIV, expr, 1); return true; -@@ -9728,6 +10481,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, +@@ -9728,6 +10576,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, return true; case HLSL_TYPE_INT: @@ -22100,7 +23754,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 case HLSL_TYPE_UINT: /* Using IMUL instead of UMUL because we're taking the low * bits, and the native compiler generates IMUL. */ -@@ -9750,6 +10504,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, +@@ -9750,6 +10599,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, case HLSL_TYPE_BOOL: case HLSL_TYPE_INT: @@ -22108,7 +23762,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 case HLSL_TYPE_UINT: generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_INE, 0, 0, true); return true; -@@ -9761,7 +10516,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, +@@ -9761,7 +10611,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, } case HLSL_OP2_RSHIFT: @@ -22117,7 +23771,20 @@ index 2afd3e1e1e5..ba56ba90403 100644 VKD3D_ASSERT(dst_type->e.numeric.type != HLSL_TYPE_BOOL); generate_vsir_instr_expr_single_instr_op(ctx, program, expr, dst_type->e.numeric.type == HLSL_TYPE_INT ? VKD3DSIH_ISHR : VKD3DSIH_USHR, 0, 0, true); -@@ -10840,12 +11595,32 @@ static void generate_vsir_scan_required_features(struct hlsl_ctx *ctx, struct vs +@@ -9866,6 +10716,12 @@ static bool sm4_generate_vsir_instr_resource_store(struct hlsl_ctx *ctx, + struct vkd3d_shader_instruction *ins; + unsigned int writemask; + ++ if (store->store_type != HLSL_RESOURCE_STORE) ++ { ++ hlsl_fixme(ctx, &instr->loc, "Stream output operations."); ++ return false; ++ } ++ + if (!store->resource.var->is_uniform) + { + hlsl_fixme(ctx, &store->node.loc, "Store to non-uniform resource variable."); +@@ -10840,12 +11696,32 @@ static void generate_vsir_scan_required_features(struct hlsl_ctx *ctx, struct vs * STENCIL_REF, and TYPED_UAV_LOAD_ADDITIONAL_FORMATS. */ } @@ -22150,7 +23817,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 extern_resources = sm4_get_extern_resources(ctx, &extern_resources_count); -@@ -10866,6 +11641,25 @@ static void generate_vsir_scan_global_flags(struct hlsl_ctx *ctx, +@@ -10866,6 +11742,25 @@ static void generate_vsir_scan_global_flags(struct hlsl_ctx *ctx, sm4_free_extern_resources(extern_resources, extern_resources_count); @@ -22176,7 +23843,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 if (entry_func->early_depth_test && vkd3d_shader_ver_ge(version, 5, 0)) program->global_flags |= VKD3DSGF_FORCE_EARLY_DEPTH_STENCIL; } -@@ -10994,6 +11788,7 @@ static enum vkd3d_data_type sm4_generate_vsir_get_format_type(const struct hlsl_ +@@ -10994,6 +11889,7 @@ static enum vkd3d_data_type sm4_generate_vsir_get_format_type(const struct hlsl_ return VKD3D_DATA_INT; case HLSL_TYPE_BOOL: @@ -22184,7 +23851,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 case HLSL_TYPE_UINT: return VKD3D_DATA_UINT; } -@@ -11153,6 +11948,13 @@ static void sm4_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl +@@ -11153,6 +12049,13 @@ static void sm4_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl ? 0 : ctx->input_control_point_count; program->tess_domain = ctx->domain; } @@ -22192,13 +23859,13 @@ index 2afd3e1e1e5..ba56ba90403 100644 + { + program->input_control_point_count = ctx->input_control_point_count; + program->input_primitive = ctx->input_primitive_type; -+ program->output_topology = VKD3D_PT_UNDEFINED; /* TODO: obtain from stream output parameters. */ ++ program->output_topology = ctx->output_topology_type; + program->vertices_out_count = ctx->max_vertex_count; + } LIST_FOR_EACH_ENTRY(cbuffer, &ctx->buffers, struct hlsl_buffer, entry) { -@@ -11288,6 +12090,7 @@ static enum D3D_RESOURCE_RETURN_TYPE sm4_data_type(const struct hlsl_type *type) +@@ -11288,6 +12191,7 @@ static enum D3D_RESOURCE_RETURN_TYPE sm4_data_type(const struct hlsl_type *type) break; case HLSL_TYPE_BOOL: @@ -22206,7 +23873,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 case HLSL_TYPE_UINT: return D3D_RETURN_TYPE_UINT; } -@@ -11373,6 +12176,8 @@ static D3D_SHADER_VARIABLE_TYPE sm4_base_type(const struct hlsl_type *type) +@@ -11373,6 +12277,8 @@ static D3D_SHADER_VARIABLE_TYPE sm4_base_type(const struct hlsl_type *type) return D3D_SVT_INT; case HLSL_TYPE_UINT: return D3D_SVT_UINT; @@ -22215,7 +23882,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 } vkd3d_unreachable(); -@@ -11696,16 +12501,13 @@ static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rd +@@ -11696,16 +12602,13 @@ static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rd static bool loop_unrolling_generate_const_bool_store(struct hlsl_ctx *ctx, struct hlsl_ir_var *var, bool val, struct hlsl_block *block, struct vkd3d_shader_location *loc) { @@ -22234,7 +23901,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 return true; } -@@ -11759,19 +12561,13 @@ static bool loop_unrolling_remove_jumps_visit(struct hlsl_ctx *ctx, struct hlsl_ +@@ -11759,19 +12662,13 @@ static bool loop_unrolling_remove_jumps_visit(struct hlsl_ctx *ctx, struct hlsl_ static struct hlsl_ir_if *loop_unrolling_generate_var_check(struct hlsl_ctx *ctx, struct hlsl_block *dst, struct hlsl_ir_var *var, struct vkd3d_shader_location *loc) { @@ -22257,7 +23924,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 if (!(iff = hlsl_new_if(ctx, cond, &then_block, NULL, loc))) return NULL; -@@ -11850,9 +12646,7 @@ static void loop_unrolling_simplify(struct hlsl_ctx *ctx, struct hlsl_block *blo +@@ -11850,9 +12747,7 @@ static void loop_unrolling_simplify(struct hlsl_ctx *ctx, struct hlsl_block *blo copy_propagation_pop_scope(state); copy_propagation_push_scope(state, ctx); @@ -22268,7 +23935,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 current_index = index_instructions(block, *index); progress |= copy_propagation_transform_block(ctx, block, state); -@@ -12113,10 +12907,9 @@ static void loop_unrolling_execute(struct hlsl_ctx *ctx, struct hlsl_block *bloc +@@ -12113,10 +13008,9 @@ static void loop_unrolling_execute(struct hlsl_ctx *ctx, struct hlsl_block *bloc static bool lower_f16tof32(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_block *block) { @@ -22280,7 +23947,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 struct hlsl_ir_expr *expr; struct hlsl_ir_var *lhs; char *body; -@@ -12179,28 +12972,21 @@ static bool lower_f16tof32(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, stru +@@ -12179,28 +13073,21 @@ static bool lower_f16tof32(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, stru return false; lhs = func->parameters.vars[0]; @@ -22312,7 +23979,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 struct hlsl_ir_expr *expr; struct hlsl_ir_var *lhs; char *body; -@@ -12251,30 +13037,22 @@ static bool lower_f32tof16(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, stru +@@ -12251,30 +13138,22 @@ static bool lower_f32tof16(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, stru return false; lhs = func->parameters.vars[0]; @@ -22346,7 +24013,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 const char *template; char *body; -@@ -12327,7 +13105,7 @@ static bool lower_isinf(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct +@@ -12327,7 +13206,7 @@ static bool lower_isinf(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct template = template_sm2; else if (hlsl_version_lt(ctx, 4, 0)) template = template_sm3; @@ -22355,7 +24022,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 template = template_int; else template = template_sm4; -@@ -12339,20 +13117,13 @@ static bool lower_isinf(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct +@@ -12339,20 +13218,13 @@ static bool lower_isinf(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct if (!(func = hlsl_compile_internal_function(ctx, "isinf", body))) return false; @@ -22378,7 +24045,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 return true; } -@@ -12366,6 +13137,7 @@ static void process_entry_function(struct hlsl_ctx *ctx, +@@ -12366,6 +13238,7 @@ static void process_entry_function(struct hlsl_ctx *ctx, struct recursive_call_ctx recursive_call_ctx; struct hlsl_ir_var *var; unsigned int i; @@ -22386,7 +24053,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 ctx->is_patch_constant_func = entry_func == ctx->patch_constant_func; -@@ -12418,41 +13190,61 @@ static void process_entry_function(struct hlsl_ctx *ctx, +@@ -12418,41 +13291,59 @@ static void process_entry_function(struct hlsl_ctx *ctx, else prepend_uniform_copy(ctx, body, var); } @@ -22450,7 +24117,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 + validate_and_record_prim_type(ctx, var); + prepend_input_var_copy(ctx, entry_func, var); + } -+ else if (hlsl_get_stream_output_type(var->data_type)) ++ else if (var->data_type->reg_size[HLSL_REGSET_STREAM_OUTPUTS]) + { + if (profile->type != VKD3D_SHADER_TYPE_GEOMETRY) { @@ -22465,13 +24132,11 @@ index 2afd3e1e1e5..ba56ba90403 100644 + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, + "Stream output parameter \"%s\" must be declared as \"inout\".", var->name); + -+ /* TODO: check that maxvertexcount * component_count(element_type) <= 1024. */ -+ -+ continue; ++ prepend_uniform_copy(ctx, body, var); } else { -@@ -12465,12 +13257,24 @@ static void process_entry_function(struct hlsl_ctx *ctx, +@@ -12465,12 +13356,24 @@ static void process_entry_function(struct hlsl_ctx *ctx, } if (var->storage_modifiers & HLSL_STORAGE_IN) @@ -22496,7 +24161,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 else append_output_var_copy(ctx, entry_func, var); } -@@ -12478,7 +13282,11 @@ static void process_entry_function(struct hlsl_ctx *ctx, +@@ -12478,7 +13381,11 @@ static void process_entry_function(struct hlsl_ctx *ctx, } if (entry_func->return_var) { @@ -22509,7 +24174,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 hlsl_error(ctx, &entry_func->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_SEMANTIC, "Entry point \"%s\" is missing a return value semantic.", entry_func->func->name); -@@ -12493,6 +13301,10 @@ static void process_entry_function(struct hlsl_ctx *ctx, +@@ -12493,6 +13400,10 @@ static void process_entry_function(struct hlsl_ctx *ctx, hlsl_fixme(ctx, &entry_func->loc, "Passthrough hull shader control point function."); } @@ -22520,7 +24185,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 if (hlsl_version_ge(ctx, 4, 0)) { hlsl_transform_ir(ctx, lower_discard_neg, body, NULL); -@@ -12503,6 +13315,9 @@ static void process_entry_function(struct hlsl_ctx *ctx, +@@ -12503,6 +13414,9 @@ static void process_entry_function(struct hlsl_ctx *ctx, hlsl_transform_ir(ctx, lower_resource_load_bias, body, NULL); } @@ -22530,7 +24195,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 loop_unrolling_execute(ctx, body); hlsl_run_const_passes(ctx, body); -@@ -12517,6 +13332,17 @@ static void process_entry_function(struct hlsl_ctx *ctx, +@@ -12517,6 +13431,17 @@ static void process_entry_function(struct hlsl_ctx *ctx, hlsl_transform_ir(ctx, lower_separate_samples, body, NULL); hlsl_transform_ir(ctx, validate_dereferences, body, NULL); @@ -22548,7 +24213,18 @@ index 2afd3e1e1e5..ba56ba90403 100644 hlsl_transform_ir(ctx, track_object_components_sampler_dim, body, NULL); if (hlsl_version_ge(ctx, 4, 0)) -@@ -12537,14 +13363,14 @@ static void process_entry_function(struct hlsl_ctx *ctx, +@@ -12532,19 +13457,25 @@ static void process_entry_function(struct hlsl_ctx *ctx, + else + sort_synthetic_separated_samplers_first(ctx); + ++ if (profile->type == VKD3D_SHADER_TYPE_GEOMETRY) ++ { ++ allocate_stream_outputs(ctx); ++ validate_and_record_stream_outputs(ctx); ++ } ++ + if (profile->major_version < 4) + { while (lower_ir(ctx, lower_nonconstant_array_loads, body)); lower_ir(ctx, lower_ternary, body); @@ -22566,7 +24242,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 lower_ir(ctx, lower_sqrt, body); lower_ir(ctx, lower_dot, body); lower_ir(ctx, lower_round, body); -@@ -12566,13 +13392,15 @@ static void process_entry_function(struct hlsl_ctx *ctx, +@@ -12566,13 +13497,15 @@ static void process_entry_function(struct hlsl_ctx *ctx, lower_ir(ctx, validate_nonconstant_vector_store_derefs, body); @@ -22583,7 +24259,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 transform_derefs(ctx, clean_constant_deref_offset_srcs, body); do -@@ -12608,6 +13436,9 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry +@@ -12608,6 +13541,9 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry else if (profile->type == VKD3D_SHADER_TYPE_DOMAIN && ctx->domain == VKD3D_TESSELLATOR_DOMAIN_INVALID) hlsl_error(ctx, &entry_func->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_ATTRIBUTE, "Entry point \"%s\" is missing a [domain] attribute.", entry_func->func->name); @@ -22593,7 +24269,7 @@ index 2afd3e1e1e5..ba56ba90403 100644 hlsl_block_init(&global_uniform_block); -@@ -12633,7 +13464,6 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry +@@ -12633,7 +13569,6 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry if (profile->major_version < 4) { mark_indexable_vars(ctx, entry_func); @@ -22928,7 +24604,7 @@ index 538f0f46854..f74ecffcd4b 100644 bool hlsl_fold_constant_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c -index b608fae21ac..72cf53761e4 100644 +index b608fae21ac..4101e92e91f 100644 --- a/libs/vkd3d/libs/vkd3d-shader/ir.c +++ b/libs/vkd3d/libs/vkd3d-shader/ir.c @@ -116,6 +116,7 @@ void vsir_program_cleanup(struct vsir_program *program) @@ -22939,7 +24615,21 @@ index b608fae21ac..72cf53761e4 100644 } const struct vkd3d_shader_parameter1 *vsir_program_get_parameter( -@@ -469,6 +470,80 @@ static bool get_opcode_from_rel_op(enum vkd3d_shader_rel_op rel_op, enum vkd3d_d +@@ -311,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); +@@ -469,6 +477,80 @@ static bool get_opcode_from_rel_op(enum vkd3d_shader_rel_op rel_op, enum vkd3d_d return false; } @@ -23020,7 +24710,7 @@ index b608fae21ac..72cf53761e4 100644 static enum vkd3d_result vsir_program_lower_ifc(struct vsir_program *program, struct vkd3d_shader_instruction *ifc, unsigned int *tmp_idx, struct vkd3d_shader_message_context *message_context) -@@ -481,6 +556,7 @@ static enum vkd3d_result vsir_program_lower_ifc(struct vsir_program *program, +@@ -481,6 +563,7 @@ static enum vkd3d_result vsir_program_lower_ifc(struct vsir_program *program, if (!shader_instruction_array_insert_at(instructions, pos + 1, 2)) return VKD3D_ERROR_OUT_OF_MEMORY; @@ -23028,7 +24718,7 @@ index b608fae21ac..72cf53761e4 100644 if (*tmp_idx == ~0u) *tmp_idx = program->temp_count++; -@@ -534,6 +610,7 @@ static enum vkd3d_result vsir_program_lower_texkill(struct vsir_program *program +@@ -534,11 +617,12 @@ static enum vkd3d_result vsir_program_lower_texkill(struct vsir_program *program if (!shader_instruction_array_insert_at(instructions, pos + 1, components_read + 1)) return VKD3D_ERROR_OUT_OF_MEMORY; @@ -23036,7 +24726,22 @@ index b608fae21ac..72cf53761e4 100644 if (*tmp_idx == ~0u) *tmp_idx = program->temp_count++; -@@ -620,6 +697,7 @@ static enum vkd3d_result vsir_program_lower_precise_mad(struct vsir_program *pro + +- /* tmp = ins->dst[0] < 0 */ ++ /* tmp = ins->src[0] < 0 */ + + ins = &instructions->elements[pos + 1]; + if (!vsir_instruction_init_with_params(program, ins, &texkill->location, VKD3DSIH_LTO, 1, 2)) +@@ -549,7 +633,7 @@ static enum vkd3d_result vsir_program_lower_texkill(struct vsir_program *program + ins->dst[0].reg.idx[0].offset = *tmp_idx; + ins->dst[0].write_mask = VKD3DSP_WRITEMASK_ALL; + +- ins->src[0].reg = texkill->dst[0].reg; ++ ins->src[0].reg = texkill->src[0].reg; + ins->src[0].swizzle = VKD3D_SHADER_NO_SWIZZLE; + vsir_register_init(&ins->src[1].reg, VKD3DSPR_IMMCONST, VKD3D_DATA_FLOAT, 0); + ins->src[1].reg.dimension = VSIR_DIMENSION_VEC4; +@@ -620,6 +704,7 @@ static enum vkd3d_result vsir_program_lower_precise_mad(struct vsir_program *pro if (!shader_instruction_array_insert_at(instructions, pos + 1, 1)) return VKD3D_ERROR_OUT_OF_MEMORY; @@ -23044,7 +24749,7 @@ index b608fae21ac..72cf53761e4 100644 if (*tmp_idx == ~0u) *tmp_idx = program->temp_count++; -@@ -664,6 +742,7 @@ static enum vkd3d_result vsir_program_lower_sm1_sincos(struct vsir_program *prog +@@ -664,6 +749,7 @@ static enum vkd3d_result vsir_program_lower_sm1_sincos(struct vsir_program *prog if (!shader_instruction_array_insert_at(instructions, pos + 1, 1)) return VKD3D_ERROR_OUT_OF_MEMORY; @@ -23052,7 +24757,25 @@ index b608fae21ac..72cf53761e4 100644 ins = &instructions->elements[pos + 1]; -@@ -716,6 +795,7 @@ static enum vkd3d_result vsir_program_lower_texldp(struct vsir_program *program, +@@ -684,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) +@@ -694,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 */ +@@ -716,6 +802,7 @@ static enum vkd3d_result vsir_program_lower_texldp(struct vsir_program *program, if (!shader_instruction_array_insert_at(instructions, pos + 1, 2)) return VKD3D_ERROR_OUT_OF_MEMORY; @@ -23060,7 +24783,7 @@ index b608fae21ac..72cf53761e4 100644 if (*tmp_idx == ~0u) *tmp_idx = program->temp_count++; -@@ -1127,6 +1207,7 @@ static enum vkd3d_result vsir_program_ensure_diffuse(struct vsir_program *progra +@@ -1127,6 +1214,7 @@ static enum vkd3d_result vsir_program_ensure_diffuse(struct vsir_program *progra if (!shader_instruction_array_insert_at(&program->instructions, i, 1)) return VKD3D_ERROR_OUT_OF_MEMORY; ins = &program->instructions.elements[i]; @@ -23068,7 +24791,16 @@ index b608fae21ac..72cf53761e4 100644 vsir_instruction_init_with_params(program, ins, &no_loc, VKD3DSIH_MOV, 1, 1); vsir_dst_param_init(&ins->dst[0], VKD3DSPR_ATTROUT, VKD3D_DATA_FLOAT, 1); ins->dst[0].reg.idx[0].offset = 0; -@@ -1345,7 +1426,6 @@ static enum vkd3d_result vsir_program_remap_output_signature(struct vsir_program +@@ -1218,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); + } + } + +@@ -1345,7 +1433,6 @@ static enum vkd3d_result vsir_program_remap_output_signature(struct vsir_program loc = ins->location; if (!shader_instruction_array_insert_at(&program->instructions, i, uninit_varying_count)) return VKD3D_ERROR_OUT_OF_MEMORY; @@ -23076,7 +24808,7 @@ index b608fae21ac..72cf53761e4 100644 ins = &program->instructions.elements[i]; for (unsigned int j = signature->element_count - uninit_varying_count; j < signature->element_count; ++j) -@@ -1732,8 +1812,20 @@ static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_i +@@ -1732,8 +1819,20 @@ static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_i return VKD3D_OK; } @@ -23097,7 +24829,7 @@ index b608fae21ac..72cf53761e4 100644 struct vkd3d_shader_instruction_array instructions; enum vkd3d_shader_type shader_type; uint8_t major; -@@ -1751,9 +1843,9 @@ struct io_normaliser +@@ -1751,9 +1850,9 @@ struct io_normaliser struct vkd3d_shader_dst_param *input_dcl_params[MAX_REG_OUTPUT]; struct vkd3d_shader_dst_param *output_dcl_params[MAX_REG_OUTPUT]; struct vkd3d_shader_dst_param *pc_dcl_params[MAX_REG_OUTPUT]; @@ -23110,7 +24842,7 @@ index b608fae21ac..72cf53761e4 100644 bool use_vocp; }; -@@ -1794,36 +1886,44 @@ struct signature_element *vsir_signature_find_element_for_reg(const struct shade +@@ -1794,36 +1893,44 @@ struct signature_element *vsir_signature_find_element_for_reg(const struct shade return NULL; } @@ -23169,7 +24901,7 @@ index b608fae21ac..72cf53761e4 100644 for (i = 0; i < register_count; ++i) { -@@ -1834,21 +1934,31 @@ static void range_map_set_register_range(uint8_t range_map[][VKD3D_VEC4_SIZE], u +@@ -1834,21 +1941,31 @@ static void range_map_set_register_range(uint8_t range_map[][VKD3D_VEC4_SIZE], u /* A synthetic patch constant range which overlaps an existing range can start upstream of it * for fork/join phase instancing, but ranges declared by dcl_indexrange should not overlap. * The latter is validated in the TPF reader. */ @@ -23207,7 +24939,7 @@ index b608fae21ac..72cf53761e4 100644 switch (reg->type) { -@@ -1879,9 +1989,21 @@ static void io_normaliser_add_index_range(struct io_normaliser *normaliser, +@@ -1879,9 +1996,21 @@ static void io_normaliser_add_index_range(struct io_normaliser *normaliser, } reg_idx = reg->idx[reg->idx_count - 1].offset; @@ -23232,7 +24964,7 @@ index b608fae21ac..72cf53761e4 100644 } static int signature_element_mask_compare(const void *a, const void *b) -@@ -1908,11 +2030,12 @@ static bool sysval_semantics_should_merge(const struct signature_element *e, con +@@ -1908,11 +2037,12 @@ static bool sysval_semantics_should_merge(const struct signature_element *e, con } /* Merge tess factor sysvals because they are an array in SPIR-V. */ @@ -23248,13 +24980,13 @@ index b608fae21ac..72cf53761e4 100644 qsort(s->elements, s->element_count, sizeof(s->elements[0]), signature_element_mask_compare); -@@ -1933,8 +2056,12 @@ static void shader_signature_map_patch_constant_index_ranges(struct shader_signa +@@ -1933,8 +2063,12 @@ static void shader_signature_map_patch_constant_index_ranges(struct shader_signa if (register_count < 2) continue; - range_map_set_register_range(range_map, e->register_index, register_count, e->mask, false); + if ((ret = range_map_set_register_range(normaliser, range_map, -+ e->register_index, register_count, e->mask, e->used_mask, false) < 0)) ++ e->register_index, register_count, e->mask, e->used_mask, false)) < 0) + return ret; } + @@ -23262,7 +24994,7 @@ index b608fae21ac..72cf53761e4 100644 } static int signature_element_register_compare(const void *a, const void *b) -@@ -1977,62 +2104,19 @@ static int signature_element_index_compare(const void *a, const void *b) +@@ -1977,62 +2111,19 @@ static int signature_element_index_compare(const void *a, const void *b) return vkd3d_u32_compare(e->sort_index, f->sort_index); } @@ -23329,7 +25061,7 @@ index b608fae21ac..72cf53761e4 100644 if (element_count) memcpy(elements, s->elements, element_count * sizeof(*elements)); -@@ -2091,42 +2175,49 @@ static bool shader_signature_merge(struct shader_signature *s, uint8_t range_map +@@ -2091,42 +2182,49 @@ static bool shader_signature_merge(struct shader_signature *s, uint8_t range_map s->elements = elements; s->element_count = element_count; @@ -23389,16 +25121,16 @@ index b608fae21ac..72cf53761e4 100644 +out: /* Restoring the original order is required for sensible trace output. */ - qsort(elements, element_count, sizeof(elements[0]), signature_element_index_compare); -- -- s->element_count = element_count; + qsort(s->elements, s->element_count, sizeof(elements[0]), signature_element_index_compare); +- s->element_count = element_count; +- - return true; + return ret; } static unsigned int shader_register_normalise_arrayed_addressing(struct vkd3d_shader_register *reg, -@@ -2342,8 +2433,9 @@ static void shader_instruction_normalise_io_params(struct vkd3d_shader_instructi +@@ -2342,8 +2440,9 @@ static void shader_instruction_normalise_io_params(struct vkd3d_shader_instructi static enum vkd3d_result vsir_program_normalise_io_registers(struct vsir_program *program, struct vsir_transformation_context *ctx) { @@ -23409,7 +25141,7 @@ index b608fae21ac..72cf53761e4 100644 unsigned int i; VKD3D_ASSERT(program->normalisation_level == VSIR_NORMALISED_HULL_CONTROL_POINT_IO); -@@ -2365,7 +2457,8 @@ static enum vkd3d_result vsir_program_normalise_io_registers(struct vsir_program +@@ -2365,7 +2464,8 @@ static enum vkd3d_result vsir_program_normalise_io_registers(struct vsir_program normaliser.output_control_point_count = ins->declaration.count; break; case VKD3DSIH_DCL_INDEX_RANGE: @@ -23419,7 +25151,7 @@ index b608fae21ac..72cf53761e4 100644 vkd3d_shader_instruction_make_nop(ins); break; case VKD3DSIH_HS_CONTROL_POINT_PHASE: -@@ -2378,12 +2471,14 @@ static enum vkd3d_result vsir_program_normalise_io_registers(struct vsir_program +@@ -2378,12 +2478,14 @@ static enum vkd3d_result vsir_program_normalise_io_registers(struct vsir_program } } @@ -23438,7 +25170,7 @@ index b608fae21ac..72cf53761e4 100644 } normaliser.phase = VKD3DSIH_INVALID; -@@ -2410,7 +2505,8 @@ struct flat_constants_normaliser +@@ -2410,7 +2512,8 @@ struct flat_constants_normaliser }; static bool get_flat_constant_register_type(const struct vkd3d_shader_register *reg, @@ -23448,7 +25180,7 @@ index b608fae21ac..72cf53761e4 100644 { static const struct { -@@ -2430,12 +2526,8 @@ static bool get_flat_constant_register_type(const struct vkd3d_shader_register * +@@ -2430,12 +2533,8 @@ static bool get_flat_constant_register_type(const struct vkd3d_shader_register * { if (reg->type == regs[i].type) { @@ -23463,7 +25195,7 @@ index b608fae21ac..72cf53761e4 100644 *set = regs[i].set; *index = reg->idx[0].offset; return true; -@@ -2449,10 +2541,11 @@ static void shader_register_normalise_flat_constants(struct vkd3d_shader_src_par +@@ -2449,10 +2548,11 @@ static void shader_register_normalise_flat_constants(struct vkd3d_shader_src_par const struct flat_constants_normaliser *normaliser) { enum vkd3d_shader_d3dbc_constant_register set; @@ -23476,7 +25208,7 @@ index b608fae21ac..72cf53761e4 100644 return; for (i = 0; i < normaliser->def_count; ++i) -@@ -2470,8 +2563,11 @@ static void shader_register_normalise_flat_constants(struct vkd3d_shader_src_par +@@ -2470,8 +2570,11 @@ static void shader_register_normalise_flat_constants(struct vkd3d_shader_src_par param->reg.type = VKD3DSPR_CONSTBUFFER; param->reg.idx[0].offset = set; /* register ID */ @@ -23488,7 +25220,7 @@ index b608fae21ac..72cf53761e4 100644 param->reg.idx_count = 3; } -@@ -2498,7 +2594,7 @@ static enum vkd3d_result vsir_program_normalise_flat_constants(struct vsir_progr +@@ -2498,7 +2601,7 @@ static enum vkd3d_result vsir_program_normalise_flat_constants(struct vsir_progr def = &normaliser.defs[normaliser.def_count++]; @@ -23497,7 +25229,7 @@ index b608fae21ac..72cf53761e4 100644 for (j = 0; j < 4; ++j) def->value[j] = ins->src[0].reg.u.immconst_u32[j]; -@@ -6021,6 +6117,7 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr +@@ -6021,6 +6124,7 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr uint32_t colour_temp, size_t *ret_pos, struct vkd3d_shader_message_context *message_context) { struct vkd3d_shader_instruction_array *instructions = &program->instructions; @@ -23505,7 +25237,7 @@ index b608fae21ac..72cf53761e4 100644 static const struct vkd3d_shader_location no_loc; size_t pos = ret - instructions->elements; struct vkd3d_shader_instruction *ins; -@@ -6045,9 +6142,10 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr +@@ -6045,9 +6149,10 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr { if (!shader_instruction_array_insert_at(&program->instructions, pos, 1)) return VKD3D_ERROR_OUT_OF_MEMORY; @@ -23517,7 +25249,7 @@ index b608fae21ac..72cf53761e4 100644 ins->flags = VKD3D_SHADER_CONDITIONAL_OP_Z; src_param_init_const_uint(&ins->src[0], 0); -@@ -6057,20 +6155,20 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr +@@ -6057,20 +6162,20 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr if (!shader_instruction_array_insert_at(&program->instructions, pos, 3)) return VKD3D_ERROR_OUT_OF_MEMORY; @@ -23541,7 +25273,7 @@ index b608fae21ac..72cf53761e4 100644 src_param_init_temp_uint(&ins->src[opcodes[compare_func].swap ? 1 : 0], colour_temp); src_param_init_parameter(&ins->src[opcodes[compare_func].swap ? 0 : 1], VKD3D_SHADER_PARAMETER_NAME_ALPHA_TEST_REF, VKD3D_DATA_UINT); -@@ -6091,14 +6189,14 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr +@@ -6091,14 +6196,14 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr ins->src[opcodes[compare_func].swap ? 1 : 0].swizzle = VKD3D_SHADER_SWIZZLE(W, W, W, W); ++ins; @@ -23558,7 +25290,7 @@ index b608fae21ac..72cf53761e4 100644 vsir_dst_param_init(&ins->dst[0], VKD3DSPR_OUTPUT, VKD3D_DATA_FLOAT, 1); ins->dst[0].reg.idx[0].offset = colour_signature_idx; ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; -@@ -6199,13 +6297,14 @@ static enum vkd3d_result insert_clip_planes_before_ret(struct vsir_program *prog +@@ -6199,13 +6304,14 @@ static enum vkd3d_result insert_clip_planes_before_ret(struct vsir_program *prog uint32_t position_temp, uint32_t low_signature_idx, uint32_t high_signature_idx, size_t *ret_pos) { struct vkd3d_shader_instruction_array *instructions = &program->instructions; @@ -23574,7 +25306,7 @@ index b608fae21ac..72cf53761e4 100644 ins = &program->instructions.elements[pos]; for (unsigned int i = 0; i < 8; ++i) -@@ -6213,7 +6312,7 @@ static enum vkd3d_result insert_clip_planes_before_ret(struct vsir_program *prog +@@ -6213,7 +6319,7 @@ static enum vkd3d_result insert_clip_planes_before_ret(struct vsir_program *prog if (!(mask & (1u << i))) continue; @@ -23583,7 +25315,7 @@ index b608fae21ac..72cf53761e4 100644 src_param_init_temp_float4(&ins->src[0], position_temp); src_param_init_parameter(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_CLIP_PLANE_0 + i, VKD3D_DATA_FLOAT); ins->src[1].swizzle = VKD3D_SHADER_NO_SWIZZLE; -@@ -6231,7 +6330,7 @@ static enum vkd3d_result insert_clip_planes_before_ret(struct vsir_program *prog +@@ -6231,7 +6337,7 @@ static enum vkd3d_result insert_clip_planes_before_ret(struct vsir_program *prog ++ins; } @@ -23592,7 +25324,7 @@ index b608fae21ac..72cf53761e4 100644 vsir_dst_param_init(&ins->dst[0], VKD3DSPR_OUTPUT, VKD3D_DATA_FLOAT, 1); ins->dst[0].reg.idx[0].offset = position_signature_idx; ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; -@@ -6388,15 +6487,16 @@ static enum vkd3d_result insert_point_size_before_ret(struct vsir_program *progr +@@ -6388,15 +6494,16 @@ static enum vkd3d_result insert_point_size_before_ret(struct vsir_program *progr const struct vkd3d_shader_instruction *ret, size_t *ret_pos) { struct vkd3d_shader_instruction_array *instructions = &program->instructions; @@ -23611,7 +25343,7 @@ index b608fae21ac..72cf53761e4 100644 vsir_dst_param_init(&ins->dst[0], VKD3DSPR_RASTOUT, VKD3D_DATA_FLOAT, 1); ins->dst[0].reg.idx[0].offset = VSIR_RASTOUT_POINT_SIZE; src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_POINT_SIZE, VKD3D_DATA_FLOAT); -@@ -6525,9 +6625,9 @@ static enum vkd3d_result vsir_program_insert_point_size_clamp(struct vsir_progra +@@ -6525,9 +6632,9 @@ static enum vkd3d_result vsir_program_insert_point_size_clamp(struct vsir_progra if (!shader_instruction_array_insert_at(&program->instructions, i + 1, !!min_parameter + !!max_parameter)) return VKD3D_ERROR_OUT_OF_MEMORY; @@ -23622,7 +25354,7 @@ index b608fae21ac..72cf53761e4 100644 if (min_parameter) { -@@ -6725,7 +6825,6 @@ static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *pr +@@ -6725,7 +6832,6 @@ static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *pr { if (!shader_instruction_array_insert_at(&program->instructions, insert_pos, 2)) return VKD3D_ERROR_OUT_OF_MEMORY; @@ -23630,7 +25362,7 @@ index b608fae21ac..72cf53761e4 100644 ins = &program->instructions.elements[insert_pos]; vsir_instruction_init_with_params(program, ins, &no_loc, VKD3DSIH_MOV, 1, 1); -@@ -6799,6 +6898,8 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro +@@ -6799,6 +6905,8 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro */ if (!shader_instruction_array_insert_at(&program->instructions, pos, 4)) return VKD3D_ERROR_OUT_OF_MEMORY; @@ -23639,7 +25371,7 @@ index b608fae21ac..72cf53761e4 100644 *ret_pos = pos + 4; ssa_temp = program->ssa_count++; -@@ -6829,6 +6930,8 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro +@@ -6829,6 +6937,8 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro */ if (!shader_instruction_array_insert_at(&program->instructions, pos, 4)) return VKD3D_ERROR_OUT_OF_MEMORY; @@ -23648,7 +25380,7 @@ index b608fae21ac..72cf53761e4 100644 *ret_pos = pos + 4; ssa_temp = program->ssa_count++; -@@ -6859,6 +6962,8 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro +@@ -6859,6 +6969,8 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro */ if (!shader_instruction_array_insert_at(&program->instructions, pos, 5)) return VKD3D_ERROR_OUT_OF_MEMORY; @@ -23657,7 +25389,7 @@ index b608fae21ac..72cf53761e4 100644 *ret_pos = pos + 5; ssa_temp = program->ssa_count++; -@@ -7037,16 +7142,18 @@ static enum vkd3d_result insert_vertex_fog_before_ret(struct vsir_program *progr +@@ -7037,16 +7149,18 @@ static enum vkd3d_result insert_vertex_fog_before_ret(struct vsir_program *progr { const struct signature_element *e = &program->output_signature.elements[source_signature_idx]; struct vkd3d_shader_instruction_array *instructions = &program->instructions; @@ -23677,7 +25409,7 @@ index b608fae21ac..72cf53761e4 100644 dst_param_init_output(&ins->dst[0], VKD3D_DATA_FLOAT, fog_signature_idx, 0x1); src_param_init_temp_float4(&ins->src[0], temp); if (source == VKD3D_SHADER_FOG_SOURCE_Z) -@@ -7056,7 +7163,7 @@ static enum vkd3d_result insert_vertex_fog_before_ret(struct vsir_program *progr +@@ -7056,7 +7170,7 @@ static enum vkd3d_result insert_vertex_fog_before_ret(struct vsir_program *progr ++ins; /* Write the position or specular output. */ @@ -23686,7 +25418,7 @@ index b608fae21ac..72cf53761e4 100644 dst_param_init_output(&ins->dst[0], vkd3d_data_type_from_component_type(e->component_type), source_signature_idx, e->mask); src_param_init_temp_float4(&ins->src[0], temp); -@@ -7691,6 +7798,54 @@ static void vsir_validate_label_register(struct validation_context *ctx, +@@ -7691,6 +7805,54 @@ static void vsir_validate_label_register(struct validation_context *ctx, reg->idx[0].offset, ctx->program->block_count); } @@ -23741,7 +25473,7 @@ index b608fae21ac..72cf53761e4 100644 static void vsir_validate_sampler_register(struct validation_context *ctx, const struct vkd3d_shader_register *reg) { -@@ -7714,9 +7869,7 @@ static void vsir_validate_sampler_register(struct validation_context *ctx, +@@ -7714,9 +7876,7 @@ static void vsir_validate_sampler_register(struct validation_context *ctx, return; } @@ -23752,7 +25484,7 @@ index b608fae21ac..72cf53761e4 100644 } static void vsir_validate_resource_register(struct validation_context *ctx, -@@ -7741,9 +7894,7 @@ static void vsir_validate_resource_register(struct validation_context *ctx, +@@ -7741,9 +7901,7 @@ static void vsir_validate_resource_register(struct validation_context *ctx, return; } @@ -23763,7 +25495,7 @@ index b608fae21ac..72cf53761e4 100644 } static void vsir_validate_uav_register(struct validation_context *ctx, -@@ -7773,9 +7924,7 @@ static void vsir_validate_uav_register(struct validation_context *ctx, +@@ -7773,9 +7931,7 @@ static void vsir_validate_uav_register(struct validation_context *ctx, return; } @@ -23774,7 +25506,7 @@ index b608fae21ac..72cf53761e4 100644 } static void vsir_validate_ssa_register(struct validation_context *ctx, -@@ -7928,6 +8077,10 @@ static void vsir_validate_register(struct validation_context *ctx, +@@ -7928,6 +8084,10 @@ static void vsir_validate_register(struct validation_context *ctx, vsir_validate_register_without_indices(ctx, reg); break; @@ -23785,7 +25517,22 @@ index b608fae21ac..72cf53761e4 100644 case VKD3DSPR_PRIMID: vsir_validate_register_without_indices(ctx, reg); break; -@@ -8115,6 +8268,8 @@ static void vsir_validate_dst_param(struct validation_context *ctx, +@@ -8095,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]; +@@ -8115,6 +8283,8 @@ static void vsir_validate_dst_param(struct validation_context *ctx, case VKD3DSPR_IMMCONST: case VKD3DSPR_IMMCONST64: @@ -23794,7 +25541,20 @@ index b608fae21ac..72cf53761e4 100644 case VKD3DSPR_SAMPLER: case VKD3DSPR_RESOURCE: validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE, -@@ -8505,10 +8660,13 @@ static void vsir_validate_signature_element(struct validation_context *ctx, +@@ -8187,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: +@@ -8505,10 +8678,13 @@ static void vsir_validate_signature_element(struct validation_context *ctx, { case VKD3D_SHADER_COMPONENT_INT: case VKD3D_SHADER_COMPONENT_UINT: @@ -23808,7 +25568,62 @@ index b608fae21ac..72cf53761e4 100644 break; default: -@@ -9776,6 +9934,9 @@ enum vkd3d_result vsir_program_transform(struct vsir_program *program, uint64_t +@@ -8684,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) +@@ -9650,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; + +@@ -9776,6 +9993,9 @@ enum vkd3d_result vsir_program_transform(struct vsir_program *program, uint64_t if (program->shader_version.major <= 2) vsir_transform(&ctx, vsir_program_ensure_diffuse); @@ -23819,27 +25634,765 @@ index b608fae21ac..72cf53761e4 100644 vsir_transform(&ctx, vsir_program_remap_output_signature); diff --git a/libs/vkd3d/libs/vkd3d-shader/msl.c b/libs/vkd3d/libs/vkd3d-shader/msl.c -index e783128e236..a5d952cd525 100644 +index e783128e236..4f37468af86 100644 --- a/libs/vkd3d/libs/vkd3d-shader/msl.c +++ b/libs/vkd3d/libs/vkd3d-shader/msl.c -@@ -44,7 +44,6 @@ struct msl_generator +@@ -18,6 +18,13 @@ + + #include "vkd3d_shader_private.h" + ++enum msl_data_type ++{ ++ MSL_DATA_FLOAT, ++ MSL_DATA_UINT, ++ MSL_DATA_UNION, ++}; ++ + struct msl_src + { + struct vkd3d_string_buffer *str; +@@ -44,7 +51,14 @@ struct msl_generator bool write_depth; const struct vkd3d_shader_interface_info *interface_info; - const struct vkd3d_shader_scan_descriptor_info1 *descriptor_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, -@@ -821,7 +820,7 @@ static void msl_generate_cbv_declaration(struct msl_generator *gen, +@@ -58,6 +72,30 @@ static void VKD3D_PRINTF_FUNC(3, 4) msl_compiler_error(struct msl_generator *gen + gen->failed = true; + } - static void msl_generate_descriptor_struct_declarations(struct msl_generator *gen) ++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) +@@ -84,6 +122,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) + { +@@ -107,15 +169,119 @@ static void msl_print_register_datatype(struct vkd3d_string_buffer *buffer, + } + } + +-static void msl_print_register_name(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 enum msl_data_type msl_print_register_name(struct vkd3d_string_buffer *buffer, + struct msl_generator *gen, const struct vkd3d_shader_register *reg) + { + switch (reg->type) + { + case VKD3DSPR_TEMP: + vkd3d_string_buffer_printf(buffer, "r[%u]", reg->idx[0].offset); +- msl_print_register_datatype(buffer, gen, reg->data_type); +- break; ++ return MSL_DATA_UNION; + + case VKD3DSPR_INPUT: + if (reg->idx_count != 1) +@@ -123,18 +289,17 @@ static void msl_print_register_name(struct vkd3d_string_buffer *buffer, + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled input register index count %u.", reg->idx_count); + vkd3d_string_buffer_printf(buffer, "", reg->type); +- break; ++ return MSL_DATA_UNION; + } + if (reg->idx[0].rel_addr) + { + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled input register indirect addressing."); + vkd3d_string_buffer_printf(buffer, "", reg->type); +- break; ++ return MSL_DATA_UNION; + } + vkd3d_string_buffer_printf(buffer, "v[%u]", reg->idx[0].offset); +- msl_print_register_datatype(buffer, gen, reg->data_type); +- break; ++ return MSL_DATA_UNION; + + case VKD3DSPR_OUTPUT: + if (reg->idx_count != 1) +@@ -142,18 +307,17 @@ static void msl_print_register_name(struct vkd3d_string_buffer *buffer, + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled output register index count %u.", reg->idx_count); + vkd3d_string_buffer_printf(buffer, "", reg->type); +- break; ++ return MSL_DATA_UNION; + } + if (reg->idx[0].rel_addr) + { + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled output register indirect addressing."); + vkd3d_string_buffer_printf(buffer, "", reg->type); +- break; ++ return MSL_DATA_UNION; + } + vkd3d_string_buffer_printf(buffer, "o[%u]", reg->idx[0].offset); +- msl_print_register_datatype(buffer, gen, reg->data_type); +- break; ++ return MSL_DATA_UNION; + + case VKD3DSPR_DEPTHOUT: + if (gen->program->shader_version.type != VKD3D_SHADER_TYPE_PIXEL) +@@ -161,89 +325,64 @@ static void msl_print_register_name(struct vkd3d_string_buffer *buffer, + "Internal compiler error: Unhandled depth output in shader type #%x.", + gen->program->shader_version.type); + vkd3d_string_buffer_printf(buffer, "o_depth"); +- break; ++ return MSL_DATA_FLOAT; + + case VKD3DSPR_IMMCONST: + switch (reg->dimension) + { + case VSIR_DIMENSION_SCALAR: +- switch (reg->data_type) +- { +- case VKD3D_DATA_INT: +- vkd3d_string_buffer_printf(buffer, "as_type(%#xu)", reg->u.immconst_u32[0]); +- break; +- case VKD3D_DATA_UINT: +- vkd3d_string_buffer_printf(buffer, "%#xu", reg->u.immconst_u32[0]); +- break; +- case VKD3D_DATA_FLOAT: +- vkd3d_string_buffer_printf(buffer, "as_type(%#xu)", reg->u.immconst_u32[0]); +- break; +- default: +- msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, +- "Internal compiler error: Unhandled immconst datatype %#x.", reg->data_type); +- vkd3d_string_buffer_printf(buffer, "", reg->data_type); +- break; +- } +- break; ++ vkd3d_string_buffer_printf(buffer, "%#xu", reg->u.immconst_u32[0]); ++ return MSL_DATA_UINT; + + case VSIR_DIMENSION_VEC4: +- switch (reg->data_type) +- { +- case VKD3D_DATA_INT: +- vkd3d_string_buffer_printf(buffer, "as_type(uint4(%#xu, %#xu, %#xu, %#xu))", +- reg->u.immconst_u32[0], reg->u.immconst_u32[1], +- reg->u.immconst_u32[2], reg->u.immconst_u32[3]); +- break; +- case VKD3D_DATA_UINT: +- vkd3d_string_buffer_printf(buffer, "uint4(%#xu, %#xu, %#xu, %#xu)", +- reg->u.immconst_u32[0], reg->u.immconst_u32[1], +- reg->u.immconst_u32[2], reg->u.immconst_u32[3]); +- break; +- case VKD3D_DATA_FLOAT: +- vkd3d_string_buffer_printf(buffer, "as_type(uint4(%#xu, %#xu, %#xu, %#xu))", +- reg->u.immconst_u32[0], reg->u.immconst_u32[1], +- reg->u.immconst_u32[2], reg->u.immconst_u32[3]); +- break; +- default: +- msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, +- "Internal compiler error: Unhandled immconst datatype %#x.", reg->data_type); +- vkd3d_string_buffer_printf(buffer, "", reg->data_type); +- break; +- } +- break; ++ vkd3d_string_buffer_printf(buffer, "uint4(%#xu, %#xu, %#xu, %#xu)", ++ reg->u.immconst_u32[0], reg->u.immconst_u32[1], ++ reg->u.immconst_u32[2], reg->u.immconst_u32[3]); ++ return MSL_DATA_UINT; + + default: + vkd3d_string_buffer_printf(buffer, "", reg->dimension); + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled dimension %#x.", reg->dimension); +- break; ++ return MSL_DATA_UINT; + } +- 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); +- break; ++ 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); ++ return MSL_DATA_UNION; ++ } ++ 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); ++ return MSL_DATA_UNION; ++ } ++ 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); ++ return MSL_DATA_UNION; ++ } ++ msl_print_cbv_name(buffer, binding->binding); ++ vkd3d_string_buffer_printf(buffer, "[%u]", reg->idx[2].offset); ++ return MSL_DATA_UNION; + } +- 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, + "Internal compiler error: Unhandled register type %#x.", reg->type); + vkd3d_string_buffer_printf(buffer, "", reg->type); +- break; ++ return MSL_DATA_UINT; + } + } + +@@ -278,24 +417,64 @@ static void msl_src_cleanup(struct msl_src *src, struct vkd3d_string_buffer_cach + vkd3d_string_buffer_release(cache, src->str); + } + +-static void msl_src_init(struct msl_src *msl_src, struct msl_generator *gen, +- const struct vkd3d_shader_src_param *vsir_src, uint32_t mask) ++static void msl_print_bitcast(struct vkd3d_string_buffer *dst, struct msl_generator *gen, const char *src, ++ enum vkd3d_data_type dst_data_type, enum msl_data_type src_data_type, enum vsir_dimension dimension) ++{ ++ bool write_cast = false; ++ ++ if (dst_data_type == VKD3D_DATA_UNORM || dst_data_type == VKD3D_DATA_SNORM) ++ dst_data_type = VKD3D_DATA_FLOAT; ++ ++ switch (src_data_type) ++ { ++ case MSL_DATA_FLOAT: ++ write_cast = dst_data_type != VKD3D_DATA_FLOAT; ++ break; ++ ++ case MSL_DATA_UINT: ++ write_cast = dst_data_type != VKD3D_DATA_UINT; ++ break; ++ ++ case MSL_DATA_UNION: ++ break; ++ } ++ ++ if (write_cast) ++ { ++ vkd3d_string_buffer_printf(dst, "as_type<"); ++ msl_print_resource_datatype(gen, dst, dst_data_type); ++ vkd3d_string_buffer_printf(dst, "%s>(", dimension == VSIR_DIMENSION_VEC4 ? "4" : ""); ++ } ++ ++ vkd3d_string_buffer_printf(dst, "%s", src); ++ ++ if (write_cast) ++ vkd3d_string_buffer_printf(dst, ")"); ++ ++ if (src_data_type == MSL_DATA_UNION) ++ msl_print_register_datatype(dst, gen, dst_data_type); ++} ++ ++static void msl_print_src_with_type(struct vkd3d_string_buffer *buffer, struct msl_generator *gen, ++ const struct vkd3d_shader_src_param *vsir_src, uint32_t mask, enum vkd3d_data_type data_type) + { + const struct vkd3d_shader_register *reg = &vsir_src->reg; +- struct vkd3d_string_buffer *str; ++ struct vkd3d_string_buffer *register_name, *str; ++ enum msl_data_type src_data_type; + +- msl_src->str = vkd3d_string_buffer_get(&gen->string_buffers); ++ register_name = vkd3d_string_buffer_get(&gen->string_buffers); + + if (reg->non_uniform) + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled 'non-uniform' modifier."); + + if (!vsir_src->modifiers) +- str = msl_src->str; ++ str = buffer; + else + str = vkd3d_string_buffer_get(&gen->string_buffers); + +- msl_print_register_name(str, gen, reg); ++ src_data_type = msl_print_register_name(register_name, gen, reg); ++ msl_print_bitcast(str, gen, register_name->buffer, data_type, src_data_type, reg->dimension); + if (reg->dimension == VSIR_DIMENSION_VEC4) + msl_print_swizzle(str, vsir_src->swizzle, mask); + +@@ -304,23 +483,30 @@ static void msl_src_init(struct msl_src *msl_src, struct msl_generator *gen, + case VKD3DSPSM_NONE: + break; + case VKD3DSPSM_NEG: +- vkd3d_string_buffer_printf(msl_src->str, "-%s", str->buffer); ++ vkd3d_string_buffer_printf(buffer, "-%s", str->buffer); + break; + case VKD3DSPSM_ABS: +- vkd3d_string_buffer_printf(msl_src->str, "abs(%s)", str->buffer); ++ vkd3d_string_buffer_printf(buffer, "abs(%s)", str->buffer); + break; + default: +- vkd3d_string_buffer_printf(msl_src->str, "(%s)", ++ vkd3d_string_buffer_printf(buffer, "(%s)", + vsir_src->modifiers, str->buffer); + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled source modifier(s) %#x.", vsir_src->modifiers); + break; + } + +- if (str != msl_src->str) ++ if (str != buffer) + vkd3d_string_buffer_release(&gen->string_buffers, str); + } + ++static void msl_src_init(struct msl_src *msl_src, struct msl_generator *gen, ++ const struct vkd3d_shader_src_param *vsir_src, uint32_t mask) ++{ ++ msl_src->str = vkd3d_string_buffer_get(&gen->string_buffers); ++ msl_print_src_with_type(msl_src->str, gen, vsir_src, mask, vsir_src->reg.data_type); ++} ++ + static void msl_dst_cleanup(struct msl_dst *dst, struct vkd3d_string_buffer_cache *cache) + { + vkd3d_string_buffer_release(cache, dst->mask); +@@ -331,6 +517,7 @@ static uint32_t msl_dst_init(struct msl_dst *msl_dst, struct msl_generator *gen, + const struct vkd3d_shader_instruction *ins, const struct vkd3d_shader_dst_param *vsir_dst) + { + uint32_t write_mask = vsir_dst->write_mask; ++ enum msl_data_type dst_data_type; + + if (ins->flags & VKD3DSI_PRECISE_XYZW) + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, +@@ -343,7 +530,9 @@ static uint32_t msl_dst_init(struct msl_dst *msl_dst, struct msl_generator *gen, + msl_dst->register_name = vkd3d_string_buffer_get(&gen->string_buffers); + msl_dst->mask = vkd3d_string_buffer_get(&gen->string_buffers); + +- msl_print_register_name(msl_dst->register_name, gen, &vsir_dst->reg); ++ dst_data_type = msl_print_register_name(msl_dst->register_name, gen, &vsir_dst->reg); ++ if (dst_data_type == MSL_DATA_UNION) ++ msl_print_register_datatype(msl_dst->mask, gen, vsir_dst->reg.data_type); + if (vsir_dst->reg.dimension == VSIR_DIMENSION_VEC4) + msl_print_write_mask(msl_dst->mask, write_mask); + +@@ -530,6 +719,89 @@ 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 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]); ++ 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("); ++ msl_print_src_with_type(read, gen, &ins->src[0], coord_mask, VKD3D_DATA_UINT); ++ if (resource_type_info->array) ++ { ++ vkd3d_string_buffer_printf(read, ", "); ++ msl_print_src_with_type(read, gen, &ins->src[0], coord_mask + 1, VKD3D_DATA_UINT); ++ } ++ if (resource_type_info->lod) ++ { ++ vkd3d_string_buffer_printf(read, ", "); ++ msl_print_src_with_type(read, gen, &ins->src[0], VKD3DSP_WRITEMASK_3, VKD3D_DATA_UINT); ++ } ++ 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_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; +@@ -671,6 +943,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; +@@ -716,144 +991,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->descriptor_info; -+ 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; -@@ -1171,7 +1170,7 @@ static void msl_generate_entrypoint(struct msl_generator *gen) +- 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; +@@ -1171,12 +1308,12 @@ static void msl_generate_entrypoint(struct msl_generator *gen) vkd3d_string_buffer_printf(gen->buffer, "vkd3d_%s_out shader_entry(\n", gen->prefix); @@ -23848,7 +26401,13 @@ index e783128e236..a5d952cd525 100644 { msl_print_indent(gen->buffer, 2); /* TODO: Configurable argument buffer binding location. */ -@@ -1195,7 +1194,7 @@ static void msl_generate_entrypoint(struct msl_generator *gen) + 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); +@@ -1195,7 +1332,7 @@ static void msl_generate_entrypoint(struct msl_generator *gen) vkd3d_string_buffer_printf(gen->buffer, " %s_main(%s_in, %s_out", gen->prefix, gen->prefix, gen->prefix); if (gen->write_depth) vkd3d_string_buffer_printf(gen->buffer, ", shader_out_depth"); @@ -23857,16 +26416,58 @@ index e783128e236..a5d952cd525 100644 vkd3d_string_buffer_printf(gen->buffer, ", descriptors"); vkd3d_string_buffer_printf(gen->buffer, ");\n"); -@@ -1234,7 +1233,7 @@ static int msl_generator_generate(struct msl_generator *gen, struct vkd3d_shader +@@ -1212,7 +1349,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) +@@ -1224,7 +1362,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,8 +1393,8 @@ static int msl_generator_generate(struct msl_generator *gen, struct vkd3d_shader gen->prefix); if (gen->write_depth) vkd3d_string_buffer_printf(gen->buffer, ", thread float& o_depth"); - if (gen->descriptor_info->descriptor_count) +- vkd3d_string_buffer_printf(gen->buffer, ", constant vkd3d_%s_descriptors& descriptors", gen->prefix); + 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"); -@@ -1276,7 +1275,6 @@ static void msl_generator_cleanup(struct msl_generator *gen) + ++gen->indent; +@@ -1276,7 +1435,6 @@ static void msl_generator_cleanup(struct msl_generator *gen) static int msl_generator_init(struct msl_generator *gen, struct vsir_program *program, const struct vkd3d_shader_compile_info *compile_info, @@ -23874,8 +26475,12 @@ index e783128e236..a5d952cd525 100644 struct vkd3d_shader_message_context *message_context) { enum vkd3d_shader_type type = program->shader_version.type; -@@ -1297,13 +1295,11 @@ static int msl_generator_init(struct msl_generator *gen, struct vsir_program *pr - return VKD3D_ERROR_INVALID_SHADER; +@@ -1294,16 +1452,14 @@ static int msl_generator_init(struct msl_generator *gen, struct vsir_program *pr + { + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled shader type %#x.", type); +- return VKD3D_ERROR_INVALID_SHADER; ++ gen->prefix = "unknown"; } gen->interface_info = vkd3d_find_struct(compile_info->next, INTERFACE_INFO); - gen->descriptor_info = descriptor_info; @@ -23888,7 +26493,7 @@ index e783128e236..a5d952cd525 100644 const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context) { -@@ -1314,8 +1310,9 @@ int msl_compile(struct vsir_program *program, uint64_t config_flags, +@@ -1314,8 +1470,9 @@ int msl_compile(struct vsir_program *program, uint64_t config_flags, return ret; VKD3D_ASSERT(program->normalisation_level == VSIR_NORMALISED_SM6); @@ -23933,7 +26538,7 @@ index c6be17bd230..95987831faa 100644 { fclose(f); diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c -index db7ebab742d..91a6686eb0d 100644 +index db7ebab742d..6a393c5f35d 100644 --- a/libs/vkd3d/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c @@ -18,6 +18,7 @@ @@ -24073,6 +26678,15 @@ index db7ebab742d..91a6686eb0d 100644 static enum vkd3d_result spirv_parser_read_header(struct spirv_parser *parser) { uint32_t magic, version, generator, bound, schema; +@@ -324,7 +426,7 @@ static enum vkd3d_result spirv_parser_read_header(struct spirv_parser *parser) + + major = (version & VKD3D_SPIRV_VERSION_MAJOR_MASK) >> VKD3D_SPIRV_VERSION_MAJOR_SHIFT; + minor = (version & VKD3D_SPIRV_VERSION_MINOR_MASK) >> VKD3D_SPIRV_VERSION_MINOR_SHIFT; +- if (major != 1 || minor > 0) ++ if (major != 1 || minor > 6) + { + spirv_parser_error(parser, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, + "Unable to parse SPIR-V version %u.%u.", major, minor); @@ -357,36 +459,260 @@ static enum vkd3d_result spirv_parser_read_header(struct spirv_parser *parser) return VKD3D_OK; } @@ -24523,6 +27137,15 @@ index db7ebab742d..91a6686eb0d 100644 unsigned int register_last = (range->last == ~0u) ? range->first : range->last; const struct vkd3d_shader_descriptor_info1 *d; unsigned int i; +@@ -6797,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)) + { @@ -6904,6 +7231,13 @@ static void spirv_compiler_emit_workgroup_memory(struct spirv_compiler *compiler const SpvStorageClass storage_class = SpvStorageClassWorkgroup; struct vkd3d_symbol reg_symbol; @@ -24662,7 +27285,7 @@ index db7ebab742d..91a6686eb0d 100644 spirv_compiler_destroy(spirv_compiler); return ret; diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c -index 82302aac666..23dab35a288 100644 +index 82302aac666..c29bedfaaa9 100644 --- a/libs/vkd3d/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c @@ -714,6 +714,22 @@ input_primitive_type_table[] = @@ -24752,9 +27375,16 @@ index 82302aac666..23dab35a288 100644 { unsigned int i; -@@ -3094,9 +3119,8 @@ bool sm4_sysval_semantic_from_semantic_name(enum vkd3d_shader_sysval_semantic *s +@@ -3091,12 +3116,15 @@ bool sm4_sysval_semantic_from_semantic_name(enum vkd3d_shader_sysval_semantic *s + {"sv_domainlocation", false, VKD3D_SHADER_TYPE_DOMAIN, ~0u}, + {"sv_position", false, VKD3D_SHADER_TYPE_DOMAIN, VKD3D_SHADER_SV_NONE}, + {"sv_primitiveid", false, VKD3D_SHADER_TYPE_DOMAIN, ~0u}, ++ {"sv_rendertargetarrayindex", false, VKD3D_SHADER_TYPE_DOMAIN, VKD3D_SHADER_SV_NONE}, ++ {"sv_viewportarrayindex", false, VKD3D_SHADER_TYPE_DOMAIN, VKD3D_SHADER_SV_NONE}, {"sv_position", true, VKD3D_SHADER_TYPE_DOMAIN, VKD3D_SHADER_SV_POSITION}, ++ {"sv_rendertargetarrayindex", true, VKD3D_SHADER_TYPE_DOMAIN, VKD3D_SHADER_SV_RENDER_TARGET_ARRAY_INDEX}, ++ {"sv_viewportarrayindex", true, VKD3D_SHADER_TYPE_DOMAIN, VKD3D_SHADER_SV_VIEWPORT_ARRAY_INDEX}, - {"position", false, VKD3D_SHADER_TYPE_GEOMETRY, VKD3D_SHADER_SV_POSITION}, - {"sv_position", false, VKD3D_SHADER_TYPE_GEOMETRY, VKD3D_SHADER_SV_POSITION}, @@ -24763,7 +27393,16 @@ index 82302aac666..23dab35a288 100644 {"position", true, VKD3D_SHADER_TYPE_GEOMETRY, VKD3D_SHADER_SV_POSITION}, {"sv_position", true, VKD3D_SHADER_TYPE_GEOMETRY, VKD3D_SHADER_SV_POSITION}, -@@ -3133,7 +3157,7 @@ bool sm4_sysval_semantic_from_semantic_name(enum vkd3d_shader_sysval_semantic *s +@@ -3107,6 +3135,8 @@ bool sm4_sysval_semantic_from_semantic_name(enum vkd3d_shader_sysval_semantic *s + {"sv_primitiveid", false, VKD3D_SHADER_TYPE_HULL, ~0u}, + + {"sv_position", true, VKD3D_SHADER_TYPE_HULL, VKD3D_SHADER_SV_POSITION}, ++ {"sv_rendertargetarrayindex", true, VKD3D_SHADER_TYPE_HULL, VKD3D_SHADER_SV_RENDER_TARGET_ARRAY_INDEX}, ++ {"sv_viewportarrayindex", true, VKD3D_SHADER_TYPE_HULL, VKD3D_SHADER_SV_VIEWPORT_ARRAY_INDEX}, + + {"position", false, VKD3D_SHADER_TYPE_PIXEL, VKD3D_SHADER_SV_POSITION}, + {"sv_position", false, VKD3D_SHADER_TYPE_PIXEL, VKD3D_SHADER_SV_POSITION}, +@@ -3133,13 +3163,17 @@ bool sm4_sysval_semantic_from_semantic_name(enum vkd3d_shader_sysval_semantic *s }; bool has_sv_prefix = !ascii_strncasecmp(semantic_name, "sv_", 3); @@ -24772,7 +27411,40 @@ index 82302aac666..23dab35a288 100644 { VKD3D_ASSERT(!output); -@@ -3197,6 +3221,8 @@ bool sm4_sysval_semantic_from_semantic_name(enum vkd3d_shader_sysval_semantic *s + if (!ascii_strcasecmp(semantic_name, "sv_position") + || (semantic_compat_mapping && !ascii_strcasecmp(semantic_name, "position"))) + *sysval_semantic = VKD3D_SHADER_SV_POSITION; ++ else if (!ascii_strcasecmp(semantic_name, "sv_rendertargetarrayindex")) ++ *sysval_semantic = VKD3D_SHADER_SV_RENDER_TARGET_ARRAY_INDEX; ++ else if (!ascii_strcasecmp(semantic_name, "sv_viewportarrayindex")) ++ *sysval_semantic = VKD3D_SHADER_SV_VIEWPORT_ARRAY_INDEX; + else if (has_sv_prefix) + return false; + else +@@ -3155,11 +3189,6 @@ bool sm4_sysval_semantic_from_semantic_name(enum vkd3d_shader_sysval_semantic *s + return get_tessfactor_sysval_semantic(sysval_semantic, domain, semantic_idx); + if (!ascii_strcasecmp(semantic_name, "sv_insidetessfactor")) + return get_insidetessfactor_sysval_semantic(sysval_semantic, domain, semantic_idx); +- if (!ascii_strcasecmp(semantic_name, "sv_position")) +- { +- *sysval_semantic = VKD3D_SHADER_SV_NONE; +- return true; +- } + } + else + { +@@ -3190,13 +3219,18 @@ bool sm4_sysval_semantic_from_semantic_name(enum vkd3d_shader_sysval_semantic *s + && (semantic_compat_mapping || has_sv_prefix) + && version->type == semantics[i].shader_type) + { +- *sysval_semantic = semantics[i].semantic; ++ if (is_patch_constant_func && output && semantics[i].semantic != ~0u) ++ *sysval_semantic = VKD3D_SHADER_SV_NONE; ++ else ++ *sysval_semantic = semantics[i].semantic; + return true; + } + } if (has_sv_prefix) return false; @@ -24781,7 +27453,7 @@ index 82302aac666..23dab35a288 100644 *sysval_semantic = VKD3D_SHADER_SV_NONE; return true; -@@ -3228,6 +3254,7 @@ static int signature_element_pointer_compare(const void *x, const void *y) +@@ -3228,6 +3262,7 @@ static int signature_element_pointer_compare(const void *x, const void *y) static void tpf_write_signature(struct tpf_compiler *tpf, const struct shader_signature *signature, uint32_t tag) { @@ -24789,7 +27461,7 @@ index 82302aac666..23dab35a288 100644 bool output = tag == TAG_OSGN || (tag == TAG_PCSG && tpf->program->shader_version.type == VKD3D_SHADER_TYPE_HULL); const struct signature_element **sorted_elements; -@@ -3256,12 +3283,16 @@ static void tpf_write_signature(struct tpf_compiler *tpf, const struct shader_si +@@ -3256,12 +3291,16 @@ static void tpf_write_signature(struct tpf_compiler *tpf, const struct shader_si if (sysval >= VKD3D_SHADER_SV_TARGET) sysval = VKD3D_SHADER_SV_NONE; @@ -24806,7 +27478,7 @@ index 82302aac666..23dab35a288 100644 } for (i = 0; i < signature->element_count; ++i) -@@ -3270,9 +3301,21 @@ static void tpf_write_signature(struct tpf_compiler *tpf, const struct shader_si +@@ -3270,9 +3309,21 @@ static void tpf_write_signature(struct tpf_compiler *tpf, const struct shader_si size_t string_offset; string_offset = put_string(&buffer, element->semantic_name); @@ -24829,7 +27501,7 @@ index 82302aac666..23dab35a288 100644 add_section(tpf, tag, &buffer); vkd3d_free(sorted_elements); } -@@ -3444,12 +3487,16 @@ static void sm4_write_register_index(const struct tpf_compiler *tpf, const struc +@@ -3444,12 +3495,16 @@ static void sm4_write_register_index(const struct tpf_compiler *tpf, const struc unsigned int j) { unsigned int addressing = sm4_get_index_addressing_from_reg(reg, j); @@ -24847,7 +27519,7 @@ index 82302aac666..23dab35a288 100644 uint32_t idx_src_token; VKD3D_ASSERT(idx_src); -@@ -3464,10 +3511,6 @@ static void sm4_write_register_index(const struct tpf_compiler *tpf, const struc +@@ -3464,10 +3519,6 @@ static void sm4_write_register_index(const struct tpf_compiler *tpf, const struc VKD3D_ASSERT(!idx_src->reg.idx[k].rel_addr); } } @@ -24858,7 +27530,73 @@ index 82302aac666..23dab35a288 100644 } static void sm4_write_dst_register(const struct tpf_compiler *tpf, const struct vkd3d_shader_dst_param *dst) -@@ -3912,6 +3955,57 @@ static void tpf_write_dcl_tessellator_output_primitive(const struct tpf_compiler +@@ -3771,6 +3822,25 @@ static void tpf_dcl_sampler(const struct tpf_compiler *tpf, const struct vkd3d_s + write_sm4_instruction(tpf, &instr); + } + ++static uint32_t pack_resource_data_type(const enum vkd3d_data_type *resource_data_type) ++{ ++ unsigned int i, k, type = 0; ++ ++ for (k = 0; k < 4; ++k) ++ { ++ for (i = ARRAY_SIZE(data_type_table) - 1; i < ARRAY_SIZE(data_type_table); --i) ++ { ++ if (resource_data_type[k] == data_type_table[i]) ++ { ++ type |= i << (4 * k); ++ break; ++ } ++ } ++ } ++ ++ return type; ++} ++ + static void tpf_dcl_texture(const struct tpf_compiler *tpf, const struct vkd3d_shader_instruction *ins) + { + const struct vkd3d_shader_structured_resource *structured_resource = &ins->declaration.structured_resource; +@@ -3778,7 +3848,6 @@ static void tpf_dcl_texture(const struct tpf_compiler *tpf, const struct vkd3d_s + const struct vkd3d_shader_version *version = &tpf->program->shader_version; + const struct vkd3d_sm4_opcode_info *info; + struct sm4_instruction instr = {0}; +- unsigned int i, k; + bool uav; + + info = get_info_from_vsir_opcode(&tpf->lookup, ins->opcode); +@@ -3793,18 +3862,11 @@ static void tpf_dcl_texture(const struct tpf_compiler *tpf, const struct vkd3d_s + instr.dsts[0] = semantic->resource.reg; + instr.dst_count = 1; + +- for (k = 0; k < 4; ++k) ++ if (ins->opcode == VKD3DSIH_DCL || ins->opcode == VKD3DSIH_DCL_UAV_TYPED) + { +- for (i = ARRAY_SIZE(data_type_table) - 1; i < ARRAY_SIZE(data_type_table); --i) +- { +- if (semantic->resource_data_type[k] == data_type_table[i]) +- { +- instr.idx[0] |= i << (4 * k); +- break; +- } +- } ++ instr.idx[0] = pack_resource_data_type(semantic->resource_data_type); ++ instr.idx_count = 1; + } +- instr.idx_count = 1; + + if (vkd3d_shader_ver_ge(version, 5, 1)) + { +@@ -3813,8 +3875,7 @@ static void tpf_dcl_texture(const struct tpf_compiler *tpf, const struct vkd3d_s + instr.dsts[0].reg.idx[2].offset = semantic->resource.range.last; + instr.dsts[0].reg.idx_count = 3; + +- instr.idx[1] = semantic->resource.range.space; +- instr.idx_count = 2; ++ instr.idx[instr.idx_count++] = semantic->resource.range.space; + } + else + { +@@ -3912,6 +3973,57 @@ static void tpf_write_dcl_tessellator_output_primitive(const struct tpf_compiler write_sm4_instruction(tpf, &instr); } @@ -24916,7 +27654,7 @@ index 82302aac666..23dab35a288 100644 static void tpf_simple_instruction(struct tpf_compiler *tpf, const struct vkd3d_shader_instruction *ins) { struct sm4_instruction_modifier *modifier; -@@ -4215,6 +4309,13 @@ static void tpf_write_shdr(struct tpf_compiler *tpf) +@@ -4215,6 +4327,13 @@ static void tpf_write_shdr(struct tpf_compiler *tpf) tpf_write_dcl_input_control_point_count(tpf, program->input_control_point_count); tpf_write_dcl_tessellator_domain(tpf, program->tess_domain); } @@ -24930,7 +27668,7 @@ index 82302aac666..23dab35a288 100644 tpf_write_program(tpf, program); -@@ -4233,6 +4334,9 @@ static void tpf_write_sfi0(struct tpf_compiler *tpf) +@@ -4233,6 +4352,9 @@ static void tpf_write_sfi0(struct tpf_compiler *tpf) if (tpf->program->features.rovs) *flags |= DXBC_SFI0_REQUIRES_ROVS; @@ -24941,7 +27679,7 @@ index 82302aac666..23dab35a288 100644 * STENCIL_REF, and TYPED_UAV_LOAD_ADDITIONAL_FORMATS. */ diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -index 021691bb3a1..9191429c439 100644 +index 021691bb3a1..4103cdc1ef9 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 @@ @@ -25112,8 +27850,42 @@ index 021691bb3a1..9191429c439 100644 } return true; -@@ -1059,7 +1127,7 @@ static void vkd3d_shader_scan_combined_sampler_declaration( - &semantic->resource.range, semantic->resource_type, VKD3D_SHADER_RESOURCE_DATA_FLOAT); +@@ -995,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; +@@ -1031,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; + } +@@ -1043,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_UNUSED))) + return; + + if (instruction->flags & VKD3DSI_SAMPLER_COMPARISON_MODE) +@@ -1054,12 +1122,12 @@ 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_UNUSED); + 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); } -static const struct vkd3d_shader_descriptor_info1 *find_descriptor( @@ -25135,7 +27907,162 @@ index 021691bb3a1..9191429c439 100644 VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, sampler->idx[0].offset))) sampler_space = d->register_space; } -@@ -1501,7 +1569,7 @@ static enum vkd3d_result convert_descriptor_info(struct vkd3d_shader_scan_descri +@@ -1146,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; +@@ -1171,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]); +- +- 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; +- } ++ 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]); + +- 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, +@@ -1259,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: +@@ -1475,8 +1500,36 @@ 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; ++ 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; ++ } ++} ++ ++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; + +@@ -1492,16 +1545,28 @@ 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_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) ++ { ++ 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; + return VKD3D_OK; } @@ -25144,7 +28071,7 @@ index 021691bb3a1..9191429c439 100644 { TRACE("scan_descriptor_info %p.\n", scan_descriptor_info); -@@ -1509,12 +1577,10 @@ static void vkd3d_shader_free_scan_descriptor_info1(struct vkd3d_shader_scan_des +@@ -1509,12 +1574,10 @@ static void vkd3d_shader_free_scan_descriptor_info1(struct vkd3d_shader_scan_des } static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_shader_compile_info *compile_info, @@ -25158,7 +28085,7 @@ index 021691bb3a1..9191429c439 100644 struct vkd3d_shader_scan_descriptor_info *descriptor_info; struct vkd3d_shader_scan_signature_info *signature_info; struct vkd3d_shader_instruction *instruction; -@@ -1523,29 +1589,25 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh +@@ -1523,29 +1586,25 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh unsigned int i; descriptor_info = vkd3d_find_struct(compile_info->next, SCAN_DESCRIPTOR_INFO); @@ -25196,16 +28123,25 @@ index 021691bb3a1..9191429c439 100644 if (TRACE_ON()) vsir_program_trace(program); -@@ -1585,7 +1647,7 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh +@@ -1567,7 +1626,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; + } + } +@@ -1585,7 +1644,7 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh } if (!ret && descriptor_info) - ret = convert_descriptor_info(descriptor_info, descriptor_info1); -+ ret = convert_descriptor_info(descriptor_info, &program->descriptors); ++ ret = convert_descriptor_info(&context, descriptor_info, &program->descriptors); if (!ret && tessellation_info) { -@@ -1599,15 +1661,10 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh +@@ -1599,15 +1658,10 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh vkd3d_shader_free_scan_combined_resource_sampler_info(combined_sampler_info); if (descriptor_info) vkd3d_shader_free_scan_descriptor_info(descriptor_info); @@ -25222,7 +28158,7 @@ index 021691bb3a1..9191429c439 100644 vkd3d_shader_scan_context_cleanup(&context); return ret; } -@@ -1631,7 +1688,7 @@ int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char +@@ -1631,7 +1685,7 @@ int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char vkd3d_shader_message_context_init(&message_context, compile_info->log_level); fill_shader_dump_data(compile_info, &dump_data); @@ -25231,7 +28167,7 @@ index 021691bb3a1..9191429c439 100644 if (compile_info->source_type == VKD3D_SHADER_SOURCE_HLSL) { -@@ -1645,7 +1702,7 @@ int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char +@@ -1645,7 +1699,7 @@ int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char if (!(ret = vsir_parse(compile_info, config_flags, &message_context, &program))) { @@ -25240,7 +28176,7 @@ index 021691bb3a1..9191429c439 100644 vsir_program_cleanup(&program); } } -@@ -1662,7 +1719,6 @@ int vsir_program_compile(struct vsir_program *program, uint64_t config_flags, +@@ -1662,7 +1716,6 @@ int vsir_program_compile(struct vsir_program *program, uint64_t config_flags, struct vkd3d_shader_message_context *message_context) { struct vkd3d_shader_scan_combined_resource_sampler_info combined_sampler_info; @@ -25248,7 +28184,7 @@ index 021691bb3a1..9191429c439 100644 struct vkd3d_shader_compile_info scan_info; int ret; -@@ -1678,28 +1734,24 @@ int vsir_program_compile(struct vsir_program *program, uint64_t config_flags, +@@ -1678,28 +1731,24 @@ int vsir_program_compile(struct vsir_program *program, uint64_t config_flags, combined_sampler_info.type = VKD3D_SHADER_STRUCTURE_TYPE_SCAN_COMBINED_RESOURCE_SAMPLER_INFO; combined_sampler_info.next = scan_info.next; scan_info.next = &combined_sampler_info; @@ -25283,7 +28219,7 @@ index 021691bb3a1..9191429c439 100644 break; default: -@@ -1711,7 +1763,8 @@ int vsir_program_compile(struct vsir_program *program, uint64_t config_flags, +@@ -1711,7 +1760,8 @@ int vsir_program_compile(struct vsir_program *program, uint64_t config_flags, } static int compile_hlsl(const struct vkd3d_shader_compile_info *compile_info, @@ -25293,7 +28229,7 @@ index 021691bb3a1..9191429c439 100644 { struct vkd3d_shader_code preprocessed; int ret; -@@ -1719,6 +1772,8 @@ static int compile_hlsl(const struct vkd3d_shader_compile_info *compile_info, +@@ -1719,6 +1769,8 @@ static int compile_hlsl(const struct vkd3d_shader_compile_info *compile_info, if ((ret = preproc_lexer_parse(compile_info, &preprocessed, message_context))) return ret; @@ -25302,7 +28238,7 @@ index 021691bb3a1..9191429c439 100644 ret = hlsl_compile_shader(&preprocessed, compile_info, out, message_context); vkd3d_shader_free_shader_code(&preprocessed); -@@ -1745,11 +1800,11 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info, +@@ -1745,11 +1797,11 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info, vkd3d_shader_message_context_init(&message_context, compile_info->log_level); fill_shader_dump_data(compile_info, &dump_data); @@ -25316,7 +28252,7 @@ index 021691bb3a1..9191429c439 100644 } else if (compile_info->source_type == VKD3D_SHADER_SOURCE_FX) { -@@ -1768,7 +1823,7 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info, +@@ -1768,7 +1820,7 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info, } if (ret >= 0) @@ -25325,7 +28261,7 @@ index 021691bb3a1..9191429c439 100644 vkd3d_shader_message_context_trace_messages(&message_context); if (!vkd3d_shader_message_context_copy_messages(&message_context, messages)) -@@ -1961,9 +2016,7 @@ const enum vkd3d_shader_source_type *vkd3d_shader_get_supported_source_types(uns +@@ -1961,9 +2013,7 @@ const enum vkd3d_shader_source_type *vkd3d_shader_get_supported_source_types(uns VKD3D_SHADER_SOURCE_DXBC_TPF, VKD3D_SHADER_SOURCE_HLSL, VKD3D_SHADER_SOURCE_D3D_BYTECODE, @@ -25335,7 +28271,7 @@ index 021691bb3a1..9191429c439 100644 VKD3D_SHADER_SOURCE_FX, }; -@@ -1996,6 +2049,9 @@ const enum vkd3d_shader_target_type *vkd3d_shader_get_supported_target_types( +@@ -1996,6 +2046,9 @@ const enum vkd3d_shader_target_type *vkd3d_shader_get_supported_target_types( VKD3D_SHADER_TARGET_SPIRV_BINARY, #if defined(HAVE_SPIRV_TOOLS) || defined(VKD3D_SHADER_UNSUPPORTED_SPIRV_PARSER) VKD3D_SHADER_TARGET_SPIRV_TEXT, @@ -25345,7 +28281,7 @@ index 021691bb3a1..9191429c439 100644 #endif VKD3D_SHADER_TARGET_D3D_ASM, VKD3D_SHADER_TARGET_D3D_BYTECODE, -@@ -2012,7 +2068,6 @@ const enum vkd3d_shader_target_type *vkd3d_shader_get_supported_target_types( +@@ -2012,7 +2065,6 @@ const enum vkd3d_shader_target_type *vkd3d_shader_get_supported_target_types( VKD3D_SHADER_TARGET_D3D_ASM, }; @@ -25353,7 +28289,7 @@ index 021691bb3a1..9191429c439 100644 static const enum vkd3d_shader_target_type dxbc_dxil_types[] = { VKD3D_SHADER_TARGET_SPIRV_BINARY, -@@ -2021,7 +2076,6 @@ const enum vkd3d_shader_target_type *vkd3d_shader_get_supported_target_types( +@@ -2021,7 +2073,6 @@ const enum vkd3d_shader_target_type *vkd3d_shader_get_supported_target_types( # endif VKD3D_SHADER_TARGET_D3D_ASM, }; @@ -25361,7 +28297,7 @@ index 021691bb3a1..9191429c439 100644 static const enum vkd3d_shader_target_type fx_types[] = { -@@ -2044,11 +2098,9 @@ const enum vkd3d_shader_target_type *vkd3d_shader_get_supported_target_types( +@@ -2044,11 +2095,9 @@ const enum vkd3d_shader_target_type *vkd3d_shader_get_supported_target_types( *count = ARRAY_SIZE(d3dbc_types); return d3dbc_types; @@ -25374,19 +28310,22 @@ index 021691bb3a1..9191429c439 100644 case VKD3D_SHADER_SOURCE_FX: *count = ARRAY_SIZE(fx_types); diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -index 03643acff3c..bf794d5e936 100644 +index 03643acff3c..3b4fb626fcc 100644 --- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -@@ -59,7 +59,7 @@ +@@ -59,8 +59,10 @@ #define VKD3D_VEC4_SIZE 4 #define VKD3D_DVEC2_SIZE 2 -#define VKD3D_SHADER_COMPONENT_TYPE_COUNT (VKD3D_SHADER_COMPONENT_UINT64 + 1) +#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 -@@ -74,6 +74,8 @@ enum vkd3d_shader_error + +@@ -74,6 +76,8 @@ enum vkd3d_shader_error VKD3D_SHADER_ERROR_DXBC_INVALID_CHUNK_SIZE = 6, VKD3D_SHADER_ERROR_DXBC_OUT_OF_MEMORY = 7, VKD3D_SHADER_ERROR_DXBC_INVALID_SIGNATURE = 8, @@ -25395,7 +28334,7 @@ index 03643acff3c..bf794d5e936 100644 VKD3D_SHADER_ERROR_TPF_MISMATCHED_CF = 1000, VKD3D_SHADER_ERROR_TPF_INVALID_REGISTER_RANGE = 1001, -@@ -167,6 +169,9 @@ enum vkd3d_shader_error +@@ -167,6 +171,9 @@ enum vkd3d_shader_error VKD3D_SHADER_ERROR_HLSL_MISPLACED_SAMPLER_STATE = 5039, VKD3D_SHADER_ERROR_HLSL_AMBIGUOUS_CALL = 5040, VKD3D_SHADER_ERROR_HLSL_DUPLICATE_PATCH = 5041, @@ -25405,7 +28344,20 @@ index 03643acff3c..bf794d5e936 100644 VKD3D_SHADER_WARNING_HLSL_IMPLICIT_TRUNCATION = 5300, VKD3D_SHADER_WARNING_HLSL_DIVISION_BY_ZERO = 5301, -@@ -261,6 +266,8 @@ enum vkd3d_shader_error +@@ -252,15 +259,21 @@ 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, + + 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, VKD3D_SHADER_ERROR_FX_INVALID_DATA = 11002, @@ -25414,7 +28366,15 @@ index 03643acff3c..bf794d5e936 100644 }; enum vkd3d_shader_opcode -@@ -1415,6 +1422,33 @@ enum vsir_normalisation_level +@@ -998,6 +1011,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 +@@ -1415,6 +1429,33 @@ enum vsir_normalisation_level VSIR_NORMALISED_SM6, }; @@ -25425,7 +28385,7 @@ index 03643acff3c..bf794d5e936 100644 + 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; @@ -25448,7 +28408,7 @@ index 03643acff3c..bf794d5e936 100644 struct vsir_program { struct vkd3d_shader_version shader_version; -@@ -1424,6 +1458,9 @@ struct vsir_program +@@ -1424,6 +1465,9 @@ struct vsir_program struct shader_signature output_signature; struct shader_signature patch_constant_signature; @@ -25458,7 +28418,7 @@ index 03643acff3c..bf794d5e936 100644 unsigned int parameter_count; const struct vkd3d_shader_parameter1 *parameters; bool free_parameters; -@@ -1445,6 +1482,9 @@ struct vsir_program +@@ -1445,6 +1489,9 @@ struct vsir_program enum vkd3d_tessellator_domain tess_domain; enum vkd3d_shader_tessellator_partitioning tess_partitioning; enum vkd3d_shader_tessellator_output_primitive tess_output_primitive; @@ -25468,7 +28428,7 @@ index 03643acff3c..bf794d5e936 100644 uint32_t io_dcls[VKD3D_BITMAP_SIZE(VKD3DSPR_COUNT)]; struct vsir_features features; -@@ -1501,28 +1541,6 @@ void vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser, struct vsir_pr +@@ -1501,28 +1548,6 @@ void vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser, struct vsir_pr void vkd3d_shader_parser_warning(struct vkd3d_shader_parser *parser, enum vkd3d_shader_error error, const char *format, ...) VKD3D_PRINTF_FUNC(3, 4); @@ -25497,7 +28457,16 @@ index 03643acff3c..bf794d5e936 100644 void vsir_program_trace(const struct vsir_program *program); const char *shader_get_type_prefix(enum vkd3d_shader_type type); -@@ -1558,6 +1576,7 @@ void vkd3d_string_buffer_clear(struct vkd3d_string_buffer *buffer); +@@ -1544,6 +1569,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, +@@ -1558,6 +1585,7 @@ void vkd3d_string_buffer_clear(struct vkd3d_string_buffer *buffer); void vkd3d_string_buffer_truncate(struct vkd3d_string_buffer *buffer, size_t size); int vkd3d_string_buffer_print_f32(struct vkd3d_string_buffer *buffer, float f); int vkd3d_string_buffer_print_f64(struct vkd3d_string_buffer *buffer, double d); @@ -25505,7 +28474,17 @@ index 03643acff3c..bf794d5e936 100644 int vkd3d_string_buffer_printf(struct vkd3d_string_buffer *buffer, const char *format, ...) VKD3D_PRINTF_FUNC(2, 3); void vkd3d_string_buffer_release(struct vkd3d_string_buffer_cache *list, struct vkd3d_string_buffer *buffer); #define vkd3d_string_buffer_trace(buffer) \ -@@ -1642,7 +1661,8 @@ bool sm4_register_from_semantic_name(const struct vkd3d_shader_version *version, +@@ -1634,7 +1662,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, +@@ -1642,7 +1671,8 @@ bool sm4_register_from_semantic_name(const struct vkd3d_shader_version *version, bool shader_sm4_is_scalar_register(const struct vkd3d_shader_register *reg); bool sm4_sysval_semantic_from_semantic_name(enum vkd3d_shader_sysval_semantic *sysval_semantic, const struct vkd3d_shader_version *version, bool semantic_compat_mapping, enum vkd3d_tessellator_domain domain, @@ -25515,7 +28494,7 @@ index 03643acff3c..bf794d5e936 100644 int d3dbc_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags, struct vkd3d_shader_message_context *message_context, struct vsir_program *program); -@@ -1665,7 +1685,6 @@ int d3dbc_compile(struct vsir_program *program, uint64_t config_flags, +@@ -1665,7 +1695,6 @@ int d3dbc_compile(struct vsir_program *program, uint64_t config_flags, struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context); int glsl_compile(struct vsir_program *program, uint64_t config_flags, @@ -25523,7 +28502,7 @@ index 03643acff3c..bf794d5e936 100644 const struct vkd3d_shader_scan_combined_resource_sampler_info *combined_sampler_info, const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context); -@@ -1673,12 +1692,10 @@ int glsl_compile(struct vsir_program *program, uint64_t config_flags, +@@ -1673,12 +1702,10 @@ int glsl_compile(struct vsir_program *program, uint64_t config_flags, #define SPIRV_MAX_SRC_COUNT 6 int spirv_compile(struct vsir_program *program, uint64_t config_flags, @@ -25536,6 +28515,37 @@ index 03643acff3c..bf794d5e936 100644 const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context); +@@ -1747,30 +1774,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; diff --git a/libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c b/libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c index 62dd5f69f77..d59a133c3d4 100644 --- a/libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c diff --git a/patches/vkd3d-latest/0002-Updated-vkd3d-to-4289ec60a1f79f68ea9bd3624141b5657b8.patch b/patches/vkd3d-latest/0002-Updated-vkd3d-to-4289ec60a1f79f68ea9bd3624141b5657b8.patch new file mode 100644 index 00000000..173f3b04 --- /dev/null +++ b/patches/vkd3d-latest/0002-Updated-vkd3d-to-4289ec60a1f79f68ea9bd3624141b5657b8.patch @@ -0,0 +1,1718 @@ +From 297a5771cca6177f491699ba1c506b29e49eced2 Mon Sep 17 00:00:00 2001 +From: Alistair Leslie-Hughes +Date: Tue, 6 May 2025 06:42:46 +1000 +Subject: [PATCH] Updated vkd3d to 4289ec60a1f79f68ea9bd3624141b5657b82d6c8. + +--- + libs/vkd3d/include/private/vkd3d_version.h | 2 +- + libs/vkd3d/libs/vkd3d-shader/dxil.c | 330 ++++++++++++-------- + libs/vkd3d/libs/vkd3d-shader/hlsl.c | 63 ++++ + libs/vkd3d/libs/vkd3d-shader/hlsl.h | 19 ++ + libs/vkd3d/libs/vkd3d-shader/hlsl.y | 70 ++++- + libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 231 +++++++++++--- + libs/vkd3d/libs/vkd3d-shader/tpf.c | 3 + + 7 files changed, 544 insertions(+), 174 deletions(-) + +diff --git a/libs/vkd3d/include/private/vkd3d_version.h b/libs/vkd3d/include/private/vkd3d_version.h +index 795bc2dc490..fb2e2f11f8b 100644 +--- a/libs/vkd3d/include/private/vkd3d_version.h ++++ b/libs/vkd3d/include/private/vkd3d_version.h +@@ -1 +1 @@ +-#define VKD3D_VCS_ID " (git a4f58be0)" ++#define VKD3D_VCS_ID " (git 4289ec60)" +diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c +index 775be85334e..52bab40b553 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/dxil.c ++++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c +@@ -647,6 +647,7 @@ enum sm6_value_type + VALUE_TYPE_REG, + VALUE_TYPE_ICB, + VALUE_TYPE_HANDLE, ++ VALUE_TYPE_SSA, + }; + + struct sm6_function_data +@@ -663,6 +664,11 @@ struct sm6_handle_data + bool non_uniform; + }; + ++struct sm6_ssa_data ++{ ++ unsigned int id; ++}; ++ + struct sm6_value + { + const struct sm6_type *type; +@@ -673,10 +679,11 @@ struct sm6_value + union + { + struct sm6_function_data function; +- struct vkd3d_shader_register reg; + const struct vkd3d_shader_immediate_constant_buffer *icb; + struct sm6_handle_data handle; ++ struct sm6_ssa_data ssa; + } u; ++ struct vkd3d_shader_register reg; + }; + + struct dxil_record +@@ -2232,7 +2239,15 @@ static inline struct sm6_value *sm6_parser_get_current_value(const struct sm6_pa + + static inline bool sm6_value_is_register(const struct sm6_value *value) + { +- return value->value_type == VALUE_TYPE_REG; ++ switch (value->value_type) ++ { ++ case VALUE_TYPE_REG: ++ case VALUE_TYPE_SSA: ++ return true; ++ ++ default: ++ return false; ++ } + } + + static bool sm6_value_is_handle(const struct sm6_value *value) +@@ -2242,18 +2257,18 @@ static bool sm6_value_is_handle(const struct sm6_value *value) + + static inline bool sm6_value_is_constant(const struct sm6_value *value) + { +- return sm6_value_is_register(value) && register_is_constant(&value->u.reg); ++ return sm6_value_is_register(value) && register_is_constant(&value->reg); + } + + static bool sm6_value_is_constant_zero(const struct sm6_value *value) + { + /* Constant vectors do not occur. */ +- return sm6_value_is_register(value) && register_is_scalar_constant_zero(&value->u.reg); ++ return sm6_value_is_register(value) && register_is_scalar_constant_zero(&value->reg); + } + + static inline bool sm6_value_is_undef(const struct sm6_value *value) + { +- return sm6_value_is_register(value) && value->u.reg.type == VKD3DSPR_UNDEF; ++ return sm6_value_is_register(value) && value->reg.type == VKD3DSPR_UNDEF; + } + + static bool sm6_value_vector_is_constant_or_undef(const struct sm6_value **values, unsigned int count) +@@ -2272,26 +2287,26 @@ static bool sm6_value_is_icb(const struct sm6_value *value) + + static bool sm6_value_is_ssa(const struct sm6_value *value) + { +- return sm6_value_is_register(value) && register_is_ssa(&value->u.reg); ++ return sm6_value_is_register(value) && register_is_ssa(&value->reg); + } + + static bool sm6_value_is_numeric_array(const struct sm6_value *value) + { +- return sm6_value_is_register(value) && register_is_numeric_array(&value->u.reg); ++ return sm6_value_is_register(value) && register_is_numeric_array(&value->reg); + } + + static inline unsigned int sm6_value_get_constant_uint(const struct sm6_value *value) + { + if (!sm6_value_is_constant(value)) + return UINT_MAX; +- return register_get_uint_value(&value->u.reg); ++ return register_get_uint_value(&value->reg); + } + + static uint64_t sm6_value_get_constant_uint64(const struct sm6_value *value) + { + if (!sm6_value_is_constant(value)) + return UINT64_MAX; +- return register_get_uint64_value(&value->u.reg); ++ return register_get_uint64_value(&value->reg); + } + + static unsigned int sm6_parser_alloc_ssa_id(struct sm6_parser *sm6) +@@ -2390,15 +2405,55 @@ static enum vkd3d_data_type vkd3d_data_type_from_sm6_type(const struct sm6_type + return VKD3D_DATA_UINT; + } + ++static void sm6_register_from_value(struct vkd3d_shader_register *reg, const struct sm6_value *value) ++{ ++ switch (value->value_type) ++ { ++ case VALUE_TYPE_REG: ++ *reg = value->reg; ++ break; ++ ++ case VALUE_TYPE_SSA: ++ register_init_with_id(reg, VKD3DSPR_SSA, vkd3d_data_type_from_sm6_type( ++ sm6_type_get_scalar_type(value->type, 0)), value->u.ssa.id); ++ reg->dimension = sm6_type_is_scalar(value->type) ? VSIR_DIMENSION_SCALAR : VSIR_DIMENSION_VEC4; ++ break; ++ ++ case VALUE_TYPE_FUNCTION: ++ case VALUE_TYPE_HANDLE: ++ case VALUE_TYPE_ICB: ++ vkd3d_unreachable(); ++ } ++} ++ ++static void sm6_parser_init_ssa_value(struct sm6_parser *sm6, struct sm6_value *value) ++{ ++ unsigned int id; ++ ++ if (register_is_ssa(&value->reg) && value->reg.idx[0].offset) ++ { ++ id = value->reg.idx[0].offset; ++ TRACE("Using forward-allocated id %u.\n", id); ++ } ++ else ++ { ++ id = sm6_parser_alloc_ssa_id(sm6); ++ } ++ ++ value->value_type = VALUE_TYPE_SSA; ++ value->u.ssa.id = id; ++ sm6_register_from_value(&value->reg, value); ++} ++ + static void register_init_ssa_vector(struct vkd3d_shader_register *reg, const struct sm6_type *type, + unsigned int component_count, struct sm6_value *value, struct sm6_parser *sm6) + { + enum vkd3d_data_type data_type; + unsigned int id; + +- if (value && register_is_ssa(&value->u.reg) && value->u.reg.idx[0].offset) ++ if (value && register_is_ssa(&value->reg) && value->reg.idx[0].offset) + { +- id = value->u.reg.idx[0].offset; ++ id = value->reg.idx[0].offset; + TRACE("Using forward-allocated id %u.\n", id); + } + else +@@ -2450,13 +2505,6 @@ static void dst_param_init_vector(struct vkd3d_shader_dst_param *param, unsigned + param->shift = 0; + } + +-static void dst_param_init_ssa_scalar(struct vkd3d_shader_dst_param *param, const struct sm6_type *type, +- struct sm6_value *value, struct sm6_parser *sm6) +-{ +- dst_param_init(param); +- register_init_ssa_scalar(¶m->reg, type, value, sm6); +-} +- + static inline void src_param_init(struct vkd3d_shader_src_param *param) + { + param->swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); +@@ -2480,7 +2528,7 @@ static void src_param_init_vector(struct vkd3d_shader_src_param *param, unsigned + static void src_param_init_from_value(struct vkd3d_shader_src_param *param, const struct sm6_value *src) + { + src_param_init(param); +- param->reg = src->u.reg; ++ sm6_register_from_value(¶m->reg, src); + } + + static void src_param_init_vector_from_reg(struct vkd3d_shader_src_param *param, +@@ -2547,9 +2595,9 @@ static bool instruction_dst_param_init_ssa_scalar(struct vkd3d_shader_instructio + if (!(param = instruction_dst_params_alloc(ins, 1, sm6))) + return false; + +- dst_param_init_ssa_scalar(param, dst->type, dst, sm6); +- param->write_mask = VKD3DSP_WRITEMASK_0; +- dst->u.reg = param->reg; ++ dst_param_init(param); ++ sm6_parser_init_ssa_value(sm6, dst); ++ sm6_register_from_value(¶m->reg, dst); + return true; + } + +@@ -2560,8 +2608,8 @@ static void instruction_dst_param_init_ssa_vector(struct vkd3d_shader_instructio + struct sm6_value *dst = sm6_parser_get_current_value(sm6); + + dst_param_init_vector(param, component_count); +- register_init_ssa_vector(¶m->reg, sm6_type_get_scalar_type(dst->type, 0), component_count, dst, sm6); +- dst->u.reg = param->reg; ++ sm6_parser_init_ssa_value(sm6, dst); ++ sm6_register_from_value(¶m->reg, dst); + } + + static bool instruction_dst_param_init_temp_vector(struct vkd3d_shader_instruction *ins, struct sm6_parser *sm6) +@@ -2576,7 +2624,7 @@ static bool instruction_dst_param_init_temp_vector(struct vkd3d_shader_instructi + param->write_mask = VKD3DSP_WRITEMASK_ALL; + param->reg.idx[0].offset = 0; + param->reg.dimension = VSIR_DIMENSION_VEC4; +- dst->u.reg = param->reg; ++ dst->reg = param->reg; + + return true; + } +@@ -2856,11 +2904,9 @@ static size_t sm6_parser_get_value_idx_by_ref(struct sm6_parser *sm6, const stru + else + { + value->type = fwd_type; +- value->value_type = VALUE_TYPE_REG; +- register_init_with_id(&value->u.reg, VKD3DSPR_SSA, vkd3d_data_type_from_sm6_type( +- sm6_type_get_scalar_type(fwd_type, 0)), sm6_parser_alloc_ssa_id(sm6)); +- value->u.reg.dimension = sm6_type_is_scalar(fwd_type) ? VSIR_DIMENSION_SCALAR +- : VSIR_DIMENSION_VEC4; ++ value->value_type = VALUE_TYPE_SSA; ++ value->u.ssa.id = sm6_parser_alloc_ssa_id(sm6); ++ sm6_register_from_value(&value->reg, value); + } + } + +@@ -2990,6 +3036,13 @@ static float register_get_float_value(const struct vkd3d_shader_register *reg) + return bitcast_uint_to_float(reg->u.immconst_u32[0]); + } + ++static inline float sm6_value_get_constant_float(const struct sm6_value *value) ++{ ++ if (!sm6_value_is_constant(value)) ++ return UINT_MAX; ++ return register_get_float_value(&value->reg); ++} ++ + static enum vkd3d_result value_allocate_constant_array(struct sm6_value *dst, const struct sm6_type *type, + const uint64_t *operands, struct sm6_parser *sm6) + { +@@ -3066,6 +3119,7 @@ static enum vkd3d_result sm6_parser_init_constexpr_gep(struct sm6_parser *sm6, c + struct sm6_value *dst) + { + const struct sm6_type *elem_type, *pointee_type, *gep_type, *ptr_type; ++ struct vkd3d_shader_register reg; + struct sm6_value *operands[3]; + unsigned int i, j, offset; + uint64_t value; +@@ -3109,7 +3163,9 @@ static enum vkd3d_result sm6_parser_init_constexpr_gep(struct sm6_parser *sm6, c + } + } + +- if (operands[0]->u.reg.idx_count > 1) ++ sm6_register_from_value(®, operands[0]); ++ ++ if (reg.idx_count > 1) + { + WARN("Unsupported stacked GEP.\n"); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, +@@ -3170,10 +3226,10 @@ static enum vkd3d_result sm6_parser_init_constexpr_gep(struct sm6_parser *sm6, c + "Module does not define a pointer type for a constexpr GEP result."); + return VKD3D_ERROR_INVALID_SHADER; + } +- dst->u.reg = operands[0]->u.reg; +- dst->u.reg.idx[1].offset = offset; +- dst->u.reg.idx[1].is_in_bounds = record->code == CST_CODE_CE_INBOUNDS_GEP; +- dst->u.reg.idx_count = 2; ++ dst->reg = reg; ++ dst->reg.idx[1].offset = offset; ++ dst->reg.idx[1].is_in_bounds = record->code == CST_CODE_CE_INBOUNDS_GEP; ++ dst->reg.idx_count = 2; + + return VKD3D_OK; + } +@@ -3232,7 +3288,7 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const + dst->type = type; + dst->value_type = VALUE_TYPE_REG; + dst->is_back_ref = true; +- vsir_register_init(&dst->u.reg, reg_type, reg_data_type, 0); ++ vsir_register_init(&dst->reg, reg_type, reg_data_type, 0); + + switch (record->code) + { +@@ -3257,9 +3313,9 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const + + value = decode_rotated_signed_value(record->operands[0]); + if (type->u.width <= 32) +- dst->u.reg.u.immconst_u32[0] = value & ((1ull << type->u.width) - 1); ++ dst->reg.u.immconst_u32[0] = value & ((1ull << type->u.width) - 1); + else +- dst->u.reg.u.immconst_u64[0] = value; ++ dst->reg.u.immconst_u64[0] = value; + + break; + +@@ -3274,11 +3330,11 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const + } + + if (type->u.width == 16) +- dst->u.reg.u.immconst_u32[0] = record->operands[0]; ++ dst->reg.u.immconst_u32[0] = record->operands[0]; + else if (type->u.width == 32) +- dst->u.reg.u.immconst_f32[0] = bitcast_uint_to_float(record->operands[0]); ++ dst->reg.u.immconst_f32[0] = bitcast_uint_to_float(record->operands[0]); + else if (type->u.width == 64) +- dst->u.reg.u.immconst_f64[0] = bitcast_uint64_to_double(record->operands[0]); ++ dst->reg.u.immconst_f64[0] = bitcast_uint64_to_double(record->operands[0]); + else + vkd3d_unreachable(); + +@@ -3344,13 +3400,13 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const + + /* Resolve later in case forward refs exist. */ + dst->type = type; +- dst->u.reg.type = VKD3DSPR_COUNT; +- dst->u.reg.idx[0].offset = value; ++ dst->reg.type = VKD3DSPR_COUNT; ++ dst->reg.idx[0].offset = value; + break; + + case CST_CODE_UNDEF: + dxil_record_validate_operand_max_count(record, 0, sm6); +- dst->u.reg.type = VKD3DSPR_UNDEF; ++ dst->reg.type = VKD3DSPR_UNDEF; + /* Mark as explicitly undefined, not the result of a missing constant code or instruction. */ + dst->is_undefined = true; + break; +@@ -3359,7 +3415,7 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const + FIXME("Unhandled constant code %u.\n", record->code); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, + "Constant code %u is unhandled.", record->code); +- dst->u.reg.type = VKD3DSPR_UNDEF; ++ dst->reg.type = VKD3DSPR_UNDEF; + break; + } + +@@ -3377,12 +3433,12 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const + for (i = base_value_idx; i < sm6->value_count; ++i) + { + dst = &sm6->values[i]; +- if (dst->u.reg.type != VKD3DSPR_COUNT) ++ if (dst->reg.type != VKD3DSPR_COUNT) + continue; + + type = dst->type; + +- src = &sm6->values[dst->u.reg.idx[0].offset]; ++ src = &sm6->values[dst->reg.idx[0].offset]; + if (!sm6_value_is_numeric_array(src)) + { + WARN("Value is not an array.\n"); +@@ -3393,7 +3449,7 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const + + *dst = *src; + dst->type = type; +- dst->u.reg.data_type = vkd3d_data_type_from_sm6_type(type->u.pointer.type); ++ dst->reg.data_type = vkd3d_data_type_from_sm6_type(type->u.pointer.type); + } + + return VKD3D_OK; +@@ -3442,7 +3498,7 @@ static void sm6_parser_declare_icb(struct sm6_parser *sm6, const struct sm6_type + 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); ++ register_init_with_id(&dst->reg, VKD3DSPR_IMMCONSTBUFFER, data_type, init); + } + + static void sm6_parser_declare_indexable_temp(struct sm6_parser *sm6, const struct sm6_type *elem_type, +@@ -3464,7 +3520,7 @@ static void sm6_parser_declare_indexable_temp(struct sm6_parser *sm6, const stru + /* The initialiser value index will be resolved later so forward references can be handled. */ + ins->declaration.indexable_temp.initialiser = (void *)(uintptr_t)init; + +- register_init_with_id(&dst->u.reg, VKD3DSPR_IDXTEMP, data_type, ins->declaration.indexable_temp.register_idx); ++ register_init_with_id(&dst->reg, VKD3DSPR_IDXTEMP, data_type, ins->declaration.indexable_temp.register_idx); + } + + static void sm6_parser_declare_tgsm_raw(struct sm6_parser *sm6, const struct sm6_type *elem_type, +@@ -3477,7 +3533,7 @@ static void sm6_parser_declare_tgsm_raw(struct sm6_parser *sm6, const struct sm6 + ins = sm6_parser_add_instruction(sm6, VKD3DSIH_DCL_TGSM_RAW); + dst_param_init(&ins->declaration.tgsm_raw.reg); + register_init_with_id(&ins->declaration.tgsm_raw.reg.reg, VKD3DSPR_GROUPSHAREDMEM, data_type, sm6->tgsm_count++); +- dst->u.reg = ins->declaration.tgsm_raw.reg.reg; ++ dst->reg = ins->declaration.tgsm_raw.reg.reg; + dst->structure_stride = 0; + ins->declaration.tgsm_raw.alignment = alignment; + byte_count = elem_type->u.width / 8u; +@@ -3503,7 +3559,7 @@ static void sm6_parser_declare_tgsm_structured(struct sm6_parser *sm6, const str + dst_param_init(&ins->declaration.tgsm_structured.reg); + register_init_with_id(&ins->declaration.tgsm_structured.reg.reg, VKD3DSPR_GROUPSHAREDMEM, + data_type, sm6->tgsm_count++); +- dst->u.reg = ins->declaration.tgsm_structured.reg.reg; ++ dst->reg = ins->declaration.tgsm_structured.reg.reg; + structure_stride = elem_type->u.width / 8u; + if (structure_stride != 4) + { +@@ -3812,11 +3868,11 @@ static enum vkd3d_result sm6_parser_globals_init(struct sm6_parser *sm6) + 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) ++ if (!sm6_value_is_register(value) || value->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; ++ if ((icb = resolve_forward_initialiser(value->reg.idx[0].offset, sm6))) ++ value->reg.idx[0].offset = icb->register_idx; + } + + return VKD3D_OK; +@@ -4027,8 +4083,9 @@ struct function_emission_state + unsigned int temp_idx; + }; + +-static bool sm6_parser_emit_reg_composite_construct(struct sm6_parser *sm6, const struct vkd3d_shader_register **operand_regs, +- unsigned int component_count, struct function_emission_state *state, struct vkd3d_shader_register *reg); ++static bool sm6_parser_emit_reg_composite_construct(struct sm6_parser *sm6, ++ const struct vkd3d_shader_register *operand_regs, unsigned int component_count, ++ struct function_emission_state *state, struct vkd3d_shader_register *reg); + + static void sm6_parser_emit_alloca(struct sm6_parser *sm6, const struct dxil_record *record, + struct vkd3d_shader_instruction *ins, struct sm6_value *dst) +@@ -4136,11 +4193,11 @@ static enum vkd3d_shader_opcode map_dx_atomicrmw_op(uint64_t code) + static void sm6_parser_emit_atomicrmw(struct sm6_parser *sm6, const struct dxil_record *record, + struct function_emission_state *state, struct sm6_value *dst) + { +- struct vkd3d_shader_register coord, const_offset, const_zero; +- const struct vkd3d_shader_register *regs[2]; + struct vkd3d_shader_dst_param *dst_params; + struct vkd3d_shader_src_param *src_params; ++ struct vkd3d_shader_register regs[2], reg; + struct vkd3d_shader_instruction *ins; ++ struct vkd3d_shader_register coord; + const struct sm6_value *ptr, *src; + enum vkd3d_shader_opcode op; + unsigned int i = 0; +@@ -4152,7 +4209,9 @@ static void sm6_parser_emit_atomicrmw(struct sm6_parser *sm6, const struct dxil_ + || !sm6_value_validate_is_backward_ref(ptr, sm6)) + return; + +- if (ptr->u.reg.type != VKD3DSPR_GROUPSHAREDMEM) ++ sm6_register_from_value(®, ptr); ++ ++ if (reg.type != VKD3DSPR_GROUPSHAREDMEM) + { + WARN("Register is not groupshared.\n"); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, +@@ -4187,17 +4246,11 @@ static void sm6_parser_emit_atomicrmw(struct sm6_parser *sm6, const struct dxil_ + + if (ptr->structure_stride) + { +- if (ptr->u.reg.idx[1].rel_addr) +- { +- regs[0] = &ptr->u.reg.idx[1].rel_addr->reg; +- } ++ if (reg.idx[1].rel_addr) ++ regs[0] = reg.idx[1].rel_addr->reg; + else +- { +- register_make_constant_uint(&const_offset, ptr->u.reg.idx[1].offset); +- regs[0] = &const_offset; +- } +- register_make_constant_uint(&const_zero, 0); +- regs[1] = &const_zero; ++ register_make_constant_uint(®s[0], reg.idx[1].offset); ++ register_make_constant_uint(®s[1], 0); + if (!sm6_parser_emit_reg_composite_construct(sm6, regs, 2, state, &coord)) + return; + } +@@ -4214,18 +4267,18 @@ static void sm6_parser_emit_atomicrmw(struct sm6_parser *sm6, const struct dxil_ + src_param_make_constant_uint(&src_params[0], 0); + src_param_init_from_value(&src_params[1], src); + ++ sm6_parser_init_ssa_value(sm6, dst); ++ + dst_params = instruction_dst_params_alloc(ins, 2, sm6); +- register_init_ssa_scalar(&dst_params[0].reg, dst->type, dst, sm6); ++ sm6_register_from_value(&dst_params[0].reg, dst); + dst_param_init(&dst_params[0]); + +- dst_params[1].reg = ptr->u.reg; ++ dst_params[1].reg = reg; + dst_params[1].reg.data_type = VKD3D_DATA_UNUSED; + dst_params[1].reg.idx[1].rel_addr = NULL; + dst_params[1].reg.idx[1].offset = ~0u; + dst_params[1].reg.idx_count = 1; + dst_param_init(&dst_params[1]); +- +- dst->u.reg = dst_params[0].reg; + } + + static enum vkd3d_shader_opcode map_binary_op(uint64_t code, const struct sm6_type *type_a, +@@ -4401,9 +4454,9 @@ 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); ++ sm6_parser_init_ssa_value(sm6, dst); ++ sm6_register_from_value(&dst_params[index].reg, dst); + vsir_dst_param_init_null(&dst_params[index ^ 1]); +- dst->u.reg = dst_params[index].reg; + } + else + { +@@ -4464,7 +4517,7 @@ static void sm6_parser_emit_br(struct sm6_parser *sm6, const struct dxil_record + dxil_record_validate_operand_max_count(record, i, sm6); + + code_block->terminator.type = TERMINATOR_COND_BR; +- code_block->terminator.conditional_reg = value->u.reg; ++ sm6_register_from_value(&code_block->terminator.conditional_reg, value); + code_block->terminator.true_block = sm6_function_get_block(function, record->operands[0], sm6); + code_block->terminator.false_block = sm6_function_get_block(function, record->operands[1], sm6); + } +@@ -4472,8 +4525,9 @@ static void sm6_parser_emit_br(struct sm6_parser *sm6, const struct dxil_record + ins->opcode = VKD3DSIH_NOP; + } + +-static bool sm6_parser_emit_reg_composite_construct(struct sm6_parser *sm6, const struct vkd3d_shader_register **operand_regs, +- unsigned int component_count, struct function_emission_state *state, struct vkd3d_shader_register *reg) ++static bool sm6_parser_emit_reg_composite_construct(struct sm6_parser *sm6, ++ const struct vkd3d_shader_register *operand_regs, unsigned int component_count, ++ struct function_emission_state *state, struct vkd3d_shader_register *reg) + { + struct vkd3d_shader_instruction *ins = state->ins; + struct vkd3d_shader_src_param *src_params; +@@ -4483,25 +4537,25 @@ static bool sm6_parser_emit_reg_composite_construct(struct sm6_parser *sm6, cons + + if (component_count == 1) + { +- *reg = *operand_regs[0]; ++ *reg = operand_regs[0]; + return true; + } + + for (i = 0; i < component_count; ++i) +- all_constant &= register_is_constant(operand_regs[i]); ++ all_constant &= register_is_constant(&operand_regs[i]); + + if (all_constant) + { +- vsir_register_init(reg, VKD3DSPR_IMMCONST, operand_regs[0]->data_type, 0); ++ vsir_register_init(reg, VKD3DSPR_IMMCONST, operand_regs[0].data_type, 0); + reg->dimension = VSIR_DIMENSION_VEC4; + for (i = 0; i < component_count; ++i) +- reg->u.immconst_u32[i] = operand_regs[i]->u.immconst_u32[0]; ++ reg->u.immconst_u32[i] = operand_regs[i].u.immconst_u32[0]; + for (; i < VKD3D_VEC4_SIZE; ++i) + reg->u.immconst_u32[i] = 0; + return true; + } + +- register_init_with_id(reg, VKD3DSPR_TEMP, operand_regs[0]->data_type, state->temp_idx++); ++ register_init_with_id(reg, VKD3DSPR_TEMP, operand_regs[0].data_type, state->temp_idx++); + reg->dimension = VSIR_DIMENSION_VEC4; + + for (i = 0; i < component_count; ++i, ++ins) +@@ -4512,7 +4566,7 @@ static bool sm6_parser_emit_reg_composite_construct(struct sm6_parser *sm6, cons + return false; + + src_param_init(&src_params[0]); +- src_params[0].reg = *operand_regs[i]; ++ src_params[0].reg = operand_regs[i]; + + if (!(dst_param = instruction_dst_params_alloc(ins, 1, sm6))) + return false; +@@ -4530,11 +4584,11 @@ static bool sm6_parser_emit_reg_composite_construct(struct sm6_parser *sm6, cons + static bool sm6_parser_emit_composite_construct(struct sm6_parser *sm6, const struct sm6_value **operands, + unsigned int component_count, struct function_emission_state *state, struct vkd3d_shader_register *reg) + { +- const struct vkd3d_shader_register *operand_regs[VKD3D_VEC4_SIZE]; ++ struct vkd3d_shader_register operand_regs[VKD3D_VEC4_SIZE]; + unsigned int i; + + for (i = 0; i < component_count; ++i) +- operand_regs[i] = &operands[i]->u.reg; ++ sm6_register_from_value(&operand_regs[i], operands[i]); + + return sm6_parser_emit_reg_composite_construct(sm6, operand_regs, component_count, state, reg); + } +@@ -4543,19 +4597,18 @@ static bool sm6_parser_emit_coordinate_construct(struct sm6_parser *sm6, const s + unsigned int max_operands, const struct sm6_value *z_operand, struct function_emission_state *state, + struct vkd3d_shader_register *reg) + { +- const struct vkd3d_shader_register *operand_regs[VKD3D_VEC4_SIZE]; ++ struct vkd3d_shader_register operand_regs[VKD3D_VEC4_SIZE]; + unsigned int component_count; + + for (component_count = 0; component_count < max_operands; ++component_count) + { + if (!z_operand && operands[component_count]->is_undefined) + break; +- operand_regs[component_count] = &operands[component_count]->u.reg; ++ sm6_register_from_value(&operand_regs[component_count], operands[component_count]); + } ++ + if (z_operand) +- { +- operand_regs[component_count++] = &z_operand->u.reg; +- } ++ sm6_register_from_value(&operand_regs[component_count++], z_operand); + + return sm6_parser_emit_reg_composite_construct(sm6, operand_regs, component_count, state, reg); + } +@@ -4780,7 +4833,7 @@ static void sm6_parser_emit_dx_atomic_binop(struct sm6_parser *sm6, enum dx_intr + } + else + { +- reg = operands[coord_idx]->u.reg; ++ sm6_register_from_value(®, operands[coord_idx]); + } + + for (i = coord_idx + coord_count; i < coord_idx + 3; ++i) +@@ -4810,7 +4863,7 @@ static void sm6_parser_emit_dx_atomic_binop(struct sm6_parser *sm6, enum dx_intr + dst_param_init(&dst_params[1]); + sm6_register_from_handle(sm6, &resource->u.handle, &dst_params[1].reg); + +- dst->u.reg = dst_params[0].reg; ++ dst->reg = dst_params[0].reg; + } + + static void sm6_parser_emit_dx_barrier(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, +@@ -5957,7 +6010,7 @@ static void sm6_parser_emit_dx_sincos(struct sm6_parser *sm6, enum dx_intrinsic_ + dst_param_init(&dst_params[1]); + register_init_ssa_scalar(&dst_params[index].reg, dst->type, dst, sm6); + vsir_dst_param_init_null(&dst_params[index ^ 1]); +- dst->u.reg = dst_params[index].reg; ++ dst->reg = dst_params[index].reg; + } + + static void sm6_parser_emit_dx_split_double(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, +@@ -6574,7 +6627,7 @@ static void sm6_parser_emit_unhandled(struct sm6_parser *sm6, struct vkd3d_shade + return; + + type = sm6_type_get_scalar_type(dst->type, 0); +- vsir_register_init(&dst->u.reg, VKD3DSPR_UNDEF, vkd3d_data_type_from_sm6_type(type), 0); ++ vsir_register_init(&dst->reg, VKD3DSPR_UNDEF, vkd3d_data_type_from_sm6_type(type), 0); + /* dst->is_undefined is not set here because it flags only explicitly undefined values. */ + } + +@@ -6680,7 +6733,7 @@ static void sm6_parser_emit_call(struct sm6_parser *sm6, const struct dxil_recor + "Expected a constant integer dx intrinsic function id."); + return; + } +- sm6_parser_decode_dx_op(sm6, register_get_uint_value(&op_value->u.reg), ++ sm6_parser_decode_dx_op(sm6, sm6_value_get_constant_uint(op_value), + fn_value->u.function.name, &operands[1], operand_count - 1, state, dst); + } + +@@ -6826,10 +6879,10 @@ 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; ++ sm6_register_from_value(&dst->reg, value); + /* 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); ++ dst->reg.data_type = vkd3d_data_type_from_sm6_type(type); + return; + } + +@@ -6841,7 +6894,7 @@ static void sm6_parser_emit_cast(struct sm6_parser *sm6, const struct dxil_recor + + /* bitcast */ + if (handler_idx == VKD3DSIH_MOV) +- src_param->reg.data_type = dst->u.reg.data_type; ++ src_param->reg.data_type = dst->reg.data_type; + } + + struct sm6_cmp_info +@@ -6994,6 +7047,7 @@ static void sm6_parser_emit_cmpxchg(struct sm6_parser *sm6, const struct dxil_re + struct vkd3d_shader_dst_param *dst_params; + struct vkd3d_shader_src_param *src_params; + const struct sm6_value *ptr, *cmp, *new; ++ struct vkd3d_shader_register reg; + unsigned int i = 0; + bool is_volatile; + uint64_t code; +@@ -7003,7 +7057,9 @@ static void sm6_parser_emit_cmpxchg(struct sm6_parser *sm6, const struct dxil_re + || !sm6_value_validate_is_backward_ref(ptr, sm6)) + return; + +- if (ptr->u.reg.type != VKD3DSPR_GROUPSHAREDMEM) ++ sm6_register_from_value(®, ptr); ++ ++ if (reg.type != VKD3DSPR_GROUPSHAREDMEM) + { + WARN("Register is not groupshared.\n"); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, +@@ -7063,10 +7119,10 @@ static void sm6_parser_emit_cmpxchg(struct sm6_parser *sm6, const struct dxil_re + return; + register_init_ssa_scalar(&dst_params[0].reg, dst->type, dst, sm6); + dst_param_init(&dst_params[0]); +- dst_params[1].reg = ptr->u.reg; ++ dst_params[1].reg = reg; + dst_param_init(&dst_params[1]); + +- dst->u.reg = dst_params[0].reg; ++ dst->reg = dst_params[0].reg; + } + + static void sm6_parser_emit_extractval(struct sm6_parser *sm6, const struct dxil_record *record, +@@ -7122,7 +7178,7 @@ static void sm6_parser_emit_extractval(struct sm6_parser *sm6, const struct dxil + + if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) + return; +- src_param->reg = src->u.reg; ++ sm6_register_from_value(&src_param->reg, src); + src_param_init_scalar(src_param, elem_idx); + + instruction_dst_param_init_ssa_scalar(ins, sm6); +@@ -7135,7 +7191,7 @@ static void sm6_parser_emit_gep(struct sm6_parser *sm6, const struct dxil_record + unsigned int elem_idx, operand_idx = 2; + enum bitcode_address_space addr_space; + const struct sm6_value *elem_value; +- struct vkd3d_shader_register *reg; ++ struct vkd3d_shader_register reg; + const struct sm6_value *src; + bool is_in_bounds; + +@@ -7149,7 +7205,9 @@ static void sm6_parser_emit_gep(struct sm6_parser *sm6, const struct dxil_record + return; + } + +- if (src->u.reg.idx_count > 1) ++ sm6_register_from_value(®, src); ++ ++ if (reg.idx_count > 1) + { + WARN("Unsupported stacked GEP.\n"); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, +@@ -7218,12 +7276,12 @@ static void sm6_parser_emit_gep(struct sm6_parser *sm6, const struct dxil_record + return; + } + +- reg = &dst->u.reg; +- *reg = src->u.reg; +- reg->idx[1].offset = 0; +- register_index_address_init(®->idx[1], elem_value, sm6); +- reg->idx[1].is_in_bounds = is_in_bounds; +- reg->idx_count = 2; ++ reg.idx[1].offset = 0; ++ register_index_address_init(®.idx[1], elem_value, sm6); ++ reg.idx[1].is_in_bounds = is_in_bounds; ++ reg.idx_count = 2; ++ ++ dst->reg = reg; + dst->structure_stride = src->structure_stride; + + ins->opcode = VKD3DSIH_NOP; +@@ -7235,6 +7293,7 @@ static void sm6_parser_emit_load(struct sm6_parser *sm6, const struct dxil_recor + const struct sm6_type *elem_type = NULL, *pointee_type; + unsigned int alignment, operand_count, i = 0; + struct vkd3d_shader_src_param *src_params; ++ struct vkd3d_shader_register reg; + const struct sm6_value *ptr; + uint64_t alignment_code; + +@@ -7272,25 +7331,29 @@ static void sm6_parser_emit_load(struct sm6_parser *sm6, const struct dxil_recor + if (record->operands[i]) + WARN("Ignoring volatile modifier.\n"); + ++ sm6_register_from_value(®, ptr); ++ + if (ptr->structure_stride) + { +- VKD3D_ASSERT(ptr->u.reg.type == VKD3DSPR_GROUPSHAREDMEM); ++ VKD3D_ASSERT(reg.type == VKD3DSPR_GROUPSHAREDMEM); + vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_LD_STRUCTURED); + + if (!(src_params = instruction_src_params_alloc(ins, 3, sm6))) + return; +- if (ptr->u.reg.idx[1].rel_addr) +- src_params[0] = *ptr->u.reg.idx[1].rel_addr; ++ if (reg.idx[1].rel_addr) ++ src_params[0] = *reg.idx[1].rel_addr; + else +- src_param_make_constant_uint(&src_params[0], ptr->u.reg.idx[1].offset); ++ src_param_make_constant_uint(&src_params[0], reg.idx[1].offset); + /* Struct offset is always zero as there is no struct, just an array. */ + src_param_make_constant_uint(&src_params[1], 0); + src_param_init_from_value(&src_params[2], ptr); + src_params[2].reg.alignment = alignment; ++ /* The offset is already in src_params[0]. */ ++ src_params[2].reg.idx_count = 1; + } + else + { +- operand_count = 1 + (ptr->u.reg.type == VKD3DSPR_GROUPSHAREDMEM); ++ operand_count = 1 + (reg.type == VKD3DSPR_GROUPSHAREDMEM); + vsir_instruction_init(ins, &sm6->p.location, (operand_count > 1) ? VKD3DSIH_LD_RAW : VKD3DSIH_MOV); + + if (!(src_params = instruction_src_params_alloc(ins, operand_count, sm6))) +@@ -7341,11 +7404,11 @@ static void sm6_parser_emit_phi(struct sm6_parser *sm6, const struct dxil_record + } + + dst->type = type; +- register_init_ssa_scalar(&dst->u.reg, type, dst, sm6); ++ register_init_ssa_scalar(&dst->reg, type, dst, sm6); + + if (!(phi = sm6_block_phi_require_space(code_block, sm6))) + return; +- phi->reg = dst->u.reg; ++ sm6_register_from_value(&phi->reg, dst); + phi->incoming_count = record->operand_count / 2u; + + if (!vkd3d_array_reserve((void **)&phi->incoming, &phi->incoming_capacity, phi->incoming_count, +@@ -7421,6 +7484,7 @@ static void sm6_parser_emit_store(struct sm6_parser *sm6, const struct dxil_reco + struct vkd3d_shader_src_param *src_params; + struct vkd3d_shader_dst_param *dst_param; + const struct sm6_value *ptr, *src; ++ struct vkd3d_shader_register reg; + uint64_t alignment_code; + + if (!(ptr = sm6_parser_get_value_by_ref(sm6, record, NULL, &i)) +@@ -7455,24 +7519,26 @@ static void sm6_parser_emit_store(struct sm6_parser *sm6, const struct dxil_reco + if (record->operands[i]) + WARN("Ignoring volatile modifier.\n"); + ++ sm6_register_from_value(®, ptr); ++ + if (ptr->structure_stride) + { +- VKD3D_ASSERT(ptr->u.reg.type == VKD3DSPR_GROUPSHAREDMEM); ++ VKD3D_ASSERT(reg.type == VKD3DSPR_GROUPSHAREDMEM); + vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_STORE_STRUCTURED); + + if (!(src_params = instruction_src_params_alloc(ins, 3, sm6))) + return; +- if (ptr->u.reg.idx[1].rel_addr) +- src_params[0] = *ptr->u.reg.idx[1].rel_addr; ++ if (reg.idx[1].rel_addr) ++ src_params[0] = *reg.idx[1].rel_addr; + else +- src_param_make_constant_uint(&src_params[0], ptr->u.reg.idx[1].offset); ++ src_param_make_constant_uint(&src_params[0], reg.idx[1].offset); + /* Struct offset is always zero as there is no struct, just an array. */ + src_param_make_constant_uint(&src_params[1], 0); + src_param_init_from_value(&src_params[2], src); + } + else + { +- operand_count = 1 + (ptr->u.reg.type == VKD3DSPR_GROUPSHAREDMEM); ++ operand_count = 1 + (reg.type == VKD3DSPR_GROUPSHAREDMEM); + vsir_instruction_init(ins, &sm6->p.location, (operand_count > 1) ? VKD3DSIH_STORE_RAW : VKD3DSIH_MOV); + + if (!(src_params = instruction_src_params_alloc(ins, operand_count, sm6))) +@@ -7484,7 +7550,7 @@ static void sm6_parser_emit_store(struct sm6_parser *sm6, const struct dxil_reco + + dst_param = instruction_dst_params_alloc(ins, 1, sm6); + dst_param_init(dst_param); +- dst_param->reg = ptr->u.reg; ++ dst_param->reg = reg; + dst_param->reg.alignment = alignment; + /* Groupshared stores contain the address in the src params. */ + if (dst_param->reg.type != VKD3DSPR_IDXTEMP) +@@ -7529,7 +7595,7 @@ static void sm6_parser_emit_switch(struct sm6_parser *sm6, const struct dxil_rec + return; + } + +- terminator->conditional_reg = src->u.reg; ++ sm6_register_from_value(&terminator->conditional_reg, src); + terminator->type = TERMINATOR_SWITCH; + + terminator->case_count = record->operand_count / 2u; +@@ -7645,7 +7711,7 @@ static bool sm6_metadata_get_uint_value(const struct sm6_parser *sm6, + if (!sm6_type_is_integer(value->type)) + return false; + +- *u = register_get_uint_value(&value->u.reg); ++ *u = sm6_value_get_constant_uint(value); + + return true; + } +@@ -7664,7 +7730,7 @@ static bool sm6_metadata_get_uint64_value(const struct sm6_parser *sm6, + if (!sm6_type_is_integer(value->type)) + return false; + +- *u = register_get_uint64_value(&value->u.reg); ++ *u = sm6_value_get_constant_uint(value); + + return true; + } +@@ -7683,7 +7749,7 @@ static bool sm6_metadata_get_float_value(const struct sm6_parser *sm6, + if (!sm6_type_is_floating_point(value->type)) + return false; + +- *f = register_get_float_value(&value->u.reg); ++ *f = sm6_value_get_constant_float(value); + + return true; + } +@@ -7868,7 +7934,7 @@ static void metadata_attachment_record_apply(const struct dxil_record *record, e + } + else if (metadata_node_get_unary_uint(node, &operand, sm6)) + { +- dst->u.reg.non_uniform = !!operand; ++ dst->reg.non_uniform = !!operand; + } + } + else +@@ -7940,13 +8006,13 @@ static enum vkd3d_result sm6_function_resolve_phi_incomings(const struct sm6_fun + "A PHI incoming value is not a constant or SSA register."); + return VKD3D_ERROR_INVALID_SHADER; + } +- if (src->u.reg.data_type != phi->reg.data_type) ++ if (src->reg.data_type != phi->reg.data_type) + { + WARN("Type mismatch.\n"); + vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_TYPE_MISMATCH, + "The type of a phi incoming value does not match the result type."); + } +- phi->incoming[j].reg = src->u.reg; ++ sm6_register_from_value(&phi->incoming[j].reg, src); + } + } + } +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c +index a6b46474812..0f9aafbe13e 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c +@@ -2291,6 +2291,26 @@ struct hlsl_ir_node *hlsl_new_interlocked(struct hlsl_ctx *ctx, enum hlsl_interl + return &interlocked->node; + } + ++static struct hlsl_ir_node *hlsl_new_sync(struct hlsl_ctx *ctx, ++ uint32_t sync_flags, const struct vkd3d_shader_location *loc) ++{ ++ struct hlsl_ir_sync *sync; ++ ++ if (!(sync = hlsl_alloc(ctx, sizeof(*sync)))) ++ return NULL; ++ ++ init_node(&sync->node, HLSL_IR_SYNC, NULL, loc); ++ sync->sync_flags = sync_flags; ++ ++ return &sync->node; ++} ++ ++struct hlsl_ir_node *hlsl_block_add_sync(struct hlsl_ctx *ctx, struct hlsl_block *block, ++ uint32_t sync_flags, const struct vkd3d_shader_location *loc) ++{ ++ return append_new_instr(ctx, block, hlsl_new_sync(ctx, sync_flags, loc)); ++} ++ + bool hlsl_index_is_noncontiguous(struct hlsl_ir_index *index) + { + struct hlsl_type *type = index->val.node->data_type; +@@ -2681,6 +2701,18 @@ static struct hlsl_ir_node *clone_interlocked(struct hlsl_ctx *ctx, + return &dst->node; + } + ++static struct hlsl_ir_node *clone_sync(struct hlsl_ctx *ctx, struct hlsl_ir_sync *src) ++{ ++ struct hlsl_ir_sync *dst; ++ ++ if (!(dst = hlsl_alloc(ctx, sizeof(*dst)))) ++ return NULL; ++ init_node(&dst->node, HLSL_IR_SYNC, NULL, &src->node.loc); ++ dst->sync_flags = src->sync_flags; ++ ++ return &dst->node; ++} ++ + static struct hlsl_ir_node *clone_compile(struct hlsl_ctx *ctx, + struct clone_instr_map *map, struct hlsl_ir_compile *compile) + { +@@ -2884,6 +2916,9 @@ static struct hlsl_ir_node *clone_instr(struct hlsl_ctx *ctx, + case HLSL_IR_INTERLOCKED: + return clone_interlocked(ctx, map, hlsl_ir_interlocked(instr)); + ++ case HLSL_IR_SYNC: ++ return clone_sync(ctx, hlsl_ir_sync(instr)); ++ + case HLSL_IR_COMPILE: + return clone_compile(ctx, map, hlsl_ir_compile(instr)); + +@@ -3341,7 +3376,9 @@ const char *hlsl_node_type_to_string(enum hlsl_ir_node_type type) + [HLSL_IR_STORE ] = "HLSL_IR_STORE", + [HLSL_IR_SWITCH ] = "HLSL_IR_SWITCH", + [HLSL_IR_SWIZZLE ] = "HLSL_IR_SWIZZLE", ++ + [HLSL_IR_INTERLOCKED ] = "HLSL_IR_INTERLOCKED", ++ [HLSL_IR_SYNC ] = "HLSL_IR_SYNC", + + [HLSL_IR_COMPILE] = "HLSL_IR_COMPILE", + [HLSL_IR_SAMPLER_STATE] = "HLSL_IR_SAMPLER_STATE", +@@ -3831,6 +3868,19 @@ static void dump_ir_interlocked(struct vkd3d_string_buffer *buffer, const struct + vkd3d_string_buffer_printf(buffer, ")"); + } + ++static void dump_ir_sync(struct vkd3d_string_buffer *buffer, const struct hlsl_ir_sync *sync) ++{ ++ vkd3d_string_buffer_printf(buffer, "sync"); ++ if (sync->sync_flags & VKD3DSSF_GLOBAL_UAV) ++ vkd3d_string_buffer_printf(buffer, "_uglobal"); ++ if (sync->sync_flags & VKD3DSSF_THREAD_GROUP_UAV) ++ vkd3d_string_buffer_printf(buffer, "_ugroup"); ++ if (sync->sync_flags & VKD3DSSF_GROUP_SHARED_MEMORY) ++ vkd3d_string_buffer_printf(buffer, "_g"); ++ if (sync->sync_flags & VKD3DSSF_THREAD_GROUP) ++ vkd3d_string_buffer_printf(buffer, "_t"); ++} ++ + static void dump_ir_compile(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer, + const struct hlsl_ir_compile *compile) + { +@@ -3968,6 +4018,10 @@ static void dump_instr(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer, + dump_ir_interlocked(buffer, hlsl_ir_interlocked(instr)); + break; + ++ case HLSL_IR_SYNC: ++ dump_ir_sync(buffer, hlsl_ir_sync(instr)); ++ break; ++ + case HLSL_IR_COMPILE: + dump_ir_compile(ctx, buffer, hlsl_ir_compile(instr)); + break; +@@ -4205,6 +4259,11 @@ static void free_ir_interlocked(struct hlsl_ir_interlocked *interlocked) + vkd3d_free(interlocked); + } + ++static void free_ir_sync(struct hlsl_ir_sync *sync) ++{ ++ vkd3d_free(sync); ++} ++ + static void free_ir_compile(struct hlsl_ir_compile *compile) + { + unsigned int i; +@@ -4295,6 +4354,10 @@ void hlsl_free_instr(struct hlsl_ir_node *node) + free_ir_interlocked(hlsl_ir_interlocked(node)); + break; + ++ case HLSL_IR_SYNC: ++ free_ir_sync(hlsl_ir_sync(node)); ++ break; ++ + case HLSL_IR_COMPILE: + free_ir_compile(hlsl_ir_compile(node)); + break; +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h +index 8cb805a2e66..9eb86534f81 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h +@@ -329,7 +329,9 @@ enum hlsl_ir_node_type + HLSL_IR_STORE, + HLSL_IR_SWIZZLE, + HLSL_IR_SWITCH, ++ + HLSL_IR_INTERLOCKED, ++ HLSL_IR_SYNC, + + HLSL_IR_COMPILE, + HLSL_IR_SAMPLER_STATE, +@@ -1006,6 +1008,15 @@ struct hlsl_ir_interlocked + struct hlsl_src coords, cmp_value, value; + }; + ++/* Represents a thread synchronization instruction such as GroupMemoryBarrier().*/ ++struct hlsl_ir_sync ++{ ++ struct hlsl_ir_node node; ++ ++ /* Flags from enum vkd3d_shader_sync_flags. */ ++ uint32_t sync_flags; ++}; ++ + struct hlsl_scope + { + /* Item entry for hlsl_ctx.scopes. */ +@@ -1343,6 +1354,12 @@ static inline struct hlsl_ir_interlocked *hlsl_ir_interlocked(const struct hlsl_ + return CONTAINING_RECORD(node, struct hlsl_ir_interlocked, node); + } + ++static inline struct hlsl_ir_sync *hlsl_ir_sync(const struct hlsl_ir_node *node) ++{ ++ VKD3D_ASSERT(node->type == HLSL_IR_SYNC); ++ return CONTAINING_RECORD(node, struct hlsl_ir_sync, node); ++} ++ + static inline struct hlsl_ir_compile *hlsl_ir_compile(const struct hlsl_ir_node *node) + { + VKD3D_ASSERT(node->type == HLSL_IR_COMPILE); +@@ -1582,6 +1599,8 @@ void hlsl_block_add_store_parent(struct hlsl_ctx *ctx, struct hlsl_block *block, + unsigned int writemask, const struct vkd3d_shader_location *loc); + struct hlsl_ir_node *hlsl_block_add_swizzle(struct hlsl_ctx *ctx, struct hlsl_block *block, uint32_t s, + unsigned int width, struct hlsl_ir_node *val, const struct vkd3d_shader_location *loc); ++struct hlsl_ir_node *hlsl_block_add_sync(struct hlsl_ctx *ctx, struct hlsl_block *block, ++ uint32_t sync_flags, const struct vkd3d_shader_location *loc); + struct hlsl_ir_node *hlsl_block_add_uint_constant(struct hlsl_ctx *ctx, struct hlsl_block *block, + unsigned int n, const struct vkd3d_shader_location *loc); + struct hlsl_ir_node *hlsl_block_add_unary_expr(struct hlsl_ctx *ctx, struct hlsl_block *block, +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y +index 702fd30bda3..05657d27b38 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y +@@ -574,13 +574,14 @@ static struct hlsl_default_value evaluate_static_expression(struct hlsl_ctx *ctx + /* fall-through */ + case HLSL_IR_CALL: + case HLSL_IR_IF: ++ case HLSL_IR_INTERLOCKED: + case HLSL_IR_LOOP: + case HLSL_IR_JUMP: + case HLSL_IR_RESOURCE_LOAD: + case HLSL_IR_RESOURCE_STORE: + case HLSL_IR_SWITCH: +- case HLSL_IR_INTERLOCKED: + case HLSL_IR_STATEBLOCK_CONSTANT: ++ case HLSL_IR_SYNC: + hlsl_error(ctx, &node->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, + "Expected literal expression."); + break; +@@ -5110,6 +5111,67 @@ static bool intrinsic_InterlockedXor(struct hlsl_ctx *ctx, + return intrinsic_interlocked(ctx, HLSL_INTERLOCKED_XOR, params, loc, "InterlockedXor"); + } + ++static void validate_group_barrier_profile(struct hlsl_ctx *ctx, const struct vkd3d_shader_location *loc) ++{ ++ if (ctx->profile->type != VKD3D_SHADER_TYPE_COMPUTE || hlsl_version_lt(ctx, 5, 0)) ++ { ++ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE, ++ "Group barriers can only be used in compute shaders 5.0 or higher."); ++ } ++} ++ ++static bool intrinsic_AllMemoryBarrier(struct hlsl_ctx *ctx, ++ const struct parse_initializer *params, const struct vkd3d_shader_location *loc) ++{ ++ validate_group_barrier_profile(ctx, loc); ++ return !!hlsl_block_add_sync(ctx, params->instrs, VKD3DSSF_GLOBAL_UAV ++ | VKD3DSSF_GROUP_SHARED_MEMORY, loc); ++} ++ ++static bool intrinsic_AllMemoryBarrierWithGroupSync(struct hlsl_ctx *ctx, ++ const struct parse_initializer *params, const struct vkd3d_shader_location *loc) ++{ ++ validate_group_barrier_profile(ctx, loc); ++ return !!hlsl_block_add_sync(ctx, params->instrs, VKD3DSSF_GLOBAL_UAV ++ | VKD3DSSF_GROUP_SHARED_MEMORY | VKD3DSSF_THREAD_GROUP, loc); ++} ++ ++static bool intrinsic_DeviceMemoryBarrier(struct hlsl_ctx *ctx, ++ const struct parse_initializer *params, const struct vkd3d_shader_location *loc) ++{ ++ if ((ctx->profile->type != VKD3D_SHADER_TYPE_COMPUTE && ctx->profile->type != VKD3D_SHADER_TYPE_PIXEL) ++ || hlsl_version_lt(ctx, 5, 0)) ++ { ++ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE, ++ "DeviceMemoryBarrier() can only be used in pixel and compute shaders 5.0 or higher."); ++ } ++ return !!hlsl_block_add_sync(ctx, params->instrs, VKD3DSSF_GLOBAL_UAV, loc); ++} ++ ++static bool intrinsic_DeviceMemoryBarrierWithGroupSync(struct hlsl_ctx *ctx, ++ const struct parse_initializer *params, const struct vkd3d_shader_location *loc) ++{ ++ validate_group_barrier_profile(ctx, loc); ++ return !!hlsl_block_add_sync(ctx, params->instrs, VKD3DSSF_GLOBAL_UAV ++ | VKD3DSSF_THREAD_GROUP, loc); ++} ++ ++static bool intrinsic_GroupMemoryBarrier(struct hlsl_ctx *ctx, ++ const struct parse_initializer *params, const struct vkd3d_shader_location *loc) ++{ ++ validate_group_barrier_profile(ctx, loc); ++ return !!hlsl_block_add_sync(ctx, params->instrs, ++ VKD3DSSF_GROUP_SHARED_MEMORY, loc); ++} ++ ++static bool intrinsic_GroupMemoryBarrierWithGroupSync(struct hlsl_ctx *ctx, ++ const struct parse_initializer *params, const struct vkd3d_shader_location *loc) ++{ ++ validate_group_barrier_profile(ctx, loc); ++ return !!hlsl_block_add_sync(ctx, params->instrs, ++ VKD3DSSF_GROUP_SHARED_MEMORY | VKD3DSSF_THREAD_GROUP, loc); ++} ++ + static const struct intrinsic_function + { + const char *name; +@@ -5121,8 +5183,14 @@ static const struct intrinsic_function + intrinsic_functions[] = + { + /* Note: these entries should be kept in alphabetical order. */ ++ {"AllMemoryBarrier", 0, true, intrinsic_AllMemoryBarrier}, ++ {"AllMemoryBarrierWithGroupSync", 0, true, intrinsic_AllMemoryBarrierWithGroupSync}, + {"D3DCOLORtoUBYTE4", 1, true, intrinsic_d3dcolor_to_ubyte4}, ++ {"DeviceMemoryBarrier", 0, true, intrinsic_DeviceMemoryBarrier}, ++ {"DeviceMemoryBarrierWithGroupSync", 0, true, intrinsic_DeviceMemoryBarrierWithGroupSync}, + {"GetRenderTargetSampleCount", 0, true, intrinsic_GetRenderTargetSampleCount}, ++ {"GroupMemoryBarrier", 0, true, intrinsic_GroupMemoryBarrier}, ++ {"GroupMemoryBarrierWithGroupSync", 0, true, intrinsic_GroupMemoryBarrierWithGroupSync}, + {"InterlockedAdd", -1, true, intrinsic_InterlockedAdd}, + {"InterlockedAnd", -1, true, intrinsic_InterlockedAnd}, + {"InterlockedCompareExchange", 4, true, intrinsic_InterlockedCompareExchange}, +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +index bc14885af2b..9c3affda534 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +@@ -288,7 +288,7 @@ static bool types_are_semantic_equivalent(struct hlsl_ctx *ctx, const struct hls + + static struct hlsl_ir_var *add_semantic_var(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *func, + struct hlsl_ir_var *var, struct hlsl_type *type, uint32_t modifiers, struct hlsl_semantic *semantic, +- uint32_t index, bool output, bool force_align, const struct vkd3d_shader_location *loc) ++ uint32_t index, bool output, bool force_align, bool create, const struct vkd3d_shader_location *loc) + { + struct hlsl_semantic new_semantic; + struct hlsl_ir_var *ext_var; +@@ -311,6 +311,11 @@ static struct hlsl_ir_var *add_semantic_var(struct hlsl_ctx *ctx, struct hlsl_ir + || ext_var->data_type->class <= HLSL_CLASS_VECTOR); + VKD3D_ASSERT(hlsl_type_is_primitive_array(type) || type->class <= HLSL_CLASS_VECTOR); + ++ vkd3d_free(new_name); ++ ++ if (!create) ++ return ext_var; ++ + if (output) + { + if (index >= semantic->reported_duplicated_output_next_index) +@@ -336,11 +341,12 @@ static struct hlsl_ir_var *add_semantic_var(struct hlsl_ctx *ctx, struct hlsl_ir + } + } + +- vkd3d_free(new_name); + return ext_var; + } + } + ++ VKD3D_ASSERT(create); ++ + if (!(hlsl_clone_semantic(ctx, &new_semantic, semantic))) + { + vkd3d_free(new_name); +@@ -429,7 +435,7 @@ static void prepend_input_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function_dec + prim_type_src->modifiers = var->data_type->modifiers & HLSL_PRIMITIVE_MODIFIERS_MASK; + + if (!(input = add_semantic_var(ctx, func, var, prim_type_src, +- modifiers, semantic, semantic_index + i, false, force_align, loc))) ++ modifiers, semantic, semantic_index + i, false, force_align, true, loc))) + return; + hlsl_init_simple_deref_from_var(&prim_deref, input); + +@@ -442,7 +448,7 @@ static void prepend_input_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function_dec + else + { + if (!(input = add_semantic_var(ctx, func, var, vector_type_src, +- modifiers, semantic, semantic_index + i, false, force_align, loc))) ++ modifiers, semantic, semantic_index + i, false, force_align, true, loc))) + return; + + if (!(load = hlsl_new_var_load(ctx, input, &var->loc))) +@@ -550,9 +556,9 @@ static void prepend_input_var_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function + list_move_head(&func->body.instrs, &block.instrs); + } + +-static void append_output_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *func, +- struct hlsl_ir_load *rhs, uint32_t modifiers, +- struct hlsl_semantic *semantic, uint32_t semantic_index, bool force_align) ++static void append_output_copy(struct hlsl_ctx *ctx, struct hlsl_block *block, ++ struct hlsl_ir_function_decl *func, struct hlsl_ir_load *rhs, uint32_t modifiers, ++ struct hlsl_semantic *semantic, uint32_t semantic_index, bool force_align, bool create) + { + struct hlsl_type *type = rhs->node.data_type, *vector_type; + struct vkd3d_shader_location *loc = &rhs->node.loc; +@@ -582,49 +588,48 @@ static void append_output_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function_dec + struct hlsl_ir_node *load; + + if (!(output = add_semantic_var(ctx, func, var, vector_type, +- modifiers, semantic, semantic_index + i, true, force_align, loc))) ++ modifiers, semantic, semantic_index + i, true, force_align, create, loc))) + return; + + if (type->class == HLSL_CLASS_MATRIX) + { +- c = hlsl_block_add_uint_constant(ctx, &func->body, i, &var->loc); +- load = hlsl_block_add_load_index(ctx, &func->body, &rhs->src, c, &var->loc); ++ c = hlsl_block_add_uint_constant(ctx, block, i, &var->loc); ++ load = hlsl_block_add_load_index(ctx, block, &rhs->src, c, &var->loc); + } + else + { + VKD3D_ASSERT(i == 0); + +- load = hlsl_block_add_load_index(ctx, &func->body, &rhs->src, NULL, &var->loc); ++ load = hlsl_block_add_load_index(ctx, block, &rhs->src, NULL, &var->loc); + } + +- hlsl_block_add_simple_store(ctx, &func->body, output, load); ++ hlsl_block_add_simple_store(ctx, block, output, load); + } + } + +-static void append_output_copy_recurse(struct hlsl_ctx *ctx, +- struct hlsl_ir_function_decl *func, struct hlsl_ir_load *rhs, uint32_t modifiers, +- struct hlsl_semantic *semantic, uint32_t semantic_index, bool force_align) ++static void append_output_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_block *block, ++ struct hlsl_ir_function_decl *func, const struct hlsl_type *type, struct hlsl_ir_load *rhs, uint32_t modifiers, ++ struct hlsl_semantic *semantic, uint32_t semantic_index, bool force_align, bool create) + { + struct vkd3d_shader_location *loc = &rhs->node.loc; +- struct hlsl_type *type = rhs->node.data_type; + struct hlsl_ir_var *var = rhs->src.var; + struct hlsl_ir_node *c; + unsigned int i; + + if (type->class == HLSL_CLASS_ARRAY || type->class == HLSL_CLASS_STRUCT) + { +- struct hlsl_ir_load *element_load; +- struct hlsl_struct_field *field; +- uint32_t elem_semantic_index; +- + for (i = 0; i < hlsl_type_element_count(type); ++i) + { +- uint32_t element_modifiers; ++ uint32_t element_modifiers, elem_semantic_index; ++ const struct hlsl_type *element_type; ++ struct hlsl_ir_load *element_load; ++ struct hlsl_struct_field *field; + + if (type->class == HLSL_CLASS_ARRAY) + { + elem_semantic_index = semantic_index + + i * hlsl_type_get_array_element_reg_size(type->e.array.type, HLSL_REGSET_NUMERIC) / 4; ++ element_type = type->e.array.type; + element_modifiers = modifiers; + force_align = true; + } +@@ -637,23 +642,24 @@ static void append_output_copy_recurse(struct hlsl_ctx *ctx, + semantic = &field->semantic; + elem_semantic_index = semantic->index; + loc = &field->loc; ++ element_type = field->type; + element_modifiers = combine_field_storage_modifiers(modifiers, field->storage_modifiers); + force_align = (i == 0); + } + +- c = hlsl_block_add_uint_constant(ctx, &func->body, i, &var->loc); ++ c = hlsl_block_add_uint_constant(ctx, block, i, &var->loc); + + if (!(element_load = hlsl_new_load_index(ctx, &rhs->src, c, loc))) + return; +- hlsl_block_add_instr(&func->body, &element_load->node); ++ hlsl_block_add_instr(block, &element_load->node); + +- append_output_copy_recurse(ctx, func, element_load, element_modifiers, +- semantic, elem_semantic_index, force_align); ++ append_output_copy_recurse(ctx, block, func, element_type, element_load, element_modifiers, semantic, ++ elem_semantic_index, force_align, create); + } + } + else + { +- append_output_copy(ctx, func, rhs, modifiers, semantic, semantic_index, force_align); ++ append_output_copy(ctx, block, func, rhs, modifiers, semantic, semantic_index, force_align, create); + } + } + +@@ -669,7 +675,8 @@ static void append_output_var_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function + return; + hlsl_block_add_instr(&func->body, &load->node); + +- append_output_copy_recurse(ctx, func, load, var->storage_modifiers, &var->semantic, var->semantic.index, false); ++ append_output_copy_recurse(ctx, &func->body, func, var->data_type, load, var->storage_modifiers, ++ &var->semantic, var->semantic.index, false, true); + } + + bool hlsl_transform_ir(struct hlsl_ctx *ctx, bool (*func)(struct hlsl_ctx *ctx, struct hlsl_ir_node *, void *), +@@ -2453,6 +2460,7 @@ static bool copy_propagation_transform_block(struct hlsl_ctx *ctx, struct hlsl_b + + case HLSL_IR_INTERLOCKED: + progress |= copy_propagation_transform_interlocked(ctx, hlsl_ir_interlocked(instr), state); ++ break; + + default: + break; +@@ -2894,6 +2902,16 @@ static void record_vectorizable_store(struct hlsl_ctx *ctx, struct hlsl_block *b + ++state->count; + } + ++static void mark_store_groups_dirty(struct hlsl_ctx *ctx, ++ struct vectorize_stores_state *state, struct hlsl_ir_var *var) ++{ ++ for (unsigned int i = 0; i < state->count; ++i) ++ { ++ if (state->groups[i].stores[0]->lhs.var == var) ++ state->groups[i].dirty = true; ++ } ++} ++ + static void find_vectorizable_store_groups(struct hlsl_ctx *ctx, struct hlsl_block *block, + struct vectorize_stores_state *state) + { +@@ -2907,20 +2925,21 @@ static void find_vectorizable_store_groups(struct hlsl_ctx *ctx, struct hlsl_blo + } + else if (instr->type == HLSL_IR_LOAD) + { +- struct hlsl_ir_var *var = hlsl_ir_load(instr)->src.var; +- + /* By vectorizing store A with store B, we are effectively moving + * store A down to happen at the same time as store B. + * If there was a load of the same variable between the two, this + * would be incorrect. + * Therefore invalidate all stores to this variable. As above, we + * could be more granular if necessary. */ +- +- for (unsigned int i = 0; i < state->count; ++i) +- { +- if (state->groups[i].stores[0]->lhs.var == var) +- state->groups[i].dirty = true; +- } ++ mark_store_groups_dirty(ctx, state, hlsl_ir_load(instr)->src.var); ++ } ++ else if (instr->type == HLSL_IR_INTERLOCKED) ++ { ++ /* An interlocked operation can be used on shared memory variables, ++ * and it is at the same time both a store and a load, thus, we ++ * should also mark all stores to this variable as dirty once we ++ * find one.*/ ++ mark_store_groups_dirty(ctx, state, hlsl_ir_interlocked(instr)->dst.var); + } + else if (instr->type == HLSL_IR_IF) + { +@@ -3338,6 +3357,59 @@ static bool split_struct_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr + return true; + } + ++struct stream_append_ctx ++{ ++ struct hlsl_ir_function_decl *func; ++ bool created; ++}; ++ ++static bool lower_stream_appends(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) ++{ ++ struct stream_append_ctx *append_ctx = context; ++ struct hlsl_ir_resource_store *store; ++ const struct hlsl_ir_node *rhs; ++ const struct hlsl_type *type; ++ struct hlsl_ir_var *var; ++ struct hlsl_block block; ++ ++ if (instr->type != HLSL_IR_RESOURCE_STORE) ++ return false; ++ ++ store = hlsl_ir_resource_store(instr); ++ if (store->store_type != HLSL_RESOURCE_STREAM_APPEND) ++ return false; ++ ++ rhs = store->value.node; ++ var = store->resource.var; ++ type = hlsl_get_stream_output_type(var->data_type); ++ ++ if (rhs->type != HLSL_IR_LOAD) ++ { ++ hlsl_fixme(ctx, &instr->loc, "Stream append rhs is not HLSL_IR_LOAD. Broadcast may be missing."); ++ return false; ++ } ++ ++ VKD3D_ASSERT(var->regs[HLSL_REGSET_STREAM_OUTPUTS].allocated); ++ ++ if (var->regs[HLSL_REGSET_STREAM_OUTPUTS].index) ++ { ++ hlsl_fixme(ctx, &instr->loc, "Append to an output stream with a nonzero stream index."); ++ return false; ++ } ++ ++ hlsl_block_init(&block); ++ ++ append_output_copy_recurse(ctx, &block, append_ctx->func, type->e.so.type, hlsl_ir_load(rhs), var->storage_modifiers, ++ &var->semantic, var->semantic.index, false, !append_ctx->created); ++ append_ctx->created = true; ++ ++ list_move_before(&instr->entry, &block.instrs); ++ hlsl_src_remove(&store->value); ++ ++ return true; ++ ++} ++ + static bool split_matrix_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) + { + const struct hlsl_ir_node *rhs; +@@ -5127,11 +5199,12 @@ static bool dce(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) + + case HLSL_IR_CALL: + case HLSL_IR_IF: ++ case HLSL_IR_INTERLOCKED: + case HLSL_IR_JUMP: + case HLSL_IR_LOOP: + case HLSL_IR_RESOURCE_STORE: + case HLSL_IR_SWITCH: +- case HLSL_IR_INTERLOCKED: ++ case HLSL_IR_SYNC: + break; + case HLSL_IR_STATEBLOCK_CONSTANT: + /* Stateblock constants should not appear in the shader program. */ +@@ -5415,6 +5488,7 @@ static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop + } + case HLSL_IR_CONSTANT: + case HLSL_IR_STRING_CONSTANT: ++ case HLSL_IR_SYNC: + break; + case HLSL_IR_COMPILE: + case HLSL_IR_SAMPLER_STATE: +@@ -6441,7 +6515,8 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var + } + } + +-static void allocate_semantic_registers(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func) ++static void allocate_semantic_registers(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, ++ uint32_t *output_reg_count) + { + struct register_allocator in_prim_allocator = {0}, patch_constant_out_patch_allocator = {0}; + struct register_allocator input_allocator = {0}, output_allocator = {0}; +@@ -6478,6 +6553,8 @@ static void allocate_semantic_registers(struct hlsl_ctx *ctx, struct hlsl_ir_fun + allocate_semantic_register(ctx, var, &output_allocator, true, !is_pixel_shader); + } + ++ *output_reg_count = output_allocator.reg_count; ++ + vkd3d_free(in_prim_allocator.allocations); + vkd3d_free(patch_constant_out_patch_allocator.allocations); + vkd3d_free(input_allocator.allocations); +@@ -7641,6 +7718,42 @@ static void validate_and_record_stream_outputs(struct hlsl_ctx *ctx) + /* TODO: check that maxvertexcount * outputdatasize <= 1024. */ + } + ++static void validate_max_output_size(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, ++ uint32_t output_reg_count) ++{ ++ unsigned int max_output_size, comp_count = 0; ++ unsigned int *reg_comp_count; ++ struct hlsl_ir_var *var; ++ uint32_t id; ++ ++ if (ctx->result) ++ return; ++ ++ if (!(reg_comp_count = hlsl_calloc(ctx, output_reg_count, sizeof(*reg_comp_count)))) ++ return; ++ ++ LIST_FOR_EACH_ENTRY(var, &entry_func->extern_vars, struct hlsl_ir_var, extern_entry) ++ { ++ if (!var->is_output_semantic) ++ continue; ++ ++ VKD3D_ASSERT(var->regs[HLSL_REGSET_NUMERIC].allocated); ++ id = var->regs[HLSL_REGSET_NUMERIC].id; ++ reg_comp_count[id] = max(reg_comp_count[id], vkd3d_log2i(var->regs[HLSL_REGSET_NUMERIC].writemask) + 1); ++ } ++ ++ for (id = 0; id < output_reg_count; ++id) ++ comp_count += reg_comp_count[id]; ++ ++ max_output_size = ctx->max_vertex_count * comp_count; ++ if (max_output_size > 1024) ++ hlsl_error(ctx, &entry_func->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MAX_VERTEX_COUNT, ++ "Max vertex count (%u) * output data component count (%u) = %u, which is greater than 1024.", ++ ctx->max_vertex_count, comp_count, max_output_size); ++ ++ vkd3d_free(reg_comp_count); ++} ++ + static void remove_unreachable_code(struct hlsl_ctx *ctx, struct hlsl_block *body) + { + struct hlsl_ir_node *instr, *next; +@@ -10718,8 +10831,20 @@ static bool sm4_generate_vsir_instr_resource_store(struct hlsl_ctx *ctx, + + if (store->store_type != HLSL_RESOURCE_STORE) + { +- hlsl_fixme(ctx, &instr->loc, "Stream output operations."); +- return false; ++ enum vkd3d_shader_opcode opcode = store->store_type == HLSL_RESOURCE_STREAM_APPEND ++ ? VKD3DSIH_EMIT : VKD3DSIH_CUT; ++ ++ VKD3D_ASSERT(!store->value.node && !store->coords.node); ++ VKD3D_ASSERT(store->resource.var->regs[HLSL_REGSET_STREAM_OUTPUTS].allocated); ++ ++ if (store->resource.var->regs[HLSL_REGSET_STREAM_OUTPUTS].index) ++ { ++ hlsl_fixme(ctx, &instr->loc, "Stream output operation with a nonzero stream index."); ++ return false; ++ } ++ ++ ins = generate_vsir_add_program_instruction(ctx, program, &store->node.loc, opcode, 0, 0); ++ return !!ins; + } + + if (!store->resource.var->is_uniform) +@@ -11264,6 +11389,19 @@ static bool sm4_generate_vsir_instr_jump(struct hlsl_ctx *ctx, + } + } + ++static bool sm4_generate_vsir_instr_sync(struct hlsl_ctx *ctx, ++ struct vsir_program *program, const struct hlsl_ir_sync *sync) ++{ ++ const struct hlsl_ir_node *instr = &sync->node; ++ struct vkd3d_shader_instruction *ins; ++ ++ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_SYNC, 0, 0))) ++ return false; ++ ins->flags = sync->sync_flags; ++ ++ return true; ++} ++ + static void sm4_generate_vsir_block(struct hlsl_ctx *ctx, struct hlsl_block *block, struct vsir_program *program); + + static void sm4_generate_vsir_instr_if(struct hlsl_ctx *ctx, struct vsir_program *program, struct hlsl_ir_if *iff) +@@ -11414,6 +11552,10 @@ static void sm4_generate_vsir_block(struct hlsl_ctx *ctx, struct hlsl_block *blo + sm4_generate_vsir_instr_interlocked(ctx, program, hlsl_ir_interlocked(instr)); + break; + ++ case HLSL_IR_SYNC: ++ sm4_generate_vsir_instr_sync(ctx, program, hlsl_ir_sync(instr)); ++ break; ++ + default: + break; + } +@@ -13236,6 +13378,8 @@ static void process_entry_function(struct hlsl_ctx *ctx, + struct hlsl_block static_initializers, global_uniforms; + struct hlsl_block *const body = &entry_func->body; + struct recursive_call_ctx recursive_call_ctx; ++ struct stream_append_ctx stream_append_ctx; ++ uint32_t output_reg_count; + struct hlsl_ir_var *var; + unsigned int i; + bool progress; +@@ -13461,6 +13605,10 @@ static void process_entry_function(struct hlsl_ctx *ctx, + { + allocate_stream_outputs(ctx); + validate_and_record_stream_outputs(ctx); ++ ++ memset(&stream_append_ctx, 0, sizeof(stream_append_ctx)); ++ stream_append_ctx.func = entry_func; ++ hlsl_transform_ir(ctx, lower_stream_appends, body, &stream_append_ctx); + } + + if (profile->major_version < 4) +@@ -13519,7 +13667,10 @@ static void process_entry_function(struct hlsl_ctx *ctx, + + allocate_register_reservations(ctx, &ctx->extern_vars); + allocate_register_reservations(ctx, &entry_func->extern_vars); +- allocate_semantic_registers(ctx, entry_func); ++ allocate_semantic_registers(ctx, entry_func, &output_reg_count); ++ ++ if (profile->type == VKD3D_SHADER_TYPE_GEOMETRY) ++ validate_max_output_size(ctx, entry_func, output_reg_count); + } + + int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, +diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c +index c29bedfaaa9..29b03871e05 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/tpf.c ++++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c +@@ -4165,6 +4165,7 @@ static void tpf_handle_instruction(struct tpf_compiler *tpf, const struct vkd3d_ + case VKD3DSIH_BREAK: + case VKD3DSIH_CASE: + case VKD3DSIH_CONTINUE: ++ case VKD3DSIH_CUT: + case VKD3DSIH_DEFAULT: + case VKD3DSIH_DISCARD: + case VKD3DSIH_DIV: +@@ -4178,6 +4179,7 @@ static void tpf_handle_instruction(struct tpf_compiler *tpf, const struct vkd3d_ + case VKD3DSIH_DSY_COARSE: + case VKD3DSIH_DSY_FINE: + case VKD3DSIH_ELSE: ++ case VKD3DSIH_EMIT: + case VKD3DSIH_ENDIF: + case VKD3DSIH_ENDLOOP: + case VKD3DSIH_ENDSWITCH: +@@ -4213,6 +4215,7 @@ static void tpf_handle_instruction(struct tpf_compiler *tpf, const struct vkd3d_ + case VKD3DSIH_IMM_ATOMIC_UMIN: + case VKD3DSIH_IMM_ATOMIC_OR: + case VKD3DSIH_IMM_ATOMIC_XOR: ++ case VKD3DSIH_SYNC: + case VKD3DSIH_IMUL: + case VKD3DSIH_INE: + case VKD3DSIH_INEG: +-- +2.47.2 + diff --git a/patches/vkd3d-latest/0002-Updated-vkd3d-to-cbce3a8631116ec10895e6c9c4a00b89b05.patch b/patches/vkd3d-latest/0002-Updated-vkd3d-to-cbce3a8631116ec10895e6c9c4a00b89b05.patch deleted file mode 100644 index 3cba1ba1..00000000 --- a/patches/vkd3d-latest/0002-Updated-vkd3d-to-cbce3a8631116ec10895e6c9c4a00b89b05.patch +++ /dev/null @@ -1,213 +0,0 @@ -From 77a6a8c574a94f8fb1a0bfbda96313e660b607c8 Mon Sep 17 00:00:00 2001 -From: Alistair Leslie-Hughes -Date: Thu, 10 Apr 2025 07:44:42 +1000 -Subject: [PATCH] Updated vkd3d to cbce3a8631116ec10895e6c9c4a00b89b051f6b0. - ---- - libs/vkd3d/libs/vkd3d-shader/fx.c | 44 ++++++++++++++++----- - libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 10 ++++- - libs/vkd3d/libs/vkd3d-shader/msl.c | 2 +- - libs/vkd3d/libs/vkd3d-shader/tpf.c | 20 +++++++--- - 4 files changed, 58 insertions(+), 18 deletions(-) - -diff --git a/libs/vkd3d/libs/vkd3d-shader/fx.c b/libs/vkd3d/libs/vkd3d-shader/fx.c -index debcb261811..c93f01039ef 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/fx.c -+++ b/libs/vkd3d/libs/vkd3d-shader/fx.c -@@ -2420,6 +2420,23 @@ static inline enum hlsl_base_type hlsl_type_from_fx_type(enum state_property_com - } - } - -+static inline bool hlsl_type_state_compatible(struct hlsl_type *lhs, enum hlsl_base_type rhs) -+{ -+ if (!hlsl_is_numeric_type(lhs)) -+ return false; -+ switch (lhs->e.numeric.type) -+ { -+ case HLSL_TYPE_INT: -+ case HLSL_TYPE_UINT: -+ return rhs == HLSL_TYPE_INT || rhs == HLSL_TYPE_UINT; -+ -+ default: -+ return lhs->e.numeric.type == rhs; -+ } -+ -+ vkd3d_unreachable(); -+} -+ - static const struct rhs_named_value filter_values[] = - { - { "MIN_MAG_MIP_POINT", 0x00 }, -@@ -2664,9 +2681,9 @@ static void resolve_fx_4_state_block_values(struct hlsl_ir_var *var, struct hlsl - struct replace_state_context replace_context; - const struct fx_4_state *state = NULL; - struct hlsl_type *state_type = NULL; -- struct hlsl_ir_node *node, *cast; - struct hlsl_ctx *ctx = fx->ctx; - enum hlsl_base_type base_type; -+ struct hlsl_ir_node *node; - unsigned int i; - - if (type->class == HLSL_CLASS_BLEND_STATE && ctx->profile->major_version == 5) -@@ -2803,9 +2820,15 @@ static void resolve_fx_4_state_block_values(struct hlsl_ir_var *var, struct hlsl - if (state_type) - { - node = entry->args->node; -- if (!(cast = hlsl_new_cast(ctx, node, state_type, &var->loc))) -- return; -- list_add_after(&node->entry, &cast->entry); -+ if (state->type == FX_UINT8 || !hlsl_type_state_compatible(node->data_type, base_type)) -+ { -+ struct hlsl_ir_node *cast; -+ -+ if (!(cast = hlsl_new_cast(ctx, node, state_type, &var->loc))) -+ return; -+ list_add_after(&node->entry, &cast->entry); -+ node = cast; -+ } - - /* FX_UINT8 values are using 32-bits in the binary. Mask higher 24 bits for those. */ - if (state->type == FX_UINT8) -@@ -2814,15 +2837,18 @@ static void resolve_fx_4_state_block_values(struct hlsl_ir_var *var, struct hlsl - - if (!(mask = hlsl_new_uint_constant(ctx, 0xff, &var->loc))) - return; -- list_add_after(&cast->entry, &mask->entry); -+ list_add_after(&node->entry, &mask->entry); - -- if (!(cast = hlsl_new_binary_expr(ctx, HLSL_OP2_BIT_AND, cast, mask))) -+ if (!(node = hlsl_new_binary_expr(ctx, HLSL_OP2_BIT_AND, node, mask))) - return; -- list_add_after(&mask->entry, &cast->entry); -+ list_add_after(&mask->entry, &node->entry); - } - -- hlsl_src_remove(entry->args); -- hlsl_src_from_node(entry->args, cast); -+ if (node != entry->args->node) -+ { -+ hlsl_src_remove(entry->args); -+ hlsl_src_from_node(entry->args, node); -+ } - - hlsl_run_const_passes(ctx, entry->instrs); - } -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -index ba56ba90403..dc7607a1393 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -@@ -6407,7 +6407,9 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var - || semantic == VKD3D_SHADER_SV_PRIMITIVE_ID) - vip_allocation = true; - -- if (semantic == VKD3D_SHADER_SV_IS_FRONT_FACE || semantic == VKD3D_SHADER_SV_SAMPLE_INDEX) -+ if (semantic == VKD3D_SHADER_SV_IS_FRONT_FACE || semantic == VKD3D_SHADER_SV_SAMPLE_INDEX -+ || (version.type == VKD3D_SHADER_TYPE_DOMAIN && !output && !is_primitive) -+ || (ctx->is_patch_constant_func && output)) - special_interpolation = true; - } - -@@ -6443,6 +6445,8 @@ static void allocate_semantic_registers(struct hlsl_ctx *ctx, struct hlsl_ir_fun - bool is_pixel_shader = ctx->profile->type == VKD3D_SHADER_TYPE_PIXEL; - struct hlsl_ir_var *var; - -+ in_prim_allocator.prioritize_smaller_writemasks = true; -+ patch_constant_out_patch_allocator.prioritize_smaller_writemasks = true; - input_allocator.prioritize_smaller_writemasks = true; - output_allocator.prioritize_smaller_writemasks = true; - -@@ -6470,6 +6474,8 @@ static void allocate_semantic_registers(struct hlsl_ctx *ctx, struct hlsl_ir_fun - allocate_semantic_register(ctx, var, &output_allocator, true, !is_pixel_shader); - } - -+ vkd3d_free(in_prim_allocator.allocations); -+ vkd3d_free(patch_constant_out_patch_allocator.allocations); - vkd3d_free(input_allocator.allocations); - vkd3d_free(output_allocator.allocations); - } -@@ -9770,7 +9776,7 @@ static void sm4_generate_vsir_instr_dcl_semantic(struct hlsl_ctx *ctx, struct vs - else - { - if (semantic == VKD3D_SHADER_SV_NONE || version->type == VKD3D_SHADER_TYPE_PIXEL -- || version->type == VKD3D_SHADER_TYPE_HULL) -+ || (version->type == VKD3D_SHADER_TYPE_HULL && !ctx->is_patch_constant_func)) - opcode = VKD3DSIH_DCL_OUTPUT; - else - opcode = VKD3DSIH_DCL_OUTPUT_SIV; -diff --git a/libs/vkd3d/libs/vkd3d-shader/msl.c b/libs/vkd3d/libs/vkd3d-shader/msl.c -index a5d952cd525..d477bfa1c1b 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/msl.c -+++ b/libs/vkd3d/libs/vkd3d-shader/msl.c -@@ -1292,7 +1292,7 @@ static int msl_generator_init(struct msl_generator *gen, struct vsir_program *pr - { - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, - "Internal compiler error: Unhandled shader type %#x.", type); -- return VKD3D_ERROR_INVALID_SHADER; -+ gen->prefix = "unknown"; - } - gen->interface_info = vkd3d_find_struct(compile_info->next, INTERFACE_INFO); - -diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c -index 23dab35a288..3be1d743acf 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/tpf.c -+++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c -@@ -3116,8 +3116,12 @@ bool sm4_sysval_semantic_from_semantic_name(enum vkd3d_shader_sysval_semantic *s - {"sv_domainlocation", false, VKD3D_SHADER_TYPE_DOMAIN, ~0u}, - {"sv_position", false, VKD3D_SHADER_TYPE_DOMAIN, VKD3D_SHADER_SV_NONE}, - {"sv_primitiveid", false, VKD3D_SHADER_TYPE_DOMAIN, ~0u}, -+ {"sv_rendertargetarrayindex", false, VKD3D_SHADER_TYPE_DOMAIN, VKD3D_SHADER_SV_NONE}, -+ {"sv_viewportarrayindex", false, VKD3D_SHADER_TYPE_DOMAIN, VKD3D_SHADER_SV_NONE}, - - {"sv_position", true, VKD3D_SHADER_TYPE_DOMAIN, VKD3D_SHADER_SV_POSITION}, -+ {"sv_rendertargetarrayindex", true, VKD3D_SHADER_TYPE_DOMAIN, VKD3D_SHADER_SV_RENDER_TARGET_ARRAY_INDEX}, -+ {"sv_viewportarrayindex", true, VKD3D_SHADER_TYPE_DOMAIN, VKD3D_SHADER_SV_VIEWPORT_ARRAY_INDEX}, - - {"sv_primitiveid", false, VKD3D_SHADER_TYPE_GEOMETRY, VKD3D_SHADER_SV_PRIMITIVE_ID}, - {"sv_gsinstanceid", false, VKD3D_SHADER_TYPE_GEOMETRY, ~0u}, -@@ -3131,6 +3135,8 @@ bool sm4_sysval_semantic_from_semantic_name(enum vkd3d_shader_sysval_semantic *s - {"sv_primitiveid", false, VKD3D_SHADER_TYPE_HULL, ~0u}, - - {"sv_position", true, VKD3D_SHADER_TYPE_HULL, VKD3D_SHADER_SV_POSITION}, -+ {"sv_rendertargetarrayindex", true, VKD3D_SHADER_TYPE_HULL, VKD3D_SHADER_SV_RENDER_TARGET_ARRAY_INDEX}, -+ {"sv_viewportarrayindex", true, VKD3D_SHADER_TYPE_HULL, VKD3D_SHADER_SV_VIEWPORT_ARRAY_INDEX}, - - {"position", false, VKD3D_SHADER_TYPE_PIXEL, VKD3D_SHADER_SV_POSITION}, - {"sv_position", false, VKD3D_SHADER_TYPE_PIXEL, VKD3D_SHADER_SV_POSITION}, -@@ -3164,6 +3170,10 @@ bool sm4_sysval_semantic_from_semantic_name(enum vkd3d_shader_sysval_semantic *s - if (!ascii_strcasecmp(semantic_name, "sv_position") - || (semantic_compat_mapping && !ascii_strcasecmp(semantic_name, "position"))) - *sysval_semantic = VKD3D_SHADER_SV_POSITION; -+ else if (!ascii_strcasecmp(semantic_name, "sv_rendertargetarrayindex")) -+ *sysval_semantic = VKD3D_SHADER_SV_RENDER_TARGET_ARRAY_INDEX; -+ else if (!ascii_strcasecmp(semantic_name, "sv_viewportarrayindex")) -+ *sysval_semantic = VKD3D_SHADER_SV_VIEWPORT_ARRAY_INDEX; - else if (has_sv_prefix) - return false; - else -@@ -3179,11 +3189,6 @@ bool sm4_sysval_semantic_from_semantic_name(enum vkd3d_shader_sysval_semantic *s - return get_tessfactor_sysval_semantic(sysval_semantic, domain, semantic_idx); - if (!ascii_strcasecmp(semantic_name, "sv_insidetessfactor")) - return get_insidetessfactor_sysval_semantic(sysval_semantic, domain, semantic_idx); -- if (!ascii_strcasecmp(semantic_name, "sv_position")) -- { -- *sysval_semantic = VKD3D_SHADER_SV_NONE; -- return true; -- } - } - else - { -@@ -3214,7 +3219,10 @@ bool sm4_sysval_semantic_from_semantic_name(enum vkd3d_shader_sysval_semantic *s - && (semantic_compat_mapping || has_sv_prefix) - && version->type == semantics[i].shader_type) - { -- *sysval_semantic = semantics[i].semantic; -+ if (is_patch_constant_func && output && semantics[i].semantic != ~0u) -+ *sysval_semantic = VKD3D_SHADER_SV_NONE; -+ else -+ *sysval_semantic = semantics[i].semantic; - return true; - } - } --- -2.47.2 - diff --git a/patches/vkd3d-latest/0003-Updated-vkd3d-to-f02ea94c428f6b2f662f78fc78eae7f3342.patch b/patches/vkd3d-latest/0003-Updated-vkd3d-to-f02ea94c428f6b2f662f78fc78eae7f3342.patch deleted file mode 100644 index 3f4a5f62..00000000 --- a/patches/vkd3d-latest/0003-Updated-vkd3d-to-f02ea94c428f6b2f662f78fc78eae7f3342.patch +++ /dev/null @@ -1,1765 +0,0 @@ -From b751f52ca93f8fd64aff26d17227e6fcbe4b3d40 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 deleted file mode 100644 index bdc6ee2d..00000000 --- a/patches/vkd3d-latest/0004-Updated-vkd3d-to-c764f71cf58e3a8327b44c588ad3696b422.patch +++ /dev/null @@ -1,304 +0,0 @@ -From ee67ac02b1545b81f14e77720b3cca0309fbf64c 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 - diff --git a/patches/vkd3d-latest/0005-Updated-vkd3d-to-ceb2787d466713096ea9746d2b63a4608fd.patch b/patches/vkd3d-latest/0005-Updated-vkd3d-to-ceb2787d466713096ea9746d2b63a4608fd.patch deleted file mode 100644 index 2483ac43..00000000 --- a/patches/vkd3d-latest/0005-Updated-vkd3d-to-ceb2787d466713096ea9746d2b63a4608fd.patch +++ /dev/null @@ -1,638 +0,0 @@ -From c6753750e48f1d5055b9b6780c0feccfbe48b913 Mon Sep 17 00:00:00 2001 -From: Alistair Leslie-Hughes -Date: Thu, 24 Apr 2025 06:51:10 +1000 -Subject: [PATCH] Updated vkd3d to ceb2787d466713096ea9746d2b63a4608fdc35f6. - ---- - libs/vkd3d/libs/vkd3d-shader/hlsl.c | 57 ++++++++--- - libs/vkd3d/libs/vkd3d-shader/hlsl.h | 18 +++- - libs/vkd3d/libs/vkd3d-shader/hlsl.y | 87 +++++++++++++--- - libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 108 ++++++++++++++++++-- - libs/vkd3d/libs/vkd3d-shader/spirv.c | 2 +- - libs/vkd3d/libs/vkd3d-shader/tpf.c | 36 ++++--- - 6 files changed, 255 insertions(+), 53 deletions(-) - -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c -index d1d20b7384c..a6b46474812 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c -@@ -387,6 +387,9 @@ static enum hlsl_regset type_get_regset(const struct hlsl_type *type) - case HLSL_CLASS_UAV: - return HLSL_REGSET_UAVS; - -+ case HLSL_CLASS_STREAM_OUTPUT: -+ return HLSL_REGSET_STREAM_OUTPUTS; -+ - default: - break; - } -@@ -493,6 +496,10 @@ static void hlsl_type_calculate_reg_size(struct hlsl_ctx *ctx, struct hlsl_type - type->reg_size[HLSL_REGSET_UAVS] = 1; - break; - -+ case HLSL_CLASS_STREAM_OUTPUT: -+ type->reg_size[HLSL_REGSET_STREAM_OUTPUTS] = 1; -+ break; -+ - case HLSL_CLASS_DEPTH_STENCIL_STATE: - case HLSL_CLASS_DEPTH_STENCIL_VIEW: - case HLSL_CLASS_EFFECT_GROUP: -@@ -511,7 +518,6 @@ static void hlsl_type_calculate_reg_size(struct hlsl_ctx *ctx, struct hlsl_type - case HLSL_CLASS_HULL_SHADER: - case HLSL_CLASS_GEOMETRY_SHADER: - case HLSL_CLASS_BLEND_STATE: -- case HLSL_CLASS_STREAM_OUTPUT: - case HLSL_CLASS_NULL: - break; - } -@@ -591,6 +597,7 @@ static bool type_is_single_component(const struct hlsl_type *type) - case HLSL_CLASS_HULL_SHADER: - case HLSL_CLASS_GEOMETRY_SHADER: - case HLSL_CLASS_BLEND_STATE: -+ case HLSL_CLASS_STREAM_OUTPUT: - case HLSL_CLASS_NULL: - return true; - -@@ -605,7 +612,6 @@ static bool type_is_single_component(const struct hlsl_type *type) - case HLSL_CLASS_PASS: - case HLSL_CLASS_TECHNIQUE: - case HLSL_CLASS_VOID: -- case HLSL_CLASS_STREAM_OUTPUT: - break; - } - vkd3d_unreachable(); -@@ -751,6 +757,7 @@ unsigned int hlsl_type_get_component_offset(struct hlsl_ctx *ctx, struct hlsl_ty - case HLSL_CLASS_HULL_SHADER: - case HLSL_CLASS_GEOMETRY_SHADER: - case HLSL_CLASS_BLEND_STATE: -+ case HLSL_CLASS_STREAM_OUTPUT: - VKD3D_ASSERT(idx == 0); - break; - -@@ -762,7 +769,6 @@ unsigned int hlsl_type_get_component_offset(struct hlsl_ctx *ctx, struct hlsl_ty - case HLSL_CLASS_SCALAR: - case HLSL_CLASS_CONSTANT_BUFFER: - case HLSL_CLASS_NULL: -- case HLSL_CLASS_STREAM_OUTPUT: - vkd3d_unreachable(); - } - type = next_type; -@@ -984,6 +990,7 @@ struct hlsl_type *hlsl_new_stream_output_type(struct hlsl_ctx *ctx, - type->class = HLSL_CLASS_STREAM_OUTPUT; - type->e.so.so_type = so_type; - type->e.so.type = data_type; -+ hlsl_type_calculate_reg_size(ctx, type); - - list_add_tail(&ctx->types, &type->entry); - -@@ -1366,6 +1373,10 @@ struct hlsl_type *hlsl_type_clone(struct hlsl_ctx *ctx, struct hlsl_type *old, - type->e.version = old->e.version; - break; - -+ case HLSL_CLASS_STREAM_OUTPUT: -+ type->e.so.so_type = old->e.so.so_type; -+ break; -+ - default: - break; - } -@@ -2053,24 +2064,28 @@ struct hlsl_ir_node *hlsl_block_add_resource_load(struct hlsl_ctx *ctx, struct h - return append_new_instr(ctx, block, hlsl_new_resource_load(ctx, params, loc)); - } - --static struct hlsl_ir_node *hlsl_new_resource_store(struct hlsl_ctx *ctx, const struct hlsl_deref *resource, -- struct hlsl_ir_node *coords, struct hlsl_ir_node *value, const struct vkd3d_shader_location *loc) -+static struct hlsl_ir_node *hlsl_new_resource_store(struct hlsl_ctx *ctx, enum hlsl_resource_store_type type, -+ const struct hlsl_deref *resource, struct hlsl_ir_node *coords, struct hlsl_ir_node *value, -+ const struct vkd3d_shader_location *loc) - { - struct hlsl_ir_resource_store *store; - - if (!(store = hlsl_alloc(ctx, sizeof(*store)))) - return NULL; - init_node(&store->node, HLSL_IR_RESOURCE_STORE, NULL, loc); -+ store->store_type = type; -+ - hlsl_copy_deref(ctx, &store->resource, resource); - hlsl_src_from_node(&store->coords, coords); - hlsl_src_from_node(&store->value, value); - return &store->node; - } - --void hlsl_block_add_resource_store(struct hlsl_ctx *ctx, struct hlsl_block *block, const struct hlsl_deref *resource, -- struct hlsl_ir_node *coords, struct hlsl_ir_node *value, const struct vkd3d_shader_location *loc) -+void hlsl_block_add_resource_store(struct hlsl_ctx *ctx, struct hlsl_block *block, -+ enum hlsl_resource_store_type type, const struct hlsl_deref *resource, struct hlsl_ir_node *coords, -+ struct hlsl_ir_node *value, const struct vkd3d_shader_location *loc) - { -- append_new_instr(ctx, block, hlsl_new_resource_store(ctx, resource, coords, value, loc)); -+ append_new_instr(ctx, block, hlsl_new_resource_store(ctx, type, resource, coords, value, loc)); - } - - struct hlsl_ir_node *hlsl_new_swizzle(struct hlsl_ctx *ctx, uint32_t s, unsigned int component_count, -@@ -2589,6 +2604,7 @@ static struct hlsl_ir_node *clone_resource_store(struct hlsl_ctx *ctx, - if (!(dst = hlsl_alloc(ctx, sizeof(*dst)))) - return NULL; - init_node(&dst->node, HLSL_IR_RESOURCE_STORE, NULL, &src->node.loc); -+ dst->store_type = src->store_type; - if (!clone_deref(ctx, map, &dst->resource, &src->resource)) - { - vkd3d_free(dst); -@@ -3720,12 +3736,26 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru - - static void dump_ir_resource_store(struct vkd3d_string_buffer *buffer, const struct hlsl_ir_resource_store *store) - { -- vkd3d_string_buffer_printf(buffer, "store_resource(resource = "); -+ static const char *const type_names[] = -+ { -+ [HLSL_RESOURCE_STORE] = "store_resource", -+ [HLSL_RESOURCE_STREAM_APPEND] = "stream_append", -+ [HLSL_RESOURCE_STREAM_RESTART] = "stream_restart", -+ }; -+ -+ VKD3D_ASSERT(store->store_type < ARRAY_SIZE(type_names)); -+ vkd3d_string_buffer_printf(buffer, "%s(resource = ", type_names[store->store_type]); - dump_deref(buffer, &store->resource); -- vkd3d_string_buffer_printf(buffer, ", coords = "); -- dump_src(buffer, &store->coords); -- vkd3d_string_buffer_printf(buffer, ", value = "); -- dump_src(buffer, &store->value); -+ if (store->coords.node) -+ { -+ vkd3d_string_buffer_printf(buffer, ", coords = "); -+ dump_src(buffer, &store->coords); -+ } -+ if (store->value.node) -+ { -+ vkd3d_string_buffer_printf(buffer, ", value = "); -+ dump_src(buffer, &store->value); -+ } - vkd3d_string_buffer_printf(buffer, ")"); - } - -@@ -4829,6 +4859,7 @@ static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const struct vkd3d_shader_compil - ctx->input_control_point_count = UINT_MAX; - ctx->max_vertex_count = 0; - ctx->input_primitive_type = VKD3D_PT_UNDEFINED; -+ ctx->output_topology_type = VKD3D_PT_UNDEFINED; - - return true; - } -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h -index fafa5740963..8cb805a2e66 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h -@@ -141,7 +141,8 @@ enum hlsl_regset - HLSL_REGSET_SAMPLERS, - HLSL_REGSET_TEXTURES, - HLSL_REGSET_UAVS, -- HLSL_REGSET_LAST_OBJECT = HLSL_REGSET_UAVS, -+ HLSL_REGSET_STREAM_OUTPUTS, -+ HLSL_REGSET_LAST_OBJECT = HLSL_REGSET_STREAM_OUTPUTS, - HLSL_REGSET_NUMERIC, - HLSL_REGSET_LAST = HLSL_REGSET_NUMERIC, - }; -@@ -894,9 +895,17 @@ struct hlsl_ir_resource_load - enum hlsl_sampler_dim sampling_dim; - }; - -+enum hlsl_resource_store_type -+{ -+ HLSL_RESOURCE_STORE, -+ HLSL_RESOURCE_STREAM_APPEND, -+ HLSL_RESOURCE_STREAM_RESTART, -+}; -+ - struct hlsl_ir_resource_store - { - struct hlsl_ir_node node; -+ enum hlsl_resource_store_type store_type; - struct hlsl_deref resource; - struct hlsl_src coords, value; - }; -@@ -1204,6 +1213,8 @@ struct hlsl_ctx - unsigned int max_vertex_count; - /* The input primitive type of a geometry shader. */ - enum vkd3d_primitive_type input_primitive_type; -+ /* The output topology type of a geometry shader. */ -+ enum vkd3d_primitive_type output_topology_type; - - /* In some cases we generate opcodes by parsing an HLSL function and then - * invoking it. If not NULL, this field is the name of the function that we -@@ -1554,8 +1565,9 @@ void hlsl_block_add_loop(struct hlsl_ctx *ctx, struct hlsl_block *block, - unsigned int unroll_limit, const struct vkd3d_shader_location *loc); - struct hlsl_ir_node *hlsl_block_add_resource_load(struct hlsl_ctx *ctx, struct hlsl_block *block, - const struct hlsl_resource_load_params *params, const struct vkd3d_shader_location *loc); --void hlsl_block_add_resource_store(struct hlsl_ctx *ctx, struct hlsl_block *block, const struct hlsl_deref *resource, -- struct hlsl_ir_node *coords, struct hlsl_ir_node *value, const struct vkd3d_shader_location *loc); -+void hlsl_block_add_resource_store(struct hlsl_ctx *ctx, struct hlsl_block *block, -+ enum hlsl_resource_store_type type, const struct hlsl_deref *resource, struct hlsl_ir_node *coords, -+ struct hlsl_ir_node *value, const struct vkd3d_shader_location *loc); - struct hlsl_ir_node *hlsl_block_add_simple_load(struct hlsl_ctx *ctx, struct hlsl_block *block, - struct hlsl_ir_var *var, const struct vkd3d_shader_location *loc); - void hlsl_block_add_simple_store(struct hlsl_ctx *ctx, struct hlsl_block *block, -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y -index 40fd142f58d..702fd30bda3 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y -@@ -2115,7 +2115,7 @@ static bool add_assignment(struct hlsl_ctx *ctx, struct hlsl_block *block, struc - VKD3D_ASSERT(coords->data_type->e.numeric.type == HLSL_TYPE_UINT); - VKD3D_ASSERT(coords->data_type->e.numeric.dimx == dim_count); - -- hlsl_block_add_resource_store(ctx, block, &resource_deref, coords, rhs, &lhs->loc); -+ hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STORE, &resource_deref, coords, rhs, &lhs->loc); - hlsl_cleanup_deref(&resource_deref); - } - else if (matrix_writemask) -@@ -6220,12 +6220,58 @@ static bool add_store_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block - if (!hlsl_init_deref_from_index_chain(ctx, &resource_deref, object)) - return false; - -- hlsl_block_add_resource_store(ctx, block, &resource_deref, offset, rhs, loc); -+ hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STORE, &resource_deref, offset, rhs, loc); - hlsl_cleanup_deref(&resource_deref); - - return true; - } - -+static bool add_so_append_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_node *object, -+ const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) -+{ -+ struct hlsl_deref so_deref; -+ struct hlsl_ir_node *rhs; -+ -+ if (params->args_count != 1) -+ { -+ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, -+ "Wrong number of arguments to method '%s': expected 1.", name); -+ return false; -+ } -+ -+ if (!hlsl_init_deref_from_index_chain(ctx, &so_deref, object)) -+ return false; -+ -+ if (!(rhs = add_implicit_conversion(ctx, block, params->args[0], object->data_type->e.so.type, loc))) -+ return false; -+ -+ hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STREAM_APPEND, &so_deref, NULL, rhs, loc); -+ hlsl_cleanup_deref(&so_deref); -+ -+ return true; -+} -+ -+static bool add_so_restartstrip_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_node *object, -+ const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) -+{ -+ struct hlsl_deref so_deref; -+ -+ if (params->args_count) -+ { -+ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, -+ "Wrong number of arguments to method '%s': expected 0.", name); -+ return false; -+ } -+ -+ if (!hlsl_init_deref_from_index_chain(ctx, &so_deref, object)) -+ return false; -+ -+ hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STREAM_RESTART, &so_deref, NULL, NULL, loc); -+ hlsl_cleanup_deref(&so_deref); -+ -+ return true; -+} -+ - static const struct method_function - { - const char *name; -@@ -6269,6 +6315,12 @@ static const struct method_function uav_methods[] = - { "Store4", add_store_method_call, "00000000000001" }, - }; - -+static const struct method_function so_methods[] = -+{ -+ { "Append", add_so_append_method_call, "" }, -+ { "RestartStrip", add_so_restartstrip_method_call, "" }, -+}; -+ - static int object_method_function_name_compare(const void *a, const void *b) - { - const struct method_function *func = b; -@@ -6280,8 +6332,7 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, stru - const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) - { - const struct hlsl_type *object_type = object->data_type; -- const struct method_function *method, *methods; -- unsigned int count; -+ const struct method_function *method; - - if (object_type->class == HLSL_CLASS_ERROR) - { -@@ -6300,13 +6351,24 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, stru - - if (object_type->class == HLSL_CLASS_TEXTURE) - { -- count = ARRAY_SIZE(texture_methods); -- methods = texture_methods; -+ method = bsearch(name, texture_methods, ARRAY_SIZE(texture_methods), sizeof(*method), -+ object_method_function_name_compare); -+ -+ if (method && method->valid_dims[object_type->sampler_dim] != '1') -+ method = NULL; - } - else if (object_type->class == HLSL_CLASS_UAV) - { -- count = ARRAY_SIZE(uav_methods); -- methods = uav_methods; -+ method = bsearch(name, uav_methods, ARRAY_SIZE(uav_methods), sizeof(*method), -+ object_method_function_name_compare); -+ -+ if (method && method->valid_dims[object_type->sampler_dim] != '1') -+ method = NULL; -+ } -+ else if (object_type->class == HLSL_CLASS_STREAM_OUTPUT) -+ { -+ method = bsearch(name, so_methods, ARRAY_SIZE(so_methods), sizeof(*method), -+ object_method_function_name_compare); - } - else - { -@@ -6319,17 +6381,10 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, stru - return false; - } - -- method = bsearch(name, methods, count, sizeof(*method), -- object_method_function_name_compare); -- -- if (method && method->valid_dims[object_type->sampler_dim] == '1') -- { -+ if (method) - return method->handler(ctx, block, object, name, params, loc); -- } - else -- { - return raise_invalid_method_object_type(ctx, object_type, name, loc); -- } - } - - static bool add_object_property_access(struct hlsl_ctx *ctx, -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -index 1c684e7b9c1..8dff48ee83e 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -@@ -5191,6 +5191,8 @@ static char get_regset_name(enum hlsl_regset regset) - return 't'; - case HLSL_REGSET_UAVS: - return 'u'; -+ case HLSL_REGSET_STREAM_OUTPUTS: -+ return 'm'; - case HLSL_REGSET_NUMERIC: - vkd3d_unreachable(); - } -@@ -5359,8 +5361,10 @@ static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop - var = store->resource.var; - var->last_read = max(var->last_read, last_read); - deref_mark_last_read(&store->resource, last_read); -- store->coords.node->last_read = last_read; -- store->value.node->last_read = last_read; -+ if (store->coords.node) -+ store->coords.node->last_read = last_read; -+ if (store->value.node) -+ store->value.node->last_read = last_read; - break; - } - case HLSL_IR_SWIZZLE: -@@ -6877,6 +6881,28 @@ static void allocate_objects(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl - } - } - -+static void allocate_stream_outputs(struct hlsl_ctx *ctx) -+{ -+ struct hlsl_ir_var *var; -+ uint32_t index = 0; -+ -+ LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) -+ { -+ if (!var->data_type->reg_size[HLSL_REGSET_STREAM_OUTPUTS]) -+ continue; -+ -+ /* We should have ensured that all stream output objects are single-element. */ -+ VKD3D_ASSERT(var->data_type->reg_size[HLSL_REGSET_STREAM_OUTPUTS] == 1); -+ -+ var->regs[HLSL_REGSET_STREAM_OUTPUTS].space = 0; -+ var->regs[HLSL_REGSET_STREAM_OUTPUTS].index = index; -+ var->regs[HLSL_REGSET_STREAM_OUTPUTS].id = index; -+ var->regs[HLSL_REGSET_STREAM_OUTPUTS].allocated = true; -+ -+ ++index; -+ } -+} -+ - bool hlsl_component_index_range_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref, - unsigned int *start, unsigned int *count) - { -@@ -7557,6 +7583,64 @@ static void validate_and_record_prim_type(struct hlsl_ctx *ctx, struct hlsl_ir_v - ctx->input_primitive_param = var; - } - -+static void validate_and_record_stream_outputs(struct hlsl_ctx *ctx) -+{ -+ static const enum vkd3d_primitive_type prim_types[] = -+ { -+ [HLSL_STREAM_OUTPUT_POINT_STREAM] = VKD3D_PT_POINTLIST, -+ [HLSL_STREAM_OUTPUT_LINE_STREAM] = VKD3D_PT_LINESTRIP, -+ [HLSL_STREAM_OUTPUT_TRIANGLE_STREAM] = VKD3D_PT_TRIANGLESTRIP, -+ }; -+ -+ bool reported_non_point_multistream = false, reported_nonzero_index = false, reported_invalid_index = false; -+ enum hlsl_so_object_type so_type; -+ const struct hlsl_type *type; -+ struct hlsl_ir_var *var; -+ -+ LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) -+ { -+ if (!var->bind_count[HLSL_REGSET_STREAM_OUTPUTS]) -+ continue; -+ -+ type = hlsl_get_stream_output_type(var->data_type); -+ so_type = type->e.so.so_type; -+ -+ VKD3D_ASSERT(so_type < ARRAY_SIZE(prim_types)); -+ -+ if (ctx->output_topology_type == VKD3D_PT_UNDEFINED) -+ { -+ ctx->output_topology_type = prim_types[so_type]; -+ } -+ else -+ { -+ if ((so_type != HLSL_STREAM_OUTPUT_POINT_STREAM || ctx->output_topology_type != VKD3D_PT_POINTLIST) -+ && !reported_non_point_multistream) -+ { -+ hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, -+ "Multiple output streams are only allowed with PointStream objects."); -+ reported_non_point_multistream = true; -+ } -+ } -+ -+ if (var->regs[HLSL_REGSET_STREAM_OUTPUTS].index && hlsl_version_lt(ctx, 5, 0) && !reported_nonzero_index) -+ { -+ hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE, -+ "Multiple output streams are only supported in shader model 5.0 or higher."); -+ reported_nonzero_index = true; -+ } -+ -+ if (var->regs[HLSL_REGSET_STREAM_OUTPUTS].index >= VKD3D_MAX_STREAM_COUNT && !reported_invalid_index) -+ { -+ hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SIZE, -+ "Output stream index %u exceeds the maximum index %u.", -+ var->regs[HLSL_REGSET_STREAM_OUTPUTS].index, VKD3D_MAX_STREAM_COUNT - 1); -+ reported_invalid_index = true; -+ } -+ } -+ -+ /* TODO: check that maxvertexcount * outputdatasize <= 1024. */ -+} -+ - static void remove_unreachable_code(struct hlsl_ctx *ctx, struct hlsl_block *body) - { - struct hlsl_ir_node *instr, *next; -@@ -10632,6 +10716,12 @@ static bool sm4_generate_vsir_instr_resource_store(struct hlsl_ctx *ctx, - struct vkd3d_shader_instruction *ins; - unsigned int writemask; - -+ if (store->store_type != HLSL_RESOURCE_STORE) -+ { -+ hlsl_fixme(ctx, &instr->loc, "Stream output operations."); -+ return false; -+ } -+ - if (!store->resource.var->is_uniform) - { - hlsl_fixme(ctx, &store->node.loc, "Store to non-uniform resource variable."); -@@ -11963,7 +12053,7 @@ static void sm4_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl - { - program->input_control_point_count = ctx->input_control_point_count; - program->input_primitive = ctx->input_primitive_type; -- program->output_topology = VKD3D_PT_UNDEFINED; /* TODO: obtain from stream output parameters. */ -+ program->output_topology = ctx->output_topology_type; - program->vertices_out_count = ctx->max_vertex_count; - } - -@@ -13240,7 +13330,7 @@ static void process_entry_function(struct hlsl_ctx *ctx, - validate_and_record_prim_type(ctx, var); - prepend_input_var_copy(ctx, entry_func, var); - } -- else if (hlsl_get_stream_output_type(var->data_type)) -+ else if (var->data_type->reg_size[HLSL_REGSET_STREAM_OUTPUTS]) - { - if (profile->type != VKD3D_SHADER_TYPE_GEOMETRY) - { -@@ -13253,9 +13343,7 @@ static void process_entry_function(struct hlsl_ctx *ctx, - hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, - "Stream output parameter \"%s\" must be declared as \"inout\".", var->name); - -- /* TODO: check that maxvertexcount * component_count(element_type) <= 1024. */ -- -- continue; -+ prepend_uniform_copy(ctx, body, var); - } - else - { -@@ -13369,6 +13457,12 @@ static void process_entry_function(struct hlsl_ctx *ctx, - else - sort_synthetic_separated_samplers_first(ctx); - -+ if (profile->type == VKD3D_SHADER_TYPE_GEOMETRY) -+ { -+ allocate_stream_outputs(ctx); -+ validate_and_record_stream_outputs(ctx); -+ } -+ - if (profile->major_version < 4) - { - while (lower_ir(ctx, lower_nonconstant_array_loads, body)); -diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c -index 05cc0b9a55e..6a393c5f35d 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/spirv.c -+++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c -@@ -426,7 +426,7 @@ static enum vkd3d_result spirv_parser_read_header(struct spirv_parser *parser) - - major = (version & VKD3D_SPIRV_VERSION_MAJOR_MASK) >> VKD3D_SPIRV_VERSION_MAJOR_SHIFT; - minor = (version & VKD3D_SPIRV_VERSION_MINOR_MASK) >> VKD3D_SPIRV_VERSION_MINOR_SHIFT; -- if (major != 1 || minor > 0) -+ if (major != 1 || minor > 6) - { - spirv_parser_error(parser, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, - "Unable to parse SPIR-V version %u.%u.", major, minor); -diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c -index 3be1d743acf..c29bedfaaa9 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/tpf.c -+++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c -@@ -3822,6 +3822,25 @@ static void tpf_dcl_sampler(const struct tpf_compiler *tpf, const struct vkd3d_s - write_sm4_instruction(tpf, &instr); - } - -+static uint32_t pack_resource_data_type(const enum vkd3d_data_type *resource_data_type) -+{ -+ unsigned int i, k, type = 0; -+ -+ for (k = 0; k < 4; ++k) -+ { -+ for (i = ARRAY_SIZE(data_type_table) - 1; i < ARRAY_SIZE(data_type_table); --i) -+ { -+ if (resource_data_type[k] == data_type_table[i]) -+ { -+ type |= i << (4 * k); -+ break; -+ } -+ } -+ } -+ -+ return type; -+} -+ - static void tpf_dcl_texture(const struct tpf_compiler *tpf, const struct vkd3d_shader_instruction *ins) - { - const struct vkd3d_shader_structured_resource *structured_resource = &ins->declaration.structured_resource; -@@ -3829,7 +3848,6 @@ static void tpf_dcl_texture(const struct tpf_compiler *tpf, const struct vkd3d_s - const struct vkd3d_shader_version *version = &tpf->program->shader_version; - const struct vkd3d_sm4_opcode_info *info; - struct sm4_instruction instr = {0}; -- unsigned int i, k; - bool uav; - - info = get_info_from_vsir_opcode(&tpf->lookup, ins->opcode); -@@ -3844,18 +3862,11 @@ static void tpf_dcl_texture(const struct tpf_compiler *tpf, const struct vkd3d_s - instr.dsts[0] = semantic->resource.reg; - instr.dst_count = 1; - -- for (k = 0; k < 4; ++k) -+ if (ins->opcode == VKD3DSIH_DCL || ins->opcode == VKD3DSIH_DCL_UAV_TYPED) - { -- for (i = ARRAY_SIZE(data_type_table) - 1; i < ARRAY_SIZE(data_type_table); --i) -- { -- if (semantic->resource_data_type[k] == data_type_table[i]) -- { -- instr.idx[0] |= i << (4 * k); -- break; -- } -- } -+ instr.idx[0] = pack_resource_data_type(semantic->resource_data_type); -+ instr.idx_count = 1; - } -- instr.idx_count = 1; - - if (vkd3d_shader_ver_ge(version, 5, 1)) - { -@@ -3864,8 +3875,7 @@ static void tpf_dcl_texture(const struct tpf_compiler *tpf, const struct vkd3d_s - instr.dsts[0].reg.idx[2].offset = semantic->resource.range.last; - instr.dsts[0].reg.idx_count = 3; - -- instr.idx[1] = semantic->resource.range.space; -- instr.idx_count = 2; -+ instr.idx[instr.idx_count++] = semantic->resource.range.space; - } - else - { --- -2.47.2 - diff --git a/patches/vkd3d-latest/0006-Updated-vkd3d-to-8882d324a6e91654b4ea2908506e400986a.patch b/patches/vkd3d-latest/0006-Updated-vkd3d-to-8882d324a6e91654b4ea2908506e400986a.patch deleted file mode 100644 index cbdbb513..00000000 --- a/patches/vkd3d-latest/0006-Updated-vkd3d-to-8882d324a6e91654b4ea2908506e400986a.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 004790ffcc95151f41ae68b2eefe425bdbfe8123 Mon Sep 17 00:00:00 2001 -From: Alistair Leslie-Hughes -Date: Tue, 29 Apr 2025 07:48:48 +1000 -Subject: [PATCH] Updated vkd3d to 8882d324a6e91654b4ea2908506e400986aed840. - ---- - libs/vkd3d/libs/vkd3d-shader/dxil.c | 2 +- - libs/vkd3d/libs/vkd3d-shader/ir.c | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c -index a3813c39bf0..d5f9626ec9d 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/dxil.c -+++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c -@@ -9689,7 +9689,7 @@ static enum vkd3d_result sm6_parser_signatures_init(struct sm6_parser *sm6, cons - if ((ret = sm6_parser_init_input_signature(sm6, &program->input_signature)) < 0) - return ret; - -- if ((ret = sm6_parser_init_output_signature(sm6, &program->output_signature) < 0)) -+ if ((ret = sm6_parser_init_output_signature(sm6, &program->output_signature)) < 0) - return ret; - - if ((ret = sm6_parser_init_patch_constant_signature(sm6, &program->patch_constant_signature)) < 0) -diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c -index 95093102552..b8f83946294 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/ir.c -+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c -@@ -2064,7 +2064,7 @@ static enum vkd3d_result shader_signature_map_patch_constant_index_ranges(struct - continue; - - if ((ret = range_map_set_register_range(normaliser, range_map, -- e->register_index, register_count, e->mask, e->used_mask, false) < 0)) -+ e->register_index, register_count, e->mask, e->used_mask, false)) < 0) - return ret; - } - --- -2.47.2 - diff --git a/patches/vkd3d-latest/0007-Updated-vkd3d-to-541060215e338a419a5a6fe6ae156fecf1c.patch b/patches/vkd3d-latest/0007-Updated-vkd3d-to-541060215e338a419a5a6fe6ae156fecf1c.patch deleted file mode 100644 index f0be979b..00000000 --- a/patches/vkd3d-latest/0007-Updated-vkd3d-to-541060215e338a419a5a6fe6ae156fecf1c.patch +++ /dev/null @@ -1,745 +0,0 @@ -From d4bb50e646849dd747c804afef18f463c6cd7a8e Mon Sep 17 00:00:00 2001 -From: Alistair Leslie-Hughes -Date: Thu, 1 May 2025 06:41:00 +1000 -Subject: [PATCH] Updated vkd3d to 541060215e338a419a5a6fe6ae156fecf1c4b89f. - ---- - libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 61 ++++++- - libs/vkd3d/libs/vkd3d-shader/dxil.c | 68 ++++--- - libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 4 +- - libs/vkd3d/libs/vkd3d-shader/ir.c | 4 +- - libs/vkd3d/libs/vkd3d-shader/msl.c | 187 ++++++++++---------- - 5 files changed, 201 insertions(+), 123 deletions(-) - -diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c -index 77498f26c7f..57d874efe37 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c -+++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c -@@ -1215,6 +1215,7 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str - struct vkd3d_shader_src_param *src_params, *predicate; - const struct vkd3d_sm1_opcode_info *opcode_info; - struct vsir_program *program = sm1->p.program; -+ unsigned int vsir_dst_count, vsir_src_count; - struct vkd3d_shader_dst_param *dst_param; - const uint32_t **ptr = &sm1->ptr; - uint32_t opcode_token; -@@ -1241,6 +1242,17 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str - goto fail; - } - -+ if (opcode_info->vkd3d_opcode == VKD3DSIH_TEXKILL) -+ { -+ vsir_src_count = 1; -+ vsir_dst_count = 0; -+ } -+ else -+ { -+ vsir_src_count = opcode_info->src_count; -+ vsir_dst_count = opcode_info->dst_count; -+ } -+ - vsir_instruction_init(ins, &sm1->p.location, opcode_info->vkd3d_opcode); - ins->flags = (opcode_token & VKD3D_SM1_INSTRUCTION_FLAGS_MASK) >> VKD3D_SM1_INSTRUCTION_FLAGS_SHIFT; - ins->coissue = opcode_token & VKD3D_SM1_COISSUE; -@@ -1248,9 +1260,9 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str - ins->structured = false; - predicated = !!(opcode_token & VKD3D_SM1_INSTRUCTION_PREDICATED); - ins->predicate = predicate = predicated ? vsir_program_get_src_params(program, 1) : NULL; -- ins->dst_count = opcode_info->dst_count; -+ ins->dst_count = vsir_dst_count; - ins->dst = dst_param = vsir_program_get_dst_params(program, ins->dst_count); -- ins->src_count = opcode_info->src_count; -+ ins->src_count = vsir_src_count; - ins->src = src_params = vsir_program_get_src_params(program, ins->src_count); - if ((!predicate && predicated) || (!src_params && ins->src_count) || (!dst_param && ins->dst_count)) - { -@@ -1298,6 +1310,25 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str - shader_sm1_read_immconst(sm1, &p, &src_params[0], VSIR_DIMENSION_VEC4, VKD3D_DATA_INT); - shader_sm1_scan_register(sm1, &dst_param->reg, dst_param->write_mask, true); - } -+ else if (ins->opcode == VKD3DSIH_TEXKILL) -+ { -+ /* TEXKILL, uniquely, encodes its argument as a destination, when it is -+ * semantically a source. Since we have multiple passes which operate -+ * generically on sources or destinations, normalize that. */ -+ const struct vkd3d_shader_register *reg; -+ struct vkd3d_shader_dst_param tmp_dst; -+ -+ reg = &tmp_dst.reg; -+ shader_sm1_read_dst_param(sm1, &p, &tmp_dst); -+ shader_sm1_scan_register(sm1, reg, tmp_dst.write_mask, false); -+ -+ vsir_src_param_init(&src_params[0], reg->type, reg->data_type, reg->idx_count); -+ src_params[0].reg = *reg; -+ src_params[0].swizzle = vsir_swizzle_from_writemask(tmp_dst.write_mask); -+ -+ if (ins->predicate) -+ shader_sm1_read_src_param(sm1, &p, predicate); -+ } - else - { - /* Destination token */ -@@ -1834,6 +1865,27 @@ static void d3dbc_write_instruction(struct d3dbc_compiler *d3dbc, const struct v - } - }; - -+static void d3dbc_write_texkill(struct d3dbc_compiler *d3dbc, const struct vkd3d_shader_instruction *ins) -+{ -+ const struct vkd3d_shader_register *reg = &ins->src[0].reg; -+ struct vkd3d_shader_instruction tmp; -+ struct vkd3d_shader_dst_param dst; -+ -+ /* TEXKILL, uniquely, encodes its argument as a destination, when it is -+ * semantically a source. We store it as a source in vsir, so convert it. */ -+ -+ vsir_dst_param_init(&dst, reg->type, reg->data_type, reg->idx_count); -+ dst.reg = *reg; -+ dst.write_mask = mask_from_swizzle(ins->src[0].swizzle); -+ -+ tmp = *ins; -+ tmp.dst_count = 1; -+ tmp.dst = &dst; -+ tmp.src_count = 0; -+ -+ d3dbc_write_instruction(d3dbc, &tmp); -+} -+ - static void d3dbc_write_vsir_def(struct d3dbc_compiler *d3dbc, const struct vkd3d_shader_instruction *ins) - { - const struct vkd3d_shader_version *version = &d3dbc->program->shader_version; -@@ -1938,6 +1990,10 @@ static void d3dbc_write_vsir_instruction(struct d3dbc_compiler *d3dbc, const str - d3dbc_write_vsir_dcl(d3dbc, ins); - break; - -+ case VKD3DSIH_TEXKILL: -+ d3dbc_write_texkill(d3dbc, ins); -+ break; -+ - case VKD3DSIH_ABS: - case VKD3DSIH_ADD: - case VKD3DSIH_CMP: -@@ -1959,7 +2015,6 @@ static void d3dbc_write_vsir_instruction(struct d3dbc_compiler *d3dbc, const str - case VKD3DSIH_SINCOS: - case VKD3DSIH_SLT: - case VKD3DSIH_TEX: -- case VKD3DSIH_TEXKILL: - case VKD3DSIH_TEXLDD: - d3dbc_write_instruction(d3dbc, ins); - break; -diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c -index d5f9626ec9d..775be85334e 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/dxil.c -+++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c -@@ -659,7 +659,8 @@ struct sm6_function_data - struct sm6_handle_data - { - const struct sm6_descriptor_info *d; -- struct vkd3d_shader_register reg; -+ const struct sm6_value *index; -+ bool non_uniform; - }; - - struct sm6_value -@@ -2519,6 +2520,25 @@ static void register_index_address_init(struct vkd3d_shader_register_index *idx, - } - } - -+static void sm6_register_from_handle(struct sm6_parser *sm6, -+ const struct sm6_handle_data *handle, struct vkd3d_shader_register *reg) -+{ -+ vsir_register_init(reg, handle->d->reg_type, handle->d->reg_data_type, 2); -+ reg->dimension = VSIR_DIMENSION_VEC4; -+ reg->idx[0].offset = handle->d->id; -+ register_index_address_init(®->idx[1], handle->index, sm6); -+ reg->non_uniform = handle->non_uniform; -+} -+ -+static void src_param_init_vector_from_handle(struct sm6_parser *sm6, -+ struct vkd3d_shader_src_param *param, const struct sm6_handle_data *handle) -+{ -+ struct vkd3d_shader_register reg; -+ -+ sm6_register_from_handle(sm6, handle, ®); -+ src_param_init_vector_from_reg(param, ®); -+} -+ - static bool instruction_dst_param_init_ssa_scalar(struct vkd3d_shader_instruction *ins, struct sm6_parser *sm6) - { - struct sm6_value *dst = sm6_parser_get_current_value(sm6); -@@ -4788,7 +4808,7 @@ static void sm6_parser_emit_dx_atomic_binop(struct sm6_parser *sm6, enum dx_intr - dst_param_init(&dst_params[0]); - register_init_ssa_scalar(&dst_params[0].reg, dst->type, dst, sm6); - dst_param_init(&dst_params[1]); -- dst_params[1].reg = resource->u.handle.reg; -+ sm6_register_from_handle(sm6, &resource->u.handle, &dst_params[1].reg); - - dst->u.reg = dst_params[0].reg; - } -@@ -4846,7 +4866,7 @@ static void sm6_parser_emit_dx_buffer_update_counter(struct sm6_parser *sm6, enu - vsir_instruction_init(ins, &sm6->p.location, (inc < 0) ? VKD3DSIH_IMM_ATOMIC_CONSUME : VKD3DSIH_IMM_ATOMIC_ALLOC); - if (!(src_params = instruction_src_params_alloc(ins, 1, sm6))) - return; -- src_param_init_vector_from_reg(&src_params[0], &resource->u.handle.reg); -+ src_param_init_vector_from_handle(sm6, &src_params[0], &resource->u.handle); - - instruction_dst_param_init_ssa_scalar(ins, sm6); - } -@@ -4878,9 +4898,9 @@ static void sm6_parser_emit_dx_calculate_lod(struct sm6_parser *sm6, enum dx_int - if (!(src_params = instruction_src_params_alloc(ins, 3, sm6))) - return; - src_param_init_vector_from_reg(&src_params[0], &coord); -- src_params[1].reg = resource->u.handle.reg; -+ sm6_register_from_handle(sm6, &resource->u.handle, &src_params[1].reg); - src_param_init_scalar(&src_params[1], !clamp); -- src_param_init_vector_from_reg(&src_params[2], &sampler->u.handle.reg); -+ src_param_init_vector_from_handle(sm6, &src_params[2], &sampler->u.handle); - - instruction_dst_param_init_ssa_scalar(ins, sm6); - } -@@ -4902,7 +4922,7 @@ static void sm6_parser_emit_dx_cbuffer_load(struct sm6_parser *sm6, enum dx_intr - - if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) - return; -- src_param_init_vector_from_reg(src_param, &buffer->u.handle.reg); -+ src_param_init_vector_from_handle(sm6, src_param, &buffer->u.handle); - /* Differently from other descriptors, constant buffers require an - * additional index, used to index within the constant buffer itself. */ - src_param->reg.idx_count = 3; -@@ -4986,7 +5006,6 @@ static void sm6_parser_emit_dx_create_handle(struct sm6_parser *sm6, enum dx_int - struct vkd3d_shader_instruction *ins = state->ins; - enum vkd3d_shader_descriptor_type type; - const struct sm6_descriptor_info *d; -- struct vkd3d_shader_register *reg; - struct sm6_value *dst; - unsigned int id; - -@@ -5003,13 +5022,8 @@ static void sm6_parser_emit_dx_create_handle(struct sm6_parser *sm6, enum dx_int - dst = sm6_parser_get_current_value(sm6); - dst->value_type = VALUE_TYPE_HANDLE; - dst->u.handle.d = d; -- -- reg = &dst->u.handle.reg; -- vsir_register_init(reg, d->reg_type, d->reg_data_type, 2); -- reg->dimension = VSIR_DIMENSION_VEC4; -- reg->idx[0].offset = id; -- register_index_address_init(®->idx[1], operands[2], sm6); -- reg->non_uniform = !!sm6_value_get_constant_uint(operands[3]); -+ dst->u.handle.index = operands[2]; -+ dst->u.handle.non_uniform = !!sm6_value_get_constant_uint(operands[3]); - - /* NOP is used to flag no instruction emitted. */ - ins->opcode = VKD3DSIH_NOP; -@@ -5284,7 +5298,7 @@ static void sm6_parser_emit_dx_get_dimensions(struct sm6_parser *sm6, enum dx_in - - if (!(src_params = instruction_src_params_alloc(ins, 1 + is_texture, sm6))) - return; -- src_param_init_vector_from_reg(&src_params[is_texture], &resource->u.handle.reg); -+ src_param_init_vector_from_handle(sm6, &src_params[is_texture], &resource->u.handle); - - if (is_texture) - { -@@ -5304,7 +5318,7 @@ static void sm6_parser_emit_dx_get_dimensions(struct sm6_parser *sm6, enum dx_in - - if (!(src_params = instruction_src_params_alloc(ins, 1, sm6))) - return; -- src_param_init_vector_from_reg(&src_params[0], &resource->u.handle.reg); -+ src_param_init_vector_from_handle(sm6, &src_params[0], &resource->u.handle); - src_params[0].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); - - if (!instruction_dst_param_init_temp_vector(ins, sm6)) -@@ -5546,7 +5560,7 @@ static void sm6_parser_emit_dx_raw_buffer_load(struct sm6_parser *sm6, enum dx_i - if (!(src_params = instruction_src_params_alloc(ins, operand_count, sm6))) - return; - src_params_init_from_operands(src_params, &operands[1], operand_count - 1); -- src_param_init_vector_from_reg(&src_params[operand_count - 1], &resource->u.handle.reg); -+ src_param_init_vector_from_handle(sm6, &src_params[operand_count - 1], &resource->u.handle); - - instruction_dst_param_init_ssa_vector(ins, component_count, sm6); - } -@@ -5617,7 +5631,7 @@ static void sm6_parser_emit_dx_raw_buffer_store(struct sm6_parser *sm6, enum dx_ - - dst_param = instruction_dst_params_alloc(ins, 1, sm6); - dst_param_init_with_mask(dst_param, write_mask); -- dst_param->reg = resource->u.handle.reg; -+ sm6_register_from_handle(sm6, &resource->u.handle, &dst_param->reg); - dst_param->reg.alignment = alignment; - } - -@@ -5658,7 +5672,7 @@ static void sm6_parser_emit_dx_buffer_load(struct sm6_parser *sm6, enum dx_intri - vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_OPERANDS, - "Ignoring structure offset for a typed buffer load."); - } -- src_param_init_vector_from_reg(&src_params[1], &resource->u.handle.reg); -+ src_param_init_vector_from_handle(sm6, &src_params[1], &resource->u.handle); - - instruction_dst_param_init_ssa_vector(ins, VKD3D_VEC4_SIZE, sm6); - } -@@ -5727,7 +5741,7 @@ static void sm6_parser_emit_dx_buffer_store(struct sm6_parser *sm6, enum dx_intr - - dst_param = instruction_dst_params_alloc(ins, 1, sm6); - dst_param_init_with_mask(dst_param, write_mask); -- dst_param->reg = resource->u.handle.reg; -+ sm6_register_from_handle(sm6, &resource->u.handle, &dst_param->reg); - } - - static void sm6_parser_emit_dx_get_sample_count(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, -@@ -5769,7 +5783,7 @@ static void sm6_parser_emit_dx_get_sample_pos(struct sm6_parser *sm6, enum dx_in - return; - if (op == DX_TEX2DMS_GET_SAMPLE_POS) - { -- src_param_init_vector_from_reg(&src_params[0], &resource->u.handle.reg); -+ src_param_init_vector_from_handle(sm6, &src_params[0], &resource->u.handle); - src_param_init_from_value(&src_params[1], operands[1]); - } - else -@@ -5873,8 +5887,8 @@ static void sm6_parser_emit_dx_sample(struct sm6_parser *sm6, enum dx_intrinsic_ - } - - src_param_init_vector_from_reg(&src_params[0], &coord); -- src_param_init_vector_from_reg(&src_params[1], &resource->u.handle.reg); -- src_param_init_vector_from_reg(&src_params[2], &sampler->u.handle.reg); -+ src_param_init_vector_from_handle(sm6, &src_params[1], &resource->u.handle); -+ src_param_init_vector_from_handle(sm6, &src_params[2], &sampler->u.handle); - instruction_set_texel_offset(ins, &operands[6], sm6); - - instruction_dst_param_init_ssa_vector(ins, component_count, sm6); -@@ -6071,8 +6085,8 @@ static void sm6_parser_emit_dx_texture_gather(struct sm6_parser *sm6, enum dx_in - src_param_init_vector_from_reg(&src_params[1], &offset); - else - instruction_set_texel_offset(ins, &operands[6], sm6); -- src_param_init_vector_from_reg(&src_params[1 + extended_offset], &resource->u.handle.reg); -- src_param_init_vector_from_reg(&src_params[2 + extended_offset], &sampler->u.handle.reg); -+ src_param_init_vector_from_handle(sm6, &src_params[1 + extended_offset], &resource->u.handle); -+ src_param_init_vector_from_handle(sm6, &src_params[2 + extended_offset], &sampler->u.handle); - /* Swizzle stored in the sampler parameter is the scalar component index to be gathered. */ - swizzle = sm6_value_get_constant_uint(operands[8]); - if (swizzle >= VKD3D_VEC4_SIZE) -@@ -6124,7 +6138,7 @@ static void sm6_parser_emit_dx_texture_load(struct sm6_parser *sm6, enum dx_intr - if (!(src_params = instruction_src_params_alloc(ins, 2 + is_multisample, sm6))) - return; - src_param_init_vector_from_reg(&src_params[0], &coord); -- src_param_init_vector_from_reg(&src_params[1], &resource->u.handle.reg); -+ src_param_init_vector_from_handle(sm6, &src_params[1], &resource->u.handle); - if (is_multisample) - src_param_init_from_value(&src_params[2], mip_level_or_sample_count); - -@@ -6177,7 +6191,7 @@ static void sm6_parser_emit_dx_texture_store(struct sm6_parser *sm6, enum dx_int - src_param_init_vector_from_reg(&src_params[1], &texel); - - dst_param = instruction_dst_params_alloc(ins, 1, sm6); -- dst_param->reg = resource->u.handle.reg; -+ sm6_register_from_handle(sm6, &resource->u.handle, &dst_param->reg); - dst_param_init_with_mask(dst_param, write_mask); - } - -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -index 8dff48ee83e..bc14885af2b 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -@@ -9263,10 +9263,10 @@ static void sm1_generate_vsir_instr_jump(struct hlsl_ctx *ctx, - - if (jump->type == HLSL_IR_JUMP_DISCARD_NEG) - { -- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_TEXKILL, 1, 0))) -+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_TEXKILL, 0, 1))) - return; - -- vsir_dst_from_hlsl_node(&ins->dst[0], ctx, condition); -+ vsir_src_from_hlsl_node(&ins->src[0], ctx, condition, VKD3DSP_WRITEMASK_ALL); - } - else - { -diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c -index b8f83946294..4101e92e91f 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/ir.c -+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c -@@ -622,7 +622,7 @@ static enum vkd3d_result vsir_program_lower_texkill(struct vsir_program *program - if (*tmp_idx == ~0u) - *tmp_idx = program->temp_count++; - -- /* tmp = ins->dst[0] < 0 */ -+ /* tmp = ins->src[0] < 0 */ - - ins = &instructions->elements[pos + 1]; - if (!vsir_instruction_init_with_params(program, ins, &texkill->location, VKD3DSIH_LTO, 1, 2)) -@@ -633,7 +633,7 @@ static enum vkd3d_result vsir_program_lower_texkill(struct vsir_program *program - ins->dst[0].reg.idx[0].offset = *tmp_idx; - ins->dst[0].write_mask = VKD3DSP_WRITEMASK_ALL; - -- ins->src[0].reg = texkill->dst[0].reg; -+ ins->src[0].reg = texkill->src[0].reg; - ins->src[0].swizzle = VKD3D_SHADER_NO_SWIZZLE; - vsir_register_init(&ins->src[1].reg, VKD3DSPR_IMMCONST, VKD3D_DATA_FLOAT, 0); - ins->src[1].reg.dimension = VSIR_DIMENSION_VEC4; -diff --git a/libs/vkd3d/libs/vkd3d-shader/msl.c b/libs/vkd3d/libs/vkd3d-shader/msl.c -index def6f459f69..4f37468af86 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/msl.c -+++ b/libs/vkd3d/libs/vkd3d-shader/msl.c -@@ -18,6 +18,13 @@ - - #include "vkd3d_shader_private.h" - -+enum msl_data_type -+{ -+ MSL_DATA_FLOAT, -+ MSL_DATA_UINT, -+ MSL_DATA_UNION, -+}; -+ - struct msl_src - { - struct vkd3d_string_buffer *str; -@@ -267,15 +274,14 @@ static void msl_print_srv_name(struct vkd3d_string_buffer *buffer, struct msl_ge - vkd3d_string_buffer_printf(buffer, ">>()"); - } - --static void msl_print_register_name(struct vkd3d_string_buffer *buffer, -+static enum msl_data_type msl_print_register_name(struct vkd3d_string_buffer *buffer, - struct msl_generator *gen, const struct vkd3d_shader_register *reg) - { - switch (reg->type) - { - case VKD3DSPR_TEMP: - vkd3d_string_buffer_printf(buffer, "r[%u]", reg->idx[0].offset); -- msl_print_register_datatype(buffer, gen, reg->data_type); -- break; -+ return MSL_DATA_UNION; - - case VKD3DSPR_INPUT: - if (reg->idx_count != 1) -@@ -283,18 +289,17 @@ static void msl_print_register_name(struct vkd3d_string_buffer *buffer, - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, - "Internal compiler error: Unhandled input register index count %u.", reg->idx_count); - vkd3d_string_buffer_printf(buffer, "", reg->type); -- break; -+ return MSL_DATA_UNION; - } - if (reg->idx[0].rel_addr) - { - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, - "Internal compiler error: Unhandled input register indirect addressing."); - vkd3d_string_buffer_printf(buffer, "", reg->type); -- break; -+ return MSL_DATA_UNION; - } - vkd3d_string_buffer_printf(buffer, "v[%u]", reg->idx[0].offset); -- msl_print_register_datatype(buffer, gen, reg->data_type); -- break; -+ return MSL_DATA_UNION; - - case VKD3DSPR_OUTPUT: - if (reg->idx_count != 1) -@@ -302,18 +307,17 @@ static void msl_print_register_name(struct vkd3d_string_buffer *buffer, - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, - "Internal compiler error: Unhandled output register index count %u.", reg->idx_count); - vkd3d_string_buffer_printf(buffer, "", reg->type); -- break; -+ return MSL_DATA_UNION; - } - if (reg->idx[0].rel_addr) - { - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, - "Internal compiler error: Unhandled output register indirect addressing."); - vkd3d_string_buffer_printf(buffer, "", reg->type); -- break; -+ return MSL_DATA_UNION; - } - vkd3d_string_buffer_printf(buffer, "o[%u]", reg->idx[0].offset); -- msl_print_register_datatype(buffer, gen, reg->data_type); -- break; -+ return MSL_DATA_UNION; - - case VKD3DSPR_DEPTHOUT: - if (gen->program->shader_version.type != VKD3D_SHADER_TYPE_PIXEL) -@@ -321,64 +325,27 @@ static void msl_print_register_name(struct vkd3d_string_buffer *buffer, - "Internal compiler error: Unhandled depth output in shader type #%x.", - gen->program->shader_version.type); - vkd3d_string_buffer_printf(buffer, "o_depth"); -- break; -+ return MSL_DATA_FLOAT; - - case VKD3DSPR_IMMCONST: - switch (reg->dimension) - { - case VSIR_DIMENSION_SCALAR: -- switch (reg->data_type) -- { -- case VKD3D_DATA_INT: -- vkd3d_string_buffer_printf(buffer, "as_type(%#xu)", reg->u.immconst_u32[0]); -- break; -- case VKD3D_DATA_UINT: -- vkd3d_string_buffer_printf(buffer, "%#xu", reg->u.immconst_u32[0]); -- break; -- case VKD3D_DATA_FLOAT: -- vkd3d_string_buffer_printf(buffer, "as_type(%#xu)", reg->u.immconst_u32[0]); -- break; -- default: -- msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, -- "Internal compiler error: Unhandled immconst datatype %#x.", reg->data_type); -- vkd3d_string_buffer_printf(buffer, "", reg->data_type); -- break; -- } -- break; -+ vkd3d_string_buffer_printf(buffer, "%#xu", reg->u.immconst_u32[0]); -+ return MSL_DATA_UINT; - - case VSIR_DIMENSION_VEC4: -- switch (reg->data_type) -- { -- case VKD3D_DATA_INT: -- vkd3d_string_buffer_printf(buffer, "as_type(uint4(%#xu, %#xu, %#xu, %#xu))", -- reg->u.immconst_u32[0], reg->u.immconst_u32[1], -- reg->u.immconst_u32[2], reg->u.immconst_u32[3]); -- break; -- case VKD3D_DATA_UINT: -- vkd3d_string_buffer_printf(buffer, "uint4(%#xu, %#xu, %#xu, %#xu)", -- reg->u.immconst_u32[0], reg->u.immconst_u32[1], -- reg->u.immconst_u32[2], reg->u.immconst_u32[3]); -- break; -- case VKD3D_DATA_FLOAT: -- vkd3d_string_buffer_printf(buffer, "as_type(uint4(%#xu, %#xu, %#xu, %#xu))", -- reg->u.immconst_u32[0], reg->u.immconst_u32[1], -- reg->u.immconst_u32[2], reg->u.immconst_u32[3]); -- break; -- default: -- msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, -- "Internal compiler error: Unhandled immconst datatype %#x.", reg->data_type); -- vkd3d_string_buffer_printf(buffer, "", reg->data_type); -- break; -- } -- break; -+ vkd3d_string_buffer_printf(buffer, "uint4(%#xu, %#xu, %#xu, %#xu)", -+ reg->u.immconst_u32[0], reg->u.immconst_u32[1], -+ reg->u.immconst_u32[2], reg->u.immconst_u32[3]); -+ return MSL_DATA_UINT; - - default: - vkd3d_string_buffer_printf(buffer, "", reg->dimension); - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, - "Internal compiler error: Unhandled dimension %#x.", reg->dimension); -- break; -+ return MSL_DATA_UINT; - } -- break; - - case VKD3DSPR_CONSTBUFFER: - { -@@ -390,33 +357,32 @@ static void msl_print_register_name(struct vkd3d_string_buffer *buffer, - "Internal compiler error: Unhandled constant buffer register index count %u.", - reg->idx_count); - vkd3d_string_buffer_printf(buffer, "", reg->type); -- break; -+ return MSL_DATA_UNION; - } - 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; -+ return MSL_DATA_UNION; - } - 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; -+ return MSL_DATA_UNION; - } - 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; -+ return MSL_DATA_UNION; - } - - default: - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, - "Internal compiler error: Unhandled register type %#x.", reg->type); - vkd3d_string_buffer_printf(buffer, "", reg->type); -- break; -+ return MSL_DATA_UINT; - } - } - -@@ -451,24 +417,64 @@ static void msl_src_cleanup(struct msl_src *src, struct vkd3d_string_buffer_cach - vkd3d_string_buffer_release(cache, src->str); - } - --static void msl_src_init(struct msl_src *msl_src, struct msl_generator *gen, -- const struct vkd3d_shader_src_param *vsir_src, uint32_t mask) -+static void msl_print_bitcast(struct vkd3d_string_buffer *dst, struct msl_generator *gen, const char *src, -+ enum vkd3d_data_type dst_data_type, enum msl_data_type src_data_type, enum vsir_dimension dimension) -+{ -+ bool write_cast = false; -+ -+ if (dst_data_type == VKD3D_DATA_UNORM || dst_data_type == VKD3D_DATA_SNORM) -+ dst_data_type = VKD3D_DATA_FLOAT; -+ -+ switch (src_data_type) -+ { -+ case MSL_DATA_FLOAT: -+ write_cast = dst_data_type != VKD3D_DATA_FLOAT; -+ break; -+ -+ case MSL_DATA_UINT: -+ write_cast = dst_data_type != VKD3D_DATA_UINT; -+ break; -+ -+ case MSL_DATA_UNION: -+ break; -+ } -+ -+ if (write_cast) -+ { -+ vkd3d_string_buffer_printf(dst, "as_type<"); -+ msl_print_resource_datatype(gen, dst, dst_data_type); -+ vkd3d_string_buffer_printf(dst, "%s>(", dimension == VSIR_DIMENSION_VEC4 ? "4" : ""); -+ } -+ -+ vkd3d_string_buffer_printf(dst, "%s", src); -+ -+ if (write_cast) -+ vkd3d_string_buffer_printf(dst, ")"); -+ -+ if (src_data_type == MSL_DATA_UNION) -+ msl_print_register_datatype(dst, gen, dst_data_type); -+} -+ -+static void msl_print_src_with_type(struct vkd3d_string_buffer *buffer, struct msl_generator *gen, -+ const struct vkd3d_shader_src_param *vsir_src, uint32_t mask, enum vkd3d_data_type data_type) - { - const struct vkd3d_shader_register *reg = &vsir_src->reg; -- struct vkd3d_string_buffer *str; -+ struct vkd3d_string_buffer *register_name, *str; -+ enum msl_data_type src_data_type; - -- msl_src->str = vkd3d_string_buffer_get(&gen->string_buffers); -+ register_name = vkd3d_string_buffer_get(&gen->string_buffers); - - if (reg->non_uniform) - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, - "Internal compiler error: Unhandled 'non-uniform' modifier."); - - if (!vsir_src->modifiers) -- str = msl_src->str; -+ str = buffer; - else - str = vkd3d_string_buffer_get(&gen->string_buffers); - -- msl_print_register_name(str, gen, reg); -+ src_data_type = msl_print_register_name(register_name, gen, reg); -+ msl_print_bitcast(str, gen, register_name->buffer, data_type, src_data_type, reg->dimension); - if (reg->dimension == VSIR_DIMENSION_VEC4) - msl_print_swizzle(str, vsir_src->swizzle, mask); - -@@ -477,23 +483,30 @@ static void msl_src_init(struct msl_src *msl_src, struct msl_generator *gen, - case VKD3DSPSM_NONE: - break; - case VKD3DSPSM_NEG: -- vkd3d_string_buffer_printf(msl_src->str, "-%s", str->buffer); -+ vkd3d_string_buffer_printf(buffer, "-%s", str->buffer); - break; - case VKD3DSPSM_ABS: -- vkd3d_string_buffer_printf(msl_src->str, "abs(%s)", str->buffer); -+ vkd3d_string_buffer_printf(buffer, "abs(%s)", str->buffer); - break; - default: -- vkd3d_string_buffer_printf(msl_src->str, "(%s)", -+ vkd3d_string_buffer_printf(buffer, "(%s)", - vsir_src->modifiers, str->buffer); - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, - "Internal compiler error: Unhandled source modifier(s) %#x.", vsir_src->modifiers); - break; - } - -- if (str != msl_src->str) -+ if (str != buffer) - vkd3d_string_buffer_release(&gen->string_buffers, str); - } - -+static void msl_src_init(struct msl_src *msl_src, struct msl_generator *gen, -+ const struct vkd3d_shader_src_param *vsir_src, uint32_t mask) -+{ -+ msl_src->str = vkd3d_string_buffer_get(&gen->string_buffers); -+ msl_print_src_with_type(msl_src->str, gen, vsir_src, mask, vsir_src->reg.data_type); -+} -+ - static void msl_dst_cleanup(struct msl_dst *dst, struct vkd3d_string_buffer_cache *cache) - { - vkd3d_string_buffer_release(cache, dst->mask); -@@ -504,6 +517,7 @@ static uint32_t msl_dst_init(struct msl_dst *msl_dst, struct msl_generator *gen, - const struct vkd3d_shader_instruction *ins, const struct vkd3d_shader_dst_param *vsir_dst) - { - uint32_t write_mask = vsir_dst->write_mask; -+ enum msl_data_type dst_data_type; - - if (ins->flags & VKD3DSI_PRECISE_XYZW) - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, -@@ -516,7 +530,9 @@ static uint32_t msl_dst_init(struct msl_dst *msl_dst, struct msl_generator *gen, - msl_dst->register_name = vkd3d_string_buffer_get(&gen->string_buffers); - msl_dst->mask = vkd3d_string_buffer_get(&gen->string_buffers); - -- msl_print_register_name(msl_dst->register_name, gen, &vsir_dst->reg); -+ dst_data_type = msl_print_register_name(msl_dst->register_name, gen, &vsir_dst->reg); -+ if (dst_data_type == MSL_DATA_UNION) -+ msl_print_register_datatype(msl_dst->mask, gen, vsir_dst->reg.data_type); - if (vsir_dst->reg.dimension == VSIR_DIMENSION_VEC4) - msl_print_write_mask(msl_dst->mask, write_mask); - -@@ -710,7 +726,6 @@ static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruct - 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; -@@ -762,34 +777,28 @@ static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruct - } - - 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); -+ msl_print_src_with_type(read, gen, &ins->src[0], coord_mask, VKD3D_DATA_UINT); - if (resource_type_info->array) -- vkd3d_string_buffer_printf(read, ", as_type(%s)", array_index.str->buffer); -+ { -+ vkd3d_string_buffer_printf(read, ", "); -+ msl_print_src_with_type(read, gen, &ins->src[0], coord_mask + 1, VKD3D_DATA_UINT); -+ } - if (resource_type_info->lod) -- vkd3d_string_buffer_printf(read, ", as_type(%s)", lod.str->buffer); -+ { -+ vkd3d_string_buffer_printf(read, ", "); -+ msl_print_src_with_type(read, gen, &ins->src[0], VKD3DSP_WRITEMASK_3, VKD3D_DATA_UINT); -+ } - 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); - } - --- -2.47.2 -