intel: pass zslice to intel_miptree_image_offset()
[mesa.git] / src / mesa / drivers / dri / intel / intel_mipmap_tree.c
index c985da5aa25d90e9daf695dafe4a17a616beb8e1..d9d2edfe190ee218eb7c0971017f3987a0d08f5b 100644 (file)
@@ -29,6 +29,9 @@
 #include "intel_mipmap_tree.h"
 #include "intel_regions.h"
 #include "intel_chipset.h"
+#ifndef I915
+#include "brw_state.h"
+#endif
 #include "main/enums.h"
 
 #define FILE_DEBUG_FLAG DEBUG_MIPTREE
@@ -269,6 +272,19 @@ intel_miptree_release(struct intel_context *intel,
 
       DBG("%s deleting %p\n", __FUNCTION__, *mt);
 
+#ifndef I915
+      /* Free up cached binding tables holding a reference on our buffer, to
+       * avoid excessive memory consumption.
+       *
+       * This isn't as aggressive as we could be, as we'd like to do
+       * it from any time we free the last ref on a region.  But intel_region.c
+       * is context-agnostic.  Perhaps our constant state cache should be, as
+       * well.
+       */
+      brw_state_cache_bo_delete(&brw_context(&intel->ctx)->surface_cache,
+                               (*mt)->region->buffer);
+#endif
+
       intel_region_release(&((*mt)->region));
 
       for (i = 0; i < MAX_TEXTURE_LEVELS; i++)
@@ -379,33 +395,26 @@ intel_miptree_set_image_offset(struct intel_mipmap_tree *mt,
 }
 
 
-/* Although we use the image_offset[] array to store relative offsets
- * to cube faces, Mesa doesn't know anything about this and expects
- * each cube face to be treated as a separate image.
- *
- * These functions present that view to mesa:
+/**
+ * Return offset to the start of a 2D slice of a texture (a mipmap level,
+ * cube face, 3D Z slice).
+ * \param mt  the texture object/miptree
+ * \param face  cube map face in [0,5] or zero for non-cube textures
+ * \param level  mipmap level
+ * \param zslice  Z slice of a 3D texture, or zero for non-3D textures
  */
-const GLuint *
-intel_miptree_depth_offsets(struct intel_mipmap_tree *mt, GLuint level)
-{
-   static const GLuint zero = 0;
-
-   if (mt->target != GL_TEXTURE_3D || mt->level[level].nr_images == 1)
-      return &zero;
-   else
-      return mt->level[level].image_offset;
-}
-
-
 GLuint
-intel_miptree_image_offset(struct intel_mipmap_tree *mt,
-                          GLuint face, GLuint level)
+intel_miptree_image_offset(const struct intel_mipmap_tree *mt,
+                           GLuint face, GLuint level, GLuint zslice)
 {
+   GLuint offset = mt->level[level].level_offset;
+
    if (mt->target == GL_TEXTURE_CUBE_MAP_ARB)
-      return (mt->level[level].level_offset +
-             mt->level[level].image_offset[face]);
-   else
-      return mt->level[level].level_offset;
+      offset += mt->level[level].image_offset[face];
+   else if (mt->target == GL_TEXTURE_3D)
+      offset += mt->level[level].image_offset[zslice];
+
+   return offset;
 }
 
 
@@ -443,7 +452,7 @@ intel_miptree_image_map(struct intel_context * intel,
    }
 
    return (intel_region_map(intel, mt->region) +
-           intel_miptree_image_offset(mt, face, level));
+           intel_miptree_image_offset(mt, face, level, 0));
 }
 
 void
@@ -468,19 +477,18 @@ intel_miptree_image_data(struct intel_context *intel,
                         GLuint src_image_pitch)
 {
    GLuint depth = dst->level[level].depth;
-   GLuint dst_offset = intel_miptree_image_offset(dst, face, level);
-   const GLuint *dst_depth_offset = intel_miptree_depth_offsets(dst, level);
    GLuint i;
    GLuint height = 0;
 
    DBG("%s: %d/%d\n", __FUNCTION__, face, level);
    for (i = 0; i < depth; i++) {
+      GLuint dst_offset = intel_miptree_image_offset(dst, face, level, i);
       height = dst->level[level].height;
       if(dst->compressed)
         height = (height + 3) / 4;
       intel_region_data(intel,
                        dst->region,
-                       dst_offset + dst_depth_offset[i], /* dst_offset */
+                       dst_offset,
                        0, 0,                             /* dstx, dsty */
                        src,
                        src_row_pitch,
@@ -503,10 +511,6 @@ intel_miptree_image_copy(struct intel_context *intel,
    GLuint width = src->level[level].width;
    GLuint height = src->level[level].height;
    GLuint depth = src->level[level].depth;
-   GLuint dst_offset = intel_miptree_image_offset(dst, face, level);
-   GLuint src_offset = intel_miptree_image_offset(src, face, level);
-   const GLuint *dst_depth_offset = intel_miptree_depth_offsets(dst, level);
-   const GLuint *src_depth_offset = intel_miptree_depth_offsets(src, level);
    GLuint i;
    GLboolean success;
 
@@ -519,10 +523,13 @@ intel_miptree_image_copy(struct intel_context *intel,
    }
 
    for (i = 0; i < depth; i++) {
+      GLuint dst_offset = intel_miptree_image_offset(dst, face, level, i);
+      GLuint src_offset = intel_miptree_image_offset(src, face, level, i);
+
       success = intel_region_copy(intel,
-                                 dst->region, dst_offset + dst_depth_offset[i],
+                                 dst->region, dst_offset,
                                  0, 0,
-                                 src->region, src_offset + src_depth_offset[i],
+                                 src->region, src_offset,
                                  0, 0, width, height, GL_COPY);
       if (!success) {
         GLubyte *src_ptr, *dst_ptr;
@@ -530,11 +537,11 @@ intel_miptree_image_copy(struct intel_context *intel,
         src_ptr = intel_region_map(intel, src->region);
         dst_ptr = intel_region_map(intel, dst->region);
 
-        _mesa_copy_rect(dst_ptr + dst_offset + dst_depth_offset[i],
+        _mesa_copy_rect(dst_ptr + dst_offset,
                         dst->cpp,
                         dst->pitch,
                         0, 0, width, height,
-                        src_ptr + src_offset + src_depth_offset[i],
+                        src_ptr + src_offset,
                         src->pitch,
                         0, 0);
         intel_region_unmap(intel, src->region);