softpipe: support for 1D/2D texture arrays
This commit is contained in:
@@ -125,6 +125,8 @@ softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
|
||||
return 1;
|
||||
case PIPE_CAP_INSTANCED_DRAWING:
|
||||
return 1;
|
||||
case PIPE_CAP_ARRAY_TEXTURES:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@@ -185,7 +187,9 @@ softpipe_is_format_supported( struct pipe_screen *screen,
|
||||
|
||||
assert(target == PIPE_BUFFER ||
|
||||
target == PIPE_TEXTURE_1D ||
|
||||
target == PIPE_TEXTURE_1D_ARRAY ||
|
||||
target == PIPE_TEXTURE_2D ||
|
||||
target == PIPE_TEXTURE_2D_ARRAY ||
|
||||
target == PIPE_TEXTURE_RECT ||
|
||||
target == PIPE_TEXTURE_3D ||
|
||||
target == PIPE_TEXTURE_CUBE);
|
||||
|
@@ -539,6 +539,19 @@ wrap_linear_unorm_clamp_to_edge(const float s[4], unsigned size,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Do coordinate to array index conversion. For array textures.
|
||||
*/
|
||||
static INLINE void
|
||||
wrap_array_layer(const float coord[4], unsigned size, int layer[4])
|
||||
{
|
||||
uint ch;
|
||||
for (ch = 0; ch < 4; ch++) {
|
||||
int c = util_ifloor(coord[ch] + 0.5F);
|
||||
layer[ch] = CLAMP(c, 0, size - 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Examine the quad's texture coordinates to compute the partial
|
||||
@@ -989,6 +1002,47 @@ img_filter_1d_nearest(struct tgsi_sampler *tgsi_sampler,
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
img_filter_1d_array_nearest(struct tgsi_sampler *tgsi_sampler,
|
||||
const float s[QUAD_SIZE],
|
||||
const float t[QUAD_SIZE],
|
||||
const float p[QUAD_SIZE],
|
||||
const float c0[QUAD_SIZE],
|
||||
enum tgsi_sampler_control control,
|
||||
float rgba[NUM_CHANNELS][QUAD_SIZE])
|
||||
{
|
||||
const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
|
||||
const struct pipe_resource *texture = samp->view->texture;
|
||||
unsigned level0, j;
|
||||
int width;
|
||||
int x[4], layer[4];
|
||||
union tex_tile_address addr;
|
||||
|
||||
level0 = samp->level;
|
||||
width = u_minify(texture->width0, level0);
|
||||
|
||||
assert(width > 0);
|
||||
|
||||
addr.value = 0;
|
||||
addr.bits.level = samp->level;
|
||||
|
||||
samp->nearest_texcoord_s(s, width, x);
|
||||
wrap_array_layer(t, texture->height0, layer);
|
||||
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
const float *out = get_texel_2d(samp, addr, x[j], layer[j]);
|
||||
int c;
|
||||
for (c = 0; c < 4; c++) {
|
||||
rgba[c][j] = out[c];
|
||||
}
|
||||
}
|
||||
|
||||
if (DEBUG_TEX) {
|
||||
print_sample(__FUNCTION__, rgba);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
img_filter_2d_nearest(struct tgsi_sampler *tgsi_sampler,
|
||||
const float s[QUAD_SIZE],
|
||||
@@ -1033,6 +1087,50 @@ img_filter_2d_nearest(struct tgsi_sampler *tgsi_sampler,
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
img_filter_2d_array_nearest(struct tgsi_sampler *tgsi_sampler,
|
||||
const float s[QUAD_SIZE],
|
||||
const float t[QUAD_SIZE],
|
||||
const float p[QUAD_SIZE],
|
||||
const float c0[QUAD_SIZE],
|
||||
enum tgsi_sampler_control control,
|
||||
float rgba[NUM_CHANNELS][QUAD_SIZE])
|
||||
{
|
||||
const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
|
||||
const struct pipe_resource *texture = samp->view->texture;
|
||||
unsigned level0, j;
|
||||
int width, height;
|
||||
int x[4], y[4], layer[4];
|
||||
union tex_tile_address addr;
|
||||
|
||||
level0 = samp->level;
|
||||
width = u_minify(texture->width0, level0);
|
||||
height = u_minify(texture->height0, level0);
|
||||
|
||||
assert(width > 0);
|
||||
assert(height > 0);
|
||||
|
||||
addr.value = 0;
|
||||
addr.bits.level = samp->level;
|
||||
|
||||
samp->nearest_texcoord_s(s, width, x);
|
||||
samp->nearest_texcoord_t(t, height, y);
|
||||
wrap_array_layer(p, texture->depth0, layer);
|
||||
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
const float *out = get_texel_3d(samp, addr, x[j], y[j], layer[j]);
|
||||
int c;
|
||||
for (c = 0; c < 4; c++) {
|
||||
rgba[c][j] = out[c];
|
||||
}
|
||||
}
|
||||
|
||||
if (DEBUG_TEX) {
|
||||
print_sample(__FUNCTION__, rgba);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static INLINE union tex_tile_address
|
||||
face(union tex_tile_address addr, unsigned face )
|
||||
{
|
||||
@@ -1167,6 +1265,47 @@ img_filter_1d_linear(struct tgsi_sampler *tgsi_sampler,
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
img_filter_1d_array_linear(struct tgsi_sampler *tgsi_sampler,
|
||||
const float s[QUAD_SIZE],
|
||||
const float t[QUAD_SIZE],
|
||||
const float p[QUAD_SIZE],
|
||||
const float c0[QUAD_SIZE],
|
||||
enum tgsi_sampler_control control,
|
||||
float rgba[NUM_CHANNELS][QUAD_SIZE])
|
||||
{
|
||||
const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
|
||||
const struct pipe_resource *texture = samp->view->texture;
|
||||
unsigned level0, j;
|
||||
int width;
|
||||
int x0[4], x1[4], layer[4];
|
||||
float xw[4]; /* weights */
|
||||
union tex_tile_address addr;
|
||||
|
||||
level0 = samp->level;
|
||||
width = u_minify(texture->width0, level0);
|
||||
|
||||
assert(width > 0);
|
||||
|
||||
addr.value = 0;
|
||||
addr.bits.level = samp->level;
|
||||
|
||||
samp->linear_texcoord_s(s, width, x0, x1, xw);
|
||||
wrap_array_layer(t, texture->height0, layer);
|
||||
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
const float *tx0 = get_texel_2d(samp, addr, x0[j], layer[j]);
|
||||
const float *tx1 = get_texel_2d(samp, addr, x1[j], layer[j]);
|
||||
int c;
|
||||
|
||||
/* interpolate R, G, B, A */
|
||||
for (c = 0; c < 4; c++) {
|
||||
rgba[c][j] = lerp(xw[j], tx0[c], tx1[c]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
img_filter_2d_linear(struct tgsi_sampler *tgsi_sampler,
|
||||
const float s[QUAD_SIZE],
|
||||
@@ -1214,6 +1353,54 @@ img_filter_2d_linear(struct tgsi_sampler *tgsi_sampler,
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
img_filter_2d_array_linear(struct tgsi_sampler *tgsi_sampler,
|
||||
const float s[QUAD_SIZE],
|
||||
const float t[QUAD_SIZE],
|
||||
const float p[QUAD_SIZE],
|
||||
const float c0[QUAD_SIZE],
|
||||
enum tgsi_sampler_control control,
|
||||
float rgba[NUM_CHANNELS][QUAD_SIZE])
|
||||
{
|
||||
const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
|
||||
const struct pipe_resource *texture = samp->view->texture;
|
||||
unsigned level0, j;
|
||||
int width, height;
|
||||
int x0[4], y0[4], x1[4], y1[4], layer[4];
|
||||
float xw[4], yw[4]; /* weights */
|
||||
union tex_tile_address addr;
|
||||
|
||||
level0 = samp->level;
|
||||
width = u_minify(texture->width0, level0);
|
||||
height = u_minify(texture->height0, level0);
|
||||
|
||||
assert(width > 0);
|
||||
assert(height > 0);
|
||||
|
||||
addr.value = 0;
|
||||
addr.bits.level = samp->level;
|
||||
|
||||
samp->linear_texcoord_s(s, width, x0, x1, xw);
|
||||
samp->linear_texcoord_t(t, height, y0, y1, yw);
|
||||
wrap_array_layer(p, texture->depth0, layer);
|
||||
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
const float *tx0 = get_texel_3d(samp, addr, x0[j], y0[j], layer[j]);
|
||||
const float *tx1 = get_texel_3d(samp, addr, x1[j], y0[j], layer[j]);
|
||||
const float *tx2 = get_texel_3d(samp, addr, x0[j], y1[j], layer[j]);
|
||||
const float *tx3 = get_texel_3d(samp, addr, x1[j], y1[j], layer[j]);
|
||||
int c;
|
||||
|
||||
/* interpolate R, G, B, A */
|
||||
for (c = 0; c < 4; c++) {
|
||||
rgba[c][j] = lerp_2d(xw[j], yw[j],
|
||||
tx0[c], tx1[c],
|
||||
tx2[c], tx3[c]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
img_filter_cube_linear(struct tgsi_sampler *tgsi_sampler,
|
||||
const float s[QUAD_SIZE],
|
||||
@@ -1906,8 +2093,10 @@ get_lambda_func(const union sp_sampler_key key)
|
||||
|
||||
switch (key.bits.target) {
|
||||
case PIPE_TEXTURE_1D:
|
||||
case PIPE_TEXTURE_1D_ARRAY:
|
||||
return compute_lambda_1d;
|
||||
case PIPE_TEXTURE_2D:
|
||||
case PIPE_TEXTURE_2D_ARRAY:
|
||||
case PIPE_TEXTURE_RECT:
|
||||
case PIPE_TEXTURE_CUBE:
|
||||
return compute_lambda_2d;
|
||||
@@ -1932,6 +2121,12 @@ get_img_filter(const union sp_sampler_key key,
|
||||
else
|
||||
return img_filter_1d_linear;
|
||||
break;
|
||||
case PIPE_TEXTURE_1D_ARRAY:
|
||||
if (filter == PIPE_TEX_FILTER_NEAREST)
|
||||
return img_filter_1d_array_nearest;
|
||||
else
|
||||
return img_filter_1d_array_linear;
|
||||
break;
|
||||
case PIPE_TEXTURE_2D:
|
||||
case PIPE_TEXTURE_RECT:
|
||||
/* Try for fast path:
|
||||
@@ -1967,6 +2162,12 @@ get_img_filter(const union sp_sampler_key key,
|
||||
else
|
||||
return img_filter_2d_linear;
|
||||
break;
|
||||
case PIPE_TEXTURE_2D_ARRAY:
|
||||
if (filter == PIPE_TEX_FILTER_NEAREST)
|
||||
return img_filter_2d_array_nearest;
|
||||
else
|
||||
return img_filter_2d_array_linear;
|
||||
break;
|
||||
case PIPE_TEXTURE_CUBE:
|
||||
if (filter == PIPE_TEX_FILTER_NEAREST)
|
||||
return img_filter_cube_nearest;
|
||||
|
@@ -227,9 +227,13 @@ 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_3D) {
|
||||
spr->base.target == PIPE_TEXTURE_3D ||
|
||||
spr->base.target == PIPE_TEXTURE_2D_ARRAY) {
|
||||
offset += layer * nblocksy * spr->stride[level];
|
||||
}
|
||||
else if (spr->base.target == PIPE_TEXTURE_1D_ARRAY) {
|
||||
offset += layer * spr->stride[level];
|
||||
}
|
||||
else {
|
||||
assert(layer == 0);
|
||||
}
|
||||
|
Reference in New Issue
Block a user