You've already forked wine-staging
mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2025-09-12 18:50:20 -07:00
3495 lines
150 KiB
Diff
3495 lines
150 KiB
Diff
From 83a3253798716f86bf8ace1e2cf0fbbd829e614a Mon Sep 17 00:00:00 2001
|
|
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
|
|
Date: Fri, 14 Mar 2025 08:23:50 +1100
|
|
Subject: [PATCH] Updated vkd3d to a4f58be00c58e06b5bd60bec7eb9e37b6f112c24.
|
|
|
|
---
|
|
libs/vkd3d/include/private/vkd3d_version.h | 2 +-
|
|
libs/vkd3d/libs/vkd3d-shader/glsl.c | 9 +-
|
|
libs/vkd3d/libs/vkd3d-shader/hlsl.c | 76 +-
|
|
libs/vkd3d/libs/vkd3d-shader/hlsl.h | 31 +-
|
|
libs/vkd3d/libs/vkd3d-shader/hlsl.l | 5 +
|
|
libs/vkd3d/libs/vkd3d-shader/hlsl.y | 735 +++++---------
|
|
libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 893 ++++++++++++++----
|
|
.../libs/vkd3d-shader/hlsl_constant_ops.c | 10 +-
|
|
libs/vkd3d/libs/vkd3d-shader/tpf.c | 10 +-
|
|
.../libs/vkd3d-shader/vkd3d_shader_private.h | 3 +
|
|
10 files changed, 1057 insertions(+), 717 deletions(-)
|
|
|
|
diff --git a/libs/vkd3d/include/private/vkd3d_version.h b/libs/vkd3d/include/private/vkd3d_version.h
|
|
index a73ae3fb03c..795bc2dc490 100644
|
|
--- a/libs/vkd3d/include/private/vkd3d_version.h
|
|
+++ b/libs/vkd3d/include/private/vkd3d_version.h
|
|
@@ -1 +1 @@
|
|
-#define VKD3D_VCS_ID " (git 81dc67b1)"
|
|
+#define VKD3D_VCS_ID " (git a4f58be0)"
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/glsl.c b/libs/vkd3d/libs/vkd3d-shader/glsl.c
|
|
index ab6604bd703..a47c2feb094 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/glsl.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/glsl.c
|
|
@@ -269,15 +269,15 @@ static void shader_glsl_print_register_name(struct vkd3d_string_buffer *buffer,
|
|
vkd3d_string_buffer_printf(buffer, "<unhandled register %#x>", reg->type);
|
|
break;
|
|
}
|
|
- if (reg->idx[0].rel_addr || reg->idx[2].rel_addr)
|
|
+ if (reg->idx[0].rel_addr)
|
|
{
|
|
vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
|
|
"Internal compiler error: Unhandled constant buffer register indirect addressing.");
|
|
vkd3d_string_buffer_printf(buffer, "<unhandled register %#x>", reg->type);
|
|
break;
|
|
}
|
|
- vkd3d_string_buffer_printf(buffer, "%s_cb_%u[%u]",
|
|
- gen->prefix, reg->idx[0].offset, reg->idx[2].offset);
|
|
+ vkd3d_string_buffer_printf(buffer, "%s_cb_%u", gen->prefix, reg->idx[0].offset);
|
|
+ shader_glsl_print_subscript(buffer, gen, reg->idx[2].rel_addr, reg->idx[2].offset);
|
|
break;
|
|
|
|
case VKD3DSPR_THREADID:
|
|
@@ -485,8 +485,7 @@ static void shader_glsl_print_subscript(struct vkd3d_string_buffer *buffer, stru
|
|
vkd3d_string_buffer_printf(buffer, "[%s", r.str->buffer);
|
|
if (offset)
|
|
vkd3d_string_buffer_printf(buffer, " + %u", offset);
|
|
- else
|
|
- vkd3d_string_buffer_printf(buffer, "]");
|
|
+ vkd3d_string_buffer_printf(buffer, "]");
|
|
glsl_src_cleanup(&r, &gen->string_buffers);
|
|
}
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c
|
|
index a7641a203f3..01586592b25 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c
|
|
@@ -234,6 +234,33 @@ unsigned int hlsl_get_multiarray_size(const struct hlsl_type *type)
|
|
return 1;
|
|
}
|
|
|
|
+const struct hlsl_type *hlsl_get_stream_output_type(const struct hlsl_type *type)
|
|
+{
|
|
+ unsigned int i;
|
|
+
|
|
+ switch (type->class)
|
|
+ {
|
|
+ case HLSL_CLASS_ARRAY:
|
|
+ return hlsl_get_stream_output_type(type->e.array.type);
|
|
+
|
|
+ case HLSL_CLASS_STRUCT:
|
|
+ for (i = 0; i < type->e.record.field_count; ++i)
|
|
+ {
|
|
+ const struct hlsl_type *field_type = hlsl_get_stream_output_type(type->e.record.fields[i].type);
|
|
+
|
|
+ if (field_type)
|
|
+ return field_type;
|
|
+ }
|
|
+ return NULL;
|
|
+
|
|
+ case HLSL_CLASS_STREAM_OUTPUT:
|
|
+ return type;
|
|
+
|
|
+ default:
|
|
+ return NULL;
|
|
+ }
|
|
+}
|
|
+
|
|
bool hlsl_type_is_resource(const struct hlsl_type *type)
|
|
{
|
|
switch (type->class)
|
|
@@ -298,6 +325,12 @@ bool hlsl_type_is_patch_array(const struct hlsl_type *type)
|
|
|| type->e.array.array_type == HLSL_ARRAY_PATCH_OUTPUT);
|
|
}
|
|
|
|
+bool hlsl_type_is_primitive_array(const struct hlsl_type *type)
|
|
+{
|
|
+ return type->class == HLSL_CLASS_ARRAY && (type->e.array.array_type != HLSL_ARRAY_GENERIC
|
|
+ || (type->modifiers & HLSL_PRIMITIVE_MODIFIERS_MASK));
|
|
+}
|
|
+
|
|
bool hlsl_base_type_is_integer(enum hlsl_base_type type)
|
|
{
|
|
switch (type)
|
|
@@ -739,8 +772,7 @@ unsigned int hlsl_type_get_component_offset(struct hlsl_ctx *ctx, struct hlsl_ty
|
|
return offset[*regset];
|
|
}
|
|
|
|
-static bool init_deref(struct hlsl_ctx *ctx, struct hlsl_deref *deref, struct hlsl_ir_var *var,
|
|
- unsigned int path_len)
|
|
+bool hlsl_init_deref(struct hlsl_ctx *ctx, struct hlsl_deref *deref, struct hlsl_ir_var *var, unsigned int path_len)
|
|
{
|
|
deref->var = var;
|
|
deref->path_len = path_len;
|
|
@@ -798,7 +830,7 @@ bool hlsl_init_deref_from_index_chain(struct hlsl_ctx *ctx, struct hlsl_deref *d
|
|
}
|
|
load = hlsl_ir_load(ptr);
|
|
|
|
- if (!init_deref(ctx, deref, load->src.var, load->src.path_len + chain_len))
|
|
+ if (!hlsl_init_deref(ctx, deref, load->src.var, load->src.path_len + chain_len))
|
|
return false;
|
|
|
|
for (i = 0; i < load->src.path_len; ++i)
|
|
@@ -867,7 +899,7 @@ static bool init_deref_from_component_index(struct hlsl_ctx *ctx, struct hlsl_bl
|
|
++path_len;
|
|
}
|
|
|
|
- if (!init_deref(ctx, deref, prefix->var, prefix->path_len + path_len))
|
|
+ if (!hlsl_init_deref(ctx, deref, prefix->var, prefix->path_len + path_len))
|
|
return false;
|
|
|
|
deref_path_len = 0;
|
|
@@ -1133,6 +1165,7 @@ unsigned int hlsl_type_component_count(const struct hlsl_type *type)
|
|
case HLSL_CLASS_HULL_SHADER:
|
|
case HLSL_CLASS_GEOMETRY_SHADER:
|
|
case HLSL_CLASS_BLEND_STATE:
|
|
+ case HLSL_CLASS_STREAM_OUTPUT:
|
|
case HLSL_CLASS_NULL:
|
|
return 1;
|
|
|
|
@@ -1140,7 +1173,6 @@ unsigned int hlsl_type_component_count(const struct hlsl_type *type)
|
|
case HLSL_CLASS_PASS:
|
|
case HLSL_CLASS_TECHNIQUE:
|
|
case HLSL_CLASS_VOID:
|
|
- case HLSL_CLASS_STREAM_OUTPUT:
|
|
break;
|
|
}
|
|
|
|
@@ -1459,7 +1491,7 @@ bool hlsl_copy_deref(struct hlsl_ctx *ctx, struct hlsl_deref *deref, const struc
|
|
|
|
VKD3D_ASSERT(!hlsl_deref_is_lowered(other));
|
|
|
|
- if (!init_deref(ctx, deref, other->var, other->path_len))
|
|
+ if (!hlsl_init_deref(ctx, deref, other->var, other->path_len))
|
|
return false;
|
|
|
|
for (i = 0; i < deref->path_len; ++i)
|
|
@@ -1521,7 +1553,7 @@ struct hlsl_ir_node *hlsl_new_store_index(struct hlsl_ctx *ctx, const struct hls
|
|
return NULL;
|
|
init_node(&store->node, HLSL_IR_STORE, NULL, loc);
|
|
|
|
- if (!init_deref(ctx, &store->lhs, lhs->var, lhs->path_len + !!idx))
|
|
+ if (!hlsl_init_deref(ctx, &store->lhs, lhs->var, lhs->path_len + !!idx))
|
|
{
|
|
vkd3d_free(store);
|
|
return NULL;
|
|
@@ -1857,7 +1889,7 @@ struct hlsl_ir_load *hlsl_new_load_index(struct hlsl_ctx *ctx, const struct hlsl
|
|
return NULL;
|
|
init_node(&load->node, HLSL_IR_LOAD, type, loc);
|
|
|
|
- if (!init_deref(ctx, &load->src, deref->var, deref->path_len + !!idx))
|
|
+ if (!hlsl_init_deref(ctx, &load->src, deref->var, deref->path_len + !!idx))
|
|
{
|
|
vkd3d_free(load);
|
|
return NULL;
|
|
@@ -1939,7 +1971,7 @@ struct hlsl_ir_node *hlsl_block_add_load_component(struct hlsl_ctx *ctx, struct
|
|
return &load->node;
|
|
}
|
|
|
|
-struct hlsl_ir_node *hlsl_new_resource_load(struct hlsl_ctx *ctx,
|
|
+static struct hlsl_ir_node *hlsl_new_resource_load(struct hlsl_ctx *ctx,
|
|
const struct hlsl_resource_load_params *params, const struct vkd3d_shader_location *loc)
|
|
{
|
|
struct hlsl_ir_resource_load *load;
|
|
@@ -1978,6 +2010,12 @@ struct hlsl_ir_node *hlsl_new_resource_load(struct hlsl_ctx *ctx,
|
|
return &load->node;
|
|
}
|
|
|
|
+struct hlsl_ir_node *hlsl_block_add_resource_load(struct hlsl_ctx *ctx, struct hlsl_block *block,
|
|
+ const struct hlsl_resource_load_params *params, const struct vkd3d_shader_location *loc)
|
|
+{
|
|
+ return append_new_instr(ctx, block, hlsl_new_resource_load(ctx, params, loc));
|
|
+}
|
|
+
|
|
static struct hlsl_ir_node *hlsl_new_resource_store(struct hlsl_ctx *ctx, const struct hlsl_deref *resource,
|
|
struct hlsl_ir_node *coords, struct hlsl_ir_node *value, const struct vkd3d_shader_location *loc)
|
|
{
|
|
@@ -2022,6 +2060,12 @@ struct hlsl_ir_node *hlsl_new_swizzle(struct hlsl_ctx *ctx, uint32_t s, unsigned
|
|
return &swizzle->node;
|
|
}
|
|
|
|
+struct hlsl_ir_node *hlsl_block_add_swizzle(struct hlsl_ctx *ctx, struct hlsl_block *block, uint32_t s,
|
|
+ unsigned int width, struct hlsl_ir_node *val, const struct vkd3d_shader_location *loc)
|
|
+{
|
|
+ return append_new_instr(ctx, block, hlsl_new_swizzle(ctx, s, width, val, loc));
|
|
+}
|
|
+
|
|
struct hlsl_ir_node *hlsl_new_matrix_swizzle(struct hlsl_ctx *ctx, struct hlsl_matrix_swizzle s,
|
|
unsigned int component_count, struct hlsl_ir_node *val, const struct vkd3d_shader_location *loc)
|
|
{
|
|
@@ -2367,7 +2411,7 @@ static bool clone_deref(struct hlsl_ctx *ctx, struct clone_instr_map *map,
|
|
|
|
VKD3D_ASSERT(!hlsl_deref_is_lowered(src));
|
|
|
|
- if (!init_deref(ctx, dst, src->var, src->path_len))
|
|
+ if (!hlsl_init_deref(ctx, dst, src->var, src->path_len))
|
|
return false;
|
|
|
|
for (i = 0; i < src->path_len; ++i)
|
|
@@ -3203,6 +3247,16 @@ struct vkd3d_string_buffer *hlsl_modifiers_to_string(struct hlsl_ctx *ctx, uint3
|
|
vkd3d_string_buffer_printf(string, "row_major ");
|
|
if (modifiers & HLSL_MODIFIER_COLUMN_MAJOR)
|
|
vkd3d_string_buffer_printf(string, "column_major ");
|
|
+ if (modifiers & HLSL_PRIMITIVE_POINT)
|
|
+ vkd3d_string_buffer_printf(string, "point ");
|
|
+ if (modifiers & HLSL_PRIMITIVE_LINE)
|
|
+ vkd3d_string_buffer_printf(string, "line ");
|
|
+ if (modifiers & HLSL_PRIMITIVE_TRIANGLE)
|
|
+ vkd3d_string_buffer_printf(string, "triangle ");
|
|
+ if (modifiers & HLSL_PRIMITIVE_LINEADJ)
|
|
+ vkd3d_string_buffer_printf(string, "lineadj ");
|
|
+ if (modifiers & HLSL_PRIMITIVE_TRIANGLEADJ)
|
|
+ vkd3d_string_buffer_printf(string, "triangleadj ");
|
|
if ((modifiers & (HLSL_STORAGE_IN | HLSL_STORAGE_OUT)) == (HLSL_STORAGE_IN | HLSL_STORAGE_OUT))
|
|
vkd3d_string_buffer_printf(string, "inout ");
|
|
else if (modifiers & HLSL_STORAGE_IN)
|
|
@@ -4736,6 +4790,8 @@ static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const struct vkd3d_shader_compil
|
|
ctx->output_primitive = 0;
|
|
ctx->partitioning = 0;
|
|
ctx->input_control_point_count = UINT_MAX;
|
|
+ ctx->max_vertex_count = 0;
|
|
+ ctx->input_primitive_type = VKD3D_PT_UNDEFINED;
|
|
|
|
return true;
|
|
}
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h
|
|
index 2ef84d35ff2..98d3d17e826 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h
|
|
@@ -417,6 +417,11 @@ struct hlsl_attribute
|
|
#define HLSL_STORAGE_ANNOTATION 0x00080000
|
|
#define HLSL_MODIFIER_UNORM 0x00100000
|
|
#define HLSL_MODIFIER_SNORM 0x00200000
|
|
+#define HLSL_PRIMITIVE_POINT 0x00400000
|
|
+#define HLSL_PRIMITIVE_LINE 0x00800000
|
|
+#define HLSL_PRIMITIVE_TRIANGLE 0x01000000
|
|
+#define HLSL_PRIMITIVE_LINEADJ 0x02000000
|
|
+#define HLSL_PRIMITIVE_TRIANGLEADJ 0x04000000
|
|
|
|
#define HLSL_TYPE_MODIFIERS_MASK (HLSL_MODIFIER_PRECISE | HLSL_MODIFIER_VOLATILE | \
|
|
HLSL_MODIFIER_CONST | HLSL_MODIFIER_ROW_MAJOR | \
|
|
@@ -427,6 +432,9 @@ struct hlsl_attribute
|
|
|
|
#define HLSL_MODIFIERS_MAJORITY_MASK (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR)
|
|
|
|
+#define HLSL_PRIMITIVE_MODIFIERS_MASK (HLSL_PRIMITIVE_POINT | HLSL_PRIMITIVE_LINE | HLSL_PRIMITIVE_TRIANGLE | \
|
|
+ HLSL_PRIMITIVE_LINEADJ | HLSL_PRIMITIVE_TRIANGLEADJ)
|
|
+
|
|
#define HLSL_ARRAY_ELEMENTS_COUNT_IMPLICIT 0
|
|
|
|
/* Reservation of a register and/or an offset for objects inside constant buffers, to be used as a
|
|
@@ -1184,10 +1192,18 @@ struct hlsl_ctx
|
|
unsigned int input_control_point_count;
|
|
struct hlsl_type *input_control_point_type;
|
|
|
|
+ /* The first declared input primitive parameter in tessellation and geometry shaders. */
|
|
+ struct hlsl_ir_var *input_primitive_param;
|
|
+
|
|
/* Whether the current function being processed during HLSL codegen is
|
|
* the patch constant function in a hull shader. */
|
|
bool is_patch_constant_func;
|
|
|
|
+ /* The maximum output vertex count of a geometry shader. */
|
|
+ unsigned int max_vertex_count;
|
|
+ /* The input primitive type of a geometry shader. */
|
|
+ enum vkd3d_primitive_type input_primitive_type;
|
|
+
|
|
/* In some cases we generate opcodes by parsing an HLSL function and then
|
|
* invoking it. If not NULL, this field is the name of the function that we
|
|
* are currently parsing, "mangled" with an internal prefix to avoid
|
|
@@ -1458,6 +1474,11 @@ static inline bool hlsl_is_numeric_type(const struct hlsl_type *type)
|
|
return type->class <= HLSL_CLASS_LAST_NUMERIC;
|
|
}
|
|
|
|
+static inline bool hlsl_is_vec1(const struct hlsl_type *type)
|
|
+{
|
|
+ return type->class == HLSL_CLASS_SCALAR || (type->class == HLSL_CLASS_VECTOR && type->e.numeric.dimx == 1);
|
|
+}
|
|
+
|
|
static inline unsigned int hlsl_sampler_dim_count(enum hlsl_sampler_dim dim)
|
|
{
|
|
switch (dim)
|
|
@@ -1530,6 +1551,8 @@ struct hlsl_ir_node *hlsl_block_add_load_index(struct hlsl_ctx *ctx, struct hlsl
|
|
void hlsl_block_add_loop(struct hlsl_ctx *ctx, struct hlsl_block *block,
|
|
struct hlsl_block *iter, struct hlsl_block *body, enum hlsl_loop_unroll_type unroll_type,
|
|
unsigned int unroll_limit, const struct vkd3d_shader_location *loc);
|
|
+struct hlsl_ir_node *hlsl_block_add_resource_load(struct hlsl_ctx *ctx, struct hlsl_block *block,
|
|
+ const struct hlsl_resource_load_params *params, const struct vkd3d_shader_location *loc);
|
|
void hlsl_block_add_resource_store(struct hlsl_ctx *ctx, struct hlsl_block *block, const struct hlsl_deref *resource,
|
|
struct hlsl_ir_node *coords, struct hlsl_ir_node *value, const struct vkd3d_shader_location *loc);
|
|
struct hlsl_ir_node *hlsl_block_add_simple_load(struct hlsl_ctx *ctx, struct hlsl_block *block,
|
|
@@ -1541,6 +1564,8 @@ void hlsl_block_add_store_component(struct hlsl_ctx *ctx, struct hlsl_block *blo
|
|
void hlsl_block_add_store_index(struct hlsl_ctx *ctx, struct hlsl_block *block,
|
|
const struct hlsl_deref *lhs, struct hlsl_ir_node *idx, struct hlsl_ir_node *rhs,
|
|
unsigned int writemask, const struct vkd3d_shader_location *loc);
|
|
+struct hlsl_ir_node *hlsl_block_add_swizzle(struct hlsl_ctx *ctx, struct hlsl_block *block, uint32_t s,
|
|
+ unsigned int width, struct hlsl_ir_node *val, const struct vkd3d_shader_location *loc);
|
|
struct hlsl_ir_node *hlsl_block_add_uint_constant(struct hlsl_ctx *ctx, struct hlsl_block *block,
|
|
unsigned int n, const struct vkd3d_shader_location *loc);
|
|
struct hlsl_ir_node *hlsl_block_add_unary_expr(struct hlsl_ctx *ctx, struct hlsl_block *block,
|
|
@@ -1567,6 +1592,7 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry
|
|
enum vkd3d_shader_target_type target_type, struct vkd3d_shader_code *out);
|
|
int hlsl_emit_effect_binary(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out);
|
|
|
|
+bool hlsl_init_deref(struct hlsl_ctx *ctx, struct hlsl_deref *deref, struct hlsl_ir_var *var, unsigned int path_len);
|
|
bool hlsl_init_deref_from_index_chain(struct hlsl_ctx *ctx, struct hlsl_deref *deref, struct hlsl_ir_node *chain);
|
|
bool hlsl_copy_deref(struct hlsl_ctx *ctx, struct hlsl_deref *deref, const struct hlsl_deref *other);
|
|
|
|
@@ -1653,8 +1679,6 @@ struct hlsl_ir_node *hlsl_new_interlocked(struct hlsl_ctx *ctx, enum hlsl_interl
|
|
struct hlsl_ir_node *value, const struct vkd3d_shader_location *loc);
|
|
struct hlsl_ir_node *hlsl_new_matrix_swizzle(struct hlsl_ctx *ctx, struct hlsl_matrix_swizzle s,
|
|
unsigned int width, struct hlsl_ir_node *val, const struct vkd3d_shader_location *loc);
|
|
-struct hlsl_ir_node *hlsl_new_resource_load(struct hlsl_ctx *ctx,
|
|
- const struct hlsl_resource_load_params *params, const struct vkd3d_shader_location *loc);
|
|
struct hlsl_type *hlsl_new_struct_type(struct hlsl_ctx *ctx, const char *name,
|
|
struct hlsl_struct_field *fields, size_t field_count);
|
|
struct hlsl_ir_node *hlsl_new_swizzle(struct hlsl_ctx *ctx, uint32_t s, unsigned int components,
|
|
@@ -1719,6 +1743,7 @@ bool hlsl_type_is_integer(const struct hlsl_type *type);
|
|
bool hlsl_type_is_resource(const struct hlsl_type *type);
|
|
bool hlsl_type_is_shader(const struct hlsl_type *type);
|
|
bool hlsl_type_is_patch_array(const struct hlsl_type *type);
|
|
+bool hlsl_type_is_primitive_array(const struct hlsl_type *type);
|
|
unsigned int hlsl_type_get_sm4_offset(const struct hlsl_type *type, unsigned int offset);
|
|
bool hlsl_types_are_equal(const struct hlsl_type *t1, const struct hlsl_type *t2);
|
|
|
|
@@ -1727,6 +1752,8 @@ void hlsl_calculate_buffer_offsets(struct hlsl_ctx *ctx);
|
|
const struct hlsl_type *hlsl_get_multiarray_element_type(const struct hlsl_type *type);
|
|
unsigned int hlsl_get_multiarray_size(const struct hlsl_type *type);
|
|
|
|
+const struct hlsl_type *hlsl_get_stream_output_type(const struct hlsl_type *type);
|
|
+
|
|
uint32_t hlsl_combine_swizzles(uint32_t first, uint32_t second, unsigned int dim);
|
|
unsigned int hlsl_combine_writemasks(unsigned int first, unsigned int second);
|
|
uint32_t hlsl_map_swizzle(uint32_t swizzle, unsigned int writemask);
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.l b/libs/vkd3d/libs/vkd3d-shader/hlsl.l
|
|
index 605a9abaa93..d9fd43b5e78 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.l
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.l
|
|
@@ -106,6 +106,8 @@ inline {return KW_INLINE; }
|
|
inout {return KW_INOUT; }
|
|
InputPatch {return KW_INPUTPATCH; }
|
|
LineStream {return KW_LINESTREAM; }
|
|
+line {return KW_LINE; }
|
|
+lineadj {return KW_LINEADJ; }
|
|
linear {return KW_LINEAR; }
|
|
matrix {return KW_MATRIX; }
|
|
namespace {return KW_NAMESPACE; }
|
|
@@ -119,6 +121,7 @@ pass {return KW_PASS; }
|
|
PixelShader {return KW_PIXELSHADER; }
|
|
PointStream {return KW_POINTSTREAM; }
|
|
pixelshader {return KW_PIXELSHADER; }
|
|
+point {return KW_POINT; }
|
|
RasterizerOrderedBuffer {return KW_RASTERIZERORDEREDBUFFER; }
|
|
RasterizerOrderedStructuredBuffer {return KW_RASTERIZERORDEREDSTRUCTUREDBUFFER; }
|
|
RasterizerOrderedTexture1D {return KW_RASTERIZERORDEREDTEXTURE1D; }
|
|
@@ -175,6 +178,8 @@ TextureCube {return KW_TEXTURECUBE; }
|
|
textureCUBE {return KW_TEXTURECUBE; }
|
|
TextureCubeArray {return KW_TEXTURECUBEARRAY; }
|
|
TriangleStream {return KW_TRIANGLESTREAM; }
|
|
+triangle {return KW_TRIANGLE; }
|
|
+triangleadj {return KW_TRIANGLEADJ; }
|
|
true {return KW_TRUE; }
|
|
typedef {return KW_TYPEDEF; }
|
|
unsigned {return KW_UNSIGNED; }
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y
|
|
index 71802fce388..ff3d58da8f4 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y
|
|
@@ -372,7 +372,15 @@ static struct hlsl_ir_node *add_implicit_conversion(struct hlsl_ctx *ctx, struct
|
|
if (node->type == HLSL_IR_SAMPLER_STATE && dst_type->class == HLSL_CLASS_SAMPLER)
|
|
return node;
|
|
|
|
- if (!implicit_compatible_data_types(ctx, src_type, dst_type))
|
|
+ if (implicit_compatible_data_types(ctx, src_type, dst_type))
|
|
+ {
|
|
+ if (hlsl_is_numeric_type(dst_type) && hlsl_is_numeric_type(src_type)
|
|
+ && dst_type->e.numeric.dimx * dst_type->e.numeric.dimy < src_type->e.numeric.dimx * src_type->e.numeric.dimy
|
|
+ && ctx->warn_implicit_truncation)
|
|
+ hlsl_warning(ctx, loc, VKD3D_SHADER_WARNING_HLSL_IMPLICIT_TRUNCATION, "Implicit truncation of %s type.",
|
|
+ src_type->class == HLSL_CLASS_VECTOR ? "vector" : "matrix");
|
|
+ }
|
|
+ else
|
|
{
|
|
struct vkd3d_string_buffer *src_string, *dst_string;
|
|
|
|
@@ -383,19 +391,12 @@ static struct hlsl_ir_node *add_implicit_conversion(struct hlsl_ctx *ctx, struct
|
|
"Can't implicitly convert from %s to %s.", src_string->buffer, dst_string->buffer);
|
|
hlsl_release_string_buffer(ctx, src_string);
|
|
hlsl_release_string_buffer(ctx, dst_string);
|
|
- return NULL;
|
|
}
|
|
|
|
- if (hlsl_is_numeric_type(dst_type) && hlsl_is_numeric_type(src_type)
|
|
- && dst_type->e.numeric.dimx * dst_type->e.numeric.dimy < src_type->e.numeric.dimx * src_type->e.numeric.dimy
|
|
- && ctx->warn_implicit_truncation)
|
|
- hlsl_warning(ctx, loc, VKD3D_SHADER_WARNING_HLSL_IMPLICIT_TRUNCATION, "Implicit truncation of %s type.",
|
|
- src_type->class == HLSL_CLASS_VECTOR ? "vector" : "matrix");
|
|
-
|
|
return add_cast(ctx, block, node, dst_type, loc);
|
|
}
|
|
|
|
-static bool add_explicit_conversion(struct hlsl_ctx *ctx, struct hlsl_block *block,
|
|
+static void add_explicit_conversion(struct hlsl_ctx *ctx, struct hlsl_block *block,
|
|
struct hlsl_type *dst_type, const struct parse_array_sizes *arrays, const struct vkd3d_shader_location *loc)
|
|
{
|
|
struct hlsl_ir_node *instr = node_from_block(block);
|
|
@@ -414,7 +415,7 @@ static bool add_explicit_conversion(struct hlsl_ctx *ctx, struct hlsl_block *blo
|
|
}
|
|
|
|
if (instr->data_type->class == HLSL_CLASS_ERROR)
|
|
- return true;
|
|
+ return;
|
|
|
|
if (!explicit_compatible_data_types(ctx, src_type, dst_type))
|
|
{
|
|
@@ -427,10 +428,9 @@ static bool add_explicit_conversion(struct hlsl_ctx *ctx, struct hlsl_block *blo
|
|
src_string->buffer, dst_string->buffer);
|
|
hlsl_release_string_buffer(ctx, src_string);
|
|
hlsl_release_string_buffer(ctx, dst_string);
|
|
- return false;
|
|
}
|
|
|
|
- return add_cast(ctx, block, instr, dst_type, loc);
|
|
+ add_cast(ctx, block, instr, dst_type, loc);
|
|
}
|
|
|
|
static uint32_t add_modifiers(struct hlsl_ctx *ctx, uint32_t modifiers, uint32_t mod,
|
|
@@ -449,7 +449,7 @@ static uint32_t add_modifiers(struct hlsl_ctx *ctx, uint32_t modifiers, uint32_t
|
|
return modifiers | mod;
|
|
}
|
|
|
|
-static bool append_conditional_break(struct hlsl_ctx *ctx, struct hlsl_block *cond_block)
|
|
+static void append_conditional_break(struct hlsl_ctx *ctx, struct hlsl_block *cond_block)
|
|
{
|
|
struct hlsl_ir_node *condition, *cast, *not;
|
|
struct hlsl_block then_block;
|
|
@@ -457,7 +457,7 @@ static bool append_conditional_break(struct hlsl_ctx *ctx, struct hlsl_block *co
|
|
|
|
/* E.g. "for (i = 0; ; ++i)". */
|
|
if (list_empty(&cond_block->instrs))
|
|
- return true;
|
|
+ return;
|
|
|
|
condition = node_from_block(cond_block);
|
|
|
|
@@ -466,15 +466,12 @@ static bool append_conditional_break(struct hlsl_ctx *ctx, struct hlsl_block *co
|
|
bool_type = hlsl_get_scalar_type(ctx, HLSL_TYPE_BOOL);
|
|
/* 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;
|
|
-
|
|
+ cast = add_cast(ctx, cond_block, condition, bool_type, &condition->loc);
|
|
not = hlsl_block_add_unary_expr(ctx, cond_block, HLSL_OP1_LOGIC_NOT, cast, &condition->loc);
|
|
|
|
hlsl_block_init(&then_block);
|
|
hlsl_block_add_jump(ctx, &then_block, HLSL_IR_JUMP_BREAK, NULL, &condition->loc);
|
|
hlsl_block_add_if(ctx, cond_block, not, &then_block, NULL, &condition->loc);
|
|
- return true;
|
|
}
|
|
|
|
static void check_attribute_list_for_duplicates(struct hlsl_ctx *ctx, const struct parse_attribute_list *attrs)
|
|
@@ -518,11 +515,7 @@ static void resolve_loop_continue(struct hlsl_ctx *ctx, struct hlsl_block *block
|
|
{
|
|
if (!hlsl_clone_block(ctx, &cond_block, cond))
|
|
return;
|
|
- if (!append_conditional_break(ctx, &cond_block))
|
|
- {
|
|
- hlsl_block_cleanup(&cond_block);
|
|
- return;
|
|
- }
|
|
+ append_conditional_break(ctx, &cond_block);
|
|
list_move_before(&instr->entry, &cond_block.instrs);
|
|
}
|
|
}
|
|
@@ -598,11 +591,7 @@ static struct hlsl_default_value evaluate_static_expression(struct hlsl_ctx *ctx
|
|
return ret;
|
|
hlsl_block_add_block(&expr, block);
|
|
|
|
- if (!(node = add_implicit_conversion(ctx, &expr, node_from_block(&expr), dst_type, loc)))
|
|
- {
|
|
- hlsl_block_cleanup(&expr);
|
|
- return ret;
|
|
- }
|
|
+ node = add_implicit_conversion(ctx, &expr, node_from_block(&expr), dst_type, loc);
|
|
|
|
/* Wrap the node into a src to allow the reference to survive the multiple const passes. */
|
|
hlsl_src_from_node(&src, node);
|
|
@@ -705,8 +694,7 @@ static struct hlsl_block *create_loop(struct hlsl_ctx *ctx, enum hlsl_loop_type
|
|
if (!init && !(init = make_empty_block(ctx)))
|
|
goto oom;
|
|
|
|
- if (!append_conditional_break(ctx, cond))
|
|
- goto oom;
|
|
+ append_conditional_break(ctx, cond);
|
|
|
|
if (type == HLSL_LOOP_DO_WHILE)
|
|
list_move_tail(&body->instrs, &cond->instrs);
|
|
@@ -850,9 +838,7 @@ static bool add_return(struct hlsl_ctx *ctx, struct hlsl_block *block,
|
|
if (return_value->data_type->class == HLSL_CLASS_ERROR)
|
|
return true;
|
|
|
|
- if (!(return_value = add_implicit_conversion(ctx, block, return_value, return_type, loc)))
|
|
- return false;
|
|
-
|
|
+ return_value = add_implicit_conversion(ctx, block, return_value, return_type, loc);
|
|
hlsl_block_add_simple_store(ctx, block, ctx->cur_function->return_var, return_value);
|
|
}
|
|
else
|
|
@@ -931,10 +917,8 @@ static bool add_array_access(struct hlsl_ctx *ctx, struct hlsl_block *block, str
|
|
return false;
|
|
}
|
|
|
|
- if (!(index = add_implicit_conversion(ctx, block, index,
|
|
- hlsl_get_vector_type(ctx, HLSL_TYPE_UINT, dim_count), &index->loc)))
|
|
- return false;
|
|
-
|
|
+ index = add_implicit_conversion(ctx, block, index,
|
|
+ hlsl_get_vector_type(ctx, HLSL_TYPE_UINT, dim_count), &index->loc);
|
|
hlsl_block_add_index(ctx, block, array, index, loc);
|
|
return true;
|
|
}
|
|
@@ -1196,6 +1180,14 @@ static bool add_typedef(struct hlsl_ctx *ctx, struct hlsl_type *const orig_type,
|
|
return true;
|
|
}
|
|
|
|
+static void check_invalid_stream_output_object(struct hlsl_ctx *ctx, const struct hlsl_type *type,
|
|
+ const char *name, const struct vkd3d_shader_location* loc)
|
|
+{
|
|
+ if (hlsl_type_component_count(type) != 1)
|
|
+ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
|
|
+ "Stream output object '%s' is not single-element.", name);
|
|
+}
|
|
+
|
|
static void initialize_var_components(struct hlsl_ctx *ctx, struct hlsl_block *instrs,
|
|
struct hlsl_ir_var *dst, unsigned int *store_index, struct hlsl_ir_node *src,
|
|
bool is_default_values_initializer);
|
|
@@ -1230,6 +1222,9 @@ static bool add_func_parameter(struct hlsl_ctx *ctx, struct hlsl_func_parameters
|
|
hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER,
|
|
"Output parameter '%s' has a default value.", param->name);
|
|
|
|
+ if (hlsl_get_stream_output_type(param->type))
|
|
+ check_invalid_stream_output_object(ctx, param->type, param->name, loc);
|
|
+
|
|
if (!(var = hlsl_new_var(ctx, param->name, param->type, loc, ¶m->semantic, param->modifiers,
|
|
¶m->reg_reservation)))
|
|
return false;
|
|
@@ -1246,9 +1241,7 @@ static bool add_func_parameter(struct hlsl_ctx *ctx, struct hlsl_func_parameters
|
|
|
|
if (!param->initializer.braces)
|
|
{
|
|
- if (!(add_implicit_conversion(ctx, param->initializer.instrs, param->initializer.args[0], param->type, loc)))
|
|
- return false;
|
|
-
|
|
+ add_implicit_conversion(ctx, param->initializer.instrs, param->initializer.args[0], param->type, loc);
|
|
param->initializer.args[0] = node_from_block(param->initializer.instrs);
|
|
}
|
|
|
|
@@ -1645,10 +1638,7 @@ static struct hlsl_ir_node *add_unary_logical_expr(struct hlsl_ctx *ctx, struct
|
|
|
|
bool_type = hlsl_get_numeric_type(ctx, arg->data_type->class, HLSL_TYPE_BOOL,
|
|
arg->data_type->e.numeric.dimx, arg->data_type->e.numeric.dimy);
|
|
-
|
|
- if (!(args[0] = add_implicit_conversion(ctx, block, arg, bool_type, loc)))
|
|
- return NULL;
|
|
-
|
|
+ args[0] = add_implicit_conversion(ctx, block, arg, bool_type, loc);
|
|
return add_expr(ctx, block, op, args, bool_type, loc);
|
|
}
|
|
|
|
@@ -1678,12 +1668,8 @@ static struct hlsl_ir_node *add_binary_arithmetic_expr(struct hlsl_ctx *ctx, str
|
|
return block->value;
|
|
}
|
|
|
|
- if (!(args[0] = add_implicit_conversion(ctx, block, arg1, common_type, loc)))
|
|
- return NULL;
|
|
-
|
|
- if (!(args[1] = add_implicit_conversion(ctx, block, arg2, common_type, loc)))
|
|
- return NULL;
|
|
-
|
|
+ args[0] = add_implicit_conversion(ctx, block, arg1, common_type, loc);
|
|
+ args[1] = add_implicit_conversion(ctx, block, arg2, common_type, loc);
|
|
return add_expr(ctx, block, op, args, common_type, loc);
|
|
}
|
|
|
|
@@ -1714,12 +1700,8 @@ static struct hlsl_ir_node *add_binary_comparison_expr(struct hlsl_ctx *ctx, str
|
|
common_type = hlsl_get_numeric_type(ctx, type, base, dimx, dimy);
|
|
return_type = hlsl_get_numeric_type(ctx, type, HLSL_TYPE_BOOL, dimx, dimy);
|
|
|
|
- if (!(args[0] = add_implicit_conversion(ctx, block, arg1, common_type, loc)))
|
|
- return NULL;
|
|
-
|
|
- if (!(args[1] = add_implicit_conversion(ctx, block, arg2, common_type, loc)))
|
|
- return NULL;
|
|
-
|
|
+ args[0] = add_implicit_conversion(ctx, block, arg1, common_type, loc);
|
|
+ args[1] = add_implicit_conversion(ctx, block, arg2, common_type, loc);
|
|
return add_expr(ctx, block, op, args, return_type, loc);
|
|
}
|
|
|
|
@@ -1737,12 +1719,8 @@ static struct hlsl_ir_node *add_binary_logical_expr(struct hlsl_ctx *ctx, struct
|
|
|
|
common_type = hlsl_get_numeric_type(ctx, type, HLSL_TYPE_BOOL, dimx, dimy);
|
|
|
|
- if (!(args[0] = add_implicit_conversion(ctx, block, arg1, common_type, loc)))
|
|
- return NULL;
|
|
-
|
|
- if (!(args[1] = add_implicit_conversion(ctx, block, arg2, common_type, loc)))
|
|
- return NULL;
|
|
-
|
|
+ args[0] = add_implicit_conversion(ctx, block, arg1, common_type, loc);
|
|
+ args[1] = add_implicit_conversion(ctx, block, arg2, common_type, loc);
|
|
return add_expr(ctx, block, op, args, common_type, loc);
|
|
}
|
|
|
|
@@ -1768,12 +1746,8 @@ static struct hlsl_ir_node *add_binary_shift_expr(struct hlsl_ctx *ctx, struct h
|
|
return_type = hlsl_get_numeric_type(ctx, type, base, dimx, dimy);
|
|
integer_type = hlsl_get_numeric_type(ctx, type, HLSL_TYPE_INT, dimx, dimy);
|
|
|
|
- if (!(args[0] = add_implicit_conversion(ctx, block, arg1, return_type, loc)))
|
|
- return NULL;
|
|
-
|
|
- if (!(args[1] = add_implicit_conversion(ctx, block, arg2, integer_type, loc)))
|
|
- return NULL;
|
|
-
|
|
+ args[0] = add_implicit_conversion(ctx, block, arg1, return_type, loc);
|
|
+ args[1] = add_implicit_conversion(ctx, block, arg2, integer_type, loc);
|
|
return add_expr(ctx, block, op, args, return_type, loc);
|
|
}
|
|
|
|
@@ -1821,12 +1795,8 @@ static struct hlsl_ir_node *add_binary_dot_expr(struct hlsl_ctx *ctx, struct hls
|
|
common_type = hlsl_get_vector_type(ctx, base, dim);
|
|
ret_type = hlsl_get_scalar_type(ctx, base);
|
|
|
|
- if (!(args[0] = add_implicit_conversion(ctx, instrs, arg1, common_type, loc)))
|
|
- return NULL;
|
|
-
|
|
- if (!(args[1] = add_implicit_conversion(ctx, instrs, arg2, common_type, loc)))
|
|
- return NULL;
|
|
-
|
|
+ args[0] = add_implicit_conversion(ctx, instrs, arg1, common_type, loc);
|
|
+ args[1] = add_implicit_conversion(ctx, instrs, arg2, common_type, loc);
|
|
return add_expr(ctx, instrs, op, args, ret_type, loc);
|
|
}
|
|
|
|
@@ -2022,8 +1992,7 @@ static bool add_assignment(struct hlsl_ctx *ctx, struct hlsl_block *block, struc
|
|
width = size;
|
|
}
|
|
|
|
- if (!(rhs = add_implicit_conversion(ctx, block, rhs, lhs_type, &rhs->loc)))
|
|
- return false;
|
|
+ rhs = add_implicit_conversion(ctx, block, rhs, lhs_type, &rhs->loc);
|
|
|
|
while (lhs->type != HLSL_IR_LOAD && lhs->type != HLSL_IR_INDEX)
|
|
{
|
|
@@ -2053,7 +2022,6 @@ static bool add_assignment(struct hlsl_ctx *ctx, struct hlsl_block *block, struc
|
|
else if (lhs->type == HLSL_IR_SWIZZLE)
|
|
{
|
|
struct hlsl_ir_swizzle *swizzle = hlsl_ir_swizzle(lhs);
|
|
- struct hlsl_ir_node *new_swizzle;
|
|
uint32_t s;
|
|
|
|
VKD3D_ASSERT(!matrix_writemask);
|
|
@@ -2084,13 +2052,9 @@ static bool add_assignment(struct hlsl_ctx *ctx, struct hlsl_block *block, struc
|
|
}
|
|
}
|
|
|
|
- if (!(new_swizzle = hlsl_new_swizzle(ctx, s, width, rhs, &swizzle->node.loc)))
|
|
- return false;
|
|
- hlsl_block_add_instr(block, new_swizzle);
|
|
-
|
|
+ rhs = hlsl_block_add_swizzle(ctx, block, s, width, rhs, &swizzle->node.loc);
|
|
lhs = swizzle->val.node;
|
|
lhs_type = hlsl_get_vector_type(ctx, lhs_type->e.numeric.type, width);
|
|
- rhs = new_swizzle;
|
|
}
|
|
else
|
|
{
|
|
@@ -2102,8 +2066,7 @@ static bool add_assignment(struct hlsl_ctx *ctx, struct hlsl_block *block, struc
|
|
/* lhs casts could have resulted in a discrepancy between the
|
|
* rhs->data_type and the type of the variable that will be ulimately
|
|
* stored to. This is corrected. */
|
|
- if (!(rhs = add_cast(ctx, block, rhs, lhs_type, &rhs->loc)))
|
|
- return false;
|
|
+ rhs = add_cast(ctx, block, rhs, lhs_type, &rhs->loc);
|
|
|
|
if (lhs->type == HLSL_IR_INDEX && hlsl_index_chain_has_resource_access(hlsl_ir_index(lhs)))
|
|
{
|
|
@@ -2325,9 +2288,7 @@ static void initialize_var_components(struct hlsl_ctx *ctx, struct hlsl_block *i
|
|
}
|
|
else
|
|
{
|
|
- if (!(conv = add_implicit_conversion(ctx, instrs, load, dst_comp_type, &src->loc)))
|
|
- return;
|
|
-
|
|
+ conv = add_implicit_conversion(ctx, instrs, load, dst_comp_type, &src->loc);
|
|
hlsl_block_add_store_component(ctx, instrs, &dst_deref, *store_index, conv);
|
|
}
|
|
}
|
|
@@ -2401,10 +2362,10 @@ static bool type_has_numeric_components(struct hlsl_type *type)
|
|
return false;
|
|
}
|
|
|
|
-static void check_invalid_in_out_modifiers(struct hlsl_ctx *ctx, unsigned int modifiers,
|
|
+static void check_invalid_non_parameter_modifiers(struct hlsl_ctx *ctx, unsigned int modifiers,
|
|
const struct vkd3d_shader_location *loc)
|
|
{
|
|
- modifiers &= (HLSL_STORAGE_IN | HLSL_STORAGE_OUT);
|
|
+ modifiers &= (HLSL_STORAGE_IN | HLSL_STORAGE_OUT | HLSL_PRIMITIVE_MODIFIERS_MASK);
|
|
if (modifiers)
|
|
{
|
|
struct vkd3d_string_buffer *string;
|
|
@@ -2438,6 +2399,7 @@ static void declare_var(struct hlsl_ctx *ctx, struct parse_variable_def *v)
|
|
bool constant_buffer = false;
|
|
struct hlsl_ir_var *var;
|
|
struct hlsl_type *type;
|
|
+ bool stream_output;
|
|
char *var_name;
|
|
unsigned int i;
|
|
|
|
@@ -2529,6 +2491,10 @@ static void declare_var(struct hlsl_ctx *ctx, struct parse_variable_def *v)
|
|
hlsl_fixme(ctx, &v->loc, "Shader model 5.1+ resource array.");
|
|
}
|
|
|
|
+ stream_output = !!hlsl_get_stream_output_type(type);
|
|
+ if (stream_output)
|
|
+ check_invalid_stream_output_object(ctx, type, v->name, &v->loc);
|
|
+
|
|
if (!(var_name = vkd3d_strdup(v->name)))
|
|
return;
|
|
|
|
@@ -2583,6 +2549,10 @@ static void declare_var(struct hlsl_ctx *ctx, struct parse_variable_def *v)
|
|
if (!(modifiers & HLSL_STORAGE_STATIC))
|
|
var->storage_modifiers |= HLSL_STORAGE_UNIFORM;
|
|
|
|
+ if (stream_output)
|
|
+ hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_MISPLACED_STREAM_OUTPUT,
|
|
+ "Stream output object '%s' is not allowed in the global scope.", var->name);
|
|
+
|
|
if ((ctx->profile->major_version < 5 || ctx->profile->type == VKD3D_SHADER_TYPE_EFFECT)
|
|
&& (var->storage_modifiers & HLSL_STORAGE_UNIFORM))
|
|
{
|
|
@@ -2713,15 +2683,8 @@ static struct hlsl_block *initialize_vars(struct hlsl_ctx *ctx, struct list *var
|
|
}
|
|
|
|
if (!v->initializer.braces)
|
|
- {
|
|
- if (!(add_implicit_conversion(ctx, v->initializer.instrs, v->initializer.args[0], type, &v->loc)))
|
|
- {
|
|
- free_parse_variable_def(v);
|
|
- continue;
|
|
- }
|
|
-
|
|
- v->initializer.args[0] = node_from_block(v->initializer.instrs);
|
|
- }
|
|
+ v->initializer.args[0] = add_implicit_conversion(ctx,
|
|
+ v->initializer.instrs, v->initializer.args[0], type, &v->loc);
|
|
|
|
if (var->data_type->class != HLSL_CLASS_ERROR)
|
|
initialize_var(ctx, var, &v->initializer, is_default_values_initializer);
|
|
@@ -2755,13 +2718,7 @@ static struct hlsl_block *initialize_vars(struct hlsl_ctx *ctx, struct list *var
|
|
}
|
|
|
|
zero = hlsl_block_add_uint_constant(ctx, &ctx->static_initializers, 0, &var->loc);
|
|
-
|
|
- if (!(cast = add_cast(ctx, &ctx->static_initializers, zero, var->data_type, &var->loc)))
|
|
- {
|
|
- free_parse_variable_def(v);
|
|
- continue;
|
|
- }
|
|
-
|
|
+ cast = add_cast(ctx, &ctx->static_initializers, zero, var->data_type, &var->loc);
|
|
hlsl_block_add_simple_store(ctx, &ctx->static_initializers, var, cast);
|
|
}
|
|
free_parse_variable_def(v);
|
|
@@ -3033,13 +2990,7 @@ static struct hlsl_ir_node *add_user_call(struct hlsl_ctx *ctx,
|
|
if (param->storage_modifiers & HLSL_STORAGE_IN)
|
|
{
|
|
if (!hlsl_types_are_equal(arg->data_type, param->data_type))
|
|
- {
|
|
- struct hlsl_ir_node *cast;
|
|
-
|
|
- if (!(cast = add_cast(ctx, args->instrs, arg, param->data_type, &arg->loc)))
|
|
- return NULL;
|
|
- arg = cast;
|
|
- }
|
|
+ arg = add_cast(ctx, args->instrs, arg, param->data_type, &arg->loc);
|
|
|
|
hlsl_block_add_simple_store(ctx, args->instrs, param, arg);
|
|
}
|
|
@@ -3125,21 +3076,13 @@ static struct hlsl_ir_node *intrinsic_float_convert_arg(struct hlsl_ctx *ctx,
|
|
return add_implicit_conversion(ctx, params->instrs, arg, type, loc);
|
|
}
|
|
|
|
-static bool convert_args(struct hlsl_ctx *ctx, const struct parse_initializer *params,
|
|
+static void convert_args(struct hlsl_ctx *ctx, const struct parse_initializer *params,
|
|
struct hlsl_type *type, const struct vkd3d_shader_location *loc)
|
|
{
|
|
unsigned int i;
|
|
|
|
for (i = 0; i < params->args_count; ++i)
|
|
- {
|
|
- struct hlsl_ir_node *new_arg;
|
|
-
|
|
- if (!(new_arg = add_implicit_conversion(ctx, params->instrs, params->args[i], type, loc)))
|
|
- return false;
|
|
- params->args[i] = new_arg;
|
|
- }
|
|
-
|
|
- return true;
|
|
+ params->args[i] = add_implicit_conversion(ctx, params->instrs, params->args[i], type, loc);
|
|
}
|
|
|
|
static struct hlsl_type *elementwise_intrinsic_get_common_type(struct hlsl_ctx *ctx,
|
|
@@ -3200,7 +3143,8 @@ static bool elementwise_intrinsic_convert_args(struct hlsl_ctx *ctx,
|
|
if (!(common_type = elementwise_intrinsic_get_common_type(ctx, params, loc)))
|
|
return false;
|
|
|
|
- return convert_args(ctx, params, common_type, loc);
|
|
+ convert_args(ctx, params, common_type, loc);
|
|
+ return true;
|
|
}
|
|
|
|
static bool elementwise_intrinsic_float_convert_args(struct hlsl_ctx *ctx,
|
|
@@ -3213,7 +3157,8 @@ static bool elementwise_intrinsic_float_convert_args(struct hlsl_ctx *ctx,
|
|
if (hlsl_type_is_integer(type))
|
|
type = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_FLOAT, type->e.numeric.dimx, type->e.numeric.dimy);
|
|
|
|
- return convert_args(ctx, params, type, loc);
|
|
+ convert_args(ctx, params, type, loc);
|
|
+ return true;
|
|
}
|
|
|
|
static bool elementwise_intrinsic_uint_convert_args(struct hlsl_ctx *ctx,
|
|
@@ -3226,7 +3171,8 @@ static bool elementwise_intrinsic_uint_convert_args(struct hlsl_ctx *ctx,
|
|
|
|
type = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_UINT, type->e.numeric.dimx, type->e.numeric.dimy);
|
|
|
|
- return convert_args(ctx, params, type, loc);
|
|
+ convert_args(ctx, params, type, loc);
|
|
+ return true;
|
|
}
|
|
|
|
static bool intrinsic_abs(struct hlsl_ctx *ctx,
|
|
@@ -3263,8 +3209,7 @@ static bool write_acos_or_asin(struct hlsl_ctx *ctx,
|
|
|
|
const char *fn_name = asin_mode ? fn_name_asin : fn_name_acos;
|
|
|
|
- if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc)))
|
|
- return false;
|
|
+ arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
|
|
type = arg->data_type;
|
|
|
|
if (!(body = hlsl_sprintf_alloc(ctx, template,
|
|
@@ -3318,9 +3263,7 @@ static bool intrinsic_all(struct hlsl_ctx *ctx,
|
|
struct hlsl_type *bool_type;
|
|
|
|
bool_type = convert_numeric_type(ctx, arg->data_type, HLSL_TYPE_BOOL);
|
|
- if (!(cast = add_cast(ctx, params->instrs, arg, bool_type, loc)))
|
|
- return false;
|
|
-
|
|
+ cast = add_cast(ctx, params->instrs, arg, bool_type, loc);
|
|
add_combine_components(ctx, params, cast, HLSL_OP2_LOGIC_AND, loc);
|
|
return true;
|
|
}
|
|
@@ -3332,9 +3275,7 @@ static bool intrinsic_any(struct hlsl_ctx *ctx, const struct parse_initializer *
|
|
struct hlsl_type *bool_type;
|
|
|
|
bool_type = convert_numeric_type(ctx, arg->data_type, HLSL_TYPE_BOOL);
|
|
- if (!(cast = add_cast(ctx, params->instrs, arg, bool_type, loc)))
|
|
- return false;
|
|
-
|
|
+ cast = add_cast(ctx, params->instrs, arg, bool_type, loc);
|
|
add_combine_components(ctx, params, cast, HLSL_OP2_LOGIC_OR, loc);
|
|
return true;
|
|
}
|
|
@@ -3522,10 +3463,7 @@ static bool intrinsic_asuint(struct hlsl_ctx *ctx,
|
|
static bool intrinsic_ceil(struct hlsl_ctx *ctx,
|
|
const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
|
|
{
|
|
- struct hlsl_ir_node *arg;
|
|
-
|
|
- if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc)))
|
|
- return false;
|
|
+ struct hlsl_ir_node *arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
|
|
|
|
return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_CEIL, arg, loc);
|
|
}
|
|
@@ -3572,10 +3510,7 @@ static bool intrinsic_clip(struct hlsl_ctx *ctx,
|
|
static bool intrinsic_cos(struct hlsl_ctx *ctx,
|
|
const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
|
|
{
|
|
- struct hlsl_ir_node *arg;
|
|
-
|
|
- if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc)))
|
|
- return false;
|
|
+ struct hlsl_ir_node *arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
|
|
|
|
return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_COS, arg, loc);
|
|
}
|
|
@@ -3596,8 +3531,7 @@ static bool write_cosh_or_sinh(struct hlsl_ctx *ctx,
|
|
static const char fn_name_sinh[] = "sinh";
|
|
static const char fn_name_cosh[] = "cosh";
|
|
|
|
- if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc)))
|
|
- return false;
|
|
+ arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
|
|
|
|
type_name = arg->data_type->name;
|
|
fn_name = sinh_mode ? fn_name_sinh : fn_name_cosh;
|
|
@@ -3635,32 +3569,18 @@ static bool intrinsic_cross(struct hlsl_ctx *ctx,
|
|
|
|
cast_type = hlsl_get_vector_type(ctx, base, 3);
|
|
|
|
- if (!(arg1_cast = add_implicit_conversion(ctx, params->instrs, arg1, cast_type, loc)))
|
|
- return false;
|
|
-
|
|
- if (!(arg2_cast = add_implicit_conversion(ctx, params->instrs, arg2, cast_type, loc)))
|
|
- return false;
|
|
-
|
|
- if (!(arg1_swzl1 = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(Z, X, Y, Z), 3, arg1_cast, loc)))
|
|
- return false;
|
|
- hlsl_block_add_instr(params->instrs, arg1_swzl1);
|
|
-
|
|
- if (!(arg2_swzl1 = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(Y, Z, X, Y), 3, arg2_cast, loc)))
|
|
- return false;
|
|
- hlsl_block_add_instr(params->instrs, arg2_swzl1);
|
|
+ arg1_cast = add_implicit_conversion(ctx, params->instrs, arg1, cast_type, loc);
|
|
+ arg2_cast = add_implicit_conversion(ctx, params->instrs, arg2, cast_type, loc);
|
|
+ arg1_swzl1 = hlsl_block_add_swizzle(ctx, params->instrs, HLSL_SWIZZLE(Z, X, Y, Z), 3, arg1_cast, loc);
|
|
+ arg2_swzl1 = hlsl_block_add_swizzle(ctx, params->instrs, HLSL_SWIZZLE(Y, Z, X, Y), 3, arg2_cast, loc);
|
|
|
|
if (!(mul1 = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, arg1_swzl1, arg2_swzl1, loc)))
|
|
return false;
|
|
|
|
mul1_neg = hlsl_block_add_unary_expr(ctx, params->instrs, HLSL_OP1_NEG, mul1, loc);
|
|
|
|
- if (!(arg1_swzl2 = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(Y, Z, X, Y), 3, arg1_cast, loc)))
|
|
- return false;
|
|
- hlsl_block_add_instr(params->instrs, arg1_swzl2);
|
|
-
|
|
- if (!(arg2_swzl2 = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(Z, X, Y, Z), 3, arg2_cast, loc)))
|
|
- return false;
|
|
- hlsl_block_add_instr(params->instrs, arg2_swzl2);
|
|
+ arg1_swzl2 = hlsl_block_add_swizzle(ctx, params->instrs, HLSL_SWIZZLE(Y, Z, X, Y), 3, arg1_cast, loc);
|
|
+ arg2_swzl2 = hlsl_block_add_swizzle(ctx, params->instrs, HLSL_SWIZZLE(Z, X, Y, Z), 3, arg2_cast, loc);
|
|
|
|
if (!(mul2 = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, arg1_swzl2, arg2_swzl2, loc)))
|
|
return false;
|
|
@@ -3673,8 +3593,7 @@ static bool intrinsic_ddx(struct hlsl_ctx *ctx,
|
|
{
|
|
struct hlsl_ir_node *arg;
|
|
|
|
- if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc)))
|
|
- return false;
|
|
+ arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
|
|
|
|
return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_DSX, arg, loc);
|
|
}
|
|
@@ -3684,8 +3603,7 @@ static bool intrinsic_ddx_coarse(struct hlsl_ctx *ctx,
|
|
{
|
|
struct hlsl_ir_node *arg;
|
|
|
|
- if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc)))
|
|
- return false;
|
|
+ arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
|
|
|
|
return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_DSX_COARSE, arg, loc);
|
|
}
|
|
@@ -3695,8 +3613,7 @@ static bool intrinsic_ddx_fine(struct hlsl_ctx *ctx,
|
|
{
|
|
struct hlsl_ir_node *arg;
|
|
|
|
- if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc)))
|
|
- return false;
|
|
+ arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
|
|
|
|
return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_DSX_FINE, arg, loc);
|
|
}
|
|
@@ -3706,8 +3623,7 @@ static bool intrinsic_ddy(struct hlsl_ctx *ctx,
|
|
{
|
|
struct hlsl_ir_node *arg;
|
|
|
|
- if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc)))
|
|
- return false;
|
|
+ arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
|
|
|
|
return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_DSY, arg, loc);
|
|
}
|
|
@@ -3717,8 +3633,7 @@ static bool intrinsic_ddy_coarse(struct hlsl_ctx *ctx,
|
|
{
|
|
struct hlsl_ir_node *arg;
|
|
|
|
- if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc)))
|
|
- return false;
|
|
+ arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
|
|
|
|
return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_DSY_COARSE, arg, loc);
|
|
}
|
|
@@ -3728,8 +3643,7 @@ static bool intrinsic_degrees(struct hlsl_ctx *ctx,
|
|
{
|
|
struct hlsl_ir_node *arg, *deg;
|
|
|
|
- if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc)))
|
|
- return false;
|
|
+ arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
|
|
|
|
/* 1 rad = 180/pi degree = 57.2957795 degree */
|
|
deg = hlsl_block_add_float_constant(ctx, params->instrs, 57.2957795f, loc);
|
|
@@ -3741,8 +3655,7 @@ static bool intrinsic_ddy_fine(struct hlsl_ctx *ctx,
|
|
{
|
|
struct hlsl_ir_node *arg;
|
|
|
|
- if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc)))
|
|
- return false;
|
|
+ arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
|
|
|
|
return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_DSY_FINE, arg, loc);
|
|
}
|
|
@@ -3796,8 +3709,7 @@ static bool intrinsic_determinant(struct hlsl_ctx *ctx,
|
|
return false;
|
|
}
|
|
|
|
- if (!(arg = intrinsic_float_convert_arg(ctx, params, arg, loc)))
|
|
- return false;
|
|
+ arg = intrinsic_float_convert_arg(ctx, params, arg, loc);
|
|
|
|
dim = min(type->e.numeric.dimx, type->e.numeric.dimy);
|
|
if (dim == 1)
|
|
@@ -3839,11 +3751,8 @@ static bool intrinsic_distance(struct hlsl_ctx *ctx,
|
|
{
|
|
struct hlsl_ir_node *arg1, *arg2, *neg, *add, *dot;
|
|
|
|
- if (!(arg1 = intrinsic_float_convert_arg(ctx, params, params->args[0], loc)))
|
|
- return false;
|
|
-
|
|
- if (!(arg2 = intrinsic_float_convert_arg(ctx, params, params->args[1], loc)))
|
|
- return false;
|
|
+ arg1 = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
|
|
+ arg2 = intrinsic_float_convert_arg(ctx, params, params->args[1], loc);
|
|
|
|
if (!(neg = add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_NEG, arg2, loc)))
|
|
return false;
|
|
@@ -3912,8 +3821,7 @@ static bool intrinsic_exp(struct hlsl_ctx *ctx,
|
|
{
|
|
struct hlsl_ir_node *arg, *mul, *coeff;
|
|
|
|
- if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc)))
|
|
- return false;
|
|
+ arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
|
|
|
|
/* 1/ln(2) */
|
|
coeff = hlsl_block_add_float_constant(ctx, params->instrs, 1.442695f, loc);
|
|
@@ -3929,8 +3837,7 @@ static bool intrinsic_exp2(struct hlsl_ctx *ctx,
|
|
{
|
|
struct hlsl_ir_node *arg;
|
|
|
|
- if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc)))
|
|
- return false;
|
|
+ arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
|
|
|
|
return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_EXP2, arg, loc);
|
|
}
|
|
@@ -3998,8 +3905,7 @@ static bool intrinsic_floor(struct hlsl_ctx *ctx,
|
|
{
|
|
struct hlsl_ir_node *arg;
|
|
|
|
- if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc)))
|
|
- return false;
|
|
+ arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
|
|
|
|
return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_FLOOR, arg, loc);
|
|
}
|
|
@@ -4011,11 +3917,8 @@ static bool intrinsic_fmod(struct hlsl_ctx *ctx, const struct parse_initializer
|
|
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)))
|
|
- return false;
|
|
-
|
|
- if (!(y = intrinsic_float_convert_arg(ctx, params, params->args[1], loc)))
|
|
- return false;
|
|
+ x = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
|
|
+ y = intrinsic_float_convert_arg(ctx, params, params->args[1], loc);
|
|
|
|
if (!(div = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_DIV, x, y, loc)))
|
|
return false;
|
|
@@ -4050,8 +3953,7 @@ static bool intrinsic_frac(struct hlsl_ctx *ctx,
|
|
{
|
|
struct hlsl_ir_node *arg;
|
|
|
|
- if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc)))
|
|
- return false;
|
|
+ arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
|
|
|
|
return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_FRACT, arg, loc);
|
|
}
|
|
@@ -4126,8 +4028,7 @@ static bool intrinsic_length(struct hlsl_ctx *ctx,
|
|
hlsl_release_string_buffer(ctx, string);
|
|
}
|
|
|
|
- if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc)))
|
|
- return false;
|
|
+ arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
|
|
|
|
if (!(dot = add_binary_dot_expr(ctx, params->instrs, arg, arg, loc)))
|
|
return false;
|
|
@@ -4189,8 +4090,7 @@ static bool intrinsic_log(struct hlsl_ctx *ctx,
|
|
{
|
|
struct hlsl_ir_node *log, *arg, *coeff;
|
|
|
|
- if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc)))
|
|
- return false;
|
|
+ arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
|
|
|
|
if (!(log = add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_LOG2, arg, loc)))
|
|
return false;
|
|
@@ -4205,8 +4105,7 @@ static bool intrinsic_log10(struct hlsl_ctx *ctx,
|
|
{
|
|
struct hlsl_ir_node *log, *arg, *coeff;
|
|
|
|
- if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc)))
|
|
- return false;
|
|
+ arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
|
|
|
|
if (!(log = add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_LOG2, arg, loc)))
|
|
return false;
|
|
@@ -4221,8 +4120,7 @@ static bool intrinsic_log2(struct hlsl_ctx *ctx,
|
|
{
|
|
struct hlsl_ir_node *arg;
|
|
|
|
- if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc)))
|
|
- return false;
|
|
+ arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
|
|
|
|
return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_LOG2, arg, loc);
|
|
}
|
|
@@ -4330,11 +4228,8 @@ static bool intrinsic_mul(struct hlsl_ctx *ctx,
|
|
ret_type = hlsl_get_scalar_type(ctx, base);
|
|
}
|
|
|
|
- if (!(cast1 = add_implicit_conversion(ctx, params->instrs, arg1, cast_type1, loc)))
|
|
- return false;
|
|
-
|
|
- if (!(cast2 = add_implicit_conversion(ctx, params->instrs, arg2, cast_type2, loc)))
|
|
- return false;
|
|
+ cast1 = add_implicit_conversion(ctx, params->instrs, arg1, cast_type1, loc);
|
|
+ cast2 = add_implicit_conversion(ctx, params->instrs, arg2, cast_type2, loc);
|
|
|
|
if (!(var = hlsl_new_synthetic_var(ctx, "mul", matrix_type, loc)))
|
|
return false;
|
|
@@ -4375,7 +4270,8 @@ static bool intrinsic_mul(struct hlsl_ctx *ctx,
|
|
}
|
|
|
|
load = hlsl_block_add_simple_load(ctx, params->instrs, var, loc);
|
|
- return !!add_implicit_conversion(ctx, params->instrs, load, ret_type, loc);
|
|
+ add_implicit_conversion(ctx, params->instrs, load, ret_type, loc);
|
|
+ return true;
|
|
}
|
|
|
|
static bool intrinsic_normalize(struct hlsl_ctx *ctx,
|
|
@@ -4394,8 +4290,7 @@ static bool intrinsic_normalize(struct hlsl_ctx *ctx,
|
|
hlsl_release_string_buffer(ctx, string);
|
|
}
|
|
|
|
- if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc)))
|
|
- return false;
|
|
+ arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
|
|
|
|
if (!(dot = add_binary_dot_expr(ctx, params->instrs, arg, arg, loc)))
|
|
return false;
|
|
@@ -4428,8 +4323,7 @@ static bool intrinsic_radians(struct hlsl_ctx *ctx,
|
|
{
|
|
struct hlsl_ir_node *arg, *rad;
|
|
|
|
- if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc)))
|
|
- return false;
|
|
+ arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
|
|
|
|
/* 1 degree = pi/180 rad = 0.0174532925f rad */
|
|
rad = hlsl_block_add_float_constant(ctx, params->instrs, 0.0174532925f, loc);
|
|
@@ -4441,8 +4335,7 @@ static bool intrinsic_rcp(struct hlsl_ctx *ctx,
|
|
{
|
|
struct hlsl_ir_node *arg;
|
|
|
|
- if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc)))
|
|
- return false;
|
|
+ arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
|
|
|
|
return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_RCP, arg, loc);
|
|
}
|
|
@@ -4473,7 +4366,6 @@ static bool intrinsic_refract(struct hlsl_ctx *ctx,
|
|
{
|
|
struct hlsl_type *type, *scalar_type;
|
|
struct hlsl_ir_function_decl *func;
|
|
- struct hlsl_ir_node *index;
|
|
char *body;
|
|
|
|
static const char template[] =
|
|
@@ -4503,9 +4395,7 @@ static bool intrinsic_refract(struct hlsl_ctx *ctx,
|
|
* which we will only use the first component of. */
|
|
|
|
scalar_type = hlsl_get_scalar_type(ctx, params->args[2]->data_type->e.numeric.type);
|
|
- if (!(index = add_implicit_conversion(ctx, params->instrs, params->args[2], scalar_type, loc)))
|
|
- return false;
|
|
- params->args[2] = index;
|
|
+ params->args[2] = add_implicit_conversion(ctx, params->instrs, params->args[2], scalar_type, loc);
|
|
|
|
if (!elementwise_intrinsic_float_convert_args(ctx, params, loc))
|
|
return false;
|
|
@@ -4528,8 +4418,7 @@ static bool intrinsic_round(struct hlsl_ctx *ctx,
|
|
{
|
|
struct hlsl_ir_node *arg;
|
|
|
|
- if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc)))
|
|
- return false;
|
|
+ arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
|
|
|
|
return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_ROUND, arg, loc);
|
|
}
|
|
@@ -4539,8 +4428,7 @@ static bool intrinsic_rsqrt(struct hlsl_ctx *ctx,
|
|
{
|
|
struct hlsl_ir_node *arg;
|
|
|
|
- if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc)))
|
|
- return false;
|
|
+ arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
|
|
|
|
return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_RSQ, arg, loc);
|
|
}
|
|
@@ -4550,8 +4438,7 @@ static bool intrinsic_saturate(struct hlsl_ctx *ctx,
|
|
{
|
|
struct hlsl_ir_node *arg;
|
|
|
|
- if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc)))
|
|
- return false;
|
|
+ arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
|
|
|
|
return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_SAT, arg, loc);
|
|
}
|
|
@@ -4574,16 +4461,14 @@ static bool intrinsic_sign(struct hlsl_ctx *ctx,
|
|
if (!(lt = add_binary_comparison_expr(ctx, params->instrs, HLSL_OP2_LESS, zero, arg, loc)))
|
|
return false;
|
|
|
|
- if (!(op1 = add_implicit_conversion(ctx, params->instrs, lt, int_type, loc)))
|
|
- return false;
|
|
+ op1 = add_implicit_conversion(ctx, params->instrs, lt, int_type, loc);
|
|
|
|
/* Check if arg < 0, cast bool to int and invert (meaning true is -1) */
|
|
|
|
if (!(lt = add_binary_comparison_expr(ctx, params->instrs, HLSL_OP2_LESS, arg, zero, loc)))
|
|
return false;
|
|
|
|
- if (!(op2 = add_implicit_conversion(ctx, params->instrs, lt, int_type, loc)))
|
|
- return false;
|
|
+ op2 = add_implicit_conversion(ctx, params->instrs, lt, int_type, loc);
|
|
|
|
if (!(neg = add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_NEG, op2, loc)))
|
|
return false;
|
|
@@ -4597,8 +4482,7 @@ static bool intrinsic_sin(struct hlsl_ctx *ctx,
|
|
{
|
|
struct hlsl_ir_node *arg;
|
|
|
|
- if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc)))
|
|
- return false;
|
|
+ arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
|
|
|
|
return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_SIN, arg, loc);
|
|
}
|
|
@@ -4672,8 +4556,7 @@ static bool intrinsic_sqrt(struct hlsl_ctx *ctx,
|
|
{
|
|
struct hlsl_ir_node *arg;
|
|
|
|
- if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc)))
|
|
- return false;
|
|
+ arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
|
|
|
|
return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_SQRT, arg, loc);
|
|
}
|
|
@@ -4692,7 +4575,8 @@ static bool intrinsic_step(struct hlsl_ctx *ctx,
|
|
params->args[1], params->args[0], loc)))
|
|
return false;
|
|
|
|
- return !!add_implicit_conversion(ctx, params->instrs, ge, type, loc);
|
|
+ add_implicit_conversion(ctx, params->instrs, ge, type, loc);
|
|
+ return true;
|
|
}
|
|
|
|
static bool intrinsic_tan(struct hlsl_ctx *ctx,
|
|
@@ -4726,8 +4610,7 @@ static bool intrinsic_tanh(struct hlsl_ctx *ctx,
|
|
" return (exp_pos - exp_neg) / (exp_pos + exp_neg);\n"
|
|
"}\n";
|
|
|
|
- if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc)))
|
|
- return false;
|
|
+ arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
|
|
type = arg->data_type;
|
|
|
|
if (!(body = hlsl_sprintf_alloc(ctx, template,
|
|
@@ -4748,7 +4631,7 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer *
|
|
unsigned int sampler_dim = hlsl_sampler_dim_count(dim);
|
|
struct hlsl_resource_load_params load_params = { 0 };
|
|
const struct hlsl_type *sampler_type;
|
|
- struct hlsl_ir_node *coords, *sample;
|
|
+ struct hlsl_ir_node *coords;
|
|
|
|
if (params->args_count != 2 && params->args_count != 4)
|
|
{
|
|
@@ -4780,47 +4663,27 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer *
|
|
else
|
|
load_params.type = HLSL_RESOURCE_SAMPLE_LOD_BIAS;
|
|
|
|
- if (!(c = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(X, Y, Z, W), sampler_dim, params->args[1], loc)))
|
|
- return false;
|
|
- hlsl_block_add_instr(params->instrs, c);
|
|
-
|
|
- if (!(coords = add_implicit_conversion(ctx, params->instrs, c,
|
|
- hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc)))
|
|
- {
|
|
- return false;
|
|
- }
|
|
-
|
|
- if (!(lod = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(W, W, W, W), 1, params->args[1], loc)))
|
|
- return false;
|
|
- hlsl_block_add_instr(params->instrs, lod);
|
|
+ c = hlsl_block_add_swizzle(ctx, params->instrs, HLSL_SWIZZLE(X, Y, Z, W), sampler_dim, params->args[1], loc);
|
|
+ coords = add_implicit_conversion(ctx, params->instrs, c,
|
|
+ hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc);
|
|
|
|
- if (!(load_params.lod = add_implicit_conversion(ctx, params->instrs, lod,
|
|
- hlsl_get_scalar_type(ctx, HLSL_TYPE_FLOAT), loc)))
|
|
- {
|
|
- return false;
|
|
- }
|
|
+ lod = hlsl_block_add_swizzle(ctx, params->instrs, HLSL_SWIZZLE(W, W, W, W), 1, params->args[1], loc);
|
|
+ load_params.lod = add_implicit_conversion(ctx, params->instrs, lod,
|
|
+ hlsl_get_scalar_type(ctx, HLSL_TYPE_FLOAT), loc);
|
|
}
|
|
else if (!strcmp(name, "tex2Dproj")
|
|
|| !strcmp(name, "tex3Dproj")
|
|
|| !strcmp(name, "texCUBEproj"))
|
|
{
|
|
- if (!(coords = add_implicit_conversion(ctx, params->instrs, params->args[1],
|
|
- hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, 4), loc)))
|
|
- {
|
|
- return false;
|
|
- }
|
|
+ coords = add_implicit_conversion(ctx, params->instrs, params->args[1],
|
|
+ hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, 4), loc);
|
|
|
|
if (hlsl_version_ge(ctx, 4, 0))
|
|
{
|
|
struct hlsl_ir_node *divisor;
|
|
|
|
- if (!(divisor = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(W, W, W, W), sampler_dim, coords, loc)))
|
|
- return false;
|
|
- hlsl_block_add_instr(params->instrs, divisor);
|
|
-
|
|
- if (!(coords = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(X, Y, Z, W), sampler_dim, coords, loc)))
|
|
- return false;
|
|
- hlsl_block_add_instr(params->instrs, coords);
|
|
+ divisor = hlsl_block_add_swizzle(ctx, params->instrs, HLSL_SWIZZLE(W, W, W, W), sampler_dim, coords, loc);
|
|
+ coords = hlsl_block_add_swizzle(ctx, params->instrs, HLSL_SWIZZLE(X, Y, Z, W), sampler_dim, coords, loc);
|
|
|
|
if (!(coords = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_DIV, coords, divisor, loc)))
|
|
return false;
|
|
@@ -4834,35 +4697,19 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer *
|
|
}
|
|
else if (params->args_count == 4) /* Gradient sampling. */
|
|
{
|
|
- if (!(coords = add_implicit_conversion(ctx, params->instrs, params->args[1],
|
|
- hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc)))
|
|
- {
|
|
- return false;
|
|
- }
|
|
-
|
|
- if (!(load_params.ddx = add_implicit_conversion(ctx, params->instrs, params->args[2],
|
|
- hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc)))
|
|
- {
|
|
- return false;
|
|
- }
|
|
-
|
|
- if (!(load_params.ddy = add_implicit_conversion(ctx, params->instrs, params->args[3],
|
|
- hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc)))
|
|
- {
|
|
- return false;
|
|
- }
|
|
-
|
|
+ coords = add_implicit_conversion(ctx, params->instrs, params->args[1],
|
|
+ hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc);
|
|
+ load_params.ddx = add_implicit_conversion(ctx, params->instrs, params->args[2],
|
|
+ hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc);
|
|
+ load_params.ddy = add_implicit_conversion(ctx, params->instrs, params->args[3],
|
|
+ hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc);
|
|
load_params.type = HLSL_RESOURCE_SAMPLE_GRAD;
|
|
}
|
|
else
|
|
{
|
|
load_params.type = HLSL_RESOURCE_SAMPLE;
|
|
-
|
|
- if (!(coords = add_implicit_conversion(ctx, params->instrs, params->args[1],
|
|
- hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc)))
|
|
- {
|
|
- return false;
|
|
- }
|
|
+ coords = add_implicit_conversion(ctx, params->instrs, params->args[1],
|
|
+ hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc);
|
|
}
|
|
|
|
/* tex1D() functions never produce 1D resource declarations. For newer profiles half offset
|
|
@@ -4889,9 +4736,7 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer *
|
|
load_params.format = hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, 4);
|
|
load_params.sampling_dim = dim;
|
|
|
|
- if (!(sample = hlsl_new_resource_load(ctx, &load_params, loc)))
|
|
- return false;
|
|
- hlsl_block_add_instr(params->instrs, sample);
|
|
+ hlsl_block_add_resource_load(ctx, params->instrs, &load_params, loc);
|
|
return true;
|
|
}
|
|
|
|
@@ -5026,10 +4871,7 @@ static bool intrinsic_transpose(struct hlsl_ctx *ctx,
|
|
static bool intrinsic_trunc(struct hlsl_ctx *ctx,
|
|
const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
|
|
{
|
|
- struct hlsl_ir_node *arg;
|
|
-
|
|
- if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc)))
|
|
- return false;
|
|
+ struct hlsl_ir_node *arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
|
|
|
|
return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_TRUNC, arg, loc);
|
|
}
|
|
@@ -5037,7 +4879,7 @@ static bool intrinsic_trunc(struct hlsl_ctx *ctx,
|
|
static bool intrinsic_d3dcolor_to_ubyte4(struct hlsl_ctx *ctx,
|
|
const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
|
|
{
|
|
- struct hlsl_ir_node *arg = params->args[0], *ret, *c, *swizzle;
|
|
+ struct hlsl_ir_node *arg = params->args[0], *ret, *c;
|
|
struct hlsl_type *arg_type = arg->data_type;
|
|
|
|
if (arg_type->class != HLSL_CLASS_SCALAR && !(arg_type->class == HLSL_CLASS_VECTOR
|
|
@@ -5054,19 +4896,11 @@ static bool intrinsic_d3dcolor_to_ubyte4(struct hlsl_ctx *ctx,
|
|
return false;
|
|
}
|
|
|
|
- if (!(arg = intrinsic_float_convert_arg(ctx, params, arg, loc)))
|
|
- return false;
|
|
-
|
|
+ arg = intrinsic_float_convert_arg(ctx, params, arg, loc);
|
|
c = hlsl_block_add_float_constant(ctx, params->instrs, 255.0f + (0.5f / 256.0f), loc);
|
|
|
|
if (arg_type->class == HLSL_CLASS_VECTOR)
|
|
- {
|
|
- if (!(swizzle = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(Z, Y, X, W), 4, arg, loc)))
|
|
- return false;
|
|
- hlsl_block_add_instr(params->instrs, swizzle);
|
|
-
|
|
- arg = swizzle;
|
|
- }
|
|
+ arg = hlsl_block_add_swizzle(ctx, params->instrs, HLSL_SWIZZLE(Z, Y, X, W), 4, arg, loc);
|
|
|
|
if (!(ret = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, arg, c, loc)))
|
|
return false;
|
|
@@ -5603,8 +5437,7 @@ static bool add_ternary(struct hlsl_ctx *ctx, struct hlsl_block *block,
|
|
{
|
|
cond_type = hlsl_get_numeric_type(ctx, common_type->class,
|
|
HLSL_TYPE_BOOL, common_type->e.numeric.dimx, common_type->e.numeric.dimy);
|
|
- if (!(cond = add_implicit_conversion(ctx, block, cond, cond_type, &cond->loc)))
|
|
- return false;
|
|
+ cond = add_implicit_conversion(ctx, block, cond, cond_type, &cond->loc);
|
|
}
|
|
else
|
|
{
|
|
@@ -5633,15 +5466,11 @@ static bool add_ternary(struct hlsl_ctx *ctx, struct hlsl_block *block,
|
|
|
|
cond_type = hlsl_get_numeric_type(ctx, common_type->class, HLSL_TYPE_BOOL,
|
|
common_type->e.numeric.dimx, common_type->e.numeric.dimy);
|
|
- if (!(cond = add_implicit_conversion(ctx, block, cond, cond_type, &cond->loc)))
|
|
- return false;
|
|
+ cond = add_implicit_conversion(ctx, block, cond, cond_type, &cond->loc);
|
|
}
|
|
|
|
- if (!(first = add_implicit_conversion(ctx, block, first, common_type, &first->loc)))
|
|
- return false;
|
|
-
|
|
- if (!(second = add_implicit_conversion(ctx, block, second, common_type, &second->loc)))
|
|
- return false;
|
|
+ first = add_implicit_conversion(ctx, block, first, common_type, &first->loc);
|
|
+ second = add_implicit_conversion(ctx, block, second, common_type, &second->loc);
|
|
}
|
|
else
|
|
{
|
|
@@ -5661,9 +5490,7 @@ static bool add_ternary(struct hlsl_ctx *ctx, struct hlsl_block *block,
|
|
|
|
cond_type = hlsl_get_numeric_type(ctx, cond_type->class, HLSL_TYPE_BOOL,
|
|
cond_type->e.numeric.dimx, cond_type->e.numeric.dimy);
|
|
- if (!(cond = add_implicit_conversion(ctx, block, cond, cond_type, &cond->loc)))
|
|
- return false;
|
|
-
|
|
+ cond = add_implicit_conversion(ctx, block, cond, cond_type, &cond->loc);
|
|
common_type = first->data_type;
|
|
}
|
|
|
|
@@ -5716,7 +5543,6 @@ static bool add_raw_load_method_call(struct hlsl_ctx *ctx, struct hlsl_block *bl
|
|
const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
|
|
{
|
|
struct hlsl_resource_load_params load_params = {.type = HLSL_RESOURCE_LOAD};
|
|
- struct hlsl_ir_node *load;
|
|
unsigned int value_dim;
|
|
|
|
if (params->args_count != 1 && params->args_count != 2)
|
|
@@ -5748,16 +5574,11 @@ static bool add_raw_load_method_call(struct hlsl_ctx *ctx, struct hlsl_block *bl
|
|
else
|
|
value_dim = 4;
|
|
|
|
- if (!(load_params.coords = add_implicit_conversion(ctx, block, params->args[0],
|
|
- hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), loc)))
|
|
- return false;
|
|
-
|
|
+ load_params.coords = add_implicit_conversion(ctx, block, params->args[0],
|
|
+ hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), loc);
|
|
load_params.format = hlsl_get_vector_type(ctx, HLSL_TYPE_UINT, value_dim);
|
|
load_params.resource = object;
|
|
-
|
|
- if (!(load = hlsl_new_resource_load(ctx, &load_params, loc)))
|
|
- return false;
|
|
- hlsl_block_add_instr(block, load);
|
|
+ hlsl_block_add_resource_load(ctx, block, &load_params, loc);
|
|
return true;
|
|
}
|
|
|
|
@@ -5767,7 +5588,6 @@ static bool add_load_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block,
|
|
const struct hlsl_type *object_type = object->data_type;
|
|
struct hlsl_resource_load_params load_params = {.type = HLSL_RESOURCE_LOAD};
|
|
unsigned int sampler_dim, offset_dim;
|
|
- struct hlsl_ir_node *load;
|
|
bool multisampled;
|
|
|
|
if (object_type->sampler_dim == HLSL_SAMPLER_DIM_RAW_BUFFER)
|
|
@@ -5794,18 +5614,12 @@ static bool add_load_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block,
|
|
}
|
|
|
|
if (multisampled)
|
|
- {
|
|
- if (!(load_params.sample_index = add_implicit_conversion(ctx, block, params->args[1],
|
|
- hlsl_get_scalar_type(ctx, HLSL_TYPE_INT), loc)))
|
|
- return false;
|
|
- }
|
|
+ load_params.sample_index = add_implicit_conversion(ctx, block, params->args[1],
|
|
+ hlsl_get_scalar_type(ctx, HLSL_TYPE_INT), loc);
|
|
|
|
if (!!offset_dim && params->args_count > 1 + multisampled)
|
|
- {
|
|
- if (!(load_params.texel_offset = add_implicit_conversion(ctx, block, params->args[1 + multisampled],
|
|
- hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc)))
|
|
- return false;
|
|
- }
|
|
+ load_params.texel_offset = add_implicit_conversion(ctx, block, params->args[1 + multisampled],
|
|
+ hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc);
|
|
|
|
if (params->args_count > 1 + multisampled + !!offset_dim)
|
|
{
|
|
@@ -5813,16 +5627,11 @@ static bool add_load_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block,
|
|
}
|
|
|
|
/* +1 for the mipmap level for non-multisampled textures */
|
|
- if (!(load_params.coords = add_implicit_conversion(ctx, block, params->args[0],
|
|
- hlsl_get_vector_type(ctx, HLSL_TYPE_INT, sampler_dim + !multisampled), loc)))
|
|
- return false;
|
|
-
|
|
+ load_params.coords = add_implicit_conversion(ctx, block, params->args[0],
|
|
+ hlsl_get_vector_type(ctx, HLSL_TYPE_INT, sampler_dim + !multisampled), loc);
|
|
load_params.format = object_type->e.resource.format;
|
|
load_params.resource = object;
|
|
-
|
|
- if (!(load = hlsl_new_resource_load(ctx, &load_params, loc)))
|
|
- return false;
|
|
- hlsl_block_add_instr(block, load);
|
|
+ hlsl_block_add_resource_load(ctx, block, &load_params, loc);
|
|
return true;
|
|
}
|
|
|
|
@@ -5833,7 +5642,6 @@ static bool add_sample_method_call(struct hlsl_ctx *ctx, struct hlsl_block *bloc
|
|
struct hlsl_resource_load_params load_params = {.type = HLSL_RESOURCE_SAMPLE};
|
|
unsigned int sampler_dim, offset_dim;
|
|
const struct hlsl_type *sampler_type;
|
|
- struct hlsl_ir_node *load;
|
|
|
|
sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim);
|
|
offset_dim = hlsl_offset_dim_count(object_type->sampler_dim);
|
|
@@ -5858,16 +5666,12 @@ static bool add_sample_method_call(struct hlsl_ctx *ctx, struct hlsl_block *bloc
|
|
return false;
|
|
}
|
|
|
|
- if (!(load_params.coords = add_implicit_conversion(ctx, block, params->args[1],
|
|
- hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc)))
|
|
- return false;
|
|
+ load_params.coords = add_implicit_conversion(ctx, block, params->args[1],
|
|
+ hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc);
|
|
|
|
if (offset_dim && params->args_count > 2)
|
|
- {
|
|
- if (!(load_params.texel_offset = add_implicit_conversion(ctx, block, params->args[2],
|
|
- hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc)))
|
|
- return false;
|
|
- }
|
|
+ load_params.texel_offset = add_implicit_conversion(ctx, block, params->args[2],
|
|
+ hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc);
|
|
|
|
if (params->args_count > 2 + !!offset_dim)
|
|
hlsl_fixme(ctx, loc, "Sample() clamp parameter.");
|
|
@@ -5877,11 +5681,7 @@ static bool add_sample_method_call(struct hlsl_ctx *ctx, struct hlsl_block *bloc
|
|
load_params.format = object_type->e.resource.format;
|
|
load_params.resource = object;
|
|
load_params.sampler = params->args[0];
|
|
-
|
|
- if (!(load = hlsl_new_resource_load(ctx, &load_params, loc)))
|
|
- return false;
|
|
- hlsl_block_add_instr(block, load);
|
|
-
|
|
+ hlsl_block_add_resource_load(ctx, block, &load_params, loc);
|
|
return true;
|
|
}
|
|
|
|
@@ -5892,7 +5692,6 @@ static bool add_sample_cmp_method_call(struct hlsl_ctx *ctx, struct hlsl_block *
|
|
struct hlsl_resource_load_params load_params = { 0 };
|
|
unsigned int sampler_dim, offset_dim;
|
|
const struct hlsl_type *sampler_type;
|
|
- struct hlsl_ir_node *load;
|
|
|
|
sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim);
|
|
offset_dim = hlsl_offset_dim_count(object_type->sampler_dim);
|
|
@@ -5923,20 +5722,14 @@ static bool add_sample_cmp_method_call(struct hlsl_ctx *ctx, struct hlsl_block *
|
|
return false;
|
|
}
|
|
|
|
- if (!(load_params.coords = add_implicit_conversion(ctx, block, params->args[1],
|
|
- hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc)))
|
|
- return false;
|
|
-
|
|
- if (!(load_params.cmp = add_implicit_conversion(ctx, block, params->args[2],
|
|
- hlsl_get_scalar_type(ctx, HLSL_TYPE_FLOAT), loc)))
|
|
- load_params.cmp = params->args[2];
|
|
+ load_params.coords = add_implicit_conversion(ctx, block, params->args[1],
|
|
+ hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc);
|
|
+ load_params.cmp = add_implicit_conversion(ctx, block, params->args[2],
|
|
+ hlsl_get_scalar_type(ctx, HLSL_TYPE_FLOAT), loc);
|
|
|
|
if (offset_dim && params->args_count > 3)
|
|
- {
|
|
- if (!(load_params.texel_offset = add_implicit_conversion(ctx, block, params->args[2],
|
|
- hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc)))
|
|
- return false;
|
|
- }
|
|
+ load_params.texel_offset = add_implicit_conversion(ctx, block, params->args[2],
|
|
+ hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc);
|
|
|
|
if (params->args_count > 3 + !!offset_dim)
|
|
hlsl_fixme(ctx, loc, "%s() clamp parameter.", name);
|
|
@@ -5946,11 +5739,7 @@ static bool add_sample_cmp_method_call(struct hlsl_ctx *ctx, struct hlsl_block *
|
|
load_params.format = object_type->e.resource.format;
|
|
load_params.resource = object;
|
|
load_params.sampler = params->args[0];
|
|
-
|
|
- if (!(load = hlsl_new_resource_load(ctx, &load_params, loc)))
|
|
- return false;
|
|
- hlsl_block_add_instr(block, load);
|
|
-
|
|
+ hlsl_block_add_resource_load(ctx, block, &load_params, loc);
|
|
return true;
|
|
}
|
|
|
|
@@ -5961,7 +5750,6 @@ static bool add_gather_method_call(struct hlsl_ctx *ctx, struct hlsl_block *bloc
|
|
struct hlsl_resource_load_params load_params = {0};
|
|
unsigned int sampler_dim, offset_dim;
|
|
const struct hlsl_type *sampler_type;
|
|
- struct hlsl_ir_node *load;
|
|
unsigned int read_channel;
|
|
|
|
sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim);
|
|
@@ -6015,9 +5803,8 @@ static bool add_gather_method_call(struct hlsl_ctx *ctx, struct hlsl_block *bloc
|
|
}
|
|
else if (offset_dim && params->args_count > 2)
|
|
{
|
|
- if (!(load_params.texel_offset = add_implicit_conversion(ctx, block, params->args[2],
|
|
- hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc)))
|
|
- return false;
|
|
+ load_params.texel_offset = add_implicit_conversion(ctx, block, params->args[2],
|
|
+ hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc);
|
|
}
|
|
|
|
sampler_type = params->args[0]->data_type;
|
|
@@ -6039,17 +5826,12 @@ static bool add_gather_method_call(struct hlsl_ctx *ctx, struct hlsl_block *bloc
|
|
return false;
|
|
}
|
|
|
|
- if (!(load_params.coords = add_implicit_conversion(ctx, block, params->args[1],
|
|
- hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc)))
|
|
- return false;
|
|
-
|
|
+ load_params.coords = add_implicit_conversion(ctx, block, params->args[1],
|
|
+ hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc);
|
|
load_params.format = hlsl_get_vector_type(ctx, object_type->e.resource.format->e.numeric.type, 4);
|
|
load_params.resource = object;
|
|
load_params.sampler = params->args[0];
|
|
-
|
|
- if (!(load = hlsl_new_resource_load(ctx, &load_params, loc)))
|
|
- return false;
|
|
- hlsl_block_add_instr(block, load);
|
|
+ hlsl_block_add_resource_load(ctx, block, &load_params, loc);
|
|
return true;
|
|
}
|
|
|
|
@@ -6060,7 +5842,6 @@ static bool add_gather_cmp_method_call(struct hlsl_ctx *ctx, struct hlsl_block *
|
|
struct hlsl_resource_load_params load_params = {0};
|
|
unsigned int sampler_dim, offset_dim;
|
|
const struct hlsl_type *sampler_type;
|
|
- struct hlsl_ir_node *load;
|
|
|
|
sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim);
|
|
offset_dim = hlsl_offset_dim_count(object_type->sampler_dim);
|
|
@@ -6127,10 +5908,7 @@ static bool add_gather_cmp_method_call(struct hlsl_ctx *ctx, struct hlsl_block *
|
|
load_params.format = hlsl_get_vector_type(ctx, object_type->e.resource.format->e.numeric.type, 4);
|
|
load_params.resource = object;
|
|
load_params.sampler = params->args[0];
|
|
-
|
|
- if (!(load = hlsl_new_resource_load(ctx, &load_params, loc)))
|
|
- return false;
|
|
- hlsl_block_add_instr(block, load);
|
|
+ hlsl_block_add_resource_load(ctx, block, &load_params, loc);
|
|
return true;
|
|
}
|
|
|
|
@@ -6219,12 +5997,8 @@ static bool add_getdimensions_method_call(struct hlsl_ctx *ctx, struct hlsl_bloc
|
|
/* Input parameter. */
|
|
if (iter->args[j] == ARG_MIP_LEVEL)
|
|
{
|
|
- if (!(args[ARG_MIP_LEVEL] = add_implicit_conversion(ctx, block, args[ARG_MIP_LEVEL],
|
|
- hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), loc)))
|
|
- {
|
|
- return false;
|
|
- }
|
|
-
|
|
+ args[ARG_MIP_LEVEL] = add_implicit_conversion(ctx, block, args[ARG_MIP_LEVEL],
|
|
+ hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), loc);
|
|
continue;
|
|
}
|
|
|
|
@@ -6263,10 +6037,7 @@ static bool add_getdimensions_method_call(struct hlsl_ctx *ctx, struct hlsl_bloc
|
|
load_params.resource = object;
|
|
load_params.lod = args[ARG_MIP_LEVEL];
|
|
load_params.format = hlsl_get_vector_type(ctx, uint_resinfo ? HLSL_TYPE_UINT : HLSL_TYPE_FLOAT, 4);
|
|
-
|
|
- if (!(res_info = hlsl_new_resource_load(ctx, &load_params, loc)))
|
|
- return false;
|
|
- hlsl_block_add_instr(block, res_info);
|
|
+ res_info = hlsl_block_add_resource_load(ctx, block, &load_params, loc);
|
|
|
|
if (!add_assignment_from_component(ctx, block, args[ARG_WIDTH], res_info, 0, loc))
|
|
return false;
|
|
@@ -6289,9 +6060,7 @@ static bool add_getdimensions_method_call(struct hlsl_ctx *ctx, struct hlsl_bloc
|
|
load_params.type = HLSL_RESOURCE_SAMPLE_INFO;
|
|
load_params.resource = object;
|
|
load_params.format = args[ARG_SAMPLE_COUNT]->data_type;
|
|
- if (!(sample_info = hlsl_new_resource_load(ctx, &load_params, loc)))
|
|
- return false;
|
|
- hlsl_block_add_instr(block, sample_info);
|
|
+ sample_info = hlsl_block_add_resource_load(ctx, block, &load_params, loc);
|
|
|
|
if (!add_assignment(ctx, block, args[ARG_SAMPLE_COUNT], ASSIGN_OP_ASSIGN, sample_info, false))
|
|
return false;
|
|
@@ -6308,7 +6077,6 @@ static bool add_sample_lod_method_call(struct hlsl_ctx *ctx, struct hlsl_block *
|
|
struct hlsl_resource_load_params load_params = { 0 };
|
|
unsigned int sampler_dim, offset_dim;
|
|
const struct hlsl_type *sampler_type;
|
|
- struct hlsl_ir_node *load;
|
|
|
|
sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim);
|
|
offset_dim = hlsl_offset_dim_count(object_type->sampler_dim);
|
|
@@ -6338,20 +6106,14 @@ static bool add_sample_lod_method_call(struct hlsl_ctx *ctx, struct hlsl_block *
|
|
return false;
|
|
}
|
|
|
|
- if (!(load_params.coords = add_implicit_conversion(ctx, block, params->args[1],
|
|
- hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc)))
|
|
- load_params.coords = params->args[1];
|
|
-
|
|
- if (!(load_params.lod = add_implicit_conversion(ctx, block, params->args[2],
|
|
- hlsl_get_scalar_type(ctx, HLSL_TYPE_FLOAT), loc)))
|
|
- load_params.lod = params->args[2];
|
|
+ load_params.coords = add_implicit_conversion(ctx, block, params->args[1],
|
|
+ hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc);
|
|
+ load_params.lod = add_implicit_conversion(ctx, block, params->args[2],
|
|
+ hlsl_get_scalar_type(ctx, HLSL_TYPE_FLOAT), loc);
|
|
|
|
if (offset_dim && params->args_count > 3)
|
|
- {
|
|
- if (!(load_params.texel_offset = add_implicit_conversion(ctx, block, params->args[3],
|
|
- hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc)))
|
|
- return false;
|
|
- }
|
|
+ load_params.texel_offset = add_implicit_conversion(ctx, block, params->args[3],
|
|
+ hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc);
|
|
|
|
if (params->args_count > 3 + !!offset_dim)
|
|
hlsl_fixme(ctx, loc, "Tiled resource status argument.");
|
|
@@ -6359,10 +6121,7 @@ static bool add_sample_lod_method_call(struct hlsl_ctx *ctx, struct hlsl_block *
|
|
load_params.format = object_type->e.resource.format;
|
|
load_params.resource = object;
|
|
load_params.sampler = params->args[0];
|
|
-
|
|
- if (!(load = hlsl_new_resource_load(ctx, &load_params, loc)))
|
|
- return false;
|
|
- hlsl_block_add_instr(block, load);
|
|
+ hlsl_block_add_resource_load(ctx, block, &load_params, loc);
|
|
return true;
|
|
}
|
|
|
|
@@ -6373,7 +6132,6 @@ static bool add_sample_grad_method_call(struct hlsl_ctx *ctx, struct hlsl_block
|
|
struct hlsl_resource_load_params load_params = { 0 };
|
|
unsigned int sampler_dim, offset_dim;
|
|
const struct hlsl_type *sampler_type;
|
|
- struct hlsl_ir_node *load;
|
|
|
|
sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim);
|
|
offset_dim = hlsl_offset_dim_count(object_type->sampler_dim);
|
|
@@ -6400,24 +6158,16 @@ static bool add_sample_grad_method_call(struct hlsl_ctx *ctx, struct hlsl_block
|
|
return false;
|
|
}
|
|
|
|
- if (!(load_params.coords = add_implicit_conversion(ctx, block, params->args[1],
|
|
- hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc)))
|
|
- load_params.coords = params->args[1];
|
|
-
|
|
- if (!(load_params.ddx = add_implicit_conversion(ctx, block, params->args[2],
|
|
- hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc)))
|
|
- load_params.ddx = params->args[2];
|
|
-
|
|
- if (!(load_params.ddy = add_implicit_conversion(ctx, block, params->args[3],
|
|
- hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc)))
|
|
- load_params.ddy = params->args[3];
|
|
+ load_params.coords = add_implicit_conversion(ctx, block, params->args[1],
|
|
+ hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc);
|
|
+ load_params.ddx = add_implicit_conversion(ctx, block, params->args[2],
|
|
+ hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc);
|
|
+ load_params.ddy = add_implicit_conversion(ctx, block, params->args[3],
|
|
+ hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc);
|
|
|
|
if (offset_dim && params->args_count > 4)
|
|
- {
|
|
- if (!(load_params.texel_offset = add_implicit_conversion(ctx, block, params->args[4],
|
|
- hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc)))
|
|
- return false;
|
|
- }
|
|
+ load_params.texel_offset = add_implicit_conversion(ctx, block, params->args[4],
|
|
+ hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc);
|
|
|
|
if (params->args_count > 4 + !!offset_dim)
|
|
hlsl_fixme(ctx, loc, "Tiled resource status argument.");
|
|
@@ -6425,10 +6175,7 @@ static bool add_sample_grad_method_call(struct hlsl_ctx *ctx, struct hlsl_block
|
|
load_params.format = object_type->e.resource.format;
|
|
load_params.resource = object;
|
|
load_params.sampler = params->args[0];
|
|
-
|
|
- if (!(load = hlsl_new_resource_load(ctx, &load_params, loc)))
|
|
- return false;
|
|
- hlsl_block_add_instr(block, load);
|
|
+ hlsl_block_add_resource_load(ctx, block, &load_params, loc);
|
|
return true;
|
|
}
|
|
|
|
@@ -6455,13 +6202,10 @@ static bool add_store_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block
|
|
else
|
|
value_dim = 4;
|
|
|
|
- if (!(offset = add_implicit_conversion(ctx, block, params->args[0],
|
|
- hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), loc)))
|
|
- return false;
|
|
-
|
|
- if (!(rhs = add_implicit_conversion(ctx, block, params->args[1],
|
|
- hlsl_get_vector_type(ctx, HLSL_TYPE_UINT, value_dim), loc)))
|
|
- return false;
|
|
+ offset = add_implicit_conversion(ctx, block, params->args[0],
|
|
+ hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), loc);
|
|
+ rhs = add_implicit_conversion(ctx, block, params->args[1],
|
|
+ hlsl_get_vector_type(ctx, HLSL_TYPE_UINT, value_dim), loc);
|
|
|
|
if (!hlsl_init_deref_from_index_chain(ctx, &resource_deref, object))
|
|
return false;
|
|
@@ -6667,15 +6411,8 @@ static bool add_switch(struct hlsl_ctx *ctx, struct hlsl_block *block,
|
|
return true;
|
|
}
|
|
|
|
- if (!(selector = add_implicit_conversion(ctx, block, selector,
|
|
- hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), &selector->loc)))
|
|
- {
|
|
- destroy_switch_cases(cases);
|
|
- destroy_block(block);
|
|
- cleanup_parse_attribute_list(attributes);
|
|
- return false;
|
|
- }
|
|
-
|
|
+ selector = add_implicit_conversion(ctx, block, selector,
|
|
+ hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), &selector->loc);
|
|
s = hlsl_new_switch(ctx, selector, cases, loc);
|
|
|
|
destroy_switch_cases(cases);
|
|
@@ -6816,6 +6553,8 @@ static void validate_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim,
|
|
%token KW_INLINE
|
|
%token KW_INOUT
|
|
%token KW_INPUTPATCH
|
|
+%token KW_LINE
|
|
+%token KW_LINEADJ
|
|
%token KW_LINEAR
|
|
%token KW_LINESTREAM
|
|
%token KW_MATRIX
|
|
@@ -6828,6 +6567,7 @@ static void validate_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim,
|
|
%token KW_PACKOFFSET
|
|
%token KW_PASS
|
|
%token KW_PIXELSHADER
|
|
+%token KW_POINT
|
|
%token KW_POINTSTREAM
|
|
%token KW_RASTERIZERORDEREDBUFFER
|
|
%token KW_RASTERIZERORDEREDSTRUCTUREDBUFFER
|
|
@@ -6878,6 +6618,8 @@ static void validate_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim,
|
|
%token KW_TEXTURE3D
|
|
%token KW_TEXTURECUBE
|
|
%token KW_TEXTURECUBEARRAY
|
|
+%token KW_TRIANGLE
|
|
+%token KW_TRIANGLEADJ
|
|
%token KW_TRIANGLESTREAM
|
|
%token KW_TRUE
|
|
%token KW_TYPEDEF
|
|
@@ -7885,7 +7627,8 @@ parameter:
|
|
parameter_decl:
|
|
var_modifiers type_no_void any_identifier arrays colon_attributes
|
|
{
|
|
- uint32_t modifiers = $1;
|
|
+ uint32_t prim_modifiers = $1 & HLSL_PRIMITIVE_MODIFIERS_MASK;
|
|
+ uint32_t modifiers = $1 & ~HLSL_PRIMITIVE_MODIFIERS_MASK;
|
|
struct hlsl_type *type;
|
|
unsigned int i;
|
|
|
|
@@ -7910,6 +7653,22 @@ parameter_decl:
|
|
}
|
|
vkd3d_free($4.sizes);
|
|
|
|
+ if (prim_modifiers && (prim_modifiers & (prim_modifiers - 1)))
|
|
+ {
|
|
+ hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER,
|
|
+ "Primitive type modifiers are mutually exclusive.");
|
|
+ prim_modifiers = 0;
|
|
+ }
|
|
+
|
|
+ if (prim_modifiers)
|
|
+ {
|
|
+ if (type->class != HLSL_CLASS_ARRAY)
|
|
+ hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER,
|
|
+ "Primitive type modifiers can only be applied to arrays.");
|
|
+ else
|
|
+ type->modifiers |= prim_modifiers;
|
|
+ }
|
|
+
|
|
$$.type = type;
|
|
|
|
if (hlsl_version_ge(ctx, 5, 1) && type->class == HLSL_CLASS_ARRAY && hlsl_type_is_resource(type))
|
|
@@ -8629,7 +8388,7 @@ variable_def_typed:
|
|
if (!(type = apply_type_modifiers(ctx, $2, &modifiers, true, &@1)))
|
|
YYABORT;
|
|
|
|
- check_invalid_in_out_modifiers(ctx, modifiers, &@1);
|
|
+ check_invalid_non_parameter_modifiers(ctx, modifiers, &@1);
|
|
|
|
$$ = $3;
|
|
$$->basic_type = type;
|
|
@@ -8644,7 +8403,7 @@ variable_def_typed:
|
|
if (!(type = apply_type_modifiers(ctx, $2, &modifiers, true, &@1)))
|
|
YYABORT;
|
|
|
|
- check_invalid_in_out_modifiers(ctx, modifiers, &@1);
|
|
+ check_invalid_non_parameter_modifiers(ctx, modifiers, &@1);
|
|
|
|
$$ = $3;
|
|
$$->basic_type = type;
|
|
@@ -8785,6 +8544,26 @@ var_modifiers:
|
|
{
|
|
$$ = add_modifiers(ctx, $2, HLSL_MODIFIER_SNORM, &@1);
|
|
}
|
|
+ | KW_LINE var_modifiers
|
|
+ {
|
|
+ $$ = add_modifiers(ctx, $2, HLSL_PRIMITIVE_LINE, &@1);
|
|
+ }
|
|
+ | KW_LINEADJ var_modifiers
|
|
+ {
|
|
+ $$ = add_modifiers(ctx, $2, HLSL_PRIMITIVE_LINEADJ, &@1);
|
|
+ }
|
|
+ | KW_POINT var_modifiers
|
|
+ {
|
|
+ $$ = add_modifiers(ctx, $2, HLSL_PRIMITIVE_POINT, &@1);
|
|
+ }
|
|
+ | KW_TRIANGLE var_modifiers
|
|
+ {
|
|
+ $$ = add_modifiers(ctx, $2, HLSL_PRIMITIVE_TRIANGLE, &@1);
|
|
+ }
|
|
+ | KW_TRIANGLEADJ var_modifiers
|
|
+ {
|
|
+ $$ = add_modifiers(ctx, $2, HLSL_PRIMITIVE_TRIANGLEADJ, &@1);
|
|
+ }
|
|
| var_identifier var_modifiers
|
|
{
|
|
$$ = $2;
|
|
@@ -8981,14 +8760,7 @@ selection_statement:
|
|
|
|
check_condition_type(ctx, condition);
|
|
|
|
- if (!(condition = add_cast(ctx, $4, condition, hlsl_get_scalar_type(ctx, HLSL_TYPE_BOOL), &@4)))
|
|
- {
|
|
- destroy_block($6.then_block);
|
|
- destroy_block($6.else_block);
|
|
- cleanup_parse_attribute_list(&$1);
|
|
- YYABORT;
|
|
- }
|
|
-
|
|
+ condition = add_cast(ctx, $4, condition, hlsl_get_scalar_type(ctx, HLSL_TYPE_BOOL), &@4);
|
|
hlsl_block_add_if(ctx, $4, condition, $6.then_block, $6.else_block, &@2);
|
|
|
|
destroy_block($6.then_block);
|
|
@@ -9449,12 +9221,7 @@ unary_expr:
|
|
hlsl_error(ctx, &@2, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER,
|
|
"Modifiers are not allowed on casts.");
|
|
|
|
- if (!add_explicit_conversion(ctx, $6, $3, &$4, &@3))
|
|
- {
|
|
- destroy_block($6);
|
|
- vkd3d_free($4.sizes);
|
|
- YYABORT;
|
|
- }
|
|
+ add_explicit_conversion(ctx, $6, $3, &$4, &@3);
|
|
vkd3d_free($4.sizes);
|
|
$$ = $6;
|
|
}
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
|
|
index edcd9ce62a7..b5652475b43 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
|
|
@@ -1214,7 +1214,6 @@ static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr,
|
|
unsigned int dim_count = hlsl_sampler_dim_count(val->data_type->sampler_dim);
|
|
struct hlsl_ir_node *coords = index->idx.node;
|
|
struct hlsl_resource_load_params params = {0};
|
|
- struct hlsl_ir_node *resource_load;
|
|
|
|
VKD3D_ASSERT(coords->data_type->class == HLSL_CLASS_VECTOR);
|
|
VKD3D_ASSERT(coords->data_type->e.numeric.type == HLSL_TYPE_UINT);
|
|
@@ -1227,10 +1226,7 @@ static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr,
|
|
params.resource = val;
|
|
params.coords = coords;
|
|
params.format = val->data_type->e.resource.format;
|
|
-
|
|
- if (!(resource_load = hlsl_new_resource_load(ctx, ¶ms, &instr->loc)))
|
|
- return false;
|
|
- hlsl_block_add_instr(block, resource_load);
|
|
+ hlsl_block_add_resource_load(ctx, block, ¶ms, &instr->loc);
|
|
return true;
|
|
}
|
|
|
|
@@ -1295,7 +1291,7 @@ static bool lower_broadcasts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, s
|
|
|
|
if (src_type->class <= HLSL_CLASS_VECTOR && dst_type->class <= HLSL_CLASS_VECTOR && src_type->e.numeric.dimx == 1)
|
|
{
|
|
- struct hlsl_ir_node *new_cast, *swizzle;
|
|
+ struct hlsl_ir_node *new_cast;
|
|
|
|
dst_scalar_type = hlsl_get_scalar_type(ctx, dst_type->e.numeric.type);
|
|
/* We need to preserve the cast since it might be doing more than just
|
|
@@ -1303,12 +1299,8 @@ static bool lower_broadcasts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, s
|
|
new_cast = hlsl_block_add_cast(ctx, block, cast->operands[0].node, dst_scalar_type, &cast->node.loc);
|
|
|
|
if (dst_type->e.numeric.dimx != 1)
|
|
- {
|
|
- if (!(swizzle = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(X, X, X, X),
|
|
- dst_type->e.numeric.dimx, new_cast, &cast->node.loc)))
|
|
- return false;
|
|
- hlsl_block_add_instr(block, swizzle);
|
|
- }
|
|
+ hlsl_block_add_swizzle(ctx, block, HLSL_SWIZZLE(X, X, X, X),
|
|
+ dst_type->e.numeric.dimx, new_cast, &cast->node.loc);
|
|
|
|
return true;
|
|
}
|
|
@@ -1400,6 +1392,17 @@ static unsigned int index_instructions(struct hlsl_block *block, unsigned int in
|
|
*
|
|
* we can copy-prop the load (@7) into a constant vector {123, 456}, but we
|
|
* cannot easily vectorize the stores @3 and @6.
|
|
+ *
|
|
+ * Moreover, we implement a transformation that propagates loads with a single
|
|
+ * non-constant index in its deref path. Consider a load of the form
|
|
+ * var[[a0][a1]...[i]...[an]], where ak are integral constants, and i is an
|
|
+ * arbitrary non-constant node. If, for all j, the following holds:
|
|
+ *
|
|
+ * var[[a0][a1]...[j]...[an]] = x[[c0*j + d0][c1*j + d1]...[cm*j + dm]],
|
|
+ *
|
|
+ * where ck, dk are constants, then we can replace the load with
|
|
+ * x[[c0*i + d0]...[cm*i + dm]]. This pass is implemented by
|
|
+ * copy_propagation_replace_with_deref().
|
|
*/
|
|
|
|
struct copy_propagation_value
|
|
@@ -1624,16 +1627,25 @@ static void copy_propagation_invalidate_variable_from_deref_recurse(struct hlsl_
|
|
|
|
if (path_node->type == HLSL_IR_CONSTANT)
|
|
{
|
|
+ uint32_t index = hlsl_ir_constant(path_node)->value.u[0].u;
|
|
+
|
|
+ /* Don't bother invalidating anything if the index is constant but
|
|
+ * out-of-range.
|
|
+ * Such indices are illegal in HLSL, but only if the code is not
|
|
+ * dead, and we can't always know if code is dead without copy-prop
|
|
+ * itself. */
|
|
+ if (index >= hlsl_type_element_count(type))
|
|
+ return;
|
|
+
|
|
copy_propagation_invalidate_variable_from_deref_recurse(ctx, var_def, deref, subtype,
|
|
- depth + 1, hlsl_ir_constant(path_node)->value.u[0].u * subtype_comp_count,
|
|
- writemask, time);
|
|
+ depth + 1, comp_start + index * subtype_comp_count, writemask, time);
|
|
}
|
|
else
|
|
{
|
|
for (i = 0; i < hlsl_type_element_count(type); ++i)
|
|
{
|
|
copy_propagation_invalidate_variable_from_deref_recurse(ctx, var_def, deref, subtype,
|
|
- depth + 1, i * subtype_comp_count, writemask, time);
|
|
+ depth + 1, comp_start + i * subtype_comp_count, writemask, time);
|
|
}
|
|
}
|
|
}
|
|
@@ -1757,6 +1769,325 @@ static bool copy_propagation_replace_with_constant_vector(struct hlsl_ctx *ctx,
|
|
return true;
|
|
}
|
|
|
|
+static bool component_index_from_deref_path_node(struct hlsl_ir_node *path_node,
|
|
+ struct hlsl_type *type, unsigned int *index)
|
|
+{
|
|
+ unsigned int idx, i;
|
|
+
|
|
+ if (path_node->type != HLSL_IR_CONSTANT)
|
|
+ return false;
|
|
+
|
|
+ idx = hlsl_ir_constant(path_node)->value.u[0].u;
|
|
+ *index = 0;
|
|
+
|
|
+ switch (type->class)
|
|
+ {
|
|
+ case HLSL_CLASS_VECTOR:
|
|
+ if (idx >= type->e.numeric.dimx)
|
|
+ return false;
|
|
+ *index = idx;
|
|
+ break;
|
|
+
|
|
+ case HLSL_CLASS_MATRIX:
|
|
+ if (idx >= hlsl_type_major_size(type))
|
|
+ return false;
|
|
+ if (hlsl_type_is_row_major(type))
|
|
+ *index = idx * type->e.numeric.dimx;
|
|
+ else
|
|
+ *index = idx * type->e.numeric.dimy;
|
|
+ break;
|
|
+
|
|
+ case HLSL_CLASS_ARRAY:
|
|
+ if (idx >= type->e.array.elements_count)
|
|
+ return false;
|
|
+ *index = idx * hlsl_type_component_count(type->e.array.type);
|
|
+ break;
|
|
+
|
|
+ case HLSL_CLASS_STRUCT:
|
|
+ for (i = 0; i < idx; ++i)
|
|
+ *index += hlsl_type_component_count(type->e.record.fields[i].type);
|
|
+ break;
|
|
+
|
|
+ default:
|
|
+ vkd3d_unreachable();
|
|
+ }
|
|
+
|
|
+ return true;
|
|
+}
|
|
+
|
|
+static bool nonconst_index_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref,
|
|
+ unsigned int *idx, unsigned int *base, unsigned int *scale, unsigned int *count)
|
|
+{
|
|
+ struct hlsl_type *type = deref->var->data_type;
|
|
+ bool found = false;
|
|
+ unsigned int i;
|
|
+
|
|
+ *base = 0;
|
|
+
|
|
+ for (i = 0; i < deref->path_len; ++i)
|
|
+ {
|
|
+ struct hlsl_ir_node *path_node = deref->path[i].node;
|
|
+ struct hlsl_type *next_type;
|
|
+
|
|
+ VKD3D_ASSERT(path_node);
|
|
+
|
|
+ /* We should always have generated a cast to UINT. */
|
|
+ VKD3D_ASSERT(hlsl_is_vec1(path_node->data_type) && path_node->data_type->e.numeric.type == HLSL_TYPE_UINT);
|
|
+
|
|
+ next_type = hlsl_get_element_type_from_path_index(ctx, type, path_node);
|
|
+
|
|
+ if (path_node->type != HLSL_IR_CONSTANT)
|
|
+ {
|
|
+ if (found)
|
|
+ return false;
|
|
+ found = true;
|
|
+ *idx = i;
|
|
+ *scale = hlsl_type_component_count(next_type);
|
|
+ *count = hlsl_type_element_count(type);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ unsigned int index;
|
|
+
|
|
+ if (!component_index_from_deref_path_node(path_node, type, &index))
|
|
+ return false;
|
|
+ *base += index;
|
|
+ }
|
|
+
|
|
+ type = next_type;
|
|
+ }
|
|
+
|
|
+ return found;
|
|
+}
|
|
+
|
|
+static struct hlsl_ir_node *new_affine_path_index(struct hlsl_ctx *ctx, const struct vkd3d_shader_location *loc,
|
|
+ struct hlsl_block *block, struct hlsl_ir_node *index, int c, int d)
|
|
+{
|
|
+ struct hlsl_ir_node *c_node, *d_node, *ic, *idx;
|
|
+ bool use_uint = c >= 0 && d >= 0;
|
|
+
|
|
+ if (!c)
|
|
+ {
|
|
+ VKD3D_ASSERT(d >= 0);
|
|
+
|
|
+ return hlsl_block_add_uint_constant(ctx, block, d, loc);
|
|
+ }
|
|
+
|
|
+ if (use_uint)
|
|
+ {
|
|
+ c_node = hlsl_block_add_uint_constant(ctx, block, c, loc);
|
|
+ d_node = hlsl_block_add_uint_constant(ctx, block, d, loc);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ c_node = hlsl_block_add_int_constant(ctx, block, c, loc);
|
|
+ d_node = hlsl_block_add_int_constant(ctx, block, d, loc);
|
|
+ index = hlsl_block_add_cast(ctx, block, index, hlsl_get_scalar_type(ctx, HLSL_TYPE_INT), loc);
|
|
+ }
|
|
+
|
|
+ ic = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, index, c_node);
|
|
+ idx = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, ic, d_node);
|
|
+ if (!use_uint)
|
|
+ idx = hlsl_block_add_cast(ctx, block, idx, hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), loc);
|
|
+
|
|
+ return idx;
|
|
+}
|
|
+
|
|
+static bool copy_propagation_replace_with_deref(struct hlsl_ctx *ctx,
|
|
+ const struct copy_propagation_state *state, const struct hlsl_ir_load *load,
|
|
+ uint32_t swizzle, struct hlsl_ir_node *instr)
|
|
+{
|
|
+ const unsigned int instr_component_count = hlsl_type_component_count(instr->data_type);
|
|
+ unsigned int nonconst_i = 0, base, scale, count;
|
|
+ struct hlsl_ir_node *index, *new_instr = NULL;
|
|
+ const struct hlsl_deref *deref = &load->src;
|
|
+ const struct hlsl_ir_var *var = deref->var;
|
|
+ unsigned int time = load->node.index;
|
|
+ struct hlsl_deref tmp_deref = {0};
|
|
+ struct hlsl_ir_load *new_load;
|
|
+ struct hlsl_ir_var *x = NULL;
|
|
+ int *c = NULL, *d = NULL;
|
|
+ uint32_t ret_swizzle = 0;
|
|
+ struct hlsl_block block;
|
|
+ unsigned int path_len;
|
|
+ bool success = false;
|
|
+ int i, j, k;
|
|
+
|
|
+ if (!nonconst_index_from_deref(ctx, deref, &nonconst_i, &base, &scale, &count))
|
|
+ return false;
|
|
+
|
|
+ if (hlsl_version_lt(ctx, 4, 0))
|
|
+ {
|
|
+ TRACE("Non-constant index propagation is not yet supported for SM1.\n");
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ VKD3D_ASSERT(count);
|
|
+
|
|
+ hlsl_block_init(&block);
|
|
+
|
|
+ index = deref->path[nonconst_i].node;
|
|
+
|
|
+ /* Iterate over the nonconst index, and check if their values all have the form
|
|
+ * x[[c0*i + d0][c1*i + d1]...[cm*i + dm]], and determine the constants c, d. */
|
|
+ for (i = 0; i < count; ++i)
|
|
+ {
|
|
+ unsigned int start = base + scale * i;
|
|
+ struct copy_propagation_value *value;
|
|
+ struct hlsl_ir_load *idx;
|
|
+ uint32_t cur_swizzle = 0;
|
|
+
|
|
+ if (!(value = copy_propagation_get_value(state, var,
|
|
+ start + hlsl_swizzle_get_component(swizzle, 0), time)))
|
|
+ goto done;
|
|
+
|
|
+ if (value->node->type != HLSL_IR_LOAD)
|
|
+ goto done;
|
|
+ idx = hlsl_ir_load(value->node);
|
|
+
|
|
+ if (!x)
|
|
+ x = idx->src.var;
|
|
+ else if (x != idx->src.var)
|
|
+ goto done;
|
|
+
|
|
+ if (i == 0)
|
|
+ {
|
|
+ path_len = idx->src.path_len;
|
|
+
|
|
+ if (path_len)
|
|
+ {
|
|
+ if (!(c = hlsl_calloc(ctx, path_len, sizeof(c[0])))
|
|
+ || !(d = hlsl_alloc(ctx, path_len * sizeof(d[0]))))
|
|
+ goto done;
|
|
+ }
|
|
+
|
|
+ for (k = 0; k < path_len; ++k)
|
|
+ {
|
|
+ if (idx->src.path[k].node->type != HLSL_IR_CONSTANT)
|
|
+ goto done;
|
|
+ d[k] = hlsl_ir_constant(idx->src.path[k].node)->value.u[0].u;
|
|
+ }
|
|
+
|
|
+ }
|
|
+ else if (i == 1)
|
|
+ {
|
|
+ struct hlsl_type *type = idx->src.var->data_type;
|
|
+
|
|
+ if (idx->src.path_len != path_len)
|
|
+ goto done;
|
|
+
|
|
+ /* Calculate constants c and d based on the first two path indices. */
|
|
+ for (k = 0; k < path_len; ++k)
|
|
+ {
|
|
+ int ix;
|
|
+
|
|
+ if (idx->src.path[k].node->type != HLSL_IR_CONSTANT)
|
|
+ goto done;
|
|
+ ix = hlsl_ir_constant(idx->src.path[k].node)->value.u[0].u;
|
|
+ c[k] = ix - d[k];
|
|
+ d[k] = ix - c[k] * i;
|
|
+
|
|
+ if (c[k] && type->class == HLSL_CLASS_STRUCT)
|
|
+ goto done;
|
|
+
|
|
+ type = hlsl_get_element_type_from_path_index(ctx, type, idx->src.path[k].node);
|
|
+ }
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ if (idx->src.path_len != path_len)
|
|
+ goto done;
|
|
+
|
|
+ /* Check that this load has the form x[[c0*i +d0][c1*i + d1]...[cm*i + dm]]. */
|
|
+ for (k = 0; k < path_len; ++k)
|
|
+ {
|
|
+ if (idx->src.path[k].node->type != HLSL_IR_CONSTANT)
|
|
+ goto done;
|
|
+ if (hlsl_ir_constant(idx->src.path[k].node)->value.u[0].u != c[k] * i + d[k])
|
|
+ goto done;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ hlsl_swizzle_set_component(&cur_swizzle, 0, value->component);
|
|
+
|
|
+ for (j = 1; j < instr_component_count; ++j)
|
|
+ {
|
|
+ struct copy_propagation_value *val;
|
|
+
|
|
+ if (!(val = copy_propagation_get_value(state, var,
|
|
+ start + hlsl_swizzle_get_component(swizzle, j), time)))
|
|
+ goto done;
|
|
+ if (val->node != &idx->node)
|
|
+ goto done;
|
|
+
|
|
+ hlsl_swizzle_set_component(&cur_swizzle, j, val->component);
|
|
+ }
|
|
+
|
|
+ if (i == 0)
|
|
+ ret_swizzle = cur_swizzle;
|
|
+ else if (ret_swizzle != cur_swizzle)
|
|
+ goto done;
|
|
+ }
|
|
+
|
|
+ if (!hlsl_init_deref(ctx, &tmp_deref, x, path_len))
|
|
+ goto done;
|
|
+
|
|
+ for (k = 0; k < path_len; ++k)
|
|
+ {
|
|
+ hlsl_src_from_node(&tmp_deref.path[k],
|
|
+ new_affine_path_index(ctx, &load->node.loc, &block, index, c[k], d[k]));
|
|
+ }
|
|
+
|
|
+ if (!(new_load = hlsl_new_load_index(ctx, &tmp_deref, NULL, &load->node.loc)))
|
|
+ goto done;
|
|
+ new_instr = &new_load->node;
|
|
+ hlsl_block_add_instr(&block, new_instr);
|
|
+
|
|
+ if (new_instr->data_type->class == HLSL_CLASS_SCALAR || new_instr->data_type->class == HLSL_CLASS_VECTOR)
|
|
+ new_instr = hlsl_block_add_swizzle(ctx, &block, ret_swizzle, instr_component_count, new_instr, &instr->loc);
|
|
+
|
|
+ if (TRACE_ON())
|
|
+ {
|
|
+ struct vkd3d_string_buffer buffer;
|
|
+
|
|
+ vkd3d_string_buffer_init(&buffer);
|
|
+
|
|
+ vkd3d_string_buffer_printf(&buffer, "Load from %s[", var->name);
|
|
+ for (j = 0; j < deref->path_len; ++j)
|
|
+ {
|
|
+ if (j == nonconst_i)
|
|
+ vkd3d_string_buffer_printf(&buffer, "[i]");
|
|
+ else
|
|
+ vkd3d_string_buffer_printf(&buffer, "[%u]", hlsl_ir_constant(deref->path[j].node)->value.u[0].u);
|
|
+ }
|
|
+ vkd3d_string_buffer_printf(&buffer, "]%s propagated as %s[",
|
|
+ debug_hlsl_swizzle(swizzle, instr_component_count), tmp_deref.var->name);
|
|
+ for (k = 0; k < path_len; ++k)
|
|
+ {
|
|
+ if (c[k])
|
|
+ vkd3d_string_buffer_printf(&buffer, "[i*%d + %d]", c[k], d[k]);
|
|
+ else
|
|
+ vkd3d_string_buffer_printf(&buffer, "[%d]", d[k]);
|
|
+ }
|
|
+ vkd3d_string_buffer_printf(&buffer, "]%s (i = %p).\n",
|
|
+ debug_hlsl_swizzle(ret_swizzle, instr_component_count), index);
|
|
+
|
|
+ vkd3d_string_buffer_trace(&buffer);
|
|
+ vkd3d_string_buffer_cleanup(&buffer);
|
|
+ }
|
|
+
|
|
+ list_move_before(&instr->entry, &block.instrs);
|
|
+ hlsl_replace_node(instr, new_instr);
|
|
+ success = true;
|
|
+
|
|
+done:
|
|
+ hlsl_cleanup_deref(&tmp_deref);
|
|
+ hlsl_block_cleanup(&block);
|
|
+ vkd3d_free(c);
|
|
+ vkd3d_free(d);
|
|
+ return success;
|
|
+}
|
|
+
|
|
static bool copy_propagation_transform_load(struct hlsl_ctx *ctx,
|
|
struct hlsl_ir_load *load, struct copy_propagation_state *state)
|
|
{
|
|
@@ -1811,6 +2142,9 @@ static bool copy_propagation_transform_load(struct hlsl_ctx *ctx,
|
|
if (copy_propagation_replace_with_single_instr(ctx, state, load, HLSL_SWIZZLE(X, Y, Z, W), &load->node))
|
|
return true;
|
|
|
|
+ if (copy_propagation_replace_with_deref(ctx, state, load, HLSL_SWIZZLE(X, Y, Z, W), &load->node))
|
|
+ return true;
|
|
+
|
|
return false;
|
|
}
|
|
|
|
@@ -1829,6 +2163,9 @@ static bool copy_propagation_transform_swizzle(struct hlsl_ctx *ctx,
|
|
if (copy_propagation_replace_with_single_instr(ctx, state, load, swizzle->u.vector, &swizzle->node))
|
|
return true;
|
|
|
|
+ if (copy_propagation_replace_with_deref(ctx, state, load, swizzle->u.vector, &swizzle->node))
|
|
+ return true;
|
|
+
|
|
return false;
|
|
}
|
|
|
|
@@ -2167,8 +2504,7 @@ static enum validation_result validate_component_index_range_from_deref(struct h
|
|
return DEREF_VALIDATION_NOT_CONSTANT;
|
|
|
|
/* We should always have generated a cast to UINT. */
|
|
- VKD3D_ASSERT(path_node->data_type->class == HLSL_CLASS_SCALAR
|
|
- && path_node->data_type->e.numeric.type == HLSL_TYPE_UINT);
|
|
+ VKD3D_ASSERT(hlsl_is_vec1(path_node->data_type) && path_node->data_type->e.numeric.type == HLSL_TYPE_UINT);
|
|
|
|
idx = hlsl_ir_constant(path_node)->value.u[0].u;
|
|
|
|
@@ -2325,11 +2661,6 @@ static bool validate_dereferences(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins
|
|
return false;
|
|
}
|
|
|
|
-static bool is_vec1(const struct hlsl_type *type)
|
|
-{
|
|
- return (type->class == HLSL_CLASS_SCALAR) || (type->class == HLSL_CLASS_VECTOR && type->e.numeric.dimx == 1);
|
|
-}
|
|
-
|
|
static bool fold_redundant_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context)
|
|
{
|
|
if (instr->type == HLSL_IR_EXPR)
|
|
@@ -2344,7 +2675,8 @@ static bool fold_redundant_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst
|
|
src_type = expr->operands[0].node->data_type;
|
|
|
|
if (hlsl_types_are_equal(src_type, dst_type)
|
|
- || (src_type->e.numeric.type == dst_type->e.numeric.type && is_vec1(src_type) && is_vec1(dst_type)))
|
|
+ || (src_type->e.numeric.type == dst_type->e.numeric.type
|
|
+ && hlsl_is_vec1(src_type) && hlsl_is_vec1(dst_type)))
|
|
{
|
|
hlsl_replace_node(&expr->node, expr->operands[0].node);
|
|
return true;
|
|
@@ -2507,18 +2839,14 @@ static bool lower_narrowing_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins
|
|
if (src_type->class <= HLSL_CLASS_VECTOR && dst_type->class <= HLSL_CLASS_VECTOR
|
|
&& dst_type->e.numeric.dimx < src_type->e.numeric.dimx)
|
|
{
|
|
- struct hlsl_ir_node *new_cast, *swizzle;
|
|
+ struct hlsl_ir_node *new_cast;
|
|
|
|
dst_vector_type = hlsl_get_vector_type(ctx, dst_type->e.numeric.type, src_type->e.numeric.dimx);
|
|
/* We need to preserve the cast since it might be doing more than just
|
|
* narrowing the vector. */
|
|
new_cast = hlsl_block_add_cast(ctx, block, cast->operands[0].node, dst_vector_type, &cast->node.loc);
|
|
-
|
|
- if (!(swizzle = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(X, Y, Z, W),
|
|
- dst_type->e.numeric.dimx, new_cast, &cast->node.loc)))
|
|
- return false;
|
|
- hlsl_block_add_instr(block, swizzle);
|
|
-
|
|
+ hlsl_block_add_swizzle(ctx, block, HLSL_SWIZZLE(X, Y, Z, W),
|
|
+ dst_type->e.numeric.dimx, new_cast, &cast->node.loc);
|
|
return true;
|
|
}
|
|
|
|
@@ -2732,9 +3060,7 @@ static bool lower_nonconstant_vector_derefs(struct hlsl_ctx *ctx, struct hlsl_ir
|
|
return false;
|
|
hlsl_block_add_instr(block, &vector_load->node);
|
|
|
|
- if (!(swizzle = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(X, X, X, X), width, idx, &instr->loc)))
|
|
- return false;
|
|
- hlsl_block_add_instr(block, swizzle);
|
|
+ swizzle = hlsl_block_add_swizzle(ctx, block, HLSL_SWIZZLE(X, X, X, X), width, idx, &instr->loc);
|
|
|
|
value.u[0].u = 0;
|
|
value.u[1].u = 1;
|
|
@@ -2867,11 +3193,8 @@ static bool lower_nonconstant_array_loads(struct hlsl_ctx *ctx, struct hlsl_ir_n
|
|
operands[0] = cut_index;
|
|
operands[1] = const_i;
|
|
equals = hlsl_block_add_expr(ctx, block, HLSL_OP2_EQUAL, operands, btype, &cut_index->loc);
|
|
-
|
|
- if (!(equals = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(X, X, X, X),
|
|
- var->data_type->e.numeric.dimx, equals, &cut_index->loc)))
|
|
- return false;
|
|
- hlsl_block_add_instr(block, equals);
|
|
+ equals = hlsl_block_add_swizzle(ctx, block, HLSL_SWIZZLE(X, X, X, X),
|
|
+ var->data_type->e.numeric.dimx, equals, &cut_index->loc);
|
|
|
|
var_load = hlsl_block_add_simple_load(ctx, block, var, &cut_index->loc);
|
|
|
|
@@ -3161,9 +3484,37 @@ static bool sort_synthetic_separated_samplers_first(struct hlsl_ctx *ctx)
|
|
return false;
|
|
}
|
|
|
|
-/* Turn CAST to int or uint as follows:
|
|
+/* Turn CAST to int or uint into TRUNC + REINTERPRET */
|
|
+static bool lower_casts_to_int(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
|
|
+{
|
|
+ struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = { 0 };
|
|
+ struct hlsl_ir_node *arg, *trunc;
|
|
+ struct hlsl_ir_expr *expr;
|
|
+
|
|
+ if (instr->type != HLSL_IR_EXPR)
|
|
+ return false;
|
|
+ expr = hlsl_ir_expr(instr);
|
|
+ if (expr->op != HLSL_OP1_CAST)
|
|
+ return false;
|
|
+
|
|
+ arg = expr->operands[0].node;
|
|
+ if (!hlsl_type_is_integer(instr->data_type) || instr->data_type->e.numeric.type == HLSL_TYPE_BOOL)
|
|
+ return false;
|
|
+ if (!hlsl_type_is_floating_point(arg->data_type))
|
|
+ return false;
|
|
+
|
|
+ trunc = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_TRUNC, arg, &instr->loc);
|
|
+
|
|
+ memset(operands, 0, sizeof(operands));
|
|
+ operands[0] = trunc;
|
|
+ hlsl_block_add_expr(ctx, block, HLSL_OP1_REINTERPRET, operands, instr->data_type, &instr->loc);
|
|
+
|
|
+ return true;
|
|
+}
|
|
+
|
|
+/* Turn TRUNC into:
|
|
*
|
|
- * CAST(x) = x - FRACT(x) + extra
|
|
+ * TRUNC(x) = x - FRACT(x) + extra
|
|
*
|
|
* where
|
|
*
|
|
@@ -3171,27 +3522,19 @@ static bool sort_synthetic_separated_samplers_first(struct hlsl_ctx *ctx)
|
|
*
|
|
* where the comparisons in the extra term are performed using CMP or SLT
|
|
* depending on whether this is a pixel or vertex shader, respectively.
|
|
- *
|
|
- * A REINTERPET (which is written as a mere MOV) is also applied to the final
|
|
- * result for type consistency.
|
|
*/
|
|
-static bool lower_casts_to_int(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
|
|
+static bool lower_trunc(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
|
|
{
|
|
- struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = { 0 };
|
|
struct hlsl_ir_node *arg, *res;
|
|
struct hlsl_ir_expr *expr;
|
|
|
|
if (instr->type != HLSL_IR_EXPR)
|
|
return false;
|
|
expr = hlsl_ir_expr(instr);
|
|
- if (expr->op != HLSL_OP1_CAST)
|
|
+ if (expr->op != HLSL_OP1_TRUNC)
|
|
return false;
|
|
|
|
arg = expr->operands[0].node;
|
|
- if (!hlsl_type_is_integer(instr->data_type) || instr->data_type->e.numeric.type == HLSL_TYPE_BOOL)
|
|
- return false;
|
|
- if (arg->data_type->e.numeric.type != HLSL_TYPE_FLOAT && arg->data_type->e.numeric.type != HLSL_TYPE_HALF)
|
|
- return false;
|
|
|
|
if (ctx->profile->type == VKD3D_SHADER_TYPE_PIXEL)
|
|
{
|
|
@@ -3241,9 +3584,6 @@ static bool lower_casts_to_int(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr,
|
|
hlsl_block_add_instr(block, res);
|
|
}
|
|
|
|
- memset(operands, 0, sizeof(operands));
|
|
- operands[0] = res;
|
|
- hlsl_block_add_expr(ctx, block, HLSL_OP1_REINTERPRET, operands, instr->data_type, &instr->loc);
|
|
return true;
|
|
}
|
|
|
|
@@ -3327,16 +3667,10 @@ static bool lower_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct h
|
|
{
|
|
mul = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, expr->operands[0].node, expr->operands[1].node);
|
|
|
|
- if (!(add_x = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(X, X, X, X),
|
|
- instr->data_type->e.numeric.dimx, mul, &expr->node.loc)))
|
|
- return false;
|
|
- hlsl_block_add_instr(block, add_x);
|
|
-
|
|
- if (!(add_y = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(Y, Y, Y, Y),
|
|
- instr->data_type->e.numeric.dimx, mul, &expr->node.loc)))
|
|
- return false;
|
|
- hlsl_block_add_instr(block, add_y);
|
|
-
|
|
+ add_x = hlsl_block_add_swizzle(ctx, block, HLSL_SWIZZLE(X, X, X, X),
|
|
+ instr->data_type->e.numeric.dimx, mul, &expr->node.loc);
|
|
+ add_y = hlsl_block_add_swizzle(ctx, block, HLSL_SWIZZLE(Y, Y, Y, Y),
|
|
+ instr->data_type->e.numeric.dimx, mul, &expr->node.loc);
|
|
hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, add_x, add_y);
|
|
}
|
|
|
|
@@ -3499,9 +3833,7 @@ static bool lower_trig(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct
|
|
{
|
|
uint32_t s = hlsl_swizzle_from_writemask(1 << i);
|
|
|
|
- if (!(comps[i] = hlsl_new_swizzle(ctx, s, 1, reduced, &instr->loc)))
|
|
- return false;
|
|
- hlsl_block_add_instr(block, comps[i]);
|
|
+ comps[i] = hlsl_block_add_swizzle(ctx, block, s, 1, reduced, &instr->loc);
|
|
}
|
|
|
|
if (!(var = hlsl_new_synthetic_var(ctx, "sincos", type, &instr->loc)))
|
|
@@ -4021,9 +4353,7 @@ static bool lower_int_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, stru
|
|
{
|
|
uint32_t s = hlsl_swizzle_from_writemask(1 << i);
|
|
|
|
- if (!(comps[i] = hlsl_new_swizzle(ctx, s, 1, mult, &instr->loc)))
|
|
- return false;
|
|
- hlsl_block_add_instr(block, comps[i]);
|
|
+ comps[i] = hlsl_block_add_swizzle(ctx, block, s, 1, mult, &instr->loc);
|
|
}
|
|
|
|
res = comps[0];
|
|
@@ -4812,8 +5142,7 @@ static void register_deref_usage(struct hlsl_ctx *ctx, struct hlsl_deref *deref)
|
|
struct hlsl_type *type;
|
|
unsigned int index;
|
|
|
|
- if (!hlsl_regset_index_from_deref(ctx, deref, regset, &index))
|
|
- return;
|
|
+ hlsl_regset_index_from_deref(ctx, deref, regset, &index);
|
|
|
|
if (regset <= HLSL_REGSET_LAST_OBJECT)
|
|
{
|
|
@@ -4824,7 +5153,6 @@ static void register_deref_usage(struct hlsl_ctx *ctx, struct hlsl_deref *deref)
|
|
{
|
|
type = hlsl_deref_get_type(ctx, deref);
|
|
|
|
- hlsl_regset_index_from_deref(ctx, deref, regset, &index);
|
|
required_bind_count = align(index + type->reg_size[regset], 4) / 4;
|
|
var->bind_count[regset] = max(var->bind_count[regset], required_bind_count);
|
|
}
|
|
@@ -5913,7 +6241,7 @@ bool hlsl_component_index_range_from_deref(struct hlsl_ctx *ctx, const struct hl
|
|
unsigned int *start, unsigned int *count)
|
|
{
|
|
struct hlsl_type *type = deref->var->data_type;
|
|
- unsigned int i, k;
|
|
+ unsigned int i;
|
|
|
|
*start = 0;
|
|
*count = 0;
|
|
@@ -5921,49 +6249,18 @@ bool hlsl_component_index_range_from_deref(struct hlsl_ctx *ctx, const struct hl
|
|
for (i = 0; i < deref->path_len; ++i)
|
|
{
|
|
struct hlsl_ir_node *path_node = deref->path[i].node;
|
|
- unsigned int idx = 0;
|
|
+ unsigned int index;
|
|
|
|
VKD3D_ASSERT(path_node);
|
|
if (path_node->type != HLSL_IR_CONSTANT)
|
|
return false;
|
|
|
|
/* We should always have generated a cast to UINT. */
|
|
- VKD3D_ASSERT(path_node->data_type->class == HLSL_CLASS_SCALAR
|
|
- && path_node->data_type->e.numeric.type == HLSL_TYPE_UINT);
|
|
-
|
|
- idx = hlsl_ir_constant(path_node)->value.u[0].u;
|
|
-
|
|
- switch (type->class)
|
|
- {
|
|
- case HLSL_CLASS_VECTOR:
|
|
- if (idx >= type->e.numeric.dimx)
|
|
- return false;
|
|
- *start += idx;
|
|
- break;
|
|
-
|
|
- case HLSL_CLASS_MATRIX:
|
|
- if (idx >= hlsl_type_major_size(type))
|
|
- return false;
|
|
- if (hlsl_type_is_row_major(type))
|
|
- *start += idx * type->e.numeric.dimx;
|
|
- else
|
|
- *start += idx * type->e.numeric.dimy;
|
|
- break;
|
|
-
|
|
- case HLSL_CLASS_ARRAY:
|
|
- if (idx >= type->e.array.elements_count)
|
|
- return false;
|
|
- *start += idx * hlsl_type_component_count(type->e.array.type);
|
|
- break;
|
|
+ VKD3D_ASSERT(hlsl_is_vec1(path_node->data_type) && path_node->data_type->e.numeric.type == HLSL_TYPE_UINT);
|
|
|
|
- case HLSL_CLASS_STRUCT:
|
|
- for (k = 0; k < idx; ++k)
|
|
- *start += hlsl_type_component_count(type->e.record.fields[k].type);
|
|
- break;
|
|
-
|
|
- default:
|
|
- vkd3d_unreachable();
|
|
- }
|
|
+ if (!component_index_from_deref_path_node(path_node, type, &index))
|
|
+ return false;
|
|
+ *start += index;
|
|
|
|
type = hlsl_get_element_type_from_path_index(ctx, type, path_node);
|
|
}
|
|
@@ -5992,8 +6289,7 @@ bool hlsl_regset_index_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref
|
|
if (path_node->type == HLSL_IR_CONSTANT)
|
|
{
|
|
/* We should always have generated a cast to UINT. */
|
|
- VKD3D_ASSERT(path_node->data_type->class == HLSL_CLASS_SCALAR
|
|
- && path_node->data_type->e.numeric.type == HLSL_TYPE_UINT);
|
|
+ VKD3D_ASSERT(hlsl_is_vec1(path_node->data_type) && path_node->data_type->e.numeric.type == HLSL_TYPE_UINT);
|
|
|
|
idx = hlsl_ir_constant(path_node)->value.u[0].u;
|
|
|
|
@@ -6061,8 +6357,7 @@ bool hlsl_offset_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref
|
|
if (offset_node)
|
|
{
|
|
/* We should always have generated a cast to UINT. */
|
|
- VKD3D_ASSERT(offset_node->data_type->class == HLSL_CLASS_SCALAR
|
|
- && offset_node->data_type->e.numeric.type == HLSL_TYPE_UINT);
|
|
+ VKD3D_ASSERT(hlsl_is_vec1(offset_node->data_type) && offset_node->data_type->e.numeric.type == HLSL_TYPE_UINT);
|
|
VKD3D_ASSERT(offset_node->type != HLSL_IR_CONSTANT);
|
|
return false;
|
|
}
|
|
@@ -6097,11 +6392,14 @@ struct hlsl_reg hlsl_reg_from_deref(struct hlsl_ctx *ctx, const struct hlsl_dere
|
|
{
|
|
const struct hlsl_ir_var *var = deref->var;
|
|
struct hlsl_reg ret = var->regs[HLSL_REGSET_NUMERIC];
|
|
- unsigned int offset = hlsl_offset_from_deref_safe(ctx, deref);
|
|
+ unsigned int offset = 0;
|
|
|
|
VKD3D_ASSERT(deref->data_type);
|
|
VKD3D_ASSERT(hlsl_is_numeric_type(deref->data_type));
|
|
|
|
+ if (!hlsl_type_is_patch_array(deref->var->data_type))
|
|
+ offset = hlsl_offset_from_deref_safe(ctx, deref);
|
|
+
|
|
ret.index += offset / 4;
|
|
ret.id += offset / 4;
|
|
|
|
@@ -6112,6 +6410,36 @@ struct hlsl_reg hlsl_reg_from_deref(struct hlsl_ctx *ctx, const struct hlsl_dere
|
|
return ret;
|
|
}
|
|
|
|
+static bool get_integral_argument_value(struct hlsl_ctx *ctx, const struct hlsl_attribute *attr,
|
|
+ unsigned int i, enum hlsl_base_type *base_type, int *value)
|
|
+{
|
|
+ const struct hlsl_ir_node *instr = attr->args[i].node;
|
|
+ const struct hlsl_type *type = instr->data_type;
|
|
+
|
|
+ if (type->class != HLSL_CLASS_SCALAR
|
|
+ || (type->e.numeric.type != HLSL_TYPE_INT && type->e.numeric.type != HLSL_TYPE_UINT))
|
|
+ {
|
|
+ struct vkd3d_string_buffer *string;
|
|
+
|
|
+ if ((string = hlsl_type_to_string(ctx, type)))
|
|
+ hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
|
|
+ "Unexpected type for argument %u of [%s]: expected int or uint, but got %s.",
|
|
+ i, attr->name, string->buffer);
|
|
+ hlsl_release_string_buffer(ctx, string);
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ if (instr->type != HLSL_IR_CONSTANT)
|
|
+ {
|
|
+ hlsl_fixme(ctx, &instr->loc, "Non-constant expression in [%s] initializer.", attr->name);
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ *base_type = type->e.numeric.type;
|
|
+ *value = hlsl_ir_constant(instr)->value.u[0].i;
|
|
+ return true;
|
|
+}
|
|
+
|
|
static const char *get_string_argument_value(struct hlsl_ctx *ctx, const struct hlsl_attribute *attr, unsigned int i)
|
|
{
|
|
const struct hlsl_ir_node *instr = attr->args[i].node;
|
|
@@ -6147,36 +6475,17 @@ static void parse_numthreads_attribute(struct hlsl_ctx *ctx, const struct hlsl_a
|
|
|
|
for (i = 0; i < attr->args_count; ++i)
|
|
{
|
|
- const struct hlsl_ir_node *instr = attr->args[i].node;
|
|
- const struct hlsl_type *type = instr->data_type;
|
|
- const struct hlsl_ir_constant *constant;
|
|
+ enum hlsl_base_type base_type;
|
|
+ int value;
|
|
|
|
- if (type->class != HLSL_CLASS_SCALAR
|
|
- || (type->e.numeric.type != HLSL_TYPE_INT && type->e.numeric.type != HLSL_TYPE_UINT))
|
|
- {
|
|
- struct vkd3d_string_buffer *string;
|
|
-
|
|
- if ((string = hlsl_type_to_string(ctx, type)))
|
|
- hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
|
|
- "Wrong type for argument %u of [numthreads]: expected int or uint, but got %s.",
|
|
- i, string->buffer);
|
|
- hlsl_release_string_buffer(ctx, string);
|
|
- break;
|
|
- }
|
|
-
|
|
- if (instr->type != HLSL_IR_CONSTANT)
|
|
- {
|
|
- hlsl_fixme(ctx, &instr->loc, "Non-constant expression in [numthreads] initializer.");
|
|
- break;
|
|
- }
|
|
- constant = hlsl_ir_constant(instr);
|
|
+ if (!get_integral_argument_value(ctx, attr, i, &base_type, &value))
|
|
+ return;
|
|
|
|
- if ((type->e.numeric.type == HLSL_TYPE_INT && constant->value.u[0].i <= 0)
|
|
- || (type->e.numeric.type == HLSL_TYPE_UINT && !constant->value.u[0].u))
|
|
- hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_THREAD_COUNT,
|
|
+ if ((base_type == HLSL_TYPE_INT && value <= 0) || (base_type == HLSL_TYPE_UINT && !value))
|
|
+ hlsl_error(ctx, &attr->args[i].node->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_THREAD_COUNT,
|
|
"Thread count must be a positive integer.");
|
|
|
|
- ctx->thread_count[i] = constant->value.u[0].u;
|
|
+ ctx->thread_count[i] = value;
|
|
}
|
|
}
|
|
|
|
@@ -6208,9 +6517,8 @@ static void parse_domain_attribute(struct hlsl_ctx *ctx, const struct hlsl_attri
|
|
|
|
static void parse_outputcontrolpoints_attribute(struct hlsl_ctx *ctx, const struct hlsl_attribute *attr)
|
|
{
|
|
- const struct hlsl_ir_node *instr;
|
|
- const struct hlsl_type *type;
|
|
- const struct hlsl_ir_constant *constant;
|
|
+ enum hlsl_base_type base_type;
|
|
+ int value;
|
|
|
|
if (attr->args_count != 1)
|
|
{
|
|
@@ -6219,35 +6527,14 @@ static void parse_outputcontrolpoints_attribute(struct hlsl_ctx *ctx, const stru
|
|
return;
|
|
}
|
|
|
|
- instr = attr->args[0].node;
|
|
- type = instr->data_type;
|
|
-
|
|
- if (type->class != HLSL_CLASS_SCALAR
|
|
- || (type->e.numeric.type != HLSL_TYPE_INT && type->e.numeric.type != HLSL_TYPE_UINT))
|
|
- {
|
|
- struct vkd3d_string_buffer *string;
|
|
-
|
|
- if ((string = hlsl_type_to_string(ctx, type)))
|
|
- hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
|
|
- "Wrong type for argument 0 of [outputcontrolpoints]: expected int or uint, but got %s.",
|
|
- string->buffer);
|
|
- hlsl_release_string_buffer(ctx, string);
|
|
- return;
|
|
- }
|
|
-
|
|
- if (instr->type != HLSL_IR_CONSTANT)
|
|
- {
|
|
- hlsl_fixme(ctx, &instr->loc, "Non-constant expression in [outputcontrolpoints] initializer.");
|
|
+ if (!get_integral_argument_value(ctx, attr, 0, &base_type, &value))
|
|
return;
|
|
- }
|
|
- constant = hlsl_ir_constant(instr);
|
|
|
|
- if ((type->e.numeric.type == HLSL_TYPE_INT && constant->value.u[0].i < 0)
|
|
- || constant->value.u[0].u > 32)
|
|
- hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_CONTROL_POINT_COUNT,
|
|
+ if (value < 0 || value > 32)
|
|
+ hlsl_error(ctx, &attr->args[0].node->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_CONTROL_POINT_COUNT,
|
|
"Output control point count must be between 0 and 32.");
|
|
|
|
- ctx->output_control_point_count = constant->value.u[0].u;
|
|
+ ctx->output_control_point_count = value;
|
|
}
|
|
|
|
static void parse_outputtopology_attribute(struct hlsl_ctx *ctx, const struct hlsl_attribute *attr)
|
|
@@ -6341,6 +6628,28 @@ static void parse_patchconstantfunc_attribute(struct hlsl_ctx *ctx, const struct
|
|
"Patch constant function \"%s\" is not defined.", name);
|
|
}
|
|
|
|
+static void parse_maxvertexcount_attribute(struct hlsl_ctx *ctx, const struct hlsl_attribute *attr)
|
|
+{
|
|
+ enum hlsl_base_type base_type;
|
|
+ int value;
|
|
+
|
|
+ if (attr->args_count != 1)
|
|
+ {
|
|
+ hlsl_error(ctx, &attr->loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT,
|
|
+ "Expected 1 parameter for [maxvertexcount] attribute, but got %u.", attr->args_count);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if (!get_integral_argument_value(ctx, attr, 0, &base_type, &value))
|
|
+ return;
|
|
+
|
|
+ if (value < 1 || value > 1024)
|
|
+ hlsl_error(ctx, &attr->args[0].node->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MAX_VERTEX_COUNT,
|
|
+ "Max vertex count must be between 1 and 1024.");
|
|
+
|
|
+ ctx->max_vertex_count = value;
|
|
+}
|
|
+
|
|
static void parse_entry_function_attributes(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func)
|
|
{
|
|
const struct hlsl_profile_info *profile = ctx->profile;
|
|
@@ -6365,6 +6674,8 @@ static void parse_entry_function_attributes(struct hlsl_ctx *ctx, struct hlsl_ir
|
|
parse_patchconstantfunc_attribute(ctx, attr);
|
|
else if (!strcmp(attr->name, "earlydepthstencil") && profile->type == VKD3D_SHADER_TYPE_PIXEL)
|
|
entry_func->early_depth_test = true;
|
|
+ else if (!strcmp(attr->name, "maxvertexcount") && profile->type == VKD3D_SHADER_TYPE_GEOMETRY)
|
|
+ parse_maxvertexcount_attribute(ctx, attr);
|
|
else
|
|
hlsl_warning(ctx, &entry_func->attrs[i]->loc, VKD3D_SHADER_WARNING_HLSL_UNKNOWN_ATTRIBUTE,
|
|
"Ignoring unknown attribute \"%s\".", entry_func->attrs[i]->name);
|
|
@@ -6437,7 +6748,71 @@ static void validate_hull_shader_attributes(struct hlsl_ctx *ctx, const struct h
|
|
}
|
|
}
|
|
|
|
-static void validate_and_record_patch_type(struct hlsl_ctx *ctx, struct hlsl_ir_var *var)
|
|
+static enum vkd3d_primitive_type get_primitive_type(struct hlsl_ctx *ctx, struct hlsl_ir_var *var)
|
|
+{
|
|
+ uint32_t prim_modifier = var->data_type->modifiers & HLSL_PRIMITIVE_MODIFIERS_MASK;
|
|
+ enum vkd3d_primitive_type prim_type = VKD3D_PT_UNDEFINED;
|
|
+
|
|
+ if (prim_modifier)
|
|
+ {
|
|
+ unsigned int count = var->data_type->e.array.elements_count;
|
|
+ unsigned int expected_count;
|
|
+
|
|
+ VKD3D_ASSERT(!(prim_modifier & (prim_modifier - 1)));
|
|
+
|
|
+ switch (prim_modifier)
|
|
+ {
|
|
+ case HLSL_PRIMITIVE_POINT:
|
|
+ prim_type = VKD3D_PT_POINTLIST;
|
|
+ expected_count = 1;
|
|
+ break;
|
|
+
|
|
+ case HLSL_PRIMITIVE_LINE:
|
|
+ prim_type = VKD3D_PT_LINELIST;
|
|
+ expected_count = 2;
|
|
+ break;
|
|
+
|
|
+ case HLSL_PRIMITIVE_TRIANGLE:
|
|
+ prim_type = VKD3D_PT_TRIANGLELIST;
|
|
+ expected_count = 3;
|
|
+ break;
|
|
+
|
|
+ case HLSL_PRIMITIVE_LINEADJ:
|
|
+ prim_type = VKD3D_PT_LINELIST_ADJ;
|
|
+ expected_count = 4;
|
|
+ break;
|
|
+
|
|
+ case HLSL_PRIMITIVE_TRIANGLEADJ:
|
|
+ prim_type = VKD3D_PT_TRIANGLELIST_ADJ;
|
|
+ expected_count = 6;
|
|
+ break;
|
|
+
|
|
+ default:
|
|
+ vkd3d_unreachable();
|
|
+ }
|
|
+
|
|
+ if (count != expected_count)
|
|
+ {
|
|
+ struct vkd3d_string_buffer *string;
|
|
+
|
|
+ if ((string = hlsl_modifiers_to_string(ctx, prim_modifier)))
|
|
+ hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_CONTROL_POINT_COUNT,
|
|
+ "Control point count %u does not match the expect count %u for the %s input primitive type.",
|
|
+ count, expected_count, string->buffer);
|
|
+ hlsl_release_string_buffer(ctx, string);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /* Patch types take precedence over primitive modifiers. */
|
|
+ if (hlsl_type_is_patch_array(var->data_type))
|
|
+ prim_type = VKD3D_PT_PATCH;
|
|
+
|
|
+ VKD3D_ASSERT(prim_type != VKD3D_PT_UNDEFINED);
|
|
+ return prim_type;
|
|
+}
|
|
+
|
|
+
|
|
+static void validate_and_record_prim_type(struct hlsl_ctx *ctx, struct hlsl_ir_var *var)
|
|
{
|
|
unsigned int control_point_count = var->data_type->e.array.elements_count;
|
|
enum hlsl_array_type array_type = var->data_type->e.array.array_type;
|
|
@@ -6455,7 +6830,7 @@ static void validate_and_record_patch_type(struct hlsl_ctx *ctx, struct hlsl_ir_
|
|
return;
|
|
}
|
|
}
|
|
- else
|
|
+ else if (array_type == HLSL_ARRAY_PATCH_OUTPUT)
|
|
{
|
|
if (!ctx->is_patch_constant_func && profile->type != VKD3D_SHADER_TYPE_DOMAIN)
|
|
{
|
|
@@ -6466,6 +6841,30 @@ static void validate_and_record_patch_type(struct hlsl_ctx *ctx, struct hlsl_ir_
|
|
}
|
|
}
|
|
|
|
+ if ((var->data_type->modifiers & HLSL_PRIMITIVE_MODIFIERS_MASK) && profile->type != VKD3D_SHADER_TYPE_GEOMETRY)
|
|
+ {
|
|
+ hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE,
|
|
+ "Input primitive parameters can only be used in geometry shaders.");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if (profile->type == VKD3D_SHADER_TYPE_GEOMETRY)
|
|
+ {
|
|
+ enum vkd3d_primitive_type prim_type = get_primitive_type(ctx, var);
|
|
+
|
|
+ if (ctx->input_primitive_type == VKD3D_PT_UNDEFINED)
|
|
+ {
|
|
+ ctx->input_primitive_type = prim_type;
|
|
+ }
|
|
+ else if (ctx->input_primitive_type != prim_type)
|
|
+ {
|
|
+ hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
|
|
+ "Input primitive type does not match the previously declared type.");
|
|
+ hlsl_note(ctx, &ctx->input_primitive_param->loc, VKD3D_SHADER_LOG_ERROR,
|
|
+ "The input primitive was previously declared here.");
|
|
+ }
|
|
+ }
|
|
+
|
|
if (control_point_count > 32)
|
|
{
|
|
hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_CONTROL_POINT_COUNT,
|
|
@@ -6478,7 +6877,7 @@ static void validate_and_record_patch_type(struct hlsl_ctx *ctx, struct hlsl_ir_
|
|
{
|
|
if (control_point_count != ctx->output_control_point_count)
|
|
hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_CONTROL_POINT_COUNT,
|
|
- "Output control point count %u does not match the count %u specified in the control point function.",
|
|
+ "Output control point count %u does not match the count %u declared in the control point function.",
|
|
control_point_count, ctx->output_control_point_count);
|
|
|
|
if (!hlsl_types_are_equal(control_point_type, ctx->output_control_point_type))
|
|
@@ -6490,22 +6889,32 @@ static void validate_and_record_patch_type(struct hlsl_ctx *ctx, struct hlsl_ir_
|
|
|
|
if (ctx->input_control_point_count != UINT_MAX)
|
|
{
|
|
- VKD3D_ASSERT(ctx->is_patch_constant_func);
|
|
+ VKD3D_ASSERT(profile->type == VKD3D_SHADER_TYPE_GEOMETRY || ctx->is_patch_constant_func);
|
|
|
|
if (control_point_count != ctx->input_control_point_count)
|
|
+ {
|
|
hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_CONTROL_POINT_COUNT,
|
|
- "Input control point count %u does not match the count %u specified in the control point function.",
|
|
+ "Input control point count %u does not match the count %u declared previously.",
|
|
control_point_count, ctx->input_control_point_count);
|
|
+ hlsl_note(ctx, &ctx->input_primitive_param->loc, VKD3D_SHADER_LOG_ERROR,
|
|
+ "The input primitive was previously declared here.");
|
|
+ }
|
|
|
|
- if (!hlsl_types_are_equal(control_point_type, ctx->input_control_point_type))
|
|
+ if (profile->type != VKD3D_SHADER_TYPE_GEOMETRY
|
|
+ && !hlsl_types_are_equal(control_point_type, ctx->input_control_point_type))
|
|
+ {
|
|
hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
|
|
- "Input control point type does not match the input type specified in the control point function.");
|
|
+ "Input control point type does not match the input type declared previously.");
|
|
+ hlsl_note(ctx, &ctx->input_primitive_param->loc, VKD3D_SHADER_LOG_ERROR,
|
|
+ "The input primitive was previously declared here.");
|
|
+ }
|
|
|
|
return;
|
|
}
|
|
|
|
ctx->input_control_point_count = control_point_count;
|
|
ctx->input_control_point_type = control_point_type;
|
|
+ ctx->input_primitive_param = var;
|
|
}
|
|
|
|
static void remove_unreachable_code(struct hlsl_ctx *ctx, struct hlsl_block *body)
|
|
@@ -6569,6 +6978,24 @@ void hlsl_lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_block *body)
|
|
lower_ir(ctx, lower_index_loads, body);
|
|
}
|
|
|
|
+
|
|
+static bool simplify_exprs(struct hlsl_ctx *ctx, struct hlsl_block *block)
|
|
+{
|
|
+ bool progress, any_progress = false;
|
|
+
|
|
+ do
|
|
+ {
|
|
+ progress = hlsl_transform_ir(ctx, hlsl_fold_constant_exprs, block, NULL);
|
|
+ progress |= hlsl_transform_ir(ctx, hlsl_normalize_binary_exprs, block, NULL);
|
|
+ progress |= hlsl_transform_ir(ctx, hlsl_fold_constant_identities, block, NULL);
|
|
+ progress |= hlsl_transform_ir(ctx, hlsl_fold_constant_swizzles, block, NULL);
|
|
+
|
|
+ any_progress |= progress;
|
|
+ } while (progress);
|
|
+
|
|
+ return any_progress;
|
|
+}
|
|
+
|
|
static void hlsl_run_folding_passes(struct hlsl_ctx *ctx, struct hlsl_block *body)
|
|
{
|
|
bool progress;
|
|
@@ -6576,15 +7003,13 @@ static void hlsl_run_folding_passes(struct hlsl_ctx *ctx, struct hlsl_block *bod
|
|
hlsl_transform_ir(ctx, fold_redundant_casts, body, NULL);
|
|
do
|
|
{
|
|
- progress = hlsl_transform_ir(ctx, hlsl_fold_constant_exprs, body, NULL);
|
|
- progress |= hlsl_transform_ir(ctx, hlsl_fold_constant_identities, body, NULL);
|
|
- progress |= hlsl_transform_ir(ctx, hlsl_normalize_binary_exprs, body, NULL);
|
|
- progress |= hlsl_transform_ir(ctx, hlsl_fold_constant_swizzles, body, NULL);
|
|
+ progress = simplify_exprs(ctx, body);
|
|
progress |= hlsl_copy_propagation_execute(ctx, body);
|
|
progress |= hlsl_transform_ir(ctx, fold_swizzle_chains, body, NULL);
|
|
progress |= hlsl_transform_ir(ctx, remove_trivial_swizzles, body, NULL);
|
|
progress |= hlsl_transform_ir(ctx, remove_trivial_conditional_branches, body, NULL);
|
|
} while (progress);
|
|
+ hlsl_transform_ir(ctx, fold_redundant_casts, body, NULL);
|
|
}
|
|
|
|
void hlsl_run_const_passes(struct hlsl_ctx *ctx, struct hlsl_block *body)
|
|
@@ -7214,7 +7639,7 @@ static bool sm4_generate_vsir_reg_from_deref(struct hlsl_ctx *ctx, struct vsir_p
|
|
}
|
|
else
|
|
{
|
|
- unsigned int offset = hlsl_offset_from_deref_safe(ctx, deref) + var->buffer_offset;
|
|
+ unsigned int offset = deref->const_offset + var->buffer_offset;
|
|
|
|
VKD3D_ASSERT(data_type->class <= HLSL_CLASS_VECTOR);
|
|
reg->type = VKD3DSPR_CONSTBUFFER;
|
|
@@ -7232,6 +7657,14 @@ static bool sm4_generate_vsir_reg_from_deref(struct hlsl_ctx *ctx, struct vsir_p
|
|
reg->idx[1].offset = offset / 4;
|
|
reg->idx_count = 2;
|
|
}
|
|
+
|
|
+ if (deref->rel_offset.node)
|
|
+ {
|
|
+ if (!(reg->idx[reg->idx_count - 1].rel_addr = sm4_generate_vsir_new_idx_src(ctx,
|
|
+ program, deref->rel_offset.node)))
|
|
+ return false;
|
|
+ }
|
|
+
|
|
*writemask = ((1u << data_type->e.numeric.dimx) - 1) << (offset & 3);
|
|
}
|
|
}
|
|
@@ -11515,9 +11948,7 @@ static void loop_unrolling_simplify(struct hlsl_ctx *ctx, struct hlsl_block *blo
|
|
copy_propagation_pop_scope(state);
|
|
copy_propagation_push_scope(state, ctx);
|
|
|
|
- progress = hlsl_transform_ir(ctx, hlsl_fold_constant_exprs, block, NULL);
|
|
- progress |= hlsl_transform_ir(ctx, hlsl_fold_constant_identities, block, NULL);
|
|
- progress |= hlsl_transform_ir(ctx, hlsl_fold_constant_swizzles, block, NULL);
|
|
+ progress = simplify_exprs(ctx, block);
|
|
|
|
current_index = index_instructions(block, *index);
|
|
progress |= copy_propagation_transform_block(ctx, block, state);
|
|
@@ -12060,42 +12491,68 @@ static void process_entry_function(struct hlsl_ctx *ctx,
|
|
else
|
|
prepend_uniform_copy(ctx, body, var);
|
|
}
|
|
- else if (hlsl_type_is_patch_array(var->data_type))
|
|
+ else if (hlsl_type_is_primitive_array(var->data_type))
|
|
{
|
|
- if (var->data_type->e.array.array_type == HLSL_ARRAY_PATCH_INPUT)
|
|
+ if (var->storage_modifiers & HLSL_STORAGE_OUT)
|
|
+ hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER,
|
|
+ "Input primitive parameter \"%s\" is declared as \"out\".", var->name);
|
|
+
|
|
+ if (profile->type != VKD3D_SHADER_TYPE_GEOMETRY)
|
|
{
|
|
- if (input_patch)
|
|
+ enum hlsl_array_type array_type = var->data_type->e.array.array_type;
|
|
+
|
|
+ if (array_type == HLSL_ARRAY_PATCH_INPUT)
|
|
{
|
|
- hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_DUPLICATE_PATCH,
|
|
- "Found multiple InputPatch parameters.");
|
|
- hlsl_note(ctx, &input_patch->loc, VKD3D_SHADER_LOG_ERROR,
|
|
- "The InputPatch parameter was previously declared here.");
|
|
- continue;
|
|
+ if (input_patch)
|
|
+ {
|
|
+ hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_DUPLICATE_PATCH,
|
|
+ "Found multiple InputPatch parameters.");
|
|
+ hlsl_note(ctx, &input_patch->loc, VKD3D_SHADER_LOG_ERROR,
|
|
+ "The InputPatch parameter was previously declared here.");
|
|
+ continue;
|
|
+ }
|
|
+ input_patch = var;
|
|
}
|
|
- input_patch = var;
|
|
- }
|
|
- else
|
|
- {
|
|
- if (output_patch)
|
|
+ else if (array_type == HLSL_ARRAY_PATCH_OUTPUT)
|
|
{
|
|
- hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_DUPLICATE_PATCH,
|
|
- "Found multiple OutputPatch parameters.");
|
|
- hlsl_note(ctx, &output_patch->loc, VKD3D_SHADER_LOG_ERROR,
|
|
- "The OutputPatch parameter was previously declared here.");
|
|
- continue;
|
|
+ if (output_patch)
|
|
+ {
|
|
+ hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_DUPLICATE_PATCH,
|
|
+ "Found multiple OutputPatch parameters.");
|
|
+ hlsl_note(ctx, &output_patch->loc, VKD3D_SHADER_LOG_ERROR,
|
|
+ "The OutputPatch parameter was previously declared here.");
|
|
+ continue;
|
|
+ }
|
|
+ output_patch = var;
|
|
}
|
|
- output_patch = var;
|
|
}
|
|
|
|
- validate_and_record_patch_type(ctx, var);
|
|
+ validate_and_record_prim_type(ctx, var);
|
|
if (profile->type == VKD3D_SHADER_TYPE_GEOMETRY)
|
|
{
|
|
- hlsl_fixme(ctx, &var->loc, "InputPatch/OutputPatch parameters in geometry shaders.");
|
|
+ hlsl_fixme(ctx, &var->loc, "Input primitive parameters in geometry shaders.");
|
|
continue;
|
|
}
|
|
|
|
prepend_input_var_copy(ctx, entry_func, var);
|
|
}
|
|
+ else if (hlsl_get_stream_output_type(var->data_type))
|
|
+ {
|
|
+ if (profile->type != VKD3D_SHADER_TYPE_GEOMETRY)
|
|
+ {
|
|
+ hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE,
|
|
+ "Stream output parameters can only be used in geometry shaders.");
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ if (!(var->storage_modifiers & HLSL_STORAGE_IN) || !(var->storage_modifiers & HLSL_STORAGE_OUT))
|
|
+ hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER,
|
|
+ "Stream output parameter \"%s\" must be declared as \"inout\".", var->name);
|
|
+
|
|
+ /* TODO: check that maxvertexcount * component_count(element_type) <= 1024. */
|
|
+
|
|
+ continue;
|
|
+ }
|
|
else
|
|
{
|
|
if (hlsl_get_multiarray_element_type(var->data_type)->class != HLSL_CLASS_STRUCT
|
|
@@ -12107,12 +12564,24 @@ static void process_entry_function(struct hlsl_ctx *ctx,
|
|
}
|
|
|
|
if (var->storage_modifiers & HLSL_STORAGE_IN)
|
|
+ {
|
|
+ if (profile->type == VKD3D_SHADER_TYPE_GEOMETRY)
|
|
+ {
|
|
+ hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_PRIMITIVE_TYPE,
|
|
+ "Input parameter \"%s\" is missing a primitive type.", var->name);
|
|
+ continue;
|
|
+ }
|
|
+
|
|
prepend_input_var_copy(ctx, entry_func, var);
|
|
+ }
|
|
if (var->storage_modifiers & HLSL_STORAGE_OUT)
|
|
{
|
|
if (profile->type == VKD3D_SHADER_TYPE_HULL && !ctx->is_patch_constant_func)
|
|
hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER,
|
|
"Output parameters are not supported in hull shader control point functions.");
|
|
+ else if (profile->type == VKD3D_SHADER_TYPE_GEOMETRY)
|
|
+ hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER,
|
|
+ "Output parameters are not allowed in geometry shaders.");
|
|
else
|
|
append_output_var_copy(ctx, entry_func, var);
|
|
}
|
|
@@ -12120,7 +12589,11 @@ static void process_entry_function(struct hlsl_ctx *ctx,
|
|
}
|
|
if (entry_func->return_var)
|
|
{
|
|
- if (entry_func->return_var->data_type->class != HLSL_CLASS_STRUCT && !entry_func->return_var->semantic.name)
|
|
+ if (profile->type == VKD3D_SHADER_TYPE_GEOMETRY)
|
|
+ hlsl_error(ctx, &entry_func->loc, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE,
|
|
+ "Geometry shaders cannot return values.");
|
|
+ else if (entry_func->return_var->data_type->class != HLSL_CLASS_STRUCT
|
|
+ && !entry_func->return_var->semantic.name)
|
|
hlsl_error(ctx, &entry_func->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_SEMANTIC,
|
|
"Entry point \"%s\" is missing a return value semantic.", entry_func->func->name);
|
|
|
|
@@ -12135,6 +12608,10 @@ static void process_entry_function(struct hlsl_ctx *ctx,
|
|
hlsl_fixme(ctx, &entry_func->loc, "Passthrough hull shader control point function.");
|
|
}
|
|
|
|
+ if (profile->type == VKD3D_SHADER_TYPE_GEOMETRY && ctx->input_primitive_type == VKD3D_PT_UNDEFINED)
|
|
+ hlsl_error(ctx, &entry_func->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_PRIMITIVE_TYPE,
|
|
+ "Entry point \"%s\" is missing an input primitive parameter.", entry_func->func->name);
|
|
+
|
|
if (hlsl_version_ge(ctx, 4, 0))
|
|
{
|
|
hlsl_transform_ir(ctx, lower_discard_neg, body, NULL);
|
|
@@ -12188,6 +12665,7 @@ static void process_entry_function(struct hlsl_ctx *ctx,
|
|
lower_ir(ctx, lower_casts_to_bool, body);
|
|
|
|
lower_ir(ctx, lower_casts_to_int, body);
|
|
+ lower_ir(ctx, lower_trunc, body);
|
|
lower_ir(ctx, lower_sqrt, body);
|
|
lower_ir(ctx, lower_dot, body);
|
|
lower_ir(ctx, lower_round, body);
|
|
@@ -12217,7 +12695,7 @@ static void process_entry_function(struct hlsl_ctx *ctx,
|
|
|
|
/* TODO: move forward, remove when no longer needed */
|
|
transform_derefs(ctx, replace_deref_path_with_offset, body);
|
|
- while (hlsl_transform_ir(ctx, hlsl_fold_constant_exprs, body, NULL));
|
|
+ simplify_exprs(ctx, body);
|
|
transform_derefs(ctx, clean_constant_deref_offset_srcs, body);
|
|
|
|
do
|
|
@@ -12253,6 +12731,9 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry
|
|
else if (profile->type == VKD3D_SHADER_TYPE_DOMAIN && ctx->domain == VKD3D_TESSELLATOR_DOMAIN_INVALID)
|
|
hlsl_error(ctx, &entry_func->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_ATTRIBUTE,
|
|
"Entry point \"%s\" is missing a [domain] attribute.", entry_func->func->name);
|
|
+ else if (profile->type == VKD3D_SHADER_TYPE_GEOMETRY && !ctx->max_vertex_count)
|
|
+ hlsl_error(ctx, &entry_func->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_ATTRIBUTE,
|
|
+ "Entry point \"%s\" is missing a [maxvertexcount] attribute.", entry_func->func->name);
|
|
|
|
hlsl_block_init(&global_uniform_block);
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c
|
|
index f4715a9224c..f74ecffcd4b 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c
|
|
@@ -1712,7 +1712,8 @@ bool hlsl_normalize_binary_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst
|
|
progress = true;
|
|
}
|
|
|
|
- if (!progress && e1 && (tmp = collect_exprs(ctx, &block, instr, op, e1->operands[1].node, arg2)))
|
|
+ if (!progress && e1 && e1->op == op
|
|
+ && (tmp = collect_exprs(ctx, &block, instr, op, e1->operands[1].node, arg2)))
|
|
{
|
|
/* (y OPR (x OPL a)) OPR (x OPL b) -> y OPR (x OPL (a OPR b)) */
|
|
arg1 = e1->operands[0].node;
|
|
@@ -1720,7 +1721,7 @@ bool hlsl_normalize_binary_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst
|
|
progress = true;
|
|
}
|
|
|
|
- if (!progress && is_op_commutative(op) && e1
|
|
+ if (!progress && is_op_commutative(op) && e1 && e1->op == op
|
|
&& (tmp = collect_exprs(ctx, &block, instr, op, e1->operands[0].node, arg2)))
|
|
{
|
|
/* ((x OPL a) OPR y) OPR (x OPL b) -> (x OPL (a OPR b)) OPR y */
|
|
@@ -1729,7 +1730,8 @@ bool hlsl_normalize_binary_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst
|
|
progress = true;
|
|
}
|
|
|
|
- if (!progress && e2 && (tmp = collect_exprs(ctx, &block, instr, op, arg1, e2->operands[0].node)))
|
|
+ if (!progress && e2 && e2->op == op
|
|
+ && (tmp = collect_exprs(ctx, &block, instr, op, arg1, e2->operands[0].node)))
|
|
{
|
|
/* (x OPL a) OPR ((x OPL b) OPR y) -> (x OPL (a OPR b)) OPR y */
|
|
arg1 = tmp;
|
|
@@ -1737,7 +1739,7 @@ bool hlsl_normalize_binary_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst
|
|
progress = true;
|
|
}
|
|
|
|
- if (!progress && is_op_commutative(op) && e2
|
|
+ if (!progress && is_op_commutative(op) && e2 && e2->op == op
|
|
&& (tmp = collect_exprs(ctx, &block, instr, op, arg1, e2->operands[1].node)))
|
|
{
|
|
/* (x OPL a) OPR (y OPR (x OPL b)) -> (x OPL (a OPR b)) OPR y */
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c
|
|
index 267f0884d83..f4525009f77 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/tpf.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c
|
|
@@ -3462,12 +3462,16 @@ static void sm4_write_register_index(const struct tpf_compiler *tpf, const struc
|
|
unsigned int j)
|
|
{
|
|
unsigned int addressing = sm4_get_index_addressing_from_reg(reg, j);
|
|
+ const struct vkd3d_shader_register_index *idx = ®->idx[j];
|
|
struct vkd3d_bytecode_buffer *buffer = tpf->buffer;
|
|
unsigned int k;
|
|
|
|
+ if (!addressing || (addressing & VKD3D_SM4_ADDRESSING_OFFSET))
|
|
+ put_u32(buffer, idx->offset);
|
|
+
|
|
if (addressing & VKD3D_SM4_ADDRESSING_RELATIVE)
|
|
{
|
|
- const struct vkd3d_shader_src_param *idx_src = reg->idx[j].rel_addr;
|
|
+ const struct vkd3d_shader_src_param *idx_src = idx->rel_addr;
|
|
uint32_t idx_src_token;
|
|
|
|
VKD3D_ASSERT(idx_src);
|
|
@@ -3482,10 +3486,6 @@ static void sm4_write_register_index(const struct tpf_compiler *tpf, const struc
|
|
VKD3D_ASSERT(!idx_src->reg.idx[k].rel_addr);
|
|
}
|
|
}
|
|
- else
|
|
- {
|
|
- put_u32(tpf->buffer, reg->idx[j].offset);
|
|
- }
|
|
}
|
|
|
|
static void sm4_write_dst_register(const struct tpf_compiler *tpf, const struct vkd3d_shader_dst_param *dst)
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
|
|
index eb50da28d24..8329bf169b0 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
|
|
@@ -169,6 +169,9 @@ enum vkd3d_shader_error
|
|
VKD3D_SHADER_ERROR_HLSL_MISPLACED_SAMPLER_STATE = 5039,
|
|
VKD3D_SHADER_ERROR_HLSL_AMBIGUOUS_CALL = 5040,
|
|
VKD3D_SHADER_ERROR_HLSL_DUPLICATE_PATCH = 5041,
|
|
+ VKD3D_SHADER_ERROR_HLSL_INVALID_MAX_VERTEX_COUNT = 5042,
|
|
+ VKD3D_SHADER_ERROR_HLSL_MISSING_PRIMITIVE_TYPE = 5043,
|
|
+ VKD3D_SHADER_ERROR_HLSL_MISPLACED_STREAM_OUTPUT = 5044,
|
|
|
|
VKD3D_SHADER_WARNING_HLSL_IMPLICIT_TRUNCATION = 5300,
|
|
VKD3D_SHADER_WARNING_HLSL_DIVISION_BY_ZERO = 5301,
|
|
--
|
|
2.47.2
|
|
|