From 3c0ae5d07cc57d0b7375f06960b5e41d5e2464df Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Tue, 27 Aug 2024 07:56:55 +1000 Subject: [PATCH] Updated vkd3d-latest patchset Squash and rebase to latest. --- ...f318e565f295d9f439e0e9ec52ba28835b3.patch} | 2748 ++++++++++++----- ...-c8cc1b1a2476a4c518756fd7604d37e8c16.patch | 1777 ----------- ...-738ecc9eb1ee65e426a4ea8186e44183775.patch | 204 -- 3 files changed, 1938 insertions(+), 2791 deletions(-) rename patches/vkd3d-latest/{0001-Updated-vkd3d-to-b23874dad600ec777c0bbe6ecc7aa3f5020.patch => 0001-Updated-vkd3d-to-f318e565f295d9f439e0e9ec52ba28835b3.patch} (88%) delete mode 100644 patches/vkd3d-latest/0002-Updated-vkd3d-to-c8cc1b1a2476a4c518756fd7604d37e8c16.patch delete mode 100644 patches/vkd3d-latest/0003-Updated-vkd3d-to-738ecc9eb1ee65e426a4ea8186e44183775.patch diff --git a/patches/vkd3d-latest/0001-Updated-vkd3d-to-b23874dad600ec777c0bbe6ecc7aa3f5020.patch b/patches/vkd3d-latest/0001-Updated-vkd3d-to-f318e565f295d9f439e0e9ec52ba28835b3.patch similarity index 88% rename from patches/vkd3d-latest/0001-Updated-vkd3d-to-b23874dad600ec777c0bbe6ecc7aa3f5020.patch rename to patches/vkd3d-latest/0001-Updated-vkd3d-to-f318e565f295d9f439e0e9ec52ba28835b3.patch index b36ab5e4..4d5fffb5 100644 --- a/patches/vkd3d-latest/0001-Updated-vkd3d-to-b23874dad600ec777c0bbe6ecc7aa3f5020.patch +++ b/patches/vkd3d-latest/0001-Updated-vkd3d-to-f318e565f295d9f439e0e9ec52ba28835b3.patch @@ -1,43 +1,44 @@ -From 5c4fa57f02c41cd48f133e49965a1c5c51f428ed Mon Sep 17 00:00:00 2001 +From 6a483e26d5143a3faaa3365f7cf728eec9b231d9 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Thu, 7 Mar 2024 10:40:41 +1100 -Subject: [PATCH] Updated vkd3d to b23874dad600ec777c0bbe6ecc7aa3f5020476d1. +Subject: [PATCH] Updated vkd3d to f318e565f295d9f439e0e9ec52ba28835b33a9ce. --- libs/vkd3d/include/private/vkd3d_common.h | 76 +- - libs/vkd3d/include/vkd3d_shader.h | 241 ++++ + libs/vkd3d/include/private/vkd3d_memory.h | 3 +- + libs/vkd3d/include/vkd3d_shader.h | 243 +++- libs/vkd3d/libs/vkd3d-common/blob.c | 1 + - libs/vkd3d/libs/vkd3d-common/debug.c | 13 +- + libs/vkd3d/libs/vkd3d-common/debug.c | 14 +- libs/vkd3d/libs/vkd3d-shader/checksum.c | 2 +- - libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 27 +- - libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 714 ++++++---- + libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 29 +- + libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 718 ++++++---- libs/vkd3d/libs/vkd3d-shader/dxbc.c | 6 +- - libs/vkd3d/libs/vkd3d-shader/dxil.c | 156 ++- - libs/vkd3d/libs/vkd3d-shader/fx.c | 920 ++++++++++-- + libs/vkd3d/libs/vkd3d-shader/dxil.c | 160 ++- + libs/vkd3d/libs/vkd3d-shader/fx.c | 1229 ++++++++++++++-- libs/vkd3d/libs/vkd3d-shader/glsl.c | 198 ++- - libs/vkd3d/libs/vkd3d-shader/hlsl.c | 344 ++++- - libs/vkd3d/libs/vkd3d-shader/hlsl.h | 159 ++- - libs/vkd3d/libs/vkd3d-shader/hlsl.l | 134 +- - libs/vkd3d/libs/vkd3d-shader/hlsl.y | 1150 ++++++++++++--- - libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 1233 ++++++++++++++--- + libs/vkd3d/libs/vkd3d-shader/hlsl.c | 379 ++++- + libs/vkd3d/libs/vkd3d-shader/hlsl.h | 167 ++- + libs/vkd3d/libs/vkd3d-shader/hlsl.l | 136 +- + libs/vkd3d/libs/vkd3d-shader/hlsl.y | 1259 +++++++++++++---- + libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 1235 +++++++++++++--- .../libs/vkd3d-shader/hlsl_constant_ops.c | 110 +- - libs/vkd3d/libs/vkd3d-shader/ir.c | 663 +++++++-- + libs/vkd3d/libs/vkd3d-shader/ir.c | 699 +++++++-- libs/vkd3d/libs/vkd3d-shader/preproc.h | 2 +- libs/vkd3d/libs/vkd3d-shader/preproc.l | 5 +- libs/vkd3d/libs/vkd3d-shader/preproc.y | 2 +- - libs/vkd3d/libs/vkd3d-shader/spirv.c | 543 +++++--- - libs/vkd3d/libs/vkd3d-shader/tpf.c | 541 +++++--- + libs/vkd3d/libs/vkd3d-shader/spirv.c | 629 ++++---- + libs/vkd3d/libs/vkd3d-shader/tpf.c | 625 +++++--- .../libs/vkd3d-shader/vkd3d_shader_main.c | 42 +- - .../libs/vkd3d-shader/vkd3d_shader_private.h | 33 +- + .../libs/vkd3d-shader/vkd3d_shader_private.h | 34 +- libs/vkd3d/libs/vkd3d/cache.c | 9 +- libs/vkd3d/libs/vkd3d/command.c | 595 ++++---- libs/vkd3d/libs/vkd3d/device.c | 190 ++- - libs/vkd3d/libs/vkd3d/resource.c | 56 +- - libs/vkd3d/libs/vkd3d/state.c | 243 +++- + libs/vkd3d/libs/vkd3d/resource.c | 58 +- + libs/vkd3d/libs/vkd3d/state.c | 262 +++- libs/vkd3d/libs/vkd3d/utils.c | 4 +- libs/vkd3d/libs/vkd3d/vkd3d_main.c | 8 +- - libs/vkd3d/libs/vkd3d/vkd3d_private.h | 12 +- - 33 files changed, 6405 insertions(+), 2027 deletions(-) + libs/vkd3d/libs/vkd3d/vkd3d_private.h | 15 +- + 34 files changed, 6981 insertions(+), 2163 deletions(-) diff --git a/libs/vkd3d/include/private/vkd3d_common.h b/libs/vkd3d/include/private/vkd3d_common.h index a9d709d10fe..c62dc00415f 100644 @@ -193,8 +194,29 @@ index a9d709d10fe..c62dc00415f 100644 return __builtin_popcount(v); #else v -= (v >> 1) & 0x55555555; +diff --git a/libs/vkd3d/include/private/vkd3d_memory.h b/libs/vkd3d/include/private/vkd3d_memory.h +index 682d35c03c6..b157fc07cb7 100644 +--- a/libs/vkd3d/include/private/vkd3d_memory.h ++++ b/libs/vkd3d/include/private/vkd3d_memory.h +@@ -19,7 +19,6 @@ + #ifndef __VKD3D_MEMORY_H + #define __VKD3D_MEMORY_H + +-#include + #include + #include + #include +@@ -44,7 +43,7 @@ static inline void *vkd3d_realloc(void *ptr, size_t size) + static inline void *vkd3d_calloc(size_t count, size_t size) + { + void *ptr; +- assert(count <= ~(size_t)0 / size); ++ VKD3D_ASSERT(!size || count <= ~(size_t)0 / size); + if (!(ptr = calloc(count, size))) + ERR("Out of memory.\n"); + return ptr; diff --git a/libs/vkd3d/include/vkd3d_shader.h b/libs/vkd3d/include/vkd3d_shader.h -index d3afcc11b16..d4756810065 100644 +index d3afcc11b16..d37d8ebad9e 100644 --- a/libs/vkd3d/include/vkd3d_shader.h +++ b/libs/vkd3d/include/vkd3d_shader.h @@ -105,6 +105,11 @@ enum vkd3d_shader_structure_type @@ -458,6 +480,15 @@ index d3afcc11b16..d4756810065 100644 /** * Symbolic register indices for mapping uniform constant register sets in * legacy Direct3D bytecode to constant buffer views in the target environment. +@@ -1674,7 +1876,7 @@ enum vkd3d_shader_sysval_semantic + VKD3D_SHADER_SV_VIEWPORT_ARRAY_INDEX = 0x05, + /** Vertex ID; SV_VertexID in Direct3D. */ + VKD3D_SHADER_SV_VERTEX_ID = 0x06, +- /** Primtive ID; SV_PrimitiveID in Direct3D. */ ++ /** Primitive ID; SV_PrimitiveID in Direct3D. */ + VKD3D_SHADER_SV_PRIMITIVE_ID = 0x07, + /** Instance ID; SV_InstanceID in Direct3D. */ + VKD3D_SHADER_SV_INSTANCE_ID = 0x08, @@ -1994,6 +2196,44 @@ struct vkd3d_shader_varying_map_info unsigned int varying_count; }; @@ -524,10 +555,18 @@ index f60ef7db769..c2c6ad67804 100644 #include "vkd3d.h" #include "vkd3d_blob.h" diff --git a/libs/vkd3d/libs/vkd3d-common/debug.c b/libs/vkd3d/libs/vkd3d-common/debug.c -index 4523fc997ef..4bfc19bd9a1 100644 +index 4523fc997ef..9a92f0ead02 100644 --- a/libs/vkd3d/libs/vkd3d-common/debug.c +++ b/libs/vkd3d/libs/vkd3d-common/debug.c -@@ -45,11 +45,12 @@ extern const char *const vkd3d_dbg_env_name; +@@ -22,7 +22,6 @@ + + #include "vkd3d_common.h" + +-#include + #include + #include + #include +@@ -45,11 +44,12 @@ extern const char *const vkd3d_dbg_env_name; static const char *const debug_level_names[] = { @@ -545,7 +584,7 @@ index 4523fc997ef..4bfc19bd9a1 100644 }; enum vkd3d_dbg_level vkd3d_dbg_get_level(void) -@@ -104,8 +105,6 @@ void vkd3d_dbg_printf(enum vkd3d_dbg_level level, const char *function, const ch +@@ -104,8 +104,6 @@ void vkd3d_dbg_printf(enum vkd3d_dbg_level level, const char *function, const ch if (vkd3d_dbg_get_level() < level) return; @@ -568,7 +607,7 @@ index 0910729a0e9..d9560628c77 100644 size -= DXBC_CHECKSUM_SKIP_BYTE_COUNT; diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c -index 9abc2c4db70..2c2f0c43ece 100644 +index 9abc2c4db70..77e9711300f 100644 --- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c +++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c @@ -254,6 +254,10 @@ static const char * const shader_opcode_names[] = @@ -637,6 +676,15 @@ index 9abc2c4db70..2c2f0c43ece 100644 { case VKD3DSIH_DCL: case VKD3DSIH_DCL_UAV_TYPED: +@@ -2242,7 +2251,7 @@ static const char *get_semantic_register_name(enum vkd3d_shader_sysval_semantic + case VKD3D_SHADER_SV_DEPTH_GREATER_EQUAL: return "oDepthGE"; + case VKD3D_SHADER_SV_DEPTH_LESS_EQUAL: return "oDepthLE"; + /* SV_Coverage has name vCoverage when used as an input, +- * but it doens't appear in the signature in that case. */ ++ * but it doesn't appear in the signature in that case. */ + case VKD3D_SHADER_SV_COVERAGE: return "oMask"; + case VKD3D_SHADER_SV_STENCIL_REF: return "oStencilRef"; + default: return "??"; @@ -2430,7 +2439,7 @@ enum vkd3d_result d3d_asm_compile(const struct vsir_program *program, { struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; @@ -656,7 +704,7 @@ index 9abc2c4db70..2c2f0c43ece 100644 case VKD3DSIH_ELSE: case VKD3DSIH_IF: diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c -index bfd5b52b436..a4c038a233a 100644 +index bfd5b52b436..d05394c3ab7 100644 --- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c +++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c @@ -757,7 +757,7 @@ static void record_constant_register(struct vkd3d_shader_sm1_parser *sm1, @@ -887,7 +935,7 @@ index bfd5b52b436..a4c038a233a 100644 if (type->modifiers & HLSL_MODIFIER_COLUMN_MAJOR) return D3DXPC_MATRIX_COLUMNS; else -@@ -1497,13 +1509,20 @@ D3DXPARAMETER_CLASS hlsl_sm1_class(const struct hlsl_type *type) +@@ -1497,13 +1509,22 @@ D3DXPARAMETER_CLASS hlsl_sm1_class(const struct hlsl_type *type) case HLSL_CLASS_TEXTURE: case HLSL_CLASS_VERTEX_SHADER: return D3DXPC_OBJECT; @@ -905,10 +953,12 @@ index bfd5b52b436..a4c038a233a 100644 + case HLSL_CLASS_DOMAIN_SHADER: + case HLSL_CLASS_HULL_SHADER: + case HLSL_CLASS_GEOMETRY_SHADER: ++ case HLSL_CLASS_BLEND_STATE: ++ case HLSL_CLASS_NULL: break; } -@@ -1593,13 +1612,20 @@ D3DXPARAMETER_TYPE hlsl_sm1_base_type(const struct hlsl_type *type) +@@ -1593,13 +1614,22 @@ D3DXPARAMETER_TYPE hlsl_sm1_base_type(const struct hlsl_type *type) case HLSL_CLASS_VERTEX_SHADER: return D3DXPT_VERTEXSHADER; @@ -926,10 +976,12 @@ index bfd5b52b436..a4c038a233a 100644 + case HLSL_CLASS_DOMAIN_SHADER: + case HLSL_CLASS_HULL_SHADER: + case HLSL_CLASS_GEOMETRY_SHADER: ++ case HLSL_CLASS_BLEND_STATE: ++ case HLSL_CLASS_NULL: break; } -@@ -1677,8 +1703,7 @@ static void sm1_sort_externs(struct hlsl_ctx *ctx) +@@ -1677,8 +1707,7 @@ static void sm1_sort_externs(struct hlsl_ctx *ctx) list_move_tail(&ctx->extern_vars, &sorted); } @@ -939,7 +991,7 @@ index bfd5b52b436..a4c038a233a 100644 { size_t ctab_offset, ctab_start, ctab_end, vars_start, size_offset, creator_offset, offset; unsigned int uniform_count = 0; -@@ -1739,11 +1764,11 @@ static void write_sm1_uniforms(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffe +@@ -1739,11 +1768,11 @@ static void write_sm1_uniforms(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffe } else { @@ -953,7 +1005,7 @@ index bfd5b52b436..a4c038a233a 100644 } } -@@ -1767,6 +1792,62 @@ static void write_sm1_uniforms(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffe +@@ -1767,6 +1796,62 @@ static void write_sm1_uniforms(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffe write_sm1_type(buffer, var->data_type, ctab_start); set_u32(buffer, var_offset + 3 * sizeof(uint32_t), var->data_type->bytecode_offset - ctab_start); @@ -991,17 +1043,17 @@ index bfd5b52b436..a4c038a233a 100644 + break; + + case HLSL_TYPE_INT: -+ uni.f = var->default_values[k].value.i; ++ uni.f = var->default_values[k].number.i; + break; + + case HLSL_TYPE_UINT: + case HLSL_TYPE_BOOL: -+ uni.f = var->default_values[k].value.u; ++ uni.f = var->default_values[k].number.u; + break; + + case HLSL_TYPE_HALF: + case HLSL_TYPE_FLOAT: -+ uni.u = var->default_values[k].value.u; ++ uni.u = var->default_values[k].number.u; + break; + + default: @@ -1016,7 +1068,7 @@ index bfd5b52b436..a4c038a233a 100644 ++uniform_count; } } -@@ -1778,7 +1859,7 @@ static void write_sm1_uniforms(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffe +@@ -1778,7 +1863,7 @@ static void write_sm1_uniforms(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffe set_u32(buffer, size_offset, vkd3d_make_u32(D3DSIO_COMMENT, (ctab_end - ctab_offset) / sizeof(uint32_t))); } @@ -1025,7 +1077,7 @@ index bfd5b52b436..a4c038a233a 100644 { return ((type << D3DSP_REGTYPE_SHIFT) & D3DSP_REGTYPE_MASK) | ((type << D3DSP_REGTYPE_SHIFT2) & D3DSP_REGTYPE_MASK2); -@@ -1791,7 +1872,7 @@ struct sm1_instruction +@@ -1791,7 +1876,7 @@ struct sm1_instruction struct sm1_dst_register { @@ -1034,7 +1086,7 @@ index bfd5b52b436..a4c038a233a 100644 D3DSHADER_PARAM_DSTMOD_TYPE mod; unsigned int writemask; uint32_t reg; -@@ -1799,19 +1880,45 @@ struct sm1_instruction +@@ -1799,19 +1884,45 @@ struct sm1_instruction struct sm1_src_register { @@ -1083,7 +1135,7 @@ index bfd5b52b436..a4c038a233a 100644 put_u32(buffer, (1u << 31) | sm1_encode_register_type(reg->type) | reg->mod | (reg->writemask << 16) | reg->reg); } -@@ -1821,15 +1928,19 @@ static void write_sm1_src_register(struct vkd3d_bytecode_buffer *buffer, +@@ -1821,15 +1932,19 @@ static void write_sm1_src_register(struct vkd3d_bytecode_buffer *buffer, put_u32(buffer, (1u << 31) | sm1_encode_register_type(reg->type) | reg->mod | (reg->swizzle << 16) | reg->reg); } @@ -1106,7 +1158,7 @@ index bfd5b52b436..a4c038a233a 100644 token |= (instr->has_dst + instr->src_count) << D3DSI_INSTLENGTH_SHIFT; put_u32(buffer, token); -@@ -1845,54 +1956,53 @@ static void sm1_map_src_swizzle(struct sm1_src_register *src, unsigned int map_w +@@ -1845,54 +1960,53 @@ static void sm1_map_src_swizzle(struct sm1_src_register *src, unsigned int map_w src->swizzle = hlsl_map_swizzle(src->swizzle, map_writemask); } @@ -1175,7 +1227,7 @@ index bfd5b52b436..a4c038a233a 100644 .srcs[2].swizzle = hlsl_swizzle_from_writemask(src3->writemask), .srcs[2].reg = src3->id, .src_count = 3, -@@ -1901,26 +2011,25 @@ static void write_sm1_ternary_op(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buf +@@ -1901,26 +2015,25 @@ static void write_sm1_ternary_op(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buf sm1_map_src_swizzle(&instr.srcs[0], instr.dst.writemask); sm1_map_src_swizzle(&instr.srcs[1], instr.dst.writemask); sm1_map_src_swizzle(&instr.srcs[2], instr.dst.writemask); @@ -1208,7 +1260,7 @@ index bfd5b52b436..a4c038a233a 100644 .srcs[1].swizzle = hlsl_swizzle_from_writemask(src2->writemask), .srcs[1].reg = src2->id, .src_count = 2, -@@ -1928,49 +2037,48 @@ static void write_sm1_binary_op(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buff +@@ -1928,49 +2041,48 @@ static void write_sm1_binary_op(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buff sm1_map_src_swizzle(&instr.srcs[0], instr.dst.writemask); sm1_map_src_swizzle(&instr.srcs[1], instr.dst.writemask); @@ -1270,7 +1322,7 @@ index bfd5b52b436..a4c038a233a 100644 .srcs[0].swizzle = hlsl_swizzle_from_writemask(src->writemask), .srcs[0].reg = src->id, .srcs[0].mod = src_mod, -@@ -1978,19 +2086,19 @@ static void write_sm1_unary_op(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffe +@@ -1978,19 +2090,19 @@ static void write_sm1_unary_op(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffe }; sm1_map_src_swizzle(&instr.srcs[0], instr.dst.writemask); @@ -1294,7 +1346,7 @@ index bfd5b52b436..a4c038a233a 100644 switch (dst_type->e.numeric.type) { -@@ -2004,7 +2112,7 @@ static void write_sm1_cast(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b +@@ -2004,7 +2116,7 @@ static void write_sm1_cast(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b /* Integrals are internally represented as floats, so no change is necessary.*/ case HLSL_TYPE_HALF: case HLSL_TYPE_FLOAT: @@ -1303,7 +1355,7 @@ index bfd5b52b436..a4c038a233a 100644 break; case HLSL_TYPE_DOUBLE: -@@ -2028,7 +2136,7 @@ static void write_sm1_cast(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b +@@ -2028,7 +2140,7 @@ static void write_sm1_cast(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b break; case HLSL_TYPE_INT: case HLSL_TYPE_UINT: @@ -1312,7 +1364,7 @@ index bfd5b52b436..a4c038a233a 100644 break; case HLSL_TYPE_BOOL: -@@ -2057,8 +2165,11 @@ static void write_sm1_cast(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b +@@ -2057,8 +2169,11 @@ static void write_sm1_cast(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b } } @@ -1325,7 +1377,7 @@ index bfd5b52b436..a4c038a233a 100644 unsigned int i, x; for (i = 0; i < ctx->constant_defs.count; ++i) -@@ -2067,12 +2178,12 @@ static void write_sm1_constant_defs(struct hlsl_ctx *ctx, struct vkd3d_bytecode_ +@@ -2067,12 +2182,12 @@ static void write_sm1_constant_defs(struct hlsl_ctx *ctx, struct vkd3d_bytecode_ uint32_t token = D3DSIO_DEF; const struct sm1_dst_register reg = { @@ -1340,7 +1392,7 @@ index bfd5b52b436..a4c038a233a 100644 token |= 5 << D3DSI_INSTLENGTH_SHIFT; put_u32(buffer, token); -@@ -2082,32 +2193,32 @@ static void write_sm1_constant_defs(struct hlsl_ctx *ctx, struct vkd3d_bytecode_ +@@ -2082,32 +2197,32 @@ static void write_sm1_constant_defs(struct hlsl_ctx *ctx, struct vkd3d_bytecode_ } } @@ -1384,7 +1436,7 @@ index bfd5b52b436..a4c038a233a 100644 token |= 2 << D3DSI_INSTLENGTH_SHIFT; put_u32(buffer, token); -@@ -2116,39 +2227,47 @@ static void write_sm1_semantic_dcl(struct hlsl_ctx *ctx, struct vkd3d_bytecode_b +@@ -2116,39 +2231,47 @@ static void write_sm1_semantic_dcl(struct hlsl_ctx *ctx, struct vkd3d_bytecode_b token |= usage_idx << D3DSP_DCL_USAGEINDEX_SHIFT; put_u32(buffer, token); @@ -1445,7 +1497,7 @@ index bfd5b52b436..a4c038a233a 100644 token |= 2 << D3DSI_INSTLENGTH_SHIFT; put_u32(buffer, token); -@@ -2175,20 +2294,22 @@ static void write_sm1_sampler_dcl(struct hlsl_ctx *ctx, struct vkd3d_bytecode_bu +@@ -2175,20 +2298,22 @@ static void write_sm1_sampler_dcl(struct hlsl_ctx *ctx, struct vkd3d_bytecode_bu token |= res_type << VKD3D_SM1_RESOURCE_TYPE_SHIFT; put_u32(buffer, token); @@ -1471,7 +1523,7 @@ index bfd5b52b436..a4c038a233a 100644 return; LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) -@@ -2210,39 +2331,38 @@ static void write_sm1_sampler_dcls(struct hlsl_ctx *ctx, struct vkd3d_bytecode_b +@@ -2210,39 +2335,38 @@ static void write_sm1_sampler_dcls(struct hlsl_ctx *ctx, struct vkd3d_bytecode_b continue; } @@ -1520,7 +1572,7 @@ index bfd5b52b436..a4c038a233a 100644 const struct hlsl_ir_node *instr, D3DSHADER_INSTRUCTION_OPCODE_TYPE opcode) { struct hlsl_ir_expr *expr = hlsl_ir_expr(instr); -@@ -2255,28 +2375,69 @@ static void write_sm1_per_component_unary_op(struct hlsl_ctx *ctx, struct vkd3d_ +@@ -2255,28 +2379,69 @@ static void write_sm1_per_component_unary_op(struct hlsl_ctx *ctx, struct vkd3d_ src.writemask = hlsl_combine_writemasks(src.writemask, 1u << i); dst.writemask = hlsl_combine_writemasks(dst.writemask, 1u << i); @@ -1595,7 +1647,7 @@ index bfd5b52b436..a4c038a233a 100644 return; } -@@ -2290,70 +2451,75 @@ static void write_sm1_expr(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b +@@ -2290,70 +2455,75 @@ static void write_sm1_expr(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b switch (expr->op) { case HLSL_OP1_ABS: @@ -1687,7 +1739,7 @@ index bfd5b52b436..a4c038a233a 100644 break; default: -@@ -2362,27 +2528,31 @@ static void write_sm1_expr(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b +@@ -2362,27 +2532,31 @@ static void write_sm1_expr(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b break; case HLSL_OP2_LOGIC_AND: @@ -1726,7 +1778,7 @@ index bfd5b52b436..a4c038a233a 100644 break; default: -@@ -2391,50 +2561,49 @@ static void write_sm1_expr(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b +@@ -2391,50 +2565,49 @@ static void write_sm1_expr(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b } } @@ -1788,7 +1840,7 @@ index bfd5b52b436..a4c038a233a 100644 { const struct hlsl_ir_jump *jump = hlsl_ir_jump(instr); -@@ -2448,54 +2617,55 @@ static void write_sm1_jump(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b +@@ -2448,54 +2621,55 @@ static void write_sm1_jump(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b { .opcode = D3DSIO_TEXKILL, @@ -1857,7 +1909,7 @@ index bfd5b52b436..a4c038a233a 100644 sm1_instr.srcs[0].reg = reg.id; } else -@@ -2503,32 +2673,34 @@ static void write_sm1_load(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b +@@ -2503,32 +2677,34 @@ static void write_sm1_load(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b } sm1_map_src_swizzle(&sm1_instr.srcs[0], sm1_instr.dst.writemask); @@ -1900,7 +1952,7 @@ index bfd5b52b436..a4c038a233a 100644 .srcs[1].reg = reg_id, .srcs[1].swizzle = hlsl_swizzle_from_writemask(VKD3DSP_WRITEMASK_ALL), -@@ -2546,69 +2718,82 @@ static void write_sm1_resource_load(struct hlsl_ctx *ctx, struct vkd3d_bytecode_ +@@ -2546,69 +2722,82 @@ static void write_sm1_resource_load(struct hlsl_ctx *ctx, struct vkd3d_bytecode_ sm1_instr.opcode |= VKD3DSI_TEXLD_PROJECT << VKD3D_SM1_INSTRUCTION_FLAGS_SHIFT; break; @@ -2006,7 +2058,7 @@ index bfd5b52b436..a4c038a233a 100644 { const struct hlsl_ir_swizzle *swizzle = hlsl_ir_swizzle(instr); const struct hlsl_ir_node *val = swizzle->val.node; -@@ -2616,27 +2801,27 @@ static void write_sm1_swizzle(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer +@@ -2616,27 +2805,27 @@ static void write_sm1_swizzle(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer { .opcode = D3DSIO_MOV, @@ -2041,7 +2093,7 @@ index bfd5b52b436..a4c038a233a 100644 const struct hlsl_ir_node *instr; LIST_FOR_EACH_ENTRY(instr, &block->instrs, struct hlsl_ir_node, entry) -@@ -2656,38 +2841,38 @@ static void write_sm1_block(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer * +@@ -2656,38 +2845,38 @@ static void write_sm1_block(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer * vkd3d_unreachable(); case HLSL_IR_CONSTANT: @@ -2088,7 +2140,7 @@ index bfd5b52b436..a4c038a233a 100644 break; default: -@@ -2696,32 +2881,45 @@ static void write_sm1_block(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer * +@@ -2696,32 +2885,45 @@ static void write_sm1_block(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer * } } @@ -2180,7 +2232,7 @@ index 4b9f67235aa..184788dc57e 100644 } diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c -index 73a8d8687c5..2a0bbe1a625 100644 +index 73a8d8687c5..4a17c62292b 100644 --- a/libs/vkd3d/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c @@ -458,6 +458,8 @@ enum dx_intrinsic_opcode @@ -2329,6 +2381,15 @@ index 73a8d8687c5..2a0bbe1a625 100644 param->reg.idx[count++].offset = i; param->reg.idx_count = count; } +@@ -4289,7 +4298,7 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco + if (!(flags & FP_ALLOW_UNSAFE_ALGEBRA)) + ins->flags |= VKD3DSI_PRECISE_X; + flags &= ~FP_ALLOW_UNSAFE_ALGEBRA; +- /* SPIR-V FPFastMathMode is only available in the Kernel executon model. */ ++ /* SPIR-V FPFastMathMode is only available in the Kernel execution model. */ + silence_warning = !(flags & ~(FP_NO_NAN | FP_NO_INF | FP_NO_SIGNED_ZEROS | FP_ALLOW_RECIPROCAL)); + break; + case VKD3DSIH_IADD: @@ -4402,7 +4411,7 @@ static void sm6_parser_emit_br(struct sm6_parser *sm6, const struct dxil_record code_block->terminator.false_block = sm6_function_get_block(function, record->operands[1], sm6); } @@ -2369,6 +2430,15 @@ index 73a8d8687c5..2a0bbe1a625 100644 } static void sm6_parser_emit_dx_stream(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, +@@ -5200,7 +5211,7 @@ static void sm6_parser_emit_dx_get_dimensions(struct sm6_parser *sm6, enum dx_in + instruction_dst_param_init_temp_vector(ins++, sm6); + state->temp_idx = 1; + +- /* DXIL does not have an instrinsic for sample info, and resinfo is expected to return ++ /* DXIL does not have an intrinsic for sample info, and resinfo is expected to return + * the sample count in .w for MS textures. The result is always a struct of 4 x uint32. */ + vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_SAMPLE_INFO); + ins->flags = VKD3DSI_SAMPLE_INFO_UINT; @@ -5331,7 +5342,7 @@ static void sm6_parser_emit_dx_load_input(struct sm6_parser *sm6, enum dx_intrin if (!is_patch_constant && !operands[3]->is_undefined) @@ -2698,7 +2768,7 @@ index 73a8d8687c5..2a0bbe1a625 100644 vkd3d_free(byte_code); diff --git a/libs/vkd3d/libs/vkd3d-shader/fx.c b/libs/vkd3d/libs/vkd3d-shader/fx.c -index 57b4ac24212..e3ebbafb3f4 100644 +index 57b4ac24212..a1d1fd6572f 100644 --- a/libs/vkd3d/libs/vkd3d-shader/fx.c +++ b/libs/vkd3d/libs/vkd3d-shader/fx.c @@ -56,6 +56,114 @@ static void string_storage_destroy(struct rb_entry *entry, void *context) @@ -2760,7 +2830,7 @@ index 57b4ac24212..e3ebbafb3f4 100644 +{ + unsigned int i; + -+ assert(comp_count <= info->max_args); ++ VKD3D_ASSERT(comp_count <= info->max_args); + + if (info->min_args == info->max_args) + { @@ -2824,16 +2894,18 @@ index 57b4ac24212..e3ebbafb3f4 100644 bool are_child_effects_supported; }; -@@ -94,6 +203,8 @@ struct fx_write_context +@@ -94,6 +203,10 @@ struct fx_write_context uint32_t texture_count; uint32_t uav_count; uint32_t sampler_state_count; + uint32_t depth_stencil_state_count; + uint32_t rasterizer_state_count; ++ uint32_t blend_state_count; ++ uint32_t string_count; int status; bool child_effect; -@@ -122,14 +233,46 @@ static uint32_t write_string(const char *string, struct fx_write_context *fx) +@@ -122,14 +235,46 @@ static uint32_t write_string(const char *string, struct fx_write_context *fx) static void write_pass(struct hlsl_ir_var *var, struct fx_write_context *fx) { @@ -2883,7 +2955,7 @@ index 57b4ac24212..e3ebbafb3f4 100644 static uint32_t write_type(const struct hlsl_type *type, struct fx_write_context *fx) { -@@ -138,7 +281,7 @@ static uint32_t write_type(const struct hlsl_type *type, struct fx_write_context +@@ -138,7 +283,7 @@ static uint32_t write_type(const struct hlsl_type *type, struct fx_write_context unsigned int elements_count; const char *name; @@ -2892,7 +2964,7 @@ index 57b4ac24212..e3ebbafb3f4 100644 if (type->class == HLSL_CLASS_ARRAY) { -@@ -274,15 +417,14 @@ static uint32_t write_fx_4_string(const char *string, struct fx_write_context *f +@@ -274,15 +419,14 @@ static uint32_t write_fx_4_string(const char *string, struct fx_write_context *f static void write_fx_4_pass(struct hlsl_ir_var *var, struct fx_write_context *fx) { struct vkd3d_bytecode_buffer *buffer = &fx->structured; @@ -2912,7 +2984,7 @@ index 57b4ac24212..e3ebbafb3f4 100644 } static void write_fx_2_pass(struct hlsl_ir_var *var, struct fx_write_context *fx) -@@ -297,6 +439,12 @@ static void write_fx_2_pass(struct hlsl_ir_var *var, struct fx_write_context *fx +@@ -297,6 +441,12 @@ static void write_fx_2_pass(struct hlsl_ir_var *var, struct fx_write_context *fx /* TODO: annotations */ /* TODO: assignments */ @@ -2925,7 +2997,7 @@ index 57b4ac24212..e3ebbafb3f4 100644 } static uint32_t get_fx_4_type_size(const struct hlsl_type *type) -@@ -402,6 +550,9 @@ static const char * get_fx_4_type_name(const struct hlsl_type *type) +@@ -402,6 +552,9 @@ static const char * get_fx_4_type_name(const struct hlsl_type *type) case HLSL_CLASS_UAV: return uav_type_names[type->sampler_dim]; @@ -2935,7 +3007,17 @@ index 57b4ac24212..e3ebbafb3f4 100644 case HLSL_CLASS_DEPTH_STENCIL_VIEW: return "DepthStencilView"; -@@ -421,10 +572,20 @@ static const char * get_fx_4_type_name(const struct hlsl_type *type) +@@ -414,6 +567,9 @@ static const char * get_fx_4_type_name(const struct hlsl_type *type) + case HLSL_CLASS_PIXEL_SHADER: + return "PixelShader"; + ++ case HLSL_CLASS_STRING: ++ return "String"; ++ + default: + return type->name; + } +@@ -421,10 +577,20 @@ static const char * get_fx_4_type_name(const struct hlsl_type *type) static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_context *fx) { @@ -2957,7 +3039,7 @@ index 57b4ac24212..e3ebbafb3f4 100644 /* Resolve arrays to element type and number of elements. */ if (type->class == HLSL_CLASS_ARRAY) -@@ -436,6 +597,22 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co +@@ -436,6 +602,22 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co name = get_fx_4_type_name(type); name_offset = write_string(name, fx); @@ -2980,7 +3062,7 @@ index 57b4ac24212..e3ebbafb3f4 100644 offset = put_u32_unaligned(buffer, name_offset); switch (type->class) -@@ -446,13 +623,19 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co +@@ -446,13 +628,21 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co put_u32_unaligned(buffer, 1); break; @@ -2997,18 +3079,23 @@ index 57b4ac24212..e3ebbafb3f4 100644 + case HLSL_CLASS_DOMAIN_SHADER: + case HLSL_CLASS_HULL_SHADER: + case HLSL_CLASS_GEOMETRY_SHADER: ++ case HLSL_CLASS_BLEND_STATE: ++ case HLSL_CLASS_STRING: put_u32_unaligned(buffer, 2); break; -@@ -464,6 +647,7 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co +@@ -464,43 +654,50 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co case HLSL_CLASS_EFFECT_GROUP: case HLSL_CLASS_PASS: case HLSL_CLASS_TECHNIQUE: + case HLSL_CLASS_CONSTANT_BUFFER: ++ case HLSL_CLASS_NULL: vkd3d_unreachable(); - case HLSL_CLASS_STRING: -@@ -473,34 +657,40 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co +- case HLSL_CLASS_STRING: + case HLSL_CLASS_VOID: + FIXME("Writing type class %u is not implemented.\n", type->class); + set_status(fx, VKD3D_ERROR_NOT_IMPLEMENTED); return 0; } @@ -3065,7 +3152,7 @@ index 57b4ac24212..e3ebbafb3f4 100644 } } else if (type->class == HLSL_CLASS_TEXTURE) -@@ -556,18 +746,38 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co +@@ -556,18 +753,46 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co { put_u32_unaligned(buffer, 6); } @@ -3076,6 +3163,14 @@ index 57b4ac24212..e3ebbafb3f4 100644 + else if (type->class == HLSL_CLASS_DEPTH_STENCIL_STATE) + { + put_u32_unaligned(buffer, 3); ++ } ++ else if (type->class == HLSL_CLASS_BLEND_STATE) ++ { ++ put_u32_unaligned(buffer, 2); ++ } ++ else if (type->class == HLSL_CLASS_STRING) ++ { ++ put_u32_unaligned(buffer, 1); + } else if (hlsl_is_numeric_type(type)) { @@ -3105,7 +3200,7 @@ index 57b4ac24212..e3ebbafb3f4 100644 return offset; } -@@ -581,8 +791,9 @@ static void write_fx_4_technique(struct hlsl_ir_var *var, struct fx_write_contex +@@ -581,8 +806,9 @@ static void write_fx_4_technique(struct hlsl_ir_var *var, struct fx_write_contex name_offset = write_string(var->name, fx); put_u32(buffer, name_offset); count_offset = put_u32(buffer, 0); @@ -3116,7 +3211,7 @@ index 57b4ac24212..e3ebbafb3f4 100644 LIST_FOR_EACH_ENTRY(pass, &var->scope->vars, struct hlsl_ir_var, scope_entry) { write_pass(pass, fx); -@@ -617,7 +828,7 @@ static void write_group(struct hlsl_ir_var *var, struct fx_write_context *fx) +@@ -617,7 +843,7 @@ static void write_group(struct hlsl_ir_var *var, struct fx_write_context *fx) put_u32(buffer, name_offset); count_offset = put_u32(buffer, 0); /* Technique count */ @@ -3125,7 +3220,21 @@ index 57b4ac24212..e3ebbafb3f4 100644 count = fx->technique_count; write_techniques(var ? var->scope : fx->ctx->globals, fx); -@@ -683,7 +894,7 @@ static uint32_t write_fx_2_parameter(const struct hlsl_type *type, const char *n +@@ -668,6 +894,13 @@ static uint32_t write_fx_2_string(const char *string, struct fx_write_context *f + return offset; + } + ++static uint32_t get_fx_2_type_class(const struct hlsl_type *type) ++{ ++ if (type->class == HLSL_CLASS_MATRIX) ++ return D3DXPC_MATRIX_ROWS; ++ return hlsl_sm1_class(type); ++} ++ + static uint32_t write_fx_2_parameter(const struct hlsl_type *type, const char *name, const struct hlsl_semantic *semantic, + struct fx_write_context *fx) + { +@@ -683,10 +916,10 @@ static uint32_t write_fx_2_parameter(const struct hlsl_type *type, const char *n } name_offset = write_string(name, fx); @@ -3133,8 +3242,12 @@ index 57b4ac24212..e3ebbafb3f4 100644 + semantic_offset = semantic->raw_name ? write_string(semantic->raw_name, fx) : 0; offset = put_u32(buffer, hlsl_sm1_base_type(type)); - put_u32(buffer, hlsl_sm1_class(type)); -@@ -705,6 +916,10 @@ static uint32_t write_fx_2_parameter(const struct hlsl_type *type, const char *n +- put_u32(buffer, hlsl_sm1_class(type)); ++ put_u32(buffer, get_fx_2_type_class(type)); + put_u32(buffer, name_offset); + put_u32(buffer, semantic_offset); + put_u32(buffer, elements_count); +@@ -705,6 +938,10 @@ static uint32_t write_fx_2_parameter(const struct hlsl_type *type, const char *n case HLSL_CLASS_STRUCT: put_u32(buffer, type->e.record.field_count); break; @@ -3145,7 +3258,7 @@ index 57b4ac24212..e3ebbafb3f4 100644 default: ; } -@@ -716,7 +931,7 @@ static uint32_t write_fx_2_parameter(const struct hlsl_type *type, const char *n +@@ -716,7 +953,7 @@ static uint32_t write_fx_2_parameter(const struct hlsl_type *type, const char *n const struct hlsl_struct_field *field = &type->e.record.fields[i]; /* Validated in check_invalid_object_fields(). */ @@ -3154,7 +3267,7 @@ index 57b4ac24212..e3ebbafb3f4 100644 write_fx_2_parameter(field->type, field->name, &field->semantic, fx); } } -@@ -794,6 +1009,9 @@ static uint32_t write_fx_2_initial_value(const struct hlsl_ir_var *var, struct f +@@ -794,6 +1031,9 @@ static uint32_t write_fx_2_initial_value(const struct hlsl_ir_var *var, struct f case HLSL_CLASS_MATRIX: case HLSL_CLASS_STRUCT: /* FIXME: write actual initial value */ @@ -3164,7 +3277,7 @@ index 57b4ac24212..e3ebbafb3f4 100644 offset = put_u32(buffer, 0); for (uint32_t i = 1; i < size / sizeof(uint32_t); ++i) -@@ -850,15 +1068,22 @@ static bool is_type_supported_fx_2(struct hlsl_ctx *ctx, const struct hlsl_type +@@ -850,15 +1090,24 @@ static bool is_type_supported_fx_2(struct hlsl_ctx *ctx, const struct hlsl_type hlsl_fixme(ctx, loc, "Write fx 2.0 parameter class %#x.", type->class); return false; @@ -3178,16 +3291,18 @@ index 57b4ac24212..e3ebbafb3f4 100644 + case HLSL_CLASS_DOMAIN_SHADER: + case HLSL_CLASS_HULL_SHADER: + case HLSL_CLASS_GEOMETRY_SHADER: ++ case HLSL_CLASS_BLEND_STATE: return false; case HLSL_CLASS_EFFECT_GROUP: case HLSL_CLASS_PASS: case HLSL_CLASS_TECHNIQUE: + case HLSL_CLASS_CONSTANT_BUFFER: ++ case HLSL_CLASS_NULL: /* This cannot appear as an extern variable. */ break; } -@@ -910,7 +1135,7 @@ static const struct fx_write_context_ops fx_2_ops = +@@ -910,7 +1159,7 @@ static const struct fx_write_context_ops fx_2_ops = static int hlsl_fx_2_write(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out) { @@ -3196,7 +3311,7 @@ index 57b4ac24212..e3ebbafb3f4 100644 struct vkd3d_bytecode_buffer buffer = { 0 }; struct vkd3d_bytecode_buffer *structured; struct fx_write_context fx; -@@ -927,7 +1152,7 @@ static int hlsl_fx_2_write(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out) +@@ -927,7 +1176,7 @@ static int hlsl_fx_2_write(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out) parameter_count = put_u32(structured, 0); /* Parameter count */ technique_count = put_u32(structured, 0); @@ -3205,7 +3320,7 @@ index 57b4ac24212..e3ebbafb3f4 100644 object_count = put_u32(structured, 0); write_fx_2_parameters(&fx); -@@ -936,6 +1161,7 @@ static int hlsl_fx_2_write(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out) +@@ -936,6 +1185,7 @@ static int hlsl_fx_2_write(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out) write_techniques(ctx->globals, &fx); set_u32(structured, technique_count, fx.technique_count); @@ -3213,7 +3328,7 @@ index 57b4ac24212..e3ebbafb3f4 100644 put_u32(structured, 0); /* String count */ put_u32(structured, 0); /* Resource count */ -@@ -972,9 +1198,72 @@ static const struct fx_write_context_ops fx_4_ops = +@@ -972,9 +1222,93 @@ static const struct fx_write_context_ops fx_4_ops = .write_string = write_fx_4_string, .write_technique = write_fx_4_technique, .write_pass = write_fx_4_pass, @@ -3253,7 +3368,7 @@ index 57b4ac24212..e3ebbafb3f4 100644 + + for (j = 0; j < comp_count; ++j) + { -+ put_u32_unaligned(buffer, value->value.u); ++ put_u32_unaligned(buffer, value->number.u); + value++; + } + break; @@ -3282,11 +3397,32 @@ index 57b4ac24212..e3ebbafb3f4 100644 + + return offset; +} ++ ++static void write_fx_4_string_initializer(struct hlsl_ir_var *var, struct fx_write_context *fx) ++{ ++ uint32_t elements_count = hlsl_get_multiarray_size(var->data_type), i; ++ const struct hlsl_default_value *value = var->default_values; ++ struct vkd3d_bytecode_buffer *buffer = &fx->structured; ++ struct hlsl_ctx *ctx = fx->ctx; ++ uint32_t offset; ++ ++ if (!value) ++ { ++ hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "String objects have to be initialized."); ++ return; ++ } ++ ++ for (i = 0; i < elements_count; ++i, ++value) ++ { ++ offset = write_fx_4_string(value->string, fx); ++ put_u32(buffer, offset); ++ } ++} + static void write_fx_4_numeric_variable(struct hlsl_ir_var *var, bool shared, struct fx_write_context *fx) { struct vkd3d_bytecode_buffer *buffer = &fx->structured; -@@ -984,22 +1273,20 @@ static void write_fx_4_numeric_variable(struct hlsl_ir_var *var, bool shared, st +@@ -984,22 +1318,20 @@ static void write_fx_4_numeric_variable(struct hlsl_ir_var *var, bool shared, st { HAS_EXPLICIT_BIND_POINT = 0x4, }; @@ -3313,7 +3449,7 @@ index 57b4ac24212..e3ebbafb3f4 100644 put_u32(buffer, flags); /* Flags */ if (shared) -@@ -1008,17 +1295,39 @@ static void write_fx_4_numeric_variable(struct hlsl_ir_var *var, bool shared, st +@@ -1008,17 +1340,43 @@ static void write_fx_4_numeric_variable(struct hlsl_ir_var *var, bool shared, st } else { @@ -3349,6 +3485,10 @@ index 57b4ac24212..e3ebbafb3f4 100644 + offset = write_fx_4_default_value(var->data_type, var->default_values, fx); + put_u32(buffer, offset); + } ++ else if (type->class == HLSL_CLASS_STRING) ++ { ++ write_fx_4_string_initializer(var, fx); ++ } + else + { + hlsl_fixme(ctx, &var->loc, "Writing annotations for type class %u is not implemented.", type->class); @@ -3358,7 +3498,7 @@ index 57b4ac24212..e3ebbafb3f4 100644 struct rhs_named_value { const char *name; -@@ -1086,11 +1395,8 @@ static void write_fx_4_state_assignment(const struct hlsl_ir_var *var, struct hl +@@ -1086,11 +1444,8 @@ static void write_fx_4_state_assignment(const struct hlsl_ir_var *var, struct hl struct hlsl_ctx *ctx = fx->ctx; struct hlsl_ir_node *value = entry->args->node; @@ -3371,7 +3511,7 @@ index 57b4ac24212..e3ebbafb3f4 100644 type_offset = put_u32(buffer, 0); rhs_offset = put_u32(buffer, 0); -@@ -1104,6 +1410,17 @@ static void write_fx_4_state_assignment(const struct hlsl_ir_var *var, struct hl +@@ -1104,6 +1459,17 @@ static void write_fx_4_state_assignment(const struct hlsl_ir_var *var, struct hl assignment_type = 1; break; } @@ -3389,31 +3529,68 @@ index 57b4ac24212..e3ebbafb3f4 100644 default: hlsl_fixme(ctx, &var->loc, "Unsupported assignment type for state %s.", entry->name); } -@@ -1118,6 +1435,9 @@ static bool state_block_contains_state(const char *name, unsigned int start, str +@@ -1112,14 +1478,28 @@ static void write_fx_4_state_assignment(const struct hlsl_ir_var *var, struct hl + set_u32(buffer, rhs_offset, value_offset); + } - for (i = start; i < block->count; ++i) +-static bool state_block_contains_state(const char *name, unsigned int start, struct hlsl_state_block *block) ++static bool state_block_contains_state(const struct hlsl_state_block_entry *entry, unsigned int start_index, ++ struct hlsl_state_block *block) + { + unsigned int i; + +- for (i = start; i < block->count; ++i) ++ for (i = start_index; i < block->count; ++i) { -+ if (block->entries[i]->is_function_call) +- if (!ascii_strcasecmp(block->entries[i]->name, name)) +- return true; ++ const struct hlsl_state_block_entry *cur = block->entries[i]; ++ ++ if (cur->is_function_call) + continue; + - if (!ascii_strcasecmp(block->entries[i]->name, name)) - return true; ++ if (ascii_strcasecmp(cur->name, entry->name)) ++ continue; ++ ++ if (cur->lhs_has_index != entry->lhs_has_index) ++ continue; ++ ++ if (cur->lhs_has_index && cur->lhs_index != entry->lhs_index) ++ continue; ++ ++ return true; } -@@ -1160,6 +1480,92 @@ static bool replace_state_block_constant(struct hlsl_ctx *ctx, struct hlsl_ir_no + + return false; +@@ -1131,6 +1511,24 @@ struct replace_state_context + struct hlsl_ir_var *var; + }; + ++static bool lower_null_constant(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) ++{ ++ struct hlsl_ir_node *c; ++ ++ if (instr->type != HLSL_IR_CONSTANT) ++ return false; ++ if (instr->data_type->class != HLSL_CLASS_NULL) ++ return false; ++ ++ if (!(c = hlsl_new_uint_constant(ctx, 0, &instr->loc))) ++ return false; ++ ++ list_add_before(&instr->entry, &c->entry); ++ hlsl_replace_node(instr, c); ++ ++ return true; ++} ++ + static bool replace_state_block_constant(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) + { + struct replace_state_context *replace_context = context; +@@ -1160,6 +1558,93 @@ static bool replace_state_block_constant(struct hlsl_ctx *ctx, struct hlsl_ir_no return true; } -+static void fold_state_value(struct hlsl_ctx *ctx, struct hlsl_state_block_entry *entry) -+{ -+ bool progress; -+ -+ do -+ { -+ progress = hlsl_transform_ir(ctx, hlsl_fold_constant_exprs, entry->instrs, NULL); -+ progress |= hlsl_copy_propagation_execute(ctx, entry->instrs); -+ } while (progress); -+} -+ +enum state_property_component_type +{ + FX_BOOL, @@ -3428,6 +3605,9 @@ index 57b4ac24212..e3ebbafb3f4 100644 + FX_TEXTURE, + FX_DEPTHSTENCILVIEW, + FX_RENDERTARGETVIEW, ++ FX_BLEND, ++ FX_VERTEXSHADER, ++ FX_PIXELSHADER, +}; + +static inline bool is_object_fx_type(enum state_property_component_type type) @@ -3442,6 +3622,9 @@ index 57b4ac24212..e3ebbafb3f4 100644 + case FX_TEXTURE: + case FX_RENDERTARGETVIEW: + case FX_DEPTHSTENCILVIEW: ++ case FX_BLEND: ++ case FX_VERTEXSHADER: ++ case FX_PIXELSHADER: + return true; + default: + return false; @@ -3468,6 +3651,12 @@ index 57b4ac24212..e3ebbafb3f4 100644 + return HLSL_CLASS_RENDER_TARGET_VIEW; + case FX_DEPTHSTENCILVIEW: + return HLSL_CLASS_DEPTH_STENCIL_VIEW; ++ case FX_BLEND: ++ return HLSL_CLASS_BLEND_STATE; ++ case FX_VERTEXSHADER: ++ return HLSL_CLASS_VERTEX_SHADER; ++ case FX_PIXELSHADER: ++ return HLSL_CLASS_PIXEL_SHADER; + default: + vkd3d_unreachable(); + } @@ -3492,7 +3681,7 @@ index 57b4ac24212..e3ebbafb3f4 100644 static void resolve_fx_4_state_block_values(struct hlsl_ir_var *var, struct hlsl_state_block_entry *entry, struct fx_write_context *fx) { -@@ -1209,37 +1615,126 @@ static void resolve_fx_4_state_block_values(struct hlsl_ir_var *var, struct hlsl +@@ -1209,44 +1694,233 @@ static void resolve_fx_4_state_block_values(struct hlsl_ir_var *var, struct hlsl { NULL } }; @@ -3543,6 +3732,51 @@ index 57b4ac24212..e3ebbafb3f4 100644 + { "BACK", 3 }, + { NULL } + }; ++ ++ static const struct rhs_named_value blend_values[] = ++ { ++ { "ZERO", 1 }, ++ { "ONE", 2 }, ++ { "SRC_COLOR", 3 }, ++ { "INV_SRC_COLOR", 4 }, ++ { "SRC_ALPHA", 5 }, ++ { "INV_SRC_ALPHA", 6 }, ++ { "DEST_ALPHA", 7 }, ++ { "INV_DEST_ALPHA", 8 }, ++ { "DEST_COLOR", 9 }, ++ { "INV_DEST_COLOR", 10 }, ++ { "SRC_ALPHA_SAT", 11 }, ++ { "BLEND_FACTOR", 14 }, ++ { "INV_BLEND_FACTOR", 15 }, ++ { "SRC1_COLOR", 16 }, ++ { "INV_SRC1_COLOR", 17 }, ++ { "SRC1_ALPHA", 18 }, ++ { "INV_SRC1_ALPHA", 19 }, ++ { NULL } ++ }; ++ ++ static const struct rhs_named_value blendop_values[] = ++ { ++ { "ADD", 1 }, ++ { "SUBTRACT", 2 }, ++ { "REV_SUBTRACT", 3 }, ++ { "MIN", 4 }, ++ { "MAX", 5 }, ++ { NULL } ++ }; ++ ++ static const struct rhs_named_value bool_values[] = ++ { ++ { "FALSE", 0 }, ++ { "TRUE", 1 }, ++ { NULL } ++ }; ++ ++ static const struct rhs_named_value null_values[] = ++ { ++ { "NULL", 0 }, ++ { NULL } ++ }; + static const struct state { @@ -3569,29 +3803,33 @@ index 57b4ac24212..e3ebbafb3f4 100644 - { "MinLOD", HLSL_CLASS_SAMPLER, HLSL_TYPE_FLOAT, 1, 53 }, - { "MaxLOD", HLSL_CLASS_SAMPLER, HLSL_TYPE_FLOAT, 1, 54 }, - /* TODO: "Texture" field */ -+ { "RasterizerState", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_RASTERIZER, 1, 1, 0 }, -+ { "DepthStencilState", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_DEPTHSTENCIL, 1, 1, 1 }, -+ ++ { "RasterizerState", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_RASTERIZER, 1, 1, 0 }, ++ { "DepthStencilState", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_DEPTHSTENCIL, 1, 1, 1 }, ++ { "BlendState", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_BLEND, 1, 1, 2 }, + { "RenderTargetView", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_RENDERTARGETVIEW, 1, 8, 3 }, + { "DepthStencilView", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_DEPTHSTENCILVIEW, 1, 1, 4 }, + -+ { "DS_StencilRef", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 9 }, ++ { "VertexShader", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_VERTEXSHADER, 1, 1, 6 }, ++ { "PixelShader", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_PIXELSHADER, 1, 1, 7 }, ++ { "DS_StencilRef", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 9 }, ++ { "AB_BlendFactor", HLSL_CLASS_PASS, HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 10 }, ++ { "AB_SampleMask", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 11 }, + + { "FillMode", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 12, fill_values }, + { "CullMode", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 13, cull_values }, -+ { "FrontCounterClockwise", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 14 }, ++ { "FrontCounterClockwise", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 14, bool_values }, + { "DepthBias", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 15 }, + { "DepthBiasClamp", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 16 }, + { "SlopeScaledDepthBias", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 17 }, -+ { "DepthClipEnable", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 18 }, -+ { "ScissorEnable", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 19 }, -+ { "MultisampleEnable", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 20 }, -+ { "AntializedLineEnable", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 21 }, ++ { "DepthClipEnable", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 18, bool_values }, ++ { "ScissorEnable", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 19, bool_values }, ++ { "MultisampleEnable", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 20, bool_values }, ++ { "AntializedLineEnable", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 21, bool_values }, + -+ { "DepthEnable", HLSL_CLASS_DEPTH_STENCIL_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 22 }, ++ { "DepthEnable", HLSL_CLASS_DEPTH_STENCIL_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 22, bool_values }, + { "DepthWriteMask", HLSL_CLASS_DEPTH_STENCIL_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 23, depth_write_mask_values }, + { "DepthFunc", HLSL_CLASS_DEPTH_STENCIL_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 24, comparison_values }, -+ { "StencilEnable", HLSL_CLASS_DEPTH_STENCIL_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 25 }, ++ { "StencilEnable", HLSL_CLASS_DEPTH_STENCIL_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 25, bool_values }, + { "StencilReadMask", HLSL_CLASS_DEPTH_STENCIL_STATE, HLSL_CLASS_SCALAR, FX_UINT8, 1, 1, 26 }, + { "StencilWriteMask", HLSL_CLASS_DEPTH_STENCIL_STATE, HLSL_CLASS_SCALAR, FX_UINT8, 1, 1, 27 }, + { "FrontFaceStencilFail", HLSL_CLASS_DEPTH_STENCIL_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 28, stencil_op_values }, @@ -3613,12 +3851,45 @@ index 57b4ac24212..e3ebbafb3f4 100644 + { "BorderColor", HLSL_CLASS_SAMPLER, HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 52 }, + { "MinLOD", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 53 }, + { "MaxLOD", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 54 }, -+ { "Texture", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_TEXTURE, 1, 1, 55 }, ++ { "Texture", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_TEXTURE, 1, 1, 55, null_values }, + + { "HullShader", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_HULLSHADER, 1, 1, 56 }, + { "DomainShader", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_DOMAINSHADER, 1, 1, 57 }, + { "ComputeShader", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_COMPUTESHADER, 1, 1, 58 }, }; ++ ++ static const struct state fx_4_blend_states[] = ++ { ++ { "AlphaToCoverageEnable", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 36, bool_values }, ++ { "BlendEnable", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 8, 37, bool_values }, ++ { "SrcBlend", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 38, blend_values }, ++ { "DestBlend", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 39, blend_values }, ++ { "BlendOp", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 40, blendop_values }, ++ { "SrcBlendAlpha", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 41, blend_values }, ++ { "DestBlendAlpha", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 42, blend_values }, ++ { "BlendOpAlpha", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 43, blendop_values }, ++ { "RenderTargetWriteMask", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT8, 1, 8, 44 }, ++ }; ++ ++ static const struct state fx_5_blend_states[] = ++ { ++ { "AlphaToCoverageEnable", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 36, bool_values }, ++ { "BlendEnable", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 8, 37, bool_values }, ++ { "SrcBlend", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 38, blend_values }, ++ { "DestBlend", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 39, blend_values }, ++ { "BlendOp", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 40, blendop_values }, ++ { "SrcBlendAlpha", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 41, blend_values }, ++ { "DestBlendAlpha", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 42, blend_values }, ++ { "BlendOpAlpha", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 43, blendop_values }, ++ { "RenderTargetWriteMask", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT8, 1, 8, 44 }, ++ }; ++ ++ struct state_table ++ { ++ const struct state *ptr; ++ unsigned int count; ++ } table; ++ const struct hlsl_type *type = hlsl_get_multiarray_element_type(var->data_type); struct replace_state_context replace_context; + struct hlsl_type *state_type = NULL; @@ -3627,13 +3898,42 @@ index 57b4ac24212..e3ebbafb3f4 100644 struct hlsl_ctx *ctx = fx->ctx; - struct hlsl_type *state_type; + enum hlsl_base_type base_type; -+ struct hlsl_ir_load *load; unsigned int i; - bool progress; - for (i = 0; i < ARRAY_SIZE(states); ++i) +- for (i = 0; i < ARRAY_SIZE(states); ++i) ++ if (type->class == HLSL_CLASS_BLEND_STATE) { -@@ -1264,69 +1759,240 @@ static void resolve_fx_4_state_block_values(struct hlsl_ir_var *var, struct hlsl +- if (type->class == states[i].container +- && !ascii_strcasecmp(entry->name, states[i].name)) ++ if (ctx->profile->major_version == 4) ++ { ++ table.ptr = fx_4_blend_states; ++ table.count = ARRAY_SIZE(fx_4_blend_states); ++ } ++ else + { +- state = &states[i]; ++ table.ptr = fx_5_blend_states; ++ table.count = ARRAY_SIZE(fx_5_blend_states); ++ } ++ } ++ else ++ { ++ table.ptr = states; ++ table.count = ARRAY_SIZE(states); ++ } ++ ++ for (i = 0; i < table.count; ++i) ++ { ++ if (type->class == table.ptr[i].container ++ && !ascii_strcasecmp(entry->name, table.ptr[i].name)) ++ { ++ state = &table.ptr[i]; + break; + } + } +@@ -1264,69 +1938,327 @@ static void resolve_fx_4_state_block_values(struct hlsl_ir_var *var, struct hlsl return; } @@ -3665,8 +3965,9 @@ index 57b4ac24212..e3ebbafb3f4 100644 - /* Turned named constants to actual constants. */ + /* Turn named constants to actual constants. */ ++ hlsl_transform_ir(ctx, lower_null_constant, entry->instrs, NULL); hlsl_transform_ir(ctx, replace_state_block_constant, entry->instrs, &replace_context); -+ fold_state_value(ctx, entry); ++ hlsl_run_const_passes(ctx, entry->instrs); - if (state->dimx) - state_type = hlsl_get_vector_type(ctx, state->type, state->dimx); @@ -3681,7 +3982,8 @@ index 57b4ac24212..e3ebbafb3f4 100644 + switch (node->type) + { + case HLSL_IR_LOAD: -+ load = hlsl_ir_load(node); ++ { ++ struct hlsl_ir_load *load = hlsl_ir_load(node); + + if (load->src.path_len) + hlsl_fixme(ctx, &ctx->location, "Arrays are not supported for RHS."); @@ -3693,6 +3995,26 @@ index 57b4ac24212..e3ebbafb3f4 100644 + } + + break; ++ } ++ case HLSL_IR_CONSTANT: ++ { ++ struct hlsl_ir_constant *c = hlsl_ir_constant(node); ++ struct hlsl_type *data_type = c->node.data_type; ++ ++ if (data_type->class == HLSL_CLASS_SCALAR && data_type->e.numeric.type == HLSL_TYPE_UINT) ++ { ++ if (c->value.u[0].u != 0) ++ hlsl_error(ctx, &ctx->location, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, ++ "Only 0 integer constants are allowed for object-typed fields."); ++ } ++ else ++ { ++ hlsl_error(ctx, &ctx->location, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, ++ "Unexpected constant used for object-typed field."); ++ } ++ ++ break; ++ } + default: + hlsl_fixme(ctx, &ctx->location, "Unhandled node type for object-typed field."); + } @@ -3750,24 +4072,42 @@ index 57b4ac24212..e3ebbafb3f4 100644 + hlsl_src_remove(entry->args); + hlsl_src_from_node(entry->args, cast); + -+ fold_state_value(ctx, entry); ++ hlsl_run_const_passes(ctx, entry->instrs); + } } -static void write_fx_4_state_object_initializer(struct hlsl_ir_var *var, struct fx_write_context *fx) -+static unsigned int decompose_fx_4_state_block(struct hlsl_ir_var *var, struct hlsl_state_block *block, -+ unsigned int entry_index, struct fx_write_context *fx) ++static bool decompose_fx_4_state_add_entries(struct hlsl_state_block *block, unsigned int entry_index, ++ unsigned int count) { - uint32_t elements_count = hlsl_get_multiarray_size(var->data_type), i, j; - struct vkd3d_bytecode_buffer *buffer = &fx->structured; - uint32_t count_offset, count; ++ if (!vkd3d_array_reserve((void **)&block->entries, &block->capacity, block->count + count, sizeof(*block->entries))) ++ return false; + +- for (i = 0; i < elements_count; ++i) ++ if (entry_index != block->count - 1) + { +- struct hlsl_state_block *block; ++ memmove(&block->entries[entry_index + count + 1], &block->entries[entry_index + 1], ++ (block->count - entry_index - 1) * sizeof(*block->entries)); ++ } ++ block->count += count; + +- count_offset = put_u32(buffer, 0); ++ return true; ++} ++ ++static unsigned int decompose_fx_4_state_function_call(struct hlsl_ir_var *var, struct hlsl_state_block *block, ++ unsigned int entry_index, struct fx_write_context *fx) ++{ + struct hlsl_state_block_entry *entry = block->entries[entry_index]; + const struct state_block_function_info *info; + struct function_component components[9]; + struct hlsl_ctx *ctx = fx->ctx; + unsigned int i; - -- for (i = 0; i < elements_count; ++i) ++ + if (!entry->is_function_call) + return 1; + @@ -3775,14 +4115,12 @@ index 57b4ac24212..e3ebbafb3f4 100644 + return 1; + + if (info->min_profile > ctx->profile->major_version) - { -- struct hlsl_state_block *block; ++ { + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_STATE_BLOCK_ENTRY, + "State %s is not supported for this profile.", entry->name); + return 1; + } - -- count_offset = put_u32(buffer, 0); ++ + /* For single argument case simply replace the name. */ + if (info->min_args == info->max_args && info->min_args == 1) + { @@ -3790,19 +4128,12 @@ index 57b4ac24212..e3ebbafb3f4 100644 + entry->name = hlsl_strdup(ctx, info->components[0].name); + return 1; + } ++ ++ if (!decompose_fx_4_state_add_entries(block, entry_index, entry->args_count - 1)) ++ return 1; - count = 0; - if (var->state_blocks) -+ if (!vkd3d_array_reserve((void **)&block->entries, &block->capacity, block->count + entry->args_count - 1, -+ sizeof(*block->entries))) -+ return 1; -+ if (entry_index != block->count - 1) -+ { -+ memmove(&block->entries[entry_index + entry->args_count], &block->entries[entry_index + 1], -+ (block->count - entry_index - 1) * sizeof(*block->entries)); -+ } -+ block->count += entry->args_count - 1; -+ + get_state_block_function_components(info, components, entry->args_count); + + for (i = 0; i < entry->args_count; ++i) @@ -3817,6 +4148,74 @@ index 57b4ac24212..e3ebbafb3f4 100644 + return entry->args_count; +} + ++/* For some states assignment sets all of the elements. This behaviour is limited to certain states of BlendState ++ object, and only when fx_5_0 profile is used. */ ++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) ++{ ++ static const char *states[] = { "SrcBlend", "DestBlend", "BlendOp", "SrcBlendAlpha", "DestBlendAlpha", "BlendOpAlpha" }; ++ 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; ++ struct hlsl_ctx *ctx = fx->ctx; ++ bool found = false; ++ unsigned int i; ++ ++ if (type->class != HLSL_CLASS_BLEND_STATE) ++ return 1; ++ if (ctx->profile->major_version != 5) ++ return 1; ++ if (entry->lhs_has_index) ++ return 1; ++ ++ for (i = 0; i < ARRAY_SIZE(states); ++i) ++ { ++ if (!ascii_strcasecmp(entry->name, states[i])) + { +- block = var->state_blocks[i]; ++ found = true; ++ break; ++ } ++ } + +- for (j = 0; j < block->count; ++j) +- { +- struct hlsl_state_block_entry *entry = block->entries[j]; ++ if (!found) ++ return 1; ++ ++ if (!decompose_fx_4_state_add_entries(block, entry_index, array_size - 1)) ++ return 1; ++ ++ block->entries[entry_index]->lhs_has_index = true; ++ for (i = 1; i < array_size; ++i) ++ { ++ block->entries[entry_index + i] = clone_stateblock_entry(ctx, entry, ++ entry->name, true, i, 0); ++ } + +- /* Skip if property is reassigned later. This will use the last assignment. */ +- if (state_block_contains_state(entry->name, j + 1, block)) +- continue; ++ return array_size; ++} + +- /* Resolve special constant names and property names. */ +- resolve_fx_4_state_block_values(var, entry, fx); ++static unsigned int decompose_fx_4_state_block(struct hlsl_ir_var *var, struct hlsl_state_block *block, ++ unsigned int entry_index, struct fx_write_context *fx) ++{ ++ struct hlsl_state_block_entry *entry = block->entries[entry_index]; + +- write_fx_4_state_assignment(var, entry, fx); +- ++count; +- } ++ if (entry->is_function_call) ++ return decompose_fx_4_state_function_call(var, block, entry_index, fx); ++ ++ return decompose_fx_4_state_block_expand_array(var, block, entry_index, fx); ++} ++ +static void write_fx_4_state_block(struct hlsl_ir_var *var, unsigned int block_index, + uint32_t count_offset, struct fx_write_context *fx) +{ @@ -3829,36 +4228,25 @@ index 57b4ac24212..e3ebbafb3f4 100644 + block = var->state_blocks[block_index]; + + for (i = 0; i < block->count;) - { -- block = var->state_blocks[i]; ++ { + i += decompose_fx_4_state_block(var, block, i, fx); -+ } + } -- for (j = 0; j < block->count; ++j) -- { -- struct hlsl_state_block_entry *entry = block->entries[j]; +- set_u32(buffer, count_offset, count); + for (i = 0; i < block->count; ++i) + { + struct hlsl_state_block_entry *entry = block->entries[i]; - -- /* Skip if property is reassigned later. This will use the last assignment. */ -- if (state_block_contains_state(entry->name, j + 1, block)) -- continue; ++ + /* Skip if property is reassigned later. This will use the last assignment. */ -+ if (state_block_contains_state(entry->name, i + 1, block)) ++ if (state_block_contains_state(entry, i + 1, block)) + continue; - -- /* Resolve special constant names and property names. */ -- resolve_fx_4_state_block_values(var, entry, fx); ++ + /* Resolve special constant names and property names. */ + resolve_fx_4_state_block_values(var, entry, fx); - -- write_fx_4_state_assignment(var, entry, fx); -- ++count; -- } ++ + write_fx_4_state_assignment(var, entry, fx); + ++count; - } ++ } + } + + set_u32(buffer, count_offset, count); @@ -3869,8 +4257,7 @@ index 57b4ac24212..e3ebbafb3f4 100644 + uint32_t elements_count = hlsl_get_multiarray_size(var->data_type), i; + struct vkd3d_bytecode_buffer *buffer = &fx->structured; + uint32_t count_offset; - -- set_u32(buffer, count_offset, count); ++ + for (i = 0; i < elements_count; ++i) + { + count_offset = put_u32(buffer, 0); @@ -3911,7 +4298,7 @@ index 57b4ac24212..e3ebbafb3f4 100644 } } -@@ -1336,7 +2002,7 @@ static void write_fx_4_object_variable(struct hlsl_ir_var *var, struct fx_write_ +@@ -1336,7 +2268,7 @@ static void write_fx_4_object_variable(struct hlsl_ir_var *var, struct fx_write_ uint32_t elements_count = hlsl_get_multiarray_size(var->data_type); struct vkd3d_bytecode_buffer *buffer = &fx->structured; uint32_t semantic_offset, bind_point = ~0u; @@ -3920,7 +4307,7 @@ index 57b4ac24212..e3ebbafb3f4 100644 struct hlsl_ctx *ctx = fx->ctx; if (var->reg_reservation.reg_type) -@@ -1344,7 +2010,7 @@ static void write_fx_4_object_variable(struct hlsl_ir_var *var, struct fx_write_ +@@ -1344,7 +2276,7 @@ static void write_fx_4_object_variable(struct hlsl_ir_var *var, struct fx_write_ type_offset = write_type(var->data_type, fx); name_offset = write_string(var->name, fx); @@ -3929,7 +4316,7 @@ index 57b4ac24212..e3ebbafb3f4 100644 put_u32(buffer, name_offset); put_u32(buffer, type_offset); -@@ -1373,9 +2039,14 @@ static void write_fx_4_object_variable(struct hlsl_ir_var *var, struct fx_write_ +@@ -1373,9 +2305,14 @@ static void write_fx_4_object_variable(struct hlsl_ir_var *var, struct fx_write_ case HLSL_CLASS_PIXEL_SHADER: case HLSL_CLASS_VERTEX_SHADER: @@ -3947,7 +4334,7 @@ index 57b4ac24212..e3ebbafb3f4 100644 fx->shader_count += elements_count; break; -@@ -1383,19 +2054,27 @@ static void write_fx_4_object_variable(struct hlsl_ir_var *var, struct fx_write_ +@@ -1383,19 +2320,37 @@ static void write_fx_4_object_variable(struct hlsl_ir_var *var, struct fx_write_ fx->dsv_count += elements_count; break; @@ -3965,6 +4352,16 @@ index 57b4ac24212..e3ebbafb3f4 100644 + write_fx_4_state_object_initializer(var, fx); + fx->rasterizer_state_count += elements_count; + break; ++ ++ case HLSL_CLASS_BLEND_STATE: ++ write_fx_4_state_object_initializer(var, fx); ++ fx->blend_state_count += elements_count; ++ break; ++ ++ case HLSL_CLASS_STRING: ++ write_fx_4_string_initializer(var, fx); ++ fx->string_count += elements_count; ++ break; + default: - hlsl_fixme(ctx, &ctx->location, "Writing initializer for object type %u is not implemented.", @@ -3980,7 +4377,7 @@ index 57b4ac24212..e3ebbafb3f4 100644 ++fx->object_variable_count; } -@@ -1438,9 +2117,7 @@ static void write_fx_4_buffer(struct hlsl_buffer *b, struct fx_write_context *fx +@@ -1438,9 +2393,7 @@ static void write_fx_4_buffer(struct hlsl_buffer *b, struct fx_write_context *fx } else { @@ -3991,7 +4388,7 @@ index 57b4ac24212..e3ebbafb3f4 100644 ++fx->buffer_count; } -@@ -1464,6 +2141,9 @@ static void write_buffers(struct fx_write_context *fx, bool shared) +@@ -1464,6 +2417,9 @@ static void write_buffers(struct fx_write_context *fx, bool shared) { struct hlsl_buffer *buffer; @@ -4001,7 +4398,7 @@ index 57b4ac24212..e3ebbafb3f4 100644 LIST_FOR_EACH_ENTRY(buffer, &fx->ctx->buffers, struct hlsl_buffer, entry) { if (!buffer->size && !fx->include_empty_buffers) -@@ -1483,12 +2163,20 @@ static bool is_supported_object_variable(const struct hlsl_ctx *ctx, const struc +@@ -1483,11 +2439,22 @@ static bool is_supported_object_variable(const struct hlsl_ctx *ctx, const struc switch (type->class) { @@ -4012,42 +4409,61 @@ index 57b4ac24212..e3ebbafb3f4 100644 case HLSL_CLASS_RENDER_TARGET_VIEW: case HLSL_CLASS_SAMPLER: case HLSL_CLASS_TEXTURE: - return true; ++ case HLSL_CLASS_BLEND_STATE: ++ case HLSL_CLASS_VERTEX_SHADER: ++ case HLSL_CLASS_STRING: ++ return true; + case HLSL_CLASS_COMPUTE_SHADER: + case HLSL_CLASS_DOMAIN_SHADER: + case HLSL_CLASS_HULL_SHADER: + if (ctx->profile->major_version < 5) + return false; -+ return true; + return true; case HLSL_CLASS_UAV: if (ctx->profile->major_version < 5) +@@ -1495,8 +2462,6 @@ static bool is_supported_object_variable(const struct hlsl_ctx *ctx, const struc + if (type->e.resource.rasteriser_ordered) return false; -@@ -1551,9 +2239,9 @@ static int hlsl_fx_4_write(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out) + return true; +- case HLSL_CLASS_VERTEX_SHADER: +- return true; + + default: + return false; +@@ -1549,11 +2514,11 @@ static int hlsl_fx_4_write(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out) + put_u32(&buffer, fx.shared_object_count); + put_u32(&buffer, fx.technique_count); size_offset = put_u32(&buffer, 0); /* Unstructured size. */ - put_u32(&buffer, 0); /* String count. */ +- put_u32(&buffer, 0); /* String count. */ ++ put_u32(&buffer, fx.string_count); put_u32(&buffer, fx.texture_count); - put_u32(&buffer, 0); /* Depth stencil state count. */ -+ put_u32(&buffer, fx.depth_stencil_state_count); - put_u32(&buffer, 0); /* Blend state count. */ +- put_u32(&buffer, 0); /* Blend state count. */ - put_u32(&buffer, 0); /* Rasterizer state count. */ ++ put_u32(&buffer, fx.depth_stencil_state_count); ++ put_u32(&buffer, fx.blend_state_count); + put_u32(&buffer, fx.rasterizer_state_count); put_u32(&buffer, fx.sampler_state_count); put_u32(&buffer, fx.rtv_count); put_u32(&buffer, fx.dsv_count); -@@ -1609,9 +2297,9 @@ static int hlsl_fx_5_write(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out) +@@ -1607,11 +2572,11 @@ static int hlsl_fx_5_write(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out) + put_u32(&buffer, fx.shared_object_count); + put_u32(&buffer, fx.technique_count); size_offset = put_u32(&buffer, 0); /* Unstructured size. */ - put_u32(&buffer, 0); /* String count. */ +- put_u32(&buffer, 0); /* String count. */ ++ put_u32(&buffer, fx.string_count); put_u32(&buffer, fx.texture_count); - put_u32(&buffer, 0); /* Depth stencil state count. */ -+ put_u32(&buffer, fx.depth_stencil_state_count); - put_u32(&buffer, 0); /* Blend state count. */ +- put_u32(&buffer, 0); /* Blend state count. */ - put_u32(&buffer, 0); /* Rasterizer state count. */ ++ put_u32(&buffer, fx.depth_stencil_state_count); ++ put_u32(&buffer, fx.blend_state_count); + put_u32(&buffer, fx.rasterizer_state_count); put_u32(&buffer, fx.sampler_state_count); put_u32(&buffer, fx.rtv_count); put_u32(&buffer, fx.dsv_count); diff --git a/libs/vkd3d/libs/vkd3d-shader/glsl.c b/libs/vkd3d/libs/vkd3d-shader/glsl.c -index 3e482a5fc70..10e12ea56f2 100644 +index 3e482a5fc70..d1f02ab568b 100644 --- a/libs/vkd3d/libs/vkd3d-shader/glsl.c +++ b/libs/vkd3d/libs/vkd3d-shader/glsl.c @@ -18,10 +18,23 @@ @@ -4136,7 +4552,7 @@ index 3e482a5fc70..10e12ea56f2 100644 + + if (reg->non_uniform) + vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, -+ "Internal compiler error: Unhandled 'non-uniform' modifer."); ++ "Internal compiler error: Unhandled 'non-uniform' modifier."); + if (vsir_src->modifiers) + vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, + "Internal compiler error: Unhandled source modifier(s) %#x.", vsir_src->modifiers); @@ -4159,10 +4575,10 @@ index 3e482a5fc70..10e12ea56f2 100644 + + if (ins->flags & VKD3DSI_PRECISE_XYZW) + vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, -+ "Internal compiler error: Unhandled 'precise' modifer."); ++ "Internal compiler error: Unhandled 'precise' modifier."); + if (vsir_dst->reg.non_uniform) + vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, -+ "Internal compiler error: Unhandled 'non-uniform' modifer."); ++ "Internal compiler error: Unhandled 'non-uniform' modifier."); + + glsl_dst->vsir = vsir_dst; + glsl_dst->register_name = vkd3d_string_buffer_get(&gen->string_buffers); @@ -4322,7 +4738,7 @@ index 3e482a5fc70..10e12ea56f2 100644 } diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c -index 99214fba6de..7f85195382d 100644 +index 99214fba6de..bd5baacd83d 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c @@ -134,7 +134,7 @@ struct hlsl_ir_var *hlsl_get_var(struct hlsl_scope *scope, const char *name) @@ -4346,16 +4762,23 @@ index 99214fba6de..7f85195382d 100644 vkd3d_free(state_block->entries); vkd3d_free(state_block); } -@@ -167,6 +167,8 @@ void hlsl_free_var(struct hlsl_ir_var *decl) +@@ -167,6 +167,15 @@ void hlsl_free_var(struct hlsl_ir_var *decl) for (k = 0; k <= HLSL_REGSET_LAST_OBJECT; ++k) vkd3d_free((void *)decl->objects_usage[k]); -+ vkd3d_free(decl->default_values); ++ if (decl->default_values) ++ { ++ unsigned int component_count = hlsl_type_component_count(decl->data_type); ++ ++ for (k = 0; k < component_count; ++k) ++ vkd3d_free((void *)decl->default_values[k].string); ++ vkd3d_free(decl->default_values); ++ } + for (i = 0; i < decl->state_block_count; ++i) hlsl_free_state_block(decl->state_blocks[i]); vkd3d_free(decl->state_blocks); -@@ -367,15 +369,22 @@ static void hlsl_type_calculate_reg_size(struct hlsl_ctx *ctx, struct hlsl_type +@@ -367,15 +376,24 @@ static void hlsl_type_calculate_reg_size(struct hlsl_ctx *ctx, struct hlsl_type type->reg_size[HLSL_REGSET_UAVS] = 1; break; @@ -4375,10 +4798,12 @@ index 99214fba6de..7f85195382d 100644 + case HLSL_CLASS_DOMAIN_SHADER: + case HLSL_CLASS_HULL_SHADER: + case HLSL_CLASS_GEOMETRY_SHADER: ++ case HLSL_CLASS_BLEND_STATE: ++ case HLSL_CLASS_NULL: break; } } -@@ -435,21 +444,28 @@ static bool type_is_single_component(const struct hlsl_type *type) +@@ -435,21 +453,30 @@ static bool type_is_single_component(const struct hlsl_type *type) { switch (type->class) { @@ -4397,6 +4822,8 @@ index 99214fba6de..7f85195382d 100644 + case HLSL_CLASS_DOMAIN_SHADER: + case HLSL_CLASS_HULL_SHADER: + case HLSL_CLASS_GEOMETRY_SHADER: ++ case HLSL_CLASS_BLEND_STATE: ++ case HLSL_CLASS_NULL: return true; case HLSL_CLASS_VECTOR: @@ -4407,7 +4834,7 @@ index 99214fba6de..7f85195382d 100644 return false; case HLSL_CLASS_EFFECT_GROUP: -@@ -474,13 +490,13 @@ static unsigned int traverse_path_from_component_index(struct hlsl_ctx *ctx, +@@ -474,13 +501,13 @@ static unsigned int traverse_path_from_component_index(struct hlsl_ctx *ctx, struct hlsl_type *type = *type_ptr; unsigned int index = *index_ptr; @@ -4424,7 +4851,7 @@ index 99214fba6de..7f85195382d 100644 *type_ptr = hlsl_get_scalar_type(ctx, type->e.numeric.type); *index_ptr = 0; return index; -@@ -490,7 +506,7 @@ static unsigned int traverse_path_from_component_index(struct hlsl_ctx *ctx, +@@ -490,7 +517,7 @@ static unsigned int traverse_path_from_component_index(struct hlsl_ctx *ctx, unsigned int y = index / type->dimx, x = index % type->dimx; bool row_major = hlsl_type_is_row_major(type); @@ -4433,7 +4860,7 @@ index 99214fba6de..7f85195382d 100644 *type_ptr = hlsl_get_vector_type(ctx, type->e.numeric.type, row_major ? type->dimx : type->dimy); *index_ptr = row_major ? x : y; return row_major ? y : x; -@@ -504,7 +520,7 @@ static unsigned int traverse_path_from_component_index(struct hlsl_ctx *ctx, +@@ -504,7 +531,7 @@ static unsigned int traverse_path_from_component_index(struct hlsl_ctx *ctx, *type_ptr = type->e.array.type; *index_ptr = index % elem_comp_count; array_index = index / elem_comp_count; @@ -4442,7 +4869,7 @@ index 99214fba6de..7f85195382d 100644 return array_index; } -@@ -528,6 +544,12 @@ static unsigned int traverse_path_from_component_index(struct hlsl_ctx *ctx, +@@ -528,6 +555,12 @@ static unsigned int traverse_path_from_component_index(struct hlsl_ctx *ctx, vkd3d_unreachable(); } @@ -4455,7 +4882,7 @@ index 99214fba6de..7f85195382d 100644 default: vkd3d_unreachable(); } -@@ -556,12 +578,14 @@ unsigned int hlsl_type_get_component_offset(struct hlsl_ctx *ctx, struct hlsl_ty +@@ -556,12 +589,14 @@ unsigned int hlsl_type_get_component_offset(struct hlsl_ctx *ctx, struct hlsl_ty switch (type->class) { @@ -4472,7 +4899,7 @@ index 99214fba6de..7f85195382d 100644 case HLSL_CLASS_STRUCT: for (r = 0; r <= HLSL_REGSET_LAST; ++r) offset[r] += type->e.record.fields[idx].reg_offset[r]; -@@ -577,21 +601,29 @@ unsigned int hlsl_type_get_component_offset(struct hlsl_ctx *ctx, struct hlsl_ty +@@ -577,21 +612,31 @@ unsigned int hlsl_type_get_component_offset(struct hlsl_ctx *ctx, struct hlsl_ty } break; @@ -4491,6 +4918,7 @@ index 99214fba6de..7f85195382d 100644 + case HLSL_CLASS_DOMAIN_SHADER: + case HLSL_CLASS_HULL_SHADER: + case HLSL_CLASS_GEOMETRY_SHADER: ++ case HLSL_CLASS_BLEND_STATE: + VKD3D_ASSERT(idx == 0); break; @@ -4500,10 +4928,11 @@ index 99214fba6de..7f85195382d 100644 case HLSL_CLASS_VOID: + case HLSL_CLASS_SCALAR: + case HLSL_CLASS_CONSTANT_BUFFER: ++ case HLSL_CLASS_NULL: vkd3d_unreachable(); } type = next_type; -@@ -638,9 +670,9 @@ bool hlsl_init_deref_from_index_chain(struct hlsl_ctx *ctx, struct hlsl_deref *d +@@ -638,9 +683,9 @@ bool hlsl_init_deref_from_index_chain(struct hlsl_ctx *ctx, struct hlsl_deref *d deref->rel_offset.node = NULL; deref->const_offset = 0; @@ -4515,7 +4944,7 @@ index 99214fba6de..7f85195382d 100644 /* Find the length of the index chain */ chain_len = 0; -@@ -687,7 +719,7 @@ bool hlsl_init_deref_from_index_chain(struct hlsl_ctx *ctx, struct hlsl_deref *d +@@ -687,7 +732,7 @@ bool hlsl_init_deref_from_index_chain(struct hlsl_ctx *ctx, struct hlsl_deref *d chain_len++; ptr = index->val.node; } @@ -4524,7 +4953,7 @@ index 99214fba6de..7f85195382d 100644 return true; } -@@ -697,7 +729,7 @@ struct hlsl_type *hlsl_deref_get_type(struct hlsl_ctx *ctx, const struct hlsl_de +@@ -697,7 +742,7 @@ struct hlsl_type *hlsl_deref_get_type(struct hlsl_ctx *ctx, const struct hlsl_de struct hlsl_type *type; unsigned int i; @@ -4533,7 +4962,7 @@ index 99214fba6de..7f85195382d 100644 if (hlsl_deref_is_lowered(deref)) return deref->data_type; -@@ -752,7 +784,7 @@ static bool init_deref_from_component_index(struct hlsl_ctx *ctx, struct hlsl_bl +@@ -752,7 +797,7 @@ static bool init_deref_from_component_index(struct hlsl_ctx *ctx, struct hlsl_bl hlsl_src_from_node(&deref->path[deref_path_len++], c); } @@ -4542,7 +4971,7 @@ index 99214fba6de..7f85195382d 100644 return true; } -@@ -760,7 +792,7 @@ static bool init_deref_from_component_index(struct hlsl_ctx *ctx, struct hlsl_bl +@@ -760,7 +805,7 @@ static bool init_deref_from_component_index(struct hlsl_ctx *ctx, struct hlsl_bl struct hlsl_type *hlsl_get_element_type_from_path_index(struct hlsl_ctx *ctx, const struct hlsl_type *type, struct hlsl_ir_node *idx) { @@ -4551,7 +4980,7 @@ index 99214fba6de..7f85195382d 100644 switch (type->class) { -@@ -780,7 +812,7 @@ struct hlsl_type *hlsl_get_element_type_from_path_index(struct hlsl_ctx *ctx, co +@@ -780,7 +825,7 @@ struct hlsl_type *hlsl_get_element_type_from_path_index(struct hlsl_ctx *ctx, co { struct hlsl_ir_constant *c = hlsl_ir_constant(idx); @@ -4560,7 +4989,7 @@ index 99214fba6de..7f85195382d 100644 return type->e.record.fields[c->value.u[0].u].type; } -@@ -865,6 +897,20 @@ struct hlsl_type *hlsl_new_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim +@@ -865,6 +910,20 @@ struct hlsl_type *hlsl_new_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim return type; } @@ -4581,7 +5010,15 @@ index 99214fba6de..7f85195382d 100644 static const char * get_case_insensitive_typename(const char *name) { static const char *const names[] = -@@ -956,14 +1002,23 @@ unsigned int hlsl_type_component_count(const struct hlsl_type *type) +@@ -876,6 +935,7 @@ static const char * get_case_insensitive_typename(const char *name) + "texture", + "vector", + "vertexshader", ++ "string", + }; + unsigned int i; + +@@ -956,14 +1016,25 @@ unsigned int hlsl_type_component_count(const struct hlsl_type *type) case HLSL_CLASS_ARRAY: return hlsl_type_component_count(type->e.array.type) * type->e.array.elements_count; @@ -4602,10 +5039,12 @@ index 99214fba6de..7f85195382d 100644 + case HLSL_CLASS_DOMAIN_SHADER: + case HLSL_CLASS_HULL_SHADER: + case HLSL_CLASS_GEOMETRY_SHADER: ++ case HLSL_CLASS_BLEND_STATE: ++ case HLSL_CLASS_NULL: return 1; case HLSL_CLASS_EFFECT_GROUP: -@@ -1038,14 +1093,23 @@ bool hlsl_types_are_equal(const struct hlsl_type *t1, const struct hlsl_type *t2 +@@ -1038,14 +1109,25 @@ bool hlsl_types_are_equal(const struct hlsl_type *t1, const struct hlsl_type *t2 case HLSL_CLASS_TECHNIQUE: return t1->e.version == t2->e.version; @@ -4626,10 +5065,12 @@ index 99214fba6de..7f85195382d 100644 + case HLSL_CLASS_DOMAIN_SHADER: + case HLSL_CLASS_HULL_SHADER: + case HLSL_CLASS_GEOMETRY_SHADER: ++ case HLSL_CLASS_BLEND_STATE: ++ case HLSL_CLASS_NULL: return true; } -@@ -1247,6 +1311,7 @@ struct hlsl_ir_var *hlsl_new_synthetic_var_named(struct hlsl_ctx *ctx, const cha +@@ -1247,6 +1329,7 @@ struct hlsl_ir_var *hlsl_new_synthetic_var_named(struct hlsl_ctx *ctx, const cha list_add_tail(&ctx->dummy_scope->vars, &var->scope_entry); else list_add_tail(&ctx->globals->vars, &var->scope_entry); @@ -4637,7 +5078,7 @@ index 99214fba6de..7f85195382d 100644 } return var; } -@@ -1265,7 +1330,7 @@ bool hlsl_copy_deref(struct hlsl_ctx *ctx, struct hlsl_deref *deref, const struc +@@ -1265,7 +1348,7 @@ bool hlsl_copy_deref(struct hlsl_ctx *ctx, struct hlsl_deref *deref, const struc if (!other) return true; @@ -4646,7 +5087,7 @@ index 99214fba6de..7f85195382d 100644 if (!init_deref(ctx, deref, other->var, other->path_len)) return false; -@@ -1322,8 +1387,8 @@ struct hlsl_ir_node *hlsl_new_store_index(struct hlsl_ctx *ctx, const struct hls +@@ -1322,8 +1405,8 @@ struct hlsl_ir_node *hlsl_new_store_index(struct hlsl_ctx *ctx, const struct hls struct hlsl_ir_store *store; unsigned int i; @@ -4657,16 +5098,16 @@ index 99214fba6de..7f85195382d 100644 if (!(store = hlsl_alloc(ctx, sizeof(*store)))) return NULL; -@@ -1394,7 +1459,7 @@ struct hlsl_ir_node *hlsl_new_constant(struct hlsl_ctx *ctx, struct hlsl_type *t +@@ -1394,7 +1477,7 @@ struct hlsl_ir_node *hlsl_new_constant(struct hlsl_ctx *ctx, struct hlsl_type *t { struct hlsl_ir_constant *c; - assert(type->class <= HLSL_CLASS_VECTOR); -+ VKD3D_ASSERT(type->class <= HLSL_CLASS_VECTOR); ++ VKD3D_ASSERT(type->class <= HLSL_CLASS_VECTOR || type->class == HLSL_CLASS_NULL); if (!(c = hlsl_alloc(ctx, sizeof(*c)))) return NULL; -@@ -1439,6 +1504,24 @@ struct hlsl_ir_node *hlsl_new_uint_constant(struct hlsl_ctx *ctx, unsigned int n +@@ -1439,6 +1522,30 @@ 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); } @@ -4687,11 +5128,17 @@ index 99214fba6de..7f85195382d 100644 + } + return &s->node; +} ++ ++struct hlsl_ir_node *hlsl_new_null_constant(struct hlsl_ctx *ctx, const struct vkd3d_shader_location *loc) ++{ ++ struct hlsl_constant_value value = { 0 }; ++ return hlsl_new_constant(ctx, ctx->builtin_types.null, &value, loc); ++} + struct hlsl_ir_node *hlsl_new_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS], struct hlsl_type *data_type, const struct vkd3d_shader_location *loc) -@@ -1468,7 +1551,7 @@ struct hlsl_ir_node *hlsl_new_binary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_exp +@@ -1468,7 +1575,7 @@ struct hlsl_ir_node *hlsl_new_binary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_exp { struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {arg1, arg2}; @@ -4700,7 +5147,7 @@ index 99214fba6de..7f85195382d 100644 return hlsl_new_expr(ctx, op, operands, arg1->data_type, &arg1->loc); } -@@ -1477,8 +1560,8 @@ struct hlsl_ir_node *hlsl_new_ternary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_ex +@@ -1477,8 +1584,8 @@ struct hlsl_ir_node *hlsl_new_ternary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_ex { struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {arg1, arg2, arg3}; @@ -4711,7 +5158,7 @@ index 99214fba6de..7f85195382d 100644 return hlsl_new_expr(ctx, op, operands, arg1->data_type, &arg1->loc); } -@@ -1540,7 +1623,7 @@ struct hlsl_ir_load *hlsl_new_load_index(struct hlsl_ctx *ctx, const struct hlsl +@@ -1540,7 +1647,7 @@ struct hlsl_ir_load *hlsl_new_load_index(struct hlsl_ctx *ctx, const struct hlsl struct hlsl_type *type; unsigned int i; @@ -4720,7 +5167,7 @@ index 99214fba6de..7f85195382d 100644 type = hlsl_deref_get_type(ctx, deref); if (idx) -@@ -1569,7 +1652,7 @@ struct hlsl_ir_load *hlsl_new_load_parent(struct hlsl_ctx *ctx, const struct hls +@@ -1569,7 +1676,7 @@ struct hlsl_ir_load *hlsl_new_load_parent(struct hlsl_ctx *ctx, const struct hls /* This deref can only exists temporarily because it is not the real owner of its members. */ struct hlsl_deref tmp_deref; @@ -4729,7 +5176,7 @@ index 99214fba6de..7f85195382d 100644 tmp_deref = *deref; tmp_deref.path_len = deref->path_len - 1; -@@ -1674,7 +1757,7 @@ struct hlsl_ir_node *hlsl_new_swizzle(struct hlsl_ctx *ctx, uint32_t s, unsigned +@@ -1674,7 +1781,7 @@ struct hlsl_ir_node *hlsl_new_swizzle(struct hlsl_ctx *ctx, uint32_t s, unsigned if (!(swizzle = hlsl_alloc(ctx, sizeof(*swizzle)))) return NULL; @@ -4738,7 +5185,7 @@ index 99214fba6de..7f85195382d 100644 if (components == 1) type = hlsl_get_scalar_type(ctx, val->data_type->e.numeric.type); else -@@ -1765,7 +1848,8 @@ struct hlsl_ir_node *hlsl_new_jump(struct hlsl_ctx *ctx, enum hlsl_ir_jump_type +@@ -1765,7 +1872,8 @@ struct hlsl_ir_node *hlsl_new_jump(struct hlsl_ctx *ctx, enum hlsl_ir_jump_type } struct hlsl_ir_node *hlsl_new_loop(struct hlsl_ctx *ctx, @@ -4748,7 +5195,7 @@ index 99214fba6de..7f85195382d 100644 { struct hlsl_ir_loop *loop; -@@ -1774,6 +1858,9 @@ struct hlsl_ir_node *hlsl_new_loop(struct hlsl_ctx *ctx, +@@ -1774,6 +1882,9 @@ struct hlsl_ir_node *hlsl_new_loop(struct hlsl_ctx *ctx, init_node(&loop->node, HLSL_IR_LOOP, NULL, loc); hlsl_block_init(&loop->body); hlsl_block_add_block(&loop->body, block); @@ -4758,7 +5205,7 @@ index 99214fba6de..7f85195382d 100644 return &loop->node; } -@@ -1836,9 +1923,7 @@ static struct hlsl_ir_node *map_instr(const struct clone_instr_map *map, struct +@@ -1836,9 +1947,7 @@ static struct hlsl_ir_node *map_instr(const struct clone_instr_map *map, struct return map->instrs[i].dst; } @@ -4769,7 +5216,7 @@ index 99214fba6de..7f85195382d 100644 } static bool clone_deref(struct hlsl_ctx *ctx, struct clone_instr_map *map, -@@ -1846,7 +1931,7 @@ static bool clone_deref(struct hlsl_ctx *ctx, struct clone_instr_map *map, +@@ -1846,7 +1955,7 @@ static bool clone_deref(struct hlsl_ctx *ctx, struct clone_instr_map *map, { unsigned int i; @@ -4778,7 +5225,7 @@ index 99214fba6de..7f85195382d 100644 if (!init_deref(ctx, dst, src->var, src->path_len)) return false; -@@ -1935,7 +2020,7 @@ static struct hlsl_ir_node *clone_loop(struct hlsl_ctx *ctx, struct clone_instr_ +@@ -1935,7 +2044,7 @@ static struct hlsl_ir_node *clone_loop(struct hlsl_ctx *ctx, struct clone_instr_ if (!clone_block(ctx, &body, &src->body, map)) return NULL; @@ -4787,7 +5234,7 @@ index 99214fba6de..7f85195382d 100644 { hlsl_block_cleanup(&body); return NULL; -@@ -1992,6 +2077,11 @@ static struct hlsl_ir_node *clone_resource_store(struct hlsl_ctx *ctx, +@@ -1992,6 +2101,11 @@ static struct hlsl_ir_node *clone_resource_store(struct hlsl_ctx *ctx, return &dst->node; } @@ -4799,7 +5246,7 @@ index 99214fba6de..7f85195382d 100644 static struct hlsl_ir_node *clone_store(struct hlsl_ctx *ctx, struct clone_instr_map *map, struct hlsl_ir_store *src) { struct hlsl_ir_store *dst; -@@ -2034,6 +2124,43 @@ static struct hlsl_ir_node *clone_stateblock_constant(struct hlsl_ctx *ctx, +@@ -2034,6 +2148,43 @@ static struct hlsl_ir_node *clone_stateblock_constant(struct hlsl_ctx *ctx, return hlsl_new_stateblock_constant(ctx, constant->name, &constant->node.loc); } @@ -4843,7 +5290,7 @@ index 99214fba6de..7f85195382d 100644 void hlsl_free_ir_switch_case(struct hlsl_ir_switch_case *c) { hlsl_block_cleanup(&c->body); -@@ -2121,6 +2248,9 @@ static struct hlsl_ir_node *clone_instr(struct hlsl_ctx *ctx, +@@ -2121,6 +2272,9 @@ static struct hlsl_ir_node *clone_instr(struct hlsl_ctx *ctx, case HLSL_IR_RESOURCE_STORE: return clone_resource_store(ctx, map, hlsl_ir_resource_store(instr)); @@ -4853,7 +5300,7 @@ index 99214fba6de..7f85195382d 100644 case HLSL_IR_STORE: return clone_store(ctx, map, hlsl_ir_store(instr)); -@@ -2249,7 +2379,7 @@ void hlsl_pop_scope(struct hlsl_ctx *ctx) +@@ -2249,7 +2403,7 @@ void hlsl_pop_scope(struct hlsl_ctx *ctx) { struct hlsl_scope *prev_scope = ctx->cur_scope->upper; @@ -4862,7 +5309,7 @@ index 99214fba6de..7f85195382d 100644 TRACE("Popping current scope.\n"); ctx->cur_scope = prev_scope; } -@@ -2327,17 +2457,17 @@ struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const stru +@@ -2327,17 +2481,17 @@ struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const stru switch (type->class) { case HLSL_CLASS_SCALAR: @@ -4883,7 +5330,7 @@ index 99214fba6de..7f85195382d 100644 vkd3d_string_buffer_printf(string, "%s%ux%u", base_types[type->e.numeric.type], type->dimy, type->dimx); return string; -@@ -2375,15 +2505,15 @@ struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const stru +@@ -2375,15 +2529,15 @@ struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const stru return string; } @@ -4902,7 +5349,7 @@ index 99214fba6de..7f85195382d 100644 vkd3d_string_buffer_printf(string, "Texture%s", dimensions[type->sampler_dim]); } if ((inner_string = hlsl_type_to_string(ctx, type->e.resource.format))) -@@ -2407,16 +2537,31 @@ struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const stru +@@ -2407,16 +2561,33 @@ struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const stru } return string; @@ -4931,10 +5378,12 @@ index 99214fba6de..7f85195382d 100644 + case HLSL_CLASS_DOMAIN_SHADER: + case HLSL_CLASS_HULL_SHADER: + case HLSL_CLASS_GEOMETRY_SHADER: ++ case HLSL_CLASS_BLEND_STATE: ++ case HLSL_CLASS_NULL: break; } -@@ -2513,19 +2658,21 @@ const char *hlsl_node_type_to_string(enum hlsl_ir_node_type type) +@@ -2513,19 +2684,21 @@ const char *hlsl_node_type_to_string(enum hlsl_ir_node_type type) { static const char * const names[] = { @@ -4969,7 +5418,7 @@ index 99214fba6de..7f85195382d 100644 }; if (type >= ARRAY_SIZE(names)) -@@ -2544,7 +2691,7 @@ const char *hlsl_jump_type_to_string(enum hlsl_ir_jump_type type) +@@ -2544,7 +2717,7 @@ const char *hlsl_jump_type_to_string(enum hlsl_ir_jump_type type) [HLSL_IR_JUMP_RETURN] = "HLSL_IR_JUMP_RETURN", }; @@ -4978,7 +5427,7 @@ index 99214fba6de..7f85195382d 100644 return names[type]; } -@@ -2634,7 +2781,7 @@ const char *debug_hlsl_writemask(unsigned int writemask) +@@ -2634,7 +2807,7 @@ const char *debug_hlsl_writemask(unsigned int writemask) char string[5]; unsigned int i = 0, pos = 0; @@ -4987,7 +5436,7 @@ index 99214fba6de..7f85195382d 100644 while (writemask) { -@@ -2653,7 +2800,7 @@ const char *debug_hlsl_swizzle(uint32_t swizzle, unsigned int size) +@@ -2653,7 +2826,7 @@ const char *debug_hlsl_swizzle(uint32_t swizzle, unsigned int size) char string[5]; unsigned int i; @@ -4996,7 +5445,7 @@ index 99214fba6de..7f85195382d 100644 for (i = 0; i < size; ++i) string[i] = components[hlsl_swizzle_get_component(swizzle, i)]; string[size] = 0; -@@ -2735,6 +2882,7 @@ const char *debug_hlsl_expr_op(enum hlsl_ir_expr_op op) +@@ -2735,6 +2908,7 @@ const char *debug_hlsl_expr_op(enum hlsl_ir_expr_op op) static const char *const op_names[] = { [HLSL_OP0_VOID] = "void", @@ -5004,7 +5453,7 @@ index 99214fba6de..7f85195382d 100644 [HLSL_OP1_ABS] = "abs", [HLSL_OP1_BIT_NOT] = "~", -@@ -2749,6 +2897,7 @@ const char *debug_hlsl_expr_op(enum hlsl_ir_expr_op op) +@@ -2749,6 +2923,7 @@ const char *debug_hlsl_expr_op(enum hlsl_ir_expr_op op) [HLSL_OP1_DSY_COARSE] = "dsy_coarse", [HLSL_OP1_DSY_FINE] = "dsy_fine", [HLSL_OP1_EXP2] = "exp2", @@ -5012,7 +5461,7 @@ index 99214fba6de..7f85195382d 100644 [HLSL_OP1_FLOOR] = "floor", [HLSL_OP1_FRACT] = "fract", [HLSL_OP1_LOG2] = "log2", -@@ -2790,6 +2939,7 @@ const char *debug_hlsl_expr_op(enum hlsl_ir_expr_op op) +@@ -2790,6 +2965,7 @@ const char *debug_hlsl_expr_op(enum hlsl_ir_expr_op op) [HLSL_OP3_CMP] = "cmp", [HLSL_OP3_DP2ADD] = "dp2add", [HLSL_OP3_TERNARY] = "ternary", @@ -5020,7 +5469,7 @@ index 99214fba6de..7f85195382d 100644 }; return op_names[op]; -@@ -2875,7 +3025,7 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru +@@ -2875,7 +3051,7 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru [HLSL_RESOURCE_RESINFO] = "resinfo", }; @@ -5029,7 +5478,7 @@ index 99214fba6de..7f85195382d 100644 vkd3d_string_buffer_printf(buffer, "%s(resource = ", type_names[load->load_type]); dump_deref(buffer, &load->resource); vkd3d_string_buffer_printf(buffer, ", sampler = "); -@@ -2929,6 +3079,11 @@ static void dump_ir_resource_store(struct vkd3d_string_buffer *buffer, const str +@@ -2929,6 +3105,11 @@ static void dump_ir_resource_store(struct vkd3d_string_buffer *buffer, const str vkd3d_string_buffer_printf(buffer, ")"); } @@ -5041,7 +5490,7 @@ index 99214fba6de..7f85195382d 100644 static void dump_ir_store(struct vkd3d_string_buffer *buffer, const struct hlsl_ir_store *store) { vkd3d_string_buffer_printf(buffer, "= ("); -@@ -3048,6 +3203,10 @@ static void dump_instr(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer, +@@ -3048,6 +3229,10 @@ static void dump_instr(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer, dump_ir_resource_store(buffer, hlsl_ir_resource_store(instr)); break; @@ -5052,7 +5501,7 @@ index 99214fba6de..7f85195382d 100644 case HLSL_IR_STORE: dump_ir_store(buffer, hlsl_ir_store(instr)); break; -@@ -3086,12 +3245,39 @@ void hlsl_dump_function(struct hlsl_ctx *ctx, const struct hlsl_ir_function_decl +@@ -3086,12 +3271,45 @@ void hlsl_dump_function(struct hlsl_ctx *ctx, const struct hlsl_ir_function_decl vkd3d_string_buffer_cleanup(&buffer); } @@ -5073,9 +5522,15 @@ index 99214fba6de..7f85195382d 100644 + vkd3d_string_buffer_printf(&buffer, "var \"%s\" default values:", var->name); + for (k = 0; k < component_count; ++k) + { -+ if (k % 4 == 0) ++ bool is_string = var->default_values[k].string; ++ ++ if (k % 4 == 0 || is_string) + vkd3d_string_buffer_printf(&buffer, "\n "); -+ vkd3d_string_buffer_printf(&buffer, " 0x%08x", var->default_values[k].value.u); ++ ++ if (is_string) ++ vkd3d_string_buffer_printf(&buffer, " %s", debugstr_a(var->default_values[k].string)); ++ else ++ vkd3d_string_buffer_printf(&buffer, " 0x%08x", var->default_values[k].number.u); + } + vkd3d_string_buffer_printf(&buffer, "\n"); + @@ -5094,7 +5549,7 @@ index 99214fba6de..7f85195382d 100644 LIST_FOR_EACH_ENTRY_SAFE(src, next, &old->uses, struct hlsl_src, entry) { -@@ -3199,6 +3385,12 @@ static void free_ir_resource_load(struct hlsl_ir_resource_load *load) +@@ -3199,6 +3417,12 @@ static void free_ir_resource_load(struct hlsl_ir_resource_load *load) vkd3d_free(load); } @@ -5107,7 +5562,7 @@ index 99214fba6de..7f85195382d 100644 static void free_ir_resource_store(struct hlsl_ir_resource_store *store) { hlsl_cleanup_deref(&store->resource); -@@ -3243,7 +3435,7 @@ static void free_ir_stateblock_constant(struct hlsl_ir_stateblock_constant *cons +@@ -3243,7 +3467,7 @@ static void free_ir_stateblock_constant(struct hlsl_ir_stateblock_constant *cons void hlsl_free_instr(struct hlsl_ir_node *node) { @@ -5116,7 +5571,7 @@ index 99214fba6de..7f85195382d 100644 switch (node->type) { -@@ -3283,6 +3475,10 @@ void hlsl_free_instr(struct hlsl_ir_node *node) +@@ -3283,6 +3507,10 @@ void hlsl_free_instr(struct hlsl_ir_node *node) free_ir_resource_load(hlsl_ir_resource_load(node)); break; @@ -5127,7 +5582,7 @@ index 99214fba6de..7f85195382d 100644 case HLSL_IR_RESOURCE_STORE: free_ir_resource_store(hlsl_ir_resource_store(node)); break; -@@ -3319,9 +3515,25 @@ void hlsl_free_attribute(struct hlsl_attribute *attr) +@@ -3319,9 +3547,25 @@ void hlsl_free_attribute(struct hlsl_attribute *attr) void hlsl_cleanup_semantic(struct hlsl_semantic *semantic) { vkd3d_free((void *)semantic->name); @@ -5153,12 +5608,13 @@ index 99214fba6de..7f85195382d 100644 static void free_function_decl(struct hlsl_ir_function_decl *decl) { unsigned int i; -@@ -3710,15 +3922,21 @@ static void declare_predefined_types(struct hlsl_ctx *ctx) - ctx->builtin_types.sampler[bt] = type; +@@ -3711,14 +3955,23 @@ static void declare_predefined_types(struct hlsl_ctx *ctx) } -+ ctx->builtin_types.string = hlsl_new_simple_type(ctx, "STRING", HLSL_CLASS_STRING); ctx->builtin_types.Void = hlsl_new_simple_type(ctx, "void", HLSL_CLASS_VOID); ++ ctx->builtin_types.null = hlsl_new_type(ctx, "NULL", HLSL_CLASS_NULL, HLSL_TYPE_UINT, 1, 1); ++ ctx->builtin_types.string = hlsl_new_simple_type(ctx, "string", HLSL_CLASS_STRING); ++ hlsl_scope_add_type(ctx->globals, ctx->builtin_types.string); hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "DepthStencilView", HLSL_CLASS_DEPTH_STENCIL_VIEW)); + hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "DepthStencilState", HLSL_CLASS_DEPTH_STENCIL_STATE)); hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "fxgroup", HLSL_CLASS_EFFECT_GROUP)); @@ -5173,10 +5629,11 @@ index 99214fba6de..7f85195382d 100644 + hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "DomainShader", HLSL_CLASS_DOMAIN_SHADER)); + hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "HullShader", HLSL_CLASS_HULL_SHADER)); + hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "GeometryShader", HLSL_CLASS_GEOMETRY_SHADER)); ++ hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "BlendState", HLSL_CLASS_BLEND_STATE)); for (i = 0; i < ARRAY_SIZE(effect_types); ++i) { -@@ -4049,6 +4267,7 @@ struct hlsl_ir_function_decl *hlsl_compile_internal_function(struct hlsl_ctx *ct +@@ -4049,6 +4302,7 @@ struct hlsl_ir_function_decl *hlsl_compile_internal_function(struct hlsl_ctx *ct /* Save and restore everything that matters. * Note that saving the scope stack is hard, and shouldn't be necessary. */ @@ -5184,7 +5641,7 @@ index 99214fba6de..7f85195382d 100644 ctx->scanner = NULL; ctx->internal_func_name = internal_name->buffer; ctx->cur_function = NULL; -@@ -4056,6 +4275,7 @@ struct hlsl_ir_function_decl *hlsl_compile_internal_function(struct hlsl_ctx *ct +@@ -4056,6 +4310,7 @@ struct hlsl_ir_function_decl *hlsl_compile_internal_function(struct hlsl_ctx *ct ctx->scanner = saved_scanner; ctx->internal_func_name = saved_internal_func_name; ctx->cur_function = saved_cur_function; @@ -5193,7 +5650,7 @@ index 99214fba6de..7f85195382d 100644 { ERR("Failed to compile intrinsic, error %u.\n", ret); diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h -index 27814f3a56f..7e8cd774ae2 100644 +index 27814f3a56f..22e25b23988 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h @@ -78,10 +78,12 @@ enum hlsl_type_class @@ -5209,7 +5666,7 @@ index 27814f3a56f..7e8cd774ae2 100644 HLSL_CLASS_RENDER_TARGET_VIEW, HLSL_CLASS_SAMPLER, HLSL_CLASS_STRING, -@@ -89,6 +91,11 @@ enum hlsl_type_class +@@ -89,7 +91,14 @@ enum hlsl_type_class HLSL_CLASS_TEXTURE, HLSL_CLASS_UAV, HLSL_CLASS_VERTEX_SHADER, @@ -5218,10 +5675,13 @@ index 27814f3a56f..7e8cd774ae2 100644 + HLSL_CLASS_HULL_SHADER, + HLSL_CLASS_GEOMETRY_SHADER, + HLSL_CLASS_CONSTANT_BUFFER, ++ HLSL_CLASS_BLEND_STATE, HLSL_CLASS_VOID, ++ HLSL_CLASS_NULL, }; -@@ -222,6 +229,8 @@ struct hlsl_semantic + enum hlsl_base_type +@@ -222,6 +231,8 @@ struct hlsl_semantic const char *name; uint32_t index; @@ -5230,7 +5690,7 @@ index 27814f3a56f..7e8cd774ae2 100644 /* If the variable or field that stores this hlsl_semantic has already reported that it is missing. */ bool reported_missing; /* In case the variable or field that stores this semantic has already reported to use a -@@ -259,8 +268,20 @@ struct hlsl_struct_field +@@ -259,8 +270,20 @@ struct hlsl_struct_field * struct. */ struct hlsl_reg { @@ -5252,7 +5712,7 @@ index 27814f3a56f..7e8cd774ae2 100644 /* Number of registers to be allocated. * Unlike the variable's type's regsize, it is not expressed in register components, but rather * in whole registers, and may depend on which components are used within the shader. */ -@@ -289,6 +310,7 @@ enum hlsl_ir_node_type +@@ -289,6 +312,7 @@ enum hlsl_ir_node_type HLSL_IR_JUMP, HLSL_IR_RESOURCE_LOAD, HLSL_IR_RESOURCE_STORE, @@ -5260,7 +5720,7 @@ index 27814f3a56f..7e8cd774ae2 100644 HLSL_IR_STORE, HLSL_IR_SWIZZLE, HLSL_IR_SWITCH, -@@ -371,6 +393,7 @@ struct hlsl_attribute +@@ -371,6 +395,7 @@ struct hlsl_attribute #define HLSL_STORAGE_LINEAR 0x00010000 #define HLSL_MODIFIER_SINGLE 0x00020000 #define HLSL_MODIFIER_EXPORT 0x00040000 @@ -5268,7 +5728,16 @@ index 27814f3a56f..7e8cd774ae2 100644 #define HLSL_TYPE_MODIFIERS_MASK (HLSL_MODIFIER_PRECISE | HLSL_MODIFIER_VOLATILE | \ HLSL_MODIFIER_CONST | HLSL_MODIFIER_ROW_MAJOR | \ -@@ -396,6 +419,14 @@ struct hlsl_reg_reservation +@@ -385,7 +410,7 @@ struct hlsl_attribute + + /* Reservation of a register and/or an offset for objects inside constant buffers, to be used as a + * starting point of their allocation. They are available through the register(·) and the +- * packoffset(·) syntaxes, respectivelly. ++ * packoffset(·) syntaxes, respectively. + * The constant buffer offset is measured register components. */ + struct hlsl_reg_reservation + { +@@ -396,6 +421,14 @@ struct hlsl_reg_reservation unsigned int offset_index; }; @@ -5283,7 +5752,7 @@ index 27814f3a56f..7e8cd774ae2 100644 struct hlsl_ir_var { struct hlsl_type *data_type; -@@ -418,6 +449,15 @@ struct hlsl_ir_var +@@ -418,6 +451,17 @@ struct hlsl_ir_var /* Scope that contains annotations for this variable. */ struct hlsl_scope *annotations; @@ -5292,14 +5761,16 @@ index 27814f3a56f..7e8cd774ae2 100644 + * This pointer is NULL for others. */ + struct hlsl_default_value + { ++ /* Default value, in case the component is a string, otherwise it is NULL. */ ++ const char *string; + /* Default value, in case the component is a numeric value. */ -+ union hlsl_constant_value_component value; ++ union hlsl_constant_value_component number; + } *default_values; + /* 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. -@@ -460,6 +500,8 @@ struct hlsl_ir_var +@@ -460,6 +504,8 @@ struct hlsl_ir_var uint32_t is_uniform : 1; uint32_t is_param : 1; uint32_t is_separated_resource : 1; @@ -5308,7 +5779,7 @@ index 27814f3a56f..7e8cd774ae2 100644 }; /* This struct is used to represent assignments in state block entries: -@@ -470,22 +512,31 @@ struct hlsl_ir_var +@@ -470,22 +516,31 @@ struct hlsl_ir_var * name[lhs_index] = args[0] * - or - * name[lhs_index] = {args[0], args[1], ...}; @@ -5344,7 +5815,7 @@ index 27814f3a56f..7e8cd774ae2 100644 struct hlsl_src *args; unsigned int args_count; }; -@@ -556,12 +607,21 @@ struct hlsl_ir_if +@@ -556,12 +611,21 @@ struct hlsl_ir_if struct hlsl_block else_block; }; @@ -5366,7 +5837,7 @@ index 27814f3a56f..7e8cd774ae2 100644 }; struct hlsl_ir_switch_case -@@ -583,13 +643,14 @@ struct hlsl_ir_switch +@@ -583,13 +647,14 @@ struct hlsl_ir_switch enum hlsl_ir_expr_op { HLSL_OP0_VOID, @@ -5382,7 +5853,7 @@ index 27814f3a56f..7e8cd774ae2 100644 HLSL_OP1_DSX, HLSL_OP1_DSX_COARSE, HLSL_OP1_DSX_FINE, -@@ -597,6 +658,7 @@ enum hlsl_ir_expr_op +@@ -597,6 +662,7 @@ enum hlsl_ir_expr_op HLSL_OP1_DSY_COARSE, HLSL_OP1_DSY_FINE, HLSL_OP1_EXP2, @@ -5390,7 +5861,7 @@ index 27814f3a56f..7e8cd774ae2 100644 HLSL_OP1_FLOOR, HLSL_OP1_FRACT, HLSL_OP1_LOG2, -@@ -610,7 +672,7 @@ enum hlsl_ir_expr_op +@@ -610,7 +676,7 @@ enum hlsl_ir_expr_op HLSL_OP1_SAT, HLSL_OP1_SIGN, HLSL_OP1_SIN, @@ -5399,7 +5870,7 @@ index 27814f3a56f..7e8cd774ae2 100644 HLSL_OP1_SQRT, HLSL_OP1_TRUNC, -@@ -643,6 +705,7 @@ enum hlsl_ir_expr_op +@@ -643,6 +709,7 @@ enum hlsl_ir_expr_op * CMP(a, b, c) returns 'b' if 'a' >= 0, and 'c' otherwise. It's used only for SM1-SM3 targets. */ HLSL_OP3_CMP, HLSL_OP3_TERNARY, @@ -5407,7 +5878,7 @@ index 27814f3a56f..7e8cd774ae2 100644 }; #define HLSL_MAX_OPERANDS 3 -@@ -775,18 +838,18 @@ struct hlsl_ir_constant +@@ -775,18 +842,18 @@ struct hlsl_ir_constant struct hlsl_ir_node node; struct hlsl_constant_value { @@ -5433,7 +5904,7 @@ index 27814f3a56f..7e8cd774ae2 100644 /* Stateblock constants are undeclared values found on state blocks or technique passes descriptions, * that do not concern regular pixel, vertex, or compute shaders, except for parsing. */ struct hlsl_ir_stateblock_constant -@@ -811,6 +874,8 @@ struct hlsl_scope +@@ -811,6 +878,8 @@ struct hlsl_scope bool loop; /* The scope was created for the switch statement. */ bool _switch; @@ -5442,15 +5913,17 @@ index 27814f3a56f..7e8cd774ae2 100644 }; struct hlsl_profile_info -@@ -931,6 +996,7 @@ struct hlsl_ctx +@@ -931,7 +1000,9 @@ struct hlsl_ctx /* matrix[HLSL_TYPE_FLOAT][1][3] is a float4x2, i.e. dimx = 2, dimy = 4 */ struct hlsl_type *matrix[HLSL_TYPE_LAST_SCALAR + 1][4][4]; struct hlsl_type *sampler[HLSL_SAMPLER_DIM_LAST_SAMPLER + 1]; + struct hlsl_type *string; struct hlsl_type *Void; ++ struct hlsl_type *null; } builtin_types; -@@ -948,6 +1014,8 @@ struct hlsl_ctx + /* List of the instruction nodes for initializing static variables. */ +@@ -948,6 +1019,8 @@ struct hlsl_ctx } *regs; size_t count, size; } constant_defs; @@ -5459,7 +5932,7 @@ index 27814f3a56f..7e8cd774ae2 100644 /* Number of temp. registers required for the shader to run, i.e. the largest temp register * index that will be used in the output bytecode (+1). */ uint32_t temp_count; -@@ -994,85 +1062,91 @@ struct hlsl_resource_load_params +@@ -994,85 +1067,91 @@ struct hlsl_resource_load_params static inline struct hlsl_ir_call *hlsl_ir_call(const struct hlsl_ir_node *node) { @@ -5565,7 +6038,7 @@ index 27814f3a56f..7e8cd774ae2 100644 return CONTAINING_RECORD(node, struct hlsl_ir_stateblock_constant, node); } -@@ -1249,6 +1323,13 @@ void hlsl_block_cleanup(struct hlsl_block *block); +@@ -1249,6 +1328,13 @@ 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); @@ -5579,7 +6052,7 @@ index 27814f3a56f..7e8cd774ae2 100644 void hlsl_run_const_passes(struct hlsl_ctx *ctx, struct hlsl_block *body); int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, -@@ -1259,7 +1340,9 @@ bool hlsl_init_deref_from_index_chain(struct hlsl_ctx *ctx, struct hlsl_deref *d +@@ -1259,7 +1345,9 @@ bool hlsl_init_deref_from_index_chain(struct hlsl_ctx *ctx, struct hlsl_deref *d bool hlsl_copy_deref(struct hlsl_ctx *ctx, struct hlsl_deref *deref, const struct hlsl_deref *other); void hlsl_cleanup_deref(struct hlsl_deref *deref); @@ -5589,7 +6062,7 @@ index 27814f3a56f..7e8cd774ae2 100644 void hlsl_cleanup_ir_switch_cases(struct list *cases); void hlsl_free_ir_switch_case(struct hlsl_ir_switch_case *c); -@@ -1270,6 +1353,7 @@ void hlsl_free_attribute(struct hlsl_attribute *attr); +@@ -1270,6 +1358,7 @@ void hlsl_free_attribute(struct hlsl_attribute *attr); void hlsl_free_instr(struct hlsl_ir_node *node); void hlsl_free_instr_list(struct list *list); void hlsl_free_state_block(struct hlsl_state_block *state_block); @@ -5597,7 +6070,7 @@ index 27814f3a56f..7e8cd774ae2 100644 void hlsl_free_type(struct hlsl_type *type); void hlsl_free_var(struct hlsl_ir_var *decl); -@@ -1342,7 +1426,7 @@ bool hlsl_index_chain_has_resource_access(struct hlsl_ir_index *index); +@@ -1342,7 +1431,7 @@ bool hlsl_index_chain_has_resource_access(struct hlsl_ir_index *index); struct hlsl_ir_node *hlsl_new_index(struct hlsl_ctx *ctx, struct hlsl_ir_node *val, struct hlsl_ir_node *idx, const struct vkd3d_shader_location *loc); struct hlsl_ir_node *hlsl_new_loop(struct hlsl_ctx *ctx, @@ -5606,7 +6079,7 @@ index 27814f3a56f..7e8cd774ae2 100644 struct hlsl_ir_node *hlsl_new_resource_load(struct hlsl_ctx *ctx, const struct hlsl_resource_load_params *params, const struct vkd3d_shader_location *loc); struct hlsl_ir_node *hlsl_new_resource_store(struct hlsl_ctx *ctx, const struct hlsl_deref *resource, -@@ -1353,6 +1437,8 @@ struct hlsl_ir_node *hlsl_new_swizzle(struct hlsl_ctx *ctx, uint32_t s, unsigned +@@ -1353,6 +1442,8 @@ struct hlsl_ir_node *hlsl_new_swizzle(struct hlsl_ctx *ctx, uint32_t s, unsigned struct hlsl_ir_node *val, const struct vkd3d_shader_location *loc); struct hlsl_ir_node *hlsl_new_stateblock_constant(struct hlsl_ctx *ctx, const char *name, struct vkd3d_shader_location *loc); @@ -5615,15 +6088,18 @@ index 27814f3a56f..7e8cd774ae2 100644 struct hlsl_ir_var *hlsl_new_synthetic_var(struct hlsl_ctx *ctx, const char *template, struct hlsl_type *type, const struct vkd3d_shader_location *loc); struct hlsl_ir_var *hlsl_new_synthetic_var_named(struct hlsl_ctx *ctx, const char *name, -@@ -1361,6 +1447,7 @@ struct hlsl_type *hlsl_new_texture_type(struct hlsl_ctx *ctx, enum hlsl_sampler_ +@@ -1361,8 +1452,10 @@ struct hlsl_type *hlsl_new_texture_type(struct hlsl_ctx *ctx, enum hlsl_sampler_ unsigned int sample_count); struct hlsl_type *hlsl_new_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim, struct hlsl_type *format, bool rasteriser_ordered); +struct hlsl_type *hlsl_new_cb_type(struct hlsl_ctx *ctx, struct hlsl_type *format); 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); struct hlsl_ir_node *hlsl_new_unary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg, -@@ -1432,10 +1519,16 @@ bool hlsl_transform_ir(struct hlsl_ctx *ctx, bool (*func)(struct hlsl_ctx *ctx, + const struct vkd3d_shader_location *loc); + struct hlsl_ir_var *hlsl_new_var(struct hlsl_ctx *ctx, const char *name, struct hlsl_type *type, +@@ -1432,10 +1525,16 @@ bool hlsl_transform_ir(struct hlsl_ctx *ctx, bool (*func)(struct hlsl_ctx *ctx, D3DXPARAMETER_CLASS hlsl_sm1_class(const struct hlsl_type *type); D3DXPARAMETER_TYPE hlsl_sm1_base_type(const struct hlsl_type *type); @@ -5645,7 +6121,7 @@ index 27814f3a56f..7e8cd774ae2 100644 bool hlsl_sm4_usage_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_semantic *semantic, bool output, D3D_NAME *usage); diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.l b/libs/vkd3d/libs/vkd3d-shader/hlsl.l -index a5923d8bf8e..b4db142f6c2 100644 +index a5923d8bf8e..0c02b27817e 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.l +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.l @@ -29,6 +29,8 @@ @@ -5671,7 +6147,23 @@ index a5923d8bf8e..b4db142f6c2 100644 IDENTIFIER [A-Za-z_][A-Za-z0-9_]* ANY (.) -@@ -164,6 +166,7 @@ textureCUBE {return KW_TEXTURECUBE; } +@@ -105,6 +107,7 @@ matrix {return KW_MATRIX; } + namespace {return KW_NAMESPACE; } + nointerpolation {return KW_NOINTERPOLATION; } + noperspective {return KW_NOPERSPECTIVE; } ++NULL {return KW_NULL; } + out {return KW_OUT; } + packoffset {return KW_PACKOFFSET; } + pass {return KW_PASS; } +@@ -142,6 +145,7 @@ stateblock {return KW_STATEBLOCK; } + stateblock_state {return KW_STATEBLOCK_STATE; } + static {return KW_STATIC; } + string {return KW_STRING; } ++String {return KW_STRING; } + struct {return KW_STRUCT; } + switch {return KW_SWITCH; } + tbuffer {return KW_TBUFFER; } +@@ -164,6 +168,7 @@ textureCUBE {return KW_TEXTURECUBE; } TextureCubeArray {return KW_TEXTURECUBEARRAY; } true {return KW_TRUE; } typedef {return KW_TYPEDEF; } @@ -5679,7 +6171,7 @@ index a5923d8bf8e..b4db142f6c2 100644 uniform {return KW_UNIFORM; } vector {return KW_VECTOR; } VertexShader {return KW_VERTEXSHADER; } -@@ -197,7 +200,9 @@ while {return KW_WHILE; } +@@ -197,7 +202,9 @@ while {return KW_WHILE; } struct hlsl_ctx *ctx = yyget_extra(yyscanner); yylval->name = hlsl_strdup(ctx, yytext); @@ -5690,7 +6182,7 @@ index a5923d8bf8e..b4db142f6c2 100644 return VAR_IDENTIFIER; else if (hlsl_get_type(ctx->cur_scope, yytext, true, true)) return TYPE_IDENTIFIER; -@@ -205,6 +210,16 @@ while {return KW_WHILE; } +@@ -205,6 +212,16 @@ while {return KW_WHILE; } return NEW_IDENTIFIER; } @@ -5707,7 +6199,7 @@ index a5923d8bf8e..b4db142f6c2 100644 [0-9]*\.[0-9]+([eE][+-]?[0-9]+)?[h|H|f|F]? { yylval->floatval = atof(yytext); return C_FLOAT; -@@ -289,6 +304,7 @@ while {return KW_WHILE; } +@@ -289,6 +306,7 @@ while {return KW_WHILE; } BEGIN(pp_ignore); string[strlen(string) - 1] = 0; @@ -5715,7 +6207,7 @@ index a5923d8bf8e..b4db142f6c2 100644 yylval->name = string; return STRING; } -@@ -338,3 +354,115 @@ int hlsl_lexer_compile(struct hlsl_ctx *ctx, const struct vkd3d_shader_code *hls +@@ -338,3 +356,115 @@ int hlsl_lexer_compile(struct hlsl_ctx *ctx, const struct vkd3d_shader_code *hls yylex_destroy(ctx->scanner); return ret; } @@ -5832,7 +6324,7 @@ index a5923d8bf8e..b4db142f6c2 100644 + str[k++] = '\0'; +} diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y -index 9c1bdef926d..30bd53d0c49 100644 +index 9c1bdef926d..3f319dea0d8 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y @@ -34,6 +34,14 @@ struct parse_fields @@ -5881,7 +6373,44 @@ index 9c1bdef926d..30bd53d0c49 100644 struct hlsl_type *basic_type; uint32_t modifiers; -@@ -342,11 +344,11 @@ static struct hlsl_ir_node *add_cast(struct hlsl_ctx *ctx, struct hlsl_block *bl +@@ -302,6 +304,26 @@ static bool implicit_compatible_data_types(struct hlsl_ctx *ctx, struct hlsl_typ + } + } + ++ if (src->class == HLSL_CLASS_NULL) ++ { ++ switch (dst->class) ++ { ++ case HLSL_CLASS_DEPTH_STENCIL_STATE: ++ case HLSL_CLASS_DEPTH_STENCIL_VIEW: ++ case HLSL_CLASS_PIXEL_SHADER: ++ case HLSL_CLASS_RASTERIZER_STATE: ++ case HLSL_CLASS_RENDER_TARGET_VIEW: ++ case HLSL_CLASS_SAMPLER: ++ case HLSL_CLASS_STRING: ++ case HLSL_CLASS_TEXTURE: ++ case HLSL_CLASS_UAV: ++ case HLSL_CLASS_VERTEX_SHADER: ++ return true; ++ default: ++ break; ++ } ++ } ++ + return hlsl_types_are_componentwise_equal(ctx, src, dst); + } + +@@ -329,6 +351,9 @@ static struct hlsl_ir_node *add_cast(struct hlsl_ctx *ctx, struct hlsl_block *bl + if (hlsl_types_are_equal(src_type, dst_type)) + return node; + ++ if (src_type->class == HLSL_CLASS_NULL) ++ return node; ++ + if (src_type->class > HLSL_CLASS_VECTOR || dst_type->class > HLSL_CLASS_VECTOR) + { + unsigned int src_comp_count = hlsl_type_component_count(src_type); +@@ -342,11 +367,11 @@ static struct hlsl_ir_node *add_cast(struct hlsl_ctx *ctx, struct hlsl_block *bl broadcast = hlsl_is_numeric_type(src_type) && src_type->dimx == 1 && src_type->dimy == 1; matrix_cast = !broadcast && dst_comp_count != src_comp_count && src_type->class == HLSL_CLASS_MATRIX && dst_type->class == HLSL_CLASS_MATRIX; @@ -5896,15 +6425,14 @@ index 9c1bdef926d..30bd53d0c49 100644 } if (!(var = hlsl_new_synthetic_var(ctx, "cast", dst_type, loc))) -@@ -573,12 +575,96 @@ static void check_loop_attributes(struct hlsl_ctx *ctx, const struct parse_attri +@@ -573,12 +598,104 @@ static void check_loop_attributes(struct hlsl_ctx *ctx, const struct parse_attri hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "Unroll attribute can't be used with 'fastopt' attribute."); } -+static union hlsl_constant_value_component evaluate_static_expression(struct hlsl_ctx *ctx, ++static struct hlsl_default_value evaluate_static_expression(struct hlsl_ctx *ctx, + struct hlsl_block *block, struct hlsl_type *dst_type, const struct vkd3d_shader_location *loc) +{ -+ union hlsl_constant_value_component ret = {0}; -+ struct hlsl_ir_constant *constant; ++ struct hlsl_default_value ret = {0}; + struct hlsl_ir_node *node; + struct hlsl_block expr; + struct hlsl_src src; @@ -5956,8 +6484,16 @@ index 9c1bdef926d..30bd53d0c49 100644 + + if (node->type == HLSL_IR_CONSTANT) + { -+ constant = hlsl_ir_constant(node); -+ ret = constant->value.u[0]; ++ struct hlsl_ir_constant *constant = hlsl_ir_constant(node); ++ ++ ret.number = constant->value.u[0]; ++ } ++ else if (node->type == HLSL_IR_STRING_CONSTANT) ++ { ++ struct hlsl_ir_string_constant *string = hlsl_ir_string_constant(node); ++ ++ if (!(ret.string = vkd3d_strdup(string->string))) ++ return ret; + } + else if (node->type == HLSL_IR_STRING_CONSTANT) + { @@ -5977,10 +6513,11 @@ index 9c1bdef926d..30bd53d0c49 100644 +static unsigned int evaluate_static_expression_as_uint(struct hlsl_ctx *ctx, struct hlsl_block *block, + const struct vkd3d_shader_location *loc) +{ -+ union hlsl_constant_value_component res; ++ struct hlsl_default_value res; + + res = evaluate_static_expression(ctx, block, hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), loc); -+ return res.u; ++ VKD3D_ASSERT(!res.string); ++ return res.number.u; +} + static struct hlsl_block *create_loop(struct hlsl_ctx *ctx, enum loop_type type, @@ -5994,7 +6531,7 @@ index 9c1bdef926d..30bd53d0c49 100644 if (attribute_list_has_duplicates(attributes)) hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "Found duplicate attribute."); -@@ -591,18 +677,29 @@ static struct hlsl_block *create_loop(struct hlsl_ctx *ctx, enum loop_type type, +@@ -591,18 +708,29 @@ static struct hlsl_block *create_loop(struct hlsl_ctx *ctx, enum loop_type type, const struct hlsl_attribute *attr = attributes->attrs[i]; if (!strcmp(attr->name, "unroll")) { @@ -6029,7 +6566,7 @@ index 9c1bdef926d..30bd53d0c49 100644 } else if (!strcmp(attr->name, "fastopt") || !strcmp(attr->name, "allow_uav_condition")) -@@ -631,7 +728,7 @@ static struct hlsl_block *create_loop(struct hlsl_ctx *ctx, enum loop_type type, +@@ -631,7 +759,7 @@ static struct hlsl_block *create_loop(struct hlsl_ctx *ctx, enum loop_type type, else list_move_head(&body->instrs, &cond->instrs); @@ -6038,7 +6575,7 @@ index 9c1bdef926d..30bd53d0c49 100644 goto oom; hlsl_block_add_instr(init, loop); -@@ -663,7 +760,7 @@ static void cleanup_parse_attribute_list(struct parse_attribute_list *attr_list) +@@ -663,7 +791,7 @@ static void cleanup_parse_attribute_list(struct parse_attribute_list *attr_list) { unsigned int i = 0; @@ -6047,7 +6584,7 @@ index 9c1bdef926d..30bd53d0c49 100644 for (i = 0; i < attr_list->count; ++i) hlsl_free_attribute((struct hlsl_attribute *) attr_list->attrs[i]); vkd3d_free(attr_list->attrs); -@@ -823,7 +920,7 @@ static bool add_record_access(struct hlsl_ctx *ctx, struct hlsl_block *block, st +@@ -823,7 +951,7 @@ static bool add_record_access(struct hlsl_ctx *ctx, struct hlsl_block *block, st { struct hlsl_ir_node *index, *c; @@ -6056,7 +6593,7 @@ index 9c1bdef926d..30bd53d0c49 100644 if (!(c = hlsl_new_uint_constant(ctx, idx, loc))) return false; -@@ -953,7 +1050,7 @@ static void free_parse_variable_def(struct parse_variable_def *v) +@@ -953,7 +1081,7 @@ 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); @@ -6065,7 +6602,7 @@ index 9c1bdef926d..30bd53d0c49 100644 vkd3d_free(v); } -@@ -964,7 +1061,7 @@ static bool gen_struct_fields(struct hlsl_ctx *ctx, struct parse_fields *fields, +@@ -964,7 +1092,7 @@ static bool gen_struct_fields(struct hlsl_ctx *ctx, struct parse_fields *fields, size_t i = 0; if (type->class == HLSL_CLASS_MATRIX) @@ -6074,7 +6611,7 @@ index 9c1bdef926d..30bd53d0c49 100644 memset(fields, 0, sizeof(*fields)); fields->count = list_count(defs); -@@ -1013,6 +1110,10 @@ static bool gen_struct_fields(struct hlsl_ctx *ctx, struct parse_fields *fields, +@@ -1013,6 +1141,10 @@ static bool gen_struct_fields(struct hlsl_ctx *ctx, struct parse_fields *fields, field->type = hlsl_new_array_type(ctx, field->type, v->arrays.sizes[k]); } } @@ -6085,7 +6622,7 @@ index 9c1bdef926d..30bd53d0c49 100644 vkd3d_free(v->arrays.sizes); field->loc = v->loc; field->name = v->name; -@@ -1094,13 +1195,16 @@ static bool add_typedef(struct hlsl_ctx *ctx, struct hlsl_type *const orig_type, +@@ -1094,13 +1226,16 @@ static bool add_typedef(struct hlsl_ctx *ctx, struct hlsl_type *const orig_type, return true; } @@ -6103,7 +6640,7 @@ index 9c1bdef926d..30bd53d0c49 100644 if ((param->modifiers & HLSL_STORAGE_OUT) && (param->modifiers & HLSL_STORAGE_UNIFORM)) hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, -@@ -1110,11 +1214,52 @@ static bool add_func_parameter(struct hlsl_ctx *ctx, struct hlsl_func_parameters +@@ -1110,11 +1245,52 @@ static bool add_func_parameter(struct hlsl_ctx *ctx, struct hlsl_func_parameters hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION, "packoffset() is not allowed on function parameters."); @@ -6156,7 +6693,7 @@ index 9c1bdef926d..30bd53d0c49 100644 if (!hlsl_add_var(ctx, var, false)) { hlsl_free_var(var); -@@ -1210,12 +1355,42 @@ static bool add_effect_group(struct hlsl_ctx *ctx, const char *name, struct hlsl +@@ -1210,12 +1386,42 @@ static bool add_effect_group(struct hlsl_ctx *ctx, const char *name, struct hlsl return true; } @@ -6203,7 +6740,7 @@ index 9c1bdef926d..30bd53d0c49 100644 return true; } -@@ -1286,72 +1461,6 @@ static struct hlsl_block *make_block(struct hlsl_ctx *ctx, struct hlsl_ir_node * +@@ -1286,72 +1492,6 @@ static struct hlsl_block *make_block(struct hlsl_ctx *ctx, struct hlsl_ir_node * return block; } @@ -6276,7 +6813,76 @@ index 9c1bdef926d..30bd53d0c49 100644 static bool expr_compatible_data_types(struct hlsl_type *t1, struct hlsl_type *t2) { /* Scalar vars can be converted to pretty much everything */ -@@ -1862,12 +1971,57 @@ static bool invert_swizzle(uint32_t *swizzle, unsigned int *writemask, unsigned +@@ -1759,49 +1899,51 @@ static struct hlsl_ir_node *add_binary_dot_expr(struct hlsl_ctx *ctx, struct hls + return add_expr(ctx, instrs, op, args, ret_type, loc); + } + +-static struct hlsl_block *add_binary_expr_merge(struct hlsl_ctx *ctx, struct hlsl_block *block1, +- struct hlsl_block *block2, enum hlsl_ir_expr_op op, const struct vkd3d_shader_location *loc) ++static struct hlsl_ir_node *add_binary_expr(struct hlsl_ctx *ctx, struct hlsl_block *block, enum hlsl_ir_expr_op op, ++ struct hlsl_ir_node *lhs, struct hlsl_ir_node *rhs, const struct vkd3d_shader_location *loc) + { +- struct hlsl_ir_node *arg1 = node_from_block(block1), *arg2 = node_from_block(block2); +- +- hlsl_block_add_block(block1, block2); +- destroy_block(block2); +- + switch (op) + { + case HLSL_OP2_ADD: + case HLSL_OP2_DIV: + case HLSL_OP2_MOD: + case HLSL_OP2_MUL: +- add_binary_arithmetic_expr(ctx, block1, op, arg1, arg2, loc); +- break; ++ return add_binary_arithmetic_expr(ctx, block, op, lhs, rhs, loc); + + case HLSL_OP2_BIT_AND: + case HLSL_OP2_BIT_OR: + case HLSL_OP2_BIT_XOR: +- add_binary_bitwise_expr(ctx, block1, op, arg1, arg2, loc); +- break; ++ return add_binary_bitwise_expr(ctx, block, op, lhs, rhs, loc); + + case HLSL_OP2_LESS: + case HLSL_OP2_GEQUAL: + case HLSL_OP2_EQUAL: + case HLSL_OP2_NEQUAL: +- add_binary_comparison_expr(ctx, block1, op, arg1, arg2, loc); +- break; ++ return add_binary_comparison_expr(ctx, block, op, lhs, rhs, loc); + + case HLSL_OP2_LOGIC_AND: + case HLSL_OP2_LOGIC_OR: +- add_binary_logical_expr(ctx, block1, op, arg1, arg2, loc); +- break; ++ return add_binary_logical_expr(ctx, block, op, lhs, rhs, loc); + + case HLSL_OP2_LSHIFT: + case HLSL_OP2_RSHIFT: +- add_binary_shift_expr(ctx, block1, op, arg1, arg2, loc); +- break; ++ return add_binary_shift_expr(ctx, block, op, lhs, rhs, loc); + + default: + vkd3d_unreachable(); + } ++} ++ ++static struct hlsl_block *add_binary_expr_merge(struct hlsl_ctx *ctx, struct hlsl_block *block1, ++ struct hlsl_block *block2, enum hlsl_ir_expr_op op, const struct vkd3d_shader_location *loc) ++{ ++ struct hlsl_ir_node *arg1 = node_from_block(block1), *arg2 = node_from_block(block2); ++ ++ hlsl_block_add_block(block1, block2); ++ destroy_block(block2); ++ ++ if (add_binary_expr(ctx, block1, op, arg1, arg2, loc) == NULL) ++ return NULL; + + return block1; + } +@@ -1862,12 +2004,57 @@ static bool invert_swizzle(uint32_t *swizzle, unsigned int *writemask, unsigned return true; } @@ -6335,13 +6941,14 @@ index 9c1bdef926d..30bd53d0c49 100644 if (assign_op == ASSIGN_OP_SUB) { -@@ -1879,13 +2033,16 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct hlsl_blo +@@ -1879,13 +2066,16 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct hlsl_blo { enum hlsl_ir_expr_op op = op_from_assignment(assign_op); - assert(op); +- if (!(rhs = add_binary_arithmetic_expr(ctx, block, op, lhs, rhs, &rhs->loc))) + VKD3D_ASSERT(op); - if (!(rhs = add_binary_arithmetic_expr(ctx, block, op, lhs, rhs, &rhs->loc))) ++ if (!(rhs = add_binary_expr(ctx, block, op, lhs, rhs, &rhs->loc))) return NULL; } @@ -6353,7 +6960,7 @@ index 9c1bdef926d..30bd53d0c49 100644 if (!(rhs = add_implicit_conversion(ctx, block, rhs, lhs_type, &rhs->loc))) return NULL; -@@ -1902,12 +2059,24 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct hlsl_blo +@@ -1902,12 +2092,24 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct hlsl_blo struct hlsl_ir_swizzle *swizzle = hlsl_ir_swizzle(lhs); struct hlsl_ir_node *new_swizzle; uint32_t s = swizzle->swizzle; @@ -6382,7 +6989,7 @@ index 9c1bdef926d..30bd53d0c49 100644 { hlsl_error(ctx, &lhs->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_WRITEMASK, "Invalid writemask."); return NULL; -@@ -1947,7 +2116,7 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct hlsl_blo +@@ -1947,7 +2149,7 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct hlsl_blo return NULL; resource_type = hlsl_deref_get_type(ctx, &resource_deref); @@ -6391,7 +6998,7 @@ index 9c1bdef926d..30bd53d0c49 100644 if (resource_type->class != HLSL_CLASS_UAV) hlsl_error(ctx, &lhs->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, -@@ -1955,13 +2124,13 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct hlsl_blo +@@ -1955,13 +2157,13 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct hlsl_blo dim_count = hlsl_sampler_dim_count(resource_type->sampler_dim); @@ -6409,7 +7016,7 @@ index 9c1bdef926d..30bd53d0c49 100644 if (!(store = hlsl_new_resource_store(ctx, &resource_deref, coords, rhs, &lhs->loc))) { -@@ -1971,12 +2140,50 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct hlsl_blo +@@ -1971,12 +2173,50 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct hlsl_blo hlsl_block_add_instr(block, store); hlsl_cleanup_deref(&resource_deref); } @@ -6460,7 +7067,7 @@ index 9c1bdef926d..30bd53d0c49 100644 for (i = 0; i < mat->data_type->dimx; ++i) { struct hlsl_ir_node *cell, *load, *store, *c; -@@ -2067,6 +2274,55 @@ static bool add_increment(struct hlsl_ctx *ctx, struct hlsl_block *block, bool d +@@ -2067,6 +2307,55 @@ static bool add_increment(struct hlsl_ctx *ctx, struct hlsl_block *block, bool d return true; } @@ -6516,7 +7123,7 @@ index 9c1bdef926d..30bd53d0c49 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) { -@@ -2087,12 +2343,33 @@ static void initialize_var_components(struct hlsl_ctx *ctx, struct hlsl_block *i +@@ -2087,12 +2376,33 @@ static void initialize_var_components(struct hlsl_ctx *ctx, struct hlsl_block *i dst_comp_type = hlsl_type_get_component_type(ctx, dst->data_type, *store_index); @@ -6532,7 +7139,7 @@ index 9c1bdef926d..30bd53d0c49 100644 - hlsl_block_add_block(instrs, &block); + if (!hlsl_clone_block(ctx, &block, instrs)) + return; -+ default_value.value = evaluate_static_expression(ctx, &block, dst_comp_type, &src->loc); ++ default_value = evaluate_static_expression(ctx, &block, dst_comp_type, &src->loc); + + if (dst->is_param) + dst_index = *store_index; @@ -6555,7 +7162,7 @@ index 9c1bdef926d..30bd53d0c49 100644 ++*store_index; } -@@ -2171,16 +2448,17 @@ static void declare_var(struct hlsl_ctx *ctx, struct parse_variable_def *v) +@@ -2171,16 +2481,17 @@ static void declare_var(struct hlsl_ctx *ctx, struct parse_variable_def *v) struct hlsl_semantic new_semantic; uint32_t modifiers = v->modifiers; bool unbounded_res_array = false; @@ -6575,7 +7182,7 @@ index 9c1bdef926d..30bd53d0c49 100644 type = basic_type; -@@ -2190,6 +2468,12 @@ static void declare_var(struct hlsl_ctx *ctx, struct parse_variable_def *v) +@@ -2190,6 +2501,12 @@ static void declare_var(struct hlsl_ctx *ctx, struct parse_variable_def *v) unbounded_res_array |= (v->arrays.sizes[i] == HLSL_ARRAY_ELEMENTS_COUNT_IMPLICIT); } @@ -6588,7 +7195,7 @@ index 9c1bdef926d..30bd53d0c49 100644 if (unbounded_res_array) { if (v->arrays.count == 1) -@@ -2246,17 +2530,22 @@ static void declare_var(struct hlsl_ctx *ctx, struct parse_variable_def *v) +@@ -2246,17 +2563,22 @@ static void declare_var(struct hlsl_ctx *ctx, struct parse_variable_def *v) } } @@ -6618,7 +7225,7 @@ index 9c1bdef926d..30bd53d0c49 100644 } if (!(var = hlsl_new_var(ctx, var_name, type, &v->loc, &new_semantic, modifiers, &v->reg_reservation))) -@@ -2266,7 +2555,18 @@ static void declare_var(struct hlsl_ctx *ctx, struct parse_variable_def *v) +@@ -2266,7 +2588,18 @@ static void declare_var(struct hlsl_ctx *ctx, struct parse_variable_def *v) return; } @@ -6638,7 +7245,7 @@ index 9c1bdef926d..30bd53d0c49 100644 if (var->buffer == ctx->globals_buffer) { -@@ -2289,8 +2589,11 @@ static void declare_var(struct hlsl_ctx *ctx, struct parse_variable_def *v) +@@ -2289,8 +2622,11 @@ static void declare_var(struct hlsl_ctx *ctx, struct parse_variable_def *v) if (!(modifiers & HLSL_STORAGE_STATIC)) var->storage_modifiers |= HLSL_STORAGE_UNIFORM; @@ -6651,7 +7258,7 @@ index 9c1bdef926d..30bd53d0c49 100644 if ((func = hlsl_get_first_func_decl(ctx, var->name))) { -@@ -2323,6 +2626,12 @@ static void declare_var(struct hlsl_ctx *ctx, struct parse_variable_def *v) +@@ -2323,6 +2659,12 @@ static void declare_var(struct hlsl_ctx *ctx, struct parse_variable_def *v) hlsl_error(ctx, &v->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_INITIALIZER, "Const variable \"%s\" is missing an initializer.", var->name); } @@ -6664,7 +7271,7 @@ index 9c1bdef926d..30bd53d0c49 100644 } if ((var->storage_modifiers & HLSL_STORAGE_STATIC) && type_has_numeric_components(var->data_type) -@@ -2348,6 +2657,7 @@ static struct hlsl_block *initialize_vars(struct hlsl_ctx *ctx, struct list *var +@@ -2348,6 +2690,7 @@ static struct hlsl_block *initialize_vars(struct hlsl_ctx *ctx, struct list *var { struct parse_variable_def *v, *v_next; struct hlsl_block *initializers; @@ -6672,7 +7279,7 @@ index 9c1bdef926d..30bd53d0c49 100644 struct hlsl_ir_var *var; struct hlsl_type *type; -@@ -2371,6 +2681,7 @@ static struct hlsl_block *initialize_vars(struct hlsl_ctx *ctx, struct list *var +@@ -2371,6 +2714,7 @@ static struct hlsl_block *initialize_vars(struct hlsl_ctx *ctx, struct list *var } type = var->data_type; @@ -6680,7 +7287,7 @@ index 9c1bdef926d..30bd53d0c49 100644 var->state_blocks = v->state_blocks; var->state_block_count = v->state_block_count; -@@ -2379,51 +2690,78 @@ static struct hlsl_block *initialize_vars(struct hlsl_ctx *ctx, struct list *var +@@ -2379,51 +2723,78 @@ static struct hlsl_block *initialize_vars(struct hlsl_ctx *ctx, struct list *var v->state_block_capacity = 0; v->state_blocks = NULL; @@ -6779,7 +7386,7 @@ index 9c1bdef926d..30bd53d0c49 100644 } else if (var->storage_modifiers & HLSL_STORAGE_STATIC) { -@@ -2469,14 +2807,18 @@ static bool func_is_compatible_match(struct hlsl_ctx *ctx, +@@ -2469,14 +2840,18 @@ static bool func_is_compatible_match(struct hlsl_ctx *ctx, { unsigned int i; @@ -6800,7 +7407,7 @@ index 9c1bdef926d..30bd53d0c49 100644 return true; } -@@ -2519,11 +2861,11 @@ static bool add_user_call(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *fu +@@ -2519,11 +2894,11 @@ static bool add_user_call(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *fu const struct parse_initializer *args, const struct vkd3d_shader_location *loc) { struct hlsl_ir_node *call; @@ -6815,7 +7422,7 @@ index 9c1bdef926d..30bd53d0c49 100644 { struct hlsl_ir_var *param = func->parameters.vars[i]; struct hlsl_ir_node *arg = args->args[i]; -@@ -2548,11 +2890,40 @@ static bool add_user_call(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *fu +@@ -2548,11 +2923,43 @@ static bool add_user_call(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *fu } } @@ -6837,14 +7444,17 @@ index 9c1bdef926d..30bd53d0c49 100644 + struct hlsl_ir_node *comp; + struct hlsl_block store_block; + -+ value.u[0] = param->default_values[j].value; -+ if (!(comp = hlsl_new_constant(ctx, type, &value, loc))) -+ return false; -+ hlsl_block_add_instr(args->instrs, comp); ++ if (!param->default_values[j].string) ++ { ++ value.u[0] = param->default_values[j].number; ++ if (!(comp = hlsl_new_constant(ctx, type, &value, loc))) ++ return false; ++ hlsl_block_add_instr(args->instrs, comp); + -+ if (!hlsl_new_store_component(ctx, &store_block, ¶m_deref, j, comp)) -+ return false; -+ hlsl_block_add_block(args->instrs, &store_block); ++ if (!hlsl_new_store_component(ctx, &store_block, ¶m_deref, j, comp)) ++ return false; ++ hlsl_block_add_block(args->instrs, &store_block); ++ } + } + } + @@ -6857,7 +7467,7 @@ index 9c1bdef926d..30bd53d0c49 100644 { struct hlsl_ir_var *param = func->parameters.vars[i]; struct hlsl_ir_node *arg = args->args[i]; -@@ -2699,6 +3070,19 @@ static bool elementwise_intrinsic_float_convert_args(struct hlsl_ctx *ctx, +@@ -2699,6 +3106,19 @@ static bool elementwise_intrinsic_float_convert_args(struct hlsl_ctx *ctx, return convert_args(ctx, params, type, loc); } @@ -6877,21 +7487,10 @@ index 9c1bdef926d..30bd53d0c49 100644 static bool intrinsic_abs(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { -@@ -2923,11 +3307,34 @@ static bool intrinsic_asfloat(struct hlsl_ctx *ctx, +@@ -2933,6 +3353,29 @@ static bool intrinsic_asfloat(struct hlsl_ctx *ctx, + return add_expr(ctx, params->instrs, HLSL_OP1_REINTERPRET, operands, data_type, loc); + } - if ((string = hlsl_type_to_string(ctx, data_type))) - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, -- "Wrong argument type of asfloat(): expected 'int', 'uint', 'float', or 'half', but got '%s'.", -+ "Wrong argument type of asfloat(): expected 'int', 'uint', 'float', or 'half', but got '%s'.", -+ string->buffer); -+ hlsl_release_string_buffer(ctx, string); -+ } -+ data_type = convert_numeric_type(ctx, data_type, HLSL_TYPE_FLOAT); -+ -+ operands[0] = params->args[0]; -+ return add_expr(ctx, params->instrs, HLSL_OP1_REINTERPRET, operands, data_type, loc); -+} -+ +static bool intrinsic_asint(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ @@ -6906,18 +7505,46 @@ index 9c1bdef926d..30bd53d0c49 100644 + if ((string = hlsl_type_to_string(ctx, data_type))) + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Wrong argument type of asint(): expected 'int', 'uint', 'float', or 'half', but got '%s'.", - string->buffer); - hlsl_release_string_buffer(ctx, string); - } -- data_type = convert_numeric_type(ctx, data_type, HLSL_TYPE_FLOAT); ++ string->buffer); ++ hlsl_release_string_buffer(ctx, string); ++ } + data_type = convert_numeric_type(ctx, data_type, HLSL_TYPE_INT); ++ ++ operands[0] = params->args[0]; ++ return add_expr(ctx, params->instrs, HLSL_OP1_REINTERPRET, operands, data_type, loc); ++} ++ + static bool intrinsic_asuint(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) + { +@@ -3331,26 +3774,69 @@ static bool intrinsic_exp(struct hlsl_ctx *ctx, + if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) + return false; - operands[0] = params->args[0]; - return add_expr(ctx, params->instrs, HLSL_OP1_REINTERPRET, operands, data_type, loc); -@@ -3353,6 +3760,49 @@ static bool intrinsic_exp2(struct hlsl_ctx *ctx, - return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_EXP2, arg, loc); - } - +- /* 1/ln(2) */ +- if (!(coeff = hlsl_new_float_constant(ctx, 1.442695f, loc))) ++ /* 1/ln(2) */ ++ if (!(coeff = hlsl_new_float_constant(ctx, 1.442695f, loc))) ++ return false; ++ hlsl_block_add_instr(params->instrs, coeff); ++ ++ if (!(mul = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, coeff, params->args[0], loc))) ++ return false; ++ ++ return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_EXP2, mul, loc); ++} ++ ++static bool intrinsic_exp2(struct hlsl_ctx *ctx, ++ const struct parse_initializer *params, const struct vkd3d_shader_location *loc) ++{ ++ struct hlsl_ir_node *arg; ++ ++ if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) ++ return false; ++ ++ return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_EXP2, arg, loc); ++} ++ +static bool intrinsic_faceforward(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ @@ -6932,39 +7559,44 @@ index 9c1bdef926d..30bd53d0c49 100644 + "}\n"; + + if (!(type = elementwise_intrinsic_get_common_type(ctx, params, loc))) -+ return false; + return false; +- hlsl_block_add_instr(params->instrs, coeff); + type = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_FLOAT, type->dimx, type->dimy); -+ + +- if (!(mul = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, coeff, params->args[0], loc))) + if (!(body = hlsl_sprintf_alloc(ctx, template, + type->name, type->name, type->name, type->name))) + return false; + func = hlsl_compile_internal_function(ctx, "faceforward", body); + vkd3d_free(body); + if (!func) -+ return false; -+ + return false; + +- return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_EXP2, mul, loc); + return add_user_call(ctx, func, params, loc); -+} -+ + } + +-static bool intrinsic_exp2(struct hlsl_ctx *ctx, +static bool intrinsic_f16tof32(struct hlsl_ctx *ctx, -+ const struct parse_initializer *params, const struct vkd3d_shader_location *loc) -+{ + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) + { +- struct hlsl_ir_node *arg; + struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {0}; + struct hlsl_type *type; -+ + +- if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) + if (!elementwise_intrinsic_uint_convert_args(ctx, params, loc)) -+ return false; -+ + return false; + +- return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_EXP2, arg, loc); + type = convert_numeric_type(ctx, params->args[0]->data_type, HLSL_TYPE_FLOAT); + + operands[0] = params->args[0]; + return add_expr(ctx, params->instrs, HLSL_OP1_F16TOF32, operands, type, loc); -+} -+ + } + static bool intrinsic_floor(struct hlsl_ctx *ctx, - const struct parse_initializer *params, const struct vkd3d_shader_location *loc) - { -@@ -3646,12 +4096,12 @@ static bool intrinsic_mul(struct hlsl_ctx *ctx, +@@ -3646,12 +4132,12 @@ static bool intrinsic_mul(struct hlsl_ctx *ctx, } else if (vect_count == 1) { @@ -6979,7 +7611,7 @@ index 9c1bdef926d..30bd53d0c49 100644 ret_type = hlsl_get_scalar_type(ctx, base); } -@@ -3764,6 +4214,17 @@ static bool intrinsic_radians(struct hlsl_ctx *ctx, +@@ -3764,6 +4250,17 @@ static bool intrinsic_radians(struct hlsl_ctx *ctx, return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, arg, rad, loc); } @@ -6997,7 +7629,7 @@ index 9c1bdef926d..30bd53d0c49 100644 static bool intrinsic_reflect(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { -@@ -3814,7 +4275,7 @@ static bool intrinsic_refract(struct hlsl_ctx *ctx, +@@ -3814,7 +4311,7 @@ static bool intrinsic_refract(struct hlsl_ctx *ctx, return false; } @@ -7006,7 +7638,7 @@ index 9c1bdef926d..30bd53d0c49 100644 mut_params = *params; mut_params.args_count = 2; if (!(res_type = elementwise_intrinsic_get_common_type(ctx, &mut_params, loc))) -@@ -4032,6 +4493,7 @@ static bool intrinsic_tanh(struct hlsl_ctx *ctx, +@@ -4032,6 +4529,7 @@ static bool intrinsic_tanh(struct hlsl_ctx *ctx, static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc, const char *name, enum hlsl_sampler_dim dim) { @@ -7014,7 +7646,7 @@ index 9c1bdef926d..30bd53d0c49 100644 struct hlsl_resource_load_params load_params = { 0 }; const struct hlsl_type *sampler_type; struct hlsl_ir_node *coords, *sample; -@@ -4043,11 +4505,6 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer * +@@ -4043,11 +4541,6 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer * return false; } @@ -7026,7 +7658,7 @@ index 9c1bdef926d..30bd53d0c49 100644 sampler_type = params->args[0]->data_type; if (sampler_type->class != HLSL_CLASS_SAMPLER || (sampler_type->sampler_dim != dim && sampler_type->sampler_dim != HLSL_SAMPLER_DIM_GENERIC)) -@@ -4061,18 +4518,22 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer * +@@ -4061,18 +4554,22 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer * hlsl_release_string_buffer(ctx, string); } @@ -7054,7 +7686,7 @@ index 9c1bdef926d..30bd53d0c49 100644 { return false; } -@@ -4099,14 +4560,13 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer * +@@ -4099,14 +4596,13 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer * if (hlsl_version_ge(ctx, 4, 0)) { @@ -7071,7 +7703,7 @@ index 9c1bdef926d..30bd53d0c49 100644 return false; hlsl_block_add_instr(params->instrs, coords); -@@ -4120,12 +4580,34 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer * +@@ -4120,12 +4616,34 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer * load_params.type = HLSL_RESOURCE_SAMPLE_PROJ; } } @@ -7107,7 +7739,7 @@ index 9c1bdef926d..30bd53d0c49 100644 { return false; } -@@ -4181,12 +4663,30 @@ static bool intrinsic_tex1D(struct hlsl_ctx *ctx, +@@ -4181,12 +4699,30 @@ static bool intrinsic_tex1D(struct hlsl_ctx *ctx, return intrinsic_tex(ctx, params, loc, "tex1D", HLSL_SAMPLER_DIM_1D); } @@ -7138,7 +7770,7 @@ index 9c1bdef926d..30bd53d0c49 100644 static bool intrinsic_tex2Dlod(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { -@@ -4205,6 +4705,12 @@ static bool intrinsic_tex3D(struct hlsl_ctx *ctx, +@@ -4205,6 +4741,12 @@ static bool intrinsic_tex3D(struct hlsl_ctx *ctx, return intrinsic_tex(ctx, params, loc, "tex3D", HLSL_SAMPLER_DIM_3D); } @@ -7151,7 +7783,7 @@ index 9c1bdef926d..30bd53d0c49 100644 static bool intrinsic_tex3Dproj(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { -@@ -4217,6 +4723,12 @@ static bool intrinsic_texCUBE(struct hlsl_ctx *ctx, +@@ -4217,6 +4759,12 @@ static bool intrinsic_texCUBE(struct hlsl_ctx *ctx, return intrinsic_tex(ctx, params, loc, "texCUBE", HLSL_SAMPLER_DIM_CUBE); } @@ -7164,7 +7796,7 @@ index 9c1bdef926d..30bd53d0c49 100644 static bool intrinsic_texCUBEproj(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { -@@ -4336,6 +4848,20 @@ static bool intrinsic_d3dcolor_to_ubyte4(struct hlsl_ctx *ctx, +@@ -4336,6 +4884,20 @@ static bool intrinsic_d3dcolor_to_ubyte4(struct hlsl_ctx *ctx, return true; } @@ -7185,7 +7817,7 @@ index 9c1bdef926d..30bd53d0c49 100644 static const struct intrinsic_function { const char *name; -@@ -4348,12 +4874,14 @@ intrinsic_functions[] = +@@ -4348,12 +4910,14 @@ intrinsic_functions[] = { /* Note: these entries should be kept in alphabetical order. */ {"D3DCOLORtoUBYTE4", 1, true, intrinsic_d3dcolor_to_ubyte4}, @@ -7200,7 +7832,7 @@ index 9c1bdef926d..30bd53d0c49 100644 {"asuint", -1, true, intrinsic_asuint}, {"atan", 1, true, intrinsic_atan}, {"atan2", 2, true, intrinsic_atan2}, -@@ -4375,6 +4903,8 @@ intrinsic_functions[] = +@@ -4375,6 +4939,8 @@ intrinsic_functions[] = {"dot", 2, true, intrinsic_dot}, {"exp", 1, true, intrinsic_exp}, {"exp2", 1, true, intrinsic_exp2}, @@ -7209,7 +7841,7 @@ index 9c1bdef926d..30bd53d0c49 100644 {"floor", 1, true, intrinsic_floor}, {"fmod", 2, true, intrinsic_fmod}, {"frac", 1, true, intrinsic_frac}, -@@ -4392,6 +4922,7 @@ intrinsic_functions[] = +@@ -4392,6 +4958,7 @@ intrinsic_functions[] = {"normalize", 1, true, intrinsic_normalize}, {"pow", 2, true, intrinsic_pow}, {"radians", 1, true, intrinsic_radians}, @@ -7217,7 +7849,7 @@ index 9c1bdef926d..30bd53d0c49 100644 {"reflect", 2, true, intrinsic_reflect}, {"refract", 3, true, intrinsic_refract}, {"round", 1, true, intrinsic_round}, -@@ -4406,12 +4937,17 @@ intrinsic_functions[] = +@@ -4406,12 +4973,17 @@ intrinsic_functions[] = {"tan", 1, true, intrinsic_tan}, {"tanh", 1, true, intrinsic_tanh}, {"tex1D", -1, false, intrinsic_tex1D}, @@ -7235,7 +7867,7 @@ index 9c1bdef926d..30bd53d0c49 100644 {"texCUBEproj", 2, false, intrinsic_texCUBEproj}, {"transpose", 1, true, intrinsic_transpose}, {"trunc", 1, true, intrinsic_trunc}, -@@ -4599,7 +5135,7 @@ static bool add_ternary(struct hlsl_ctx *ctx, struct hlsl_block *block, +@@ -4599,7 +5171,7 @@ static bool add_ternary(struct hlsl_ctx *ctx, struct hlsl_block *block, common_type = first->data_type; } @@ -7244,7 +7876,7 @@ index 9c1bdef926d..30bd53d0c49 100644 args[0] = cond; args[1] = first; -@@ -5481,6 +6017,7 @@ static bool state_block_add_entry(struct hlsl_state_block *state_block, struct h +@@ -5481,6 +6053,7 @@ static bool state_block_add_entry(struct hlsl_state_block *state_block, struct h %token KW_BREAK %token KW_BUFFER %token KW_CASE @@ -7252,7 +7884,15 @@ index 9c1bdef926d..30bd53d0c49 100644 %token KW_CBUFFER %token KW_CENTROID %token KW_COLUMN_MAJOR -@@ -5566,6 +6103,7 @@ static bool state_block_add_entry(struct hlsl_state_block *state_block, struct h +@@ -5513,6 +6086,7 @@ static bool state_block_add_entry(struct hlsl_state_block *state_block, struct h + %token KW_NAMESPACE + %token KW_NOINTERPOLATION + %token KW_NOPERSPECTIVE ++%token KW_NULL + %token KW_OUT + %token KW_PACKOFFSET + %token KW_PASS +@@ -5566,6 +6140,7 @@ static bool state_block_add_entry(struct hlsl_state_block *state_block, struct h %token KW_TEXTURECUBEARRAY %token KW_TRUE %token KW_TYPEDEF @@ -7260,7 +7900,7 @@ index 9c1bdef926d..30bd53d0c49 100644 %token KW_UNIFORM %token KW_VECTOR %token KW_VERTEXSHADER -@@ -5670,6 +6208,8 @@ static bool state_block_add_entry(struct hlsl_state_block *state_block, struct h +@@ -5670,6 +6245,8 @@ static bool state_block_add_entry(struct hlsl_state_block *state_block, struct h %type if_body @@ -7269,7 +7909,7 @@ index 9c1bdef926d..30bd53d0c49 100644 %type var_modifiers %type any_identifier -@@ -5678,6 +6218,7 @@ static bool state_block_add_entry(struct hlsl_state_block *state_block, struct h +@@ -5678,6 +6255,7 @@ static bool state_block_add_entry(struct hlsl_state_block *state_block, struct h %type name_opt %type parameter @@ -7277,7 +7917,7 @@ index 9c1bdef926d..30bd53d0c49 100644 %type param_list %type parameters -@@ -5717,8 +6258,7 @@ hlsl_prog: +@@ -5717,8 +6295,7 @@ hlsl_prog: | hlsl_prog buffer_declaration buffer_body | hlsl_prog declaration_statement { @@ -7287,7 +7927,7 @@ index 9c1bdef926d..30bd53d0c49 100644 destroy_block($2); } | hlsl_prog preproc_directive -@@ -5742,19 +6282,31 @@ pass: +@@ -5742,19 +6319,31 @@ pass: annotations_list: variables_def_typed ';' @@ -7321,7 +7961,7 @@ index 9c1bdef926d..30bd53d0c49 100644 { struct hlsl_scope *scope = ctx->cur_scope; -@@ -6083,7 +6635,7 @@ func_declaration: +@@ -6083,7 +6672,7 @@ func_declaration: if (!$1.first) { @@ -7330,7 +7970,7 @@ index 9c1bdef926d..30bd53d0c49 100644 for (i = 0; i < $1.parameters.count; ++i) { -@@ -6198,7 +6750,7 @@ func_prototype_no_attrs: +@@ -6198,7 +6787,7 @@ func_prototype_no_attrs: * brittle and ugly. */ @@ -7339,7 +7979,7 @@ index 9c1bdef926d..30bd53d0c49 100644 for (i = 0; i < params->count; ++i) { struct hlsl_ir_var *orig_param = params->vars[i]; -@@ -6282,6 +6834,13 @@ switch_scope_start: +@@ -6282,6 +6871,13 @@ switch_scope_start: ctx->cur_scope->_switch = true; } @@ -7353,7 +7993,7 @@ index 9c1bdef926d..30bd53d0c49 100644 var_identifier: VAR_IDENTIFIER | NEW_IDENTIFIER -@@ -6315,6 +6874,9 @@ semantic: +@@ -6315,6 +6911,9 @@ semantic: { char *p; @@ -7363,7 +8003,7 @@ index 9c1bdef926d..30bd53d0c49 100644 for (p = $2 + strlen($2); p > $2 && isdigit(p[-1]); --p) ; $$.name = $2; -@@ -6330,22 +6892,34 @@ register_reservation: +@@ -6330,22 +6929,34 @@ register_reservation: ':' KW_REGISTER '(' any_identifier ')' { memset(&$$, 0, sizeof($$)); @@ -7401,7 +8041,7 @@ index 9c1bdef926d..30bd53d0c49 100644 hlsl_error(ctx, &@4, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION, "Invalid register reservation '%s'.", $4); } -@@ -6358,12 +6932,45 @@ register_reservation: +@@ -6358,12 +6969,45 @@ register_reservation: vkd3d_free($4); vkd3d_free($6); } @@ -7448,7 +8088,7 @@ index 9c1bdef926d..30bd53d0c49 100644 hlsl_error(ctx, &@6, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION, "Invalid register reservation '%s'.", $6); -@@ -6375,6 +6982,26 @@ register_reservation: +@@ -6375,6 +7019,26 @@ register_reservation: vkd3d_free($6); vkd3d_free($8); } @@ -7475,7 +8115,7 @@ index 9c1bdef926d..30bd53d0c49 100644 packoffset_reservation: ':' KW_PACKOFFSET '(' any_identifier ')' -@@ -6427,6 +7054,14 @@ param_list: +@@ -6427,6 +7091,14 @@ param_list: } parameter: @@ -7490,7 +8130,7 @@ index 9c1bdef926d..30bd53d0c49 100644 var_modifiers type_no_void any_identifier arrays colon_attribute { uint32_t modifiers = $1; -@@ -6449,11 +7084,18 @@ parameter: +@@ -6449,11 +7121,18 @@ parameter: } type = hlsl_new_array_type(ctx, type, $4.sizes[i]); } @@ -7509,7 +8149,20 @@ index 9c1bdef926d..30bd53d0c49 100644 } texture_type: -@@ -6696,6 +7338,10 @@ type_no_void: +@@ -6662,12 +7341,6 @@ type_no_void: + { + validate_texture_format_type(ctx, $3, &@3); + +- if (hlsl_version_lt(ctx, 4, 1)) +- { +- hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, +- "Multisampled texture object declaration needs sample count for profile %s.", ctx->profile->name); +- } +- + $$ = hlsl_new_texture_type(ctx, $1, $3, 0); + } + | texture_ms_type '<' type ',' shift_expr '>' +@@ -6696,6 +7369,10 @@ type_no_void: validate_uav_type(ctx, $1, $3, &@3); $$ = hlsl_new_uav_type(ctx, $1, $3, true); } @@ -7520,7 +8173,7 @@ index 9c1bdef926d..30bd53d0c49 100644 | TYPE_IDENTIFIER { $$ = hlsl_get_type(ctx->cur_scope, $1, true, true); -@@ -6713,6 +7359,26 @@ type_no_void: +@@ -6713,6 +7390,26 @@ type_no_void: } vkd3d_free($1); } @@ -7547,7 +8200,7 @@ index 9c1bdef926d..30bd53d0c49 100644 | KW_STRUCT TYPE_IDENTIFIER { $$ = hlsl_get_type(ctx->cur_scope, $2, true, true); -@@ -6724,6 +7390,10 @@ type_no_void: +@@ -6724,6 +7421,10 @@ type_no_void: { $$ = hlsl_get_type(ctx->cur_scope, "RenderTargetView", true, true); } @@ -7558,7 +8211,7 @@ index 9c1bdef926d..30bd53d0c49 100644 | KW_DEPTHSTENCILVIEW { $$ = hlsl_get_type(ctx->cur_scope, "DepthStencilView", true, true); -@@ -6736,6 +7406,33 @@ type_no_void: +@@ -6736,6 +7437,37 @@ type_no_void: { $$ = hlsl_get_type(ctx->cur_scope, "PixelShader", true, true); } @@ -7588,11 +8241,15 @@ index 9c1bdef926d..30bd53d0c49 100644 + | KW_RASTERIZERSTATE + { + $$ = hlsl_get_type(ctx->cur_scope, "RasterizerState", true, true); ++ } ++ | KW_BLENDSTATE ++ { ++ $$ = hlsl_get_type(ctx->cur_scope, "BlendState", true, true); + } type: type_no_void -@@ -6840,10 +7537,10 @@ variables_def_typed: +@@ -6840,10 +7572,10 @@ variables_def_typed: { struct parse_variable_def *head_def; @@ -7605,7 +8262,7 @@ index 9c1bdef926d..30bd53d0c49 100644 $3->basic_type = head_def->basic_type; $3->modifiers = head_def->modifiers; $3->modifiers_loc = head_def->modifiers_loc; -@@ -6855,7 +7552,7 @@ variables_def_typed: +@@ -6855,7 +7587,7 @@ variables_def_typed: } variable_decl: @@ -7614,7 +8271,7 @@ index 9c1bdef926d..30bd53d0c49 100644 { $$ = hlsl_alloc(ctx, sizeof(*$$)); $$->loc = @1; -@@ -6863,6 +7560,7 @@ variable_decl: +@@ -6863,6 +7595,7 @@ variable_decl: $$->arrays = $2; $$->semantic = $3.semantic; $$->reg_reservation = $3.reg_reservation; @@ -7622,7 +8279,7 @@ index 9c1bdef926d..30bd53d0c49 100644 } state_block_start: -@@ -6932,6 +7630,34 @@ state_block: +@@ -6932,6 +7665,34 @@ state_block: hlsl_src_from_node(&entry->args[i], $5.args[i]); vkd3d_free($5.args); @@ -7657,7 +8314,7 @@ index 9c1bdef926d..30bd53d0c49 100644 $$ = $1; state_block_add_entry($$, entry); } -@@ -7020,52 +7746,43 @@ variable_def_typed: +@@ -7020,52 +7781,43 @@ variable_def_typed: $$->modifiers_loc = @1; } @@ -7675,14 +8332,14 @@ index 9c1bdef926d..30bd53d0c49 100644 { - uint32_t *new_array; - unsigned int size; -+ $$ = evaluate_static_expression_as_uint(ctx, $2, &@2); - +- - size = evaluate_static_expression_as_uint(ctx, $2, &@2); - - destroy_block($2); - - $$ = $4; -- ++ $$ = evaluate_static_expression_as_uint(ctx, $2, &@2); + - if (!size) + if (!$$) { @@ -7728,7 +8385,7 @@ index 9c1bdef926d..30bd53d0c49 100644 if (!(new_array = hlsl_realloc(ctx, $$.sizes, ($$.count + 1) * sizeof(*new_array)))) { -@@ -7074,7 +7791,7 @@ arrays: +@@ -7074,7 +7826,7 @@ arrays: } $$.sizes = new_array; @@ -7737,7 +8394,7 @@ index 9c1bdef926d..30bd53d0c49 100644 } var_modifiers: -@@ -7156,6 +7873,8 @@ var_modifiers: +@@ -7156,6 +7908,8 @@ var_modifiers: } | var_identifier var_modifiers { @@ -7746,7 +8403,7 @@ index 9c1bdef926d..30bd53d0c49 100644 if (!strcmp($1, "precise")) $$ = add_modifiers(ctx, $2, HLSL_MODIFIER_PRECISE, &@1); else if (!strcmp($1, "single")) -@@ -7587,6 +8306,23 @@ primary_expr: +@@ -7587,6 +8341,35 @@ primary_expr: YYABORT; } } @@ -7766,12 +8423,24 @@ index 9c1bdef926d..30bd53d0c49 100644 + hlsl_free_instr(c); + YYABORT; + } ++ } ++ | KW_NULL ++ { ++ struct hlsl_ir_node *c; ++ ++ if (!(c = hlsl_new_null_constant(ctx, &@1))) ++ YYABORT; ++ if (!($$ = make_block(ctx, c))) ++ { ++ hlsl_free_instr(c); ++ YYABORT; ++ } + } | VAR_IDENTIFIER { struct hlsl_ir_load *load; diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -index bdb72a1fab9..049461cdb7d 100644 +index bdb72a1fab9..a695eefabf6 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c @@ -20,6 +20,7 @@ @@ -7947,7 +8616,7 @@ index bdb72a1fab9..049461cdb7d 100644 continue; } -@@ -1623,27 +1632,34 @@ static bool copy_propagation_transform_load(struct hlsl_ctx *ctx, +@@ -1623,27 +1632,36 @@ static bool copy_propagation_transform_load(struct hlsl_ctx *ctx, switch (type->class) { @@ -7967,6 +8636,8 @@ index bdb72a1fab9..049461cdb7d 100644 + case HLSL_CLASS_RENDER_TARGET_VIEW: + case HLSL_CLASS_DEPTH_STENCIL_VIEW: + case HLSL_CLASS_GEOMETRY_SHADER: ++ case HLSL_CLASS_BLEND_STATE: ++ case HLSL_CLASS_NULL: break; case HLSL_CLASS_MATRIX: @@ -7985,7 +8656,7 @@ index bdb72a1fab9..049461cdb7d 100644 case HLSL_CLASS_TECHNIQUE: case HLSL_CLASS_VOID: vkd3d_unreachable(); -@@ -1685,11 +1701,11 @@ static bool copy_propagation_transform_object_load(struct hlsl_ctx *ctx, +@@ -1685,11 +1703,11 @@ static bool copy_propagation_transform_object_load(struct hlsl_ctx *ctx, if (!hlsl_component_index_range_from_deref(ctx, deref, &start, &count)) return false; @@ -7999,7 +8670,7 @@ index bdb72a1fab9..049461cdb7d 100644 /* Only HLSL_IR_LOAD can produce an object. */ load = hlsl_ir_load(value->node); -@@ -1970,6 +1986,76 @@ bool hlsl_copy_propagation_execute(struct hlsl_ctx *ctx, struct hlsl_block *bloc +@@ -1970,6 +1988,76 @@ bool hlsl_copy_propagation_execute(struct hlsl_ctx *ctx, struct hlsl_block *bloc return progress; } @@ -8076,7 +8747,7 @@ index bdb72a1fab9..049461cdb7d 100644 static void note_non_static_deref_expressions(struct hlsl_ctx *ctx, const struct hlsl_deref *deref, const char *usage) { -@@ -1979,7 +2065,7 @@ static void note_non_static_deref_expressions(struct hlsl_ctx *ctx, const struct +@@ -1979,7 +2067,7 @@ static void note_non_static_deref_expressions(struct hlsl_ctx *ctx, const struct { struct hlsl_ir_node *path_node = deref->path[i].node; @@ -8085,7 +8756,7 @@ index bdb72a1fab9..049461cdb7d 100644 if (path_node->type != HLSL_IR_CONSTANT) hlsl_note(ctx, &path_node->loc, VKD3D_SHADER_LOG_ERROR, "Expression for %s within \"%s\" cannot be resolved statically.", -@@ -1987,60 +2073,77 @@ static void note_non_static_deref_expressions(struct hlsl_ctx *ctx, const struct +@@ -1987,60 +2075,77 @@ static void note_non_static_deref_expressions(struct hlsl_ctx *ctx, const struct } } @@ -8199,7 +8870,7 @@ index bdb72a1fab9..049461cdb7d 100644 } return false; -@@ -2436,7 +2539,7 @@ static bool lower_nonconstant_vector_derefs(struct hlsl_ctx *ctx, struct hlsl_ir +@@ -2436,7 +2541,7 @@ static bool lower_nonconstant_vector_derefs(struct hlsl_ctx *ctx, struct hlsl_ir return false; deref = &hlsl_ir_load(instr)->src; @@ -8208,7 +8879,7 @@ index bdb72a1fab9..049461cdb7d 100644 if (deref->path_len == 0) return false; -@@ -2510,7 +2613,7 @@ static bool validate_nonconstant_vector_store_derefs(struct hlsl_ctx *ctx, struc +@@ -2510,7 +2615,7 @@ static bool validate_nonconstant_vector_store_derefs(struct hlsl_ctx *ctx, struc return false; deref = &hlsl_ir_store(instr)->lhs; @@ -8217,7 +8888,7 @@ index bdb72a1fab9..049461cdb7d 100644 if (deref->path_len == 0) return false; -@@ -2531,6 +2634,124 @@ static bool validate_nonconstant_vector_store_derefs(struct hlsl_ctx *ctx, struc +@@ -2531,6 +2636,124 @@ static bool validate_nonconstant_vector_store_derefs(struct hlsl_ctx *ctx, struc return false; } @@ -8342,7 +9013,7 @@ index bdb72a1fab9..049461cdb7d 100644 /* Lower combined samples and sampler variables to synthesized separated textures and samplers. * That is, translate SM1-style samples in the source to SM4-style samples in the bytecode. */ static bool lower_combined_samples(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) -@@ -2554,11 +2775,11 @@ static bool lower_combined_samples(struct hlsl_ctx *ctx, struct hlsl_ir_node *in +@@ -2554,11 +2777,11 @@ static bool lower_combined_samples(struct hlsl_ctx *ctx, struct hlsl_ir_node *in case HLSL_RESOURCE_RESINFO: case HLSL_RESOURCE_SAMPLE_CMP: case HLSL_RESOURCE_SAMPLE_CMP_LZ: @@ -8355,7 +9026,7 @@ index bdb72a1fab9..049461cdb7d 100644 case HLSL_RESOURCE_SAMPLE_LOD: case HLSL_RESOURCE_SAMPLE_LOD_BIAS: case HLSL_RESOURCE_SAMPLE_PROJ: -@@ -2573,7 +2794,7 @@ static bool lower_combined_samples(struct hlsl_ctx *ctx, struct hlsl_ir_node *in +@@ -2573,7 +2796,7 @@ static bool lower_combined_samples(struct hlsl_ctx *ctx, struct hlsl_ir_node *in return false; } @@ -8364,7 +9035,7 @@ index bdb72a1fab9..049461cdb7d 100644 if (!(name = hlsl_get_string_buffer(ctx))) return false; -@@ -2590,7 +2811,7 @@ static bool lower_combined_samples(struct hlsl_ctx *ctx, struct hlsl_ir_node *in +@@ -2590,7 +2813,7 @@ static bool lower_combined_samples(struct hlsl_ctx *ctx, struct hlsl_ir_node *in struct hlsl_type *arr_type = load->resource.var->data_type; for (i = 0; i < load->resource.path_len; ++i) { @@ -8373,7 +9044,7 @@ index bdb72a1fab9..049461cdb7d 100644 texture_array_type = hlsl_new_array_type(ctx, texture_array_type, arr_type->e.array.elements_count); arr_type = arr_type->e.array.type; } -@@ -2619,8 +2840,8 @@ static bool lower_combined_samples(struct hlsl_ctx *ctx, struct hlsl_ir_node *in +@@ -2619,8 +2842,8 @@ static bool lower_combined_samples(struct hlsl_ctx *ctx, struct hlsl_ir_node *in hlsl_copy_deref(ctx, &load->sampler, &load->resource); load->resource.var = var; @@ -8384,7 +9055,7 @@ index bdb72a1fab9..049461cdb7d 100644 return true; } -@@ -2918,6 +3139,108 @@ static bool lower_floor(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct +@@ -2918,6 +3141,108 @@ static bool lower_floor(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct return true; } @@ -8493,7 +9164,7 @@ index bdb72a1fab9..049461cdb7d 100644 static bool lower_logic_not(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS]; -@@ -2936,7 +3259,7 @@ static bool lower_logic_not(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, st +@@ -2936,7 +3261,7 @@ static bool lower_logic_not(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, st float_type = hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, arg->data_type->dimx); /* If this is happens, it means we failed to cast the argument to boolean somewhere. */ @@ -8502,7 +9173,7 @@ index bdb72a1fab9..049461cdb7d 100644 if (!(arg_cast = hlsl_new_cast(ctx, arg, float_type, &arg->loc))) return false; -@@ -2992,7 +3315,7 @@ static bool lower_ternary(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, stru +@@ -2992,7 +3317,7 @@ static bool lower_ternary(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, stru return false; } @@ -8511,7 +9182,7 @@ index bdb72a1fab9..049461cdb7d 100644 type = hlsl_get_numeric_type(ctx, instr->data_type->class, HLSL_TYPE_FLOAT, instr->data_type->dimx, instr->data_type->dimy); -@@ -3290,7 +3613,7 @@ static bool lower_casts_to_bool(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr +@@ -3290,7 +3615,7 @@ static bool lower_casts_to_bool(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr return false; /* Narrowing casts should have already been lowered. */ @@ -8520,7 +9191,7 @@ index bdb72a1fab9..049461cdb7d 100644 zero = hlsl_new_constant(ctx, arg_type, &zero_value, &instr->loc); if (!zero) -@@ -3312,7 +3635,7 @@ struct hlsl_ir_node *hlsl_add_conditional(struct hlsl_ctx *ctx, struct hlsl_bloc +@@ -3312,7 +3637,7 @@ struct hlsl_ir_node *hlsl_add_conditional(struct hlsl_ctx *ctx, struct hlsl_bloc struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS]; struct hlsl_ir_node *cond; @@ -8529,7 +9200,7 @@ index bdb72a1fab9..049461cdb7d 100644 if (cond_type->e.numeric.type != HLSL_TYPE_BOOL) { -@@ -3511,7 +3834,7 @@ static bool lower_int_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, stru +@@ -3511,7 +3836,7 @@ static bool lower_int_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, stru { arg1 = expr->operands[0].node; arg2 = expr->operands[1].node; @@ -8538,7 +9209,7 @@ index bdb72a1fab9..049461cdb7d 100644 dimx = arg1->data_type->dimx; is_bool = type->e.numeric.type == HLSL_TYPE_BOOL; -@@ -3729,6 +4052,7 @@ static bool dce(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +@@ -3729,6 +4054,7 @@ static bool dce(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) case HLSL_IR_INDEX: case HLSL_IR_LOAD: case HLSL_IR_RESOURCE_LOAD: @@ -8546,7 +9217,7 @@ index bdb72a1fab9..049461cdb7d 100644 case HLSL_IR_SWIZZLE: if (list_empty(&instr->uses)) { -@@ -3786,8 +4110,8 @@ static bool mark_indexable_vars(struct hlsl_ctx *ctx, struct hlsl_deref *deref, +@@ -3786,8 +4112,8 @@ static bool mark_indexable_vars(struct hlsl_ctx *ctx, struct hlsl_deref *deref, if (!deref->rel_offset.node) return false; @@ -8557,7 +9228,7 @@ index bdb72a1fab9..049461cdb7d 100644 deref->var->indexable = true; return true; -@@ -3815,15 +4139,16 @@ static void allocate_register_reservations(struct hlsl_ctx *ctx) +@@ -3815,15 +4141,16 @@ static void allocate_register_reservations(struct hlsl_ctx *ctx) LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) { @@ -8576,7 +9247,7 @@ index bdb72a1fab9..049461cdb7d 100644 { struct vkd3d_string_buffer *type_string; -@@ -3839,10 +4164,8 @@ static void allocate_register_reservations(struct hlsl_ctx *ctx) +@@ -3839,10 +4166,8 @@ static void allocate_register_reservations(struct hlsl_ctx *ctx) else { var->regs[r].allocated = true; @@ -8589,7 +9260,7 @@ index bdb72a1fab9..049461cdb7d 100644 } } } -@@ -4010,6 +4333,7 @@ static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop +@@ -4010,6 +4335,7 @@ static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop break; } case HLSL_IR_CONSTANT: @@ -8597,7 +9268,7 @@ index bdb72a1fab9..049461cdb7d 100644 break; } } -@@ -4111,7 +4435,7 @@ static struct hlsl_reg allocate_register(struct hlsl_ctx *ctx, struct register_a +@@ -4111,7 +4437,7 @@ static struct hlsl_reg allocate_register(struct hlsl_ctx *ctx, struct register_a unsigned int writemask; uint32_t reg_idx; @@ -8606,7 +9277,7 @@ index bdb72a1fab9..049461cdb7d 100644 for (reg_idx = 0;; ++reg_idx) { -@@ -4133,6 +4457,30 @@ static struct hlsl_reg allocate_register(struct hlsl_ctx *ctx, struct register_a +@@ -4133,6 +4459,30 @@ static struct hlsl_reg allocate_register(struct hlsl_ctx *ctx, struct register_a return ret; } @@ -8637,7 +9308,7 @@ index bdb72a1fab9..049461cdb7d 100644 static bool is_range_available(const struct register_allocator *allocator, unsigned int first_write, unsigned int last_read, uint32_t reg_idx, unsigned int reg_size) { -@@ -4181,8 +4529,10 @@ static struct hlsl_reg allocate_numeric_registers_for_type(struct hlsl_ctx *ctx, +@@ -4181,8 +4531,10 @@ static struct hlsl_reg allocate_numeric_registers_for_type(struct hlsl_ctx *ctx, { unsigned int reg_size = type->reg_size[HLSL_REGSET_NUMERIC]; @@ -8649,7 +9320,7 @@ index bdb72a1fab9..049461cdb7d 100644 else return allocate_range(ctx, allocator, first_write, last_read, reg_size); } -@@ -4224,7 +4574,7 @@ static bool track_object_components_sampler_dim(struct hlsl_ctx *ctx, struct hls +@@ -4224,7 +4576,7 @@ static bool track_object_components_sampler_dim(struct hlsl_ctx *ctx, struct hls { enum hlsl_sampler_dim dim; @@ -8658,7 +9329,7 @@ index bdb72a1fab9..049461cdb7d 100644 dim = var->objects_usage[regset][index].sampler_dim; if (dim != load->sampling_dim) -@@ -4334,6 +4684,44 @@ static void calculate_resource_register_counts(struct hlsl_ctx *ctx) +@@ -4334,6 +4686,44 @@ static void calculate_resource_register_counts(struct hlsl_ctx *ctx) } } @@ -8703,7 +9374,7 @@ index bdb72a1fab9..049461cdb7d 100644 static void allocate_variable_temp_register(struct hlsl_ctx *ctx, struct hlsl_ir_var *var, struct register_allocator *allocator) { -@@ -4373,13 +4761,7 @@ static void allocate_temp_registers_recurse(struct hlsl_ctx *ctx, +@@ -4373,13 +4763,7 @@ static void allocate_temp_registers_recurse(struct hlsl_ctx *ctx, if (ctx->profile->major_version >= 4 && instr->type == HLSL_IR_CONSTANT) continue; @@ -8718,7 +9389,7 @@ index bdb72a1fab9..049461cdb7d 100644 switch (instr->type) { -@@ -4474,9 +4856,9 @@ static void allocate_const_registers_recurse(struct hlsl_ctx *ctx, +@@ -4474,9 +4858,9 @@ static void allocate_const_registers_recurse(struct hlsl_ctx *ctx, 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)); @@ -8731,7 +9402,7 @@ index bdb72a1fab9..049461cdb7d 100644 for (x = 0, i = 0; x < 4; ++x) { -@@ -4587,8 +4969,46 @@ static void sort_uniforms_by_numeric_bind_count(struct hlsl_ctx *ctx) +@@ -4587,8 +4971,46 @@ static void sort_uniforms_by_numeric_bind_count(struct hlsl_ctx *ctx) list_move_tail(&ctx->extern_vars, &sorted); } @@ -8778,7 +9449,7 @@ index bdb72a1fab9..049461cdb7d 100644 struct register_allocator allocator = {0}; struct hlsl_ir_var *var; -@@ -4597,6 +5017,7 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_ir_functi +@@ -4597,6 +5019,7 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_ir_functi LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) { unsigned int reg_size = var->data_type->reg_size[HLSL_REGSET_NUMERIC]; @@ -8786,7 +9457,7 @@ index bdb72a1fab9..049461cdb7d 100644 if (!var->is_uniform || reg_size == 0) continue; -@@ -4606,15 +5027,18 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_ir_functi +@@ -4606,15 +5029,18 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_ir_functi unsigned int reg_idx = var->reg_reservation.reg_index; unsigned int i; @@ -8810,7 +9481,7 @@ index bdb72a1fab9..049461cdb7d 100644 record_allocation(ctx, &allocator, reg_idx + i, VKD3DSP_WRITEMASK_ALL, 1, UINT_MAX); } -@@ -4627,6 +5051,8 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_ir_functi +@@ -4627,6 +5053,8 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_ir_functi } } @@ -8819,7 +9490,7 @@ index bdb72a1fab9..049461cdb7d 100644 LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) { unsigned int alloc_size = 4 * var->bind_count[HLSL_REGSET_NUMERIC]; -@@ -4644,6 +5070,8 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_ir_functi +@@ -4644,6 +5072,8 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_ir_functi allocate_const_registers_recurse(ctx, &entry_func->body, &allocator); @@ -8828,7 +9499,7 @@ index bdb72a1fab9..049461cdb7d 100644 vkd3d_free(allocator.allocations); } -@@ -4693,11 +5121,11 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var +@@ -4693,11 +5123,11 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var uint32_t reg; bool builtin; @@ -8842,7 +9513,7 @@ index bdb72a1fab9..049461cdb7d 100644 D3DDECLUSAGE usage; uint32_t usage_idx; -@@ -4705,8 +5133,12 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var +@@ -4705,8 +5135,12 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var if (ctx->profile->major_version == 1 && output && ctx->profile->type == VKD3D_SHADER_TYPE_PIXEL) return; @@ -8857,7 +9528,7 @@ index bdb72a1fab9..049461cdb7d 100644 { hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SEMANTIC, "Invalid semantic '%s'.", var->semantic.name); -@@ -4715,7 +5147,6 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var +@@ -4715,7 +5149,6 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var if ((!output && !var->last_read) || (output && !var->first_write)) return; @@ -8865,7 +9536,7 @@ index bdb72a1fab9..049461cdb7d 100644 } else { -@@ -4762,13 +5193,14 @@ static void allocate_semantic_registers(struct hlsl_ctx *ctx) +@@ -4762,13 +5195,14 @@ static void allocate_semantic_registers(struct hlsl_ctx *ctx) } } @@ -8882,7 +9553,7 @@ index bdb72a1fab9..049461cdb7d 100644 return buffer; } return NULL; -@@ -4783,6 +5215,7 @@ static void hlsl_calculate_buffer_offset(struct hlsl_ctx *ctx, struct hlsl_ir_va +@@ -4783,6 +5217,7 @@ static void hlsl_calculate_buffer_offset(struct hlsl_ctx *ctx, struct hlsl_ir_va if (register_reservation) { var->buffer_offset = 4 * var->reg_reservation.reg_index; @@ -8890,7 +9561,7 @@ index bdb72a1fab9..049461cdb7d 100644 } else { -@@ -4815,6 +5248,7 @@ static void hlsl_calculate_buffer_offset(struct hlsl_ctx *ctx, struct hlsl_ir_va +@@ -4815,6 +5250,7 @@ static void hlsl_calculate_buffer_offset(struct hlsl_ctx *ctx, struct hlsl_ir_va } } var->buffer_offset = var->reg_reservation.offset_index; @@ -8898,7 +9569,7 @@ index bdb72a1fab9..049461cdb7d 100644 } else { -@@ -4913,11 +5347,19 @@ void hlsl_calculate_buffer_offsets(struct hlsl_ctx *ctx) +@@ -4913,11 +5349,19 @@ void hlsl_calculate_buffer_offsets(struct hlsl_ctx *ctx) } } @@ -8919,7 +9590,7 @@ index bdb72a1fab9..049461cdb7d 100644 LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) { -@@ -4938,32 +5380,59 @@ static void allocate_buffers(struct hlsl_ctx *ctx) +@@ -4938,32 +5382,59 @@ static void allocate_buffers(struct hlsl_ctx *ctx) if (buffer->type == HLSL_BUFFER_CONSTANT) { @@ -8989,7 +9660,7 @@ index bdb72a1fab9..049461cdb7d 100644 ++index; } else -@@ -4980,7 +5449,7 @@ static void allocate_buffers(struct hlsl_ctx *ctx) +@@ -4980,7 +5451,7 @@ static void allocate_buffers(struct hlsl_ctx *ctx) } static const struct hlsl_ir_var *get_allocated_object(struct hlsl_ctx *ctx, enum hlsl_regset regset, @@ -8998,7 +9669,7 @@ index bdb72a1fab9..049461cdb7d 100644 { const struct hlsl_ir_var *var; unsigned int start, count; -@@ -4995,12 +5464,18 @@ static const struct hlsl_ir_var *get_allocated_object(struct hlsl_ctx *ctx, enum +@@ -4995,12 +5466,18 @@ static const struct hlsl_ir_var *get_allocated_object(struct hlsl_ctx *ctx, enum start = var->reg_reservation.reg_index; count = var->data_type->reg_size[regset]; @@ -9018,7 +9689,7 @@ index bdb72a1fab9..049461cdb7d 100644 count = var->regs[regset].allocation_size; } else -@@ -5017,8 +5492,8 @@ static const struct hlsl_ir_var *get_allocated_object(struct hlsl_ctx *ctx, enum +@@ -5017,8 +5494,8 @@ static const struct hlsl_ir_var *get_allocated_object(struct hlsl_ctx *ctx, enum static void allocate_objects(struct hlsl_ctx *ctx, enum hlsl_regset regset) { char regset_name = get_regset_name(regset); @@ -9028,7 +9699,7 @@ index bdb72a1fab9..049461cdb7d 100644 if (regset == HLSL_REGSET_UAVS) { -@@ -5041,35 +5516,44 @@ static void allocate_objects(struct hlsl_ctx *ctx, enum hlsl_regset regset) +@@ -5041,35 +5518,44 @@ static void allocate_objects(struct hlsl_ctx *ctx, enum hlsl_regset regset) if (var->regs[regset].allocated) { const struct hlsl_ir_var *reserved_object, *last_reported = NULL; @@ -9082,7 +9753,7 @@ index bdb72a1fab9..049461cdb7d 100644 } else { -@@ -5078,7 +5562,7 @@ static void allocate_objects(struct hlsl_ctx *ctx, enum hlsl_regset regset) +@@ -5078,7 +5564,7 @@ static void allocate_objects(struct hlsl_ctx *ctx, enum hlsl_regset regset) while (available < count) { @@ -9091,7 +9762,7 @@ index bdb72a1fab9..049461cdb7d 100644 available = 0; else ++available; -@@ -5086,10 +5570,15 @@ static void allocate_objects(struct hlsl_ctx *ctx, enum hlsl_regset regset) +@@ -5086,10 +5572,15 @@ static void allocate_objects(struct hlsl_ctx *ctx, enum hlsl_regset regset) } index -= count; @@ -9110,7 +9781,7 @@ index bdb72a1fab9..049461cdb7d 100644 ++index; } } -@@ -5109,12 +5598,12 @@ bool hlsl_component_index_range_from_deref(struct hlsl_ctx *ctx, const struct hl +@@ -5109,12 +5600,12 @@ bool hlsl_component_index_range_from_deref(struct hlsl_ctx *ctx, const struct hl struct hlsl_ir_node *path_node = deref->path[i].node; unsigned int idx = 0; @@ -9125,7 +9796,7 @@ index bdb72a1fab9..049461cdb7d 100644 && path_node->data_type->e.numeric.type == HLSL_TYPE_UINT); idx = hlsl_ir_constant(path_node)->value.u[0].u; -@@ -5123,21 +5612,13 @@ bool hlsl_component_index_range_from_deref(struct hlsl_ctx *ctx, const struct hl +@@ -5123,21 +5614,13 @@ bool hlsl_component_index_range_from_deref(struct hlsl_ctx *ctx, const struct hl { case HLSL_CLASS_VECTOR: if (idx >= type->dimx) @@ -9147,7 +9818,7 @@ index bdb72a1fab9..049461cdb7d 100644 if (hlsl_type_is_row_major(type)) *start += idx * type->dimx; else -@@ -5146,11 +5627,7 @@ bool hlsl_component_index_range_from_deref(struct hlsl_ctx *ctx, const struct hl +@@ -5146,11 +5629,7 @@ bool hlsl_component_index_range_from_deref(struct hlsl_ctx *ctx, const struct hl case HLSL_CLASS_ARRAY: if (idx >= type->e.array.elements_count) @@ -9159,7 +9830,7 @@ index bdb72a1fab9..049461cdb7d 100644 *start += idx * hlsl_type_component_count(type->e.array.type); break; -@@ -5186,11 +5663,11 @@ bool hlsl_regset_index_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref +@@ -5186,11 +5665,11 @@ bool hlsl_regset_index_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref struct hlsl_ir_node *path_node = deref->path[i].node; unsigned int idx = 0; @@ -9173,7 +9844,7 @@ index bdb72a1fab9..049461cdb7d 100644 && path_node->data_type->e.numeric.type == HLSL_TYPE_UINT); idx = hlsl_ir_constant(path_node)->value.u[0].u; -@@ -5240,8 +5717,8 @@ bool hlsl_regset_index_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref +@@ -5240,8 +5719,8 @@ bool hlsl_regset_index_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref type = hlsl_get_element_type_from_path_index(ctx, type, path_node); } @@ -9184,7 +9855,7 @@ index bdb72a1fab9..049461cdb7d 100644 return index_is_constant; } -@@ -5256,16 +5733,17 @@ bool hlsl_offset_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref +@@ -5256,16 +5735,17 @@ bool hlsl_offset_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref if (offset_node) { /* We should always have generated a cast to UINT. */ @@ -9205,7 +9876,7 @@ index bdb72a1fab9..049461cdb7d 100644 "Dereference is out of bounds. %u/%u", *offset, size); return false; } -@@ -5280,8 +5758,9 @@ unsigned int hlsl_offset_from_deref_safe(struct hlsl_ctx *ctx, const struct hlsl +@@ -5280,8 +5760,9 @@ unsigned int hlsl_offset_from_deref_safe(struct hlsl_ctx *ctx, const struct hlsl if (hlsl_offset_from_deref(ctx, deref, &offset)) return offset; @@ -9217,7 +9888,7 @@ index bdb72a1fab9..049461cdb7d 100644 return 0; } -@@ -5292,9 +5771,10 @@ struct hlsl_reg hlsl_reg_from_deref(struct hlsl_ctx *ctx, const struct hlsl_dere +@@ -5292,9 +5773,10 @@ struct hlsl_reg hlsl_reg_from_deref(struct hlsl_ctx *ctx, const struct hlsl_dere struct hlsl_reg ret = var->regs[HLSL_REGSET_NUMERIC]; unsigned int offset = hlsl_offset_from_deref_safe(ctx, deref); @@ -9230,7 +9901,7 @@ index bdb72a1fab9..049461cdb7d 100644 ret.id += offset / 4; ret.writemask = 0xf & (0xf << (offset % 4)); -@@ -5446,6 +5926,414 @@ void hlsl_run_const_passes(struct hlsl_ctx *ctx, struct hlsl_block *body) +@@ -5446,6 +5928,414 @@ void hlsl_run_const_passes(struct hlsl_ctx *ctx, struct hlsl_block *body) } while (progress); } @@ -9645,7 +10316,7 @@ index bdb72a1fab9..049461cdb7d 100644 int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, enum vkd3d_shader_target_type target_type, struct vkd3d_shader_code *out) { -@@ -5466,6 +6354,9 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry +@@ -5466,6 +6356,9 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry if (ctx->result) return ctx->result; @@ -9655,7 +10326,7 @@ index bdb72a1fab9..049461cdb7d 100644 lower_return(ctx, entry_func, body, false); while (hlsl_transform_ir(ctx, lower_calls, body, NULL)); -@@ -5532,6 +6423,7 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry +@@ -5532,6 +6425,7 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry hlsl_transform_ir(ctx, lower_discard_neg, body, NULL); } @@ -9663,7 +10334,7 @@ index bdb72a1fab9..049461cdb7d 100644 hlsl_run_const_passes(ctx, body); remove_unreachable_code(ctx, body); -@@ -5541,7 +6433,7 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry +@@ -5541,7 +6435,7 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry lower_ir(ctx, lower_casts_to_bool, body); lower_ir(ctx, lower_int_dot, body); @@ -9672,7 +10343,7 @@ index bdb72a1fab9..049461cdb7d 100644 hlsl_transform_ir(ctx, track_object_components_sampler_dim, body, NULL); if (profile->major_version >= 4) hlsl_transform_ir(ctx, lower_combined_samples, body, NULL); -@@ -5555,6 +6447,8 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry +@@ -5555,6 +6449,8 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry if (profile->major_version < 4) { @@ -9681,7 +10352,7 @@ index bdb72a1fab9..049461cdb7d 100644 lower_ir(ctx, lower_ternary, body); lower_ir(ctx, lower_nonfloat_exprs, body); -@@ -5569,6 +6463,7 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry +@@ -5569,6 +6465,7 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry lower_ir(ctx, lower_round, body); lower_ir(ctx, lower_ceil, body); lower_ir(ctx, lower_floor, body); @@ -9689,7 +10360,7 @@ index bdb72a1fab9..049461cdb7d 100644 lower_ir(ctx, lower_comparison_operators, body); lower_ir(ctx, lower_logic_not, body); if (ctx->profile->type == VKD3D_SHADER_TYPE_PIXEL) -@@ -5628,7 +6523,25 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry +@@ -5628,7 +6525,25 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry switch (target_type) { case VKD3D_SHADER_TARGET_D3D_BYTECODE: @@ -10055,7 +10726,7 @@ index 16015fa8a81..db4913b7c62 100644 } arg1 = hlsl_ir_constant(expr->operands[0].node); diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c -index b3b745fc1b2..c1b8582af6d 100644 +index b3b745fc1b2..6dbe30b1553 100644 --- a/libs/vkd3d/libs/vkd3d-shader/ir.c +++ b/libs/vkd3d/libs/vkd3d-shader/ir.c @@ -19,9 +19,73 @@ @@ -10831,7 +11502,44 @@ index b3b745fc1b2..c1b8582af6d 100644 if (current == reference) return; -@@ -3796,7 +4012,7 @@ static enum vkd3d_result vsir_cfg_sort_nodes(struct vsir_cfg *cfg) +@@ -3615,11 +3831,16 @@ static void vsir_cfg_compute_dominators(struct vsir_cfg *cfg) + { + struct vsir_block *block2 = &cfg->blocks[j]; + +- if (block2->label == 0) ++ if (block2->label == 0 || !vsir_block_dominates(block, block2)) + continue; + +- if (vsir_block_dominates(block, block2)) +- vkd3d_string_buffer_printf(&cfg->debug_buffer, " %u", block2->label); ++ if (cfg->debug_buffer.content_size > 512) ++ { ++ TRACE("%s...\n", cfg->debug_buffer.buffer); ++ vkd3d_string_buffer_clear(&cfg->debug_buffer); ++ vkd3d_string_buffer_printf(&cfg->debug_buffer, "Block %u dominates: ...", block->label); ++ } ++ vkd3d_string_buffer_printf(&cfg->debug_buffer, " %u", block2->label); + } + TRACE("%s\n", cfg->debug_buffer.buffer); + vkd3d_string_buffer_clear(&cfg->debug_buffer); +@@ -3711,7 +3932,16 @@ static enum vkd3d_result vsir_cfg_compute_loops(struct vsir_cfg *cfg) + vkd3d_string_buffer_printf(&cfg->debug_buffer, "Back edge %u -> %u with loop:", block->label, header->label); + + for (k = 0; k < loop->count; ++k) ++ { ++ if (cfg->debug_buffer.content_size > 512) ++ { ++ TRACE("%s...\n", cfg->debug_buffer.buffer); ++ vkd3d_string_buffer_clear(&cfg->debug_buffer); ++ vkd3d_string_buffer_printf(&cfg->debug_buffer, "Back edge %u -> %u with loop: ...", ++ block->label, header->label); ++ } + vkd3d_string_buffer_printf(&cfg->debug_buffer, " %u", loop->blocks[k]->label); ++ } + + TRACE("%s\n", cfg->debug_buffer.buffer); + vkd3d_string_buffer_clear(&cfg->debug_buffer); +@@ -3796,7 +4026,7 @@ static enum vkd3d_result vsir_cfg_sort_nodes(struct vsir_cfg *cfg) /* Do not count back edges. */ if (cfg->loops_by_header[i] != SIZE_MAX) { @@ -10840,7 +11548,7 @@ index b3b745fc1b2..c1b8582af6d 100644 in_degrees[i] -= 1; } -@@ -3882,7 +4098,7 @@ static enum vkd3d_result vsir_cfg_sort_nodes(struct vsir_cfg *cfg) +@@ -3882,7 +4112,7 @@ static enum vkd3d_result vsir_cfg_sort_nodes(struct vsir_cfg *cfg) inner_stack_item->seen_count += new_seen_count; @@ -10849,7 +11557,7 @@ index b3b745fc1b2..c1b8582af6d 100644 if (inner_stack_item->seen_count != inner_stack_item->loop->count) break; -@@ -3902,7 +4118,7 @@ static enum vkd3d_result vsir_cfg_sort_nodes(struct vsir_cfg *cfg) +@@ -3902,7 +4132,7 @@ static enum vkd3d_result vsir_cfg_sort_nodes(struct vsir_cfg *cfg) if (vsir_block_dominates(successor, block)) continue; @@ -10858,7 +11566,7 @@ index b3b745fc1b2..c1b8582af6d 100644 --in_degrees[successor->label - 1]; if (in_degrees[successor->label - 1] == 0) -@@ -3923,7 +4139,7 @@ static enum vkd3d_result vsir_cfg_sort_nodes(struct vsir_cfg *cfg) +@@ -3923,7 +4153,7 @@ static enum vkd3d_result vsir_cfg_sort_nodes(struct vsir_cfg *cfg) goto fail; } @@ -10867,7 +11575,29 @@ index b3b745fc1b2..c1b8582af6d 100644 vkd3d_free(in_degrees); vkd3d_free(sorter.stack); -@@ -3993,7 +4209,7 @@ static enum vkd3d_result vsir_cfg_generate_synthetic_loop_intervals(struct vsir_ +@@ -3934,7 +4164,15 @@ static enum vkd3d_result vsir_cfg_sort_nodes(struct vsir_cfg *cfg) + vkd3d_string_buffer_printf(&cfg->debug_buffer, "Block order:"); + + for (i = 0; i < cfg->order.count; ++i) ++ { ++ if (cfg->debug_buffer.content_size > 512) ++ { ++ TRACE("%s...\n", cfg->debug_buffer.buffer); ++ vkd3d_string_buffer_clear(&cfg->debug_buffer); ++ vkd3d_string_buffer_printf(&cfg->debug_buffer, "Block order: ..."); ++ } + vkd3d_string_buffer_printf(&cfg->debug_buffer, " %u", cfg->order.blocks[i]->label); ++ } + + TRACE("%s\n", cfg->debug_buffer.buffer); + vkd3d_string_buffer_clear(&cfg->debug_buffer); +@@ -3988,12 +4226,12 @@ static enum vkd3d_result vsir_cfg_generate_synthetic_loop_intervals(struct vsir_ + ACTION_EXTEND, + } action = ACTION_CREATE_NEW; + +- /* We've already contructed loop intervals for the back ++ /* We've already constructed loop intervals for the back + * edges, there's nothing more to do. */ if (vsir_block_dominates(successor, block)) continue; @@ -10876,7 +11606,7 @@ index b3b745fc1b2..c1b8582af6d 100644 /* Jumping from a block to the following one is always * possible, so nothing to do. */ -@@ -4066,7 +4282,7 @@ static enum vkd3d_result vsir_cfg_generate_synthetic_loop_intervals(struct vsir_ +@@ -4066,7 +4304,7 @@ static enum vkd3d_result vsir_cfg_generate_synthetic_loop_intervals(struct vsir_ { if (interval->synthetic) interval->begin = min(begin, interval->begin); @@ -10885,7 +11615,7 @@ index b3b745fc1b2..c1b8582af6d 100644 } } -@@ -4119,7 +4335,7 @@ static void vsir_cfg_compute_edge_action(struct vsir_cfg *cfg, struct vsir_block +@@ -4119,7 +4357,7 @@ static void vsir_cfg_compute_edge_action(struct vsir_cfg *cfg, struct vsir_block break; } @@ -10894,7 +11624,7 @@ index b3b745fc1b2..c1b8582af6d 100644 action->jump_type = JUMP_CONTINUE; } else -@@ -4141,7 +4357,7 @@ static void vsir_cfg_compute_edge_action(struct vsir_cfg *cfg, struct vsir_block +@@ -4141,7 +4379,7 @@ static void vsir_cfg_compute_edge_action(struct vsir_cfg *cfg, struct vsir_block if (action->target == UINT_MAX) { @@ -10903,7 +11633,7 @@ index b3b745fc1b2..c1b8582af6d 100644 action->jump_type = JUMP_NONE; } else -@@ -4168,7 +4384,7 @@ static enum vkd3d_result vsir_cfg_build_structured_program(struct vsir_cfg *cfg) +@@ -4168,7 +4406,7 @@ static enum vkd3d_result vsir_cfg_build_structured_program(struct vsir_cfg *cfg) struct vsir_block *block = cfg->order.blocks[i]; struct vsir_cfg_structure *structure; @@ -10912,7 +11642,7 @@ index b3b745fc1b2..c1b8582af6d 100644 /* Open loop intervals. */ while (open_interval_idx < cfg->loop_interval_count) -@@ -4192,7 +4408,7 @@ static enum vkd3d_result vsir_cfg_build_structured_program(struct vsir_cfg *cfg) +@@ -4192,7 +4430,7 @@ static enum vkd3d_result vsir_cfg_build_structured_program(struct vsir_cfg *cfg) structure->u.block = block; /* Generate between zero and two jump instructions. */ @@ -10921,7 +11651,7 @@ index b3b745fc1b2..c1b8582af6d 100644 { case VKD3DSIH_BRANCH: { -@@ -4227,7 +4443,7 @@ static enum vkd3d_result vsir_cfg_build_structured_program(struct vsir_cfg *cfg) +@@ -4227,7 +4465,7 @@ static enum vkd3d_result vsir_cfg_build_structured_program(struct vsir_cfg *cfg) * selection ladders. */ if (action_true.successor == action_false.successor) { @@ -10930,7 +11660,7 @@ index b3b745fc1b2..c1b8582af6d 100644 } else { -@@ -4243,7 +4459,7 @@ static enum vkd3d_result vsir_cfg_build_structured_program(struct vsir_cfg *cfg) +@@ -4243,10 +4481,10 @@ static enum vkd3d_result vsir_cfg_build_structured_program(struct vsir_cfg *cfg) struct vsir_cfg_structure_list *inner_loop_frame = stack[stack_depth - 2]; struct vsir_cfg_structure *inner_loop = &inner_loop_frame->structures[inner_loop_frame->count - 1]; @@ -10938,8 +11668,12 @@ index b3b745fc1b2..c1b8582af6d 100644 + VKD3D_ASSERT(inner_loop->type == STRUCTURE_TYPE_LOOP); /* Otherwise, if one of the branches is - * continueing the inner loop we're inside, -@@ -4260,7 +4476,7 @@ static enum vkd3d_result vsir_cfg_build_structured_program(struct vsir_cfg *cfg) +- * continueing the inner loop we're inside, ++ * continue-ing the inner loop we're inside, + * make sure it's the false branch (because it + * will be optimized out later). */ + if (action_true.jump_type == JUMP_CONTINUE && action_true.target == inner_loop->u.loop.idx) +@@ -4260,7 +4498,7 @@ static enum vkd3d_result vsir_cfg_build_structured_program(struct vsir_cfg *cfg) action_false = tmp; } @@ -10948,7 +11682,7 @@ index b3b745fc1b2..c1b8582af6d 100644 if (!(structure = vsir_cfg_structure_list_append(stack[stack_depth - 1], STRUCTURE_TYPE_JUMP))) goto fail; -@@ -4300,8 +4516,8 @@ static enum vkd3d_result vsir_cfg_build_structured_program(struct vsir_cfg *cfg) +@@ -4300,8 +4538,8 @@ static enum vkd3d_result vsir_cfg_build_structured_program(struct vsir_cfg *cfg) } } @@ -10959,7 +11693,7 @@ index b3b745fc1b2..c1b8582af6d 100644 if (TRACE_ON()) vsir_cfg_dump_structured_program(cfg); -@@ -4325,7 +4541,7 @@ static void vsir_cfg_remove_trailing_continue(struct vsir_cfg *cfg, +@@ -4325,7 +4563,7 @@ static void vsir_cfg_remove_trailing_continue(struct vsir_cfg *cfg, && !last->u.jump.condition && last->u.jump.target == target) { --list->count; @@ -10968,7 +11702,7 @@ index b3b745fc1b2..c1b8582af6d 100644 --cfg->loop_intervals[target].target_count; } } -@@ -4366,7 +4582,7 @@ static enum vkd3d_result vsir_cfg_move_breaks_out_of_selections(struct vsir_cfg +@@ -4366,7 +4604,7 @@ static enum vkd3d_result vsir_cfg_move_breaks_out_of_selections(struct vsir_cfg size_t pos = list->count - 1; selection = &list->structures[pos]; @@ -10977,7 +11711,7 @@ index b3b745fc1b2..c1b8582af6d 100644 if_break = vsir_cfg_get_trailing_break(&selection->u.selection.if_body); else_break = vsir_cfg_get_trailing_break(&selection->u.selection.else_body); -@@ -4387,19 +4603,19 @@ static enum vkd3d_result vsir_cfg_move_breaks_out_of_selections(struct vsir_cfg +@@ -4387,19 +4625,19 @@ static enum vkd3d_result vsir_cfg_move_breaks_out_of_selections(struct vsir_cfg /* Pointer `selection' could have been invalidated by the append * operation. */ selection = &list->structures[pos]; @@ -11000,7 +11734,7 @@ index b3b745fc1b2..c1b8582af6d 100644 --cfg->loop_intervals[else_target].target_count; } -@@ -4507,7 +4723,7 @@ static enum vkd3d_result vsir_cfg_append_loop(struct vsir_cfg *cfg, +@@ -4507,7 +4745,7 @@ static enum vkd3d_result vsir_cfg_append_loop(struct vsir_cfg *cfg, } target = trailing_break->u.jump.target; @@ -11009,7 +11743,7 @@ index b3b745fc1b2..c1b8582af6d 100644 /* If the loop is not targeted by any jump, we can remove it. The * trailing `break' then targets another loop, so we have to keep -@@ -4674,7 +4890,7 @@ static void vsir_cfg_mark_trampolines(struct vsir_cfg *cfg, struct vsir_cfg_stru +@@ -4674,7 +4912,7 @@ static void vsir_cfg_mark_trampolines(struct vsir_cfg *cfg, struct vsir_cfg_stru break; for (l = loop; l && l->u.loop.idx != structure->u.jump.target; l = l->u.loop.outer_loop) { @@ -11018,7 +11752,7 @@ index b3b745fc1b2..c1b8582af6d 100644 l->u.loop.needs_trampoline = true; } break; -@@ -4714,7 +4930,7 @@ static void vsir_cfg_mark_launchers(struct vsir_cfg *cfg, struct vsir_cfg_struct +@@ -4714,7 +4952,7 @@ static void vsir_cfg_mark_launchers(struct vsir_cfg *cfg, struct vsir_cfg_struct case STRUCTURE_TYPE_JUMP: if (structure->u.jump.type != JUMP_BREAK && structure->u.jump.type != JUMP_CONTINUE) break; @@ -11027,7 +11761,24 @@ index b3b745fc1b2..c1b8582af6d 100644 if (loop->u.loop.needs_trampoline) structure->u.jump.needs_launcher = true; break; -@@ -4912,7 +5128,7 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_jump(struct vsir_cfg *cfg, +@@ -4888,14 +5126,14 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_jump(struct vsir_cfg *cfg, + struct vsir_cfg_emit_target *target = cfg->target; + const struct vkd3d_shader_location no_loc = {0}; + /* Encode the jump target as the loop index plus a bit to remember whether +- * we're breaking or continueing. */ ++ * we're breaking or continue-ing. */ + unsigned int jump_target = jump->target << 1; + enum vkd3d_shader_opcode opcode; + + switch (jump->type) + { + case JUMP_CONTINUE: +- /* If we're continueing the loop we're directly inside, then we can emit a ++ /* If we're continue-ing the loop we're directly inside, then we can emit a + * `continue'. Otherwise we first have to break all the loops between here + * and the loop to continue, recording our intention to continue + * in the lowest bit of jump_target. */ +@@ -4912,7 +5150,7 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_jump(struct vsir_cfg *cfg, break; case JUMP_RET: @@ -11036,7 +11787,7 @@ index b3b745fc1b2..c1b8582af6d 100644 opcode = VKD3DSIH_RET; break; -@@ -5049,22 +5265,22 @@ static enum vkd3d_result vsir_program_structurize(struct vsir_program *program, +@@ -5049,22 +5287,22 @@ static enum vkd3d_result vsir_program_structurize(struct vsir_program *program, { struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; @@ -11064,7 +11815,7 @@ index b3b745fc1b2..c1b8582af6d 100644 target.instructions[target.ins_count++] = *ins; ++i; if ((ret = vsir_program_structurize_function(program, message_context, -@@ -5222,22 +5438,22 @@ static enum vkd3d_result vsir_program_materialize_undominated_ssas_to_temps(stru +@@ -5222,22 +5460,22 @@ static enum vkd3d_result vsir_program_materialize_undominated_ssas_to_temps(stru { struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; @@ -11092,7 +11843,7 @@ index b3b745fc1b2..c1b8582af6d 100644 ++i; if ((ret = vsir_program_materialize_undominated_ssas_to_temps_in_function( program, message_context, &i)) < 0) -@@ -5253,6 +5469,192 @@ static enum vkd3d_result vsir_program_materialize_undominated_ssas_to_temps(stru +@@ -5253,6 +5491,192 @@ static enum vkd3d_result vsir_program_materialize_undominated_ssas_to_temps(stru return VKD3D_OK; } @@ -11285,7 +12036,7 @@ index b3b745fc1b2..c1b8582af6d 100644 struct validation_context { struct vkd3d_shader_message_context *message_context; -@@ -5641,7 +6043,7 @@ static void vsir_validate_dst_count(struct validation_context *ctx, +@@ -5641,7 +6065,7 @@ static void vsir_validate_dst_count(struct validation_context *ctx, if (instruction->dst_count != count) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DEST_COUNT, "Invalid destination count %u for an instruction of type %#x, expected %u.", @@ -11294,7 +12045,7 @@ index b3b745fc1b2..c1b8582af6d 100644 } static void vsir_validate_src_count(struct validation_context *ctx, -@@ -5650,7 +6052,7 @@ static void vsir_validate_src_count(struct validation_context *ctx, +@@ -5650,7 +6074,7 @@ static void vsir_validate_src_count(struct validation_context *ctx, if (instruction->src_count != count) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SOURCE_COUNT, "Invalid source count %u for an instruction of type %#x, expected %u.", @@ -11303,7 +12054,7 @@ index b3b745fc1b2..c1b8582af6d 100644 } static bool vsir_validate_src_min_count(struct validation_context *ctx, -@@ -5660,7 +6062,7 @@ static bool vsir_validate_src_min_count(struct validation_context *ctx, +@@ -5660,7 +6084,7 @@ static bool vsir_validate_src_min_count(struct validation_context *ctx, { validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SOURCE_COUNT, "Invalid source count %u for an instruction of type %#x, expected at least %u.", @@ -11312,7 +12063,7 @@ index b3b745fc1b2..c1b8582af6d 100644 return false; } -@@ -5674,7 +6076,7 @@ static bool vsir_validate_src_max_count(struct validation_context *ctx, +@@ -5674,7 +6098,7 @@ static bool vsir_validate_src_max_count(struct validation_context *ctx, { validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SOURCE_COUNT, "Invalid source count %u for an instruction of type %#x, expected at most %u.", @@ -11321,7 +12072,7 @@ index b3b745fc1b2..c1b8582af6d 100644 return false; } -@@ -5697,11 +6099,11 @@ static const char *name_from_cf_type(enum cf_type type) +@@ -5697,11 +6121,11 @@ static const char *name_from_cf_type(enum cf_type type) static void vsir_validate_cf_type(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction, enum cf_type expected_type) { @@ -11336,7 +12087,7 @@ index b3b745fc1b2..c1b8582af6d 100644 } static void vsir_validate_instruction(struct validation_context *ctx) -@@ -5718,13 +6120,13 @@ static void vsir_validate_instruction(struct validation_context *ctx) +@@ -5718,13 +6142,13 @@ static void vsir_validate_instruction(struct validation_context *ctx) for (i = 0; i < instruction->src_count; ++i) vsir_validate_src_param(ctx, &instruction->src[i]); @@ -11353,7 +12104,7 @@ index b3b745fc1b2..c1b8582af6d 100644 { case VKD3DSIH_HS_DECLS: case VKD3DSIH_HS_CONTROL_POINT_PHASE: -@@ -5733,12 +6135,14 @@ static void vsir_validate_instruction(struct validation_context *ctx) +@@ -5733,12 +6157,14 @@ static void vsir_validate_instruction(struct validation_context *ctx) vsir_validate_dst_count(ctx, instruction, 0); vsir_validate_src_count(ctx, instruction, 0); if (version->type != VKD3D_SHADER_TYPE_HULL) @@ -11373,7 +12124,7 @@ index b3b745fc1b2..c1b8582af6d 100644 ctx->dcl_temps_found = false; return; -@@ -5812,7 +6216,7 @@ static void vsir_validate_instruction(struct validation_context *ctx) +@@ -5812,7 +6238,7 @@ static void vsir_validate_instruction(struct validation_context *ctx) && ctx->phase == VKD3DSIH_INVALID) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_HANDLER, "Instruction %#x appear before any phase instruction in a hull shader.", @@ -11382,7 +12133,7 @@ index b3b745fc1b2..c1b8582af6d 100644 /* We support two different control flow types in shaders: * block-based, like DXIL and SPIR-V, and structured, like D3DBC -@@ -5824,7 +6228,7 @@ static void vsir_validate_instruction(struct validation_context *ctx) +@@ -5824,7 +6250,7 @@ static void vsir_validate_instruction(struct validation_context *ctx) * block, but need for that hasn't arisen yet, so we don't. */ if (ctx->cf_type == CF_TYPE_UNKNOWN && !vsir_instruction_is_dcl(instruction)) { @@ -11391,7 +12142,7 @@ index b3b745fc1b2..c1b8582af6d 100644 ctx->cf_type = CF_TYPE_BLOCKS; else ctx->cf_type = CF_TYPE_STRUCTURED; -@@ -5832,7 +6236,7 @@ static void vsir_validate_instruction(struct validation_context *ctx) +@@ -5832,7 +6258,7 @@ static void vsir_validate_instruction(struct validation_context *ctx) if (ctx->cf_type == CF_TYPE_BLOCKS && !vsir_instruction_is_dcl(instruction)) { @@ -11400,7 +12151,7 @@ index b3b745fc1b2..c1b8582af6d 100644 { case VKD3DSIH_LABEL: if (ctx->inside_block) -@@ -5844,20 +6248,22 @@ static void vsir_validate_instruction(struct validation_context *ctx) +@@ -5844,20 +6270,22 @@ static void vsir_validate_instruction(struct validation_context *ctx) case VKD3DSIH_BRANCH: case VKD3DSIH_SWITCH_MONOLITHIC: if (!ctx->inside_block) @@ -11428,7 +12179,7 @@ index b3b745fc1b2..c1b8582af6d 100644 { case VKD3DSIH_DCL_TEMPS: vsir_validate_dst_count(ctx, instruction, 0); -@@ -5877,7 +6283,7 @@ static void vsir_validate_instruction(struct validation_context *ctx) +@@ -5877,7 +6305,7 @@ static void vsir_validate_instruction(struct validation_context *ctx) vsir_validate_src_count(ctx, instruction, 1); if (!vkd3d_array_reserve((void **)&ctx->blocks, &ctx->blocks_capacity, ctx->depth + 1, sizeof(*ctx->blocks))) return; @@ -11437,7 +12188,7 @@ index b3b745fc1b2..c1b8582af6d 100644 break; case VKD3DSIH_IFC: -@@ -5896,7 +6302,7 @@ static void vsir_validate_instruction(struct validation_context *ctx) +@@ -5896,7 +6324,7 @@ static void vsir_validate_instruction(struct validation_context *ctx) if (ctx->depth == 0 || ctx->blocks[ctx->depth - 1] != VKD3DSIH_IF) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW, "ELSE instruction doesn't terminate IF block."); else @@ -11446,7 +12197,7 @@ index b3b745fc1b2..c1b8582af6d 100644 break; case VKD3DSIH_ENDIF: -@@ -5915,7 +6321,7 @@ static void vsir_validate_instruction(struct validation_context *ctx) +@@ -5915,7 +6343,7 @@ static void vsir_validate_instruction(struct validation_context *ctx) vsir_validate_src_count(ctx, instruction, version->major <= 3 ? 2 : 0); if (!vkd3d_array_reserve((void **)&ctx->blocks, &ctx->blocks_capacity, ctx->depth + 1, sizeof(*ctx->blocks))) return; @@ -11455,7 +12206,7 @@ index b3b745fc1b2..c1b8582af6d 100644 break; case VKD3DSIH_ENDLOOP: -@@ -5934,7 +6340,7 @@ static void vsir_validate_instruction(struct validation_context *ctx) +@@ -5934,7 +6362,7 @@ static void vsir_validate_instruction(struct validation_context *ctx) vsir_validate_src_count(ctx, instruction, 1); if (!vkd3d_array_reserve((void **)&ctx->blocks, &ctx->blocks_capacity, ctx->depth + 1, sizeof(*ctx->blocks))) return; @@ -11464,7 +12215,7 @@ index b3b745fc1b2..c1b8582af6d 100644 break; case VKD3DSIH_ENDREP: -@@ -5953,7 +6359,7 @@ static void vsir_validate_instruction(struct validation_context *ctx) +@@ -5953,7 +6381,7 @@ static void vsir_validate_instruction(struct validation_context *ctx) vsir_validate_src_count(ctx, instruction, 1); if (!vkd3d_array_reserve((void **)&ctx->blocks, &ctx->blocks_capacity, ctx->depth + 1, sizeof(*ctx->blocks))) return; @@ -11473,7 +12224,7 @@ index b3b745fc1b2..c1b8582af6d 100644 break; case VKD3DSIH_ENDSWITCH: -@@ -6225,7 +6631,7 @@ enum vkd3d_result vsir_program_normalise(struct vsir_program *program, uint64_t +@@ -6225,7 +6653,7 @@ enum vkd3d_result vsir_program_normalise(struct vsir_program *program, uint64_t return result; } @@ -11482,7 +12233,7 @@ index b3b745fc1b2..c1b8582af6d 100644 return result; if ((result = instruction_array_normalise_flat_constants(program)) < 0) -@@ -6241,6 +6647,9 @@ enum vkd3d_result vsir_program_normalise(struct vsir_program *program, uint64_t +@@ -6241,6 +6669,9 @@ enum vkd3d_result vsir_program_normalise(struct vsir_program *program, uint64_t return result; } @@ -11549,7 +12300,7 @@ index 009c35ffb97..366e351e3b5 100644 } diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c -index 984a4f894f6..bc8a7a5b28c 100644 +index 984a4f894f6..ed37ac5c45e 100644 --- a/libs/vkd3d/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c @@ -313,7 +313,7 @@ static bool vkd3d_spirv_stream_append(struct vkd3d_spirv_stream *dst_stream, @@ -11698,7 +12449,16 @@ index 984a4f894f6..bc8a7a5b28c 100644 scalar_id = vkd3d_spirv_get_type_id(builder, component_type, 1); return vkd3d_spirv_get_op_type_vector(builder, scalar_id, component_count); } -@@ -2250,7 +2266,7 @@ static void vkd3d_symbol_make_register(struct vkd3d_symbol *symbol, +@@ -2140,6 +2156,8 @@ struct vkd3d_symbol_descriptor_array + unsigned int set; + unsigned int binding; + unsigned int push_constant_index; ++ bool write_only; ++ bool coherent; + }; + + struct vkd3d_symbol_register_data +@@ -2250,7 +2268,7 @@ static void vkd3d_symbol_make_register(struct vkd3d_symbol *symbol, case VKD3DSPR_OUTPUT: case VKD3DSPR_PATCHCONST: symbol->key.reg.idx = reg->idx_count ? reg->idx[reg->idx_count - 1].offset : ~0u; @@ -11707,7 +12467,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 break; case VKD3DSPR_IMMCONSTBUFFER: -@@ -2377,6 +2393,7 @@ struct ssa_register_info +@@ -2377,6 +2395,7 @@ struct ssa_register_info struct spirv_compiler { struct vkd3d_spirv_builder spirv_builder; @@ -11715,7 +12475,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 struct vkd3d_shader_message_context *message_context; struct vkd3d_shader_location location; -@@ -2403,6 +2420,11 @@ struct spirv_compiler +@@ -2403,6 +2422,11 @@ struct spirv_compiler struct vkd3d_push_constant_buffer_binding *push_constants; const struct vkd3d_shader_spirv_target_info *spirv_target_info; @@ -11727,7 +12487,16 @@ index 984a4f894f6..bc8a7a5b28c 100644 bool prolog_emitted; struct shader_signature input_signature; struct shader_signature output_signature; -@@ -2513,13 +2535,10 @@ static struct spirv_compiler *spirv_compiler_create(const struct vsir_program *p +@@ -2490,6 +2514,8 @@ static void spirv_compiler_destroy(struct spirv_compiler *compiler) + vkd3d_free(compiler->push_constants); + vkd3d_free(compiler->descriptor_offset_ids); + ++ vkd3d_free(compiler->spirv_parameter_info); ++ + vkd3d_spirv_builder_free(&compiler->spirv_builder); + + rb_destroy(&compiler->symbol_table, vkd3d_symbol_free, NULL); +@@ -2513,13 +2539,10 @@ static struct spirv_compiler *spirv_compiler_create(const struct vsir_program *p const struct vkd3d_shader_scan_descriptor_info1 *scan_descriptor_info, struct vkd3d_shader_message_context *message_context, uint64_t config_flags) { @@ -11741,7 +12510,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 unsigned int i; if (!(compiler = vkd3d_malloc(sizeof(*compiler)))) -@@ -2547,13 +2566,6 @@ static struct spirv_compiler *spirv_compiler_create(const struct vsir_program *p +@@ -2547,13 +2570,6 @@ static struct spirv_compiler *spirv_compiler_create(const struct vsir_program *p compiler->spirv_target_info = target_info; } @@ -11755,7 +12524,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 vkd3d_spirv_builder_init(&compiler->spirv_builder, spirv_compiler_get_entry_point_name(compiler)); compiler->formatting = VKD3D_SHADER_COMPILE_OPTION_FORMATTING_INDENT -@@ -2893,7 +2905,7 @@ static struct vkd3d_shader_descriptor_binding spirv_compiler_get_descriptor_bind +@@ -2893,7 +2909,7 @@ static struct vkd3d_shader_descriptor_binding spirv_compiler_get_descriptor_bind if (is_uav_counter) { @@ -11764,7 +12533,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 binding_offsets = compiler->offset_info.uav_counter_offsets; for (i = 0; i < shader_interface->uav_counter_count; ++i) { -@@ -3011,7 +3023,7 @@ static uint32_t spirv_compiler_get_constant(struct spirv_compiler *compiler, +@@ -3011,7 +3027,7 @@ static uint32_t spirv_compiler_get_constant(struct spirv_compiler *compiler, struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; unsigned int i; @@ -11773,7 +12542,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count); switch (component_type) -@@ -3052,7 +3064,7 @@ static uint32_t spirv_compiler_get_constant64(struct spirv_compiler *compiler, +@@ -3052,7 +3068,7 @@ static uint32_t spirv_compiler_get_constant64(struct spirv_compiler *compiler, struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; unsigned int i; @@ -11782,7 +12551,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count); if (component_type != VKD3D_SHADER_COMPONENT_DOUBLE && component_type != VKD3D_SHADER_COMPONENT_UINT64) -@@ -3274,21 +3286,6 @@ static uint32_t spirv_compiler_emit_array_variable(struct spirv_compiler *compil +@@ -3274,21 +3290,6 @@ static uint32_t spirv_compiler_emit_array_variable(struct spirv_compiler *compil return vkd3d_spirv_build_op_variable(builder, stream, ptr_type_id, storage_class, 0); } @@ -11804,7 +12573,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 static const struct vkd3d_spec_constant_info { enum vkd3d_shader_parameter_name name; -@@ -3298,6 +3295,7 @@ static const struct vkd3d_spec_constant_info +@@ -3298,6 +3299,7 @@ static const struct vkd3d_spec_constant_info vkd3d_shader_parameters[] = { {VKD3D_SHADER_PARAMETER_NAME_RASTERIZER_SAMPLE_COUNT, 1, "sample_count"}, @@ -11812,7 +12581,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 }; static const struct vkd3d_spec_constant_info *get_spec_constant_info(enum vkd3d_shader_parameter_name name) -@@ -3318,12 +3316,11 @@ static uint32_t spirv_compiler_alloc_spec_constant_id(struct spirv_compiler *com +@@ -3318,12 +3320,11 @@ static uint32_t spirv_compiler_alloc_spec_constant_id(struct spirv_compiler *com { if (!compiler->current_spec_constant_id) { @@ -11827,7 +12596,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 if (current->type == VKD3D_SHADER_PARAMETER_TYPE_SPECIALIZATION_CONSTANT) id = max(current->u.specialization_constant.id + 1, id); -@@ -3336,7 +3333,7 @@ static uint32_t spirv_compiler_alloc_spec_constant_id(struct spirv_compiler *com +@@ -3336,7 +3337,7 @@ static uint32_t spirv_compiler_alloc_spec_constant_id(struct spirv_compiler *com } static uint32_t spirv_compiler_emit_spec_constant(struct spirv_compiler *compiler, @@ -11836,7 +12605,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; const struct vkd3d_spec_constant_info *info; -@@ -3345,7 +3342,7 @@ static uint32_t spirv_compiler_emit_spec_constant(struct spirv_compiler *compile +@@ -3345,7 +3346,7 @@ static uint32_t spirv_compiler_emit_spec_constant(struct spirv_compiler *compile info = get_spec_constant_info(name); default_value = info ? info->default_value : 0; @@ -11845,7 +12614,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 id = vkd3d_spirv_build_op_spec_constant(builder, type_id, default_value); vkd3d_spirv_build_op_decorate1(builder, id, SpvDecorationSpecId, spec_id); -@@ -3364,7 +3361,7 @@ static uint32_t spirv_compiler_emit_spec_constant(struct spirv_compiler *compile +@@ -3364,7 +3365,7 @@ static uint32_t spirv_compiler_emit_spec_constant(struct spirv_compiler *compile } static uint32_t spirv_compiler_get_spec_constant(struct spirv_compiler *compiler, @@ -11854,38 +12623,38 @@ index 984a4f894f6..bc8a7a5b28c 100644 { unsigned int i; -@@ -3374,30 +3371,66 @@ static uint32_t spirv_compiler_get_spec_constant(struct spirv_compiler *compiler +@@ -3374,30 +3375,66 @@ static uint32_t spirv_compiler_get_spec_constant(struct spirv_compiler *compiler return compiler->spec_constants[i].id; } - return spirv_compiler_emit_spec_constant(compiler, name, spec_id); + return spirv_compiler_emit_spec_constant(compiler, name, spec_id, type); - } - --static uint32_t spirv_compiler_emit_uint_shader_parameter(struct spirv_compiler *compiler, -- enum vkd3d_shader_parameter_name name) ++} ++ +static uint32_t spirv_compiler_get_buffer_parameter(struct spirv_compiler *compiler, + const struct vkd3d_shader_parameter1 *parameter, enum vkd3d_data_type type) - { -- const struct vkd3d_shader_parameter *parameter; ++{ + struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; + unsigned int index = parameter - compiler->program->parameters; + uint32_t type_id, ptr_id, ptr_type_id; - -- if (!(parameter = spirv_compiler_get_shader_parameter(compiler, name))) ++ + type_id = vkd3d_spirv_get_type_id(builder, vkd3d_component_type_from_data_type(type), 1); + ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassUniform, type_id); + ptr_id = vkd3d_spirv_build_op_access_chain1(builder, ptr_type_id, + compiler->spirv_parameter_info[index].buffer_id, + spirv_compiler_get_constant_uint(compiler, 0)); + return vkd3d_spirv_build_op_load(builder, type_id, ptr_id, SpvMemoryAccessMaskNone); -+} -+ + } + +-static uint32_t spirv_compiler_emit_uint_shader_parameter(struct spirv_compiler *compiler, +- enum vkd3d_shader_parameter_name name) +static uint32_t spirv_compiler_emit_shader_parameter(struct spirv_compiler *compiler, + enum vkd3d_shader_parameter_name name, enum vkd3d_data_type type) -+{ + { +- const struct vkd3d_shader_parameter *parameter; + const struct vkd3d_shader_parameter1 *parameter; -+ + +- if (!(parameter = spirv_compiler_get_shader_parameter(compiler, name))) + static const struct + { + enum vkd3d_data_type type; @@ -11929,7 +12698,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 } static uint32_t spirv_compiler_emit_construct_vector(struct spirv_compiler *compiler, -@@ -3409,7 +3442,7 @@ static uint32_t spirv_compiler_emit_construct_vector(struct spirv_compiler *comp +@@ -3409,7 +3446,7 @@ static uint32_t spirv_compiler_emit_construct_vector(struct spirv_compiler *comp uint32_t type_id, result_id; unsigned int i; @@ -11938,7 +12707,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count); if (val_component_count == 1) -@@ -3470,11 +3503,11 @@ static bool spirv_compiler_get_register_info(struct spirv_compiler *compiler, +@@ -3470,11 +3507,11 @@ static bool spirv_compiler_get_register_info(struct spirv_compiler *compiler, struct vkd3d_symbol reg_symbol, *symbol; struct rb_entry *entry; @@ -11952,7 +12721,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 register_info->id = compiler->temp_id + reg->idx[0].offset; register_info->storage_class = SpvStorageClassPrivate; register_info->descriptor_array = NULL; -@@ -3605,7 +3638,7 @@ static void spirv_compiler_emit_dereference_register(struct spirv_compiler *comp +@@ -3605,7 +3642,7 @@ static void spirv_compiler_emit_dereference_register(struct spirv_compiler *comp if (reg->type == VKD3DSPR_CONSTBUFFER) { @@ -11961,7 +12730,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 if (register_info->descriptor_array) indexes[index_count++] = spirv_compiler_get_descriptor_index(compiler, reg, register_info->descriptor_array, register_info->binding_base_idx, VKD3D_SHADER_RESOURCE_BUFFER); -@@ -3723,7 +3756,7 @@ static uint32_t spirv_compiler_emit_swizzle(struct spirv_compiler *compiler, +@@ -3723,7 +3760,7 @@ static uint32_t spirv_compiler_emit_swizzle(struct spirv_compiler *compiler, { if (write_mask & (VKD3DSP_WRITEMASK_0 << i)) { @@ -11970,7 +12739,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 components[component_idx++] = val_id; } } -@@ -3748,7 +3781,7 @@ static uint32_t spirv_compiler_emit_vector_shuffle(struct spirv_compiler *compil +@@ -3748,7 +3785,7 @@ static uint32_t spirv_compiler_emit_vector_shuffle(struct spirv_compiler *compil uint32_t type_id; unsigned int i; @@ -11979,7 +12748,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 for (i = 0; i < component_count; ++i) { -@@ -3771,7 +3804,7 @@ static uint32_t spirv_compiler_emit_int_to_bool(struct spirv_compiler *compiler, +@@ -3771,7 +3808,7 @@ static uint32_t spirv_compiler_emit_int_to_bool(struct spirv_compiler *compiler, uint32_t type_id; SpvOp op; @@ -11988,7 +12757,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count); op = condition & VKD3D_SHADER_CONDITIONAL_OP_Z ? SpvOpIEqual : SpvOpINotEqual; -@@ -3901,7 +3934,7 @@ static uint32_t spirv_compiler_emit_load_constant(struct spirv_compiler *compile +@@ -3901,7 +3938,7 @@ static uint32_t spirv_compiler_emit_load_constant(struct spirv_compiler *compile uint32_t values[VKD3D_VEC4_SIZE] = {0}; unsigned int i, j; @@ -11997,7 +12766,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 if (reg->dimension == VSIR_DIMENSION_SCALAR) { -@@ -3929,7 +3962,7 @@ static uint32_t spirv_compiler_emit_load_constant64(struct spirv_compiler *compi +@@ -3929,7 +3966,7 @@ static uint32_t spirv_compiler_emit_load_constant64(struct spirv_compiler *compi uint64_t values[VKD3D_DVEC2_SIZE] = {0}; unsigned int i, j; @@ -12006,7 +12775,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 if (reg->dimension == VSIR_DIMENSION_SCALAR) { -@@ -3956,7 +3989,7 @@ static uint32_t spirv_compiler_emit_load_undef(struct spirv_compiler *compiler, +@@ -3956,7 +3993,7 @@ static uint32_t spirv_compiler_emit_load_undef(struct spirv_compiler *compiler, struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; uint32_t type_id; @@ -12015,7 +12784,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 type_id = vkd3d_spirv_get_type_id_for_data_type(builder, reg->data_type, component_count); return vkd3d_spirv_get_op_undef(builder, type_id); -@@ -3972,8 +4005,8 @@ static uint32_t spirv_compiler_emit_load_scalar(struct spirv_compiler *compiler, +@@ -3972,8 +4009,8 @@ static uint32_t spirv_compiler_emit_load_scalar(struct spirv_compiler *compiler, enum vkd3d_shader_component_type component_type; uint32_t skipped_component_mask; @@ -12026,7 +12795,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 component_idx = vsir_write_mask_get_component_idx(write_mask); component_idx = vsir_swizzle_get_component(swizzle, component_idx); -@@ -4096,8 +4129,8 @@ static uint32_t spirv_compiler_emit_constant_array(struct spirv_compiler *compil +@@ -4096,8 +4133,8 @@ static uint32_t spirv_compiler_emit_constant_array(struct spirv_compiler *compil static const struct ssa_register_info *spirv_compiler_get_ssa_register_info(const struct spirv_compiler *compiler, const struct vkd3d_shader_register *reg) { @@ -12037,7 +12806,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 return &compiler->ssa_register_info[reg->idx[0].offset]; } -@@ -4105,7 +4138,7 @@ static void spirv_compiler_set_ssa_register_info(const struct spirv_compiler *co +@@ -4105,7 +4142,7 @@ static void spirv_compiler_set_ssa_register_info(const struct spirv_compiler *co const struct vkd3d_shader_register *reg, uint32_t val_id) { unsigned int i = reg->idx[0].offset; @@ -12046,7 +12815,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 compiler->ssa_register_info[i].data_type = reg->data_type; compiler->ssa_register_info[i].id = val_id; } -@@ -4125,10 +4158,10 @@ static uint32_t spirv_compiler_emit_load_ssa_reg(struct spirv_compiler *compiler +@@ -4125,10 +4162,10 @@ static uint32_t spirv_compiler_emit_load_ssa_reg(struct spirv_compiler *compiler if (!val_id) { /* Should only be from a missing instruction implementation. */ @@ -12059,7 +12828,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 reg_component_type = vkd3d_component_type_from_data_type(ssa->data_type); -@@ -4172,6 +4205,8 @@ static uint32_t spirv_compiler_emit_load_reg(struct spirv_compiler *compiler, +@@ -4172,6 +4209,8 @@ static uint32_t spirv_compiler_emit_load_reg(struct spirv_compiler *compiler, return spirv_compiler_emit_load_constant64(compiler, reg, swizzle, write_mask); else if (reg->type == VKD3DSPR_UNDEF) return spirv_compiler_emit_load_undef(compiler, reg, write_mask); @@ -12068,7 +12837,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 component_count = vsir_write_mask_component_count(write_mask); component_type = vkd3d_component_type_from_data_type(reg->data_type); -@@ -4348,7 +4383,7 @@ static void spirv_compiler_emit_store(struct spirv_compiler *compiler, +@@ -4348,7 +4387,7 @@ static void spirv_compiler_emit_store(struct spirv_compiler *compiler, unsigned int i, src_idx, dst_idx; uint32_t type_id, dst_val_id; @@ -12077,7 +12846,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 component_count = vsir_write_mask_component_count(write_mask); dst_component_count = vsir_write_mask_component_count(dst_write_mask); -@@ -4373,7 +4408,7 @@ static void spirv_compiler_emit_store(struct spirv_compiler *compiler, +@@ -4373,7 +4412,7 @@ static void spirv_compiler_emit_store(struct spirv_compiler *compiler, type_id = vkd3d_spirv_get_type_id(builder, component_type, dst_component_count); dst_val_id = vkd3d_spirv_build_op_load(builder, type_id, dst_id, SpvMemoryAccessMaskNone); @@ -12086,7 +12855,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 for (i = 0, src_idx = 0, dst_idx = 0; dst_idx < VKD3D_VEC4_SIZE; ++dst_idx) { -@@ -4402,7 +4437,7 @@ static void spirv_compiler_emit_store_reg(struct spirv_compiler *compiler, +@@ -4402,7 +4441,7 @@ static void spirv_compiler_emit_store_reg(struct spirv_compiler *compiler, uint32_t src_write_mask = write_mask; uint32_t type_id; @@ -12095,7 +12864,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 if (reg->type == VKD3DSPR_SSA) { -@@ -4461,7 +4496,7 @@ static uint32_t spirv_compiler_emit_sat(struct spirv_compiler *compiler, +@@ -4461,7 +4500,7 @@ static uint32_t spirv_compiler_emit_sat(struct spirv_compiler *compiler, static void spirv_compiler_emit_store_dst(struct spirv_compiler *compiler, const struct vkd3d_shader_dst_param *dst, uint32_t val_id) { @@ -12104,7 +12873,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 if (dst->modifiers & VKD3DSPDM_SATURATE) val_id = spirv_compiler_emit_sat(compiler, &dst->reg, dst->write_mask, val_id); -@@ -4893,7 +4928,7 @@ static uint32_t spirv_compiler_get_invocation_id(struct spirv_compiler *compiler +@@ -4893,7 +4932,7 @@ static uint32_t spirv_compiler_get_invocation_id(struct spirv_compiler *compiler { struct vkd3d_shader_register r; @@ -12113,7 +12882,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 vsir_register_init(&r, VKD3DSPR_OUTPOINTID, VKD3D_DATA_FLOAT, 0); return spirv_compiler_get_register_id(compiler, &r); -@@ -5013,7 +5048,7 @@ static uint32_t spirv_compiler_emit_builtin_variable_v(struct spirv_compiler *co +@@ -5013,7 +5052,7 @@ static uint32_t spirv_compiler_emit_builtin_variable_v(struct spirv_compiler *co unsigned int sizes[2]; uint32_t id; @@ -12122,7 +12891,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 memcpy(sizes, array_sizes, size_count * sizeof(sizes[0])); array_sizes = sizes; sizes[0] = max(sizes[0], builtin->spirv_array_size); -@@ -5175,7 +5210,7 @@ static uint32_t spirv_compiler_emit_input(struct spirv_compiler *compiler, +@@ -5175,7 +5214,7 @@ static uint32_t spirv_compiler_emit_input(struct spirv_compiler *compiler, use_private_var ? VKD3D_SHADER_COMPONENT_FLOAT : component_type, use_private_var ? VKD3DSP_WRITEMASK_ALL : reg_write_mask); reg_symbol.info.reg.is_aggregate = array_sizes[0] || array_sizes[1]; @@ -12131,7 +12900,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 spirv_compiler_put_symbol(compiler, ®_symbol); vkd3d_spirv_build_op_name(builder, var_id, reg_type == VKD3DSPR_PATCHCONST ? "vpc%u" : "v%u", element_idx); -@@ -5221,8 +5256,8 @@ static void spirv_compiler_emit_input_register(struct spirv_compiler *compiler, +@@ -5221,8 +5260,8 @@ static void spirv_compiler_emit_input_register(struct spirv_compiler *compiler, uint32_t write_mask; uint32_t input_id; @@ -12142,7 +12911,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 if (!(builtin = get_spirv_builtin_for_register(reg->type))) { -@@ -5356,8 +5391,8 @@ static void spirv_compiler_emit_output_register(struct spirv_compiler *compiler, +@@ -5356,8 +5395,8 @@ static void spirv_compiler_emit_output_register(struct spirv_compiler *compiler, uint32_t write_mask; uint32_t output_id; @@ -12153,7 +12922,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 if (!(builtin = get_spirv_builtin_for_register(reg->type))) { -@@ -5543,7 +5578,7 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler, +@@ -5543,7 +5582,7 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler, use_private_variable ? VKD3D_SHADER_COMPONENT_FLOAT : component_type, use_private_variable ? VKD3DSP_WRITEMASK_ALL : reg_write_mask); reg_symbol.info.reg.is_aggregate = array_sizes[0] || array_sizes[1]; @@ -12162,7 +12931,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 spirv_compiler_put_symbol(compiler, ®_symbol); -@@ -5881,7 +5916,7 @@ static void spirv_compiler_emit_temps(struct spirv_compiler *compiler, uint32_t +@@ -5881,7 +5920,7 @@ static void spirv_compiler_emit_temps(struct spirv_compiler *compiler, uint32_t function_location = spirv_compiler_get_current_function_location(compiler); vkd3d_spirv_begin_function_stream_insertion(builder, function_location); @@ -12171,7 +12940,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 compiler->temp_count = count; for (i = 0; i < compiler->temp_count; ++i) { -@@ -5889,7 +5924,7 @@ static void spirv_compiler_emit_temps(struct spirv_compiler *compiler, uint32_t +@@ -5889,7 +5928,7 @@ static void spirv_compiler_emit_temps(struct spirv_compiler *compiler, uint32_t SpvStorageClassPrivate, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE); if (!i) compiler->temp_id = id; @@ -12180,7 +12949,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 vkd3d_spirv_build_op_name(builder, id, "r%u", i); } -@@ -5899,7 +5934,7 @@ static void spirv_compiler_emit_temps(struct spirv_compiler *compiler, uint32_t +@@ -5899,7 +5938,7 @@ static void spirv_compiler_emit_temps(struct spirv_compiler *compiler, uint32_t static void spirv_compiler_allocate_ssa_register_ids(struct spirv_compiler *compiler, unsigned int count) { @@ -12189,7 +12958,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 if (!(compiler->ssa_register_info = vkd3d_calloc(count, sizeof(*compiler->ssa_register_info)))) { ERR("Failed to allocate SSA register value id array, count %u.\n", count); -@@ -6001,7 +6036,7 @@ static void spirv_compiler_emit_push_constant_buffers(struct spirv_compiler *com +@@ -6001,7 +6040,7 @@ static void spirv_compiler_emit_push_constant_buffers(struct spirv_compiler *com vkd3d_spirv_build_op_decorate1(builder, member_ids[j], SpvDecorationArrayStride, 4); descriptor_offsets_member_idx = j; compiler->descriptor_offsets_member_id = spirv_compiler_get_constant_uint(compiler, j); @@ -12198,7 +12967,171 @@ index 984a4f894f6..bc8a7a5b28c 100644 } struct_id = vkd3d_spirv_build_op_type_struct(builder, member_ids, count); -@@ -6488,7 +6523,7 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp +@@ -6041,21 +6080,54 @@ static void spirv_compiler_emit_push_constant_buffers(struct spirv_compiler *com + } + } + ++static const struct vkd3d_shader_descriptor_info1 *spirv_compiler_get_descriptor_info( ++ struct spirv_compiler *compiler, enum vkd3d_shader_descriptor_type type, ++ const struct vkd3d_shader_register_range *range) ++{ ++ const struct vkd3d_shader_scan_descriptor_info1 *descriptor_info = compiler->scan_descriptor_info; ++ unsigned int register_last = (range->last == ~0u) ? range->first : range->last; ++ const struct vkd3d_shader_descriptor_info1 *d; ++ unsigned int i; ++ ++ for (i = 0; i < descriptor_info->descriptor_count; ++i) ++ { ++ d = &descriptor_info->descriptors[i]; ++ if (d->type == type && d->register_space == range->space && d->register_index <= range->first ++ && (d->count == ~0u || d->count > register_last - d->register_index)) ++ return d; ++ } ++ ++ return NULL; ++} ++ + struct vkd3d_descriptor_variable_info + { + const struct vkd3d_symbol *array_symbol; + unsigned int binding_base_idx; + }; + ++static void spirv_compiler_decorate_descriptor(struct spirv_compiler *compiler, ++ uint32_t var_id, bool write_only, bool coherent) ++{ ++ struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; ++ ++ if (write_only) ++ vkd3d_spirv_build_op_decorate(builder, var_id, SpvDecorationNonReadable, NULL, 0); ++ if (coherent) ++ vkd3d_spirv_build_op_decorate(builder, var_id, SpvDecorationCoherent, NULL, 0); ++} ++ + static uint32_t spirv_compiler_build_descriptor_variable(struct spirv_compiler *compiler, + SpvStorageClass storage_class, uint32_t type_id, const struct vkd3d_shader_register *reg, + const struct vkd3d_shader_register_range *range, enum vkd3d_shader_resource_type resource_type, +- bool is_uav_counter, struct vkd3d_descriptor_variable_info *var_info) ++ bool is_uav, bool is_uav_counter, struct vkd3d_descriptor_variable_info *var_info) + { + struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; + struct vkd3d_descriptor_binding_address binding_address; + struct vkd3d_shader_descriptor_binding binding; ++ const struct vkd3d_shader_descriptor_info1 *d; + uint32_t array_type_id, ptr_type_id, var_id; ++ bool write_only = false, coherent = false; + struct vkd3d_symbol symbol; + struct rb_entry *entry; + +@@ -6063,6 +6135,14 @@ static uint32_t spirv_compiler_build_descriptor_variable(struct spirv_compiler * + resource_type, is_uav_counter, &binding_address); + var_info->binding_base_idx = binding_address.binding_base_idx; + ++ if (is_uav) ++ { ++ d = spirv_compiler_get_descriptor_info(compiler, VKD3D_SHADER_DESCRIPTOR_TYPE_UAV, range); ++ write_only = !(d->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_READ); ++ /* ROVs are implicitly globally coherent. */ ++ coherent = d->uav_flags & (VKD3DSUF_GLOBALLY_COHERENT | VKD3DSUF_RASTERISER_ORDERED_VIEW); ++ } ++ + if (binding.count == 1 && range->first == binding_address.binding_base_idx && range->last != ~0u + && binding_address.push_constant_index == ~0u) + { +@@ -6072,6 +6152,7 @@ static uint32_t spirv_compiler_build_descriptor_variable(struct spirv_compiler * + + spirv_compiler_emit_descriptor_binding(compiler, var_id, &binding); + spirv_compiler_emit_register_debug_name(builder, var_id, reg); ++ spirv_compiler_decorate_descriptor(compiler, var_id, write_only, coherent); + + var_info->array_symbol = NULL; + return var_id; +@@ -6089,6 +6170,8 @@ static uint32_t spirv_compiler_build_descriptor_variable(struct spirv_compiler * + symbol.key.descriptor_array.set = binding.set; + symbol.key.descriptor_array.binding = binding.binding; + symbol.key.descriptor_array.push_constant_index = binding_address.push_constant_index; ++ symbol.key.descriptor_array.write_only = write_only; ++ symbol.key.descriptor_array.coherent = coherent; + if ((entry = rb_get(&compiler->symbol_table, &symbol))) + { + var_info->array_symbol = RB_ENTRY_VALUE(entry, struct vkd3d_symbol, entry); +@@ -6099,6 +6182,7 @@ static uint32_t spirv_compiler_build_descriptor_variable(struct spirv_compiler * + ptr_type_id, storage_class, 0); + spirv_compiler_emit_descriptor_binding(compiler, var_id, &binding); + spirv_compiler_emit_register_debug_name(builder, var_id, reg); ++ spirv_compiler_decorate_descriptor(compiler, var_id, write_only, coherent); + + symbol.id = var_id; + symbol.descriptor_array = NULL; +@@ -6155,7 +6239,7 @@ static void spirv_compiler_emit_cbv_declaration(struct spirv_compiler *compiler, + vkd3d_spirv_build_op_name(builder, struct_id, "cb%u_struct", size); + + var_id = spirv_compiler_build_descriptor_variable(compiler, storage_class, struct_id, +- ®, range, VKD3D_SHADER_RESOURCE_BUFFER, false, &var_info); ++ ®, range, VKD3D_SHADER_RESOURCE_BUFFER, false, false, &var_info); + + vkd3d_symbol_make_register(®_symbol, ®); + vkd3d_symbol_set_register_info(®_symbol, var_id, storage_class, +@@ -6212,7 +6296,7 @@ static void spirv_compiler_emit_sampler_declaration(struct spirv_compiler *compi + + type_id = vkd3d_spirv_get_op_type_sampler(builder); + var_id = spirv_compiler_build_descriptor_variable(compiler, storage_class, type_id, ®, +- range, VKD3D_SHADER_RESOURCE_NONE, false, &var_info); ++ range, VKD3D_SHADER_RESOURCE_NONE, false, false, &var_info); + + vkd3d_symbol_make_register(®_symbol, ®); + vkd3d_symbol_set_register_info(®_symbol, var_id, storage_class, +@@ -6259,26 +6343,6 @@ static SpvImageFormat image_format_for_image_read(enum vkd3d_shader_component_ty + } + } + +-static const struct vkd3d_shader_descriptor_info1 *spirv_compiler_get_descriptor_info( +- struct spirv_compiler *compiler, enum vkd3d_shader_descriptor_type type, +- const struct vkd3d_shader_register_range *range) +-{ +- const struct vkd3d_shader_scan_descriptor_info1 *descriptor_info = compiler->scan_descriptor_info; +- unsigned int register_last = (range->last == ~0u) ? range->first : range->last; +- const struct vkd3d_shader_descriptor_info1 *d; +- unsigned int i; +- +- for (i = 0; i < descriptor_info->descriptor_count; ++i) +- { +- d = &descriptor_info->descriptors[i]; +- if (d->type == type && d->register_space == range->space && d->register_index <= range->first +- && (d->count == ~0u || d->count > register_last - d->register_index)) +- return d; +- } +- +- return NULL; +-} +- + static uint32_t spirv_compiler_get_image_type_id(struct spirv_compiler *compiler, + const struct vkd3d_shader_register *reg, const struct vkd3d_shader_register_range *range, + const struct vkd3d_spirv_resource_type *resource_type_info, enum vkd3d_shader_component_type data_type, +@@ -6457,7 +6521,7 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp + } + + var_id = spirv_compiler_build_descriptor_variable(compiler, storage_class, type_id, ®, +- range, resource_type, false, &var_info); ++ range, resource_type, is_uav, false, &var_info); + + if (is_uav) + { +@@ -6465,13 +6529,6 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp + + d = spirv_compiler_get_descriptor_info(compiler, VKD3D_SHADER_DESCRIPTOR_TYPE_UAV, range); + +- if (!(d->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_READ)) +- vkd3d_spirv_build_op_decorate(builder, var_id, SpvDecorationNonReadable, NULL, 0); +- +- /* ROVs are implicitly globally coherent. */ +- if (d->uav_flags & (VKD3DSUF_GLOBALLY_COHERENT | VKD3DSUF_RASTERISER_ORDERED_VIEW)) +- vkd3d_spirv_build_op_decorate(builder, var_id, SpvDecorationCoherent, NULL, 0); +- + if (d->uav_flags & VKD3DSUF_RASTERISER_ORDERED_VIEW) + { + if (compiler->shader_type != VKD3D_SHADER_TYPE_PIXEL) +@@ -6488,7 +6545,7 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp if (d->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_COUNTER) { @@ -12207,7 +13140,16 @@ index 984a4f894f6..bc8a7a5b28c 100644 counter_type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); if (spirv_compiler_is_opengl_target(compiler)) -@@ -6831,7 +6866,7 @@ static void spirv_compiler_enter_shader_phase(struct spirv_compiler *compiler, +@@ -6514,7 +6571,7 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp + } + + counter_var_id = spirv_compiler_build_descriptor_variable(compiler, storage_class, +- type_id, ®, range, resource_type, true, &counter_var_info); ++ type_id, ®, range, resource_type, false, true, &counter_var_info); + } + } + +@@ -6831,7 +6888,7 @@ static void spirv_compiler_enter_shader_phase(struct spirv_compiler *compiler, uint32_t function_id, void_id, function_type_id; struct vkd3d_shader_phase *phase; @@ -12216,7 +13158,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 if (!is_in_default_phase(compiler)) spirv_compiler_leave_shader_phase(compiler); -@@ -6843,16 +6878,16 @@ static void spirv_compiler_enter_shader_phase(struct spirv_compiler *compiler, +@@ -6843,16 +6900,16 @@ static void spirv_compiler_enter_shader_phase(struct spirv_compiler *compiler, vkd3d_spirv_build_op_function(builder, void_id, function_id, SpvFunctionControlMaskNone, function_type_id); @@ -12236,7 +13178,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 compiler->emit_default_control_point_phase = instruction->flags; } -@@ -6908,7 +6943,7 @@ static void spirv_compiler_emit_default_control_point_phase(struct spirv_compile +@@ -6908,7 +6965,7 @@ static void spirv_compiler_emit_default_control_point_phase(struct spirv_compile input_reg.idx[1].offset = 0; input_id = spirv_compiler_get_register_id(compiler, &input_reg); @@ -12245,7 +13187,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 for (i = 0; i < output_signature->element_count; ++i) { const struct signature_element *output = &output_signature->elements[i]; -@@ -6916,8 +6951,8 @@ static void spirv_compiler_emit_default_control_point_phase(struct spirv_compile +@@ -6916,8 +6973,8 @@ static void spirv_compiler_emit_default_control_point_phase(struct spirv_compile struct vkd3d_shader_register_info output_reg_info; struct vkd3d_shader_register output_reg; @@ -12256,7 +13198,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 input_reg.idx[1].offset = i; input_id = spirv_compiler_get_register_id(compiler, &input_reg); -@@ -7016,7 +7051,7 @@ static SpvOp spirv_compiler_map_alu_instruction(const struct vkd3d_shader_instru +@@ -7016,7 +7073,7 @@ static SpvOp spirv_compiler_map_alu_instruction(const struct vkd3d_shader_instru { static const struct { @@ -12265,7 +13207,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 SpvOp spirv_op; } alu_ops[] = -@@ -7056,7 +7091,7 @@ static SpvOp spirv_compiler_map_alu_instruction(const struct vkd3d_shader_instru +@@ -7056,7 +7113,7 @@ static SpvOp spirv_compiler_map_alu_instruction(const struct vkd3d_shader_instru for (i = 0; i < ARRAY_SIZE(alu_ops); ++i) { @@ -12274,7 +13216,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 return alu_ops[i].spirv_op; } -@@ -7065,7 +7100,7 @@ static SpvOp spirv_compiler_map_alu_instruction(const struct vkd3d_shader_instru +@@ -7065,7 +7122,7 @@ static SpvOp spirv_compiler_map_alu_instruction(const struct vkd3d_shader_instru static SpvOp spirv_compiler_map_logical_instruction(const struct vkd3d_shader_instruction *instruction) { @@ -12283,7 +13225,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 { case VKD3DSIH_AND: return SpvOpLogicalAnd; -@@ -7085,25 +7120,25 @@ static void spirv_compiler_emit_bool_cast(struct spirv_compiler *compiler, +@@ -7085,25 +7142,25 @@ static void spirv_compiler_emit_bool_cast(struct spirv_compiler *compiler, const struct vkd3d_shader_src_param *src = instruction->src; uint32_t val_id; @@ -12314,7 +13256,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 } else { -@@ -7126,7 +7161,7 @@ static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compil +@@ -7126,7 +7183,7 @@ static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compil SpvOp op = SpvOpMax; unsigned int i; @@ -12323,7 +13265,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 { /* At least some drivers support this anyway, but if validation is enabled it will fail. */ FIXME("Unsupported 64-bit source for bit count.\n"); -@@ -7142,8 +7177,8 @@ static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compil +@@ -7142,8 +7199,8 @@ static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compil /* VSIR supports logic ops AND/OR/XOR on bool values. */ op = spirv_compiler_map_logical_instruction(instruction); } @@ -12334,7 +13276,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 { /* VSIR supports cast from bool to signed/unsigned integer types and floating point types, * where bool is treated as a 1-bit integer and a signed 'true' value converts to -1. */ -@@ -7158,14 +7193,14 @@ static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compil +@@ -7158,14 +7215,14 @@ static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compil if (op == SpvOpMax) { @@ -12353,7 +13295,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 type_id = spirv_compiler_get_type_id_for_dst(compiler, dst); -@@ -7179,8 +7214,8 @@ static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compil +@@ -7179,8 +7236,8 @@ static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compil * Microsoft fxc will compile immediate constants larger than 5 bits. * Fixing up the constants would be more elegant, but the simplest way is * to let this handle constants too. */ @@ -12364,7 +13306,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 { uint32_t mask_id = spirv_compiler_get_constant_vector(compiler, VKD3D_SHADER_COMPONENT_UINT, vsir_write_mask_component_count(dst->write_mask), 0x1f); -@@ -7218,7 +7253,7 @@ static enum GLSLstd450 spirv_compiler_map_ext_glsl_instruction( +@@ -7218,7 +7275,7 @@ static enum GLSLstd450 spirv_compiler_map_ext_glsl_instruction( { static const struct { @@ -12373,7 +13315,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 enum GLSLstd450 glsl_inst; } glsl_insts[] = -@@ -7258,7 +7293,7 @@ static enum GLSLstd450 spirv_compiler_map_ext_glsl_instruction( +@@ -7258,7 +7315,7 @@ static enum GLSLstd450 spirv_compiler_map_ext_glsl_instruction( for (i = 0; i < ARRAY_SIZE(glsl_insts); ++i) { @@ -12382,7 +13324,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 return glsl_insts[i].glsl_inst; } -@@ -7276,27 +7311,27 @@ static void spirv_compiler_emit_ext_glsl_instruction(struct spirv_compiler *comp +@@ -7276,27 +7333,27 @@ static void spirv_compiler_emit_ext_glsl_instruction(struct spirv_compiler *comp unsigned int i, component_count; enum GLSLstd450 glsl_inst; @@ -12417,7 +13359,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 type_id = spirv_compiler_get_type_id_for_dst(compiler, dst); -@@ -7306,8 +7341,8 @@ static void spirv_compiler_emit_ext_glsl_instruction(struct spirv_compiler *comp +@@ -7306,8 +7363,8 @@ static void spirv_compiler_emit_ext_glsl_instruction(struct spirv_compiler *comp val_id = vkd3d_spirv_build_op_ext_inst(builder, type_id, instr_set_id, glsl_inst, src_id, instruction->src_count); @@ -12428,7 +13370,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 { /* In D3D bits are numbered from the most significant bit. */ component_count = vsir_write_mask_component_count(dst->write_mask); -@@ -7415,7 +7450,7 @@ static void spirv_compiler_emit_movc(struct spirv_compiler *compiler, +@@ -7415,7 +7472,7 @@ static void spirv_compiler_emit_movc(struct spirv_compiler *compiler, if (src[0].reg.data_type != VKD3D_DATA_BOOL) { @@ -12437,7 +13379,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 condition_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, SpvOpFOrdGreaterThanEqual, vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count), condition_id, spirv_compiler_get_constant_float_vector(compiler, 0.0f, component_count)); -@@ -7437,7 +7472,7 @@ static void spirv_compiler_emit_swapc(struct spirv_compiler *compiler, +@@ -7437,7 +7494,7 @@ static void spirv_compiler_emit_swapc(struct spirv_compiler *compiler, uint32_t condition_id, src1_id, src2_id, type_id, val_id; unsigned int component_count; @@ -12446,7 +13388,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 condition_id = spirv_compiler_emit_load_src(compiler, &src[0], dst->write_mask); src1_id = spirv_compiler_emit_load_src(compiler, &src[1], dst->write_mask); -@@ -7469,14 +7504,14 @@ static void spirv_compiler_emit_dot(struct spirv_compiler *compiler, +@@ -7469,14 +7526,14 @@ static void spirv_compiler_emit_dot(struct spirv_compiler *compiler, component_count = vsir_write_mask_component_count(dst->write_mask); component_type = vkd3d_component_type_from_data_type(dst->reg.data_type); @@ -12464,7 +13406,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 for (i = 0; i < ARRAY_SIZE(src_ids); ++i) src_ids[i] = spirv_compiler_emit_load_src(compiler, &src[i], write_mask); -@@ -7606,8 +7641,8 @@ static void spirv_compiler_emit_int_div(struct spirv_compiler *compiler, +@@ -7606,8 +7663,8 @@ static void spirv_compiler_emit_int_div(struct spirv_compiler *compiler, unsigned int component_count = 0; SpvOp div_op, mod_op; @@ -12475,7 +13417,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 if (dst[0].reg.type != VKD3DSPR_NULL) { -@@ -7668,8 +7703,8 @@ static void spirv_compiler_emit_ftoi(struct spirv_compiler *compiler, +@@ -7668,8 +7725,8 @@ static void spirv_compiler_emit_ftoi(struct spirv_compiler *compiler, enum vkd3d_shader_component_type component_type; unsigned int component_count; @@ -12486,7 +13428,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 /* OpConvertFToI has undefined results if the result cannot be represented * as a signed integer, but Direct3D expects the result to saturate, -@@ -7721,8 +7756,8 @@ static void spirv_compiler_emit_ftou(struct spirv_compiler *compiler, +@@ -7721,8 +7778,8 @@ static void spirv_compiler_emit_ftou(struct spirv_compiler *compiler, uint32_t src_type_id, dst_type_id, condition_type_id; unsigned int component_count; @@ -12497,7 +13439,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 /* OpConvertFToU has undefined results if the result cannot be represented * as an unsigned integer, but Direct3D expects the result to saturate, -@@ -7770,7 +7805,7 @@ static void spirv_compiler_emit_bitfield_instruction(struct spirv_compiler *comp +@@ -7770,7 +7827,7 @@ static void spirv_compiler_emit_bitfield_instruction(struct spirv_compiler *comp SpvOp op; src_count = instruction->src_count; @@ -12506,7 +13448,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 component_type = vkd3d_component_type_from_data_type(dst->reg.data_type); type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); -@@ -7778,17 +7813,17 @@ static void spirv_compiler_emit_bitfield_instruction(struct spirv_compiler *comp +@@ -7778,17 +7835,17 @@ static void spirv_compiler_emit_bitfield_instruction(struct spirv_compiler *comp mask_id = spirv_compiler_get_constant_uint(compiler, size - 1); size_id = spirv_compiler_get_constant_uint(compiler, size); @@ -12527,7 +13469,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 for (i = 0, k = 0; i < VKD3D_VEC4_SIZE; ++i) { if (!(write_mask = dst->write_mask & (VKD3DSP_WRITEMASK_0 << i))) -@@ -7832,7 +7867,7 @@ static void spirv_compiler_emit_f16tof32(struct spirv_compiler *compiler, +@@ -7832,7 +7889,7 @@ static void spirv_compiler_emit_f16tof32(struct spirv_compiler *compiler, scalar_type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, 1); /* FIXME: Consider a single UnpackHalf2x16 instruction per 2 components. */ @@ -12536,7 +13478,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 for (i = 0, j = 0; i < VKD3D_VEC4_SIZE; ++i) { if (!(write_mask = dst->write_mask & (VKD3DSP_WRITEMASK_0 << i))) -@@ -7866,7 +7901,7 @@ static void spirv_compiler_emit_f32tof16(struct spirv_compiler *compiler, +@@ -7866,7 +7923,7 @@ static void spirv_compiler_emit_f32tof16(struct spirv_compiler *compiler, zero_id = spirv_compiler_get_constant_float(compiler, 0.0f); /* FIXME: Consider a single PackHalf2x16 instruction per 2 components. */ @@ -12545,7 +13487,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 for (i = 0, j = 0; i < VKD3D_VEC4_SIZE; ++i) { if (!(write_mask = dst->write_mask & (VKD3DSP_WRITEMASK_0 << i))) -@@ -7895,7 +7930,7 @@ static void spirv_compiler_emit_comparison_instruction(struct spirv_compiler *co +@@ -7895,7 +7952,7 @@ static void spirv_compiler_emit_comparison_instruction(struct spirv_compiler *co unsigned int component_count; SpvOp op; @@ -12554,7 +13496,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 { case VKD3DSIH_DEQO: case VKD3DSIH_EQO: op = SpvOpFOrdEqual; break; -@@ -7916,7 +7951,7 @@ static void spirv_compiler_emit_comparison_instruction(struct spirv_compiler *co +@@ -7916,7 +7973,7 @@ static void spirv_compiler_emit_comparison_instruction(struct spirv_compiler *co case VKD3DSIH_UGE: op = SpvOpUGreaterThanEqual; break; case VKD3DSIH_ULT: op = SpvOpULessThan; break; default: @@ -12563,7 +13505,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 return; } -@@ -7949,7 +7984,7 @@ static void spirv_compiler_emit_orderedness_instruction(struct spirv_compiler *c +@@ -7949,7 +8006,7 @@ static void spirv_compiler_emit_orderedness_instruction(struct spirv_compiler *c src0_id = vkd3d_spirv_build_op_is_nan(builder, type_id, src0_id); src1_id = vkd3d_spirv_build_op_is_nan(builder, type_id, src1_id); val_id = vkd3d_spirv_build_op_logical_or(builder, type_id, src0_id, src1_id); @@ -12572,7 +13514,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 val_id = vkd3d_spirv_build_op_logical_not(builder, type_id, val_id); spirv_compiler_emit_store_dst(compiler, dst, val_id); } -@@ -7964,7 +7999,7 @@ static void spirv_compiler_emit_float_comparison_instruction(struct spirv_compil +@@ -7964,7 +8021,7 @@ static void spirv_compiler_emit_float_comparison_instruction(struct spirv_compil unsigned int component_count; SpvOp op; @@ -12581,7 +13523,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 { case VKD3DSIH_SLT: op = SpvOpFOrdLessThan; break; case VKD3DSIH_SGE: op = SpvOpFOrdGreaterThanEqual; break; -@@ -8113,6 +8148,8 @@ static void spirv_compiler_emit_discard(struct spirv_compiler *compiler, +@@ -8113,6 +8170,8 @@ static void spirv_compiler_emit_discard(struct spirv_compiler *compiler, if (src->reg.data_type != VKD3D_DATA_BOOL) condition_id = spirv_compiler_emit_int_to_bool(compiler, instruction->flags, src->reg.data_type, 1, condition_id); @@ -12590,7 +13532,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 void_id = vkd3d_spirv_get_op_type_void(builder); vkd3d_spirv_build_op_function_call(builder, void_id, spirv_compiler_get_discard_function_id(compiler), &condition_id, 1); -@@ -8262,7 +8299,7 @@ static void spirv_compiler_emit_deriv_instruction(struct spirv_compiler *compile +@@ -8262,7 +8321,7 @@ static void spirv_compiler_emit_deriv_instruction(struct spirv_compiler *compile static const struct instruction_info { @@ -12599,7 +13541,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 SpvOp op; bool needs_derivative_control; } -@@ -8279,7 +8316,7 @@ static void spirv_compiler_emit_deriv_instruction(struct spirv_compiler *compile +@@ -8279,7 +8338,7 @@ static void spirv_compiler_emit_deriv_instruction(struct spirv_compiler *compile info = NULL; for (i = 0; i < ARRAY_SIZE(deriv_instructions); ++i) { @@ -12608,7 +13550,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 { info = &deriv_instructions[i]; break; -@@ -8287,15 +8324,15 @@ static void spirv_compiler_emit_deriv_instruction(struct spirv_compiler *compile +@@ -8287,15 +8346,15 @@ static void spirv_compiler_emit_deriv_instruction(struct spirv_compiler *compile } if (!info) { @@ -12627,7 +13569,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 type_id = spirv_compiler_get_type_id_for_dst(compiler, dst); src_id = spirv_compiler_emit_load_src(compiler, src, dst->write_mask); -@@ -8329,7 +8366,7 @@ static const struct vkd3d_symbol *spirv_compiler_find_resource(struct spirv_comp +@@ -8329,7 +8388,7 @@ static const struct vkd3d_symbol *spirv_compiler_find_resource(struct spirv_comp vkd3d_symbol_make_resource(&resource_key, resource_reg); entry = rb_get(&compiler->symbol_table, &resource_key); @@ -12636,7 +13578,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 return RB_ENTRY_VALUE(entry, struct vkd3d_symbol, entry); } -@@ -8438,8 +8475,8 @@ static void spirv_compiler_prepare_image(struct spirv_compiler *compiler, +@@ -8438,8 +8497,8 @@ static void spirv_compiler_prepare_image(struct spirv_compiler *compiler, { struct vkd3d_shader_register_info register_info; @@ -12647,7 +13589,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 if (!spirv_compiler_get_register_info(compiler, sampler_reg, ®ister_info)) ERR("Failed to get sampler register info.\n"); -@@ -8497,7 +8534,7 @@ static void spirv_compiler_emit_ld(struct spirv_compiler *compiler, +@@ -8497,7 +8556,7 @@ static void spirv_compiler_emit_ld(struct spirv_compiler *compiler, uint32_t coordinate_mask; bool multisample; @@ -12656,7 +13598,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 spirv_compiler_prepare_image(compiler, &image, &src[1].reg, NULL, VKD3D_IMAGE_FLAG_NONE); -@@ -8522,7 +8559,7 @@ static void spirv_compiler_emit_ld(struct spirv_compiler *compiler, +@@ -8522,7 +8581,7 @@ static void spirv_compiler_emit_ld(struct spirv_compiler *compiler, image_operands[image_operand_count++] = spirv_compiler_emit_load_src(compiler, &src[2], VKD3DSP_WRITEMASK_0); } @@ -12665,7 +13607,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 val_id = vkd3d_spirv_build_op_image_fetch(builder, type_id, image.image_id, coordinate_id, operands_mask, image_operands, image_operand_count); -@@ -8576,7 +8613,7 @@ static void spirv_compiler_emit_sample(struct spirv_compiler *compiler, +@@ -8576,7 +8635,7 @@ static void spirv_compiler_emit_sample(struct spirv_compiler *compiler, spirv_compiler_prepare_image(compiler, &image, &resource->reg, &sampler->reg, VKD3D_IMAGE_FLAG_SAMPLED); @@ -12674,7 +13616,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 { case VKD3DSIH_SAMPLE: op = SpvOpImageSampleImplicitLod; -@@ -8603,7 +8640,7 @@ static void spirv_compiler_emit_sample(struct spirv_compiler *compiler, +@@ -8603,7 +8662,7 @@ static void spirv_compiler_emit_sample(struct spirv_compiler *compiler, &src[3], VKD3DSP_WRITEMASK_0); break; default: @@ -12683,7 +13625,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 return; } -@@ -8616,7 +8653,7 @@ static void spirv_compiler_emit_sample(struct spirv_compiler *compiler, +@@ -8616,7 +8675,7 @@ static void spirv_compiler_emit_sample(struct spirv_compiler *compiler, sampled_type_id = vkd3d_spirv_get_type_id(builder, image.sampled_type, VKD3D_VEC4_SIZE); coordinate_id = spirv_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_ALL); @@ -12692,7 +13634,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 val_id = vkd3d_spirv_build_op_image_sample(builder, op, sampled_type_id, image.sampled_image_id, coordinate_id, operands_mask, image_operands, image_operand_count); -@@ -8637,7 +8674,7 @@ static void spirv_compiler_emit_sample_c(struct spirv_compiler *compiler, +@@ -8637,7 +8696,7 @@ static void spirv_compiler_emit_sample_c(struct spirv_compiler *compiler, uint32_t image_operands[2]; SpvOp op; @@ -12701,7 +13643,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 { op = SpvOpImageSampleDrefExplicitLod; operands_mask |= SpvImageOperandsLodMask; -@@ -8687,12 +8724,12 @@ static void spirv_compiler_emit_gather4(struct spirv_compiler *compiler, +@@ -8687,12 +8746,12 @@ static void spirv_compiler_emit_gather4(struct spirv_compiler *compiler, uint32_t coordinate_mask; bool extended_offset; @@ -12718,7 +13660,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 addr = &src[0]; offset = extended_offset ? &src[1] : NULL; -@@ -8801,7 +8838,7 @@ static void spirv_compiler_emit_ld_raw_structured_srv_uav(struct spirv_compiler +@@ -8801,7 +8860,7 @@ static void spirv_compiler_emit_ld_raw_structured_srv_uav(struct spirv_compiler type_id, resource_symbol->info.resource.structure_stride, &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0); @@ -12727,7 +13669,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 for (i = 0, j = 0; i < VKD3D_VEC4_SIZE; ++i) { if (!(dst->write_mask & (VKD3DSP_WRITEMASK_0 << i))) -@@ -8833,7 +8870,7 @@ static void spirv_compiler_emit_ld_raw_structured_srv_uav(struct spirv_compiler +@@ -8833,7 +8892,7 @@ static void spirv_compiler_emit_ld_raw_structured_srv_uav(struct spirv_compiler type_id, image.structure_stride, &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0); texel_type_id = vkd3d_spirv_get_type_id(builder, image.sampled_type, VKD3D_VEC4_SIZE); @@ -12736,7 +13678,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 for (i = 0, j = 0; i < VKD3D_VEC4_SIZE; ++i) { if (!(dst->write_mask & (VKD3DSP_WRITEMASK_0 << i))) -@@ -8876,7 +8913,7 @@ static void spirv_compiler_emit_ld_tgsm(struct spirv_compiler *compiler, +@@ -8876,7 +8935,7 @@ static void spirv_compiler_emit_ld_tgsm(struct spirv_compiler *compiler, base_coordinate_id = spirv_compiler_emit_raw_structured_addressing(compiler, type_id, reg_info.structure_stride, &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0); @@ -12745,7 +13687,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 for (i = 0, j = 0; i < VKD3D_VEC4_SIZE; ++i) { if (!(dst->write_mask & (VKD3DSP_WRITEMASK_0 << i))) -@@ -8939,7 +8976,7 @@ static void spirv_compiler_emit_store_uav_raw_structured(struct spirv_compiler * +@@ -8939,7 +8998,7 @@ static void spirv_compiler_emit_store_uav_raw_structured(struct spirv_compiler * &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0); data = &src[instruction->src_count - 1]; @@ -12754,7 +13696,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 val_id = spirv_compiler_emit_load_src(compiler, data, dst->write_mask); component_count = vsir_write_mask_component_count(dst->write_mask); -@@ -8963,12 +9000,11 @@ static void spirv_compiler_emit_store_uav_raw_structured(struct spirv_compiler * +@@ -8963,12 +9022,11 @@ static void spirv_compiler_emit_store_uav_raw_structured(struct spirv_compiler * { type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); spirv_compiler_prepare_image(compiler, &image, &dst->reg, NULL, VKD3D_IMAGE_FLAG_NONE); @@ -12768,7 +13710,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 val_id = spirv_compiler_emit_load_src(compiler, data, dst->write_mask); component_count = vsir_write_mask_component_count(dst->write_mask); -@@ -9007,7 +9043,6 @@ static void spirv_compiler_emit_store_tgsm(struct spirv_compiler *compiler, +@@ -9007,7 +9065,6 @@ static void spirv_compiler_emit_store_tgsm(struct spirv_compiler *compiler, type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, reg_info.storage_class, type_id); @@ -12776,7 +13718,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 base_coordinate_id = spirv_compiler_emit_raw_structured_addressing(compiler, type_id, reg_info.structure_stride, &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0); -@@ -9145,12 +9180,12 @@ static void spirv_compiler_emit_uav_counter_instruction(struct spirv_compiler *c +@@ -9145,12 +9202,12 @@ static void spirv_compiler_emit_uav_counter_instruction(struct spirv_compiler *c uint32_t operands[3]; SpvOp op; @@ -12791,7 +13733,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); -@@ -9211,7 +9246,7 @@ static SpvOp spirv_compiler_map_atomic_instruction(const struct vkd3d_shader_ins +@@ -9211,7 +9268,7 @@ static SpvOp spirv_compiler_map_atomic_instruction(const struct vkd3d_shader_ins { static const struct { @@ -12800,7 +13742,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 SpvOp spirv_op; } atomic_ops[] = -@@ -9240,16 +9275,16 @@ static SpvOp spirv_compiler_map_atomic_instruction(const struct vkd3d_shader_ins +@@ -9240,16 +9297,16 @@ static SpvOp spirv_compiler_map_atomic_instruction(const struct vkd3d_shader_ins for (i = 0; i < ARRAY_SIZE(atomic_ops); ++i) { @@ -12820,7 +13762,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 } static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compiler, -@@ -9274,12 +9309,12 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil +@@ -9274,12 +9331,12 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil bool raw; SpvOp op; @@ -12835,7 +13777,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 return; } -@@ -9315,14 +9350,14 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil +@@ -9315,14 +9372,14 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); if (structure_stride || raw) { @@ -12852,7 +13794,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 coordinate_id = spirv_compiler_emit_load_src(compiler, &src[0], coordinate_mask); } -@@ -9360,7 +9395,7 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil +@@ -9360,7 +9417,7 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil { WARN("Ignoring 'volatile' attribute.\n"); spirv_compiler_warning(compiler, VKD3D_SHADER_WARNING_SPV_IGNORING_FLAG, @@ -12861,7 +13803,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 } memory_semantic = (instruction->flags & VKD3DARF_SEQ_CST) -@@ -9379,7 +9414,7 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil +@@ -9379,7 +9436,7 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil result_id = vkd3d_spirv_build_op_trv(builder, &builder->function_stream, op, type_id, operands, i); @@ -12870,7 +13812,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 spirv_compiler_emit_store_dst(compiler, dst, result_id); } -@@ -9511,8 +9546,8 @@ static uint32_t spirv_compiler_emit_query_sample_count(struct spirv_compiler *co +@@ -9511,8 +9568,8 @@ static uint32_t spirv_compiler_emit_query_sample_count(struct spirv_compiler *co if (src->reg.type == VKD3DSPR_RASTERIZER) { @@ -12881,7 +13823,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 } else { -@@ -9684,13 +9719,13 @@ static void spirv_compiler_emit_eval_attrib(struct spirv_compiler *compiler, +@@ -9684,13 +9741,13 @@ static void spirv_compiler_emit_eval_attrib(struct spirv_compiler *compiler, src_ids[src_count++] = register_info.id; @@ -12897,7 +13839,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 op = GLSLstd450InterpolateAtSample; src_ids[src_count++] = spirv_compiler_emit_load_src(compiler, &src[1], VKD3DSP_WRITEMASK_0); } -@@ -9772,7 +9807,7 @@ static void spirv_compiler_emit_emit_stream(struct spirv_compiler *compiler, +@@ -9772,7 +9829,7 @@ static void spirv_compiler_emit_emit_stream(struct spirv_compiler *compiler, struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; unsigned int stream_idx; @@ -12906,7 +13848,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 stream_idx = instruction->src[0].reg.idx[0].offset; else stream_idx = 0; -@@ -9793,7 +9828,7 @@ static void spirv_compiler_emit_cut_stream(struct spirv_compiler *compiler, +@@ -9793,7 +9850,7 @@ static void spirv_compiler_emit_cut_stream(struct spirv_compiler *compiler, struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; unsigned int stream_idx; @@ -12915,14 +13857,13 @@ index 984a4f894f6..bc8a7a5b28c 100644 stream_idx = instruction->src[0].reg.idx[0].offset; else stream_idx = 0; -@@ -9807,9 +9842,68 @@ static void spirv_compiler_emit_cut_stream(struct spirv_compiler *compiler, +@@ -9807,9 +9864,68 @@ static void spirv_compiler_emit_cut_stream(struct spirv_compiler *compiler, vkd3d_spirv_build_op_end_primitive(builder); } -static SpvOp map_wave_bool_op(enum vkd3d_shader_opcode handler_idx) +static uint32_t map_quad_read_across_direction(enum vkd3d_shader_opcode opcode) - { -- switch (handler_idx) ++{ + switch (opcode) + { + case VKD3DSIH_QUAD_READ_ACROSS_X: @@ -12981,12 +13922,13 @@ index 984a4f894f6..bc8a7a5b28c 100644 +} + +static SpvOp map_wave_bool_op(enum vkd3d_shader_opcode opcode) -+{ + { +- switch (handler_idx) + switch (opcode) { case VKD3DSIH_WAVE_ACTIVE_ALL_EQUAL: return SpvOpGroupNonUniformAllEqual; -@@ -9833,7 +9927,7 @@ static void spirv_compiler_emit_wave_bool_op(struct spirv_compiler *compiler, +@@ -9833,7 +9949,7 @@ static void spirv_compiler_emit_wave_bool_op(struct spirv_compiler *compiler, vkd3d_spirv_enable_capability(builder, SpvCapabilityGroupNonUniformVote); @@ -12995,7 +13937,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 type_id = vkd3d_spirv_get_op_type_bool(builder); val_id = spirv_compiler_emit_load_src(compiler, src, dst->write_mask); val_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, op, -@@ -9865,9 +9959,9 @@ static void spirv_compiler_emit_wave_active_ballot(struct spirv_compiler *compil +@@ -9865,9 +9981,9 @@ static void spirv_compiler_emit_wave_active_ballot(struct spirv_compiler *compil spirv_compiler_emit_store_dst(compiler, dst, val_id); } @@ -13007,7 +13949,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 { case VKD3DSIH_WAVE_ACTIVE_BIT_AND: return SpvOpGroupNonUniformBitwiseAnd; -@@ -9905,7 +9999,7 @@ static void spirv_compiler_emit_wave_alu_op(struct spirv_compiler *compiler, +@@ -9905,7 +10021,7 @@ static void spirv_compiler_emit_wave_alu_op(struct spirv_compiler *compiler, uint32_t type_id, val_id; SpvOp op; @@ -13016,7 +13958,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 type_id = vkd3d_spirv_get_type_id_for_data_type(builder, dst->reg.data_type, vsir_write_mask_component_count(dst->write_mask)); -@@ -9928,7 +10022,7 @@ static void spirv_compiler_emit_wave_bit_count(struct spirv_compiler *compiler, +@@ -9928,7 +10044,7 @@ static void spirv_compiler_emit_wave_bit_count(struct spirv_compiler *compiler, SpvGroupOperation group_op; uint32_t type_id, val_id; @@ -13025,7 +13967,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 : SpvGroupOperationReduce; val_id = spirv_compiler_emit_group_nonuniform_ballot(compiler, instruction->src); -@@ -10014,7 +10108,7 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, +@@ -10014,7 +10130,7 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, compiler->location = instruction->location; @@ -13034,7 +13976,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 { case VKD3DSIH_DCL_GLOBAL_FLAGS: spirv_compiler_emit_dcl_global_flags(compiler, instruction); -@@ -10337,6 +10431,14 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, +@@ -10337,6 +10453,14 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, case VKD3DSIH_CUT_STREAM: spirv_compiler_emit_cut_stream(compiler, instruction); break; @@ -13049,7 +13991,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 case VKD3DSIH_WAVE_ACTIVE_ALL_EQUAL: case VKD3DSIH_WAVE_ALL_TRUE: case VKD3DSIH_WAVE_ANY_TRUE: -@@ -10371,7 +10473,6 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, +@@ -10371,7 +10495,6 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, case VKD3DSIH_WAVE_READ_LANE_FIRST: spirv_compiler_emit_wave_read_lane_first(compiler, instruction); break; @@ -13057,7 +13999,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 case VKD3DSIH_DCL_HS_MAX_TESSFACTOR: case VKD3DSIH_DCL_INPUT_CONTROL_POINT_COUNT: case VKD3DSIH_DCL_INPUT_SGV: -@@ -10381,7 +10482,6 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, +@@ -10381,7 +10504,6 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, case VKD3DSIH_DCL_OUTPUT_SIV: case VKD3DSIH_DCL_RESOURCE_RAW: case VKD3DSIH_DCL_RESOURCE_STRUCTURED: @@ -13065,7 +14007,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 case VKD3DSIH_DCL_UAV_RAW: case VKD3DSIH_DCL_UAV_STRUCTURED: case VKD3DSIH_DCL_UAV_TYPED: -@@ -10390,9 +10490,9 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, +@@ -10390,9 +10512,9 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, /* nothing to do */ break; default: @@ -13077,7 +14019,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 break; } -@@ -10476,12 +10576,16 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, struct +@@ -10476,12 +10598,16 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, struct struct vkd3d_shader_instruction_array instructions; enum vkd3d_shader_spirv_environment environment; enum vkd3d_result result = VKD3D_OK; @@ -13095,7 +14037,7 @@ index 984a4f894f6..bc8a7a5b28c 100644 if (program->temp_count) spirv_compiler_emit_temps(compiler, program->temp_count); if (program->ssa_count) -@@ -10489,9 +10593,38 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, struct +@@ -10489,9 +10615,38 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, struct spirv_compiler_emit_descriptor_declarations(compiler); @@ -13135,10 +14077,18 @@ index 984a4f894f6..bc8a7a5b28c 100644 memset(&program->instructions, 0, sizeof(program->instructions)); diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c -index b562e815a81..d6d5bbc1c07 100644 +index b562e815a81..84f641cc316 100644 --- a/libs/vkd3d/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c -@@ -780,7 +780,7 @@ static void shader_sm4_read_shader_data(struct vkd3d_shader_instruction *ins, ui +@@ -22,6 +22,7 @@ + */ + + #include "hlsl.h" ++#include "vkd3d_shader_private.h" + + #define SM4_MAX_SRC_COUNT 6 + #define SM4_MAX_DST_COUNT 2 +@@ -780,7 +781,7 @@ static void shader_sm4_read_shader_data(struct vkd3d_shader_instruction *ins, ui if (type != VKD3D_SM4_SHADER_DATA_IMMEDIATE_CONSTANT_BUFFER) { FIXME("Ignoring shader data type %#x.\n", type); @@ -13147,7 +14097,7 @@ index b562e815a81..d6d5bbc1c07 100644 return; } -@@ -789,7 +789,7 @@ static void shader_sm4_read_shader_data(struct vkd3d_shader_instruction *ins, ui +@@ -789,7 +790,7 @@ static void shader_sm4_read_shader_data(struct vkd3d_shader_instruction *ins, ui if (icb_size % 4) { FIXME("Unexpected immediate constant buffer size %u.\n", icb_size); @@ -13156,7 +14106,7 @@ index b562e815a81..d6d5bbc1c07 100644 return; } -@@ -797,7 +797,7 @@ static void shader_sm4_read_shader_data(struct vkd3d_shader_instruction *ins, ui +@@ -797,7 +798,7 @@ static void shader_sm4_read_shader_data(struct vkd3d_shader_instruction *ins, ui { ERR("Failed to allocate immediate constant buffer, size %u.\n", icb_size); vkd3d_shader_parser_error(&priv->p, VKD3D_SHADER_ERROR_TPF_OUT_OF_MEMORY, "Out of memory."); @@ -13165,7 +14115,7 @@ index b562e815a81..d6d5bbc1c07 100644 return; } icb->register_idx = 0; -@@ -1716,7 +1716,7 @@ static enum vkd3d_sm4_swizzle_type vkd3d_sm4_get_default_swizzle_type( +@@ -1716,7 +1717,7 @@ static enum vkd3d_sm4_swizzle_type vkd3d_sm4_get_default_swizzle_type( const struct vkd3d_sm4_register_type_info *register_type_info = get_info_from_vkd3d_register_type(lookup, vkd3d_type); @@ -13174,7 +14124,7 @@ index b562e815a81..d6d5bbc1c07 100644 return register_type_info->default_src_swizzle_type; } -@@ -2395,16 +2395,16 @@ static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, str +@@ -2395,16 +2396,16 @@ static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, str if (!(opcode_info = get_info_from_sm4_opcode(&sm4->lookup, opcode))) { FIXME("Unrecognized opcode %#x, opcode_token 0x%08x.\n", opcode, opcode_token); @@ -13196,7 +14146,7 @@ index b562e815a81..d6d5bbc1c07 100644 ins->flags = 0; ins->coissue = false; ins->raw = false; -@@ -2417,7 +2417,7 @@ static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, str +@@ -2417,7 +2418,7 @@ static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, str { ERR("Failed to allocate src parameters.\n"); vkd3d_shader_parser_error(&sm4->p, VKD3D_SHADER_ERROR_TPF_OUT_OF_MEMORY, "Out of memory."); @@ -13205,7 +14155,7 @@ index b562e815a81..d6d5bbc1c07 100644 return; } ins->resource_type = VKD3D_SHADER_RESOURCE_NONE; -@@ -2459,7 +2459,7 @@ static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, str +@@ -2459,7 +2460,7 @@ static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, str { ERR("Failed to allocate dst parameters.\n"); vkd3d_shader_parser_error(&sm4->p, VKD3D_SHADER_ERROR_TPF_OUT_OF_MEMORY, "Out of memory."); @@ -13214,7 +14164,7 @@ index b562e815a81..d6d5bbc1c07 100644 return; } for (i = 0; i < ins->dst_count; ++i) -@@ -2467,7 +2467,7 @@ static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, str +@@ -2467,7 +2468,7 @@ static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, str if (!(shader_sm4_read_dst_param(sm4, &p, *ptr, map_data_type(opcode_info->dst_info[i]), &dst_params[i]))) { @@ -13223,7 +14173,7 @@ index b562e815a81..d6d5bbc1c07 100644 return; } dst_params[i].modifiers |= instruction_dst_modifier; -@@ -2478,7 +2478,7 @@ static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, str +@@ -2478,7 +2479,7 @@ static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, str if (!(shader_sm4_read_src_param(sm4, &p, *ptr, map_data_type(opcode_info->src_info[i]), &src_params[i]))) { @@ -13232,7 +14182,7 @@ index b562e815a81..d6d5bbc1c07 100644 return; } } -@@ -2488,12 +2488,12 @@ static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, str +@@ -2488,12 +2489,12 @@ static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, str fail: *ptr = sm4->end; @@ -13247,7 +14197,7 @@ index b562e815a81..d6d5bbc1c07 100644 struct vkd3d_shader_message_context *message_context) { struct vkd3d_shader_version version; -@@ -2552,9 +2552,9 @@ static bool shader_sm4_init(struct vkd3d_shader_sm4_parser *sm4, struct vsir_pro +@@ -2552,9 +2553,9 @@ static bool shader_sm4_init(struct vkd3d_shader_sm4_parser *sm4, struct vsir_pro version.minor = VKD3D_SM4_VERSION_MINOR(version_token); /* Estimate instruction count to avoid reallocation in most shaders. */ @@ -13259,7 +14209,7 @@ index b562e815a81..d6d5bbc1c07 100644 sm4->ptr = sm4->start; init_sm4_lookup_tables(&sm4->lookup); -@@ -2651,7 +2651,7 @@ int tpf_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t con +@@ -2651,7 +2652,7 @@ int tpf_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t con } if (!shader_sm4_init(&sm4, program, dxbc_desc.byte_code, dxbc_desc.byte_code_size, @@ -13268,7 +14218,7 @@ index b562e815a81..d6d5bbc1c07 100644 { WARN("Failed to initialise shader parser.\n"); free_dxbc_shader_desc(&dxbc_desc); -@@ -2693,7 +2693,7 @@ int tpf_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t con +@@ -2693,7 +2694,7 @@ int tpf_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t con ins = &instructions->elements[instructions->count]; shader_sm4_read_instruction(&sm4, ins); @@ -13277,7 +14227,7 @@ index b562e815a81..d6d5bbc1c07 100644 { WARN("Encountered unrecognized or invalid instruction.\n"); vsir_program_cleanup(program); -@@ -2762,6 +2762,7 @@ bool hlsl_sm4_register_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_sem +@@ -2762,6 +2763,7 @@ bool hlsl_sm4_register_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_sem {"depth", true, VKD3D_SHADER_TYPE_PIXEL, VKD3DSPR_DEPTHOUT, false}, {"sv_depth", true, VKD3D_SHADER_TYPE_PIXEL, VKD3DSPR_DEPTHOUT, false}, {"sv_target", true, VKD3D_SHADER_TYPE_PIXEL, VKD3DSPR_OUTPUT, true}, @@ -13285,7 +14235,7 @@ index b562e815a81..d6d5bbc1c07 100644 }; for (i = 0; i < ARRAY_SIZE(register_table); ++i) -@@ -2817,6 +2818,7 @@ bool hlsl_sm4_usage_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_semant +@@ -2817,6 +2819,7 @@ bool hlsl_sm4_usage_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_semant {"depth", true, VKD3D_SHADER_TYPE_PIXEL, D3D_NAME_DEPTH}, {"sv_target", true, VKD3D_SHADER_TYPE_PIXEL, D3D_NAME_TARGET}, {"sv_depth", true, VKD3D_SHADER_TYPE_PIXEL, D3D_NAME_DEPTH}, @@ -13293,7 +14243,7 @@ index b562e815a81..d6d5bbc1c07 100644 {"sv_position", false, VKD3D_SHADER_TYPE_VERTEX, D3D_NAME_UNDEFINED}, {"sv_vertexid", false, VKD3D_SHADER_TYPE_VERTEX, D3D_NAME_VERTEX_ID}, -@@ -2885,7 +2887,7 @@ static void write_sm4_signature(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc, +@@ -2885,7 +2888,7 @@ static void write_sm4_signature(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc, continue; ret = hlsl_sm4_usage_from_semantic(ctx, &var->semantic, output, &usage); @@ -13302,7 +14252,7 @@ index b562e815a81..d6d5bbc1c07 100644 if (usage == ~0u) continue; usage_idx = var->semantic.index; -@@ -2896,7 +2898,7 @@ static void write_sm4_signature(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc, +@@ -2896,7 +2899,7 @@ static void write_sm4_signature(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc, } else { @@ -13311,7 +14261,7 @@ index b562e815a81..d6d5bbc1c07 100644 reg_idx = var->regs[HLSL_REGSET_NUMERIC].id; } -@@ -2973,7 +2975,7 @@ static D3D_SHADER_VARIABLE_CLASS sm4_class(const struct hlsl_type *type) +@@ -2973,7 +2976,7 @@ static D3D_SHADER_VARIABLE_CLASS sm4_class(const struct hlsl_type *type) switch (type->class) { case HLSL_CLASS_MATRIX: @@ -13320,7 +14270,7 @@ index b562e815a81..d6d5bbc1c07 100644 if (type->modifiers & HLSL_MODIFIER_COLUMN_MAJOR) return D3D_SVC_MATRIX_COLUMNS; else -@@ -2984,11 +2986,13 @@ static D3D_SHADER_VARIABLE_CLASS sm4_class(const struct hlsl_type *type) +@@ -2984,11 +2987,13 @@ static D3D_SHADER_VARIABLE_CLASS sm4_class(const struct hlsl_type *type) return D3D_SVC_VECTOR; case HLSL_CLASS_ARRAY: @@ -13334,7 +14284,7 @@ index b562e815a81..d6d5bbc1c07 100644 case HLSL_CLASS_RENDER_TARGET_VIEW: case HLSL_CLASS_SAMPLER: case HLSL_CLASS_STRING: -@@ -2997,6 +3001,11 @@ static D3D_SHADER_VARIABLE_CLASS sm4_class(const struct hlsl_type *type) +@@ -2997,6 +3002,13 @@ static D3D_SHADER_VARIABLE_CLASS sm4_class(const struct hlsl_type *type) case HLSL_CLASS_UAV: case HLSL_CLASS_VERTEX_SHADER: case HLSL_CLASS_VOID: @@ -13343,10 +14293,12 @@ index b562e815a81..d6d5bbc1c07 100644 + case HLSL_CLASS_DOMAIN_SHADER: + case HLSL_CLASS_HULL_SHADER: + case HLSL_CLASS_GEOMETRY_SHADER: ++ case HLSL_CLASS_BLEND_STATE: ++ case HLSL_CLASS_NULL: break; } vkd3d_unreachable(); -@@ -3077,7 +3086,7 @@ static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b +@@ -3077,7 +3089,7 @@ static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b } else { @@ -13355,23 +14307,60 @@ index b562e815a81..d6d5bbc1c07 100644 type->bytecode_offset = put_u32(buffer, vkd3d_make_u32(sm4_class(array_type), sm4_base_type(array_type))); put_u32(buffer, vkd3d_make_u32(array_type->dimy, array_type->dimx)); put_u32(buffer, vkd3d_make_u32(array_size, 0)); -@@ -3178,13 +3187,14 @@ struct extern_resource +@@ -3098,8 +3110,6 @@ static D3D_SHADER_INPUT_TYPE sm4_resource_type(const struct hlsl_type *type) + { + switch (type->class) + { +- case HLSL_CLASS_ARRAY: +- return sm4_resource_type(type->e.array.type); + case HLSL_CLASS_SAMPLER: + return D3D_SIT_SAMPLER; + case HLSL_CLASS_TEXTURE: +@@ -3115,9 +3125,6 @@ static D3D_SHADER_INPUT_TYPE sm4_resource_type(const struct hlsl_type *type) + + static D3D_RESOURCE_RETURN_TYPE sm4_resource_format(const struct hlsl_type *type) + { +- if (type->class == HLSL_CLASS_ARRAY) +- return sm4_resource_format(type->e.array.type); +- + switch (type->e.resource.format->e.numeric.type) + { + case HLSL_TYPE_DOUBLE: +@@ -3142,9 +3149,6 @@ static D3D_RESOURCE_RETURN_TYPE sm4_resource_format(const struct hlsl_type *type + + static D3D_SRV_DIMENSION sm4_rdef_resource_dimension(const struct hlsl_type *type) + { +- if (type->class == HLSL_CLASS_ARRAY) +- return sm4_rdef_resource_dimension(type->e.array.type); +- + switch (type->sampler_dim) + { + case HLSL_SAMPLER_DIM_1D: +@@ -3178,13 +3182,21 @@ struct extern_resource /* var is only not NULL if this resource is a whole variable, so it may be responsible for more * than one component. */ const struct hlsl_ir_var *var; + const struct hlsl_buffer *buffer; char *name; - struct hlsl_type *data_type; +- struct hlsl_type *data_type; bool is_user_packed; ++ /* The data type of a single component of the resource. ++ * This might be different from the data type of the resource itself in 4.0 ++ * profiles, where an array (or multi-dimensional array) is handled as a ++ * single resource, unlike in 5.0. */ ++ struct hlsl_type *component_type; ++ enum hlsl_regset regset; - unsigned int id, bind_count; + unsigned int id, space, index, bind_count; ++ ++ struct vkd3d_shader_location loc; }; static int sm4_compare_extern_resources(const void *a, const void *b) -@@ -3196,7 +3206,10 @@ static int sm4_compare_extern_resources(const void *a, const void *b) +@@ -3196,7 +3208,10 @@ static int sm4_compare_extern_resources(const void *a, const void *b) if ((r = vkd3d_u32_compare(aa->regset, bb->regset))) return r; @@ -13383,7 +14372,7 @@ index b562e815a81..d6d5bbc1c07 100644 } static void sm4_free_extern_resources(struct extern_resource *extern_resources, unsigned int count) -@@ -3220,6 +3233,7 @@ static struct extern_resource *sm4_get_extern_resources(struct hlsl_ctx *ctx, un +@@ -3220,6 +3235,7 @@ static struct extern_resource *sm4_get_extern_resources(struct hlsl_ctx *ctx, un bool separate_components = ctx->profile->major_version == 5 && ctx->profile->minor_version == 0; struct extern_resource *extern_resources = NULL; const struct hlsl_ir_var *var; @@ -13391,46 +14380,53 @@ index b562e815a81..d6d5bbc1c07 100644 enum hlsl_regset regset; size_t capacity = 0; char *name; -@@ -3272,13 +3286,16 @@ static struct extern_resource *sm4_get_extern_resources(struct hlsl_ctx *ctx, un +@@ -3272,14 +3288,19 @@ static struct extern_resource *sm4_get_extern_resources(struct hlsl_ctx *ctx, un hlsl_release_string_buffer(ctx, name_buffer); extern_resources[*count].var = NULL; + extern_resources[*count].buffer = NULL; extern_resources[*count].name = name; - extern_resources[*count].data_type = component_type; +- extern_resources[*count].data_type = component_type; extern_resources[*count].is_user_packed = !!var->reg_reservation.reg_type; ++ extern_resources[*count].component_type = component_type; ++ extern_resources[*count].regset = regset; - extern_resources[*count].id = var->regs[regset].id + regset_offset; + extern_resources[*count].id = var->regs[regset].id; + extern_resources[*count].space = var->regs[regset].space; + extern_resources[*count].index = var->regs[regset].index + regset_offset; extern_resources[*count].bind_count = 1; ++ extern_resources[*count].loc = var->loc; ++*count; -@@ -3313,13 +3330,19 @@ static struct extern_resource *sm4_get_extern_resources(struct hlsl_ctx *ctx, un + } +@@ -3313,28 +3334,75 @@ static struct extern_resource *sm4_get_extern_resources(struct hlsl_ctx *ctx, un } extern_resources[*count].var = var; + extern_resources[*count].buffer = NULL; extern_resources[*count].name = name; - extern_resources[*count].data_type = var->data_type; +- extern_resources[*count].data_type = var->data_type; - extern_resources[*count].is_user_packed = !!var->reg_reservation.reg_type; + /* For some reason 5.1 resources aren't marked as + * user-packed, but cbuffers still are. */ + extern_resources[*count].is_user_packed = hlsl_version_lt(ctx, 5, 1) + && !!var->reg_reservation.reg_type; ++ ++ extern_resources[*count].component_type = hlsl_type_get_component_type(ctx, var->data_type, 0); extern_resources[*count].regset = r; extern_resources[*count].id = var->regs[r].id; + extern_resources[*count].space = var->regs[r].space; + extern_resources[*count].index = var->regs[r].index; extern_resources[*count].bind_count = var->bind_count[r]; ++ extern_resources[*count].loc = var->loc; ++*count; -@@ -3327,14 +3350,51 @@ static struct extern_resource *sm4_get_extern_resources(struct hlsl_ctx *ctx, un + } } } @@ -13458,14 +14454,16 @@ index b562e815a81..d6d5bbc1c07 100644 + extern_resources[*count].buffer = buffer; + + extern_resources[*count].name = name; -+ extern_resources[*count].data_type = NULL; + extern_resources[*count].is_user_packed = !!buffer->reservation.reg_type; + ++ extern_resources[*count].component_type = NULL; ++ + extern_resources[*count].regset = HLSL_REGSET_NUMERIC; + extern_resources[*count].id = buffer->reg.id; + extern_resources[*count].space = buffer->reg.space; + extern_resources[*count].index = buffer->reg.index; + extern_resources[*count].bind_count = 1; ++ extern_resources[*count].loc = buffer->loc; + + ++*count; + } @@ -13483,7 +14481,7 @@ index b562e815a81..d6d5bbc1c07 100644 size_t cbuffer_position, resource_position, creator_position; const struct hlsl_profile_info *profile = ctx->profile; struct vkd3d_bytecode_buffer buffer = {0}; -@@ -3354,19 +3414,15 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) +@@ -3354,19 +3422,15 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) extern_resources = sm4_get_extern_resources(ctx, &extern_resources_count); @@ -13504,7 +14502,7 @@ index b562e815a81..d6d5bbc1c07 100644 resource_position = put_u32(&buffer, 0); put_u32(&buffer, vkd3d_make_u32(vkd3d_make_u16(profile->minor_version, profile->major_version), target_types[profile->type])); -@@ -3378,7 +3434,7 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) +@@ -3378,7 +3442,7 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) put_u32(&buffer, hlsl_version_ge(ctx, 5, 1) ? TAG_RD11_REVERSE : TAG_RD11); put_u32(&buffer, 15 * sizeof(uint32_t)); /* size of RDEF header including this header */ put_u32(&buffer, 6 * sizeof(uint32_t)); /* size of buffer desc */ @@ -13513,7 +14511,7 @@ index b562e815a81..d6d5bbc1c07 100644 put_u32(&buffer, 10 * sizeof(uint32_t)); /* size of variable desc */ put_u32(&buffer, 9 * sizeof(uint32_t)); /* size of type desc */ put_u32(&buffer, 3 * sizeof(uint32_t)); /* size of member desc */ -@@ -3395,21 +3451,15 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) +@@ -3395,55 +3459,38 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) const struct extern_resource *resource = &extern_resources[i]; uint32_t flags = 0; @@ -13534,12 +14532,16 @@ index b562e815a81..d6d5bbc1c07 100644 + if (resource->buffer) + put_u32(&buffer, resource->buffer->type == HLSL_BUFFER_CONSTANT ? D3D_SIT_CBUFFER : D3D_SIT_TBUFFER); else -+ put_u32(&buffer, sm4_resource_type(resource->data_type)); ++ put_u32(&buffer, sm4_resource_type(resource->component_type)); + if (resource->regset == HLSL_REGSET_TEXTURES || resource->regset == HLSL_REGSET_UAVS) { - unsigned int dimx = hlsl_type_get_component_type(ctx, resource->data_type, 0)->e.resource.format->dimx; +- unsigned int dimx = hlsl_type_get_component_type(ctx, resource->data_type, 0)->e.resource.format->dimx; ++ unsigned int dimx = resource->component_type->e.resource.format->dimx; -@@ -3418,32 +3468,21 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) +- put_u32(&buffer, sm4_resource_format(resource->data_type)); +- put_u32(&buffer, sm4_rdef_resource_dimension(resource->data_type)); ++ put_u32(&buffer, sm4_resource_format(resource->component_type)); ++ put_u32(&buffer, sm4_rdef_resource_dimension(resource->component_type)); put_u32(&buffer, ~0u); /* FIXME: multisample count */ flags |= (dimx - 1) << VKD3D_SM4_SIF_TEXTURE_COMPONENTS_SHIFT; } @@ -13583,7 +14585,7 @@ index b562e815a81..d6d5bbc1c07 100644 } for (i = 0; i < extern_resources_count; ++i) -@@ -3451,16 +3490,7 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) +@@ -3451,16 +3498,7 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) const struct extern_resource *resource = &extern_resources[i]; string_offset = put_string(&buffer, resource->name); @@ -13601,7 +14603,7 @@ index b562e815a81..d6d5bbc1c07 100644 } /* Buffers. */ -@@ -3522,7 +3552,7 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) +@@ -3522,7 +3560,7 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) put_u32(&buffer, var->data_type->reg_size[HLSL_REGSET_NUMERIC] * sizeof(float)); put_u32(&buffer, flags); put_u32(&buffer, 0); /* type */ @@ -13610,7 +14612,7 @@ index b562e815a81..d6d5bbc1c07 100644 if (profile->major_version >= 5) { -@@ -3546,6 +3576,34 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) +@@ -3546,6 +3584,41 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) set_u32(&buffer, var_offset, string_offset); write_sm4_type(ctx, &buffer, var->data_type); set_u32(&buffer, var_offset + 4 * sizeof(uint32_t), var->data_type->bytecode_offset); @@ -13631,6 +14633,13 @@ index b562e815a81..d6d5bbc1c07 100644 + unsigned int comp_offset; + enum hlsl_regset regset; + ++ if (comp_type->class == HLSL_CLASS_STRING) ++ { ++ hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, ++ "Cannot write string default value."); ++ continue; ++ } ++ + comp_offset = hlsl_type_get_component_offset(ctx, var->data_type, k, ®set); + if (regset == HLSL_REGSET_NUMERIC) + { @@ -13638,14 +14647,14 @@ index b562e815a81..d6d5bbc1c07 100644 + hlsl_fixme(ctx, &var->loc, "Write double default values."); + + set_u32(&buffer, default_value_offset + comp_offset * sizeof(uint32_t), -+ var->default_values[k].value.u); ++ var->default_values[k].number.u); + } + } + } ++j; } } -@@ -3611,9 +3669,9 @@ static uint32_t sm4_encode_instruction_modifier(const struct sm4_instruction_mod +@@ -3611,9 +3684,9 @@ static uint32_t sm4_encode_instruction_modifier(const struct sm4_instruction_mod switch (imod->type) { case VKD3D_SM4_MODIFIER_AOFFIMMI: @@ -13658,7 +14667,7 @@ index b562e815a81..d6d5bbc1c07 100644 word |= ((uint32_t)imod->u.aoffimmi.u & 0xf) << VKD3D_SM4_AOFFIMMI_U_SHIFT; word |= ((uint32_t)imod->u.aoffimmi.v & 0xf) << VKD3D_SM4_AOFFIMMI_V_SHIFT; word |= ((uint32_t)imod->u.aoffimmi.w & 0xf) << VKD3D_SM4_AOFFIMMI_W_SHIFT; -@@ -3652,7 +3710,7 @@ struct sm4_instruction +@@ -3652,7 +3725,7 @@ struct sm4_instruction static void sm4_register_from_node(struct vkd3d_shader_register *reg, uint32_t *writemask, const struct hlsl_ir_node *instr) { @@ -13667,7 +14676,7 @@ index b562e815a81..d6d5bbc1c07 100644 reg->type = VKD3DSPR_TEMP; reg->dimension = VSIR_DIMENSION_VEC4; reg->idx[0].offset = instr->reg.id; -@@ -3671,7 +3729,7 @@ static void sm4_numeric_register_from_deref(struct hlsl_ctx *ctx, struct vkd3d_s +@@ -3671,7 +3744,7 @@ static void sm4_numeric_register_from_deref(struct hlsl_ctx *ctx, struct vkd3d_s reg->idx[0].offset = var->regs[HLSL_REGSET_NUMERIC].id; reg->dimension = VSIR_DIMENSION_VEC4; @@ -13676,7 +14685,7 @@ index b562e815a81..d6d5bbc1c07 100644 if (!var->indexable) { -@@ -3690,13 +3748,13 @@ static void sm4_numeric_register_from_deref(struct hlsl_ctx *ctx, struct vkd3d_s +@@ -3690,13 +3763,13 @@ static void sm4_numeric_register_from_deref(struct hlsl_ctx *ctx, struct vkd3d_s struct vkd3d_shader_src_param *idx_src; unsigned int idx_writemask; @@ -13692,7 +14701,7 @@ index b562e815a81..d6d5bbc1c07 100644 idx_src->swizzle = swizzle_from_sm4(hlsl_swizzle_from_writemask(idx_writemask)); } } -@@ -3720,42 +3778,79 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct vkd3d_shader_re +@@ -3720,42 +3793,79 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct vkd3d_shader_re { reg->type = VKD3DSPR_RESOURCE; reg->dimension = VSIR_DIMENSION_VEC4; @@ -13788,7 +14797,7 @@ index b562e815a81..d6d5bbc1c07 100644 *writemask = ((1u << data_type->dimx) - 1) << (offset & 3); } } -@@ -3780,7 +3875,7 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct vkd3d_shader_re +@@ -3780,7 +3890,7 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct vkd3d_shader_re { struct hlsl_reg hlsl_reg = hlsl_reg_from_deref(ctx, deref); @@ -13797,7 +14806,7 @@ index b562e815a81..d6d5bbc1c07 100644 reg->type = VKD3DSPR_INPUT; reg->dimension = VSIR_DIMENSION_VEC4; reg->idx[0].offset = hlsl_reg.id; -@@ -3812,7 +3907,7 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct vkd3d_shader_re +@@ -3812,7 +3922,7 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct vkd3d_shader_re { struct hlsl_reg hlsl_reg = hlsl_reg_from_deref(ctx, deref); @@ -13806,7 +14815,7 @@ index b562e815a81..d6d5bbc1c07 100644 reg->type = VKD3DSPR_OUTPUT; reg->dimension = VSIR_DIMENSION_VEC4; reg->idx[0].offset = hlsl_reg.id; -@@ -3948,7 +4043,7 @@ static uint32_t sm4_encode_register(const struct tpf_writer *tpf, const struct v +@@ -3948,7 +4058,7 @@ static uint32_t sm4_encode_register(const struct tpf_writer *tpf, const struct v switch (sm4_swizzle_type) { case VKD3D_SM4_SWIZZLE_NONE: @@ -13815,7 +14824,7 @@ index b562e815a81..d6d5bbc1c07 100644 token |= (sm4_swizzle << VKD3D_SM4_WRITEMASK_SHIFT) & VKD3D_SM4_WRITEMASK_MASK; break; -@@ -3980,16 +4075,16 @@ static void sm4_write_register_index(const struct tpf_writer *tpf, const struct +@@ -3980,16 +4090,16 @@ static void sm4_write_register_index(const struct tpf_writer *tpf, const struct const struct vkd3d_shader_src_param *idx_src = reg->idx[j].rel_addr; uint32_t idx_src_token; @@ -13836,7 +14845,7 @@ index b562e815a81..d6d5bbc1c07 100644 } } else -@@ -4139,18 +4234,36 @@ static bool encode_texel_offset_as_aoffimmi(struct sm4_instruction *instr, +@@ -4139,47 +4249,76 @@ static bool encode_texel_offset_as_aoffimmi(struct sm4_instruction *instr, static void write_sm4_dcl_constant_buffer(const struct tpf_writer *tpf, const struct hlsl_buffer *cbuffer) { @@ -13877,7 +14886,12 @@ index b562e815a81..d6d5bbc1c07 100644 write_sm4_instruction(tpf, &instr); } -@@ -4163,7 +4276,6 @@ static void write_sm4_dcl_samplers(const struct tpf_writer *tpf, const struct ex + static void write_sm4_dcl_samplers(const struct tpf_writer *tpf, const struct extern_resource *resource) + { +- struct hlsl_type *component_type; + unsigned int i; + struct sm4_instruction instr = + { .opcode = VKD3D_SM4_OP_DCL_SAMPLER, .dsts[0].reg.type = VKD3DSPR_SAMPLER, @@ -13885,13 +14899,15 @@ index b562e815a81..d6d5bbc1c07 100644 .dst_count = 1, }; -@@ -4172,14 +4284,29 @@ static void write_sm4_dcl_samplers(const struct tpf_writer *tpf, const struct ex - if (component_type->sampler_dim == HLSL_SAMPLER_DIM_COMPARISON) +- component_type = hlsl_type_get_component_type(tpf->ctx, resource->data_type, 0); ++ VKD3D_ASSERT(resource->regset == HLSL_REGSET_SAMPLERS); + +- if (component_type->sampler_dim == HLSL_SAMPLER_DIM_COMPARISON) ++ if (resource->component_type->sampler_dim == HLSL_SAMPLER_DIM_COMPARISON) instr.extra_bits |= VKD3D_SM4_SAMPLER_COMPARISON << VKD3D_SM4_SAMPLER_MODE_SHIFT; - assert(resource->regset == HLSL_REGSET_SAMPLERS); -+ VKD3D_ASSERT(resource->regset == HLSL_REGSET_SAMPLERS); - +- for (i = 0; i < resource->bind_count; ++i) { if (resource->var && !resource->var->objects_usage[HLSL_REGSET_SAMPLERS][i].used) @@ -13917,19 +14933,35 @@ index b562e815a81..d6d5bbc1c07 100644 write_sm4_instruction(tpf, &instr); } } -@@ -4192,7 +4319,7 @@ static void write_sm4_dcl_textures(const struct tpf_writer *tpf, const struct ex +@@ -4190,11 +4329,12 @@ static void write_sm4_dcl_textures(const struct tpf_writer *tpf, const struct ex + enum hlsl_regset regset = uav ? HLSL_REGSET_UAVS : HLSL_REGSET_TEXTURES; + struct hlsl_type *component_type; struct sm4_instruction instr; ++ bool multisampled; unsigned int i; - assert(resource->regset == regset); + VKD3D_ASSERT(resource->regset == regset); - component_type = hlsl_type_get_component_type(tpf->ctx, resource->data_type, 0); +- component_type = hlsl_type_get_component_type(tpf->ctx, resource->data_type, 0); ++ component_type = resource->component_type; -@@ -4212,6 +4339,23 @@ static void write_sm4_dcl_textures(const struct tpf_writer *tpf, const struct ex + for (i = 0; i < resource->bind_count; ++i) + { +@@ -4212,20 +4352,47 @@ static void write_sm4_dcl_textures(const struct tpf_writer *tpf, const struct ex .idx_count = 1, }; ++ multisampled = component_type->sampler_dim == HLSL_SAMPLER_DIM_2DMS ++ || component_type->sampler_dim == HLSL_SAMPLER_DIM_2DMSARRAY; ++ ++ if (hlsl_version_lt(tpf->ctx, 4, 1) && multisampled && !component_type->sample_count) ++ { ++ hlsl_error(tpf->ctx, &resource->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, ++ "Multisampled texture object declaration needs sample count for profile %s.", ++ tpf->ctx->profile->name); ++ } ++ + if (hlsl_version_ge(tpf->ctx, 5, 1)) + { + VKD3D_ASSERT(!i); @@ -13949,8 +14981,44 @@ index b562e815a81..d6d5bbc1c07 100644 + if (uav) { - switch (resource->data_type->sampler_dim) -@@ -4449,7 +4593,7 @@ static void write_sm4_unary_op_with_two_destinations(const struct tpf_writer *tp +- switch (resource->data_type->sampler_dim) ++ switch (component_type->sampler_dim) + { +- case HLSL_SAMPLER_DIM_STRUCTURED_BUFFER: +- instr.opcode = VKD3D_SM5_OP_DCL_UAV_STRUCTURED; +- instr.byte_stride = resource->data_type->e.resource.format->reg_size[HLSL_REGSET_NUMERIC] * 4; +- break; +- default: +- instr.opcode = VKD3D_SM5_OP_DCL_UAV_TYPED; +- break; ++ case HLSL_SAMPLER_DIM_STRUCTURED_BUFFER: ++ instr.opcode = VKD3D_SM5_OP_DCL_UAV_STRUCTURED; ++ instr.byte_stride = component_type->e.resource.format->reg_size[HLSL_REGSET_NUMERIC] * 4; ++ break; ++ default: ++ instr.opcode = VKD3D_SM5_OP_DCL_UAV_TYPED; ++ break; + } + +- if (resource->data_type->e.resource.rasteriser_ordered) ++ if (component_type->e.resource.rasteriser_ordered) + instr.opcode |= VKD3DSUF_RASTERISER_ORDERED_VIEW << VKD3D_SM5_UAV_FLAGS_SHIFT; + } + else +@@ -4234,11 +4401,8 @@ static void write_sm4_dcl_textures(const struct tpf_writer *tpf, const struct ex + } + instr.extra_bits |= (sm4_resource_dimension(component_type) << VKD3D_SM4_RESOURCE_TYPE_SHIFT); + +- if (component_type->sampler_dim == HLSL_SAMPLER_DIM_2DMS +- || component_type->sampler_dim == HLSL_SAMPLER_DIM_2DMSARRAY) +- { ++ if (multisampled) + instr.extra_bits |= component_type->sample_count << VKD3D_SM4_RESOURCE_SAMPLE_COUNT_SHIFT; +- } + + write_sm4_instruction(tpf, &instr); + } +@@ -4449,7 +4613,7 @@ static void write_sm4_unary_op_with_two_destinations(const struct tpf_writer *tp memset(&instr, 0, sizeof(instr)); instr.opcode = opcode; @@ -13959,7 +15027,7 @@ index b562e815a81..d6d5bbc1c07 100644 sm4_dst_from_node(&instr.dsts[dst_idx], dst); instr.dsts[1 - dst_idx].reg.type = VKD3DSPR_NULL; instr.dsts[1 - dst_idx].reg.dimension = VSIR_DIMENSION_NONE; -@@ -4508,7 +4652,7 @@ static void write_sm4_binary_op_with_two_destinations(const struct tpf_writer *t +@@ -4508,7 +4672,7 @@ static void write_sm4_binary_op_with_two_destinations(const struct tpf_writer *t memset(&instr, 0, sizeof(instr)); instr.opcode = opcode; @@ -13968,7 +15036,7 @@ index b562e815a81..d6d5bbc1c07 100644 sm4_dst_from_node(&instr.dsts[dst_idx], dst); instr.dsts[1 - dst_idx].reg.type = VKD3DSPR_NULL; instr.dsts[1 - dst_idx].reg.dimension = VSIR_DIMENSION_NONE; -@@ -4706,7 +4850,7 @@ static void write_sm4_sampleinfo(const struct tpf_writer *tpf, const struct hlsl +@@ -4706,7 +4870,7 @@ static void write_sm4_sampleinfo(const struct tpf_writer *tpf, const struct hlsl const struct hlsl_ir_node *dst = &load->node; struct sm4_instruction instr; @@ -13977,7 +15045,7 @@ index b562e815a81..d6d5bbc1c07 100644 memset(&instr, 0, sizeof(instr)); instr.opcode = VKD3D_SM4_OP_SAMPLE_INFO; -@@ -4735,7 +4879,7 @@ static void write_sm4_resinfo(const struct tpf_writer *tpf, const struct hlsl_ir +@@ -4735,7 +4899,7 @@ static void write_sm4_resinfo(const struct tpf_writer *tpf, const struct hlsl_ir return; } @@ -13986,7 +15054,7 @@ index b562e815a81..d6d5bbc1c07 100644 memset(&instr, 0, sizeof(instr)); instr.opcode = VKD3D_SM4_OP_RESINFO; -@@ -4789,7 +4933,7 @@ static void write_sm4_cast(const struct tpf_writer *tpf, const struct hlsl_ir_ex +@@ -4789,7 +4953,7 @@ static void write_sm4_cast(const struct tpf_writer *tpf, const struct hlsl_ir_ex const struct hlsl_type *src_type = arg1->data_type; /* Narrowing casts were already lowered. */ @@ -13995,7 +15063,7 @@ index b562e815a81..d6d5bbc1c07 100644 switch (dst_type->e.numeric.type) { -@@ -4904,6 +5048,25 @@ static void write_sm4_store_uav_typed(const struct tpf_writer *tpf, const struct +@@ -4904,6 +5068,25 @@ static void write_sm4_store_uav_typed(const struct tpf_writer *tpf, const struct write_sm4_instruction(tpf, &instr); } @@ -14021,7 +15089,7 @@ index b562e815a81..d6d5bbc1c07 100644 static void write_sm4_expr(const struct tpf_writer *tpf, const struct hlsl_ir_expr *expr) { const struct hlsl_ir_node *arg1 = expr->operands[0].node; -@@ -4912,13 +5075,21 @@ static void write_sm4_expr(const struct tpf_writer *tpf, const struct hlsl_ir_ex +@@ -4912,13 +5095,21 @@ static void write_sm4_expr(const struct tpf_writer *tpf, const struct hlsl_ir_ex const struct hlsl_type *dst_type = expr->node.data_type; struct vkd3d_string_buffer *dst_type_string; @@ -14044,7 +15112,7 @@ index b562e815a81..d6d5bbc1c07 100644 case HLSL_OP1_ABS: switch (dst_type->e.numeric.type) { -@@ -4932,7 +5103,7 @@ static void write_sm4_expr(const struct tpf_writer *tpf, const struct hlsl_ir_ex +@@ -4932,7 +5123,7 @@ static void write_sm4_expr(const struct tpf_writer *tpf, const struct hlsl_ir_ex break; case HLSL_OP1_BIT_NOT: @@ -14053,7 +15121,7 @@ index b562e815a81..d6d5bbc1c07 100644 write_sm4_unary_op(tpf, VKD3D_SM4_OP_NOT, &expr->node, arg1, 0); break; -@@ -4941,67 +5112,73 @@ static void write_sm4_expr(const struct tpf_writer *tpf, const struct hlsl_ir_ex +@@ -4941,67 +5132,73 @@ static void write_sm4_expr(const struct tpf_writer *tpf, const struct hlsl_ir_ex break; case HLSL_OP1_CEIL: @@ -14140,7 +15208,7 @@ index b562e815a81..d6d5bbc1c07 100644 write_sm4_unary_op(tpf, VKD3D_SM4_OP_NOT, &expr->node, arg1, 0); break; -@@ -5022,39 +5199,77 @@ static void write_sm4_expr(const struct tpf_writer *tpf, const struct hlsl_ir_ex +@@ -5022,39 +5219,77 @@ static void write_sm4_expr(const struct tpf_writer *tpf, const struct hlsl_ir_ex } break; @@ -14224,7 +15292,7 @@ index b562e815a81..d6d5bbc1c07 100644 write_sm4_unary_op(tpf, VKD3D_SM4_OP_ROUND_Z, &expr->node, arg1, 0); break; -@@ -5076,17 +5291,17 @@ static void write_sm4_expr(const struct tpf_writer *tpf, const struct hlsl_ir_ex +@@ -5076,17 +5311,17 @@ static void write_sm4_expr(const struct tpf_writer *tpf, const struct hlsl_ir_ex break; case HLSL_OP2_BIT_AND: @@ -14245,7 +15313,7 @@ index b562e815a81..d6d5bbc1c07 100644 write_sm4_binary_op(tpf, VKD3D_SM4_OP_XOR, &expr->node, arg1, arg2); break; -@@ -5139,7 +5354,7 @@ static void write_sm4_expr(const struct tpf_writer *tpf, const struct hlsl_ir_ex +@@ -5139,7 +5374,7 @@ static void write_sm4_expr(const struct tpf_writer *tpf, const struct hlsl_ir_ex { const struct hlsl_type *src_type = arg1->data_type; @@ -14254,7 +15322,7 @@ index b562e815a81..d6d5bbc1c07 100644 switch (src_type->e.numeric.type) { -@@ -5165,7 +5380,7 @@ static void write_sm4_expr(const struct tpf_writer *tpf, const struct hlsl_ir_ex +@@ -5165,7 +5400,7 @@ static void write_sm4_expr(const struct tpf_writer *tpf, const struct hlsl_ir_ex { const struct hlsl_type *src_type = arg1->data_type; @@ -14263,7 +15331,7 @@ index b562e815a81..d6d5bbc1c07 100644 switch (src_type->e.numeric.type) { -@@ -5194,7 +5409,7 @@ static void write_sm4_expr(const struct tpf_writer *tpf, const struct hlsl_ir_ex +@@ -5194,7 +5429,7 @@ static void write_sm4_expr(const struct tpf_writer *tpf, const struct hlsl_ir_ex { const struct hlsl_type *src_type = arg1->data_type; @@ -14272,7 +15340,7 @@ index b562e815a81..d6d5bbc1c07 100644 switch (src_type->e.numeric.type) { -@@ -5220,18 +5435,18 @@ static void write_sm4_expr(const struct tpf_writer *tpf, const struct hlsl_ir_ex +@@ -5220,18 +5455,18 @@ static void write_sm4_expr(const struct tpf_writer *tpf, const struct hlsl_ir_ex } case HLSL_OP2_LOGIC_AND: @@ -14295,7 +15363,7 @@ index b562e815a81..d6d5bbc1c07 100644 write_sm4_binary_op(tpf, VKD3D_SM4_OP_ISHL, &expr->node, arg1, arg2); break; -@@ -5310,7 +5525,7 @@ static void write_sm4_expr(const struct tpf_writer *tpf, const struct hlsl_ir_ex +@@ -5310,7 +5545,7 @@ static void write_sm4_expr(const struct tpf_writer *tpf, const struct hlsl_ir_ex { const struct hlsl_type *src_type = arg1->data_type; @@ -14304,7 +15372,7 @@ index b562e815a81..d6d5bbc1c07 100644 switch (src_type->e.numeric.type) { -@@ -5333,8 +5548,8 @@ static void write_sm4_expr(const struct tpf_writer *tpf, const struct hlsl_ir_ex +@@ -5333,8 +5568,8 @@ static void write_sm4_expr(const struct tpf_writer *tpf, const struct hlsl_ir_ex } case HLSL_OP2_RSHIFT: @@ -14315,7 +15383,7 @@ index b562e815a81..d6d5bbc1c07 100644 write_sm4_binary_op(tpf, dst_type->e.numeric.type == HLSL_TYPE_INT ? VKD3D_SM4_OP_ISHR : VKD3D_SM4_OP_USHR, &expr->node, arg1, arg2); break; -@@ -5358,7 +5573,7 @@ static void write_sm4_if(const struct tpf_writer *tpf, const struct hlsl_ir_if * +@@ -5358,7 +5593,7 @@ static void write_sm4_if(const struct tpf_writer *tpf, const struct hlsl_ir_if * .src_count = 1, }; @@ -14324,7 +15392,7 @@ index b562e815a81..d6d5bbc1c07 100644 sm4_src_from_node(tpf, &instr.srcs[0], iff->condition.node, VKD3DSP_WRITEMASK_ALL); write_sm4_instruction(tpf, &instr); -@@ -5436,7 +5651,7 @@ static void write_sm4_load(const struct tpf_writer *tpf, const struct hlsl_ir_lo +@@ -5436,7 +5671,7 @@ static void write_sm4_load(const struct tpf_writer *tpf, const struct hlsl_ir_lo sm4_dst_from_node(&instr.dsts[0], &load->node); instr.dst_count = 1; @@ -14333,7 +15401,7 @@ index b562e815a81..d6d5bbc1c07 100644 if (type->e.numeric.type == HLSL_TYPE_BOOL && var_is_user_input(tpf->ctx, load->src.var)) { struct hlsl_constant_value value; -@@ -5553,7 +5768,7 @@ static void write_sm4_resource_load(const struct tpf_writer *tpf, const struct h +@@ -5553,7 +5788,7 @@ static void write_sm4_resource_load(const struct tpf_writer *tpf, const struct h case HLSL_RESOURCE_SAMPLE_LOD_BIAS: case HLSL_RESOURCE_SAMPLE_GRAD: /* Combined sample expressions were lowered. */ @@ -14342,7 +15410,7 @@ index b562e815a81..d6d5bbc1c07 100644 write_sm4_sample(tpf, load); break; -@@ -5706,7 +5921,7 @@ static void write_sm4_block(const struct tpf_writer *tpf, const struct hlsl_bloc +@@ -5706,7 +5941,7 @@ static void write_sm4_block(const struct tpf_writer *tpf, const struct hlsl_bloc if (!instr->reg.allocated) { @@ -14351,7 +15419,7 @@ index b562e815a81..d6d5bbc1c07 100644 continue; } } -@@ -5799,21 +6014,13 @@ static void write_sm4_shdr(struct hlsl_ctx *ctx, +@@ -5799,21 +6034,13 @@ static void write_sm4_shdr(struct hlsl_ctx *ctx, LIST_FOR_EACH_ENTRY(cbuffer, &ctx->buffers, struct hlsl_buffer, entry) { if (cbuffer->reg.allocated) @@ -14373,12 +15441,12 @@ index b562e815a81..d6d5bbc1c07 100644 if (resource->regset == HLSL_REGSET_SAMPLERS) write_sm4_dcl_samplers(&tpf, resource); else if (resource->regset == HLSL_REGSET_TEXTURES) -@@ -5875,7 +6082,7 @@ static void write_sm4_sfi0(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) +@@ -5875,7 +6102,7 @@ static void write_sm4_sfi0(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) extern_resources = sm4_get_extern_resources(ctx, &extern_resources_count); for (unsigned int i = 0; i < extern_resources_count; ++i) { - if (extern_resources[i].data_type->e.resource.rasteriser_ordered) -+ if (extern_resources[i].data_type && extern_resources[i].data_type->e.resource.rasteriser_ordered) ++ if (extern_resources[i].component_type && extern_resources[i].component_type->e.resource.rasteriser_ordered) *flags |= VKD3D_SM4_REQUIRES_ROVS; } sm4_free_extern_resources(extern_resources, extern_resources_count); @@ -14506,10 +15574,18 @@ index 14a3fa778e5..3c1ffcdbee3 100644 if (!shader_instruction_array_reserve(instructions, instructions->count + count)) return false; diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -index 29b8d6ad022..13b4dab76d1 100644 +index 29b8d6ad022..ef66a8ca07a 100644 --- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -@@ -151,6 +151,8 @@ enum vkd3d_shader_error +@@ -51,7 +51,6 @@ + #include "vkd3d_shader.h" + #include "wine/list.h" + +-#include + #include + #include + #include +@@ -151,6 +150,8 @@ enum vkd3d_shader_error VKD3D_SHADER_ERROR_HLSL_DUPLICATE_SWITCH_CASE = 5028, VKD3D_SHADER_ERROR_HLSL_MISSING_TECHNIQUE = 5029, VKD3D_SHADER_ERROR_HLSL_UNKNOWN_MODIFIER = 5030, @@ -14518,7 +15594,7 @@ index 29b8d6ad022..13b4dab76d1 100644 VKD3D_SHADER_WARNING_HLSL_IMPLICIT_TRUNCATION = 5300, VKD3D_SHADER_WARNING_HLSL_DIVISION_BY_ZERO = 5301, -@@ -455,6 +457,10 @@ enum vkd3d_shader_opcode +@@ -455,6 +456,10 @@ enum vkd3d_shader_opcode VKD3DSIH_PHASE, VKD3DSIH_PHI, VKD3DSIH_POW, @@ -14529,7 +15605,7 @@ index 29b8d6ad022..13b4dab76d1 100644 VKD3DSIH_RCP, VKD3DSIH_REP, VKD3DSIH_RESINFO, -@@ -613,6 +619,7 @@ enum vkd3d_shader_register_type +@@ -613,6 +618,7 @@ enum vkd3d_shader_register_type VKD3DSPR_SSA, VKD3DSPR_WAVELANECOUNT, VKD3DSPR_WAVELANEINDEX, @@ -14537,7 +15613,7 @@ index 29b8d6ad022..13b4dab76d1 100644 VKD3DSPR_COUNT, -@@ -805,6 +812,7 @@ enum vkd3d_tessellator_domain +@@ -805,6 +811,7 @@ enum vkd3d_tessellator_domain #define VKD3DSI_NONE 0x0 #define VKD3DSI_TEXLD_PROJECT 0x1 @@ -14545,7 +15621,7 @@ index 29b8d6ad022..13b4dab76d1 100644 #define VKD3DSI_INDEXED_DYNAMIC 0x4 #define VKD3DSI_RESINFO_RCP_FLOAT 0x1 #define VKD3DSI_RESINFO_UINT 0x2 -@@ -1189,7 +1197,7 @@ struct vkd3d_shader_location +@@ -1189,7 +1196,7 @@ struct vkd3d_shader_location struct vkd3d_shader_instruction { struct vkd3d_shader_location location; @@ -14554,7 +15630,7 @@ index 29b8d6ad022..13b4dab76d1 100644 uint32_t flags; unsigned int dst_count; unsigned int src_count; -@@ -1238,8 +1246,8 @@ static inline bool vkd3d_shader_ver_le(const struct vkd3d_shader_version *v, uns +@@ -1238,8 +1245,8 @@ static inline bool vkd3d_shader_ver_le(const struct vkd3d_shader_version *v, uns return v->major < major || (v->major == major && v->minor <= minor); } @@ -14565,7 +15641,7 @@ index 29b8d6ad022..13b4dab76d1 100644 static inline bool vkd3d_shader_instruction_has_texel_offset(const struct vkd3d_shader_instruction *ins) { -@@ -1303,14 +1311,14 @@ void *shader_param_allocator_get(struct vkd3d_shader_param_allocator *allocator, +@@ -1303,14 +1310,14 @@ void *shader_param_allocator_get(struct vkd3d_shader_param_allocator *allocator, static inline struct vkd3d_shader_src_param *shader_src_param_allocator_get( struct vkd3d_shader_param_allocator *allocator, unsigned int count) { @@ -14582,7 +15658,7 @@ index 29b8d6ad022..13b4dab76d1 100644 return shader_param_allocator_get(allocator, count); } -@@ -1355,6 +1363,10 @@ struct vsir_program +@@ -1355,6 +1362,10 @@ struct vsir_program struct shader_signature output_signature; struct shader_signature patch_constant_signature; @@ -14593,7 +15669,7 @@ index 29b8d6ad022..13b4dab76d1 100644 unsigned int input_control_point_count, output_control_point_count; unsigned int flat_constant_count[3]; unsigned int block_count; -@@ -1370,7 +1382,10 @@ void vsir_program_cleanup(struct vsir_program *program); +@@ -1370,7 +1381,10 @@ void vsir_program_cleanup(struct vsir_program *program); int vsir_program_compile(struct vsir_program *program, uint64_t config_flags, const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context); @@ -14605,7 +15681,7 @@ index 29b8d6ad022..13b4dab76d1 100644 enum vkd3d_result vsir_program_normalise(struct vsir_program *program, uint64_t config_flags, const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context); enum vkd3d_result vsir_program_validate(struct vsir_program *program, uint64_t config_flags, -@@ -1663,7 +1678,7 @@ static inline unsigned int vsir_write_mask_get_component_idx(uint32_t write_mask +@@ -1663,7 +1677,7 @@ static inline unsigned int vsir_write_mask_get_component_idx(uint32_t write_mask { unsigned int i; @@ -14614,7 +15690,7 @@ index 29b8d6ad022..13b4dab76d1 100644 for (i = 0; i < VKD3D_VEC4_SIZE; ++i) { if (write_mask & (VKD3DSP_WRITEMASK_0 << i)) -@@ -1677,13 +1692,13 @@ static inline unsigned int vsir_write_mask_get_component_idx(uint32_t write_mask +@@ -1677,13 +1691,13 @@ static inline unsigned int vsir_write_mask_get_component_idx(uint32_t write_mask static inline unsigned int vsir_write_mask_component_count(uint32_t write_mask) { unsigned int count = vkd3d_popcount(write_mask & VKD3DSP_WRITEMASK_ALL); @@ -16652,7 +17728,7 @@ index cfc9c5f5ed3..01841c89692 100644 } diff --git a/libs/vkd3d/libs/vkd3d/resource.c b/libs/vkd3d/libs/vkd3d/resource.c -index c897d9f2c5a..ac29088b9cb 100644 +index c897d9f2c5a..6d6820d3752 100644 --- a/libs/vkd3d/libs/vkd3d/resource.c +++ b/libs/vkd3d/libs/vkd3d/resource.c @@ -312,7 +312,7 @@ static ULONG STDMETHODCALLTYPE d3d12_heap_AddRef(ID3D12Heap *iface) @@ -16744,6 +17820,15 @@ index c897d9f2c5a..ac29088b9cb 100644 heap_offset, requirements.size, heap->desc.SizeInBytes); return E_INVALIDARG; } +@@ -2192,7 +2184,7 @@ static HRESULT vkd3d_bind_heap_memory(struct d3d12_device *device, + goto allocate_memory; + } + +- /* Syncronisation is not required for binding, but vkMapMemory() may be called ++ /* Synchronisation is not required for binding, but vkMapMemory() may be called + * from another thread and it requires exclusive access. */ + vkd3d_mutex_lock(&heap->mutex); + @@ -2414,7 +2406,7 @@ static struct vkd3d_view *vkd3d_view_create(uint32_t magic, VkDescriptorType vk_ { struct vkd3d_view *view; @@ -16859,7 +17944,7 @@ index c897d9f2c5a..ac29088b9cb 100644 } diff --git a/libs/vkd3d/libs/vkd3d/state.c b/libs/vkd3d/libs/vkd3d/state.c -index 7197193523d..0bdb7ea524d 100644 +index 7197193523d..d9d200e4850 100644 --- a/libs/vkd3d/libs/vkd3d/state.c +++ b/libs/vkd3d/libs/vkd3d/state.c @@ -194,7 +194,7 @@ struct d3d12_root_signature *unsafe_impl_from_ID3D12RootSignature(ID3D12RootSign @@ -16979,23 +18064,25 @@ index 7197193523d..0bdb7ea524d 100644 if (range->NumDescriptors == UINT_MAX) { unbounded = true; -@@ -453,7 +537,7 @@ static HRESULT d3d12_root_signature_info_from_desc(struct d3d12_root_signature_i +@@ -453,8 +537,8 @@ static HRESULT d3d12_root_signature_info_from_desc(struct d3d12_root_signature_i { case D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE: if (FAILED(hr = d3d12_root_signature_info_count_descriptors(info, - &p->u.DescriptorTable, use_array))) +- return hr; + p, use_array))) - return hr; ++ goto done; ++info->cost; break; -@@ -463,23 +547,41 @@ static HRESULT d3d12_root_signature_info_from_desc(struct d3d12_root_signature_i + +@@ -463,35 +547,80 @@ static HRESULT d3d12_root_signature_info_from_desc(struct d3d12_root_signature_i ++info->cbv_count; ++info->binding_count; info->cost += 2; + if (FAILED(hr = d3d12_root_signature_info_add_range(info, + VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, p->ShaderVisibility, + p->u.Descriptor.RegisterSpace, p->u.Descriptor.ShaderRegister, 1))) -+ return hr; ++ goto done; break; + case D3D12_ROOT_PARAMETER_TYPE_SRV: @@ -17006,7 +18093,7 @@ index 7197193523d..0bdb7ea524d 100644 + if (FAILED(hr = d3d12_root_signature_info_add_range(info, + VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, p->ShaderVisibility, + p->u.Descriptor.RegisterSpace, p->u.Descriptor.ShaderRegister, 1))) -+ return hr; ++ goto done; break; + case D3D12_ROOT_PARAMETER_TYPE_UAV: @@ -17017,7 +18104,7 @@ index 7197193523d..0bdb7ea524d 100644 + if (FAILED(hr = d3d12_root_signature_info_add_range(info, + VKD3D_SHADER_DESCRIPTOR_TYPE_UAV, p->ShaderVisibility, + p->u.Descriptor.RegisterSpace, p->u.Descriptor.ShaderRegister, 1))) -+ return hr; ++ goto done; break; case D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS: @@ -17026,14 +18113,21 @@ index 7197193523d..0bdb7ea524d 100644 + if (FAILED(hr = d3d12_root_signature_info_add_range(info, + VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, p->ShaderVisibility, + p->u.Constants.RegisterSpace, p->u.Constants.ShaderRegister, 1))) -+ return hr; ++ goto done; break; default: -@@ -491,6 +593,30 @@ static HRESULT d3d12_root_signature_info_from_desc(struct d3d12_root_signature_i + FIXME("Unhandled type %#x for parameter %u.\n", p->ParameterType, i); +- return E_NOTIMPL; ++ hr = E_NOTIMPL; ++ goto done; + } + } + info->binding_count += desc->NumStaticSamplers; info->sampler_count += desc->NumStaticSamplers; +- return S_OK; + for (i = 0; i < desc->NumStaticSamplers; ++i) + { + const D3D12_STATIC_SAMPLER_DESC *s = &desc->pStaticSamplers[i]; @@ -17041,7 +18135,7 @@ index 7197193523d..0bdb7ea524d 100644 + if (FAILED(hr = d3d12_root_signature_info_add_range(info, + VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, s->ShaderVisibility, + s->RegisterSpace, s->ShaderRegister, 1))) -+ return hr; ++ goto done; + } + + qsort(info->ranges, info->range_count, sizeof(*info->ranges), @@ -17050,27 +18144,44 @@ index 7197193523d..0bdb7ea524d 100644 + for (i = D3D12_SHADER_VISIBILITY_VERTEX; i <= D3D12_SHADER_VISIBILITY_MESH; ++i) + { + if (FAILED(hr = d3d12_root_signature_info_range_validate(info->ranges, info->range_count, i))) -+ return hr; ++ goto done; + } + ++ hr = S_OK; ++done: + vkd3d_free(info->ranges); + info->ranges = NULL; + info->range_count = 0; + info->range_capacity = 0; + - return S_OK; ++ return hr; } -@@ -512,7 +638,7 @@ static HRESULT d3d12_root_signature_init_push_constants(struct d3d12_root_signat + static HRESULT d3d12_root_signature_init_push_constants(struct d3d12_root_signature *root_signature, +@@ -509,14 +638,18 @@ static HRESULT d3d12_root_signature_init_push_constants(struct d3d12_root_signat + for (i = 0; i < desc->NumParameters; ++i) + { + const D3D12_ROOT_PARAMETER *p = &desc->pParameters[i]; ++ D3D12_SHADER_VISIBILITY visibility; ++ if (p->ParameterType != D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS) continue; - assert(p->ShaderVisibility <= D3D12_SHADER_VISIBILITY_PIXEL); -+ VKD3D_ASSERT(p->ShaderVisibility <= D3D12_SHADER_VISIBILITY_PIXEL); - push_constants[p->ShaderVisibility].stageFlags = use_vk_heaps ? VK_SHADER_STAGE_ALL - : stage_flags_from_visibility(p->ShaderVisibility); - push_constants[p->ShaderVisibility].size += align(p->u.Constants.Num32BitValues, 4) * sizeof(uint32_t); -@@ -645,7 +771,7 @@ static HRESULT d3d12_root_signature_append_descriptor_set_layout(struct d3d12_ro +- push_constants[p->ShaderVisibility].stageFlags = use_vk_heaps ? VK_SHADER_STAGE_ALL +- : stage_flags_from_visibility(p->ShaderVisibility); +- push_constants[p->ShaderVisibility].size += align(p->u.Constants.Num32BitValues, 4) * sizeof(uint32_t); ++ visibility = use_vk_heaps ? D3D12_SHADER_VISIBILITY_ALL : p->ShaderVisibility; ++ VKD3D_ASSERT(visibility <= D3D12_SHADER_VISIBILITY_PIXEL); ++ ++ push_constants[visibility].stageFlags = stage_flags_from_visibility(visibility); ++ push_constants[visibility].size += align(p->u.Constants.Num32BitValues, 4) * sizeof(uint32_t); + } ++ + if (push_constants[D3D12_SHADER_VISIBILITY_ALL].size) + { + /* When D3D12_SHADER_VISIBILITY_ALL is used we use a single push +@@ -645,7 +778,7 @@ static HRESULT d3d12_root_signature_append_descriptor_set_layout(struct d3d12_ro return S_OK; } @@ -17079,7 +18190,7 @@ index 7197193523d..0bdb7ea524d 100644 enum vkd3d_shader_descriptor_type descriptor_type, unsigned int register_space, unsigned int register_idx, bool buffer_descriptor, enum vkd3d_shader_visibility shader_visibility, unsigned int descriptor_count, struct vkd3d_descriptor_set_context *context) -@@ -670,33 +796,38 @@ static void d3d12_root_signature_append_vk_binding(struct d3d12_root_signature * +@@ -670,33 +803,38 @@ static void d3d12_root_signature_append_vk_binding(struct d3d12_root_signature * } if (context->unbounded_offset != UINT_MAX) @@ -17129,7 +18240,7 @@ index 7197193523d..0bdb7ea524d 100644 } static uint32_t vkd3d_descriptor_magic_from_d3d12(D3D12_DESCRIPTOR_RANGE_TYPE type) -@@ -764,6 +895,7 @@ static HRESULT d3d12_root_signature_init_descriptor_array_binding(struct d3d12_r +@@ -764,6 +902,7 @@ static HRESULT d3d12_root_signature_init_descriptor_array_binding(struct d3d12_r enum vkd3d_shader_visibility shader_visibility = vkd3d_shader_visibility_from_d3d12(visibility); bool is_buffer = range->type == VKD3D_SHADER_DESCRIPTOR_TYPE_CBV; enum vkd3d_shader_descriptor_type descriptor_type = range->type; @@ -17137,7 +18248,7 @@ index 7197193523d..0bdb7ea524d 100644 if (range->descriptor_count == UINT_MAX) context->unbounded_offset = range->offset; -@@ -775,8 +907,9 @@ static HRESULT d3d12_root_signature_init_descriptor_array_binding(struct d3d12_r +@@ -775,8 +914,9 @@ static HRESULT d3d12_root_signature_init_descriptor_array_binding(struct d3d12_r return E_NOTIMPL; ++context->current_binding; @@ -17149,7 +18260,7 @@ index 7197193523d..0bdb7ea524d 100644 } if (!vk_binding_from_d3d12_descriptor_range(context->current_binding, -@@ -784,8 +917,9 @@ static HRESULT d3d12_root_signature_init_descriptor_array_binding(struct d3d12_r +@@ -784,8 +924,9 @@ static HRESULT d3d12_root_signature_init_descriptor_array_binding(struct d3d12_r return E_NOTIMPL; ++context->current_binding; @@ -17161,7 +18272,7 @@ index 7197193523d..0bdb7ea524d 100644 context->unbounded_offset = UINT_MAX; -@@ -955,20 +1089,6 @@ static void d3d12_root_signature_map_descriptor_unbounded_binding(struct d3d12_r +@@ -955,20 +1096,6 @@ static void d3d12_root_signature_map_descriptor_unbounded_binding(struct d3d12_r descriptor_offset, is_buffer, shader_visibility, context); } @@ -17182,7 +18293,7 @@ index 7197193523d..0bdb7ea524d 100644 static int compare_descriptor_range(const void *a, const void *b) { const struct d3d12_root_descriptor_table_range *range_a = a, *range_b = b; -@@ -983,25 +1103,6 @@ static int compare_descriptor_range(const void *a, const void *b) +@@ -983,25 +1110,6 @@ static int compare_descriptor_range(const void *a, const void *b) return (range_a->descriptor_count == UINT_MAX) - (range_b->descriptor_count == UINT_MAX); } @@ -17208,7 +18319,7 @@ index 7197193523d..0bdb7ea524d 100644 static HRESULT d3d12_root_signature_init_root_descriptor_tables(struct d3d12_root_signature *root_signature, const D3D12_ROOT_SIGNATURE_DESC *desc, const struct d3d12_root_signature_info *info, struct vkd3d_descriptor_set_context *context) -@@ -1062,10 +1163,6 @@ static HRESULT d3d12_root_signature_init_root_descriptor_tables(struct d3d12_roo +@@ -1062,10 +1170,6 @@ static HRESULT d3d12_root_signature_init_root_descriptor_tables(struct d3d12_roo offset += range->NumDescriptors; } @@ -17219,7 +18330,7 @@ index 7197193523d..0bdb7ea524d 100644 qsort(table->ranges, range_count, sizeof(*table->ranges), compare_descriptor_range); for (j = 0; j < range_count; ++j) -@@ -1130,9 +1227,10 @@ static HRESULT d3d12_root_signature_init_root_descriptor_tables(struct d3d12_roo +@@ -1130,9 +1234,10 @@ static HRESULT d3d12_root_signature_init_root_descriptor_tables(struct d3d12_roo cur_binding = context->current_binding; @@ -17232,7 +18343,7 @@ index 7197193523d..0bdb7ea524d 100644 /* Unroll descriptor range. */ for (k = 0; k < range->descriptor_count; ++k) -@@ -1175,6 +1273,7 @@ static HRESULT d3d12_root_signature_init_root_descriptors(struct d3d12_root_sign +@@ -1175,6 +1280,7 @@ static HRESULT d3d12_root_signature_init_root_descriptors(struct d3d12_root_sign { VkDescriptorSetLayoutBinding *cur_binding = context->current_binding; unsigned int i; @@ -17240,7 +18351,7 @@ index 7197193523d..0bdb7ea524d 100644 root_signature->push_descriptor_mask = 0; -@@ -1188,10 +1287,11 @@ static HRESULT d3d12_root_signature_init_root_descriptors(struct d3d12_root_sign +@@ -1188,10 +1294,11 @@ static HRESULT d3d12_root_signature_init_root_descriptors(struct d3d12_root_sign root_signature->push_descriptor_mask |= 1u << i; @@ -17254,7 +18365,7 @@ index 7197193523d..0bdb7ea524d 100644 cur_binding->descriptorType = vk_descriptor_type_from_d3d12_root_parameter(p->ParameterType); cur_binding->descriptorCount = 1; cur_binding->stageFlags = stage_flags_from_visibility(p->ShaderVisibility); -@@ -1215,7 +1315,7 @@ static HRESULT d3d12_root_signature_init_static_samplers(struct d3d12_root_signa +@@ -1215,7 +1322,7 @@ static HRESULT d3d12_root_signature_init_static_samplers(struct d3d12_root_signa unsigned int i; HRESULT hr; @@ -17263,7 +18374,7 @@ index 7197193523d..0bdb7ea524d 100644 for (i = 0; i < desc->NumStaticSamplers; ++i) { const D3D12_STATIC_SAMPLER_DESC *s = &desc->pStaticSamplers[i]; -@@ -1223,9 +1323,10 @@ static HRESULT d3d12_root_signature_init_static_samplers(struct d3d12_root_signa +@@ -1223,9 +1330,10 @@ static HRESULT d3d12_root_signature_init_static_samplers(struct d3d12_root_signa if (FAILED(hr = vkd3d_create_static_sampler(device, s, &root_signature->static_samplers[i]))) return hr; @@ -17276,7 +18387,7 @@ index 7197193523d..0bdb7ea524d 100644 cur_binding->descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; cur_binding->descriptorCount = 1; cur_binding->stageFlags = stage_flags_from_visibility(s->ShaderVisibility); -@@ -1600,7 +1701,7 @@ static HRESULT vkd3d_render_pass_cache_create_pass_locked(struct vkd3d_render_pa +@@ -1600,7 +1708,7 @@ static HRESULT vkd3d_render_pass_cache_create_pass_locked(struct vkd3d_render_pa have_depth_stencil = key->depth_enable || key->stencil_enable; rt_count = have_depth_stencil ? key->attachment_count - 1 : key->attachment_count; @@ -17285,7 +18396,7 @@ index 7197193523d..0bdb7ea524d 100644 for (index = 0, attachment_index = 0; index < rt_count; ++index) { -@@ -2140,7 +2241,7 @@ struct d3d12_pipeline_state *unsafe_impl_from_ID3D12PipelineState(ID3D12Pipeline +@@ -2140,7 +2248,7 @@ struct d3d12_pipeline_state *unsafe_impl_from_ID3D12PipelineState(ID3D12Pipeline { if (!iface) return NULL; @@ -17294,7 +18405,7 @@ index 7197193523d..0bdb7ea524d 100644 return impl_from_ID3D12PipelineState(iface); } -@@ -2296,7 +2397,7 @@ static HRESULT d3d12_pipeline_state_init_uav_counters(struct d3d12_pipeline_stat +@@ -2296,7 +2404,7 @@ static HRESULT d3d12_pipeline_state_init_uav_counters(struct d3d12_pipeline_stat unsigned int i, j; HRESULT hr; @@ -17303,7 +18414,7 @@ index 7197193523d..0bdb7ea524d 100644 for (i = 0; i < shader_info->descriptor_count; ++i) { -@@ -2911,7 +3012,7 @@ static HRESULT d3d12_graphics_pipeline_state_create_render_pass( +@@ -2911,7 +3019,7 @@ static HRESULT d3d12_graphics_pipeline_state_create_render_pass( if (dsv_format) { @@ -17312,7 +18423,7 @@ index 7197193523d..0bdb7ea524d 100644 key.depth_enable = graphics->ds_desc.depthTestEnable; key.stencil_enable = graphics->ds_desc.stencilTestEnable; key.depth_stencil_write = graphics->ds_desc.depthWriteEnable -@@ -2928,7 +3029,7 @@ static HRESULT d3d12_graphics_pipeline_state_create_render_pass( +@@ -2928,7 +3036,7 @@ static HRESULT d3d12_graphics_pipeline_state_create_render_pass( if (key.attachment_count != ARRAY_SIZE(key.vk_formats)) key.vk_formats[ARRAY_SIZE(key.vk_formats) - 1] = VK_FORMAT_UNDEFINED; for (i = key.attachment_count; i < ARRAY_SIZE(key.vk_formats); ++i) @@ -17321,7 +18432,7 @@ index 7197193523d..0bdb7ea524d 100644 key.padding = 0; key.sample_count = graphics->ms_desc.rasterizationSamples; -@@ -3476,7 +3577,7 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s +@@ -3476,7 +3584,7 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s graphics->ms_desc.pSampleMask = NULL; if (desc->sample_mask != ~0u) { @@ -17330,7 +18441,7 @@ index 7197193523d..0bdb7ea524d 100644 graphics->sample_mask[0] = desc->sample_mask; graphics->sample_mask[1] = 0xffffffffu; graphics->ms_desc.pSampleMask = graphics->sample_mask; -@@ -3769,7 +3870,7 @@ VkPipeline d3d12_pipeline_state_get_or_create_pipeline(struct d3d12_pipeline_sta +@@ -3769,7 +3877,7 @@ VkPipeline d3d12_pipeline_state_get_or_create_pipeline(struct d3d12_pipeline_sta .pDynamicStates = dynamic_states, }; @@ -17399,10 +18510,18 @@ index c7431bd821b..9eccec111c7 100644 return S_OK; } diff --git a/libs/vkd3d/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/libs/vkd3d/vkd3d_private.h -index d1fa866d9e3..a4bd2202f39 100644 +index d1fa866d9e3..ba4e2e8488d 100644 --- a/libs/vkd3d/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/libs/vkd3d/vkd3d_private.h -@@ -123,6 +123,7 @@ struct vkd3d_vulkan_info +@@ -37,7 +37,6 @@ + #include "vkd3d.h" + #include "vkd3d_shader.h" + +-#include + #include + #include + #include +@@ -123,6 +122,7 @@ struct vkd3d_vulkan_info bool KHR_image_format_list; bool KHR_maintenance2; bool KHR_maintenance3; @@ -17410,7 +18529,7 @@ index d1fa866d9e3..a4bd2202f39 100644 bool KHR_push_descriptor; bool KHR_sampler_mirror_clamp_to_edge; bool KHR_timeline_semaphore; -@@ -145,6 +146,8 @@ struct vkd3d_vulkan_info +@@ -145,6 +145,8 @@ struct vkd3d_vulkan_info bool rasterization_stream; bool transform_feedback_queries; @@ -17419,7 +18538,16 @@ index d1fa866d9e3..a4bd2202f39 100644 bool uav_read_without_format; -@@ -784,8 +787,8 @@ extern const enum vkd3d_vk_descriptor_set_index vk_descriptor_set_index_table[]; +@@ -676,7 +678,7 @@ static inline void *d3d12_desc_get_object_ref(const volatile struct d3d12_desc * + void *view; + + /* Some games, e.g. Shadow of the Tomb Raider, GRID 2019, and Horizon Zero Dawn, write descriptors +- * from multiple threads without syncronisation. This is apparently valid in Windows. */ ++ * from multiple threads without synchronisation. This is apparently valid in Windows. */ + for (;;) + { + do +@@ -784,8 +786,8 @@ extern const enum vkd3d_vk_descriptor_set_index vk_descriptor_set_index_table[]; static inline enum vkd3d_vk_descriptor_set_index vkd3d_vk_descriptor_set_index_from_vk_descriptor_type( VkDescriptorType type) { @@ -17430,7 +18558,7 @@ index d1fa866d9e3..a4bd2202f39 100644 return vk_descriptor_set_index_table[type]; } -@@ -1229,7 +1232,7 @@ enum vkd3d_pipeline_bind_point +@@ -1229,7 +1231,7 @@ enum vkd3d_pipeline_bind_point /* ID3D12CommandList */ struct d3d12_command_list { @@ -17439,7 +18567,7 @@ index d1fa866d9e3..a4bd2202f39 100644 unsigned int refcount; D3D12_COMMAND_LIST_TYPE type; -@@ -1753,7 +1756,6 @@ static inline void vk_prepend_struct(void *header, void *structure) +@@ -1753,7 +1755,6 @@ static inline void vk_prepend_struct(void *header, void *structure) { VkBaseOutStructure *vk_header = header, *vk_structure = structure; @@ -17447,7 +18575,7 @@ index d1fa866d9e3..a4bd2202f39 100644 vk_structure->pNext = vk_header->pNext; vk_header->pNext = vk_structure; } -@@ -1766,7 +1768,7 @@ static inline void vkd3d_prepend_struct(void *header, void *structure) +@@ -1766,7 +1767,7 @@ static inline void vkd3d_prepend_struct(void *header, void *structure) const void *next; } *vkd3d_header = header, *vkd3d_structure = structure; @@ -17457,5 +18585,5 @@ index d1fa866d9e3..a4bd2202f39 100644 vkd3d_header->next = vkd3d_structure; } -- -2.43.0 +2.45.2 diff --git a/patches/vkd3d-latest/0002-Updated-vkd3d-to-c8cc1b1a2476a4c518756fd7604d37e8c16.patch b/patches/vkd3d-latest/0002-Updated-vkd3d-to-c8cc1b1a2476a4c518756fd7604d37e8c16.patch deleted file mode 100644 index 5418c3ef..00000000 --- a/patches/vkd3d-latest/0002-Updated-vkd3d-to-c8cc1b1a2476a4c518756fd7604d37e8c16.patch +++ /dev/null @@ -1,1777 +0,0 @@ -From 5942f59d8cade40d6bb21f8c46fc05fcee79dbb3 Mon Sep 17 00:00:00 2001 -From: Alistair Leslie-Hughes -Date: Tue, 20 Aug 2024 06:47:55 +1000 -Subject: [PATCH] Updated vkd3d to c8cc1b1a2476a4c518756fd7604d37e8c1611af3. - ---- - libs/vkd3d/include/private/vkd3d_memory.h | 3 +- - libs/vkd3d/include/vkd3d_shader.h | 2 +- - libs/vkd3d/libs/vkd3d-common/debug.c | 1 - - libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 2 +- - libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 10 +- - libs/vkd3d/libs/vkd3d-shader/dxil.c | 4 +- - libs/vkd3d/libs/vkd3d-shader/fx.c | 389 +++++++++++++++--- - libs/vkd3d/libs/vkd3d-shader/glsl.c | 6 +- - libs/vkd3d/libs/vkd3d-shader/hlsl.c | 45 +- - libs/vkd3d/libs/vkd3d-shader/hlsl.h | 10 +- - libs/vkd3d/libs/vkd3d-shader/hlsl.l | 2 + - libs/vkd3d/libs/vkd3d-shader/hlsl.y | 125 ++++-- - libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 2 + - libs/vkd3d/libs/vkd3d-shader/ir.c | 36 +- - libs/vkd3d/libs/vkd3d-shader/tpf.c | 94 +++-- - .../libs/vkd3d-shader/vkd3d_shader_private.h | 1 - - libs/vkd3d/libs/vkd3d/resource.c | 2 +- - libs/vkd3d/libs/vkd3d/state.c | 12 +- - libs/vkd3d/libs/vkd3d/vkd3d_private.h | 3 +- - 19 files changed, 582 insertions(+), 167 deletions(-) - -diff --git a/libs/vkd3d/include/private/vkd3d_memory.h b/libs/vkd3d/include/private/vkd3d_memory.h -index 682d35c03c6..e191dc11b73 100644 ---- a/libs/vkd3d/include/private/vkd3d_memory.h -+++ b/libs/vkd3d/include/private/vkd3d_memory.h -@@ -19,7 +19,6 @@ - #ifndef __VKD3D_MEMORY_H - #define __VKD3D_MEMORY_H - --#include - #include - #include - #include -@@ -44,7 +43,7 @@ static inline void *vkd3d_realloc(void *ptr, size_t size) - static inline void *vkd3d_calloc(size_t count, size_t size) - { - void *ptr; -- assert(count <= ~(size_t)0 / size); -+ VKD3D_ASSERT(count <= ~(size_t)0 / size); - if (!(ptr = calloc(count, size))) - ERR("Out of memory.\n"); - return ptr; -diff --git a/libs/vkd3d/include/vkd3d_shader.h b/libs/vkd3d/include/vkd3d_shader.h -index d4756810065..d37d8ebad9e 100644 ---- a/libs/vkd3d/include/vkd3d_shader.h -+++ b/libs/vkd3d/include/vkd3d_shader.h -@@ -1876,7 +1876,7 @@ enum vkd3d_shader_sysval_semantic - VKD3D_SHADER_SV_VIEWPORT_ARRAY_INDEX = 0x05, - /** Vertex ID; SV_VertexID in Direct3D. */ - VKD3D_SHADER_SV_VERTEX_ID = 0x06, -- /** Primtive ID; SV_PrimitiveID in Direct3D. */ -+ /** Primitive ID; SV_PrimitiveID in Direct3D. */ - VKD3D_SHADER_SV_PRIMITIVE_ID = 0x07, - /** Instance ID; SV_InstanceID in Direct3D. */ - VKD3D_SHADER_SV_INSTANCE_ID = 0x08, -diff --git a/libs/vkd3d/libs/vkd3d-common/debug.c b/libs/vkd3d/libs/vkd3d-common/debug.c -index 4bfc19bd9a1..9a92f0ead02 100644 ---- a/libs/vkd3d/libs/vkd3d-common/debug.c -+++ b/libs/vkd3d/libs/vkd3d-common/debug.c -@@ -22,7 +22,6 @@ - - #include "vkd3d_common.h" - --#include - #include - #include - #include -diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c -index 2c2f0c43ece..77e9711300f 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c -+++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c -@@ -2251,7 +2251,7 @@ static const char *get_semantic_register_name(enum vkd3d_shader_sysval_semantic - case VKD3D_SHADER_SV_DEPTH_GREATER_EQUAL: return "oDepthGE"; - case VKD3D_SHADER_SV_DEPTH_LESS_EQUAL: return "oDepthLE"; - /* SV_Coverage has name vCoverage when used as an input, -- * but it doens't appear in the signature in that case. */ -+ * but it doesn't appear in the signature in that case. */ - case VKD3D_SHADER_SV_COVERAGE: return "oMask"; - case VKD3D_SHADER_SV_STENCIL_REF: return "oStencilRef"; - default: return "??"; -diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c -index a4c038a233a..d05394c3ab7 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c -+++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c -@@ -1523,6 +1523,8 @@ D3DXPARAMETER_CLASS hlsl_sm1_class(const struct hlsl_type *type) - case HLSL_CLASS_DOMAIN_SHADER: - case HLSL_CLASS_HULL_SHADER: - case HLSL_CLASS_GEOMETRY_SHADER: -+ case HLSL_CLASS_BLEND_STATE: -+ case HLSL_CLASS_NULL: - break; - } - -@@ -1626,6 +1628,8 @@ D3DXPARAMETER_TYPE hlsl_sm1_base_type(const struct hlsl_type *type) - case HLSL_CLASS_DOMAIN_SHADER: - case HLSL_CLASS_HULL_SHADER: - case HLSL_CLASS_GEOMETRY_SHADER: -+ case HLSL_CLASS_BLEND_STATE: -+ case HLSL_CLASS_NULL: - break; - } - -@@ -1826,17 +1830,17 @@ void write_sm1_uniforms(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buff - break; - - case HLSL_TYPE_INT: -- uni.f = var->default_values[k].value.i; -+ uni.f = var->default_values[k].number.i; - break; - - case HLSL_TYPE_UINT: - case HLSL_TYPE_BOOL: -- uni.f = var->default_values[k].value.u; -+ uni.f = var->default_values[k].number.u; - break; - - case HLSL_TYPE_HALF: - case HLSL_TYPE_FLOAT: -- uni.u = var->default_values[k].value.u; -+ uni.u = var->default_values[k].number.u; - break; - - default: -diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c -index 2a0bbe1a625..4a17c62292b 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/dxil.c -+++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c -@@ -4298,7 +4298,7 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco - if (!(flags & FP_ALLOW_UNSAFE_ALGEBRA)) - ins->flags |= VKD3DSI_PRECISE_X; - flags &= ~FP_ALLOW_UNSAFE_ALGEBRA; -- /* SPIR-V FPFastMathMode is only available in the Kernel executon model. */ -+ /* SPIR-V FPFastMathMode is only available in the Kernel execution model. */ - silence_warning = !(flags & ~(FP_NO_NAN | FP_NO_INF | FP_NO_SIGNED_ZEROS | FP_ALLOW_RECIPROCAL)); - break; - case VKD3DSIH_IADD: -@@ -5211,7 +5211,7 @@ static void sm6_parser_emit_dx_get_dimensions(struct sm6_parser *sm6, enum dx_in - instruction_dst_param_init_temp_vector(ins++, sm6); - state->temp_idx = 1; - -- /* DXIL does not have an instrinsic for sample info, and resinfo is expected to return -+ /* DXIL does not have an intrinsic for sample info, and resinfo is expected to return - * the sample count in .w for MS textures. The result is always a struct of 4 x uint32. */ - vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_SAMPLE_INFO); - ins->flags = VKD3DSI_SAMPLE_INFO_UINT; -diff --git a/libs/vkd3d/libs/vkd3d-shader/fx.c b/libs/vkd3d/libs/vkd3d-shader/fx.c -index e3ebbafb3f4..a1d1fd6572f 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/fx.c -+++ b/libs/vkd3d/libs/vkd3d-shader/fx.c -@@ -111,7 +111,7 @@ static void get_state_block_function_components(const struct state_block_functio - { - unsigned int i; - -- assert(comp_count <= info->max_args); -+ VKD3D_ASSERT(comp_count <= info->max_args); - - if (info->min_args == info->max_args) - { -@@ -205,6 +205,8 @@ struct fx_write_context - uint32_t sampler_state_count; - uint32_t depth_stencil_state_count; - uint32_t rasterizer_state_count; -+ uint32_t blend_state_count; -+ uint32_t string_count; - int status; - - bool child_effect; -@@ -565,6 +567,9 @@ static const char * get_fx_4_type_name(const struct hlsl_type *type) - case HLSL_CLASS_PIXEL_SHADER: - return "PixelShader"; - -+ case HLSL_CLASS_STRING: -+ return "String"; -+ - default: - return type->name; - } -@@ -636,6 +641,8 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co - case HLSL_CLASS_DOMAIN_SHADER: - case HLSL_CLASS_HULL_SHADER: - case HLSL_CLASS_GEOMETRY_SHADER: -+ case HLSL_CLASS_BLEND_STATE: -+ case HLSL_CLASS_STRING: - put_u32_unaligned(buffer, 2); - break; - -@@ -648,9 +655,9 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co - case HLSL_CLASS_PASS: - case HLSL_CLASS_TECHNIQUE: - case HLSL_CLASS_CONSTANT_BUFFER: -+ case HLSL_CLASS_NULL: - vkd3d_unreachable(); - -- case HLSL_CLASS_STRING: - case HLSL_CLASS_VOID: - FIXME("Writing type class %u is not implemented.\n", type->class); - set_status(fx, VKD3D_ERROR_NOT_IMPLEMENTED); -@@ -754,6 +761,14 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co - { - put_u32_unaligned(buffer, 3); - } -+ else if (type->class == HLSL_CLASS_BLEND_STATE) -+ { -+ put_u32_unaligned(buffer, 2); -+ } -+ else if (type->class == HLSL_CLASS_STRING) -+ { -+ put_u32_unaligned(buffer, 1); -+ } - else if (hlsl_is_numeric_type(type)) - { - numeric_desc = get_fx_4_numeric_type_description(type, fx); -@@ -879,6 +894,13 @@ static uint32_t write_fx_2_string(const char *string, struct fx_write_context *f - return offset; - } - -+static uint32_t get_fx_2_type_class(const struct hlsl_type *type) -+{ -+ if (type->class == HLSL_CLASS_MATRIX) -+ return D3DXPC_MATRIX_ROWS; -+ return hlsl_sm1_class(type); -+} -+ - static uint32_t write_fx_2_parameter(const struct hlsl_type *type, const char *name, const struct hlsl_semantic *semantic, - struct fx_write_context *fx) - { -@@ -897,7 +919,7 @@ static uint32_t write_fx_2_parameter(const struct hlsl_type *type, const char *n - semantic_offset = semantic->raw_name ? write_string(semantic->raw_name, fx) : 0; - - offset = put_u32(buffer, hlsl_sm1_base_type(type)); -- put_u32(buffer, hlsl_sm1_class(type)); -+ put_u32(buffer, get_fx_2_type_class(type)); - put_u32(buffer, name_offset); - put_u32(buffer, semantic_offset); - put_u32(buffer, elements_count); -@@ -1078,12 +1100,14 @@ static bool is_type_supported_fx_2(struct hlsl_ctx *ctx, const struct hlsl_type - case HLSL_CLASS_DOMAIN_SHADER: - case HLSL_CLASS_HULL_SHADER: - case HLSL_CLASS_GEOMETRY_SHADER: -+ case HLSL_CLASS_BLEND_STATE: - return false; - - case HLSL_CLASS_EFFECT_GROUP: - case HLSL_CLASS_PASS: - case HLSL_CLASS_TECHNIQUE: - case HLSL_CLASS_CONSTANT_BUFFER: -+ case HLSL_CLASS_NULL: - /* This cannot appear as an extern variable. */ - break; - } -@@ -1234,7 +1258,7 @@ static uint32_t write_fx_4_default_value(struct hlsl_type *value_type, struct hl - - for (j = 0; j < comp_count; ++j) - { -- put_u32_unaligned(buffer, value->value.u); -+ put_u32_unaligned(buffer, value->number.u); - value++; - } - break; -@@ -1264,6 +1288,27 @@ static uint32_t write_fx_4_default_value(struct hlsl_type *value_type, struct hl - return offset; - } - -+static void write_fx_4_string_initializer(struct hlsl_ir_var *var, struct fx_write_context *fx) -+{ -+ uint32_t elements_count = hlsl_get_multiarray_size(var->data_type), i; -+ const struct hlsl_default_value *value = var->default_values; -+ struct vkd3d_bytecode_buffer *buffer = &fx->structured; -+ struct hlsl_ctx *ctx = fx->ctx; -+ uint32_t offset; -+ -+ if (!value) -+ { -+ hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "String objects have to be initialized."); -+ return; -+ } -+ -+ for (i = 0; i < elements_count; ++i, ++value) -+ { -+ offset = write_fx_4_string(value->string, fx); -+ put_u32(buffer, offset); -+ } -+} -+ - static void write_fx_4_numeric_variable(struct hlsl_ir_var *var, bool shared, struct fx_write_context *fx) - { - struct vkd3d_bytecode_buffer *buffer = &fx->structured; -@@ -1322,6 +1367,10 @@ static void write_fx_4_annotation(struct hlsl_ir_var *var, struct fx_write_conte - offset = write_fx_4_default_value(var->data_type, var->default_values, fx); - put_u32(buffer, offset); - } -+ else if (type->class == HLSL_CLASS_STRING) -+ { -+ write_fx_4_string_initializer(var, fx); -+ } - else - { - hlsl_fixme(ctx, &var->loc, "Writing annotations for type class %u is not implemented.", type->class); -@@ -1429,17 +1478,28 @@ static void write_fx_4_state_assignment(const struct hlsl_ir_var *var, struct hl - set_u32(buffer, rhs_offset, value_offset); - } - --static bool state_block_contains_state(const char *name, unsigned int start, struct hlsl_state_block *block) -+static bool state_block_contains_state(const struct hlsl_state_block_entry *entry, unsigned int start_index, -+ struct hlsl_state_block *block) - { - unsigned int i; - -- for (i = start; i < block->count; ++i) -+ for (i = start_index; i < block->count; ++i) - { -- if (block->entries[i]->is_function_call) -+ const struct hlsl_state_block_entry *cur = block->entries[i]; -+ -+ if (cur->is_function_call) - continue; - -- if (!ascii_strcasecmp(block->entries[i]->name, name)) -- return true; -+ if (ascii_strcasecmp(cur->name, entry->name)) -+ continue; -+ -+ if (cur->lhs_has_index != entry->lhs_has_index) -+ continue; -+ -+ if (cur->lhs_has_index && cur->lhs_index != entry->lhs_index) -+ continue; -+ -+ return true; - } - - return false; -@@ -1451,6 +1511,24 @@ struct replace_state_context - struct hlsl_ir_var *var; - }; - -+static bool lower_null_constant(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) -+{ -+ struct hlsl_ir_node *c; -+ -+ if (instr->type != HLSL_IR_CONSTANT) -+ return false; -+ if (instr->data_type->class != HLSL_CLASS_NULL) -+ return false; -+ -+ if (!(c = hlsl_new_uint_constant(ctx, 0, &instr->loc))) -+ return false; -+ -+ list_add_before(&instr->entry, &c->entry); -+ hlsl_replace_node(instr, c); -+ -+ return true; -+} -+ - static bool replace_state_block_constant(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) - { - struct replace_state_context *replace_context = context; -@@ -1480,17 +1558,6 @@ static bool replace_state_block_constant(struct hlsl_ctx *ctx, struct hlsl_ir_no - return true; - } - --static void fold_state_value(struct hlsl_ctx *ctx, struct hlsl_state_block_entry *entry) --{ -- bool progress; -- -- do -- { -- progress = hlsl_transform_ir(ctx, hlsl_fold_constant_exprs, entry->instrs, NULL); -- progress |= hlsl_copy_propagation_execute(ctx, entry->instrs); -- } while (progress); --} -- - enum state_property_component_type - { - FX_BOOL, -@@ -1505,6 +1572,9 @@ enum state_property_component_type - FX_TEXTURE, - FX_DEPTHSTENCILVIEW, - FX_RENDERTARGETVIEW, -+ FX_BLEND, -+ FX_VERTEXSHADER, -+ FX_PIXELSHADER, - }; - - static inline bool is_object_fx_type(enum state_property_component_type type) -@@ -1519,6 +1589,9 @@ static inline bool is_object_fx_type(enum state_property_component_type type) - case FX_TEXTURE: - case FX_RENDERTARGETVIEW: - case FX_DEPTHSTENCILVIEW: -+ case FX_BLEND: -+ case FX_VERTEXSHADER: -+ case FX_PIXELSHADER: - return true; - default: - return false; -@@ -1545,6 +1618,12 @@ static inline enum hlsl_type_class hlsl_type_class_from_fx_type(enum state_prope - return HLSL_CLASS_RENDER_TARGET_VIEW; - case FX_DEPTHSTENCILVIEW: - return HLSL_CLASS_DEPTH_STENCIL_VIEW; -+ case FX_BLEND: -+ return HLSL_CLASS_BLEND_STATE; -+ case FX_VERTEXSHADER: -+ return HLSL_CLASS_VERTEX_SHADER; -+ case FX_PIXELSHADER: -+ return HLSL_CLASS_PIXEL_SHADER; - default: - vkd3d_unreachable(); - } -@@ -1663,6 +1742,51 @@ static void resolve_fx_4_state_block_values(struct hlsl_ir_var *var, struct hlsl - { NULL } - }; - -+ static const struct rhs_named_value blend_values[] = -+ { -+ { "ZERO", 1 }, -+ { "ONE", 2 }, -+ { "SRC_COLOR", 3 }, -+ { "INV_SRC_COLOR", 4 }, -+ { "SRC_ALPHA", 5 }, -+ { "INV_SRC_ALPHA", 6 }, -+ { "DEST_ALPHA", 7 }, -+ { "INV_DEST_ALPHA", 8 }, -+ { "DEST_COLOR", 9 }, -+ { "INV_DEST_COLOR", 10 }, -+ { "SRC_ALPHA_SAT", 11 }, -+ { "BLEND_FACTOR", 14 }, -+ { "INV_BLEND_FACTOR", 15 }, -+ { "SRC1_COLOR", 16 }, -+ { "INV_SRC1_COLOR", 17 }, -+ { "SRC1_ALPHA", 18 }, -+ { "INV_SRC1_ALPHA", 19 }, -+ { NULL } -+ }; -+ -+ static const struct rhs_named_value blendop_values[] = -+ { -+ { "ADD", 1 }, -+ { "SUBTRACT", 2 }, -+ { "REV_SUBTRACT", 3 }, -+ { "MIN", 4 }, -+ { "MAX", 5 }, -+ { NULL } -+ }; -+ -+ static const struct rhs_named_value bool_values[] = -+ { -+ { "FALSE", 0 }, -+ { "TRUE", 1 }, -+ { NULL } -+ }; -+ -+ static const struct rhs_named_value null_values[] = -+ { -+ { "NULL", 0 }, -+ { NULL } -+ }; -+ - static const struct state - { - const char *name; -@@ -1676,29 +1800,33 @@ static void resolve_fx_4_state_block_values(struct hlsl_ir_var *var, struct hlsl - } - states[] = - { -- { "RasterizerState", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_RASTERIZER, 1, 1, 0 }, -- { "DepthStencilState", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_DEPTHSTENCIL, 1, 1, 1 }, -- -+ { "RasterizerState", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_RASTERIZER, 1, 1, 0 }, -+ { "DepthStencilState", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_DEPTHSTENCIL, 1, 1, 1 }, -+ { "BlendState", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_BLEND, 1, 1, 2 }, - { "RenderTargetView", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_RENDERTARGETVIEW, 1, 8, 3 }, - { "DepthStencilView", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_DEPTHSTENCILVIEW, 1, 1, 4 }, - -- { "DS_StencilRef", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 9 }, -+ { "VertexShader", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_VERTEXSHADER, 1, 1, 6 }, -+ { "PixelShader", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_PIXELSHADER, 1, 1, 7 }, -+ { "DS_StencilRef", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 9 }, -+ { "AB_BlendFactor", HLSL_CLASS_PASS, HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 10 }, -+ { "AB_SampleMask", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 11 }, - - { "FillMode", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 12, fill_values }, - { "CullMode", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 13, cull_values }, -- { "FrontCounterClockwise", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 14 }, -+ { "FrontCounterClockwise", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 14, bool_values }, - { "DepthBias", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 15 }, - { "DepthBiasClamp", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 16 }, - { "SlopeScaledDepthBias", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 17 }, -- { "DepthClipEnable", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 18 }, -- { "ScissorEnable", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 19 }, -- { "MultisampleEnable", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 20 }, -- { "AntializedLineEnable", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 21 }, -+ { "DepthClipEnable", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 18, bool_values }, -+ { "ScissorEnable", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 19, bool_values }, -+ { "MultisampleEnable", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 20, bool_values }, -+ { "AntializedLineEnable", HLSL_CLASS_RASTERIZER_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 21, bool_values }, - -- { "DepthEnable", HLSL_CLASS_DEPTH_STENCIL_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 22 }, -+ { "DepthEnable", HLSL_CLASS_DEPTH_STENCIL_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 22, bool_values }, - { "DepthWriteMask", HLSL_CLASS_DEPTH_STENCIL_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 23, depth_write_mask_values }, - { "DepthFunc", HLSL_CLASS_DEPTH_STENCIL_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 24, comparison_values }, -- { "StencilEnable", HLSL_CLASS_DEPTH_STENCIL_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 25 }, -+ { "StencilEnable", HLSL_CLASS_DEPTH_STENCIL_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 25, bool_values }, - { "StencilReadMask", HLSL_CLASS_DEPTH_STENCIL_STATE, HLSL_CLASS_SCALAR, FX_UINT8, 1, 1, 26 }, - { "StencilWriteMask", HLSL_CLASS_DEPTH_STENCIL_STATE, HLSL_CLASS_SCALAR, FX_UINT8, 1, 1, 27 }, - { "FrontFaceStencilFail", HLSL_CLASS_DEPTH_STENCIL_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 28, stencil_op_values }, -@@ -1720,12 +1848,45 @@ static void resolve_fx_4_state_block_values(struct hlsl_ir_var *var, struct hlsl - { "BorderColor", HLSL_CLASS_SAMPLER, HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 52 }, - { "MinLOD", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 53 }, - { "MaxLOD", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 54 }, -- { "Texture", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_TEXTURE, 1, 1, 55 }, -+ { "Texture", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_TEXTURE, 1, 1, 55, null_values }, - - { "HullShader", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_HULLSHADER, 1, 1, 56 }, - { "DomainShader", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_DOMAINSHADER, 1, 1, 57 }, - { "ComputeShader", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_COMPUTESHADER, 1, 1, 58 }, - }; -+ -+ static const struct state fx_4_blend_states[] = -+ { -+ { "AlphaToCoverageEnable", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 36, bool_values }, -+ { "BlendEnable", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 8, 37, bool_values }, -+ { "SrcBlend", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 38, blend_values }, -+ { "DestBlend", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 39, blend_values }, -+ { "BlendOp", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 40, blendop_values }, -+ { "SrcBlendAlpha", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 41, blend_values }, -+ { "DestBlendAlpha", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 42, blend_values }, -+ { "BlendOpAlpha", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 43, blendop_values }, -+ { "RenderTargetWriteMask", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT8, 1, 8, 44 }, -+ }; -+ -+ static const struct state fx_5_blend_states[] = -+ { -+ { "AlphaToCoverageEnable", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 36, bool_values }, -+ { "BlendEnable", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 8, 37, bool_values }, -+ { "SrcBlend", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 38, blend_values }, -+ { "DestBlend", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 39, blend_values }, -+ { "BlendOp", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 40, blendop_values }, -+ { "SrcBlendAlpha", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 41, blend_values }, -+ { "DestBlendAlpha", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 42, blend_values }, -+ { "BlendOpAlpha", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 43, blendop_values }, -+ { "RenderTargetWriteMask", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT8, 1, 8, 44 }, -+ }; -+ -+ struct state_table -+ { -+ const struct state *ptr; -+ unsigned int count; -+ } table; -+ - const struct hlsl_type *type = hlsl_get_multiarray_element_type(var->data_type); - struct replace_state_context replace_context; - struct hlsl_type *state_type = NULL; -@@ -1733,15 +1894,33 @@ static void resolve_fx_4_state_block_values(struct hlsl_ir_var *var, struct hlsl - const struct state *state = NULL; - struct hlsl_ctx *ctx = fx->ctx; - enum hlsl_base_type base_type; -- struct hlsl_ir_load *load; - unsigned int i; - -- for (i = 0; i < ARRAY_SIZE(states); ++i) -+ if (type->class == HLSL_CLASS_BLEND_STATE) - { -- if (type->class == states[i].container -- && !ascii_strcasecmp(entry->name, states[i].name)) -+ if (ctx->profile->major_version == 4) - { -- state = &states[i]; -+ table.ptr = fx_4_blend_states; -+ table.count = ARRAY_SIZE(fx_4_blend_states); -+ } -+ else -+ { -+ table.ptr = fx_5_blend_states; -+ table.count = ARRAY_SIZE(fx_5_blend_states); -+ } -+ } -+ else -+ { -+ table.ptr = states; -+ table.count = ARRAY_SIZE(states); -+ } -+ -+ for (i = 0; i < table.count; ++i) -+ { -+ if (type->class == table.ptr[i].container -+ && !ascii_strcasecmp(entry->name, table.ptr[i].name)) -+ { -+ state = &table.ptr[i]; - break; - } - } -@@ -1786,8 +1965,9 @@ static void resolve_fx_4_state_block_values(struct hlsl_ir_var *var, struct hlsl - replace_context.var = var; - - /* Turn named constants to actual constants. */ -+ hlsl_transform_ir(ctx, lower_null_constant, entry->instrs, NULL); - hlsl_transform_ir(ctx, replace_state_block_constant, entry->instrs, &replace_context); -- fold_state_value(ctx, entry); -+ hlsl_run_const_passes(ctx, entry->instrs); - - /* Now cast and run folding again. */ - -@@ -1798,7 +1978,8 @@ static void resolve_fx_4_state_block_values(struct hlsl_ir_var *var, struct hlsl - switch (node->type) - { - case HLSL_IR_LOAD: -- load = hlsl_ir_load(node); -+ { -+ struct hlsl_ir_load *load = hlsl_ir_load(node); - - if (load->src.path_len) - hlsl_fixme(ctx, &ctx->location, "Arrays are not supported for RHS."); -@@ -1810,6 +1991,26 @@ static void resolve_fx_4_state_block_values(struct hlsl_ir_var *var, struct hlsl - } - - break; -+ } -+ case HLSL_IR_CONSTANT: -+ { -+ struct hlsl_ir_constant *c = hlsl_ir_constant(node); -+ struct hlsl_type *data_type = c->node.data_type; -+ -+ if (data_type->class == HLSL_CLASS_SCALAR && data_type->e.numeric.type == HLSL_TYPE_UINT) -+ { -+ if (c->value.u[0].u != 0) -+ hlsl_error(ctx, &ctx->location, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, -+ "Only 0 integer constants are allowed for object-typed fields."); -+ } -+ else -+ { -+ hlsl_error(ctx, &ctx->location, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, -+ "Unexpected constant used for object-typed field."); -+ } -+ -+ break; -+ } - default: - hlsl_fixme(ctx, &ctx->location, "Unhandled node type for object-typed field."); - } -@@ -1857,11 +2058,27 @@ static void resolve_fx_4_state_block_values(struct hlsl_ir_var *var, struct hlsl - hlsl_src_remove(entry->args); - hlsl_src_from_node(entry->args, cast); - -- fold_state_value(ctx, entry); -+ hlsl_run_const_passes(ctx, entry->instrs); - } - } - --static unsigned int decompose_fx_4_state_block(struct hlsl_ir_var *var, struct hlsl_state_block *block, -+static bool decompose_fx_4_state_add_entries(struct hlsl_state_block *block, unsigned int entry_index, -+ unsigned int count) -+{ -+ if (!vkd3d_array_reserve((void **)&block->entries, &block->capacity, block->count + count, sizeof(*block->entries))) -+ return false; -+ -+ if (entry_index != block->count - 1) -+ { -+ memmove(&block->entries[entry_index + count + 1], &block->entries[entry_index + 1], -+ (block->count - entry_index - 1) * sizeof(*block->entries)); -+ } -+ block->count += count; -+ -+ return true; -+} -+ -+static unsigned int decompose_fx_4_state_function_call(struct hlsl_ir_var *var, struct hlsl_state_block *block, - unsigned int entry_index, struct fx_write_context *fx) - { - struct hlsl_state_block_entry *entry = block->entries[entry_index]; -@@ -1891,15 +2108,8 @@ static unsigned int decompose_fx_4_state_block(struct hlsl_ir_var *var, struct h - return 1; - } - -- if (!vkd3d_array_reserve((void **)&block->entries, &block->capacity, block->count + entry->args_count - 1, -- sizeof(*block->entries))) -+ if (!decompose_fx_4_state_add_entries(block, entry_index, entry->args_count - 1)) - return 1; -- if (entry_index != block->count - 1) -- { -- memmove(&block->entries[entry_index + entry->args_count], &block->entries[entry_index + 1], -- (block->count - entry_index - 1) * sizeof(*block->entries)); -- } -- block->count += entry->args_count - 1; - - get_state_block_function_components(info, components, entry->args_count); - -@@ -1915,6 +2125,62 @@ static unsigned int decompose_fx_4_state_block(struct hlsl_ir_var *var, struct h - return entry->args_count; - } - -+/* For some states assignment sets all of the elements. This behaviour is limited to certain states of BlendState -+ object, and only when fx_5_0 profile is used. */ -+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) -+{ -+ static const char *states[] = { "SrcBlend", "DestBlend", "BlendOp", "SrcBlendAlpha", "DestBlendAlpha", "BlendOpAlpha" }; -+ 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; -+ struct hlsl_ctx *ctx = fx->ctx; -+ bool found = false; -+ unsigned int i; -+ -+ if (type->class != HLSL_CLASS_BLEND_STATE) -+ return 1; -+ if (ctx->profile->major_version != 5) -+ return 1; -+ if (entry->lhs_has_index) -+ return 1; -+ -+ for (i = 0; i < ARRAY_SIZE(states); ++i) -+ { -+ if (!ascii_strcasecmp(entry->name, states[i])) -+ { -+ found = true; -+ break; -+ } -+ } -+ -+ if (!found) -+ return 1; -+ -+ if (!decompose_fx_4_state_add_entries(block, entry_index, array_size - 1)) -+ return 1; -+ -+ block->entries[entry_index]->lhs_has_index = true; -+ for (i = 1; i < array_size; ++i) -+ { -+ block->entries[entry_index + i] = clone_stateblock_entry(ctx, entry, -+ entry->name, true, i, 0); -+ } -+ -+ return array_size; -+} -+ -+static unsigned int decompose_fx_4_state_block(struct hlsl_ir_var *var, struct hlsl_state_block *block, -+ unsigned int entry_index, struct fx_write_context *fx) -+{ -+ struct hlsl_state_block_entry *entry = block->entries[entry_index]; -+ -+ if (entry->is_function_call) -+ return decompose_fx_4_state_function_call(var, block, entry_index, fx); -+ -+ return decompose_fx_4_state_block_expand_array(var, block, entry_index, fx); -+} -+ - static void write_fx_4_state_block(struct hlsl_ir_var *var, unsigned int block_index, - uint32_t count_offset, struct fx_write_context *fx) - { -@@ -1936,7 +2202,7 @@ static void write_fx_4_state_block(struct hlsl_ir_var *var, unsigned int block_i - struct hlsl_state_block_entry *entry = block->entries[i]; - - /* Skip if property is reassigned later. This will use the last assignment. */ -- if (state_block_contains_state(entry->name, i + 1, block)) -+ if (state_block_contains_state(entry, i + 1, block)) - continue; - - /* Resolve special constant names and property names. */ -@@ -2069,6 +2335,16 @@ static void write_fx_4_object_variable(struct hlsl_ir_var *var, struct fx_write_ - fx->rasterizer_state_count += elements_count; - break; - -+ case HLSL_CLASS_BLEND_STATE: -+ write_fx_4_state_object_initializer(var, fx); -+ fx->blend_state_count += elements_count; -+ break; -+ -+ case HLSL_CLASS_STRING: -+ write_fx_4_string_initializer(var, fx); -+ fx->string_count += elements_count; -+ break; -+ - default: - hlsl_fixme(ctx, &ctx->location, "Writing initializer for object class %u is not implemented.", - type->class); -@@ -2170,6 +2446,9 @@ static bool is_supported_object_variable(const struct hlsl_ctx *ctx, const struc - case HLSL_CLASS_RENDER_TARGET_VIEW: - case HLSL_CLASS_SAMPLER: - case HLSL_CLASS_TEXTURE: -+ case HLSL_CLASS_BLEND_STATE: -+ case HLSL_CLASS_VERTEX_SHADER: -+ case HLSL_CLASS_STRING: - return true; - case HLSL_CLASS_COMPUTE_SHADER: - case HLSL_CLASS_DOMAIN_SHADER: -@@ -2183,8 +2462,6 @@ static bool is_supported_object_variable(const struct hlsl_ctx *ctx, const struc - if (type->e.resource.rasteriser_ordered) - return false; - return true; -- case HLSL_CLASS_VERTEX_SHADER: -- return true; - - default: - return false; -@@ -2237,10 +2514,10 @@ static int hlsl_fx_4_write(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out) - put_u32(&buffer, fx.shared_object_count); - put_u32(&buffer, fx.technique_count); - size_offset = put_u32(&buffer, 0); /* Unstructured size. */ -- put_u32(&buffer, 0); /* String count. */ -+ put_u32(&buffer, fx.string_count); - put_u32(&buffer, fx.texture_count); - put_u32(&buffer, fx.depth_stencil_state_count); -- put_u32(&buffer, 0); /* Blend state count. */ -+ put_u32(&buffer, fx.blend_state_count); - put_u32(&buffer, fx.rasterizer_state_count); - put_u32(&buffer, fx.sampler_state_count); - put_u32(&buffer, fx.rtv_count); -@@ -2295,10 +2572,10 @@ static int hlsl_fx_5_write(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out) - put_u32(&buffer, fx.shared_object_count); - put_u32(&buffer, fx.technique_count); - size_offset = put_u32(&buffer, 0); /* Unstructured size. */ -- put_u32(&buffer, 0); /* String count. */ -+ put_u32(&buffer, fx.string_count); - put_u32(&buffer, fx.texture_count); - put_u32(&buffer, fx.depth_stencil_state_count); -- put_u32(&buffer, 0); /* Blend state count. */ -+ put_u32(&buffer, fx.blend_state_count); - put_u32(&buffer, fx.rasterizer_state_count); - put_u32(&buffer, fx.sampler_state_count); - put_u32(&buffer, fx.rtv_count); -diff --git a/libs/vkd3d/libs/vkd3d-shader/glsl.c b/libs/vkd3d/libs/vkd3d-shader/glsl.c -index 10e12ea56f2..d1f02ab568b 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/glsl.c -+++ b/libs/vkd3d/libs/vkd3d-shader/glsl.c -@@ -115,7 +115,7 @@ static void glsl_src_init(struct glsl_src *glsl_src, struct vkd3d_glsl_generator - - if (reg->non_uniform) - vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, -- "Internal compiler error: Unhandled 'non-uniform' modifer."); -+ "Internal compiler error: Unhandled 'non-uniform' modifier."); - if (vsir_src->modifiers) - vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, - "Internal compiler error: Unhandled source modifier(s) %#x.", vsir_src->modifiers); -@@ -138,10 +138,10 @@ static uint32_t glsl_dst_init(struct glsl_dst *glsl_dst, struct vkd3d_glsl_gener - - if (ins->flags & VKD3DSI_PRECISE_XYZW) - vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, -- "Internal compiler error: Unhandled 'precise' modifer."); -+ "Internal compiler error: Unhandled 'precise' modifier."); - if (vsir_dst->reg.non_uniform) - vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, -- "Internal compiler error: Unhandled 'non-uniform' modifer."); -+ "Internal compiler error: Unhandled 'non-uniform' modifier."); - - glsl_dst->vsir = vsir_dst; - glsl_dst->register_name = vkd3d_string_buffer_get(&gen->string_buffers); -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c -index 7f85195382d..bd5baacd83d 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c -@@ -167,7 +167,14 @@ void hlsl_free_var(struct hlsl_ir_var *decl) - for (k = 0; k <= HLSL_REGSET_LAST_OBJECT; ++k) - vkd3d_free((void *)decl->objects_usage[k]); - -- vkd3d_free(decl->default_values); -+ if (decl->default_values) -+ { -+ unsigned int component_count = hlsl_type_component_count(decl->data_type); -+ -+ for (k = 0; k < component_count; ++k) -+ vkd3d_free((void *)decl->default_values[k].string); -+ vkd3d_free(decl->default_values); -+ } - - for (i = 0; i < decl->state_block_count; ++i) - hlsl_free_state_block(decl->state_blocks[i]); -@@ -385,6 +392,8 @@ static void hlsl_type_calculate_reg_size(struct hlsl_ctx *ctx, struct hlsl_type - case HLSL_CLASS_DOMAIN_SHADER: - case HLSL_CLASS_HULL_SHADER: - case HLSL_CLASS_GEOMETRY_SHADER: -+ case HLSL_CLASS_BLEND_STATE: -+ case HLSL_CLASS_NULL: - break; - } - } -@@ -459,6 +468,8 @@ static bool type_is_single_component(const struct hlsl_type *type) - case HLSL_CLASS_DOMAIN_SHADER: - case HLSL_CLASS_HULL_SHADER: - case HLSL_CLASS_GEOMETRY_SHADER: -+ case HLSL_CLASS_BLEND_STATE: -+ case HLSL_CLASS_NULL: - return true; - - case HLSL_CLASS_VECTOR: -@@ -615,6 +626,7 @@ unsigned int hlsl_type_get_component_offset(struct hlsl_ctx *ctx, struct hlsl_ty - case HLSL_CLASS_DOMAIN_SHADER: - case HLSL_CLASS_HULL_SHADER: - case HLSL_CLASS_GEOMETRY_SHADER: -+ case HLSL_CLASS_BLEND_STATE: - VKD3D_ASSERT(idx == 0); - break; - -@@ -624,6 +636,7 @@ unsigned int hlsl_type_get_component_offset(struct hlsl_ctx *ctx, struct hlsl_ty - case HLSL_CLASS_VOID: - case HLSL_CLASS_SCALAR: - case HLSL_CLASS_CONSTANT_BUFFER: -+ case HLSL_CLASS_NULL: - vkd3d_unreachable(); - } - type = next_type; -@@ -922,6 +935,7 @@ static const char * get_case_insensitive_typename(const char *name) - "texture", - "vector", - "vertexshader", -+ "string", - }; - unsigned int i; - -@@ -1019,6 +1033,8 @@ unsigned int hlsl_type_component_count(const struct hlsl_type *type) - case HLSL_CLASS_DOMAIN_SHADER: - case HLSL_CLASS_HULL_SHADER: - case HLSL_CLASS_GEOMETRY_SHADER: -+ case HLSL_CLASS_BLEND_STATE: -+ case HLSL_CLASS_NULL: - return 1; - - case HLSL_CLASS_EFFECT_GROUP: -@@ -1110,6 +1126,8 @@ bool hlsl_types_are_equal(const struct hlsl_type *t1, const struct hlsl_type *t2 - case HLSL_CLASS_DOMAIN_SHADER: - case HLSL_CLASS_HULL_SHADER: - case HLSL_CLASS_GEOMETRY_SHADER: -+ case HLSL_CLASS_BLEND_STATE: -+ case HLSL_CLASS_NULL: - return true; - } - -@@ -1459,7 +1477,7 @@ struct hlsl_ir_node *hlsl_new_constant(struct hlsl_ctx *ctx, struct hlsl_type *t - { - struct hlsl_ir_constant *c; - -- VKD3D_ASSERT(type->class <= HLSL_CLASS_VECTOR); -+ VKD3D_ASSERT(type->class <= HLSL_CLASS_VECTOR || type->class == HLSL_CLASS_NULL); - - if (!(c = hlsl_alloc(ctx, sizeof(*c)))) - return NULL; -@@ -1522,6 +1540,12 @@ struct hlsl_ir_node *hlsl_new_string_constant(struct hlsl_ctx *ctx, const char * - return &s->node; - } - -+struct hlsl_ir_node *hlsl_new_null_constant(struct hlsl_ctx *ctx, const struct vkd3d_shader_location *loc) -+{ -+ struct hlsl_constant_value value = { 0 }; -+ return hlsl_new_constant(ctx, ctx->builtin_types.null, &value, loc); -+} -+ - struct hlsl_ir_node *hlsl_new_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, - struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS], - struct hlsl_type *data_type, const struct vkd3d_shader_location *loc) -@@ -2562,6 +2586,8 @@ struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const stru - case HLSL_CLASS_DOMAIN_SHADER: - case HLSL_CLASS_HULL_SHADER: - case HLSL_CLASS_GEOMETRY_SHADER: -+ case HLSL_CLASS_BLEND_STATE: -+ case HLSL_CLASS_NULL: - break; - } - -@@ -3262,9 +3288,15 @@ void hlsl_dump_var_default_values(const struct hlsl_ir_var *var) - vkd3d_string_buffer_printf(&buffer, "var \"%s\" default values:", var->name); - for (k = 0; k < component_count; ++k) - { -- if (k % 4 == 0) -+ bool is_string = var->default_values[k].string; -+ -+ if (k % 4 == 0 || is_string) - vkd3d_string_buffer_printf(&buffer, "\n "); -- vkd3d_string_buffer_printf(&buffer, " 0x%08x", var->default_values[k].value.u); -+ -+ if (is_string) -+ vkd3d_string_buffer_printf(&buffer, " %s", debugstr_a(var->default_values[k].string)); -+ else -+ vkd3d_string_buffer_printf(&buffer, " 0x%08x", var->default_values[k].number.u); - } - vkd3d_string_buffer_printf(&buffer, "\n"); - -@@ -3922,8 +3954,10 @@ static void declare_predefined_types(struct hlsl_ctx *ctx) - ctx->builtin_types.sampler[bt] = type; - } - -- ctx->builtin_types.string = hlsl_new_simple_type(ctx, "STRING", HLSL_CLASS_STRING); - ctx->builtin_types.Void = hlsl_new_simple_type(ctx, "void", HLSL_CLASS_VOID); -+ ctx->builtin_types.null = hlsl_new_type(ctx, "NULL", HLSL_CLASS_NULL, HLSL_TYPE_UINT, 1, 1); -+ ctx->builtin_types.string = hlsl_new_simple_type(ctx, "string", HLSL_CLASS_STRING); -+ hlsl_scope_add_type(ctx->globals, ctx->builtin_types.string); - hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "DepthStencilView", HLSL_CLASS_DEPTH_STENCIL_VIEW)); - hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "DepthStencilState", HLSL_CLASS_DEPTH_STENCIL_STATE)); - hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "fxgroup", HLSL_CLASS_EFFECT_GROUP)); -@@ -3937,6 +3971,7 @@ static void declare_predefined_types(struct hlsl_ctx *ctx) - hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "DomainShader", HLSL_CLASS_DOMAIN_SHADER)); - hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "HullShader", HLSL_CLASS_HULL_SHADER)); - hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "GeometryShader", HLSL_CLASS_GEOMETRY_SHADER)); -+ hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "BlendState", HLSL_CLASS_BLEND_STATE)); - - for (i = 0; i < ARRAY_SIZE(effect_types); ++i) - { -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h -index 7e8cd774ae2..22e25b23988 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h -@@ -96,7 +96,9 @@ enum hlsl_type_class - HLSL_CLASS_HULL_SHADER, - HLSL_CLASS_GEOMETRY_SHADER, - HLSL_CLASS_CONSTANT_BUFFER, -+ HLSL_CLASS_BLEND_STATE, - HLSL_CLASS_VOID, -+ HLSL_CLASS_NULL, - }; - - enum hlsl_base_type -@@ -408,7 +410,7 @@ struct hlsl_attribute - - /* Reservation of a register and/or an offset for objects inside constant buffers, to be used as a - * starting point of their allocation. They are available through the register(·) and the -- * packoffset(·) syntaxes, respectivelly. -+ * packoffset(·) syntaxes, respectively. - * The constant buffer offset is measured register components. */ - struct hlsl_reg_reservation - { -@@ -454,8 +456,10 @@ struct hlsl_ir_var - * This pointer is NULL for others. */ - struct hlsl_default_value - { -+ /* Default value, in case the component is a string, otherwise it is NULL. */ -+ const char *string; - /* Default value, in case the component is a numeric value. */ -- union hlsl_constant_value_component value; -+ union hlsl_constant_value_component number; - } *default_values; - - /* A dynamic array containing the state block on the variable's declaration, if any. -@@ -998,6 +1002,7 @@ struct hlsl_ctx - struct hlsl_type *sampler[HLSL_SAMPLER_DIM_LAST_SAMPLER + 1]; - struct hlsl_type *string; - struct hlsl_type *Void; -+ struct hlsl_type *null; - } builtin_types; - - /* List of the instruction nodes for initializing static variables. */ -@@ -1450,6 +1455,7 @@ struct hlsl_type *hlsl_new_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim - struct hlsl_type *hlsl_new_cb_type(struct hlsl_ctx *ctx, struct hlsl_type *format); - 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); - struct hlsl_ir_node *hlsl_new_unary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg, - const struct vkd3d_shader_location *loc); - struct hlsl_ir_var *hlsl_new_var(struct hlsl_ctx *ctx, const char *name, struct hlsl_type *type, -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.l b/libs/vkd3d/libs/vkd3d-shader/hlsl.l -index b4db142f6c2..0c02b27817e 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl.l -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.l -@@ -107,6 +107,7 @@ matrix {return KW_MATRIX; } - namespace {return KW_NAMESPACE; } - nointerpolation {return KW_NOINTERPOLATION; } - noperspective {return KW_NOPERSPECTIVE; } -+NULL {return KW_NULL; } - out {return KW_OUT; } - packoffset {return KW_PACKOFFSET; } - pass {return KW_PASS; } -@@ -144,6 +145,7 @@ stateblock {return KW_STATEBLOCK; } - stateblock_state {return KW_STATEBLOCK_STATE; } - static {return KW_STATIC; } - string {return KW_STRING; } -+String {return KW_STRING; } - struct {return KW_STRUCT; } - switch {return KW_SWITCH; } - tbuffer {return KW_TBUFFER; } -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y -index 30bd53d0c49..3f319dea0d8 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y -@@ -304,6 +304,26 @@ static bool implicit_compatible_data_types(struct hlsl_ctx *ctx, struct hlsl_typ - } - } - -+ if (src->class == HLSL_CLASS_NULL) -+ { -+ switch (dst->class) -+ { -+ case HLSL_CLASS_DEPTH_STENCIL_STATE: -+ case HLSL_CLASS_DEPTH_STENCIL_VIEW: -+ case HLSL_CLASS_PIXEL_SHADER: -+ case HLSL_CLASS_RASTERIZER_STATE: -+ case HLSL_CLASS_RENDER_TARGET_VIEW: -+ case HLSL_CLASS_SAMPLER: -+ case HLSL_CLASS_STRING: -+ case HLSL_CLASS_TEXTURE: -+ case HLSL_CLASS_UAV: -+ case HLSL_CLASS_VERTEX_SHADER: -+ return true; -+ default: -+ break; -+ } -+ } -+ - return hlsl_types_are_componentwise_equal(ctx, src, dst); - } - -@@ -331,6 +351,9 @@ static struct hlsl_ir_node *add_cast(struct hlsl_ctx *ctx, struct hlsl_block *bl - if (hlsl_types_are_equal(src_type, dst_type)) - return node; - -+ if (src_type->class == HLSL_CLASS_NULL) -+ return node; -+ - if (src_type->class > HLSL_CLASS_VECTOR || dst_type->class > HLSL_CLASS_VECTOR) - { - unsigned int src_comp_count = hlsl_type_component_count(src_type); -@@ -575,11 +598,10 @@ static void check_loop_attributes(struct hlsl_ctx *ctx, const struct parse_attri - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "Unroll attribute can't be used with 'fastopt' attribute."); - } - --static union hlsl_constant_value_component evaluate_static_expression(struct hlsl_ctx *ctx, -+static struct hlsl_default_value evaluate_static_expression(struct hlsl_ctx *ctx, - struct hlsl_block *block, struct hlsl_type *dst_type, const struct vkd3d_shader_location *loc) - { -- union hlsl_constant_value_component ret = {0}; -- struct hlsl_ir_constant *constant; -+ struct hlsl_default_value ret = {0}; - struct hlsl_ir_node *node; - struct hlsl_block expr; - struct hlsl_src src; -@@ -631,8 +653,16 @@ static union hlsl_constant_value_component evaluate_static_expression(struct hls - - if (node->type == HLSL_IR_CONSTANT) - { -- constant = hlsl_ir_constant(node); -- ret = constant->value.u[0]; -+ struct hlsl_ir_constant *constant = hlsl_ir_constant(node); -+ -+ ret.number = constant->value.u[0]; -+ } -+ else if (node->type == HLSL_IR_STRING_CONSTANT) -+ { -+ struct hlsl_ir_string_constant *string = hlsl_ir_string_constant(node); -+ -+ if (!(ret.string = vkd3d_strdup(string->string))) -+ return ret; - } - else if (node->type == HLSL_IR_STRING_CONSTANT) - { -@@ -652,10 +682,11 @@ static union hlsl_constant_value_component evaluate_static_expression(struct hls - static unsigned int evaluate_static_expression_as_uint(struct hlsl_ctx *ctx, struct hlsl_block *block, - const struct vkd3d_shader_location *loc) - { -- union hlsl_constant_value_component res; -+ struct hlsl_default_value res; - - res = evaluate_static_expression(ctx, block, hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), loc); -- return res.u; -+ VKD3D_ASSERT(!res.string); -+ return res.number.u; - } - - static struct hlsl_block *create_loop(struct hlsl_ctx *ctx, enum loop_type type, -@@ -1868,49 +1899,51 @@ static struct hlsl_ir_node *add_binary_dot_expr(struct hlsl_ctx *ctx, struct hls - return add_expr(ctx, instrs, op, args, ret_type, loc); - } - --static struct hlsl_block *add_binary_expr_merge(struct hlsl_ctx *ctx, struct hlsl_block *block1, -- struct hlsl_block *block2, enum hlsl_ir_expr_op op, const struct vkd3d_shader_location *loc) -+static struct hlsl_ir_node *add_binary_expr(struct hlsl_ctx *ctx, struct hlsl_block *block, enum hlsl_ir_expr_op op, -+ struct hlsl_ir_node *lhs, struct hlsl_ir_node *rhs, const struct vkd3d_shader_location *loc) - { -- struct hlsl_ir_node *arg1 = node_from_block(block1), *arg2 = node_from_block(block2); -- -- hlsl_block_add_block(block1, block2); -- destroy_block(block2); -- - switch (op) - { - case HLSL_OP2_ADD: - case HLSL_OP2_DIV: - case HLSL_OP2_MOD: - case HLSL_OP2_MUL: -- add_binary_arithmetic_expr(ctx, block1, op, arg1, arg2, loc); -- break; -+ return add_binary_arithmetic_expr(ctx, block, op, lhs, rhs, loc); - - case HLSL_OP2_BIT_AND: - case HLSL_OP2_BIT_OR: - case HLSL_OP2_BIT_XOR: -- add_binary_bitwise_expr(ctx, block1, op, arg1, arg2, loc); -- break; -+ return add_binary_bitwise_expr(ctx, block, op, lhs, rhs, loc); - - case HLSL_OP2_LESS: - case HLSL_OP2_GEQUAL: - case HLSL_OP2_EQUAL: - case HLSL_OP2_NEQUAL: -- add_binary_comparison_expr(ctx, block1, op, arg1, arg2, loc); -- break; -+ return add_binary_comparison_expr(ctx, block, op, lhs, rhs, loc); - - case HLSL_OP2_LOGIC_AND: - case HLSL_OP2_LOGIC_OR: -- add_binary_logical_expr(ctx, block1, op, arg1, arg2, loc); -- break; -+ return add_binary_logical_expr(ctx, block, op, lhs, rhs, loc); - - case HLSL_OP2_LSHIFT: - case HLSL_OP2_RSHIFT: -- add_binary_shift_expr(ctx, block1, op, arg1, arg2, loc); -- break; -+ return add_binary_shift_expr(ctx, block, op, lhs, rhs, loc); - - default: - vkd3d_unreachable(); - } -+} -+ -+static struct hlsl_block *add_binary_expr_merge(struct hlsl_ctx *ctx, struct hlsl_block *block1, -+ struct hlsl_block *block2, enum hlsl_ir_expr_op op, const struct vkd3d_shader_location *loc) -+{ -+ struct hlsl_ir_node *arg1 = node_from_block(block1), *arg2 = node_from_block(block2); -+ -+ hlsl_block_add_block(block1, block2); -+ destroy_block(block2); -+ -+ if (add_binary_expr(ctx, block1, op, arg1, arg2, loc) == NULL) -+ return NULL; - - return block1; - } -@@ -2034,7 +2067,7 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct hlsl_blo - enum hlsl_ir_expr_op op = op_from_assignment(assign_op); - - VKD3D_ASSERT(op); -- if (!(rhs = add_binary_arithmetic_expr(ctx, block, op, lhs, rhs, &rhs->loc))) -+ if (!(rhs = add_binary_expr(ctx, block, op, lhs, rhs, &rhs->loc))) - return NULL; - } - -@@ -2350,7 +2383,7 @@ static void initialize_var_components(struct hlsl_ctx *ctx, struct hlsl_block *i - - if (!hlsl_clone_block(ctx, &block, instrs)) - return; -- default_value.value = evaluate_static_expression(ctx, &block, dst_comp_type, &src->loc); -+ default_value = evaluate_static_expression(ctx, &block, dst_comp_type, &src->loc); - - if (dst->is_param) - dst_index = *store_index; -@@ -2908,14 +2941,17 @@ static bool add_user_call(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *fu - struct hlsl_ir_node *comp; - struct hlsl_block store_block; - -- value.u[0] = param->default_values[j].value; -- if (!(comp = hlsl_new_constant(ctx, type, &value, loc))) -- return false; -- hlsl_block_add_instr(args->instrs, comp); -+ if (!param->default_values[j].string) -+ { -+ value.u[0] = param->default_values[j].number; -+ if (!(comp = hlsl_new_constant(ctx, type, &value, loc))) -+ return false; -+ hlsl_block_add_instr(args->instrs, comp); - -- if (!hlsl_new_store_component(ctx, &store_block, ¶m_deref, j, comp)) -- return false; -- hlsl_block_add_block(args->instrs, &store_block); -+ if (!hlsl_new_store_component(ctx, &store_block, ¶m_deref, j, comp)) -+ return false; -+ hlsl_block_add_block(args->instrs, &store_block); -+ } - } - } - -@@ -6050,6 +6086,7 @@ static bool state_block_add_entry(struct hlsl_state_block *state_block, struct h - %token KW_NAMESPACE - %token KW_NOINTERPOLATION - %token KW_NOPERSPECTIVE -+%token KW_NULL - %token KW_OUT - %token KW_PACKOFFSET - %token KW_PASS -@@ -7304,12 +7341,6 @@ type_no_void: - { - validate_texture_format_type(ctx, $3, &@3); - -- if (hlsl_version_lt(ctx, 4, 1)) -- { -- hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, -- "Multisampled texture object declaration needs sample count for profile %s.", ctx->profile->name); -- } -- - $$ = hlsl_new_texture_type(ctx, $1, $3, 0); - } - | texture_ms_type '<' type ',' shift_expr '>' -@@ -7433,6 +7464,10 @@ type_no_void: - { - $$ = hlsl_get_type(ctx->cur_scope, "RasterizerState", true, true); - } -+ | KW_BLENDSTATE -+ { -+ $$ = hlsl_get_type(ctx->cur_scope, "BlendState", true, true); -+ } - - type: - type_no_void -@@ -8323,6 +8358,18 @@ primary_expr: - YYABORT; - } - } -+ | KW_NULL -+ { -+ struct hlsl_ir_node *c; -+ -+ if (!(c = hlsl_new_null_constant(ctx, &@1))) -+ YYABORT; -+ if (!($$ = make_block(ctx, c))) -+ { -+ hlsl_free_instr(c); -+ YYABORT; -+ } -+ } - | VAR_IDENTIFIER - { - struct hlsl_ir_load *load; -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -index 049461cdb7d..a695eefabf6 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -@@ -1648,6 +1648,8 @@ static bool copy_propagation_transform_load(struct hlsl_ctx *ctx, - case HLSL_CLASS_RENDER_TARGET_VIEW: - case HLSL_CLASS_DEPTH_STENCIL_VIEW: - case HLSL_CLASS_GEOMETRY_SHADER: -+ case HLSL_CLASS_BLEND_STATE: -+ case HLSL_CLASS_NULL: - break; - - case HLSL_CLASS_MATRIX: -diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c -index c1b8582af6d..6dbe30b1553 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/ir.c -+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c -@@ -3831,11 +3831,16 @@ static void vsir_cfg_compute_dominators(struct vsir_cfg *cfg) - { - struct vsir_block *block2 = &cfg->blocks[j]; - -- if (block2->label == 0) -+ if (block2->label == 0 || !vsir_block_dominates(block, block2)) - continue; - -- if (vsir_block_dominates(block, block2)) -- vkd3d_string_buffer_printf(&cfg->debug_buffer, " %u", block2->label); -+ if (cfg->debug_buffer.content_size > 512) -+ { -+ TRACE("%s...\n", cfg->debug_buffer.buffer); -+ vkd3d_string_buffer_clear(&cfg->debug_buffer); -+ vkd3d_string_buffer_printf(&cfg->debug_buffer, "Block %u dominates: ...", block->label); -+ } -+ vkd3d_string_buffer_printf(&cfg->debug_buffer, " %u", block2->label); - } - TRACE("%s\n", cfg->debug_buffer.buffer); - vkd3d_string_buffer_clear(&cfg->debug_buffer); -@@ -3927,7 +3932,16 @@ static enum vkd3d_result vsir_cfg_compute_loops(struct vsir_cfg *cfg) - vkd3d_string_buffer_printf(&cfg->debug_buffer, "Back edge %u -> %u with loop:", block->label, header->label); - - for (k = 0; k < loop->count; ++k) -+ { -+ if (cfg->debug_buffer.content_size > 512) -+ { -+ TRACE("%s...\n", cfg->debug_buffer.buffer); -+ vkd3d_string_buffer_clear(&cfg->debug_buffer); -+ vkd3d_string_buffer_printf(&cfg->debug_buffer, "Back edge %u -> %u with loop: ...", -+ block->label, header->label); -+ } - vkd3d_string_buffer_printf(&cfg->debug_buffer, " %u", loop->blocks[k]->label); -+ } - - TRACE("%s\n", cfg->debug_buffer.buffer); - vkd3d_string_buffer_clear(&cfg->debug_buffer); -@@ -4150,7 +4164,15 @@ static enum vkd3d_result vsir_cfg_sort_nodes(struct vsir_cfg *cfg) - vkd3d_string_buffer_printf(&cfg->debug_buffer, "Block order:"); - - for (i = 0; i < cfg->order.count; ++i) -+ { -+ if (cfg->debug_buffer.content_size > 512) -+ { -+ TRACE("%s...\n", cfg->debug_buffer.buffer); -+ vkd3d_string_buffer_clear(&cfg->debug_buffer); -+ vkd3d_string_buffer_printf(&cfg->debug_buffer, "Block order: ..."); -+ } - vkd3d_string_buffer_printf(&cfg->debug_buffer, " %u", cfg->order.blocks[i]->label); -+ } - - TRACE("%s\n", cfg->debug_buffer.buffer); - vkd3d_string_buffer_clear(&cfg->debug_buffer); -@@ -4204,7 +4226,7 @@ static enum vkd3d_result vsir_cfg_generate_synthetic_loop_intervals(struct vsir_ - ACTION_EXTEND, - } action = ACTION_CREATE_NEW; - -- /* We've already contructed loop intervals for the back -+ /* We've already constructed loop intervals for the back - * edges, there's nothing more to do. */ - if (vsir_block_dominates(successor, block)) - continue; -@@ -4462,7 +4484,7 @@ static enum vkd3d_result vsir_cfg_build_structured_program(struct vsir_cfg *cfg) - VKD3D_ASSERT(inner_loop->type == STRUCTURE_TYPE_LOOP); - - /* Otherwise, if one of the branches is -- * continueing the inner loop we're inside, -+ * continue-ing the inner loop we're inside, - * make sure it's the false branch (because it - * will be optimized out later). */ - if (action_true.jump_type == JUMP_CONTINUE && action_true.target == inner_loop->u.loop.idx) -@@ -5104,14 +5126,14 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_jump(struct vsir_cfg *cfg, - struct vsir_cfg_emit_target *target = cfg->target; - const struct vkd3d_shader_location no_loc = {0}; - /* Encode the jump target as the loop index plus a bit to remember whether -- * we're breaking or continueing. */ -+ * we're breaking or continue-ing. */ - unsigned int jump_target = jump->target << 1; - enum vkd3d_shader_opcode opcode; - - switch (jump->type) - { - case JUMP_CONTINUE: -- /* If we're continueing the loop we're directly inside, then we can emit a -+ /* If we're continue-ing the loop we're directly inside, then we can emit a - * `continue'. Otherwise we first have to break all the loops between here - * and the loop to continue, recording our intention to continue - * in the lowest bit of jump_target. */ -diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c -index d6d5bbc1c07..84f641cc316 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/tpf.c -+++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c -@@ -22,6 +22,7 @@ - */ - - #include "hlsl.h" -+#include "vkd3d_shader_private.h" - - #define SM4_MAX_SRC_COUNT 6 - #define SM4_MAX_DST_COUNT 2 -@@ -3006,6 +3007,8 @@ static D3D_SHADER_VARIABLE_CLASS sm4_class(const struct hlsl_type *type) - case HLSL_CLASS_DOMAIN_SHADER: - case HLSL_CLASS_HULL_SHADER: - case HLSL_CLASS_GEOMETRY_SHADER: -+ case HLSL_CLASS_BLEND_STATE: -+ case HLSL_CLASS_NULL: - break; - } - vkd3d_unreachable(); -@@ -3107,8 +3110,6 @@ static D3D_SHADER_INPUT_TYPE sm4_resource_type(const struct hlsl_type *type) - { - switch (type->class) - { -- case HLSL_CLASS_ARRAY: -- return sm4_resource_type(type->e.array.type); - case HLSL_CLASS_SAMPLER: - return D3D_SIT_SAMPLER; - case HLSL_CLASS_TEXTURE: -@@ -3124,9 +3125,6 @@ static D3D_SHADER_INPUT_TYPE sm4_resource_type(const struct hlsl_type *type) - - static D3D_RESOURCE_RETURN_TYPE sm4_resource_format(const struct hlsl_type *type) - { -- if (type->class == HLSL_CLASS_ARRAY) -- return sm4_resource_format(type->e.array.type); -- - switch (type->e.resource.format->e.numeric.type) - { - case HLSL_TYPE_DOUBLE: -@@ -3151,9 +3149,6 @@ static D3D_RESOURCE_RETURN_TYPE sm4_resource_format(const struct hlsl_type *type - - static D3D_SRV_DIMENSION sm4_rdef_resource_dimension(const struct hlsl_type *type) - { -- if (type->class == HLSL_CLASS_ARRAY) -- return sm4_rdef_resource_dimension(type->e.array.type); -- - switch (type->sampler_dim) - { - case HLSL_SAMPLER_DIM_1D: -@@ -3190,11 +3185,18 @@ struct extern_resource - const struct hlsl_buffer *buffer; - - char *name; -- struct hlsl_type *data_type; - bool is_user_packed; - -+ /* The data type of a single component of the resource. -+ * This might be different from the data type of the resource itself in 4.0 -+ * profiles, where an array (or multi-dimensional array) is handled as a -+ * single resource, unlike in 5.0. */ -+ struct hlsl_type *component_type; -+ - enum hlsl_regset regset; - unsigned int id, space, index, bind_count; -+ -+ struct vkd3d_shader_location loc; - }; - - static int sm4_compare_extern_resources(const void *a, const void *b) -@@ -3289,14 +3291,16 @@ static struct extern_resource *sm4_get_extern_resources(struct hlsl_ctx *ctx, un - extern_resources[*count].buffer = NULL; - - extern_resources[*count].name = name; -- extern_resources[*count].data_type = component_type; - extern_resources[*count].is_user_packed = !!var->reg_reservation.reg_type; - -+ extern_resources[*count].component_type = component_type; -+ - extern_resources[*count].regset = regset; - extern_resources[*count].id = var->regs[regset].id; - extern_resources[*count].space = var->regs[regset].space; - extern_resources[*count].index = var->regs[regset].index + regset_offset; - extern_resources[*count].bind_count = 1; -+ extern_resources[*count].loc = var->loc; - - ++*count; - } -@@ -3333,17 +3337,19 @@ static struct extern_resource *sm4_get_extern_resources(struct hlsl_ctx *ctx, un - extern_resources[*count].buffer = NULL; - - extern_resources[*count].name = name; -- extern_resources[*count].data_type = var->data_type; - /* For some reason 5.1 resources aren't marked as - * user-packed, but cbuffers still are. */ - extern_resources[*count].is_user_packed = hlsl_version_lt(ctx, 5, 1) - && !!var->reg_reservation.reg_type; - -+ extern_resources[*count].component_type = hlsl_type_get_component_type(ctx, var->data_type, 0); -+ - extern_resources[*count].regset = r; - extern_resources[*count].id = var->regs[r].id; - extern_resources[*count].space = var->regs[r].space; - extern_resources[*count].index = var->regs[r].index; - extern_resources[*count].bind_count = var->bind_count[r]; -+ extern_resources[*count].loc = var->loc; - - ++*count; - } -@@ -3374,14 +3380,16 @@ static struct extern_resource *sm4_get_extern_resources(struct hlsl_ctx *ctx, un - extern_resources[*count].buffer = buffer; - - extern_resources[*count].name = name; -- extern_resources[*count].data_type = NULL; - extern_resources[*count].is_user_packed = !!buffer->reservation.reg_type; - -+ extern_resources[*count].component_type = NULL; -+ - extern_resources[*count].regset = HLSL_REGSET_NUMERIC; - extern_resources[*count].id = buffer->reg.id; - extern_resources[*count].space = buffer->reg.space; - extern_resources[*count].index = buffer->reg.index; - extern_resources[*count].bind_count = 1; -+ extern_resources[*count].loc = buffer->loc; - - ++*count; - } -@@ -3458,13 +3466,13 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) - if (resource->buffer) - put_u32(&buffer, resource->buffer->type == HLSL_BUFFER_CONSTANT ? D3D_SIT_CBUFFER : D3D_SIT_TBUFFER); - else -- put_u32(&buffer, sm4_resource_type(resource->data_type)); -+ put_u32(&buffer, sm4_resource_type(resource->component_type)); - if (resource->regset == HLSL_REGSET_TEXTURES || resource->regset == HLSL_REGSET_UAVS) - { -- unsigned int dimx = hlsl_type_get_component_type(ctx, resource->data_type, 0)->e.resource.format->dimx; -+ unsigned int dimx = resource->component_type->e.resource.format->dimx; - -- put_u32(&buffer, sm4_resource_format(resource->data_type)); -- put_u32(&buffer, sm4_rdef_resource_dimension(resource->data_type)); -+ put_u32(&buffer, sm4_resource_format(resource->component_type)); -+ put_u32(&buffer, sm4_rdef_resource_dimension(resource->component_type)); - put_u32(&buffer, ~0u); /* FIXME: multisample count */ - flags |= (dimx - 1) << VKD3D_SM4_SIF_TEXTURE_COMPONENTS_SHIFT; - } -@@ -3593,6 +3601,13 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) - unsigned int comp_offset; - enum hlsl_regset regset; - -+ if (comp_type->class == HLSL_CLASS_STRING) -+ { -+ hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, -+ "Cannot write string default value."); -+ continue; -+ } -+ - comp_offset = hlsl_type_get_component_offset(ctx, var->data_type, k, ®set); - if (regset == HLSL_REGSET_NUMERIC) - { -@@ -3600,7 +3615,7 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) - hlsl_fixme(ctx, &var->loc, "Write double default values."); - - set_u32(&buffer, default_value_offset + comp_offset * sizeof(uint32_t), -- var->default_values[k].value.u); -+ var->default_values[k].number.u); - } - } - } -@@ -4269,7 +4284,6 @@ static void write_sm4_dcl_constant_buffer(const struct tpf_writer *tpf, const st - - static void write_sm4_dcl_samplers(const struct tpf_writer *tpf, const struct extern_resource *resource) - { -- struct hlsl_type *component_type; - unsigned int i; - struct sm4_instruction instr = - { -@@ -4279,13 +4293,11 @@ static void write_sm4_dcl_samplers(const struct tpf_writer *tpf, const struct ex - .dst_count = 1, - }; - -- component_type = hlsl_type_get_component_type(tpf->ctx, resource->data_type, 0); -+ VKD3D_ASSERT(resource->regset == HLSL_REGSET_SAMPLERS); - -- if (component_type->sampler_dim == HLSL_SAMPLER_DIM_COMPARISON) -+ if (resource->component_type->sampler_dim == HLSL_SAMPLER_DIM_COMPARISON) - instr.extra_bits |= VKD3D_SM4_SAMPLER_COMPARISON << VKD3D_SM4_SAMPLER_MODE_SHIFT; - -- VKD3D_ASSERT(resource->regset == HLSL_REGSET_SAMPLERS); -- - for (i = 0; i < resource->bind_count; ++i) - { - if (resource->var && !resource->var->objects_usage[HLSL_REGSET_SAMPLERS][i].used) -@@ -4317,11 +4329,12 @@ static void write_sm4_dcl_textures(const struct tpf_writer *tpf, const struct ex - enum hlsl_regset regset = uav ? HLSL_REGSET_UAVS : HLSL_REGSET_TEXTURES; - struct hlsl_type *component_type; - struct sm4_instruction instr; -+ bool multisampled; - unsigned int i; - - VKD3D_ASSERT(resource->regset == regset); - -- component_type = hlsl_type_get_component_type(tpf->ctx, resource->data_type, 0); -+ component_type = resource->component_type; - - for (i = 0; i < resource->bind_count; ++i) - { -@@ -4339,6 +4352,16 @@ static void write_sm4_dcl_textures(const struct tpf_writer *tpf, const struct ex - .idx_count = 1, - }; - -+ multisampled = component_type->sampler_dim == HLSL_SAMPLER_DIM_2DMS -+ || component_type->sampler_dim == HLSL_SAMPLER_DIM_2DMSARRAY; -+ -+ if (hlsl_version_lt(tpf->ctx, 4, 1) && multisampled && !component_type->sample_count) -+ { -+ hlsl_error(tpf->ctx, &resource->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, -+ "Multisampled texture object declaration needs sample count for profile %s.", -+ tpf->ctx->profile->name); -+ } -+ - if (hlsl_version_ge(tpf->ctx, 5, 1)) - { - VKD3D_ASSERT(!i); -@@ -4358,18 +4381,18 @@ static void write_sm4_dcl_textures(const struct tpf_writer *tpf, const struct ex - - if (uav) - { -- switch (resource->data_type->sampler_dim) -+ switch (component_type->sampler_dim) - { -- case HLSL_SAMPLER_DIM_STRUCTURED_BUFFER: -- instr.opcode = VKD3D_SM5_OP_DCL_UAV_STRUCTURED; -- instr.byte_stride = resource->data_type->e.resource.format->reg_size[HLSL_REGSET_NUMERIC] * 4; -- break; -- default: -- instr.opcode = VKD3D_SM5_OP_DCL_UAV_TYPED; -- break; -+ case HLSL_SAMPLER_DIM_STRUCTURED_BUFFER: -+ instr.opcode = VKD3D_SM5_OP_DCL_UAV_STRUCTURED; -+ instr.byte_stride = component_type->e.resource.format->reg_size[HLSL_REGSET_NUMERIC] * 4; -+ break; -+ default: -+ instr.opcode = VKD3D_SM5_OP_DCL_UAV_TYPED; -+ break; - } - -- if (resource->data_type->e.resource.rasteriser_ordered) -+ if (component_type->e.resource.rasteriser_ordered) - instr.opcode |= VKD3DSUF_RASTERISER_ORDERED_VIEW << VKD3D_SM5_UAV_FLAGS_SHIFT; - } - else -@@ -4378,11 +4401,8 @@ static void write_sm4_dcl_textures(const struct tpf_writer *tpf, const struct ex - } - instr.extra_bits |= (sm4_resource_dimension(component_type) << VKD3D_SM4_RESOURCE_TYPE_SHIFT); - -- if (component_type->sampler_dim == HLSL_SAMPLER_DIM_2DMS -- || component_type->sampler_dim == HLSL_SAMPLER_DIM_2DMSARRAY) -- { -+ if (multisampled) - instr.extra_bits |= component_type->sample_count << VKD3D_SM4_RESOURCE_SAMPLE_COUNT_SHIFT; -- } - - write_sm4_instruction(tpf, &instr); - } -@@ -6082,7 +6102,7 @@ static void write_sm4_sfi0(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) - extern_resources = sm4_get_extern_resources(ctx, &extern_resources_count); - for (unsigned int i = 0; i < extern_resources_count; ++i) - { -- if (extern_resources[i].data_type && extern_resources[i].data_type->e.resource.rasteriser_ordered) -+ if (extern_resources[i].component_type && extern_resources[i].component_type->e.resource.rasteriser_ordered) - *flags |= VKD3D_SM4_REQUIRES_ROVS; - } - sm4_free_extern_resources(extern_resources, extern_resources_count); -diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -index 13b4dab76d1..ef66a8ca07a 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -@@ -51,7 +51,6 @@ - #include "vkd3d_shader.h" - #include "wine/list.h" - --#include - #include - #include - #include -diff --git a/libs/vkd3d/libs/vkd3d/resource.c b/libs/vkd3d/libs/vkd3d/resource.c -index ac29088b9cb..6d6820d3752 100644 ---- a/libs/vkd3d/libs/vkd3d/resource.c -+++ b/libs/vkd3d/libs/vkd3d/resource.c -@@ -2184,7 +2184,7 @@ static HRESULT vkd3d_bind_heap_memory(struct d3d12_device *device, - goto allocate_memory; - } - -- /* Syncronisation is not required for binding, but vkMapMemory() may be called -+ /* Synchronisation is not required for binding, but vkMapMemory() may be called - * from another thread and it requires exclusive access. */ - vkd3d_mutex_lock(&heap->mutex); - -diff --git a/libs/vkd3d/libs/vkd3d/state.c b/libs/vkd3d/libs/vkd3d/state.c -index 0bdb7ea524d..519d1a2d85f 100644 ---- a/libs/vkd3d/libs/vkd3d/state.c -+++ b/libs/vkd3d/libs/vkd3d/state.c -@@ -635,14 +635,18 @@ static HRESULT d3d12_root_signature_init_push_constants(struct d3d12_root_signat - for (i = 0; i < desc->NumParameters; ++i) - { - const D3D12_ROOT_PARAMETER *p = &desc->pParameters[i]; -+ D3D12_SHADER_VISIBILITY visibility; -+ - if (p->ParameterType != D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS) - continue; - -- VKD3D_ASSERT(p->ShaderVisibility <= D3D12_SHADER_VISIBILITY_PIXEL); -- push_constants[p->ShaderVisibility].stageFlags = use_vk_heaps ? VK_SHADER_STAGE_ALL -- : stage_flags_from_visibility(p->ShaderVisibility); -- push_constants[p->ShaderVisibility].size += align(p->u.Constants.Num32BitValues, 4) * sizeof(uint32_t); -+ visibility = use_vk_heaps ? D3D12_SHADER_VISIBILITY_ALL : p->ShaderVisibility; -+ VKD3D_ASSERT(visibility <= D3D12_SHADER_VISIBILITY_PIXEL); -+ -+ push_constants[visibility].stageFlags = stage_flags_from_visibility(visibility); -+ push_constants[visibility].size += align(p->u.Constants.Num32BitValues, 4) * sizeof(uint32_t); - } -+ - if (push_constants[D3D12_SHADER_VISIBILITY_ALL].size) - { - /* When D3D12_SHADER_VISIBILITY_ALL is used we use a single push -diff --git a/libs/vkd3d/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/libs/vkd3d/vkd3d_private.h -index a4bd2202f39..ba4e2e8488d 100644 ---- a/libs/vkd3d/libs/vkd3d/vkd3d_private.h -+++ b/libs/vkd3d/libs/vkd3d/vkd3d_private.h -@@ -37,7 +37,6 @@ - #include "vkd3d.h" - #include "vkd3d_shader.h" - --#include - #include - #include - #include -@@ -679,7 +678,7 @@ static inline void *d3d12_desc_get_object_ref(const volatile struct d3d12_desc * - void *view; - - /* Some games, e.g. Shadow of the Tomb Raider, GRID 2019, and Horizon Zero Dawn, write descriptors -- * from multiple threads without syncronisation. This is apparently valid in Windows. */ -+ * from multiple threads without synchronisation. This is apparently valid in Windows. */ - for (;;) - { - do --- -2.43.0 - diff --git a/patches/vkd3d-latest/0003-Updated-vkd3d-to-738ecc9eb1ee65e426a4ea8186e44183775.patch b/patches/vkd3d-latest/0003-Updated-vkd3d-to-738ecc9eb1ee65e426a4ea8186e44183775.patch deleted file mode 100644 index 51c933b0..00000000 --- a/patches/vkd3d-latest/0003-Updated-vkd3d-to-738ecc9eb1ee65e426a4ea8186e44183775.patch +++ /dev/null @@ -1,204 +0,0 @@ -From b43ca0b2d66c89b21388ee6b4427c5f681a8ced1 Mon Sep 17 00:00:00 2001 -From: Alistair Leslie-Hughes -Date: Wed, 21 Aug 2024 06:59:06 +1000 -Subject: [PATCH] Updated vkd3d to 738ecc9eb1ee65e426a4ea8186e4418377580984. - ---- - libs/vkd3d/include/private/vkd3d_memory.h | 2 +- - libs/vkd3d/libs/vkd3d-shader/spirv.c | 78 +++++++++++++---------- - 2 files changed, 47 insertions(+), 33 deletions(-) - -diff --git a/libs/vkd3d/include/private/vkd3d_memory.h b/libs/vkd3d/include/private/vkd3d_memory.h -index e191dc11b73..b157fc07cb7 100644 ---- a/libs/vkd3d/include/private/vkd3d_memory.h -+++ b/libs/vkd3d/include/private/vkd3d_memory.h -@@ -43,7 +43,7 @@ static inline void *vkd3d_realloc(void *ptr, size_t size) - static inline void *vkd3d_calloc(size_t count, size_t size) - { - void *ptr; -- VKD3D_ASSERT(count <= ~(size_t)0 / size); -+ VKD3D_ASSERT(!size || count <= ~(size_t)0 / size); - if (!(ptr = calloc(count, size))) - ERR("Out of memory.\n"); - return ptr; -diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c -index bc8a7a5b28c..36574e8b1e5 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/spirv.c -+++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c -@@ -2156,6 +2156,8 @@ struct vkd3d_symbol_descriptor_array - unsigned int set; - unsigned int binding; - unsigned int push_constant_index; -+ bool write_only; -+ bool coherent; - }; - - struct vkd3d_symbol_register_data -@@ -2512,6 +2514,8 @@ static void spirv_compiler_destroy(struct spirv_compiler *compiler) - vkd3d_free(compiler->push_constants); - vkd3d_free(compiler->descriptor_offset_ids); - -+ vkd3d_free(compiler->spirv_parameter_info); -+ - vkd3d_spirv_builder_free(&compiler->spirv_builder); - - rb_destroy(&compiler->symbol_table, vkd3d_symbol_free, NULL); -@@ -6076,6 +6080,26 @@ static void spirv_compiler_emit_push_constant_buffers(struct spirv_compiler *com - } - } - -+static const struct vkd3d_shader_descriptor_info1 *spirv_compiler_get_descriptor_info( -+ struct spirv_compiler *compiler, enum vkd3d_shader_descriptor_type type, -+ const struct vkd3d_shader_register_range *range) -+{ -+ const struct vkd3d_shader_scan_descriptor_info1 *descriptor_info = compiler->scan_descriptor_info; -+ unsigned int register_last = (range->last == ~0u) ? range->first : range->last; -+ const struct vkd3d_shader_descriptor_info1 *d; -+ unsigned int i; -+ -+ for (i = 0; i < descriptor_info->descriptor_count; ++i) -+ { -+ d = &descriptor_info->descriptors[i]; -+ if (d->type == type && d->register_space == range->space && d->register_index <= range->first -+ && (d->count == ~0u || d->count > register_last - d->register_index)) -+ return d; -+ } -+ -+ return NULL; -+} -+ - struct vkd3d_descriptor_variable_info - { - const struct vkd3d_symbol *array_symbol; -@@ -6085,12 +6109,14 @@ struct vkd3d_descriptor_variable_info - static uint32_t spirv_compiler_build_descriptor_variable(struct spirv_compiler *compiler, - SpvStorageClass storage_class, uint32_t type_id, const struct vkd3d_shader_register *reg, - const struct vkd3d_shader_register_range *range, enum vkd3d_shader_resource_type resource_type, -- bool is_uav_counter, struct vkd3d_descriptor_variable_info *var_info) -+ bool is_uav, bool is_uav_counter, struct vkd3d_descriptor_variable_info *var_info) - { - struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; - struct vkd3d_descriptor_binding_address binding_address; - struct vkd3d_shader_descriptor_binding binding; -+ const struct vkd3d_shader_descriptor_info1 *d; - uint32_t array_type_id, ptr_type_id, var_id; -+ bool write_only = false, coherent = false; - struct vkd3d_symbol symbol; - struct rb_entry *entry; - -@@ -6116,6 +6142,14 @@ static uint32_t spirv_compiler_build_descriptor_variable(struct spirv_compiler * - array_type_id = vkd3d_spirv_get_op_type_runtime_array(builder, type_id); - ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, storage_class, array_type_id); - -+ if (is_uav) -+ { -+ d = spirv_compiler_get_descriptor_info(compiler, VKD3D_SHADER_DESCRIPTOR_TYPE_UAV, range); -+ write_only = !(d->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_READ); -+ /* ROVs are implicitly globally coherent. */ -+ coherent = d->uav_flags & (VKD3DSUF_GLOBALLY_COHERENT | VKD3DSUF_RASTERISER_ORDERED_VIEW); -+ } -+ - /* Declare one array variable per Vulkan binding, and use it for - * all array declarations which map to it. */ - symbol.type = VKD3D_SYMBOL_DESCRIPTOR_ARRAY; -@@ -6124,6 +6158,8 @@ static uint32_t spirv_compiler_build_descriptor_variable(struct spirv_compiler * - symbol.key.descriptor_array.set = binding.set; - symbol.key.descriptor_array.binding = binding.binding; - symbol.key.descriptor_array.push_constant_index = binding_address.push_constant_index; -+ symbol.key.descriptor_array.write_only = write_only; -+ symbol.key.descriptor_array.coherent = coherent; - if ((entry = rb_get(&compiler->symbol_table, &symbol))) - { - var_info->array_symbol = RB_ENTRY_VALUE(entry, struct vkd3d_symbol, entry); -@@ -6135,6 +6171,11 @@ static uint32_t spirv_compiler_build_descriptor_variable(struct spirv_compiler * - spirv_compiler_emit_descriptor_binding(compiler, var_id, &binding); - spirv_compiler_emit_register_debug_name(builder, var_id, reg); - -+ if (write_only) -+ vkd3d_spirv_build_op_decorate(builder, var_id, SpvDecorationNonReadable, NULL, 0); -+ if (coherent) -+ vkd3d_spirv_build_op_decorate(builder, var_id, SpvDecorationCoherent, NULL, 0); -+ - symbol.id = var_id; - symbol.descriptor_array = NULL; - symbol.info.descriptor_array.storage_class = storage_class; -@@ -6190,7 +6231,7 @@ static void spirv_compiler_emit_cbv_declaration(struct spirv_compiler *compiler, - vkd3d_spirv_build_op_name(builder, struct_id, "cb%u_struct", size); - - var_id = spirv_compiler_build_descriptor_variable(compiler, storage_class, struct_id, -- ®, range, VKD3D_SHADER_RESOURCE_BUFFER, false, &var_info); -+ ®, range, VKD3D_SHADER_RESOURCE_BUFFER, false, false, &var_info); - - vkd3d_symbol_make_register(®_symbol, ®); - vkd3d_symbol_set_register_info(®_symbol, var_id, storage_class, -@@ -6247,7 +6288,7 @@ static void spirv_compiler_emit_sampler_declaration(struct spirv_compiler *compi - - type_id = vkd3d_spirv_get_op_type_sampler(builder); - var_id = spirv_compiler_build_descriptor_variable(compiler, storage_class, type_id, ®, -- range, VKD3D_SHADER_RESOURCE_NONE, false, &var_info); -+ range, VKD3D_SHADER_RESOURCE_NONE, false, false, &var_info); - - vkd3d_symbol_make_register(®_symbol, ®); - vkd3d_symbol_set_register_info(®_symbol, var_id, storage_class, -@@ -6294,26 +6335,6 @@ static SpvImageFormat image_format_for_image_read(enum vkd3d_shader_component_ty - } - } - --static const struct vkd3d_shader_descriptor_info1 *spirv_compiler_get_descriptor_info( -- struct spirv_compiler *compiler, enum vkd3d_shader_descriptor_type type, -- const struct vkd3d_shader_register_range *range) --{ -- const struct vkd3d_shader_scan_descriptor_info1 *descriptor_info = compiler->scan_descriptor_info; -- unsigned int register_last = (range->last == ~0u) ? range->first : range->last; -- const struct vkd3d_shader_descriptor_info1 *d; -- unsigned int i; -- -- for (i = 0; i < descriptor_info->descriptor_count; ++i) -- { -- d = &descriptor_info->descriptors[i]; -- if (d->type == type && d->register_space == range->space && d->register_index <= range->first -- && (d->count == ~0u || d->count > register_last - d->register_index)) -- return d; -- } -- -- return NULL; --} -- - static uint32_t spirv_compiler_get_image_type_id(struct spirv_compiler *compiler, - const struct vkd3d_shader_register *reg, const struct vkd3d_shader_register_range *range, - const struct vkd3d_spirv_resource_type *resource_type_info, enum vkd3d_shader_component_type data_type, -@@ -6492,7 +6513,7 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp - } - - var_id = spirv_compiler_build_descriptor_variable(compiler, storage_class, type_id, ®, -- range, resource_type, false, &var_info); -+ range, resource_type, is_uav, false, &var_info); - - if (is_uav) - { -@@ -6500,13 +6521,6 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp - - d = spirv_compiler_get_descriptor_info(compiler, VKD3D_SHADER_DESCRIPTOR_TYPE_UAV, range); - -- if (!(d->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_READ)) -- vkd3d_spirv_build_op_decorate(builder, var_id, SpvDecorationNonReadable, NULL, 0); -- -- /* ROVs are implicitly globally coherent. */ -- if (d->uav_flags & (VKD3DSUF_GLOBALLY_COHERENT | VKD3DSUF_RASTERISER_ORDERED_VIEW)) -- vkd3d_spirv_build_op_decorate(builder, var_id, SpvDecorationCoherent, NULL, 0); -- - if (d->uav_flags & VKD3DSUF_RASTERISER_ORDERED_VIEW) - { - if (compiler->shader_type != VKD3D_SHADER_TYPE_PIXEL) -@@ -6549,7 +6563,7 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp - } - - counter_var_id = spirv_compiler_build_descriptor_variable(compiler, storage_class, -- type_id, ®, range, resource_type, true, &counter_var_info); -+ type_id, ®, range, resource_type, false, true, &counter_var_info); - } - } - --- -2.43.0 -