r600/sfn: use correct FS output location if not all outputs are used
authorGert Wollny <gert.wollny@collabora.com>
Tue, 16 May 2023 16:41:09 +0000 (18:41 +0200)
committerMarge Bot <emma+marge@anholt.net>
Thu, 18 May 2023 06:09:50 +0000 (06:09 +0000)
Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/8973

Fixes 79ca456b4837b3bc21cf9ef3c03c505c4b4909f6
    r600/sfn: rewrite NIR backend

Signed-off-by: Gert Wollny <gert.wollny@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23058>

src/gallium/drivers/r600/sfn/sfn_shader_fs.cpp

index 010b546..15e4c13 100644 (file)
@@ -508,19 +508,22 @@ FragmentShader::emit_export_pixel(nir_intrinsic_instr& intr)
 
       for (unsigned k = 0; k < color_outputs; ++k) {
 
-         unsigned location =
-            (m_dual_source_blend && (semantics.location == FRAG_RESULT_COLOR)
-                ? semantics.dual_source_blend_index
-                : driver_location) + k;
+         unsigned location = semantics.location - FRAG_RESULT_DATA0;
 
-         sfn_log << SfnLog::io << "Pixel output at loc:" << location << "\n";
+         if (semantics.location == FRAG_RESULT_COLOR)
+            location = driver_location + k;
+
+         if (semantics.dual_source_blend_index)
+            location = semantics.dual_source_blend_index;
+
+         sfn_log << SfnLog::io << "Pixel output at loc:" << location
+                 << "("<< semantics.location << ") of "<< m_max_color_exports<<"\n";
 
          if (location >= m_max_color_exports) {
             sfn_log << SfnLog::io << "Pixel output loc:" << location
                     << " dl:" << driver_location << " skipped  because  we have only "
                     << m_max_color_exports << " CBs\n";
             return true;
-            ;
          }
 
          m_last_pixel_export = new ExportInstr(ExportInstr::pixel, location, value);
@@ -532,13 +535,19 @@ FragmentShader::emit_export_pixel(nir_intrinsic_instr& intr)
 
          /* Hack: force dual source output handling if one color output has a
           * dual_source_blend_index > 0 */
-         if (semantics.location == FRAG_RESULT_COLOR &&
-             semantics.dual_source_blend_index > 0)
+         if (semantics.dual_source_blend_index > 0)
             m_dual_source_blend = true;
 
          if (m_num_color_exports > 1)
             m_fs_write_all = false;
          unsigned mask = (0xfu << (location * 4));
+
+         /* If the i-th target format is set, all previous target formats must
+          * be non-zero to avoid hangs. - from radeonsi, seems to apply to eg as well.
+          /*/
+         for (unsigned i = 0; i < location; ++i)
+            mask |= (0x1u << (i * 4));
+
          m_color_export_mask |= mask;
 
          emit_instruction(m_last_pixel_export);