Mesa (master): vc4: Mostly fix offset calculation for NPOT mipmap levels.

Eric Anholt anholt at kemper.freedesktop.org
Thu Oct 9 09:05:57 UTC 2014


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

Author: Eric Anholt <eric at anholt.net>
Date:   Mon Oct  6 15:47:38 2014 -0700

vc4: Mostly fix offset calculation for NPOT mipmap levels.

The non-base NPOT levels are stored as POT-aligned images.  We get that
POT alignment by minifying the POT-aligned base level.

This means that level strides are also POT aligned, so we have to tell the
rendering mode config that our resource is larger than the actual
requested area.

Fixes the fbo-generatemipmap-formats NPOT cases.  Regresses
depthstencil-render-miplevels 273 * -- the texture presentation now works
(where it was completely broken before), it looks like there's some
overflow of image bounds happening at the lower miplevels.

---

 src/gallium/drivers/vc4/vc4_resource.c |   13 +++++++++++--
 src/gallium/drivers/vc4/vc4_state.c    |   13 ++++++++++++-
 2 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/src/gallium/drivers/vc4/vc4_resource.c b/src/gallium/drivers/vc4/vc4_resource.c
index 239443e..7006af3 100644
--- a/src/gallium/drivers/vc4/vc4_resource.c
+++ b/src/gallium/drivers/vc4/vc4_resource.c
@@ -198,14 +198,23 @@ vc4_setup_slices(struct vc4_resource *rsc)
         struct pipe_resource *prsc = &rsc->base.b;
         uint32_t width = prsc->width0;
         uint32_t height = prsc->height0;
+        uint32_t pot_width = util_next_power_of_two(width);
+        uint32_t pot_height = util_next_power_of_two(height);
         uint32_t offset = 0;
         uint32_t utile_w = vc4_utile_width(rsc->cpp);
         uint32_t utile_h = vc4_utile_height(rsc->cpp);
 
         for (int i = prsc->last_level; i >= 0; i--) {
                 struct vc4_resource_slice *slice = &rsc->slices[i];
-                uint32_t level_width = u_minify(width, i);
-                uint32_t level_height = u_minify(height, i);
+
+                uint32_t level_width, level_height;
+                if (i == 0) {
+                        level_width = width;
+                        level_height = height;
+                } else {
+                        level_width = u_minify(pot_width, i);
+                        level_height = u_minify(pot_height, i);
+                }
 
                 if (rsc->tiled == VC4_TILING_FORMAT_LINEAR) {
                         slice->tiling = VC4_TILING_FORMAT_LINEAR;
diff --git a/src/gallium/drivers/vc4/vc4_state.c b/src/gallium/drivers/vc4/vc4_state.c
index 5f5eee8..2a123eb 100644
--- a/src/gallium/drivers/vc4/vc4_state.c
+++ b/src/gallium/drivers/vc4/vc4_state.c
@@ -389,10 +389,21 @@ vc4_set_framebuffer_state(struct pipe_context *pctx,
 
         cso->nr_cbufs = framebuffer->nr_cbufs;
 
+        pipe_surface_reference(&cso->zsbuf, framebuffer->zsbuf);
+
         cso->width = framebuffer->width;
         cso->height = framebuffer->height;
 
-        pipe_surface_reference(&cso->zsbuf, framebuffer->zsbuf);
+        /* Nonzero texture mipmap levels are laid out as if they were in
+         * power-of-two-sized spaces.  The renderbuffer config infers its
+         * stride from the width parameter, so we need to configure our
+         * framebuffer.  Note that if the z/color buffers were mismatched
+         * sizes, we wouldn't be able to do this.
+         */
+        if ((cso->cbufs[0] && cso->cbufs[0]->u.tex.level) ||
+             (cso->zsbuf && cso->zsbuf->u.tex.level)) {
+                cso->width = util_next_power_of_two(cso->width);
+        }
 
         vc4->dirty |= VC4_DIRTY_FRAMEBUFFER;
 }




More information about the mesa-commit mailing list