Module: Mesa
Branch: master
Commit: e4484a0309ab44a790df29a599fb2b01eb885d5a
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=e4484a0309ab44a790df29a599fb2b01eb885d5a

Author: Chad Versace <chad.vers...@linux.intel.com>
Date:   Fri Apr  5 16:35:47 2013 -0700

intel/hsw: Enable hiz (v2)

Enable hiz by setting intel_context::has_hiz.  However, to work around
a hardware bug, we selectively enable hiz for only nicely aligned miptree
slices.

No Piglit regressions on Haswell 0x0d26 rev07 when based atop
mesa-master-4ad3601.

Improves the performance of GLB27_TRex_C24Z16_FixedTimeStep by 18.52%
(hsw-0x0d26-rev07; kernel-3.9.0-rc1; GLBenchmark 2.7.0 Release a68901;
samples=3).

v2: Replace the check for IS_HASWELL(devid) in intel_miptree_slice_has_hiz()
    with a conditional set of has_hiz. [for anholt]

Reviewed-by: Eric Anholt <e...@anholt.net>
Signed-off-by: Chad Versace <chad.vers...@linux.intel.com>

---

 src/mesa/drivers/dri/intel/intel_context.c     |    2 +-
 src/mesa/drivers/dri/intel/intel_mipmap_tree.c |   51 +++++++++++++++++++++++-
 2 files changed, 51 insertions(+), 2 deletions(-)

diff --git a/src/mesa/drivers/dri/intel/intel_context.c 
b/src/mesa/drivers/dri/intel/intel_context.c
index 990fbea..797a4c8 100644
--- a/src/mesa/drivers/dri/intel/intel_context.c
+++ b/src/mesa/drivers/dri/intel/intel_context.c
@@ -694,7 +694,7 @@ intelInitContext(struct intel_context *intel,
 
    intel->has_separate_stencil = intel->intelScreen->hw_has_separate_stencil;
    intel->must_use_separate_stencil = 
intel->intelScreen->hw_must_use_separate_stencil;
-   intel->has_hiz = intel->gen >= 6 && !intel->is_haswell;
+   intel->has_hiz = intel->gen >= 6;
    intel->has_llc = intel->intelScreen->hw_has_llc;
    intel->has_swizzling = intel->intelScreen->hw_has_swizzling;
 
diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c 
b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
index df6bade..bd31368 100644
--- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
+++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
@@ -29,6 +29,7 @@
 #include <GL/internal/dri_interface.h>
 
 #include "intel_batchbuffer.h"
+#include "intel_chipset.h"
 #include "intel_context.h"
 #include "intel_mipmap_tree.h"
 #include "intel_regions.h"
@@ -985,6 +986,53 @@ intel_miptree_alloc_mcs(struct intel_context *intel,
    return mt->mcs_mt;
 }
 
+/**
+ * Helper for intel_miptree_alloc_hiz() that sets
+ * \c mt->level[level].slice[layer].has_hiz. Return true if and only if
+ * \c has_hiz was set.
+ */
+static bool
+intel_miptree_slice_enable_hiz(struct intel_context *intel,
+                               struct intel_mipmap_tree *mt,
+                               uint32_t level,
+                               uint32_t layer)
+{
+   assert(mt->hiz_mt);
+
+   if (intel->is_haswell) {
+      /* Disable HiZ for some slices to work around a hardware bug.
+       *
+       * Haswell hardware fails to respect
+       * 3DSTATE_DEPTH_BUFFER.Depth_Coordinate_Offset_X/Y when during HiZ
+       * ambiguate operations.  The failure is inconsistent and affected by
+       * other GPU contexts. Running a heavy GPU workload in a separate
+       * process causes the failure rate to drop to nearly 0.
+       *
+       * To workaround the bug, we enable HiZ only when we can guarantee that
+       * the Depth Coordinate Offset fields will be set to 0. The function
+       * brw_get_depthstencil_tile_masks() is used to calculate the fields,
+       * and the function is sometimes called in such a way that the presence
+       * of an attached stencil buffer changes the fuction's return value.
+       *
+       * The largest tile size considered by brw_get_depthstencil_tile_masks()
+       * is that of the stencil buffer. Therefore, if this hiz slice's
+       * corresponding depth slice has an offset that is aligned to the
+       * stencil buffer tile size, 64x64 pixels, then
+       * 3DSTATE_DEPTH_BUFFER.Depth_Coordinate_Offset_X/Y is set to 0.
+       */
+      uint32_t depth_x_offset = mt->level[level].slice[layer].x_offset;
+      uint32_t depth_y_offset = mt->level[level].slice[layer].y_offset;
+      if ((depth_x_offset & 63) || (depth_y_offset & 63)) {
+         return false;
+      }
+   }
+
+   mt->level[level].slice[layer].has_hiz = true;
+   return true;
+}
+
+
+
 bool
 intel_miptree_alloc_hiz(struct intel_context *intel,
                        struct intel_mipmap_tree *mt,
@@ -1010,7 +1058,8 @@ intel_miptree_alloc_hiz(struct intel_context *intel,
    struct intel_resolve_map *head = &mt->hiz_map;
    for (int level = mt->first_level; level <= mt->last_level; ++level) {
       for (int layer = 0; layer < mt->level[level].depth; ++layer) {
-         mt->level[level].slice[layer].has_hiz = true;
+         if (!intel_miptree_slice_enable_hiz(intel, mt, level, layer))
+            continue;
 
         head->next = malloc(sizeof(*head->next));
         head->next->prev = head;

_______________________________________________
mesa-commit mailing list
mesa-commit@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-commit

Reply via email to