diff --git a/.gitlab-ci/traces-panfrost.yml b/.gitlab-ci/traces-panfrost.yml index 6aca928956b..b4323971199 100644 --- a/.gitlab-ci/traces-panfrost.yml +++ b/.gitlab-ci/traces-panfrost.yml @@ -45,9 +45,9 @@ traces: - path: gputest/triangle.trace expectations: - device: gl-panfrost-t860 - checksum: 6def0c34ade7d4ec930b45d0eef6e46a + checksum: 75c5a2e261d576d115a659f6cd52a90d - device: gl-panfrost-t760 - checksum: 6def0c34ade7d4ec930b45d0eef6e46a + checksum: 75c5a2e261d576d115a659f6cd52a90d - path: humus/Portals.trace expectations: - device: gl-panfrost-t860 @@ -190,11 +190,11 @@ traces: - path: gputest/pixmark-julia-fp32.trace expectations: - device: gl-panfrost-t860 - checksum: 03c268b0afaf341b4d8226cc6892273a + checksum: d85b6967b7c768f28395c5c5dfbcfe3e - path: gputest/plot3d.trace expectations: - device: gl-panfrost-t860 - checksum: 522afab0fd4bbabbc2f78735646069d8 + checksum: 991efbfd046f70e1fd965d3983bb2965 - path: humus/AmbientAperture.trace expectations: - device: gl-panfrost-t860 diff --git a/src/gallium/drivers/panfrost/pan_blend.h b/src/gallium/drivers/panfrost/pan_blend.h index 785d3076865..300bb8a819a 100644 --- a/src/gallium/drivers/panfrost/pan_blend.h +++ b/src/gallium/drivers/panfrost/pan_blend.h @@ -68,7 +68,7 @@ struct panfrost_blend_shader_final { }; struct panfrost_blend_equation_final { - struct mali_blend_equation_packed equation; + struct MALI_BLEND_EQUATION equation; float constant; }; @@ -77,7 +77,7 @@ struct panfrost_blend_rt { * fixed-function configuration for this blend state */ bool has_fixed_function; - struct mali_blend_equation_packed equation; + struct MALI_BLEND_EQUATION equation; /* Mask of blend color components read */ unsigned constant_mask; diff --git a/src/gallium/drivers/panfrost/pan_blend_cso.c b/src/gallium/drivers/panfrost/pan_blend_cso.c index 43edddb9dd5..e5d27037ac8 100644 --- a/src/gallium/drivers/panfrost/pan_blend_cso.c +++ b/src/gallium/drivers/panfrost/pan_blend_cso.c @@ -129,8 +129,17 @@ panfrost_create_blend_state(struct pipe_context *pipe, &rt->equation, &rt->constant_mask); - if (rt->has_fixed_function) - rt->opaque = (rt->equation.opaque[0] == 0xf0122122); + if (rt->has_fixed_function) { + rt->opaque = pipe.rgb_src_factor == PIPE_BLENDFACTOR_ONE && + pipe.rgb_dst_factor == PIPE_BLENDFACTOR_ZERO && + (pipe.rgb_func == PIPE_BLEND_ADD || + pipe.rgb_func == PIPE_BLEND_SUBTRACT) && + pipe.alpha_src_factor == PIPE_BLENDFACTOR_ONE && + pipe.alpha_dst_factor == PIPE_BLENDFACTOR_ZERO && + (pipe.alpha_func == PIPE_BLEND_ADD || + pipe.alpha_func == PIPE_BLEND_SUBTRACT) && + pipe.colormask == 0xf; + } rt->load_dest = util_blend_uses_dest(pipe) || pipe.colormask != 0xF; diff --git a/src/gallium/drivers/panfrost/pan_blending.c b/src/gallium/drivers/panfrost/pan_blending.c index 5a94975230d..fda516c8089 100644 --- a/src/gallium/drivers/panfrost/pan_blending.c +++ b/src/gallium/drivers/panfrost/pan_blending.c @@ -28,76 +28,7 @@ #include "gallium/auxiliary/util/u_blend.h" #include "util/format/u_format.h" -/* - * Implements fixed-function blending on Midgard. - * - * Midgard splits blending into a fixed-function fast path and a programmable - * slow path. The fixed function blending architecture is based on "dominant" - * blend factors. Blending is encoded separately (but identically) between RGB - * and alpha functions. - * - * Essentially, for a given blending operation, there is a single dominant - * factor. The following dominant factors are possible: - * - * - zero - * - source color - * - destination color - * - source alpha - * - destination alpha - * - constant float - * - * Further, a dominant factor's arithmetic compliment could be used. For - * instance, to encode GL_ONE_MINUS_SOURCE_ALPHA, the dominant factor would be - * MALI_DOMINANT_SRC_ALPHA with the complement_dominant bit set. - * - * A single constant float can be passed to the fixed-function hardware, - * allowing CONSTANT_ALPHA support. Further, if all components of the constant - * glBlendColor are identical, CONSTANT_COLOR can be implemented with the - * constant float mode. If the components differ, programmable blending is - * required. - * - * The nondominant factor can be either: - * - * - the same as the dominant factor (MALI_BLEND_NON_MIRROR) - * - zero (MALI_BLEND_NON_ZERO) - * - * Exactly one of the blend operation's source or destination can be used as - * the dominant factor; this is selected by the - * MALI_BLEND_DOM_SOURCE/DESTINATION flag. - * - * By default, all blending follows the standard OpenGL addition equation: - * - * out = source_value * source_factor + destination_value * destination_factor - * - * By setting the negate_source or negate_dest bits, other blend functions can - * be created. For instance, for SUBTRACT mode, set the "negate destination" - * flag, and similarly for REVERSE_SUBTRACT with "negate source". - * - * Finally, there is a "clip modifier" controlling the final blending - * behaviour, allowing for the following modes: - * - * - normal - * - force source factor to one (MALI_BLEND_MODE_SOURCE_ONE) - * - force destination factor to one (MALI_BLEND_MODE_DEST_ONE) - * - * The clipping flags can be used to encode blend modes where the nondominant - * factor is ONE. - * - * As an example putting it all together, to encode the following blend state: - * - * glBlendEquation(GL_FUNC_REVERSE_SUBTRACT); - * glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_ONE); - * - * We need the following configuration: - * - * - negate source (for REVERSE_SUBTRACT) - * - dominant factor "source alpha" - * - complement dominant - * - source dominant - * - force destination to ONE - * - * The following routines implement this fixed function blending encoding - */ +/* Implements fixed-function blending on Midgard. */ /* Not all formats can be blended by fixed-function hardware */ @@ -161,54 +92,6 @@ uncomplement_factor(int factor) return (complement == -1) ? factor : complement; } - -/* Attempt to find the dominant factor given a particular factor, complementing - * as necessary */ - -static bool -panfrost_make_dominant_factor(unsigned src_factor, enum mali_dominant_factor *factor) -{ - switch (src_factor) { - case PIPE_BLENDFACTOR_SRC_COLOR: - case PIPE_BLENDFACTOR_INV_SRC_COLOR: - *factor = MALI_DOMINANT_SRC_COLOR; - break; - - case PIPE_BLENDFACTOR_SRC_ALPHA: - case PIPE_BLENDFACTOR_INV_SRC_ALPHA: - *factor = MALI_DOMINANT_SRC_ALPHA; - break; - - case PIPE_BLENDFACTOR_DST_COLOR: - case PIPE_BLENDFACTOR_INV_DST_COLOR: - *factor = MALI_DOMINANT_DST_COLOR; - break; - - case PIPE_BLENDFACTOR_DST_ALPHA: - case PIPE_BLENDFACTOR_INV_DST_ALPHA: - *factor = MALI_DOMINANT_DST_ALPHA; - break; - - case PIPE_BLENDFACTOR_ONE: - case PIPE_BLENDFACTOR_ZERO: - *factor = MALI_DOMINANT_ZERO; - break; - - case PIPE_BLENDFACTOR_CONST_ALPHA: - case PIPE_BLENDFACTOR_INV_CONST_ALPHA: - case PIPE_BLENDFACTOR_CONST_COLOR: - case PIPE_BLENDFACTOR_INV_CONST_COLOR: - *factor = MALI_DOMINANT_CONSTANT; - break; - - default: - /* Fancy blend modes not supported */ - return false; - } - - return true; -} - /* Check if this is a special edge case blend factor, which may require the use * of clip modifiers */ @@ -218,98 +101,154 @@ is_edge_blendfactor(unsigned factor) return factor == PIPE_BLENDFACTOR_ONE || factor == PIPE_BLENDFACTOR_ZERO; } -/* Perform the actual fixed function encoding. Encode the function with negate - * bits. Check for various cases to work out the dominant/nondominant split and - * accompanying flags. */ +static bool +factor_is_supported(unsigned factor) +{ + return factor != PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE && + factor != PIPE_BLENDFACTOR_SRC1_COLOR && + factor != PIPE_BLENDFACTOR_SRC1_ALPHA && + factor != PIPE_BLENDFACTOR_INV_SRC1_COLOR && + factor != PIPE_BLENDFACTOR_INV_SRC1_ALPHA; +} static bool -panfrost_make_fixed_blend_part(unsigned func, unsigned src_factor, unsigned dst_factor, unsigned *out) +can_use_fixed_function_blend(unsigned blend_func, + unsigned src_factor, + unsigned dest_factor) { - struct mali_blend_mode part = { 0 }; + if (blend_func != PIPE_BLEND_ADD && + blend_func != PIPE_BLEND_SUBTRACT && + blend_func != PIPE_BLEND_REVERSE_SUBTRACT) + return false; - /* Make sure that the blend function is representible */ + if (!factor_is_supported(src_factor) || + !factor_is_supported(dest_factor)) + return false; - switch (func) { - case PIPE_BLEND_ADD: + if (src_factor != dest_factor && + src_factor != complement_factor(dest_factor) && + complement_factor(src_factor) != dest_factor && + !is_edge_blendfactor(src_factor) && + !is_edge_blendfactor(dest_factor)) + return false; + + return true; +} + +static void to_c_factor(unsigned factor, struct MALI_BLEND_FUNCTION *function) +{ + if (complement_factor(factor) >= 0) + function->invert_c = true; + + switch (uncomplement_factor(factor)) { + case PIPE_BLENDFACTOR_ONE: + case PIPE_BLENDFACTOR_ZERO: + function->invert_c = factor == PIPE_BLENDFACTOR_ONE; + function->c = MALI_BLEND_OPERAND_C_ZERO; break; - /* TODO: Reenable subtraction modes when those fixed */ - case PIPE_BLEND_SUBTRACT: - case PIPE_BLEND_REVERSE_SUBTRACT: + case PIPE_BLENDFACTOR_SRC_ALPHA: + function->c = MALI_BLEND_OPERAND_C_SRC_ALPHA; + break; + + case PIPE_BLENDFACTOR_DST_ALPHA: + function->c = MALI_BLEND_OPERAND_C_DEST_ALPHA; + break; + + case PIPE_BLENDFACTOR_SRC_COLOR: + function->c = MALI_BLEND_OPERAND_C_SRC; + break; + + case PIPE_BLENDFACTOR_DST_COLOR: + function->c = MALI_BLEND_OPERAND_C_DEST; + break; + + case PIPE_BLENDFACTOR_CONST_COLOR: + case PIPE_BLENDFACTOR_CONST_ALPHA: + function->c = MALI_BLEND_OPERAND_C_CONSTANT; + break; default: - return false; + unreachable("Invalid blend factor"); } - part.clip_modifier = MALI_BLEND_MOD_NORMAL; +} - /* Decide which is dominant, source or destination. If one is an edge - * case, use the other as a factor. If they're the same, it doesn't - * matter; we just mirror. If they're different non-edge-cases, you - * need a blend shader (don't do that). */ +static bool +to_panfrost_function(unsigned blend_func, + unsigned src_factor, + unsigned dest_factor, + struct MALI_BLEND_FUNCTION *function) +{ + if (!can_use_fixed_function_blend(blend_func, src_factor, dest_factor)) + return false; - if (is_edge_blendfactor(dst_factor)) { - part.dominant = MALI_BLEND_DOM_SOURCE; - part.nondominant_mode = MALI_BLEND_NON_ZERO; + if (src_factor == PIPE_BLENDFACTOR_ZERO) { + function->a = MALI_BLEND_OPERAND_A_ZERO; + function->b = MALI_BLEND_OPERAND_B_DEST; + if (blend_func == PIPE_BLEND_SUBTRACT) + function->negate_b = true; + to_c_factor(dest_factor, function); + } else if (src_factor == PIPE_BLENDFACTOR_ONE) { + function->a = MALI_BLEND_OPERAND_A_SRC; + function->b = MALI_BLEND_OPERAND_B_DEST; + if (blend_func == PIPE_BLEND_SUBTRACT) + function->negate_b = true; + else if (blend_func == PIPE_BLEND_REVERSE_SUBTRACT) + function->negate_a = true; + to_c_factor(dest_factor, function); + } else if (dest_factor == PIPE_BLENDFACTOR_ZERO) { + function->a = MALI_BLEND_OPERAND_A_ZERO; + function->b = MALI_BLEND_OPERAND_B_SRC; + if (blend_func == PIPE_BLEND_REVERSE_SUBTRACT) + function->negate_b = true; + to_c_factor(src_factor, function); + } else if (dest_factor == PIPE_BLENDFACTOR_ONE) { + function->a = MALI_BLEND_OPERAND_A_DEST; + function->b = MALI_BLEND_OPERAND_B_SRC; + if (blend_func == PIPE_BLEND_SUBTRACT) + function->negate_a = true; + else if (blend_func == PIPE_BLEND_REVERSE_SUBTRACT) + function->negate_b = true; + to_c_factor(src_factor, function); + } else if (src_factor == dest_factor) { + function->a = MALI_BLEND_OPERAND_A_ZERO; + to_c_factor(src_factor, function); - if (dst_factor == PIPE_BLENDFACTOR_ONE) - part.clip_modifier = MALI_BLEND_MOD_DEST_ONE; - } else if (is_edge_blendfactor(src_factor)) { - part.dominant = MALI_BLEND_DOM_DESTINATION; - part.nondominant_mode = MALI_BLEND_NON_ZERO; - - if (src_factor == PIPE_BLENDFACTOR_ONE) - part.clip_modifier = MALI_BLEND_MOD_SOURCE_ONE; - } else if (src_factor == dst_factor) { - /* XXX: Why? */ - part.dominant = func == PIPE_BLEND_ADD ? - MALI_BLEND_DOM_DESTINATION : MALI_BLEND_DOM_SOURCE; - - part.nondominant_mode = MALI_BLEND_NON_MIRROR; - } else if (src_factor == complement_factor(dst_factor)) { - /* TODO: How does this work exactly? */ - part.dominant = MALI_BLEND_DOM_SOURCE; - part.nondominant_mode = MALI_BLEND_NON_MIRROR; - part.clip_modifier = MALI_BLEND_MOD_DEST_ONE; - - /* The complement is handled by the clip modifier, don't set a - * complement flag */ - - dst_factor = src_factor; - } else if (dst_factor == complement_factor(src_factor)) { - part.dominant = MALI_BLEND_DOM_SOURCE; - part.nondominant_mode = MALI_BLEND_NON_MIRROR; - part.clip_modifier = MALI_BLEND_MOD_SOURCE_ONE; - - src_factor = dst_factor; + switch (blend_func) { + case PIPE_BLEND_ADD: + function->b = MALI_BLEND_OPERAND_B_SRC_PLUS_DEST; + break; + case PIPE_BLEND_REVERSE_SUBTRACT: + function->negate_b = true; + /* fall-through */ + case PIPE_BLEND_SUBTRACT: + function->b = MALI_BLEND_OPERAND_B_SRC_MINUS_DEST; + break; + default: + unreachable("Invalid blend function"); + } } else { - return false; + assert(src_factor == complement_factor(dest_factor) || + complement_factor(src_factor) == dest_factor); + + function->a = MALI_BLEND_OPERAND_A_DEST; + to_c_factor(src_factor, function); + + switch (blend_func) { + case PIPE_BLEND_ADD: + function->b = MALI_BLEND_OPERAND_B_SRC_MINUS_DEST; + break; + case PIPE_BLEND_REVERSE_SUBTRACT: + function->b = MALI_BLEND_OPERAND_B_SRC_PLUS_DEST; + function->negate_b = true; + break; + case PIPE_BLEND_SUBTRACT: + function->b = MALI_BLEND_OPERAND_B_SRC_PLUS_DEST; + function->negate_a = true; + break; + } } - unsigned in_dominant_factor = - part.dominant == MALI_BLEND_DOM_SOURCE ? src_factor : dst_factor; - - if (part.clip_modifier == MALI_BLEND_MOD_NORMAL && in_dominant_factor == PIPE_BLENDFACTOR_ONE) { - part.clip_modifier = part.dominant == MALI_BLEND_DOM_SOURCE ? MALI_BLEND_MOD_SOURCE_ONE : MALI_BLEND_MOD_DEST_ONE; - in_dominant_factor = PIPE_BLENDFACTOR_ZERO; - } - - enum mali_dominant_factor dominant_factor; - - if (!panfrost_make_dominant_factor(in_dominant_factor, &dominant_factor)) - return false; - - part.dominant_factor = dominant_factor; - part.complement_dominant = util_blend_factor_is_inverted(in_dominant_factor); - - /* It's not clear what this does, but fixes some ADD blending tests. - * More research is needed XXX */ - - if ((part.clip_modifier == MALI_BLEND_MOD_SOURCE_ONE) && (part.dominant == MALI_BLEND_DOM_SOURCE)) - part.negate_dest = true; - - /* Write out mode */ - memcpy(out, &part, sizeof(part)); - return true; } @@ -340,19 +279,20 @@ panfrost_constant_mask(unsigned *factors, unsigned num_factors) */ bool -panfrost_make_fixed_blend_mode( - struct pipe_rt_blend_state blend, - struct mali_blend_equation_packed *out, - unsigned *constant_mask) +panfrost_make_fixed_blend_mode(const struct pipe_rt_blend_state blend, + struct MALI_BLEND_EQUATION *equation, + unsigned *constant_mask) { /* If no blending is enabled, default back on `replace` mode */ if (!blend.blend_enable) { - pan_pack(out, BLEND_EQUATION, cfg) { - cfg.color_mask = blend.colormask; - cfg.rgb_mode = cfg.alpha_mode = 0x122; - } - + equation->color_mask = blend.colormask; + equation->rgb.a = MALI_BLEND_OPERAND_A_SRC; + equation->rgb.b = MALI_BLEND_OPERAND_B_SRC; + equation->rgb.c = MALI_BLEND_OPERAND_C_ZERO; + equation->alpha.a = MALI_BLEND_OPERAND_A_SRC; + equation->alpha.b = MALI_BLEND_OPERAND_B_SRC; + equation->alpha.c = MALI_BLEND_OPERAND_C_ZERO; return true; } @@ -368,25 +308,16 @@ panfrost_make_fixed_blend_mode( *constant_mask = panfrost_constant_mask(factors, ARRAY_SIZE(factors)); /* Try to compile the actual fixed-function blend */ - - unsigned rgb_mode = 0; - unsigned alpha_mode = 0; - - if (!panfrost_make_fixed_blend_part( - blend.rgb_func, blend.rgb_src_factor, blend.rgb_dst_factor, - &rgb_mode)) + if (!to_panfrost_function(blend.rgb_func, blend.rgb_src_factor, + blend.rgb_dst_factor, + &equation->rgb)) return false; - if (!panfrost_make_fixed_blend_part( - blend.alpha_func, blend.alpha_src_factor, blend.alpha_dst_factor, - &alpha_mode)) + if (!to_panfrost_function(blend.alpha_func, blend.alpha_src_factor, + blend.alpha_dst_factor, + &equation->alpha)) return false; - pan_pack(out, BLEND_EQUATION, cfg) { - cfg.color_mask = blend.colormask; - cfg.rgb_mode = rgb_mode; - cfg.alpha_mode = alpha_mode; - } - + equation->color_mask = blend.colormask; return true; } diff --git a/src/gallium/drivers/panfrost/pan_blending.h b/src/gallium/drivers/panfrost/pan_blending.h index c466e8d665a..d34e472de50 100644 --- a/src/gallium/drivers/panfrost/pan_blending.h +++ b/src/gallium/drivers/panfrost/pan_blending.h @@ -28,14 +28,14 @@ #include "pipe/p_state.h" #include "pipe/p_defines.h" #include +#include "pan_blend.h" struct panfrost_blend_state; bool -panfrost_make_fixed_blend_mode( - const struct pipe_rt_blend_state blend, - struct mali_blend_equation_packed *out, - unsigned *constant_mask); +panfrost_make_fixed_blend_mode(const struct pipe_rt_blend_state blend, + struct MALI_BLEND_EQUATION *equation, + unsigned *constant_mask); bool panfrost_can_fixed_blend(enum pipe_format format); diff --git a/src/gallium/drivers/panfrost/pan_cmdstream.c b/src/gallium/drivers/panfrost/pan_cmdstream.c index 1cbfeb8c433..fd0b6ad1e77 100644 --- a/src/gallium/drivers/panfrost/pan_cmdstream.c +++ b/src/gallium/drivers/panfrost/pan_cmdstream.c @@ -307,8 +307,12 @@ panfrost_emit_bifrost_blend(struct panfrost_batch *batch, enum pipe_format format = batch->key.cbufs[i]->format; const struct util_format_description *format_desc; format_desc = util_format_description(format); + struct mali_blend_equation_packed peq; - brts[i].equation = blend[i].equation.equation; + pan_pack(&peq, BLEND_EQUATION, cfg) { + cfg = blend[i].equation.equation; + } + brts[i].equation = peq; /* TODO: this is a bit more complicated */ brts[i].constant = blend[i].equation.constant; @@ -338,7 +342,13 @@ panfrost_emit_midgard_blend(struct panfrost_batch *batch, if (rt_count == 0) { /* Disable blending for depth-only */ pan_pack(rts, MIDGARD_BLEND, cfg) { - cfg.equation = 0xf0122122; /* Replace */ + cfg.equation.color_mask = 0xf; + cfg.equation.rgb.a = MALI_BLEND_OPERAND_A_SRC; + cfg.equation.rgb.b = MALI_BLEND_OPERAND_B_SRC; + cfg.equation.rgb.c = MALI_BLEND_OPERAND_C_ZERO; + cfg.equation.alpha.a = MALI_BLEND_OPERAND_A_SRC; + cfg.equation.alpha.b = MALI_BLEND_OPERAND_B_SRC; + cfg.equation.alpha.c = MALI_BLEND_OPERAND_C_ZERO; } return; } @@ -357,7 +367,7 @@ panfrost_emit_midgard_blend(struct panfrost_batch *batch, if (blend[i].is_shader) { cfg.shader = blend[i].shader.gpu | blend[i].shader.first_tag; } else { - cfg.equation = blend[i].equation.equation.opaque[0]; + cfg.equation = blend[i].equation.equation; cfg.constant = blend[i].equation.constant; } } @@ -460,7 +470,7 @@ panfrost_prepare_midgard_fs_state(struct panfrost_context *ctx, state->sfbd_blend_shader = blend[0].shader.gpu | blend[0].shader.first_tag; } else { - state->sfbd_blend_equation = blend[0].equation.equation.opaque[0]; + state->sfbd_blend_equation = blend[0].equation.equation; state->sfbd_blend_constant = blend[0].equation.constant; } } else { diff --git a/src/panfrost/include/panfrost-job.h b/src/panfrost/include/panfrost-job.h index 1d32a35ee66..1482ce75b88 100644 --- a/src/panfrost/include/panfrost-job.h +++ b/src/panfrost/include/panfrost-job.h @@ -38,51 +38,6 @@ typedef uint32_t u32; typedef uint64_t u64; typedef uint64_t mali_ptr; -enum mali_nondominant_mode { - MALI_BLEND_NON_MIRROR = 0, - MALI_BLEND_NON_ZERO = 1 -}; - -enum mali_dominant_blend { - MALI_BLEND_DOM_SOURCE = 0, - MALI_BLEND_DOM_DESTINATION = 1 -}; - -enum mali_dominant_factor { - MALI_DOMINANT_UNK0 = 0, - MALI_DOMINANT_ZERO = 1, - MALI_DOMINANT_SRC_COLOR = 2, - MALI_DOMINANT_DST_COLOR = 3, - MALI_DOMINANT_UNK4 = 4, - MALI_DOMINANT_SRC_ALPHA = 5, - MALI_DOMINANT_DST_ALPHA = 6, - MALI_DOMINANT_CONSTANT = 7, -}; - -enum mali_blend_modifier { - MALI_BLEND_MOD_UNK0 = 0, - MALI_BLEND_MOD_NORMAL = 1, - MALI_BLEND_MOD_SOURCE_ONE = 2, - MALI_BLEND_MOD_DEST_ONE = 3, -}; - -struct mali_blend_mode { - enum mali_blend_modifier clip_modifier : 2; - unsigned unused_0 : 1; - unsigned negate_source : 1; - - enum mali_dominant_blend dominant : 1; - - enum mali_nondominant_mode nondominant_mode : 1; - - unsigned unused_1 : 1; - - unsigned negate_dest : 1; - - enum mali_dominant_factor dominant_factor : 3; - unsigned complement_dominant : 1; -} __attribute__((packed)); - /* Compressed per-pixel formats. Each of these formats expands to one to four * floating-point or integer numbers, as defined by the OpenGL specification. * There are various places in OpenGL where the user can specify a compressed diff --git a/src/panfrost/lib/decode.c b/src/panfrost/lib/decode.c index f1f3db80c03..e6d35b65972 100644 --- a/src/panfrost/lib/decode.c +++ b/src/panfrost/lib/decode.c @@ -1185,15 +1185,19 @@ pandecode_vertex_tiler_postfix_pre( if (!is_bifrost) { /* TODO: Blend shaders routing/disasm */ - union midgard_blend blend; + pandecode_log("SFBD Blend:\n"); + pandecode_indent++; if (state.multisample_misc.sfbd_blend_shader) { - blend.shader = state.sfbd_blend_shader; + pandecode_shader_address("Shader", state.sfbd_blend_shader); } else { - blend.equation.opaque[0] = state.sfbd_blend_equation; - blend.constant = state.sfbd_blend_constant; + DUMP_UNPACKED(BLEND_EQUATION, state.sfbd_blend_equation, "Equation:\n"); + pandecode_prop("Constant = %f", state.sfbd_blend_constant); } - mali_ptr shader = pandecode_midgard_blend(&blend, state.multisample_misc.sfbd_blend_shader); - if (shader & ~0xF) + pandecode_indent--; + pandecode_log("\n"); + + mali_ptr shader = state.sfbd_blend_shader & ~0xF; + if (state.multisample_misc.sfbd_blend_shader && shader) pandecode_blend_shader_disassemble(shader, job_no, job_type, false, gpu_id); } pandecode_indent--; diff --git a/src/panfrost/lib/midgard.xml b/src/panfrost/lib/midgard.xml index 202327f1d62..a978d0a8bd8 100644 --- a/src/panfrost/lib/midgard.xml +++ b/src/panfrost/lib/midgard.xml @@ -285,10 +285,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + @@ -301,7 +334,7 @@ - + @@ -553,7 +586,7 @@ - + diff --git a/src/panfrost/lib/pan_blit.c b/src/panfrost/lib/pan_blit.c index b068e02a0e2..8f30b05c478 100644 --- a/src/panfrost/lib/pan_blit.c +++ b/src/panfrost/lib/pan_blit.c @@ -207,16 +207,6 @@ panfrost_load_midg( cfg.format = (MALI_CHANNEL_R << 0) | (MALI_CHANNEL_G << 3) | (MALI_RGBA32F << 12); } - struct mali_blend_equation_packed eq; - - pan_pack(&eq, BLEND_EQUATION, cfg) { - cfg.rgb_mode = 0x122; - cfg.alpha_mode = 0x122; - - if (loc < FRAG_RESULT_DATA0) - cfg.color_mask = 0x0; - } - /* Determine the sampler type needed. Stencil is always sampled as * UINT. Pure (U)INT is always (U)INT. Everything else is FLOAT. */ @@ -271,7 +261,15 @@ panfrost_load_midg( if (cfg.multisample_misc.sfbd_blend_shader) { cfg.sfbd_blend_shader = blend_shader; } else { - cfg.sfbd_blend_equation = eq.opaque[0]; + cfg.sfbd_blend_equation.rgb.a = MALI_BLEND_OPERAND_A_SRC; + cfg.sfbd_blend_equation.rgb.b = MALI_BLEND_OPERAND_B_SRC; + cfg.sfbd_blend_equation.rgb.c = MALI_BLEND_OPERAND_C_ZERO; + cfg.sfbd_blend_equation.alpha.a = MALI_BLEND_OPERAND_A_SRC; + cfg.sfbd_blend_equation.alpha.b = MALI_BLEND_OPERAND_B_SRC; + cfg.sfbd_blend_equation.alpha.c = MALI_BLEND_OPERAND_C_ZERO; + + if (loc >= FRAG_RESULT_DATA0) + cfg.sfbd_blend_equation.color_mask = 0xf; cfg.sfbd_blend_constant = 0; } } else if (!(pool->dev->quirks & IS_BIFROST)) { @@ -313,6 +311,20 @@ panfrost_load_midg( void *dest = shader_meta_t.cpu + MALI_RENDERER_STATE_LENGTH + sizeof(struct midgard_blend_rt) * i; if (loc == (FRAG_RESULT_DATA0 + i)) { + struct mali_blend_equation_packed eq; + + pan_pack(&eq, BLEND_EQUATION, cfg) { + cfg.rgb.a = MALI_BLEND_OPERAND_A_SRC; + cfg.rgb.b = MALI_BLEND_OPERAND_B_SRC; + cfg.rgb.c = MALI_BLEND_OPERAND_C_ZERO; + cfg.alpha.a = MALI_BLEND_OPERAND_A_SRC; + cfg.alpha.b = MALI_BLEND_OPERAND_B_SRC; + cfg.alpha.c = MALI_BLEND_OPERAND_C_ZERO; + + if (loc >= FRAG_RESULT_DATA0) + cfg.color_mask = 0xf; + } + union midgard_blend replace = { .equation = eq };