summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_exec.c120
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_exec.h13
-rw-r--r--src/gallium/drivers/softpipe/sp_screen.c4
-rw-r--r--src/gallium/drivers/softpipe/sp_tex_sample.c172
-rw-r--r--src/gallium/drivers/softpipe/sp_tex_sample.h5
-rw-r--r--src/gallium/drivers/softpipe/sp_texture.c4
6 files changed, 274 insertions, 44 deletions
diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c
index 0b58f097ecf..428227d735f 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_exec.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c
@@ -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 );
}
diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.h b/src/gallium/auxiliary/tgsi/tgsi_exec.h
index 0ecb4e952bb..fc1ee09abf3 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_exec.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_exec.h
@@ -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,
diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c
index 5051462bf12..3a38182994c 100644
--- a/src/gallium/drivers/softpipe/sp_screen.c
+++ b/src/gallium/drivers/softpipe/sp_screen.c
@@ -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)
diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c
index 992a2f760f8..5bbf11cb0ad 100644
--- a/src/gallium/drivers/softpipe/sp_tex_sample.c
+++ b/src/gallium/drivers/softpipe/sp_tex_sample.c
@@ -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 {
diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.h b/src/gallium/drivers/softpipe/sp_tex_sample.h
index dd847af69d7..8415196dfbd 100644
--- a/src/gallium/drivers/softpipe/sp_tex_sample.h
+++ b/src/gallium/drivers/softpipe/sp_tex_sample.h
@@ -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;
};
diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c
index b4bca076bda..9c31daa63f3 100644
--- a/src/gallium/drivers/softpipe/sp_texture.c
+++ b/src/gallium/drivers/softpipe/sp_texture.c
@@ -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)));
}