diff --git a/patches/vkd3d-latest/0001-wined3d-rename-shader_extract_from_dxbc-to-wined3d_s.patch b/patches/vkd3d-latest/0001-wined3d-rename-shader_extract_from_dxbc-to-wined3d_s.patch index 3cd8988b..dc24c167 100644 --- a/patches/vkd3d-latest/0001-wined3d-rename-shader_extract_from_dxbc-to-wined3d_s.patch +++ b/patches/vkd3d-latest/0001-wined3d-rename-shader_extract_from_dxbc-to-wined3d_s.patch @@ -1,4 +1,4 @@ -From b349a2915750a5de22339a8bd12ec10ad35d61da Mon Sep 17 00:00:00 2001 +From 494b9575bff5b2f6a2225847752899af0860768f Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Wed, 17 May 2023 08:13:47 +1000 Subject: [PATCH 1/2] wined3d: rename shader_extract_from_dxbc to diff --git a/patches/vkd3d-latest/0002-Update-vkd3d-to-bb680e73de4ac22700ec89b1f466eea8da0a.patch b/patches/vkd3d-latest/0002-Updated-vkd3d-to-5dee6561c2a9aeeb951cc9786a8b28eebf8.patch similarity index 95% rename from patches/vkd3d-latest/0002-Update-vkd3d-to-bb680e73de4ac22700ec89b1f466eea8da0a.patch rename to patches/vkd3d-latest/0002-Updated-vkd3d-to-5dee6561c2a9aeeb951cc9786a8b28eebf8.patch index 7ebe4988..306b48fd 100644 --- a/patches/vkd3d-latest/0002-Update-vkd3d-to-bb680e73de4ac22700ec89b1f466eea8da0a.patch +++ b/patches/vkd3d-latest/0002-Updated-vkd3d-to-5dee6561c2a9aeeb951cc9786a8b28eebf8.patch @@ -1,7 +1,7 @@ -From d87f229d13f4b43a24a30f61fe55c6783e2b395d Mon Sep 17 00:00:00 2001 +From abf5cf7db7444633f69d579cbc73da58ccf73581 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Wed, 17 May 2023 08:35:40 +1000 -Subject: [PATCH 2/2] Update vkd3d to bb680e73de4ac22700ec89b1f466eea8da0a2120 +Subject: [PATCH 2/2] Updated vkd3d to 5dee6561c2a9aeeb951cc9786a8b28eebf8adc4d --- libs/vkd3d/Makefile.in | 6 +- @@ -17,29 +17,29 @@ Subject: [PATCH 2/2] Update vkd3d to bb680e73de4ac22700ec89b1f466eea8da0a2120 libs/vkd3d/include/vkd3d_windows.h | 284 + libs/vkd3d/libs/vkd3d-common/blob.c | 1 + libs/vkd3d/libs/vkd3d-common/debug.c | 4 +- - .../libs/vkd3d-shader/{trace.c => d3d_asm.c} | 23 +- + .../libs/vkd3d-shader/{trace.c => d3d_asm.c} | 25 +- libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 1121 +++- libs/vkd3d/libs/vkd3d-shader/dxbc.c | 1773 +----- - libs/vkd3d/libs/vkd3d-shader/hlsl.c | 551 +- - libs/vkd3d/libs/vkd3d-shader/hlsl.h | 220 +- + libs/vkd3d/libs/vkd3d-shader/hlsl.c | 617 +- + libs/vkd3d/libs/vkd3d-shader/hlsl.h | 229 +- libs/vkd3d/libs/vkd3d-shader/hlsl.l | 8 + - libs/vkd3d/libs/vkd3d-shader/hlsl.y | 2316 +++++--- - libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 1524 +++-- - .../libs/vkd3d-shader/hlsl_constant_ops.c | 289 +- - libs/vkd3d/libs/vkd3d-shader/hlsl_sm1.c | 980 ---- + libs/vkd3d/libs/vkd3d-shader/hlsl.y | 2355 +++++--- + libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 1802 ++++-- + .../libs/vkd3d-shader/hlsl_constant_ops.c | 358 +- + libs/vkd3d/libs/vkd3d-shader/hlsl_sm1.c | 980 --- libs/vkd3d/libs/vkd3d-shader/hlsl_sm4.c | 2531 -------- libs/vkd3d/libs/vkd3d-shader/ir.c | 1073 ++++ libs/vkd3d/libs/vkd3d-shader/preproc.h | 2 +- - libs/vkd3d/libs/vkd3d-shader/preproc.l | 7 +- + libs/vkd3d/libs/vkd3d-shader/preproc.l | 6 +- libs/vkd3d/libs/vkd3d-shader/spirv.c | 1311 ++--- - libs/vkd3d/libs/vkd3d-shader/tpf.c | 5219 +++++++++++++++++ + libs/vkd3d/libs/vkd3d-shader/tpf.c | 5234 +++++++++++++++++ .../libs/vkd3d-shader/vkd3d_shader_main.c | 241 +- .../libs/vkd3d-shader/vkd3d_shader_private.h | 91 +- libs/vkd3d/libs/vkd3d/command.c | 160 +- libs/vkd3d/libs/vkd3d/device.c | 205 +- libs/vkd3d/libs/vkd3d/resource.c | 935 ++- libs/vkd3d/libs/vkd3d/vkd3d_private.h | 238 +- - 35 files changed, 14192 insertions(+), 8695 deletions(-) + 35 files changed, 14574 insertions(+), 8790 deletions(-) create mode 100644 libs/vkd3d/include/list.h create mode 100644 libs/vkd3d/include/private/list.h create mode 100644 libs/vkd3d/include/private/rbtree.h @@ -2248,7 +2248,7 @@ diff --git a/libs/vkd3d/libs/vkd3d-shader/trace.c b/libs/vkd3d/libs/vkd3d-shader similarity index 98% rename from libs/vkd3d/libs/vkd3d-shader/trace.c rename to libs/vkd3d/libs/vkd3d-shader/d3d_asm.c -index 6cd2dcb270c..3357b4505c0 100644 +index 6cd2dcb270c..0a821b5c878 100644 --- a/libs/vkd3d/libs/vkd3d-shader/trace.c +++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c @@ -109,6 +109,7 @@ static const char * const shader_opcode_names[] = @@ -2259,6 +2259,15 @@ index 6cd2dcb270c..3357b4505c0 100644 [VKD3DSIH_DIV ] = "div", [VKD3DSIH_DLT ] = "dlt", [VKD3DSIH_DMAX ] = "dmax", +@@ -645,7 +646,7 @@ static void shader_dump_decl_usage(struct vkd3d_d3d_asm_compiler *compiler, + break; + + case VKD3D_SHADER_RESOURCE_TEXTURE_3D: +- shader_addline(buffer, "_3d"); ++ shader_addline(buffer, "_volume"); + break; + + case VKD3D_SHADER_RESOURCE_TEXTURE_CUBE: @@ -660,8 +661,9 @@ static void shader_dump_decl_usage(struct vkd3d_d3d_asm_compiler *compiler, else if (semantic->resource.reg.reg.type == VKD3DSPR_RESOURCE || semantic->resource.reg.reg.type == VKD3DSPR_UAV) { @@ -5455,7 +5464,7 @@ index d99ea2e36b6..3e3f06faeb5 100644 { put_u32(buffer, versioned_root_signature_get_parameter_type(desc, i)); diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c -index 64d6e87065b..5bca84ba38a 100644 +index 64d6e87065b..f439c9f3383 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c @@ -112,8 +112,12 @@ struct hlsl_ir_var *hlsl_get_var(struct hlsl_scope *scope, const char *name) @@ -5504,16 +5513,16 @@ index 64d6e87065b..5bca84ba38a 100644 -static unsigned int get_array_size(const struct hlsl_type *type) +const struct hlsl_type *hlsl_get_multiarray_element_type(const struct hlsl_type *type) - { -- if (type->type == HLSL_CLASS_ARRAY) -- return get_array_size(type->e.array.type) * type->e.array.elements_count; ++{ + if (type->class == HLSL_CLASS_ARRAY) + return hlsl_get_multiarray_element_type(type->e.array.type); + return type; +} + +unsigned int hlsl_get_multiarray_size(const struct hlsl_type *type) -+{ + { +- if (type->type == HLSL_CLASS_ARRAY) +- return get_array_size(type->e.array.type) * type->e.array.elements_count; + if (type->class == HLSL_CLASS_ARRAY) + return hlsl_get_multiarray_size(type->e.array.type) * type->e.array.elements_count; return 1; @@ -5991,7 +6000,14 @@ index 64d6e87065b..5bca84ba38a 100644 } struct hlsl_ir_node *hlsl_new_call(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *decl, -@@ -1050,7 +1151,7 @@ struct hlsl_ir_constant *hlsl_new_constant(struct hlsl_ctx *ctx, struct hlsl_typ +@@ -1045,66 +1146,54 @@ struct hlsl_ir_node *hlsl_new_call(struct hlsl_ctx *ctx, struct hlsl_ir_function + return &call->node; + } + +-struct hlsl_ir_constant *hlsl_new_constant(struct hlsl_ctx *ctx, struct hlsl_type *type, +- const struct vkd3d_shader_location *loc) ++struct hlsl_ir_node *hlsl_new_constant(struct hlsl_ctx *ctx, struct hlsl_type *type, ++ const struct hlsl_constant_value *value, const struct vkd3d_shader_location *loc) { struct hlsl_ir_constant *c; @@ -6000,71 +6016,79 @@ index 64d6e87065b..5bca84ba38a 100644 if (!(c = hlsl_alloc(ctx, sizeof(*c)))) return NULL; -@@ -1060,41 +1161,40 @@ struct hlsl_ir_constant *hlsl_new_constant(struct hlsl_ctx *ctx, struct hlsl_typ - return c; + + init_node(&c->node, HLSL_IR_CONSTANT, type, loc); ++ c->value = *value; + +- return c; ++ return &c->node; } -struct hlsl_ir_constant *hlsl_new_bool_constant(struct hlsl_ctx *ctx, bool b, const struct vkd3d_shader_location *loc) +struct hlsl_ir_node *hlsl_new_bool_constant(struct hlsl_ctx *ctx, bool b, const struct vkd3d_shader_location *loc) { - struct hlsl_ir_constant *c; - - if ((c = hlsl_new_constant(ctx, hlsl_get_scalar_type(ctx, HLSL_TYPE_BOOL), loc))) +- struct hlsl_ir_constant *c; +- +- if ((c = hlsl_new_constant(ctx, hlsl_get_scalar_type(ctx, HLSL_TYPE_BOOL), loc))) - c->value[0].u = b ? ~0u : 0; -+ c->value.u[0].u = b ? ~0u : 0; ++ struct hlsl_constant_value value; - return c; -+ return &c->node; ++ value.u[0].u = b ? ~0u : 0; ++ return hlsl_new_constant(ctx, hlsl_get_scalar_type(ctx, HLSL_TYPE_BOOL), &value, loc); } -struct hlsl_ir_constant *hlsl_new_float_constant(struct hlsl_ctx *ctx, float f, +struct hlsl_ir_node *hlsl_new_float_constant(struct hlsl_ctx *ctx, float f, const struct vkd3d_shader_location *loc) { - struct hlsl_ir_constant *c; +- struct hlsl_ir_constant *c; ++ struct hlsl_constant_value value; - if ((c = hlsl_new_constant(ctx, hlsl_get_scalar_type(ctx, HLSL_TYPE_FLOAT), loc))) +- if ((c = hlsl_new_constant(ctx, hlsl_get_scalar_type(ctx, HLSL_TYPE_FLOAT), loc))) - c->value[0].f = f; -+ c->value.u[0].f = f; - +- - return c; -+ return &c->node; ++ value.u[0].f = f; ++ return hlsl_new_constant(ctx, hlsl_get_scalar_type(ctx, HLSL_TYPE_FLOAT), &value, loc); } -struct hlsl_ir_constant *hlsl_new_int_constant(struct hlsl_ctx *ctx, int n, - const struct vkd3d_shader_location *loc) +struct hlsl_ir_node *hlsl_new_int_constant(struct hlsl_ctx *ctx, int32_t n, const struct vkd3d_shader_location *loc) { - struct hlsl_ir_constant *c; - - c = hlsl_new_constant(ctx, hlsl_get_scalar_type(ctx, HLSL_TYPE_INT), loc); - - if (c) +- struct hlsl_ir_constant *c; +- +- c = hlsl_new_constant(ctx, hlsl_get_scalar_type(ctx, HLSL_TYPE_INT), loc); +- +- if (c) - c->value[0].i = n; -+ c->value.u[0].i = n; ++ struct hlsl_constant_value value; - return c; -+ return &c->node; ++ value.u[0].i = n; ++ return hlsl_new_constant(ctx, hlsl_get_scalar_type(ctx, HLSL_TYPE_INT), &value, loc); } -struct hlsl_ir_constant *hlsl_new_uint_constant(struct hlsl_ctx *ctx, unsigned int n, +struct hlsl_ir_node *hlsl_new_uint_constant(struct hlsl_ctx *ctx, unsigned int n, const struct vkd3d_shader_location *loc) { - struct hlsl_ir_constant *c; -@@ -1102,9 +1202,9 @@ struct hlsl_ir_constant *hlsl_new_uint_constant(struct hlsl_ctx *ctx, unsigned i - c = hlsl_new_constant(ctx, hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), loc); +- struct hlsl_ir_constant *c; +- +- c = hlsl_new_constant(ctx, hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), loc); ++ struct hlsl_constant_value value; - if (c) +- if (c) - c->value[0].u = n; -+ c->value.u[0].u = n; - +- - return c; -+ return &c->node; ++ value.u[0].u = n; ++ return hlsl_new_constant(ctx, hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), &value, loc); } struct hlsl_ir_node *hlsl_new_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, -@@ -1124,11 +1224,11 @@ struct hlsl_ir_node *hlsl_new_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op +@@ -1124,11 +1213,11 @@ struct hlsl_ir_node *hlsl_new_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op } struct hlsl_ir_node *hlsl_new_unary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, @@ -6078,7 +6102,7 @@ index 64d6e87065b..5bca84ba38a 100644 } struct hlsl_ir_node *hlsl_new_binary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, -@@ -1140,17 +1240,21 @@ struct hlsl_ir_node *hlsl_new_binary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_exp +@@ -1140,17 +1229,21 @@ struct hlsl_ir_node *hlsl_new_binary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_exp return hlsl_new_expr(ctx, op, operands, arg1->data_type, &arg1->loc); } @@ -6105,9 +6129,23 @@ index 64d6e87065b..5bca84ba38a 100644 } struct hlsl_ir_load *hlsl_new_load_index(struct hlsl_ctx *ctx, const struct hlsl_deref *deref, -@@ -1184,22 +1288,22 @@ struct hlsl_ir_load *hlsl_new_load_index(struct hlsl_ctx *ctx, const struct hlsl +@@ -1183,23 +1276,36 @@ struct hlsl_ir_load *hlsl_new_load_index(struct hlsl_ctx *ctx, const struct hlsl + return load; } ++struct hlsl_ir_load *hlsl_new_load_parent(struct hlsl_ctx *ctx, const struct hlsl_deref *deref, ++ const struct vkd3d_shader_location *loc) ++{ ++ /* This deref can only exists temporarily because it is not the real owner of its members. */ ++ struct hlsl_deref tmp_deref; ++ ++ assert(deref->path_len >= 1); ++ ++ tmp_deref = *deref; ++ tmp_deref.path_len = deref->path_len - 1; ++ return hlsl_new_load_index(ctx, &tmp_deref, NULL, loc); ++} ++ struct hlsl_ir_load *hlsl_new_var_load(struct hlsl_ctx *ctx, struct hlsl_ir_var *var, - struct vkd3d_shader_location loc) + const struct vkd3d_shader_location *loc) @@ -6132,7 +6170,7 @@ index 64d6e87065b..5bca84ba38a 100644 if (!(load = hlsl_alloc(ctx, sizeof(*load)))) return NULL; -@@ -1213,14 +1317,14 @@ struct hlsl_ir_load *hlsl_new_load_component(struct hlsl_ctx *ctx, struct hlsl_b +@@ -1213,14 +1319,14 @@ struct hlsl_ir_load *hlsl_new_load_component(struct hlsl_ctx *ctx, struct hlsl_b vkd3d_free(load); return NULL; } @@ -6151,7 +6189,7 @@ index 64d6e87065b..5bca84ba38a 100644 const struct hlsl_resource_load_params *params, const struct vkd3d_shader_location *loc) { struct hlsl_ir_resource_load *load; -@@ -1229,24 +1333,36 @@ struct hlsl_ir_resource_load *hlsl_new_resource_load(struct hlsl_ctx *ctx, +@@ -1229,24 +1335,37 @@ struct hlsl_ir_resource_load *hlsl_new_resource_load(struct hlsl_ctx *ctx, return NULL; init_node(&load->node, HLSL_IR_RESOURCE_LOAD, params->format, loc); load->load_type = params->type; @@ -6184,6 +6222,7 @@ index 64d6e87065b..5bca84ba38a 100644 - return load; + hlsl_src_from_node(&load->ddx, params->ddx); + hlsl_src_from_node(&load->ddy, params->ddy); ++ hlsl_src_from_node(&load->cmp, params->cmp); + load->sampling_dim = params->sampling_dim; + if (load->sampling_dim == HLSL_SAMPLER_DIM_GENERIC) + load->sampling_dim = hlsl_deref_get_type(ctx, &load->resource)->sampler_dim; @@ -6195,7 +6234,7 @@ index 64d6e87065b..5bca84ba38a 100644 struct hlsl_ir_node *coords, struct hlsl_ir_node *value, const struct vkd3d_shader_location *loc) { struct hlsl_ir_resource_store *store; -@@ -1257,10 +1373,10 @@ struct hlsl_ir_resource_store *hlsl_new_resource_store(struct hlsl_ctx *ctx, con +@@ -1257,10 +1376,10 @@ struct hlsl_ir_resource_store *hlsl_new_resource_store(struct hlsl_ctx *ctx, con hlsl_copy_deref(ctx, &store->resource, resource); hlsl_src_from_node(&store->coords, coords); hlsl_src_from_node(&store->value, value); @@ -6208,7 +6247,7 @@ index 64d6e87065b..5bca84ba38a 100644 struct hlsl_ir_node *val, const struct vkd3d_shader_location *loc) { struct hlsl_ir_swizzle *swizzle; -@@ -1275,29 +1391,66 @@ struct hlsl_ir_swizzle *hlsl_new_swizzle(struct hlsl_ctx *ctx, DWORD s, unsigned +@@ -1275,29 +1394,66 @@ struct hlsl_ir_swizzle *hlsl_new_swizzle(struct hlsl_ctx *ctx, DWORD s, unsigned init_node(&swizzle->node, HLSL_IR_SWIZZLE, type, loc); hlsl_src_from_node(&swizzle->val, val); swizzle->swizzle = s; @@ -6283,7 +6322,7 @@ index 64d6e87065b..5bca84ba38a 100644 } struct clone_instr_map -@@ -1319,11 +1472,13 @@ static bool clone_block(struct hlsl_ctx *ctx, struct hlsl_block *dst_block, +@@ -1319,11 +1475,13 @@ static bool clone_block(struct hlsl_ctx *ctx, struct hlsl_block *dst_block, const struct hlsl_ir_node *src; struct hlsl_ir_node *dst; @@ -6298,7 +6337,7 @@ index 64d6e87065b..5bca84ba38a 100644 return false; } list_add_tail(&dst_block->instrs, &dst->entry); -@@ -1332,7 +1487,7 @@ static bool clone_block(struct hlsl_ctx *ctx, struct hlsl_block *dst_block, +@@ -1332,7 +1490,7 @@ static bool clone_block(struct hlsl_ctx *ctx, struct hlsl_block *dst_block, { if (!vkd3d_array_reserve((void **)&map->instrs, &map->capacity, map->count + 1, sizeof(*map->instrs))) { @@ -6307,16 +6346,21 @@ index 64d6e87065b..5bca84ba38a 100644 return false; } -@@ -1394,7 +1549,7 @@ static struct hlsl_ir_node *clone_constant(struct hlsl_ctx *ctx, struct hlsl_ir_ +@@ -1390,12 +1548,7 @@ static struct hlsl_ir_node *clone_call(struct hlsl_ctx *ctx, struct hlsl_ir_call - if (!(dst = hlsl_new_constant(ctx, src->node.data_type, &src->node.loc))) - return NULL; + static struct hlsl_ir_node *clone_constant(struct hlsl_ctx *ctx, struct hlsl_ir_constant *src) + { +- struct hlsl_ir_constant *dst; +- +- if (!(dst = hlsl_new_constant(ctx, src->node.data_type, &src->node.loc))) +- return NULL; - memcpy(dst->value, src->value, sizeof(src->value)); -+ dst->value = src->value; - return &dst->node; +- return &dst->node; ++ return hlsl_new_constant(ctx, src->node.data_type, &src->value, &src->node.loc); } -@@ -1411,27 +1566,30 @@ static struct hlsl_ir_node *clone_expr(struct hlsl_ctx *ctx, struct clone_instr_ + static struct hlsl_ir_node *clone_expr(struct hlsl_ctx *ctx, struct clone_instr_map *map, struct hlsl_ir_expr *src) +@@ -1411,27 +1564,30 @@ static struct hlsl_ir_node *clone_expr(struct hlsl_ctx *ctx, struct clone_instr_ static struct hlsl_ir_node *clone_if(struct hlsl_ctx *ctx, struct clone_instr_map *map, struct hlsl_ir_if *src) { @@ -6326,11 +6370,11 @@ index 64d6e87065b..5bca84ba38a 100644 - if (!(dst = hlsl_new_if(ctx, map_instr(map, src->condition.node), src->node.loc))) + if (!clone_block(ctx, &then_block, &src->then_block, map)) - return NULL; ++ return NULL; + if (!clone_block(ctx, &else_block, &src->else_block, map)) + { + hlsl_block_cleanup(&then_block); -+ return NULL; + return NULL; + } - if (!clone_block(ctx, &dst->then_instrs, &src->then_instrs, map) @@ -6358,7 +6402,7 @@ index 64d6e87065b..5bca84ba38a 100644 } static struct hlsl_ir_node *clone_load(struct hlsl_ctx *ctx, struct clone_instr_map *map, struct hlsl_ir_load *src) -@@ -1452,16 +1610,18 @@ static struct hlsl_ir_node *clone_load(struct hlsl_ctx *ctx, struct clone_instr_ +@@ -1452,16 +1608,18 @@ static struct hlsl_ir_node *clone_load(struct hlsl_ctx *ctx, struct clone_instr_ static struct hlsl_ir_node *clone_loop(struct hlsl_ctx *ctx, struct clone_instr_map *map, struct hlsl_ir_loop *src) { @@ -6382,19 +6426,20 @@ index 64d6e87065b..5bca84ba38a 100644 } static struct hlsl_ir_node *clone_resource_load(struct hlsl_ctx *ctx, -@@ -1486,7 +1646,11 @@ static struct hlsl_ir_node *clone_resource_load(struct hlsl_ctx *ctx, +@@ -1486,7 +1644,12 @@ static struct hlsl_ir_node *clone_resource_load(struct hlsl_ctx *ctx, } clone_src(map, &dst->coords, &src->coords); clone_src(map, &dst->lod, &src->lod); + clone_src(map, &dst->ddx, &src->ddx); + clone_src(map, &dst->ddy, &src->ddy); + clone_src(map, &dst->sample_index, &src->sample_index); ++ clone_src(map, &dst->cmp, &src->cmp); clone_src(map, &dst->texel_offset, &src->texel_offset); + dst->sampling_dim = src->sampling_dim; return &dst->node; } -@@ -1529,12 +1693,19 @@ static struct hlsl_ir_node *clone_store(struct hlsl_ctx *ctx, struct clone_instr +@@ -1529,12 +1692,19 @@ static struct hlsl_ir_node *clone_store(struct hlsl_ctx *ctx, struct clone_instr static struct hlsl_ir_node *clone_swizzle(struct hlsl_ctx *ctx, struct clone_instr_map *map, struct hlsl_ir_swizzle *src) { @@ -6418,7 +6463,7 @@ index 64d6e87065b..5bca84ba38a 100644 } static struct hlsl_ir_node *clone_instr(struct hlsl_ctx *ctx, -@@ -1554,6 +1725,9 @@ static struct hlsl_ir_node *clone_instr(struct hlsl_ctx *ctx, +@@ -1554,6 +1724,9 @@ static struct hlsl_ir_node *clone_instr(struct hlsl_ctx *ctx, case HLSL_IR_IF: return clone_if(ctx, map, hlsl_ir_if(instr)); @@ -6428,7 +6473,7 @@ index 64d6e87065b..5bca84ba38a 100644 case HLSL_IR_JUMP: return clone_jump(ctx, hlsl_ir_jump(instr)); -@@ -1593,13 +1767,12 @@ struct hlsl_ir_function_decl *hlsl_new_func_decl(struct hlsl_ctx *ctx, +@@ -1593,13 +1766,12 @@ struct hlsl_ir_function_decl *hlsl_new_func_decl(struct hlsl_ctx *ctx, struct hlsl_type *return_type, const struct hlsl_func_parameters *parameters, const struct hlsl_semantic *semantic, const struct vkd3d_shader_location *loc) { @@ -6444,7 +6489,7 @@ index 64d6e87065b..5bca84ba38a 100644 decl->return_type = return_type; decl->parameters = *parameters; decl->loc = *loc; -@@ -1620,17 +1793,17 @@ struct hlsl_ir_function_decl *hlsl_new_func_decl(struct hlsl_ctx *ctx, +@@ -1620,17 +1792,17 @@ struct hlsl_ir_function_decl *hlsl_new_func_decl(struct hlsl_ctx *ctx, if (!(constant = hlsl_new_bool_constant(ctx, false, loc))) return decl; @@ -6466,7 +6511,7 @@ index 64d6e87065b..5bca84ba38a 100644 { struct hlsl_buffer *buffer; -@@ -1640,7 +1813,7 @@ struct hlsl_buffer *hlsl_new_buffer(struct hlsl_ctx *ctx, enum hlsl_buffer_type +@@ -1640,7 +1812,7 @@ struct hlsl_buffer *hlsl_new_buffer(struct hlsl_ctx *ctx, enum hlsl_buffer_type buffer->name = name; if (reservation) buffer->reservation = *reservation; @@ -6475,7 +6520,7 @@ index 64d6e87065b..5bca84ba38a 100644 list_add_tail(&ctx->buffers, &buffer->entry); return buffer; } -@@ -1698,10 +1871,10 @@ static int compare_param_hlsl_types(const struct hlsl_type *t1, const struct hls +@@ -1698,10 +1870,10 @@ static int compare_param_hlsl_types(const struct hlsl_type *t1, const struct hls { int r; @@ -6489,7 +6534,7 @@ index 64d6e87065b..5bca84ba38a 100644 return r; } if ((r = vkd3d_u32_compare(t1->base_type, t2->base_type))) -@@ -1718,7 +1891,7 @@ static int compare_param_hlsl_types(const struct hlsl_type *t1, const struct hls +@@ -1718,7 +1890,7 @@ static int compare_param_hlsl_types(const struct hlsl_type *t1, const struct hls return r; if ((r = vkd3d_u32_compare(t1->dimy, t2->dimy))) return r; @@ -6498,7 +6543,7 @@ index 64d6e87065b..5bca84ba38a 100644 { size_t i; -@@ -1738,7 +1911,7 @@ static int compare_param_hlsl_types(const struct hlsl_type *t1, const struct hls +@@ -1738,7 +1910,7 @@ static int compare_param_hlsl_types(const struct hlsl_type *t1, const struct hls } return 0; } @@ -6507,7 +6552,7 @@ index 64d6e87065b..5bca84ba38a 100644 { if ((r = vkd3d_u32_compare(t1->e.array.elements_count, t2->e.array.elements_count))) return r; -@@ -1768,7 +1941,7 @@ static int compare_function_decl_rb(const void *key, const struct rb_entry *entr +@@ -1768,7 +1940,7 @@ static int compare_function_decl_rb(const void *key, const struct rb_entry *entr struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const struct hlsl_type *type) { @@ -6516,7 +6561,7 @@ index 64d6e87065b..5bca84ba38a 100644 static const char *const base_types[] = { -@@ -1789,7 +1962,7 @@ struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const stru +@@ -1789,7 +1961,7 @@ struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const stru return string; } @@ -6525,7 +6570,7 @@ index 64d6e87065b..5bca84ba38a 100644 { case HLSL_CLASS_SCALAR: assert(type->base_type < ARRAY_SIZE(base_types)); -@@ -1808,10 +1981,9 @@ struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const stru +@@ -1808,10 +1980,9 @@ struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const stru case HLSL_CLASS_ARRAY: { @@ -6537,7 +6582,7 @@ index 64d6e87065b..5bca84ba38a 100644 ; if ((inner_string = hlsl_type_to_string(ctx, t))) -@@ -1820,7 +1992,7 @@ struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const stru +@@ -1820,7 +1991,7 @@ struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const stru hlsl_release_string_buffer(ctx, inner_string); } @@ -6546,7 +6591,7 @@ index 64d6e87065b..5bca84ba38a 100644 { if (t->e.array.elements_count == HLSL_ARRAY_ELEMENTS_COUNT_IMPLICIT) vkd3d_string_buffer_printf(string, "[]"); -@@ -1860,13 +2032,26 @@ struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const stru +@@ -1860,13 +2031,26 @@ struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const stru assert(type->sampler_dim < ARRAY_SIZE(dimensions)); assert(type->e.resource_format->base_type < ARRAY_SIZE(base_types)); @@ -6577,7 +6622,7 @@ index 64d6e87065b..5bca84ba38a 100644 return string; default: -@@ -1943,6 +2128,7 @@ const char *hlsl_node_type_to_string(enum hlsl_ir_node_type type) +@@ -1943,6 +2127,7 @@ const char *hlsl_node_type_to_string(enum hlsl_ir_node_type type) "HLSL_IR_CONSTANT", "HLSL_IR_EXPR", "HLSL_IR_IF", @@ -6585,7 +6630,7 @@ index 64d6e87065b..5bca84ba38a 100644 "HLSL_IR_LOAD", "HLSL_IR_LOOP", "HLSL_IR_JUMP", -@@ -2107,7 +2293,7 @@ static void dump_ir_constant(struct vkd3d_string_buffer *buffer, const struct hl +@@ -2107,7 +2292,7 @@ static void dump_ir_constant(struct vkd3d_string_buffer *buffer, const struct hl vkd3d_string_buffer_printf(buffer, "{"); for (x = 0; x < type->dimx; ++x) { @@ -6594,7 +6639,7 @@ index 64d6e87065b..5bca84ba38a 100644 switch (type->base_type) { -@@ -2168,6 +2354,7 @@ const char *debug_hlsl_expr_op(enum hlsl_ir_expr_op op) +@@ -2168,6 +2353,7 @@ const char *debug_hlsl_expr_op(enum hlsl_ir_expr_op op) [HLSL_OP1_SIN] = "sin", [HLSL_OP1_SIN_REDUCED] = "sin_reduced", [HLSL_OP1_SQRT] = "sqrt", @@ -6602,7 +6647,7 @@ index 64d6e87065b..5bca84ba38a 100644 [HLSL_OP2_ADD] = "+", [HLSL_OP2_BIT_AND] = "&", -@@ -2214,9 +2401,9 @@ static void dump_ir_if(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer, +@@ -2214,9 +2400,9 @@ static void dump_ir_if(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer, vkd3d_string_buffer_printf(buffer, "if ("); dump_src(buffer, &if_node->condition); vkd3d_string_buffer_printf(buffer, ") {\n"); @@ -6614,16 +6659,19 @@ index 64d6e87065b..5bca84ba38a 100644 vkd3d_string_buffer_printf(buffer, " %10s }", ""); } -@@ -2256,6 +2443,8 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru +@@ -2255,7 +2441,11 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru + { [HLSL_RESOURCE_LOAD] = "load_resource", [HLSL_RESOURCE_SAMPLE] = "sample", ++ [HLSL_RESOURCE_SAMPLE_CMP] = "sample_cmp", ++ [HLSL_RESOURCE_SAMPLE_CMP_LZ] = "sample_cmp_lz", [HLSL_RESOURCE_SAMPLE_LOD] = "sample_lod", + [HLSL_RESOURCE_SAMPLE_LOD_BIAS] = "sample_biased", + [HLSL_RESOURCE_SAMPLE_GRAD] = "sample_grad", [HLSL_RESOURCE_GATHER_RED] = "gather_red", [HLSL_RESOURCE_GATHER_GREEN] = "gather_green", [HLSL_RESOURCE_GATHER_BLUE] = "gather_blue", -@@ -2269,6 +2458,11 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru +@@ -2269,6 +2459,11 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru dump_deref(buffer, &load->sampler); vkd3d_string_buffer_printf(buffer, ", coords = "); dump_src(buffer, &load->coords); @@ -6635,7 +6683,7 @@ index 64d6e87065b..5bca84ba38a 100644 if (load->texel_offset.node) { vkd3d_string_buffer_printf(buffer, ", offset = "); -@@ -2279,6 +2473,16 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru +@@ -2279,6 +2474,21 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru vkd3d_string_buffer_printf(buffer, ", lod = "); dump_src(buffer, &load->lod); } @@ -6648,11 +6696,16 @@ index 64d6e87065b..5bca84ba38a 100644 + { + vkd3d_string_buffer_printf(buffer, ", ddy = "); + dump_src(buffer, &load->ddy); ++ } ++ if (load->cmp.node) ++ { ++ vkd3d_string_buffer_printf(buffer, ", cmp = "); ++ dump_src(buffer, &load->cmp); + } vkd3d_string_buffer_printf(buffer, ")"); } -@@ -2321,6 +2525,14 @@ static void dump_ir_swizzle(struct vkd3d_string_buffer *buffer, const struct hls +@@ -2321,6 +2531,14 @@ static void dump_ir_swizzle(struct vkd3d_string_buffer *buffer, const struct hls } } @@ -6667,7 +6720,7 @@ index 64d6e87065b..5bca84ba38a 100644 static void dump_instr(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer, const struct hlsl_ir_node *instr) { if (instr->index) -@@ -2348,6 +2560,10 @@ static void dump_instr(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer, +@@ -2348,6 +2566,10 @@ static void dump_instr(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer, dump_ir_if(ctx, buffer, hlsl_ir_if(instr)); break; @@ -6678,7 +6731,7 @@ index 64d6e87065b..5bca84ba38a 100644 case HLSL_IR_JUMP: dump_ir_jump(buffer, hlsl_ir_jump(instr)); break; -@@ -2421,7 +2637,7 @@ void hlsl_free_type(struct hlsl_type *type) +@@ -2421,7 +2643,7 @@ void hlsl_free_type(struct hlsl_type *type) size_t i; vkd3d_free((void *)type->name); @@ -6687,7 +6740,7 @@ index 64d6e87065b..5bca84ba38a 100644 { for (i = 0; i < type->e.record.field_count; ++i) { -@@ -2447,6 +2663,11 @@ void hlsl_free_instr_list(struct list *list) +@@ -2447,6 +2669,11 @@ void hlsl_free_instr_list(struct list *list) hlsl_free_instr(node); } @@ -6699,7 +6752,7 @@ index 64d6e87065b..5bca84ba38a 100644 static void free_ir_call(struct hlsl_ir_call *call) { vkd3d_free(call); -@@ -2468,8 +2689,8 @@ static void free_ir_expr(struct hlsl_ir_expr *expr) +@@ -2468,8 +2695,8 @@ static void free_ir_expr(struct hlsl_ir_expr *expr) static void free_ir_if(struct hlsl_ir_if *if_node) { @@ -6710,7 +6763,7 @@ index 64d6e87065b..5bca84ba38a 100644 hlsl_src_remove(&if_node->condition); vkd3d_free(if_node); } -@@ -2487,7 +2708,7 @@ static void free_ir_load(struct hlsl_ir_load *load) +@@ -2487,7 +2714,7 @@ static void free_ir_load(struct hlsl_ir_load *load) static void free_ir_loop(struct hlsl_ir_loop *loop) { @@ -6719,18 +6772,19 @@ index 64d6e87065b..5bca84ba38a 100644 vkd3d_free(loop); } -@@ -2497,7 +2718,10 @@ static void free_ir_resource_load(struct hlsl_ir_resource_load *load) +@@ -2497,7 +2724,11 @@ static void free_ir_resource_load(struct hlsl_ir_resource_load *load) hlsl_cleanup_deref(&load->resource); hlsl_src_remove(&load->coords); hlsl_src_remove(&load->lod); + hlsl_src_remove(&load->ddx); + hlsl_src_remove(&load->ddy); ++ hlsl_src_remove(&load->cmp); hlsl_src_remove(&load->texel_offset); + hlsl_src_remove(&load->sample_index); vkd3d_free(load); } -@@ -2522,6 +2746,13 @@ static void free_ir_swizzle(struct hlsl_ir_swizzle *swizzle) +@@ -2522,6 +2753,13 @@ static void free_ir_swizzle(struct hlsl_ir_swizzle *swizzle) vkd3d_free(swizzle); } @@ -6744,7 +6798,7 @@ index 64d6e87065b..5bca84ba38a 100644 void hlsl_free_instr(struct hlsl_ir_node *node) { assert(list_empty(&node->uses)); -@@ -2544,6 +2775,10 @@ void hlsl_free_instr(struct hlsl_ir_node *node) +@@ -2544,6 +2782,10 @@ void hlsl_free_instr(struct hlsl_ir_node *node) free_ir_if(hlsl_ir_if(node)); break; @@ -6755,7 +6809,7 @@ index 64d6e87065b..5bca84ba38a 100644 case HLSL_IR_JUMP: free_ir_jump(hlsl_ir_jump(node)); break; -@@ -2600,7 +2835,7 @@ static void free_function_decl(struct hlsl_ir_function_decl *decl) +@@ -2600,7 +2842,7 @@ static void free_function_decl(struct hlsl_ir_function_decl *decl) vkd3d_free((void *)decl->attrs); vkd3d_free(decl->parameters.vars); @@ -6764,7 +6818,25 @@ index 64d6e87065b..5bca84ba38a 100644 vkd3d_free(decl); } -@@ -2844,8 +3079,8 @@ static void declare_predefined_types(struct hlsl_ctx *ctx) +@@ -2826,11 +3068,12 @@ static void declare_predefined_types(struct hlsl_ctx *ctx) + + static const char *const sampler_names[] = + { +- [HLSL_SAMPLER_DIM_GENERIC] = "sampler", +- [HLSL_SAMPLER_DIM_1D] = "sampler1D", +- [HLSL_SAMPLER_DIM_2D] = "sampler2D", +- [HLSL_SAMPLER_DIM_3D] = "sampler3D", +- [HLSL_SAMPLER_DIM_CUBE] = "samplerCUBE", ++ [HLSL_SAMPLER_DIM_GENERIC] = "sampler", ++ [HLSL_SAMPLER_DIM_COMPARISON] = "SamplerComparisonState", ++ [HLSL_SAMPLER_DIM_1D] = "sampler1D", ++ [HLSL_SAMPLER_DIM_2D] = "sampler2D", ++ [HLSL_SAMPLER_DIM_3D] = "sampler3D", ++ [HLSL_SAMPLER_DIM_CUBE] = "samplerCUBE", + }; + + static const struct +@@ -2844,8 +3087,8 @@ static void declare_predefined_types(struct hlsl_ctx *ctx) { {"dword", HLSL_CLASS_SCALAR, HLSL_TYPE_UINT, 1, 1}, {"float", HLSL_CLASS_SCALAR, HLSL_TYPE_FLOAT, 1, 1}, @@ -6775,7 +6847,7 @@ index 64d6e87065b..5bca84ba38a 100644 {"STRING", HLSL_CLASS_OBJECT, HLSL_TYPE_STRING, 1, 1}, {"TEXTURE", HLSL_CLASS_OBJECT, HLSL_TYPE_TEXTURE, 1, 1}, {"PIXELSHADER", HLSL_CLASS_OBJECT, HLSL_TYPE_PIXELSHADER, 1, 1}, -@@ -2999,10 +3234,10 @@ static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const char *source_name, +@@ -2999,10 +3242,10 @@ static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const char *source_name, list_init(&ctx->buffers); if (!(ctx->globals_buffer = hlsl_new_buffer(ctx, HLSL_BUFFER_CONSTANT, @@ -6789,7 +6861,7 @@ index 64d6e87065b..5bca84ba38a 100644 ctx->cur_buffer = ctx->globals_buffer; diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h -index ccbf22a5801..376191b9ff3 100644 +index ccbf22a5801..a7ff1f23858 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h @@ -21,10 +21,12 @@ @@ -6807,7 +6879,7 @@ index ccbf22a5801..376191b9ff3 100644 /* 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 -@@ -102,18 +104,21 @@ enum hlsl_base_type +@@ -102,18 +104,22 @@ enum hlsl_base_type enum hlsl_sampler_dim { @@ -6824,6 +6896,7 @@ index ccbf22a5801..376191b9ff3 100644 - HLSL_SAMPLER_DIM_CUBEARRAY, - HLSL_SAMPLER_DIM_MAX = HLSL_SAMPLER_DIM_CUBEARRAY, + HLSL_SAMPLER_DIM_GENERIC, ++ HLSL_SAMPLER_DIM_COMPARISON, + HLSL_SAMPLER_DIM_1D, + HLSL_SAMPLER_DIM_2D, + HLSL_SAMPLER_DIM_3D, @@ -6841,7 +6914,7 @@ index ccbf22a5801..376191b9ff3 100644 }; enum hlsl_regset -@@ -134,16 +139,17 @@ struct hlsl_type +@@ -134,16 +140,17 @@ struct hlsl_type /* Item entry in hlsl_scope->types. hlsl_type->name is used as key (if not NULL). */ struct rb_entry scope_entry; @@ -6863,7 +6936,7 @@ index ccbf22a5801..376191b9ff3 100644 * Otherwise, sampler_dim is not used */ enum hlsl_sampler_dim sampler_dim; /* Name, in case the type is a named struct or a typedef. */ -@@ -207,6 +213,16 @@ struct hlsl_semantic +@@ -207,6 +214,16 @@ struct hlsl_semantic { const char *name; uint32_t index; @@ -6880,7 +6953,7 @@ index ccbf22a5801..376191b9ff3 100644 }; /* A field within a struct type declaration, used in hlsl_type.e.fields. */ -@@ -228,16 +244,21 @@ struct hlsl_struct_field +@@ -228,16 +245,21 @@ struct hlsl_struct_field size_t name_bytecode_offset; }; @@ -6905,7 +6978,7 @@ index ccbf22a5801..376191b9ff3 100644 unsigned int writemask; /* Whether the register has been allocated. */ bool allocated; -@@ -254,6 +275,7 @@ enum hlsl_ir_node_type +@@ -254,6 +276,7 @@ enum hlsl_ir_node_type HLSL_IR_CONSTANT, HLSL_IR_EXPR, HLSL_IR_IF, @@ -6913,7 +6986,7 @@ index ccbf22a5801..376191b9ff3 100644 HLSL_IR_LOAD, HLSL_IR_LOOP, HLSL_IR_JUMP, -@@ -342,12 +364,17 @@ struct hlsl_attribute +@@ -342,12 +365,17 @@ struct hlsl_attribute #define HLSL_ARRAY_ELEMENTS_COUNT_IMPLICIT 0 @@ -6935,7 +7008,7 @@ index ccbf22a5801..376191b9ff3 100644 }; struct hlsl_ir_var -@@ -360,8 +387,7 @@ struct hlsl_ir_var +@@ -360,8 +388,7 @@ struct hlsl_ir_var struct hlsl_buffer *buffer; /* Bitfield for storage modifiers (type modifiers are stored in data_type->modifiers). */ unsigned int storage_modifiers; @@ -6945,7 +7018,7 @@ index ccbf22a5801..376191b9ff3 100644 struct hlsl_reg_reservation reg_reservation; /* Item entry in hlsl_scope.vars. Specifically hlsl_ctx.globals.vars if the variable is global. */ -@@ -384,6 +410,13 @@ struct hlsl_ir_var +@@ -384,6 +411,13 @@ struct hlsl_ir_var * and the buffer_offset instead. */ struct hlsl_reg regs[HLSL_REGSET_LAST + 1]; @@ -6959,7 +7032,7 @@ index ccbf22a5801..376191b9ff3 100644 uint32_t is_input_semantic : 1; uint32_t is_output_semantic : 1; uint32_t is_uniform : 1; -@@ -446,8 +479,8 @@ struct hlsl_ir_if +@@ -446,8 +480,8 @@ struct hlsl_ir_if { struct hlsl_ir_node node; struct hlsl_src condition; @@ -6970,7 +7043,7 @@ index ccbf22a5801..376191b9ff3 100644 }; struct hlsl_ir_loop -@@ -485,6 +518,7 @@ enum hlsl_ir_expr_op +@@ -485,6 +519,7 @@ enum hlsl_ir_expr_op HLSL_OP1_SIN, HLSL_OP1_SIN_REDUCED, /* Reduced range [-pi, pi] */ HLSL_OP1_SQRT, @@ -6978,7 +7051,7 @@ index ccbf22a5801..376191b9ff3 100644 HLSL_OP2_ADD, HLSL_OP2_BIT_AND, -@@ -540,6 +574,12 @@ struct hlsl_ir_swizzle +@@ -540,6 +575,12 @@ struct hlsl_ir_swizzle DWORD swizzle; }; @@ -6991,26 +7064,29 @@ index ccbf22a5801..376191b9ff3 100644 /* Reference to a variable, or a part of it (e.g. a vector within a matrix within a struct). */ struct hlsl_deref { -@@ -575,6 +615,8 @@ enum hlsl_resource_load_type +@@ -574,7 +615,11 @@ enum hlsl_resource_load_type + { HLSL_RESOURCE_LOAD, HLSL_RESOURCE_SAMPLE, ++ HLSL_RESOURCE_SAMPLE_CMP, ++ HLSL_RESOURCE_SAMPLE_CMP_LZ, HLSL_RESOURCE_SAMPLE_LOD, + HLSL_RESOURCE_SAMPLE_LOD_BIAS, + HLSL_RESOURCE_SAMPLE_GRAD, HLSL_RESOURCE_GATHER_RED, HLSL_RESOURCE_GATHER_GREEN, HLSL_RESOURCE_GATHER_BLUE, -@@ -586,7 +628,8 @@ struct hlsl_ir_resource_load +@@ -586,7 +631,8 @@ struct hlsl_ir_resource_load struct hlsl_ir_node node; enum hlsl_resource_load_type load_type; struct hlsl_deref resource, sampler; - struct hlsl_src coords, lod, texel_offset; -+ struct hlsl_src coords, lod, ddx, ddy, sample_index, texel_offset; ++ struct hlsl_src coords, lod, ddx, ddy, cmp, sample_index, texel_offset; + enum hlsl_sampler_dim sampling_dim; }; struct hlsl_ir_resource_store -@@ -607,13 +650,16 @@ struct hlsl_ir_store +@@ -607,13 +653,16 @@ struct hlsl_ir_store struct hlsl_ir_constant { struct hlsl_ir_node node; @@ -7033,7 +7109,7 @@ index ccbf22a5801..376191b9ff3 100644 /* Constant register of type 'c' where the constant value is stored for SM1. */ struct hlsl_reg reg; }; -@@ -674,6 +720,9 @@ struct hlsl_buffer +@@ -674,6 +723,9 @@ struct hlsl_buffer unsigned size, used_size; /* Register of type 'b' on which the buffer is allocated. */ struct hlsl_reg reg; @@ -7043,19 +7119,19 @@ index ccbf22a5801..376191b9ff3 100644 }; struct hlsl_ctx -@@ -780,8 +829,9 @@ struct hlsl_resource_load_params +@@ -780,8 +832,9 @@ struct hlsl_resource_load_params { struct hlsl_type *format; enum hlsl_resource_load_type type; - struct hlsl_deref resource, sampler; - struct hlsl_ir_node *coords, *lod, *texel_offset; + struct hlsl_ir_node *resource, *sampler; -+ struct hlsl_ir_node *coords, *lod, *ddx, *ddy, *sample_index, *texel_offset; ++ struct hlsl_ir_node *coords, *lod, *ddx, *ddy, *cmp, *sample_index, *texel_offset; + enum hlsl_sampler_dim sampling_dim; }; static inline struct hlsl_ir_call *hlsl_ir_call(const struct hlsl_ir_node *node) -@@ -850,6 +900,27 @@ static inline struct hlsl_ir_swizzle *hlsl_ir_swizzle(const struct hlsl_ir_node +@@ -850,6 +903,27 @@ static inline struct hlsl_ir_swizzle *hlsl_ir_swizzle(const struct hlsl_ir_node return CONTAINING_RECORD(node, struct hlsl_ir_swizzle, node); } @@ -7083,7 +7159,7 @@ index ccbf22a5801..376191b9ff3 100644 static inline void hlsl_src_from_node(struct hlsl_src *src, struct hlsl_ir_node *node) { src->node = node; -@@ -873,6 +944,15 @@ static inline void *hlsl_alloc(struct hlsl_ctx *ctx, size_t size) +@@ -873,6 +947,15 @@ static inline void *hlsl_alloc(struct hlsl_ctx *ctx, size_t size) return ptr; } @@ -7099,7 +7175,7 @@ index ccbf22a5801..376191b9ff3 100644 static inline void *hlsl_realloc(struct hlsl_ctx *ctx, void *ptr, size_t size) { void *ret = vkd3d_realloc(ptr, size); -@@ -948,6 +1028,8 @@ static inline unsigned int hlsl_sampler_dim_count(enum hlsl_sampler_dim dim) +@@ -948,6 +1031,8 @@ static inline unsigned int hlsl_sampler_dim_count(enum hlsl_sampler_dim dim) switch (dim) { case HLSL_SAMPLER_DIM_1D: @@ -7108,7 +7184,7 @@ index ccbf22a5801..376191b9ff3 100644 return 1; case HLSL_SAMPLER_DIM_1DARRAY: case HLSL_SAMPLER_DIM_2D: -@@ -974,11 +1056,12 @@ struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const stru +@@ -974,11 +1059,12 @@ struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const stru struct vkd3d_string_buffer *hlsl_modifiers_to_string(struct hlsl_ctx *ctx, unsigned int modifiers); const char *hlsl_node_type_to_string(enum hlsl_ir_node_type type); @@ -7122,7 +7198,7 @@ index ccbf22a5801..376191b9ff3 100644 bool hlsl_clone_block(struct hlsl_ctx *ctx, struct hlsl_block *dst_block, const struct hlsl_block *src_block); void hlsl_dump_function(struct hlsl_ctx *ctx, const struct hlsl_ir_function_decl *func); -@@ -986,6 +1069,7 @@ void hlsl_dump_function(struct hlsl_ctx *ctx, const struct hlsl_ir_function_decl +@@ -986,6 +1072,7 @@ void hlsl_dump_function(struct hlsl_ctx *ctx, const struct hlsl_ir_function_decl int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, enum vkd3d_shader_target_type target_type, struct vkd3d_shader_code *out); @@ -7130,7 +7206,7 @@ index ccbf22a5801..376191b9ff3 100644 bool hlsl_copy_deref(struct hlsl_ctx *ctx, struct hlsl_deref *deref, const struct hlsl_deref *other); void hlsl_cleanup_deref(struct hlsl_deref *deref); -@@ -1012,64 +1096,71 @@ const char *hlsl_jump_type_to_string(enum hlsl_ir_jump_type type); +@@ -1012,64 +1099,73 @@ const char *hlsl_jump_type_to_string(enum hlsl_ir_jump_type type); struct hlsl_type *hlsl_new_array_type(struct hlsl_ctx *ctx, struct hlsl_type *basic_type, unsigned int array_size); struct hlsl_ir_node *hlsl_new_binary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2); @@ -7142,11 +7218,13 @@ index ccbf22a5801..376191b9ff3 100644 struct hlsl_ir_node *hlsl_new_call(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *decl, const struct vkd3d_shader_location *loc); -struct hlsl_ir_expr *hlsl_new_cast(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_type *type, +- const struct vkd3d_shader_location *loc); +-struct hlsl_ir_constant *hlsl_new_constant(struct hlsl_ctx *ctx, struct hlsl_type *type, +struct hlsl_ir_node *hlsl_new_cast(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_type *type, const struct vkd3d_shader_location *loc); - struct hlsl_ir_constant *hlsl_new_constant(struct hlsl_ctx *ctx, struct hlsl_type *type, - const struct vkd3d_shader_location *loc); -struct hlsl_ir_expr *hlsl_new_copy(struct hlsl_ctx *ctx, struct hlsl_ir_node *node); ++struct hlsl_ir_node *hlsl_new_constant(struct hlsl_ctx *ctx, struct hlsl_type *type, ++ const struct hlsl_constant_value *value, const struct vkd3d_shader_location *loc); +struct hlsl_ir_node *hlsl_new_copy(struct hlsl_ctx *ctx, struct hlsl_ir_node *node); struct hlsl_ir_node *hlsl_new_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS], @@ -7175,6 +7253,8 @@ index ccbf22a5801..376191b9ff3 100644 struct hlsl_ir_load *hlsl_new_load_index(struct hlsl_ctx *ctx, const struct hlsl_deref *deref, struct hlsl_ir_node *idx, const struct vkd3d_shader_location *loc); -struct hlsl_ir_load *hlsl_new_load_component(struct hlsl_ctx *ctx, struct hlsl_block *block, ++struct hlsl_ir_load *hlsl_new_load_parent(struct hlsl_ctx *ctx, const struct hlsl_deref *deref, ++ const struct vkd3d_shader_location *loc); +struct hlsl_ir_node *hlsl_new_load_component(struct hlsl_ctx *ctx, struct hlsl_block *block, const struct hlsl_deref *deref, unsigned int comp, const struct vkd3d_shader_location *loc); @@ -7223,7 +7303,7 @@ index ccbf22a5801..376191b9ff3 100644 const struct hlsl_reg_reservation *reg_reservation); void hlsl_error(struct hlsl_ctx *ctx, const struct vkd3d_shader_location *loc, -@@ -1101,6 +1192,9 @@ enum hlsl_regset hlsl_type_get_regset(const struct hlsl_type *type); +@@ -1101,6 +1197,9 @@ 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); @@ -7233,7 +7313,7 @@ index ccbf22a5801..376191b9ff3 100644 unsigned int hlsl_combine_swizzles(unsigned int first, unsigned int second, unsigned int dim); unsigned int hlsl_combine_writemasks(unsigned int first, unsigned int second); unsigned int hlsl_map_swizzle(unsigned int swizzle, unsigned int writemask); -@@ -1109,12 +1203,16 @@ unsigned int hlsl_swizzle_from_writemask(unsigned int writemask); +@@ -1109,12 +1208,16 @@ 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); bool hlsl_component_index_range_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref, unsigned int *start, unsigned int *count); @@ -7250,7 +7330,7 @@ index ccbf22a5801..376191b9ff3 100644 bool hlsl_sm1_register_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_semantic *semantic, bool output, D3DSHADER_PARAM_REGISTER_TYPE *type, unsigned int *reg); -@@ -1124,7 +1222,7 @@ int hlsl_sm1_write(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_fun +@@ -1124,7 +1227,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, @@ -7300,7 +7380,7 @@ index adff1da04d8..e9ae3ccf3d3 100644 FIXME("Malformed preprocessor line directive?\n"); BEGIN(INITIAL); diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y -index fd1eaf6ec95..dae1851c7ad 100644 +index fd1eaf6ec95..209428f761a 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y @@ -85,8 +85,8 @@ struct parse_function @@ -7964,12 +8044,12 @@ index fd1eaf6ec95..dae1851c7ad 100644 return false; - list_add_tail(instrs, &cast->node.entry); - index = &cast->node; -- -- if (expr_type->type == HLSL_CLASS_MATRIX) -- return add_matrix_index(ctx, instrs, array, index, loc); + list_add_tail(instrs, &cast->entry); + index = cast; +- if (expr_type->type == HLSL_CLASS_MATRIX) +- return add_matrix_index(ctx, instrs, array, index, loc); +- - if (expr_type->type != HLSL_CLASS_ARRAY && expr_type->type != HLSL_CLASS_VECTOR) + if (expr_type->class != HLSL_CLASS_ARRAY && expr_type->class != HLSL_CLASS_VECTOR && expr_type->class != HLSL_CLASS_MATRIX) { @@ -8133,17 +8213,17 @@ index fd1eaf6ec95..dae1851c7ad 100644 { - if (node->data_type->type != HLSL_CLASS_SCALAR) - return 0; -- ++ struct hlsl_ir_constant *constant; ++ struct hlsl_ir_node *node; ++ unsigned int ret = 0; + - switch (node->type) - { - case HLSL_IR_CONSTANT: - { - struct hlsl_ir_constant *constant = hlsl_ir_constant(node); - const union hlsl_constant_value *value = &constant->value[0]; -+ struct hlsl_ir_constant *constant; -+ struct hlsl_ir_node *node; -+ unsigned int ret = 0; - +- - switch (constant->node.data_type->base_type) - { - case HLSL_TYPE_UINT: @@ -8865,7 +8945,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 count = hlsl_type_component_count(arg->data_type); for (i = 0; i < count; ++i) -@@ -2404,46 +2403,117 @@ static bool intrinsic_all(struct hlsl_ctx *ctx, +@@ -2404,50 +2403,121 @@ static bool intrinsic_all(struct hlsl_ctx *ctx, if (!(load = add_load_component(ctx, params->instrs, arg, i, loc))) return false; @@ -8916,19 +8996,24 @@ index fd1eaf6ec95..dae1851c7ad 100644 - data_type = params->args[0]->data_type; - if (data_type->base_type == HLSL_TYPE_BOOL || data_type->base_type == HLSL_TYPE_DOUBLE) +- { +- struct vkd3d_string_buffer *string; + if (!(dot = add_binary_dot_expr(ctx, params->instrs, arg, arg, loc))) + return false; -+ + +- if ((string = hlsl_type_to_string(ctx, data_type))) +- hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, +- "Wrong type for argument 0 of asuint(): expected 'int', 'uint', 'float', or 'half', but got '%s'.", +- string->buffer); +- hlsl_release_string_buffer(ctx, string); + return !!add_binary_comparison_expr(ctx, params->instrs, HLSL_OP2_NEQUAL, dot, zero, loc); + } + else if (arg->data_type->base_type == HLSL_TYPE_BOOL) - { -- struct vkd3d_string_buffer *string; ++ { + if (!(bfalse = hlsl_new_bool_constant(ctx, false, loc))) + return false; + list_add_tail(params->instrs, &bfalse->entry); - -- if ((string = hlsl_type_to_string(ctx, data_type))) ++ + or = bfalse; + + count = hlsl_type_component_count(arg->data_type); @@ -9004,9 +9089,13 @@ index fd1eaf6ec95..dae1851c7ad 100644 + struct vkd3d_string_buffer *string; + + if ((string = hlsl_type_to_string(ctx, data_type))) - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, - "Wrong type for argument 0 of asuint(): expected 'int', 'uint', 'float', or 'half', but got '%s'.", - string->buffer); ++ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, ++ "Wrong type for argument 0 of asuint(): expected 'int', 'uint', 'float', or 'half', but got '%s'.", ++ string->buffer); ++ hlsl_release_string_buffer(ctx, string); + } + data_type = convert_numeric_type(ctx, data_type, HLSL_TYPE_UINT); + @@ -2483,7 +2553,7 @@ static bool intrinsic_cos(struct hlsl_ctx *ctx, static bool intrinsic_cross(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) @@ -9103,16 +9192,15 @@ index fd1eaf6ec95..dae1851c7ad 100644 return false; return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_EXP2, mul, loc); -@@ -2604,6 +2693,48 @@ static bool intrinsic_floor(struct hlsl_ctx *ctx, +@@ -2604,6 +2693,43 @@ static bool intrinsic_floor(struct hlsl_ctx *ctx, return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_FLOOR, arg, loc); } +static bool intrinsic_fmod(struct hlsl_ctx *ctx, const struct parse_initializer *params, + const struct vkd3d_shader_location *loc) +{ -+ struct hlsl_ir_node *x, *y, *div, *abs, *frac, *neg_frac, *ge, *select; -+ struct hlsl_ir_constant *zero; -+ unsigned int count, i; ++ struct hlsl_ir_node *x, *y, *div, *abs, *frac, *neg_frac, *ge, *select, *zero; ++ static const struct hlsl_constant_value zero_value; + + if (!(x = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) + return false; @@ -9123,13 +9211,9 @@ index fd1eaf6ec95..dae1851c7ad 100644 + if (!(div = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_DIV, x, y, loc))) + return false; + -+ if (!(zero = hlsl_new_constant(ctx, div->data_type, loc))) ++ if (!(zero = hlsl_new_constant(ctx, div->data_type, &zero_value, loc))) + return false; -+ list_add_tail(params->instrs, &zero->node.entry); -+ -+ count = hlsl_type_element_count(div->data_type); -+ for (i = 0; i < count; ++i) -+ zero->value.u[i].f = 0.0f; ++ list_add_tail(params->instrs, &zero->entry); + + if (!(abs = add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_ABS, div, loc))) + return false; @@ -9140,7 +9224,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 + if (!(neg_frac = add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_NEG, frac, loc))) + return false; + -+ if (!(ge = add_binary_comparison_expr(ctx, params->instrs, HLSL_OP2_GEQUAL, div, &zero->node, loc))) ++ if (!(ge = add_binary_comparison_expr(ctx, params->instrs, HLSL_OP2_GEQUAL, div, zero, loc))) + return false; + + if (!(select = hlsl_add_conditional(ctx, params->instrs, ge, frac, neg_frac))) @@ -9152,7 +9236,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 static bool intrinsic_frac(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { -@@ -2635,7 +2766,7 @@ static bool intrinsic_length(struct hlsl_ctx *ctx, +@@ -2635,7 +2761,7 @@ static bool intrinsic_length(struct hlsl_ctx *ctx, struct hlsl_type *type = params->args[0]->data_type; struct hlsl_ir_node *arg, *dot; @@ -9161,7 +9245,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 { struct vkd3d_string_buffer *string; -@@ -2692,20 +2823,18 @@ static struct hlsl_ir_node * add_pow_expr(struct hlsl_ctx *ctx, +@@ -2692,20 +2818,18 @@ static struct hlsl_ir_node * add_pow_expr(struct hlsl_ctx *ctx, static bool intrinsic_lit(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { @@ -9171,8 +9255,8 @@ index fd1eaf6ec95..dae1851c7ad 100644 - struct hlsl_ir_node *diffuse; - struct hlsl_ir_store *store; + struct hlsl_ir_node *n_l_neg, *n_h_neg, *specular_or, *specular_pow, *load; -+ struct hlsl_ir_node *n_l, *n_h, *m, *diffuse, *zero, *store; -+ struct hlsl_ir_constant *init; ++ struct hlsl_ir_node *n_l, *n_h, *m, *diffuse, *zero, *store, *init; ++ struct hlsl_constant_value init_value; + struct hlsl_ir_load *var_load; struct hlsl_deref var_deref; struct hlsl_type *ret_type; @@ -9189,21 +9273,26 @@ index fd1eaf6ec95..dae1851c7ad 100644 { hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Invalid argument type."); return false; -@@ -2728,35 +2857,33 @@ static bool intrinsic_lit(struct hlsl_ctx *ctx, +@@ -2726,37 +2850,35 @@ static bool intrinsic_lit(struct hlsl_ctx *ctx, + return false; + hlsl_init_simple_deref_from_var(&var_deref, var); - if (!(init = hlsl_new_constant(ctx, ret_type, loc))) +- if (!(init = hlsl_new_constant(ctx, ret_type, loc))) ++ init_value.u[0].f = 1.0f; ++ init_value.u[1].f = 0.0f; ++ init_value.u[2].f = 0.0f; ++ init_value.u[3].f = 1.0f; ++ if (!(init = hlsl_new_constant(ctx, ret_type, &init_value, loc))) return false; - init->value[0].f = 1.0f; - init->value[1].f = 0.0f; - init->value[2].f = 0.0f; - init->value[3].f = 1.0f; -+ init->value.u[0].f = 1.0f; -+ init->value.u[1].f = 0.0f; -+ init->value.u[2].f = 0.0f; -+ init->value.u[3].f = 1.0f; - list_add_tail(params->instrs, &init->node.entry); +- list_add_tail(params->instrs, &init->node.entry); ++ list_add_tail(params->instrs, &init->entry); - if (!(store = hlsl_new_simple_store(ctx, var, &init->node))) +- if (!(store = hlsl_new_simple_store(ctx, var, &init->node))) ++ if (!(store = hlsl_new_simple_store(ctx, var, init))) return false; - list_add_tail(params->instrs, &store->node.entry); + list_add_tail(params->instrs, &store->entry); @@ -9235,7 +9324,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 return false; if (!(specular_or = add_binary_logical_expr(ctx, params->instrs, HLSL_OP2_LOGIC_OR, n_l_neg, n_h_neg, loc))) -@@ -2765,20 +2892,67 @@ static bool intrinsic_lit(struct hlsl_ctx *ctx, +@@ -2765,20 +2887,67 @@ static bool intrinsic_lit(struct hlsl_ctx *ctx, if (!(specular_pow = add_pow_expr(ctx, params->instrs, n_h, m, loc))) return false; @@ -9307,7 +9396,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 static bool intrinsic_max(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { -@@ -2808,15 +2982,15 @@ static bool intrinsic_mul(struct hlsl_ctx *ctx, +@@ -2808,15 +2977,15 @@ static bool intrinsic_mul(struct hlsl_ctx *ctx, struct hlsl_ir_load *load; struct hlsl_ir_var *var; @@ -9326,7 +9415,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 { vect_count++; cast_type2 = hlsl_get_matrix_type(ctx, base, 1, arg2->data_type->dimx); -@@ -2854,13 +3028,11 @@ static bool intrinsic_mul(struct hlsl_ctx *ctx, +@@ -2854,13 +3023,11 @@ static bool intrinsic_mul(struct hlsl_ctx *ctx, for (j = 0; j < matrix_type->dimy; ++j) { struct hlsl_ir_node *instr = NULL; @@ -9341,7 +9430,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 if (!(value1 = add_load_component(ctx, params->instrs, cast1, j * cast1->data_type->dimx + k, loc))) return false; -@@ -2868,7 +3040,7 @@ static bool intrinsic_mul(struct hlsl_ctx *ctx, +@@ -2868,7 +3035,7 @@ static bool intrinsic_mul(struct hlsl_ctx *ctx, if (!(value2 = add_load_component(ctx, params->instrs, cast2, k * cast2->data_type->dimx + i, loc))) return false; @@ -9350,7 +9439,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 return false; if (instr) -@@ -2882,13 +3054,13 @@ static bool intrinsic_mul(struct hlsl_ctx *ctx, +@@ -2882,13 +3049,13 @@ static bool intrinsic_mul(struct hlsl_ctx *ctx, } } @@ -9366,7 +9455,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 return false; list_add_tail(params->instrs, &load->node.entry); -@@ -2901,7 +3073,7 @@ static bool intrinsic_normalize(struct hlsl_ctx *ctx, +@@ -2901,7 +3068,7 @@ static bool intrinsic_normalize(struct hlsl_ctx *ctx, struct hlsl_type *type = params->args[0]->data_type; struct hlsl_ir_node *dot, *rsq, *arg; @@ -9375,26 +9464,26 @@ index fd1eaf6ec95..dae1851c7ad 100644 { struct vkd3d_string_buffer *string; -@@ -2986,6 +3158,42 @@ static bool intrinsic_saturate(struct hlsl_ctx *ctx, +@@ -2986,6 +3153,42 @@ static bool intrinsic_saturate(struct hlsl_ctx *ctx, return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_SAT, arg, loc); } +static bool intrinsic_sign(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ -+ struct hlsl_ir_node *lt, *neg, *op1, *op2, *arg = params->args[0]; -+ struct hlsl_ir_constant *zero; ++ struct hlsl_ir_node *lt, *neg, *op1, *op2, *zero, *arg = params->args[0]; ++ static const struct hlsl_constant_value zero_value; + + struct hlsl_type *int_type = hlsl_get_numeric_type(ctx, arg->data_type->class, HLSL_TYPE_INT, + arg->data_type->dimx, arg->data_type->dimy); + -+ if (!(zero = hlsl_new_constant(ctx, hlsl_get_scalar_type(ctx, arg->data_type->base_type), loc))) ++ if (!(zero = hlsl_new_constant(ctx, hlsl_get_scalar_type(ctx, arg->data_type->base_type), &zero_value, loc))) + return false; -+ list_add_tail(params->instrs, &zero->node.entry); ++ list_add_tail(params->instrs, &zero->entry); + + /* Check if 0 < arg, cast bool to int */ + -+ if (!(lt = add_binary_comparison_expr(ctx, params->instrs, HLSL_OP2_LESS, &zero->node, arg, loc))) ++ if (!(lt = add_binary_comparison_expr(ctx, params->instrs, HLSL_OP2_LESS, zero, arg, loc))) + return false; + + if (!(op1 = add_implicit_conversion(ctx, params->instrs, lt, int_type, loc))) @@ -9402,7 +9491,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 + + /* Check if arg < 0, cast bool to int and invert (meaning true is -1) */ + -+ if (!(lt = add_binary_comparison_expr(ctx, params->instrs, HLSL_OP2_LESS, arg, &zero->node, loc))) ++ if (!(lt = add_binary_comparison_expr(ctx, params->instrs, HLSL_OP2_LESS, arg, zero, loc))) + return false; + + if (!(op2 = add_implicit_conversion(ctx, params->instrs, lt, int_type, loc))) @@ -9418,7 +9507,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 static bool intrinsic_sin(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { -@@ -3001,8 +3209,7 @@ static bool intrinsic_sin(struct hlsl_ctx *ctx, +@@ -3001,8 +3204,7 @@ static bool intrinsic_sin(struct hlsl_ctx *ctx, static bool intrinsic_smoothstep(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { @@ -9428,7 +9517,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 if (!elementwise_intrinsic_float_convert_args(ctx, params, loc)) return false; -@@ -3022,9 +3229,9 @@ static bool intrinsic_smoothstep(struct hlsl_ctx *ctx, +@@ -3022,9 +3224,9 @@ static bool intrinsic_smoothstep(struct hlsl_ctx *ctx, if (!(one = hlsl_new_float_constant(ctx, 1.0, loc))) return false; @@ -9440,7 +9529,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 return false; if (!(p = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, p_num, p_denom, loc))) -@@ -3035,16 +3242,16 @@ static bool intrinsic_smoothstep(struct hlsl_ctx *ctx, +@@ -3035,16 +3237,16 @@ static bool intrinsic_smoothstep(struct hlsl_ctx *ctx, if (!(minus_two = hlsl_new_float_constant(ctx, -2.0, loc))) return false; @@ -9461,7 +9550,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 return false; if (!(p = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, p, p, loc))) -@@ -3081,7 +3288,7 @@ static bool intrinsic_step(struct hlsl_ctx *ctx, +@@ -3081,7 +3283,7 @@ static bool intrinsic_step(struct hlsl_ctx *ctx, return false; type = ge->data_type; @@ -9470,7 +9559,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 return !!add_implicit_conversion(ctx, params->instrs, ge, type, loc); } -@@ -3090,9 +3297,7 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer * +@@ -3090,9 +3292,7 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer * { struct hlsl_resource_load_params load_params = {.type = HLSL_RESOURCE_SAMPLE}; const struct hlsl_type *sampler_type; @@ -9481,7 +9570,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 if (params->args_count != 2 && params->args_count != 4) { -@@ -3107,7 +3312,7 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer * +@@ -3107,7 +3307,7 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer * } sampler_type = params->args[0]->data_type; @@ -9490,7 +9579,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 || (sampler_type->sampler_dim != dim && sampler_type->sampler_dim != HLSL_SAMPLER_DIM_GENERIC)) { struct vkd3d_string_buffer *string; -@@ -3118,24 +3323,19 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer * +@@ -3118,24 +3318,19 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer * name, ctx->builtin_types.sampler[dim]->name, string->buffer); hlsl_release_string_buffer(ctx, string); } @@ -9518,7 +9607,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 return true; } -@@ -3156,13 +3356,14 @@ static bool intrinsic_transpose(struct hlsl_ctx *ctx, +@@ -3156,13 +3351,14 @@ static bool intrinsic_transpose(struct hlsl_ctx *ctx, { struct hlsl_ir_node *arg = params->args[0]; struct hlsl_type *arg_type = arg->data_type; @@ -9535,7 +9624,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 { struct vkd3d_string_buffer *string; -@@ -3174,7 +3375,7 @@ static bool intrinsic_transpose(struct hlsl_ctx *ctx, +@@ -3174,7 +3370,7 @@ static bool intrinsic_transpose(struct hlsl_ctx *ctx, return false; } @@ -9544,7 +9633,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 { list_add_tail(params->instrs, &arg->entry); return true; -@@ -3190,21 +3391,75 @@ static bool intrinsic_transpose(struct hlsl_ctx *ctx, +@@ -3190,21 +3386,75 @@ static bool intrinsic_transpose(struct hlsl_ctx *ctx, { for (j = 0; j < arg_type->dimy; ++j) { @@ -9624,7 +9713,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 return true; } -@@ -3220,22 +3475,31 @@ static const struct intrinsic_function +@@ -3220,22 +3470,31 @@ static const struct intrinsic_function intrinsic_functions[] = { /* Note: these entries should be kept in alphabetical order. */ @@ -9656,7 +9745,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 {"max", 2, true, intrinsic_max}, {"min", 2, true, intrinsic_min}, {"mul", 2, true, intrinsic_mul}, -@@ -3245,6 +3509,7 @@ intrinsic_functions[] = +@@ -3245,6 +3504,7 @@ intrinsic_functions[] = {"round", 1, true, intrinsic_round}, {"rsqrt", 1, true, intrinsic_rsqrt}, {"saturate", 1, true, intrinsic_saturate}, @@ -9664,7 +9753,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 {"sin", 1, true, intrinsic_sin}, {"smoothstep", 3, true, intrinsic_smoothstep}, {"sqrt", 1, true, intrinsic_sqrt}, -@@ -3252,6 +3517,7 @@ intrinsic_functions[] = +@@ -3252,6 +3512,7 @@ intrinsic_functions[] = {"tex2D", -1, false, intrinsic_tex2D}, {"tex3D", -1, false, intrinsic_tex3D}, {"transpose", 1, true, intrinsic_transpose}, @@ -9672,7 +9761,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 }; static int intrinsic_function_name_compare(const void *a, const void *b) -@@ -3291,11 +3557,11 @@ static struct list *add_call(struct hlsl_ctx *ctx, const char *name, +@@ -3291,11 +3552,11 @@ static struct list *add_call(struct hlsl_ctx *ctx, const char *name, if (param->storage_modifiers & HLSL_STORAGE_IN) { @@ -9686,7 +9775,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 } } -@@ -3316,7 +3582,7 @@ static struct list *add_call(struct hlsl_ctx *ctx, const char *name, +@@ -3316,7 +3577,7 @@ static struct list *add_call(struct hlsl_ctx *ctx, const char *name, hlsl_error(ctx, &arg->loc, VKD3D_SHADER_ERROR_HLSL_MODIFIES_CONST, "Output argument to \"%s\" is const.", decl->func->name); @@ -9695,7 +9784,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 goto fail; list_add_tail(args->instrs, &load->node.entry); -@@ -3329,7 +3595,7 @@ static struct list *add_call(struct hlsl_ctx *ctx, const char *name, +@@ -3329,7 +3590,7 @@ static struct list *add_call(struct hlsl_ctx *ctx, const char *name, { struct hlsl_ir_load *load; @@ -9704,7 +9793,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 goto fail; list_add_tail(args->instrs, &load->node.entry); } -@@ -3360,7 +3626,7 @@ static struct list *add_call(struct hlsl_ctx *ctx, const char *name, +@@ -3360,7 +3621,7 @@ static struct list *add_call(struct hlsl_ctx *ctx, const char *name, for (i = 0; i < args->args_count; ++i) { @@ -9713,7 +9802,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 { struct vkd3d_string_buffer *string; -@@ -3397,71 +3663,408 @@ fail: +@@ -3397,20 +3658,20 @@ fail: } static struct list *add_constructor(struct hlsl_ctx *ctx, struct hlsl_type *type, @@ -9725,57 +9814,37 @@ index fd1eaf6ec95..dae1851c7ad 100644 unsigned int i, idx = 0; - if (!(var = hlsl_new_synthetic_var(ctx, "constructor", type, &loc))) -- return NULL; + if (!(var = hlsl_new_synthetic_var(ctx, "constructor", type, loc))) -+ return NULL; -+ -+ for (i = 0; i < params->args_count; ++i) -+ { -+ struct hlsl_ir_node *arg = params->args[i]; -+ + return NULL; + + for (i = 0; i < params->args_count; ++i) + { + struct hlsl_ir_node *arg = params->args[i]; + +- if (arg->data_type->type == HLSL_CLASS_OBJECT) + if (arg->data_type->class == HLSL_CLASS_OBJECT) -+ { -+ struct vkd3d_string_buffer *string; -+ -+ if ((string = hlsl_type_to_string(ctx, arg->data_type))) -+ hlsl_error(ctx, &arg->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, -+ "Invalid type %s for constructor argument.", string->buffer); -+ hlsl_release_string_buffer(ctx, string); -+ continue; -+ } -+ -+ initialize_var_components(ctx, params->instrs, var, &idx, arg); -+ } -+ -+ if (!(load = hlsl_new_var_load(ctx, var, loc))) -+ return NULL; -+ list_add_tail(params->instrs, &load->node.entry); -+ -+ vkd3d_free(params->args); -+ return params->instrs; -+} -+ -+static unsigned int hlsl_offset_dim_count(enum hlsl_sampler_dim dim) + { + struct vkd3d_string_buffer *string; + +@@ -3455,320 +3716,526 @@ static unsigned int hlsl_offset_dim_count(enum hlsl_sampler_dim dim) + } + } + +-static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *object, +- const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +-{ +- const struct hlsl_type *object_type = object->data_type; +- struct hlsl_ir_load *object_load; ++static bool raise_invalid_method_object_type(struct hlsl_ctx *ctx, const struct hlsl_type *object_type, ++ const char *method, const struct vkd3d_shader_location *loc) +{ -+ switch (dim) -+ { -+ case HLSL_SAMPLER_DIM_1D: -+ case HLSL_SAMPLER_DIM_1DARRAY: -+ return 1; -+ case HLSL_SAMPLER_DIM_2D: -+ case HLSL_SAMPLER_DIM_2DMS: -+ case HLSL_SAMPLER_DIM_2DARRAY: -+ case HLSL_SAMPLER_DIM_2DMSARRAY: -+ return 2; -+ case HLSL_SAMPLER_DIM_3D: -+ return 3; -+ case HLSL_SAMPLER_DIM_CUBE: -+ case HLSL_SAMPLER_DIM_CUBEARRAY: -+ /* Offset parameters not supported for these types. */ -+ return 0; -+ default: -+ vkd3d_unreachable(); -+ } ++ struct vkd3d_string_buffer *string; ++ ++ if ((string = hlsl_type_to_string(ctx, object_type))) ++ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, ++ "Method '%s' is not defined on type '%s'.", method, string->buffer); ++ hlsl_release_string_buffer(ctx, string); ++ return false; +} + +static bool add_load_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *object, @@ -9788,6 +9857,12 @@ index fd1eaf6ec95..dae1851c7ad 100644 + struct hlsl_ir_node *load; + bool multisampled; + ++ if (object_type->sampler_dim == HLSL_SAMPLER_DIM_CUBE ++ || object_type->sampler_dim == HLSL_SAMPLER_DIM_CUBEARRAY) ++ { ++ return raise_invalid_method_object_type(ctx, object_type, name, loc); ++ } ++ + multisampled = object_type->sampler_dim == HLSL_SAMPLER_DIM_2DMS + || object_type->sampler_dim == HLSL_SAMPLER_DIM_2DMSARRAY; + @@ -9841,6 +9916,12 @@ index fd1eaf6ec95..dae1851c7ad 100644 + const struct hlsl_type *sampler_type; + struct hlsl_ir_node *load; + ++ if (object_type->sampler_dim == HLSL_SAMPLER_DIM_2DMS ++ || object_type->sampler_dim == HLSL_SAMPLER_DIM_2DMSARRAY) ++ { ++ return raise_invalid_method_object_type(ctx, object_type, name, loc); ++ } ++ + if (params->args_count < 2 || params->args_count > 4 + !!offset_dim) + { + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, @@ -9889,6 +9970,80 @@ index fd1eaf6ec95..dae1851c7ad 100644 + return true; +} + ++static bool add_sample_cmp_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *object, ++ const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) ++{ ++ const struct hlsl_type *object_type = object->data_type; ++ const unsigned int sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim); ++ const unsigned int offset_dim = hlsl_offset_dim_count(object_type->sampler_dim); ++ struct hlsl_resource_load_params load_params = { 0 }; ++ const struct hlsl_type *sampler_type; ++ struct hlsl_ir_node *load; ++ ++ if (object_type->sampler_dim == HLSL_SAMPLER_DIM_2DMS ++ || object_type->sampler_dim == HLSL_SAMPLER_DIM_2DMSARRAY) ++ { ++ return raise_invalid_method_object_type(ctx, object_type, name, loc); ++ } ++ ++ if (!strcmp(name, "SampleCmpLevelZero")) ++ load_params.type = HLSL_RESOURCE_SAMPLE_CMP_LZ; ++ else ++ load_params.type = HLSL_RESOURCE_SAMPLE_CMP; ++ ++ if (params->args_count < 3 || params->args_count > 5 + !!offset_dim) ++ { ++ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, ++ "Wrong number of arguments to method '%s': expected from 3 to %u, but got %u.", ++ name, 5 + !!offset_dim, params->args_count); ++ return false; ++ } ++ ++ sampler_type = params->args[0]->data_type; ++ if (sampler_type->class != HLSL_CLASS_OBJECT || sampler_type->base_type != HLSL_TYPE_SAMPLER ++ || sampler_type->sampler_dim != HLSL_SAMPLER_DIM_COMPARISON) ++ { ++ struct vkd3d_string_buffer *string; ++ ++ if ((string = hlsl_type_to_string(ctx, sampler_type))) ++ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, ++ "Wrong type for argument 0 of %s(): expected 'SamplerComparisonState', but got '%s'.", ++ name, string->buffer); ++ hlsl_release_string_buffer(ctx, string); ++ return false; ++ } ++ ++ if (!(load_params.coords = add_implicit_conversion(ctx, instrs, params->args[1], ++ hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) ++ return false; ++ ++ if (!(load_params.cmp = add_implicit_conversion(ctx, instrs, params->args[2], ++ hlsl_get_scalar_type(ctx, HLSL_TYPE_FLOAT), loc))) ++ load_params.cmp = params->args[2]; ++ ++ if (offset_dim && params->args_count > 3) ++ { ++ if (!(load_params.texel_offset = add_implicit_conversion(ctx, instrs, params->args[2], ++ hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc))) ++ return false; ++ } ++ ++ if (params->args_count > 3 + !!offset_dim) ++ hlsl_fixme(ctx, loc, "%s() clamp parameter.", name); ++ if (params->args_count > 4 + !!offset_dim) ++ hlsl_fixme(ctx, loc, "Tiled resource status argument."); ++ ++ load_params.format = object_type->e.resource_format; ++ load_params.resource = object; ++ load_params.sampler = params->args[0]; ++ ++ if (!(load = hlsl_new_resource_load(ctx, &load_params, loc))) ++ return false; ++ list_add_tail(instrs, &load->entry); ++ ++ return true; ++} ++ +static bool add_gather_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *object, + const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ @@ -9900,6 +10055,14 @@ index fd1eaf6ec95..dae1851c7ad 100644 + struct hlsl_ir_node *load; + unsigned int read_channel; + ++ if (object_type->sampler_dim != HLSL_SAMPLER_DIM_2D ++ && object_type->sampler_dim != HLSL_SAMPLER_DIM_2DARRAY ++ && object_type->sampler_dim != HLSL_SAMPLER_DIM_CUBE ++ && object_type->sampler_dim != HLSL_SAMPLER_DIM_CUBEARRAY) ++ { ++ return raise_invalid_method_object_type(ctx, object_type, name, loc); ++ } ++ + if (!strcmp(name, "GatherGreen")) + { + load_params.type = HLSL_RESOURCE_GATHER_GREEN; @@ -9941,7 +10104,9 @@ index fd1eaf6ec95..dae1851c7ad 100644 + + if (params->args_count == 3 + !!offset_dim || params->args_count == 7) + hlsl_fixme(ctx, loc, "Tiled resource status argument."); -+ + +- if (object_type->type != HLSL_CLASS_OBJECT || object_type->base_type != HLSL_TYPE_TEXTURE +- || object_type->sampler_dim == HLSL_SAMPLER_DIM_GENERIC) + if (params->args_count == 6 || params->args_count == 7) + { + hlsl_fixme(ctx, loc, "Multiple %s() offset parameters.", name); @@ -9956,225 +10121,25 @@ index fd1eaf6ec95..dae1851c7ad 100644 + sampler_type = params->args[0]->data_type; + if (sampler_type->class != HLSL_CLASS_OBJECT || sampler_type->base_type != HLSL_TYPE_SAMPLER + || sampler_type->sampler_dim != HLSL_SAMPLER_DIM_GENERIC) -+ { -+ struct vkd3d_string_buffer *string; -+ -+ if ((string = hlsl_type_to_string(ctx, sampler_type))) -+ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, -+ "Wrong type for argument 1 of %s(): expected 'sampler', but got '%s'.", name, string->buffer); -+ hlsl_release_string_buffer(ctx, string); -+ return false; -+ } -+ -+ if (read_channel >= object_type->e.resource_format->dimx) -+ { -+ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, -+ "Method %s() requires at least %u channels.", name, read_channel + 1); -+ return false; -+ } -+ -+ if (!(load_params.coords = add_implicit_conversion(ctx, instrs, params->args[1], -+ hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) -+ return false; -+ -+ load_params.format = hlsl_get_vector_type(ctx, object_type->e.resource_format->base_type, 4); -+ load_params.resource = object; -+ load_params.sampler = params->args[0]; -+ -+ if (!(load = hlsl_new_resource_load(ctx, &load_params, loc))) -+ return false; -+ list_add_tail(instrs, &load->entry); -+ return true; -+} -+ -+static bool add_sample_lod_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *object, -+ const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) -+{ -+ const struct hlsl_type *object_type = object->data_type; -+ struct hlsl_resource_load_params load_params = { 0 }; -+ const unsigned int sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim); -+ const unsigned int offset_dim = hlsl_offset_dim_count(object_type->sampler_dim); -+ const struct hlsl_type *sampler_type; -+ struct hlsl_ir_node *load; -+ -+ if (!strcmp(name, "SampleLevel")) -+ load_params.type = HLSL_RESOURCE_SAMPLE_LOD; -+ else -+ load_params.type = HLSL_RESOURCE_SAMPLE_LOD_BIAS; -+ -+ if (params->args_count < 3 || params->args_count > 4 + !!offset_dim) -+ { -+ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, -+ "Wrong number of arguments to method '%s': expected from 3 to %u, but got %u.", -+ name, 4 + !!offset_dim, params->args_count); -+ return false; -+ } -+ -+ sampler_type = params->args[0]->data_type; -+ if (sampler_type->class != HLSL_CLASS_OBJECT || sampler_type->base_type != HLSL_TYPE_SAMPLER -+ || sampler_type->sampler_dim != HLSL_SAMPLER_DIM_GENERIC) -+ { -+ struct vkd3d_string_buffer *string; -+ -+ if ((string = hlsl_type_to_string(ctx, sampler_type))) -+ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, -+ "Wrong type for argument 0 of %s(): expected 'sampler', but got '%s'.", name, string->buffer); -+ hlsl_release_string_buffer(ctx, string); -+ return false; -+ } -+ -+ if (!(load_params.coords = add_implicit_conversion(ctx, instrs, params->args[1], -+ hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) -+ load_params.coords = params->args[1]; -+ -+ if (!(load_params.lod = add_implicit_conversion(ctx, instrs, params->args[2], -+ hlsl_get_scalar_type(ctx, HLSL_TYPE_FLOAT), loc))) -+ load_params.lod = params->args[2]; -+ -+ if (offset_dim && params->args_count > 3) -+ { -+ if (!(load_params.texel_offset = add_implicit_conversion(ctx, instrs, params->args[3], -+ hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc))) -+ return false; -+ } -+ -+ if (params->args_count > 3 + !!offset_dim) -+ hlsl_fixme(ctx, loc, "Tiled resource status argument."); -+ -+ load_params.format = object_type->e.resource_format; -+ load_params.resource = object; -+ load_params.sampler = params->args[0]; -+ -+ if (!(load = hlsl_new_resource_load(ctx, &load_params, loc))) -+ return false; -+ list_add_tail(instrs, &load->entry); -+ return true; -+} -+ -+static bool add_sample_grad_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *object, -+ const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) -+{ -+ const struct hlsl_type *object_type = object->data_type; -+ struct hlsl_resource_load_params load_params = { 0 }; -+ const unsigned int sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim); -+ const unsigned int offset_dim = hlsl_offset_dim_count(object_type->sampler_dim); -+ const struct hlsl_type *sampler_type; -+ struct hlsl_ir_node *load; -+ -+ load_params.type = HLSL_RESOURCE_SAMPLE_GRAD; - -- for (i = 0; i < params->args_count; ++i) -+ if (params->args_count < 4 || params->args_count > 5 + !!offset_dim) - { -- struct hlsl_ir_node *arg = params->args[i]; -- -- if (arg->data_type->type == HLSL_CLASS_OBJECT) -- { -- struct vkd3d_string_buffer *string; -+ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, -+ "Wrong number of arguments to method '%s': expected from 4 to %u, but got %u.", -+ name, 5 + !!offset_dim, params->args_count); -+ return false; -+ } - -- if ((string = hlsl_type_to_string(ctx, arg->data_type))) -- hlsl_error(ctx, &arg->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, -- "Invalid type %s for constructor argument.", string->buffer); -- hlsl_release_string_buffer(ctx, string); -- continue; -- } -+ sampler_type = params->args[0]->data_type; -+ if (sampler_type->class != HLSL_CLASS_OBJECT || sampler_type->base_type != HLSL_TYPE_SAMPLER -+ || sampler_type->sampler_dim != HLSL_SAMPLER_DIM_GENERIC) -+ { -+ struct vkd3d_string_buffer *string; - -- initialize_var_components(ctx, params->instrs, var, &idx, arg); -+ if ((string = hlsl_type_to_string(ctx, sampler_type))) -+ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, -+ "Wrong type for argument 0 of %s(): expected 'sampler', but got '%s'.", name, string->buffer); -+ hlsl_release_string_buffer(ctx, string); -+ return false; - } - -- if (!(load = hlsl_new_var_load(ctx, var, loc))) -- return NULL; -- list_add_tail(params->instrs, &load->node.entry); -+ if (!(load_params.coords = add_implicit_conversion(ctx, instrs, params->args[1], -+ hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) -+ load_params.coords = params->args[1]; - -- vkd3d_free(params->args); -- return params->instrs; --} -+ if (!(load_params.ddx = add_implicit_conversion(ctx, instrs, params->args[2], -+ hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) -+ load_params.ddx = params->args[2]; - --static unsigned int hlsl_offset_dim_count(enum hlsl_sampler_dim dim) --{ -- switch (dim) -+ if (!(load_params.ddy = add_implicit_conversion(ctx, instrs, params->args[3], -+ hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) -+ load_params.ddy = params->args[3]; -+ -+ if (offset_dim && params->args_count > 4) - { -- case HLSL_SAMPLER_DIM_1D: -- case HLSL_SAMPLER_DIM_1DARRAY: -- return 1; -- case HLSL_SAMPLER_DIM_2D: -- case HLSL_SAMPLER_DIM_2DMS: -- case HLSL_SAMPLER_DIM_2DARRAY: -- case HLSL_SAMPLER_DIM_2DMSARRAY: -- return 2; -- case HLSL_SAMPLER_DIM_3D: -- return 3; -- case HLSL_SAMPLER_DIM_CUBE: -- case HLSL_SAMPLER_DIM_CUBEARRAY: -- /* Offset parameters not supported for these types. */ -- return 0; -- default: -- vkd3d_unreachable(); -+ if (!(load_params.texel_offset = add_implicit_conversion(ctx, instrs, params->args[4], -+ hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc))) -+ return false; - } -+ -+ if (params->args_count > 4 + !!offset_dim) -+ hlsl_fixme(ctx, loc, "Tiled resource status argument."); -+ -+ load_params.format = object_type->e.resource_format; -+ load_params.resource = object; -+ load_params.sampler = params->args[0]; -+ -+ if (!(load = hlsl_new_resource_load(ctx, &load_params, loc))) -+ return false; -+ list_add_tail(instrs, &load->entry); -+ return true; - } - - static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *object, - const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) - { - const struct hlsl_type *object_type = object->data_type; -- struct hlsl_ir_load *object_load; - -- if (object_type->type != HLSL_CLASS_OBJECT || object_type->base_type != HLSL_TYPE_TEXTURE -+ if (object_type->class != HLSL_CLASS_OBJECT || object_type->base_type != HLSL_TYPE_TEXTURE - || object_type->sampler_dim == HLSL_SAMPLER_DIM_GENERIC) { struct vkd3d_string_buffer *string; -@@ -3473,119 +4076,17 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl + +- if ((string = hlsl_type_to_string(ctx, object_type))) ++ if ((string = hlsl_type_to_string(ctx, sampler_type))) + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, +- "Type '%s' does not have methods.", string->buffer); ++ "Wrong type for argument 1 of %s(): expected 'sampler', but got '%s'.", name, string->buffer); + hlsl_release_string_buffer(ctx, string); return false; } - /* Only HLSL_IR_LOAD can return an object. */ - object_load = hlsl_ir_load(object); - - if (!strcmp(name, "Load") - && object_type->sampler_dim != HLSL_SAMPLER_DIM_CUBE - && object_type->sampler_dim != HLSL_SAMPLER_DIM_CUBEARRAY) +- if (!strcmp(name, "Load") +- && object_type->sampler_dim != HLSL_SAMPLER_DIM_CUBE +- && object_type->sampler_dim != HLSL_SAMPLER_DIM_CUBEARRAY) ++ if (read_channel >= object_type->e.resource_format->dimx) { - const unsigned int sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim); - const unsigned int offset_dim = hlsl_offset_dim_count(object_type->sampler_dim); @@ -10184,7 +10149,11 @@ index fd1eaf6ec95..dae1851c7ad 100644 - - multisampled = object_type->sampler_dim == HLSL_SAMPLER_DIM_2DMS - || object_type->sampler_dim == HLSL_SAMPLER_DIM_2DMSARRAY; -- ++ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, ++ "Method %s() requires at least %u channels.", name, read_channel + 1); ++ return false; ++ } + - if (params->args_count < 1 + multisampled || params->args_count > 3 + multisampled) - { - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, @@ -10196,7 +10165,10 @@ index fd1eaf6ec95..dae1851c7ad 100644 - { - hlsl_fixme(ctx, loc, "Load() sampling index parameter."); - } -- ++ if (!(load_params.coords = add_implicit_conversion(ctx, instrs, params->args[1], ++ hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) ++ return false; + - assert(offset_dim); - if (params->args_count > 1 + multisampled) - { @@ -10208,24 +10180,51 @@ index fd1eaf6ec95..dae1851c7ad 100644 - { - hlsl_fixme(ctx, loc, "Tiled resource status argument."); - } -- ++ load_params.format = hlsl_get_vector_type(ctx, object_type->e.resource_format->base_type, 4); ++ load_params.resource = object; ++ load_params.sampler = params->args[0]; + - /* +1 for the mipmap level */ - if (!(load_params.coords = add_implicit_conversion(ctx, instrs, params->args[0], - hlsl_get_vector_type(ctx, HLSL_TYPE_INT, sampler_dim + 1), loc))) - return false; -- ++ if (!(load = hlsl_new_resource_load(ctx, &load_params, loc))) ++ return false; ++ list_add_tail(instrs, &load->entry); ++ return true; ++} + - load_params.format = object_type->e.resource_format; - load_params.resource = object_load->src; -- ++static bool add_sample_lod_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *object, ++ const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) ++{ ++ const struct hlsl_type *object_type = object->data_type; ++ struct hlsl_resource_load_params load_params = { 0 }; ++ const unsigned int sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim); ++ const unsigned int offset_dim = hlsl_offset_dim_count(object_type->sampler_dim); ++ const struct hlsl_type *sampler_type; ++ struct hlsl_ir_node *load; + - if (!(load = hlsl_new_resource_load(ctx, &load_params, loc))) - return false; - list_add_tail(instrs, &load->node.entry); - return true; -+ return add_load_method_call(ctx, instrs, object, name, params, loc); ++ if (object_type->sampler_dim == HLSL_SAMPLER_DIM_2DMS ++ || object_type->sampler_dim == HLSL_SAMPLER_DIM_2DMSARRAY) ++ { ++ return raise_invalid_method_object_type(ctx, object_type, name, loc); } - else if (!strcmp(name, "Sample") - && object_type->sampler_dim != HLSL_SAMPLER_DIM_2DMS - && object_type->sampler_dim != HLSL_SAMPLER_DIM_2DMSARRAY) +- else if (!strcmp(name, "Sample") +- && object_type->sampler_dim != HLSL_SAMPLER_DIM_2DMS +- && object_type->sampler_dim != HLSL_SAMPLER_DIM_2DMSARRAY) ++ ++ if (!strcmp(name, "SampleLevel")) ++ load_params.type = HLSL_RESOURCE_SAMPLE_LOD; ++ else ++ load_params.type = HLSL_RESOURCE_SAMPLE_LOD_BIAS; ++ ++ if (params->args_count < 3 || params->args_count > 4 + !!offset_dim) { - const unsigned int sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim); - const unsigned int offset_dim = hlsl_offset_dim_count(object_type->sampler_dim); @@ -10233,7 +10232,12 @@ index fd1eaf6ec95..dae1851c7ad 100644 - const struct hlsl_type *sampler_type; - struct hlsl_ir_resource_load *load; - struct hlsl_ir_load *sampler_load; -- ++ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, ++ "Wrong number of arguments to method '%s': expected from 3 to %u, but got %u.", ++ name, 4 + !!offset_dim, params->args_count); ++ return false; ++ } + - if (params->args_count < 2 || params->args_count > 4 + !!offset_dim) - { - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, @@ -10241,55 +10245,98 @@ index fd1eaf6ec95..dae1851c7ad 100644 - 4 + !!offset_dim, params->args_count); - return false; - } -- ++ sampler_type = params->args[0]->data_type; ++ if (sampler_type->class != HLSL_CLASS_OBJECT || sampler_type->base_type != HLSL_TYPE_SAMPLER ++ || sampler_type->sampler_dim != HLSL_SAMPLER_DIM_GENERIC) ++ { ++ struct vkd3d_string_buffer *string; + - sampler_type = params->args[0]->data_type; - if (sampler_type->type != HLSL_CLASS_OBJECT || sampler_type->base_type != HLSL_TYPE_SAMPLER - || sampler_type->sampler_dim != HLSL_SAMPLER_DIM_GENERIC) - { - struct vkd3d_string_buffer *string; -- ++ if ((string = hlsl_type_to_string(ctx, sampler_type))) ++ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, ++ "Wrong type for argument 0 of %s(): expected 'sampler', but got '%s'.", name, string->buffer); ++ hlsl_release_string_buffer(ctx, string); ++ return false; ++ } + - if ((string = hlsl_type_to_string(ctx, sampler_type))) - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, - "Wrong type for argument 0 of Sample(): expected 'sampler', but got '%s'.", string->buffer); - hlsl_release_string_buffer(ctx, string); - return false; - } -- ++ if (!(load_params.coords = add_implicit_conversion(ctx, instrs, params->args[1], ++ hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) ++ load_params.coords = params->args[1]; + - /* Only HLSL_IR_LOAD can return an object. */ - sampler_load = hlsl_ir_load(params->args[0]); -- ++ if (!(load_params.lod = add_implicit_conversion(ctx, instrs, params->args[2], ++ hlsl_get_scalar_type(ctx, HLSL_TYPE_FLOAT), loc))) ++ load_params.lod = params->args[2]; + - if (!(load_params.coords = add_implicit_conversion(ctx, instrs, params->args[1], - hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) -- return false; -- ++ if (offset_dim && params->args_count > 3) ++ { ++ if (!(load_params.texel_offset = add_implicit_conversion(ctx, instrs, params->args[3], ++ hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc))) + return false; ++ } + - if (offset_dim && params->args_count > 2) - { - if (!(load_params.texel_offset = add_implicit_conversion(ctx, instrs, params->args[2], - hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc))) - return false; - } -- ++ if (params->args_count > 3 + !!offset_dim) ++ hlsl_fixme(ctx, loc, "Tiled resource status argument."); + - if (params->args_count > 2 + !!offset_dim) - hlsl_fixme(ctx, loc, "Sample() clamp parameter."); - if (params->args_count > 3 + !!offset_dim) - hlsl_fixme(ctx, loc, "Tiled resource status argument."); -- ++ load_params.format = object_type->e.resource_format; ++ load_params.resource = object; ++ load_params.sampler = params->args[0]; + - load_params.format = object_type->e.resource_format; - load_params.resource = object_load->src; - load_params.sampler = sampler_load->src; -- ++ if (!(load = hlsl_new_resource_load(ctx, &load_params, loc))) ++ return false; ++ list_add_tail(instrs, &load->entry); ++ return true; ++} + - if (!(load = hlsl_new_resource_load(ctx, &load_params, loc))) - return false; - list_add_tail(instrs, &load->node.entry); -- ++static bool add_sample_grad_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *object, ++ const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) ++{ ++ const struct hlsl_type *object_type = object->data_type; ++ struct hlsl_resource_load_params load_params = { 0 }; ++ const unsigned int sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim); ++ const unsigned int offset_dim = hlsl_offset_dim_count(object_type->sampler_dim); ++ const struct hlsl_type *sampler_type; ++ struct hlsl_ir_node *load; + - return true; -+ return add_sample_method_call(ctx, instrs, object, name, params, loc); - } - else if ((!strcmp(name, "Gather") || !strcmp(name, "GatherRed") || !strcmp(name, "GatherBlue") - || !strcmp(name, "GatherGreen") || !strcmp(name, "GatherAlpha")) -@@ -3594,164 +4095,25 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl - || object_type->sampler_dim == HLSL_SAMPLER_DIM_CUBE - || object_type->sampler_dim == HLSL_SAMPLER_DIM_CUBEARRAY)) +- } +- else if ((!strcmp(name, "Gather") || !strcmp(name, "GatherRed") || !strcmp(name, "GatherBlue") +- || !strcmp(name, "GatherGreen") || !strcmp(name, "GatherAlpha")) +- && (object_type->sampler_dim == HLSL_SAMPLER_DIM_2D +- || object_type->sampler_dim == HLSL_SAMPLER_DIM_2DARRAY +- || object_type->sampler_dim == HLSL_SAMPLER_DIM_CUBE +- || object_type->sampler_dim == HLSL_SAMPLER_DIM_CUBEARRAY)) ++ if (object_type->sampler_dim == HLSL_SAMPLER_DIM_2DMS ++ || object_type->sampler_dim == HLSL_SAMPLER_DIM_2DMSARRAY) { - const unsigned int sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim); - const unsigned int offset_dim = hlsl_offset_dim_count(object_type->sampler_dim); @@ -10340,7 +10387,9 @@ index fd1eaf6ec95..dae1851c7ad 100644 - - if (params->args_count == 3 + !!offset_dim || params->args_count == 7) - hlsl_fixme(ctx, loc, "Tiled resource status argument."); -- ++ return raise_invalid_method_object_type(ctx, object_type, name, loc); ++ } + - if (params->args_count == 6 || params->args_count == 7) - { - hlsl_fixme(ctx, loc, "Multiple %s() offset parameters.", name); @@ -10351,47 +10400,74 @@ index fd1eaf6ec95..dae1851c7ad 100644 - hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc))) - return false; - } -- ++ load_params.type = HLSL_RESOURCE_SAMPLE_GRAD; + - sampler_type = params->args[0]->data_type; - if (sampler_type->type != HLSL_CLASS_OBJECT || sampler_type->base_type != HLSL_TYPE_SAMPLER - || sampler_type->sampler_dim != HLSL_SAMPLER_DIM_GENERIC) - { - struct vkd3d_string_buffer *string; -- ++ if (params->args_count < 4 || params->args_count > 5 + !!offset_dim) ++ { ++ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, ++ "Wrong number of arguments to method '%s': expected from 4 to %u, but got %u.", ++ name, 5 + !!offset_dim, params->args_count); ++ return false; ++ } + - if ((string = hlsl_type_to_string(ctx, sampler_type))) - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, - "Wrong type for argument 1 of %s(): expected 'sampler', but got '%s'.", name, string->buffer); - hlsl_release_string_buffer(ctx, string); - return false; - } -- ++ sampler_type = params->args[0]->data_type; ++ if (sampler_type->class != HLSL_CLASS_OBJECT || sampler_type->base_type != HLSL_TYPE_SAMPLER ++ || sampler_type->sampler_dim != HLSL_SAMPLER_DIM_GENERIC) ++ { ++ struct vkd3d_string_buffer *string; + - if (read_channel >= object_type->e.resource_format->dimx) - { -- hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, ++ if ((string = hlsl_type_to_string(ctx, sampler_type))) + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, - "Method %s() requires at least %u channels.", name, read_channel + 1); - return false; - } -- ++ "Wrong type for argument 0 of %s(): expected 'sampler', but got '%s'.", name, string->buffer); ++ hlsl_release_string_buffer(ctx, string); ++ return false; ++ } + - /* Only HLSL_IR_LOAD can return an object. */ - sampler_load = hlsl_ir_load(params->args[0]); -- ++ if (!(load_params.coords = add_implicit_conversion(ctx, instrs, params->args[1], ++ hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) ++ load_params.coords = params->args[1]; + - if (!(load_params.coords = add_implicit_conversion(ctx, instrs, params->args[1], - hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) - return false; -- ++ if (!(load_params.ddx = add_implicit_conversion(ctx, instrs, params->args[2], ++ hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) ++ load_params.ddx = params->args[2]; + - load_params.format = hlsl_get_vector_type(ctx, object_type->e.resource_format->base_type, 4); - load_params.resource = object_load->src; - load_params.sampler = sampler_load->src; -- ++ if (!(load_params.ddy = add_implicit_conversion(ctx, instrs, params->args[3], ++ hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) ++ load_params.ddy = params->args[3]; + - if (!(load = hlsl_new_resource_load(ctx, &load_params, loc))) - return false; - list_add_tail(instrs, &load->node.entry); - return true; -+ return add_gather_method_call(ctx, instrs, object, name, params, loc); - } - else if (!strcmp(name, "SampleLevel") - && object_type->sampler_dim != HLSL_SAMPLER_DIM_2DMS - && object_type->sampler_dim != HLSL_SAMPLER_DIM_2DMSARRAY) +- } +- else if (!strcmp(name, "SampleLevel") +- && object_type->sampler_dim != HLSL_SAMPLER_DIM_2DMS +- && object_type->sampler_dim != HLSL_SAMPLER_DIM_2DMSARRAY) ++ if (offset_dim && params->args_count > 4) { - struct hlsl_resource_load_params load_params = {.type = HLSL_RESOURCE_SAMPLE_LOD}; - const unsigned int sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim); @@ -10405,7 +10481,9 @@ index fd1eaf6ec95..dae1851c7ad 100644 - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, - "Wrong number of arguments to method 'SampleLevel': expected from 3 to %u, but got %u.", - 4 + !!offset_dim, params->args_count); -- return false; ++ if (!(load_params.texel_offset = add_implicit_conversion(ctx, instrs, params->args[4], ++ hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc))) + return false; - } - - sampler_type = params->args[0]->data_type; @@ -10413,60 +10491,114 @@ index fd1eaf6ec95..dae1851c7ad 100644 - || sampler_type->sampler_dim != HLSL_SAMPLER_DIM_GENERIC) - { - struct vkd3d_string_buffer *string; -- ++ } + - if ((string = hlsl_type_to_string(ctx, sampler_type))) - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, - "Wrong type for argument 0 of SampleLevel(): expected 'sampler', but got '%s'.", string->buffer); - hlsl_release_string_buffer(ctx, string); - return false; - } -- ++ if (params->args_count > 4 + !!offset_dim) ++ hlsl_fixme(ctx, loc, "Tiled resource status argument."); + - /* Only HLSL_IR_LOAD can return an object. */ - sampler_load = hlsl_ir_load(params->args[0]); -- ++ load_params.format = object_type->e.resource_format; ++ load_params.resource = object; ++ load_params.sampler = params->args[0]; + - if (!(load_params.coords = add_implicit_conversion(ctx, instrs, params->args[1], - hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) - load_params.coords = params->args[1]; -- ++ if (!(load = hlsl_new_resource_load(ctx, &load_params, loc))) ++ return false; ++ list_add_tail(instrs, &load->entry); ++ return true; ++} + - if (!(load_params.lod = add_implicit_conversion(ctx, instrs, params->args[2], - hlsl_get_scalar_type(ctx, HLSL_TYPE_FLOAT), loc))) - load_params.lod = params->args[2]; -- ++static const struct method_function ++{ ++ const char *name; ++ bool (*handler)(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *object, ++ const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc); ++} ++object_methods[] = ++{ ++ { "Gather", add_gather_method_call }, ++ { "GatherAlpha", add_gather_method_call }, ++ { "GatherBlue", add_gather_method_call }, ++ { "GatherGreen", add_gather_method_call }, ++ { "GatherRed", add_gather_method_call }, ++ ++ { "Load", add_load_method_call }, ++ ++ { "Sample", add_sample_method_call }, ++ { "SampleBias", add_sample_lod_method_call }, ++ { "SampleCmp", add_sample_cmp_method_call }, ++ { "SampleCmpLevelZero", add_sample_cmp_method_call }, ++ { "SampleGrad", add_sample_grad_method_call }, ++ { "SampleLevel", add_sample_lod_method_call }, ++}; + - if (offset_dim && params->args_count > 3) - { - if (!(load_params.texel_offset = add_implicit_conversion(ctx, instrs, params->args[3], - hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc))) - return false; - } -- ++static int object_method_function_name_compare(const void *a, const void *b) ++{ ++ const struct method_function *func = b; + - if (params->args_count > 3 + !!offset_dim) - hlsl_fixme(ctx, loc, "Tiled resource status argument."); -- ++ return strcmp(a, func->name); ++} + - load_params.format = object_type->e.resource_format; - load_params.resource = object_load->src; - load_params.sampler = sampler_load->src; -- ++static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *object, ++ const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) ++{ ++ const struct hlsl_type *object_type = object->data_type; ++ const struct method_function *method; + - if (!(load = hlsl_new_resource_load(ctx, &load_params, loc))) - return false; - list_add_tail(instrs, &load->node.entry); - return true; -+ return add_sample_lod_method_call(ctx, instrs, object, name, params, loc); -+ } -+ else if (!strcmp(name, "SampleBias") -+ && object_type->sampler_dim != HLSL_SAMPLER_DIM_2DMS -+ && object_type->sampler_dim != HLSL_SAMPLER_DIM_2DMSARRAY) -+ { -+ return add_sample_lod_method_call(ctx, instrs, object, name, params, loc); -+ } -+ else if (!strcmp(name, "SampleGrad") -+ && object_type->sampler_dim != HLSL_SAMPLER_DIM_2DMS -+ && object_type->sampler_dim != HLSL_SAMPLER_DIM_2DMSARRAY) -+ { -+ return add_sample_grad_method_call(ctx, instrs, object, name, params, loc); - } - else +- } +- else ++ if (object_type->class != HLSL_CLASS_OBJECT || object_type->base_type != HLSL_TYPE_TEXTURE ++ || object_type->sampler_dim == HLSL_SAMPLER_DIM_GENERIC) { -@@ -3768,7 +4130,7 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl + struct vkd3d_string_buffer *string; + + if ((string = hlsl_type_to_string(ctx, object_type))) +- hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, +- "Method '%s' is not defined on type '%s'.", name, string->buffer); ++ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, ++ "Type '%s' does not have methods.", string->buffer); + hlsl_release_string_buffer(ctx, string); + return false; + } ++ ++ if ((method = bsearch(name, object_methods, ARRAY_SIZE(object_methods), ++ sizeof(*method), object_method_function_name_compare))) ++ { ++ return method->handler(ctx, instrs, object, name, params, loc); ++ } ++ else ++ { ++ return raise_invalid_method_object_type(ctx, object_type, name, loc); ++ } + } + static void validate_texture_format_type(struct hlsl_ctx *ctx, struct hlsl_type *format, const struct vkd3d_shader_location *loc) { @@ -10475,7 +10607,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 { struct vkd3d_string_buffer *string; -@@ -3846,6 +4208,7 @@ static void validate_texture_format_type(struct hlsl_ctx *ctx, struct hlsl_type +@@ -3846,6 +4313,7 @@ static void validate_texture_format_type(struct hlsl_ctx *ctx, struct hlsl_type %token KW_NAMESPACE %token KW_NOINTERPOLATION %token KW_OUT @@ -10483,7 +10615,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 %token KW_PASS %token KW_PIXELSHADER %token KW_PRECISE -@@ -3854,6 +4217,8 @@ static void validate_texture_format_type(struct hlsl_ctx *ctx, struct hlsl_type +@@ -3854,6 +4322,8 @@ static void validate_texture_format_type(struct hlsl_ctx *ctx, struct hlsl_type %token KW_RETURN %token KW_REGISTER %token KW_ROW_MAJOR @@ -10492,7 +10624,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 %token KW_RWTEXTURE1D %token KW_RWTEXTURE2D %token KW_RWTEXTURE3D -@@ -3933,6 +4298,7 @@ static void validate_texture_format_type(struct hlsl_ctx *ctx, struct hlsl_type +@@ -3933,6 +4403,7 @@ static void validate_texture_format_type(struct hlsl_ctx *ctx, struct hlsl_type %type conditional_expr %type declaration %type declaration_statement @@ -10500,7 +10632,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 %type equality_expr %type expr %type expr_optional -@@ -3968,6 +4334,7 @@ static void validate_texture_format_type(struct hlsl_ctx *ctx, struct hlsl_type +@@ -3968,6 +4439,7 @@ static void validate_texture_format_type(struct hlsl_ctx *ctx, struct hlsl_type %type attribute %type attribute_list @@ -10508,7 +10640,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 %type boolean -@@ -3999,6 +4366,7 @@ static void validate_texture_format_type(struct hlsl_ctx *ctx, struct hlsl_type +@@ -3999,6 +4471,7 @@ static void validate_texture_format_type(struct hlsl_ctx *ctx, struct hlsl_type %type parameters %type register_opt @@ -10516,7 +10648,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 %type texture_type texture_ms_type uav_type -@@ -4037,7 +4405,7 @@ buffer_declaration: +@@ -4037,7 +4510,7 @@ buffer_declaration: if ($3.semantic.name) hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_INVALID_SEMANTIC, "Semantics are not allowed on buffers."); @@ -10525,7 +10657,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 YYABORT; } -@@ -4261,6 +4629,14 @@ attribute_list: +@@ -4261,6 +4734,14 @@ attribute_list: $$.attrs[$$.count++] = $2; } @@ -10540,7 +10672,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 func_declaration: func_prototype compound_statement { -@@ -4349,8 +4725,11 @@ func_prototype_no_attrs: +@@ -4349,8 +4830,11 @@ func_prototype_no_attrs: "Semantics are not allowed on void functions."); } @@ -10553,7 +10685,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 if (($$.decl = get_func_decl(&ctx->functions, $3, &$5))) { -@@ -4476,17 +4855,24 @@ var_identifier: +@@ -4476,17 +4960,24 @@ var_identifier: colon_attribute: %empty { @@ -10582,7 +10714,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 $$.reg_reservation = $1; } -@@ -4499,6 +4885,9 @@ semantic: +@@ -4499,6 +4990,9 @@ semantic: ; $$.name = $2; $$.index = atoi(p); @@ -10592,7 +10724,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 *p = 0; } -@@ -4518,6 +4907,21 @@ register_opt: +@@ -4518,6 +5012,21 @@ register_opt: vkd3d_free($6); } @@ -10614,7 +10746,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 parameters: scope_start { -@@ -4536,7 +4940,7 @@ param_list: +@@ -4536,7 +5045,7 @@ param_list: parameter { memset(&$$, 0, sizeof($$)); @@ -10623,7 +10755,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 { ERR("Error adding function parameter %s.\n", $1.name); YYABORT; -@@ -4545,7 +4949,7 @@ param_list: +@@ -4545,7 +5054,7 @@ param_list: | param_list ',' parameter { $$ = $1; @@ -10632,7 +10764,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 { hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_REDEFINED, "Parameter \"%s\" is already declared.", $3.name); -@@ -4624,7 +5028,15 @@ texture_ms_type: +@@ -4624,7 +5133,15 @@ texture_ms_type: } uav_type: @@ -10649,7 +10781,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 { $$ = HLSL_SAMPLER_DIM_1D; } -@@ -4640,7 +5052,7 @@ uav_type: +@@ -4640,7 +5157,7 @@ uav_type: type_no_void: KW_VECTOR '<' type ',' C_INTEGER '>' { @@ -10658,7 +10790,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 { struct vkd3d_string_buffer *string; -@@ -4667,7 +5079,7 @@ type_no_void: +@@ -4667,7 +5184,7 @@ type_no_void: } | KW_MATRIX '<' type ',' C_INTEGER ',' C_INTEGER '>' { @@ -10667,7 +10799,27 @@ index fd1eaf6ec95..dae1851c7ad 100644 { struct vkd3d_string_buffer *string; -@@ -4740,23 +5152,58 @@ type_no_void: +@@ -4702,6 +5219,10 @@ type_no_void: + { + $$ = ctx->builtin_types.sampler[HLSL_SAMPLER_DIM_GENERIC]; + } ++ | KW_SAMPLERCOMPARISONSTATE ++ { ++ $$ = ctx->builtin_types.sampler[HLSL_SAMPLER_DIM_COMPARISON]; ++ } + | KW_SAMPLER1D + { + $$ = ctx->builtin_types.sampler[HLSL_SAMPLER_DIM_1D]; +@@ -4716,7 +5237,7 @@ type_no_void: + } + | KW_SAMPLERCUBE + { +- $$ = ctx->builtin_types.sampler[HLSL_SAMPLER_DIM_3D]; ++ $$ = ctx->builtin_types.sampler[HLSL_SAMPLER_DIM_CUBE]; + } + | KW_TEXTURE + { +@@ -4740,23 +5261,58 @@ type_no_void: } | texture_ms_type '<' type ',' shift_expr '>' { @@ -10734,7 +10886,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 $$ = hlsl_new_uav_type(ctx, $1, $3); } | TYPE_IDENTIFIER -@@ -4779,7 +5226,7 @@ type_no_void: +@@ -4779,7 +5335,7 @@ type_no_void: | KW_STRUCT TYPE_IDENTIFIER { $$ = hlsl_get_type(ctx->cur_scope, $2, true, true); @@ -10743,7 +10895,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_REDEFINED, "\"%s\" redefined as a structure.", $2); vkd3d_free($2); } -@@ -4934,10 +5381,17 @@ arrays: +@@ -4934,10 +5490,17 @@ arrays: } | '[' expr ']' arrays { @@ -10763,7 +10915,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 $$ = $4; -@@ -4988,59 +5442,59 @@ var_modifiers: +@@ -4988,59 +5551,59 @@ var_modifiers: } | KW_EXTERN var_modifiers { @@ -10837,7 +10989,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 } -@@ -5145,6 +5599,7 @@ statement: +@@ -5145,6 +5708,7 @@ statement: declaration_statement | expr_statement | compound_statement @@ -10845,7 +10997,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 | jump_statement | selection_statement | loop_statement -@@ -5152,7 +5607,7 @@ statement: +@@ -5152,7 +5716,7 @@ statement: jump_statement: KW_RETURN expr ';' { @@ -10854,7 +11006,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 YYABORT; $$ = $2; } -@@ -5160,65 +5615,81 @@ jump_statement: +@@ -5160,65 +5724,81 @@ jump_statement: { if (!($$ = make_empty_list(ctx))) YYABORT; @@ -10959,7 +11111,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 hlsl_pop_scope(ctx); } -@@ -5250,31 +5721,31 @@ func_arguments: +@@ -5250,31 +5830,31 @@ func_arguments: primary_expr: C_FLOAT { @@ -10998,7 +11150,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 YYABORT; } } -@@ -5288,7 +5759,7 @@ primary_expr: +@@ -5288,7 +5868,7 @@ primary_expr: hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, "Variable \"%s\" is not defined.", $1); YYABORT; } @@ -11007,7 +11159,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 YYABORT; if (!($$ = make_list(ctx, &load->node))) YYABORT; -@@ -5316,7 +5787,7 @@ primary_expr: +@@ -5316,7 +5896,7 @@ primary_expr: if (!(var = hlsl_new_synthetic_var(ctx, "state_block_expr", hlsl_get_scalar_type(ctx, HLSL_TYPE_INT), &@1))) YYABORT; @@ -11016,7 +11168,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 YYABORT; if (!($$ = make_list(ctx, &load->node))) YYABORT; -@@ -5332,7 +5803,7 @@ postfix_expr: +@@ -5332,7 +5912,7 @@ postfix_expr: primary_expr | postfix_expr OP_INC { @@ -11025,7 +11177,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 { destroy_instr_list($1); YYABORT; -@@ -5341,7 +5812,7 @@ postfix_expr: +@@ -5341,7 +5921,7 @@ postfix_expr: } | postfix_expr OP_DEC { @@ -11034,7 +11186,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 { destroy_instr_list($1); YYABORT; -@@ -5352,7 +5823,7 @@ postfix_expr: +@@ -5352,7 +5932,7 @@ postfix_expr: { struct hlsl_ir_node *node = node_from_list($1); @@ -11043,7 +11195,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 { struct hlsl_type *type = node->data_type; const struct hlsl_struct_field *field; -@@ -5365,20 +5836,20 @@ postfix_expr: +@@ -5365,20 +5945,20 @@ postfix_expr: } field_idx = field - type->e.record.fields; @@ -11068,7 +11220,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 $$ = $1; } else -@@ -5391,10 +5862,10 @@ postfix_expr: +@@ -5391,10 +5971,10 @@ postfix_expr: { struct hlsl_ir_node *array = node_from_list($1), *index = node_from_list($3); @@ -11081,7 +11233,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 { destroy_instr_list($1); YYABORT; -@@ -5412,7 +5883,7 @@ postfix_expr: +@@ -5412,7 +5992,7 @@ postfix_expr: free_parse_initializer(&$4); YYABORT; } @@ -11090,7 +11242,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 { struct vkd3d_string_buffer *string; -@@ -5432,7 +5903,7 @@ postfix_expr: +@@ -5432,7 +6012,7 @@ postfix_expr: YYABORT; } @@ -11099,7 +11251,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 { free_parse_initializer(&$4); YYABORT; -@@ -5459,7 +5930,7 @@ unary_expr: +@@ -5459,7 +6039,7 @@ unary_expr: postfix_expr | OP_INC unary_expr { @@ -11108,7 +11260,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 { destroy_instr_list($2); YYABORT; -@@ -5468,7 +5939,7 @@ unary_expr: +@@ -5468,7 +6048,7 @@ unary_expr: } | OP_DEC unary_expr { @@ -11117,7 +11269,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 { destroy_instr_list($2); YYABORT; -@@ -5545,31 +6016,31 @@ mul_expr: +@@ -5545,31 +6125,31 @@ mul_expr: unary_expr | mul_expr '*' unary_expr { @@ -11155,7 +11307,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 } shift_expr: -@@ -5587,30 +6058,30 @@ relational_expr: +@@ -5587,30 +6167,30 @@ relational_expr: shift_expr | relational_expr '<' shift_expr { @@ -11192,7 +11344,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 } bitand_expr: -@@ -5652,7 +6123,26 @@ conditional_expr: +@@ -5652,7 +6232,26 @@ conditional_expr: logicor_expr | logicor_expr '?' expr ':' assignment_expr { @@ -11221,7 +11373,7 @@ index fd1eaf6ec95..dae1851c7ad 100644 assignment_expr: diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -index ab59875738c..bbb5223b1ec 100644 +index ab59875738c..4317604bdfa 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c @@ -27,11 +27,11 @@ static struct hlsl_ir_node *new_offset_from_path_index(struct hlsl_ctx *ctx, str @@ -11313,7 +11465,25 @@ index ab59875738c..bbb5223b1ec 100644 type = hlsl_get_element_type_from_path_index(ctx, type, deref->path[i].node); } -@@ -140,7 +140,7 @@ static void replace_deref_path_with_offset(struct hlsl_ctx *ctx, struct hlsl_der +@@ -123,15 +123,14 @@ static struct hlsl_ir_node *new_offset_instr_from_deref(struct hlsl_ctx *ctx, st + } + + /* TODO: remove when no longer needed, only used for transform_deref_paths_into_offsets() */ +-static void replace_deref_path_with_offset(struct hlsl_ctx *ctx, struct hlsl_deref *deref, ++static bool replace_deref_path_with_offset(struct hlsl_ctx *ctx, struct hlsl_deref *deref, + struct hlsl_ir_node *instr) + { + const struct hlsl_type *type; + struct hlsl_ir_node *offset; + struct hlsl_block block; + +- if (!deref->var) +- return; ++ assert(deref->var); + + /* register offsets shouldn't be used before this point is reached. */ + assert(!deref->offset.node); +@@ -140,48 +139,22 @@ static void replace_deref_path_with_offset(struct hlsl_ctx *ctx, struct hlsl_der /* Instructions that directly refer to structs or arrays (instead of single-register components) * are removed later by dce. So it is not a problem to just cleanup their derefs. */ @@ -11321,8 +11491,52 @@ index ab59875738c..bbb5223b1ec 100644 + if (type->class == HLSL_CLASS_STRUCT || type->class == HLSL_CLASS_ARRAY) { hlsl_cleanup_deref(deref); - return; -@@ -191,14 +191,14 @@ static void prepend_uniform_copy(struct hlsl_ctx *ctx, struct list *instrs, stru +- return; ++ return true; + } + + deref->offset_regset = hlsl_type_get_regset(type); + + if (!(offset = new_offset_instr_from_deref(ctx, &block, deref, &instr->loc))) +- return; ++ return false; + list_move_before(&instr->entry, &block.instrs); + + hlsl_cleanup_deref(deref); + hlsl_src_from_node(&deref->offset, offset); +-} +- +-/* TODO: remove when no longer needed. */ +-static bool transform_deref_paths_into_offsets(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +-{ +- switch(instr->type) +- { +- case HLSL_IR_LOAD: +- replace_deref_path_with_offset(ctx, &hlsl_ir_load(instr)->src, instr); +- return true; +- +- case HLSL_IR_STORE: +- replace_deref_path_with_offset(ctx, &hlsl_ir_store(instr)->lhs, instr); +- return true; + +- case HLSL_IR_RESOURCE_LOAD: +- replace_deref_path_with_offset(ctx, &hlsl_ir_resource_load(instr)->resource, instr); +- replace_deref_path_with_offset(ctx, &hlsl_ir_resource_load(instr)->sampler, instr); +- return true; +- +- case HLSL_IR_RESOURCE_STORE: +- replace_deref_path_with_offset(ctx, &hlsl_ir_resource_store(instr)->resource, instr); +- return true; +- +- default: +- return false; +- } +- return false; ++ return true; + } + + /* Split uniforms into two variables representing the constant and temp +@@ -191,14 +164,14 @@ static void prepend_uniform_copy(struct hlsl_ctx *ctx, struct list *instrs, stru { struct vkd3d_string_buffer *name; struct hlsl_ir_var *uniform; @@ -11339,7 +11553,7 @@ index ab59875738c..bbb5223b1ec 100644 return; list_add_before(&temp->scope_entry, &uniform->scope_entry); list_add_tail(&ctx->extern_vars, &uniform->extern_entry); -@@ -212,17 +212,53 @@ static void prepend_uniform_copy(struct hlsl_ctx *ctx, struct list *instrs, stru +@@ -212,17 +185,53 @@ static void prepend_uniform_copy(struct hlsl_ctx *ctx, struct list *instrs, stru temp->name = hlsl_strdup(ctx, name->buffer); hlsl_release_string_buffer(ctx, name); @@ -11396,7 +11610,7 @@ index ab59875738c..bbb5223b1ec 100644 { struct hlsl_semantic new_semantic; struct vkd3d_string_buffer *name; -@@ -230,15 +266,50 @@ static struct hlsl_ir_var *add_semantic_var(struct hlsl_ctx *ctx, struct hlsl_ir +@@ -230,15 +239,50 @@ static struct hlsl_ir_var *add_semantic_var(struct hlsl_ctx *ctx, struct hlsl_ir if (!(name = hlsl_get_string_buffer(ctx))) return NULL; @@ -11451,7 +11665,7 @@ index ab59875738c..bbb5223b1ec 100644 { hlsl_release_string_buffer(ctx, name); hlsl_cleanup_semantic(&new_semantic); -@@ -257,80 +328,116 @@ static struct hlsl_ir_var *add_semantic_var(struct hlsl_ctx *ctx, struct hlsl_ir +@@ -257,80 +301,116 @@ static struct hlsl_ir_var *add_semantic_var(struct hlsl_ctx *ctx, struct hlsl_ir } static void prepend_input_copy(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_load *lhs, @@ -11604,7 +11818,7 @@ index ab59875738c..bbb5223b1ec 100644 } } -@@ -341,45 +448,51 @@ static void prepend_input_var_copy(struct hlsl_ctx *ctx, struct list *instrs, st +@@ -341,45 +421,51 @@ static void prepend_input_var_copy(struct hlsl_ctx *ctx, struct list *instrs, st struct hlsl_ir_load *load; /* This redundant load is expected to be deleted later by DCE. */ @@ -11671,7 +11885,7 @@ index ab59875738c..bbb5223b1ec 100644 return; list_add_tail(instrs, &load->node.entry); } -@@ -394,38 +507,57 @@ static void append_output_copy(struct hlsl_ctx *ctx, struct list *instrs, struct +@@ -394,38 +480,57 @@ static void append_output_copy(struct hlsl_ctx *ctx, struct list *instrs, struct if (!(store = hlsl_new_simple_store(ctx, output, &load->node))) return; @@ -11750,7 +11964,7 @@ index ab59875738c..bbb5223b1ec 100644 } } -@@ -437,17 +569,14 @@ static void append_output_var_copy(struct hlsl_ctx *ctx, struct list *instrs, st +@@ -437,17 +542,14 @@ static void append_output_var_copy(struct hlsl_ctx *ctx, struct list *instrs, st struct hlsl_ir_load *load; /* This redundant load is expected to be deleted later by DCE. */ @@ -11771,7 +11985,7 @@ index ab59875738c..bbb5223b1ec 100644 struct hlsl_block *block, void *context) { struct hlsl_ir_node *instr, *next; -@@ -459,11 +588,11 @@ static bool transform_ir(struct hlsl_ctx *ctx, bool (*func)(struct hlsl_ctx *ctx +@@ -459,11 +561,11 @@ static bool transform_ir(struct hlsl_ctx *ctx, bool (*func)(struct hlsl_ctx *ctx { struct hlsl_ir_if *iff = hlsl_ir_if(instr); @@ -11786,7 +12000,52 @@ index ab59875738c..bbb5223b1ec 100644 progress |= func(ctx, instr, context); } -@@ -506,7 +635,7 @@ static bool find_recursive_calls(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst +@@ -471,6 +573,44 @@ static bool transform_ir(struct hlsl_ctx *ctx, bool (*func)(struct hlsl_ctx *ctx + return progress; + } + ++static bool transform_instr_derefs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) ++{ ++ bool res; ++ bool (*func)(struct hlsl_ctx *ctx, struct hlsl_deref *, struct hlsl_ir_node *) = context; ++ ++ switch(instr->type) ++ { ++ case HLSL_IR_LOAD: ++ res = func(ctx, &hlsl_ir_load(instr)->src, instr); ++ return res; ++ ++ case HLSL_IR_STORE: ++ res = func(ctx, &hlsl_ir_store(instr)->lhs, instr); ++ return res; ++ ++ case HLSL_IR_RESOURCE_LOAD: ++ res = func(ctx, &hlsl_ir_resource_load(instr)->resource, instr); ++ if (hlsl_ir_resource_load(instr)->sampler.var) ++ res |= func(ctx, &hlsl_ir_resource_load(instr)->sampler, instr); ++ return res; ++ ++ case HLSL_IR_RESOURCE_STORE: ++ res = func(ctx, &hlsl_ir_resource_store(instr)->resource, instr); ++ return res; ++ ++ default: ++ return false; ++ } ++ return false; ++} ++ ++static bool transform_derefs(struct hlsl_ctx *ctx, ++ bool (*func)(struct hlsl_ctx *ctx, struct hlsl_deref *, struct hlsl_ir_node *), ++ struct hlsl_block *block) ++{ ++ return hlsl_transform_ir(ctx, transform_instr_derefs, block, func); ++} ++ + struct recursive_call_ctx + { + const struct hlsl_ir_function_decl **backtrace; +@@ -506,7 +646,7 @@ static bool find_recursive_calls(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst return false; call_ctx->backtrace[call_ctx->count++] = decl; @@ -11795,7 +12054,7 @@ index ab59875738c..bbb5223b1ec 100644 --call_ctx->count; -@@ -516,21 +645,23 @@ static bool find_recursive_calls(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst +@@ -516,21 +656,23 @@ static bool find_recursive_calls(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst static void insert_early_return_break(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *func, struct hlsl_ir_node *cf_instr) { @@ -11826,7 +12085,7 @@ index ab59875738c..bbb5223b1ec 100644 } /* Remove HLSL_IR_JUMP_RETURN calls by altering subsequent control flow. */ -@@ -566,7 +697,7 @@ static bool lower_return(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *fun +@@ -566,7 +708,7 @@ static bool lower_return(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *fun * the CF instruction, shove it into an if block, and then lower that if * block. * @@ -11835,7 +12094,7 @@ index ab59875738c..bbb5223b1ec 100644 * and run this pass multiple times, but we already know the only block * that still needs to be addressed, so there's not much point.) * -@@ -591,8 +722,8 @@ static bool lower_return(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *fun +@@ -591,8 +733,8 @@ static bool lower_return(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *fun { struct hlsl_ir_if *iff = hlsl_ir_if(instr); @@ -11846,7 +12105,7 @@ index ab59875738c..bbb5223b1ec 100644 if (has_early_return) { -@@ -628,18 +759,17 @@ static bool lower_return(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *fun +@@ -628,18 +770,17 @@ static bool lower_return(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *fun else if (instr->type == HLSL_IR_JUMP) { struct hlsl_ir_jump *jump = hlsl_ir_jump(instr); @@ -11869,7 +12128,7 @@ index ab59875738c..bbb5223b1ec 100644 has_early_return = true; if (in_loop) -@@ -675,9 +805,9 @@ static bool lower_return(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *fun +@@ -675,9 +816,9 @@ static bool lower_return(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *fun else if (cf_instr) { struct list *tail = list_tail(&block->instrs); @@ -11881,7 +12140,7 @@ index ab59875738c..bbb5223b1ec 100644 /* If we're in a loop, we should have used "break" instead. */ assert(!in_loop); -@@ -685,21 +815,21 @@ static bool lower_return(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *fun +@@ -685,21 +826,21 @@ static bool lower_return(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *fun if (tail == &cf_instr->entry) return has_early_return; @@ -11913,7 +12172,7 @@ index ab59875738c..bbb5223b1ec 100644 } return has_early_return; -@@ -721,7 +851,6 @@ static bool lower_calls(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void * +@@ -721,7 +862,6 @@ static bool lower_calls(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void * hlsl_error(ctx, &call->node.loc, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, "Function \"%s\" is not defined.", decl->func->name); @@ -11921,7 +12180,7 @@ index ab59875738c..bbb5223b1ec 100644 if (!hlsl_clone_block(ctx, &block, &decl->body)) return false; list_move_before(&call->node.entry, &block.instrs); -@@ -731,6 +860,142 @@ static bool lower_calls(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void * +@@ -731,6 +871,142 @@ static bool lower_calls(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void * return true; } @@ -12064,7 +12323,7 @@ index ab59875738c..bbb5223b1ec 100644 /* Lower casts from vec1 to vecN to swizzles. */ static bool lower_broadcasts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) { -@@ -746,26 +1011,24 @@ static bool lower_broadcasts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, v +@@ -746,26 +1022,24 @@ static bool lower_broadcasts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, v src_type = cast->operands[0].node->data_type; dst_type = cast->node.data_type; @@ -12097,7 +12356,7 @@ index ab59875738c..bbb5223b1ec 100644 } hlsl_replace_node(&cast->node, replacement); -@@ -949,9 +1212,9 @@ static void copy_propagation_invalidate_variable_from_deref_recurse(struct hlsl_ +@@ -949,9 +1223,9 @@ static void copy_propagation_invalidate_variable_from_deref_recurse(struct hlsl_ path_node = deref->path[depth].node; subtype = hlsl_get_element_type_from_path_index(ctx, type, path_node); @@ -12109,7 +12368,7 @@ index ab59875738c..bbb5223b1ec 100644 for (i = 0; i < idx; ++i) comp_start += hlsl_type_component_count(type->e.record.fields[i].type); -@@ -966,7 +1229,7 @@ static void copy_propagation_invalidate_variable_from_deref_recurse(struct hlsl_ +@@ -966,7 +1240,7 @@ static void copy_propagation_invalidate_variable_from_deref_recurse(struct hlsl_ if (path_node->type == HLSL_IR_CONSTANT) { copy_propagation_invalidate_variable_from_deref_recurse(ctx, var_def, deref, subtype, @@ -12118,7 +12377,7 @@ index ab59875738c..bbb5223b1ec 100644 } else { -@@ -1041,14 +1304,14 @@ static bool copy_propagation_replace_with_single_instr(struct hlsl_ctx *ctx, +@@ -1041,14 +1315,14 @@ static bool copy_propagation_replace_with_single_instr(struct hlsl_ctx *ctx, var->name, start, start + count, debug_hlsl_swizzle(swizzle, instr_component_count), new_instr, debug_hlsl_swizzle(ret_swizzle, instr_component_count)); @@ -12137,16 +12396,19 @@ index ab59875738c..bbb5223b1ec 100644 } hlsl_replace_node(instr, new_instr); -@@ -1061,7 +1324,7 @@ static bool copy_propagation_replace_with_constant_vector(struct hlsl_ctx *ctx, +@@ -1061,9 +1335,9 @@ static bool copy_propagation_replace_with_constant_vector(struct hlsl_ctx *ctx, { const unsigned int instr_component_count = hlsl_type_component_count(instr->data_type); const struct hlsl_ir_var *var = deref->var; - union hlsl_constant_value values[4] = {0}; +- struct hlsl_ir_constant *cons; + struct hlsl_constant_value values = {0}; - struct hlsl_ir_constant *cons; unsigned int start, count, i; ++ struct hlsl_ir_node *cons; -@@ -1076,15 +1339,12 @@ static bool copy_propagation_replace_with_constant_vector(struct hlsl_ctx *ctx, + if (!hlsl_component_index_range_from_deref(ctx, deref, &start, &count)) + return false; +@@ -1076,21 +1350,17 @@ static bool copy_propagation_replace_with_constant_vector(struct hlsl_ctx *ctx, || value->node->type != HLSL_IR_CONSTANT) return false; @@ -12154,17 +12416,25 @@ index ab59875738c..bbb5223b1ec 100644 + values.u[i] = hlsl_ir_constant(value->node)->value.u[value->component]; } - if (!(cons = hlsl_new_constant(ctx, instr->data_type, &instr->loc))) +- if (!(cons = hlsl_new_constant(ctx, instr->data_type, &instr->loc))) ++ if (!(cons = hlsl_new_constant(ctx, instr->data_type, &values, &instr->loc))) return false; - cons->value[0] = values[0]; - cons->value[1] = values[1]; - cons->value[2] = values[2]; - cons->value[3] = values[3]; -+ cons->value = values; - list_add_before(&instr->entry, &cons->node.entry); +- list_add_before(&instr->entry, &cons->node.entry); ++ list_add_before(&instr->entry, &cons->entry); TRACE("Load from %s[%u-%u]%s turned into a constant %p.\n", -@@ -1099,7 +1359,7 @@ static bool copy_propagation_transform_load(struct hlsl_ctx *ctx, + var->name, start, start + count, debug_hlsl_swizzle(swizzle, instr_component_count), cons); + +- hlsl_replace_node(instr, &cons->node); ++ hlsl_replace_node(instr, cons); + return true; + } + +@@ -1099,7 +1369,7 @@ static bool copy_propagation_transform_load(struct hlsl_ctx *ctx, { struct hlsl_type *type = load->node.data_type; @@ -12173,7 +12443,7 @@ index ab59875738c..bbb5223b1ec 100644 { case HLSL_CLASS_SCALAR: case HLSL_CLASS_VECTOR: -@@ -1220,7 +1480,7 @@ static void copy_propagation_record_store(struct hlsl_ctx *ctx, struct hlsl_ir_s +@@ -1220,7 +1490,7 @@ static void copy_propagation_record_store(struct hlsl_ctx *ctx, struct hlsl_ir_s { unsigned int writemask = store->writemask; @@ -12182,7 +12452,7 @@ index ab59875738c..bbb5223b1ec 100644 writemask = VKD3DSP_WRITEMASK_0; copy_propagation_set_value(var_def, start, writemask, store->rhs.node); } -@@ -1270,8 +1530,8 @@ static void copy_propagation_invalidate_from_block(struct hlsl_ctx *ctx, struct +@@ -1270,8 +1540,8 @@ static void copy_propagation_invalidate_from_block(struct hlsl_ctx *ctx, struct { struct hlsl_ir_if *iff = hlsl_ir_if(instr); @@ -12193,7 +12463,7 @@ index ab59875738c..bbb5223b1ec 100644 break; } -@@ -1301,19 +1561,19 @@ static bool copy_propagation_process_if(struct hlsl_ctx *ctx, struct hlsl_ir_if +@@ -1301,19 +1571,19 @@ static bool copy_propagation_process_if(struct hlsl_ctx *ctx, struct hlsl_ir_if bool progress = false; copy_propagation_state_init(ctx, &inner_state, state); @@ -12217,7 +12487,7 @@ index ab59875738c..bbb5223b1ec 100644 return progress; } -@@ -1471,7 +1731,7 @@ static bool validate_static_object_references(struct hlsl_ctx *ctx, struct hlsl_ +@@ -1471,7 +1741,7 @@ static bool validate_static_object_references(struct hlsl_ctx *ctx, struct hlsl_ static bool is_vec1(const struct hlsl_type *type) { @@ -12226,7 +12496,7 @@ index ab59875738c..bbb5223b1ec 100644 } static bool fold_redundant_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) -@@ -1505,21 +1765,20 @@ static bool fold_redundant_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst +@@ -1505,21 +1775,20 @@ static bool fold_redundant_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst static bool split_copy(struct hlsl_ctx *ctx, struct hlsl_ir_store *store, const struct hlsl_ir_load *load, const unsigned int idx, struct hlsl_type *type) { @@ -12253,7 +12523,7 @@ index ab59875738c..bbb5223b1ec 100644 return true; } -@@ -1538,7 +1797,7 @@ static bool split_array_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, +@@ -1538,7 +1807,7 @@ static bool split_array_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, store = hlsl_ir_store(instr); rhs = store->rhs.node; type = rhs->data_type; @@ -12262,7 +12532,7 @@ index ab59875738c..bbb5223b1ec 100644 return false; element_type = type->e.array.type; -@@ -1575,7 +1834,7 @@ static bool split_struct_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr +@@ -1575,7 +1844,7 @@ static bool split_struct_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr store = hlsl_ir_store(instr); rhs = store->rhs.node; type = rhs->data_type; @@ -12271,7 +12541,7 @@ index ab59875738c..bbb5223b1ec 100644 return false; if (rhs->type != HLSL_IR_LOAD) -@@ -1614,7 +1873,7 @@ static bool split_matrix_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr +@@ -1614,7 +1883,7 @@ static bool split_matrix_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr store = hlsl_ir_store(instr); rhs = store->rhs.node; type = rhs->data_type; @@ -12280,7 +12550,7 @@ index ab59875738c..bbb5223b1ec 100644 return false; element_type = hlsl_get_vector_type(ctx, type->base_type, hlsl_type_minor_size(type)); -@@ -1649,22 +1908,21 @@ static bool lower_narrowing_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins +@@ -1649,22 +1918,21 @@ static bool lower_narrowing_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins src_type = cast->operands[0].node->data_type; dst_type = cast->node.data_type; @@ -12309,7 +12579,7 @@ index ab59875738c..bbb5223b1ec 100644 return true; } -@@ -1684,8 +1942,7 @@ static bool fold_swizzle_chains(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr +@@ -1684,8 +1952,7 @@ static bool fold_swizzle_chains(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr if (next_instr->type == HLSL_IR_SWIZZLE) { @@ -12319,7 +12589,7 @@ index ab59875738c..bbb5223b1ec 100644 unsigned int combined_swizzle; combined_swizzle = hlsl_combine_swizzles(hlsl_ir_swizzle(next_instr)->swizzle, -@@ -1695,9 +1952,8 @@ static bool fold_swizzle_chains(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr +@@ -1695,9 +1962,8 @@ static bool fold_swizzle_chains(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr if (!(new_swizzle = hlsl_new_swizzle(ctx, combined_swizzle, instr->data_type->dimx, next_instr, &instr->loc))) return false; @@ -12331,7 +12601,89 @@ index ab59875738c..bbb5223b1ec 100644 return true; } -@@ -1737,7 +1993,7 @@ static bool lower_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, voi +@@ -1725,6 +1991,81 @@ static bool remove_trivial_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *i + return true; + } + ++static bool lower_nonconstant_vector_derefs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) ++{ ++ struct hlsl_ir_node *idx; ++ struct hlsl_deref *deref; ++ struct hlsl_type *type; ++ unsigned int i; ++ ++ if (instr->type != HLSL_IR_LOAD) ++ return false; ++ ++ deref = &hlsl_ir_load(instr)->src; ++ assert(deref->var); ++ ++ if (deref->path_len == 0) ++ return false; ++ ++ type = deref->var->data_type; ++ for (i = 0; i < deref->path_len - 1; ++i) ++ type = hlsl_get_element_type_from_path_index(ctx, type, deref->path[i].node); ++ ++ idx = deref->path[deref->path_len - 1].node; ++ ++ if (type->class == HLSL_CLASS_VECTOR && idx->type != HLSL_IR_CONSTANT) ++ { ++ struct hlsl_ir_node *eq, *swizzle, *dot, *c, *operands[HLSL_MAX_OPERANDS] = {0}; ++ struct hlsl_constant_value value; ++ struct hlsl_ir_load *vector_load; ++ enum hlsl_ir_expr_op op; ++ ++ if (!(vector_load = hlsl_new_load_parent(ctx, deref, &instr->loc))) ++ return false; ++ list_add_before(&instr->entry, &vector_load->node.entry); ++ ++ if (!(swizzle = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(X, X, X, X), type->dimx, idx, &instr->loc))) ++ return false; ++ list_add_before(&instr->entry, &swizzle->entry); ++ ++ value.u[0].u = 0; ++ value.u[1].u = 1; ++ value.u[2].u = 2; ++ value.u[3].u = 3; ++ if (!(c = hlsl_new_constant(ctx, hlsl_get_vector_type(ctx, HLSL_TYPE_UINT, type->dimx), &value, &instr->loc))) ++ return false; ++ list_add_before(&instr->entry, &c->entry); ++ ++ operands[0] = swizzle; ++ operands[1] = c; ++ if (!(eq = hlsl_new_expr(ctx, HLSL_OP2_EQUAL, operands, ++ hlsl_get_vector_type(ctx, HLSL_TYPE_BOOL, type->dimx), &instr->loc))) ++ return false; ++ list_add_before(&instr->entry, &eq->entry); ++ ++ if (!(eq = hlsl_new_cast(ctx, eq, type, &instr->loc))) ++ return false; ++ list_add_before(&instr->entry, &eq->entry); ++ ++ op = HLSL_OP2_DOT; ++ if (type->dimx == 1) ++ op = type->base_type == HLSL_TYPE_BOOL ? HLSL_OP2_LOGIC_AND : HLSL_OP2_MUL; ++ ++ /* Note: We may be creating a DOT for bool vectors here, which we need to lower to ++ * LOGIC_OR + LOGIC_AND. */ ++ operands[0] = &vector_load->node; ++ operands[1] = eq; ++ if (!(dot = hlsl_new_expr(ctx, op, operands, instr->data_type, &instr->loc))) ++ return false; ++ list_add_before(&instr->entry, &dot->entry); ++ hlsl_replace_node(instr, dot); ++ ++ return true; ++ } ++ ++ return false; ++} ++ + /* Lower DIV to RCP + MUL. */ + static bool lower_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) + { +@@ -1737,7 +2078,7 @@ static bool lower_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, voi if (expr->op != HLSL_OP2_DIV) return false; @@ -12340,7 +12692,7 @@ index ab59875738c..bbb5223b1ec 100644 return false; list_add_before(&expr->node.entry, &rcp->entry); expr->op = HLSL_OP2_MUL; -@@ -1758,7 +2014,7 @@ static bool lower_sqrt(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *c +@@ -1758,7 +2099,7 @@ static bool lower_sqrt(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *c if (expr->op != HLSL_OP1_SQRT) return false; @@ -12349,7 +12701,7 @@ index ab59875738c..bbb5223b1ec 100644 return false; list_add_before(&expr->node.entry, &rsq->entry); expr->op = HLSL_OP1_RCP; -@@ -1770,9 +2026,7 @@ static bool lower_sqrt(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *c +@@ -1770,9 +2111,7 @@ static bool lower_sqrt(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *c /* Lower DP2 to MUL + ADD */ static bool lower_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) { @@ -12360,7 +12712,7 @@ index ab59875738c..bbb5223b1ec 100644 struct hlsl_ir_expr *expr; if (instr->type != HLSL_IR_EXPR) -@@ -1791,11 +2045,11 @@ static bool lower_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *co +@@ -1791,11 +2130,11 @@ static bool lower_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *co if (!(zero = hlsl_new_float_constant(ctx, 0.0f, &expr->node.loc))) return false; @@ -12374,7 +12726,7 @@ index ab59875738c..bbb5223b1ec 100644 if (!(replacement = hlsl_new_expr(ctx, HLSL_OP3_DP2ADD, operands, instr->data_type, &expr->node.loc))) return false; -@@ -1808,13 +2062,13 @@ static bool lower_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *co +@@ -1808,13 +2147,13 @@ static bool lower_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *co if (!(add_x = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(X, X, X, X), instr->data_type->dimx, mul, &expr->node.loc))) return false; @@ -12391,7 +12743,7 @@ index ab59875738c..bbb5223b1ec 100644 return false; } list_add_before(&instr->entry, &replacement->entry); -@@ -1836,7 +2090,7 @@ static bool lower_abs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *co +@@ -1836,7 +2175,7 @@ static bool lower_abs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *co if (expr->op != HLSL_OP1_ABS) return false; @@ -12400,39 +12752,54 @@ index ab59875738c..bbb5223b1ec 100644 return false; list_add_before(&instr->entry, &neg->entry); -@@ -1848,6 +2102,51 @@ static bool lower_abs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *co +@@ -1848,77 +2187,124 @@ static bool lower_abs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *co return true; } +-static bool lower_casts_to_bool(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +/* Lower ROUND using FRC, ROUND(x) -> ((x + 0.5) - FRC(x + 0.5)). */ +static bool lower_round(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) -+{ -+ struct hlsl_ir_node *arg, *neg, *sum, *frc, *replacement; + { +- struct hlsl_type *type = instr->data_type, *arg_type; +- struct hlsl_ir_constant *zero; ++ struct hlsl_ir_node *arg, *neg, *sum, *frc, *half, *replacement; + struct hlsl_type *type = instr->data_type; ++ struct hlsl_constant_value half_value; + unsigned int i, component_count; -+ struct hlsl_ir_constant *half; -+ struct hlsl_ir_expr *expr; + struct hlsl_ir_expr *expr; + + if (instr->type != HLSL_IR_EXPR) + return false; + -+ if (instr->type != HLSL_IR_EXPR) -+ return false; -+ -+ expr = hlsl_ir_expr(instr); + expr = hlsl_ir_expr(instr); +- if (expr->op != HLSL_OP1_CAST) +- return false; +- arg_type = expr->operands[0].node->data_type; +- if (type->type > HLSL_CLASS_VECTOR || arg_type->type > HLSL_CLASS_VECTOR) + arg = expr->operands[0].node; + if (expr->op != HLSL_OP1_ROUND) -+ return false; -+ -+ if (!(half = hlsl_new_constant(ctx, type, &expr->node.loc))) -+ return false; + return false; +- if (type->base_type != HLSL_TYPE_BOOL) + + component_count = hlsl_type_component_count(type); + for (i = 0; i < component_count; ++i) -+ half->value.u[i].f = 0.5f; -+ list_add_before(&instr->entry, &half->node.entry); -+ -+ if (!(sum = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, arg, &half->node))) -+ return false; ++ half_value.u[i].f = 0.5f; ++ if (!(half = hlsl_new_constant(ctx, type, &half_value, &expr->node.loc))) + return false; + +- /* Narrowing casts should have already been lowered. */ +- assert(type->dimx == arg_type->dimx); ++ list_add_before(&instr->entry, &half->entry); + +- zero = hlsl_new_constant(ctx, arg_type, &instr->loc); +- if (!zero) ++ if (!(sum = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, arg, half))) + return false; +- list_add_before(&instr->entry, &zero->node.entry); + list_add_before(&instr->entry, &sum->entry); -+ + +- expr->op = HLSL_OP2_NEQUAL; +- hlsl_src_from_node(&expr->operands[1], &zero->node); + if (!(frc = hlsl_new_unary_expr(ctx, HLSL_OP1_FRACT, sum, &instr->loc))) + return false; + list_add_before(&instr->entry, &frc->entry); @@ -12449,19 +12816,35 @@ index ab59875738c..bbb5223b1ec 100644 + return true; +} + - static bool lower_casts_to_bool(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) - { - struct hlsl_type *type = instr->data_type, *arg_type; -@@ -1860,7 +2159,7 @@ static bool lower_casts_to_bool(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr - if (expr->op != HLSL_OP1_CAST) - return false; - arg_type = expr->operands[0].node->data_type; -- if (type->type > HLSL_CLASS_VECTOR || arg_type->type > HLSL_CLASS_VECTOR) ++static bool lower_casts_to_bool(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) ++{ ++ struct hlsl_type *type = instr->data_type, *arg_type; ++ static const struct hlsl_constant_value zero_value; ++ struct hlsl_ir_node *zero; ++ struct hlsl_ir_expr *expr; ++ ++ if (instr->type != HLSL_IR_EXPR) ++ return false; ++ expr = hlsl_ir_expr(instr); ++ if (expr->op != HLSL_OP1_CAST) ++ return false; ++ arg_type = expr->operands[0].node->data_type; + if (type->class > HLSL_CLASS_VECTOR || arg_type->class > HLSL_CLASS_VECTOR) - return false; - if (type->base_type != HLSL_TYPE_BOOL) - return false; -@@ -1879,46 +2178,47 @@ static bool lower_casts_to_bool(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr ++ return false; ++ if (type->base_type != HLSL_TYPE_BOOL) ++ return false; ++ ++ /* Narrowing casts should have already been lowered. */ ++ assert(type->dimx == arg_type->dimx); ++ ++ zero = hlsl_new_constant(ctx, arg_type, &zero_value, &instr->loc); ++ if (!zero) ++ return false; ++ list_add_before(&instr->entry, &zero->entry); ++ ++ expr->op = HLSL_OP2_NEQUAL; ++ hlsl_src_from_node(&expr->operands[1], zero); + return true; } @@ -12496,12 +12879,12 @@ index ab59875738c..bbb5223b1ec 100644 return NULL; - list_add_tail(&iff->else_instrs.instrs, &store->node.entry); + hlsl_block_add_instr(&else_block, store); - -- if (!(load = hlsl_new_var_load(ctx, var, condition->loc))) ++ + if (!(iff = hlsl_new_if(ctx, condition, &then_block, &else_block, &condition->loc))) + return NULL; + list_add_tail(instrs, &iff->entry); -+ + +- if (!(load = hlsl_new_var_load(ctx, var, condition->loc))) + if (!(load = hlsl_new_var_load(ctx, var, &condition->loc))) return NULL; list_add_tail(instrs, &load->node.entry); @@ -12513,16 +12896,17 @@ index ab59875738c..bbb5223b1ec 100644 static bool lower_int_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) { - struct hlsl_ir_node *arg1, *arg2, *xor, *and, *abs1, *abs2, *div, *neg; -+ struct hlsl_ir_node *arg1, *arg2, *xor, *and, *abs1, *abs2, *div, *neg, *cast1, *cast2, *cast3, *cond; ++ struct hlsl_ir_node *arg1, *arg2, *xor, *and, *abs1, *abs2, *div, *neg, *cast1, *cast2, *cast3, *cond, *high_bit; struct hlsl_type *type = instr->data_type, *utype; - struct hlsl_ir_expr *cast1, *cast2, *cast3; - struct hlsl_ir_constant *high_bit; +- struct hlsl_ir_constant *high_bit; ++ struct hlsl_constant_value high_bit_value; struct hlsl_ir_expr *expr; - struct hlsl_ir_load *cond; unsigned int i; if (instr->type != HLSL_IR_EXPR) -@@ -1928,11 +2228,11 @@ static bool lower_int_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, +@@ -1928,69 +2314,67 @@ static bool lower_int_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, arg2 = expr->operands[1].node; if (expr->op != HLSL_OP2_DIV) return false; @@ -12536,15 +12920,20 @@ index ab59875738c..bbb5223b1ec 100644 if (!(xor = hlsl_new_binary_expr(ctx, HLSL_OP2_BIT_XOR, arg1, arg2))) return false; -@@ -1941,56 +2241,54 @@ static bool lower_int_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, - if (!(high_bit = hlsl_new_constant(ctx, type, &instr->loc))) - return false; + list_add_before(&instr->entry, &xor->entry); + +- if (!(high_bit = hlsl_new_constant(ctx, type, &instr->loc))) +- return false; for (i = 0; i < type->dimx; ++i) - high_bit->value[i].u = 0x80000000; -+ high_bit->value.u[i].u = 0x80000000; - list_add_before(&instr->entry, &high_bit->node.entry); +- list_add_before(&instr->entry, &high_bit->node.entry); ++ high_bit_value.u[i].u = 0x80000000; ++ if (!(high_bit = hlsl_new_constant(ctx, type, &high_bit_value, &instr->loc))) ++ return false; ++ list_add_before(&instr->entry, &high_bit->entry); - if (!(and = hlsl_new_binary_expr(ctx, HLSL_OP2_BIT_AND, xor, &high_bit->node))) +- if (!(and = hlsl_new_binary_expr(ctx, HLSL_OP2_BIT_AND, xor, &high_bit->node))) ++ if (!(and = hlsl_new_binary_expr(ctx, HLSL_OP2_BIT_AND, xor, high_bit))) return false; list_add_before(&instr->entry, &and->entry); @@ -12595,16 +12984,17 @@ index ab59875738c..bbb5223b1ec 100644 static bool lower_int_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) { - struct hlsl_ir_node *arg1, *arg2, *and, *abs1, *abs2, *div, *neg; -+ struct hlsl_ir_node *arg1, *arg2, *and, *abs1, *abs2, *div, *neg, *cast1, *cast2, *cast3, *cond; ++ struct hlsl_ir_node *arg1, *arg2, *and, *abs1, *abs2, *div, *neg, *cast1, *cast2, *cast3, *cond, *high_bit; struct hlsl_type *type = instr->data_type, *utype; - struct hlsl_ir_expr *cast1, *cast2, *cast3; - struct hlsl_ir_constant *high_bit; +- struct hlsl_ir_constant *high_bit; ++ struct hlsl_constant_value high_bit_value; struct hlsl_ir_expr *expr; - struct hlsl_ir_load *cond; unsigned int i; if (instr->type != HLSL_IR_EXPR) -@@ -2000,53 +2298,53 @@ static bool lower_int_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, +@@ -2000,53 +2384,53 @@ static bool lower_int_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, arg2 = expr->operands[1].node; if (expr->op != HLSL_OP2_MOD) return false; @@ -12616,14 +13006,18 @@ index ab59875738c..bbb5223b1ec 100644 - utype = hlsl_get_numeric_type(ctx, type->type, HLSL_TYPE_UINT, type->dimx, type->dimy); + utype = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_UINT, type->dimx, type->dimy); - if (!(high_bit = hlsl_new_constant(ctx, type, &instr->loc))) - return false; +- if (!(high_bit = hlsl_new_constant(ctx, type, &instr->loc))) +- return false; for (i = 0; i < type->dimx; ++i) - high_bit->value[i].u = 0x80000000; -+ high_bit->value.u[i].u = 0x80000000; - list_add_before(&instr->entry, &high_bit->node.entry); +- list_add_before(&instr->entry, &high_bit->node.entry); ++ high_bit_value.u[i].u = 0x80000000; ++ if (!(high_bit = hlsl_new_constant(ctx, type, &high_bit_value, &instr->loc))) ++ return false; ++ list_add_before(&instr->entry, &high_bit->entry); - if (!(and = hlsl_new_binary_expr(ctx, HLSL_OP2_BIT_AND, arg1, &high_bit->node))) +- if (!(and = hlsl_new_binary_expr(ctx, HLSL_OP2_BIT_AND, arg1, &high_bit->node))) ++ if (!(and = hlsl_new_binary_expr(ctx, HLSL_OP2_BIT_AND, arg1, high_bit))) return false; list_add_before(&instr->entry, &and->entry); @@ -12670,7 +13064,7 @@ index ab59875738c..bbb5223b1ec 100644 return true; } -@@ -2063,14 +2361,14 @@ static bool lower_int_abs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void +@@ -2063,14 +2447,14 @@ static bool lower_int_abs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void if (expr->op != HLSL_OP1_ABS) return false; @@ -12687,19 +13081,74 @@ index ab59875738c..bbb5223b1ec 100644 return false; list_add_before(&instr->entry, &neg->entry); -@@ -2082,10 +2380,9 @@ static bool lower_int_abs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void +@@ -2080,12 +2464,63 @@ static bool lower_int_abs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void + return true; + } ++static bool lower_int_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) ++{ ++ struct hlsl_ir_node *arg1, *arg2, *mult, *comps[4] = {0}, *res; ++ struct hlsl_type *type = instr->data_type; ++ struct hlsl_ir_expr *expr; ++ unsigned int i, dimx; ++ bool is_bool; ++ ++ if (instr->type != HLSL_IR_EXPR) ++ return false; ++ expr = hlsl_ir_expr(instr); ++ ++ if (expr->op != HLSL_OP2_DOT) ++ return false; ++ ++ if (type->base_type == HLSL_TYPE_INT || type->base_type == HLSL_TYPE_UINT ++ || type->base_type == HLSL_TYPE_BOOL) ++ { ++ arg1 = expr->operands[0].node; ++ arg2 = expr->operands[1].node; ++ assert(arg1->data_type->dimx == arg2->data_type->dimx); ++ dimx = arg1->data_type->dimx; ++ is_bool = type->base_type == HLSL_TYPE_BOOL; ++ ++ if (!(mult = hlsl_new_binary_expr(ctx, is_bool ? HLSL_OP2_LOGIC_AND : HLSL_OP2_MUL, arg1, arg2))) ++ return false; ++ list_add_before(&instr->entry, &mult->entry); ++ ++ for (i = 0; i < dimx; ++i) ++ { ++ unsigned int s = hlsl_swizzle_from_writemask(1 << i); ++ ++ if (!(comps[i] = hlsl_new_swizzle(ctx, s, 1, mult, &instr->loc))) ++ return false; ++ list_add_before(&instr->entry, &comps[i]->entry); ++ } ++ ++ res = comps[0]; ++ for (i = 1; i < dimx; ++i) ++ { ++ if (!(res = hlsl_new_binary_expr(ctx, is_bool ? HLSL_OP2_LOGIC_OR : HLSL_OP2_ADD, res, comps[i]))) ++ return false; ++ list_add_before(&instr->entry, &res->entry); ++ } ++ ++ hlsl_replace_node(instr, res); ++ return true; ++ } ++ ++ return false; ++} ++ static bool lower_float_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) { - struct hlsl_ir_node *arg1, *arg2, *mul1, *neg1, *ge, *neg2, *div, *mul2, *frc; -+ struct hlsl_ir_node *arg1, *arg2, *mul1, *neg1, *ge, *neg2, *div, *mul2, *frc, *cond; ++ struct hlsl_ir_node *arg1, *arg2, *mul1, *neg1, *ge, *neg2, *div, *mul2, *frc, *cond, *one; struct hlsl_type *type = instr->data_type, *btype; - struct hlsl_ir_constant *one; +- struct hlsl_ir_constant *one; - struct hlsl_ir_load *cond; ++ struct hlsl_constant_value one_value; struct hlsl_ir_expr *expr; unsigned int i; -@@ -2096,17 +2393,17 @@ static bool lower_float_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr +@@ -2096,17 +2531,17 @@ static bool lower_float_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr arg2 = expr->operands[1].node; if (expr->op != HLSL_OP2_MOD) return false; @@ -12720,7 +13169,7 @@ index ab59875738c..bbb5223b1ec 100644 return false; list_add_before(&instr->entry, &neg1->entry); -@@ -2115,7 +2412,7 @@ static bool lower_float_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr +@@ -2115,20 +2550,20 @@ static bool lower_float_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr ge->data_type = btype; list_add_before(&instr->entry, &ge->entry); @@ -12729,20 +13178,25 @@ index ab59875738c..bbb5223b1ec 100644 return false; list_add_before(&instr->entry, &neg2->entry); -@@ -2125,10 +2422,10 @@ static bool lower_float_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr - if (!(one = hlsl_new_constant(ctx, type, &instr->loc))) + if (!(cond = hlsl_add_conditional(ctx, &instr->entry, ge, arg2, neg2))) return false; + +- if (!(one = hlsl_new_constant(ctx, type, &instr->loc))) +- return false; for (i = 0; i < type->dimx; ++i) - one->value[i].f = 1.0f; -+ one->value.u[i].f = 1.0f; - list_add_before(&instr->entry, &one->node.entry); +- list_add_before(&instr->entry, &one->node.entry); ++ one_value.u[i].f = 1.0f; ++ if (!(one = hlsl_new_constant(ctx, type, &one_value, &instr->loc))) ++ return false; ++ list_add_before(&instr->entry, &one->entry); - if (!(div = hlsl_new_binary_expr(ctx, HLSL_OP2_DIV, &one->node, &cond->node))) -+ if (!(div = hlsl_new_binary_expr(ctx, HLSL_OP2_DIV, &one->node, cond))) ++ if (!(div = hlsl_new_binary_expr(ctx, HLSL_OP2_DIV, one, cond))) return false; list_add_before(&instr->entry, &div->entry); -@@ -2136,7 +2433,7 @@ static bool lower_float_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr +@@ -2136,7 +2571,7 @@ static bool lower_float_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr return false; list_add_before(&instr->entry, &mul2->entry); @@ -12751,7 +13205,7 @@ index ab59875738c..bbb5223b1ec 100644 return false; list_add_before(&instr->entry, &frc->entry); -@@ -2144,7 +2441,7 @@ static bool lower_float_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr +@@ -2144,7 +2579,7 @@ static bool lower_float_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr hlsl_src_remove(&expr->operands[0]); hlsl_src_remove(&expr->operands[1]); hlsl_src_from_node(&expr->operands[0], frc); @@ -12760,7 +13214,7 @@ index ab59875738c..bbb5223b1ec 100644 return true; } -@@ -2155,6 +2452,7 @@ static bool dce(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +@@ -2155,6 +2590,7 @@ static bool dce(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) { case HLSL_IR_CONSTANT: case HLSL_IR_EXPR: @@ -12768,7 +13222,7 @@ index ab59875738c..bbb5223b1ec 100644 case HLSL_IR_LOAD: case HLSL_IR_RESOURCE_LOAD: case HLSL_IR_SWIZZLE: -@@ -2204,8 +2502,8 @@ static unsigned int index_instructions(struct hlsl_block *block, unsigned int in +@@ -2204,8 +2640,8 @@ static unsigned int index_instructions(struct hlsl_block *block, unsigned int in if (instr->type == HLSL_IR_IF) { struct hlsl_ir_if *iff = hlsl_ir_if(instr); @@ -12779,7 +13233,7 @@ index ab59875738c..bbb5223b1ec 100644 } else if (instr->type == HLSL_IR_LOOP) { -@@ -2262,9 +2560,9 @@ static void allocate_register_reservations(struct hlsl_ctx *ctx) +@@ -2262,9 +2698,9 @@ static void allocate_register_reservations(struct hlsl_ctx *ctx) continue; regset = hlsl_type_get_regset(var->data_type); @@ -12791,7 +13245,7 @@ index ab59875738c..bbb5223b1ec 100644 { struct vkd3d_string_buffer *type_string; -@@ -2277,8 +2575,11 @@ static void allocate_register_reservations(struct hlsl_ctx *ctx) +@@ -2277,8 +2713,11 @@ static void allocate_register_reservations(struct hlsl_ctx *ctx) else { var->regs[regset].allocated = true; @@ -12805,7 +13259,7 @@ index ab59875738c..bbb5223b1ec 100644 } } } -@@ -2286,9 +2587,9 @@ static void allocate_register_reservations(struct hlsl_ctx *ctx) +@@ -2286,9 +2725,9 @@ static void allocate_register_reservations(struct hlsl_ctx *ctx) /* Compute the earliest and latest liveness for each variable. In the case that * a variable is accessed inside of a loop, we promote its liveness to extend @@ -12818,7 +13272,7 @@ index ab59875738c..bbb5223b1ec 100644 static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop_first, unsigned int loop_last) { struct hlsl_ir_node *instr; -@@ -2296,7 +2597,7 @@ static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop +@@ -2296,7 +2735,7 @@ static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop LIST_FOR_EACH_ENTRY(instr, &block->instrs, struct hlsl_ir_node, entry) { @@ -12827,7 +13281,7 @@ index ab59875738c..bbb5223b1ec 100644 switch (instr->type) { -@@ -2311,9 +2612,9 @@ static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop +@@ -2311,9 +2750,9 @@ static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop var = store->lhs.var; if (!var->first_write) var->first_write = loop_first ? min(instr->index, loop_first) : instr->index; @@ -12839,7 +13293,7 @@ index ab59875738c..bbb5223b1ec 100644 break; } case HLSL_IR_EXPR: -@@ -2322,16 +2623,16 @@ static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop +@@ -2322,16 +2761,16 @@ static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop unsigned int i; for (i = 0; i < ARRAY_SIZE(expr->operands) && expr->operands[i].node; ++i) @@ -12860,7 +13314,7 @@ index ab59875738c..bbb5223b1ec 100644 break; } case HLSL_IR_LOAD: -@@ -2339,9 +2640,9 @@ static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop +@@ -2339,9 +2778,9 @@ static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop struct hlsl_ir_load *load = hlsl_ir_load(instr); var = load->src.var; @@ -12872,7 +13326,7 @@ index ab59875738c..bbb5223b1ec 100644 break; } case HLSL_IR_LOOP: -@@ -2357,22 +2658,28 @@ static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop +@@ -2357,22 +2796,30 @@ static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop struct hlsl_ir_resource_load *load = hlsl_ir_resource_load(instr); var = load->resource.var; @@ -12905,10 +13359,12 @@ index ab59875738c..bbb5223b1ec 100644 + load->ddy.node->last_read = last_read; + if (load->sample_index.node) + load->sample_index.node->last_read = last_read; ++ if (load->cmp.node) ++ load->cmp.node->last_read = last_read; break; } case HLSL_IR_RESOURCE_STORE: -@@ -2380,18 +2687,26 @@ static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop +@@ -2380,18 +2827,26 @@ static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop struct hlsl_ir_resource_store *store = hlsl_ir_resource_store(instr); var = store->resource.var; @@ -12940,7 +13396,7 @@ index ab59875738c..bbb5223b1ec 100644 break; } case HLSL_IR_CONSTANT: -@@ -2426,127 +2741,142 @@ static void compute_liveness(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl +@@ -2426,127 +2881,142 @@ static void compute_liveness(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl compute_liveness_recurse(&entry_func->body, 0, 0); } @@ -13145,7 +13601,7 @@ index ab59875738c..bbb5223b1ec 100644 } static const char *debug_register(char class, struct hlsl_reg reg, const struct hlsl_type *type) -@@ -2565,14 +2895,99 @@ static const char *debug_register(char class, struct hlsl_reg reg, const struct +@@ -2565,14 +3035,99 @@ static const char *debug_register(char class, struct hlsl_reg reg, const struct return vkd3d_dbg_sprintf("%c%u%s", class, reg.id, debug_hlsl_writemask(reg.writemask)); } @@ -13247,7 +13703,7 @@ index ab59875738c..bbb5223b1ec 100644 var->first_write, var->last_read, var->data_type); TRACE("Allocated %s to %s (liveness %u-%u).\n", var->name, debug_register('r', -@@ -2580,7 +2995,8 @@ static void allocate_variable_temp_register(struct hlsl_ctx *ctx, struct hlsl_ir +@@ -2580,15 +3135,20 @@ static void allocate_variable_temp_register(struct hlsl_ctx *ctx, struct hlsl_ir } } @@ -13257,8 +13713,12 @@ index ab59875738c..bbb5223b1ec 100644 { struct hlsl_ir_node *instr; -@@ -2588,7 +3004,7 @@ static void allocate_temp_registers_recurse(struct hlsl_ctx *ctx, struct hlsl_bl + LIST_FOR_EACH_ENTRY(instr, &block->instrs, struct hlsl_ir_node, entry) { ++ /* In SM4 all constants are inlined. */ ++ if (ctx->profile->major_version >= 4 && instr->type == HLSL_IR_CONSTANT) ++ continue; ++ if (!instr->reg.allocated && instr->last_read) { - instr->reg = allocate_numeric_registers_for_type(ctx, liveness, instr->index, instr->last_read, @@ -13266,7 +13726,7 @@ index ab59875738c..bbb5223b1ec 100644 instr->data_type); TRACE("Allocated anonymous expression @%u to %s (liveness %u-%u).\n", instr->index, debug_register('r', instr->reg, instr->data_type), instr->index, instr->last_read); -@@ -2599,8 +3015,8 @@ static void allocate_temp_registers_recurse(struct hlsl_ctx *ctx, struct hlsl_bl +@@ -2599,8 +3159,8 @@ static void allocate_temp_registers_recurse(struct hlsl_ctx *ctx, struct hlsl_bl case HLSL_IR_IF: { struct hlsl_ir_if *iff = hlsl_ir_if(instr); @@ -13277,7 +13737,7 @@ index ab59875738c..bbb5223b1ec 100644 break; } -@@ -2609,21 +3025,21 @@ static void allocate_temp_registers_recurse(struct hlsl_ctx *ctx, struct hlsl_bl +@@ -2609,21 +3169,21 @@ static void allocate_temp_registers_recurse(struct hlsl_ctx *ctx, struct hlsl_bl struct hlsl_ir_load *load = hlsl_ir_load(instr); /* We need to at least allocate a variable for undefs. * FIXME: We should probably find a way to remove them instead. */ @@ -13302,7 +13762,7 @@ index ab59875738c..bbb5223b1ec 100644 break; } -@@ -2633,7 +3049,8 @@ static void allocate_temp_registers_recurse(struct hlsl_ctx *ctx, struct hlsl_bl +@@ -2633,7 +3193,8 @@ static void allocate_temp_registers_recurse(struct hlsl_ctx *ctx, struct hlsl_bl } } @@ -13312,7 +13772,7 @@ index ab59875738c..bbb5223b1ec 100644 { struct hlsl_constant_defs *defs = &ctx->constant_defs; struct hlsl_ir_node *instr; -@@ -2649,7 +3066,7 @@ static void allocate_const_registers_recurse(struct hlsl_ctx *ctx, struct hlsl_b +@@ -2649,7 +3210,7 @@ static void allocate_const_registers_recurse(struct hlsl_ctx *ctx, struct hlsl_b unsigned int x, y, i, writemask, end_reg; unsigned int reg_size = type->reg_size[HLSL_REGSET_NUMERIC]; @@ -13321,7 +13781,7 @@ index ab59875738c..bbb5223b1ec 100644 TRACE("Allocated constant @%u to %s.\n", instr->index, debug_register('c', constant->reg, type)); if (!hlsl_array_reserve(ctx, (void **)&defs->values, &defs->size, -@@ -2662,7 +3079,7 @@ static void allocate_const_registers_recurse(struct hlsl_ctx *ctx, struct hlsl_b +@@ -2662,7 +3223,7 @@ static void allocate_const_registers_recurse(struct hlsl_ctx *ctx, struct hlsl_b defs->count = end_reg; } @@ -13330,7 +13790,7 @@ index ab59875738c..bbb5223b1ec 100644 if (!(writemask = constant->reg.writemask)) writemask = (1u << type->dimx) - 1; -@@ -2671,12 +3088,12 @@ static void allocate_const_registers_recurse(struct hlsl_ctx *ctx, struct hlsl_b +@@ -2671,12 +3232,12 @@ static void allocate_const_registers_recurse(struct hlsl_ctx *ctx, struct hlsl_b { for (x = 0, i = 0; x < 4; ++x) { @@ -13345,7 +13805,7 @@ index ab59875738c..bbb5223b1ec 100644 switch (type->base_type) { -@@ -2714,15 +3131,15 @@ static void allocate_const_registers_recurse(struct hlsl_ctx *ctx, struct hlsl_b +@@ -2714,15 +3275,15 @@ static void allocate_const_registers_recurse(struct hlsl_ctx *ctx, struct hlsl_b case HLSL_IR_IF: { struct hlsl_ir_if *iff = hlsl_ir_if(instr); @@ -13364,7 +13824,7 @@ index ab59875738c..bbb5223b1ec 100644 break; } -@@ -2734,10 +3151,10 @@ static void allocate_const_registers_recurse(struct hlsl_ctx *ctx, struct hlsl_b +@@ -2734,10 +3295,10 @@ static void allocate_const_registers_recurse(struct hlsl_ctx *ctx, struct hlsl_b static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func) { @@ -13377,7 +13837,7 @@ index ab59875738c..bbb5223b1ec 100644 LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) { -@@ -2748,12 +3165,14 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_ir_functi +@@ -2748,12 +3309,14 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_ir_functi if (reg_size == 0) continue; @@ -13393,7 +13853,7 @@ index ab59875738c..bbb5223b1ec 100644 } /* Simple greedy temporary register allocation pass that just assigns a unique -@@ -2762,15 +3181,33 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_ir_functi +@@ -2762,15 +3325,33 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_ir_functi * does not handle constants. */ static void allocate_temp_registers(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func) { @@ -13432,7 +13892,7 @@ index ab59875738c..bbb5223b1ec 100644 { [VKD3D_SHADER_TYPE_PIXEL] = "Pixel", [VKD3D_SHADER_TYPE_VERTEX] = "Vertex", -@@ -2791,7 +3228,12 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var +@@ -2791,7 +3372,12 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var D3DDECLUSAGE usage; uint32_t usage_idx; @@ -13446,7 +13906,7 @@ index ab59875738c..bbb5223b1ec 100644 { hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SEMANTIC, "Invalid semantic '%s'.", var->semantic.name); -@@ -2800,8 +3242,6 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var +@@ -2800,8 +3386,6 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var if ((!output && !var->last_read) || (output && !var->first_write)) return; @@ -13455,7 +13915,7 @@ index ab59875738c..bbb5223b1ec 100644 } else { -@@ -2827,6 +3267,7 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var +@@ -2827,6 +3411,7 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var { var->regs[HLSL_REGSET_NUMERIC].allocated = true; var->regs[HLSL_REGSET_NUMERIC].id = (*counter)++; @@ -13463,7 +13923,7 @@ index ab59875738c..bbb5223b1ec 100644 var->regs[HLSL_REGSET_NUMERIC].writemask = (1 << var->data_type->dimx) - 1; TRACE("Allocated %s to %s.\n", var->name, debug_register(output ? 'o' : 'v', var->regs[HLSL_REGSET_NUMERIC], var->data_type)); -@@ -2853,23 +3294,117 @@ static const struct hlsl_buffer *get_reserved_buffer(struct hlsl_ctx *ctx, uint3 +@@ -2853,23 +3438,117 @@ static const struct hlsl_buffer *get_reserved_buffer(struct hlsl_ctx *ctx, uint3 LIST_FOR_EACH_ENTRY(buffer, &ctx->buffers, const struct hlsl_buffer, entry) { @@ -13587,7 +14047,7 @@ index ab59875738c..bbb5223b1ec 100644 } static void allocate_buffers(struct hlsl_ctx *ctx) -@@ -2880,15 +3415,17 @@ static void allocate_buffers(struct hlsl_ctx *ctx) +@@ -2880,15 +3559,17 @@ static void allocate_buffers(struct hlsl_ctx *ctx) LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) { @@ -13607,7 +14067,7 @@ index ab59875738c..bbb5223b1ec 100644 LIST_FOR_EACH_ENTRY(buffer, &ctx->buffers, struct hlsl_buffer, entry) { if (!buffer->used_size) -@@ -2896,28 +3433,30 @@ static void allocate_buffers(struct hlsl_ctx *ctx) +@@ -2896,28 +3577,30 @@ static void allocate_buffers(struct hlsl_ctx *ctx) if (buffer->type == HLSL_BUFFER_CONSTANT) { @@ -13644,7 +14104,7 @@ index ab59875738c..bbb5223b1ec 100644 buffer->reg.allocated = true; TRACE("Allocated %s to cb%u.\n", buffer->name, index); ++index; -@@ -2939,13 +3478,17 @@ static const struct hlsl_ir_var *get_allocated_object(struct hlsl_ctx *ctx, enum +@@ -2939,13 +3622,17 @@ static const struct hlsl_ir_var *get_allocated_object(struct hlsl_ctx *ctx, enum uint32_t index) { const struct hlsl_ir_var *var; @@ -13663,7 +14123,7 @@ index ab59875738c..bbb5223b1ec 100644 return var; } return NULL; -@@ -2956,7 +3499,6 @@ static void allocate_objects(struct hlsl_ctx *ctx, enum hlsl_regset regset) +@@ -2956,7 +3643,6 @@ static void allocate_objects(struct hlsl_ctx *ctx, enum hlsl_regset regset) char regset_name = get_regset_name(regset); struct hlsl_ir_var *var; uint32_t min_index = 0; @@ -13671,7 +14131,7 @@ index ab59875738c..bbb5223b1ec 100644 if (regset == HLSL_REGSET_UAVS) { -@@ -2968,19 +3510,17 @@ static void allocate_objects(struct hlsl_ctx *ctx, enum hlsl_regset regset) +@@ -2968,19 +3654,17 @@ static void allocate_objects(struct hlsl_ctx *ctx, enum hlsl_regset regset) } } @@ -13696,7 +14156,7 @@ index ab59875738c..bbb5223b1ec 100644 if (var->regs[regset].id < min_index) { -@@ -2988,28 +3528,44 @@ static void allocate_objects(struct hlsl_ctx *ctx, enum hlsl_regset regset) +@@ -2988,28 +3672,44 @@ static void allocate_objects(struct hlsl_ctx *ctx, enum hlsl_regset regset) hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_OVERLAPPING_RESERVATIONS, "UAV index (%u) must be higher than the maximum render target index (%u).", var->regs[regset].id, min_index - 1); @@ -13753,7 +14213,7 @@ index ab59875738c..bbb5223b1ec 100644 ++index; } } -@@ -3034,12 +3590,12 @@ bool hlsl_component_index_range_from_deref(struct hlsl_ctx *ctx, const struct hl +@@ -3034,12 +3734,12 @@ bool hlsl_component_index_range_from_deref(struct hlsl_ctx *ctx, const struct hl return false; /* We should always have generated a cast to UINT. */ @@ -13769,7 +14229,7 @@ index ab59875738c..bbb5223b1ec 100644 { case HLSL_CLASS_VECTOR: if (idx >= type->dimx) -@@ -3090,6 +3646,55 @@ bool hlsl_component_index_range_from_deref(struct hlsl_ctx *ctx, const struct hl +@@ -3090,6 +3790,55 @@ bool hlsl_component_index_range_from_deref(struct hlsl_ctx *ctx, const struct hl return true; } @@ -13825,7 +14285,7 @@ index ab59875738c..bbb5223b1ec 100644 bool hlsl_offset_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref, unsigned int *offset) { struct hlsl_ir_node *offset_node = deref->offset.node; -@@ -3102,13 +3707,13 @@ bool hlsl_offset_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref +@@ -3102,13 +3851,13 @@ bool hlsl_offset_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref } /* We should always have generated a cast to UINT. */ @@ -13841,7 +14301,7 @@ index ab59875738c..bbb5223b1ec 100644 size = deref->var->data_type->reg_size[deref->offset_regset]; if (*offset >= size) -@@ -3170,7 +3775,7 @@ static void parse_numthreads_attribute(struct hlsl_ctx *ctx, const struct hlsl_a +@@ -3170,7 +3919,7 @@ static void parse_numthreads_attribute(struct hlsl_ctx *ctx, const struct hlsl_a const struct hlsl_type *type = instr->data_type; const struct hlsl_ir_constant *constant; @@ -13850,7 +14310,7 @@ index ab59875738c..bbb5223b1ec 100644 || (type->base_type != HLSL_TYPE_INT && type->base_type != HLSL_TYPE_UINT)) { struct vkd3d_string_buffer *string; -@@ -3190,13 +3795,32 @@ static void parse_numthreads_attribute(struct hlsl_ctx *ctx, const struct hlsl_a +@@ -3190,15 +3939,34 @@ static void parse_numthreads_attribute(struct hlsl_ctx *ctx, const struct hlsl_a } constant = hlsl_ir_constant(instr); @@ -13863,9 +14323,9 @@ index ab59875738c..bbb5223b1ec 100644 - ctx->thread_count[i] = constant->value[0].u; + ctx->thread_count[i] = constant->value.u[0].u; -+ } -+} -+ + } + } + +static bool type_has_object_components(struct hlsl_type *type) +{ + if (type->class == HLSL_CLASS_OBJECT) @@ -13881,12 +14341,14 @@ index ab59875738c..bbb5223b1ec 100644 + if (type_has_object_components(type->e.record.fields[i].type)) + return true; + } - } ++ } + return false; - } - ++} ++ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, -@@ -3212,7 +3836,7 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry + enum vkd3d_shader_target_type target_type, struct vkd3d_shader_code *out) + { +@@ -3212,7 +3980,7 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry list_move_head(&body->instrs, &ctx->static_initializers); memset(&recursive_call_ctx, 0, sizeof(recursive_call_ctx)); @@ -13895,7 +14357,7 @@ index ab59875738c..bbb5223b1ec 100644 vkd3d_free(recursive_call_ctx.backtrace); /* Avoid going into an infinite loop when processing call instructions. -@@ -3222,7 +3846,9 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry +@@ -3222,7 +3990,9 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry lower_return(ctx, entry_func, body, false); @@ -13906,7 +14368,7 @@ index ab59875738c..bbb5223b1ec 100644 LIST_FOR_EACH_ENTRY(var, &ctx->globals->vars, struct hlsl_ir_var, scope_entry) { -@@ -3234,15 +3860,22 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry +@@ -3234,15 +4004,22 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry { var = entry_func->parameters.vars[i]; @@ -13931,7 +14393,7 @@ index ab59875738c..bbb5223b1ec 100644 if (var->storage_modifiers & HLSL_STORAGE_IN) prepend_input_var_copy(ctx, &body->instrs, var); -@@ -3252,7 +3885,7 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry +@@ -3252,7 +4029,7 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry } if (entry_func->return_var) { @@ -13940,7 +14402,7 @@ index ab59875738c..bbb5223b1ec 100644 hlsl_error(ctx, &entry_func->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_SEMANTIC, "Entry point \"%s\" is missing a return value semantic.", entry_func->func->name); -@@ -3274,53 +3907,55 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry +@@ -3274,53 +4051,61 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry hlsl_error(ctx, &entry_func->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_ATTRIBUTE, "Entry point \"%s\" is missing a [numthreads] attribute.", entry_func->func->name); @@ -13968,10 +14430,12 @@ index ab59875738c..bbb5223b1ec 100644 + + hlsl_transform_ir(ctx, lower_narrowing_casts, body, NULL); + hlsl_transform_ir(ctx, lower_casts_to_bool, body, NULL); ++ hlsl_transform_ir(ctx, lower_int_dot, body, NULL); + hlsl_transform_ir(ctx, lower_int_division, body, NULL); + hlsl_transform_ir(ctx, lower_int_modulus, body, NULL); + hlsl_transform_ir(ctx, lower_int_abs, body, NULL); + hlsl_transform_ir(ctx, lower_float_modulus, body, NULL); ++ hlsl_transform_ir(ctx, fold_redundant_casts, body, NULL); do { - progress = transform_ir(ctx, hlsl_fold_constant_exprs, body, NULL); @@ -13986,6 +14450,10 @@ index ab59875738c..bbb5223b1ec 100644 } while (progress); ++ hlsl_transform_ir(ctx, lower_nonconstant_vector_derefs, body, NULL); ++ hlsl_transform_ir(ctx, lower_casts_to_bool, body, NULL); ++ hlsl_transform_ir(ctx, lower_int_dot, body, NULL); ++ if (profile->major_version < 4) { - transform_ir(ctx, lower_division, body, NULL); @@ -14010,7 +14478,7 @@ index ab59875738c..bbb5223b1ec 100644 /* TODO: move forward, remove when no longer needed */ - transform_ir(ctx, transform_deref_paths_into_offsets, body, NULL); - while (transform_ir(ctx, hlsl_fold_constant_exprs, body, NULL)); -+ hlsl_transform_ir(ctx, transform_deref_paths_into_offsets, body, NULL); ++ transform_derefs(ctx, replace_deref_path_with_offset, body); + while (hlsl_transform_ir(ctx, hlsl_fold_constant_exprs, body, NULL)); do @@ -14020,7 +14488,7 @@ index ab59875738c..bbb5223b1ec 100644 compute_liveness(ctx, entry_func); -@@ -3328,6 +3963,9 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry +@@ -3328,6 +4113,9 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry rb_for_each_entry(&ctx->functions, dump_function, ctx); allocate_register_reservations(ctx); @@ -14031,7 +14499,7 @@ index ab59875738c..bbb5223b1ec 100644 if (profile->major_version < 4) { diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c -index 3210bbd5712..9fa2acd5d5e 100644 +index 3210bbd5712..301113c8477 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c @@ -22,7 +22,49 @@ @@ -14318,7 +14786,7 @@ index 3210bbd5712..9fa2acd5d5e 100644 assert(src1->node.data_type->base_type == src2->node.data_type->base_type); for (k = 0; k < 4; ++k) -@@ -229,192 +272,192 @@ static bool fold_nequal(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, +@@ -229,270 +272,270 @@ static bool fold_nequal(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, { case HLSL_TYPE_FLOAT: case HLSL_TYPE_HALF: @@ -14565,34 +15033,114 @@ index 3210bbd5712..9fa2acd5d5e 100644 return false; } } -@@ -436,7 +479,7 @@ static bool fold_bit_xor(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, + return true; + } + +-static bool fold_bit_xor(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, +- struct hlsl_ir_constant *src1, struct hlsl_ir_constant *src2) ++static bool fold_bit_xor(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) + { +- enum hlsl_base_type type = dst->node.data_type->base_type; ++ enum hlsl_base_type type = dst_type->base_type; + unsigned int k; + + assert(type == src1->node.data_type->base_type); + assert(type == src2->node.data_type->base_type); + +- for (k = 0; k < dst->node.data_type->dimx; ++k) ++ for (k = 0; k < dst_type->dimx; ++k) + { + switch (type) { case HLSL_TYPE_INT: case HLSL_TYPE_UINT: - dst->value[k].u = src1->value[k].u ^ src2->value[k].u; -+ dst->value.u[k].u = src1->value.u[k].u ^ src2->value.u[k].u; ++ dst->u[k].u = src1->value.u[k].u ^ src2->value.u[k].u; break; default: -@@ -462,7 +505,7 @@ static bool fold_bit_and(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, +- FIXME("Fold bit xor for type %s.\n", debug_hlsl_type(ctx, dst->node.data_type)); ++ FIXME("Fold bit xor for type %s.\n", debug_hlsl_type(ctx, dst_type)); + return false; + } + } + return true; + } + +-static bool fold_bit_and(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, +- struct hlsl_ir_constant *src1, struct hlsl_ir_constant *src2) ++static bool fold_bit_and(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) + { +- enum hlsl_base_type type = dst->node.data_type->base_type; ++ enum hlsl_base_type type = dst_type->base_type; + unsigned int k; + + assert(type == src1->node.data_type->base_type); + assert(type == src2->node.data_type->base_type); + +- for (k = 0; k < dst->node.data_type->dimx; ++k) ++ for (k = 0; k < dst_type->dimx; ++k) + { + switch (type) { case HLSL_TYPE_INT: case HLSL_TYPE_UINT: - dst->value[k].u = src1->value[k].u & src2->value[k].u; -+ dst->value.u[k].u = src1->value.u[k].u & src2->value.u[k].u; ++ dst->u[k].u = src1->value.u[k].u & src2->value.u[k].u; break; default: -@@ -488,7 +531,7 @@ static bool fold_bit_or(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, +- FIXME("Fold bit and for type %s.\n", debug_hlsl_type(ctx, dst->node.data_type)); ++ FIXME("Fold bit and for type %s.\n", debug_hlsl_type(ctx, dst_type)); + return false; + } + } + return true; + } + +-static bool fold_bit_or(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, +- struct hlsl_ir_constant *src1, struct hlsl_ir_constant *src2) ++static bool fold_bit_or(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) + { +- enum hlsl_base_type type = dst->node.data_type->base_type; ++ enum hlsl_base_type type = dst_type->base_type; + unsigned int k; + + assert(type == src1->node.data_type->base_type); + assert(type == src2->node.data_type->base_type); + +- for (k = 0; k < dst->node.data_type->dimx; ++k) ++ for (k = 0; k < dst_type->dimx; ++k) + { + switch (type) { case HLSL_TYPE_INT: case HLSL_TYPE_UINT: - dst->value[k].u = src1->value[k].u | src2->value[k].u; -+ dst->value.u[k].u = src1->value.u[k].u | src2->value.u[k].u; ++ dst->u[k].u = src1->value.u[k].u | src2->value.u[k].u; break; default: -@@ -512,7 +555,7 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, +- FIXME("Fold bit or for type %s.\n", debug_hlsl_type(ctx, dst->node.data_type)); ++ FIXME("Fold bit or for type %s.\n", debug_hlsl_type(ctx, dst_type)); + return false; + } + } +@@ -501,7 +544,9 @@ static bool fold_bit_or(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, + + bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) + { +- struct hlsl_ir_constant *arg1, *arg2 = NULL, *res; ++ struct hlsl_ir_constant *arg1, *arg2 = NULL; ++ struct hlsl_constant_value res = {0}; ++ struct hlsl_ir_node *res_node; + struct hlsl_ir_expr *expr; + unsigned int i; + bool success; +@@ -512,7 +557,7 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, if (!expr->operands[0].node) return false; @@ -14601,7 +15149,7 @@ index 3210bbd5712..9fa2acd5d5e 100644 return false; for (i = 0; i < ARRAY_SIZE(expr->operands); ++i) -@@ -521,7 +564,7 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, +@@ -521,64 +566,65 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, { if (expr->operands[i].node->type != HLSL_IR_CONSTANT) return false; @@ -14610,69 +15158,130 @@ index 3210bbd5712..9fa2acd5d5e 100644 } } arg1 = hlsl_ir_constant(expr->operands[0].node); -@@ -533,40 +576,44 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, + if (expr->operands[1].node) + arg2 = hlsl_ir_constant(expr->operands[1].node); +- if (!(res = hlsl_new_constant(ctx, instr->data_type, &instr->loc))) +- return false; +- switch (expr->op) { + case HLSL_OP1_ABS: -+ success = fold_abs(ctx, &res->value, instr->data_type, arg1); ++ success = fold_abs(ctx, &res, instr->data_type, arg1); + break; + case HLSL_OP1_CAST: - success = fold_cast(ctx, res, arg1); -+ success = fold_cast(ctx, &res->value, instr->data_type, arg1); ++ success = fold_cast(ctx, &res, instr->data_type, arg1); break; case HLSL_OP1_NEG: - success = fold_neg(ctx, res, arg1); -+ success = fold_neg(ctx, &res->value, instr->data_type, arg1); ++ success = fold_neg(ctx, &res, instr->data_type, arg1); break; case HLSL_OP2_ADD: - success = fold_add(ctx, res, arg1, arg2); -+ success = fold_add(ctx, &res->value, instr->data_type, arg1, arg2); ++ success = fold_add(ctx, &res, instr->data_type, arg1, arg2); break; case HLSL_OP2_MUL: - success = fold_mul(ctx, res, arg1, arg2); -+ success = fold_mul(ctx, &res->value, instr->data_type, arg1, arg2); ++ success = fold_mul(ctx, &res, instr->data_type, arg1, arg2); break; case HLSL_OP2_NEQUAL: - success = fold_nequal(ctx, res, arg1, arg2); -+ success = fold_nequal(ctx, &res->value, instr->data_type, arg1, arg2); ++ success = fold_nequal(ctx, &res, instr->data_type, arg1, arg2); break; case HLSL_OP2_DIV: - success = fold_div(ctx, res, arg1, arg2); -+ success = fold_div(ctx, &res->value, instr->data_type, arg1, arg2, &instr->loc); ++ success = fold_div(ctx, &res, instr->data_type, arg1, arg2, &instr->loc); break; case HLSL_OP2_MOD: - success = fold_mod(ctx, res, arg1, arg2); -+ success = fold_mod(ctx, &res->value, instr->data_type, arg1, arg2, &instr->loc); ++ success = fold_mod(ctx, &res, instr->data_type, arg1, arg2, &instr->loc); break; case HLSL_OP2_MAX: - success = fold_max(ctx, res, arg1, arg2); -+ success = fold_max(ctx, &res->value, instr->data_type, arg1, arg2); ++ success = fold_max(ctx, &res, instr->data_type, arg1, arg2); break; case HLSL_OP2_MIN: - success = fold_min(ctx, res, arg1, arg2); -+ success = fold_min(ctx, &res->value, instr->data_type, arg1, arg2); ++ success = fold_min(ctx, &res, instr->data_type, arg1, arg2); break; case HLSL_OP2_BIT_XOR: -@@ -616,7 +663,7 @@ bool hlsl_fold_constant_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst +- success = fold_bit_xor(ctx, res, arg1, arg2); ++ success = fold_bit_xor(ctx, &res, instr->data_type, arg1, arg2); + break; + + case HLSL_OP2_BIT_AND: +- success = fold_bit_and(ctx, res, arg1, arg2); ++ success = fold_bit_and(ctx, &res, instr->data_type, arg1, arg2); + break; + + case HLSL_OP2_BIT_OR: +- success = fold_bit_or(ctx, res, arg1, arg2); ++ success = fold_bit_or(ctx, &res, instr->data_type, arg1, arg2); + break; + + default: +@@ -589,20 +635,20 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, + + if (success) + { +- list_add_before(&expr->node.entry, &res->node.entry); +- hlsl_replace_node(&expr->node, &res->node); +- } +- else +- { +- vkd3d_free(res); ++ if (!(res_node = hlsl_new_constant(ctx, instr->data_type, &res, &instr->loc))) ++ return false; ++ list_add_before(&expr->node.entry, &res_node->entry); ++ hlsl_replace_node(&expr->node, res_node); + } + return success; + } + + bool hlsl_fold_constant_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) + { +- struct hlsl_ir_constant *value, *res; ++ struct hlsl_constant_value value; + struct hlsl_ir_swizzle *swizzle; ++ struct hlsl_ir_constant *src; ++ struct hlsl_ir_node *dst; + unsigned int i; + + if (instr->type != HLSL_IR_SWIZZLE) +@@ -610,15 +656,15 @@ bool hlsl_fold_constant_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst + swizzle = hlsl_ir_swizzle(instr); + if (swizzle->val.node->type != HLSL_IR_CONSTANT) return false; +- value = hlsl_ir_constant(swizzle->val.node); +- +- if (!(res = hlsl_new_constant(ctx, instr->data_type, &instr->loc))) +- return false; ++ src = hlsl_ir_constant(swizzle->val.node); for (i = 0; i < swizzle->node.data_type->dimx; ++i) - res->value[i] = value->value[hlsl_swizzle_get_component(swizzle->swizzle, i)]; -+ res->value.u[i] = value->value.u[hlsl_swizzle_get_component(swizzle->swizzle, i)]; ++ value.u[i] = src->value.u[hlsl_swizzle_get_component(swizzle->swizzle, i)]; ++ ++ if (!(dst = hlsl_new_constant(ctx, instr->data_type, &value, &instr->loc))) ++ return false; - list_add_before(&swizzle->node.entry, &res->node.entry); - hlsl_replace_node(&swizzle->node, &res->node); +- list_add_before(&swizzle->node.entry, &res->node.entry); +- hlsl_replace_node(&swizzle->node, &res->node); ++ list_add_before(&swizzle->node.entry, &dst->entry); ++ hlsl_replace_node(&swizzle->node, dst); + return true; + } diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_sm1.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_sm1.c deleted file mode 100644 index 4a62d804ed6..00000000000 @@ -19289,18 +19898,10 @@ index 4860cf5f90e..e1cb75e177c 100644 struct preproc_if_state { diff --git a/libs/vkd3d/libs/vkd3d-shader/preproc.l b/libs/vkd3d/libs/vkd3d-shader/preproc.l -index bb5a6b61de1..8e35e3555ba 100644 +index bb5a6b61de1..94079696280 100644 --- a/libs/vkd3d/libs/vkd3d-shader/preproc.l +++ b/libs/vkd3d/libs/vkd3d-shader/preproc.l -@@ -20,7 +20,6 @@ - - %{ - --#include "preproc.h" - #include "preproc.tab.h" - - #undef ERROR /* defined in wingdi.h */ -@@ -41,6 +40,7 @@ static void update_location(struct preproc_ctx *ctx); +@@ -41,6 +41,7 @@ static void update_location(struct preproc_ctx *ctx); %option bison-locations %option extra-type="struct preproc_ctx *" %option never-interactive @@ -19308,7 +19909,7 @@ index bb5a6b61de1..8e35e3555ba 100644 %option noinput %option nounput %option noyy_top_state -@@ -75,6 +75,7 @@ INT_SUFFIX [uUlL]{0,2} +@@ -75,6 +76,7 @@ INT_SUFFIX [uUlL]{0,2} "*/" {yy_pop_state(yyscanner);} <> {yy_pop_state(yyscanner);} . {} @@ -19316,7 +19917,7 @@ index bb5a6b61de1..8e35e3555ba 100644 (\\{NEWLINE}|[^\n])* {return T_STRING;} -@@ -176,9 +177,9 @@ INT_SUFFIX [uUlL]{0,2} +@@ -176,9 +178,9 @@ INT_SUFFIX [uUlL]{0,2} return T_NEWLINE; } @@ -21454,10 +22055,10 @@ index 53e13735937..cc0b63e8284 100644 } diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c new file mode 100644 -index 00000000000..2166eb41ac2 +index 00000000000..d066b13ee4e --- /dev/null +++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c -@@ -0,0 +1,5219 @@ +@@ -0,0 +1,5234 @@ +/* + * TPF (Direct3D shader models 4 and 5 bytecode) support + * @@ -24972,16 +25573,6 @@ index 00000000000..2166eb41ac2 + sm4_register_from_node(&dst->reg, &dst->writemask, &swizzle_type, instr); +} + -+static void sm4_src_from_node(struct sm4_src_register *src, -+ const struct hlsl_ir_node *instr, unsigned int map_writemask) -+{ -+ unsigned int writemask; -+ -+ sm4_register_from_node(&src->reg, &writemask, &src->swizzle_type, instr); -+ if (src->swizzle_type == VKD3D_SM4_SWIZZLE_VEC4) -+ src->swizzle = hlsl_map_swizzle(hlsl_swizzle_from_writemask(writemask), map_writemask); -+} -+ +static void sm4_src_from_constant_value(struct sm4_src_register *src, + const struct hlsl_constant_value *value, unsigned int width, unsigned int map_writemask) +{ @@ -25005,6 +25596,24 @@ index 00000000000..2166eb41ac2 + } +} + ++static void sm4_src_from_node(struct sm4_src_register *src, ++ const struct hlsl_ir_node *instr, unsigned int map_writemask) ++{ ++ unsigned int writemask; ++ ++ if (instr->type == HLSL_IR_CONSTANT) ++ { ++ struct hlsl_ir_constant *constant = hlsl_ir_constant(instr); ++ ++ sm4_src_from_constant_value(src, &constant->value, instr->data_type->dimx, map_writemask); ++ return; ++ } ++ ++ sm4_register_from_node(&src->reg, &writemask, &src->swizzle_type, instr); ++ if (src->swizzle_type == VKD3D_SM4_SWIZZLE_VEC4) ++ src->swizzle = hlsl_map_swizzle(hlsl_swizzle_from_writemask(writemask), map_writemask); ++} ++ +static uint32_t sm4_encode_register(const struct sm4_register *reg) +{ + return (reg->type << VKD3D_SM4_REGISTER_TYPE_SHIFT) @@ -25109,8 +25718,12 @@ index 00000000000..2166eb41ac2 + + modif.type = VKD3D_SM4_MODIFIER_AOFFIMMI; + modif.u.aoffimmi.u = offset->value.u[0].i; -+ modif.u.aoffimmi.v = offset->value.u[1].i; -+ modif.u.aoffimmi.w = offset->value.u[2].i; ++ modif.u.aoffimmi.v = 0; ++ modif.u.aoffimmi.w = 0; ++ if (offset->node.data_type->dimx > 1) ++ modif.u.aoffimmi.v = offset->value.u[1].i; ++ if (offset->node.data_type->dimx > 2) ++ modif.u.aoffimmi.w = offset->value.u[2].i; + if (modif.u.aoffimmi.u < -8 || modif.u.aoffimmi.u > 7 + || modif.u.aoffimmi.v < -8 || modif.u.aoffimmi.v > 7 + || modif.u.aoffimmi.w < -8 || modif.u.aoffimmi.w > 7) @@ -25140,23 +25753,24 @@ index 00000000000..2166eb41ac2 +static void write_sm4_dcl_samplers(struct vkd3d_bytecode_buffer *buffer, const struct hlsl_ir_var *var) +{ + unsigned int i, count = var->data_type->reg_size[HLSL_REGSET_SAMPLERS]; -+ struct sm4_instruction instr; ++ struct sm4_instruction instr = ++ { ++ .opcode = VKD3D_SM4_OP_DCL_SAMPLER, ++ ++ .dsts[0].reg.type = VKD3D_SM4_RT_SAMPLER, ++ .dsts[0].reg.idx_count = 1, ++ .dst_count = 1, ++ }; ++ ++ if (var->data_type->sampler_dim == HLSL_SAMPLER_DIM_COMPARISON) ++ instr.opcode |= VKD3D_SM4_SAMPLER_COMPARISON << VKD3D_SM4_SAMPLER_MODE_SHIFT; + + for (i = 0; i < count; ++i) + { + if (!var->objects_usage[HLSL_REGSET_SAMPLERS][i].used) + continue; + -+ instr = (struct sm4_instruction) -+ { -+ .opcode = VKD3D_SM4_OP_DCL_SAMPLER, -+ -+ .dsts[0].reg.type = VKD3D_SM4_RT_SAMPLER, -+ .dsts[0].reg.idx = {var->regs[HLSL_REGSET_SAMPLERS].id + i}, -+ .dsts[0].reg.idx_count = 1, -+ .dst_count = 1, -+ }; -+ ++ instr.dsts[0].reg.idx[0] = var->regs[HLSL_REGSET_SAMPLERS].id + i; + write_sm4_instruction(buffer, &instr); + } +} @@ -25454,24 +26068,6 @@ index 00000000000..2166eb41ac2 + write_sm4_instruction(buffer, &instr); +} + -+static void write_sm4_constant(struct hlsl_ctx *ctx, -+ struct vkd3d_bytecode_buffer *buffer, const struct hlsl_ir_constant *constant) -+{ -+ const unsigned int dimx = constant->node.data_type->dimx; -+ struct sm4_instruction instr; -+ -+ memset(&instr, 0, sizeof(instr)); -+ instr.opcode = VKD3D_SM4_OP_MOV; -+ -+ sm4_dst_from_node(&instr.dsts[0], &constant->node); -+ instr.dst_count = 1; -+ -+ sm4_src_from_constant_value(&instr.srcs[0], &constant->value, dimx, instr.dsts[0].writemask); -+ instr.src_count = 1, -+ -+ write_sm4_instruction(buffer, &instr); -+} -+ +static void write_sm4_ld(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, + const struct hlsl_type *resource_type, const struct hlsl_ir_node *dst, + const struct hlsl_deref *resource, const struct hlsl_ir_node *coords, @@ -25481,8 +26077,8 @@ index 00000000000..2166eb41ac2 + 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); ++ unsigned int coords_writemask = VKD3DSP_WRITEMASK_ALL; + struct sm4_instruction instr; -+ unsigned int dim_count; + + memset(&instr, 0, sizeof(instr)); + if (uav) @@ -25503,19 +26099,20 @@ index 00000000000..2166eb41ac2 + sm4_dst_from_node(&instr.dsts[0], dst); + instr.dst_count = 1; + -+ sm4_src_from_node(&instr.srcs[0], coords, VKD3DSP_WRITEMASK_ALL); -+ + if (!uav) + { + /* Mipmap level is in the last component in the IR, but needs to be in the W + * component in the instruction. */ -+ dim_count = hlsl_sampler_dim_count(dim); ++ unsigned int dim_count = hlsl_sampler_dim_count(dim); ++ + if (dim_count == 1) -+ instr.srcs[0].swizzle = hlsl_combine_swizzles(instr.srcs[0].swizzle, HLSL_SWIZZLE(X, X, X, Y), 4); ++ coords_writemask = VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_3; + if (dim_count == 2) -+ instr.srcs[0].swizzle = hlsl_combine_swizzles(instr.srcs[0].swizzle, HLSL_SWIZZLE(X, Y, X, Z), 4); ++ coords_writemask = VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1 | VKD3DSP_WRITEMASK_3; + } + ++ sm4_src_from_node(&instr.srcs[0], coords, coords_writemask); ++ + sm4_src_from_deref(ctx, &instr.srcs[1], resource, resource_type, instr.dsts[0].writemask); + + instr.src_count = 2; @@ -25568,6 +26165,14 @@ index 00000000000..2166eb41ac2 + instr.opcode = VKD3D_SM4_OP_SAMPLE; + break; + ++ case HLSL_RESOURCE_SAMPLE_CMP: ++ instr.opcode = VKD3D_SM4_OP_SAMPLE_C; ++ break; ++ ++ case HLSL_RESOURCE_SAMPLE_CMP_LZ: ++ instr.opcode = VKD3D_SM4_OP_SAMPLE_C_LZ; ++ break; ++ + case HLSL_RESOURCE_SAMPLE_LOD: + instr.opcode = VKD3D_SM4_OP_SAMPLE_LOD; + break; @@ -25614,6 +26219,12 @@ index 00000000000..2166eb41ac2 + sm4_src_from_node(&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); ++ ++instr.src_count; ++ } + + write_sm4_instruction(buffer, &instr); +} @@ -26412,6 +27023,8 @@ index 00000000000..2166eb41ac2 + break; + + case HLSL_RESOURCE_SAMPLE: ++ case HLSL_RESOURCE_SAMPLE_CMP: ++ case HLSL_RESOURCE_SAMPLE_CMP_LZ: + case HLSL_RESOURCE_SAMPLE_LOD: + case HLSL_RESOURCE_SAMPLE_LOD_BIAS: + case HLSL_RESOURCE_SAMPLE_GRAD: @@ -26532,16 +27145,19 @@ index 00000000000..2166eb41ac2 + } + + assert(instr->data_type->class == HLSL_CLASS_SCALAR || instr->data_type->class == HLSL_CLASS_VECTOR); ++ ++ if (!instr->reg.allocated) ++ { ++ assert(instr->type == HLSL_IR_CONSTANT); ++ continue; ++ } + } + + switch (instr->type) + { + case HLSL_IR_CALL: -+ vkd3d_unreachable(); -+ + case HLSL_IR_CONSTANT: -+ write_sm4_constant(ctx, buffer, hlsl_ir_constant(instr)); -+ break; ++ vkd3d_unreachable(); + + case HLSL_IR_EXPR: + write_sm4_expr(ctx, buffer, hlsl_ir_expr(instr)); diff --git a/patches/vkd3d-latest/0003-Updated-vkd3d-to-7c360330d74f5c2f6de962355927ee6e7d7.patch b/patches/vkd3d-latest/0003-Updated-vkd3d-to-7c360330d74f5c2f6de962355927ee6e7d7.patch deleted file mode 100644 index f56c5099..00000000 --- a/patches/vkd3d-latest/0003-Updated-vkd3d-to-7c360330d74f5c2f6de962355927ee6e7d7.patch +++ /dev/null @@ -1,611 +0,0 @@ -From 8af3410aba9ba20ac32a17241dfe1f33f259fbd1 Mon Sep 17 00:00:00 2001 -From: Alistair Leslie-Hughes -Date: Fri, 2 Jun 2023 10:30:18 +1000 -Subject: [PATCH 3/3] Updated vkd3d to 7c360330d74f5c2f6de962355927ee6e7d7dfbf0 - ---- - libs/vkd3d/libs/vkd3d-shader/hlsl.c | 21 +- - libs/vkd3d/libs/vkd3d-shader/hlsl.h | 7 +- - libs/vkd3d/libs/vkd3d-shader/hlsl.y | 202 +++++++++++++++----- - libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 6 + - libs/vkd3d/libs/vkd3d-shader/preproc.l | 1 + - libs/vkd3d/libs/vkd3d-shader/tpf.c | 96 +++++----- - 6 files changed, 239 insertions(+), 94 deletions(-) - -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c -index 5bca84ba38a..152ec6275eb 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c -@@ -1356,6 +1356,7 @@ struct hlsl_ir_node *hlsl_new_resource_load(struct hlsl_ctx *ctx, - hlsl_src_from_node(&load->lod, params->lod); - hlsl_src_from_node(&load->ddx, params->ddx); - hlsl_src_from_node(&load->ddy, params->ddy); -+ hlsl_src_from_node(&load->cmp, params->cmp); - load->sampling_dim = params->sampling_dim; - if (load->sampling_dim == HLSL_SAMPLER_DIM_GENERIC) - load->sampling_dim = hlsl_deref_get_type(ctx, &load->resource)->sampler_dim; -@@ -1649,6 +1650,7 @@ static struct hlsl_ir_node *clone_resource_load(struct hlsl_ctx *ctx, - clone_src(map, &dst->ddx, &src->ddx); - clone_src(map, &dst->ddy, &src->ddy); - clone_src(map, &dst->sample_index, &src->sample_index); -+ clone_src(map, &dst->cmp, &src->cmp); - clone_src(map, &dst->texel_offset, &src->texel_offset); - dst->sampling_dim = src->sampling_dim; - return &dst->node; -@@ -2442,6 +2444,8 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru - { - [HLSL_RESOURCE_LOAD] = "load_resource", - [HLSL_RESOURCE_SAMPLE] = "sample", -+ [HLSL_RESOURCE_SAMPLE_CMP] = "sample_cmp", -+ [HLSL_RESOURCE_SAMPLE_CMP_LZ] = "sample_cmp_lz", - [HLSL_RESOURCE_SAMPLE_LOD] = "sample_lod", - [HLSL_RESOURCE_SAMPLE_LOD_BIAS] = "sample_biased", - [HLSL_RESOURCE_SAMPLE_GRAD] = "sample_grad", -@@ -2483,6 +2487,11 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru - vkd3d_string_buffer_printf(buffer, ", ddy = "); - dump_src(buffer, &load->ddy); - } -+ if (load->cmp.node) -+ { -+ vkd3d_string_buffer_printf(buffer, ", cmp = "); -+ dump_src(buffer, &load->cmp); -+ } - vkd3d_string_buffer_printf(buffer, ")"); - } - -@@ -2720,6 +2729,7 @@ static void free_ir_resource_load(struct hlsl_ir_resource_load *load) - hlsl_src_remove(&load->lod); - hlsl_src_remove(&load->ddx); - hlsl_src_remove(&load->ddy); -+ hlsl_src_remove(&load->cmp); - hlsl_src_remove(&load->texel_offset); - hlsl_src_remove(&load->sample_index); - vkd3d_free(load); -@@ -3061,11 +3071,12 @@ static void declare_predefined_types(struct hlsl_ctx *ctx) - - static const char *const sampler_names[] = - { -- [HLSL_SAMPLER_DIM_GENERIC] = "sampler", -- [HLSL_SAMPLER_DIM_1D] = "sampler1D", -- [HLSL_SAMPLER_DIM_2D] = "sampler2D", -- [HLSL_SAMPLER_DIM_3D] = "sampler3D", -- [HLSL_SAMPLER_DIM_CUBE] = "samplerCUBE", -+ [HLSL_SAMPLER_DIM_GENERIC] = "sampler", -+ [HLSL_SAMPLER_DIM_COMPARISON] = "SamplerComparisonState", -+ [HLSL_SAMPLER_DIM_1D] = "sampler1D", -+ [HLSL_SAMPLER_DIM_2D] = "sampler2D", -+ [HLSL_SAMPLER_DIM_3D] = "sampler3D", -+ [HLSL_SAMPLER_DIM_CUBE] = "samplerCUBE", - }; - - static const struct -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h -index 376191b9ff3..6b79c582f55 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h -@@ -105,6 +105,7 @@ enum hlsl_base_type - enum hlsl_sampler_dim - { - HLSL_SAMPLER_DIM_GENERIC, -+ HLSL_SAMPLER_DIM_COMPARISON, - HLSL_SAMPLER_DIM_1D, - HLSL_SAMPLER_DIM_2D, - HLSL_SAMPLER_DIM_3D, -@@ -614,6 +615,8 @@ enum hlsl_resource_load_type - { - HLSL_RESOURCE_LOAD, - HLSL_RESOURCE_SAMPLE, -+ HLSL_RESOURCE_SAMPLE_CMP, -+ HLSL_RESOURCE_SAMPLE_CMP_LZ, - HLSL_RESOURCE_SAMPLE_LOD, - HLSL_RESOURCE_SAMPLE_LOD_BIAS, - HLSL_RESOURCE_SAMPLE_GRAD, -@@ -628,7 +631,7 @@ struct hlsl_ir_resource_load - struct hlsl_ir_node node; - enum hlsl_resource_load_type load_type; - struct hlsl_deref resource, sampler; -- struct hlsl_src coords, lod, ddx, ddy, sample_index, texel_offset; -+ struct hlsl_src coords, lod, ddx, ddy, cmp, sample_index, texel_offset; - enum hlsl_sampler_dim sampling_dim; - }; - -@@ -830,7 +833,7 @@ struct hlsl_resource_load_params - struct hlsl_type *format; - enum hlsl_resource_load_type type; - struct hlsl_ir_node *resource, *sampler; -- struct hlsl_ir_node *coords, *lod, *ddx, *ddy, *sample_index, *texel_offset; -+ struct hlsl_ir_node *coords, *lod, *ddx, *ddy, *cmp, *sample_index, *texel_offset; - enum hlsl_sampler_dim sampling_dim; - }; - -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y -index dae1851c7ad..cf483d82c65 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y -@@ -3721,6 +3721,18 @@ static unsigned int hlsl_offset_dim_count(enum hlsl_sampler_dim dim) - } - } - -+static bool raise_invalid_method_object_type(struct hlsl_ctx *ctx, const struct hlsl_type *object_type, -+ const char *method, const struct vkd3d_shader_location *loc) -+{ -+ struct vkd3d_string_buffer *string; -+ -+ if ((string = hlsl_type_to_string(ctx, object_type))) -+ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, -+ "Method '%s' is not defined on type '%s'.", method, string->buffer); -+ hlsl_release_string_buffer(ctx, string); -+ return false; -+} -+ - static bool add_load_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *object, - const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) - { -@@ -3731,6 +3743,12 @@ static bool add_load_method_call(struct hlsl_ctx *ctx, struct list *instrs, stru - struct hlsl_ir_node *load; - bool multisampled; - -+ if (object_type->sampler_dim == HLSL_SAMPLER_DIM_CUBE -+ || object_type->sampler_dim == HLSL_SAMPLER_DIM_CUBEARRAY) -+ { -+ return raise_invalid_method_object_type(ctx, object_type, name, loc); -+ } -+ - multisampled = object_type->sampler_dim == HLSL_SAMPLER_DIM_2DMS - || object_type->sampler_dim == HLSL_SAMPLER_DIM_2DMSARRAY; - -@@ -3784,6 +3802,12 @@ static bool add_sample_method_call(struct hlsl_ctx *ctx, struct list *instrs, st - const struct hlsl_type *sampler_type; - struct hlsl_ir_node *load; - -+ if (object_type->sampler_dim == HLSL_SAMPLER_DIM_2DMS -+ || object_type->sampler_dim == HLSL_SAMPLER_DIM_2DMSARRAY) -+ { -+ return raise_invalid_method_object_type(ctx, object_type, name, loc); -+ } -+ - if (params->args_count < 2 || params->args_count > 4 + !!offset_dim) - { - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, -@@ -3832,6 +3856,80 @@ static bool add_sample_method_call(struct hlsl_ctx *ctx, struct list *instrs, st - return true; - } - -+static bool add_sample_cmp_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *object, -+ const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) -+{ -+ const struct hlsl_type *object_type = object->data_type; -+ const unsigned int sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim); -+ const unsigned int offset_dim = hlsl_offset_dim_count(object_type->sampler_dim); -+ struct hlsl_resource_load_params load_params = { 0 }; -+ const struct hlsl_type *sampler_type; -+ struct hlsl_ir_node *load; -+ -+ if (object_type->sampler_dim == HLSL_SAMPLER_DIM_2DMS -+ || object_type->sampler_dim == HLSL_SAMPLER_DIM_2DMSARRAY) -+ { -+ return raise_invalid_method_object_type(ctx, object_type, name, loc); -+ } -+ -+ if (!strcmp(name, "SampleCmpLevelZero")) -+ load_params.type = HLSL_RESOURCE_SAMPLE_CMP_LZ; -+ else -+ load_params.type = HLSL_RESOURCE_SAMPLE_CMP; -+ -+ if (params->args_count < 3 || params->args_count > 5 + !!offset_dim) -+ { -+ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, -+ "Wrong number of arguments to method '%s': expected from 3 to %u, but got %u.", -+ name, 5 + !!offset_dim, params->args_count); -+ return false; -+ } -+ -+ sampler_type = params->args[0]->data_type; -+ if (sampler_type->class != HLSL_CLASS_OBJECT || sampler_type->base_type != HLSL_TYPE_SAMPLER -+ || sampler_type->sampler_dim != HLSL_SAMPLER_DIM_COMPARISON) -+ { -+ struct vkd3d_string_buffer *string; -+ -+ if ((string = hlsl_type_to_string(ctx, sampler_type))) -+ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, -+ "Wrong type for argument 0 of %s(): expected 'SamplerComparisonState', but got '%s'.", -+ name, string->buffer); -+ hlsl_release_string_buffer(ctx, string); -+ return false; -+ } -+ -+ if (!(load_params.coords = add_implicit_conversion(ctx, instrs, params->args[1], -+ hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) -+ return false; -+ -+ if (!(load_params.cmp = add_implicit_conversion(ctx, instrs, params->args[2], -+ hlsl_get_scalar_type(ctx, HLSL_TYPE_FLOAT), loc))) -+ load_params.cmp = params->args[2]; -+ -+ if (offset_dim && params->args_count > 3) -+ { -+ if (!(load_params.texel_offset = add_implicit_conversion(ctx, instrs, params->args[2], -+ hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc))) -+ return false; -+ } -+ -+ if (params->args_count > 3 + !!offset_dim) -+ hlsl_fixme(ctx, loc, "%s() clamp parameter.", name); -+ if (params->args_count > 4 + !!offset_dim) -+ hlsl_fixme(ctx, loc, "Tiled resource status argument."); -+ -+ load_params.format = object_type->e.resource_format; -+ load_params.resource = object; -+ load_params.sampler = params->args[0]; -+ -+ if (!(load = hlsl_new_resource_load(ctx, &load_params, loc))) -+ return false; -+ list_add_tail(instrs, &load->entry); -+ -+ return true; -+} -+ - static bool add_gather_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *object, - const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) - { -@@ -3843,6 +3941,14 @@ static bool add_gather_method_call(struct hlsl_ctx *ctx, struct list *instrs, st - struct hlsl_ir_node *load; - unsigned int read_channel; - -+ if (object_type->sampler_dim != HLSL_SAMPLER_DIM_2D -+ && object_type->sampler_dim != HLSL_SAMPLER_DIM_2DARRAY -+ && object_type->sampler_dim != HLSL_SAMPLER_DIM_CUBE -+ && object_type->sampler_dim != HLSL_SAMPLER_DIM_CUBEARRAY) -+ { -+ return raise_invalid_method_object_type(ctx, object_type, name, loc); -+ } -+ - if (!strcmp(name, "GatherGreen")) - { - load_params.type = HLSL_RESOURCE_GATHER_GREEN; -@@ -3940,6 +4046,12 @@ static bool add_sample_lod_method_call(struct hlsl_ctx *ctx, struct list *instrs - const struct hlsl_type *sampler_type; - struct hlsl_ir_node *load; - -+ if (object_type->sampler_dim == HLSL_SAMPLER_DIM_2DMS -+ || object_type->sampler_dim == HLSL_SAMPLER_DIM_2DMSARRAY) -+ { -+ return raise_invalid_method_object_type(ctx, object_type, name, loc); -+ } -+ - if (!strcmp(name, "SampleLevel")) - load_params.type = HLSL_RESOURCE_SAMPLE_LOD; - else -@@ -4004,6 +4116,12 @@ static bool add_sample_grad_method_call(struct hlsl_ctx *ctx, struct list *instr - const struct hlsl_type *sampler_type; - struct hlsl_ir_node *load; - -+ if (object_type->sampler_dim == HLSL_SAMPLER_DIM_2DMS -+ || object_type->sampler_dim == HLSL_SAMPLER_DIM_2DMSARRAY) -+ { -+ return raise_invalid_method_object_type(ctx, object_type, name, loc); -+ } -+ - load_params.type = HLSL_RESOURCE_SAMPLE_GRAD; - - if (params->args_count < 4 || params->args_count > 5 + !!offset_dim) -@@ -4059,10 +4177,42 @@ static bool add_sample_grad_method_call(struct hlsl_ctx *ctx, struct list *instr - return true; - } - -+static const struct method_function -+{ -+ const char *name; -+ bool (*handler)(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *object, -+ const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc); -+} -+object_methods[] = -+{ -+ { "Gather", add_gather_method_call }, -+ { "GatherAlpha", add_gather_method_call }, -+ { "GatherBlue", add_gather_method_call }, -+ { "GatherGreen", add_gather_method_call }, -+ { "GatherRed", add_gather_method_call }, -+ -+ { "Load", add_load_method_call }, -+ -+ { "Sample", add_sample_method_call }, -+ { "SampleBias", add_sample_lod_method_call }, -+ { "SampleCmp", add_sample_cmp_method_call }, -+ { "SampleCmpLevelZero", add_sample_cmp_method_call }, -+ { "SampleGrad", add_sample_grad_method_call }, -+ { "SampleLevel", add_sample_lod_method_call }, -+}; -+ -+static int object_method_function_name_compare(const void *a, const void *b) -+{ -+ const struct method_function *func = b; -+ -+ return strcmp(a, func->name); -+} -+ - static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *object, - const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) - { - const struct hlsl_type *object_type = object->data_type; -+ const struct method_function *method; - - if (object_type->class != HLSL_CLASS_OBJECT || object_type->base_type != HLSL_TYPE_TEXTURE - || object_type->sampler_dim == HLSL_SAMPLER_DIM_GENERIC) -@@ -4076,54 +4226,14 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl - return false; - } - -- if (!strcmp(name, "Load") -- && object_type->sampler_dim != HLSL_SAMPLER_DIM_CUBE -- && object_type->sampler_dim != HLSL_SAMPLER_DIM_CUBEARRAY) -- { -- return add_load_method_call(ctx, instrs, object, name, params, loc); -- } -- else if (!strcmp(name, "Sample") -- && object_type->sampler_dim != HLSL_SAMPLER_DIM_2DMS -- && object_type->sampler_dim != HLSL_SAMPLER_DIM_2DMSARRAY) -- { -- return add_sample_method_call(ctx, instrs, object, name, params, loc); -- } -- else if ((!strcmp(name, "Gather") || !strcmp(name, "GatherRed") || !strcmp(name, "GatherBlue") -- || !strcmp(name, "GatherGreen") || !strcmp(name, "GatherAlpha")) -- && (object_type->sampler_dim == HLSL_SAMPLER_DIM_2D -- || object_type->sampler_dim == HLSL_SAMPLER_DIM_2DARRAY -- || object_type->sampler_dim == HLSL_SAMPLER_DIM_CUBE -- || object_type->sampler_dim == HLSL_SAMPLER_DIM_CUBEARRAY)) -- { -- return add_gather_method_call(ctx, instrs, object, name, params, loc); -- } -- else if (!strcmp(name, "SampleLevel") -- && object_type->sampler_dim != HLSL_SAMPLER_DIM_2DMS -- && object_type->sampler_dim != HLSL_SAMPLER_DIM_2DMSARRAY) -- { -- return add_sample_lod_method_call(ctx, instrs, object, name, params, loc); -- } -- else if (!strcmp(name, "SampleBias") -- && object_type->sampler_dim != HLSL_SAMPLER_DIM_2DMS -- && object_type->sampler_dim != HLSL_SAMPLER_DIM_2DMSARRAY) -- { -- return add_sample_lod_method_call(ctx, instrs, object, name, params, loc); -- } -- else if (!strcmp(name, "SampleGrad") -- && object_type->sampler_dim != HLSL_SAMPLER_DIM_2DMS -- && object_type->sampler_dim != HLSL_SAMPLER_DIM_2DMSARRAY) -+ if ((method = bsearch(name, object_methods, ARRAY_SIZE(object_methods), -+ sizeof(*method), object_method_function_name_compare))) - { -- return add_sample_grad_method_call(ctx, instrs, object, name, params, loc); -+ return method->handler(ctx, instrs, object, name, params, loc); - } - else - { -- struct vkd3d_string_buffer *string; -- -- if ((string = hlsl_type_to_string(ctx, object_type))) -- hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, -- "Method '%s' is not defined on type '%s'.", name, string->buffer); -- hlsl_release_string_buffer(ctx, string); -- return false; -+ return raise_invalid_method_object_type(ctx, object_type, name, loc); - } - } - -@@ -5114,6 +5224,10 @@ type_no_void: - { - $$ = ctx->builtin_types.sampler[HLSL_SAMPLER_DIM_GENERIC]; - } -+ | KW_SAMPLERCOMPARISONSTATE -+ { -+ $$ = ctx->builtin_types.sampler[HLSL_SAMPLER_DIM_COMPARISON]; -+ } - | KW_SAMPLER1D - { - $$ = ctx->builtin_types.sampler[HLSL_SAMPLER_DIM_1D]; -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -index bbb5223b1ec..2b6c595a15d 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -@@ -2680,6 +2680,8 @@ static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop - load->ddy.node->last_read = last_read; - if (load->sample_index.node) - load->sample_index.node->last_read = last_read; -+ if (load->cmp.node) -+ load->cmp.node->last_read = last_read; - break; - } - case HLSL_IR_RESOURCE_STORE: -@@ -3002,6 +3004,10 @@ static void allocate_temp_registers_recurse(struct hlsl_ctx *ctx, - - LIST_FOR_EACH_ENTRY(instr, &block->instrs, struct hlsl_ir_node, entry) - { -+ /* In SM4 all constants are inlined. */ -+ if (ctx->profile->major_version >= 4 && instr->type == HLSL_IR_CONSTANT) -+ continue; -+ - if (!instr->reg.allocated && instr->last_read) - { - instr->reg = allocate_numeric_registers_for_type(ctx, allocator, instr->index, instr->last_read, -diff --git a/libs/vkd3d/libs/vkd3d-shader/preproc.l b/libs/vkd3d/libs/vkd3d-shader/preproc.l -index 8e35e3555ba..94079696280 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/preproc.l -+++ b/libs/vkd3d/libs/vkd3d-shader/preproc.l -@@ -20,6 +20,7 @@ - - %{ - -+#include "preproc.h" - #include "preproc.tab.h" - - #undef ERROR /* defined in wingdi.h */ -diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c -index 2166eb41ac2..60948d6498b 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/tpf.c -+++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c -@@ -3512,16 +3512,6 @@ static void sm4_dst_from_node(struct sm4_dst_register *dst, const struct hlsl_ir - sm4_register_from_node(&dst->reg, &dst->writemask, &swizzle_type, instr); - } - --static void sm4_src_from_node(struct sm4_src_register *src, -- const struct hlsl_ir_node *instr, unsigned int map_writemask) --{ -- unsigned int writemask; -- -- sm4_register_from_node(&src->reg, &writemask, &src->swizzle_type, instr); -- if (src->swizzle_type == VKD3D_SM4_SWIZZLE_VEC4) -- src->swizzle = hlsl_map_swizzle(hlsl_swizzle_from_writemask(writemask), map_writemask); --} -- - static void sm4_src_from_constant_value(struct sm4_src_register *src, - const struct hlsl_constant_value *value, unsigned int width, unsigned int map_writemask) - { -@@ -3545,6 +3535,24 @@ 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) -+{ -+ unsigned int writemask; -+ -+ if (instr->type == HLSL_IR_CONSTANT) -+ { -+ struct hlsl_ir_constant *constant = hlsl_ir_constant(instr); -+ -+ sm4_src_from_constant_value(src, &constant->value, instr->data_type->dimx, map_writemask); -+ return; -+ } -+ -+ sm4_register_from_node(&src->reg, &writemask, &src->swizzle_type, instr); -+ if (src->swizzle_type == VKD3D_SM4_SWIZZLE_VEC4) -+ src->swizzle = hlsl_map_swizzle(hlsl_swizzle_from_writemask(writemask), map_writemask); -+} -+ - static uint32_t sm4_encode_register(const struct sm4_register *reg) - { - return (reg->type << VKD3D_SM4_REGISTER_TYPE_SHIFT) -@@ -3680,23 +3688,24 @@ static void write_sm4_dcl_constant_buffer(struct vkd3d_bytecode_buffer *buffer, - static void write_sm4_dcl_samplers(struct vkd3d_bytecode_buffer *buffer, const struct hlsl_ir_var *var) - { - unsigned int i, count = var->data_type->reg_size[HLSL_REGSET_SAMPLERS]; -- struct sm4_instruction instr; -+ struct sm4_instruction instr = -+ { -+ .opcode = VKD3D_SM4_OP_DCL_SAMPLER, -+ -+ .dsts[0].reg.type = VKD3D_SM4_RT_SAMPLER, -+ .dsts[0].reg.idx_count = 1, -+ .dst_count = 1, -+ }; -+ -+ if (var->data_type->sampler_dim == HLSL_SAMPLER_DIM_COMPARISON) -+ instr.opcode |= VKD3D_SM4_SAMPLER_COMPARISON << VKD3D_SM4_SAMPLER_MODE_SHIFT; - - for (i = 0; i < count; ++i) - { - if (!var->objects_usage[HLSL_REGSET_SAMPLERS][i].used) - continue; - -- instr = (struct sm4_instruction) -- { -- .opcode = VKD3D_SM4_OP_DCL_SAMPLER, -- -- .dsts[0].reg.type = VKD3D_SM4_RT_SAMPLER, -- .dsts[0].reg.idx = {var->regs[HLSL_REGSET_SAMPLERS].id + i}, -- .dsts[0].reg.idx_count = 1, -- .dst_count = 1, -- }; -- -+ instr.dsts[0].reg.idx[0] = var->regs[HLSL_REGSET_SAMPLERS].id + i; - write_sm4_instruction(buffer, &instr); - } - } -@@ -3994,24 +4003,6 @@ static void write_sm4_binary_op_with_two_destinations(struct vkd3d_bytecode_buff - write_sm4_instruction(buffer, &instr); - } - --static void write_sm4_constant(struct hlsl_ctx *ctx, -- struct vkd3d_bytecode_buffer *buffer, const struct hlsl_ir_constant *constant) --{ -- const unsigned int dimx = constant->node.data_type->dimx; -- struct sm4_instruction instr; -- -- memset(&instr, 0, sizeof(instr)); -- instr.opcode = VKD3D_SM4_OP_MOV; -- -- sm4_dst_from_node(&instr.dsts[0], &constant->node); -- instr.dst_count = 1; -- -- sm4_src_from_constant_value(&instr.srcs[0], &constant->value, dimx, instr.dsts[0].writemask); -- instr.src_count = 1, -- -- write_sm4_instruction(buffer, &instr); --} -- - static void write_sm4_ld(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, - const struct hlsl_type *resource_type, const struct hlsl_ir_node *dst, - const struct hlsl_deref *resource, const struct hlsl_ir_node *coords, -@@ -4108,6 +4099,14 @@ static void write_sm4_sample(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer - instr.opcode = VKD3D_SM4_OP_SAMPLE; - break; - -+ case HLSL_RESOURCE_SAMPLE_CMP: -+ instr.opcode = VKD3D_SM4_OP_SAMPLE_C; -+ break; -+ -+ case HLSL_RESOURCE_SAMPLE_CMP_LZ: -+ instr.opcode = VKD3D_SM4_OP_SAMPLE_C_LZ; -+ break; -+ - case HLSL_RESOURCE_SAMPLE_LOD: - instr.opcode = VKD3D_SM4_OP_SAMPLE_LOD; - break; -@@ -4154,6 +4153,12 @@ static void write_sm4_sample(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer - sm4_src_from_node(&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); -+ ++instr.src_count; -+ } - - write_sm4_instruction(buffer, &instr); - } -@@ -4952,6 +4957,8 @@ static void write_sm4_resource_load(struct hlsl_ctx *ctx, - break; - - case HLSL_RESOURCE_SAMPLE: -+ case HLSL_RESOURCE_SAMPLE_CMP: -+ case HLSL_RESOURCE_SAMPLE_CMP_LZ: - case HLSL_RESOURCE_SAMPLE_LOD: - case HLSL_RESOURCE_SAMPLE_LOD_BIAS: - case HLSL_RESOURCE_SAMPLE_GRAD: -@@ -5072,16 +5079,19 @@ static void write_sm4_block(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer * - } - - assert(instr->data_type->class == HLSL_CLASS_SCALAR || instr->data_type->class == HLSL_CLASS_VECTOR); -+ -+ if (!instr->reg.allocated) -+ { -+ assert(instr->type == HLSL_IR_CONSTANT); -+ continue; -+ } - } - - switch (instr->type) - { - case HLSL_IR_CALL: -- vkd3d_unreachable(); -- - case HLSL_IR_CONSTANT: -- write_sm4_constant(ctx, buffer, hlsl_ir_constant(instr)); -- break; -+ vkd3d_unreachable(); - - case HLSL_IR_EXPR: - write_sm4_expr(ctx, buffer, hlsl_ir_expr(instr)); --- -2.40.1 - diff --git a/patches/vkd3d-latest/0004-Update-vkd3d-to-82ddc6b417b79919f3e730ef3f2e167ab846.patch b/patches/vkd3d-latest/0004-Update-vkd3d-to-82ddc6b417b79919f3e730ef3f2e167ab846.patch deleted file mode 100644 index fb4599c2..00000000 --- a/patches/vkd3d-latest/0004-Update-vkd3d-to-82ddc6b417b79919f3e730ef3f2e167ab846.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 0c66ff2fbfc263e55ebd008772f56e4f432e32a9 Mon Sep 17 00:00:00 2001 -From: Alistair Leslie-Hughes -Date: Wed, 7 Jun 2023 08:12:13 +1000 -Subject: [PATCH] Update vkd3d to 82ddc6b417b79919f3e730ef3f2e167ab8462010 - ---- - libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 2 +- - libs/vkd3d/libs/vkd3d-shader/hlsl.y | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c -index 3357b4505c0..0a821b5c878 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c -+++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c -@@ -646,7 +646,7 @@ static void shader_dump_decl_usage(struct vkd3d_d3d_asm_compiler *compiler, - break; - - case VKD3D_SHADER_RESOURCE_TEXTURE_3D: -- shader_addline(buffer, "_3d"); -+ shader_addline(buffer, "_volume"); - break; - - case VKD3D_SHADER_RESOURCE_TEXTURE_CUBE: -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y -index cf483d82c65..30d0975102f 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y -@@ -5242,7 +5242,7 @@ type_no_void: - } - | KW_SAMPLERCUBE - { -- $$ = ctx->builtin_types.sampler[HLSL_SAMPLER_DIM_3D]; -+ $$ = ctx->builtin_types.sampler[HLSL_SAMPLER_DIM_CUBE]; - } - | KW_TEXTURE - { --- -2.40.1 - diff --git a/patches/vkd3d-latest/0005--Updated-vkd3d-to-ebf7573571d4bfcd3f38846886106f204fd.patch b/patches/vkd3d-latest/0005--Updated-vkd3d-to-ebf7573571d4bfcd3f38846886106f204fd.patch deleted file mode 100644 index 4875240d..00000000 --- a/patches/vkd3d-latest/0005--Updated-vkd3d-to-ebf7573571d4bfcd3f38846886106f204fd.patch +++ /dev/null @@ -1,336 +0,0 @@ -From 65a602939e9306618d1ec33d19b217b869638beb Mon Sep 17 00:00:00 2001 -From: Alistair Leslie-Hughes -Date: Thu, 8 Jun 2023 14:11:22 +1000 -Subject: [PATCH] Updated vkd3d to ebf7573571d4bfcd3f38846886106f204fd7f0e8 - ---- - libs/vkd3d/libs/vkd3d-shader/hlsl.c | 13 ++ - libs/vkd3d/libs/vkd3d-shader/hlsl.h | 2 + - libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 209 ++++++++++++++++---- - 3 files changed, 191 insertions(+), 33 deletions(-) - -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c -index 152ec6275eb..f1edfa5e625 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c -@@ -1287,6 +1287,19 @@ struct hlsl_ir_load *hlsl_new_load_index(struct hlsl_ctx *ctx, const struct hlsl - return load; - } - -+struct hlsl_ir_load *hlsl_new_load_parent(struct hlsl_ctx *ctx, const struct hlsl_deref *deref, -+ const struct vkd3d_shader_location *loc) -+{ -+ /* This deref can only exists temporarily because it is not the real owner of its members. */ -+ struct hlsl_deref tmp_deref; -+ -+ assert(deref->path_len >= 1); -+ -+ tmp_deref = *deref; -+ tmp_deref.path_len = deref->path_len - 1; -+ return hlsl_new_load_index(ctx, &tmp_deref, NULL, loc); -+} -+ - struct hlsl_ir_load *hlsl_new_var_load(struct hlsl_ctx *ctx, struct hlsl_ir_var *var, - const struct vkd3d_shader_location *loc) - { -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h -index 6b79c582f55..14037a4a96f 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h -@@ -1129,6 +1129,8 @@ struct hlsl_ir_load *hlsl_new_var_load(struct hlsl_ctx *ctx, struct hlsl_ir_var - const struct vkd3d_shader_location *loc); - struct hlsl_ir_load *hlsl_new_load_index(struct hlsl_ctx *ctx, const struct hlsl_deref *deref, - struct hlsl_ir_node *idx, const struct vkd3d_shader_location *loc); -+struct hlsl_ir_load *hlsl_new_load_parent(struct hlsl_ctx *ctx, const struct hlsl_deref *deref, -+ const struct vkd3d_shader_location *loc); - struct hlsl_ir_node *hlsl_new_load_component(struct hlsl_ctx *ctx, struct hlsl_block *block, - const struct hlsl_deref *deref, unsigned int comp, const struct vkd3d_shader_location *loc); - -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -index 2b6c595a15d..72ab27d3b80 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -@@ -123,15 +123,14 @@ static struct hlsl_ir_node *new_offset_instr_from_deref(struct hlsl_ctx *ctx, st - } - - /* TODO: remove when no longer needed, only used for transform_deref_paths_into_offsets() */ --static void replace_deref_path_with_offset(struct hlsl_ctx *ctx, struct hlsl_deref *deref, -+static bool replace_deref_path_with_offset(struct hlsl_ctx *ctx, struct hlsl_deref *deref, - struct hlsl_ir_node *instr) - { - const struct hlsl_type *type; - struct hlsl_ir_node *offset; - struct hlsl_block block; - -- if (!deref->var) -- return; -+ assert(deref->var); - - /* register offsets shouldn't be used before this point is reached. */ - assert(!deref->offset.node); -@@ -143,45 +142,19 @@ static void replace_deref_path_with_offset(struct hlsl_ctx *ctx, struct hlsl_der - if (type->class == HLSL_CLASS_STRUCT || type->class == HLSL_CLASS_ARRAY) - { - hlsl_cleanup_deref(deref); -- return; -+ return true; - } - - deref->offset_regset = hlsl_type_get_regset(type); - - if (!(offset = new_offset_instr_from_deref(ctx, &block, deref, &instr->loc))) -- return; -+ return false; - list_move_before(&instr->entry, &block.instrs); - - hlsl_cleanup_deref(deref); - hlsl_src_from_node(&deref->offset, offset); --} - --/* TODO: remove when no longer needed. */ --static bool transform_deref_paths_into_offsets(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) --{ -- switch(instr->type) -- { -- case HLSL_IR_LOAD: -- replace_deref_path_with_offset(ctx, &hlsl_ir_load(instr)->src, instr); -- return true; -- -- case HLSL_IR_STORE: -- replace_deref_path_with_offset(ctx, &hlsl_ir_store(instr)->lhs, instr); -- return true; -- -- case HLSL_IR_RESOURCE_LOAD: -- replace_deref_path_with_offset(ctx, &hlsl_ir_resource_load(instr)->resource, instr); -- replace_deref_path_with_offset(ctx, &hlsl_ir_resource_load(instr)->sampler, instr); -- return true; -- -- case HLSL_IR_RESOURCE_STORE: -- replace_deref_path_with_offset(ctx, &hlsl_ir_resource_store(instr)->resource, instr); -- return true; -- -- default: -- return false; -- } -- return false; -+ return true; - } - - /* Split uniforms into two variables representing the constant and temp -@@ -600,6 +573,44 @@ bool hlsl_transform_ir(struct hlsl_ctx *ctx, bool (*func)(struct hlsl_ctx *ctx, - return progress; - } - -+static bool transform_instr_derefs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) -+{ -+ bool res; -+ bool (*func)(struct hlsl_ctx *ctx, struct hlsl_deref *, struct hlsl_ir_node *) = context; -+ -+ switch(instr->type) -+ { -+ case HLSL_IR_LOAD: -+ res = func(ctx, &hlsl_ir_load(instr)->src, instr); -+ return res; -+ -+ case HLSL_IR_STORE: -+ res = func(ctx, &hlsl_ir_store(instr)->lhs, instr); -+ return res; -+ -+ case HLSL_IR_RESOURCE_LOAD: -+ res = func(ctx, &hlsl_ir_resource_load(instr)->resource, instr); -+ if (hlsl_ir_resource_load(instr)->sampler.var) -+ res |= func(ctx, &hlsl_ir_resource_load(instr)->sampler, instr); -+ return res; -+ -+ case HLSL_IR_RESOURCE_STORE: -+ res = func(ctx, &hlsl_ir_resource_store(instr)->resource, instr); -+ return res; -+ -+ default: -+ return false; -+ } -+ return false; -+} -+ -+static bool transform_derefs(struct hlsl_ctx *ctx, -+ bool (*func)(struct hlsl_ctx *ctx, struct hlsl_deref *, struct hlsl_ir_node *), -+ struct hlsl_block *block) -+{ -+ return hlsl_transform_ir(ctx, transform_instr_derefs, block, func); -+} -+ - struct recursive_call_ctx - { - const struct hlsl_ir_function_decl **backtrace; -@@ -1981,6 +1992,81 @@ static bool remove_trivial_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *i - return true; - } - -+static bool lower_nonconstant_vector_derefs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) -+{ -+ struct hlsl_ir_node *idx; -+ struct hlsl_deref *deref; -+ struct hlsl_type *type; -+ unsigned int i; -+ -+ if (instr->type != HLSL_IR_LOAD) -+ return false; -+ -+ deref = &hlsl_ir_load(instr)->src; -+ assert(deref->var); -+ -+ if (deref->path_len == 0) -+ return false; -+ -+ type = deref->var->data_type; -+ for (i = 0; i < deref->path_len - 1; ++i) -+ type = hlsl_get_element_type_from_path_index(ctx, type, deref->path[i].node); -+ -+ idx = deref->path[deref->path_len - 1].node; -+ -+ if (type->class == HLSL_CLASS_VECTOR && idx->type != HLSL_IR_CONSTANT) -+ { -+ struct hlsl_ir_node *eq, *swizzle, *dot, *operands[HLSL_MAX_OPERANDS] = {0}; -+ struct hlsl_ir_load *vector_load; -+ struct hlsl_ir_constant *c; -+ enum hlsl_ir_expr_op op; -+ -+ if (!(vector_load = hlsl_new_load_parent(ctx, deref, &instr->loc))) -+ return false; -+ list_add_before(&instr->entry, &vector_load->node.entry); -+ -+ if (!(swizzle = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(X, X, X, X), type->dimx, idx, &instr->loc))) -+ return false; -+ list_add_before(&instr->entry, &swizzle->entry); -+ -+ if (!(c = hlsl_new_constant(ctx, hlsl_get_vector_type(ctx, HLSL_TYPE_UINT, type->dimx), &instr->loc))) -+ return false; -+ c->value.u[0].u = 0; -+ c->value.u[1].u = 1; -+ c->value.u[2].u = 2; -+ c->value.u[3].u = 3; -+ list_add_before(&instr->entry, &c->node.entry); -+ -+ operands[0] = swizzle; -+ operands[1] = &c->node; -+ if (!(eq = hlsl_new_expr(ctx, HLSL_OP2_EQUAL, operands, -+ hlsl_get_vector_type(ctx, HLSL_TYPE_BOOL, type->dimx), &instr->loc))) -+ return false; -+ list_add_before(&instr->entry, &eq->entry); -+ -+ if (!(eq = hlsl_new_cast(ctx, eq, type, &instr->loc))) -+ return false; -+ list_add_before(&instr->entry, &eq->entry); -+ -+ op = HLSL_OP2_DOT; -+ if (type->dimx == 1) -+ op = type->base_type == HLSL_TYPE_BOOL ? HLSL_OP2_LOGIC_AND : HLSL_OP2_MUL; -+ -+ /* Note: We may be creating a DOT for bool vectors here, which we need to lower to -+ * LOGIC_OR + LOGIC_AND. */ -+ operands[0] = &vector_load->node; -+ operands[1] = eq; -+ if (!(dot = hlsl_new_expr(ctx, op, operands, instr->data_type, &instr->loc))) -+ return false; -+ list_add_before(&instr->entry, &dot->entry); -+ hlsl_replace_node(instr, dot); -+ -+ return true; -+ } -+ -+ return false; -+} -+ - /* Lower DIV to RCP + MUL. */ - static bool lower_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) - { -@@ -2378,6 +2464,58 @@ static bool lower_int_abs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void - return true; - } - -+static bool lower_int_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) -+{ -+ struct hlsl_ir_node *arg1, *arg2, *mult, *comps[4] = {0}, *res; -+ struct hlsl_type *type = instr->data_type; -+ struct hlsl_ir_expr *expr; -+ unsigned int i, dimx; -+ bool is_bool; -+ -+ if (instr->type != HLSL_IR_EXPR) -+ return false; -+ expr = hlsl_ir_expr(instr); -+ -+ if (expr->op != HLSL_OP2_DOT) -+ return false; -+ -+ if (type->base_type == HLSL_TYPE_INT || type->base_type == HLSL_TYPE_UINT -+ || type->base_type == HLSL_TYPE_BOOL) -+ { -+ arg1 = expr->operands[0].node; -+ arg2 = expr->operands[1].node; -+ assert(arg1->data_type->dimx == arg2->data_type->dimx); -+ dimx = arg1->data_type->dimx; -+ is_bool = type->base_type == HLSL_TYPE_BOOL; -+ -+ if (!(mult = hlsl_new_binary_expr(ctx, is_bool ? HLSL_OP2_LOGIC_AND : HLSL_OP2_MUL, arg1, arg2))) -+ return false; -+ list_add_before(&instr->entry, &mult->entry); -+ -+ for (i = 0; i < dimx; ++i) -+ { -+ unsigned int s = hlsl_swizzle_from_writemask(1 << i); -+ -+ if (!(comps[i] = hlsl_new_swizzle(ctx, s, 1, mult, &instr->loc))) -+ return false; -+ list_add_before(&instr->entry, &comps[i]->entry); -+ } -+ -+ res = comps[0]; -+ for (i = 1; i < dimx; ++i) -+ { -+ if (!(res = hlsl_new_binary_expr(ctx, is_bool ? HLSL_OP2_LOGIC_OR : HLSL_OP2_ADD, res, comps[i]))) -+ return false; -+ list_add_before(&instr->entry, &res->entry); -+ } -+ -+ hlsl_replace_node(instr, res); -+ return true; -+ } -+ -+ return false; -+} -+ - static bool lower_float_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) - { - struct hlsl_ir_node *arg1, *arg2, *mul1, *neg1, *ge, *neg2, *div, *mul2, *frc, *cond; -@@ -3925,6 +4063,7 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry - - hlsl_transform_ir(ctx, lower_narrowing_casts, body, NULL); - hlsl_transform_ir(ctx, lower_casts_to_bool, body, NULL); -+ hlsl_transform_ir(ctx, lower_int_dot, body, NULL); - hlsl_transform_ir(ctx, lower_int_division, body, NULL); - hlsl_transform_ir(ctx, lower_int_modulus, body, NULL); - hlsl_transform_ir(ctx, lower_int_abs, body, NULL); -@@ -3939,6 +4078,10 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry - } - while (progress); - -+ hlsl_transform_ir(ctx, lower_nonconstant_vector_derefs, body, NULL); -+ hlsl_transform_ir(ctx, lower_casts_to_bool, body, NULL); -+ hlsl_transform_ir(ctx, lower_int_dot, body, NULL); -+ - if (profile->major_version < 4) - { - hlsl_transform_ir(ctx, lower_division, body, NULL); -@@ -3956,7 +4099,7 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry - hlsl_transform_ir(ctx, track_object_components_usage, body, NULL); - - /* TODO: move forward, remove when no longer needed */ -- hlsl_transform_ir(ctx, transform_deref_paths_into_offsets, body, NULL); -+ transform_derefs(ctx, replace_deref_path_with_offset, body); - while (hlsl_transform_ir(ctx, hlsl_fold_constant_exprs, body, NULL)); - - do --- -2.40.1 -