diff options
author | Christian König <[email protected]> | 2011-05-07 14:11:40 +0200 |
---|---|---|
committer | Christian König <[email protected]> | 2011-05-07 14:11:40 +0200 |
commit | 213b9004a6ee033a16af3dcd187aa68b56c39858 (patch) | |
tree | f577f4dc276f70dad63f102f69f87f4d566186ef /src/gallium/auxiliary | |
parent | 6ad846ee78d9d8ba93dcecdefbf89f2b981333ef (diff) | |
parent | 03615c02d81437cf546609fc6a39c6c73be39360 (diff) |
Merge remote-tracking branch 'origin/master' into pipe-video
Conflicts:
src/gallium/drivers/r600/r600_state.c
Diffstat (limited to 'src/gallium/auxiliary')
-rw-r--r-- | src/gallium/auxiliary/draw/draw_context.h | 2 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_vertex.c | 3 | ||||
-rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c | 2 | ||||
-rw-r--r-- | src/gallium/auxiliary/os/os_time.c | 2 | ||||
-rw-r--r-- | src/gallium/auxiliary/rbug/rbug_context.c | 7 | ||||
-rw-r--r-- | src/gallium/auxiliary/rbug/rbug_core.c | 14 | ||||
-rw-r--r-- | src/gallium/auxiliary/rbug/rbug_texture.c | 7 | ||||
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_build.c | 4 | ||||
-rw-r--r-- | src/gallium/auxiliary/util/u_format.csv | 2 | ||||
-rw-r--r-- | src/gallium/auxiliary/util/u_format_other.c | 204 | ||||
-rw-r--r-- | src/gallium/auxiliary/util/u_format_other.h | 26 | ||||
-rw-r--r-- | src/gallium/auxiliary/util/u_format_r11g11b10f.h | 190 | ||||
-rw-r--r-- | src/gallium/auxiliary/util/u_format_rgb9e5.h | 164 | ||||
-rw-r--r-- | src/gallium/auxiliary/util/u_math.h | 8 |
14 files changed, 589 insertions, 46 deletions
diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h index 7db75b71b43..5523e44563b 100644 --- a/src/gallium/auxiliary/draw/draw_context.h +++ b/src/gallium/auxiliary/draw/draw_context.h @@ -243,7 +243,7 @@ boolean draw_need_pipeline(const struct draw_context *draw, unsigned prim ); static INLINE int -draw_get_shader_param(unsigned shader, enum pipe_cap param) +draw_get_shader_param(unsigned shader, enum pipe_shader_cap param) { switch(shader) { case PIPE_SHADER_VERTEX: diff --git a/src/gallium/auxiliary/draw/draw_vertex.c b/src/gallium/auxiliary/draw/draw_vertex.c index a4f5e882c0a..a1b2b8ff975 100644 --- a/src/gallium/auxiliary/draw/draw_vertex.c +++ b/src/gallium/auxiliary/draw/draw_vertex.c @@ -60,10 +60,9 @@ draw_compute_vertex_size(struct vertex_info *vinfo) void draw_dump_emitted_vertex(const struct vertex_info *vinfo, const uint8_t *data) { - unsigned i, j; + unsigned i; for (i = 0; i < vinfo->num_attribs; i++) { - j = vinfo->attrib[i].src_index; switch (vinfo->attrib[i].emit) { case EMIT_OMIT: debug_printf("EMIT_OMIT:"); diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c index d1585c8e2b7..d8adb9fbfaf 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c @@ -2565,7 +2565,7 @@ lp_build_system_values_array(struct gallivm_state *gallivm, for (i = 0; i < info->num_system_values; i++) { LLVMValueRef index = lp_build_const_int32(gallivm, i * 4); - LLVMValueRef ptr, value; + LLVMValueRef ptr, value = 0; switch (info->system_value_semantic_name[i]) { case TGSI_SEMANTIC_INSTANCEID: diff --git a/src/gallium/auxiliary/os/os_time.c b/src/gallium/auxiliary/os/os_time.c index 84907215fe6..325f316784c 100644 --- a/src/gallium/auxiliary/os/os_time.c +++ b/src/gallium/auxiliary/os/os_time.c @@ -37,7 +37,7 @@ #if !defined(PIPE_OS_EMBEDDED) -#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_CYGWIN) +#if defined(PIPE_OS_UNIX) # include <sys/time.h> /* timeval */ #elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) # include <windows.h> diff --git a/src/gallium/auxiliary/rbug/rbug_context.c b/src/gallium/auxiliary/rbug/rbug_context.c index 36824058c7d..1188dd966e4 100644 --- a/src/gallium/auxiliary/rbug/rbug_context.c +++ b/src/gallium/auxiliary/rbug/rbug_context.c @@ -470,9 +470,6 @@ int rbug_send_context_draw_blocked(struct rbug_connection *__con, struct rbug_proto_context_list * rbug_demarshal_context_list(struct rbug_proto_header *header) { - uint32_t len = 0; - uint32_t pos = 0; - uint8_t *data = NULL; struct rbug_proto_context_list *ret; if (!header) @@ -480,9 +477,6 @@ struct rbug_proto_context_list * rbug_demarshal_context_list(struct rbug_proto_h if (header->opcode != (int32_t)RBUG_OP_CONTEXT_LIST) return NULL; - pos = 0; - len = header->length * 4; - data = (uint8_t*)&header[1]; ret = MALLOC(sizeof(*ret)); if (!ret) return NULL; @@ -490,7 +484,6 @@ struct rbug_proto_context_list * rbug_demarshal_context_list(struct rbug_proto_h ret->header.__message = header; ret->header.opcode = header->opcode; - return ret; } diff --git a/src/gallium/auxiliary/rbug/rbug_core.c b/src/gallium/auxiliary/rbug/rbug_core.c index 1d47d13c9f3..514a10932bc 100644 --- a/src/gallium/auxiliary/rbug/rbug_core.c +++ b/src/gallium/auxiliary/rbug/rbug_core.c @@ -226,9 +226,6 @@ int rbug_send_error_reply(struct rbug_connection *__con, struct rbug_proto_noop * rbug_demarshal_noop(struct rbug_proto_header *header) { - uint32_t len = 0; - uint32_t pos = 0; - uint8_t *data = NULL; struct rbug_proto_noop *ret; if (!header) @@ -236,9 +233,6 @@ struct rbug_proto_noop * rbug_demarshal_noop(struct rbug_proto_header *header) if (header->opcode != (int32_t)RBUG_OP_NOOP) return NULL; - pos = 0; - len = header->length * 4; - data = (uint8_t*)&header[1]; ret = MALLOC(sizeof(*ret)); if (!ret) return NULL; @@ -246,15 +240,11 @@ struct rbug_proto_noop * rbug_demarshal_noop(struct rbug_proto_header *header) ret->header.__message = header; ret->header.opcode = header->opcode; - return ret; } struct rbug_proto_ping * rbug_demarshal_ping(struct rbug_proto_header *header) { - uint32_t len = 0; - uint32_t pos = 0; - uint8_t *data = NULL; struct rbug_proto_ping *ret; if (!header) @@ -262,9 +252,6 @@ struct rbug_proto_ping * rbug_demarshal_ping(struct rbug_proto_header *header) if (header->opcode != (int32_t)RBUG_OP_PING) return NULL; - pos = 0; - len = header->length * 4; - data = (uint8_t*)&header[1]; ret = MALLOC(sizeof(*ret)); if (!ret) return NULL; @@ -272,7 +259,6 @@ struct rbug_proto_ping * rbug_demarshal_ping(struct rbug_proto_header *header) ret->header.__message = header; ret->header.opcode = header->opcode; - return ret; } diff --git a/src/gallium/auxiliary/rbug/rbug_texture.c b/src/gallium/auxiliary/rbug/rbug_texture.c index 2ad577915e8..017c8d0b99b 100644 --- a/src/gallium/auxiliary/rbug/rbug_texture.c +++ b/src/gallium/auxiliary/rbug/rbug_texture.c @@ -410,9 +410,6 @@ int rbug_send_texture_read_reply(struct rbug_connection *__con, struct rbug_proto_texture_list * rbug_demarshal_texture_list(struct rbug_proto_header *header) { - uint32_t len = 0; - uint32_t pos = 0; - uint8_t *data = NULL; struct rbug_proto_texture_list *ret; if (!header) @@ -420,9 +417,6 @@ struct rbug_proto_texture_list * rbug_demarshal_texture_list(struct rbug_proto_h if (header->opcode != (int32_t)RBUG_OP_TEXTURE_LIST) return NULL; - pos = 0; - len = header->length * 4; - data = (uint8_t*)&header[1]; ret = MALLOC(sizeof(*ret)); if (!ret) return NULL; @@ -430,7 +424,6 @@ struct rbug_proto_texture_list * rbug_demarshal_texture_list(struct rbug_proto_h ret->header.__message = header; ret->header.opcode = header->opcode; - return ret; } diff --git a/src/gallium/auxiliary/tgsi/tgsi_build.c b/src/gallium/auxiliary/tgsi/tgsi_build.c index d2cb98e84af..269940ec840 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_build.c +++ b/src/gallium/auxiliary/tgsi/tgsi_build.c @@ -917,7 +917,6 @@ tgsi_build_full_instruction( for( i = 0; i < full_inst->Instruction.NumDstRegs; i++ ) { const struct tgsi_full_dst_register *reg = &full_inst->Dst[i]; struct tgsi_dst_register *dst_register; - struct tgsi_token *prev_token; if( maxsize <= size ) return 0; @@ -932,7 +931,6 @@ tgsi_build_full_instruction( reg->Register.Index, instruction, header ); - prev_token = (struct tgsi_token *) dst_register; if( reg->Register.Indirect ) { struct tgsi_src_register *ind; @@ -1001,7 +999,6 @@ tgsi_build_full_instruction( for( i = 0; i < full_inst->Instruction.NumSrcRegs; i++ ) { const struct tgsi_full_src_register *reg = &full_inst->Src[i]; struct tgsi_src_register *src_register; - struct tgsi_token *prev_token; if( maxsize <= size ) return 0; @@ -1021,7 +1018,6 @@ tgsi_build_full_instruction( reg->Register.Index, instruction, header ); - prev_token = (struct tgsi_token *) src_register; if( reg->Register.Indirect ) { struct tgsi_src_register *ind; diff --git a/src/gallium/auxiliary/util/u_format.csv b/src/gallium/auxiliary/util/u_format.csv index e4b3f5df6ee..347e2beb8dd 100644 --- a/src/gallium/auxiliary/util/u_format.csv +++ b/src/gallium/auxiliary/util/u_format.csv @@ -147,7 +147,7 @@ PIPE_FORMAT_G8R8_G8B8_UNORM , subsampled, 2, 1, x32 , , , , xyz # some special formats not fitting anywhere else PIPE_FORMAT_R10G10B10A2_USCALED , plain, 1, 1, u10 , u10 , u10 , u2 , xyzw, rgb -PIPE_FORMAT_R11G11B10_FLOAT , plain, 1, 1, f11 , f11 , f10 , , xyz1, rgb +PIPE_FORMAT_R11G11B10_FLOAT , other, 1, 1, x32 , , , , xyz1, rgb PIPE_FORMAT_R9G9B9E5_FLOAT , other, 1, 1, x32 , , , , xyz1, rgb PIPE_FORMAT_R1_UNORM , other, 8, 1, x8 , , , , x001, rgb # A.k.a. D3DFMT_CxV8U8 diff --git a/src/gallium/auxiliary/util/u_format_other.c b/src/gallium/auxiliary/util/u_format_other.c index fa42ec37138..c23f4ee4ac5 100644 --- a/src/gallium/auxiliary/util/u_format_other.c +++ b/src/gallium/auxiliary/util/u_format_other.c @@ -28,6 +28,8 @@ #include "u_math.h" #include "u_format_other.h" +#include "u_format_rgb9e5.h" +#include "u_format_r11g11b10f.h" void @@ -35,7 +37,23 @@ util_format_r9g9b9e5_float_unpack_rgba_float(float *dst_row, unsigned dst_stride const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) { - + unsigned x, y; + for(y = 0; y < height; y += 1) { + float *dst = dst_row; + const uint8_t *src = src_row; + for(x = 0; x < width; x += 1) { + uint32_t value = *(const uint32_t *)src; +#ifdef PIPE_ARCH_BIG_ENDIAN + value = util_bswap32(value); +#endif + rgb9e5_to_float3(value, dst); + dst[3] = 1; /* a */ + src += 4; + dst += 4; + } + src_row += src_stride; + dst_row += dst_stride/sizeof(*dst_row); + } } void @@ -43,14 +61,34 @@ util_format_r9g9b9e5_float_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride const float *src_row, unsigned src_stride, unsigned width, unsigned height) { - + unsigned x, y; + for(y = 0; y < height; y += 1) { + const float *src = src_row; + uint8_t *dst = dst_row; + for(x = 0; x < width; x += 1) { + uint32_t value = float3_to_rgb9e5(src); +#ifdef PIPE_ARCH_BIG_ENDIAN + value = util_bswap32(value); +#endif + *(uint32_t *)dst = value; + src += 4; + dst += 4; + } + dst_row += dst_stride; + src_row += src_stride/sizeof(*src_row); + } } void util_format_r9g9b9e5_float_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) { - + uint32_t value = *(const uint32_t *)src; +#ifdef PIPE_ARCH_BIG_ENDIAN + value = util_bswap32(value); +#endif + rgb9e5_to_float3(value, dst); + dst[3] = 1; /* a */ } @@ -59,7 +97,27 @@ util_format_r9g9b9e5_float_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_str const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) { - + unsigned x, y; + float p[3]; + for(y = 0; y < height; y += 1) { + uint8_t *dst = dst_row; + const uint8_t *src = src_row; + for(x = 0; x < width; x += 1) { + uint32_t value = *(const uint32_t *)src; +#ifdef PIPE_ARCH_BIG_ENDIAN + value = util_bswap32(value); +#endif + rgb9e5_to_float3(value, p); + dst[0] = float_to_ubyte(p[0]); /* r */ + dst[1] = float_to_ubyte(p[1]); /* g */ + dst[2] = float_to_ubyte(p[2]); /* b */ + dst[3] = 255; /* a */ + src += 4; + dst += 4; + } + src_row += src_stride; + dst_row += dst_stride/sizeof(*dst_row); + } } @@ -68,7 +126,145 @@ util_format_r9g9b9e5_float_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_strid const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) { + unsigned x, y; + float p[3]; + for(y = 0; y < height; y += 1) { + const uint8_t *src = src_row; + uint8_t *dst = dst_row; + for(x = 0; x < width; x += 1) { + uint32_t value; + p[0] = ubyte_to_float(src[0]); + p[1] = ubyte_to_float(src[1]); + p[2] = ubyte_to_float(src[2]); + value = float3_to_rgb9e5(p); +#ifdef PIPE_ARCH_BIG_ENDIAN + value = util_bswap32(value); +#endif + *(uint32_t *)dst = value; + src += 4; + dst += 4; + } + dst_row += dst_stride; + src_row += src_stride/sizeof(*src_row); + } +} + +void +util_format_r11g11b10_float_unpack_rgba_float(float *dst_row, unsigned dst_stride, + const uint8_t *src_row, unsigned src_stride, + unsigned width, unsigned height) +{ + unsigned x, y; + for(y = 0; y < height; y += 1) { + float *dst = dst_row; + const uint8_t *src = src_row; + for(x = 0; x < width; x += 1) { + uint32_t value = *(const uint32_t *)src; +#ifdef PIPE_ARCH_BIG_ENDIAN + value = util_bswap32(value); +#endif + r11g11b10f_to_float3(value, dst); + dst[3] = 1; /* a */ + src += 4; + dst += 4; + } + src_row += src_stride; + dst_row += dst_stride/sizeof(*dst_row); + } +} + +void +util_format_r11g11b10_float_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, + const float *src_row, unsigned src_stride, + unsigned width, unsigned height) +{ + unsigned x, y; + for(y = 0; y < height; y += 1) { + const float *src = src_row; + uint8_t *dst = dst_row; + for(x = 0; x < width; x += 1) { + uint32_t value = float3_to_r11g11b10f(src); +#ifdef PIPE_ARCH_BIG_ENDIAN + value = util_bswap32(value); +#endif + *(uint32_t *)dst = value; + src += 4; + dst += 4; + } + dst_row += dst_stride; + src_row += src_stride/sizeof(*src_row); + } +} + +void +util_format_r11g11b10_float_fetch_rgba_float(float *dst, const uint8_t *src, + unsigned i, unsigned j) +{ + uint32_t value = *(const uint32_t *)src; +#ifdef PIPE_ARCH_BIG_ENDIAN + value = util_bswap32(value); +#endif + r11g11b10f_to_float3(value, dst); + dst[3] = 1; /* a */ +} + + +void +util_format_r11g11b10_float_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, + const uint8_t *src_row, unsigned src_stride, + unsigned width, unsigned height) +{ + unsigned x, y; + float p[3]; + for(y = 0; y < height; y += 1) { + uint8_t *dst = dst_row; + const uint8_t *src = src_row; + for(x = 0; x < width; x += 1) { + uint32_t value = *(const uint32_t *)src; +#ifdef PIPE_ARCH_BIG_ENDIAN + value = util_bswap32(value); +#endif + r11g11b10f_to_float3(value, p); + dst[0] = float_to_ubyte(p[0]); /* r */ + dst[1] = float_to_ubyte(p[1]); /* g */ + dst[2] = float_to_ubyte(p[2]); /* b */ + dst[3] = 255; /* a */ + src += 4; + dst += 4; + } + src_row += src_stride; + dst_row += dst_stride/sizeof(*dst_row); + } +} + + +void +util_format_r11g11b10_float_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, + const uint8_t *src_row, unsigned src_stride, + unsigned width, unsigned height) +{ + unsigned x, y; + float p[3]; + for(y = 0; y < height; y += 1) { + const uint8_t *src = src_row; + uint8_t *dst = dst_row; + for(x = 0; x < width; x += 1) { + uint32_t value; + p[0] = ubyte_to_float(src[0]); + p[1] = ubyte_to_float(src[1]); + p[2] = ubyte_to_float(src[2]); + value = float3_to_r11g11b10f(p); +#ifdef PIPE_ARCH_BIG_ENDIAN + value = util_bswap32(value); +#endif + *(uint32_t *)dst = value; + src += 4; + dst += 4; + } + dst_row += dst_stride; + src_row += src_stride/sizeof(*src_row); + } } diff --git a/src/gallium/auxiliary/util/u_format_other.h b/src/gallium/auxiliary/util/u_format_other.h index 98c97be33fa..2f6a908bbe8 100644 --- a/src/gallium/auxiliary/util/u_format_other.h +++ b/src/gallium/auxiliary/util/u_format_other.h @@ -57,6 +57,32 @@ util_format_r9g9b9e5_float_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_strid const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); + +void +util_format_r11g11b10_float_unpack_rgba_float(float *dst_row, unsigned dst_stride, + const uint8_t *src_row, unsigned src_stride, + unsigned width, unsigned height); + +void +util_format_r11g11b10_float_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, + const float *src_row, unsigned src_stride, + unsigned width, unsigned height); + +void +util_format_r11g11b10_float_fetch_rgba_float(float *dst, const uint8_t *src, + unsigned i, unsigned j); + +void +util_format_r11g11b10_float_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, + const uint8_t *src_row, unsigned src_stride, + unsigned width, unsigned height); + +void +util_format_r11g11b10_float_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, + const uint8_t *src_row, unsigned src_stride, + unsigned width, unsigned height); + + void util_format_r1_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, diff --git a/src/gallium/auxiliary/util/u_format_r11g11b10f.h b/src/gallium/auxiliary/util/u_format_r11g11b10f.h new file mode 100644 index 00000000000..c4181d0e34e --- /dev/null +++ b/src/gallium/auxiliary/util/u_format_r11g11b10f.h @@ -0,0 +1,190 @@ +/* + * Copyright (C) 2011 Marek Olšák <[email protected]> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/* Based on code from The OpenGL Programming Guide / 7th Edition, Appendix J. + * Available here: http://www.opengl-redbook.com/appendices/ + * The algorithm in the book contains a bug though, which is fixed in the code + * below. + */ + +#define UF11_EXPONENT_BIAS 15 +#define UF11_EXPONENT_BITS 0x1F +#define UF11_EXPONENT_SHIFT 6 +#define UF11_MANTISSA_BITS 0x3F +#define UF11_MANTISSA_SHIFT (23 - UF11_EXPONENT_SHIFT) +#define UF11_MAX_EXPONENT (UF11_EXPONENT_BITS << UF11_EXPONENT_SHIFT) + +#define UF10_EXPONENT_BIAS 15 +#define UF10_EXPONENT_BITS 0x1F +#define UF10_EXPONENT_SHIFT 5 +#define UF10_MANTISSA_BITS 0x3F +#define UF10_MANTISSA_SHIFT (23 - UF10_EXPONENT_SHIFT) +#define UF10_MAX_EXPONENT (UF10_EXPONENT_BITS << UF10_EXPONENT_SHIFT) + +#define F32_INFINITY 0x7f800000 + +static INLINE unsigned f32_to_uf11(float val) +{ + uint32_t f32 = (*(uint32_t *) &val); + uint16_t uf11 = 0; + + /* Decode little-endian 32-bit floating-point value */ + int sign = (f32 >> 16) & 0x8000; + /* Map exponent to the range [-127,128] */ + int exponent = ((f32 >> 23) & 0xff) - 127; + int mantissa = f32 & 0x007fffff; + + if (sign) return 0; + + if (exponent == 128) { /* Infinity or NaN */ + uf11 = UF11_MAX_EXPONENT; + if (mantissa) uf11 |= (mantissa & UF11_MANTISSA_BITS); + } + else if (exponent > 15) { /* Overflow - flush to Infinity */ + uf11 = UF11_MAX_EXPONENT; + } + else if (exponent > -15) { /* Representable value */ + exponent += UF11_EXPONENT_BIAS; + mantissa >>= UF11_MANTISSA_SHIFT; + uf11 = exponent << UF11_EXPONENT_SHIFT | mantissa; + } + + return uf11; +} + +static INLINE float uf11_to_f32(uint16_t val) +{ + union { + float f; + uint32_t ui; + } f32; + + int exponent = (val & 0x07c0) >> UF11_EXPONENT_SHIFT; + int mantissa = (val & 0x003f); + + f32.f = 0.0; + + if (exponent == 0) { + if (mantissa != 0) { + const float scale = 1.0 / (1 << 20); + f32.f = scale * mantissa; + } + } + else if (exponent == 31) { + f32.ui = F32_INFINITY | mantissa; + } + else { + float scale, decimal; + exponent -= 15; + if (exponent < 0) { + scale = 1.0 / (1 << -exponent); + } + else { + scale = 1 << exponent; + } + decimal = 1.0 + (float) mantissa / 64; + f32.f = scale * decimal; + } + + return f32.f; +} + +static INLINE unsigned f32_to_uf10(float val) +{ + uint32_t f32 = (*(uint32_t *) &val); + uint16_t uf10 = 0; + + /* Decode little-endian 32-bit floating-point value */ + int sign = (f32 >> 16) & 0x8000; + /* Map exponent to the range [-127,128] */ + int exponent = ((f32 >> 23) & 0xff) - 127; + int mantissa = f32 & 0x007fffff; + + if (sign) return 0; + + if (exponent == 128) { /* Infinity or NaN */ + uf10 = UF10_MAX_EXPONENT; + if (mantissa) uf10 |= (mantissa & UF10_MANTISSA_BITS); + } + else if (exponent > 15) { /* Overflow - flush to Infinity */ + uf10 = UF10_MAX_EXPONENT; + } + else if (exponent > -15) { /* Representable value */ + exponent += UF10_EXPONENT_BIAS; + mantissa >>= UF10_MANTISSA_SHIFT; + uf10 = exponent << UF10_EXPONENT_SHIFT | mantissa; + } + + return uf10; +} + +static INLINE float uf10_to_f32(uint16_t val) +{ + union { + float f; + uint32_t ui; + } f32; + + int exponent = (val & 0x07c0) >> UF10_EXPONENT_SHIFT; + int mantissa = (val & 0x003f); + + f32.f = 0.0; + + if (exponent == 0) { + if (mantissa != 0) { + const float scale = 1.0 / (1 << 20); + f32.f = scale * mantissa; + } + } + else if (exponent == 31) { + f32.ui = F32_INFINITY | mantissa; + } + else { + float scale, decimal; + exponent -= 15; + if (exponent < 0) { + scale = 1.0 / (1 << -exponent); + } + else { + scale = 1 << exponent; + } + decimal = 1.0 + (float) mantissa / 32; + f32.f = scale * decimal; + } + + return f32.f; +} + +static INLINE unsigned float3_to_r11g11b10f(const float rgb[3]) +{ + return ( f32_to_uf11(rgb[0]) & 0x7ff) | + ((f32_to_uf11(rgb[1]) & 0x7ff) << 11) | + ((f32_to_uf10(rgb[2]) & 0x3ff) << 22); +} + +static INLINE void r11g11b10f_to_float3(unsigned rgb, float retval[3]) +{ + retval[0] = uf11_to_f32( rgb & 0x7ff); + retval[1] = uf11_to_f32((rgb >> 11) & 0x7ff); + retval[2] = uf10_to_f32((rgb >> 22) & 0x3ff); +} diff --git a/src/gallium/auxiliary/util/u_format_rgb9e5.h b/src/gallium/auxiliary/util/u_format_rgb9e5.h new file mode 100644 index 00000000000..c2a3f6f3e9d --- /dev/null +++ b/src/gallium/auxiliary/util/u_format_rgb9e5.h @@ -0,0 +1,164 @@ +/* + * Copyright (C) 2011 Marek Olšák <[email protected]> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/* Copied from EXT_texture_shared_exponent and edited. */ + +#ifndef RGB9E5_H +#define RGB9E5_H + +#include <math.h> +#include <assert.h> + +#define RGB9E5_EXPONENT_BITS 5 +#define RGB9E5_MANTISSA_BITS 9 +#define RGB9E5_EXP_BIAS 15 +#define RGB9E5_MAX_VALID_BIASED_EXP 31 + +#define MAX_RGB9E5_EXP (RGB9E5_MAX_VALID_BIASED_EXP - RGB9E5_EXP_BIAS) +#define RGB9E5_MANTISSA_VALUES (1<<RGB9E5_MANTISSA_BITS) +#define MAX_RGB9E5_MANTISSA (RGB9E5_MANTISSA_VALUES-1) +#define MAX_RGB9E5 (((float)MAX_RGB9E5_MANTISSA)/RGB9E5_MANTISSA_VALUES * (1<<MAX_RGB9E5_EXP)) +#define EPSILON_RGB9E5 ((1.0/RGB9E5_MANTISSA_VALUES) / (1<<RGB9E5_EXP_BIAS)) + +typedef union { + unsigned int raw; + float value; + struct { +#if defined(MESA_BIG_ENDIAN) || defined(PIPE_ARCH_BIG_ENDIAN) + unsigned int negative:1; + unsigned int biasedexponent:8; + unsigned int mantissa:23; +#else + unsigned int mantissa:23; + unsigned int biasedexponent:8; + unsigned int negative:1; +#endif + } field; +} float754; + +typedef union { + unsigned int raw; + struct { +#if defined(MESA_BIG_ENDIAN) || defined(PIPE_ARCH_BIG_ENDIAN) + unsigned int biasedexponent:RGB9E5_EXPONENT_BITS; + unsigned int b:RGB9E5_MANTISSA_BITS; + unsigned int g:RGB9E5_MANTISSA_BITS; + unsigned int r:RGB9E5_MANTISSA_BITS; +#else + unsigned int r:RGB9E5_MANTISSA_BITS; + unsigned int g:RGB9E5_MANTISSA_BITS; + unsigned int b:RGB9E5_MANTISSA_BITS; + unsigned int biasedexponent:RGB9E5_EXPONENT_BITS; +#endif + } field; +} rgb9e5; + +static INLINE float rgb9e5_ClampRange(float x) +{ + if (x > 0.0) { + if (x >= MAX_RGB9E5) { + return MAX_RGB9E5; + } else { + return x; + } + } else { + /* NaN gets here too since comparisons with NaN always fail! */ + return 0.0; + } +} + +/* Ok, FloorLog2 is not correct for the denorm and zero values, but we + are going to do a max of this value with the minimum rgb9e5 exponent + that will hide these problem cases. */ +static INLINE int rgb9e5_FloorLog2(float x) +{ + float754 f; + + f.value = x; + return (f.field.biasedexponent - 127); +} + +static INLINE unsigned float3_to_rgb9e5(const float rgb[3]) +{ + rgb9e5 retval; + float maxrgb; + int rm, gm, bm; + float rc, gc, bc; + int exp_shared, maxm; + double denom; + + rc = rgb9e5_ClampRange(rgb[0]); + gc = rgb9e5_ClampRange(rgb[1]); + bc = rgb9e5_ClampRange(rgb[2]); + + maxrgb = MAX3(rc, gc, bc); + exp_shared = MAX2(-RGB9E5_EXP_BIAS-1, rgb9e5_FloorLog2(maxrgb)) + 1 + RGB9E5_EXP_BIAS; + assert(exp_shared <= RGB9E5_MAX_VALID_BIASED_EXP); + assert(exp_shared >= 0); + /* This pow function could be replaced by a table. */ + denom = pow(2, exp_shared - RGB9E5_EXP_BIAS - RGB9E5_MANTISSA_BITS); + + maxm = (int) floor(maxrgb / denom + 0.5); + if (maxm == MAX_RGB9E5_MANTISSA+1) { + denom *= 2; + exp_shared += 1; + assert(exp_shared <= RGB9E5_MAX_VALID_BIASED_EXP); + } else { + assert(maxm <= MAX_RGB9E5_MANTISSA); + } + + rm = (int) floor(rc / denom + 0.5); + gm = (int) floor(gc / denom + 0.5); + bm = (int) floor(bc / denom + 0.5); + + assert(rm <= MAX_RGB9E5_MANTISSA); + assert(gm <= MAX_RGB9E5_MANTISSA); + assert(bm <= MAX_RGB9E5_MANTISSA); + assert(rm >= 0); + assert(gm >= 0); + assert(bm >= 0); + + retval.field.r = rm; + retval.field.g = gm; + retval.field.b = bm; + retval.field.biasedexponent = exp_shared; + + return retval.raw; +} + +static INLINE void rgb9e5_to_float3(unsigned rgb, float retval[3]) +{ + rgb9e5 v; + int exponent; + float scale; + + v.raw = rgb; + exponent = v.field.biasedexponent - RGB9E5_EXP_BIAS - RGB9E5_MANTISSA_BITS; + scale = (float) pow(2, exponent); + + retval[0] = v.field.r * scale; + retval[1] = v.field.g * scale; + retval[2] = v.field.b * scale; +} + +#endif diff --git a/src/gallium/auxiliary/util/u_math.h b/src/gallium/auxiliary/util/u_math.h index e3d4c06b6f9..dad6a101fd7 100644 --- a/src/gallium/auxiliary/util/u_math.h +++ b/src/gallium/auxiliary/util/u_math.h @@ -581,11 +581,11 @@ util_bswap16(uint16_t n) #define MIN2( A, B ) ( (A)<(B) ? (A) : (B) ) #define MAX2( A, B ) ( (A)>(B) ? (A) : (B) ) -#define MIN3( A, B, C ) MIN2( MIN2( A, B ), C ) -#define MAX3( A, B, C ) MAX2( MAX2( A, B ), C ) +#define MIN3( A, B, C ) ((A) < (B) ? MIN2(A, C) : MIN2(B, C)) +#define MAX3( A, B, C ) ((A) > (B) ? MAX2(A, C) : MAX2(B, C)) -#define MIN4( A, B, C, D ) MIN2( MIN2( A, B ), MIN2(C, D) ) -#define MAX4( A, B, C, D ) MAX2( MAX2( A, B ), MAX2(C, D) ) +#define MIN4( A, B, C, D ) ((A) < (B) ? MIN3(A, C, D) : MIN3(B, C, D)) +#define MAX4( A, B, C, D ) ((A) > (B) ? MAX3(A, C, D) : MAX3(B, C, D)) /** |