intel: Convert from GLboolean to 'bool' from stdbool.h.
[mesa.git] / src / mesa / drivers / dri / intel / intel_mipmap_tree.c
index ef1966ea7e14c0136e87a1ec3bb59df08b38d7e0..d96e751fb213da071926d030fd69497dcc8fdc7e 100644 (file)
 #include "intel_mipmap_tree.h"
 #include "intel_regions.h"
 #include "intel_tex_layout.h"
-#ifndef I915
-#include "brw_state.h"
-#endif
+#include "intel_tex.h"
+#include "intel_blit.h"
 #include "main/enums.h"
+#include "main/formats.h"
+#include "main/teximage.h"
 
 #define FILE_DEBUG_FLAG DEBUG_MIPTREE
 
@@ -57,48 +58,45 @@ target_to_target(GLenum target)
 static struct intel_mipmap_tree *
 intel_miptree_create_internal(struct intel_context *intel,
                              GLenum target,
-                             GLenum internal_format,
+                             gl_format format,
                              GLuint first_level,
                              GLuint last_level,
                              GLuint width0,
                              GLuint height0,
-                             GLuint depth0, GLuint cpp, GLuint compress_byte,
-                             uint32_t tiling)
+                             GLuint depth0)
 {
-   GLboolean ok;
    struct intel_mipmap_tree *mt = calloc(sizeof(*mt), 1);
+   int compress_byte = 0;
 
    DBG("%s target %s format %s level %d..%d <-- %p\n", __FUNCTION__,
        _mesa_lookup_enum_by_nr(target),
-       _mesa_lookup_enum_by_nr(internal_format), 
+       _mesa_get_format_name(format),
        first_level, last_level, mt);
 
+   if (_mesa_is_format_compressed(format))
+      compress_byte = intel_compressed_num_bytes(format);
+
    mt->target = target_to_target(target);
-   mt->internal_format = internal_format;
+   mt->format = format;
    mt->first_level = first_level;
    mt->last_level = last_level;
    mt->width0 = width0;
    mt->height0 = height0;
    mt->depth0 = depth0;
-   mt->cpp = compress_byte ? compress_byte : cpp;
+   mt->cpp = compress_byte ? compress_byte : _mesa_get_format_bytes(mt->format);
    mt->compressed = compress_byte ? 1 : 0;
    mt->refcount = 1; 
 
 #ifdef I915
+   (void) intel;
    if (intel->is_945)
-      ok = i945_miptree_layout(intel, mt, tiling);
+      i945_miptree_layout(mt);
    else
-      ok = i915_miptree_layout(intel, mt, tiling);
+      i915_miptree_layout(mt);
 #else
-   ok = brw_miptree_layout(intel, mt, tiling);
+   brw_miptree_layout(intel, mt);
 #endif
 
-   if (!ok) {
-      free(mt);
-      DBG("%s not okay - returning NULL\n", __FUNCTION__);
-      return NULL;
-   }
-
    return mt;
 }
 
@@ -106,41 +104,39 @@ intel_miptree_create_internal(struct intel_context *intel,
 struct intel_mipmap_tree *
 intel_miptree_create(struct intel_context *intel,
                     GLenum target,
-                    GLenum base_format,
-                    GLenum internal_format,
+                    gl_format format,
                     GLuint first_level,
                     GLuint last_level,
                     GLuint width0,
                     GLuint height0,
-                    GLuint depth0, GLuint cpp, GLuint compress_byte,
-                    GLboolean expect_accelerated_upload)
+                    GLuint depth0,
+                    bool expect_accelerated_upload)
 {
    struct intel_mipmap_tree *mt;
-   uint32_t tiling;
+   uint32_t tiling = I915_TILING_NONE;
+   GLenum base_format = _mesa_get_format_base_format(format);
 
-   if (intel->use_texture_tiling && compress_byte == 0) {
+   if (intel->use_texture_tiling && !_mesa_is_format_compressed(format)) {
       if (intel->gen >= 4 &&
          (base_format == GL_DEPTH_COMPONENT ||
           base_format == GL_DEPTH_STENCIL_EXT))
         tiling = I915_TILING_Y;
-      else
+      else if (width0 >= 64)
         tiling = I915_TILING_X;
-   } else
-      tiling = I915_TILING_NONE;
+   }
 
-   mt = intel_miptree_create_internal(intel, target, internal_format,
+   mt = intel_miptree_create_internal(intel, target, format,
                                      first_level, last_level, width0,
-                                     height0, depth0, cpp, compress_byte,
-                                     tiling);
+                                     height0, depth0);
    /*
     * pitch == 0 || height == 0  indicates the null texture
     */
-   if (!mt || !mt->total_height) {
+   if (!mt || !mt->total_width || !mt->total_height) {
       free(mt);
       return NULL;
    }
 
-   mt->region = intel_region_alloc(intel,
+   mt->region = intel_region_alloc(intel->intelScreen,
                                   tiling,
                                   mt->cpp,
                                   mt->total_width,
@@ -159,20 +155,14 @@ intel_miptree_create(struct intel_context *intel,
 struct intel_mipmap_tree *
 intel_miptree_create_for_region(struct intel_context *intel,
                                GLenum target,
-                               GLenum internal_format,
-                               GLuint first_level,
-                               GLuint last_level,
-                               struct intel_region *region,
-                               GLuint depth0,
-                               GLuint compress_byte)
+                               gl_format format,
+                               struct intel_region *region)
 {
    struct intel_mipmap_tree *mt;
 
-   mt = intel_miptree_create_internal(intel, target, internal_format,
-                                     first_level, last_level,
-                                     region->width, region->height, 1,
-                                     region->cpp, compress_byte,
-                                     I915_TILING_NONE);
+   mt = intel_miptree_create_internal(intel, target, format,
+                                     0, 0,
+                                     region->width, region->height, 1);
    if (!mt)
       return mt;
 
@@ -185,15 +175,22 @@ void
 intel_miptree_reference(struct intel_mipmap_tree **dst,
                         struct intel_mipmap_tree *src)
 {
-   src->refcount++;
+   if (*dst == src)
+      return;
+
+   intel_miptree_release(dst);
+
+   if (src) {
+      src->refcount++;
+      DBG("%s %p refcount now %d\n", __FUNCTION__, src, src->refcount);
+   }
+
    *dst = src;
-   DBG("%s %p refcount now %d\n", __FUNCTION__, src, src->refcount);
 }
 
 
 void
-intel_miptree_release(struct intel_context *intel,
-                      struct intel_mipmap_tree **mt)
+intel_miptree_release(struct intel_mipmap_tree **mt)
 {
    if (!*mt)
       return;
@@ -204,20 +201,8 @@ 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));
+      intel_region_release(&((*mt)->hiz_region));
 
       for (i = 0; i < MAX_TEXTURE_LEVELS; i++) {
         free((*mt)->level[i].x_offset);
@@ -229,6 +214,23 @@ intel_miptree_release(struct intel_context *intel,
    *mt = NULL;
 }
 
+void
+intel_miptree_get_dimensions_for_image(struct gl_texture_image *image,
+                                       int *width, int *height, int *depth)
+{
+   switch (image->TexObject->Target) {
+   case GL_TEXTURE_1D_ARRAY:
+      *width = image->Width;
+      *height = 1;
+      *depth = image->Height;
+      break;
+   default:
+      *width = image->Width;
+      *height = image->Height;
+      *depth = image->Depth;
+      break;
+   }
+}
 
 /**
  * Can the image be pulled into a unified mipmap tree?  This mirrors
@@ -236,37 +238,33 @@ intel_miptree_release(struct intel_context *intel,
  *
  * Not sure whether I want to pass gl_texture_image here.
  */
-GLboolean
+bool
 intel_miptree_match_image(struct intel_mipmap_tree *mt,
                           struct gl_texture_image *image)
 {
-   GLboolean isCompressed = _mesa_is_format_compressed(image->TexFormat);
    struct intel_texture_image *intelImage = intel_texture_image(image);
-   GLuint level = intelImage->level;
+   GLuint level = intelImage->base.Base.Level;
+   int width, height, depth;
 
    /* Images with borders are never pulled into mipmap trees. */
    if (image->Border)
-      return GL_FALSE;
+      return false;
 
-   if (image->InternalFormat != mt->internal_format ||
-       isCompressed != mt->compressed)
-      return GL_FALSE;
+   if (image->TexFormat != mt->format)
+      return false;
 
-   if (!isCompressed &&
-       !mt->compressed &&
-       _mesa_get_format_bytes(image->TexFormat) != mt->cpp)
-      return GL_FALSE;
+   intel_miptree_get_dimensions_for_image(image, &width, &height, &depth);
 
    /* Test image dimensions against the base level image adjusted for
     * minification.  This will also catch images not present in the
     * tree, changed targets, etc.
     */
-   if (image->Width != mt->level[level].width ||
-       image->Height != mt->level[level].height ||
-       image->Depth != mt->level[level].depth)
-      return GL_FALSE;
+   if (width != mt->level[level].width ||
+       height != mt->level[level].height ||
+       depth != mt->level[level].depth)
+      return false;
 
-   return GL_TRUE;
+   return true;
 }
 
 
@@ -321,158 +319,127 @@ intel_miptree_get_image_offset(struct intel_mipmap_tree *mt,
                               GLuint level, GLuint face, GLuint depth,
                               GLuint *x, GLuint *y)
 {
-   if (mt->target == GL_TEXTURE_CUBE_MAP_ARB) {
+   switch (mt->target) {
+   case GL_TEXTURE_CUBE_MAP_ARB:
       *x = mt->level[level].x_offset[face];
       *y = mt->level[level].y_offset[face];
-   } else if (mt->target == GL_TEXTURE_3D) {
+      break;
+   case GL_TEXTURE_3D:
+   case GL_TEXTURE_2D_ARRAY_EXT:
+   case GL_TEXTURE_1D_ARRAY_EXT:
+      assert(depth < mt->level[level].nr_images);
       *x = mt->level[level].x_offset[depth];
       *y = mt->level[level].y_offset[depth];
-   } else {
+      break;
+   default:
       *x = mt->level[level].x_offset[0];
       *y = mt->level[level].y_offset[0];
+      break;
    }
 }
 
 /**
- * Map a teximage in a mipmap tree.
- * \param row_stride  returns row stride in bytes
- * \param image_stride  returns image stride in bytes (for 3D textures).
- * \param image_offsets pointer to array of pixel offsets from the returned
- *       pointer to each depth image
- * \return address of mapping
+ * Copies the image's current data to the given miptree, and associates that
+ * miptree with the image.
  */
-GLubyte *
-intel_miptree_image_map(struct intel_context * intel,
-                        struct intel_mipmap_tree * mt,
-                        GLuint face,
-                        GLuint level,
-                        GLuint * row_stride, GLuint * image_offsets)
-{
-   GLuint x, y;
-   DBG("%s \n", __FUNCTION__);
-
-   if (row_stride)
-      *row_stride = mt->region->pitch * mt->cpp;
-
-   if (mt->target == GL_TEXTURE_3D) {
-      int i;
-
-      for (i = 0; i < mt->level[level].depth; i++) {
-
-        intel_miptree_get_image_offset(mt, level, face, i,
-                                       &x, &y);
-        image_offsets[i] = x + y * mt->region->pitch;
-      }
-
-      return intel_region_map(intel, mt->region);
-   } else {
-      assert(mt->level[level].depth == 1);
-      intel_miptree_get_image_offset(mt, level, face, 0,
-                                    &x, &y);
-      image_offsets[0] = 0;
-
-      return intel_region_map(intel, mt->region) +
-        (x + y * mt->region->pitch) * mt->cpp;
-   }
-}
-
-
 void
-intel_miptree_image_unmap(struct intel_context *intel,
-                          struct intel_mipmap_tree *mt)
+intel_miptree_copy_teximage(struct intel_context *intel,
+                           struct intel_texture_image *intelImage,
+                           struct intel_mipmap_tree *dst_mt)
 {
-   DBG("%s\n", __FUNCTION__);
-   intel_region_unmap(intel, mt->region);
-}
-
-
-/**
- * Upload data for a particular image.
- */
-void
-intel_miptree_image_data(struct intel_context *intel,
-                        struct intel_mipmap_tree *dst,
-                        GLuint face,
-                        GLuint level,
-                        void *src,
-                        GLuint src_row_pitch,
-                        GLuint src_image_pitch)
-{
-   const GLuint depth = dst->level[level].depth;
-   GLuint i;
-
-   DBG("%s: %d/%d\n", __FUNCTION__, face, level);
-   for (i = 0; i < depth; i++) {
-      GLuint dst_x, dst_y, height;
-
-      intel_miptree_get_image_offset(dst, level, face, i, &dst_x, &dst_y);
-
-      height = dst->level[level].height;
-      if(dst->compressed)
-        height = (height + 3) / 4;
-
-      intel_region_data(intel,
-                       dst->region, 0, dst_x, dst_y,
-                       src,
-                       src_row_pitch,
-                       0, 0,                             /* source x, y */
-                       dst->level[level].width, height); /* width, height */
-
-      src = (char *)src + src_image_pitch * dst->cpp;
+   struct intel_mipmap_tree *src_mt = intelImage->mt;
+   int level = intelImage->base.Base.Level;
+   int face = intelImage->base.Base.Face;
+   GLuint width = src_mt->level[level].width;
+   GLuint height = src_mt->level[level].height;
+   GLuint depth = src_mt->level[level].depth;
+   int slice;
+   void *src, *dst;
+
+   if (dst_mt->compressed) {
+      unsigned int align_w, align_h;
+
+      intel_get_texture_alignment_unit(intelImage->base.Base.TexFormat,
+                                      &align_w, &align_h);
+      height = ALIGN(height, align_h) / align_h;
+      width = ALIGN(width, align_w);
    }
-}
-
 
-/**
- * Copy mipmap image between trees
- */
-void
-intel_miptree_image_copy(struct intel_context *intel,
-                         struct intel_mipmap_tree *dst,
-                         GLuint face, GLuint level,
-                         struct intel_mipmap_tree *src)
-{
-   GLuint width = src->level[level].width;
-   GLuint height = src->level[level].height;
-   GLuint depth = src->level[level].depth;
-   GLuint src_x, src_y, dst_x, dst_y;
-   GLuint i;
-   GLboolean success;
-
-   if (dst->compressed) {
-       GLuint align_w, align_h;
-
-       intel_get_texture_alignment_unit(dst->internal_format,
-                                        &align_w, &align_h);
-       height = (height + 3) / 4;
-       width = ALIGN(width, align_w);
+   for (slice = 0; slice < depth; slice++) {
+      unsigned int dst_x, dst_y, src_x, src_y;
+
+      intel_miptree_get_image_offset(dst_mt, level, face, slice,
+                                    &dst_x, &dst_y);
+
+      if (src_mt) {
+        /* Copy potentially with the blitter:
+         */
+        intel_miptree_get_image_offset(src_mt, level, face, slice,
+                                       &src_x, &src_y);
+
+        DBG("validate blit mt %p %d,%d/%d -> mt %p %d,%d/%d (%dx%d)\n",
+            src_mt, src_x, src_y, src_mt->region->pitch * src_mt->region->cpp,
+            dst_mt, dst_x, dst_y, dst_mt->region->pitch * dst_mt->region->cpp,
+            width, height);
+
+        if (!intelEmitCopyBlit(intel,
+                               dst_mt->region->cpp,
+                               src_mt->region->pitch, src_mt->region->bo,
+                               0, src_mt->region->tiling,
+                               dst_mt->region->pitch, dst_mt->region->bo,
+                               0, dst_mt->region->tiling,
+                               src_x, src_y,
+                               dst_x, dst_y,
+                               width, height,
+                               GL_COPY)) {
+
+           fallback_debug("miptree validate blit for %s failed\n",
+                          _mesa_get_format_name(intelImage->base.Base.TexFormat));
+           dst = intel_region_map(intel, dst_mt->region);
+           src = intel_region_map(intel, src_mt->region);
+
+           _mesa_copy_rect(dst,
+                           dst_mt->cpp,
+                           dst_mt->region->pitch,
+                           dst_x, dst_y,
+                           width, height,
+                           src, src_mt->region->pitch,
+                           src_x, src_y);
+
+           intel_region_unmap(intel, dst_mt->region);
+           intel_region_unmap(intel, src_mt->region);
+        }
+      } else {
+        dst = intel_region_map(intel, dst_mt->region);
+
+        DBG("validate upload mt %p -> mt %p %d,%d/%d (%dx%d)\n",
+            src,
+            dst_mt, dst_x, dst_y, dst_mt->region->pitch * dst_mt->region->cpp,
+            width, height);
+
+        src = intelImage->base.Base.Data;
+        src += (intelImage->base.Base.RowStride *
+                intelImage->base.Base.Height *
+                dst_mt->region->cpp *
+                slice);
+
+        _mesa_copy_rect(dst,
+                        dst_mt->region->cpp,
+                        dst_mt->region->pitch,
+                        dst_x, dst_y,
+                        width, height,
+                        src,
+                        intelImage->base.Base.RowStride,
+                        0, 0);
+
+        intel_region_unmap(intel, dst_mt->region);
+      }
    }
 
-   intel_prepare_render(intel);
-
-   for (i = 0; i < depth; i++) {
-      intel_miptree_get_image_offset(src, level, face, i, &src_x, &src_y);
-      intel_miptree_get_image_offset(dst, level, face, i, &dst_x, &dst_y);
-      success = intel_region_copy(intel,
-                                 dst->region, 0, dst_x, dst_y,
-                                 src->region, 0, src_x, src_y,
-                                 width, height, GL_FALSE,
-                                 GL_COPY);
-      if (!success) {
-        GLubyte *src_ptr, *dst_ptr;
-
-        src_ptr = intel_region_map(intel, src->region);
-        dst_ptr = intel_region_map(intel, dst->region);
-
-        _mesa_copy_rect(dst_ptr,
-                        dst->cpp,
-                        dst->region->pitch,
-                        dst_x, dst_y, width, height,
-                        src_ptr,
-                        src->region->pitch,
-                        src_x, src_y);
-        intel_region_unmap(intel, src->region);
-        intel_region_unmap(intel, dst->region);
-      }
+   if (!src_mt) {
+      _mesa_free_texmemory(intelImage->base.Base.Data);
+      intelImage->base.Base.Data = NULL;
    }
+
+   intel_miptree_reference(&intelImage->mt, dst_mt);
 }