panfrost: Dual source blend support
authorIcecream95 <ixn@keemail.me>
Thu, 25 Jun 2020 10:56:14 +0000 (22:56 +1200)
committerMarge Bot <eric+marge@anholt.net>
Wed, 15 Jul 2020 01:30:00 +0000 (01:30 +0000)
Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5620>

docs/features.txt
src/gallium/drivers/panfrost/nir/nir_lower_blend.c
src/gallium/drivers/panfrost/nir/nir_lower_blend.h
src/gallium/drivers/panfrost/pan_blend_shaders.c
src/gallium/drivers/panfrost/pan_screen.c

index 9af96985be60092c1929034ac9252e406cfc8251..e147967d420d1f073832d6bf9071863df7f72ab5 100644 (file)
@@ -99,7 +99,7 @@ GL 3.2, GLSL 1.50 --- all DONE: i965, nv50, nvc0, r600, radeonsi, llvmpipe, soft
 
 GL 3.3, GLSL 3.30 --- all DONE: i965, nv50, nvc0, r600, radeonsi, llvmpipe, softpipe, virgl
 
-  GL_ARB_blend_func_extended                            DONE (freedreno/a3xx, swr, zink)
+  GL_ARB_blend_func_extended                            DONE (freedreno/a3xx, swr, zink, panfrost)
   GL_ARB_explicit_attrib_location                       DONE (all drivers that support GLSL)
   GL_ARB_occlusion_query2                               DONE (freedreno, swr, v3d, zink, panfrost)
   GL_ARB_sampler_objects                                DONE (all drivers)
index 13cef5d6e1413fa90d6c4ae5969ae0da7a030ebe..a325a77fa874ed80607225f6da443498eb6a9506 100644 (file)
@@ -95,7 +95,7 @@ nir_alpha_saturate(
 static nir_ssa_def *
 nir_blend_factor_value(
    nir_builder *b,
-   nir_ssa_def *src, nir_ssa_def *dst, nir_ssa_def *bconst,
+   nir_ssa_def *src, nir_ssa_def *src1, nir_ssa_def *dst, nir_ssa_def *bconst,
    unsigned chan,
    enum blend_factor factor,
    bool half)
@@ -105,10 +105,14 @@ nir_blend_factor_value(
       return half ? nir_imm_float16(b, 0.0) : nir_imm_float(b, 0.0);
    case BLEND_FACTOR_SRC_COLOR:
       return nir_channel(b, src, chan);
+   case BLEND_FACTOR_SRC1_COLOR:
+      return nir_channel(b, src1, chan);
    case BLEND_FACTOR_DST_COLOR:
       return nir_channel(b, dst, chan);
    case BLEND_FACTOR_SRC_ALPHA:
       return nir_channel(b, src, 3);
+   case BLEND_FACTOR_SRC1_ALPHA:
+      return nir_channel(b, src1, 3);
    case BLEND_FACTOR_DST_ALPHA:
       return nir_channel(b, dst, 3);
    case BLEND_FACTOR_CONSTANT_COLOR:
@@ -126,14 +130,14 @@ static nir_ssa_def *
 nir_blend_factor(
    nir_builder *b,
    nir_ssa_def *raw_scalar,
-   nir_ssa_def *src, nir_ssa_def *dst, nir_ssa_def *bconst,
+   nir_ssa_def *src, nir_ssa_def *src1, nir_ssa_def *dst, nir_ssa_def *bconst,
    unsigned chan,
    enum blend_factor factor,
    bool inverted,
    bool half)
 {
    nir_ssa_def *f =
-      nir_blend_factor_value(b, src, dst, bconst, chan, factor, half);
+      nir_blend_factor_value(b, src, src1, dst, bconst, chan, factor, half);
 
    nir_ssa_def *unity = half ? nir_imm_float16(b, 1.0) : nir_imm_float(b, 1.0);
 
@@ -256,7 +260,7 @@ static nir_ssa_def *
 nir_blend(
    nir_builder *b,
    nir_lower_blend_options options,
-   nir_ssa_def *src, nir_ssa_def *dst)
+   nir_ssa_def *src, nir_ssa_def *src1, nir_ssa_def *dst)
 {
    if (options.logicop_enable)
       return nir_blend_logicop(b, options, src, dst);
@@ -281,12 +285,12 @@ nir_blend(
       if (nir_blend_factored(chan.func)) {
          psrc = nir_blend_factor(
                    b, psrc,
-                   src, dst, bconst, c,
+                   src, src1, dst, bconst, c,
                    chan.src_factor, chan.invert_src_factor, options.half);
 
          pdst = nir_blend_factor(
                    b, pdst,
-                   src, dst, bconst, c,
+                   src, src1, dst, bconst, c,
                    chan.dst_factor, chan.invert_dst_factor, options.half);
       }
 
@@ -349,11 +353,14 @@ nir_lower_blend(nir_shader *shader, nir_lower_blend_options options)
             /* Grab the input color */
             nir_ssa_def *src = nir_ssa_for_src(&b, intr->src[1], 4);
 
+            /* Grab the dual-source input color */
+            nir_ssa_def *src1 = options.src1;
+
             /* Grab the tilebuffer color - io lowered to load_output */
             nir_ssa_def *dst = nir_load_var(&b, var);
 
             /* Blend the two colors per the passed options */
-            nir_ssa_def *blended = nir_blend(&b, options, src, dst);
+            nir_ssa_def *blended = nir_blend(&b, options, src, src1, dst);
 
             /* Write out the final color instead of the input */
             nir_instr_rewrite_src(instr, &intr->src[1],
index 4bce2cc79b8a15311eca3dc59b4b575fa82dfd88..f015bba147311866bc19a261f5e3078bd0bc7727 100644 (file)
@@ -55,6 +55,8 @@ typedef struct {
 
    /* Use fp16 instead of fp32 */
    bool half;
+
+   nir_ssa_def *src1;
 } nir_lower_blend_options;
 
 void nir_lower_blend(nir_shader *shader, nir_lower_blend_options options);
index 32132e22ecd684ab1af126064c6ffd24c850f36d..74aac4ebb38b1c356048da81afe8550d98bc3120 100644 (file)
@@ -165,11 +165,15 @@ panfrost_compile_blend_shader(
         /* Create the blend variables */
 
         nir_variable *c_src = nir_variable_create(shader, nir_var_shader_in, glsl_vector_type(GLSL_TYPE_FLOAT, 4), "gl_Color");
+        nir_variable *c_src1 = nir_variable_create(shader, nir_var_shader_in, glsl_vector_type(GLSL_TYPE_FLOAT, 4), "gl_Color1");
         nir_variable *c_out = nir_variable_create(shader, nir_var_shader_out, glsl_vector_type(g, 4), "gl_FragColor");
 
         c_src->data.location = VARYING_SLOT_COL0;
+        c_src1->data.location = VARYING_SLOT_VAR0;
         c_out->data.location = FRAG_RESULT_COLOR;
 
+        c_src1->data.driver_location = 1;
+
         /* Setup nir_builder */
 
         nir_builder _b;
@@ -179,25 +183,28 @@ panfrost_compile_blend_shader(
 
         /* Setup inputs */
 
-        nir_ssa_def *s_src = nir_load_var(b, c_src);
-
-        if (T == nir_type_float16)
-                s_src = nir_f2f16(b, s_src);
-        else if (T == nir_type_int16)
-                s_src = nir_i2i16(b, nir_iclamp(b, s_src, -32768, 32767));
-        else if (T == nir_type_uint16)
-                s_src = nir_u2u16(b, nir_umin(b, s_src, nir_imm_int(b, 65535)));
-        else if (T == nir_type_int8)
-                s_src = nir_i2i8(b, nir_iclamp(b, s_src, -128, 127));
-        else if (T == nir_type_uint8)
-                s_src = nir_u2u8(b, nir_umin(b, s_src, nir_imm_int(b, 255)));
+        nir_ssa_def *s_src[] = {nir_load_var(b, c_src), nir_load_var(b, c_src1)};
+
+        for (int i = 0; i < ARRAY_SIZE(s_src); ++i) {
+                if (T == nir_type_float16)
+                        s_src[i] = nir_f2f16(b, s_src[i]);
+                else if (T == nir_type_int16)
+                        s_src[i] = nir_i2i16(b, nir_iclamp(b, s_src[i], -32768, 32767));
+                else if (T == nir_type_uint16)
+                        s_src[i] = nir_u2u16(b, nir_umin(b, s_src[i], nir_imm_int(b, 65535)));
+                else if (T == nir_type_int8)
+                        s_src[i] = nir_i2i8(b, nir_iclamp(b, s_src[i], -128, 127));
+                else if (T == nir_type_uint8)
+                        s_src[i] = nir_u2u8(b, nir_umin(b, s_src[i], nir_imm_int(b, 255)));
+        }
 
         /* Build a trivial blend shader */
-        nir_store_var(b, c_out, s_src, 0xFF);
+        nir_store_var(b, c_out, s_src[0], 0xFF);
 
         nir_lower_blend_options options =
                 nir_make_options(cso, rt);
         options.format = format;
+        options.src1 = s_src[1];
 
         if (T == nir_type_float16)
                 options.half = true;
index 1cb7fc3cbda996c84be0628f9b815c17bfa370eb..e22363ff533c7ff9dda0e74d531f4a4cd4583f43 100644 (file)
@@ -120,7 +120,7 @@ panfrost_get_param(struct pipe_screen *screen, enum pipe_cap param)
                 return is_gles3 ? 4 : 1;
 
         case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
-                return is_gl3 ? 1 : 0;
+                return 1;
 
         /* Throttling frames breaks pipelining */
         case PIPE_CAP_THROTTLE: