16-bit RGBA surface format for accum buffers
authorBrian <brian.paul@tungstengraphics.com>
Sun, 14 Oct 2007 17:53:15 +0000 (11:53 -0600)
committerBrian <brian.paul@tungstengraphics.com>
Sun, 14 Oct 2007 17:53:15 +0000 (11:53 -0600)
src/mesa/pipe/softpipe/sp_region.c
src/mesa/pipe/softpipe/sp_surface.c

index faf2737..982e081 100644 (file)
@@ -212,9 +212,7 @@ sp_region_copy(struct pipe_context *pipe,
    pipe->region_unmap(pipe, dst);
 }
 
-/* Fill a rectangular sub-region.  Need better logic about when to
- * push buffers into AGP - will currently do so whenever possible.
- */
+
 static ubyte *
 get_pointer(struct pipe_region *dst, unsigned x, unsigned y)
 {
@@ -222,6 +220,13 @@ get_pointer(struct pipe_region *dst, unsigned x, unsigned y)
 }
 
 
+#define UBYTE_TO_USHORT(B) ((B) | ((B) << 8))
+
+
+/**
+ * Fill a rectangular sub-region.  Need better logic about when to
+ * push buffers into AGP - will currently do so whenever possible.
+ */
 static void
 sp_region_fill(struct pipe_context *pipe,
                struct pipe_region *dst,
@@ -237,32 +242,54 @@ sp_region_fill(struct pipe_context *pipe,
    (void)pipe->region_map(pipe, dst);
 
    switch (dst->cpp) {
-   case 1: {
-      ubyte *row = get_pointer(dst, dstx, dsty);
-      for (i = 0; i < height; i++) {
-        memset(row, value, width);
+   case 1:
+      {
+         ubyte *row = get_pointer(dst, dstx, dsty);
+         for (i = 0; i < height; i++) {
+            memset(row, value, width);
         row += dst->pitch;
+         }
       }
-   }
-   break;
-   case 2: {
-      ushort *row = (ushort *) get_pointer(dst, dstx, dsty);
-      for (i = 0; i < height; i++) {
-        for (j = 0; j < width; j++)
-           row[j] = value;
-        row += dst->pitch;
+      break;
+   case 2:
+      {
+         ushort *row = (ushort *) get_pointer(dst, dstx, dsty);
+         for (i = 0; i < height; i++) {
+            for (j = 0; j < width; j++)
+               row[j] = value;
+            row += dst->pitch;
+         }
       }
-   }
-   break;
-   case 4: {
-      unsigned *row = (unsigned *) get_pointer(dst, dstx, dsty);
-      for (i = 0; i < height; i++) {
-        for (j = 0; j < width; j++)
-           row[j] = value;
-        row += dst->pitch;
+      break;
+   case 4:
+      {
+         unsigned *row = (unsigned *) get_pointer(dst, dstx, dsty);
+         for (i = 0; i < height; i++) {
+            for (j = 0; j < width; j++)
+               row[j] = value;
+            row += dst->pitch;
+         }
       }
-   }
-   break;
+      break;
+   case 8:
+      {
+         /* expand the 4-byte clear value to an 8-byte value */
+         ushort *row = (ushort *) get_pointer(dst, dstx, dsty);
+         ushort val0 = UBYTE_TO_USHORT((value >>  0) & 0xff);
+         ushort val1 = UBYTE_TO_USHORT((value >>  8) & 0xff);
+         ushort val2 = UBYTE_TO_USHORT((value >> 16) & 0xff);
+         ushort val3 = UBYTE_TO_USHORT((value >> 24) & 0xff);
+         for (i = 0; i < height; i++) {
+            for (j = 0; j < width; j++) {
+               row[j*4+0] = val0;
+               row[j*4+1] = val1;
+               row[j*4+2] = val2;
+               row[j*4+3] = val3;
+            }
+            row += dst->pitch * 4;
+         }
+      }
+      break;
    default:
       assert(0);
       break;
index 07def21..02a072f 100755 (executable)
  */
 
 
+/** Convert GLshort in [-32768,32767] to GLfloat in [-1.0,1.0] */
+#define SHORT_TO_FLOAT(S)   ((2.0F * (S) + 1.0F) * (1.0F/65535.0F))
+
+#define UNCLAMPED_FLOAT_TO_SHORT(us, f)  \
+   us = ( (short) ( CLAMP((f), 0.0, 1.0) * 32767.0F) )
+
+
+
+#if 0
+#define CLIP_TILE \
+   do { \
+      assert(x + w <= ps->width);               \
+      assert(y + h <= ps->height);              \
+   } while(0)
+
+#else
+#define CLIP_TILE \
+   do { \
+      if (x + w > ps->width) \
+         w = ps->width - x; \
+      if (y + h > ps->height) \
+         h = ps->height -y; \
+   } while(0)
+#endif
+
 
 /*** PIPE_FORMAT_U_A8_R8_G8_B8 ***/
 
@@ -108,16 +133,8 @@ a8r8g8b8_get_tile(struct pipe_surface *ps,
 
    assert(ps->format == PIPE_FORMAT_U_A8_R8_G8_B8);
 
-#if 0
-   assert(x + w <= ps->width);
-   assert(y + h <= ps->height);
-#else
-   /* temp clipping hack */
-   if (x + w > ps->width)
-      w = ps->width - x;
-   if (y + h > ps->height)
-      h = ps->height -y;
-#endif
+   CLIP_TILE;
+
    for (i = 0; i < h; i++) {
       float *pRow = p;
       for (j = 0; j < w; j++) {
@@ -147,16 +164,8 @@ a8r8g8b8_put_tile(struct pipe_surface *ps,
 
    assert(ps->format == PIPE_FORMAT_U_A8_R8_G8_B8);
 
-#if 0
-   assert(x + w <= ps->width);
-   assert(y + h <= ps->height);
-#else
-   /* temp clipping hack */
-   if (x + w > ps->width)
-      w = ps->width - x;
-   if (y + h > ps->height)
-      h = ps->height -y;
-#endif
+   CLIP_TILE;
+
    for (i = 0; i < h; i++) {
       const float *pRow = p;
       for (j = 0; j < w; j++) {
@@ -256,16 +265,8 @@ z16_get_tile(struct pipe_surface *ps,
 
    assert(ps->format == PIPE_FORMAT_U_Z16);
 
-#if 0
-   assert(x + w <= ps->width);
-   assert(y + h <= ps->height);
-#else
-   /* temp clipping hack */
-   if (x + w > ps->width)
-      w = ps->width - x;
-   if (y + h > ps->height)
-      h = ps->height -y;
-#endif
+   CLIP_TILE;
+
    for (i = 0; i < h; i++) {
       float *pRow = p;
       for (j = 0; j < w; j++) {
@@ -338,16 +339,8 @@ l8_get_tile(struct pipe_surface *ps,
 
    assert(ps->format == PIPE_FORMAT_U_L8);
 
-#if 0
-   assert(x + w <= ps->width);
-   assert(y + h <= ps->height);
-#else
-   /* temp clipping hack */
-   if (x + w > ps->width)
-      w = ps->width - x;
-   if (y + h > ps->height)
-      h = ps->height -y;
-#endif
+   CLIP_TILE;
+
    for (i = 0; i < h; i++) {
       float *pRow = p;
       for (j = 0; j < w; j++) {
@@ -422,16 +415,8 @@ a8_get_tile(struct pipe_surface *ps,
 
    assert(ps->format == PIPE_FORMAT_U_A8);
 
-#if 0
-   assert(x + w <= ps->width);
-   assert(y + h <= ps->height);
-#else
-   /* temp clipping hack */
-   if (x + w > ps->width)
-      w = ps->width - x;
-   if (y + h > ps->height)
-      h = ps->height -y;
-#endif
+   CLIP_TILE;
+
    for (i = 0; i < h; i++) {
       float *pRow = p;
       for (j = 0; j < w; j++) {
@@ -447,6 +432,74 @@ a8_get_tile(struct pipe_surface *ps,
 }
 
 
+/*** PIPE_FORMAT_S_R16_G16_B16_A16 ***/
+
+static void
+r16g16b16a16_get_tile(struct pipe_surface *ps,
+                      unsigned x, unsigned y, unsigned w, unsigned h, float *p)
+{
+   const short *src
+      = ((const short *) (ps->region->map + ps->offset))
+      + (y * ps->region->pitch + x) * 4;
+   unsigned i, j;
+   unsigned w0 = w;
+
+   assert(ps->format == PIPE_FORMAT_S_R16_G16_B16_A16);
+
+   CLIP_TILE;
+
+   for (i = 0; i < h; i++) {
+      float *pRow = p;
+      const short *pixel = src;
+      for (j = 0; j < w; j++) {
+         pRow[0] = SHORT_TO_FLOAT(pixel[0]);
+         pRow[1] = SHORT_TO_FLOAT(pixel[1]);
+         pRow[2] = SHORT_TO_FLOAT(pixel[2]);
+         pRow[3] = SHORT_TO_FLOAT(pixel[3]);
+         pRow += 4;
+         pixel += 4;
+      }
+      src += ps->region->pitch * 4;
+      p += w0 * 4;
+   }
+}
+
+
+static void
+r16g16b16a16_put_tile(struct pipe_surface *ps,
+                      unsigned x, unsigned y, unsigned w, unsigned h,
+                      const float *p)
+{
+   short *dst
+      = ((short *) (ps->region->map + ps->offset))
+      + (y * ps->region->pitch + x) * 4;
+   unsigned i, j;
+   unsigned w0 = w;
+
+   assert(ps->format == PIPE_FORMAT_S_R16_G16_B16_A16);
+
+   CLIP_TILE;
+
+   for (i = 0; i < h; i++) {
+      const float *pRow = p;
+      for (j = 0; j < w; j++) {
+         short r, g, b, a;
+         UNCLAMPED_FLOAT_TO_SHORT(r, pRow[0]);
+         UNCLAMPED_FLOAT_TO_SHORT(g, pRow[1]);
+         UNCLAMPED_FLOAT_TO_SHORT(b, pRow[2]);
+         UNCLAMPED_FLOAT_TO_SHORT(a, pRow[3]);
+         dst[j*4+0] = r;
+         dst[j*4+1] = g;
+         dst[j*4+2] = b;
+         dst[j*4+3] = a;
+         pRow += 4;
+      }
+      dst += ps->region->pitch * 4;
+      p += w0 * 4;
+   }
+}
+
+
 
 /*** PIPE_FORMAT_U_I8 ***/
 
@@ -507,16 +560,8 @@ i8_get_tile(struct pipe_surface *ps,
 
    assert(ps->format == PIPE_FORMAT_U_I8);
 
-#if 0
-   assert(x + w <= ps->width);
-   assert(y + h <= ps->height);
-#else
-   /* temp clipping hack */
-   if (x + w > ps->width)
-      w = ps->width - x;
-   if (y + h > ps->height)
-      h = ps->height -y;
-#endif
+   CLIP_TILE;
+
    for (i = 0; i < h; i++) {
       float *pRow = p;
       for (j = 0; j < w; j++) {
@@ -593,16 +638,8 @@ a8_l8_get_tile(struct pipe_surface *ps,
 
    assert(ps->format == PIPE_FORMAT_U_A8_L8);
 
-#if 0
-   assert(x + w <= ps->width);
-   assert(y + h <= ps->height);
-#else
-   /* temp clipping hack */
-   if (x + w > ps->width)
-      w = ps->width - x;
-   if (y + h > ps->height)
-      h = ps->height -y;
-#endif
+   CLIP_TILE;
+
    for (i = 0; i < h; i++) {
       float *pRow = p;
       for (j = 0; j < w; j++) {
@@ -673,16 +710,8 @@ z32_get_tile(struct pipe_surface *ps,
 
    assert(ps->format == PIPE_FORMAT_U_Z16);
 
-#if 0
-   assert(x + w <= ps->width);
-   assert(y + h <= ps->height);
-#else
-   /* temp clipping hack */
-   if (x + w > ps->width)
-      w = ps->width - x;
-   if (y + h > ps->height)
-      h = ps->height -y;
-#endif
+   CLIP_TILE;
+
    for (i = 0; i < h; i++) {
       float *pRow = p;
       for (j = 0; j < w; j++) {
@@ -786,16 +815,8 @@ s8z24_get_tile(struct pipe_surface *ps,
 
    assert(ps->format == PIPE_FORMAT_S8_Z24);
 
-#if 0
-   assert(x + w <= ps->width);
-   assert(y + h <= ps->height);
-#else
-   /* temp clipping hack */
-   if (x + w > ps->width)
-      w = ps->width - x;
-   if (y + h > ps->height)
-      h = ps->height -y;
-#endif
+   CLIP_TILE;
+
    for (i = 0; i < h; i++) {
       float *pRow = p;
       for (j = 0; j < w; j++) {
@@ -883,6 +904,11 @@ softpipe_init_surface_funcs(struct softpipe_surface *sps)
       sps->surface.get_tile = a8_l8_get_tile;
       break;
 
+   case PIPE_FORMAT_S_R16_G16_B16_A16:
+      sps->surface.get_tile = r16g16b16a16_get_tile;
+      sps->surface.put_tile = r16g16b16a16_put_tile;
+      break;
+
    case PIPE_FORMAT_U_Z16:
       sps->read_quad_z = z16_read_quad_z;
       sps->write_quad_z = z16_write_quad_z;