softpipe: fix array textures to use resource array_size

Don't use height for 1D array textures or depth for 2D array textures.
This commit is contained in:
Brian Paul 2011-01-28 20:25:27 -07:00
parent b3cfcdf923
commit 80777743b7
3 changed files with 88 additions and 21 deletions

View file

@ -774,6 +774,43 @@ get_texel_3d(const struct sp_sampler_variant *samp,
}
/* Get texel pointer for 1D array texture */
static INLINE const float *
get_texel_1d_array(const struct sp_sampler_variant *samp,
union tex_tile_address addr, int x, int y)
{
const struct pipe_resource *texture = samp->view->texture;
unsigned level = addr.bits.level;
if (x < 0 || x >= (int) u_minify(texture->width0, level)) {
return samp->sampler->border_color;
}
else {
return get_texel_2d_no_border(samp, addr, x, y);
}
}
/* Get texel pointer for 2D array texture */
static INLINE const float *
get_texel_2d_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 < texture->array_size);
if (x < 0 || x >= (int) u_minify(texture->width0, level) ||
y < 0 || y >= (int) u_minify(texture->height0, level)) {
return samp->sampler->border_color;
}
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.
@ -1027,10 +1064,10 @@ img_filter_1d_array_nearest(struct tgsi_sampler *tgsi_sampler,
addr.bits.level = samp->level;
samp->nearest_texcoord_s(s, width, x);
wrap_array_layer(t, texture->height0, layer);
wrap_array_layer(t, texture->array_size, layer);
for (j = 0; j < QUAD_SIZE; j++) {
const float *out = get_texel_2d(samp, addr, x[j], layer[j]);
const float *out = get_texel_1d_array(samp, addr, x[j], layer[j]);
int c;
for (c = 0; c < 4; c++) {
rgba[c][j] = out[c];
@ -1115,10 +1152,10 @@ img_filter_2d_array_nearest(struct tgsi_sampler *tgsi_sampler,
samp->nearest_texcoord_s(s, width, x);
samp->nearest_texcoord_t(t, height, y);
wrap_array_layer(p, texture->depth0, layer);
wrap_array_layer(p, texture->array_size, layer);
for (j = 0; j < QUAD_SIZE; j++) {
const float *out = get_texel_3d(samp, addr, x[j], y[j], layer[j]);
const float *out = get_texel_2d_array(samp, addr, x[j], y[j], layer[j]);
int c;
for (c = 0; c < 4; c++) {
rgba[c][j] = out[c];
@ -1291,11 +1328,11 @@ img_filter_1d_array_linear(struct tgsi_sampler *tgsi_sampler,
addr.bits.level = samp->level;
samp->linear_texcoord_s(s, width, x0, x1, xw);
wrap_array_layer(t, texture->height0, layer);
wrap_array_layer(t, texture->array_size, 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]);
const float *tx0 = get_texel_1d_array(samp, addr, x0[j], layer[j]);
const float *tx1 = get_texel_1d_array(samp, addr, x1[j], layer[j]);
int c;
/* interpolate R, G, B, A */
@ -1382,13 +1419,13 @@ img_filter_2d_array_linear(struct tgsi_sampler *tgsi_sampler,
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);
wrap_array_layer(p, texture->array_size, 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]);
const float *tx0 = get_texel_2d_array(samp, addr, x0[j], y0[j], layer[j]);
const float *tx1 = get_texel_2d_array(samp, addr, x1[j], y0[j], layer[j]);
const float *tx2 = get_texel_2d_array(samp, addr, x0[j], y1[j], layer[j]);
const float *tx3 = get_texel_2d_array(samp, addr, x1[j], y1[j], layer[j]);
int c;
/* interpolate R, G, B, A */

View file

@ -251,6 +251,7 @@ sp_find_cached_tile_tex(struct softpipe_tex_tile_cache *tc,
tc->tex_level != addr.bits.level ||
tc->tex_z != addr.bits.z) {
/* get new transfer (view into texture) */
unsigned width, height, layer;
if (tc->tex_trans) {
if (tc->tex_trans_map) {
@ -262,14 +263,22 @@ sp_find_cached_tile_tex(struct softpipe_tex_tile_cache *tc,
tc->tex_trans = NULL;
}
width = u_minify(tc->texture->width0, addr.bits.level);
if (tc->texture->target == PIPE_TEXTURE_1D_ARRAY) {
height = tc->texture->array_size;
layer = 0;
}
else {
height = u_minify(tc->texture->height0, addr.bits.level);
layer = addr.bits.face + addr.bits.z;
}
tc->tex_trans =
pipe_get_transfer(tc->pipe, tc->texture,
addr.bits.level,
addr.bits.face + addr.bits.z,
layer,
PIPE_TRANSFER_READ | PIPE_TRANSFER_UNSYNCHRONIZED,
0, 0,
u_minify(tc->texture->width0, addr.bits.level),
u_minify(tc->texture->height0, addr.bits.level));
0, 0, width, height);
tc->tex_trans_map = tc->pipe->transfer_map(tc->pipe, tc->tex_trans);

View file

@ -62,13 +62,21 @@ softpipe_resource_layout(struct pipe_screen *screen,
unsigned buffer_size = 0;
for (level = 0; level <= pt->last_level; level++) {
unsigned slices;
if (pt->target == PIPE_TEXTURE_CUBE)
slices = 6;
else if (pt->target == PIPE_TEXTURE_3D)
slices = depth;
else
slices = pt->array_size;
spr->stride[level] = util_format_get_stride(pt->format, width);
spr->level_offset[level] = buffer_size;
buffer_size += (util_format_get_nblocksy(pt->format, height) *
((pt->target == PIPE_TEXTURE_CUBE) ? 6 : depth) *
spr->stride[level]);
slices * spr->stride[level]);
width = u_minify(width, 1);
height = u_minify(height, 1);
@ -296,7 +304,7 @@ softpipe_surface_destroy(struct pipe_context *pipe,
* a resource object.
* \param pipe rendering context
* \param resource the resource to transfer in/out of
* \param sr indicates cube face or 3D texture slice
* \param level which mipmap level
* \param usage bitmask of PIPE_TRANSFER_x flags
* \param box the 1D/2D/3D region of interest
*/
@ -315,8 +323,21 @@ softpipe_get_transfer(struct pipe_context *pipe,
/* make sure the requested region is in the image bounds */
assert(box->x + box->width <= u_minify(resource->width0, level));
assert(box->y + box->height <= u_minify(resource->height0, level));
assert(box->z + box->depth <= (u_minify(resource->depth0, level) + resource->array_size - 1));
if (resource->target == PIPE_TEXTURE_1D_ARRAY) {
assert(box->y + box->height <= resource->array_size);
}
else {
assert(box->y + box->height <= u_minify(resource->height0, level));
if (resource->target == PIPE_TEXTURE_2D_ARRAY) {
assert(box->z + box->depth <= resource->array_size);
}
else if (resource->target == PIPE_TEXTURE_CUBE) {
assert(box->z < 6);
}
else {
assert(box->z + box->depth <= (u_minify(resource->depth0, level)));
}
}
/*
* Transfers, like other pipe operations, must happen in order, so flush the