softpipe: don't assert when creating surfaces with multiple layers
authorRoland Scheidegger <sroland@vmware.com>
Wed, 13 Mar 2013 20:19:20 +0000 (21:19 +0100)
committerRoland Scheidegger <sroland@vmware.com>
Wed, 13 Mar 2013 23:21:56 +0000 (00:21 +0100)
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@vmware.com>
src/gallium/drivers/softpipe/sp_texture.c
src/gallium/drivers/softpipe/sp_tile_cache.c

index 0d1481af23fd6def13ef56eb8b19d9123239d43c..2db0de875033f9484294d3050901c4ac4d826ac3 100644 (file)
@@ -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;
 }
index dded0e17342ba4f046e0161f9975ddb66af74f77..b6dd6af48afad12e2f22e8969abfb608e690601e 100644 (file)
@@ -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);
    }