intel: devinfo: store slice/subslice/eu masks
authorLionel Landwerlin <lionel.g.landwerlin@intel.com>
Wed, 14 Mar 2018 13:16:01 +0000 (13:16 +0000)
committerLionel Landwerlin <lionel.g.landwerlin@intel.com>
Thu, 22 Mar 2018 20:14:22 +0000 (20:14 +0000)
We want to store values coming from the kernel but as a first step, we
can generate mask values out the numbers already stored in the
gen_device_info masks.

v2: Add a helper to set EU masks (Lionel/Ken)

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/intel/dev/gen_device_info.c
src/intel/dev/gen_device_info.h

index 29d24ae..acf921b 100644 (file)
@@ -874,6 +874,57 @@ static const struct gen_device_info gen_device_info_icl_1x8 = {
    GEN11_FEATURES(1, 1, subslices(1), 6),
 };
 
+static void
+gen_device_info_set_eu_mask(struct gen_device_info *devinfo,
+                            unsigned slice,
+                            unsigned subslice,
+                            unsigned eu_mask)
+{
+   unsigned subslice_offset = slice * devinfo->eu_slice_stride +
+      subslice * devinfo->eu_subslice_stride;
+
+   for (unsigned b_eu = 0; b_eu < devinfo->eu_subslice_stride; b_eu++) {
+      devinfo->eu_masks[subslice_offset + b_eu] =
+         (((1U << devinfo->num_eu_per_subslice) - 1) >> (b_eu * 8)) & 0xff;
+   }
+}
+
+/* Generate slice/subslice/eu masks from number of
+ * slices/subslices/eu_per_subslices in the per generation/gt gen_device_info
+ * structure.
+ *
+ * These can be overridden with values reported by the kernel either from
+ * getparam SLICE_MASK/SUBSLICE_MASK values or from the kernel version 4.17+
+ * through the i915 query uapi.
+ */
+static void
+fill_masks(struct gen_device_info *devinfo)
+{
+   devinfo->slice_masks = (1U << devinfo->num_slices) - 1;
+
+   /* Subslice masks */
+   unsigned max_subslices = 0;
+   for (int s = 0; s < devinfo->num_slices; s++)
+      max_subslices = MAX2(devinfo->num_subslices[s], max_subslices);
+   devinfo->subslice_slice_stride = DIV_ROUND_UP(max_subslices, 8);
+
+   for (int s = 0; s < devinfo->num_slices; s++) {
+      devinfo->subslice_masks[s * devinfo->subslice_slice_stride] =
+         (1U << devinfo->num_subslices[s]) - 1;
+   }
+
+   /* EU masks */
+   devinfo->eu_subslice_stride = DIV_ROUND_UP(devinfo->num_eu_per_subslice, 8);
+   devinfo->eu_slice_stride = max_subslices * devinfo->eu_subslice_stride;
+
+   for (int s = 0; s < devinfo->num_slices; s++) {
+      for (int ss = 0; ss < devinfo->num_subslices[s]; ss++) {
+         gen_device_info_set_eu_mask(devinfo, s, ss,
+                                     (1U << devinfo->num_eu_per_subslice) - 1);
+      }
+   }
+}
+
 bool
 gen_get_device_info(int devid, struct gen_device_info *devinfo)
 {
@@ -887,6 +938,8 @@ gen_get_device_info(int devid, struct gen_device_info *devinfo)
       return false;
    }
 
+   fill_masks(devinfo);
+
    /* From the Skylake PRM, 3DSTATE_PS::Scratch Space Base Pointer:
     *
     * "Scratch Space per slice is computed based on 4 sub-slices.  SW must
index 17285ff..793ce09 100644 (file)
 #include <stdbool.h>
 #include <stdint.h>
 
+#include "util/macros.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#define GEN_DEVICE_MAX_SLICES           (6)  /* Maximum on gen10 */
+#define GEN_DEVICE_MAX_SUBSLICES        (8)  /* Maximum on gen11 */
+#define GEN_DEVICE_MAX_EUS_PER_SUBSLICE (10) /* Maximum on Haswell */
+
 /**
  * Intel hardware information and quirks
  */
@@ -112,7 +118,7 @@ struct gen_device_info
    /**
     * Number of subslices for each slice (used to be uniform until CNL).
     */
-   unsigned num_subslices[3];
+   unsigned num_subslices[GEN_DEVICE_MAX_SUBSLICES];
 
    /**
     * Number of EU per subslice.
@@ -124,6 +130,37 @@ struct gen_device_info
     */
    unsigned num_thread_per_eu;
 
+   /**
+    * A bit mask of the slices available.
+    */
+   uint8_t slice_masks;
+
+   /**
+    * An array of bit mask of the subslices available, use subslice_slice_stride
+    * to access this array.
+    */
+   uint8_t subslice_masks[GEN_DEVICE_MAX_SLICES *
+                          DIV_ROUND_UP(GEN_DEVICE_MAX_SUBSLICES, 8)];
+
+   /**
+    * An array of bit mask of EUs available, use eu_slice_stride &
+    * eu_subslice_stride to access this array.
+    */
+   uint8_t eu_masks[GEN_DEVICE_MAX_SLICES *
+                    GEN_DEVICE_MAX_SUBSLICES *
+                    DIV_ROUND_UP(GEN_DEVICE_MAX_EUS_PER_SUBSLICE, 8)];
+
+   /**
+    * Stride to access subslice_masks[].
+    */
+   uint16_t subslice_slice_stride;
+
+   /**
+    * Strides to access eu_masks[].
+    */
+   uint16_t eu_slice_stride;
+   uint16_t eu_subslice_stride;
+
    unsigned l3_banks;
    unsigned max_vs_threads;   /**< Maximum Vertex Shader threads */
    unsigned max_tcs_threads;  /**< Maximum Hull Shader threads */