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_format_other.h" 30#include "util/u_math.h" 31#include "util/format_rgb9e5.h" 32#include "util/format_r11g11b10f.h" 33 34 35void 36util_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 56void 57util_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 76void 77util_format_r9g9b9e5_float_fetch_rgba_float(float *dst, const uint8_t *src, 78 UNUSED unsigned i, UNUSED 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 86void 87util_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 112void 113util_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 138void 139util_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 159void 160util_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 179void 180util_format_r11g11b10_float_fetch_rgba_float(float *dst, const uint8_t *src, 181 UNUSED unsigned i, UNUSED 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 189void 190util_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 215void 216util_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 241void 242util_format_r1_unorm_unpack_rgba_float(UNUSED float *dst_row, UNUSED unsigned dst_stride, 243 UNUSED const uint8_t *src_row, UNUSED unsigned src_stride, 244 UNUSED unsigned width, UNUSED unsigned height) 245{ 246 247} 248 249 250void 251util_format_r1_unorm_pack_rgba_float(UNUSED uint8_t *dst_row, UNUSED unsigned dst_stride, 252 UNUSED const float *src_row, UNUSED unsigned src_stride, 253 UNUSED unsigned width, UNUSED unsigned height) 254{ 255 256} 257 258 259void 260util_format_r1_unorm_fetch_rgba_float(UNUSED float *dst, UNUSED const uint8_t *src, 261 UNUSED unsigned i, UNUSED unsigned j) 262{ 263 264} 265 266 267void 268util_format_r1_unorm_unpack_rgba_8unorm(UNUSED uint8_t *dst_row, UNUSED unsigned dst_stride, 269 UNUSED const uint8_t *src_row, UNUSED unsigned src_stride, 270 UNUSED unsigned width, UNUSED unsigned height) 271{ 272 273} 274 275 276void 277util_format_r1_unorm_pack_rgba_8unorm(UNUSED uint8_t *dst_row, UNUSED unsigned dst_stride, 278 UNUSED const uint8_t *src_row, UNUSED unsigned src_stride, 279 UNUSED unsigned width, UNUSED unsigned height) 280{ 281} 282 283 284/* 285 * PIPE_FORMAT_R8G8Bx_SNORM 286 * 287 * A.k.a. D3DFMT_CxV8U8 288 */ 289 290static uint8_t 291r8g8bx_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 300void 301util_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 329void 330util_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 357void 358util_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 382void 383util_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 408void 409util_format_r8g8bx_snorm_fetch_rgba_float(float *dst, const uint8_t *src, 410 UNUSED unsigned i, UNUSED 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