mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2025-01-28 22:04:43 -08:00
1517 lines
62 KiB
Diff
1517 lines
62 KiB
Diff
From 4cfee2377ba2cf2eefea8abbb53596fca5dd6f11 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->modifiers << VKD3D_SM1_DST_MODIFIER_SHIFT)
|
|
- | (reg->write_mask << VKD3D_SM1_WRITEMASK_SHIFT) | reg->reg.idx[0].offset);
|
|
+ | (reg->write_mask << VKD3D_SM1_WRITEMASK_SHIFT)
|
|
+ | (reg->reg.idx[0].offset & VKD3D_SM1_REGISTER_NUMBER_MASK));
|
|
}
|
|
|
|
static void write_sm1_src_register(struct vkd3d_bytecode_buffer *buffer, const struct vkd3d_shader_src_param *reg)
|
|
{
|
|
put_u32(buffer, VKD3D_SM1_INSTRUCTION_PARAMETER
|
|
- | sm1_encode_register_type(reg->reg.type)
|
|
+ | sm1_encode_register_type(®->reg)
|
|
| (reg->modifiers << VKD3D_SM1_SRC_MODIFIER_SHIFT)
|
|
- | (swizzle_from_vsir(reg->swizzle) << VKD3D_SM1_SWIZZLE_SHIFT) | reg->reg.idx[0].offset);
|
|
+ | (swizzle_from_vsir(reg->swizzle) << VKD3D_SM1_SWIZZLE_SHIFT)
|
|
+ | (reg->reg.idx[0].offset & VKD3D_SM1_REGISTER_NUMBER_MASK));
|
|
}
|
|
|
|
static void d3dbc_write_instruction(struct d3dbc_compiler *d3dbc, const struct vkd3d_shader_instruction *ins)
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c
|
|
index 4493602dfb7..399c2b67eae 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/dxil.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c
|
|
@@ -430,6 +430,8 @@ enum dx_intrinsic_opcode
|
|
DX_DERIV_COARSEY = 84,
|
|
DX_DERIV_FINEX = 85,
|
|
DX_DERIV_FINEY = 86,
|
|
+ DX_EVAL_SAMPLE_INDEX = 88,
|
|
+ DX_EVAL_CENTROID = 89,
|
|
DX_SAMPLE_INDEX = 90,
|
|
DX_COVERAGE = 91,
|
|
DX_THREAD_ID = 93,
|
|
@@ -5098,6 +5100,53 @@ static void sm6_parser_emit_dx_dot(struct sm6_parser *sm6, enum dx_intrinsic_opc
|
|
instruction_dst_param_init_ssa_scalar(ins, sm6);
|
|
}
|
|
|
|
+static void sm6_parser_emit_dx_eval_attrib(struct sm6_parser *sm6, enum dx_intrinsic_opcode op,
|
|
+ const struct sm6_value **operands, struct function_emission_state *state)
|
|
+{
|
|
+ struct vkd3d_shader_instruction *ins = state->ins;
|
|
+ struct vkd3d_shader_src_param *src_params;
|
|
+ const struct shader_signature *signature;
|
|
+ unsigned int row_index, column_index;
|
|
+ const struct signature_element *e;
|
|
+
|
|
+ row_index = sm6_value_get_constant_uint(operands[0]);
|
|
+ column_index = sm6_value_get_constant_uint(operands[2]);
|
|
+
|
|
+ signature = &sm6->p.program->input_signature;
|
|
+ if (row_index >= signature->element_count)
|
|
+ {
|
|
+ WARN("Invalid row index %u.\n", row_index);
|
|
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
|
|
+ "Invalid input row index %u for an attribute evaluation.", row_index);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ e = &signature->elements[row_index];
|
|
+ if (column_index >= VKD3D_VEC4_SIZE || !(e->mask & (1 << column_index)))
|
|
+ {
|
|
+ WARN("Invalid column index %u.\n", column_index);
|
|
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
|
|
+ "Invalid input column index %u for an attribute evaluation.", column_index);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ vsir_instruction_init(ins, &sm6->p.location, (op == DX_EVAL_CENTROID)
|
|
+ ? VKD3DSIH_EVAL_CENTROID : VKD3DSIH_EVAL_SAMPLE_INDEX);
|
|
+
|
|
+ if (!(src_params = instruction_src_params_alloc(ins, 1 + (op == DX_EVAL_SAMPLE_INDEX), sm6)))
|
|
+ return;
|
|
+
|
|
+ src_params[0].reg = sm6->input_params[row_index].reg;
|
|
+ src_param_init_scalar(&src_params[0], column_index);
|
|
+ if (e->register_count > 1)
|
|
+ register_index_address_init(&src_params[0].reg.idx[0], operands[1], sm6);
|
|
+
|
|
+ if (op == DX_EVAL_SAMPLE_INDEX)
|
|
+ src_param_init_from_value(&src_params[1], operands[3]);
|
|
+
|
|
+ instruction_dst_param_init_ssa_scalar(ins, sm6);
|
|
+}
|
|
+
|
|
static void sm6_parser_emit_dx_fabs(struct sm6_parser *sm6, enum dx_intrinsic_opcode op,
|
|
const struct sm6_value **operands, struct function_emission_state *state)
|
|
{
|
|
@@ -6288,6 +6337,8 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] =
|
|
[DX_DOT4 ] = {"g", "RRRRRRRR", sm6_parser_emit_dx_dot},
|
|
[DX_EMIT_STREAM ] = {"v", "c", sm6_parser_emit_dx_stream},
|
|
[DX_EMIT_THEN_CUT_STREAM ] = {"v", "c", sm6_parser_emit_dx_stream},
|
|
+ [DX_EVAL_CENTROID ] = {"o", "cic", sm6_parser_emit_dx_eval_attrib},
|
|
+ [DX_EVAL_SAMPLE_INDEX ] = {"o", "cici", sm6_parser_emit_dx_eval_attrib},
|
|
[DX_EXP ] = {"g", "R", sm6_parser_emit_dx_unary},
|
|
[DX_FABS ] = {"g", "R", sm6_parser_emit_dx_fabs},
|
|
[DX_FIRST_BIT_HI ] = {"i", "m", sm6_parser_emit_dx_unary},
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h
|
|
index 7c9547a1c01..2acc003c9a1 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h
|
|
@@ -861,6 +861,10 @@ enum hlsl_resource_load_type
|
|
HLSL_RESOURCE_GATHER_GREEN,
|
|
HLSL_RESOURCE_GATHER_BLUE,
|
|
HLSL_RESOURCE_GATHER_ALPHA,
|
|
+ HLSL_RESOURCE_GATHER_CMP_RED,
|
|
+ HLSL_RESOURCE_GATHER_CMP_GREEN,
|
|
+ HLSL_RESOURCE_GATHER_CMP_BLUE,
|
|
+ HLSL_RESOURCE_GATHER_CMP_ALPHA,
|
|
HLSL_RESOURCE_SAMPLE_INFO,
|
|
HLSL_RESOURCE_RESINFO,
|
|
};
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y
|
|
index a3814a810b5..dbed11cd8b3 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y
|
|
@@ -6124,6 +6124,87 @@ static bool add_gather_method_call(struct hlsl_ctx *ctx, struct hlsl_block *bloc
|
|
return true;
|
|
}
|
|
|
|
+static bool add_gather_cmp_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_node *object,
|
|
+ const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
|
|
+{
|
|
+ const struct hlsl_type *object_type = object->data_type;
|
|
+ struct hlsl_resource_load_params load_params = {0};
|
|
+ unsigned int sampler_dim, offset_dim;
|
|
+ const struct hlsl_type *sampler_type;
|
|
+ struct hlsl_ir_node *load;
|
|
+
|
|
+ sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim);
|
|
+ offset_dim = hlsl_offset_dim_count(object_type->sampler_dim);
|
|
+
|
|
+ if (!strcmp(name, "GatherCmpGreen"))
|
|
+ load_params.type = HLSL_RESOURCE_GATHER_CMP_GREEN;
|
|
+ else if (!strcmp(name, "GatherCmpBlue"))
|
|
+ load_params.type = HLSL_RESOURCE_GATHER_CMP_BLUE;
|
|
+ else if (!strcmp(name, "GatherCmpAlpha"))
|
|
+ load_params.type = HLSL_RESOURCE_GATHER_CMP_ALPHA;
|
|
+ else
|
|
+ load_params.type = HLSL_RESOURCE_GATHER_CMP_RED;
|
|
+
|
|
+ if (!strcmp(name, "GatherCmp") || !offset_dim)
|
|
+ {
|
|
+ if (params->args_count < 3 || params->args_count > 4 + !!offset_dim)
|
|
+ {
|
|
+ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT,
|
|
+ "Wrong number of arguments to method '%s': expected from 3 to %u, but got %u.",
|
|
+ name, 4 + !!offset_dim, params->args_count);
|
|
+ return false;
|
|
+ }
|
|
+ }
|
|
+ else if (params->args_count < 3 || params->args_count == 6 || params->args_count > 8)
|
|
+ {
|
|
+ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT,
|
|
+ "Wrong number of arguments to method '%s': expected 3, 4, 5, 7, or 8, but got %u.",
|
|
+ name, params->args_count);
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ if (params->args_count == 5 || params->args_count == 8)
|
|
+ {
|
|
+ hlsl_fixme(ctx, loc, "Tiled resource status argument.");
|
|
+ }
|
|
+ else if (offset_dim && params->args_count > 3)
|
|
+ {
|
|
+ if (!(load_params.texel_offset = add_implicit_conversion(ctx, block, params->args[3],
|
|
+ hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc)))
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ sampler_type = params->args[0]->data_type;
|
|
+ if (sampler_type->class != HLSL_CLASS_SAMPLER || sampler_type->sampler_dim != HLSL_SAMPLER_DIM_COMPARISON)
|
|
+ {
|
|
+ struct vkd3d_string_buffer *string;
|
|
+
|
|
+ if ((string = hlsl_type_to_string(ctx, sampler_type)))
|
|
+ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
|
|
+ "Wrong type for argument 0 of %s(): expected 'SamplerComparisonState', but got '%s'.",
|
|
+ name, string->buffer);
|
|
+ hlsl_release_string_buffer(ctx, string);
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ if (!(load_params.coords = add_implicit_conversion(ctx, block, params->args[1],
|
|
+ hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc)))
|
|
+ return false;
|
|
+
|
|
+ if (!(load_params.cmp = add_implicit_conversion(ctx, block, params->args[2],
|
|
+ hlsl_get_scalar_type(ctx, HLSL_TYPE_FLOAT), loc)))
|
|
+ return false;
|
|
+
|
|
+ load_params.format = hlsl_get_vector_type(ctx, object_type->e.resource.format->e.numeric.type, 4);
|
|
+ load_params.resource = object;
|
|
+ load_params.sampler = params->args[0];
|
|
+
|
|
+ if (!(load = hlsl_new_resource_load(ctx, &load_params, loc)))
|
|
+ return false;
|
|
+ hlsl_block_add_instr(block, load);
|
|
+ return true;
|
|
+}
|
|
+
|
|
static bool add_assignment_from_component(struct hlsl_ctx *ctx, struct hlsl_block *instrs, struct hlsl_ir_node *dest,
|
|
struct hlsl_ir_node *src, unsigned int component, const struct vkd3d_shader_location *loc)
|
|
{
|
|
@@ -6491,6 +6572,11 @@ texture_methods[] =
|
|
{ "Gather", add_gather_method_call, "00010101001000" },
|
|
{ "GatherAlpha", add_gather_method_call, "00010101001000" },
|
|
{ "GatherBlue", add_gather_method_call, "00010101001000" },
|
|
+ { "GatherCmp", add_gather_cmp_method_call, "00010101001000" },
|
|
+ { "GatherCmpAlpha", add_gather_cmp_method_call, "00010101001000" },
|
|
+ { "GatherCmpBlue", add_gather_cmp_method_call, "00010101001000" },
|
|
+ { "GatherCmpGreen", add_gather_cmp_method_call, "00010101001000" },
|
|
+ { "GatherCmpRed", add_gather_cmp_method_call, "00010101001000" },
|
|
{ "GatherGreen", add_gather_method_call, "00010101001000" },
|
|
{ "GatherRed", add_gather_method_call, "00010101001000" },
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
|
|
index a43ea53089e..08f139f5e8f 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
|
|
@@ -2949,6 +2949,10 @@ static bool lower_combined_samples(struct hlsl_ctx *ctx, struct hlsl_ir_node *in
|
|
case HLSL_RESOURCE_GATHER_GREEN:
|
|
case HLSL_RESOURCE_GATHER_BLUE:
|
|
case HLSL_RESOURCE_GATHER_ALPHA:
|
|
+ case HLSL_RESOURCE_GATHER_CMP_RED:
|
|
+ case HLSL_RESOURCE_GATHER_CMP_GREEN:
|
|
+ case HLSL_RESOURCE_GATHER_CMP_BLUE:
|
|
+ case HLSL_RESOURCE_GATHER_CMP_ALPHA:
|
|
case HLSL_RESOURCE_RESINFO:
|
|
case HLSL_RESOURCE_SAMPLE_CMP:
|
|
case HLSL_RESOURCE_SAMPLE_CMP_LZ:
|
|
@@ -3537,6 +3541,51 @@ static bool lower_ternary(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, stru
|
|
return true;
|
|
}
|
|
|
|
+static bool lower_resource_load_bias(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context)
|
|
+{
|
|
+ struct hlsl_ir_node *swizzle, *store;
|
|
+ struct hlsl_ir_resource_load *load;
|
|
+ struct hlsl_ir_load *tmp_load;
|
|
+ struct hlsl_ir_var *tmp_var;
|
|
+ struct hlsl_deref deref;
|
|
+
|
|
+ if (instr->type != HLSL_IR_RESOURCE_LOAD)
|
|
+ return false;
|
|
+ load = hlsl_ir_resource_load(instr);
|
|
+ if (load->load_type != HLSL_RESOURCE_SAMPLE_LOD
|
|
+ && load->load_type != HLSL_RESOURCE_SAMPLE_LOD_BIAS)
|
|
+ return false;
|
|
+
|
|
+ if (!load->lod.node)
|
|
+ return false;
|
|
+
|
|
+ if (!(tmp_var = hlsl_new_synthetic_var(ctx, "coords-with-lod",
|
|
+ hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, 4), &instr->loc)))
|
|
+ return false;
|
|
+
|
|
+ if (!(swizzle = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(X, X, X, X), 4, load->lod.node, &load->lod.node->loc)))
|
|
+ return false;
|
|
+ list_add_before(&instr->entry, &swizzle->entry);
|
|
+
|
|
+ if (!(store = hlsl_new_simple_store(ctx, tmp_var, swizzle)))
|
|
+ return false;
|
|
+ list_add_before(&instr->entry, &store->entry);
|
|
+
|
|
+ hlsl_init_simple_deref_from_var(&deref, tmp_var);
|
|
+ if (!(store = hlsl_new_store_index(ctx, &deref, NULL, load->coords.node, 0, &instr->loc)))
|
|
+ return false;
|
|
+ list_add_before(&instr->entry, &store->entry);
|
|
+
|
|
+ if (!(tmp_load = hlsl_new_var_load(ctx, tmp_var, &instr->loc)))
|
|
+ return false;
|
|
+ list_add_before(&instr->entry, &tmp_load->node.entry);
|
|
+
|
|
+ hlsl_src_remove(&load->coords);
|
|
+ hlsl_src_from_node(&load->coords, &tmp_load->node);
|
|
+ hlsl_src_remove(&load->lod);
|
|
+ return true;
|
|
+}
|
|
+
|
|
static bool lower_comparison_operators(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr,
|
|
struct hlsl_block *block)
|
|
{
|
|
@@ -9596,18 +9645,18 @@ static bool sm4_generate_vsir_instr_sample(struct hlsl_ctx *ctx,
|
|
}
|
|
|
|
static bool sm4_generate_vsir_instr_gather(struct hlsl_ctx *ctx, struct vsir_program *program,
|
|
- const struct hlsl_ir_resource_load *load, uint32_t swizzle)
|
|
+ const struct hlsl_ir_resource_load *load, uint32_t swizzle, bool compare)
|
|
{
|
|
const struct vkd3d_shader_version *version = &program->shader_version;
|
|
const struct hlsl_ir_node *texel_offset = load->texel_offset.node;
|
|
const struct hlsl_ir_node *coords = load->coords.node;
|
|
const struct hlsl_deref *resource = &load->resource;
|
|
+ enum vkd3d_shader_opcode opcode = VKD3DSIH_GATHER4;
|
|
const struct hlsl_deref *sampler = &load->sampler;
|
|
const struct hlsl_ir_node *instr = &load->node;
|
|
+ unsigned int src_count = 3, current_arg = 0;
|
|
struct vkd3d_shader_instruction *ins;
|
|
- enum vkd3d_shader_opcode opcode;
|
|
|
|
- opcode = VKD3DSIH_GATHER4;
|
|
if (texel_offset && !sm4_generate_vsir_validate_texel_offset_aoffimmi(texel_offset))
|
|
{
|
|
if (!vkd3d_shader_ver_ge(version, 5, 0))
|
|
@@ -9617,50 +9666,40 @@ static bool sm4_generate_vsir_instr_gather(struct hlsl_ctx *ctx, struct vsir_pro
|
|
return false;
|
|
}
|
|
opcode = VKD3DSIH_GATHER4_PO;
|
|
+ ++src_count;
|
|
}
|
|
|
|
- if (opcode == VKD3DSIH_GATHER4)
|
|
+ if (compare)
|
|
{
|
|
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, opcode, 1, 3)))
|
|
- return false;
|
|
+ opcode = opcode == VKD3DSIH_GATHER4 ? VKD3DSIH_GATHER4_C : VKD3DSIH_GATHER4_PO_C;
|
|
+ ++src_count;
|
|
+ }
|
|
|
|
- vsir_dst_from_hlsl_node(&ins->dst[0], ctx, instr);
|
|
- vsir_src_from_hlsl_node(&ins->src[0], ctx, coords, VKD3DSP_WRITEMASK_ALL);
|
|
- sm4_generate_vsir_encode_texel_offset_as_aoffimmi(ins, texel_offset);
|
|
+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, opcode, 1, src_count)))
|
|
+ return false;
|
|
|
|
- if (!sm4_generate_vsir_init_src_param_from_deref(ctx, program,
|
|
- &ins->src[1], resource, ins->dst[0].write_mask, &instr->loc))
|
|
- return false;
|
|
+ vsir_dst_from_hlsl_node(&ins->dst[0], ctx, instr);
|
|
+ vsir_src_from_hlsl_node(&ins->src[current_arg++], ctx, coords, VKD3DSP_WRITEMASK_ALL);
|
|
|
|
- if (!sm4_generate_vsir_init_src_param_from_deref(ctx, program,
|
|
- &ins->src[2], sampler, VKD3DSP_WRITEMASK_ALL, &instr->loc))
|
|
- return false;
|
|
- ins->src[2].reg.dimension = VSIR_DIMENSION_VEC4;
|
|
- ins->src[2].swizzle = swizzle;
|
|
- }
|
|
- else if (opcode == VKD3DSIH_GATHER4_PO)
|
|
- {
|
|
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, opcode, 1, 4)))
|
|
- return false;
|
|
+ if (opcode == VKD3DSIH_GATHER4_PO || opcode == VKD3DSIH_GATHER4_PO_C)
|
|
+ vsir_src_from_hlsl_node(&ins->src[current_arg++], ctx, texel_offset, VKD3DSP_WRITEMASK_ALL);
|
|
+ else
|
|
+ sm4_generate_vsir_encode_texel_offset_as_aoffimmi(ins, texel_offset);
|
|
|
|
- vsir_dst_from_hlsl_node(&ins->dst[0], ctx, instr);
|
|
- vsir_src_from_hlsl_node(&ins->src[0], ctx, coords, VKD3DSP_WRITEMASK_ALL);
|
|
- vsir_src_from_hlsl_node(&ins->src[1], ctx, texel_offset, VKD3DSP_WRITEMASK_ALL);
|
|
+ if (!sm4_generate_vsir_init_src_param_from_deref(ctx, program,
|
|
+ &ins->src[current_arg++], resource, ins->dst[0].write_mask, &instr->loc))
|
|
+ return false;
|
|
|
|
- if (!sm4_generate_vsir_init_src_param_from_deref(ctx, program,
|
|
- &ins->src[2], resource, ins->dst[0].write_mask, &instr->loc))
|
|
- return false;
|
|
+ if (!sm4_generate_vsir_init_src_param_from_deref(ctx, program,
|
|
+ &ins->src[current_arg], sampler, VKD3DSP_WRITEMASK_ALL, &instr->loc))
|
|
+ return false;
|
|
+ ins->src[current_arg].reg.dimension = VSIR_DIMENSION_VEC4;
|
|
+ ins->src[current_arg].swizzle = swizzle;
|
|
+ current_arg++;
|
|
+
|
|
+ if (compare)
|
|
+ vsir_src_from_hlsl_node(&ins->src[current_arg++], ctx, load->cmp.node, VKD3DSP_WRITEMASK_0);
|
|
|
|
- if (!sm4_generate_vsir_init_src_param_from_deref(ctx, program,
|
|
- &ins->src[3], sampler, VKD3DSP_WRITEMASK_ALL, &instr->loc))
|
|
- return false;
|
|
- ins->src[3].reg.dimension = VSIR_DIMENSION_VEC4;
|
|
- ins->src[3].swizzle = swizzle;
|
|
- }
|
|
- else
|
|
- {
|
|
- vkd3d_unreachable();
|
|
- }
|
|
return true;
|
|
}
|
|
|
|
@@ -9723,6 +9762,32 @@ static bool sm4_generate_vsir_instr_resinfo(struct hlsl_ctx *ctx,
|
|
return true;
|
|
}
|
|
|
|
+static uint32_t get_gather_swizzle(enum hlsl_resource_load_type type)
|
|
+{
|
|
+ switch (type)
|
|
+ {
|
|
+ case HLSL_RESOURCE_GATHER_RED:
|
|
+ case HLSL_RESOURCE_GATHER_CMP_RED:
|
|
+ return VKD3D_SHADER_SWIZZLE(X, X, X, X);
|
|
+
|
|
+ case HLSL_RESOURCE_GATHER_GREEN:
|
|
+ case HLSL_RESOURCE_GATHER_CMP_GREEN:
|
|
+ return VKD3D_SHADER_SWIZZLE(Y, Y, Y, Y);
|
|
+
|
|
+ case HLSL_RESOURCE_GATHER_BLUE:
|
|
+ case HLSL_RESOURCE_GATHER_CMP_BLUE:
|
|
+ return VKD3D_SHADER_SWIZZLE(Z, Z, Z, Z);
|
|
+
|
|
+ case HLSL_RESOURCE_GATHER_ALPHA:
|
|
+ case HLSL_RESOURCE_GATHER_CMP_ALPHA:
|
|
+ return VKD3D_SHADER_SWIZZLE(W, W, W, W);
|
|
+ default:
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
static bool sm4_generate_vsir_instr_resource_load(struct hlsl_ctx *ctx,
|
|
struct vsir_program *program, const struct hlsl_ir_resource_load *load)
|
|
{
|
|
@@ -9754,16 +9819,16 @@ static bool sm4_generate_vsir_instr_resource_load(struct hlsl_ctx *ctx,
|
|
return sm4_generate_vsir_instr_sample(ctx, program, load);
|
|
|
|
case HLSL_RESOURCE_GATHER_RED:
|
|
- return sm4_generate_vsir_instr_gather(ctx, program, load, VKD3D_SHADER_SWIZZLE(X, X, X, X));
|
|
-
|
|
case HLSL_RESOURCE_GATHER_GREEN:
|
|
- return sm4_generate_vsir_instr_gather(ctx, program, load, VKD3D_SHADER_SWIZZLE(Y, Y, Y, Y));
|
|
-
|
|
case HLSL_RESOURCE_GATHER_BLUE:
|
|
- return sm4_generate_vsir_instr_gather(ctx, program, load, VKD3D_SHADER_SWIZZLE(Z, Z, Z, Z));
|
|
-
|
|
case HLSL_RESOURCE_GATHER_ALPHA:
|
|
- return sm4_generate_vsir_instr_gather(ctx, program, load, VKD3D_SHADER_SWIZZLE(W, W, W, W));
|
|
+ return sm4_generate_vsir_instr_gather(ctx, program, load, get_gather_swizzle(load->load_type), false);
|
|
+
|
|
+ case HLSL_RESOURCE_GATHER_CMP_RED:
|
|
+ case HLSL_RESOURCE_GATHER_CMP_GREEN:
|
|
+ case HLSL_RESOURCE_GATHER_CMP_BLUE:
|
|
+ case HLSL_RESOURCE_GATHER_CMP_ALPHA:
|
|
+ return sm4_generate_vsir_instr_gather(ctx, program, load, get_gather_swizzle(load->load_type), true);
|
|
|
|
case HLSL_RESOURCE_SAMPLE_INFO:
|
|
return sm4_generate_vsir_instr_sample_info(ctx, program, load);
|
|
@@ -11039,13 +11104,14 @@ static void process_entry_function(struct hlsl_ctx *ctx,
|
|
append_output_var_copy(ctx, entry_func, entry_func->return_var);
|
|
}
|
|
|
|
- if (profile->major_version >= 4)
|
|
+ if (hlsl_version_ge(ctx, 4, 0))
|
|
{
|
|
hlsl_transform_ir(ctx, lower_discard_neg, body, NULL);
|
|
}
|
|
else
|
|
{
|
|
hlsl_transform_ir(ctx, lower_discard_nz, body, NULL);
|
|
+ hlsl_transform_ir(ctx, lower_resource_load_bias, body, NULL);
|
|
}
|
|
|
|
loop_unrolling_execute(ctx, body);
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c
|
|
index cdc0c18466f..ec7e2d036c8 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/ir.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c
|
|
@@ -703,7 +703,56 @@ static enum vkd3d_result vsir_program_lower_sm1_sincos(struct vsir_program *prog
|
|
return VKD3D_OK;
|
|
}
|
|
|
|
-static enum vkd3d_result vsir_program_lower_tex(struct vsir_program *program, struct vkd3d_shader_instruction *tex)
|
|
+static enum vkd3d_result vsir_program_lower_texldp(struct vsir_program *program,
|
|
+ struct vkd3d_shader_instruction *tex, unsigned int *tmp_idx)
|
|
+{
|
|
+ struct vkd3d_shader_instruction_array *instructions = &program->instructions;
|
|
+ struct vkd3d_shader_location *location = &tex->location;
|
|
+ struct vkd3d_shader_instruction *div_ins, *tex_ins;
|
|
+ size_t pos = tex - instructions->elements;
|
|
+ unsigned int w_comp;
|
|
+
|
|
+ w_comp = vsir_swizzle_get_component(tex->src[0].swizzle, 3);
|
|
+
|
|
+ if (!shader_instruction_array_insert_at(instructions, pos + 1, 2))
|
|
+ return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
+
|
|
+ if (*tmp_idx == ~0u)
|
|
+ *tmp_idx = program->temp_count++;
|
|
+
|
|
+ div_ins = &instructions->elements[pos + 1];
|
|
+ tex_ins = &instructions->elements[pos + 2];
|
|
+
|
|
+ if (!vsir_instruction_init_with_params(program, div_ins, location, VKD3DSIH_DIV, 1, 2))
|
|
+ return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
+
|
|
+ vsir_dst_param_init(&div_ins->dst[0], VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1);
|
|
+ div_ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4;
|
|
+ div_ins->dst[0].reg.idx[0].offset = *tmp_idx;
|
|
+ div_ins->dst[0].write_mask = VKD3DSP_WRITEMASK_ALL;
|
|
+
|
|
+ div_ins->src[0] = tex->src[0];
|
|
+
|
|
+ div_ins->src[1] = tex->src[0];
|
|
+ div_ins->src[1].swizzle = vkd3d_shader_create_swizzle(w_comp, w_comp, w_comp, w_comp);
|
|
+
|
|
+ if (!vsir_instruction_init_with_params(program, tex_ins, location, VKD3DSIH_TEX, 1, 2))
|
|
+ return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
+
|
|
+ tex_ins->dst[0] = tex->dst[0];
|
|
+
|
|
+ tex_ins->src[0].reg = div_ins->dst[0].reg;
|
|
+ tex_ins->src[0].swizzle = VKD3D_SHADER_NO_SWIZZLE;
|
|
+
|
|
+ tex_ins->src[1] = tex->src[1];
|
|
+
|
|
+ vkd3d_shader_instruction_make_nop(tex);
|
|
+
|
|
+ return VKD3D_OK;
|
|
+}
|
|
+
|
|
+static enum vkd3d_result vsir_program_lower_tex(struct vsir_program *program,
|
|
+ struct vkd3d_shader_instruction *tex, struct vkd3d_shader_message_context *message_context)
|
|
{
|
|
unsigned int idx = tex->src[1].reg.idx[0].offset;
|
|
struct vkd3d_shader_src_param *srcs;
|
|
@@ -711,16 +760,34 @@ static enum vkd3d_result vsir_program_lower_tex(struct vsir_program *program, st
|
|
VKD3D_ASSERT(tex->src[1].reg.idx_count == 1);
|
|
VKD3D_ASSERT(!tex->src[1].reg.idx[0].rel_addr);
|
|
|
|
- if (!(srcs = shader_src_param_allocator_get(&program->instructions.src_params, 3)))
|
|
+ if (!(srcs = shader_src_param_allocator_get(&program->instructions.src_params, 4)))
|
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
|
|
srcs[0] = tex->src[0];
|
|
vsir_src_param_init_resource(&srcs[1], idx, idx);
|
|
vsir_src_param_init_sampler(&srcs[2], idx, idx);
|
|
|
|
- tex->opcode = VKD3DSIH_SAMPLE;
|
|
- tex->src = srcs;
|
|
- tex->src_count = 3;
|
|
+ if (!tex->flags)
|
|
+ {
|
|
+ tex->opcode = VKD3DSIH_SAMPLE;
|
|
+ tex->src = srcs;
|
|
+ tex->src_count = 3;
|
|
+ }
|
|
+ else if (tex->flags == VKD3DSI_TEXLD_BIAS)
|
|
+ {
|
|
+ tex->opcode = VKD3DSIH_SAMPLE_B;
|
|
+ tex->src = srcs;
|
|
+ tex->src_count = 4;
|
|
+
|
|
+ srcs[3] = tex->src[0];
|
|
+ srcs[3].swizzle = VKD3D_SHADER_SWIZZLE(W, W, W, W);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ vkd3d_shader_error(message_context, &tex->location,
|
|
+ VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, "Unhandled tex flags %#x.", tex->flags);
|
|
+ return VKD3D_ERROR_NOT_IMPLEMENTED;
|
|
+ }
|
|
|
|
return VKD3D_OK;
|
|
}
|
|
@@ -885,8 +952,16 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr
|
|
break;
|
|
|
|
case VKD3DSIH_TEX:
|
|
- if ((ret = vsir_program_lower_tex(program, ins)) < 0)
|
|
- return ret;
|
|
+ if (ins->flags == VKD3DSI_TEXLD_PROJECT)
|
|
+ {
|
|
+ if ((ret = vsir_program_lower_texldp(program, ins, &tmp_idx)) < 0)
|
|
+ return ret;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ if ((ret = vsir_program_lower_tex(program, ins, message_context)) < 0)
|
|
+ return ret;
|
|
+ }
|
|
break;
|
|
|
|
case VKD3DSIH_TEXLDD:
|
|
@@ -1117,6 +1192,7 @@ static void remove_unread_output_components(const struct shader_signature *signa
|
|
switch (dst->reg.type)
|
|
{
|
|
case VKD3DSPR_OUTPUT:
|
|
+ case VKD3DSPR_TEXCRDOUT:
|
|
e = vsir_signature_find_element_for_reg(signature, dst->reg.idx[0].offset, 0);
|
|
break;
|
|
|
|
@@ -2102,6 +2178,7 @@ static bool shader_dst_param_io_normalise(struct vkd3d_shader_dst_param *dst_par
|
|
signature = normaliser->patch_constant_signature;
|
|
break;
|
|
|
|
+ case VKD3DSPR_TEXCRDOUT:
|
|
case VKD3DSPR_COLOROUT:
|
|
reg_idx = reg->idx[0].offset;
|
|
signature = normaliser->output_signature;
|
|
@@ -2205,8 +2282,6 @@ static void shader_src_param_io_normalise(struct vkd3d_shader_src_param *src_par
|
|
break;
|
|
|
|
case VKD3DSPR_TEXTURE:
|
|
- if (normaliser->shader_type != VKD3D_SHADER_TYPE_PIXEL)
|
|
- return;
|
|
reg->type = VKD3DSPR_INPUT;
|
|
reg_idx = reg->idx[0].offset;
|
|
signature = normaliser->input_signature;
|
|
@@ -2338,16 +2413,12 @@ static bool get_flat_constant_register_type(const struct vkd3d_shader_register *
|
|
{
|
|
enum vkd3d_shader_register_type type;
|
|
enum vkd3d_shader_d3dbc_constant_register set;
|
|
- uint32_t offset;
|
|
}
|
|
regs[] =
|
|
{
|
|
- {VKD3DSPR_CONST, VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER, 0},
|
|
- {VKD3DSPR_CONST2, VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER, 2048},
|
|
- {VKD3DSPR_CONST3, VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER, 4096},
|
|
- {VKD3DSPR_CONST4, VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER, 6144},
|
|
- {VKD3DSPR_CONSTINT, VKD3D_SHADER_D3DBC_INT_CONSTANT_REGISTER, 0},
|
|
- {VKD3DSPR_CONSTBOOL, VKD3D_SHADER_D3DBC_BOOL_CONSTANT_REGISTER, 0},
|
|
+ {VKD3DSPR_CONST, VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER},
|
|
+ {VKD3DSPR_CONSTINT, VKD3D_SHADER_D3DBC_INT_CONSTANT_REGISTER},
|
|
+ {VKD3DSPR_CONSTBOOL, VKD3D_SHADER_D3DBC_BOOL_CONSTANT_REGISTER},
|
|
};
|
|
|
|
unsigned int i;
|
|
@@ -2363,7 +2434,7 @@ static bool get_flat_constant_register_type(const struct vkd3d_shader_register *
|
|
}
|
|
|
|
*set = regs[i].set;
|
|
- *index = regs[i].offset + reg->idx[0].offset;
|
|
+ *index = reg->idx[0].offset;
|
|
return true;
|
|
}
|
|
}
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c
|
|
index a7b935543a0..cfbadab8933 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/spirv.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c
|
|
@@ -7301,7 +7301,6 @@ static SpvOp spirv_compiler_map_alu_instruction(const struct vkd3d_shader_instru
|
|
{VKD3DSIH_DDIV, SpvOpFDiv},
|
|
{VKD3DSIH_DIV, SpvOpFDiv},
|
|
{VKD3DSIH_DMUL, SpvOpFMul},
|
|
- {VKD3DSIH_DTOF, SpvOpFConvert},
|
|
{VKD3DSIH_DTOI, SpvOpConvertFToS},
|
|
{VKD3DSIH_DTOU, SpvOpConvertFToU},
|
|
{VKD3DSIH_FREM, SpvOpFRem},
|
|
@@ -7939,6 +7938,7 @@ static void spirv_compiler_emit_ftoi(struct spirv_compiler *compiler,
|
|
uint32_t src_type_id, dst_type_id, condition_type_id;
|
|
enum vkd3d_shader_component_type component_type;
|
|
unsigned int component_count;
|
|
+ uint32_t write_mask;
|
|
|
|
VKD3D_ASSERT(instruction->dst_count == 1);
|
|
VKD3D_ASSERT(instruction->src_count == 1);
|
|
@@ -7948,21 +7948,23 @@ static void spirv_compiler_emit_ftoi(struct spirv_compiler *compiler,
|
|
* and for NaN to yield zero. */
|
|
|
|
component_count = vsir_write_mask_component_count(dst->write_mask);
|
|
- src_type_id = spirv_compiler_get_type_id_for_reg(compiler, &src->reg, dst->write_mask);
|
|
- dst_type_id = spirv_compiler_get_type_id_for_dst(compiler, dst);
|
|
- src_id = spirv_compiler_emit_load_src(compiler, src, dst->write_mask);
|
|
|
|
if (src->reg.data_type == VKD3D_DATA_DOUBLE)
|
|
{
|
|
+ write_mask = vkd3d_write_mask_from_component_count(component_count);
|
|
int_min_id = spirv_compiler_get_constant_double_vector(compiler, -2147483648.0, component_count);
|
|
float_max_id = spirv_compiler_get_constant_double_vector(compiler, 2147483648.0, component_count);
|
|
}
|
|
else
|
|
{
|
|
+ write_mask = dst->write_mask;
|
|
int_min_id = spirv_compiler_get_constant_float_vector(compiler, -2147483648.0f, component_count);
|
|
float_max_id = spirv_compiler_get_constant_float_vector(compiler, 2147483648.0f, component_count);
|
|
}
|
|
|
|
+ src_type_id = spirv_compiler_get_type_id_for_reg(compiler, &src->reg, write_mask);
|
|
+ dst_type_id = spirv_compiler_get_type_id_for_dst(compiler, dst);
|
|
+ src_id = spirv_compiler_emit_load_src(compiler, src, write_mask);
|
|
val_id = vkd3d_spirv_build_op_glsl_std450_max(builder, src_type_id, src_id, int_min_id);
|
|
|
|
/* VSIR allows the destination of a signed conversion to be unsigned. */
|
|
@@ -7992,6 +7994,7 @@ static void spirv_compiler_emit_ftou(struct spirv_compiler *compiler,
|
|
const struct vkd3d_shader_src_param *src = instruction->src;
|
|
uint32_t src_type_id, dst_type_id, condition_type_id;
|
|
unsigned int component_count;
|
|
+ uint32_t write_mask;
|
|
|
|
VKD3D_ASSERT(instruction->dst_count == 1);
|
|
VKD3D_ASSERT(instruction->src_count == 1);
|
|
@@ -8001,21 +8004,23 @@ static void spirv_compiler_emit_ftou(struct spirv_compiler *compiler,
|
|
* and for NaN to yield zero. */
|
|
|
|
component_count = vsir_write_mask_component_count(dst->write_mask);
|
|
- src_type_id = spirv_compiler_get_type_id_for_reg(compiler, &src->reg, dst->write_mask);
|
|
- dst_type_id = spirv_compiler_get_type_id_for_dst(compiler, dst);
|
|
- src_id = spirv_compiler_emit_load_src(compiler, src, dst->write_mask);
|
|
|
|
if (src->reg.data_type == VKD3D_DATA_DOUBLE)
|
|
{
|
|
+ write_mask = vkd3d_write_mask_from_component_count(component_count);
|
|
zero_id = spirv_compiler_get_constant_double_vector(compiler, 0.0, component_count);
|
|
float_max_id = spirv_compiler_get_constant_double_vector(compiler, 4294967296.0, component_count);
|
|
}
|
|
else
|
|
{
|
|
+ write_mask = dst->write_mask;
|
|
zero_id = spirv_compiler_get_constant_float_vector(compiler, 0.0f, component_count);
|
|
float_max_id = spirv_compiler_get_constant_float_vector(compiler, 4294967296.0f, component_count);
|
|
}
|
|
|
|
+ src_type_id = spirv_compiler_get_type_id_for_reg(compiler, &src->reg, write_mask);
|
|
+ dst_type_id = spirv_compiler_get_type_id_for_dst(compiler, dst);
|
|
+ src_id = spirv_compiler_emit_load_src(compiler, src, write_mask);
|
|
val_id = vkd3d_spirv_build_op_glsl_std450_max(builder, src_type_id, src_id, zero_id);
|
|
|
|
uint_max_id = spirv_compiler_get_constant_uint_vector(compiler, UINT_MAX, component_count);
|
|
@@ -8029,6 +8034,29 @@ static void spirv_compiler_emit_ftou(struct spirv_compiler *compiler,
|
|
spirv_compiler_emit_store_dst(compiler, dst, val_id);
|
|
}
|
|
|
|
+static void spirv_compiler_emit_dtof(struct spirv_compiler *compiler,
|
|
+ const struct vkd3d_shader_instruction *instruction)
|
|
+{
|
|
+ struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
|
+ const struct vkd3d_shader_dst_param *dst = instruction->dst;
|
|
+ const struct vkd3d_shader_src_param *src = instruction->src;
|
|
+ uint32_t type_id, val_id, src_id;
|
|
+ unsigned int component_count;
|
|
+ uint32_t write_mask;
|
|
+
|
|
+ component_count = vsir_write_mask_component_count(dst->write_mask);
|
|
+ write_mask = vkd3d_write_mask_from_component_count(component_count);
|
|
+
|
|
+ src_id = spirv_compiler_emit_load_src(compiler, src, write_mask);
|
|
+
|
|
+ type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, component_count);
|
|
+ val_id = vkd3d_spirv_build_op_tr1(builder, &builder->function_stream, SpvOpFConvert, type_id, src_id);
|
|
+ if (instruction->flags & VKD3DSI_PRECISE_XYZW)
|
|
+ vkd3d_spirv_build_op_decorate(builder, val_id, SpvDecorationNoContraction, NULL, 0);
|
|
+
|
|
+ spirv_compiler_emit_store_dst(compiler, dst, val_id);
|
|
+}
|
|
+
|
|
static void spirv_compiler_emit_bitfield_instruction(struct spirv_compiler *compiler,
|
|
const struct vkd3d_shader_instruction *instruction)
|
|
{
|
|
@@ -10419,7 +10447,6 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler,
|
|
case VKD3DSIH_DDIV:
|
|
case VKD3DSIH_DIV:
|
|
case VKD3DSIH_DMUL:
|
|
- case VKD3DSIH_DTOF:
|
|
case VKD3DSIH_FREM:
|
|
case VKD3DSIH_FTOD:
|
|
case VKD3DSIH_IADD:
|
|
@@ -10507,6 +10534,9 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler,
|
|
case VKD3DSIH_FTOU:
|
|
spirv_compiler_emit_ftou(compiler, instruction);
|
|
break;
|
|
+ case VKD3DSIH_DTOF:
|
|
+ spirv_compiler_emit_dtof(compiler, instruction);
|
|
+ break;
|
|
case VKD3DSIH_DEQO:
|
|
case VKD3DSIH_DGEO:
|
|
case VKD3DSIH_DLT:
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c
|
|
index 872603052ac..7f115057622 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/tpf.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c
|
|
@@ -4758,6 +4758,8 @@ static void tpf_handle_instruction(struct tpf_compiler *tpf, const struct vkd3d_
|
|
case VKD3DSIH_FTOU:
|
|
case VKD3DSIH_GATHER4:
|
|
case VKD3DSIH_GATHER4_PO:
|
|
+ case VKD3DSIH_GATHER4_C:
|
|
+ case VKD3DSIH_GATHER4_PO_C:
|
|
case VKD3DSIH_GEO:
|
|
case VKD3DSIH_HS_CONTROL_POINT_PHASE:
|
|
case VKD3DSIH_HS_FORK_PHASE:
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
|
|
index 3bfb0a7c3cd..7e8ec156aad 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
|
|
@@ -595,28 +595,25 @@ enum vkd3d_shader_opcode
|
|
|
|
enum vkd3d_shader_register_type
|
|
{
|
|
- VKD3DSPR_TEMP = 0,
|
|
- VKD3DSPR_INPUT = 1,
|
|
- VKD3DSPR_CONST = 2,
|
|
- VKD3DSPR_ADDR = 3,
|
|
- VKD3DSPR_TEXTURE = 3,
|
|
- VKD3DSPR_RASTOUT = 4,
|
|
- VKD3DSPR_ATTROUT = 5,
|
|
- VKD3DSPR_TEXCRDOUT = 6,
|
|
- VKD3DSPR_OUTPUT = 6,
|
|
- VKD3DSPR_CONSTINT = 7,
|
|
- VKD3DSPR_COLOROUT = 8,
|
|
- VKD3DSPR_DEPTHOUT = 9,
|
|
- VKD3DSPR_COMBINED_SAMPLER = 10,
|
|
- VKD3DSPR_CONST2 = 11,
|
|
- VKD3DSPR_CONST3 = 12,
|
|
- VKD3DSPR_CONST4 = 13,
|
|
- VKD3DSPR_CONSTBOOL = 14,
|
|
- VKD3DSPR_LOOP = 15,
|
|
- VKD3DSPR_TEMPFLOAT16 = 16,
|
|
- VKD3DSPR_MISCTYPE = 17,
|
|
- VKD3DSPR_LABEL = 18,
|
|
- VKD3DSPR_PREDICATE = 19,
|
|
+ VKD3DSPR_TEMP,
|
|
+ VKD3DSPR_INPUT,
|
|
+ VKD3DSPR_CONST,
|
|
+ VKD3DSPR_ADDR,
|
|
+ VKD3DSPR_TEXTURE,
|
|
+ VKD3DSPR_RASTOUT,
|
|
+ VKD3DSPR_ATTROUT,
|
|
+ VKD3DSPR_TEXCRDOUT,
|
|
+ VKD3DSPR_OUTPUT,
|
|
+ VKD3DSPR_CONSTINT,
|
|
+ VKD3DSPR_COLOROUT,
|
|
+ VKD3DSPR_DEPTHOUT,
|
|
+ VKD3DSPR_COMBINED_SAMPLER,
|
|
+ VKD3DSPR_CONSTBOOL,
|
|
+ VKD3DSPR_LOOP,
|
|
+ VKD3DSPR_TEMPFLOAT16,
|
|
+ VKD3DSPR_MISCTYPE,
|
|
+ VKD3DSPR_LABEL,
|
|
+ VKD3DSPR_PREDICATE,
|
|
VKD3DSPR_IMMCONST,
|
|
VKD3DSPR_IMMCONST64,
|
|
VKD3DSPR_CONSTBUFFER,
|
|
--
|
|
2.45.2
|
|
|