Files
wine-staging/patches/vkd3d-latest/0003-Updated-vkd3d-to-b5b5c67b34be0c54bb4ee8a5439d65c2d1d.patch
Alistair Leslie-Hughes bbcdf55b0a Updated vkd3d-latest patchset
2025-10-30 07:44:02 +11:00

5283 lines
226 KiB
Diff

From 4d87ad9ccaeae715096c6248fe60ddaacc182575 Mon Sep 17 00:00:00 2001
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
Date: Tue, 14 Oct 2025 10:43:27 +1100
Subject: [PATCH] Updated vkd3d to b5b5c67b34be0c54bb4ee8a5439d65c2d1d6ba5d.
---
libs/vkd3d/include/vkd3d_shader.h | 61 ++
libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 5 -
libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 92 +-
libs/vkd3d/libs/vkd3d-shader/dxil.c | 118 ++-
libs/vkd3d/libs/vkd3d-shader/glsl.c | 54 +-
libs/vkd3d/libs/vkd3d-shader/hlsl.c | 4 +-
libs/vkd3d/libs/vkd3d-shader/hlsl.h | 4 +-
libs/vkd3d/libs/vkd3d-shader/hlsl.l | 1 -
libs/vkd3d/libs/vkd3d-shader/hlsl.y | 54 +-
libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 897 ++++++++++--------
libs/vkd3d/libs/vkd3d-shader/ir.c | 653 +++++++++++--
libs/vkd3d/libs/vkd3d-shader/msl.c | 26 +-
libs/vkd3d/libs/vkd3d-shader/spirv.c | 334 ++-----
.../libs/vkd3d-shader/vkd3d_shader_main.c | 77 +-
.../libs/vkd3d-shader/vkd3d_shader_private.h | 52 +-
15 files changed, 1455 insertions(+), 977 deletions(-)
diff --git a/libs/vkd3d/include/vkd3d_shader.h b/libs/vkd3d/include/vkd3d_shader.h
index 3a2f54c8f22..df1f5d5250d 100644
--- a/libs/vkd3d/include/vkd3d_shader.h
+++ b/libs/vkd3d/include/vkd3d_shader.h
@@ -125,6 +125,11 @@ enum vkd3d_shader_structure_type
* \since 1.18
*/
VKD3D_SHADER_STRUCTURE_TYPE_SCAN_THREAD_GROUP_SIZE_INFO,
+ /**
+ * The structure is a vkd3d_shader_d3dbc_source_info structure.
+ * \since 1.18
+ */
+ VKD3D_SHADER_STRUCTURE_TYPE_D3DBC_SOURCE_INFO,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_STRUCTURE_TYPE),
};
@@ -2312,6 +2317,61 @@ struct vkd3d_shader_scan_thread_group_size_info
unsigned int x, y, z;
};
+/**
+ * A chained structure containing legacy Direct3D bytecode compilation parameters.
+ * This structure specifies some information about the source environment that
+ * is not specified in the source shader format, but may be necessary for the
+ * target format.
+ *
+ * This structure is optional.
+ *
+ * This structure extends vkd3d_shader_compile_info.
+ *
+ * This structure contains only input parameters.
+ *
+ * \since 1.18
+ */
+struct vkd3d_shader_d3dbc_source_info
+{
+ /** Must be set to VKD3D_SHADER_STRUCTURE_TYPE_D3DBC_SOURCE_INFO. */
+ enum vkd3d_shader_structure_type type;
+ /** Optional pointer to a structure containing further parameters. */
+ const void *next;
+
+ /**
+ * The dimension of each texture bound to the shader.
+ *
+ * If this structure is not specified, the dimension for all textures will
+ * be VKD3D_SHADER_RESOURCE_TEXTURE_2D.
+ *
+ * The dimension of textures in this array not used by the shader will be
+ * ignored.
+ *
+ * This field is ignored for shader models 2 and higher.
+ */
+ enum vkd3d_shader_resource_type texture_dimensions[6];
+
+ /**
+ * A mask indicating which samplers should be shadow (i.e. comparison-mode)
+ * samplers. When legacy Direct3D shaders are used with the Direct3D 8 and 9
+ * APIs, this is implied by the format of the sampled resource; e.g. a
+ * D3DFMT_D24S8 texture implies shadow sampling, while a D3DFMT_A8R8G8B8
+ * or D3DFMT_INTZ texture does not.
+ * This information is necessary when converting to other formats
+ * (e.g. SPIR-V, GLSL) which specify this in the shader.
+ *
+ * For example, if bit 1 is set (so the value is 0x2), this indicates that
+ * the sampler at bind point 1 (and no others) should be a shadow sampler.
+ *
+ * Bits in this mask corresponding to textures not used by the shader will
+ * be ignored.
+ *
+ * If this structure is not specified, no samplers will be considered to
+ * be shadow samplers.
+ */
+ uint32_t shadow_samplers;
+};
+
/**
* Data type of a shader varying, returned as part of struct
* vkd3d_shader_signature_element.
@@ -2805,6 +2865,7 @@ VKD3D_SHADER_API const enum vkd3d_shader_target_type *vkd3d_shader_get_supported
*
* Depending on the source and target types, this function may support the
* following chained structures:
+ * - vkd3d_shader_d3dbc_source_info
* - vkd3d_shader_descriptor_offset_info
* - vkd3d_shader_hlsl_source_info
* - vkd3d_shader_interface_info
diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c
index 6f8fbe84b90..4573cb67fb5 100644
--- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c
+++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c
@@ -145,11 +145,6 @@ static void shader_dump_global_flags(struct vkd3d_d3d_asm_compiler *compiler, en
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");
diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
index 2379efd3a02..b2d4ec23c6e 100644
--- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
+++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
@@ -248,6 +248,10 @@ struct vkd3d_shader_sm1_parser
struct vkd3d_shader_parser p;
struct vsir_program *program;
+ const struct vkd3d_shader_d3dbc_source_info *d3dbc_source_info;
+
+ uint16_t texture_descriptors;
+
struct
{
#define MAX_CONSTANT_COUNT 8192
@@ -938,6 +942,27 @@ static void shader_sm1_scan_register(struct vkd3d_shader_sm1_parser *sm1,
add_signature_element_from_register(sm1, reg, false, mask, 0);
}
+static void d3dbc_add_combined_sampler_descriptor(struct vkd3d_shader_sm1_parser *d3dbc,
+ unsigned int sampler_idx, enum vkd3d_shader_resource_type resource_type)
+{
+ struct vkd3d_shader_register_range range = {.first = sampler_idx, .last = sampler_idx};
+ const struct vkd3d_shader_d3dbc_source_info *source_info = d3dbc->d3dbc_source_info;
+ struct vsir_program *program = d3dbc->program;
+ struct vkd3d_shader_descriptor_info1 *d;
+
+ if (!vsir_program_add_descriptor(program, VKD3D_SHADER_DESCRIPTOR_TYPE_SRV,
+ sampler_idx, &range, resource_type, VSIR_DATA_F32))
+ vkd3d_shader_parser_error(&d3dbc->p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY,
+ "Failed to create SRV descriptor for combined sampler %u.", sampler_idx);
+
+ if (!(d = vsir_program_add_descriptor(program, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER,
+ sampler_idx, &range, VKD3D_SHADER_RESOURCE_NONE, VSIR_DATA_UNUSED)))
+ vkd3d_shader_parser_error(&d3dbc->p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY,
+ "Failed to create sampler descriptor for combined sampler %u.", sampler_idx);
+ else if (source_info && source_info->shadow_samplers & (1u << sampler_idx))
+ d->flags |= VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_SAMPLER_COMPARISON_MODE;
+}
+
/* Read a parameter token from the input stream, and possibly a relative
* addressing token. */
static void shader_sm1_read_param(struct vkd3d_shader_sm1_parser *sm1,
@@ -1102,6 +1127,11 @@ static void shader_sm1_read_semantic(struct vkd3d_shader_sm1_parser *sm1,
range->first = range->last = semantic->resource.reg.reg.idx[0].offset;
add_signature_element_from_semantic(sm1, semantic);
+ if (semantic->resource_type)
+ {
+ d3dbc_add_combined_sampler_descriptor(sm1, range->first, semantic->resource_type);
+ sm1->texture_descriptors |= (1u << range->first);
+ }
}
static void shader_sm1_read_immconst(struct vkd3d_shader_sm1_parser *sm1, const uint32_t **ptr,
@@ -1196,6 +1226,43 @@ static void shader_sm1_read_comment(struct vkd3d_shader_sm1_parser *sm1)
}
}
+static void d3dbc_update_descriptors(struct vkd3d_shader_sm1_parser *d3dbc,
+ const struct vkd3d_shader_instruction *ins)
+{
+ enum vkd3d_shader_resource_type type = VKD3D_SHADER_RESOURCE_TEXTURE_2D;
+ const struct vkd3d_shader_d3dbc_source_info *source_info;
+ unsigned int sampler_idx;
+
+ switch (ins->opcode)
+ {
+ case VSIR_OP_TEX:
+ case VSIR_OP_TEXBEM:
+ case VSIR_OP_TEXBEML:
+ case VSIR_OP_TEXDP3TEX:
+ case VSIR_OP_TEXLD:
+ case VSIR_OP_TEXM3x2TEX:
+ case VSIR_OP_TEXM3x3SPEC:
+ case VSIR_OP_TEXM3x3TEX:
+ case VSIR_OP_TEXM3x3VSPEC:
+ case VSIR_OP_TEXREG2AR:
+ case VSIR_OP_TEXREG2GB:
+ case VSIR_OP_TEXREG2RGB:
+ sampler_idx = ins->dst[0].reg.idx[0].offset;
+ if ((d3dbc->texture_descriptors & (1u << sampler_idx)))
+ break;
+
+ if ((source_info = d3dbc->d3dbc_source_info)
+ && sampler_idx < ARRAY_SIZE(source_info->texture_dimensions))
+ type = source_info->texture_dimensions[sampler_idx];
+ d3dbc_add_combined_sampler_descriptor(d3dbc, sampler_idx, type);
+ d3dbc->texture_descriptors |= (1u << sampler_idx);
+ break;
+
+ default:
+ break;
+ }
+}
+
static void shader_sm1_validate_instruction(struct vkd3d_shader_sm1_parser *sm1, struct vkd3d_shader_instruction *ins)
{
if ((ins->opcode == VSIR_OP_BREAKP || ins->opcode == VSIR_OP_IF) && ins->flags)
@@ -1360,6 +1427,9 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str
goto fail;
}
+ if (program->shader_version.major == 1)
+ d3dbc_update_descriptors(sm1, ins);
+
shader_sm1_validate_instruction(sm1, ins);
return;
@@ -1397,6 +1467,8 @@ static enum vkd3d_result shader_sm1_init(struct vkd3d_shader_sm1_parser *sm1, st
uint16_t shader_type;
size_t token_count;
+ sm1->d3dbc_source_info = vkd3d_find_struct(compile_info->next, D3DBC_SOURCE_INFO);
+
token_count = code_size / sizeof(*sm1->start);
if (token_count < 2)
@@ -1478,6 +1550,7 @@ int d3dbc_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t c
struct vkd3d_shader_message_context *message_context, struct vsir_program *program)
{
struct vkd3d_shader_sm1_parser sm1 = {0};
+ struct vkd3d_shader_descriptor_info1 *d;
struct vkd3d_shader_instruction *ins;
unsigned int i;
int ret;
@@ -1506,8 +1579,23 @@ int d3dbc_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t c
}
}
- for (i = 0; i < ARRAY_SIZE(program->flat_constant_count); ++i)
- program->flat_constant_count[i] = get_external_constant_count(&sm1, i);
+ for (i = 0; i < 3; ++i)
+ {
+ struct vkd3d_shader_register_range range = {.space = 0, .first = i, .last = i};
+ unsigned int size = get_external_constant_count(&sm1, i);
+
+ if (size)
+ {
+ if (!(d = vsir_program_add_descriptor(program, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV,
+ i, &range, VKD3D_SHADER_RESOURCE_BUFFER, VSIR_DATA_U32)))
+ vkd3d_shader_parser_error(&sm1.p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY,
+ "Failed to create CBV descriptor.");
+ else
+ d->buffer_size = size * 16;
+ }
+ }
+
+ program->has_descriptor_info = true;
if (ret >= 0 && sm1.p.status < 0)
ret = sm1.p.status;
diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c
index f82644d4679..c7af58118df 100644
--- a/libs/vkd3d/libs/vkd3d-shader/dxil.c
+++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c
@@ -2430,9 +2430,9 @@ static unsigned int sm6_parser_alloc_ssa_id(struct sm6_parser *sm6)
}
static void instruction_init_with_resource(struct vkd3d_shader_instruction *ins,
- enum vkd3d_shader_opcode handler_idx, const struct sm6_value *resource, struct sm6_parser *sm6)
+ enum vkd3d_shader_opcode opcode, const struct sm6_value *resource, struct sm6_parser *dxil)
{
- vsir_instruction_init(ins, &sm6->p.location, handler_idx);
+ vsir_instruction_init(ins, &dxil->p.location, opcode);
ins->resource_type = resource->u.handle.d->resource_type;
ins->raw = resource->u.handle.d->kind == RESOURCE_KIND_RAWBUFFER;
ins->structured = resource->u.handle.d->kind == RESOURCE_KIND_STRUCTUREDBUFFER;
@@ -4467,6 +4467,8 @@ static void sm6_parser_emit_atomicrmw(struct sm6_parser *sm6, const struct dxil_
/* 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);
+ else
+ WARN("Ignoring atomic ordering %"PRIu64".\n", code);
if ((code = record->operands[i]) != 1)
WARN("Ignoring synchronisation scope %"PRIu64".\n", code);
@@ -4484,7 +4486,7 @@ static void sm6_parser_emit_atomicrmw(struct sm6_parser *sm6, const struct dxil_
ins = state->ins;
vsir_instruction_init(ins, &sm6->p.location, op);
- ins->flags = is_volatile ? VKD3DARF_SEQ_CST | VKD3DARF_VOLATILE : VKD3DARF_SEQ_CST;
+ ins->flags = is_volatile ? VKD3DARF_VOLATILE : 0;
if (!(src_params = instruction_src_params_alloc(ins, 2, sm6)))
return;
@@ -4509,7 +4511,7 @@ static void sm6_parser_emit_atomicrmw(struct sm6_parser *sm6, const struct dxil_
}
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)
+ const struct sm6_type *type_b, struct sm6_parser *sm6, enum vkd3d_shader_opcode *aux_opcode)
{
bool is_int = sm6_type_is_bool_i16_i32_i64(type_a);
bool is_double = sm6_type_is_double(type_a);
@@ -4532,12 +4534,17 @@ static enum vkd3d_shader_opcode map_binary_op(uint64_t code, const struct sm6_ty
"Type mismatch in binary operation arguments.");
}
+ *aux_opcode = VSIR_OP_NOP;
+
switch (code)
{
case BINOP_ADD:
+ op = is_int ? VSIR_OP_IADD : (is_double ? VSIR_OP_DADD : VSIR_OP_ADD);
+ is_valid = !is_bool;
+ break;
case BINOP_SUB:
- /* NEG is applied later for subtraction. */
op = is_int ? VSIR_OP_IADD : (is_double ? VSIR_OP_DADD : VSIR_OP_ADD);
+ *aux_opcode = is_int ? VSIR_OP_INEG : VSIR_OP_NEG;
is_valid = !is_bool;
break;
case BINOP_AND:
@@ -4601,12 +4608,13 @@ static enum vkd3d_shader_opcode map_binary_op(uint64_t code, const struct sm6_ty
}
static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_record *record,
- struct vkd3d_shader_instruction *ins, struct sm6_value *dst)
+ struct sm6_block *code_block, struct vkd3d_shader_instruction *ins, struct sm6_value *dst)
{
+ enum vkd3d_shader_opcode opcode, aux_opcode;
struct vkd3d_shader_src_param *src_params;
- enum vkd3d_shader_opcode handler_idx;
+ struct vkd3d_shader_dst_param *dst_params;
+ uint32_t type_flags = 0, aux_id = 0;
const struct sm6_value *a, *b;
- uint32_t type_flags = 0;
uint64_t code, flags;
bool silence_warning;
unsigned int i = 0;
@@ -4622,15 +4630,34 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco
return;
code = record->operands[i++];
- if ((handler_idx = map_binary_op(code, a->type, b->type, sm6)) == VSIR_OP_INVALID)
+ if ((opcode = map_binary_op(code, a->type, b->type, sm6, &aux_opcode)) == VSIR_OP_INVALID)
return;
- vsir_instruction_init(ins, &sm6->p.location, handler_idx);
+ if (aux_opcode != VSIR_OP_NOP)
+ {
+ vsir_instruction_init(ins, &sm6->p.location, aux_opcode);
+
+ if (!(dst_params = instruction_dst_params_alloc(ins, 1, sm6))
+ || !(src_params = instruction_src_params_alloc(ins, 1, sm6)))
+ return;
+
+ aux_id = sm6_parser_alloc_ssa_id(sm6);
+
+ src_param_init_from_value(&src_params[0], b, DXIL_TYPE_SIGNED, sm6);
+
+ dst_param_init(&dst_params[0]);
+ register_init_with_id(&dst_params[0].reg, VKD3DSPR_SSA, src_params[0].reg.data_type, aux_id);
+
+ ++ins;
+ ++code_block->instruction_count;
+ }
+
+ vsir_instruction_init(ins, &sm6->p.location, opcode);
flags = (record->operand_count > i) ? record->operands[i] : 0;
silence_warning = false;
- switch (handler_idx)
+ switch (opcode)
{
case VSIR_OP_ADD:
case VSIR_OP_MUL:
@@ -4674,14 +4701,22 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco
if (!(src_params = instruction_src_params_alloc(ins, 2, sm6)))
return;
+
src_param_init_from_value(&src_params[0], a, type_flags, sm6);
- src_param_init_from_value(&src_params[1], b, type_flags, sm6);
- if (code == BINOP_SUB)
- src_params[1].modifiers = VKD3DSPSM_NEG;
+
+ if (aux_opcode == VSIR_OP_NOP)
+ {
+ src_param_init_from_value(&src_params[1], b, type_flags, sm6);
+ }
+ else
+ {
+ src_param_init(&src_params[1]);
+ register_init_with_id(&src_params[1].reg, VKD3DSPR_SSA, src_params[0].reg.data_type, aux_id);
+ }
dst->type = a->type;
- if (handler_idx == VSIR_OP_ISHL || handler_idx == VSIR_OP_ISHR || handler_idx == VSIR_OP_USHR)
+ if (opcode == VSIR_OP_ISHL || opcode == VSIR_OP_ISHR || opcode == VSIR_OP_USHR)
{
/* DXC emits AND instructions where necessary to mask shift counts.
* Shift binops do not imply masking the shift as the TPF equivalents
@@ -5041,18 +5076,18 @@ static void sm6_parser_emit_dx_atomic_binop(struct sm6_parser *sm6, enum dx_intr
unsigned int i, coord_idx, coord_count = 1;
struct vkd3d_shader_dst_param *dst_params;
struct vkd3d_shader_src_param *src_params;
- enum vkd3d_shader_opcode handler_idx;
struct vkd3d_shader_instruction *ins;
const struct sm6_value *resource;
struct vkd3d_shader_register reg;
+ enum vkd3d_shader_opcode opcode;
resource = operands[0];
if (!sm6_value_validate_is_handle(resource, sm6))
return;
if (is_cmp_xchg)
- handler_idx = VSIR_OP_IMM_ATOMIC_CMP_EXCH;
- else if ((handler_idx = map_dx_atomic_binop(operands[1], sm6)) == VSIR_OP_INVALID)
+ opcode = VSIR_OP_IMM_ATOMIC_CMP_EXCH;
+ else if ((opcode = map_dx_atomic_binop(operands[1], sm6)) == VSIR_OP_INVALID)
return;
coord_idx = 2 - is_cmp_xchg;
@@ -5074,13 +5109,13 @@ static void sm6_parser_emit_dx_atomic_binop(struct sm6_parser *sm6, enum dx_intr
{
WARN("Ignoring unexpected operand.\n");
vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_OPERANDS,
- "Ignoring an unexpected defined operand value for atomic instruction %u.", handler_idx);
+ "Ignoring an unexpected defined operand value for atomic instruction %u.", opcode);
break;
}
}
ins = state->ins;
- vsir_instruction_init(ins, &sm6->p.location, handler_idx);
+ vsir_instruction_init(ins, &sm6->p.location, opcode);
if (!(src_params = instruction_src_params_alloc(ins, 2 + is_cmp_xchg, sm6)))
return;
@@ -5223,16 +5258,16 @@ 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_opcode handler_idx,
+static void sm6_parser_dcl_register_builtin(struct sm6_parser *dxil, enum vkd3d_shader_opcode opcode,
enum vkd3d_shader_register_type reg_type, enum vsir_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->io_regs_declared, reg_type))
+ if (!bitmap_is_set(dxil->io_regs_declared, reg_type))
{
- bitmap_set(sm6->io_regs_declared, reg_type);
- if (!(ins = sm6_parser_add_instruction(sm6, handler_idx)))
+ bitmap_set(dxil->io_regs_declared, reg_type);
+ if (!(ins = sm6_parser_add_instruction(dxil, opcode)))
return;
dst_param = &ins->declaration.dst;
vsir_register_init(&dst_param->reg, reg_type, data_type, 0);
@@ -5394,21 +5429,21 @@ static void sm6_parser_emit_dx_dot(struct sm6_parser *sm6, enum dx_intrinsic_opc
struct vkd3d_shader_src_param *src_params;
struct vkd3d_shader_instruction *ins;
struct vkd3d_shader_register regs[2];
- enum vkd3d_shader_opcode handler_idx;
+ enum vkd3d_shader_opcode opcode;
unsigned int component_count;
switch (op)
{
case DX_DOT2:
- handler_idx = VSIR_OP_DP2;
+ opcode = VSIR_OP_DP2;
component_count = 2;
break;
case DX_DOT3:
- handler_idx = VSIR_OP_DP3;
+ opcode = VSIR_OP_DP3;
component_count = 3;
break;
case DX_DOT4:
- handler_idx = VSIR_OP_DP4;
+ opcode = VSIR_OP_DP4;
component_count = 4;
break;
default:
@@ -5421,7 +5456,7 @@ static void sm6_parser_emit_dx_dot(struct sm6_parser *sm6, enum dx_intrinsic_opc
return;
ins = state->ins;
- vsir_instruction_init(ins, &sm6->p.location, handler_idx);
+ vsir_instruction_init(ins, &sm6->p.location, opcode);
if (!(src_params = instruction_src_params_alloc(ins, 2, sm6)))
return;
src_param_init_vector_from_reg(&src_params[0], &regs[0]);
@@ -5483,11 +5518,10 @@ static void sm6_parser_emit_dx_fabs(struct sm6_parser *sm6, enum dx_intrinsic_op
struct vkd3d_shader_instruction *ins = state->ins;
struct vkd3d_shader_src_param *src_param;
- vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_MOV);
+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_ABS);
if (!(src_param = instruction_src_params_alloc(ins, 1, sm6)))
return;
src_param_init_from_value(src_param, operands[0], 0, sm6);
- src_param->modifiers = VKD3DSPSM_ABS;
instruction_dst_param_init_ssa_scalar(ins, 0, sm6);
}
@@ -7125,7 +7159,7 @@ static void sm6_parser_emit_cast(struct sm6_parser *dxil, const struct dxil_reco
struct sm6_cmp_info
{
- enum vkd3d_shader_opcode handler_idx;
+ enum vkd3d_shader_opcode opcode;
bool src_swap;
uint32_t type_flags;
};
@@ -7227,7 +7261,7 @@ static void sm6_parser_emit_cmp2(struct sm6_parser *sm6, const struct dxil_recor
"Type mismatch in comparison operation arguments.");
}
- if (!(cmp = sm6_map_cmp2_op(code)) || !cmp->handler_idx || cmp->handler_idx == VSIR_OP_INVALID)
+ if (!(cmp = sm6_map_cmp2_op(code)) || !cmp->opcode || cmp->opcode == VSIR_OP_INVALID)
{
FIXME("Unhandled operation %"PRIu64".\n", code);
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
@@ -7235,7 +7269,7 @@ static void sm6_parser_emit_cmp2(struct sm6_parser *sm6, const struct dxil_recor
return;
}
- vsir_instruction_init(ins, &sm6->p.location, cmp->handler_idx);
+ vsir_instruction_init(ins, &sm6->p.location, cmp->opcode);
flags = (record->operand_count > i) ? record->operands[i] : 0;
silence_warning = false;
@@ -7327,6 +7361,8 @@ static void sm6_parser_emit_cmpxchg(struct sm6_parser *sm6, const struct dxil_re
/* It's currently not possible to specify an atomic ordering in HLSL, and it defaults to seq_cst. */
if (success_ordering != ORDERING_SEQCST)
FIXME("Unhandled success ordering %"PRIu64".\n", success_ordering);
+ else
+ WARN("Ignoring success ordering %"PRIu64".\n", success_ordering);
if (success_ordering != failure_ordering)
FIXME("Unhandled failure ordering %"PRIu64".\n", failure_ordering);
@@ -7334,7 +7370,7 @@ static void sm6_parser_emit_cmpxchg(struct sm6_parser *sm6, const struct dxil_re
FIXME("Ignoring weak cmpxchg.\n");
vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_IMM_ATOMIC_CMP_EXCH);
- ins->flags = is_volatile ? VKD3DARF_SEQ_CST | VKD3DARF_VOLATILE : VKD3DARF_SEQ_CST;
+ ins->flags = is_volatile ? VKD3DARF_VOLATILE : 0;
if (!(src_params = instruction_src_params_alloc(ins, 3, sm6)))
return;
@@ -8342,7 +8378,7 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const
break;
}
case FUNC_CODE_INST_BINOP:
- sm6_parser_emit_binop(sm6, record, ins, dst);
+ sm6_parser_emit_binop(sm6, record, code_block, ins, dst);
break;
case FUNC_CODE_INST_BR:
sm6_parser_emit_br(sm6, record, function, code_block, ins);
@@ -10121,22 +10157,22 @@ static enum vkd3d_result sm6_parser_emit_thread_group(struct sm6_parser *sm6, co
return VKD3D_OK;
}
-static void sm6_parser_emit_dcl_count(struct sm6_parser *sm6, enum vkd3d_shader_opcode handler_idx, unsigned int count)
+static void sm6_parser_emit_dcl_count(struct sm6_parser *dxil, enum vkd3d_shader_opcode opcode, unsigned int count)
{
struct vkd3d_shader_instruction *ins;
- if (!(ins = sm6_parser_add_instruction(sm6, handler_idx)))
+ if (!(ins = sm6_parser_add_instruction(dxil, opcode)))
return;
ins->declaration.count = count;
}
-static void sm6_parser_emit_dcl_primitive_topology(struct sm6_parser *sm6,
- enum vkd3d_shader_opcode handler_idx, enum vkd3d_primitive_type primitive_type,
+static void sm6_parser_emit_dcl_primitive_topology(struct sm6_parser *dxil,
+ enum vkd3d_shader_opcode opcode, enum vkd3d_primitive_type primitive_type,
unsigned int patch_vertex_count)
{
struct vkd3d_shader_instruction *ins;
- if (!(ins = sm6_parser_add_instruction(sm6, handler_idx)))
+ if (!(ins = sm6_parser_add_instruction(dxil, opcode)))
return;
ins->declaration.primitive_type.type = primitive_type;
ins->declaration.primitive_type.patch_vertex_count = patch_vertex_count;
diff --git a/libs/vkd3d/libs/vkd3d-shader/glsl.c b/libs/vkd3d/libs/vkd3d-shader/glsl.c
index b2679beff9f..88c87ae33ee 100644
--- a/libs/vkd3d/libs/vkd3d-shader/glsl.c
+++ b/libs/vkd3d/libs/vkd3d-shader/glsl.c
@@ -280,7 +280,7 @@ static void shader_glsl_print_register_name(struct vkd3d_string_buffer *buffer,
break;
case VKD3DSPR_THREADID:
- vkd3d_string_buffer_printf(buffer, "gl_GlobalInvocationID");
+ vkd3d_string_buffer_printf(buffer, "uvec4(gl_GlobalInvocationID, 0)");
break;
case VKD3DSPR_IDXTEMP:
@@ -419,25 +419,11 @@ static void shader_glsl_print_src(struct vkd3d_string_buffer *buffer, struct vkd
if (reg->dimension == VSIR_DIMENSION_VEC4)
shader_glsl_print_swizzle(str, vsir_src->swizzle, mask);
- switch (vsir_src->modifiers)
+ if (vsir_src->modifiers)
{
- case VKD3DSPSM_NONE:
- break;
- case VKD3DSPSM_NEG:
- vkd3d_string_buffer_printf(buffer, "-%s", str->buffer);
- break;
- case VKD3DSPSM_ABS:
- vkd3d_string_buffer_printf(buffer, "abs(%s)", str->buffer);
- break;
- case VKD3DSPSM_ABSNEG:
- vkd3d_string_buffer_printf(buffer, "-abs(%s)", str->buffer);
- break;
- default:
- vkd3d_string_buffer_printf(buffer, "<unhandled modifier %#x>(%s)",
- vsir_src->modifiers, str->buffer);
- vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
- "Internal compiler error: Unhandled source modifier(s) %#x.", vsir_src->modifiers);
- break;
+ vkd3d_string_buffer_printf(buffer, "<unhandled modifier %#x>(%s)", vsir_src->modifiers, str->buffer);
+ vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
+ "Internal compiler error: Unhandled source modifier(s) %#x.", vsir_src->modifiers);
}
if (str != buffer)
@@ -1240,25 +1226,33 @@ static void shader_glsl_mov(struct vkd3d_glsl_generator *gen, const struct vkd3d
static void shader_glsl_movc(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins)
{
+ struct vkd3d_string_buffer *src1, *src2;
unsigned int component_count;
- struct glsl_src src[3];
+ struct glsl_src src[1];
struct glsl_dst dst;
uint32_t mask;
+ /* Sadly, mix() in unextended GLSL 4.40 can only select between
+ * floating-point sources. The earliest version able to select between
+ * integer sources is version 4.50; the same functionality is also
+ * provided by the EXT_shader_integer_mix extension. */
+
mask = glsl_dst_init(&dst, gen, ins, &ins->dst[0]);
glsl_src_init(&src[0], gen, &ins->src[0], mask);
- glsl_src_init(&src[1], gen, &ins->src[1], mask);
- glsl_src_init(&src[2], gen, &ins->src[2], mask);
+ src1 = vkd3d_string_buffer_get(&gen->string_buffers);
+ src2 = vkd3d_string_buffer_get(&gen->string_buffers);
+ shader_glsl_print_src(src1, gen, &ins->src[1], mask, VSIR_DATA_F32);
+ shader_glsl_print_src(src2, gen, &ins->src[2], mask, VSIR_DATA_F32);
if ((component_count = vsir_write_mask_component_count(mask)) > 1)
- shader_glsl_print_assignment(gen, &dst, "mix(%s, %s, bvec%u(%s))",
- src[2].str->buffer, src[1].str->buffer, component_count, src[0].str->buffer);
+ shader_glsl_print_assignment_ext(gen, &dst, VSIR_DATA_F32, "mix(%s, %s, bvec%u(%s))",
+ src2->buffer, src1->buffer, component_count, src[0].str->buffer);
else
- shader_glsl_print_assignment(gen, &dst, "mix(%s, %s, bool(%s))",
- src[2].str->buffer, src[1].str->buffer, src[0].str->buffer);
+ shader_glsl_print_assignment_ext(gen, &dst, VSIR_DATA_F32, "mix(%s, %s, bool(%s))",
+ src2->buffer, src1->buffer, src[0].str->buffer);
- glsl_src_cleanup(&src[2], &gen->string_buffers);
- glsl_src_cleanup(&src[1], &gen->string_buffers);
+ vkd3d_string_buffer_release(&gen->string_buffers, src2);
+ vkd3d_string_buffer_release(&gen->string_buffers, src1);
glsl_src_cleanup(&src[0], &gen->string_buffers);
glsl_dst_cleanup(&dst, &gen->string_buffers);
}
@@ -1485,6 +1479,9 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen,
switch (ins->opcode)
{
+ case VSIR_OP_ABS:
+ shader_glsl_intrinsic(gen, ins, "abs");
+ break;
case VSIR_OP_ADD:
case VSIR_OP_IADD:
shader_glsl_binop(gen, ins, "+");
@@ -1597,6 +1594,7 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen,
shader_glsl_relop(gen, ins, "!=", "notEqual");
break;
case VSIR_OP_INEG:
+ case VSIR_OP_NEG:
shader_glsl_unary_op(gen, ins, "-");
break;
case VSIR_OP_ISHL:
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c
index ec1e27d9496..3b0a7acb52a 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c
@@ -2205,11 +2205,11 @@ static struct hlsl_ir_node *hlsl_new_resource_store(struct hlsl_ctx *ctx,
return &store->node;
}
-void hlsl_block_add_resource_store(struct hlsl_ctx *ctx, struct hlsl_block *block,
+struct hlsl_ir_node *hlsl_block_add_resource_store(struct hlsl_ctx *ctx, struct hlsl_block *block,
enum hlsl_resource_store_type type, const struct hlsl_deref *resource, struct hlsl_ir_node *coords,
struct hlsl_ir_node *value, uint32_t writemask, const struct vkd3d_shader_location *loc)
{
- append_new_instr(ctx, block, hlsl_new_resource_store(ctx, type, resource, coords, value, writemask, loc));
+ return append_new_instr(ctx, block, hlsl_new_resource_store(ctx, type, resource, coords, value, writemask, loc));
}
struct hlsl_ir_node *hlsl_new_swizzle(struct hlsl_ctx *ctx, uint32_t s, unsigned int component_count,
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h
index 6c6243db799..829fcba0aab 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h
@@ -534,6 +534,8 @@ struct hlsl_ir_var
struct
{
bool used;
+ bool uav_read;
+ bool uav_atomics;
enum hlsl_sampler_dim sampler_dim;
struct vkd3d_shader_location first_sampler_dim_loc;
} *objects_usage[HLSL_REGSET_LAST_OBJECT + 1];
@@ -1599,7 +1601,7 @@ void hlsl_block_add_loop(struct hlsl_ctx *ctx, struct hlsl_block *block,
unsigned int unroll_limit, const struct vkd3d_shader_location *loc);
struct hlsl_ir_node *hlsl_block_add_resource_load(struct hlsl_ctx *ctx, struct hlsl_block *block,
const struct hlsl_resource_load_params *params, const struct vkd3d_shader_location *loc);
-void hlsl_block_add_resource_store(struct hlsl_ctx *ctx, struct hlsl_block *block,
+struct hlsl_ir_node *hlsl_block_add_resource_store(struct hlsl_ctx *ctx, struct hlsl_block *block,
enum hlsl_resource_store_type type, const struct hlsl_deref *resource, struct hlsl_ir_node *coords,
struct hlsl_ir_node *value, uint32_t writemask, const struct vkd3d_shader_location *loc);
struct hlsl_ir_node *hlsl_block_add_simple_load(struct hlsl_ctx *ctx, struct hlsl_block *block,
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.l b/libs/vkd3d/libs/vkd3d-shader/hlsl.l
index da9f0d39136..c41d807cca1 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.l
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.l
@@ -83,7 +83,6 @@ ComputeShader {return KW_COMPUTESHADER; }
compile {return KW_COMPILE; }
CompileShader {return KW_COMPILESHADER; }
const {return KW_CONST; }
-ConstructGSWithSO {return KW_CONSTRUCTGSWITHSO; }
continue {return KW_CONTINUE; }
DepthStencilState {return KW_DEPTHSTENCILSTATE; }
DepthStencilView {return KW_DEPTHSTENCILVIEW; }
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y
index 37b116bed40..27afac71320 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y
@@ -5337,6 +5337,23 @@ static bool intrinsic_AllMemoryBarrierWithGroupSync(struct hlsl_ctx *ctx,
| VKD3DSSF_GROUP_SHARED_MEMORY | VKD3DSSF_THREAD_GROUP, loc);
}
+static bool intrinsic_ConstructGSWithSO(struct hlsl_ctx *ctx,
+ const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
+{
+ struct hlsl_ir_node *compile;
+
+ if (params->args_count != 2 && params->args_count != 6)
+ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT,
+ "Wrong number of arguments to ConstructGSWithSO(): expected 2 or 6, but got %u.", params->args_count);
+
+ if (!(compile = hlsl_new_compile(ctx, HLSL_COMPILE_TYPE_CONSTRUCTGSWITHSO,
+ NULL, params->args, params->args_count, params->instrs, loc)))
+ return false;
+
+ hlsl_block_add_instr(params->instrs, compile);
+ return true;
+}
+
static bool intrinsic_DeviceMemoryBarrier(struct hlsl_ctx *ctx,
const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
{
@@ -5386,6 +5403,7 @@ intrinsic_functions[] =
/* Note: these entries should be kept in alphabetical order. */
{"AllMemoryBarrier", 0, true, intrinsic_AllMemoryBarrier},
{"AllMemoryBarrierWithGroupSync", 0, true, intrinsic_AllMemoryBarrierWithGroupSync},
+ {"ConstructGSWithSO", -1, false, intrinsic_ConstructGSWithSO},
{"D3DCOLORtoUBYTE4", 1, true, intrinsic_d3dcolor_to_ubyte4},
{"DeviceMemoryBarrier", 0, true, intrinsic_DeviceMemoryBarrier},
{"DeviceMemoryBarrierWithGroupSync", 0, true, intrinsic_DeviceMemoryBarrierWithGroupSync},
@@ -5629,36 +5647,6 @@ static struct hlsl_block *add_shader_compilation(struct hlsl_ctx *ctx, const cha
return make_block(ctx, compile);
}
-static struct hlsl_block *add_compile_variant(struct hlsl_ctx *ctx, enum hlsl_compile_type compile_type,
- struct parse_initializer *args, const struct vkd3d_shader_location *loc)
-{
- struct hlsl_ir_node *compile;
-
- switch (compile_type)
- {
- case HLSL_COMPILE_TYPE_COMPILE:
- vkd3d_unreachable();
-
- case HLSL_COMPILE_TYPE_CONSTRUCTGSWITHSO:
- if (args->args_count != 2 && args->args_count != 6)
- {
- hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT,
- "Wrong number of arguments to ConstructGSWithSO: expected 2 or 6, but got %u.",
- args->args_count);
- }
- break;
- }
-
- if (!(compile = hlsl_new_compile(ctx, compile_type, NULL, args->args, args->args_count, args->instrs, loc)))
- {
- free_parse_initializer(args);
- return NULL;
- }
-
- free_parse_initializer(args);
- return make_block(ctx, compile);
-}
-
static struct hlsl_block *add_constructor(struct hlsl_ctx *ctx, struct hlsl_type *type,
struct parse_initializer *params, const struct vkd3d_shader_location *loc)
{
@@ -6939,7 +6927,6 @@ static void validate_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim,
%token KW_COMPILESHADER
%token KW_COMPUTESHADER
%token KW_CONST
-%token KW_CONSTRUCTGSWITHSO
%token KW_CONTINUE
%token KW_DEFAULT
%token KW_DEPTHSTENCILSTATE
@@ -9453,11 +9440,6 @@ primary_expr:
vkd3d_free($3);
vkd3d_free($5);
}
- | KW_CONSTRUCTGSWITHSO '(' func_arguments ')'
- {
- if (!($$ = add_compile_variant(ctx, HLSL_COMPILE_TYPE_CONSTRUCTGSWITHSO, &$3, &@1)))
- YYABORT;
- }
| var_identifier '(' func_arguments ')'
{
if (!($$ = add_call(ctx, $1, &$3, &@1)))
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
index d22330cedb7..8f4e4cda73f 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
@@ -926,18 +926,17 @@ bool hlsl_transform_ir(struct hlsl_ctx *ctx, bool (*func)(struct hlsl_ctx *ctx,
return progress;
}
-typedef bool (*PFN_lower_func)(struct hlsl_ctx *, struct hlsl_ir_node *, struct hlsl_block *);
+typedef struct hlsl_ir_node *(*PFN_replace_func)(struct hlsl_ctx *, struct hlsl_ir_node *, struct hlsl_block *);
-static bool call_lower_func(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context)
+static bool call_replace_func(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context)
{
- PFN_lower_func func = context;
+ struct hlsl_ir_node *replacement;
+ PFN_replace_func func = context;
struct hlsl_block block;
hlsl_block_init(&block);
- if (func(ctx, instr, &block))
+ if ((replacement = func(ctx, instr, &block)))
{
- struct hlsl_ir_node *replacement = LIST_ENTRY(list_tail(&block.instrs), struct hlsl_ir_node, entry);
-
list_move_before(&instr->entry, &block.instrs);
hlsl_replace_node(instr, replacement);
return true;
@@ -949,12 +948,17 @@ static bool call_lower_func(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, vo
}
}
-/* Specific form of transform_ir() for passes which convert a single instruction
- * to a block of one or more instructions. This helper takes care of setting up
- * the block and calling hlsl_replace_node_with_block(). */
-static bool lower_ir(struct hlsl_ctx *ctx, PFN_lower_func func, struct hlsl_block *block)
+/* Specific form of transform_ir() for passes which replace a single instruction
+ * with another instruction. This includes passes which lower an instruction
+ * to one or more new instructions, and passes which fold away a redundant
+ * instruction.
+ *
+ * New instructions should be added to "block", and the replacement instruction
+ * should be returned. If the instruction should be left alone, NULL should be
+ * returned instead. */
+static bool replace_ir(struct hlsl_ctx *ctx, PFN_replace_func func, struct hlsl_block *block)
{
- return hlsl_transform_ir(ctx, call_lower_func, block, func);
+ return hlsl_transform_ir(ctx, call_replace_func, block, func);
}
static bool transform_instr_derefs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context)
@@ -1295,7 +1299,8 @@ static struct hlsl_ir_node *add_zero_mipmap_level(struct hlsl_ctx *ctx, struct h
return hlsl_block_add_simple_load(ctx, block, coords, loc);
}
-static bool lower_complex_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
+static struct hlsl_ir_node *lower_complex_casts(struct hlsl_ctx *ctx,
+ struct hlsl_ir_node *instr, struct hlsl_block *block)
{
unsigned int src_comp_count, dst_comp_count;
struct hlsl_type *src_type, *dst_type;
@@ -1306,17 +1311,17 @@ static bool lower_complex_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr
unsigned int dst_idx;
if (instr->type != HLSL_IR_EXPR)
- return false;
+ return NULL;
if (hlsl_ir_expr(instr)->op != HLSL_OP1_CAST)
- return false;
+ return NULL;
arg = hlsl_ir_expr(instr)->operands[0].node;
dst_type = instr->data_type;
src_type = arg->data_type;
if (src_type->class <= HLSL_CLASS_VECTOR && dst_type->class <= HLSL_CLASS_VECTOR)
- return false;
+ return NULL;
src_comp_count = hlsl_type_component_count(src_type);
dst_comp_count = hlsl_type_component_count(dst_type);
@@ -1332,7 +1337,7 @@ static bool lower_complex_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr
}
if (!(var = hlsl_new_synthetic_var(ctx, "cast", dst_type, &instr->loc)))
- return false;
+ return NULL;
hlsl_init_simple_deref_from_var(&var_deref, var);
for (dst_idx = 0; dst_idx < dst_comp_count; ++dst_idx)
@@ -1363,8 +1368,7 @@ static bool lower_complex_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr
hlsl_block_add_store_component(ctx, block, &var_deref, dst_idx, cast);
}
- hlsl_block_add_simple_load(ctx, block, var, &instr->loc);
- return true;
+ return hlsl_block_add_simple_load(ctx, block, var, &instr->loc);
}
/* hlsl_ir_swizzle nodes that directly point to a matrix value are only a parse-time construct that
@@ -1372,7 +1376,8 @@ static bool lower_complex_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr
* an assignment or as a value made from different components of the matrix. The former cases should
* have already been split into several separate assignments, but the latter are lowered by this
* pass. */
-static bool lower_matrix_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
+static struct hlsl_ir_node *lower_matrix_swizzles(struct hlsl_ctx *ctx,
+ struct hlsl_ir_node *instr, struct hlsl_block *block)
{
struct hlsl_ir_swizzle *swizzle;
struct hlsl_deref var_deref;
@@ -1381,14 +1386,14 @@ static bool lower_matrix_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins
unsigned int k, i;
if (instr->type != HLSL_IR_SWIZZLE)
- return false;
+ return NULL;
swizzle = hlsl_ir_swizzle(instr);
matrix_type = swizzle->val.node->data_type;
if (matrix_type->class != HLSL_CLASS_MATRIX)
- return false;
+ return NULL;
if (!(var = hlsl_new_synthetic_var(ctx, "matrix-swizzle", instr->data_type, &instr->loc)))
- return false;
+ return NULL;
hlsl_init_simple_deref_from_var(&var_deref, var);
for (i = 0; i < instr->data_type->e.numeric.dimx; ++i)
@@ -1401,8 +1406,7 @@ static bool lower_matrix_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins
hlsl_block_add_store_component(ctx, block, &var_deref, i, load);
}
- hlsl_block_add_simple_load(ctx, block, var, &instr->loc);
- return true;
+ return hlsl_block_add_simple_load(ctx, block, var, &instr->loc);
}
/* hlsl_ir_index nodes are a parse-time construct used to represent array indexing and struct
@@ -1411,7 +1415,8 @@ static bool lower_matrix_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins
* For the latter case, this pass takes care of lowering hlsl_ir_indexes into individual
* hlsl_ir_loads, or individual hlsl_ir_resource_loads, in case the indexing is a
* resource access. */
-static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
+static struct hlsl_ir_node *lower_index_loads(struct hlsl_ctx *ctx,
+ struct hlsl_ir_node *instr, struct hlsl_block *block)
{
struct hlsl_deref var_deref;
struct hlsl_ir_index *index;
@@ -1420,7 +1425,7 @@ static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr,
struct hlsl_ir_var *var;
if (instr->type != HLSL_IR_INDEX)
- return false;
+ return NULL;
index = hlsl_ir_index(instr);
val = index->val.node;
@@ -1435,14 +1440,13 @@ static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr,
VKD3D_ASSERT(coords->data_type->e.numeric.dimx == dim_count);
if (!(coords = add_zero_mipmap_level(ctx, block, coords, &instr->loc)))
- return false;
+ return NULL;
params.type = HLSL_RESOURCE_LOAD;
params.resource = val;
params.coords = coords;
params.format = val->data_type->e.resource.format;
- hlsl_block_add_resource_load(ctx, block, &params, &instr->loc);
- return true;
+ return hlsl_block_add_resource_load(ctx, block, &params, &instr->loc);
}
if (val->type == HLSL_IR_RESOURCE_LOAD)
@@ -1459,7 +1463,7 @@ static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr,
struct hlsl_deref row_deref;
if (!(var = hlsl_new_synthetic_var(ctx, "row", instr->data_type, &instr->loc)))
- return false;
+ return NULL;
hlsl_init_simple_deref_from_var(&row_deref, var);
for (unsigned int i = 0; i < mat->data_type->e.numeric.dimx; ++i)
@@ -1488,7 +1492,7 @@ static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr,
hlsl_block_add_store_component(ctx, block, &row_deref, i, &column_load->node);
}
- hlsl_block_add_simple_load(ctx, block, var, &instr->loc);
+ return hlsl_block_add_simple_load(ctx, block, var, &instr->loc);
}
else
{
@@ -1506,14 +1510,13 @@ static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr,
appended_load->node.data_type = type;
hlsl_block_add_instr(block, &appended_load->node);
+ return &appended_load->node;
}
-
- return true;
}
}
if (!(var = hlsl_new_synthetic_var(ctx, "index-val", val->data_type, &instr->loc)))
- return false;
+ return NULL;
hlsl_init_simple_deref_from_var(&var_deref, var);
hlsl_block_add_simple_store(ctx, block, var, val);
@@ -1527,7 +1530,7 @@ static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr,
VKD3D_ASSERT(!hlsl_type_is_row_major(mat->data_type));
if (!(var = hlsl_new_synthetic_var(ctx, "row", instr->data_type, &instr->loc)))
- return false;
+ return NULL;
hlsl_init_simple_deref_from_var(&row_deref, var);
for (i = 0; i < mat->data_type->e.numeric.dimx; ++i)
@@ -1537,37 +1540,34 @@ static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr,
c = hlsl_block_add_uint_constant(ctx, block, i, &instr->loc);
if (!(load = hlsl_new_load_index(ctx, &var_deref, c, &instr->loc)))
- return false;
+ return NULL;
hlsl_block_add_instr(block, &load->node);
if (!(load = hlsl_new_load_index(ctx, &load->src, index->idx.node, &instr->loc)))
- return false;
+ return NULL;
hlsl_block_add_instr(block, &load->node);
hlsl_block_add_store_index(ctx, block, &row_deref, c, &load->node, 0, &instr->loc);
}
- hlsl_block_add_simple_load(ctx, block, var, &instr->loc);
- }
- else
- {
- hlsl_block_add_load_index(ctx, block, &var_deref, index->idx.node, &instr->loc);
+ return hlsl_block_add_simple_load(ctx, block, var, &instr->loc);
}
- return true;
+
+ return hlsl_block_add_load_index(ctx, block, &var_deref, index->idx.node, &instr->loc);
}
/* Lower casts from vec1 to vecN to swizzles. */
-static bool lower_broadcasts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
+static struct hlsl_ir_node *lower_broadcasts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
{
const struct hlsl_type *src_type, *dst_type;
struct hlsl_type *dst_scalar_type;
struct hlsl_ir_expr *cast;
if (instr->type != HLSL_IR_EXPR)
- return false;
+ return NULL;
cast = hlsl_ir_expr(instr);
if (cast->op != HLSL_OP1_CAST)
- return false;
+ return NULL;
src_type = cast->operands[0].node->data_type;
dst_type = cast->node.data_type;
@@ -1581,17 +1581,17 @@ static bool lower_broadcasts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, s
new_cast = hlsl_block_add_cast(ctx, block, cast->operands[0].node, dst_scalar_type, &cast->node.loc);
if (dst_type->e.numeric.dimx != 1)
- hlsl_block_add_swizzle(ctx, block, HLSL_SWIZZLE(X, X, X, X),
+ return hlsl_block_add_swizzle(ctx, block, HLSL_SWIZZLE(X, X, X, X),
dst_type->e.numeric.dimx, new_cast, &cast->node.loc);
- return true;
+ return new_cast;
}
- return false;
+ return NULL;
}
/* Lowers loads from TGSMs to resource loads. */
-static bool lower_tgsm_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
+static struct hlsl_ir_node *lower_tgsm_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
{
struct hlsl_resource_load_params params = {.type = HLSL_RESOURCE_LOAD};
const struct vkd3d_shader_location *loc = &instr->loc;
@@ -1599,29 +1599,28 @@ static bool lower_tgsm_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, s
struct hlsl_deref *deref;
if (instr->type != HLSL_IR_LOAD || !hlsl_is_numeric_type(instr->data_type))
- return false;
+ return NULL;
load = hlsl_ir_load(instr);
deref = &load->src;
if (!deref->var->is_tgsm)
- return false;
+ return NULL;
if (deref->path_len)
{
hlsl_fixme(ctx, &instr->loc, "Load from indexed TGSM.");
- return false;
+ return NULL;
}
params.resource = hlsl_block_add_simple_load(ctx, block, deref->var, loc);
params.format = instr->data_type;
params.coords = hlsl_block_add_uint_constant(ctx, block, 0, &instr->loc);
- hlsl_block_add_resource_load(ctx, block, &params, loc);
-
- return true;
+ return hlsl_block_add_resource_load(ctx, block, &params, loc);
}
/* Lowers stores to TGSMs to resource stores. */
-static bool lower_tgsm_stores(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
+static struct hlsl_ir_node *lower_tgsm_stores(struct hlsl_ctx *ctx,
+ struct hlsl_ir_node *instr, struct hlsl_block *block)
{
struct hlsl_ir_store *store;
struct hlsl_ir_node *coords;
@@ -1629,26 +1628,24 @@ static bool lower_tgsm_stores(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr,
struct hlsl_deref *deref;
if (instr->type != HLSL_IR_STORE)
- return false;
+ return NULL;
store = hlsl_ir_store(instr);
deref = &store->lhs;
if (!deref->var->is_tgsm)
- return false;
+ return NULL;
if (deref->path_len)
{
hlsl_fixme(ctx, &instr->loc, "Store to indexed TGSM.");
- return false;
+ return NULL;
}
hlsl_init_simple_deref_from_var(&res_deref, deref->var);
coords = hlsl_block_add_uint_constant(ctx, block, 0, &instr->loc);
- hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STORE, &res_deref,
+ return hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STORE, &res_deref,
coords, store->rhs.node, store->writemask, &instr->loc);
-
- return true;
}
/* Allocate a unique, ordered index to each instruction, which will be used for
@@ -3567,7 +3564,8 @@ static bool validate_dereferences(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins
return false;
}
-static bool fold_redundant_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context)
+static struct hlsl_ir_node *fold_redundant_casts(struct hlsl_ctx *ctx,
+ struct hlsl_ir_node *instr, struct hlsl_block *block)
{
if (instr->type == HLSL_IR_EXPR)
{
@@ -3576,20 +3574,17 @@ static bool fold_redundant_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst
const struct hlsl_type *src_type;
if (expr->op != HLSL_OP1_CAST)
- return false;
+ return NULL;
src_type = expr->operands[0].node->data_type;
if (hlsl_types_are_equal(src_type, dst_type)
|| (src_type->e.numeric.type == dst_type->e.numeric.type
&& hlsl_is_vec1(src_type) && hlsl_is_vec1(dst_type)))
- {
- hlsl_replace_node(&expr->node, expr->operands[0].node);
- return true;
- }
+ return expr->operands[0].node;
}
- return false;
+ return NULL;
}
/* Copy an element of a complex variable. Helper for
@@ -3824,17 +3819,18 @@ static bool split_matrix_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr
return true;
}
-static bool lower_narrowing_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
+static struct hlsl_ir_node *lower_narrowing_casts(struct hlsl_ctx *ctx,
+ struct hlsl_ir_node *instr, struct hlsl_block *block)
{
const struct hlsl_type *src_type, *dst_type;
struct hlsl_type *dst_vector_type;
struct hlsl_ir_expr *cast;
if (instr->type != HLSL_IR_EXPR)
- return false;
+ return NULL;
cast = hlsl_ir_expr(instr);
if (cast->op != HLSL_OP1_CAST)
- return false;
+ return NULL;
src_type = cast->operands[0].node->data_type;
dst_type = cast->node.data_type;
@@ -3847,65 +3843,58 @@ static bool lower_narrowing_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins
/* We need to preserve the cast since it might be doing more than just
* narrowing the vector. */
new_cast = hlsl_block_add_cast(ctx, block, cast->operands[0].node, dst_vector_type, &cast->node.loc);
- hlsl_block_add_swizzle(ctx, block, HLSL_SWIZZLE(X, Y, Z, W),
+ return hlsl_block_add_swizzle(ctx, block, HLSL_SWIZZLE(X, Y, Z, W),
dst_type->e.numeric.dimx, new_cast, &cast->node.loc);
- return true;
}
- return false;
+ return NULL;
}
-static bool fold_swizzle_chains(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context)
+static struct hlsl_ir_node *fold_swizzle_chains(struct hlsl_ctx *ctx,
+ struct hlsl_ir_node *instr, struct hlsl_block *block)
{
struct hlsl_ir_swizzle *swizzle;
struct hlsl_ir_node *next_instr;
if (instr->type != HLSL_IR_SWIZZLE)
- return false;
+ return NULL;
swizzle = hlsl_ir_swizzle(instr);
next_instr = swizzle->val.node;
if (next_instr->type == HLSL_IR_SWIZZLE)
{
- struct hlsl_ir_node *new_swizzle;
uint32_t combined_swizzle;
combined_swizzle = hlsl_combine_swizzles(hlsl_ir_swizzle(next_instr)->u.vector,
swizzle->u.vector, instr->data_type->e.numeric.dimx);
next_instr = hlsl_ir_swizzle(next_instr)->val.node;
- if (!(new_swizzle = hlsl_new_swizzle(ctx, combined_swizzle,
- instr->data_type->e.numeric.dimx, next_instr, &instr->loc)))
- return false;
-
- list_add_before(&instr->entry, &new_swizzle->entry);
- hlsl_replace_node(instr, new_swizzle);
- return true;
+ return hlsl_block_add_swizzle(ctx, block, combined_swizzle,
+ instr->data_type->e.numeric.dimx, next_instr, &instr->loc);
}
- return false;
+ return NULL;
}
-static bool remove_trivial_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context)
+static struct hlsl_ir_node *fold_trivial_swizzles(struct hlsl_ctx *ctx,
+ struct hlsl_ir_node *instr, struct hlsl_block *block)
{
struct hlsl_ir_swizzle *swizzle;
unsigned int i;
if (instr->type != HLSL_IR_SWIZZLE)
- return false;
+ return NULL;
swizzle = hlsl_ir_swizzle(instr);
if (instr->data_type->e.numeric.dimx != swizzle->val.node->data_type->e.numeric.dimx)
- return false;
+ return NULL;
for (i = 0; i < instr->data_type->e.numeric.dimx; ++i)
if (hlsl_swizzle_get_component(swizzle->u.vector, i) != i)
- return false;
-
- hlsl_replace_node(instr, swizzle->val.node);
+ return NULL;
- return true;
+ return swizzle->val.node;
}
static bool remove_trivial_conditional_branches(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context)
@@ -4028,7 +4017,8 @@ static bool normalize_switch_cases(struct hlsl_ctx *ctx, struct hlsl_ir_node *in
return true;
}
-static bool lower_nonconstant_vector_derefs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
+static struct hlsl_ir_node *lower_nonconstant_vector_derefs(struct hlsl_ctx *ctx,
+ struct hlsl_ir_node *instr, struct hlsl_block *block)
{
struct hlsl_ir_node *idx;
struct hlsl_deref *deref;
@@ -4036,13 +4026,13 @@ static bool lower_nonconstant_vector_derefs(struct hlsl_ctx *ctx, struct hlsl_ir
unsigned int i;
if (instr->type != HLSL_IR_LOAD)
- return false;
+ return NULL;
deref = &hlsl_ir_load(instr)->src;
VKD3D_ASSERT(deref->var);
if (deref->path_len == 0)
- return false;
+ return NULL;
type = deref->var->data_type;
for (i = 0; i < deref->path_len - 1; ++i)
@@ -4059,7 +4049,7 @@ static bool lower_nonconstant_vector_derefs(struct hlsl_ctx *ctx, struct hlsl_ir
enum hlsl_ir_expr_op op;
if (!(vector_load = hlsl_new_load_parent(ctx, deref, &instr->loc)))
- return false;
+ return NULL;
hlsl_block_add_instr(block, &vector_load->node);
swizzle = hlsl_block_add_swizzle(ctx, block, HLSL_SWIZZLE(X, X, X, X), width, idx, &instr->loc);
@@ -4069,7 +4059,7 @@ static bool lower_nonconstant_vector_derefs(struct hlsl_ctx *ctx, struct hlsl_ir
value.u[2].u = 2;
value.u[3].u = 3;
if (!(c = hlsl_new_constant(ctx, hlsl_get_vector_type(ctx, HLSL_TYPE_UINT, width), &value, &instr->loc)))
- return false;
+ return NULL;
hlsl_block_add_instr(block, c);
operands[0] = swizzle;
@@ -4086,14 +4076,14 @@ static bool lower_nonconstant_vector_derefs(struct hlsl_ctx *ctx, struct hlsl_ir
* LOGIC_OR + LOGIC_AND. */
operands[0] = &vector_load->node;
operands[1] = eq;
- hlsl_block_add_expr(ctx, block, op, operands, instr->data_type, &instr->loc);
- return true;
+ return hlsl_block_add_expr(ctx, block, op, operands, instr->data_type, &instr->loc);
}
- return false;
+ return NULL;
}
-static bool validate_nonconstant_vector_store_derefs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
+static struct hlsl_ir_node *validate_nonconstant_vector_store_derefs(struct hlsl_ctx *ctx,
+ struct hlsl_ir_node *instr, struct hlsl_block *block)
{
struct hlsl_ir_node *idx;
struct hlsl_deref *deref;
@@ -4101,13 +4091,13 @@ static bool validate_nonconstant_vector_store_derefs(struct hlsl_ctx *ctx, struc
unsigned int i;
if (instr->type != HLSL_IR_STORE)
- return false;
+ return NULL;
deref = &hlsl_ir_store(instr)->lhs;
VKD3D_ASSERT(deref->var);
if (deref->path_len == 0)
- return false;
+ return NULL;
type = deref->var->data_type;
for (i = 0; i < deref->path_len - 1; ++i)
@@ -4122,7 +4112,7 @@ static bool validate_nonconstant_vector_store_derefs(struct hlsl_ctx *ctx, struc
hlsl_fixme(ctx, &instr->loc, "Non-constant vector addressing on store. Unrolling may be missing.");
}
- return false;
+ return NULL;
}
static bool deref_supports_sm1_indirect_addressing(struct hlsl_ctx *ctx, const struct hlsl_deref *deref)
@@ -4136,8 +4126,8 @@ static bool deref_supports_sm1_indirect_addressing(struct hlsl_ctx *ctx, const s
* This is achieved through a synthetic variable. The non-constant index is compared for equality
* with every possible value it can have within the array bounds, and the ternary operator is used
* to update the value of the synthetic var when the equality check passes. */
-static bool lower_nonconstant_array_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr,
- struct hlsl_block *block)
+static struct hlsl_ir_node *lower_nonconstant_array_loads(struct hlsl_ctx *ctx,
+ struct hlsl_ir_node *instr, struct hlsl_block *block)
{
struct hlsl_constant_value zero_value = {0};
struct hlsl_ir_node *cut_index, *zero;
@@ -4149,15 +4139,15 @@ static bool lower_nonconstant_array_loads(struct hlsl_ctx *ctx, struct hlsl_ir_n
bool row_major;
if (instr->type != HLSL_IR_LOAD)
- return false;
+ return NULL;
load = hlsl_ir_load(instr);
deref = &load->src;
if (deref->path_len == 0)
- return false;
+ return NULL;
if (deref_supports_sm1_indirect_addressing(ctx, deref))
- return false;
+ return NULL;
for (i = deref->path_len - 1; ; --i)
{
@@ -4168,7 +4158,7 @@ static bool lower_nonconstant_array_loads(struct hlsl_ctx *ctx, struct hlsl_ir_n
}
if (i == 0)
- return false;
+ return NULL;
}
cut_index = deref->path[i_cut].node;
@@ -4180,10 +4170,10 @@ static bool lower_nonconstant_array_loads(struct hlsl_ctx *ctx, struct hlsl_ir_n
VKD3D_ASSERT(cut_type->class == HLSL_CLASS_ARRAY || row_major);
if (!(var = hlsl_new_synthetic_var(ctx, row_major ? "row_major-load" : "array-load", instr->data_type, &instr->loc)))
- return false;
+ return NULL;
if (!(zero = hlsl_new_constant(ctx, instr->data_type, &zero_value, &instr->loc)))
- return false;
+ return NULL;
hlsl_block_add_instr(block, zero);
hlsl_block_add_simple_store(ctx, block, var, zero);
@@ -4209,7 +4199,7 @@ static bool lower_nonconstant_array_loads(struct hlsl_ctx *ctx, struct hlsl_ir_n
var_load = hlsl_block_add_simple_load(ctx, block, var, &cut_index->loc);
if (!hlsl_copy_deref(ctx, &deref_copy, deref))
- return false;
+ return NULL;
hlsl_src_remove(&deref_copy.path[i_cut]);
hlsl_src_from_node(&deref_copy.path[i_cut], const_i);
specific_load = hlsl_block_add_load_index(ctx, block, &deref_copy, NULL, &cut_index->loc);
@@ -4223,8 +4213,7 @@ static bool lower_nonconstant_array_loads(struct hlsl_ctx *ctx, struct hlsl_ir_n
hlsl_block_add_simple_store(ctx, block, var, ternary);
}
- hlsl_block_add_simple_load(ctx, block, var, &instr->loc);
- return true;
+ return hlsl_block_add_simple_load(ctx, block, var, &instr->loc);
}
static struct hlsl_type *clone_texture_array_as_combined_sampler_array(struct hlsl_ctx *ctx, struct hlsl_type *type)
@@ -4495,31 +4484,30 @@ static bool sort_synthetic_separated_samplers_first(struct hlsl_ctx *ctx)
}
/* Turn CAST to int or uint into TRUNC + REINTERPRET */
-static bool lower_casts_to_int(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
+static struct hlsl_ir_node *lower_casts_to_int(struct hlsl_ctx *ctx,
+ struct hlsl_ir_node *instr, struct hlsl_block *block)
{
struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = { 0 };
struct hlsl_ir_node *arg, *trunc;
struct hlsl_ir_expr *expr;
if (instr->type != HLSL_IR_EXPR)
- return false;
+ return NULL;
expr = hlsl_ir_expr(instr);
if (expr->op != HLSL_OP1_CAST)
- return false;
+ return NULL;
arg = expr->operands[0].node;
if (!hlsl_type_is_integer(instr->data_type) || instr->data_type->e.numeric.type == HLSL_TYPE_BOOL)
- return false;
+ return NULL;
if (!hlsl_type_is_floating_point(arg->data_type))
- return false;
+ return NULL;
trunc = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_TRUNC, arg, &instr->loc);
memset(operands, 0, sizeof(operands));
operands[0] = trunc;
- hlsl_block_add_expr(ctx, block, HLSL_OP1_REINTERPRET, operands, instr->data_type, &instr->loc);
-
- return true;
+ return hlsl_block_add_expr(ctx, block, HLSL_OP1_REINTERPRET, operands, instr->data_type, &instr->loc);
}
/* Turn TRUNC into:
@@ -4533,16 +4521,16 @@ static bool lower_casts_to_int(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr,
* where the comparisons in the extra term are performed using CMP or SLT
* depending on whether this is a pixel or vertex shader, respectively.
*/
-static bool lower_trunc(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
+static struct hlsl_ir_node *lower_trunc(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
{
struct hlsl_ir_node *arg, *res;
struct hlsl_ir_expr *expr;
if (instr->type != HLSL_IR_EXPR)
- return false;
+ return NULL;
expr = hlsl_ir_expr(instr);
if (expr->op != HLSL_OP1_TRUNC)
- return false;
+ return NULL;
arg = expr->operands[0].node;
@@ -4553,7 +4541,7 @@ static bool lower_trunc(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct
memset(&zero_value, 0, sizeof(zero_value));
if (!(zero = hlsl_new_constant(ctx, arg->data_type, &zero_value, &instr->loc)))
- return false;
+ return NULL;
hlsl_block_add_instr(block, zero);
one_value.u[0].f = 1.0;
@@ -4561,22 +4549,22 @@ static bool lower_trunc(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct
one_value.u[2].f = 1.0;
one_value.u[3].f = 1.0;
if (!(one = hlsl_new_constant(ctx, arg->data_type, &one_value, &instr->loc)))
- return false;
+ return NULL;
hlsl_block_add_instr(block, one);
fract = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_FRACT, arg, &instr->loc);
neg_fract = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, fract, &instr->loc);
if (!(has_fract = hlsl_new_ternary_expr(ctx, HLSL_OP3_CMP, neg_fract, zero, one)))
- return false;
+ return NULL;
hlsl_block_add_instr(block, has_fract);
if (!(extra = hlsl_new_ternary_expr(ctx, HLSL_OP3_CMP, arg, zero, has_fract)))
- return false;
+ return NULL;
hlsl_block_add_instr(block, extra);
floor = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, arg, neg_fract);
- res = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, floor, extra);
+ return hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, floor, extra);
}
else
{
@@ -4590,11 +4578,10 @@ static bool lower_trunc(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct
floor = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, arg, neg_fract);
if (!(res = hlsl_new_ternary_expr(ctx, HLSL_OP3_MAD, is_neg, has_fract, floor)))
- return false;
+ return NULL;
hlsl_block_add_instr(block, res);
+ return res;
}
-
- return true;
}
/* Lower modulus using:
@@ -4602,7 +4589,8 @@ static bool lower_trunc(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct
* mod(x, y) = x - trunc(x / y) * y;
*
*/
-static bool lower_int_modulus_sm1(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
+static struct hlsl_ir_node *lower_int_modulus_sm1(struct hlsl_ctx *ctx,
+ struct hlsl_ir_node *instr, struct hlsl_block *block)
{
struct hlsl_ir_node *div, *trunc, *mul, *neg, *operands[2], *ret;
struct hlsl_type *float_type;
@@ -4610,15 +4598,15 @@ static bool lower_int_modulus_sm1(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins
bool is_float;
if (instr->type != HLSL_IR_EXPR)
- return false;
+ return NULL;
expr = hlsl_ir_expr(instr);
if (expr->op != HLSL_OP2_MOD)
- return false;
+ return NULL;
is_float = instr->data_type->e.numeric.type == HLSL_TYPE_FLOAT
|| instr->data_type->e.numeric.type == HLSL_TYPE_HALF;
if (is_float)
- return false;
+ return NULL;
float_type = hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, instr->data_type->e.numeric.dimx);
for (unsigned int i = 0; i < 2; ++i)
@@ -4631,13 +4619,11 @@ static bool lower_int_modulus_sm1(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins
mul = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, trunc, operands[1]);
neg = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, mul, &instr->loc);
ret = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, operands[0], neg);
- hlsl_block_add_cast(ctx, block, ret, instr->data_type, &instr->loc);
-
- return true;
+ return hlsl_block_add_cast(ctx, block, ret, instr->data_type, &instr->loc);
}
/* Lower DIV to RCP + MUL. */
-static bool lower_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
+static struct hlsl_ir_node *lower_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
{
struct hlsl_ir_node *rcp, *ret, *operands[2];
struct hlsl_type *float_type;
@@ -4645,10 +4631,10 @@ static bool lower_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, str
bool is_float;
if (instr->type != HLSL_IR_EXPR)
- return false;
+ return NULL;
expr = hlsl_ir_expr(instr);
if (expr->op != HLSL_OP2_DIV)
- return false;
+ return NULL;
is_float = instr->data_type->e.numeric.type == HLSL_TYPE_FLOAT
|| instr->data_type->e.numeric.type == HLSL_TYPE_HALF;
@@ -4665,42 +4651,40 @@ static bool lower_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, str
ret = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, operands[0], rcp);
if (!is_float)
ret = hlsl_block_add_cast(ctx, block, ret, instr->data_type, &instr->loc);
-
- return true;
+ return ret;
}
/* Lower SQRT to RSQ + RCP. */
-static bool lower_sqrt(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
+static struct hlsl_ir_node *lower_sqrt(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
{
struct hlsl_ir_expr *expr;
struct hlsl_ir_node *rsq;
if (instr->type != HLSL_IR_EXPR)
- return false;
+ return NULL;
expr = hlsl_ir_expr(instr);
if (expr->op != HLSL_OP1_SQRT)
- return false;
+ return NULL;
rsq = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_RSQ, expr->operands[0].node, &instr->loc);
- hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_RCP, rsq, &instr->loc);
- return true;
+ return hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_RCP, rsq, &instr->loc);
}
/* Lower DP2 to MUL + ADD */
-static bool lower_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
+static struct hlsl_ir_node *lower_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
{
struct hlsl_ir_node *arg1, *arg2, *mul, *add_x, *add_y;
struct hlsl_ir_expr *expr;
if (instr->type != HLSL_IR_EXPR)
- return false;
+ return NULL;
expr = hlsl_ir_expr(instr);
arg1 = expr->operands[0].node;
arg2 = expr->operands[1].node;
if (expr->op != HLSL_OP2_DOT)
- return false;
+ return NULL;
if (arg1->data_type->e.numeric.dimx != 2)
- return false;
+ return NULL;
if (ctx->profile->type == VKD3D_SHADER_TYPE_PIXEL)
{
@@ -4710,7 +4694,7 @@ static bool lower_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct h
operands[1] = arg2;
operands[2] = hlsl_block_add_float_constant(ctx, block, 0.0f, &expr->node.loc);
- hlsl_block_add_expr(ctx, block, HLSL_OP3_DP2ADD, operands, instr->data_type, &expr->node.loc);
+ return hlsl_block_add_expr(ctx, block, HLSL_OP3_DP2ADD, operands, instr->data_type, &expr->node.loc);
}
else
{
@@ -4720,32 +4704,29 @@ static bool lower_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct h
instr->data_type->e.numeric.dimx, mul, &expr->node.loc);
add_y = hlsl_block_add_swizzle(ctx, block, HLSL_SWIZZLE(Y, Y, Y, Y),
instr->data_type->e.numeric.dimx, mul, &expr->node.loc);
- hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, add_x, add_y);
+ return hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, add_x, add_y);
}
-
- return true;
}
/* Lower ABS to MAX */
-static bool lower_abs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
+static struct hlsl_ir_node *lower_abs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
{
struct hlsl_ir_node *arg, *neg;
struct hlsl_ir_expr *expr;
if (instr->type != HLSL_IR_EXPR)
- return false;
+ return NULL;
expr = hlsl_ir_expr(instr);
arg = expr->operands[0].node;
if (expr->op != HLSL_OP1_ABS)
- return false;
+ return NULL;
neg = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, arg, &instr->loc);
- hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MAX, neg, arg);
- return true;
+ return hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MAX, neg, arg);
}
/* Lower ROUND using FRC, ROUND(x) -> ((x + 0.5) - FRC(x + 0.5)). */
-static bool lower_round(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
+static struct hlsl_ir_node *lower_round(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
{
struct hlsl_ir_node *arg, *neg, *sum, *frc, *half;
struct hlsl_type *type = instr->data_type;
@@ -4754,69 +4735,66 @@ static bool lower_round(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct
struct hlsl_ir_expr *expr;
if (instr->type != HLSL_IR_EXPR)
- return false;
+ return NULL;
expr = hlsl_ir_expr(instr);
arg = expr->operands[0].node;
if (expr->op != HLSL_OP1_ROUND)
- return false;
+ return NULL;
component_count = hlsl_type_component_count(type);
for (i = 0; i < component_count; ++i)
half_value.u[i].f = 0.5f;
if (!(half = hlsl_new_constant(ctx, type, &half_value, &expr->node.loc)))
- return false;
+ return NULL;
hlsl_block_add_instr(block, half);
sum = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, arg, half);
frc = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_FRACT, sum, &instr->loc);
neg = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, frc, &instr->loc);
- hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, sum, neg);
- return true;
+ return hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, sum, neg);
}
/* Lower CEIL to FRC */
-static bool lower_ceil(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
+static struct hlsl_ir_node *lower_ceil(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
{
struct hlsl_ir_node *arg, *neg, *frc;
struct hlsl_ir_expr *expr;
if (instr->type != HLSL_IR_EXPR)
- return false;
+ return NULL;
expr = hlsl_ir_expr(instr);
arg = expr->operands[0].node;
if (expr->op != HLSL_OP1_CEIL)
- return false;
+ return NULL;
neg = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, arg, &instr->loc);
frc = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_FRACT, neg, &instr->loc);
- hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, frc, arg);
- return true;
+ return hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, frc, arg);
}
/* Lower FLOOR to FRC */
-static bool lower_floor(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
+static struct hlsl_ir_node *lower_floor(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
{
struct hlsl_ir_node *arg, *neg, *frc;
struct hlsl_ir_expr *expr;
if (instr->type != HLSL_IR_EXPR)
- return false;
+ return NULL;
expr = hlsl_ir_expr(instr);
arg = expr->operands[0].node;
if (expr->op != HLSL_OP1_FLOOR)
- return false;
+ return NULL;
frc = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_FRACT, arg, &instr->loc);
neg = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, frc, &instr->loc);
- hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, neg, arg);
- return true;
+ return hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, neg, arg);
}
/* Lower SIN/COS to SINCOS for SM1. */
-static bool lower_trig(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
+static struct hlsl_ir_node *lower_trig(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
{
struct hlsl_ir_node *arg, *half, *two_pi, *reciprocal_two_pi, *neg_pi;
struct hlsl_constant_value half_value, two_pi_value, reciprocal_two_pi_value, neg_pi_value;
@@ -4828,7 +4806,7 @@ static bool lower_trig(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct
int i;
if (instr->type != HLSL_IR_EXPR)
- return false;
+ return NULL;
expr = hlsl_ir_expr(instr);
if (expr->op == HLSL_OP1_SIN)
@@ -4836,7 +4814,7 @@ static bool lower_trig(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct
else if (expr->op == HLSL_OP1_COS)
op = HLSL_OP1_COS_REDUCED;
else
- return false;
+ return NULL;
arg = expr->operands[0].node;
type = arg->data_type;
@@ -4854,23 +4832,23 @@ static bool lower_trig(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct
|| !(two_pi = hlsl_new_constant(ctx, type, &two_pi_value, &instr->loc))
|| !(reciprocal_two_pi = hlsl_new_constant(ctx, type, &reciprocal_two_pi_value, &instr->loc))
|| !(neg_pi = hlsl_new_constant(ctx, type, &neg_pi_value, &instr->loc)))
- return false;
+ return NULL;
hlsl_block_add_instr(block, half);
hlsl_block_add_instr(block, two_pi);
hlsl_block_add_instr(block, reciprocal_two_pi);
hlsl_block_add_instr(block, neg_pi);
if (!(mad = hlsl_new_ternary_expr(ctx, HLSL_OP3_MAD, arg, reciprocal_two_pi, half)))
- return false;
+ return NULL;
hlsl_block_add_instr(block, mad);
frc = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_FRACT, mad, &instr->loc);
if (!(reduced = hlsl_new_ternary_expr(ctx, HLSL_OP3_MAD, frc, two_pi, neg_pi)))
- return false;
+ return NULL;
hlsl_block_add_instr(block, reduced);
if (type->e.numeric.dimx == 1)
{
- sincos = hlsl_block_add_unary_expr(ctx, block, op, reduced, &instr->loc);
+ return hlsl_block_add_unary_expr(ctx, block, op, reduced, &instr->loc);
}
else
{
@@ -4886,7 +4864,7 @@ static bool lower_trig(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct
}
if (!(var = hlsl_new_synthetic_var(ctx, "sincos", type, &instr->loc)))
- return false;
+ return NULL;
hlsl_init_simple_deref_from_var(&var_deref, var);
for (i = 0; i < type->e.numeric.dimx; ++i)
@@ -4895,13 +4873,11 @@ static bool lower_trig(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct
hlsl_block_add_store_component(ctx, block, &var_deref, i, sincos);
}
- hlsl_block_add_load_index(ctx, block, &var_deref, NULL, &instr->loc);
+ return hlsl_block_add_load_index(ctx, block, &var_deref, NULL, &instr->loc);
}
-
- return true;
}
-static bool lower_logic_not(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
+static struct hlsl_ir_node *lower_logic_not(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
{
struct hlsl_ir_node *arg, *arg_cast, *neg, *one, *sub;
struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS];
@@ -4910,10 +4886,10 @@ static bool lower_logic_not(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, st
struct hlsl_ir_expr *expr;
if (instr->type != HLSL_IR_EXPR)
- return false;
+ return NULL;
expr = hlsl_ir_expr(instr);
if (expr->op != HLSL_OP1_LOGIC_NOT)
- return false;
+ return NULL;
arg = expr->operands[0].node;
float_type = hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, arg->data_type->e.numeric.dimx);
@@ -4930,19 +4906,18 @@ static bool lower_logic_not(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, st
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;
+ return NULL;
hlsl_block_add_instr(block, one);
sub = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, one, neg);
memset(operands, 0, sizeof(operands));
operands[0] = sub;
- hlsl_block_add_expr(ctx, block, HLSL_OP1_REINTERPRET, operands, instr->data_type, &instr->loc);
- return true;
+ return hlsl_block_add_expr(ctx, block, HLSL_OP1_REINTERPRET, operands, instr->data_type, &instr->loc);
}
/* Lower TERNARY to CMP for SM1. */
-static bool lower_ternary(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
+static struct hlsl_ir_node *lower_ternary(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
{
struct hlsl_ir_node *cond, *first, *second, *float_cond, *neg;
struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {0};
@@ -4950,11 +4925,11 @@ static bool lower_ternary(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, stru
struct hlsl_type *type;
if (instr->type != HLSL_IR_EXPR)
- return false;
+ return NULL;
expr = hlsl_ir_expr(instr);
if (expr->op != HLSL_OP3_TERNARY)
- return false;
+ return NULL;
cond = expr->operands[0].node;
first = expr->operands[1].node;
@@ -4963,7 +4938,7 @@ static bool lower_ternary(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, stru
if (cond->data_type->class > HLSL_CLASS_VECTOR || instr->data_type->class > HLSL_CLASS_VECTOR)
{
hlsl_fixme(ctx, &instr->loc, "Lower ternary of type other than scalar or vector.");
- return false;
+ return NULL;
}
VKD3D_ASSERT(cond->data_type->e.numeric.type == HLSL_TYPE_BOOL);
@@ -4977,8 +4952,7 @@ static bool lower_ternary(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, stru
operands[0] = neg;
operands[1] = second;
operands[2] = first;
- hlsl_block_add_expr(ctx, block, HLSL_OP3_CMP, operands, first->data_type, &instr->loc);
- return true;
+ return hlsl_block_add_expr(ctx, block, HLSL_OP3_CMP, operands, first->data_type, &instr->loc);
}
static bool lower_resource_load_bias(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context)
@@ -5026,7 +5000,7 @@ static bool lower_resource_load_bias(struct hlsl_ctx *ctx, struct hlsl_ir_node *
return true;
}
-static bool lower_comparison_operators(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr,
+static struct hlsl_ir_node *lower_comparison_operators(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr,
struct hlsl_block *block)
{
struct hlsl_ir_node *arg1, *arg1_cast, *arg2, *arg2_cast, *slt, *res;
@@ -5036,10 +5010,10 @@ static bool lower_comparison_operators(struct hlsl_ctx *ctx, struct hlsl_ir_node
bool negate = false;
if (instr->type != HLSL_IR_EXPR)
- return false;
+ return NULL;
expr = hlsl_ir_expr(instr);
if (!hlsl_is_comparison_op(expr->op))
- return false;
+ return NULL;
arg1 = expr->operands[0].node;
arg2 = expr->operands[1].node;
@@ -5096,7 +5070,7 @@ static bool lower_comparison_operators(struct hlsl_ctx *ctx, struct hlsl_ir_node
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;
+ return NULL;
hlsl_block_add_instr(block, one);
slt_neg = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, slt, &instr->loc);
@@ -5111,8 +5085,7 @@ static bool lower_comparison_operators(struct hlsl_ctx *ctx, struct hlsl_ir_node
* and casts to BOOL have already been lowered to "!= 0". */
memset(operands, 0, sizeof(operands));
operands[0] = res;
- hlsl_block_add_expr(ctx, block, HLSL_OP1_REINTERPRET, operands, instr->data_type, &instr->loc);
- return true;
+ return hlsl_block_add_expr(ctx, block, HLSL_OP1_REINTERPRET, operands, instr->data_type, &instr->loc);
}
/* Intended to be used for SM1-SM3, lowers SLT instructions (only available in vertex shaders) to
@@ -5123,7 +5096,7 @@ static bool lower_comparison_operators(struct hlsl_ctx *ctx, struct hlsl_ir_node
* = ((x - y) >= 0) ? 0.0 : 1.0
* = CMP(x - y, 0.0, 1.0)
*/
-static bool lower_slt(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
+static struct hlsl_ir_node *lower_slt(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
{
struct hlsl_ir_node *arg1, *arg2, *arg1_cast, *arg2_cast, *neg, *sub, *zero, *one, *cmp;
struct hlsl_constant_value zero_value, one_value;
@@ -5131,10 +5104,10 @@ static bool lower_slt(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct h
struct hlsl_ir_expr *expr;
if (instr->type != HLSL_IR_EXPR)
- return false;
+ return NULL;
expr = hlsl_ir_expr(instr);
if (expr->op != HLSL_OP2_SLT)
- return false;
+ return NULL;
arg1 = expr->operands[0].node;
arg2 = expr->operands[1].node;
@@ -5147,7 +5120,7 @@ static bool lower_slt(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct h
memset(&zero_value, 0, sizeof(zero_value));
if (!(zero = hlsl_new_constant(ctx, float_type, &zero_value, &instr->loc)))
- return false;
+ return NULL;
hlsl_block_add_instr(block, zero);
one_value.u[0].f = 1.0;
@@ -5155,14 +5128,13 @@ static bool lower_slt(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct h
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;
+ return NULL;
hlsl_block_add_instr(block, one);
if (!(cmp = hlsl_new_ternary_expr(ctx, HLSL_OP3_CMP, sub, zero, one)))
- return false;
+ return NULL;
hlsl_block_add_instr(block, cmp);
-
- return true;
+ return cmp;
}
/* Intended to be used for SM1-SM3, lowers CMP instructions (only available in pixel shaders) to
@@ -5173,7 +5145,7 @@ static bool lower_slt(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct h
* = z * ((x < 0) ? 1.0 : 0.0) + y * ((x < 0) ? 0.0 : 1.0)
* = z * SLT(x, 0.0) + y * (1 - SLT(x, 0.0))
*/
-static bool lower_cmp(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
+static struct hlsl_ir_node *lower_cmp(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
{
struct hlsl_ir_node *args[3], *args_cast[3], *slt, *neg_slt, *sub, *zero, *one, *mul1, *mul2;
struct hlsl_constant_value zero_value, one_value;
@@ -5182,10 +5154,10 @@ static bool lower_cmp(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct h
unsigned int i;
if (instr->type != HLSL_IR_EXPR)
- return false;
+ return NULL;
expr = hlsl_ir_expr(instr);
if (expr->op != HLSL_OP3_CMP)
- return false;
+ return NULL;
float_type = hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, instr->data_type->e.numeric.dimx);
@@ -5197,7 +5169,7 @@ static bool lower_cmp(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct h
memset(&zero_value, 0, sizeof(zero_value));
if (!(zero = hlsl_new_constant(ctx, float_type, &zero_value, &instr->loc)))
- return false;
+ return NULL;
hlsl_block_add_instr(block, zero);
one_value.u[0].f = 1.0;
@@ -5205,7 +5177,7 @@ static bool lower_cmp(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct h
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;
+ return NULL;
hlsl_block_add_instr(block, one);
slt = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_SLT, args_cast[0], zero);
@@ -5213,11 +5185,11 @@ static bool lower_cmp(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct h
neg_slt = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, slt, &instr->loc);
sub = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, one, neg_slt);
mul2 = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, args_cast[1], sub);
- hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, mul1, mul2);
- return true;
+ return hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, mul1, mul2);
}
-static bool lower_casts_to_bool(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
+static struct hlsl_ir_node *lower_casts_to_bool(struct hlsl_ctx *ctx,
+ struct hlsl_ir_node *instr, struct hlsl_block *block)
{
struct hlsl_type *type = instr->data_type, *arg_type;
static const struct hlsl_constant_value zero_value;
@@ -5225,28 +5197,27 @@ static bool lower_casts_to_bool(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr
struct hlsl_ir_expr *expr;
if (instr->type != HLSL_IR_EXPR)
- return false;
+ return NULL;
expr = hlsl_ir_expr(instr);
if (expr->op != HLSL_OP1_CAST)
- return false;
+ return NULL;
arg_type = expr->operands[0].node->data_type;
if (type->class > HLSL_CLASS_VECTOR || arg_type->class > HLSL_CLASS_VECTOR)
- return false;
+ return NULL;
if (type->e.numeric.type != HLSL_TYPE_BOOL)
- return false;
+ return NULL;
/* Narrowing casts should have already been lowered. */
VKD3D_ASSERT(type->e.numeric.dimx == arg_type->e.numeric.dimx);
zero = hlsl_new_constant(ctx, arg_type, &zero_value, &instr->loc);
if (!zero)
- return false;
+ return NULL;
hlsl_block_add_instr(block, zero);
neq = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_NEQUAL, expr->operands[0].node, zero);
neq->data_type = expr->node.data_type;
-
- return true;
+ return neq;
}
struct hlsl_ir_node *hlsl_add_conditional(struct hlsl_ctx *ctx, struct hlsl_block *instrs,
@@ -5270,7 +5241,8 @@ struct hlsl_ir_node *hlsl_add_conditional(struct hlsl_ctx *ctx, struct hlsl_bloc
return hlsl_block_add_expr(ctx, instrs, HLSL_OP3_TERNARY, operands, if_true->data_type, &condition->loc);
}
-static bool lower_int_division_sm4(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
+static struct hlsl_ir_node *lower_int_division_sm4(struct hlsl_ctx *ctx,
+ struct hlsl_ir_node *instr, struct hlsl_block *block)
{
struct hlsl_ir_node *arg1, *arg2, *xor, *and, *abs1, *abs2, *div, *neg, *cast1, *cast2, *cast3, *high_bit;
struct hlsl_type *type = instr->data_type, *utype;
@@ -5279,16 +5251,16 @@ static bool lower_int_division_sm4(struct hlsl_ctx *ctx, struct hlsl_ir_node *in
unsigned int i;
if (instr->type != HLSL_IR_EXPR)
- return false;
+ return NULL;
expr = hlsl_ir_expr(instr);
arg1 = expr->operands[0].node;
arg2 = expr->operands[1].node;
if (expr->op != HLSL_OP2_DIV)
- return false;
+ return NULL;
if (type->class != HLSL_CLASS_SCALAR && type->class != HLSL_CLASS_VECTOR)
- return false;
+ return NULL;
if (type->e.numeric.type != HLSL_TYPE_INT)
- return false;
+ return NULL;
utype = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_UINT, type->e.numeric.dimx, type->e.numeric.dimy);
xor = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_BIT_XOR, arg1, arg2);
@@ -5296,7 +5268,7 @@ static bool lower_int_division_sm4(struct hlsl_ctx *ctx, struct hlsl_ir_node *in
for (i = 0; i < type->e.numeric.dimx; ++i)
high_bit_value.u[i].u = 0x80000000;
if (!(high_bit = hlsl_new_constant(ctx, type, &high_bit_value, &instr->loc)))
- return false;
+ return NULL;
hlsl_block_add_instr(block, high_bit);
and = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_BIT_AND, xor, high_bit);
@@ -5310,7 +5282,8 @@ static bool lower_int_division_sm4(struct hlsl_ctx *ctx, struct hlsl_ir_node *in
return hlsl_add_conditional(ctx, block, and, neg, cast3);
}
-static bool lower_int_modulus_sm4(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
+static struct hlsl_ir_node *lower_int_modulus_sm4(struct hlsl_ctx *ctx,
+ struct hlsl_ir_node *instr, struct hlsl_block *block)
{
struct hlsl_ir_node *arg1, *arg2, *and, *abs1, *abs2, *div, *neg, *cast1, *cast2, *cast3, *high_bit;
struct hlsl_type *type = instr->data_type, *utype;
@@ -5319,22 +5292,22 @@ static bool lower_int_modulus_sm4(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins
unsigned int i;
if (instr->type != HLSL_IR_EXPR)
- return false;
+ return NULL;
expr = hlsl_ir_expr(instr);
arg1 = expr->operands[0].node;
arg2 = expr->operands[1].node;
if (expr->op != HLSL_OP2_MOD)
- return false;
+ return NULL;
if (type->class != HLSL_CLASS_SCALAR && type->class != HLSL_CLASS_VECTOR)
- return false;
+ return NULL;
if (type->e.numeric.type != HLSL_TYPE_INT)
- return false;
+ return NULL;
utype = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_UINT, type->e.numeric.dimx, type->e.numeric.dimy);
for (i = 0; i < type->e.numeric.dimx; ++i)
high_bit_value.u[i].u = 0x80000000;
if (!(high_bit = hlsl_new_constant(ctx, type, &high_bit_value, &instr->loc)))
- return false;
+ return NULL;
hlsl_block_add_instr(block, high_bit);
and = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_BIT_AND, arg1, high_bit);
@@ -5348,31 +5321,30 @@ static bool lower_int_modulus_sm4(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins
return hlsl_add_conditional(ctx, block, and, neg, cast3);
}
-static bool lower_int_abs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
+static struct hlsl_ir_node *lower_int_abs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
{
struct hlsl_type *type = instr->data_type;
struct hlsl_ir_node *arg, *neg;
struct hlsl_ir_expr *expr;
if (instr->type != HLSL_IR_EXPR)
- return false;
+ return NULL;
expr = hlsl_ir_expr(instr);
if (expr->op != HLSL_OP1_ABS)
- return false;
+ return NULL;
if (type->class != HLSL_CLASS_SCALAR && type->class != HLSL_CLASS_VECTOR)
- return false;
+ return NULL;
if (type->e.numeric.type != HLSL_TYPE_INT)
- return false;
+ return NULL;
arg = expr->operands[0].node;
neg = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, arg, &instr->loc);
- hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MAX, arg, neg);
- return true;
+ return hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MAX, arg, neg);
}
-static bool lower_int_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
+static struct hlsl_ir_node *lower_int_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
{
struct hlsl_ir_node *arg1, *arg2, *mult, *comps[4] = {0}, *res;
struct hlsl_type *type = instr->data_type;
@@ -5381,11 +5353,11 @@ static bool lower_int_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, stru
bool is_bool;
if (instr->type != HLSL_IR_EXPR)
- return false;
+ return NULL;
expr = hlsl_ir_expr(instr);
if (expr->op != HLSL_OP2_DOT)
- return false;
+ return NULL;
if (hlsl_type_is_integer(type))
{
@@ -5407,14 +5379,14 @@ static bool lower_int_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, stru
res = comps[0];
for (i = 1; i < dimx; ++i)
res = hlsl_block_add_binary_expr(ctx, block, is_bool ? HLSL_OP2_LOGIC_OR : HLSL_OP2_ADD, res, comps[i]);
-
- return true;
+ return res;
}
- return false;
+ return NULL;
}
-static bool lower_float_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
+static struct hlsl_ir_node *lower_float_modulus(struct hlsl_ctx *ctx,
+ struct hlsl_ir_node *instr, struct hlsl_block *block)
{
struct hlsl_ir_node *arg1, *arg2, *mul1, *neg1, *ge, *neg2, *div, *mul2, *frc, *cond, *one;
struct hlsl_type *type = instr->data_type, *btype;
@@ -5423,16 +5395,16 @@ static bool lower_float_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr
unsigned int i;
if (instr->type != HLSL_IR_EXPR)
- return false;
+ return NULL;
expr = hlsl_ir_expr(instr);
arg1 = expr->operands[0].node;
arg2 = expr->operands[1].node;
if (expr->op != HLSL_OP2_MOD)
- return false;
+ return NULL;
if (type->class != HLSL_CLASS_SCALAR && type->class != HLSL_CLASS_VECTOR)
- return false;
+ return NULL;
if (type->e.numeric.type != HLSL_TYPE_FLOAT)
- return false;
+ return NULL;
btype = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_BOOL, type->e.numeric.dimx, type->e.numeric.dimy);
mul1 = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, arg2, arg1);
@@ -5447,14 +5419,13 @@ static bool lower_float_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr
for (i = 0; i < type->e.numeric.dimx; ++i)
one_value.u[i].f = 1.0f;
if (!(one = hlsl_new_constant(ctx, type, &one_value, &instr->loc)))
- return false;
+ return NULL;
hlsl_block_add_instr(block, one);
div = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_DIV, one, cond);
mul2 = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, div, arg1);
frc = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_FRACT, mul2, &instr->loc);
- hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, frc, cond);
- return true;
+ return hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, frc, cond);
}
static bool lower_discard_neg(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context)
@@ -6167,7 +6138,7 @@ static bool track_object_components_sampler_dim(struct hlsl_ctx *ctx, struct hls
return false;
}
-static void register_deref_usage(struct hlsl_ctx *ctx, struct hlsl_deref *deref)
+static void register_deref_usage(struct hlsl_ctx *ctx, const struct hlsl_deref *deref)
{
struct hlsl_ir_var *var = deref->var;
enum hlsl_regset regset = hlsl_deref_get_regset(ctx, deref);
@@ -6215,18 +6186,43 @@ static bool track_components_usage(struct hlsl_ctx *ctx, struct hlsl_ir_node *in
}
case HLSL_IR_RESOURCE_LOAD:
- register_deref_usage(ctx, &hlsl_ir_resource_load(instr)->resource);
- if (hlsl_ir_resource_load(instr)->sampler.var)
- register_deref_usage(ctx, &hlsl_ir_resource_load(instr)->sampler);
+ {
+ const struct hlsl_ir_resource_load *load = hlsl_ir_resource_load(instr);
+
+ register_deref_usage(ctx, &load->resource);
+ if (load->sampler.var)
+ register_deref_usage(ctx, &load->sampler);
+
+ if (hlsl_deref_get_regset(ctx, &load->resource) == HLSL_REGSET_UAVS)
+ {
+ unsigned int index;
+
+ hlsl_regset_index_from_deref(ctx, &load->resource, HLSL_REGSET_UAVS, &index);
+ load->resource.var->objects_usage[HLSL_REGSET_UAVS][index].uav_read = true;
+ }
break;
+ }
case HLSL_IR_RESOURCE_STORE:
register_deref_usage(ctx, &hlsl_ir_resource_store(instr)->resource);
break;
case HLSL_IR_INTERLOCKED:
- register_deref_usage(ctx, &hlsl_ir_interlocked(instr)->dst);
+ {
+ const struct hlsl_ir_interlocked *interlocked = hlsl_ir_interlocked(instr);
+
+ register_deref_usage(ctx, &interlocked->dst);
+
+ if (hlsl_deref_get_regset(ctx, &interlocked->dst) == HLSL_REGSET_UAVS)
+ {
+ unsigned int index;
+
+ hlsl_regset_index_from_deref(ctx, &interlocked->dst, HLSL_REGSET_UAVS, &index);
+ interlocked->dst.var->objects_usage[HLSL_REGSET_UAVS][index].uav_read = true;
+ interlocked->dst.var->objects_usage[HLSL_REGSET_UAVS][index].uav_atomics = true;
+ }
break;
+ }
default:
break;
@@ -8234,7 +8230,7 @@ static void remove_unreachable_code(struct hlsl_ctx *ctx, struct hlsl_block *bod
void hlsl_lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_block *body)
{
- lower_ir(ctx, lower_index_loads, body);
+ replace_ir(ctx, lower_index_loads, body);
}
static enum hlsl_ir_expr_op invert_comparison_op(enum hlsl_ir_expr_op op)
@@ -8537,27 +8533,27 @@ static void hlsl_run_folding_passes(struct hlsl_ctx *ctx, struct hlsl_block *bod
{
bool progress;
- hlsl_transform_ir(ctx, fold_redundant_casts, body, NULL);
+ replace_ir(ctx, fold_redundant_casts, body);
do
{
progress = simplify_exprs(ctx, body);
progress |= hlsl_copy_propagation_execute(ctx, body);
- progress |= hlsl_transform_ir(ctx, fold_swizzle_chains, body, NULL);
- progress |= hlsl_transform_ir(ctx, remove_trivial_swizzles, body, NULL);
+ progress |= replace_ir(ctx, fold_swizzle_chains, body);
+ progress |= replace_ir(ctx, fold_trivial_swizzles, body);
progress |= hlsl_transform_ir(ctx, remove_trivial_conditional_branches, body, NULL);
} while (progress);
- hlsl_transform_ir(ctx, fold_redundant_casts, body, NULL);
+ replace_ir(ctx, fold_redundant_casts, body);
}
void hlsl_run_const_passes(struct hlsl_ctx *ctx, struct hlsl_block *body)
{
bool progress;
- lower_ir(ctx, lower_complex_casts, body);
- lower_ir(ctx, lower_matrix_swizzles, body);
+ replace_ir(ctx, lower_complex_casts, body);
+ replace_ir(ctx, lower_matrix_swizzles, body);
- lower_ir(ctx, lower_broadcasts, body);
- while (hlsl_transform_ir(ctx, fold_redundant_casts, body, NULL));
+ replace_ir(ctx, lower_broadcasts, body);
+ while (replace_ir(ctx, fold_redundant_casts, body));
do
{
progress = hlsl_transform_ir(ctx, split_array_copies, body, NULL);
@@ -8566,16 +8562,16 @@ void hlsl_run_const_passes(struct hlsl_ctx *ctx, struct hlsl_block *body)
while (progress);
hlsl_transform_ir(ctx, split_matrix_copies, body, NULL);
- lower_ir(ctx, lower_narrowing_casts, body);
- lower_ir(ctx, lower_int_dot, body);
+ replace_ir(ctx, lower_narrowing_casts, body);
+ replace_ir(ctx, lower_int_dot, body);
if (hlsl_version_ge(ctx, 4, 0))
{
- lower_ir(ctx, lower_int_modulus_sm4, body);
- lower_ir(ctx, lower_int_division_sm4, body);
+ replace_ir(ctx, lower_int_modulus_sm4, body);
+ replace_ir(ctx, lower_int_division_sm4, body);
}
- lower_ir(ctx, lower_int_abs, body);
- lower_ir(ctx, lower_casts_to_bool, body);
- lower_ir(ctx, lower_float_modulus, body);
+ replace_ir(ctx, lower_int_abs, body);
+ replace_ir(ctx, lower_casts_to_bool, body);
+ replace_ir(ctx, lower_float_modulus, body);
hlsl_run_folding_passes(ctx, body);
}
@@ -10189,10 +10185,7 @@ static void sm1_generate_vsir(struct hlsl_ctx *ctx, const struct vkd3d_shader_co
struct hlsl_ir_function_decl *func, struct list *semantic_vars,
struct hlsl_block *body, uint64_t config_flags, struct vsir_program *program)
{
- struct hlsl_ir_var *var;
struct hlsl_block block;
- struct hlsl_reg *reg;
- unsigned int *count;
program->ssa_count = 0;
program->temp_count = 0;
@@ -10207,17 +10200,6 @@ static void sm1_generate_vsir(struct hlsl_ctx *ctx, const struct vkd3d_shader_co
sm1_generate_vsir_block(ctx, body, program);
- count = &program->flat_constant_count[VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER];
- LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
- {
- if (!var->is_uniform)
- continue;
-
- if (!(reg = &var->regs[HLSL_REGSET_NUMERIC])->allocation_size)
- continue;
-
- *count = max(*count, reg->id + reg->allocation_size);
- }
program->ssa_count = ctx->ssa_count;
program->temp_count = ctx->temp_count;
@@ -12785,9 +12767,9 @@ static void sm4_generate_vsir_add_dcl_sampler(struct hlsl_ctx *ctx,
}
}
-static enum vkd3d_shader_resource_type sm4_generate_vsir_get_resource_type(const struct hlsl_type *type)
+static enum vkd3d_shader_resource_type get_vsir_resource_type(enum hlsl_sampler_dim sampler_dim)
{
- switch (type->sampler_dim)
+ switch (sampler_dim)
{
case HLSL_SAMPLER_DIM_1D:
return VKD3D_SHADER_RESOURCE_TEXTURE_1D;
@@ -12816,7 +12798,7 @@ static enum vkd3d_shader_resource_type sm4_generate_vsir_get_resource_type(const
}
}
-static enum vsir_data_type sm4_generate_vsir_get_format_type(const struct hlsl_type *type)
+static enum vsir_data_type get_vsir_resource_data_type(const struct hlsl_type *type)
{
const struct hlsl_type *format = type->e.resource.format;
@@ -12953,10 +12935,10 @@ static void sm4_generate_vsir_add_dcl_texture(struct hlsl_ctx *ctx,
}
else
{
- ins->declaration.semantic.resource_type = sm4_generate_vsir_get_resource_type(resource->component_type);
+ ins->declaration.semantic.resource_type = get_vsir_resource_type(resource->component_type->sampler_dim);
for (unsigned int j = 0; j < 4; ++j)
- ins->declaration.semantic.resource_data_type[j] = sm4_generate_vsir_get_format_type(component_type);
+ ins->declaration.semantic.resource_data_type[j] = get_vsir_resource_data_type(component_type);
if (multisampled)
ins->declaration.semantic.sample_count = component_type->sample_count;
@@ -13108,6 +13090,140 @@ static void sm4_generate_vsir(struct hlsl_ctx *ctx,
program->temp_count = ctx->temp_count;
}
+static void generate_vsir_descriptors_for_var(struct hlsl_ctx *ctx, struct vsir_program *program,
+ const struct hlsl_ir_var *var, enum hlsl_regset r, enum vkd3d_shader_descriptor_type type)
+{
+ unsigned int component_count = hlsl_type_component_count(var->data_type);
+
+ for (unsigned int k = 0; k < component_count; ++k)
+ {
+ const struct hlsl_type *component_type = hlsl_type_get_component_type(ctx, var->data_type, k);
+ struct vkd3d_shader_register_range range;
+ struct vkd3d_shader_descriptor_info1 *d;
+ unsigned int regset_offset;
+ enum hlsl_regset regset;
+ uint32_t id;
+
+ if (!hlsl_type_is_resource(component_type))
+ continue;
+ regset_offset = hlsl_type_get_component_offset(ctx, var->data_type, k, &regset);
+ if (regset != r)
+ continue;
+ if (regset_offset > var->regs[r].allocation_size)
+ continue;
+
+ if (!var->objects_usage[r][regset_offset].used)
+ continue;
+
+ id = var->regs[r].id + regset_offset;
+ range.space = var->regs[r].space;
+ range.first = var->regs[r].index + regset_offset;
+ /* FIXME: 5.1 arrays. */
+ range.last = var->regs[r].index + regset_offset;
+
+ if (type == VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER)
+ {
+ if (!(d = vsir_program_add_descriptor(program, type, id,
+ &range, VKD3D_SHADER_RESOURCE_NONE, VSIR_DATA_UNUSED)))
+ return;
+ if (component_type->sampler_dim == HLSL_SAMPLER_DIM_COMPARISON)
+ d->flags |= VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_SAMPLER_COMPARISON_MODE;
+ }
+ else
+ {
+ if (component_type->class == HLSL_CLASS_SAMPLER)
+ d = vsir_program_add_descriptor(program, type, id, &range,
+ get_vsir_resource_type(var->objects_usage[r][regset_offset].sampler_dim), VSIR_DATA_F32);
+ else
+ d = vsir_program_add_descriptor(program, type, id, &range,
+ get_vsir_resource_type(component_type->sampler_dim),
+ get_vsir_resource_data_type(component_type));
+ if (!d)
+ return;
+
+ if (component_type->sampler_dim == HLSL_SAMPLER_DIM_RAW_BUFFER)
+ d->flags |= VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_RAW_BUFFER;
+ else if (component_type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER)
+ d->structure_stride = hlsl_type_get_packed_size(component_type->e.resource.format);
+ else if (component_type->sampler_dim == HLSL_SAMPLER_DIM_2DMS
+ || component_type->sampler_dim == HLSL_SAMPLER_DIM_2DMSARRAY)
+ d->sample_count = component_type->sample_count;
+
+ if (type == VKD3D_SHADER_DESCRIPTOR_TYPE_UAV && component_type->e.resource.rasteriser_ordered)
+ d->uav_flags |= VKD3DSUF_RASTERISER_ORDERED_VIEW;
+
+ if (var->objects_usage[r][regset_offset].uav_read)
+ d->flags |= VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_READ;
+ if (var->objects_usage[r][regset_offset].uav_atomics)
+ d->flags |= VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_ATOMICS;
+ }
+ }
+}
+
+static void generate_vsir_descriptors(struct hlsl_ctx *ctx, struct vsir_program *program)
+{
+ struct vkd3d_shader_register_range range;
+ struct vkd3d_shader_descriptor_info1 *d;
+ const struct hlsl_ir_var *var;
+
+ if (program->shader_version.major < 4)
+ {
+ uint32_t flat_constant_count = 0;
+
+ LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
+ {
+ const struct hlsl_reg *reg = &var->regs[HLSL_REGSET_NUMERIC];
+
+ if (var->is_uniform && reg->allocation_size)
+ flat_constant_count = max(flat_constant_count, reg->id + reg->allocation_size);
+
+ generate_vsir_descriptors_for_var(ctx, program, var,
+ HLSL_REGSET_SAMPLERS, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER);
+ generate_vsir_descriptors_for_var(ctx, program, var,
+ HLSL_REGSET_SAMPLERS, VKD3D_SHADER_DESCRIPTOR_TYPE_SRV);
+ }
+
+ if (flat_constant_count)
+ {
+ range.space = 0;
+ range.first = range.last = VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER;
+ if ((d = vsir_program_add_descriptor(program, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV,
+ range.first, &range, VKD3D_SHADER_RESOURCE_BUFFER, VSIR_DATA_U32)))
+ d->buffer_size = flat_constant_count * 16;
+ }
+ }
+ else
+ {
+ struct hlsl_buffer *buffer;
+
+ LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
+ {
+ generate_vsir_descriptors_for_var(ctx, program, var,
+ HLSL_REGSET_SAMPLERS, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER);
+ generate_vsir_descriptors_for_var(ctx, program, var,
+ HLSL_REGSET_TEXTURES, VKD3D_SHADER_DESCRIPTOR_TYPE_SRV);
+ generate_vsir_descriptors_for_var(ctx, program, var,
+ HLSL_REGSET_UAVS, VKD3D_SHADER_DESCRIPTOR_TYPE_UAV);
+ }
+
+ LIST_FOR_EACH_ENTRY(buffer, &ctx->buffers, struct hlsl_buffer, entry)
+ {
+ if (!buffer->reg.allocated)
+ continue;
+
+ range.space = buffer->reg.space;
+ range.first = buffer->reg.index;
+ /* FIXME: 5.1 arrays. */
+ range.last = buffer->reg.index;
+ if ((d = vsir_program_add_descriptor(program, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV,
+ buffer->reg.id, &range, VKD3D_SHADER_RESOURCE_BUFFER, VSIR_DATA_U32)))
+ d->buffer_size = align(buffer->size, 4) * sizeof(float);
+ }
+ }
+
+ program->has_descriptor_info = true;
+}
+
/* For some reason, for matrices, values from default value initializers end
* up in different components than from regular initializers. Default value
* initializers fill the matrix in vertical reading order
@@ -13877,8 +13993,8 @@ static void loop_unrolling_simplify(struct hlsl_ctx *ctx, struct hlsl_block *blo
current_index = index_instructions(block, *index);
progress |= copy_propagation_transform_block(ctx, block, state);
- progress |= hlsl_transform_ir(ctx, fold_swizzle_chains, block, NULL);
- progress |= hlsl_transform_ir(ctx, remove_trivial_swizzles, block, NULL);
+ progress |= replace_ir(ctx, fold_swizzle_chains, block);
+ progress |= replace_ir(ctx, fold_trivial_swizzles, block);
progress |= hlsl_transform_ir(ctx, remove_trivial_conditional_branches, block, NULL);
} while (progress);
@@ -14131,7 +14247,7 @@ static void loop_unrolling_execute(struct hlsl_ctx *ctx, struct hlsl_block *bloc
hlsl_transform_ir(ctx, resolve_loops, block, NULL);
}
-static bool lower_countbits(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_block *block)
+static struct hlsl_ir_node *lower_countbits(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_block *block)
{
struct hlsl_ir_function_decl *func;
struct hlsl_ir_node *call, *rhs;
@@ -14150,33 +14266,31 @@ static bool lower_countbits(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, str
"}\n";
if (node->type != HLSL_IR_EXPR)
- return false;
+ return NULL;
expr = hlsl_ir_expr(node);
if (expr->op != HLSL_OP1_COUNTBITS)
- return false;
+ return NULL;
rhs = expr->operands[0].node;
if (!(body = hlsl_sprintf_alloc(ctx, template, hlsl_type_component_count(rhs->data_type))))
- return false;
+ return NULL;
func = hlsl_compile_internal_function(ctx, "countbits", body);
vkd3d_free(body);
if (!func)
- return false;
+ return NULL;
lhs = func->parameters.vars[0];
hlsl_block_add_simple_store(ctx, block, lhs, rhs);
if (!(call = hlsl_new_call(ctx, func, &node->loc)))
- return false;
+ return NULL;
hlsl_block_add_instr(block, call);
- hlsl_block_add_simple_load(ctx, block, func->return_var, &node->loc);
-
- return true;
+ return hlsl_block_add_simple_load(ctx, block, func->return_var, &node->loc);
}
-static bool lower_ctz(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_block *block)
+static struct hlsl_ir_node *lower_ctz(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_block *block)
{
struct hlsl_ir_function_decl *func;
struct hlsl_ir_node *call, *rhs;
@@ -14201,11 +14315,11 @@ static bool lower_ctz(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hl
"}\n";
if (node->type != HLSL_IR_EXPR)
- return false;
+ return NULL;
expr = hlsl_ir_expr(node);
if (expr->op != HLSL_OP1_CTZ)
- return false;
+ return NULL;
rhs = expr->operands[0].node;
if (!(body = hlsl_sprintf_alloc(ctx, template, hlsl_type_component_count(rhs->data_type))))
@@ -14213,21 +14327,19 @@ static bool lower_ctz(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hl
func = hlsl_compile_internal_function(ctx, "ctz", body);
vkd3d_free(body);
if (!func)
- return false;
+ return NULL;
lhs = func->parameters.vars[0];
hlsl_block_add_simple_store(ctx, block, lhs, rhs);
if (!(call = hlsl_new_call(ctx, func, &node->loc)))
- return false;
+ return NULL;
hlsl_block_add_instr(block, call);
- hlsl_block_add_simple_load(ctx, block, func->return_var, &node->loc);
-
- return true;
+ return hlsl_block_add_simple_load(ctx, block, func->return_var, &node->loc);
}
-static bool lower_f16tof32(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_block *block)
+static struct hlsl_ir_node *lower_f16tof32(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_block *block)
{
struct hlsl_ir_function_decl *func;
struct hlsl_ir_node *call, *rhs;
@@ -14282,29 +14394,28 @@ static bool lower_f16tof32(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, stru
expr = hlsl_ir_expr(node);
if (expr->op != HLSL_OP1_F16TOF32)
- return false;
+ return NULL;
rhs = expr->operands[0].node;
component_count = hlsl_type_component_count(rhs->data_type);
if (!(body = hlsl_sprintf_alloc(ctx, template, component_count, component_count)))
- return false;
+ return NULL;
if (!(func = hlsl_compile_internal_function(ctx, "soft_f16tof32", body)))
- return false;
+ return NULL;
lhs = func->parameters.vars[0];
hlsl_block_add_simple_store(ctx, block, lhs, rhs);
if (!(call = hlsl_new_call(ctx, func, &node->loc)))
- return false;
+ return NULL;
hlsl_block_add_instr(block, call);
- hlsl_block_add_simple_load(ctx, block, func->return_var, &node->loc);
- return true;
+ return hlsl_block_add_simple_load(ctx, block, func->return_var, &node->loc);
}
-static bool lower_f32tof16(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_block *block)
+static struct hlsl_ir_node *lower_f32tof16(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_block *block)
{
struct hlsl_ir_function_decl *func;
struct hlsl_ir_node *call, *rhs;
@@ -14342,34 +14453,33 @@ static bool lower_f32tof16(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, stru
"}\n";
if (node->type != HLSL_IR_EXPR)
- return false;
+ return NULL;
expr = hlsl_ir_expr(node);
if (expr->op != HLSL_OP1_F32TOF16)
- return false;
+ return NULL;
rhs = expr->operands[0].node;
component_count = hlsl_type_component_count(rhs->data_type);
if (!(body = hlsl_sprintf_alloc(ctx, template, component_count, component_count)))
- return false;
+ return NULL;
if (!(func = hlsl_compile_internal_function(ctx, "soft_f32tof16", body)))
- return false;
+ return NULL;
lhs = func->parameters.vars[0];
hlsl_block_add_simple_store(ctx, block, lhs, rhs);
if (!(call = hlsl_new_call(ctx, func, &node->loc)))
- return false;
+ return NULL;
hlsl_block_add_instr(block, call);
- hlsl_block_add_simple_load(ctx, block, func->return_var, &node->loc);
- return true;
+ return hlsl_block_add_simple_load(ctx, block, func->return_var, &node->loc);
}
-static bool lower_find_msb(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_block *block)
+static struct hlsl_ir_node *lower_find_msb(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_block *block)
{
struct hlsl_ir_function_decl *func;
struct hlsl_ir_node *call, *rhs;
@@ -14406,33 +14516,31 @@ static bool lower_find_msb(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, stru
"}\n";
if (node->type != HLSL_IR_EXPR)
- return false;
+ return NULL;
expr = hlsl_ir_expr(node);
if (expr->op != HLSL_OP1_FIND_MSB)
- return false;
+ return NULL;
rhs = expr->operands[0].node;
if (!(body = hlsl_sprintf_alloc(ctx, template, rhs->data_type->name, hlsl_type_component_count(rhs->data_type))))
- return false;
+ return NULL;
func = hlsl_compile_internal_function(ctx, "find_msb", body);
vkd3d_free(body);
if (!func)
- return false;
+ return NULL;
lhs = func->parameters.vars[0];
hlsl_block_add_simple_store(ctx, block, lhs, rhs);
if (!(call = hlsl_new_call(ctx, func, &node->loc)))
- return false;
+ return NULL;
hlsl_block_add_instr(block, call);
- hlsl_block_add_simple_load(ctx, block, func->return_var, &node->loc);
-
- return true;
+ return hlsl_block_add_simple_load(ctx, block, func->return_var, &node->loc);
}
-static bool lower_isinf(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_block *block)
+static struct hlsl_ir_node *lower_isinf(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_block *block)
{
struct hlsl_ir_function_decl *func;
struct hlsl_ir_node *call, *rhs;
@@ -14477,12 +14585,12 @@ static bool lower_isinf(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct
"}";
if (node->type != HLSL_IR_EXPR)
- return false;
+ return NULL;
expr = hlsl_ir_expr(node);
if (expr->op != HLSL_OP1_ISINF)
- return false;
+ return NULL;
rhs = expr->operands[0].node;
@@ -14497,19 +14605,18 @@ static bool lower_isinf(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct
component_count = hlsl_type_component_count(rhs->data_type);
if (!(body = hlsl_sprintf_alloc(ctx, template, component_count, component_count)))
- return false;
+ return NULL;
if (!(func = hlsl_compile_internal_function(ctx, "isinf", body)))
- return false;
+ return NULL;
hlsl_block_add_simple_store(ctx, block, func->parameters.vars[0], rhs);
if (!(call = hlsl_new_call(ctx, func, &node->loc)))
- return false;
+ return NULL;
hlsl_block_add_instr(block, call);
- hlsl_block_add_simple_load(ctx, block, func->return_var, &node->loc);
- return true;
+ return hlsl_block_add_simple_load(ctx, block, func->return_var, &node->loc);
}
static void process_entry_function(struct hlsl_ctx *ctx, struct list *semantic_vars, struct hlsl_block *body,
@@ -14548,25 +14655,25 @@ static void process_entry_function(struct hlsl_ctx *ctx, struct list *semantic_v
if (hlsl_version_ge(ctx, 4, 0) && hlsl_version_lt(ctx, 5, 0))
{
- lower_ir(ctx, lower_countbits, body);
- lower_ir(ctx, lower_ctz, body);
- lower_ir(ctx, lower_f16tof32, body);
- lower_ir(ctx, lower_f32tof16, body);
- lower_ir(ctx, lower_find_msb, body);
+ replace_ir(ctx, lower_countbits, body);
+ replace_ir(ctx, lower_ctz, body);
+ replace_ir(ctx, lower_f16tof32, body);
+ replace_ir(ctx, lower_f32tof16, body);
+ replace_ir(ctx, lower_find_msb, body);
}
- lower_ir(ctx, lower_isinf, body);
+ replace_ir(ctx, lower_isinf, body);
lower_return(ctx, entry_func, body, false);
while (hlsl_transform_ir(ctx, lower_calls, body, NULL));
- lower_ir(ctx, lower_complex_casts, body);
- lower_ir(ctx, lower_matrix_swizzles, body);
- lower_ir(ctx, lower_index_loads, body);
+ replace_ir(ctx, lower_complex_casts, body);
+ replace_ir(ctx, lower_matrix_swizzles, body);
+ replace_ir(ctx, lower_index_loads, body);
- lower_ir(ctx, lower_tgsm_loads, body);
- lower_ir(ctx, lower_tgsm_stores, body);
+ replace_ir(ctx, lower_tgsm_loads, body);
+ replace_ir(ctx, lower_tgsm_stores, body);
if (entry_func->return_var)
{
@@ -14739,9 +14846,9 @@ static void process_entry_function(struct hlsl_ctx *ctx, struct list *semantic_v
remove_unreachable_code(ctx, body);
hlsl_transform_ir(ctx, normalize_switch_cases, body, NULL);
- lower_ir(ctx, lower_nonconstant_vector_derefs, body);
- lower_ir(ctx, lower_casts_to_bool, body);
- lower_ir(ctx, lower_int_dot, body);
+ replace_ir(ctx, lower_nonconstant_vector_derefs, body);
+ replace_ir(ctx, lower_casts_to_bool, body);
+ replace_ir(ctx, lower_int_dot, body);
if (hlsl_version_lt(ctx, 4, 0))
hlsl_transform_ir(ctx, lower_separate_samples, body, NULL);
@@ -14753,8 +14860,8 @@ static void process_entry_function(struct hlsl_ctx *ctx, struct list *semantic_v
progress = vectorize_exprs(ctx, body);
compute_liveness(ctx, body);
progress |= hlsl_transform_ir(ctx, dce, body, NULL);
- progress |= hlsl_transform_ir(ctx, fold_swizzle_chains, body, NULL);
- progress |= hlsl_transform_ir(ctx, remove_trivial_swizzles, body, NULL);
+ progress |= replace_ir(ctx, fold_swizzle_chains, body);
+ progress |= replace_ir(ctx, fold_trivial_swizzles, body);
progress |= vectorize_stores(ctx, body);
} while (progress);
@@ -14782,37 +14889,37 @@ static void process_entry_function(struct hlsl_ctx *ctx, struct list *semantic_v
if (profile->major_version < 4)
{
- while (lower_ir(ctx, lower_nonconstant_array_loads, body));
+ while (replace_ir(ctx, lower_nonconstant_array_loads, body));
- lower_ir(ctx, lower_ternary, body);
- lower_ir(ctx, lower_int_modulus_sm1, body);
- lower_ir(ctx, lower_division, body);
+ replace_ir(ctx, lower_ternary, body);
+ replace_ir(ctx, lower_int_modulus_sm1, body);
+ replace_ir(ctx, lower_division, body);
/* Constants casted to float must be folded, and new casts to bool also need to be lowered. */
hlsl_transform_ir(ctx, hlsl_fold_constant_exprs, body, NULL);
- lower_ir(ctx, lower_casts_to_bool, body);
-
- lower_ir(ctx, lower_casts_to_int, body);
- lower_ir(ctx, lower_trunc, body);
- lower_ir(ctx, lower_sqrt, body);
- lower_ir(ctx, lower_dot, body);
- lower_ir(ctx, lower_round, body);
- lower_ir(ctx, lower_ceil, body);
- lower_ir(ctx, lower_floor, body);
- lower_ir(ctx, lower_trig, body);
- lower_ir(ctx, lower_comparison_operators, body);
- lower_ir(ctx, lower_logic_not, body);
+ replace_ir(ctx, lower_casts_to_bool, body);
+
+ replace_ir(ctx, lower_casts_to_int, body);
+ replace_ir(ctx, lower_trunc, body);
+ replace_ir(ctx, lower_sqrt, body);
+ replace_ir(ctx, lower_dot, body);
+ replace_ir(ctx, lower_round, body);
+ replace_ir(ctx, lower_ceil, body);
+ replace_ir(ctx, lower_floor, body);
+ replace_ir(ctx, lower_trig, body);
+ replace_ir(ctx, lower_comparison_operators, body);
+ replace_ir(ctx, lower_logic_not, body);
if (ctx->profile->type == VKD3D_SHADER_TYPE_PIXEL)
- lower_ir(ctx, lower_slt, body);
+ replace_ir(ctx, lower_slt, body);
else
- lower_ir(ctx, lower_cmp, body);
+ replace_ir(ctx, lower_cmp, body);
}
if (profile->major_version < 2)
{
- lower_ir(ctx, lower_abs, body);
+ replace_ir(ctx, lower_abs, body);
}
- lower_ir(ctx, validate_nonconstant_vector_store_derefs, body);
+ replace_ir(ctx, validate_nonconstant_vector_store_derefs, body);
hlsl_run_folding_passes(ctx, body);
@@ -14930,6 +15037,8 @@ int hlsl_emit_vsir(struct hlsl_ctx *ctx, const struct vkd3d_shader_compile_info
if (program->shader_version.type == VKD3D_SHADER_TYPE_HULL)
generate_vsir_signature(ctx, program, ctx->patch_constant_func, &patch_semantic_vars);
+ generate_vsir_descriptors(ctx, program);
+
if (program->shader_version.major < 4)
sm1_generate_ctab(ctx, reflection_data);
else
diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c
index 670f6c31cf8..13ea8a433a6 100644
--- a/libs/vkd3d/libs/vkd3d-shader/ir.c
+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c
@@ -299,6 +299,7 @@ const char *vsir_opcode_get_name(enum vkd3d_shader_opcode op, const char *error)
[VSIR_OP_MOVC ] = "movc",
[VSIR_OP_MSAD ] = "msad",
[VSIR_OP_MUL ] = "mul",
+ [VSIR_OP_NEG ] = "neg",
[VSIR_OP_NEO ] = "ne_ord",
[VSIR_OP_NEU ] = "ne",
[VSIR_OP_NOP ] = "nop",
@@ -747,6 +748,38 @@ bool vsir_signature_find_sysval(const struct shader_signature *signature,
return false;
}
+struct vkd3d_shader_descriptor_info1 *vsir_program_add_descriptor(struct vsir_program *program,
+ enum vkd3d_shader_descriptor_type type, unsigned int register_id,
+ const struct vkd3d_shader_register_range *range,
+ enum vkd3d_shader_resource_type resource_type, enum vsir_data_type resource_data_type)
+{
+ struct vkd3d_shader_scan_descriptor_info1 *info = &program->descriptors;
+ struct vkd3d_shader_descriptor_info1 *d;
+
+ if (!info)
+ return NULL;
+
+ if (!vkd3d_array_reserve((void **)&info->descriptors, &program->descriptors_size,
+ info->descriptor_count + 1, sizeof(*info->descriptors)))
+ {
+ ERR("Failed to allocate descriptor info.\n");
+ return NULL;
+ }
+
+ d = &info->descriptors[info->descriptor_count];
+ memset(d, 0, sizeof(*d));
+ d->type = type;
+ d->register_id = register_id;
+ d->register_space = range->space;
+ d->register_index = range->first;
+ d->resource_type = resource_type;
+ d->resource_data_type = resource_data_type;
+ d->count = (range->last == ~0u) ? ~0u : range->last - range->first + 1;
+ ++info->descriptor_count;
+
+ return d;
+}
+
const char *debug_vsir_writemask(unsigned int writemask)
{
static const char components[] = {'x', 'y', 'z', 'w'};
@@ -1422,8 +1455,8 @@ static enum vkd3d_result vsir_program_lower_imul(struct vsir_program *program,
static enum vkd3d_result vsir_program_lower_udiv(struct vsir_program *program,
struct vsir_program_iterator *it, struct vsir_transformation_context *ctx)
{
+ unsigned int count = 3, src0_id, src1_id, divisor_id;
struct vkd3d_shader_instruction *udiv, *ins, *mov;
- unsigned int count = 2;
udiv = vsir_program_iterator_current(it);
@@ -1437,9 +1470,9 @@ static enum vkd3d_result vsir_program_lower_udiv(struct vsir_program *program,
}
if (udiv->dst[0].reg.type != VKD3DSPR_NULL)
- ++count;
+ count += 2;
if (udiv->dst[1].reg.type != VKD3DSPR_NULL)
- ++count;
+ count += 2;
if (!vsir_program_iterator_insert_after(it, count))
return VKD3D_ERROR_OUT_OF_MEMORY;
@@ -1451,14 +1484,33 @@ static enum vkd3d_result vsir_program_lower_udiv(struct vsir_program *program,
return VKD3D_ERROR_OUT_OF_MEMORY;
mov->src[0] = udiv->src[0];
- dst_param_init_ssa(&mov->dst[0], program->ssa_count, udiv->src[0].reg.data_type, udiv->src[0].reg.dimension);
+ src0_id = program->ssa_count++;
+ dst_param_init_ssa(&mov->dst[0], src0_id, udiv->src[0].reg.data_type, udiv->src[0].reg.dimension);
mov = vsir_program_iterator_next(it);
if (!(vsir_instruction_init_with_params(program, mov, &udiv->location, VSIR_OP_MOV, 1, 1)))
return VKD3D_ERROR_OUT_OF_MEMORY;
mov->src[0] = udiv->src[1];
- dst_param_init_ssa(&mov->dst[0], program->ssa_count + 1, udiv->src[1].reg.data_type, udiv->src[1].reg.dimension);
+ src1_id = program->ssa_count++;
+ dst_param_init_ssa(&mov->dst[0], src1_id, udiv->src[1].reg.data_type, udiv->src[1].reg.dimension);
+
+ mov = vsir_program_iterator_next(it);
+ if (!(vsir_instruction_init_with_params(program, mov, &udiv->location, VSIR_OP_MOVC, 1, 3)))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+
+ src_param_init_ssa(&mov->src[0], src1_id, udiv->src[1].reg.data_type, udiv->src[1].reg.dimension);
+ src_param_init_ssa(&mov->src[1], src1_id, udiv->src[1].reg.data_type, udiv->src[1].reg.dimension);
+ vsir_register_init(&mov->src[2].reg, VKD3DSPR_IMMCONST, VSIR_DATA_U32, 0);
+ mov->src[2].reg.dimension = udiv->src[1].reg.dimension;
+ mov->src[2].reg.u.immconst_u32[0] = 1;
+ mov->src[2].reg.u.immconst_u32[1] = 1;
+ mov->src[2].reg.u.immconst_u32[2] = 1;
+ mov->src[2].reg.u.immconst_u32[3] = 1;
+ if (mov->src[2].reg.dimension == VSIR_DIMENSION_VEC4)
+ mov->src[2].swizzle = VKD3D_SHADER_NO_SWIZZLE;
+ divisor_id = program->ssa_count++;
+ dst_param_init_ssa(&mov->dst[0], divisor_id, mov->src[1].reg.data_type, mov->src[1].reg.dimension);
if (udiv->dst[0].reg.type != VKD3DSPR_NULL)
{
@@ -1469,11 +1521,30 @@ static enum vkd3d_result vsir_program_lower_udiv(struct vsir_program *program,
ins->flags = udiv->flags;
- src_param_init_ssa(&ins->src[0], program->ssa_count,
- udiv->src[0].reg.data_type, udiv->src[0].reg.dimension);
- src_param_init_ssa(&ins->src[1], program->ssa_count + 1,
- udiv->src[1].reg.data_type, udiv->src[1].reg.dimension);
+ src_param_init_ssa(&ins->src[0], src0_id, udiv->src[0].reg.data_type, udiv->src[0].reg.dimension);
+ src_param_init_ssa(&ins->src[1], divisor_id, udiv->src[1].reg.data_type, udiv->src[1].reg.dimension);
+ dst_param_init_ssa(&ins->dst[0], program->ssa_count, udiv->src[1].reg.data_type, udiv->src[1].reg.dimension);
+
+ /* Like its TPF equivalent, division by zero is well-defined for
+ * VSIR_OP_UDIV, and returns UINT_MAX. Division by zero is undefined
+ * for VSIR_OP_UDIV_SIMPLE and VSIR_OP_UREM, so handle it here. */
+ ins = vsir_program_iterator_next(it);
+ if (!(vsir_instruction_init_with_params(program, ins, &udiv->location, VSIR_OP_MOVC, 1, 3)))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+
+ src_param_init_ssa(&ins->src[0], src1_id, udiv->src[1].reg.data_type, udiv->src[1].reg.dimension);
+ src_param_init_ssa(&ins->src[1], program->ssa_count, udiv->src[1].reg.data_type, udiv->src[1].reg.dimension);
+ vsir_register_init(&ins->src[2].reg, VKD3DSPR_IMMCONST, VSIR_DATA_U32, 0);
+ ins->src[2].reg.dimension = udiv->src[1].reg.dimension;
+ ins->src[2].reg.u.immconst_u32[0] = UINT_MAX;
+ ins->src[2].reg.u.immconst_u32[1] = UINT_MAX;
+ ins->src[2].reg.u.immconst_u32[2] = UINT_MAX;
+ ins->src[2].reg.u.immconst_u32[3] = UINT_MAX;
+ if (ins->src[2].reg.dimension == VSIR_DIMENSION_VEC4)
+ ins->src[2].swizzle = VKD3D_SHADER_NO_SWIZZLE;
ins->dst[0] = udiv->dst[0];
+
+ ++program->ssa_count;
}
if (udiv->dst[1].reg.type != VKD3DSPR_NULL)
@@ -1485,15 +1556,30 @@ static enum vkd3d_result vsir_program_lower_udiv(struct vsir_program *program,
ins->flags = udiv->flags;
- src_param_init_ssa(&ins->src[0], program->ssa_count,
- udiv->src[0].reg.data_type, udiv->src[0].reg.dimension);
- src_param_init_ssa(&ins->src[1], program->ssa_count + 1,
- udiv->src[1].reg.data_type, udiv->src[1].reg.dimension);
+ src_param_init_ssa(&ins->src[0], src0_id, udiv->src[0].reg.data_type, udiv->src[0].reg.dimension);
+ src_param_init_ssa(&ins->src[1], divisor_id, udiv->src[1].reg.data_type, udiv->src[1].reg.dimension);
+ dst_param_init_ssa(&ins->dst[0], program->ssa_count, udiv->src[1].reg.data_type, udiv->src[1].reg.dimension);
+
+ ins = vsir_program_iterator_next(it);
+ if (!(vsir_instruction_init_with_params(program, ins, &udiv->location, VSIR_OP_MOVC, 1, 3)))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+
+ src_param_init_ssa(&ins->src[0], src1_id, udiv->src[1].reg.data_type, udiv->src[1].reg.dimension);
+ src_param_init_ssa(&ins->src[1], program->ssa_count, udiv->src[1].reg.data_type, udiv->src[1].reg.dimension);
+ vsir_register_init(&ins->src[2].reg, VKD3DSPR_IMMCONST, VSIR_DATA_U32, 0);
+ ins->src[2].reg.dimension = udiv->src[1].reg.dimension;
+ ins->src[2].reg.u.immconst_u32[0] = UINT_MAX;
+ ins->src[2].reg.u.immconst_u32[1] = UINT_MAX;
+ ins->src[2].reg.u.immconst_u32[2] = UINT_MAX;
+ ins->src[2].reg.u.immconst_u32[3] = UINT_MAX;
+ if (ins->src[2].reg.dimension == VSIR_DIMENSION_VEC4)
+ ins->src[2].swizzle = VKD3D_SHADER_NO_SWIZZLE;
ins->dst[0] = udiv->dst[1];
+
+ ++program->ssa_count;
}
vkd3d_shader_instruction_make_nop(udiv);
- program->ssa_count += 2;
return VKD3D_OK;
}
@@ -1648,6 +1734,7 @@ static enum vkd3d_result vsir_program_lower_texcrd(struct vsir_program *program,
static enum vkd3d_result vsir_program_lower_texld_sm1(struct vsir_program *program,
struct vkd3d_shader_instruction *ins, struct vkd3d_shader_message_context *message_context)
{
+ const struct vkd3d_shader_descriptor_info1 *sampler;
unsigned int idx = ins->src[0].reg.idx[0].offset;
struct vkd3d_shader_src_param *srcs;
@@ -1660,7 +1747,7 @@ static enum vkd3d_result vsir_program_lower_texld_sm1(struct vsir_program *progr
return VKD3D_ERROR_NOT_IMPLEMENTED;
}
- if (!(srcs = vsir_program_get_src_params(program, 3)))
+ if (!(srcs = vsir_program_get_src_params(program, 4)))
return VKD3D_ERROR_OUT_OF_MEMORY;
/* Note we run before I/O normalization. */
@@ -1668,9 +1755,26 @@ static enum vkd3d_result vsir_program_lower_texld_sm1(struct vsir_program *progr
vsir_src_param_init_resource(&srcs[1], idx, idx);
vsir_src_param_init_sampler(&srcs[2], idx, idx);
- ins->opcode = VSIR_OP_SAMPLE;
- ins->src = srcs;
- ins->src_count = 3;
+ sampler = vkd3d_shader_find_descriptor(&program->descriptors, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, idx);
+ if (sampler->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_SAMPLER_COMPARISON_MODE)
+ {
+ enum vkd3d_shader_swizzle_component ref = vsir_swizzle_get_component(srcs[0].swizzle, 2);
+
+ ins->opcode = VSIR_OP_SAMPLE_C;
+ ins->src = srcs;
+ ins->src_count = 4;
+
+ srcs[1].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X);
+
+ srcs[3] = srcs[0];
+ srcs[3].swizzle = vkd3d_shader_create_swizzle(ref, ref, ref, ref);
+ }
+ else
+ {
+ ins->opcode = VSIR_OP_SAMPLE;
+ ins->src = srcs;
+ ins->src_count = 3;
+ }
return VKD3D_OK;
}
@@ -1730,6 +1834,7 @@ static enum vkd3d_result vsir_program_lower_texldp(struct vsir_program *program,
static enum vkd3d_result vsir_program_lower_texld(struct vsir_program *program,
struct vkd3d_shader_instruction *tex, struct vkd3d_shader_message_context *message_context)
{
+ const struct vkd3d_shader_descriptor_info1 *sampler;
unsigned int idx = tex->src[1].reg.idx[0].offset;
struct vkd3d_shader_src_param *srcs;
@@ -1743,7 +1848,21 @@ static enum vkd3d_result vsir_program_lower_texld(struct vsir_program *program,
vsir_src_param_init_resource(&srcs[1], idx, idx);
vsir_src_param_init_sampler(&srcs[2], idx, idx);
- if (!tex->flags)
+ sampler = vkd3d_shader_find_descriptor(&program->descriptors, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, idx);
+ if (sampler->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_SAMPLER_COMPARISON_MODE)
+ {
+ enum vkd3d_shader_swizzle_component ref = vsir_swizzle_get_component(srcs[0].swizzle, 2);
+
+ tex->opcode = VSIR_OP_SAMPLE_C;
+ tex->src = srcs;
+ tex->src_count = 4;
+
+ srcs[1].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X);
+
+ srcs[3] = srcs[0];
+ srcs[3].swizzle = vkd3d_shader_create_swizzle(ref, ref, ref, ref);
+ }
+ else if (!tex->flags)
{
tex->opcode = VSIR_OP_SAMPLE;
tex->src = srcs;
@@ -1825,6 +1944,7 @@ static enum vkd3d_result vsir_program_lower_texldl(struct vsir_program *program,
static enum vkd3d_result vsir_program_lower_tex(struct vsir_program *program, struct vkd3d_shader_instruction *ins)
{
+ const struct vkd3d_shader_descriptor_info1 *sampler;
unsigned int idx = ins->dst[0].reg.idx[0].offset;
struct vkd3d_shader_src_param *srcs;
@@ -1834,7 +1954,7 @@ static enum vkd3d_result vsir_program_lower_tex(struct vsir_program *program, st
/* We run before I/O normalization. */
VKD3D_ASSERT(program->normalisation_level < VSIR_NORMALISED_SM6);
- if (!(srcs = vsir_program_get_src_params(program, 3)))
+ if (!(srcs = vsir_program_get_src_params(program, 4)))
return VKD3D_ERROR_OUT_OF_MEMORY;
vsir_src_param_init(&srcs[0], VKD3DSPR_TEXTURE, VSIR_DATA_F32, 1);
@@ -1845,9 +1965,24 @@ static enum vkd3d_result vsir_program_lower_tex(struct vsir_program *program, st
vsir_src_param_init_resource(&srcs[1], idx, idx);
vsir_src_param_init_sampler(&srcs[2], idx, idx);
- ins->opcode = VSIR_OP_SAMPLE;
- ins->src = srcs;
- ins->src_count = 3;
+ sampler = vkd3d_shader_find_descriptor(&program->descriptors, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, idx);
+ if (sampler->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_SAMPLER_COMPARISON_MODE)
+ {
+ ins->opcode = VSIR_OP_SAMPLE_C;
+ ins->src = srcs;
+ ins->src_count = 4;
+
+ srcs[1].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X);
+
+ srcs[3] = srcs[0];
+ srcs[3].swizzle = VKD3D_SHADER_SWIZZLE(Z, Z, Z, Z);
+ }
+ else
+ {
+ ins->opcode = VSIR_OP_SAMPLE;
+ ins->src = srcs;
+ ins->src_count = 3;
+ }
return VKD3D_OK;
}
@@ -2039,6 +2174,72 @@ static enum vkd3d_result vsir_program_lower_d3dbc_instructions(struct vsir_progr
return VKD3D_OK;
}
+static enum vkd3d_result vsir_program_lower_modifiers(struct vsir_program *program,
+ struct vsir_transformation_context *ctx)
+{
+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions), new_it;
+ struct vkd3d_shader_instruction *ins, *new_ins;
+ unsigned int i, j;
+
+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it))
+ {
+ for (i = 0; i < ins->src_count; ++i)
+ {
+ enum vkd3d_shader_opcode new_opcodes[2] = {VSIR_OP_NOP, VSIR_OP_NOP};
+ struct vkd3d_shader_src_param *src = &ins->src[i];
+
+ /* TODO: support other modifiers, including destination modifiers. */
+ switch (src->modifiers)
+ {
+ case VKD3DSPSM_ABS:
+ new_opcodes[0] = VSIR_OP_ABS;
+ break;
+
+ case VKD3DSPSM_NEG:
+ new_opcodes[0] = data_type_is_integer(src->reg.data_type) ? VSIR_OP_INEG : VSIR_OP_NEG;
+ break;
+
+ case VKD3DSPSM_ABSNEG:
+ new_opcodes[0] = VSIR_OP_ABS;
+ new_opcodes[1] = VSIR_OP_NEG;
+ break;
+
+ default:
+ continue;
+ }
+
+ for (j = 0; j < 2 && new_opcodes[j] != VSIR_OP_NOP; ++j)
+ {
+ if (!(new_ins = vsir_program_iterator_insert_before(&it, &new_it, 1)))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+ ins = vsir_program_iterator_current(&it);
+
+ if (!vsir_instruction_init_with_params(program, new_ins, &ins->location, new_opcodes[j], 1, 1))
+ {
+ vkd3d_shader_instruction_make_nop(new_ins);
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+ }
+
+ new_ins->src[0] = *src;
+ new_ins->src[0].modifiers = VKD3DSPSM_NONE;
+
+ dst_param_init_ssa(&new_ins->dst[0], program->ssa_count, src->reg.data_type, src->reg.dimension);
+ src_param_init_ssa(src, program->ssa_count, src->reg.data_type, src->reg.dimension);
+
+ if (data_type_is_64_bit(src->reg.data_type))
+ {
+ new_ins->dst[0].write_mask = vsir_write_mask_64_from_32(new_ins->dst[0].write_mask);
+ src->swizzle = vsir_swizzle_64_from_32(src->swizzle);
+ }
+
+ ++program->ssa_count;
+ }
+ }
+ }
+
+ return VKD3D_OK;
+}
+
static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *program,
struct vsir_transformation_context *ctx)
{
@@ -3936,6 +4137,19 @@ static void cf_flattener_set_error(struct cf_flattener *flattener, enum vkd3d_re
flattener->status = error;
}
+static struct vkd3d_shader_instruction *cf_flattener_instruction_append(struct cf_flattener *flattener)
+{
+ struct vkd3d_shader_instruction *ins;
+
+ if (!(ins = shader_instruction_array_append(&flattener->instructions)))
+ {
+ ERR("Failed to allocate instructions.\n");
+ cf_flattener_set_error(flattener, VKD3D_ERROR_OUT_OF_MEMORY);
+ return NULL;
+ }
+ return ins;
+}
+
static bool cf_flattener_copy_instruction(struct cf_flattener *flattener,
const struct vkd3d_shader_instruction *instruction)
{
@@ -3944,7 +4158,7 @@ static bool cf_flattener_copy_instruction(struct cf_flattener *flattener,
if (instruction->opcode == VSIR_OP_NOP)
return true;
- if (!(dst_ins = shader_instruction_array_append(&flattener->instructions)))
+ if (!(dst_ins = cf_flattener_instruction_append(flattener)))
return false;
*dst_ins = *instruction;
@@ -3975,7 +4189,7 @@ static void cf_flattener_emit_label(struct cf_flattener *flattener, unsigned int
{
struct vkd3d_shader_instruction *ins;
- if (!(ins = shader_instruction_array_append(&flattener->instructions)))
+ if (!(ins = cf_flattener_instruction_append(flattener)))
return;
if (!vsir_instruction_init_label(ins, &flattener->location, label_id, flattener->program))
{
@@ -3993,7 +4207,7 @@ static struct vkd3d_shader_src_param *cf_flattener_emit_branch(struct cf_flatten
struct vkd3d_shader_src_param *src_params, *false_branch_param;
struct vkd3d_shader_instruction *ins;
- if (!(ins = shader_instruction_array_append(&flattener->instructions)))
+ if (!(ins = cf_flattener_instruction_append(flattener)))
return NULL;
vsir_instruction_init(ins, &flattener->location, VSIR_OP_BRANCH);
@@ -4144,13 +4358,6 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte
is_hull_shader = program->shader_version.type == VKD3D_SHADER_TYPE_HULL;
after_declarations_section = is_hull_shader;
- if (!shader_instruction_array_reserve(&flattener->instructions, instructions->count + 1))
- {
- ERR("Failed to allocate instructions.\n");
- cf_flattener_set_error(flattener, VKD3D_ERROR_OUT_OF_MEMORY);
- return VKD3D_ERROR_OUT_OF_MEMORY;
- }
-
it = vsir_program_iterator(instructions);
for (instruction = vsir_program_iterator_head(&it); instruction; instruction = vsir_program_iterator_next(&it))
{
@@ -4609,16 +4816,14 @@ static enum vkd3d_result vsir_program_lower_switch_to_selection_ladder(struct vs
vsir_src_param_init_label(&dst_ins->src[0], default_label);
}
- if (!shader_instruction_array_reserve(&instructions, instructions.count + 3 * case_count - 1))
- goto fail;
-
if_label = current_label;
for (j = 0; j < case_count; ++j)
{
unsigned int fallthrough_label, case_label = label_from_src_param(&ins->src[3 + 2 * j + 1]);
- dst_ins = shader_instruction_array_append(&instructions);
+ if (!(dst_ins = shader_instruction_array_append(&instructions)))
+ goto fail;
if (!vsir_instruction_init_with_params(program, dst_ins, &ins->location, VSIR_OP_IEQ, 1, 2))
{
vkd3d_shader_instruction_make_nop(dst_ins);
@@ -4636,7 +4841,8 @@ static enum vkd3d_result vsir_program_lower_switch_to_selection_ladder(struct vs
else
fallthrough_label = block_count + 1;
- dst_ins = shader_instruction_array_append(&instructions);
+ if (!(dst_ins = shader_instruction_array_append(&instructions)))
+ goto fail;
if (!vsir_instruction_init_with_params(program, dst_ins, &ins->location, VSIR_OP_BRANCH, 0, 3))
{
vkd3d_shader_instruction_make_nop(dst_ins);
@@ -4660,7 +4866,8 @@ static enum vkd3d_result vsir_program_lower_switch_to_selection_ladder(struct vs
}
else
{
- dst_ins = shader_instruction_array_append(&instructions);
+ if (!(dst_ins = shader_instruction_array_append(&instructions)))
+ goto fail;
if (!vsir_instruction_init_with_params(program, dst_ins, &ins->location, VSIR_OP_LABEL, 0, 1))
{
vkd3d_shader_instruction_make_nop(dst_ins);
@@ -4755,8 +4962,8 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps_in_function(
struct vsir_program_iterator it_begin = *it;
struct ssas_to_temps_alloc alloc = {0};
struct vkd3d_shader_instruction *ins;
- size_t phi_count, incoming_count;
unsigned int current_label = 0;
+ size_t phi_count;
VKD3D_ASSERT(program->cf_type == VSIR_CF_BLOCKS);
@@ -4770,7 +4977,6 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps_in_function(
goto fail;
phi_count = 0;
- incoming_count = 0;
for (ins = vsir_program_iterator_current(it); ins; ins = vsir_program_iterator_next(it))
{
unsigned int j, temp_idx;
@@ -4819,8 +5025,6 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps_in_function(
incoming->dst = ins->dst;
alloc.table[ins->dst->reg.idx[0].offset] = temp_idx;
-
- ++incoming_count;
}
materialize_ssas_to_temps_process_reg(program, &alloc, &ins->dst->reg);
@@ -4829,9 +5033,6 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps_in_function(
if (!phi_count)
goto done;
- if (!shader_instruction_array_reserve(&program->instructions, program->instructions.count + incoming_count))
- goto fail;
-
*it = it_begin;
for (ins = vsir_program_iterator_current(it); ins; ins = vsir_program_iterator_next(it))
@@ -4856,7 +5057,8 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps_in_function(
case VSIR_OP_SWITCH_MONOLITHIC:
info = &block_info[current_label - 1];
- mov_ins = vsir_program_iterator_insert_before_and_move(it, info->incoming_count);
+ if (!(mov_ins = vsir_program_iterator_insert_before_and_move(it, info->incoming_count)))
+ goto fail;
VKD3D_ASSERT(mov_ins);
for (j = 0; j < info->incoming_count; ++j)
@@ -6782,23 +6984,14 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_block(struct vsir_cfg *cfg
struct vsir_cfg_emit_target *target = cfg->target;
struct vkd3d_shader_instruction *ins, *end, *dst;
struct vsir_program_iterator it;
- size_t ins_count = 0;
it = block->begin;
end = vsir_program_iterator_current(&block->end);
for (ins = vsir_program_iterator_current(&it); ins != end; ins = vsir_program_iterator_next(&it))
{
- ++ins_count;
- }
-
- if (!shader_instruction_array_reserve(&target->instructions, target->instructions.count + ins_count))
- return VKD3D_ERROR_OUT_OF_MEMORY;
-
- it = block->begin;
- for (ins = vsir_program_iterator_current(&it); ins != end; ins = vsir_program_iterator_next(&it))
- {
- dst = shader_instruction_array_append(&target->instructions);
+ if (!(dst = shader_instruction_array_append(&target->instructions)))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
VKD3D_ASSERT(dst);
*dst = *ins;
}
@@ -6822,10 +7015,8 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_loop(struct vsir_cfg *cfg,
if ((ret = vsir_cfg_structure_list_emit(cfg, &loop->body, loop->idx)) < 0)
return ret;
- if (!shader_instruction_array_reserve(&target->instructions, target->instructions.count + 5))
+ if (!(ins = shader_instruction_array_append(&target->instructions)))
return VKD3D_ERROR_OUT_OF_MEMORY;
-
- ins = shader_instruction_array_append(&target->instructions);
vsir_instruction_init(ins, &no_loc, VSIR_OP_ENDLOOP);
/* Add a trampoline to implement multilevel jumping depending on the stored
@@ -6840,7 +7031,8 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_loop(struct vsir_cfg *cfg,
* we have to reach an outer loop, so we keep breaking. */
const unsigned int inner_break_target = loop->idx << 1;
- ins = shader_instruction_array_append(&target->instructions);
+ if (!(ins = shader_instruction_array_append(&target->instructions)))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
if (!vsir_instruction_init_with_params(cfg->program, ins, &no_loc, VSIR_OP_IEQ, 1, 2))
{
vkd3d_shader_instruction_make_nop(ins);
@@ -6853,7 +7045,8 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_loop(struct vsir_cfg *cfg,
src_param_init_temp_uint(&ins->src[0], target->jump_target_temp_idx);
src_param_init_const_uint(&ins->src[1], outer_continue_target);
- ins = shader_instruction_array_append(&target->instructions);
+ if (!(ins = shader_instruction_array_append(&target->instructions)))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
if (!vsir_instruction_init_with_params(cfg->program, ins, &no_loc, VSIR_OP_CONTINUEP, 0, 1))
{
vkd3d_shader_instruction_make_nop(ins);
@@ -6875,7 +7068,8 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_loop(struct vsir_cfg *cfg,
src_param_init_temp_uint(&ins->src[0], target->jump_target_temp_idx);
src_param_init_const_uint(&ins->src[1], inner_break_target);
- ins = shader_instruction_array_append(&target->instructions);
+ if (!(ins = shader_instruction_array_append(&target->instructions)))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
if (!vsir_instruction_init_with_params(cfg->program, ins, &no_loc, VSIR_OP_BREAKP, 0, 1))
{
vkd3d_shader_instruction_make_nop(ins);
@@ -6971,12 +7165,10 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_jump(struct vsir_cfg *cfg,
vkd3d_unreachable();
}
- if (!shader_instruction_array_reserve(&target->instructions, target->instructions.count + 2))
- return VKD3D_ERROR_OUT_OF_MEMORY;
-
if (jump->needs_launcher)
{
- ins = shader_instruction_array_append(&target->instructions);
+ if (!(ins = shader_instruction_array_append(&target->instructions)))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
if (!vsir_instruction_init_with_params(cfg->program, ins, &no_loc, VSIR_OP_MOV, 1, 1))
{
vkd3d_shader_instruction_make_nop(ins);
@@ -6987,7 +7179,8 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_jump(struct vsir_cfg *cfg,
src_param_init_const_uint(&ins->src[0], jump_target);
}
- ins = shader_instruction_array_append(&target->instructions);
+ if (!(ins = shader_instruction_array_append(&target->instructions)))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
if (!vsir_instruction_init_with_params(cfg->program, ins, &no_loc, opcode, 0, !!jump->condition))
{
vkd3d_shader_instruction_make_nop(ins);
@@ -8097,35 +8290,41 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro
struct vkd3d_shader_instruction *ins = vsir_program_iterator_current(it);
struct vkd3d_shader_location loc = ins->location;
uint32_t ssa_factor = program->ssa_count++;
- uint32_t ssa_temp, ssa_temp2;
+ uint32_t ssa_temp, ssa_temp2, ssa_temp3;
switch (mode)
{
case VKD3D_SHADER_FOG_FRAGMENT_LINEAR:
/* We generate the following code:
*
- * add sr0, FOG_END, -vFOG.x
- * mul_sat srFACTOR, sr0, FOG_SCALE
+ * neg sr0, vFOG.x
+ * add sr1, FOG_END, sr0
+ * mul_sat srFACTOR, sr1, FOG_SCALE
*/
- if (!(ins = vsir_program_iterator_insert_before_and_move(it, 4)))
+ if (!(ins = vsir_program_iterator_insert_before_and_move(it, 6)))
return VKD3D_ERROR_OUT_OF_MEMORY;
ssa_temp = program->ssa_count++;
+ ssa_temp2 = program->ssa_count++;
- vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_ADD, 1, 2);
+ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_NEG, 1, 1);
dst_param_init_ssa_float(&ins->dst[0], ssa_temp);
+ vsir_src_param_init(&ins->src[0], VKD3DSPR_INPUT, VSIR_DATA_F32, 1);
+ ins->src[0].reg.idx[0].offset = fog_signature_idx;
+ ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4;
+ ins->src[0].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X);
+ ins = vsir_program_iterator_next(it);
+
+ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_ADD, 1, 2);
+ dst_param_init_ssa_float(&ins->dst[0], ssa_temp2);
src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_FOG_END, VSIR_DATA_F32);
- vsir_src_param_init(&ins->src[1], VKD3DSPR_INPUT, VSIR_DATA_F32, 1);
- ins->src[1].reg.idx[0].offset = fog_signature_idx;
- ins->src[1].reg.dimension = VSIR_DIMENSION_VEC4;
- ins->src[1].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X);
- ins->src[1].modifiers = VKD3DSPSM_NEG;
+ src_param_init_ssa_float(&ins->src[1], ssa_temp);
ins = vsir_program_iterator_next(it);
vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MUL, 1, 2);
dst_param_init_ssa_float(&ins->dst[0], ssa_factor);
ins->dst[0].modifiers = VKD3DSPDM_SATURATE;
- src_param_init_ssa_float(&ins->src[0], ssa_temp);
+ src_param_init_ssa_float(&ins->src[0], ssa_temp2);
src_param_init_parameter(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_FOG_SCALE, VSIR_DATA_F32);
ins = vsir_program_iterator_next(it);
@@ -8135,12 +8334,14 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro
/* We generate the following code:
*
* mul sr0, FOG_SCALE, vFOG.x
- * exp_sat srFACTOR, -sr0
+ * neg sr1, sr0
+ * exp_sat srFACTOR, sr1
*/
- if (!(ins = vsir_program_iterator_insert_before_and_move(it, 4)))
+ if (!(ins = vsir_program_iterator_insert_before_and_move(it, 6)))
return VKD3D_ERROR_OUT_OF_MEMORY;
ssa_temp = program->ssa_count++;
+ ssa_temp2 = program->ssa_count++;
vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MUL, 1, 2);
dst_param_init_ssa_float(&ins->dst[0], ssa_temp);
@@ -8151,11 +8352,15 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro
ins->src[1].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X);
ins = vsir_program_iterator_next(it);
+ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_NEG, 1, 1);
+ dst_param_init_ssa_float(&ins->dst[0], ssa_temp2);
+ src_param_init_ssa_float(&ins->src[0], ssa_temp);
+ ins = vsir_program_iterator_next(it);
+
vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_EXP, 1, 1);
dst_param_init_ssa_float(&ins->dst[0], ssa_factor);
ins->dst[0].modifiers = VKD3DSPDM_SATURATE;
- src_param_init_ssa_float(&ins->src[0], ssa_temp);
- ins->src[0].modifiers = VKD3DSPSM_NEG;
+ src_param_init_ssa_float(&ins->src[0], ssa_temp2);
ins = vsir_program_iterator_next(it);
break;
@@ -8164,13 +8369,15 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro
*
* mul sr0, FOG_SCALE, vFOG.x
* mul sr1, sr0, sr0
- * exp_sat srFACTOR, -sr1
+ * neg sr2, sr1
+ * exp_sat srFACTOR, sr2
*/
- if (!(ins = vsir_program_iterator_insert_before_and_move(it, 5)))
+ if (!(ins = vsir_program_iterator_insert_before_and_move(it, 7)))
return VKD3D_ERROR_OUT_OF_MEMORY;
ssa_temp = program->ssa_count++;
ssa_temp2 = program->ssa_count++;
+ ssa_temp3 = program->ssa_count++;
vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MUL, 1, 2);
dst_param_init_ssa_float(&ins->dst[0], ssa_temp);
@@ -8187,11 +8394,15 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro
src_param_init_ssa_float(&ins->src[1], ssa_temp);
ins = vsir_program_iterator_next(it);
+ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_NEG, 1, 1);
+ dst_param_init_ssa_float(&ins->dst[0], ssa_temp3);
+ src_param_init_ssa_float(&ins->src[0], ssa_temp2);
+ ins = vsir_program_iterator_next(it);
+
vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_EXP, 1, 1);
dst_param_init_ssa_float(&ins->dst[0], ssa_factor);
ins->dst[0].modifiers = VKD3DSPDM_SATURATE;
- src_param_init_ssa_float(&ins->src[0], ssa_temp2);
- ins->src[0].modifiers = VKD3DSPSM_NEG;
+ src_param_init_ssa_float(&ins->src[0], ssa_temp3);
ins = vsir_program_iterator_next(it);
break;
@@ -8201,21 +8412,28 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro
/* We generate the following code:
*
- * add sr0, FRAG_COLOUR, -FOG_COLOUR
- * mad oC0, sr0, srFACTOR, FOG_COLOUR
+ * neg sr0, FOG_COLOUR
+ * add sr1, FRAG_COLOUR, sr0
+ * mad oC0, sr1, srFACTOR, FOG_COLOUR
*/
+ ssa_temp = program->ssa_count++;
+ ssa_temp2 = program->ssa_count++;
+
+ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_NEG, 1, 1);
+ dst_param_init_ssa_float4(&ins->dst[0], ssa_temp);
+ src_param_init_parameter_vec4(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_FOG_COLOUR, VSIR_DATA_F32);
+ ins = vsir_program_iterator_next(it);
vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_ADD, 1, 2);
- dst_param_init_ssa_float4(&ins->dst[0], program->ssa_count++);
+ dst_param_init_ssa_float4(&ins->dst[0], ssa_temp2);
src_param_init_temp_float4(&ins->src[0], colour_temp);
- src_param_init_parameter_vec4(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_FOG_COLOUR, VSIR_DATA_F32);
- ins->src[1].modifiers = VKD3DSPSM_NEG;
+ src_param_init_ssa_float4(&ins->src[1], ssa_temp);
ins = vsir_program_iterator_next(it);
vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MAD, 1, 3);
dst_param_init_output(&ins->dst[0], VSIR_DATA_F32, colour_signature_idx,
program->output_signature.elements[colour_signature_idx].mask);
- src_param_init_ssa_float4(&ins->src[0], program->ssa_count - 1);
+ src_param_init_ssa_float4(&ins->src[0], ssa_temp2);
src_param_init_ssa_float(&ins->src[1], ssa_factor);
src_param_init_parameter_vec4(&ins->src[2], VKD3D_SHADER_PARAMETER_NAME_FOG_COLOUR, VSIR_DATA_F32);
ins = vsir_program_iterator_next(it);
@@ -8560,6 +8778,7 @@ static bool vsir_src_is_masked(enum vkd3d_shader_opcode opcode, unsigned int src
case VSIR_OP_MOVC:
case VSIR_OP_MSAD: /* FIXME: Is this correct? */
case VSIR_OP_MUL:
+ case VSIR_OP_NEG:
case VSIR_OP_NEO:
case VSIR_OP_NEU:
case VSIR_OP_NOT:
@@ -11482,6 +11701,18 @@ static void vsir_validate_float_elementwise_operation(struct validation_context
vsir_validate_elementwise_operation(ctx, instruction, types);
}
+static void vsir_validate_float_or_double_elementwise_operation(struct validation_context *ctx,
+ const struct vkd3d_shader_instruction *instruction)
+{
+ static const bool types[VSIR_DATA_TYPE_COUNT] =
+ {
+ [VSIR_DATA_F32] = true,
+ [VSIR_DATA_F64] = true,
+ };
+
+ vsir_validate_elementwise_operation(ctx, instruction, types);
+}
+
static void vsir_validate_integer_elementwise_operation(struct validation_context *ctx,
const struct vkd3d_shader_instruction *instruction)
{
@@ -12534,7 +12765,7 @@ struct vsir_validator_instruction_desc
static const struct vsir_validator_instruction_desc vsir_validator_instructions[] =
{
- [VSIR_OP_ABS] = {1, 1, vsir_validate_float_elementwise_operation},
+ [VSIR_OP_ABS] = {1, 1, vsir_validate_float_or_double_elementwise_operation},
[VSIR_OP_ACOS] = {1, 1, vsir_validate_float_elementwise_operation},
[VSIR_OP_ADD] = {1, 2, vsir_validate_float_elementwise_operation},
[VSIR_OP_AND] = {1, 2, vsir_validate_logic_elementwise_operation},
@@ -12629,6 +12860,7 @@ static const struct vsir_validator_instruction_desc vsir_validator_instructions[
[VSIR_OP_MAX] = {1, 2, vsir_validate_float_elementwise_operation},
[VSIR_OP_MIN] = {1, 2, vsir_validate_float_elementwise_operation},
[VSIR_OP_MUL] = {1, 2, vsir_validate_float_elementwise_operation},
+ [VSIR_OP_NEG] = {1, 1, vsir_validate_float_or_double_elementwise_operation},
[VSIR_OP_NEO] = {1, 2, vsir_validate_float_comparison_operation},
[VSIR_OP_NEU] = {1, 2, vsir_validate_float_comparison_operation},
[VSIR_OP_NOP] = {0, 0, vsir_validate_nop},
@@ -12899,8 +13131,6 @@ static void vsir_transform_(
struct vsir_transformation_context *ctx, const char *step_name,
enum vkd3d_result (*step)(struct vsir_program *program, struct vsir_transformation_context *ctx))
{
- ctx->progress = false;
-
if (ctx->result < 0)
return;
@@ -13050,6 +13280,7 @@ static bool vsir_instruction_has_side_effects(const struct vkd3d_shader_instruct
case VSIR_OP_MOVC:
case VSIR_OP_MSAD:
case VSIR_OP_MUL:
+ case VSIR_OP_NEG:
case VSIR_OP_NEO:
case VSIR_OP_NEU:
case VSIR_OP_NOP:
@@ -13317,6 +13548,229 @@ static enum vkd3d_result vsir_program_dce(struct vsir_program *program,
return VKD3D_OK;
}
+/*
+ * This pass attempts to reduce redundant MOVs (copies) by combining them with
+ * adjacent instructions. The resulting MOVs will subsequently be removed by
+ * DCE if no longer used.
+ *
+ * We attempt to combine two instructions, not necessarily consecutive,
+ * of the form
+ *
+ * mov aaa.bbb, ccc
+ * XXX ..., aaa.ddd
+ *
+ * into
+ *
+ * XXX ..., ccc
+ *
+ * There are many constraints, including:
+ *
+ * - The ddd components of aaa must not have been modified between the
+ * two instructions.
+ * Currently, only SSA is supported, so this is trivial.
+ *
+ * - The relevant components of ccc must not have been modified between the
+ * two instructions.
+ * Currently, we require ccc to be a read-only register, so this is trivial.
+ *
+ * - ddd must be a subset of bbb. This is again trivial for SSA.
+ */
+
+struct vsir_copy_propagation_state
+{
+ /* The sources for each SSA register, if it was written by a
+ * MOV instruction, or NULL if not.
+ *
+ * We do not add or remove instructions in this pass, only modifying their
+ * content, so these pointers are safe to store.
+ */
+ const struct vkd3d_shader_instruction **ssa_sources;
+};
+
+static bool is_read_only(const struct vsir_program *program, enum vkd3d_shader_register_type type)
+{
+ switch (type)
+ {
+ case VKD3DSPR_ADDR:
+ case VKD3DSPR_IDXTEMP:
+ case VKD3DSPR_LOOP:
+ case VKD3DSPR_TEMP:
+ case VKD3DSPR_TEMPFLOAT16:
+ return false;
+
+ case VKD3DSPR_TEXTURE:
+ return vkd3d_shader_ver_ge(&program->shader_version, 1, 4);
+
+ /* Not applicable since they're not numeric or can't be sources. */
+ case VKD3DSPR_ATTROUT:
+ case VKD3DSPR_COLOROUT:
+ case VKD3DSPR_COMBINED_SAMPLER:
+ case VKD3DSPR_COUNT:
+ case VKD3DSPR_DEPTHOUT:
+ case VKD3DSPR_DEPTHOUTGE:
+ case VKD3DSPR_DEPTHOUTLE:
+ case VKD3DSPR_FUNCTIONBODY:
+ case VKD3DSPR_FUNCTIONPOINTER:
+ case VKD3DSPR_GROUPSHAREDMEM:
+ case VKD3DSPR_INVALID:
+ case VKD3DSPR_LABEL:
+ case VKD3DSPR_NULL:
+ case VKD3DSPR_OUTPUT:
+ case VKD3DSPR_OUTSTENCILREF:
+ case VKD3DSPR_PREDICATE:
+ case VKD3DSPR_RASTERIZER:
+ case VKD3DSPR_RASTOUT:
+ case VKD3DSPR_RESOURCE:
+ case VKD3DSPR_SAMPLER:
+ case VKD3DSPR_STREAM:
+ case VKD3DSPR_TEXCRDOUT:
+ case VKD3DSPR_UAV:
+ return false;
+
+ case VKD3DSPR_CONST:
+ case VKD3DSPR_CONSTBOOL:
+ case VKD3DSPR_CONSTBUFFER:
+ case VKD3DSPR_CONSTINT:
+ case VKD3DSPR_COVERAGE:
+ case VKD3DSPR_FORKINSTID:
+ case VKD3DSPR_GSINSTID:
+ case VKD3DSPR_IMMCONST:
+ case VKD3DSPR_IMMCONST64:
+ case VKD3DSPR_IMMCONSTBUFFER:
+ case VKD3DSPR_INCONTROLPOINT:
+ case VKD3DSPR_INPUT:
+ case VKD3DSPR_JOININSTID:
+ case VKD3DSPR_LOCALTHREADID:
+ case VKD3DSPR_LOCALTHREADINDEX:
+ case VKD3DSPR_MISCTYPE:
+ case VKD3DSPR_OUTCONTROLPOINT:
+ case VKD3DSPR_OUTPOINTID:
+ case VKD3DSPR_PARAMETER:
+ case VKD3DSPR_PATCHCONST:
+ case VKD3DSPR_POINT_COORD:
+ case VKD3DSPR_PRIMID:
+ case VKD3DSPR_SAMPLEMASK:
+ case VKD3DSPR_SSA:
+ case VKD3DSPR_TESSCOORD:
+ case VKD3DSPR_THREADGROUPID:
+ case VKD3DSPR_THREADID:
+ case VKD3DSPR_UNDEF:
+ case VKD3DSPR_WAVELANECOUNT:
+ case VKD3DSPR_WAVELANEINDEX:
+ return true;
+ }
+
+ vkd3d_unreachable();
+}
+
+static bool can_propagate_ssa_source(const struct vsir_program *program, const struct vkd3d_shader_instruction *ins)
+{
+ if (ins->opcode != VSIR_OP_MOV)
+ return false;
+ /* TODO: Propagate copies for other register types. */
+ if (ins->dst[0].reg.type != VKD3DSPR_SSA)
+ return false;
+ if (ins->dst[0].modifiers || ins->dst[0].shift)
+ return false;
+
+ /* TODO: We can perform copy-prop for read-write register types, but we
+ * have to be sure that the register wasn't modified between the two
+ * instructions. */
+ if (!is_read_only(program, ins->src[0].reg.type))
+ return false;
+ for (unsigned int k = 0; k < ins->src[0].reg.idx_count; ++k)
+ {
+ if (ins->src[0].reg.idx[k].rel_addr && !is_read_only(program, ins->src[0].reg.idx[k].rel_addr->reg.type))
+ return false;
+ }
+
+ /* Don't bother with other source modifiers for now; the HLSL compiler
+ * doesn't emit them. */
+ switch (ins->src[0].modifiers)
+ {
+ case VKD3DSPSM_ABS:
+ case VKD3DSPSM_ABSNEG:
+ case VKD3DSPSM_NEG:
+ case VKD3DSPSM_NONE:
+ break;
+
+ default:
+ return false;
+ }
+ return true;
+}
+
+static enum vkd3d_result vsir_program_copy_propagation(struct vsir_program *program,
+ struct vsir_transformation_context *ctx)
+{
+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions);
+ struct vsir_copy_propagation_state state = {0};
+ struct vkd3d_shader_instruction *ins;
+
+ if (!(state.ssa_sources = vkd3d_calloc(program->ssa_count, sizeof(*state.ssa_sources))))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+
+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it))
+ {
+ for (unsigned int j = 0; j < ins->src_count; ++j)
+ {
+ struct vkd3d_shader_src_param *src = &ins->src[j];
+ const struct vkd3d_shader_src_param *mov_src;
+ const struct vkd3d_shader_instruction *mov;
+ enum vsir_data_type data_type;
+ uint32_t new_swizzle = 0;
+
+ if (src->reg.type != VKD3DSPR_SSA)
+ continue;
+ if (data_type_is_64_bit(src->reg.data_type))
+ continue;
+ if (!(mov = state.ssa_sources[src->reg.idx[0].offset]))
+ continue;
+ mov_src = &mov->src[0];
+ data_type = src->reg.data_type;
+
+ src->reg = mov_src->reg;
+ src->reg.data_type = data_type;
+
+ if (!shader_register_clone_relative_addresses(&src->reg, program))
+ {
+ vkd3d_free(state.ssa_sources);
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+ }
+
+ for (unsigned int k = 0; k < 4; ++k)
+ {
+ unsigned int s = vsir_swizzle_get_component(src->swizzle, k);
+
+ if (mov_src->reg.type == VKD3DSPR_IMMCONST)
+ src->reg.u.immconst_u32[k] = mov_src->reg.u.immconst_u32[s];
+ else
+ vsir_swizzle_set_component(&new_swizzle, k, vsir_swizzle_get_component(mov_src->swizzle, s));
+ }
+ if (mov_src->reg.type != VKD3DSPR_IMMCONST)
+ src->swizzle = new_swizzle;
+
+ if (src->modifiers == VKD3DSPSM_NONE)
+ src->modifiers = mov_src->modifiers;
+ else if (src->modifiers == VKD3DSPSM_NEG && mov_src->modifiers == VKD3DSPSM_ABS)
+ src->modifiers = VKD3DSPSM_ABSNEG;
+ else if (src->modifiers == VKD3DSPSM_NEG && mov_src->modifiers == VKD3DSPSM_ABSNEG)
+ src->modifiers = VKD3DSPSM_ABS;
+ else if (src->modifiers == VKD3DSPSM_NEG && mov_src->modifiers == VKD3DSPSM_NEG)
+ src->modifiers = VKD3DSPSM_NONE;
+ /* Otherwise no change is necessary. */
+
+ ctx->progress = true;
+ }
+
+ if (can_propagate_ssa_source(program, ins))
+ state.ssa_sources[ins->dst[0].reg.idx[0].offset] = ins;
+ }
+
+ vkd3d_free(state.ssa_sources);
+ return VKD3D_OK;
+}
+
enum vkd3d_result vsir_program_optimize(struct vsir_program *program, uint64_t config_flags,
const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context)
{
@@ -13325,7 +13779,11 @@ enum vkd3d_result vsir_program_optimize(struct vsir_program *program, uint64_t c
vsir_transformation_context_init(&ctx, program, config_flags, compile_info, message_context);
do
+ {
+ ctx.progress = false;
+ vsir_transform(&ctx, vsir_program_copy_propagation);
vsir_transform(&ctx, vsir_program_dce);
+ }
while (ctx.progress);
if (TRACE_ON())
@@ -13388,6 +13846,7 @@ enum vkd3d_result vsir_program_transform(struct vsir_program *program, uint64_t
struct vsir_transformation_context ctx;
vsir_transformation_context_init(&ctx, program, config_flags, compile_info, message_context);
+ vsir_transform(&ctx, vsir_program_lower_modifiers);
vsir_transform(&ctx, vsir_program_lower_instructions);
if (program->shader_version.major >= 6)
diff --git a/libs/vkd3d/libs/vkd3d-shader/msl.c b/libs/vkd3d/libs/vkd3d-shader/msl.c
index 8a89dcabd5e..fc136e3ac98 100644
--- a/libs/vkd3d/libs/vkd3d-shader/msl.c
+++ b/libs/vkd3d/libs/vkd3d-shader/msl.c
@@ -602,25 +602,11 @@ static void msl_print_src_with_type(struct vkd3d_string_buffer *buffer, struct m
if (reg->dimension == VSIR_DIMENSION_VEC4)
msl_print_swizzle(str, vsir_src->swizzle, mask);
- switch (vsir_src->modifiers)
+ if (vsir_src->modifiers)
{
- case VKD3DSPSM_NONE:
- break;
- case VKD3DSPSM_NEG:
- vkd3d_string_buffer_printf(buffer, "-%s", str->buffer);
- break;
- case VKD3DSPSM_ABS:
- vkd3d_string_buffer_printf(buffer, "abs(%s)", str->buffer);
- break;
- case VKD3DSPSM_ABSNEG:
- vkd3d_string_buffer_printf(buffer, "-abs(%s)", str->buffer);
- break;
- default:
- vkd3d_string_buffer_printf(buffer, "<unhandled modifier %#x>(%s)",
- vsir_src->modifiers, str->buffer);
- msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
- "Internal compiler error: Unhandled source modifier(s) %#x.", vsir_src->modifiers);
- break;
+ vkd3d_string_buffer_printf(buffer, "<unhandled modifier %#x>(%s)", vsir_src->modifiers, str->buffer);
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
+ "Internal compiler error: Unhandled source modifier(s) %#x.", vsir_src->modifiers);
}
if (str != buffer)
@@ -1472,6 +1458,9 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d
switch (ins->opcode)
{
+ case VSIR_OP_ABS:
+ msl_intrinsic(gen, ins, "abs");
+ break;
case VSIR_OP_ACOS:
msl_intrinsic(gen, ins, "acos");
break;
@@ -1624,6 +1613,7 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d
msl_relop(gen, ins, "!=");
break;
case VSIR_OP_INEG:
+ case VSIR_OP_NEG:
msl_unary_op(gen, ins, "-");
break;
case VSIR_OP_ITOF:
diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c
index 3deca660b00..31271660e4f 100644
--- a/libs/vkd3d/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c
@@ -989,7 +989,7 @@ struct vkd3d_spirv_builder
uint32_t type_bool_id;
uint32_t type_void_id;
uint32_t scope_subgroup_id;
- uint32_t numeric_type_ids[VKD3D_SHADER_COMPONENT_TYPE_COUNT][VKD3D_VEC4_SIZE];
+ uint32_t numeric_type_ids[VSIR_DATA_TYPE_COUNT][VKD3D_VEC4_SIZE];
struct vkd3d_spirv_stream debug_stream; /* debug instructions */
struct vkd3d_spirv_stream annotation_stream; /* decoration instructions */
@@ -2116,20 +2116,6 @@ static uint32_t vkd3d_spirv_build_op_fdiv(struct vkd3d_spirv_builder *builder,
SpvOpFDiv, result_type, operand0, operand1);
}
-static uint32_t vkd3d_spirv_build_op_fnegate(struct vkd3d_spirv_builder *builder,
- uint32_t result_type, uint32_t operand)
-{
- return vkd3d_spirv_build_op_tr1(builder, &builder->function_stream,
- SpvOpFNegate, result_type, operand);
-}
-
-static uint32_t vkd3d_spirv_build_op_snegate(struct vkd3d_spirv_builder *builder,
- uint32_t result_type, uint32_t operand)
-{
- return vkd3d_spirv_build_op_tr1(builder, &builder->function_stream,
- SpvOpSNegate, result_type, operand);
-}
-
static uint32_t vkd3d_spirv_build_op_and(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint32_t operand0, uint32_t operand1)
{
@@ -2478,19 +2464,6 @@ static uint32_t vkd3d_spirv_build_op_group_nonuniform_broadcast_first(struct vkd
result_type, vkd3d_spirv_get_op_scope_subgroup(builder), val_id);
}
-static uint32_t vkd3d_spirv_build_op_glsl_std450_tr1(struct vkd3d_spirv_builder *builder,
- enum GLSLstd450 op, uint32_t result_type, uint32_t operand)
-{
- uint32_t id = vkd3d_spirv_get_glsl_std450_instr_set(builder);
- return vkd3d_spirv_build_op_ext_inst(builder, result_type, id, op, &operand, 1);
-}
-
-static uint32_t vkd3d_spirv_build_op_glsl_std450_fabs(struct vkd3d_spirv_builder *builder,
- uint32_t result_type, uint32_t operand)
-{
- return vkd3d_spirv_build_op_glsl_std450_tr1(builder, GLSLstd450FAbs, result_type, operand);
-}
-
static uint32_t vkd3d_spirv_build_op_glsl_std450_max(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint32_t x, uint32_t y)
{
@@ -2518,71 +2491,69 @@ static uint32_t vkd3d_spirv_build_op_glsl_std450_nclamp(struct vkd3d_spirv_build
GLSLstd450NClamp, operands, ARRAY_SIZE(operands));
}
-static uint32_t spirv_get_type_id_for_component_type(struct vkd3d_spirv_builder *builder,
- enum vkd3d_shader_component_type component_type, unsigned int component_count)
+static uint32_t spirv_get_type_id(struct vkd3d_spirv_builder *builder,
+ enum vsir_data_type data_type, unsigned int component_count)
{
uint32_t scalar_id, type_id;
- VKD3D_ASSERT(component_type < VKD3D_SHADER_COMPONENT_TYPE_COUNT);
+ VKD3D_ASSERT(data_type < VSIR_DATA_TYPE_COUNT);
if (!component_count || component_count > VKD3D_VEC4_SIZE)
{
ERR("Invalid component count %u.\n", component_count);
return 0;
}
- if ((type_id = builder->numeric_type_ids[component_type][component_count - 1]))
+ if ((type_id = builder->numeric_type_ids[data_type][component_count - 1]))
return type_id;
if (component_count == 1)
{
- switch (component_type)
+ switch (data_type)
{
- case VKD3D_SHADER_COMPONENT_VOID:
- type_id = vkd3d_spirv_get_op_type_void(builder);
+ case VSIR_DATA_BOOL:
+ type_id = vkd3d_spirv_get_op_type_bool(builder);
break;
- case VKD3D_SHADER_COMPONENT_FLOAT:
+
+ case VSIR_DATA_F32:
type_id = vkd3d_spirv_get_op_type_float(builder, 32);
break;
- case VKD3D_SHADER_COMPONENT_INT:
- case VKD3D_SHADER_COMPONENT_UINT:
- type_id = vkd3d_spirv_get_op_type_int(builder, 32, component_type == VKD3D_SHADER_COMPONENT_INT);
+
+ case VSIR_DATA_F64:
+ type_id = vkd3d_spirv_get_op_type_float(builder, 64);
break;
- case VKD3D_SHADER_COMPONENT_BOOL:
- type_id = vkd3d_spirv_get_op_type_bool(builder);
+
+ case VSIR_DATA_I32:
+ case VSIR_DATA_U32:
+ type_id = vkd3d_spirv_get_op_type_int(builder, 32, data_type == VSIR_DATA_I32);
break;
- case VKD3D_SHADER_COMPONENT_DOUBLE:
- type_id = vkd3d_spirv_get_op_type_float(builder, 64);
+
+ case VSIR_DATA_I64:
+ case VSIR_DATA_U64:
+ type_id = vkd3d_spirv_get_op_type_int(builder, 64, data_type == VSIR_DATA_I64);
break;
- case VKD3D_SHADER_COMPONENT_INT64:
- case VKD3D_SHADER_COMPONENT_UINT64:
- type_id = vkd3d_spirv_get_op_type_int(builder, 64, component_type == VKD3D_SHADER_COMPONENT_INT64);
+
+ case VSIR_DATA_UNUSED:
+ type_id = vkd3d_spirv_get_op_type_void(builder);
break;
+
default:
- FIXME("Unhandled component type %#x.\n", component_type);
+ FIXME("Unhandled data type \"%s\" (%#x).\n",
+ vsir_data_type_get_name(data_type, "<unknown>"), data_type);
return 0;
}
}
else
{
- VKD3D_ASSERT(component_type != VKD3D_SHADER_COMPONENT_VOID);
- scalar_id = spirv_get_type_id_for_component_type(builder, component_type, 1);
+ VKD3D_ASSERT(data_type != VSIR_DATA_UNUSED);
+ scalar_id = spirv_get_type_id(builder, data_type, 1);
type_id = vkd3d_spirv_get_op_type_vector(builder, scalar_id, component_count);
}
- builder->numeric_type_ids[component_type][component_count - 1] = type_id;
+ builder->numeric_type_ids[data_type][component_count - 1] = type_id;
return type_id;
}
-static uint32_t spirv_get_type_id(struct vkd3d_spirv_builder *builder,
- enum vsir_data_type data_type, unsigned int component_count)
-{
- enum vkd3d_shader_component_type component_type;
-
- component_type = vkd3d_component_type_from_data_type(data_type);
- return spirv_get_type_id_for_component_type(builder, component_type, component_count);
-}
-
static void vkd3d_spirv_builder_init(struct vkd3d_spirv_builder *builder,
const char *entry_point, const char *source_name)
{
@@ -4846,74 +4817,23 @@ static void spirv_compiler_emit_execution_mode1(struct spirv_compiler *compiler,
spirv_compiler_emit_execution_mode(compiler, mode, &literal, 1);
}
-static uint32_t spirv_compiler_emit_abs(struct spirv_compiler *compiler,
- const struct vkd3d_shader_register *reg, uint32_t write_mask, uint32_t val_id)
-{
- struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
- uint32_t type_id;
-
- type_id = spirv_compiler_get_type_id_for_reg(compiler, reg, write_mask);
- if (data_type_is_floating_point(reg->data_type))
- return vkd3d_spirv_build_op_glsl_std450_fabs(builder, type_id, val_id);
-
- FIXME("Unhandled data type %#x.\n", reg->data_type);
- return val_id;
-}
-
-static uint32_t spirv_compiler_emit_neg(struct spirv_compiler *compiler,
- const struct vkd3d_shader_register *reg, uint32_t write_mask, uint32_t val_id)
-{
- struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
- uint32_t type_id;
-
- type_id = spirv_compiler_get_type_id_for_reg(compiler, reg, write_mask);
- if (data_type_is_floating_point(reg->data_type))
- return vkd3d_spirv_build_op_fnegate(builder, type_id, val_id);
- else if (data_type_is_integer(reg->data_type))
- return vkd3d_spirv_build_op_snegate(builder, type_id, val_id);
-
- FIXME("Unhandled data type %#x.\n", reg->data_type);
- return val_id;
-}
-
-static uint32_t spirv_compiler_emit_src_modifier(struct spirv_compiler *compiler,
- const struct vkd3d_shader_register *reg, uint32_t write_mask,
- enum vkd3d_shader_src_modifier modifier, uint32_t val_id)
-{
- switch (modifier)
- {
- case VKD3DSPSM_NONE:
- break;
- case VKD3DSPSM_NEG:
- return spirv_compiler_emit_neg(compiler, reg, write_mask, val_id);
- case VKD3DSPSM_ABS:
- return spirv_compiler_emit_abs(compiler, reg, write_mask, val_id);
- case VKD3DSPSM_ABSNEG:
- val_id = spirv_compiler_emit_abs(compiler, reg, write_mask, val_id);
- return spirv_compiler_emit_neg(compiler, reg, write_mask, val_id);
- default:
- FIXME("Unhandled src modifier %#x.\n", modifier);
- break;
- }
-
- return val_id;
-}
-
static uint32_t spirv_compiler_emit_load_src(struct spirv_compiler *compiler,
const struct vkd3d_shader_src_param *src, uint32_t write_mask)
{
- uint32_t val_id;
+ if (src->modifiers)
+ spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED,
+ "Unhandled source modifier(s) %#x.", src->modifiers);
- val_id = spirv_compiler_emit_load_reg(compiler, &src->reg, src->swizzle, write_mask);
- return spirv_compiler_emit_src_modifier(compiler, &src->reg, write_mask, src->modifiers, val_id);
+ return spirv_compiler_emit_load_reg(compiler, &src->reg, src->swizzle, write_mask);
}
static uint32_t spirv_compiler_emit_load_src_with_type(struct spirv_compiler *compiler,
- const struct vkd3d_shader_src_param *src, uint32_t write_mask, enum vkd3d_shader_component_type component_type)
+ const struct vkd3d_shader_src_param *src, uint32_t write_mask, enum vsir_data_type data_type)
{
struct vkd3d_shader_src_param src_param = *src;
- src_param.reg.data_type = vsir_data_type_from_component_type(component_type);
+ src_param.reg.data_type = data_type;
+
return spirv_compiler_emit_load_src(compiler, &src_param, write_mask);
}
@@ -5081,10 +5001,8 @@ static void spirv_compiler_emit_store_dst(struct spirv_compiler *compiler,
}
static void spirv_compiler_emit_store_dst_swizzled(struct spirv_compiler *compiler,
- const struct vkd3d_shader_dst_param *dst, uint32_t val_id,
- enum vkd3d_shader_component_type component_type, uint32_t swizzle)
+ const struct vkd3d_shader_dst_param *dst, uint32_t val_id, enum vsir_data_type data_type, uint32_t swizzle)
{
- enum vsir_data_type data_type = vsir_data_type_from_component_type(component_type);
struct vkd3d_shader_dst_param typed_dst = *dst;
val_id = spirv_compiler_emit_swizzle(compiler, val_id,
@@ -5096,23 +5014,17 @@ static void spirv_compiler_emit_store_dst_swizzled(struct spirv_compiler *compil
}
static void spirv_compiler_emit_store_dst_components(struct spirv_compiler *compiler,
- const struct vkd3d_shader_dst_param *dst, enum vkd3d_shader_component_type component_type,
- uint32_t *component_ids)
+ const struct vkd3d_shader_dst_param *dst, enum vsir_data_type data_type, uint32_t *component_ids)
{
unsigned int component_count = vsir_write_mask_component_count(dst->write_mask);
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
uint32_t type_id, dst_type_id, val_id;
- type_id = spirv_get_type_id_for_component_type(builder, component_type, component_count);
+ type_id = spirv_get_type_id(builder, data_type, component_count);
if (component_count > 1)
- {
- val_id = vkd3d_spirv_build_op_composite_construct(builder,
- type_id, component_ids, component_count);
- }
+ val_id = vkd3d_spirv_build_op_composite_construct(builder, type_id, component_ids, component_count);
else
- {
val_id = *component_ids;
- }
dst_type_id = spirv_get_type_id(builder, dst->reg.data_type, component_count);
if (dst_type_id != type_id)
@@ -5122,8 +5034,7 @@ static void spirv_compiler_emit_store_dst_components(struct spirv_compiler *comp
}
static void spirv_compiler_emit_store_dst_scalar(struct spirv_compiler *compiler,
- const struct vkd3d_shader_dst_param *dst, uint32_t val_id,
- enum vkd3d_shader_component_type component_type, uint32_t swizzle)
+ const struct vkd3d_shader_dst_param *dst, uint32_t val_id, enum vsir_data_type data_type, uint32_t swizzle)
{
unsigned int component_count = vsir_write_mask_component_count(dst->write_mask);
uint32_t component_ids[VKD3D_VEC4_SIZE];
@@ -5137,7 +5048,7 @@ static void spirv_compiler_emit_store_dst_scalar(struct spirv_compiler *compiler
component_ids[i] = val_id;
}
- spirv_compiler_emit_store_dst_components(compiler, dst, component_type, component_ids);
+ spirv_compiler_emit_store_dst_components(compiler, dst, data_type, component_ids);
}
static void spirv_compiler_decorate_builtin(struct spirv_compiler *compiler,
@@ -5229,7 +5140,7 @@ static void spirv_compiler_decorate_builtin(struct spirv_compiler *compiler,
}
static void spirv_compiler_emit_interpolation_decorations(struct spirv_compiler *compiler,
- enum vkd3d_shader_component_type component_type, uint32_t id, enum vkd3d_shader_interpolation_mode mode)
+ enum vsir_data_type data_type, uint32_t id, enum vkd3d_shader_interpolation_mode mode)
{
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
@@ -5238,7 +5149,7 @@ static void spirv_compiler_emit_interpolation_decorations(struct spirv_compiler
case VKD3DSIM_NONE:
/* VUID-StandaloneSpirv-Flat-04744: integer or double types must be
* decorated 'Flat' for fragment shaders. */
- if (compiler->shader_type != VKD3D_SHADER_TYPE_PIXEL || component_type == VKD3D_SHADER_COMPONENT_FLOAT)
+ if (compiler->shader_type != VKD3D_SHADER_TYPE_PIXEL || data_type == VSIR_DATA_F32)
break;
/* fall through */
case VKD3DSIM_CONSTANT:
@@ -5724,7 +5635,6 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler,
unsigned int component_idx, input_component_count;
const struct signature_element *signature_element;
const struct shader_signature *shader_signature;
- enum vkd3d_shader_component_type component_type;
enum vkd3d_shader_register_type sysval_reg_type;
const struct vkd3d_spirv_builtin *builtin;
enum vkd3d_shader_sysval_semantic sysval;
@@ -5782,13 +5692,11 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler,
if (builtin)
{
data_type = builtin->data_type;
- component_type = vkd3d_component_type_from_data_type(data_type);
input_component_count = builtin->component_count;
}
else
{
- component_type = signature_element->component_type;
- data_type = vsir_data_type_from_component_type(component_type);
+ data_type = vsir_data_type_from_component_type(signature_element->component_type);
input_component_count = vsir_write_mask_component_count(signature_element->mask);
}
@@ -5841,8 +5749,8 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler,
if (component_idx)
vkd3d_spirv_build_op_decorate1(builder, input_id, SpvDecorationComponent, component_idx);
- spirv_compiler_emit_interpolation_decorations(compiler, component_type, input_id,
- signature_element->interpolation_mode);
+ spirv_compiler_emit_interpolation_decorations(compiler, data_type,
+ input_id, signature_element->interpolation_mode);
}
var_id = input_id;
@@ -6879,7 +6787,7 @@ static const struct vkd3d_spirv_resource_type *spirv_compiler_enable_resource_ty
return resource_type_info;
}
-static SpvImageFormat image_format_for_image_read(enum vkd3d_shader_component_type data_type)
+static SpvImageFormat image_format_for_image_read(enum vsir_data_type data_type)
{
/* The following formats are supported by Direct3D 11 hardware for UAV
* typed loads. A newer hardware may support more formats for UAV typed
@@ -6887,11 +6795,11 @@ static SpvImageFormat image_format_for_image_read(enum vkd3d_shader_component_ty
*/
switch (data_type)
{
- case VKD3D_SHADER_COMPONENT_FLOAT:
+ case VSIR_DATA_F32:
return SpvImageFormatR32f;
- case VKD3D_SHADER_COMPONENT_INT:
+ case VSIR_DATA_I32:
return SpvImageFormatR32i;
- case VKD3D_SHADER_COMPONENT_UINT:
+ case VSIR_DATA_U32:
return SpvImageFormatR32ui;
default:
FIXME("Unhandled type %#x.\n", data_type);
@@ -6901,8 +6809,7 @@ static SpvImageFormat image_format_for_image_read(enum vkd3d_shader_component_ty
static uint32_t spirv_compiler_get_image_type_id(struct spirv_compiler *compiler,
const struct vkd3d_shader_register *reg, const struct vkd3d_shader_register_range *range,
- const struct vkd3d_spirv_resource_type *resource_type_info, enum vkd3d_shader_component_type data_type,
- bool raw_structured)
+ const struct vkd3d_spirv_resource_type *resource_type_info, enum vsir_data_type data_type, bool raw_structured)
{
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
const struct vkd3d_shader_descriptor_info1 *d;
@@ -6923,15 +6830,15 @@ static uint32_t spirv_compiler_get_image_type_id(struct spirv_compiler *compiler
vkd3d_spirv_enable_capability(builder, SpvCapabilityStorageImageReadWithoutFormat);
}
- sampled_type_id = spirv_get_type_id_for_component_type(builder, data_type, 1);
- return vkd3d_spirv_get_op_type_image(builder, sampled_type_id, resource_type_info->dim,
- 2, resource_type_info->arrayed, resource_type_info->ms,
- reg->type == VKD3DSPR_UAV ? 2 : 1, format);
+ sampled_type_id = spirv_get_type_id(builder, data_type, 1);
+
+ return vkd3d_spirv_get_op_type_image(builder, sampled_type_id, resource_type_info->dim, 2,
+ resource_type_info->arrayed, resource_type_info->ms, reg->type == VKD3DSPR_UAV ? 2 : 1, format);
}
static void spirv_compiler_emit_combined_sampler_declarations(struct spirv_compiler *compiler,
const struct vkd3d_shader_register *resource, const struct vkd3d_shader_register_range *resource_range,
- enum vkd3d_shader_resource_type resource_type, enum vkd3d_shader_component_type sampled_type,
+ enum vkd3d_shader_resource_type resource_type, enum vsir_data_type sampled_type,
unsigned int structure_stride, bool raw, const struct vkd3d_spirv_resource_type *resource_type_info)
{
const struct vkd3d_shader_interface_info *shader_interface = &compiler->shader_interface;
@@ -6992,7 +6899,7 @@ static void spirv_compiler_emit_combined_sampler_declarations(struct spirv_compi
symbol.id = var_id;
symbol.descriptor_array = NULL;
symbol.info.resource.range = *resource_range;
- symbol.info.resource.sampled_type = vsir_data_type_from_component_type(sampled_type);
+ symbol.info.resource.sampled_type = sampled_type;
symbol.info.resource.type_id = image_type_id;
symbol.info.resource.resource_type_info = resource_type_info;
symbol.info.resource.structure_stride = structure_stride;
@@ -7017,9 +6924,9 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp
uint32_t counter_type_id, type_id, var_id, counter_var_id = 0;
const struct vkd3d_spirv_resource_type *resource_type_info;
unsigned int sample_count = descriptor->sample_count;
- enum vkd3d_shader_component_type sampled_type;
struct vkd3d_symbol resource_symbol;
struct vkd3d_shader_register reg;
+ enum vsir_data_type sampled_type;
vsir_register_init(&reg, is_uav ? VKD3DSPR_UAV : VKD3DSPR_RESOURCE, VSIR_DATA_F32, 1);
reg.idx[0].offset = descriptor->register_id;
@@ -7036,7 +6943,7 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp
return;
}
- sampled_type = vkd3d_component_type_from_data_type(descriptor->resource_data_type);
+ sampled_type = descriptor->resource_data_type;
if (!is_uav && spirv_compiler_has_combined_sampler_for_resource(compiler, range))
{
@@ -7049,7 +6956,7 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp
{
uint32_t array_type_id, struct_id;
- type_id = spirv_get_type_id(builder, descriptor->resource_data_type, 1);
+ type_id = spirv_get_type_id(builder, sampled_type, 1);
array_type_id = vkd3d_spirv_get_op_type_runtime_array(builder, type_id);
vkd3d_spirv_build_op_decorate1(builder, array_type_id, SpvDecorationArrayStride, 4);
@@ -7122,7 +7029,7 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp
resource_symbol.id = var_id;
resource_symbol.descriptor_array = var_info.array_symbol;
resource_symbol.info.resource.range = *range;
- resource_symbol.info.resource.sampled_type = descriptor->resource_data_type;
+ resource_symbol.info.resource.sampled_type = sampled_type;
resource_symbol.info.resource.type_id = type_id;
resource_symbol.info.resource.resource_type_info = resource_type_info;
resource_symbol.info.resource.structure_stride = structure_stride;
@@ -7564,6 +7471,7 @@ static SpvOp spirv_compiler_map_alu_instruction(const struct vkd3d_shader_instru
{VSIR_OP_ITOF, SpvOpConvertSToF},
{VSIR_OP_ITOI, SpvOpSConvert},
{VSIR_OP_MUL, SpvOpFMul},
+ {VSIR_OP_NEG, SpvOpFNegate},
{VSIR_OP_NOT, SpvOpNot},
{VSIR_OP_OR, SpvOpBitwiseOr},
{VSIR_OP_UDIV_SIMPLE, SpvOpUDiv},
@@ -7641,14 +7549,13 @@ static void spirv_compiler_emit_bool_cast(struct spirv_compiler *compiler,
static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compiler *compiler,
const struct vkd3d_shader_instruction *instruction)
{
- uint32_t src_ids[SPIRV_MAX_SRC_COUNT], condition_id = 0, uint_max_id = 0;
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
const struct vkd3d_shader_dst_param *dst = instruction->dst;
const struct vkd3d_shader_src_param *src = instruction->src;
- unsigned int i, component_count;
+ uint32_t src_ids[SPIRV_MAX_SRC_COUNT];
uint32_t type_id, val_id;
SpvOp op = SpvOpMax;
- bool check_zero;
+ unsigned int i;
if (src->reg.data_type == VSIR_DATA_U64 && instruction->opcode == VSIR_OP_COUNTBITS)
{
@@ -7688,44 +7595,14 @@ static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compil
return VKD3D_ERROR_INVALID_SHADER;
}
- /* SPIR-V doesn't mandate a behaviour when a denominator is zero,
- * so we have an explicit check. */
- switch (instruction->opcode)
- {
- case VSIR_OP_IDIV:
- case VSIR_OP_IREM:
- case VSIR_OP_UDIV_SIMPLE:
- case VSIR_OP_UREM:
- check_zero = true;
- break;
-
- default:
- check_zero = false;
- break;
- }
-
VKD3D_ASSERT(instruction->dst_count == 1);
VKD3D_ASSERT(instruction->src_count <= SPIRV_MAX_SRC_COUNT);
- if (check_zero)
- VKD3D_ASSERT(instruction->src_count == 2);
- component_count = vsir_write_mask_component_count(dst[0].write_mask);
type_id = spirv_compiler_get_type_id_for_dst(compiler, dst);
for (i = 0; i < instruction->src_count; ++i)
src_ids[i] = spirv_compiler_emit_load_src(compiler, &src[i], dst->write_mask);
- if (check_zero)
- {
- condition_id = spirv_compiler_emit_int_to_bool(compiler,
- VKD3D_SHADER_CONDITIONAL_OP_NZ, src[1].reg.data_type, component_count, src_ids[1]);
-
- if (data_type_is_64_bit(dst[0].reg.data_type))
- uint_max_id = spirv_compiler_get_constant_uint64_vector(compiler, UINT64_MAX, component_count);
- else
- uint_max_id = spirv_compiler_get_constant_uint_vector(compiler, UINT_MAX, component_count);
- }
-
/* The SPIR-V specification states, "The resulting value is undefined if
* Shift is greater than or equal to the bit width of the components of
* Base." Direct3D applies only the lowest 5 bits of the shift.
@@ -7746,9 +7623,6 @@ static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compil
if (instruction->flags & VKD3DSI_PRECISE_XYZW)
vkd3d_spirv_build_op_decorate(builder, val_id, SpvDecorationNoContraction, NULL, 0);
- if (check_zero)
- val_id = vkd3d_spirv_build_op_select(builder, type_id, condition_id, val_id, uint_max_id);
-
spirv_compiler_emit_store_dst(compiler, dst, val_id);
return VKD3D_OK;
}
@@ -8230,16 +8104,16 @@ static void spirv_compiler_emit_bitfield_instruction(struct spirv_compiler *comp
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
const struct vkd3d_shader_dst_param *dst = instruction->dst;
const struct vkd3d_shader_src_param *src = instruction->src;
- enum vkd3d_shader_component_type component_type;
unsigned int i, j, k, src_count, size;
+ enum vsir_data_type data_type;
uint32_t write_mask;
SpvOp op;
src_count = instruction->src_count;
VKD3D_ASSERT(2 <= src_count && src_count <= ARRAY_SIZE(src_ids));
- component_type = vkd3d_component_type_from_data_type(dst->reg.data_type);
- type_id = spirv_get_type_id(builder, dst->reg.data_type, 1);
+ data_type = dst->reg.data_type;
+ type_id = spirv_get_type_id(builder, data_type, 1);
size = data_type_is_64_bit(src[src_count - 1].reg.data_type) ? 0x40 : 0x20;
mask_id = spirv_compiler_get_constant_uint(compiler, size - 1);
size_id = spirv_compiler_get_constant_uint(compiler, size);
@@ -8265,7 +8139,7 @@ static void spirv_compiler_emit_bitfield_instruction(struct spirv_compiler *comp
for (j = 0; j < src_count; ++j)
{
src_ids[src_count - j - 1] = spirv_compiler_emit_load_src_with_type(compiler,
- &src[j], write_mask, component_type);
+ &src[j], write_mask, data_type);
}
/* In SPIR-V, the last two operands are Offset and Count. */
@@ -8281,7 +8155,7 @@ static void spirv_compiler_emit_bitfield_instruction(struct spirv_compiler *comp
op, type_id, src_ids, src_count);
}
- spirv_compiler_emit_store_dst_components(compiler, dst, component_type, constituents);
+ spirv_compiler_emit_store_dst_components(compiler, dst, data_type, constituents);
}
static void spirv_compiler_emit_f16tof32(struct spirv_compiler *compiler,
@@ -8313,8 +8187,7 @@ static void spirv_compiler_emit_f16tof32(struct spirv_compiler *compiler,
scalar_type_id, result_id, 0);
}
- spirv_compiler_emit_store_dst_components(compiler,
- dst, vkd3d_component_type_from_data_type(dst->reg.data_type), components);
+ spirv_compiler_emit_store_dst_components(compiler, dst, dst->reg.data_type, components);
}
static void spirv_compiler_emit_f32tof16(struct spirv_compiler *compiler,
@@ -8349,8 +8222,7 @@ static void spirv_compiler_emit_f32tof16(struct spirv_compiler *compiler,
instr_set_id, GLSLstd450PackHalf2x16, &src_id, 1);
}
- spirv_compiler_emit_store_dst_components(compiler,
- dst, vkd3d_component_type_from_data_type(dst->reg.data_type), components);
+ spirv_compiler_emit_store_dst_components(compiler, dst, dst->reg.data_type, components);
}
static void spirv_compiler_emit_comparison_instruction(struct spirv_compiler *compiler,
@@ -8918,8 +8790,7 @@ static void spirv_compiler_prepare_image(struct spirv_compiler *compiler,
}
image->image_type_id = spirv_compiler_get_image_type_id(compiler, resource_reg, &symbol->info.resource.range,
- image->resource_type_info, vkd3d_component_type_from_data_type(image->sampled_type),
- image->structure_stride || image->raw);
+ image->resource_type_info, image->sampled_type, image->structure_stride || image->raw);
if (sampled)
{
@@ -9014,8 +8885,7 @@ static void spirv_compiler_emit_ld(struct spirv_compiler *compiler,
val_id = vkd3d_spirv_build_op_image_fetch(builder, type_id,
image.image_id, coordinate_id, operands_mask, image_operands, image_operand_count);
- spirv_compiler_emit_store_dst_swizzled(compiler, dst, val_id,
- vkd3d_component_type_from_data_type(image.sampled_type), src[1].swizzle);
+ spirv_compiler_emit_store_dst_swizzled(compiler, dst, val_id, image.sampled_type, src[1].swizzle);
}
static void spirv_compiler_emit_lod(struct spirv_compiler *compiler,
@@ -9040,8 +8910,7 @@ static void spirv_compiler_emit_lod(struct spirv_compiler *compiler,
val_id = vkd3d_spirv_build_op_image_query_lod(builder,
type_id, image.sampled_image_id, coordinate_id);
- spirv_compiler_emit_store_dst_swizzled(compiler, dst, val_id,
- vkd3d_component_type_from_data_type(image.sampled_type), resource->swizzle);
+ spirv_compiler_emit_store_dst_swizzled(compiler, dst, val_id, image.sampled_type, resource->swizzle);
}
static void spirv_compiler_emit_sample(struct spirv_compiler *compiler,
@@ -9111,8 +8980,7 @@ static void spirv_compiler_emit_sample(struct spirv_compiler *compiler,
val_id = vkd3d_spirv_build_op_image_sample(builder, op, sampled_type_id,
image.sampled_image_id, coordinate_id, operands_mask, image_operands, image_operand_count);
- spirv_compiler_emit_store_dst_swizzled(compiler, dst, val_id,
- vkd3d_component_type_from_data_type(image.sampled_type), resource->swizzle);
+ spirv_compiler_emit_store_dst_swizzled(compiler, dst, val_id, image.sampled_type, resource->swizzle);
}
static void spirv_compiler_emit_sample_c(struct spirv_compiler *compiler,
@@ -9157,8 +9025,7 @@ static void spirv_compiler_emit_sample_c(struct spirv_compiler *compiler,
image.sampled_image_id, coordinate_id, dref_id, operands_mask,
image_operands, image_operand_count);
- spirv_compiler_emit_store_dst_scalar(compiler, dst, val_id,
- vkd3d_component_type_from_data_type(image.sampled_type), src[1].swizzle);
+ spirv_compiler_emit_store_dst_scalar(compiler, dst, val_id, image.sampled_type, src[1].swizzle);
}
static void spirv_compiler_emit_gather4(struct spirv_compiler *compiler,
@@ -9230,8 +9097,7 @@ static void spirv_compiler_emit_gather4(struct spirv_compiler *compiler,
operands_mask, image_operands, image_operand_count);
}
- spirv_compiler_emit_store_dst_swizzled(compiler, dst, val_id,
- vkd3d_component_type_from_data_type(image.sampled_type), resource->swizzle);
+ spirv_compiler_emit_store_dst_swizzled(compiler, dst, val_id, image.sampled_type, resource->swizzle);
}
static uint32_t spirv_compiler_emit_raw_structured_addressing(
@@ -9293,7 +9159,7 @@ static void spirv_compiler_emit_ld_raw_structured_srv_uav(struct spirv_compiler
texel_type_id = spirv_get_type_id(builder, resource_symbol->info.resource.sampled_type, 1);
ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassUniform, texel_type_id);
- type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1);
+ type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1);
base_coordinate_id = spirv_compiler_emit_raw_structured_addressing(compiler,
type_id, resource_symbol->info.resource.structure_stride,
&src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0);
@@ -9325,7 +9191,7 @@ static void spirv_compiler_emit_ld_raw_structured_srv_uav(struct spirv_compiler
spirv_compiler_prepare_image(compiler, &image, &resource->reg, NULL, VKD3D_IMAGE_FLAG_NONE);
- type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1);
+ type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1);
base_coordinate_id = spirv_compiler_emit_raw_structured_addressing(compiler,
type_id, image.structure_stride, &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0);
@@ -9348,7 +9214,7 @@ static void spirv_compiler_emit_ld_raw_structured_srv_uav(struct spirv_compiler
type_id, val_id, 0);
}
}
- spirv_compiler_emit_store_dst_components(compiler, dst, VKD3D_SHADER_COMPONENT_UINT, constituents);
+ spirv_compiler_emit_store_dst_components(compiler, dst, VSIR_DATA_U32, constituents);
}
static void spirv_compiler_emit_ld_tgsm(struct spirv_compiler *compiler,
@@ -9388,7 +9254,7 @@ 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);
}
- spirv_compiler_emit_store_dst_components(compiler, dst, VKD3D_SHADER_COMPONENT_UINT, constituents);
+ spirv_compiler_emit_store_dst_components(compiler, dst, VSIR_DATA_U32, constituents);
}
static void spirv_compiler_emit_ld_raw_structured(struct spirv_compiler *compiler,
@@ -9430,7 +9296,7 @@ static void spirv_compiler_emit_store_uav_raw_structured(struct spirv_compiler *
type_id = spirv_get_type_id(builder, resource_symbol->info.resource.sampled_type, 1);
ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassUniform, type_id);
- type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1);
+ type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1);
base_coordinate_id = spirv_compiler_emit_raw_structured_addressing(compiler,
type_id, resource_symbol->info.resource.structure_stride,
&src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0);
@@ -9458,7 +9324,7 @@ static void spirv_compiler_emit_store_uav_raw_structured(struct spirv_compiler *
}
else
{
- type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1);
+ type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1);
spirv_compiler_prepare_image(compiler, &image, &dst->reg, NULL, VKD3D_IMAGE_FLAG_NONE);
base_coordinate_id = spirv_compiler_emit_raw_structured_addressing(compiler,
type_id, image.structure_stride, &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0);
@@ -9569,7 +9435,7 @@ static void spirv_compiler_emit_ld_uav_typed(struct spirv_compiler *compiler,
val_id = vkd3d_spirv_build_op_load(builder, type_id, ptr_id, SpvMemoryAccessMaskNone);
spirv_compiler_emit_store_dst_swizzled(compiler, dst, val_id,
- vkd3d_component_type_from_data_type(resource_symbol->info.resource.sampled_type), src[1].swizzle);
+ resource_symbol->info.resource.sampled_type, src[1].swizzle);
}
else
{
@@ -9581,8 +9447,7 @@ static void spirv_compiler_emit_ld_uav_typed(struct spirv_compiler *compiler,
val_id = vkd3d_spirv_build_op_image_read(builder, type_id,
image.image_id, coordinate_id, SpvImageOperandsMaskNone, NULL, 0);
- spirv_compiler_emit_store_dst_swizzled(compiler, dst, val_id,
- vkd3d_component_type_from_data_type(image.sampled_type), src[1].swizzle);
+ spirv_compiler_emit_store_dst_swizzled(compiler, dst, val_id, image.sampled_type, src[1].swizzle);
}
}
@@ -9608,8 +9473,8 @@ static void spirv_compiler_emit_store_uav_typed(struct spirv_compiler *compiler,
indices[0] = spirv_compiler_get_constant_uint(compiler, 0);
indices[1] = coordinate_id;
- val_id = spirv_compiler_emit_load_src_with_type(compiler, &src[1], VKD3DSP_WRITEMASK_0,
- vkd3d_component_type_from_data_type(resource_symbol->info.resource.sampled_type));
+ val_id = spirv_compiler_emit_load_src_with_type(compiler, &src[1],
+ VKD3DSP_WRITEMASK_0, resource_symbol->info.resource.sampled_type);
ptr_id = vkd3d_spirv_build_op_access_chain(builder, ptr_type_id, resource_symbol->id, indices, 2);
vkd3d_spirv_build_op_store(builder, ptr_id, val_id, SpvMemoryAccessMaskNone);
}
@@ -9620,8 +9485,7 @@ static void spirv_compiler_emit_store_uav_typed(struct spirv_compiler *compiler,
spirv_compiler_prepare_image(compiler, &image, &dst->reg, NULL, VKD3D_IMAGE_FLAG_NONE);
coordinate_mask = (1u << image.resource_type_info->coordinate_component_count) - 1;
coordinate_id = spirv_compiler_emit_load_src(compiler, &src[0], coordinate_mask);
- texel_id = spirv_compiler_emit_load_src_with_type(compiler, &src[1],
- dst->write_mask, vkd3d_component_type_from_data_type(image.sampled_type));
+ texel_id = spirv_compiler_emit_load_src_with_type(compiler, &src[1], dst->write_mask, image.sampled_type);
vkd3d_spirv_build_op_image_write(builder, image.image_id, coordinate_id, texel_id,
SpvImageOperandsMaskNone, NULL, 0);
@@ -9756,11 +9620,9 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil
const struct vkd3d_shader_src_param *src = instruction->src;
const struct vkd3d_symbol *resource_symbol = NULL;
uint32_t ptr_type_id, type_id, val_id, result_id;
- enum vkd3d_shader_component_type component_type;
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;
enum vsir_data_type data_type;
unsigned int structure_stride;
@@ -9811,7 +9673,7 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil
}
}
- type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1);
+ type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1);
if (structure_stride || raw)
{
VKD3D_ASSERT(!raw != !structure_stride);
@@ -9853,8 +9715,7 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil
}
}
- component_type = vkd3d_component_type_from_data_type(data_type);
- val_id = spirv_compiler_emit_load_src_with_type(compiler, &src[1], VKD3DSP_WRITEMASK_0, component_type);
+ val_id = spirv_compiler_emit_load_src_with_type(compiler, &src[1], VKD3DSP_WRITEMASK_0, data_type);
if (instruction->flags & VKD3DARF_VOLATILE)
{
@@ -9863,17 +9724,13 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil
vsir_opcode_get_name(instruction->opcode, "<unknown>"), instruction->opcode);
}
- 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, memory_semantic);
+ operands[i++] = spirv_compiler_get_constant_uint(compiler, SpvMemorySemanticsMaskNone);
if (instruction->src_count >= 3)
{
- 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++] = spirv_compiler_get_constant_uint(compiler, SpvMemorySemanticsMaskNone);
+ operands[i++] = spirv_compiler_emit_load_src_with_type(compiler, &src[2], VKD3DSP_WRITEMASK_0, data_type);
}
operands[i++] = val_id;
result_id = vkd3d_spirv_build_op_trv(builder, &builder->function_stream,
@@ -10648,6 +10505,7 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler,
case VSIR_OP_ITOF:
case VSIR_OP_ITOI:
case VSIR_OP_MUL:
+ case VSIR_OP_NEG:
case VSIR_OP_NOT:
case VSIR_OP_OR:
case VSIR_OP_UDIV_SIMPLE:
diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
index 2b5badb8871..821c639ee16 100644
--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
@@ -950,6 +950,7 @@ static bool vkd3d_shader_signature_from_shader_signature(struct vkd3d_shader_sig
struct vkd3d_shader_scan_context
{
const struct vkd3d_shader_version *version;
+ const struct vkd3d_shader_d3dbc_source_info *d3dbc_source_info;
struct vkd3d_shader_scan_descriptor_info1 *scan_descriptor_info;
size_t descriptors_size;
@@ -1017,6 +1018,7 @@ static void vkd3d_shader_scan_context_init(struct vkd3d_shader_scan_context *con
context->location.line = 2; /* Line 1 is the version token. */
context->api_version = VKD3D_SHADER_API_VERSION_1_2;
context->combined_sampler_info = combined_sampler_info;
+ context->d3dbc_source_info = vkd3d_find_struct(compile_info->next, D3DBC_SOURCE_INFO);
for (i = 0; i < compile_info->option_count; ++i)
{
@@ -1218,15 +1220,6 @@ static void vkd3d_shader_scan_sampler_declaration(struct vkd3d_shader_scan_conte
d->flags |= VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_SAMPLER_COMPARISON_MODE;
}
-static void vkd3d_shader_scan_combined_sampler_declaration(
- struct vkd3d_shader_scan_context *context, const struct vkd3d_shader_semantic *semantic)
-{
- vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, &semantic->resource.reg.reg,
- &semantic->resource.range, VKD3D_SHADER_RESOURCE_NONE, VSIR_DATA_UNUSED);
- vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, &semantic->resource.reg.reg,
- &semantic->resource.range, semantic->resource_type, VSIR_DATA_F32);
-}
-
const struct vkd3d_shader_descriptor_info1 *vkd3d_shader_find_descriptor(
const struct vkd3d_shader_scan_descriptor_info1 *info,
enum vkd3d_shader_descriptor_type type, unsigned int register_id)
@@ -1312,40 +1305,6 @@ static void vkd3d_shader_scan_combined_sampler_usage(struct vkd3d_shader_scan_co
s->sampler_index = sampler_idx;
}
-static void vkd3d_shader_scan_sample_instruction(struct vkd3d_shader_scan_context *context,
- const struct vkd3d_shader_register *resource, const struct vkd3d_shader_register *sampler)
-{
- unsigned int resource_idx = resource->idx[0].offset;
- unsigned int sampler_idx = sampler->idx[0].offset;
-
- vkd3d_shader_scan_combined_sampler_usage(context, resource, sampler);
-
- if (!context->scan_descriptor_info)
- return;
-
- /* Sample instructions lowered from 1.x texture instructions have no
- * DCL, so we need to add the resource if it didn't already exist.
- * Such descriptors have a fixed count, type, etc. */
-
- if (!vkd3d_shader_find_descriptor(context->scan_descriptor_info,
- VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, resource_idx))
- {
- struct vkd3d_shader_register_range range = {.first = resource_idx, .last = resource_idx};
-
- vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, resource,
- &range, VKD3D_SHADER_RESOURCE_TEXTURE_2D, VSIR_DATA_F32);
- }
-
- if (!vkd3d_shader_find_descriptor(context->scan_descriptor_info,
- VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, sampler_idx))
- {
- struct vkd3d_shader_register_range range = {.first = sampler_idx, .last = sampler_idx};
-
- vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, resource,
- &range, VKD3D_SHADER_RESOURCE_NONE, VSIR_DATA_UNUSED);
- }
-}
-
static void vkd3d_shader_scan_resource_declaration(struct vkd3d_shader_scan_context *context,
const struct vkd3d_shader_resource *resource, enum vkd3d_shader_resource_type resource_type,
enum vsir_data_type resource_data_type, unsigned int sample_count,
@@ -1403,14 +1362,9 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte
vkd3d_shader_scan_sampler_declaration(context, instruction);
break;
case VSIR_OP_DCL:
- if (instruction->declaration.semantic.resource_type == VKD3D_SHADER_RESOURCE_NONE)
- break;
-
- if (instruction->declaration.semantic.resource.reg.reg.type == VKD3DSPR_COMBINED_SAMPLER)
- {
- vkd3d_shader_scan_combined_sampler_declaration(context, &instruction->declaration.semantic);
+ if (instruction->declaration.semantic.resource_type == VKD3D_SHADER_RESOURCE_NONE
+ || instruction->declaration.semantic.resource.reg.reg.type == VKD3DSPR_COMBINED_SAMPLER)
break;
- }
/* fall through */
case VSIR_OP_DCL_UAV_TYPED:
vkd3d_shader_scan_typed_resource_declaration(context, instruction);
@@ -1564,6 +1518,7 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte
break;
case VSIR_OP_GATHER4:
case VSIR_OP_GATHER4_C:
+ case VSIR_OP_SAMPLE:
case VSIR_OP_SAMPLE_B:
case VSIR_OP_SAMPLE_C:
case VSIR_OP_SAMPLE_C_LZ:
@@ -1571,9 +1526,6 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte
case VSIR_OP_SAMPLE_LOD:
vkd3d_shader_scan_combined_sampler_usage(context, &instruction->src[1].reg, &instruction->src[2].reg);
break;
- case VSIR_OP_SAMPLE:
- vkd3d_shader_scan_sample_instruction(context, &instruction->src[1].reg, &instruction->src[2].reg);
- break;
case VSIR_OP_GATHER4_PO:
case VSIR_OP_GATHER4_PO_C:
vkd3d_shader_scan_combined_sampler_usage(context, &instruction->src[2].reg, &instruction->src[3].reg);
@@ -1714,7 +1666,6 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh
struct vkd3d_shader_scan_context context;
struct vkd3d_shader_instruction *ins;
int ret = VKD3D_OK;
- unsigned int i;
descriptor_info = vkd3d_find_struct(compile_info->next, SCAN_DESCRIPTOR_INFO);
if (descriptor_info)
@@ -1729,6 +1680,9 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh
add_descriptor_info = true;
}
+ if (program->has_descriptor_info)
+ add_descriptor_info = false;
+
tessellation_info = vkd3d_find_struct(compile_info->next, SCAN_HULL_SHADER_TESSELLATION_INFO);
thread_group_size_info = vkd3d_find_struct(compile_info->next, SCAN_THREAD_GROUP_SIZE_INFO);
@@ -1747,21 +1701,6 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh
break;
}
- for (i = 0; i < ARRAY_SIZE(program->flat_constant_count); ++i)
- {
- struct vkd3d_shader_register_range range = {.space = 0, .first = i, .last = i};
- struct vkd3d_shader_register reg = {.idx[0].offset = i, .idx_count = 1};
- unsigned int size = program->flat_constant_count[i];
- struct vkd3d_shader_descriptor_info1 *d;
-
- if (size)
- {
- if ((d = vkd3d_shader_scan_add_descriptor(&context, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV,
- &reg, &range, VKD3D_SHADER_RESOURCE_BUFFER, VSIR_DATA_U32)))
- d->buffer_size = size * 16;
- }
- }
-
if (!ret && signature_info)
{
if (!vkd3d_shader_signature_from_shader_signature(&signature_info->input, &program->input_signature)
diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
index df0eb2ff789..c70096f1f75 100644
--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -503,6 +503,7 @@ enum vkd3d_shader_opcode
VSIR_OP_MOVC,
VSIR_OP_MSAD,
VSIR_OP_MUL,
+ VSIR_OP_NEG,
VSIR_OP_NEO,
VSIR_OP_NEU,
VSIR_OP_NOP,
@@ -878,8 +879,7 @@ enum vkd3d_shader_uav_flags
enum vkd3d_shader_atomic_rmw_flags
{
- VKD3DARF_SEQ_CST = 0x1,
- VKD3DARF_VOLATILE = 0x2,
+ VKD3DARF_VOLATILE = 0x1,
};
enum vkd3d_tessellator_domain
@@ -1590,6 +1590,7 @@ struct vsir_program
struct vkd3d_shader_scan_descriptor_info1 descriptors;
bool has_descriptor_info;
+ size_t descriptors_size;
unsigned int parameter_count;
const struct vkd3d_shader_parameter1 *parameters;
@@ -1597,7 +1598,6 @@ struct vsir_program
unsigned int input_control_point_count, output_control_point_count;
struct vsir_thread_group_size thread_group_size;
- unsigned int flat_constant_count[3];
unsigned int block_count; /* maximum block count in any function */
unsigned int temp_count;
unsigned int ssa_count;
@@ -1636,6 +1636,10 @@ enum vkd3d_result vsir_allocate_temp_registers(struct vsir_program *program,
enum vkd3d_result vsir_update_dcl_temps(struct vsir_program *program,
struct vkd3d_shader_message_context *message_context);
+struct vkd3d_shader_descriptor_info1 *vsir_program_add_descriptor(struct vsir_program *program,
+ enum vkd3d_shader_descriptor_type type, unsigned int register_id,
+ const struct vkd3d_shader_register_range *range,
+ enum vkd3d_shader_resource_type resource_type, enum vsir_data_type resource_data_type);
bool vsir_program_add_icb(struct vsir_program *program, struct vkd3d_shader_immediate_constant_buffer *icb);
void vsir_program_cleanup(struct vsir_program *program);
const struct vkd3d_shader_parameter1 *vsir_program_get_parameter(
@@ -1883,42 +1887,6 @@ int hlsl_parse(const struct vkd3d_shader_compile_info *compile_info,
struct vkd3d_shader_message_context *message_context,
struct vsir_program *program, struct vkd3d_shader_code *reflection_data);
-static inline enum vkd3d_shader_component_type vkd3d_component_type_from_data_type( enum vsir_data_type data_type)
-{
- switch (data_type)
- {
- case VSIR_DATA_BOOL:
- return VKD3D_SHADER_COMPONENT_BOOL;
- case VSIR_DATA_F16:
- return VKD3D_SHADER_COMPONENT_FLOAT16;
- case VSIR_DATA_F32:
- case VSIR_DATA_SNORM:
- case VSIR_DATA_UNORM:
- return VKD3D_SHADER_COMPONENT_FLOAT;
- case VSIR_DATA_F64:
- return VKD3D_SHADER_COMPONENT_DOUBLE;
- case VSIR_DATA_I16:
- return VKD3D_SHADER_COMPONENT_INT16;
- case VSIR_DATA_I32:
- return VKD3D_SHADER_COMPONENT_INT;
- case VSIR_DATA_I64:
- return VKD3D_SHADER_COMPONENT_INT64;
- case VSIR_DATA_U16:
- return VKD3D_SHADER_COMPONENT_UINT16;
- case VSIR_DATA_U32:
- return VKD3D_SHADER_COMPONENT_UINT;
- case VSIR_DATA_U64:
- return VKD3D_SHADER_COMPONENT_UINT64;
- case VSIR_DATA_UNUSED:
- return VKD3D_SHADER_COMPONENT_VOID;
- default:
- FIXME("Unhandled data type %#x.\n", data_type);
- /* fall-through */
- case VSIR_DATA_MIXED:
- return VKD3D_SHADER_COMPONENT_UINT;
- }
-}
-
static inline enum vsir_data_type vsir_data_type_from_component_type(enum vkd3d_shader_component_type component_type)
{
switch (component_type)
@@ -1954,12 +1922,6 @@ static inline enum vsir_data_type vsir_data_type_from_component_type(enum vkd3d_
return VSIR_DATA_UNUSED;
}
-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_INT64
- || component_type == VKD3D_SHADER_COMPONENT_UINT64;
-}
-
static inline unsigned int vsir_write_mask_get_component_idx(uint32_t write_mask)
{
unsigned int i;
--
2.51.0