mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-11-21 16:46:54 -08:00
1243 lines
51 KiB
Diff
1243 lines
51 KiB
Diff
From fe3714ac04e56180db0ac935c92bba21308de94d Mon Sep 17 00:00:00 2001
|
|
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
|
|
Date: Thu, 28 Mar 2024 10:39:27 +1100
|
|
Subject: [PATCH] Updated vkd3d to b1eaf8327bf59b516f80e232e86332473ed97edc.
|
|
|
|
---
|
|
libs/vkd3d/include/private/vkd3d_common.h | 2 +
|
|
libs/vkd3d/include/private/vkd3d_memory.h | 9 +
|
|
libs/vkd3d/include/vkd3d_shader.h | 17 +-
|
|
libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 30 +++
|
|
libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 8 +
|
|
libs/vkd3d/libs/vkd3d-shader/dxil.c | 254 ++++++++++++++++++
|
|
libs/vkd3d/libs/vkd3d-shader/fx.c | 68 ++++-
|
|
libs/vkd3d/libs/vkd3d-shader/hlsl.c | 40 ++-
|
|
libs/vkd3d/libs/vkd3d-shader/hlsl.h | 1 +
|
|
libs/vkd3d/libs/vkd3d-shader/hlsl.y | 12 +-
|
|
libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 55 +++-
|
|
libs/vkd3d/libs/vkd3d-shader/spirv.c | 36 ++-
|
|
libs/vkd3d/libs/vkd3d-shader/tpf.c | 121 +++------
|
|
.../libs/vkd3d-shader/vkd3d_shader_private.h | 11 +
|
|
14 files changed, 539 insertions(+), 125 deletions(-)
|
|
|
|
diff --git a/libs/vkd3d/include/private/vkd3d_common.h b/libs/vkd3d/include/private/vkd3d_common.h
|
|
index 974ff9446db..1cc8ecc38f3 100644
|
|
--- a/libs/vkd3d/include/private/vkd3d_common.h
|
|
+++ b/libs/vkd3d/include/private/vkd3d_common.h
|
|
@@ -75,6 +75,8 @@
|
|
#define TAG_XNAP VKD3D_MAKE_TAG('X', 'N', 'A', 'P')
|
|
#define TAG_XNAS VKD3D_MAKE_TAG('X', 'N', 'A', 'S')
|
|
|
|
+#define TAG_RD11_REVERSE 0x25441313
|
|
+
|
|
static inline uint64_t align(uint64_t addr, size_t alignment)
|
|
{
|
|
return (addr + (alignment - 1)) & ~(alignment - 1);
|
|
diff --git a/libs/vkd3d/include/private/vkd3d_memory.h b/libs/vkd3d/include/private/vkd3d_memory.h
|
|
index bb177e39add..682d35c03c6 100644
|
|
--- a/libs/vkd3d/include/private/vkd3d_memory.h
|
|
+++ b/libs/vkd3d/include/private/vkd3d_memory.h
|
|
@@ -65,6 +65,15 @@ static inline char *vkd3d_strdup(const char *string)
|
|
return ptr;
|
|
}
|
|
|
|
+static inline void *vkd3d_memdup(const void *mem, size_t size)
|
|
+{
|
|
+ void *ptr;
|
|
+
|
|
+ if ((ptr = vkd3d_malloc(size)))
|
|
+ memcpy(ptr, mem, size);
|
|
+ return ptr;
|
|
+}
|
|
+
|
|
bool vkd3d_array_reserve(void **elements, size_t *capacity, size_t element_count, size_t element_size);
|
|
|
|
#endif /* __VKD3D_MEMORY_H */
|
|
diff --git a/libs/vkd3d/include/vkd3d_shader.h b/libs/vkd3d/include/vkd3d_shader.h
|
|
index 83b90474af4..0ce2ef67b50 100644
|
|
--- a/libs/vkd3d/include/vkd3d_shader.h
|
|
+++ b/libs/vkd3d/include/vkd3d_shader.h
|
|
@@ -302,12 +302,25 @@ enum vkd3d_shader_compile_option_name
|
|
/**
|
|
* If \a value is non-zero compilation will produce a child effect using
|
|
* shared object descriptions, as instructed by the "shared" modifier.
|
|
- * Child effects are supported with fx_2_0, fx_4_0, and fx_4_1. This option
|
|
- * and "shared" modifiers are ignored for fx_5_0 profile, and non-fx profiles.
|
|
+ * Child effects are supported with fx_4_0, and fx_4_1 profiles. This option
|
|
+ * and "shared" modifiers are ignored for the fx_5_0 profile and non-fx profiles.
|
|
+ * The fx_2_0 profile does not have a separate concept of child effects, variables
|
|
+ * marked with "shared" modifier will be marked as such in a binary.
|
|
*
|
|
* \since 1.12
|
|
*/
|
|
VKD3D_SHADER_COMPILE_OPTION_CHILD_EFFECT = 0x0000000b,
|
|
+ /**
|
|
+ * If \a value is nonzero, emit a compile warning warn when vectors or
|
|
+ * matrices are truncated in an implicit conversion.
|
|
+ * If warnings are disabled, this option has no effect.
|
|
+ * This option has no effects for targets other than HLSL.
|
|
+ *
|
|
+ * The default value is nonzero, i.e. enable implicit truncation warnings.
|
|
+ *
|
|
+ * \since 1.12
|
|
+ */
|
|
+ VKD3D_SHADER_COMPILE_OPTION_WARN_IMPLICIT_TRUNCATION = 0x0000000c,
|
|
|
|
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 0623a129eae..2b5feb94103 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c
|
|
@@ -448,6 +448,23 @@ static void shader_dump_global_flags(struct vkd3d_d3d_asm_compiler *compiler,
|
|
vkd3d_string_buffer_printf(&compiler->buffer, "unknown_flags(%#"PRIx64")", (uint64_t)global_flags);
|
|
}
|
|
|
|
+static void shader_dump_atomic_op_flags(struct vkd3d_d3d_asm_compiler *compiler, uint32_t atomic_flags)
|
|
+{
|
|
+ if (atomic_flags & VKD3DARF_SEQ_CST)
|
|
+ {
|
|
+ vkd3d_string_buffer_printf(&compiler->buffer, "_seqCst");
|
|
+ atomic_flags &= ~VKD3DARF_SEQ_CST;
|
|
+ }
|
|
+ if (atomic_flags & VKD3DARF_VOLATILE)
|
|
+ {
|
|
+ vkd3d_string_buffer_printf(&compiler->buffer, "_volatile");
|
|
+ atomic_flags &= ~VKD3DARF_VOLATILE;
|
|
+ }
|
|
+
|
|
+ if (atomic_flags)
|
|
+ vkd3d_string_buffer_printf(&compiler->buffer, "_unknown_flags(%#x)", atomic_flags);
|
|
+}
|
|
+
|
|
static void shader_dump_sync_flags(struct vkd3d_d3d_asm_compiler *compiler, uint32_t sync_flags)
|
|
{
|
|
if (sync_flags & VKD3DSSF_GLOBAL_UAV)
|
|
@@ -1734,6 +1751,19 @@ static void shader_dump_instruction_flags(struct vkd3d_d3d_asm_compiler *compile
|
|
}
|
|
break;
|
|
|
|
+ case VKD3DSIH_IMM_ATOMIC_CMP_EXCH:
|
|
+ case VKD3DSIH_IMM_ATOMIC_IADD:
|
|
+ case VKD3DSIH_IMM_ATOMIC_AND:
|
|
+ case VKD3DSIH_IMM_ATOMIC_IMAX:
|
|
+ case VKD3DSIH_IMM_ATOMIC_IMIN:
|
|
+ case VKD3DSIH_IMM_ATOMIC_OR:
|
|
+ case VKD3DSIH_IMM_ATOMIC_UMAX:
|
|
+ case VKD3DSIH_IMM_ATOMIC_UMIN:
|
|
+ case VKD3DSIH_IMM_ATOMIC_EXCH:
|
|
+ case VKD3DSIH_IMM_ATOMIC_XOR:
|
|
+ shader_dump_atomic_op_flags(compiler, ins->flags);
|
|
+ break;
|
|
+
|
|
case VKD3DSIH_SYNC:
|
|
shader_dump_sync_flags(compiler, ins->flags);
|
|
break;
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
|
|
index 3b935b07d61..099729fbb6c 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
|
|
@@ -2333,6 +2333,14 @@ static void write_sm1_expr(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b
|
|
}
|
|
break;
|
|
|
|
+ case HLSL_OP2_LOGIC_AND:
|
|
+ write_sm1_binary_op(ctx, buffer, D3DSIO_MIN, &instr->reg, &arg1->reg, &arg2->reg);
|
|
+ break;
|
|
+
|
|
+ case HLSL_OP2_LOGIC_OR:
|
|
+ write_sm1_binary_op(ctx, buffer, D3DSIO_MAX, &instr->reg, &arg1->reg, &arg2->reg);
|
|
+ break;
|
|
+
|
|
case HLSL_OP2_SLT:
|
|
if (ctx->profile->type == VKD3D_SHADER_TYPE_PIXEL)
|
|
hlsl_fixme(ctx, &instr->loc, "Lower SLT instructions for pixel shaders.");
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c
|
|
index 7f9a74fa737..0787ee13930 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/dxil.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c
|
|
@@ -401,10 +401,15 @@ enum dx_intrinsic_opcode
|
|
DX_ATOMIC_BINOP = 78,
|
|
DX_ATOMIC_CMP_XCHG = 79,
|
|
DX_BARRIER = 80,
|
|
+ DX_DISCARD = 82,
|
|
DX_DERIV_COARSEX = 83,
|
|
DX_DERIV_COARSEY = 84,
|
|
DX_DERIV_FINEX = 85,
|
|
DX_DERIV_FINEY = 86,
|
|
+ DX_THREAD_ID = 93,
|
|
+ DX_GROUP_ID = 94,
|
|
+ DX_THREAD_ID_IN_GROUP = 95,
|
|
+ DX_FLATTENED_THREAD_ID_IN_GROUP = 96,
|
|
DX_SPLIT_DOUBLE = 102,
|
|
DX_LEGACY_F32TOF16 = 130,
|
|
DX_LEGACY_F16TOF32 = 131,
|
|
@@ -459,6 +464,32 @@ enum dxil_predicate
|
|
ICMP_SLE = 41,
|
|
};
|
|
|
|
+enum dxil_rmw_code
|
|
+{
|
|
+ RMW_XCHG = 0,
|
|
+ RMW_ADD = 1,
|
|
+ RMW_SUB = 2,
|
|
+ RMW_AND = 3,
|
|
+ RMW_NAND = 4,
|
|
+ RMW_OR = 5,
|
|
+ RMW_XOR = 6,
|
|
+ RMW_MAX = 7,
|
|
+ RMW_MIN = 8,
|
|
+ RMW_UMAX = 9,
|
|
+ RMW_UMIN = 10,
|
|
+};
|
|
+
|
|
+enum dxil_atomic_ordering
|
|
+{
|
|
+ ORDERING_NOTATOMIC = 0,
|
|
+ ORDERING_UNORDERED = 1,
|
|
+ ORDERING_MONOTONIC = 2,
|
|
+ ORDERING_ACQUIRE = 3,
|
|
+ ORDERING_RELEASE = 4,
|
|
+ ORDERING_ACQREL = 5,
|
|
+ ORDERING_SEQCST = 6,
|
|
+};
|
|
+
|
|
enum dxil_atomic_binop_code
|
|
{
|
|
ATOMIC_BINOP_ADD,
|
|
@@ -758,6 +789,7 @@ struct sm6_parser
|
|
|
|
struct vkd3d_shader_dst_param *output_params;
|
|
struct vkd3d_shader_dst_param *input_params;
|
|
+ uint32_t input_regs_declared[(VKD3DSPR_COUNT + 0x1f) / 0x20];
|
|
|
|
struct sm6_function *functions;
|
|
size_t function_count;
|
|
@@ -2588,6 +2620,18 @@ static bool sm6_value_validate_is_bool(const struct sm6_value *value, struct sm6
|
|
return true;
|
|
}
|
|
|
|
+static bool sm6_value_validate_is_pointer_to_i32(const struct sm6_value *value, struct sm6_parser *sm6)
|
|
+{
|
|
+ if (!sm6_type_is_pointer(value->type) || !sm6_type_is_i32(value->type->u.pointer.type))
|
|
+ {
|
|
+ WARN("Operand result type %u is not a pointer to i32.\n", value->type->class);
|
|
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
|
|
+ "An int32 pointer operand passed to a DXIL instruction is not an int32 pointer.");
|
|
+ return false;
|
|
+ }
|
|
+ return true;
|
|
+}
|
|
+
|
|
static const struct sm6_value *sm6_parser_get_value_safe(struct sm6_parser *sm6, unsigned int idx)
|
|
{
|
|
if (idx < sm6->value_count)
|
|
@@ -2960,6 +3004,8 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const
|
|
|
|
default:
|
|
FIXME("Unhandled constant code %u.\n", record->code);
|
|
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
|
|
+ "Constant code %u is unhandled.", record->code);
|
|
dst->u.reg.type = VKD3DSPR_UNDEF;
|
|
break;
|
|
}
|
|
@@ -3500,6 +3546,9 @@ struct function_emission_state
|
|
unsigned int temp_idx;
|
|
};
|
|
|
|
+static bool sm6_parser_emit_reg_composite_construct(struct sm6_parser *sm6, const struct vkd3d_shader_register **operand_regs,
|
|
+ unsigned int component_count, struct function_emission_state *state, struct vkd3d_shader_register *reg);
|
|
+
|
|
static void sm6_parser_emit_alloca(struct sm6_parser *sm6, const struct dxil_record *record,
|
|
struct vkd3d_shader_instruction *ins, struct sm6_value *dst)
|
|
{
|
|
@@ -3575,6 +3624,129 @@ static void sm6_parser_emit_alloca(struct sm6_parser *sm6, const struct dxil_rec
|
|
sm6_parser_declare_indexable_temp(sm6, elem_type, type[0]->u.array.count, alignment, true, 0, ins, dst);
|
|
}
|
|
|
|
+static enum vkd3d_shader_opcode map_dx_atomicrmw_op(uint64_t code)
|
|
+{
|
|
+ switch (code)
|
|
+ {
|
|
+ case RMW_ADD:
|
|
+ return VKD3DSIH_IMM_ATOMIC_IADD;
|
|
+ case RMW_AND:
|
|
+ return VKD3DSIH_IMM_ATOMIC_AND;
|
|
+ case RMW_MAX:
|
|
+ return VKD3DSIH_IMM_ATOMIC_IMAX;
|
|
+ case RMW_MIN:
|
|
+ return VKD3DSIH_IMM_ATOMIC_IMIN;
|
|
+ case RMW_OR:
|
|
+ return VKD3DSIH_IMM_ATOMIC_OR;
|
|
+ case RMW_UMAX:
|
|
+ return VKD3DSIH_IMM_ATOMIC_UMAX;
|
|
+ case RMW_UMIN:
|
|
+ return VKD3DSIH_IMM_ATOMIC_UMIN;
|
|
+ case RMW_XCHG:
|
|
+ return VKD3DSIH_IMM_ATOMIC_EXCH;
|
|
+ case RMW_XOR:
|
|
+ return VKD3DSIH_IMM_ATOMIC_XOR;
|
|
+ default:
|
|
+ /* DXIL currently doesn't use SUB and NAND. */
|
|
+ return VKD3DSIH_INVALID;
|
|
+ }
|
|
+}
|
|
+
|
|
+static void sm6_parser_emit_atomicrmw(struct sm6_parser *sm6, const struct dxil_record *record,
|
|
+ struct function_emission_state *state, struct sm6_value *dst)
|
|
+{
|
|
+ struct vkd3d_shader_register coord, const_offset, const_zero;
|
|
+ const struct vkd3d_shader_register *regs[2];
|
|
+ struct vkd3d_shader_dst_param *dst_params;
|
|
+ struct vkd3d_shader_src_param *src_params;
|
|
+ struct vkd3d_shader_instruction *ins;
|
|
+ const struct sm6_value *ptr, *src;
|
|
+ enum vkd3d_shader_opcode op;
|
|
+ unsigned int i = 0;
|
|
+ bool is_volatile;
|
|
+ uint64_t code;
|
|
+
|
|
+ if (!(ptr = sm6_parser_get_value_by_ref(sm6, record, NULL, &i))
|
|
+ || !sm6_value_validate_is_pointer_to_i32(ptr, sm6))
|
|
+ return;
|
|
+
|
|
+ if (ptr->u.reg.type != VKD3DSPR_GROUPSHAREDMEM)
|
|
+ {
|
|
+ WARN("Register is not groupshared.\n");
|
|
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
|
|
+ "The destination register for an atomicrmw instruction is not groupshared memory.");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ dst->type = ptr->type->u.pointer.type;
|
|
+
|
|
+ if (!(src = sm6_parser_get_value_by_ref(sm6, record, dst->type, &i)))
|
|
+ return;
|
|
+
|
|
+ if (!dxil_record_validate_operand_count(record, i + 4, i + 4, sm6))
|
|
+ return;
|
|
+
|
|
+ if ((op = map_dx_atomicrmw_op(code = record->operands[i++])) == VKD3DSIH_INVALID)
|
|
+ {
|
|
+ FIXME("Unhandled atomicrmw op %"PRIu64".\n", code);
|
|
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
|
|
+ "Operation %"PRIu64" for an atomicrmw instruction is unhandled.", code);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ is_volatile = record->operands[i++];
|
|
+
|
|
+ /* It's currently not possible to specify an atomic ordering in HLSL, and it defaults to seq_cst. */
|
|
+ if ((code = record->operands[i++]) != ORDERING_SEQCST)
|
|
+ FIXME("Unhandled atomic ordering %"PRIu64".\n", code);
|
|
+
|
|
+ if ((code = record->operands[i]) != 1)
|
|
+ WARN("Ignoring synchronisation scope %"PRIu64".\n", code);
|
|
+
|
|
+ if (ptr->structure_stride)
|
|
+ {
|
|
+ if (ptr->u.reg.idx[1].rel_addr)
|
|
+ {
|
|
+ regs[0] = &ptr->u.reg.idx[1].rel_addr->reg;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ register_make_constant_uint(&const_offset, ptr->u.reg.idx[1].offset);
|
|
+ regs[0] = &const_offset;
|
|
+ }
|
|
+ register_make_constant_uint(&const_zero, 0);
|
|
+ regs[1] = &const_zero;
|
|
+ if (!sm6_parser_emit_reg_composite_construct(sm6, regs, 2, state, &coord))
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ ins = state->ins;
|
|
+ vsir_instruction_init(ins, &sm6->p.location, op);
|
|
+ ins->flags = is_volatile ? VKD3DARF_SEQ_CST | VKD3DARF_VOLATILE : VKD3DARF_SEQ_CST;
|
|
+
|
|
+ if (!(src_params = instruction_src_params_alloc(ins, 2, sm6)))
|
|
+ return;
|
|
+ if (ptr->structure_stride)
|
|
+ src_param_init_vector_from_reg(&src_params[0], &coord);
|
|
+ else
|
|
+ src_param_make_constant_uint(&src_params[0], 0);
|
|
+ src_param_init_from_value(&src_params[1], src);
|
|
+
|
|
+ dst_params = instruction_dst_params_alloc(ins, 2, sm6);
|
|
+ register_init_ssa_scalar(&dst_params[0].reg, dst->type, dst, sm6);
|
|
+ dst_param_init(&dst_params[0]);
|
|
+
|
|
+ dst_params[1].reg = ptr->u.reg;
|
|
+ /* The groupshared register has data type UAV when accessed. */
|
|
+ dst_params[1].reg.data_type = VKD3D_DATA_UAV;
|
|
+ dst_params[1].reg.idx[1].rel_addr = NULL;
|
|
+ dst_params[1].reg.idx[1].offset = ~0u;
|
|
+ dst_params[1].reg.idx_count = 1;
|
|
+ dst_param_init(&dst_params[1]);
|
|
+
|
|
+ dst->u.reg = dst_params[0].reg;
|
|
+}
|
|
+
|
|
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)
|
|
{
|
|
@@ -4212,6 +4384,22 @@ static void sm6_parser_emit_dx_cbuffer_load(struct sm6_parser *sm6, enum dx_intr
|
|
instruction_dst_param_init_ssa_vector(ins, sm6_type_max_vector_size(type), sm6);
|
|
}
|
|
|
|
+static void sm6_parser_dcl_register_builtin(struct sm6_parser *sm6,
|
|
+ enum vkd3d_shader_register_type reg_type, enum vkd3d_data_type data_type, unsigned int component_count)
|
|
+{
|
|
+ struct vkd3d_shader_dst_param *dst_param;
|
|
+ struct vkd3d_shader_instruction *ins;
|
|
+
|
|
+ if (!bitmap_is_set(sm6->input_regs_declared, reg_type))
|
|
+ {
|
|
+ bitmap_set(sm6->input_regs_declared, reg_type);
|
|
+ ins = sm6_parser_add_instruction(sm6, VKD3DSIH_DCL_INPUT);
|
|
+ dst_param = &ins->declaration.dst;
|
|
+ vsir_register_init(&dst_param->reg, reg_type, data_type, 0);
|
|
+ dst_param_init_vector(dst_param, component_count);
|
|
+ }
|
|
+}
|
|
+
|
|
static const struct sm6_descriptor_info *sm6_parser_get_descriptor(struct sm6_parser *sm6,
|
|
enum vkd3d_shader_descriptor_type type, unsigned int id, const struct sm6_value *address)
|
|
{
|
|
@@ -4273,6 +4461,18 @@ static void sm6_parser_emit_dx_create_handle(struct sm6_parser *sm6, enum dx_int
|
|
ins->handler_idx = VKD3DSIH_NOP;
|
|
}
|
|
|
|
+static void sm6_parser_emit_dx_discard(struct sm6_parser *sm6, enum dx_intrinsic_opcode op,
|
|
+ const struct sm6_value **operands, struct function_emission_state *state)
|
|
+{
|
|
+ struct vkd3d_shader_instruction *ins = state->ins;
|
|
+ struct vkd3d_shader_src_param *src_param;
|
|
+
|
|
+ vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_DISCARD);
|
|
+
|
|
+ if ((src_param = instruction_src_params_alloc(ins, 1, sm6)))
|
|
+ src_param_init_from_value(src_param, operands[0]);
|
|
+}
|
|
+
|
|
static void sm6_parser_emit_dx_fabs(struct sm6_parser *sm6, enum dx_intrinsic_opcode op,
|
|
const struct sm6_value **operands, struct function_emission_state *state)
|
|
{
|
|
@@ -4288,6 +4488,48 @@ static void sm6_parser_emit_dx_fabs(struct sm6_parser *sm6, enum dx_intrinsic_op
|
|
instruction_dst_param_init_ssa_scalar(ins, sm6);
|
|
}
|
|
|
|
+static void sm6_parser_emit_dx_compute_builtin(struct sm6_parser *sm6, enum dx_intrinsic_opcode op,
|
|
+ const struct sm6_value **operands, struct function_emission_state *state)
|
|
+{
|
|
+ unsigned int component_count = 3, component_idx = 0;
|
|
+ struct vkd3d_shader_instruction *ins = state->ins;
|
|
+ struct vkd3d_shader_src_param *src_param;
|
|
+ enum vkd3d_shader_register_type reg_type;
|
|
+
|
|
+ switch (op)
|
|
+ {
|
|
+ case DX_THREAD_ID:
|
|
+ reg_type = VKD3DSPR_THREADID;
|
|
+ break;
|
|
+ case DX_GROUP_ID:
|
|
+ reg_type = VKD3DSPR_THREADGROUPID;
|
|
+ break;
|
|
+ case DX_THREAD_ID_IN_GROUP:
|
|
+ reg_type = VKD3DSPR_LOCALTHREADID;
|
|
+ break;
|
|
+ case DX_FLATTENED_THREAD_ID_IN_GROUP:
|
|
+ reg_type = VKD3DSPR_LOCALTHREADINDEX;
|
|
+ component_count = 1;
|
|
+ break;
|
|
+ default:
|
|
+ vkd3d_unreachable();
|
|
+ }
|
|
+
|
|
+ sm6_parser_dcl_register_builtin(sm6, reg_type, VKD3D_DATA_UINT, component_count);
|
|
+ vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV);
|
|
+ if (!(src_param = instruction_src_params_alloc(ins, 1, sm6)))
|
|
+ return;
|
|
+ vsir_register_init(&src_param->reg, reg_type, VKD3D_DATA_UINT, 0);
|
|
+ if (component_count > 1)
|
|
+ {
|
|
+ src_param->reg.dimension = VSIR_DIMENSION_VEC4;
|
|
+ component_idx = sm6_value_get_constant_uint(operands[0]);
|
|
+ }
|
|
+ src_param_init_scalar(src_param, component_idx);
|
|
+
|
|
+ instruction_dst_param_init_ssa_scalar(ins, sm6);
|
|
+}
|
|
+
|
|
static enum vkd3d_shader_opcode sm6_dx_map_ma_op(enum dx_intrinsic_opcode op, const struct sm6_type *type)
|
|
{
|
|
switch (op)
|
|
@@ -5086,17 +5328,20 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] =
|
|
[DX_DERIV_COARSEY ] = {"e", "R", sm6_parser_emit_dx_unary},
|
|
[DX_DERIV_FINEX ] = {"e", "R", sm6_parser_emit_dx_unary},
|
|
[DX_DERIV_FINEY ] = {"e", "R", sm6_parser_emit_dx_unary},
|
|
+ [DX_DISCARD ] = {"v", "1", sm6_parser_emit_dx_discard},
|
|
[DX_EXP ] = {"g", "R", sm6_parser_emit_dx_unary},
|
|
[DX_FABS ] = {"g", "R", sm6_parser_emit_dx_fabs},
|
|
[DX_FIRST_BIT_HI ] = {"i", "m", sm6_parser_emit_dx_unary},
|
|
[DX_FIRST_BIT_LO ] = {"i", "m", sm6_parser_emit_dx_unary},
|
|
[DX_FIRST_BIT_SHI ] = {"i", "m", sm6_parser_emit_dx_unary},
|
|
+ [DX_FLATTENED_THREAD_ID_IN_GROUP ] = {"i", "", sm6_parser_emit_dx_compute_builtin},
|
|
[DX_FMA ] = {"g", "RRR", sm6_parser_emit_dx_ma},
|
|
[DX_FMAD ] = {"g", "RRR", sm6_parser_emit_dx_ma},
|
|
[DX_FMAX ] = {"g", "RR", sm6_parser_emit_dx_binary},
|
|
[DX_FMIN ] = {"g", "RR", sm6_parser_emit_dx_binary},
|
|
[DX_FRC ] = {"g", "R", sm6_parser_emit_dx_unary},
|
|
[DX_GET_DIMENSIONS ] = {"D", "Hi", sm6_parser_emit_dx_get_dimensions},
|
|
+ [DX_GROUP_ID ] = {"i", "c", sm6_parser_emit_dx_compute_builtin},
|
|
[DX_IBFE ] = {"m", "iiR", sm6_parser_emit_dx_tertiary},
|
|
[DX_HCOS ] = {"g", "R", sm6_parser_emit_dx_unary},
|
|
[DX_HSIN ] = {"g", "R", sm6_parser_emit_dx_unary},
|
|
@@ -5134,6 +5379,8 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] =
|
|
[DX_TEXTURE_GATHER_CMP ] = {"o", "HHffffiicf", sm6_parser_emit_dx_texture_gather},
|
|
[DX_TEXTURE_LOAD ] = {"o", "HiiiiCCC", sm6_parser_emit_dx_texture_load},
|
|
[DX_TEXTURE_STORE ] = {"v", "Hiiiooooc", sm6_parser_emit_dx_texture_store},
|
|
+ [DX_THREAD_ID ] = {"i", "c", sm6_parser_emit_dx_compute_builtin},
|
|
+ [DX_THREAD_ID_IN_GROUP ] = {"i", "c", sm6_parser_emit_dx_compute_builtin},
|
|
[DX_UBFE ] = {"m", "iiR", sm6_parser_emit_dx_tertiary},
|
|
[DX_UMAD ] = {"m", "RRR", sm6_parser_emit_dx_ma},
|
|
[DX_UMAX ] = {"m", "RR", sm6_parser_emit_dx_binary},
|
|
@@ -6607,6 +6854,13 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const
|
|
case FUNC_CODE_INST_ALLOCA:
|
|
sm6_parser_emit_alloca(sm6, record, ins, dst);
|
|
break;
|
|
+ case FUNC_CODE_INST_ATOMICRMW:
|
|
+ {
|
|
+ struct function_emission_state state = {code_block, ins};
|
|
+ sm6_parser_emit_atomicrmw(sm6, record, &state, dst);
|
|
+ sm6->p.program.temp_count = max(sm6->p.program.temp_count, state.temp_idx);
|
|
+ break;
|
|
+ }
|
|
case FUNC_CODE_INST_BINOP:
|
|
sm6_parser_emit_binop(sm6, record, ins, dst);
|
|
break;
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/fx.c b/libs/vkd3d/libs/vkd3d-shader/fx.c
|
|
index f2be00da33a..9424a5685a7 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/fx.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/fx.c
|
|
@@ -611,11 +611,15 @@ static uint32_t write_fx_2_string(const char *string, struct fx_write_context *f
|
|
{
|
|
struct vkd3d_bytecode_buffer *buffer = &fx->unstructured;
|
|
const char *s = string ? string : "";
|
|
+ static const char tail[3];
|
|
uint32_t size, offset;
|
|
|
|
size = strlen(s) + 1;
|
|
offset = put_u32(buffer, size);
|
|
bytecode_put_bytes(buffer, s, size);
|
|
+ size %= 4;
|
|
+ if (size)
|
|
+ bytecode_put_bytes_unaligned(buffer, tail, 4 - size);
|
|
return offset;
|
|
}
|
|
|
|
@@ -639,10 +643,13 @@ static uint32_t write_fx_2_parameter(const struct hlsl_type *type, const char *n
|
|
|
|
switch (type->base_type)
|
|
{
|
|
+ case HLSL_TYPE_HALF:
|
|
case HLSL_TYPE_FLOAT:
|
|
case HLSL_TYPE_BOOL:
|
|
case HLSL_TYPE_INT:
|
|
+ case HLSL_TYPE_UINT:
|
|
case HLSL_TYPE_VOID:
|
|
+ case HLSL_TYPE_TEXTURE:
|
|
break;
|
|
default:
|
|
hlsl_fixme(ctx, &ctx->location, "Writing parameter type %u is not implemented.",
|
|
@@ -766,21 +773,72 @@ static uint32_t write_fx_2_initial_value(const struct hlsl_ir_var *var, struct f
|
|
return offset;
|
|
}
|
|
|
|
+static bool is_type_supported_fx_2(const struct hlsl_type *type)
|
|
+{
|
|
+ type = hlsl_get_multiarray_element_type(type);
|
|
+
|
|
+ if (type->class == HLSL_CLASS_STRUCT)
|
|
+ return true;
|
|
+
|
|
+ switch (type->base_type)
|
|
+ {
|
|
+ case HLSL_TYPE_FLOAT:
|
|
+ case HLSL_TYPE_HALF:
|
|
+ case HLSL_TYPE_DOUBLE:
|
|
+ case HLSL_TYPE_INT:
|
|
+ case HLSL_TYPE_UINT:
|
|
+ case HLSL_TYPE_BOOL:
|
|
+ case HLSL_TYPE_PIXELSHADER:
|
|
+ case HLSL_TYPE_VERTEXSHADER:
|
|
+ case HLSL_TYPE_STRING:
|
|
+ return true;
|
|
+ case HLSL_TYPE_TEXTURE:
|
|
+ case HLSL_TYPE_SAMPLER:
|
|
+ switch (type->sampler_dim)
|
|
+ {
|
|
+ case HLSL_SAMPLER_DIM_1D:
|
|
+ case HLSL_SAMPLER_DIM_2D:
|
|
+ case HLSL_SAMPLER_DIM_3D:
|
|
+ case HLSL_SAMPLER_DIM_CUBE:
|
|
+ case HLSL_SAMPLER_DIM_GENERIC:
|
|
+ return true;
|
|
+ default:
|
|
+ ;
|
|
+ }
|
|
+ break;
|
|
+ default:
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ return false;
|
|
+}
|
|
+
|
|
static void write_fx_2_parameters(struct fx_write_context *fx)
|
|
{
|
|
struct vkd3d_bytecode_buffer *buffer = &fx->structured;
|
|
- uint32_t desc_offset, value_offset;
|
|
+ uint32_t desc_offset, value_offset, flags;
|
|
struct hlsl_ctx *ctx = fx->ctx;
|
|
struct hlsl_ir_var *var;
|
|
+ enum fx_2_parameter_flags
|
|
+ {
|
|
+ IS_SHARED = 0x1,
|
|
+ };
|
|
|
|
LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
|
|
{
|
|
+ if (!is_type_supported_fx_2(var->data_type))
|
|
+ continue;
|
|
+
|
|
desc_offset = write_fx_2_parameter(var->data_type, var->name, &var->semantic, fx);
|
|
value_offset = write_fx_2_initial_value(var, fx);
|
|
|
|
+ flags = 0;
|
|
+ if (var->storage_modifiers & HLSL_STORAGE_SHARED)
|
|
+ flags |= IS_SHARED;
|
|
+
|
|
put_u32(buffer, desc_offset); /* Parameter description */
|
|
put_u32(buffer, value_offset); /* Value */
|
|
- put_u32(buffer, 0); /* Flags */
|
|
+ put_u32(buffer, flags); /* Flags */
|
|
|
|
put_u32(buffer, 0); /* Annotations count */
|
|
if (has_annotations(var))
|
|
@@ -799,12 +857,13 @@ static const struct fx_write_context_ops fx_2_ops =
|
|
|
|
static int hlsl_fx_2_write(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out)
|
|
{
|
|
- uint32_t offset, size, technique_count, parameter_count;
|
|
+ uint32_t offset, size, technique_count, parameter_count, object_count;
|
|
struct vkd3d_bytecode_buffer buffer = { 0 };
|
|
struct vkd3d_bytecode_buffer *structured;
|
|
struct fx_write_context fx;
|
|
|
|
fx_write_context_init(ctx, &fx_2_ops, &fx);
|
|
+ fx.object_variable_count = 1;
|
|
structured = &fx.structured;
|
|
|
|
/* First entry is always zeroed and skipped. */
|
|
@@ -816,10 +875,11 @@ static int hlsl_fx_2_write(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out)
|
|
parameter_count = put_u32(structured, 0); /* Parameter count */
|
|
technique_count = put_u32(structured, 0);
|
|
put_u32(structured, 0); /* Unknown */
|
|
- put_u32(structured, 0); /* Object count */
|
|
+ object_count = put_u32(structured, 0);
|
|
|
|
write_fx_2_parameters(&fx);
|
|
set_u32(structured, parameter_count, fx.parameter_count);
|
|
+ set_u32(structured, object_count, fx.object_variable_count);
|
|
|
|
write_techniques(ctx->globals, &fx);
|
|
set_u32(structured, technique_count, fx.technique_count);
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c
|
|
index a82334e58fd..cba954c988f 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c
|
|
@@ -785,6 +785,7 @@ static const char * get_case_insensitive_typename(const char *name)
|
|
"float",
|
|
"matrix",
|
|
"pixelshader",
|
|
+ "texture",
|
|
"vector",
|
|
"vertexshader",
|
|
};
|
|
@@ -3408,7 +3409,7 @@ static void declare_predefined_types(struct hlsl_ctx *ctx)
|
|
{"fxgroup", HLSL_CLASS_OBJECT, HLSL_TYPE_EFFECT_GROUP, 1, 1},
|
|
{"pass", HLSL_CLASS_OBJECT, HLSL_TYPE_PASS, 1, 1},
|
|
{"STRING", HLSL_CLASS_OBJECT, HLSL_TYPE_STRING, 1, 1},
|
|
- {"TEXTURE", HLSL_CLASS_OBJECT, HLSL_TYPE_TEXTURE, 1, 1},
|
|
+ {"texture", HLSL_CLASS_OBJECT, HLSL_TYPE_TEXTURE, 1, 1},
|
|
{"pixelshader", HLSL_CLASS_OBJECT, HLSL_TYPE_PIXELSHADER, 1, 1},
|
|
{"vertexshader", HLSL_CLASS_OBJECT, HLSL_TYPE_VERTEXSHADER, 1, 1},
|
|
{"RenderTargetView",HLSL_CLASS_OBJECT, HLSL_TYPE_RENDERTARGETVIEW, 1, 1},
|
|
@@ -3592,24 +3593,35 @@ static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const struct vkd3d_shader_compil
|
|
return false;
|
|
ctx->cur_buffer = ctx->globals_buffer;
|
|
|
|
+ ctx->warn_implicit_truncation = true;
|
|
+
|
|
for (i = 0; i < compile_info->option_count; ++i)
|
|
{
|
|
const struct vkd3d_shader_compile_option *option = &compile_info->options[i];
|
|
|
|
- if (option->name == VKD3D_SHADER_COMPILE_OPTION_PACK_MATRIX_ORDER)
|
|
- {
|
|
- if (option->value == VKD3D_SHADER_COMPILE_OPTION_PACK_MATRIX_ROW_MAJOR)
|
|
- ctx->matrix_majority = HLSL_MODIFIER_ROW_MAJOR;
|
|
- else if (option->value == VKD3D_SHADER_COMPILE_OPTION_PACK_MATRIX_COLUMN_MAJOR)
|
|
- ctx->matrix_majority = HLSL_MODIFIER_COLUMN_MAJOR;
|
|
- }
|
|
- else if (option->name == VKD3D_SHADER_COMPILE_OPTION_BACKWARD_COMPATIBILITY)
|
|
- {
|
|
- ctx->semantic_compat_mapping = option->value & VKD3D_SHADER_COMPILE_OPTION_BACKCOMPAT_MAP_SEMANTIC_NAMES;
|
|
- }
|
|
- else if (option->name == VKD3D_SHADER_COMPILE_OPTION_CHILD_EFFECT)
|
|
+ switch (option->name)
|
|
{
|
|
- ctx->child_effect = !!option->value;
|
|
+ case VKD3D_SHADER_COMPILE_OPTION_PACK_MATRIX_ORDER:
|
|
+ if (option->value == VKD3D_SHADER_COMPILE_OPTION_PACK_MATRIX_ROW_MAJOR)
|
|
+ ctx->matrix_majority = HLSL_MODIFIER_ROW_MAJOR;
|
|
+ else if (option->value == VKD3D_SHADER_COMPILE_OPTION_PACK_MATRIX_COLUMN_MAJOR)
|
|
+ ctx->matrix_majority = HLSL_MODIFIER_COLUMN_MAJOR;
|
|
+ break;
|
|
+
|
|
+ case VKD3D_SHADER_COMPILE_OPTION_BACKWARD_COMPATIBILITY:
|
|
+ ctx->semantic_compat_mapping = option->value & VKD3D_SHADER_COMPILE_OPTION_BACKCOMPAT_MAP_SEMANTIC_NAMES;
|
|
+ break;
|
|
+
|
|
+ case VKD3D_SHADER_COMPILE_OPTION_CHILD_EFFECT:
|
|
+ ctx->child_effect = option->value;
|
|
+ break;
|
|
+
|
|
+ case VKD3D_SHADER_COMPILE_OPTION_WARN_IMPLICIT_TRUNCATION:
|
|
+ ctx->warn_implicit_truncation = option->value;
|
|
+ break;
|
|
+
|
|
+ default:
|
|
+ break;
|
|
}
|
|
}
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h
|
|
index 561782efbf8..c6321f2ead2 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h
|
|
@@ -925,6 +925,7 @@ struct hlsl_ctx
|
|
|
|
bool semantic_compat_mapping;
|
|
bool child_effect;
|
|
+ bool warn_implicit_truncation;
|
|
};
|
|
|
|
struct hlsl_resource_load_params
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y
|
|
index ec8b3d22af2..52c2176542c 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y
|
|
@@ -413,7 +413,7 @@ static struct hlsl_ir_node *add_implicit_conversion(struct hlsl_ctx *ctx, struct
|
|
return NULL;
|
|
}
|
|
|
|
- if (dst_type->dimx * dst_type->dimy < src_type->dimx * src_type->dimy)
|
|
+ if (dst_type->dimx * dst_type->dimy < src_type->dimx * src_type->dimy && ctx->warn_implicit_truncation)
|
|
hlsl_warning(ctx, loc, VKD3D_SHADER_WARNING_HLSL_IMPLICIT_TRUNCATION, "Implicit truncation of %s type.",
|
|
src_type->class == HLSL_CLASS_VECTOR ? "vector" : "matrix");
|
|
|
|
@@ -438,8 +438,9 @@ static uint32_t add_modifiers(struct hlsl_ctx *ctx, uint32_t modifiers, uint32_t
|
|
|
|
static bool append_conditional_break(struct hlsl_ctx *ctx, struct hlsl_block *cond_block)
|
|
{
|
|
- struct hlsl_ir_node *condition, *not, *iff, *jump;
|
|
+ struct hlsl_ir_node *condition, *cast, *not, *iff, *jump;
|
|
struct hlsl_block then_block;
|
|
+ struct hlsl_type *bool_type;
|
|
|
|
/* E.g. "for (i = 0; ; ++i)". */
|
|
if (list_empty(&cond_block->instrs))
|
|
@@ -449,7 +450,12 @@ static bool append_conditional_break(struct hlsl_ctx *ctx, struct hlsl_block *co
|
|
|
|
check_condition_type(ctx, condition);
|
|
|
|
- if (!(not = hlsl_new_unary_expr(ctx, HLSL_OP1_LOGIC_NOT, condition, &condition->loc)))
|
|
+ bool_type = hlsl_get_scalar_type(ctx, HLSL_TYPE_BOOL);
|
|
+ if (!(cast = hlsl_new_cast(ctx, condition, bool_type, &condition->loc)))
|
|
+ return false;
|
|
+ hlsl_block_add_instr(cond_block, cast);
|
|
+
|
|
+ if (!(not = hlsl_new_unary_expr(ctx, HLSL_OP1_LOGIC_NOT, cast, &condition->loc)))
|
|
return false;
|
|
hlsl_block_add_instr(cond_block, not);
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
|
|
index ff349ab49ef..5c09ce04f5b 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
|
|
@@ -2902,6 +2902,55 @@ static bool lower_floor(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct
|
|
return true;
|
|
}
|
|
|
|
+static bool lower_logic_not(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
|
|
+{
|
|
+ struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS];
|
|
+ struct hlsl_ir_node *arg, *arg_cast, *neg, *one, *sub, *res;
|
|
+ struct hlsl_constant_value one_value;
|
|
+ struct hlsl_type *float_type;
|
|
+ struct hlsl_ir_expr *expr;
|
|
+
|
|
+ if (instr->type != HLSL_IR_EXPR)
|
|
+ return false;
|
|
+ expr = hlsl_ir_expr(instr);
|
|
+ if (expr->op != HLSL_OP1_LOGIC_NOT)
|
|
+ return false;
|
|
+
|
|
+ arg = expr->operands[0].node;
|
|
+ float_type = hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, arg->data_type->dimx);
|
|
+
|
|
+ /* If this is happens, it means we failed to cast the argument to boolean somewhere. */
|
|
+ assert(arg->data_type->base_type == HLSL_TYPE_BOOL);
|
|
+
|
|
+ if (!(arg_cast = hlsl_new_cast(ctx, arg, float_type, &arg->loc)))
|
|
+ return false;
|
|
+ hlsl_block_add_instr(block, arg_cast);
|
|
+
|
|
+ if (!(neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, arg_cast, &instr->loc)))
|
|
+ return false;
|
|
+ hlsl_block_add_instr(block, neg);
|
|
+
|
|
+ one_value.u[0].f = 1.0;
|
|
+ one_value.u[1].f = 1.0;
|
|
+ one_value.u[2].f = 1.0;
|
|
+ one_value.u[3].f = 1.0;
|
|
+ if (!(one = hlsl_new_constant(ctx, float_type, &one_value, &instr->loc)))
|
|
+ return false;
|
|
+ hlsl_block_add_instr(block, one);
|
|
+
|
|
+ if (!(sub = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, one, neg)))
|
|
+ return false;
|
|
+ hlsl_block_add_instr(block, sub);
|
|
+
|
|
+ memset(operands, 0, sizeof(operands));
|
|
+ operands[0] = sub;
|
|
+ if (!(res = hlsl_new_expr(ctx, HLSL_OP1_REINTERPRET, operands, instr->data_type, &instr->loc)))
|
|
+ return false;
|
|
+ hlsl_block_add_instr(block, res);
|
|
+
|
|
+ return true;
|
|
+}
|
|
+
|
|
/* Use movc/cmp for the ternary operator. */
|
|
static bool lower_ternary(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
|
|
{
|
|
@@ -3573,6 +3622,8 @@ static bool lower_nonfloat_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst
|
|
case HLSL_OP1_NEG:
|
|
case HLSL_OP2_ADD:
|
|
case HLSL_OP2_DIV:
|
|
+ case HLSL_OP2_LOGIC_AND:
|
|
+ case HLSL_OP2_LOGIC_OR:
|
|
case HLSL_OP2_MAX:
|
|
case HLSL_OP2_MIN:
|
|
case HLSL_OP2_MUL:
|
|
@@ -3761,9 +3812,6 @@ static void allocate_register_reservations(struct hlsl_ctx *ctx)
|
|
{
|
|
unsigned int r;
|
|
|
|
- if (!hlsl_type_is_resource(var->data_type))
|
|
- continue;
|
|
-
|
|
if (var->reg_reservation.reg_type)
|
|
{
|
|
for (r = 0; r <= HLSL_REGSET_LAST_OBJECT; ++r)
|
|
@@ -5420,6 +5468,7 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry
|
|
lower_ir(ctx, lower_ceil, body);
|
|
lower_ir(ctx, lower_floor, body);
|
|
lower_ir(ctx, lower_comparison_operators, body);
|
|
+ lower_ir(ctx, lower_logic_not, body);
|
|
if (ctx->profile->type == VKD3D_SHADER_TYPE_PIXEL)
|
|
lower_ir(ctx, lower_slt, body);
|
|
else
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c
|
|
index 673400efd69..1cae2d7d9d4 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/spirv.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c
|
|
@@ -3396,7 +3396,7 @@ struct vkd3d_shader_register_info
|
|
bool is_aggregate;
|
|
};
|
|
|
|
-static bool spirv_compiler_get_register_info(const struct spirv_compiler *compiler,
|
|
+static bool spirv_compiler_get_register_info(struct spirv_compiler *compiler,
|
|
const struct vkd3d_shader_register *reg, struct vkd3d_shader_register_info *register_info)
|
|
{
|
|
struct vkd3d_symbol reg_symbol, *symbol;
|
|
@@ -3422,7 +3422,8 @@ static bool spirv_compiler_get_register_info(const struct spirv_compiler *compil
|
|
vkd3d_symbol_make_register(®_symbol, reg);
|
|
if (!(entry = rb_get(&compiler->symbol_table, ®_symbol)))
|
|
{
|
|
- FIXME("Unrecognized register (%s).\n", debug_vkd3d_symbol(®_symbol));
|
|
+ spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_INVALID_REGISTER_TYPE,
|
|
+ "Unrecognized register (%s).\n", debug_vkd3d_symbol(®_symbol));
|
|
memset(register_info, 0, sizeof(*register_info));
|
|
return false;
|
|
}
|
|
@@ -4094,7 +4095,7 @@ static uint32_t spirv_compiler_emit_load_reg(struct spirv_compiler *compiler,
|
|
struct vkd3d_shader_register_info reg_info;
|
|
unsigned int component_count;
|
|
uint32_t type_id, val_id;
|
|
- uint32_t write_mask32;
|
|
+ uint32_t val_write_mask;
|
|
|
|
if (reg->type == VKD3DSPR_IMMCONST)
|
|
return spirv_compiler_emit_load_constant(compiler, reg, swizzle, write_mask);
|
|
@@ -4114,17 +4115,17 @@ static uint32_t spirv_compiler_emit_load_reg(struct spirv_compiler *compiler,
|
|
type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count);
|
|
return vkd3d_spirv_get_op_undef(builder, type_id);
|
|
}
|
|
- assert(reg_info.component_type != VKD3D_SHADER_COMPONENT_DOUBLE);
|
|
spirv_compiler_emit_dereference_register(compiler, reg, ®_info);
|
|
|
|
- write_mask32 = data_type_is_64_bit(reg->data_type) ? vsir_write_mask_32_from_64(write_mask) : write_mask;
|
|
+ val_write_mask = (data_type_is_64_bit(reg->data_type) && !component_type_is_64_bit(reg_info.component_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 (vsir_write_mask_component_count(write_mask32) == 1)
|
|
+ else if (vsir_write_mask_component_count(val_write_mask) == 1)
|
|
{
|
|
return spirv_compiler_emit_load_scalar(compiler, reg, swizzle, write_mask, ®_info);
|
|
}
|
|
@@ -4137,7 +4138,7 @@ static uint32_t spirv_compiler_emit_load_reg(struct spirv_compiler *compiler,
|
|
|
|
swizzle = data_type_is_64_bit(reg->data_type) ? vsir_swizzle_32_from_64(swizzle) : swizzle;
|
|
val_id = spirv_compiler_emit_swizzle(compiler,
|
|
- val_id, reg_info.write_mask, reg_info.component_type, swizzle, write_mask32);
|
|
+ val_id, reg_info.write_mask, reg_info.component_type, swizzle, val_write_mask);
|
|
|
|
if (component_type != reg_info.component_type)
|
|
{
|
|
@@ -7123,6 +7124,7 @@ static enum GLSLstd450 spirv_compiler_map_ext_glsl_instruction(
|
|
}
|
|
glsl_insts[] =
|
|
{
|
|
+ {VKD3DSIH_ABS, GLSLstd450FAbs},
|
|
{VKD3DSIH_ACOS, GLSLstd450Acos},
|
|
{VKD3DSIH_ASIN, GLSLstd450Asin},
|
|
{VKD3DSIH_ATAN, GLSLstd450Atan},
|
|
@@ -8005,8 +8007,9 @@ static void spirv_compiler_emit_discard(struct spirv_compiler *compiler,
|
|
* a mismatch between the VSIR structure and the SPIR-V one, which would cause problems if
|
|
* structurisation is necessary. Therefore we emit it as a function call. */
|
|
condition_id = spirv_compiler_emit_load_src(compiler, src, VKD3DSP_WRITEMASK_0);
|
|
- condition_id = spirv_compiler_emit_int_to_bool(compiler,
|
|
- instruction->flags, src->reg.data_type, 1, condition_id);
|
|
+ if (src->reg.data_type != VKD3D_DATA_BOOL)
|
|
+ condition_id = spirv_compiler_emit_int_to_bool(compiler,
|
|
+ instruction->flags, src->reg.data_type, 1, condition_id);
|
|
void_id = vkd3d_spirv_get_op_type_void(builder);
|
|
vkd3d_spirv_build_op_function_call(builder, void_id, spirv_compiler_get_discard_function_id(compiler),
|
|
&condition_id, 1);
|
|
@@ -8785,7 +8788,6 @@ static void spirv_compiler_emit_ld_tgsm(struct spirv_compiler *compiler,
|
|
ptr_id = vkd3d_spirv_build_op_access_chain1(builder, ptr_type_id, reg_info.id, coordinate_id);
|
|
constituents[j++] = vkd3d_spirv_build_op_load(builder, type_id, ptr_id, SpvMemoryAccessMaskNone);
|
|
}
|
|
- assert(dst->reg.data_type == VKD3D_DATA_UINT);
|
|
spirv_compiler_emit_store_dst_components(compiler, dst, VKD3D_SHADER_COMPONENT_UINT, constituents);
|
|
}
|
|
|
|
@@ -8907,7 +8909,6 @@ static void spirv_compiler_emit_store_tgsm(struct spirv_compiler *compiler,
|
|
type_id, reg_info.structure_stride, &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0);
|
|
|
|
data = &src[instruction->src_count - 1];
|
|
- assert(data->reg.data_type == VKD3D_DATA_UINT);
|
|
val_id = spirv_compiler_emit_load_src(compiler, data, dst->write_mask);
|
|
|
|
component_count = vsir_write_mask_component_count(dst->write_mask);
|
|
@@ -9159,6 +9160,7 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil
|
|
const struct vkd3d_shader_dst_param *resource;
|
|
uint32_t coordinate_id, sample_id, pointer_id;
|
|
struct vkd3d_shader_register_info reg_info;
|
|
+ SpvMemorySemanticsMask memory_semantic;
|
|
struct vkd3d_shader_image image;
|
|
unsigned int structure_stride;
|
|
uint32_t coordinate_mask;
|
|
@@ -9250,12 +9252,19 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil
|
|
|
|
val_id = spirv_compiler_emit_load_src_with_type(compiler, &src[1], VKD3DSP_WRITEMASK_0, component_type);
|
|
|
|
+ if (instruction->flags & VKD3DARF_VOLATILE)
|
|
+ WARN("Ignoring 'volatile' attribute.\n");
|
|
+
|
|
+ memory_semantic = (instruction->flags & VKD3DARF_SEQ_CST)
|
|
+ ? SpvMemorySemanticsSequentiallyConsistentMask
|
|
+ : SpvMemorySemanticsMaskNone;
|
|
+
|
|
operands[i++] = pointer_id;
|
|
operands[i++] = spirv_compiler_get_constant_uint(compiler, scope);
|
|
- operands[i++] = spirv_compiler_get_constant_uint(compiler, SpvMemorySemanticsMaskNone);
|
|
+ operands[i++] = spirv_compiler_get_constant_uint(compiler, memory_semantic);
|
|
if (instruction->src_count >= 3)
|
|
{
|
|
- operands[i++] = spirv_compiler_get_constant_uint(compiler, SpvMemorySemanticsMaskNone);
|
|
+ operands[i++] = spirv_compiler_get_constant_uint(compiler, memory_semantic);
|
|
operands[i++] = spirv_compiler_emit_load_src_with_type(compiler, &src[2], VKD3DSP_WRITEMASK_0, component_type);
|
|
}
|
|
operands[i++] = val_id;
|
|
@@ -9808,6 +9817,7 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler,
|
|
case VKD3DSIH_ISFINITE:
|
|
spirv_compiler_emit_isfinite(compiler, instruction);
|
|
break;
|
|
+ case VKD3DSIH_ABS:
|
|
case VKD3DSIH_ACOS:
|
|
case VKD3DSIH_ASIN:
|
|
case VKD3DSIH_ATAN:
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c
|
|
index cb4f6d4ddbf..4d0658313d5 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/tpf.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c
|
|
@@ -2994,26 +2994,23 @@ static D3D_SHADER_VARIABLE_CLASS sm4_class(const struct hlsl_type *type)
|
|
{
|
|
switch (type->class)
|
|
{
|
|
- case HLSL_CLASS_ARRAY:
|
|
- return sm4_class(type->e.array.type);
|
|
case HLSL_CLASS_MATRIX:
|
|
assert(type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK);
|
|
if (type->modifiers & HLSL_MODIFIER_COLUMN_MAJOR)
|
|
return D3D_SVC_MATRIX_COLUMNS;
|
|
else
|
|
return D3D_SVC_MATRIX_ROWS;
|
|
- case HLSL_CLASS_OBJECT:
|
|
- return D3D_SVC_OBJECT;
|
|
case HLSL_CLASS_SCALAR:
|
|
return D3D_SVC_SCALAR;
|
|
- case HLSL_CLASS_STRUCT:
|
|
- return D3D_SVC_STRUCT;
|
|
case HLSL_CLASS_VECTOR:
|
|
return D3D_SVC_VECTOR;
|
|
- default:
|
|
- ERR("Invalid class %#x.\n", type->class);
|
|
- vkd3d_unreachable();
|
|
+
|
|
+ case HLSL_CLASS_ARRAY:
|
|
+ case HLSL_CLASS_STRUCT:
|
|
+ case HLSL_CLASS_OBJECT:
|
|
+ break;
|
|
}
|
|
+ vkd3d_unreachable();
|
|
}
|
|
|
|
static D3D_SHADER_VARIABLE_TYPE sm4_base_type(const struct hlsl_type *type)
|
|
@@ -3029,68 +3026,8 @@ static D3D_SHADER_VARIABLE_TYPE sm4_base_type(const struct hlsl_type *type)
|
|
return D3D_SVT_FLOAT;
|
|
case HLSL_TYPE_INT:
|
|
return D3D_SVT_INT;
|
|
- case HLSL_TYPE_PIXELSHADER:
|
|
- return D3D_SVT_PIXELSHADER;
|
|
- case HLSL_TYPE_SAMPLER:
|
|
- switch (type->sampler_dim)
|
|
- {
|
|
- case HLSL_SAMPLER_DIM_1D:
|
|
- return D3D_SVT_SAMPLER1D;
|
|
- case HLSL_SAMPLER_DIM_2D:
|
|
- return D3D_SVT_SAMPLER2D;
|
|
- case HLSL_SAMPLER_DIM_3D:
|
|
- return D3D_SVT_SAMPLER3D;
|
|
- case HLSL_SAMPLER_DIM_CUBE:
|
|
- return D3D_SVT_SAMPLERCUBE;
|
|
- case HLSL_SAMPLER_DIM_GENERIC:
|
|
- return D3D_SVT_SAMPLER;
|
|
- default:
|
|
- vkd3d_unreachable();
|
|
- }
|
|
- break;
|
|
- case HLSL_TYPE_STRING:
|
|
- return D3D_SVT_STRING;
|
|
- case HLSL_TYPE_TEXTURE:
|
|
- switch (type->sampler_dim)
|
|
- {
|
|
- case HLSL_SAMPLER_DIM_1D:
|
|
- return D3D_SVT_TEXTURE1D;
|
|
- case HLSL_SAMPLER_DIM_2D:
|
|
- return D3D_SVT_TEXTURE2D;
|
|
- case HLSL_SAMPLER_DIM_2DMS:
|
|
- return D3D_SVT_TEXTURE2DMS;
|
|
- case HLSL_SAMPLER_DIM_3D:
|
|
- return D3D_SVT_TEXTURE3D;
|
|
- case HLSL_SAMPLER_DIM_CUBE:
|
|
- return D3D_SVT_TEXTURECUBE;
|
|
- case HLSL_SAMPLER_DIM_GENERIC:
|
|
- return D3D_SVT_TEXTURE;
|
|
- default:
|
|
- vkd3d_unreachable();
|
|
- }
|
|
- break;
|
|
case HLSL_TYPE_UINT:
|
|
return D3D_SVT_UINT;
|
|
- case HLSL_TYPE_VERTEXSHADER:
|
|
- return D3D_SVT_VERTEXSHADER;
|
|
- case HLSL_TYPE_VOID:
|
|
- return D3D_SVT_VOID;
|
|
- case HLSL_TYPE_UAV:
|
|
- switch (type->sampler_dim)
|
|
- {
|
|
- case HLSL_SAMPLER_DIM_1D:
|
|
- return D3D_SVT_RWTEXTURE1D;
|
|
- case HLSL_SAMPLER_DIM_2D:
|
|
- return D3D_SVT_RWTEXTURE2D;
|
|
- case HLSL_SAMPLER_DIM_3D:
|
|
- return D3D_SVT_RWTEXTURE3D;
|
|
- case HLSL_SAMPLER_DIM_1DARRAY:
|
|
- return D3D_SVT_RWTEXTURE1DARRAY;
|
|
- case HLSL_SAMPLER_DIM_2DARRAY:
|
|
- return D3D_SVT_RWTEXTURE2DARRAY;
|
|
- default:
|
|
- vkd3d_unreachable();
|
|
- }
|
|
default:
|
|
vkd3d_unreachable();
|
|
}
|
|
@@ -3101,8 +3038,8 @@ static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b
|
|
const struct hlsl_type *array_type = hlsl_get_multiarray_element_type(type);
|
|
const char *name = array_type->name ? array_type->name : "<unnamed>";
|
|
const struct hlsl_profile_info *profile = ctx->profile;
|
|
- unsigned int field_count = 0, array_size = 0;
|
|
- size_t fields_offset = 0, name_offset = 0;
|
|
+ unsigned int array_size = 0;
|
|
+ size_t name_offset = 0;
|
|
size_t i;
|
|
|
|
if (type->bytecode_offset)
|
|
@@ -3116,32 +3053,47 @@ static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b
|
|
|
|
if (array_type->class == HLSL_CLASS_STRUCT)
|
|
{
|
|
- field_count = array_type->e.record.field_count;
|
|
+ unsigned int field_count = 0;
|
|
+ size_t fields_offset = 0;
|
|
|
|
- for (i = 0; i < field_count; ++i)
|
|
+ for (i = 0; i < array_type->e.record.field_count; ++i)
|
|
{
|
|
struct hlsl_struct_field *field = &array_type->e.record.fields[i];
|
|
|
|
+ if (!field->type->reg_size[HLSL_REGSET_NUMERIC])
|
|
+ continue;
|
|
+
|
|
field->name_bytecode_offset = put_string(buffer, field->name);
|
|
write_sm4_type(ctx, buffer, field->type);
|
|
+ ++field_count;
|
|
}
|
|
|
|
fields_offset = bytecode_align(buffer);
|
|
|
|
- for (i = 0; i < field_count; ++i)
|
|
+ for (i = 0; i < array_type->e.record.field_count; ++i)
|
|
{
|
|
struct hlsl_struct_field *field = &array_type->e.record.fields[i];
|
|
|
|
+ if (!field->type->reg_size[HLSL_REGSET_NUMERIC])
|
|
+ continue;
|
|
+
|
|
put_u32(buffer, field->name_bytecode_offset);
|
|
put_u32(buffer, field->type->bytecode_offset);
|
|
put_u32(buffer, field->reg_offset[HLSL_REGSET_NUMERIC]);
|
|
}
|
|
+ type->bytecode_offset = put_u32(buffer, vkd3d_make_u32(D3D_SVC_STRUCT, D3D_SVT_VOID));
|
|
+ put_u32(buffer, vkd3d_make_u32(1, hlsl_type_component_count(array_type)));
|
|
+ put_u32(buffer, vkd3d_make_u32(array_size, field_count));
|
|
+ put_u32(buffer, fields_offset);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ assert(array_type->class <= HLSL_CLASS_LAST_NUMERIC);
|
|
+ type->bytecode_offset = put_u32(buffer, vkd3d_make_u32(sm4_class(array_type), sm4_base_type(array_type)));
|
|
+ put_u32(buffer, vkd3d_make_u32(array_type->dimy, array_type->dimx));
|
|
+ put_u32(buffer, vkd3d_make_u32(array_size, 0));
|
|
+ put_u32(buffer, 1);
|
|
}
|
|
-
|
|
- type->bytecode_offset = put_u32(buffer, vkd3d_make_u32(sm4_class(type), sm4_base_type(type)));
|
|
- put_u32(buffer, vkd3d_make_u32(type->dimy, type->dimx));
|
|
- put_u32(buffer, vkd3d_make_u32(array_size, field_count));
|
|
- put_u32(buffer, fields_offset);
|
|
|
|
if (profile->major_version >= 5)
|
|
{
|
|
@@ -3333,7 +3285,7 @@ static struct extern_resource *sm4_get_extern_resources(struct hlsl_ctx *ctx, un
|
|
|
|
extern_resources[*count].name = name;
|
|
extern_resources[*count].data_type = component_type;
|
|
- extern_resources[*count].is_user_packed = false;
|
|
+ extern_resources[*count].is_user_packed = !!var->reg_reservation.reg_type;
|
|
|
|
extern_resources[*count].regset = regset;
|
|
extern_resources[*count].id = var->regs[regset].id + regset_offset;
|
|
@@ -3528,8 +3480,7 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc)
|
|
|
|
LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
|
|
{
|
|
- if (var->is_uniform && var->buffer == cbuffer
|
|
- && var->data_type->class != HLSL_CLASS_OBJECT)
|
|
+ if (var->is_uniform && var->buffer == cbuffer && var->data_type->reg_size[HLSL_REGSET_NUMERIC])
|
|
++var_count;
|
|
}
|
|
|
|
@@ -3563,8 +3514,7 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc)
|
|
|
|
LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
|
|
{
|
|
- if (var->is_uniform && var->buffer == cbuffer
|
|
- && var->data_type->class != HLSL_CLASS_OBJECT)
|
|
+ if (var->is_uniform && var->buffer == cbuffer && var->data_type->reg_size[HLSL_REGSET_NUMERIC])
|
|
{
|
|
uint32_t flags = 0;
|
|
|
|
@@ -3591,8 +3541,7 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc)
|
|
j = 0;
|
|
LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
|
|
{
|
|
- if (var->is_uniform && var->buffer == cbuffer
|
|
- && var->data_type->class != HLSL_CLASS_OBJECT)
|
|
+ if (var->is_uniform && var->buffer == cbuffer && var->data_type->reg_size[HLSL_REGSET_NUMERIC])
|
|
{
|
|
const unsigned int var_size = (profile->major_version >= 5 ? 10 : 6);
|
|
size_t var_offset = vars_start + j * var_size * sizeof(uint32_t);
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
|
|
index a33b6d2d967..6d442cd517d 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
|
|
@@ -755,6 +755,12 @@ enum vkd3d_shader_uav_flags
|
|
VKD3DSUF_ORDER_PRESERVING_COUNTER = 0x100,
|
|
};
|
|
|
|
+enum vkd3d_shader_atomic_rmw_flags
|
|
+{
|
|
+ VKD3DARF_SEQ_CST = 0x1,
|
|
+ VKD3DARF_VOLATILE = 0x2,
|
|
+};
|
|
+
|
|
enum vkd3d_tessellator_domain
|
|
{
|
|
VKD3D_TESSELLATOR_DOMAIN_LINE = 1,
|
|
@@ -1611,6 +1617,11 @@ static inline enum vkd3d_shader_component_type vkd3d_component_type_from_resourc
|
|
}
|
|
}
|
|
|
|
+static inline bool component_type_is_64_bit(enum vkd3d_shader_component_type component_type)
|
|
+{
|
|
+ return component_type == VKD3D_SHADER_COMPONENT_DOUBLE || component_type == VKD3D_SHADER_COMPONENT_UINT64;
|
|
+}
|
|
+
|
|
enum vkd3d_shader_input_sysval_semantic vkd3d_siv_from_sysval_indexed(enum vkd3d_shader_sysval_semantic sysval,
|
|
unsigned int index);
|
|
|
|
--
|
|
2.43.0
|
|
|