wine-staging/patches/vkd3d-latest/0001-Updated-vkd3d-to-45679a966c73669bdb7fa371569dcc34a44.patch
2023-12-16 18:59:12 +11:00

1166 lines
49 KiB
Diff

From b68e960703095111f31a57b291a710a7be409745 Mon Sep 17 00:00:00 2001
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
Date: Fri, 8 Dec 2023 13:21:19 +1100
Subject: [PATCH] Updated vkd3d to 45679a966c73669bdb7fa371569dcc34a448d8d4.
---
libs/vkd3d/include/private/vkd3d_common.h | 4 +-
libs/vkd3d/libs/vkd3d-common/blob.c | 1 +
libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 4 +-
libs/vkd3d/libs/vkd3d-shader/dxil.c | 423 +++++++++++++++++-
libs/vkd3d/libs/vkd3d-shader/hlsl.y | 20 +-
libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 12 +-
libs/vkd3d/libs/vkd3d-shader/ir.c | 5 +-
libs/vkd3d/libs/vkd3d-shader/spirv.c | 127 ++++--
libs/vkd3d/libs/vkd3d-shader/tpf.c | 11 +
.../libs/vkd3d-shader/vkd3d_shader_main.c | 45 +-
.../libs/vkd3d-shader/vkd3d_shader_private.h | 3 +
11 files changed, 564 insertions(+), 91 deletions(-)
diff --git a/libs/vkd3d/include/private/vkd3d_common.h b/libs/vkd3d/include/private/vkd3d_common.h
index 34fde1a2aa0..e9bff2fbba3 100644
--- a/libs/vkd3d/include/private/vkd3d_common.h
+++ b/libs/vkd3d/include/private/vkd3d_common.h
@@ -80,7 +80,7 @@ static inline size_t align(size_t addr, size_t alignment)
# ifdef __MINGW_PRINTF_FORMAT
# define VKD3D_PRINTF_FUNC(fmt, args) __attribute__((format(__MINGW_PRINTF_FORMAT, fmt, args)))
# else
-# define VKD3D_PRINTF_FUNC(fmt, args) /* __attribute__((format(printf, fmt, args))) */
+# define VKD3D_PRINTF_FUNC(fmt, args) __attribute__((format(printf, fmt, args)))
# endif
# define VKD3D_UNUSED __attribute__((unused))
# define VKD3D_UNREACHABLE __builtin_unreachable()
@@ -107,7 +107,7 @@ static inline unsigned int vkd3d_popcount(unsigned int v)
{
#ifdef _MSC_VER
return __popcnt(v);
-#elif defined(__MINGW32__)
+#elif defined(HAVE_BUILTIN_POPCOUNT)
return __builtin_popcount(v);
#else
v -= (v >> 1) & 0x55555555;
diff --git a/libs/vkd3d/libs/vkd3d-common/blob.c b/libs/vkd3d/libs/vkd3d-common/blob.c
index 71ab9a2c51e..fa2812619ac 100644
--- a/libs/vkd3d/libs/vkd3d-common/blob.c
+++ b/libs/vkd3d/libs/vkd3d-common/blob.c
@@ -17,6 +17,7 @@
*/
#define COBJMACROS
+
#define CONST_VTABLE
#include "vkd3d.h"
#include "vkd3d_blob.h"
diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
index 3d139416b61..c78ffebac69 100644
--- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
+++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
@@ -2253,7 +2253,7 @@ static void write_sm1_jump(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b
{
struct hlsl_reg *reg = &jump->condition.node->reg;
- struct sm1_instruction instr =
+ struct sm1_instruction sm1_instr =
{
.opcode = D3DSIO_TEXKILL,
@@ -2263,7 +2263,7 @@ static void write_sm1_jump(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b
.has_dst = 1,
};
- write_sm1_instruction(ctx, buffer, &instr);
+ write_sm1_instruction(ctx, buffer, &sm1_instr);
break;
}
diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c
index beb9ae574dc..a1065c8bc45 100644
--- a/libs/vkd3d/libs/vkd3d-shader/dxil.c
+++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c
@@ -296,8 +296,28 @@ enum dx_intrinsic_opcode
{
DX_LOAD_INPUT = 4,
DX_STORE_OUTPUT = 5,
+ DX_EXP = 21,
+ DX_FRC = 22,
+ DX_LOG = 23,
+ DX_SQRT = 24,
+ DX_RSQRT = 25,
+ DX_ROUND_NE = 26,
+ DX_ROUND_NI = 27,
+ DX_ROUND_PI = 28,
+ DX_ROUND_Z = 29,
+ DX_BFREV = 30,
+ DX_COUNT_BITS = 31,
+ DX_FIRST_BIT_LO = 32,
+ DX_FIRST_BIT_HI = 33,
+ DX_FIRST_BIT_SHI = 34,
DX_CREATE_HANDLE = 57,
DX_CBUFFER_LOAD_LEGACY = 59,
+ DX_DERIV_COARSEX = 83,
+ DX_DERIV_COARSEY = 84,
+ DX_DERIV_FINEX = 85,
+ DX_DERIV_FINEY = 86,
+ DX_LEGACY_F32TOF16 = 130,
+ DX_LEGACY_F16TOF32 = 131,
};
enum dxil_cast_code
@@ -439,6 +459,7 @@ struct dxil_record
{
unsigned int code;
unsigned int operand_count;
+ const struct dxil_record *attachment;
uint64_t operands[];
};
@@ -581,6 +602,7 @@ struct sm6_parser
size_t descriptor_count;
unsigned int indexable_temp_count;
+ unsigned int icb_count;
struct sm6_value *values;
size_t value_count;
@@ -796,6 +818,7 @@ static enum vkd3d_result sm6_parser_read_unabbrev_record(struct sm6_parser *sm6)
record->code = code;
record->operand_count = count;
+ record->attachment = NULL;
for (i = 0; i < count; ++i)
record->operands[i] = sm6_parser_read_vbr(sm6, 6);
@@ -1012,6 +1035,7 @@ static enum vkd3d_result sm6_parser_read_abbrev_record(struct sm6_parser *sm6, u
if (!abbrev->operands[i + 1].read_operand(sm6, abbrev->operands[i + 1].context, &record->operands[i]))
goto fail;
record->operand_count = count;
+ record->attachment = NULL;
/* An array can occur only as the last operand. */
if (abbrev->is_array)
@@ -1572,6 +1596,11 @@ static bool sm6_type_is_bool_i16_i32_i64(const struct sm6_type *type)
return type->class == TYPE_CLASS_INTEGER && (type->u.width == 1 || type->u.width >= 16);
}
+static bool sm6_type_is_i16_i32_i64(const struct sm6_type *type)
+{
+ return type->class == TYPE_CLASS_INTEGER && type->u.width >= 16;
+}
+
static bool sm6_type_is_bool(const struct sm6_type *type)
{
return type->class == TYPE_CLASS_INTEGER && type->u.width == 1;
@@ -1587,6 +1616,16 @@ static inline bool sm6_type_is_i32(const struct sm6_type *type)
return type->class == TYPE_CLASS_INTEGER && type->u.width == 32;
}
+static bool sm6_type_is_float(const struct sm6_type *type)
+{
+ return type->class == TYPE_CLASS_FLOAT && type->u.width == 32;
+}
+
+static bool sm6_type_is_f16_f32(const struct sm6_type *type)
+{
+ return type->class == TYPE_CLASS_FLOAT && (type->u.width == 16 || type->u.width == 32);
+}
+
static inline bool sm6_type_is_floating_point(const struct sm6_type *type)
{
return type->class == TYPE_CLASS_FLOAT;
@@ -2412,7 +2451,7 @@ static enum vkd3d_result value_allocate_constant_array(struct sm6_value *dst, co
return VKD3D_ERROR_INVALID_SHADER;
}
size = max(size, sizeof(icb->data[0]));
- count = type->u.array.count * size / sizeof(icb->data[0]);
+ count = operands ? type->u.array.count * size / sizeof(icb->data[0]) : 0;
if (!(icb = vkd3d_malloc(offsetof(struct vkd3d_shader_immediate_constant_buffer, data[count]))))
{
@@ -2433,9 +2472,14 @@ static enum vkd3d_result value_allocate_constant_array(struct sm6_value *dst, co
dst->value_type = VALUE_TYPE_ICB;
dst->u.icb = icb;
+ icb->register_idx = sm6->icb_count++;
icb->data_type = vkd3d_data_type_from_sm6_type(elem_type);
icb->element_count = type->u.array.count;
icb->component_count = 1;
+ icb->is_null = !operands;
+
+ if (!operands)
+ return VKD3D_OK;
count = type->u.array.count;
if (size > sizeof(icb->data[0]))
@@ -2510,12 +2554,10 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const
switch (record->code)
{
case CST_CODE_NULL:
- if (sm6_type_is_array(type))
+ if (sm6_type_is_array(type)
+ && (ret = value_allocate_constant_array(dst, type, NULL, sm6)) < 0)
{
- FIXME("Constant null arrays are not supported.\n");
- vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
- "Constant null arrays are not supported.");
- return VKD3D_ERROR_INVALID_SHADER;
+ return ret;
}
/* For non-aggregates, register constant data is already zero-filled. */
break;
@@ -2588,6 +2630,13 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const
break;
}
+ if (record->attachment)
+ {
+ WARN("Ignoring metadata attachment.\n");
+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_ATTACHMENT,
+ "Ignoring a metadata attachment for a constant.");
+ }
+
++sm6->value_count;
}
@@ -2626,6 +2675,18 @@ static struct vkd3d_shader_instruction *sm6_parser_add_instruction(struct sm6_pa
return ins;
}
+static void sm6_parser_declare_icb(struct sm6_parser *sm6, const struct sm6_type *elem_type, unsigned int count,
+ unsigned int alignment, unsigned int init, struct sm6_value *dst)
+{
+ enum vkd3d_data_type data_type = vkd3d_data_type_from_sm6_type(elem_type);
+ struct vkd3d_shader_instruction *ins;
+
+ ins = sm6_parser_add_instruction(sm6, VKD3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER);
+ /* The icb value index will be resolved later so forward references can be handled. */
+ ins->declaration.icb = (void *)(intptr_t)init;
+ register_init_with_id(&dst->u.reg, VKD3DSPR_IMMCONSTBUFFER, data_type, init);
+}
+
static void sm6_parser_declare_indexable_temp(struct sm6_parser *sm6, const struct sm6_type *elem_type,
unsigned int count, unsigned int alignment, unsigned int init, struct sm6_value *dst)
{
@@ -2762,7 +2823,10 @@ static bool sm6_parser_declare_global(struct sm6_parser *sm6, const struct dxil_
if (address_space == ADDRESS_SPACE_DEFAULT)
{
- sm6_parser_declare_indexable_temp(sm6, scalar_type, count, alignment, init, dst);
+ if (is_constant)
+ sm6_parser_declare_icb(sm6, scalar_type, count, alignment, init, dst);
+ else
+ sm6_parser_declare_indexable_temp(sm6, scalar_type, count, alignment, init, dst);
}
else if (address_space == ADDRESS_SPACE_GROUPSHARED)
{
@@ -2806,11 +2870,11 @@ static const struct vkd3d_shader_immediate_constant_buffer *resolve_forward_init
static enum vkd3d_result sm6_parser_globals_init(struct sm6_parser *sm6)
{
const struct dxil_block *block = &sm6->root_block;
+ size_t i, base_value_idx = sm6->value_count;
struct vkd3d_shader_instruction *ins;
const struct dxil_record *record;
enum vkd3d_result ret;
uint64_t version;
- size_t i;
sm6->p.location.line = block->id;
sm6->p.location.column = 0;
@@ -2868,6 +2932,21 @@ static enum vkd3d_result sm6_parser_globals_init(struct sm6_parser *sm6)
ins->declaration.indexable_temp.initialiser = resolve_forward_initialiser(
(uintptr_t)ins->declaration.indexable_temp.initialiser, sm6);
}
+ else if (ins->handler_idx == VKD3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER)
+ {
+ ins->declaration.icb = resolve_forward_initialiser((uintptr_t)ins->declaration.icb, sm6);
+ }
+ }
+ for (i = base_value_idx; i < sm6->value_count; ++i)
+ {
+ const struct vkd3d_shader_immediate_constant_buffer *icb;
+ struct sm6_value *value = &sm6->values[i];
+
+ if (!sm6_value_is_register(value) || value->u.reg.type != VKD3DSPR_IMMCONSTBUFFER)
+ continue;
+
+ if ((icb = resolve_forward_initialiser(value->u.reg.idx[0].offset, sm6)))
+ value->u.reg.idx[0].offset = icb->register_idx;
}
return VKD3D_OK;
@@ -3171,6 +3250,67 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco
}
}
+static enum vkd3d_shader_opcode map_dx_unary_op(enum dx_intrinsic_opcode op)
+{
+ switch (op)
+ {
+ case DX_EXP:
+ return VKD3DSIH_EXP;
+ case DX_FRC:
+ return VKD3DSIH_FRC;
+ case DX_LOG:
+ return VKD3DSIH_LOG;
+ case DX_SQRT:
+ return VKD3DSIH_SQRT;
+ case DX_RSQRT:
+ return VKD3DSIH_RSQ;
+ case DX_ROUND_NE:
+ return VKD3DSIH_ROUND_NE;
+ case DX_ROUND_NI:
+ return VKD3DSIH_ROUND_NI;
+ case DX_ROUND_PI:
+ return VKD3DSIH_ROUND_PI;
+ case DX_ROUND_Z:
+ return VKD3DSIH_ROUND_Z;
+ case DX_BFREV:
+ return VKD3DSIH_BFREV;
+ case DX_COUNT_BITS:
+ return VKD3DSIH_COUNTBITS;
+ case DX_FIRST_BIT_LO:
+ return VKD3DSIH_FIRSTBIT_LO;
+ case DX_FIRST_BIT_HI:
+ return VKD3DSIH_FIRSTBIT_HI;
+ case DX_FIRST_BIT_SHI:
+ return VKD3DSIH_FIRSTBIT_SHI;
+ case DX_DERIV_COARSEX:
+ return VKD3DSIH_DSX_COARSE;
+ case DX_DERIV_COARSEY:
+ return VKD3DSIH_DSY_COARSE;
+ case DX_DERIV_FINEX:
+ return VKD3DSIH_DSX_FINE;
+ case DX_DERIV_FINEY:
+ return VKD3DSIH_DSY_FINE;
+ case DX_LEGACY_F32TOF16:
+ return VKD3DSIH_F32TOF16;
+ case DX_LEGACY_F16TOF32:
+ return VKD3DSIH_F16TOF32;
+ default:
+ vkd3d_unreachable();
+ }
+}
+
+static void sm6_parser_emit_dx_unary(struct sm6_parser *sm6, struct sm6_block *code_block,
+ enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct vkd3d_shader_instruction *ins)
+{
+ struct vkd3d_shader_src_param *src_param;
+
+ vsir_instruction_init(ins, &sm6->p.location, map_dx_unary_op(op));
+ src_param = instruction_src_params_alloc(ins, 1, sm6);
+ src_param_init_from_value(src_param, operands[0]);
+
+ instruction_dst_param_init_ssa_scalar(ins, sm6);
+}
+
static void sm6_parser_emit_dx_cbuffer_load(struct sm6_parser *sm6, struct sm6_block *code_block,
enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct vkd3d_shader_instruction *ins)
{
@@ -3344,7 +3484,7 @@ static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, struct sm6_b
struct sm6_dx_opcode_info
{
- const char ret_type;
+ const char *ret_type;
const char *operand_info;
void (*handler)(struct sm6_parser *, struct sm6_block *, enum dx_intrinsic_opcode,
const struct sm6_value **, struct vkd3d_shader_instruction *);
@@ -3355,16 +3495,40 @@ struct sm6_dx_opcode_info
b -> constant int1
c -> constant int8/16/32
i -> int32
+ m -> int16/32/64
+ f -> float
+ e -> half/float
+ g -> half/float/double
H -> handle
v -> void
o -> overloaded
*/
static const struct sm6_dx_opcode_info sm6_dx_op_table[] =
{
- [DX_CBUFFER_LOAD_LEGACY ] = {'o', "Hi", sm6_parser_emit_dx_cbuffer_load},
- [DX_CREATE_HANDLE ] = {'H', "ccib", sm6_parser_emit_dx_create_handle},
- [DX_LOAD_INPUT ] = {'o', "ii8i", sm6_parser_emit_dx_load_input},
- [DX_STORE_OUTPUT ] = {'v', "ii8o", sm6_parser_emit_dx_store_output},
+ [DX_BFREV ] = {"m0", "m", sm6_parser_emit_dx_unary},
+ [DX_CBUFFER_LOAD_LEGACY ] = {"o", "Hi", sm6_parser_emit_dx_cbuffer_load},
+ [DX_COUNT_BITS ] = {"i", "m", sm6_parser_emit_dx_unary},
+ [DX_CREATE_HANDLE ] = {"H", "ccib", sm6_parser_emit_dx_create_handle},
+ [DX_DERIV_COARSEX ] = {"e0", "e", sm6_parser_emit_dx_unary},
+ [DX_DERIV_COARSEY ] = {"e0", "e", sm6_parser_emit_dx_unary},
+ [DX_DERIV_FINEX ] = {"e0", "e", sm6_parser_emit_dx_unary},
+ [DX_DERIV_FINEY ] = {"e0", "e", sm6_parser_emit_dx_unary},
+ [DX_EXP ] = {"g0", "g", sm6_parser_emit_dx_unary},
+ [DX_FIRST_BIT_HI ] = {"i", "m", sm6_parser_emit_dx_unary},
+ [DX_FIRST_BIT_LO ] = {"i", "m", sm6_parser_emit_dx_unary},
+ [DX_FIRST_BIT_SHI ] = {"i", "m", sm6_parser_emit_dx_unary},
+ [DX_FRC ] = {"g0", "g", sm6_parser_emit_dx_unary},
+ [DX_LEGACY_F16TOF32 ] = {"f", "i", sm6_parser_emit_dx_unary},
+ [DX_LEGACY_F32TOF16 ] = {"i", "f", sm6_parser_emit_dx_unary},
+ [DX_LOAD_INPUT ] = {"o", "ii8i", sm6_parser_emit_dx_load_input},
+ [DX_LOG ] = {"g0", "g", sm6_parser_emit_dx_unary},
+ [DX_ROUND_NE ] = {"g0", "g", sm6_parser_emit_dx_unary},
+ [DX_ROUND_NI ] = {"g0", "g", sm6_parser_emit_dx_unary},
+ [DX_ROUND_PI ] = {"g0", "g", sm6_parser_emit_dx_unary},
+ [DX_ROUND_Z ] = {"g0", "g", sm6_parser_emit_dx_unary},
+ [DX_RSQRT ] = {"g0", "g", sm6_parser_emit_dx_unary},
+ [DX_SQRT ] = {"g0", "g", sm6_parser_emit_dx_unary},
+ [DX_STORE_OUTPUT ] = {"v", "ii8o", sm6_parser_emit_dx_store_output},
};
static bool sm6_parser_validate_operand_type(struct sm6_parser *sm6, const struct sm6_value *value, char info_type,
@@ -3389,6 +3553,14 @@ static bool sm6_parser_validate_operand_type(struct sm6_parser *sm6, const struc
&& type->u.width <= 32;
case 'i':
return sm6_type_is_i32(type);
+ case 'm':
+ return sm6_type_is_i16_i32_i64(type);
+ case 'f':
+ return sm6_type_is_float(type);
+ case 'e':
+ return sm6_type_is_f16_f32(type);
+ case 'g':
+ return sm6_type_is_floating_point(type);
case 'H':
return (is_return || sm6_value_is_handle(value)) && type == sm6->handle_type;
case 'v':
@@ -3402,6 +3574,17 @@ static bool sm6_parser_validate_operand_type(struct sm6_parser *sm6, const struc
}
}
+static bool operand_types_match(struct sm6_value *dst, const struct sm6_value **operands, unsigned int operand_count,
+ char index_char)
+{
+ unsigned int i = index_char - '0';
+
+ assert(i < 10);
+ if (i >= operand_count)
+ return false;
+ return dst->type == operands[i]->type;
+}
+
static bool sm6_parser_validate_dx_op(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const char *name,
const struct sm6_value **operands, unsigned int operand_count, struct sm6_value *dst)
{
@@ -3410,7 +3593,9 @@ static bool sm6_parser_validate_dx_op(struct sm6_parser *sm6, enum dx_intrinsic_
info = &sm6_dx_op_table[op];
- if (!sm6_parser_validate_operand_type(sm6, dst, info->ret_type, true))
+ assert(info->ret_type[0]);
+ if (!sm6_parser_validate_operand_type(sm6, dst, info->ret_type[0], true)
+ || (info->ret_type[1] && !operand_types_match(dst, operands, operand_count, info->ret_type[1])))
{
WARN("Failed to validate return type for dx intrinsic id %u, '%s'.\n", op, name);
/* Return type validation failure is not so critical. We only need to set
@@ -3700,6 +3885,9 @@ static void sm6_parser_emit_cast(struct sm6_parser *sm6, const struct dxil_recor
if (handler_idx == VKD3DSIH_NOP)
{
dst->u.reg = value->u.reg;
+ /* Set the result type for casts from 16-bit min precision. */
+ if (type->u.width != 16)
+ dst->u.reg.data_type = vkd3d_data_type_from_sm6_type(type);
return;
}
@@ -4153,6 +4341,208 @@ static bool sm6_metadata_get_uint64_value(const struct sm6_parser *sm6,
return true;
}
+static void sm6_parser_metadata_attachment_block_init(struct sm6_parser *sm6, const struct dxil_block *target_block,
+ const struct dxil_block *block)
+{
+ struct dxil_record *target_record;
+ const struct dxil_record *record;
+ unsigned int i;
+ uint64_t index;
+
+ for (i = 0; i < block->record_count; ++i)
+ {
+ record = block->records[i];
+ if (record->code != METADATA_ATTACHMENT)
+ {
+ WARN("Ignoring record with code %u.\n", record->code);
+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_ATTACHMENT,
+ "Ignoring a metadata attachment record with code %u.", record->code);
+ continue;
+ }
+ if (!(record->operand_count & 1))
+ {
+ WARN("Ignoring function attachment.\n");
+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_ATTACHMENT,
+ "Ignoring a metadata function attachment.");
+ continue;
+ }
+
+ index = record->operands[0];
+ if (!target_block->record_count || index >= target_block->record_count - 1)
+ {
+ WARN("Invalid record index %"PRIu64".\n", index);
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
+ "Invalid record index %"PRIu64" for a metadata attachment.", index);
+ continue;
+ }
+ /* 'index' is an instruction index, but records[0] is DECLAREBLOCKS, not an instruction. */
+ target_record = target_block->records[index + 1];
+ if (target_record->attachment)
+ {
+ WARN("Overwriting record attachment.\n");
+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_ATTACHMENT,
+ "The target record for a metadata attachment already has an attachment.");
+ }
+ target_record->attachment = record;
+ }
+}
+
+static void sm6_parser_metadata_attachments_init(struct sm6_parser *sm6, const struct dxil_block *block)
+{
+ unsigned int i;
+
+ for (i = 0; i < block->child_block_count; ++i)
+ {
+ if (block->child_blocks[i]->id == METADATA_ATTACHMENT_BLOCK)
+ sm6_parser_metadata_attachment_block_init(sm6, block, block->child_blocks[i]);
+ }
+}
+
+static const struct sm6_metadata_value *sm6_parser_find_metadata_kind(const struct sm6_parser *sm6, uint64_t id)
+{
+ unsigned int i, j;
+
+ for (i = 0; i < ARRAY_SIZE(sm6->metadata_tables); ++i)
+ {
+ for (j = 0; j < sm6->metadata_tables[i].count; ++j)
+ {
+ if (sm6->metadata_tables[i].values[j].type == VKD3D_METADATA_KIND
+ && sm6->metadata_tables[i].values[j].u.kind.id == id)
+ return &sm6->metadata_tables[i].values[j];
+ }
+ }
+
+ return NULL;
+}
+
+static const struct sm6_metadata_value *sm6_parser_metadata_get_value(const struct sm6_parser *sm6, uint64_t index)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(sm6->metadata_tables); ++i)
+ {
+ if (sm6->metadata_tables[i].count > index)
+ break;
+ index -= sm6->metadata_tables[i].count;
+ }
+
+ return (index < sm6->metadata_tables[i].count) ? &sm6->metadata_tables[i].values[index] : NULL;
+}
+
+static bool metadata_node_get_unary_uint(const struct sm6_metadata_node *node, unsigned int *operand,
+ struct sm6_parser *sm6)
+{
+ if (node->operand_count != 1)
+ {
+ FIXME("Ignoring node with %u operands.\n", node->operand_count);
+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_ATTACHMENT,
+ "Ignoring metadata attachment node with %u operands; expected unary.", node->operand_count);
+ return false;
+ }
+ if (!sm6_metadata_value_is_value(node->operands[0])
+ || !sm6_metadata_get_uint_value(sm6, node->operands[0], operand))
+ {
+ WARN("Failed to get operand value.\n");
+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_ATTACHMENT,
+ "Failed to get a metadata attachment operand value; ignoring the attachment.");
+ return false;
+ }
+
+ return true;
+}
+
+static void metadata_attachment_record_apply(const struct dxil_record *record, enum bitcode_function_code func_code,
+ struct vkd3d_shader_instruction *ins, struct sm6_value *dst, struct sm6_parser *sm6)
+{
+ static const char *ignored_names[] =
+ {
+ "alias.scope",
+ "dx.controlflow.hints",
+ "llvm.loop",
+ "noalias",
+ "tbaa",
+ "range",
+ };
+ const struct sm6_metadata_node *node;
+ const struct sm6_metadata_value *m;
+ unsigned int i, j, operand;
+ bool ignored = false;
+ const char *name;
+
+ if (record->attachment)
+ {
+ WARN("Ignoring nested metadata attachment.\n");
+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_ATTACHMENT,
+ "Ignoring a nested metadata attachment.");
+ }
+
+ assert(record->operand_count & 1);
+ for (i = 1; i < record->operand_count; i += 2)
+ {
+ if (!(m = sm6_parser_find_metadata_kind(sm6, record->operands[i])))
+ {
+ WARN("Failed to find metadata kind %"PRIx64".\n", record->operands[i]);
+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_ATTACHMENT,
+ "Failed to find metadata kind %"PRIx64" for an attachment.", record->operands[i]);
+ continue;
+ }
+ name = m->u.kind.name;
+
+ m = sm6_parser_metadata_get_value(sm6, record->operands[i + 1]);
+ if (!m || !sm6_metadata_value_is_node(m))
+ {
+ WARN("Failed to retrieve metadata attachment node.\n");
+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_ATTACHMENT,
+ "Failed to retrieve a metadata attachment node.");
+ continue;
+ }
+ node = m->u.node;
+
+ if (!strcmp(name, "dx.precise"))
+ {
+ if (!sm6_value_is_register(dst))
+ {
+ WARN("Precise value is not a register.\n");
+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_ATTACHMENT,
+ "A value marked as precise is not a register.");
+ }
+ else if (metadata_node_get_unary_uint(node, &operand, sm6) && operand)
+ {
+ ins->flags |= sm6_type_is_scalar(dst->type) ? VKD3DSI_PRECISE_X : VKD3DSI_PRECISE_XYZW;
+ }
+ }
+ else if (!strcmp(name, "dx.nonuniform"))
+ {
+ if (!sm6_value_is_register(dst))
+ {
+ WARN("Non-uniform value is not a register.\n");
+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_ATTACHMENT,
+ "A value marked as non-uniform is not a register.");
+ }
+ else if (metadata_node_get_unary_uint(node, &operand, sm6))
+ {
+ dst->u.reg.non_uniform = !!operand;
+ }
+ }
+ else
+ {
+ for (j = 0; j < ARRAY_SIZE(ignored_names); ++j)
+ if (!strcmp(name, ignored_names[j]))
+ break;
+ if (j == ARRAY_SIZE(ignored_names))
+ {
+ WARN("Ignoring metadata attachment '%s'.\n", name);
+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_ATTACHMENT,
+ "Ignoring a metadata attachment named '%s'.", name);
+ }
+ ignored = true;
+ }
+
+ if (func_code != FUNC_CODE_INST_CALL && !ignored)
+ WARN("Metadata attachment target is not a function call.\n");
+ }
+}
+
static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const struct dxil_block *block,
struct sm6_function *function)
{
@@ -4278,6 +4668,9 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const
return VKD3D_ERROR;
assert(ins->handler_idx != VKD3DSIH_INVALID);
+ if (record->attachment)
+ metadata_attachment_record_apply(record->attachment, record->code, ins, dst, sm6);
+
if (is_terminator)
{
++block_idx;
@@ -4331,6 +4724,8 @@ static enum vkd3d_result sm6_parser_module_init(struct sm6_parser *sm6, const st
sm6->p.location.line = block->id;
sm6->p.location.column = 0;
+ sm6_parser_metadata_attachments_init(sm6, block);
+
switch (block->id)
{
case CONSTANTS_BLOCK:
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y
index 0dde4c18587..ed053f16312 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y
@@ -487,27 +487,27 @@ static void resolve_loop_continue(struct hlsl_ctx *ctx, struct hlsl_block *block
else if (instr->type == HLSL_IR_JUMP)
{
struct hlsl_ir_jump *jump = hlsl_ir_jump(instr);
- struct hlsl_block block;
+ struct hlsl_block cond_block;
if (jump->type != HLSL_IR_JUMP_UNRESOLVED_CONTINUE)
continue;
if (type == LOOP_DO_WHILE)
{
- if (!hlsl_clone_block(ctx, &block, cond))
+ if (!hlsl_clone_block(ctx, &cond_block, cond))
return;
- if (!append_conditional_break(ctx, &block))
+ if (!append_conditional_break(ctx, &cond_block))
{
- hlsl_block_cleanup(&block);
+ hlsl_block_cleanup(&cond_block);
return;
}
- list_move_before(&instr->entry, &block.instrs);
+ list_move_before(&instr->entry, &cond_block.instrs);
}
else if (type == LOOP_FOR)
{
- if (!hlsl_clone_block(ctx, &block, iter))
+ if (!hlsl_clone_block(ctx, &cond_block, iter))
return;
- list_move_before(&instr->entry, &block.instrs);
+ list_move_before(&instr->entry, &cond_block.instrs);
}
jump->type = HLSL_IR_JUMP_CONTINUE;
}
@@ -3553,7 +3553,7 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer *
{
struct hlsl_resource_load_params load_params = { 0 };
const struct hlsl_type *sampler_type;
- struct hlsl_ir_node *coords, *load;
+ struct hlsl_ir_node *coords, *sample;
if (params->args_count != 2 && params->args_count != 4)
{
@@ -3688,9 +3688,9 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer *
load_params.format = hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, 4);
load_params.sampling_dim = dim;
- if (!(load = hlsl_new_resource_load(ctx, &load_params, loc)))
+ if (!(sample = hlsl_new_resource_load(ctx, &load_params, loc)))
return false;
- hlsl_block_add_instr(params->instrs, load);
+ hlsl_block_add_instr(params->instrs, sample);
return true;
}
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
index 4a622185741..88cbef61d5f 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
@@ -1090,7 +1090,7 @@ static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr,
unsigned int dim_count = hlsl_sampler_dim_count(val->data_type->sampler_dim);
struct hlsl_ir_node *coords = index->idx.node;
struct hlsl_resource_load_params params = {0};
- struct hlsl_ir_node *load;
+ struct hlsl_ir_node *resource_load;
assert(coords->data_type->class == HLSL_CLASS_VECTOR);
assert(coords->data_type->base_type == HLSL_TYPE_UINT);
@@ -1104,9 +1104,9 @@ static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr,
params.coords = coords;
params.format = val->data_type->e.resource_format;
- if (!(load = hlsl_new_resource_load(ctx, &params, &instr->loc)))
+ if (!(resource_load = hlsl_new_resource_load(ctx, &params, &instr->loc)))
return false;
- hlsl_block_add_instr(block, load);
+ hlsl_block_add_instr(block, resource_load);
return true;
}
@@ -2301,7 +2301,6 @@ static bool normalize_switch_cases(struct hlsl_ctx *ctx, struct hlsl_ir_node *in
struct hlsl_ir_switch_case *c, *def = NULL;
bool missing_terminal_break = false;
struct hlsl_ir_node *node;
- struct hlsl_ir_jump *jump;
struct hlsl_ir_switch *s;
if (instr->type != HLSL_IR_SWITCH)
@@ -2320,10 +2319,7 @@ static bool normalize_switch_cases(struct hlsl_ctx *ctx, struct hlsl_ir_node *in
{
node = LIST_ENTRY(list_tail(&c->body.instrs), struct hlsl_ir_node, entry);
if (node->type == HLSL_IR_JUMP)
- {
- jump = hlsl_ir_jump(node);
- terminal_break = jump->type == HLSL_IR_JUMP_BREAK;
- }
+ terminal_break = (hlsl_ir_jump(node)->type == HLSL_IR_JUMP_BREAK);
}
missing_terminal_break |= !terminal_break;
diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c
index 710811c6761..a35ef862096 100644
--- a/libs/vkd3d/libs/vkd3d-shader/ir.c
+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c
@@ -463,6 +463,7 @@ static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_i
struct vkd3d_shader_instruction_array *instructions;
struct control_point_normaliser normaliser;
unsigned int input_control_point_count;
+ struct vkd3d_shader_location location;
struct vkd3d_shader_instruction *ins;
enum vkd3d_result ret;
unsigned int i, j;
@@ -513,8 +514,10 @@ static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_i
return VKD3D_OK;
case VKD3DSIH_HS_FORK_PHASE:
case VKD3DSIH_HS_JOIN_PHASE:
+ /* ins may be relocated if the instruction array expands. */
+ location = ins->location;
ret = control_point_normaliser_emit_hs_input(&normaliser, input_signature,
- input_control_point_count, i, &ins->location);
+ input_control_point_count, i, &location);
*src_instructions = normaliser.instructions;
return ret;
default:
diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c
index c8a43adbe03..a22c59577ac 100644
--- a/libs/vkd3d/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c
@@ -1194,6 +1194,16 @@ static uint32_t vkd3d_spirv_get_op_constant64(struct vkd3d_spirv_builder *builde
(const uint32_t *)&value, 2, vkd3d_spirv_build_op_constant64);
}
+static uint32_t vkd3d_spirv_build_op_constant_null(struct vkd3d_spirv_builder *builder, uint32_t result_type)
+{
+ return vkd3d_spirv_build_op_tr(builder, &builder->global_stream, SpvOpConstantNull, result_type);
+}
+
+static uint32_t vkd3d_spirv_get_op_constant_null(struct vkd3d_spirv_builder *builder, uint32_t result_type)
+{
+ return vkd3d_spirv_build_once1(builder, SpvOpConstantNull, result_type, vkd3d_spirv_build_op_constant_null);
+}
+
static uint32_t vkd3d_spirv_build_op_constant_composite(struct vkd3d_spirv_builder *builder,
uint32_t result_type, const uint32_t *constituents, unsigned int constituent_count)
{
@@ -2152,6 +2162,7 @@ static void vkd3d_symbol_make_register(struct vkd3d_symbol *symbol,
break;
case VKD3DSPR_IMMCONSTBUFFER:
+ symbol->key.reg.idx = reg->idx_count > 1 ? reg->idx[0].offset : 0;
break;
default:
@@ -3498,7 +3509,7 @@ static void spirv_compiler_emit_dereference_register(struct spirv_compiler *comp
}
else if (reg->type == VKD3DSPR_IMMCONSTBUFFER)
{
- indexes[index_count++] = spirv_compiler_emit_register_addressing(compiler, &reg->idx[0]);
+ indexes[index_count++] = spirv_compiler_emit_register_addressing(compiler, &reg->idx[reg->idx_count - 1]);
}
else if (reg->type == VKD3DSPR_IDXTEMP)
{
@@ -3756,6 +3767,69 @@ static uint32_t spirv_compiler_emit_load_scalar(struct spirv_compiler *compiler,
return val_id;
}
+static uint32_t spirv_compiler_emit_constant_array(struct spirv_compiler *compiler,
+ const struct vkd3d_shader_immediate_constant_buffer *icb, uint32_t *type_id_out)
+{
+ uint32_t *elements, elem_type_id, length_id, type_id, const_id;
+ struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
+ enum vkd3d_shader_component_type component_type;
+ unsigned int i, element_count, component_count;
+
+ element_count = icb->element_count;
+
+ component_type = vkd3d_component_type_from_data_type(icb->data_type);
+ component_count = icb->component_count;
+ elem_type_id = vkd3d_spirv_get_type_id_for_data_type(builder, icb->data_type, component_count);
+ length_id = spirv_compiler_get_constant_uint(compiler, element_count);
+ type_id = vkd3d_spirv_get_op_type_array(builder, elem_type_id, length_id);
+
+ if (type_id_out)
+ *type_id_out = type_id;
+
+ if (icb->is_null)
+ {
+ /* All values are null. Workgroup memory initialisers require OpConstantNull. */
+ return vkd3d_spirv_get_op_constant_null(builder, type_id);
+ }
+
+ if (!(elements = vkd3d_calloc(element_count, sizeof(*elements))))
+ {
+ ERR("Failed to allocate %u elements.", element_count);
+ spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_OUT_OF_MEMORY,
+ "Failed to allocate %u constant array elements.", element_count);
+ return 0;
+ }
+
+ switch (icb->data_type)
+ {
+ case VKD3D_DATA_FLOAT:
+ case VKD3D_DATA_INT:
+ case VKD3D_DATA_UINT:
+ for (i = 0; i < element_count; ++i)
+ elements[i] = spirv_compiler_get_constant(compiler, component_type, component_count,
+ &icb->data[component_count * i]);
+ break;
+ case VKD3D_DATA_DOUBLE:
+ case VKD3D_DATA_UINT64:
+ {
+ uint64_t *data = (uint64_t *)icb->data;
+ for (i = 0; i < element_count; ++i)
+ elements[i] = spirv_compiler_get_constant64(compiler, component_type, component_count,
+ &data[component_count * i]);
+ break;
+ }
+ default:
+ FIXME("Unhandled data type %u.\n", icb->data_type);
+ spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_INVALID_TYPE,
+ "Immediate constant buffer data type %u is unhandled.", icb->data_type);
+ break;
+ }
+
+ const_id = vkd3d_spirv_build_op_constant_composite(builder, type_id, elements, element_count);
+ vkd3d_free(elements);
+ return const_id;
+}
+
static const struct ssa_register_info *spirv_compiler_get_ssa_register_info(const struct spirv_compiler *compiler,
const struct vkd3d_shader_register *reg)
{
@@ -5493,39 +5567,40 @@ static void spirv_compiler_emit_dcl_indexable_temp(struct spirv_compiler *compil
{
const struct vkd3d_shader_indexable_temp *temp = &instruction->declaration.indexable_temp;
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
+ uint32_t id, type_id, length_id, ptr_type_id, init_id = 0;
+ enum vkd3d_shader_component_type component_type;
struct vkd3d_shader_register reg;
struct vkd3d_symbol reg_symbol;
+ SpvStorageClass storage_class;
size_t function_location;
- uint32_t id;
- if (temp->component_count != 4)
- FIXME("Unhandled component count %u.\n", temp->component_count);
+ storage_class = SpvStorageClassFunction;
vsir_register_init(&reg, VKD3DSPR_IDXTEMP, VKD3D_DATA_FLOAT, 1);
reg.idx[0].offset = temp->register_idx;
if (temp->alignment)
WARN("Ignoring alignment %u.\n", temp->alignment);
- if (temp->initialiser)
- {
- FIXME("Initialisers are not supported.\n");
- spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED,
- "Initialisers for indexable temps are not supported.");
- }
function_location = spirv_compiler_get_current_function_location(compiler);
vkd3d_spirv_begin_function_stream_insertion(builder, function_location);
- id = spirv_compiler_emit_array_variable(compiler, &builder->function_stream,
- SpvStorageClassFunction, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE, &temp->register_size, 1);
+ component_type = vkd3d_component_type_from_data_type(temp->data_type);
+ type_id = vkd3d_spirv_get_type_id(builder, component_type, temp->component_count);
+ length_id = spirv_compiler_get_constant_uint(compiler, temp->register_size);
+ type_id = vkd3d_spirv_get_op_type_array(builder, type_id, length_id);
+ ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, storage_class, type_id);
+ if (temp->initialiser)
+ init_id = spirv_compiler_emit_constant_array(compiler, temp->initialiser, NULL);
+ id = vkd3d_spirv_build_op_variable(builder, &builder->function_stream, ptr_type_id, storage_class, init_id);
spirv_compiler_emit_register_debug_name(builder, id, &reg);
vkd3d_spirv_end_function_stream_insertion(builder);
vkd3d_symbol_make_register(&reg_symbol, &reg);
- vkd3d_symbol_set_register_info(&reg_symbol, id,
- SpvStorageClassFunction, VKD3D_SHADER_COMPONENT_FLOAT, VKD3DSP_WRITEMASK_ALL);
+ vkd3d_symbol_set_register_info(&reg_symbol, id, storage_class,
+ component_type, vkd3d_write_mask_from_component_count(temp->component_count));
spirv_compiler_put_symbol(compiler, &reg_symbol);
}
@@ -5743,34 +5818,24 @@ static void spirv_compiler_emit_dcl_immediate_constant_buffer(struct spirv_compi
const struct vkd3d_shader_instruction *instruction)
{
const struct vkd3d_shader_immediate_constant_buffer *icb = instruction->declaration.icb;
- uint32_t *elements, length_id, type_id, const_id, ptr_type_id, icb_id;
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
+ uint32_t type_id, const_id, ptr_type_id, icb_id;
struct vkd3d_shader_register reg;
struct vkd3d_symbol reg_symbol;
- unsigned int i;
- assert(icb->data_type == VKD3D_DATA_FLOAT);
- assert(icb->component_count == VKD3D_VEC4_SIZE);
-
- if (!(elements = vkd3d_calloc(icb->element_count, sizeof(*elements))))
- return;
- for (i = 0; i < icb->element_count; ++i)
- elements[i] = spirv_compiler_get_constant(compiler,
- VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE, &icb->data[4 * i]);
- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE);
- length_id = spirv_compiler_get_constant_uint(compiler, icb->element_count);
- type_id = vkd3d_spirv_get_op_type_array(builder, type_id, length_id);
- const_id = vkd3d_spirv_build_op_constant_composite(builder, type_id, elements, icb->element_count);
+ const_id = spirv_compiler_emit_constant_array(compiler, icb, &type_id);
ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassPrivate, type_id);
icb_id = vkd3d_spirv_build_op_variable(builder, &builder->global_stream,
ptr_type_id, SpvStorageClassPrivate, const_id);
vkd3d_spirv_build_op_name(builder, icb_id, "icb");
- vkd3d_free(elements);
- vsir_register_init(&reg, VKD3DSPR_IMMCONSTBUFFER, VKD3D_DATA_FLOAT, 0);
+ /* Set an index count of 2 so vkd3d_symbol_make_register() uses idx[0] as a buffer id. */
+ vsir_register_init(&reg, VKD3DSPR_IMMCONSTBUFFER, VKD3D_DATA_FLOAT, 2);
+ reg.idx[0].offset = icb->register_idx;
vkd3d_symbol_make_register(&reg_symbol, &reg);
vkd3d_symbol_set_register_info(&reg_symbol, icb_id, SpvStorageClassPrivate,
- VKD3D_SHADER_COMPONENT_FLOAT, VKD3DSP_WRITEMASK_ALL);
+ vkd3d_component_type_from_data_type(icb->data_type),
+ vkd3d_write_mask_from_component_count(icb->component_count));
spirv_compiler_put_symbol(compiler, &reg_symbol);
}
diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c
index 80f8ab98c08..163cd90ee13 100644
--- a/libs/vkd3d/libs/vkd3d-shader/tpf.c
+++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c
@@ -792,9 +792,11 @@ static void shader_sm4_read_shader_data(struct vkd3d_shader_instruction *ins, ui
ins->handler_idx = VKD3DSIH_INVALID;
return;
}
+ icb->register_idx = 0;
icb->data_type = VKD3D_DATA_FLOAT;
icb->component_count = VKD3D_VEC4_SIZE;
icb->element_count = icb_size / VKD3D_VEC4_SIZE;
+ icb->is_null = false;
memcpy(icb->data, tokens, sizeof(*tokens) * icb_size);
shader_instruction_array_add_icb(&priv->p.instructions, icb);
ins->declaration.icb = icb;
@@ -1930,6 +1932,15 @@ static bool shader_sm4_read_param(struct vkd3d_shader_sm4_parser *priv, const ui
break;
}
}
+ else if (register_type == VKD3D_SM4_RT_IMMCONSTBUFFER)
+ {
+ if (param->idx_count != 1)
+ {
+ WARN("Unexpected idx count %u.\n", param->idx_count);
+ vkd3d_shader_parser_error(&priv->p, VKD3D_SHADER_ERROR_TPF_INVALID_REGISTER_INDEX_COUNT,
+ "Invalid index count %u for immediate const buffer register; expected count 1.", param->idx_count);
+ }
+ }
else if (!shader_is_sm_5_1(priv) && vsir_register_is_descriptor(param))
{
/* SM5.1 places a symbol identifier in idx[0] and moves
diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
index 8fd8945151f..d4a9d391477 100644
--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
@@ -23,6 +23,8 @@
#include <stdio.h>
#include <math.h>
+/* VKD3D_DEBUG_ENV_NAME("VKD3D_SHADER_DEBUG"); */
+
static inline int char_to_int(char c)
{
if ('0' <= c && c <= '9')
@@ -888,6 +890,21 @@ static void vkd3d_shader_scan_combined_sampler_declaration(
&semantic->resource.range, semantic->resource_type, VKD3D_SHADER_RESOURCE_DATA_FLOAT);
}
+static const struct vkd3d_shader_descriptor_info1 *find_descriptor(
+ const struct vkd3d_shader_scan_descriptor_info1 *info,
+ enum vkd3d_shader_descriptor_type type, unsigned int register_id)
+{
+ for (unsigned int i = 0; i < info->descriptor_count; ++i)
+ {
+ const struct vkd3d_shader_descriptor_info1 *d = &info->descriptors[i];
+
+ if (d->type == type && d->register_id == register_id)
+ return d;
+ }
+
+ return NULL;
+}
+
static void vkd3d_shader_scan_combined_sampler_usage(struct vkd3d_shader_scan_context *context,
const struct vkd3d_shader_register *resource, const struct vkd3d_shader_register *sampler)
{
@@ -913,7 +930,6 @@ static void vkd3d_shader_scan_combined_sampler_usage(struct vkd3d_shader_scan_co
if (vkd3d_shader_ver_ge(context->version, 5, 1))
{
- const struct vkd3d_shader_scan_descriptor_info1 *info = context->scan_descriptor_info;
const struct vkd3d_shader_descriptor_info1 *d;
bool dynamic_resource, dynamic_sampler;
@@ -928,30 +944,13 @@ static void vkd3d_shader_scan_combined_sampler_usage(struct vkd3d_shader_scan_co
if (dynamic_resource || dynamic_sampler)
return;
- for (i = 0; i < info->descriptor_count; ++i)
- {
- d = &info->descriptors[i];
- if (d->type != VKD3D_SHADER_DESCRIPTOR_TYPE_SRV)
- continue;
- if (d->register_id != resource->idx[0].offset)
- continue;
+ if ((d = find_descriptor(context->scan_descriptor_info,
+ VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, resource->idx[0].offset)))
resource_space = d->register_space;
- break;
- }
- if (sampler)
- {
- for (i = 0; i < info->descriptor_count; ++i)
- {
- d = &info->descriptors[i];
- if (d->type != VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER)
- continue;
- if (d->register_id != sampler->idx[0].offset)
- continue;
- sampler_space = d->register_space;
- break;
- }
- }
+ if (sampler && (d = find_descriptor(context->scan_descriptor_info,
+ VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, sampler->idx[0].offset)))
+ sampler_space = d->register_space;
}
for (i = 0; i < info->combined_sampler_count; ++i)
diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
index a93fa7160f7..4944b8a1c53 100644
--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -196,6 +196,7 @@ enum vkd3d_shader_error
VKD3D_SHADER_WARNING_DXIL_ENTRY_POINT_MISMATCH = 8306,
VKD3D_SHADER_WARNING_DXIL_INVALID_MASK = 8307,
VKD3D_SHADER_WARNING_DXIL_INVALID_OPERATION = 8308,
+ VKD3D_SHADER_WARNING_DXIL_IGNORING_ATTACHMENT = 8309,
VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED = 9000,
VKD3D_SHADER_ERROR_VSIR_INVALID_HANDLER = 9001,
@@ -793,10 +794,12 @@ struct vkd3d_shader_version
struct vkd3d_shader_immediate_constant_buffer
{
+ unsigned int register_idx;
enum vkd3d_data_type data_type;
/* total count is element_count * component_count */
unsigned int element_count;
unsigned int component_count;
+ bool is_null;
uint32_t data[];
};
--
2.43.0