softpipe: fix array textures to use resource array_size
authorBrian Paul <brianp@vmware.com>
Sat, 29 Jan 2011 03:25:27 +0000 (20:25 -0700)
committerBrian Paul <brianp@vmware.com>
Sat, 29 Jan 2011 03:25:27 +0000 (20:25 -0700)
Don't use height for 1D array textures or depth for 2D array textures.

src/gallium/drivers/softpipe/sp_tex_sample.c
src/gallium/drivers/softpipe/sp_tex_tile_cache.c
src/gallium/drivers/softpipe/sp_texture.c

index 15f7eb2b94ef0d66dec5a158cdc40cb30e03a730..8a4ef934348390229288cb713e157249e6b6af39 100644 (file)
@@ -774,6 +774,43 @@ get_texel_3d(const struct sp_sampler_variant *samp,
 }
 
 
+/* Get texel pointer for 1D array texture */
+static INLINE const float *
+get_texel_1d_array(const struct sp_sampler_variant *samp,
+                   union tex_tile_address addr, int x, int y)
+{
+   const struct pipe_resource *texture = samp->view->texture;
+   unsigned level = addr.bits.level;
+
+   if (x < 0 || x >= (int) u_minify(texture->width0, level)) {
+      return samp->sampler->border_color;
+   }
+   else {
+      return get_texel_2d_no_border(samp, addr, x, y);
+   }
+}
+
+
+/* Get texel pointer for 2D array texture */
+static INLINE const float *
+get_texel_2d_array(const struct sp_sampler_variant *samp,
+                   union tex_tile_address addr, int x, int y, int layer)
+{
+   const struct pipe_resource *texture = samp->view->texture;
+   unsigned level = addr.bits.level;
+
+   assert(layer < texture->array_size);
+
+   if (x < 0 || x >= (int) u_minify(texture->width0, level) ||
+       y < 0 || y >= (int) u_minify(texture->height0, level)) {
+      return samp->sampler->border_color;
+   }
+   else {
+      return get_texel_3d_no_border(samp, addr, x, y, layer);
+   }
+}
+
+
 /**
  * Given the logbase2 of a mipmap's base level size and a mipmap level,
  * return the size (in texels) of that mipmap level.
@@ -1027,10 +1064,10 @@ img_filter_1d_array_nearest(struct tgsi_sampler *tgsi_sampler,
    addr.bits.level = samp->level;
 
    samp->nearest_texcoord_s(s, width, x);
-   wrap_array_layer(t, texture->height0, layer);
+   wrap_array_layer(t, texture->array_size, layer);
 
    for (j = 0; j < QUAD_SIZE; j++) {
-      const float *out = get_texel_2d(samp, addr, x[j], layer[j]);
+      const float *out = get_texel_1d_array(samp, addr, x[j], layer[j]);
       int c;
       for (c = 0; c < 4; c++) {
          rgba[c][j] = out[c];
@@ -1115,10 +1152,10 @@ img_filter_2d_array_nearest(struct tgsi_sampler *tgsi_sampler,
 
    samp->nearest_texcoord_s(s, width, x);
    samp->nearest_texcoord_t(t, height, y);
-   wrap_array_layer(p, texture->depth0, layer);
+   wrap_array_layer(p, texture->array_size, layer);
 
    for (j = 0; j < QUAD_SIZE; j++) {
-      const float *out = get_texel_3d(samp, addr, x[j], y[j], layer[j]);
+      const float *out = get_texel_2d_array(samp, addr, x[j], y[j], layer[j]);
       int c;
       for (c = 0; c < 4; c++) {
          rgba[c][j] = out[c];
@@ -1291,11 +1328,11 @@ img_filter_1d_array_linear(struct tgsi_sampler *tgsi_sampler,
    addr.bits.level = samp->level;
 
    samp->linear_texcoord_s(s, width, x0, x1, xw);
-   wrap_array_layer(t, texture->height0, layer);
+   wrap_array_layer(t, texture->array_size, layer);
 
    for (j = 0; j < QUAD_SIZE; j++) {
-      const float *tx0 = get_texel_2d(samp, addr, x0[j], layer[j]);
-      const float *tx1 = get_texel_2d(samp, addr, x1[j], layer[j]);
+      const float *tx0 = get_texel_1d_array(samp, addr, x0[j], layer[j]);
+      const float *tx1 = get_texel_1d_array(samp, addr, x1[j], layer[j]);
       int c;
 
       /* interpolate R, G, B, A */
@@ -1382,13 +1419,13 @@ img_filter_2d_array_linear(struct tgsi_sampler *tgsi_sampler,
 
    samp->linear_texcoord_s(s, width,  x0, x1, xw);
    samp->linear_texcoord_t(t, height, y0, y1, yw);
-   wrap_array_layer(p, texture->depth0, layer);
+   wrap_array_layer(p, texture->array_size, layer);
 
    for (j = 0; j < QUAD_SIZE; j++) {
-      const float *tx0 = get_texel_3d(samp, addr, x0[j], y0[j], layer[j]);
-      const float *tx1 = get_texel_3d(samp, addr, x1[j], y0[j], layer[j]);
-      const float *tx2 = get_texel_3d(samp, addr, x0[j], y1[j], layer[j]);
-      const float *tx3 = get_texel_3d(samp, addr, x1[j], y1[j], layer[j]);
+      const float *tx0 = get_texel_2d_array(samp, addr, x0[j], y0[j], layer[j]);
+      const float *tx1 = get_texel_2d_array(samp, addr, x1[j], y0[j], layer[j]);
+      const float *tx2 = get_texel_2d_array(samp, addr, x0[j], y1[j], layer[j]);
+      const float *tx3 = get_texel_2d_array(samp, addr, x1[j], y1[j], layer[j]);
       int c;
 
       /* interpolate R, G, B, A */
index 5105e77d4366daf6a0e9e968ba2ce168cfe5e487..e589ee7c84100b8393a4f9392d2e98c2579b71ae 100644 (file)
@@ -251,6 +251,7 @@ sp_find_cached_tile_tex(struct softpipe_tex_tile_cache *tc,
           tc->tex_level != addr.bits.level ||
           tc->tex_z != addr.bits.z) {
          /* get new transfer (view into texture) */
+         unsigned width, height, layer;
 
          if (tc->tex_trans) {
             if (tc->tex_trans_map) {
@@ -262,14 +263,22 @@ sp_find_cached_tile_tex(struct softpipe_tex_tile_cache *tc,
             tc->tex_trans = NULL;
          }
 
+         width = u_minify(tc->texture->width0, addr.bits.level);
+         if (tc->texture->target == PIPE_TEXTURE_1D_ARRAY) {
+            height = tc->texture->array_size;
+            layer = 0;
+         }
+         else {
+            height = u_minify(tc->texture->height0, addr.bits.level);
+            layer = addr.bits.face + addr.bits.z;
+         }
+
          tc->tex_trans = 
             pipe_get_transfer(tc->pipe, tc->texture,
                               addr.bits.level,
-                              addr.bits.face + addr.bits.z,
+                              layer,
                               PIPE_TRANSFER_READ | PIPE_TRANSFER_UNSYNCHRONIZED,
-                              0, 0,
-                              u_minify(tc->texture->width0, addr.bits.level),
-                              u_minify(tc->texture->height0, addr.bits.level));
+                              0, 0, width, height);
 
          tc->tex_trans_map = tc->pipe->transfer_map(tc->pipe, tc->tex_trans);
 
index 2daed2022e98081bfdf73c00bb802de87a7a1a03..95374c34ec3fd335f73ef71dbd48b6729bba87fc 100644 (file)
@@ -62,13 +62,21 @@ softpipe_resource_layout(struct pipe_screen *screen,
    unsigned buffer_size = 0;
 
    for (level = 0; level <= pt->last_level; level++) {
+      unsigned slices;
+
+      if (pt->target == PIPE_TEXTURE_CUBE)
+         slices = 6;
+      else if (pt->target == PIPE_TEXTURE_3D)
+         slices = depth;
+      else
+         slices = pt->array_size;
+
       spr->stride[level] = util_format_get_stride(pt->format, width);
 
       spr->level_offset[level] = buffer_size;
 
       buffer_size += (util_format_get_nblocksy(pt->format, height) *
-                      ((pt->target == PIPE_TEXTURE_CUBE) ? 6 : depth) *
-                      spr->stride[level]);
+                      slices * spr->stride[level]);
 
       width  = u_minify(width, 1);
       height = u_minify(height, 1);
@@ -296,7 +304,7 @@ softpipe_surface_destroy(struct pipe_context *pipe,
  * a resource object.
  * \param pipe  rendering context
  * \param resource  the resource to transfer in/out of
- * \param sr  indicates cube face or 3D texture slice
+ * \param level  which mipmap level
  * \param usage  bitmask of PIPE_TRANSFER_x flags
  * \param box  the 1D/2D/3D region of interest
  */
@@ -315,8 +323,21 @@ softpipe_get_transfer(struct pipe_context *pipe,
 
    /* make sure the requested region is in the image bounds */
    assert(box->x + box->width <= u_minify(resource->width0, level));
-   assert(box->y + box->height <= u_minify(resource->height0, level));
-   assert(box->z + box->depth <= (u_minify(resource->depth0, level) + resource->array_size - 1));
+   if (resource->target == PIPE_TEXTURE_1D_ARRAY) {
+      assert(box->y + box->height <= resource->array_size);
+   }
+   else {
+      assert(box->y + box->height <= u_minify(resource->height0, level));
+      if (resource->target == PIPE_TEXTURE_2D_ARRAY) {
+         assert(box->z + box->depth <= resource->array_size);
+      }
+      else if (resource->target == PIPE_TEXTURE_CUBE) {
+         assert(box->z < 6);
+      }
+      else {
+         assert(box->z + box->depth <= (u_minify(resource->depth0, level)));
+      }
+   }
 
    /*
     * Transfers, like other pipe operations, must happen in order, so flush the