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