diff options
author | Jason Ekstrand <[email protected]> | 2015-06-23 18:05:25 -0700 |
---|---|---|
committer | Jason Ekstrand <[email protected]> | 2015-06-23 18:05:25 -0700 |
commit | a62edcce4eb4c800d972817a20ee874bf2a2c3ef (patch) | |
tree | 46083a8762d45a6c595c7aaee2bb1cd0fc36eb62 /src/gallium/drivers/softpipe | |
parent | 9b9f973ca6d3cc1ec5be27857def00a83c032464 (diff) | |
parent | 6844d6b7f8398a25eff511541b187afeb1199ce0 (diff) |
Merge remote-tracking branch 'mesa-public/master' into vulkan
Diffstat (limited to 'src/gallium/drivers/softpipe')
-rw-r--r-- | src/gallium/drivers/softpipe/sp_public.h | 8 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_query.c | 2 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_screen.c | 9 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_state_sampler.c | 12 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_tex_sample.c | 1228 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_tex_sample.h | 28 | ||||
-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 |
8 files changed, 745 insertions, 557 deletions
diff --git a/src/gallium/drivers/softpipe/sp_public.h b/src/gallium/drivers/softpipe/sp_public.h index 62d0903d87a..88a9b5e6643 100644 --- a/src/gallium/drivers/softpipe/sp_public.h +++ b/src/gallium/drivers/softpipe/sp_public.h @@ -1,10 +1,18 @@ #ifndef SP_PUBLIC_H #define SP_PUBLIC_H +#ifdef __cplusplus +extern "C" { +#endif + struct pipe_screen; struct sw_winsys; struct pipe_screen * softpipe_create_screen(struct sw_winsys *winsys); +#ifdef __cplusplus +} +#endif + #endif diff --git a/src/gallium/drivers/softpipe/sp_query.c b/src/gallium/drivers/softpipe/sp_query.c index e77387082bc..76105b4c0ec 100644 --- a/src/gallium/drivers/softpipe/sp_query.c +++ b/src/gallium/drivers/softpipe/sp_query.c @@ -277,7 +277,7 @@ softpipe_check_render_cond(struct softpipe_context *sp) b = pipe->get_query_result(pipe, sp->render_cond_query, wait, (void*)&result); if (b) - return (!result == sp->render_cond_cond); + return (!result) == sp->render_cond_cond; else return TRUE; } diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c index d289e28a6f8..a688d319bb8 100644 --- a/src/gallium/drivers/softpipe/sp_screen.c +++ b/src/gallium/drivers/softpipe/sp_screen.c @@ -191,7 +191,9 @@ softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param) case PIPE_CAP_ENDIANNESS: return PIPE_ENDIAN_NATIVE; case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS: + return 4; case PIPE_CAP_TEXTURE_GATHER_SM5: + return 1; case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT: case PIPE_CAP_TEXTURE_QUERY_LOD: case PIPE_CAP_SAMPLE_SHADING: @@ -200,13 +202,15 @@ 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: + return -32; case PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET: - return 0; + return 31; case PIPE_CAP_DRAW_INDIRECT: return 1; @@ -237,6 +241,7 @@ softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param) return 0; case PIPE_CAP_MULTISAMPLE_Z_RESOLVE: case PIPE_CAP_RESOURCE_FROM_USER_MEMORY: + case PIPE_CAP_DEVICE_RESET_STATUS_QUERY: return 0; } /* should only get here on unhandled cases */ 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..1010b63de2c 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -131,68 +131,80 @@ repeat(int coord, unsigned size) * \param icoord returns the integer texcoords */ static void -wrap_nearest_repeat(float s, unsigned size, int *icoord) +wrap_nearest_repeat(float s, unsigned size, int offset, int *icoord) { /* s limited to [0,1) */ /* i limited to [0,size-1] */ int i = util_ifloor(s * size); - *icoord = repeat(i, size); + *icoord = repeat(i + offset, size); } static void -wrap_nearest_clamp(float s, unsigned size, int *icoord) +wrap_nearest_clamp(float s, unsigned size, int offset, int *icoord) { /* s limited to [0,1] */ /* i limited to [0,size-1] */ + s *= size; + s += offset; if (s <= 0.0F) *icoord = 0; - else if (s >= 1.0F) + else if (s >= size) *icoord = size - 1; else - *icoord = util_ifloor(s * size); + *icoord = util_ifloor(s); } static void -wrap_nearest_clamp_to_edge(float s, unsigned size, int *icoord) +wrap_nearest_clamp_to_edge(float s, unsigned size, int offset, int *icoord) { /* s limited to [min,max] */ /* i limited to [0, size-1] */ - const float min = 1.0F / (2.0F * size); - const float max = 1.0F - min; + const float min = 0.5F; + const float max = (float)size - 0.5F; + + s *= size; + s += offset; + if (s < min) *icoord = 0; else if (s > max) *icoord = size - 1; else - *icoord = util_ifloor(s * size); + *icoord = util_ifloor(s); } static void -wrap_nearest_clamp_to_border(float s, unsigned size, int *icoord) +wrap_nearest_clamp_to_border(float s, unsigned size, int offset, int *icoord) { /* s limited to [min,max] */ /* i limited to [-1, size] */ - const float min = -1.0F / (2.0F * size); - const float max = 1.0F - min; + const float min = -0.5F; + const float max = size + 0.5F; + + s *= size; + s += offset; if (s <= min) *icoord = -1; else if (s >= max) *icoord = size; else - *icoord = util_ifloor(s * size); + *icoord = util_ifloor(s); } - static void -wrap_nearest_mirror_repeat(float s, unsigned size, int *icoord) +wrap_nearest_mirror_repeat(float s, unsigned size, int offset, int *icoord) { const float min = 1.0F / (2.0F * size); const float max = 1.0F - min; - const int flr = util_ifloor(s); - float u = frac(s); + int flr; + float u; + + s += (float)offset / size; + flr = util_ifloor(s); + u = frac(s); if (flr & 1) u = 1.0F - u; if (u < min) @@ -205,51 +217,52 @@ wrap_nearest_mirror_repeat(float s, unsigned size, int *icoord) static void -wrap_nearest_mirror_clamp(float s, unsigned size, int *icoord) +wrap_nearest_mirror_clamp(float s, unsigned size, int offset, int *icoord) { /* s limited to [0,1] */ /* i limited to [0,size-1] */ - const float u = fabsf(s); + const float u = fabsf(s * size + offset); if (u <= 0.0F) *icoord = 0; - else if (u >= 1.0F) + else if (u >= size) *icoord = size - 1; else - *icoord = util_ifloor(u * size); + *icoord = util_ifloor(u); } static void -wrap_nearest_mirror_clamp_to_edge(float s, unsigned size, int *icoord) +wrap_nearest_mirror_clamp_to_edge(float s, unsigned size, int offset, int *icoord) { /* s limited to [min,max] */ /* i limited to [0, size-1] */ - const float min = 1.0F / (2.0F * size); - const float max = 1.0F - min; - const float u = fabsf(s); + const float min = 0.5F; + const float max = (float)size - 0.5F; + const float u = fabsf(s * size + offset); + if (u < min) *icoord = 0; else if (u > max) *icoord = size - 1; else - *icoord = util_ifloor(u * size); + *icoord = util_ifloor(u); } static void -wrap_nearest_mirror_clamp_to_border(float s, unsigned size, int *icoord) +wrap_nearest_mirror_clamp_to_border(float s, unsigned size, int offset, int *icoord) { - /* s limited to [min,max] */ - /* i limited to [0, size-1] */ - const float min = -1.0F / (2.0F * size); - const float max = 1.0F - min; - const float u = fabsf(s); + /* u limited to [-0.5, size-0.5] */ + const float min = -0.5F; + const float max = (float)size + 0.5F; + const float u = fabsf(s * size + offset); + if (u < min) *icoord = -1; else if (u > max) *icoord = size; else - *icoord = util_ifloor(u * size); + *icoord = util_ifloor(u); } @@ -264,22 +277,23 @@ wrap_nearest_mirror_clamp_to_border(float s, unsigned size, int *icoord) * \param icoord returns the computed integer texture coord */ static void -wrap_linear_repeat(float s, unsigned size, +wrap_linear_repeat(float s, unsigned size, int offset, int *icoord0, int *icoord1, float *w) { float u = s * size - 0.5F; - *icoord0 = repeat(util_ifloor(u), size); + *icoord0 = repeat(util_ifloor(u) + offset, size); *icoord1 = repeat(*icoord0 + 1, size); *w = frac(u); } static void -wrap_linear_clamp(float s, unsigned size, +wrap_linear_clamp(float s, unsigned size, int offset, int *icoord0, int *icoord1, float *w) { - float u = CLAMP(s, 0.0F, 1.0F); - u = u * size - 0.5f; + float u = CLAMP(s * size + offset, 0.0F, (float)size); + + u = u - 0.5f; *icoord0 = util_ifloor(u); *icoord1 = *icoord0 + 1; *w = frac(u); @@ -287,11 +301,11 @@ wrap_linear_clamp(float s, unsigned size, static void -wrap_linear_clamp_to_edge(float s, unsigned size, +wrap_linear_clamp_to_edge(float s, unsigned size, int offset, int *icoord0, int *icoord1, float *w) { - float u = CLAMP(s, 0.0F, 1.0F); - u = u * size - 0.5f; + float u = CLAMP(s * size + offset, 0.0F, (float)size); + u = u - 0.5f; *icoord0 = util_ifloor(u); *icoord1 = *icoord0 + 1; if (*icoord0 < 0) @@ -303,13 +317,13 @@ wrap_linear_clamp_to_edge(float s, unsigned size, static void -wrap_linear_clamp_to_border(float s, unsigned size, +wrap_linear_clamp_to_border(float s, unsigned size, int offset, int *icoord0, int *icoord1, float *w) { - const float min = -1.0F / (2.0F * size); - const float max = 1.0F - min; - float u = CLAMP(s, min, max); - u = u * size - 0.5f; + const float min = -0.5F; + const float max = (float)size + 0.5F; + float u = CLAMP(s * size + offset, min, max); + u = u - 0.5f; *icoord0 = util_ifloor(u); *icoord1 = *icoord0 + 1; *w = frac(u); @@ -317,11 +331,15 @@ wrap_linear_clamp_to_border(float s, unsigned size, static void -wrap_linear_mirror_repeat(float s, unsigned size, +wrap_linear_mirror_repeat(float s, unsigned size, int offset, int *icoord0, int *icoord1, float *w) { - const int flr = util_ifloor(s); - float u = frac(s); + int flr; + float u; + + s += (float)offset / size; + flr = util_ifloor(s); + u = frac(s); if (flr & 1) u = 1.0F - u; u = u * size - 0.5F; @@ -336,14 +354,12 @@ wrap_linear_mirror_repeat(float s, unsigned size, static void -wrap_linear_mirror_clamp(float s, unsigned size, +wrap_linear_mirror_clamp(float s, unsigned size, int offset, int *icoord0, int *icoord1, float *w) { - float u = fabsf(s); - if (u >= 1.0F) + float u = fabsf(s * size + offset); + if (u >= size) u = (float) size; - else - u *= size; u -= 0.5F; *icoord0 = util_ifloor(u); *icoord1 = *icoord0 + 1; @@ -352,14 +368,12 @@ wrap_linear_mirror_clamp(float s, unsigned size, static void -wrap_linear_mirror_clamp_to_edge(float s, unsigned size, +wrap_linear_mirror_clamp_to_edge(float s, unsigned size, int offset, int *icoord0, int *icoord1, float *w) { - float u = fabsf(s); - if (u >= 1.0F) + float u = fabsf(s * size + offset); + if (u >= size) u = (float) size; - else - u *= size; u -= 0.5F; *icoord0 = util_ifloor(u); *icoord1 = *icoord0 + 1; @@ -372,18 +386,16 @@ wrap_linear_mirror_clamp_to_edge(float s, unsigned size, static void -wrap_linear_mirror_clamp_to_border(float s, unsigned size, +wrap_linear_mirror_clamp_to_border(float s, unsigned size, int offset, int *icoord0, int *icoord1, float *w) { - const float min = -1.0F / (2.0F * size); - const float max = 1.0F - min; - float u = fabsf(s); + const float min = -0.5F; + const float max = size + 0.5F; + float u = fabsf(s * size + offset); if (u <= min) - u = min * size; + u = min; else if (u >= max) - u = max * size; - else - u *= size; + u = max; u -= 0.5F; *icoord0 = util_ifloor(u); *icoord1 = *icoord0 + 1; @@ -395,10 +407,10 @@ wrap_linear_mirror_clamp_to_border(float s, unsigned size, * PIPE_TEX_WRAP_CLAMP for nearest sampling, unnormalized coords. */ static void -wrap_nearest_unorm_clamp(float s, unsigned size, int *icoord) +wrap_nearest_unorm_clamp(float s, unsigned size, int offset, int *icoord) { int i = util_ifloor(s); - *icoord = CLAMP(i, 0, (int) size-1); + *icoord = CLAMP(i + offset, 0, (int) size-1); } @@ -406,9 +418,9 @@ wrap_nearest_unorm_clamp(float s, unsigned size, int *icoord) * PIPE_TEX_WRAP_CLAMP_TO_BORDER for nearest sampling, unnormalized coords. */ static void -wrap_nearest_unorm_clamp_to_border(float s, unsigned size, int *icoord) +wrap_nearest_unorm_clamp_to_border(float s, unsigned size, int offset, int *icoord) { - *icoord = util_ifloor( CLAMP(s, -0.5F, (float) size + 0.5F) ); + *icoord = util_ifloor( CLAMP(s + offset, -0.5F, (float) size + 0.5F) ); } @@ -416,9 +428,9 @@ wrap_nearest_unorm_clamp_to_border(float s, unsigned size, int *icoord) * PIPE_TEX_WRAP_CLAMP_TO_EDGE for nearest sampling, unnormalized coords. */ static void -wrap_nearest_unorm_clamp_to_edge(float s, unsigned size, int *icoord) +wrap_nearest_unorm_clamp_to_edge(float s, unsigned size, int offset, int *icoord) { - *icoord = util_ifloor( CLAMP(s, 0.5F, (float) size - 0.5F) ); + *icoord = util_ifloor( CLAMP(s + offset, 0.5F, (float) size - 0.5F) ); } @@ -426,11 +438,11 @@ wrap_nearest_unorm_clamp_to_edge(float s, unsigned size, int *icoord) * PIPE_TEX_WRAP_CLAMP for linear sampling, unnormalized coords. */ static void -wrap_linear_unorm_clamp(float s, unsigned size, +wrap_linear_unorm_clamp(float s, unsigned size, int offset, int *icoord0, int *icoord1, float *w) { /* Not exactly what the spec says, but it matches NVIDIA output */ - float u = CLAMP(s - 0.5F, 0.0f, (float) size - 1.0f); + float u = CLAMP(s + offset - 0.5F, 0.0f, (float) size - 1.0f); *icoord0 = util_ifloor(u); *icoord1 = *icoord0 + 1; *w = frac(u); @@ -441,10 +453,10 @@ wrap_linear_unorm_clamp(float s, unsigned size, * PIPE_TEX_WRAP_CLAMP_TO_BORDER for linear sampling, unnormalized coords. */ static void -wrap_linear_unorm_clamp_to_border(float s, unsigned size, +wrap_linear_unorm_clamp_to_border(float s, unsigned size, int offset, int *icoord0, int *icoord1, float *w) { - float u = CLAMP(s, -0.5F, (float) size + 0.5F); + float u = CLAMP(s + offset, -0.5F, (float) size + 0.5F); u -= 0.5F; *icoord0 = util_ifloor(u); *icoord1 = *icoord0 + 1; @@ -458,10 +470,10 @@ wrap_linear_unorm_clamp_to_border(float s, unsigned size, * PIPE_TEX_WRAP_CLAMP_TO_EDGE for linear sampling, unnormalized coords. */ static void -wrap_linear_unorm_clamp_to_edge(float s, unsigned size, +wrap_linear_unorm_clamp_to_edge(float s, unsigned size, int offset, int *icoord0, int *icoord1, float *w) { - float u = CLAMP(s, +0.5F, (float) size - 0.5F); + float u = CLAMP(s + offset, +0.5F, (float) size - 0.5F); u -= 0.5F; *icoord0 = util_ifloor(u); *icoord1 = *icoord0 + 1; @@ -474,11 +486,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 +769,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 +905,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, @@ -1008,22 +1019,18 @@ print_sample_4(const char *function, float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZ static INLINE void img_filter_2d_linear_repeat_POT(struct sp_sampler_view *sp_sview, struct sp_sampler *sp_samp, - float s, - float t, - float p, - unsigned level, - unsigned face_id, + const struct img_filter_args *args, float *rgba) { - unsigned xpot = pot_level_size(sp_sview->xpot, level); - unsigned ypot = pot_level_size(sp_sview->ypot, level); + unsigned xpot = pot_level_size(sp_sview->xpot, args->level); + unsigned ypot = pot_level_size(sp_sview->ypot, args->level); int xmax = (xpot - 1) & (TEX_TILE_SIZE - 1); /* MIN2(TEX_TILE_SIZE, xpot) - 1; */ int ymax = (ypot - 1) & (TEX_TILE_SIZE - 1); /* MIN2(TEX_TILE_SIZE, ypot) - 1; */ union tex_tile_address addr; int c; - float u = s * xpot - 0.5F; - float v = t * ypot - 0.5F; + float u = (args->s * xpot - 0.5F) + args->offset[0]; + float v = (args->t * ypot - 0.5F) + args->offset[1]; int uflr = util_ifloor(u); int vflr = util_ifloor(v); @@ -1037,7 +1044,7 @@ img_filter_2d_linear_repeat_POT(struct sp_sampler_view *sp_sview, const float *tx[4]; addr.value = 0; - addr.bits.level = level; + addr.bits.level = args->level; /* Can we fetch all four at once: */ @@ -1066,21 +1073,17 @@ img_filter_2d_linear_repeat_POT(struct sp_sampler_view *sp_sview, static INLINE void img_filter_2d_nearest_repeat_POT(struct sp_sampler_view *sp_sview, struct sp_sampler *sp_samp, - float s, - float t, - float p, - unsigned level, - unsigned face_id, + const struct img_filter_args *args, float rgba[TGSI_QUAD_SIZE]) { - unsigned xpot = pot_level_size(sp_sview->xpot, level); - unsigned ypot = pot_level_size(sp_sview->ypot, level); + unsigned xpot = pot_level_size(sp_sview->xpot, args->level); + unsigned ypot = pot_level_size(sp_sview->ypot, args->level); const float *out; union tex_tile_address addr; int c; - float u = s * xpot; - float v = t * ypot; + float u = args->s * xpot + args->offset[0]; + float v = args->t * ypot + args->offset[1]; int uflr = util_ifloor(u); int vflr = util_ifloor(v); @@ -1089,7 +1092,7 @@ img_filter_2d_nearest_repeat_POT(struct sp_sampler_view *sp_sview, int y0 = vflr & (ypot - 1); addr.value = 0; - addr.bits.level = level; + addr.bits.level = args->level; out = get_texel_2d_no_border(sp_sview, addr, x0, y0); for (c = 0; c < TGSI_QUAD_SIZE; c++) @@ -1104,26 +1107,22 @@ img_filter_2d_nearest_repeat_POT(struct sp_sampler_view *sp_sview, static INLINE void img_filter_2d_nearest_clamp_POT(struct sp_sampler_view *sp_sview, struct sp_sampler *sp_samp, - float s, - float t, - float p, - unsigned level, - unsigned face_id, + const struct img_filter_args *args, float rgba[TGSI_QUAD_SIZE]) { - unsigned xpot = pot_level_size(sp_sview->xpot, level); - unsigned ypot = pot_level_size(sp_sview->ypot, level); + unsigned xpot = pot_level_size(sp_sview->xpot, args->level); + unsigned ypot = pot_level_size(sp_sview->ypot, args->level); union tex_tile_address addr; int c; - float u = s * xpot; - float v = t * ypot; + float u = args->s * xpot + args->offset[0]; + float v = args->t * ypot + args->offset[1]; int x0, y0; const float *out; addr.value = 0; - addr.bits.level = level; + addr.bits.level = args->level; x0 = util_ifloor(u); if (x0 < 0) @@ -1150,11 +1149,7 @@ img_filter_2d_nearest_clamp_POT(struct sp_sampler_view *sp_sview, static void img_filter_1d_nearest(struct sp_sampler_view *sp_sview, struct sp_sampler *sp_samp, - float s, - float t, - float p, - unsigned level, - unsigned face_id, + const struct img_filter_args *args, float rgba[TGSI_QUAD_SIZE]) { const struct pipe_resource *texture = sp_sview->base.texture; @@ -1164,14 +1159,14 @@ img_filter_1d_nearest(struct sp_sampler_view *sp_sview, const float *out; int c; - width = u_minify(texture->width0, level); + width = u_minify(texture->width0, args->level); assert(width > 0); addr.value = 0; - addr.bits.level = level; + addr.bits.level = args->level; - sp_samp->nearest_texcoord_s(s, width, &x); + sp_samp->nearest_texcoord_s(args->s, width, args->offset[0], &x); out = get_texel_2d(sp_sview, sp_samp, addr, x, 0); for (c = 0; c < TGSI_QUAD_SIZE; c++) @@ -1186,11 +1181,7 @@ img_filter_1d_nearest(struct sp_sampler_view *sp_sview, static void img_filter_1d_array_nearest(struct sp_sampler_view *sp_sview, struct sp_sampler *sp_samp, - float s, - float t, - float p, - unsigned level, - unsigned face_id, + const struct img_filter_args *args, float *rgba) { const struct pipe_resource *texture = sp_sview->base.texture; @@ -1200,15 +1191,16 @@ img_filter_1d_array_nearest(struct sp_sampler_view *sp_sview, const float *out; int c; - width = u_minify(texture->width0, level); + width = u_minify(texture->width0, args->level); assert(width > 0); addr.value = 0; - addr.bits.level = level; + addr.bits.level = args->level; - sp_samp->nearest_texcoord_s(s, width, &x); - wrap_array_layer(t, texture->array_size, &layer); + sp_samp->nearest_texcoord_s(args->s, width, args->offset[0], &x); + layer = coord_to_layer(args->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++) @@ -1223,11 +1215,7 @@ img_filter_1d_array_nearest(struct sp_sampler_view *sp_sview, static void img_filter_2d_nearest(struct sp_sampler_view *sp_sview, struct sp_sampler *sp_samp, - float s, - float t, - float p, - unsigned level, - unsigned face_id, + const struct img_filter_args *args, float *rgba) { const struct pipe_resource *texture = sp_sview->base.texture; @@ -1237,17 +1225,17 @@ img_filter_2d_nearest(struct sp_sampler_view *sp_sview, const float *out; int c; - width = u_minify(texture->width0, level); - height = u_minify(texture->height0, level); + width = u_minify(texture->width0, args->level); + height = u_minify(texture->height0, args->level); assert(width > 0); assert(height > 0); addr.value = 0; - addr.bits.level = level; + addr.bits.level = args->level; - sp_samp->nearest_texcoord_s(s, width, &x); - sp_samp->nearest_texcoord_t(t, height, &y); + sp_samp->nearest_texcoord_s(args->s, width, args->offset[0], &x); + sp_samp->nearest_texcoord_t(args->t, height, args->offset[1], &y); out = get_texel_2d(sp_sview, sp_samp, addr, x, y); for (c = 0; c < TGSI_QUAD_SIZE; c++) @@ -1262,11 +1250,7 @@ img_filter_2d_nearest(struct sp_sampler_view *sp_sview, static void img_filter_2d_array_nearest(struct sp_sampler_view *sp_sview, struct sp_sampler *sp_samp, - float s, - float t, - float p, - unsigned level, - unsigned face_id, + const struct img_filter_args *args, float *rgba) { const struct pipe_resource *texture = sp_sview->base.texture; @@ -1276,18 +1260,19 @@ img_filter_2d_array_nearest(struct sp_sampler_view *sp_sview, const float *out; int c; - width = u_minify(texture->width0, level); - height = u_minify(texture->height0, level); + width = u_minify(texture->width0, args->level); + height = u_minify(texture->height0, args->level); assert(width > 0); assert(height > 0); addr.value = 0; - addr.bits.level = level; + addr.bits.level = args->level; - sp_samp->nearest_texcoord_s(s, width, &x); - sp_samp->nearest_texcoord_t(t, height, &y); - wrap_array_layer(p, texture->array_size, &layer); + sp_samp->nearest_texcoord_s(args->s, width, args->offset[0], &x); + sp_samp->nearest_texcoord_t(args->t, height, args->offset[1], &y); + layer = coord_to_layer(args->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,54 +1284,43 @@ 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, - float s, - float t, - float p, - unsigned level, - unsigned face_id, + const struct img_filter_args *args, float *rgba) { 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; - width = u_minify(texture->width0, level); - height = u_minify(texture->height0, level); + width = u_minify(texture->width0, args->level); + height = u_minify(texture->height0, args->level); assert(width > 0); assert(height > 0); addr.value = 0; - addr.bits.level = level; + addr.bits.level = args->level; /* * If NEAREST filtering is done within a miplevel, always apply wrap * mode CLAMP_TO_EDGE. */ if (sp_samp->base.seamless_cube_map) { - wrap_nearest_clamp_to_edge(s, width, &x); - wrap_nearest_clamp_to_edge(t, height, &y); + wrap_nearest_clamp_to_edge(args->s, width, args->offset[0], &x); + wrap_nearest_clamp_to_edge(args->t, height, args->offset[1], &y); } else { /* Would probably make sense to ignore mode and just do edge clamp */ - sp_samp->nearest_texcoord_s(s, width, &x); - sp_samp->nearest_texcoord_t(t, height, &y); + sp_samp->nearest_texcoord_s(args->s, width, args->offset[0], &x); + sp_samp->nearest_texcoord_t(args->t, height, args->offset[1], &y); } - out = get_texel_2d(sp_sview, sp_samp, face(addr, face_id), x, y); + layerface = args->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]; @@ -1358,34 +1332,32 @@ img_filter_cube_nearest(struct sp_sampler_view *sp_sview, static void img_filter_cube_array_nearest(struct sp_sampler_view *sp_sview, struct sp_sampler *sp_samp, - float s, - float t, - float p, - unsigned level, - unsigned face_id, + const struct img_filter_args *args, float *rgba) { 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; - width = u_minify(texture->width0, level); - height = u_minify(texture->height0, level); + width = u_minify(texture->width0, args->level); + height = u_minify(texture->height0, args->level); assert(width > 0); assert(height > 0); addr.value = 0; - addr.bits.level = level; + addr.bits.level = args->level; - sp_samp->nearest_texcoord_s(s, width, &x); - sp_samp->nearest_texcoord_t(t, height, &y); - wrap_array_layer(p, texture->array_size, &layer); + sp_samp->nearest_texcoord_s(args->s, width, args->offset[0], &x); + sp_samp->nearest_texcoord_t(args->t, height, args->offset[1], &y); + layerface = coord_to_layer(6 * args->p + sp_sview->base.u.tex.first_layer, + sp_sview->base.u.tex.first_layer, + sp_sview->base.u.tex.last_layer - 5) + args->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]; @@ -1397,11 +1369,7 @@ img_filter_cube_array_nearest(struct sp_sampler_view *sp_sview, static void img_filter_3d_nearest(struct sp_sampler_view *sp_sview, struct sp_sampler *sp_samp, - float s, - float t, - float p, - unsigned level, - unsigned face_id, + const struct img_filter_args *args, float *rgba) { const struct pipe_resource *texture = sp_sview->base.texture; @@ -1411,20 +1379,20 @@ img_filter_3d_nearest(struct sp_sampler_view *sp_sview, const float *out; int c; - width = u_minify(texture->width0, level); - height = u_minify(texture->height0, level); - depth = u_minify(texture->depth0, level); + width = u_minify(texture->width0, args->level); + height = u_minify(texture->height0, args->level); + depth = u_minify(texture->depth0, args->level); assert(width > 0); assert(height > 0); assert(depth > 0); - sp_samp->nearest_texcoord_s(s, width, &x); - sp_samp->nearest_texcoord_t(t, height, &y); - sp_samp->nearest_texcoord_p(p, depth, &z); + sp_samp->nearest_texcoord_s(args->s, width, args->offset[0], &x); + sp_samp->nearest_texcoord_t(args->t, height, args->offset[1], &y); + sp_samp->nearest_texcoord_p(args->p, depth, args->offset[2], &z); addr.value = 0; - addr.bits.level = level; + addr.bits.level = args->level; out = get_texel_3d(sp_sview, sp_samp, addr, x, y, z); for (c = 0; c < TGSI_QUAD_SIZE; c++) @@ -1435,11 +1403,7 @@ img_filter_3d_nearest(struct sp_sampler_view *sp_sview, static void img_filter_1d_linear(struct sp_sampler_view *sp_sview, struct sp_sampler *sp_samp, - float s, - float t, - float p, - unsigned level, - unsigned face_id, + const struct img_filter_args *args, float *rgba) { const struct pipe_resource *texture = sp_sview->base.texture; @@ -1450,14 +1414,14 @@ img_filter_1d_linear(struct sp_sampler_view *sp_sview, const float *tx0, *tx1; int c; - width = u_minify(texture->width0, level); + width = u_minify(texture->width0, args->level); assert(width > 0); addr.value = 0; - addr.bits.level = level; + addr.bits.level = args->level; - sp_samp->linear_texcoord_s(s, width, &x0, &x1, &xw); + sp_samp->linear_texcoord_s(args->s, width, args->offset[0], &x0, &x1, &xw); tx0 = get_texel_2d(sp_sview, sp_samp, addr, x0, 0); tx1 = get_texel_2d(sp_sview, sp_samp, addr, x1, 0); @@ -1471,11 +1435,7 @@ img_filter_1d_linear(struct sp_sampler_view *sp_sview, static void img_filter_1d_array_linear(struct sp_sampler_view *sp_sview, struct sp_sampler *sp_samp, - float s, - float t, - float p, - unsigned level, - unsigned face_id, + const struct img_filter_args *args, float *rgba) { const struct pipe_resource *texture = sp_sview->base.texture; @@ -1486,15 +1446,16 @@ img_filter_1d_array_linear(struct sp_sampler_view *sp_sview, const float *tx0, *tx1; int c; - width = u_minify(texture->width0, level); + width = u_minify(texture->width0, args->level); assert(width > 0); addr.value = 0; - addr.bits.level = level; + addr.bits.level = args->level; - sp_samp->linear_texcoord_s(s, width, &x0, &x1, &xw); - wrap_array_layer(t, texture->array_size, &layer); + sp_samp->linear_texcoord_s(args->s, width, args->offset[0], &x0, &x1, &xw); + layer = coord_to_layer(args->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); @@ -1504,15 +1465,77 @@ img_filter_1d_array_linear(struct sp_sampler_view *sp_sview, rgba[TGSI_NUM_CHANNELS*c] = lerp(xw, tx0[c], tx1[c]); } +/* + * Retrieve the gathered value, need to convert to the + * TGSI expected interface, and take component select + * and swizzling into account. + */ +static float +get_gather_value(const struct sp_sampler_view *sp_sview, + int chan_in, int comp_sel, + const float *tx[4]) +{ + int chan; + unsigned swizzle; + + /* + * softpipe samples in a different order + * to TGSI expects, so we need to swizzle, + * the samples into the correct slots. + */ + switch (chan_in) { + case 0: + chan = 2; + break; + case 1: + chan = 3; + break; + case 2: + chan = 1; + break; + case 3: + chan = 0; + break; + default: + assert(0); + return 0.0; + } + + /* pick which component to use for the swizzle */ + switch (comp_sel) { + case 0: + swizzle = sp_sview->base.swizzle_r; + break; + case 1: + swizzle = sp_sview->base.swizzle_g; + break; + case 2: + swizzle = sp_sview->base.swizzle_b; + break; + case 3: + swizzle = sp_sview->base.swizzle_a; + break; + default: + assert(0); + return 0.0; + } + + /* get correct result using the channel and swizzle */ + switch (swizzle) { + case PIPE_SWIZZLE_ZERO: + return 0.0; + case PIPE_SWIZZLE_ONE: + return 1.0; + default: + return tx[chan][swizzle]; + } +} + static void img_filter_2d_linear(struct sp_sampler_view *sp_sview, struct sp_sampler *sp_samp, - float s, - float t, - float p, - unsigned level, - unsigned face_id, + const struct img_filter_args *args, float *rgba) { const struct pipe_resource *texture = sp_sview->base.texture; @@ -1520,42 +1543,45 @@ img_filter_2d_linear(struct sp_sampler_view *sp_sview, int x0, y0, x1, y1; float xw, yw; /* weights */ union tex_tile_address addr; - const float *tx0, *tx1, *tx2, *tx3; + const float *tx[4]; int c; - width = u_minify(texture->width0, level); - height = u_minify(texture->height0, level); + width = u_minify(texture->width0, args->level); + height = u_minify(texture->height0, args->level); assert(width > 0); assert(height > 0); addr.value = 0; - addr.bits.level = level; + addr.bits.level = args->level; - sp_samp->linear_texcoord_s(s, width, &x0, &x1, &xw); - sp_samp->linear_texcoord_t(t, height, &y0, &y1, &yw); + sp_samp->linear_texcoord_s(args->s, width, args->offset[0], &x0, &x1, &xw); + sp_samp->linear_texcoord_t(args->t, height, args->offset[1], &y0, &y1, &yw); - tx0 = get_texel_2d(sp_sview, sp_samp, addr, x0, y0); - tx1 = get_texel_2d(sp_sview, sp_samp, addr, x1, y0); - tx2 = get_texel_2d(sp_sview, sp_samp, addr, x0, y1); - tx3 = get_texel_2d(sp_sview, sp_samp, addr, x1, y1); + tx[0] = get_texel_2d(sp_sview, sp_samp, addr, x0, y0); + tx[1] = get_texel_2d(sp_sview, sp_samp, addr, x1, y0); + tx[2] = get_texel_2d(sp_sview, sp_samp, addr, x0, y1); + tx[3] = get_texel_2d(sp_sview, sp_samp, addr, x1, y1); - /* interpolate R, G, B, A */ - for (c = 0; c < TGSI_QUAD_SIZE; c++) - rgba[TGSI_NUM_CHANNELS*c] = lerp_2d(xw, yw, - tx0[c], tx1[c], - tx2[c], tx3[c]); + if (args->gather_only) { + for (c = 0; c < TGSI_QUAD_SIZE; c++) + rgba[TGSI_NUM_CHANNELS*c] = get_gather_value(sp_sview, c, + args->gather_comp, + tx); + } else { + /* interpolate R, G, B, A */ + for (c = 0; c < TGSI_QUAD_SIZE; c++) + rgba[TGSI_NUM_CHANNELS*c] = lerp_2d(xw, yw, + tx[0][c], tx[1][c], + tx[2][c], tx[3][c]); + } } static void img_filter_2d_array_linear(struct sp_sampler_view *sp_sview, struct sp_sampler *sp_samp, - float s, - float t, - float p, - unsigned level, - unsigned face_id, + const struct img_filter_args *args, float *rgba) { const struct pipe_resource *texture = sp_sview->base.texture; @@ -1563,63 +1589,67 @@ img_filter_2d_array_linear(struct sp_sampler_view *sp_sview, int x0, y0, x1, y1, layer; float xw, yw; /* weights */ union tex_tile_address addr; - const float *tx0, *tx1, *tx2, *tx3; + const float *tx[4]; int c; - width = u_minify(texture->width0, level); - height = u_minify(texture->height0, level); + width = u_minify(texture->width0, args->level); + height = u_minify(texture->height0, args->level); assert(width > 0); assert(height > 0); 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); - - 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); - tx2 = get_texel_2d_array(sp_sview, sp_samp, addr, x0, y1, layer); - tx3 = get_texel_2d_array(sp_sview, sp_samp, addr, x1, y1, layer); - - /* interpolate R, G, B, A */ - for (c = 0; c < TGSI_QUAD_SIZE; c++) - rgba[TGSI_NUM_CHANNELS*c] = lerp_2d(xw, yw, - tx0[c], tx1[c], - tx2[c], tx3[c]); + addr.bits.level = args->level; + + sp_samp->linear_texcoord_s(args->s, width, args->offset[0], &x0, &x1, &xw); + sp_samp->linear_texcoord_t(args->t, height, args->offset[1], &y0, &y1, &yw); + layer = coord_to_layer(args->p, sp_sview->base.u.tex.first_layer, + sp_sview->base.u.tex.last_layer); + + tx[0] = get_texel_2d_array(sp_sview, sp_samp, addr, x0, y0, layer); + tx[1] = get_texel_2d_array(sp_sview, sp_samp, addr, x1, y0, layer); + tx[2] = get_texel_2d_array(sp_sview, sp_samp, addr, x0, y1, layer); + tx[3] = get_texel_2d_array(sp_sview, sp_samp, addr, x1, y1, layer); + + if (args->gather_only) { + for (c = 0; c < TGSI_QUAD_SIZE; c++) + rgba[TGSI_NUM_CHANNELS*c] = get_gather_value(sp_sview, c, + args->gather_comp, + tx); + } else { + /* interpolate R, G, B, A */ + for (c = 0; c < TGSI_QUAD_SIZE; c++) + rgba[TGSI_NUM_CHANNELS*c] = lerp_2d(xw, yw, + tx[0][c], tx[1][c], + tx[2][c], tx[3][c]); + } } static void img_filter_cube_linear(struct sp_sampler_view *sp_sview, struct sp_sampler *sp_samp, - float s, - float t, - float p, - unsigned level, - unsigned face_id, + const struct img_filter_args *args, float *rgba) { 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; - const float *tx0, *tx1, *tx2, *tx3; + union tex_tile_address addr; + const float *tx[4]; 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); - height = u_minify(texture->height0, level); + width = u_minify(texture->width0, args->level); + height = u_minify(texture->height0, args->level); assert(width > 0); assert(height > 0); addr.value = 0; - addr.bits.level = level; + addr.bits.level = args->level; /* * For seamless if LINEAR filtering is done within a miplevel, @@ -1627,43 +1657,47 @@ img_filter_cube_linear(struct sp_sampler_view *sp_sview, */ 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); + wrap_linear_clamp_to_border(args->s, width, args->offset[0], &x0, &x1, &xw); + wrap_linear_clamp_to_border(args->t, height, args->offset[1], &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); + sp_samp->linear_texcoord_s(args->s, width, args->offset[0], &x0, &x1, &xw); + sp_samp->linear_texcoord_t(args->t, height, args->offset[1], &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); + tx[0] = get_texel_cube_seamless(sp_sview, addr, x0, y0, corner0, layer, args->face_id); + tx[1] = get_texel_cube_seamless(sp_sview, addr, x1, y0, corner1, layer, args->face_id); + tx[2] = get_texel_cube_seamless(sp_sview, addr, x0, y1, corner2, layer, args->face_id); + tx[3] = get_texel_cube_seamless(sp_sview, addr, x1, y1, corner3, layer, args->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); + tx[0] = get_texel_cube_array(sp_sview, sp_samp, addr, x0, y0, layer + args->face_id); + tx[1] = get_texel_cube_array(sp_sview, sp_samp, addr, x1, y0, layer + args->face_id); + tx[2] = get_texel_cube_array(sp_sview, sp_samp, addr, x0, y1, layer + args->face_id); + tx[3] = get_texel_cube_array(sp_sview, sp_samp, addr, x1, y1, layer + args->face_id); + } + + if (args->gather_only) { + for (c = 0; c < TGSI_QUAD_SIZE; c++) + rgba[TGSI_NUM_CHANNELS*c] = get_gather_value(sp_sview, c, + args->gather_comp, + tx); + } else { + /* interpolate R, G, B, A */ + for (c = 0; c < TGSI_QUAD_SIZE; c++) + rgba[TGSI_NUM_CHANNELS*c] = lerp_2d(xw, yw, + tx[0][c], tx[1][c], + tx[2][c], tx[3][c]); } - /* interpolate R, G, B, A */ - for (c = 0; c < TGSI_QUAD_SIZE; c++) - rgba[TGSI_NUM_CHANNELS*c] = lerp_2d(xw, yw, - tx0[c], tx1[c], - tx2[c], tx3[c]); } static void img_filter_cube_array_linear(struct sp_sampler_view *sp_sview, struct sp_sampler *sp_samp, - float s, - float t, - float p, - unsigned level, - unsigned face_id, + const struct img_filter_args *args, float *rgba) { const struct pipe_resource *texture = sp_sview->base.texture; @@ -1671,42 +1705,68 @@ img_filter_cube_array_linear(struct sp_sampler_view *sp_sview, int x0, y0, x1, y1, layer; float xw, yw; /* weights */ union tex_tile_address addr; - const float *tx0, *tx1, *tx2, *tx3; + const float *tx[4]; + 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); - height = u_minify(texture->height0, level); + width = u_minify(texture->width0, args->level); + height = u_minify(texture->height0, args->level); assert(width > 0); assert(height > 0); addr.value = 0; - addr.bits.level = level; + addr.bits.level = args->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(args->s, width, args->offset[0], &x0, &x1, &xw); + wrap_linear_clamp_to_border(args->t, height, args->offset[1], &y0, &y1, &yw); + } else { + /* Would probably make sense to ignore mode and just do edge clamp */ + sp_samp->linear_texcoord_s(args->s, width, args->offset[0], &x0, &x1, &xw); + sp_samp->linear_texcoord_t(args->t, height, args->offset[1], &y0, &y1, &yw); + } - 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); + layer = coord_to_layer(6 * args->p + sp_sview->base.u.tex.first_layer, + sp_sview->base.u.tex.first_layer, + sp_sview->base.u.tex.last_layer - 5); - /* interpolate R, G, B, A */ - for (c = 0; c < TGSI_QUAD_SIZE; c++) - rgba[TGSI_NUM_CHANNELS*c] = lerp_2d(xw, yw, - tx0[c], tx1[c], - tx2[c], tx3[c]); + if (sp_samp->base.seamless_cube_map) { + tx[0] = get_texel_cube_seamless(sp_sview, addr, x0, y0, corner0, layer, args->face_id); + tx[1] = get_texel_cube_seamless(sp_sview, addr, x1, y0, corner1, layer, args->face_id); + tx[2] = get_texel_cube_seamless(sp_sview, addr, x0, y1, corner2, layer, args->face_id); + tx[3] = get_texel_cube_seamless(sp_sview, addr, x1, y1, corner3, layer, args->face_id); + } else { + tx[0] = get_texel_cube_array(sp_sview, sp_samp, addr, x0, y0, layer + args->face_id); + tx[1] = get_texel_cube_array(sp_sview, sp_samp, addr, x1, y0, layer + args->face_id); + tx[2] = get_texel_cube_array(sp_sview, sp_samp, addr, x0, y1, layer + args->face_id); + tx[3] = get_texel_cube_array(sp_sview, sp_samp, addr, x1, y1, layer + args->face_id); + } + + if (args->gather_only) { + for (c = 0; c < TGSI_QUAD_SIZE; c++) + rgba[TGSI_NUM_CHANNELS*c] = get_gather_value(sp_sview, c, + args->gather_comp, + tx); + } else { + /* interpolate R, G, B, A */ + for (c = 0; c < TGSI_QUAD_SIZE; c++) + rgba[TGSI_NUM_CHANNELS*c] = lerp_2d(xw, yw, + tx[0][c], tx[1][c], + tx[2][c], tx[3][c]); + } } static void img_filter_3d_linear(struct sp_sampler_view *sp_sview, struct sp_sampler *sp_samp, - float s, - float t, - float p, - unsigned level, - unsigned face_id, + const struct img_filter_args *args, float *rgba) { const struct pipe_resource *texture = sp_sview->base.texture; @@ -1717,21 +1777,20 @@ img_filter_3d_linear(struct sp_sampler_view *sp_sview, const float *tx00, *tx01, *tx02, *tx03, *tx10, *tx11, *tx12, *tx13; int c; - width = u_minify(texture->width0, level); - height = u_minify(texture->height0, level); - depth = u_minify(texture->depth0, level); + width = u_minify(texture->width0, args->level); + height = u_minify(texture->height0, args->level); + depth = u_minify(texture->depth0, args->level); addr.value = 0; - addr.bits.level = level; + addr.bits.level = args->level; assert(width > 0); assert(height > 0); assert(depth > 0); - sp_samp->linear_texcoord_s(s, width, &x0, &x1, &xw); - sp_samp->linear_texcoord_t(t, height, &y0, &y1, &yw); - sp_samp->linear_texcoord_p(p, depth, &z0, &z1, &zw); - + sp_samp->linear_texcoord_s(args->s, width, args->offset[0], &x0, &x1, &xw); + sp_samp->linear_texcoord_t(args->t, height, args->offset[1], &y0, &y1, &yw); + sp_samp->linear_texcoord_p(args->p, depth, args->offset[2], &z0, &z1, &zw); tx00 = get_texel_3d(sp_sview, sp_samp, addr, x0, y0, z0); tx01 = get_texel_3d(sp_sview, sp_samp, addr, x1, y0, z0); @@ -1837,6 +1896,7 @@ compute_lambda_lod(struct sp_sampler_view *sp_sview, } break; case tgsi_sampler_lod_zero: + case tgsi_sampler_gather: /* this is all static state in the sampler really need clamp here? */ lod[0] = lod[1] = lod[2] = lod[3] = CLAMP(lod_bias, min_lod, max_lod); break; @@ -1846,6 +1906,12 @@ compute_lambda_lod(struct sp_sampler_view *sp_sview, } } +static INLINE unsigned +get_gather_component(const float lod_in[TGSI_QUAD_SIZE]) +{ + /* gather component is stored in lod_in slot as unsigned */ + return (*(unsigned int *)lod_in) & 0x3; +} static void mip_filter_linear(struct sp_sampler_view *sp_sview, @@ -1857,36 +1923,45 @@ mip_filter_linear(struct sp_sampler_view *sp_sview, const float p[TGSI_QUAD_SIZE], const float c0[TGSI_QUAD_SIZE], const float lod_in[TGSI_QUAD_SIZE], - enum tgsi_sampler_control control, + const struct filter_args *filt_args, float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]) { const struct pipe_sampler_view *psview = &sp_sview->base; int j; float lod[TGSI_QUAD_SIZE]; + struct img_filter_args args; - compute_lambda_lod(sp_sview, sp_samp, s, t, p, lod_in, control, lod); + compute_lambda_lod(sp_sview, sp_samp, s, t, p, lod_in, filt_args->control, lod); + + args.offset = filt_args->offset; + args.gather_only = filt_args->control == tgsi_sampler_gather; + args.gather_comp = get_gather_component(lod_in); for (j = 0; j < TGSI_QUAD_SIZE; j++) { int level0 = psview->u.tex.first_level + (int)lod[j]; - if (lod[j] < 0.0) - mag_filter(sp_sview, sp_samp, s[j], t[j], p[j], - psview->u.tex.first_level, - sp_sview->faces[j], &rgba[0][j]); - - else if (level0 >= (int) psview->u.tex.last_level) - min_filter(sp_sview, sp_samp, s[j], t[j], p[j], psview->u.tex.last_level, - sp_sview->faces[j], &rgba[0][j]); + args.s = s[j]; + args.t = t[j]; + args.p = p[j]; + args.face_id = sp_sview->faces[j]; + if (lod[j] < 0.0) { + args.level = psview->u.tex.first_level; + mag_filter(sp_sview, sp_samp, &args, &rgba[0][j]); + } + else if (level0 >= (int) psview->u.tex.last_level) { + args.level = psview->u.tex.last_level; + min_filter(sp_sview, sp_samp, &args, &rgba[0][j]); + } else { float levelBlend = frac(lod[j]); float rgbax[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]; int c; - min_filter(sp_sview, sp_samp, s[j], t[j], p[j], level0, - sp_sview->faces[j], &rgbax[0][0]); - min_filter(sp_sview, sp_samp, s[j], t[j], p[j], level0+1, - sp_sview->faces[j], &rgbax[0][1]); + args.level = level0; + min_filter(sp_sview, sp_samp, &args, &rgbax[0][0]); + args.level = level0+1; + min_filter(sp_sview, sp_samp, &args, &rgbax[0][1]); for (c = 0; c < 4; c++) { rgba[c][j] = lerp(levelBlend, rgbax[c][0], rgbax[c][1]); @@ -1915,25 +1990,33 @@ mip_filter_nearest(struct sp_sampler_view *sp_sview, const float p[TGSI_QUAD_SIZE], const float c0[TGSI_QUAD_SIZE], const float lod_in[TGSI_QUAD_SIZE], - enum tgsi_sampler_control control, + const struct filter_args *filt_args, float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]) { const struct pipe_sampler_view *psview = &sp_sview->base; float lod[TGSI_QUAD_SIZE]; int j; + struct img_filter_args args; + + args.offset = filt_args->offset; + args.gather_only = filt_args->control == tgsi_sampler_gather; + args.gather_comp = get_gather_component(lod_in); - compute_lambda_lod(sp_sview, sp_samp, s, t, p, lod_in, control, lod); + compute_lambda_lod(sp_sview, sp_samp, s, t, p, lod_in, filt_args->control, lod); for (j = 0; j < TGSI_QUAD_SIZE; j++) { - if (lod[j] < 0.0) - mag_filter(sp_sview, sp_samp, s[j], t[j], p[j], - psview->u.tex.first_level, - sp_sview->faces[j], &rgba[0][j]); - else { + args.s = s[j]; + args.t = t[j]; + args.p = p[j]; + args.face_id = sp_sview->faces[j]; + + if (lod[j] < 0.0) { + args.level = psview->u.tex.first_level; + mag_filter(sp_sview, sp_samp, &args, &rgba[0][j]); + } else { int level = psview->u.tex.first_level + (int)(lod[j] + 0.5F); - level = MIN2(level, (int)psview->u.tex.last_level); - min_filter(sp_sview, sp_samp, s[j], t[j], p[j], - level, sp_sview->faces[j], &rgba[0][j]); + args.level = MIN2(level, (int)psview->u.tex.last_level); + min_filter(sp_sview, sp_samp, &args, &rgba[0][j]); } } @@ -1953,24 +2036,29 @@ mip_filter_none(struct sp_sampler_view *sp_sview, const float p[TGSI_QUAD_SIZE], const float c0[TGSI_QUAD_SIZE], const float lod_in[TGSI_QUAD_SIZE], - enum tgsi_sampler_control control, + const struct filter_args *filt_args, float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]) { float lod[TGSI_QUAD_SIZE]; int j; + struct img_filter_args args; + + args.level = sp_sview->base.u.tex.first_level; + args.offset = filt_args->offset; + args.gather_only = filt_args->control == tgsi_sampler_gather; - compute_lambda_lod(sp_sview, sp_samp, s, t, p, lod_in, control, lod); + compute_lambda_lod(sp_sview, sp_samp, s, t, p, lod_in, filt_args->control, lod); for (j = 0; j < TGSI_QUAD_SIZE; j++) { - if (lod[j] < 0.0) { - mag_filter(sp_sview, sp_samp, s[j], t[j], p[j], - sp_sview->base.u.tex.first_level, - sp_sview->faces[j], &rgba[0][j]); + args.s = s[j]; + args.t = t[j]; + args.p = p[j]; + args.face_id = sp_sview->faces[j]; + if (lod[j] < 0.0) { + mag_filter(sp_sview, sp_samp, &args, &rgba[0][j]); } else { - min_filter(sp_sview, sp_samp, s[j], t[j], p[j], - sp_sview->base.u.tex.first_level, - sp_sview->faces[j], &rgba[0][j]); + min_filter(sp_sview, sp_samp, &args, &rgba[0][j]); } } } @@ -1986,15 +2074,21 @@ mip_filter_none_no_filter_select(struct sp_sampler_view *sp_sview, const float p[TGSI_QUAD_SIZE], const float c0[TGSI_QUAD_SIZE], const float lod_in[TGSI_QUAD_SIZE], - enum tgsi_sampler_control control, + const struct filter_args *filt_args, float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]) { int j; - - for (j = 0; j < TGSI_QUAD_SIZE; j++) - mag_filter(sp_sview, sp_samp, s[j], t[j], p[j], - sp_sview->base.u.tex.first_level, - sp_sview->faces[j], &rgba[0][j]); + struct img_filter_args args; + args.level = sp_sview->base.u.tex.first_level; + args.offset = filt_args->offset; + args.gather_only = filt_args->control == tgsi_sampler_gather; + for (j = 0; j < TGSI_QUAD_SIZE; j++) { + args.s = s[j]; + args.t = t[j]; + args.p = p[j]; + args.face_id = sp_sview->faces[j]; + mag_filter(sp_sview, sp_samp, &args, &rgba[0][j]); + } } @@ -2050,7 +2144,7 @@ img_filter_2d_ewa(struct sp_sampler_view *sp_sview, float scaling = 1.0f / (1 << level0); int width = u_minify(texture->width0, level0); int height = u_minify(texture->height0, level0); - + struct img_filter_args args; float ux = dudx * scaling; float vx = dvdx * scaling; float uy = dudy * scaling; @@ -2100,7 +2194,8 @@ img_filter_2d_ewa(struct sp_sampler_view *sp_sview, * full, then the pixel values are read from the image. */ ddq = 2 * A; - + + args.level = level; for (j = 0; j < TGSI_QUAD_SIZE; j++) { /* Heckbert MS thesis, p. 59; scan over the bounding box of the ellipse * and incrementally update the value of Ax^2+Bxy*Cy^2; when this @@ -2117,6 +2212,8 @@ img_filter_2d_ewa(struct sp_sampler_view *sp_sview, float num[4] = {0.0F, 0.0F, 0.0F, 0.0F}; buffer_next = 0; den = 0; + args.face_id = sp_sview->faces[j]; + U = u0 - tex_u; for (v = v0; v <= v1; ++v) { float V = v - tex_v; @@ -2148,8 +2245,10 @@ img_filter_2d_ewa(struct sp_sampler_view *sp_sview, * accelerated img_filter_2d_nearest_XXX functions. */ for (jj = 0; jj < buffer_next; jj++) { - min_filter(sp_sview, sp_samp, s_buffer[jj], t_buffer[jj], p[jj], - level, sp_sview->faces[j], &rgba_temp[0][jj]); + args.s = s_buffer[jj]; + args.t = t_buffer[jj]; + args.p = p[jj]; + min_filter(sp_sview, sp_samp, &args, &rgba_temp[0][jj]); num[0] += weight_buffer[jj] * rgba_temp[0][jj]; num[1] += weight_buffer[jj] * rgba_temp[1][jj]; num[2] += weight_buffer[jj] * rgba_temp[2][jj]; @@ -2176,8 +2275,10 @@ img_filter_2d_ewa(struct sp_sampler_view *sp_sview, * accelerated img_filter_2d_nearest_XXX functions. */ for (jj = 0; jj < buffer_next; jj++) { - min_filter(sp_sview, sp_samp, s_buffer[jj], t_buffer[jj], p[jj], - level, sp_sview->faces[j], &rgba_temp[0][jj]); + args.s = s_buffer[jj]; + args.t = t_buffer[jj]; + args.p = p[jj]; + min_filter(sp_sview, sp_samp, &args, &rgba_temp[0][jj]); num[0] += weight_buffer[jj] * rgba_temp[0][jj]; num[1] += weight_buffer[jj] * rgba_temp[1][jj]; num[2] += weight_buffer[jj] * rgba_temp[2][jj]; @@ -2196,8 +2297,10 @@ img_filter_2d_ewa(struct sp_sampler_view *sp_sview, rgba[2]=0; rgba[3]=0;*/ /* not enough pixels in resampling, resort to direct interpolation */ - min_filter(sp_sview, sp_samp, s[j], t[j], p[j], level, - sp_sview->faces[j], &rgba_temp[0][j]); + args.s = s[j]; + args.t = t[j]; + args.p = p[j]; + min_filter(sp_sview, sp_samp, &args, &rgba_temp[0][j]); den = 1; num[0] = rgba_temp[0][j]; num[1] = rgba_temp[1][j]; @@ -2226,7 +2329,7 @@ mip_filter_linear_aniso(struct sp_sampler_view *sp_sview, const float p[TGSI_QUAD_SIZE], const float c0[TGSI_QUAD_SIZE], const float lod_in[TGSI_QUAD_SIZE], - enum tgsi_sampler_control control, + const struct filter_args *filt_args, float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]) { const struct pipe_resource *texture = sp_sview->base.texture; @@ -2241,11 +2344,12 @@ mip_filter_linear_aniso(struct sp_sampler_view *sp_sview, float dudy = (s[QUAD_TOP_LEFT] - s[QUAD_BOTTOM_LEFT]) * s_to_u; float dvdx = (t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT]) * t_to_v; float dvdy = (t[QUAD_TOP_LEFT] - t[QUAD_BOTTOM_LEFT]) * t_to_v; - - if (control == tgsi_sampler_lod_bias || - control == tgsi_sampler_lod_none || + struct img_filter_args args; + + if (filt_args->control == tgsi_sampler_lod_bias || + filt_args->control == tgsi_sampler_lod_none || /* XXX FIXME */ - control == tgsi_sampler_derivs_explicit) { + filt_args->control == tgsi_sampler_derivs_explicit) { /* note: instead of working with Px and Py, we will use the * squared length instead, to avoid sqrt. */ @@ -2282,12 +2386,12 @@ mip_filter_linear_aniso(struct sp_sampler_view *sp_sview, * this since 0.5*log(x) = log(sqrt(x)) */ lambda = 0.5F * util_fast_log2(Pmin2) + sp_samp->base.lod_bias; - compute_lod(&sp_samp->base, control, lambda, lod_in, lod); + compute_lod(&sp_samp->base, filt_args->control, lambda, lod_in, lod); } else { - assert(control == tgsi_sampler_lod_explicit || - control == tgsi_sampler_lod_zero); - compute_lod(&sp_samp->base, control, sp_samp->base.lod_bias, lod_in, lod); + assert(filt_args->control == tgsi_sampler_lod_explicit || + filt_args->control == tgsi_sampler_lod_zero); + compute_lod(&sp_samp->base, filt_args->control, sp_samp->base.lod_bias, lod_in, lod); } /* XXX: Take into account all lod values. @@ -2300,9 +2404,14 @@ mip_filter_linear_aniso(struct sp_sampler_view *sp_sview, */ if (level0 >= (int) psview->u.tex.last_level) { int j; - for (j = 0; j < TGSI_QUAD_SIZE; j++) - min_filter(sp_sview, sp_samp, s[j], t[j], p[j], psview->u.tex.last_level, - sp_sview->faces[j], &rgba[0][j]); + for (j = 0; j < TGSI_QUAD_SIZE; j++) { + args.s = s[j]; + args.t = t[j]; + args.p = p[j]; + args.level = psview->u.tex.last_level; + args.face_id = sp_sview->faces[j]; + min_filter(sp_sview, sp_samp, &args, &rgba[0][j]); + } } else { /* don't bother interpolating between multiple LODs; it doesn't @@ -2334,29 +2443,33 @@ mip_filter_linear_2d_linear_repeat_POT( const float p[TGSI_QUAD_SIZE], const float c0[TGSI_QUAD_SIZE], const float lod_in[TGSI_QUAD_SIZE], - enum tgsi_sampler_control control, + const struct filter_args *filt_args, float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]) { const struct pipe_sampler_view *psview = &sp_sview->base; int j; float lod[TGSI_QUAD_SIZE]; - compute_lambda_lod(sp_sview, sp_samp, s, t, p, lod_in, control, lod); + compute_lambda_lod(sp_sview, sp_samp, s, t, p, lod_in, filt_args->control, lod); for (j = 0; j < TGSI_QUAD_SIZE; j++) { int level0 = psview->u.tex.first_level + (int)lod[j]; - + struct img_filter_args args; /* Catches both negative and large values of level0: */ + args.s = s[j]; + args.t = t[j]; + args.p = p[j]; + args.face_id = sp_sview->faces[j]; + args.offset = filt_args->offset; + args.gather_only = filt_args->control == tgsi_sampler_gather; if ((unsigned)level0 >= psview->u.tex.last_level) { if (level0 < 0) - img_filter_2d_linear_repeat_POT(sp_sview, sp_samp, s[j], t[j], p[j], - psview->u.tex.first_level, - sp_sview->faces[j], &rgba[0][j]); + args.level = psview->u.tex.first_level; else - img_filter_2d_linear_repeat_POT(sp_sview, sp_samp, s[j], t[j], p[j], - psview->u.tex.last_level, - sp_sview->faces[j], &rgba[0][j]); + args.level = psview->u.tex.last_level; + img_filter_2d_linear_repeat_POT(sp_sview, sp_samp, &args, + &rgba[0][j]); } else { @@ -2364,10 +2477,10 @@ mip_filter_linear_2d_linear_repeat_POT( float rgbax[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]; int c; - img_filter_2d_linear_repeat_POT(sp_sview, sp_samp, s[j], t[j], p[j], level0, - sp_sview->faces[j], &rgbax[0][0]); - img_filter_2d_linear_repeat_POT(sp_sview, sp_samp, s[j], t[j], p[j], level0+1, - sp_sview->faces[j], &rgbax[0][1]); + args.level = level0; + img_filter_2d_linear_repeat_POT(sp_sview, sp_samp, &args, &rgbax[0][0]); + args.level = level0+1; + img_filter_2d_linear_repeat_POT(sp_sview, sp_samp, &args, &rgbax[0][1]); for (c = 0; c < TGSI_NUM_CHANNELS; c++) rgba[c][j] = lerp(levelBlend, rgbax[c][0], rgbax[c][1]); @@ -2395,11 +2508,12 @@ sample_compare(struct sp_sampler_view *sp_sview, float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]) { const struct pipe_sampler_state *sampler = &sp_samp->base; - int j; - int k[4]; + int j, v; + int k[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]; float pc[4]; const struct util_format_description *format_desc; unsigned chan_type; + bool is_gather = (control == tgsi_sampler_gather); /** * Compare texcoord 'p' (aka R) against texture value 'rgba[0]' @@ -2408,13 +2522,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]; @@ -2443,65 +2557,74 @@ sample_compare(struct sp_sampler_view *sp_sview, pc[3] = CLAMP(pc[3], 0.0F, 1.0F); } - /* compare four texcoords vs. four texture samples */ - switch (sampler->compare_func) { - case PIPE_FUNC_LESS: - k[0] = pc[0] < rgba[0][0]; - k[1] = pc[1] < rgba[0][1]; - k[2] = pc[2] < rgba[0][2]; - k[3] = pc[3] < rgba[0][3]; - break; - case PIPE_FUNC_LEQUAL: - k[0] = pc[0] <= rgba[0][0]; - k[1] = pc[1] <= rgba[0][1]; - k[2] = pc[2] <= rgba[0][2]; - k[3] = pc[3] <= rgba[0][3]; - break; - case PIPE_FUNC_GREATER: - k[0] = pc[0] > rgba[0][0]; - k[1] = pc[1] > rgba[0][1]; - k[2] = pc[2] > rgba[0][2]; - k[3] = pc[3] > rgba[0][3]; - break; - case PIPE_FUNC_GEQUAL: - k[0] = pc[0] >= rgba[0][0]; - k[1] = pc[1] >= rgba[0][1]; - k[2] = pc[2] >= rgba[0][2]; - k[3] = pc[3] >= rgba[0][3]; - break; - case PIPE_FUNC_EQUAL: - k[0] = pc[0] == rgba[0][0]; - k[1] = pc[1] == rgba[0][1]; - k[2] = pc[2] == rgba[0][2]; - k[3] = pc[3] == rgba[0][3]; - break; - case PIPE_FUNC_NOTEQUAL: - k[0] = pc[0] != rgba[0][0]; - k[1] = pc[1] != rgba[0][1]; - k[2] = pc[2] != rgba[0][2]; - k[3] = pc[3] != rgba[0][3]; - break; - case PIPE_FUNC_ALWAYS: - k[0] = k[1] = k[2] = k[3] = 1; - break; - case PIPE_FUNC_NEVER: - k[0] = k[1] = k[2] = k[3] = 0; - break; - default: - k[0] = k[1] = k[2] = k[3] = 0; - assert(0); - break; + for (v = 0; v < (is_gather ? TGSI_NUM_CHANNELS : 1); v++) { + /* compare four texcoords vs. four texture samples */ + switch (sampler->compare_func) { + case PIPE_FUNC_LESS: + k[v][0] = pc[0] < rgba[v][0]; + k[v][1] = pc[1] < rgba[v][1]; + k[v][2] = pc[2] < rgba[v][2]; + k[v][3] = pc[3] < rgba[v][3]; + break; + case PIPE_FUNC_LEQUAL: + k[v][0] = pc[0] <= rgba[v][0]; + k[v][1] = pc[1] <= rgba[v][1]; + k[v][2] = pc[2] <= rgba[v][2]; + k[v][3] = pc[3] <= rgba[v][3]; + break; + case PIPE_FUNC_GREATER: + k[v][0] = pc[0] > rgba[v][0]; + k[v][1] = pc[1] > rgba[v][1]; + k[v][2] = pc[2] > rgba[v][2]; + k[v][3] = pc[3] > rgba[v][3]; + break; + case PIPE_FUNC_GEQUAL: + k[v][0] = pc[0] >= rgba[v][0]; + k[v][1] = pc[1] >= rgba[v][1]; + k[v][2] = pc[2] >= rgba[v][2]; + k[v][3] = pc[3] >= rgba[v][3]; + break; + case PIPE_FUNC_EQUAL: + k[v][0] = pc[0] == rgba[v][0]; + k[v][1] = pc[1] == rgba[v][1]; + k[v][2] = pc[2] == rgba[v][2]; + k[v][3] = pc[3] == rgba[v][3]; + break; + case PIPE_FUNC_NOTEQUAL: + k[v][0] = pc[0] != rgba[v][0]; + k[v][1] = pc[1] != rgba[v][1]; + k[v][2] = pc[2] != rgba[v][2]; + k[v][3] = pc[3] != rgba[v][3]; + break; + case PIPE_FUNC_ALWAYS: + k[v][0] = k[v][1] = k[v][2] = k[v][3] = 1; + break; + case PIPE_FUNC_NEVER: + k[v][0] = k[v][1] = k[v][2] = k[v][3] = 0; + break; + default: + k[v][0] = k[v][1] = k[v][2] = k[v][3] = 0; + assert(0); + break; + } } - for (j = 0; j < TGSI_QUAD_SIZE; j++) { - rgba[0][j] = k[j]; - rgba[1][j] = k[j]; - rgba[2][j] = k[j]; - rgba[3][j] = 1.0F; + if (is_gather) { + for (j = 0; j < TGSI_QUAD_SIZE; j++) { + for (v = 0; v < TGSI_NUM_CHANNELS; v++) { + rgba[v][j] = k[v][j]; + } + } + } else { + for (j = 0; j < TGSI_QUAD_SIZE; j++) { + rgba[0][j] = k[0][j]; + rgba[1][j] = k[0][j]; + rgba[2][j] = k[0][j]; + rgba[3][j] = 1.0F; + } } } - static void do_swizzling(const struct pipe_sampler_view *sview, float in[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE], @@ -2679,9 +2802,9 @@ any_swizzle(const struct pipe_sampler_view *view) static img_filter_func get_img_filter(const struct sp_sampler_view *sp_sview, const struct pipe_sampler_state *sampler, - unsigned filter) + unsigned filter, bool gather) { - switch (sp_sview->base.texture->target) { + switch (sp_sview->base.target) { case PIPE_BUFFER: case PIPE_TEXTURE_1D: if (filter == PIPE_TEX_FILTER_NEAREST) @@ -2699,7 +2822,7 @@ get_img_filter(const struct sp_sampler_view *sp_sview, case PIPE_TEXTURE_RECT: /* Try for fast path: */ - if (sp_sview->pot2d && + if (!gather && sp_sview->pot2d && sampler->wrap_s == sampler->wrap_t && sampler->normalized_coords) { @@ -2769,35 +2892,38 @@ sample_mip(struct sp_sampler_view *sp_sview, const float p[TGSI_QUAD_SIZE], const float c0[TGSI_QUAD_SIZE], const float lod[TGSI_QUAD_SIZE], - enum tgsi_sampler_control control, + const struct filter_args *filt_args, float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]) { mip_filter_func mip_filter; img_filter_func min_img_filter = NULL; img_filter_func mag_img_filter = NULL; - if (sp_sview->pot2d & sp_samp->min_mag_equal_repeat_linear) { + if (filt_args->control == tgsi_sampler_gather) { + mip_filter = mip_filter_nearest; + min_img_filter = get_img_filter(sp_sview, &sp_samp->base, PIPE_TEX_FILTER_LINEAR, true); + } else if (sp_sview->pot2d & sp_samp->min_mag_equal_repeat_linear) { mip_filter = mip_filter_linear_2d_linear_repeat_POT; } else { mip_filter = sp_samp->mip_filter; - min_img_filter = get_img_filter(sp_sview, &sp_samp->base, sp_samp->min_img_filter); + min_img_filter = get_img_filter(sp_sview, &sp_samp->base, sp_samp->min_img_filter, false); if (sp_samp->min_mag_equal) { mag_img_filter = min_img_filter; } else { - mag_img_filter = get_img_filter(sp_sview, &sp_samp->base, sp_samp->base.mag_img_filter); + mag_img_filter = get_img_filter(sp_sview, &sp_samp->base, sp_samp->base.mag_img_filter, false); } } mip_filter(sp_sview, sp_samp, min_img_filter, mag_img_filter, - s, t, p, c0, lod, control, rgba); + s, t, p, c0, lod, filt_args, rgba); if (sp_samp->base.compare_mode != PIPE_TEX_COMPARE_NONE) { - sample_compare(sp_sview, sp_samp, s, t, p, c0, lod, control, rgba); + sample_compare(sp_sview, sp_samp, s, t, p, c0, lod, filt_args->control, rgba); } - if (sp_sview->need_swizzle) { + if (sp_sview->need_swizzle && filt_args->control != tgsi_sampler_gather) { float rgba_temp[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]; memcpy(rgba_temp, rgba, sizeof(rgba_temp)); do_swizzling(&sp_sview->base, rgba_temp, rgba); @@ -2818,7 +2944,7 @@ sample_cube(struct sp_sampler_view *sp_sview, const float p[TGSI_QUAD_SIZE], const float c0[TGSI_QUAD_SIZE], const float c1[TGSI_QUAD_SIZE], - enum tgsi_sampler_control control, + const struct filter_args *filt_args, float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]) { unsigned j; @@ -2896,7 +3022,7 @@ sample_cube(struct sp_sampler_view *sp_sview, } } - sample_mip(sp_sview, sp_samp, ssss, tttt, pppp, c0, c1, control, rgba); + sample_mip(sp_sview, sp_samp, ssss, tttt, pppp, c0, c1, filt_args, rgba); } @@ -2907,7 +3033,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 +3050,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 +3101,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 +3124,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 +3147,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 +3271,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 +3307,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 ); @@ -3230,7 +3391,7 @@ sp_tgsi_get_samples(struct tgsi_sampler *tgsi_sampler, float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]) { struct sp_tgsi_sampler *sp_samp = (struct sp_tgsi_sampler *)tgsi_sampler; - + struct filter_args filt_args; assert(sview_index < PIPE_MAX_SHADER_SAMPLER_VIEWS); assert(sampler_index < PIPE_MAX_SAMPLERS); assert(sp_samp->sp_sampler[sampler_index]); @@ -3244,9 +3405,12 @@ sp_tgsi_get_samples(struct tgsi_sampler *tgsi_sampler, } return; } + + filt_args.control = control; + filt_args.offset = offset; sp_samp->sp_sview[sview_index].get_samples(&sp_samp->sp_sview[sview_index], sp_samp->sp_sampler[sampler_index], - s, t, p, c0, lod, control, rgba); + s, t, p, c0, lod, &filt_args, rgba); } diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.h b/src/gallium/drivers/softpipe/sp_tex_sample.h index 00a97c5186b..7d1aafc4473 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.h +++ b/src/gallium/drivers/softpipe/sp_tex_sample.h @@ -38,10 +38,12 @@ struct sp_sampler; typedef void (*wrap_nearest_func)(float s, unsigned size, + int offset, int *icoord); typedef void (*wrap_linear_func)(float s, unsigned size, + int offset, int *icoord0, int *icoord1, float *w); @@ -51,15 +53,27 @@ typedef float (*compute_lambda_func)(const struct sp_sampler_view *sp_sview, const float t[TGSI_QUAD_SIZE], const float p[TGSI_QUAD_SIZE]); +struct img_filter_args { + float s; + float t; + float p; + unsigned level; + unsigned face_id; + const int8_t *offset; + bool gather_only; + int gather_comp; +}; + typedef void (*img_filter_func)(struct sp_sampler_view *sp_sview, struct sp_sampler *sp_samp, - float s, - float t, - float p, - unsigned level, - unsigned face_id, + const struct img_filter_args *args, float *rgba); +struct filter_args { + enum tgsi_sampler_control control; + const int8_t *offset; +}; + typedef void (*mip_filter_func)(struct sp_sampler_view *sp_sview, struct sp_sampler *sp_samp, img_filter_func min_filter, @@ -69,7 +83,7 @@ typedef void (*mip_filter_func)(struct sp_sampler_view *sp_sview, const float p[TGSI_QUAD_SIZE], const float c0[TGSI_QUAD_SIZE], const float lod[TGSI_QUAD_SIZE], - enum tgsi_sampler_control control, + const struct filter_args *args, float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]); @@ -80,7 +94,7 @@ typedef void (*filter_func)(struct sp_sampler_view *sp_sview, const float p[TGSI_QUAD_SIZE], const float c0[TGSI_QUAD_SIZE], const float lod[TGSI_QUAD_SIZE], - enum tgsi_sampler_control control, + const struct filter_args *args, float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]); 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; |