2024-10-04 18:28:16 -07:00
|
|
|
From 1b1edbf05da10281bbb9b0ef228752ec9c21ab28 Mon Sep 17 00:00:00 2001
|
2024-10-02 19:53:56 -07:00
|
|
|
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
|
|
|
|
|