[Mesa-dev] [PATCH 08/10] softpipe: add ARB_texture_cube_map_array support
Dave Airlie
airlied at gmail.com
Tue Nov 6 14:16:03 PST 2012
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.
Signed-off-by: Dave Airlie <airlied at redhat.com>
---
src/gallium/auxiliary/tgsi/tgsi_exec.c | 112 ++++++++++++-----
src/gallium/auxiliary/tgsi/tgsi_exec.h | 1 +
src/gallium/drivers/softpipe/sp_screen.c | 4 +-
src/gallium/drivers/softpipe/sp_tex_sample.c | 172 +++++++++++++++++++++++++--
src/gallium/drivers/softpipe/sp_tex_sample.h | 5 +-
src/gallium/drivers/softpipe/sp_texture.c | 4 +
6 files changed, 255 insertions(+), 43 deletions(-)
diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c
index 0b58f09..3ccf94e 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];
@@ -1738,15 +1739,15 @@ fetch_texel( struct tgsi_sampler *sampler,
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 +1769,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 +1782,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 +1802,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 +1816,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 +1830,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 +1846,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 +1858,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 +1892,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 +1951,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 +1968,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 +1976,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 +1995,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 +2152,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 +2174,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 +2182,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 +2194,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 +2209,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 +2244,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 +2259,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 +3676,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 +3699,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 +4241,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 0ecb4e9..70d1fef 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_exec.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_exec.h
@@ -105,6 +105,7 @@ struct 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]);
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 5051462..3a38182 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 992a2f7..5bbf11c 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 dd847af..8415196 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 b4bca07..9c31daa 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)));
}
--
1.7.11.7
More information about the mesa-dev
mailing list