diff --git a/patches/vkd3d-latest/0001-Updated-vkd3d-to-ca05e57e67306e9b97eb22a35cd77728e3e.patch b/patches/vkd3d-latest/0001-Updated-vkd3d-to-ca05e57e67306e9b97eb22a35cd77728e3e.patch index 75fecc02..611b8984 100644 --- a/patches/vkd3d-latest/0001-Updated-vkd3d-to-ca05e57e67306e9b97eb22a35cd77728e3e.patch +++ b/patches/vkd3d-latest/0001-Updated-vkd3d-to-ca05e57e67306e9b97eb22a35cd77728e3e.patch @@ -1,7 +1,7 @@ -From a66fff01c4ccc1b1d25f6cf92a9a2301281fbbc4 Mon Sep 17 00:00:00 2001 +From b7cf024c15c33db9f98f4c23e6ed0c151e61de9a Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Wed, 17 May 2023 08:35:40 +1000 -Subject: [PATCH 1/3] Updated vkd3d to ca05e57e67306e9b97eb22a35cd77728e3e91db9 +Subject: [PATCH] Updated vkd3d to ca05e57e67306e9b97eb22a35cd77728e3e91db9 --- libs/vkd3d/include/list.h | 270 +++++++++++ diff --git a/patches/vkd3d-latest/0002-Updated-vkd3d-to-1006e8cbd4f46b560b939a894a03b08ce1f.patch b/patches/vkd3d-latest/0002-Updated-vkd3d-to-1006e8cbd4f46b560b939a894a03b08ce1f.patch index ad6f9c33..57ff7bf8 100644 --- a/patches/vkd3d-latest/0002-Updated-vkd3d-to-1006e8cbd4f46b560b939a894a03b08ce1f.patch +++ b/patches/vkd3d-latest/0002-Updated-vkd3d-to-1006e8cbd4f46b560b939a894a03b08ce1f.patch @@ -1,8 +1,7 @@ -From 76bde8ac9ee47e0e7078a8510c0677b48300de50 Mon Sep 17 00:00:00 2001 +From 5bdc4358540e8a56d72dac033f0ac5606b29d2b1 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Fri, 29 Sep 2023 13:08:54 +1000 -Subject: [PATCH 2/3] Updated vkd3d to - 1006e8cbd4f46b560b939a894a03b08ce1f20def. +Subject: [PATCH] Updated vkd3d to 1006e8cbd4f46b560b939a894a03b08ce1f20def. --- libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 33 +- diff --git a/patches/vkd3d-latest/0003-Updated-vkd3d-to-c92772657f47fa906b3414e3d90bbc3fcb2.patch b/patches/vkd3d-latest/0003-Updated-vkd3d-to-c92772657f47fa906b3414e3d90bbc3fcb2.patch new file mode 100644 index 00000000..d670ca51 --- /dev/null +++ b/patches/vkd3d-latest/0003-Updated-vkd3d-to-c92772657f47fa906b3414e3d90bbc3fcb2.patch @@ -0,0 +1,1858 @@ +From cd447febf8dae4ef53e9088a06d66dd46ddb93d5 Mon Sep 17 00:00:00 2001 +From: Alistair Leslie-Hughes +Date: Wed, 4 Oct 2023 11:35:18 +1100 +Subject: [PATCH] Updated vkd3d to c92772657f47fa906b3414e3d90bbc3fcb2d2090. + +--- + libs/vkd3d/libs/vkd3d-common/blob.c | 1 + + libs/vkd3d/libs/vkd3d-shader/hlsl.h | 2 +- + libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 2 +- + libs/vkd3d/libs/vkd3d-shader/tpf.c | 327 +++++++++-------- + .../libs/vkd3d-shader/vkd3d_shader_private.h | 2 +- + libs/vkd3d/libs/vkd3d/command.c | 332 +++++++++++------- + libs/vkd3d/libs/vkd3d/device.c | 4 +- + libs/vkd3d/libs/vkd3d/vkd3d_private.h | 3 +- + 8 files changed, 384 insertions(+), 289 deletions(-) + +diff --git a/libs/vkd3d/libs/vkd3d-common/blob.c b/libs/vkd3d/libs/vkd3d-common/blob.c +index ce00e536d39..fa2812619ac 100644 +--- a/libs/vkd3d/libs/vkd3d-common/blob.c ++++ b/libs/vkd3d/libs/vkd3d-common/blob.c +@@ -18,6 +18,7 @@ + + #define COBJMACROS + ++#define CONST_VTABLE + #include "vkd3d.h" + #include "vkd3d_blob.h" + #include "vkd3d_debug.h" +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h +index 2cde5d58eba..f33e1d74378 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h +@@ -1273,7 +1273,7 @@ int hlsl_sm1_write(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_fun + bool hlsl_sm4_usage_from_semantic(struct hlsl_ctx *ctx, + const struct hlsl_semantic *semantic, bool output, D3D_NAME *usage); + bool hlsl_sm4_register_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_semantic *semantic, +- bool output, enum vkd3d_shader_register_type *type, enum vkd3d_sm4_swizzle_type *swizzle_type, bool *has_idx); ++ bool output, enum vkd3d_shader_register_type *type, bool *has_idx); + int hlsl_sm4_write(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, struct vkd3d_shader_code *out); + + struct hlsl_ir_function_decl *hlsl_compile_internal_function(struct hlsl_ctx *ctx, const char *name, const char *hlsl); +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +index 76572cf93ec..b113696ebb7 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +@@ -3703,7 +3703,7 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var + "Invalid semantic '%s'.", var->semantic.name); + return; + } +- if ((builtin = hlsl_sm4_register_from_semantic(ctx, &var->semantic, output, &type, NULL, &has_idx))) ++ if ((builtin = hlsl_sm4_register_from_semantic(ctx, &var->semantic, output, &type, &has_idx))) + reg = has_idx ? var->semantic.index : 0; + } + +diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c +index 63771736eaa..fbd8458356d 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/tpf.c ++++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c +@@ -510,6 +510,8 @@ enum vkd3d_sm4_swizzle_type + VKD3D_SM4_SWIZZLE_NONE = 0x0, /* swizzle bitfield contains a mask */ + VKD3D_SM4_SWIZZLE_VEC4 = 0x1, + VKD3D_SM4_SWIZZLE_SCALAR = 0x2, ++ ++ VKD3D_SM4_SWIZZLE_INVALID = ~0u, + }; + + enum vkd3d_sm4_dimension +@@ -1526,6 +1528,9 @@ struct vkd3d_sm4_register_type_info + { + enum vkd3d_sm4_register_type sm4_type; + enum vkd3d_shader_register_type vkd3d_type; ++ ++ /* Swizzle type to be used for src registers when their dimension is VKD3D_SM4_DIMENSION_VEC4. */ ++ enum vkd3d_sm4_swizzle_type default_src_swizzle_type; + }; + + static const enum vkd3d_shader_register_precision register_precision_table[] = +@@ -1565,42 +1570,42 @@ static void init_sm4_lookup_tables(struct vkd3d_sm4_lookup_tables *lookup) + + static const struct vkd3d_sm4_register_type_info register_type_table[] = + { +- {VKD3D_SM4_RT_TEMP, VKD3DSPR_TEMP}, +- {VKD3D_SM4_RT_INPUT, VKD3DSPR_INPUT}, +- {VKD3D_SM4_RT_OUTPUT, VKD3DSPR_OUTPUT}, +- {VKD3D_SM4_RT_INDEXABLE_TEMP, VKD3DSPR_IDXTEMP}, +- {VKD3D_SM4_RT_IMMCONST, VKD3DSPR_IMMCONST}, +- {VKD3D_SM4_RT_IMMCONST64, VKD3DSPR_IMMCONST64}, +- {VKD3D_SM4_RT_SAMPLER, VKD3DSPR_SAMPLER}, +- {VKD3D_SM4_RT_RESOURCE, VKD3DSPR_RESOURCE}, +- {VKD3D_SM4_RT_CONSTBUFFER, VKD3DSPR_CONSTBUFFER}, +- {VKD3D_SM4_RT_IMMCONSTBUFFER, VKD3DSPR_IMMCONSTBUFFER}, +- {VKD3D_SM4_RT_PRIMID, VKD3DSPR_PRIMID}, +- {VKD3D_SM4_RT_DEPTHOUT, VKD3DSPR_DEPTHOUT}, +- {VKD3D_SM4_RT_NULL, VKD3DSPR_NULL}, +- {VKD3D_SM4_RT_RASTERIZER, VKD3DSPR_RASTERIZER}, +- {VKD3D_SM4_RT_OMASK, VKD3DSPR_SAMPLEMASK}, +- {VKD3D_SM5_RT_STREAM, VKD3DSPR_STREAM}, +- {VKD3D_SM5_RT_FUNCTION_BODY, VKD3DSPR_FUNCTIONBODY}, +- {VKD3D_SM5_RT_FUNCTION_POINTER, VKD3DSPR_FUNCTIONPOINTER}, +- {VKD3D_SM5_RT_OUTPUT_CONTROL_POINT_ID, VKD3DSPR_OUTPOINTID}, +- {VKD3D_SM5_RT_FORK_INSTANCE_ID, VKD3DSPR_FORKINSTID}, +- {VKD3D_SM5_RT_JOIN_INSTANCE_ID, VKD3DSPR_JOININSTID}, +- {VKD3D_SM5_RT_INPUT_CONTROL_POINT, VKD3DSPR_INCONTROLPOINT}, +- {VKD3D_SM5_RT_OUTPUT_CONTROL_POINT, VKD3DSPR_OUTCONTROLPOINT}, +- {VKD3D_SM5_RT_PATCH_CONSTANT_DATA, VKD3DSPR_PATCHCONST}, +- {VKD3D_SM5_RT_DOMAIN_LOCATION, VKD3DSPR_TESSCOORD}, +- {VKD3D_SM5_RT_UAV, VKD3DSPR_UAV}, +- {VKD3D_SM5_RT_SHARED_MEMORY, VKD3DSPR_GROUPSHAREDMEM}, +- {VKD3D_SM5_RT_THREAD_ID, VKD3DSPR_THREADID}, +- {VKD3D_SM5_RT_THREAD_GROUP_ID, VKD3DSPR_THREADGROUPID}, +- {VKD3D_SM5_RT_LOCAL_THREAD_ID, VKD3DSPR_LOCALTHREADID}, +- {VKD3D_SM5_RT_COVERAGE, VKD3DSPR_COVERAGE}, +- {VKD3D_SM5_RT_LOCAL_THREAD_INDEX, VKD3DSPR_LOCALTHREADINDEX}, +- {VKD3D_SM5_RT_GS_INSTANCE_ID, VKD3DSPR_GSINSTID}, +- {VKD3D_SM5_RT_DEPTHOUT_GREATER_EQUAL, VKD3DSPR_DEPTHOUTGE}, +- {VKD3D_SM5_RT_DEPTHOUT_LESS_EQUAL, VKD3DSPR_DEPTHOUTLE}, +- {VKD3D_SM5_RT_OUTPUT_STENCIL_REF, VKD3DSPR_OUTSTENCILREF}, ++ {VKD3D_SM4_RT_TEMP, VKD3DSPR_TEMP, VKD3D_SM4_SWIZZLE_VEC4}, ++ {VKD3D_SM4_RT_INPUT, VKD3DSPR_INPUT, VKD3D_SM4_SWIZZLE_VEC4}, ++ {VKD3D_SM4_RT_OUTPUT, VKD3DSPR_OUTPUT, VKD3D_SM4_SWIZZLE_INVALID}, ++ {VKD3D_SM4_RT_INDEXABLE_TEMP, VKD3DSPR_IDXTEMP, VKD3D_SM4_SWIZZLE_VEC4}, ++ {VKD3D_SM4_RT_IMMCONST, VKD3DSPR_IMMCONST, VKD3D_SM4_SWIZZLE_NONE}, ++ {VKD3D_SM4_RT_IMMCONST64, VKD3DSPR_IMMCONST64, VKD3D_SM4_SWIZZLE_NONE}, ++ {VKD3D_SM4_RT_SAMPLER, VKD3DSPR_SAMPLER, VKD3D_SM4_SWIZZLE_SCALAR}, ++ {VKD3D_SM4_RT_RESOURCE, VKD3DSPR_RESOURCE, VKD3D_SM4_SWIZZLE_VEC4}, ++ {VKD3D_SM4_RT_CONSTBUFFER, VKD3DSPR_CONSTBUFFER, VKD3D_SM4_SWIZZLE_VEC4}, ++ {VKD3D_SM4_RT_IMMCONSTBUFFER, VKD3DSPR_IMMCONSTBUFFER, VKD3D_SM4_SWIZZLE_VEC4}, ++ {VKD3D_SM4_RT_PRIMID, VKD3DSPR_PRIMID, VKD3D_SM4_SWIZZLE_NONE}, ++ {VKD3D_SM4_RT_DEPTHOUT, VKD3DSPR_DEPTHOUT, VKD3D_SM4_SWIZZLE_VEC4}, ++ {VKD3D_SM4_RT_NULL, VKD3DSPR_NULL, VKD3D_SM4_SWIZZLE_INVALID}, ++ {VKD3D_SM4_RT_RASTERIZER, VKD3DSPR_RASTERIZER, VKD3D_SM4_SWIZZLE_VEC4}, ++ {VKD3D_SM4_RT_OMASK, VKD3DSPR_SAMPLEMASK, VKD3D_SM4_SWIZZLE_VEC4}, ++ {VKD3D_SM5_RT_STREAM, VKD3DSPR_STREAM, VKD3D_SM4_SWIZZLE_VEC4}, ++ {VKD3D_SM5_RT_FUNCTION_BODY, VKD3DSPR_FUNCTIONBODY, VKD3D_SM4_SWIZZLE_VEC4}, ++ {VKD3D_SM5_RT_FUNCTION_POINTER, VKD3DSPR_FUNCTIONPOINTER, VKD3D_SM4_SWIZZLE_VEC4}, ++ {VKD3D_SM5_RT_OUTPUT_CONTROL_POINT_ID, VKD3DSPR_OUTPOINTID, VKD3D_SM4_SWIZZLE_VEC4}, ++ {VKD3D_SM5_RT_FORK_INSTANCE_ID, VKD3DSPR_FORKINSTID, VKD3D_SM4_SWIZZLE_VEC4}, ++ {VKD3D_SM5_RT_JOIN_INSTANCE_ID, VKD3DSPR_JOININSTID, VKD3D_SM4_SWIZZLE_VEC4}, ++ {VKD3D_SM5_RT_INPUT_CONTROL_POINT, VKD3DSPR_INCONTROLPOINT, VKD3D_SM4_SWIZZLE_VEC4}, ++ {VKD3D_SM5_RT_OUTPUT_CONTROL_POINT, VKD3DSPR_OUTCONTROLPOINT, VKD3D_SM4_SWIZZLE_VEC4}, ++ {VKD3D_SM5_RT_PATCH_CONSTANT_DATA, VKD3DSPR_PATCHCONST, VKD3D_SM4_SWIZZLE_VEC4}, ++ {VKD3D_SM5_RT_DOMAIN_LOCATION, VKD3DSPR_TESSCOORD, VKD3D_SM4_SWIZZLE_VEC4}, ++ {VKD3D_SM5_RT_UAV, VKD3DSPR_UAV, VKD3D_SM4_SWIZZLE_VEC4}, ++ {VKD3D_SM5_RT_SHARED_MEMORY, VKD3DSPR_GROUPSHAREDMEM, VKD3D_SM4_SWIZZLE_VEC4}, ++ {VKD3D_SM5_RT_THREAD_ID, VKD3DSPR_THREADID, VKD3D_SM4_SWIZZLE_VEC4}, ++ {VKD3D_SM5_RT_THREAD_GROUP_ID, VKD3DSPR_THREADGROUPID, VKD3D_SM4_SWIZZLE_VEC4}, ++ {VKD3D_SM5_RT_LOCAL_THREAD_ID, VKD3DSPR_LOCALTHREADID, VKD3D_SM4_SWIZZLE_VEC4}, ++ {VKD3D_SM5_RT_COVERAGE, VKD3DSPR_COVERAGE, VKD3D_SM4_SWIZZLE_VEC4}, ++ {VKD3D_SM5_RT_LOCAL_THREAD_INDEX, VKD3DSPR_LOCALTHREADINDEX,VKD3D_SM4_SWIZZLE_VEC4}, ++ {VKD3D_SM5_RT_GS_INSTANCE_ID, VKD3DSPR_GSINSTID, VKD3D_SM4_SWIZZLE_VEC4}, ++ {VKD3D_SM5_RT_DEPTHOUT_GREATER_EQUAL, VKD3DSPR_DEPTHOUTGE, VKD3D_SM4_SWIZZLE_VEC4}, ++ {VKD3D_SM5_RT_DEPTHOUT_LESS_EQUAL, VKD3DSPR_DEPTHOUTLE, VKD3D_SM4_SWIZZLE_VEC4}, ++ {VKD3D_SM5_RT_OUTPUT_STENCIL_REF, VKD3DSPR_OUTSTENCILREF, VKD3D_SM4_SWIZZLE_VEC4}, + }; + + memset(lookup, 0, sizeof(*lookup)); +@@ -1636,6 +1641,16 @@ static const struct vkd3d_sm4_register_type_info *get_info_from_vkd3d_register_t + return lookup->register_type_info_from_vkd3d[vkd3d_type]; + } + ++static enum vkd3d_sm4_swizzle_type vkd3d_sm4_get_default_swizzle_type( ++ const struct vkd3d_sm4_lookup_tables *lookup, enum vkd3d_shader_register_type vkd3d_type) ++{ ++ const struct vkd3d_sm4_register_type_info *register_type_info = ++ get_info_from_vkd3d_register_type(lookup, vkd3d_type); ++ ++ assert(register_type_info); ++ return register_type_info->default_src_swizzle_type; ++} ++ + static void map_register(const struct vkd3d_shader_sm4_parser *sm4, struct vkd3d_shader_register *reg) + { + switch (sm4->p.shader_version.type) +@@ -2700,7 +2715,7 @@ static bool type_is_integer(const struct hlsl_type *type) + } + + bool hlsl_sm4_register_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_semantic *semantic, +- bool output, enum vkd3d_shader_register_type *type, enum vkd3d_sm4_swizzle_type *swizzle_type, bool *has_idx) ++ bool output, enum vkd3d_shader_register_type *type, bool *has_idx) + { + unsigned int i; + +@@ -2709,25 +2724,24 @@ bool hlsl_sm4_register_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_sem + const char *semantic; + bool output; + enum vkd3d_shader_type shader_type; +- enum vkd3d_sm4_swizzle_type swizzle_type; + enum vkd3d_shader_register_type type; + bool has_idx; + } + register_table[] = + { +- {"sv_dispatchthreadid", false, VKD3D_SHADER_TYPE_COMPUTE, VKD3D_SM4_SWIZZLE_VEC4, VKD3DSPR_THREADID, false}, +- {"sv_groupid", false, VKD3D_SHADER_TYPE_COMPUTE, VKD3D_SM4_SWIZZLE_VEC4, VKD3DSPR_THREADGROUPID, false}, +- {"sv_groupthreadid", false, VKD3D_SHADER_TYPE_COMPUTE, VKD3D_SM4_SWIZZLE_VEC4, VKD3DSPR_LOCALTHREADID, false}, ++ {"sv_dispatchthreadid", false, VKD3D_SHADER_TYPE_COMPUTE, VKD3DSPR_THREADID, false}, ++ {"sv_groupid", false, VKD3D_SHADER_TYPE_COMPUTE, VKD3DSPR_THREADGROUPID, false}, ++ {"sv_groupthreadid", false, VKD3D_SHADER_TYPE_COMPUTE, VKD3DSPR_LOCALTHREADID, false}, + +- {"sv_primitiveid", false, VKD3D_SHADER_TYPE_GEOMETRY, VKD3D_SM4_SWIZZLE_NONE, VKD3DSPR_PRIMID, false}, ++ {"sv_primitiveid", false, VKD3D_SHADER_TYPE_GEOMETRY, VKD3DSPR_PRIMID, false}, + + /* Put sv_target in this table, instead of letting it fall through to + * default varying allocation, so that the register index matches the + * usage index. */ +- {"color", true, VKD3D_SHADER_TYPE_PIXEL, VKD3D_SM4_SWIZZLE_VEC4, VKD3DSPR_OUTPUT, true}, +- {"depth", true, VKD3D_SHADER_TYPE_PIXEL, VKD3D_SM4_SWIZZLE_VEC4, VKD3DSPR_DEPTHOUT, false}, +- {"sv_depth", true, VKD3D_SHADER_TYPE_PIXEL, VKD3D_SM4_SWIZZLE_VEC4, VKD3DSPR_DEPTHOUT, false}, +- {"sv_target", true, VKD3D_SHADER_TYPE_PIXEL, VKD3D_SM4_SWIZZLE_VEC4, VKD3DSPR_OUTPUT, true}, ++ {"color", true, VKD3D_SHADER_TYPE_PIXEL, VKD3DSPR_OUTPUT, true}, ++ {"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}, + }; + + for (i = 0; i < ARRAY_SIZE(register_table); ++i) +@@ -2738,8 +2752,6 @@ bool hlsl_sm4_register_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_sem + { + if (type) + *type = register_table[i].type; +- if (swizzle_type) +- *swizzle_type = register_table[i].swizzle_type; + *has_idx = register_table[i].has_idx; + return true; + } +@@ -2851,7 +2863,7 @@ static void write_sm4_signature(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc, + continue; + usage_idx = var->semantic.index; + +- if (hlsl_sm4_register_from_semantic(ctx, &var->semantic, output, NULL, NULL, &has_idx)) ++ if (hlsl_sm4_register_from_semantic(ctx, &var->semantic, output, NULL, &has_idx)) + { + reg_idx = has_idx ? var->semantic.index : ~0u; + } +@@ -3623,13 +3635,7 @@ struct sm4_instruction + struct vkd3d_shader_dst_param dsts[2]; + unsigned int dst_count; + +- struct sm4_src_register +- { +- struct vkd3d_shader_register reg; +- enum vkd3d_sm4_swizzle_type swizzle_type; +- DWORD swizzle; +- unsigned int mod; +- } srcs[5]; ++ struct vkd3d_shader_src_param srcs[5]; + unsigned int src_count; + + unsigned int byte_stride; +@@ -3639,8 +3645,7 @@ struct sm4_instruction + }; + + static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct vkd3d_shader_register *reg, +- unsigned int *writemask, enum vkd3d_sm4_swizzle_type *swizzle_type, +- const struct hlsl_deref *deref) ++ uint32_t *writemask, const struct hlsl_deref *deref) + { + const struct hlsl_type *data_type = hlsl_deref_get_type(ctx, deref); + const struct hlsl_ir_var *var = deref->var; +@@ -3653,8 +3658,6 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct vkd3d_shader_re + { + reg->type = VKD3DSPR_RESOURCE; + reg->dimension = VSIR_DIMENSION_VEC4; +- if (swizzle_type) +- *swizzle_type = VKD3D_SM4_SWIZZLE_VEC4; + reg->idx[0].offset = var->regs[HLSL_REGSET_TEXTURES].id; + reg->idx[0].offset += hlsl_offset_from_deref_safe(ctx, deref); + assert(regset == HLSL_REGSET_TEXTURES); +@@ -3665,8 +3668,6 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct vkd3d_shader_re + { + reg->type = VKD3DSPR_UAV; + reg->dimension = VSIR_DIMENSION_VEC4; +- if (swizzle_type) +- *swizzle_type = VKD3D_SM4_SWIZZLE_VEC4; + reg->idx[0].offset = var->regs[HLSL_REGSET_UAVS].id; + reg->idx[0].offset += hlsl_offset_from_deref_safe(ctx, deref); + assert(regset == HLSL_REGSET_UAVS); +@@ -3677,8 +3678,6 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct vkd3d_shader_re + { + reg->type = VKD3DSPR_SAMPLER; + reg->dimension = VSIR_DIMENSION_NONE; +- if (swizzle_type) +- *swizzle_type = VKD3D_SM4_SWIZZLE_NONE; + reg->idx[0].offset = var->regs[HLSL_REGSET_SAMPLERS].id; + reg->idx[0].offset += hlsl_offset_from_deref_safe(ctx, deref); + assert(regset == HLSL_REGSET_SAMPLERS); +@@ -3692,8 +3691,6 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct vkd3d_shader_re + assert(data_type->class <= HLSL_CLASS_VECTOR); + reg->type = VKD3DSPR_CONSTBUFFER; + reg->dimension = VSIR_DIMENSION_VEC4; +- if (swizzle_type) +- *swizzle_type = VKD3D_SM4_SWIZZLE_VEC4; + reg->idx[0].offset = var->buffer->reg.id; + reg->idx[1].offset = offset / 4; + reg->idx_count = 2; +@@ -3704,7 +3701,7 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct vkd3d_shader_re + { + bool has_idx; + +- if (hlsl_sm4_register_from_semantic(ctx, &var->semantic, false, ®->type, swizzle_type, &has_idx)) ++ if (hlsl_sm4_register_from_semantic(ctx, &var->semantic, false, ®->type, &has_idx)) + { + unsigned int offset = hlsl_offset_from_deref_safe(ctx, deref); + +@@ -3724,8 +3721,6 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct vkd3d_shader_re + assert(hlsl_reg.allocated); + reg->type = VKD3DSPR_INPUT; + reg->dimension = VSIR_DIMENSION_VEC4; +- if (swizzle_type) +- *swizzle_type = VKD3D_SM4_SWIZZLE_VEC4; + reg->idx[0].offset = hlsl_reg.id; + reg->idx_count = 1; + *writemask = hlsl_reg.writemask; +@@ -3735,7 +3730,7 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct vkd3d_shader_re + { + bool has_idx; + +- if (hlsl_sm4_register_from_semantic(ctx, &var->semantic, true, ®->type, swizzle_type, &has_idx)) ++ if (hlsl_sm4_register_from_semantic(ctx, &var->semantic, true, ®->type, &has_idx)) + { + unsigned int offset = hlsl_offset_from_deref_safe(ctx, deref); + +@@ -3770,34 +3765,32 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct vkd3d_shader_re + assert(hlsl_reg.allocated); + reg->type = VKD3DSPR_TEMP; + reg->dimension = VSIR_DIMENSION_VEC4; +- if (swizzle_type) +- *swizzle_type = VKD3D_SM4_SWIZZLE_VEC4; + reg->idx[0].offset = hlsl_reg.id; + reg->idx_count = 1; + *writemask = hlsl_reg.writemask; + } + } + +-static void sm4_src_from_deref(struct hlsl_ctx *ctx, struct sm4_src_register *src, ++static void sm4_src_from_deref(const struct tpf_writer *tpf, struct vkd3d_shader_src_param *src, + const struct hlsl_deref *deref, unsigned int map_writemask) + { +- unsigned int writemask, hlsl_swizzle; ++ unsigned int hlsl_swizzle; ++ uint32_t writemask; + +- sm4_register_from_deref(ctx, &src->reg, &writemask, &src->swizzle_type, deref); +- if (src->swizzle_type == VKD3D_SM4_SWIZZLE_VEC4) ++ sm4_register_from_deref(tpf->ctx, &src->reg, &writemask, deref); ++ if (vkd3d_sm4_get_default_swizzle_type(&tpf->lookup, src->reg.type) == VKD3D_SM4_SWIZZLE_VEC4) + { + hlsl_swizzle = hlsl_map_swizzle(hlsl_swizzle_from_writemask(writemask), map_writemask); + src->swizzle = swizzle_from_sm4(hlsl_swizzle); + } + } + +-static void sm4_register_from_node(struct vkd3d_shader_register *reg, unsigned int *writemask, +- enum vkd3d_sm4_swizzle_type *swizzle_type, const struct hlsl_ir_node *instr) ++static void sm4_register_from_node(struct vkd3d_shader_register *reg, uint32_t *writemask, ++ const struct hlsl_ir_node *instr) + { + assert(instr->reg.allocated); + reg->type = VKD3DSPR_TEMP; + reg->dimension = VSIR_DIMENSION_VEC4; +- *swizzle_type = VKD3D_SM4_SWIZZLE_VEC4; + reg->idx[0].offset = instr->reg.id; + reg->idx_count = 1; + *writemask = instr->reg.writemask; +@@ -3805,16 +3798,13 @@ static void sm4_register_from_node(struct vkd3d_shader_register *reg, unsigned i + + static void sm4_dst_from_node(struct vkd3d_shader_dst_param *dst, const struct hlsl_ir_node *instr) + { +- unsigned int swizzle_type; +- +- sm4_register_from_node(&dst->reg, &dst->write_mask, &swizzle_type, instr); ++ sm4_register_from_node(&dst->reg, &dst->write_mask, instr); + } + +-static void sm4_src_from_constant_value(struct sm4_src_register *src, ++static void sm4_src_from_constant_value(struct vkd3d_shader_src_param *src, + const struct hlsl_constant_value *value, unsigned int width, unsigned int map_writemask) + { + src->swizzle = VKD3D_SHADER_NO_SWIZZLE; +- src->swizzle_type = VKD3D_SM4_SWIZZLE_NONE; + src->reg.type = VKD3DSPR_IMMCONST; + if (width == 1) + { +@@ -3836,10 +3826,11 @@ static void sm4_src_from_constant_value(struct sm4_src_register *src, + } + } + +-static void sm4_src_from_node(struct sm4_src_register *src, +- const struct hlsl_ir_node *instr, unsigned int map_writemask) ++static void sm4_src_from_node(const struct tpf_writer *tpf, struct vkd3d_shader_src_param *src, ++ const struct hlsl_ir_node *instr, uint32_t map_writemask) + { +- unsigned int writemask, hlsl_swizzle; ++ unsigned int hlsl_swizzle; ++ uint32_t writemask; + + if (instr->type == HLSL_IR_CONSTANT) + { +@@ -3849,8 +3840,8 @@ static void sm4_src_from_node(struct sm4_src_register *src, + return; + } + +- sm4_register_from_node(&src->reg, &writemask, &src->swizzle_type, instr); +- if (src->swizzle_type == VKD3D_SM4_SWIZZLE_VEC4) ++ sm4_register_from_node(&src->reg, &writemask, instr); ++ if (vkd3d_sm4_get_default_swizzle_type(&tpf->lookup, src->reg.type) == VKD3D_SM4_SWIZZLE_VEC4) + { + hlsl_swizzle = hlsl_map_swizzle(hlsl_swizzle_from_writemask(writemask), map_writemask); + src->swizzle = swizzle_from_sm4(hlsl_swizzle); +@@ -3892,12 +3883,12 @@ static void sm4_write_dst_register(const struct tpf_writer *tpf, const struct vk + } + } + +-static void sm4_write_src_register(const struct tpf_writer *tpf, const struct sm4_src_register *src) ++static void sm4_write_src_register(const struct tpf_writer *tpf, const struct vkd3d_shader_src_param *src) + { + const struct vkd3d_sm4_register_type_info *register_type_info; + struct vkd3d_bytecode_buffer *buffer = tpf->buffer; + uint32_t sm4_reg_type, reg_dim; +- uint32_t token = 0; ++ uint32_t token = 0, mod_token = 0; + unsigned int j; + + register_type_info = get_info_from_vkd3d_register_type(&tpf->lookup, src->reg.type); +@@ -3918,16 +3909,47 @@ static void sm4_write_src_register(const struct tpf_writer *tpf, const struct sm + token |= reg_dim << VKD3D_SM4_DIMENSION_SHIFT; + if (reg_dim == VKD3D_SM4_DIMENSION_VEC4) + { +- token |= (uint32_t)src->swizzle_type << VKD3D_SM4_SWIZZLE_TYPE_SHIFT; ++ token |= (uint32_t)register_type_info->default_src_swizzle_type << VKD3D_SM4_SWIZZLE_TYPE_SHIFT; + token |= swizzle_to_sm4(src->swizzle) << VKD3D_SM4_SWIZZLE_SHIFT; + } +- if (src->mod) +- token |= VKD3D_SM4_EXTENDED_OPERAND; +- put_u32(buffer, token); + +- if (src->mod) +- put_u32(buffer, (src->mod << VKD3D_SM4_REGISTER_MODIFIER_SHIFT) +- | VKD3D_SM4_EXTENDED_OPERAND_MODIFIER); ++ switch (src->modifiers) ++ { ++ case VKD3DSPSM_NONE: ++ mod_token = VKD3D_SM4_REGISTER_MODIFIER_NONE; ++ break; ++ ++ case VKD3DSPSM_ABS: ++ mod_token = (VKD3D_SM4_REGISTER_MODIFIER_ABS << VKD3D_SM4_REGISTER_MODIFIER_SHIFT) ++ | VKD3D_SM4_EXTENDED_OPERAND_MODIFIER; ++ break; ++ ++ case VKD3DSPSM_NEG: ++ mod_token = (VKD3D_SM4_REGISTER_MODIFIER_NEGATE << VKD3D_SM4_REGISTER_MODIFIER_SHIFT) ++ | VKD3D_SM4_EXTENDED_OPERAND_MODIFIER; ++ break; ++ ++ case VKD3DSPSM_ABSNEG: ++ mod_token = (VKD3D_SM4_REGISTER_MODIFIER_ABS_NEGATE << VKD3D_SM4_REGISTER_MODIFIER_SHIFT) ++ | VKD3D_SM4_EXTENDED_OPERAND_MODIFIER; ++ break; ++ ++ default: ++ ERR("Unhandled register modifier %#x.\n", src->modifiers); ++ vkd3d_unreachable(); ++ break; ++ } ++ ++ if (src->modifiers) ++ { ++ token |= VKD3D_SM4_EXTENDED_OPERAND; ++ put_u32(buffer, token); ++ put_u32(buffer, mod_token); ++ } ++ else ++ { ++ put_u32(buffer, token); ++ } + + for (j = 0; j < src->reg.idx_count; ++j) + { +@@ -3947,7 +3969,7 @@ static void sm4_write_src_register(const struct tpf_writer *tpf, const struct sm + } + } + +-static uint32_t vkd3d_shader_dst_param_order(const struct vkd3d_shader_dst_param *dst) ++static uint32_t sm4_token_count_from_dst_register(const struct vkd3d_shader_dst_param *dst) + { + uint32_t order = 1; + if (dst->reg.type == VKD3DSPR_IMMCONST) +@@ -3956,13 +3978,13 @@ static uint32_t vkd3d_shader_dst_param_order(const struct vkd3d_shader_dst_param + return order; + } + +-static uint32_t sm4_src_register_order(const struct sm4_src_register *src) ++static uint32_t sm4_token_count_from_src_register(const struct vkd3d_shader_src_param *src) + { + uint32_t order = 1; + if (src->reg.type == VKD3DSPR_IMMCONST) + order += src->reg.dimension == VSIR_DIMENSION_VEC4 ? 4 : 1; + order += src->reg.idx_count; +- if (src->mod) ++ if (src->modifiers) + ++order; + return order; + } +@@ -3975,9 +3997,9 @@ static void write_sm4_instruction(const struct tpf_writer *tpf, const struct sm4 + + size += instr->modifier_count; + for (i = 0; i < instr->dst_count; ++i) +- size += vkd3d_shader_dst_param_order(&instr->dsts[i]); ++ size += sm4_token_count_from_dst_register(&instr->dsts[i]); + for (i = 0; i < instr->src_count; ++i) +- size += sm4_src_register_order(&instr->srcs[i]); ++ size += sm4_token_count_from_src_register(&instr->srcs[i]); + size += instr->idx_count; + if (instr->byte_stride) + ++size; +@@ -4047,7 +4069,6 @@ static void write_sm4_dcl_constant_buffer(const struct tpf_writer *tpf, const st + .srcs[0].reg.idx[0].offset = cbuffer->reg.id, + .srcs[0].reg.idx[1].offset = (cbuffer->used_size + 3) / 4, + .srcs[0].reg.idx_count = 2, +- .srcs[0].swizzle_type = VKD3D_SM4_SWIZZLE_VEC4, + .srcs[0].swizzle = VKD3D_SHADER_NO_SWIZZLE, + .src_count = 1, + }; +@@ -4154,7 +4175,7 @@ static void write_sm4_dcl_semantic(const struct tpf_writer *tpf, const struct hl + .dst_count = 1, + }; + +- if (hlsl_sm4_register_from_semantic(tpf->ctx, &var->semantic, output, &instr.dsts[0].reg.type, NULL, &has_idx)) ++ if (hlsl_sm4_register_from_semantic(tpf->ctx, &var->semantic, output, &instr.dsts[0].reg.type, &has_idx)) + { + if (has_idx) + { +@@ -4280,7 +4301,7 @@ static void write_sm4_ret(const struct tpf_writer *tpf) + } + + static void write_sm4_unary_op(const struct tpf_writer *tpf, enum vkd3d_sm4_opcode opcode, +- const struct hlsl_ir_node *dst, const struct hlsl_ir_node *src, unsigned int src_mod) ++ const struct hlsl_ir_node *dst, const struct hlsl_ir_node *src, enum vkd3d_shader_src_modifier src_mod) + { + struct sm4_instruction instr; + +@@ -4290,8 +4311,8 @@ static void write_sm4_unary_op(const struct tpf_writer *tpf, enum vkd3d_sm4_opco + sm4_dst_from_node(&instr.dsts[0], dst); + instr.dst_count = 1; + +- sm4_src_from_node(&instr.srcs[0], src, instr.dsts[0].write_mask); +- instr.srcs[0].mod = src_mod; ++ sm4_src_from_node(tpf, &instr.srcs[0], src, instr.dsts[0].write_mask); ++ instr.srcs[0].modifiers = src_mod; + instr.src_count = 1; + + write_sm4_instruction(tpf, &instr); +@@ -4313,7 +4334,7 @@ static void write_sm4_unary_op_with_two_destinations(const struct tpf_writer *tp + instr.dsts[1 - dst_idx].reg.idx_count = 0; + instr.dst_count = 2; + +- sm4_src_from_node(&instr.srcs[0], src, instr.dsts[dst_idx].write_mask); ++ sm4_src_from_node(tpf, &instr.srcs[0], src, instr.dsts[dst_idx].write_mask); + instr.src_count = 1; + + write_sm4_instruction(tpf, &instr); +@@ -4330,8 +4351,8 @@ static void write_sm4_binary_op(const struct tpf_writer *tpf, enum vkd3d_sm4_opc + sm4_dst_from_node(&instr.dsts[0], dst); + instr.dst_count = 1; + +- sm4_src_from_node(&instr.srcs[0], src1, instr.dsts[0].write_mask); +- sm4_src_from_node(&instr.srcs[1], src2, instr.dsts[0].write_mask); ++ sm4_src_from_node(tpf, &instr.srcs[0], src1, instr.dsts[0].write_mask); ++ sm4_src_from_node(tpf, &instr.srcs[1], src2, instr.dsts[0].write_mask); + instr.src_count = 2; + + write_sm4_instruction(tpf, &instr); +@@ -4349,8 +4370,8 @@ static void write_sm4_binary_op_dot(const struct tpf_writer *tpf, enum vkd3d_sm4 + sm4_dst_from_node(&instr.dsts[0], dst); + instr.dst_count = 1; + +- sm4_src_from_node(&instr.srcs[0], src1, VKD3DSP_WRITEMASK_ALL); +- sm4_src_from_node(&instr.srcs[1], src2, VKD3DSP_WRITEMASK_ALL); ++ sm4_src_from_node(tpf, &instr.srcs[0], src1, VKD3DSP_WRITEMASK_ALL); ++ sm4_src_from_node(tpf, &instr.srcs[1], src2, VKD3DSP_WRITEMASK_ALL); + instr.src_count = 2; + + write_sm4_instruction(tpf, &instr); +@@ -4373,8 +4394,8 @@ static void write_sm4_binary_op_with_two_destinations(const struct tpf_writer *t + instr.dsts[1 - dst_idx].reg.idx_count = 0; + instr.dst_count = 2; + +- sm4_src_from_node(&instr.srcs[0], src1, instr.dsts[dst_idx].write_mask); +- sm4_src_from_node(&instr.srcs[1], src2, instr.dsts[dst_idx].write_mask); ++ sm4_src_from_node(tpf, &instr.srcs[0], src1, instr.dsts[dst_idx].write_mask); ++ sm4_src_from_node(tpf, &instr.srcs[1], src2, instr.dsts[dst_idx].write_mask); + instr.src_count = 2; + + write_sm4_instruction(tpf, &instr); +@@ -4392,9 +4413,9 @@ static void write_sm4_ternary_op(const struct tpf_writer *tpf, enum vkd3d_sm4_op + sm4_dst_from_node(&instr.dsts[0], dst); + instr.dst_count = 1; + +- sm4_src_from_node(&instr.srcs[0], src1, instr.dsts[0].write_mask); +- sm4_src_from_node(&instr.srcs[1], src2, instr.dsts[0].write_mask); +- sm4_src_from_node(&instr.srcs[2], src3, instr.dsts[0].write_mask); ++ sm4_src_from_node(tpf, &instr.srcs[0], src1, instr.dsts[0].write_mask); ++ sm4_src_from_node(tpf, &instr.srcs[1], src2, instr.dsts[0].write_mask); ++ sm4_src_from_node(tpf, &instr.srcs[2], src3, instr.dsts[0].write_mask); + instr.src_count = 3; + + write_sm4_instruction(tpf, &instr); +@@ -4443,9 +4464,9 @@ static void write_sm4_ld(const struct tpf_writer *tpf, const struct hlsl_ir_node + coords_writemask = VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1 | VKD3DSP_WRITEMASK_3; + } + +- sm4_src_from_node(&instr.srcs[0], coords, coords_writemask); ++ sm4_src_from_node(tpf, &instr.srcs[0], coords, coords_writemask); + +- sm4_src_from_deref(tpf->ctx, &instr.srcs[1], resource, instr.dsts[0].write_mask); ++ sm4_src_from_deref(tpf, &instr.srcs[1], resource, instr.dsts[0].write_mask); + + instr.src_count = 2; + +@@ -4459,7 +4480,6 @@ static void write_sm4_ld(const struct tpf_writer *tpf, const struct hlsl_ir_node + index = hlsl_ir_constant(sample_index); + + memset(&instr.srcs[2], 0, sizeof(instr.srcs[2])); +- instr.srcs[2].swizzle_type = VKD3D_SM4_SWIZZLE_NONE; + reg->type = VKD3DSPR_IMMCONST; + reg->dimension = VSIR_DIMENSION_SCALAR; + reg->u.immconst_uint[0] = index->value.u[0].u; +@@ -4470,7 +4490,7 @@ static void write_sm4_ld(const struct tpf_writer *tpf, const struct hlsl_ir_node + } + else + { +- sm4_src_from_node(&instr.srcs[2], sample_index, 0); ++ sm4_src_from_node(tpf, &instr.srcs[2], sample_index, 0); + } + + ++instr.src_count; +@@ -4532,27 +4552,27 @@ static void write_sm4_sample(const struct tpf_writer *tpf, const struct hlsl_ir_ + sm4_dst_from_node(&instr.dsts[0], dst); + instr.dst_count = 1; + +- sm4_src_from_node(&instr.srcs[0], coords, VKD3DSP_WRITEMASK_ALL); +- sm4_src_from_deref(tpf->ctx, &instr.srcs[1], resource, instr.dsts[0].write_mask); +- sm4_src_from_deref(tpf->ctx, &instr.srcs[2], sampler, VKD3DSP_WRITEMASK_ALL); ++ sm4_src_from_node(tpf, &instr.srcs[0], coords, VKD3DSP_WRITEMASK_ALL); ++ sm4_src_from_deref(tpf, &instr.srcs[1], resource, instr.dsts[0].write_mask); ++ sm4_src_from_deref(tpf, &instr.srcs[2], sampler, VKD3DSP_WRITEMASK_ALL); + instr.src_count = 3; + + if (load->load_type == HLSL_RESOURCE_SAMPLE_LOD + || load->load_type == HLSL_RESOURCE_SAMPLE_LOD_BIAS) + { +- sm4_src_from_node(&instr.srcs[3], load->lod.node, VKD3DSP_WRITEMASK_ALL); ++ sm4_src_from_node(tpf, &instr.srcs[3], load->lod.node, VKD3DSP_WRITEMASK_ALL); + ++instr.src_count; + } + else if (load->load_type == HLSL_RESOURCE_SAMPLE_GRAD) + { +- sm4_src_from_node(&instr.srcs[3], load->ddx.node, VKD3DSP_WRITEMASK_ALL); +- sm4_src_from_node(&instr.srcs[4], load->ddy.node, VKD3DSP_WRITEMASK_ALL); ++ sm4_src_from_node(tpf, &instr.srcs[3], load->ddx.node, VKD3DSP_WRITEMASK_ALL); ++ sm4_src_from_node(tpf, &instr.srcs[4], load->ddy.node, VKD3DSP_WRITEMASK_ALL); + instr.src_count += 2; + } + else if (load->load_type == HLSL_RESOURCE_SAMPLE_CMP + || load->load_type == HLSL_RESOURCE_SAMPLE_CMP_LZ) + { +- sm4_src_from_node(&instr.srcs[3], load->cmp.node, VKD3DSP_WRITEMASK_ALL); ++ sm4_src_from_node(tpf, &instr.srcs[3], load->cmp.node, VKD3DSP_WRITEMASK_ALL); + ++instr.src_count; + } + +@@ -4575,7 +4595,7 @@ static void write_sm4_sampleinfo(const struct tpf_writer *tpf, const struct hlsl + sm4_dst_from_node(&instr.dsts[0], dst); + instr.dst_count = 1; + +- sm4_src_from_deref(tpf->ctx, &instr.srcs[0], resource, instr.dsts[0].write_mask); ++ sm4_src_from_deref(tpf, &instr.srcs[0], resource, instr.dsts[0].write_mask); + instr.src_count = 1; + + write_sm4_instruction(tpf, &instr); +@@ -4597,8 +4617,8 @@ static void write_sm4_resinfo(const struct tpf_writer *tpf, const struct hlsl_ir + sm4_dst_from_node(&instr.dsts[0], dst); + instr.dst_count = 1; + +- sm4_src_from_node(&instr.srcs[0], load->lod.node, VKD3DSP_WRITEMASK_ALL); +- sm4_src_from_deref(tpf->ctx, &instr.srcs[1], resource, instr.dsts[0].write_mask); ++ sm4_src_from_node(tpf, &instr.srcs[0], load->lod.node, VKD3DSP_WRITEMASK_ALL); ++ sm4_src_from_deref(tpf, &instr.srcs[1], resource, instr.dsts[0].write_mask); + instr.src_count = 2; + + write_sm4_instruction(tpf, &instr); +@@ -4620,8 +4640,7 @@ static void write_sm4_cast_from_bool(const struct tpf_writer *tpf, const struct + sm4_dst_from_node(&instr.dsts[0], &expr->node); + instr.dst_count = 1; + +- sm4_src_from_node(&instr.srcs[0], arg, instr.dsts[0].write_mask); +- instr.srcs[1].swizzle_type = VKD3D_SM4_SWIZZLE_NONE; ++ sm4_src_from_node(tpf, &instr.srcs[0], arg, instr.dsts[0].write_mask); + instr.srcs[1].reg.type = VKD3DSPR_IMMCONST; + instr.srcs[1].reg.dimension = VSIR_DIMENSION_SCALAR; + instr.srcs[1].reg.u.immconst_uint[0] = mask; +@@ -4747,11 +4766,11 @@ static void write_sm4_store_uav_typed(const struct tpf_writer *tpf, const struct + memset(&instr, 0, sizeof(instr)); + instr.opcode = VKD3D_SM5_OP_STORE_UAV_TYPED; + +- sm4_register_from_deref(tpf->ctx, &instr.dsts[0].reg, &instr.dsts[0].write_mask, NULL, dst); ++ sm4_register_from_deref(tpf->ctx, &instr.dsts[0].reg, &instr.dsts[0].write_mask, dst); + instr.dst_count = 1; + +- sm4_src_from_node(&instr.srcs[0], coords, VKD3DSP_WRITEMASK_ALL); +- sm4_src_from_node(&instr.srcs[1], value, VKD3DSP_WRITEMASK_ALL); ++ sm4_src_from_node(tpf, &instr.srcs[0], coords, VKD3DSP_WRITEMASK_ALL); ++ sm4_src_from_node(tpf, &instr.srcs[1], value, VKD3DSP_WRITEMASK_ALL); + instr.src_count = 2; + + write_sm4_instruction(tpf, &instr); +@@ -4776,7 +4795,7 @@ static void write_sm4_expr(const struct tpf_writer *tpf, const struct hlsl_ir_ex + switch (dst_type->base_type) + { + case HLSL_TYPE_FLOAT: +- write_sm4_unary_op(tpf, VKD3D_SM4_OP_MOV, &expr->node, arg1, VKD3D_SM4_REGISTER_MODIFIER_ABS); ++ write_sm4_unary_op(tpf, VKD3D_SM4_OP_MOV, &expr->node, arg1, VKD3DSPSM_ABS); + break; + + default: +@@ -4857,7 +4876,7 @@ static void write_sm4_expr(const struct tpf_writer *tpf, const struct hlsl_ir_ex + switch (dst_type->base_type) + { + case HLSL_TYPE_FLOAT: +- write_sm4_unary_op(tpf, VKD3D_SM4_OP_MOV, &expr->node, arg1, VKD3D_SM4_REGISTER_MODIFIER_NEGATE); ++ write_sm4_unary_op(tpf, VKD3D_SM4_OP_MOV, &expr->node, arg1, VKD3DSPSM_NEG); + break; + + case HLSL_TYPE_INT: +@@ -5208,7 +5227,7 @@ static void write_sm4_if(const struct tpf_writer *tpf, const struct hlsl_ir_if * + + assert(iff->condition.node->data_type->dimx == 1); + +- sm4_src_from_node(&instr.srcs[0], iff->condition.node, VKD3DSP_WRITEMASK_ALL); ++ sm4_src_from_node(tpf, &instr.srcs[0], iff->condition.node, VKD3DSP_WRITEMASK_ALL); + write_sm4_instruction(tpf, &instr); + + write_sm4_block(tpf, &iff->then_block); +@@ -5243,7 +5262,7 @@ static void write_sm4_jump(const struct tpf_writer *tpf, const struct hlsl_ir_ju + + memset(&instr.srcs[0], 0, sizeof(*instr.srcs)); + instr.src_count = 1; +- sm4_src_from_node(&instr.srcs[0], jump->condition.node, VKD3DSP_WRITEMASK_ALL); ++ sm4_src_from_node(tpf, &instr.srcs[0], jump->condition.node, VKD3DSP_WRITEMASK_ALL); + break; + } + +@@ -5289,7 +5308,7 @@ static void write_sm4_load(const struct tpf_writer *tpf, const struct hlsl_ir_lo + + instr.opcode = VKD3D_SM4_OP_MOVC; + +- sm4_src_from_deref(tpf->ctx, &instr.srcs[0], &load->src, instr.dsts[0].write_mask); ++ sm4_src_from_deref(tpf, &instr.srcs[0], &load->src, instr.dsts[0].write_mask); + + memset(&value, 0xff, sizeof(value)); + sm4_src_from_constant_value(&instr.srcs[1], &value, type->dimx, instr.dsts[0].write_mask); +@@ -5301,7 +5320,7 @@ static void write_sm4_load(const struct tpf_writer *tpf, const struct hlsl_ir_lo + { + instr.opcode = VKD3D_SM4_OP_MOV; + +- sm4_src_from_deref(tpf->ctx, &instr.srcs[0], &load->src, instr.dsts[0].write_mask); ++ sm4_src_from_deref(tpf, &instr.srcs[0], &load->src, instr.dsts[0].write_mask); + instr.src_count = 1; + } + +@@ -5327,7 +5346,7 @@ static void write_sm4_gather(const struct tpf_writer *tpf, const struct hlsl_ir_ + const struct hlsl_deref *resource, const struct hlsl_deref *sampler, + const struct hlsl_ir_node *coords, DWORD swizzle, const struct hlsl_ir_node *texel_offset) + { +- struct sm4_src_register *src; ++ struct vkd3d_shader_src_param *src; + struct sm4_instruction instr; + + memset(&instr, 0, sizeof(instr)); +@@ -5337,7 +5356,7 @@ static void write_sm4_gather(const struct tpf_writer *tpf, const struct hlsl_ir_ + sm4_dst_from_node(&instr.dsts[0], dst); + instr.dst_count = 1; + +- sm4_src_from_node(&instr.srcs[instr.src_count++], coords, VKD3DSP_WRITEMASK_ALL); ++ sm4_src_from_node(tpf, &instr.srcs[instr.src_count++], coords, VKD3DSP_WRITEMASK_ALL); + + if (texel_offset) + { +@@ -5350,16 +5369,15 @@ static void write_sm4_gather(const struct tpf_writer *tpf, const struct hlsl_ir_ + return; + } + instr.opcode = VKD3D_SM5_OP_GATHER4_PO; +- sm4_src_from_node(&instr.srcs[instr.src_count++], texel_offset, VKD3DSP_WRITEMASK_ALL); ++ sm4_src_from_node(tpf, &instr.srcs[instr.src_count++], texel_offset, VKD3DSP_WRITEMASK_ALL); + } + } + +- sm4_src_from_deref(tpf->ctx, &instr.srcs[instr.src_count++], resource, instr.dsts[0].write_mask); ++ sm4_src_from_deref(tpf, &instr.srcs[instr.src_count++], resource, instr.dsts[0].write_mask); + + src = &instr.srcs[instr.src_count++]; +- sm4_src_from_deref(tpf->ctx, src, sampler, VKD3DSP_WRITEMASK_ALL); ++ sm4_src_from_deref(tpf, src, sampler, VKD3DSP_WRITEMASK_ALL); + src->reg.dimension = VSIR_DIMENSION_VEC4; +- src->swizzle_type = VKD3D_SM4_SWIZZLE_SCALAR; + src->swizzle = swizzle; + + write_sm4_instruction(tpf, &instr); +@@ -5454,16 +5472,16 @@ static void write_sm4_store(const struct tpf_writer *tpf, const struct hlsl_ir_s + { + const struct hlsl_ir_node *rhs = store->rhs.node; + struct sm4_instruction instr; +- unsigned int writemask; ++ uint32_t writemask; + + memset(&instr, 0, sizeof(instr)); + instr.opcode = VKD3D_SM4_OP_MOV; + +- sm4_register_from_deref(tpf->ctx, &instr.dsts[0].reg, &writemask, NULL, &store->lhs); ++ sm4_register_from_deref(tpf->ctx, &instr.dsts[0].reg, &writemask, &store->lhs); + instr.dsts[0].write_mask = hlsl_combine_writemasks(writemask, store->writemask); + instr.dst_count = 1; + +- sm4_src_from_node(&instr.srcs[0], rhs, instr.dsts[0].write_mask); ++ sm4_src_from_node(tpf, &instr.srcs[0], rhs, instr.dsts[0].write_mask); + instr.src_count = 1; + + write_sm4_instruction(tpf, &instr); +@@ -5471,8 +5489,9 @@ static void write_sm4_store(const struct tpf_writer *tpf, const struct hlsl_ir_s + + static void write_sm4_swizzle(const struct tpf_writer *tpf, const struct hlsl_ir_swizzle *swizzle) + { +- unsigned int writemask, hlsl_swizzle; ++ unsigned int hlsl_swizzle; + struct sm4_instruction instr; ++ uint32_t writemask; + + memset(&instr, 0, sizeof(instr)); + instr.opcode = VKD3D_SM4_OP_MOV; +@@ -5480,7 +5499,7 @@ static void write_sm4_swizzle(const struct tpf_writer *tpf, const struct hlsl_ir + sm4_dst_from_node(&instr.dsts[0], &swizzle->node); + instr.dst_count = 1; + +- sm4_register_from_node(&instr.srcs[0].reg, &writemask, &instr.srcs[0].swizzle_type, swizzle->val.node); ++ sm4_register_from_node(&instr.srcs[0].reg, &writemask, swizzle->val.node); + hlsl_swizzle = hlsl_map_swizzle(hlsl_combine_swizzles(hlsl_swizzle_from_writemask(writemask), + swizzle->swizzle, swizzle->node.data_type->dimx), instr.dsts[0].write_mask); + instr.srcs[0].swizzle = swizzle_from_sm4(hlsl_swizzle); +diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +index af75ef3bda8..f006d2db532 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h ++++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +@@ -758,7 +758,7 @@ void vsir_register_init(struct vkd3d_shader_register *reg, enum vkd3d_shader_reg + struct vkd3d_shader_dst_param + { + struct vkd3d_shader_register reg; +- DWORD write_mask; ++ uint32_t write_mask; + DWORD modifiers; + DWORD shift; + }; +diff --git a/libs/vkd3d/libs/vkd3d/command.c b/libs/vkd3d/libs/vkd3d/command.c +index 4ac0329f7e7..a1bffa6cb90 100644 +--- a/libs/vkd3d/libs/vkd3d/command.c ++++ b/libs/vkd3d/libs/vkd3d/command.c +@@ -1942,9 +1942,9 @@ static void d3d12_command_signature_decref(struct d3d12_command_signature *signa + } + + /* ID3D12CommandList */ +-static inline struct d3d12_command_list *impl_from_ID3D12GraphicsCommandList3(ID3D12GraphicsCommandList3 *iface) ++static inline struct d3d12_command_list *impl_from_ID3D12GraphicsCommandList4(ID3D12GraphicsCommandList4 *iface) + { +- return CONTAINING_RECORD(iface, struct d3d12_command_list, ID3D12GraphicsCommandList3_iface); ++ return CONTAINING_RECORD(iface, struct d3d12_command_list, ID3D12GraphicsCommandList4_iface); + } + + static void d3d12_command_list_invalidate_current_framebuffer(struct d3d12_command_list *list) +@@ -2290,12 +2290,13 @@ static void d3d12_command_list_track_resource_usage(struct d3d12_command_list *l + } + } + +-static HRESULT STDMETHODCALLTYPE d3d12_command_list_QueryInterface(ID3D12GraphicsCommandList3 *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_command_list_QueryInterface(ID3D12GraphicsCommandList4 *iface, + REFIID iid, void **object) + { + TRACE("iface %p, iid %s, object %p.\n", iface, debugstr_guid(iid), object); + +- if (IsEqualGUID(iid, &IID_ID3D12GraphicsCommandList3) ++ if (IsEqualGUID(iid, &IID_ID3D12GraphicsCommandList4) ++ || IsEqualGUID(iid, &IID_ID3D12GraphicsCommandList3) + || IsEqualGUID(iid, &IID_ID3D12GraphicsCommandList2) + || IsEqualGUID(iid, &IID_ID3D12GraphicsCommandList1) + || IsEqualGUID(iid, &IID_ID3D12GraphicsCommandList) +@@ -2304,7 +2305,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_list_QueryInterface(ID3D12Graphic + || IsEqualGUID(iid, &IID_ID3D12Object) + || IsEqualGUID(iid, &IID_IUnknown)) + { +- ID3D12GraphicsCommandList3_AddRef(iface); ++ ID3D12GraphicsCommandList4_AddRef(iface); + *object = iface; + return S_OK; + } +@@ -2315,9 +2316,9 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_list_QueryInterface(ID3D12Graphic + return E_NOINTERFACE; + } + +-static ULONG STDMETHODCALLTYPE d3d12_command_list_AddRef(ID3D12GraphicsCommandList3 *iface) ++static ULONG STDMETHODCALLTYPE d3d12_command_list_AddRef(ID3D12GraphicsCommandList4 *iface) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); + ULONG refcount = InterlockedIncrement(&list->refcount); + + TRACE("%p increasing refcount to %u.\n", list, refcount); +@@ -2330,9 +2331,9 @@ static void vkd3d_pipeline_bindings_cleanup(struct vkd3d_pipeline_bindings *bind + vkd3d_free(bindings->vk_uav_counter_views); + } + +-static ULONG STDMETHODCALLTYPE d3d12_command_list_Release(ID3D12GraphicsCommandList3 *iface) ++static ULONG STDMETHODCALLTYPE d3d12_command_list_Release(ID3D12GraphicsCommandList4 *iface) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); + ULONG refcount = InterlockedDecrement(&list->refcount); + + TRACE("%p decreasing refcount to %u.\n", list, refcount); +@@ -2358,66 +2359,66 @@ static ULONG STDMETHODCALLTYPE d3d12_command_list_Release(ID3D12GraphicsCommandL + return refcount; + } + +-static HRESULT STDMETHODCALLTYPE d3d12_command_list_GetPrivateData(ID3D12GraphicsCommandList3 *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_command_list_GetPrivateData(ID3D12GraphicsCommandList4 *iface, + REFGUID guid, UINT *data_size, void *data) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return vkd3d_get_private_data(&list->private_store, guid, data_size, data); + } + +-static HRESULT STDMETHODCALLTYPE d3d12_command_list_SetPrivateData(ID3D12GraphicsCommandList3 *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_command_list_SetPrivateData(ID3D12GraphicsCommandList4 *iface, + REFGUID guid, UINT data_size, const void *data) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return vkd3d_set_private_data(&list->private_store, guid, data_size, data); + } + +-static HRESULT STDMETHODCALLTYPE d3d12_command_list_SetPrivateDataInterface(ID3D12GraphicsCommandList3 *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_command_list_SetPrivateDataInterface(ID3D12GraphicsCommandList4 *iface, + REFGUID guid, const IUnknown *data) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); + + TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data); + + return vkd3d_set_private_data_interface(&list->private_store, guid, data); + } + +-static HRESULT STDMETHODCALLTYPE d3d12_command_list_SetName(ID3D12GraphicsCommandList3 *iface, const WCHAR *name) ++static HRESULT STDMETHODCALLTYPE d3d12_command_list_SetName(ID3D12GraphicsCommandList4 *iface, const WCHAR *name) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); + + TRACE("iface %p, name %s.\n", iface, debugstr_w(name, list->device->wchar_size)); + + return name ? S_OK : E_INVALIDARG; + } + +-static HRESULT STDMETHODCALLTYPE d3d12_command_list_GetDevice(ID3D12GraphicsCommandList3 *iface, REFIID iid, void **device) ++static HRESULT STDMETHODCALLTYPE d3d12_command_list_GetDevice(ID3D12GraphicsCommandList4 *iface, REFIID iid, void **device) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); + + TRACE("iface %p, iid %s, device %p.\n", iface, debugstr_guid(iid), device); + + return d3d12_device_query_interface(list->device, iid, device); + } + +-static D3D12_COMMAND_LIST_TYPE STDMETHODCALLTYPE d3d12_command_list_GetType(ID3D12GraphicsCommandList3 *iface) ++static D3D12_COMMAND_LIST_TYPE STDMETHODCALLTYPE d3d12_command_list_GetType(ID3D12GraphicsCommandList4 *iface) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); + + TRACE("iface %p.\n", iface); + + return list->type; + } + +-static HRESULT STDMETHODCALLTYPE d3d12_command_list_Close(ID3D12GraphicsCommandList3 *iface) ++static HRESULT STDMETHODCALLTYPE d3d12_command_list_Close(ID3D12GraphicsCommandList4 *iface) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); + const struct vkd3d_vk_device_procs *vk_procs; + VkResult vr; + +@@ -2461,7 +2462,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_list_Close(ID3D12GraphicsCommandL + static void d3d12_command_list_reset_state(struct d3d12_command_list *list, + ID3D12PipelineState *initial_pipeline_state) + { +- ID3D12GraphicsCommandList3 *iface = &list->ID3D12GraphicsCommandList3_iface; ++ ID3D12GraphicsCommandList4 *iface = &list->ID3D12GraphicsCommandList4_iface; + + memset(list->strides, 0, sizeof(list->strides)); + list->primitive_topology = D3D_PRIMITIVE_TOPOLOGY_POINTLIST; +@@ -2497,14 +2498,14 @@ static void d3d12_command_list_reset_state(struct d3d12_command_list *list, + + list->descriptor_heap_count = 0; + +- ID3D12GraphicsCommandList3_SetPipelineState(iface, initial_pipeline_state); ++ ID3D12GraphicsCommandList4_SetPipelineState(iface, initial_pipeline_state); + } + +-static HRESULT STDMETHODCALLTYPE d3d12_command_list_Reset(ID3D12GraphicsCommandList3 *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_command_list_Reset(ID3D12GraphicsCommandList4 *iface, + ID3D12CommandAllocator *allocator, ID3D12PipelineState *initial_pipeline_state) + { + struct d3d12_command_allocator *allocator_impl = unsafe_impl_from_ID3D12CommandAllocator(allocator); +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); + HRESULT hr; + + TRACE("iface %p, allocator %p, initial_pipeline_state %p.\n", +@@ -2531,7 +2532,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_list_Reset(ID3D12GraphicsCommandL + return hr; + } + +-static void STDMETHODCALLTYPE d3d12_command_list_ClearState(ID3D12GraphicsCommandList3 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_ClearState(ID3D12GraphicsCommandList4 *iface, + ID3D12PipelineState *pipeline_state) + { + FIXME("iface %p, pipline_state %p stub!\n", iface, pipeline_state); +@@ -3390,11 +3391,11 @@ static void d3d12_command_list_check_index_buffer_strip_cut_value(struct d3d12_c + } + } + +-static void STDMETHODCALLTYPE d3d12_command_list_DrawInstanced(ID3D12GraphicsCommandList3 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_DrawInstanced(ID3D12GraphicsCommandList4 *iface, + UINT vertex_count_per_instance, UINT instance_count, UINT start_vertex_location, + UINT start_instance_location) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); + const struct vkd3d_vk_device_procs *vk_procs; + + TRACE("iface %p, vertex_count_per_instance %u, instance_count %u, " +@@ -3414,11 +3415,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_DrawInstanced(ID3D12GraphicsCom + instance_count, start_vertex_location, start_instance_location)); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_DrawIndexedInstanced(ID3D12GraphicsCommandList3 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_DrawIndexedInstanced(ID3D12GraphicsCommandList4 *iface, + UINT index_count_per_instance, UINT instance_count, UINT start_vertex_location, + INT base_vertex_location, UINT start_instance_location) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); + const struct vkd3d_vk_device_procs *vk_procs; + + TRACE("iface %p, index_count_per_instance %u, instance_count %u, start_vertex_location %u, " +@@ -3440,10 +3441,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_DrawIndexedInstanced(ID3D12Grap + instance_count, start_vertex_location, base_vertex_location, start_instance_location)); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_Dispatch(ID3D12GraphicsCommandList3 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_Dispatch(ID3D12GraphicsCommandList4 *iface, + UINT x, UINT y, UINT z) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); + const struct vkd3d_vk_device_procs *vk_procs; + + TRACE("iface %p, x %u, y %u, z %u.\n", iface, x, y, z); +@@ -3459,10 +3460,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_Dispatch(ID3D12GraphicsCommandL + VK_CALL(vkCmdDispatch(list->vk_command_buffer, x, y, z)); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_CopyBufferRegion(ID3D12GraphicsCommandList3 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_CopyBufferRegion(ID3D12GraphicsCommandList4 *iface, + ID3D12Resource *dst, UINT64 dst_offset, ID3D12Resource *src, UINT64 src_offset, UINT64 byte_count) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); + struct d3d12_resource *dst_resource, *src_resource; + const struct vkd3d_vk_device_procs *vk_procs; + VkBufferCopy buffer_copy; +@@ -3744,11 +3745,11 @@ static bool validate_d3d12_box(const D3D12_BOX *box) + && box->back > box->front; + } + +-static void STDMETHODCALLTYPE d3d12_command_list_CopyTextureRegion(ID3D12GraphicsCommandList3 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_CopyTextureRegion(ID3D12GraphicsCommandList4 *iface, + const D3D12_TEXTURE_COPY_LOCATION *dst, UINT dst_x, UINT dst_y, UINT dst_z, + const D3D12_TEXTURE_COPY_LOCATION *src, const D3D12_BOX *src_box) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); + struct d3d12_resource *dst_resource, *src_resource; + const struct vkd3d_format *src_format, *dst_format; + const struct vkd3d_vk_device_procs *vk_procs; +@@ -3869,10 +3870,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_CopyTextureRegion(ID3D12Graphic + } + } + +-static void STDMETHODCALLTYPE d3d12_command_list_CopyResource(ID3D12GraphicsCommandList3 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_CopyResource(ID3D12GraphicsCommandList4 *iface, + ID3D12Resource *dst, ID3D12Resource *src) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); + struct d3d12_resource *dst_resource, *src_resource; + const struct vkd3d_format *dst_format, *src_format; + const struct vkd3d_vk_device_procs *vk_procs; +@@ -3939,7 +3940,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_CopyResource(ID3D12GraphicsComm + } + } + +-static void STDMETHODCALLTYPE d3d12_command_list_CopyTiles(ID3D12GraphicsCommandList3 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_CopyTiles(ID3D12GraphicsCommandList4 *iface, + ID3D12Resource *tiled_resource, const D3D12_TILED_RESOURCE_COORDINATE *tile_region_start_coordinate, + const D3D12_TILE_REGION_SIZE *tile_region_size, ID3D12Resource *buffer, UINT64 buffer_offset, + D3D12_TILE_COPY_FLAGS flags) +@@ -3950,11 +3951,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_CopyTiles(ID3D12GraphicsCommand + buffer, buffer_offset, flags); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_ResolveSubresource(ID3D12GraphicsCommandList3 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_ResolveSubresource(ID3D12GraphicsCommandList4 *iface, + ID3D12Resource *dst, UINT dst_sub_resource_idx, + ID3D12Resource *src, UINT src_sub_resource_idx, DXGI_FORMAT format) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); + const struct vkd3d_format *src_format, *dst_format, *vk_format; + struct d3d12_resource *dst_resource, *src_resource; + const struct vkd3d_vk_device_procs *vk_procs; +@@ -4017,10 +4018,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_ResolveSubresource(ID3D12Graphi + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &vk_image_resolve)); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_IASetPrimitiveTopology(ID3D12GraphicsCommandList3 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_IASetPrimitiveTopology(ID3D12GraphicsCommandList4 *iface, + D3D12_PRIMITIVE_TOPOLOGY topology) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); + + TRACE("iface %p, topology %#x.\n", iface, topology); + +@@ -4031,11 +4032,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_IASetPrimitiveTopology(ID3D12Gr + d3d12_command_list_invalidate_current_pipeline(list); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_RSSetViewports(ID3D12GraphicsCommandList3 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_RSSetViewports(ID3D12GraphicsCommandList4 *iface, + UINT viewport_count, const D3D12_VIEWPORT *viewports) + { + VkViewport vk_viewports[D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE]; +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); + const struct vkd3d_vk_device_procs *vk_procs; + unsigned int i; + +@@ -4069,10 +4070,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_RSSetViewports(ID3D12GraphicsCo + VK_CALL(vkCmdSetViewport(list->vk_command_buffer, 0, viewport_count, vk_viewports)); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_RSSetScissorRects(ID3D12GraphicsCommandList3 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_RSSetScissorRects(ID3D12GraphicsCommandList4 *iface, + UINT rect_count, const D3D12_RECT *rects) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); + VkRect2D vk_rects[D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE]; + const struct vkd3d_vk_device_procs *vk_procs; + unsigned int i; +@@ -4097,10 +4098,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_RSSetScissorRects(ID3D12Graphic + VK_CALL(vkCmdSetScissor(list->vk_command_buffer, 0, rect_count, vk_rects)); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_OMSetBlendFactor(ID3D12GraphicsCommandList3 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_OMSetBlendFactor(ID3D12GraphicsCommandList4 *iface, + const FLOAT blend_factor[4]) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); + const struct vkd3d_vk_device_procs *vk_procs; + + TRACE("iface %p, blend_factor %p.\n", iface, blend_factor); +@@ -4109,10 +4110,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_OMSetBlendFactor(ID3D12Graphics + VK_CALL(vkCmdSetBlendConstants(list->vk_command_buffer, blend_factor)); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_OMSetStencilRef(ID3D12GraphicsCommandList3 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_OMSetStencilRef(ID3D12GraphicsCommandList4 *iface, + UINT stencil_ref) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); + const struct vkd3d_vk_device_procs *vk_procs; + + TRACE("iface %p, stencil_ref %u.\n", iface, stencil_ref); +@@ -4121,11 +4122,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_OMSetStencilRef(ID3D12GraphicsC + VK_CALL(vkCmdSetStencilReference(list->vk_command_buffer, VK_STENCIL_FRONT_AND_BACK, stencil_ref)); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_SetPipelineState(ID3D12GraphicsCommandList3 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_SetPipelineState(ID3D12GraphicsCommandList4 *iface, + ID3D12PipelineState *pipeline_state) + { + struct d3d12_pipeline_state *state = unsafe_impl_from_ID3D12PipelineState(pipeline_state); +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); + + TRACE("iface %p, pipeline_state %p.\n", iface, pipeline_state); + +@@ -4176,10 +4177,10 @@ static unsigned int d3d12_find_ds_multiplanar_transition(const D3D12_RESOURCE_BA + return 0; + } + +-static void STDMETHODCALLTYPE d3d12_command_list_ResourceBarrier(ID3D12GraphicsCommandList3 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_ResourceBarrier(ID3D12GraphicsCommandList4 *iface, + UINT barrier_count, const D3D12_RESOURCE_BARRIER *barriers) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); + bool have_aliasing_barriers = false, have_split_barriers = false; + const struct vkd3d_vk_device_procs *vk_procs; + const struct vkd3d_vulkan_info *vk_info; +@@ -4402,13 +4403,13 @@ static void STDMETHODCALLTYPE d3d12_command_list_ResourceBarrier(ID3D12GraphicsC + WARN("Issuing split barrier(s) on D3D12_RESOURCE_BARRIER_FLAG_END_ONLY.\n"); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_ExecuteBundle(ID3D12GraphicsCommandList3 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_ExecuteBundle(ID3D12GraphicsCommandList4 *iface, + ID3D12GraphicsCommandList *command_list) + { + FIXME("iface %p, command_list %p stub!\n", iface, command_list); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_SetDescriptorHeaps(ID3D12GraphicsCommandList3 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_SetDescriptorHeaps(ID3D12GraphicsCommandList4 *iface, + UINT heap_count, ID3D12DescriptorHeap *const *heaps) + { + TRACE("iface %p, heap_count %u, heaps %p.\n", iface, heap_count, heaps); +@@ -4434,10 +4435,10 @@ static void d3d12_command_list_set_root_signature(struct d3d12_command_list *lis + d3d12_command_list_invalidate_root_parameters(list, bind_point); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootSignature(ID3D12GraphicsCommandList3 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootSignature(ID3D12GraphicsCommandList4 *iface, + ID3D12RootSignature *root_signature) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); + + TRACE("iface %p, root_signature %p.\n", iface, root_signature); + +@@ -4445,10 +4446,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootSignature(ID3D12G + unsafe_impl_from_ID3D12RootSignature(root_signature)); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootSignature(ID3D12GraphicsCommandList3 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootSignature(ID3D12GraphicsCommandList4 *iface, + ID3D12RootSignature *root_signature) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); + + TRACE("iface %p, root_signature %p.\n", iface, root_signature); + +@@ -4487,10 +4488,10 @@ static void d3d12_command_list_set_descriptor_table(struct d3d12_command_list *l + bindings->descriptor_table_active_mask |= (uint64_t)1 << index; + } + +-static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootDescriptorTable(ID3D12GraphicsCommandList3 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootDescriptorTable(ID3D12GraphicsCommandList4 *iface, + UINT root_parameter_index, D3D12_GPU_DESCRIPTOR_HANDLE base_descriptor) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); + + TRACE("iface %p, root_parameter_index %u, base_descriptor %#"PRIx64".\n", + iface, root_parameter_index, base_descriptor.ptr); +@@ -4499,10 +4500,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootDescriptorTable(I + root_parameter_index, base_descriptor); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootDescriptorTable(ID3D12GraphicsCommandList3 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootDescriptorTable(ID3D12GraphicsCommandList4 *iface, + UINT root_parameter_index, D3D12_GPU_DESCRIPTOR_HANDLE base_descriptor) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); + + TRACE("iface %p, root_parameter_index %u, base_descriptor %#"PRIx64".\n", + iface, root_parameter_index, base_descriptor.ptr); +@@ -4524,10 +4525,10 @@ static void d3d12_command_list_set_root_constants(struct d3d12_command_list *lis + c->stage_flags, c->offset + offset * sizeof(uint32_t), count * sizeof(uint32_t), data)); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRoot32BitConstant(ID3D12GraphicsCommandList3 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRoot32BitConstant(ID3D12GraphicsCommandList4 *iface, + UINT root_parameter_index, UINT data, UINT dst_offset) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); + + TRACE("iface %p, root_parameter_index %u, data 0x%08x, dst_offset %u.\n", + iface, root_parameter_index, data, dst_offset); +@@ -4536,10 +4537,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRoot32BitConstant(ID3 + root_parameter_index, dst_offset, 1, &data); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRoot32BitConstant(ID3D12GraphicsCommandList3 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRoot32BitConstant(ID3D12GraphicsCommandList4 *iface, + UINT root_parameter_index, UINT data, UINT dst_offset) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); + + TRACE("iface %p, root_parameter_index %u, data 0x%08x, dst_offset %u.\n", + iface, root_parameter_index, data, dst_offset); +@@ -4548,10 +4549,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRoot32BitConstant(ID + root_parameter_index, dst_offset, 1, &data); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRoot32BitConstants(ID3D12GraphicsCommandList3 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRoot32BitConstants(ID3D12GraphicsCommandList4 *iface, + UINT root_parameter_index, UINT constant_count, const void *data, UINT dst_offset) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); + + TRACE("iface %p, root_parameter_index %u, constant_count %u, data %p, dst_offset %u.\n", + iface, root_parameter_index, constant_count, data, dst_offset); +@@ -4560,10 +4561,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRoot32BitConstants(ID + root_parameter_index, dst_offset, constant_count, data); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRoot32BitConstants(ID3D12GraphicsCommandList3 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRoot32BitConstants(ID3D12GraphicsCommandList4 *iface, + UINT root_parameter_index, UINT constant_count, const void *data, UINT dst_offset) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); + + TRACE("iface %p, root_parameter_index %u, constant_count %u, data %p, dst_offset %u.\n", + iface, root_parameter_index, constant_count, data, dst_offset); +@@ -4625,9 +4626,9 @@ static void d3d12_command_list_set_root_cbv(struct d3d12_command_list *list, + } + + static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootConstantBufferView( +- ID3D12GraphicsCommandList3 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address) ++ ID3D12GraphicsCommandList4 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); + + TRACE("iface %p, root_parameter_index %u, address %#"PRIx64".\n", + iface, root_parameter_index, address); +@@ -4636,9 +4637,9 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootConstantBufferVie + } + + static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootConstantBufferView( +- ID3D12GraphicsCommandList3 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address) ++ ID3D12GraphicsCommandList4 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); + + TRACE("iface %p, root_parameter_index %u, address %#"PRIx64".\n", + iface, root_parameter_index, address); +@@ -4697,9 +4698,9 @@ static void d3d12_command_list_set_root_descriptor(struct d3d12_command_list *li + } + + static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootShaderResourceView( +- ID3D12GraphicsCommandList3 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address) ++ ID3D12GraphicsCommandList4 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); + + TRACE("iface %p, root_parameter_index %u, address %#"PRIx64".\n", + iface, root_parameter_index, address); +@@ -4709,9 +4710,9 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootShaderResourceVie + } + + static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootShaderResourceView( +- ID3D12GraphicsCommandList3 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address) ++ ID3D12GraphicsCommandList4 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); + + TRACE("iface %p, root_parameter_index %u, address %#"PRIx64".\n", + iface, root_parameter_index, address); +@@ -4721,9 +4722,9 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootShaderResourceVi + } + + static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootUnorderedAccessView( +- ID3D12GraphicsCommandList3 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address) ++ ID3D12GraphicsCommandList4 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); + + TRACE("iface %p, root_parameter_index %u, address %#"PRIx64".\n", + iface, root_parameter_index, address); +@@ -4733,9 +4734,9 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootUnorderedAccessVi + } + + static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootUnorderedAccessView( +- ID3D12GraphicsCommandList3 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address) ++ ID3D12GraphicsCommandList4 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); + + TRACE("iface %p, root_parameter_index %u, address %#"PRIx64".\n", + iface, root_parameter_index, address); +@@ -4744,10 +4745,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootUnorderedAccessV + root_parameter_index, address); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_IASetIndexBuffer(ID3D12GraphicsCommandList3 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_IASetIndexBuffer(ID3D12GraphicsCommandList4 *iface, + const D3D12_INDEX_BUFFER_VIEW *view) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); + const struct vkd3d_vk_device_procs *vk_procs; + struct d3d12_resource *resource; + enum VkIndexType index_type; +@@ -4787,10 +4788,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_IASetIndexBuffer(ID3D12Graphics + view->BufferLocation - resource->gpu_address, index_type)); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_IASetVertexBuffers(ID3D12GraphicsCommandList3 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_IASetVertexBuffers(ID3D12GraphicsCommandList4 *iface, + UINT start_slot, UINT view_count, const D3D12_VERTEX_BUFFER_VIEW *views) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); + const struct vkd3d_null_resources *null_resources; + struct vkd3d_gpu_va_allocator *gpu_va_allocator; + VkDeviceSize offsets[ARRAY_SIZE(list->strides)]; +@@ -4845,10 +4846,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_IASetVertexBuffers(ID3D12Graphi + d3d12_command_list_invalidate_current_pipeline(list); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_SOSetTargets(ID3D12GraphicsCommandList3 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_SOSetTargets(ID3D12GraphicsCommandList4 *iface, + UINT start_slot, UINT view_count, const D3D12_STREAM_OUTPUT_BUFFER_VIEW *views) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); + VkDeviceSize offsets[ARRAY_SIZE(list->so_counter_buffers)]; + VkDeviceSize sizes[ARRAY_SIZE(list->so_counter_buffers)]; + VkBuffer buffers[ARRAY_SIZE(list->so_counter_buffers)]; +@@ -4910,11 +4911,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_SOSetTargets(ID3D12GraphicsComm + VK_CALL(vkCmdBindTransformFeedbackBuffersEXT(list->vk_command_buffer, first, count, buffers, offsets, sizes)); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_OMSetRenderTargets(ID3D12GraphicsCommandList3 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_OMSetRenderTargets(ID3D12GraphicsCommandList4 *iface, + UINT render_target_descriptor_count, const D3D12_CPU_DESCRIPTOR_HANDLE *render_target_descriptors, + BOOL single_descriptor_handle, const D3D12_CPU_DESCRIPTOR_HANDLE *depth_stencil_descriptor) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); + const struct d3d12_rtv_desc *rtv_desc; + const struct d3d12_dsv_desc *dsv_desc; + VkFormat prev_dsv_format; +@@ -5115,12 +5116,12 @@ static void d3d12_command_list_clear(struct d3d12_command_list *list, + } + } + +-static void STDMETHODCALLTYPE d3d12_command_list_ClearDepthStencilView(ID3D12GraphicsCommandList3 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_ClearDepthStencilView(ID3D12GraphicsCommandList4 *iface, + D3D12_CPU_DESCRIPTOR_HANDLE dsv, D3D12_CLEAR_FLAGS flags, float depth, UINT8 stencil, + UINT rect_count, const D3D12_RECT *rects) + { + const union VkClearValue clear_value = {.depthStencil = {depth, stencil}}; +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); + const struct d3d12_dsv_desc *dsv_desc = d3d12_dsv_desc_from_cpu_handle(dsv); + struct VkAttachmentDescription attachment_desc; + struct VkAttachmentReference ds_reference; +@@ -5164,10 +5165,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearDepthStencilView(ID3D12Gra + &clear_value, rect_count, rects); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_ClearRenderTargetView(ID3D12GraphicsCommandList3 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_ClearRenderTargetView(ID3D12GraphicsCommandList4 *iface, + D3D12_CPU_DESCRIPTOR_HANDLE rtv, const FLOAT color[4], UINT rect_count, const D3D12_RECT *rects) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); + const struct d3d12_rtv_desc *rtv_desc = d3d12_rtv_desc_from_cpu_handle(rtv); + struct VkAttachmentDescription attachment_desc; + struct VkAttachmentReference color_reference; +@@ -5412,11 +5413,11 @@ static const struct vkd3d_format *vkd3d_fixup_clear_uav_uint_colour(struct d3d12 + } + } + +-static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewUint(ID3D12GraphicsCommandList3 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewUint(ID3D12GraphicsCommandList4 *iface, + D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle, D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle, ID3D12Resource *resource, + const UINT values[4], UINT rect_count, const D3D12_RECT *rects) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); + struct vkd3d_view *descriptor, *uint_view = NULL; + struct d3d12_device *device = list->device; + struct vkd3d_texture_view_desc view_desc; +@@ -5480,11 +5481,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewUint(ID + vkd3d_view_decref(uint_view, device); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewFloat(ID3D12GraphicsCommandList3 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewFloat(ID3D12GraphicsCommandList4 *iface, + D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle, D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle, ID3D12Resource *resource, + const float values[4], UINT rect_count, const D3D12_RECT *rects) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); + struct d3d12_resource *resource_impl; + VkClearColorValue colour; + struct vkd3d_view *view; +@@ -5500,16 +5501,16 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewFloat(I + d3d12_command_list_clear_uav(list, resource_impl, view, &colour, rect_count, rects); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_DiscardResource(ID3D12GraphicsCommandList3 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_DiscardResource(ID3D12GraphicsCommandList4 *iface, + ID3D12Resource *resource, const D3D12_DISCARD_REGION *region) + { + FIXME_ONCE("iface %p, resource %p, region %p stub!\n", iface, resource, region); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_BeginQuery(ID3D12GraphicsCommandList3 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_BeginQuery(ID3D12GraphicsCommandList4 *iface, + ID3D12QueryHeap *heap, D3D12_QUERY_TYPE type, UINT index) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); + struct d3d12_query_heap *query_heap = unsafe_impl_from_ID3D12QueryHeap(heap); + const struct vkd3d_vk_device_procs *vk_procs; + VkQueryControlFlags flags = 0; +@@ -5536,10 +5537,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_BeginQuery(ID3D12GraphicsComman + VK_CALL(vkCmdBeginQuery(list->vk_command_buffer, query_heap->vk_query_pool, index, flags)); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_EndQuery(ID3D12GraphicsCommandList3 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_EndQuery(ID3D12GraphicsCommandList4 *iface, + ID3D12QueryHeap *heap, D3D12_QUERY_TYPE type, UINT index) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); + struct d3d12_query_heap *query_heap = unsafe_impl_from_ID3D12QueryHeap(heap); + const struct vkd3d_vk_device_procs *vk_procs; + +@@ -5581,12 +5582,12 @@ static size_t get_query_stride(D3D12_QUERY_TYPE type) + return sizeof(uint64_t); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_ResolveQueryData(ID3D12GraphicsCommandList3 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_ResolveQueryData(ID3D12GraphicsCommandList4 *iface, + ID3D12QueryHeap *heap, D3D12_QUERY_TYPE type, UINT start_index, UINT query_count, + ID3D12Resource *dst_buffer, UINT64 aligned_dst_buffer_offset) + { + const struct d3d12_query_heap *query_heap = unsafe_impl_from_ID3D12QueryHeap(heap); +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); + struct d3d12_resource *buffer = unsafe_impl_from_ID3D12Resource(dst_buffer); + const struct vkd3d_vk_device_procs *vk_procs; + unsigned int i, first, count; +@@ -5662,10 +5663,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_ResolveQueryData(ID3D12Graphics + } + } + +-static void STDMETHODCALLTYPE d3d12_command_list_SetPredication(ID3D12GraphicsCommandList3 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_SetPredication(ID3D12GraphicsCommandList4 *iface, + ID3D12Resource *buffer, UINT64 aligned_buffer_offset, D3D12_PREDICATION_OP operation) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); + struct d3d12_resource *resource = unsafe_impl_from_ID3D12Resource(buffer); + const struct vkd3d_vulkan_info *vk_info = &list->device->vk_info; + const struct vkd3d_vk_device_procs *vk_procs; +@@ -5734,19 +5735,19 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetPredication(ID3D12GraphicsCo + } + } + +-static void STDMETHODCALLTYPE d3d12_command_list_SetMarker(ID3D12GraphicsCommandList3 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_SetMarker(ID3D12GraphicsCommandList4 *iface, + UINT metadata, const void *data, UINT size) + { + FIXME("iface %p, metadata %#x, data %p, size %u stub!\n", iface, metadata, data, size); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_BeginEvent(ID3D12GraphicsCommandList3 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_BeginEvent(ID3D12GraphicsCommandList4 *iface, + UINT metadata, const void *data, UINT size) + { + FIXME("iface %p, metadata %#x, data %p, size %u stub!\n", iface, metadata, data, size); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_EndEvent(ID3D12GraphicsCommandList3 *iface) ++static void STDMETHODCALLTYPE d3d12_command_list_EndEvent(ID3D12GraphicsCommandList4 *iface) + { + FIXME("iface %p stub!\n", iface); + } +@@ -5755,14 +5756,14 @@ STATIC_ASSERT(sizeof(VkDispatchIndirectCommand) == sizeof(D3D12_DISPATCH_ARGUMEN + STATIC_ASSERT(sizeof(VkDrawIndexedIndirectCommand) == sizeof(D3D12_DRAW_INDEXED_ARGUMENTS)); + STATIC_ASSERT(sizeof(VkDrawIndirectCommand) == sizeof(D3D12_DRAW_ARGUMENTS)); + +-static void STDMETHODCALLTYPE d3d12_command_list_ExecuteIndirect(ID3D12GraphicsCommandList3 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_ExecuteIndirect(ID3D12GraphicsCommandList4 *iface, + ID3D12CommandSignature *command_signature, UINT max_command_count, ID3D12Resource *arg_buffer, + UINT64 arg_buffer_offset, ID3D12Resource *count_buffer, UINT64 count_buffer_offset) + { + struct d3d12_command_signature *sig_impl = unsafe_impl_from_ID3D12CommandSignature(command_signature); + struct d3d12_resource *count_impl = unsafe_impl_from_ID3D12Resource(count_buffer); + struct d3d12_resource *arg_impl = unsafe_impl_from_ID3D12Resource(arg_buffer); +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); + const D3D12_COMMAND_SIGNATURE_DESC *signature_desc; + const struct vkd3d_vk_device_procs *vk_procs; + unsigned int i; +@@ -5861,7 +5862,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_ExecuteIndirect(ID3D12GraphicsC + d3d12_command_signature_decref(sig_impl); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_AtomicCopyBufferUINT(ID3D12GraphicsCommandList3 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_AtomicCopyBufferUINT(ID3D12GraphicsCommandList4 *iface, + ID3D12Resource *dst_buffer, UINT64 dst_offset, + ID3D12Resource *src_buffer, UINT64 src_offset, + UINT dependent_resource_count, ID3D12Resource * const *dependent_resources, +@@ -5874,7 +5875,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_AtomicCopyBufferUINT(ID3D12Grap + dependent_resource_count, dependent_resources, dependent_sub_resource_ranges); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_AtomicCopyBufferUINT64(ID3D12GraphicsCommandList3 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_AtomicCopyBufferUINT64(ID3D12GraphicsCommandList4 *iface, + ID3D12Resource *dst_buffer, UINT64 dst_offset, + ID3D12Resource *src_buffer, UINT64 src_offset, + UINT dependent_resource_count, ID3D12Resource * const *dependent_resources, +@@ -5887,20 +5888,20 @@ static void STDMETHODCALLTYPE d3d12_command_list_AtomicCopyBufferUINT64(ID3D12Gr + dependent_resource_count, dependent_resources, dependent_sub_resource_ranges); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_OMSetDepthBounds(ID3D12GraphicsCommandList3 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_OMSetDepthBounds(ID3D12GraphicsCommandList4 *iface, + FLOAT min, FLOAT max) + { + FIXME("iface %p, min %.8e, max %.8e stub!\n", iface, min, max); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_SetSamplePositions(ID3D12GraphicsCommandList3 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_SetSamplePositions(ID3D12GraphicsCommandList4 *iface, + UINT sample_count, UINT pixel_count, D3D12_SAMPLE_POSITION *sample_positions) + { + FIXME("iface %p, sample_count %u, pixel_count %u, sample_positions %p stub!\n", + iface, sample_count, pixel_count, sample_positions); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_ResolveSubresourceRegion(ID3D12GraphicsCommandList3 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_ResolveSubresourceRegion(ID3D12GraphicsCommandList4 *iface, + ID3D12Resource *dst_resource, UINT dst_sub_resource_idx, UINT dst_x, UINT dst_y, + ID3D12Resource *src_resource, UINT src_sub_resource_idx, + D3D12_RECT *src_rect, DXGI_FORMAT format, D3D12_RESOLVE_MODE mode) +@@ -5912,16 +5913,16 @@ static void STDMETHODCALLTYPE d3d12_command_list_ResolveSubresourceRegion(ID3D12 + src_resource, src_sub_resource_idx, src_rect, format, mode); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_SetViewInstanceMask(ID3D12GraphicsCommandList3 *iface, UINT mask) ++static void STDMETHODCALLTYPE d3d12_command_list_SetViewInstanceMask(ID3D12GraphicsCommandList4 *iface, UINT mask) + { + FIXME("iface %p, mask %#x stub!\n", iface, mask); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_WriteBufferImmediate(ID3D12GraphicsCommandList3 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_WriteBufferImmediate(ID3D12GraphicsCommandList4 *iface, + UINT count, const D3D12_WRITEBUFFERIMMEDIATE_PARAMETER *parameters, + const D3D12_WRITEBUFFERIMMEDIATE_MODE *modes) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); + struct d3d12_resource *resource; + unsigned int i; + +@@ -5934,13 +5935,76 @@ static void STDMETHODCALLTYPE d3d12_command_list_WriteBufferImmediate(ID3D12Grap + } + } + +-static void STDMETHODCALLTYPE d3d12_command_list_SetProtectedResourceSession(ID3D12GraphicsCommandList3 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_SetProtectedResourceSession(ID3D12GraphicsCommandList4 *iface, + ID3D12ProtectedResourceSession *protected_session) + { + FIXME("iface %p, protected_session %p stub!\n", iface, protected_session); + } + +-static const struct ID3D12GraphicsCommandList3Vtbl d3d12_command_list_vtbl = ++static void STDMETHODCALLTYPE d3d12_command_list_BeginRenderPass(ID3D12GraphicsCommandList4 *iface, ++ UINT count, const D3D12_RENDER_PASS_RENDER_TARGET_DESC *render_targets, ++ const D3D12_RENDER_PASS_DEPTH_STENCIL_DESC *depth_stencil, D3D12_RENDER_PASS_FLAGS flags) ++{ ++ FIXME("iface %p, count %u, render_targets %p, depth_stencil %p, flags %#x stub!\n", iface, ++ count, render_targets, depth_stencil, flags); ++} ++ ++static void STDMETHODCALLTYPE d3d12_command_list_EndRenderPass(ID3D12GraphicsCommandList4 *iface) ++{ ++ FIXME("iface %p stub!\n", iface); ++} ++ ++static void STDMETHODCALLTYPE d3d12_command_list_InitializeMetaCommand(ID3D12GraphicsCommandList4 *iface, ++ ID3D12MetaCommand *meta_command, const void *parameters_data, SIZE_T data_size_in_bytes) ++{ ++ FIXME("iface %p, meta_command %p, parameters_data %p, data_size_in_bytes %lu stub!\n", iface, ++ meta_command, parameters_data, data_size_in_bytes); ++} ++ ++static void STDMETHODCALLTYPE d3d12_command_list_ExecuteMetaCommand(ID3D12GraphicsCommandList4 *iface, ++ ID3D12MetaCommand *meta_command, const void *parameters_data, SIZE_T data_size_in_bytes) ++{ ++ FIXME("iface %p, meta_command %p, parameters_data %p, data_size_in_bytes %lu stub!\n", iface, ++ meta_command, parameters_data, data_size_in_bytes); ++} ++ ++static void STDMETHODCALLTYPE d3d12_command_list_BuildRaytracingAccelerationStructure(ID3D12GraphicsCommandList4 *iface, ++ const D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_DESC *desc, UINT count, ++ const D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_DESC *postbuild_info_descs) ++{ ++ FIXME("iface %p, desc %p, count %u, postbuild_info_descs %p stub!\n", iface, desc, count, postbuild_info_descs); ++} ++ ++static void STDMETHODCALLTYPE d3d12_command_list_EmitRaytracingAccelerationStructurePostbuildInfo(ID3D12GraphicsCommandList4 *iface, ++ const D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_DESC *desc, ++ UINT structures_count, const D3D12_GPU_VIRTUAL_ADDRESS *src_structure_data) ++{ ++ FIXME("iface %p, desc %p, structures_count %u, src_structure_data %p stub!\n", ++ iface, desc, structures_count, src_structure_data); ++} ++ ++static void STDMETHODCALLTYPE d3d12_command_list_CopyRaytracingAccelerationStructure(ID3D12GraphicsCommandList4 *iface, ++ D3D12_GPU_VIRTUAL_ADDRESS dst_structure_data, ++ D3D12_GPU_VIRTUAL_ADDRESS src_structure_data, ++ D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE mode) ++{ ++ FIXME("iface %p, dst_structure_data %#"PRIx64", src_structure_data %#"PRIx64", mode %u stub!\n", ++ iface, dst_structure_data, src_structure_data, mode); ++} ++ ++static void STDMETHODCALLTYPE d3d12_command_list_SetPipelineState1(ID3D12GraphicsCommandList4 *iface, ++ ID3D12StateObject *state_object) ++{ ++ FIXME("iface %p, state_object %p stub!\n", iface, state_object); ++} ++ ++static void STDMETHODCALLTYPE d3d12_command_list_DispatchRays(ID3D12GraphicsCommandList4 *iface, ++ const D3D12_DISPATCH_RAYS_DESC *desc) ++{ ++ FIXME("iface %p, desc %p stub!\n", iface, desc); ++} ++ ++static const struct ID3D12GraphicsCommandList4Vtbl d3d12_command_list_vtbl = + { + /* IUnknown methods */ + d3d12_command_list_QueryInterface, +@@ -6018,6 +6082,16 @@ static const struct ID3D12GraphicsCommandList3Vtbl d3d12_command_list_vtbl = + d3d12_command_list_WriteBufferImmediate, + /* ID3D12GraphicsCommandList3 methods */ + d3d12_command_list_SetProtectedResourceSession, ++ /* ID3D12GraphicsCommandList4 methods */ ++ d3d12_command_list_BeginRenderPass, ++ d3d12_command_list_EndRenderPass, ++ d3d12_command_list_InitializeMetaCommand, ++ d3d12_command_list_ExecuteMetaCommand, ++ d3d12_command_list_BuildRaytracingAccelerationStructure, ++ d3d12_command_list_EmitRaytracingAccelerationStructurePostbuildInfo, ++ d3d12_command_list_CopyRaytracingAccelerationStructure, ++ d3d12_command_list_SetPipelineState1, ++ d3d12_command_list_DispatchRays, + }; + + static struct d3d12_command_list *unsafe_impl_from_ID3D12CommandList(ID3D12CommandList *iface) +@@ -6025,7 +6099,7 @@ static struct d3d12_command_list *unsafe_impl_from_ID3D12CommandList(ID3D12Comma + if (!iface) + return NULL; + assert(iface->lpVtbl == (struct ID3D12CommandListVtbl *)&d3d12_command_list_vtbl); +- return CONTAINING_RECORD(iface, struct d3d12_command_list, ID3D12GraphicsCommandList3_iface); ++ return CONTAINING_RECORD(iface, struct d3d12_command_list, ID3D12GraphicsCommandList4_iface); + } + + static HRESULT d3d12_command_list_init(struct d3d12_command_list *list, struct d3d12_device *device, +@@ -6034,7 +6108,7 @@ static HRESULT d3d12_command_list_init(struct d3d12_command_list *list, struct d + { + HRESULT hr; + +- list->ID3D12GraphicsCommandList3_iface.lpVtbl = &d3d12_command_list_vtbl; ++ list->ID3D12GraphicsCommandList4_iface.lpVtbl = &d3d12_command_list_vtbl; + list->refcount = 1; + + list->type = type; +diff --git a/libs/vkd3d/libs/vkd3d/device.c b/libs/vkd3d/libs/vkd3d/device.c +index d8c94fbfd94..6ff298741f8 100644 +--- a/libs/vkd3d/libs/vkd3d/device.c ++++ b/libs/vkd3d/libs/vkd3d/device.c +@@ -2667,8 +2667,8 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandList(ID3D12Device5 *i + initial_pipeline_state, &object))) + return hr; + +- return return_interface(&object->ID3D12GraphicsCommandList3_iface, +- &IID_ID3D12GraphicsCommandList3, riid, command_list); ++ return return_interface(&object->ID3D12GraphicsCommandList4_iface, ++ &IID_ID3D12GraphicsCommandList4, riid, command_list); + } + + /* Direct3D feature levels restrict which formats can be optionally supported. */ +diff --git a/libs/vkd3d/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/libs/vkd3d/vkd3d_private.h +index 89f8b15ee14..6a9c8c657d1 100644 +--- a/libs/vkd3d/libs/vkd3d/vkd3d_private.h ++++ b/libs/vkd3d/libs/vkd3d/vkd3d_private.h +@@ -22,6 +22,7 @@ + #define COBJMACROS + #define NONAMELESSUNION + #define VK_NO_PROTOTYPES ++#define CONST_VTABLE + + #ifdef _WIN32 + # define _WIN32_WINNT 0x0600 /* for condition variables */ +@@ -1428,7 +1429,7 @@ enum vkd3d_pipeline_bind_point + /* ID3D12CommandList */ + struct d3d12_command_list + { +- ID3D12GraphicsCommandList3 ID3D12GraphicsCommandList3_iface; ++ ID3D12GraphicsCommandList4 ID3D12GraphicsCommandList4_iface; + LONG refcount; + + D3D12_COMMAND_LIST_TYPE type; +-- +2.42.0 + diff --git a/patches/vkd3d-latest/0003-vkd3d-shader-Fix-compiler-warning.patch b/patches/vkd3d-latest/0003-vkd3d-shader-Fix-compiler-warning.patch deleted file mode 100644 index 8cc333dc..00000000 --- a/patches/vkd3d-latest/0003-vkd3d-shader-Fix-compiler-warning.patch +++ /dev/null @@ -1,30 +0,0 @@ -From f624fad55b83330c84a883efa46a1541325db9aa Mon Sep 17 00:00:00 2001 -From: Alistair Leslie-Hughes -Date: Fri, 29 Sep 2023 17:22:13 +1000 -Subject: [PATCH 3/3] vkd3d-shader: Fix compiler warning. -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -vkd3d-shader/tpf.c:3810:39: warning: passing argument 2 of ‘sm4_register_from_node’ from incompatible pointer type [-Wincompatible-pointer-types] -vkd3d-shader/tpf.c:4750:59: warning: passing argument 3 of ‘sm4_register_from_deref’ from incompatible pointer type [-Wincompatible-pointer-types] ---- - libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -index af75ef3bda8..2e9a98a6fc3 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -@@ -758,7 +758,7 @@ void vsir_register_init(struct vkd3d_shader_register *reg, enum vkd3d_shader_reg - struct vkd3d_shader_dst_param - { - struct vkd3d_shader_register reg; -- DWORD write_mask; -+ unsigned int write_mask; - DWORD modifiers; - DWORD shift; - }; --- -2.42.0 - diff --git a/patches/vkd3d-latest/0004-Updated-vkd3d-to-6a942581db3093a2e5b5a76334601868e21.patch b/patches/vkd3d-latest/0004-Updated-vkd3d-to-6a942581db3093a2e5b5a76334601868e21.patch new file mode 100644 index 00000000..e831282f --- /dev/null +++ b/patches/vkd3d-latest/0004-Updated-vkd3d-to-6a942581db3093a2e5b5a76334601868e21.patch @@ -0,0 +1,3289 @@ +From 7bd7902bc3338fb9789c3f8dabb65485df4fb2f1 Mon Sep 17 00:00:00 2001 +From: Alistair Leslie-Hughes +Date: Wed, 11 Oct 2023 07:11:35 +1100 +Subject: [PATCH] Updated vkd3d to 6a942581db3093a2e5b5a76334601868e217a60d. + +--- + libs/vkd3d/include/vkd3d_shader.h | 34 +- + libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 7 +- + libs/vkd3d/libs/vkd3d-shader/hlsl.c | 54 +- + libs/vkd3d/libs/vkd3d-shader/hlsl.h | 18 +- + libs/vkd3d/libs/vkd3d-shader/hlsl.l | 2 + + libs/vkd3d/libs/vkd3d-shader/hlsl.y | 157 +++- + libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 92 +- + .../libs/vkd3d-shader/hlsl_constant_ops.c | 170 ++++ + libs/vkd3d/libs/vkd3d-shader/ir.c | 71 ++ + libs/vkd3d/libs/vkd3d-shader/spirv.c | 14 +- + libs/vkd3d/libs/vkd3d-shader/tpf.c | 806 +++++++++--------- + .../libs/vkd3d-shader/vkd3d_shader_main.c | 15 + + .../libs/vkd3d-shader/vkd3d_shader_private.h | 3 +- + libs/vkd3d/libs/vkd3d/command.c | 292 ++++--- + libs/vkd3d/libs/vkd3d/device.c | 20 +- + libs/vkd3d/libs/vkd3d/resource.c | 8 +- + libs/vkd3d/libs/vkd3d/vkd3d_private.h | 4 +- + 17 files changed, 1132 insertions(+), 635 deletions(-) + +diff --git a/libs/vkd3d/include/vkd3d_shader.h b/libs/vkd3d/include/vkd3d_shader.h +index 01356ce3931..9d0d768b43d 100644 +--- a/libs/vkd3d/include/vkd3d_shader.h ++++ b/libs/vkd3d/include/vkd3d_shader.h +@@ -1383,16 +1383,30 @@ struct vkd3d_shader_descriptor_info + * + * This structure extends vkd3d_shader_compile_info. + * +- * When scanning a legacy Direct3D shader, vkd3d-shader enumerates each +- * constant register set used by the shader as a single constant buffer +- * descriptor, as follows: +- * - The \ref vkd3d_shader_descriptor_info.type field is set to +- * VKD3D_SHADER_DESCRIPTOR_TYPE_CBV. +- * - The \ref vkd3d_shader_descriptor_info.register_space field is set to zero. +- * - The \ref vkd3d_shader_descriptor_info.register_index field is set to a +- * member of enum vkd3d_shader_d3dbc_constant_register denoting which set +- * is used. +- * - The \ref vkd3d_shader_descriptor_info.count field is set to one. ++ * When scanning a legacy Direct3D shader, vkd3d-shader enumerates descriptors ++ * as follows: ++ * ++ * - Each constant register set used by the shader is scanned as a single ++ * constant buffer descriptor, as follows: ++ * * The \ref vkd3d_shader_descriptor_info.type field is set to ++ * VKD3D_SHADER_DESCRIPTOR_TYPE_CBV. ++ * * The \ref vkd3d_shader_descriptor_info.register_space field is set to zero. ++ * * The \ref vkd3d_shader_descriptor_info.register_index field is set to a ++ * member of enum vkd3d_shader_d3dbc_constant_register denoting which set ++ * is used. ++ * * The \ref vkd3d_shader_descriptor_info.count field is set to one. ++ * - Each sampler used by the shader is scanned as two separate descriptors, ++ * one representing the texture, and one representing the sampler state. ++ * If desired, these may be mapped back into a single combined sampler using ++ * struct vkd3d_shader_combined_resource_sampler. ++ * The fields are set as follows: ++ * * The \ref vkd3d_shader_descriptor_info.type field is set to ++ * VKD3D_SHADER_DESCRIPTOR_TYPE_SRV and VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER ++ * respectively. ++ * * The \ref vkd3d_shader_descriptor_info.register_space field is set to zero. ++ * * The \ref vkd3d_shader_descriptor_info.register_index field is set to the ++ * binding index of the original sampler, for both descriptors. ++ * * The \ref vkd3d_shader_descriptor_info.count field is set to one. + * + * In summary, there may be up to three such descriptors, one for each register + * set used by the shader: float, integer, and boolean. +diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c +index 6a3513a2827..38a607351fe 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c ++++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c +@@ -637,7 +637,7 @@ static void shader_dump_decl_usage(struct vkd3d_d3d_asm_compiler *compiler, + { + struct vkd3d_string_buffer *buffer = &compiler->buffer; + +- if (semantic->resource.reg.reg.type == VKD3DSPR_SAMPLER) ++ if (semantic->resource.reg.reg.type == VKD3DSPR_COMBINED_SAMPLER) + { + switch (semantic->resource_type) + { +@@ -880,9 +880,7 @@ static void shader_dump_register(struct vkd3d_d3d_asm_compiler *compiler, const + break; + + case VKD3DSPR_COLOROUT: +- shader_addline(buffer, "o"); +- if (!shader_ver_ge(&compiler->shader_version, 4, 0)) +- shader_addline(buffer, "C"); ++ shader_addline(buffer, "oC"); + break; + + case VKD3DSPR_DEPTHOUT: +@@ -926,6 +924,7 @@ static void shader_dump_register(struct vkd3d_d3d_asm_compiler *compiler, const + shader_addline(buffer, "aL"); + break; + ++ case VKD3DSPR_COMBINED_SAMPLER: + case VKD3DSPR_SAMPLER: + shader_addline(buffer, "s"); + is_descriptor = true; +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c +index 5fe9047bf25..b42e30888a9 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c +@@ -216,13 +216,15 @@ bool hlsl_type_is_resource(const struct hlsl_type *type) + return false; + } + +-enum hlsl_regset hlsl_type_get_regset(const struct hlsl_type *type) ++/* Only intended to be used for derefs (after copies have been lowered to components or vectors) or ++ * resources, since for both their data types span across a single regset. */ ++static enum hlsl_regset type_get_regset(const struct hlsl_type *type) + { + if (type->class <= HLSL_CLASS_LAST_NUMERIC) + return HLSL_REGSET_NUMERIC; + + if (type->class == HLSL_CLASS_ARRAY) +- return hlsl_type_get_regset(type->e.array.type); ++ return type_get_regset(type->e.array.type); + + if (type->class == HLSL_CLASS_OBJECT) + { +@@ -245,6 +247,18 @@ enum hlsl_regset hlsl_type_get_regset(const struct hlsl_type *type) + vkd3d_unreachable(); + } + ++enum hlsl_regset hlsl_deref_get_regset(struct hlsl_ctx *ctx, const struct hlsl_deref *deref) ++{ ++ struct hlsl_type *type; ++ ++ if (deref->data_type) ++ type = deref->data_type; ++ else ++ type = hlsl_deref_get_type(ctx, deref); ++ ++ return type_get_regset(type); ++} ++ + unsigned int hlsl_type_get_sm4_offset(const struct hlsl_type *type, unsigned int offset) + { + /* Align to the next vec4 boundary if: +@@ -324,7 +338,7 @@ static void hlsl_type_calculate_reg_size(struct hlsl_ctx *ctx, struct hlsl_type + { + if (hlsl_type_is_resource(type)) + { +- enum hlsl_regset regset = hlsl_type_get_regset(type); ++ enum hlsl_regset regset = type_get_regset(type); + + type->reg_size[regset] = 1; + } +@@ -452,11 +466,11 @@ struct hlsl_type *hlsl_type_get_component_type(struct hlsl_ctx *ctx, struct hlsl + } + + unsigned int hlsl_type_get_component_offset(struct hlsl_ctx *ctx, struct hlsl_type *type, +- enum hlsl_regset regset, unsigned int index) ++ unsigned int index, enum hlsl_regset *regset) + { ++ unsigned int offset[HLSL_REGSET_LAST + 1] = {0}; + struct hlsl_type *next_type; +- unsigned int offset = 0; +- unsigned int idx; ++ unsigned int idx, r; + + while (!type_is_single_component(type)) + { +@@ -468,19 +482,22 @@ unsigned int hlsl_type_get_component_offset(struct hlsl_ctx *ctx, struct hlsl_ty + case HLSL_CLASS_SCALAR: + case HLSL_CLASS_VECTOR: + case HLSL_CLASS_MATRIX: +- if (regset == HLSL_REGSET_NUMERIC) +- offset += idx; ++ offset[HLSL_REGSET_NUMERIC] += idx; + break; + + case HLSL_CLASS_STRUCT: +- offset += type->e.record.fields[idx].reg_offset[regset]; ++ for (r = 0; r <= HLSL_REGSET_LAST; ++r) ++ offset[r] += type->e.record.fields[idx].reg_offset[r]; + break; + + case HLSL_CLASS_ARRAY: +- if (regset == HLSL_REGSET_NUMERIC) +- offset += idx * align(type->e.array.type->reg_size[regset], 4); +- else +- offset += idx * type->e.array.type->reg_size[regset]; ++ for (r = 0; r <= HLSL_REGSET_LAST; ++r) ++ { ++ if (r == HLSL_REGSET_NUMERIC) ++ offset[r] += idx * align(type->e.array.type->reg_size[r], 4); ++ else ++ offset[r] += idx * type->e.array.type->reg_size[r]; ++ } + break; + + case HLSL_CLASS_OBJECT: +@@ -493,7 +510,8 @@ unsigned int hlsl_type_get_component_offset(struct hlsl_ctx *ctx, struct hlsl_ty + type = next_type; + } + +- return offset; ++ *regset = type_get_regset(type); ++ return offset[*regset]; + } + + static bool init_deref(struct hlsl_ctx *ctx, struct hlsl_deref *deref, struct hlsl_ir_var *var, +@@ -2193,6 +2211,10 @@ struct vkd3d_string_buffer *hlsl_modifiers_to_string(struct hlsl_ctx *ctx, unsig + vkd3d_string_buffer_printf(string, "extern "); + if (modifiers & HLSL_STORAGE_NOINTERPOLATION) + vkd3d_string_buffer_printf(string, "nointerpolation "); ++ if (modifiers & HLSL_STORAGE_CENTROID) ++ vkd3d_string_buffer_printf(string, "centroid "); ++ if (modifiers & HLSL_STORAGE_NOPERSPECTIVE) ++ vkd3d_string_buffer_printf(string, "noperspective "); + if (modifiers & HLSL_MODIFIER_PRECISE) + vkd3d_string_buffer_printf(string, "precise "); + if (modifiers & HLSL_STORAGE_SHARED) +@@ -2540,6 +2562,10 @@ static void dump_ir_jump(struct vkd3d_string_buffer *buffer, const struct hlsl_i + case HLSL_IR_JUMP_RETURN: + vkd3d_string_buffer_printf(buffer, "return"); + break; ++ ++ case HLSL_IR_JUMP_UNRESOLVED_CONTINUE: ++ vkd3d_string_buffer_printf(buffer, "unresolved_continue"); ++ break; + } + } + +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h +index f33e1d74378..29259767104 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h +@@ -25,9 +25,6 @@ + #include "d3dcommon.h" + #include "d3dx9shader.h" + +-enum vkd3d_sm4_register_type; +-enum vkd3d_sm4_swizzle_type; +- + /* The general IR structure is inspired by Mesa GLSL hir, even though the code + * ends up being quite different in practice. Anyway, here comes the relevant + * licensing information. +@@ -357,11 +354,16 @@ struct hlsl_attribute + #define HLSL_STORAGE_IN 0x00000800 + #define HLSL_STORAGE_OUT 0x00001000 + #define HLSL_MODIFIER_INLINE 0x00002000 ++#define HLSL_STORAGE_CENTROID 0x00004000 ++#define HLSL_STORAGE_NOPERSPECTIVE 0x00008000 + + #define HLSL_TYPE_MODIFIERS_MASK (HLSL_MODIFIER_PRECISE | HLSL_MODIFIER_VOLATILE | \ + HLSL_MODIFIER_CONST | HLSL_MODIFIER_ROW_MAJOR | \ + HLSL_MODIFIER_COLUMN_MAJOR) + ++#define HLSL_INTERPOLATION_MODIFIERS_MASK (HLSL_STORAGE_NOINTERPOLATION | HLSL_STORAGE_CENTROID | \ ++ HLSL_STORAGE_NOPERSPECTIVE) ++ + #define HLSL_MODIFIERS_MAJORITY_MASK (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR) + + #define HLSL_ARRAY_ELEMENTS_COUNT_IMPLICIT 0 +@@ -577,6 +579,10 @@ enum hlsl_ir_jump_type + HLSL_IR_JUMP_DISCARD_NEG, + HLSL_IR_JUMP_DISCARD_NZ, + HLSL_IR_JUMP_RETURN, ++ /* UNRESOLVED_CONTINUE type is used by the parser when 'continue' statement is found, ++ it never reaches code generation, and is resolved to CONTINUE type once iteration ++ and loop exit logic was properly applied. */ ++ HLSL_IR_JUMP_UNRESOLVED_CONTINUE, + }; + + struct hlsl_ir_jump +@@ -702,6 +708,8 @@ struct hlsl_scope + struct rb_tree types; + /* Scope containing this scope. This value is NULL for the global scope. */ + struct hlsl_scope *upper; ++ /* The scope was created for the loop statement. */ ++ bool loop; + }; + + struct hlsl_profile_info +@@ -1232,13 +1240,12 @@ unsigned int hlsl_type_get_array_element_reg_size(const struct hlsl_type *type, + struct hlsl_type *hlsl_type_get_component_type(struct hlsl_ctx *ctx, struct hlsl_type *type, + unsigned int index); + unsigned int hlsl_type_get_component_offset(struct hlsl_ctx *ctx, struct hlsl_type *type, +- enum hlsl_regset regset, unsigned int index); ++ unsigned int index, enum hlsl_regset *regset); + bool hlsl_type_is_row_major(const struct hlsl_type *type); + unsigned int hlsl_type_minor_size(const struct hlsl_type *type); + unsigned int hlsl_type_major_size(const struct hlsl_type *type); + unsigned int hlsl_type_element_count(const struct hlsl_type *type); + bool hlsl_type_is_resource(const struct hlsl_type *type); +-enum hlsl_regset hlsl_type_get_regset(const struct hlsl_type *type); + unsigned int hlsl_type_get_sm4_offset(const struct hlsl_type *type, unsigned int offset); + bool hlsl_types_are_equal(const struct hlsl_type *t1, const struct hlsl_type *t2); + +@@ -1251,6 +1258,7 @@ unsigned int hlsl_map_swizzle(unsigned int swizzle, unsigned int writemask); + unsigned int hlsl_swizzle_from_writemask(unsigned int writemask); + + struct hlsl_type *hlsl_deref_get_type(struct hlsl_ctx *ctx, const struct hlsl_deref *deref); ++enum hlsl_regset hlsl_deref_get_regset(struct hlsl_ctx *ctx, const struct hlsl_deref *deref); + bool hlsl_component_index_range_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref, + unsigned int *start, unsigned int *count); + bool hlsl_regset_index_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref, +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.l b/libs/vkd3d/libs/vkd3d-shader/hlsl.l +index e9ae3ccf3d3..90abd64a3c6 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.l ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.l +@@ -74,6 +74,7 @@ BlendState {return KW_BLENDSTATE; } + break {return KW_BREAK; } + Buffer {return KW_BUFFER; } + cbuffer {return KW_CBUFFER; } ++centroid {return KW_CENTROID; } + compile {return KW_COMPILE; } + const {return KW_CONST; } + continue {return KW_CONTINUE; } +@@ -95,6 +96,7 @@ inout {return KW_INOUT; } + matrix {return KW_MATRIX; } + namespace {return KW_NAMESPACE; } + nointerpolation {return KW_NOINTERPOLATION; } ++noperspective {return KW_NOPERSPECTIVE; } + out {return KW_OUT; } + packoffset {return KW_PACKOFFSET; } + pass {return KW_PASS; } +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y +index a47246de2be..ba738473ffd 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y +@@ -464,6 +464,50 @@ static bool attribute_list_has_duplicates(const struct parse_attribute_list *att + return false; + } + ++static void resolve_loop_continue(struct hlsl_ctx *ctx, struct hlsl_block *block, enum loop_type type, ++ struct hlsl_block *cond, struct hlsl_block *iter) ++{ ++ struct hlsl_ir_node *instr, *next; ++ ++ LIST_FOR_EACH_ENTRY_SAFE(instr, next, &block->instrs, struct hlsl_ir_node, entry) ++ { ++ if (instr->type == HLSL_IR_IF) ++ { ++ struct hlsl_ir_if *iff = hlsl_ir_if(instr); ++ ++ resolve_loop_continue(ctx, &iff->then_block, type, cond, iter); ++ resolve_loop_continue(ctx, &iff->else_block, type, cond, iter); ++ } ++ else if (instr->type == HLSL_IR_JUMP) ++ { ++ struct hlsl_ir_jump *jump = hlsl_ir_jump(instr); ++ struct hlsl_block block; ++ ++ if (jump->type != HLSL_IR_JUMP_UNRESOLVED_CONTINUE) ++ continue; ++ ++ if (type == LOOP_DO_WHILE) ++ { ++ if (!hlsl_clone_block(ctx, &block, cond)) ++ return; ++ if (!append_conditional_break(ctx, &block)) ++ { ++ hlsl_block_cleanup(&block); ++ return; ++ } ++ list_move_before(&instr->entry, &block.instrs); ++ } ++ else if (type == LOOP_FOR) ++ { ++ if (!hlsl_clone_block(ctx, &block, iter)) ++ return; ++ list_move_before(&instr->entry, &block.instrs); ++ } ++ jump->type = HLSL_IR_JUMP_CONTINUE; ++ } ++ } ++} ++ + static struct hlsl_block *create_loop(struct hlsl_ctx *ctx, enum loop_type type, + const struct parse_attribute_list *attributes, struct hlsl_block *init, struct hlsl_block *cond, + struct hlsl_block *iter, struct hlsl_block *body, const struct vkd3d_shader_location *loc) +@@ -501,6 +545,8 @@ static struct hlsl_block *create_loop(struct hlsl_ctx *ctx, enum loop_type type, + } + } + ++ resolve_loop_continue(ctx, body, type, cond, iter); ++ + if (!init && !(init = make_empty_block(ctx))) + goto oom; + +@@ -2961,6 +3007,33 @@ static bool intrinsic_frac(struct hlsl_ctx *ctx, + return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_FRACT, arg, loc); + } + ++static bool intrinsic_fwidth(struct hlsl_ctx *ctx, ++ const struct parse_initializer *params, const struct vkd3d_shader_location *loc) ++{ ++ struct hlsl_ir_function_decl *func; ++ struct hlsl_type *type; ++ char *body; ++ ++ static const char template[] = ++ "%s fwidth(%s x)\n" ++ "{\n" ++ " return abs(ddx(x)) + abs(ddy(x));\n" ++ "}"; ++ ++ if (!elementwise_intrinsic_float_convert_args(ctx, params, loc)) ++ return false; ++ type = params->args[0]->data_type; ++ ++ if (!(body = hlsl_sprintf_alloc(ctx, template, type->name, type->name))) ++ return false; ++ func = hlsl_compile_internal_function(ctx, "fwidth", body); ++ vkd3d_free(body); ++ if (!func) ++ return false; ++ ++ return add_user_call(ctx, func, params, loc); ++} ++ + static bool intrinsic_ldexp(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) + { +@@ -3690,6 +3763,7 @@ intrinsic_functions[] = + {"floor", 1, true, intrinsic_floor}, + {"fmod", 2, true, intrinsic_fmod}, + {"frac", 1, true, intrinsic_frac}, ++ {"fwidth", 1, true, intrinsic_fwidth}, + {"ldexp", 2, true, intrinsic_ldexp}, + {"length", 1, true, intrinsic_length}, + {"lerp", 3, true, intrinsic_lerp}, +@@ -4559,6 +4633,14 @@ static void validate_texture_format_type(struct hlsl_ctx *ctx, struct hlsl_type + } + } + ++static struct hlsl_scope *get_loop_scope(struct hlsl_scope *scope) ++{ ++ if (scope->loop) ++ return scope; ++ ++ return scope->upper ? get_loop_scope(scope->upper) : NULL; ++} ++ + } + + %locations +@@ -4603,6 +4685,7 @@ static void validate_texture_format_type(struct hlsl_ctx *ctx, struct hlsl_type + %token KW_BREAK + %token KW_BUFFER + %token KW_CBUFFER ++%token KW_CENTROID + %token KW_COLUMN_MAJOR + %token KW_COMPILE + %token KW_CONST +@@ -4625,6 +4708,7 @@ static void validate_texture_format_type(struct hlsl_ctx *ctx, struct hlsl_type + %token KW_MATRIX + %token KW_NAMESPACE + %token KW_NOINTERPOLATION ++%token KW_NOPERSPECTIVE + %token KW_OUT + %token KW_PACKOFFSET + %token KW_PASS +@@ -4967,7 +5051,7 @@ field: + + if (!(type = apply_type_modifiers(ctx, $2, &modifiers, true, &@1))) + YYABORT; +- if (modifiers & ~HLSL_STORAGE_NOINTERPOLATION) ++ if (modifiers & ~HLSL_INTERPOLATION_MODIFIERS_MASK) + { + struct vkd3d_string_buffer *string; + +@@ -5264,6 +5348,13 @@ scope_start: + hlsl_push_scope(ctx); + } + ++loop_scope_start: ++ %empty ++ { ++ hlsl_push_scope(ctx); ++ ctx->cur_scope->loop = true; ++ } ++ + var_identifier: + VAR_IDENTIFIER + | NEW_IDENTIFIER +@@ -5916,6 +6007,14 @@ var_modifiers: + { + $$ = add_modifiers(ctx, $2, HLSL_STORAGE_NOINTERPOLATION, &@1); + } ++ | KW_CENTROID var_modifiers ++ { ++ $$ = add_modifiers(ctx, $2, HLSL_STORAGE_CENTROID, &@1); ++ } ++ | KW_NOPERSPECTIVE var_modifiers ++ { ++ $$ = add_modifiers(ctx, $2, HLSL_STORAGE_NOPERSPECTIVE, &@1); ++ } + | KW_PRECISE var_modifiers + { + $$ = add_modifiers(ctx, $2, HLSL_MODIFIER_PRECISE, &@1); +@@ -6076,7 +6175,43 @@ statement: + | loop_statement + + jump_statement: +- KW_RETURN expr ';' ++ KW_BREAK ';' ++ { ++ struct hlsl_ir_node *jump; ++ ++ /* TODO: allow 'break' in the 'switch' statements. */ ++ ++ if (!get_loop_scope(ctx->cur_scope)) ++ { ++ hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, ++ "The 'break' statement must be used inside of a loop."); ++ } ++ ++ if (!($$ = make_empty_block(ctx))) ++ YYABORT; ++ if (!(jump = hlsl_new_jump(ctx, HLSL_IR_JUMP_BREAK, NULL, &@1))) ++ YYABORT; ++ hlsl_block_add_instr($$, jump); ++ } ++ | KW_CONTINUE ';' ++ { ++ struct hlsl_ir_node *jump; ++ struct hlsl_scope *scope; ++ ++ if (!(scope = get_loop_scope(ctx->cur_scope))) ++ { ++ hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, ++ "The 'continue' statement must be used inside of a loop."); ++ } ++ ++ if (!($$ = make_empty_block(ctx))) ++ YYABORT; ++ ++ if (!(jump = hlsl_new_jump(ctx, HLSL_IR_JUMP_UNRESOLVED_CONTINUE, NULL, &@1))) ++ YYABORT; ++ hlsl_block_add_instr($$, jump); ++ } ++ | KW_RETURN expr ';' + { + $$ = $2; + if (!add_return(ctx, $$, node_from_block($$), &@1)) +@@ -6165,22 +6300,24 @@ if_body: + } + + loop_statement: +- attribute_list_optional KW_WHILE '(' expr ')' statement ++ attribute_list_optional loop_scope_start KW_WHILE '(' expr ')' statement + { +- $$ = create_loop(ctx, LOOP_WHILE, &$1, NULL, $4, NULL, $6, &@2); ++ $$ = create_loop(ctx, LOOP_WHILE, &$1, NULL, $5, NULL, $7, &@3); ++ hlsl_pop_scope(ctx); + } +- | attribute_list_optional KW_DO statement KW_WHILE '(' expr ')' ';' ++ | attribute_list_optional loop_scope_start KW_DO statement KW_WHILE '(' expr ')' ';' + { +- $$ = create_loop(ctx, LOOP_DO_WHILE, &$1, NULL, $6, NULL, $3, &@2); ++ $$ = create_loop(ctx, LOOP_DO_WHILE, &$1, NULL, $7, NULL, $4, &@3); ++ hlsl_pop_scope(ctx); + } +- | attribute_list_optional KW_FOR '(' scope_start expr_statement expr_statement expr_optional ')' statement ++ | attribute_list_optional loop_scope_start KW_FOR '(' expr_statement expr_statement expr_optional ')' statement + { +- $$ = create_loop(ctx, LOOP_FOR, &$1, $5, $6, $7, $9, &@2); ++ $$ = create_loop(ctx, LOOP_FOR, &$1, $5, $6, $7, $9, &@3); + hlsl_pop_scope(ctx); + } +- | attribute_list_optional KW_FOR '(' scope_start declaration expr_statement expr_optional ')' statement ++ | attribute_list_optional loop_scope_start KW_FOR '(' declaration expr_statement expr_optional ')' statement + { +- $$ = create_loop(ctx, LOOP_FOR, &$1, $5, $6, $7, $9, &@2); ++ $$ = create_loop(ctx, LOOP_FOR, &$1, $5, $6, $7, $9, &@3); + hlsl_pop_scope(ctx); + } + +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +index b113696ebb7..5c816e89523 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +@@ -97,7 +97,7 @@ static struct hlsl_ir_node *new_offset_from_path_index(struct hlsl_ctx *ctx, str + static struct hlsl_ir_node *new_offset_instr_from_deref(struct hlsl_ctx *ctx, struct hlsl_block *block, + const struct hlsl_deref *deref, const struct vkd3d_shader_location *loc) + { +- enum hlsl_regset regset = hlsl_type_get_regset(deref->data_type); ++ enum hlsl_regset regset = hlsl_deref_get_regset(ctx, deref); + struct hlsl_ir_node *offset = NULL; + struct hlsl_type *type; + unsigned int i; +@@ -377,6 +377,8 @@ static void prepend_input_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_block * + + for (i = 0; i < hlsl_type_element_count(type); ++i) + { ++ unsigned int element_modifiers = modifiers; ++ + if (type->class == HLSL_CLASS_ARRAY) + { + elem_semantic_index = semantic_index +@@ -391,6 +393,17 @@ static void prepend_input_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_block * + semantic = &field->semantic; + elem_semantic_index = semantic->index; + loc = &field->loc; ++ element_modifiers |= field->storage_modifiers; ++ ++ /* TODO: 'sample' modifier is not supported yet */ ++ ++ /* 'nointerpolation' always takes precedence, next the same is done for 'sample', ++ remaining modifiers are combined. */ ++ if (element_modifiers & HLSL_STORAGE_NOINTERPOLATION) ++ { ++ element_modifiers &= ~HLSL_INTERPOLATION_MODIFIERS_MASK; ++ element_modifiers |= HLSL_STORAGE_NOINTERPOLATION; ++ } + } + + if (!(c = hlsl_new_uint_constant(ctx, i, &var->loc))) +@@ -402,7 +415,7 @@ static void prepend_input_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_block * + return; + list_add_after(&c->entry, &element_load->node.entry); + +- prepend_input_copy_recurse(ctx, block, element_load, modifiers, semantic, elem_semantic_index); ++ prepend_input_copy_recurse(ctx, block, element_load, element_modifiers, semantic, elem_semantic_index); + } + } + else +@@ -2062,6 +2075,25 @@ static bool remove_trivial_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *i + return true; + } + ++static bool remove_trivial_conditional_branches(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) ++{ ++ struct hlsl_ir_constant *condition; ++ struct hlsl_ir_if *iff; ++ ++ if (instr->type != HLSL_IR_IF) ++ return false; ++ iff = hlsl_ir_if(instr); ++ if (iff->condition.node->type != HLSL_IR_CONSTANT) ++ return false; ++ condition = hlsl_ir_constant(iff->condition.node); ++ ++ list_move_before(&instr->entry, condition->value.u[0].u ? &iff->then_block.instrs : &iff->else_block.instrs); ++ list_remove(&instr->entry); ++ hlsl_free_instr(instr); ++ ++ return true; ++} ++ + static bool lower_nonconstant_vector_derefs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) + { + struct hlsl_ir_node *idx; +@@ -2177,7 +2209,7 @@ static bool lower_combined_samples(struct hlsl_ctx *ctx, struct hlsl_ir_node *in + return false; + } + +- assert(hlsl_type_get_regset(load->resource.var->data_type) == HLSL_REGSET_SAMPLERS); ++ assert(hlsl_deref_get_regset(ctx, &load->resource) == HLSL_REGSET_SAMPLERS); + + if (!(name = hlsl_get_string_buffer(ctx))) + return false; +@@ -2968,31 +3000,39 @@ static void allocate_register_reservations(struct hlsl_ctx *ctx) + + LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) + { +- enum hlsl_regset regset; ++ unsigned int r; + + if (!hlsl_type_is_resource(var->data_type)) + continue; +- regset = hlsl_type_get_regset(var->data_type); + +- if (var->reg_reservation.reg_type && var->regs[regset].allocation_size) ++ if (var->reg_reservation.reg_type) + { +- if (var->reg_reservation.reg_type != get_regset_name(regset)) ++ for (r = 0; r <= HLSL_REGSET_LAST_OBJECT; ++r) + { +- struct vkd3d_string_buffer *type_string; +- +- type_string = hlsl_type_to_string(ctx, var->data_type); +- hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION, +- "Object of type '%s' must be bound to register type '%c'.", +- type_string->buffer, get_regset_name(regset)); +- hlsl_release_string_buffer(ctx, type_string); +- } +- else +- { +- var->regs[regset].allocated = true; +- var->regs[regset].id = var->reg_reservation.reg_index; +- TRACE("Allocated reserved %s to %c%u-%c%u.\n", var->name, var->reg_reservation.reg_type, +- var->reg_reservation.reg_index, var->reg_reservation.reg_type, +- var->reg_reservation.reg_index + var->regs[regset].allocation_size); ++ if (var->regs[r].allocation_size > 0) ++ { ++ if (var->reg_reservation.reg_type != get_regset_name(r)) ++ { ++ struct vkd3d_string_buffer *type_string; ++ ++ /* We can throw this error because resources can only span across a single ++ * regset, but we have to check for multiple regsets if we support register ++ * reservations for structs for SM5. */ ++ type_string = hlsl_type_to_string(ctx, var->data_type); ++ hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION, ++ "Object of type '%s' must be bound to register type '%c'.", ++ type_string->buffer, get_regset_name(r)); ++ hlsl_release_string_buffer(ctx, type_string); ++ } ++ else ++ { ++ var->regs[r].allocated = true; ++ var->regs[r].id = var->reg_reservation.reg_index; ++ TRACE("Allocated reserved %s to %c%u-%c%u.\n", var->name, var->reg_reservation.reg_type, ++ var->reg_reservation.reg_index, var->reg_reservation.reg_type, ++ var->reg_reservation.reg_index + var->regs[r].allocation_size); ++ } ++ } + } + } + } +@@ -3331,7 +3371,7 @@ static bool track_object_components_sampler_dim(struct hlsl_ctx *ctx, struct hls + load = hlsl_ir_resource_load(instr); + var = load->resource.var; + +- regset = hlsl_type_get_regset(hlsl_deref_get_type(ctx, &load->resource)); ++ regset = hlsl_deref_get_regset(ctx, &load->resource); + if (!hlsl_regset_index_from_deref(ctx, &load->resource, regset, &index)) + return false; + +@@ -3376,7 +3416,8 @@ static bool track_object_components_usage(struct hlsl_ctx *ctx, struct hlsl_ir_n + load = hlsl_ir_resource_load(instr); + var = load->resource.var; + +- regset = hlsl_type_get_regset(hlsl_deref_get_type(ctx, &load->resource)); ++ regset = hlsl_deref_get_regset(ctx, &load->resource); ++ + if (!hlsl_regset_index_from_deref(ctx, &load->resource, regset, &index)) + return false; + +@@ -4183,7 +4224,7 @@ bool hlsl_offset_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref + return false; + + *offset = hlsl_ir_constant(offset_node)->value.u[0].u; +- regset = hlsl_type_get_regset(deref->data_type); ++ regset = hlsl_deref_get_regset(ctx, deref); + + size = deref->var->data_type->reg_size[regset]; + if (*offset >= size) +@@ -4408,6 +4449,7 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry + progress |= hlsl_copy_propagation_execute(ctx, body); + progress |= hlsl_transform_ir(ctx, fold_swizzle_chains, body, NULL); + progress |= hlsl_transform_ir(ctx, remove_trivial_swizzles, body, NULL); ++ progress |= hlsl_transform_ir(ctx, remove_trivial_conditional_branches, body, NULL); + } + while (progress); + +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c +index cff0ba31efb..64629dc2959 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c +@@ -113,6 +113,32 @@ static int32_t double_to_int(double x) + return x; + } + ++static bool fold_bit_not(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, ++ const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src) ++{ ++ enum hlsl_base_type type = dst_type->base_type; ++ unsigned int k; ++ ++ assert(type == src->node.data_type->base_type); ++ ++ for (k = 0; k < dst_type->dimx; ++k) ++ { ++ switch (type) ++ { ++ case HLSL_TYPE_INT: ++ case HLSL_TYPE_UINT: ++ case HLSL_TYPE_BOOL: ++ dst->u[k].u = ~src->value.u[k].u; ++ break; ++ ++ default: ++ vkd3d_unreachable(); ++ } ++ } ++ ++ return true; ++} ++ + static bool fold_cast(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, + const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src) + { +@@ -334,6 +360,30 @@ static bool fold_neg(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, + return true; + } + ++static bool fold_not(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, ++ const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src) ++{ ++ enum hlsl_base_type type = dst_type->base_type; ++ unsigned int k; ++ ++ assert(type == src->node.data_type->base_type); ++ ++ for (k = 0; k < dst_type->dimx; ++k) ++ { ++ switch (type) ++ { ++ case HLSL_TYPE_BOOL: ++ dst->u[k].u = ~src->value.u[k].u; ++ break; ++ ++ default: ++ FIXME("Fold logic 'not' for type %s.\n", debug_hlsl_type(ctx, dst_type)); ++ return false; ++ } ++ } ++ return true; ++} ++ + static bool fold_rcp(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, + const struct hlsl_ir_constant *src, const struct vkd3d_shader_location *loc) + { +@@ -379,6 +429,46 @@ static bool fold_rcp(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, cons + return true; + } + ++static bool fold_rsq(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, ++ const struct hlsl_ir_constant *src, const struct vkd3d_shader_location *loc) ++{ ++ enum hlsl_base_type type = dst_type->base_type; ++ unsigned int k; ++ ++ assert(type == src->node.data_type->base_type); ++ ++ for (k = 0; k < dst_type->dimx; ++k) ++ { ++ switch (type) ++ { ++ case HLSL_TYPE_FLOAT: ++ case HLSL_TYPE_HALF: ++ if (ctx->profile->major_version >= 4) ++ { ++ if (src->value.u[k].f < 0.0f) ++ hlsl_warning(ctx, loc, VKD3D_SHADER_WARNING_HLSL_IMAGINARY_NUMERIC_RESULT, ++ "Imaginary square root result."); ++ else if (src->value.u[k].f == 0.0f) ++ hlsl_warning(ctx, loc, VKD3D_SHADER_WARNING_HLSL_IMAGINARY_NUMERIC_RESULT, ++ "Floating point division by zero."); ++ } ++ dst->u[k].f = 1.0f / sqrtf(src->value.u[k].f); ++ if (ctx->profile->major_version < 4 && !isfinite(dst->u[k].f)) ++ { ++ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_NON_FINITE_RESULT, ++ "Infinities and NaNs are not allowed by the shader model."); ++ } ++ break; ++ ++ default: ++ FIXME("Fold 'rsq' for type %s.\n", debug_hlsl_type(ctx, dst_type)); ++ return false; ++ } ++ } ++ ++ return true; ++} ++ + static bool fold_sat(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, + const struct hlsl_ir_constant *src) + { +@@ -808,6 +898,36 @@ static bool fold_less(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, con + return true; + } + ++static bool fold_lshift(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, ++ const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2) ++{ ++ unsigned int k; ++ ++ assert(dst_type->base_type == src1->node.data_type->base_type); ++ assert(src2->node.data_type->base_type == HLSL_TYPE_INT); ++ ++ for (k = 0; k < dst_type->dimx; ++k) ++ { ++ unsigned int shift = src2->value.u[k].u % 32; ++ ++ switch (src1->node.data_type->base_type) ++ { ++ case HLSL_TYPE_INT: ++ dst->u[k].i = src1->value.u[k].i << shift; ++ break; ++ ++ case HLSL_TYPE_UINT: ++ dst->u[k].u = src1->value.u[k].u << shift; ++ break; ++ ++ default: ++ vkd3d_unreachable(); ++ } ++ } ++ ++ return true; ++} ++ + static bool fold_max(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, + const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2) + { +@@ -1032,6 +1152,36 @@ static bool fold_ternary(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, + return true; + } + ++static bool fold_rshift(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, ++ const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2) ++{ ++ unsigned int k; ++ ++ assert(dst_type->base_type == src1->node.data_type->base_type); ++ assert(src2->node.data_type->base_type == HLSL_TYPE_INT); ++ ++ for (k = 0; k < dst_type->dimx; ++k) ++ { ++ unsigned int shift = src2->value.u[k].u % 32; ++ ++ switch (src1->node.data_type->base_type) ++ { ++ case HLSL_TYPE_INT: ++ dst->u[k].i = src1->value.u[k].i >> shift; ++ break; ++ ++ case HLSL_TYPE_UINT: ++ dst->u[k].u = src1->value.u[k].u >> shift; ++ break; ++ ++ default: ++ vkd3d_unreachable(); ++ } ++ } ++ ++ return true; ++} ++ + bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) + { + struct hlsl_ir_constant *arg1, *arg2 = NULL, *arg3 = NULL; +@@ -1071,6 +1221,10 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, + success = fold_abs(ctx, &res, instr->data_type, arg1); + break; + ++ case HLSL_OP1_BIT_NOT: ++ success = fold_bit_not(ctx, &res, instr->data_type, arg1); ++ break; ++ + case HLSL_OP1_CAST: + success = fold_cast(ctx, &res, instr->data_type, arg1); + break; +@@ -1091,10 +1245,18 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, + success = fold_neg(ctx, &res, instr->data_type, arg1); + break; + ++ case HLSL_OP1_LOGIC_NOT: ++ success = fold_not(ctx, &res, instr->data_type, arg1); ++ break; ++ + case HLSL_OP1_RCP: + success = fold_rcp(ctx, &res, instr->data_type, arg1, &instr->loc); + break; + ++ case HLSL_OP1_RSQ: ++ success = fold_rsq(ctx, &res, instr->data_type, arg1, &instr->loc); ++ break; ++ + case HLSL_OP1_SAT: + success = fold_sat(ctx, &res, instr->data_type, arg1); + break; +@@ -1141,6 +1303,10 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, + success = fold_less(ctx, &res, instr->data_type, arg1, arg2); + break; + ++ case HLSL_OP2_LSHIFT: ++ success = fold_lshift(ctx, &res, instr->data_type, arg1, arg2); ++ break; ++ + case HLSL_OP2_MAX: + success = fold_max(ctx, &res, instr->data_type, arg1, arg2); + break; +@@ -1161,6 +1327,10 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, + success = fold_nequal(ctx, &res, instr->data_type, arg1, arg2); + break; + ++ case HLSL_OP2_RSHIFT: ++ success = fold_rshift(ctx, &res, instr->data_type, arg1, arg2); ++ break; ++ + case HLSL_OP3_DP2ADD: + success = fold_dp2add(ctx, &res, instr->data_type, arg1, arg2, arg3); + break; +diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c +index a97747b515a..511b0e8faf9 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/ir.c ++++ b/libs/vkd3d/libs/vkd3d-shader/ir.c +@@ -1350,6 +1350,74 @@ static void remove_dead_code(struct vkd3d_shader_parser *parser) + } + } + ++static enum vkd3d_result normalise_combined_samplers(struct vkd3d_shader_parser *parser) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < parser->instructions.count; ++i) ++ { ++ struct vkd3d_shader_instruction *ins = &parser->instructions.elements[i]; ++ struct vkd3d_shader_src_param *srcs; ++ ++ switch (ins->handler_idx) ++ { ++ case VKD3DSIH_TEX: ++ if (!(srcs = shader_src_param_allocator_get(&parser->instructions.src_params, 3))) ++ return VKD3D_ERROR_OUT_OF_MEMORY; ++ memset(srcs, 0, sizeof(*srcs) * 3); ++ ++ ins->handler_idx = VKD3DSIH_SAMPLE; ++ ++ srcs[0] = ins->src[0]; ++ ++ srcs[1].reg.type = VKD3DSPR_RESOURCE; ++ srcs[1].reg.idx[0] = ins->src[1].reg.idx[0]; ++ srcs[1].reg.idx[1] = ins->src[1].reg.idx[0]; ++ srcs[1].reg.idx_count = 2; ++ srcs[1].reg.data_type = VKD3D_DATA_RESOURCE; ++ srcs[1].swizzle = VKD3D_SHADER_NO_SWIZZLE; ++ ++ srcs[2].reg.type = VKD3DSPR_SAMPLER; ++ srcs[2].reg.idx[0] = ins->src[1].reg.idx[0]; ++ srcs[2].reg.idx[1] = ins->src[1].reg.idx[0]; ++ srcs[2].reg.idx_count = 2; ++ srcs[2].reg.data_type = VKD3D_DATA_SAMPLER; ++ ++ ins->src = srcs; ++ ins->src_count = 3; ++ break; ++ ++ case VKD3DSIH_TEXBEM: ++ case VKD3DSIH_TEXBEML: ++ case VKD3DSIH_TEXCOORD: ++ case VKD3DSIH_TEXDEPTH: ++ case VKD3DSIH_TEXDP3: ++ case VKD3DSIH_TEXDP3TEX: ++ case VKD3DSIH_TEXLDD: ++ case VKD3DSIH_TEXLDL: ++ case VKD3DSIH_TEXM3x2PAD: ++ case VKD3DSIH_TEXM3x2TEX: ++ case VKD3DSIH_TEXM3x3DIFF: ++ case VKD3DSIH_TEXM3x3PAD: ++ case VKD3DSIH_TEXM3x3SPEC: ++ case VKD3DSIH_TEXM3x3TEX: ++ case VKD3DSIH_TEXM3x3VSPEC: ++ case VKD3DSIH_TEXREG2AR: ++ case VKD3DSIH_TEXREG2GB: ++ case VKD3DSIH_TEXREG2RGB: ++ vkd3d_shader_parser_error(parser, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, ++ "Aborting due to not yet implemented feature: " ++ "Combined sampler instruction %#x.", ins->handler_idx); ++ return VKD3D_ERROR_NOT_IMPLEMENTED; ++ ++ default: ++ break; ++ } ++ } ++ ++ return VKD3D_OK; ++} ++ + enum vkd3d_result vkd3d_shader_normalise(struct vkd3d_shader_parser *parser, + const struct vkd3d_shader_compile_info *compile_info) + { +@@ -1380,6 +1448,9 @@ enum vkd3d_result vkd3d_shader_normalise(struct vkd3d_shader_parser *parser, + if (result >= 0) + remove_dead_code(parser); + ++ if (result >= 0) ++ result = normalise_combined_samplers(parser); ++ + if (result >= 0 && TRACE_ON()) + vkd3d_shader_trace(instructions, &parser->shader_version); + +diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c +index 07e276c57da..1c8b52e6d37 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/spirv.c ++++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c +@@ -3003,9 +3003,11 @@ static bool spirv_compiler_get_register_name(char *buffer, unsigned int buffer_s + snprintf(buffer, buffer_size, "vicp%u", idx); + break; + case VKD3DSPR_OUTPUT: +- case VKD3DSPR_COLOROUT: + snprintf(buffer, buffer_size, "o%u", idx); + break; ++ case VKD3DSPR_COLOROUT: ++ snprintf(buffer, buffer_size, "oC%u", idx); ++ break; + case VKD3DSPR_DEPTHOUT: + case VKD3DSPR_DEPTHOUTGE: + case VKD3DSPR_DEPTHOUTLE: +@@ -5061,6 +5063,9 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler, + + if (is_patch_constant) + location += shader_signature_next_location(&compiler->output_signature); ++ else if (compiler->shader_type == VKD3D_SHADER_TYPE_PIXEL ++ && signature_element->sysval_semantic == VKD3D_SHADER_SV_TARGET) ++ location = signature_element->semantic_index; + + id = spirv_compiler_emit_array_variable(compiler, &builder->global_stream, + storage_class, component_type, output_component_count, array_sizes, 2); +@@ -5513,13 +5518,14 @@ static void spirv_compiler_emit_push_constant_buffers(struct spirv_compiler *com + + struct_id = vkd3d_spirv_build_op_type_struct(builder, member_ids, count); + vkd3d_spirv_build_op_decorate(builder, struct_id, SpvDecorationBlock, NULL, 0); +- vkd3d_spirv_build_op_name(builder, struct_id, "push_cb"); ++ vkd3d_spirv_build_op_name(builder, struct_id, "push_cb_struct"); + vkd3d_free(member_ids); + + pointer_type_id = vkd3d_spirv_get_op_type_pointer(builder, storage_class, struct_id); + var_id = vkd3d_spirv_build_op_variable(builder, &builder->global_stream, + pointer_type_id, storage_class, 0); + compiler->push_constants_var_id = var_id; ++ vkd3d_spirv_build_op_name(builder, var_id, "push_cb"); + + for (i = 0, j = 0; i < compiler->shader_interface.push_constant_buffer_count; ++i) + { +@@ -5627,8 +5633,10 @@ static void spirv_compiler_emit_cbv_declaration(struct spirv_compiler *compiler, + struct vkd3d_symbol reg_symbol; + unsigned int size; + +- vsir_register_init(®, VKD3DSPR_CONSTBUFFER, VKD3D_DATA_FLOAT, 1); ++ vsir_register_init(®, VKD3DSPR_CONSTBUFFER, VKD3D_DATA_FLOAT, 3); + reg.idx[0].offset = register_id; ++ reg.idx[1].offset = range->first; ++ reg.idx[2].offset = range->last; + + size = size_in_bytes / (VKD3D_VEC4_SIZE * sizeof(uint32_t)); + +diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c +index fbd8458356d..c471d1c586b 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/tpf.c ++++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c +@@ -383,6 +383,8 @@ enum vkd3d_sm4_opcode + VKD3D_SM5_OP_SAMPLE_GRAD_CL_S = 0xe8, + VKD3D_SM5_OP_SAMPLE_C_CL_S = 0xe9, + VKD3D_SM5_OP_CHECK_ACCESS_FULLY_MAPPED = 0xea, ++ ++ VKD3D_SM4_OP_COUNT, + }; + + enum vkd3d_sm4_instruction_modifier +@@ -607,6 +609,7 @@ struct sm4_index_range_array + + struct vkd3d_sm4_lookup_tables + { ++ const struct vkd3d_sm4_opcode_info *opcode_info_from_sm4[VKD3D_SM4_OP_COUNT]; + const struct vkd3d_sm4_register_type_info *register_type_info_from_sm4[VKD3D_SM4_REGISTER_TYPE_COUNT]; + const struct vkd3d_sm4_register_type_info *register_type_info_from_vkd3d[VKD3DSPR_COUNT]; + }; +@@ -615,8 +618,6 @@ struct vkd3d_shader_sm4_parser + { + const uint32_t *start, *end, *ptr; + +- unsigned int output_map[MAX_REG_OUTPUT]; +- + enum vkd3d_shader_opcode phase; + bool has_control_point_phase; + unsigned int input_register_masks[MAX_REG_OUTPUT]; +@@ -1243,287 +1244,6 @@ static void shader_sm5_read_sync(struct vkd3d_shader_instruction *ins, uint32_t + ins->flags = (opcode_token & VKD3D_SM5_SYNC_FLAGS_MASK) >> VKD3D_SM5_SYNC_FLAGS_SHIFT; + } + +-/* +- * d -> VKD3D_DATA_DOUBLE +- * f -> VKD3D_DATA_FLOAT +- * i -> VKD3D_DATA_INT +- * u -> VKD3D_DATA_UINT +- * O -> VKD3D_DATA_OPAQUE +- * R -> VKD3D_DATA_RESOURCE +- * S -> VKD3D_DATA_SAMPLER +- * U -> VKD3D_DATA_UAV +- */ +-static const struct vkd3d_sm4_opcode_info opcode_table[] = +-{ +- {VKD3D_SM4_OP_ADD, VKD3DSIH_ADD, "f", "ff"}, +- {VKD3D_SM4_OP_AND, VKD3DSIH_AND, "u", "uu"}, +- {VKD3D_SM4_OP_BREAK, VKD3DSIH_BREAK, "", ""}, +- {VKD3D_SM4_OP_BREAKC, VKD3DSIH_BREAKP, "", "u", +- shader_sm4_read_conditional_op}, +- {VKD3D_SM4_OP_CASE, VKD3DSIH_CASE, "", "u", +- shader_sm4_read_case_condition}, +- {VKD3D_SM4_OP_CONTINUE, VKD3DSIH_CONTINUE, "", ""}, +- {VKD3D_SM4_OP_CONTINUEC, VKD3DSIH_CONTINUEP, "", "u", +- shader_sm4_read_conditional_op}, +- {VKD3D_SM4_OP_CUT, VKD3DSIH_CUT, "", ""}, +- {VKD3D_SM4_OP_DEFAULT, VKD3DSIH_DEFAULT, "", ""}, +- {VKD3D_SM4_OP_DERIV_RTX, VKD3DSIH_DSX, "f", "f"}, +- {VKD3D_SM4_OP_DERIV_RTY, VKD3DSIH_DSY, "f", "f"}, +- {VKD3D_SM4_OP_DISCARD, VKD3DSIH_DISCARD, "", "u", +- shader_sm4_read_conditional_op}, +- {VKD3D_SM4_OP_DIV, VKD3DSIH_DIV, "f", "ff"}, +- {VKD3D_SM4_OP_DP2, VKD3DSIH_DP2, "f", "ff"}, +- {VKD3D_SM4_OP_DP3, VKD3DSIH_DP3, "f", "ff"}, +- {VKD3D_SM4_OP_DP4, VKD3DSIH_DP4, "f", "ff"}, +- {VKD3D_SM4_OP_ELSE, VKD3DSIH_ELSE, "", ""}, +- {VKD3D_SM4_OP_EMIT, VKD3DSIH_EMIT, "", ""}, +- {VKD3D_SM4_OP_ENDIF, VKD3DSIH_ENDIF, "", ""}, +- {VKD3D_SM4_OP_ENDLOOP, VKD3DSIH_ENDLOOP, "", ""}, +- {VKD3D_SM4_OP_ENDSWITCH, VKD3DSIH_ENDSWITCH, "", ""}, +- {VKD3D_SM4_OP_EQ, VKD3DSIH_EQ, "u", "ff"}, +- {VKD3D_SM4_OP_EXP, VKD3DSIH_EXP, "f", "f"}, +- {VKD3D_SM4_OP_FRC, VKD3DSIH_FRC, "f", "f"}, +- {VKD3D_SM4_OP_FTOI, VKD3DSIH_FTOI, "i", "f"}, +- {VKD3D_SM4_OP_FTOU, VKD3DSIH_FTOU, "u", "f"}, +- {VKD3D_SM4_OP_GE, VKD3DSIH_GE, "u", "ff"}, +- {VKD3D_SM4_OP_IADD, VKD3DSIH_IADD, "i", "ii"}, +- {VKD3D_SM4_OP_IF, VKD3DSIH_IF, "", "u", +- shader_sm4_read_conditional_op}, +- {VKD3D_SM4_OP_IEQ, VKD3DSIH_IEQ, "u", "ii"}, +- {VKD3D_SM4_OP_IGE, VKD3DSIH_IGE, "u", "ii"}, +- {VKD3D_SM4_OP_ILT, VKD3DSIH_ILT, "u", "ii"}, +- {VKD3D_SM4_OP_IMAD, VKD3DSIH_IMAD, "i", "iii"}, +- {VKD3D_SM4_OP_IMAX, VKD3DSIH_IMAX, "i", "ii"}, +- {VKD3D_SM4_OP_IMIN, VKD3DSIH_IMIN, "i", "ii"}, +- {VKD3D_SM4_OP_IMUL, VKD3DSIH_IMUL, "ii", "ii"}, +- {VKD3D_SM4_OP_INE, VKD3DSIH_INE, "u", "ii"}, +- {VKD3D_SM4_OP_INEG, VKD3DSIH_INEG, "i", "i"}, +- {VKD3D_SM4_OP_ISHL, VKD3DSIH_ISHL, "i", "ii"}, +- {VKD3D_SM4_OP_ISHR, VKD3DSIH_ISHR, "i", "ii"}, +- {VKD3D_SM4_OP_ITOF, VKD3DSIH_ITOF, "f", "i"}, +- {VKD3D_SM4_OP_LABEL, VKD3DSIH_LABEL, "", "O"}, +- {VKD3D_SM4_OP_LD, VKD3DSIH_LD, "u", "iR"}, +- {VKD3D_SM4_OP_LD2DMS, VKD3DSIH_LD2DMS, "u", "iRi"}, +- {VKD3D_SM4_OP_LOG, VKD3DSIH_LOG, "f", "f"}, +- {VKD3D_SM4_OP_LOOP, VKD3DSIH_LOOP, "", ""}, +- {VKD3D_SM4_OP_LT, VKD3DSIH_LT, "u", "ff"}, +- {VKD3D_SM4_OP_MAD, VKD3DSIH_MAD, "f", "fff"}, +- {VKD3D_SM4_OP_MIN, VKD3DSIH_MIN, "f", "ff"}, +- {VKD3D_SM4_OP_MAX, VKD3DSIH_MAX, "f", "ff"}, +- {VKD3D_SM4_OP_SHADER_DATA, VKD3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER, "", "", +- shader_sm4_read_shader_data}, +- {VKD3D_SM4_OP_MOV, VKD3DSIH_MOV, "f", "f"}, +- {VKD3D_SM4_OP_MOVC, VKD3DSIH_MOVC, "f", "uff"}, +- {VKD3D_SM4_OP_MUL, VKD3DSIH_MUL, "f", "ff"}, +- {VKD3D_SM4_OP_NE, VKD3DSIH_NE, "u", "ff"}, +- {VKD3D_SM4_OP_NOP, VKD3DSIH_NOP, "", ""}, +- {VKD3D_SM4_OP_NOT, VKD3DSIH_NOT, "u", "u"}, +- {VKD3D_SM4_OP_OR, VKD3DSIH_OR, "u", "uu"}, +- {VKD3D_SM4_OP_RESINFO, VKD3DSIH_RESINFO, "f", "iR"}, +- {VKD3D_SM4_OP_RET, VKD3DSIH_RET, "", ""}, +- {VKD3D_SM4_OP_RETC, VKD3DSIH_RETP, "", "u", +- shader_sm4_read_conditional_op}, +- {VKD3D_SM4_OP_ROUND_NE, VKD3DSIH_ROUND_NE, "f", "f"}, +- {VKD3D_SM4_OP_ROUND_NI, VKD3DSIH_ROUND_NI, "f", "f"}, +- {VKD3D_SM4_OP_ROUND_PI, VKD3DSIH_ROUND_PI, "f", "f"}, +- {VKD3D_SM4_OP_ROUND_Z, VKD3DSIH_ROUND_Z, "f", "f"}, +- {VKD3D_SM4_OP_RSQ, VKD3DSIH_RSQ, "f", "f"}, +- {VKD3D_SM4_OP_SAMPLE, VKD3DSIH_SAMPLE, "u", "fRS"}, +- {VKD3D_SM4_OP_SAMPLE_C, VKD3DSIH_SAMPLE_C, "f", "fRSf"}, +- {VKD3D_SM4_OP_SAMPLE_C_LZ, VKD3DSIH_SAMPLE_C_LZ, "f", "fRSf"}, +- {VKD3D_SM4_OP_SAMPLE_LOD, VKD3DSIH_SAMPLE_LOD, "u", "fRSf"}, +- {VKD3D_SM4_OP_SAMPLE_GRAD, VKD3DSIH_SAMPLE_GRAD, "u", "fRSff"}, +- {VKD3D_SM4_OP_SAMPLE_B, VKD3DSIH_SAMPLE_B, "u", "fRSf"}, +- {VKD3D_SM4_OP_SQRT, VKD3DSIH_SQRT, "f", "f"}, +- {VKD3D_SM4_OP_SWITCH, VKD3DSIH_SWITCH, "", "i"}, +- {VKD3D_SM4_OP_SINCOS, VKD3DSIH_SINCOS, "ff", "f"}, +- {VKD3D_SM4_OP_UDIV, VKD3DSIH_UDIV, "uu", "uu"}, +- {VKD3D_SM4_OP_ULT, VKD3DSIH_ULT, "u", "uu"}, +- {VKD3D_SM4_OP_UGE, VKD3DSIH_UGE, "u", "uu"}, +- {VKD3D_SM4_OP_UMUL, VKD3DSIH_UMUL, "uu", "uu"}, +- {VKD3D_SM4_OP_UMAX, VKD3DSIH_UMAX, "u", "uu"}, +- {VKD3D_SM4_OP_UMIN, VKD3DSIH_UMIN, "u", "uu"}, +- {VKD3D_SM4_OP_USHR, VKD3DSIH_USHR, "u", "uu"}, +- {VKD3D_SM4_OP_UTOF, VKD3DSIH_UTOF, "f", "u"}, +- {VKD3D_SM4_OP_XOR, VKD3DSIH_XOR, "u", "uu"}, +- {VKD3D_SM4_OP_DCL_RESOURCE, VKD3DSIH_DCL, "", "", +- shader_sm4_read_dcl_resource}, +- {VKD3D_SM4_OP_DCL_CONSTANT_BUFFER, VKD3DSIH_DCL_CONSTANT_BUFFER, "", "", +- shader_sm4_read_dcl_constant_buffer}, +- {VKD3D_SM4_OP_DCL_SAMPLER, VKD3DSIH_DCL_SAMPLER, "", "", +- shader_sm4_read_dcl_sampler}, +- {VKD3D_SM4_OP_DCL_INDEX_RANGE, VKD3DSIH_DCL_INDEX_RANGE, "", "", +- shader_sm4_read_dcl_index_range}, +- {VKD3D_SM4_OP_DCL_OUTPUT_TOPOLOGY, VKD3DSIH_DCL_OUTPUT_TOPOLOGY, "", "", +- shader_sm4_read_dcl_output_topology}, +- {VKD3D_SM4_OP_DCL_INPUT_PRIMITIVE, VKD3DSIH_DCL_INPUT_PRIMITIVE, "", "", +- shader_sm4_read_dcl_input_primitive}, +- {VKD3D_SM4_OP_DCL_VERTICES_OUT, VKD3DSIH_DCL_VERTICES_OUT, "", "", +- shader_sm4_read_declaration_count}, +- {VKD3D_SM4_OP_DCL_INPUT, VKD3DSIH_DCL_INPUT, "", "", +- shader_sm4_read_declaration_dst}, +- {VKD3D_SM4_OP_DCL_INPUT_SGV, VKD3DSIH_DCL_INPUT_SGV, "", "", +- shader_sm4_read_declaration_register_semantic}, +- {VKD3D_SM4_OP_DCL_INPUT_SIV, VKD3DSIH_DCL_INPUT_SIV, "", "", +- shader_sm4_read_declaration_register_semantic}, +- {VKD3D_SM4_OP_DCL_INPUT_PS, VKD3DSIH_DCL_INPUT_PS, "", "", +- shader_sm4_read_dcl_input_ps}, +- {VKD3D_SM4_OP_DCL_INPUT_PS_SGV, VKD3DSIH_DCL_INPUT_PS_SGV, "", "", +- shader_sm4_read_declaration_register_semantic}, +- {VKD3D_SM4_OP_DCL_INPUT_PS_SIV, VKD3DSIH_DCL_INPUT_PS_SIV, "", "", +- shader_sm4_read_dcl_input_ps_siv}, +- {VKD3D_SM4_OP_DCL_OUTPUT, VKD3DSIH_DCL_OUTPUT, "", "", +- shader_sm4_read_declaration_dst}, +- {VKD3D_SM4_OP_DCL_OUTPUT_SIV, VKD3DSIH_DCL_OUTPUT_SIV, "", "", +- shader_sm4_read_declaration_register_semantic}, +- {VKD3D_SM4_OP_DCL_TEMPS, VKD3DSIH_DCL_TEMPS, "", "", +- shader_sm4_read_declaration_count}, +- {VKD3D_SM4_OP_DCL_INDEXABLE_TEMP, VKD3DSIH_DCL_INDEXABLE_TEMP, "", "", +- shader_sm4_read_dcl_indexable_temp}, +- {VKD3D_SM4_OP_DCL_GLOBAL_FLAGS, VKD3DSIH_DCL_GLOBAL_FLAGS, "", "", +- shader_sm4_read_dcl_global_flags}, +- {VKD3D_SM4_OP_LOD, VKD3DSIH_LOD, "f", "fRS"}, +- {VKD3D_SM4_OP_GATHER4, VKD3DSIH_GATHER4, "u", "fRS"}, +- {VKD3D_SM4_OP_SAMPLE_POS, VKD3DSIH_SAMPLE_POS, "f", "Ru"}, +- {VKD3D_SM4_OP_SAMPLE_INFO, VKD3DSIH_SAMPLE_INFO, "f", "R"}, +- {VKD3D_SM5_OP_HS_DECLS, VKD3DSIH_HS_DECLS, "", ""}, +- {VKD3D_SM5_OP_HS_CONTROL_POINT_PHASE, VKD3DSIH_HS_CONTROL_POINT_PHASE, "", ""}, +- {VKD3D_SM5_OP_HS_FORK_PHASE, VKD3DSIH_HS_FORK_PHASE, "", ""}, +- {VKD3D_SM5_OP_HS_JOIN_PHASE, VKD3DSIH_HS_JOIN_PHASE, "", ""}, +- {VKD3D_SM5_OP_EMIT_STREAM, VKD3DSIH_EMIT_STREAM, "", "f"}, +- {VKD3D_SM5_OP_CUT_STREAM, VKD3DSIH_CUT_STREAM, "", "f"}, +- {VKD3D_SM5_OP_FCALL, VKD3DSIH_FCALL, "", "O", +- shader_sm5_read_fcall}, +- {VKD3D_SM5_OP_BUFINFO, VKD3DSIH_BUFINFO, "i", "U"}, +- {VKD3D_SM5_OP_DERIV_RTX_COARSE, VKD3DSIH_DSX_COARSE, "f", "f"}, +- {VKD3D_SM5_OP_DERIV_RTX_FINE, VKD3DSIH_DSX_FINE, "f", "f"}, +- {VKD3D_SM5_OP_DERIV_RTY_COARSE, VKD3DSIH_DSY_COARSE, "f", "f"}, +- {VKD3D_SM5_OP_DERIV_RTY_FINE, VKD3DSIH_DSY_FINE, "f", "f"}, +- {VKD3D_SM5_OP_GATHER4_C, VKD3DSIH_GATHER4_C, "f", "fRSf"}, +- {VKD3D_SM5_OP_GATHER4_PO, VKD3DSIH_GATHER4_PO, "f", "fiRS"}, +- {VKD3D_SM5_OP_GATHER4_PO_C, VKD3DSIH_GATHER4_PO_C, "f", "fiRSf"}, +- {VKD3D_SM5_OP_RCP, VKD3DSIH_RCP, "f", "f"}, +- {VKD3D_SM5_OP_F32TOF16, VKD3DSIH_F32TOF16, "u", "f"}, +- {VKD3D_SM5_OP_F16TOF32, VKD3DSIH_F16TOF32, "f", "u"}, +- {VKD3D_SM5_OP_COUNTBITS, VKD3DSIH_COUNTBITS, "u", "u"}, +- {VKD3D_SM5_OP_FIRSTBIT_HI, VKD3DSIH_FIRSTBIT_HI, "u", "u"}, +- {VKD3D_SM5_OP_FIRSTBIT_LO, VKD3DSIH_FIRSTBIT_LO, "u", "u"}, +- {VKD3D_SM5_OP_FIRSTBIT_SHI, VKD3DSIH_FIRSTBIT_SHI, "u", "i"}, +- {VKD3D_SM5_OP_UBFE, VKD3DSIH_UBFE, "u", "iiu"}, +- {VKD3D_SM5_OP_IBFE, VKD3DSIH_IBFE, "i", "iii"}, +- {VKD3D_SM5_OP_BFI, VKD3DSIH_BFI, "u", "iiuu"}, +- {VKD3D_SM5_OP_BFREV, VKD3DSIH_BFREV, "u", "u"}, +- {VKD3D_SM5_OP_SWAPC, VKD3DSIH_SWAPC, "ff", "uff"}, +- {VKD3D_SM5_OP_DCL_STREAM, VKD3DSIH_DCL_STREAM, "", "O"}, +- {VKD3D_SM5_OP_DCL_FUNCTION_BODY, VKD3DSIH_DCL_FUNCTION_BODY, "", "", +- shader_sm5_read_dcl_function_body}, +- {VKD3D_SM5_OP_DCL_FUNCTION_TABLE, VKD3DSIH_DCL_FUNCTION_TABLE, "", "", +- shader_sm5_read_dcl_function_table}, +- {VKD3D_SM5_OP_DCL_INTERFACE, VKD3DSIH_DCL_INTERFACE, "", "", +- shader_sm5_read_dcl_interface}, +- {VKD3D_SM5_OP_DCL_INPUT_CONTROL_POINT_COUNT, VKD3DSIH_DCL_INPUT_CONTROL_POINT_COUNT, "", "", +- shader_sm5_read_control_point_count}, +- {VKD3D_SM5_OP_DCL_OUTPUT_CONTROL_POINT_COUNT, VKD3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT, "", "", +- shader_sm5_read_control_point_count}, +- {VKD3D_SM5_OP_DCL_TESSELLATOR_DOMAIN, VKD3DSIH_DCL_TESSELLATOR_DOMAIN, "", "", +- shader_sm5_read_dcl_tessellator_domain}, +- {VKD3D_SM5_OP_DCL_TESSELLATOR_PARTITIONING, VKD3DSIH_DCL_TESSELLATOR_PARTITIONING, "", "", +- shader_sm5_read_dcl_tessellator_partitioning}, +- {VKD3D_SM5_OP_DCL_TESSELLATOR_OUTPUT_PRIMITIVE, VKD3DSIH_DCL_TESSELLATOR_OUTPUT_PRIMITIVE, "", "", +- shader_sm5_read_dcl_tessellator_output_primitive}, +- {VKD3D_SM5_OP_DCL_HS_MAX_TESSFACTOR, VKD3DSIH_DCL_HS_MAX_TESSFACTOR, "", "", +- shader_sm5_read_dcl_hs_max_tessfactor}, +- {VKD3D_SM5_OP_DCL_HS_FORK_PHASE_INSTANCE_COUNT, VKD3DSIH_DCL_HS_FORK_PHASE_INSTANCE_COUNT, "", "", +- shader_sm4_read_declaration_count}, +- {VKD3D_SM5_OP_DCL_HS_JOIN_PHASE_INSTANCE_COUNT, VKD3DSIH_DCL_HS_JOIN_PHASE_INSTANCE_COUNT, "", "", +- shader_sm4_read_declaration_count}, +- {VKD3D_SM5_OP_DCL_THREAD_GROUP, VKD3DSIH_DCL_THREAD_GROUP, "", "", +- shader_sm5_read_dcl_thread_group}, +- {VKD3D_SM5_OP_DCL_UAV_TYPED, VKD3DSIH_DCL_UAV_TYPED, "", "", +- shader_sm4_read_dcl_resource}, +- {VKD3D_SM5_OP_DCL_UAV_RAW, VKD3DSIH_DCL_UAV_RAW, "", "", +- shader_sm5_read_dcl_uav_raw}, +- {VKD3D_SM5_OP_DCL_UAV_STRUCTURED, VKD3DSIH_DCL_UAV_STRUCTURED, "", "", +- shader_sm5_read_dcl_uav_structured}, +- {VKD3D_SM5_OP_DCL_TGSM_RAW, VKD3DSIH_DCL_TGSM_RAW, "", "", +- shader_sm5_read_dcl_tgsm_raw}, +- {VKD3D_SM5_OP_DCL_TGSM_STRUCTURED, VKD3DSIH_DCL_TGSM_STRUCTURED, "", "", +- shader_sm5_read_dcl_tgsm_structured}, +- {VKD3D_SM5_OP_DCL_RESOURCE_RAW, VKD3DSIH_DCL_RESOURCE_RAW, "", "", +- shader_sm5_read_dcl_resource_raw}, +- {VKD3D_SM5_OP_DCL_RESOURCE_STRUCTURED, VKD3DSIH_DCL_RESOURCE_STRUCTURED, "", "", +- shader_sm5_read_dcl_resource_structured}, +- {VKD3D_SM5_OP_LD_UAV_TYPED, VKD3DSIH_LD_UAV_TYPED, "u", "iU"}, +- {VKD3D_SM5_OP_STORE_UAV_TYPED, VKD3DSIH_STORE_UAV_TYPED, "U", "iu"}, +- {VKD3D_SM5_OP_LD_RAW, VKD3DSIH_LD_RAW, "u", "iU"}, +- {VKD3D_SM5_OP_STORE_RAW, VKD3DSIH_STORE_RAW, "U", "uu"}, +- {VKD3D_SM5_OP_LD_STRUCTURED, VKD3DSIH_LD_STRUCTURED, "u", "iiR"}, +- {VKD3D_SM5_OP_STORE_STRUCTURED, VKD3DSIH_STORE_STRUCTURED, "U", "iiu"}, +- {VKD3D_SM5_OP_ATOMIC_AND, VKD3DSIH_ATOMIC_AND, "U", "iu"}, +- {VKD3D_SM5_OP_ATOMIC_OR, VKD3DSIH_ATOMIC_OR, "U", "iu"}, +- {VKD3D_SM5_OP_ATOMIC_XOR, VKD3DSIH_ATOMIC_XOR, "U", "iu"}, +- {VKD3D_SM5_OP_ATOMIC_CMP_STORE, VKD3DSIH_ATOMIC_CMP_STORE, "U", "iuu"}, +- {VKD3D_SM5_OP_ATOMIC_IADD, VKD3DSIH_ATOMIC_IADD, "U", "ii"}, +- {VKD3D_SM5_OP_ATOMIC_IMAX, VKD3DSIH_ATOMIC_IMAX, "U", "ii"}, +- {VKD3D_SM5_OP_ATOMIC_IMIN, VKD3DSIH_ATOMIC_IMIN, "U", "ii"}, +- {VKD3D_SM5_OP_ATOMIC_UMAX, VKD3DSIH_ATOMIC_UMAX, "U", "iu"}, +- {VKD3D_SM5_OP_ATOMIC_UMIN, VKD3DSIH_ATOMIC_UMIN, "U", "iu"}, +- {VKD3D_SM5_OP_IMM_ATOMIC_ALLOC, VKD3DSIH_IMM_ATOMIC_ALLOC, "u", "U"}, +- {VKD3D_SM5_OP_IMM_ATOMIC_CONSUME, VKD3DSIH_IMM_ATOMIC_CONSUME, "u", "U"}, +- {VKD3D_SM5_OP_IMM_ATOMIC_IADD, VKD3DSIH_IMM_ATOMIC_IADD, "uU", "ii"}, +- {VKD3D_SM5_OP_IMM_ATOMIC_AND, VKD3DSIH_IMM_ATOMIC_AND, "uU", "iu"}, +- {VKD3D_SM5_OP_IMM_ATOMIC_OR, VKD3DSIH_IMM_ATOMIC_OR, "uU", "iu"}, +- {VKD3D_SM5_OP_IMM_ATOMIC_XOR, VKD3DSIH_IMM_ATOMIC_XOR, "uU", "iu"}, +- {VKD3D_SM5_OP_IMM_ATOMIC_EXCH, VKD3DSIH_IMM_ATOMIC_EXCH, "uU", "iu"}, +- {VKD3D_SM5_OP_IMM_ATOMIC_CMP_EXCH, VKD3DSIH_IMM_ATOMIC_CMP_EXCH, "uU", "iuu"}, +- {VKD3D_SM5_OP_IMM_ATOMIC_IMAX, VKD3DSIH_IMM_ATOMIC_IMAX, "iU", "ii"}, +- {VKD3D_SM5_OP_IMM_ATOMIC_IMIN, VKD3DSIH_IMM_ATOMIC_IMIN, "iU", "ii"}, +- {VKD3D_SM5_OP_IMM_ATOMIC_UMAX, VKD3DSIH_IMM_ATOMIC_UMAX, "uU", "iu"}, +- {VKD3D_SM5_OP_IMM_ATOMIC_UMIN, VKD3DSIH_IMM_ATOMIC_UMIN, "uU", "iu"}, +- {VKD3D_SM5_OP_SYNC, VKD3DSIH_SYNC, "", "", +- shader_sm5_read_sync}, +- {VKD3D_SM5_OP_DADD, VKD3DSIH_DADD, "d", "dd"}, +- {VKD3D_SM5_OP_DMAX, VKD3DSIH_DMAX, "d", "dd"}, +- {VKD3D_SM5_OP_DMIN, VKD3DSIH_DMIN, "d", "dd"}, +- {VKD3D_SM5_OP_DMUL, VKD3DSIH_DMUL, "d", "dd"}, +- {VKD3D_SM5_OP_DEQ, VKD3DSIH_DEQ, "u", "dd"}, +- {VKD3D_SM5_OP_DGE, VKD3DSIH_DGE, "u", "dd"}, +- {VKD3D_SM5_OP_DLT, VKD3DSIH_DLT, "u", "dd"}, +- {VKD3D_SM5_OP_DNE, VKD3DSIH_DNE, "u", "dd"}, +- {VKD3D_SM5_OP_DMOV, VKD3DSIH_DMOV, "d", "d"}, +- {VKD3D_SM5_OP_DMOVC, VKD3DSIH_DMOVC, "d", "udd"}, +- {VKD3D_SM5_OP_DTOF, VKD3DSIH_DTOF, "f", "d"}, +- {VKD3D_SM5_OP_FTOD, VKD3DSIH_FTOD, "d", "f"}, +- {VKD3D_SM5_OP_EVAL_SAMPLE_INDEX, VKD3DSIH_EVAL_SAMPLE_INDEX, "f", "fi"}, +- {VKD3D_SM5_OP_EVAL_CENTROID, VKD3DSIH_EVAL_CENTROID, "f", "f"}, +- {VKD3D_SM5_OP_DCL_GS_INSTANCES, VKD3DSIH_DCL_GS_INSTANCES, "", "", +- shader_sm4_read_declaration_count}, +- {VKD3D_SM5_OP_DDIV, VKD3DSIH_DDIV, "d", "dd"}, +- {VKD3D_SM5_OP_DFMA, VKD3DSIH_DFMA, "d", "ddd"}, +- {VKD3D_SM5_OP_DRCP, VKD3DSIH_DRCP, "d", "d"}, +- {VKD3D_SM5_OP_MSAD, VKD3DSIH_MSAD, "u", "uuu"}, +- {VKD3D_SM5_OP_DTOI, VKD3DSIH_DTOI, "i", "d"}, +- {VKD3D_SM5_OP_DTOU, VKD3DSIH_DTOU, "u", "d"}, +- {VKD3D_SM5_OP_ITOD, VKD3DSIH_ITOD, "d", "i"}, +- {VKD3D_SM5_OP_UTOD, VKD3DSIH_UTOD, "d", "u"}, +- {VKD3D_SM5_OP_GATHER4_S, VKD3DSIH_GATHER4_S, "uu", "fRS"}, +- {VKD3D_SM5_OP_GATHER4_C_S, VKD3DSIH_GATHER4_C_S, "fu", "fRSf"}, +- {VKD3D_SM5_OP_GATHER4_PO_S, VKD3DSIH_GATHER4_PO_S, "fu", "fiRS"}, +- {VKD3D_SM5_OP_GATHER4_PO_C_S, VKD3DSIH_GATHER4_PO_C_S, "fu", "fiRSf"}, +- {VKD3D_SM5_OP_LD_S, VKD3DSIH_LD_S, "uu", "iR"}, +- {VKD3D_SM5_OP_LD2DMS_S, VKD3DSIH_LD2DMS_S, "uu", "iRi"}, +- {VKD3D_SM5_OP_LD_UAV_TYPED_S, VKD3DSIH_LD_UAV_TYPED_S, "uu", "iU"}, +- {VKD3D_SM5_OP_LD_RAW_S, VKD3DSIH_LD_RAW_S, "uu", "iU"}, +- {VKD3D_SM5_OP_LD_STRUCTURED_S, VKD3DSIH_LD_STRUCTURED_S, "uu", "iiR"}, +- {VKD3D_SM5_OP_SAMPLE_LOD_S, VKD3DSIH_SAMPLE_LOD_S, "uu", "fRSf"}, +- {VKD3D_SM5_OP_SAMPLE_C_LZ_S, VKD3DSIH_SAMPLE_C_LZ_S, "fu", "fRSf"}, +- {VKD3D_SM5_OP_SAMPLE_CL_S, VKD3DSIH_SAMPLE_CL_S, "uu", "fRSf"}, +- {VKD3D_SM5_OP_SAMPLE_B_CL_S, VKD3DSIH_SAMPLE_B_CL_S, "uu", "fRSff"}, +- {VKD3D_SM5_OP_SAMPLE_GRAD_CL_S, VKD3DSIH_SAMPLE_GRAD_CL_S, "uu", "fRSfff"}, +- {VKD3D_SM5_OP_SAMPLE_C_CL_S, VKD3DSIH_SAMPLE_C_CL_S, "fu", "fRSff"}, +- {VKD3D_SM5_OP_CHECK_ACCESS_FULLY_MAPPED, VKD3DSIH_CHECK_ACCESS_FULLY_MAPPED, "u", "u"}, +-}; +- + struct vkd3d_sm4_register_type_info + { + enum vkd3d_sm4_register_type sm4_type; +@@ -1550,24 +1270,291 @@ struct tpf_writer + struct vkd3d_sm4_lookup_tables lookup; + }; + +-static const struct vkd3d_sm4_opcode_info *get_opcode_info(enum vkd3d_sm4_opcode opcode) +-{ +- unsigned int i; +- +- for (i = 0; i < sizeof(opcode_table) / sizeof(*opcode_table); ++i) +- { +- if (opcode == opcode_table[i].opcode) +- return &opcode_table[i]; +- } +- +- return NULL; +-} +- + static void init_sm4_lookup_tables(struct vkd3d_sm4_lookup_tables *lookup) + { +- const struct vkd3d_sm4_register_type_info *info; + unsigned int i; + ++ /* ++ * d -> VKD3D_DATA_DOUBLE ++ * f -> VKD3D_DATA_FLOAT ++ * i -> VKD3D_DATA_INT ++ * u -> VKD3D_DATA_UINT ++ * O -> VKD3D_DATA_OPAQUE ++ * R -> VKD3D_DATA_RESOURCE ++ * S -> VKD3D_DATA_SAMPLER ++ * U -> VKD3D_DATA_UAV ++ */ ++ static const struct vkd3d_sm4_opcode_info opcode_table[] = ++ { ++ {VKD3D_SM4_OP_ADD, VKD3DSIH_ADD, "f", "ff"}, ++ {VKD3D_SM4_OP_AND, VKD3DSIH_AND, "u", "uu"}, ++ {VKD3D_SM4_OP_BREAK, VKD3DSIH_BREAK, "", ""}, ++ {VKD3D_SM4_OP_BREAKC, VKD3DSIH_BREAKP, "", "u", ++ shader_sm4_read_conditional_op}, ++ {VKD3D_SM4_OP_CASE, VKD3DSIH_CASE, "", "u", ++ shader_sm4_read_case_condition}, ++ {VKD3D_SM4_OP_CONTINUE, VKD3DSIH_CONTINUE, "", ""}, ++ {VKD3D_SM4_OP_CONTINUEC, VKD3DSIH_CONTINUEP, "", "u", ++ shader_sm4_read_conditional_op}, ++ {VKD3D_SM4_OP_CUT, VKD3DSIH_CUT, "", ""}, ++ {VKD3D_SM4_OP_DEFAULT, VKD3DSIH_DEFAULT, "", ""}, ++ {VKD3D_SM4_OP_DERIV_RTX, VKD3DSIH_DSX, "f", "f"}, ++ {VKD3D_SM4_OP_DERIV_RTY, VKD3DSIH_DSY, "f", "f"}, ++ {VKD3D_SM4_OP_DISCARD, VKD3DSIH_DISCARD, "", "u", ++ shader_sm4_read_conditional_op}, ++ {VKD3D_SM4_OP_DIV, VKD3DSIH_DIV, "f", "ff"}, ++ {VKD3D_SM4_OP_DP2, VKD3DSIH_DP2, "f", "ff"}, ++ {VKD3D_SM4_OP_DP3, VKD3DSIH_DP3, "f", "ff"}, ++ {VKD3D_SM4_OP_DP4, VKD3DSIH_DP4, "f", "ff"}, ++ {VKD3D_SM4_OP_ELSE, VKD3DSIH_ELSE, "", ""}, ++ {VKD3D_SM4_OP_EMIT, VKD3DSIH_EMIT, "", ""}, ++ {VKD3D_SM4_OP_ENDIF, VKD3DSIH_ENDIF, "", ""}, ++ {VKD3D_SM4_OP_ENDLOOP, VKD3DSIH_ENDLOOP, "", ""}, ++ {VKD3D_SM4_OP_ENDSWITCH, VKD3DSIH_ENDSWITCH, "", ""}, ++ {VKD3D_SM4_OP_EQ, VKD3DSIH_EQ, "u", "ff"}, ++ {VKD3D_SM4_OP_EXP, VKD3DSIH_EXP, "f", "f"}, ++ {VKD3D_SM4_OP_FRC, VKD3DSIH_FRC, "f", "f"}, ++ {VKD3D_SM4_OP_FTOI, VKD3DSIH_FTOI, "i", "f"}, ++ {VKD3D_SM4_OP_FTOU, VKD3DSIH_FTOU, "u", "f"}, ++ {VKD3D_SM4_OP_GE, VKD3DSIH_GE, "u", "ff"}, ++ {VKD3D_SM4_OP_IADD, VKD3DSIH_IADD, "i", "ii"}, ++ {VKD3D_SM4_OP_IF, VKD3DSIH_IF, "", "u", ++ shader_sm4_read_conditional_op}, ++ {VKD3D_SM4_OP_IEQ, VKD3DSIH_IEQ, "u", "ii"}, ++ {VKD3D_SM4_OP_IGE, VKD3DSIH_IGE, "u", "ii"}, ++ {VKD3D_SM4_OP_ILT, VKD3DSIH_ILT, "u", "ii"}, ++ {VKD3D_SM4_OP_IMAD, VKD3DSIH_IMAD, "i", "iii"}, ++ {VKD3D_SM4_OP_IMAX, VKD3DSIH_IMAX, "i", "ii"}, ++ {VKD3D_SM4_OP_IMIN, VKD3DSIH_IMIN, "i", "ii"}, ++ {VKD3D_SM4_OP_IMUL, VKD3DSIH_IMUL, "ii", "ii"}, ++ {VKD3D_SM4_OP_INE, VKD3DSIH_INE, "u", "ii"}, ++ {VKD3D_SM4_OP_INEG, VKD3DSIH_INEG, "i", "i"}, ++ {VKD3D_SM4_OP_ISHL, VKD3DSIH_ISHL, "i", "ii"}, ++ {VKD3D_SM4_OP_ISHR, VKD3DSIH_ISHR, "i", "ii"}, ++ {VKD3D_SM4_OP_ITOF, VKD3DSIH_ITOF, "f", "i"}, ++ {VKD3D_SM4_OP_LABEL, VKD3DSIH_LABEL, "", "O"}, ++ {VKD3D_SM4_OP_LD, VKD3DSIH_LD, "u", "iR"}, ++ {VKD3D_SM4_OP_LD2DMS, VKD3DSIH_LD2DMS, "u", "iRi"}, ++ {VKD3D_SM4_OP_LOG, VKD3DSIH_LOG, "f", "f"}, ++ {VKD3D_SM4_OP_LOOP, VKD3DSIH_LOOP, "", ""}, ++ {VKD3D_SM4_OP_LT, VKD3DSIH_LT, "u", "ff"}, ++ {VKD3D_SM4_OP_MAD, VKD3DSIH_MAD, "f", "fff"}, ++ {VKD3D_SM4_OP_MIN, VKD3DSIH_MIN, "f", "ff"}, ++ {VKD3D_SM4_OP_MAX, VKD3DSIH_MAX, "f", "ff"}, ++ {VKD3D_SM4_OP_SHADER_DATA, VKD3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER, "", "", ++ shader_sm4_read_shader_data}, ++ {VKD3D_SM4_OP_MOV, VKD3DSIH_MOV, "f", "f"}, ++ {VKD3D_SM4_OP_MOVC, VKD3DSIH_MOVC, "f", "uff"}, ++ {VKD3D_SM4_OP_MUL, VKD3DSIH_MUL, "f", "ff"}, ++ {VKD3D_SM4_OP_NE, VKD3DSIH_NE, "u", "ff"}, ++ {VKD3D_SM4_OP_NOP, VKD3DSIH_NOP, "", ""}, ++ {VKD3D_SM4_OP_NOT, VKD3DSIH_NOT, "u", "u"}, ++ {VKD3D_SM4_OP_OR, VKD3DSIH_OR, "u", "uu"}, ++ {VKD3D_SM4_OP_RESINFO, VKD3DSIH_RESINFO, "f", "iR"}, ++ {VKD3D_SM4_OP_RET, VKD3DSIH_RET, "", ""}, ++ {VKD3D_SM4_OP_RETC, VKD3DSIH_RETP, "", "u", ++ shader_sm4_read_conditional_op}, ++ {VKD3D_SM4_OP_ROUND_NE, VKD3DSIH_ROUND_NE, "f", "f"}, ++ {VKD3D_SM4_OP_ROUND_NI, VKD3DSIH_ROUND_NI, "f", "f"}, ++ {VKD3D_SM4_OP_ROUND_PI, VKD3DSIH_ROUND_PI, "f", "f"}, ++ {VKD3D_SM4_OP_ROUND_Z, VKD3DSIH_ROUND_Z, "f", "f"}, ++ {VKD3D_SM4_OP_RSQ, VKD3DSIH_RSQ, "f", "f"}, ++ {VKD3D_SM4_OP_SAMPLE, VKD3DSIH_SAMPLE, "u", "fRS"}, ++ {VKD3D_SM4_OP_SAMPLE_C, VKD3DSIH_SAMPLE_C, "f", "fRSf"}, ++ {VKD3D_SM4_OP_SAMPLE_C_LZ, VKD3DSIH_SAMPLE_C_LZ, "f", "fRSf"}, ++ {VKD3D_SM4_OP_SAMPLE_LOD, VKD3DSIH_SAMPLE_LOD, "u", "fRSf"}, ++ {VKD3D_SM4_OP_SAMPLE_GRAD, VKD3DSIH_SAMPLE_GRAD, "u", "fRSff"}, ++ {VKD3D_SM4_OP_SAMPLE_B, VKD3DSIH_SAMPLE_B, "u", "fRSf"}, ++ {VKD3D_SM4_OP_SQRT, VKD3DSIH_SQRT, "f", "f"}, ++ {VKD3D_SM4_OP_SWITCH, VKD3DSIH_SWITCH, "", "i"}, ++ {VKD3D_SM4_OP_SINCOS, VKD3DSIH_SINCOS, "ff", "f"}, ++ {VKD3D_SM4_OP_UDIV, VKD3DSIH_UDIV, "uu", "uu"}, ++ {VKD3D_SM4_OP_ULT, VKD3DSIH_ULT, "u", "uu"}, ++ {VKD3D_SM4_OP_UGE, VKD3DSIH_UGE, "u", "uu"}, ++ {VKD3D_SM4_OP_UMUL, VKD3DSIH_UMUL, "uu", "uu"}, ++ {VKD3D_SM4_OP_UMAX, VKD3DSIH_UMAX, "u", "uu"}, ++ {VKD3D_SM4_OP_UMIN, VKD3DSIH_UMIN, "u", "uu"}, ++ {VKD3D_SM4_OP_USHR, VKD3DSIH_USHR, "u", "uu"}, ++ {VKD3D_SM4_OP_UTOF, VKD3DSIH_UTOF, "f", "u"}, ++ {VKD3D_SM4_OP_XOR, VKD3DSIH_XOR, "u", "uu"}, ++ {VKD3D_SM4_OP_DCL_RESOURCE, VKD3DSIH_DCL, "", "", ++ shader_sm4_read_dcl_resource}, ++ {VKD3D_SM4_OP_DCL_CONSTANT_BUFFER, VKD3DSIH_DCL_CONSTANT_BUFFER, "", "", ++ shader_sm4_read_dcl_constant_buffer}, ++ {VKD3D_SM4_OP_DCL_SAMPLER, VKD3DSIH_DCL_SAMPLER, "", "", ++ shader_sm4_read_dcl_sampler}, ++ {VKD3D_SM4_OP_DCL_INDEX_RANGE, VKD3DSIH_DCL_INDEX_RANGE, "", "", ++ shader_sm4_read_dcl_index_range}, ++ {VKD3D_SM4_OP_DCL_OUTPUT_TOPOLOGY, VKD3DSIH_DCL_OUTPUT_TOPOLOGY, "", "", ++ shader_sm4_read_dcl_output_topology}, ++ {VKD3D_SM4_OP_DCL_INPUT_PRIMITIVE, VKD3DSIH_DCL_INPUT_PRIMITIVE, "", "", ++ shader_sm4_read_dcl_input_primitive}, ++ {VKD3D_SM4_OP_DCL_VERTICES_OUT, VKD3DSIH_DCL_VERTICES_OUT, "", "", ++ shader_sm4_read_declaration_count}, ++ {VKD3D_SM4_OP_DCL_INPUT, VKD3DSIH_DCL_INPUT, "", "", ++ shader_sm4_read_declaration_dst}, ++ {VKD3D_SM4_OP_DCL_INPUT_SGV, VKD3DSIH_DCL_INPUT_SGV, "", "", ++ shader_sm4_read_declaration_register_semantic}, ++ {VKD3D_SM4_OP_DCL_INPUT_SIV, VKD3DSIH_DCL_INPUT_SIV, "", "", ++ shader_sm4_read_declaration_register_semantic}, ++ {VKD3D_SM4_OP_DCL_INPUT_PS, VKD3DSIH_DCL_INPUT_PS, "", "", ++ shader_sm4_read_dcl_input_ps}, ++ {VKD3D_SM4_OP_DCL_INPUT_PS_SGV, VKD3DSIH_DCL_INPUT_PS_SGV, "", "", ++ shader_sm4_read_declaration_register_semantic}, ++ {VKD3D_SM4_OP_DCL_INPUT_PS_SIV, VKD3DSIH_DCL_INPUT_PS_SIV, "", "", ++ shader_sm4_read_dcl_input_ps_siv}, ++ {VKD3D_SM4_OP_DCL_OUTPUT, VKD3DSIH_DCL_OUTPUT, "", "", ++ shader_sm4_read_declaration_dst}, ++ {VKD3D_SM4_OP_DCL_OUTPUT_SIV, VKD3DSIH_DCL_OUTPUT_SIV, "", "", ++ shader_sm4_read_declaration_register_semantic}, ++ {VKD3D_SM4_OP_DCL_TEMPS, VKD3DSIH_DCL_TEMPS, "", "", ++ shader_sm4_read_declaration_count}, ++ {VKD3D_SM4_OP_DCL_INDEXABLE_TEMP, VKD3DSIH_DCL_INDEXABLE_TEMP, "", "", ++ shader_sm4_read_dcl_indexable_temp}, ++ {VKD3D_SM4_OP_DCL_GLOBAL_FLAGS, VKD3DSIH_DCL_GLOBAL_FLAGS, "", "", ++ shader_sm4_read_dcl_global_flags}, ++ {VKD3D_SM4_OP_LOD, VKD3DSIH_LOD, "f", "fRS"}, ++ {VKD3D_SM4_OP_GATHER4, VKD3DSIH_GATHER4, "u", "fRS"}, ++ {VKD3D_SM4_OP_SAMPLE_POS, VKD3DSIH_SAMPLE_POS, "f", "Ru"}, ++ {VKD3D_SM4_OP_SAMPLE_INFO, VKD3DSIH_SAMPLE_INFO, "f", "R"}, ++ {VKD3D_SM5_OP_HS_DECLS, VKD3DSIH_HS_DECLS, "", ""}, ++ {VKD3D_SM5_OP_HS_CONTROL_POINT_PHASE, VKD3DSIH_HS_CONTROL_POINT_PHASE, "", ""}, ++ {VKD3D_SM5_OP_HS_FORK_PHASE, VKD3DSIH_HS_FORK_PHASE, "", ""}, ++ {VKD3D_SM5_OP_HS_JOIN_PHASE, VKD3DSIH_HS_JOIN_PHASE, "", ""}, ++ {VKD3D_SM5_OP_EMIT_STREAM, VKD3DSIH_EMIT_STREAM, "", "f"}, ++ {VKD3D_SM5_OP_CUT_STREAM, VKD3DSIH_CUT_STREAM, "", "f"}, ++ {VKD3D_SM5_OP_FCALL, VKD3DSIH_FCALL, "", "O", ++ shader_sm5_read_fcall}, ++ {VKD3D_SM5_OP_BUFINFO, VKD3DSIH_BUFINFO, "i", "U"}, ++ {VKD3D_SM5_OP_DERIV_RTX_COARSE, VKD3DSIH_DSX_COARSE, "f", "f"}, ++ {VKD3D_SM5_OP_DERIV_RTX_FINE, VKD3DSIH_DSX_FINE, "f", "f"}, ++ {VKD3D_SM5_OP_DERIV_RTY_COARSE, VKD3DSIH_DSY_COARSE, "f", "f"}, ++ {VKD3D_SM5_OP_DERIV_RTY_FINE, VKD3DSIH_DSY_FINE, "f", "f"}, ++ {VKD3D_SM5_OP_GATHER4_C, VKD3DSIH_GATHER4_C, "f", "fRSf"}, ++ {VKD3D_SM5_OP_GATHER4_PO, VKD3DSIH_GATHER4_PO, "f", "fiRS"}, ++ {VKD3D_SM5_OP_GATHER4_PO_C, VKD3DSIH_GATHER4_PO_C, "f", "fiRSf"}, ++ {VKD3D_SM5_OP_RCP, VKD3DSIH_RCP, "f", "f"}, ++ {VKD3D_SM5_OP_F32TOF16, VKD3DSIH_F32TOF16, "u", "f"}, ++ {VKD3D_SM5_OP_F16TOF32, VKD3DSIH_F16TOF32, "f", "u"}, ++ {VKD3D_SM5_OP_COUNTBITS, VKD3DSIH_COUNTBITS, "u", "u"}, ++ {VKD3D_SM5_OP_FIRSTBIT_HI, VKD3DSIH_FIRSTBIT_HI, "u", "u"}, ++ {VKD3D_SM5_OP_FIRSTBIT_LO, VKD3DSIH_FIRSTBIT_LO, "u", "u"}, ++ {VKD3D_SM5_OP_FIRSTBIT_SHI, VKD3DSIH_FIRSTBIT_SHI, "u", "i"}, ++ {VKD3D_SM5_OP_UBFE, VKD3DSIH_UBFE, "u", "iiu"}, ++ {VKD3D_SM5_OP_IBFE, VKD3DSIH_IBFE, "i", "iii"}, ++ {VKD3D_SM5_OP_BFI, VKD3DSIH_BFI, "u", "iiuu"}, ++ {VKD3D_SM5_OP_BFREV, VKD3DSIH_BFREV, "u", "u"}, ++ {VKD3D_SM5_OP_SWAPC, VKD3DSIH_SWAPC, "ff", "uff"}, ++ {VKD3D_SM5_OP_DCL_STREAM, VKD3DSIH_DCL_STREAM, "", "O"}, ++ {VKD3D_SM5_OP_DCL_FUNCTION_BODY, VKD3DSIH_DCL_FUNCTION_BODY, "", "", ++ shader_sm5_read_dcl_function_body}, ++ {VKD3D_SM5_OP_DCL_FUNCTION_TABLE, VKD3DSIH_DCL_FUNCTION_TABLE, "", "", ++ shader_sm5_read_dcl_function_table}, ++ {VKD3D_SM5_OP_DCL_INTERFACE, VKD3DSIH_DCL_INTERFACE, "", "", ++ shader_sm5_read_dcl_interface}, ++ {VKD3D_SM5_OP_DCL_INPUT_CONTROL_POINT_COUNT, VKD3DSIH_DCL_INPUT_CONTROL_POINT_COUNT, "", "", ++ shader_sm5_read_control_point_count}, ++ {VKD3D_SM5_OP_DCL_OUTPUT_CONTROL_POINT_COUNT, VKD3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT, "", "", ++ shader_sm5_read_control_point_count}, ++ {VKD3D_SM5_OP_DCL_TESSELLATOR_DOMAIN, VKD3DSIH_DCL_TESSELLATOR_DOMAIN, "", "", ++ shader_sm5_read_dcl_tessellator_domain}, ++ {VKD3D_SM5_OP_DCL_TESSELLATOR_PARTITIONING, VKD3DSIH_DCL_TESSELLATOR_PARTITIONING, "", "", ++ shader_sm5_read_dcl_tessellator_partitioning}, ++ {VKD3D_SM5_OP_DCL_TESSELLATOR_OUTPUT_PRIMITIVE, VKD3DSIH_DCL_TESSELLATOR_OUTPUT_PRIMITIVE, "", "", ++ shader_sm5_read_dcl_tessellator_output_primitive}, ++ {VKD3D_SM5_OP_DCL_HS_MAX_TESSFACTOR, VKD3DSIH_DCL_HS_MAX_TESSFACTOR, "", "", ++ shader_sm5_read_dcl_hs_max_tessfactor}, ++ {VKD3D_SM5_OP_DCL_HS_FORK_PHASE_INSTANCE_COUNT, VKD3DSIH_DCL_HS_FORK_PHASE_INSTANCE_COUNT, "", "", ++ shader_sm4_read_declaration_count}, ++ {VKD3D_SM5_OP_DCL_HS_JOIN_PHASE_INSTANCE_COUNT, VKD3DSIH_DCL_HS_JOIN_PHASE_INSTANCE_COUNT, "", "", ++ shader_sm4_read_declaration_count}, ++ {VKD3D_SM5_OP_DCL_THREAD_GROUP, VKD3DSIH_DCL_THREAD_GROUP, "", "", ++ shader_sm5_read_dcl_thread_group}, ++ {VKD3D_SM5_OP_DCL_UAV_TYPED, VKD3DSIH_DCL_UAV_TYPED, "", "", ++ shader_sm4_read_dcl_resource}, ++ {VKD3D_SM5_OP_DCL_UAV_RAW, VKD3DSIH_DCL_UAV_RAW, "", "", ++ shader_sm5_read_dcl_uav_raw}, ++ {VKD3D_SM5_OP_DCL_UAV_STRUCTURED, VKD3DSIH_DCL_UAV_STRUCTURED, "", "", ++ shader_sm5_read_dcl_uav_structured}, ++ {VKD3D_SM5_OP_DCL_TGSM_RAW, VKD3DSIH_DCL_TGSM_RAW, "", "", ++ shader_sm5_read_dcl_tgsm_raw}, ++ {VKD3D_SM5_OP_DCL_TGSM_STRUCTURED, VKD3DSIH_DCL_TGSM_STRUCTURED, "", "", ++ shader_sm5_read_dcl_tgsm_structured}, ++ {VKD3D_SM5_OP_DCL_RESOURCE_RAW, VKD3DSIH_DCL_RESOURCE_RAW, "", "", ++ shader_sm5_read_dcl_resource_raw}, ++ {VKD3D_SM5_OP_DCL_RESOURCE_STRUCTURED, VKD3DSIH_DCL_RESOURCE_STRUCTURED, "", "", ++ shader_sm5_read_dcl_resource_structured}, ++ {VKD3D_SM5_OP_LD_UAV_TYPED, VKD3DSIH_LD_UAV_TYPED, "u", "iU"}, ++ {VKD3D_SM5_OP_STORE_UAV_TYPED, VKD3DSIH_STORE_UAV_TYPED, "U", "iu"}, ++ {VKD3D_SM5_OP_LD_RAW, VKD3DSIH_LD_RAW, "u", "iU"}, ++ {VKD3D_SM5_OP_STORE_RAW, VKD3DSIH_STORE_RAW, "U", "uu"}, ++ {VKD3D_SM5_OP_LD_STRUCTURED, VKD3DSIH_LD_STRUCTURED, "u", "iiR"}, ++ {VKD3D_SM5_OP_STORE_STRUCTURED, VKD3DSIH_STORE_STRUCTURED, "U", "iiu"}, ++ {VKD3D_SM5_OP_ATOMIC_AND, VKD3DSIH_ATOMIC_AND, "U", "iu"}, ++ {VKD3D_SM5_OP_ATOMIC_OR, VKD3DSIH_ATOMIC_OR, "U", "iu"}, ++ {VKD3D_SM5_OP_ATOMIC_XOR, VKD3DSIH_ATOMIC_XOR, "U", "iu"}, ++ {VKD3D_SM5_OP_ATOMIC_CMP_STORE, VKD3DSIH_ATOMIC_CMP_STORE, "U", "iuu"}, ++ {VKD3D_SM5_OP_ATOMIC_IADD, VKD3DSIH_ATOMIC_IADD, "U", "ii"}, ++ {VKD3D_SM5_OP_ATOMIC_IMAX, VKD3DSIH_ATOMIC_IMAX, "U", "ii"}, ++ {VKD3D_SM5_OP_ATOMIC_IMIN, VKD3DSIH_ATOMIC_IMIN, "U", "ii"}, ++ {VKD3D_SM5_OP_ATOMIC_UMAX, VKD3DSIH_ATOMIC_UMAX, "U", "iu"}, ++ {VKD3D_SM5_OP_ATOMIC_UMIN, VKD3DSIH_ATOMIC_UMIN, "U", "iu"}, ++ {VKD3D_SM5_OP_IMM_ATOMIC_ALLOC, VKD3DSIH_IMM_ATOMIC_ALLOC, "u", "U"}, ++ {VKD3D_SM5_OP_IMM_ATOMIC_CONSUME, VKD3DSIH_IMM_ATOMIC_CONSUME, "u", "U"}, ++ {VKD3D_SM5_OP_IMM_ATOMIC_IADD, VKD3DSIH_IMM_ATOMIC_IADD, "uU", "ii"}, ++ {VKD3D_SM5_OP_IMM_ATOMIC_AND, VKD3DSIH_IMM_ATOMIC_AND, "uU", "iu"}, ++ {VKD3D_SM5_OP_IMM_ATOMIC_OR, VKD3DSIH_IMM_ATOMIC_OR, "uU", "iu"}, ++ {VKD3D_SM5_OP_IMM_ATOMIC_XOR, VKD3DSIH_IMM_ATOMIC_XOR, "uU", "iu"}, ++ {VKD3D_SM5_OP_IMM_ATOMIC_EXCH, VKD3DSIH_IMM_ATOMIC_EXCH, "uU", "iu"}, ++ {VKD3D_SM5_OP_IMM_ATOMIC_CMP_EXCH, VKD3DSIH_IMM_ATOMIC_CMP_EXCH, "uU", "iuu"}, ++ {VKD3D_SM5_OP_IMM_ATOMIC_IMAX, VKD3DSIH_IMM_ATOMIC_IMAX, "iU", "ii"}, ++ {VKD3D_SM5_OP_IMM_ATOMIC_IMIN, VKD3DSIH_IMM_ATOMIC_IMIN, "iU", "ii"}, ++ {VKD3D_SM5_OP_IMM_ATOMIC_UMAX, VKD3DSIH_IMM_ATOMIC_UMAX, "uU", "iu"}, ++ {VKD3D_SM5_OP_IMM_ATOMIC_UMIN, VKD3DSIH_IMM_ATOMIC_UMIN, "uU", "iu"}, ++ {VKD3D_SM5_OP_SYNC, VKD3DSIH_SYNC, "", "", ++ shader_sm5_read_sync}, ++ {VKD3D_SM5_OP_DADD, VKD3DSIH_DADD, "d", "dd"}, ++ {VKD3D_SM5_OP_DMAX, VKD3DSIH_DMAX, "d", "dd"}, ++ {VKD3D_SM5_OP_DMIN, VKD3DSIH_DMIN, "d", "dd"}, ++ {VKD3D_SM5_OP_DMUL, VKD3DSIH_DMUL, "d", "dd"}, ++ {VKD3D_SM5_OP_DEQ, VKD3DSIH_DEQ, "u", "dd"}, ++ {VKD3D_SM5_OP_DGE, VKD3DSIH_DGE, "u", "dd"}, ++ {VKD3D_SM5_OP_DLT, VKD3DSIH_DLT, "u", "dd"}, ++ {VKD3D_SM5_OP_DNE, VKD3DSIH_DNE, "u", "dd"}, ++ {VKD3D_SM5_OP_DMOV, VKD3DSIH_DMOV, "d", "d"}, ++ {VKD3D_SM5_OP_DMOVC, VKD3DSIH_DMOVC, "d", "udd"}, ++ {VKD3D_SM5_OP_DTOF, VKD3DSIH_DTOF, "f", "d"}, ++ {VKD3D_SM5_OP_FTOD, VKD3DSIH_FTOD, "d", "f"}, ++ {VKD3D_SM5_OP_EVAL_SAMPLE_INDEX, VKD3DSIH_EVAL_SAMPLE_INDEX, "f", "fi"}, ++ {VKD3D_SM5_OP_EVAL_CENTROID, VKD3DSIH_EVAL_CENTROID, "f", "f"}, ++ {VKD3D_SM5_OP_DCL_GS_INSTANCES, VKD3DSIH_DCL_GS_INSTANCES, "", "", ++ shader_sm4_read_declaration_count}, ++ {VKD3D_SM5_OP_DDIV, VKD3DSIH_DDIV, "d", "dd"}, ++ {VKD3D_SM5_OP_DFMA, VKD3DSIH_DFMA, "d", "ddd"}, ++ {VKD3D_SM5_OP_DRCP, VKD3DSIH_DRCP, "d", "d"}, ++ {VKD3D_SM5_OP_MSAD, VKD3DSIH_MSAD, "u", "uuu"}, ++ {VKD3D_SM5_OP_DTOI, VKD3DSIH_DTOI, "i", "d"}, ++ {VKD3D_SM5_OP_DTOU, VKD3DSIH_DTOU, "u", "d"}, ++ {VKD3D_SM5_OP_ITOD, VKD3DSIH_ITOD, "d", "i"}, ++ {VKD3D_SM5_OP_UTOD, VKD3DSIH_UTOD, "d", "u"}, ++ {VKD3D_SM5_OP_GATHER4_S, VKD3DSIH_GATHER4_S, "uu", "fRS"}, ++ {VKD3D_SM5_OP_GATHER4_C_S, VKD3DSIH_GATHER4_C_S, "fu", "fRSf"}, ++ {VKD3D_SM5_OP_GATHER4_PO_S, VKD3DSIH_GATHER4_PO_S, "fu", "fiRS"}, ++ {VKD3D_SM5_OP_GATHER4_PO_C_S, VKD3DSIH_GATHER4_PO_C_S, "fu", "fiRSf"}, ++ {VKD3D_SM5_OP_LD_S, VKD3DSIH_LD_S, "uu", "iR"}, ++ {VKD3D_SM5_OP_LD2DMS_S, VKD3DSIH_LD2DMS_S, "uu", "iRi"}, ++ {VKD3D_SM5_OP_LD_UAV_TYPED_S, VKD3DSIH_LD_UAV_TYPED_S, "uu", "iU"}, ++ {VKD3D_SM5_OP_LD_RAW_S, VKD3DSIH_LD_RAW_S, "uu", "iU"}, ++ {VKD3D_SM5_OP_LD_STRUCTURED_S, VKD3DSIH_LD_STRUCTURED_S, "uu", "iiR"}, ++ {VKD3D_SM5_OP_SAMPLE_LOD_S, VKD3DSIH_SAMPLE_LOD_S, "uu", "fRSf"}, ++ {VKD3D_SM5_OP_SAMPLE_C_LZ_S, VKD3DSIH_SAMPLE_C_LZ_S, "fu", "fRSf"}, ++ {VKD3D_SM5_OP_SAMPLE_CL_S, VKD3DSIH_SAMPLE_CL_S, "uu", "fRSf"}, ++ {VKD3D_SM5_OP_SAMPLE_B_CL_S, VKD3DSIH_SAMPLE_B_CL_S, "uu", "fRSff"}, ++ {VKD3D_SM5_OP_SAMPLE_GRAD_CL_S, VKD3DSIH_SAMPLE_GRAD_CL_S, "uu", "fRSfff"}, ++ {VKD3D_SM5_OP_SAMPLE_C_CL_S, VKD3DSIH_SAMPLE_C_CL_S, "fu", "fRSff"}, ++ {VKD3D_SM5_OP_CHECK_ACCESS_FULLY_MAPPED, VKD3DSIH_CHECK_ACCESS_FULLY_MAPPED, "u", "u"}, ++ }; ++ + static const struct vkd3d_sm4_register_type_info register_type_table[] = + { + {VKD3D_SM4_RT_TEMP, VKD3DSPR_TEMP, VKD3D_SM4_SWIZZLE_VEC4}, +@@ -1610,9 +1597,17 @@ static void init_sm4_lookup_tables(struct vkd3d_sm4_lookup_tables *lookup) + + memset(lookup, 0, sizeof(*lookup)); + ++ for (i = 0; i < ARRAY_SIZE(opcode_table); ++i) ++ { ++ const struct vkd3d_sm4_opcode_info *info = &opcode_table[i]; ++ ++ lookup->opcode_info_from_sm4[info->opcode] = info; ++ } ++ + for (i = 0; i < ARRAY_SIZE(register_type_table); ++i) + { +- info = ®ister_type_table[i]; ++ const struct vkd3d_sm4_register_type_info *info = ®ister_type_table[i]; ++ + lookup->register_type_info_from_sm4[info->sm4_type] = info; + lookup->register_type_info_from_vkd3d[info->vkd3d_type] = info; + } +@@ -1625,6 +1620,14 @@ static void tpf_writer_init(struct tpf_writer *tpf, struct hlsl_ctx *ctx, struct + init_sm4_lookup_tables(&tpf->lookup); + } + ++static const struct vkd3d_sm4_opcode_info *get_info_from_sm4_opcode( ++ const struct vkd3d_sm4_lookup_tables *lookup, enum vkd3d_sm4_opcode sm4_opcode) ++{ ++ if (sm4_opcode >= VKD3D_SM4_OP_COUNT) ++ return NULL; ++ return lookup->opcode_info_from_sm4[sm4_opcode]; ++} ++ + static const struct vkd3d_sm4_register_type_info *get_info_from_sm4_register_type( + const struct vkd3d_sm4_lookup_tables *lookup, enum vkd3d_sm4_register_type sm4_type) + { +@@ -1651,31 +1654,6 @@ static enum vkd3d_sm4_swizzle_type vkd3d_sm4_get_default_swizzle_type( + return register_type_info->default_src_swizzle_type; + } + +-static void map_register(const struct vkd3d_shader_sm4_parser *sm4, struct vkd3d_shader_register *reg) +-{ +- switch (sm4->p.shader_version.type) +- { +- case VKD3D_SHADER_TYPE_PIXEL: +- if (reg->type == VKD3DSPR_OUTPUT) +- { +- unsigned int reg_idx = reg->idx[0].offset; +- +- if (reg_idx >= ARRAY_SIZE(sm4->output_map)) +- { +- /* Validated later */ +- break; +- } +- +- reg->type = VKD3DSPR_COLOROUT; +- reg->idx[0].offset = sm4->output_map[reg_idx]; +- } +- break; +- +- default: +- break; +- } +-} +- + static enum vkd3d_data_type map_data_type(char t) + { + switch (t) +@@ -1939,8 +1917,6 @@ static bool shader_sm4_read_param(struct vkd3d_shader_sm4_parser *priv, const ui + ++param->idx_count; + } + +- map_register(priv, param); +- + return true; + } + +@@ -2360,7 +2336,7 @@ static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, str + } + --len; + +- if (!(opcode_info = get_opcode_info(opcode))) ++ if (!(opcode_info = get_info_from_sm4_opcode(&sm4->lookup, opcode))) + { + FIXME("Unrecognized opcode %#x, opcode_token 0x%08x.\n", opcode, opcode_token); + ins->handler_idx = VKD3DSIH_INVALID; +@@ -2471,7 +2447,6 @@ static bool shader_sm4_init(struct vkd3d_shader_sm4_parser *sm4, const uint32_t + { + struct vkd3d_shader_version version; + uint32_t version_token, token_count; +- unsigned int i; + + if (byte_code_size / sizeof(*byte_code) < 2) + { +@@ -2531,23 +2506,6 @@ static bool shader_sm4_init(struct vkd3d_shader_sm4_parser *sm4, const uint32_t + return false; + sm4->ptr = sm4->start; + +- memset(sm4->output_map, 0xff, sizeof(sm4->output_map)); +- for (i = 0; i < output_signature->element_count; ++i) +- { +- struct signature_element *e = &output_signature->elements[i]; +- +- if (version.type == VKD3D_SHADER_TYPE_PIXEL +- && ascii_strcasecmp(e->semantic_name, "SV_Target")) +- continue; +- if (e->register_index >= ARRAY_SIZE(sm4->output_map)) +- { +- WARN("Invalid output index %u.\n", e->register_index); +- continue; +- } +- +- sm4->output_map[e->register_index] = e->semantic_index; +- } +- + init_sm4_lookup_tables(&sm4->lookup); + + return true; +@@ -3250,8 +3208,7 @@ static struct extern_resource *sm4_get_extern_resources(struct hlsl_ctx *ctx, un + if (!hlsl_type_is_resource(component_type)) + continue; + +- regset = hlsl_type_get_regset(component_type); +- regset_offset = hlsl_type_get_component_offset(ctx, var->data_type, regset, k); ++ regset_offset = hlsl_type_get_component_offset(ctx, var->data_type, k, ®set); + + if (regset_offset > var->regs[regset].allocation_size) + continue; +@@ -3297,38 +3254,43 @@ static struct extern_resource *sm4_get_extern_resources(struct hlsl_ctx *ctx, un + } + else + { ++ unsigned int r; ++ + if (!hlsl_type_is_resource(var->data_type)) + continue; +- regset = hlsl_type_get_regset(var->data_type); +- if (!var->regs[regset].allocated) +- continue; + +- if (!(hlsl_array_reserve(ctx, (void **)&extern_resources, &capacity, *count + 1, +- sizeof(*extern_resources)))) ++ for (r = 0; r <= HLSL_REGSET_LAST; ++r) + { +- sm4_free_extern_resources(extern_resources, *count); +- *count = 0; +- return NULL; +- } ++ if (!var->regs[r].allocated) ++ continue; + +- if (!(name = hlsl_strdup(ctx, string_skip_tag(var->name)))) +- { +- sm4_free_extern_resources(extern_resources, *count); +- *count = 0; +- return NULL; +- } ++ 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].var = var; + +- extern_resources[*count].name = name; +- extern_resources[*count].data_type = var->data_type; +- extern_resources[*count].is_user_packed = !!var->reg_reservation.reg_type; ++ extern_resources[*count].name = name; ++ extern_resources[*count].data_type = var->data_type; ++ extern_resources[*count].is_user_packed = !!var->reg_reservation.reg_type; + +- extern_resources[*count].regset = regset; +- extern_resources[*count].id = var->regs[regset].id; +- extern_resources[*count].bind_count = var->bind_count[regset]; ++ extern_resources[*count].regset = r; ++ extern_resources[*count].id = var->regs[r].id; ++ extern_resources[*count].bind_count = var->bind_count[r]; + +- ++*count; ++ ++*count; ++ } + } + } + +@@ -3628,6 +3590,7 @@ static uint32_t sm4_encode_instruction_modifier(const struct sm4_instruction_mod + struct sm4_instruction + { + enum vkd3d_sm4_opcode opcode; ++ uint32_t extra_bits; + + struct sm4_instruction_modifier modifiers[1]; + unsigned int modifier_count; +@@ -3652,7 +3615,7 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct vkd3d_shader_re + + if (var->is_uniform) + { +- enum hlsl_regset regset = hlsl_type_get_regset(data_type); ++ enum hlsl_regset regset = hlsl_deref_get_regset(ctx, deref); + + if (regset == HLSL_REGSET_TEXTURES) + { +@@ -3909,8 +3872,13 @@ static void sm4_write_src_register(const struct tpf_writer *tpf, const struct vk + token |= reg_dim << VKD3D_SM4_DIMENSION_SHIFT; + if (reg_dim == VKD3D_SM4_DIMENSION_VEC4) + { +- token |= (uint32_t)register_type_info->default_src_swizzle_type << VKD3D_SM4_SWIZZLE_TYPE_SHIFT; +- token |= swizzle_to_sm4(src->swizzle) << VKD3D_SM4_SWIZZLE_SHIFT; ++ uint32_t swizzle_type = (uint32_t)register_type_info->default_src_swizzle_type; ++ ++ token |= swizzle_type << VKD3D_SM4_SWIZZLE_TYPE_SHIFT; ++ if (swizzle_type == VKD3D_SM4_SWIZZLE_SCALAR) ++ token |= (swizzle_to_sm4(src->swizzle) & 0x3) << VKD3D_SM4_SWIZZLE_SHIFT; ++ else ++ token |= swizzle_to_sm4(src->swizzle) << VKD3D_SM4_SWIZZLE_SHIFT; + } + + switch (src->modifiers) +@@ -3969,53 +3937,25 @@ static void sm4_write_src_register(const struct tpf_writer *tpf, const struct vk + } + } + +-static uint32_t sm4_token_count_from_dst_register(const struct vkd3d_shader_dst_param *dst) +-{ +- uint32_t order = 1; +- if (dst->reg.type == VKD3DSPR_IMMCONST) +- order += dst->reg.dimension == VSIR_DIMENSION_VEC4 ? 4 : 1; +- order += dst->reg.idx_count; +- return order; +-} +- +-static uint32_t sm4_token_count_from_src_register(const struct vkd3d_shader_src_param *src) +-{ +- uint32_t order = 1; +- if (src->reg.type == VKD3DSPR_IMMCONST) +- order += src->reg.dimension == VSIR_DIMENSION_VEC4 ? 4 : 1; +- order += src->reg.idx_count; +- if (src->modifiers) +- ++order; +- return order; +-} +- + static void write_sm4_instruction(const struct tpf_writer *tpf, const struct sm4_instruction *instr) + { + struct vkd3d_bytecode_buffer *buffer = tpf->buffer; +- uint32_t token = instr->opcode; +- unsigned int size = 1, i, j; +- +- size += instr->modifier_count; +- for (i = 0; i < instr->dst_count; ++i) +- size += sm4_token_count_from_dst_register(&instr->dsts[i]); +- for (i = 0; i < instr->src_count; ++i) +- size += sm4_token_count_from_src_register(&instr->srcs[i]); +- size += instr->idx_count; +- if (instr->byte_stride) +- ++size; +- +- token |= (size << VKD3D_SM4_INSTRUCTION_LENGTH_SHIFT); ++ uint32_t token = instr->opcode | instr->extra_bits; ++ unsigned int size, i, j; ++ size_t token_position; + + if (instr->modifier_count > 0) + token |= VKD3D_SM4_INSTRUCTION_MODIFIER; +- put_u32(buffer, token); ++ ++ token_position = put_u32(buffer, 0); + + for (i = 0; i < instr->modifier_count; ++i) + { +- token = sm4_encode_instruction_modifier(&instr->modifiers[i]); ++ uint32_t modifier_token = sm4_encode_instruction_modifier(&instr->modifiers[i]); ++ + if (instr->modifier_count > i + 1) +- token |= VKD3D_SM4_INSTRUCTION_MODIFIER; +- put_u32(buffer, token); ++ modifier_token |= VKD3D_SM4_INSTRUCTION_MODIFIER; ++ put_u32(buffer, modifier_token); + } + + for (i = 0; i < instr->dst_count; ++i) +@@ -4029,6 +3969,10 @@ static void write_sm4_instruction(const struct tpf_writer *tpf, const struct sm4 + + for (j = 0; j < instr->idx_count; ++j) + put_u32(buffer, instr->idx[j]); ++ ++ size = (bytecode_get_size(buffer) - token_position) / sizeof(uint32_t); ++ token |= (size << VKD3D_SM4_INSTRUCTION_LENGTH_SHIFT); ++ set_u32(buffer, token_position, token); + } + + static bool encode_texel_offset_as_aoffimmi(struct sm4_instruction *instr, +@@ -4091,7 +4035,7 @@ static void write_sm4_dcl_samplers(const struct tpf_writer *tpf, const struct ex + component_type = hlsl_type_get_component_type(tpf->ctx, resource->data_type, 0); + + if (component_type->sampler_dim == HLSL_SAMPLER_DIM_COMPARISON) +- instr.opcode |= VKD3D_SM4_SAMPLER_COMPARISON << VKD3D_SM4_SAMPLER_MODE_SHIFT; ++ instr.extra_bits |= VKD3D_SM4_SAMPLER_COMPARISON << VKD3D_SM4_SAMPLER_MODE_SHIFT; + + assert(resource->regset == HLSL_REGSET_SAMPLERS); + +@@ -4150,12 +4094,12 @@ static void write_sm4_dcl_textures(const struct tpf_writer *tpf, const struct ex + { + instr.opcode = VKD3D_SM4_OP_DCL_RESOURCE; + } +- instr.opcode |= (sm4_resource_dimension(component_type) << VKD3D_SM4_RESOURCE_TYPE_SHIFT); ++ 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) + { +- instr.opcode |= component_type->sample_count << VKD3D_SM4_RESOURCE_SAMPLE_COUNT_SHIFT; ++ instr.extra_bits |= component_type->sample_count << VKD3D_SM4_RESOURCE_SAMPLE_COUNT_SHIFT; + } + + write_sm4_instruction(tpf, &instr); +@@ -4230,9 +4174,35 @@ static void write_sm4_dcl_semantic(const struct tpf_writer *tpf, const struct hl + enum vkd3d_shader_interpolation_mode mode = VKD3DSIM_LINEAR; + + if ((var->storage_modifiers & HLSL_STORAGE_NOINTERPOLATION) || type_is_integer(var->data_type)) ++ { + mode = VKD3DSIM_CONSTANT; ++ } ++ else ++ { ++ static const struct ++ { ++ unsigned int modifiers; ++ enum vkd3d_shader_interpolation_mode mode; ++ } ++ modes[] = ++ { ++ { HLSL_STORAGE_CENTROID | HLSL_STORAGE_NOPERSPECTIVE, VKD3DSIM_LINEAR_NOPERSPECTIVE_CENTROID }, ++ { HLSL_STORAGE_NOPERSPECTIVE, VKD3DSIM_LINEAR_NOPERSPECTIVE }, ++ { HLSL_STORAGE_CENTROID, VKD3DSIM_LINEAR_CENTROID }, ++ }; ++ unsigned int i; ++ ++ for (i = 0; i < ARRAY_SIZE(modes); ++i) ++ { ++ if ((var->storage_modifiers & modes[i].modifiers) == modes[i].modifiers) ++ { ++ mode = modes[i].mode; ++ break; ++ } ++ } ++ } + +- instr.opcode |= mode << VKD3D_SM4_INTERPOLATION_MODE_SHIFT; ++ instr.extra_bits |= mode << VKD3D_SM4_INTERPOLATION_MODE_SHIFT; + } + } + else +@@ -4429,7 +4399,7 @@ static void write_sm4_ld(const struct tpf_writer *tpf, const struct hlsl_ir_node + const struct hlsl_type *resource_type = hlsl_deref_get_type(tpf->ctx, resource); + bool multisampled = resource_type->base_type == HLSL_TYPE_TEXTURE + && (resource_type->sampler_dim == HLSL_SAMPLER_DIM_2DMS || resource_type->sampler_dim == HLSL_SAMPLER_DIM_2DMSARRAY); +- bool uav = (hlsl_type_get_regset(resource_type) == HLSL_REGSET_UAVS); ++ bool uav = (hlsl_deref_get_regset(tpf->ctx, resource) == HLSL_REGSET_UAVS); + unsigned int coords_writemask = VKD3DSP_WRITEMASK_ALL; + struct sm4_instruction instr; + +@@ -4590,7 +4560,7 @@ static void write_sm4_sampleinfo(const struct tpf_writer *tpf, const struct hlsl + memset(&instr, 0, sizeof(instr)); + instr.opcode = VKD3D_SM4_OP_SAMPLE_INFO; + if (dst->data_type->base_type == HLSL_TYPE_UINT) +- instr.opcode |= VKD3DSI_SAMPLE_INFO_UINT << VKD3D_SM4_INSTRUCTION_FLAGS_SHIFT; ++ instr.extra_bits |= VKD3DSI_SAMPLE_INFO_UINT << VKD3D_SM4_INSTRUCTION_FLAGS_SHIFT; + + sm4_dst_from_node(&instr.dsts[0], dst); + instr.dst_count = 1; +@@ -4612,7 +4582,7 @@ static void write_sm4_resinfo(const struct tpf_writer *tpf, const struct hlsl_ir + memset(&instr, 0, sizeof(instr)); + instr.opcode = VKD3D_SM4_OP_RESINFO; + if (dst->data_type->base_type == HLSL_TYPE_UINT) +- instr.opcode |= VKD3DSI_RESINFO_UINT << VKD3D_SM4_INSTRUCTION_FLAGS_SHIFT; ++ instr.extra_bits |= VKD3DSI_RESINFO_UINT << VKD3D_SM4_INSTRUCTION_FLAGS_SHIFT; + + sm4_dst_from_node(&instr.dsts[0], dst); + instr.dst_count = 1; +@@ -5256,6 +5226,10 @@ static void write_sm4_jump(const struct tpf_writer *tpf, const struct hlsl_ir_ju + instr.opcode = VKD3D_SM4_OP_BREAK; + break; + ++ case HLSL_IR_JUMP_CONTINUE: ++ instr.opcode = VKD3D_SM4_OP_CONTINUE; ++ break; ++ + case HLSL_IR_JUMP_DISCARD_NZ: + { + instr.opcode = VKD3D_SM4_OP_DISCARD | VKD3D_SM4_CONDITIONAL_NZ; +diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c +index 1bd61090139..d9b6995a11e 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c ++++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c +@@ -837,6 +837,15 @@ static void vkd3d_shader_scan_sampler_declaration(struct vkd3d_shader_scan_conte + d->flags |= VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_SAMPLER_COMPARISON_MODE; + } + ++static void vkd3d_shader_scan_combined_sampler_declaration( ++ struct vkd3d_shader_scan_context *context, const struct vkd3d_shader_semantic *semantic) ++{ ++ vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, &semantic->resource.reg.reg, ++ &semantic->resource.range, VKD3D_SHADER_RESOURCE_NONE, VKD3D_SHADER_RESOURCE_DATA_UINT); ++ vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, &semantic->resource.reg.reg, ++ &semantic->resource.range, semantic->resource_type, VKD3D_SHADER_RESOURCE_DATA_FLOAT); ++} ++ + static void vkd3d_shader_scan_resource_declaration(struct vkd3d_shader_scan_context *context, + const struct vkd3d_shader_resource *resource, enum vkd3d_shader_resource_type resource_type, + enum vkd3d_shader_resource_data_type resource_data_type, +@@ -945,6 +954,12 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte + vkd3d_shader_scan_sampler_declaration(context, instruction); + break; + case VKD3DSIH_DCL: ++ if (instruction->declaration.semantic.resource.reg.reg.type == VKD3DSPR_COMBINED_SAMPLER) ++ { ++ vkd3d_shader_scan_combined_sampler_declaration(context, &instruction->declaration.semantic); ++ break; ++ } ++ /* fall through */ + case VKD3DSIH_DCL_UAV_TYPED: + vkd3d_shader_scan_typed_resource_declaration(context, instruction); + break; +diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +index f006d2db532..37c9625874f 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h ++++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +@@ -488,7 +488,7 @@ enum vkd3d_shader_register_type + VKD3DSPR_CONSTINT = 7, + VKD3DSPR_COLOROUT = 8, + VKD3DSPR_DEPTHOUT = 9, +- VKD3DSPR_SAMPLER = 10, ++ VKD3DSPR_COMBINED_SAMPLER = 10, + VKD3DSPR_CONST2 = 11, + VKD3DSPR_CONST3 = 12, + VKD3DSPR_CONST4 = 13, +@@ -504,6 +504,7 @@ enum vkd3d_shader_register_type + VKD3DSPR_IMMCONSTBUFFER, + VKD3DSPR_PRIMID, + VKD3DSPR_NULL, ++ VKD3DSPR_SAMPLER, + VKD3DSPR_RESOURCE, + VKD3DSPR_UAV, + VKD3DSPR_OUTPOINTID, +diff --git a/libs/vkd3d/libs/vkd3d/command.c b/libs/vkd3d/libs/vkd3d/command.c +index a1bffa6cb90..37484e5ea01 100644 +--- a/libs/vkd3d/libs/vkd3d/command.c ++++ b/libs/vkd3d/libs/vkd3d/command.c +@@ -1942,9 +1942,9 @@ static void d3d12_command_signature_decref(struct d3d12_command_signature *signa + } + + /* ID3D12CommandList */ +-static inline struct d3d12_command_list *impl_from_ID3D12GraphicsCommandList4(ID3D12GraphicsCommandList4 *iface) ++static inline struct d3d12_command_list *impl_from_ID3D12GraphicsCommandList5(ID3D12GraphicsCommandList5 *iface) + { +- return CONTAINING_RECORD(iface, struct d3d12_command_list, ID3D12GraphicsCommandList4_iface); ++ return CONTAINING_RECORD(iface, struct d3d12_command_list, ID3D12GraphicsCommandList5_iface); + } + + static void d3d12_command_list_invalidate_current_framebuffer(struct d3d12_command_list *list) +@@ -2290,12 +2290,13 @@ static void d3d12_command_list_track_resource_usage(struct d3d12_command_list *l + } + } + +-static HRESULT STDMETHODCALLTYPE d3d12_command_list_QueryInterface(ID3D12GraphicsCommandList4 *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_command_list_QueryInterface(ID3D12GraphicsCommandList5 *iface, + REFIID iid, void **object) + { + TRACE("iface %p, iid %s, object %p.\n", iface, debugstr_guid(iid), object); + +- if (IsEqualGUID(iid, &IID_ID3D12GraphicsCommandList4) ++ if (IsEqualGUID(iid, &IID_ID3D12GraphicsCommandList5) ++ || IsEqualGUID(iid, &IID_ID3D12GraphicsCommandList4) + || IsEqualGUID(iid, &IID_ID3D12GraphicsCommandList3) + || IsEqualGUID(iid, &IID_ID3D12GraphicsCommandList2) + || IsEqualGUID(iid, &IID_ID3D12GraphicsCommandList1) +@@ -2305,7 +2306,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_list_QueryInterface(ID3D12Graphic + || IsEqualGUID(iid, &IID_ID3D12Object) + || IsEqualGUID(iid, &IID_IUnknown)) + { +- ID3D12GraphicsCommandList4_AddRef(iface); ++ ID3D12GraphicsCommandList5_AddRef(iface); + *object = iface; + return S_OK; + } +@@ -2316,9 +2317,9 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_list_QueryInterface(ID3D12Graphic + return E_NOINTERFACE; + } + +-static ULONG STDMETHODCALLTYPE d3d12_command_list_AddRef(ID3D12GraphicsCommandList4 *iface) ++static ULONG STDMETHODCALLTYPE d3d12_command_list_AddRef(ID3D12GraphicsCommandList5 *iface) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); + ULONG refcount = InterlockedIncrement(&list->refcount); + + TRACE("%p increasing refcount to %u.\n", list, refcount); +@@ -2331,9 +2332,9 @@ static void vkd3d_pipeline_bindings_cleanup(struct vkd3d_pipeline_bindings *bind + vkd3d_free(bindings->vk_uav_counter_views); + } + +-static ULONG STDMETHODCALLTYPE d3d12_command_list_Release(ID3D12GraphicsCommandList4 *iface) ++static ULONG STDMETHODCALLTYPE d3d12_command_list_Release(ID3D12GraphicsCommandList5 *iface) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); + ULONG refcount = InterlockedDecrement(&list->refcount); + + TRACE("%p decreasing refcount to %u.\n", list, refcount); +@@ -2359,66 +2360,66 @@ static ULONG STDMETHODCALLTYPE d3d12_command_list_Release(ID3D12GraphicsCommandL + return refcount; + } + +-static HRESULT STDMETHODCALLTYPE d3d12_command_list_GetPrivateData(ID3D12GraphicsCommandList4 *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_command_list_GetPrivateData(ID3D12GraphicsCommandList5 *iface, + REFGUID guid, UINT *data_size, void *data) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return vkd3d_get_private_data(&list->private_store, guid, data_size, data); + } + +-static HRESULT STDMETHODCALLTYPE d3d12_command_list_SetPrivateData(ID3D12GraphicsCommandList4 *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_command_list_SetPrivateData(ID3D12GraphicsCommandList5 *iface, + REFGUID guid, UINT data_size, const void *data) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data); + + return vkd3d_set_private_data(&list->private_store, guid, data_size, data); + } + +-static HRESULT STDMETHODCALLTYPE d3d12_command_list_SetPrivateDataInterface(ID3D12GraphicsCommandList4 *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_command_list_SetPrivateDataInterface(ID3D12GraphicsCommandList5 *iface, + REFGUID guid, const IUnknown *data) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); + + TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data); + + return vkd3d_set_private_data_interface(&list->private_store, guid, data); + } + +-static HRESULT STDMETHODCALLTYPE d3d12_command_list_SetName(ID3D12GraphicsCommandList4 *iface, const WCHAR *name) ++static HRESULT STDMETHODCALLTYPE d3d12_command_list_SetName(ID3D12GraphicsCommandList5 *iface, const WCHAR *name) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); + + TRACE("iface %p, name %s.\n", iface, debugstr_w(name, list->device->wchar_size)); + + return name ? S_OK : E_INVALIDARG; + } + +-static HRESULT STDMETHODCALLTYPE d3d12_command_list_GetDevice(ID3D12GraphicsCommandList4 *iface, REFIID iid, void **device) ++static HRESULT STDMETHODCALLTYPE d3d12_command_list_GetDevice(ID3D12GraphicsCommandList5 *iface, REFIID iid, void **device) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); + + TRACE("iface %p, iid %s, device %p.\n", iface, debugstr_guid(iid), device); + + return d3d12_device_query_interface(list->device, iid, device); + } + +-static D3D12_COMMAND_LIST_TYPE STDMETHODCALLTYPE d3d12_command_list_GetType(ID3D12GraphicsCommandList4 *iface) ++static D3D12_COMMAND_LIST_TYPE STDMETHODCALLTYPE d3d12_command_list_GetType(ID3D12GraphicsCommandList5 *iface) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); + + TRACE("iface %p.\n", iface); + + return list->type; + } + +-static HRESULT STDMETHODCALLTYPE d3d12_command_list_Close(ID3D12GraphicsCommandList4 *iface) ++static HRESULT STDMETHODCALLTYPE d3d12_command_list_Close(ID3D12GraphicsCommandList5 *iface) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); + const struct vkd3d_vk_device_procs *vk_procs; + VkResult vr; + +@@ -2462,7 +2463,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_list_Close(ID3D12GraphicsCommandL + static void d3d12_command_list_reset_state(struct d3d12_command_list *list, + ID3D12PipelineState *initial_pipeline_state) + { +- ID3D12GraphicsCommandList4 *iface = &list->ID3D12GraphicsCommandList4_iface; ++ ID3D12GraphicsCommandList5 *iface = &list->ID3D12GraphicsCommandList5_iface; + + memset(list->strides, 0, sizeof(list->strides)); + list->primitive_topology = D3D_PRIMITIVE_TOPOLOGY_POINTLIST; +@@ -2498,14 +2499,14 @@ static void d3d12_command_list_reset_state(struct d3d12_command_list *list, + + list->descriptor_heap_count = 0; + +- ID3D12GraphicsCommandList4_SetPipelineState(iface, initial_pipeline_state); ++ ID3D12GraphicsCommandList5_SetPipelineState(iface, initial_pipeline_state); + } + +-static HRESULT STDMETHODCALLTYPE d3d12_command_list_Reset(ID3D12GraphicsCommandList4 *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_command_list_Reset(ID3D12GraphicsCommandList5 *iface, + ID3D12CommandAllocator *allocator, ID3D12PipelineState *initial_pipeline_state) + { + struct d3d12_command_allocator *allocator_impl = unsafe_impl_from_ID3D12CommandAllocator(allocator); +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); + HRESULT hr; + + TRACE("iface %p, allocator %p, initial_pipeline_state %p.\n", +@@ -2532,7 +2533,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_list_Reset(ID3D12GraphicsCommandL + return hr; + } + +-static void STDMETHODCALLTYPE d3d12_command_list_ClearState(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_ClearState(ID3D12GraphicsCommandList5 *iface, + ID3D12PipelineState *pipeline_state) + { + FIXME("iface %p, pipline_state %p stub!\n", iface, pipeline_state); +@@ -3391,11 +3392,11 @@ static void d3d12_command_list_check_index_buffer_strip_cut_value(struct d3d12_c + } + } + +-static void STDMETHODCALLTYPE d3d12_command_list_DrawInstanced(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_DrawInstanced(ID3D12GraphicsCommandList5 *iface, + UINT vertex_count_per_instance, UINT instance_count, UINT start_vertex_location, + UINT start_instance_location) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); + const struct vkd3d_vk_device_procs *vk_procs; + + TRACE("iface %p, vertex_count_per_instance %u, instance_count %u, " +@@ -3415,11 +3416,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_DrawInstanced(ID3D12GraphicsCom + instance_count, start_vertex_location, start_instance_location)); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_DrawIndexedInstanced(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_DrawIndexedInstanced(ID3D12GraphicsCommandList5 *iface, + UINT index_count_per_instance, UINT instance_count, UINT start_vertex_location, + INT base_vertex_location, UINT start_instance_location) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); + const struct vkd3d_vk_device_procs *vk_procs; + + TRACE("iface %p, index_count_per_instance %u, instance_count %u, start_vertex_location %u, " +@@ -3441,10 +3442,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_DrawIndexedInstanced(ID3D12Grap + instance_count, start_vertex_location, base_vertex_location, start_instance_location)); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_Dispatch(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_Dispatch(ID3D12GraphicsCommandList5 *iface, + UINT x, UINT y, UINT z) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); + const struct vkd3d_vk_device_procs *vk_procs; + + TRACE("iface %p, x %u, y %u, z %u.\n", iface, x, y, z); +@@ -3460,10 +3461,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_Dispatch(ID3D12GraphicsCommandL + VK_CALL(vkCmdDispatch(list->vk_command_buffer, x, y, z)); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_CopyBufferRegion(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_CopyBufferRegion(ID3D12GraphicsCommandList5 *iface, + ID3D12Resource *dst, UINT64 dst_offset, ID3D12Resource *src, UINT64 src_offset, UINT64 byte_count) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); + struct d3d12_resource *dst_resource, *src_resource; + const struct vkd3d_vk_device_procs *vk_procs; + VkBufferCopy buffer_copy; +@@ -3745,11 +3746,11 @@ static bool validate_d3d12_box(const D3D12_BOX *box) + && box->back > box->front; + } + +-static void STDMETHODCALLTYPE d3d12_command_list_CopyTextureRegion(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_CopyTextureRegion(ID3D12GraphicsCommandList5 *iface, + const D3D12_TEXTURE_COPY_LOCATION *dst, UINT dst_x, UINT dst_y, UINT dst_z, + const D3D12_TEXTURE_COPY_LOCATION *src, const D3D12_BOX *src_box) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); + struct d3d12_resource *dst_resource, *src_resource; + const struct vkd3d_format *src_format, *dst_format; + const struct vkd3d_vk_device_procs *vk_procs; +@@ -3870,10 +3871,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_CopyTextureRegion(ID3D12Graphic + } + } + +-static void STDMETHODCALLTYPE d3d12_command_list_CopyResource(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_CopyResource(ID3D12GraphicsCommandList5 *iface, + ID3D12Resource *dst, ID3D12Resource *src) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); + struct d3d12_resource *dst_resource, *src_resource; + const struct vkd3d_format *dst_format, *src_format; + const struct vkd3d_vk_device_procs *vk_procs; +@@ -3940,7 +3941,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_CopyResource(ID3D12GraphicsComm + } + } + +-static void STDMETHODCALLTYPE d3d12_command_list_CopyTiles(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_CopyTiles(ID3D12GraphicsCommandList5 *iface, + ID3D12Resource *tiled_resource, const D3D12_TILED_RESOURCE_COORDINATE *tile_region_start_coordinate, + const D3D12_TILE_REGION_SIZE *tile_region_size, ID3D12Resource *buffer, UINT64 buffer_offset, + D3D12_TILE_COPY_FLAGS flags) +@@ -3951,11 +3952,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_CopyTiles(ID3D12GraphicsCommand + buffer, buffer_offset, flags); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_ResolveSubresource(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_ResolveSubresource(ID3D12GraphicsCommandList5 *iface, + ID3D12Resource *dst, UINT dst_sub_resource_idx, + ID3D12Resource *src, UINT src_sub_resource_idx, DXGI_FORMAT format) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); + const struct vkd3d_format *src_format, *dst_format, *vk_format; + struct d3d12_resource *dst_resource, *src_resource; + const struct vkd3d_vk_device_procs *vk_procs; +@@ -4018,10 +4019,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_ResolveSubresource(ID3D12Graphi + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &vk_image_resolve)); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_IASetPrimitiveTopology(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_IASetPrimitiveTopology(ID3D12GraphicsCommandList5 *iface, + D3D12_PRIMITIVE_TOPOLOGY topology) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); + + TRACE("iface %p, topology %#x.\n", iface, topology); + +@@ -4032,11 +4033,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_IASetPrimitiveTopology(ID3D12Gr + d3d12_command_list_invalidate_current_pipeline(list); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_RSSetViewports(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_RSSetViewports(ID3D12GraphicsCommandList5 *iface, + UINT viewport_count, const D3D12_VIEWPORT *viewports) + { + VkViewport vk_viewports[D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE]; +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); + const struct vkd3d_vk_device_procs *vk_procs; + unsigned int i; + +@@ -4070,10 +4071,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_RSSetViewports(ID3D12GraphicsCo + VK_CALL(vkCmdSetViewport(list->vk_command_buffer, 0, viewport_count, vk_viewports)); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_RSSetScissorRects(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_RSSetScissorRects(ID3D12GraphicsCommandList5 *iface, + UINT rect_count, const D3D12_RECT *rects) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); + VkRect2D vk_rects[D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE]; + const struct vkd3d_vk_device_procs *vk_procs; + unsigned int i; +@@ -4098,10 +4099,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_RSSetScissorRects(ID3D12Graphic + VK_CALL(vkCmdSetScissor(list->vk_command_buffer, 0, rect_count, vk_rects)); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_OMSetBlendFactor(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_OMSetBlendFactor(ID3D12GraphicsCommandList5 *iface, + const FLOAT blend_factor[4]) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); + const struct vkd3d_vk_device_procs *vk_procs; + + TRACE("iface %p, blend_factor %p.\n", iface, blend_factor); +@@ -4110,10 +4111,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_OMSetBlendFactor(ID3D12Graphics + VK_CALL(vkCmdSetBlendConstants(list->vk_command_buffer, blend_factor)); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_OMSetStencilRef(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_OMSetStencilRef(ID3D12GraphicsCommandList5 *iface, + UINT stencil_ref) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); + const struct vkd3d_vk_device_procs *vk_procs; + + TRACE("iface %p, stencil_ref %u.\n", iface, stencil_ref); +@@ -4122,11 +4123,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_OMSetStencilRef(ID3D12GraphicsC + VK_CALL(vkCmdSetStencilReference(list->vk_command_buffer, VK_STENCIL_FRONT_AND_BACK, stencil_ref)); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_SetPipelineState(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_SetPipelineState(ID3D12GraphicsCommandList5 *iface, + ID3D12PipelineState *pipeline_state) + { + struct d3d12_pipeline_state *state = unsafe_impl_from_ID3D12PipelineState(pipeline_state); +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); + + TRACE("iface %p, pipeline_state %p.\n", iface, pipeline_state); + +@@ -4177,10 +4178,10 @@ static unsigned int d3d12_find_ds_multiplanar_transition(const D3D12_RESOURCE_BA + return 0; + } + +-static void STDMETHODCALLTYPE d3d12_command_list_ResourceBarrier(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_ResourceBarrier(ID3D12GraphicsCommandList5 *iface, + UINT barrier_count, const D3D12_RESOURCE_BARRIER *barriers) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); + bool have_aliasing_barriers = false, have_split_barriers = false; + const struct vkd3d_vk_device_procs *vk_procs; + const struct vkd3d_vulkan_info *vk_info; +@@ -4403,13 +4404,13 @@ static void STDMETHODCALLTYPE d3d12_command_list_ResourceBarrier(ID3D12GraphicsC + WARN("Issuing split barrier(s) on D3D12_RESOURCE_BARRIER_FLAG_END_ONLY.\n"); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_ExecuteBundle(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_ExecuteBundle(ID3D12GraphicsCommandList5 *iface, + ID3D12GraphicsCommandList *command_list) + { + FIXME("iface %p, command_list %p stub!\n", iface, command_list); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_SetDescriptorHeaps(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_SetDescriptorHeaps(ID3D12GraphicsCommandList5 *iface, + UINT heap_count, ID3D12DescriptorHeap *const *heaps) + { + TRACE("iface %p, heap_count %u, heaps %p.\n", iface, heap_count, heaps); +@@ -4435,10 +4436,10 @@ static void d3d12_command_list_set_root_signature(struct d3d12_command_list *lis + d3d12_command_list_invalidate_root_parameters(list, bind_point); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootSignature(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootSignature(ID3D12GraphicsCommandList5 *iface, + ID3D12RootSignature *root_signature) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); + + TRACE("iface %p, root_signature %p.\n", iface, root_signature); + +@@ -4446,10 +4447,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootSignature(ID3D12G + unsafe_impl_from_ID3D12RootSignature(root_signature)); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootSignature(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootSignature(ID3D12GraphicsCommandList5 *iface, + ID3D12RootSignature *root_signature) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); + + TRACE("iface %p, root_signature %p.\n", iface, root_signature); + +@@ -4488,10 +4489,10 @@ static void d3d12_command_list_set_descriptor_table(struct d3d12_command_list *l + bindings->descriptor_table_active_mask |= (uint64_t)1 << index; + } + +-static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootDescriptorTable(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootDescriptorTable(ID3D12GraphicsCommandList5 *iface, + UINT root_parameter_index, D3D12_GPU_DESCRIPTOR_HANDLE base_descriptor) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); + + TRACE("iface %p, root_parameter_index %u, base_descriptor %#"PRIx64".\n", + iface, root_parameter_index, base_descriptor.ptr); +@@ -4500,10 +4501,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootDescriptorTable(I + root_parameter_index, base_descriptor); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootDescriptorTable(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootDescriptorTable(ID3D12GraphicsCommandList5 *iface, + UINT root_parameter_index, D3D12_GPU_DESCRIPTOR_HANDLE base_descriptor) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); + + TRACE("iface %p, root_parameter_index %u, base_descriptor %#"PRIx64".\n", + iface, root_parameter_index, base_descriptor.ptr); +@@ -4525,10 +4526,10 @@ static void d3d12_command_list_set_root_constants(struct d3d12_command_list *lis + c->stage_flags, c->offset + offset * sizeof(uint32_t), count * sizeof(uint32_t), data)); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRoot32BitConstant(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRoot32BitConstant(ID3D12GraphicsCommandList5 *iface, + UINT root_parameter_index, UINT data, UINT dst_offset) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); + + TRACE("iface %p, root_parameter_index %u, data 0x%08x, dst_offset %u.\n", + iface, root_parameter_index, data, dst_offset); +@@ -4537,10 +4538,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRoot32BitConstant(ID3 + root_parameter_index, dst_offset, 1, &data); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRoot32BitConstant(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRoot32BitConstant(ID3D12GraphicsCommandList5 *iface, + UINT root_parameter_index, UINT data, UINT dst_offset) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); + + TRACE("iface %p, root_parameter_index %u, data 0x%08x, dst_offset %u.\n", + iface, root_parameter_index, data, dst_offset); +@@ -4549,10 +4550,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRoot32BitConstant(ID + root_parameter_index, dst_offset, 1, &data); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRoot32BitConstants(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRoot32BitConstants(ID3D12GraphicsCommandList5 *iface, + UINT root_parameter_index, UINT constant_count, const void *data, UINT dst_offset) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); + + TRACE("iface %p, root_parameter_index %u, constant_count %u, data %p, dst_offset %u.\n", + iface, root_parameter_index, constant_count, data, dst_offset); +@@ -4561,10 +4562,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRoot32BitConstants(ID + root_parameter_index, dst_offset, constant_count, data); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRoot32BitConstants(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRoot32BitConstants(ID3D12GraphicsCommandList5 *iface, + UINT root_parameter_index, UINT constant_count, const void *data, UINT dst_offset) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); + + TRACE("iface %p, root_parameter_index %u, constant_count %u, data %p, dst_offset %u.\n", + iface, root_parameter_index, constant_count, data, dst_offset); +@@ -4626,9 +4627,9 @@ static void d3d12_command_list_set_root_cbv(struct d3d12_command_list *list, + } + + static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootConstantBufferView( +- ID3D12GraphicsCommandList4 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address) ++ ID3D12GraphicsCommandList5 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); + + TRACE("iface %p, root_parameter_index %u, address %#"PRIx64".\n", + iface, root_parameter_index, address); +@@ -4637,9 +4638,9 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootConstantBufferVie + } + + static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootConstantBufferView( +- ID3D12GraphicsCommandList4 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address) ++ ID3D12GraphicsCommandList5 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); + + TRACE("iface %p, root_parameter_index %u, address %#"PRIx64".\n", + iface, root_parameter_index, address); +@@ -4698,9 +4699,9 @@ static void d3d12_command_list_set_root_descriptor(struct d3d12_command_list *li + } + + static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootShaderResourceView( +- ID3D12GraphicsCommandList4 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address) ++ ID3D12GraphicsCommandList5 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); + + TRACE("iface %p, root_parameter_index %u, address %#"PRIx64".\n", + iface, root_parameter_index, address); +@@ -4710,9 +4711,9 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootShaderResourceVie + } + + static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootShaderResourceView( +- ID3D12GraphicsCommandList4 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address) ++ ID3D12GraphicsCommandList5 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); + + TRACE("iface %p, root_parameter_index %u, address %#"PRIx64".\n", + iface, root_parameter_index, address); +@@ -4722,9 +4723,9 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootShaderResourceVi + } + + static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootUnorderedAccessView( +- ID3D12GraphicsCommandList4 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address) ++ ID3D12GraphicsCommandList5 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); + + TRACE("iface %p, root_parameter_index %u, address %#"PRIx64".\n", + iface, root_parameter_index, address); +@@ -4734,9 +4735,9 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootUnorderedAccessVi + } + + static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootUnorderedAccessView( +- ID3D12GraphicsCommandList4 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address) ++ ID3D12GraphicsCommandList5 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); + + TRACE("iface %p, root_parameter_index %u, address %#"PRIx64".\n", + iface, root_parameter_index, address); +@@ -4745,10 +4746,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootUnorderedAccessV + root_parameter_index, address); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_IASetIndexBuffer(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_IASetIndexBuffer(ID3D12GraphicsCommandList5 *iface, + const D3D12_INDEX_BUFFER_VIEW *view) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); + const struct vkd3d_vk_device_procs *vk_procs; + struct d3d12_resource *resource; + enum VkIndexType index_type; +@@ -4788,10 +4789,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_IASetIndexBuffer(ID3D12Graphics + view->BufferLocation - resource->gpu_address, index_type)); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_IASetVertexBuffers(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_IASetVertexBuffers(ID3D12GraphicsCommandList5 *iface, + UINT start_slot, UINT view_count, const D3D12_VERTEX_BUFFER_VIEW *views) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); + const struct vkd3d_null_resources *null_resources; + struct vkd3d_gpu_va_allocator *gpu_va_allocator; + VkDeviceSize offsets[ARRAY_SIZE(list->strides)]; +@@ -4846,10 +4847,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_IASetVertexBuffers(ID3D12Graphi + d3d12_command_list_invalidate_current_pipeline(list); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_SOSetTargets(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_SOSetTargets(ID3D12GraphicsCommandList5 *iface, + UINT start_slot, UINT view_count, const D3D12_STREAM_OUTPUT_BUFFER_VIEW *views) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); + VkDeviceSize offsets[ARRAY_SIZE(list->so_counter_buffers)]; + VkDeviceSize sizes[ARRAY_SIZE(list->so_counter_buffers)]; + VkBuffer buffers[ARRAY_SIZE(list->so_counter_buffers)]; +@@ -4911,11 +4912,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_SOSetTargets(ID3D12GraphicsComm + VK_CALL(vkCmdBindTransformFeedbackBuffersEXT(list->vk_command_buffer, first, count, buffers, offsets, sizes)); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_OMSetRenderTargets(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_OMSetRenderTargets(ID3D12GraphicsCommandList5 *iface, + UINT render_target_descriptor_count, const D3D12_CPU_DESCRIPTOR_HANDLE *render_target_descriptors, + BOOL single_descriptor_handle, const D3D12_CPU_DESCRIPTOR_HANDLE *depth_stencil_descriptor) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); + const struct d3d12_rtv_desc *rtv_desc; + const struct d3d12_dsv_desc *dsv_desc; + VkFormat prev_dsv_format; +@@ -5116,12 +5117,12 @@ static void d3d12_command_list_clear(struct d3d12_command_list *list, + } + } + +-static void STDMETHODCALLTYPE d3d12_command_list_ClearDepthStencilView(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_ClearDepthStencilView(ID3D12GraphicsCommandList5 *iface, + D3D12_CPU_DESCRIPTOR_HANDLE dsv, D3D12_CLEAR_FLAGS flags, float depth, UINT8 stencil, + UINT rect_count, const D3D12_RECT *rects) + { + const union VkClearValue clear_value = {.depthStencil = {depth, stencil}}; +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); + const struct d3d12_dsv_desc *dsv_desc = d3d12_dsv_desc_from_cpu_handle(dsv); + struct VkAttachmentDescription attachment_desc; + struct VkAttachmentReference ds_reference; +@@ -5165,10 +5166,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearDepthStencilView(ID3D12Gra + &clear_value, rect_count, rects); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_ClearRenderTargetView(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_ClearRenderTargetView(ID3D12GraphicsCommandList5 *iface, + D3D12_CPU_DESCRIPTOR_HANDLE rtv, const FLOAT color[4], UINT rect_count, const D3D12_RECT *rects) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); + const struct d3d12_rtv_desc *rtv_desc = d3d12_rtv_desc_from_cpu_handle(rtv); + struct VkAttachmentDescription attachment_desc; + struct VkAttachmentReference color_reference; +@@ -5413,11 +5414,11 @@ static const struct vkd3d_format *vkd3d_fixup_clear_uav_uint_colour(struct d3d12 + } + } + +-static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewUint(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewUint(ID3D12GraphicsCommandList5 *iface, + D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle, D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle, ID3D12Resource *resource, + const UINT values[4], UINT rect_count, const D3D12_RECT *rects) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); + struct vkd3d_view *descriptor, *uint_view = NULL; + struct d3d12_device *device = list->device; + struct vkd3d_texture_view_desc view_desc; +@@ -5481,11 +5482,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewUint(ID + vkd3d_view_decref(uint_view, device); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewFloat(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewFloat(ID3D12GraphicsCommandList5 *iface, + D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle, D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle, ID3D12Resource *resource, + const float values[4], UINT rect_count, const D3D12_RECT *rects) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); + struct d3d12_resource *resource_impl; + VkClearColorValue colour; + struct vkd3d_view *view; +@@ -5501,16 +5502,16 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewFloat(I + d3d12_command_list_clear_uav(list, resource_impl, view, &colour, rect_count, rects); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_DiscardResource(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_DiscardResource(ID3D12GraphicsCommandList5 *iface, + ID3D12Resource *resource, const D3D12_DISCARD_REGION *region) + { + FIXME_ONCE("iface %p, resource %p, region %p stub!\n", iface, resource, region); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_BeginQuery(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_BeginQuery(ID3D12GraphicsCommandList5 *iface, + ID3D12QueryHeap *heap, D3D12_QUERY_TYPE type, UINT index) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); + struct d3d12_query_heap *query_heap = unsafe_impl_from_ID3D12QueryHeap(heap); + const struct vkd3d_vk_device_procs *vk_procs; + VkQueryControlFlags flags = 0; +@@ -5537,10 +5538,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_BeginQuery(ID3D12GraphicsComman + VK_CALL(vkCmdBeginQuery(list->vk_command_buffer, query_heap->vk_query_pool, index, flags)); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_EndQuery(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_EndQuery(ID3D12GraphicsCommandList5 *iface, + ID3D12QueryHeap *heap, D3D12_QUERY_TYPE type, UINT index) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); + struct d3d12_query_heap *query_heap = unsafe_impl_from_ID3D12QueryHeap(heap); + const struct vkd3d_vk_device_procs *vk_procs; + +@@ -5582,12 +5583,12 @@ static size_t get_query_stride(D3D12_QUERY_TYPE type) + return sizeof(uint64_t); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_ResolveQueryData(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_ResolveQueryData(ID3D12GraphicsCommandList5 *iface, + ID3D12QueryHeap *heap, D3D12_QUERY_TYPE type, UINT start_index, UINT query_count, + ID3D12Resource *dst_buffer, UINT64 aligned_dst_buffer_offset) + { + const struct d3d12_query_heap *query_heap = unsafe_impl_from_ID3D12QueryHeap(heap); +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); + struct d3d12_resource *buffer = unsafe_impl_from_ID3D12Resource(dst_buffer); + const struct vkd3d_vk_device_procs *vk_procs; + unsigned int i, first, count; +@@ -5663,10 +5664,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_ResolveQueryData(ID3D12Graphics + } + } + +-static void STDMETHODCALLTYPE d3d12_command_list_SetPredication(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_SetPredication(ID3D12GraphicsCommandList5 *iface, + ID3D12Resource *buffer, UINT64 aligned_buffer_offset, D3D12_PREDICATION_OP operation) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); + struct d3d12_resource *resource = unsafe_impl_from_ID3D12Resource(buffer); + const struct vkd3d_vulkan_info *vk_info = &list->device->vk_info; + const struct vkd3d_vk_device_procs *vk_procs; +@@ -5735,19 +5736,19 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetPredication(ID3D12GraphicsCo + } + } + +-static void STDMETHODCALLTYPE d3d12_command_list_SetMarker(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_SetMarker(ID3D12GraphicsCommandList5 *iface, + UINT metadata, const void *data, UINT size) + { + FIXME("iface %p, metadata %#x, data %p, size %u stub!\n", iface, metadata, data, size); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_BeginEvent(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_BeginEvent(ID3D12GraphicsCommandList5 *iface, + UINT metadata, const void *data, UINT size) + { + FIXME("iface %p, metadata %#x, data %p, size %u stub!\n", iface, metadata, data, size); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_EndEvent(ID3D12GraphicsCommandList4 *iface) ++static void STDMETHODCALLTYPE d3d12_command_list_EndEvent(ID3D12GraphicsCommandList5 *iface) + { + FIXME("iface %p stub!\n", iface); + } +@@ -5756,14 +5757,14 @@ STATIC_ASSERT(sizeof(VkDispatchIndirectCommand) == sizeof(D3D12_DISPATCH_ARGUMEN + STATIC_ASSERT(sizeof(VkDrawIndexedIndirectCommand) == sizeof(D3D12_DRAW_INDEXED_ARGUMENTS)); + STATIC_ASSERT(sizeof(VkDrawIndirectCommand) == sizeof(D3D12_DRAW_ARGUMENTS)); + +-static void STDMETHODCALLTYPE d3d12_command_list_ExecuteIndirect(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_ExecuteIndirect(ID3D12GraphicsCommandList5 *iface, + ID3D12CommandSignature *command_signature, UINT max_command_count, ID3D12Resource *arg_buffer, + UINT64 arg_buffer_offset, ID3D12Resource *count_buffer, UINT64 count_buffer_offset) + { + struct d3d12_command_signature *sig_impl = unsafe_impl_from_ID3D12CommandSignature(command_signature); + struct d3d12_resource *count_impl = unsafe_impl_from_ID3D12Resource(count_buffer); + struct d3d12_resource *arg_impl = unsafe_impl_from_ID3D12Resource(arg_buffer); +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); + const D3D12_COMMAND_SIGNATURE_DESC *signature_desc; + const struct vkd3d_vk_device_procs *vk_procs; + unsigned int i; +@@ -5862,7 +5863,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_ExecuteIndirect(ID3D12GraphicsC + d3d12_command_signature_decref(sig_impl); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_AtomicCopyBufferUINT(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_AtomicCopyBufferUINT(ID3D12GraphicsCommandList5 *iface, + ID3D12Resource *dst_buffer, UINT64 dst_offset, + ID3D12Resource *src_buffer, UINT64 src_offset, + UINT dependent_resource_count, ID3D12Resource * const *dependent_resources, +@@ -5875,7 +5876,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_AtomicCopyBufferUINT(ID3D12Grap + dependent_resource_count, dependent_resources, dependent_sub_resource_ranges); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_AtomicCopyBufferUINT64(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_AtomicCopyBufferUINT64(ID3D12GraphicsCommandList5 *iface, + ID3D12Resource *dst_buffer, UINT64 dst_offset, + ID3D12Resource *src_buffer, UINT64 src_offset, + UINT dependent_resource_count, ID3D12Resource * const *dependent_resources, +@@ -5888,20 +5889,20 @@ static void STDMETHODCALLTYPE d3d12_command_list_AtomicCopyBufferUINT64(ID3D12Gr + dependent_resource_count, dependent_resources, dependent_sub_resource_ranges); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_OMSetDepthBounds(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_OMSetDepthBounds(ID3D12GraphicsCommandList5 *iface, + FLOAT min, FLOAT max) + { + FIXME("iface %p, min %.8e, max %.8e stub!\n", iface, min, max); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_SetSamplePositions(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_SetSamplePositions(ID3D12GraphicsCommandList5 *iface, + UINT sample_count, UINT pixel_count, D3D12_SAMPLE_POSITION *sample_positions) + { + FIXME("iface %p, sample_count %u, pixel_count %u, sample_positions %p stub!\n", + iface, sample_count, pixel_count, sample_positions); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_ResolveSubresourceRegion(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_ResolveSubresourceRegion(ID3D12GraphicsCommandList5 *iface, + ID3D12Resource *dst_resource, UINT dst_sub_resource_idx, UINT dst_x, UINT dst_y, + ID3D12Resource *src_resource, UINT src_sub_resource_idx, + D3D12_RECT *src_rect, DXGI_FORMAT format, D3D12_RESOLVE_MODE mode) +@@ -5913,16 +5914,16 @@ static void STDMETHODCALLTYPE d3d12_command_list_ResolveSubresourceRegion(ID3D12 + src_resource, src_sub_resource_idx, src_rect, format, mode); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_SetViewInstanceMask(ID3D12GraphicsCommandList4 *iface, UINT mask) ++static void STDMETHODCALLTYPE d3d12_command_list_SetViewInstanceMask(ID3D12GraphicsCommandList5 *iface, UINT mask) + { + FIXME("iface %p, mask %#x stub!\n", iface, mask); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_WriteBufferImmediate(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_WriteBufferImmediate(ID3D12GraphicsCommandList5 *iface, + UINT count, const D3D12_WRITEBUFFERIMMEDIATE_PARAMETER *parameters, + const D3D12_WRITEBUFFERIMMEDIATE_MODE *modes) + { +- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList4(iface); ++ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); + struct d3d12_resource *resource; + unsigned int i; + +@@ -5935,13 +5936,13 @@ static void STDMETHODCALLTYPE d3d12_command_list_WriteBufferImmediate(ID3D12Grap + } + } + +-static void STDMETHODCALLTYPE d3d12_command_list_SetProtectedResourceSession(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_SetProtectedResourceSession(ID3D12GraphicsCommandList5 *iface, + ID3D12ProtectedResourceSession *protected_session) + { + FIXME("iface %p, protected_session %p stub!\n", iface, protected_session); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_BeginRenderPass(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_BeginRenderPass(ID3D12GraphicsCommandList5 *iface, + UINT count, const D3D12_RENDER_PASS_RENDER_TARGET_DESC *render_targets, + const D3D12_RENDER_PASS_DEPTH_STENCIL_DESC *depth_stencil, D3D12_RENDER_PASS_FLAGS flags) + { +@@ -5949,33 +5950,33 @@ static void STDMETHODCALLTYPE d3d12_command_list_BeginRenderPass(ID3D12GraphicsC + count, render_targets, depth_stencil, flags); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_EndRenderPass(ID3D12GraphicsCommandList4 *iface) ++static void STDMETHODCALLTYPE d3d12_command_list_EndRenderPass(ID3D12GraphicsCommandList5 *iface) + { + FIXME("iface %p stub!\n", iface); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_InitializeMetaCommand(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_InitializeMetaCommand(ID3D12GraphicsCommandList5 *iface, + ID3D12MetaCommand *meta_command, const void *parameters_data, SIZE_T data_size_in_bytes) + { + FIXME("iface %p, meta_command %p, parameters_data %p, data_size_in_bytes %lu stub!\n", iface, + meta_command, parameters_data, data_size_in_bytes); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_ExecuteMetaCommand(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_ExecuteMetaCommand(ID3D12GraphicsCommandList5 *iface, + ID3D12MetaCommand *meta_command, const void *parameters_data, SIZE_T data_size_in_bytes) + { + FIXME("iface %p, meta_command %p, parameters_data %p, data_size_in_bytes %lu stub!\n", iface, + meta_command, parameters_data, data_size_in_bytes); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_BuildRaytracingAccelerationStructure(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_BuildRaytracingAccelerationStructure(ID3D12GraphicsCommandList5 *iface, + const D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_DESC *desc, UINT count, + const D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_DESC *postbuild_info_descs) + { + FIXME("iface %p, desc %p, count %u, postbuild_info_descs %p stub!\n", iface, desc, count, postbuild_info_descs); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_EmitRaytracingAccelerationStructurePostbuildInfo(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_EmitRaytracingAccelerationStructurePostbuildInfo(ID3D12GraphicsCommandList5 *iface, + const D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_DESC *desc, + UINT structures_count, const D3D12_GPU_VIRTUAL_ADDRESS *src_structure_data) + { +@@ -5983,7 +5984,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_EmitRaytracingAccelerationStruc + iface, desc, structures_count, src_structure_data); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_CopyRaytracingAccelerationStructure(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_CopyRaytracingAccelerationStructure(ID3D12GraphicsCommandList5 *iface, + D3D12_GPU_VIRTUAL_ADDRESS dst_structure_data, + D3D12_GPU_VIRTUAL_ADDRESS src_structure_data, + D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE mode) +@@ -5992,19 +5993,31 @@ static void STDMETHODCALLTYPE d3d12_command_list_CopyRaytracingAccelerationStruc + iface, dst_structure_data, src_structure_data, mode); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_SetPipelineState1(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_SetPipelineState1(ID3D12GraphicsCommandList5 *iface, + ID3D12StateObject *state_object) + { + FIXME("iface %p, state_object %p stub!\n", iface, state_object); + } + +-static void STDMETHODCALLTYPE d3d12_command_list_DispatchRays(ID3D12GraphicsCommandList4 *iface, ++static void STDMETHODCALLTYPE d3d12_command_list_DispatchRays(ID3D12GraphicsCommandList5 *iface, + const D3D12_DISPATCH_RAYS_DESC *desc) + { + FIXME("iface %p, desc %p stub!\n", iface, desc); + } + +-static const struct ID3D12GraphicsCommandList4Vtbl d3d12_command_list_vtbl = ++static void STDMETHODCALLTYPE d3d12_command_list_RSSetShadingRate(ID3D12GraphicsCommandList5 *iface, ++ D3D12_SHADING_RATE rate, const D3D12_SHADING_RATE_COMBINER *combiners) ++{ ++ FIXME("iface %p, rate %#x, combiners %p stub!\n", iface, rate, combiners); ++} ++ ++static void STDMETHODCALLTYPE d3d12_command_list_RSSetShadingRateImage(ID3D12GraphicsCommandList5 *iface, ++ ID3D12Resource *rate_image) ++{ ++ FIXME("iface %p, rate_image %p stub!\n", iface, rate_image); ++} ++ ++static const struct ID3D12GraphicsCommandList5Vtbl d3d12_command_list_vtbl = + { + /* IUnknown methods */ + d3d12_command_list_QueryInterface, +@@ -6092,6 +6105,9 @@ static const struct ID3D12GraphicsCommandList4Vtbl d3d12_command_list_vtbl = + d3d12_command_list_CopyRaytracingAccelerationStructure, + d3d12_command_list_SetPipelineState1, + d3d12_command_list_DispatchRays, ++ /* ID3D12GraphicsCommandList5 methods */ ++ d3d12_command_list_RSSetShadingRate, ++ d3d12_command_list_RSSetShadingRateImage, + }; + + static struct d3d12_command_list *unsafe_impl_from_ID3D12CommandList(ID3D12CommandList *iface) +@@ -6099,7 +6115,7 @@ static struct d3d12_command_list *unsafe_impl_from_ID3D12CommandList(ID3D12Comma + if (!iface) + return NULL; + assert(iface->lpVtbl == (struct ID3D12CommandListVtbl *)&d3d12_command_list_vtbl); +- return CONTAINING_RECORD(iface, struct d3d12_command_list, ID3D12GraphicsCommandList4_iface); ++ return CONTAINING_RECORD(iface, struct d3d12_command_list, ID3D12GraphicsCommandList5_iface); + } + + static HRESULT d3d12_command_list_init(struct d3d12_command_list *list, struct d3d12_device *device, +@@ -6108,7 +6124,7 @@ static HRESULT d3d12_command_list_init(struct d3d12_command_list *list, struct d + { + HRESULT hr; + +- list->ID3D12GraphicsCommandList4_iface.lpVtbl = &d3d12_command_list_vtbl; ++ list->ID3D12GraphicsCommandList5_iface.lpVtbl = &d3d12_command_list_vtbl; + list->refcount = 1; + + list->type = type; +diff --git a/libs/vkd3d/libs/vkd3d/device.c b/libs/vkd3d/libs/vkd3d/device.c +index 6ff298741f8..3e17400a78a 100644 +--- a/libs/vkd3d/libs/vkd3d/device.c ++++ b/libs/vkd3d/libs/vkd3d/device.c +@@ -2667,8 +2667,8 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandList(ID3D12Device5 *i + initial_pipeline_state, &object))) + return hr; + +- return return_interface(&object->ID3D12GraphicsCommandList4_iface, +- &IID_ID3D12GraphicsCommandList4, riid, command_list); ++ return return_interface(&object->ID3D12GraphicsCommandList5_iface, ++ &IID_ID3D12GraphicsCommandList5, riid, command_list); + } + + /* Direct3D feature levels restrict which formats can be optionally supported. */ +@@ -3645,7 +3645,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateHeap(ID3D12Device5 *iface, + TRACE("iface %p, desc %p, iid %s, heap %p.\n", + iface, desc, debugstr_guid(iid), heap); + +- if (FAILED(hr = d3d12_heap_create(device, desc, NULL, &object))) ++ if (FAILED(hr = d3d12_heap_create(device, desc, NULL, NULL, &object))) + { + *heap = NULL; + return hr; +@@ -4024,10 +4024,20 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateHeap1(ID3D12Device5 *iface, + const D3D12_HEAP_DESC *desc, ID3D12ProtectedResourceSession *protected_session, + REFIID iid, void **heap) + { +- FIXME("iface %p, desc %p, protected_session %p, iid %s, heap %p stub!\n", ++ struct d3d12_device *device = impl_from_ID3D12Device5(iface); ++ struct d3d12_heap *object; ++ HRESULT hr; ++ ++ TRACE("iface %p, desc %p, protected_session %p, iid %s, heap %p.\n", + iface, desc, protected_session, debugstr_guid(iid), heap); + +- return E_NOTIMPL; ++ if (FAILED(hr = d3d12_heap_create(device, desc, NULL, protected_session, &object))) ++ { ++ *heap = NULL; ++ return hr; ++ } ++ ++ return return_interface(&object->ID3D12Heap_iface, &IID_ID3D12Heap, iid, heap); + } + + static HRESULT STDMETHODCALLTYPE d3d12_device_CreateReservedResource1(ID3D12Device5 *iface, +diff --git a/libs/vkd3d/libs/vkd3d/resource.c b/libs/vkd3d/libs/vkd3d/resource.c +index 14fb24a9c94..ad1d2d66692 100644 +--- a/libs/vkd3d/libs/vkd3d/resource.c ++++ b/libs/vkd3d/libs/vkd3d/resource.c +@@ -574,11 +574,15 @@ static HRESULT d3d12_heap_init(struct d3d12_heap *heap, + } + + HRESULT d3d12_heap_create(struct d3d12_device *device, const D3D12_HEAP_DESC *desc, +- const struct d3d12_resource *resource, struct d3d12_heap **heap) ++ const struct d3d12_resource *resource, ID3D12ProtectedResourceSession *protected_session, ++ struct d3d12_heap **heap) + { + struct d3d12_heap *object; + HRESULT hr; + ++ if (protected_session) ++ FIXME("Protected session is not supported.\n"); ++ + if (!(object = vkd3d_malloc(sizeof(*object)))) + return E_OUTOFMEMORY; + +@@ -2064,7 +2068,7 @@ static HRESULT vkd3d_allocate_resource_memory( + heap_desc.Properties = *heap_properties; + heap_desc.Alignment = 0; + heap_desc.Flags = heap_flags; +- if (SUCCEEDED(hr = d3d12_heap_create(device, &heap_desc, resource, &resource->heap))) ++ if (SUCCEEDED(hr = d3d12_heap_create(device, &heap_desc, resource, NULL, &resource->heap))) + resource->flags |= VKD3D_RESOURCE_DEDICATED_HEAP; + return hr; + } +diff --git a/libs/vkd3d/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/libs/vkd3d/vkd3d_private.h +index 6a9c8c657d1..625a43125c9 100644 +--- a/libs/vkd3d/libs/vkd3d/vkd3d_private.h ++++ b/libs/vkd3d/libs/vkd3d/vkd3d_private.h +@@ -682,7 +682,7 @@ struct d3d12_heap + }; + + HRESULT d3d12_heap_create(struct d3d12_device *device, const D3D12_HEAP_DESC *desc, +- const struct d3d12_resource *resource, struct d3d12_heap **heap); ++ const struct d3d12_resource *resource, ID3D12ProtectedResourceSession *protected_session, struct d3d12_heap **heap); + struct d3d12_heap *unsafe_impl_from_ID3D12Heap(ID3D12Heap *iface); + + #define VKD3D_RESOURCE_PUBLIC_FLAGS \ +@@ -1429,7 +1429,7 @@ enum vkd3d_pipeline_bind_point + /* ID3D12CommandList */ + struct d3d12_command_list + { +- ID3D12GraphicsCommandList4 ID3D12GraphicsCommandList4_iface; ++ ID3D12GraphicsCommandList5 ID3D12GraphicsCommandList5_iface; + LONG refcount; + + D3D12_COMMAND_LIST_TYPE type; +-- +2.42.0 +