Based in part on a vkd3d-proton patch by Joshua Ashton.
Signed-off-by: Conor McCarthy cmccarthy@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; };