summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/softpipe
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/softpipe')
-rw-r--r--src/gallium/drivers/softpipe/sp_tex_sample.c61
-rw-r--r--src/gallium/drivers/softpipe/sp_tex_tile_cache.c17
-rw-r--r--src/gallium/drivers/softpipe/sp_texture.c31
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 15f7eb2b94..8a4ef93434 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 5105e77d43..e589ee7c84 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 2daed2022e..95374c34ec 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