wine-staging/patches/vkd3d-latest/0006-Updated-vkd3d-to-164608a007db3e682fe34b46e9acee49216.patch
2024-03-22 17:43:13 +11:00

1579 lines
68 KiB
Diff

From 90c1abd17c4f00af62b9eda122caaf6d2cd5365e Mon Sep 17 00:00:00 2001
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
Date: Tue, 19 Mar 2024 12:20:44 +1100
Subject: [PATCH] Updated vkd3d to 164608a007db3e682fe34b46e9acee4921677a73.
---
libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 219 +++++++--------
libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 8 +-
libs/vkd3d/libs/vkd3d-shader/dxil.c | 121 ++++++++-
libs/vkd3d/libs/vkd3d-shader/fx.c | 199 ++++++++++++--
libs/vkd3d/libs/vkd3d-shader/glsl.c | 9 +
libs/vkd3d/libs/vkd3d-shader/hlsl.h | 2 +
libs/vkd3d/libs/vkd3d-shader/ir.c | 356 ++++++++++++++++---------
libs/vkd3d/libs/vkd3d-shader/spirv.c | 2 +-
8 files changed, 655 insertions(+), 261 deletions(-)
diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c
index fcbb321edd1..0623a129eae 100644
--- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c
+++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c
@@ -514,79 +514,88 @@ static void shader_dump_uav_flags(struct vkd3d_d3d_asm_compiler *compiler, uint3
vkd3d_string_buffer_printf(&compiler->buffer, "_unknown_flags(%#x)", uav_flags);
}
-static void shader_dump_tessellator_domain(struct vkd3d_d3d_asm_compiler *compiler,
- enum vkd3d_tessellator_domain domain)
+static void shader_print_tessellator_domain(struct vkd3d_d3d_asm_compiler *compiler,
+ const char *prefix, enum vkd3d_tessellator_domain d, const char *suffix)
{
struct vkd3d_string_buffer *buffer = &compiler->buffer;
+ const char *domain;
- shader_addline(buffer, "domain_");
- switch (domain)
+ switch (d)
{
case VKD3D_TESSELLATOR_DOMAIN_LINE:
- shader_addline(buffer, "isoline");
+ domain = "domain_isoline";
break;
case VKD3D_TESSELLATOR_DOMAIN_TRIANGLE:
- shader_addline(buffer, "tri");
+ domain = "domain_tri";
break;
case VKD3D_TESSELLATOR_DOMAIN_QUAD:
- shader_addline(buffer, "quad");
+ domain = "domain_quad";
break;
default:
- shader_addline(buffer, "unknown_tessellator_domain(%#x)", domain);
- break;
+ vkd3d_string_buffer_printf(buffer, "%s%s<unhandled tessellator domain %#x>%s%s",
+ prefix, compiler->colours.error, d, compiler->colours.reset, suffix);
+ return;
}
+
+ vkd3d_string_buffer_printf(buffer, "%s%s%s", prefix, domain, suffix);
}
-static void shader_dump_tessellator_output_primitive(struct vkd3d_d3d_asm_compiler *compiler,
- enum vkd3d_shader_tessellator_output_primitive output_primitive)
+static void shader_print_tessellator_output_primitive(struct vkd3d_d3d_asm_compiler *compiler,
+ const char *prefix, enum vkd3d_shader_tessellator_output_primitive p, const char *suffix)
{
struct vkd3d_string_buffer *buffer = &compiler->buffer;
+ const char *primitive;
- shader_addline(buffer, "output_");
- switch (output_primitive)
+ switch (p)
{
case VKD3D_SHADER_TESSELLATOR_OUTPUT_POINT:
- shader_addline(buffer, "point");
+ primitive = "output_point";
break;
case VKD3D_SHADER_TESSELLATOR_OUTPUT_LINE:
- shader_addline(buffer, "line");
+ primitive = "output_line";
break;
case VKD3D_SHADER_TESSELLATOR_OUTPUT_TRIANGLE_CW:
- shader_addline(buffer, "triangle_cw");
+ primitive = "output_triangle_cw";
break;
case VKD3D_SHADER_TESSELLATOR_OUTPUT_TRIANGLE_CCW:
- shader_addline(buffer, "triangle_ccw");
+ primitive = "output_triangle_ccw";
break;
default:
- shader_addline(buffer, "unknown_tessellator_output_primitive(%#x)", output_primitive);
- break;
+ vkd3d_string_buffer_printf(buffer, "%s%s<unhandled tessellator output primitive %#x>%s%s",
+ prefix, compiler->colours.error, p, compiler->colours.reset, suffix);
+ return;
}
+
+ vkd3d_string_buffer_printf(buffer, "%s%s%s", prefix, primitive, suffix);
}
-static void shader_dump_tessellator_partitioning(struct vkd3d_d3d_asm_compiler *compiler,
- enum vkd3d_shader_tessellator_partitioning partitioning)
+static void shader_print_tessellator_partitioning(struct vkd3d_d3d_asm_compiler *compiler,
+ const char *prefix, enum vkd3d_shader_tessellator_partitioning p, const char *suffix)
{
struct vkd3d_string_buffer *buffer = &compiler->buffer;
+ const char *partitioning;
- shader_addline(buffer, "partitioning_");
- switch (partitioning)
+ switch (p)
{
case VKD3D_SHADER_TESSELLATOR_PARTITIONING_INTEGER:
- shader_addline(buffer, "integer");
+ partitioning = "partitioning_integer";
break;
case VKD3D_SHADER_TESSELLATOR_PARTITIONING_POW2:
- shader_addline(buffer, "pow2");
+ partitioning = "partitioning_pow2";
break;
case VKD3D_SHADER_TESSELLATOR_PARTITIONING_FRACTIONAL_ODD:
- shader_addline(buffer, "fractional_odd");
+ partitioning = "partitioning_fractional_odd";
break;
case VKD3D_SHADER_TESSELLATOR_PARTITIONING_FRACTIONAL_EVEN:
- shader_addline(buffer, "fractional_even");
+ partitioning = "partitioning_fractional_even";
break;
default:
- shader_addline(buffer, "unknown_tessellator_partitioning(%#x)", partitioning);
- break;
+ vkd3d_string_buffer_printf(buffer, "%s%s<unhandled tessellator partitioning %#x>%s%s",
+ prefix, compiler->colours.error, p, compiler->colours.reset, suffix);
+ return;
}
+
+ vkd3d_string_buffer_printf(buffer, "%s%s%s", prefix, partitioning, suffix);
}
static void shader_dump_shader_input_sysval_semantic(struct vkd3d_d3d_asm_compiler *compiler,
@@ -798,8 +807,8 @@ static void shader_dump_decl_usage(struct vkd3d_d3d_asm_compiler *compiler,
}
}
-static void shader_dump_src_param(struct vkd3d_d3d_asm_compiler *compiler,
- const struct vkd3d_shader_src_param *param);
+static void shader_print_src_param(struct vkd3d_d3d_asm_compiler *compiler,
+ const char *prefix, const struct vkd3d_shader_src_param *param, const char *suffix);
static void shader_print_float_literal(struct vkd3d_d3d_asm_compiler *compiler,
const char *prefix, float f, const char *suffix)
@@ -896,13 +905,9 @@ static void shader_print_untyped_literal(struct vkd3d_d3d_asm_compiler *compiler
static void shader_print_subscript(struct vkd3d_d3d_asm_compiler *compiler,
unsigned int offset, const struct vkd3d_shader_src_param *rel_addr)
{
- vkd3d_string_buffer_printf(&compiler->buffer, "[");
if (rel_addr)
- {
- shader_dump_src_param(compiler, rel_addr);
- vkd3d_string_buffer_printf(&compiler->buffer, " + ");
- }
- shader_print_uint_literal(compiler, "", offset, "]");
+ shader_print_src_param(compiler, "[", rel_addr, " + ");
+ shader_print_uint_literal(compiler, rel_addr ? "" : "[", offset, "]");
}
static void shader_print_subscript_range(struct vkd3d_d3d_asm_compiler *compiler,
@@ -1378,6 +1383,9 @@ static void shader_dump_reg_type(struct vkd3d_d3d_asm_compiler *compiler,
if (!(compiler->flags & VSIR_ASM_FLAG_DUMP_TYPES))
return;
+ if (reg->data_type == VKD3D_DATA_UNUSED)
+ return;
+
if (reg->dimension < ARRAY_SIZE(dimensions))
dimension = dimensions[reg->dimension];
else
@@ -1414,11 +1422,12 @@ static void shader_print_write_mask(struct vkd3d_d3d_asm_compiler *compiler,
compiler->colours.write_mask, buffer, compiler->colours.reset, suffix);
}
-static void shader_dump_dst_param(struct vkd3d_d3d_asm_compiler *compiler,
- const struct vkd3d_shader_dst_param *param, bool is_declaration)
+static void shader_print_dst_param(struct vkd3d_d3d_asm_compiler *compiler,
+ const char *prefix, const struct vkd3d_shader_dst_param *param, bool is_declaration, const char *suffix)
{
uint32_t write_mask = param->write_mask;
+ vkd3d_string_buffer_printf(&compiler->buffer, "%s", prefix);
shader_dump_register(compiler, &param->reg, is_declaration);
if (write_mask && param->reg.dimension == VSIR_DIMENSION_VEC4)
@@ -1432,48 +1441,65 @@ static void shader_dump_dst_param(struct vkd3d_d3d_asm_compiler *compiler,
shader_print_precision(compiler, &param->reg);
shader_print_non_uniform(compiler, &param->reg);
shader_dump_reg_type(compiler, &param->reg);
+ vkd3d_string_buffer_printf(&compiler->buffer, "%s", suffix);
}
-static void shader_dump_src_param(struct vkd3d_d3d_asm_compiler *compiler,
- const struct vkd3d_shader_src_param *param)
+static void shader_print_src_param(struct vkd3d_d3d_asm_compiler *compiler,
+ const char *prefix, const struct vkd3d_shader_src_param *param, const char *suffix)
{
enum vkd3d_shader_src_modifier src_modifier = param->modifiers;
struct vkd3d_string_buffer *buffer = &compiler->buffer;
uint32_t swizzle = param->swizzle;
+ const char *modifier = "";
if (src_modifier == VKD3DSPSM_NEG
|| src_modifier == VKD3DSPSM_BIASNEG
|| src_modifier == VKD3DSPSM_SIGNNEG
|| src_modifier == VKD3DSPSM_X2NEG
|| src_modifier == VKD3DSPSM_ABSNEG)
- shader_addline(buffer, "-");
+ modifier = "-";
else if (src_modifier == VKD3DSPSM_COMP)
- shader_addline(buffer, "1-");
+ modifier = "1-";
else if (src_modifier == VKD3DSPSM_NOT)
- shader_addline(buffer, "!");
+ modifier = "!";
+ vkd3d_string_buffer_printf(buffer, "%s%s", prefix, modifier);
if (src_modifier == VKD3DSPSM_ABS || src_modifier == VKD3DSPSM_ABSNEG)
- shader_addline(buffer, "|");
+ vkd3d_string_buffer_printf(buffer, "|");
shader_dump_register(compiler, &param->reg, false);
switch (src_modifier)
{
- case VKD3DSPSM_NONE: break;
- case VKD3DSPSM_NEG: break;
- case VKD3DSPSM_NOT: break;
- case VKD3DSPSM_BIAS: shader_addline(buffer, "_bias"); break;
- case VKD3DSPSM_BIASNEG: shader_addline(buffer, "_bias"); break;
- case VKD3DSPSM_SIGN: shader_addline(buffer, "_bx2"); break;
- case VKD3DSPSM_SIGNNEG: shader_addline(buffer, "_bx2"); break;
- case VKD3DSPSM_COMP: break;
- case VKD3DSPSM_X2: shader_addline(buffer, "_x2"); break;
- case VKD3DSPSM_X2NEG: shader_addline(buffer, "_x2"); break;
- case VKD3DSPSM_DZ: shader_addline(buffer, "_dz"); break;
- case VKD3DSPSM_DW: shader_addline(buffer, "_dw"); break;
+ case VKD3DSPSM_NONE:
+ case VKD3DSPSM_NEG:
+ case VKD3DSPSM_COMP:
+ case VKD3DSPSM_ABS:
case VKD3DSPSM_ABSNEG:
- case VKD3DSPSM_ABS: /* handled later */ break;
- default: shader_addline(buffer, "_unknown_modifier(%#x)", src_modifier);
+ case VKD3DSPSM_NOT:
+ break;
+ case VKD3DSPSM_BIAS:
+ case VKD3DSPSM_BIASNEG:
+ vkd3d_string_buffer_printf(buffer, "_bias");
+ break;
+ case VKD3DSPSM_SIGN:
+ case VKD3DSPSM_SIGNNEG:
+ vkd3d_string_buffer_printf(buffer, "_bx2");
+ break;
+ case VKD3DSPSM_X2:
+ case VKD3DSPSM_X2NEG:
+ vkd3d_string_buffer_printf(buffer, "_x2");
+ break;
+ case VKD3DSPSM_DZ:
+ vkd3d_string_buffer_printf(buffer, "_dz");
+ break;
+ case VKD3DSPSM_DW:
+ vkd3d_string_buffer_printf(buffer, "_dw");
+ break;
+ default:
+ vkd3d_string_buffer_printf(buffer, "_%s<unhandled modifier %#x>%s",
+ compiler->colours.error, src_modifier, compiler->colours.reset);
+ break;
}
if (param->reg.type != VKD3DSPR_IMMCONST && param->reg.type != VKD3DSPR_IMMCONST64
@@ -1491,26 +1517,22 @@ static void shader_dump_src_param(struct vkd3d_d3d_asm_compiler *compiler,
swizzle_z = vsir_swizzle_get_component(swizzle, 2);
swizzle_w = vsir_swizzle_get_component(swizzle, 3);
- if (swizzle_x == swizzle_y
- && swizzle_x == swizzle_z
- && swizzle_x == swizzle_w)
- {
- shader_addline(buffer, ".%s%c%s", compiler->colours.swizzle,
+ if (swizzle_x == swizzle_y && swizzle_x == swizzle_z && swizzle_x == swizzle_w)
+ vkd3d_string_buffer_printf(buffer, ".%s%c%s", compiler->colours.swizzle,
swizzle_chars[swizzle_x], compiler->colours.reset);
- }
else
- {
- shader_addline(buffer, ".%s%c%c%c%c%s", compiler->colours.swizzle,
+ vkd3d_string_buffer_printf(buffer, ".%s%c%c%c%c%s", compiler->colours.swizzle,
swizzle_chars[swizzle_x], swizzle_chars[swizzle_y],
swizzle_chars[swizzle_z], swizzle_chars[swizzle_w], compiler->colours.reset);
- }
}
+
if (src_modifier == VKD3DSPSM_ABS || src_modifier == VKD3DSPSM_ABSNEG)
- shader_addline(buffer, "|");
+ vkd3d_string_buffer_printf(buffer, "|");
shader_print_precision(compiler, &param->reg);
shader_print_non_uniform(compiler, &param->reg);
shader_dump_reg_type(compiler, &param->reg);
+ vkd3d_string_buffer_printf(buffer, "%s", suffix);
}
static void shader_dump_ins_modifiers(struct vkd3d_d3d_asm_compiler *compiler,
@@ -1784,11 +1806,7 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler,
compiler->current = ins;
if (ins->predicate)
- {
- vkd3d_string_buffer_printf(buffer, "(");
- shader_dump_src_param(compiler, ins->predicate);
- vkd3d_string_buffer_printf(buffer, ") ");
- }
+ shader_print_src_param(compiler, "(", ins->predicate, ") ");
/* PixWin marks instructions with the coissue flag with a '+' */
if (ins->coissue)
@@ -1842,8 +1860,7 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler,
break;
case VKD3DSIH_DCL_INDEX_RANGE:
- vkd3d_string_buffer_printf(buffer, " ");
- shader_dump_dst_param(compiler, &ins->declaration.index_range.dst, true);
+ shader_print_dst_param(compiler, " ", &ins->declaration.index_range.dst, true, "");
shader_print_uint_literal(compiler, " ", ins->declaration.index_range.register_count, "");
break;
@@ -1861,16 +1878,14 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler,
case VKD3DSIH_DCL_INPUT_PS:
vkd3d_string_buffer_printf(buffer, " ");
shader_dump_interpolation_mode(compiler, ins->flags);
- shader_addline(buffer, " ");
- shader_dump_dst_param(compiler, &ins->declaration.dst, true);
+ shader_print_dst_param(compiler, " ", &ins->declaration.dst, true, "");
break;
case VKD3DSIH_DCL_INPUT_PS_SGV:
case VKD3DSIH_DCL_INPUT_SGV:
case VKD3DSIH_DCL_INPUT_SIV:
case VKD3DSIH_DCL_OUTPUT_SIV:
- vkd3d_string_buffer_printf(buffer, " ");
- shader_dump_dst_param(compiler, &ins->declaration.register_semantic.reg, true);
+ shader_print_dst_param(compiler, " ", &ins->declaration.register_semantic.reg, true, "");
shader_addline(buffer, ", ");
shader_dump_shader_input_sysval_semantic(compiler, ins->declaration.register_semantic.sysval_semantic);
break;
@@ -1878,16 +1893,14 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler,
case VKD3DSIH_DCL_INPUT_PS_SIV:
vkd3d_string_buffer_printf(buffer, " ");
shader_dump_interpolation_mode(compiler, ins->flags);
- shader_addline(buffer, " ");
- shader_dump_dst_param(compiler, &ins->declaration.register_semantic.reg, true);
+ shader_print_dst_param(compiler, " ", &ins->declaration.register_semantic.reg, true, "");
shader_addline(buffer, ", ");
shader_dump_shader_input_sysval_semantic(compiler, ins->declaration.register_semantic.sysval_semantic);
break;
case VKD3DSIH_DCL_INPUT:
case VKD3DSIH_DCL_OUTPUT:
- vkd3d_string_buffer_printf(buffer, " ");
- shader_dump_dst_param(compiler, &ins->declaration.dst, true);
+ shader_print_dst_param(compiler, " ", &ins->declaration.dst, true, "");
break;
case VKD3DSIH_DCL_INPUT_PRIMITIVE:
@@ -1904,14 +1917,12 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler,
break;
case VKD3DSIH_DCL_RESOURCE_RAW:
- vkd3d_string_buffer_printf(buffer, " ");
- shader_dump_dst_param(compiler, &ins->declaration.raw_resource.resource.reg, true);
+ shader_print_dst_param(compiler, " ", &ins->declaration.raw_resource.resource.reg, true, "");
shader_dump_register_space(compiler, ins->declaration.raw_resource.resource.range.space);
break;
case VKD3DSIH_DCL_RESOURCE_STRUCTURED:
- vkd3d_string_buffer_printf(buffer, " ");
- shader_dump_dst_param(compiler, &ins->declaration.structured_resource.resource.reg, true);
+ shader_print_dst_param(compiler, " ", &ins->declaration.structured_resource.resource.reg, true, "");
shader_print_uint_literal(compiler, ", ", ins->declaration.structured_resource.byte_stride, "");
shader_dump_register_space(compiler, ins->declaration.structured_resource.resource.range.space);
break;
@@ -1935,29 +1946,24 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler,
break;
case VKD3DSIH_DCL_TESSELLATOR_DOMAIN:
- vkd3d_string_buffer_printf(buffer, " ");
- shader_dump_tessellator_domain(compiler, ins->declaration.tessellator_domain);
+ shader_print_tessellator_domain(compiler, " ", ins->declaration.tessellator_domain, "");
break;
case VKD3DSIH_DCL_TESSELLATOR_OUTPUT_PRIMITIVE:
- vkd3d_string_buffer_printf(buffer, " ");
- shader_dump_tessellator_output_primitive(compiler, ins->declaration.tessellator_output_primitive);
+ shader_print_tessellator_output_primitive(compiler, " ", ins->declaration.tessellator_output_primitive, "");
break;
case VKD3DSIH_DCL_TESSELLATOR_PARTITIONING:
- vkd3d_string_buffer_printf(buffer, " ");
- shader_dump_tessellator_partitioning(compiler, ins->declaration.tessellator_partitioning);
+ shader_print_tessellator_partitioning(compiler, " ", ins->declaration.tessellator_partitioning, "");
break;
case VKD3DSIH_DCL_TGSM_RAW:
- vkd3d_string_buffer_printf(buffer, " ");
- shader_dump_dst_param(compiler, &ins->declaration.tgsm_raw.reg, true);
+ shader_print_dst_param(compiler, " ", &ins->declaration.tgsm_raw.reg, true, "");
shader_print_uint_literal(compiler, ", ", ins->declaration.tgsm_raw.byte_count, "");
break;
case VKD3DSIH_DCL_TGSM_STRUCTURED:
- vkd3d_string_buffer_printf(buffer, " ");
- shader_dump_dst_param(compiler, &ins->declaration.tgsm_structured.reg, true);
+ shader_print_dst_param(compiler, " ", &ins->declaration.tgsm_structured.reg, true, "");
shader_print_uint_literal(compiler, ", ", ins->declaration.tgsm_structured.byte_stride, "");
shader_print_uint_literal(compiler, ", ", ins->declaration.tgsm_structured.structure_count, "");
break;
@@ -1970,15 +1976,13 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler,
case VKD3DSIH_DCL_UAV_RAW:
shader_dump_uav_flags(compiler, ins->flags);
- shader_addline(buffer, " ");
- shader_dump_dst_param(compiler, &ins->declaration.raw_resource.resource.reg, true);
+ shader_print_dst_param(compiler, " ", &ins->declaration.raw_resource.resource.reg, true, "");
shader_dump_register_space(compiler, ins->declaration.raw_resource.resource.range.space);
break;
case VKD3DSIH_DCL_UAV_STRUCTURED:
shader_dump_uav_flags(compiler, ins->flags);
- shader_addline(buffer, " ");
- shader_dump_dst_param(compiler, &ins->declaration.structured_resource.resource.reg, true);
+ shader_print_dst_param(compiler, " ", &ins->declaration.structured_resource.resource.reg, true, "");
shader_print_uint_literal(compiler, ", ", ins->declaration.structured_resource.byte_stride, "");
shader_dump_register_space(compiler, ins->declaration.structured_resource.resource.range.space);
break;
@@ -2040,15 +2044,13 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler,
for (i = 0; i < ins->dst_count; ++i)
{
shader_dump_ins_modifiers(compiler, &ins->dst[i]);
- shader_addline(buffer, !i ? " " : ", ");
- shader_dump_dst_param(compiler, &ins->dst[i], false);
+ shader_print_dst_param(compiler, !i ? " " : ", ", &ins->dst[i], false, "");
}
/* Other source tokens */
for (i = ins->dst_count; i < (ins->dst_count + ins->src_count); ++i)
{
- shader_addline(buffer, !i ? " " : ", ");
- shader_dump_src_param(compiler, &ins->src[i - ins->dst_count]);
+ shader_print_src_param(compiler, !i ? " " : ", ", &ins->src[i - ins->dst_count], "");
}
break;
}
@@ -2321,6 +2323,10 @@ enum vkd3d_result d3d_asm_compile(const struct vsir_program *program,
--indent;
break;
+ case VKD3DSIH_LABEL:
+ indent = 0;
+ break;
+
default:
break;
}
@@ -2339,6 +2345,7 @@ enum vkd3d_result d3d_asm_compile(const struct vsir_program *program,
case VKD3DSIH_IFC:
case VKD3DSIH_LOOP:
case VKD3DSIH_SWITCH:
+ case VKD3DSIH_LABEL:
++indent;
break;
diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
index 9f153a1da04..3b935b07d61 100644
--- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
+++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
@@ -1494,12 +1494,12 @@ static uint32_t sm1_version(enum vkd3d_shader_type type, unsigned int major, uns
return D3DPS_VERSION(major, minor);
}
-static D3DXPARAMETER_CLASS sm1_class(const struct hlsl_type *type)
+D3DXPARAMETER_CLASS hlsl_sm1_class(const struct hlsl_type *type)
{
switch (type->class)
{
case HLSL_CLASS_ARRAY:
- return sm1_class(type->e.array.type);
+ return hlsl_sm1_class(type->e.array.type);
case HLSL_CLASS_MATRIX:
assert(type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK);
if (type->modifiers & HLSL_MODIFIER_COLUMN_MAJOR)
@@ -1520,7 +1520,7 @@ static D3DXPARAMETER_CLASS sm1_class(const struct hlsl_type *type)
}
}
-static D3DXPARAMETER_TYPE sm1_base_type(const struct hlsl_type *type)
+D3DXPARAMETER_TYPE hlsl_sm1_base_type(const struct hlsl_type *type)
{
switch (type->base_type)
{
@@ -1615,7 +1615,7 @@ static void write_sm1_type(struct vkd3d_bytecode_buffer *buffer, struct hlsl_typ
}
}
- type->bytecode_offset = put_u32(buffer, vkd3d_make_u32(sm1_class(type), sm1_base_type(array_type)));
+ type->bytecode_offset = put_u32(buffer, vkd3d_make_u32(hlsl_sm1_class(type), hlsl_sm1_base_type(array_type)));
put_u32(buffer, vkd3d_make_u32(type->dimy, type->dimx));
put_u32(buffer, vkd3d_make_u32(array_size, field_count));
put_u32(buffer, fields_offset);
diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c
index 86671c07d70..7f9a74fa737 100644
--- a/libs/vkd3d/libs/vkd3d-shader/dxil.c
+++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c
@@ -342,6 +342,8 @@ enum dx_intrinsic_opcode
{
DX_LOAD_INPUT = 4,
DX_STORE_OUTPUT = 5,
+ DX_FABS = 6,
+ DX_SATURATE = 7,
DX_ISNAN = 8,
DX_ISINF = 9,
DX_ISFINITE = 10,
@@ -374,6 +376,10 @@ enum dx_intrinsic_opcode
DX_IMIN = 38,
DX_UMAX = 39,
DX_UMIN = 40,
+ DX_FMAD = 46,
+ DX_FMA = 47,
+ DX_IMAD = 48,
+ DX_UMAD = 49,
DX_IBFE = 51,
DX_UBFE = 52,
DX_CREATE_HANDLE = 57,
@@ -388,6 +394,7 @@ enum dx_intrinsic_opcode
DX_TEXTURE_STORE = 67,
DX_BUFFER_LOAD = 68,
DX_BUFFER_STORE = 69,
+ DX_BUFFER_UPDATE_COUNTER = 70,
DX_GET_DIMENSIONS = 72,
DX_TEXTURE_GATHER = 73,
DX_TEXTURE_GATHER_CMP = 74,
@@ -2374,14 +2381,18 @@ static void register_index_address_init(struct vkd3d_shader_register_index *idx,
}
}
-static void instruction_dst_param_init_ssa_scalar(struct vkd3d_shader_instruction *ins, struct sm6_parser *sm6)
+static bool instruction_dst_param_init_ssa_scalar(struct vkd3d_shader_instruction *ins, struct sm6_parser *sm6)
{
- struct vkd3d_shader_dst_param *param = instruction_dst_params_alloc(ins, 1, sm6);
struct sm6_value *dst = sm6_parser_get_current_value(sm6);
+ struct vkd3d_shader_dst_param *param;
+
+ if (!(param = instruction_dst_params_alloc(ins, 1, sm6)))
+ return false;
dst_param_init_ssa_scalar(param, dst->type, dst, sm6);
param->write_mask = VKD3DSP_WRITEMASK_0;
dst->u.reg = param->reg;
+ return true;
}
static void instruction_dst_param_init_ssa_vector(struct vkd3d_shader_instruction *ins,
@@ -4134,6 +4145,43 @@ static void sm6_parser_emit_dx_barrier(struct sm6_parser *sm6, enum dx_intrinsic
}
}
+static void sm6_parser_emit_dx_buffer_update_counter(struct sm6_parser *sm6, enum dx_intrinsic_opcode op,
+ const struct sm6_value **operands, struct function_emission_state *state)
+{
+ struct vkd3d_shader_instruction *ins = state->ins;
+ struct vkd3d_shader_src_param *src_params;
+ const struct sm6_value *resource;
+ unsigned int i;
+ int8_t inc;
+
+ resource = operands[0];
+ if (!sm6_value_validate_is_handle(resource, sm6))
+ return;
+
+ if (!sm6_value_is_constant(operands[1]))
+ {
+ FIXME("Unsupported dynamic update operand.\n");
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
+ "A dynamic update value for a UAV counter operation is not supported.");
+ return;
+ }
+ i = sm6_value_get_constant_uint(operands[1]);
+ if (i != 1 && i != 255)
+ {
+ WARN("Unexpected update value %#x.\n", i);
+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_OPERANDS,
+ "Update value %#x for a UAV counter operation is not supported.", i);
+ }
+ inc = i;
+
+ vsir_instruction_init(ins, &sm6->p.location, (inc < 0) ? VKD3DSIH_IMM_ATOMIC_CONSUME : VKD3DSIH_IMM_ATOMIC_ALLOC);
+ if (!(src_params = instruction_src_params_alloc(ins, 1, sm6)))
+ return;
+ src_param_init_vector_from_reg(&src_params[0], &resource->u.handle.reg);
+
+ instruction_dst_param_init_ssa_scalar(ins, sm6);
+}
+
static void sm6_parser_emit_dx_cbuffer_load(struct sm6_parser *sm6, enum dx_intrinsic_opcode op,
const struct sm6_value **operands, struct function_emission_state *state)
{
@@ -4225,6 +4273,53 @@ static void sm6_parser_emit_dx_create_handle(struct sm6_parser *sm6, enum dx_int
ins->handler_idx = VKD3DSIH_NOP;
}
+static void sm6_parser_emit_dx_fabs(struct sm6_parser *sm6, enum dx_intrinsic_opcode op,
+ const struct sm6_value **operands, struct function_emission_state *state)
+{
+ struct vkd3d_shader_instruction *ins = state->ins;
+ struct vkd3d_shader_src_param *src_param;
+
+ vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV);
+ if (!(src_param = instruction_src_params_alloc(ins, 1, sm6)))
+ return;
+ src_param_init_from_value(src_param, operands[0]);
+ src_param->modifiers = VKD3DSPSM_ABS;
+
+ instruction_dst_param_init_ssa_scalar(ins, sm6);
+}
+
+static enum vkd3d_shader_opcode sm6_dx_map_ma_op(enum dx_intrinsic_opcode op, const struct sm6_type *type)
+{
+ switch (op)
+ {
+ case DX_FMA:
+ return VKD3DSIH_DFMA;
+ case DX_FMAD:
+ return VKD3DSIH_MAD;
+ case DX_IMAD:
+ case DX_UMAD:
+ return VKD3DSIH_IMAD;
+ default:
+ vkd3d_unreachable();
+ }
+}
+
+static void sm6_parser_emit_dx_ma(struct sm6_parser *sm6, enum dx_intrinsic_opcode op,
+ const struct sm6_value **operands, struct function_emission_state *state)
+{
+ struct vkd3d_shader_instruction *ins = state->ins;
+ struct vkd3d_shader_src_param *src_params;
+ unsigned int i;
+
+ vsir_instruction_init(ins, &sm6->p.location, sm6_dx_map_ma_op(op, operands[0]->type));
+ if (!(src_params = instruction_src_params_alloc(ins, 3, sm6)))
+ return;
+ for (i = 0; i < 3; ++i)
+ src_param_init_from_value(&src_params[i], operands[i]);
+
+ instruction_dst_param_init_ssa_scalar(ins, sm6);
+}
+
static void sm6_parser_emit_dx_get_dimensions(struct sm6_parser *sm6, enum dx_intrinsic_opcode op,
const struct sm6_value **operands, struct function_emission_state *state)
{
@@ -4681,6 +4776,21 @@ static void sm6_parser_emit_dx_sample(struct sm6_parser *sm6, enum dx_intrinsic_
instruction_dst_param_init_ssa_vector(ins, component_count, sm6);
}
+static void sm6_parser_emit_dx_saturate(struct sm6_parser *sm6, enum dx_intrinsic_opcode op,
+ const struct sm6_value **operands, struct function_emission_state *state)
+{
+ struct vkd3d_shader_instruction *ins = state->ins;
+ struct vkd3d_shader_src_param *src_param;
+
+ vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV);
+ if (!(src_param = instruction_src_params_alloc(ins, 1, sm6)))
+ return;
+ src_param_init_from_value(src_param, operands[0]);
+
+ if (instruction_dst_param_init_ssa_scalar(ins, sm6))
+ ins->dst->modifiers = VKD3DSPDM_SATURATE;
+}
+
static void sm6_parser_emit_dx_sincos(struct sm6_parser *sm6, enum dx_intrinsic_opcode op,
const struct sm6_value **operands, struct function_emission_state *state)
{
@@ -4967,6 +5077,7 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] =
[DX_BFREV ] = {"m", "R", sm6_parser_emit_dx_unary},
[DX_BUFFER_LOAD ] = {"o", "Hii", sm6_parser_emit_dx_buffer_load},
[DX_BUFFER_STORE ] = {"v", "Hiiooooc", sm6_parser_emit_dx_buffer_store},
+ [DX_BUFFER_UPDATE_COUNTER ] = {"i", "H8", sm6_parser_emit_dx_buffer_update_counter},
[DX_CBUFFER_LOAD_LEGACY ] = {"o", "Hi", sm6_parser_emit_dx_cbuffer_load},
[DX_COS ] = {"g", "R", sm6_parser_emit_dx_sincos},
[DX_COUNT_BITS ] = {"i", "m", sm6_parser_emit_dx_unary},
@@ -4976,9 +5087,12 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] =
[DX_DERIV_FINEX ] = {"e", "R", sm6_parser_emit_dx_unary},
[DX_DERIV_FINEY ] = {"e", "R", sm6_parser_emit_dx_unary},
[DX_EXP ] = {"g", "R", sm6_parser_emit_dx_unary},
+ [DX_FABS ] = {"g", "R", sm6_parser_emit_dx_fabs},
[DX_FIRST_BIT_HI ] = {"i", "m", sm6_parser_emit_dx_unary},
[DX_FIRST_BIT_LO ] = {"i", "m", sm6_parser_emit_dx_unary},
[DX_FIRST_BIT_SHI ] = {"i", "m", sm6_parser_emit_dx_unary},
+ [DX_FMA ] = {"g", "RRR", sm6_parser_emit_dx_ma},
+ [DX_FMAD ] = {"g", "RRR", sm6_parser_emit_dx_ma},
[DX_FMAX ] = {"g", "RR", sm6_parser_emit_dx_binary},
[DX_FMIN ] = {"g", "RR", sm6_parser_emit_dx_binary},
[DX_FRC ] = {"g", "R", sm6_parser_emit_dx_unary},
@@ -4987,6 +5101,7 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] =
[DX_HCOS ] = {"g", "R", sm6_parser_emit_dx_unary},
[DX_HSIN ] = {"g", "R", sm6_parser_emit_dx_unary},
[DX_HTAN ] = {"g", "R", sm6_parser_emit_dx_unary},
+ [DX_IMAD ] = {"m", "RRR", sm6_parser_emit_dx_ma},
[DX_IMAX ] = {"m", "RR", sm6_parser_emit_dx_binary},
[DX_IMIN ] = {"m", "RR", sm6_parser_emit_dx_binary},
[DX_ISFINITE ] = {"1", "g", sm6_parser_emit_dx_unary},
@@ -5009,6 +5124,7 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] =
[DX_SAMPLE_C_LZ ] = {"o", "HHffffiiif", sm6_parser_emit_dx_sample},
[DX_SAMPLE_GRAD ] = {"o", "HHffffiiifffffff", sm6_parser_emit_dx_sample},
[DX_SAMPLE_LOD ] = {"o", "HHffffiiif", sm6_parser_emit_dx_sample},
+ [DX_SATURATE ] = {"g", "R", sm6_parser_emit_dx_saturate},
[DX_SIN ] = {"g", "R", sm6_parser_emit_dx_sincos},
[DX_SPLIT_DOUBLE ] = {"S", "d", sm6_parser_emit_dx_split_double},
[DX_SQRT ] = {"g", "R", sm6_parser_emit_dx_unary},
@@ -5019,6 +5135,7 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] =
[DX_TEXTURE_LOAD ] = {"o", "HiiiiCCC", sm6_parser_emit_dx_texture_load},
[DX_TEXTURE_STORE ] = {"v", "Hiiiooooc", sm6_parser_emit_dx_texture_store},
[DX_UBFE ] = {"m", "iiR", sm6_parser_emit_dx_tertiary},
+ [DX_UMAD ] = {"m", "RRR", sm6_parser_emit_dx_ma},
[DX_UMAX ] = {"m", "RR", sm6_parser_emit_dx_binary},
[DX_UMIN ] = {"m", "RR", sm6_parser_emit_dx_binary},
};
diff --git a/libs/vkd3d/libs/vkd3d-shader/fx.c b/libs/vkd3d/libs/vkd3d-shader/fx.c
index fdf132e9ed4..f2be00da33a 100644
--- a/libs/vkd3d/libs/vkd3d-shader/fx.c
+++ b/libs/vkd3d/libs/vkd3d-shader/fx.c
@@ -61,7 +61,6 @@ struct fx_write_context;
struct fx_write_context_ops
{
uint32_t (*write_string)(const char *string, struct fx_write_context *fx);
- uint32_t (*write_type)(const struct hlsl_type *type, struct fx_write_context *fx);
void (*write_technique)(struct hlsl_ir_var *var, struct fx_write_context *fx);
void (*write_pass)(struct hlsl_ir_var *var, struct fx_write_context *fx);
bool are_child_effects_supported;
@@ -87,6 +86,7 @@ struct fx_write_context
uint32_t object_variable_count;
uint32_t shared_object_count;
uint32_t shader_variable_count;
+ uint32_t parameter_count;
int status;
bool child_effect;
@@ -102,6 +102,11 @@ static void set_status(struct fx_write_context *fx, int status)
fx->status = status;
}
+static bool has_annotations(const struct hlsl_ir_var *var)
+{
+ return var->annotations && !list_empty(&var->annotations->vars);
+}
+
static uint32_t write_string(const char *string, struct fx_write_context *fx)
{
return fx->ops->write_string(string, fx);
@@ -112,12 +117,16 @@ static void write_pass(struct hlsl_ir_var *var, struct fx_write_context *fx)
fx->ops->write_pass(var, fx);
}
+static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_context *fx);
+
static uint32_t write_type(const struct hlsl_type *type, struct fx_write_context *fx)
{
struct type_entry *type_entry;
unsigned int elements_count;
const char *name;
+ assert(fx->ctx->profile->major_version >= 4);
+
if (type->class == HLSL_CLASS_ARRAY)
{
name = hlsl_get_multiarray_element_type(type)->name;
@@ -143,7 +152,7 @@ static uint32_t write_type(const struct hlsl_type *type, struct fx_write_context
if (!(type_entry = hlsl_alloc(fx->ctx, sizeof(*type_entry))))
return 0;
- type_entry->offset = fx->ops->write_type(type, fx);
+ type_entry->offset = write_fx_4_type(type, fx);
type_entry->name = name;
type_entry->elements_count = elements_count;
@@ -156,6 +165,7 @@ static void fx_write_context_init(struct hlsl_ctx *ctx, const struct fx_write_co
struct fx_write_context *fx)
{
unsigned int version = ctx->profile->major_version;
+ struct hlsl_block block;
memset(fx, 0, sizeof(*fx));
@@ -181,6 +191,11 @@ static void fx_write_context_init(struct hlsl_ctx *ctx, const struct fx_write_co
list_init(&fx->types);
fx->child_effect = fx->ops->are_child_effects_supported && ctx->child_effect;
+
+ hlsl_block_init(&block);
+ hlsl_prepend_global_uniform_copy(fx->ctx, &block);
+ hlsl_block_cleanup(&block);
+ hlsl_calculate_buffer_offsets(fx->ctx);
}
static int fx_write_context_cleanup(struct fx_write_context *fx)
@@ -302,7 +317,7 @@ static uint32_t get_fx_4_numeric_type_description(const struct hlsl_type *type,
value |= numeric_type_class[type->class];
break;
default:
- hlsl_fixme(ctx, &ctx->location, "Not implemented for type class %u.\n", type->class);
+ hlsl_fixme(ctx, &ctx->location, "Not implemented for type class %u.", type->class);
return 0;
}
@@ -315,7 +330,7 @@ static uint32_t get_fx_4_numeric_type_description(const struct hlsl_type *type,
value |= (numeric_base_type[type->base_type] << NUMERIC_BASE_TYPE_SHIFT);
break;
default:
- hlsl_fixme(ctx, &ctx->location, "Not implemented for base type %u.\n", type->base_type);
+ hlsl_fixme(ctx, &ctx->location, "Not implemented for base type %u.", type->base_type);
return 0;
}
@@ -416,7 +431,7 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co
put_u32_unaligned(buffer, variable_type[type->class]);
break;
default:
- hlsl_fixme(ctx, &ctx->location, "Writing type class %u is not implemented.\n", type->class);
+ hlsl_fixme(ctx, &ctx->location, "Writing type class %u is not implemented.", type->class);
return 0;
}
@@ -498,7 +513,7 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co
put_u32_unaligned(buffer, uav_type[type->sampler_dim]);
break;
default:
- hlsl_fixme(ctx, &ctx->location, "Object type %u is not supported.\n", type->base_type);
+ hlsl_fixme(ctx, &ctx->location, "Object type %u is not supported.", type->base_type);
return 0;
}
}
@@ -604,6 +619,73 @@ static uint32_t write_fx_2_string(const char *string, struct fx_write_context *f
return offset;
}
+static uint32_t write_fx_2_parameter(const struct hlsl_type *type, const char *name, const struct hlsl_semantic *semantic,
+ struct fx_write_context *fx)
+{
+ struct vkd3d_bytecode_buffer *buffer = &fx->unstructured;
+ uint32_t semantic_offset, offset, elements_count = 0, name_offset;
+ struct hlsl_ctx *ctx = fx->ctx;
+ size_t i;
+
+ /* Resolve arrays to element type and number of elements. */
+ if (type->class == HLSL_CLASS_ARRAY)
+ {
+ elements_count = hlsl_get_multiarray_size(type);
+ type = hlsl_get_multiarray_element_type(type);
+ }
+
+ name_offset = write_string(name, fx);
+ semantic_offset = write_string(semantic->name, fx);
+
+ switch (type->base_type)
+ {
+ case HLSL_TYPE_FLOAT:
+ case HLSL_TYPE_BOOL:
+ case HLSL_TYPE_INT:
+ case HLSL_TYPE_VOID:
+ break;
+ default:
+ hlsl_fixme(ctx, &ctx->location, "Writing parameter type %u is not implemented.",
+ type->base_type);
+ return 0;
+ };
+
+ offset = put_u32(buffer, hlsl_sm1_base_type(type));
+ put_u32(buffer, hlsl_sm1_class(type));
+ put_u32(buffer, name_offset);
+ put_u32(buffer, semantic_offset);
+ put_u32(buffer, elements_count);
+
+ switch (type->class)
+ {
+ case HLSL_CLASS_VECTOR:
+ put_u32(buffer, type->dimx);
+ put_u32(buffer, type->dimy);
+ break;
+ case HLSL_CLASS_SCALAR:
+ case HLSL_CLASS_MATRIX:
+ put_u32(buffer, type->dimy);
+ put_u32(buffer, type->dimx);
+ break;
+ case HLSL_CLASS_STRUCT:
+ put_u32(buffer, type->e.record.field_count);
+ break;
+ default:
+ ;
+ }
+
+ if (type->class == HLSL_CLASS_STRUCT)
+ {
+ for (i = 0; i < type->e.record.field_count; ++i)
+ {
+ const struct hlsl_struct_field *field = &type->e.record.fields[i];
+ write_fx_2_parameter(field->type, field->name, &field->semantic, fx);
+ }
+ }
+
+ return offset;
+}
+
static void write_fx_2_technique(struct hlsl_ir_var *var, struct fx_write_context *fx)
{
struct vkd3d_bytecode_buffer *buffer = &fx->structured;
@@ -626,6 +708,88 @@ static void write_fx_2_technique(struct hlsl_ir_var *var, struct fx_write_contex
set_u32(buffer, count_offset, count);
}
+static uint32_t get_fx_2_type_size(const struct hlsl_type *type)
+{
+ uint32_t size = 0, elements_count;
+ size_t i;
+
+ if (type->class == HLSL_CLASS_ARRAY)
+ {
+ elements_count = hlsl_get_multiarray_size(type);
+ type = hlsl_get_multiarray_element_type(type);
+ return get_fx_2_type_size(type) * elements_count;
+ }
+ else if (type->class == HLSL_CLASS_STRUCT)
+ {
+ for (i = 0; i < type->e.record.field_count; ++i)
+ {
+ const struct hlsl_struct_field *field = &type->e.record.fields[i];
+ size += get_fx_2_type_size(field->type);
+ }
+
+ return size;
+ }
+
+ return type->dimx * type->dimy * sizeof(float);
+}
+
+static uint32_t write_fx_2_initial_value(const struct hlsl_ir_var *var, struct fx_write_context *fx)
+{
+ struct vkd3d_bytecode_buffer *buffer = &fx->unstructured;
+ const struct hlsl_type *type = var->data_type;
+ uint32_t i, offset, size, elements_count = 1;
+
+ size = get_fx_2_type_size(type);
+
+ if (type->class == HLSL_CLASS_ARRAY)
+ {
+ elements_count = hlsl_get_multiarray_size(type);
+ type = hlsl_get_multiarray_element_type(type);
+ }
+
+ if (type->class == HLSL_CLASS_OBJECT)
+ {
+ /* Objects are given sequential ids. */
+ offset = put_u32(buffer, fx->object_variable_count++);
+ for (i = 1; i < elements_count; ++i)
+ put_u32(buffer, fx->object_variable_count++);
+ }
+ else
+ {
+ /* FIXME: write actual initial value */
+ offset = put_u32(buffer, 0);
+
+ for (i = 1; i < size / sizeof(uint32_t); ++i)
+ put_u32(buffer, 0);
+ }
+
+ return offset;
+}
+
+static void write_fx_2_parameters(struct fx_write_context *fx)
+{
+ struct vkd3d_bytecode_buffer *buffer = &fx->structured;
+ uint32_t desc_offset, value_offset;
+ struct hlsl_ctx *ctx = fx->ctx;
+ struct hlsl_ir_var *var;
+
+ LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
+ {
+ desc_offset = write_fx_2_parameter(var->data_type, var->name, &var->semantic, fx);
+ value_offset = write_fx_2_initial_value(var, fx);
+
+ put_u32(buffer, desc_offset); /* Parameter description */
+ put_u32(buffer, value_offset); /* Value */
+ put_u32(buffer, 0); /* Flags */
+
+ put_u32(buffer, 0); /* Annotations count */
+ if (has_annotations(var))
+ hlsl_fixme(ctx, &ctx->location, "Writing annotations for parameters is not implemented.");
+
+ ++fx->parameter_count;
+ }
+}
+
static const struct fx_write_context_ops fx_2_ops =
{
.write_string = write_fx_2_string,
@@ -635,9 +799,9 @@ static const struct fx_write_context_ops fx_2_ops =
static int hlsl_fx_2_write(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out)
{
+ uint32_t offset, size, technique_count, parameter_count;
struct vkd3d_bytecode_buffer buffer = { 0 };
struct vkd3d_bytecode_buffer *structured;
- uint32_t offset, size, technique_count;
struct fx_write_context fx;
fx_write_context_init(ctx, &fx_2_ops, &fx);
@@ -649,12 +813,13 @@ static int hlsl_fx_2_write(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out)
put_u32(&buffer, 0xfeff0901); /* Version. */
offset = put_u32(&buffer, 0);
- put_u32(structured, 0); /* Parameter count */
+ parameter_count = put_u32(structured, 0); /* Parameter count */
technique_count = put_u32(structured, 0);
put_u32(structured, 0); /* Unknown */
put_u32(structured, 0); /* Object count */
- /* TODO: parameters */
+ write_fx_2_parameters(&fx);
+ set_u32(structured, parameter_count, fx.parameter_count);
write_techniques(ctx->globals, &fx);
set_u32(structured, technique_count, fx.technique_count);
@@ -692,7 +857,6 @@ static int hlsl_fx_2_write(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out)
static const struct fx_write_context_ops fx_4_ops =
{
.write_string = write_fx_4_string,
- .write_type = write_fx_4_type,
.write_technique = write_fx_4_technique,
.write_pass = write_fx_4_pass,
.are_child_effects_supported = true,
@@ -707,6 +871,7 @@ static void write_fx_4_numeric_variable(struct hlsl_ir_var *var, struct fx_write
{
HAS_EXPLICIT_BIND_POINT = 0x4,
};
+ struct hlsl_ctx *ctx = fx->ctx;
/* Explicit bind point. */
if (var->reg_reservation.reg_type)
@@ -725,7 +890,8 @@ static void write_fx_4_numeric_variable(struct hlsl_ir_var *var, struct fx_write
put_u32(buffer, flags); /* Flags */
put_u32(buffer, 0); /* Annotations count */
- /* FIXME: write annotations */
+ if (has_annotations(var))
+ hlsl_fixme(ctx, &ctx->location, "Writing annotations for numeric variables is not implemented.");
}
static void write_fx_4_object_variable(struct hlsl_ir_var *var, struct fx_write_context *fx)
@@ -771,12 +937,13 @@ static void write_fx_4_object_variable(struct hlsl_ir_var *var, struct fx_write_
++fx->shader_variable_count;
break;
default:
- hlsl_fixme(ctx, &ctx->location, "Writing initializer for object type %u is not implemented.\n",
+ hlsl_fixme(ctx, &ctx->location, "Writing initializer for object type %u is not implemented.",
type->base_type);
}
put_u32(buffer, 0); /* Annotations count */
- /* FIXME: write annotations */
+ if (has_annotations(var))
+ hlsl_fixme(ctx, &ctx->location, "Writing annotations for object variables is not implemented.");
++fx->object_variable_count;
}
@@ -834,12 +1001,6 @@ static void write_fx_4_buffer(struct hlsl_buffer *b, struct fx_write_context *fx
static void write_buffers(struct fx_write_context *fx)
{
struct hlsl_buffer *buffer;
- struct hlsl_block block;
-
- hlsl_block_init(&block);
- hlsl_prepend_global_uniform_copy(fx->ctx, &block);
- hlsl_block_init(&block);
- hlsl_calculate_buffer_offsets(fx->ctx);
LIST_FOR_EACH_ENTRY(buffer, &fx->ctx->buffers, struct hlsl_buffer, entry)
{
diff --git a/libs/vkd3d/libs/vkd3d-shader/glsl.c b/libs/vkd3d/libs/vkd3d-shader/glsl.c
index 23ea89c47be..3977852a48d 100644
--- a/libs/vkd3d/libs/vkd3d-shader/glsl.c
+++ b/libs/vkd3d/libs/vkd3d-shader/glsl.c
@@ -24,6 +24,7 @@ struct vkd3d_glsl_generator
struct vkd3d_string_buffer buffer;
struct vkd3d_shader_location location;
struct vkd3d_shader_message_context *message_context;
+ unsigned int indent;
bool failed;
};
@@ -39,8 +40,14 @@ static void VKD3D_PRINTF_FUNC(3, 4) vkd3d_glsl_compiler_error(
generator->failed = true;
}
+static void shader_glsl_print_indent(struct vkd3d_string_buffer *buffer, unsigned int indent)
+{
+ vkd3d_string_buffer_printf(buffer, "%*s", 4 * indent, "");
+}
+
static void shader_glsl_unhandled(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins)
{
+ shader_glsl_print_indent(&gen->buffer, gen->indent);
vkd3d_string_buffer_printf(&gen->buffer, "/* <unhandled instruction %#x> */\n", ins->handler_idx);
vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
"Internal compiler error: Unhandled instruction %#x.", ins->handler_idx);
@@ -57,6 +64,7 @@ static void shader_glsl_ret(struct vkd3d_glsl_generator *generator,
*/
if (version->major >= 4)
{
+ shader_glsl_print_indent(&generator->buffer, generator->indent);
vkd3d_string_buffer_printf(&generator->buffer, "return;\n");
}
}
@@ -92,6 +100,7 @@ static int vkd3d_glsl_generator_generate(struct vkd3d_glsl_generator *generator,
vkd3d_string_buffer_printf(&generator->buffer, "#version 440\n\n");
vkd3d_string_buffer_printf(&generator->buffer, "void main()\n{\n");
+ ++generator->indent;
for (i = 0; i < instructions->count; ++i)
{
vkd3d_glsl_handle_instruction(generator, &instructions->elements[i]);
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h
index 5ced5edc766..561782efbf8 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h
@@ -1363,6 +1363,8 @@ bool hlsl_fold_constant_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst
bool hlsl_transform_ir(struct hlsl_ctx *ctx, bool (*func)(struct hlsl_ctx *ctx, struct hlsl_ir_node *, void *),
struct hlsl_block *block, void *context);
+D3DXPARAMETER_CLASS hlsl_sm1_class(const struct hlsl_type *type);
+D3DXPARAMETER_TYPE hlsl_sm1_base_type(const struct hlsl_type *type);
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);
bool hlsl_sm1_usage_from_semantic(const struct hlsl_semantic *semantic, D3DDECLUSAGE *usage, uint32_t *usage_idx);
diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c
index 55d1216460f..ec32faae8da 100644
--- a/libs/vkd3d/libs/vkd3d-shader/ir.c
+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c
@@ -456,7 +456,7 @@ void vsir_dst_param_init(struct vkd3d_shader_dst_param *param, enum vkd3d_shader
void vsir_src_param_init_label(struct vkd3d_shader_src_param *param, unsigned int label_id)
{
- vsir_src_param_init(param, VKD3DSPR_LABEL, VKD3D_DATA_UINT, 1);
+ vsir_src_param_init(param, VKD3DSPR_LABEL, VKD3D_DATA_UNUSED, 1);
param->reg.dimension = VSIR_DIMENSION_NONE;
param->reg.idx[0].offset = label_id;
}
@@ -467,12 +467,24 @@ static void src_param_init_ssa_bool(struct vkd3d_shader_src_param *src, unsigned
src->reg.idx[0].offset = idx;
}
+static void src_param_init_temp_bool(struct vkd3d_shader_src_param *src, unsigned int idx)
+{
+ vsir_src_param_init(src, VKD3DSPR_TEMP, VKD3D_DATA_BOOL, 1);
+ src->reg.idx[0].offset = idx;
+}
+
static void dst_param_init_ssa_bool(struct vkd3d_shader_dst_param *dst, unsigned int idx)
{
vsir_dst_param_init(dst, VKD3DSPR_SSA, VKD3D_DATA_BOOL, 1);
dst->reg.idx[0].offset = idx;
}
+static void dst_param_init_temp_bool(struct vkd3d_shader_dst_param *dst, unsigned int idx)
+{
+ vsir_dst_param_init(dst, VKD3DSPR_TEMP, VKD3D_DATA_BOOL, 1);
+ dst->reg.idx[0].offset = idx;
+}
+
static void dst_param_init_temp_uint(struct vkd3d_shader_dst_param *dst, unsigned int idx)
{
vsir_dst_param_init(dst, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1);
@@ -2913,132 +2925,6 @@ fail:
return VKD3D_ERROR_OUT_OF_MEMORY;
}
-static enum vkd3d_result vsir_program_structurise(struct vsir_program *program)
-{
- const unsigned int block_temp_idx = program->temp_count;
- struct vkd3d_shader_instruction *instructions = NULL;
- const struct vkd3d_shader_location no_loc = {0};
- size_t ins_capacity = 0, ins_count = 0, i;
- bool first_label_found = false;
-
- if (!reserve_instructions(&instructions, &ins_capacity, program->instructions.count))
- goto fail;
-
- for (i = 0; i < program->instructions.count; ++i)
- {
- struct vkd3d_shader_instruction *ins = &program->instructions.elements[i];
-
- switch (ins->handler_idx)
- {
- case VKD3DSIH_PHI:
- case VKD3DSIH_SWITCH_MONOLITHIC:
- vkd3d_unreachable();
-
- case VKD3DSIH_LABEL:
- if (!reserve_instructions(&instructions, &ins_capacity, ins_count + 4))
- goto fail;
-
- if (!first_label_found)
- {
- first_label_found = true;
-
- if (!vsir_instruction_init_with_params(program,
- &instructions[ins_count], &no_loc, VKD3DSIH_MOV, 1, 1))
- goto fail;
- dst_param_init_temp_uint(&instructions[ins_count].dst[0], block_temp_idx);
- src_param_init_const_uint(&instructions[ins_count].src[0], label_from_src_param(&ins->src[0]));
- ins_count++;
-
- if (!vsir_instruction_init_with_params(program,
- &instructions[ins_count], &no_loc, VKD3DSIH_LOOP, 0, 0))
- goto fail;
- ins_count++;
-
- if (!vsir_instruction_init_with_params(program,
- &instructions[ins_count], &no_loc, VKD3DSIH_SWITCH, 0, 1))
- goto fail;
- src_param_init_temp_uint(&instructions[ins_count].src[0], block_temp_idx);
- ins_count++;
- }
-
- if (!vsir_instruction_init_with_params(program,
- &instructions[ins_count], &no_loc, VKD3DSIH_CASE, 0, 1))
- goto fail;
- src_param_init_const_uint(&instructions[ins_count].src[0], label_from_src_param(&ins->src[0]));
- ins_count++;
- break;
-
- case VKD3DSIH_BRANCH:
- if (!reserve_instructions(&instructions, &ins_capacity, ins_count + 2))
- goto fail;
-
- if (vsir_register_is_label(&ins->src[0].reg))
- {
- if (!vsir_instruction_init_with_params(program,
- &instructions[ins_count], &no_loc, VKD3DSIH_MOV, 1, 1))
- goto fail;
- dst_param_init_temp_uint(&instructions[ins_count].dst[0], block_temp_idx);
- src_param_init_const_uint(&instructions[ins_count].src[0], label_from_src_param(&ins->src[0]));
- ins_count++;
- }
- else
- {
- if (!vsir_instruction_init_with_params(program,
- &instructions[ins_count], &no_loc, VKD3DSIH_MOVC, 1, 3))
- goto fail;
- dst_param_init_temp_uint(&instructions[ins_count].dst[0], block_temp_idx);
- instructions[ins_count].src[0] = ins->src[0];
- src_param_init_const_uint(&instructions[ins_count].src[1], label_from_src_param(&ins->src[1]));
- src_param_init_const_uint(&instructions[ins_count].src[2], label_from_src_param(&ins->src[2]));
- ins_count++;
- }
-
- if (!vsir_instruction_init_with_params(program,
- &instructions[ins_count], &no_loc, VKD3DSIH_BREAK, 0, 0))
- goto fail;
- ins_count++;
- break;
-
- case VKD3DSIH_RET:
- default:
- if (!reserve_instructions(&instructions, &ins_capacity, ins_count + 1))
- goto fail;
-
- instructions[ins_count++] = *ins;
- break;
- }
- }
-
- assert(first_label_found);
-
- if (!reserve_instructions(&instructions, &ins_capacity, ins_count + 3))
- goto fail;
-
- if (!vsir_instruction_init_with_params(program, &instructions[ins_count], &no_loc, VKD3DSIH_ENDSWITCH, 0, 0))
- goto fail;
- ins_count++;
-
- if (!vsir_instruction_init_with_params(program, &instructions[ins_count], &no_loc, VKD3DSIH_ENDLOOP, 0, 0))
- goto fail;
- ins_count++;
-
- if (!vsir_instruction_init_with_params(program, &instructions[ins_count], &no_loc, VKD3DSIH_RET, 0, 0))
- goto fail;
- ins_count++;
-
- vkd3d_free(program->instructions.elements);
- program->instructions.elements = instructions;
- program->instructions.capacity = ins_capacity;
- program->instructions.count = ins_count;
- program->temp_count += 1;
-
- return VKD3D_OK;
-
-fail:
- vkd3d_free(instructions);
- return VKD3D_ERROR_OUT_OF_MEMORY;
-}
-
struct vsir_block_list
{
struct vsir_block **blocks;
@@ -3283,6 +3169,11 @@ struct vsir_cfg
size_t loop_interval_count, loop_interval_capacity;
struct vsir_cfg_structure_list structured_program;
+
+ struct vkd3d_shader_instruction *instructions;
+ size_t ins_capacity, ins_count;
+ unsigned int jump_target_temp_idx;
+ unsigned int temp_count;
};
static void vsir_cfg_cleanup(struct vsir_cfg *cfg)
@@ -4295,6 +4186,213 @@ fail:
return VKD3D_ERROR_OUT_OF_MEMORY;
}
+static enum vkd3d_result vsir_cfg_structure_list_emit(struct vsir_cfg *cfg,
+ struct vsir_cfg_structure_list *list, unsigned int loop_idx)
+{
+ const struct vkd3d_shader_location no_loc = {0};
+ enum vkd3d_result ret;
+ size_t i;
+
+ for (i = 0; i < list->count; ++i)
+ {
+ struct vsir_cfg_structure *structure = &list->structures[i];
+
+ switch (structure->type)
+ {
+ case STRUCTURE_TYPE_BLOCK:
+ {
+ struct vsir_block *block = structure->u.block;
+
+ if (!reserve_instructions(&cfg->instructions, &cfg->ins_capacity, cfg->ins_count + (block->end - block->begin)))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+
+ memcpy(&cfg->instructions[cfg->ins_count], block->begin, (char *)block->end - (char *)block->begin);
+
+ cfg->ins_count += block->end - block->begin;
+ break;
+ }
+
+ case STRUCTURE_TYPE_LOOP:
+ {
+ if (!reserve_instructions(&cfg->instructions, &cfg->ins_capacity, cfg->ins_count + 1))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+
+ vsir_instruction_init(&cfg->instructions[cfg->ins_count++], &no_loc, VKD3DSIH_LOOP);
+
+ if ((ret = vsir_cfg_structure_list_emit(cfg, &structure->u.loop.body, structure->u.loop.idx)) < 0)
+ return ret;
+
+ if (!reserve_instructions(&cfg->instructions, &cfg->ins_capacity, cfg->ins_count + 5))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+
+ vsir_instruction_init(&cfg->instructions[cfg->ins_count++], &no_loc, VKD3DSIH_ENDLOOP);
+
+ /* Add a trampoline to implement multilevel jumping depending on the stored
+ * jump_target value. */
+ if (loop_idx != UINT_MAX)
+ {
+ /* If the multilevel jump is a `continue' and the target is the loop we're inside
+ * right now, then we can finally do the `continue'. */
+ const unsigned int outer_continue_target = loop_idx << 1 | 1;
+ /* If the multilevel jump is a `continue' to any other target, or if it is a `break'
+ * and the target is not the loop we just finished emitting, then it means that
+ * we have to reach an outer loop, so we keep breaking. */
+ const unsigned int inner_break_target = structure->u.loop.idx << 1;
+
+ if (!vsir_instruction_init_with_params(cfg->program, &cfg->instructions[cfg->ins_count],
+ &no_loc, VKD3DSIH_IEQ, 1, 2))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+
+ dst_param_init_temp_bool(&cfg->instructions[cfg->ins_count].dst[0], cfg->temp_count);
+ src_param_init_temp_uint(&cfg->instructions[cfg->ins_count].src[0], cfg->jump_target_temp_idx);
+ src_param_init_const_uint(&cfg->instructions[cfg->ins_count].src[1], outer_continue_target);
+
+ ++cfg->ins_count;
+
+ if (!vsir_instruction_init_with_params(cfg->program, &cfg->instructions[cfg->ins_count],
+ &no_loc, VKD3DSIH_CONTINUEP, 0, 1))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+
+ src_param_init_temp_bool(&cfg->instructions[cfg->ins_count].src[0], cfg->temp_count);
+
+ ++cfg->ins_count;
+ ++cfg->temp_count;
+
+ if (!vsir_instruction_init_with_params(cfg->program, &cfg->instructions[cfg->ins_count],
+ &no_loc, VKD3DSIH_IEQ, 1, 2))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+
+ dst_param_init_temp_bool(&cfg->instructions[cfg->ins_count].dst[0], cfg->temp_count);
+ src_param_init_temp_uint(&cfg->instructions[cfg->ins_count].src[0], cfg->jump_target_temp_idx);
+ src_param_init_const_uint(&cfg->instructions[cfg->ins_count].src[1], inner_break_target);
+
+ ++cfg->ins_count;
+
+ if (!vsir_instruction_init_with_params(cfg->program, &cfg->instructions[cfg->ins_count],
+ &no_loc, VKD3DSIH_BREAKP, 0, 1))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+ cfg->instructions[cfg->ins_count].flags |= VKD3D_SHADER_CONDITIONAL_OP_Z;
+
+ src_param_init_temp_bool(&cfg->instructions[cfg->ins_count].src[0], cfg->temp_count);
+
+ ++cfg->ins_count;
+ ++cfg->temp_count;
+ }
+
+ break;
+ }
+
+ case STRUCTURE_TYPE_JUMP:
+ {
+ /* Encode the jump target as the loop index plus a bit to remember whether
+ * we're breaking or continueing. */
+ unsigned int jump_target = structure->u.jump.target << 1;
+ enum vkd3d_shader_opcode opcode;
+
+ switch (structure->u.jump.type)
+ {
+ case JUMP_CONTINUE:
+ /* If we're continueing the loop we're directly inside, then we can emit a
+ * `continue'. Otherwise we first have to break all the loops between here
+ * and the loop to continue, recording our intention to continue
+ * in the lowest bit of jump_target. */
+ if (structure->u.jump.target == loop_idx)
+ {
+ opcode = structure->u.jump.condition ? VKD3DSIH_CONTINUEP : VKD3DSIH_CONTINUE;
+ break;
+ }
+ jump_target |= 1;
+ /* fall through */
+
+ case JUMP_BREAK:
+ opcode = structure->u.jump.condition ? VKD3DSIH_BREAKP : VKD3DSIH_BREAK;
+ break;
+
+ case JUMP_RET:
+ assert(!structure->u.jump.condition);
+ opcode = VKD3DSIH_RET;
+ break;
+
+ default:
+ vkd3d_unreachable();
+ }
+
+ if (!reserve_instructions(&cfg->instructions, &cfg->ins_capacity, cfg->ins_count + 2))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+
+ if (opcode == VKD3DSIH_BREAK || opcode == VKD3DSIH_BREAKP)
+ {
+ if (!vsir_instruction_init_with_params(cfg->program, &cfg->instructions[cfg->ins_count],
+ &no_loc, VKD3DSIH_MOV, 1, 1))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+
+ dst_param_init_temp_uint(&cfg->instructions[cfg->ins_count].dst[0], cfg->jump_target_temp_idx);
+ src_param_init_const_uint(&cfg->instructions[cfg->ins_count].src[0], jump_target);
+
+ ++cfg->ins_count;
+ }
+
+ if (!vsir_instruction_init_with_params(cfg->program, &cfg->instructions[cfg->ins_count],
+ &no_loc, opcode, 0, !!structure->u.jump.condition))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+
+ if (structure->u.jump.invert_condition)
+ cfg->instructions[cfg->ins_count].flags |= VKD3D_SHADER_CONDITIONAL_OP_Z;
+
+ if (structure->u.jump.condition)
+ cfg->instructions[cfg->ins_count].src[0] = *structure->u.jump.condition;
+
+ ++cfg->ins_count;
+ break;
+ }
+
+ default:
+ vkd3d_unreachable();
+ }
+ }
+
+ return VKD3D_OK;
+}
+
+static enum vkd3d_result vsir_cfg_emit_structured_program(struct vsir_cfg *cfg)
+{
+ enum vkd3d_result ret;
+ size_t i;
+
+ cfg->jump_target_temp_idx = cfg->program->temp_count;
+ cfg->temp_count = cfg->program->temp_count + 1;
+
+ if (!reserve_instructions(&cfg->instructions, &cfg->ins_capacity, cfg->program->instructions.count))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+
+ /* Copy declarations until the first block. */
+ for (i = 0; i < cfg->program->instructions.count; ++i)
+ {
+ struct vkd3d_shader_instruction *ins = &cfg->program->instructions.elements[i];
+
+ if (ins->handler_idx == VKD3DSIH_LABEL)
+ break;
+
+ cfg->instructions[cfg->ins_count++] = *ins;
+ }
+
+ if ((ret = vsir_cfg_structure_list_emit(cfg, &cfg->structured_program, UINT_MAX)) < 0)
+ goto fail;
+
+ vkd3d_free(cfg->program->instructions.elements);
+ cfg->program->instructions.elements = cfg->instructions;
+ cfg->program->instructions.capacity = cfg->ins_capacity;
+ cfg->program->instructions.count = cfg->ins_count;
+ cfg->program->temp_count = cfg->temp_count;
+
+ return VKD3D_OK;
+
+fail:
+ vkd3d_free(cfg->instructions);
+
+ return ret;
+}
+
enum vkd3d_result vkd3d_shader_normalise(struct vkd3d_shader_parser *parser,
const struct vkd3d_shader_compile_info *compile_info)
{
@@ -4346,7 +4444,7 @@ enum vkd3d_result vkd3d_shader_normalise(struct vkd3d_shader_parser *parser,
return result;
}
- if ((result = vsir_program_structurise(program)) < 0)
+ if ((result = vsir_cfg_emit_structured_program(&cfg)) < 0)
{
vsir_cfg_cleanup(&cfg);
return result;
@@ -4609,7 +4707,7 @@ static void vsir_validate_register(struct validation_context *ctx,
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_PRECISION, "Invalid precision %#x for a LABEL register.",
reg->precision);
- if (reg->data_type != VKD3D_DATA_UINT)
+ if (reg->data_type != VKD3D_DATA_UNUSED)
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, "Invalid data type %#x for a LABEL register.",
reg->data_type);
diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c
index b4f34c42124..f830bbdaa6d 100644
--- a/libs/vkd3d/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c
@@ -7480,7 +7480,7 @@ static void spirv_compiler_emit_imad(struct spirv_compiler *compiler,
unsigned int i, component_count;
component_count = vsir_write_mask_component_count(dst->write_mask);
- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_INT, component_count);
+ type_id = vkd3d_spirv_get_type_id_for_data_type(builder, dst->reg.data_type, component_count);
for (i = 0; i < ARRAY_SIZE(src_ids); ++i)
src_ids[i] = spirv_compiler_emit_load_src(compiler, &src[i], dst->write_mask);
--
2.43.0