From d45fdc3f1f8200c1f1703bdcd5a74a153c74b1c4 Mon Sep 17 00:00:00 2001 From: Brian Date: Sun, 14 Oct 2007 11:53:15 -0600 Subject: [PATCH] 16-bit RGBA surface format for accum buffers --- src/mesa/pipe/softpipe/sp_region.c | 77 +++++++---- src/mesa/pipe/softpipe/sp_surface.c | 206 ++++++++++++++++------------ 2 files changed, 168 insertions(+), 115 deletions(-) diff --git a/src/mesa/pipe/softpipe/sp_region.c b/src/mesa/pipe/softpipe/sp_region.c index faf2737d6bb..982e081f603 100644 --- a/src/mesa/pipe/softpipe/sp_region.c +++ b/src/mesa/pipe/softpipe/sp_region.c @@ -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; diff --git a/src/mesa/pipe/softpipe/sp_surface.c b/src/mesa/pipe/softpipe/sp_surface.c index 07def21d42b..02a072fe9be 100755 --- a/src/mesa/pipe/softpipe/sp_surface.c +++ b/src/mesa/pipe/softpipe/sp_surface.c @@ -43,6 +43,31 @@ */ +/** 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; -- 2.30.2