gallium/ddebug: new pipe for hang detection and driver state dumping (v2)
[mesa.git] / src / gallium / drivers / softpipe / sp_texture.c
index 2db0de875033f9484294d3050901c4ac4d826ac3..e1ea5df24ca420a1dbe836cf8a9ae597c855c2dc 100644 (file)
@@ -1,6 +1,6 @@
 /**************************************************************************
  * 
- * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2006 VMware, Inc.
  * All Rights Reserved.
  * 
  * Permission is hereby granted, free of charge, to any person obtaining a
@@ -18,7 +18,7 @@
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -26,8 +26,8 @@
  **************************************************************************/
  /*
   * Authors:
-  *   Keith Whitwell <keith@tungstengraphics.com>
-  *   Michel Dänzer <michel@tungstengraphics.com>
+  *   Keith Whitwell <keithw@vmware.com>
+  *   Michel Dänzer <daenzer@vmware.com>
   */
 
 #include "pipe/p_defines.h"
@@ -60,14 +60,17 @@ softpipe_resource_layout(struct pipe_screen *screen,
    unsigned width = pt->width0;
    unsigned height = pt->height0;
    unsigned depth = pt->depth0;
-   unsigned buffer_size = 0;
+   uint64_t buffer_size = 0;
 
    for (level = 0; level <= pt->last_level; level++) {
-      unsigned slices;
+      unsigned slices, nblocksy;
+
+      nblocksy = util_format_get_nblocksy(pt->format, height);
 
       if (pt->target == PIPE_TEXTURE_CUBE)
-         slices = 6;
-      else if (pt->target == PIPE_TEXTURE_3D)
+         assert(pt->array_size == 6);
+
+      if (pt->target == PIPE_TEXTURE_3D)
          slices = depth;
       else
          slices = pt->array_size;
@@ -76,8 +79,15 @@ softpipe_resource_layout(struct pipe_screen *screen,
 
       spr->level_offset[level] = buffer_size;
 
-      buffer_size += (util_format_get_nblocksy(pt->format, height) *
-                      slices * spr->stride[level]);
+      /* if row_stride * height > SP_MAX_TEXTURE_SIZE */
+      if ((uint64_t)spr->stride[level] * nblocksy > SP_MAX_TEXTURE_SIZE) {
+         /* image too large */
+         return FALSE;
+      }
+
+      spr->img_stride[level] = spr->stride[level] * nblocksy;
+
+      buffer_size += (uint64_t) spr->img_stride[level] * slices;
 
       width  = u_minify(width, 1);
       height = u_minify(height, 1);
@@ -88,7 +98,7 @@ softpipe_resource_layout(struct pipe_screen *screen,
       return FALSE;
 
    if (allocate) {
-      spr->data = align_malloc(buffer_size, 16);
+      spr->data = align_malloc(buffer_size, 64);
       return spr->data != NULL;
    }
    else {
@@ -128,7 +138,7 @@ softpipe_displaytarget_layout(struct pipe_screen *screen,
                                           spr->base.format,
                                           spr->base.width0, 
                                           spr->base.height0,
-                                          16,
+                                          64,
                                           &spr->stride[0] );
 
    return spr->dt != NULL;
@@ -253,22 +263,9 @@ static unsigned
 sp_get_tex_image_offset(const struct softpipe_resource *spr,
                         unsigned level, unsigned layer)
 {
-   const unsigned hgt = u_minify(spr->base.height0, level);
-   const unsigned nblocksy = util_format_get_nblocksy(spr->base.format, hgt);
    unsigned offset = spr->level_offset[level];
 
-   if (spr->base.target == PIPE_TEXTURE_CUBE ||
-       spr->base.target == PIPE_TEXTURE_CUBE_ARRAY ||
-       spr->base.target == PIPE_TEXTURE_3D ||
-       spr->base.target == PIPE_TEXTURE_2D_ARRAY) {
-      offset += layer * nblocksy * spr->stride[level];
-   }
-   else if (spr->base.target == PIPE_TEXTURE_1D_ARRAY) {
-      offset += layer * spr->stride[level];
-   }
-   else {
-      assert(layer == 0);
-   }
+   offset += layer * spr->img_stride[level];
 
    return offset;
 }
@@ -354,31 +351,29 @@ softpipe_transfer_map(struct pipe_context *pipe,
    struct softpipe_transfer *spt;
    struct pipe_transfer *pt;
    enum pipe_format format = resource->format;
-   const unsigned hgt = u_minify(spr->base.height0, level);
-   const unsigned nblocksy = util_format_get_nblocksy(format, hgt);
    uint8_t *map;
 
    assert(resource);
    assert(level <= resource->last_level);
 
    /* make sure the requested region is in the image bounds */
-   assert(box->x + box->width <= u_minify(resource->width0, level));
+   assert(box->x + box->width <= (int) u_minify(resource->width0, level));
    if (resource->target == PIPE_TEXTURE_1D_ARRAY) {
-      assert(box->y + box->height <= resource->array_size);
+      assert(box->y + box->height <= (int) resource->array_size);
    }
    else {
-      assert(box->y + box->height <= u_minify(resource->height0, level));
+      assert(box->y + box->height <= (int) u_minify(resource->height0, level));
       if (resource->target == PIPE_TEXTURE_2D_ARRAY) {
-         assert(box->z + box->depth <= resource->array_size);
+         assert(box->z + box->depth <= (int) resource->array_size);
       }
       else if (resource->target == PIPE_TEXTURE_CUBE) {
          assert(box->z < 6);
       }
       else if (resource->target == PIPE_TEXTURE_CUBE_ARRAY) {
-         assert(box->z <= resource->array_size);
+         assert(box->z <= (int) resource->array_size);
       }
       else {
-         assert(box->z + box->depth <= (u_minify(resource->depth0, level)));
+         assert(box->z + box->depth <= (int) u_minify(resource->depth0, level));
       }
    }
 
@@ -414,7 +409,7 @@ softpipe_transfer_map(struct pipe_context *pipe,
    pt->usage = usage;
    pt->box = *box;
    pt->stride = spr->stride[level];
-   pt->layer_stride = pt->stride * nblocksy;
+   pt->layer_stride = spr->img_stride[level];
 
    spt->offset = sp_get_tex_image_offset(spr, level, box->z);