Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com Signed-off-by: Francisco Casas fcasas@codeweavers.com --- v2: * Use the new single component syntax --- Makefile.am | 1 + tests/matrix-semantics.shader_test | 71 ++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 tests/matrix-semantics.shader_test
diff --git a/Makefile.am b/Makefile.am index dd3ce1ff..74c23b2b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -108,6 +108,7 @@ vkd3d_shader_tests = \ tests/hlsl-vector-indexing-uniform.shader_test \ tests/logic-operations.shader_test \ tests/math.shader_test \ + tests/matrix-semantics.shader_test \ tests/nointerpolation.shader_test \ tests/pow.shader_test \ tests/preproc-if.shader_test \ diff --git a/tests/matrix-semantics.shader_test b/tests/matrix-semantics.shader_test new file mode 100644 index 00000000..6a089683 --- /dev/null +++ b/tests/matrix-semantics.shader_test @@ -0,0 +1,71 @@ +[pixel shader] +float4x1 main() : sv_target +{ + return float4(1.0, 2.0, 3.0, 4.0); +} + +[test] +todo draw quad +probe all rgba (1.0, 2.0, 3.0, 4.0) + +[pixel shader] +row_major float1x4 main() : sv_target +{ + return float4(1.0, 2.0, 3.0, 4.0); +} + +[test] +todo draw quad +probe all rgba (1.0, 2.0, 3.0, 4.0) + +[require] +shader model >= 4.0 + +[pixel shader] +row_major float4x1 main() : sv_target +{ + return float4(1.0, 2.0, 3.0, 4.0); +} + +[test] +todo draw quad +probe all r (1.0) + +[pixel shader] +float1x4 main() : sv_target +{ + return float4(1.0, 2.0, 3.0, 4.0); +} + +[test] +todo draw quad +probe all r (1.0) + +[pixel shader] +void main(out row_major float1x4 x : sv_target0, out float1x4 y : sv_target1) +{ + x = float4(1.0, 2.0, 3.0, 4.0); + y = float4(5.0, 6.0, 7.0, 8.0); +} + +[test] +todo draw quad +probe all rgba (1.0, 2.0, 3.0, 4.0) + +[pixel shader fail todo] +void main(out float1x4 x : sv_target0, out float1x4 y : sv_target1) +{ + x = float4(1.0, 2.0, 3.0, 4.0); + y = float4(5.0, 6.0, 7.0, 8.0); +} + +[pixel shader] +void main(out float1x4 x : sv_target0, out float1x4 y : sv_target4) +{ + x = float4(1.0, 2.0, 3.0, 4.0); + y = float4(5.0, 6.0, 7.0, 8.0); +} + +[test] +todo draw quad +probe all r (1.0)
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com Signed-off-by: Francisco Casas fcasas@codeweavers.com --- If this is reverted on top of "Lower numeric casts", then the shader runner crashes with:
shader_runner: ../vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h:1165: vkd3d_write_mask_component_count: Assertion `1 <= count && count <= VKD3D_VEC4_SIZE' failed.
While the HLSL copiler is expected to output correct programs, the DXBC parser should not crash on malformed inputs anyway, so there is a bug to be fixed there too.
v2: * Use hlsl_type_component_count() --- libs/vkd3d-shader/hlsl_codegen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 78b22910..e38660af 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -1348,7 +1348,7 @@ static void allocate_variable_temp_register(struct hlsl_ctx *ctx, struct hlsl_ir var->last_read, var->data_type->reg_size); else var->reg = allocate_register(ctx, liveness, var->first_write, - var->last_read, var->data_type->dimx); + var->last_read, hlsl_type_component_count(var->data_type)); TRACE("Allocated %s to %s (liveness %u-%u).\n", var->name, debug_register('r', var->reg, var->data_type), var->first_write, var->last_read); }
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com --- There is another call to hlsl_new_cast() in hlsl.y that I didn't redirect to add_cast(), because it doesn't require the upcoming matrix conversion patch. I don't know if you want it to be redirected too. --- libs/vkd3d-shader/hlsl.y | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index faac562a..ac22c51d 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -266,7 +266,7 @@ static bool implicit_compatible_data_types(struct hlsl_type *t1, struct hlsl_typ return false; }
-static struct hlsl_ir_node *add_implicit_conversion(struct hlsl_ctx *ctx, struct list *instrs, +static struct hlsl_ir_node *add_cast(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *node, struct hlsl_type *dst_type, const struct vkd3d_shader_location *loc) { struct hlsl_type *src_type = node->data_type; @@ -275,6 +275,17 @@ static struct hlsl_ir_node *add_implicit_conversion(struct hlsl_ctx *ctx, struct if (hlsl_types_are_equal(src_type, dst_type)) return node;
+ if (!(cast = hlsl_new_cast(ctx, node, dst_type, loc))) + return NULL; + list_add_tail(instrs, &cast->node.entry); + return &cast->node; +} + +static struct hlsl_ir_node *add_implicit_conversion(struct hlsl_ctx *ctx, struct list *instrs, + struct hlsl_ir_node *node, struct hlsl_type *dst_type, const struct vkd3d_shader_location *loc) +{ + struct hlsl_type *src_type = node->data_type; + if (!implicit_compatible_data_types(src_type, dst_type)) { struct vkd3d_string_buffer *src_string, *dst_string; @@ -289,14 +300,7 @@ static struct hlsl_ir_node *add_implicit_conversion(struct hlsl_ctx *ctx, struct return NULL; }
- if (dst_type->dimx * dst_type->dimy < src_type->dimx * src_type->dimy) - hlsl_warning(ctx, loc, VKD3D_SHADER_WARNING_HLSL_IMPLICIT_TRUNCATION, "Implicit truncation of %s type.", - src_type->type == HLSL_CLASS_VECTOR ? "vector" : "matrix"); - - if (!(cast = hlsl_new_cast(ctx, node, dst_type, loc))) - return NULL; - list_add_tail(instrs, &cast->node.entry); - return &cast->node; + return add_cast(ctx, instrs, node, dst_type, loc); }
static DWORD add_modifiers(struct hlsl_ctx *ctx, DWORD modifiers, DWORD mod, const struct vkd3d_shader_location loc) @@ -3718,7 +3722,6 @@ unary_expr: { struct hlsl_type *src_type = node_from_list($6)->data_type; struct hlsl_type *dst_type; - struct hlsl_ir_expr *cast; unsigned int i;
if ($2) @@ -3746,12 +3749,11 @@ unary_expr: YYABORT; }
- if (!(cast = hlsl_new_cast(ctx, node_from_list($6), dst_type, &@3))) + if (!add_cast(ctx, $6, node_from_list($6), dst_type, &@3)) { hlsl_free_instr_list($6); YYABORT; } - list_add_tail($6, &cast->node.entry); $$ = $6; }
On 6/1/22 05:46, Giovanni Mascellani wrote:
@@ -289,14 +300,7 @@ static struct hlsl_ir_node *add_implicit_conversion(struct hlsl_ctx *ctx, struct return NULL; }
- if (dst_type->dimx * dst_type->dimy < src_type->dimx * src_type->dimy)
hlsl_warning(ctx, loc, VKD3D_SHADER_WARNING_HLSL_IMPLICIT_TRUNCATION, "Implicit truncation of %s type.",
src_type->type == HLSL_CLASS_VECTOR ? "vector" : "matrix");
This seems to have been accidentally deleted.
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com --- I had to add a forward declaration for add_load(). I don't know if in cases like that it is preferred to add a forward declaration (which adds cruft) or move the definition backwards (which break the vague logical order functions have). --- libs/vkd3d-shader/hlsl.y | 93 ++++++++++++++++++- tests/hlsl-duplicate-modifiers.shader_test | 2 +- tests/hlsl-initializer-matrix.shader_test | 2 +- ...lsl-return-implicit-conversion.shader_test | 10 +- tests/hlsl-shape.shader_test | 10 +- tests/matrix-semantics.shader_test | 20 ++-- 6 files changed, 111 insertions(+), 26 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index ac22c51d..b61d2d84 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -266,6 +266,9 @@ static bool implicit_compatible_data_types(struct hlsl_type *t1, struct hlsl_typ return false; }
+static struct hlsl_ir_load *add_load(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *var_node, + struct hlsl_ir_node *offset, struct hlsl_type *data_type, const struct vkd3d_shader_location loc); + static struct hlsl_ir_node *add_cast(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *node, struct hlsl_type *dst_type, const struct vkd3d_shader_location *loc) { @@ -275,10 +278,92 @@ static struct hlsl_ir_node *add_cast(struct hlsl_ctx *ctx, struct list *instrs, if (hlsl_types_are_equal(src_type, dst_type)) return node;
- if (!(cast = hlsl_new_cast(ctx, node, dst_type, loc))) - return NULL; - list_add_tail(instrs, &cast->node.entry); - return &cast->node; + if ((src_type->type == HLSL_CLASS_MATRIX || dst_type->type == HLSL_CLASS_MATRIX) + && src_type->type <= HLSL_CLASS_LAST_NUMERIC && dst_type->type <= HLSL_CLASS_LAST_NUMERIC) + { + struct vkd3d_string_buffer *name; + static unsigned int counter = 0; + struct hlsl_ir_load *load; + struct hlsl_ir_var *var; + unsigned int dst_idx; + bool broadcast; + + broadcast = src_type->dimx == 1 && src_type->dimy == 1; + assert(dst_type->dimx * dst_type->dimy <= src_type->dimx * src_type->dimy || broadcast); + if (src_type->type == HLSL_CLASS_MATRIX && dst_type->type == HLSL_CLASS_MATRIX && !broadcast) + { + assert(dst_type->dimx <= src_type->dimx); + assert(dst_type->dimy <= src_type->dimy); + } + + name = vkd3d_string_buffer_get(&ctx->string_buffers); + vkd3d_string_buffer_printf(name, "<cast-%u>", counter++); + var = hlsl_new_synthetic_var(ctx, name->buffer, dst_type, *loc); + vkd3d_string_buffer_release(&ctx->string_buffers, name); + if (!var) + return NULL; + + for (dst_idx = 0; dst_idx < dst_type->dimx * dst_type->dimy; ++dst_idx) + { + struct hlsl_type *src_scalar_type, *dst_scalar_type; + unsigned int src_idx, src_offset, dst_offset; + struct hlsl_ir_store *store; + struct hlsl_ir_constant *c; + + if (broadcast) + { + src_idx = 0; + } + else + { + if (src_type->type == HLSL_CLASS_MATRIX && dst_type->type == HLSL_CLASS_MATRIX) + { + unsigned int x = dst_idx % dst_type->dimx, y = dst_idx / dst_type->dimx; + + src_idx = y * src_type->dimx + x; + } + else + { + src_idx = dst_idx; + } + } + + dst_offset = hlsl_compute_component_offset(ctx, dst_type, dst_idx, &dst_scalar_type); + src_offset = hlsl_compute_component_offset(ctx, src_type, src_idx, &src_scalar_type); + + if (!(c = hlsl_new_uint_constant(ctx, src_offset, loc))) + return NULL; + list_add_tail(instrs, &c->node.entry); + + if (!(load = add_load(ctx, instrs, node, &c->node, src_scalar_type, *loc))) + return NULL; + + if (!(cast = hlsl_new_cast(ctx, &load->node, dst_scalar_type, loc))) + return NULL; + list_add_tail(instrs, &cast->node.entry); + + if (!(c = hlsl_new_uint_constant(ctx, dst_offset, loc))) + return NULL; + list_add_tail(instrs, &c->node.entry); + + if (!(store = hlsl_new_store(ctx, var, &c->node, &cast->node, 0, *loc))) + return NULL; + list_add_tail(instrs, &store->node.entry); + } + + if (!(load = hlsl_new_load(ctx, var, NULL, dst_type, *loc))) + return NULL; + list_add_tail(instrs, &load->node.entry); + + return &load->node; + } + else + { + if (!(cast = hlsl_new_cast(ctx, node, dst_type, loc))) + return NULL; + list_add_tail(instrs, &cast->node.entry); + return &cast->node; + } }
static struct hlsl_ir_node *add_implicit_conversion(struct hlsl_ctx *ctx, struct list *instrs, diff --git a/tests/hlsl-duplicate-modifiers.shader_test b/tests/hlsl-duplicate-modifiers.shader_test index fcae12da..6491701a 100644 --- a/tests/hlsl-duplicate-modifiers.shader_test +++ b/tests/hlsl-duplicate-modifiers.shader_test @@ -7,5 +7,5 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (0.1, 0.2, 0.3, 0.4) diff --git a/tests/hlsl-initializer-matrix.shader_test b/tests/hlsl-initializer-matrix.shader_test index ea9de9c0..7e12b0a0 100644 --- a/tests/hlsl-initializer-matrix.shader_test +++ b/tests/hlsl-initializer-matrix.shader_test @@ -55,7 +55,7 @@ float4 main() : SV_TARGET }
[test] -todo draw quad +draw quad probe all rgba (21, 22, 31, 32)
diff --git a/tests/hlsl-return-implicit-conversion.shader_test b/tests/hlsl-return-implicit-conversion.shader_test index bf99d9cb..4fe8e7eb 100644 --- a/tests/hlsl-return-implicit-conversion.shader_test +++ b/tests/hlsl-return-implicit-conversion.shader_test @@ -5,7 +5,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (0.4, 0.3, 0.2, 0.1)
[pixel shader] @@ -15,7 +15,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (0.4, 0.3, 0.2, 0.1)
[pixel shader] @@ -25,7 +25,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (0.4, 0.3, 0.2, 0.1)
[pixel shader] @@ -35,8 +35,8 @@ float4x1 main() : sv_target }
[test] -todo draw quad -probe all rgba (0.4, 0.3, 0.2, 0.1) +draw quad +todo probe all rgba (0.4, 0.3, 0.2, 0.1)
[pixel shader] float3 func() diff --git a/tests/hlsl-shape.shader_test b/tests/hlsl-shape.shader_test index 57d59534..65cc322c 100644 --- a/tests/hlsl-shape.shader_test +++ b/tests/hlsl-shape.shader_test @@ -211,7 +211,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (2.0, 4.0, 6.0, 8.0)
[pixel shader] @@ -235,7 +235,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (2.0, 4.0, 6.0, 8.0)
[pixel shader] @@ -260,7 +260,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (2.0, 4.0, 6.0, 8.0)
[pixel shader] @@ -309,7 +309,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (2.0, 4.0, 0.0, 0.0)
[pixel shader] @@ -321,7 +321,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (2.0, 4.0, 0.0, 0.0)
[pixel shader] diff --git a/tests/matrix-semantics.shader_test b/tests/matrix-semantics.shader_test index 6a089683..d297b0d9 100644 --- a/tests/matrix-semantics.shader_test +++ b/tests/matrix-semantics.shader_test @@ -5,8 +5,8 @@ float4x1 main() : sv_target }
[test] -todo draw quad -probe all rgba (1.0, 2.0, 3.0, 4.0) +draw quad +todo probe all rgba (1.0, 2.0, 3.0, 4.0)
[pixel shader] row_major float1x4 main() : sv_target @@ -15,7 +15,7 @@ row_major float1x4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (1.0, 2.0, 3.0, 4.0)
[require] @@ -28,8 +28,8 @@ row_major float4x1 main() : sv_target }
[test] -todo draw quad -probe all r (1.0) +draw quad +todo probe all r (1.0)
[pixel shader] float1x4 main() : sv_target @@ -38,8 +38,8 @@ float1x4 main() : sv_target }
[test] -todo draw quad -probe all r (1.0) +draw quad +todo probe all r (1.0)
[pixel shader] void main(out row_major float1x4 x : sv_target0, out float1x4 y : sv_target1) @@ -49,7 +49,7 @@ void main(out row_major float1x4 x : sv_target0, out float1x4 y : sv_target1) }
[test] -todo draw quad +draw quad probe all rgba (1.0, 2.0, 3.0, 4.0)
[pixel shader fail todo] @@ -67,5 +67,5 @@ void main(out float1x4 x : sv_target0, out float1x4 y : sv_target4) }
[test] -todo draw quad -probe all r (1.0) +draw quad +todo probe all r (1.0)
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com --- libs/vkd3d-shader/hlsl.y | 54 +++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 31 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index b61d2d84..d6ea668d 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -670,7 +670,7 @@ static bool add_record_load(struct hlsl_ctx *ctx, struct list *instrs, struct hl return !!add_load(ctx, instrs, record, &c->node, field->type, loc); }
-static struct hlsl_ir_expr *add_binary_arithmetic_expr(struct hlsl_ctx *ctx, struct list *instrs, +static struct hlsl_ir_node *add_binary_arithmetic_expr(struct hlsl_ctx *ctx, struct list *instrs, enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2, const struct vkd3d_shader_location *loc);
@@ -678,8 +678,7 @@ static struct hlsl_ir_node *add_matrix_scalar_load(struct hlsl_ctx *ctx, struct struct hlsl_ir_node *matrix, struct hlsl_ir_node *x, struct hlsl_ir_node *y, const struct vkd3d_shader_location *loc) { - struct hlsl_ir_node *major, *minor; - struct hlsl_ir_expr *mul, *add; + struct hlsl_ir_node *major, *minor, *mul, *add; struct hlsl_ir_constant *four; struct hlsl_ir_load *load; struct hlsl_type *type = matrix->data_type, *scalar_type; @@ -704,10 +703,10 @@ static struct hlsl_ir_node *add_matrix_scalar_load(struct hlsl_ctx *ctx, struct if (!(mul = add_binary_arithmetic_expr(ctx, instrs, HLSL_OP2_MUL, &four->node, major, loc))) return NULL;
- if (!(add = add_binary_arithmetic_expr(ctx, instrs, HLSL_OP2_ADD, &mul->node, minor, loc))) + if (!(add = add_binary_arithmetic_expr(ctx, instrs, HLSL_OP2_ADD, mul, minor, loc))) return NULL;
- if (!(load = add_load(ctx, instrs, matrix, &add->node, scalar_type, *loc))) + if (!(load = add_load(ctx, instrs, matrix, add, scalar_type, *loc))) return NULL;
return &load->node; @@ -1198,7 +1197,7 @@ static bool expr_common_shape(struct hlsl_ctx *ctx, struct hlsl_type *t1, struct return true; }
-static struct hlsl_ir_expr *add_expr(struct hlsl_ctx *ctx, struct list *instrs, +static struct hlsl_ir_node *add_expr(struct hlsl_ctx *ctx, struct list *instrs, enum hlsl_ir_expr_op op, struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS], struct hlsl_type *type, const struct vkd3d_shader_location *loc) { @@ -1213,7 +1212,7 @@ static struct hlsl_ir_expr *add_expr(struct hlsl_ctx *ctx, struct list *instrs, hlsl_src_from_node(&expr->operands[i], operands[i]); list_add_tail(instrs, &expr->node.entry);
- return expr; + return &expr->node; }
static void check_integer_type(struct hlsl_ctx *ctx, const struct hlsl_ir_node *instr) @@ -1237,7 +1236,7 @@ static void check_integer_type(struct hlsl_ctx *ctx, const struct hlsl_ir_node * } }
-static struct hlsl_ir_expr *add_unary_arithmetic_expr(struct hlsl_ctx *ctx, struct list *instrs, +static struct hlsl_ir_node *add_unary_arithmetic_expr(struct hlsl_ctx *ctx, struct list *instrs, enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg, const struct vkd3d_shader_location *loc) { struct hlsl_ir_node *args[HLSL_MAX_OPERANDS] = {arg}; @@ -1245,7 +1244,7 @@ static struct hlsl_ir_expr *add_unary_arithmetic_expr(struct hlsl_ctx *ctx, stru return add_expr(ctx, instrs, op, args, arg->data_type, loc); }
-static struct hlsl_ir_expr *add_unary_bitwise_expr(struct hlsl_ctx *ctx, struct list *instrs, +static struct hlsl_ir_node *add_unary_bitwise_expr(struct hlsl_ctx *ctx, struct list *instrs, enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg, const struct vkd3d_shader_location *loc) { check_integer_type(ctx, arg); @@ -1253,7 +1252,7 @@ static struct hlsl_ir_expr *add_unary_bitwise_expr(struct hlsl_ctx *ctx, struct return add_unary_arithmetic_expr(ctx, instrs, op, arg, loc); }
-static struct hlsl_ir_expr *add_unary_logical_expr(struct hlsl_ctx *ctx, struct list *instrs, +static struct hlsl_ir_node *add_unary_logical_expr(struct hlsl_ctx *ctx, struct list *instrs, enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg, const struct vkd3d_shader_location *loc) { struct hlsl_ir_node *args[HLSL_MAX_OPERANDS] = {0}; @@ -1268,7 +1267,7 @@ static struct hlsl_ir_expr *add_unary_logical_expr(struct hlsl_ctx *ctx, struct return add_expr(ctx, instrs, op, args, bool_type, loc); }
-static struct hlsl_ir_expr *add_binary_arithmetic_expr(struct hlsl_ctx *ctx, struct list *instrs, +static struct hlsl_ir_node *add_binary_arithmetic_expr(struct hlsl_ctx *ctx, struct list *instrs, enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2, const struct vkd3d_shader_location *loc) { @@ -1303,7 +1302,7 @@ static struct list *add_binary_arithmetic_expr_merge(struct hlsl_ctx *ctx, struc return list1; }
-static struct hlsl_ir_expr *add_binary_bitwise_expr(struct hlsl_ctx *ctx, struct list *instrs, +static struct hlsl_ir_node *add_binary_bitwise_expr(struct hlsl_ctx *ctx, struct list *instrs, enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2, const struct vkd3d_shader_location *loc) { @@ -1325,7 +1324,7 @@ static struct list *add_binary_bitwise_expr_merge(struct hlsl_ctx *ctx, struct l return list1; }
-static struct hlsl_ir_expr *add_binary_comparison_expr(struct hlsl_ctx *ctx, struct list *instrs, +static struct hlsl_ir_node *add_binary_comparison_expr(struct hlsl_ctx *ctx, struct list *instrs, enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2, struct vkd3d_shader_location *loc) { @@ -1361,7 +1360,7 @@ static struct list *add_binary_comparison_expr_merge(struct hlsl_ctx *ctx, struc return list1; }
-static struct hlsl_ir_expr *add_binary_logical_expr(struct hlsl_ctx *ctx, struct list *instrs, +static struct hlsl_ir_node *add_binary_logical_expr(struct hlsl_ctx *ctx, struct list *instrs, enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2, const struct vkd3d_shader_location *loc) { @@ -1396,7 +1395,7 @@ static struct list *add_binary_logical_expr_merge(struct hlsl_ctx *ctx, struct l return list1; }
-static struct hlsl_ir_expr *add_binary_shift_expr(struct hlsl_ctx *ctx, struct list *instrs, +static struct hlsl_ir_node *add_binary_shift_expr(struct hlsl_ctx *ctx, struct list *instrs, enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2, const struct vkd3d_shader_location *loc) { @@ -1505,22 +1504,17 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in
if (assign_op == ASSIGN_OP_SUB) { - struct hlsl_ir_expr *expr; - - if (!(expr = add_unary_arithmetic_expr(ctx, instrs, HLSL_OP1_NEG, rhs, &rhs->loc))) + if (!(rhs = add_unary_arithmetic_expr(ctx, instrs, HLSL_OP1_NEG, rhs, &rhs->loc))) return NULL; - rhs = &expr->node; assign_op = ASSIGN_OP_ADD; } if (assign_op != ASSIGN_OP_ASSIGN) { enum hlsl_ir_expr_op op = op_from_assignment(assign_op); - struct hlsl_ir_expr *expr;
assert(op); - if (!(expr = add_binary_arithmetic_expr(ctx, instrs, op, lhs, rhs, &rhs->loc))) + if (!(rhs = add_binary_arithmetic_expr(ctx, instrs, op, lhs, rhs, &rhs->loc))) return NULL; - rhs = &expr->node; }
if (lhs_type->type <= HLSL_CLASS_LAST_NUMERIC) @@ -1890,12 +1884,12 @@ static bool intrinsic_abs(struct hlsl_ctx *ctx, static bool intrinsic_clamp(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { - struct hlsl_ir_expr *max; + struct hlsl_ir_node *max;
if (!(max = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MAX, params->args[0], params->args[1], loc))) return false;
- return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MIN, &max->node, params->args[2], loc); + return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MIN, max, params->args[2], loc); }
static bool intrinsic_cross(struct hlsl_ctx *ctx, @@ -1903,8 +1897,7 @@ static bool intrinsic_cross(struct hlsl_ctx *ctx, { struct hlsl_ir_swizzle *arg1_swzl1, *arg1_swzl2, *arg2_swzl1, *arg2_swzl2; struct hlsl_ir_node *arg1 = params->args[0], *arg2 = params->args[1]; - struct hlsl_ir_node *arg1_cast, *arg2_cast, *mul1_neg; - struct hlsl_ir_expr *mul1, *mul2; + struct hlsl_ir_node *arg1_cast, *arg2_cast, *mul1_neg, *mul1, *mul2; struct hlsl_type *cast_type; enum hlsl_base_type base;
@@ -1933,7 +1926,7 @@ static bool intrinsic_cross(struct hlsl_ctx *ctx, &arg1_swzl1->node, &arg2_swzl1->node, loc))) return false;
- if (!(mul1_neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, &mul1->node, *loc))) + if (!(mul1_neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, mul1, *loc))) return false; list_add_tail(params->instrs, &mul1_neg->entry);
@@ -1949,7 +1942,7 @@ static bool intrinsic_cross(struct hlsl_ctx *ctx, &arg1_swzl2->node, &arg2_swzl2->node, loc))) return false;
- return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_ADD, &mul2->node, mul1_neg, loc); + return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_ADD, mul2, mul1_neg, loc); }
static bool intrinsic_floor(struct hlsl_ctx *ctx, @@ -1978,8 +1971,7 @@ static bool intrinsic_min(struct hlsl_ctx *ctx, static bool intrinsic_pow(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { - struct hlsl_ir_node *log, *exp, *arg; - struct hlsl_ir_expr *mul; + struct hlsl_ir_node *log, *exp, *arg, *mul;
if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) return false; @@ -1991,7 +1983,7 @@ static bool intrinsic_pow(struct hlsl_ctx *ctx, if (!(mul = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, params->args[1], log, loc))) return false;
- if (!(exp = hlsl_new_unary_expr(ctx, HLSL_OP1_EXP2, &mul->node, *loc))) + if (!(exp = hlsl_new_unary_expr(ctx, HLSL_OP1_EXP2, mul, *loc))) return false; list_add_tail(params->instrs, &exp->entry); return true;
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com --- libs/vkd3d-shader/hlsl.y | 74 ++++++++++++++++++++++++++++++++++++ tests/hlsl-shape.shader_test | 30 +++++++-------- 2 files changed, 89 insertions(+), 15 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index d6ea668d..22853ceb 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -1197,6 +1197,22 @@ static bool expr_common_shape(struct hlsl_ctx *ctx, struct hlsl_type *t1, struct return true; }
+static unsigned int minor_size(const struct hlsl_type *type) +{ + if (type->modifiers & HLSL_MODIFIER_ROW_MAJOR) + return type->dimx; + else + return type->dimy; +} + +static unsigned int major_size(const struct hlsl_type *type) +{ + if (type->modifiers & HLSL_MODIFIER_ROW_MAJOR) + return type->dimy; + else + return type->dimx; +} + static struct hlsl_ir_node *add_expr(struct hlsl_ctx *ctx, struct list *instrs, enum hlsl_ir_expr_op op, struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS], struct hlsl_type *type, const struct vkd3d_shader_location *loc) @@ -1204,6 +1220,64 @@ static struct hlsl_ir_node *add_expr(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_expr *expr; unsigned int i;
+ if (type->type == HLSL_CLASS_MATRIX) + { + struct vkd3d_string_buffer *name; + static unsigned int counter = 0; + struct hlsl_type *vector_type; + struct hlsl_ir_load *load; + struct hlsl_ir_var *var; + + vector_type = hlsl_get_vector_type(ctx, type->base_type, minor_size(type)); + + name = vkd3d_string_buffer_get(&ctx->string_buffers); + vkd3d_string_buffer_printf(name, "<split_op-%u>", counter++); + var = hlsl_new_synthetic_var(ctx, name->buffer, type, *loc); + vkd3d_string_buffer_release(&ctx->string_buffers, name); + if (!var) + return NULL; + + for (i = 0; i < major_size(type); i++) + { + struct hlsl_ir_node *value, *vector_operands[HLSL_MAX_OPERANDS] = { NULL }; + struct hlsl_ir_store *store; + struct hlsl_ir_constant *c; + unsigned int j; + + if (!(c = hlsl_new_uint_constant(ctx, 4 * i, loc))) + return NULL; + list_add_tail(instrs, &c->node.entry); + + for (j = 0; j < HLSL_MAX_OPERANDS; j++) + { + if (operands[j]) + { + struct hlsl_type *vector_arg_type; + struct hlsl_ir_load *load; + + vector_arg_type = hlsl_get_vector_type(ctx, operands[j]->data_type->base_type, minor_size(type)); + + if (!(load = add_load(ctx, instrs, operands[j], &c->node, vector_arg_type, *loc))) + return NULL; + vector_operands[j] = &load->node; + } + } + + if (!(value = add_expr(ctx, instrs, op, vector_operands, vector_type, loc))) + return NULL; + + if (!(store = hlsl_new_store(ctx, var, &c->node, value, 0, *loc))) + return NULL; + list_add_tail(instrs, &store->node.entry); + } + + if (!(load = hlsl_new_load(ctx, var, NULL, type, *loc))) + return NULL; + list_add_tail(instrs, &load->node.entry); + + return &load->node; + } + if (!(expr = hlsl_alloc(ctx, sizeof(*expr)))) return NULL; init_node(&expr->node, HLSL_IR_EXPR, type, *loc); diff --git a/tests/hlsl-shape.shader_test b/tests/hlsl-shape.shader_test index 65cc322c..b96f0fd2 100644 --- a/tests/hlsl-shape.shader_test +++ b/tests/hlsl-shape.shader_test @@ -93,7 +93,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (2.0, 4.0, 7.0, 9.0)
[pixel shader] @@ -107,7 +107,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (2.0, 4.0, 7.0, 9.0)
[pixel shader] @@ -122,7 +122,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (2.0, 4.0, 6.0, 8.0)
[pixel shader] @@ -137,7 +137,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (2.0, 4.0, 6.0, 8.0)
[pixel shader] @@ -152,7 +152,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (2.0, 7.0, 12.0, 17.0)
[pixel shader] @@ -167,7 +167,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (2.0, 7.0, 12.0, 17.0)
[pixel shader] @@ -183,7 +183,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (2.0, 4.0, 6.0, 0.0)
[pixel shader] @@ -199,7 +199,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (9.0, 11.0, 13.0, 0.0)
[pixel shader] @@ -223,7 +223,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (2.0, 4.0, 6.0, 8.0)
[pixel shader] @@ -247,7 +247,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (2.0, 4.0, 6.0, 8.0)
[pixel shader] @@ -273,7 +273,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (2.0, 4.0, 6.0, 8.0)
[pixel shader] @@ -285,7 +285,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (2.0, 3.0, 4.0, 5.0)
[pixel shader] @@ -297,7 +297,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (2.0, 3.0, 4.0, 5.0)
[pixel shader] @@ -336,7 +336,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (2.0, 3.0, 4.0, 5.0)
[pixel shader] @@ -351,5 +351,5 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (6.0, 7.0, 8.0, 9.0)
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com --- libs/vkd3d-shader/hlsl.y | 118 ++++++++++++++++++++++++ tests/hlsl-majority-pragma.shader_test | 2 +- tests/hlsl-majority-typedef.shader_test | 2 +- tests/hlsl-mul.shader_test | 36 ++++---- 4 files changed, 138 insertions(+), 20 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 22853ceb..617f726e 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -2042,6 +2042,123 @@ static bool intrinsic_min(struct hlsl_ctx *ctx, return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MIN, params->args[0], params->args[1], loc); }
+static bool intrinsic_mul(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *arg1 = params->args[0], *arg2 = params->args[1], *cast1, *cast2; + enum hlsl_base_type base = expr_common_base_type(arg1->data_type->base_type, arg2->data_type->base_type); + struct hlsl_type *cast_type1 = arg1->data_type, *cast_type2 = arg2->data_type, *matrix_type, *ret_type; + unsigned int i, j, k, vect_count = 0; + struct vkd3d_string_buffer *name; + static unsigned int counter = 0; + struct hlsl_ir_load *load; + struct hlsl_ir_var *var; + + if (arg1->data_type->type == HLSL_CLASS_SCALAR || arg2->data_type->type == HLSL_CLASS_SCALAR) + return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, arg1, arg2, loc); + + if (arg1->data_type->type == HLSL_CLASS_VECTOR) + { + vect_count++; + cast_type1 = hlsl_get_matrix_type(ctx, base, arg1->data_type->dimx, 1); + } + if (arg2->data_type->type == HLSL_CLASS_VECTOR) + { + vect_count++; + cast_type2 = hlsl_get_matrix_type(ctx, base, 1, arg2->data_type->dimx); + } + + matrix_type = hlsl_get_matrix_type(ctx, base, cast_type2->dimx, cast_type1->dimy); + + if (vect_count == 0) + { + ret_type = matrix_type; + } + else if (vect_count == 1) + { + assert(matrix_type->dimx == 1 || matrix_type->dimy == 1); + ret_type = hlsl_get_vector_type(ctx, base, matrix_type->dimx * matrix_type->dimy); + } + else + { + assert(matrix_type->dimx == 1 && matrix_type->dimy == 1); + 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; + + name = vkd3d_string_buffer_get(&ctx->string_buffers); + vkd3d_string_buffer_printf(name, "<mul-%u>", counter++); + var = hlsl_new_synthetic_var(ctx, name->buffer, matrix_type, *loc); + vkd3d_string_buffer_release(&ctx->string_buffers, name); + if (!var) + return false; + + for (i = 0; i < matrix_type->dimx; ++i) + for (j = 0; j < matrix_type->dimy; ++j) + { + struct hlsl_ir_node *node = NULL; + struct hlsl_type *scalar_type; + struct hlsl_ir_store *store; + struct hlsl_ir_constant *c; + unsigned int offset; + + for (k = 0; k < cast_type1->dimx && k < cast_type2->dimy; ++k) + { + struct hlsl_ir_load *value1, *value2; + struct hlsl_ir_node *mul; + + offset = hlsl_compute_component_offset(ctx, cast_type1, j * cast_type1->dimx + k, &scalar_type); + if (!(c = hlsl_new_uint_constant(ctx, offset, loc))) + return false; + list_add_tail(params->instrs, &c->node.entry); + + if (!(value1 = add_load(ctx, params->instrs, cast1, &c->node, scalar_type, *loc))) + return false; + + offset = hlsl_compute_component_offset(ctx, cast_type2, k * cast_type2->dimx + i, &scalar_type); + if (!(c = hlsl_new_uint_constant(ctx, offset, loc))) + return false; + list_add_tail(params->instrs, &c->node.entry); + + if (!(value2 = add_load(ctx, params->instrs, cast2, &c->node, scalar_type, *loc))) + return false; + + if (!(mul = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, &value1->node, &value2->node, loc))) + return false; + + if (node) + { + if (!(node = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_ADD, node, mul, loc))) + return false; + } + else + { + node = mul; + } + } + + offset = hlsl_compute_component_offset(ctx, matrix_type, j * matrix_type->dimx + i, &scalar_type); + if (!(c = hlsl_new_uint_constant(ctx, offset, loc))) + return false; + list_add_tail(params->instrs, &c->node.entry); + + if (!(store = hlsl_new_store(ctx, var, &c->node, node, 0, *loc))) + return false; + list_add_tail(params->instrs, &store->node.entry); + } + + if (!(load = hlsl_new_load(ctx, var, NULL, matrix_type, *loc))) + return false; + list_add_tail(params->instrs, &load->node.entry); + + return !!add_implicit_conversion(ctx, params->instrs, &load->node, ret_type, loc); +} + static bool intrinsic_pow(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { @@ -2102,6 +2219,7 @@ intrinsic_functions[] = {"floor", 1, true, intrinsic_floor}, {"max", 2, true, intrinsic_max}, {"min", 2, true, intrinsic_min}, + {"mul", 2, true, intrinsic_mul}, {"pow", 2, true, intrinsic_pow}, {"round", 1, true, intrinsic_round}, {"saturate", 1, true, intrinsic_saturate}, diff --git a/tests/hlsl-majority-pragma.shader_test b/tests/hlsl-majority-pragma.shader_test index a9f917ff..e7fc75cd 100644 --- a/tests/hlsl-majority-pragma.shader_test +++ b/tests/hlsl-majority-pragma.shader_test @@ -17,5 +17,5 @@ uniform 0 float4 0.1 0.2 0.0 0.0 uniform 4 float4 0.3 0.4 0.0 0.0 uniform 8 float4 0.1 0.3 0.0 0.0 uniform 12 float4 0.2 0.4 0.0 0.0 -todo draw quad +draw quad probe all rgba (0.17, 0.39, 0.17, 0.39) 1 diff --git a/tests/hlsl-majority-typedef.shader_test b/tests/hlsl-majority-typedef.shader_test index 192c96db..1460e9a0 100644 --- a/tests/hlsl-majority-typedef.shader_test +++ b/tests/hlsl-majority-typedef.shader_test @@ -18,5 +18,5 @@ uniform 0 float4 0.1 0.2 0.0 0.0 uniform 4 float4 0.3 0.4 0.0 0.0 uniform 8 float4 0.1 0.3 0.0 0.0 uniform 12 float4 0.2 0.4 0.0 0.0 -todo draw quad +draw quad probe all rgba (0.17, 0.39, 0.17, 0.39) 1 diff --git a/tests/hlsl-mul.shader_test b/tests/hlsl-mul.shader_test index 1d137e69..7b453187 100644 --- a/tests/hlsl-mul.shader_test +++ b/tests/hlsl-mul.shader_test @@ -12,7 +12,7 @@ float4 main(float4 pos : sv_position) : sv_target }
[test] -todo draw quad +draw quad probe all rgba (30.0, 70.0, 110.0, 150.0)
[pixel shader] @@ -28,7 +28,7 @@ float4 main(float4 pos : sv_position) : sv_target }
[test] -todo draw quad +draw quad probe all rgba (90.0, 100.0, 110.0, 120.0)
[pixel shader] @@ -44,7 +44,7 @@ float4 main(float4 pos : sv_position) : sv_target }
[test] -todo draw quad +draw quad probe all rgba (14.0, 38.0, 62.0, 86.0)
[pixel shader] @@ -60,7 +60,7 @@ float4 main(float4 pos : sv_position) : sv_target }
[test] -todo draw quad +draw quad probe all rgba (38.0, 44.0, 50.0, 56.0)
[pixel shader] @@ -75,7 +75,7 @@ float4 main(float4 pos : sv_position) : sv_target }
[test] -todo draw quad +draw quad probe all rgba (14.0, 32.0, 50.0, 0.0)
[pixel shader] @@ -90,7 +90,7 @@ float4 main(float4 pos : sv_position) : sv_target }
[test] -todo draw quad +draw quad probe all rgba (30.0, 36.0, 42.0, 0.0)
[pixel shader] @@ -106,7 +106,7 @@ float4 main(float4 pos : sv_position) : sv_target }
[test] -todo draw quad +draw quad probe all rgba (50.0, 60.0, 70.0, 80.0)
[pixel shader] @@ -122,7 +122,7 @@ float4 main(float4 pos : sv_position) : sv_target }
[test] -todo draw quad +draw quad probe all rgba (50.0, 60.0, 70.0, 80.0)
[pixel shader] @@ -138,7 +138,7 @@ float4 main(float4 pos : sv_position) : sv_target }
[test] -todo draw quad +draw quad probe all rgba (10.0, 20.0, 30.0, 40.0)
[pixel shader] @@ -154,7 +154,7 @@ float4 main(float4 pos : sv_position) : sv_target }
[test] -todo draw quad +draw quad probe all rgba (10.0, 50.0, 90.0, 130.0)
[pixel shader] @@ -170,7 +170,7 @@ float4 main(float4 pos : sv_position) : sv_target }
[test] -todo draw quad +draw quad probe all rgba (10.0, 20.0, 30.0, 40.0)
[pixel shader] @@ -186,7 +186,7 @@ float4 main(float4 pos : sv_position) : sv_target }
[test] -todo draw quad +draw quad probe all rgba (10.0, 50.0, 90.0, 130.0)
[pixel shader] @@ -202,7 +202,7 @@ float4 main(float4 pos : sv_position) : sv_target }
[test] -todo draw quad +draw quad probe all rgba (90.0, 100.0, 110.0, 120.0)
[pixel shader] @@ -218,7 +218,7 @@ float4 main(float4 pos : sv_position) : sv_target }
[test] -todo draw quad +draw quad probe all rgba (5.0, 10.0, 15.0, 20.0)
[pixel shader] @@ -234,7 +234,7 @@ float4 main(float4 pos : sv_position) : sv_target }
[test] -todo draw quad +draw quad probe all rgba (2.0, 4.0, 6.0, 8.0)
[pixel shader] @@ -250,7 +250,7 @@ float4 main(float4 pos : sv_position) : sv_target }
[test] -todo draw quad +draw quad probe all rgba (30.0, 70.0, 110.0, 150.0)
[pixel shader] @@ -268,7 +268,7 @@ float4 main(float4 pos : sv_position) : sv_target }
[test] -todo draw quad +draw quad probe all rgba (83.0, 98.0, 113.0, 128.0)
[pixel shader] @@ -286,5 +286,5 @@ float4 main(float4 pos : sv_position) : sv_target }
[test] -todo draw quad +draw quad probe all rgba (78.0, 96.0, 114.0, 0.0)