diff --git a/patches/vkd3d-latest/0001-Updated-vkd3d-to-a68fd1b0ded735580b0ec9025f75fe02d62.patch b/patches/vkd3d-latest/0001-Updated-vkd3d-to-a68fd1b0ded735580b0ec9025f75fe02d62.patch index 04e0470c..24c394b6 100644 --- a/patches/vkd3d-latest/0001-Updated-vkd3d-to-a68fd1b0ded735580b0ec9025f75fe02d62.patch +++ b/patches/vkd3d-latest/0001-Updated-vkd3d-to-a68fd1b0ded735580b0ec9025f75fe02d62.patch @@ -1,4 +1,4 @@ -From c2e60d4422dcf282cc05b674c4f5326929b49326 Mon Sep 17 00:00:00 2001 +From b07df60cda09cbe2698b4e864feacde4245403d1 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Fri, 29 Nov 2024 07:14:57 +1100 Subject: [PATCH] Updated vkd3d to a68fd1b0ded735580b0ec9025f75fe02d62966df. diff --git a/patches/vkd3d-latest/0002-Updated-vkd3d-to-d164752efc2dffc06d1e3ad9dd04cafff31.patch b/patches/vkd3d-latest/0002-Updated-vkd3d-to-d164752efc2dffc06d1e3ad9dd04cafff31.patch new file mode 100644 index 00000000..3ce57f38 --- /dev/null +++ b/patches/vkd3d-latest/0002-Updated-vkd3d-to-d164752efc2dffc06d1e3ad9dd04cafff31.patch @@ -0,0 +1,1516 @@ +From 338dc2926ae97ad64ff352299b915f05c3fb3da6 Mon Sep 17 00:00:00 2001 +From: Alistair Leslie-Hughes +Date: Thu, 19 Dec 2024 06:57:42 +1100 +Subject: [PATCH] Updated vkd3d to d164752efc2dffc06d1e3ad9dd04cafff31e742a. + +--- + libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 301 ++++-------------- + libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 234 +++++++++----- + libs/vkd3d/libs/vkd3d-shader/dxil.c | 51 +++ + libs/vkd3d/libs/vkd3d-shader/hlsl.h | 4 + + libs/vkd3d/libs/vkd3d-shader/hlsl.y | 86 +++++ + libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 158 ++++++--- + libs/vkd3d/libs/vkd3d-shader/ir.c | 105 +++++- + libs/vkd3d/libs/vkd3d-shader/spirv.c | 46 ++- + libs/vkd3d/libs/vkd3d-shader/tpf.c | 2 + + .../libs/vkd3d-shader/vkd3d_shader_private.h | 41 ++- + 10 files changed, 629 insertions(+), 399 deletions(-) + +diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c +index 8c96befadea..69e14e0c7bf 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c ++++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c +@@ -354,6 +354,64 @@ static const char * const shader_opcode_names[] = + [VKD3DSIH_XOR ] = "xor", + }; + ++static const char * const shader_register_names[] = ++{ ++ [VKD3DSPR_ADDR ] = "a", ++ [VKD3DSPR_ATTROUT ] = "oD", ++ [VKD3DSPR_COLOROUT ] = "oC", ++ [VKD3DSPR_COMBINED_SAMPLER ] = "s", ++ [VKD3DSPR_CONST ] = "c", ++ [VKD3DSPR_CONSTBOOL ] = "b", ++ [VKD3DSPR_CONSTBUFFER ] = "cb", ++ [VKD3DSPR_CONSTINT ] = "i", ++ [VKD3DSPR_COVERAGE ] = "vCoverage", ++ [VKD3DSPR_DEPTHOUT ] = "oDepth", ++ [VKD3DSPR_DEPTHOUTGE ] = "oDepthGE", ++ [VKD3DSPR_DEPTHOUTLE ] = "oDepthLE", ++ [VKD3DSPR_FORKINSTID ] = "vForkInstanceId", ++ [VKD3DSPR_FUNCTIONBODY ] = "fb", ++ [VKD3DSPR_FUNCTIONPOINTER ] = "fp", ++ [VKD3DSPR_GROUPSHAREDMEM ] = "g", ++ [VKD3DSPR_GSINSTID ] = "vGSInstanceID", ++ [VKD3DSPR_IDXTEMP ] = "x", ++ [VKD3DSPR_IMMCONST ] = "l", ++ [VKD3DSPR_IMMCONST64 ] = "d", ++ [VKD3DSPR_IMMCONSTBUFFER ] = "icb", ++ [VKD3DSPR_INCONTROLPOINT ] = "vicp", ++ [VKD3DSPR_INPUT ] = "v", ++ [VKD3DSPR_JOININSTID ] = "vJoinInstanceId", ++ [VKD3DSPR_LABEL ] = "l", ++ [VKD3DSPR_LOCALTHREADID ] = "vThreadIDInGroup", ++ [VKD3DSPR_LOCALTHREADINDEX ] = "vThreadIDInGroupFlattened", ++ [VKD3DSPR_LOOP ] = "aL", ++ [VKD3DSPR_NULL ] = "null", ++ [VKD3DSPR_OUTCONTROLPOINT ] = "vocp", ++ [VKD3DSPR_OUTPOINTID ] = "vOutputControlPointID", ++ [VKD3DSPR_OUTPUT ] = "o", ++ [VKD3DSPR_OUTSTENCILREF ] = "oStencilRef", ++ [VKD3DSPR_PARAMETER ] = "parameter", ++ [VKD3DSPR_PATCHCONST ] = "vpc", ++ [VKD3DSPR_POINT_COORD ] = "vPointCoord", ++ [VKD3DSPR_PREDICATE ] = "p", ++ [VKD3DSPR_PRIMID ] = "primID", ++ [VKD3DSPR_RASTERIZER ] = "rasterizer", ++ [VKD3DSPR_RESOURCE ] = "t", ++ [VKD3DSPR_SAMPLEMASK ] = "oMask", ++ [VKD3DSPR_SAMPLER ] = "s", ++ [VKD3DSPR_SSA ] = "sr", ++ [VKD3DSPR_STREAM ] = "m", ++ [VKD3DSPR_TEMP ] = "r", ++ [VKD3DSPR_TESSCOORD ] = "vDomainLocation", ++ [VKD3DSPR_TEXCRDOUT ] = "oT", ++ [VKD3DSPR_TEXTURE ] = "t", ++ [VKD3DSPR_THREADGROUPID ] = "vThreadGroupID", ++ [VKD3DSPR_THREADID ] = "vThreadID", ++ [VKD3DSPR_UAV ] = "u", ++ [VKD3DSPR_UNDEF ] = "undef", ++ [VKD3DSPR_WAVELANECOUNT ] = "vWaveLaneCount", ++ [VKD3DSPR_WAVELANEINDEX ] = "vWaveLaneIndex", ++}; ++ + struct vkd3d_d3d_asm_colours + { + const char *reset; +@@ -377,22 +435,6 @@ struct vkd3d_d3d_asm_compiler + const struct vkd3d_shader_instruction *current; + }; + +-/* Convert floating point offset relative to a register file to an absolute +- * offset for float constants. */ +-static unsigned int shader_get_float_offset(enum vkd3d_shader_register_type register_type, UINT register_idx) +-{ +- switch (register_type) +- { +- case VKD3DSPR_CONST: return register_idx; +- case VKD3DSPR_CONST2: return 2048 + register_idx; +- case VKD3DSPR_CONST3: return 4096 + register_idx; +- case VKD3DSPR_CONST4: return 6144 + register_idx; +- default: +- FIXME("Unsupported register type: %u.\n", register_type); +- return register_idx; +- } +-} +- + static void shader_dump_global_flags(struct vkd3d_d3d_asm_compiler *compiler, enum vsir_global_flags global_flags) + { + unsigned int i; +@@ -966,82 +1008,10 @@ static void shader_print_register(struct vkd3d_d3d_asm_compiler *compiler, const + reg->type == VKD3DSPR_LABEL ? compiler->colours.label : compiler->colours.reg); + switch (reg->type) + { +- case VKD3DSPR_TEMP: +- vkd3d_string_buffer_printf(buffer, "r"); +- break; +- +- case VKD3DSPR_INPUT: +- vkd3d_string_buffer_printf(buffer, "v"); +- break; +- +- case VKD3DSPR_CONST: +- case VKD3DSPR_CONST2: +- case VKD3DSPR_CONST3: +- case VKD3DSPR_CONST4: +- vkd3d_string_buffer_printf(buffer, "c"); +- offset = shader_get_float_offset(reg->type, offset); +- break; +- +- case VKD3DSPR_TEXTURE: /* vs: case VKD3DSPR_ADDR */ +- vkd3d_string_buffer_printf(buffer, "%c", +- compiler->shader_version.type == VKD3D_SHADER_TYPE_PIXEL ? 't' : 'a'); +- break; +- + case VKD3DSPR_RASTOUT: + vkd3d_string_buffer_printf(buffer, "%s", rastout_reg_names[offset]); + break; + +- case VKD3DSPR_COLOROUT: +- vkd3d_string_buffer_printf(buffer, "oC"); +- break; +- +- case VKD3DSPR_DEPTHOUT: +- vkd3d_string_buffer_printf(buffer, "oDepth"); +- break; +- +- case VKD3DSPR_DEPTHOUTGE: +- vkd3d_string_buffer_printf(buffer, "oDepthGE"); +- break; +- +- case VKD3DSPR_DEPTHOUTLE: +- vkd3d_string_buffer_printf(buffer, "oDepthLE"); +- break; +- +- case VKD3DSPR_ATTROUT: +- vkd3d_string_buffer_printf(buffer, "oD"); +- break; +- +- case VKD3DSPR_TEXCRDOUT: +- /* Vertex shaders >= 3.0 use general purpose output registers +- * (VKD3DSPR_OUTPUT), which can include an address token. */ +- if (vkd3d_shader_ver_ge(&compiler->shader_version, 3, 0)) +- vkd3d_string_buffer_printf(buffer, "o"); +- else +- vkd3d_string_buffer_printf(buffer, "oT"); +- break; +- +- case VKD3DSPR_CONSTINT: +- vkd3d_string_buffer_printf(buffer, "i"); +- break; +- +- case VKD3DSPR_CONSTBOOL: +- vkd3d_string_buffer_printf(buffer, "b"); +- break; +- +- case VKD3DSPR_LABEL: +- vkd3d_string_buffer_printf(buffer, "l"); +- break; +- +- case VKD3DSPR_LOOP: +- vkd3d_string_buffer_printf(buffer, "aL"); +- break; +- +- case VKD3DSPR_COMBINED_SAMPLER: +- case VKD3DSPR_SAMPLER: +- vkd3d_string_buffer_printf(buffer, "s"); +- is_descriptor = true; +- break; +- + case VKD3DSPR_MISCTYPE: + if (offset > 1) + vkd3d_string_buffer_printf(buffer, "%s%s", +@@ -1050,156 +1020,20 @@ static void shader_print_register(struct vkd3d_d3d_asm_compiler *compiler, const + vkd3d_string_buffer_printf(buffer, "%s", misctype_reg_names[offset]); + break; + +- case VKD3DSPR_PREDICATE: +- vkd3d_string_buffer_printf(buffer, "p"); +- break; +- +- case VKD3DSPR_IMMCONST: +- vkd3d_string_buffer_printf(buffer, "l"); +- break; +- +- case VKD3DSPR_IMMCONST64: +- vkd3d_string_buffer_printf(buffer, "d"); +- break; +- ++ case VKD3DSPR_COMBINED_SAMPLER: ++ case VKD3DSPR_SAMPLER: + case VKD3DSPR_CONSTBUFFER: +- vkd3d_string_buffer_printf(buffer, "cb"); +- is_descriptor = true; +- break; +- +- case VKD3DSPR_IMMCONSTBUFFER: +- vkd3d_string_buffer_printf(buffer, "icb"); +- break; +- +- case VKD3DSPR_PRIMID: +- vkd3d_string_buffer_printf(buffer, "primID"); +- break; +- +- case VKD3DSPR_NULL: +- vkd3d_string_buffer_printf(buffer, "null"); +- break; +- +- case VKD3DSPR_RASTERIZER: +- vkd3d_string_buffer_printf(buffer, "rasterizer"); +- break; +- + case VKD3DSPR_RESOURCE: +- vkd3d_string_buffer_printf(buffer, "t"); +- is_descriptor = true; +- break; +- + case VKD3DSPR_UAV: +- vkd3d_string_buffer_printf(buffer, "u"); + is_descriptor = true; +- break; +- +- case VKD3DSPR_OUTPOINTID: +- vkd3d_string_buffer_printf(buffer, "vOutputControlPointID"); +- break; +- +- case VKD3DSPR_FORKINSTID: +- vkd3d_string_buffer_printf(buffer, "vForkInstanceId"); +- break; +- +- case VKD3DSPR_JOININSTID: +- vkd3d_string_buffer_printf(buffer, "vJoinInstanceId"); +- break; +- +- case VKD3DSPR_INCONTROLPOINT: +- vkd3d_string_buffer_printf(buffer, "vicp"); +- break; +- +- case VKD3DSPR_OUTCONTROLPOINT: +- vkd3d_string_buffer_printf(buffer, "vocp"); +- break; +- +- case VKD3DSPR_PATCHCONST: +- vkd3d_string_buffer_printf(buffer, "vpc"); +- break; +- +- case VKD3DSPR_TESSCOORD: +- vkd3d_string_buffer_printf(buffer, "vDomainLocation"); +- break; +- +- case VKD3DSPR_GROUPSHAREDMEM: +- vkd3d_string_buffer_printf(buffer, "g"); +- break; +- +- case VKD3DSPR_THREADID: +- vkd3d_string_buffer_printf(buffer, "vThreadID"); +- break; +- +- case VKD3DSPR_THREADGROUPID: +- vkd3d_string_buffer_printf(buffer, "vThreadGroupID"); +- break; +- +- case VKD3DSPR_LOCALTHREADID: +- vkd3d_string_buffer_printf(buffer, "vThreadIDInGroup"); +- break; +- +- case VKD3DSPR_LOCALTHREADINDEX: +- vkd3d_string_buffer_printf(buffer, "vThreadIDInGroupFlattened"); +- break; +- +- case VKD3DSPR_IDXTEMP: +- vkd3d_string_buffer_printf(buffer, "x"); +- break; +- +- case VKD3DSPR_STREAM: +- vkd3d_string_buffer_printf(buffer, "m"); +- break; +- +- case VKD3DSPR_FUNCTIONBODY: +- vkd3d_string_buffer_printf(buffer, "fb"); +- break; +- +- case VKD3DSPR_FUNCTIONPOINTER: +- vkd3d_string_buffer_printf(buffer, "fp"); +- break; +- +- case VKD3DSPR_COVERAGE: +- vkd3d_string_buffer_printf(buffer, "vCoverage"); +- break; +- +- case VKD3DSPR_SAMPLEMASK: +- vkd3d_string_buffer_printf(buffer, "oMask"); +- break; +- +- case VKD3DSPR_GSINSTID: +- vkd3d_string_buffer_printf(buffer, "vGSInstanceID"); +- break; +- +- case VKD3DSPR_OUTSTENCILREF: +- vkd3d_string_buffer_printf(buffer, "oStencilRef"); +- break; +- +- case VKD3DSPR_UNDEF: +- vkd3d_string_buffer_printf(buffer, "undef"); +- break; +- +- case VKD3DSPR_SSA: +- vkd3d_string_buffer_printf(buffer, "sr"); +- break; +- +- case VKD3DSPR_WAVELANECOUNT: +- vkd3d_string_buffer_printf(buffer, "vWaveLaneCount"); +- break; +- +- case VKD3DSPR_WAVELANEINDEX: +- vkd3d_string_buffer_printf(buffer, "vWaveLaneIndex"); +- break; +- +- case VKD3DSPR_PARAMETER: +- vkd3d_string_buffer_printf(buffer, "parameter"); +- break; +- +- case VKD3DSPR_POINT_COORD: +- vkd3d_string_buffer_printf(buffer, "vPointCoord"); +- break; ++ /* fall through */ + + default: +- vkd3d_string_buffer_printf(buffer, "%s%s", +- compiler->colours.error, reg->type, compiler->colours.reset); ++ if (reg->type < ARRAY_SIZE(shader_register_names) && shader_register_names[reg->type]) ++ vkd3d_string_buffer_printf(buffer, "%s", shader_register_names[reg->type]); ++ else ++ vkd3d_string_buffer_printf(buffer, "%s%s", ++ compiler->colours.error, reg->type, compiler->colours.reset); + break; + } + +@@ -2132,8 +1966,7 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler, + + case VKD3DSIH_DEF: + vkd3d_string_buffer_printf(buffer, " %sc%u%s", compiler->colours.reg, +- shader_get_float_offset(ins->dst[0].reg.type, ins->dst[0].reg.idx[0].offset), +- compiler->colours.reset); ++ ins->dst[0].reg.idx[0].offset, compiler->colours.reset); + shader_print_float_literal(compiler, " = ", ins->src[0].reg.u.immconst_f32[0], ""); + shader_print_float_literal(compiler, ", ", ins->src[0].reg.u.immconst_f32[1], ""); + shader_print_float_literal(compiler, ", ", ins->src[0].reg.u.immconst_f32[2], ""); +diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c +index a931883e8d1..58e35cf22e8 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c ++++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c +@@ -89,6 +89,32 @@ + #define VKD3D_SM1_VERSION_MAJOR(version) (((version) >> 8u) & 0xffu) + #define VKD3D_SM1_VERSION_MINOR(version) (((version) >> 0u) & 0xffu) + ++enum vkd3d_sm1_register_type ++{ ++ VKD3D_SM1_REG_TEMP = 0x00, ++ VKD3D_SM1_REG_INPUT = 0x01, ++ VKD3D_SM1_REG_CONST = 0x02, ++ VKD3D_SM1_REG_ADDR = 0x03, ++ VKD3D_SM1_REG_TEXTURE = 0x03, ++ VKD3D_SM1_REG_RASTOUT = 0x04, ++ VKD3D_SM1_REG_ATTROUT = 0x05, ++ VKD3D_SM1_REG_TEXCRDOUT = 0x06, ++ VKD3D_SM1_REG_OUTPUT = 0x06, ++ VKD3D_SM1_REG_CONSTINT = 0x07, ++ VKD3D_SM1_REG_COLOROUT = 0x08, ++ VKD3D_SM1_REG_DEPTHOUT = 0x09, ++ VKD3D_SM1_REG_SAMPLER = 0x0a, ++ VKD3D_SM1_REG_CONST2 = 0x0b, ++ VKD3D_SM1_REG_CONST3 = 0x0c, ++ VKD3D_SM1_REG_CONST4 = 0x0d, ++ VKD3D_SM1_REG_CONSTBOOL = 0x0e, ++ VKD3D_SM1_REG_LOOP = 0x0f, ++ VKD3D_SM1_REG_TEMPFLOAT16 = 0x10, ++ VKD3D_SM1_REG_MISCTYPE = 0x11, ++ VKD3D_SM1_REG_LABEL = 0x12, ++ VKD3D_SM1_REG_PREDICATE = 0x13, ++}; ++ + enum vkd3d_sm1_address_mode_type + { + VKD3D_SM1_ADDRESS_MODE_ABSOLUTE = 0x0, +@@ -388,6 +414,34 @@ static const struct vkd3d_sm1_opcode_info ps_opcode_table[] = + {0, 0, 0, VKD3DSIH_INVALID}, + }; + ++static const struct ++{ ++ enum vkd3d_sm1_register_type d3dbc_type; ++ enum vkd3d_shader_register_type vsir_type; ++} ++register_types[] = ++{ ++ {VKD3D_SM1_REG_TEMP, VKD3DSPR_TEMP}, ++ {VKD3D_SM1_REG_INPUT, VKD3DSPR_INPUT}, ++ {VKD3D_SM1_REG_CONST, VKD3DSPR_CONST}, ++ {VKD3D_SM1_REG_ADDR, VKD3DSPR_ADDR}, ++ {VKD3D_SM1_REG_TEXTURE, VKD3DSPR_TEXTURE}, ++ {VKD3D_SM1_REG_RASTOUT, VKD3DSPR_RASTOUT}, ++ {VKD3D_SM1_REG_ATTROUT, VKD3DSPR_ATTROUT}, ++ {VKD3D_SM1_REG_OUTPUT, VKD3DSPR_OUTPUT}, ++ {VKD3D_SM1_REG_TEXCRDOUT, VKD3DSPR_TEXCRDOUT}, ++ {VKD3D_SM1_REG_CONSTINT, VKD3DSPR_CONSTINT}, ++ {VKD3D_SM1_REG_COLOROUT, VKD3DSPR_COLOROUT}, ++ {VKD3D_SM1_REG_DEPTHOUT, VKD3DSPR_DEPTHOUT}, ++ {VKD3D_SM1_REG_SAMPLER, VKD3DSPR_COMBINED_SAMPLER}, ++ {VKD3D_SM1_REG_CONSTBOOL, VKD3DSPR_CONSTBOOL}, ++ {VKD3D_SM1_REG_LOOP, VKD3DSPR_LOOP}, ++ {VKD3D_SM1_REG_TEMPFLOAT16, VKD3DSPR_TEMPFLOAT16}, ++ {VKD3D_SM1_REG_MISCTYPE, VKD3DSPR_MISCTYPE}, ++ {VKD3D_SM1_REG_LABEL, VKD3DSPR_LABEL}, ++ {VKD3D_SM1_REG_PREDICATE, VKD3DSPR_PREDICATE}, ++}; ++ + static const enum vkd3d_shader_resource_type resource_type_table[] = + { + /* VKD3D_SM1_RESOURCE_UNKNOWN */ VKD3D_SHADER_RESOURCE_NONE, +@@ -453,6 +507,7 @@ static unsigned int idx_count_from_reg_type(enum vkd3d_shader_register_type reg_ + switch (reg_type) + { + case VKD3DSPR_DEPTHOUT: ++ case VKD3DSPR_ADDR: + return 0; + + default: +@@ -460,52 +515,82 @@ static unsigned int idx_count_from_reg_type(enum vkd3d_shader_register_type reg_ + } + } + +-static void shader_sm1_parse_src_param(uint32_t param, struct vkd3d_shader_src_param *rel_addr, +- struct vkd3d_shader_src_param *src) ++static enum vkd3d_shader_register_type parse_register_type( ++ struct vkd3d_shader_sm1_parser *sm1, uint32_t param, unsigned int *index_offset) + { +- enum vkd3d_shader_register_type reg_type = ((param & VKD3D_SM1_REGISTER_TYPE_MASK) >> VKD3D_SM1_REGISTER_TYPE_SHIFT) ++ enum vkd3d_sm1_register_type d3dbc_type = ((param & VKD3D_SM1_REGISTER_TYPE_MASK) >> VKD3D_SM1_REGISTER_TYPE_SHIFT) + | ((param & VKD3D_SM1_REGISTER_TYPE_MASK2) >> VKD3D_SM1_REGISTER_TYPE_SHIFT2); +- unsigned int idx_count = idx_count_from_reg_type(reg_type); + +- vsir_register_init(&src->reg, reg_type, VKD3D_DATA_FLOAT, idx_count); +- src->reg.precision = VKD3D_SHADER_REGISTER_PRECISION_DEFAULT; +- src->reg.non_uniform = false; +- if (idx_count == 1) ++ *index_offset = 0; ++ ++ if (d3dbc_type == VKD3D_SM1_REG_CONST2) + { +- src->reg.idx[0].offset = param & VKD3D_SM1_REGISTER_NUMBER_MASK; +- src->reg.idx[0].rel_addr = rel_addr; ++ *index_offset = 2048; ++ return VKD3DSPR_CONST; + } +- if (src->reg.type == VKD3DSPR_SAMPLER) +- src->reg.dimension = VSIR_DIMENSION_NONE; +- else if (src->reg.type == VKD3DSPR_DEPTHOUT) +- src->reg.dimension = VSIR_DIMENSION_SCALAR; +- else +- src->reg.dimension = VSIR_DIMENSION_VEC4; +- src->swizzle = swizzle_from_sm1((param & VKD3D_SM1_SWIZZLE_MASK) >> VKD3D_SM1_SWIZZLE_SHIFT); +- src->modifiers = (param & VKD3D_SM1_SRC_MODIFIER_MASK) >> VKD3D_SM1_SRC_MODIFIER_SHIFT; ++ ++ if (d3dbc_type == VKD3D_SM1_REG_CONST3) ++ { ++ *index_offset = 4096; ++ return VKD3DSPR_CONST; ++ } ++ ++ if (d3dbc_type == VKD3D_SM1_REG_CONST4) ++ { ++ *index_offset = 6144; ++ return VKD3DSPR_CONST; ++ } ++ ++ if (d3dbc_type == VKD3D_SM1_REG_ADDR) ++ return sm1->p.program->shader_version.type == VKD3D_SHADER_TYPE_PIXEL ? VKD3DSPR_TEXTURE : VKD3DSPR_ADDR; ++ if (d3dbc_type == VKD3D_SM1_REG_TEXCRDOUT) ++ return vkd3d_shader_ver_ge(&sm1->p.program->shader_version, 3, 0) ? VKD3DSPR_OUTPUT : VKD3DSPR_TEXCRDOUT; ++ ++ for (unsigned int i = 0; i < ARRAY_SIZE(register_types); ++i) ++ { ++ if (register_types[i].d3dbc_type == d3dbc_type) ++ return register_types[i].vsir_type; ++ } ++ ++ return VKD3DSPR_INVALID; + } + +-static void shader_sm1_parse_dst_param(uint32_t param, struct vkd3d_shader_src_param *rel_addr, +- struct vkd3d_shader_dst_param *dst) ++static void d3dbc_parse_register(struct vkd3d_shader_sm1_parser *d3dbc, ++ struct vkd3d_shader_register *reg, uint32_t param, struct vkd3d_shader_src_param *rel_addr) + { +- enum vkd3d_shader_register_type reg_type = ((param & VKD3D_SM1_REGISTER_TYPE_MASK) >> VKD3D_SM1_REGISTER_TYPE_SHIFT) +- | ((param & VKD3D_SM1_REGISTER_TYPE_MASK2) >> VKD3D_SM1_REGISTER_TYPE_SHIFT2); +- unsigned int idx_count = idx_count_from_reg_type(reg_type); +- +- vsir_register_init(&dst->reg, reg_type, VKD3D_DATA_FLOAT, idx_count); +- dst->reg.precision = VKD3D_SHADER_REGISTER_PRECISION_DEFAULT; +- dst->reg.non_uniform = false; ++ enum vkd3d_shader_register_type reg_type; ++ unsigned int index_offset, idx_count; ++ ++ reg_type = parse_register_type(d3dbc, param, &index_offset); ++ idx_count = idx_count_from_reg_type(reg_type); ++ vsir_register_init(reg, reg_type, VKD3D_DATA_FLOAT, idx_count); ++ reg->precision = VKD3D_SHADER_REGISTER_PRECISION_DEFAULT; ++ reg->non_uniform = false; + if (idx_count == 1) + { +- dst->reg.idx[0].offset = param & VKD3D_SM1_REGISTER_NUMBER_MASK; +- dst->reg.idx[0].rel_addr = rel_addr; ++ reg->idx[0].offset = index_offset + (param & VKD3D_SM1_REGISTER_NUMBER_MASK); ++ reg->idx[0].rel_addr = rel_addr; + } +- if (dst->reg.type == VKD3DSPR_SAMPLER) +- dst->reg.dimension = VSIR_DIMENSION_NONE; +- else if (dst->reg.type == VKD3DSPR_DEPTHOUT) +- dst->reg.dimension = VSIR_DIMENSION_SCALAR; ++ if (reg->type == VKD3DSPR_SAMPLER) ++ reg->dimension = VSIR_DIMENSION_NONE; ++ else if (reg->type == VKD3DSPR_DEPTHOUT) ++ reg->dimension = VSIR_DIMENSION_SCALAR; + else +- dst->reg.dimension = VSIR_DIMENSION_VEC4; ++ reg->dimension = VSIR_DIMENSION_VEC4; ++} ++ ++static void shader_sm1_parse_src_param(struct vkd3d_shader_sm1_parser *sm1, uint32_t param, ++ struct vkd3d_shader_src_param *rel_addr, struct vkd3d_shader_src_param *src) ++{ ++ d3dbc_parse_register(sm1, &src->reg, param, rel_addr); ++ src->swizzle = swizzle_from_sm1((param & VKD3D_SM1_SWIZZLE_MASK) >> VKD3D_SM1_SWIZZLE_SHIFT); ++ src->modifiers = (param & VKD3D_SM1_SRC_MODIFIER_MASK) >> VKD3D_SM1_SRC_MODIFIER_SHIFT; ++} ++ ++static void shader_sm1_parse_dst_param(struct vkd3d_shader_sm1_parser *sm1, uint32_t param, ++ struct vkd3d_shader_src_param *rel_addr, struct vkd3d_shader_dst_param *dst) ++{ ++ d3dbc_parse_register(sm1, &dst->reg, param, rel_addr); + dst->modifiers = (param & VKD3D_SM1_DST_MODIFIER_MASK) >> VKD3D_SM1_DST_MODIFIER_SHIFT; + dst->shift = (param & VKD3D_SM1_DSTSHIFT_MASK) >> VKD3D_SM1_DSTSHIFT_SHIFT; + +@@ -686,26 +771,18 @@ static bool add_signature_element_from_register(struct vkd3d_shader_sm1_parser * + VKD3D_SHADER_SV_NONE, SM1_COLOR_REGISTER_OFFSET + register_index, is_dcl, mask); + + case VKD3DSPR_TEXTURE: +- /* For vertex shaders, this is ADDR. */ +- if (version->type == VKD3D_SHADER_TYPE_VERTEX) +- return true; + return add_signature_element(sm1, false, "TEXCOORD", register_index, + VKD3D_SHADER_SV_NONE, register_index, is_dcl, mask); + ++ case VKD3DSPR_TEXCRDOUT: ++ return add_signature_element(sm1, true, "TEXCOORD", register_index, ++ VKD3D_SHADER_SV_NONE, register_index, is_dcl, mask); ++ + case VKD3DSPR_OUTPUT: + if (version->type == VKD3D_SHADER_TYPE_VERTEX) + { +- /* For sm < 2 vertex shaders, this is TEXCRDOUT. +- * +- * For sm3 vertex shaders, this is OUTPUT, but we already +- * should have had a DCL instruction. */ +- if (version->major == 3) +- { +- add_signature_mask(sm1, true, register_index, mask); +- return true; +- } +- return add_signature_element(sm1, true, "TEXCOORD", register_index, +- VKD3D_SHADER_SV_NONE, register_index, is_dcl, mask); ++ add_signature_mask(sm1, true, register_index, mask); ++ return true; + } + /* fall through */ + +@@ -842,18 +919,6 @@ static void shader_sm1_scan_register(struct vkd3d_shader_sm1_parser *sm1, + record_constant_register(sm1, VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER, register_index, from_def); + break; + +- case VKD3DSPR_CONST2: +- record_constant_register(sm1, VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER, 2048 + register_index, from_def); +- break; +- +- case VKD3DSPR_CONST3: +- record_constant_register(sm1, VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER, 4096 + register_index, from_def); +- break; +- +- case VKD3DSPR_CONST4: +- record_constant_register(sm1, VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER, 6144 + register_index, from_def); +- break; +- + case VKD3DSPR_CONSTINT: + record_constant_register(sm1, VKD3D_SHADER_D3DBC_INT_CONSTANT_REGISTER, register_index, from_def); + break; +@@ -961,9 +1026,9 @@ static void shader_sm1_read_src_param(struct vkd3d_shader_sm1_parser *sm1, const + sm1->abort = true; + return; + } +- shader_sm1_parse_src_param(addr_token, NULL, src_rel_addr); ++ shader_sm1_parse_src_param(sm1, addr_token, NULL, src_rel_addr); + } +- shader_sm1_parse_src_param(token, src_rel_addr, src_param); ++ shader_sm1_parse_src_param(sm1, token, src_rel_addr, src_param); + } + + static void shader_sm1_read_dst_param(struct vkd3d_shader_sm1_parser *sm1, const uint32_t **ptr, +@@ -982,9 +1047,9 @@ static void shader_sm1_read_dst_param(struct vkd3d_shader_sm1_parser *sm1, const + sm1->abort = true; + return; + } +- shader_sm1_parse_src_param(addr_token, NULL, dst_rel_addr); ++ shader_sm1_parse_src_param(sm1, addr_token, NULL, dst_rel_addr); + } +- shader_sm1_parse_dst_param(token, dst_rel_addr, dst_param); ++ shader_sm1_parse_dst_param(sm1, token, dst_rel_addr, dst_param); + + if (dst_param->reg.type == VKD3DSPR_RASTOUT && dst_param->reg.idx[0].offset == VSIR_RASTOUT_POINT_SIZE) + sm1->p.program->has_point_size = true; +@@ -1027,7 +1092,7 @@ static void shader_sm1_read_semantic(struct vkd3d_shader_sm1_parser *sm1, + semantic->resource_data_type[1] = VKD3D_DATA_FLOAT; + semantic->resource_data_type[2] = VKD3D_DATA_FLOAT; + semantic->resource_data_type[3] = VKD3D_DATA_FLOAT; +- shader_sm1_parse_dst_param(dst_token, NULL, &semantic->resource.reg); ++ shader_sm1_parse_dst_param(sm1, dst_token, NULL, &semantic->resource.reg); + range = &semantic->resource.range; + range->space = 0; + range->first = range->last = semantic->resource.reg.reg.idx[0].offset; +@@ -1621,10 +1686,33 @@ static void d3dbc_write_comment(struct d3dbc_compiler *d3dbc, + set_u32(buffer, offset, vkd3d_make_u32(VKD3D_SM1_OP_COMMENT, (end - start) / sizeof(uint32_t))); + } + +-static uint32_t sm1_encode_register_type(enum vkd3d_shader_register_type type) ++static enum vkd3d_sm1_register_type d3dbc_register_type_from_vsir(const struct vkd3d_shader_register *reg) ++{ ++ if (reg->type == VKD3DSPR_CONST) ++ { ++ if (reg->idx[0].offset >= 6144) ++ return VKD3D_SM1_REG_CONST4; ++ if (reg->idx[0].offset >= 4096) ++ return VKD3D_SM1_REG_CONST3; ++ if (reg->idx[0].offset >= 2048) ++ return VKD3D_SM1_REG_CONST2; ++ } ++ ++ for (unsigned int i = 0; i < ARRAY_SIZE(register_types); ++i) ++ { ++ if (register_types[i].vsir_type == reg->type) ++ return register_types[i].d3dbc_type; ++ } ++ ++ vkd3d_unreachable(); ++} ++ ++static uint32_t sm1_encode_register_type(const struct vkd3d_shader_register *reg) + { +- return ((type << VKD3D_SM1_REGISTER_TYPE_SHIFT) & VKD3D_SM1_REGISTER_TYPE_MASK) +- | ((type << VKD3D_SM1_REGISTER_TYPE_SHIFT2) & VKD3D_SM1_REGISTER_TYPE_MASK2); ++ enum vkd3d_sm1_register_type sm1_type = d3dbc_register_type_from_vsir(reg); ++ ++ return ((sm1_type << VKD3D_SM1_REGISTER_TYPE_SHIFT) & VKD3D_SM1_REGISTER_TYPE_MASK) ++ | ((sm1_type << VKD3D_SM1_REGISTER_TYPE_SHIFT2) & VKD3D_SM1_REGISTER_TYPE_MASK2); + } + + static uint32_t swizzle_from_vsir(uint32_t swizzle) +@@ -1673,17 +1761,19 @@ static void write_sm1_dst_register(struct vkd3d_bytecode_buffer *buffer, const s + { + VKD3D_ASSERT(reg->write_mask); + put_u32(buffer, VKD3D_SM1_INSTRUCTION_PARAMETER +- | sm1_encode_register_type(reg->reg.type) ++ | sm1_encode_register_type(®->reg) + | (reg->modifiers << VKD3D_SM1_DST_MODIFIER_SHIFT) +- | (reg->write_mask << VKD3D_SM1_WRITEMASK_SHIFT) | reg->reg.idx[0].offset); ++ | (reg->write_mask << VKD3D_SM1_WRITEMASK_SHIFT) ++ | (reg->reg.idx[0].offset & VKD3D_SM1_REGISTER_NUMBER_MASK)); + } + + static void write_sm1_src_register(struct vkd3d_bytecode_buffer *buffer, const struct vkd3d_shader_src_param *reg) + { + put_u32(buffer, VKD3D_SM1_INSTRUCTION_PARAMETER +- | sm1_encode_register_type(reg->reg.type) ++ | sm1_encode_register_type(®->reg) + | (reg->modifiers << VKD3D_SM1_SRC_MODIFIER_SHIFT) +- | (swizzle_from_vsir(reg->swizzle) << VKD3D_SM1_SWIZZLE_SHIFT) | reg->reg.idx[0].offset); ++ | (swizzle_from_vsir(reg->swizzle) << VKD3D_SM1_SWIZZLE_SHIFT) ++ | (reg->reg.idx[0].offset & VKD3D_SM1_REGISTER_NUMBER_MASK)); + } + + static void d3dbc_write_instruction(struct d3dbc_compiler *d3dbc, const struct vkd3d_shader_instruction *ins) +diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c +index 4493602dfb7..399c2b67eae 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/dxil.c ++++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c +@@ -430,6 +430,8 @@ enum dx_intrinsic_opcode + DX_DERIV_COARSEY = 84, + DX_DERIV_FINEX = 85, + DX_DERIV_FINEY = 86, ++ DX_EVAL_SAMPLE_INDEX = 88, ++ DX_EVAL_CENTROID = 89, + DX_SAMPLE_INDEX = 90, + DX_COVERAGE = 91, + DX_THREAD_ID = 93, +@@ -5098,6 +5100,53 @@ static void sm6_parser_emit_dx_dot(struct sm6_parser *sm6, enum dx_intrinsic_opc + instruction_dst_param_init_ssa_scalar(ins, sm6); + } + ++static void sm6_parser_emit_dx_eval_attrib(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, ++ const struct sm6_value **operands, struct function_emission_state *state) ++{ ++ struct vkd3d_shader_instruction *ins = state->ins; ++ struct vkd3d_shader_src_param *src_params; ++ const struct shader_signature *signature; ++ unsigned int row_index, column_index; ++ const struct signature_element *e; ++ ++ row_index = sm6_value_get_constant_uint(operands[0]); ++ column_index = sm6_value_get_constant_uint(operands[2]); ++ ++ signature = &sm6->p.program->input_signature; ++ if (row_index >= signature->element_count) ++ { ++ WARN("Invalid row index %u.\n", row_index); ++ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, ++ "Invalid input row index %u for an attribute evaluation.", row_index); ++ return; ++ } ++ ++ e = &signature->elements[row_index]; ++ if (column_index >= VKD3D_VEC4_SIZE || !(e->mask & (1 << column_index))) ++ { ++ WARN("Invalid column index %u.\n", column_index); ++ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, ++ "Invalid input column index %u for an attribute evaluation.", column_index); ++ return; ++ } ++ ++ vsir_instruction_init(ins, &sm6->p.location, (op == DX_EVAL_CENTROID) ++ ? VKD3DSIH_EVAL_CENTROID : VKD3DSIH_EVAL_SAMPLE_INDEX); ++ ++ if (!(src_params = instruction_src_params_alloc(ins, 1 + (op == DX_EVAL_SAMPLE_INDEX), sm6))) ++ return; ++ ++ src_params[0].reg = sm6->input_params[row_index].reg; ++ src_param_init_scalar(&src_params[0], column_index); ++ if (e->register_count > 1) ++ register_index_address_init(&src_params[0].reg.idx[0], operands[1], sm6); ++ ++ if (op == DX_EVAL_SAMPLE_INDEX) ++ src_param_init_from_value(&src_params[1], operands[3]); ++ ++ instruction_dst_param_init_ssa_scalar(ins, sm6); ++} ++ + static void sm6_parser_emit_dx_fabs(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, + const struct sm6_value **operands, struct function_emission_state *state) + { +@@ -6288,6 +6337,8 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] = + [DX_DOT4 ] = {"g", "RRRRRRRR", sm6_parser_emit_dx_dot}, + [DX_EMIT_STREAM ] = {"v", "c", sm6_parser_emit_dx_stream}, + [DX_EMIT_THEN_CUT_STREAM ] = {"v", "c", sm6_parser_emit_dx_stream}, ++ [DX_EVAL_CENTROID ] = {"o", "cic", sm6_parser_emit_dx_eval_attrib}, ++ [DX_EVAL_SAMPLE_INDEX ] = {"o", "cici", sm6_parser_emit_dx_eval_attrib}, + [DX_EXP ] = {"g", "R", sm6_parser_emit_dx_unary}, + [DX_FABS ] = {"g", "R", sm6_parser_emit_dx_fabs}, + [DX_FIRST_BIT_HI ] = {"i", "m", sm6_parser_emit_dx_unary}, +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h +index 7c9547a1c01..2acc003c9a1 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h +@@ -861,6 +861,10 @@ enum hlsl_resource_load_type + HLSL_RESOURCE_GATHER_GREEN, + HLSL_RESOURCE_GATHER_BLUE, + HLSL_RESOURCE_GATHER_ALPHA, ++ HLSL_RESOURCE_GATHER_CMP_RED, ++ HLSL_RESOURCE_GATHER_CMP_GREEN, ++ HLSL_RESOURCE_GATHER_CMP_BLUE, ++ HLSL_RESOURCE_GATHER_CMP_ALPHA, + HLSL_RESOURCE_SAMPLE_INFO, + HLSL_RESOURCE_RESINFO, + }; +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y +index a3814a810b5..dbed11cd8b3 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y +@@ -6124,6 +6124,87 @@ static bool add_gather_method_call(struct hlsl_ctx *ctx, struct hlsl_block *bloc + return true; + } + ++static bool add_gather_cmp_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_node *object, ++ const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) ++{ ++ const struct hlsl_type *object_type = object->data_type; ++ struct hlsl_resource_load_params load_params = {0}; ++ unsigned int sampler_dim, offset_dim; ++ const struct hlsl_type *sampler_type; ++ struct hlsl_ir_node *load; ++ ++ sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim); ++ offset_dim = hlsl_offset_dim_count(object_type->sampler_dim); ++ ++ if (!strcmp(name, "GatherCmpGreen")) ++ load_params.type = HLSL_RESOURCE_GATHER_CMP_GREEN; ++ else if (!strcmp(name, "GatherCmpBlue")) ++ load_params.type = HLSL_RESOURCE_GATHER_CMP_BLUE; ++ else if (!strcmp(name, "GatherCmpAlpha")) ++ load_params.type = HLSL_RESOURCE_GATHER_CMP_ALPHA; ++ else ++ load_params.type = HLSL_RESOURCE_GATHER_CMP_RED; ++ ++ if (!strcmp(name, "GatherCmp") || !offset_dim) ++ { ++ if (params->args_count < 3 || params->args_count > 4 + !!offset_dim) ++ { ++ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, ++ "Wrong number of arguments to method '%s': expected from 3 to %u, but got %u.", ++ name, 4 + !!offset_dim, params->args_count); ++ return false; ++ } ++ } ++ else if (params->args_count < 3 || params->args_count == 6 || params->args_count > 8) ++ { ++ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, ++ "Wrong number of arguments to method '%s': expected 3, 4, 5, 7, or 8, but got %u.", ++ name, params->args_count); ++ return false; ++ } ++ ++ if (params->args_count == 5 || params->args_count == 8) ++ { ++ hlsl_fixme(ctx, loc, "Tiled resource status argument."); ++ } ++ else if (offset_dim && params->args_count > 3) ++ { ++ if (!(load_params.texel_offset = add_implicit_conversion(ctx, block, params->args[3], ++ hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc))) ++ return false; ++ } ++ ++ sampler_type = params->args[0]->data_type; ++ if (sampler_type->class != HLSL_CLASS_SAMPLER || sampler_type->sampler_dim != HLSL_SAMPLER_DIM_COMPARISON) ++ { ++ struct vkd3d_string_buffer *string; ++ ++ if ((string = hlsl_type_to_string(ctx, sampler_type))) ++ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, ++ "Wrong type for argument 0 of %s(): expected 'SamplerComparisonState', but got '%s'.", ++ name, string->buffer); ++ hlsl_release_string_buffer(ctx, string); ++ return false; ++ } ++ ++ if (!(load_params.coords = add_implicit_conversion(ctx, block, params->args[1], ++ hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) ++ return false; ++ ++ if (!(load_params.cmp = add_implicit_conversion(ctx, block, params->args[2], ++ hlsl_get_scalar_type(ctx, HLSL_TYPE_FLOAT), loc))) ++ return false; ++ ++ load_params.format = hlsl_get_vector_type(ctx, object_type->e.resource.format->e.numeric.type, 4); ++ load_params.resource = object; ++ load_params.sampler = params->args[0]; ++ ++ if (!(load = hlsl_new_resource_load(ctx, &load_params, loc))) ++ return false; ++ hlsl_block_add_instr(block, load); ++ return true; ++} ++ + static bool add_assignment_from_component(struct hlsl_ctx *ctx, struct hlsl_block *instrs, struct hlsl_ir_node *dest, + struct hlsl_ir_node *src, unsigned int component, const struct vkd3d_shader_location *loc) + { +@@ -6491,6 +6572,11 @@ texture_methods[] = + { "Gather", add_gather_method_call, "00010101001000" }, + { "GatherAlpha", add_gather_method_call, "00010101001000" }, + { "GatherBlue", add_gather_method_call, "00010101001000" }, ++ { "GatherCmp", add_gather_cmp_method_call, "00010101001000" }, ++ { "GatherCmpAlpha", add_gather_cmp_method_call, "00010101001000" }, ++ { "GatherCmpBlue", add_gather_cmp_method_call, "00010101001000" }, ++ { "GatherCmpGreen", add_gather_cmp_method_call, "00010101001000" }, ++ { "GatherCmpRed", add_gather_cmp_method_call, "00010101001000" }, + { "GatherGreen", add_gather_method_call, "00010101001000" }, + { "GatherRed", add_gather_method_call, "00010101001000" }, + +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +index a43ea53089e..08f139f5e8f 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +@@ -2949,6 +2949,10 @@ static bool lower_combined_samples(struct hlsl_ctx *ctx, struct hlsl_ir_node *in + case HLSL_RESOURCE_GATHER_GREEN: + case HLSL_RESOURCE_GATHER_BLUE: + case HLSL_RESOURCE_GATHER_ALPHA: ++ case HLSL_RESOURCE_GATHER_CMP_RED: ++ case HLSL_RESOURCE_GATHER_CMP_GREEN: ++ case HLSL_RESOURCE_GATHER_CMP_BLUE: ++ case HLSL_RESOURCE_GATHER_CMP_ALPHA: + case HLSL_RESOURCE_RESINFO: + case HLSL_RESOURCE_SAMPLE_CMP: + case HLSL_RESOURCE_SAMPLE_CMP_LZ: +@@ -3537,6 +3541,51 @@ static bool lower_ternary(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, stru + return true; + } + ++static bool lower_resource_load_bias(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) ++{ ++ struct hlsl_ir_node *swizzle, *store; ++ struct hlsl_ir_resource_load *load; ++ struct hlsl_ir_load *tmp_load; ++ struct hlsl_ir_var *tmp_var; ++ struct hlsl_deref deref; ++ ++ if (instr->type != HLSL_IR_RESOURCE_LOAD) ++ return false; ++ load = hlsl_ir_resource_load(instr); ++ if (load->load_type != HLSL_RESOURCE_SAMPLE_LOD ++ && load->load_type != HLSL_RESOURCE_SAMPLE_LOD_BIAS) ++ return false; ++ ++ if (!load->lod.node) ++ return false; ++ ++ if (!(tmp_var = hlsl_new_synthetic_var(ctx, "coords-with-lod", ++ hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, 4), &instr->loc))) ++ return false; ++ ++ if (!(swizzle = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(X, X, X, X), 4, load->lod.node, &load->lod.node->loc))) ++ return false; ++ list_add_before(&instr->entry, &swizzle->entry); ++ ++ if (!(store = hlsl_new_simple_store(ctx, tmp_var, swizzle))) ++ return false; ++ list_add_before(&instr->entry, &store->entry); ++ ++ hlsl_init_simple_deref_from_var(&deref, tmp_var); ++ if (!(store = hlsl_new_store_index(ctx, &deref, NULL, load->coords.node, 0, &instr->loc))) ++ return false; ++ list_add_before(&instr->entry, &store->entry); ++ ++ if (!(tmp_load = hlsl_new_var_load(ctx, tmp_var, &instr->loc))) ++ return false; ++ list_add_before(&instr->entry, &tmp_load->node.entry); ++ ++ hlsl_src_remove(&load->coords); ++ hlsl_src_from_node(&load->coords, &tmp_load->node); ++ hlsl_src_remove(&load->lod); ++ return true; ++} ++ + static bool lower_comparison_operators(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, + struct hlsl_block *block) + { +@@ -9596,18 +9645,18 @@ static bool sm4_generate_vsir_instr_sample(struct hlsl_ctx *ctx, + } + + static bool sm4_generate_vsir_instr_gather(struct hlsl_ctx *ctx, struct vsir_program *program, +- const struct hlsl_ir_resource_load *load, uint32_t swizzle) ++ const struct hlsl_ir_resource_load *load, uint32_t swizzle, bool compare) + { + const struct vkd3d_shader_version *version = &program->shader_version; + const struct hlsl_ir_node *texel_offset = load->texel_offset.node; + const struct hlsl_ir_node *coords = load->coords.node; + const struct hlsl_deref *resource = &load->resource; ++ enum vkd3d_shader_opcode opcode = VKD3DSIH_GATHER4; + const struct hlsl_deref *sampler = &load->sampler; + const struct hlsl_ir_node *instr = &load->node; ++ unsigned int src_count = 3, current_arg = 0; + struct vkd3d_shader_instruction *ins; +- enum vkd3d_shader_opcode opcode; + +- opcode = VKD3DSIH_GATHER4; + if (texel_offset && !sm4_generate_vsir_validate_texel_offset_aoffimmi(texel_offset)) + { + if (!vkd3d_shader_ver_ge(version, 5, 0)) +@@ -9617,50 +9666,40 @@ static bool sm4_generate_vsir_instr_gather(struct hlsl_ctx *ctx, struct vsir_pro + return false; + } + opcode = VKD3DSIH_GATHER4_PO; ++ ++src_count; + } + +- if (opcode == VKD3DSIH_GATHER4) ++ if (compare) + { +- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, opcode, 1, 3))) +- return false; ++ opcode = opcode == VKD3DSIH_GATHER4 ? VKD3DSIH_GATHER4_C : VKD3DSIH_GATHER4_PO_C; ++ ++src_count; ++ } + +- vsir_dst_from_hlsl_node(&ins->dst[0], ctx, instr); +- vsir_src_from_hlsl_node(&ins->src[0], ctx, coords, VKD3DSP_WRITEMASK_ALL); +- sm4_generate_vsir_encode_texel_offset_as_aoffimmi(ins, texel_offset); ++ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, opcode, 1, src_count))) ++ return false; + +- if (!sm4_generate_vsir_init_src_param_from_deref(ctx, program, +- &ins->src[1], resource, ins->dst[0].write_mask, &instr->loc)) +- return false; ++ vsir_dst_from_hlsl_node(&ins->dst[0], ctx, instr); ++ vsir_src_from_hlsl_node(&ins->src[current_arg++], ctx, coords, VKD3DSP_WRITEMASK_ALL); + +- if (!sm4_generate_vsir_init_src_param_from_deref(ctx, program, +- &ins->src[2], sampler, VKD3DSP_WRITEMASK_ALL, &instr->loc)) +- return false; +- ins->src[2].reg.dimension = VSIR_DIMENSION_VEC4; +- ins->src[2].swizzle = swizzle; +- } +- else if (opcode == VKD3DSIH_GATHER4_PO) +- { +- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, opcode, 1, 4))) +- return false; ++ if (opcode == VKD3DSIH_GATHER4_PO || opcode == VKD3DSIH_GATHER4_PO_C) ++ vsir_src_from_hlsl_node(&ins->src[current_arg++], ctx, texel_offset, VKD3DSP_WRITEMASK_ALL); ++ else ++ sm4_generate_vsir_encode_texel_offset_as_aoffimmi(ins, texel_offset); + +- vsir_dst_from_hlsl_node(&ins->dst[0], ctx, instr); +- vsir_src_from_hlsl_node(&ins->src[0], ctx, coords, VKD3DSP_WRITEMASK_ALL); +- vsir_src_from_hlsl_node(&ins->src[1], ctx, texel_offset, VKD3DSP_WRITEMASK_ALL); ++ if (!sm4_generate_vsir_init_src_param_from_deref(ctx, program, ++ &ins->src[current_arg++], resource, ins->dst[0].write_mask, &instr->loc)) ++ return false; + +- if (!sm4_generate_vsir_init_src_param_from_deref(ctx, program, +- &ins->src[2], resource, ins->dst[0].write_mask, &instr->loc)) +- return false; ++ if (!sm4_generate_vsir_init_src_param_from_deref(ctx, program, ++ &ins->src[current_arg], sampler, VKD3DSP_WRITEMASK_ALL, &instr->loc)) ++ return false; ++ ins->src[current_arg].reg.dimension = VSIR_DIMENSION_VEC4; ++ ins->src[current_arg].swizzle = swizzle; ++ current_arg++; ++ ++ if (compare) ++ vsir_src_from_hlsl_node(&ins->src[current_arg++], ctx, load->cmp.node, VKD3DSP_WRITEMASK_0); + +- if (!sm4_generate_vsir_init_src_param_from_deref(ctx, program, +- &ins->src[3], sampler, VKD3DSP_WRITEMASK_ALL, &instr->loc)) +- return false; +- ins->src[3].reg.dimension = VSIR_DIMENSION_VEC4; +- ins->src[3].swizzle = swizzle; +- } +- else +- { +- vkd3d_unreachable(); +- } + return true; + } + +@@ -9723,6 +9762,32 @@ static bool sm4_generate_vsir_instr_resinfo(struct hlsl_ctx *ctx, + return true; + } + ++static uint32_t get_gather_swizzle(enum hlsl_resource_load_type type) ++{ ++ switch (type) ++ { ++ case HLSL_RESOURCE_GATHER_RED: ++ case HLSL_RESOURCE_GATHER_CMP_RED: ++ return VKD3D_SHADER_SWIZZLE(X, X, X, X); ++ ++ case HLSL_RESOURCE_GATHER_GREEN: ++ case HLSL_RESOURCE_GATHER_CMP_GREEN: ++ return VKD3D_SHADER_SWIZZLE(Y, Y, Y, Y); ++ ++ case HLSL_RESOURCE_GATHER_BLUE: ++ case HLSL_RESOURCE_GATHER_CMP_BLUE: ++ return VKD3D_SHADER_SWIZZLE(Z, Z, Z, Z); ++ ++ case HLSL_RESOURCE_GATHER_ALPHA: ++ case HLSL_RESOURCE_GATHER_CMP_ALPHA: ++ return VKD3D_SHADER_SWIZZLE(W, W, W, W); ++ default: ++ return 0; ++ } ++ ++ return 0; ++} ++ + static bool sm4_generate_vsir_instr_resource_load(struct hlsl_ctx *ctx, + struct vsir_program *program, const struct hlsl_ir_resource_load *load) + { +@@ -9754,16 +9819,16 @@ static bool sm4_generate_vsir_instr_resource_load(struct hlsl_ctx *ctx, + return sm4_generate_vsir_instr_sample(ctx, program, load); + + case HLSL_RESOURCE_GATHER_RED: +- return sm4_generate_vsir_instr_gather(ctx, program, load, VKD3D_SHADER_SWIZZLE(X, X, X, X)); +- + case HLSL_RESOURCE_GATHER_GREEN: +- return sm4_generate_vsir_instr_gather(ctx, program, load, VKD3D_SHADER_SWIZZLE(Y, Y, Y, Y)); +- + case HLSL_RESOURCE_GATHER_BLUE: +- return sm4_generate_vsir_instr_gather(ctx, program, load, VKD3D_SHADER_SWIZZLE(Z, Z, Z, Z)); +- + case HLSL_RESOURCE_GATHER_ALPHA: +- return sm4_generate_vsir_instr_gather(ctx, program, load, VKD3D_SHADER_SWIZZLE(W, W, W, W)); ++ return sm4_generate_vsir_instr_gather(ctx, program, load, get_gather_swizzle(load->load_type), false); ++ ++ case HLSL_RESOURCE_GATHER_CMP_RED: ++ case HLSL_RESOURCE_GATHER_CMP_GREEN: ++ case HLSL_RESOURCE_GATHER_CMP_BLUE: ++ case HLSL_RESOURCE_GATHER_CMP_ALPHA: ++ return sm4_generate_vsir_instr_gather(ctx, program, load, get_gather_swizzle(load->load_type), true); + + case HLSL_RESOURCE_SAMPLE_INFO: + return sm4_generate_vsir_instr_sample_info(ctx, program, load); +@@ -11039,13 +11104,14 @@ static void process_entry_function(struct hlsl_ctx *ctx, + append_output_var_copy(ctx, entry_func, entry_func->return_var); + } + +- if (profile->major_version >= 4) ++ if (hlsl_version_ge(ctx, 4, 0)) + { + hlsl_transform_ir(ctx, lower_discard_neg, body, NULL); + } + else + { + hlsl_transform_ir(ctx, lower_discard_nz, body, NULL); ++ hlsl_transform_ir(ctx, lower_resource_load_bias, body, NULL); + } + + loop_unrolling_execute(ctx, body); +diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c +index cdc0c18466f..ec7e2d036c8 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/ir.c ++++ b/libs/vkd3d/libs/vkd3d-shader/ir.c +@@ -703,7 +703,56 @@ static enum vkd3d_result vsir_program_lower_sm1_sincos(struct vsir_program *prog + return VKD3D_OK; + } + +-static enum vkd3d_result vsir_program_lower_tex(struct vsir_program *program, struct vkd3d_shader_instruction *tex) ++static enum vkd3d_result vsir_program_lower_texldp(struct vsir_program *program, ++ struct vkd3d_shader_instruction *tex, unsigned int *tmp_idx) ++{ ++ struct vkd3d_shader_instruction_array *instructions = &program->instructions; ++ struct vkd3d_shader_location *location = &tex->location; ++ struct vkd3d_shader_instruction *div_ins, *tex_ins; ++ size_t pos = tex - instructions->elements; ++ unsigned int w_comp; ++ ++ w_comp = vsir_swizzle_get_component(tex->src[0].swizzle, 3); ++ ++ if (!shader_instruction_array_insert_at(instructions, pos + 1, 2)) ++ return VKD3D_ERROR_OUT_OF_MEMORY; ++ ++ if (*tmp_idx == ~0u) ++ *tmp_idx = program->temp_count++; ++ ++ div_ins = &instructions->elements[pos + 1]; ++ tex_ins = &instructions->elements[pos + 2]; ++ ++ if (!vsir_instruction_init_with_params(program, div_ins, location, VKD3DSIH_DIV, 1, 2)) ++ return VKD3D_ERROR_OUT_OF_MEMORY; ++ ++ vsir_dst_param_init(&div_ins->dst[0], VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1); ++ div_ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; ++ div_ins->dst[0].reg.idx[0].offset = *tmp_idx; ++ div_ins->dst[0].write_mask = VKD3DSP_WRITEMASK_ALL; ++ ++ div_ins->src[0] = tex->src[0]; ++ ++ div_ins->src[1] = tex->src[0]; ++ div_ins->src[1].swizzle = vkd3d_shader_create_swizzle(w_comp, w_comp, w_comp, w_comp); ++ ++ if (!vsir_instruction_init_with_params(program, tex_ins, location, VKD3DSIH_TEX, 1, 2)) ++ return VKD3D_ERROR_OUT_OF_MEMORY; ++ ++ tex_ins->dst[0] = tex->dst[0]; ++ ++ tex_ins->src[0].reg = div_ins->dst[0].reg; ++ tex_ins->src[0].swizzle = VKD3D_SHADER_NO_SWIZZLE; ++ ++ tex_ins->src[1] = tex->src[1]; ++ ++ vkd3d_shader_instruction_make_nop(tex); ++ ++ return VKD3D_OK; ++} ++ ++static enum vkd3d_result vsir_program_lower_tex(struct vsir_program *program, ++ struct vkd3d_shader_instruction *tex, struct vkd3d_shader_message_context *message_context) + { + unsigned int idx = tex->src[1].reg.idx[0].offset; + struct vkd3d_shader_src_param *srcs; +@@ -711,16 +760,34 @@ static enum vkd3d_result vsir_program_lower_tex(struct vsir_program *program, st + VKD3D_ASSERT(tex->src[1].reg.idx_count == 1); + VKD3D_ASSERT(!tex->src[1].reg.idx[0].rel_addr); + +- if (!(srcs = shader_src_param_allocator_get(&program->instructions.src_params, 3))) ++ if (!(srcs = shader_src_param_allocator_get(&program->instructions.src_params, 4))) + return VKD3D_ERROR_OUT_OF_MEMORY; + + srcs[0] = tex->src[0]; + vsir_src_param_init_resource(&srcs[1], idx, idx); + vsir_src_param_init_sampler(&srcs[2], idx, idx); + +- tex->opcode = VKD3DSIH_SAMPLE; +- tex->src = srcs; +- tex->src_count = 3; ++ if (!tex->flags) ++ { ++ tex->opcode = VKD3DSIH_SAMPLE; ++ tex->src = srcs; ++ tex->src_count = 3; ++ } ++ else if (tex->flags == VKD3DSI_TEXLD_BIAS) ++ { ++ tex->opcode = VKD3DSIH_SAMPLE_B; ++ tex->src = srcs; ++ tex->src_count = 4; ++ ++ srcs[3] = tex->src[0]; ++ srcs[3].swizzle = VKD3D_SHADER_SWIZZLE(W, W, W, W); ++ } ++ else ++ { ++ vkd3d_shader_error(message_context, &tex->location, ++ VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, "Unhandled tex flags %#x.", tex->flags); ++ return VKD3D_ERROR_NOT_IMPLEMENTED; ++ } + + return VKD3D_OK; + } +@@ -885,8 +952,16 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr + break; + + case VKD3DSIH_TEX: +- if ((ret = vsir_program_lower_tex(program, ins)) < 0) +- return ret; ++ if (ins->flags == VKD3DSI_TEXLD_PROJECT) ++ { ++ if ((ret = vsir_program_lower_texldp(program, ins, &tmp_idx)) < 0) ++ return ret; ++ } ++ else ++ { ++ if ((ret = vsir_program_lower_tex(program, ins, message_context)) < 0) ++ return ret; ++ } + break; + + case VKD3DSIH_TEXLDD: +@@ -1117,6 +1192,7 @@ static void remove_unread_output_components(const struct shader_signature *signa + switch (dst->reg.type) + { + case VKD3DSPR_OUTPUT: ++ case VKD3DSPR_TEXCRDOUT: + e = vsir_signature_find_element_for_reg(signature, dst->reg.idx[0].offset, 0); + break; + +@@ -2102,6 +2178,7 @@ static bool shader_dst_param_io_normalise(struct vkd3d_shader_dst_param *dst_par + signature = normaliser->patch_constant_signature; + break; + ++ case VKD3DSPR_TEXCRDOUT: + case VKD3DSPR_COLOROUT: + reg_idx = reg->idx[0].offset; + signature = normaliser->output_signature; +@@ -2205,8 +2282,6 @@ static void shader_src_param_io_normalise(struct vkd3d_shader_src_param *src_par + break; + + case VKD3DSPR_TEXTURE: +- if (normaliser->shader_type != VKD3D_SHADER_TYPE_PIXEL) +- return; + reg->type = VKD3DSPR_INPUT; + reg_idx = reg->idx[0].offset; + signature = normaliser->input_signature; +@@ -2338,16 +2413,12 @@ static bool get_flat_constant_register_type(const struct vkd3d_shader_register * + { + enum vkd3d_shader_register_type type; + enum vkd3d_shader_d3dbc_constant_register set; +- uint32_t offset; + } + regs[] = + { +- {VKD3DSPR_CONST, VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER, 0}, +- {VKD3DSPR_CONST2, VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER, 2048}, +- {VKD3DSPR_CONST3, VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER, 4096}, +- {VKD3DSPR_CONST4, VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER, 6144}, +- {VKD3DSPR_CONSTINT, VKD3D_SHADER_D3DBC_INT_CONSTANT_REGISTER, 0}, +- {VKD3DSPR_CONSTBOOL, VKD3D_SHADER_D3DBC_BOOL_CONSTANT_REGISTER, 0}, ++ {VKD3DSPR_CONST, VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER}, ++ {VKD3DSPR_CONSTINT, VKD3D_SHADER_D3DBC_INT_CONSTANT_REGISTER}, ++ {VKD3DSPR_CONSTBOOL, VKD3D_SHADER_D3DBC_BOOL_CONSTANT_REGISTER}, + }; + + unsigned int i; +@@ -2363,7 +2434,7 @@ static bool get_flat_constant_register_type(const struct vkd3d_shader_register * + } + + *set = regs[i].set; +- *index = regs[i].offset + reg->idx[0].offset; ++ *index = reg->idx[0].offset; + return true; + } + } +diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c +index a7b935543a0..cfbadab8933 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/spirv.c ++++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c +@@ -7301,7 +7301,6 @@ static SpvOp spirv_compiler_map_alu_instruction(const struct vkd3d_shader_instru + {VKD3DSIH_DDIV, SpvOpFDiv}, + {VKD3DSIH_DIV, SpvOpFDiv}, + {VKD3DSIH_DMUL, SpvOpFMul}, +- {VKD3DSIH_DTOF, SpvOpFConvert}, + {VKD3DSIH_DTOI, SpvOpConvertFToS}, + {VKD3DSIH_DTOU, SpvOpConvertFToU}, + {VKD3DSIH_FREM, SpvOpFRem}, +@@ -7939,6 +7938,7 @@ static void spirv_compiler_emit_ftoi(struct spirv_compiler *compiler, + uint32_t src_type_id, dst_type_id, condition_type_id; + enum vkd3d_shader_component_type component_type; + unsigned int component_count; ++ uint32_t write_mask; + + VKD3D_ASSERT(instruction->dst_count == 1); + VKD3D_ASSERT(instruction->src_count == 1); +@@ -7948,21 +7948,23 @@ static void spirv_compiler_emit_ftoi(struct spirv_compiler *compiler, + * and for NaN to yield zero. */ + + component_count = vsir_write_mask_component_count(dst->write_mask); +- src_type_id = spirv_compiler_get_type_id_for_reg(compiler, &src->reg, dst->write_mask); +- dst_type_id = spirv_compiler_get_type_id_for_dst(compiler, dst); +- src_id = spirv_compiler_emit_load_src(compiler, src, dst->write_mask); + + if (src->reg.data_type == VKD3D_DATA_DOUBLE) + { ++ write_mask = vkd3d_write_mask_from_component_count(component_count); + int_min_id = spirv_compiler_get_constant_double_vector(compiler, -2147483648.0, component_count); + float_max_id = spirv_compiler_get_constant_double_vector(compiler, 2147483648.0, component_count); + } + else + { ++ write_mask = dst->write_mask; + int_min_id = spirv_compiler_get_constant_float_vector(compiler, -2147483648.0f, component_count); + float_max_id = spirv_compiler_get_constant_float_vector(compiler, 2147483648.0f, component_count); + } + ++ src_type_id = spirv_compiler_get_type_id_for_reg(compiler, &src->reg, write_mask); ++ dst_type_id = spirv_compiler_get_type_id_for_dst(compiler, dst); ++ src_id = spirv_compiler_emit_load_src(compiler, src, write_mask); + val_id = vkd3d_spirv_build_op_glsl_std450_max(builder, src_type_id, src_id, int_min_id); + + /* VSIR allows the destination of a signed conversion to be unsigned. */ +@@ -7992,6 +7994,7 @@ static void spirv_compiler_emit_ftou(struct spirv_compiler *compiler, + const struct vkd3d_shader_src_param *src = instruction->src; + uint32_t src_type_id, dst_type_id, condition_type_id; + unsigned int component_count; ++ uint32_t write_mask; + + VKD3D_ASSERT(instruction->dst_count == 1); + VKD3D_ASSERT(instruction->src_count == 1); +@@ -8001,21 +8004,23 @@ static void spirv_compiler_emit_ftou(struct spirv_compiler *compiler, + * and for NaN to yield zero. */ + + component_count = vsir_write_mask_component_count(dst->write_mask); +- src_type_id = spirv_compiler_get_type_id_for_reg(compiler, &src->reg, dst->write_mask); +- dst_type_id = spirv_compiler_get_type_id_for_dst(compiler, dst); +- src_id = spirv_compiler_emit_load_src(compiler, src, dst->write_mask); + + if (src->reg.data_type == VKD3D_DATA_DOUBLE) + { ++ write_mask = vkd3d_write_mask_from_component_count(component_count); + zero_id = spirv_compiler_get_constant_double_vector(compiler, 0.0, component_count); + float_max_id = spirv_compiler_get_constant_double_vector(compiler, 4294967296.0, component_count); + } + else + { ++ write_mask = dst->write_mask; + zero_id = spirv_compiler_get_constant_float_vector(compiler, 0.0f, component_count); + float_max_id = spirv_compiler_get_constant_float_vector(compiler, 4294967296.0f, component_count); + } + ++ src_type_id = spirv_compiler_get_type_id_for_reg(compiler, &src->reg, write_mask); ++ dst_type_id = spirv_compiler_get_type_id_for_dst(compiler, dst); ++ src_id = spirv_compiler_emit_load_src(compiler, src, write_mask); + val_id = vkd3d_spirv_build_op_glsl_std450_max(builder, src_type_id, src_id, zero_id); + + uint_max_id = spirv_compiler_get_constant_uint_vector(compiler, UINT_MAX, component_count); +@@ -8029,6 +8034,29 @@ static void spirv_compiler_emit_ftou(struct spirv_compiler *compiler, + spirv_compiler_emit_store_dst(compiler, dst, val_id); + } + ++static void spirv_compiler_emit_dtof(struct spirv_compiler *compiler, ++ const struct vkd3d_shader_instruction *instruction) ++{ ++ struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; ++ const struct vkd3d_shader_dst_param *dst = instruction->dst; ++ const struct vkd3d_shader_src_param *src = instruction->src; ++ uint32_t type_id, val_id, src_id; ++ unsigned int component_count; ++ uint32_t write_mask; ++ ++ component_count = vsir_write_mask_component_count(dst->write_mask); ++ write_mask = vkd3d_write_mask_from_component_count(component_count); ++ ++ src_id = spirv_compiler_emit_load_src(compiler, src, write_mask); ++ ++ type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, component_count); ++ val_id = vkd3d_spirv_build_op_tr1(builder, &builder->function_stream, SpvOpFConvert, type_id, src_id); ++ if (instruction->flags & VKD3DSI_PRECISE_XYZW) ++ vkd3d_spirv_build_op_decorate(builder, val_id, SpvDecorationNoContraction, NULL, 0); ++ ++ spirv_compiler_emit_store_dst(compiler, dst, val_id); ++} ++ + static void spirv_compiler_emit_bitfield_instruction(struct spirv_compiler *compiler, + const struct vkd3d_shader_instruction *instruction) + { +@@ -10419,7 +10447,6 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, + case VKD3DSIH_DDIV: + case VKD3DSIH_DIV: + case VKD3DSIH_DMUL: +- case VKD3DSIH_DTOF: + case VKD3DSIH_FREM: + case VKD3DSIH_FTOD: + case VKD3DSIH_IADD: +@@ -10507,6 +10534,9 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, + case VKD3DSIH_FTOU: + spirv_compiler_emit_ftou(compiler, instruction); + break; ++ case VKD3DSIH_DTOF: ++ spirv_compiler_emit_dtof(compiler, instruction); ++ break; + case VKD3DSIH_DEQO: + case VKD3DSIH_DGEO: + case VKD3DSIH_DLT: +diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c +index 872603052ac..7f115057622 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/tpf.c ++++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c +@@ -4758,6 +4758,8 @@ static void tpf_handle_instruction(struct tpf_compiler *tpf, const struct vkd3d_ + case VKD3DSIH_FTOU: + case VKD3DSIH_GATHER4: + case VKD3DSIH_GATHER4_PO: ++ case VKD3DSIH_GATHER4_C: ++ case VKD3DSIH_GATHER4_PO_C: + case VKD3DSIH_GEO: + case VKD3DSIH_HS_CONTROL_POINT_PHASE: + case VKD3DSIH_HS_FORK_PHASE: +diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +index 3bfb0a7c3cd..7e8ec156aad 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h ++++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +@@ -595,28 +595,25 @@ enum vkd3d_shader_opcode + + enum vkd3d_shader_register_type + { +- VKD3DSPR_TEMP = 0, +- VKD3DSPR_INPUT = 1, +- VKD3DSPR_CONST = 2, +- VKD3DSPR_ADDR = 3, +- VKD3DSPR_TEXTURE = 3, +- VKD3DSPR_RASTOUT = 4, +- VKD3DSPR_ATTROUT = 5, +- VKD3DSPR_TEXCRDOUT = 6, +- VKD3DSPR_OUTPUT = 6, +- VKD3DSPR_CONSTINT = 7, +- VKD3DSPR_COLOROUT = 8, +- VKD3DSPR_DEPTHOUT = 9, +- VKD3DSPR_COMBINED_SAMPLER = 10, +- VKD3DSPR_CONST2 = 11, +- VKD3DSPR_CONST3 = 12, +- VKD3DSPR_CONST4 = 13, +- VKD3DSPR_CONSTBOOL = 14, +- VKD3DSPR_LOOP = 15, +- VKD3DSPR_TEMPFLOAT16 = 16, +- VKD3DSPR_MISCTYPE = 17, +- VKD3DSPR_LABEL = 18, +- VKD3DSPR_PREDICATE = 19, ++ VKD3DSPR_TEMP, ++ VKD3DSPR_INPUT, ++ VKD3DSPR_CONST, ++ VKD3DSPR_ADDR, ++ VKD3DSPR_TEXTURE, ++ VKD3DSPR_RASTOUT, ++ VKD3DSPR_ATTROUT, ++ VKD3DSPR_TEXCRDOUT, ++ VKD3DSPR_OUTPUT, ++ VKD3DSPR_CONSTINT, ++ VKD3DSPR_COLOROUT, ++ VKD3DSPR_DEPTHOUT, ++ VKD3DSPR_COMBINED_SAMPLER, ++ VKD3DSPR_CONSTBOOL, ++ VKD3DSPR_LOOP, ++ VKD3DSPR_TEMPFLOAT16, ++ VKD3DSPR_MISCTYPE, ++ VKD3DSPR_LABEL, ++ VKD3DSPR_PREDICATE, + VKD3DSPR_IMMCONST, + VKD3DSPR_IMMCONST64, + VKD3DSPR_CONSTBUFFER, +-- +2.45.2 + diff --git a/patches/vkd3d-latest/0003-Updated-vkd3d-to-b60995b106724581ed33d3ea327e7dd662f.patch b/patches/vkd3d-latest/0003-Updated-vkd3d-to-b60995b106724581ed33d3ea327e7dd662f.patch new file mode 100644 index 00000000..a2734d23 --- /dev/null +++ b/patches/vkd3d-latest/0003-Updated-vkd3d-to-b60995b106724581ed33d3ea327e7dd662f.patch @@ -0,0 +1,527 @@ +From b5cda26fc89a32ae26cb04cba1e6c62c899f6419 Mon Sep 17 00:00:00 2001 +From: Alistair Leslie-Hughes +Date: Sat, 21 Dec 2024 12:28:11 +1100 +Subject: [PATCH] Updated vkd3d to b60995b106724581ed33d3ea327e7dd662f1f4d9. + +--- + libs/vkd3d/libs/vkd3d-shader/hlsl.h | 3 - + libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 204 +++++++++++++++++++- + libs/vkd3d/libs/vkd3d-shader/ir.c | 37 +++- + libs/vkd3d/libs/vkd3d-shader/tpf.c | 199 ------------------- + 4 files changed, 232 insertions(+), 211 deletions(-) + +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h +index 2acc003c9a1..b0e2b54c348 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h +@@ -1688,9 +1688,6 @@ struct extern_resource *sm4_get_extern_resources(struct hlsl_ctx *ctx, unsigned + void sm4_free_extern_resources(struct extern_resource *extern_resources, unsigned int count); + void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rdef); + +-enum vkd3d_shader_interpolation_mode sm4_get_interpolation_mode(struct hlsl_type *type, +- unsigned int storage_modifiers); +- + struct hlsl_ir_function_decl *hlsl_compile_internal_function(struct hlsl_ctx *ctx, const char *name, const char *hlsl); + + int hlsl_lexer_compile(struct hlsl_ctx *ctx, const struct vkd3d_shader_code *hlsl); +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +index 08f139f5e8f..4ccbed78f38 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +@@ -5489,7 +5489,8 @@ static uint32_t allocate_temp_registers(struct hlsl_ctx *ctx, struct hlsl_ir_fun + return allocator.reg_count; + } + +-enum vkd3d_shader_interpolation_mode sm4_get_interpolation_mode(struct hlsl_type *type, unsigned int storage_modifiers) ++static enum vkd3d_shader_interpolation_mode sm4_get_interpolation_mode(struct hlsl_type *type, ++ unsigned int storage_modifiers) + { + unsigned int i; + +@@ -10083,6 +10084,207 @@ static void sm4_generate_vsir_add_function(struct hlsl_ctx *ctx, + generate_vsir_add_program_instruction(ctx, program, &func->loc, VKD3DSIH_RET, 0, 0); + } + ++static int sm4_compare_extern_resources(const void *a, const void *b) ++{ ++ const struct extern_resource *aa = a; ++ const struct extern_resource *bb = b; ++ int r; ++ ++ if ((r = vkd3d_u32_compare(aa->regset, bb->regset))) ++ return r; ++ ++ if ((r = vkd3d_u32_compare(aa->space, bb->space))) ++ return r; ++ ++ return vkd3d_u32_compare(aa->index, bb->index); ++} ++ ++static const char *string_skip_tag(const char *string) ++{ ++ if (!strncmp(string, "", strlen(""))) ++ return string + strlen(""); ++ return string; ++} ++ ++void sm4_free_extern_resources(struct extern_resource *extern_resources, unsigned int count) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < count; ++i) ++ { ++ vkd3d_free(extern_resources[i].name); ++ } ++ vkd3d_free(extern_resources); ++} ++ ++struct extern_resource *sm4_get_extern_resources(struct hlsl_ctx *ctx, unsigned int *count) ++{ ++ 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; ++ struct hlsl_buffer *buffer; ++ enum hlsl_regset regset; ++ size_t capacity = 0; ++ char *name; ++ ++ *count = 0; ++ ++ LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) ++ { ++ if (separate_components) ++ { ++ unsigned int component_count = hlsl_type_component_count(var->data_type); ++ unsigned int k, regset_offset; ++ ++ for (k = 0; k < component_count; ++k) ++ { ++ struct hlsl_type *component_type = hlsl_type_get_component_type(ctx, var->data_type, k); ++ struct vkd3d_string_buffer *name_buffer; ++ ++ if (!hlsl_type_is_resource(component_type)) ++ continue; ++ ++ regset_offset = hlsl_type_get_component_offset(ctx, var->data_type, k, ®set); ++ if (regset_offset > var->regs[regset].allocation_size) ++ continue; ++ ++ if (!var->objects_usage[regset][regset_offset].used) ++ continue; ++ ++ if (!(hlsl_array_reserve(ctx, (void **)&extern_resources, ++ &capacity, *count + 1, sizeof(*extern_resources)))) ++ { ++ sm4_free_extern_resources(extern_resources, *count); ++ *count = 0; ++ return NULL; ++ } ++ ++ if (!(name_buffer = hlsl_component_to_string(ctx, var, k))) ++ { ++ sm4_free_extern_resources(extern_resources, *count); ++ *count = 0; ++ return NULL; ++ } ++ if (!(name = hlsl_strdup(ctx, string_skip_tag(name_buffer->buffer)))) ++ { ++ sm4_free_extern_resources(extern_resources, *count); ++ *count = 0; ++ hlsl_release_string_buffer(ctx, name_buffer); ++ return NULL; ++ } ++ 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].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; ++ } ++ } ++ else ++ { ++ unsigned int r; ++ ++ if (!hlsl_type_is_resource(var->data_type)) ++ continue; ++ ++ for (r = 0; r <= HLSL_REGSET_LAST; ++r) ++ { ++ if (!var->regs[r].allocated) ++ continue; ++ ++ if (!(hlsl_array_reserve(ctx, (void **)&extern_resources, ++ &capacity, *count + 1, sizeof(*extern_resources)))) ++ { ++ sm4_free_extern_resources(extern_resources, *count); ++ *count = 0; ++ return NULL; ++ } ++ ++ if (!(name = hlsl_strdup(ctx, string_skip_tag(var->name)))) ++ { ++ sm4_free_extern_resources(extern_resources, *count); ++ *count = 0; ++ return NULL; ++ } ++ ++ extern_resources[*count].var = var; ++ extern_resources[*count].buffer = NULL; ++ ++ extern_resources[*count].name = name; ++ /* 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; ++ } ++ } ++ } ++ ++ LIST_FOR_EACH_ENTRY(buffer, &ctx->buffers, struct hlsl_buffer, entry) ++ { ++ if (!buffer->reg.allocated) ++ continue; ++ ++ if (!(hlsl_array_reserve(ctx, (void **)&extern_resources, ++ &capacity, *count + 1, sizeof(*extern_resources)))) ++ { ++ sm4_free_extern_resources(extern_resources, *count); ++ *count = 0; ++ return NULL; ++ } ++ ++ if (!(name = hlsl_strdup(ctx, buffer->name))) ++ { ++ sm4_free_extern_resources(extern_resources, *count); ++ *count = 0; ++ return NULL; ++ } ++ ++ extern_resources[*count].var = NULL; ++ extern_resources[*count].buffer = buffer; ++ ++ extern_resources[*count].name = name; ++ 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; ++ } ++ ++ qsort(extern_resources, *count, sizeof(*extern_resources), sm4_compare_extern_resources); ++ ++ return extern_resources; ++} ++ + static void generate_vsir_scan_required_features(struct hlsl_ctx *ctx, struct vsir_program *program) + { + struct extern_resource *extern_resources; +diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c +index ec7e2d036c8..c2e4b5a4947 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/ir.c ++++ b/libs/vkd3d/libs/vkd3d-shader/ir.c +@@ -8141,6 +8141,16 @@ static void vsir_validate_dst_param(struct validation_context *ctx, + } + } + ++static void vsir_validate_io_src_param(struct validation_context *ctx, ++ const struct vkd3d_shader_src_param *src) ++{ ++ struct vsir_io_register_data io_reg_data; ++ ++ if (!vsir_get_io_register_data(ctx, src->reg.type, &io_reg_data) || !(io_reg_data.flags & INPUT_BIT)) ++ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE, ++ "Invalid register type %#x used as source parameter.", src->reg.type); ++} ++ + static void vsir_validate_src_param(struct validation_context *ctx, + const struct vkd3d_shader_src_param *src) + { +@@ -8176,18 +8186,24 @@ static void vsir_validate_src_param(struct validation_context *ctx, + "Invalid NULL register used as source parameter."); + break; + ++ case VKD3DSPR_INPUT: ++ vsir_validate_io_src_param(ctx, src); ++ break; ++ + case VKD3DSPR_OUTPUT: +- if (ctx->program->shader_version.type != VKD3D_SHADER_TYPE_HULL +- || (ctx->phase != VKD3DSIH_HS_FORK_PHASE && ctx->phase != VKD3DSIH_HS_JOIN_PHASE)) +- validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE, +- "Invalid OUTPUT register used as source parameter."); ++ vsir_validate_io_src_param(ctx, src); ++ break; ++ ++ case VKD3DSPR_INCONTROLPOINT: ++ vsir_validate_io_src_param(ctx, src); ++ break; ++ ++ case VKD3DSPR_OUTCONTROLPOINT: ++ vsir_validate_io_src_param(ctx, src); + break; + + case VKD3DSPR_PATCHCONST: +- if (ctx->program->shader_version.type != VKD3D_SHADER_TYPE_DOMAIN +- && ctx->program->shader_version.type != VKD3D_SHADER_TYPE_HULL) +- validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE, +- "PATCHCONST register used as source parameters are only allowed in Hull and Domain Shaders."); ++ vsir_validate_io_src_param(ctx, src); + break; + + default: +@@ -8293,6 +8309,11 @@ static void vsir_validate_signature_element(struct validation_context *ctx, + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SIGNATURE, + "element %u of %s signature: Invalid zero register count.", idx, signature_type_name); + ++ if (ctx->program->normalisation_level < VSIR_NORMALISED_SM6 && element->register_count != 1) ++ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SIGNATURE, ++ "element %u of %s signature: Invalid register count %u.", idx, signature_type_name, ++ element->register_count); ++ + if (element->register_index != UINT_MAX && (element->register_index >= MAX_REG_OUTPUT + || MAX_REG_OUTPUT - element->register_index < element->register_count)) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SIGNATURE, +diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c +index 7f115057622..bdc1c738a32 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/tpf.c ++++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c +@@ -3483,205 +3483,6 @@ static D3D_SRV_DIMENSION sm4_rdef_resource_dimension(const struct hlsl_type *typ + } + } + +-static int sm4_compare_extern_resources(const void *a, const void *b) +-{ +- const struct extern_resource *aa = (const struct extern_resource *)a; +- const struct extern_resource *bb = (const struct extern_resource *)b; +- int r; +- +- if ((r = vkd3d_u32_compare(aa->regset, bb->regset))) +- return r; +- +- if ((r = vkd3d_u32_compare(aa->space, bb->space))) +- return r; +- +- return vkd3d_u32_compare(aa->index, bb->index); +-} +- +-void sm4_free_extern_resources(struct extern_resource *extern_resources, unsigned int count) +-{ +- unsigned int i; +- +- for (i = 0; i < count; ++i) +- vkd3d_free(extern_resources[i].name); +- vkd3d_free(extern_resources); +-} +- +-static const char *string_skip_tag(const char *string) +-{ +- if (!strncmp(string, "", strlen(""))) +- return string + strlen(""); +- return string; +-} +- +-struct extern_resource *sm4_get_extern_resources(struct hlsl_ctx *ctx, unsigned int *count) +-{ +- 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; +- struct hlsl_buffer *buffer; +- enum hlsl_regset regset; +- size_t capacity = 0; +- char *name; +- +- *count = 0; +- +- LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) +- { +- if (separate_components) +- { +- unsigned int component_count = hlsl_type_component_count(var->data_type); +- unsigned int k, regset_offset; +- +- for (k = 0; k < component_count; ++k) +- { +- struct hlsl_type *component_type = hlsl_type_get_component_type(ctx, var->data_type, k); +- struct vkd3d_string_buffer *name_buffer; +- +- if (!hlsl_type_is_resource(component_type)) +- continue; +- +- regset_offset = hlsl_type_get_component_offset(ctx, var->data_type, k, ®set); +- +- if (regset_offset > var->regs[regset].allocation_size) +- continue; +- +- if (var->objects_usage[regset][regset_offset].used) +- { +- if (!(hlsl_array_reserve(ctx, (void **)&extern_resources, &capacity, *count + 1, +- sizeof(*extern_resources)))) +- { +- sm4_free_extern_resources(extern_resources, *count); +- *count = 0; +- return NULL; +- } +- +- if (!(name_buffer = hlsl_component_to_string(ctx, var, k))) +- { +- sm4_free_extern_resources(extern_resources, *count); +- *count = 0; +- return NULL; +- } +- if (!(name = hlsl_strdup(ctx, string_skip_tag(name_buffer->buffer)))) +- { +- sm4_free_extern_resources(extern_resources, *count); +- *count = 0; +- hlsl_release_string_buffer(ctx, name_buffer); +- return NULL; +- } +- 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].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; +- } +- } +- } +- else +- { +- unsigned int r; +- +- if (!hlsl_type_is_resource(var->data_type)) +- continue; +- +- for (r = 0; r <= HLSL_REGSET_LAST; ++r) +- { +- if (!var->regs[r].allocated) +- continue; +- +- if (!(hlsl_array_reserve(ctx, (void **)&extern_resources, &capacity, *count + 1, +- sizeof(*extern_resources)))) +- { +- sm4_free_extern_resources(extern_resources, *count); +- *count = 0; +- return NULL; +- } +- +- if (!(name = hlsl_strdup(ctx, string_skip_tag(var->name)))) +- { +- sm4_free_extern_resources(extern_resources, *count); +- *count = 0; +- return NULL; +- } +- +- extern_resources[*count].var = var; +- extern_resources[*count].buffer = NULL; +- +- extern_resources[*count].name = name; +- /* 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; +- } +- } +- } +- +- LIST_FOR_EACH_ENTRY(buffer, &ctx->buffers, struct hlsl_buffer, entry) +- { +- if (!buffer->reg.allocated) +- continue; +- +- if (!(hlsl_array_reserve(ctx, (void **)&extern_resources, &capacity, *count + 1, +- sizeof(*extern_resources)))) +- { +- sm4_free_extern_resources(extern_resources, *count); +- *count = 0; +- return NULL; +- } +- +- if (!(name = hlsl_strdup(ctx, buffer->name))) +- { +- sm4_free_extern_resources(extern_resources, *count); +- *count = 0; +- return NULL; +- } +- +- extern_resources[*count].var = NULL; +- extern_resources[*count].buffer = buffer; +- +- extern_resources[*count].name = name; +- 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; +- } +- +- qsort(extern_resources, *count, sizeof(*extern_resources), sm4_compare_extern_resources); +- return extern_resources; +-} +- + /* For some reason, for matrices, values from default value initializers end up in different + * components than from regular initializers. Default value initializers fill the matrix in + * vertical reading order (left-to-right top-to-bottom) instead of regular reading order +-- +2.45.2 +