[Mesa-dev] [PATCH] llvmpipe: fix bogus handling of first_layer when setting up texture sampling

sroland at vmware.com sroland at vmware.com
Thu May 16 19:04:03 PDT 2013


From: Roland Scheidegger <sroland at vmware.com>

The code avoided first_layer parameter in the sampler interface (and needing
to do another calculation at runtime) by fixing up the base texture pointer
instead. Unfortunately, this didn't actually work as we have mip-first
texture layout so fixing up the base ptr by a fixed amount is very wrong if
there are mipmaps present. The wrong offsets caused misrendering and crashes.
Fix this by just adjusting the individual mip level offsets instead.
Spotted by Jose.
---
 src/gallium/drivers/llvmpipe/lp_setup.c         |   23 ++++++++++++++---------
 src/gallium/drivers/llvmpipe/lp_state_sampler.c |    6 ++++--
 2 files changed, 18 insertions(+), 11 deletions(-)

diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c
index b5b00d1..ce9be92 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup.c
@@ -748,23 +748,28 @@ lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup,
                      jit_tex->img_stride[j] = lp_tex->img_stride[j];
                   }
 
-                  /*
-                   * We don't use anything like first_element (for buffers) or
-                   * first_layer (for arrays), instead adjust the last_element
-                   * (width) or last_layer (depth) plus the base pointer.
-                   * Less parameters and faster at shader execution.
-                   * XXX Could do the same for mip levels.
-                   */
                   if (res->target == PIPE_TEXTURE_1D_ARRAY ||
                       res->target == PIPE_TEXTURE_2D_ARRAY) {
+                     /*
+                      * For arrays, we don't have first_layer, instead adjust
+                      * last_layer (depth) plus the mip level offsets
+                      * (as we have mip-first layout can't just adjust base ptr).
+                      * XXX For mip levels, could do something similar.
+                      */
                      jit_tex->depth = view->u.tex.last_layer - view->u.tex.first_layer + 1;
-                     jit_tex->base = (uint8_t *)jit_tex->base +
-                                     view->u.tex.first_layer * lp_tex->img_stride[0];
+                     for (j = first_level; j <= last_level; j++) {
+                        jit_tex->mip_offsets[j] += view->u.tex.first_layer *
+                                                   lp_tex->img_stride[j];
+                     }
                      assert(view->u.tex.first_layer <= view->u.tex.last_layer);
                      assert(view->u.tex.last_layer < res->array_size);
                   }
                }
                else {
+                  /*
+                   * For buffers, we don't have first_element, instead adjust
+                   * last_element (width) plus the base pointer.
+                   */
                   unsigned view_blocksize = util_format_get_blocksize(view->format);
                   /* probably don't really need to fill that out */
                   jit_tex->mip_offsets[0] = 0;
diff --git a/src/gallium/drivers/llvmpipe/lp_state_sampler.c b/src/gallium/drivers/llvmpipe/lp_state_sampler.c
index 6498d13..6b7e327 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_sampler.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_sampler.c
@@ -320,8 +320,10 @@ prepare_shader_sampling(
                if (res->target == PIPE_TEXTURE_1D_ARRAY ||
                    res->target == PIPE_TEXTURE_2D_ARRAY) {
                   num_layers = view->u.tex.last_layer - view->u.tex.first_layer + 1;
-                  addr = (uint8_t *)addr +
-                                  view->u.tex.first_layer * lp_tex->img_stride[0];
+                  for (j = first_level; j <= last_level; j++) {
+                     mip_offsets[j] += view->u.tex.first_layer *
+                                       lp_tex->img_stride[j];
+                  }
                   assert(view->u.tex.first_layer <= view->u.tex.last_layer);
                   assert(view->u.tex.last_layer < res->array_size);
                }
-- 
1.7.9.5


More information about the mesa-dev mailing list