diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_exec.c | 120 | ||||
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_exec.h | 13 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_screen.c | 4 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_tex_sample.c | 172 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_tex_sample.h | 5 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_texture.c | 4 |
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))); } |