wine-staging/patches/vkd3d-latest/0006-Updated-vkd3d-to-ee28861837c825818ace2e1e50825ade87a.patch
2023-09-16 09:31:27 +10:00

433 lines
18 KiB
Diff

From d781aee2d58e59b61a34fefef0a4ce4b527a6c99 Mon Sep 17 00:00:00 2001
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
Date: Sat, 16 Sep 2023 07:19:25 +1000
Subject: [PATCH] Updated vkd3d to ee28861837c825818ace2e1e50825ade87a9c723.
---
libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 2 +-
libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 4 -
libs/vkd3d/libs/vkd3d-shader/hlsl.c | 3 +-
libs/vkd3d/libs/vkd3d-shader/hlsl.h | 9 +-
libs/vkd3d/libs/vkd3d-shader/hlsl.y | 56 +++++++++-
libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 100 ++++++++++++++++++
libs/vkd3d/libs/vkd3d-shader/spirv.c | 10 +-
libs/vkd3d/libs/vkd3d-shader/tpf.c | 25 +++++
.../libs/vkd3d-shader/vkd3d_shader_main.c | 3 +-
9 files changed, 197 insertions(+), 15 deletions(-)
diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c
index d72402eb250..f0c386f1b3a 100644
--- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c
+++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c
@@ -714,7 +714,7 @@ static void shader_dump_decl_usage(struct vkd3d_d3d_asm_compiler *compiler,
break;
case VKD3D_DECL_USAGE_TEXCOORD:
- shader_addline(buffer, "texture%u", semantic->usage_idx);
+ shader_addline(buffer, "texcoord%u", semantic->usage_idx);
break;
case VKD3D_DECL_USAGE_TANGENT:
diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
index 2b02d51f59a..d5104ae9b79 100644
--- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
+++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
@@ -1982,10 +1982,6 @@ static void write_sm1_sampler_dcl(struct hlsl_ctx *ctx, struct vkd3d_bytecode_bu
switch (sampler_dim)
{
- case HLSL_SAMPLER_DIM_1D:
- res_type = VKD3D_SM1_RESOURCE_TEXTURE_1D;
- break;
-
case HLSL_SAMPLER_DIM_2D:
res_type = VKD3D_SM1_RESOURCE_TEXTURE_2D;
break;
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c
index b8cf6813f67..5fe9047bf25 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c
@@ -2486,7 +2486,8 @@ const char *debug_hlsl_expr_op(enum hlsl_ir_expr_op op)
[HLSL_OP2_RSHIFT] = ">>",
[HLSL_OP3_DP2ADD] = "dp2add",
- [HLSL_OP3_LERP] = "lerp",
+ [HLSL_OP3_MOVC] = "movc",
+ [HLSL_OP3_TERNARY] = "ternary",
};
return op_names[op];
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h
index 73b08ee3ea0..2cde5d58eba 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h
@@ -550,8 +550,15 @@ enum hlsl_ir_expr_op
HLSL_OP2_NEQUAL,
HLSL_OP2_RSHIFT,
+ /* DP2ADD(a, b, c) computes the scalar product of a.xy and b.xy,
+ * then adds c. */
HLSL_OP3_DP2ADD,
- HLSL_OP3_LERP,
+ /* MOVC(a, b, c) returns c if a is bitwise zero and b otherwise.
+ * TERNARY(a, b, c) returns c if a == 0 and b otherwise.
+ * They differ for floating point numbers, because
+ * -0.0 == 0.0, but it is not bitwise zero. */
+ HLSL_OP3_MOVC,
+ HLSL_OP3_TERNARY,
};
#define HLSL_MAX_OPERANDS 3
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y
index 161d1ab42c3..fb6d485ea69 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y
@@ -2913,6 +2913,7 @@ static bool intrinsic_fmod(struct hlsl_ctx *ctx, const struct parse_initializer
const struct vkd3d_shader_location *loc)
{
struct hlsl_ir_node *x, *y, *div, *abs, *frac, *neg_frac, *ge, *select, *zero;
+ struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = { 0 };
static const struct hlsl_constant_value zero_value;
if (!(x = intrinsic_float_convert_arg(ctx, params, params->args[0], loc)))
@@ -2940,7 +2941,10 @@ static bool intrinsic_fmod(struct hlsl_ctx *ctx, const struct parse_initializer
if (!(ge = add_binary_comparison_expr(ctx, params->instrs, HLSL_OP2_GEQUAL, div, zero, loc)))
return false;
- if (!(select = hlsl_add_conditional(ctx, params->instrs, ge, frac, neg_frac)))
+ operands[0] = ge;
+ operands[1] = frac;
+ operands[2] = neg_frac;
+ if (!(select = add_expr(ctx, params->instrs, HLSL_OP3_TERNARY, operands, x->data_type, loc)))
return false;
return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, select, y, loc);
@@ -3453,7 +3457,42 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer *
if (!(coords = add_implicit_conversion(ctx, params->instrs, params->args[1],
hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, hlsl_sampler_dim_count(dim)), loc)))
- coords = params->args[1];
+ {
+ return false;
+ }
+
+ /* tex1D() functions never produce 1D resource declarations. For newer profiles half offset
+ is used for the second coordinate, while older ones appear to replicate first coordinate.*/
+ if (dim == HLSL_SAMPLER_DIM_1D)
+ {
+ struct hlsl_ir_load *load;
+ struct hlsl_ir_node *half;
+ struct hlsl_ir_var *var;
+ unsigned int idx = 0;
+
+ if (!(var = hlsl_new_synthetic_var(ctx, "coords", hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, 2), loc)))
+ return false;
+
+ initialize_var_components(ctx, params->instrs, var, &idx, coords);
+ if (shader_profile_version_ge(ctx, 4, 0))
+ {
+ if (!(half = hlsl_new_float_constant(ctx, 0.5f, loc)))
+ return false;
+ hlsl_block_add_instr(params->instrs, half);
+
+ initialize_var_components(ctx, params->instrs, var, &idx, half);
+ }
+ else
+ initialize_var_components(ctx, params->instrs, var, &idx, coords);
+
+ if (!(load = hlsl_new_var_load(ctx, var, loc)))
+ return false;
+ hlsl_block_add_instr(params->instrs, &load->node);
+
+ coords = &load->node;
+
+ dim = HLSL_SAMPLER_DIM_2D;
+ }
load_params.coords = coords;
load_params.resource = params->args[0];
@@ -3466,6 +3505,12 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer *
return true;
}
+static bool intrinsic_tex1D(struct hlsl_ctx *ctx,
+ const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
+{
+ return intrinsic_tex(ctx, params, loc, "tex1D", HLSL_SAMPLER_DIM_1D);
+}
+
static bool intrinsic_tex2D(struct hlsl_ctx *ctx,
const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
{
@@ -3652,6 +3697,7 @@ intrinsic_functions[] =
{"smoothstep", 3, true, intrinsic_smoothstep},
{"sqrt", 1, true, intrinsic_sqrt},
{"step", 2, true, intrinsic_step},
+ {"tex1D", -1, false, intrinsic_tex1D},
{"tex2D", -1, false, intrinsic_tex2D},
{"tex3D", -1, false, intrinsic_tex3D},
{"texCUBE", -1, false, intrinsic_texCUBE},
@@ -6555,6 +6601,7 @@ conditional_expr:
struct hlsl_ir_node *cond = node_from_block($1);
struct hlsl_ir_node *first = node_from_block($3);
struct hlsl_ir_node *second = node_from_block($5);
+ struct hlsl_ir_node *args[HLSL_MAX_OPERANDS] = { 0 };
struct hlsl_type *common_type;
hlsl_block_add_block($1, $3);
@@ -6571,7 +6618,10 @@ conditional_expr:
if (!(second = add_implicit_conversion(ctx, $1, second, common_type, &@5)))
YYABORT;
- if (!hlsl_add_conditional(ctx, $1, cond, first, second))
+ args[0] = cond;
+ args[1] = first;
+ args[2] = second;
+ if (!add_expr(ctx, $1, HLSL_OP3_TERNARY, args, common_type, &@1))
YYABORT;
$$ = $1;
}
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
index 710d2908166..be024842164 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
@@ -934,6 +934,55 @@ static struct hlsl_ir_node *add_zero_mipmap_level(struct hlsl_ctx *ctx, struct h
return &coords_load->node;
}
+/* hlsl_ir_swizzle nodes that directly point to a matrix value are only a parse-time construct that
+ * represents matrix swizzles (e.g. mat._m01_m23) before we know if they will be used in the lhs of
+ * 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)
+{
+ struct hlsl_ir_swizzle *swizzle;
+ struct hlsl_ir_load *var_load;
+ struct hlsl_deref var_deref;
+ struct hlsl_type *matrix_type;
+ struct hlsl_ir_var *var;
+ unsigned int x, y, k, i;
+
+ if (instr->type != HLSL_IR_SWIZZLE)
+ return false;
+ swizzle = hlsl_ir_swizzle(instr);
+ matrix_type = swizzle->val.node->data_type;
+ if (matrix_type->class != HLSL_CLASS_MATRIX)
+ return false;
+
+ if (!(var = hlsl_new_synthetic_var(ctx, "matrix-swizzle", instr->data_type, &instr->loc)))
+ return false;
+ hlsl_init_simple_deref_from_var(&var_deref, var);
+
+ for (i = 0; i < instr->data_type->dimx; ++i)
+ {
+ struct hlsl_block store_block;
+ struct hlsl_ir_node *load;
+
+ y = (swizzle->swizzle >> (8 * i + 4)) & 0xf;
+ x = (swizzle->swizzle >> 8 * i) & 0xf;
+ k = y * matrix_type->dimx + x;
+
+ if (!(load = hlsl_add_load_component(ctx, block, swizzle->val.node, k, &instr->loc)))
+ return false;
+
+ if (!hlsl_new_store_component(ctx, &store_block, &var_deref, i, load))
+ return false;
+ hlsl_block_add_block(block, &store_block);
+ }
+
+ if (!(var_load = hlsl_new_var_load(ctx, var, &instr->loc)))
+ return false;
+ hlsl_block_add_instr(block, &var_load->node);
+
+ return true;
+}
+
/* hlsl_ir_index nodes are a parse-time construct used to represent array indexing and struct
* record access before knowing if they will be used in the lhs of an assignment --in which case
* they are lowered into a deref-- or as the load of an element within a larger value.
@@ -2391,6 +2440,54 @@ static bool lower_round(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *
return true;
}
+/* Use 'movc' for the ternary operator. */
+static bool lower_ternary(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context)
+{
+ struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS], *replacement;
+ struct hlsl_ir_node *zero, *cond, *first, *second;
+ struct hlsl_constant_value zero_value = { 0 };
+ struct hlsl_ir_expr *expr;
+ struct hlsl_type *type;
+
+ if (instr->type != HLSL_IR_EXPR)
+ return false;
+
+ expr = hlsl_ir_expr(instr);
+ if (expr->op != HLSL_OP3_TERNARY)
+ return false;
+
+ cond = expr->operands[0].node;
+ first = expr->operands[1].node;
+ second = expr->operands[2].node;
+
+ if (cond->data_type->base_type == HLSL_TYPE_FLOAT)
+ {
+ if (!(zero = hlsl_new_constant(ctx, cond->data_type, &zero_value, &instr->loc)))
+ return false;
+ list_add_tail(&instr->entry, &zero->entry);
+
+ memset(operands, 0, sizeof(operands));
+ operands[0] = zero;
+ operands[1] = cond;
+ type = cond->data_type;
+ type = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_BOOL, type->dimx, type->dimy);
+ if (!(cond = hlsl_new_expr(ctx, HLSL_OP2_NEQUAL, operands, type, &instr->loc)))
+ return false;
+ list_add_before(&instr->entry, &cond->entry);
+ }
+
+ memset(operands, 0, sizeof(operands));
+ operands[0] = cond;
+ operands[1] = first;
+ operands[2] = second;
+ if (!(replacement = hlsl_new_expr(ctx, HLSL_OP3_MOVC, operands, first->data_type, &instr->loc)))
+ return false;
+ list_add_before(&instr->entry, &replacement->entry);
+
+ hlsl_replace_node(instr, replacement);
+ return true;
+}
+
static bool lower_casts_to_bool(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context)
{
struct hlsl_type *type = instr->data_type, *arg_type;
@@ -4247,6 +4344,7 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry
while (hlsl_transform_ir(ctx, lower_calls, body, NULL));
+ lower_ir(ctx, lower_matrix_swizzles, body);
hlsl_transform_ir(ctx, lower_index_loads, body, NULL);
LIST_FOR_EACH_ENTRY(var, &ctx->globals->vars, struct hlsl_ir_var, scope_entry)
@@ -4349,6 +4447,8 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry
hlsl_transform_ir(ctx, track_object_components_usage, body, NULL);
sort_synthetic_separated_samplers_first(ctx);
+ if (profile->major_version >= 4)
+ hlsl_transform_ir(ctx, lower_ternary, body, NULL);
if (profile->major_version < 4)
{
hlsl_transform_ir(ctx, lower_division, body, NULL);
diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c
index f93960d6d54..95f6914acb7 100644
--- a/libs/vkd3d/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c
@@ -5564,7 +5564,7 @@ static uint32_t spirv_compiler_build_descriptor_variable(struct spirv_compiler *
}
static void spirv_compiler_emit_cbv_declaration(struct spirv_compiler *compiler,
- const struct vkd3d_shader_register_range *range, unsigned int register_id, unsigned int size)
+ const struct vkd3d_shader_register_range *range, unsigned int register_id, unsigned int size_in_bytes)
{
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
uint32_t vec4_id, array_type_id, length_id, struct_id, var_id;
@@ -5572,6 +5572,7 @@ static void spirv_compiler_emit_cbv_declaration(struct spirv_compiler *compiler,
struct vkd3d_push_constant_buffer_binding *push_cb;
struct vkd3d_descriptor_variable_info var_info;
struct vkd3d_symbol reg_symbol;
+ unsigned int size;
struct vkd3d_shader_register reg =
{
@@ -5580,18 +5581,19 @@ static void spirv_compiler_emit_cbv_declaration(struct spirv_compiler *compiler,
.idx_count = 1,
};
+ size = size_in_bytes / (VKD3D_VEC4_SIZE * sizeof(uint32_t));
+
if ((push_cb = spirv_compiler_find_push_constant_buffer(compiler, range)))
{
/* Push constant buffers are handled in
* spirv_compiler_emit_push_constant_buffers().
*/
- unsigned int cb_size_in_bytes = size * VKD3D_VEC4_SIZE * sizeof(uint32_t);
push_cb->reg = reg;
push_cb->size = size;
- if (cb_size_in_bytes > push_cb->pc.size)
+ if (size_in_bytes > push_cb->pc.size)
{
WARN("Constant buffer size %u exceeds push constant size %u.\n",
- cb_size_in_bytes, push_cb->pc.size);
+ size_in_bytes, push_cb->pc.size);
}
return;
}
diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c
index 7949be150bf..045fb6c5f64 100644
--- a/libs/vkd3d/libs/vkd3d-shader/tpf.c
+++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c
@@ -4341,6 +4341,26 @@ static void write_sm4_binary_op_with_two_destinations(const struct tpf_writer *t
write_sm4_instruction(tpf, &instr);
}
+static void write_sm4_ternary_op(const struct tpf_writer *tpf, enum vkd3d_sm4_opcode opcode,
+ const struct hlsl_ir_node *dst, const struct hlsl_ir_node *src1, const struct hlsl_ir_node *src2,
+ const struct hlsl_ir_node *src3)
+{
+ struct sm4_instruction instr;
+
+ memset(&instr, 0, sizeof(instr));
+ instr.opcode = opcode;
+
+ sm4_dst_from_node(&instr.dsts[0], dst);
+ instr.dst_count = 1;
+
+ sm4_src_from_node(&instr.srcs[0], src1, instr.dsts[0].writemask);
+ sm4_src_from_node(&instr.srcs[1], src2, instr.dsts[0].writemask);
+ sm4_src_from_node(&instr.srcs[2], src3, instr.dsts[0].writemask);
+ instr.src_count = 3;
+
+ write_sm4_instruction(tpf, &instr);
+}
+
static void write_sm4_ld(const struct tpf_writer *tpf, const struct hlsl_ir_node *dst,
const struct hlsl_deref *resource, const struct hlsl_ir_node *coords,
const struct hlsl_ir_node *sample_index, const struct hlsl_ir_node *texel_offset,
@@ -4702,6 +4722,7 @@ static void write_sm4_expr(const struct tpf_writer *tpf, const struct hlsl_ir_ex
{
const struct hlsl_ir_node *arg1 = expr->operands[0].node;
const struct hlsl_ir_node *arg2 = expr->operands[1].node;
+ const struct hlsl_ir_node *arg3 = expr->operands[2].node;
const struct hlsl_type *dst_type = expr->node.data_type;
struct vkd3d_string_buffer *dst_type_string;
@@ -5127,6 +5148,10 @@ static void write_sm4_expr(const struct tpf_writer *tpf, const struct hlsl_ir_ex
&expr->node, arg1, arg2);
break;
+ case HLSL_OP3_MOVC:
+ write_sm4_ternary_op(tpf, VKD3D_SM4_OP_MOVC, &expr->node, arg1, arg2, arg3);
+ break;
+
default:
hlsl_fixme(tpf->ctx, &expr->node.loc, "SM4 %s expression.", debug_hlsl_expr_op(expr->op));
}
diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
index a70894a160d..9d8fa82fb86 100644
--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
@@ -705,7 +705,8 @@ static void vkd3d_shader_scan_add_uav_flag(const struct vkd3d_shader_scan_contex
for (i = 0; i < context->scan_descriptor_info->descriptor_count; ++i)
{
- if (context->scan_descriptor_info->descriptors[i].register_id == range_id)
+ if (context->scan_descriptor_info->descriptors[i].type == VKD3D_SHADER_DESCRIPTOR_TYPE_UAV
+ && context->scan_descriptor_info->descriptors[i].register_id == range_id)
{
context->scan_descriptor_info->descriptors[i].flags |= flag;
break;
--
2.40.1