Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/ValveSoftware/vkd3d.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrancisco Casas <fcasas@codeweavers.com>2022-03-08 19:13:15 +0300
committerGiovanni Mascellani <gmascellani@codeweavers.com>2022-07-27 11:50:36 +0300
commit061858ee83c486527d1c68bcfbe02e2a9487f376 (patch)
tree1ef8380a55cb079a95234e467fbf9bcd7ca945a7
parentd42a016fe7d782b59d89fb503c060426deb4eee2 (diff)
vkd3d-shader/hlsl: Lower complex broadcasts.experimental-vkd3d-20220728proton_7.0experimental_7.0
-rw-r--r--libs/vkd3d-shader/hlsl.h3
-rw-r--r--libs/vkd3d-shader/hlsl.y6
-rw-r--r--libs/vkd3d-shader/hlsl_codegen.c69
-rw-r--r--tests/cast-broadcast.shader_test4
4 files changed, 65 insertions, 17 deletions
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h
index 3680a8c7..30db2c69 100644
--- a/libs/vkd3d-shader/hlsl.h
+++ b/libs/vkd3d-shader/hlsl.h
@@ -891,4 +891,7 @@ int hlsl_sm4_write(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_fun
int hlsl_lexer_compile(struct hlsl_ctx *ctx, const struct vkd3d_shader_code *hlsl);
+void hlsl_initialize_var_components(struct hlsl_ctx *ctx, struct list *instrs,
+ struct hlsl_ir_var *dst, unsigned int *store_index, struct hlsl_ir_node *src);
+
#endif
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y
index d73f5f27..a0d89a7d 100644
--- a/libs/vkd3d-shader/hlsl.y
+++ b/libs/vkd3d-shader/hlsl.y
@@ -1866,7 +1866,7 @@ static bool add_increment(struct hlsl_ctx *ctx, struct list *instrs, bool decrem
return true;
}
-static void initialize_var_components(struct hlsl_ctx *ctx, struct list *instrs,
+void hlsl_initialize_var_components(struct hlsl_ctx *ctx, struct list *instrs,
struct hlsl_ir_var *dst, unsigned int *store_index, struct hlsl_ir_node *src)
{
unsigned int src_comp_count = hlsl_type_component_count(src->data_type);
@@ -2032,7 +2032,7 @@ static struct list *declare_vars(struct hlsl_ctx *ctx, struct hlsl_type *basic_t
for (k = 0; k < v->initializer.args_count; ++k)
{
- initialize_var_components(ctx, v->initializer.instrs, var,
+ hlsl_initialize_var_components(ctx, v->initializer.instrs, var,
&store_index, v->initializer.args[k]);
}
}
@@ -2745,7 +2745,7 @@ static struct list *add_constructor(struct hlsl_ctx *ctx, struct hlsl_type *type
continue;
}
- initialize_var_components(ctx, params->instrs, var, &idx, arg);
+ hlsl_initialize_var_components(ctx, params->instrs, var, &idx, arg);
}
if (!(load = hlsl_new_var_load(ctx, var, loc)))
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c
index 15828d01..12760eaf 100644
--- a/libs/vkd3d-shader/hlsl_codegen.c
+++ b/libs/vkd3d-shader/hlsl_codegen.c
@@ -604,6 +604,62 @@ static bool lower_broadcasts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, v
return false;
}
+/* Lower broadcasts casts from vec1 to struct and array types. */
+static bool lower_complex_broadcasts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context)
+{
+ struct hlsl_type *src_type, *dst_type;
+ struct hlsl_ir_expr *cast;
+ struct hlsl_ir_node *src;
+
+ if (instr->type != HLSL_IR_EXPR)
+ return false;
+ cast = hlsl_ir_expr(instr);
+ if (cast->op != HLSL_OP1_CAST)
+ return false;
+ src = cast->operands[0].node;
+ src_type = src->data_type;
+ dst_type = cast->node.data_type;
+
+ if (src_type->type > HLSL_CLASS_VECTOR || src_type->dimx != 1)
+ return false;
+
+ if (HLSL_CLASS_VECTOR < dst_type->type && dst_type->type < HLSL_CLASS_OBJECT)
+ {
+ unsigned int size = hlsl_type_component_count(dst_type);
+ struct vkd3d_string_buffer *string;
+ static unsigned int counter = 0;
+ struct list *broadcast_instrs;
+ unsigned int store_index = 0;
+ struct hlsl_ir_load *load;
+ struct hlsl_ir_var *var;
+
+ if (!(string = hlsl_get_string_buffer(ctx)))
+ return false;
+ vkd3d_string_buffer_printf(string, "<broadcast-%x>", counter++);
+ if (!(var = hlsl_new_synthetic_var(ctx, string->buffer, dst_type, instr->loc)))
+ return false;
+ hlsl_release_string_buffer(ctx, string);
+
+ if (!(broadcast_instrs = hlsl_alloc(ctx, sizeof(*broadcast_instrs))))
+ return false;
+ list_init(broadcast_instrs);
+
+ while (store_index < size)
+ hlsl_initialize_var_components(ctx, broadcast_instrs, var, &store_index, src);
+
+ list_move_before(&cast->node.entry, broadcast_instrs);
+ vkd3d_free(broadcast_instrs);
+
+ load = hlsl_new_var_load(ctx, var, var->loc);
+ list_add_before(&cast->node.entry, &load->node.entry);
+ hlsl_replace_node(&cast->node, &load->node);
+
+ return true;
+ }
+
+ return false;
+}
+
enum copy_propagation_value_state
{
VALUE_STATE_NOT_WRITTEN = 0,
@@ -1217,12 +1273,6 @@ static bool split_array_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr,
element_type = type->e.array.type;
element_size = hlsl_type_get_array_element_reg_size(element_type);
- if (rhs->type != HLSL_IR_LOAD)
- {
- hlsl_fixme(ctx, &instr->loc, "Array store rhs is not HLSL_IR_LOAD. Broadcast may be missing.");
- return false;
- }
-
for (i = 0; i < type->e.array.elements_count; ++i)
{
if (!split_copy(ctx, store, hlsl_ir_load(rhs), i * element_size, element_type))
@@ -1253,12 +1303,6 @@ static bool split_struct_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr
if (type->type != HLSL_CLASS_STRUCT)
return false;
- if (rhs->type != HLSL_IR_LOAD)
- {
- hlsl_fixme(ctx, &instr->loc, "Struct store rhs is not HLSL_IR_LOAD. Broadcast may be missing.");
- return false;
- }
-
for (i = 0; i < type->e.record.field_count; ++i)
{
const struct hlsl_struct_field *field = &type->e.record.fields[i];
@@ -2973,6 +3017,7 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry
"Entry point \"%s\" is missing a [numthreads] attribute.", entry_func->func->name);
transform_ir(ctx, lower_broadcasts, body, NULL);
+ transform_ir(ctx, lower_complex_broadcasts, body, NULL);
while (transform_ir(ctx, fold_redundant_casts, body, NULL));
do
{
diff --git a/tests/cast-broadcast.shader_test b/tests/cast-broadcast.shader_test
index 02d14c0b..8b1948f5 100644
--- a/tests/cast-broadcast.shader_test
+++ b/tests/cast-broadcast.shader_test
@@ -20,5 +20,5 @@ float4 main() : SV_TARGET
}
[test]
-todo draw quad
-todo probe all rgba (84.0, 84.0, 84.0, 84.0)
+draw quad
+probe all rgba (84.0, 84.0, 84.0, 84.0)