Mesa (master): softpipe: don' t assert when creating surfaces with multiple layers

Roland Scheidegger sroland at kemper.freedesktop.org
Wed Mar 13 23:23:19 UTC 2013


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

Author: Roland Scheidegger <sroland at vmware.com>
Date:   Wed Mar 13 21:19:20 2013 +0100

softpipe: don't assert when creating surfaces with multiple layers

We can't handle them yet, however we can safely just warn (we will
just render to first layer, which is fine since we can't handle
rendertarget system value neither).
Also make behavior more predictable with buffer surfaces
(it would sometimes hit bogus asserts because of the union in the surface,
instead create the surface but assert when trying to set a buffer
in the framebuffer).

Reviewed-by: Jose Fonseca <jfonseca at vmware.com>

---

 src/gallium/drivers/softpipe/sp_texture.c    |   30 +++++++++++++++++--------
 src/gallium/drivers/softpipe/sp_tile_cache.c |   18 ++++++++++-----
 2 files changed, 32 insertions(+), 16 deletions(-)

diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c
index 0d1481a..2db0de8 100644
--- a/src/gallium/drivers/softpipe/sp_texture.c
+++ b/src/gallium/drivers/softpipe/sp_texture.c
@@ -283,10 +283,6 @@ softpipe_create_surface(struct pipe_context *pipe,
                         const struct pipe_surface *surf_tmpl)
 {
    struct pipe_surface *ps;
-   unsigned level = surf_tmpl->u.tex.level;
-
-   assert(level <= pt->last_level);
-   assert(surf_tmpl->u.tex.first_layer == surf_tmpl->u.tex.last_layer);
 
    ps = CALLOC_STRUCT(pipe_surface);
    if (ps) {
@@ -294,12 +290,26 @@ softpipe_create_surface(struct pipe_context *pipe,
       pipe_resource_reference(&ps->texture, pt);
       ps->context = pipe;
       ps->format = surf_tmpl->format;
-      ps->width = u_minify(pt->width0, level);
-      ps->height = u_minify(pt->height0, level);
-
-      ps->u.tex.level = level;
-      ps->u.tex.first_layer = surf_tmpl->u.tex.first_layer;
-      ps->u.tex.last_layer = surf_tmpl->u.tex.last_layer;
+      if (pt->target != PIPE_BUFFER) {
+         assert(surf_tmpl->u.tex.level <= pt->last_level);
+         ps->width = u_minify(pt->width0, surf_tmpl->u.tex.level);
+         ps->height = u_minify(pt->height0, surf_tmpl->u.tex.level);
+         ps->u.tex.level = surf_tmpl->u.tex.level;
+         ps->u.tex.first_layer = surf_tmpl->u.tex.first_layer;
+         ps->u.tex.last_layer = surf_tmpl->u.tex.last_layer;
+         if (ps->u.tex.first_layer != ps->u.tex.last_layer) {
+            debug_printf("creating surface with multiple layers, rendering to first layer only\n");
+         }
+      }
+      else {
+         /* setting width as number of elements should get us correct renderbuffer width */
+         ps->width = surf_tmpl->u.buf.last_element - surf_tmpl->u.buf.first_element + 1;
+         ps->height = pt->height0;
+         ps->u.buf.first_element = surf_tmpl->u.buf.first_element;
+         ps->u.buf.last_element = surf_tmpl->u.buf.last_element;
+         assert(ps->u.buf.first_element <= ps->u.buf.last_element);
+         assert(ps->u.buf.last_element < ps->width);
+      }
    }
    return ps;
 }
diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c
index dded0e1..b6dd6af 100644
--- a/src/gallium/drivers/softpipe/sp_tile_cache.c
+++ b/src/gallium/drivers/softpipe/sp_tile_cache.c
@@ -170,12 +170,18 @@ sp_tile_cache_set_surface(struct softpipe_tile_cache *tc,
    tc->surface = ps;
 
    if (ps) {
-      tc->transfer_map = pipe_transfer_map(pipe, ps->texture,
-                                           ps->u.tex.level, ps->u.tex.first_layer,
-                                           PIPE_TRANSFER_READ_WRITE |
-                                           PIPE_TRANSFER_UNSYNCHRONIZED,
-                                           0, 0, ps->width, ps->height,
-                                           &tc->transfer);
+      if (ps->texture->target != PIPE_BUFFER) {
+         tc->transfer_map = pipe_transfer_map(pipe, ps->texture,
+                                              ps->u.tex.level, ps->u.tex.first_layer,
+                                              PIPE_TRANSFER_READ_WRITE |
+                                              PIPE_TRANSFER_UNSYNCHRONIZED,
+                                              0, 0, ps->width, ps->height,
+                                              &tc->transfer);
+      }
+      else {
+         /* can't render to buffers */
+         assert(0);
+      }
 
       tc->depth_stencil = util_format_is_depth_or_stencil(ps->format);
    }




More information about the mesa-commit mailing list