wine-staging/patches/vkd3d-latest/0002-Updated-vkd3d-to-a2aeb3a1421c5540b7f4d0e68ec3ff211e1.patch
2024-10-03 12:54:36 +10:00

950 lines
40 KiB
Diff

From f7442f283e45fca56616dc6dbbd9db472bebef3a Mon Sep 17 00:00:00 2001
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
Date: Tue, 24 Sep 2024 08:29:40 +1000
Subject: [PATCH] Updated vkd3d to a2aeb3a1421c5540b7f4d0e68ec3ff211e15f646.
---
libs/vkd3d/include/vkd3d_shader.h | 11 +++
libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 13 ++-
libs/vkd3d/libs/vkd3d-shader/fx.c | 2 +
libs/vkd3d/libs/vkd3d-shader/glsl.c | 56 +++++++++++
libs/vkd3d/libs/vkd3d-shader/hlsl.c | 39 ++++++--
libs/vkd3d/libs/vkd3d-shader/hlsl.h | 13 +++
libs/vkd3d/libs/vkd3d-shader/hlsl.l | 1 -
libs/vkd3d/libs/vkd3d-shader/hlsl.y | 93 ++++++++++---------
libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 36 ++++++-
libs/vkd3d/libs/vkd3d-shader/spirv.c | 64 +++++--------
libs/vkd3d/libs/vkd3d-shader/tpf.c | 1 +
.../libs/vkd3d-shader/vkd3d_shader_private.h | 2 +
libs/vkd3d/libs/vkd3d/state.c | 4 +-
13 files changed, 234 insertions(+), 101 deletions(-)
diff --git a/libs/vkd3d/include/vkd3d_shader.h b/libs/vkd3d/include/vkd3d_shader.h
index 46feff35138..115bb21b932 100644
--- a/libs/vkd3d/include/vkd3d_shader.h
+++ b/libs/vkd3d/include/vkd3d_shader.h
@@ -190,6 +190,17 @@ enum vkd3d_shader_compile_option_backward_compatibility
* - DEPTH to SV_Depth for pixel shader outputs.
*/
VKD3D_SHADER_COMPILE_OPTION_BACKCOMPAT_MAP_SEMANTIC_NAMES = 0x00000001,
+ /**
+ * Causes 'double' to behave as an alias for 'float'. This option only
+ * applies to HLSL sources with shader model 1-3 target profiles. Without
+ * this option using the 'double' type produces compilation errors in
+ * these target profiles.
+ *
+ * This option is disabled by default.
+ *
+ * \since 1.14
+ */
+ VKD3D_SHADER_COMPILE_OPTION_DOUBLE_AS_FLOAT_ALIAS = 0x00000002,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_BACKWARD_COMPATIBILITY),
};
diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
index 10f2e5e5e6d..34752a1ab89 100644
--- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
+++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
@@ -1522,6 +1522,7 @@ D3DXPARAMETER_CLASS hlsl_sm1_class(const struct hlsl_type *type)
case HLSL_CLASS_DEPTH_STENCIL_STATE:
case HLSL_CLASS_DEPTH_STENCIL_VIEW:
case HLSL_CLASS_EFFECT_GROUP:
+ case HLSL_CLASS_ERROR:
case HLSL_CLASS_PASS:
case HLSL_CLASS_RASTERIZER_STATE:
case HLSL_CLASS_RENDER_TARGET_VIEW:
@@ -1627,6 +1628,7 @@ D3DXPARAMETER_TYPE hlsl_sm1_base_type(const struct hlsl_type *type)
case HLSL_CLASS_DEPTH_STENCIL_STATE:
case HLSL_CLASS_DEPTH_STENCIL_VIEW:
case HLSL_CLASS_EFFECT_GROUP:
+ case HLSL_CLASS_ERROR:
case HLSL_CLASS_PASS:
case HLSL_CLASS_RASTERIZER_STATE:
case HLSL_CLASS_RENDER_TARGET_VIEW:
@@ -1719,7 +1721,7 @@ static void sm1_sort_externs(struct hlsl_ctx *ctx)
void write_sm1_uniforms(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer)
{
- size_t ctab_offset, ctab_start, ctab_end, vars_start, size_offset, creator_offset, offset;
+ size_t ctab_offset, ctab_start, ctab_end, vars_offset, vars_start, size_offset, creator_offset, offset;
unsigned int uniform_count = 0;
struct hlsl_ir_var *var;
@@ -1755,11 +1757,12 @@ void write_sm1_uniforms(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buff
creator_offset = put_u32(buffer, 0);
put_u32(buffer, sm1_version(ctx->profile->type, ctx->profile->major_version, ctx->profile->minor_version));
put_u32(buffer, uniform_count);
- put_u32(buffer, sizeof(D3DXSHADER_CONSTANTTABLE)); /* offset of constants */
+ vars_offset = put_u32(buffer, 0);
put_u32(buffer, 0); /* FIXME: flags */
put_u32(buffer, 0); /* FIXME: target string */
vars_start = bytecode_align(buffer);
+ set_u32(buffer, vars_offset, vars_start - ctab_start);
LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
{
@@ -1835,8 +1838,10 @@ void write_sm1_uniforms(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buff
switch (comp_type->e.numeric.type)
{
case HLSL_TYPE_DOUBLE:
- hlsl_fixme(ctx, &var->loc, "Write double default values.");
- uni.u = 0;
+ if (ctx->double_as_float_alias)
+ uni.u = var->default_values[k].number.u;
+ else
+ uni.u = 0;
break;
case HLSL_TYPE_INT:
diff --git a/libs/vkd3d/libs/vkd3d-shader/fx.c b/libs/vkd3d/libs/vkd3d-shader/fx.c
index 1314bc09e73..7d4a9d2e2ff 100644
--- a/libs/vkd3d/libs/vkd3d-shader/fx.c
+++ b/libs/vkd3d/libs/vkd3d-shader/fx.c
@@ -665,6 +665,7 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co
case HLSL_CLASS_ARRAY:
case HLSL_CLASS_EFFECT_GROUP:
+ case HLSL_CLASS_ERROR:
case HLSL_CLASS_PASS:
case HLSL_CLASS_TECHNIQUE:
case HLSL_CLASS_CONSTANT_BUFFER:
@@ -1117,6 +1118,7 @@ static bool is_type_supported_fx_2(struct hlsl_ctx *ctx, const struct hlsl_type
return false;
case HLSL_CLASS_EFFECT_GROUP:
+ case HLSL_CLASS_ERROR:
case HLSL_CLASS_PASS:
case HLSL_CLASS_TECHNIQUE:
case HLSL_CLASS_CONSTANT_BUFFER:
diff --git a/libs/vkd3d/libs/vkd3d-shader/glsl.c b/libs/vkd3d/libs/vkd3d-shader/glsl.c
index dd1c121d5a8..b29f13f2b19 100644
--- a/libs/vkd3d/libs/vkd3d-shader/glsl.c
+++ b/libs/vkd3d/libs/vkd3d-shader/glsl.c
@@ -305,6 +305,9 @@ static void glsl_src_init(struct glsl_src *glsl_src, struct vkd3d_glsl_generator
{
case VKD3DSPSM_NONE:
break;
+ case VKD3DSPSM_NEG:
+ vkd3d_string_buffer_printf(glsl_src->str, "-%s", str->buffer);
+ break;
case VKD3DSPSM_ABS:
vkd3d_string_buffer_printf(glsl_src->str, "abs(%s)", str->buffer);
break;
@@ -414,6 +417,22 @@ static void shader_glsl_binop(struct vkd3d_glsl_generator *gen,
glsl_dst_cleanup(&dst, &gen->string_buffers);
}
+static void shader_glsl_intrinsic(struct vkd3d_glsl_generator *gen,
+ const struct vkd3d_shader_instruction *ins, const char *op)
+{
+ struct glsl_src src;
+ struct glsl_dst dst;
+ uint32_t mask;
+
+ mask = glsl_dst_init(&dst, gen, ins, &ins->dst[0]);
+ glsl_src_init(&src, gen, &ins->src[0], mask);
+
+ shader_glsl_print_assignment(gen, &dst, "%s(%s)", op, src.str->buffer);
+
+ glsl_src_cleanup(&src, &gen->string_buffers);
+ glsl_dst_cleanup(&dst, &gen->string_buffers);
+}
+
static void shader_glsl_relop(struct vkd3d_glsl_generator *gen,
const struct vkd3d_shader_instruction *ins, const char *scalar_op, const char *vector_op)
{
@@ -453,6 +472,31 @@ static void shader_glsl_mov(struct vkd3d_glsl_generator *gen, const struct vkd3d
glsl_dst_cleanup(&dst, &gen->string_buffers);
}
+static void shader_glsl_movc(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins)
+{
+ unsigned int component_count;
+ struct glsl_src src[3];
+ struct glsl_dst dst;
+ uint32_t mask;
+
+ 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);
+
+ 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);
+ else
+ shader_glsl_print_assignment(gen, &dst, "mix(%s, %s, bool(%s))",
+ src[2].str->buffer, src[1].str->buffer, src[0].str->buffer);
+
+ glsl_src_cleanup(&src[2], &gen->string_buffers);
+ glsl_src_cleanup(&src[1], &gen->string_buffers);
+ glsl_src_cleanup(&src[0], &gen->string_buffers);
+ glsl_dst_cleanup(&dst, &gen->string_buffers);
+}
+
static void shader_glsl_print_sysval_name(struct vkd3d_string_buffer *buffer, struct vkd3d_glsl_generator *gen,
enum vkd3d_shader_sysval_semantic sysval, unsigned int idx)
{
@@ -608,6 +652,15 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen,
case VKD3DSIH_DCL_OUTPUT_SIV:
case VKD3DSIH_NOP:
break;
+ case VKD3DSIH_DIV:
+ shader_glsl_binop(gen, ins, "/");
+ break;
+ case VKD3DSIH_FRC:
+ shader_glsl_intrinsic(gen, ins, "fract");
+ break;
+ case VKD3DSIH_GEO:
+ shader_glsl_relop(gen, ins, ">=", "greaterThanEqual");
+ break;
case VKD3DSIH_INE:
case VKD3DSIH_NEU:
shader_glsl_relop(gen, ins, "!=", "notEqual");
@@ -615,6 +668,9 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen,
case VKD3DSIH_MOV:
shader_glsl_mov(gen, ins);
break;
+ case VKD3DSIH_MOVC:
+ shader_glsl_movc(gen, ins);
+ break;
case VKD3DSIH_MUL:
shader_glsl_binop(gen, ins, "*");
break;
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c
index 6323260eab7..f4401bc5d89 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c
@@ -276,6 +276,7 @@ bool hlsl_type_is_shader(const struct hlsl_type *type)
case HLSL_CLASS_DEPTH_STENCIL_STATE:
case HLSL_CLASS_DEPTH_STENCIL_VIEW:
case HLSL_CLASS_EFFECT_GROUP:
+ case HLSL_CLASS_ERROR:
case HLSL_CLASS_PASS:
case HLSL_CLASS_RASTERIZER_STATE:
case HLSL_CLASS_RENDER_TARGET_VIEW:
@@ -418,6 +419,7 @@ static void hlsl_type_calculate_reg_size(struct hlsl_ctx *ctx, struct hlsl_type
case HLSL_CLASS_DEPTH_STENCIL_STATE:
case HLSL_CLASS_DEPTH_STENCIL_VIEW:
case HLSL_CLASS_EFFECT_GROUP:
+ case HLSL_CLASS_ERROR:
case HLSL_CLASS_PASS:
case HLSL_CLASS_PIXEL_SHADER:
case HLSL_CLASS_RASTERIZER_STATE:
@@ -494,6 +496,7 @@ static bool type_is_single_component(const struct hlsl_type *type)
{
case HLSL_CLASS_DEPTH_STENCIL_STATE:
case HLSL_CLASS_DEPTH_STENCIL_VIEW:
+ case HLSL_CLASS_ERROR:
case HLSL_CLASS_PIXEL_SHADER:
case HLSL_CLASS_SCALAR:
case HLSL_CLASS_SAMPLER:
@@ -670,6 +673,7 @@ unsigned int hlsl_type_get_component_offset(struct hlsl_ctx *ctx, struct hlsl_ty
break;
case HLSL_CLASS_EFFECT_GROUP:
+ case HLSL_CLASS_ERROR:
case HLSL_CLASS_PASS:
case HLSL_CLASS_TECHNIQUE:
case HLSL_CLASS_VOID:
@@ -1061,6 +1065,7 @@ unsigned int hlsl_type_component_count(const struct hlsl_type *type)
case HLSL_CLASS_DEPTH_STENCIL_STATE:
case HLSL_CLASS_DEPTH_STENCIL_VIEW:
+ case HLSL_CLASS_ERROR:
case HLSL_CLASS_PIXEL_SHADER:
case HLSL_CLASS_RASTERIZER_STATE:
case HLSL_CLASS_RENDER_TARGET_VIEW:
@@ -1155,6 +1160,7 @@ bool hlsl_types_are_equal(const struct hlsl_type *t1, const struct hlsl_type *t2
case HLSL_CLASS_DEPTH_STENCIL_STATE:
case HLSL_CLASS_DEPTH_STENCIL_VIEW:
case HLSL_CLASS_EFFECT_GROUP:
+ case HLSL_CLASS_ERROR:
case HLSL_CLASS_PASS:
case HLSL_CLASS_PIXEL_SHADER:
case HLSL_CLASS_RASTERIZER_STATE:
@@ -1629,6 +1635,16 @@ struct hlsl_ir_node *hlsl_new_ternary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_ex
return hlsl_new_expr(ctx, op, operands, arg1->data_type, &arg1->loc);
}
+static struct hlsl_ir_node *hlsl_new_error_expr(struct hlsl_ctx *ctx)
+{
+ static const struct vkd3d_shader_location loc = {.source_name = "<error>"};
+ struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {0};
+
+ /* Use a dummy location; we should never report any messages related to
+ * this expression. */
+ return hlsl_new_expr(ctx, HLSL_OP0_ERROR, operands, ctx->builtin_types.error, &loc);
+}
+
struct hlsl_ir_node *hlsl_new_if(struct hlsl_ctx *ctx, struct hlsl_ir_node *condition,
struct hlsl_block *then_block, struct hlsl_block *else_block, const struct vkd3d_shader_location *loc)
{
@@ -2710,6 +2726,10 @@ struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const stru
}
return string;
+ case HLSL_CLASS_ERROR:
+ vkd3d_string_buffer_printf(string, "<error type>");
+ return string;
+
case HLSL_CLASS_DEPTH_STENCIL_STATE:
case HLSL_CLASS_DEPTH_STENCIL_VIEW:
case HLSL_CLASS_EFFECT_GROUP:
@@ -3049,6 +3069,7 @@ const char *debug_hlsl_expr_op(enum hlsl_ir_expr_op op)
{
static const char *const op_names[] =
{
+ [HLSL_OP0_ERROR] = "error",
[HLSL_OP0_VOID] = "void",
[HLSL_OP0_RASTERIZER_SAMPLE_COUNT] = "GetRenderTargetSampleCount",
@@ -3990,12 +4011,12 @@ static void declare_predefined_types(struct hlsl_ctx *ctx)
static const char * const names[] =
{
- "float",
- "half",
- "double",
- "int",
- "uint",
- "bool",
+ [HLSL_TYPE_FLOAT] = "float",
+ [HLSL_TYPE_HALF] = "half",
+ [HLSL_TYPE_DOUBLE] = "double",
+ [HLSL_TYPE_INT] = "int",
+ [HLSL_TYPE_UINT] = "uint",
+ [HLSL_TYPE_BOOL] = "bool",
};
static const char *const variants_float[] = {"min10float", "min16float"};
@@ -4146,6 +4167,7 @@ static void declare_predefined_types(struct hlsl_ctx *ctx)
ctx->builtin_types.Void = hlsl_new_simple_type(ctx, "void", HLSL_CLASS_VOID);
ctx->builtin_types.null = hlsl_new_type(ctx, "NULL", HLSL_CLASS_NULL, HLSL_TYPE_UINT, 1, 1);
ctx->builtin_types.string = hlsl_new_simple_type(ctx, "string", HLSL_CLASS_STRING);
+ ctx->builtin_types.error = hlsl_new_simple_type(ctx, "<error type>", HLSL_CLASS_ERROR);
hlsl_scope_add_type(ctx->globals, ctx->builtin_types.string);
hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "DepthStencilView", HLSL_CLASS_DEPTH_STENCIL_VIEW));
hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "DepthStencilState", HLSL_CLASS_DEPTH_STENCIL_STATE));
@@ -4248,6 +4270,7 @@ static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const struct vkd3d_shader_compil
case VKD3D_SHADER_COMPILE_OPTION_BACKWARD_COMPATIBILITY:
ctx->semantic_compat_mapping = option->value & VKD3D_SHADER_COMPILE_OPTION_BACKCOMPAT_MAP_SEMANTIC_NAMES;
+ ctx->double_as_float_alias = option->value & VKD3D_SHADER_COMPILE_OPTION_DOUBLE_AS_FLOAT_ALIAS;
break;
case VKD3D_SHADER_COMPILE_OPTION_CHILD_EFFECT:
@@ -4267,6 +4290,10 @@ static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const struct vkd3d_shader_compil
}
}
+ if (!(ctx->error_instr = hlsl_new_error_expr(ctx)))
+ return false;
+ hlsl_block_add_instr(&ctx->static_initializers, ctx->error_instr);
+
ctx->domain = VKD3D_TESSELLATOR_DOMAIN_INVALID;
ctx->output_control_point_count = UINT_MAX;
ctx->output_primitive = 0;
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h
index 20a96692a48..b8678962f67 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h
@@ -106,6 +106,7 @@ enum hlsl_type_class
HLSL_CLASS_BLEND_STATE,
HLSL_CLASS_VOID,
HLSL_CLASS_NULL,
+ HLSL_CLASS_ERROR,
};
enum hlsl_base_type
@@ -361,6 +362,9 @@ struct hlsl_block
{
/* List containing instruction nodes; linked by the hlsl_ir_node.entry fields. */
struct list instrs;
+ /* Instruction representing the "value" of this block, if applicable.
+ * This may point to an instruction outside of this block! */
+ struct hlsl_ir_node *value;
};
/* A reference to an instruction node (struct hlsl_ir_node), usable as a field in other structs.
@@ -657,6 +661,7 @@ struct hlsl_ir_switch
enum hlsl_ir_expr_op
{
+ HLSL_OP0_ERROR,
HLSL_OP0_VOID,
HLSL_OP0_RASTERIZER_SAMPLE_COUNT,
@@ -1043,8 +1048,12 @@ struct hlsl_ctx
struct hlsl_type *string;
struct hlsl_type *Void;
struct hlsl_type *null;
+ struct hlsl_type *error;
} builtin_types;
+ /* Pre-allocated "error" expression. */
+ struct hlsl_ir_node *error_instr;
+
/* List of the instruction nodes for initializing static variables. */
struct hlsl_block static_initializers;
@@ -1091,6 +1100,7 @@ struct hlsl_ctx
bool child_effect;
bool include_empty_buffers;
bool warn_implicit_truncation;
+ bool double_as_float_alias;
};
static inline bool hlsl_version_ge(const struct hlsl_ctx *ctx, unsigned int major, unsigned int minor)
@@ -1211,16 +1221,19 @@ static inline struct hlsl_ir_stateblock_constant *hlsl_ir_stateblock_constant(co
static inline void hlsl_block_init(struct hlsl_block *block)
{
list_init(&block->instrs);
+ block->value = NULL;
}
static inline void hlsl_block_add_instr(struct hlsl_block *block, struct hlsl_ir_node *instr)
{
list_add_tail(&block->instrs, &instr->entry);
+ block->value = (instr->data_type ? instr : NULL);
}
static inline void hlsl_block_add_block(struct hlsl_block *block, struct hlsl_block *add)
{
list_move_tail(&block->instrs, &add->instrs);
+ block->value = add->value;
}
static inline void hlsl_src_from_node(struct hlsl_src *src, struct hlsl_ir_node *node)
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.l b/libs/vkd3d/libs/vkd3d-shader/hlsl.l
index b7c242661e3..97d8b13772b 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.l
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.l
@@ -90,7 +90,6 @@ default {return KW_DEFAULT; }
discard {return KW_DISCARD; }
DomainShader {return KW_DOMAINSHADER; }
do {return KW_DO; }
-double {return KW_DOUBLE; }
else {return KW_ELSE; }
export {return KW_EXPORT; }
extern {return KW_EXTERN; }
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y
index 67262c2ccfd..c39f2020ef7 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y
@@ -147,7 +147,7 @@ static void yyerror(YYLTYPE *loc, void *scanner, struct hlsl_ctx *ctx, const cha
static struct hlsl_ir_node *node_from_block(struct hlsl_block *block)
{
- return LIST_ENTRY(list_tail(&block->instrs), struct hlsl_ir_node, entry);
+ return block->value;
}
static struct hlsl_block *make_empty_block(struct hlsl_ctx *ctx)
@@ -489,9 +489,10 @@ static bool append_conditional_break(struct hlsl_ctx *ctx, struct hlsl_block *co
check_condition_type(ctx, condition);
bool_type = hlsl_get_scalar_type(ctx, HLSL_TYPE_BOOL);
- if (!(cast = hlsl_new_cast(ctx, condition, bool_type, &condition->loc)))
+ /* We already checked for a 1-component numeric type, so
+ * add_implicit_conversion() is equivalent to add_cast() here. */
+ if (!(cast = add_cast(ctx, cond_block, condition, bool_type, &condition->loc)))
return false;
- hlsl_block_add_instr(cond_block, cast);
if (!(not = hlsl_new_unary_expr(ctx, HLSL_OP1_LOGIC_NOT, cast, &condition->loc)))
return false;
@@ -639,14 +640,14 @@ static struct hlsl_default_value evaluate_static_expression(struct hlsl_ctx *ctx
return ret;
hlsl_block_add_block(&expr, block);
- if (!add_implicit_conversion(ctx, &expr, node_from_block(&expr), dst_type, loc))
+ if (!(node = add_implicit_conversion(ctx, &expr, node_from_block(&expr), dst_type, loc)))
{
hlsl_block_cleanup(&expr);
return ret;
}
/* Wrap the node into a src to allow the reference to survive the multiple const passes. */
- hlsl_src_from_node(&src, node_from_block(&expr));
+ hlsl_src_from_node(&src, node);
hlsl_run_const_passes(ctx, &expr);
node = src.node;
hlsl_src_remove(&src);
@@ -1710,12 +1711,18 @@ static struct hlsl_ir_node *add_unary_arithmetic_expr(struct hlsl_ctx *ctx, stru
{
struct hlsl_ir_node *args[HLSL_MAX_OPERANDS] = {arg};
+ if (arg->data_type->class == HLSL_CLASS_ERROR)
+ return arg;
+
return add_expr(ctx, block, op, args, arg->data_type, loc);
}
static struct hlsl_ir_node *add_unary_bitwise_expr(struct hlsl_ctx *ctx, struct hlsl_block *block,
enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg, const struct vkd3d_shader_location *loc)
{
+ if (arg->data_type->class == HLSL_CLASS_ERROR)
+ return arg;
+
check_integer_type(ctx, arg);
return add_unary_arithmetic_expr(ctx, block, op, arg, loc);
@@ -1727,6 +1734,9 @@ static struct hlsl_ir_node *add_unary_logical_expr(struct hlsl_ctx *ctx, struct
struct hlsl_ir_node *args[HLSL_MAX_OPERANDS] = {0};
struct hlsl_type *bool_type;
+ if (arg->data_type->class == HLSL_CLASS_ERROR)
+ return arg;
+
bool_type = hlsl_get_numeric_type(ctx, arg->data_type->class, HLSL_TYPE_BOOL,
arg->data_type->dimx, arg->data_type->dimy);
@@ -1756,7 +1766,11 @@ static struct hlsl_ir_node *add_binary_arithmetic_expr(struct hlsl_ctx *ctx, str
struct hlsl_ir_node *args[HLSL_MAX_OPERANDS] = {0};
struct hlsl_type *common_type;
- common_type = get_common_numeric_type(ctx, arg1, arg2, loc);
+ if (!(common_type = get_common_numeric_type(ctx, arg1, arg2, loc)))
+ {
+ block->value = ctx->error_instr;
+ return block->value;
+ }
if (!(args[0] = add_implicit_conversion(ctx, block, arg1, common_type, loc)))
return NULL;
@@ -2059,18 +2073,17 @@ static bool invert_swizzle_matrix(uint32_t *swizzle, unsigned int *writemask, un
return true;
}
-static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_node *lhs,
+static bool add_assignment(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_node *lhs,
enum parse_assign_op assign_op, struct hlsl_ir_node *rhs)
{
struct hlsl_type *lhs_type = lhs->data_type;
- struct hlsl_ir_node *copy;
unsigned int writemask = 0, width = 0;
bool matrix_writemask = false;
if (assign_op == ASSIGN_OP_SUB)
{
if (!(rhs = add_unary_arithmetic_expr(ctx, block, HLSL_OP1_NEG, rhs, &rhs->loc)))
- return NULL;
+ return false;
assign_op = ASSIGN_OP_ADD;
}
if (assign_op != ASSIGN_OP_ASSIGN)
@@ -2079,7 +2092,7 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct hlsl_blo
VKD3D_ASSERT(op);
if (!(rhs = add_binary_expr(ctx, block, op, lhs, rhs, &rhs->loc)))
- return NULL;
+ return false;
}
if (hlsl_is_numeric_type(lhs_type))
@@ -2089,14 +2102,14 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct hlsl_blo
}
if (!(rhs = add_implicit_conversion(ctx, block, rhs, lhs_type, &rhs->loc)))
- return NULL;
+ return false;
while (lhs->type != HLSL_IR_LOAD && lhs->type != HLSL_IR_INDEX)
{
if (lhs->type == HLSL_IR_EXPR && hlsl_ir_expr(lhs)->op == HLSL_OP1_CAST)
{
hlsl_fixme(ctx, &lhs->loc, "Cast on the LHS.");
- return NULL;
+ return false;
}
else if (lhs->type == HLSL_IR_SWIZZLE)
{
@@ -2111,25 +2124,23 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct hlsl_blo
if (swizzle->val.node->type != HLSL_IR_LOAD && swizzle->val.node->type != HLSL_IR_INDEX)
{
hlsl_fixme(ctx, &lhs->loc, "Unhandled source of matrix swizzle.");
- return NULL;
+ return false;
}
if (!invert_swizzle_matrix(&s, &writemask, &width))
{
hlsl_error(ctx, &lhs->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_WRITEMASK, "Invalid writemask for matrix.");
- return NULL;
+ return false;
}
matrix_writemask = true;
}
else if (!invert_swizzle(&s, &writemask, &width))
{
hlsl_error(ctx, &lhs->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_WRITEMASK, "Invalid writemask.");
- return NULL;
+ return false;
}
if (!(new_swizzle = hlsl_new_swizzle(ctx, s, width, rhs, &swizzle->node.loc)))
- {
- return NULL;
- }
+ return false;
hlsl_block_add_instr(block, new_swizzle);
lhs = swizzle->val.node;
@@ -2138,7 +2149,7 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct hlsl_blo
else
{
hlsl_error(ctx, &lhs->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_LVALUE, "Invalid lvalue.");
- return NULL;
+ return false;
}
}
@@ -2153,11 +2164,11 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct hlsl_blo
if (!hlsl_index_is_resource_access(hlsl_ir_index(lhs)))
{
hlsl_fixme(ctx, &lhs->loc, "Non-direct structured resource store.");
- return NULL;
+ return false;
}
if (!hlsl_init_deref_from_index_chain(ctx, &resource_deref, hlsl_ir_index(lhs)->val.node))
- return NULL;
+ return false;
resource_type = hlsl_deref_get_type(ctx, &resource_deref);
VKD3D_ASSERT(resource_type->class == HLSL_CLASS_TEXTURE || resource_type->class == HLSL_CLASS_UAV);
@@ -2179,7 +2190,7 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct hlsl_blo
if (!(store = hlsl_new_resource_store(ctx, &resource_deref, coords, rhs, &lhs->loc)))
{
hlsl_cleanup_deref(&resource_deref);
- return NULL;
+ return false;
}
hlsl_block_add_instr(block, store);
hlsl_cleanup_deref(&resource_deref);
@@ -2206,13 +2217,13 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct hlsl_blo
if (!(load = hlsl_add_load_component(ctx, block, rhs, k++, &rhs->loc)))
{
hlsl_cleanup_deref(&deref);
- return NULL;
+ return false;
}
if (!hlsl_new_store_component(ctx, &store_block, &deref, component, load))
{
hlsl_cleanup_deref(&deref);
- return NULL;
+ return false;
}
hlsl_block_add_block(block, &store_block);
}
@@ -2237,23 +2248,23 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct hlsl_blo
continue;
if (!(c = hlsl_new_uint_constant(ctx, i, &lhs->loc)))
- return NULL;
+ return false;
hlsl_block_add_instr(block, c);
if (!(cell = hlsl_new_index(ctx, &row->node, c, &lhs->loc)))
- return NULL;
+ return false;
hlsl_block_add_instr(block, cell);
if (!(load = hlsl_add_load_component(ctx, block, rhs, k++, &rhs->loc)))
- return NULL;
+ return false;
if (!hlsl_init_deref_from_index_chain(ctx, &deref, cell))
- return NULL;
+ return false;
if (!(store = hlsl_new_store_index(ctx, &deref, NULL, load, 0, &rhs->loc)))
{
hlsl_cleanup_deref(&deref);
- return NULL;
+ return false;
}
hlsl_block_add_instr(block, store);
hlsl_cleanup_deref(&deref);
@@ -2265,24 +2276,19 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct hlsl_blo
struct hlsl_deref deref;
if (!hlsl_init_deref_from_index_chain(ctx, &deref, lhs))
- return NULL;
+ return false;
if (!(store = hlsl_new_store_index(ctx, &deref, NULL, rhs, writemask, &rhs->loc)))
{
hlsl_cleanup_deref(&deref);
- return NULL;
+ return false;
}
hlsl_block_add_instr(block, store);
hlsl_cleanup_deref(&deref);
}
- /* Don't use the instruction itself as a source, as this makes structure
- * splitting easier. Instead copy it here. Since we retrieve sources from
- * the last instruction in the list, we do need to copy. */
- if (!(copy = hlsl_new_copy(ctx, rhs)))
- return NULL;
- hlsl_block_add_instr(block, copy);
- return copy;
+ block->value = rhs;
+ return true;
}
static bool add_increment(struct hlsl_ctx *ctx, struct hlsl_block *block, bool decrement, bool post,
@@ -5340,11 +5346,6 @@ static bool add_ternary(struct hlsl_ctx *ctx, struct hlsl_block *block,
}
else
{
- cond_type = hlsl_get_numeric_type(ctx, cond_type->class, HLSL_TYPE_BOOL,
- cond_type->dimx, cond_type->dimy);
- if (!(cond = add_implicit_conversion(ctx, block, cond, cond_type, &cond->loc)))
- return false;
-
if (common_type->dimx == 1 && common_type->dimy == 1)
{
common_type = hlsl_get_numeric_type(ctx, cond_type->class,
@@ -5366,6 +5367,11 @@ static bool add_ternary(struct hlsl_ctx *ctx, struct hlsl_block *block,
hlsl_release_string_buffer(ctx, cond_string);
hlsl_release_string_buffer(ctx, value_string);
}
+
+ cond_type = hlsl_get_numeric_type(ctx, common_type->class, HLSL_TYPE_BOOL,
+ common_type->dimx, common_type->dimy);
+ if (!(cond = add_implicit_conversion(ctx, block, cond, cond_type, &cond->loc)))
+ return false;
}
if (!(first = add_implicit_conversion(ctx, block, first, common_type, &first->loc)))
@@ -6296,7 +6302,6 @@ static bool state_block_add_entry(struct hlsl_state_block *state_block, struct h
%token KW_DISCARD
%token KW_DO
%token KW_DOMAINSHADER
-%token KW_DOUBLE
%token KW_ELSE
%token KW_EXPORT
%token KW_EXTERN
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
index 6cae0e3b5c9..feab6cf06c1 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
@@ -1655,11 +1655,16 @@ static bool copy_propagation_transform_load(struct hlsl_ctx *ctx,
case HLSL_CLASS_MATRIX:
case HLSL_CLASS_ARRAY:
case HLSL_CLASS_STRUCT:
- case HLSL_CLASS_CONSTANT_BUFFER:
- /* FIXME: Actually we shouldn't even get here, but we don't split
- * matrices yet. */
+ /* We can't handle complex types here.
+ * They should have been already split anyway by earlier passes,
+ * but they may not have been deleted yet. We can't rely on DCE to
+ * solve that problem for us, since we may be called on a partial
+ * block, but DCE deletes dead stores, so it needs to be able to
+ * see the whole program. */
+ case HLSL_CLASS_ERROR:
return false;
+ case HLSL_CLASS_CONSTANT_BUFFER:
case HLSL_CLASS_EFFECT_GROUP:
case HLSL_CLASS_PASS:
case HLSL_CLASS_TECHNIQUE:
@@ -6622,7 +6627,13 @@ static bool sm1_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx,
return true;
case HLSL_TYPE_DOUBLE:
- hlsl_fixme(ctx, &instr->loc, "SM1 cast from double to float.");
+ if (ctx->double_as_float_alias)
+ {
+ sm1_generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, 0, 0, true);
+ return true;
+ }
+ hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
+ "The 'double' type is not supported for the %s profile.", ctx->profile->name);
break;
default:
@@ -6660,7 +6671,22 @@ static bool sm1_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx,
break;
case HLSL_TYPE_DOUBLE:
- hlsl_fixme(ctx, &instr->loc, "SM1 cast to double.");
+ switch (src_type->e.numeric.type)
+ {
+ case HLSL_TYPE_FLOAT:
+ if (ctx->double_as_float_alias)
+ {
+ sm1_generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, 0, 0, true);
+ return true;
+ }
+ hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
+ "The 'double' type is not supported for the %s profile.", ctx->profile->name);
+ break;
+
+ default:
+ hlsl_fixme(ctx, &instr->loc, "SM1 cast to double.");
+ break;
+ }
break;
case HLSL_TYPE_BOOL:
diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c
index 7f1e0fea2c3..1876ad38653 100644
--- a/libs/vkd3d/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c
@@ -394,6 +394,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];
struct vkd3d_spirv_stream debug_stream; /* debug instructions */
struct vkd3d_spirv_stream annotation_stream; /* decoration instructions */
@@ -1902,29 +1903,37 @@ static uint32_t vkd3d_spirv_build_op_glsl_std450_nclamp(struct vkd3d_spirv_build
static uint32_t vkd3d_spirv_get_type_id(struct vkd3d_spirv_builder *builder,
enum vkd3d_shader_component_type component_type, unsigned int component_count)
{
- uint32_t scalar_id;
+ uint32_t scalar_id, type_id;
+
+ VKD3D_ASSERT(component_type < VKD3D_SHADER_COMPONENT_TYPE_COUNT);
+ VKD3D_ASSERT(1 <= component_count && component_count <= VKD3D_VEC4_SIZE);
+
+ if ((type_id = builder->numeric_type_ids[component_type][component_count - 1]))
+ return type_id;
if (component_count == 1)
{
switch (component_type)
{
case VKD3D_SHADER_COMPONENT_VOID:
- return vkd3d_spirv_get_op_type_void(builder);
+ type_id = vkd3d_spirv_get_op_type_void(builder);
break;
case VKD3D_SHADER_COMPONENT_FLOAT:
- return vkd3d_spirv_get_op_type_float(builder, 32);
+ type_id = vkd3d_spirv_get_op_type_float(builder, 32);
break;
case VKD3D_SHADER_COMPONENT_INT:
case VKD3D_SHADER_COMPONENT_UINT:
- return vkd3d_spirv_get_op_type_int(builder, 32, component_type == VKD3D_SHADER_COMPONENT_INT);
+ type_id = vkd3d_spirv_get_op_type_int(builder, 32, component_type == VKD3D_SHADER_COMPONENT_INT);
break;
case VKD3D_SHADER_COMPONENT_BOOL:
- return vkd3d_spirv_get_op_type_bool(builder);
+ type_id = vkd3d_spirv_get_op_type_bool(builder);
break;
case VKD3D_SHADER_COMPONENT_DOUBLE:
- return vkd3d_spirv_get_op_type_float(builder, 64);
+ type_id = vkd3d_spirv_get_op_type_float(builder, 64);
+ break;
case VKD3D_SHADER_COMPONENT_UINT64:
- return vkd3d_spirv_get_op_type_int(builder, 64, 0);
+ type_id = vkd3d_spirv_get_op_type_int(builder, 64, 0);
+ break;
default:
FIXME("Unhandled component type %#x.\n", component_type);
return 0;
@@ -1934,46 +1943,21 @@ static uint32_t vkd3d_spirv_get_type_id(struct vkd3d_spirv_builder *builder,
{
VKD3D_ASSERT(component_type != VKD3D_SHADER_COMPONENT_VOID);
scalar_id = vkd3d_spirv_get_type_id(builder, component_type, 1);
- return vkd3d_spirv_get_op_type_vector(builder, scalar_id, component_count);
+ type_id = vkd3d_spirv_get_op_type_vector(builder, scalar_id, component_count);
}
+
+ builder->numeric_type_ids[component_type][component_count - 1] = type_id;
+
+ return type_id;
}
static uint32_t vkd3d_spirv_get_type_id_for_data_type(struct vkd3d_spirv_builder *builder,
enum vkd3d_data_type data_type, unsigned int component_count)
{
- uint32_t scalar_id;
+ enum vkd3d_shader_component_type component_type;
- if (component_count == 1)
- {
- switch (data_type)
- {
- case VKD3D_DATA_HALF: /* Minimum precision. TODO: native 16-bit */
- case VKD3D_DATA_FLOAT:
- case VKD3D_DATA_SNORM:
- case VKD3D_DATA_UNORM:
- return vkd3d_spirv_get_op_type_float(builder, 32);
- break;
- case VKD3D_DATA_INT:
- case VKD3D_DATA_UINT:
- case VKD3D_DATA_UINT16: /* Minimum precision. TODO: native 16-bit */
- return vkd3d_spirv_get_op_type_int(builder, 32, data_type == VKD3D_DATA_INT);
- break;
- case VKD3D_DATA_DOUBLE:
- return vkd3d_spirv_get_op_type_float(builder, 64);
- case VKD3D_DATA_UINT64:
- return vkd3d_spirv_get_op_type_int(builder, 64, 0);
- case VKD3D_DATA_BOOL:
- return vkd3d_spirv_get_op_type_bool(builder);
- default:
- FIXME("Unhandled data type %#x.\n", data_type);
- return 0;
- }
- }
- else
- {
- scalar_id = vkd3d_spirv_get_type_id_for_data_type(builder, data_type, 1);
- return vkd3d_spirv_get_op_type_vector(builder, scalar_id, component_count);
- }
+ component_type = vkd3d_component_type_from_data_type(data_type);
+ return vkd3d_spirv_get_type_id(builder, component_type, component_count);
}
static void vkd3d_spirv_builder_init(struct vkd3d_spirv_builder *builder, const char *entry_point)
diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c
index 884a2998d5b..ab9f4cf2b57 100644
--- a/libs/vkd3d/libs/vkd3d-shader/tpf.c
+++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c
@@ -3236,6 +3236,7 @@ static D3D_SHADER_VARIABLE_CLASS sm4_class(const struct hlsl_type *type)
case HLSL_CLASS_DEPTH_STENCIL_STATE:
case HLSL_CLASS_DEPTH_STENCIL_VIEW:
case HLSL_CLASS_EFFECT_GROUP:
+ case HLSL_CLASS_ERROR:
case HLSL_CLASS_STRUCT:
case HLSL_CLASS_PASS:
case HLSL_CLASS_PIXEL_SHADER:
diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
index 447210449da..7ac86e35227 100644
--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -59,6 +59,8 @@
#define VKD3D_VEC4_SIZE 4
#define VKD3D_DVEC2_SIZE 2
+#define VKD3D_SHADER_COMPONENT_TYPE_COUNT (VKD3D_SHADER_COMPONENT_UINT64 + 1)
+
enum vkd3d_shader_error
{
VKD3D_SHADER_ERROR_DXBC_INVALID_SIZE = 1,
diff --git a/libs/vkd3d/libs/vkd3d/state.c b/libs/vkd3d/libs/vkd3d/state.c
index ea7d8f040b5..fb377177403 100644
--- a/libs/vkd3d/libs/vkd3d/state.c
+++ b/libs/vkd3d/libs/vkd3d/state.c
@@ -1107,7 +1107,9 @@ static int compare_descriptor_range(const void *a, const void *b)
if ((ret = vkd3d_u32_compare(range_a->offset, range_b->offset)))
return ret;
- return (range_a->descriptor_count == UINT_MAX) - (range_b->descriptor_count == UINT_MAX);
+ /* Place bounded ranges after unbounded ones of equal offset,
+ * so the bounded range can be mapped to the unbounded one. */
+ return (range_b->descriptor_count == UINT_MAX) - (range_a->descriptor_count == UINT_MAX);
}
static HRESULT d3d12_root_signature_init_root_descriptor_tables(struct d3d12_root_signature *root_signature,
--
2.45.2