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