panfrost: Route format through fixed-function blending
authorAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Tue, 2 Jul 2019 13:47:13 +0000 (06:47 -0700)
committerAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Wed, 10 Jul 2019 13:12:05 +0000 (06:12 -0700)
Not all framebuffer formats are supported by the fixed-function blender.

Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
src/gallium/drivers/panfrost/pan_blending.c
src/gallium/drivers/panfrost/pan_blending.h
src/gallium/drivers/panfrost/pan_context.c

index 14f99f64eddd594668cbae6fbbdf8a98a17ba0a9..6bdc8395d186d40daea6abd2b1b1fe965d45c38b 100644 (file)
@@ -26,6 +26,7 @@
 #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 */
 
@@ -345,10 +374,20 @@ panfrost_make_constant(unsigned *factors, unsigned num_factors, const struct pip
  */
 
 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;
 
index 8ddd81147ebfd65538b9b3b7d3b96d68e38802c9..4be0c4d43854123035259d50e5ac124ab85638a4 100644 (file)
 
 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
index be5d0a14cf5a74aaa88b8d0d8b72924178fec2b4..c26a6dbaabb592fc8bacc743fe8082ef70a3be54 100644 (file)
@@ -2378,15 +2378,14 @@ panfrost_create_blend_state(struct pipe_context *pipe,
 
         /* 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);