You've already forked wine-staging
mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2025-12-15 08:03:15 -08:00
5283 lines
226 KiB
Diff
5283 lines
226 KiB
Diff
From 55e98ca5107db1afba25205f66972abed9ff9f1c 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], ®s[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, ¶ms, &instr->loc);
|
|
- return true;
|
|
+ return hlsl_block_add_resource_load(ctx, block, ¶ms, &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, ¶ms, loc);
|
|
-
|
|
- return true;
|
|
+ return hlsl_block_add_resource_load(ctx, block, ¶ms, 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, ®set);
|
|
+ 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(®, 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,
|
|
- ®, &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
|
|
|