panfrost/midgard: Skip blend for REPLACE (shader)
authorAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Tue, 2 Jul 2019 16:48:19 +0000 (09:48 -0700)
committerAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Wed, 10 Jul 2019 13:12:06 +0000 (06:12 -0700)
Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
src/gallium/drivers/panfrost/midgard/nir_lower_blend.c

index af0a7ac31cf90c4e496163dbf9850f2ece9b775e..0fadeba6674a8328cdfb393f7ba3fbb2330fe726 100644 (file)
@@ -200,12 +200,35 @@ nir_blend(
    return nir_color_mask(b, options.rt[0].colormask, blended, dst);
 }
 
+static bool
+nir_is_blend_channel_replace(nir_lower_blend_channel chan)
+{
+   return
+      (chan.src_factor == BLEND_FACTOR_ZERO) &&
+      (chan.dst_factor == BLEND_FACTOR_ZERO) &&
+      (chan.invert_src_factor && !chan.invert_dst_factor) &&
+      (chan.func == BLEND_FUNC_ADD || chan.func == BLEND_FUNC_SUBTRACT || chan.func == BLEND_FUNC_MAX);
+}
+
+static bool
+nir_is_blend_replace(nir_lower_blend_options options)
+{
+   return
+      nir_is_blend_channel_replace(options.rt[0].rgb) &&
+      nir_is_blend_channel_replace(options.rt[0].alpha);
+}
+
 void
 nir_lower_blend(nir_shader *shader, nir_lower_blend_options options)
 {
    /* Blend shaders are represented as special fragment shaders */
    assert(shader->info.stage == MESA_SHADER_FRAGMENT);
 
+   /* Special case replace, since there's nothing to do and we don't want to
+    * degrade intermediate precision (e.g. for non-blendable R32F targets) */
+   if (nir_is_blend_replace(options))
+      return;
+
    nir_foreach_function(func, shader) {
       nir_foreach_block(block, func->impl) {
          nir_foreach_instr_safe(instr, block) {