softpipe: enable ARB_texture_view
authorRoland Scheidegger <sroland@vmware.com>
Wed, 13 May 2015 20:56:07 +0000 (22:56 +0200)
committerRoland Scheidegger <sroland@vmware.com>
Wed, 13 May 2015 20:57:50 +0000 (22:57 +0200)
Some bits were already there for texture views but some were missing.
In particular for cube map views things needed to change a bit.
For simplicity I ended up removing the separate face addr bit (just use
the z bit) - cube arrays didn't use it already, so just follow the same
logic there. (In theory using separate bits could allow for better hash
function but I don't think anyone ever did some measurements of that so
probably not worth the trouble, if we'd reintroduce it we'd certainly
wanted to use the same logic for cube arrays and cube maps.)
Also extend the seamless cube sampling to cube arrays - as there were no
piglit failures before this is apparently untested, but things now generally
work quite the same for cube textures and cube array textures so there
hopefully shouldn't be any trouble...

49 new piglits, 47 pass, 2 fail (both due to fake multisampling).

v2: incorporate Brian's feedback, add sampler view validation,
function rename, formatting fixes.

Reviewed-by: Brian Paul <brianp@vmware.com>
docs/GL3.txt
docs/relnotes/10.6.0.html
src/gallium/drivers/softpipe/sp_screen.c
src/gallium/drivers/softpipe/sp_state_sampler.c
src/gallium/drivers/softpipe/sp_tex_sample.c
src/gallium/drivers/softpipe/sp_tex_tile_cache.c
src/gallium/drivers/softpipe/sp_tex_tile_cache.h

index 32b7809d10c869a9f1a9c0da02a93e9d0161cd45..5a15bc55f475d2514be65e88657a09558a01f4f3 100644 (file)
@@ -169,7 +169,7 @@ GL 4.3, GLSL 4.30:
   GL_ARB_texture_buffer_range                          DONE (nv50, nvc0, i965, r600, radeonsi, llvmpipe)
   GL_ARB_texture_query_levels                          DONE (all drivers that support GLSL 1.30)
   GL_ARB_texture_storage_multisample                   DONE (all drivers that support GL_ARB_texture_multisample)
-  GL_ARB_texture_view                                  DONE (i965, nv50, nvc0, llvmpipe)
+  GL_ARB_texture_view                                  DONE (i965, nv50, nvc0, llvmpipe, softpipe)
   GL_ARB_vertex_attrib_binding                         DONE (all drivers)
 
 
index 3f69f986ccdce4348881b07623010c9e062e4e0a..6d3798688657eaa28beb89e5c7e79681a3e3b75a 100644 (file)
@@ -56,7 +56,7 @@ Note: some of the new features are only available with certain drivers.
 <li>GL_ARB_pipeline_statistics_query on i965, nv50, nvc0, r600, radeonsi, softpipe</li>
 <li>GL_ARB_program_interface_query (all drivers)</li>
 <li>GL_ARB_texture_stencil8 on nv50, nvc0, r600, radeonsi, softpipe</li>
-<li>GL_ARB_texture_view on llvmpipe</li>
+<li>GL_ARB_texture_view on llvmpipe, softpipe</li>
 <li>GL_ARB_uniform_buffer_object on freedreno</li>
 <li>GL_ARB_vertex_attrib_64bit on nvc0, softpipe</li>
 <li>GL_ARB_viewport_array, GL_AMD_vertex_shader_viewport_index on i965/gen6</li>
index fc32c56b6997b57a4091c45678efc206f504261e..b3bc1773e9f4301479b394e0151b83c85fb3dee0 100644 (file)
@@ -200,8 +200,9 @@ softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
    case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
       return 1;
    case PIPE_CAP_TGSI_FS_FINE_DERIVATIVE:
-   case PIPE_CAP_SAMPLER_VIEW_TARGET:
       return 0;
+   case PIPE_CAP_SAMPLER_VIEW_TARGET:
+      return 1;
    case PIPE_CAP_FAKE_SW_MSAA:
       return 1;
    case PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET:
index e56fb5b1485315528024b9a235f28121ad1b240d..d7a3360713fbf7f5fd31738de9c1cf2e057a92cc 100644 (file)
@@ -202,7 +202,7 @@ prepare_shader_sampling(
             struct pipe_resource *res = view->texture;
             int j;
 
-            if (res->target != PIPE_BUFFER) {
+            if (view->target != PIPE_BUFFER) {
                first_level = view->u.tex.first_level;
                last_level = view->u.tex.last_level;
                assert(first_level <= last_level);
@@ -214,15 +214,17 @@ prepare_shader_sampling(
                   row_stride[j] = sp_tex->stride[j];
                   img_stride[j] = sp_tex->img_stride[j];
                }
-               if (res->target == PIPE_TEXTURE_1D_ARRAY ||
-                   res->target == PIPE_TEXTURE_2D_ARRAY ||
-                   res->target == PIPE_TEXTURE_CUBE_ARRAY) {
+               if (view->target == PIPE_TEXTURE_1D_ARRAY ||
+                   view->target == PIPE_TEXTURE_2D_ARRAY ||
+                   view->target == PIPE_TEXTURE_CUBE ||
+                   view->target == PIPE_TEXTURE_CUBE_ARRAY) {
                   num_layers = view->u.tex.last_layer - view->u.tex.first_layer + 1;
                   for (j = first_level; j <= last_level; j++) {
                      mip_offsets[j] += view->u.tex.first_layer *
                                        sp_tex->img_stride[j];
                   }
-                  if (res->target == PIPE_TEXTURE_CUBE_ARRAY) {
+                  if (view->target == PIPE_TEXTURE_CUBE ||
+                      view->target == PIPE_TEXTURE_CUBE_ARRAY) {
                      assert(num_layers % 6 == 0);
                   }
                   assert(view->u.tex.first_layer <= view->u.tex.last_layer);
index 68dcf57240d32c5b42504e962068091d4628bf28..21fb6b00e30ed28db0fad510888ab2980d8bc794 100644 (file)
@@ -474,11 +474,11 @@ wrap_linear_unorm_clamp_to_edge(float s, unsigned size,
 /**
  * Do coordinate to array index conversion.  For array textures.
  */
-static INLINE void
-wrap_array_layer(float coord, unsigned size, int *layer)
+static INLINE int
+coord_to_layer(float coord, unsigned first_layer, unsigned last_layer)
 {
    int c = util_ifloor(coord + 0.5F);
-   *layer = CLAMP(c, 0, (int) size - 1);
+   return CLAMP(c, (int)first_layer, (int)last_layer);
 }
 
 
@@ -757,61 +757,6 @@ get_next_ycoord(unsigned face, unsigned fall_off_index, int max, int xc, int yc)
 }
 
 
-static INLINE const float *
-get_texel_cube_seamless(const struct sp_sampler_view *sp_sview,
-                        union tex_tile_address addr, int x, int y,
-                        float *corner)
-{
-   const struct pipe_resource *texture = sp_sview->base.texture;
-   unsigned level = addr.bits.level;
-   unsigned face = addr.bits.face;
-   int new_x, new_y, max_x;
-
-   max_x = (int) u_minify(texture->width0, level);
-
-   assert(texture->width0 == texture->height0);
-   new_x = x;
-   new_y = y;
-
-   /* change the face */
-   if (x < 0) {
-      /*
-       * Cheat with corners. They are difficult and I believe because we don't get
-       * per-pixel faces we can actually have multiple corner texels per pixel,
-       * which screws things up majorly in any case (as the per spec behavior is
-       * to average the 3 remaining texels, which we might not have).
-       * Hence just make sure that the 2nd coord is clamped, will simply pick the
-       * sample which would have fallen off the x coord, but not y coord.
-       * So the filter weight of the samples will be wrong, but at least this
-       * ensures that only valid texels near the corner are used.
-       */
-      if (y < 0 || y >= max_x) {
-         y = CLAMP(y, 0, max_x - 1);
-      }
-      new_x = get_next_xcoord(face, 0, max_x -1, x, y);
-      new_y = get_next_ycoord(face, 0, max_x -1, x, y);
-      face = get_next_face(face, 0);
-   } else if (x >= max_x) {
-      if (y < 0 || y >= max_x) {
-         y = CLAMP(y, 0, max_x - 1);
-      }
-      new_x = get_next_xcoord(face, 1, max_x -1, x, y);
-      new_y = get_next_ycoord(face, 1, max_x -1, x, y);
-      face = get_next_face(face, 1);
-   } else if (y < 0) {
-      new_x = get_next_xcoord(face, 2, max_x -1, x, y);
-      new_y = get_next_ycoord(face, 2, max_x -1, x, y);
-      face = get_next_face(face, 2);
-   } else if (y >= max_x) {
-      new_x = get_next_xcoord(face, 3, max_x -1, x, y);
-      new_y = get_next_ycoord(face, 3, max_x -1, x, y);
-      face = get_next_face(face, 3);
-   }
-
-   addr.bits.face = face;
-   return get_texel_2d_no_border( sp_sview, addr, new_x, new_y );
-}
-
 /* Gather a quad of adjacent texels within a tile:
  */
 static INLINE void
@@ -948,6 +893,60 @@ get_texel_2d_array(const struct sp_sampler_view *sp_sview,
 }
 
 
+static INLINE const float *
+get_texel_cube_seamless(const struct sp_sampler_view *sp_sview,
+                        union tex_tile_address addr, int x, int y,
+                        float *corner, int layer, unsigned face)
+{
+   const struct pipe_resource *texture = sp_sview->base.texture;
+   unsigned level = addr.bits.level;
+   int new_x, new_y, max_x;
+
+   max_x = (int) u_minify(texture->width0, level);
+
+   assert(texture->width0 == texture->height0);
+   new_x = x;
+   new_y = y;
+
+   /* change the face */
+   if (x < 0) {
+      /*
+       * Cheat with corners. They are difficult and I believe because we don't get
+       * per-pixel faces we can actually have multiple corner texels per pixel,
+       * which screws things up majorly in any case (as the per spec behavior is
+       * to average the 3 remaining texels, which we might not have).
+       * Hence just make sure that the 2nd coord is clamped, will simply pick the
+       * sample which would have fallen off the x coord, but not y coord.
+       * So the filter weight of the samples will be wrong, but at least this
+       * ensures that only valid texels near the corner are used.
+       */
+      if (y < 0 || y >= max_x) {
+         y = CLAMP(y, 0, max_x - 1);
+      }
+      new_x = get_next_xcoord(face, 0, max_x -1, x, y);
+      new_y = get_next_ycoord(face, 0, max_x -1, x, y);
+      face = get_next_face(face, 0);
+   } else if (x >= max_x) {
+      if (y < 0 || y >= max_x) {
+         y = CLAMP(y, 0, max_x - 1);
+      }
+      new_x = get_next_xcoord(face, 1, max_x -1, x, y);
+      new_y = get_next_ycoord(face, 1, max_x -1, x, y);
+      face = get_next_face(face, 1);
+   } else if (y < 0) {
+      new_x = get_next_xcoord(face, 2, max_x -1, x, y);
+      new_y = get_next_ycoord(face, 2, max_x -1, x, y);
+      face = get_next_face(face, 2);
+   } else if (y >= max_x) {
+      new_x = get_next_xcoord(face, 3, max_x -1, x, y);
+      new_y = get_next_ycoord(face, 3, max_x -1, x, y);
+      face = get_next_face(face, 3);
+   }
+
+   return get_texel_3d_no_border(sp_sview, addr, new_x, new_y, layer + face);
+}
+
+
 /* Get texel pointer for cube array texture */
 static INLINE const float *
 get_texel_cube_array(const struct sp_sampler_view *sp_sview,
@@ -1208,7 +1207,8 @@ img_filter_1d_array_nearest(struct sp_sampler_view *sp_sview,
    addr.bits.level = level;
 
    sp_samp->nearest_texcoord_s(s, width, &x);
-   wrap_array_layer(t, texture->array_size, &layer);
+   layer = coord_to_layer(t, sp_sview->base.u.tex.first_layer,
+                          sp_sview->base.u.tex.last_layer);
 
    out = get_texel_1d_array(sp_sview, sp_samp, addr, x, layer);
    for (c = 0; c < TGSI_QUAD_SIZE; c++)
@@ -1287,7 +1287,8 @@ img_filter_2d_array_nearest(struct sp_sampler_view *sp_sview,
 
    sp_samp->nearest_texcoord_s(s, width, &x);
    sp_samp->nearest_texcoord_t(t, height, &y);
-   wrap_array_layer(p, texture->array_size, &layer);
+   layer = coord_to_layer(p, sp_sview->base.u.tex.first_layer,
+                          sp_sview->base.u.tex.last_layer);
 
    out = get_texel_2d_array(sp_sview, sp_samp, addr, x, y, layer);
    for (c = 0; c < TGSI_QUAD_SIZE; c++)
@@ -1299,14 +1300,6 @@ img_filter_2d_array_nearest(struct sp_sampler_view *sp_sview,
 }
 
 
-static INLINE union tex_tile_address
-face(union tex_tile_address addr, unsigned face )
-{
-   addr.bits.face = face;
-   return addr;
-}
-
-
 static void
 img_filter_cube_nearest(struct sp_sampler_view *sp_sview,
                         struct sp_sampler *sp_samp,
@@ -1319,7 +1312,7 @@ img_filter_cube_nearest(struct sp_sampler_view *sp_sview,
 {
    const struct pipe_resource *texture = sp_sview->base.texture;
    int width, height;
-   int x, y;
+   int x, y, layerface;
    union tex_tile_address addr;
    const float *out;
    int c;
@@ -1346,7 +1339,8 @@ img_filter_cube_nearest(struct sp_sampler_view *sp_sview,
       sp_samp->nearest_texcoord_t(t, height, &y);
    }
 
-   out = get_texel_2d(sp_sview, sp_samp, face(addr, face_id), x, y);
+   layerface = face_id + sp_sview->base.u.tex.first_layer;
+   out = get_texel_cube_array(sp_sview, sp_samp, addr, x, y, layerface);
    for (c = 0; c < TGSI_QUAD_SIZE; c++)
       rgba[TGSI_NUM_CHANNELS*c] = out[c];
 
@@ -1367,7 +1361,7 @@ img_filter_cube_array_nearest(struct sp_sampler_view *sp_sview,
 {
    const struct pipe_resource *texture = sp_sview->base.texture;
    int width, height;
-   int x, y, layer;
+   int x, y, layerface;
    union tex_tile_address addr;
    const float *out;
    int c;
@@ -1383,9 +1377,11 @@ img_filter_cube_array_nearest(struct sp_sampler_view *sp_sview,
 
    sp_samp->nearest_texcoord_s(s, width, &x);
    sp_samp->nearest_texcoord_t(t, height, &y);
-   wrap_array_layer(p, texture->array_size, &layer);
+   layerface = coord_to_layer(6 * p + sp_sview->base.u.tex.first_layer,
+                              sp_sview->base.u.tex.first_layer,
+                              sp_sview->base.u.tex.last_layer - 5) + face_id;
 
-   out = get_texel_cube_array(sp_sview, sp_samp, addr, x, y, layer * 6 + face_id);
+   out = get_texel_cube_array(sp_sview, sp_samp, addr, x, y, layerface);
    for (c = 0; c < TGSI_QUAD_SIZE; c++)
       rgba[TGSI_NUM_CHANNELS*c] = out[c];
 
@@ -1494,7 +1490,8 @@ img_filter_1d_array_linear(struct sp_sampler_view *sp_sview,
    addr.bits.level = level;
 
    sp_samp->linear_texcoord_s(s, width, &x0, &x1, &xw);
-   wrap_array_layer(t, texture->array_size, &layer);
+   layer = coord_to_layer(t, sp_sview->base.u.tex.first_layer,
+                          sp_sview->base.u.tex.last_layer);
 
    tx0 = get_texel_1d_array(sp_sview, sp_samp, addr, x0, layer);
    tx1 = get_texel_1d_array(sp_sview, sp_samp, addr, x1, layer);
@@ -1577,7 +1574,8 @@ img_filter_2d_array_linear(struct sp_sampler_view *sp_sview,
 
    sp_samp->linear_texcoord_s(s, width,  &x0, &x1, &xw);
    sp_samp->linear_texcoord_t(t, height, &y0, &y1, &yw);
-   wrap_array_layer(p, texture->array_size, &layer);
+   layer = coord_to_layer(p, sp_sview->base.u.tex.first_layer,
+                          sp_sview->base.u.tex.last_layer);
 
    tx0 = get_texel_2d_array(sp_sview, sp_samp, addr, x0, y0, layer);
    tx1 = get_texel_2d_array(sp_sview, sp_samp, addr, x1, y0, layer);
@@ -1604,9 +1602,9 @@ img_filter_cube_linear(struct sp_sampler_view *sp_sview,
 {
    const struct pipe_resource *texture = sp_sview->base.texture;
    int width, height;
-   int x0, y0, x1, y1;
+   int x0, y0, x1, y1, layer;
    float xw, yw; /* weights */
-   union tex_tile_address addr, addrj;
+   union tex_tile_address addr;
    const float *tx0, *tx1, *tx2, *tx3;
    float corner0[TGSI_QUAD_SIZE], corner1[TGSI_QUAD_SIZE],
          corner2[TGSI_QUAD_SIZE], corner3[TGSI_QUAD_SIZE];
@@ -1635,19 +1633,20 @@ img_filter_cube_linear(struct sp_sampler_view *sp_sview,
       sp_samp->linear_texcoord_t(t, height, &y0, &y1, &yw);
    }
 
-   addrj = face(addr, face_id);
+   layer = sp_sview->base.u.tex.first_layer;
 
    if (sp_samp->base.seamless_cube_map) {
-      tx0 = get_texel_cube_seamless(sp_sview, addrj, x0, y0, corner0);
-      tx1 = get_texel_cube_seamless(sp_sview, addrj, x1, y0, corner1);
-      tx2 = get_texel_cube_seamless(sp_sview, addrj, x0, y1, corner2);
-      tx3 = get_texel_cube_seamless(sp_sview, addrj, x1, y1, corner3);
+      tx0 = get_texel_cube_seamless(sp_sview, addr, x0, y0, corner0, layer, face_id);
+      tx1 = get_texel_cube_seamless(sp_sview, addr, x1, y0, corner1, layer, face_id);
+      tx2 = get_texel_cube_seamless(sp_sview, addr, x0, y1, corner2, layer, face_id);
+      tx3 = get_texel_cube_seamless(sp_sview, addr, x1, y1, corner3, layer, face_id);
    } else {
-      tx0 = get_texel_2d(sp_sview, sp_samp, addrj, x0, y0);
-      tx1 = get_texel_2d(sp_sview, sp_samp, addrj, x1, y0);
-      tx2 = get_texel_2d(sp_sview, sp_samp, addrj, x0, y1);
-      tx3 = get_texel_2d(sp_sview, sp_samp, addrj, x1, y1);
+      tx0 = get_texel_cube_array(sp_sview, sp_samp, addr, x0, y0, layer + face_id);
+      tx1 = get_texel_cube_array(sp_sview, sp_samp, addr, x1, y0, layer + face_id);
+      tx2 = get_texel_cube_array(sp_sview, sp_samp, addr, x0, y1, layer + face_id);
+      tx3 = get_texel_cube_array(sp_sview, sp_samp, addr, x1, y1, layer + face_id);
    }
+
    /* interpolate R, G, B, A */
    for (c = 0; c < TGSI_QUAD_SIZE; c++)
       rgba[TGSI_NUM_CHANNELS*c] = lerp_2d(xw, yw,
@@ -1672,6 +1671,8 @@ img_filter_cube_array_linear(struct sp_sampler_view *sp_sview,
    float xw, yw; /* weights */
    union tex_tile_address addr;
    const float *tx0, *tx1, *tx2, *tx3;
+   float corner0[TGSI_QUAD_SIZE], corner1[TGSI_QUAD_SIZE],
+         corner2[TGSI_QUAD_SIZE], corner3[TGSI_QUAD_SIZE];
    int c;
 
    width = u_minify(texture->width0, level);
@@ -1683,14 +1684,35 @@ img_filter_cube_array_linear(struct sp_sampler_view *sp_sview,
    addr.value = 0;
    addr.bits.level = level;
 
-   sp_samp->linear_texcoord_s(s, width,  &x0, &x1, &xw);
-   sp_samp->linear_texcoord_t(t, height, &y0, &y1, &yw);
-   wrap_array_layer(p, texture->array_size, &layer);
+   /*
+    * For seamless if LINEAR filtering is done within a miplevel,
+    * always apply wrap mode CLAMP_TO_BORDER.
+    */
+   if (sp_samp->base.seamless_cube_map) {
+      /* Note this is a bit overkill, actual clamping is not required */
+      wrap_linear_clamp_to_border(s, width, &x0, &x1, &xw);
+      wrap_linear_clamp_to_border(t, height, &y0, &y1, &yw);
+   } else {
+      /* Would probably make sense to ignore mode and just do edge clamp */
+      sp_samp->linear_texcoord_s(s, width,  &x0, &x1, &xw);
+      sp_samp->linear_texcoord_t(t, height, &y0, &y1, &yw);
+   }
+
+   layer = coord_to_layer(6 * p + sp_sview->base.u.tex.first_layer,
+                          sp_sview->base.u.tex.first_layer,
+                          sp_sview->base.u.tex.last_layer - 5);
 
-   tx0 = get_texel_cube_array(sp_sview, sp_samp, addr, x0, y0, layer * 6 + face_id);
-   tx1 = get_texel_cube_array(sp_sview, sp_samp, addr, x1, y0, layer * 6 + face_id);
-   tx2 = get_texel_cube_array(sp_sview, sp_samp, addr, x0, y1, layer * 6 + face_id);
-   tx3 = get_texel_cube_array(sp_sview, sp_samp, addr, x1, y1, layer * 6 + face_id);
+   if (sp_samp->base.seamless_cube_map) {
+      tx0 = get_texel_cube_seamless(sp_sview, addr, x0, y0, corner0, layer, face_id);
+      tx1 = get_texel_cube_seamless(sp_sview, addr, x1, y0, corner1, layer, face_id);
+      tx2 = get_texel_cube_seamless(sp_sview, addr, x0, y1, corner2, layer, face_id);
+      tx3 = get_texel_cube_seamless(sp_sview, addr, x1, y1, corner3, layer, face_id);
+   } else {
+      tx0 = get_texel_cube_array(sp_sview, sp_samp, addr, x0, y0, layer + face_id);
+      tx1 = get_texel_cube_array(sp_sview, sp_samp, addr, x1, y0, layer + face_id);
+      tx2 = get_texel_cube_array(sp_sview, sp_samp, addr, x0, y1, layer + face_id);
+      tx3 = get_texel_cube_array(sp_sview, sp_samp, addr, x1, y1, layer + face_id);
+   }
 
    /* interpolate R, G, B, A */
    for (c = 0; c < TGSI_QUAD_SIZE; c++)
@@ -2408,13 +2430,13 @@ sample_compare(struct sp_sampler_view *sp_sview,
     * RGBA channels.  We look at the red channel here.
     */
 
-   if (sp_sview->base.texture->target == PIPE_TEXTURE_2D_ARRAY ||
-       sp_sview->base.texture->target == PIPE_TEXTURE_CUBE) {
+   if (sp_sview->base.target == PIPE_TEXTURE_2D_ARRAY ||
+       sp_sview->base.target == PIPE_TEXTURE_CUBE) {
       pc[0] = c0[0];
       pc[1] = c0[1];
       pc[2] = c0[2];
       pc[3] = c0[3];
-   } else if (sp_sview->base.texture->target == PIPE_TEXTURE_CUBE_ARRAY) {
+   } else if (sp_sview->base.target == PIPE_TEXTURE_CUBE_ARRAY) {
       pc[0] = c1[0];
       pc[1] = c1[1];
       pc[2] = c1[2];
@@ -2681,7 +2703,7 @@ get_img_filter(const struct sp_sampler_view *sp_sview,
                const struct pipe_sampler_state *sampler,
                unsigned filter)
 {
-   switch (sp_sview->base.texture->target) {
+   switch (sp_sview->base.target) {
    case PIPE_BUFFER:
    case PIPE_TEXTURE_1D:
       if (filter == PIPE_TEX_FILTER_NEAREST) 
@@ -2907,7 +2929,7 @@ sp_get_dims(struct sp_sampler_view *sp_sview, int level,
    const struct pipe_sampler_view *view = &sp_sview->base;
    const struct pipe_resource *texture = view->texture;
 
-   if (texture->target == PIPE_BUFFER) {
+   if (view->target == PIPE_BUFFER) {
       dims[0] = (view->u.buf.last_element - view->u.buf.first_element) + 1;
       /* the other values are undefined, but let's avoid potential valgrind
        * warnings.
@@ -2924,7 +2946,7 @@ sp_get_dims(struct sp_sampler_view *sp_sview, int level,
    dims[3] = view->u.tex.last_level - view->u.tex.first_level + 1;
    dims[0] = u_minify(texture->width0, level);
 
-   switch(texture->target) {
+   switch (view->target) {
    case PIPE_TEXTURE_1D_ARRAY:
       dims[1] = view->u.tex.last_layer - view->u.tex.first_layer + 1;
       /* fallthrough */
@@ -2975,13 +2997,16 @@ sp_get_texels(struct sp_sampler_view *sp_sview,
 
    addr.value = 0;
    /* TODO write a better test for LOD */
-   addr.bits.level = lod[0];
+   addr.bits.level = sp_sview->base.target == PIPE_BUFFER ? 0 :
+                        CLAMP(lod[0] + sp_sview->base.u.tex.first_level, 
+                              sp_sview->base.u.tex.first_level,
+                              sp_sview->base.u.tex.last_level);
 
    width = u_minify(texture->width0, addr.bits.level);
    height = u_minify(texture->height0, addr.bits.level);
    depth = u_minify(texture->depth0, addr.bits.level);
 
-   switch(texture->target) {
+   switch (sp_sview->base.target) {
    case PIPE_BUFFER:
    case PIPE_TEXTURE_1D:
       for (j = 0; j < TGSI_QUAD_SIZE; j++) {
@@ -2995,7 +3020,8 @@ sp_get_texels(struct sp_sampler_view *sp_sview,
    case PIPE_TEXTURE_1D_ARRAY:
       for (j = 0; j < TGSI_QUAD_SIZE; j++) {
          int x = CLAMP(v_i[j] + offset[0], 0, width - 1);
-         int y = CLAMP(v_j[j], sp_sview->base.u.tex.first_layer, sp_sview->base.u.tex.last_layer);
+         int y = CLAMP(v_j[j], sp_sview->base.u.tex.first_layer,
+                       sp_sview->base.u.tex.last_layer);
          tx = get_texel_2d_no_border(sp_sview, addr, x, y);
          for (c = 0; c < 4; c++) {
             rgba[c][j] = tx[c];
@@ -3017,7 +3043,8 @@ sp_get_texels(struct sp_sampler_view *sp_sview,
       for (j = 0; j < TGSI_QUAD_SIZE; j++) {
          int x = CLAMP(v_i[j] + offset[0], 0, width - 1);
          int y = CLAMP(v_j[j] + offset[1], 0, height - 1);
-         int layer = CLAMP(v_k[j], sp_sview->base.u.tex.first_layer, sp_sview->base.u.tex.last_layer);
+         int layer = CLAMP(v_k[j], sp_sview->base.u.tex.first_layer,
+                           sp_sview->base.u.tex.last_layer);
          tx = get_texel_3d_no_border(sp_sview, addr, x, y, layer);
          for (c = 0; c < 4; c++) {
             rgba[c][j] = tx[c];
@@ -3140,7 +3167,7 @@ softpipe_get_lambda_func(const struct pipe_sampler_view *view, unsigned shader)
    if (shader != PIPE_SHADER_FRAGMENT)
       return compute_lambda_vert;
 
-   switch (view->texture->target) {
+   switch (view->target) {
    case PIPE_BUFFER:
    case PIPE_TEXTURE_1D:
    case PIPE_TEXTURE_1D_ARRAY:
@@ -3176,19 +3203,49 @@ softpipe_create_sampler_view(struct pipe_context *pipe,
       pipe_resource_reference(&view->texture, resource);
       view->context = pipe;
 
+#ifdef DEBUG
+     /*
+      * This is possibly too lenient, but the primary reason is just
+      * to catch state trackers which forget to initialize this, so
+      * it only catches clearly impossible view targets.
+      */
+      if (view->target != resource->target) {
+         if (view->target == PIPE_TEXTURE_1D)
+            assert(resource->target == PIPE_TEXTURE_1D_ARRAY);
+         else if (view->target == PIPE_TEXTURE_1D_ARRAY)
+            assert(resource->target == PIPE_TEXTURE_1D);
+         else if (view->target == PIPE_TEXTURE_2D)
+            assert(resource->target == PIPE_TEXTURE_2D_ARRAY ||
+                   resource->target == PIPE_TEXTURE_CUBE ||
+                   resource->target == PIPE_TEXTURE_CUBE_ARRAY);
+         else if (view->target == PIPE_TEXTURE_2D_ARRAY)
+            assert(resource->target == PIPE_TEXTURE_2D ||
+                   resource->target == PIPE_TEXTURE_CUBE ||
+                   resource->target == PIPE_TEXTURE_CUBE_ARRAY);
+         else if (view->target == PIPE_TEXTURE_CUBE)
+            assert(resource->target == PIPE_TEXTURE_CUBE_ARRAY ||
+                   resource->target == PIPE_TEXTURE_2D_ARRAY);
+         else if (view->target == PIPE_TEXTURE_CUBE_ARRAY)
+            assert(resource->target == PIPE_TEXTURE_CUBE ||
+                   resource->target == PIPE_TEXTURE_2D_ARRAY);
+         else
+            assert(0);
+      }
+#endif
+
       if (any_swizzle(view)) {
          sview->need_swizzle = TRUE;
       }
 
-      if (resource->target == PIPE_TEXTURE_CUBE ||
-          resource->target == PIPE_TEXTURE_CUBE_ARRAY)
+      if (view->target == PIPE_TEXTURE_CUBE ||
+          view->target == PIPE_TEXTURE_CUBE_ARRAY)
          sview->get_samples = sample_cube;
       else {
          sview->get_samples = sample_mip;
       }
       sview->pot2d = spr->pot &&
-                     (resource->target == PIPE_TEXTURE_2D ||
-                      resource->target == PIPE_TEXTURE_RECT);
+                     (view->target == PIPE_TEXTURE_2D ||
+                      view->target == PIPE_TEXTURE_RECT);
 
       sview->xpot = util_logbase2( resource->width0 );
       sview->ypot = util_logbase2( resource->height0 );
index ab8ba60849a62089826a34840c8c1ac229a7e572..4a421a8f8827bfb489d34772b40c53444036511c 100644 (file)
@@ -151,7 +151,7 @@ sp_tex_tile_cache_set_sampler_view(struct softpipe_tex_tile_cache *tc,
          tc->entries[i].addr.bits.invalid = 1;
       }
 
-      tc->tex_face = -1; /* any invalid value here */
+      tc->tex_z = -1; /* any invalid value here */
    }
 }
 
@@ -172,7 +172,7 @@ sp_flush_tex_tile_cache(struct softpipe_tex_tile_cache *tc)
       for (pos = 0; pos < Elements(tc->entries); pos++) {
          tc->entries[pos].addr.bits.invalid = 1;
       }
-      tc->tex_face = -1;
+      tc->tex_z = -1;
    }
 
 }
@@ -190,8 +190,7 @@ tex_cache_pos( union tex_tile_address addr )
 {
    uint entry = (addr.bits.x + 
                  addr.bits.y * 9 + 
-                 addr.bits.z * 3 + 
-                 addr.bits.face + 
+                 addr.bits.z +
                  addr.bits.level * 7);
 
    return entry % NUM_TEX_TILE_ENTRIES;
@@ -226,7 +225,6 @@ sp_find_cached_tile_tex(struct softpipe_tex_tile_cache *tc,
 
       /* check if we need to get a new transfer */
       if (!tc->tex_trans ||
-          tc->tex_face != addr.bits.face ||
           tc->tex_level != addr.bits.level ||
           tc->tex_z != addr.bits.z) {
          /* get new transfer (view into texture) */
@@ -245,7 +243,7 @@ sp_find_cached_tile_tex(struct softpipe_tex_tile_cache *tc,
          }
          else {
             height = u_minify(tc->texture->height0, addr.bits.level);
-            layer = addr.bits.face + addr.bits.z;
+            layer = addr.bits.z;
          }
 
          tc->tex_trans_map =
@@ -255,7 +253,6 @@ sp_find_cached_tile_tex(struct softpipe_tex_tile_cache *tc,
                               PIPE_TRANSFER_READ | PIPE_TRANSFER_UNSYNCHRONIZED,
                               0, 0, width, height, &tc->tex_trans);
 
-         tc->tex_face = addr.bits.face;
          tc->tex_level = addr.bits.level;
          tc->tex_z = addr.bits.z;
       }
index 4eb42460552667899e155524b93ae3650630f353..2233effc439916567a099b6bf29efb0783b47520 100644 (file)
@@ -55,7 +55,6 @@ union tex_tile_address {
       unsigned x:TEX_ADDR_BITS;  /* 16K / TILE_SIZE */
       unsigned y:TEX_ADDR_BITS;  /* 16K / TILE_SIZE */
       unsigned z:TEX_Z_BITS;     /* 16K -- z not tiled */
-      unsigned face:3;
       unsigned level:4;
       unsigned invalid:1;
    } bits;
@@ -94,7 +93,7 @@ struct softpipe_tex_tile_cache
 
    struct pipe_transfer *tex_trans;
    void *tex_trans_map;
-   int tex_face, tex_level, tex_z;
+   int tex_level, tex_z;
 
    unsigned swizzle_r;
    unsigned swizzle_g;
@@ -141,7 +140,6 @@ tex_tile_address( unsigned x,
    addr.bits.x = x / TEX_TILE_SIZE;
    addr.bits.y = y / TEX_TILE_SIZE;
    addr.bits.z = z;
-   addr.bits.face = face;
    addr.bits.level = level;
 
    return addr;