mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-11-21 16:46:54 -08:00
4527 lines
208 KiB
Diff
4527 lines
208 KiB
Diff
From 0e56d61705e984093a7e54d0ec788e99545011df Mon Sep 17 00:00:00 2001
|
|
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
|
|
Date: Fri, 8 Dec 2023 13:21:19 +1100
|
|
Subject: [PATCH] Updated vkd3d to 3bafee344d8d50172d8da18512ba070c6826b18d.
|
|
|
|
---
|
|
libs/vkd3d/include/private/vkd3d_common.h | 4 +-
|
|
libs/vkd3d/include/vkd3d_shader.h | 20 +
|
|
libs/vkd3d/libs/vkd3d-common/blob.c | 1 +
|
|
libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 135 ++--
|
|
libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 16 +-
|
|
libs/vkd3d/libs/vkd3d-shader/dxbc.c | 4 -
|
|
libs/vkd3d/libs/vkd3d-shader/dxil.c | 699 +++++++++++++++---
|
|
libs/vkd3d/libs/vkd3d-shader/hlsl.y | 20 +-
|
|
libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 12 +-
|
|
libs/vkd3d/libs/vkd3d-shader/ir.c | 29 +-
|
|
libs/vkd3d/libs/vkd3d-shader/spirv.c | 669 ++++++++++-------
|
|
libs/vkd3d/libs/vkd3d-shader/tpf.c | 82 +-
|
|
.../libs/vkd3d-shader/vkd3d_shader_main.c | 86 ++-
|
|
.../libs/vkd3d-shader/vkd3d_shader_private.h | 54 +-
|
|
libs/vkd3d/libs/vkd3d/command.c | 4 +
|
|
libs/vkd3d/libs/vkd3d/device.c | 114 ++-
|
|
libs/vkd3d/libs/vkd3d/resource.c | 19 +-
|
|
libs/vkd3d/libs/vkd3d/state.c | 27 +-
|
|
libs/vkd3d/libs/vkd3d/utils.c | 2 +
|
|
libs/vkd3d/libs/vkd3d/vkd3d_private.h | 23 +-
|
|
20 files changed, 1475 insertions(+), 545 deletions(-)
|
|
|
|
diff --git a/libs/vkd3d/include/private/vkd3d_common.h b/libs/vkd3d/include/private/vkd3d_common.h
|
|
index 34fde1a2aa0..e9bff2fbba3 100644
|
|
--- a/libs/vkd3d/include/private/vkd3d_common.h
|
|
+++ b/libs/vkd3d/include/private/vkd3d_common.h
|
|
@@ -80,7 +80,7 @@ static inline size_t align(size_t addr, size_t alignment)
|
|
# ifdef __MINGW_PRINTF_FORMAT
|
|
# define VKD3D_PRINTF_FUNC(fmt, args) __attribute__((format(__MINGW_PRINTF_FORMAT, fmt, args)))
|
|
# else
|
|
-# define VKD3D_PRINTF_FUNC(fmt, args) /* __attribute__((format(printf, fmt, args))) */
|
|
+# define VKD3D_PRINTF_FUNC(fmt, args) __attribute__((format(printf, fmt, args)))
|
|
# endif
|
|
# define VKD3D_UNUSED __attribute__((unused))
|
|
# define VKD3D_UNREACHABLE __builtin_unreachable()
|
|
@@ -107,7 +107,7 @@ static inline unsigned int vkd3d_popcount(unsigned int v)
|
|
{
|
|
#ifdef _MSC_VER
|
|
return __popcnt(v);
|
|
-#elif defined(__MINGW32__)
|
|
+#elif defined(HAVE_BUILTIN_POPCOUNT)
|
|
return __builtin_popcount(v);
|
|
#else
|
|
v -= (v >> 1) & 0x55555555;
|
|
diff --git a/libs/vkd3d/include/vkd3d_shader.h b/libs/vkd3d/include/vkd3d_shader.h
|
|
index 290f9085d2d..b1a1fff6451 100644
|
|
--- a/libs/vkd3d/include/vkd3d_shader.h
|
|
+++ b/libs/vkd3d/include/vkd3d_shader.h
|
|
@@ -196,6 +196,14 @@ enum vkd3d_shader_compile_option_fragment_coordinate_origin
|
|
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_FRAGMENT_COORDINATE_ORIGIN),
|
|
};
|
|
|
|
+/** Advertises feature availability. \since 1.11 */
|
|
+enum vkd3d_shader_compile_option_feature_flags
|
|
+{
|
|
+ VKD3D_SHADER_COMPILE_OPTION_FEATURE_INT64 = 0x00000001,
|
|
+
|
|
+ VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_FEATURE_FLAGS),
|
|
+};
|
|
+
|
|
enum vkd3d_shader_compile_option_name
|
|
{
|
|
/**
|
|
@@ -253,6 +261,16 @@ enum vkd3d_shader_compile_option_name
|
|
* \since 1.10
|
|
*/
|
|
VKD3D_SHADER_COMPILE_OPTION_FRAGMENT_COORDINATE_ORIGIN = 0x00000009,
|
|
+ /**
|
|
+ * This option specifies the shader features available in the target
|
|
+ * environment. These are not extensions, i.e. they are always supported
|
|
+ * by the driver, but may not be supported by the available hardware.
|
|
+ *
|
|
+ * \a value is a member of enum vkd3d_shader_compile_option_feature_flags.
|
|
+ *
|
|
+ * \since 1.11
|
|
+ */
|
|
+ VKD3D_SHADER_COMPILE_OPTION_FEATURE = 0x0000000a,
|
|
|
|
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_NAME),
|
|
};
|
|
@@ -1551,6 +1569,8 @@ enum vkd3d_shader_component_type
|
|
VKD3D_SHADER_COMPONENT_BOOL = 0x4,
|
|
/** 64-bit IEEE floating-point. */
|
|
VKD3D_SHADER_COMPONENT_DOUBLE = 0x5,
|
|
+ /** 64-bit unsigned integer. \since 1.11 */
|
|
+ VKD3D_SHADER_COMPONENT_UINT64 = 0x6,
|
|
|
|
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPONENT_TYPE),
|
|
};
|
|
diff --git a/libs/vkd3d/libs/vkd3d-common/blob.c b/libs/vkd3d/libs/vkd3d-common/blob.c
|
|
index 71ab9a2c51e..fa2812619ac 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-common/blob.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-common/blob.c
|
|
@@ -17,6 +17,7 @@
|
|
*/
|
|
|
|
#define COBJMACROS
|
|
+
|
|
#define CONST_VTABLE
|
|
#include "vkd3d.h"
|
|
#include "vkd3d_blob.h"
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c
|
|
index 82d1d71d9d3..0589bc42174 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c
|
|
@@ -364,6 +364,7 @@ struct vkd3d_d3d_asm_compiler
|
|
struct vkd3d_string_buffer buffer;
|
|
struct vkd3d_shader_version shader_version;
|
|
struct vkd3d_d3d_asm_colours colours;
|
|
+ enum vsir_asm_dialect dialect;
|
|
};
|
|
|
|
static int VKD3D_PRINTF_FUNC(2, 3) shader_addline(struct vkd3d_string_buffer *buffer, const char *format, ...)
|
|
@@ -606,7 +607,7 @@ static void shader_dump_resource_type(struct vkd3d_d3d_asm_compiler *compiler, e
|
|
vkd3d_string_buffer_printf(&compiler->buffer, "unknown");
|
|
}
|
|
|
|
-static void shader_dump_data_type(struct vkd3d_d3d_asm_compiler *compiler, const enum vkd3d_data_type *type)
|
|
+static void shader_dump_data_type(struct vkd3d_d3d_asm_compiler *compiler, enum vkd3d_data_type type)
|
|
{
|
|
static const char *const data_type_names[] =
|
|
{
|
|
@@ -623,19 +624,31 @@ static void shader_dump_data_type(struct vkd3d_d3d_asm_compiler *compiler, const
|
|
[VKD3D_DATA_DOUBLE ] = "double",
|
|
[VKD3D_DATA_CONTINUED] = "<continued>",
|
|
[VKD3D_DATA_UNUSED ] = "<unused>",
|
|
+ [VKD3D_DATA_UINT8 ] = "uint8",
|
|
+ [VKD3D_DATA_UINT64 ] = "uint64",
|
|
+ [VKD3D_DATA_BOOL ] = "bool",
|
|
};
|
|
+
|
|
const char *name;
|
|
+
|
|
+ if (type < ARRAY_SIZE(data_type_names))
|
|
+ name = data_type_names[type];
|
|
+ else
|
|
+ name = "<unknown>";
|
|
+
|
|
+ vkd3d_string_buffer_printf(&compiler->buffer, "%s", name);
|
|
+}
|
|
+
|
|
+static void shader_dump_resource_data_type(struct vkd3d_d3d_asm_compiler *compiler, const enum vkd3d_data_type *type)
|
|
+{
|
|
int i;
|
|
|
|
vkd3d_string_buffer_printf(&compiler->buffer, "(");
|
|
|
|
for (i = 0; i < 4; i++)
|
|
{
|
|
- if (type[i] < ARRAY_SIZE(data_type_names))
|
|
- name = data_type_names[type[i]];
|
|
- else
|
|
- name = "unknown";
|
|
- vkd3d_string_buffer_printf(&compiler->buffer, "%s%s", i == 0 ? "" : ",", name);
|
|
+ vkd3d_string_buffer_printf(&compiler->buffer, "%s", i == 0 ? "" : ",");
|
|
+ shader_dump_data_type(compiler, type[i]);
|
|
}
|
|
|
|
vkd3d_string_buffer_printf(&compiler->buffer, ")");
|
|
@@ -682,7 +695,7 @@ static void shader_dump_decl_usage(struct vkd3d_d3d_asm_compiler *compiler,
|
|
if (semantic->resource.reg.reg.type == VKD3DSPR_UAV)
|
|
shader_dump_uav_flags(compiler, flags);
|
|
shader_addline(buffer, " ");
|
|
- shader_dump_data_type(compiler, semantic->resource_data_type);
|
|
+ shader_dump_resource_data_type(compiler, semantic->resource_data_type);
|
|
}
|
|
else
|
|
{
|
|
@@ -1096,15 +1109,15 @@ static void shader_dump_register(struct vkd3d_d3d_asm_compiler *compiler, const
|
|
switch (reg->data_type)
|
|
{
|
|
case VKD3D_DATA_FLOAT:
|
|
- shader_print_float_literal(compiler, "", reg->u.immconst_float[0], "");
|
|
+ shader_print_float_literal(compiler, "", reg->u.immconst_f32[0], "");
|
|
break;
|
|
case VKD3D_DATA_INT:
|
|
- shader_print_int_literal(compiler, "", reg->u.immconst_uint[0], "");
|
|
+ shader_print_int_literal(compiler, "", reg->u.immconst_u32[0], "");
|
|
break;
|
|
case VKD3D_DATA_RESOURCE:
|
|
case VKD3D_DATA_SAMPLER:
|
|
case VKD3D_DATA_UINT:
|
|
- shader_print_uint_literal(compiler, "", reg->u.immconst_uint[0], "");
|
|
+ shader_print_uint_literal(compiler, "", reg->u.immconst_u32[0], "");
|
|
break;
|
|
default:
|
|
shader_addline(buffer, "<unhandled data type %#x>", reg->data_type);
|
|
@@ -1116,24 +1129,24 @@ static void shader_dump_register(struct vkd3d_d3d_asm_compiler *compiler, const
|
|
switch (reg->data_type)
|
|
{
|
|
case VKD3D_DATA_FLOAT:
|
|
- shader_print_float_literal(compiler, "", reg->u.immconst_float[0], "");
|
|
- shader_print_float_literal(compiler, ", ", reg->u.immconst_float[1], "");
|
|
- shader_print_float_literal(compiler, ", ", reg->u.immconst_float[2], "");
|
|
- shader_print_float_literal(compiler, ", ", reg->u.immconst_float[3], "");
|
|
+ shader_print_float_literal(compiler, "", reg->u.immconst_f32[0], "");
|
|
+ shader_print_float_literal(compiler, ", ", reg->u.immconst_f32[1], "");
|
|
+ shader_print_float_literal(compiler, ", ", reg->u.immconst_f32[2], "");
|
|
+ shader_print_float_literal(compiler, ", ", reg->u.immconst_f32[3], "");
|
|
break;
|
|
case VKD3D_DATA_INT:
|
|
- shader_print_int_literal(compiler, "", reg->u.immconst_uint[0], "");
|
|
- shader_print_int_literal(compiler, ", ", reg->u.immconst_uint[1], "");
|
|
- shader_print_int_literal(compiler, ", ", reg->u.immconst_uint[2], "");
|
|
- shader_print_int_literal(compiler, ", ", reg->u.immconst_uint[3], "");
|
|
+ shader_print_int_literal(compiler, "", reg->u.immconst_u32[0], "");
|
|
+ shader_print_int_literal(compiler, ", ", reg->u.immconst_u32[1], "");
|
|
+ shader_print_int_literal(compiler, ", ", reg->u.immconst_u32[2], "");
|
|
+ shader_print_int_literal(compiler, ", ", reg->u.immconst_u32[3], "");
|
|
break;
|
|
case VKD3D_DATA_RESOURCE:
|
|
case VKD3D_DATA_SAMPLER:
|
|
case VKD3D_DATA_UINT:
|
|
- shader_print_uint_literal(compiler, "", reg->u.immconst_uint[0], "");
|
|
- shader_print_uint_literal(compiler, ", ", reg->u.immconst_uint[1], "");
|
|
- shader_print_uint_literal(compiler, ", ", reg->u.immconst_uint[2], "");
|
|
- shader_print_uint_literal(compiler, ", ", reg->u.immconst_uint[3], "");
|
|
+ shader_print_uint_literal(compiler, "", reg->u.immconst_u32[0], "");
|
|
+ shader_print_uint_literal(compiler, ", ", reg->u.immconst_u32[1], "");
|
|
+ shader_print_uint_literal(compiler, ", ", reg->u.immconst_u32[2], "");
|
|
+ shader_print_uint_literal(compiler, ", ", reg->u.immconst_u32[3], "");
|
|
break;
|
|
default:
|
|
shader_addline(buffer, "<unhandled data type %#x>", reg->data_type);
|
|
@@ -1155,9 +1168,9 @@ static void shader_dump_register(struct vkd3d_d3d_asm_compiler *compiler, const
|
|
{
|
|
if (reg->data_type == VKD3D_DATA_DOUBLE)
|
|
{
|
|
- shader_print_double_literal(compiler, "", reg->u.immconst_double[0], "");
|
|
+ shader_print_double_literal(compiler, "", reg->u.immconst_f64[0], "");
|
|
if (reg->dimension == VSIR_DIMENSION_VEC4)
|
|
- shader_print_double_literal(compiler, ", ", reg->u.immconst_double[1], "");
|
|
+ shader_print_double_literal(compiler, ", ", reg->u.immconst_f64[1], "");
|
|
}
|
|
else
|
|
{
|
|
@@ -1265,6 +1278,32 @@ static void shader_print_non_uniform(struct vkd3d_d3d_asm_compiler *compiler, co
|
|
compiler->colours.modifier, compiler->colours.reset);
|
|
}
|
|
|
|
+static void shader_dump_reg_type(struct vkd3d_d3d_asm_compiler *compiler,
|
|
+ const struct vkd3d_shader_register *reg)
|
|
+{
|
|
+ static const char *dimensions[] =
|
|
+ {
|
|
+ [VSIR_DIMENSION_NONE] = "",
|
|
+ [VSIR_DIMENSION_SCALAR] = "s:",
|
|
+ [VSIR_DIMENSION_VEC4] = "v4:",
|
|
+ };
|
|
+
|
|
+ struct vkd3d_string_buffer *buffer = &compiler->buffer;
|
|
+ const char *dimension;
|
|
+
|
|
+ if (compiler->dialect != VSIR_ASM_VSIR)
|
|
+ return;
|
|
+
|
|
+ if (reg->dimension < ARRAY_SIZE(dimensions))
|
|
+ dimension = dimensions[reg->dimension];
|
|
+ else
|
|
+ dimension = "??";
|
|
+
|
|
+ shader_addline(buffer, " <%s", dimension);
|
|
+ shader_dump_data_type(compiler, reg->data_type);
|
|
+ shader_addline(buffer, ">");
|
|
+}
|
|
+
|
|
static void shader_dump_dst_param(struct vkd3d_d3d_asm_compiler *compiler,
|
|
const struct vkd3d_shader_dst_param *param, bool is_declaration)
|
|
{
|
|
@@ -1278,7 +1317,7 @@ static void shader_dump_dst_param(struct vkd3d_d3d_asm_compiler *compiler,
|
|
static const char write_mask_chars[] = "xyzw";
|
|
|
|
if (param->reg.data_type == VKD3D_DATA_DOUBLE)
|
|
- write_mask = vkd3d_write_mask_32_from_64(write_mask);
|
|
+ write_mask = vsir_write_mask_32_from_64(write_mask);
|
|
|
|
shader_addline(buffer, ".%s", compiler->colours.write_mask);
|
|
if (write_mask & VKD3DSP_WRITEMASK_0)
|
|
@@ -1294,6 +1333,7 @@ static void shader_dump_dst_param(struct vkd3d_d3d_asm_compiler *compiler,
|
|
|
|
shader_print_precision(compiler, ¶m->reg);
|
|
shader_print_non_uniform(compiler, ¶m->reg);
|
|
+ shader_dump_reg_type(compiler, ¶m->reg);
|
|
}
|
|
|
|
static void shader_dump_src_param(struct vkd3d_d3d_asm_compiler *compiler,
|
|
@@ -1341,10 +1381,10 @@ static void shader_dump_src_param(struct vkd3d_d3d_asm_compiler *compiler,
|
|
if (param->reg.type != VKD3DSPR_IMMCONST && param->reg.type != VKD3DSPR_IMMCONST64
|
|
&& param->reg.dimension == VSIR_DIMENSION_VEC4)
|
|
{
|
|
- unsigned int swizzle_x = vkd3d_swizzle_get_component(swizzle, 0);
|
|
- unsigned int swizzle_y = vkd3d_swizzle_get_component(swizzle, 1);
|
|
- unsigned int swizzle_z = vkd3d_swizzle_get_component(swizzle, 2);
|
|
- unsigned int swizzle_w = vkd3d_swizzle_get_component(swizzle, 3);
|
|
+ unsigned int swizzle_x = vsir_swizzle_get_component(swizzle, 0);
|
|
+ unsigned int swizzle_y = vsir_swizzle_get_component(swizzle, 1);
|
|
+ unsigned int swizzle_z = vsir_swizzle_get_component(swizzle, 2);
|
|
+ unsigned int swizzle_w = vsir_swizzle_get_component(swizzle, 3);
|
|
|
|
static const char swizzle_chars[] = "xyzw";
|
|
|
|
@@ -1367,6 +1407,7 @@ static void shader_dump_src_param(struct vkd3d_d3d_asm_compiler *compiler,
|
|
|
|
shader_print_precision(compiler, ¶m->reg);
|
|
shader_print_non_uniform(compiler, ¶m->reg);
|
|
+ shader_dump_reg_type(compiler, ¶m->reg);
|
|
}
|
|
|
|
static void shader_dump_ins_modifiers(struct vkd3d_d3d_asm_compiler *compiler,
|
|
@@ -1577,6 +1618,12 @@ static void shader_dump_instruction_flags(struct vkd3d_d3d_asm_compiler *compile
|
|
shader_addline(buffer, "p");
|
|
break;
|
|
|
|
+ case VKD3DSIH_ISHL:
|
|
+ case VKD3DSIH_ISHR:
|
|
+ case VKD3DSIH_USHR:
|
|
+ if (ins->flags & VKD3DSI_SHIFT_UNMASKED)
|
|
+ shader_addline(buffer, "_unmasked");
|
|
+ /* fall through */
|
|
default:
|
|
shader_dump_precise_flags(compiler, ins->flags);
|
|
break;
|
|
@@ -1835,25 +1882,25 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler,
|
|
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);
|
|
- shader_print_float_literal(compiler, " = ", ins->src[0].reg.u.immconst_float[0], "");
|
|
- shader_print_float_literal(compiler, ", ", ins->src[0].reg.u.immconst_float[1], "");
|
|
- shader_print_float_literal(compiler, ", ", ins->src[0].reg.u.immconst_float[2], "");
|
|
- shader_print_float_literal(compiler, ", ", ins->src[0].reg.u.immconst_float[3], "");
|
|
+ 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], "");
|
|
+ shader_print_float_literal(compiler, ", ", ins->src[0].reg.u.immconst_f32[3], "");
|
|
break;
|
|
|
|
case VKD3DSIH_DEFI:
|
|
vkd3d_string_buffer_printf(buffer, " %si%u%s", compiler->colours.reg,
|
|
ins->dst[0].reg.idx[0].offset, compiler->colours.reset);
|
|
- shader_print_int_literal(compiler, " = ", ins->src[0].reg.u.immconst_uint[0], "");
|
|
- shader_print_int_literal(compiler, ", ", ins->src[0].reg.u.immconst_uint[1], "");
|
|
- shader_print_int_literal(compiler, ", ", ins->src[0].reg.u.immconst_uint[2], "");
|
|
- shader_print_int_literal(compiler, ", ", ins->src[0].reg.u.immconst_uint[3], "");
|
|
+ shader_print_int_literal(compiler, " = ", ins->src[0].reg.u.immconst_u32[0], "");
|
|
+ shader_print_int_literal(compiler, ", ", ins->src[0].reg.u.immconst_u32[1], "");
|
|
+ shader_print_int_literal(compiler, ", ", ins->src[0].reg.u.immconst_u32[2], "");
|
|
+ shader_print_int_literal(compiler, ", ", ins->src[0].reg.u.immconst_u32[3], "");
|
|
break;
|
|
|
|
case VKD3DSIH_DEFB:
|
|
vkd3d_string_buffer_printf(buffer, " %sb%u%s", compiler->colours.reg,
|
|
ins->dst[0].reg.idx[0].offset, compiler->colours.reset);
|
|
- shader_print_bool_literal(compiler, " = ", ins->src[0].reg.u.immconst_uint[0], "");
|
|
+ shader_print_bool_literal(compiler, " = ", ins->src[0].reg.u.immconst_u32[0], "");
|
|
break;
|
|
|
|
default:
|
|
@@ -1883,7 +1930,7 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler,
|
|
|| ins->resource_data_type[1] != VKD3D_DATA_FLOAT
|
|
|| ins->resource_data_type[2] != VKD3D_DATA_FLOAT
|
|
|| ins->resource_data_type[3] != VKD3D_DATA_FLOAT)
|
|
- shader_dump_data_type(compiler, ins->resource_data_type);
|
|
+ shader_dump_resource_data_type(compiler, ins->resource_data_type);
|
|
|
|
for (i = 0; i < ins->dst_count; ++i)
|
|
{
|
|
@@ -1906,10 +1953,13 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler,
|
|
|
|
enum vkd3d_result vkd3d_dxbc_binary_to_text(const struct vkd3d_shader_instruction_array *instructions,
|
|
const struct vkd3d_shader_version *shader_version, const struct vkd3d_shader_compile_info *compile_info,
|
|
- struct vkd3d_shader_code *out)
|
|
+ struct vkd3d_shader_code *out, enum vsir_asm_dialect dialect)
|
|
{
|
|
enum vkd3d_shader_compile_option_formatting_flags formatting;
|
|
- struct vkd3d_d3d_asm_compiler compiler;
|
|
+ struct vkd3d_d3d_asm_compiler compiler =
|
|
+ {
|
|
+ .dialect = dialect,
|
|
+ };
|
|
enum vkd3d_result result = VKD3D_OK;
|
|
struct vkd3d_string_buffer *buffer;
|
|
unsigned int indent, i, j;
|
|
@@ -2002,6 +2052,7 @@ enum vkd3d_result vkd3d_dxbc_binary_to_text(const struct vkd3d_shader_instructio
|
|
{
|
|
case VKD3DSIH_ELSE:
|
|
case VKD3DSIH_IF:
|
|
+ case VKD3DSIH_IFC:
|
|
case VKD3DSIH_LOOP:
|
|
case VKD3DSIH_SWITCH:
|
|
++indent;
|
|
@@ -2034,7 +2085,7 @@ void vkd3d_shader_trace(const struct vkd3d_shader_instruction_array *instruction
|
|
const char *p, *q, *end;
|
|
struct vkd3d_shader_code code;
|
|
|
|
- if (vkd3d_dxbc_binary_to_text(instructions, shader_version, NULL, &code) != VKD3D_OK)
|
|
+ if (vkd3d_dxbc_binary_to_text(instructions, shader_version, NULL, &code, VSIR_ASM_VSIR) != VKD3D_OK)
|
|
return;
|
|
|
|
end = (const char *)code.code + code.size;
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
|
|
index 3d139416b61..ca6e3b72de9 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
|
|
@@ -987,7 +987,7 @@ static void shader_sm1_read_immconst(struct vkd3d_shader_sm1_parser *sm1, const
|
|
src_param->reg.idx[2].rel_addr = NULL;
|
|
src_param->reg.idx_count = 0;
|
|
src_param->reg.dimension = dimension;
|
|
- memcpy(src_param->reg.u.immconst_uint, *ptr, count * sizeof(uint32_t));
|
|
+ memcpy(src_param->reg.u.immconst_u32, *ptr, count * sizeof(uint32_t));
|
|
src_param->swizzle = VKD3D_SHADER_NO_SWIZZLE;
|
|
src_param->modifiers = 0;
|
|
|
|
@@ -1063,12 +1063,12 @@ static void shader_sm1_validate_instruction(struct vkd3d_shader_sm1_parser *sm1,
|
|
}
|
|
}
|
|
|
|
-static unsigned int mask_from_swizzle(unsigned int swizzle)
|
|
+static unsigned int mask_from_swizzle(uint32_t swizzle)
|
|
{
|
|
- return (1u << vkd3d_swizzle_get_component(swizzle, 0))
|
|
- | (1u << vkd3d_swizzle_get_component(swizzle, 1))
|
|
- | (1u << vkd3d_swizzle_get_component(swizzle, 2))
|
|
- | (1u << vkd3d_swizzle_get_component(swizzle, 3));
|
|
+ return (1u << vsir_swizzle_get_component(swizzle, 0))
|
|
+ | (1u << vsir_swizzle_get_component(swizzle, 1))
|
|
+ | (1u << vsir_swizzle_get_component(swizzle, 2))
|
|
+ | (1u << vsir_swizzle_get_component(swizzle, 3));
|
|
}
|
|
|
|
static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, struct vkd3d_shader_instruction *ins)
|
|
@@ -2253,7 +2253,7 @@ static void write_sm1_jump(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b
|
|
{
|
|
struct hlsl_reg *reg = &jump->condition.node->reg;
|
|
|
|
- struct sm1_instruction instr =
|
|
+ struct sm1_instruction sm1_instr =
|
|
{
|
|
.opcode = D3DSIO_TEXKILL,
|
|
|
|
@@ -2263,7 +2263,7 @@ static void write_sm1_jump(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b
|
|
.has_dst = 1,
|
|
};
|
|
|
|
- write_sm1_instruction(ctx, buffer, &instr);
|
|
+ write_sm1_instruction(ctx, buffer, &sm1_instr);
|
|
break;
|
|
}
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/dxbc.c b/libs/vkd3d/libs/vkd3d-shader/dxbc.c
|
|
index 7834c1e1615..63deaaad29a 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/dxbc.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/dxbc.c
|
|
@@ -431,10 +431,6 @@ static int shader_parse_signature(const struct vkd3d_shader_dxbc_section_desc *s
|
|
case TAG_OSG5:
|
|
if (e[i].sysval_semantic == VKD3D_SHADER_SV_NONE)
|
|
e[i].sysval_semantic = map_fragment_output_sysval(e[i].semantic_name);
|
|
- /* Fall through. */
|
|
- case TAG_PCSG:
|
|
- case TAG_PSG1:
|
|
- e[i].used_mask = e[i].mask & ~e[i].used_mask;
|
|
break;
|
|
}
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c
|
|
index beb9ae574dc..2424b176068 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/dxil.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c
|
|
@@ -29,6 +29,9 @@ static const uint64_t MAX_ALIGNMENT_EXPONENT = 29;
|
|
static const uint64_t GLOBALVAR_FLAG_IS_CONSTANT = 1;
|
|
static const uint64_t GLOBALVAR_FLAG_EXPLICIT_TYPE = 2;
|
|
static const unsigned int GLOBALVAR_ADDRESS_SPACE_SHIFT = 2;
|
|
+static const uint64_t ALLOCA_FLAG_IN_ALLOCA = 0x20;
|
|
+static const uint64_t ALLOCA_FLAG_EXPLICIT_TYPE = 0x40;
|
|
+static const uint64_t ALLOCA_ALIGNMENT_MASK = ALLOCA_FLAG_IN_ALLOCA - 1;
|
|
static const unsigned int SHADER_DESCRIPTOR_TYPE_COUNT = 4;
|
|
|
|
static const unsigned int dx_max_thread_group_size[3] = {1024, 1024, 64};
|
|
@@ -296,8 +299,28 @@ enum dx_intrinsic_opcode
|
|
{
|
|
DX_LOAD_INPUT = 4,
|
|
DX_STORE_OUTPUT = 5,
|
|
+ DX_EXP = 21,
|
|
+ DX_FRC = 22,
|
|
+ DX_LOG = 23,
|
|
+ DX_SQRT = 24,
|
|
+ DX_RSQRT = 25,
|
|
+ DX_ROUND_NE = 26,
|
|
+ DX_ROUND_NI = 27,
|
|
+ DX_ROUND_PI = 28,
|
|
+ DX_ROUND_Z = 29,
|
|
+ DX_BFREV = 30,
|
|
+ DX_COUNT_BITS = 31,
|
|
+ DX_FIRST_BIT_LO = 32,
|
|
+ DX_FIRST_BIT_HI = 33,
|
|
+ DX_FIRST_BIT_SHI = 34,
|
|
DX_CREATE_HANDLE = 57,
|
|
DX_CBUFFER_LOAD_LEGACY = 59,
|
|
+ DX_DERIV_COARSEX = 83,
|
|
+ DX_DERIV_COARSEY = 84,
|
|
+ DX_DERIV_FINEX = 85,
|
|
+ DX_DERIV_FINEY = 86,
|
|
+ DX_LEGACY_F32TOF16 = 130,
|
|
+ DX_LEGACY_F16TOF32 = 131,
|
|
};
|
|
|
|
enum dxil_cast_code
|
|
@@ -439,6 +462,7 @@ struct dxil_record
|
|
{
|
|
unsigned int code;
|
|
unsigned int operand_count;
|
|
+ const struct dxil_record *attachment;
|
|
uint64_t operands[];
|
|
};
|
|
|
|
@@ -581,6 +605,7 @@ struct sm6_parser
|
|
size_t descriptor_count;
|
|
|
|
unsigned int indexable_temp_count;
|
|
+ unsigned int icb_count;
|
|
|
|
struct sm6_value *values;
|
|
size_t value_count;
|
|
@@ -796,6 +821,7 @@ static enum vkd3d_result sm6_parser_read_unabbrev_record(struct sm6_parser *sm6)
|
|
|
|
record->code = code;
|
|
record->operand_count = count;
|
|
+ record->attachment = NULL;
|
|
|
|
for (i = 0; i < count; ++i)
|
|
record->operands[i] = sm6_parser_read_vbr(sm6, 6);
|
|
@@ -1012,6 +1038,7 @@ static enum vkd3d_result sm6_parser_read_abbrev_record(struct sm6_parser *sm6, u
|
|
if (!abbrev->operands[i + 1].read_operand(sm6, abbrev->operands[i + 1].context, &record->operands[i]))
|
|
goto fail;
|
|
record->operand_count = count;
|
|
+ record->attachment = NULL;
|
|
|
|
/* An array can occur only as the last operand. */
|
|
if (abbrev->is_array)
|
|
@@ -1210,7 +1237,7 @@ static size_t dxil_block_compute_module_decl_count(const struct dxil_block *bloc
|
|
size_t i, count;
|
|
|
|
for (i = 0, count = 0; i < block->record_count; ++i)
|
|
- count += block->records[i]->code == MODULE_CODE_FUNCTION;
|
|
+ count += block->records[i]->code == MODULE_CODE_FUNCTION || block->records[i]->code == MODULE_CODE_GLOBALVAR;
|
|
return count;
|
|
}
|
|
|
|
@@ -1572,6 +1599,11 @@ static bool sm6_type_is_bool_i16_i32_i64(const struct sm6_type *type)
|
|
return type->class == TYPE_CLASS_INTEGER && (type->u.width == 1 || type->u.width >= 16);
|
|
}
|
|
|
|
+static bool sm6_type_is_i16_i32_i64(const struct sm6_type *type)
|
|
+{
|
|
+ return type->class == TYPE_CLASS_INTEGER && type->u.width >= 16;
|
|
+}
|
|
+
|
|
static bool sm6_type_is_bool(const struct sm6_type *type)
|
|
{
|
|
return type->class == TYPE_CLASS_INTEGER && type->u.width == 1;
|
|
@@ -1587,6 +1619,16 @@ static inline bool sm6_type_is_i32(const struct sm6_type *type)
|
|
return type->class == TYPE_CLASS_INTEGER && type->u.width == 32;
|
|
}
|
|
|
|
+static bool sm6_type_is_float(const struct sm6_type *type)
|
|
+{
|
|
+ return type->class == TYPE_CLASS_FLOAT && type->u.width == 32;
|
|
+}
|
|
+
|
|
+static bool sm6_type_is_f16_f32(const struct sm6_type *type)
|
|
+{
|
|
+ return type->class == TYPE_CLASS_FLOAT && (type->u.width == 16 || type->u.width == 32);
|
|
+}
|
|
+
|
|
static inline bool sm6_type_is_floating_point(const struct sm6_type *type)
|
|
{
|
|
return type->class == TYPE_CLASS_FLOAT;
|
|
@@ -1844,12 +1886,12 @@ static unsigned int register_get_uint_value(const struct vkd3d_shader_register *
|
|
|
|
if (reg->type == VKD3DSPR_IMMCONST64)
|
|
{
|
|
- if (reg->u.immconst_uint64[0] > UINT_MAX)
|
|
+ if (reg->u.immconst_u64[0] > UINT_MAX)
|
|
FIXME("Truncating 64-bit value.\n");
|
|
- return reg->u.immconst_uint64[0];
|
|
+ return reg->u.immconst_u64[0];
|
|
}
|
|
|
|
- return reg->u.immconst_uint[0];
|
|
+ return reg->u.immconst_u32[0];
|
|
}
|
|
|
|
static uint64_t register_get_uint64_value(const struct vkd3d_shader_register *reg)
|
|
@@ -1860,7 +1902,7 @@ static uint64_t register_get_uint64_value(const struct vkd3d_shader_register *re
|
|
if (reg->dimension == VSIR_DIMENSION_VEC4)
|
|
WARN("Returning vec4.x.\n");
|
|
|
|
- return (reg->type == VKD3DSPR_IMMCONST64) ? reg->u.immconst_uint64[0] : reg->u.immconst_uint[0];
|
|
+ return (reg->type == VKD3DSPR_IMMCONST64) ? reg->u.immconst_u64[0] : reg->u.immconst_u32[0];
|
|
}
|
|
|
|
static inline bool sm6_value_is_function_dcl(const struct sm6_value *value)
|
|
@@ -2412,7 +2454,7 @@ static enum vkd3d_result value_allocate_constant_array(struct sm6_value *dst, co
|
|
return VKD3D_ERROR_INVALID_SHADER;
|
|
}
|
|
size = max(size, sizeof(icb->data[0]));
|
|
- count = type->u.array.count * size / sizeof(icb->data[0]);
|
|
+ count = operands ? type->u.array.count * size / sizeof(icb->data[0]) : 0;
|
|
|
|
if (!(icb = vkd3d_malloc(offsetof(struct vkd3d_shader_immediate_constant_buffer, data[count]))))
|
|
{
|
|
@@ -2433,9 +2475,14 @@ static enum vkd3d_result value_allocate_constant_array(struct sm6_value *dst, co
|
|
dst->value_type = VALUE_TYPE_ICB;
|
|
dst->u.icb = icb;
|
|
|
|
+ icb->register_idx = sm6->icb_count++;
|
|
icb->data_type = vkd3d_data_type_from_sm6_type(elem_type);
|
|
icb->element_count = type->u.array.count;
|
|
icb->component_count = 1;
|
|
+ icb->is_null = !operands;
|
|
+
|
|
+ if (!operands)
|
|
+ return VKD3D_OK;
|
|
|
|
count = type->u.array.count;
|
|
if (size > sizeof(icb->data[0]))
|
|
@@ -2510,12 +2557,10 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const
|
|
switch (record->code)
|
|
{
|
|
case CST_CODE_NULL:
|
|
- if (sm6_type_is_array(type))
|
|
+ if (sm6_type_is_array(type)
|
|
+ && (ret = value_allocate_constant_array(dst, type, NULL, sm6)) < 0)
|
|
{
|
|
- FIXME("Constant null arrays are not supported.\n");
|
|
- vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
|
|
- "Constant null arrays are not supported.");
|
|
- return VKD3D_ERROR_INVALID_SHADER;
|
|
+ return ret;
|
|
}
|
|
/* For non-aggregates, register constant data is already zero-filled. */
|
|
break;
|
|
@@ -2532,9 +2577,9 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const
|
|
|
|
value = decode_rotated_signed_value(record->operands[0]);
|
|
if (type->u.width <= 32)
|
|
- dst->u.reg.u.immconst_uint[0] = value & ((1ull << type->u.width) - 1);
|
|
+ dst->u.reg.u.immconst_u32[0] = value & ((1ull << type->u.width) - 1);
|
|
else
|
|
- dst->u.reg.u.immconst_uint64[0] = value;
|
|
+ dst->u.reg.u.immconst_u64[0] = value;
|
|
|
|
break;
|
|
|
|
@@ -2551,9 +2596,9 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const
|
|
if (type->u.width == 16)
|
|
FIXME("Half float type is not supported yet.\n");
|
|
else if (type->u.width == 32)
|
|
- dst->u.reg.u.immconst_float[0] = bitcast_uint64_to_float(record->operands[0]);
|
|
+ dst->u.reg.u.immconst_f32[0] = bitcast_uint64_to_float(record->operands[0]);
|
|
else if (type->u.width == 64)
|
|
- dst->u.reg.u.immconst_double[0] = bitcast_uint64_to_double(record->operands[0]);
|
|
+ dst->u.reg.u.immconst_f64[0] = bitcast_uint64_to_double(record->operands[0]);
|
|
else
|
|
vkd3d_unreachable();
|
|
|
|
@@ -2588,6 +2633,13 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const
|
|
break;
|
|
}
|
|
|
|
+ if (record->attachment)
|
|
+ {
|
|
+ WARN("Ignoring metadata attachment.\n");
|
|
+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_ATTACHMENT,
|
|
+ "Ignoring a metadata attachment for a constant.");
|
|
+ }
|
|
+
|
|
++sm6->value_count;
|
|
}
|
|
|
|
@@ -2626,13 +2678,28 @@ static struct vkd3d_shader_instruction *sm6_parser_add_instruction(struct sm6_pa
|
|
return ins;
|
|
}
|
|
|
|
-static void sm6_parser_declare_indexable_temp(struct sm6_parser *sm6, const struct sm6_type *elem_type,
|
|
- unsigned int count, unsigned int alignment, unsigned int init, struct sm6_value *dst)
|
|
+static void sm6_parser_declare_icb(struct sm6_parser *sm6, const struct sm6_type *elem_type, unsigned int count,
|
|
+ unsigned int alignment, unsigned int init, struct sm6_value *dst)
|
|
{
|
|
enum vkd3d_data_type data_type = vkd3d_data_type_from_sm6_type(elem_type);
|
|
struct vkd3d_shader_instruction *ins;
|
|
|
|
- ins = sm6_parser_add_instruction(sm6, VKD3DSIH_DCL_INDEXABLE_TEMP);
|
|
+ ins = sm6_parser_add_instruction(sm6, VKD3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER);
|
|
+ /* The icb value index will be resolved later so forward references can be handled. */
|
|
+ ins->declaration.icb = (void *)(intptr_t)init;
|
|
+ register_init_with_id(&dst->u.reg, VKD3DSPR_IMMCONSTBUFFER, data_type, init);
|
|
+}
|
|
+
|
|
+static void sm6_parser_declare_indexable_temp(struct sm6_parser *sm6, const struct sm6_type *elem_type,
|
|
+ unsigned int count, unsigned int alignment, unsigned int init, struct vkd3d_shader_instruction *ins,
|
|
+ struct sm6_value *dst)
|
|
+{
|
|
+ enum vkd3d_data_type data_type = vkd3d_data_type_from_sm6_type(elem_type);
|
|
+
|
|
+ if (ins)
|
|
+ vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_DCL_INDEXABLE_TEMP);
|
|
+ else
|
|
+ ins = sm6_parser_add_instruction(sm6, VKD3DSIH_DCL_INDEXABLE_TEMP);
|
|
ins->declaration.indexable_temp.register_idx = sm6->indexable_temp_count++;
|
|
ins->declaration.indexable_temp.register_size = count;
|
|
ins->declaration.indexable_temp.alignment = alignment;
|
|
@@ -2762,7 +2829,10 @@ static bool sm6_parser_declare_global(struct sm6_parser *sm6, const struct dxil_
|
|
|
|
if (address_space == ADDRESS_SPACE_DEFAULT)
|
|
{
|
|
- sm6_parser_declare_indexable_temp(sm6, scalar_type, count, alignment, init, dst);
|
|
+ if (is_constant)
|
|
+ sm6_parser_declare_icb(sm6, scalar_type, count, alignment, init, dst);
|
|
+ else
|
|
+ sm6_parser_declare_indexable_temp(sm6, scalar_type, count, alignment, init, NULL, dst);
|
|
}
|
|
else if (address_space == ADDRESS_SPACE_GROUPSHARED)
|
|
{
|
|
@@ -2790,31 +2860,37 @@ static const struct vkd3d_shader_immediate_constant_buffer *resolve_forward_init
|
|
|
|
assert(index);
|
|
--index;
|
|
- if (!(value = sm6_parser_get_value_safe(sm6, index)) || !sm6_value_is_icb(value))
|
|
+ if (!(value = sm6_parser_get_value_safe(sm6, index)) || (!sm6_value_is_icb(value) && !sm6_value_is_undef(value)))
|
|
{
|
|
WARN("Invalid initialiser index %zu.\n", index);
|
|
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
|
|
"Global variable initialiser value index %zu is invalid.", index);
|
|
return NULL;
|
|
}
|
|
- else
|
|
+ else if (sm6_value_is_icb(value))
|
|
{
|
|
return value->u.icb;
|
|
}
|
|
+ /* In VSIR, initialisation with undefined values of objects is implied, not explicit. */
|
|
+ return NULL;
|
|
}
|
|
|
|
static enum vkd3d_result sm6_parser_globals_init(struct sm6_parser *sm6)
|
|
{
|
|
+ size_t i, count, base_value_idx = sm6->value_count;
|
|
const struct dxil_block *block = &sm6->root_block;
|
|
struct vkd3d_shader_instruction *ins;
|
|
const struct dxil_record *record;
|
|
enum vkd3d_result ret;
|
|
uint64_t version;
|
|
- size_t i;
|
|
|
|
sm6->p.location.line = block->id;
|
|
sm6->p.location.column = 0;
|
|
|
|
+ for (i = 0, count = 0; i < block->record_count; ++i)
|
|
+ count += block->records[i]->code == MODULE_CODE_GLOBALVAR;
|
|
+ sm6_parser_require_space(sm6, count);
|
|
+
|
|
for (i = 0; i < block->record_count; ++i)
|
|
{
|
|
sm6->p.location.column = i;
|
|
@@ -2868,6 +2944,21 @@ static enum vkd3d_result sm6_parser_globals_init(struct sm6_parser *sm6)
|
|
ins->declaration.indexable_temp.initialiser = resolve_forward_initialiser(
|
|
(uintptr_t)ins->declaration.indexable_temp.initialiser, sm6);
|
|
}
|
|
+ else if (ins->handler_idx == VKD3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER)
|
|
+ {
|
|
+ ins->declaration.icb = resolve_forward_initialiser((uintptr_t)ins->declaration.icb, sm6);
|
|
+ }
|
|
+ }
|
|
+ for (i = base_value_idx; i < sm6->value_count; ++i)
|
|
+ {
|
|
+ const struct vkd3d_shader_immediate_constant_buffer *icb;
|
|
+ struct sm6_value *value = &sm6->values[i];
|
|
+
|
|
+ if (!sm6_value_is_register(value) || value->u.reg.type != VKD3DSPR_IMMCONSTBUFFER)
|
|
+ continue;
|
|
+
|
|
+ if ((icb = resolve_forward_initialiser(value->u.reg.idx[0].offset, sm6)))
|
|
+ value->u.reg.idx[0].offset = icb->register_idx;
|
|
}
|
|
|
|
return VKD3D_OK;
|
|
@@ -2908,45 +2999,6 @@ static void sm6_parser_init_signature(struct sm6_parser *sm6, const struct shade
|
|
}
|
|
}
|
|
|
|
-static void sm6_parser_emit_signature(struct sm6_parser *sm6, const struct shader_signature *s,
|
|
- enum vkd3d_shader_opcode handler_idx, enum vkd3d_shader_opcode siv_handler_idx,
|
|
- struct vkd3d_shader_dst_param *params)
|
|
-{
|
|
- struct vkd3d_shader_instruction *ins;
|
|
- struct vkd3d_shader_dst_param *param;
|
|
- const struct signature_element *e;
|
|
- unsigned int i;
|
|
-
|
|
- for (i = 0; i < s->element_count; ++i)
|
|
- {
|
|
- e = &s->elements[i];
|
|
-
|
|
- /* Do not check e->used_mask because in some cases it is zero for used elements.
|
|
- * TODO: scan ahead for used I/O elements. */
|
|
-
|
|
- if (e->sysval_semantic != VKD3D_SHADER_SV_NONE && e->sysval_semantic != VKD3D_SHADER_SV_TARGET)
|
|
- {
|
|
- ins = sm6_parser_add_instruction(sm6, siv_handler_idx);
|
|
- param = &ins->declaration.register_semantic.reg;
|
|
- ins->declaration.register_semantic.sysval_semantic = vkd3d_siv_from_sysval(e->sysval_semantic);
|
|
- }
|
|
- else
|
|
- {
|
|
- ins = sm6_parser_add_instruction(sm6, handler_idx);
|
|
- param = &ins->declaration.dst;
|
|
- }
|
|
-
|
|
- ins->flags = e->interpolation_mode;
|
|
- *param = params[i];
|
|
-
|
|
- if (e->register_count > 1)
|
|
- {
|
|
- param->reg.idx[0].rel_addr = NULL;
|
|
- param->reg.idx[0].offset = e->register_count;
|
|
- }
|
|
- }
|
|
-}
|
|
-
|
|
static void sm6_parser_init_output_signature(struct sm6_parser *sm6, const struct shader_signature *output_signature)
|
|
{
|
|
sm6_parser_init_signature(sm6, output_signature, VKD3DSPR_OUTPUT, sm6->output_params);
|
|
@@ -2957,19 +3009,6 @@ static void sm6_parser_init_input_signature(struct sm6_parser *sm6, const struct
|
|
sm6_parser_init_signature(sm6, input_signature, VKD3DSPR_INPUT, sm6->input_params);
|
|
}
|
|
|
|
-static void sm6_parser_emit_output_signature(struct sm6_parser *sm6, const struct shader_signature *output_signature)
|
|
-{
|
|
- sm6_parser_emit_signature(sm6, output_signature, VKD3DSIH_DCL_OUTPUT, VKD3DSIH_DCL_OUTPUT_SIV, sm6->output_params);
|
|
-}
|
|
-
|
|
-static void sm6_parser_emit_input_signature(struct sm6_parser *sm6, const struct shader_signature *input_signature)
|
|
-{
|
|
- sm6_parser_emit_signature(sm6, input_signature,
|
|
- (sm6->p.shader_version.type == VKD3D_SHADER_TYPE_PIXEL) ? VKD3DSIH_DCL_INPUT_PS : VKD3DSIH_DCL_INPUT,
|
|
- (sm6->p.shader_version.type == VKD3D_SHADER_TYPE_PIXEL) ? VKD3DSIH_DCL_INPUT_PS_SIV : VKD3DSIH_DCL_INPUT_SIV,
|
|
- sm6->input_params);
|
|
-}
|
|
-
|
|
static const struct sm6_value *sm6_parser_next_function_definition(struct sm6_parser *sm6)
|
|
{
|
|
size_t i, count = sm6->function_count;
|
|
@@ -2992,6 +3031,81 @@ static struct sm6_block *sm6_block_create()
|
|
return block;
|
|
}
|
|
|
|
+static void sm6_parser_emit_alloca(struct sm6_parser *sm6, const struct dxil_record *record,
|
|
+ struct vkd3d_shader_instruction *ins, struct sm6_value *dst)
|
|
+{
|
|
+ const struct sm6_type *type[2], *elem_type;
|
|
+ const struct sm6_value *size;
|
|
+ unsigned int i, alignment;
|
|
+ uint64_t packed_operands;
|
|
+
|
|
+ if (!dxil_record_validate_operand_count(record, 4, 4, sm6))
|
|
+ return;
|
|
+
|
|
+ for (i = 0; i < 2; ++i)
|
|
+ {
|
|
+ if (!(type[i] = sm6_parser_get_type(sm6, record->operands[i])))
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ packed_operands = record->operands[3];
|
|
+ if (packed_operands & ALLOCA_FLAG_IN_ALLOCA)
|
|
+ WARN("Ignoring in_alloca flag.\n");
|
|
+ if (!(packed_operands & ALLOCA_FLAG_EXPLICIT_TYPE))
|
|
+ {
|
|
+ FIXME("Unhandled implicit type.\n");
|
|
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
|
|
+ "Implicit result type for ALLOCA instructions is not supported.");
|
|
+ return;
|
|
+ }
|
|
+ packed_operands &= ~(ALLOCA_FLAG_IN_ALLOCA | ALLOCA_FLAG_EXPLICIT_TYPE);
|
|
+
|
|
+ if (!sm6_type_is_array(type[0]) || !sm6_type_is_numeric(elem_type = type[0]->u.array.elem_type))
|
|
+ {
|
|
+ WARN("Type is not a numeric array.\n");
|
|
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
|
|
+ "Result type of an ALLOCA instruction is not a numeric array.");
|
|
+ return;
|
|
+ }
|
|
+ /* The second type operand is the type of the allocation size operand, in case it is a
|
|
+ * forward reference. We only support a constant size, so no forward ref support is needed. */
|
|
+ if (!sm6_type_is_integer(type[1]))
|
|
+ {
|
|
+ WARN("Size operand type is not scalar integer.\n");
|
|
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
|
|
+ "The type of the allocation size operand of an ALLOCA instruction is not scalar integer.");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if (!(dst->type = sm6_type_get_pointer_to_type(type[0], ADDRESS_SPACE_DEFAULT, sm6)))
|
|
+ {
|
|
+ WARN("Failed to get pointer type for type class %u.\n", type[0]->class);
|
|
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_MODULE,
|
|
+ "Module does not define a pointer type for an ALLOCA instruction.");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if (!(size = sm6_parser_get_value_safe(sm6, record->operands[2])))
|
|
+ return;
|
|
+ /* A size of 1 means one instance of type[0], i.e. one array. */
|
|
+ if (sm6_value_get_constant_uint(size) != 1)
|
|
+ {
|
|
+ FIXME("Allocation size is not 1.\n");
|
|
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
|
|
+ "ALLOCA instruction allocation sizes other than 1 are not supported.");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if (!bitcode_parse_alignment(packed_operands & ALLOCA_ALIGNMENT_MASK, &alignment))
|
|
+ WARN("Invalid alignment %"PRIu64".\n", packed_operands);
|
|
+ packed_operands &= ~ALLOCA_ALIGNMENT_MASK;
|
|
+
|
|
+ if (packed_operands)
|
|
+ WARN("Ignoring flags %#"PRIx64".\n", packed_operands);
|
|
+
|
|
+ sm6_parser_declare_indexable_temp(sm6, elem_type, type[0]->u.array.count, alignment, 0, ins, dst);
|
|
+}
|
|
+
|
|
static enum vkd3d_shader_opcode map_binary_op(uint64_t code, const struct sm6_type *type_a,
|
|
const struct sm6_type *type_b, struct sm6_parser *sm6)
|
|
{
|
|
@@ -3092,8 +3206,10 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco
|
|
unsigned int i = 0;
|
|
|
|
a = sm6_parser_get_value_by_ref(sm6, record, NULL, &i);
|
|
+ if (!a)
|
|
+ return;
|
|
b = sm6_parser_get_value_by_ref(sm6, record, a->type, &i);
|
|
- if (!a || !b)
|
|
+ if (!b)
|
|
return;
|
|
|
|
if (!dxil_record_validate_operand_count(record, i + 1, i + 2, sm6))
|
|
@@ -3167,10 +3283,77 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco
|
|
}
|
|
else
|
|
{
|
|
+ if (handler_idx == VKD3DSIH_ISHL || handler_idx == VKD3DSIH_ISHR || handler_idx == VKD3DSIH_USHR)
|
|
+ {
|
|
+ /* DXC emits AND instructions where necessary to mask shift counts. Shift binops
|
|
+ * do not imply masking the shift as the TPF equivalents do. */
|
|
+ ins->flags |= VKD3DSI_SHIFT_UNMASKED;
|
|
+ }
|
|
instruction_dst_param_init_ssa_scalar(ins, sm6);
|
|
}
|
|
}
|
|
|
|
+static enum vkd3d_shader_opcode map_dx_unary_op(enum dx_intrinsic_opcode op)
|
|
+{
|
|
+ switch (op)
|
|
+ {
|
|
+ case DX_EXP:
|
|
+ return VKD3DSIH_EXP;
|
|
+ case DX_FRC:
|
|
+ return VKD3DSIH_FRC;
|
|
+ case DX_LOG:
|
|
+ return VKD3DSIH_LOG;
|
|
+ case DX_SQRT:
|
|
+ return VKD3DSIH_SQRT;
|
|
+ case DX_RSQRT:
|
|
+ return VKD3DSIH_RSQ;
|
|
+ case DX_ROUND_NE:
|
|
+ return VKD3DSIH_ROUND_NE;
|
|
+ case DX_ROUND_NI:
|
|
+ return VKD3DSIH_ROUND_NI;
|
|
+ case DX_ROUND_PI:
|
|
+ return VKD3DSIH_ROUND_PI;
|
|
+ case DX_ROUND_Z:
|
|
+ return VKD3DSIH_ROUND_Z;
|
|
+ case DX_BFREV:
|
|
+ return VKD3DSIH_BFREV;
|
|
+ case DX_COUNT_BITS:
|
|
+ return VKD3DSIH_COUNTBITS;
|
|
+ case DX_FIRST_BIT_LO:
|
|
+ return VKD3DSIH_FIRSTBIT_LO;
|
|
+ case DX_FIRST_BIT_HI:
|
|
+ return VKD3DSIH_FIRSTBIT_HI;
|
|
+ case DX_FIRST_BIT_SHI:
|
|
+ return VKD3DSIH_FIRSTBIT_SHI;
|
|
+ case DX_DERIV_COARSEX:
|
|
+ return VKD3DSIH_DSX_COARSE;
|
|
+ case DX_DERIV_COARSEY:
|
|
+ return VKD3DSIH_DSY_COARSE;
|
|
+ case DX_DERIV_FINEX:
|
|
+ return VKD3DSIH_DSX_FINE;
|
|
+ case DX_DERIV_FINEY:
|
|
+ return VKD3DSIH_DSY_FINE;
|
|
+ case DX_LEGACY_F32TOF16:
|
|
+ return VKD3DSIH_F32TOF16;
|
|
+ case DX_LEGACY_F16TOF32:
|
|
+ return VKD3DSIH_F16TOF32;
|
|
+ default:
|
|
+ vkd3d_unreachable();
|
|
+ }
|
|
+}
|
|
+
|
|
+static void sm6_parser_emit_dx_unary(struct sm6_parser *sm6, struct sm6_block *code_block,
|
|
+ enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct vkd3d_shader_instruction *ins)
|
|
+{
|
|
+ struct vkd3d_shader_src_param *src_param;
|
|
+
|
|
+ vsir_instruction_init(ins, &sm6->p.location, map_dx_unary_op(op));
|
|
+ src_param = instruction_src_params_alloc(ins, 1, sm6);
|
|
+ src_param_init_from_value(src_param, operands[0]);
|
|
+
|
|
+ instruction_dst_param_init_ssa_scalar(ins, sm6);
|
|
+}
|
|
+
|
|
static void sm6_parser_emit_dx_cbuffer_load(struct sm6_parser *sm6, struct sm6_block *code_block,
|
|
enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct vkd3d_shader_instruction *ins)
|
|
{
|
|
@@ -3344,7 +3527,7 @@ static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, struct sm6_b
|
|
|
|
struct sm6_dx_opcode_info
|
|
{
|
|
- const char ret_type;
|
|
+ const char *ret_type;
|
|
const char *operand_info;
|
|
void (*handler)(struct sm6_parser *, struct sm6_block *, enum dx_intrinsic_opcode,
|
|
const struct sm6_value **, struct vkd3d_shader_instruction *);
|
|
@@ -3355,16 +3538,40 @@ struct sm6_dx_opcode_info
|
|
b -> constant int1
|
|
c -> constant int8/16/32
|
|
i -> int32
|
|
+ m -> int16/32/64
|
|
+ f -> float
|
|
+ e -> half/float
|
|
+ g -> half/float/double
|
|
H -> handle
|
|
v -> void
|
|
o -> overloaded
|
|
*/
|
|
static const struct sm6_dx_opcode_info sm6_dx_op_table[] =
|
|
{
|
|
- [DX_CBUFFER_LOAD_LEGACY ] = {'o', "Hi", sm6_parser_emit_dx_cbuffer_load},
|
|
- [DX_CREATE_HANDLE ] = {'H', "ccib", sm6_parser_emit_dx_create_handle},
|
|
- [DX_LOAD_INPUT ] = {'o', "ii8i", sm6_parser_emit_dx_load_input},
|
|
- [DX_STORE_OUTPUT ] = {'v', "ii8o", sm6_parser_emit_dx_store_output},
|
|
+ [DX_BFREV ] = {"m0", "m", sm6_parser_emit_dx_unary},
|
|
+ [DX_CBUFFER_LOAD_LEGACY ] = {"o", "Hi", sm6_parser_emit_dx_cbuffer_load},
|
|
+ [DX_COUNT_BITS ] = {"i", "m", sm6_parser_emit_dx_unary},
|
|
+ [DX_CREATE_HANDLE ] = {"H", "ccib", sm6_parser_emit_dx_create_handle},
|
|
+ [DX_DERIV_COARSEX ] = {"e0", "e", sm6_parser_emit_dx_unary},
|
|
+ [DX_DERIV_COARSEY ] = {"e0", "e", sm6_parser_emit_dx_unary},
|
|
+ [DX_DERIV_FINEX ] = {"e0", "e", sm6_parser_emit_dx_unary},
|
|
+ [DX_DERIV_FINEY ] = {"e0", "e", sm6_parser_emit_dx_unary},
|
|
+ [DX_EXP ] = {"g0", "g", sm6_parser_emit_dx_unary},
|
|
+ [DX_FIRST_BIT_HI ] = {"i", "m", sm6_parser_emit_dx_unary},
|
|
+ [DX_FIRST_BIT_LO ] = {"i", "m", sm6_parser_emit_dx_unary},
|
|
+ [DX_FIRST_BIT_SHI ] = {"i", "m", sm6_parser_emit_dx_unary},
|
|
+ [DX_FRC ] = {"g0", "g", sm6_parser_emit_dx_unary},
|
|
+ [DX_LEGACY_F16TOF32 ] = {"f", "i", sm6_parser_emit_dx_unary},
|
|
+ [DX_LEGACY_F32TOF16 ] = {"i", "f", sm6_parser_emit_dx_unary},
|
|
+ [DX_LOAD_INPUT ] = {"o", "ii8i", sm6_parser_emit_dx_load_input},
|
|
+ [DX_LOG ] = {"g0", "g", sm6_parser_emit_dx_unary},
|
|
+ [DX_ROUND_NE ] = {"g0", "g", sm6_parser_emit_dx_unary},
|
|
+ [DX_ROUND_NI ] = {"g0", "g", sm6_parser_emit_dx_unary},
|
|
+ [DX_ROUND_PI ] = {"g0", "g", sm6_parser_emit_dx_unary},
|
|
+ [DX_ROUND_Z ] = {"g0", "g", sm6_parser_emit_dx_unary},
|
|
+ [DX_RSQRT ] = {"g0", "g", sm6_parser_emit_dx_unary},
|
|
+ [DX_SQRT ] = {"g0", "g", sm6_parser_emit_dx_unary},
|
|
+ [DX_STORE_OUTPUT ] = {"v", "ii8o", sm6_parser_emit_dx_store_output},
|
|
};
|
|
|
|
static bool sm6_parser_validate_operand_type(struct sm6_parser *sm6, const struct sm6_value *value, char info_type,
|
|
@@ -3389,6 +3596,14 @@ static bool sm6_parser_validate_operand_type(struct sm6_parser *sm6, const struc
|
|
&& type->u.width <= 32;
|
|
case 'i':
|
|
return sm6_type_is_i32(type);
|
|
+ case 'm':
|
|
+ return sm6_type_is_i16_i32_i64(type);
|
|
+ case 'f':
|
|
+ return sm6_type_is_float(type);
|
|
+ case 'e':
|
|
+ return sm6_type_is_f16_f32(type);
|
|
+ case 'g':
|
|
+ return sm6_type_is_floating_point(type);
|
|
case 'H':
|
|
return (is_return || sm6_value_is_handle(value)) && type == sm6->handle_type;
|
|
case 'v':
|
|
@@ -3402,6 +3617,17 @@ static bool sm6_parser_validate_operand_type(struct sm6_parser *sm6, const struc
|
|
}
|
|
}
|
|
|
|
+static bool operand_types_match(struct sm6_value *dst, const struct sm6_value **operands, unsigned int operand_count,
|
|
+ char index_char)
|
|
+{
|
|
+ unsigned int i = index_char - '0';
|
|
+
|
|
+ assert(i < 10);
|
|
+ if (i >= operand_count)
|
|
+ return false;
|
|
+ return dst->type == operands[i]->type;
|
|
+}
|
|
+
|
|
static bool sm6_parser_validate_dx_op(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const char *name,
|
|
const struct sm6_value **operands, unsigned int operand_count, struct sm6_value *dst)
|
|
{
|
|
@@ -3410,7 +3636,9 @@ static bool sm6_parser_validate_dx_op(struct sm6_parser *sm6, enum dx_intrinsic_
|
|
|
|
info = &sm6_dx_op_table[op];
|
|
|
|
- if (!sm6_parser_validate_operand_type(sm6, dst, info->ret_type, true))
|
|
+ assert(info->ret_type[0]);
|
|
+ if (!sm6_parser_validate_operand_type(sm6, dst, info->ret_type[0], true)
|
|
+ || (info->ret_type[1] && !operand_types_match(dst, operands, operand_count, info->ret_type[1])))
|
|
{
|
|
WARN("Failed to validate return type for dx intrinsic id %u, '%s'.\n", op, name);
|
|
/* Return type validation failure is not so critical. We only need to set
|
|
@@ -3700,6 +3928,9 @@ static void sm6_parser_emit_cast(struct sm6_parser *sm6, const struct dxil_recor
|
|
if (handler_idx == VKD3DSIH_NOP)
|
|
{
|
|
dst->u.reg = value->u.reg;
|
|
+ /* Set the result type for casts from 16-bit min precision. */
|
|
+ if (type->u.width != 16)
|
|
+ dst->u.reg.data_type = vkd3d_data_type_from_sm6_type(type);
|
|
return;
|
|
}
|
|
|
|
@@ -3775,8 +4006,10 @@ static void sm6_parser_emit_cmp2(struct sm6_parser *sm6, const struct dxil_recor
|
|
}
|
|
|
|
a = sm6_parser_get_value_by_ref(sm6, record, NULL, &i);
|
|
+ if (!a)
|
|
+ return;
|
|
b = sm6_parser_get_value_by_ref(sm6, record, a->type, &i);
|
|
- if (!a || !b)
|
|
+ if (!b)
|
|
return;
|
|
|
|
if (!dxil_record_validate_operand_count(record, i + 1, i + 2, sm6))
|
|
@@ -4065,6 +4298,57 @@ static void sm6_parser_emit_ret(struct sm6_parser *sm6, const struct dxil_record
|
|
ins->handler_idx = VKD3DSIH_NOP;
|
|
}
|
|
|
|
+static void sm6_parser_emit_store(struct sm6_parser *sm6, const struct dxil_record *record,
|
|
+ struct vkd3d_shader_instruction *ins, struct sm6_value *dst)
|
|
+{
|
|
+ struct vkd3d_shader_src_param *src_param;
|
|
+ struct vkd3d_shader_dst_param *dst_param;
|
|
+ const struct sm6_type *pointee_type;
|
|
+ const struct sm6_value *ptr, *src;
|
|
+ unsigned int i = 0, alignment;
|
|
+ uint64_t alignment_code;
|
|
+
|
|
+ if (!(ptr = sm6_parser_get_value_by_ref(sm6, record, NULL, &i))
|
|
+ || !sm6_value_validate_is_register(ptr, sm6)
|
|
+ || !sm6_value_validate_is_pointer(ptr, sm6))
|
|
+ {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ pointee_type = ptr->type->u.pointer.type;
|
|
+ if (!(src = sm6_parser_get_value_by_ref(sm6, record, pointee_type, &i)))
|
|
+ return;
|
|
+ if (!sm6_value_validate_is_numeric(src, sm6))
|
|
+ return;
|
|
+
|
|
+ if (pointee_type != src->type)
|
|
+ {
|
|
+ WARN("Type mismatch.\n");
|
|
+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_TYPE_MISMATCH,
|
|
+ "Type mismatch in pointer store arguments.");
|
|
+ }
|
|
+
|
|
+ if (!dxil_record_validate_operand_count(record, i + 2, i + 2, sm6))
|
|
+ return;
|
|
+
|
|
+ alignment_code = record->operands[i++];
|
|
+ if (!bitcode_parse_alignment(alignment_code, &alignment))
|
|
+ WARN("Invalid alignment %"PRIu64".\n", alignment_code);
|
|
+
|
|
+ if (record->operands[i])
|
|
+ WARN("Ignoring volatile modifier.\n");
|
|
+
|
|
+ vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV);
|
|
+
|
|
+ src_param = instruction_src_params_alloc(ins, 1, sm6);
|
|
+ src_param_init_from_value(&src_param[0], src);
|
|
+
|
|
+ dst_param = instruction_dst_params_alloc(ins, 1, sm6);
|
|
+ dst_param_init(dst_param);
|
|
+ dst_param->reg = ptr->u.reg;
|
|
+ dst_param->reg.alignment = alignment;
|
|
+}
|
|
+
|
|
static void sm6_parser_emit_vselect(struct sm6_parser *sm6, const struct dxil_record *record,
|
|
struct vkd3d_shader_instruction *ins, struct sm6_value *dst)
|
|
{
|
|
@@ -4153,6 +4437,208 @@ static bool sm6_metadata_get_uint64_value(const struct sm6_parser *sm6,
|
|
return true;
|
|
}
|
|
|
|
+static void sm6_parser_metadata_attachment_block_init(struct sm6_parser *sm6, const struct dxil_block *target_block,
|
|
+ const struct dxil_block *block)
|
|
+{
|
|
+ struct dxil_record *target_record;
|
|
+ const struct dxil_record *record;
|
|
+ unsigned int i;
|
|
+ uint64_t index;
|
|
+
|
|
+ for (i = 0; i < block->record_count; ++i)
|
|
+ {
|
|
+ record = block->records[i];
|
|
+ if (record->code != METADATA_ATTACHMENT)
|
|
+ {
|
|
+ WARN("Ignoring record with code %u.\n", record->code);
|
|
+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_ATTACHMENT,
|
|
+ "Ignoring a metadata attachment record with code %u.", record->code);
|
|
+ continue;
|
|
+ }
|
|
+ if (!(record->operand_count & 1))
|
|
+ {
|
|
+ WARN("Ignoring function attachment.\n");
|
|
+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_ATTACHMENT,
|
|
+ "Ignoring a metadata function attachment.");
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ index = record->operands[0];
|
|
+ if (!target_block->record_count || index >= target_block->record_count - 1)
|
|
+ {
|
|
+ WARN("Invalid record index %"PRIu64".\n", index);
|
|
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
|
|
+ "Invalid record index %"PRIu64" for a metadata attachment.", index);
|
|
+ continue;
|
|
+ }
|
|
+ /* 'index' is an instruction index, but records[0] is DECLAREBLOCKS, not an instruction. */
|
|
+ target_record = target_block->records[index + 1];
|
|
+ if (target_record->attachment)
|
|
+ {
|
|
+ WARN("Overwriting record attachment.\n");
|
|
+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_ATTACHMENT,
|
|
+ "The target record for a metadata attachment already has an attachment.");
|
|
+ }
|
|
+ target_record->attachment = record;
|
|
+ }
|
|
+}
|
|
+
|
|
+static void sm6_parser_metadata_attachments_init(struct sm6_parser *sm6, const struct dxil_block *block)
|
|
+{
|
|
+ unsigned int i;
|
|
+
|
|
+ for (i = 0; i < block->child_block_count; ++i)
|
|
+ {
|
|
+ if (block->child_blocks[i]->id == METADATA_ATTACHMENT_BLOCK)
|
|
+ sm6_parser_metadata_attachment_block_init(sm6, block, block->child_blocks[i]);
|
|
+ }
|
|
+}
|
|
+
|
|
+static const struct sm6_metadata_value *sm6_parser_find_metadata_kind(const struct sm6_parser *sm6, uint64_t id)
|
|
+{
|
|
+ unsigned int i, j;
|
|
+
|
|
+ for (i = 0; i < ARRAY_SIZE(sm6->metadata_tables); ++i)
|
|
+ {
|
|
+ for (j = 0; j < sm6->metadata_tables[i].count; ++j)
|
|
+ {
|
|
+ if (sm6->metadata_tables[i].values[j].type == VKD3D_METADATA_KIND
|
|
+ && sm6->metadata_tables[i].values[j].u.kind.id == id)
|
|
+ return &sm6->metadata_tables[i].values[j];
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return NULL;
|
|
+}
|
|
+
|
|
+static const struct sm6_metadata_value *sm6_parser_metadata_get_value(const struct sm6_parser *sm6, uint64_t index)
|
|
+{
|
|
+ unsigned int i;
|
|
+
|
|
+ for (i = 0; i < ARRAY_SIZE(sm6->metadata_tables); ++i)
|
|
+ {
|
|
+ if (sm6->metadata_tables[i].count > index)
|
|
+ break;
|
|
+ index -= sm6->metadata_tables[i].count;
|
|
+ }
|
|
+
|
|
+ return (index < sm6->metadata_tables[i].count) ? &sm6->metadata_tables[i].values[index] : NULL;
|
|
+}
|
|
+
|
|
+static bool metadata_node_get_unary_uint(const struct sm6_metadata_node *node, unsigned int *operand,
|
|
+ struct sm6_parser *sm6)
|
|
+{
|
|
+ if (node->operand_count != 1)
|
|
+ {
|
|
+ FIXME("Ignoring node with %u operands.\n", node->operand_count);
|
|
+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_ATTACHMENT,
|
|
+ "Ignoring metadata attachment node with %u operands; expected unary.", node->operand_count);
|
|
+ return false;
|
|
+ }
|
|
+ if (!sm6_metadata_value_is_value(node->operands[0])
|
|
+ || !sm6_metadata_get_uint_value(sm6, node->operands[0], operand))
|
|
+ {
|
|
+ WARN("Failed to get operand value.\n");
|
|
+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_ATTACHMENT,
|
|
+ "Failed to get a metadata attachment operand value; ignoring the attachment.");
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ return true;
|
|
+}
|
|
+
|
|
+static void metadata_attachment_record_apply(const struct dxil_record *record, enum bitcode_function_code func_code,
|
|
+ struct vkd3d_shader_instruction *ins, struct sm6_value *dst, struct sm6_parser *sm6)
|
|
+{
|
|
+ static const char *ignored_names[] =
|
|
+ {
|
|
+ "alias.scope",
|
|
+ "dx.controlflow.hints",
|
|
+ "llvm.loop",
|
|
+ "noalias",
|
|
+ "tbaa",
|
|
+ "range",
|
|
+ };
|
|
+ const struct sm6_metadata_node *node;
|
|
+ const struct sm6_metadata_value *m;
|
|
+ unsigned int i, j, operand;
|
|
+ bool ignored = false;
|
|
+ const char *name;
|
|
+
|
|
+ if (record->attachment)
|
|
+ {
|
|
+ WARN("Ignoring nested metadata attachment.\n");
|
|
+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_ATTACHMENT,
|
|
+ "Ignoring a nested metadata attachment.");
|
|
+ }
|
|
+
|
|
+ assert(record->operand_count & 1);
|
|
+ for (i = 1; i < record->operand_count; i += 2)
|
|
+ {
|
|
+ if (!(m = sm6_parser_find_metadata_kind(sm6, record->operands[i])))
|
|
+ {
|
|
+ WARN("Failed to find metadata kind %"PRIx64".\n", record->operands[i]);
|
|
+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_ATTACHMENT,
|
|
+ "Failed to find metadata kind %"PRIx64" for an attachment.", record->operands[i]);
|
|
+ continue;
|
|
+ }
|
|
+ name = m->u.kind.name;
|
|
+
|
|
+ m = sm6_parser_metadata_get_value(sm6, record->operands[i + 1]);
|
|
+ if (!m || !sm6_metadata_value_is_node(m))
|
|
+ {
|
|
+ WARN("Failed to retrieve metadata attachment node.\n");
|
|
+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_ATTACHMENT,
|
|
+ "Failed to retrieve a metadata attachment node.");
|
|
+ continue;
|
|
+ }
|
|
+ node = m->u.node;
|
|
+
|
|
+ if (!strcmp(name, "dx.precise"))
|
|
+ {
|
|
+ if (!sm6_value_is_register(dst))
|
|
+ {
|
|
+ WARN("Precise value is not a register.\n");
|
|
+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_ATTACHMENT,
|
|
+ "A value marked as precise is not a register.");
|
|
+ }
|
|
+ else if (metadata_node_get_unary_uint(node, &operand, sm6) && operand)
|
|
+ {
|
|
+ ins->flags |= sm6_type_is_scalar(dst->type) ? VKD3DSI_PRECISE_X : VKD3DSI_PRECISE_XYZW;
|
|
+ }
|
|
+ }
|
|
+ else if (!strcmp(name, "dx.nonuniform"))
|
|
+ {
|
|
+ if (!sm6_value_is_register(dst))
|
|
+ {
|
|
+ WARN("Non-uniform value is not a register.\n");
|
|
+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_ATTACHMENT,
|
|
+ "A value marked as non-uniform is not a register.");
|
|
+ }
|
|
+ else if (metadata_node_get_unary_uint(node, &operand, sm6))
|
|
+ {
|
|
+ dst->u.reg.non_uniform = !!operand;
|
|
+ }
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ for (j = 0; j < ARRAY_SIZE(ignored_names); ++j)
|
|
+ if (!strcmp(name, ignored_names[j]))
|
|
+ break;
|
|
+ if (j == ARRAY_SIZE(ignored_names))
|
|
+ {
|
|
+ WARN("Ignoring metadata attachment '%s'.\n", name);
|
|
+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_ATTACHMENT,
|
|
+ "Ignoring a metadata attachment named '%s'.", name);
|
|
+ }
|
|
+ ignored = true;
|
|
+ }
|
|
+
|
|
+ if (func_code != FUNC_CODE_INST_CALL && !ignored)
|
|
+ WARN("Metadata attachment target is not a function call.\n");
|
|
+ }
|
|
+}
|
|
+
|
|
static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const struct dxil_block *block,
|
|
struct sm6_function *function)
|
|
{
|
|
@@ -4240,6 +4726,9 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const
|
|
record = block->records[i];
|
|
switch (record->code)
|
|
{
|
|
+ case FUNC_CODE_INST_ALLOCA:
|
|
+ sm6_parser_emit_alloca(sm6, record, ins, dst);
|
|
+ break;
|
|
case FUNC_CODE_INST_BINOP:
|
|
sm6_parser_emit_binop(sm6, record, ins, dst);
|
|
break;
|
|
@@ -4266,6 +4755,9 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const
|
|
is_terminator = true;
|
|
ret_found = true;
|
|
break;
|
|
+ case FUNC_CODE_INST_STORE:
|
|
+ sm6_parser_emit_store(sm6, record, ins, dst);
|
|
+ break;
|
|
case FUNC_CODE_INST_VSELECT:
|
|
sm6_parser_emit_vselect(sm6, record, ins, dst);
|
|
break;
|
|
@@ -4278,6 +4770,9 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const
|
|
return VKD3D_ERROR;
|
|
assert(ins->handler_idx != VKD3DSIH_INVALID);
|
|
|
|
+ if (record->attachment)
|
|
+ metadata_attachment_record_apply(record->attachment, record->code, ins, dst, sm6);
|
|
+
|
|
if (is_terminator)
|
|
{
|
|
++block_idx;
|
|
@@ -4331,6 +4826,8 @@ static enum vkd3d_result sm6_parser_module_init(struct sm6_parser *sm6, const st
|
|
sm6->p.location.line = block->id;
|
|
sm6->p.location.column = 0;
|
|
|
|
+ sm6_parser_metadata_attachments_init(sm6, block);
|
|
+
|
|
switch (block->id)
|
|
{
|
|
case CONSTANTS_BLOCK:
|
|
@@ -4645,7 +5142,7 @@ static const enum vkd3d_shader_sysval_semantic sysval_semantic_table[] =
|
|
{
|
|
[SEMANTIC_KIND_ARBITRARY] = VKD3D_SHADER_SV_NONE,
|
|
[SEMANTIC_KIND_POSITION] = VKD3D_SHADER_SV_POSITION,
|
|
- [SEMANTIC_KIND_TARGET] = VKD3D_SHADER_SV_NONE,
|
|
+ [SEMANTIC_KIND_TARGET] = VKD3D_SHADER_SV_TARGET,
|
|
};
|
|
|
|
static enum vkd3d_shader_sysval_semantic sysval_semantic_from_dxil_semantic_kind(enum dxil_semantic_kind kind)
|
|
@@ -5538,7 +6035,7 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t
|
|
if ((magic = sm6->start[0]) != BITCODE_MAGIC)
|
|
{
|
|
WARN("Unknown magic number 0x%08x.\n", magic);
|
|
- vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_UNKNOWN_MAGIC_NUMBER,
|
|
+ vkd3d_shader_warning(message_context, &location, VKD3D_SHADER_WARNING_DXIL_UNKNOWN_MAGIC_NUMBER,
|
|
"DXIL bitcode chunk magic number 0x%08x is not the expected 0x%08x.", magic, BITCODE_MAGIC);
|
|
}
|
|
|
|
@@ -5547,7 +6044,7 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t
|
|
if ((version.type = version_token >> 16) >= VKD3D_SHADER_TYPE_COUNT)
|
|
{
|
|
FIXME("Unknown shader type %#x.\n", version.type);
|
|
- vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_UNKNOWN_SHADER_TYPE,
|
|
+ vkd3d_shader_warning(message_context, &location, VKD3D_SHADER_WARNING_DXIL_UNKNOWN_SHADER_TYPE,
|
|
"Unknown shader type %#x.", version.type);
|
|
}
|
|
|
|
@@ -5573,10 +6070,10 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t
|
|
if ((ret = dxil_block_init(block, NULL, sm6)) < 0)
|
|
{
|
|
if (ret == VKD3D_ERROR_OUT_OF_MEMORY)
|
|
- vkd3d_shader_error(message_context, &location, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY,
|
|
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY,
|
|
"Out of memory parsing DXIL bitcode chunk.");
|
|
else if (ret == VKD3D_ERROR_INVALID_SHADER)
|
|
- vkd3d_shader_error(message_context, &location, VKD3D_SHADER_ERROR_DXIL_INVALID_BITCODE,
|
|
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_BITCODE,
|
|
"DXIL bitcode chunk has invalid bitcode.");
|
|
else
|
|
vkd3d_unreachable();
|
|
@@ -5606,10 +6103,10 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t
|
|
if ((ret = sm6_parser_type_table_init(sm6)) < 0)
|
|
{
|
|
if (ret == VKD3D_ERROR_OUT_OF_MEMORY)
|
|
- vkd3d_shader_error(message_context, &location, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY,
|
|
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY,
|
|
"Out of memory parsing DXIL type table.");
|
|
else if (ret == VKD3D_ERROR_INVALID_SHADER)
|
|
- vkd3d_shader_error(message_context, &location, VKD3D_SHADER_ERROR_DXIL_INVALID_TYPE_TABLE,
|
|
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_TYPE_TABLE,
|
|
"DXIL type table is invalid.");
|
|
else
|
|
vkd3d_unreachable();
|
|
@@ -5619,10 +6116,10 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t
|
|
if ((ret = sm6_parser_symtab_init(sm6)) < 0)
|
|
{
|
|
if (ret == VKD3D_ERROR_OUT_OF_MEMORY)
|
|
- vkd3d_shader_error(message_context, &location, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY,
|
|
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY,
|
|
"Out of memory parsing DXIL value symbol table.");
|
|
else if (ret == VKD3D_ERROR_INVALID_SHADER)
|
|
- vkd3d_shader_error(message_context, &location, VKD3D_SHADER_ERROR_DXIL_INVALID_VALUE_SYMTAB,
|
|
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_VALUE_SYMTAB,
|
|
"DXIL value symbol table is invalid.");
|
|
else
|
|
vkd3d_unreachable();
|
|
@@ -5633,7 +6130,7 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t
|
|
|| !(sm6->input_params = shader_parser_get_dst_params(&sm6->p, input_signature->element_count)))
|
|
{
|
|
ERR("Failed to allocate input/output parameters.\n");
|
|
- vkd3d_shader_error(message_context, &location, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY,
|
|
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY,
|
|
"Out of memory allocating input/output parameters.");
|
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
}
|
|
@@ -5642,7 +6139,7 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t
|
|
if (!(sm6->functions = vkd3d_calloc(function_count, sizeof(*sm6->functions))))
|
|
{
|
|
ERR("Failed to allocate function array.\n");
|
|
- vkd3d_shader_error(message_context, &location, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY,
|
|
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY,
|
|
"Out of memory allocating DXIL function array.");
|
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
}
|
|
@@ -5650,14 +6147,14 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t
|
|
if (sm6_parser_compute_max_value_count(sm6, &sm6->root_block, 0) == SIZE_MAX)
|
|
{
|
|
WARN("Value array count overflowed.\n");
|
|
- vkd3d_shader_error(message_context, &location, VKD3D_SHADER_ERROR_DXIL_INVALID_MODULE,
|
|
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_MODULE,
|
|
"Overflow occurred in the DXIL module value count.");
|
|
return VKD3D_ERROR_INVALID_SHADER;
|
|
}
|
|
if (!(sm6->values = vkd3d_calloc(sm6->value_capacity, sizeof(*sm6->values))))
|
|
{
|
|
ERR("Failed to allocate value array.\n");
|
|
- vkd3d_shader_error(message_context, &location, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY,
|
|
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY,
|
|
"Out of memory allocating DXIL value array.");
|
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
}
|
|
@@ -5684,7 +6181,7 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t
|
|
if (j == ARRAY_SIZE(sm6->metadata_tables))
|
|
{
|
|
FIXME("Too many metadata tables.\n");
|
|
- vkd3d_shader_error(message_context, &location, VKD3D_SHADER_ERROR_DXIL_INVALID_METADATA,
|
|
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_METADATA,
|
|
"A metadata table count greater than %zu is unsupported.", ARRAY_SIZE(sm6->metadata_tables));
|
|
return VKD3D_ERROR_INVALID_SHADER;
|
|
}
|
|
@@ -5702,22 +6199,20 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t
|
|
if ((ret = sm6_parser_module_init(sm6, &sm6->root_block, 0)) < 0)
|
|
{
|
|
if (ret == VKD3D_ERROR_OUT_OF_MEMORY)
|
|
- vkd3d_shader_error(message_context, &location, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY,
|
|
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY,
|
|
"Out of memory parsing DXIL module.");
|
|
else if (ret == VKD3D_ERROR_INVALID_SHADER)
|
|
- vkd3d_shader_error(message_context, &location, VKD3D_SHADER_ERROR_DXIL_INVALID_MODULE,
|
|
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_MODULE,
|
|
"DXIL module is invalid.");
|
|
return ret;
|
|
}
|
|
|
|
if (!sm6_parser_require_space(sm6, output_signature->element_count + input_signature->element_count))
|
|
{
|
|
- vkd3d_shader_error(message_context, &location, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY,
|
|
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY,
|
|
"Out of memory emitting shader signature declarations.");
|
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
}
|
|
- sm6_parser_emit_output_signature(sm6, output_signature);
|
|
- sm6_parser_emit_input_signature(sm6, input_signature);
|
|
|
|
sm6->p.shader_desc.ssa_count = sm6->ssa_next_id;
|
|
|
|
@@ -5732,7 +6227,7 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t
|
|
assert(sm6->function_count == 1);
|
|
if (!sm6_block_emit_instructions(fn->blocks[0], sm6))
|
|
{
|
|
- vkd3d_shader_error(message_context, &location, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY,
|
|
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY,
|
|
"Out of memory emitting shader instructions.");
|
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
}
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y
|
|
index 0dde4c18587..ed053f16312 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y
|
|
@@ -487,27 +487,27 @@ static void resolve_loop_continue(struct hlsl_ctx *ctx, struct hlsl_block *block
|
|
else if (instr->type == HLSL_IR_JUMP)
|
|
{
|
|
struct hlsl_ir_jump *jump = hlsl_ir_jump(instr);
|
|
- struct hlsl_block block;
|
|
+ struct hlsl_block cond_block;
|
|
|
|
if (jump->type != HLSL_IR_JUMP_UNRESOLVED_CONTINUE)
|
|
continue;
|
|
|
|
if (type == LOOP_DO_WHILE)
|
|
{
|
|
- if (!hlsl_clone_block(ctx, &block, cond))
|
|
+ if (!hlsl_clone_block(ctx, &cond_block, cond))
|
|
return;
|
|
- if (!append_conditional_break(ctx, &block))
|
|
+ if (!append_conditional_break(ctx, &cond_block))
|
|
{
|
|
- hlsl_block_cleanup(&block);
|
|
+ hlsl_block_cleanup(&cond_block);
|
|
return;
|
|
}
|
|
- list_move_before(&instr->entry, &block.instrs);
|
|
+ list_move_before(&instr->entry, &cond_block.instrs);
|
|
}
|
|
else if (type == LOOP_FOR)
|
|
{
|
|
- if (!hlsl_clone_block(ctx, &block, iter))
|
|
+ if (!hlsl_clone_block(ctx, &cond_block, iter))
|
|
return;
|
|
- list_move_before(&instr->entry, &block.instrs);
|
|
+ list_move_before(&instr->entry, &cond_block.instrs);
|
|
}
|
|
jump->type = HLSL_IR_JUMP_CONTINUE;
|
|
}
|
|
@@ -3553,7 +3553,7 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer *
|
|
{
|
|
struct hlsl_resource_load_params load_params = { 0 };
|
|
const struct hlsl_type *sampler_type;
|
|
- struct hlsl_ir_node *coords, *load;
|
|
+ struct hlsl_ir_node *coords, *sample;
|
|
|
|
if (params->args_count != 2 && params->args_count != 4)
|
|
{
|
|
@@ -3688,9 +3688,9 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer *
|
|
load_params.format = hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, 4);
|
|
load_params.sampling_dim = dim;
|
|
|
|
- if (!(load = hlsl_new_resource_load(ctx, &load_params, loc)))
|
|
+ if (!(sample = hlsl_new_resource_load(ctx, &load_params, loc)))
|
|
return false;
|
|
- hlsl_block_add_instr(params->instrs, load);
|
|
+ hlsl_block_add_instr(params->instrs, sample);
|
|
return true;
|
|
}
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
|
|
index 4a622185741..88cbef61d5f 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
|
|
@@ -1090,7 +1090,7 @@ static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr,
|
|
unsigned int dim_count = hlsl_sampler_dim_count(val->data_type->sampler_dim);
|
|
struct hlsl_ir_node *coords = index->idx.node;
|
|
struct hlsl_resource_load_params params = {0};
|
|
- struct hlsl_ir_node *load;
|
|
+ struct hlsl_ir_node *resource_load;
|
|
|
|
assert(coords->data_type->class == HLSL_CLASS_VECTOR);
|
|
assert(coords->data_type->base_type == HLSL_TYPE_UINT);
|
|
@@ -1104,9 +1104,9 @@ static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr,
|
|
params.coords = coords;
|
|
params.format = val->data_type->e.resource_format;
|
|
|
|
- if (!(load = hlsl_new_resource_load(ctx, ¶ms, &instr->loc)))
|
|
+ if (!(resource_load = hlsl_new_resource_load(ctx, ¶ms, &instr->loc)))
|
|
return false;
|
|
- hlsl_block_add_instr(block, load);
|
|
+ hlsl_block_add_instr(block, resource_load);
|
|
return true;
|
|
}
|
|
|
|
@@ -2301,7 +2301,6 @@ static bool normalize_switch_cases(struct hlsl_ctx *ctx, struct hlsl_ir_node *in
|
|
struct hlsl_ir_switch_case *c, *def = NULL;
|
|
bool missing_terminal_break = false;
|
|
struct hlsl_ir_node *node;
|
|
- struct hlsl_ir_jump *jump;
|
|
struct hlsl_ir_switch *s;
|
|
|
|
if (instr->type != HLSL_IR_SWITCH)
|
|
@@ -2320,10 +2319,7 @@ static bool normalize_switch_cases(struct hlsl_ctx *ctx, struct hlsl_ir_node *in
|
|
{
|
|
node = LIST_ENTRY(list_tail(&c->body.instrs), struct hlsl_ir_node, entry);
|
|
if (node->type == HLSL_IR_JUMP)
|
|
- {
|
|
- jump = hlsl_ir_jump(node);
|
|
- terminal_break = jump->type == HLSL_IR_JUMP_BREAK;
|
|
- }
|
|
+ terminal_break = (hlsl_ir_jump(node)->type == HLSL_IR_JUMP_BREAK);
|
|
}
|
|
|
|
missing_terminal_break |= !terminal_break;
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c
|
|
index 710811c6761..d38b3c39712 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/ir.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c
|
|
@@ -63,7 +63,7 @@ static void shader_instruction_eliminate_phase_instance_id(struct vkd3d_shader_i
|
|
if (shader_register_is_phase_instance_id(reg))
|
|
{
|
|
vsir_register_init(reg, VKD3DSPR_IMMCONST, reg->data_type, 0);
|
|
- reg->u.immconst_uint[0] = instance_id;
|
|
+ reg->u.immconst_u32[0] = instance_id;
|
|
continue;
|
|
}
|
|
shader_register_eliminate_phase_addressing(reg, instance_id);
|
|
@@ -463,6 +463,7 @@ static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_i
|
|
struct vkd3d_shader_instruction_array *instructions;
|
|
struct control_point_normaliser normaliser;
|
|
unsigned int input_control_point_count;
|
|
+ struct vkd3d_shader_location location;
|
|
struct vkd3d_shader_instruction *ins;
|
|
enum vkd3d_result ret;
|
|
unsigned int i, j;
|
|
@@ -513,8 +514,10 @@ static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_i
|
|
return VKD3D_OK;
|
|
case VKD3DSIH_HS_FORK_PHASE:
|
|
case VKD3DSIH_HS_JOIN_PHASE:
|
|
+ /* ins may be relocated if the instruction array expands. */
|
|
+ location = ins->location;
|
|
ret = control_point_normaliser_emit_hs_input(&normaliser, input_signature,
|
|
- input_control_point_count, i, &ins->location);
|
|
+ input_control_point_count, i, &location);
|
|
*src_instructions = normaliser.instructions;
|
|
return ret;
|
|
default:
|
|
@@ -590,19 +593,19 @@ struct signature_element *vsir_signature_find_element_for_reg(const struct shade
|
|
}
|
|
|
|
static unsigned int range_map_get_register_count(uint8_t range_map[][VKD3D_VEC4_SIZE],
|
|
- unsigned int register_idx, unsigned int write_mask)
|
|
+ unsigned int register_idx, uint32_t write_mask)
|
|
{
|
|
- return range_map[register_idx][vkd3d_write_mask_get_component_idx(write_mask)];
|
|
+ return range_map[register_idx][vsir_write_mask_get_component_idx(write_mask)];
|
|
}
|
|
|
|
static void range_map_set_register_range(uint8_t range_map[][VKD3D_VEC4_SIZE], unsigned int register_idx,
|
|
- unsigned int register_count, unsigned int write_mask, bool is_dcl_indexrange)
|
|
+ unsigned int register_count, uint32_t write_mask, bool is_dcl_indexrange)
|
|
{
|
|
unsigned int i, j, r, c, component_idx, component_count;
|
|
|
|
assert(write_mask <= VKD3DSP_WRITEMASK_ALL);
|
|
- component_idx = vkd3d_write_mask_get_component_idx(write_mask);
|
|
- component_count = vkd3d_write_mask_component_count(write_mask);
|
|
+ component_idx = vsir_write_mask_get_component_idx(write_mask);
|
|
+ component_count = vsir_write_mask_component_count(write_mask);
|
|
|
|
assert(register_idx < MAX_REG_OUTPUT && MAX_REG_OUTPUT - register_idx >= register_count);
|
|
|
|
@@ -896,7 +899,7 @@ static bool shader_dst_param_io_normalise(struct vkd3d_shader_dst_param *dst_par
|
|
element_idx = shader_signature_find_element_for_reg(signature, reg_idx, write_mask);
|
|
e = &signature->elements[element_idx];
|
|
|
|
- dst_param->write_mask >>= vkd3d_write_mask_get_component_idx(e->mask);
|
|
+ dst_param->write_mask >>= vsir_write_mask_get_component_idx(e->mask);
|
|
if (is_io_dcl)
|
|
{
|
|
/* Validated in the TPF reader. */
|
|
@@ -999,7 +1002,7 @@ static void shader_src_param_io_normalise(struct vkd3d_shader_src_param *src_par
|
|
|
|
id_idx = reg->idx_count - 1;
|
|
reg_idx = reg->idx[id_idx].offset;
|
|
- write_mask = VKD3DSP_WRITEMASK_0 << vkd3d_swizzle_get_component(src_param->swizzle, 0);
|
|
+ write_mask = VKD3DSP_WRITEMASK_0 << vsir_swizzle_get_component(src_param->swizzle, 0);
|
|
element_idx = shader_signature_find_element_for_reg(signature, reg_idx, write_mask);
|
|
|
|
e = &signature->elements[element_idx];
|
|
@@ -1008,10 +1011,10 @@ static void shader_src_param_io_normalise(struct vkd3d_shader_src_param *src_par
|
|
reg->idx[id_idx].offset = element_idx;
|
|
reg->idx_count = id_idx + 1;
|
|
|
|
- if ((component_idx = vkd3d_write_mask_get_component_idx(e->mask)))
|
|
+ if ((component_idx = vsir_write_mask_get_component_idx(e->mask)))
|
|
{
|
|
for (i = 0; i < VKD3D_VEC4_SIZE; ++i)
|
|
- if (vkd3d_swizzle_get_component(src_param->swizzle, i))
|
|
+ if (vsir_swizzle_get_component(src_param->swizzle, i))
|
|
src_param->swizzle -= component_idx << VKD3D_SHADER_SWIZZLE_SHIFT(i);
|
|
}
|
|
}
|
|
@@ -1215,7 +1218,7 @@ static void shader_register_normalise_flat_constants(struct vkd3d_shader_src_par
|
|
param->reg.idx_count = 0;
|
|
param->reg.dimension = VSIR_DIMENSION_VEC4;
|
|
for (j = 0; j < 4; ++j)
|
|
- param->reg.u.immconst_uint[j] = normaliser->defs[i].value[j];
|
|
+ param->reg.u.immconst_u32[j] = normaliser->defs[i].value[j];
|
|
return;
|
|
}
|
|
}
|
|
@@ -1251,7 +1254,7 @@ static enum vkd3d_result instruction_array_normalise_flat_constants(struct vkd3d
|
|
|
|
get_flat_constant_register_type((struct vkd3d_shader_register *)&ins->dst[0].reg, &def->set, &def->index);
|
|
for (j = 0; j < 4; ++j)
|
|
- def->value[j] = ins->src[0].reg.u.immconst_uint[j];
|
|
+ def->value[j] = ins->src[0].reg.u.immconst_u32[j];
|
|
|
|
vkd3d_shader_instruction_make_nop(ins);
|
|
}
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c
|
|
index c8a43adbe03..387784f2358 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/spirv.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c
|
|
@@ -133,7 +133,7 @@ static void vkd3d_spirv_dump(const struct vkd3d_shader_code *spirv,
|
|
}
|
|
}
|
|
|
|
-static void vkd3d_spirv_validate(const struct vkd3d_shader_code *spirv,
|
|
+static bool vkd3d_spirv_validate(struct vkd3d_string_buffer *buffer, const struct vkd3d_shader_code *spirv,
|
|
enum vkd3d_shader_spirv_environment environment)
|
|
{
|
|
spv_diagnostic diagnostic = NULL;
|
|
@@ -145,12 +145,13 @@ static void vkd3d_spirv_validate(const struct vkd3d_shader_code *spirv,
|
|
if ((ret = spvValidateBinary(context, spirv->code, spirv->size / sizeof(uint32_t),
|
|
&diagnostic)))
|
|
{
|
|
- FIXME("Failed to validate SPIR-V binary, ret %d.\n", ret);
|
|
- FIXME("Diagnostic message: %s.\n", debugstr_a(diagnostic->error));
|
|
+ vkd3d_string_buffer_printf(buffer, "%s", diagnostic->error);
|
|
}
|
|
|
|
spvDiagnosticDestroy(diagnostic);
|
|
spvContextDestroy(context);
|
|
+
|
|
+ return !ret;
|
|
}
|
|
|
|
#else
|
|
@@ -163,8 +164,11 @@ static enum vkd3d_result vkd3d_spirv_binary_to_text(const struct vkd3d_shader_co
|
|
}
|
|
static void vkd3d_spirv_dump(const struct vkd3d_shader_code *spirv,
|
|
enum vkd3d_shader_spirv_environment environment) {}
|
|
-static void vkd3d_spirv_validate(const struct vkd3d_shader_code *spirv,
|
|
- enum vkd3d_shader_spirv_environment environment) {}
|
|
+static bool vkd3d_spirv_validate(struct vkd3d_string_buffer *buffer, const struct vkd3d_shader_code *spirv,
|
|
+ enum vkd3d_shader_spirv_environment environment)
|
|
+{
|
|
+ return true;
|
|
+}
|
|
|
|
#endif /* HAVE_SPIRV_TOOLS */
|
|
|
|
@@ -1194,6 +1198,16 @@ static uint32_t vkd3d_spirv_get_op_constant64(struct vkd3d_spirv_builder *builde
|
|
(const uint32_t *)&value, 2, vkd3d_spirv_build_op_constant64);
|
|
}
|
|
|
|
+static uint32_t vkd3d_spirv_build_op_constant_null(struct vkd3d_spirv_builder *builder, uint32_t result_type)
|
|
+{
|
|
+ return vkd3d_spirv_build_op_tr(builder, &builder->global_stream, SpvOpConstantNull, result_type);
|
|
+}
|
|
+
|
|
+static uint32_t vkd3d_spirv_get_op_constant_null(struct vkd3d_spirv_builder *builder, uint32_t result_type)
|
|
+{
|
|
+ return vkd3d_spirv_build_once1(builder, SpvOpConstantNull, result_type, vkd3d_spirv_build_op_constant_null);
|
|
+}
|
|
+
|
|
static uint32_t vkd3d_spirv_build_op_constant_composite(struct vkd3d_spirv_builder *builder,
|
|
uint32_t result_type, const uint32_t *constituents, unsigned int constituent_count)
|
|
{
|
|
@@ -1783,6 +1797,8 @@ static uint32_t vkd3d_spirv_get_type_id(struct vkd3d_spirv_builder *builder,
|
|
break;
|
|
case VKD3D_SHADER_COMPONENT_DOUBLE:
|
|
return vkd3d_spirv_get_op_type_float(builder, 64);
|
|
+ case VKD3D_SHADER_COMPONENT_UINT64:
|
|
+ return vkd3d_spirv_get_op_type_int(builder, 64, 0);
|
|
default:
|
|
FIXME("Unhandled component type %#x.\n", component_type);
|
|
return 0;
|
|
@@ -1816,6 +1832,8 @@ static uint32_t vkd3d_spirv_get_type_id_for_data_type(struct vkd3d_spirv_builder
|
|
break;
|
|
case VKD3D_DATA_DOUBLE:
|
|
return vkd3d_spirv_get_op_type_float(builder, 64);
|
|
+ case VKD3D_DATA_UINT64:
|
|
+ return vkd3d_spirv_get_op_type_int(builder, 64, 0);
|
|
case VKD3D_DATA_BOOL:
|
|
return vkd3d_spirv_get_op_type_bool(builder);
|
|
default:
|
|
@@ -2152,6 +2170,7 @@ static void vkd3d_symbol_make_register(struct vkd3d_symbol *symbol,
|
|
break;
|
|
|
|
case VKD3DSPR_IMMCONSTBUFFER:
|
|
+ symbol->key.reg.idx = reg->idx_count > 1 ? reg->idx[0].offset : 0;
|
|
break;
|
|
|
|
default:
|
|
@@ -2159,6 +2178,15 @@ static void vkd3d_symbol_make_register(struct vkd3d_symbol *symbol,
|
|
}
|
|
}
|
|
|
|
+static void vkd3d_symbol_make_io(struct vkd3d_symbol *symbol,
|
|
+ enum vkd3d_shader_register_type type, unsigned int index)
|
|
+{
|
|
+ symbol->type = VKD3D_SYMBOL_REGISTER;
|
|
+ memset(&symbol->key, 0, sizeof(symbol->key));
|
|
+ symbol->key.reg.type = type;
|
|
+ symbol->key.reg.idx = index;
|
|
+}
|
|
+
|
|
static void vkd3d_symbol_set_register_info(struct vkd3d_symbol *symbol,
|
|
uint32_t val_id, SpvStorageClass storage_class,
|
|
enum vkd3d_shader_component_type component_type, DWORD write_mask)
|
|
@@ -2376,12 +2404,15 @@ struct spirv_compiler
|
|
struct vkd3d_shader_spec_constant *spec_constants;
|
|
size_t spec_constants_size;
|
|
enum vkd3d_shader_compile_option_formatting_flags formatting;
|
|
+ enum vkd3d_shader_compile_option_feature_flags features;
|
|
bool write_tess_geom_point_size;
|
|
|
|
struct vkd3d_string_buffer_cache string_buffers;
|
|
|
|
struct ssa_register_info *ssa_register_info;
|
|
unsigned int ssa_register_count;
|
|
+
|
|
+ uint64_t config_flags;
|
|
};
|
|
|
|
static bool is_in_default_phase(const struct spirv_compiler *compiler)
|
|
@@ -2437,7 +2468,8 @@ static void spirv_compiler_destroy(struct spirv_compiler *compiler)
|
|
static struct spirv_compiler *spirv_compiler_create(const struct vkd3d_shader_version *shader_version,
|
|
struct vkd3d_shader_desc *shader_desc, const struct vkd3d_shader_compile_info *compile_info,
|
|
const struct vkd3d_shader_scan_descriptor_info1 *scan_descriptor_info,
|
|
- struct vkd3d_shader_message_context *message_context, const struct vkd3d_shader_location *location)
|
|
+ struct vkd3d_shader_message_context *message_context, const struct vkd3d_shader_location *location,
|
|
+ uint64_t config_flags)
|
|
{
|
|
const struct shader_signature *patch_constant_signature = &shader_desc->patch_constant_signature;
|
|
const struct shader_signature *output_signature = &shader_desc->output_signature;
|
|
@@ -2454,6 +2486,7 @@ static struct spirv_compiler *spirv_compiler_create(const struct vkd3d_shader_ve
|
|
memset(compiler, 0, sizeof(*compiler));
|
|
compiler->message_context = message_context;
|
|
compiler->location = *location;
|
|
+ compiler->config_flags = config_flags;
|
|
|
|
if ((target_info = vkd3d_find_struct(compile_info->next, SPIRV_TARGET_INFO)))
|
|
{
|
|
@@ -2533,6 +2566,10 @@ static struct spirv_compiler *spirv_compiler_create(const struct vkd3d_shader_ve
|
|
WARN("Ignoring unrecognised value %#x for option %#x.\n", option->value, option->name);
|
|
break;
|
|
|
|
+ case VKD3D_SHADER_COMPILE_OPTION_FEATURE:
|
|
+ compiler->features = option->value;
|
|
+ break;
|
|
+
|
|
default:
|
|
WARN("Ignoring unrecognised option %#x with value %#x.\n", option->name, option->value);
|
|
break;
|
|
@@ -2955,7 +2992,7 @@ static uint32_t spirv_compiler_get_constant64(struct spirv_compiler *compiler,
|
|
assert(0 < component_count && component_count <= VKD3D_DVEC2_SIZE);
|
|
type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count);
|
|
|
|
- if (component_type != VKD3D_SHADER_COMPONENT_DOUBLE)
|
|
+ if (component_type != VKD3D_SHADER_COMPONENT_DOUBLE && component_type != VKD3D_SHADER_COMPONENT_UINT64)
|
|
{
|
|
FIXME("Unhandled component_type %#x.\n", component_type);
|
|
return vkd3d_spirv_get_op_undef(builder, type_id);
|
|
@@ -3015,14 +3052,21 @@ static uint32_t spirv_compiler_get_constant_double_vector(struct spirv_compiler
|
|
component_count, (const uint64_t *)values);
|
|
}
|
|
|
|
+static uint32_t spirv_compiler_get_constant_uint64_vector(struct spirv_compiler *compiler,
|
|
+ uint64_t value, unsigned int component_count)
|
|
+{
|
|
+ const uint64_t values[] = {value, value};
|
|
+ return spirv_compiler_get_constant64(compiler, VKD3D_SHADER_COMPONENT_UINT64, component_count, values);
|
|
+}
|
|
+
|
|
static uint32_t spirv_compiler_get_type_id_for_reg(struct spirv_compiler *compiler,
|
|
- const struct vkd3d_shader_register *reg, DWORD write_mask)
|
|
+ const struct vkd3d_shader_register *reg, uint32_t write_mask)
|
|
{
|
|
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
|
|
|
return vkd3d_spirv_get_type_id(builder,
|
|
vkd3d_component_type_from_data_type(reg->data_type),
|
|
- vkd3d_write_mask_component_count(write_mask));
|
|
+ vsir_write_mask_component_count(write_mask));
|
|
}
|
|
|
|
static uint32_t spirv_compiler_get_type_id_for_dst(struct spirv_compiler *compiler,
|
|
@@ -3498,7 +3542,7 @@ static void spirv_compiler_emit_dereference_register(struct spirv_compiler *comp
|
|
}
|
|
else if (reg->type == VKD3DSPR_IMMCONSTBUFFER)
|
|
{
|
|
- indexes[index_count++] = spirv_compiler_emit_register_addressing(compiler, ®->idx[0]);
|
|
+ indexes[index_count++] = spirv_compiler_emit_register_addressing(compiler, ®->idx[reg->idx_count - 1]);
|
|
}
|
|
else if (reg->type == VKD3DSPR_IDXTEMP)
|
|
{
|
|
@@ -3530,7 +3574,7 @@ static void spirv_compiler_emit_dereference_register(struct spirv_compiler *comp
|
|
|
|
if (index_count)
|
|
{
|
|
- component_count = vkd3d_write_mask_component_count(register_info->write_mask);
|
|
+ component_count = vsir_write_mask_component_count(register_info->write_mask);
|
|
type_id = vkd3d_spirv_get_type_id(builder, register_info->component_type, component_count);
|
|
ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, register_info->storage_class, type_id);
|
|
register_info->id = vkd3d_spirv_build_op_access_chain(builder, ptr_type_id,
|
|
@@ -3562,24 +3606,24 @@ static bool vkd3d_swizzle_is_equal(unsigned int dst_write_mask,
|
|
return vkd3d_compact_swizzle(VKD3D_SHADER_NO_SWIZZLE, dst_write_mask) == vkd3d_compact_swizzle(swizzle, write_mask);
|
|
}
|
|
|
|
-static bool vkd3d_swizzle_is_scalar(unsigned int swizzle)
|
|
+static bool vkd3d_swizzle_is_scalar(uint32_t swizzle)
|
|
{
|
|
- unsigned int component_idx = vkd3d_swizzle_get_component(swizzle, 0);
|
|
- return vkd3d_swizzle_get_component(swizzle, 1) == component_idx
|
|
- && vkd3d_swizzle_get_component(swizzle, 2) == component_idx
|
|
- && vkd3d_swizzle_get_component(swizzle, 3) == component_idx;
|
|
+ unsigned int component_idx = vsir_swizzle_get_component(swizzle, 0);
|
|
+ return vsir_swizzle_get_component(swizzle, 1) == component_idx
|
|
+ && vsir_swizzle_get_component(swizzle, 2) == component_idx
|
|
+ && vsir_swizzle_get_component(swizzle, 3) == component_idx;
|
|
}
|
|
|
|
static uint32_t spirv_compiler_emit_swizzle(struct spirv_compiler *compiler,
|
|
- uint32_t val_id, unsigned int val_write_mask, enum vkd3d_shader_component_type component_type,
|
|
- unsigned int swizzle, unsigned int write_mask)
|
|
+ uint32_t val_id, uint32_t val_write_mask, enum vkd3d_shader_component_type component_type,
|
|
+ uint32_t swizzle, uint32_t write_mask)
|
|
{
|
|
unsigned int i, component_idx, component_count, val_component_count;
|
|
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
|
uint32_t type_id, components[VKD3D_VEC4_SIZE];
|
|
|
|
- component_count = vkd3d_write_mask_component_count(write_mask);
|
|
- val_component_count = vkd3d_write_mask_component_count(val_write_mask);
|
|
+ component_count = vsir_write_mask_component_count(write_mask);
|
|
+ val_component_count = vsir_write_mask_component_count(val_write_mask);
|
|
|
|
if (component_count == val_component_count
|
|
&& (component_count == 1 || vkd3d_swizzle_is_equal(val_write_mask, swizzle, write_mask)))
|
|
@@ -3589,9 +3633,9 @@ static uint32_t spirv_compiler_emit_swizzle(struct spirv_compiler *compiler,
|
|
|
|
if (component_count == 1)
|
|
{
|
|
- component_idx = vkd3d_write_mask_get_component_idx(write_mask);
|
|
- component_idx = vkd3d_swizzle_get_component(swizzle, component_idx);
|
|
- component_idx -= vkd3d_write_mask_get_component_idx(val_write_mask);
|
|
+ component_idx = vsir_write_mask_get_component_idx(write_mask);
|
|
+ component_idx = vsir_swizzle_get_component(swizzle, component_idx);
|
|
+ component_idx -= vsir_write_mask_get_component_idx(val_write_mask);
|
|
return vkd3d_spirv_build_op_composite_extract1(builder, type_id, val_id, component_idx);
|
|
}
|
|
|
|
@@ -3601,7 +3645,7 @@ static uint32_t spirv_compiler_emit_swizzle(struct spirv_compiler *compiler,
|
|
{
|
|
if (write_mask & (VKD3DSP_WRITEMASK_0 << i))
|
|
{
|
|
- assert(VKD3DSP_WRITEMASK_0 << vkd3d_swizzle_get_component(swizzle, i) == val_write_mask);
|
|
+ assert(VKD3DSP_WRITEMASK_0 << vsir_swizzle_get_component(swizzle, i) == val_write_mask);
|
|
components[component_idx++] = val_id;
|
|
}
|
|
}
|
|
@@ -3611,14 +3655,14 @@ static uint32_t spirv_compiler_emit_swizzle(struct spirv_compiler *compiler,
|
|
for (i = 0, component_idx = 0; i < VKD3D_VEC4_SIZE; ++i)
|
|
{
|
|
if (write_mask & (VKD3DSP_WRITEMASK_0 << i))
|
|
- components[component_idx++] = vkd3d_swizzle_get_component(swizzle, i);
|
|
+ components[component_idx++] = vsir_swizzle_get_component(swizzle, i);
|
|
}
|
|
return vkd3d_spirv_build_op_vector_shuffle(builder,
|
|
type_id, val_id, val_id, components, component_count);
|
|
}
|
|
|
|
static uint32_t spirv_compiler_emit_vector_shuffle(struct spirv_compiler *compiler,
|
|
- uint32_t vector1_id, uint32_t vector2_id, unsigned int swizzle, unsigned int write_mask,
|
|
+ uint32_t vector1_id, uint32_t vector2_id, uint32_t swizzle, uint32_t write_mask,
|
|
enum vkd3d_shader_component_type component_type, unsigned int component_count)
|
|
{
|
|
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
|
@@ -3631,9 +3675,9 @@ static uint32_t spirv_compiler_emit_vector_shuffle(struct spirv_compiler *compil
|
|
for (i = 0; i < component_count; ++i)
|
|
{
|
|
if (write_mask & (VKD3DSP_WRITEMASK_0 << i))
|
|
- components[i] = vkd3d_swizzle_get_component(swizzle, i);
|
|
+ components[i] = vsir_swizzle_get_component(swizzle, i);
|
|
else
|
|
- components[i] = VKD3D_VEC4_SIZE + vkd3d_swizzle_get_component(swizzle, i);
|
|
+ components[i] = VKD3D_VEC4_SIZE + vsir_swizzle_get_component(swizzle, i);
|
|
}
|
|
|
|
type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count);
|
|
@@ -3642,9 +3686,9 @@ static uint32_t spirv_compiler_emit_vector_shuffle(struct spirv_compiler *compil
|
|
}
|
|
|
|
static uint32_t spirv_compiler_emit_load_constant(struct spirv_compiler *compiler,
|
|
- const struct vkd3d_shader_register *reg, DWORD swizzle, DWORD write_mask)
|
|
+ const struct vkd3d_shader_register *reg, uint32_t swizzle, uint32_t write_mask)
|
|
{
|
|
- unsigned int component_count = vkd3d_write_mask_component_count(write_mask);
|
|
+ unsigned int component_count = vsir_write_mask_component_count(write_mask);
|
|
uint32_t values[VKD3D_VEC4_SIZE] = {0};
|
|
unsigned int i, j;
|
|
|
|
@@ -3653,14 +3697,14 @@ static uint32_t spirv_compiler_emit_load_constant(struct spirv_compiler *compile
|
|
if (reg->dimension == VSIR_DIMENSION_SCALAR)
|
|
{
|
|
for (i = 0; i < component_count; ++i)
|
|
- values[i] = *reg->u.immconst_uint;
|
|
+ values[i] = *reg->u.immconst_u32;
|
|
}
|
|
else
|
|
{
|
|
for (i = 0, j = 0; i < VKD3D_VEC4_SIZE; ++i)
|
|
{
|
|
if (write_mask & (VKD3DSP_WRITEMASK_0 << i))
|
|
- values[j++] = reg->u.immconst_uint[vkd3d_swizzle_get_component(swizzle, i)];
|
|
+ values[j++] = reg->u.immconst_u32[vsir_swizzle_get_component(swizzle, i)];
|
|
}
|
|
}
|
|
|
|
@@ -3669,9 +3713,9 @@ static uint32_t spirv_compiler_emit_load_constant(struct spirv_compiler *compile
|
|
}
|
|
|
|
static uint32_t spirv_compiler_emit_load_constant64(struct spirv_compiler *compiler,
|
|
- const struct vkd3d_shader_register *reg, DWORD swizzle, DWORD write_mask)
|
|
+ const struct vkd3d_shader_register *reg, uint32_t swizzle, uint32_t write_mask)
|
|
{
|
|
- unsigned int component_count = vkd3d_write_mask_component_count(write_mask);
|
|
+ unsigned int component_count = vsir_write_mask_component_count(write_mask);
|
|
uint64_t values[VKD3D_DVEC2_SIZE] = {0};
|
|
unsigned int i, j;
|
|
|
|
@@ -3680,14 +3724,14 @@ static uint32_t spirv_compiler_emit_load_constant64(struct spirv_compiler *compi
|
|
if (reg->dimension == VSIR_DIMENSION_SCALAR)
|
|
{
|
|
for (i = 0; i < component_count; ++i)
|
|
- values[i] = *reg->u.immconst_uint64;
|
|
+ values[i] = *reg->u.immconst_u64;
|
|
}
|
|
else
|
|
{
|
|
for (i = 0, j = 0; i < VKD3D_DVEC2_SIZE; ++i)
|
|
{
|
|
if (write_mask & (VKD3DSP_WRITEMASK_0 << i))
|
|
- values[j++] = reg->u.immconst_uint64[vkd3d_swizzle_get_component64(swizzle, i)];
|
|
+ values[j++] = reg->u.immconst_u64[vsir_swizzle_get_component64(swizzle, i)];
|
|
}
|
|
}
|
|
|
|
@@ -3696,9 +3740,9 @@ static uint32_t spirv_compiler_emit_load_constant64(struct spirv_compiler *compi
|
|
}
|
|
|
|
static uint32_t spirv_compiler_emit_load_undef(struct spirv_compiler *compiler,
|
|
- const struct vkd3d_shader_register *reg, DWORD write_mask)
|
|
+ const struct vkd3d_shader_register *reg, uint32_t write_mask)
|
|
{
|
|
- unsigned int component_count = vkd3d_write_mask_component_count(write_mask);
|
|
+ unsigned int component_count = vsir_write_mask_component_count(write_mask);
|
|
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
|
uint32_t type_id;
|
|
|
|
@@ -3709,28 +3753,28 @@ static uint32_t spirv_compiler_emit_load_undef(struct spirv_compiler *compiler,
|
|
}
|
|
|
|
static uint32_t spirv_compiler_emit_load_scalar(struct spirv_compiler *compiler,
|
|
- const struct vkd3d_shader_register *reg, DWORD swizzle, DWORD write_mask,
|
|
+ const struct vkd3d_shader_register *reg, uint32_t swizzle, uint32_t write_mask,
|
|
const struct vkd3d_shader_register_info *reg_info)
|
|
{
|
|
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
|
uint32_t type_id, ptr_type_id, index, reg_id, val_id;
|
|
unsigned int component_idx, reg_component_count;
|
|
enum vkd3d_shader_component_type component_type;
|
|
- unsigned int skipped_component_mask;
|
|
+ uint32_t skipped_component_mask;
|
|
|
|
assert(!register_is_constant_or_undef(reg));
|
|
- assert(vkd3d_write_mask_component_count(write_mask) == 1);
|
|
+ assert(vsir_write_mask_component_count(write_mask) == 1);
|
|
|
|
- component_idx = vkd3d_write_mask_get_component_idx(write_mask);
|
|
- component_idx = vkd3d_swizzle_get_component(swizzle, component_idx);
|
|
+ component_idx = vsir_write_mask_get_component_idx(write_mask);
|
|
+ component_idx = vsir_swizzle_get_component(swizzle, component_idx);
|
|
skipped_component_mask = ~reg_info->write_mask & ((VKD3DSP_WRITEMASK_0 << component_idx) - 1);
|
|
if (skipped_component_mask)
|
|
- component_idx -= vkd3d_write_mask_component_count(skipped_component_mask);
|
|
+ component_idx -= vsir_write_mask_component_count(skipped_component_mask);
|
|
component_type = vkd3d_component_type_from_data_type(reg->data_type);
|
|
|
|
- reg_component_count = vkd3d_write_mask_component_count(reg_info->write_mask);
|
|
+ reg_component_count = vsir_write_mask_component_count(reg_info->write_mask);
|
|
|
|
- if (component_idx >= vkd3d_write_mask_component_count(reg_info->write_mask))
|
|
+ if (component_idx >= vsir_write_mask_component_count(reg_info->write_mask))
|
|
{
|
|
ERR("Invalid component_idx %u for register %#x, %u (write_mask %#x).\n",
|
|
component_idx, reg->type, reg->idx[0].offset, reg_info->write_mask);
|
|
@@ -3756,6 +3800,69 @@ static uint32_t spirv_compiler_emit_load_scalar(struct spirv_compiler *compiler,
|
|
return val_id;
|
|
}
|
|
|
|
+static uint32_t spirv_compiler_emit_constant_array(struct spirv_compiler *compiler,
|
|
+ const struct vkd3d_shader_immediate_constant_buffer *icb, uint32_t *type_id_out)
|
|
+{
|
|
+ uint32_t *elements, elem_type_id, length_id, type_id, const_id;
|
|
+ struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
|
+ enum vkd3d_shader_component_type component_type;
|
|
+ unsigned int i, element_count, component_count;
|
|
+
|
|
+ element_count = icb->element_count;
|
|
+
|
|
+ component_type = vkd3d_component_type_from_data_type(icb->data_type);
|
|
+ component_count = icb->component_count;
|
|
+ elem_type_id = vkd3d_spirv_get_type_id_for_data_type(builder, icb->data_type, component_count);
|
|
+ length_id = spirv_compiler_get_constant_uint(compiler, element_count);
|
|
+ type_id = vkd3d_spirv_get_op_type_array(builder, elem_type_id, length_id);
|
|
+
|
|
+ if (type_id_out)
|
|
+ *type_id_out = type_id;
|
|
+
|
|
+ if (icb->is_null)
|
|
+ {
|
|
+ /* All values are null. Workgroup memory initialisers require OpConstantNull. */
|
|
+ return vkd3d_spirv_get_op_constant_null(builder, type_id);
|
|
+ }
|
|
+
|
|
+ if (!(elements = vkd3d_calloc(element_count, sizeof(*elements))))
|
|
+ {
|
|
+ ERR("Failed to allocate %u elements.", element_count);
|
|
+ spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_OUT_OF_MEMORY,
|
|
+ "Failed to allocate %u constant array elements.", element_count);
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ switch (icb->data_type)
|
|
+ {
|
|
+ case VKD3D_DATA_FLOAT:
|
|
+ case VKD3D_DATA_INT:
|
|
+ case VKD3D_DATA_UINT:
|
|
+ for (i = 0; i < element_count; ++i)
|
|
+ elements[i] = spirv_compiler_get_constant(compiler, component_type, component_count,
|
|
+ &icb->data[component_count * i]);
|
|
+ break;
|
|
+ case VKD3D_DATA_DOUBLE:
|
|
+ case VKD3D_DATA_UINT64:
|
|
+ {
|
|
+ uint64_t *data = (uint64_t *)icb->data;
|
|
+ for (i = 0; i < element_count; ++i)
|
|
+ elements[i] = spirv_compiler_get_constant64(compiler, component_type, component_count,
|
|
+ &data[component_count * i]);
|
|
+ break;
|
|
+ }
|
|
+ default:
|
|
+ FIXME("Unhandled data type %u.\n", icb->data_type);
|
|
+ spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_INVALID_TYPE,
|
|
+ "Immediate constant buffer data type %u is unhandled.", icb->data_type);
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ const_id = vkd3d_spirv_build_op_constant_composite(builder, type_id, elements, element_count);
|
|
+ vkd3d_free(elements);
|
|
+ return const_id;
|
|
+}
|
|
+
|
|
static const struct ssa_register_info *spirv_compiler_get_ssa_register_info(const struct spirv_compiler *compiler,
|
|
const struct vkd3d_shader_register *reg)
|
|
{
|
|
@@ -3775,7 +3882,7 @@ static void spirv_compiler_set_ssa_register_info(const struct spirv_compiler *co
|
|
|
|
static uint32_t spirv_compiler_emit_load_ssa_reg(struct spirv_compiler *compiler,
|
|
const struct vkd3d_shader_register *reg, enum vkd3d_shader_component_type component_type,
|
|
- unsigned int swizzle)
|
|
+ uint32_t swizzle)
|
|
{
|
|
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
|
enum vkd3d_shader_component_type reg_component_type;
|
|
@@ -3801,19 +3908,19 @@ static uint32_t spirv_compiler_emit_load_ssa_reg(struct spirv_compiler *compiler
|
|
}
|
|
|
|
type_id = vkd3d_spirv_get_type_id(builder, component_type, 1);
|
|
- component_idx = vkd3d_swizzle_get_component(swizzle, 0);
|
|
+ component_idx = vsir_swizzle_get_component(swizzle, 0);
|
|
return vkd3d_spirv_build_op_composite_extract1(builder, type_id, val_id, component_idx);
|
|
}
|
|
|
|
static uint32_t spirv_compiler_emit_load_reg(struct spirv_compiler *compiler,
|
|
- const struct vkd3d_shader_register *reg, DWORD swizzle, DWORD write_mask)
|
|
+ const struct vkd3d_shader_register *reg, DWORD swizzle, uint32_t write_mask)
|
|
{
|
|
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
|
enum vkd3d_shader_component_type component_type;
|
|
struct vkd3d_shader_register_info reg_info;
|
|
unsigned int component_count;
|
|
- unsigned int write_mask32;
|
|
uint32_t type_id, val_id;
|
|
+ uint32_t write_mask32;
|
|
|
|
if (reg->type == VKD3DSPR_IMMCONST)
|
|
return spirv_compiler_emit_load_constant(compiler, reg, swizzle, write_mask);
|
|
@@ -3822,7 +3929,7 @@ static uint32_t spirv_compiler_emit_load_reg(struct spirv_compiler *compiler,
|
|
else if (reg->type == VKD3DSPR_UNDEF)
|
|
return spirv_compiler_emit_load_undef(compiler, reg, write_mask);
|
|
|
|
- component_count = vkd3d_write_mask_component_count(write_mask);
|
|
+ component_count = vsir_write_mask_component_count(write_mask);
|
|
component_type = vkd3d_component_type_from_data_type(reg->data_type);
|
|
|
|
if (reg->type == VKD3DSPR_SSA)
|
|
@@ -3836,21 +3943,21 @@ static uint32_t spirv_compiler_emit_load_reg(struct spirv_compiler *compiler,
|
|
assert(reg_info.component_type != VKD3D_SHADER_COMPONENT_DOUBLE);
|
|
spirv_compiler_emit_dereference_register(compiler, reg, ®_info);
|
|
|
|
- write_mask32 = (reg->data_type == VKD3D_DATA_DOUBLE) ? vkd3d_write_mask_32_from_64(write_mask) : write_mask;
|
|
+ write_mask32 = data_type_is_64_bit(reg->data_type) ? vsir_write_mask_32_from_64(write_mask) : write_mask;
|
|
|
|
/* Intermediate value (no storage class). */
|
|
if (reg_info.storage_class == SpvStorageClassMax)
|
|
{
|
|
val_id = reg_info.id;
|
|
}
|
|
- else if (vkd3d_write_mask_component_count(write_mask32) == 1)
|
|
+ else if (vsir_write_mask_component_count(write_mask32) == 1)
|
|
{
|
|
return spirv_compiler_emit_load_scalar(compiler, reg, swizzle, write_mask, ®_info);
|
|
}
|
|
else
|
|
{
|
|
type_id = vkd3d_spirv_get_type_id(builder,
|
|
- reg_info.component_type, vkd3d_write_mask_component_count(reg_info.write_mask));
|
|
+ reg_info.component_type, vsir_write_mask_component_count(reg_info.write_mask));
|
|
val_id = vkd3d_spirv_build_op_load(builder, type_id, reg_info.id, SpvMemoryAccessMaskNone);
|
|
}
|
|
|
|
@@ -3904,7 +4011,7 @@ static uint32_t spirv_compiler_emit_neg(struct spirv_compiler *compiler,
|
|
type_id = spirv_compiler_get_type_id_for_reg(compiler, reg, write_mask);
|
|
if (reg->data_type == VKD3D_DATA_FLOAT || reg->data_type == VKD3D_DATA_DOUBLE)
|
|
return vkd3d_spirv_build_op_fnegate(builder, type_id, val_id);
|
|
- else if (reg->data_type == VKD3D_DATA_INT || reg->data_type == VKD3D_DATA_UINT)
|
|
+ else if (data_type_is_integer(reg->data_type))
|
|
return vkd3d_spirv_build_op_snegate(builder, type_id, val_id);
|
|
|
|
FIXME("Unhandled data type %#x.\n", reg->data_type);
|
|
@@ -3953,19 +4060,19 @@ static uint32_t spirv_compiler_emit_load_src_with_type(struct spirv_compiler *co
|
|
}
|
|
|
|
static void spirv_compiler_emit_store_scalar(struct spirv_compiler *compiler,
|
|
- uint32_t dst_id, unsigned int dst_write_mask, enum vkd3d_shader_component_type component_type,
|
|
- SpvStorageClass storage_class, unsigned int write_mask, uint32_t val_id)
|
|
+ uint32_t dst_id, uint32_t dst_write_mask, enum vkd3d_shader_component_type component_type,
|
|
+ SpvStorageClass storage_class, uint32_t write_mask, uint32_t val_id)
|
|
{
|
|
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
|
uint32_t type_id, ptr_type_id, index;
|
|
unsigned int component_idx;
|
|
|
|
- if (vkd3d_write_mask_component_count(dst_write_mask) > 1)
|
|
+ if (vsir_write_mask_component_count(dst_write_mask) > 1)
|
|
{
|
|
type_id = vkd3d_spirv_get_type_id(builder, component_type, 1);
|
|
ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, storage_class, type_id);
|
|
- component_idx = vkd3d_write_mask_get_component_idx(write_mask);
|
|
- component_idx -= vkd3d_write_mask_get_component_idx(dst_write_mask);
|
|
+ component_idx = vsir_write_mask_get_component_idx(write_mask);
|
|
+ component_idx -= vsir_write_mask_get_component_idx(dst_write_mask);
|
|
index = spirv_compiler_get_constant_uint(compiler, component_idx);
|
|
dst_id = vkd3d_spirv_build_op_in_bounds_access_chain1(builder, ptr_type_id, dst_id, index);
|
|
}
|
|
@@ -3974,8 +4081,8 @@ static void spirv_compiler_emit_store_scalar(struct spirv_compiler *compiler,
|
|
}
|
|
|
|
static void spirv_compiler_emit_store(struct spirv_compiler *compiler,
|
|
- uint32_t dst_id, unsigned int dst_write_mask, enum vkd3d_shader_component_type component_type,
|
|
- SpvStorageClass storage_class, unsigned int write_mask, uint32_t val_id)
|
|
+ uint32_t dst_id, uint32_t dst_write_mask, enum vkd3d_shader_component_type component_type,
|
|
+ SpvStorageClass storage_class, uint32_t write_mask, uint32_t val_id)
|
|
{
|
|
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
|
unsigned int component_count, dst_component_count;
|
|
@@ -3985,14 +4092,14 @@ static void spirv_compiler_emit_store(struct spirv_compiler *compiler,
|
|
|
|
assert(write_mask);
|
|
|
|
- component_count = vkd3d_write_mask_component_count(write_mask);
|
|
- dst_component_count = vkd3d_write_mask_component_count(dst_write_mask);
|
|
+ component_count = vsir_write_mask_component_count(write_mask);
|
|
+ dst_component_count = vsir_write_mask_component_count(dst_write_mask);
|
|
|
|
if (dst_component_count == 1 && component_count != 1)
|
|
{
|
|
type_id = vkd3d_spirv_get_type_id(builder, component_type, 1);
|
|
val_id = vkd3d_spirv_build_op_composite_extract1(builder, type_id, val_id,
|
|
- vkd3d_write_mask_get_component_idx(dst_write_mask));
|
|
+ vsir_write_mask_get_component_idx(dst_write_mask));
|
|
write_mask &= dst_write_mask;
|
|
component_count = 1;
|
|
}
|
|
@@ -4029,12 +4136,12 @@ static void spirv_compiler_emit_store(struct spirv_compiler *compiler,
|
|
}
|
|
|
|
static void spirv_compiler_emit_store_reg(struct spirv_compiler *compiler,
|
|
- const struct vkd3d_shader_register *reg, unsigned int write_mask, uint32_t val_id)
|
|
+ const struct vkd3d_shader_register *reg, uint32_t write_mask, uint32_t val_id)
|
|
{
|
|
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
|
enum vkd3d_shader_component_type component_type;
|
|
struct vkd3d_shader_register_info reg_info;
|
|
- unsigned int src_write_mask = write_mask;
|
|
+ uint32_t src_write_mask = write_mask;
|
|
uint32_t type_id;
|
|
|
|
assert(!register_is_constant_or_undef(reg));
|
|
@@ -4052,10 +4159,10 @@ static void spirv_compiler_emit_store_reg(struct spirv_compiler *compiler,
|
|
component_type = vkd3d_component_type_from_data_type(reg->data_type);
|
|
if (component_type != reg_info.component_type)
|
|
{
|
|
- if (reg->data_type == VKD3D_DATA_DOUBLE)
|
|
- src_write_mask = vkd3d_write_mask_32_from_64(write_mask);
|
|
+ if (data_type_is_64_bit(reg->data_type))
|
|
+ src_write_mask = vsir_write_mask_32_from_64(write_mask);
|
|
type_id = vkd3d_spirv_get_type_id(builder, reg_info.component_type,
|
|
- vkd3d_write_mask_component_count(src_write_mask));
|
|
+ vsir_write_mask_component_count(src_write_mask));
|
|
val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id);
|
|
component_type = reg_info.component_type;
|
|
}
|
|
@@ -4065,9 +4172,9 @@ static void spirv_compiler_emit_store_reg(struct spirv_compiler *compiler,
|
|
}
|
|
|
|
static uint32_t spirv_compiler_emit_sat(struct spirv_compiler *compiler,
|
|
- const struct vkd3d_shader_register *reg, DWORD write_mask, uint32_t val_id)
|
|
+ const struct vkd3d_shader_register *reg, uint32_t write_mask, uint32_t val_id)
|
|
{
|
|
- unsigned int component_count = vkd3d_write_mask_component_count(write_mask);
|
|
+ unsigned int component_count = vsir_write_mask_component_count(write_mask);
|
|
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
|
uint32_t type_id, zero_id, one_id;
|
|
|
|
@@ -4118,7 +4225,7 @@ static void spirv_compiler_emit_store_dst_components(struct spirv_compiler *comp
|
|
const struct vkd3d_shader_dst_param *dst, enum vkd3d_shader_component_type component_type,
|
|
uint32_t *component_ids)
|
|
{
|
|
- unsigned int component_count = vkd3d_write_mask_component_count(dst->write_mask);
|
|
+ unsigned int component_count = vsir_write_mask_component_count(dst->write_mask);
|
|
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
|
uint32_t type_id, val_id;
|
|
|
|
@@ -4137,16 +4244,16 @@ static void spirv_compiler_emit_store_dst_components(struct spirv_compiler *comp
|
|
|
|
static void spirv_compiler_emit_store_dst_scalar(struct spirv_compiler *compiler,
|
|
const struct vkd3d_shader_dst_param *dst, uint32_t val_id,
|
|
- enum vkd3d_shader_component_type component_type, DWORD swizzle)
|
|
+ enum vkd3d_shader_component_type component_type, uint32_t swizzle)
|
|
{
|
|
- unsigned int component_count = vkd3d_write_mask_component_count(dst->write_mask);
|
|
+ unsigned int component_count = vsir_write_mask_component_count(dst->write_mask);
|
|
uint32_t component_ids[VKD3D_VEC4_SIZE];
|
|
unsigned int component_idx, i;
|
|
|
|
- component_idx = vkd3d_write_mask_get_component_idx(dst->write_mask);
|
|
+ component_idx = vsir_write_mask_get_component_idx(dst->write_mask);
|
|
for (i = 0; i < component_count; ++i)
|
|
{
|
|
- if (vkd3d_swizzle_get_component(swizzle, component_idx + i))
|
|
+ if (vsir_swizzle_get_component(swizzle, component_idx + i))
|
|
ERR("Invalid swizzle %#x for scalar value, write mask %#x.\n", swizzle, dst->write_mask);
|
|
|
|
component_ids[i] = val_id;
|
|
@@ -4191,14 +4298,18 @@ static void spirv_compiler_decorate_builtin(struct spirv_compiler *compiler,
|
|
}
|
|
|
|
static void spirv_compiler_emit_interpolation_decorations(struct spirv_compiler *compiler,
|
|
- uint32_t id, enum vkd3d_shader_interpolation_mode mode)
|
|
+ enum vkd3d_shader_component_type component_type, uint32_t id, enum vkd3d_shader_interpolation_mode mode)
|
|
{
|
|
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
|
|
|
switch (mode)
|
|
{
|
|
case VKD3DSIM_NONE:
|
|
- break;
|
|
+ /* VUID-StandaloneSpirv-Flat-04744: integer or double types must be
|
|
+ * decorated 'Flat' for fragment shaders. */
|
|
+ if (compiler->shader_type != VKD3D_SHADER_TYPE_PIXEL || component_type == VKD3D_SHADER_COMPONENT_FLOAT)
|
|
+ break;
|
|
+ /* fall through */
|
|
case VKD3DSIM_CONSTANT:
|
|
vkd3d_spirv_build_op_decorate(builder, id, SpvDecorationFlat, NULL, 0);
|
|
break;
|
|
@@ -4226,7 +4337,8 @@ static void spirv_compiler_emit_interpolation_decorations(struct spirv_compiler
|
|
}
|
|
|
|
static uint32_t spirv_compiler_emit_int_to_bool(struct spirv_compiler *compiler,
|
|
- enum vkd3d_shader_conditional_op condition, unsigned int component_count, uint32_t val_id)
|
|
+ enum vkd3d_shader_conditional_op condition, enum vkd3d_data_type data_type,
|
|
+ unsigned int component_count, uint32_t val_id)
|
|
{
|
|
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
|
uint32_t type_id;
|
|
@@ -4237,7 +4349,9 @@ static uint32_t spirv_compiler_emit_int_to_bool(struct spirv_compiler *compiler,
|
|
type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count);
|
|
op = condition & VKD3D_SHADER_CONDITIONAL_OP_Z ? SpvOpIEqual : SpvOpINotEqual;
|
|
return vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, op, type_id, val_id,
|
|
- spirv_compiler_get_constant_uint_vector(compiler, 0, component_count));
|
|
+ data_type == VKD3D_DATA_UINT64
|
|
+ ? spirv_compiler_get_constant_uint64_vector(compiler, 0, component_count)
|
|
+ : spirv_compiler_get_constant_uint_vector(compiler, 0, component_count));
|
|
}
|
|
|
|
static uint32_t spirv_compiler_emit_bool_to_int(struct spirv_compiler *compiler,
|
|
@@ -4252,6 +4366,19 @@ static uint32_t spirv_compiler_emit_bool_to_int(struct spirv_compiler *compiler,
|
|
return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id);
|
|
}
|
|
|
|
+static uint32_t spirv_compiler_emit_bool_to_int64(struct spirv_compiler *compiler,
|
|
+ unsigned int component_count, uint32_t val_id, bool signedness)
|
|
+{
|
|
+ struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
|
+ uint32_t type_id, true_id, false_id;
|
|
+
|
|
+ true_id = spirv_compiler_get_constant_uint64_vector(compiler, signedness ? UINT64_MAX : 1,
|
|
+ component_count);
|
|
+ false_id = spirv_compiler_get_constant_uint64_vector(compiler, 0, component_count);
|
|
+ type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT64, component_count);
|
|
+ return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id);
|
|
+}
|
|
+
|
|
static uint32_t spirv_compiler_emit_bool_to_float(struct spirv_compiler *compiler,
|
|
unsigned int component_count, uint32_t val_id, bool signedness)
|
|
{
|
|
@@ -4422,9 +4549,9 @@ vkd3d_register_builtins[] =
|
|
};
|
|
|
|
static void spirv_compiler_emit_register_execution_mode(struct spirv_compiler *compiler,
|
|
- const struct vkd3d_shader_register *reg)
|
|
+ enum vkd3d_shader_register_type type)
|
|
{
|
|
- switch (reg->type)
|
|
+ switch (type)
|
|
{
|
|
case VKD3DSPR_DEPTHOUTGE:
|
|
spirv_compiler_emit_execution_mode(compiler, SpvExecutionModeDepthGreater, NULL, 0);
|
|
@@ -4437,9 +4564,9 @@ static void spirv_compiler_emit_register_execution_mode(struct spirv_compiler *c
|
|
VKD3D_SHADER_SPIRV_EXTENSION_EXT_STENCIL_EXPORT))
|
|
{
|
|
FIXME("The target environment does not support stencil export.\n");
|
|
- spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_STENCIL_EXPORT_UNSUPPORTED,
|
|
- "Cannot export stencil reference value for register id %u. "
|
|
- "The target environment does not support stencil export.", reg->idx[0].offset);
|
|
+ spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_UNSUPPORTED_FEATURE,
|
|
+ "Cannot export stencil reference value. "
|
|
+ "The target environment does not support stencil export.");
|
|
}
|
|
vkd3d_spirv_enable_capability(&compiler->spirv_builder, SpvCapabilityStencilExportEXT);
|
|
spirv_compiler_emit_execution_mode(compiler, SpvExecutionModeStencilRefReplacingEXT, NULL, 0);
|
|
@@ -4674,17 +4801,16 @@ static unsigned int shader_signature_next_location(const struct shader_signature
|
|
}
|
|
|
|
static uint32_t spirv_compiler_emit_input(struct spirv_compiler *compiler,
|
|
- const struct vkd3d_shader_dst_param *dst)
|
|
+ enum vkd3d_shader_register_type reg_type, unsigned int element_idx)
|
|
{
|
|
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
|
- const struct vkd3d_shader_register *reg = &dst->reg;
|
|
unsigned int component_idx, input_component_count;
|
|
const struct signature_element *signature_element;
|
|
const struct shader_signature *shader_signature;
|
|
enum vkd3d_shader_component_type component_type;
|
|
const struct vkd3d_spirv_builtin *builtin;
|
|
enum vkd3d_shader_sysval_semantic sysval;
|
|
- unsigned int write_mask, reg_write_mask;
|
|
+ uint32_t write_mask, reg_write_mask;
|
|
struct vkd3d_symbol *symbol = NULL;
|
|
uint32_t val_id, input_id, var_id;
|
|
uint32_t type_id, float_type_id;
|
|
@@ -4693,26 +4819,21 @@ static uint32_t spirv_compiler_emit_input(struct spirv_compiler *compiler,
|
|
struct rb_entry *entry = NULL;
|
|
bool use_private_var = false;
|
|
unsigned int array_sizes[2];
|
|
- unsigned int element_idx;
|
|
-
|
|
- assert(!reg->idx_count || !reg->idx[0].rel_addr);
|
|
- assert(reg->idx_count < 2 || !reg->idx[1].rel_addr);
|
|
|
|
- shader_signature = reg->type == VKD3DSPR_PATCHCONST
|
|
+ shader_signature = reg_type == VKD3DSPR_PATCHCONST
|
|
? &compiler->patch_constant_signature : &compiler->input_signature;
|
|
|
|
- element_idx = reg->idx[reg->idx_count - 1].offset;
|
|
signature_element = &shader_signature->elements[element_idx];
|
|
sysval = signature_element->sysval_semantic;
|
|
/* The Vulkan spec does not explicitly forbid passing varyings from the
|
|
* TCS to the TES via builtins. However, Mesa doesn't seem to handle it
|
|
* well, and we don't actually need them to be in builtins. */
|
|
- if (compiler->shader_type == VKD3D_SHADER_TYPE_DOMAIN && reg->type != VKD3DSPR_PATCHCONST)
|
|
+ if (compiler->shader_type == VKD3D_SHADER_TYPE_DOMAIN && reg_type != VKD3DSPR_PATCHCONST)
|
|
sysval = VKD3D_SHADER_SV_NONE;
|
|
|
|
builtin = get_spirv_builtin_for_sysval(compiler, sysval);
|
|
|
|
- array_sizes[0] = (reg->type == VKD3DSPR_PATCHCONST ? 0 : compiler->input_control_point_count);
|
|
+ array_sizes[0] = (reg_type == VKD3DSPR_PATCHCONST ? 0 : compiler->input_control_point_count);
|
|
array_sizes[1] = signature_element->register_count;
|
|
if (array_sizes[1] == 1 && !vsir_sysval_semantic_is_tess_factor(signature_element->sysval_semantic)
|
|
&& (!vsir_sysval_semantic_is_clip_cull(signature_element->sysval_semantic) || array_sizes[0]))
|
|
@@ -4731,8 +4852,8 @@ static uint32_t spirv_compiler_emit_input(struct spirv_compiler *compiler,
|
|
else
|
|
{
|
|
component_type = signature_element->component_type;
|
|
- input_component_count = vkd3d_write_mask_component_count(signature_element->mask);
|
|
- component_idx = vkd3d_write_mask_get_component_idx(signature_element->mask);
|
|
+ input_component_count = vsir_write_mask_component_count(signature_element->mask);
|
|
+ component_idx = vsir_write_mask_get_component_idx(signature_element->mask);
|
|
}
|
|
|
|
if (needs_private_io_variable(builtin))
|
|
@@ -4742,13 +4863,13 @@ static uint32_t spirv_compiler_emit_input(struct spirv_compiler *compiler,
|
|
}
|
|
else
|
|
{
|
|
- component_idx = vkd3d_write_mask_get_component_idx(write_mask);
|
|
+ component_idx = vsir_write_mask_get_component_idx(write_mask);
|
|
reg_write_mask = write_mask >> component_idx;
|
|
}
|
|
|
|
storage_class = SpvStorageClassInput;
|
|
|
|
- vkd3d_symbol_make_register(®_symbol, reg);
|
|
+ vkd3d_symbol_make_io(®_symbol, reg_type, element_idx);
|
|
|
|
if ((entry = rb_get(&compiler->symbol_table, ®_symbol)))
|
|
{
|
|
@@ -4756,7 +4877,7 @@ static uint32_t spirv_compiler_emit_input(struct spirv_compiler *compiler,
|
|
* duplicate declarations are: a single register split into multiple declarations having
|
|
* different components, which should have been merged, and declarations in one phase
|
|
* being repeated in another (i.e. vcp/vocp), which should have been deleted. */
|
|
- if (reg->type != VKD3DSPR_INPUT || !is_in_fork_or_join_phase(compiler))
|
|
+ if (reg_type != VKD3DSPR_INPUT || !is_in_fork_or_join_phase(compiler))
|
|
FIXME("Duplicate input definition found.\n");
|
|
symbol = RB_ENTRY_VALUE(entry, struct vkd3d_symbol, entry);
|
|
return symbol->id;
|
|
@@ -4765,7 +4886,7 @@ static uint32_t spirv_compiler_emit_input(struct spirv_compiler *compiler,
|
|
if (builtin)
|
|
{
|
|
input_id = spirv_compiler_emit_builtin_variable_v(compiler, builtin, storage_class, array_sizes, 2);
|
|
- if (reg->type == VKD3DSPR_PATCHCONST)
|
|
+ if (reg_type == VKD3DSPR_PATCHCONST)
|
|
vkd3d_spirv_build_op_decorate(builder, input_id, SpvDecorationPatch, NULL, 0);
|
|
}
|
|
else
|
|
@@ -4775,7 +4896,7 @@ static uint32_t spirv_compiler_emit_input(struct spirv_compiler *compiler,
|
|
input_id = spirv_compiler_emit_array_variable(compiler, &builder->global_stream,
|
|
storage_class, component_type, input_component_count, array_sizes, 2);
|
|
vkd3d_spirv_add_iface_variable(builder, input_id);
|
|
- if (reg->type == VKD3DSPR_PATCHCONST)
|
|
+ if (reg_type == VKD3DSPR_PATCHCONST)
|
|
{
|
|
vkd3d_spirv_build_op_decorate(builder, input_id, SpvDecorationPatch, NULL, 0);
|
|
location += shader_signature_next_location(&compiler->input_signature);
|
|
@@ -4784,7 +4905,8 @@ static uint32_t spirv_compiler_emit_input(struct spirv_compiler *compiler,
|
|
if (component_idx)
|
|
vkd3d_spirv_build_op_decorate1(builder, input_id, SpvDecorationComponent, component_idx);
|
|
|
|
- spirv_compiler_emit_interpolation_decorations(compiler, input_id, signature_element->interpolation_mode);
|
|
+ spirv_compiler_emit_interpolation_decorations(compiler, component_type, input_id,
|
|
+ signature_element->interpolation_mode);
|
|
}
|
|
|
|
var_id = input_id;
|
|
@@ -4802,12 +4924,14 @@ static uint32_t spirv_compiler_emit_input(struct spirv_compiler *compiler,
|
|
assert(!builtin || !builtin->spirv_array_size || use_private_var || array_sizes[0] || array_sizes[1]);
|
|
spirv_compiler_put_symbol(compiler, ®_symbol);
|
|
|
|
- spirv_compiler_emit_register_debug_name(builder, var_id, reg);
|
|
+ vkd3d_spirv_build_op_name(builder, var_id, reg_type == VKD3DSPR_PATCHCONST ? "vpc%u" : "v%u", element_idx);
|
|
|
|
if (use_private_var)
|
|
{
|
|
- struct vkd3d_shader_register dst_reg = *reg;
|
|
- dst_reg.data_type = VKD3D_DATA_FLOAT;
|
|
+ struct vkd3d_shader_register dst_reg;
|
|
+
|
|
+ vsir_register_init(&dst_reg, reg_type, VKD3D_DATA_FLOAT, 1);
|
|
+ dst_reg.idx[0].offset = element_idx;
|
|
|
|
type_id = vkd3d_spirv_get_type_id(builder, component_type, input_component_count);
|
|
|
|
@@ -4824,9 +4948,9 @@ static uint32_t spirv_compiler_emit_input(struct spirv_compiler *compiler,
|
|
|
|
val_id = spirv_compiler_emit_swizzle(compiler, val_id,
|
|
vkd3d_write_mask_from_component_count(input_component_count),
|
|
- VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_SHADER_NO_SWIZZLE, dst->write_mask >> component_idx);
|
|
+ VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_SHADER_NO_SWIZZLE, signature_element->mask >> component_idx);
|
|
|
|
- spirv_compiler_emit_store_reg(compiler, &dst_reg, dst->write_mask, val_id);
|
|
+ spirv_compiler_emit_store_reg(compiler, &dst_reg, signature_element->mask, val_id);
|
|
}
|
|
|
|
return input_id;
|
|
@@ -4896,7 +5020,7 @@ static void calculate_clip_or_cull_distance_mask(const struct signature_element
|
|
return;
|
|
}
|
|
|
|
- write_mask = e->mask >> vkd3d_write_mask_get_component_idx(e->mask);
|
|
+ write_mask = e->mask >> vsir_write_mask_get_component_idx(e->mask);
|
|
*mask |= (write_mask & VKD3DSP_WRITEMASK_ALL) << (VKD3D_VEC4_SIZE * e->semantic_index);
|
|
}
|
|
|
|
@@ -4995,7 +5119,7 @@ static void spirv_compiler_emit_output_register(struct spirv_compiler *compiler,
|
|
SpvStorageClassOutput, builtin->component_type, write_mask);
|
|
reg_symbol.info.reg.is_aggregate = builtin->spirv_array_size;
|
|
spirv_compiler_put_symbol(compiler, ®_symbol);
|
|
- spirv_compiler_emit_register_execution_mode(compiler, reg);
|
|
+ spirv_compiler_emit_register_execution_mode(compiler, reg->type);
|
|
spirv_compiler_emit_register_debug_name(builder, output_id, reg);
|
|
}
|
|
|
|
@@ -5024,46 +5148,44 @@ static uint32_t spirv_compiler_emit_shader_phase_builtin_variable(struct spirv_c
|
|
return id;
|
|
}
|
|
|
|
-static void spirv_compiler_emit_output(struct spirv_compiler *compiler, const struct vkd3d_shader_dst_param *dst)
|
|
+static void spirv_compiler_emit_output(struct spirv_compiler *compiler,
|
|
+ enum vkd3d_shader_register_type reg_type, unsigned int element_idx)
|
|
{
|
|
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
|
- const struct vkd3d_shader_register *reg = &dst->reg;
|
|
unsigned int component_idx, output_component_count;
|
|
const struct signature_element *signature_element;
|
|
enum vkd3d_shader_component_type component_type;
|
|
const struct shader_signature *shader_signature;
|
|
const struct vkd3d_spirv_builtin *builtin;
|
|
enum vkd3d_shader_sysval_semantic sysval;
|
|
- unsigned int write_mask, reg_write_mask;
|
|
+ uint32_t write_mask, reg_write_mask;
|
|
bool use_private_variable = false;
|
|
struct vkd3d_symbol reg_symbol;
|
|
SpvStorageClass storage_class;
|
|
unsigned int array_sizes[2];
|
|
- unsigned int element_idx;
|
|
bool is_patch_constant;
|
|
uint32_t id, var_id;
|
|
|
|
- is_patch_constant = is_in_fork_or_join_phase(compiler);
|
|
+ is_patch_constant = (reg_type == VKD3DSPR_PATCHCONST);
|
|
|
|
shader_signature = is_patch_constant ? &compiler->patch_constant_signature : &compiler->output_signature;
|
|
|
|
- element_idx = reg->idx[reg->idx_count - 1].offset;
|
|
signature_element = &shader_signature->elements[element_idx];
|
|
sysval = signature_element->sysval_semantic;
|
|
/* Don't use builtins for TCS -> TES varyings. See spirv_compiler_emit_input(). */
|
|
if (compiler->shader_type == VKD3D_SHADER_TYPE_HULL && !is_patch_constant)
|
|
sysval = VKD3D_SHADER_SV_NONE;
|
|
- array_sizes[0] = (reg->type == VKD3DSPR_PATCHCONST ? 0 : compiler->output_control_point_count);
|
|
+ array_sizes[0] = (reg_type == VKD3DSPR_PATCHCONST ? 0 : compiler->output_control_point_count);
|
|
array_sizes[1] = signature_element->register_count;
|
|
if (array_sizes[1] == 1 && !vsir_sysval_semantic_is_tess_factor(signature_element->sysval_semantic))
|
|
array_sizes[1] = 0;
|
|
|
|
- builtin = vkd3d_get_spirv_builtin(compiler, dst->reg.type, sysval);
|
|
+ builtin = vkd3d_get_spirv_builtin(compiler, reg_type, sysval);
|
|
|
|
write_mask = signature_element->mask;
|
|
|
|
- component_idx = vkd3d_write_mask_get_component_idx(write_mask);
|
|
- output_component_count = vkd3d_write_mask_component_count(write_mask);
|
|
+ component_idx = vsir_write_mask_get_component_idx(write_mask);
|
|
+ output_component_count = vsir_write_mask_component_count(write_mask);
|
|
if (builtin)
|
|
{
|
|
component_type = builtin->component_type;
|
|
@@ -5077,15 +5199,18 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler, const st
|
|
|
|
storage_class = SpvStorageClassOutput;
|
|
|
|
- if (get_shader_output_swizzle(compiler, signature_element->register_index) != VKD3D_SHADER_NO_SWIZZLE
|
|
- || (compiler->output_info[element_idx].id && compiler->output_info[element_idx].array_element_mask)
|
|
- || needs_private_io_variable(builtin))
|
|
+ if (needs_private_io_variable(builtin))
|
|
+ use_private_variable = true;
|
|
+
|
|
+ if (!is_patch_constant
|
|
+ && (get_shader_output_swizzle(compiler, signature_element->register_index) != VKD3D_SHADER_NO_SWIZZLE
|
|
+ || (compiler->output_info[element_idx].id && compiler->output_info[element_idx].array_element_mask)))
|
|
{
|
|
use_private_variable = true;
|
|
}
|
|
|
|
reg_write_mask = write_mask >> component_idx;
|
|
- vkd3d_symbol_make_register(®_symbol, reg);
|
|
+ vkd3d_symbol_make_io(®_symbol, reg_type, element_idx);
|
|
|
|
if (rb_get(&compiler->symbol_table, ®_symbol))
|
|
{
|
|
@@ -5094,7 +5219,7 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler, const st
|
|
return;
|
|
}
|
|
|
|
- if (compiler->output_info[element_idx].id)
|
|
+ if (!is_patch_constant && compiler->output_info[element_idx].id)
|
|
{
|
|
id = compiler->output_info[element_idx].id;
|
|
}
|
|
@@ -5105,7 +5230,7 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler, const st
|
|
else
|
|
id = spirv_compiler_emit_builtin_variable_v(compiler, builtin, storage_class, array_sizes, 2);
|
|
|
|
- spirv_compiler_emit_register_execution_mode(compiler, &dst->reg);
|
|
+ spirv_compiler_emit_register_execution_mode(compiler, reg_type);
|
|
}
|
|
else if (signature_element->target_location == SIGNATURE_TARGET_LOCATION_UNUSED)
|
|
{
|
|
@@ -5146,8 +5271,11 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler, const st
|
|
|
|
spirv_compiler_decorate_xfb_output(compiler, id, output_component_count, signature_element);
|
|
|
|
- compiler->output_info[element_idx].id = id;
|
|
- compiler->output_info[element_idx].component_type = component_type;
|
|
+ if (!is_patch_constant)
|
|
+ {
|
|
+ compiler->output_info[element_idx].id = id;
|
|
+ compiler->output_info[element_idx].component_type = component_type;
|
|
+ }
|
|
|
|
var_id = id;
|
|
if (use_private_variable)
|
|
@@ -5165,8 +5293,7 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler, const st
|
|
|
|
spirv_compiler_put_symbol(compiler, ®_symbol);
|
|
|
|
- if (!is_patch_constant)
|
|
- spirv_compiler_emit_register_debug_name(builder, var_id, reg);
|
|
+ vkd3d_spirv_build_op_name(builder, var_id, reg_type == VKD3DSPR_PATCHCONST ? "vpc%u" : "o%u", element_idx);
|
|
|
|
if (use_private_variable)
|
|
{
|
|
@@ -5198,9 +5325,9 @@ static uint32_t spirv_compiler_get_output_array_index(struct spirv_compiler *com
|
|
static void spirv_compiler_emit_store_shader_output(struct spirv_compiler *compiler,
|
|
const struct shader_signature *signature, const struct signature_element *output,
|
|
const struct vkd3d_shader_output_info *output_info,
|
|
- uint32_t output_index_id, uint32_t val_id, unsigned int write_mask)
|
|
+ uint32_t output_index_id, uint32_t val_id, uint32_t write_mask)
|
|
{
|
|
- unsigned int dst_write_mask, use_mask, uninit_mask, swizzle, mask;
|
|
+ uint32_t dst_write_mask, use_mask, uninit_mask, swizzle, mask;
|
|
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
|
uint32_t type_id, zero_id, ptr_type_id, chain_id, object_id;
|
|
const struct signature_element *element;
|
|
@@ -5222,7 +5349,7 @@ static void spirv_compiler_emit_store_shader_output(struct spirv_compiler *compi
|
|
use_mask |= element->used_mask;
|
|
}
|
|
}
|
|
- index = vkd3d_write_mask_get_component_idx(output->mask);
|
|
+ index = vsir_write_mask_get_component_idx(output->mask);
|
|
dst_write_mask >>= index;
|
|
use_mask >>= index;
|
|
write_mask &= dst_write_mask;
|
|
@@ -5246,7 +5373,7 @@ static void spirv_compiler_emit_store_shader_output(struct spirv_compiler *compi
|
|
output_info->component_type, VKD3D_VEC4_SIZE, 0);
|
|
val_id = spirv_compiler_emit_vector_shuffle(compiler,
|
|
zero_id, val_id, swizzle, uninit_mask, output_info->component_type,
|
|
- vkd3d_write_mask_component_count(write_mask));
|
|
+ vsir_write_mask_component_count(write_mask));
|
|
}
|
|
else
|
|
{
|
|
@@ -5258,7 +5385,7 @@ static void spirv_compiler_emit_store_shader_output(struct spirv_compiler *compi
|
|
if (output_index_id)
|
|
{
|
|
type_id = vkd3d_spirv_get_type_id(builder,
|
|
- output_info->component_type, vkd3d_write_mask_component_count(dst_write_mask));
|
|
+ output_info->component_type, vsir_write_mask_component_count(dst_write_mask));
|
|
ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassOutput, type_id);
|
|
output_id = vkd3d_spirv_build_op_access_chain1(builder, ptr_type_id, output_id, output_index_id);
|
|
}
|
|
@@ -5444,6 +5571,21 @@ static void spirv_compiler_emit_dcl_global_flags(struct spirv_compiler *compiler
|
|
flags &= ~(VKD3DSGF_ENABLE_DOUBLE_PRECISION_FLOAT_OPS | VKD3DSGF_ENABLE_11_1_DOUBLE_EXTENSIONS);
|
|
}
|
|
|
|
+ if (flags & VKD3DSGF_ENABLE_INT64)
|
|
+ {
|
|
+ if (compiler->features & VKD3D_SHADER_COMPILE_OPTION_FEATURE_INT64)
|
|
+ {
|
|
+ vkd3d_spirv_enable_capability(&compiler->spirv_builder, SpvCapabilityInt64);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ WARN("Unsupported 64-bit integer ops.\n");
|
|
+ spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_UNSUPPORTED_FEATURE,
|
|
+ "The target environment does not support 64-bit integers.");
|
|
+ }
|
|
+ flags &= ~VKD3DSGF_ENABLE_INT64;
|
|
+ }
|
|
+
|
|
if (flags & ~(VKD3DSGF_REFACTORING_ALLOWED | VKD3DSGF_ENABLE_RAW_AND_STRUCTURED_BUFFERS))
|
|
FIXME("Unhandled global flags %#"PRIx64".\n", (uint64_t)flags);
|
|
else
|
|
@@ -5493,39 +5635,40 @@ static void spirv_compiler_emit_dcl_indexable_temp(struct spirv_compiler *compil
|
|
{
|
|
const struct vkd3d_shader_indexable_temp *temp = &instruction->declaration.indexable_temp;
|
|
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
|
+ uint32_t id, type_id, length_id, ptr_type_id, init_id = 0;
|
|
+ enum vkd3d_shader_component_type component_type;
|
|
struct vkd3d_shader_register reg;
|
|
struct vkd3d_symbol reg_symbol;
|
|
+ SpvStorageClass storage_class;
|
|
size_t function_location;
|
|
- uint32_t id;
|
|
|
|
- if (temp->component_count != 4)
|
|
- FIXME("Unhandled component count %u.\n", temp->component_count);
|
|
+ storage_class = SpvStorageClassFunction;
|
|
|
|
vsir_register_init(®, VKD3DSPR_IDXTEMP, VKD3D_DATA_FLOAT, 1);
|
|
reg.idx[0].offset = temp->register_idx;
|
|
|
|
if (temp->alignment)
|
|
WARN("Ignoring alignment %u.\n", temp->alignment);
|
|
- if (temp->initialiser)
|
|
- {
|
|
- FIXME("Initialisers are not supported.\n");
|
|
- spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED,
|
|
- "Initialisers for indexable temps are not supported.");
|
|
- }
|
|
|
|
function_location = spirv_compiler_get_current_function_location(compiler);
|
|
vkd3d_spirv_begin_function_stream_insertion(builder, function_location);
|
|
|
|
- id = spirv_compiler_emit_array_variable(compiler, &builder->function_stream,
|
|
- SpvStorageClassFunction, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE, &temp->register_size, 1);
|
|
+ component_type = vkd3d_component_type_from_data_type(temp->data_type);
|
|
+ type_id = vkd3d_spirv_get_type_id(builder, component_type, temp->component_count);
|
|
+ length_id = spirv_compiler_get_constant_uint(compiler, temp->register_size);
|
|
+ type_id = vkd3d_spirv_get_op_type_array(builder, type_id, length_id);
|
|
+ ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, storage_class, type_id);
|
|
+ if (temp->initialiser)
|
|
+ init_id = spirv_compiler_emit_constant_array(compiler, temp->initialiser, NULL);
|
|
+ id = vkd3d_spirv_build_op_variable(builder, &builder->function_stream, ptr_type_id, storage_class, init_id);
|
|
|
|
spirv_compiler_emit_register_debug_name(builder, id, ®);
|
|
|
|
vkd3d_spirv_end_function_stream_insertion(builder);
|
|
|
|
vkd3d_symbol_make_register(®_symbol, ®);
|
|
- vkd3d_symbol_set_register_info(®_symbol, id,
|
|
- SpvStorageClassFunction, VKD3D_SHADER_COMPONENT_FLOAT, VKD3DSP_WRITEMASK_ALL);
|
|
+ vkd3d_symbol_set_register_info(®_symbol, id, storage_class,
|
|
+ component_type, vkd3d_write_mask_from_component_count(temp->component_count));
|
|
spirv_compiler_put_symbol(compiler, ®_symbol);
|
|
}
|
|
|
|
@@ -5743,34 +5886,24 @@ static void spirv_compiler_emit_dcl_immediate_constant_buffer(struct spirv_compi
|
|
const struct vkd3d_shader_instruction *instruction)
|
|
{
|
|
const struct vkd3d_shader_immediate_constant_buffer *icb = instruction->declaration.icb;
|
|
- uint32_t *elements, length_id, type_id, const_id, ptr_type_id, icb_id;
|
|
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
|
+ uint32_t type_id, const_id, ptr_type_id, icb_id;
|
|
struct vkd3d_shader_register reg;
|
|
struct vkd3d_symbol reg_symbol;
|
|
- unsigned int i;
|
|
|
|
- assert(icb->data_type == VKD3D_DATA_FLOAT);
|
|
- assert(icb->component_count == VKD3D_VEC4_SIZE);
|
|
-
|
|
- if (!(elements = vkd3d_calloc(icb->element_count, sizeof(*elements))))
|
|
- return;
|
|
- for (i = 0; i < icb->element_count; ++i)
|
|
- elements[i] = spirv_compiler_get_constant(compiler,
|
|
- VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE, &icb->data[4 * i]);
|
|
- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE);
|
|
- length_id = spirv_compiler_get_constant_uint(compiler, icb->element_count);
|
|
- type_id = vkd3d_spirv_get_op_type_array(builder, type_id, length_id);
|
|
- const_id = vkd3d_spirv_build_op_constant_composite(builder, type_id, elements, icb->element_count);
|
|
+ const_id = spirv_compiler_emit_constant_array(compiler, icb, &type_id);
|
|
ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassPrivate, type_id);
|
|
icb_id = vkd3d_spirv_build_op_variable(builder, &builder->global_stream,
|
|
ptr_type_id, SpvStorageClassPrivate, const_id);
|
|
vkd3d_spirv_build_op_name(builder, icb_id, "icb");
|
|
- vkd3d_free(elements);
|
|
|
|
- vsir_register_init(®, VKD3DSPR_IMMCONSTBUFFER, VKD3D_DATA_FLOAT, 0);
|
|
+ /* Set an index count of 2 so vkd3d_symbol_make_register() uses idx[0] as a buffer id. */
|
|
+ vsir_register_init(®, VKD3DSPR_IMMCONSTBUFFER, VKD3D_DATA_FLOAT, 2);
|
|
+ reg.idx[0].offset = icb->register_idx;
|
|
vkd3d_symbol_make_register(®_symbol, ®);
|
|
vkd3d_symbol_set_register_info(®_symbol, icb_id, SpvStorageClassPrivate,
|
|
- VKD3D_SHADER_COMPONENT_FLOAT, VKD3DSP_WRITEMASK_ALL);
|
|
+ vkd3d_component_type_from_data_type(icb->data_type),
|
|
+ vkd3d_write_mask_from_component_count(icb->component_count));
|
|
spirv_compiler_put_symbol(compiler, ®_symbol);
|
|
}
|
|
|
|
@@ -6147,37 +6280,22 @@ static void spirv_compiler_emit_dcl_input(struct spirv_compiler *compiler,
|
|
{
|
|
const struct vkd3d_shader_dst_param *dst = &instruction->declaration.dst;
|
|
|
|
- /* OUTPOINTID is handled in spirv_compiler_emit_hull_shader_builtins(). */
|
|
- if (dst->reg.type == VKD3DSPR_INPUT || dst->reg.type == VKD3DSPR_PATCHCONST)
|
|
- spirv_compiler_emit_input(compiler, dst);
|
|
- else if (dst->reg.type != VKD3DSPR_OUTPOINTID)
|
|
+ /* INPUT and PATCHCONST are handled in spirv_compiler_emit_io_declarations().
|
|
+ * OUTPOINTID is handled in spirv_compiler_emit_hull_shader_builtins(). */
|
|
+ if (dst->reg.type != VKD3DSPR_INPUT && dst->reg.type != VKD3DSPR_PATCHCONST
|
|
+ && dst->reg.type != VKD3DSPR_OUTPOINTID)
|
|
spirv_compiler_emit_input_register(compiler, dst);
|
|
}
|
|
|
|
-static void spirv_compiler_emit_dcl_input_sysval(struct spirv_compiler *compiler,
|
|
- const struct vkd3d_shader_instruction *instruction)
|
|
-{
|
|
- spirv_compiler_emit_input(compiler, &instruction->declaration.register_semantic.reg);
|
|
-}
|
|
-
|
|
static void spirv_compiler_emit_dcl_output(struct spirv_compiler *compiler,
|
|
const struct vkd3d_shader_instruction *instruction)
|
|
{
|
|
const struct vkd3d_shader_dst_param *dst = &instruction->declaration.dst;
|
|
|
|
- if (dst->reg.type == VKD3DSPR_OUTPUT
|
|
- || (is_in_fork_or_join_phase(compiler) && dst->reg.type == VKD3DSPR_PATCHCONST))
|
|
- spirv_compiler_emit_output(compiler, dst);
|
|
- else
|
|
+ if (dst->reg.type != VKD3DSPR_OUTPUT && dst->reg.type != VKD3DSPR_PATCHCONST)
|
|
spirv_compiler_emit_output_register(compiler, dst);
|
|
}
|
|
|
|
-static void spirv_compiler_emit_dcl_output_siv(struct spirv_compiler *compiler,
|
|
- const struct vkd3d_shader_instruction *instruction)
|
|
-{
|
|
- spirv_compiler_emit_output(compiler, &instruction->declaration.register_semantic.reg);
|
|
-}
|
|
-
|
|
static void spirv_compiler_emit_dcl_stream(struct spirv_compiler *compiler,
|
|
const struct vkd3d_shader_instruction *instruction)
|
|
{
|
|
@@ -6377,7 +6495,6 @@ static void spirv_compiler_emit_default_control_point_phase(struct spirv_compile
|
|
|
|
static void spirv_compiler_leave_shader_phase(struct spirv_compiler *compiler)
|
|
{
|
|
- const struct shader_signature *signature = &compiler->output_signature;
|
|
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
|
|
|
if (is_in_control_point_phase(compiler) && compiler->emit_default_control_point_phase)
|
|
@@ -6395,7 +6512,6 @@ static void spirv_compiler_leave_shader_phase(struct spirv_compiler *compiler)
|
|
|
|
/* Fork and join phases share output registers (patch constants).
|
|
* Control point phase has separate output registers. */
|
|
- memset(compiler->output_info, 0, signature->element_count * sizeof(*compiler->output_info));
|
|
memset(compiler->private_output_variable, 0, sizeof(compiler->private_output_variable));
|
|
memset(compiler->private_output_variable_write_mask, 0, sizeof(compiler->private_output_variable_write_mask));
|
|
}
|
|
@@ -6438,15 +6554,12 @@ static void spirv_compiler_emit_default_control_point_phase(struct spirv_compile
|
|
{
|
|
const struct shader_signature *output_signature = &compiler->output_signature;
|
|
const struct shader_signature *input_signature = &compiler->input_signature;
|
|
+ uint32_t type_id, output_ptr_type_id, input_id, dst_id, invocation_id;
|
|
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
|
enum vkd3d_shader_component_type component_type;
|
|
struct vkd3d_shader_src_param invocation;
|
|
struct vkd3d_shader_register input_reg;
|
|
- uint32_t type_id, output_ptr_type_id;
|
|
- uint32_t input_id, output_id, dst_id;
|
|
unsigned int component_count;
|
|
- unsigned int array_sizes[2];
|
|
- uint32_t invocation_id;
|
|
unsigned int i;
|
|
|
|
invocation_id = spirv_compiler_emit_load_invocation_id(compiler);
|
|
@@ -6466,6 +6579,8 @@ static void spirv_compiler_emit_default_control_point_phase(struct spirv_compile
|
|
{
|
|
const struct signature_element *output = &output_signature->elements[i];
|
|
const struct signature_element *input = &input_signature->elements[i];
|
|
+ struct vkd3d_shader_register_info output_reg_info;
|
|
+ struct vkd3d_shader_register output_reg;
|
|
|
|
assert(input->mask == output->mask);
|
|
assert(input->component_type == output->component_type);
|
|
@@ -6473,22 +6588,16 @@ static void spirv_compiler_emit_default_control_point_phase(struct spirv_compile
|
|
input_reg.idx[1].offset = i;
|
|
input_id = spirv_compiler_get_register_id(compiler, &input_reg);
|
|
|
|
+ vsir_register_init(&output_reg, VKD3DSPR_OUTPUT, VKD3D_DATA_FLOAT, 1);
|
|
+ output_reg.idx[0].offset = i;
|
|
+ spirv_compiler_get_register_info(compiler, &output_reg, &output_reg_info);
|
|
+
|
|
component_type = output->component_type;
|
|
- component_count = vkd3d_write_mask_component_count(output->mask);
|
|
+ component_count = vsir_write_mask_component_count(output->mask);
|
|
type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count);
|
|
- if ((array_sizes[0] = (input->register_count > 1) ? input->register_count : 0))
|
|
- type_id = vkd3d_spirv_get_op_type_array(builder, type_id, spirv_compiler_get_constant_uint(compiler,
|
|
- array_sizes[0]));
|
|
-
|
|
- array_sizes[1] = compiler->output_control_point_count;
|
|
- output_id = spirv_compiler_emit_array_variable(compiler, &builder->global_stream, SpvStorageClassOutput,
|
|
- component_type, component_count, array_sizes, 2);
|
|
- vkd3d_spirv_add_iface_variable(builder, output_id);
|
|
- vkd3d_spirv_build_op_decorate1(builder, output_id, SpvDecorationLocation, output->register_index);
|
|
- vkd3d_spirv_build_op_name(builder, output_id, "vocp%u", output->register_index);
|
|
-
|
|
output_ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassOutput, type_id);
|
|
- dst_id = vkd3d_spirv_build_op_access_chain1(builder, output_ptr_type_id, output_id, invocation_id);
|
|
+
|
|
+ dst_id = vkd3d_spirv_build_op_access_chain1(builder, output_ptr_type_id, output_reg_info.id, invocation_id);
|
|
|
|
vkd3d_spirv_build_op_copy_memory(builder, dst_id, input_id, SpvMemoryAccessMaskNone);
|
|
}
|
|
@@ -6593,12 +6702,14 @@ static SpvOp spirv_compiler_map_alu_instruction(const struct vkd3d_shader_instru
|
|
{VKD3DSIH_ISHR, SpvOpShiftRightArithmetic},
|
|
{VKD3DSIH_ITOD, SpvOpConvertSToF},
|
|
{VKD3DSIH_ITOF, SpvOpConvertSToF},
|
|
+ {VKD3DSIH_ITOI, SpvOpSConvert},
|
|
{VKD3DSIH_MUL, SpvOpFMul},
|
|
{VKD3DSIH_NOT, SpvOpNot},
|
|
{VKD3DSIH_OR, SpvOpBitwiseOr},
|
|
{VKD3DSIH_USHR, SpvOpShiftRightLogical},
|
|
{VKD3DSIH_UTOD, SpvOpConvertUToF},
|
|
{VKD3DSIH_UTOF, SpvOpConvertUToF},
|
|
+ {VKD3DSIH_UTOU, SpvOpUConvert},
|
|
{VKD3DSIH_XOR, SpvOpBitwiseXor},
|
|
};
|
|
unsigned int i;
|
|
@@ -6650,6 +6761,10 @@ static void spirv_compiler_emit_bool_cast(struct spirv_compiler *compiler,
|
|
{
|
|
val_id = spirv_compiler_emit_bool_to_int(compiler, 1, val_id, instruction->handler_idx == VKD3DSIH_ITOI);
|
|
}
|
|
+ else if (dst->reg.data_type == VKD3D_DATA_UINT64)
|
|
+ {
|
|
+ val_id = spirv_compiler_emit_bool_to_int64(compiler, 1, val_id, instruction->handler_idx == VKD3DSIH_ITOI);
|
|
+ }
|
|
else
|
|
{
|
|
WARN("Unhandled data type %u.\n", dst->reg.data_type);
|
|
@@ -6715,11 +6830,11 @@ static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compil
|
|
* Microsoft fxc will compile immediate constants larger than 5 bits.
|
|
* Fixing up the constants would be more elegant, but the simplest way is
|
|
* to let this handle constants too. */
|
|
- if (instruction->handler_idx == VKD3DSIH_ISHL || instruction->handler_idx == VKD3DSIH_ISHR
|
|
- || instruction->handler_idx == VKD3DSIH_USHR)
|
|
+ if (!(instruction->flags & VKD3DSI_SHIFT_UNMASKED) && (instruction->handler_idx == VKD3DSIH_ISHL
|
|
+ || instruction->handler_idx == VKD3DSIH_ISHR || instruction->handler_idx == VKD3DSIH_USHR))
|
|
{
|
|
uint32_t mask_id = spirv_compiler_get_constant_vector(compiler,
|
|
- VKD3D_SHADER_COMPONENT_UINT, vkd3d_write_mask_component_count(dst->write_mask), 0x1f);
|
|
+ VKD3D_SHADER_COMPONENT_UINT, vsir_write_mask_component_count(dst->write_mask), 0x1f);
|
|
src_ids[1] = vkd3d_spirv_build_op_and(builder, type_id, src_ids[1], mask_id);
|
|
}
|
|
|
|
@@ -6849,7 +6964,7 @@ static void spirv_compiler_emit_mov(struct spirv_compiler *compiler,
|
|
return;
|
|
}
|
|
|
|
- component_count = vkd3d_write_mask_component_count(dst->write_mask);
|
|
+ component_count = vsir_write_mask_component_count(dst->write_mask);
|
|
if (component_count != 1 && component_count != VKD3D_VEC4_SIZE
|
|
&& dst_reg_info.write_mask == VKD3DSP_WRITEMASK_ALL)
|
|
{
|
|
@@ -6863,7 +6978,7 @@ static void spirv_compiler_emit_mov(struct spirv_compiler *compiler,
|
|
for (i = 0; i < ARRAY_SIZE(components); ++i)
|
|
{
|
|
if (dst->write_mask & (VKD3DSP_WRITEMASK_0 << i))
|
|
- components[i] = VKD3D_VEC4_SIZE + vkd3d_swizzle_get_component(src->swizzle, i);
|
|
+ components[i] = VKD3D_VEC4_SIZE + vsir_swizzle_get_component(src->swizzle, i);
|
|
else
|
|
components[i] = i;
|
|
}
|
|
@@ -6877,6 +6992,11 @@ static void spirv_compiler_emit_mov(struct spirv_compiler *compiler,
|
|
|
|
general_implementation:
|
|
val_id = spirv_compiler_emit_load_src(compiler, src, dst->write_mask);
|
|
+ if (dst->reg.data_type != src->reg.data_type)
|
|
+ {
|
|
+ val_id = vkd3d_spirv_build_op_bitcast(builder, vkd3d_spirv_get_type_id_for_data_type(builder,
|
|
+ dst->reg.data_type, vsir_write_mask_component_count(dst->write_mask)), val_id);
|
|
+ }
|
|
spirv_compiler_emit_store_dst(compiler, dst, val_id);
|
|
}
|
|
|
|
@@ -6893,12 +7013,12 @@ static void spirv_compiler_emit_movc(struct spirv_compiler *compiler,
|
|
src1_id = spirv_compiler_emit_load_src(compiler, &src[1], dst->write_mask);
|
|
src2_id = spirv_compiler_emit_load_src(compiler, &src[2], dst->write_mask);
|
|
|
|
- component_count = vkd3d_write_mask_component_count(dst->write_mask);
|
|
+ component_count = vsir_write_mask_component_count(dst->write_mask);
|
|
type_id = spirv_compiler_get_type_id_for_dst(compiler, dst);
|
|
|
|
if (src[0].reg.data_type != VKD3D_DATA_BOOL)
|
|
condition_id = spirv_compiler_emit_int_to_bool(compiler,
|
|
- VKD3D_SHADER_CONDITIONAL_OP_NZ, component_count, condition_id);
|
|
+ VKD3D_SHADER_CONDITIONAL_OP_NZ, src[0].reg.data_type, component_count, condition_id);
|
|
val_id = vkd3d_spirv_build_op_select(builder, type_id, condition_id, src1_id, src2_id);
|
|
|
|
spirv_compiler_emit_store_dst(compiler, dst, val_id);
|
|
@@ -6919,11 +7039,11 @@ static void spirv_compiler_emit_swapc(struct spirv_compiler *compiler,
|
|
src1_id = spirv_compiler_emit_load_src(compiler, &src[1], dst->write_mask);
|
|
src2_id = spirv_compiler_emit_load_src(compiler, &src[2], dst->write_mask);
|
|
|
|
- component_count = vkd3d_write_mask_component_count(dst->write_mask);
|
|
+ component_count = vsir_write_mask_component_count(dst->write_mask);
|
|
type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, component_count);
|
|
|
|
condition_id = spirv_compiler_emit_int_to_bool(compiler,
|
|
- VKD3D_SHADER_CONDITIONAL_OP_NZ, component_count, condition_id);
|
|
+ VKD3D_SHADER_CONDITIONAL_OP_NZ, src[0].reg.data_type, component_count, condition_id);
|
|
|
|
val_id = vkd3d_spirv_build_op_select(builder, type_id, condition_id, src2_id, src1_id);
|
|
spirv_compiler_emit_store_dst(compiler, &dst[0], val_id);
|
|
@@ -6942,7 +7062,7 @@ static void spirv_compiler_emit_dot(struct spirv_compiler *compiler,
|
|
unsigned int component_count, i;
|
|
DWORD write_mask;
|
|
|
|
- component_count = vkd3d_write_mask_component_count(dst->write_mask);
|
|
+ component_count = vsir_write_mask_component_count(dst->write_mask);
|
|
component_type = vkd3d_component_type_from_data_type(dst->reg.data_type);
|
|
|
|
if (instruction->handler_idx == VKD3DSIH_DP4)
|
|
@@ -6980,7 +7100,7 @@ static void spirv_compiler_emit_rcp(struct spirv_compiler *compiler,
|
|
uint32_t type_id, src_id, val_id, div_id;
|
|
unsigned int component_count;
|
|
|
|
- component_count = vkd3d_write_mask_component_count(dst->write_mask);
|
|
+ component_count = vsir_write_mask_component_count(dst->write_mask);
|
|
type_id = spirv_compiler_get_type_id_for_dst(compiler, dst);
|
|
|
|
src_id = spirv_compiler_emit_load_src(compiler, src, dst->write_mask);
|
|
@@ -7060,7 +7180,7 @@ static void spirv_compiler_emit_imad(struct spirv_compiler *compiler,
|
|
uint32_t type_id, val_id, src_ids[3];
|
|
unsigned int i, component_count;
|
|
|
|
- component_count = vkd3d_write_mask_component_count(dst->write_mask);
|
|
+ component_count = vsir_write_mask_component_count(dst->write_mask);
|
|
type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_INT, component_count);
|
|
|
|
for (i = 0; i < ARRAY_SIZE(src_ids); ++i)
|
|
@@ -7087,16 +7207,18 @@ static void spirv_compiler_emit_int_div(struct spirv_compiler *compiler,
|
|
|
|
if (dst[0].reg.type != VKD3DSPR_NULL)
|
|
{
|
|
- component_count = vkd3d_write_mask_component_count(dst[0].write_mask);
|
|
+ component_count = vsir_write_mask_component_count(dst[0].write_mask);
|
|
type_id = spirv_compiler_get_type_id_for_dst(compiler, &dst[0]);
|
|
|
|
src0_id = spirv_compiler_emit_load_src(compiler, &src[0], dst[0].write_mask);
|
|
src1_id = spirv_compiler_emit_load_src(compiler, &src[1], dst[0].write_mask);
|
|
|
|
condition_id = spirv_compiler_emit_int_to_bool(compiler,
|
|
- VKD3D_SHADER_CONDITIONAL_OP_NZ, component_count, src1_id);
|
|
- uint_max_id = spirv_compiler_get_constant_uint_vector(compiler,
|
|
- 0xffffffff, component_count);
|
|
+ VKD3D_SHADER_CONDITIONAL_OP_NZ, src[1].reg.data_type, component_count, src1_id);
|
|
+ if (dst[0].reg.data_type == VKD3D_DATA_UINT64)
|
|
+ uint_max_id = spirv_compiler_get_constant_uint64_vector(compiler, UINT64_MAX, component_count);
|
|
+ else
|
|
+ uint_max_id = spirv_compiler_get_constant_uint_vector(compiler, 0xffffffff, component_count);
|
|
|
|
val_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, div_op, type_id, src0_id, src1_id);
|
|
/* The SPIR-V spec says: "The resulting value is undefined if Operand 2 is 0." */
|
|
@@ -7109,16 +7231,18 @@ static void spirv_compiler_emit_int_div(struct spirv_compiler *compiler,
|
|
{
|
|
if (!component_count || dst[0].write_mask != dst[1].write_mask)
|
|
{
|
|
- component_count = vkd3d_write_mask_component_count(dst[1].write_mask);
|
|
+ component_count = vsir_write_mask_component_count(dst[1].write_mask);
|
|
type_id = spirv_compiler_get_type_id_for_dst(compiler, &dst[1]);
|
|
|
|
src0_id = spirv_compiler_emit_load_src(compiler, &src[0], dst[1].write_mask);
|
|
src1_id = spirv_compiler_emit_load_src(compiler, &src[1], dst[1].write_mask);
|
|
|
|
condition_id = spirv_compiler_emit_int_to_bool(compiler,
|
|
- VKD3D_SHADER_CONDITIONAL_OP_NZ, component_count, src1_id);
|
|
- uint_max_id = spirv_compiler_get_constant_uint_vector(compiler,
|
|
- 0xffffffff, component_count);
|
|
+ VKD3D_SHADER_CONDITIONAL_OP_NZ, src[1].reg.data_type, component_count, src1_id);
|
|
+ if (dst[1].reg.data_type == VKD3D_DATA_UINT64)
|
|
+ uint_max_id = spirv_compiler_get_constant_uint64_vector(compiler, UINT64_MAX, component_count);
|
|
+ else
|
|
+ uint_max_id = spirv_compiler_get_constant_uint_vector(compiler, 0xffffffff, component_count);
|
|
}
|
|
|
|
val_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, mod_op, type_id, src0_id, src1_id);
|
|
@@ -7147,7 +7271,7 @@ static void spirv_compiler_emit_ftoi(struct spirv_compiler *compiler,
|
|
* as a signed integer, but Direct3D expects the result to saturate,
|
|
* and for NaN to yield zero. */
|
|
|
|
- component_count = vkd3d_write_mask_component_count(dst->write_mask);
|
|
+ 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);
|
|
@@ -7200,7 +7324,7 @@ static void spirv_compiler_emit_ftou(struct spirv_compiler *compiler,
|
|
* as an unsigned integer, but Direct3D expects the result to saturate,
|
|
* and for NaN to yield zero. */
|
|
|
|
- component_count = vkd3d_write_mask_component_count(dst->write_mask);
|
|
+ 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);
|
|
@@ -7387,7 +7511,7 @@ static void spirv_compiler_emit_comparison_instruction(struct spirv_compiler *co
|
|
return;
|
|
}
|
|
|
|
- component_count = vkd3d_write_mask_component_count(dst->write_mask);
|
|
+ component_count = vsir_write_mask_component_count(dst->write_mask);
|
|
|
|
src0_id = spirv_compiler_emit_load_src(compiler, &src[0], dst->write_mask);
|
|
src1_id = spirv_compiler_emit_load_src(compiler, &src[1], dst->write_mask);
|
|
@@ -7409,7 +7533,7 @@ static uint32_t spirv_compiler_emit_conditional_branch(struct spirv_compiler *co
|
|
uint32_t condition_id, merge_block_id;
|
|
|
|
condition_id = spirv_compiler_emit_load_src(compiler, src, VKD3DSP_WRITEMASK_0);
|
|
- condition_id = spirv_compiler_emit_int_to_bool(compiler, instruction->flags, 1, condition_id);
|
|
+ condition_id = spirv_compiler_emit_int_to_bool(compiler, instruction->flags, src->reg.data_type, 1, condition_id);
|
|
|
|
merge_block_id = vkd3d_spirv_alloc_id(builder);
|
|
|
|
@@ -7542,7 +7666,7 @@ static int spirv_compiler_emit_control_flow_instruction(struct spirv_compiler *c
|
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
|
|
val_id = spirv_compiler_emit_load_src(compiler, src, VKD3DSP_WRITEMASK_0);
|
|
- condition_id = spirv_compiler_emit_int_to_bool(compiler, instruction->flags, 1, val_id);
|
|
+ condition_id = spirv_compiler_emit_int_to_bool(compiler, instruction->flags, src->reg.data_type, 1, val_id);
|
|
|
|
true_label = vkd3d_spirv_alloc_id(builder);
|
|
merge_block_id = vkd3d_spirv_alloc_id(builder);
|
|
@@ -7705,7 +7829,7 @@ static int spirv_compiler_emit_control_flow_instruction(struct spirv_compiler *c
|
|
"The swizzle for a switch case value is not scalar.");
|
|
}
|
|
assert(src->reg.type == VKD3DSPR_IMMCONST);
|
|
- value = *src->reg.u.immconst_uint;
|
|
+ value = *src->reg.u.immconst_u32;
|
|
|
|
if (!vkd3d_array_reserve((void **)&cf_info->u.switch_.case_blocks, &cf_info->u.switch_.case_blocks_size,
|
|
2 * (cf_info->u.switch_.case_block_count + 1), sizeof(*cf_info->u.switch_.case_blocks)))
|
|
@@ -8325,7 +8449,7 @@ static void spirv_compiler_emit_gather4(struct spirv_compiler *compiler,
|
|
}
|
|
else
|
|
{
|
|
- component_idx = vkd3d_swizzle_get_component(sampler->swizzle, 0);
|
|
+ component_idx = vsir_swizzle_get_component(sampler->swizzle, 0);
|
|
/* Nvidia driver requires signed integer type. */
|
|
component_id = spirv_compiler_get_constant(compiler,
|
|
VKD3D_SHADER_COMPONENT_INT, 1, &component_idx);
|
|
@@ -8403,7 +8527,7 @@ static void spirv_compiler_emit_ld_raw_structured_srv_uav(struct spirv_compiler
|
|
if (!(dst->write_mask & (VKD3DSP_WRITEMASK_0 << i)))
|
|
continue;
|
|
|
|
- component_idx = vkd3d_swizzle_get_component(resource->swizzle, i);
|
|
+ component_idx = vsir_swizzle_get_component(resource->swizzle, i);
|
|
coordinate_id = base_coordinate_id;
|
|
if (component_idx)
|
|
coordinate_id = vkd3d_spirv_build_op_iadd(builder, type_id,
|
|
@@ -8435,7 +8559,7 @@ static void spirv_compiler_emit_ld_raw_structured_srv_uav(struct spirv_compiler
|
|
if (!(dst->write_mask & (VKD3DSP_WRITEMASK_0 << i)))
|
|
continue;
|
|
|
|
- component_idx = vkd3d_swizzle_get_component(resource->swizzle, i);
|
|
+ component_idx = vsir_swizzle_get_component(resource->swizzle, i);
|
|
coordinate_id = base_coordinate_id;
|
|
if (component_idx)
|
|
coordinate_id = vkd3d_spirv_build_op_iadd(builder, type_id,
|
|
@@ -8479,7 +8603,7 @@ static void spirv_compiler_emit_ld_tgsm(struct spirv_compiler *compiler,
|
|
if (!(dst->write_mask & (VKD3DSP_WRITEMASK_0 << i)))
|
|
continue;
|
|
|
|
- component_idx = vkd3d_swizzle_get_component(resource->swizzle, i);
|
|
+ component_idx = vsir_swizzle_get_component(resource->swizzle, i);
|
|
coordinate_id = base_coordinate_id;
|
|
if (component_idx)
|
|
coordinate_id = vkd3d_spirv_build_op_iadd(builder, type_id,
|
|
@@ -8540,7 +8664,7 @@ static void spirv_compiler_emit_store_uav_raw_structured(struct spirv_compiler *
|
|
assert(data->reg.data_type == VKD3D_DATA_UINT);
|
|
val_id = spirv_compiler_emit_load_src(compiler, data, dst->write_mask);
|
|
|
|
- component_count = vkd3d_write_mask_component_count(dst->write_mask);
|
|
+ component_count = vsir_write_mask_component_count(dst->write_mask);
|
|
for (component_idx = 0; component_idx < component_count; ++component_idx)
|
|
{
|
|
data_id = component_count > 1 ?
|
|
@@ -8569,7 +8693,7 @@ static void spirv_compiler_emit_store_uav_raw_structured(struct spirv_compiler *
|
|
assert(data->reg.data_type == VKD3D_DATA_UINT);
|
|
val_id = spirv_compiler_emit_load_src(compiler, data, dst->write_mask);
|
|
|
|
- component_count = vkd3d_write_mask_component_count(dst->write_mask);
|
|
+ component_count = vsir_write_mask_component_count(dst->write_mask);
|
|
for (component_idx = 0; component_idx < component_count; ++component_idx)
|
|
{
|
|
/* Mesa Vulkan drivers require the texel parameter to be a vector. */
|
|
@@ -8613,7 +8737,7 @@ static void spirv_compiler_emit_store_tgsm(struct spirv_compiler *compiler,
|
|
assert(data->reg.data_type == VKD3D_DATA_UINT);
|
|
val_id = spirv_compiler_emit_load_src(compiler, data, dst->write_mask);
|
|
|
|
- component_count = vkd3d_write_mask_component_count(dst->write_mask);
|
|
+ component_count = vsir_write_mask_component_count(dst->write_mask);
|
|
for (component_idx = 0; component_idx < component_count; ++component_idx)
|
|
{
|
|
data_id = component_count > 1 ?
|
|
@@ -9275,7 +9399,7 @@ static void spirv_compiler_emit_eval_attrib(struct spirv_compiler *compiler,
|
|
}
|
|
|
|
type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT,
|
|
- vkd3d_write_mask_component_count(register_info.write_mask));
|
|
+ vsir_write_mask_component_count(register_info.write_mask));
|
|
|
|
instr_set_id = vkd3d_spirv_get_glsl_std450_instr_set(builder);
|
|
val_id = vkd3d_spirv_build_op_ext_inst(builder, type_id, instr_set_id, op, src_ids, src_count);
|
|
@@ -9425,18 +9549,9 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler,
|
|
case VKD3DSIH_DCL_INPUT:
|
|
spirv_compiler_emit_dcl_input(compiler, instruction);
|
|
break;
|
|
- case VKD3DSIH_DCL_INPUT_PS_SGV:
|
|
- case VKD3DSIH_DCL_INPUT_PS_SIV:
|
|
- case VKD3DSIH_DCL_INPUT_SGV:
|
|
- case VKD3DSIH_DCL_INPUT_SIV:
|
|
- spirv_compiler_emit_dcl_input_sysval(compiler, instruction);
|
|
- break;
|
|
case VKD3DSIH_DCL_OUTPUT:
|
|
spirv_compiler_emit_dcl_output(compiler, instruction);
|
|
break;
|
|
- case VKD3DSIH_DCL_OUTPUT_SIV:
|
|
- spirv_compiler_emit_dcl_output_siv(compiler, instruction);
|
|
- break;
|
|
case VKD3DSIH_DCL_STREAM:
|
|
spirv_compiler_emit_dcl_stream(compiler, instruction);
|
|
break;
|
|
@@ -9719,6 +9834,11 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler,
|
|
case VKD3DSIH_DCL_CONSTANT_BUFFER:
|
|
case VKD3DSIH_DCL_HS_MAX_TESSFACTOR:
|
|
case VKD3DSIH_DCL_INPUT_CONTROL_POINT_COUNT:
|
|
+ case VKD3DSIH_DCL_INPUT_SGV:
|
|
+ case VKD3DSIH_DCL_INPUT_SIV:
|
|
+ case VKD3DSIH_DCL_INPUT_PS_SGV:
|
|
+ case VKD3DSIH_DCL_INPUT_PS_SIV:
|
|
+ case VKD3DSIH_DCL_OUTPUT_SIV:
|
|
case VKD3DSIH_DCL_RESOURCE_RAW:
|
|
case VKD3DSIH_DCL_RESOURCE_STRUCTURED:
|
|
case VKD3DSIH_DCL_SAMPLER:
|
|
@@ -9740,6 +9860,30 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler,
|
|
return ret;
|
|
}
|
|
|
|
+static void spirv_compiler_emit_io_declarations(struct spirv_compiler *compiler)
|
|
+{
|
|
+ for (unsigned int i = 0; i < compiler->input_signature.element_count; ++i)
|
|
+ spirv_compiler_emit_input(compiler, VKD3DSPR_INPUT, i);
|
|
+
|
|
+ for (unsigned int i = 0; i < compiler->output_signature.element_count; ++i)
|
|
+ {
|
|
+ /* PS outputs other than TARGET have dedicated registers and therefore
|
|
+ * go through spirv_compiler_emit_dcl_output() for now. */
|
|
+ if (compiler->shader_type == VKD3D_SHADER_TYPE_PIXEL
|
|
+ && compiler->output_signature.elements[i].sysval_semantic != VKD3D_SHADER_SV_TARGET)
|
|
+ continue;
|
|
+ spirv_compiler_emit_output(compiler, VKD3DSPR_OUTPUT, i);
|
|
+ }
|
|
+
|
|
+ for (unsigned int i = 0; i < compiler->patch_constant_signature.element_count; ++i)
|
|
+ {
|
|
+ if (compiler->shader_type == VKD3D_SHADER_TYPE_HULL)
|
|
+ spirv_compiler_emit_output(compiler, VKD3DSPR_PATCHCONST, i);
|
|
+ else
|
|
+ spirv_compiler_emit_input(compiler, VKD3DSPR_PATCHCONST, i);
|
|
+ }
|
|
+}
|
|
+
|
|
static void spirv_compiler_emit_descriptor_declarations(struct spirv_compiler *compiler)
|
|
{
|
|
unsigned int i;
|
|
@@ -9826,6 +9970,8 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler,
|
|
if (compiler->shader_type != VKD3D_SHADER_TYPE_HULL)
|
|
spirv_compiler_emit_shader_signature_outputs(compiler);
|
|
|
|
+ spirv_compiler_emit_io_declarations(compiler);
|
|
+
|
|
for (i = 0; i < instructions.count && result >= 0; ++i)
|
|
{
|
|
compiler->location.line = i + 1;
|
|
@@ -9874,11 +10020,28 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler,
|
|
if (!vkd3d_spirv_compile_module(builder, spirv, spirv_compiler_get_entry_point_name(compiler)))
|
|
return VKD3D_ERROR;
|
|
|
|
- if (TRACE_ON())
|
|
+ if (TRACE_ON() || parser->config_flags & VKD3D_SHADER_CONFIG_FLAG_FORCE_VALIDATION)
|
|
{
|
|
enum vkd3d_shader_spirv_environment environment = spirv_compiler_get_target_environment(compiler);
|
|
- vkd3d_spirv_dump(spirv, environment);
|
|
- vkd3d_spirv_validate(spirv, environment);
|
|
+ struct vkd3d_string_buffer buffer;
|
|
+
|
|
+ if (TRACE_ON())
|
|
+ vkd3d_spirv_dump(spirv, environment);
|
|
+
|
|
+ vkd3d_string_buffer_init(&buffer);
|
|
+ if (!vkd3d_spirv_validate(&buffer, spirv, environment))
|
|
+ {
|
|
+ FIXME("Failed to validate SPIR-V binary.\n");
|
|
+ vkd3d_shader_trace_text(buffer.buffer, buffer.content_size);
|
|
+
|
|
+ if (compiler->config_flags & VKD3D_SHADER_CONFIG_FLAG_FORCE_VALIDATION)
|
|
+ {
|
|
+ spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_INVALID_SHADER,
|
|
+ "Execution generated an invalid shader, failing compilation:\n%s",
|
|
+ buffer.buffer);
|
|
+ }
|
|
+ }
|
|
+ vkd3d_string_buffer_cleanup(&buffer);
|
|
}
|
|
|
|
if (compiler->failed)
|
|
@@ -9905,7 +10068,7 @@ int spirv_compile(struct vkd3d_shader_parser *parser,
|
|
int ret;
|
|
|
|
if (!(spirv_compiler = spirv_compiler_create(&parser->shader_version, &parser->shader_desc,
|
|
- compile_info, scan_descriptor_info, message_context, &parser->location)))
|
|
+ compile_info, scan_descriptor_info, message_context, &parser->location, parser->config_flags)))
|
|
{
|
|
ERR("Failed to create SPIR-V compiler.\n");
|
|
return VKD3D_ERROR;
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c
|
|
index 80f8ab98c08..f859e758d8e 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/tpf.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c
|
|
@@ -792,9 +792,11 @@ static void shader_sm4_read_shader_data(struct vkd3d_shader_instruction *ins, ui
|
|
ins->handler_idx = VKD3DSIH_INVALID;
|
|
return;
|
|
}
|
|
+ icb->register_idx = 0;
|
|
icb->data_type = VKD3D_DATA_FLOAT;
|
|
icb->component_count = VKD3D_VEC4_SIZE;
|
|
icb->element_count = icb_size / VKD3D_VEC4_SIZE;
|
|
+ icb->is_null = false;
|
|
memcpy(icb->data, tokens, sizeof(*tokens) * icb_size);
|
|
shader_instruction_array_add_icb(&priv->p.instructions, icb);
|
|
ins->declaration.icb = icb;
|
|
@@ -918,10 +920,11 @@ static void shader_sm4_read_dcl_index_range(struct vkd3d_shader_instruction *ins
|
|
uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv)
|
|
{
|
|
struct vkd3d_shader_index_range *index_range = &ins->declaration.index_range;
|
|
- unsigned int i, register_idx, register_count, write_mask;
|
|
+ unsigned int i, register_idx, register_count;
|
|
enum vkd3d_shader_register_type type;
|
|
struct sm4_index_range_array *ranges;
|
|
unsigned int *io_masks;
|
|
+ uint32_t write_mask;
|
|
|
|
shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_OPAQUE,
|
|
&index_range->dst);
|
|
@@ -931,7 +934,7 @@ static void shader_sm4_read_dcl_index_range(struct vkd3d_shader_instruction *ins
|
|
register_count = index_range->register_count;
|
|
write_mask = index_range->dst.write_mask;
|
|
|
|
- if (vkd3d_write_mask_component_count(write_mask) != 1)
|
|
+ if (vsir_write_mask_component_count(write_mask) != 1)
|
|
{
|
|
WARN("Unhandled write mask %#x.\n", write_mask);
|
|
vkd3d_shader_parser_warning(&priv->p, VKD3D_SHADER_WARNING_TPF_UNHANDLED_INDEX_RANGE_MASK,
|
|
@@ -1900,19 +1903,19 @@ static bool shader_sm4_read_param(struct vkd3d_shader_sm4_parser *priv, const ui
|
|
|
|
if (register_type == VKD3D_SM4_RT_IMMCONST || register_type == VKD3D_SM4_RT_IMMCONST64)
|
|
{
|
|
- unsigned int dword_count;
|
|
+ unsigned int u32_count;
|
|
|
|
switch (param->dimension)
|
|
{
|
|
case VSIR_DIMENSION_SCALAR:
|
|
- dword_count = 1 + (register_type == VKD3D_SM4_RT_IMMCONST64);
|
|
- if (end - *ptr < dword_count)
|
|
+ u32_count = 1 + (register_type == VKD3D_SM4_RT_IMMCONST64);
|
|
+ if (end - *ptr < u32_count)
|
|
{
|
|
WARN("Invalid ptr %p, end %p.\n", *ptr, end);
|
|
return false;
|
|
}
|
|
- memcpy(param->u.immconst_uint, *ptr, dword_count * sizeof(DWORD));
|
|
- *ptr += dword_count;
|
|
+ memcpy(param->u.immconst_u32, *ptr, u32_count * sizeof(uint32_t));
|
|
+ *ptr += u32_count;
|
|
break;
|
|
|
|
case VSIR_DIMENSION_VEC4:
|
|
@@ -1921,7 +1924,7 @@ static bool shader_sm4_read_param(struct vkd3d_shader_sm4_parser *priv, const ui
|
|
WARN("Invalid ptr %p, end %p.\n", *ptr, end);
|
|
return false;
|
|
}
|
|
- memcpy(param->u.immconst_uint, *ptr, VKD3D_VEC4_SIZE * sizeof(DWORD));
|
|
+ memcpy(param->u.immconst_u32, *ptr, VKD3D_VEC4_SIZE * sizeof(uint32_t));
|
|
*ptr += 4;
|
|
break;
|
|
|
|
@@ -1930,6 +1933,15 @@ static bool shader_sm4_read_param(struct vkd3d_shader_sm4_parser *priv, const ui
|
|
break;
|
|
}
|
|
}
|
|
+ else if (register_type == VKD3D_SM4_RT_IMMCONSTBUFFER)
|
|
+ {
|
|
+ if (param->idx_count != 1)
|
|
+ {
|
|
+ WARN("Unexpected idx count %u.\n", param->idx_count);
|
|
+ vkd3d_shader_parser_error(&priv->p, VKD3D_SHADER_ERROR_TPF_INVALID_REGISTER_INDEX_COUNT,
|
|
+ "Invalid index count %u for immediate const buffer register; expected count 1.", param->idx_count);
|
|
+ }
|
|
+ }
|
|
else if (!shader_is_sm_5_1(priv) && vsir_register_is_descriptor(param))
|
|
{
|
|
/* SM5.1 places a symbol identifier in idx[0] and moves
|
|
@@ -1970,10 +1982,10 @@ static uint32_t swizzle_from_sm4(uint32_t s)
|
|
static uint32_t swizzle_to_sm4(uint32_t s)
|
|
{
|
|
uint32_t ret = 0;
|
|
- ret |= ((vkd3d_swizzle_get_component(s, 0)) & 0x3);
|
|
- ret |= ((vkd3d_swizzle_get_component(s, 1)) & 0x3) << 2;
|
|
- ret |= ((vkd3d_swizzle_get_component(s, 2)) & 0x3) << 4;
|
|
- ret |= ((vkd3d_swizzle_get_component(s, 3)) & 0x3) << 6;
|
|
+ ret |= ((vsir_swizzle_get_component(s, 0)) & 0x3);
|
|
+ ret |= ((vsir_swizzle_get_component(s, 1)) & 0x3) << 2;
|
|
+ ret |= ((vsir_swizzle_get_component(s, 2)) & 0x3) << 4;
|
|
+ ret |= ((vsir_swizzle_get_component(s, 3)) & 0x3) << 6;
|
|
return ret;
|
|
}
|
|
|
|
@@ -2002,12 +2014,12 @@ static bool register_is_control_point_input(const struct vkd3d_shader_register *
|
|
|| priv->p.shader_version.type == VKD3D_SHADER_TYPE_GEOMETRY));
|
|
}
|
|
|
|
-static unsigned int mask_from_swizzle(unsigned int swizzle)
|
|
+static uint32_t mask_from_swizzle(uint32_t swizzle)
|
|
{
|
|
- return (1u << vkd3d_swizzle_get_component(swizzle, 0))
|
|
- | (1u << vkd3d_swizzle_get_component(swizzle, 1))
|
|
- | (1u << vkd3d_swizzle_get_component(swizzle, 2))
|
|
- | (1u << vkd3d_swizzle_get_component(swizzle, 3));
|
|
+ return (1u << vsir_swizzle_get_component(swizzle, 0))
|
|
+ | (1u << vsir_swizzle_get_component(swizzle, 1))
|
|
+ | (1u << vsir_swizzle_get_component(swizzle, 2))
|
|
+ | (1u << vsir_swizzle_get_component(swizzle, 3));
|
|
}
|
|
|
|
static bool shader_sm4_validate_input_output_register(struct vkd3d_shader_sm4_parser *priv,
|
|
@@ -2219,7 +2231,7 @@ static bool shader_sm4_read_dst_param(struct vkd3d_shader_sm4_parser *priv, cons
|
|
}
|
|
|
|
if (data_type == VKD3D_DATA_DOUBLE)
|
|
- dst_param->write_mask = vkd3d_write_mask_64_from_32(dst_param->write_mask);
|
|
+ dst_param->write_mask = vsir_write_mask_64_from_32(dst_param->write_mask);
|
|
/* Some scalar registers are declared with no write mask in shader bytecode. */
|
|
if (!dst_param->write_mask && shader_sm4_is_scalar_register(&dst_param->reg))
|
|
dst_param->write_mask = VKD3DSP_WRITEMASK_0;
|
|
@@ -2533,6 +2545,16 @@ static bool shader_sm4_init(struct vkd3d_shader_sm4_parser *sm4, const uint32_t
|
|
return true;
|
|
}
|
|
|
|
+static void uninvert_used_masks(struct shader_signature *signature)
|
|
+{
|
|
+ for (unsigned int i = 0; i < signature->element_count; ++i)
|
|
+ {
|
|
+ struct signature_element *e = &signature->elements[i];
|
|
+
|
|
+ e->used_mask = e->mask & ~e->used_mask;
|
|
+ }
|
|
+}
|
|
+
|
|
static bool shader_sm4_parser_validate_signature(struct vkd3d_shader_sm4_parser *sm4,
|
|
const struct shader_signature *signature, unsigned int *masks, const char *name)
|
|
{
|
|
@@ -2628,6 +2650,12 @@ int vkd3d_shader_sm4_parser_create(const struct vkd3d_shader_compile_info *compi
|
|
return VKD3D_ERROR_INVALID_ARGUMENT;
|
|
}
|
|
|
|
+ /* DXBC stores used masks inverted for output signatures, for some reason.
|
|
+ * We return them un-inverted. */
|
|
+ uninvert_used_masks(&shader_desc->output_signature);
|
|
+ if (sm4->p.shader_version.type == VKD3D_SHADER_TYPE_HULL)
|
|
+ uninvert_used_masks(&shader_desc->patch_constant_signature);
|
|
+
|
|
if (!shader_sm4_parser_validate_signature(sm4, &shader_desc->input_signature,
|
|
sm4->input_register_masks, "Input")
|
|
|| !shader_sm4_parser_validate_signature(sm4, &shader_desc->output_signature,
|
|
@@ -3842,7 +3870,7 @@ static void sm4_src_from_constant_value(struct vkd3d_shader_src_param *src,
|
|
if (width == 1)
|
|
{
|
|
src->reg.dimension = VSIR_DIMENSION_SCALAR;
|
|
- src->reg.u.immconst_uint[0] = value->u[0].u;
|
|
+ src->reg.u.immconst_u32[0] = value->u[0].u;
|
|
}
|
|
else
|
|
{
|
|
@@ -3852,9 +3880,9 @@ static void sm4_src_from_constant_value(struct vkd3d_shader_src_param *src,
|
|
for (i = 0; i < 4; ++i)
|
|
{
|
|
if ((map_writemask & (1u << i)) && (j < width))
|
|
- src->reg.u.immconst_uint[i] = value->u[j++].u;
|
|
+ src->reg.u.immconst_u32[i] = value->u[j++].u;
|
|
else
|
|
- src->reg.u.immconst_uint[i] = 0;
|
|
+ src->reg.u.immconst_u32[i] = 0;
|
|
}
|
|
}
|
|
}
|
|
@@ -4049,12 +4077,12 @@ static void sm4_write_src_register(const struct tpf_writer *tpf, const struct vk
|
|
|
|
if (src->reg.type == VKD3DSPR_IMMCONST)
|
|
{
|
|
- put_u32(buffer, src->reg.u.immconst_uint[0]);
|
|
+ put_u32(buffer, src->reg.u.immconst_u32[0]);
|
|
if (src->reg.dimension == VSIR_DIMENSION_VEC4)
|
|
{
|
|
- put_u32(buffer, src->reg.u.immconst_uint[1]);
|
|
- put_u32(buffer, src->reg.u.immconst_uint[2]);
|
|
- put_u32(buffer, src->reg.u.immconst_uint[3]);
|
|
+ put_u32(buffer, src->reg.u.immconst_u32[1]);
|
|
+ put_u32(buffer, src->reg.u.immconst_u32[2]);
|
|
+ put_u32(buffer, src->reg.u.immconst_u32[3]);
|
|
}
|
|
}
|
|
}
|
|
@@ -4589,7 +4617,7 @@ static void write_sm4_ld(const struct tpf_writer *tpf, const struct hlsl_ir_node
|
|
memset(&instr.srcs[2], 0, sizeof(instr.srcs[2]));
|
|
reg->type = VKD3DSPR_IMMCONST;
|
|
reg->dimension = VSIR_DIMENSION_SCALAR;
|
|
- reg->u.immconst_uint[0] = index->value.u[0].u;
|
|
+ reg->u.immconst_u32[0] = index->value.u[0].u;
|
|
}
|
|
else if (tpf->ctx->profile->major_version == 4 && tpf->ctx->profile->minor_version == 0)
|
|
{
|
|
@@ -4750,7 +4778,7 @@ static void write_sm4_cast_from_bool(const struct tpf_writer *tpf, const struct
|
|
sm4_src_from_node(tpf, &instr.srcs[0], arg, instr.dsts[0].write_mask);
|
|
instr.srcs[1].reg.type = VKD3DSPR_IMMCONST;
|
|
instr.srcs[1].reg.dimension = VSIR_DIMENSION_SCALAR;
|
|
- instr.srcs[1].reg.u.immconst_uint[0] = mask;
|
|
+ instr.srcs[1].reg.u.immconst_u32[0] = mask;
|
|
instr.src_count = 2;
|
|
|
|
write_sm4_instruction(tpf, &instr);
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
|
|
index 8fd8945151f..8fd98d2a551 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
|
|
@@ -23,6 +23,8 @@
|
|
#include <stdio.h>
|
|
#include <math.h>
|
|
|
|
+/* VKD3D_DEBUG_ENV_NAME("VKD3D_SHADER_DEBUG"); */
|
|
+
|
|
static inline int char_to_int(char c)
|
|
{
|
|
if ('0' <= c && c <= '9')
|
|
@@ -305,6 +307,16 @@ void vkd3d_shader_vwarning(struct vkd3d_shader_message_context *context, const s
|
|
vkd3d_string_buffer_printf(&context->messages, "\n");
|
|
}
|
|
|
|
+void vkd3d_shader_warning(struct vkd3d_shader_message_context *context, const struct vkd3d_shader_location *location,
|
|
+ enum vkd3d_shader_error error, const char *format, ...)
|
|
+{
|
|
+ va_list args;
|
|
+
|
|
+ va_start(args, format);
|
|
+ vkd3d_shader_vwarning(context, location, error, format, args);
|
|
+ va_end(args);
|
|
+}
|
|
+
|
|
void vkd3d_shader_verror(struct vkd3d_shader_message_context *context, const struct vkd3d_shader_location *location,
|
|
enum vkd3d_shader_error error, const char *format, va_list args)
|
|
{
|
|
@@ -888,6 +900,21 @@ static void vkd3d_shader_scan_combined_sampler_declaration(
|
|
&semantic->resource.range, semantic->resource_type, VKD3D_SHADER_RESOURCE_DATA_FLOAT);
|
|
}
|
|
|
|
+static const struct vkd3d_shader_descriptor_info1 *find_descriptor(
|
|
+ const struct vkd3d_shader_scan_descriptor_info1 *info,
|
|
+ enum vkd3d_shader_descriptor_type type, unsigned int register_id)
|
|
+{
|
|
+ for (unsigned int i = 0; i < info->descriptor_count; ++i)
|
|
+ {
|
|
+ const struct vkd3d_shader_descriptor_info1 *d = &info->descriptors[i];
|
|
+
|
|
+ if (d->type == type && d->register_id == register_id)
|
|
+ return d;
|
|
+ }
|
|
+
|
|
+ return NULL;
|
|
+}
|
|
+
|
|
static void vkd3d_shader_scan_combined_sampler_usage(struct vkd3d_shader_scan_context *context,
|
|
const struct vkd3d_shader_register *resource, const struct vkd3d_shader_register *sampler)
|
|
{
|
|
@@ -913,7 +940,6 @@ static void vkd3d_shader_scan_combined_sampler_usage(struct vkd3d_shader_scan_co
|
|
|
|
if (vkd3d_shader_ver_ge(context->version, 5, 1))
|
|
{
|
|
- const struct vkd3d_shader_scan_descriptor_info1 *info = context->scan_descriptor_info;
|
|
const struct vkd3d_shader_descriptor_info1 *d;
|
|
bool dynamic_resource, dynamic_sampler;
|
|
|
|
@@ -928,30 +954,13 @@ static void vkd3d_shader_scan_combined_sampler_usage(struct vkd3d_shader_scan_co
|
|
if (dynamic_resource || dynamic_sampler)
|
|
return;
|
|
|
|
- for (i = 0; i < info->descriptor_count; ++i)
|
|
- {
|
|
- d = &info->descriptors[i];
|
|
- if (d->type != VKD3D_SHADER_DESCRIPTOR_TYPE_SRV)
|
|
- continue;
|
|
- if (d->register_id != resource->idx[0].offset)
|
|
- continue;
|
|
+ if ((d = find_descriptor(context->scan_descriptor_info,
|
|
+ VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, resource->idx[0].offset)))
|
|
resource_space = d->register_space;
|
|
- break;
|
|
- }
|
|
|
|
- if (sampler)
|
|
- {
|
|
- for (i = 0; i < info->descriptor_count; ++i)
|
|
- {
|
|
- d = &info->descriptors[i];
|
|
- if (d->type != VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER)
|
|
- continue;
|
|
- if (d->register_id != sampler->idx[0].offset)
|
|
- continue;
|
|
- sampler_space = d->register_space;
|
|
- break;
|
|
- }
|
|
- }
|
|
+ if (sampler && (d = find_descriptor(context->scan_descriptor_info,
|
|
+ VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, sampler->idx[0].offset)))
|
|
+ sampler_space = d->register_space;
|
|
}
|
|
|
|
for (i = 0; i < info->combined_sampler_count; ++i)
|
|
@@ -1074,6 +1083,9 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte
|
|
vkd3d_shader_scan_sampler_declaration(context, instruction);
|
|
break;
|
|
case VKD3DSIH_DCL:
|
|
+ if (instruction->declaration.semantic.resource_type == VKD3D_SHADER_RESOURCE_NONE)
|
|
+ break;
|
|
+
|
|
if (instruction->declaration.semantic.resource.reg.reg.type == VKD3DSPR_COMBINED_SAMPLER)
|
|
{
|
|
vkd3d_shader_scan_combined_sampler_declaration(context, &instruction->declaration.semantic);
|
|
@@ -1541,16 +1553,15 @@ static int vkd3d_shader_parser_compile(struct vkd3d_shader_parser *parser,
|
|
|
|
scan_info = *compile_info;
|
|
|
|
- if ((ret = scan_with_parser(&scan_info, message_context, &scan_descriptor_info, parser)) < 0)
|
|
- return ret;
|
|
-
|
|
switch (compile_info->target_type)
|
|
{
|
|
case VKD3D_SHADER_TARGET_D3D_ASM:
|
|
- ret = vkd3d_dxbc_binary_to_text(&parser->instructions, &parser->shader_version, compile_info, out);
|
|
+ ret = vkd3d_dxbc_binary_to_text(&parser->instructions, &parser->shader_version, compile_info, out, VSIR_ASM_D3D);
|
|
break;
|
|
|
|
case VKD3D_SHADER_TARGET_GLSL:
|
|
+ if ((ret = scan_with_parser(&scan_info, message_context, &scan_descriptor_info, parser)) < 0)
|
|
+ return ret;
|
|
if (!(glsl_generator = vkd3d_glsl_generator_create(&parser->shader_version,
|
|
message_context, &parser->location)))
|
|
{
|
|
@@ -1561,19 +1572,22 @@ static int vkd3d_shader_parser_compile(struct vkd3d_shader_parser *parser,
|
|
|
|
ret = vkd3d_glsl_generator_generate(glsl_generator, parser, out);
|
|
vkd3d_glsl_generator_destroy(glsl_generator);
|
|
+ vkd3d_shader_free_scan_descriptor_info1(&scan_descriptor_info);
|
|
break;
|
|
|
|
case VKD3D_SHADER_TARGET_SPIRV_BINARY:
|
|
case VKD3D_SHADER_TARGET_SPIRV_TEXT:
|
|
+ if ((ret = scan_with_parser(&scan_info, message_context, &scan_descriptor_info, parser)) < 0)
|
|
+ return ret;
|
|
ret = spirv_compile(parser, &scan_descriptor_info, compile_info, out, message_context);
|
|
+ vkd3d_shader_free_scan_descriptor_info1(&scan_descriptor_info);
|
|
break;
|
|
|
|
default:
|
|
/* Validation should prevent us from reaching this. */
|
|
- assert(0);
|
|
+ vkd3d_unreachable();
|
|
}
|
|
|
|
- vkd3d_shader_free_scan_descriptor_info1(&scan_descriptor_info);
|
|
return ret;
|
|
}
|
|
|
|
@@ -1622,14 +1636,10 @@ static int compile_d3d_bytecode(const struct vkd3d_shader_compile_info *compile_
|
|
return ret;
|
|
}
|
|
|
|
- if (compile_info->target_type == VKD3D_SHADER_TARGET_D3D_ASM)
|
|
- {
|
|
- ret = vkd3d_dxbc_binary_to_text(&parser->instructions, &parser->shader_version, compile_info, out);
|
|
- vkd3d_shader_parser_destroy(parser);
|
|
- return ret;
|
|
- }
|
|
+ ret = vkd3d_shader_parser_compile(parser, compile_info, out, message_context);
|
|
|
|
- return VKD3D_ERROR;
|
|
+ vkd3d_shader_parser_destroy(parser);
|
|
+ return ret;
|
|
}
|
|
|
|
static int compile_dxbc_dxil(const struct vkd3d_shader_compile_info *compile_info,
|
|
@@ -1907,6 +1917,10 @@ const enum vkd3d_shader_target_type *vkd3d_shader_get_supported_target_types(
|
|
|
|
static const enum vkd3d_shader_target_type d3dbc_types[] =
|
|
{
|
|
+ VKD3D_SHADER_TARGET_SPIRV_BINARY,
|
|
+#ifdef HAVE_SPIRV_TOOLS
|
|
+ VKD3D_SHADER_TARGET_SPIRV_TEXT,
|
|
+#endif
|
|
VKD3D_SHADER_TARGET_D3D_ASM,
|
|
};
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
|
|
index a93fa7160f7..47b245bd7ee 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
|
|
@@ -91,11 +91,12 @@ enum vkd3d_shader_error
|
|
VKD3D_SHADER_ERROR_SPV_INVALID_REGISTER_TYPE = 2001,
|
|
VKD3D_SHADER_ERROR_SPV_INVALID_DESCRIPTOR_BINDING = 2002,
|
|
VKD3D_SHADER_ERROR_SPV_DESCRIPTOR_IDX_UNSUPPORTED = 2003,
|
|
- VKD3D_SHADER_ERROR_SPV_STENCIL_EXPORT_UNSUPPORTED = 2004,
|
|
+ VKD3D_SHADER_ERROR_SPV_UNSUPPORTED_FEATURE = 2004,
|
|
VKD3D_SHADER_ERROR_SPV_OUT_OF_MEMORY = 2005,
|
|
VKD3D_SHADER_ERROR_SPV_INVALID_TYPE = 2006,
|
|
VKD3D_SHADER_ERROR_SPV_INVALID_HANDLER = 2007,
|
|
VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED = 2008,
|
|
+ VKD3D_SHADER_ERROR_SPV_INVALID_SHADER = 2009,
|
|
|
|
VKD3D_SHADER_WARNING_SPV_INVALID_SWIZZLE = 2300,
|
|
|
|
@@ -196,6 +197,7 @@ enum vkd3d_shader_error
|
|
VKD3D_SHADER_WARNING_DXIL_ENTRY_POINT_MISMATCH = 8306,
|
|
VKD3D_SHADER_WARNING_DXIL_INVALID_MASK = 8307,
|
|
VKD3D_SHADER_WARNING_DXIL_INVALID_OPERATION = 8308,
|
|
+ VKD3D_SHADER_WARNING_DXIL_IGNORING_ATTACHMENT = 8309,
|
|
|
|
VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED = 9000,
|
|
VKD3D_SHADER_ERROR_VSIR_INVALID_HANDLER = 9001,
|
|
@@ -618,6 +620,11 @@ static inline bool data_type_is_bool(enum vkd3d_data_type data_type)
|
|
return data_type == VKD3D_DATA_BOOL;
|
|
}
|
|
|
|
+static inline bool data_type_is_64_bit(enum vkd3d_data_type data_type)
|
|
+{
|
|
+ return data_type == VKD3D_DATA_DOUBLE || data_type == VKD3D_DATA_UINT64;
|
|
+}
|
|
+
|
|
enum vsir_dimension
|
|
{
|
|
VSIR_DIMENSION_NONE,
|
|
@@ -740,6 +747,7 @@ enum vkd3d_tessellator_domain
|
|
#define VKD3DSI_RESINFO_UINT 0x2
|
|
#define VKD3DSI_SAMPLE_INFO_UINT 0x1
|
|
#define VKD3DSI_SAMPLER_COMPARISON_MODE 0x1
|
|
+#define VKD3DSI_SHIFT_UNMASKED 0x1
|
|
|
|
#define VKD3DSI_PRECISE_X 0x100
|
|
#define VKD3DSI_PRECISE_Y 0x200
|
|
@@ -793,10 +801,12 @@ struct vkd3d_shader_version
|
|
|
|
struct vkd3d_shader_immediate_constant_buffer
|
|
{
|
|
+ unsigned int register_idx;
|
|
enum vkd3d_data_type data_type;
|
|
/* total count is element_count * component_count */
|
|
unsigned int element_count;
|
|
unsigned int component_count;
|
|
+ bool is_null;
|
|
uint32_t data[];
|
|
};
|
|
|
|
@@ -831,10 +841,10 @@ struct vkd3d_shader_register
|
|
unsigned int alignment;
|
|
union
|
|
{
|
|
- DWORD immconst_uint[VKD3D_VEC4_SIZE];
|
|
- float immconst_float[VKD3D_VEC4_SIZE];
|
|
- uint64_t immconst_uint64[VKD3D_DVEC2_SIZE];
|
|
- double immconst_double[VKD3D_DVEC2_SIZE];
|
|
+ uint32_t immconst_u32[VKD3D_VEC4_SIZE];
|
|
+ float immconst_f32[VKD3D_VEC4_SIZE];
|
|
+ uint64_t immconst_u64[VKD3D_DVEC2_SIZE];
|
|
+ double immconst_f64[VKD3D_DVEC2_SIZE];
|
|
unsigned fp_body_idx;
|
|
} u;
|
|
};
|
|
@@ -1311,9 +1321,15 @@ struct vkd3d_string_buffer_cache
|
|
size_t count, max_count, capacity;
|
|
};
|
|
|
|
+enum vsir_asm_dialect
|
|
+{
|
|
+ VSIR_ASM_VSIR,
|
|
+ VSIR_ASM_D3D,
|
|
+};
|
|
+
|
|
enum vkd3d_result vkd3d_dxbc_binary_to_text(const struct vkd3d_shader_instruction_array *instructions,
|
|
const struct vkd3d_shader_version *shader_version, const struct vkd3d_shader_compile_info *compile_info,
|
|
- struct vkd3d_shader_code *out);
|
|
+ struct vkd3d_shader_code *out, enum vsir_asm_dialect dialect);
|
|
void vkd3d_string_buffer_cleanup(struct vkd3d_string_buffer *buffer);
|
|
struct vkd3d_string_buffer *vkd3d_string_buffer_get(struct vkd3d_string_buffer_cache *list);
|
|
void vkd3d_string_buffer_init(struct vkd3d_string_buffer *buffer);
|
|
@@ -1382,6 +1398,8 @@ void vkd3d_shader_verror(struct vkd3d_shader_message_context *context, const str
|
|
enum vkd3d_shader_error error, const char *format, va_list args);
|
|
void vkd3d_shader_vnote(struct vkd3d_shader_message_context *context, const struct vkd3d_shader_location *location,
|
|
enum vkd3d_shader_log_level level, const char *format, va_list args);
|
|
+void vkd3d_shader_warning(struct vkd3d_shader_message_context *context, const struct vkd3d_shader_location *location,
|
|
+ enum vkd3d_shader_error error, const char *format, ...) VKD3D_PRINTF_FUNC(4, 5);
|
|
void vkd3d_shader_vwarning(struct vkd3d_shader_message_context *context, const struct vkd3d_shader_location *location,
|
|
enum vkd3d_shader_error error, const char *format, va_list args);
|
|
|
|
@@ -1444,6 +1462,8 @@ static inline enum vkd3d_shader_component_type vkd3d_component_type_from_data_ty
|
|
return VKD3D_SHADER_COMPONENT_INT;
|
|
case VKD3D_DATA_DOUBLE:
|
|
return VKD3D_SHADER_COMPONENT_DOUBLE;
|
|
+ case VKD3D_DATA_UINT64:
|
|
+ return VKD3D_SHADER_COMPONENT_UINT64;
|
|
case VKD3D_DATA_BOOL:
|
|
return VKD3D_SHADER_COMPONENT_BOOL;
|
|
default:
|
|
@@ -1505,7 +1525,7 @@ static inline enum vkd3d_shader_input_sysval_semantic vkd3d_siv_from_sysval(enum
|
|
return vkd3d_siv_from_sysval_indexed(sysval, 0);
|
|
}
|
|
|
|
-static inline unsigned int vkd3d_write_mask_get_component_idx(DWORD write_mask)
|
|
+static inline unsigned int vsir_write_mask_get_component_idx(uint32_t write_mask)
|
|
{
|
|
unsigned int i;
|
|
|
|
@@ -1520,7 +1540,7 @@ static inline unsigned int vkd3d_write_mask_get_component_idx(DWORD write_mask)
|
|
return 0;
|
|
}
|
|
|
|
-static inline unsigned int vkd3d_write_mask_component_count(DWORD write_mask)
|
|
+static inline unsigned int vsir_write_mask_component_count(uint32_t write_mask)
|
|
{
|
|
unsigned int count = vkd3d_popcount(write_mask & VKD3DSP_WRITEMASK_ALL);
|
|
assert(1 <= count && count <= VKD3D_VEC4_SIZE);
|
|
@@ -1533,32 +1553,30 @@ static inline unsigned int vkd3d_write_mask_from_component_count(unsigned int co
|
|
return (VKD3DSP_WRITEMASK_0 << component_count) - 1;
|
|
}
|
|
|
|
-static inline unsigned int vkd3d_write_mask_64_from_32(DWORD write_mask32)
|
|
+static inline uint32_t vsir_write_mask_64_from_32(uint32_t write_mask32)
|
|
{
|
|
- unsigned int write_mask64 = write_mask32 | (write_mask32 >> 1);
|
|
+ uint32_t write_mask64 = write_mask32 | (write_mask32 >> 1);
|
|
return (write_mask64 & VKD3DSP_WRITEMASK_0) | ((write_mask64 & VKD3DSP_WRITEMASK_2) >> 1);
|
|
}
|
|
|
|
-static inline unsigned int vkd3d_write_mask_32_from_64(unsigned int write_mask64)
|
|
+static inline uint32_t vsir_write_mask_32_from_64(uint32_t write_mask64)
|
|
{
|
|
- unsigned int write_mask32 = (write_mask64 | (write_mask64 << 1))
|
|
+ uint32_t write_mask32 = (write_mask64 | (write_mask64 << 1))
|
|
& (VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_2);
|
|
return write_mask32 | (write_mask32 << 1);
|
|
}
|
|
|
|
-static inline unsigned int vkd3d_swizzle_get_component(DWORD swizzle,
|
|
- unsigned int idx)
|
|
+static inline unsigned int vsir_swizzle_get_component(uint32_t swizzle, unsigned int idx)
|
|
{
|
|
return (swizzle >> VKD3D_SHADER_SWIZZLE_SHIFT(idx)) & VKD3D_SHADER_SWIZZLE_MASK;
|
|
}
|
|
|
|
-static inline unsigned int vkd3d_swizzle_get_component64(DWORD swizzle,
|
|
- unsigned int idx)
|
|
+static inline unsigned int vsir_swizzle_get_component64(uint32_t swizzle, unsigned int idx)
|
|
{
|
|
return ((swizzle >> VKD3D_SHADER_SWIZZLE_SHIFT(idx * 2)) & VKD3D_SHADER_SWIZZLE_MASK) / 2u;
|
|
}
|
|
|
|
-static inline unsigned int vkd3d_compact_swizzle(unsigned int swizzle, unsigned int write_mask)
|
|
+static inline unsigned int vkd3d_compact_swizzle(uint32_t swizzle, uint32_t write_mask)
|
|
{
|
|
unsigned int i, compacted_swizzle = 0;
|
|
|
|
@@ -1567,7 +1585,7 @@ static inline unsigned int vkd3d_compact_swizzle(unsigned int swizzle, unsigned
|
|
if (write_mask & (VKD3DSP_WRITEMASK_0 << i))
|
|
{
|
|
compacted_swizzle <<= VKD3D_SHADER_SWIZZLE_SHIFT(1);
|
|
- compacted_swizzle |= vkd3d_swizzle_get_component(swizzle, i);
|
|
+ compacted_swizzle |= vsir_swizzle_get_component(swizzle, i);
|
|
}
|
|
}
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d/command.c b/libs/vkd3d/libs/vkd3d/command.c
|
|
index 15c8317b191..549f6a45ffb 100644
|
|
--- a/libs/vkd3d/libs/vkd3d/command.c
|
|
+++ b/libs/vkd3d/libs/vkd3d/command.c
|
|
@@ -2644,6 +2644,8 @@ static bool d3d12_command_list_update_compute_pipeline(struct d3d12_command_list
|
|
{
|
|
const struct vkd3d_vk_device_procs *vk_procs = &list->device->vk_procs;
|
|
|
|
+ vkd3d_cond_signal(&list->device->worker_cond);
|
|
+
|
|
if (list->current_pipeline != VK_NULL_HANDLE)
|
|
return true;
|
|
|
|
@@ -2665,6 +2667,8 @@ static bool d3d12_command_list_update_graphics_pipeline(struct d3d12_command_lis
|
|
VkRenderPass vk_render_pass;
|
|
VkPipeline vk_pipeline;
|
|
|
|
+ vkd3d_cond_signal(&list->device->worker_cond);
|
|
+
|
|
if (list->current_pipeline != VK_NULL_HANDLE)
|
|
return true;
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d/device.c b/libs/vkd3d/libs/vkd3d/device.c
|
|
index 5c801ca4676..69a46e9188a 100644
|
|
--- a/libs/vkd3d/libs/vkd3d/device.c
|
|
+++ b/libs/vkd3d/libs/vkd3d/device.c
|
|
@@ -2056,7 +2056,7 @@ static HRESULT d3d12_device_init_pipeline_cache(struct d3d12_device *device)
|
|
VkPipelineCacheCreateInfo cache_info;
|
|
VkResult vr;
|
|
|
|
- vkd3d_mutex_init(&device->mutex);
|
|
+ vkd3d_mutex_init(&device->pipeline_cache_mutex);
|
|
|
|
cache_info.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
|
|
cache_info.pNext = NULL;
|
|
@@ -2080,7 +2080,7 @@ static void d3d12_device_destroy_pipeline_cache(struct d3d12_device *device)
|
|
if (device->vk_pipeline_cache)
|
|
VK_CALL(vkDestroyPipelineCache(device->vk_device, device->vk_pipeline_cache, NULL));
|
|
|
|
- vkd3d_mutex_destroy(&device->mutex);
|
|
+ vkd3d_mutex_destroy(&device->pipeline_cache_mutex);
|
|
}
|
|
|
|
#define VKD3D_VA_FALLBACK_BASE 0x8000000000000000ull
|
|
@@ -2495,6 +2495,28 @@ static ULONG STDMETHODCALLTYPE d3d12_device_AddRef(ID3D12Device5 *iface)
|
|
return refcount;
|
|
}
|
|
|
|
+static HRESULT device_worker_stop(struct d3d12_device *device)
|
|
+{
|
|
+ HRESULT hr;
|
|
+
|
|
+ TRACE("device %p.\n", device);
|
|
+
|
|
+ vkd3d_mutex_lock(&device->worker_mutex);
|
|
+
|
|
+ device->worker_should_exit = true;
|
|
+ vkd3d_cond_signal(&device->worker_cond);
|
|
+
|
|
+ vkd3d_mutex_unlock(&device->worker_mutex);
|
|
+
|
|
+ if (FAILED(hr = vkd3d_join_thread(device->vkd3d_instance, &device->worker_thread)))
|
|
+ return hr;
|
|
+
|
|
+ vkd3d_mutex_destroy(&device->worker_mutex);
|
|
+ vkd3d_cond_destroy(&device->worker_cond);
|
|
+
|
|
+ return S_OK;
|
|
+}
|
|
+
|
|
static ULONG STDMETHODCALLTYPE d3d12_device_Release(ID3D12Device5 *iface)
|
|
{
|
|
struct d3d12_device *device = impl_from_ID3D12Device5(iface);
|
|
@@ -2520,6 +2542,9 @@ static ULONG STDMETHODCALLTYPE d3d12_device_Release(ID3D12Device5 *iface)
|
|
d3d12_device_destroy_vkd3d_queues(device);
|
|
vkd3d_desc_object_cache_cleanup(&device->view_desc_cache);
|
|
vkd3d_desc_object_cache_cleanup(&device->cbuffer_desc_cache);
|
|
+ if (device->use_vk_heaps)
|
|
+ device_worker_stop(device);
|
|
+ vkd3d_free(device->heaps);
|
|
VK_CALL(vkDestroyDevice(device->vk_device, NULL));
|
|
if (device->parent)
|
|
IUnknown_Release(device->parent);
|
|
@@ -4251,6 +4276,40 @@ struct d3d12_device *unsafe_impl_from_ID3D12Device5(ID3D12Device5 *iface)
|
|
return impl_from_ID3D12Device5(iface);
|
|
}
|
|
|
|
+static void *device_worker_main(void *arg)
|
|
+{
|
|
+ struct d3d12_descriptor_heap *heap;
|
|
+ struct d3d12_device *device = arg;
|
|
+ size_t i;
|
|
+
|
|
+ vkd3d_set_thread_name("device_worker");
|
|
+
|
|
+ vkd3d_mutex_lock(&device->worker_mutex);
|
|
+
|
|
+ while (!device->worker_should_exit)
|
|
+ {
|
|
+ for (i = 0; i < device->heap_count; ++i)
|
|
+ {
|
|
+ /* Descriptor updates are not written to Vulkan descriptor sets until a command list
|
|
+ * is submitted to a queue, while the client is free to write d3d12 descriptors earlier,
|
|
+ * from any thread. This causes a delay right before command list execution, so
|
|
+ * handling these updates in a worker thread can speed up execution significantly. */
|
|
+ heap = device->heaps[i];
|
|
+ if (heap->dirty_list_head == UINT_MAX)
|
|
+ continue;
|
|
+ vkd3d_mutex_lock(&heap->vk_sets_mutex);
|
|
+ d3d12_desc_flush_vk_heap_updates_locked(heap, device);
|
|
+ vkd3d_mutex_unlock(&heap->vk_sets_mutex);
|
|
+ }
|
|
+
|
|
+ vkd3d_cond_wait(&device->worker_cond, &device->worker_mutex);
|
|
+ }
|
|
+
|
|
+ vkd3d_mutex_unlock(&device->worker_mutex);
|
|
+
|
|
+ return NULL;
|
|
+}
|
|
+
|
|
static HRESULT d3d12_device_init(struct d3d12_device *device,
|
|
struct vkd3d_instance *instance, const struct vkd3d_device_create_info *create_info)
|
|
{
|
|
@@ -4270,6 +4329,14 @@ static HRESULT d3d12_device_init(struct d3d12_device *device,
|
|
|
|
device->vk_device = VK_NULL_HANDLE;
|
|
|
|
+ device->heaps = NULL;
|
|
+ device->heap_capacity = 0;
|
|
+ device->heap_count = 0;
|
|
+ memset(&device->worker_thread, 0, sizeof(device->worker_thread));
|
|
+ device->worker_should_exit = false;
|
|
+ vkd3d_mutex_init(&device->worker_mutex);
|
|
+ vkd3d_cond_init(&device->worker_cond);
|
|
+
|
|
if (FAILED(hr = vkd3d_create_vk_device(device, create_info)))
|
|
goto out_free_instance;
|
|
|
|
@@ -4291,6 +4358,13 @@ static HRESULT d3d12_device_init(struct d3d12_device *device,
|
|
if (FAILED(hr = vkd3d_vk_descriptor_heap_layouts_init(device)))
|
|
goto out_cleanup_uav_clear_state;
|
|
|
|
+ if (device->use_vk_heaps && FAILED(hr = vkd3d_create_thread(device->vkd3d_instance,
|
|
+ device_worker_main, device, &device->worker_thread)))
|
|
+ {
|
|
+ WARN("Failed to create worker thread, hr %#x.\n", hr);
|
|
+ goto out_cleanup_descriptor_heap_layouts;
|
|
+ }
|
|
+
|
|
vkd3d_render_pass_cache_init(&device->render_pass_cache);
|
|
vkd3d_gpu_va_allocator_init(&device->gpu_va_allocator);
|
|
vkd3d_time_domains_init(device);
|
|
@@ -4308,6 +4382,8 @@ static HRESULT d3d12_device_init(struct d3d12_device *device,
|
|
|
|
return S_OK;
|
|
|
|
+out_cleanup_descriptor_heap_layouts:
|
|
+ vkd3d_vk_descriptor_heap_layouts_cleanup(device);
|
|
out_cleanup_uav_clear_state:
|
|
vkd3d_uav_clear_state_cleanup(&device->uav_clear_state, device);
|
|
out_destroy_null_resources:
|
|
@@ -4361,6 +4437,40 @@ void d3d12_device_mark_as_removed(struct d3d12_device *device, HRESULT reason,
|
|
device->removed_reason = reason;
|
|
}
|
|
|
|
+HRESULT d3d12_device_add_descriptor_heap(struct d3d12_device *device, struct d3d12_descriptor_heap *heap)
|
|
+{
|
|
+ vkd3d_mutex_lock(&device->worker_mutex);
|
|
+
|
|
+ if (!vkd3d_array_reserve((void **)&device->heaps, &device->heap_capacity, device->heap_count + 1,
|
|
+ sizeof(*device->heaps)))
|
|
+ {
|
|
+ vkd3d_mutex_unlock(&device->worker_mutex);
|
|
+ return E_OUTOFMEMORY;
|
|
+ }
|
|
+ device->heaps[device->heap_count++] = heap;
|
|
+
|
|
+ vkd3d_mutex_unlock(&device->worker_mutex);
|
|
+
|
|
+ return S_OK;
|
|
+}
|
|
+
|
|
+void d3d12_device_remove_descriptor_heap(struct d3d12_device *device, struct d3d12_descriptor_heap *heap)
|
|
+{
|
|
+ size_t i;
|
|
+
|
|
+ vkd3d_mutex_lock(&device->worker_mutex);
|
|
+
|
|
+ for (i = 0; i < device->heap_count; ++i)
|
|
+ {
|
|
+ if (device->heaps[i] == heap)
|
|
+ {
|
|
+ device->heaps[i] = device->heaps[--device->heap_count];
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ vkd3d_mutex_unlock(&device->worker_mutex);
|
|
+}
|
|
|
|
#ifdef _WIN32
|
|
struct thread_data
|
|
diff --git a/libs/vkd3d/libs/vkd3d/resource.c b/libs/vkd3d/libs/vkd3d/resource.c
|
|
index abbdfbe2015..609c67102a6 100644
|
|
--- a/libs/vkd3d/libs/vkd3d/resource.c
|
|
+++ b/libs/vkd3d/libs/vkd3d/resource.c
|
|
@@ -2632,20 +2632,18 @@ void d3d12_desc_flush_vk_heap_updates_locked(struct d3d12_descriptor_heap *descr
|
|
for (; i != UINT_MAX; i = next)
|
|
{
|
|
src = &descriptors[i];
|
|
- next = (int)src->next >> 1;
|
|
+ next = vkd3d_atomic_exchange(&src->next, 0);
|
|
+ next = (int)next >> 1;
|
|
|
|
+ /* A race exists here between updating src->next and getting the current object. The best
|
|
+ * we can do is get the object last, which may result in a harmless rewrite later. */
|
|
u.object = d3d12_desc_get_object_ref(src, device);
|
|
|
|
if (!u.object)
|
|
- {
|
|
- vkd3d_atomic_exchange(&src->next, 0);
|
|
continue;
|
|
- }
|
|
|
|
writes.held_refs[writes.held_ref_count++] = u.object;
|
|
d3d12_desc_write_vk_heap(descriptor_heap, i, &writes, u.object, device);
|
|
-
|
|
- vkd3d_atomic_exchange(&src->next, 0);
|
|
}
|
|
|
|
/* Avoid thunk calls wherever possible. */
|
|
@@ -3997,6 +3995,9 @@ static ULONG STDMETHODCALLTYPE d3d12_descriptor_heap_Release(ID3D12DescriptorHea
|
|
{
|
|
struct d3d12_desc *descriptors = (struct d3d12_desc *)heap->descriptors;
|
|
|
|
+ if (heap->use_vk_heaps)
|
|
+ d3d12_device_remove_descriptor_heap(device, heap);
|
|
+
|
|
for (i = 0; i < heap->desc.NumDescriptors; ++i)
|
|
{
|
|
d3d12_desc_destroy(&descriptors[i], device);
|
|
@@ -4320,6 +4321,12 @@ HRESULT d3d12_descriptor_heap_create(struct d3d12_device *device,
|
|
dst[i].next = 0;
|
|
}
|
|
object->dirty_list_head = UINT_MAX;
|
|
+
|
|
+ if (object->use_vk_heaps && FAILED(hr = d3d12_device_add_descriptor_heap(device, object)))
|
|
+ {
|
|
+ vkd3d_free(object);
|
|
+ return hr;
|
|
+ }
|
|
}
|
|
else
|
|
{
|
|
diff --git a/libs/vkd3d/libs/vkd3d/state.c b/libs/vkd3d/libs/vkd3d/state.c
|
|
index fc3187f4bea..1457ddf9c7f 100644
|
|
--- a/libs/vkd3d/libs/vkd3d/state.c
|
|
+++ b/libs/vkd3d/libs/vkd3d/state.c
|
|
@@ -515,7 +515,7 @@ static HRESULT d3d12_root_signature_init_push_constants(struct d3d12_root_signat
|
|
assert(p->ShaderVisibility <= D3D12_SHADER_VISIBILITY_PIXEL);
|
|
push_constants[p->ShaderVisibility].stageFlags = use_vk_heaps ? VK_SHADER_STAGE_ALL
|
|
: stage_flags_from_visibility(p->ShaderVisibility);
|
|
- push_constants[p->ShaderVisibility].size += p->u.Constants.Num32BitValues * sizeof(uint32_t);
|
|
+ push_constants[p->ShaderVisibility].size += align(p->u.Constants.Num32BitValues, 4) * sizeof(uint32_t);
|
|
}
|
|
if (push_constants[D3D12_SHADER_VISIBILITY_ALL].size)
|
|
{
|
|
@@ -564,7 +564,7 @@ static HRESULT d3d12_root_signature_init_push_constants(struct d3d12_root_signat
|
|
|
|
idx = push_constant_count == 1 ? 0 : p->ShaderVisibility;
|
|
offset = push_constants_offset[idx];
|
|
- push_constants_offset[idx] += p->u.Constants.Num32BitValues * sizeof(uint32_t);
|
|
+ push_constants_offset[idx] += align(p->u.Constants.Num32BitValues, 4) * sizeof(uint32_t);
|
|
|
|
root_signature->parameters[i].parameter_type = p->ParameterType;
|
|
root_constant->stage_flags = push_constant_count == 1
|
|
@@ -1691,7 +1691,7 @@ HRESULT vkd3d_render_pass_cache_find(struct vkd3d_render_pass_cache *cache,
|
|
HRESULT hr = S_OK;
|
|
unsigned int i;
|
|
|
|
- vkd3d_mutex_lock(&device->mutex);
|
|
+ vkd3d_mutex_lock(&device->pipeline_cache_mutex);
|
|
|
|
for (i = 0; i < cache->render_pass_count; ++i)
|
|
{
|
|
@@ -1708,7 +1708,7 @@ HRESULT vkd3d_render_pass_cache_find(struct vkd3d_render_pass_cache *cache,
|
|
if (!found)
|
|
hr = vkd3d_render_pass_cache_create_pass_locked(cache, device, key, vk_render_pass);
|
|
|
|
- vkd3d_mutex_unlock(&device->mutex);
|
|
+ vkd3d_mutex_unlock(&device->pipeline_cache_mutex);
|
|
|
|
return hr;
|
|
}
|
|
@@ -2129,6 +2129,16 @@ static inline unsigned int typed_uav_compile_option(const struct d3d12_device *d
|
|
: VKD3D_SHADER_COMPILE_OPTION_TYPED_UAV_READ_FORMAT_R32;
|
|
}
|
|
|
|
+static unsigned int feature_flags_compile_option(const struct d3d12_device *device)
|
|
+{
|
|
+ unsigned int flags = 0;
|
|
+
|
|
+ if (device->feature_options1.Int64ShaderOps)
|
|
+ flags |= VKD3D_SHADER_COMPILE_OPTION_FEATURE_INT64;
|
|
+
|
|
+ return flags;
|
|
+}
|
|
+
|
|
static HRESULT create_shader_stage(struct d3d12_device *device,
|
|
struct VkPipelineShaderStageCreateInfo *stage_desc, enum VkShaderStageFlagBits stage,
|
|
const D3D12_SHADER_BYTECODE *code, const struct vkd3d_shader_interface_info *shader_interface)
|
|
@@ -2145,6 +2155,7 @@ static HRESULT create_shader_stage(struct d3d12_device *device,
|
|
{VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_10},
|
|
{VKD3D_SHADER_COMPILE_OPTION_TYPED_UAV, typed_uav_compile_option(device)},
|
|
{VKD3D_SHADER_COMPILE_OPTION_WRITE_TESS_GEOM_POINT_SIZE, 0},
|
|
+ {VKD3D_SHADER_COMPILE_OPTION_FEATURE, feature_flags_compile_option(device)},
|
|
};
|
|
|
|
stage_desc->sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
|
@@ -3615,7 +3626,7 @@ static VkPipeline d3d12_pipeline_state_find_compiled_pipeline(const struct d3d12
|
|
|
|
*vk_render_pass = VK_NULL_HANDLE;
|
|
|
|
- vkd3d_mutex_lock(&device->mutex);
|
|
+ vkd3d_mutex_lock(&device->pipeline_cache_mutex);
|
|
|
|
LIST_FOR_EACH_ENTRY(current, &graphics->compiled_pipelines, struct vkd3d_compiled_pipeline, entry)
|
|
{
|
|
@@ -3627,7 +3638,7 @@ static VkPipeline d3d12_pipeline_state_find_compiled_pipeline(const struct d3d12
|
|
}
|
|
}
|
|
|
|
- vkd3d_mutex_unlock(&device->mutex);
|
|
+ vkd3d_mutex_unlock(&device->pipeline_cache_mutex);
|
|
|
|
return vk_pipeline;
|
|
}
|
|
@@ -3646,7 +3657,7 @@ static bool d3d12_pipeline_state_put_pipeline_to_cache(struct d3d12_pipeline_sta
|
|
compiled_pipeline->vk_pipeline = vk_pipeline;
|
|
compiled_pipeline->vk_render_pass = vk_render_pass;
|
|
|
|
- vkd3d_mutex_lock(&device->mutex);
|
|
+ vkd3d_mutex_lock(&device->pipeline_cache_mutex);
|
|
|
|
LIST_FOR_EACH_ENTRY(current, &graphics->compiled_pipelines, struct vkd3d_compiled_pipeline, entry)
|
|
{
|
|
@@ -3661,7 +3672,7 @@ static bool d3d12_pipeline_state_put_pipeline_to_cache(struct d3d12_pipeline_sta
|
|
if (compiled_pipeline)
|
|
list_add_tail(&graphics->compiled_pipelines, &compiled_pipeline->entry);
|
|
|
|
- vkd3d_mutex_unlock(&device->mutex);
|
|
+ vkd3d_mutex_unlock(&device->pipeline_cache_mutex);
|
|
return compiled_pipeline;
|
|
}
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d/utils.c b/libs/vkd3d/libs/vkd3d/utils.c
|
|
index 9b28068be51..5ebe1b63e99 100644
|
|
--- a/libs/vkd3d/libs/vkd3d/utils.c
|
|
+++ b/libs/vkd3d/libs/vkd3d/utils.c
|
|
@@ -539,6 +539,7 @@ bool is_valid_feature_level(D3D_FEATURE_LEVEL feature_level)
|
|
{
|
|
static const D3D_FEATURE_LEVEL valid_feature_levels[] =
|
|
{
|
|
+ D3D_FEATURE_LEVEL_12_2,
|
|
D3D_FEATURE_LEVEL_12_1,
|
|
D3D_FEATURE_LEVEL_12_0,
|
|
D3D_FEATURE_LEVEL_11_1,
|
|
@@ -548,6 +549,7 @@ bool is_valid_feature_level(D3D_FEATURE_LEVEL feature_level)
|
|
D3D_FEATURE_LEVEL_9_3,
|
|
D3D_FEATURE_LEVEL_9_2,
|
|
D3D_FEATURE_LEVEL_9_1,
|
|
+ D3D_FEATURE_LEVEL_1_0_CORE,
|
|
};
|
|
unsigned int i;
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/libs/vkd3d/vkd3d_private.h
|
|
index f06f564d6ea..bd7e7290d9e 100644
|
|
--- a/libs/vkd3d/libs/vkd3d/vkd3d_private.h
|
|
+++ b/libs/vkd3d/libs/vkd3d/vkd3d_private.h
|
|
@@ -1757,9 +1757,23 @@ struct d3d12_device
|
|
|
|
struct vkd3d_gpu_va_allocator gpu_va_allocator;
|
|
|
|
- struct vkd3d_mutex mutex;
|
|
struct vkd3d_desc_object_cache view_desc_cache;
|
|
struct vkd3d_desc_object_cache cbuffer_desc_cache;
|
|
+
|
|
+ VkDescriptorPoolSize vk_pool_sizes[VKD3D_DESCRIPTOR_POOL_COUNT];
|
|
+ unsigned int vk_pool_count;
|
|
+ struct vkd3d_vk_descriptor_heap_layout vk_descriptor_heap_layouts[VKD3D_SET_INDEX_COUNT];
|
|
+ bool use_vk_heaps;
|
|
+
|
|
+ struct d3d12_descriptor_heap **heaps;
|
|
+ size_t heap_capacity;
|
|
+ size_t heap_count;
|
|
+ union vkd3d_thread_handle worker_thread;
|
|
+ struct vkd3d_mutex worker_mutex;
|
|
+ struct vkd3d_cond worker_cond;
|
|
+ bool worker_should_exit;
|
|
+
|
|
+ struct vkd3d_mutex pipeline_cache_mutex;
|
|
struct vkd3d_render_pass_cache render_pass_cache;
|
|
VkPipelineCache vk_pipeline_cache;
|
|
|
|
@@ -1799,11 +1813,6 @@ struct d3d12_device
|
|
const struct vkd3d_format_compatibility_list *format_compatibility_lists;
|
|
struct vkd3d_null_resources null_resources;
|
|
struct vkd3d_uav_clear_state uav_clear_state;
|
|
-
|
|
- VkDescriptorPoolSize vk_pool_sizes[VKD3D_DESCRIPTOR_POOL_COUNT];
|
|
- unsigned int vk_pool_count;
|
|
- struct vkd3d_vk_descriptor_heap_layout vk_descriptor_heap_layouts[VKD3D_SET_INDEX_COUNT];
|
|
- bool use_vk_heaps;
|
|
};
|
|
|
|
HRESULT d3d12_device_create(struct vkd3d_instance *instance,
|
|
@@ -1813,6 +1822,8 @@ bool d3d12_device_is_uma(struct d3d12_device *device, bool *coherent);
|
|
void d3d12_device_mark_as_removed(struct d3d12_device *device, HRESULT reason,
|
|
const char *message, ...) VKD3D_PRINTF_FUNC(3, 4);
|
|
struct d3d12_device *unsafe_impl_from_ID3D12Device5(ID3D12Device5 *iface);
|
|
+HRESULT d3d12_device_add_descriptor_heap(struct d3d12_device *device, struct d3d12_descriptor_heap *heap);
|
|
+void d3d12_device_remove_descriptor_heap(struct d3d12_device *device, struct d3d12_descriptor_heap *heap);
|
|
|
|
static inline HRESULT d3d12_device_query_interface(struct d3d12_device *device, REFIID iid, void **object)
|
|
{
|
|
--
|
|
2.43.0
|
|
|