diff --git a/src/gallium/drivers/panfrost/pan_blend_cso.c b/src/gallium/drivers/panfrost/pan_blend_cso.c index 4bcc3e57a66..4b1ef541e6b 100644 --- a/src/gallium/drivers/panfrost/pan_blend_cso.c +++ b/src/gallium/drivers/panfrost/pan_blend_cso.c @@ -109,7 +109,7 @@ GENX(pan_blend_get_shader_locked)(struct pan_blend_shader_cache *cache, #if PAN_ARCH < 6 enum pipe_format rt_formats[8] = {0}; - rt_formats[rt] = key.format; + rt_formats[rt] = GENX(pan_blend_shader_fmt)(key.format); NIR_PASS(_, nir, pan_nir_lower_framebuffer, rt_formats, pan_raw_format_mask_midgard(rt_formats), MAX2(key.nr_samples, 1), (cache->gpu_id >> 16) < 0x700); diff --git a/src/gallium/drivers/panfrost/pan_cmdstream.c b/src/gallium/drivers/panfrost/pan_cmdstream.c index 8559a52f7ce..b8dfedaec1f 100644 --- a/src/gallium/drivers/panfrost/pan_cmdstream.c +++ b/src/gallium/drivers/panfrost/pan_cmdstream.c @@ -4309,12 +4309,12 @@ panfrost_create_blend_state(struct pipe_context *pipe, /* Could this possibly be fixed-function? */ .fixed_function = !blend->logicop_enable && - pan_blend_can_fixed_function(equation, supports_2src) && + pan_blend_can_fixed_function(PAN_ARCH, equation, supports_2src) && (!constant_mask || pan_blend_supports_constant(PAN_ARCH, c)), .fixed_function_float = !blend->logicop_enable && - pan_blend_can_fixed_function(float_equation, supports_2src) && + pan_blend_can_fixed_function(PAN_ARCH, float_equation, supports_2src) && (!constant_mask || pan_blend_supports_constant(PAN_ARCH, c)), .alpha_zero_nop = pan_blend_alpha_zero_nop(equation), diff --git a/src/panfrost/lib/pan_blend.c b/src/panfrost/lib/pan_blend.c index 64a740538b7..96f7484f8d0 100644 --- a/src/panfrost/lib/pan_blend.c +++ b/src/panfrost/lib/pan_blend.c @@ -62,7 +62,8 @@ is_2srcdest(enum pipe_blend_func blend_func, enum pipe_blendfactor src_factor, } static bool -can_fixed_function_equation(enum pipe_blend_func blend_func, +can_fixed_function_equation(unsigned arch, + enum pipe_blend_func blend_func, enum pipe_blendfactor src_factor, enum pipe_blendfactor dest_factor, bool is_alpha, bool is_float, @@ -96,6 +97,9 @@ can_fixed_function_equation(enum pipe_blend_func blend_func, enum pipe_blendfactor src = util_blendfactor_without_invert(src_factor); enum pipe_blendfactor dest = util_blendfactor_without_invert(dest_factor); + if (arch < 6 && + (src == PIPE_BLENDFACTOR_DST_ALPHA)) + return false; return (src == dest) || (src == PIPE_BLENDFACTOR_ONE) || (dest == PIPE_BLENDFACTOR_ONE); } @@ -278,15 +282,16 @@ pan_pack_blend_constant(enum pipe_format format, float cons) /* Determines if an equation can run in fixed function */ bool -pan_blend_can_fixed_function(const struct pan_blend_equation equation, +pan_blend_can_fixed_function(unsigned arch, + const struct pan_blend_equation equation, bool supports_2src) { return !equation.blend_enable || - (can_fixed_function_equation( + (can_fixed_function_equation(arch, equation.rgb_func, equation.rgb_src_factor, equation.rgb_dst_factor, false /* is_alpha */, equation.is_float, supports_2src) && - can_fixed_function_equation( + can_fixed_function_equation(arch, equation.alpha_func, equation.alpha_src_factor, equation.alpha_dst_factor, true /* is_alpha */, equation.is_float, supports_2src)); @@ -328,10 +333,6 @@ to_mali_function(enum pipe_blend_func blend_func, bool is_alpha, bool is_float, struct MALI_BLEND_FUNCTION *function) { - assert(can_fixed_function_equation(blend_func, src_factor, dest_factor, - is_alpha, is_float, - true /* supports_2src */)); - /* We handle ZERO/ONE specially since it's the hardware has 0 and can invert * to 1 but Gallium has 0 as the uninverted version. */ @@ -778,6 +779,9 @@ GENX(pan_blend_shader_fmt)(enum pipe_format format) { switch (format) { #if PAN_ARCH < 6 + case PIPE_FORMAT_A16_FLOAT: + case PIPE_FORMAT_I16_FLOAT: + return PIPE_FORMAT_R16G16B16A16_FLOAT; case PIPE_FORMAT_R10G10B10A2_UNORM: case PIPE_FORMAT_R10G10B10X2_UNORM: return PIPE_FORMAT_R8G8B8A8_UNORM; diff --git a/src/panfrost/lib/pan_blend.h b/src/panfrost/lib/pan_blend.h index 2a9e6d64ddd..0a84d4afe80 100644 --- a/src/panfrost/lib/pan_blend.h +++ b/src/panfrost/lib/pan_blend.h @@ -60,7 +60,8 @@ struct pan_blend_shader_key { bool pan_blend_reads_dest(const struct pan_blend_equation eq); -bool pan_blend_can_fixed_function(const struct pan_blend_equation equation, +bool pan_blend_can_fixed_function(unsigned arch, + const struct pan_blend_equation equation, bool supports_2src); bool pan_blend_is_opaque(const struct pan_blend_equation eq); diff --git a/src/panfrost/lib/pan_format.c b/src/panfrost/lib/pan_format.c index c5c054a6aa3..ffd169d7074 100644 --- a/src/panfrost/lib/pan_format.c +++ b/src/panfrost/lib/pan_format.c @@ -92,6 +92,9 @@ const struct pan_blendable_format BFMT_SRGB(R8G8B8A8, R8G8B8A8), BFMT2(A8_UNORM, R8G8B8A8, R8, 0), +#if PAN_ARCH < 6 + BFMT2(I8_UNORM, R8G8B8A8, R8, 0), +#endif BFMT2(R5G6B5_UNORM, R5G6B5A0, R5G6B5, 0), BFMT2(B5G6R5_UNORM, R5G6B5A0, R5G6B5, 0), diff --git a/src/panfrost/lib/tests/test-blend.c b/src/panfrost/lib/tests/test-blend.c index ded6d17d985..f01fc73d7af 100644 --- a/src/panfrost/lib/tests/test-blend.c +++ b/src/panfrost/lib/tests/test-blend.c @@ -281,16 +281,24 @@ main(int argc, const char **argv) { unsigned nr_pass = 0, nr_fail = 0; + /* The architecture we test for is arbitrary and used only for checking + * whether we can use fixed function. If we really wanted to be paranoid + * we could add a loop checking all architectures, but in practice there's + * not much difference and we're only checking for internal consistency + * anyway + */ + unsigned arch = 10; + for (unsigned i = 0; i < ARRAY_SIZE(blend_tests); ++i) { struct test T = blend_tests[i]; ASSERT_EQ(T.constant_mask, pan_blend_constant_mask(T.eq)); ASSERT_EQ(T.reads_dest, pan_blend_reads_dest(T.eq)); ASSERT_EQ(T.opaque, pan_blend_is_opaque(T.eq)); - ASSERT_EQ(T.fixed_function, pan_blend_can_fixed_function(T.eq, true)); + ASSERT_EQ(T.fixed_function, pan_blend_can_fixed_function(arch, T.eq, true)); ASSERT_EQ(T.alpha_zero_nop, pan_blend_alpha_zero_nop(T.eq)); ASSERT_EQ(T.alpha_one_store, pan_blend_alpha_one_store(T.eq)); - if (pan_blend_can_fixed_function(T.eq, true)) { + if (pan_blend_can_fixed_function(arch, T.eq, true)) { ASSERT_EQ(T.hardware, pan_pack_blend(T.eq)); } } diff --git a/src/panfrost/vulkan/panvk_vX_blend.c b/src/panfrost/vulkan/panvk_vX_blend.c index 505a7213f1c..7f42708f228 100644 --- a/src/panfrost/vulkan/panvk_vX_blend.c +++ b/src/panfrost/vulkan/panvk_vX_blend.c @@ -230,7 +230,7 @@ blend_needs_shader(const struct pan_blend_state *state, unsigned rt_idx, return true; bool supports_2src = pan_blend_supports_2src(PAN_ARCH); - if (!pan_blend_can_fixed_function(rt->equation, supports_2src)) + if (!pan_blend_can_fixed_function(PAN_ARCH, rt->equation, supports_2src)) return true; unsigned constant_mask = pan_blend_constant_mask(rt->equation);