1 /************************************************************************** 2 * 3 * Copyright 2010 VMware, Inc. 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sub license, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 17 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 18 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 19 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 20 * USE OR OTHER DEALINGS IN THE SOFTWARE. 21 * 22 * The above copyright notice and this permission notice (including the 23 * next paragraph) shall be included in all copies or substantial portions 24 * of the Software. 25 * 26 **************************************************************************/ 27 28 29 #include "u_math.h" 30 #include "u_format_other.h" 31 #include "util/format_rgb9e5.h" 32 #include "util/format_r11g11b10f.h" 33 34 35 void 36 util_format_r9g9b9e5_float_unpack_rgba_float(float *dst_row, unsigned dst_stride, 37 const uint8_t *src_row, unsigned src_stride, 38 unsigned width, unsigned height) 39 { 40 unsigned x, y; 41 for(y = 0; y < height; y += 1) { 42 float *dst = dst_row; 43 const uint8_t *src = src_row; 44 for(x = 0; x < width; x += 1) { 45 uint32_t value = util_cpu_to_le32(*(const uint32_t *)src); 46 rgb9e5_to_float3(value, dst); 47 dst[3] = 1; /* a */ 48 src += 4; 49 dst += 4; 50 } 51 src_row += src_stride; 52 dst_row += dst_stride/sizeof(*dst_row); 53 } 54 } 55 56 void 57 util_format_r9g9b9e5_float_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, 58 const float *src_row, unsigned src_stride, 59 unsigned width, unsigned height) 60 { 61 unsigned x, y; 62 for(y = 0; y < height; y += 1) { 63 const float *src = src_row; 64 uint8_t *dst = dst_row; 65 for(x = 0; x < width; x += 1) { 66 uint32_t value = util_cpu_to_le32(float3_to_rgb9e5(src)); 67 *(uint32_t *)dst = value; 68 src += 4; 69 dst += 4; 70 } 71 dst_row += dst_stride; 72 src_row += src_stride/sizeof(*src_row); 73 } 74 } 75 76 void 77 util_format_r9g9b9e5_float_fetch_rgba_float(float *dst, const uint8_t *src, 78 unsigned i, unsigned j) 79 { 80 uint32_t value = util_cpu_to_le32(*(const uint32_t *)src); 81 rgb9e5_to_float3(value, dst); 82 dst[3] = 1; /* a */ 83 } 84 85 86 void 87 util_format_r9g9b9e5_float_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, 88 const uint8_t *src_row, unsigned src_stride, 89 unsigned width, unsigned height) 90 { 91 unsigned x, y; 92 float p[3]; 93 for(y = 0; y < height; y += 1) { 94 uint8_t *dst = dst_row; 95 const uint8_t *src = src_row; 96 for(x = 0; x < width; x += 1) { 97 uint32_t value = util_cpu_to_le32(*(const uint32_t *)src); 98 rgb9e5_to_float3(value, p); 99 dst[0] = float_to_ubyte(p[0]); /* r */ 100 dst[1] = float_to_ubyte(p[1]); /* g */ 101 dst[2] = float_to_ubyte(p[2]); /* b */ 102 dst[3] = 255; /* a */ 103 src += 4; 104 dst += 4; 105 } 106 src_row += src_stride; 107 dst_row += dst_stride/sizeof(*dst_row); 108 } 109 } 110 111 112 void 113 util_format_r9g9b9e5_float_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, 114 const uint8_t *src_row, unsigned src_stride, 115 unsigned width, unsigned height) 116 { 117 unsigned x, y; 118 float p[3]; 119 for(y = 0; y < height; y += 1) { 120 const uint8_t *src = src_row; 121 uint8_t *dst = dst_row; 122 for(x = 0; x < width; x += 1) { 123 uint32_t value; 124 p[0] = ubyte_to_float(src[0]); 125 p[1] = ubyte_to_float(src[1]); 126 p[2] = ubyte_to_float(src[2]); 127 value = util_cpu_to_le32(float3_to_rgb9e5(p)); 128 *(uint32_t *)dst = value; 129 src += 4; 130 dst += 4; 131 } 132 dst_row += dst_stride; 133 src_row += src_stride/sizeof(*src_row); 134 } 135 } 136 137 138 void 139 util_format_r11g11b10_float_unpack_rgba_float(float *dst_row, unsigned dst_stride, 140 const uint8_t *src_row, unsigned src_stride, 141 unsigned width, unsigned height) 142 { 143 unsigned x, y; 144 for(y = 0; y < height; y += 1) { 145 float *dst = dst_row; 146 const uint8_t *src = src_row; 147 for(x = 0; x < width; x += 1) { 148 uint32_t value = util_cpu_to_le32(*(const uint32_t *)src); 149 r11g11b10f_to_float3(value, dst); 150 dst[3] = 1; /* a */ 151 src += 4; 152 dst += 4; 153 } 154 src_row += src_stride; 155 dst_row += dst_stride/sizeof(*dst_row); 156 } 157 } 158 159 void 160 util_format_r11g11b10_float_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, 161 const float *src_row, unsigned src_stride, 162 unsigned width, unsigned height) 163 { 164 unsigned x, y; 165 for(y = 0; y < height; y += 1) { 166 const float *src = src_row; 167 uint8_t *dst = dst_row; 168 for(x = 0; x < width; x += 1) { 169 uint32_t value = util_cpu_to_le32(float3_to_r11g11b10f(src)); 170 *(uint32_t *)dst = value; 171 src += 4; 172 dst += 4; 173 } 174 dst_row += dst_stride; 175 src_row += src_stride/sizeof(*src_row); 176 } 177 } 178 179 void 180 util_format_r11g11b10_float_fetch_rgba_float(float *dst, const uint8_t *src, 181 unsigned i, unsigned j) 182 { 183 uint32_t value = util_cpu_to_le32(*(const uint32_t *)src); 184 r11g11b10f_to_float3(value, dst); 185 dst[3] = 1; /* a */ 186 } 187 188 189 void 190 util_format_r11g11b10_float_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, 191 const uint8_t *src_row, unsigned src_stride, 192 unsigned width, unsigned height) 193 { 194 unsigned x, y; 195 float p[3]; 196 for(y = 0; y < height; y += 1) { 197 uint8_t *dst = dst_row; 198 const uint8_t *src = src_row; 199 for(x = 0; x < width; x += 1) { 200 uint32_t value = util_cpu_to_le32(*(const uint32_t *)src); 201 r11g11b10f_to_float3(value, p); 202 dst[0] = float_to_ubyte(p[0]); /* r */ 203 dst[1] = float_to_ubyte(p[1]); /* g */ 204 dst[2] = float_to_ubyte(p[2]); /* b */ 205 dst[3] = 255; /* a */ 206 src += 4; 207 dst += 4; 208 } 209 src_row += src_stride; 210 dst_row += dst_stride/sizeof(*dst_row); 211 } 212 } 213 214 215 void 216 util_format_r11g11b10_float_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, 217 const uint8_t *src_row, unsigned src_stride, 218 unsigned width, unsigned height) 219 { 220 unsigned x, y; 221 float p[3]; 222 for(y = 0; y < height; y += 1) { 223 const uint8_t *src = src_row; 224 uint8_t *dst = dst_row; 225 for(x = 0; x < width; x += 1) { 226 uint32_t value; 227 p[0] = ubyte_to_float(src[0]); 228 p[1] = ubyte_to_float(src[1]); 229 p[2] = ubyte_to_float(src[2]); 230 value = util_cpu_to_le32(float3_to_r11g11b10f(p)); 231 *(uint32_t *)dst = value; 232 src += 4; 233 dst += 4; 234 } 235 dst_row += dst_stride; 236 src_row += src_stride/sizeof(*src_row); 237 } 238 } 239 240 241 void 242 util_format_r1_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, 243 const uint8_t *src_row, unsigned src_stride, 244 unsigned width, unsigned height) 245 { 246 247 } 248 249 250 void 251 util_format_r1_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, 252 const float *src_row, unsigned src_stride, 253 unsigned width, unsigned height) 254 { 255 256 } 257 258 259 void 260 util_format_r1_unorm_fetch_rgba_float(float *dst, const uint8_t *src, 261 unsigned i, unsigned j) 262 { 263 264 } 265 266 267 void 268 util_format_r1_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, 269 const uint8_t *src_row, unsigned src_stride, 270 unsigned width, unsigned height) 271 { 272 273 } 274 275 276 void 277 util_format_r1_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, 278 const uint8_t *src_row, unsigned src_stride, 279 unsigned width, unsigned height) 280 { 281 } 282 283 284 /* 285 * PIPE_FORMAT_R8G8Bx_SNORM 286 * 287 * A.k.a. D3DFMT_CxV8U8 288 */ 289 290 static uint8_t 291 r8g8bx_derive(int16_t r, int16_t g) 292 { 293 /* Derive blue from red and green components. 294 * Apparently, we must always use integers to perform calculations, 295 * otherwise the results won't match D3D's CxV8U8 definition. 296 */ 297 return (uint8_t)sqrtf(0x7f * 0x7f - r * r - g * g) * 0xff / 0x7f; 298 } 299 300 void 301 util_format_r8g8bx_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, 302 const uint8_t *src_row, unsigned src_stride, 303 unsigned width, unsigned height) 304 { 305 unsigned x, y; 306 307 for(y = 0; y < height; y += 1) { 308 float *dst = dst_row; 309 const uint16_t *src = (const uint16_t *)src_row; 310 for(x = 0; x < width; x += 1) { 311 uint16_t value = util_cpu_to_le16(*src++); 312 int16_t r, g; 313 314 r = ((int16_t)(value << 8)) >> 8; 315 g = ((int16_t)(value << 0)) >> 8; 316 317 dst[0] = (float)(r * (1.0f/0x7f)); /* r */ 318 dst[1] = (float)(g * (1.0f/0x7f)); /* g */ 319 dst[2] = r8g8bx_derive(r, g) * (1.0f/0xff); /* b */ 320 dst[3] = 1.0f; /* a */ 321 dst += 4; 322 } 323 src_row += src_stride; 324 dst_row += dst_stride/sizeof(*dst_row); 325 } 326 } 327 328 329 void 330 util_format_r8g8bx_snorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, 331 const uint8_t *src_row, unsigned src_stride, 332 unsigned width, unsigned height) 333 { 334 unsigned x, y; 335 for(y = 0; y < height; y += 1) { 336 uint8_t *dst = dst_row; 337 const uint16_t *src = (const uint16_t *)src_row; 338 for(x = 0; x < width; x += 1) { 339 uint16_t value = util_cpu_to_le16(*src++); 340 int16_t r, g; 341 342 r = ((int16_t)(value << 8)) >> 8; 343 g = ((int16_t)(value << 0)) >> 8; 344 345 dst[0] = (uint8_t)(((uint16_t)MAX2(r, 0)) * 0xff / 0x7f); /* r */ 346 dst[1] = (uint8_t)(((uint16_t)MAX2(g, 0)) * 0xff / 0x7f); /* g */ 347 dst[2] = r8g8bx_derive(r, g); /* b */ 348 dst[3] = 255; /* a */ 349 dst += 4; 350 } 351 src_row += src_stride; 352 dst_row += dst_stride/sizeof(*dst_row); 353 } 354 } 355 356 357 void 358 util_format_r8g8bx_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, 359 const float *src_row, unsigned src_stride, 360 unsigned width, unsigned height) 361 { 362 unsigned x, y; 363 for(y = 0; y < height; y += 1) { 364 const float *src = src_row; 365 uint16_t *dst = (uint16_t *)dst_row; 366 for(x = 0; x < width; x += 1) { 367 uint16_t value = 0; 368 369 value |= (uint16_t)(((int8_t)(CLAMP(src[0], -1, 1) * 0x7f)) & 0xff) ; 370 value |= (uint16_t)((((int8_t)(CLAMP(src[1], -1, 1) * 0x7f)) & 0xff) << 8) ; 371 372 *dst++ = util_le16_to_cpu(value); 373 374 src += 4; 375 } 376 dst_row += dst_stride; 377 src_row += src_stride/sizeof(*src_row); 378 } 379 } 380 381 382 void 383 util_format_r8g8bx_snorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, 384 const uint8_t *src_row, unsigned src_stride, 385 unsigned width, unsigned height) 386 { 387 unsigned x, y; 388 389 for(y = 0; y < height; y += 1) { 390 const uint8_t *src = src_row; 391 uint16_t *dst = (uint16_t *)dst_row; 392 for(x = 0; x < width; x += 1) { 393 uint16_t value = 0; 394 395 value |= src[0] >> 1; 396 value |= (src[1] >> 1) << 8; 397 398 *dst++ = util_le16_to_cpu(value); 399 400 src += 4; 401 } 402 dst_row += dst_stride; 403 src_row += src_stride/sizeof(*src_row); 404 } 405 } 406 407 408 void 409 util_format_r8g8bx_snorm_fetch_rgba_float(float *dst, const uint8_t *src, 410 unsigned i, unsigned j) 411 { 412 uint16_t value = util_cpu_to_le16(*(const uint16_t *)src); 413 int16_t r, g; 414 415 r = ((int16_t)(value << 8)) >> 8; 416 g = ((int16_t)(value << 0)) >> 8; 417 418 dst[0] = r * (1.0f/0x7f); /* r */ 419 dst[1] = g * (1.0f/0x7f); /* g */ 420 dst[2] = r8g8bx_derive(r, g) * (1.0f/0xff); /* b */ 421 dst[3] = 1.0f; /* a */ 422 } 423