From: Marek Olšák <marek.ol...@amd.com>

This fixes compressedteximage piglit tests.

+10 piglits

Evergreen and Cayman have the same issue. R600 and R700 don't.
---
 src/gallium/drivers/radeon/r600_pipe_common.h |  1 +
 src/gallium/drivers/radeonsi/r600_blit.c      | 16 ++++++++++++++++
 src/gallium/drivers/radeonsi/si_state.c       |  5 +++--
 3 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h 
b/src/gallium/drivers/radeon/r600_pipe_common.h
index 21b09d2..e2c4acc 100644
--- a/src/gallium/drivers/radeon/r600_pipe_common.h
+++ b/src/gallium/drivers/radeon/r600_pipe_common.h
@@ -144,6 +144,7 @@ struct r600_texture {
        unsigned                        color_clear_value[2];
 
        bool                            non_disp_tiling; /* R600-Cayman only */
+       unsigned                        mipmap_shift;
 };
 
 struct r600_tiling_info {
diff --git a/src/gallium/drivers/radeonsi/r600_blit.c 
b/src/gallium/drivers/radeonsi/r600_blit.c
index fef4ccc..483596e 100644
--- a/src/gallium/drivers/radeonsi/r600_blit.c
+++ b/src/gallium/drivers/radeonsi/r600_blit.c
@@ -430,6 +430,21 @@ static void r600_compressed_to_blittable(struct 
pipe_resource *tex,
        rtex->surface.level[0].npix_y = util_format_get_nblocksy(orig->format, 
orig->npix0_y);
        rtex->surface.level[level].npix_x = 
util_format_get_nblocksx(orig->format, orig->npix_x);
        rtex->surface.level[level].npix_y = 
util_format_get_nblocksy(orig->format, orig->npix_y);
+
+       /* By dividing the dimensions by 4, we effectively decrement
+        * last_level by 2, therefore the last 2 mipmap levels disappear and
+        * aren't blittable. Note that the last 3 mipmap levels (4x4, 2x2,
+        * 1x1) have equal slice sizes, which is an important assumption
+        * for this to work.
+        *
+        * In order to make the last 2 mipmap levels blittable, we have to
+        * add the slice size of the last mipmap level to the texture
+        * address, so that even though the hw thinks it reads last_level-2,
+        * it will actually read last_level-1, and if we add the slice size*2,
+        * it will read last_level. That's how this workaround works.
+        */
+       if (level > rtex->resource.b.b.last_level-2)
+               rtex->mipmap_shift = level - (rtex->resource.b.b.last_level-2);
 }
 
 static void r600_change_format(struct pipe_resource *tex,
@@ -463,6 +478,7 @@ static void r600_reset_blittable_to_orig(struct 
pipe_resource *tex,
        rtex->surface.level[0].npix_y = orig->npix0_y;
        rtex->surface.level[level].npix_x = orig->npix_x;
        rtex->surface.level[level].npix_y = orig->npix_y;
+       rtex->mipmap_shift = 0;
 }
 
 static void r600_resource_copy_region(struct pipe_context *ctx,
diff --git a/src/gallium/drivers/radeonsi/si_state.c 
b/src/gallium/drivers/radeonsi/si_state.c
index 9541d0a..1d5f4b7 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -2469,6 +2469,7 @@ static struct pipe_sampler_view 
*si_create_sampler_view(struct pipe_context *ctx
 
        va = r600_resource_va(ctx->screen, texture);
        va += surflevel[0].offset;
+       va += tmp->mipmap_shift * surflevel[texture->last_level].slice_size;
        view->state[0] = va >> 8;
        view->state[1] = (S_008F14_BASE_ADDRESS_HI(va >> 40) |
                          S_008F14_DATA_FORMAT(format) |
@@ -2480,10 +2481,10 @@ static struct pipe_sampler_view 
*si_create_sampler_view(struct pipe_context *ctx
                          S_008F1C_DST_SEL_Z(si_map_swizzle(swizzle[2])) |
                          S_008F1C_DST_SEL_W(si_map_swizzle(swizzle[3])) |
                          S_008F1C_BASE_LEVEL(texture->nr_samples > 1 ?
-                                                     0 : 
state->u.tex.first_level) |
+                                                     0 : 
state->u.tex.first_level - tmp->mipmap_shift) |
                          S_008F1C_LAST_LEVEL(texture->nr_samples > 1 ?
                                                      
util_logbase2(texture->nr_samples) :
-                                                     state->u.tex.last_level) |
+                                                     state->u.tex.last_level - 
tmp->mipmap_shift) |
                          S_008F1C_TILING_INDEX(si_tile_mode_index(tmp, 0, 
false)) |
                          S_008F1C_POW2_PAD(texture->last_level > 0) |
                          S_008F1C_TYPE(si_tex_dim(texture->target, 
texture->nr_samples)));
-- 
1.8.1.2

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to