#include "pan_blending.h"
#include "pan_context.h"
#include "gallium/auxiliary/util/u_blend.h"
+#include "util/u_format.h"
/*
* Implements fixed-function blending on Midgard.
* The following routines implement this fixed function blending encoding
*/
+/* Not all formats can be blended by fixed-function hardware */
+
+static bool
+panfrost_can_blend(enum pipe_format format)
+{
+ /* Fixed-function can handle sRGB */
+ format = util_format_linear(format);
+
+ /* Decompose the format */
+ const struct util_format_description *desc =
+ util_format_description(format);
+
+ /* Any 8-bit unorm is supported */
+ if (util_format_is_unorm8(desc))
+ return true;
+
+ /* Certain special formats are, too */
+ switch (format) {
+ case PIPE_FORMAT_B5G6R5_UNORM:
+ case PIPE_FORMAT_B4G4R4A4_UNORM:
+ case PIPE_FORMAT_B5G5R5A1_UNORM:
+ case PIPE_FORMAT_R10G10B10A2_UNORM:
+ return true;
+ default:
+ return false;
+ }
+}
+
/* Helper to find the uncomplemented Gallium blend factor corresponding to a
* complemented Gallium blend factor */
*/
bool
-panfrost_make_fixed_blend_mode(const struct pipe_rt_blend_state *blend, struct panfrost_blend_state *so, unsigned colormask, const struct pipe_blend_color *blend_color)
+panfrost_make_fixed_blend_mode(
+ const struct pipe_rt_blend_state *blend,
+ struct panfrost_blend_state *so,
+ unsigned colormask,
+ const struct pipe_blend_color *blend_color,
+ enum pipe_format format)
{
struct mali_blend_equation *out = &so->equation;
+ /* Check if the format supports fixed-function blending at all */
+
+ if (!panfrost_can_blend(format))
+ return false;
+
/* Gallium and Mali represent colour masks identically. XXX: Static assert for future proof */
out->color_mask = colormask;
struct panfrost_blend_state;
-bool panfrost_make_fixed_blend_mode(const struct pipe_rt_blend_state *blend, struct panfrost_blend_state *so, unsigned colormask, const struct pipe_blend_color *blend_color);
+bool panfrost_make_fixed_blend_mode(
+ const struct pipe_rt_blend_state *blend,
+ struct panfrost_blend_state *so,
+ unsigned colormask,
+ const struct pipe_blend_color *blend_color,
+ enum pipe_format format);
#endif
/* Compile the blend state, first as fixed-function if we can */
- if (panfrost_make_fixed_blend_mode(&blend->rt[0], so, blend->rt[0].colormask, &ctx->blend_color))
- return so;
+ /* TODO: Key by format */
+ enum pipe_format format = ctx->pipe_framebuffer.nr_cbufs ?
+ ctx->pipe_framebuffer.cbufs[0]->format :
+ PIPE_FORMAT_R8G8B8A8_UNORM;
- /* TODO: Key against framebuffer. TODO: MRT explicitly */
- if (!ctx->pipe_framebuffer.nr_cbufs)
+ if (panfrost_make_fixed_blend_mode(&blend->rt[0], so, blend->rt[0].colormask, &ctx->blend_color, format))
return so;
- enum pipe_format format = ctx->pipe_framebuffer.cbufs[0]->format;
-
/* If we can't, compile a blend shader instead */
panfrost_make_blend_shader(ctx, so, &ctx->blend_color, format);