Based in part on a vkd3d-proton patch by Joshua Ashton.
Signed-off-by: Conor McCarthy <cmccarthy(a)codeweavers.com>
---
libs/vkd3d-shader/dxbc.c | 15 +++++----
libs/vkd3d-shader/trace.c | 41 +++++++++++++++++++++++-
libs/vkd3d-shader/vkd3d_shader_private.h | 3 ++
3 files changed, 52 insertions(+), 7 deletions(-)
diff --git a/libs/vkd3d-shader/dxbc.c b/libs/vkd3d-shader/dxbc.c
index 6e7c1746..da102056 100644
--- a/libs/vkd3d-shader/dxbc.c
+++ b/libs/vkd3d-shader/dxbc.c
@@ -331,6 +331,7 @@ enum vkd3d_sm4_register_type
VKD3D_SM4_RT_OUTPUT = 0x02,
VKD3D_SM4_RT_INDEXABLE_TEMP = 0x03,
VKD3D_SM4_RT_IMMCONST = 0x04,
+ VKD3D_SM4_RT_IMMCONST64 = 0x05,
VKD3D_SM4_RT_SAMPLER = 0x06,
VKD3D_SM4_RT_RESOURCE = 0x07,
VKD3D_SM4_RT_CONSTBUFFER = 0x08,
@@ -1265,7 +1266,7 @@ static const enum vkd3d_shader_register_type register_type_table[] =
/* VKD3D_SM4_RT_OUTPUT */ VKD3DSPR_OUTPUT,
/* VKD3D_SM4_RT_INDEXABLE_TEMP */ VKD3DSPR_IDXTEMP,
/* VKD3D_SM4_RT_IMMCONST */ VKD3DSPR_IMMCONST,
- /* UNKNOWN */ ~0u,
+ /* VKD3D_SM4_RT_IMMCONST64 */ VKD3DSPR_IMMCONST64,
/* VKD3D_SM4_RT_SAMPLER */ VKD3DSPR_SAMPLER,
/* VKD3D_SM4_RT_RESOURCE */ VKD3DSPR_RESOURCE,
/* VKD3D_SM4_RT_CONSTBUFFER */ VKD3DSPR_CONSTBUFFER,
@@ -1656,21 +1657,23 @@ static bool shader_sm4_read_param(struct vkd3d_sm4_data *priv, const DWORD **ptr
return false;
}
- if (register_type == VKD3D_SM4_RT_IMMCONST)
+ if (register_type == VKD3D_SM4_RT_IMMCONST || register_type == VKD3D_SM4_RT_IMMCONST64)
{
enum vkd3d_sm4_dimension dimension = (token & VKD3D_SM4_DIMENSION_MASK) >> VKD3D_SM4_DIMENSION_SHIFT;
+ unsigned int dword_count;
switch (dimension)
{
case VKD3D_SM4_DIMENSION_SCALAR:
param->immconst_type = VKD3D_IMMCONST_SCALAR;
- if (end - *ptr < 1)
+ dword_count = 1 + (register_type == VKD3D_SM4_RT_IMMCONST64);
+ if (end - *ptr < dword_count)
{
WARN("Invalid ptr %p, end %p.\n", *ptr, end);
return false;
}
- memcpy(param->u.immconst_uint, *ptr, 1 * sizeof(DWORD));
- *ptr += 1;
+ memcpy(param->u.immconst_uint, *ptr, dword_count * sizeof(DWORD));
+ *ptr += dword_count;
break;
case VKD3D_SM4_DIMENSION_VEC4:
@@ -1744,7 +1747,7 @@ static bool shader_sm4_read_src_param(struct vkd3d_sm4_data *priv, const DWORD *
return false;
}
- if (src_param->reg.type == VKD3DSPR_IMMCONST)
+ if (src_param->reg.type == VKD3DSPR_IMMCONST || src_param->reg.type == VKD3DSPR_IMMCONST64)
{
src_param->swizzle = VKD3D_SHADER_NO_SWIZZLE;
}
diff --git a/libs/vkd3d-shader/trace.c b/libs/vkd3d-shader/trace.c
index b80aef67..d66681b9 100644
--- a/libs/vkd3d-shader/trace.c
+++ b/libs/vkd3d-shader/trace.c
@@ -722,6 +722,17 @@ static void shader_print_float_literal(struct vkd3d_d3d_asm_compiler *compiler,
prefix, compiler->colours.literal, f, compiler->colours.reset, suffix);
}
+static void shader_print_double_literal(struct vkd3d_d3d_asm_compiler *compiler,
+ const char *prefix, double d, const char *suffix)
+{
+ if (isfinite(d) && signbit(d))
+ vkd3d_string_buffer_printf(&compiler->buffer, "%s-%s%.15e%s%s",
+ prefix, compiler->colours.literal, -d, compiler->colours.reset, suffix);
+ else
+ vkd3d_string_buffer_printf(&compiler->buffer, "%s%s%.15e%s%s",
+ prefix, compiler->colours.literal, d, compiler->colours.reset, suffix);
+}
+
static void shader_print_int_literal(struct vkd3d_d3d_asm_compiler *compiler,
const char *prefix, int i, const char *suffix)
{
@@ -886,6 +897,10 @@ static void shader_dump_register(struct vkd3d_d3d_asm_compiler *compiler, const
shader_addline(buffer, "l");
break;
+ case VKD3DSPR_IMMCONST64:
+ shader_addline(buffer, "d");
+ break;
+
case VKD3DSPR_CONSTBUFFER:
shader_addline(buffer, "cb");
is_descriptor = true;
@@ -1058,6 +1073,29 @@ static void shader_dump_register(struct vkd3d_d3d_asm_compiler *compiler, const
}
shader_addline(buffer, ")");
}
+ else if (reg->type == VKD3DSPR_IMMCONST64)
+ {
+ shader_addline(buffer, "%s(", compiler->colours.reset);
+ /* A double2 vector is treated as a float4 vector in enum vkd3d_immconst_type. */
+ if (reg->immconst_type == VKD3D_IMMCONST_SCALAR || reg->immconst_type == VKD3D_IMMCONST_VEC4)
+ {
+ if (reg->data_type == VKD3D_DATA_DOUBLE)
+ {
+ shader_print_double_literal(compiler, "", reg->u.immconst_double[0], "");
+ if (reg->immconst_type == VKD3D_IMMCONST_VEC4)
+ shader_print_double_literal(compiler, ", ", reg->u.immconst_double[1], "");
+ }
+ else
+ {
+ shader_addline(buffer, "<unhandled data type %#x>", reg->data_type);
+ }
+ }
+ else
+ {
+ shader_addline(buffer, "<unhandled immconst_type %#x>", reg->immconst_type);
+ }
+ shader_addline(buffer, ")");
+ }
else if (reg->type != VKD3DSPR_RASTOUT
&& reg->type != VKD3DSPR_MISCTYPE
&& reg->type != VKD3DSPR_NULL)
@@ -1181,7 +1219,8 @@ static void shader_dump_src_param(struct vkd3d_d3d_asm_compiler *compiler,
default: shader_addline(buffer, "_unknown_modifier(%#x)", src_modifier);
}
- if (param->reg.type != VKD3DSPR_IMMCONST && param->reg.type != VKD3DSPR_SAMPLER)
+ if (param->reg.type != VKD3DSPR_IMMCONST && param->reg.type != VKD3DSPR_IMMCONST64
+ && param->reg.type != VKD3DSPR_SAMPLER)
{
static const char swizzle_chars[] = "xyzw";
DWORD swizzle_x = (swizzle >> VKD3D_SHADER_SWIZZLE_SHIFT(0)) & VKD3D_SHADER_SWIZZLE_MASK;
diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h
index 9e40a3bf..b3cd8cef 100644
--- a/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -58,6 +58,7 @@
#include <string.h>
#define VKD3D_VEC4_SIZE 4
+#define VKD3D_DVEC2_SIZE 2
enum vkd3d_shader_error
{
@@ -387,6 +388,7 @@ enum vkd3d_shader_register_type
VKD3DSPR_LABEL = 18,
VKD3DSPR_PREDICATE = 19,
VKD3DSPR_IMMCONST,
+ VKD3DSPR_IMMCONST64,
VKD3DSPR_CONSTBUFFER,
VKD3DSPR_IMMCONSTBUFFER,
VKD3DSPR_PRIMID,
@@ -619,6 +621,7 @@ struct vkd3d_shader_register
{
DWORD immconst_uint[VKD3D_VEC4_SIZE];
float immconst_float[VKD3D_VEC4_SIZE];
+ double immconst_double[VKD3D_DVEC2_SIZE];
unsigned fp_body_idx;
} u;
};
--
2.32.0