Module: Mesa
Branch: 10.5
Commit: 61fc1295af5bbde3abe755fb263c1827c58688ae
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=61fc1295af5bbde3abe755fb263c1827c58688ae

Author: Ilia Mirkin <[email protected]>
Date:   Sun Mar 15 16:38:42 2015 -0400

freedreno/a3xx: fix 3d texture layout

The SZ2 field contains the layer size of a lower miplevel. It only
contains 4 bits, which limits the maximum layer size it can describe. In
situations where the next miplevel would be too big, the hardware
appears to keep minifying the size until it hits one of that size.
Unfortunately the hardware's ideas about sizes can differ from
freedreno's which can still lead to issues. Minimize those by stopping
to minify as soon as possible.

Signed-off-by: Ilia Mirkin <[email protected]>
Cc: "10.4 10.5" <[email protected]>
(cherry picked from commit 738c8319ac85b175994b35d1fdc4860e18184b93)

---

 src/gallium/drivers/freedreno/a3xx/fd3_texture.c   |    7 +++++--
 src/gallium/drivers/freedreno/freedreno_resource.c |   16 +++++++++++-----
 2 files changed, 16 insertions(+), 7 deletions(-)

diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_texture.c 
b/src/gallium/drivers/freedreno/a3xx/fd3_texture.c
index 567f6c7..59b3a93 100644
--- a/src/gallium/drivers/freedreno/a3xx/fd3_texture.c
+++ b/src/gallium/drivers/freedreno/a3xx/fd3_texture.c
@@ -212,6 +212,7 @@ fd3_sampler_view_create(struct pipe_context *pctx, struct 
pipe_resource *prsc,
        struct fd_resource *rsc = fd_resource(prsc);
        unsigned lvl = cso->u.tex.first_level;
        unsigned miplevels = cso->u.tex.last_level - lvl;
+       uint32_t sz2 = 0;
 
        if (!so)
                return NULL;
@@ -252,8 +253,10 @@ fd3_sampler_view_create(struct pipe_context *pctx, struct 
pipe_resource *prsc,
        case PIPE_TEXTURE_3D:
                so->texconst3 =
                                A3XX_TEX_CONST_3_DEPTH(u_minify(prsc->depth0, 
lvl)) |
-                               A3XX_TEX_CONST_3_LAYERSZ1(rsc->slices[0].size0) 
|
-                               A3XX_TEX_CONST_3_LAYERSZ2(rsc->slices[0].size0);
+                               
A3XX_TEX_CONST_3_LAYERSZ1(rsc->slices[lvl].size0);
+               while (lvl < cso->u.tex.last_level && sz2 != 
rsc->slices[lvl+1].size0)
+                       sz2 = rsc->slices[++lvl].size0;
+               so->texconst3 |= A3XX_TEX_CONST_3_LAYERSZ2(sz2);
                break;
        default:
                so->texconst3 = 0x00000000;
diff --git a/src/gallium/drivers/freedreno/freedreno_resource.c 
b/src/gallium/drivers/freedreno/freedreno_resource.c
index 69e5452..efafb89 100644
--- a/src/gallium/drivers/freedreno/freedreno_resource.c
+++ b/src/gallium/drivers/freedreno/freedreno_resource.c
@@ -215,14 +215,20 @@ setup_slices(struct fd_resource *rsc, uint32_t alignment)
 
                slice->pitch = width = align(width, 32);
                slice->offset = size;
-               /* 1d array, 2d array, 3d textures (but not cube!) must all 
have the
-                * same layer size for each miplevel on a3xx. These are also the
-                * targets that have non-1 alignment.
+               /* 1d array and 2d array textures must all have the same layer 
size
+                * for each miplevel on a3xx. 3d textures can have different 
layer
+                * sizes for high levels, but the hw auto-sizer is buggy (or at 
least
+                * different than what this code does), so as soon as the layer 
size
+                * range gets into range, we stop reducing it.
                 */
-               if (level == 0 || layers_in_level == 1 || alignment == 1)
+               if (prsc->target == PIPE_TEXTURE_3D && (
+                                       level == 1 ||
+                                       (level > 1 && rsc->slices[level - 
1].size0 > 0xf000)))
+                       slice->size0 = align(slice->pitch * height * rsc->cpp, 
alignment);
+               else if (level == 0 || rsc->layer_first || alignment == 1)
                        slice->size0 = align(slice->pitch * height * rsc->cpp, 
alignment);
                else
-                       slice->size0 = rsc->slices[0].size0;
+                       slice->size0 = rsc->slices[level - 1].size0;
 
                size += slice->size0 * depth * layers_in_level;
 

_______________________________________________
mesa-commit mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/mesa-commit

Reply via email to