diff --git a/patches/vkd3d-latest/0001-Updated-vkd3d-to-9619582d1b6a54720e17a148a72b446fda2.patch b/patches/vkd3d-latest/0001-Updated-vkd3d-to-9619582d1b6a54720e17a148a72b446fda2.patch index c2da59c6..f26b5571 100644 --- a/patches/vkd3d-latest/0001-Updated-vkd3d-to-9619582d1b6a54720e17a148a72b446fda2.patch +++ b/patches/vkd3d-latest/0001-Updated-vkd3d-to-9619582d1b6a54720e17a148a72b446fda2.patch @@ -1,4 +1,4 @@ -From caa0d7f0cafae8a67fb79dd7426839126285a092 Mon Sep 17 00:00:00 2001 +From 37be48827f00f33b78d769de7935076c6a2840e5 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Fri, 29 Nov 2024 07:14:57 +1100 Subject: [PATCH] Updated vkd3d to 9619582d1b6a54720e17a148a72b446fda2fd41f. diff --git a/patches/vkd3d-latest/0002-Updated-vkd3d-to-39cbef9e018ee760ffd175fdd6729e47052.patch b/patches/vkd3d-latest/0002-Updated-vkd3d-to-39cbef9e018ee760ffd175fdd6729e47052.patch index bf778c6a..39b53d70 100644 --- a/patches/vkd3d-latest/0002-Updated-vkd3d-to-39cbef9e018ee760ffd175fdd6729e47052.patch +++ b/patches/vkd3d-latest/0002-Updated-vkd3d-to-39cbef9e018ee760ffd175fdd6729e47052.patch @@ -1,4 +1,4 @@ -From f5513fb3ce1827645b74a43d1486c60d4dcdfe9b Mon Sep 17 00:00:00 2001 +From c5b9e806ed3c3535916aba32bf267f2eac2a4780 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Tue, 3 Dec 2024 09:14:28 +1100 Subject: [PATCH] Updated vkd3d to 39cbef9e018ee760ffd175fdd6729e470529fb77. diff --git a/patches/vkd3d-latest/0003-Updated-vkd3d-to-36fda8e28ca31517ae051b2e46b00d71a23.patch b/patches/vkd3d-latest/0003-Updated-vkd3d-to-36fda8e28ca31517ae051b2e46b00d71a23.patch new file mode 100644 index 00000000..9b8b4de1 --- /dev/null +++ b/patches/vkd3d-latest/0003-Updated-vkd3d-to-36fda8e28ca31517ae051b2e46b00d71a23.patch @@ -0,0 +1,1803 @@ +From a28b8bf865e552385d9a3658894e9cdbfe23e5f4 Mon Sep 17 00:00:00 2001 +From: Alistair Leslie-Hughes +Date: Wed, 4 Dec 2024 07:19:12 +1100 +Subject: [PATCH] Updated vkd3d to 36fda8e28ca31517ae051b2e46b00d71a23c01a8. + +--- + libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 34 +- + libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 205 ++++++------ + libs/vkd3d/libs/vkd3d-shader/glsl.c | 7 - + libs/vkd3d/libs/vkd3d-shader/hlsl.c | 156 +++++----- + libs/vkd3d/libs/vkd3d-shader/hlsl.h | 2 + + libs/vkd3d/libs/vkd3d-shader/hlsl.y | 134 +++++--- + libs/vkd3d/libs/vkd3d-shader/ir.c | 292 +++++++++--------- + libs/vkd3d/libs/vkd3d-shader/msl.c | 65 +++- + libs/vkd3d/libs/vkd3d-shader/spirv.c | 166 ++++------ + .../libs/vkd3d-shader/vkd3d_shader_private.h | 2 + + 10 files changed, 551 insertions(+), 512 deletions(-) + +diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c +index 7c5444f63a3..8c96befadea 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c ++++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c +@@ -49,7 +49,7 @@ static const char * const shader_opcode_names[] = + [VKD3DSIH_BFREV ] = "bfrev", + [VKD3DSIH_BRANCH ] = "branch", + [VKD3DSIH_BREAK ] = "break", +- [VKD3DSIH_BREAKC ] = "breakc", ++ [VKD3DSIH_BREAKC ] = "break", + [VKD3DSIH_BREAKP ] = "breakp", + [VKD3DSIH_BUFINFO ] = "bufinfo", + [VKD3DSIH_CALL ] = "call", +@@ -183,7 +183,7 @@ static const char * const shader_opcode_names[] = + [VKD3DSIH_IDIV ] = "idiv", + [VKD3DSIH_IEQ ] = "ieq", + [VKD3DSIH_IF ] = "if", +- [VKD3DSIH_IFC ] = "ifc", ++ [VKD3DSIH_IFC ] = "if", + [VKD3DSIH_IGE ] = "ige", + [VKD3DSIH_ILT ] = "ilt", + [VKD3DSIH_IMAD ] = "imad", +@@ -815,7 +815,7 @@ static void shader_print_dcl_usage(struct vkd3d_d3d_asm_compiler *compiler, + usage = "tessfactor"; + break; + case VKD3D_DECL_USAGE_POSITIONT: +- usage = "positionT"; ++ usage = "positiont"; + indexed = true; + break; + case VKD3D_DECL_USAGE_FOG: +@@ -2547,6 +2547,33 @@ static void trace_signature(const struct shader_signature *signature, const char + vkd3d_string_buffer_cleanup(&buffer); + } + ++static void trace_io_declarations(const struct vsir_program *program) ++{ ++ struct vkd3d_string_buffer buffer; ++ bool empty = true; ++ unsigned int i; ++ ++ vkd3d_string_buffer_init(&buffer); ++ ++ vkd3d_string_buffer_printf(&buffer, "Input/output declarations:"); ++ ++ 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 (empty) ++ vkd3d_string_buffer_printf(&buffer, " empty"); ++ ++ TRACE("%s\n", buffer.buffer); ++ ++ vkd3d_string_buffer_cleanup(&buffer); ++} ++ + void vsir_program_trace(const struct vsir_program *program) + { + const unsigned int flags = VSIR_ASM_FLAG_DUMP_TYPES | VSIR_ASM_FLAG_DUMP_ALL_INDICES; +@@ -2556,6 +2583,7 @@ void vsir_program_trace(const struct vsir_program *program) + trace_signature(&program->input_signature, "Input"); + trace_signature(&program->output_signature, "Output"); + trace_signature(&program->patch_constant_signature, "Patch-constant"); ++ trace_io_declarations(program); + + if (d3d_asm_compile(program, NULL, &code, flags) != VKD3D_OK) + return; +diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c +index 7db658fb541..7ffd060d833 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c ++++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c +@@ -235,7 +235,7 @@ static const struct vkd3d_sm1_opcode_info vs_opcode_table[] = + /* Arithmetic */ + {VKD3D_SM1_OP_NOP, 0, 0, VKD3DSIH_NOP}, + {VKD3D_SM1_OP_MOV, 1, 1, VKD3DSIH_MOV}, +- {VKD3D_SM1_OP_MOVA, 1, 1, VKD3DSIH_MOVA, {2, 0}, {~0u, ~0u}}, ++ {VKD3D_SM1_OP_MOVA, 1, 1, VKD3DSIH_MOVA, {2, 0}}, + {VKD3D_SM1_OP_ADD, 1, 2, VKD3DSIH_ADD}, + {VKD3D_SM1_OP_SUB, 1, 2, VKD3DSIH_SUB}, + {VKD3D_SM1_OP_MAD, 1, 3, VKD3DSIH_MAD}, +@@ -248,22 +248,22 @@ static const struct vkd3d_sm1_opcode_info vs_opcode_table[] = + {VKD3D_SM1_OP_MAX, 1, 2, VKD3DSIH_MAX}, + {VKD3D_SM1_OP_SLT, 1, 2, VKD3DSIH_SLT}, + {VKD3D_SM1_OP_SGE, 1, 2, VKD3DSIH_SGE}, +- {VKD3D_SM1_OP_ABS, 1, 1, VKD3DSIH_ABS}, ++ {VKD3D_SM1_OP_ABS, 1, 1, VKD3DSIH_ABS, {2, 0}}, + {VKD3D_SM1_OP_EXP, 1, 1, VKD3DSIH_EXP}, + {VKD3D_SM1_OP_LOG, 1, 1, VKD3DSIH_LOG}, + {VKD3D_SM1_OP_EXPP, 1, 1, VKD3DSIH_EXPP}, + {VKD3D_SM1_OP_LOGP, 1, 1, VKD3DSIH_LOGP}, + {VKD3D_SM1_OP_LIT, 1, 1, VKD3DSIH_LIT}, + {VKD3D_SM1_OP_DST, 1, 2, VKD3DSIH_DST}, +- {VKD3D_SM1_OP_LRP, 1, 3, VKD3DSIH_LRP}, ++ {VKD3D_SM1_OP_LRP, 1, 3, VKD3DSIH_LRP, {2, 0}}, + {VKD3D_SM1_OP_FRC, 1, 1, VKD3DSIH_FRC}, +- {VKD3D_SM1_OP_POW, 1, 2, VKD3DSIH_POW}, +- {VKD3D_SM1_OP_CRS, 1, 2, VKD3DSIH_CRS}, +- {VKD3D_SM1_OP_SGN, 1, 3, VKD3DSIH_SGN, {2, 0}, { 2, 1}}, +- {VKD3D_SM1_OP_SGN, 1, 1, VKD3DSIH_SGN, {3, 0}, {~0u, ~0u}}, +- {VKD3D_SM1_OP_NRM, 1, 1, VKD3DSIH_NRM,}, +- {VKD3D_SM1_OP_SINCOS, 1, 3, VKD3DSIH_SINCOS, {2, 0}, { 2, 1}}, +- {VKD3D_SM1_OP_SINCOS, 1, 1, VKD3DSIH_SINCOS, {3, 0}, {~0u, ~0u}}, ++ {VKD3D_SM1_OP_POW, 1, 2, VKD3DSIH_POW, {2, 0}}, ++ {VKD3D_SM1_OP_CRS, 1, 2, VKD3DSIH_CRS, {2, 0}}, ++ {VKD3D_SM1_OP_SGN, 1, 3, VKD3DSIH_SGN, {2, 0}, {2, 1}}, ++ {VKD3D_SM1_OP_SGN, 1, 1, VKD3DSIH_SGN, {3, 0}}, ++ {VKD3D_SM1_OP_NRM, 1, 1, VKD3DSIH_NRM, {2, 0}}, ++ {VKD3D_SM1_OP_SINCOS, 1, 3, VKD3DSIH_SINCOS, {2, 0}, {2, 1}}, ++ {VKD3D_SM1_OP_SINCOS, 1, 1, VKD3DSIH_SINCOS, {3, 0}}, + /* Matrix */ + {VKD3D_SM1_OP_M4x4, 1, 2, VKD3DSIH_M4x4}, + {VKD3D_SM1_OP_M4x3, 1, 2, VKD3DSIH_M4x3}, +@@ -274,27 +274,27 @@ static const struct vkd3d_sm1_opcode_info vs_opcode_table[] = + {VKD3D_SM1_OP_DCL, 0, 0, VKD3DSIH_DCL}, + /* Constant definitions */ + {VKD3D_SM1_OP_DEF, 1, 1, VKD3DSIH_DEF}, +- {VKD3D_SM1_OP_DEFB, 1, 1, VKD3DSIH_DEFB}, +- {VKD3D_SM1_OP_DEFI, 1, 1, VKD3DSIH_DEFI}, ++ {VKD3D_SM1_OP_DEFB, 1, 1, VKD3DSIH_DEFB, {2, 0}}, ++ {VKD3D_SM1_OP_DEFI, 1, 1, VKD3DSIH_DEFI, {2, 0}}, + /* Control flow */ +- {VKD3D_SM1_OP_REP, 0, 1, VKD3DSIH_REP, {2, 0}, {~0u, ~0u}}, +- {VKD3D_SM1_OP_ENDREP, 0, 0, VKD3DSIH_ENDREP, {2, 0}, {~0u, ~0u}}, +- {VKD3D_SM1_OP_IF, 0, 1, VKD3DSIH_IF, {2, 0}, {~0u, ~0u}}, +- {VKD3D_SM1_OP_IFC, 0, 2, VKD3DSIH_IFC, {2, 1}, {~0u, ~0u}}, +- {VKD3D_SM1_OP_ELSE, 0, 0, VKD3DSIH_ELSE, {2, 0}, {~0u, ~0u}}, +- {VKD3D_SM1_OP_ENDIF, 0, 0, VKD3DSIH_ENDIF, {2, 0}, {~0u, ~0u}}, +- {VKD3D_SM1_OP_BREAK, 0, 0, VKD3DSIH_BREAK, {2, 1}, {~0u, ~0u}}, +- {VKD3D_SM1_OP_BREAKC, 0, 2, VKD3DSIH_BREAKC, {2, 1}, {~0u, ~0u}}, +- {VKD3D_SM1_OP_BREAKP, 0, 1, VKD3DSIH_BREAKP}, +- {VKD3D_SM1_OP_CALL, 0, 1, VKD3DSIH_CALL, {2, 0}, {~0u, ~0u}}, +- {VKD3D_SM1_OP_CALLNZ, 0, 2, VKD3DSIH_CALLNZ, {2, 0}, {~0u, ~0u}}, +- {VKD3D_SM1_OP_LOOP, 0, 2, VKD3DSIH_LOOP, {2, 0}, {~0u, ~0u}}, +- {VKD3D_SM1_OP_RET, 0, 0, VKD3DSIH_RET, {2, 0}, {~0u, ~0u}}, +- {VKD3D_SM1_OP_ENDLOOP, 0, 0, VKD3DSIH_ENDLOOP, {2, 0}, {~0u, ~0u}}, +- {VKD3D_SM1_OP_LABEL, 0, 1, VKD3DSIH_LABEL, {2, 0}, {~0u, ~0u}}, +- +- {VKD3D_SM1_OP_SETP, 1, 2, VKD3DSIH_SETP}, +- {VKD3D_SM1_OP_TEXLDL, 1, 2, VKD3DSIH_TEXLDL, {3, 0}, {~0u, ~0u}}, ++ {VKD3D_SM1_OP_REP, 0, 1, VKD3DSIH_REP, {2, 0}}, ++ {VKD3D_SM1_OP_ENDREP, 0, 0, VKD3DSIH_ENDREP, {2, 0}}, ++ {VKD3D_SM1_OP_IF, 0, 1, VKD3DSIH_IF, {2, 0}}, ++ {VKD3D_SM1_OP_IFC, 0, 2, VKD3DSIH_IFC, {2, 1}}, ++ {VKD3D_SM1_OP_ELSE, 0, 0, VKD3DSIH_ELSE, {2, 0}}, ++ {VKD3D_SM1_OP_ENDIF, 0, 0, VKD3DSIH_ENDIF, {2, 0}}, ++ {VKD3D_SM1_OP_BREAK, 0, 0, VKD3DSIH_BREAK, {2, 1}}, ++ {VKD3D_SM1_OP_BREAKC, 0, 2, VKD3DSIH_BREAKC, {2, 1}}, ++ {VKD3D_SM1_OP_BREAKP, 0, 1, VKD3DSIH_BREAKP, {2, 1}}, ++ {VKD3D_SM1_OP_CALL, 0, 1, VKD3DSIH_CALL, {2, 0}}, ++ {VKD3D_SM1_OP_CALLNZ, 0, 2, VKD3DSIH_CALLNZ, {2, 0}}, ++ {VKD3D_SM1_OP_LOOP, 0, 2, VKD3DSIH_LOOP, {2, 0}}, ++ {VKD3D_SM1_OP_RET, 0, 0, VKD3DSIH_RET, {2, 0}}, ++ {VKD3D_SM1_OP_ENDLOOP, 0, 0, VKD3DSIH_ENDLOOP, {2, 0}}, ++ {VKD3D_SM1_OP_LABEL, 0, 1, VKD3DSIH_LABEL, {2, 0}}, ++ ++ {VKD3D_SM1_OP_SETP, 1, 2, VKD3DSIH_SETP, {2, 1}}, ++ {VKD3D_SM1_OP_TEXLDL, 1, 2, VKD3DSIH_TEXLDL, {3, 0}}, + {0, 0, 0, VKD3DSIH_INVALID}, + }; + +@@ -307,89 +307,84 @@ static const struct vkd3d_sm1_opcode_info ps_opcode_table[] = + {VKD3D_SM1_OP_SUB, 1, 2, VKD3DSIH_SUB}, + {VKD3D_SM1_OP_MAD, 1, 3, VKD3DSIH_MAD}, + {VKD3D_SM1_OP_MUL, 1, 2, VKD3DSIH_MUL}, +- {VKD3D_SM1_OP_RCP, 1, 1, VKD3DSIH_RCP}, +- {VKD3D_SM1_OP_RSQ, 1, 1, VKD3DSIH_RSQ}, ++ {VKD3D_SM1_OP_RCP, 1, 1, VKD3DSIH_RCP, {2, 0}}, ++ {VKD3D_SM1_OP_RSQ, 1, 1, VKD3DSIH_RSQ, {2, 0}}, + {VKD3D_SM1_OP_DP3, 1, 2, VKD3DSIH_DP3}, +- {VKD3D_SM1_OP_DP4, 1, 2, VKD3DSIH_DP4}, +- {VKD3D_SM1_OP_MIN, 1, 2, VKD3DSIH_MIN}, +- {VKD3D_SM1_OP_MAX, 1, 2, VKD3DSIH_MAX}, +- {VKD3D_SM1_OP_SLT, 1, 2, VKD3DSIH_SLT}, +- {VKD3D_SM1_OP_SGE, 1, 2, VKD3DSIH_SGE}, +- {VKD3D_SM1_OP_ABS, 1, 1, VKD3DSIH_ABS}, +- {VKD3D_SM1_OP_EXP, 1, 1, VKD3DSIH_EXP}, +- {VKD3D_SM1_OP_LOG, 1, 1, VKD3DSIH_LOG}, +- {VKD3D_SM1_OP_EXPP, 1, 1, VKD3DSIH_EXPP}, +- {VKD3D_SM1_OP_LOGP, 1, 1, VKD3DSIH_LOGP}, +- {VKD3D_SM1_OP_DST, 1, 2, VKD3DSIH_DST}, ++ {VKD3D_SM1_OP_DP4, 1, 2, VKD3DSIH_DP4, {1, 2}}, ++ {VKD3D_SM1_OP_MIN, 1, 2, VKD3DSIH_MIN, {2, 0}}, ++ {VKD3D_SM1_OP_MAX, 1, 2, VKD3DSIH_MAX, {2, 0}}, ++ {VKD3D_SM1_OP_ABS, 1, 1, VKD3DSIH_ABS, {2, 0}}, ++ {VKD3D_SM1_OP_EXP, 1, 1, VKD3DSIH_EXP, {2, 0}}, ++ {VKD3D_SM1_OP_LOG, 1, 1, VKD3DSIH_LOG, {2, 0}}, + {VKD3D_SM1_OP_LRP, 1, 3, VKD3DSIH_LRP}, +- {VKD3D_SM1_OP_FRC, 1, 1, VKD3DSIH_FRC}, +- {VKD3D_SM1_OP_CND, 1, 3, VKD3DSIH_CND, {1, 0}, { 1, 4}}, +- {VKD3D_SM1_OP_CMP, 1, 3, VKD3DSIH_CMP, {1, 2}, { 3, 0}}, +- {VKD3D_SM1_OP_POW, 1, 2, VKD3DSIH_POW}, +- {VKD3D_SM1_OP_CRS, 1, 2, VKD3DSIH_CRS}, +- {VKD3D_SM1_OP_NRM, 1, 1, VKD3DSIH_NRM}, +- {VKD3D_SM1_OP_SINCOS, 1, 3, VKD3DSIH_SINCOS, {2, 0}, { 2, 1}}, +- {VKD3D_SM1_OP_SINCOS, 1, 1, VKD3DSIH_SINCOS, {3, 0}, {~0u, ~0u}}, +- {VKD3D_SM1_OP_DP2ADD, 1, 3, VKD3DSIH_DP2ADD, {2, 0}, {~0u, ~0u}}, ++ {VKD3D_SM1_OP_FRC, 1, 1, VKD3DSIH_FRC, {2, 0}}, ++ {VKD3D_SM1_OP_CND, 1, 3, VKD3DSIH_CND, {1, 0}, {1, 4}}, ++ {VKD3D_SM1_OP_CMP, 1, 3, VKD3DSIH_CMP, {1, 2}}, ++ {VKD3D_SM1_OP_POW, 1, 2, VKD3DSIH_POW, {2, 0}}, ++ {VKD3D_SM1_OP_CRS, 1, 2, VKD3DSIH_CRS, {2, 0}}, ++ {VKD3D_SM1_OP_NRM, 1, 1, VKD3DSIH_NRM, {2, 0}}, ++ {VKD3D_SM1_OP_SINCOS, 1, 3, VKD3DSIH_SINCOS, {2, 0}, {2, 1}}, ++ {VKD3D_SM1_OP_SINCOS, 1, 1, VKD3DSIH_SINCOS, {3, 0}}, ++ {VKD3D_SM1_OP_DP2ADD, 1, 3, VKD3DSIH_DP2ADD, {2, 0}}, + /* Matrix */ +- {VKD3D_SM1_OP_M4x4, 1, 2, VKD3DSIH_M4x4}, +- {VKD3D_SM1_OP_M4x3, 1, 2, VKD3DSIH_M4x3}, +- {VKD3D_SM1_OP_M3x4, 1, 2, VKD3DSIH_M3x4}, +- {VKD3D_SM1_OP_M3x3, 1, 2, VKD3DSIH_M3x3}, +- {VKD3D_SM1_OP_M3x2, 1, 2, VKD3DSIH_M3x2}, ++ {VKD3D_SM1_OP_M4x4, 1, 2, VKD3DSIH_M4x4, {2, 0}}, ++ {VKD3D_SM1_OP_M4x3, 1, 2, VKD3DSIH_M4x3, {2, 0}}, ++ {VKD3D_SM1_OP_M3x4, 1, 2, VKD3DSIH_M3x4, {2, 0}}, ++ {VKD3D_SM1_OP_M3x3, 1, 2, VKD3DSIH_M3x3, {2, 0}}, ++ {VKD3D_SM1_OP_M3x2, 1, 2, VKD3DSIH_M3x2, {2, 0}}, + /* Declarations */ +- {VKD3D_SM1_OP_DCL, 0, 0, VKD3DSIH_DCL}, ++ {VKD3D_SM1_OP_DCL, 0, 0, VKD3DSIH_DCL, {2, 0}}, + /* Constant definitions */ + {VKD3D_SM1_OP_DEF, 1, 1, VKD3DSIH_DEF}, +- {VKD3D_SM1_OP_DEFB, 1, 1, VKD3DSIH_DEFB}, +- {VKD3D_SM1_OP_DEFI, 1, 1, VKD3DSIH_DEFI}, ++ {VKD3D_SM1_OP_DEFB, 1, 1, VKD3DSIH_DEFB, {2, 0}}, ++ {VKD3D_SM1_OP_DEFI, 1, 1, VKD3DSIH_DEFI, {2, 1}}, + /* Control flow */ +- {VKD3D_SM1_OP_REP, 0, 1, VKD3DSIH_REP, {2, 1}, {~0u, ~0u}}, +- {VKD3D_SM1_OP_ENDREP, 0, 0, VKD3DSIH_ENDREP, {2, 1}, {~0u, ~0u}}, +- {VKD3D_SM1_OP_IF, 0, 1, VKD3DSIH_IF, {2, 1}, {~0u, ~0u}}, +- {VKD3D_SM1_OP_IFC, 0, 2, VKD3DSIH_IFC, {2, 1}, {~0u, ~0u}}, +- {VKD3D_SM1_OP_ELSE, 0, 0, VKD3DSIH_ELSE, {2, 1}, {~0u, ~0u}}, +- {VKD3D_SM1_OP_ENDIF, 0, 0, VKD3DSIH_ENDIF, {2, 1}, {~0u, ~0u}}, +- {VKD3D_SM1_OP_BREAK, 0, 0, VKD3DSIH_BREAK, {2, 1}, {~0u, ~0u}}, +- {VKD3D_SM1_OP_BREAKC, 0, 2, VKD3DSIH_BREAKC, {2, 1}, {~0u, ~0u}}, +- {VKD3D_SM1_OP_BREAKP, 0, 1, VKD3DSIH_BREAKP}, +- {VKD3D_SM1_OP_CALL, 0, 1, VKD3DSIH_CALL, {2, 1}, {~0u, ~0u}}, +- {VKD3D_SM1_OP_CALLNZ, 0, 2, VKD3DSIH_CALLNZ, {2, 1}, {~0u, ~0u}}, +- {VKD3D_SM1_OP_LOOP, 0, 2, VKD3DSIH_LOOP, {3, 0}, {~0u, ~0u}}, +- {VKD3D_SM1_OP_RET, 0, 0, VKD3DSIH_RET, {2, 1}, {~0u, ~0u}}, +- {VKD3D_SM1_OP_ENDLOOP, 0, 0, VKD3DSIH_ENDLOOP, {3, 0}, {~0u, ~0u}}, +- {VKD3D_SM1_OP_LABEL, 0, 1, VKD3DSIH_LABEL, {2, 1}, {~0u, ~0u}}, ++ {VKD3D_SM1_OP_REP, 0, 1, VKD3DSIH_REP, {2, 1}}, ++ {VKD3D_SM1_OP_ENDREP, 0, 0, VKD3DSIH_ENDREP, {2, 1}}, ++ {VKD3D_SM1_OP_IF, 0, 1, VKD3DSIH_IF, {2, 1}}, ++ {VKD3D_SM1_OP_IFC, 0, 2, VKD3DSIH_IFC, {2, 1}}, ++ {VKD3D_SM1_OP_ELSE, 0, 0, VKD3DSIH_ELSE, {2, 1}}, ++ {VKD3D_SM1_OP_ENDIF, 0, 0, VKD3DSIH_ENDIF, {2, 1}}, ++ {VKD3D_SM1_OP_BREAK, 0, 0, VKD3DSIH_BREAK, {2, 1}}, ++ {VKD3D_SM1_OP_BREAKC, 0, 2, VKD3DSIH_BREAKC, {2, 1}}, ++ {VKD3D_SM1_OP_BREAKP, 0, 1, VKD3DSIH_BREAKP, {2, 1}}, ++ {VKD3D_SM1_OP_CALL, 0, 1, VKD3DSIH_CALL, {2, 1}}, ++ {VKD3D_SM1_OP_CALLNZ, 0, 2, VKD3DSIH_CALLNZ, {2, 1}}, ++ {VKD3D_SM1_OP_LOOP, 0, 2, VKD3DSIH_LOOP, {3, 0}}, ++ {VKD3D_SM1_OP_RET, 0, 0, VKD3DSIH_RET, {2, 1}}, ++ {VKD3D_SM1_OP_ENDLOOP, 0, 0, VKD3DSIH_ENDLOOP, {3, 0}}, ++ {VKD3D_SM1_OP_LABEL, 0, 1, VKD3DSIH_LABEL, {2, 1}}, + /* Texture */ +- {VKD3D_SM1_OP_TEXCOORD, 1, 0, VKD3DSIH_TEXCOORD, {0, 0}, { 1, 3}}, +- {VKD3D_SM1_OP_TEXCOORD, 1, 1, VKD3DSIH_TEXCOORD, {1 ,4}, { 1, 4}}, +- {VKD3D_SM1_OP_TEXKILL, 1, 0, VKD3DSIH_TEXKILL, {1 ,0}, { 3, 0}}, +- {VKD3D_SM1_OP_TEX, 1, 0, VKD3DSIH_TEX, {0, 0}, { 1, 3}}, +- {VKD3D_SM1_OP_TEX, 1, 1, VKD3DSIH_TEX, {1, 4}, { 1, 4}}, +- {VKD3D_SM1_OP_TEX, 1, 2, VKD3DSIH_TEX, {2, 0}, {~0u, ~0u}}, +- {VKD3D_SM1_OP_TEXBEM, 1, 1, VKD3DSIH_TEXBEM, {0, 0}, { 1, 3}}, +- {VKD3D_SM1_OP_TEXBEML, 1, 1, VKD3DSIH_TEXBEML, {1, 0}, { 1, 3}}, +- {VKD3D_SM1_OP_TEXREG2AR, 1, 1, VKD3DSIH_TEXREG2AR, {1, 0}, { 1, 3}}, +- {VKD3D_SM1_OP_TEXREG2GB, 1, 1, VKD3DSIH_TEXREG2GB, {1, 0}, { 1, 3}}, +- {VKD3D_SM1_OP_TEXREG2RGB, 1, 1, VKD3DSIH_TEXREG2RGB, {1, 2}, { 1, 3}}, +- {VKD3D_SM1_OP_TEXM3x2PAD, 1, 1, VKD3DSIH_TEXM3x2PAD, {1, 0}, { 1, 3}}, +- {VKD3D_SM1_OP_TEXM3x2TEX, 1, 1, VKD3DSIH_TEXM3x2TEX, {1, 0}, { 1, 3}}, +- {VKD3D_SM1_OP_TEXM3x3PAD, 1, 1, VKD3DSIH_TEXM3x3PAD, {1, 0}, { 1, 3}}, +- {VKD3D_SM1_OP_TEXM3x3DIFF, 1, 1, VKD3DSIH_TEXM3x3DIFF, {0, 0}, { 0, 0}}, +- {VKD3D_SM1_OP_TEXM3x3SPEC, 1, 2, VKD3DSIH_TEXM3x3SPEC, {1, 0}, { 1, 3}}, +- {VKD3D_SM1_OP_TEXM3x3VSPEC, 1, 1, VKD3DSIH_TEXM3x3VSPEC, {1, 0}, { 1, 3}}, +- {VKD3D_SM1_OP_TEXM3x3TEX, 1, 1, VKD3DSIH_TEXM3x3TEX, {1, 0}, { 1, 3}}, +- {VKD3D_SM1_OP_TEXDP3TEX, 1, 1, VKD3DSIH_TEXDP3TEX, {1, 2}, { 1, 3}}, +- {VKD3D_SM1_OP_TEXM3x2DEPTH, 1, 1, VKD3DSIH_TEXM3x2DEPTH, {1, 3}, { 1, 3}}, +- {VKD3D_SM1_OP_TEXDP3, 1, 1, VKD3DSIH_TEXDP3, {1, 2}, { 1, 3}}, +- {VKD3D_SM1_OP_TEXM3x3, 1, 1, VKD3DSIH_TEXM3x3, {1, 2}, { 1, 3}}, +- {VKD3D_SM1_OP_TEXDEPTH, 1, 0, VKD3DSIH_TEXDEPTH, {1, 4}, { 1, 4}}, +- {VKD3D_SM1_OP_BEM, 1, 2, VKD3DSIH_BEM, {1, 4}, { 1, 4}}, +- {VKD3D_SM1_OP_DSX, 1, 1, VKD3DSIH_DSX, {2, 1}, {~0u, ~0u}}, +- {VKD3D_SM1_OP_DSY, 1, 1, VKD3DSIH_DSY, {2, 1}, {~0u, ~0u}}, +- {VKD3D_SM1_OP_TEXLDD, 1, 4, VKD3DSIH_TEXLDD, {2, 1}, {~0u, ~0u}}, +- {VKD3D_SM1_OP_SETP, 1, 2, VKD3DSIH_SETP}, +- {VKD3D_SM1_OP_TEXLDL, 1, 2, VKD3DSIH_TEXLDL, {3, 0}, {~0u, ~0u}}, +- {VKD3D_SM1_OP_PHASE, 0, 0, VKD3DSIH_PHASE}, ++ {VKD3D_SM1_OP_TEXCOORD, 1, 0, VKD3DSIH_TEXCOORD, {0, 0}, {1, 3}}, ++ {VKD3D_SM1_OP_TEXCOORD, 1, 1, VKD3DSIH_TEXCOORD, {1, 4}, {1, 4}}, ++ {VKD3D_SM1_OP_TEXKILL, 1, 0, VKD3DSIH_TEXKILL, {1, 0}}, ++ {VKD3D_SM1_OP_TEX, 1, 0, VKD3DSIH_TEX, {0, 0}, {1, 3}}, ++ {VKD3D_SM1_OP_TEX, 1, 1, VKD3DSIH_TEX, {1, 4}, {1, 4}}, ++ {VKD3D_SM1_OP_TEX, 1, 2, VKD3DSIH_TEX, {2, 0}}, ++ {VKD3D_SM1_OP_TEXBEM, 1, 1, VKD3DSIH_TEXBEM, {0, 0}, {1, 3}}, ++ {VKD3D_SM1_OP_TEXBEML, 1, 1, VKD3DSIH_TEXBEML, {1, 0}, {1, 3}}, ++ {VKD3D_SM1_OP_TEXREG2AR, 1, 1, VKD3DSIH_TEXREG2AR, {1, 0}, {1, 3}}, ++ {VKD3D_SM1_OP_TEXREG2GB, 1, 1, VKD3DSIH_TEXREG2GB, {1, 0}, {1, 3}}, ++ {VKD3D_SM1_OP_TEXREG2RGB, 1, 1, VKD3DSIH_TEXREG2RGB, {1, 2}, {1, 3}}, ++ {VKD3D_SM1_OP_TEXM3x2PAD, 1, 1, VKD3DSIH_TEXM3x2PAD, {1, 0}, {1, 3}}, ++ {VKD3D_SM1_OP_TEXM3x2TEX, 1, 1, VKD3DSIH_TEXM3x2TEX, {1, 0}, {1, 3}}, ++ {VKD3D_SM1_OP_TEXM3x3PAD, 1, 1, VKD3DSIH_TEXM3x3PAD, {1, 0}, {1, 3}}, ++ {VKD3D_SM1_OP_TEXM3x3DIFF, 1, 1, VKD3DSIH_TEXM3x3DIFF, {0, 0}, {0, 0}}, ++ {VKD3D_SM1_OP_TEXM3x3SPEC, 1, 2, VKD3DSIH_TEXM3x3SPEC, {1, 0}, {1, 3}}, ++ {VKD3D_SM1_OP_TEXM3x3VSPEC, 1, 1, VKD3DSIH_TEXM3x3VSPEC, {1, 0}, {1, 3}}, ++ {VKD3D_SM1_OP_TEXM3x3TEX, 1, 1, VKD3DSIH_TEXM3x3TEX, {1, 0}, {1, 3}}, ++ {VKD3D_SM1_OP_TEXDP3TEX, 1, 1, VKD3DSIH_TEXDP3TEX, {1, 2}, {1, 3}}, ++ {VKD3D_SM1_OP_TEXM3x2DEPTH, 1, 1, VKD3DSIH_TEXM3x2DEPTH, {1, 3}, {1, 3}}, ++ {VKD3D_SM1_OP_TEXDP3, 1, 1, VKD3DSIH_TEXDP3, {1, 2}, {1, 3}}, ++ {VKD3D_SM1_OP_TEXM3x3, 1, 1, VKD3DSIH_TEXM3x3, {1, 2}, {1, 3}}, ++ {VKD3D_SM1_OP_TEXDEPTH, 1, 0, VKD3DSIH_TEXDEPTH, {1, 4}, {1, 4}}, ++ {VKD3D_SM1_OP_BEM, 1, 2, VKD3DSIH_BEM, {1, 4}, {1, 4}}, ++ {VKD3D_SM1_OP_DSX, 1, 1, VKD3DSIH_DSX, {2, 1}}, ++ {VKD3D_SM1_OP_DSY, 1, 1, VKD3DSIH_DSY, {2, 1}}, ++ {VKD3D_SM1_OP_TEXLDD, 1, 4, VKD3DSIH_TEXLDD, {2, 1}}, ++ {VKD3D_SM1_OP_SETP, 1, 2, VKD3DSIH_SETP, {2, 1}}, ++ {VKD3D_SM1_OP_TEXLDL, 1, 2, VKD3DSIH_TEXLDL, {3, 0}}, ++ {VKD3D_SM1_OP_PHASE, 0, 0, VKD3DSIH_PHASE, {1, 4}, {1, 4}}, + {0, 0, 0, VKD3DSIH_INVALID}, + }; + +diff --git a/libs/vkd3d/libs/vkd3d-shader/glsl.c b/libs/vkd3d/libs/vkd3d-shader/glsl.c +index 0df0e30f399..113c7eee65f 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/glsl.c ++++ b/libs/vkd3d/libs/vkd3d-shader/glsl.c +@@ -1507,13 +1507,6 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen, + case VKD3DSIH_DCL_INDEXABLE_TEMP: + shader_glsl_dcl_indexable_temp(gen, ins); + break; +- case VKD3DSIH_DCL_INPUT: +- case VKD3DSIH_DCL_INPUT_PS: +- case VKD3DSIH_DCL_INPUT_PS_SGV: +- case VKD3DSIH_DCL_INPUT_PS_SIV: +- case VKD3DSIH_DCL_INPUT_SGV: +- case VKD3DSIH_DCL_OUTPUT: +- case VKD3DSIH_DCL_OUTPUT_SIV: + case VKD3DSIH_NOP: + break; + case VKD3DSIH_DEFAULT: +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c +index 97c6c0a1377..f0d24b835e5 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c +@@ -2700,10 +2700,8 @@ struct hlsl_ir_function_decl *hlsl_get_func_decl(struct hlsl_ctx *ctx, const cha + return NULL; + } + +-struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const struct hlsl_type *type) ++static void hlsl_dump_type(struct vkd3d_string_buffer *buffer, const struct hlsl_type *type) + { +- struct vkd3d_string_buffer *string, *inner_string; +- + static const char *const base_types[] = + { + [HLSL_TYPE_FLOAT] = "float", +@@ -2727,31 +2725,28 @@ struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const stru + [HLSL_SAMPLER_DIM_CUBEARRAY] = "CubeArray", + }; + +- if (!(string = hlsl_get_string_buffer(ctx))) +- return NULL; +- + if (type->name) + { +- vkd3d_string_buffer_printf(string, "%s", type->name); +- return string; ++ vkd3d_string_buffer_printf(buffer, "%s", type->name); ++ return; + } + + switch (type->class) + { + case HLSL_CLASS_SCALAR: + VKD3D_ASSERT(type->e.numeric.type < ARRAY_SIZE(base_types)); +- vkd3d_string_buffer_printf(string, "%s", base_types[type->e.numeric.type]); +- return string; ++ vkd3d_string_buffer_printf(buffer, "%s", base_types[type->e.numeric.type]); ++ return; + + case HLSL_CLASS_VECTOR: + VKD3D_ASSERT(type->e.numeric.type < ARRAY_SIZE(base_types)); +- vkd3d_string_buffer_printf(string, "%s%u", base_types[type->e.numeric.type], type->dimx); +- return string; ++ vkd3d_string_buffer_printf(buffer, "%s%u", base_types[type->e.numeric.type], type->dimx); ++ return; + + case HLSL_CLASS_MATRIX: + VKD3D_ASSERT(type->e.numeric.type < ARRAY_SIZE(base_types)); +- vkd3d_string_buffer_printf(string, "%s%ux%u", base_types[type->e.numeric.type], type->dimy, type->dimx); +- return string; ++ vkd3d_string_buffer_printf(buffer, "%s%ux%u", base_types[type->e.numeric.type], type->dimy, type->dimx); ++ return; + + case HLSL_CLASS_ARRAY: + { +@@ -2760,102 +2755,85 @@ struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const stru + for (t = type; t->class == HLSL_CLASS_ARRAY; t = t->e.array.type) + ; + +- if ((inner_string = hlsl_type_to_string(ctx, t))) +- { +- vkd3d_string_buffer_printf(string, "%s", inner_string->buffer); +- hlsl_release_string_buffer(ctx, inner_string); +- } +- ++ hlsl_dump_type(buffer, t); + for (t = type; t->class == HLSL_CLASS_ARRAY; t = t->e.array.type) + { + if (t->e.array.elements_count == HLSL_ARRAY_ELEMENTS_COUNT_IMPLICIT) +- vkd3d_string_buffer_printf(string, "[]"); ++ vkd3d_string_buffer_printf(buffer, "[]"); + else +- vkd3d_string_buffer_printf(string, "[%u]", t->e.array.elements_count); ++ vkd3d_string_buffer_printf(buffer, "[%u]", t->e.array.elements_count); + } +- return string; ++ return; + } + + case HLSL_CLASS_STRUCT: +- vkd3d_string_buffer_printf(string, ""); +- return string; ++ vkd3d_string_buffer_printf(buffer, ""); ++ return; + + case HLSL_CLASS_TEXTURE: + if (type->sampler_dim == HLSL_SAMPLER_DIM_RAW_BUFFER) + { +- vkd3d_string_buffer_printf(string, "ByteAddressBuffer"); +- return string; ++ vkd3d_string_buffer_printf(buffer, "ByteAddressBuffer"); ++ return; + } + + if (type->sampler_dim == HLSL_SAMPLER_DIM_GENERIC) + { +- vkd3d_string_buffer_printf(string, "Texture"); +- return string; ++ vkd3d_string_buffer_printf(buffer, "Texture"); ++ return; + } + + VKD3D_ASSERT(hlsl_is_numeric_type(type->e.resource.format)); + VKD3D_ASSERT(type->e.resource.format->e.numeric.type < ARRAY_SIZE(base_types)); + if (type->sampler_dim == HLSL_SAMPLER_DIM_BUFFER) + { +- vkd3d_string_buffer_printf(string, "Buffer"); ++ vkd3d_string_buffer_printf(buffer, "Buffer<"); + } + else + { + VKD3D_ASSERT(type->sampler_dim < ARRAY_SIZE(dimensions)); +- vkd3d_string_buffer_printf(string, "Texture%s", dimensions[type->sampler_dim]); +- } +- if ((inner_string = hlsl_type_to_string(ctx, type->e.resource.format))) +- { +- vkd3d_string_buffer_printf(string, "<%s>", inner_string->buffer); +- hlsl_release_string_buffer(ctx, inner_string); ++ vkd3d_string_buffer_printf(buffer, "Texture%s<", dimensions[type->sampler_dim]); + } +- return string; ++ hlsl_dump_type(buffer, type->e.resource.format); ++ vkd3d_string_buffer_printf(buffer, ">"); ++ return; + + case HLSL_CLASS_UAV: + if (type->sampler_dim == HLSL_SAMPLER_DIM_RAW_BUFFER) + { +- vkd3d_string_buffer_printf(string, "RWByteAddressBuffer"); +- return string; ++ vkd3d_string_buffer_printf(buffer, "RWByteAddressBuffer"); ++ return; + } + if (type->sampler_dim == HLSL_SAMPLER_DIM_BUFFER) +- vkd3d_string_buffer_printf(string, "RWBuffer"); ++ vkd3d_string_buffer_printf(buffer, "RWBuffer<"); + else if (type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) +- vkd3d_string_buffer_printf(string, "RWStructuredBuffer"); ++ vkd3d_string_buffer_printf(buffer, "RWStructuredBuffer<"); + else +- vkd3d_string_buffer_printf(string, "RWTexture%s", dimensions[type->sampler_dim]); +- if ((inner_string = hlsl_type_to_string(ctx, type->e.resource.format))) +- { +- vkd3d_string_buffer_printf(string, "<%s>", inner_string->buffer); +- hlsl_release_string_buffer(ctx, inner_string); +- } +- return string; ++ vkd3d_string_buffer_printf(buffer, "RWTexture%s<", dimensions[type->sampler_dim]); ++ hlsl_dump_type(buffer, type->e.resource.format); ++ vkd3d_string_buffer_printf(buffer, ">"); ++ return; + + case HLSL_CLASS_CONSTANT_BUFFER: +- vkd3d_string_buffer_printf(string, "ConstantBuffer"); +- if ((inner_string = hlsl_type_to_string(ctx, type->e.resource.format))) +- { +- vkd3d_string_buffer_printf(string, "<%s>", inner_string->buffer); +- hlsl_release_string_buffer(ctx, inner_string); +- } +- return string; ++ vkd3d_string_buffer_printf(buffer, "ConstantBuffer<"); ++ hlsl_dump_type(buffer, type->e.resource.format); ++ vkd3d_string_buffer_printf(buffer, ">"); ++ return; + + case HLSL_CLASS_ERROR: +- vkd3d_string_buffer_printf(string, ""); +- return string; ++ vkd3d_string_buffer_printf(buffer, ""); ++ return; + + case HLSL_CLASS_STREAM_OUTPUT: + if (type->e.so.so_type == HLSL_STREAM_OUTPUT_POINT_STREAM) +- vkd3d_string_buffer_printf(string, "PointStream"); ++ vkd3d_string_buffer_printf(buffer, "PointStream<"); + else if (type->e.so.so_type == HLSL_STREAM_OUTPUT_LINE_STREAM) +- vkd3d_string_buffer_printf(string, "LineStream"); ++ vkd3d_string_buffer_printf(buffer, "LineStream<"); + else +- vkd3d_string_buffer_printf(string, "TriangleStream"); +- if ((inner_string = hlsl_type_to_string(ctx, type->e.so.type))) +- { +- vkd3d_string_buffer_printf(string, "<%s>", inner_string->buffer); +- hlsl_release_string_buffer(ctx, inner_string); +- } +- return string; ++ vkd3d_string_buffer_printf(buffer, "TriangleStream<"); ++ hlsl_dump_type(buffer, type->e.so.type); ++ vkd3d_string_buffer_printf(buffer, ">"); ++ return; + + case HLSL_CLASS_DEPTH_STENCIL_STATE: + case HLSL_CLASS_DEPTH_STENCIL_VIEW: +@@ -2878,8 +2856,17 @@ struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const stru + break; + } + +- vkd3d_string_buffer_printf(string, ""); +- return string; ++ vkd3d_string_buffer_printf(buffer, ""); ++} ++ ++struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const struct hlsl_type *type) ++{ ++ struct vkd3d_string_buffer *buffer; ++ ++ if (!(buffer = hlsl_get_string_buffer(ctx))) ++ return NULL; ++ hlsl_dump_type(buffer, type); ++ return buffer; + } + + struct vkd3d_string_buffer *hlsl_component_to_string(struct hlsl_ctx *ctx, const struct hlsl_ir_var *var, +@@ -3042,7 +3029,8 @@ static void dump_ir_var(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer + vkd3d_string_buffer_printf(buffer, "%s ", string->buffer); + hlsl_release_string_buffer(ctx, string); + } +- vkd3d_string_buffer_printf(buffer, "%s %s", debug_hlsl_type(ctx, var->data_type), var->name); ++ hlsl_dump_type(buffer, var->data_type); ++ vkd3d_string_buffer_printf(buffer, " %s", var->name); + if (var->semantic.name) + vkd3d_string_buffer_printf(buffer, " : %s%u", var->semantic.name, var->semantic.index); + } +@@ -3123,34 +3111,28 @@ const char *debug_hlsl_swizzle(uint32_t swizzle, unsigned int size) + return vkd3d_dbg_sprintf(".%s", string); + } + +-static void dump_ir_call(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer, const struct hlsl_ir_call *call) ++void hlsl_dump_ir_function_decl(struct hlsl_ctx *ctx, ++ struct vkd3d_string_buffer *buffer, const struct hlsl_ir_function_decl *f) + { +- const struct hlsl_ir_function_decl *decl = call->decl; +- struct vkd3d_string_buffer *string; + size_t i; + +- if (!(string = hlsl_type_to_string(ctx, decl->return_type))) +- return; +- +- vkd3d_string_buffer_printf(buffer, "call %s %s(", string->buffer, decl->func->name); +- hlsl_release_string_buffer(ctx, string); +- +- for (i = 0; i < decl->parameters.count; ++i) ++ hlsl_dump_type(buffer, f->return_type); ++ vkd3d_string_buffer_printf(buffer, " %s(", f->func->name); ++ for (i = 0; i < f->parameters.count; ++i) + { +- const struct hlsl_ir_var *param = decl->parameters.vars[i]; +- +- if (!(string = hlsl_type_to_string(ctx, param->data_type))) +- return; +- + if (i) + vkd3d_string_buffer_printf(buffer, ", "); +- vkd3d_string_buffer_printf(buffer, "%s", string->buffer); +- +- hlsl_release_string_buffer(ctx, string); ++ dump_ir_var(ctx, buffer, f->parameters.vars[i]); + } + vkd3d_string_buffer_printf(buffer, ")"); + } + ++static void dump_ir_call(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer, const struct hlsl_ir_call *call) ++{ ++ vkd3d_string_buffer_printf(buffer, "call "); ++ hlsl_dump_ir_function_decl(ctx, buffer, call->decl); ++} ++ + static void dump_ir_constant(struct vkd3d_string_buffer *buffer, const struct hlsl_ir_constant *constant) + { + struct hlsl_type *type = constant->node.data_type; +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h +index 25d1b8df947..addc98d5a43 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h +@@ -1437,6 +1437,8 @@ 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); + + void hlsl_dump_function(struct hlsl_ctx *ctx, const struct hlsl_ir_function_decl *func); ++void hlsl_dump_ir_function_decl(struct hlsl_ctx *ctx, ++ struct vkd3d_string_buffer *buffer, const struct hlsl_ir_function_decl *f); + void hlsl_dump_var_default_values(const struct hlsl_ir_var *var); + + bool hlsl_state_block_add_entry(struct hlsl_state_block *state_block, +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y +index 5bcd5e9034b..afa41f4b1c2 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y +@@ -475,7 +475,11 @@ static bool add_explicit_conversion(struct hlsl_ctx *ctx, struct hlsl_block *blo + for (i = 0; i < arrays->count; ++i) + { + if (arrays->sizes[i] == HLSL_ARRAY_ELEMENTS_COUNT_IMPLICIT) ++ { + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Implicit size arrays not allowed in casts."); ++ dst_type = ctx->builtin_types.error; ++ break; ++ } + dst_type = hlsl_new_array_type(ctx, dst_type, arrays->sizes[i]); + } + +@@ -1190,6 +1194,8 @@ static bool gen_struct_fields(struct hlsl_ctx *ctx, struct parse_fields *fields, + { + hlsl_error(ctx, &v->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Implicit size arrays not allowed in struct fields."); ++ field->type = ctx->builtin_types.error; ++ break; + } + + field->type = hlsl_new_array_type(ctx, field->type, v->arrays.sizes[k]); +@@ -1280,6 +1286,12 @@ static bool add_typedef(struct hlsl_ctx *ctx, struct hlsl_type *const orig_type, + { + hlsl_error(ctx, &v->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Implicit size arrays not allowed in typedefs."); ++ if (!(type = hlsl_type_clone(ctx, ctx->builtin_types.error, 0, 0))) ++ { ++ free_parse_variable_def(v); ++ ret = false; ++ } ++ break; + } + + if (!(type = hlsl_new_array_type(ctx, type, v->arrays.sizes[i]))) +@@ -2668,26 +2680,30 @@ static void declare_var(struct hlsl_ctx *ctx, struct parse_variable_def *v) + { + hlsl_error(ctx, &v->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Only innermost array size can be implicit."); +- v->initializer.args_count = 0; ++ type = ctx->builtin_types.error; ++ break; + } + else if (elem_components == 0) + { + hlsl_error(ctx, &v->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Cannot declare an implicit size array of a size 0 type."); +- v->initializer.args_count = 0; ++ type = ctx->builtin_types.error; ++ break; + } + else if (size == 0) + { + hlsl_error(ctx, &v->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Implicit size arrays need to be initialized."); +- v->initializer.args_count = 0; ++ type = ctx->builtin_types.error; ++ break; + } + else if (size % elem_components != 0) + { + hlsl_error(ctx, &v->loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, + "Cannot initialize implicit size array with %u components, expected a multiple of %u.", + size, elem_components); +- v->initializer.args_count = 0; ++ type = ctx->builtin_types.error; ++ break; + } + else + { +@@ -2906,7 +2922,8 @@ static struct hlsl_block *initialize_vars(struct hlsl_ctx *ctx, struct list *var + v->initializer.args[0] = node_from_block(v->initializer.instrs); + } + +- initialize_var(ctx, var, &v->initializer, is_default_values_initializer); ++ if (var->data_type->class != HLSL_CLASS_ERROR) ++ initialize_var(ctx, var, &v->initializer, is_default_values_initializer); + + if (is_default_values_initializer) + { +@@ -2995,9 +3012,16 @@ static struct hlsl_ir_function_decl *find_function_call(struct hlsl_ctx *ctx, + const char *name, const struct parse_initializer *args, bool is_compile, + const struct vkd3d_shader_location *loc) + { +- struct hlsl_ir_function_decl *decl, *compatible_match = NULL; ++ struct hlsl_ir_function_decl *decl; ++ struct vkd3d_string_buffer *s; + struct hlsl_ir_function *func; + struct rb_entry *entry; ++ size_t i; ++ struct ++ { ++ struct hlsl_ir_function_decl **candidates; ++ size_t count, capacity; ++ } candidates = {0}; + + if (!(entry = rb_get(&ctx->functions, name))) + return NULL; +@@ -3005,18 +3029,41 @@ static struct hlsl_ir_function_decl *find_function_call(struct hlsl_ctx *ctx, + + LIST_FOR_EACH_ENTRY(decl, &func->overloads, struct hlsl_ir_function_decl, entry) + { +- if (func_is_compatible_match(ctx, decl, is_compile, args)) ++ if (!func_is_compatible_match(ctx, decl, is_compile, args)) ++ continue; ++ ++ if (!(hlsl_array_reserve(ctx, (void **)&candidates.candidates, ++ &candidates.capacity, candidates.count + 1, sizeof(decl)))) ++ { ++ vkd3d_free(candidates.candidates); ++ return NULL; ++ } ++ candidates.candidates[candidates.count++] = decl; ++ } ++ ++ if (!candidates.count) ++ return NULL; ++ ++ if (candidates.count > 1) ++ { ++ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_AMBIGUOUS_CALL, "Ambiguous function call."); ++ if ((s = hlsl_get_string_buffer(ctx))) + { +- if (compatible_match) ++ hlsl_note(ctx, loc, VKD3D_SHADER_LOG_ERROR, "Candidates are:"); ++ for (i = 0; i < candidates.count; ++i) + { +- hlsl_fixme(ctx, loc, "Prioritize between multiple compatible function overloads."); +- break; ++ hlsl_dump_ir_function_decl(ctx, s, candidates.candidates[i]); ++ hlsl_note(ctx, loc, VKD3D_SHADER_LOG_ERROR, " %s;", s->buffer); ++ vkd3d_string_buffer_clear(s); + } +- compatible_match = decl; ++ hlsl_release_string_buffer(ctx, s); + } + } + +- return compatible_match; ++ decl = candidates.candidates[0]; ++ vkd3d_free(candidates.candidates); ++ ++ return decl; + } + + static struct hlsl_ir_node *hlsl_new_void_expr(struct hlsl_ctx *ctx, const struct vkd3d_shader_location *loc) +@@ -5445,6 +5492,17 @@ static struct hlsl_block *add_constructor(struct hlsl_ctx *ctx, struct hlsl_type + struct hlsl_ir_load *load; + struct hlsl_ir_var *var; + ++ if (!hlsl_is_numeric_type(type)) ++ { ++ struct vkd3d_string_buffer *string; ++ ++ if ((string = hlsl_type_to_string(ctx, type))) ++ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, ++ "Constructor data type %s is not numeric.", string->buffer); ++ hlsl_release_string_buffer(ctx, string); ++ return NULL; ++ } ++ + if (!(var = hlsl_new_synthetic_var(ctx, "constructor", type, loc))) + return NULL; + +@@ -7688,7 +7746,10 @@ parameter_decl: + { + hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Implicit size arrays not allowed in function parameters."); ++ type = ctx->builtin_types.error; ++ break; + } ++ + type = hlsl_new_array_type(ctx, type, $4.sizes[i]); + } + vkd3d_free($4.sizes); +@@ -8110,14 +8171,9 @@ typedef: + } + + if (modifiers) +- { + hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, + "Storage modifiers are not allowed on typedefs."); +- LIST_FOR_EACH_ENTRY_SAFE(v, v_next, $4, struct parse_variable_def, entry) +- vkd3d_free(v); +- vkd3d_free($4); +- YYABORT; +- } ++ + if (!add_typedef(ctx, type, $4)) + YYABORT; + } +@@ -9001,17 +9057,24 @@ primary_expr: + struct hlsl_ir_load *load; + struct hlsl_ir_var *var; + +- if (!(var = hlsl_get_var(ctx->cur_scope, $1))) ++ if ((var = hlsl_get_var(ctx->cur_scope, $1))) ++ { ++ vkd3d_free($1); ++ ++ if (!(load = hlsl_new_var_load(ctx, var, &@1))) ++ YYABORT; ++ if (!($$ = make_block(ctx, &load->node))) ++ YYABORT; ++ } ++ else + { + hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, "Variable \"%s\" is not defined.", $1); + vkd3d_free($1); +- YYABORT; ++ ++ if (!($$ = make_empty_block(ctx))) ++ YYABORT; ++ $$->value = ctx->error_instr; + } +- vkd3d_free($1); +- if (!(load = hlsl_new_var_load(ctx, var, &@1))) +- YYABORT; +- if (!($$ = make_block(ctx, &load->node))) +- YYABORT; + } + | '(' expr ')' + { +@@ -9171,23 +9234,8 @@ postfix_expr: + | var_modifiers type '(' initializer_expr_list ')' + { + if ($1) +- { + hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, + "Modifiers are not allowed on constructors."); +- free_parse_initializer(&$4); +- YYABORT; +- } +- if (!hlsl_is_numeric_type($2)) +- { +- struct vkd3d_string_buffer *string; +- +- if ((string = hlsl_type_to_string(ctx, $2))) +- hlsl_error(ctx, &@2, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, +- "Constructor data type %s is not numeric.", string->buffer); +- hlsl_release_string_buffer(ctx, string); +- free_parse_initializer(&$4); +- YYABORT; +- } + + if (!($$ = add_constructor(ctx, $2, &$4, &@2))) + { +@@ -9255,11 +9303,8 @@ unary_expr: + | '(' var_modifiers type arrays ')' unary_expr + { + if ($2) +- { + hlsl_error(ctx, &@2, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, + "Modifiers are not allowed on casts."); +- YYABORT; +- } + + if (!add_explicit_conversion(ctx, $6, $3, &$4, &@3)) + { +@@ -9403,10 +9448,7 @@ assignment_expr: + struct hlsl_ir_node *lhs = node_from_block($1), *rhs = node_from_block($3); + + if (lhs->data_type->modifiers & HLSL_MODIFIER_CONST) +- { + hlsl_error(ctx, &@2, VKD3D_SHADER_ERROR_HLSL_MODIFIES_CONST, "Statement modifies a const expression."); +- YYABORT; +- } + hlsl_block_add_block($3, $1); + destroy_block($1); + if (!add_assignment(ctx, $3, lhs, $2, rhs)) +diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c +index 53b26dac76e..64c9585af52 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/ir.c ++++ b/libs/vkd3d/libs/vkd3d-shader/ir.c +@@ -750,6 +750,76 @@ static enum vkd3d_result vsir_program_lower_texldd(struct vsir_program *program, + return VKD3D_OK; + } + ++static enum vkd3d_result vsir_program_lower_dcl_input(struct vsir_program *program, ++ struct vkd3d_shader_instruction *ins, struct vsir_transformation_context *ctx) ++{ ++ switch (ins->declaration.dst.reg.type) ++ { ++ case VKD3DSPR_INPUT: ++ case VKD3DSPR_OUTPUT: ++ case VKD3DSPR_PATCHCONST: ++ case VKD3DSPR_INCONTROLPOINT: ++ case VKD3DSPR_OUTCONTROLPOINT: ++ break; ++ ++ case VKD3DSPR_PRIMID: ++ case VKD3DSPR_FORKINSTID: ++ case VKD3DSPR_JOININSTID: ++ case VKD3DSPR_THREADID: ++ case VKD3DSPR_THREADGROUPID: ++ case VKD3DSPR_LOCALTHREADID: ++ case VKD3DSPR_LOCALTHREADINDEX: ++ case VKD3DSPR_COVERAGE: ++ case VKD3DSPR_TESSCOORD: ++ case VKD3DSPR_OUTPOINTID: ++ case VKD3DSPR_GSINSTID: ++ case VKD3DSPR_WAVELANECOUNT: ++ case VKD3DSPR_WAVELANEINDEX: ++ bitmap_set(program->io_dcls, ins->declaration.dst.reg.type); ++ break; ++ ++ default: ++ vkd3d_shader_error(ctx->message_context, &ins->location, ++ VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE, ++ "Internal compiler error: invalid register type %#x for DCL_INPUT.", ++ ins->declaration.dst.reg.type); ++ return VKD3D_ERROR; ++ } ++ ++ return VKD3D_OK; ++} ++ ++static enum vkd3d_result vsir_program_lower_dcl_output(struct vsir_program *program, ++ struct vkd3d_shader_instruction *ins, struct vsir_transformation_context *ctx) ++{ ++ switch (ins->declaration.dst.reg.type) ++ { ++ case VKD3DSPR_INPUT: ++ case VKD3DSPR_OUTPUT: ++ case VKD3DSPR_PATCHCONST: ++ case VKD3DSPR_INCONTROLPOINT: ++ case VKD3DSPR_OUTCONTROLPOINT: ++ break; ++ ++ case VKD3DSPR_DEPTHOUT: ++ case VKD3DSPR_SAMPLEMASK: ++ case VKD3DSPR_DEPTHOUTGE: ++ case VKD3DSPR_DEPTHOUTLE: ++ case VKD3DSPR_OUTSTENCILREF: ++ bitmap_set(program->io_dcls, ins->declaration.dst.reg.type); ++ break; ++ ++ default: ++ vkd3d_shader_error(ctx->message_context, &ins->location, ++ VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE, ++ "Internal compiler error: invalid register type %#x for DCL_OUTPUT.", ++ ins->declaration.dst.reg.type); ++ return VKD3D_ERROR; ++ } ++ ++ return VKD3D_OK; ++} ++ + static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *program, + struct vsir_transformation_context *ctx) + { +@@ -790,6 +860,25 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr + vkd3d_shader_instruction_make_nop(ins); + break; + ++ case VKD3DSIH_DCL_INPUT: ++ vsir_program_lower_dcl_input(program, ins, ctx); ++ vkd3d_shader_instruction_make_nop(ins); ++ break; ++ ++ case VKD3DSIH_DCL_OUTPUT: ++ vsir_program_lower_dcl_output(program, ins, ctx); ++ vkd3d_shader_instruction_make_nop(ins); ++ break; ++ ++ case VKD3DSIH_DCL_INPUT_SGV: ++ case VKD3DSIH_DCL_INPUT_SIV: ++ case VKD3DSIH_DCL_INPUT_PS: ++ case VKD3DSIH_DCL_INPUT_PS_SGV: ++ case VKD3DSIH_DCL_INPUT_PS_SIV: ++ case VKD3DSIH_DCL_OUTPUT_SIV: ++ vkd3d_shader_instruction_make_nop(ins); ++ break; ++ + case VKD3DSIH_SINCOS: + if ((ret = vsir_program_lower_sm1_sincos(program, ins)) < 0) + return ret; +@@ -1271,12 +1360,6 @@ static void flattener_eliminate_phase_related_dcls(struct hull_flattener *normal + vkd3d_shader_instruction_make_nop(ins); + return; + } +- else if (ins->opcode == VKD3DSIH_DCL_INPUT && shader_register_is_phase_instance_id( +- &ins->declaration.dst.reg)) +- { +- vkd3d_shader_instruction_make_nop(ins); +- return; +- } + + if (normaliser->phase == VKD3DSIH_INVALID || vsir_instruction_is_dcl(ins)) + return; +@@ -1433,11 +1516,10 @@ static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_p + { + struct vkd3d_shader_instruction *ins; + const struct signature_element *e; +- unsigned int i, count, stride = 0; ++ unsigned int i, count = 2; + + for (i = 0; i < s->element_count; ++i) +- stride += !!s->elements[i].used_mask; +- count = 2 + 3 * stride; ++ count += !!s->elements[i].used_mask; + + if (!shader_instruction_array_reserve(&normaliser->instructions, normaliser->instructions.count + count)) + return VKD3D_ERROR_OUT_OF_MEMORY; +@@ -1449,78 +1531,43 @@ static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_p + ins = &normaliser->instructions.elements[dst]; + vsir_instruction_init(ins, location, VKD3DSIH_HS_CONTROL_POINT_PHASE); + +- ins = &normaliser->instructions.elements[dst + 1 + 3 * stride]; +- vsir_instruction_init(ins, location, VKD3DSIH_RET); +- +- ins = &normaliser->instructions.elements[dst + 1]; ++ ++ins; + + for (i = 0; i < s->element_count; ++i) + { +- struct vkd3d_shader_instruction *ins_in, *ins_out, *ins_mov; +- struct vkd3d_shader_dst_param *param_in, *param_out; +- + e = &s->elements[i]; + if (!e->used_mask) + continue; + +- ins_in = ins; +- ins_out = &ins[stride]; +- ins_mov = &ins[2 * stride]; +- +- if (e->sysval_semantic != VKD3D_SHADER_SV_NONE) +- { +- vsir_instruction_init(ins_in, location, VKD3DSIH_DCL_INPUT_SIV); +- param_in = &ins_in->declaration.register_semantic.reg; +- ins_in->declaration.register_semantic.sysval_semantic = vkd3d_siv_from_sysval(e->sysval_semantic); +- +- vsir_instruction_init(ins_out, location, VKD3DSIH_DCL_OUTPUT_SIV); +- param_out = &ins_out->declaration.register_semantic.reg; +- ins_out->declaration.register_semantic.sysval_semantic = vkd3d_siv_from_sysval(e->sysval_semantic); +- } +- else +- { +- vsir_instruction_init(ins_in, location, VKD3DSIH_DCL_INPUT); +- param_in = &ins_in->declaration.dst; +- +- vsir_instruction_init(ins_out, location, VKD3DSIH_DCL_OUTPUT); +- param_out = &ins_out->declaration.dst; +- } +- +- vsir_dst_param_init_io(param_in, VKD3DSPR_INPUT, e, 2); +- param_in->reg.idx[0].offset = input_control_point_count; +- param_in->reg.idx[1].offset = e->register_index; +- param_in->write_mask = e->mask; +- +- vsir_dst_param_init_io(param_out, VKD3DSPR_OUTPUT, e, 2); +- param_out->reg.idx[0].offset = input_control_point_count; +- param_out->reg.idx[1].offset = e->register_index; +- param_out->write_mask = e->mask; +- +- vsir_instruction_init(ins_mov, location, VKD3DSIH_MOV); +- ins_mov->dst = shader_dst_param_allocator_get(&normaliser->instructions.dst_params, 1); +- ins_mov->dst_count = 1; +- ins_mov->src = shader_src_param_allocator_get(&normaliser->instructions.src_params, 1); +- ins_mov->src_count = 1; ++ vsir_instruction_init(ins, location, VKD3DSIH_MOV); ++ ins->dst = shader_dst_param_allocator_get(&normaliser->instructions.dst_params, 1); ++ ins->dst_count = 1; ++ ins->src = shader_src_param_allocator_get(&normaliser->instructions.src_params, 1); ++ ins->src_count = 1; + +- if (!ins_mov->dst || ! ins_mov->src) ++ if (!ins->dst || ! ins->src) + { + WARN("Failed to allocate dst/src param.\n"); + return VKD3D_ERROR_OUT_OF_MEMORY; + } + +- vsir_dst_param_init_io(&ins_mov->dst[0], VKD3DSPR_OUTPUT, e, 2); +- ins_mov->dst[0].reg.idx[0].offset = 0; +- ins_mov->dst[0].reg.idx[0].rel_addr = normaliser->outpointid_param; +- ins_mov->dst[0].reg.idx[1].offset = e->register_index; ++ vsir_dst_param_init_io(&ins->dst[0], VKD3DSPR_OUTPUT, e, 2); ++ ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; ++ ins->dst[0].reg.idx[0].offset = 0; ++ ins->dst[0].reg.idx[0].rel_addr = normaliser->outpointid_param; ++ ins->dst[0].reg.idx[1].offset = e->register_index; + +- vsir_src_param_init_io(&ins_mov->src[0], VKD3DSPR_INPUT, e, 2); +- ins_mov->src[0].reg.idx[0].offset = 0; +- ins_mov->src[0].reg.idx[0].rel_addr = normaliser->outpointid_param; +- ins_mov->src[0].reg.idx[1].offset = e->register_index; ++ vsir_src_param_init_io(&ins->src[0], VKD3DSPR_INPUT, e, 2); ++ ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4; ++ ins->src[0].reg.idx[0].offset = 0; ++ ins->src[0].reg.idx[0].rel_addr = normaliser->outpointid_param; ++ ins->src[0].reg.idx[1].offset = e->register_index; + + ++ins; + } + ++ vsir_instruction_init(ins, location, VKD3DSIH_RET); ++ + return VKD3D_OK; + } + +@@ -2042,12 +2089,11 @@ static unsigned int shader_register_normalise_arrayed_addressing(struct vkd3d_sh + return id_idx; + } + +-static bool shader_dst_param_io_normalise(struct vkd3d_shader_dst_param *dst_param, bool is_io_dcl, ++static bool shader_dst_param_io_normalise(struct vkd3d_shader_dst_param *dst_param, + struct io_normaliser *normaliser) + { + unsigned int id_idx, reg_idx, write_mask, element_idx; + struct vkd3d_shader_register *reg = &dst_param->reg; +- struct vkd3d_shader_dst_param **dcl_params; + const struct shader_signature *signature; + const struct signature_element *e; + +@@ -2063,26 +2109,22 @@ static bool shader_dst_param_io_normalise(struct vkd3d_shader_dst_param *dst_par + /* Convert patch constant outputs to the patch constant register type to avoid the need + * to convert compiler symbols when accessed as inputs in a later stage. */ + reg->type = VKD3DSPR_PATCHCONST; +- dcl_params = normaliser->pc_dcl_params; + } + else + { + signature = normaliser->output_signature; +- dcl_params = normaliser->output_dcl_params; + } + break; + + case VKD3DSPR_PATCHCONST: + reg_idx = reg->idx[reg->idx_count - 1].offset; + signature = normaliser->patch_constant_signature; +- dcl_params = normaliser->pc_dcl_params; + break; + + case VKD3DSPR_COLOROUT: + reg_idx = reg->idx[0].offset; + signature = normaliser->output_signature; + reg->type = VKD3DSPR_OUTPUT; +- dcl_params = normaliser->output_dcl_params; + break; + + case VKD3DSPR_INCONTROLPOINT: +@@ -2090,14 +2132,12 @@ static bool shader_dst_param_io_normalise(struct vkd3d_shader_dst_param *dst_par + reg_idx = reg->idx[reg->idx_count - 1].offset; + signature = normaliser->input_signature; + reg->type = VKD3DSPR_INPUT; +- dcl_params = normaliser->input_dcl_params; + break; + + case VKD3DSPR_ATTROUT: + reg_idx = SM1_COLOR_REGISTER_OFFSET + reg->idx[0].offset; + signature = normaliser->output_signature; + reg->type = VKD3DSPR_OUTPUT; +- dcl_params = normaliser->output_dcl_params; + break; + + case VKD3DSPR_RASTOUT: +@@ -2107,7 +2147,6 @@ static bool shader_dst_param_io_normalise(struct vkd3d_shader_dst_param *dst_par + reg_idx = SM1_RASTOUT_REGISTER_OFFSET + reg->idx[0].offset; + signature = normaliser->output_signature; + reg->type = VKD3DSPR_OUTPUT; +- dcl_params = normaliser->output_dcl_params; + /* Fog and point size are scalar, but fxc/d3dcompiler emits a full + * write mask when writing to them. */ + if (reg->idx[0].offset > 0) +@@ -2123,54 +2162,15 @@ static bool shader_dst_param_io_normalise(struct vkd3d_shader_dst_param *dst_par + vkd3d_unreachable(); + e = &signature->elements[element_idx]; + +- if (is_io_dcl) +- { +- /* Validated in the TPF reader. */ +- VKD3D_ASSERT(element_idx < ARRAY_SIZE(normaliser->input_dcl_params)); +- +- if (dcl_params[element_idx]) +- { +- /* Merge split declarations into a single one. */ +- dcl_params[element_idx]->write_mask |= dst_param->write_mask; +- /* Turn this into a nop. */ +- return false; +- } +- else +- { +- dcl_params[element_idx] = dst_param; +- } +- } +- + if (io_normaliser_is_in_control_point_phase(normaliser) && reg->type == VKD3DSPR_OUTPUT) + { +- if (is_io_dcl) +- { +- /* Emit an array size for the control points for consistency with inputs. */ +- reg->idx[0].offset = normaliser->output_control_point_count; +- } +- else +- { +- /* The control point id param. */ +- VKD3D_ASSERT(reg->idx[0].rel_addr); +- } ++ /* The control point id param. */ ++ VKD3D_ASSERT(reg->idx[0].rel_addr); + id_idx = 1; + } + + if ((e->register_count > 1 || vsir_sysval_semantic_is_tess_factor(e->sysval_semantic))) +- { +- if (is_io_dcl) +- { +- /* For control point I/O, idx 0 contains the control point count. +- * Ensure it is moved up to the next slot. */ +- reg->idx[id_idx].offset = reg->idx[0].offset; +- reg->idx[0].offset = e->register_count; +- ++id_idx; +- } +- else +- { +- id_idx = shader_register_normalise_arrayed_addressing(reg, id_idx, e->register_index); +- } +- } ++ id_idx = shader_register_normalise_arrayed_addressing(reg, id_idx, e->register_index); + + /* Replace the register index with the signature element index */ + reg->idx[id_idx].offset = element_idx; +@@ -2264,37 +2264,10 @@ static void shader_src_param_io_normalise(struct vkd3d_shader_src_param *src_par + static void shader_instruction_normalise_io_params(struct vkd3d_shader_instruction *ins, + struct io_normaliser *normaliser) + { +- struct vkd3d_shader_register *reg; + unsigned int i; + + switch (ins->opcode) + { +- case VKD3DSIH_DCL_INPUT: +- if (normaliser->shader_type == VKD3D_SHADER_TYPE_HULL) +- { +- reg = &ins->declaration.dst.reg; +- +- /* We don't need to keep OUTCONTROLPOINT or PATCHCONST input declarations since their +- * equivalents were declared earlier, but INCONTROLPOINT may be the first occurrence. */ +- if (reg->type == VKD3DSPR_OUTCONTROLPOINT || reg->type == VKD3DSPR_PATCHCONST) +- vkd3d_shader_instruction_make_nop(ins); +- else if (reg->type == VKD3DSPR_INCONTROLPOINT) +- reg->type = VKD3DSPR_INPUT; +- } +- /* fall through */ +- case VKD3DSIH_DCL_INPUT_PS: +- case VKD3DSIH_DCL_OUTPUT: +- if (!shader_dst_param_io_normalise(&ins->declaration.dst, true, normaliser)) +- vkd3d_shader_instruction_make_nop(ins); +- break; +- case VKD3DSIH_DCL_INPUT_SGV: +- case VKD3DSIH_DCL_INPUT_SIV: +- case VKD3DSIH_DCL_INPUT_PS_SGV: +- case VKD3DSIH_DCL_INPUT_PS_SIV: +- case VKD3DSIH_DCL_OUTPUT_SIV: +- if (!shader_dst_param_io_normalise(&ins->declaration.register_semantic.reg, true, normaliser)) +- vkd3d_shader_instruction_make_nop(ins); +- break; + case VKD3DSIH_HS_CONTROL_POINT_PHASE: + case VKD3DSIH_HS_FORK_PHASE: + case VKD3DSIH_HS_JOIN_PHASE: +@@ -2307,7 +2280,7 @@ static void shader_instruction_normalise_io_params(struct vkd3d_shader_instructi + if (vsir_instruction_is_dcl(ins)) + break; + for (i = 0; i < ins->dst_count; ++i) +- shader_dst_param_io_normalise(&ins->dst[i], false, normaliser); ++ shader_dst_param_io_normalise(&ins->dst[i], normaliser); + for (i = 0; i < ins->src_count; ++i) + shader_src_param_io_normalise(&ins->src[i], normaliser); + break; +@@ -9139,6 +9112,41 @@ enum vkd3d_result vsir_program_validate(struct vsir_program *program, uint64_t c + vsir_validate_signature(&ctx, &program->output_signature, SIGNATURE_TYPE_OUTPUT); + vsir_validate_signature(&ctx, &program->patch_constant_signature, SIGNATURE_TYPE_PATCH_CONSTANT); + ++ for (i = 0; i < sizeof(program->io_dcls) * CHAR_BIT; ++i) ++ { ++ if (!bitmap_is_set(program->io_dcls, i)) ++ continue; ++ ++ switch (i) ++ { ++ /* Input registers */ ++ case VKD3DSPR_PRIMID: ++ case VKD3DSPR_FORKINSTID: ++ case VKD3DSPR_JOININSTID: ++ case VKD3DSPR_THREADID: ++ case VKD3DSPR_THREADGROUPID: ++ case VKD3DSPR_LOCALTHREADID: ++ case VKD3DSPR_LOCALTHREADINDEX: ++ case VKD3DSPR_COVERAGE: ++ case VKD3DSPR_TESSCOORD: ++ case VKD3DSPR_OUTPOINTID: ++ case VKD3DSPR_GSINSTID: ++ case VKD3DSPR_WAVELANECOUNT: ++ case VKD3DSPR_WAVELANEINDEX: ++ /* Output registers */ ++ case VKD3DSPR_DEPTHOUT: ++ case VKD3DSPR_SAMPLEMASK: ++ case VKD3DSPR_DEPTHOUTGE: ++ case VKD3DSPR_DEPTHOUTLE: ++ case VKD3DSPR_OUTSTENCILREF: ++ break; ++ ++ default: ++ validator_error(&ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SIGNATURE, ++ "Invalid input/output declaration %u.", i); ++ } ++ } ++ + if (!(ctx.temps = vkd3d_calloc(ctx.program->temp_count, sizeof(*ctx.temps)))) + goto fail; + +diff --git a/libs/vkd3d/libs/vkd3d-shader/msl.c b/libs/vkd3d/libs/vkd3d-shader/msl.c +index 9a3c3ed885e..0406b8fbd51 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/msl.c ++++ b/libs/vkd3d/libs/vkd3d-shader/msl.c +@@ -398,6 +398,28 @@ static void msl_binop(struct msl_generator *gen, const struct vkd3d_shader_instr + msl_dst_cleanup(&dst, &gen->string_buffers); + } + ++static void msl_dot(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins, uint32_t src_mask) ++{ ++ unsigned int component_count; ++ struct msl_src src[2]; ++ struct msl_dst dst; ++ uint32_t dst_mask; ++ ++ dst_mask = msl_dst_init(&dst, gen, ins, &ins->dst[0]); ++ msl_src_init(&src[0], gen, &ins->src[0], src_mask); ++ msl_src_init(&src[1], gen, &ins->src[1], src_mask); ++ ++ if ((component_count = vsir_write_mask_component_count(dst_mask)) > 1) ++ msl_print_assignment(gen, &dst, "float%u(dot(%s, %s))", ++ component_count, src[0].str->buffer, src[1].str->buffer); ++ else ++ msl_print_assignment(gen, &dst, "dot(%s, %s)", src[0].str->buffer, src[1].str->buffer); ++ ++ msl_src_cleanup(&src[1], &gen->string_buffers); ++ msl_src_cleanup(&src[0], &gen->string_buffers); ++ msl_dst_cleanup(&dst, &gen->string_buffers); ++} ++ + static void msl_intrinsic(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins, const char *op) + { + struct msl_src src; +@@ -513,14 +535,26 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d + case VKD3DSIH_AND: + msl_binop(gen, ins, "&"); + break; +- case VKD3DSIH_DCL_INPUT: +- case VKD3DSIH_DCL_OUTPUT: +- case VKD3DSIH_DCL_OUTPUT_SIV: + case VKD3DSIH_NOP: + break; + case VKD3DSIH_DIV: + msl_binop(gen, ins, "/"); + break; ++ case VKD3DSIH_DP2: ++ msl_dot(gen, ins, vkd3d_write_mask_from_component_count(2)); ++ break; ++ case VKD3DSIH_DP3: ++ msl_dot(gen, ins, vkd3d_write_mask_from_component_count(3)); ++ break; ++ case VKD3DSIH_DP4: ++ msl_dot(gen, ins, VKD3DSP_WRITEMASK_ALL); ++ break; ++ case VKD3DSIH_IEQ: ++ msl_relop(gen, ins, "=="); ++ break; ++ case VKD3DSIH_EXP: ++ msl_intrinsic(gen, ins, "exp2"); ++ break; + case VKD3DSIH_FRC: + msl_intrinsic(gen, ins, "fract"); + break; +@@ -533,6 +567,9 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d + case VKD3DSIH_GEO: + msl_relop(gen, ins, ">="); + break; ++ case VKD3DSIH_LTO: ++ msl_relop(gen, ins, "<"); ++ break; + case VKD3DSIH_INE: + case VKD3DSIH_NEU: + msl_relop(gen, ins, "!="); +@@ -562,6 +599,9 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d + case VKD3DSIH_ROUND_Z: + msl_intrinsic(gen, ins, "trunc"); + break; ++ case VKD3DSIH_SQRT: ++ msl_intrinsic(gen, ins, "sqrt"); ++ break; + default: + msl_unhandled(gen, ins); + break; +@@ -737,13 +777,6 @@ static void msl_generate_input_struct_declarations(struct msl_generator *gen) + continue; + } + +- if (e->interpolation_mode != VKD3DSIM_NONE) +- { +- msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, +- "Internal compiler error: Unhandled interpolation mode %#x.", e->interpolation_mode); +- continue; +- } +- + if(e->register_count > 1) + { + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, +@@ -787,6 +820,18 @@ static void msl_generate_input_struct_declarations(struct msl_generator *gen) + break; + } + ++ switch (e->interpolation_mode) ++ { ++ /* The default interpolation attribute. */ ++ case VKD3DSIM_LINEAR: ++ case VKD3DSIM_NONE: ++ break; ++ default: ++ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, ++ "Internal compiler error: Unhandled interpolation mode %#x.", e->interpolation_mode); ++ break; ++ } ++ + vkd3d_string_buffer_printf(buffer, ";\n"); + } + +diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c +index 649f92a57f3..0b14f50a312 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/spirv.c ++++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c +@@ -4851,35 +4851,36 @@ static const struct vkd3d_spirv_builtin vkd3d_output_point_size_builtin = + static const struct + { + enum vkd3d_shader_register_type reg_type; ++ SpvStorageClass storage_class; + struct vkd3d_spirv_builtin builtin; + } + vkd3d_register_builtins[] = + { +- {VKD3DSPR_THREADID, {VKD3D_SHADER_COMPONENT_INT, 3, SpvBuiltInGlobalInvocationId}}, +- {VKD3DSPR_LOCALTHREADID, {VKD3D_SHADER_COMPONENT_INT, 3, SpvBuiltInLocalInvocationId}}, +- {VKD3DSPR_LOCALTHREADINDEX, {VKD3D_SHADER_COMPONENT_INT, 1, SpvBuiltInLocalInvocationIndex}}, +- {VKD3DSPR_THREADGROUPID, {VKD3D_SHADER_COMPONENT_INT, 3, SpvBuiltInWorkgroupId}}, ++ {VKD3DSPR_THREADID, SpvStorageClassInput, {VKD3D_SHADER_COMPONENT_INT, 3, SpvBuiltInGlobalInvocationId}}, ++ {VKD3DSPR_LOCALTHREADID, SpvStorageClassInput, {VKD3D_SHADER_COMPONENT_INT, 3, SpvBuiltInLocalInvocationId}}, ++ {VKD3DSPR_LOCALTHREADINDEX, SpvStorageClassInput, {VKD3D_SHADER_COMPONENT_INT, 1, SpvBuiltInLocalInvocationIndex}}, ++ {VKD3DSPR_THREADGROUPID, SpvStorageClassInput, {VKD3D_SHADER_COMPONENT_INT, 3, SpvBuiltInWorkgroupId}}, + +- {VKD3DSPR_GSINSTID, {VKD3D_SHADER_COMPONENT_INT, 1, SpvBuiltInInvocationId}}, +- {VKD3DSPR_OUTPOINTID, {VKD3D_SHADER_COMPONENT_INT, 1, SpvBuiltInInvocationId}}, ++ {VKD3DSPR_GSINSTID, SpvStorageClassInput, {VKD3D_SHADER_COMPONENT_INT, 1, SpvBuiltInInvocationId}}, ++ {VKD3DSPR_OUTPOINTID, SpvStorageClassInput, {VKD3D_SHADER_COMPONENT_INT, 1, SpvBuiltInInvocationId}}, + +- {VKD3DSPR_PRIMID, {VKD3D_SHADER_COMPONENT_INT, 1, SpvBuiltInPrimitiveId}}, ++ {VKD3DSPR_PRIMID, SpvStorageClassInput, {VKD3D_SHADER_COMPONENT_INT, 1, SpvBuiltInPrimitiveId}}, + +- {VKD3DSPR_TESSCOORD, {VKD3D_SHADER_COMPONENT_FLOAT, 3, SpvBuiltInTessCoord}}, ++ {VKD3DSPR_TESSCOORD, SpvStorageClassInput, {VKD3D_SHADER_COMPONENT_FLOAT, 3, SpvBuiltInTessCoord}}, + +- {VKD3DSPR_POINT_COORD, {VKD3D_SHADER_COMPONENT_FLOAT, 2, SpvBuiltInPointCoord}}, ++ {VKD3DSPR_POINT_COORD, SpvStorageClassInput, {VKD3D_SHADER_COMPONENT_FLOAT, 2, SpvBuiltInPointCoord}}, + +- {VKD3DSPR_COVERAGE, {VKD3D_SHADER_COMPONENT_UINT, 1, SpvBuiltInSampleMask, NULL, 1}}, +- {VKD3DSPR_SAMPLEMASK, {VKD3D_SHADER_COMPONENT_UINT, 1, SpvBuiltInSampleMask, NULL, 1}}, ++ {VKD3DSPR_COVERAGE, SpvStorageClassInput, {VKD3D_SHADER_COMPONENT_UINT, 1, SpvBuiltInSampleMask, NULL, 1}}, ++ {VKD3DSPR_SAMPLEMASK, SpvStorageClassOutput, {VKD3D_SHADER_COMPONENT_UINT, 1, SpvBuiltInSampleMask, NULL, 1}}, + +- {VKD3DSPR_DEPTHOUT, {VKD3D_SHADER_COMPONENT_FLOAT, 1, SpvBuiltInFragDepth}}, +- {VKD3DSPR_DEPTHOUTGE, {VKD3D_SHADER_COMPONENT_FLOAT, 1, SpvBuiltInFragDepth}}, +- {VKD3DSPR_DEPTHOUTLE, {VKD3D_SHADER_COMPONENT_FLOAT, 1, SpvBuiltInFragDepth}}, ++ {VKD3DSPR_DEPTHOUT, SpvStorageClassOutput, {VKD3D_SHADER_COMPONENT_FLOAT, 1, SpvBuiltInFragDepth}}, ++ {VKD3DSPR_DEPTHOUTGE, SpvStorageClassOutput, {VKD3D_SHADER_COMPONENT_FLOAT, 1, SpvBuiltInFragDepth}}, ++ {VKD3DSPR_DEPTHOUTLE, SpvStorageClassOutput, {VKD3D_SHADER_COMPONENT_FLOAT, 1, SpvBuiltInFragDepth}}, + +- {VKD3DSPR_OUTSTENCILREF, {VKD3D_SHADER_COMPONENT_UINT, 1, SpvBuiltInFragStencilRefEXT}}, ++ {VKD3DSPR_OUTSTENCILREF, SpvStorageClassOutput, {VKD3D_SHADER_COMPONENT_UINT, 1, SpvBuiltInFragStencilRefEXT}}, + +- {VKD3DSPR_WAVELANECOUNT, {VKD3D_SHADER_COMPONENT_UINT, 1, SpvBuiltInSubgroupSize}}, +- {VKD3DSPR_WAVELANEINDEX, {VKD3D_SHADER_COMPONENT_UINT, 1, SpvBuiltInSubgroupLocalInvocationId}}, ++ {VKD3DSPR_WAVELANECOUNT, SpvStorageClassInput, {VKD3D_SHADER_COMPONENT_UINT, 1, SpvBuiltInSubgroupSize}}, ++ {VKD3DSPR_WAVELANEINDEX, SpvStorageClassInput, {VKD3D_SHADER_COMPONENT_UINT, 1, SpvBuiltInSubgroupLocalInvocationId}}, + }; + + static void spirv_compiler_emit_register_execution_mode(struct spirv_compiler *compiler, +@@ -4938,14 +4939,18 @@ static const struct vkd3d_spirv_builtin *get_spirv_builtin_for_sysval( + } + + static const struct vkd3d_spirv_builtin *get_spirv_builtin_for_register( +- enum vkd3d_shader_register_type reg_type) ++ enum vkd3d_shader_register_type reg_type, SpvStorageClass *storage_class) + { + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(vkd3d_register_builtins); ++i) + { + if (vkd3d_register_builtins[i].reg_type == reg_type) ++ { ++ if (storage_class) ++ *storage_class = vkd3d_register_builtins[i].storage_class; + return &vkd3d_register_builtins[i].builtin; ++ } + } + + return NULL; +@@ -4958,7 +4963,7 @@ static const struct vkd3d_spirv_builtin *vkd3d_get_spirv_builtin(const struct sp + + if ((builtin = get_spirv_builtin_for_sysval(compiler, sysval))) + return builtin; +- if ((builtin = get_spirv_builtin_for_register(reg_type))) ++ if ((builtin = get_spirv_builtin_for_register(reg_type, NULL))) + return builtin; + + if ((sysval != VKD3D_SHADER_SV_NONE && sysval != VKD3D_SHADER_SV_TARGET) +@@ -5290,21 +5295,26 @@ static uint32_t spirv_compiler_emit_input(struct spirv_compiler *compiler, + return input_id; + } + +-static void spirv_compiler_emit_input_register(struct spirv_compiler *compiler, ++static void spirv_compiler_emit_io_register(struct spirv_compiler *compiler, + const struct vkd3d_shader_dst_param *dst) + { + struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; + const struct vkd3d_shader_register *reg = &dst->reg; + const struct vkd3d_spirv_builtin *builtin; + struct vkd3d_symbol reg_symbol; ++ SpvStorageClass storage_class; ++ uint32_t write_mask, id; + struct rb_entry *entry; +- uint32_t write_mask; +- uint32_t input_id; + + VKD3D_ASSERT(!reg->idx_count || !reg->idx[0].rel_addr); + VKD3D_ASSERT(reg->idx_count < 2); + +- if (!(builtin = get_spirv_builtin_for_register(reg->type))) ++ if (reg->type == VKD3DSPR_RASTOUT && reg->idx[0].offset == VSIR_RASTOUT_POINT_SIZE) ++ { ++ builtin = &vkd3d_output_point_size_builtin; ++ storage_class = SpvStorageClassOutput; ++ } ++ else if (!(builtin = get_spirv_builtin_for_register(reg->type, &storage_class))) + { + FIXME("Unhandled register %#x.\n", reg->type); + return; +@@ -5315,14 +5325,15 @@ static void spirv_compiler_emit_input_register(struct spirv_compiler *compiler, + if ((entry = rb_get(&compiler->symbol_table, ®_symbol))) + return; + +- input_id = spirv_compiler_emit_builtin_variable(compiler, builtin, SpvStorageClassInput, 0); ++ id = spirv_compiler_emit_builtin_variable(compiler, builtin, storage_class, 0); + + write_mask = vkd3d_write_mask_from_component_count(builtin->component_count); +- vkd3d_symbol_set_register_info(®_symbol, input_id, +- SpvStorageClassInput, builtin->component_type, write_mask); ++ vkd3d_symbol_set_register_info(®_symbol, id, ++ storage_class, builtin->component_type, write_mask); + reg_symbol.info.reg.is_aggregate = builtin->spirv_array_size; + spirv_compiler_put_symbol(compiler, ®_symbol); +- spirv_compiler_emit_register_debug_name(builder, input_id, reg); ++ spirv_compiler_emit_register_execution_mode(compiler, reg->type); ++ spirv_compiler_emit_register_debug_name(builder, id, reg); + } + + static unsigned int get_shader_output_swizzle(const struct spirv_compiler *compiler, +@@ -5426,41 +5437,6 @@ static void spirv_compiler_emit_shader_signature_outputs(struct spirv_compiler * + } + } + +-static void spirv_compiler_emit_output_register(struct spirv_compiler *compiler, +- const struct vkd3d_shader_dst_param *dst) +-{ +- struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; +- const struct vkd3d_shader_register *reg = &dst->reg; +- const struct vkd3d_spirv_builtin *builtin; +- struct vkd3d_symbol reg_symbol; +- uint32_t write_mask; +- uint32_t output_id; +- +- VKD3D_ASSERT(!reg->idx_count || !reg->idx[0].rel_addr); +- VKD3D_ASSERT(reg->idx_count < 2); +- +- if (reg->type == VKD3DSPR_RASTOUT && reg->idx[0].offset == VSIR_RASTOUT_POINT_SIZE) +- { +- builtin = &vkd3d_output_point_size_builtin; +- } +- else if (!(builtin = get_spirv_builtin_for_register(reg->type))) +- { +- FIXME("Unhandled register %#x.\n", reg->type); +- return; +- } +- +- output_id = spirv_compiler_emit_builtin_variable(compiler, builtin, SpvStorageClassOutput, 0); +- +- vkd3d_symbol_make_register(®_symbol, reg); +- write_mask = vkd3d_write_mask_from_component_count(builtin->component_count); +- vkd3d_symbol_set_register_info(®_symbol, output_id, +- SpvStorageClassOutput, builtin->component_type, write_mask); +- reg_symbol.info.reg.is_aggregate = builtin->spirv_array_size; +- spirv_compiler_put_symbol(compiler, ®_symbol); +- spirv_compiler_emit_register_execution_mode(compiler, reg->type); +- spirv_compiler_emit_register_debug_name(builder, output_id, reg); +-} +- + static uint32_t spirv_compiler_emit_shader_phase_builtin_variable(struct spirv_compiler *compiler, + const struct vkd3d_spirv_builtin *builtin, const unsigned int *array_sizes, unsigned int size_count) + { +@@ -5825,16 +5801,6 @@ static void spirv_compiler_emit_shader_epilogue_function(struct spirv_compiler * + compiler->epilogue_function_id = 0; + } + +-static void spirv_compiler_emit_hull_shader_builtins(struct spirv_compiler *compiler) +-{ +- struct vkd3d_shader_dst_param dst; +- +- memset(&dst, 0, sizeof(dst)); +- vsir_register_init(&dst.reg, VKD3DSPR_OUTPOINTID, VKD3D_DATA_FLOAT, 0); +- dst.write_mask = VKD3DSP_WRITEMASK_0; +- spirv_compiler_emit_input_register(compiler, &dst); +-} +- + static void spirv_compiler_emit_initial_declarations(struct spirv_compiler *compiler) + { + const struct vkd3d_shader_transform_feedback_info *xfb_info = compiler->xfb_info; +@@ -5847,7 +5813,6 @@ static void spirv_compiler_emit_initial_declarations(struct spirv_compiler *comp + break; + case VKD3D_SHADER_TYPE_HULL: + vkd3d_spirv_set_execution_model(builder, SpvExecutionModelTessellationControl); +- spirv_compiler_emit_hull_shader_builtins(compiler); + break; + case VKD3D_SHADER_TYPE_DOMAIN: + vkd3d_spirv_set_execution_model(builder, SpvExecutionModelTessellationEvaluation); +@@ -6667,27 +6632,6 @@ static void spirv_compiler_emit_dcl_tgsm_structured(struct spirv_compiler *compi + tgsm_structured->structure_count * stride, stride, tgsm_structured->zero_init); + } + +-static void spirv_compiler_emit_dcl_input(struct spirv_compiler *compiler, +- const struct vkd3d_shader_instruction *instruction) +-{ +- const struct vkd3d_shader_dst_param *dst = &instruction->declaration.dst; +- +- /* INPUT and PATCHCONST are handled in spirv_compiler_emit_io_declarations(). +- * OUTPOINTID is handled in spirv_compiler_emit_hull_shader_builtins(). */ +- if (dst->reg.type != VKD3DSPR_INPUT && dst->reg.type != VKD3DSPR_PATCHCONST +- && dst->reg.type != VKD3DSPR_OUTPOINTID) +- spirv_compiler_emit_input_register(compiler, dst); +-} +- +-static void spirv_compiler_emit_dcl_output(struct spirv_compiler *compiler, +- const struct vkd3d_shader_instruction *instruction) +-{ +- const struct vkd3d_shader_dst_param *dst = &instruction->declaration.dst; +- +- if (dst->reg.type != VKD3DSPR_OUTPUT && dst->reg.type != VKD3DSPR_PATCHCONST) +- spirv_compiler_emit_output_register(compiler, dst); +-} +- + static void spirv_compiler_emit_dcl_stream(struct spirv_compiler *compiler, + const struct vkd3d_shader_instruction *instruction) + { +@@ -10113,13 +10057,6 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, + case VKD3DSIH_DCL_TGSM_STRUCTURED: + spirv_compiler_emit_dcl_tgsm_structured(compiler, instruction); + break; +- case VKD3DSIH_DCL_INPUT_PS: +- case VKD3DSIH_DCL_INPUT: +- spirv_compiler_emit_dcl_input(compiler, instruction); +- break; +- case VKD3DSIH_DCL_OUTPUT: +- spirv_compiler_emit_dcl_output(compiler, instruction); +- break; + case VKD3DSIH_DCL_STREAM: + spirv_compiler_emit_dcl_stream(compiler, instruction); + break; +@@ -10457,11 +10394,6 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, + break; + case VKD3DSIH_DCL_HS_MAX_TESSFACTOR: + case VKD3DSIH_DCL_INPUT_CONTROL_POINT_COUNT: +- case VKD3DSIH_DCL_INPUT_SGV: +- case VKD3DSIH_DCL_INPUT_SIV: +- case VKD3DSIH_DCL_INPUT_PS_SGV: +- case VKD3DSIH_DCL_INPUT_PS_SIV: +- case VKD3DSIH_DCL_OUTPUT_SIV: + case VKD3DSIH_DCL_RESOURCE_RAW: + case VKD3DSIH_DCL_RESOURCE_STRUCTURED: + case VKD3DSIH_DCL_UAV_RAW: +@@ -10482,6 +10414,8 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, + + static void spirv_compiler_emit_io_declarations(struct spirv_compiler *compiler) + { ++ struct vkd3d_shader_dst_param dst; ++ + for (unsigned int i = 0; i < compiler->input_signature.element_count; ++i) + spirv_compiler_emit_input(compiler, VKD3DSPR_INPUT, i); + +@@ -10505,19 +10439,27 @@ static void spirv_compiler_emit_io_declarations(struct spirv_compiler *compiler) + + if (compiler->program->has_point_size) + { +- struct vkd3d_shader_dst_param dst; +- + vsir_dst_param_init(&dst, VKD3DSPR_RASTOUT, VKD3D_DATA_FLOAT, 1); + dst.reg.idx[0].offset = VSIR_RASTOUT_POINT_SIZE; +- spirv_compiler_emit_output_register(compiler, &dst); ++ spirv_compiler_emit_io_register(compiler, &dst); + } + + if (compiler->program->has_point_coord) + { +- struct vkd3d_shader_dst_param dst; +- + vsir_dst_param_init(&dst, VKD3DSPR_POINT_COORD, VKD3D_DATA_FLOAT, 0); +- spirv_compiler_emit_input_register(compiler, &dst); ++ spirv_compiler_emit_io_register(compiler, &dst); ++ } ++ ++ for (unsigned int i = 0; i < sizeof(compiler->program->io_dcls) * CHAR_BIT; ++i) ++ { ++ /* For hull shaders we internally generate references to OUTPOINTID, ++ * so that must always be enabled. */ ++ if (bitmap_is_set(compiler->program->io_dcls, i) ++ || (compiler->program->shader_version.type == VKD3D_SHADER_TYPE_HULL && i == VKD3DSPR_OUTPOINTID)) ++ { ++ vsir_dst_param_init(&dst, i, VKD3D_DATA_FLOAT, 0); ++ spirv_compiler_emit_io_register(compiler, &dst); ++ } + } + } + +diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +index 55b28cdd875..eb6d7f26a2c 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h ++++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +@@ -163,6 +163,7 @@ enum vkd3d_shader_error + VKD3D_SHADER_ERROR_HLSL_INVALID_OUTPUT_PRIMITIVE = 5037, + VKD3D_SHADER_ERROR_HLSL_INVALID_PARTITIONING = 5038, + VKD3D_SHADER_ERROR_HLSL_MISPLACED_SAMPLER_STATE = 5039, ++ VKD3D_SHADER_ERROR_HLSL_AMBIGUOUS_CALL = 5040, + + VKD3D_SHADER_WARNING_HLSL_IMPLICIT_TRUNCATION = 5300, + VKD3D_SHADER_WARNING_HLSL_DIVISION_BY_ZERO = 5301, +@@ -1433,6 +1434,7 @@ struct vsir_program + enum vsir_control_flow_type cf_type; + enum vsir_normalisation_level normalisation_level; + enum vkd3d_tessellator_domain tess_domain; ++ uint32_t io_dcls[VKD3D_BITMAP_SIZE(VKD3DSPR_COUNT)]; + + const char **block_names; + size_t block_name_count; +-- +2.45.2 + diff --git a/patches/vkd3d-latest/0004-Updated-vkd3d-to-01117c716dea0e934ac594a7596d90ad948.patch b/patches/vkd3d-latest/0004-Updated-vkd3d-to-01117c716dea0e934ac594a7596d90ad948.patch new file mode 100644 index 00000000..e1bd517b --- /dev/null +++ b/patches/vkd3d-latest/0004-Updated-vkd3d-to-01117c716dea0e934ac594a7596d90ad948.patch @@ -0,0 +1,302 @@ +From fa35dd1156e8acc109be7fcc8e0c2fc79ee19974 Mon Sep 17 00:00:00 2001 +From: Alistair Leslie-Hughes +Date: Thu, 5 Dec 2024 09:55:52 +1100 +Subject: [PATCH] Updated vkd3d to 01117c716dea0e934ac594a7596d90ad94895d65. + +--- + libs/vkd3d/libs/vkd3d-shader/hlsl.c | 3 -- + libs/vkd3d/libs/vkd3d-shader/hlsl.h | 3 -- + libs/vkd3d/libs/vkd3d-shader/ir.c | 16 +++++- + libs/vkd3d/libs/vkd3d-shader/msl.c | 78 +++++++++++++++++++++++++++-- + 4 files changed, 90 insertions(+), 10 deletions(-) + +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c +index f0d24b835e5..e7518404aa0 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c +@@ -3203,13 +3203,11 @@ const char *debug_hlsl_expr_op(enum hlsl_ir_expr_op op) + [HLSL_OP1_LOG2] = "log2", + [HLSL_OP1_LOGIC_NOT] = "!", + [HLSL_OP1_NEG] = "-", +- [HLSL_OP1_NRM] = "nrm", + [HLSL_OP1_RCP] = "rcp", + [HLSL_OP1_REINTERPRET] = "reinterpret", + [HLSL_OP1_ROUND] = "round", + [HLSL_OP1_RSQ] = "rsq", + [HLSL_OP1_SAT] = "sat", +- [HLSL_OP1_SIGN] = "sign", + [HLSL_OP1_SIN] = "sin", + [HLSL_OP1_SIN_REDUCED] = "sin_reduced", + [HLSL_OP1_SQRT] = "sqrt", +@@ -3219,7 +3217,6 @@ const char *debug_hlsl_expr_op(enum hlsl_ir_expr_op op) + [HLSL_OP2_BIT_AND] = "&", + [HLSL_OP2_BIT_OR] = "|", + [HLSL_OP2_BIT_XOR] = "^", +- [HLSL_OP2_CRS] = "crs", + [HLSL_OP2_DIV] = "/", + [HLSL_OP2_DOT] = "dot", + [HLSL_OP2_EQUAL] = "==", +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h +index addc98d5a43..b899c16357c 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h +@@ -714,13 +714,11 @@ enum hlsl_ir_expr_op + HLSL_OP1_LOG2, + HLSL_OP1_LOGIC_NOT, + HLSL_OP1_NEG, +- HLSL_OP1_NRM, + HLSL_OP1_RCP, + HLSL_OP1_REINTERPRET, + HLSL_OP1_ROUND, + HLSL_OP1_RSQ, + HLSL_OP1_SAT, +- HLSL_OP1_SIGN, + HLSL_OP1_SIN, + HLSL_OP1_SIN_REDUCED, /* Reduced range [-pi, pi], writes to .y */ + HLSL_OP1_SQRT, +@@ -730,7 +728,6 @@ enum hlsl_ir_expr_op + HLSL_OP2_BIT_AND, + HLSL_OP2_BIT_OR, + HLSL_OP2_BIT_XOR, +- HLSL_OP2_CRS, + HLSL_OP2_DIV, + HLSL_OP2_DOT, + HLSL_OP2_EQUAL, +diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c +index 64c9585af52..fbc3ac0f49d 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/ir.c ++++ b/libs/vkd3d/libs/vkd3d-shader/ir.c +@@ -7195,6 +7195,7 @@ static void vsir_validate_register_without_indices(struct validation_context *ct + static void vsir_validate_io_register(struct validation_context *ctx, + const struct vkd3d_shader_register *reg) + { ++ unsigned int control_point_count = 0, control_point_index; + const struct shader_signature *signature; + bool has_control_point = false; + +@@ -7209,6 +7210,7 @@ static void vsir_validate_io_register(struct validation_context *ctx, + case VKD3D_SHADER_TYPE_HULL: + case VKD3D_SHADER_TYPE_DOMAIN: + has_control_point = true; ++ control_point_count = ctx->program->input_control_point_count; + break; + + default: +@@ -7225,6 +7227,7 @@ static void vsir_validate_io_register(struct validation_context *ctx, + { + signature = &ctx->program->output_signature; + has_control_point = ctx->program->normalisation_level >= VSIR_NORMALISED_HULL_CONTROL_POINT_IO; ++ control_point_count = ctx->program->output_control_point_count; + } + else + { +@@ -7241,11 +7244,13 @@ static void vsir_validate_io_register(struct validation_context *ctx, + case VKD3DSPR_INCONTROLPOINT: + signature = &ctx->program->input_signature; + has_control_point = true; ++ control_point_count = ctx->program->input_control_point_count; + break; + + case VKD3DSPR_OUTCONTROLPOINT: + signature = &ctx->program->output_signature; + has_control_point = true; ++ control_point_count = ctx->program->output_control_point_count; + break; + + case VKD3DSPR_PATCHCONST: +@@ -7262,6 +7267,8 @@ static void vsir_validate_io_register(struct validation_context *ctx, + * allowed to have a relative address. */ + unsigned int expected_idx_count = 1 + !!has_control_point; + ++ control_point_index = 0; ++ + if (reg->idx_count != expected_idx_count) + { + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX_COUNT, +@@ -7280,7 +7287,7 @@ static void vsir_validate_io_register(struct validation_context *ctx, + /* If the signature element is not an array, indices are + * [signature] or [control point, signature]. If the signature + * element is an array, indices are [array, signature] or +- * [control point, array, signature]. In any case `signature' is ++ * [array, control point, signature]. In any case `signature' is + * not allowed to have a relative address, while the others are. + */ + if (reg->idx_count < 1) +@@ -7314,6 +7321,7 @@ static void vsir_validate_io_register(struct validation_context *ctx, + is_array = true; + + expected_idx_count = 1 + !!has_control_point + !!is_array; ++ control_point_index = !!is_array; + + if (reg->idx_count != expected_idx_count) + { +@@ -7323,6 +7331,12 @@ static void vsir_validate_io_register(struct validation_context *ctx, + return; + } + } ++ ++ if (has_control_point && !reg->idx[control_point_index].rel_addr ++ && reg->idx[control_point_index].offset >= control_point_count) ++ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX, ++ "Control point index %u exceeds the control point count %u in a register of type %#x.", ++ reg->idx[control_point_index].offset, control_point_count, reg->type); + } + + static void vsir_validate_temp_register(struct validation_context *ctx, +diff --git a/libs/vkd3d/libs/vkd3d-shader/msl.c b/libs/vkd3d/libs/vkd3d-shader/msl.c +index 0406b8fbd51..f1ca581f1d2 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/msl.c ++++ b/libs/vkd3d/libs/vkd3d-shader/msl.c +@@ -422,16 +422,25 @@ static void msl_dot(struct msl_generator *gen, const struct vkd3d_shader_instruc + + static void msl_intrinsic(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins, const char *op) + { ++ struct vkd3d_string_buffer *args; + struct msl_src src; + struct msl_dst dst; ++ unsigned int i; + uint32_t mask; + + mask = msl_dst_init(&dst, gen, ins, &ins->dst[0]); +- msl_src_init(&src, gen, &ins->src[0], mask); ++ args = vkd3d_string_buffer_get(&gen->string_buffers); + +- msl_print_assignment(gen, &dst, "%s(%s)", op, src.str->buffer); ++ for (i = 0; i < ins->src_count; ++i) ++ { ++ msl_src_init(&src, gen, &ins->src[i], mask); ++ vkd3d_string_buffer_printf(args, "%s%s", i ? ", " : "", src.str->buffer); ++ msl_src_cleanup(&src, &gen->string_buffers); ++ } + +- msl_src_cleanup(&src, &gen->string_buffers); ++ msl_print_assignment(gen, &dst, "%s(%s)", op, args->buffer); ++ ++ vkd3d_string_buffer_release(&gen->string_buffers, args); + msl_dst_cleanup(&dst, &gen->string_buffers); + } + +@@ -477,6 +486,31 @@ static void msl_cast(struct msl_generator *gen, const struct vkd3d_shader_instru + msl_dst_cleanup(&dst, &gen->string_buffers); + } + ++static void msl_if(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) ++{ ++ const char *condition; ++ struct msl_src src; ++ ++ msl_src_init(&src, gen, &ins->src[0], VKD3DSP_WRITEMASK_0); ++ ++ msl_print_indent(gen->buffer, gen->indent); ++ condition = ins->flags == VKD3D_SHADER_CONDITIONAL_OP_NZ ? "bool" : "!bool"; ++ vkd3d_string_buffer_printf(gen->buffer, "if (%s(%s))\n", condition, src.str->buffer); ++ ++ msl_src_cleanup(&src, &gen->string_buffers); ++ ++ msl_print_indent(gen->buffer, gen->indent); ++ vkd3d_string_buffer_printf(gen->buffer, "{\n"); ++ ++gen->indent; ++} ++ ++static void msl_endif(struct msl_generator *gen) ++{ ++ --gen->indent; ++ msl_print_indent(gen->buffer, gen->indent); ++ vkd3d_string_buffer_printf(gen->buffer, "}\n"); ++} ++ + static void msl_mov(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) + { + struct msl_src src; +@@ -549,6 +583,9 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d + case VKD3DSIH_DP4: + msl_dot(gen, ins, VKD3DSP_WRITEMASK_ALL); + break; ++ case VKD3DSIH_ENDIF: ++ msl_endif(gen); ++ break; + case VKD3DSIH_IEQ: + msl_relop(gen, ins, "=="); + break; +@@ -567,9 +604,18 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d + case VKD3DSIH_GEO: + msl_relop(gen, ins, ">="); + break; ++ case VKD3DSIH_IF: ++ msl_if(gen, ins); ++ break; + case VKD3DSIH_LTO: + msl_relop(gen, ins, "<"); + break; ++ case VKD3DSIH_MAX: ++ msl_intrinsic(gen, ins, "max"); ++ break; ++ case VKD3DSIH_MIN: ++ msl_intrinsic(gen, ins, "min"); ++ break; + case VKD3DSIH_INE: + case VKD3DSIH_NEU: + msl_relop(gen, ins, "!="); +@@ -578,6 +624,9 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d + case VKD3DSIH_UTOF: + msl_cast(gen, ins, "float"); + break; ++ case VKD3DSIH_LOG: ++ msl_intrinsic(gen, ins, "log2"); ++ break; + case VKD3DSIH_MOV: + msl_mov(gen, ins); + break; +@@ -593,12 +642,21 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d + case VKD3DSIH_RET: + msl_ret(gen, ins); + break; ++ case VKD3DSIH_ROUND_NE: ++ msl_intrinsic(gen, ins, "rint"); ++ break; ++ case VKD3DSIH_ROUND_NI: ++ msl_intrinsic(gen, ins, "floor"); ++ break; + case VKD3DSIH_ROUND_PI: + msl_intrinsic(gen, ins, "ceil"); + break; + case VKD3DSIH_ROUND_Z: + msl_intrinsic(gen, ins, "trunc"); + break; ++ case VKD3DSIH_RSQ: ++ msl_intrinsic(gen, ins, "rsqrt"); ++ break; + case VKD3DSIH_SQRT: + msl_intrinsic(gen, ins, "sqrt"); + break; +@@ -765,6 +823,16 @@ static void msl_generate_input_struct_declarations(struct msl_generator *gen) + + if (e->sysval_semantic) + { ++ if (e->sysval_semantic == VKD3D_SHADER_SV_IS_FRONT_FACE) ++ { ++ if (type != VKD3D_SHADER_TYPE_PIXEL) ++ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, ++ "Internal compiler error: Unhandled SV_IS_FRONT_FACE in shader type #%x.", type); ++ ++ msl_print_indent(gen->buffer, 1); ++ vkd3d_string_buffer_printf(buffer, "bool is_front_face [[front_facing]];\n"); ++ continue; ++ } + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled system value %#x.", e->sysval_semantic); + continue; +@@ -979,6 +1047,10 @@ static void msl_generate_entrypoint_prologue(struct msl_generator *gen) + vkd3d_string_buffer_printf(buffer, " = input.shader_in_%u", i); + msl_print_write_mask(buffer, e->mask); + } ++ else if (e->sysval_semantic == VKD3D_SHADER_SV_IS_FRONT_FACE) ++ { ++ vkd3d_string_buffer_printf(buffer, ".u = uint4(input.is_front_face ? 0xffffffffu : 0u, 0, 0, 0)"); ++ } + else + { + vkd3d_string_buffer_printf(buffer, " = ", e->sysval_semantic); +-- +2.45.2 +