Module: Mesa
Branch: master
Commit: 5bd0e0adb1790cbc36e66c1c37a6a4338a851750
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=5bd0e0adb1790cbc36e66c1c37a6a4338a851750

Author: Luca Barbieri <l...@luca-barbieri.com>
Date:   Sat Sep  4 17:12:02 2010 +0200

nvfx: fix swizzling of high bpp surfaces

---

 src/gallium/drivers/nvfx/nv04_2d.h      |   20 ++++++++
 src/gallium/drivers/nvfx/nvfx_surface.c |   82 ++++++++++++++++---------------
 2 files changed, 63 insertions(+), 39 deletions(-)

diff --git a/src/gallium/drivers/nvfx/nv04_2d.h 
b/src/gallium/drivers/nvfx/nv04_2d.h
index e638b8c..e7d872a 100644
--- a/src/gallium/drivers/nvfx/nv04_2d.h
+++ b/src/gallium/drivers/nvfx/nv04_2d.h
@@ -47,6 +47,26 @@ struct nv04_region {
        unsigned w, h, d;
 };
 
+static inline void
+nv04_region_try_to_linearize(struct nv04_region* rgn)
+{
+       assert(!rgn->pitch);
+
+       if(rgn->d <= 1)
+       {
+               if(rgn->h <= 1 || rgn->w <= 2)
+                       rgn->pitch = rgn->w << rgn->bpps;
+       }
+       else
+       {
+               if(rgn->h <= 2 && rgn->w <= 2)
+               {
+                       rgn->pitch = rgn->w << rgn->bpps;
+                       rgn->offset += rgn->z * rgn->h * rgn->pitch;
+               }
+       }
+}
+
 void
 nv04_memcpy(struct nv04_2d_context *ctx,
                struct nouveau_bo* dstbo, int dstoff,
diff --git a/src/gallium/drivers/nvfx/nvfx_surface.c 
b/src/gallium/drivers/nvfx/nvfx_surface.c
index 34fd4c4..0255e3f 100644
--- a/src/gallium/drivers/nvfx/nvfx_surface.c
+++ b/src/gallium/drivers/nvfx/nvfx_surface.c
@@ -47,6 +47,7 @@ static INLINE void
 nvfx_region_set_format(struct nv04_region* rgn, enum pipe_format format)
 {
        unsigned bits = util_format_get_blocksizebits(format);
+       unsigned shift = 0;
        switch(bits)
        {
        case 8:
@@ -58,39 +59,20 @@ nvfx_region_set_format(struct nv04_region* rgn, enum 
pipe_format format)
        case 32:
                rgn->bpps = 2;
                break;
-       default:
-               {
-                       int shift;
-                       assert(util_is_power_of_two(bits));
-                       shift = util_logbase2(bits) - 3;
-                       assert(shift >= 2);
-                       rgn->bpps = 2;
-                       shift -= 2;
-
-                       rgn->x = util_format_get_nblocksx(format, rgn->x) << 
shift;
-                       rgn->y = util_format_get_nblocksy(format, rgn->y);
-               }
+       case 64:
+               rgn->bpps = 2;
+               shift = 1;
+               break;
+       case 128:
+               rgn->bpps = 2;
+               shift = 2;
+               break;
        }
-}
 
-static INLINE void
-nvfx_region_fixup_swizzled(struct nv04_region* rgn, unsigned zslice, unsigned 
width, unsigned height, unsigned depth)
-{
-       // TODO: move this code to surface creation?
-       if((depth <= 1) && (height <= 1 || width <= 2))
-               rgn->pitch = width << rgn->bpps;
-       else if(depth > 1 && height <= 2 && width <= 2)
-       {
-               rgn->pitch = width << rgn->bpps;
-               rgn->offset += (zslice * width * height) << rgn->bpps;
-       }
-       else
-       {
-               rgn->pitch = 0;
-               rgn->z = zslice;
-               rgn->w = width;
-               rgn->h = height;
-               rgn->d = depth;
+       if(shift) {
+               rgn->x = util_format_get_nblocksx(format, rgn->x) << shift;
+               rgn->y = util_format_get_nblocksy(format, rgn->y);
+               rgn->w <<= shift;
        }
 }
 
@@ -100,7 +82,6 @@ nvfx_region_init_for_surface(struct nv04_region* rgn, struct 
nvfx_surface* surf,
        rgn->x = x;
        rgn->y = y;
        rgn->z = 0;
-       nvfx_region_set_format(rgn, surf->base.base.format);
 
        if(surf->temp)
        {
@@ -113,11 +94,22 @@ nvfx_region_init_for_surface(struct nv04_region* rgn, 
struct nvfx_surface* surf,
        } else {
                rgn->bo = ((struct nvfx_resource*)surf->base.base.texture)->bo;
                rgn->offset = surf->base.base.offset;
-               rgn->pitch = surf->pitch;
 
-               if(!(surf->base.base.texture->flags & 
NVFX_RESOURCE_FLAG_LINEAR))
-                       nvfx_region_fixup_swizzled(rgn, surf->base.base.zslice, 
surf->base.base.width, surf->base.base.height, 
u_minify(surf->base.base.texture->depth0, surf->base.base.level));
+               if(surf->base.base.texture->flags & NVFX_RESOURCE_FLAG_LINEAR)
+                       rgn->pitch = surf->pitch;
+               else
+               {
+                       rgn->pitch = 0;
+                       rgn->z = surf->base.base.zslice;
+                       rgn->w = surf->base.base.width;
+                       rgn->h = surf->base.base.height;
+                       rgn->d = u_minify(surf->base.base.texture->depth0, 
surf->base.base.level);
+               }
        }
+
+       nvfx_region_set_format(rgn, surf->base.base.format);
+       if(!rgn->pitch)
+               nv04_region_try_to_linearize(rgn);
 }
 
 static INLINE void
@@ -135,14 +127,26 @@ nvfx_region_init_for_subresource(struct nv04_region* rgn, 
struct pipe_resource*
 
        rgn->bo = ((struct nvfx_resource*)pt)->bo;
        rgn->offset = nvfx_subresource_offset(pt, sub.face, sub.level, z);
-       rgn->pitch = nvfx_subresource_pitch(pt, sub.level);
        rgn->x = x;
        rgn->y = y;
-       rgn->z = 0;
+
+       if(pt->flags & NVFX_RESOURCE_FLAG_LINEAR)
+       {
+               rgn->pitch = nvfx_subresource_pitch(pt, sub.level);
+               rgn->z = 0;
+       }
+       else
+       {
+               rgn->pitch = 0;
+               rgn->z = z;
+               rgn->w = u_minify(pt->width0, sub.level);
+               rgn->h = u_minify(pt->height0, sub.level);
+               rgn->d = u_minify(pt->depth0, sub.level);
+       }
 
        nvfx_region_set_format(rgn, pt->format);
-       if(!(pt->flags & NVFX_RESOURCE_FLAG_LINEAR))
-               nvfx_region_fixup_swizzled(rgn, z, u_minify(pt->width0, 
sub.level), u_minify(pt->height0, sub.level), u_minify(pt->depth0, sub.level));
+       if(!rgn->pitch)
+               nv04_region_try_to_linearize(rgn);
 }
 
 // TODO: actually test this for all formats, it's probably wrong for some...

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

Reply via email to