2023-12-15 15:17:11 -08:00
|
|
|
From 81c388b185d602d9c66222118abe9dcbd3742a47 Mon Sep 17 00:00:00 2001
|
2023-12-12 23:30:39 -08:00
|
|
|
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
|
|
|
|
Date: Wed, 13 Dec 2023 09:32:05 +1100
|
|
|
|
Subject: [PATCH] Updated vkd3d to 1015cc952e42828d79a68cfa0e659cac53772676.
|
|
|
|
|
|
|
|
---
|
|
|
|
libs/vkd3d/include/vkd3d_shader.h | 18 ++
|
|
|
|
libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 73 +++++-
|
|
|
|
libs/vkd3d/libs/vkd3d-shader/dxbc.c | 4 -
|
|
|
|
libs/vkd3d/libs/vkd3d-shader/dxil.c | 222 +++++++++++++-----
|
|
|
|
libs/vkd3d/libs/vkd3d-shader/spirv.c | 220 ++++++++++-------
|
|
|
|
libs/vkd3d/libs/vkd3d-shader/tpf.c | 16 ++
|
|
|
|
.../libs/vkd3d-shader/vkd3d_shader_main.c | 4 +-
|
|
|
|
.../libs/vkd3d-shader/vkd3d_shader_private.h | 11 +-
|
|
|
|
8 files changed, 395 insertions(+), 173 deletions(-)
|
|
|
|
|
|
|
|
diff --git a/libs/vkd3d/include/vkd3d_shader.h b/libs/vkd3d/include/vkd3d_shader.h
|
|
|
|
index 290f9085d2d..a6bf8964183 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),
|
|
|
|
};
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c
|
|
|
|
index 82d1d71d9d3..2d52ee07724 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
|
|
|
|
{
|
|
|
|
@@ -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)
|
|
|
|
{
|
|
|
|
@@ -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,
|
|
|
|
@@ -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;
|
|
|
|
@@ -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/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 a1065c8bc45..602056e25d4 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};
|
|
|
|
@@ -2688,12 +2691,15 @@ static void sm6_parser_declare_icb(struct sm6_parser *sm6, const struct sm6_type
|
|
|
|
}
|
|
|
|
|
|
|
|
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)
|
|
|
|
+ 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);
|
|
|
|
- struct vkd3d_shader_instruction *ins;
|
|
|
|
|
|
|
|
- ins = sm6_parser_add_instruction(sm6, VKD3DSIH_DCL_INDEXABLE_TEMP);
|
|
|
|
+ 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;
|
|
|
|
@@ -2826,7 +2832,7 @@ static bool sm6_parser_declare_global(struct sm6_parser *sm6, const struct dxil_
|
|
|
|
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, dst);
|
|
|
|
+ sm6_parser_declare_indexable_temp(sm6, scalar_type, count, alignment, init, NULL, dst);
|
|
|
|
}
|
|
|
|
else if (address_space == ADDRESS_SPACE_GROUPSHARED)
|
|
|
|
{
|
|
|
|
@@ -2854,17 +2860,19 @@ 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)
|
|
|
|
@@ -2987,45 +2995,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);
|
|
|
|
@@ -3036,19 +3005,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;
|
|
|
|
@@ -3071,6 +3027,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)
|
|
|
|
{
|
|
|
|
@@ -3171,8 +3202,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))
|
|
|
|
@@ -3246,6 +3279,12 @@ 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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@@ -3963,8 +4002,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))
|
|
|
|
@@ -4253,6 +4294,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)
|
|
|
|
{
|
|
|
|
@@ -4630,6 +4722,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;
|
|
|
|
@@ -4656,6 +4751,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;
|
|
|
|
@@ -5040,7 +5138,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)
|
|
|
|
@@ -6111,8 +6209,6 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t
|
|
|
|
"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;
|
|
|
|
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c
|
|
|
|
index a22c59577ac..db45920200d 100644
|
|
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/spirv.c
|
|
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c
|
|
|
|
@@ -2170,6 +2170,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)
|
|
|
|
@@ -2387,6 +2396,7 @@ 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;
|
|
|
|
@@ -2544,6 +2554,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;
|
|
|
|
@@ -4496,9 +4510,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);
|
|
|
|
@@ -4511,9 +4525,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);
|
|
|
|
@@ -4748,10 +4762,9 @@ 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;
|
|
|
|
@@ -4767,26 +4780,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]))
|
|
|
|
@@ -4822,7 +4830,7 @@ static uint32_t spirv_compiler_emit_input(struct spirv_compiler *compiler,
|
|
|
|
|
|
|
|
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)))
|
|
|
|
{
|
|
|
|
@@ -4830,7 +4838,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;
|
|
|
|
@@ -4839,7 +4847,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
|
|
|
|
@@ -4849,7 +4857,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);
|
|
|
|
@@ -4876,12 +4884,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);
|
|
|
|
|
|
|
|
@@ -4898,9 +4908,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;
|
|
|
|
@@ -5069,7 +5079,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);
|
|
|
|
}
|
|
|
|
|
|
|
|
@@ -5098,10 +5108,10 @@ 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;
|
|
|
|
@@ -5113,26 +5123,24 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler, const st
|
|
|
|
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;
|
|
|
|
|
|
|
|
@@ -5151,15 +5159,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))
|
|
|
|
{
|
|
|
|
@@ -5168,7 +5179,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;
|
|
|
|
}
|
|
|
|
@@ -5179,7 +5190,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)
|
|
|
|
{
|
|
|
|
@@ -5220,8 +5231,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)
|
|
|
|
@@ -5239,8 +5253,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)
|
|
|
|
{
|
|
|
|
@@ -5518,6 +5531,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
|
|
|
|
@@ -6212,37 +6240,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)
|
|
|
|
{
|
|
|
|
@@ -6442,7 +6455,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)
|
|
|
|
@@ -6460,7 +6472,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));
|
|
|
|
}
|
|
|
|
@@ -6503,15 +6514,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);
|
|
|
|
@@ -6531,6 +6539,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);
|
|
|
|
@@ -6538,22 +6548,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);
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
@@ -6780,8 +6784,8 @@ 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);
|
|
|
|
@@ -6942,6 +6946,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, vkd3d_write_mask_component_count(dst->write_mask)), val_id);
|
|
|
|
+ }
|
|
|
|
spirv_compiler_emit_store_dst(compiler, dst, val_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
@@ -7150,6 +7159,13 @@ static void spirv_compiler_emit_int_div(struct spirv_compiler *compiler,
|
|
|
|
div_op = instruction->handler_idx == VKD3DSIH_IDIV ? SpvOpSDiv : SpvOpUDiv;
|
|
|
|
mod_op = instruction->handler_idx == VKD3DSIH_IDIV ? SpvOpSRem : SpvOpUMod;
|
|
|
|
|
|
|
|
+ if (dst[0].reg.data_type == VKD3D_DATA_UINT64 || dst[1].reg.data_type == VKD3D_DATA_UINT64)
|
|
|
|
+ {
|
|
|
|
+ FIXME("Unsupported 64-bit result.\n");
|
|
|
|
+ spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_UNSUPPORTED_FEATURE,
|
|
|
|
+ "Bool cast to 64-bit integer is not supported.");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
if (dst[0].reg.type != VKD3DSPR_NULL)
|
|
|
|
{
|
|
|
|
component_count = vkd3d_write_mask_component_count(dst[0].write_mask);
|
|
|
|
@@ -9490,18 +9506,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;
|
|
|
|
@@ -9784,6 +9791,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:
|
|
|
|
@@ -9805,6 +9817,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;
|
|
|
|
@@ -9891,6 +9927,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;
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c
|
|
|
|
index 163cd90ee13..1b009c13016 100644
|
|
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/tpf.c
|
|
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c
|
|
|
|
@@ -2544,6 +2544,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)
|
|
|
|
{
|
|
|
|
@@ -2639,6 +2649,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,
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
|
|
|
|
index d4a9d391477..4fd5c9bd034 100644
|
|
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
|
|
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
|
|
|
|
@@ -1546,7 +1546,7 @@ static int vkd3d_shader_parser_compile(struct vkd3d_shader_parser *parser,
|
|
|
|
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:
|
|
|
|
@@ -1623,7 +1623,7 @@ static int compile_d3d_bytecode(const struct vkd3d_shader_compile_info *compile_
|
|
|
|
|
|
|
|
if (compile_info->target_type == 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);
|
|
|
|
vkd3d_shader_parser_destroy(parser);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
|
|
|
|
index 4944b8a1c53..0e8d75d9897 100644
|
|
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
|
|
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
|
|
|
|
@@ -91,7 +91,7 @@ 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,
|
|
|
|
@@ -741,6 +741,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
|
|
|
|
@@ -1314,9 +1315,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);
|
|
|
|
--
|
|
|
|
2.43.0
|
|
|
|
|