[Mesa-dev] [PATCH 16/29] i965/fs: Import helpers to convert vectors into arrays and back.

Francisco Jerez currojerez at riseup.net
Sat May 2 08:29:43 PDT 2015


These functions implement the memory layout of a vecN value in a
message or return payload.  The conversion is not always trivial
because the shared unit may not support the SIMD16 or SIMD4x2 vector
layouts, requiring splitting the payload in half and merging the reply
in the former case, or spreading a SIMD4x2 vector over four SIMD8
registers using a stride conversion in the latter case.

v2: Drop VEC4 suport.
---
 .../drivers/dri/i965/brw_fs_surface_builder.cpp    | 62 ++++++++++++++++++++++
 1 file changed, 62 insertions(+)

diff --git a/src/mesa/drivers/dri/i965/brw_fs_surface_builder.cpp b/src/mesa/drivers/dri/i965/brw_fs_surface_builder.cpp
index 007d5f4..b914241 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_surface_builder.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_surface_builder.cpp
@@ -214,5 +214,67 @@ namespace {
          delete[] components;
          return dst;
       }
+
+      /**
+       * Description of the layout of a vector when stored in a message
+       * payload in the form required by the recipient shared unit.
+       */
+      struct vector_layout {
+         /**
+          * Construct a vector_layout based on the current SIMD mode and
+          * whether the target shared unit supports SIMD16 messages.
+          */
+         vector_layout(const fs_builder &bld, bool has_simd16) :
+            halves(!has_simd16 && bld.dispatch_width() == 16 ? 2 : 1)
+         {
+         }
+
+         /**
+          * Number of reduced SIMD width vectors the original vector has to be
+          * divided into.  It will be equal to one if the execution dispatch
+          * width is natively supported by the shared unit.
+          */
+         unsigned halves;
+      };
+
+      /**
+       * Convert a vector into an array of registers with the layout expected
+       * by the recipient shared unit.  \p i selects the half of the payload
+       * that will be returned.
+       */
+      array_reg
+      emit_insert(const vector_layout &layout,
+                  const fs_builder &bld,
+                  const fs_reg &src,
+                  unsigned size, unsigned i = 0)
+      {
+         assert(i < layout.halves);
+         const array_reg tmp = emit_flatten(bld, src, size);
+
+         if (layout.halves > 1 && tmp.file != BAD_FILE)
+            return emit_stride(bld.half(i), offset(tmp, i),
+                               size, 1, layout.halves);
+         else
+            return tmp;
+      }
+
+      /**
+       * Convert an array of registers back into a vector according to the
+       * layout expected from some shared unit.  The \p srcs array should
+       * contain the halves of the payload as individual array registers.
+       */
+      fs_reg
+      emit_extract(const vector_layout &layout,
+                   const fs_builder &bld,
+                   const array_reg srcs[],
+                   unsigned size)
+      {
+         if (layout.halves > 1 &&
+             srcs[0].file != BAD_FILE && srcs[1].file != BAD_FILE)
+            return natural_reg(bld,
+                               emit_zip(bld.half(0), srcs[0], srcs[1], size));
+         else
+            return natural_reg(bld, srcs[0]);
+      }
    }
 }
-- 
2.3.5



More information about the mesa-dev mailing list