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
627 lines
30 KiB
Diff
627 lines
30 KiB
Diff
From b36e73b23646553bf2b9976a888b74a7122dc784 Mon Sep 17 00:00:00 2001
|
|
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
|
|
Date: Sat, 20 Sep 2025 07:06:08 +1000
|
|
Subject: [PATCH] Updated vkd3d to 52b9aa416bb4e8be2fb6e28ffd1234cc10db96c6.
|
|
|
|
---
|
|
libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 3 -
|
|
libs/vkd3d/libs/vkd3d-shader/dxil.c | 38 +++--
|
|
libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 1 +
|
|
libs/vkd3d/libs/vkd3d-shader/ir.c | 166 +++++++++++++++-----
|
|
libs/vkd3d/libs/vkd3d-shader/msl.c | 7 +-
|
|
libs/vkd3d/libs/vkd3d-shader/spirv.c | 12 +-
|
|
libs/vkd3d/libs/vkd3d-shader/tpf.c | 4 +-
|
|
7 files changed, 166 insertions(+), 65 deletions(-)
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
|
|
index a9195b3454a..b4e079f507e 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
|
|
@@ -2150,9 +2150,6 @@ int d3dbc_compile(struct vsir_program *program, uint64_t config_flags,
|
|
if ((result = vsir_allocate_temp_registers(program, message_context)))
|
|
return result;
|
|
|
|
- if ((result = vsir_update_dcl_temps(program, message_context)))
|
|
- return result;
|
|
-
|
|
d3dbc.program = program;
|
|
d3dbc.message_context = message_context;
|
|
switch (version->type)
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c
|
|
index 63dcbd3c08a..5d8ab701cc0 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/dxil.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c
|
|
@@ -4627,6 +4627,7 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco
|
|
struct vkd3d_shader_src_param *src_params;
|
|
enum vkd3d_shader_opcode handler_idx;
|
|
const struct sm6_value *a, *b;
|
|
+ uint32_t type_flags = 0;
|
|
uint64_t code, flags;
|
|
bool silence_warning;
|
|
unsigned int i = 0;
|
|
@@ -4668,6 +4669,8 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco
|
|
silence_warning = !(flags & ~(OB_NO_UNSIGNED_WRAP | OB_NO_SIGNED_WRAP));
|
|
break;
|
|
case VSIR_OP_ISHR:
|
|
+ type_flags |= DXIL_TYPE_SIGNED;
|
|
+ /* fall through */
|
|
case VSIR_OP_USHR:
|
|
case VSIR_OP_IDIV:
|
|
case VSIR_OP_UDIV_SIMPLE:
|
|
@@ -4692,8 +4695,8 @@ 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, 0, sm6);
|
|
- src_param_init_from_value(&src_params[1], b, 0, sm6);
|
|
+ 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;
|
|
|
|
@@ -4706,7 +4709,7 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco
|
|
* do. */
|
|
ins->flags |= VKD3DSI_SHIFT_UNMASKED;
|
|
}
|
|
- instruction_dst_param_init_ssa_scalar(ins, 0, sm6);
|
|
+ instruction_dst_param_init_ssa_scalar(ins, type_flags, sm6);
|
|
}
|
|
|
|
static const struct sm6_block *sm6_function_get_block(const struct sm6_function *function, uint64_t index,
|
|
@@ -4972,8 +4975,11 @@ static void sm6_parser_emit_dx_unary(struct sm6_parser *sm6, enum dx_intrinsic_o
|
|
instruction_dst_param_init_ssa_scalar(ins, 0, sm6);
|
|
}
|
|
|
|
-static enum vkd3d_shader_opcode map_dx_binary_op(enum dx_intrinsic_opcode op, const struct sm6_type *type)
|
|
+static enum vkd3d_shader_opcode map_dx_binary_op(enum dx_intrinsic_opcode op,
|
|
+ const struct sm6_type *type, uint32_t *type_flags)
|
|
{
|
|
+ *type_flags = 0;
|
|
+
|
|
switch (op)
|
|
{
|
|
case DX_FMAX:
|
|
@@ -4981,8 +4987,10 @@ static enum vkd3d_shader_opcode map_dx_binary_op(enum dx_intrinsic_opcode op, co
|
|
case DX_FMIN:
|
|
return type->u.width == 64 ? VSIR_OP_DMIN : VSIR_OP_MIN;
|
|
case DX_IMAX:
|
|
+ *type_flags |= DXIL_TYPE_SIGNED;
|
|
return VSIR_OP_IMAX;
|
|
case DX_IMIN:
|
|
+ *type_flags |= DXIL_TYPE_SIGNED;
|
|
return VSIR_OP_IMIN;
|
|
case DX_QUAD_READ_LANE_AT:
|
|
return VSIR_OP_QUAD_READ_LANE_AT;
|
|
@@ -5002,14 +5010,15 @@ static void sm6_parser_emit_dx_binary(struct sm6_parser *sm6, enum dx_intrinsic_
|
|
{
|
|
struct vkd3d_shader_instruction *ins = state->ins;
|
|
struct vkd3d_shader_src_param *src_params;
|
|
+ uint32_t type_flags;
|
|
|
|
- vsir_instruction_init(ins, &sm6->p.location, map_dx_binary_op(op, operands[0]->type));
|
|
+ vsir_instruction_init(ins, &sm6->p.location, map_dx_binary_op(op, operands[0]->type, &type_flags));
|
|
if (!(src_params = instruction_src_params_alloc(ins, 2, sm6)))
|
|
return;
|
|
- src_param_init_from_value(&src_params[0], operands[0], 0, sm6);
|
|
- src_param_init_from_value(&src_params[1], operands[1], 0, sm6);
|
|
+ src_param_init_from_value(&src_params[0], operands[0], type_flags, sm6);
|
|
+ src_param_init_from_value(&src_params[1], operands[1], type_flags, sm6);
|
|
|
|
- instruction_dst_param_init_ssa_scalar(ins, 0, sm6);
|
|
+ instruction_dst_param_init_ssa_scalar(ins, type_flags, sm6);
|
|
}
|
|
|
|
static enum vkd3d_shader_opcode map_dx_atomic_binop(const struct sm6_value *operand, struct sm6_parser *sm6)
|
|
@@ -7140,6 +7149,7 @@ struct sm6_cmp_info
|
|
{
|
|
enum vkd3d_shader_opcode handler_idx;
|
|
bool src_swap;
|
|
+ uint32_t type_flags;
|
|
};
|
|
|
|
static const struct sm6_cmp_info *sm6_map_cmp2_op(uint64_t code)
|
|
@@ -7169,10 +7179,10 @@ static const struct sm6_cmp_info *sm6_map_cmp2_op(uint64_t code)
|
|
[ICMP_UGE] = {VSIR_OP_UGE},
|
|
[ICMP_ULT] = {VSIR_OP_ULT},
|
|
[ICMP_ULE] = {VSIR_OP_UGE, true},
|
|
- [ICMP_SGT] = {VSIR_OP_ILT, true},
|
|
- [ICMP_SGE] = {VSIR_OP_IGE},
|
|
- [ICMP_SLT] = {VSIR_OP_ILT},
|
|
- [ICMP_SLE] = {VSIR_OP_IGE, true},
|
|
+ [ICMP_SGT] = {VSIR_OP_ILT, true, DXIL_TYPE_SIGNED},
|
|
+ [ICMP_SGE] = {VSIR_OP_IGE, false, DXIL_TYPE_SIGNED},
|
|
+ [ICMP_SLT] = {VSIR_OP_ILT, false, DXIL_TYPE_SIGNED},
|
|
+ [ICMP_SLE] = {VSIR_OP_IGE, true, DXIL_TYPE_SIGNED},
|
|
};
|
|
|
|
return (code < ARRAY_SIZE(cmp_op_table)) ? &cmp_op_table[code] : NULL;
|
|
@@ -7273,8 +7283,8 @@ static void sm6_parser_emit_cmp2(struct sm6_parser *sm6, const struct dxil_recor
|
|
|
|
if (!(src_params = instruction_src_params_alloc(ins, 2, sm6)))
|
|
return;
|
|
- src_param_init_from_value(&src_params[0 ^ cmp->src_swap], a, 0, sm6);
|
|
- src_param_init_from_value(&src_params[1 ^ cmp->src_swap], b, 0, sm6);
|
|
+ src_param_init_from_value(&src_params[0 ^ cmp->src_swap], a, cmp->type_flags, sm6);
|
|
+ src_param_init_from_value(&src_params[1 ^ cmp->src_swap], b, cmp->type_flags, sm6);
|
|
|
|
instruction_dst_param_init_ssa_scalar(ins, 0, sm6);
|
|
}
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
|
|
index eaf7d7a3d63..bb8fdb8bd60 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
|
|
@@ -9031,6 +9031,7 @@ static void vsir_src_from_hlsl_constant_value(struct vkd3d_shader_src_param *src
|
|
}
|
|
|
|
src->reg.dimension = VSIR_DIMENSION_VEC4;
|
|
+ src->swizzle = VKD3D_SHADER_NO_SWIZZLE;
|
|
for (i = 0, j = 0; i < 4; ++i)
|
|
{
|
|
if ((map_writemask & (1u << i)) && (j < width))
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c
|
|
index 506b397fb02..a242f32d824 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/ir.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c
|
|
@@ -1017,16 +1017,15 @@ static void dst_param_init_output(struct vkd3d_shader_dst_param *dst,
|
|
dst->write_mask = write_mask;
|
|
}
|
|
|
|
-void vsir_instruction_init(struct vkd3d_shader_instruction *ins, const struct vkd3d_shader_location *location,
|
|
- enum vkd3d_shader_opcode opcode)
|
|
+void vsir_instruction_init(struct vkd3d_shader_instruction *ins,
|
|
+ const struct vkd3d_shader_location *location, enum vkd3d_shader_opcode opcode)
|
|
{
|
|
- memset(ins, 0, sizeof(*ins));
|
|
- ins->location = *location;
|
|
- ins->opcode = opcode;
|
|
- ins->resource_data_type[0] = VSIR_DATA_F32;
|
|
- ins->resource_data_type[1] = VSIR_DATA_F32;
|
|
- ins->resource_data_type[2] = VSIR_DATA_F32;
|
|
- ins->resource_data_type[3] = VSIR_DATA_F32;
|
|
+ *ins = (struct vkd3d_shader_instruction)
|
|
+ {
|
|
+ .location = *location,
|
|
+ .opcode = opcode,
|
|
+ .resource_data_type = {VSIR_DATA_F32, VSIR_DATA_F32, VSIR_DATA_F32, VSIR_DATA_F32},
|
|
+ };
|
|
}
|
|
|
|
bool vsir_instruction_init_with_params(struct vsir_program *program,
|
|
@@ -1305,6 +1304,7 @@ static enum vkd3d_result vsir_program_lower_texkill(struct vsir_program *program
|
|
ins->src[1].reg.u.immconst_f32[1] = 0.0f;
|
|
ins->src[1].reg.u.immconst_f32[2] = 0.0f;
|
|
ins->src[1].reg.u.immconst_f32[3] = 0.0f;
|
|
+ ins->src[1].swizzle = VKD3D_SHADER_NO_SWIZZLE;
|
|
|
|
/* tmp.x = tmp.x || tmp.y */
|
|
/* tmp.x = tmp.x || tmp.z */
|
|
@@ -2306,6 +2306,7 @@ static enum vkd3d_result vsir_program_ensure_diffuse(struct vsir_program *progra
|
|
ins->dst[0].write_mask = VKD3DSP_WRITEMASK_ALL & ~program->diffuse_written_mask;
|
|
vsir_src_param_init(&ins->src[0], VKD3DSPR_IMMCONST, VSIR_DATA_F32, 0);
|
|
ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4;
|
|
+ ins->src[0].swizzle = VKD3D_SHADER_NO_SWIZZLE;
|
|
for (i = 0; i < 4; ++i)
|
|
ins->src[0].reg.u.immconst_f32[i] = 1.0f;
|
|
return VKD3D_OK;
|
|
@@ -2527,6 +2528,7 @@ static enum vkd3d_result vsir_program_remap_output_signature(struct vsir_program
|
|
dst_param_init_output(&ins->dst[0], VSIR_DATA_F32, e->register_index, e->mask);
|
|
vsir_src_param_init(&ins->src[0], VKD3DSPR_IMMCONST, VSIR_DATA_F32, 0);
|
|
ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4;
|
|
+ ins->src[0].swizzle = VKD3D_SHADER_NO_SWIZZLE;
|
|
ins = vsir_program_iterator_next(&it);
|
|
}
|
|
}
|
|
@@ -3669,6 +3671,7 @@ static void shader_register_normalise_flat_constants(struct vkd3d_shader_src_par
|
|
{
|
|
enum vkd3d_shader_d3dbc_constant_register set;
|
|
struct vkd3d_shader_src_param *rel_addr;
|
|
+ unsigned int c;
|
|
uint32_t index;
|
|
size_t i, j;
|
|
|
|
@@ -3683,7 +3686,11 @@ static void shader_register_normalise_flat_constants(struct vkd3d_shader_src_par
|
|
param->reg.idx_count = 0;
|
|
param->reg.dimension = VSIR_DIMENSION_VEC4;
|
|
for (j = 0; j < 4; ++j)
|
|
- param->reg.u.immconst_u32[j] = normaliser->defs[i].value[j];
|
|
+ {
|
|
+ c = vsir_swizzle_get_component(param->swizzle, j);
|
|
+ param->reg.u.immconst_u32[j] = normaliser->defs[i].value[c];
|
|
+ }
|
|
+ param->swizzle = VKD3D_SHADER_NO_SWIZZLE;
|
|
return;
|
|
}
|
|
}
|
|
@@ -7932,6 +7939,7 @@ static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *pr
|
|
ins->dst[0].write_mask = VKD3DSP_WRITEMASK_2 | VKD3DSP_WRITEMASK_3;
|
|
vsir_src_param_init(&ins->src[0], VKD3DSPR_IMMCONST, VSIR_DATA_F32, 0);
|
|
ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4;
|
|
+ ins->src[0].swizzle = VKD3D_SHADER_NO_SWIZZLE;
|
|
vsir_program_iterator_next(&it);
|
|
|
|
program->has_point_coord = true;
|
|
@@ -8932,11 +8940,13 @@ struct temp_allocator
|
|
uint32_t temp_id;
|
|
enum vkd3d_shader_register_type type;
|
|
unsigned int idx;
|
|
+ bool force_first;
|
|
} *ssa_regs, *temp_regs;
|
|
size_t ssa_count, temp_count;
|
|
unsigned int new_temp_count;
|
|
enum vkd3d_result result;
|
|
uint8_t *current_allocation;
|
|
+ bool ps_1_x;
|
|
};
|
|
|
|
static void temp_allocator_set_src(struct temp_allocator *allocator, struct vkd3d_shader_src_param *src)
|
|
@@ -9084,15 +9094,12 @@ static int temp_allocate_compare_open(const void *ptr1, const void *ptr2)
|
|
const struct temp_allocator_reg * const *reg1 = ptr1, * const *reg2 = ptr2;
|
|
int ret;
|
|
|
|
+ if ((ret = vkd3d_u32_compare((*reg1)->force_first, (*reg2)->force_first)))
|
|
+ return -ret;
|
|
if ((ret = vkd3d_u32_compare((*reg1)->liveness_reg->first_write, (*reg2)->liveness_reg->first_write)))
|
|
return ret;
|
|
if ((ret = vkd3d_u32_compare((*reg1)->liveness_reg->last_access, (*reg2)->liveness_reg->last_access)))
|
|
return ret;
|
|
- /* r0 must compare before everything else for SM 1.x PS (see comment below). */
|
|
- if ((*reg1)->type == VKD3DSPR_TEMP && (*reg1)->idx == 0)
|
|
- return -1;
|
|
- if ((*reg2)->type == VKD3DSPR_TEMP && (*reg2)->idx == 0)
|
|
- return 1;
|
|
return 0;
|
|
}
|
|
|
|
@@ -9260,6 +9267,17 @@ static enum vkd3d_result temp_allocator_compute_allocation_map(struct temp_alloc
|
|
{
|
|
reg->type = VKD3DSPR_TEMP;
|
|
reg->idx = i - allocator->ssa_count;
|
|
+
|
|
+ /* For SM 1.x ps we need to ensure that r0 is reallocated to itself,
|
|
+ * because it doubles as the output register. To do so we
|
|
+ * artificially make it alive for the whole program and make it
|
|
+ * compare before anything else. */
|
|
+ if (reg->idx == 0 && allocator->ps_1_x)
|
|
+ {
|
|
+ reg->force_first = true;
|
|
+ liveness->ssa_regs[i].first_write = 0;
|
|
+ liveness->ssa_regs[i].last_access = UINT_MAX;
|
|
+ }
|
|
}
|
|
|
|
reg->liveness_reg = &liveness->ssa_regs[i];
|
|
@@ -9367,15 +9385,8 @@ enum vkd3d_result vsir_allocate_temp_registers(struct vsir_program *program,
|
|
allocator.temp_regs = regs + program->ssa_count;
|
|
allocator.new_temp_count = 0;
|
|
|
|
- /* For SM 1.x ps we need to ensure that r0 is reallocated to itself, because
|
|
- * it doubles as the output register. To do so we artificially make it
|
|
- * alive for the whole program. */
|
|
- if (program->shader_version.type == VKD3D_SHADER_TYPE_PIXEL
|
|
- && program->shader_version.major < 2 && allocator.temp_count >= 1)
|
|
- {
|
|
- tracker.temp_regs[0].first_write = 0;
|
|
- tracker.temp_regs[0].last_access = UINT_MAX;
|
|
- }
|
|
+ if (program->shader_version.type == VKD3D_SHADER_TYPE_PIXEL && program->shader_version.major < 2)
|
|
+ allocator.ps_1_x = true;
|
|
|
|
if ((ret = temp_allocator_compute_allocation_map(&allocator, &tracker)) < 0)
|
|
{
|
|
@@ -9418,6 +9429,9 @@ enum vkd3d_result vsir_update_dcl_temps(struct vsir_program *program,
|
|
struct vkd3d_shader_instruction *ins;
|
|
unsigned int temp_count = 0;
|
|
|
|
+ if (program->shader_version.major < 4)
|
|
+ return VKD3D_OK;
|
|
+
|
|
for (ins = vsir_program_iterator_tail(&it); ins; ins = vsir_program_iterator_prev(&it))
|
|
{
|
|
location = ins->location;
|
|
@@ -9429,10 +9443,9 @@ enum vkd3d_result vsir_update_dcl_temps(struct vsir_program *program,
|
|
continue;
|
|
}
|
|
|
|
- if (temp_count && program->shader_version.major >= 4
|
|
- && (ins->opcode == VSIR_OP_HS_CONTROL_POINT_PHASE
|
|
- || ins->opcode == VSIR_OP_HS_FORK_PHASE
|
|
- || ins->opcode == VSIR_OP_HS_JOIN_PHASE))
|
|
+ if (temp_count && (ins->opcode == VSIR_OP_HS_CONTROL_POINT_PHASE
|
|
+ || ins->opcode == VSIR_OP_HS_FORK_PHASE
|
|
+ || ins->opcode == VSIR_OP_HS_JOIN_PHASE))
|
|
{
|
|
/* The phase didn't have a dcl_temps instruction, but we added
|
|
* temps here, so we need to insert one. */
|
|
@@ -9459,7 +9472,7 @@ enum vkd3d_result vsir_update_dcl_temps(struct vsir_program *program,
|
|
}
|
|
}
|
|
|
|
- if (temp_count && program->shader_version.major >= 4)
|
|
+ if (temp_count)
|
|
{
|
|
ins = vsir_program_iterator_head(&it);
|
|
location = ins->location;
|
|
@@ -10581,6 +10594,16 @@ static void vsir_validate_src_param(struct validation_context *ctx,
|
|
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SWIZZLE, "Source of dimension %u has invalid swizzle %#x.",
|
|
src->reg.dimension, src->swizzle);
|
|
|
|
+ if (src->reg.dimension == VSIR_DIMENSION_VEC4 && src->reg.type == VKD3DSPR_IMMCONST
|
|
+ && src->swizzle != VKD3D_SHADER_NO_SWIZZLE)
|
|
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SWIZZLE,
|
|
+ "Immediate constant source has invalid swizzle %#x.", src->swizzle);
|
|
+
|
|
+ if (src->reg.dimension == VSIR_DIMENSION_VEC4 && src->reg.type == VKD3DSPR_IMMCONST64
|
|
+ && src->swizzle != VKD3D_SHADER_SWIZZLE(X, Y, X, X))
|
|
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SWIZZLE,
|
|
+ "Immediate constant source has invalid swizzle %#x.", src->swizzle);
|
|
+
|
|
if (src->modifiers >= VKD3DSPSM_COUNT)
|
|
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_MODIFIERS, "Source has invalid modifiers %#x.",
|
|
src->modifiers);
|
|
@@ -11299,6 +11322,7 @@ static void vsir_validate_integer_elementwise_operation(struct validation_contex
|
|
static const bool types[VSIR_DATA_TYPE_COUNT] =
|
|
{
|
|
[VSIR_DATA_I32] = true,
|
|
+ [VSIR_DATA_I64] = true,
|
|
[VSIR_DATA_U32] = true,
|
|
[VSIR_DATA_U64] = true,
|
|
};
|
|
@@ -11306,6 +11330,18 @@ static void vsir_validate_integer_elementwise_operation(struct validation_contex
|
|
vsir_validate_elementwise_operation(ctx, instruction, types);
|
|
}
|
|
|
|
+static void vsir_validate_signed_integer_elementwise_operation(struct validation_context *ctx,
|
|
+ const struct vkd3d_shader_instruction *instruction)
|
|
+{
|
|
+ static const bool types[VSIR_DATA_TYPE_COUNT] =
|
|
+ {
|
|
+ [VSIR_DATA_I32] = true,
|
|
+ [VSIR_DATA_I64] = true,
|
|
+ };
|
|
+
|
|
+ vsir_validate_elementwise_operation(ctx, instruction, types);
|
|
+}
|
|
+
|
|
static void vsir_validate_logic_elementwise_operation(struct validation_context *ctx,
|
|
const struct vkd3d_shader_instruction *instruction)
|
|
{
|
|
@@ -11399,6 +11435,18 @@ static void vsir_validate_integer_comparison_operation(struct validation_context
|
|
vsir_validate_comparison_operation(ctx, instruction, types);
|
|
}
|
|
|
|
+static void vsir_validate_signed_integer_comparison_operation(struct validation_context *ctx,
|
|
+ const struct vkd3d_shader_instruction *instruction)
|
|
+{
|
|
+ static const bool types[VSIR_DATA_TYPE_COUNT] =
|
|
+ {
|
|
+ [VSIR_DATA_I32] = true,
|
|
+ [VSIR_DATA_I64] = true,
|
|
+ };
|
|
+
|
|
+ vsir_validate_comparison_operation(ctx, instruction, types);
|
|
+}
|
|
+
|
|
static void vsir_validate_cast_operation(struct validation_context *ctx,
|
|
const struct vkd3d_shader_instruction *instruction,
|
|
const bool src_types[VSIR_DATA_TYPE_COUNT], const bool dst_types[VSIR_DATA_TYPE_COUNT])
|
|
@@ -11428,19 +11476,20 @@ static void vsir_validate_cast_operation(struct validation_context *ctx,
|
|
}
|
|
|
|
static void vsir_validate_shift_operation(struct validation_context *ctx,
|
|
- const struct vkd3d_shader_instruction *instruction)
|
|
+ const struct vkd3d_shader_instruction *instruction, const bool types[VSIR_DATA_TYPE_COUNT])
|
|
{
|
|
enum vsir_data_type dst_data_type, src_data_type;
|
|
|
|
- static const bool types[] =
|
|
+ static const bool shift_types[] =
|
|
{
|
|
[VSIR_DATA_I32] = true,
|
|
+ [VSIR_DATA_I64] = true,
|
|
[VSIR_DATA_U32] = true,
|
|
[VSIR_DATA_U64] = true,
|
|
};
|
|
|
|
dst_data_type = instruction->dst[0].reg.data_type;
|
|
- if ((size_t)dst_data_type >= ARRAY_SIZE(types) || !types[dst_data_type])
|
|
+ if ((size_t)dst_data_type >= VSIR_DATA_TYPE_COUNT || !types[dst_data_type])
|
|
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE,
|
|
"Invalid destination data type \"%s\" (%#x) for shift operation \"%s\" (%#x).",
|
|
vsir_data_type_get_name(dst_data_type, "<unknown>"), dst_data_type,
|
|
@@ -11455,7 +11504,7 @@ static void vsir_validate_shift_operation(struct validation_context *ctx,
|
|
vsir_opcode_get_name(instruction->opcode, "<unknown>"), instruction->opcode);
|
|
|
|
src_data_type = instruction->src[1].reg.data_type;
|
|
- if ((size_t)src_data_type >= ARRAY_SIZE(types) || !types[src_data_type])
|
|
+ if ((size_t)src_data_type >= ARRAY_SIZE(shift_types) || !shift_types[src_data_type])
|
|
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE,
|
|
"Invalid source operand 1 data type \"%s\" (%#x) for shift operation \"%s\" (%#x).",
|
|
vsir_data_type_get_name(src_data_type, "<unknown>"), src_data_type,
|
|
@@ -12020,6 +12069,32 @@ static void vsir_validate_ifc(struct validation_context *ctx, const struct vkd3d
|
|
vsir_validator_push_block(ctx, VSIR_OP_IF);
|
|
}
|
|
|
|
+static void vsir_validate_ishl(struct validation_context *ctx,
|
|
+ const struct vkd3d_shader_instruction *instruction)
|
|
+{
|
|
+ static const bool types[VSIR_DATA_TYPE_COUNT] =
|
|
+ {
|
|
+ [VSIR_DATA_I32] = true,
|
|
+ [VSIR_DATA_I64] = true,
|
|
+ [VSIR_DATA_U32] = true,
|
|
+ [VSIR_DATA_U64] = true,
|
|
+ };
|
|
+
|
|
+ vsir_validate_shift_operation(ctx, instruction, types);
|
|
+}
|
|
+
|
|
+static void vsir_validate_ishr(struct validation_context *ctx,
|
|
+ const struct vkd3d_shader_instruction *instruction)
|
|
+{
|
|
+ static const bool types[VSIR_DATA_TYPE_COUNT] =
|
|
+ {
|
|
+ [VSIR_DATA_I32] = true,
|
|
+ [VSIR_DATA_I64] = true,
|
|
+ };
|
|
+
|
|
+ vsir_validate_shift_operation(ctx, instruction, types);
|
|
+}
|
|
+
|
|
static void vsir_validate_itof(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction)
|
|
{
|
|
static const bool src_types[VSIR_DATA_TYPE_COUNT] =
|
|
@@ -12251,6 +12326,18 @@ static void vsir_validate_switch_monolithic(struct validation_context *ctx,
|
|
ctx->inside_block = false;
|
|
}
|
|
|
|
+static void vsir_validate_ushr(struct validation_context *ctx,
|
|
+ const struct vkd3d_shader_instruction *instruction)
|
|
+{
|
|
+ static const bool types[VSIR_DATA_TYPE_COUNT] =
|
|
+ {
|
|
+ [VSIR_DATA_U32] = true,
|
|
+ [VSIR_DATA_U64] = true,
|
|
+ };
|
|
+
|
|
+ vsir_validate_shift_operation(ctx, instruction, types);
|
|
+}
|
|
+
|
|
struct vsir_validator_instruction_desc
|
|
{
|
|
unsigned int dst_param_count;
|
|
@@ -12330,17 +12417,17 @@ static const struct vsir_validator_instruction_desc vsir_validator_instructions[
|
|
[VSIR_OP_IEQ] = {1, 2, vsir_validate_integer_comparison_operation},
|
|
[VSIR_OP_IF] = {0, 1, vsir_validate_if},
|
|
[VSIR_OP_IFC] = {0, 2, vsir_validate_ifc},
|
|
- [VSIR_OP_IGE] = {1, 2, vsir_validate_integer_comparison_operation},
|
|
- [VSIR_OP_ILT] = {1, 2, vsir_validate_integer_comparison_operation},
|
|
+ [VSIR_OP_IGE] = {1, 2, vsir_validate_signed_integer_comparison_operation},
|
|
+ [VSIR_OP_ILT] = {1, 2, vsir_validate_signed_integer_comparison_operation},
|
|
[VSIR_OP_IMAD] = {1, 3, vsir_validate_integer_elementwise_operation},
|
|
- [VSIR_OP_IMAX] = {1, 2, vsir_validate_integer_elementwise_operation},
|
|
- [VSIR_OP_IMIN] = {1, 2, vsir_validate_integer_elementwise_operation},
|
|
+ [VSIR_OP_IMAX] = {1, 2, vsir_validate_signed_integer_elementwise_operation},
|
|
+ [VSIR_OP_IMIN] = {1, 2, vsir_validate_signed_integer_elementwise_operation},
|
|
[VSIR_OP_INE] = {1, 2, vsir_validate_integer_comparison_operation},
|
|
[VSIR_OP_INEG] = {1, 1, vsir_validate_integer_elementwise_operation},
|
|
[VSIR_OP_IREM] = {1, 2, vsir_validate_integer_elementwise_operation},
|
|
[VSIR_OP_ISFINITE] = {1, 1, vsir_validate_float_comparison_operation},
|
|
- [VSIR_OP_ISHL] = {1, 2, vsir_validate_shift_operation},
|
|
- [VSIR_OP_ISHR] = {1, 2, vsir_validate_shift_operation},
|
|
+ [VSIR_OP_ISHL] = {1, 2, vsir_validate_ishl},
|
|
+ [VSIR_OP_ISHR] = {1, 2, vsir_validate_ishr},
|
|
[VSIR_OP_ISINF] = {1, 1, vsir_validate_float_comparison_operation},
|
|
[VSIR_OP_ISNAN] = {1, 1, vsir_validate_float_comparison_operation},
|
|
[VSIR_OP_ITOF] = {1, 1, vsir_validate_itof},
|
|
@@ -12370,6 +12457,7 @@ static const struct vsir_validator_instruction_desc vsir_validator_instructions[
|
|
[VSIR_OP_SAMPLE_INFO] = {1, 1, vsir_validate_sample_info},
|
|
[VSIR_OP_SWITCH] = {0, 1, vsir_validate_switch},
|
|
[VSIR_OP_SWITCH_MONOLITHIC] = {0, ~0u, vsir_validate_switch_monolithic},
|
|
+ [VSIR_OP_USHR] = {1, 2, vsir_validate_ushr},
|
|
};
|
|
|
|
static void vsir_validate_instruction(struct validation_context *ctx,
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/msl.c b/libs/vkd3d/libs/vkd3d-shader/msl.c
|
|
index 9150e77e2c6..2005e842201 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/msl.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/msl.c
|
|
@@ -167,6 +167,7 @@ static void msl_print_register_datatype(struct vkd3d_string_buffer *buffer,
|
|
case VSIR_DATA_F32:
|
|
vkd3d_string_buffer_printf(buffer, "f");
|
|
break;
|
|
+ case VSIR_DATA_BOOL:
|
|
case VSIR_DATA_I32:
|
|
vkd3d_string_buffer_printf(buffer, "i");
|
|
break;
|
|
@@ -799,6 +800,7 @@ static void msl_relop(struct msl_generator *gen, const struct vkd3d_shader_instr
|
|
static void msl_cast(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins, const char *constructor)
|
|
{
|
|
unsigned int component_count;
|
|
+ const char *negate;
|
|
struct msl_src src;
|
|
struct msl_dst dst;
|
|
uint32_t mask;
|
|
@@ -806,10 +808,11 @@ static void msl_cast(struct msl_generator *gen, const struct vkd3d_shader_instru
|
|
mask = msl_dst_init(&dst, gen, ins, &ins->dst[0]);
|
|
msl_src_init(&src, gen, &ins->src[0], mask);
|
|
|
|
+ negate = ins->opcode == VSIR_OP_UTOF && data_type_is_bool(ins->src[0].reg.data_type) ? "-" : "";
|
|
if ((component_count = vsir_write_mask_component_count(mask)) > 1)
|
|
- msl_print_assignment(gen, &dst, "%s%u(%s)", constructor, component_count, src.str->buffer);
|
|
+ msl_print_assignment(gen, &dst, "%s%u(%s%s)", constructor, component_count, negate, src.str->buffer);
|
|
else
|
|
- msl_print_assignment(gen, &dst, "%s(%s)", constructor, src.str->buffer);
|
|
+ msl_print_assignment(gen, &dst, "%s(%s%s)", constructor, negate, src.str->buffer);
|
|
|
|
msl_src_cleanup(&src, &gen->string_buffers);
|
|
msl_dst_cleanup(&dst, &gen->string_buffers);
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c
|
|
index 8ffc68935f3..0fdeba75c58 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/spirv.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c
|
|
@@ -8155,7 +8155,7 @@ static void spirv_compiler_emit_ftoi(struct spirv_compiler *compiler,
|
|
component_type = vkd3d_component_type_from_data_type(dst->reg.data_type);
|
|
|
|
int_max_id = spirv_compiler_get_constant_vector(compiler, component_type, component_count, INT_MAX);
|
|
- condition_type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count);
|
|
+ condition_type_id = spirv_get_type_id(builder, VSIR_DATA_BOOL, component_count);
|
|
condition_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream,
|
|
SpvOpFOrdGreaterThanEqual, condition_type_id, val_id, float_max_id);
|
|
|
|
@@ -8208,7 +8208,7 @@ static void spirv_compiler_emit_ftou(struct spirv_compiler *compiler,
|
|
val_id = vkd3d_spirv_build_op_glsl_std450_max(builder, src_type_id, src_id, zero_id);
|
|
|
|
uint_max_id = spirv_compiler_get_constant_uint_vector(compiler, UINT_MAX, component_count);
|
|
- condition_type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count);
|
|
+ condition_type_id = spirv_get_type_id(builder, VSIR_DATA_BOOL, component_count);
|
|
condition_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream,
|
|
SpvOpFOrdGreaterThanEqual, condition_type_id, val_id, float_max_id);
|
|
|
|
@@ -8233,7 +8233,7 @@ static void spirv_compiler_emit_dtof(struct spirv_compiler *compiler,
|
|
|
|
src_id = spirv_compiler_emit_load_src(compiler, src, write_mask);
|
|
|
|
- type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_FLOAT, component_count);
|
|
+ type_id = spirv_get_type_id(builder, VSIR_DATA_F32, component_count);
|
|
val_id = vkd3d_spirv_build_op_tr1(builder, &builder->function_stream, SpvOpFConvert, type_id, src_id);
|
|
if (instruction->flags & VKD3DSI_PRECISE_XYZW)
|
|
vkd3d_spirv_build_op_decorate(builder, val_id, SpvDecorationNoContraction, NULL, 0);
|
|
@@ -8257,7 +8257,7 @@ static void spirv_compiler_emit_bitfield_instruction(struct spirv_compiler *comp
|
|
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_for_component_type(builder, component_type, 1);
|
|
+ type_id = spirv_get_type_id(builder, dst->reg.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);
|
|
@@ -8314,8 +8314,8 @@ static void spirv_compiler_emit_f16tof32(struct spirv_compiler *compiler,
|
|
unsigned int i, j;
|
|
|
|
instr_set_id = vkd3d_spirv_get_glsl_std450_instr_set(builder);
|
|
- type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_FLOAT, 2);
|
|
- scalar_type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_FLOAT, 1);
|
|
+ type_id = spirv_get_type_id(builder, VSIR_DATA_F32, 2);
|
|
+ scalar_type_id = spirv_get_type_id(builder, VSIR_DATA_F32, 1);
|
|
|
|
/* FIXME: Consider a single UnpackHalf2x16 instruction per 2 components. */
|
|
VKD3D_ASSERT(dst->write_mask & VKD3DSP_WRITEMASK_ALL);
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c
|
|
index 2541aef1314..7ff2a305cfa 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/tpf.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c
|
|
@@ -3483,7 +3483,9 @@ static uint32_t sm4_encode_register(const struct tpf_compiler *tpf, const struct
|
|
switch (sm4_swizzle_type)
|
|
{
|
|
case VKD3D_SM4_SWIZZLE_NONE:
|
|
- VKD3D_ASSERT(sm4_swizzle || register_is_constant(reg));
|
|
+ if (register_is_constant(reg))
|
|
+ break;
|
|
+ VKD3D_ASSERT(sm4_swizzle);
|
|
token |= (sm4_swizzle << VKD3D_SM4_WRITEMASK_SHIFT) & VKD3D_SM4_WRITEMASK_MASK;
|
|
break;
|
|
|
|
--
|
|
2.51.0
|
|
|