softpipe: remove the 32bits limitation on depth(-stencil) formats
authorMorgan Armand <morgan.devel@gmail.com>
Wed, 7 Dec 2011 20:30:48 +0000 (21:30 +0100)
committerDave Airlie <airlied@redhat.com>
Tue, 3 Jan 2012 16:19:08 +0000 (16:19 +0000)
This patch remove the 32bits limitation. As a side effect, it bring the support for the GL_ARB_depth_buffer_float extension.
No regression have been found on piglit, and all tests for GL_ARB_depth_buffer_float pass successfully.

Signed-off-by: Dave Airlie <airlied@redhat.com>
src/gallium/auxiliary/util/u_tile.c
src/gallium/drivers/softpipe/sp_clear.c
src/gallium/drivers/softpipe/sp_quad_depth_test.c
src/gallium/drivers/softpipe/sp_screen.c
src/gallium/drivers/softpipe/sp_tile_cache.c
src/gallium/drivers/softpipe/sp_tile_cache.h

index 02bdb731d386c1b7577857a7fa60a476170a0e73..357e896ade78ce35545061835bdbb619c6884e89 100644 (file)
@@ -344,6 +344,31 @@ z32f_x24s8_get_tile_rgba(const float *src,
    }
 }
 
+/*** PIPE_FORMAT_X32_S8X24_UINT ***/
+
+/**
+ * Return S component as four uint32_t in [0..255].  Z part ignored.
+ */
+static void
+x32_s8_get_tile_rgba(const unsigned *src,
+                     unsigned w, unsigned h,
+                     float *p,
+                     unsigned dst_stride)
+{
+   unsigned i, j;
+
+   for (i = 0; i < h; i++) {
+      float *pRow = p;
+      for (j = 0; j < w; j++, pRow += 4) {
+         src++;
+         pRow[0] =
+         pRow[1] =
+         pRow[2] =
+         pRow[3] = (float)(*src++ & 0xff);
+      }
+      p += dst_stride;
+   }
+}
 
 void
 pipe_tile_raw_to_rgba(enum pipe_format format,
@@ -381,6 +406,9 @@ pipe_tile_raw_to_rgba(enum pipe_format format,
    case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
       z32f_x24s8_get_tile_rgba((float *) src, w, h, dst, dst_stride);
       break;
+   case PIPE_FORMAT_X32_S8X24_UINT:
+      x32_s8_get_tile_rgba((float *) src, w, h, dst, dst_stride);
+      break;
    default:
       util_format_read_4f(format,
                           dst, dst_stride * sizeof(float),
index b59524a2214d0add0c4e4cc9a9808661b12fadb7..dd6bd833e61a31aa90f134d8eb97bd31e776a7fd 100644 (file)
@@ -50,7 +50,7 @@ softpipe_clear(struct pipe_context *pipe, unsigned buffers,
                double depth, unsigned stencil)
 {
    struct softpipe_context *softpipe = softpipe_context(pipe);
-   unsigned cv;
+   uint64_t cv;
    uint i;
 
    if (softpipe->no_rast)
@@ -73,7 +73,7 @@ softpipe_clear(struct pipe_context *pipe, unsigned buffers,
       static const union pipe_color_union zero;
       struct pipe_surface *ps = softpipe->framebuffer.zsbuf;
 
-      cv = util_pack_z_stencil(ps->format, depth, stencil);
+      cv = util_pack64_z_stencil(ps->format, depth, stencil);
       sp_tile_cache_clear(softpipe->zsbuf_cache, &zero, cv);
    }
 
index 4cf378e68e45cdd0829ba4e5a6b366e8948941dd..529a5ad5a4eca05bb73c04bd4a16a342aba09998 100644 (file)
@@ -32,6 +32,7 @@
 
 #include "pipe/p_defines.h"
 #include "util/u_format.h"
+#include "util/u_math.h"
 #include "util/u_memory.h"
 #include "tgsi/tgsi_scan.h"
 #include "sp_context.h"
@@ -102,6 +103,21 @@ get_depth_stencil_values( struct depth_data *data,
          data->stencilVals[j] = tile->data.stencil8[y][x];
       }
       break;
+   case PIPE_FORMAT_Z32_FLOAT:
+      for (j = 0; j < QUAD_SIZE; j++) {
+         int x = quad->input.x0 % TILE_SIZE + (j & 1);
+         int y = quad->input.y0 % TILE_SIZE + (j >> 1);
+         data->bzzzz[j] = tile->data.depth32[y][x];
+      }
+      break;
+   case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
+      for (j = 0; j < QUAD_SIZE; j++) {
+         int x = quad->input.x0 % TILE_SIZE + (j & 1);
+         int y = quad->input.y0 % TILE_SIZE + (j >> 1);
+         data->bzzzz[j] = tile->data.depth64[y][x] & 0xffffffff;
+         data->stencilVals[j] = (tile->data.depth64[y][x] >> 32) & 0xff;
+      }
+      break;
    default:
       assert(0);
    }
@@ -182,6 +198,17 @@ convert_quad_depth( struct depth_data *data,
          }
       }
       break;
+   case PIPE_FORMAT_Z32_FLOAT:
+   case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
+      {
+         union fi fui;
+
+         for (j = 0; j < QUAD_SIZE; j++) {
+            fui.f = quad->output.depth[j];
+            data->qzzzz[j] = fui.ui;
+         }
+      }
+      break;
    default:
       assert(0);
    }
@@ -207,6 +234,8 @@ convert_quad_stencil( struct depth_data *data,
    case PIPE_FORMAT_X8Z24_UNORM:
    case PIPE_FORMAT_S8_UINT_Z24_UNORM:
    case PIPE_FORMAT_S8_UINT:
+   case PIPE_FORMAT_Z32_FLOAT:
+   case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
       for (j = 0; j < QUAD_SIZE; j++) {
          data->shader_stencil_refs[j] = ((unsigned)(quad->output.stencil[j]));
       }
@@ -272,7 +301,20 @@ write_depth_stencil_values( struct depth_data *data,
          tile->data.stencil8[y][x] = data->stencilVals[j];
       }
       break;
-
+   case PIPE_FORMAT_Z32_FLOAT:
+      for (j = 0; j < QUAD_SIZE; j++) {
+         int x = quad->input.x0 % TILE_SIZE + (j & 1);
+         int y = quad->input.y0 % TILE_SIZE + (j >> 1);
+         tile->data.depth32[y][x] = data->bzzzz[j];
+      }
+      break;
+   case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
+      for (j = 0; j < QUAD_SIZE; j++) {
+         int x = quad->input.x0 % TILE_SIZE + (j & 1);
+         int y = quad->input.y0 % TILE_SIZE + (j >> 1);
+         tile->data.depth64[y][x] = (uint64_t)data->bzzzz[j] | ((uint64_t)data->stencilVals[j] << 32);
+      }
+      break;
    default:
       assert(0);
    }
index 49e8626b0d4e360d506d1e9c04f34673400b5e15..e58a4867cad8d0dd7eee9f8e056b320f9a7889b1 100644 (file)
@@ -250,19 +250,6 @@ softpipe_is_format_supported( struct pipe_screen *screen,
    if (bind & PIPE_BIND_DEPTH_STENCIL) {
       if (format_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS)
          return FALSE;
-
-      /*
-       * TODO: Unfortunately we cannot render into anything more than 32 bits
-       * because we encode depth and stencil clear values into a 32bit word.
-       */
-      if (format_desc->block.bits > 32)
-         return FALSE;
-
-      /*
-       * TODO: eliminate this restriction
-       */
-      if (format == PIPE_FORMAT_Z32_FLOAT)
-         return FALSE;
    }
 
    /*
index ad6b0156c7ecfdd1ac6ee216275d94c77b56e953..659ac58e5b0f5997b37ead181061ed77e3eb8dd1 100644 (file)
@@ -268,7 +268,7 @@ clear_tile_rgba(struct softpipe_cached_tile *tile,
 static void
 clear_tile(struct softpipe_cached_tile *tile,
            enum pipe_format format,
-           uint clear_value)
+           uint64_t clear_value)
 {
    uint i, j;
 
@@ -295,7 +295,19 @@ clear_tile(struct softpipe_cached_tile *tile,
       else {
          for (i = 0; i < TILE_SIZE; i++) {
             for (j = 0; j < TILE_SIZE; j++) {
-               tile->data.color32[i][j] = clear_value;
+               tile->data.depth32[i][j] = clear_value;
+            }
+         }
+      }
+      break;
+   case 8:
+      if (clear_value == 0) {
+         memset(tile->data.any, 0, 8 * TILE_SIZE * TILE_SIZE);
+      }
+      else {
+         for (i = 0; i < TILE_SIZE; i++) {
+            for (j = 0; j < TILE_SIZE; j++) {
+               tile->data.depth64[i][j] = clear_value;
             }
          }
       }
@@ -601,7 +613,7 @@ sp_find_cached_tile(struct softpipe_tile_cache *tc,
 void
 sp_tile_cache_clear(struct softpipe_tile_cache *tc,
                     const union pipe_color_union *color,
-                    uint clearValue)
+                    uint64_t clearValue)
 {
    uint pos;
 
index 88d527c3e99de8d0248a50c69d9cb2ec6b017c36..775676b4bf5b7f9050363dc14e6129eb46bfc671 100644 (file)
@@ -70,6 +70,7 @@ struct softpipe_cached_tile
       ubyte stencil8[TILE_SIZE][TILE_SIZE];
       uint colorui128[TILE_SIZE][TILE_SIZE][4];
       int colori128[TILE_SIZE][TILE_SIZE][4];
+      uint64_t depth64[TILE_SIZE][TILE_SIZE];
       ubyte any[1];
    } data;
 };
@@ -88,7 +89,7 @@ struct softpipe_tile_cache
    struct softpipe_cached_tile *entries[NUM_ENTRIES];
    uint clear_flags[(MAX_WIDTH / TILE_SIZE) * (MAX_HEIGHT / TILE_SIZE) / 32];
    union pipe_color_union clear_color; /**< for color bufs */
-   uint clear_val;        /**< for z+stencil */
+   uint64_t clear_val;        /**< for z+stencil */
    boolean depth_stencil; /**< Is the surface a depth/stencil format? */
 
    struct softpipe_cached_tile *tile;  /**< scratch tile for clears */
@@ -123,7 +124,7 @@ sp_flush_tile_cache(struct softpipe_tile_cache *tc);
 extern void
 sp_tile_cache_clear(struct softpipe_tile_cache *tc,
                     const union pipe_color_union *color,
-                    uint clearValue);
+                    uint64_t clearValue);
 
 extern struct softpipe_cached_tile *
 sp_find_cached_tile(struct softpipe_tile_cache *tc,