[Mesa-dev] [PATCH 08/23] i965: Import helpers to convert vectors into arrays and back.

Francisco Jerez currojerez at riseup.net
Tue Apr 28 11:44:19 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.
---
 src/mesa/drivers/dri/i965/brw_ir_surface_builder.h | 100 +++++++++++++++++++++
 1 file changed, 100 insertions(+)

diff --git a/src/mesa/drivers/dri/i965/brw_ir_surface_builder.h b/src/mesa/drivers/dri/i965/brw_ir_surface_builder.h
index b2c0043..b6890b4 100644
--- a/src/mesa/drivers/dri/i965/brw_ir_surface_builder.h
+++ b/src/mesa/drivers/dri/i965/brw_ir_surface_builder.h
@@ -182,6 +182,106 @@ namespace brw {
          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 SIMD4x2 and SIMD16
+          * vector arrangements.
+          */
+         vector_layout(const svec4_builder &bld,
+                       bool has_simd4x2, bool has_simd16) :
+            halves(!has_simd16 && bld.dispatch_width() == 16 ? 2 : 1),
+            stride(1)
+         {
+         }
+
+         vector_layout(const vec4_builder &bld,
+                       bool has_simd4x2, bool has_simd16) :
+            halves(1),
+            stride(has_simd4x2 ? 1 : 4)
+         {
+         }
+
+         /**
+          * 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;
+
+         /**
+          * Number of components to skip over in the payload for each
+          * component of the value.  It will be equal to one except for
+          * SIMD8-only messages in SIMD4x2 mode.
+          */
+         unsigned stride;
+      };
+
+      /**
+       * 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.
+       */
+      inline array_reg
+      emit_insert(const vector_layout &layout,
+                  const svec4_builder &bld,
+                  const src_svec4 &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;
+      }
+
+      inline array_reg
+      emit_insert(const vector_layout &layout,
+                  const vec4_builder &bld,
+                  const src_reg &src,
+                  unsigned size, unsigned i = 0)
+      {
+         assert(i == 0);
+         const array_reg tmp = emit_flatten(bld, src, size);
+         return emit_stride(bld, tmp, size, layout.stride, 1);
+      }
+
+      /**
+       * 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.
+       */
+      inline src_svec4
+      emit_extract(const vector_layout &layout,
+                   const svec4_builder &bld,
+                   const array_reg srcs[],
+                   unsigned size)
+      {
+         if (layout.halves > 1)
+            return bld.natural_reg(emit_zip(bld.half(0), srcs[0], srcs[1],
+                                            size));
+         else
+            return bld.natural_reg(srcs[0]);
+      }
+
+      inline src_reg
+      emit_extract(const vector_layout &layout,
+                   const vec4_builder &bld,
+                   const array_reg srcs[],
+                   unsigned size)
+      {
+         return resize(bld.natural_reg(emit_stride(bld, srcs[0],
+                                                   size, 1, layout.stride)),
+                       size);
+      }
    }
 }
 
-- 
2.3.5



More information about the mesa-dev mailing list