diff options
author | Francisco Casas <fcasas@codeweavers.com> | 2022-03-08 19:13:15 +0300 |
---|---|---|
committer | Giovanni Mascellani <gmascellani@codeweavers.com> | 2022-07-27 11:50:36 +0300 |
commit | 061858ee83c486527d1c68bcfbe02e2a9487f376 (patch) | |
tree | 1ef8380a55cb079a95234e467fbf9bcd7ca945a7 | |
parent | d42a016fe7d782b59d89fb503c060426deb4eee2 (diff) |
vkd3d-shader/hlsl: Lower complex broadcasts.experimental-vkd3d-20220728proton_7.0experimental_7.0
-rw-r--r-- | libs/vkd3d-shader/hlsl.h | 3 | ||||
-rw-r--r-- | libs/vkd3d-shader/hlsl.y | 6 | ||||
-rw-r--r-- | libs/vkd3d-shader/hlsl_codegen.c | 69 | ||||
-rw-r--r-- | tests/cast-broadcast.shader_test | 4 |
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) |