OSDN Git Service

softpipe: add ARB_texture_cube_map_array support (v1.1)
authorDave Airlie <airlied@gmail.com>
Sat, 3 Nov 2012 10:51:45 +0000 (20:51 +1000)
committerDave Airlie <airlied@redhat.com>
Fri, 9 Nov 2012 00:29:26 +0000 (10:29 +1000)
This adds support to the softpipe texture sampler and tgsi exec.

In order to handle the extra input to the texture sampling,
I've had to expand the interfaces to take a c1 value for storing
the texture compare value for the TEX2 case.

v1.1: add comments (Brian)

Reviewed-by: Brian Paul <brianp@vmware.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
src/gallium/auxiliary/tgsi/tgsi_exec.c
src/gallium/auxiliary/tgsi/tgsi_exec.h
src/gallium/drivers/softpipe/sp_screen.c
src/gallium/drivers/softpipe/sp_tex_sample.c
src/gallium/drivers/softpipe/sp_tex_sample.h
src/gallium/drivers/softpipe/sp_texture.c

index 0b58f09..428227d 100644 (file)
@@ -1709,6 +1709,7 @@ fetch_texel( struct tgsi_sampler *sampler,
              const union tgsi_exec_channel *t,
              const union tgsi_exec_channel *p,
              const union tgsi_exec_channel *c0,
+             const union tgsi_exec_channel *c1,
              enum tgsi_sampler_control control,
              union tgsi_exec_channel *r,
              union tgsi_exec_channel *g,
@@ -1718,7 +1719,7 @@ fetch_texel( struct tgsi_sampler *sampler,
    uint j;
    float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE];
 
-   sampler->get_samples(sampler, s->f, t->f, p->f, c0->f, control, rgba);
+   sampler->get_samples(sampler, s->f, t->f, p->f, c0->f, c1->f, control, rgba);
 
    for (j = 0; j < 4; j++) {
       r->f[j] = rgba[0][j];
@@ -1734,19 +1735,25 @@ fetch_texel( struct tgsi_sampler *sampler,
 #define TEX_MODIFIER_LOD_BIAS       2
 #define TEX_MODIFIER_EXPLICIT_LOD   3
 
-
+/*
+ * execute a texture instruction.
+ *
+ * modifier is used to control the channel routing for the\
+ * instruction variants like proj, lod, and texture with lod bias.
+ * sampler indicates which src register the sampler is contained in.
+ */
 static void
 exec_tex(struct tgsi_exec_machine *mach,
          const struct tgsi_full_instruction *inst,
-         uint modifier)
+         uint modifier, uint sampler)
 {
-   const uint unit = inst->Src[1].Register.Index;
-   union tgsi_exec_channel r[4];
+   const uint unit = inst->Src[sampler].Register.Index;
+   union tgsi_exec_channel r[4], cubearraycomp, cubelod;
    const union tgsi_exec_channel *lod = &ZeroVec;
    enum tgsi_sampler_control control;
    uint chan;
 
-   if (modifier != TEX_MODIFIER_NONE) {
+   if (modifier != TEX_MODIFIER_NONE && (sampler == 1)) {
       FETCH(&r[3], 0, TGSI_CHAN_W);
       if (modifier != TEX_MODIFIER_PROJECTED) {
          lod = &r[3];
@@ -1768,7 +1775,7 @@ exec_tex(struct tgsi_exec_machine *mach,
       }
 
       fetch_texel(mach->Samplers[unit],
-                  &r[0], &ZeroVec, &ZeroVec, lod,  /* S, T, P, LOD */
+                  &r[0], &ZeroVec, &ZeroVec, lod, &ZeroVec, /* S, T, P, LOD */
                   control,
                   &r[0], &r[1], &r[2], &r[3]);     /* R, G, B, A */
       break;
@@ -1781,7 +1788,7 @@ exec_tex(struct tgsi_exec_machine *mach,
       }
 
       fetch_texel(mach->Samplers[unit],
-                  &r[0], &ZeroVec, &r[2], lod,  /* S, T, P, LOD */
+                  &r[0], &ZeroVec, &r[2], lod, &ZeroVec, /* S, T, P, LOD */
                   control,
                   &r[0], &r[1], &r[2], &r[3]);     /* R, G, B, A */
       break;
@@ -1801,7 +1808,7 @@ exec_tex(struct tgsi_exec_machine *mach,
       }
 
       fetch_texel(mach->Samplers[unit],
-                  &r[0], &r[1], &r[2], lod,     /* S, T, P, LOD */
+                  &r[0], &r[1], &r[2], lod, &ZeroVec,    /* S, T, P, LOD */
                   control,
                   &r[0], &r[1], &r[2], &r[3]);  /* outputs */
       break;
@@ -1815,7 +1822,7 @@ exec_tex(struct tgsi_exec_machine *mach,
       }
 
       fetch_texel(mach->Samplers[unit],
-                  &r[0], &r[1], &ZeroVec, lod,     /* S, T, P, LOD */
+                  &r[0], &r[1], &ZeroVec, lod, &ZeroVec,    /* S, T, P, LOD */
                   control,
                   &r[0], &r[1], &r[2], &r[3]);  /* outputs */
       break;
@@ -1829,7 +1836,7 @@ exec_tex(struct tgsi_exec_machine *mach,
       }
 
       fetch_texel(mach->Samplers[unit],
-                  &r[0], &r[1], &r[2], lod,     /* S, T, P, LOD */
+                  &r[0], &r[1], &r[2], lod, &ZeroVec,    /* S, T, P, LOD */
                   control,
                   &r[0], &r[1], &r[2], &r[3]);  /* outputs */
       break;
@@ -1845,7 +1852,7 @@ exec_tex(struct tgsi_exec_machine *mach,
       }
 
       fetch_texel(mach->Samplers[unit],
-                  &r[0], &r[1], &r[2], lod,     /* S, T, P, LOD */
+                  &r[0], &r[1], &r[2], lod, &ZeroVec,    /* S, T, P, LOD */
                   control,
                   &r[0], &r[1], &r[2], &r[3]);  /* outputs */
       break;
@@ -1857,7 +1864,24 @@ exec_tex(struct tgsi_exec_machine *mach,
       FETCH(&r[3], 0, TGSI_CHAN_W);
 
       fetch_texel(mach->Samplers[unit],
-                  &r[0], &r[1], &r[2], &r[3],     /* S, T, P, LOD */
+                  &r[0], &r[1], &r[2], &r[3], &ZeroVec,    /* S, T, P, LOD */
+                  control,
+                  &r[0], &r[1], &r[2], &r[3]);  /* outputs */
+      break;
+   case TGSI_TEXTURE_CUBE_ARRAY:
+      FETCH(&r[0], 0, TGSI_CHAN_X);
+      FETCH(&r[1], 0, TGSI_CHAN_Y);
+      FETCH(&r[2], 0, TGSI_CHAN_Z);
+      FETCH(&r[3], 0, TGSI_CHAN_W);
+
+      if (modifier == TEX_MODIFIER_EXPLICIT_LOD ||
+          modifier == TEX_MODIFIER_LOD_BIAS)
+         FETCH(&cubelod, 1, TGSI_CHAN_X);
+      else
+         cubelod = ZeroVec;
+
+      fetch_texel(mach->Samplers[unit],
+                  &r[0], &r[1], &r[2], &r[3], &cubelod,    /* S, T, P, LOD */
                   control,
                   &r[0], &r[1], &r[2], &r[3]);  /* outputs */
       break;
@@ -1874,11 +1898,24 @@ exec_tex(struct tgsi_exec_machine *mach,
       }
 
       fetch_texel(mach->Samplers[unit],
-                  &r[0], &r[1], &r[2], lod,
+                  &r[0], &r[1], &r[2], lod, &ZeroVec,
                   control,
                   &r[0], &r[1], &r[2], &r[3]);
       break;
 
+   case TGSI_TEXTURE_SHADOWCUBE_ARRAY:
+      FETCH(&r[0], 0, TGSI_CHAN_X);
+      FETCH(&r[1], 0, TGSI_CHAN_Y);
+      FETCH(&r[2], 0, TGSI_CHAN_Z);
+      FETCH(&r[3], 0, TGSI_CHAN_W);
+
+      FETCH(&cubearraycomp, 1, TGSI_CHAN_X);
+
+      fetch_texel(mach->Samplers[unit],
+                  &r[0], &r[1], &r[2], &r[3], &cubearraycomp, /* S, T, P, LOD */
+                  control,
+                  &r[0], &r[1], &r[2], &r[3]);  /* outputs */
+      break;
    default:
       assert(0);
    }
@@ -1920,7 +1957,7 @@ exec_txd(struct tgsi_exec_machine *mach,
       FETCH(&r[0], 0, TGSI_CHAN_X);
 
       fetch_texel(mach->Samplers[unit],
-                  &r[0], &ZeroVec, &ZeroVec, &ZeroVec,   /* S, T, P, BIAS */
+                  &r[0], &ZeroVec, &ZeroVec, &ZeroVec, &ZeroVec,   /* S, T, P, BIAS */
                   tgsi_sampler_lod_bias,
                   &r[0], &r[1], &r[2], &r[3]);           /* R, G, B, A */
       break;
@@ -1937,7 +1974,7 @@ exec_txd(struct tgsi_exec_machine *mach,
       FETCH(&r[2], 0, TGSI_CHAN_Z);
 
       fetch_texel(mach->Samplers[unit],
-                  &r[0], &r[1], &r[2], &ZeroVec,   /* inputs */
+                  &r[0], &r[1], &r[2], &ZeroVec, &ZeroVec,   /* inputs */
                   tgsi_sampler_lod_bias,
                   &r[0], &r[1], &r[2], &r[3]);     /* outputs */
       break;
@@ -1945,13 +1982,13 @@ exec_txd(struct tgsi_exec_machine *mach,
    case TGSI_TEXTURE_2D_ARRAY:
    case TGSI_TEXTURE_3D:
    case TGSI_TEXTURE_CUBE:
-
+   case TGSI_TEXTURE_CUBE_ARRAY:
       FETCH(&r[0], 0, TGSI_CHAN_X);
       FETCH(&r[1], 0, TGSI_CHAN_Y);
       FETCH(&r[2], 0, TGSI_CHAN_Z);
 
       fetch_texel(mach->Samplers[unit],
-                  &r[0], &r[1], &r[2], &ZeroVec,
+                  &r[0], &r[1], &r[2], &ZeroVec, &ZeroVec,
                   tgsi_sampler_lod_bias,
                   &r[0], &r[1], &r[2], &r[3]);
       break;
@@ -1964,7 +2001,7 @@ exec_txd(struct tgsi_exec_machine *mach,
       FETCH(&r[3], 0, TGSI_CHAN_W);
 
       fetch_texel(mach->Samplers[unit],
-                  &r[0], &r[1], &r[2], &r[3],
+                  &r[0], &r[1], &r[2], &r[3], &ZeroVec,
                   tgsi_sampler_lod_bias,
                   &r[0], &r[1], &r[2], &r[3]);
       break;
@@ -2121,7 +2158,7 @@ exec_sample(struct tgsi_exec_machine *mach,
       }
 
       fetch_texel(mach->Samplers[sampler_unit],
-                  &r[0], &ZeroVec, &ZeroVec, lod,  /* S, T, P, LOD */
+                  &r[0], &ZeroVec, &ZeroVec, lod, &ZeroVec,  /* S, T, P, LOD */
                   control,
                   &r[0], &r[1], &r[2], &r[3]);     /* R, G, B, A */
       break;
@@ -2143,7 +2180,7 @@ exec_sample(struct tgsi_exec_machine *mach,
       }
 
       fetch_texel(mach->Samplers[sampler_unit],
-                  &r[0], &r[1], &r[2], lod,     /* S, T, P, LOD */
+                  &r[0], &r[1], &r[2], lod, &ZeroVec,     /* S, T, P, LOD */
                   control,
                   &r[0], &r[1], &r[2], &r[3]);  /* outputs */
       break;
@@ -2151,6 +2188,7 @@ exec_sample(struct tgsi_exec_machine *mach,
    case TGSI_TEXTURE_2D_ARRAY:
    case TGSI_TEXTURE_3D:
    case TGSI_TEXTURE_CUBE:
+   case TGSI_TEXTURE_CUBE_ARRAY:
       FETCH(&r[0], 0, TGSI_CHAN_X);
       FETCH(&r[1], 0, TGSI_CHAN_Y);
       FETCH(&r[2], 0, TGSI_CHAN_Z);
@@ -2162,7 +2200,7 @@ exec_sample(struct tgsi_exec_machine *mach,
       }
 
       fetch_texel(mach->Samplers[sampler_unit],
-                  &r[0], &r[1], &r[2], lod,
+                  &r[0], &r[1], &r[2], lod, &ZeroVec,
                   control,
                   &r[0], &r[1], &r[2], &r[3]);
       break;
@@ -2177,7 +2215,7 @@ exec_sample(struct tgsi_exec_machine *mach,
       assert(modifier != TEX_MODIFIER_PROJECTED);
 
       fetch_texel(mach->Samplers[sampler_unit],
-                  &r[0], &r[1], &r[2], &r[3],
+                  &r[0], &r[1], &r[2], &r[3], &ZeroVec,
                   control,
                   &r[0], &r[1], &r[2], &r[3]);
       break;
@@ -2212,7 +2250,7 @@ exec_sample_d(struct tgsi_exec_machine *mach,
       FETCH(&r[0], 0, TGSI_CHAN_X);
 
       fetch_texel(mach->Samplers[sampler_unit],
-                  &r[0], &ZeroVec, &ZeroVec, &ZeroVec,   /* S, T, P, BIAS */
+                  &r[0], &ZeroVec, &ZeroVec, &ZeroVec, &ZeroVec,   /* S, T, P, BIAS */
                   tgsi_sampler_lod_bias,
                   &r[0], &r[1], &r[2], &r[3]);           /* R, G, B, A */
       break;
@@ -2227,20 +2265,21 @@ exec_sample_d(struct tgsi_exec_machine *mach,
       FETCH(&r[2], 0, TGSI_CHAN_Z);
 
       fetch_texel(mach->Samplers[sampler_unit],
-                  &r[0], &r[1], &r[2], &ZeroVec,   /* inputs */
+                  &r[0], &r[1], &r[2], &ZeroVec, &ZeroVec,   /* inputs */
                   tgsi_sampler_lod_bias,
                   &r[0], &r[1], &r[2], &r[3]);     /* outputs */
       break;
 
    case TGSI_TEXTURE_3D:
    case TGSI_TEXTURE_CUBE:
+   case TGSI_TEXTURE_CUBE_ARRAY:
 
       FETCH(&r[0], 0, TGSI_CHAN_X);
       FETCH(&r[1], 0, TGSI_CHAN_Y);
       FETCH(&r[2], 0, TGSI_CHAN_Z);
 
       fetch_texel(mach->Samplers[sampler_unit],
-                  &r[0], &r[1], &r[2], &ZeroVec,
+                  &r[0], &r[1], &r[2], &ZeroVec, &ZeroVec,
                   tgsi_sampler_lod_bias,
                   &r[0], &r[1], &r[2], &r[3]);
       break;
@@ -3643,14 +3682,14 @@ exec_instruction(
       /* simple texture lookup */
       /* src[0] = texcoord */
       /* src[1] = sampler unit */
-      exec_tex(mach, inst, TEX_MODIFIER_NONE);
+      exec_tex(mach, inst, TEX_MODIFIER_NONE, 1);
       break;
 
    case TGSI_OPCODE_TXB:
       /* Texture lookup with lod bias */
       /* src[0] = texcoord (src[0].w = LOD bias) */
       /* src[1] = sampler unit */
-      exec_tex(mach, inst, TEX_MODIFIER_LOD_BIAS);
+      exec_tex(mach, inst, TEX_MODIFIER_LOD_BIAS, 1);
       break;
 
    case TGSI_OPCODE_TXD:
@@ -3666,14 +3705,14 @@ exec_instruction(
       /* Texture lookup with explit LOD */
       /* src[0] = texcoord (src[0].w = LOD) */
       /* src[1] = sampler unit */
-      exec_tex(mach, inst, TEX_MODIFIER_EXPLICIT_LOD);
+      exec_tex(mach, inst, TEX_MODIFIER_EXPLICIT_LOD, 1);
       break;
 
    case TGSI_OPCODE_TXP:
       /* Texture lookup with projection */
       /* src[0] = texcoord (src[0].w = projection) */
       /* src[1] = sampler unit */
-      exec_tex(mach, inst, TEX_MODIFIER_PROJECTED);
+      exec_tex(mach, inst, TEX_MODIFIER_PROJECTED, 1);
       break;
 
    case TGSI_OPCODE_UP2H:
@@ -4208,6 +4247,27 @@ exec_instruction(
       exec_vector_unary(mach, inst, micro_isgn, TGSI_EXEC_DATA_INT, TGSI_EXEC_DATA_INT);
       break;
 
+   case TGSI_OPCODE_TEX2:
+      /* simple texture lookup */
+      /* src[0] = texcoord */
+      /* src[1] = compare */
+      /* src[2] = sampler unit */
+      exec_tex(mach, inst, TEX_MODIFIER_NONE, 2);
+      break;
+   case TGSI_OPCODE_TXB2:
+      /* simple texture lookup */
+      /* src[0] = texcoord */
+      /* src[1] = bias */
+      /* src[2] = sampler unit */
+      exec_tex(mach, inst, TEX_MODIFIER_LOD_BIAS, 2);
+      break;
+   case TGSI_OPCODE_TXL2:
+      /* simple texture lookup */
+      /* src[0] = texcoord */
+      /* src[1] = lod */
+      /* src[2] = sampler unit */
+      exec_tex(mach, inst, TEX_MODIFIER_EXPLICIT_LOD, 2);
+      break;
    default:
       assert( 0 );
    }
index 0ecb4e9..fc1ee09 100644 (file)
@@ -100,11 +100,24 @@ enum tgsi_sampler_control {
 struct tgsi_sampler
 {
    /** Get samples for four fragments in a quad */
+   /* this interface contains 5 sets of channels that vary
+    * depending on the sampler.
+    * s - the first texture coordinate for sampling.
+    * t - the second texture coordinate for sampling - unused for 1D,
+          layer for 1D arrays.
+    * p - the third coordinate for sampling for 3D, cube, cube arrays,
+    *     layer for 2D arrays. Compare value for 1D/2D shadows.
+    * c0 - lod value for lod variants, compare value for shadow cube
+    *      and shadow 2d arrays.
+    * c1 - cube array only - lod for cube map arrays
+    *                        compare for shadow cube map arrays.
+    */
    void (*get_samples)(struct tgsi_sampler *sampler,
                        const float s[TGSI_QUAD_SIZE],
                        const float t[TGSI_QUAD_SIZE],
                        const float p[TGSI_QUAD_SIZE],
                        const float c0[TGSI_QUAD_SIZE],
+                       const float c1[TGSI_QUAD_SIZE],
                        enum tgsi_sampler_control control,
                        float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]);
    void (*get_dims)(struct tgsi_sampler *sampler, int level,
index 5051462..3a38182 100644 (file)
@@ -169,6 +169,7 @@ softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
    case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT:
       return 0;
    case PIPE_CAP_QUERY_TIMESTAMP:
+   case PIPE_CAP_CUBE_MAP_ARRAY:
       return 1;
    }
    /* should only get here on unhandled cases */
@@ -279,7 +280,8 @@ softpipe_is_format_supported( struct pipe_screen *screen,
           target == PIPE_TEXTURE_2D_ARRAY ||
           target == PIPE_TEXTURE_RECT ||
           target == PIPE_TEXTURE_3D ||
-          target == PIPE_TEXTURE_CUBE);
+          target == PIPE_TEXTURE_CUBE ||
+          target == PIPE_TEXTURE_CUBE_ARRAY);
 
    format_desc = util_format_description(format);
    if (!format_desc)
index 992a2f7..5bbf11c 100644 (file)
@@ -739,6 +739,25 @@ get_texel_2d_array(const struct sp_sampler_variant *samp,
 }
 
 
+/* Get texel pointer for cube array texture */
+static INLINE const float *
+get_texel_cube_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 < (int) texture->array_size);
+   assert(layer >= 0);
+
+   if (x < 0 || x >= (int) u_minify(texture->width0, level) ||
+       y < 0 || y >= (int) u_minify(texture->height0, level)) {
+      return samp->sampler->border_color.f;
+   }
+   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.
@@ -1123,6 +1142,45 @@ img_filter_cube_nearest(struct tgsi_sampler *tgsi_sampler,
    }
 }
 
+static void
+img_filter_cube_array_nearest(struct tgsi_sampler *tgsi_sampler,
+                        float s,
+                        float t,
+                        float p,
+                        unsigned level,
+                        unsigned face_id,
+                        enum tgsi_sampler_control control,
+                        float *rgba)
+{
+   const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
+   const struct pipe_resource *texture = samp->view->texture;
+   int width, height;
+   int x, y, layer;
+   union tex_tile_address addr;
+   const float *out;
+   int c;
+
+   width = u_minify(texture->width0, level);
+   height = u_minify(texture->height0, level);
+
+   assert(width > 0);
+   assert(height > 0);
+   addr.value = 0;
+   addr.bits.level = level;
+
+   samp->nearest_texcoord_s(s, width, &x);
+   samp->nearest_texcoord_t(t, height, &y);
+   wrap_array_layer(p, texture->array_size, &layer);
+
+   out = get_texel_cube_array(samp, addr, x, y, layer * 6 + face_id);
+   for (c = 0; c < TGSI_QUAD_SIZE; c++)
+      rgba[TGSI_NUM_CHANNELS*c] = out[c];
+
+   if (DEBUG_TEX) {
+      print_sample(__FUNCTION__, rgba);
+   }
+}
 
 static void
 img_filter_3d_nearest(struct tgsi_sampler *tgsi_sampler,
@@ -1373,6 +1431,50 @@ img_filter_cube_linear(struct tgsi_sampler *tgsi_sampler,
 
 
 static void
+img_filter_cube_array_linear(struct tgsi_sampler *tgsi_sampler,
+                             float s,
+                             float t,
+                             float p,
+                             unsigned level,
+                             unsigned face_id,
+                             enum tgsi_sampler_control control,
+                             float *rgba)
+{
+   const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
+   const struct pipe_resource *texture = samp->view->texture;
+   int width, height;
+   int x0, y0, x1, y1, layer;
+   float xw, yw; /* weights */
+   union tex_tile_address addr, addrj;
+   const float *tx0, *tx1, *tx2, *tx3;
+   int c;
+
+   width = u_minify(texture->width0, level);
+   height = u_minify(texture->height0, level);
+
+   assert(width > 0);
+   assert(height > 0);
+
+   addr.value = 0;
+   addr.bits.level = level;
+
+   samp->linear_texcoord_s(s, width,  &x0, &x1, &xw);
+   samp->linear_texcoord_t(t, height, &y0, &y1, &yw);
+   wrap_array_layer(p, texture->array_size, &layer);
+
+   tx0 = get_texel_cube_array(samp, addr, x0, y0, layer * 6 + face_id);
+   tx1 = get_texel_cube_array(samp, addr, x1, y0, layer * 6 + face_id);
+   tx2 = get_texel_cube_array(samp, addr, x0, y1, layer * 6 + face_id);
+   tx3 = get_texel_cube_array(samp, addr, x1, y1, layer * 6 + face_id);
+
+   /* interpolate R, G, B, A */
+   for (c = 0; c < TGSI_QUAD_SIZE; c++)
+      rgba[TGSI_NUM_CHANNELS*c] = lerp_2d(xw, yw,
+                                          tx0[c], tx1[c],
+                                          tx2[c], tx3[c]);
+}
+
+static void
 img_filter_3d_linear(struct tgsi_sampler *tgsi_sampler,
                      float s,
                      float t,
@@ -1451,6 +1553,7 @@ mip_filter_linear(struct tgsi_sampler *tgsi_sampler,
                   const float t[TGSI_QUAD_SIZE],
                   const float p[TGSI_QUAD_SIZE],
                   const float c0[TGSI_QUAD_SIZE],
+                  const float c1[TGSI_QUAD_SIZE],
                   enum tgsi_sampler_control control,
                   float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
 {
@@ -1461,11 +1564,18 @@ mip_filter_linear(struct tgsi_sampler *tgsi_sampler,
 
    if (control == tgsi_sampler_lod_bias) {
       float lambda = samp->compute_lambda(samp, s, t, p) + samp->sampler->lod_bias;
-      compute_lod(samp->sampler, lambda, c0, lod);
+      if (samp->key.bits.target == PIPE_TEXTURE_CUBE_ARRAY)
+         compute_lod(samp->sampler, lambda, c1, lod);
+      else
+         compute_lod(samp->sampler, lambda, c0, lod);
    } else {
       assert(control == tgsi_sampler_lod_explicit);
 
-      memcpy(lod, c0, sizeof(lod));
+      if (samp->key.bits.target == PIPE_TEXTURE_CUBE_ARRAY)
+         memcpy(lod, c1, sizeof(lod));
+      else
+         memcpy(lod, c0, sizeof(lod));
+
    }
 
    for (j = 0; j < TGSI_QUAD_SIZE; j++) {
@@ -1508,6 +1618,7 @@ mip_filter_nearest(struct tgsi_sampler *tgsi_sampler,
                    const float t[TGSI_QUAD_SIZE],
                    const float p[TGSI_QUAD_SIZE],
                    const float c0[TGSI_QUAD_SIZE],
+                   const float c1[TGSI_QUAD_SIZE],
                    enum tgsi_sampler_control control,
                    float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
 {
@@ -1518,11 +1629,17 @@ mip_filter_nearest(struct tgsi_sampler *tgsi_sampler,
 
    if (control == tgsi_sampler_lod_bias) {
       float lambda = samp->compute_lambda(samp, s, t, p) + samp->sampler->lod_bias;
-      compute_lod(samp->sampler, lambda, c0, lod);
+      if (samp->key.bits.target == PIPE_TEXTURE_CUBE_ARRAY)
+         compute_lod(samp->sampler, lambda, c1, lod);
+      else
+         compute_lod(samp->sampler, lambda, c0, lod);
    } else {
       assert(control == tgsi_sampler_lod_explicit);
 
-      memcpy(lod, c0, sizeof(lod));
+      if (samp->key.bits.target == PIPE_TEXTURE_CUBE_ARRAY)
+         memcpy(lod, c1, sizeof(lod));
+      else
+         memcpy(lod, c0, sizeof(lod));
    }
 
    for (j = 0; j < TGSI_QUAD_SIZE; j++) {
@@ -1547,6 +1664,7 @@ mip_filter_none(struct tgsi_sampler *tgsi_sampler,
                 const float t[TGSI_QUAD_SIZE],
                 const float p[TGSI_QUAD_SIZE],
                 const float c0[TGSI_QUAD_SIZE],
+                const float c1[TGSI_QUAD_SIZE],
                 enum tgsi_sampler_control control,
                 float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
 {
@@ -1556,11 +1674,17 @@ mip_filter_none(struct tgsi_sampler *tgsi_sampler,
 
    if (control == tgsi_sampler_lod_bias) {
       float lambda = samp->compute_lambda(samp, s, t, p) + samp->sampler->lod_bias;
-      compute_lod(samp->sampler, lambda, c0, lod);
+      if (samp->key.bits.target == PIPE_TEXTURE_CUBE_ARRAY)
+         compute_lod(samp->sampler, lambda, c1, lod);
+      else
+         compute_lod(samp->sampler, lambda, c0, lod);
    } else {
       assert(control == tgsi_sampler_lod_explicit);
 
-      memcpy(lod, c0, sizeof(lod));
+      if (samp->key.bits.target == PIPE_TEXTURE_CUBE_ARRAY)
+         memcpy(lod, c1, sizeof(lod));
+      else
+         memcpy(lod, c0, sizeof(lod));
    }
 
    for (j = 0; j < TGSI_QUAD_SIZE; j++) {
@@ -1580,6 +1704,7 @@ mip_filter_none_no_filter_select(struct tgsi_sampler *tgsi_sampler,
                                      const float t[TGSI_QUAD_SIZE],
                                      const float p[TGSI_QUAD_SIZE],
                                      const float c0[TGSI_QUAD_SIZE],
+                                     const float c1[TGSI_QUAD_SIZE],
                                      enum tgsi_sampler_control control,
                                      float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
 {
@@ -1814,6 +1939,7 @@ mip_filter_linear_aniso(struct tgsi_sampler *tgsi_sampler,
                         const float t[TGSI_QUAD_SIZE],
                         const float p[TGSI_QUAD_SIZE],
                         const float c0[TGSI_QUAD_SIZE],
+                        const float c1[TGSI_QUAD_SIZE],
                         enum tgsi_sampler_control control,
                         float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
 {
@@ -1913,6 +2039,7 @@ mip_filter_linear_2d_linear_repeat_POT(
    const float t[TGSI_QUAD_SIZE],
    const float p[TGSI_QUAD_SIZE],
    const float c0[TGSI_QUAD_SIZE],
+   const float c1[TGSI_QUAD_SIZE],
    enum tgsi_sampler_control control,
    float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
 {
@@ -1971,6 +2098,7 @@ sample_compare(struct tgsi_sampler *tgsi_sampler,
                const float t[TGSI_QUAD_SIZE],
                const float p[TGSI_QUAD_SIZE],
                const float c0[TGSI_QUAD_SIZE],
+               const float c1[TGSI_QUAD_SIZE],
                enum tgsi_sampler_control control,
                float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
 {
@@ -1980,7 +2108,7 @@ sample_compare(struct tgsi_sampler *tgsi_sampler,
    float val;
    float pc0, pc1, pc2, pc3;
 
-   samp->mip_filter(tgsi_sampler, s, t, p, c0, control, rgba);
+   samp->mip_filter(tgsi_sampler, s, t, p, c0, c1, control, rgba);
 
    /**
     * Compare texcoord 'p' (aka R) against texture value 'rgba[0]'
@@ -1995,6 +2123,11 @@ sample_compare(struct tgsi_sampler *tgsi_sampler,
       pc1 = CLAMP(c0[1], 0.0F, 1.0F);
       pc2 = CLAMP(c0[2], 0.0F, 1.0F);
       pc3 = CLAMP(c0[3], 0.0F, 1.0F);
+   } else if (samp->view->texture->target == PIPE_TEXTURE_CUBE_ARRAY) {
+      pc0 = CLAMP(c1[0], 0.0F, 1.0F);
+      pc1 = CLAMP(c1[1], 0.0F, 1.0F);
+      pc2 = CLAMP(c1[2], 0.0F, 1.0F);
+      pc3 = CLAMP(c1[3], 0.0F, 1.0F);
    } else {
       pc0 = CLAMP(p[0], 0.0F, 1.0F);
       pc1 = CLAMP(p[1], 0.0F, 1.0F);
@@ -2081,6 +2214,7 @@ sample_cube(struct tgsi_sampler *tgsi_sampler,
             const float t[TGSI_QUAD_SIZE],
             const float p[TGSI_QUAD_SIZE],
             const float c0[TGSI_QUAD_SIZE],
+            const float c1[TGSI_QUAD_SIZE],
             enum tgsi_sampler_control control,
             float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
 {
@@ -2091,8 +2225,12 @@ sample_cube(struct tgsi_sampler *tgsi_sampler,
    /* Not actually used, but the intermediate steps that do the
     * dereferencing don't know it.
     */
-   static const float pppp[4] = { 0, 0, 0, 0 };
+   static float pppp[4] = { 0, 0, 0, 0 };
 
+   pppp[0] = c0[0];
+   pppp[1] = c0[1];
+   pppp[2] = c0[2];
+   pppp[3] = c0[3];
    /*
      major axis
      direction    target                             sc     tc    ma
@@ -2160,7 +2298,7 @@ sample_cube(struct tgsi_sampler *tgsi_sampler,
     * is not active, this will point somewhere deeper into the
     * pipeline, eg. to mip_filter or even img_filter.
     */
-   samp->compare(tgsi_sampler, ssss, tttt, pppp, c0, control, rgba);
+   samp->compare(tgsi_sampler, ssss, tttt, pppp, c0, c1, control, rgba);
 }
 
 
@@ -2243,13 +2381,14 @@ sample_swizzle(struct tgsi_sampler *tgsi_sampler,
                const float t[TGSI_QUAD_SIZE],
                const float p[TGSI_QUAD_SIZE],
                const float c0[TGSI_QUAD_SIZE],
+               const float c1[TGSI_QUAD_SIZE],
                enum tgsi_sampler_control control,
                float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
 {
    struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
    float rgba_temp[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE];
 
-   samp->sample_target(tgsi_sampler, s, t, p, c0, control, rgba_temp);
+   samp->sample_target(tgsi_sampler, s, t, p, c0, c1, control, rgba_temp);
 
    do_swizzling(samp, rgba_temp, rgba);
 }
@@ -2370,6 +2509,7 @@ get_lambda_func(const union sp_sampler_key key)
    case PIPE_TEXTURE_2D_ARRAY:
    case PIPE_TEXTURE_RECT:
    case PIPE_TEXTURE_CUBE:
+   case PIPE_TEXTURE_CUBE_ARRAY:
       return compute_lambda_2d;
    case PIPE_TEXTURE_3D:
       return compute_lambda_3d;
@@ -2445,6 +2585,12 @@ get_img_filter(const union sp_sampler_key key,
       else
          return img_filter_cube_linear;
       break;
+   case PIPE_TEXTURE_CUBE_ARRAY:
+      if (filter == PIPE_TEX_FILTER_NEAREST) 
+         return img_filter_cube_array_nearest;
+      else
+         return img_filter_cube_array_linear;
+      break;
    case PIPE_TEXTURE_3D:
       if (filter == PIPE_TEX_FILTER_NEAREST) 
          return img_filter_3d_nearest;
@@ -2516,6 +2662,10 @@ sample_get_dims(struct tgsi_sampler *tgsi_sampler, int level,
        dims[1] = u_minify(texture->height0, level);
        dims[2] = u_minify(texture->depth0, level);
        return;
+    case PIPE_TEXTURE_CUBE_ARRAY:
+       dims[1] = u_minify(texture->height0, level);
+       dims[2] = texture->array_size / 6;
+       return;
     default:
        assert(!"unexpected texture target in sample_get_dims()");
        return;
@@ -2722,7 +2872,7 @@ sp_create_sampler_variant( const struct pipe_sampler_state *sampler,
       samp->compare = samp->mip_filter;
    }
    
-   if (key.bits.target == PIPE_TEXTURE_CUBE) {
+   if (key.bits.target == PIPE_TEXTURE_CUBE || key.bits.target == PIPE_TEXTURE_CUBE_ARRAY) {
       samp->sample_target = sample_cube;
    }
    else {
index dd847af..8415196 100644 (file)
@@ -63,13 +63,14 @@ typedef void (*filter_func)(struct tgsi_sampler *tgsi_sampler,
                             const float t[TGSI_QUAD_SIZE],
                             const float p[TGSI_QUAD_SIZE],
                             const float c0[TGSI_QUAD_SIZE],
+                            const float c1[TGSI_QUAD_SIZE],
                             enum tgsi_sampler_control control,
                             float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]);
 
 
 union sp_sampler_key {
    struct {
-      unsigned target:3;
+      unsigned target:5;
       unsigned is_pot:1;
       unsigned processor:2;
       unsigned unit:4;
@@ -77,7 +78,7 @@ union sp_sampler_key {
       unsigned swizzle_g:3;
       unsigned swizzle_b:3;
       unsigned swizzle_a:3;
-      unsigned pad:10;
+      unsigned pad:8;
    } bits;
    unsigned value;
 };
index b4bca07..9c31daa 100644 (file)
@@ -258,6 +258,7 @@ sp_get_tex_image_offset(const struct softpipe_resource *spr,
    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];
@@ -364,6 +365,9 @@ softpipe_transfer_map(struct pipe_context *pipe,
       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);
+      }
       else {
          assert(box->z + box->depth <= (u_minify(resource->depth0, level)));
       }