diff options
-rw-r--r-- | docs/GL3.txt | 2 | ||||
-rw-r--r-- | docs/relnotes/10.6.0.html | 2 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_screen.c | 3 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_state_sampler.c | 12 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_tex_sample.c | 273 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_tex_tile_cache.c | 11 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_tex_tile_cache.h | 4 |
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; |