anv/gen11: Emit SLICE_HASH_TABLE when pipes are unbalanced.
authorRafael Antognolli <rafael.antognolli@intel.com>
Mon, 22 Jul 2019 17:56:53 +0000 (10:56 -0700)
committerRafael Antognolli <rafael.antognolli@intel.com>
Mon, 12 Aug 2019 23:19:08 +0000 (16:19 -0700)
If the pixel pipes have a different number of subslices, emit a slice
hashing table that will ensure proper workload distribution.

v2: Don't need to set the mask - it's mbo (Ken).

src/intel/vulkan/anv_device.c
src/intel/vulkan/anv_private.h
src/intel/vulkan/genX_state.c

index 9154c1ab5a7431d3a2a40ee598101d3b2edc6964..c55b5233cc77d2d7cbf94255d9fee5d79fa95083 100644 (file)
@@ -2596,6 +2596,7 @@ void anv_DestroyDevice(
     * BO will go away in a couple of lines so we don't actually leak.
     */
    anv_state_pool_free(&device->dynamic_state_pool, device->border_colors);
+   anv_state_pool_free(&device->dynamic_state_pool, device->slice_hash);
 #endif
 
    anv_scratch_pool_finish(device, &device->scratch_pool);
index 85cf7ea9b6ddda8f4a557d8949a63bb366babddd..78b5b0793e5b1f34addae3e5b8e799725d746c63 100644 (file)
@@ -1139,6 +1139,8 @@ struct anv_device {
 
     struct anv_state                            border_colors;
 
+    struct anv_state                            slice_hash;
+
     struct anv_queue                            queue;
 
     struct anv_scratch_pool                     scratch_pool;
index 496c63afa6723c5b7a9b6f369a00722deff23294..de8b753dd34b306e5dee66dd7e67d6bbe4548648 100644 (file)
@@ -88,6 +88,79 @@ gen10_emit_wa_lri_to_cache_mode_zero(struct anv_batch *batch)
 }
 #endif
 
+static void
+genX(emit_slice_hashing_state)(struct anv_device *device,
+                               struct anv_batch *batch)
+{
+#if GEN_GEN == 11
+   const unsigned *ppipe_subslices = device->info.ppipe_subslices;
+   int subslices_delta = ppipe_subslices[0] - ppipe_subslices[1];
+   if (subslices_delta == 0)
+      return;
+
+   unsigned size = GENX(SLICE_HASH_TABLE_length) * 4;
+   device->slice_hash =
+      anv_state_pool_alloc(&device->dynamic_state_pool, size, 64);
+
+   struct GENX(SLICE_HASH_TABLE) table0 = {
+      .Entry = {
+         { 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1 },
+         { 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1 },
+         { 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0 },
+         { 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1 },
+         { 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1 },
+         { 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0 },
+         { 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1 },
+         { 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1 },
+         { 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0 },
+         { 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1 },
+         { 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1 },
+         { 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0 },
+         { 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1 },
+         { 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1 },
+         { 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0 },
+         { 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1 }
+      }
+   };
+
+   struct GENX(SLICE_HASH_TABLE) table1 = {
+      .Entry = {
+         { 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0 },
+         { 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0 },
+         { 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1 },
+         { 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0 },
+         { 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0 },
+         { 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1 },
+         { 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0 },
+         { 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0 },
+         { 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1 },
+         { 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0 },
+         { 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0 },
+         { 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1 },
+         { 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0 },
+         { 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0 },
+         { 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1 },
+         { 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0 }
+      }
+   };
+
+   const struct GENX(SLICE_HASH_TABLE) *table =
+      subslices_delta < 0 ? &table0 : &table1;
+   GENX(SLICE_HASH_TABLE_pack)(NULL, device->slice_hash.map, table);
+
+   anv_batch_emit(batch, GENX(3DSTATE_SLICE_TABLE_STATE_POINTERS), ptr) {
+      ptr.SliceHashStatePointerValid = true;
+      ptr.SliceHashTableStatePointer = device->slice_hash.offset;
+   }
+
+   anv_batch_emit(batch, GENX(3DSTATE_3D_MODE), mode) {
+      mode.SliceHashingTableEnable = true;
+   }
+#else
+   device->slice_hash = (struct anv_state) { 0 };
+#endif
+}
+
 VkResult
 genX(init_device_state)(struct anv_device *device)
 {
@@ -211,7 +284,9 @@ genX(init_device_state)(struct anv_device *device)
       lri.RegisterOffset = GENX(SLICE_COMMON_ECO_CHICKEN1_num);
       lri.DataDWord      = slice_common_eco_chicken1;
    }
+
 #endif
+   genX(emit_slice_hashing_state)(device, &batch);
 
 #if GEN_GEN >= 11
    /* hardware specification recommends disabling repacking for