summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/GL3.txt2
-rw-r--r--docs/relnotes/10.6.0.html2
-rw-r--r--src/gallium/drivers/softpipe/sp_screen.c3
-rw-r--r--src/gallium/drivers/softpipe/sp_state_sampler.c12
-rw-r--r--src/gallium/drivers/softpipe/sp_tex_sample.c273
-rw-r--r--src/gallium/drivers/softpipe/sp_tex_tile_cache.c11
-rw-r--r--src/gallium/drivers/softpipe/sp_tex_tile_cache.h4
7 files changed, 181 insertions, 126 deletions
diff --git a/docs/GL3.txt b/docs/GL3.txt
index 32b7809d10c..5a15bc55f47 100644
--- a/docs/GL3.txt
+++ b/docs/GL3.txt
@@ -169,7 +169,7 @@ GL 4.3, GLSL 4.30:
GL_ARB_texture_buffer_range DONE (nv50, nvc0, i965, r600, radeonsi, llvmpipe)
GL_ARB_texture_query_levels DONE (all drivers that support GLSL 1.30)
GL_ARB_texture_storage_multisample DONE (all drivers that support GL_ARB_texture_multisample)
- GL_ARB_texture_view DONE (i965, nv50, nvc0, llvmpipe)
+ GL_ARB_texture_view DONE (i965, nv50, nvc0, llvmpipe, softpipe)
GL_ARB_vertex_attrib_binding DONE (all drivers)
diff --git a/docs/relnotes/10.6.0.html b/docs/relnotes/10.6.0.html
index 3f69f986ccd..6d379868865 100644
--- a/docs/relnotes/10.6.0.html
+++ b/docs/relnotes/10.6.0.html
@@ -56,7 +56,7 @@ Note: some of the new features are only available with certain drivers.
<li>GL_ARB_pipeline_statistics_query on i965, nv50, nvc0, r600, radeonsi, softpipe</li>
<li>GL_ARB_program_interface_query (all drivers)</li>
<li>GL_ARB_texture_stencil8 on nv50, nvc0, r600, radeonsi, softpipe</li>
-<li>GL_ARB_texture_view on llvmpipe</li>
+<li>GL_ARB_texture_view on llvmpipe, softpipe</li>
<li>GL_ARB_uniform_buffer_object on freedreno</li>
<li>GL_ARB_vertex_attrib_64bit on nvc0, softpipe</li>
<li>GL_ARB_viewport_array, GL_AMD_vertex_shader_viewport_index on i965/gen6</li>
diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c
index fc32c56b699..b3bc1773e9f 100644
--- a/src/gallium/drivers/softpipe/sp_screen.c
+++ b/src/gallium/drivers/softpipe/sp_screen.c
@@ -200,8 +200,9 @@ softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
return 1;
case PIPE_CAP_TGSI_FS_FINE_DERIVATIVE:
- case PIPE_CAP_SAMPLER_VIEW_TARGET:
return 0;
+ case PIPE_CAP_SAMPLER_VIEW_TARGET:
+ return 1;
case PIPE_CAP_FAKE_SW_MSAA:
return 1;
case PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET:
diff --git a/src/gallium/drivers/softpipe/sp_state_sampler.c b/src/gallium/drivers/softpipe/sp_state_sampler.c
index e56fb5b1485..d7a3360713f 100644
--- a/src/gallium/drivers/softpipe/sp_state_sampler.c
+++ b/src/gallium/drivers/softpipe/sp_state_sampler.c
@@ -202,7 +202,7 @@ prepare_shader_sampling(
struct pipe_resource *res = view->texture;
int j;
- if (res->target != PIPE_BUFFER) {
+ if (view->target != PIPE_BUFFER) {
first_level = view->u.tex.first_level;
last_level = view->u.tex.last_level;
assert(first_level <= last_level);
@@ -214,15 +214,17 @@ prepare_shader_sampling(
row_stride[j] = sp_tex->stride[j];
img_stride[j] = sp_tex->img_stride[j];
}
- if (res->target == PIPE_TEXTURE_1D_ARRAY ||
- res->target == PIPE_TEXTURE_2D_ARRAY ||
- res->target == PIPE_TEXTURE_CUBE_ARRAY) {
+ if (view->target == PIPE_TEXTURE_1D_ARRAY ||
+ view->target == PIPE_TEXTURE_2D_ARRAY ||
+ view->target == PIPE_TEXTURE_CUBE ||
+ view->target == PIPE_TEXTURE_CUBE_ARRAY) {
num_layers = view->u.tex.last_layer - view->u.tex.first_layer + 1;
for (j = first_level; j <= last_level; j++) {
mip_offsets[j] += view->u.tex.first_layer *
sp_tex->img_stride[j];
}
- if (res->target == PIPE_TEXTURE_CUBE_ARRAY) {
+ if (view->target == PIPE_TEXTURE_CUBE ||
+ view->target == PIPE_TEXTURE_CUBE_ARRAY) {
assert(num_layers % 6 == 0);
}
assert(view->u.tex.first_layer <= view->u.tex.last_layer);
diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c
index 68dcf57240d..21fb6b00e30 100644
--- a/src/gallium/drivers/softpipe/sp_tex_sample.c
+++ b/src/gallium/drivers/softpipe/sp_tex_sample.c
@@ -474,11 +474,11 @@ wrap_linear_unorm_clamp_to_edge(float s, unsigned size,
/**
* Do coordinate to array index conversion. For array textures.
*/
-static INLINE void
-wrap_array_layer(float coord, unsigned size, int *layer)
+static INLINE int
+coord_to_layer(float coord, unsigned first_layer, unsigned last_layer)
{
int c = util_ifloor(coord + 0.5F);
- *layer = CLAMP(c, 0, (int) size - 1);
+ return CLAMP(c, (int)first_layer, (int)last_layer);
}
@@ -757,61 +757,6 @@ get_next_ycoord(unsigned face, unsigned fall_off_index, int max, int xc, int yc)
}
-static INLINE const float *
-get_texel_cube_seamless(const struct sp_sampler_view *sp_sview,
- union tex_tile_address addr, int x, int y,
- float *corner)
-{
- const struct pipe_resource *texture = sp_sview->base.texture;
- unsigned level = addr.bits.level;
- unsigned face = addr.bits.face;
- int new_x, new_y, max_x;
-
- max_x = (int) u_minify(texture->width0, level);
-
- assert(texture->width0 == texture->height0);
- new_x = x;
- new_y = y;
-
- /* change the face */
- if (x < 0) {
- /*
- * Cheat with corners. They are difficult and I believe because we don't get
- * per-pixel faces we can actually have multiple corner texels per pixel,
- * which screws things up majorly in any case (as the per spec behavior is
- * to average the 3 remaining texels, which we might not have).
- * Hence just make sure that the 2nd coord is clamped, will simply pick the
- * sample which would have fallen off the x coord, but not y coord.
- * So the filter weight of the samples will be wrong, but at least this
- * ensures that only valid texels near the corner are used.
- */
- if (y < 0 || y >= max_x) {
- y = CLAMP(y, 0, max_x - 1);
- }
- new_x = get_next_xcoord(face, 0, max_x -1, x, y);
- new_y = get_next_ycoord(face, 0, max_x -1, x, y);
- face = get_next_face(face, 0);
- } else if (x >= max_x) {
- if (y < 0 || y >= max_x) {
- y = CLAMP(y, 0, max_x - 1);
- }
- new_x = get_next_xcoord(face, 1, max_x -1, x, y);
- new_y = get_next_ycoord(face, 1, max_x -1, x, y);
- face = get_next_face(face, 1);
- } else if (y < 0) {
- new_x = get_next_xcoord(face, 2, max_x -1, x, y);
- new_y = get_next_ycoord(face, 2, max_x -1, x, y);
- face = get_next_face(face, 2);
- } else if (y >= max_x) {
- new_x = get_next_xcoord(face, 3, max_x -1, x, y);
- new_y = get_next_ycoord(face, 3, max_x -1, x, y);
- face = get_next_face(face, 3);
- }
-
- addr.bits.face = face;
- return get_texel_2d_no_border( sp_sview, addr, new_x, new_y );
-}
-
/* Gather a quad of adjacent texels within a tile:
*/
static INLINE void
@@ -948,6 +893,60 @@ get_texel_2d_array(const struct sp_sampler_view *sp_sview,
}
+static INLINE const float *
+get_texel_cube_seamless(const struct sp_sampler_view *sp_sview,
+ union tex_tile_address addr, int x, int y,
+ float *corner, int layer, unsigned face)
+{
+ const struct pipe_resource *texture = sp_sview->base.texture;
+ unsigned level = addr.bits.level;
+ int new_x, new_y, max_x;
+
+ max_x = (int) u_minify(texture->width0, level);
+
+ assert(texture->width0 == texture->height0);
+ new_x = x;
+ new_y = y;
+
+ /* change the face */
+ if (x < 0) {
+ /*
+ * Cheat with corners. They are difficult and I believe because we don't get
+ * per-pixel faces we can actually have multiple corner texels per pixel,
+ * which screws things up majorly in any case (as the per spec behavior is
+ * to average the 3 remaining texels, which we might not have).
+ * Hence just make sure that the 2nd coord is clamped, will simply pick the
+ * sample which would have fallen off the x coord, but not y coord.
+ * So the filter weight of the samples will be wrong, but at least this
+ * ensures that only valid texels near the corner are used.
+ */
+ if (y < 0 || y >= max_x) {
+ y = CLAMP(y, 0, max_x - 1);
+ }
+ new_x = get_next_xcoord(face, 0, max_x -1, x, y);
+ new_y = get_next_ycoord(face, 0, max_x -1, x, y);
+ face = get_next_face(face, 0);
+ } else if (x >= max_x) {
+ if (y < 0 || y >= max_x) {
+ y = CLAMP(y, 0, max_x - 1);
+ }
+ new_x = get_next_xcoord(face, 1, max_x -1, x, y);
+ new_y = get_next_ycoord(face, 1, max_x -1, x, y);
+ face = get_next_face(face, 1);
+ } else if (y < 0) {
+ new_x = get_next_xcoord(face, 2, max_x -1, x, y);
+ new_y = get_next_ycoord(face, 2, max_x -1, x, y);
+ face = get_next_face(face, 2);
+ } else if (y >= max_x) {
+ new_x = get_next_xcoord(face, 3, max_x -1, x, y);
+ new_y = get_next_ycoord(face, 3, max_x -1, x, y);
+ face = get_next_face(face, 3);
+ }
+
+ return get_texel_3d_no_border(sp_sview, addr, new_x, new_y, layer + face);
+}
+
+
/* Get texel pointer for cube array texture */
static INLINE const float *
get_texel_cube_array(const struct sp_sampler_view *sp_sview,
@@ -1208,7 +1207,8 @@ img_filter_1d_array_nearest(struct sp_sampler_view *sp_sview,
addr.bits.level = level;
sp_samp->nearest_texcoord_s(s, width, &x);
- wrap_array_layer(t, texture->array_size, &layer);
+ layer = coord_to_layer(t, sp_sview->base.u.tex.first_layer,
+ sp_sview->base.u.tex.last_layer);
out = get_texel_1d_array(sp_sview, sp_samp, addr, x, layer);
for (c = 0; c < TGSI_QUAD_SIZE; c++)
@@ -1287,7 +1287,8 @@ img_filter_2d_array_nearest(struct sp_sampler_view *sp_sview,
sp_samp->nearest_texcoord_s(s, width, &x);
sp_samp->nearest_texcoord_t(t, height, &y);
- wrap_array_layer(p, texture->array_size, &layer);
+ layer = coord_to_layer(p, sp_sview->base.u.tex.first_layer,
+ sp_sview->base.u.tex.last_layer);
out = get_texel_2d_array(sp_sview, sp_samp, addr, x, y, layer);
for (c = 0; c < TGSI_QUAD_SIZE; c++)
@@ -1299,14 +1300,6 @@ img_filter_2d_array_nearest(struct sp_sampler_view *sp_sview,
}
-static INLINE union tex_tile_address
-face(union tex_tile_address addr, unsigned face )
-{
- addr.bits.face = face;
- return addr;
-}
-
-
static void
img_filter_cube_nearest(struct sp_sampler_view *sp_sview,
struct sp_sampler *sp_samp,
@@ -1319,7 +1312,7 @@ img_filter_cube_nearest(struct sp_sampler_view *sp_sview,
{
const struct pipe_resource *texture = sp_sview->base.texture;
int width, height;
- int x, y;
+ int x, y, layerface;
union tex_tile_address addr;
const float *out;
int c;
@@ -1346,7 +1339,8 @@ img_filter_cube_nearest(struct sp_sampler_view *sp_sview,
sp_samp->nearest_texcoord_t(t, height, &y);
}
- out = get_texel_2d(sp_sview, sp_samp, face(addr, face_id), x, y);
+ layerface = face_id + sp_sview->base.u.tex.first_layer;
+ out = get_texel_cube_array(sp_sview, sp_samp, addr, x, y, layerface);
for (c = 0; c < TGSI_QUAD_SIZE; c++)
rgba[TGSI_NUM_CHANNELS*c] = out[c];
@@ -1367,7 +1361,7 @@ img_filter_cube_array_nearest(struct sp_sampler_view *sp_sview,
{
const struct pipe_resource *texture = sp_sview->base.texture;
int width, height;
- int x, y, layer;
+ int x, y, layerface;
union tex_tile_address addr;
const float *out;
int c;
@@ -1383,9 +1377,11 @@ img_filter_cube_array_nearest(struct sp_sampler_view *sp_sview,
sp_samp->nearest_texcoord_s(s, width, &x);
sp_samp->nearest_texcoord_t(t, height, &y);
- wrap_array_layer(p, texture->array_size, &layer);
+ layerface = coord_to_layer(6 * p + sp_sview->base.u.tex.first_layer,
+ sp_sview->base.u.tex.first_layer,
+ sp_sview->base.u.tex.last_layer - 5) + face_id;
- out = get_texel_cube_array(sp_sview, sp_samp, addr, x, y, layer * 6 + face_id);
+ out = get_texel_cube_array(sp_sview, sp_samp, addr, x, y, layerface);
for (c = 0; c < TGSI_QUAD_SIZE; c++)
rgba[TGSI_NUM_CHANNELS*c] = out[c];
@@ -1494,7 +1490,8 @@ img_filter_1d_array_linear(struct sp_sampler_view *sp_sview,
addr.bits.level = level;
sp_samp->linear_texcoord_s(s, width, &x0, &x1, &xw);
- wrap_array_layer(t, texture->array_size, &layer);
+ layer = coord_to_layer(t, sp_sview->base.u.tex.first_layer,
+ sp_sview->base.u.tex.last_layer);
tx0 = get_texel_1d_array(sp_sview, sp_samp, addr, x0, layer);
tx1 = get_texel_1d_array(sp_sview, sp_samp, addr, x1, layer);
@@ -1577,7 +1574,8 @@ img_filter_2d_array_linear(struct sp_sampler_view *sp_sview,
sp_samp->linear_texcoord_s(s, width, &x0, &x1, &xw);
sp_samp->linear_texcoord_t(t, height, &y0, &y1, &yw);
- wrap_array_layer(p, texture->array_size, &layer);
+ layer = coord_to_layer(p, sp_sview->base.u.tex.first_layer,
+ sp_sview->base.u.tex.last_layer);
tx0 = get_texel_2d_array(sp_sview, sp_samp, addr, x0, y0, layer);
tx1 = get_texel_2d_array(sp_sview, sp_samp, addr, x1, y0, layer);
@@ -1604,9 +1602,9 @@ img_filter_cube_linear(struct sp_sampler_view *sp_sview,
{
const struct pipe_resource *texture = sp_sview->base.texture;
int width, height;
- int x0, y0, x1, y1;
+ int x0, y0, x1, y1, layer;
float xw, yw; /* weights */
- union tex_tile_address addr, addrj;
+ union tex_tile_address addr;
const float *tx0, *tx1, *tx2, *tx3;
float corner0[TGSI_QUAD_SIZE], corner1[TGSI_QUAD_SIZE],
corner2[TGSI_QUAD_SIZE], corner3[TGSI_QUAD_SIZE];
@@ -1635,19 +1633,20 @@ img_filter_cube_linear(struct sp_sampler_view *sp_sview,
sp_samp->linear_texcoord_t(t, height, &y0, &y1, &yw);
}
- addrj = face(addr, face_id);
+ layer = sp_sview->base.u.tex.first_layer;
if (sp_samp->base.seamless_cube_map) {
- tx0 = get_texel_cube_seamless(sp_sview, addrj, x0, y0, corner0);
- tx1 = get_texel_cube_seamless(sp_sview, addrj, x1, y0, corner1);
- tx2 = get_texel_cube_seamless(sp_sview, addrj, x0, y1, corner2);
- tx3 = get_texel_cube_seamless(sp_sview, addrj, x1, y1, corner3);
+ tx0 = get_texel_cube_seamless(sp_sview, addr, x0, y0, corner0, layer, face_id);
+ tx1 = get_texel_cube_seamless(sp_sview, addr, x1, y0, corner1, layer, face_id);
+ tx2 = get_texel_cube_seamless(sp_sview, addr, x0, y1, corner2, layer, face_id);
+ tx3 = get_texel_cube_seamless(sp_sview, addr, x1, y1, corner3, layer, face_id);
} else {
- tx0 = get_texel_2d(sp_sview, sp_samp, addrj, x0, y0);
- tx1 = get_texel_2d(sp_sview, sp_samp, addrj, x1, y0);
- tx2 = get_texel_2d(sp_sview, sp_samp, addrj, x0, y1);
- tx3 = get_texel_2d(sp_sview, sp_samp, addrj, x1, y1);
+ tx0 = get_texel_cube_array(sp_sview, sp_samp, addr, x0, y0, layer + face_id);
+ tx1 = get_texel_cube_array(sp_sview, sp_samp, addr, x1, y0, layer + face_id);
+ tx2 = get_texel_cube_array(sp_sview, sp_samp, addr, x0, y1, layer + face_id);
+ tx3 = get_texel_cube_array(sp_sview, sp_samp, addr, x1, y1, layer + face_id);
}
+
/* interpolate R, G, B, A */
for (c = 0; c < TGSI_QUAD_SIZE; c++)
rgba[TGSI_NUM_CHANNELS*c] = lerp_2d(xw, yw,
@@ -1672,6 +1671,8 @@ img_filter_cube_array_linear(struct sp_sampler_view *sp_sview,
float xw, yw; /* weights */
union tex_tile_address addr;
const float *tx0, *tx1, *tx2, *tx3;
+ float corner0[TGSI_QUAD_SIZE], corner1[TGSI_QUAD_SIZE],
+ corner2[TGSI_QUAD_SIZE], corner3[TGSI_QUAD_SIZE];
int c;
width = u_minify(texture->width0, level);
@@ -1683,14 +1684,35 @@ img_filter_cube_array_linear(struct sp_sampler_view *sp_sview,
addr.value = 0;
addr.bits.level = level;
- sp_samp->linear_texcoord_s(s, width, &x0, &x1, &xw);
- sp_samp->linear_texcoord_t(t, height, &y0, &y1, &yw);
- wrap_array_layer(p, texture->array_size, &layer);
+ /*
+ * For seamless if LINEAR filtering is done within a miplevel,
+ * always apply wrap mode CLAMP_TO_BORDER.
+ */
+ if (sp_samp->base.seamless_cube_map) {
+ /* Note this is a bit overkill, actual clamping is not required */
+ wrap_linear_clamp_to_border(s, width, &x0, &x1, &xw);
+ wrap_linear_clamp_to_border(t, height, &y0, &y1, &yw);
+ } else {
+ /* Would probably make sense to ignore mode and just do edge clamp */
+ sp_samp->linear_texcoord_s(s, width, &x0, &x1, &xw);
+ sp_samp->linear_texcoord_t(t, height, &y0, &y1, &yw);
+ }
+
+ layer = coord_to_layer(6 * p + sp_sview->base.u.tex.first_layer,
+ sp_sview->base.u.tex.first_layer,
+ sp_sview->base.u.tex.last_layer - 5);
- tx0 = get_texel_cube_array(sp_sview, sp_samp, addr, x0, y0, layer * 6 + face_id);
- tx1 = get_texel_cube_array(sp_sview, sp_samp, addr, x1, y0, layer * 6 + face_id);
- tx2 = get_texel_cube_array(sp_sview, sp_samp, addr, x0, y1, layer * 6 + face_id);
- tx3 = get_texel_cube_array(sp_sview, sp_samp, addr, x1, y1, layer * 6 + face_id);
+ if (sp_samp->base.seamless_cube_map) {
+ tx0 = get_texel_cube_seamless(sp_sview, addr, x0, y0, corner0, layer, face_id);
+ tx1 = get_texel_cube_seamless(sp_sview, addr, x1, y0, corner1, layer, face_id);
+ tx2 = get_texel_cube_seamless(sp_sview, addr, x0, y1, corner2, layer, face_id);
+ tx3 = get_texel_cube_seamless(sp_sview, addr, x1, y1, corner3, layer, face_id);
+ } else {
+ tx0 = get_texel_cube_array(sp_sview, sp_samp, addr, x0, y0, layer + face_id);
+ tx1 = get_texel_cube_array(sp_sview, sp_samp, addr, x1, y0, layer + face_id);
+ tx2 = get_texel_cube_array(sp_sview, sp_samp, addr, x0, y1, layer + face_id);
+ tx3 = get_texel_cube_array(sp_sview, sp_samp, addr, x1, y1, layer + face_id);
+ }
/* interpolate R, G, B, A */
for (c = 0; c < TGSI_QUAD_SIZE; c++)
@@ -2408,13 +2430,13 @@ sample_compare(struct sp_sampler_view *sp_sview,
* RGBA channels. We look at the red channel here.
*/
- if (sp_sview->base.texture->target == PIPE_TEXTURE_2D_ARRAY ||
- sp_sview->base.texture->target == PIPE_TEXTURE_CUBE) {
+ if (sp_sview->base.target == PIPE_TEXTURE_2D_ARRAY ||
+ sp_sview->base.target == PIPE_TEXTURE_CUBE) {
pc[0] = c0[0];
pc[1] = c0[1];
pc[2] = c0[2];
pc[3] = c0[3];
- } else if (sp_sview->base.texture->target == PIPE_TEXTURE_CUBE_ARRAY) {
+ } else if (sp_sview->base.target == PIPE_TEXTURE_CUBE_ARRAY) {
pc[0] = c1[0];
pc[1] = c1[1];
pc[2] = c1[2];
@@ -2681,7 +2703,7 @@ get_img_filter(const struct sp_sampler_view *sp_sview,
const struct pipe_sampler_state *sampler,
unsigned filter)
{
- switch (sp_sview->base.texture->target) {
+ switch (sp_sview->base.target) {
case PIPE_BUFFER:
case PIPE_TEXTURE_1D:
if (filter == PIPE_TEX_FILTER_NEAREST)
@@ -2907,7 +2929,7 @@ sp_get_dims(struct sp_sampler_view *sp_sview, int level,
const struct pipe_sampler_view *view = &sp_sview->base;
const struct pipe_resource *texture = view->texture;
- if (texture->target == PIPE_BUFFER) {
+ if (view->target == PIPE_BUFFER) {
dims[0] = (view->u.buf.last_element - view->u.buf.first_element) + 1;
/* the other values are undefined, but let's avoid potential valgrind
* warnings.
@@ -2924,7 +2946,7 @@ sp_get_dims(struct sp_sampler_view *sp_sview, int level,
dims[3] = view->u.tex.last_level - view->u.tex.first_level + 1;
dims[0] = u_minify(texture->width0, level);
- switch(texture->target) {
+ switch (view->target) {
case PIPE_TEXTURE_1D_ARRAY:
dims[1] = view->u.tex.last_layer - view->u.tex.first_layer + 1;
/* fallthrough */
@@ -2975,13 +2997,16 @@ sp_get_texels(struct sp_sampler_view *sp_sview,
addr.value = 0;
/* TODO write a better test for LOD */
- addr.bits.level = lod[0];
+ addr.bits.level = sp_sview->base.target == PIPE_BUFFER ? 0 :
+ CLAMP(lod[0] + sp_sview->base.u.tex.first_level,
+ sp_sview->base.u.tex.first_level,
+ sp_sview->base.u.tex.last_level);
width = u_minify(texture->width0, addr.bits.level);
height = u_minify(texture->height0, addr.bits.level);
depth = u_minify(texture->depth0, addr.bits.level);
- switch(texture->target) {
+ switch (sp_sview->base.target) {
case PIPE_BUFFER:
case PIPE_TEXTURE_1D:
for (j = 0; j < TGSI_QUAD_SIZE; j++) {
@@ -2995,7 +3020,8 @@ sp_get_texels(struct sp_sampler_view *sp_sview,
case PIPE_TEXTURE_1D_ARRAY:
for (j = 0; j < TGSI_QUAD_SIZE; j++) {
int x = CLAMP(v_i[j] + offset[0], 0, width - 1);
- int y = CLAMP(v_j[j], sp_sview->base.u.tex.first_layer, sp_sview->base.u.tex.last_layer);
+ int y = CLAMP(v_j[j], sp_sview->base.u.tex.first_layer,
+ sp_sview->base.u.tex.last_layer);
tx = get_texel_2d_no_border(sp_sview, addr, x, y);
for (c = 0; c < 4; c++) {
rgba[c][j] = tx[c];
@@ -3017,7 +3043,8 @@ sp_get_texels(struct sp_sampler_view *sp_sview,
for (j = 0; j < TGSI_QUAD_SIZE; j++) {
int x = CLAMP(v_i[j] + offset[0], 0, width - 1);
int y = CLAMP(v_j[j] + offset[1], 0, height - 1);
- int layer = CLAMP(v_k[j], sp_sview->base.u.tex.first_layer, sp_sview->base.u.tex.last_layer);
+ int layer = CLAMP(v_k[j], sp_sview->base.u.tex.first_layer,
+ sp_sview->base.u.tex.last_layer);
tx = get_texel_3d_no_border(sp_sview, addr, x, y, layer);
for (c = 0; c < 4; c++) {
rgba[c][j] = tx[c];
@@ -3140,7 +3167,7 @@ softpipe_get_lambda_func(const struct pipe_sampler_view *view, unsigned shader)
if (shader != PIPE_SHADER_FRAGMENT)
return compute_lambda_vert;
- switch (view->texture->target) {
+ switch (view->target) {
case PIPE_BUFFER:
case PIPE_TEXTURE_1D:
case PIPE_TEXTURE_1D_ARRAY:
@@ -3176,19 +3203,49 @@ softpipe_create_sampler_view(struct pipe_context *pipe,
pipe_resource_reference(&view->texture, resource);
view->context = pipe;
+#ifdef DEBUG
+ /*
+ * This is possibly too lenient, but the primary reason is just
+ * to catch state trackers which forget to initialize this, so
+ * it only catches clearly impossible view targets.
+ */
+ if (view->target != resource->target) {
+ if (view->target == PIPE_TEXTURE_1D)
+ assert(resource->target == PIPE_TEXTURE_1D_ARRAY);
+ else if (view->target == PIPE_TEXTURE_1D_ARRAY)
+ assert(resource->target == PIPE_TEXTURE_1D);
+ else if (view->target == PIPE_TEXTURE_2D)
+ assert(resource->target == PIPE_TEXTURE_2D_ARRAY ||
+ resource->target == PIPE_TEXTURE_CUBE ||
+ resource->target == PIPE_TEXTURE_CUBE_ARRAY);
+ else if (view->target == PIPE_TEXTURE_2D_ARRAY)
+ assert(resource->target == PIPE_TEXTURE_2D ||
+ resource->target == PIPE_TEXTURE_CUBE ||
+ resource->target == PIPE_TEXTURE_CUBE_ARRAY);
+ else if (view->target == PIPE_TEXTURE_CUBE)
+ assert(resource->target == PIPE_TEXTURE_CUBE_ARRAY ||
+ resource->target == PIPE_TEXTURE_2D_ARRAY);
+ else if (view->target == PIPE_TEXTURE_CUBE_ARRAY)
+ assert(resource->target == PIPE_TEXTURE_CUBE ||
+ resource->target == PIPE_TEXTURE_2D_ARRAY);
+ else
+ assert(0);
+ }
+#endif
+
if (any_swizzle(view)) {
sview->need_swizzle = TRUE;
}
- if (resource->target == PIPE_TEXTURE_CUBE ||
- resource->target == PIPE_TEXTURE_CUBE_ARRAY)
+ if (view->target == PIPE_TEXTURE_CUBE ||
+ view->target == PIPE_TEXTURE_CUBE_ARRAY)
sview->get_samples = sample_cube;
else {
sview->get_samples = sample_mip;
}
sview->pot2d = spr->pot &&
- (resource->target == PIPE_TEXTURE_2D ||
- resource->target == PIPE_TEXTURE_RECT);
+ (view->target == PIPE_TEXTURE_2D ||
+ view->target == PIPE_TEXTURE_RECT);
sview->xpot = util_logbase2( resource->width0 );
sview->ypot = util_logbase2( resource->height0 );
diff --git a/src/gallium/drivers/softpipe/sp_tex_tile_cache.c b/src/gallium/drivers/softpipe/sp_tex_tile_cache.c
index ab8ba60849a..4a421a8f882 100644
--- a/src/gallium/drivers/softpipe/sp_tex_tile_cache.c
+++ b/src/gallium/drivers/softpipe/sp_tex_tile_cache.c
@@ -151,7 +151,7 @@ sp_tex_tile_cache_set_sampler_view(struct softpipe_tex_tile_cache *tc,
tc->entries[i].addr.bits.invalid = 1;
}
- tc->tex_face = -1; /* any invalid value here */
+ tc->tex_z = -1; /* any invalid value here */
}
}
@@ -172,7 +172,7 @@ sp_flush_tex_tile_cache(struct softpipe_tex_tile_cache *tc)
for (pos = 0; pos < Elements(tc->entries); pos++) {
tc->entries[pos].addr.bits.invalid = 1;
}
- tc->tex_face = -1;
+ tc->tex_z = -1;
}
}
@@ -190,8 +190,7 @@ tex_cache_pos( union tex_tile_address addr )
{
uint entry = (addr.bits.x +
addr.bits.y * 9 +
- addr.bits.z * 3 +
- addr.bits.face +
+ addr.bits.z +
addr.bits.level * 7);
return entry % NUM_TEX_TILE_ENTRIES;
@@ -226,7 +225,6 @@ sp_find_cached_tile_tex(struct softpipe_tex_tile_cache *tc,
/* check if we need to get a new transfer */
if (!tc->tex_trans ||
- tc->tex_face != addr.bits.face ||
tc->tex_level != addr.bits.level ||
tc->tex_z != addr.bits.z) {
/* get new transfer (view into texture) */
@@ -245,7 +243,7 @@ sp_find_cached_tile_tex(struct softpipe_tex_tile_cache *tc,
}
else {
height = u_minify(tc->texture->height0, addr.bits.level);
- layer = addr.bits.face + addr.bits.z;
+ layer = addr.bits.z;
}
tc->tex_trans_map =
@@ -255,7 +253,6 @@ sp_find_cached_tile_tex(struct softpipe_tex_tile_cache *tc,
PIPE_TRANSFER_READ | PIPE_TRANSFER_UNSYNCHRONIZED,
0, 0, width, height, &tc->tex_trans);
- tc->tex_face = addr.bits.face;
tc->tex_level = addr.bits.level;
tc->tex_z = addr.bits.z;
}
diff --git a/src/gallium/drivers/softpipe/sp_tex_tile_cache.h b/src/gallium/drivers/softpipe/sp_tex_tile_cache.h
index 4eb42460552..2233effc439 100644
--- a/src/gallium/drivers/softpipe/sp_tex_tile_cache.h
+++ b/src/gallium/drivers/softpipe/sp_tex_tile_cache.h
@@ -55,7 +55,6 @@ union tex_tile_address {
unsigned x:TEX_ADDR_BITS; /* 16K / TILE_SIZE */
unsigned y:TEX_ADDR_BITS; /* 16K / TILE_SIZE */
unsigned z:TEX_Z_BITS; /* 16K -- z not tiled */
- unsigned face:3;
unsigned level:4;
unsigned invalid:1;
} bits;
@@ -94,7 +93,7 @@ struct softpipe_tex_tile_cache
struct pipe_transfer *tex_trans;
void *tex_trans_map;
- int tex_face, tex_level, tex_z;
+ int tex_level, tex_z;
unsigned swizzle_r;
unsigned swizzle_g;
@@ -141,7 +140,6 @@ tex_tile_address( unsigned x,
addr.bits.x = x / TEX_TILE_SIZE;
addr.bits.y = y / TEX_TILE_SIZE;
addr.bits.z = z;
- addr.bits.face = face;
addr.bits.level = level;
return addr;