From 80777743b7b6238f034b8cb81d8d907d74929334 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 28 Jan 2011 20:25:27 -0700 Subject: [PATCH] softpipe: fix array textures to use resource array_size Don't use height for 1D array textures or depth for 2D array textures. --- src/gallium/drivers/softpipe/sp_tex_sample.c | 61 +++++++++++++++---- .../drivers/softpipe/sp_tex_tile_cache.c | 17 ++++-- src/gallium/drivers/softpipe/sp_texture.c | 31 ++++++++-- 3 files changed, 88 insertions(+), 21 deletions(-) diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index 15f7eb2b94e..8a4ef934348 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -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 */ diff --git a/src/gallium/drivers/softpipe/sp_tex_tile_cache.c b/src/gallium/drivers/softpipe/sp_tex_tile_cache.c index 5105e77d436..e589ee7c841 100644 --- a/src/gallium/drivers/softpipe/sp_tex_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tex_tile_cache.c @@ -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); diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c index 2daed2022e9..95374c34ec3 100644 --- a/src/gallium/drivers/softpipe/sp_texture.c +++ b/src/gallium/drivers/softpipe/sp_texture.c @@ -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 -- 2.30.2