intel: Add resolve functions for miptrees
authorChad Versace <chad.versace@linux.intel.com>
Wed, 16 Nov 2011 02:20:02 +0000 (18:20 -0800)
committerChad Versace <chad.versace@linux.intel.com>
Tue, 22 Nov 2011 18:50:49 +0000 (10:50 -0800)
Add functions that
   - set a miptree slice as needing a resolve
   - resolve a single slice of a miptree
   - resolve all slices of a miptree

Reviewed-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Chad Versace <chad.versace@linux.intel.com>
src/mesa/drivers/dri/intel/intel_mipmap_tree.c
src/mesa/drivers/dri/intel/intel_mipmap_tree.h

index 900b260cdf9a56733df447350d42c8153295569c..b4f6bb31897b4a084ad2bc2d401476e609ecc74d 100644 (file)
@@ -29,6 +29,7 @@
 #include "intel_context.h"
 #include "intel_mipmap_tree.h"
 #include "intel_regions.h"
+#include "intel_resolve_map.h"
 #include "intel_span.h"
 #include "intel_tex_layout.h"
 #include "intel_tex.h"
@@ -41,7 +42,6 @@
 
 #define FILE_DEBUG_FLAG DEBUG_MIPTREE
 
-
 static GLenum
 target_to_target(GLenum target)
 {
@@ -263,6 +263,7 @@ intel_miptree_release(struct intel_mipmap_tree **mt)
       intel_region_release(&((*mt)->region));
       intel_miptree_release(&(*mt)->stencil_mt);
       intel_miptree_release(&(*mt)->hiz_mt);
+      intel_resolve_map_clear(&(*mt)->hiz_map);
 
       for (i = 0; i < MAX_TEXTURE_LEVELS; i++) {
         free((*mt)->level[i].slice);
@@ -595,3 +596,118 @@ intel_miptree_alloc_hiz(struct intel_context *intel,
                                      true);
    return mt->hiz_mt != NULL;
 }
+
+void
+intel_miptree_slice_set_needs_hiz_resolve(struct intel_mipmap_tree *mt,
+                                         uint32_t level,
+                                         uint32_t layer)
+{
+   intel_miptree_check_level_layer(mt, level, layer);
+
+   if (!mt->hiz_mt)
+      return;
+
+   intel_resolve_map_set(&mt->hiz_map,
+                        level, layer, INTEL_NEED_HIZ_RESOLVE);
+}
+
+
+void
+intel_miptree_slice_set_needs_depth_resolve(struct intel_mipmap_tree *mt,
+                                            uint32_t level,
+                                            uint32_t layer)
+{
+   intel_miptree_check_level_layer(mt, level, layer);
+
+   if (!mt->hiz_mt)
+      return;
+
+   intel_resolve_map_set(&mt->hiz_map,
+                        level, layer, INTEL_NEED_DEPTH_RESOLVE);
+}
+
+typedef void (*resolve_func_t)(struct intel_context *intel,
+                              struct intel_mipmap_tree *mt,
+                              uint32_t level,
+                              uint32_t layer);
+
+static bool
+intel_miptree_slice_resolve(struct intel_context *intel,
+                           struct intel_mipmap_tree *mt,
+                           uint32_t level,
+                           uint32_t layer,
+                           enum intel_need_resolve need,
+                           resolve_func_t func)
+{
+   intel_miptree_check_level_layer(mt, level, layer);
+
+   struct intel_resolve_map *item =
+        intel_resolve_map_get(&mt->hiz_map, level, layer);
+
+   if (!item || item->need != need)
+      return false;
+
+   func(intel, mt, level, layer);
+   intel_resolve_map_remove(item);
+   return true;
+}
+
+bool
+intel_miptree_slice_resolve_hiz(struct intel_context *intel,
+                               struct intel_mipmap_tree *mt,
+                               uint32_t level,
+                               uint32_t layer)
+{
+   return intel_miptree_slice_resolve(intel, mt, level, layer,
+                                     INTEL_NEED_HIZ_RESOLVE,
+                                     intel->vtbl.resolve_hiz_slice);
+}
+
+bool
+intel_miptree_slice_resolve_depth(struct intel_context *intel,
+                                 struct intel_mipmap_tree *mt,
+                                 uint32_t level,
+                                 uint32_t layer)
+{
+   return intel_miptree_slice_resolve(intel, mt, level, layer,
+                                     INTEL_NEED_DEPTH_RESOLVE,
+                                     intel->vtbl.resolve_depth_slice);
+}
+
+static bool
+intel_miptree_all_slices_resolve(struct intel_context *intel,
+                                struct intel_mipmap_tree *mt,
+                                enum intel_need_resolve need,
+                                resolve_func_t func)
+{
+   bool did_resolve = false;
+   struct intel_resolve_map *i;
+
+   for (i = mt->hiz_map.next; i; i = i->next) {
+      if (i->need != need)
+        continue;
+      func(intel, mt, i->level, i->layer);
+      intel_resolve_map_remove(i);
+      did_resolve = true;
+   }
+
+   return did_resolve;
+}
+
+bool
+intel_miptree_all_slices_resolve_hiz(struct intel_context *intel,
+                                    struct intel_mipmap_tree *mt)
+{
+   return intel_miptree_all_slices_resolve(intel, mt,
+                                          INTEL_NEED_HIZ_RESOLVE,
+                                          intel->vtbl.resolve_hiz_slice);
+}
+
+bool
+intel_miptree_all_slices_resolve_depth(struct intel_context *intel,
+                                      struct intel_mipmap_tree *mt)
+{
+   return intel_miptree_all_slices_resolve(intel, mt,
+                                          INTEL_NEED_DEPTH_RESOLVE,
+                                          intel->vtbl.resolve_depth_slice);
+}
index 9531f20297c887e595b8c0108d51e20984cea033..2cecd29f33e55201c8576370e040f7fe1c5d5c0d 100644 (file)
@@ -284,15 +284,72 @@ intel_miptree_s8z24_gather(struct intel_context *intel,
                            uint32_t level,
                            uint32_t layer);
 
+/**
+ * \name Miptree HiZ functions
+ * \{
+ *
+ * It is safe to call the "slice_set_need_resolve" and "slice_resolve"
+ * functions on a miptree without HiZ. In that case, each function is a no-op.
+ */
+
 /**
  * \brief Allocate the miptree's embedded HiZ miptree.
  * \see intel_mipmap_tree:hiz_mt
  * \return false if allocation failed
  */
+
 bool
 intel_miptree_alloc_hiz(struct intel_context *intel,
                        struct intel_mipmap_tree *mt);
 
+void
+intel_miptree_slice_set_needs_hiz_resolve(struct intel_mipmap_tree *mt,
+                                          uint32_t level,
+                                         uint32_t depth);
+void
+intel_miptree_slice_set_needs_depth_resolve(struct intel_mipmap_tree *mt,
+                                            uint32_t level,
+                                           uint32_t depth);
+void
+intel_miptree_all_slices_set_need_hiz_resolve(struct intel_mipmap_tree *mt);
+
+void
+intel_miptree_all_slices_set_need_depth_resolve(struct intel_mipmap_tree *mt);
+
+/**
+ * \return false if no resolve was needed
+ */
+bool
+intel_miptree_slice_resolve_hiz(struct intel_context *intel,
+                               struct intel_mipmap_tree *mt,
+                               unsigned int level,
+                               unsigned int depth);
+
+/**
+ * \return false if no resolve was needed
+ */
+bool
+intel_miptree_slice_resolve_depth(struct intel_context *intel,
+                                 struct intel_mipmap_tree *mt,
+                                 unsigned int level,
+                                 unsigned int depth);
+
+/**
+ * \return false if no resolve was needed
+ */
+bool
+intel_miptree_all_slices_resolve_hiz(struct intel_context *intel,
+                                    struct intel_mipmap_tree *mt);
+
+/**
+ * \return false if no resolve was needed
+ */
+bool
+intel_miptree_all_slices_resolve_depth(struct intel_context *intel,
+                                      struct intel_mipmap_tree *mt);
+
+/**\}*/
+
 /* i915_mipmap_tree.c:
  */
 void i915_miptree_layout(struct intel_mipmap_tree *mt);