1 /* 2 * Copyright 2008 Corbin Simpson <MostAwesomeDude (at) gmail.com> 3 * Copyright 2010 Marek Olk <maraeo (at) gmail.com> 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * on the rights to use, copy, modify, merge, publish, distribute, sub 9 * license, and/or sell copies of the Software, and to permit persons to whom 10 * the Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the next 13 * paragraph) shall be included in all copies or substantial portions of the 14 * Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 22 * USE OR OTHER DEALINGS IN THE SOFTWARE. */ 23 24 /* Always include headers in the reverse order!! ~ M. */ 25 #include "r300_texture.h" 26 27 #include "r300_context.h" 28 #include "r300_reg.h" 29 #include "r300_texture_desc.h" 30 #include "r300_transfer.h" 31 #include "r300_screen.h" 32 33 #include "util/u_format.h" 34 #include "util/u_format_s3tc.h" 35 #include "util/u_math.h" 36 #include "util/u_memory.h" 37 #include "util/u_mm.h" 38 39 #include "pipe/p_screen.h" 40 41 unsigned r300_get_swizzle_combined(const unsigned char *swizzle_format, 42 const unsigned char *swizzle_view, 43 boolean dxtc_swizzle) 44 { 45 unsigned i; 46 unsigned char swizzle[4]; 47 unsigned result = 0; 48 const uint32_t swizzle_shift[4] = { 49 R300_TX_FORMAT_R_SHIFT, 50 R300_TX_FORMAT_G_SHIFT, 51 R300_TX_FORMAT_B_SHIFT, 52 R300_TX_FORMAT_A_SHIFT 53 }; 54 uint32_t swizzle_bit[4] = { 55 dxtc_swizzle ? R300_TX_FORMAT_Z : R300_TX_FORMAT_X, 56 R300_TX_FORMAT_Y, 57 dxtc_swizzle ? R300_TX_FORMAT_X : R300_TX_FORMAT_Z, 58 R300_TX_FORMAT_W 59 }; 60 61 if (swizzle_view) { 62 /* Combine two sets of swizzles. */ 63 util_format_compose_swizzles(swizzle_format, swizzle_view, swizzle); 64 } else { 65 memcpy(swizzle, swizzle_format, 4); 66 } 67 68 /* Get swizzle. */ 69 for (i = 0; i < 4; i++) { 70 switch (swizzle[i]) { 71 case UTIL_FORMAT_SWIZZLE_Y: 72 result |= swizzle_bit[1] << swizzle_shift[i]; 73 break; 74 case UTIL_FORMAT_SWIZZLE_Z: 75 result |= swizzle_bit[2] << swizzle_shift[i]; 76 break; 77 case UTIL_FORMAT_SWIZZLE_W: 78 result |= swizzle_bit[3] << swizzle_shift[i]; 79 break; 80 case UTIL_FORMAT_SWIZZLE_0: 81 result |= R300_TX_FORMAT_ZERO << swizzle_shift[i]; 82 break; 83 case UTIL_FORMAT_SWIZZLE_1: 84 result |= R300_TX_FORMAT_ONE << swizzle_shift[i]; 85 break; 86 default: /* UTIL_FORMAT_SWIZZLE_X */ 87 result |= swizzle_bit[0] << swizzle_shift[i]; 88 } 89 } 90 return result; 91 } 92 93 /* Translate a pipe_format into a useful texture format for sampling. 94 * 95 * Some special formats are translated directly using R300_EASY_TX_FORMAT, 96 * but the majority of them is translated in a generic way, automatically 97 * supporting all the formats hw can support. 98 * 99 * R300_EASY_TX_FORMAT swizzles the texture. 100 * Note the signature of R300_EASY_TX_FORMAT: 101 * R300_EASY_TX_FORMAT(B, G, R, A, FORMAT); 102 * 103 * The FORMAT specifies how the texture sampler will treat the texture, and 104 * makes available X, Y, Z, W, ZERO, and ONE for swizzling. */ 105 uint32_t r300_translate_texformat(enum pipe_format format, 106 const unsigned char *swizzle_view, 107 boolean is_r500, 108 boolean dxtc_swizzle) 109 { 110 uint32_t result = 0; 111 const struct util_format_description *desc; 112 unsigned i; 113 boolean uniform = TRUE; 114 const uint32_t sign_bit[4] = { 115 R300_TX_FORMAT_SIGNED_W, 116 R300_TX_FORMAT_SIGNED_Z, 117 R300_TX_FORMAT_SIGNED_Y, 118 R300_TX_FORMAT_SIGNED_X, 119 }; 120 121 desc = util_format_description(format); 122 123 /* Colorspace (return non-RGB formats directly). */ 124 switch (desc->colorspace) { 125 /* Depth stencil formats. 126 * Swizzles are added in r300_merge_textures_and_samplers. */ 127 case UTIL_FORMAT_COLORSPACE_ZS: 128 switch (format) { 129 case PIPE_FORMAT_Z16_UNORM: 130 return R300_TX_FORMAT_X16; 131 case PIPE_FORMAT_X8Z24_UNORM: 132 case PIPE_FORMAT_S8_UINT_Z24_UNORM: 133 if (is_r500) 134 return R500_TX_FORMAT_Y8X24; 135 else 136 return R300_TX_FORMAT_Y16X16; 137 default: 138 return ~0; /* Unsupported. */ 139 } 140 141 /* YUV formats. */ 142 case UTIL_FORMAT_COLORSPACE_YUV: 143 result |= R300_TX_FORMAT_YUV_TO_RGB; 144 145 switch (format) { 146 case PIPE_FORMAT_UYVY: 147 return R300_EASY_TX_FORMAT(X, Y, Z, ONE, YVYU422) | result; 148 case PIPE_FORMAT_YUYV: 149 return R300_EASY_TX_FORMAT(X, Y, Z, ONE, VYUY422) | result; 150 default: 151 return ~0; /* Unsupported/unknown. */ 152 } 153 154 /* Add gamma correction. */ 155 case UTIL_FORMAT_COLORSPACE_SRGB: 156 result |= R300_TX_FORMAT_GAMMA; 157 break; 158 159 default: 160 switch (format) { 161 /* Same as YUV but without the YUR->RGB conversion. */ 162 case PIPE_FORMAT_R8G8_B8G8_UNORM: 163 return R300_EASY_TX_FORMAT(X, Y, Z, ONE, YVYU422) | result; 164 case PIPE_FORMAT_G8R8_G8B8_UNORM: 165 return R300_EASY_TX_FORMAT(X, Y, Z, ONE, VYUY422) | result; 166 default:; 167 } 168 } 169 170 /* Add swizzling. */ 171 /* The RGTC1_SNORM and LATC1_SNORM swizzle is done in the shader. */ 172 if (format != PIPE_FORMAT_RGTC1_SNORM && 173 format != PIPE_FORMAT_LATC1_SNORM) { 174 if (util_format_is_compressed(format) && 175 dxtc_swizzle && 176 format != PIPE_FORMAT_RGTC2_UNORM && 177 format != PIPE_FORMAT_RGTC2_SNORM && 178 format != PIPE_FORMAT_LATC2_UNORM && 179 format != PIPE_FORMAT_LATC2_SNORM) { 180 result |= r300_get_swizzle_combined(desc->swizzle, swizzle_view, 181 TRUE); 182 } else { 183 result |= r300_get_swizzle_combined(desc->swizzle, swizzle_view, 184 FALSE); 185 } 186 } 187 188 /* S3TC formats. */ 189 if (desc->layout == UTIL_FORMAT_LAYOUT_S3TC) { 190 if (!util_format_s3tc_enabled) { 191 return ~0; /* Unsupported. */ 192 } 193 194 switch (format) { 195 case PIPE_FORMAT_DXT1_RGB: 196 case PIPE_FORMAT_DXT1_RGBA: 197 case PIPE_FORMAT_DXT1_SRGB: 198 case PIPE_FORMAT_DXT1_SRGBA: 199 return R300_TX_FORMAT_DXT1 | result; 200 case PIPE_FORMAT_DXT3_RGBA: 201 case PIPE_FORMAT_DXT3_SRGBA: 202 return R300_TX_FORMAT_DXT3 | result; 203 case PIPE_FORMAT_DXT5_RGBA: 204 case PIPE_FORMAT_DXT5_SRGBA: 205 return R300_TX_FORMAT_DXT5 | result; 206 default: 207 return ~0; /* Unsupported/unknown. */ 208 } 209 } 210 211 /* RGTC formats. */ 212 if (desc->layout == UTIL_FORMAT_LAYOUT_RGTC) { 213 switch (format) { 214 case PIPE_FORMAT_RGTC1_SNORM: 215 case PIPE_FORMAT_LATC1_SNORM: 216 case PIPE_FORMAT_LATC1_UNORM: 217 case PIPE_FORMAT_RGTC1_UNORM: 218 return R500_TX_FORMAT_ATI1N | result; 219 220 case PIPE_FORMAT_RGTC2_SNORM: 221 case PIPE_FORMAT_LATC2_SNORM: 222 result |= sign_bit[1] | sign_bit[0]; 223 case PIPE_FORMAT_RGTC2_UNORM: 224 case PIPE_FORMAT_LATC2_UNORM: 225 return R400_TX_FORMAT_ATI2N | result; 226 227 default: 228 return ~0; /* Unsupported/unknown. */ 229 } 230 } 231 232 /* This is truly a special format. 233 * It stores R8G8 and B is computed using sqrt(1 - R^2 - G^2) 234 * in the sampler unit. Also known as D3DFMT_CxV8U8. */ 235 if (format == PIPE_FORMAT_R8G8Bx_SNORM) { 236 return R300_TX_FORMAT_CxV8U8 | result; 237 } 238 239 /* Integer and fixed-point 16.16 textures are not supported. */ 240 for (i = 0; i < 4; i++) { 241 if (desc->channel[i].type == UTIL_FORMAT_TYPE_FIXED || 242 ((desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED || 243 desc->channel[i].type == UTIL_FORMAT_TYPE_UNSIGNED) && 244 (!desc->channel[i].normalized || 245 desc->channel[i].pure_integer))) { 246 return ~0; /* Unsupported/unknown. */ 247 } 248 } 249 250 /* Add sign. */ 251 for (i = 0; i < desc->nr_channels; i++) { 252 if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED) { 253 result |= sign_bit[i]; 254 } 255 } 256 257 /* See whether the components are of the same size. */ 258 for (i = 1; i < desc->nr_channels; i++) { 259 uniform = uniform && desc->channel[0].size == desc->channel[i].size; 260 } 261 262 /* Non-uniform formats. */ 263 if (!uniform) { 264 switch (desc->nr_channels) { 265 case 3: 266 if (desc->channel[0].size == 5 && 267 desc->channel[1].size == 6 && 268 desc->channel[2].size == 5) { 269 return R300_TX_FORMAT_Z5Y6X5 | result; 270 } 271 if (desc->channel[0].size == 5 && 272 desc->channel[1].size == 5 && 273 desc->channel[2].size == 6) { 274 return R300_TX_FORMAT_Z6Y5X5 | result; 275 } 276 if (desc->channel[0].size == 2 && 277 desc->channel[1].size == 3 && 278 desc->channel[2].size == 3) { 279 return R300_TX_FORMAT_Z3Y3X2 | result; 280 } 281 return ~0; /* Unsupported/unknown. */ 282 283 case 4: 284 if (desc->channel[0].size == 5 && 285 desc->channel[1].size == 5 && 286 desc->channel[2].size == 5 && 287 desc->channel[3].size == 1) { 288 return R300_TX_FORMAT_W1Z5Y5X5 | result; 289 } 290 if (desc->channel[0].size == 10 && 291 desc->channel[1].size == 10 && 292 desc->channel[2].size == 10 && 293 desc->channel[3].size == 2) { 294 return R300_TX_FORMAT_W2Z10Y10X10 | result; 295 } 296 } 297 return ~0; /* Unsupported/unknown. */ 298 } 299 300 /* Find the first non-VOID channel. */ 301 for (i = 0; i < 4; i++) { 302 if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) { 303 break; 304 } 305 } 306 307 if (i == 4) 308 return ~0; /* Unsupported/unknown. */ 309 310 /* And finally, uniform formats. */ 311 switch (desc->channel[i].type) { 312 case UTIL_FORMAT_TYPE_UNSIGNED: 313 case UTIL_FORMAT_TYPE_SIGNED: 314 if (!desc->channel[i].normalized && 315 desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB) { 316 return ~0; 317 } 318 319 switch (desc->channel[i].size) { 320 case 4: 321 switch (desc->nr_channels) { 322 case 2: 323 return R300_TX_FORMAT_Y4X4 | result; 324 case 4: 325 return R300_TX_FORMAT_W4Z4Y4X4 | result; 326 } 327 return ~0; 328 329 case 8: 330 switch (desc->nr_channels) { 331 case 1: 332 return R300_TX_FORMAT_X8 | result; 333 case 2: 334 return R300_TX_FORMAT_Y8X8 | result; 335 case 4: 336 return R300_TX_FORMAT_W8Z8Y8X8 | result; 337 } 338 return ~0; 339 340 case 16: 341 switch (desc->nr_channels) { 342 case 1: 343 return R300_TX_FORMAT_X16 | result; 344 case 2: 345 return R300_TX_FORMAT_Y16X16 | result; 346 case 4: 347 return R300_TX_FORMAT_W16Z16Y16X16 | result; 348 } 349 } 350 return ~0; 351 352 case UTIL_FORMAT_TYPE_FLOAT: 353 switch (desc->channel[i].size) { 354 case 16: 355 switch (desc->nr_channels) { 356 case 1: 357 return R300_TX_FORMAT_16F | result; 358 case 2: 359 return R300_TX_FORMAT_16F_16F | result; 360 case 4: 361 return R300_TX_FORMAT_16F_16F_16F_16F | result; 362 } 363 return ~0; 364 365 case 32: 366 switch (desc->nr_channels) { 367 case 1: 368 return R300_TX_FORMAT_32F | result; 369 case 2: 370 return R300_TX_FORMAT_32F_32F | result; 371 case 4: 372 return R300_TX_FORMAT_32F_32F_32F_32F | result; 373 } 374 } 375 } 376 377 return ~0; /* Unsupported/unknown. */ 378 } 379 380 uint32_t r500_tx_format_msb_bit(enum pipe_format format) 381 { 382 switch (format) { 383 case PIPE_FORMAT_RGTC1_UNORM: 384 case PIPE_FORMAT_RGTC1_SNORM: 385 case PIPE_FORMAT_LATC1_UNORM: 386 case PIPE_FORMAT_LATC1_SNORM: 387 case PIPE_FORMAT_X8Z24_UNORM: 388 case PIPE_FORMAT_S8_UINT_Z24_UNORM: 389 return R500_TXFORMAT_MSB; 390 default: 391 return 0; 392 } 393 } 394 395 /* Buffer formats. */ 396 397 /* Colorbuffer formats. This is the unswizzled format of the RB3D block's 398 * output. For the swizzling of the targets, check the shader's format. */ 399 static uint32_t r300_translate_colorformat(enum pipe_format format) 400 { 401 switch (format) { 402 /* 8-bit buffers. */ 403 case PIPE_FORMAT_A8_UNORM: 404 case PIPE_FORMAT_A8_SNORM: 405 case PIPE_FORMAT_I8_UNORM: 406 case PIPE_FORMAT_I8_SNORM: 407 case PIPE_FORMAT_L8_UNORM: 408 case PIPE_FORMAT_L8_SNORM: 409 case PIPE_FORMAT_R8_UNORM: 410 case PIPE_FORMAT_R8_SNORM: 411 return R300_COLOR_FORMAT_I8; 412 413 /* 16-bit buffers. */ 414 case PIPE_FORMAT_L8A8_UNORM: 415 case PIPE_FORMAT_L8A8_SNORM: 416 case PIPE_FORMAT_R8G8_UNORM: 417 case PIPE_FORMAT_R8G8_SNORM: 418 /* These formats work fine with UV88 if US_OUT_FMT is set correctly. */ 419 case PIPE_FORMAT_A16_UNORM: 420 case PIPE_FORMAT_A16_SNORM: 421 case PIPE_FORMAT_A16_FLOAT: 422 case PIPE_FORMAT_L16_UNORM: 423 case PIPE_FORMAT_L16_SNORM: 424 case PIPE_FORMAT_L16_FLOAT: 425 case PIPE_FORMAT_I16_UNORM: 426 case PIPE_FORMAT_I16_SNORM: 427 case PIPE_FORMAT_I16_FLOAT: 428 case PIPE_FORMAT_R16_UNORM: 429 case PIPE_FORMAT_R16_SNORM: 430 case PIPE_FORMAT_R16_FLOAT: 431 return R300_COLOR_FORMAT_UV88; 432 433 case PIPE_FORMAT_B5G6R5_UNORM: 434 return R300_COLOR_FORMAT_RGB565; 435 436 case PIPE_FORMAT_B5G5R5A1_UNORM: 437 case PIPE_FORMAT_B5G5R5X1_UNORM: 438 return R300_COLOR_FORMAT_ARGB1555; 439 440 case PIPE_FORMAT_B4G4R4A4_UNORM: 441 case PIPE_FORMAT_B4G4R4X4_UNORM: 442 return R300_COLOR_FORMAT_ARGB4444; 443 444 /* 32-bit buffers. */ 445 case PIPE_FORMAT_B8G8R8A8_UNORM: 446 /*case PIPE_FORMAT_B8G8R8A8_SNORM:*/ 447 case PIPE_FORMAT_B8G8R8X8_UNORM: 448 /*case PIPE_FORMAT_B8G8R8X8_SNORM:*/ 449 case PIPE_FORMAT_R8G8B8A8_UNORM: 450 case PIPE_FORMAT_R8G8B8A8_SNORM: 451 case PIPE_FORMAT_R8G8B8X8_UNORM: 452 /*case PIPE_FORMAT_R8G8B8X8_SNORM:*/ 453 /* These formats work fine with ARGB8888 if US_OUT_FMT is set 454 * correctly. */ 455 case PIPE_FORMAT_R16G16_UNORM: 456 case PIPE_FORMAT_R16G16_SNORM: 457 case PIPE_FORMAT_R16G16_FLOAT: 458 case PIPE_FORMAT_L16A16_UNORM: 459 case PIPE_FORMAT_L16A16_SNORM: 460 case PIPE_FORMAT_L16A16_FLOAT: 461 case PIPE_FORMAT_A32_FLOAT: 462 case PIPE_FORMAT_L32_FLOAT: 463 case PIPE_FORMAT_I32_FLOAT: 464 case PIPE_FORMAT_R32_FLOAT: 465 return R300_COLOR_FORMAT_ARGB8888; 466 467 case PIPE_FORMAT_R10G10B10A2_UNORM: 468 case PIPE_FORMAT_R10G10B10X2_SNORM: 469 case PIPE_FORMAT_B10G10R10A2_UNORM: 470 return R500_COLOR_FORMAT_ARGB2101010; /* R5xx-only? */ 471 472 /* 64-bit buffers. */ 473 case PIPE_FORMAT_R16G16B16A16_UNORM: 474 case PIPE_FORMAT_R16G16B16A16_SNORM: 475 case PIPE_FORMAT_R16G16B16A16_FLOAT: 476 /* These formats work fine with ARGB16161616 if US_OUT_FMT is set 477 * correctly. */ 478 case PIPE_FORMAT_R32G32_FLOAT: 479 case PIPE_FORMAT_L32A32_FLOAT: 480 return R300_COLOR_FORMAT_ARGB16161616; 481 482 /* 128-bit buffers. */ 483 case PIPE_FORMAT_R32G32B32A32_FLOAT: 484 return R300_COLOR_FORMAT_ARGB32323232; 485 486 /* YUV buffers. */ 487 case PIPE_FORMAT_UYVY: 488 return R300_COLOR_FORMAT_YVYU; 489 case PIPE_FORMAT_YUYV: 490 return R300_COLOR_FORMAT_VYUY; 491 default: 492 return ~0; /* Unsupported. */ 493 } 494 } 495 496 /* Depthbuffer and stencilbuffer. Thankfully, we only support two flavors. */ 497 static uint32_t r300_translate_zsformat(enum pipe_format format) 498 { 499 switch (format) { 500 /* 16-bit depth, no stencil */ 501 case PIPE_FORMAT_Z16_UNORM: 502 return R300_DEPTHFORMAT_16BIT_INT_Z; 503 /* 24-bit depth, ignored stencil */ 504 case PIPE_FORMAT_X8Z24_UNORM: 505 /* 24-bit depth, 8-bit stencil */ 506 case PIPE_FORMAT_S8_UINT_Z24_UNORM: 507 return R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL; 508 default: 509 return ~0; /* Unsupported. */ 510 } 511 } 512 513 /* Shader output formats. This is essentially the swizzle from the shader 514 * to the RB3D block. 515 * 516 * Note that formats are stored from C3 to C0. */ 517 static uint32_t r300_translate_out_fmt(enum pipe_format format) 518 { 519 uint32_t modifier = 0; 520 unsigned i; 521 const struct util_format_description *desc; 522 boolean uniform_sign; 523 524 desc = util_format_description(format); 525 526 /* Find the first non-VOID channel. */ 527 for (i = 0; i < 4; i++) { 528 if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) { 529 break; 530 } 531 } 532 533 if (i == 4) 534 return ~0; /* Unsupported/unknown. */ 535 536 /* Specifies how the shader output is written to the fog unit. */ 537 switch (desc->channel[i].type) { 538 case UTIL_FORMAT_TYPE_FLOAT: 539 switch (desc->channel[i].size) { 540 case 32: 541 switch (desc->nr_channels) { 542 case 1: 543 modifier |= R300_US_OUT_FMT_C_32_FP; 544 break; 545 case 2: 546 modifier |= R300_US_OUT_FMT_C2_32_FP; 547 break; 548 case 4: 549 modifier |= R300_US_OUT_FMT_C4_32_FP; 550 break; 551 } 552 break; 553 554 case 16: 555 switch (desc->nr_channels) { 556 case 1: 557 modifier |= R300_US_OUT_FMT_C_16_FP; 558 break; 559 case 2: 560 modifier |= R300_US_OUT_FMT_C2_16_FP; 561 break; 562 case 4: 563 modifier |= R300_US_OUT_FMT_C4_16_FP; 564 break; 565 } 566 break; 567 } 568 break; 569 570 default: 571 switch (desc->channel[i].size) { 572 case 16: 573 switch (desc->nr_channels) { 574 case 1: 575 modifier |= R300_US_OUT_FMT_C_16; 576 break; 577 case 2: 578 modifier |= R300_US_OUT_FMT_C2_16; 579 break; 580 case 4: 581 modifier |= R300_US_OUT_FMT_C4_16; 582 break; 583 } 584 break; 585 586 case 10: 587 modifier |= R300_US_OUT_FMT_C4_10; 588 break; 589 590 default: 591 /* C4_8 seems to be used for the formats whose pixel size 592 * is <= 32 bits. */ 593 modifier |= R300_US_OUT_FMT_C4_8; 594 break; 595 } 596 } 597 598 /* Add sign. */ 599 uniform_sign = TRUE; 600 for (i = 0; i < desc->nr_channels; i++) 601 if (desc->channel[i].type != UTIL_FORMAT_TYPE_SIGNED) 602 uniform_sign = FALSE; 603 604 if (uniform_sign) 605 modifier |= R300_OUT_SIGN(0xf); 606 607 /* Add swizzles and return. */ 608 switch (format) { 609 /*** Special cases (non-standard channel mapping) ***/ 610 611 /* X8 612 * COLORFORMAT_I8 stores the Z component (C2). */ 613 case PIPE_FORMAT_A8_UNORM: 614 case PIPE_FORMAT_A8_SNORM: 615 return modifier | R300_C2_SEL_A; 616 case PIPE_FORMAT_I8_UNORM: 617 case PIPE_FORMAT_I8_SNORM: 618 case PIPE_FORMAT_L8_UNORM: 619 case PIPE_FORMAT_L8_SNORM: 620 case PIPE_FORMAT_R8_UNORM: 621 case PIPE_FORMAT_R8_SNORM: 622 return modifier | R300_C2_SEL_R; 623 624 /* X8Y8 625 * COLORFORMAT_UV88 stores ZX (C2 and C0). */ 626 case PIPE_FORMAT_L8A8_SNORM: 627 case PIPE_FORMAT_L8A8_UNORM: 628 return modifier | R300_C0_SEL_A | R300_C2_SEL_R; 629 case PIPE_FORMAT_R8G8_SNORM: 630 case PIPE_FORMAT_R8G8_UNORM: 631 return modifier | R300_C0_SEL_G | R300_C2_SEL_R; 632 633 /* X32Y32 634 * ARGB16161616 stores XZ for RG32F */ 635 case PIPE_FORMAT_R32G32_FLOAT: 636 return modifier | R300_C0_SEL_R | R300_C2_SEL_G; 637 638 /*** Generic cases (standard channel mapping) ***/ 639 640 /* BGRA outputs. */ 641 case PIPE_FORMAT_B5G6R5_UNORM: 642 case PIPE_FORMAT_B5G5R5A1_UNORM: 643 case PIPE_FORMAT_B5G5R5X1_UNORM: 644 case PIPE_FORMAT_B4G4R4A4_UNORM: 645 case PIPE_FORMAT_B4G4R4X4_UNORM: 646 case PIPE_FORMAT_B8G8R8A8_UNORM: 647 /*case PIPE_FORMAT_B8G8R8A8_SNORM:*/ 648 case PIPE_FORMAT_B8G8R8X8_UNORM: 649 /*case PIPE_FORMAT_B8G8R8X8_SNORM:*/ 650 case PIPE_FORMAT_B10G10R10A2_UNORM: 651 return modifier | 652 R300_C0_SEL_B | R300_C1_SEL_G | 653 R300_C2_SEL_R | R300_C3_SEL_A; 654 655 /* ARGB outputs. */ 656 case PIPE_FORMAT_A16_UNORM: 657 case PIPE_FORMAT_A16_SNORM: 658 case PIPE_FORMAT_A16_FLOAT: 659 case PIPE_FORMAT_A32_FLOAT: 660 return modifier | 661 R300_C0_SEL_A | R300_C1_SEL_R | 662 R300_C2_SEL_G | R300_C3_SEL_B; 663 664 /* RGBA outputs. */ 665 case PIPE_FORMAT_R8G8B8X8_UNORM: 666 /*case PIPE_FORMAT_R8G8B8X8_SNORM:*/ 667 case PIPE_FORMAT_R8G8B8A8_UNORM: 668 case PIPE_FORMAT_R8G8B8A8_SNORM: 669 case PIPE_FORMAT_R10G10B10A2_UNORM: 670 case PIPE_FORMAT_R10G10B10X2_SNORM: 671 case PIPE_FORMAT_R16_UNORM: 672 case PIPE_FORMAT_R16G16_UNORM: 673 case PIPE_FORMAT_R16G16B16A16_UNORM: 674 case PIPE_FORMAT_R16_SNORM: 675 case PIPE_FORMAT_R16G16_SNORM: 676 case PIPE_FORMAT_R16G16B16A16_SNORM: 677 case PIPE_FORMAT_R16_FLOAT: 678 case PIPE_FORMAT_R16G16_FLOAT: 679 case PIPE_FORMAT_R16G16B16A16_FLOAT: 680 case PIPE_FORMAT_R32_FLOAT: 681 case PIPE_FORMAT_R32G32B32A32_FLOAT: 682 case PIPE_FORMAT_L16_UNORM: 683 case PIPE_FORMAT_L16_SNORM: 684 case PIPE_FORMAT_L16_FLOAT: 685 case PIPE_FORMAT_L32_FLOAT: 686 case PIPE_FORMAT_I16_UNORM: 687 case PIPE_FORMAT_I16_SNORM: 688 case PIPE_FORMAT_I16_FLOAT: 689 case PIPE_FORMAT_I32_FLOAT: 690 return modifier | 691 R300_C0_SEL_R | R300_C1_SEL_G | 692 R300_C2_SEL_B | R300_C3_SEL_A; 693 694 /* LA outputs. */ 695 case PIPE_FORMAT_L16A16_UNORM: 696 case PIPE_FORMAT_L16A16_SNORM: 697 case PIPE_FORMAT_L16A16_FLOAT: 698 case PIPE_FORMAT_L32A32_FLOAT: 699 return modifier | 700 R300_C0_SEL_R | R300_C1_SEL_A; 701 702 default: 703 return ~0; /* Unsupported. */ 704 } 705 } 706 707 static uint32_t r300_translate_colormask_swizzle(enum pipe_format format) 708 { 709 switch (format) { 710 case PIPE_FORMAT_A8_UNORM: 711 case PIPE_FORMAT_A8_SNORM: 712 case PIPE_FORMAT_A16_UNORM: 713 case PIPE_FORMAT_A16_SNORM: 714 case PIPE_FORMAT_A16_FLOAT: 715 case PIPE_FORMAT_A32_FLOAT: 716 return COLORMASK_AAAA; 717 718 case PIPE_FORMAT_I8_UNORM: 719 case PIPE_FORMAT_I8_SNORM: 720 case PIPE_FORMAT_L8_UNORM: 721 case PIPE_FORMAT_L8_SNORM: 722 case PIPE_FORMAT_R8_UNORM: 723 case PIPE_FORMAT_R8_SNORM: 724 case PIPE_FORMAT_R32_FLOAT: 725 case PIPE_FORMAT_L32_FLOAT: 726 case PIPE_FORMAT_I32_FLOAT: 727 return COLORMASK_RRRR; 728 729 case PIPE_FORMAT_L8A8_SNORM: 730 case PIPE_FORMAT_L8A8_UNORM: 731 case PIPE_FORMAT_L16A16_UNORM: 732 case PIPE_FORMAT_L16A16_SNORM: 733 case PIPE_FORMAT_L16A16_FLOAT: 734 case PIPE_FORMAT_L32A32_FLOAT: 735 return COLORMASK_ARRA; 736 737 case PIPE_FORMAT_R8G8_SNORM: 738 case PIPE_FORMAT_R8G8_UNORM: 739 case PIPE_FORMAT_R16G16_UNORM: 740 case PIPE_FORMAT_R16G16_SNORM: 741 case PIPE_FORMAT_R16G16_FLOAT: 742 case PIPE_FORMAT_R32G32_FLOAT: 743 return COLORMASK_GRRG; 744 745 case PIPE_FORMAT_B5G6R5_UNORM: 746 case PIPE_FORMAT_B5G5R5A1_UNORM: 747 case PIPE_FORMAT_B5G5R5X1_UNORM: 748 case PIPE_FORMAT_B4G4R4A4_UNORM: 749 case PIPE_FORMAT_B4G4R4X4_UNORM: 750 case PIPE_FORMAT_B8G8R8A8_UNORM: 751 /*case PIPE_FORMAT_B8G8R8A8_SNORM:*/ 752 case PIPE_FORMAT_B8G8R8X8_UNORM: 753 /*case PIPE_FORMAT_B8G8R8X8_SNORM:*/ 754 case PIPE_FORMAT_B10G10R10A2_UNORM: 755 return COLORMASK_BGRA; 756 757 case PIPE_FORMAT_R8G8B8X8_UNORM: 758 /*case PIPE_FORMAT_R8G8B8X8_SNORM:*/ 759 case PIPE_FORMAT_R8G8B8A8_UNORM: 760 case PIPE_FORMAT_R8G8B8A8_SNORM: 761 case PIPE_FORMAT_R10G10B10A2_UNORM: 762 case PIPE_FORMAT_R10G10B10X2_SNORM: 763 case PIPE_FORMAT_R16_UNORM: 764 case PIPE_FORMAT_R16G16B16A16_UNORM: 765 case PIPE_FORMAT_R16_SNORM: 766 case PIPE_FORMAT_R16G16B16A16_SNORM: 767 case PIPE_FORMAT_R16_FLOAT: 768 case PIPE_FORMAT_R16G16B16A16_FLOAT: 769 case PIPE_FORMAT_R32G32B32A32_FLOAT: 770 case PIPE_FORMAT_L16_UNORM: 771 case PIPE_FORMAT_L16_SNORM: 772 case PIPE_FORMAT_L16_FLOAT: 773 case PIPE_FORMAT_I16_UNORM: 774 case PIPE_FORMAT_I16_SNORM: 775 case PIPE_FORMAT_I16_FLOAT: 776 return COLORMASK_RGBA; 777 778 default: 779 return ~0; /* Unsupported. */ 780 } 781 } 782 783 boolean r300_is_colorbuffer_format_supported(enum pipe_format format) 784 { 785 return r300_translate_colorformat(format) != ~0 && 786 r300_translate_out_fmt(format) != ~0 && 787 r300_translate_colormask_swizzle(format) != ~0; 788 } 789 790 boolean r300_is_zs_format_supported(enum pipe_format format) 791 { 792 return r300_translate_zsformat(format) != ~0; 793 } 794 795 boolean r300_is_sampler_format_supported(enum pipe_format format) 796 { 797 return r300_translate_texformat(format, 0, TRUE, FALSE) != ~0; 798 } 799 800 void r300_texture_setup_format_state(struct r300_screen *screen, 801 struct r300_resource *tex, 802 enum pipe_format format, 803 unsigned level, 804 unsigned width0_override, 805 unsigned height0_override, 806 struct r300_texture_format_state *out) 807 { 808 struct pipe_resource *pt = &tex->b.b; 809 struct r300_texture_desc *desc = &tex->tex; 810 boolean is_r500 = screen->caps.is_r500; 811 unsigned width, height, depth; 812 unsigned txwidth, txheight, txdepth; 813 814 width = u_minify(width0_override, level); 815 height = u_minify(height0_override, level); 816 depth = u_minify(desc->depth0, level); 817 818 txwidth = (width - 1) & 0x7ff; 819 txheight = (height - 1) & 0x7ff; 820 txdepth = util_logbase2(depth) & 0xf; 821 822 /* Mask out all the fields we change. */ 823 out->format0 = 0; 824 out->format1 &= ~R300_TX_FORMAT_TEX_COORD_TYPE_MASK; 825 out->format2 &= R500_TXFORMAT_MSB; 826 out->tile_config = 0; 827 828 /* Set sampler state. */ 829 out->format0 = 830 R300_TX_WIDTH(txwidth) | 831 R300_TX_HEIGHT(txheight) | 832 R300_TX_DEPTH(txdepth); 833 834 if (desc->uses_stride_addressing) { 835 unsigned stride = 836 r300_stride_to_width(format, desc->stride_in_bytes[level]); 837 /* rectangles love this */ 838 out->format0 |= R300_TX_PITCH_EN; 839 out->format2 = (stride - 1) & 0x1fff; 840 } 841 842 if (pt->target == PIPE_TEXTURE_CUBE) { 843 out->format1 |= R300_TX_FORMAT_CUBIC_MAP; 844 } 845 if (pt->target == PIPE_TEXTURE_3D) { 846 out->format1 |= R300_TX_FORMAT_3D; 847 } 848 849 /* large textures on r500 */ 850 if (is_r500) 851 { 852 unsigned us_width = txwidth; 853 unsigned us_height = txheight; 854 unsigned us_depth = txdepth; 855 856 if (width > 2048) { 857 out->format2 |= R500_TXWIDTH_BIT11; 858 } 859 if (height > 2048) { 860 out->format2 |= R500_TXHEIGHT_BIT11; 861 } 862 863 /* The US_FORMAT register fixes an R500 TX addressing bug. 864 * Don't ask why it must be set like this. I don't know it either. */ 865 if (width > 2048) { 866 us_width = (0x000007FF + us_width) >> 1; 867 us_depth |= 0x0000000D; 868 } 869 if (height > 2048) { 870 us_height = (0x000007FF + us_height) >> 1; 871 us_depth |= 0x0000000E; 872 } 873 874 out->us_format0 = 875 R300_TX_WIDTH(us_width) | 876 R300_TX_HEIGHT(us_height) | 877 R300_TX_DEPTH(us_depth); 878 } 879 880 out->tile_config = R300_TXO_MACRO_TILE(desc->macrotile[level]) | 881 R300_TXO_MICRO_TILE(desc->microtile); 882 } 883 884 static void r300_texture_setup_fb_state(struct r300_surface *surf) 885 { 886 struct r300_resource *tex = r300_resource(surf->base.texture); 887 unsigned level = surf->base.u.tex.level; 888 unsigned stride = 889 r300_stride_to_width(surf->base.format, tex->tex.stride_in_bytes[level]); 890 891 /* Set framebuffer state. */ 892 if (util_format_is_depth_or_stencil(surf->base.format)) { 893 surf->pitch = 894 stride | 895 R300_DEPTHMACROTILE(tex->tex.macrotile[level]) | 896 R300_DEPTHMICROTILE(tex->tex.microtile); 897 surf->format = r300_translate_zsformat(surf->base.format); 898 surf->pitch_zmask = tex->tex.zmask_stride_in_pixels[level]; 899 surf->pitch_hiz = tex->tex.hiz_stride_in_pixels[level]; 900 } else { 901 surf->pitch = 902 stride | 903 r300_translate_colorformat(surf->base.format) | 904 R300_COLOR_TILE(tex->tex.macrotile[level]) | 905 R300_COLOR_MICROTILE(tex->tex.microtile); 906 surf->format = r300_translate_out_fmt(surf->base.format); 907 surf->colormask_swizzle = 908 r300_translate_colormask_swizzle(surf->base.format); 909 } 910 } 911 912 static void r300_texture_destroy(struct pipe_screen *screen, 913 struct pipe_resource* texture) 914 { 915 struct r300_resource* tex = (struct r300_resource*)texture; 916 917 pb_reference(&tex->buf, NULL); 918 FREE(tex); 919 } 920 921 boolean r300_resource_get_handle(struct pipe_screen* screen, 922 struct pipe_resource *texture, 923 struct winsys_handle *whandle) 924 { 925 struct radeon_winsys *rws = r300_screen(screen)->rws; 926 struct r300_resource* tex = (struct r300_resource*)texture; 927 928 if (!tex) { 929 return FALSE; 930 } 931 932 return rws->buffer_get_handle(tex->buf, 933 tex->tex.stride_in_bytes[0], whandle); 934 } 935 936 static const struct u_resource_vtbl r300_texture_vtbl = 937 { 938 NULL, /* get_handle */ 939 r300_texture_destroy, /* resource_destroy */ 940 r300_texture_get_transfer, /* get_transfer */ 941 r300_texture_transfer_destroy, /* transfer_destroy */ 942 r300_texture_transfer_map, /* transfer_map */ 943 NULL, /* transfer_flush_region */ 944 r300_texture_transfer_unmap, /* transfer_unmap */ 945 NULL /* transfer_inline_write */ 946 }; 947 948 /* The common texture constructor. */ 949 static struct r300_resource* 950 r300_texture_create_object(struct r300_screen *rscreen, 951 const struct pipe_resource *base, 952 enum radeon_bo_layout microtile, 953 enum radeon_bo_layout macrotile, 954 unsigned stride_in_bytes_override, 955 struct pb_buffer *buffer) 956 { 957 struct radeon_winsys *rws = rscreen->rws; 958 struct r300_resource *tex = CALLOC_STRUCT(r300_resource); 959 if (!tex) { 960 if (buffer) 961 pb_reference(&buffer, NULL); 962 return NULL; 963 } 964 965 if (base->nr_samples > 1) 966 return NULL; 967 968 pipe_reference_init(&tex->b.b.reference, 1); 969 tex->b.b.screen = &rscreen->screen; 970 tex->b.b.usage = base->usage; 971 tex->b.b.bind = base->bind; 972 tex->b.b.flags = base->flags; 973 tex->b.vtbl = &r300_texture_vtbl; 974 tex->tex.microtile = microtile; 975 tex->tex.macrotile[0] = macrotile; 976 tex->tex.stride_in_bytes_override = stride_in_bytes_override; 977 tex->domain = base->flags & R300_RESOURCE_FLAG_TRANSFER ? 978 RADEON_DOMAIN_GTT : 979 RADEON_DOMAIN_VRAM | RADEON_DOMAIN_GTT; 980 tex->buf = buffer; 981 982 r300_texture_desc_init(rscreen, tex, base); 983 984 /* Create the backing buffer if needed. */ 985 if (!tex->buf) { 986 tex->buf = rws->buffer_create(rws, tex->tex.size_in_bytes, 2048, 987 base->bind, tex->domain); 988 989 if (!tex->buf) { 990 FREE(tex); 991 return NULL; 992 } 993 } 994 995 tex->cs_buf = rws->buffer_get_cs_handle(tex->buf); 996 997 rws->buffer_set_tiling(tex->buf, NULL, 998 tex->tex.microtile, tex->tex.macrotile[0], 999 0, 0, 0, 0, 0, 1000 tex->tex.stride_in_bytes[0]); 1001 1002 return tex; 1003 } 1004 1005 /* Create a new texture. */ 1006 struct pipe_resource *r300_texture_create(struct pipe_screen *screen, 1007 const struct pipe_resource *base) 1008 { 1009 struct r300_screen *rscreen = r300_screen(screen); 1010 enum radeon_bo_layout microtile, macrotile; 1011 1012 if ((base->flags & R300_RESOURCE_FLAG_TRANSFER) || 1013 (base->bind & PIPE_BIND_SCANOUT)) { 1014 microtile = RADEON_LAYOUT_LINEAR; 1015 macrotile = RADEON_LAYOUT_LINEAR; 1016 } else { 1017 /* This will make the texture_create_function select the layout. */ 1018 microtile = RADEON_LAYOUT_UNKNOWN; 1019 macrotile = RADEON_LAYOUT_UNKNOWN; 1020 } 1021 1022 return (struct pipe_resource*) 1023 r300_texture_create_object(rscreen, base, microtile, macrotile, 1024 0, NULL); 1025 } 1026 1027 struct pipe_resource *r300_texture_from_handle(struct pipe_screen *screen, 1028 const struct pipe_resource *base, 1029 struct winsys_handle *whandle) 1030 { 1031 struct r300_screen *rscreen = r300_screen(screen); 1032 struct radeon_winsys *rws = rscreen->rws; 1033 struct pb_buffer *buffer; 1034 enum radeon_bo_layout microtile, macrotile; 1035 unsigned stride; 1036 1037 /* Support only 2D textures without mipmaps */ 1038 if ((base->target != PIPE_TEXTURE_2D && 1039 base->target != PIPE_TEXTURE_RECT) || 1040 base->depth0 != 1 || 1041 base->last_level != 0) { 1042 return NULL; 1043 } 1044 1045 buffer = rws->buffer_from_handle(rws, whandle, &stride); 1046 if (!buffer) 1047 return NULL; 1048 1049 rws->buffer_get_tiling(buffer, µtile, ¯otile, NULL, NULL, NULL, NULL, NULL); 1050 1051 /* Enforce a microtiled zbuffer. */ 1052 if (util_format_is_depth_or_stencil(base->format) && 1053 microtile == RADEON_LAYOUT_LINEAR) { 1054 switch (util_format_get_blocksize(base->format)) { 1055 case 4: 1056 microtile = RADEON_LAYOUT_TILED; 1057 break; 1058 1059 case 2: 1060 microtile = RADEON_LAYOUT_SQUARETILED; 1061 break; 1062 } 1063 } 1064 1065 return (struct pipe_resource*) 1066 r300_texture_create_object(rscreen, base, microtile, macrotile, 1067 stride, buffer); 1068 } 1069 1070 /* Not required to implement u_resource_vtbl, consider moving to another file: 1071 */ 1072 struct pipe_surface* r300_create_surface_custom(struct pipe_context * ctx, 1073 struct pipe_resource* texture, 1074 const struct pipe_surface *surf_tmpl, 1075 unsigned width0_override, 1076 unsigned height0_override) 1077 { 1078 struct r300_resource* tex = r300_resource(texture); 1079 struct r300_surface* surface = CALLOC_STRUCT(r300_surface); 1080 unsigned level = surf_tmpl->u.tex.level; 1081 1082 assert(surf_tmpl->u.tex.first_layer == surf_tmpl->u.tex.last_layer); 1083 1084 if (surface) { 1085 uint32_t offset, tile_height; 1086 1087 pipe_reference_init(&surface->base.reference, 1); 1088 pipe_resource_reference(&surface->base.texture, texture); 1089 surface->base.context = ctx; 1090 surface->base.format = surf_tmpl->format; 1091 surface->base.width = u_minify(width0_override, level); 1092 surface->base.height = u_minify(height0_override, level); 1093 surface->base.usage = surf_tmpl->usage; 1094 surface->base.u.tex.level = level; 1095 surface->base.u.tex.first_layer = surf_tmpl->u.tex.first_layer; 1096 surface->base.u.tex.last_layer = surf_tmpl->u.tex.last_layer; 1097 1098 surface->buf = tex->buf; 1099 surface->cs_buf = tex->cs_buf; 1100 1101 /* Prefer VRAM if there are multiple domains to choose from. */ 1102 surface->domain = tex->domain; 1103 if (surface->domain & RADEON_DOMAIN_VRAM) 1104 surface->domain &= ~RADEON_DOMAIN_GTT; 1105 1106 surface->offset = r300_texture_get_offset(tex, level, 1107 surf_tmpl->u.tex.first_layer); 1108 r300_texture_setup_fb_state(surface); 1109 1110 /* Parameters for the CBZB clear. */ 1111 surface->cbzb_allowed = tex->tex.cbzb_allowed[level]; 1112 surface->cbzb_width = align(surface->base.width, 64); 1113 1114 /* Height must be aligned to the size of a tile. */ 1115 tile_height = r300_get_pixel_alignment(surface->base.format, 1116 tex->b.b.nr_samples, 1117 tex->tex.microtile, 1118 tex->tex.macrotile[level], 1119 DIM_HEIGHT, 0); 1120 1121 surface->cbzb_height = align((surface->base.height + 1) / 2, 1122 tile_height); 1123 1124 /* Offset must be aligned to 2K and must point at the beginning 1125 * of a scanline. */ 1126 offset = surface->offset + 1127 tex->tex.stride_in_bytes[level] * surface->cbzb_height; 1128 surface->cbzb_midpoint_offset = offset & ~2047; 1129 1130 surface->cbzb_pitch = surface->pitch & 0x1ffffc; 1131 1132 if (util_format_get_blocksizebits(surface->base.format) == 32) 1133 surface->cbzb_format = R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL; 1134 else 1135 surface->cbzb_format = R300_DEPTHFORMAT_16BIT_INT_Z; 1136 1137 DBG(r300_context(ctx), DBG_CBZB, 1138 "CBZB Allowed: %s, Dim: %ix%i, Misalignment: %i, Micro: %s, Macro: %s\n", 1139 surface->cbzb_allowed ? "YES" : " NO", 1140 surface->cbzb_width, surface->cbzb_height, 1141 offset & 2047, 1142 tex->tex.microtile ? "YES" : " NO", 1143 tex->tex.macrotile[level] ? "YES" : " NO"); 1144 } 1145 1146 return &surface->base; 1147 } 1148 1149 struct pipe_surface* r300_create_surface(struct pipe_context * ctx, 1150 struct pipe_resource* texture, 1151 const struct pipe_surface *surf_tmpl) 1152 { 1153 return r300_create_surface_custom(ctx, texture, surf_tmpl, 1154 texture->width0, 1155 texture->height0); 1156 } 1157 1158 /* Not required to implement u_resource_vtbl, consider moving to another file: 1159 */ 1160 void r300_surface_destroy(struct pipe_context *ctx, struct pipe_surface* s) 1161 { 1162 pipe_resource_reference(&s->texture, NULL); 1163 FREE(s); 1164 } 1165