wine-staging/patches/vkd3d-latest/0002-Updated-vkd3d-to-d164752efc2dffc06d1e3ad9dd04cafff31.patch
2024-12-21 12:28:52 +11:00

1517 lines
62 KiB
Diff

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