1848b8605Smrg/* 2848b8605Smrg * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> 3848b8605Smrg * Copyright 2010 Marek Olšák <maraeo@gmail.com> 4848b8605Smrg * 5848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a 6848b8605Smrg * copy of this software and associated documentation files (the "Software"), 7848b8605Smrg * to deal in the Software without restriction, including without limitation 8848b8605Smrg * on the rights to use, copy, modify, merge, publish, distribute, sub 9848b8605Smrg * license, and/or sell copies of the Software, and to permit persons to whom 10848b8605Smrg * the Software is furnished to do so, subject to the following conditions: 11848b8605Smrg * 12848b8605Smrg * The above copyright notice and this permission notice (including the next 13848b8605Smrg * paragraph) shall be included in all copies or substantial portions of the 14848b8605Smrg * Software. 15848b8605Smrg * 16848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17848b8605Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 19848b8605Smrg * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 20848b8605Smrg * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 21848b8605Smrg * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 22848b8605Smrg * USE OR OTHER DEALINGS IN THE SOFTWARE. */ 23848b8605Smrg 24848b8605Smrg/* Always include headers in the reverse order!! ~ M. */ 25848b8605Smrg#include "r300_texture.h" 26848b8605Smrg 27848b8605Smrg#include "r300_context.h" 28848b8605Smrg#include "r300_reg.h" 29848b8605Smrg#include "r300_texture_desc.h" 30848b8605Smrg#include "r300_transfer.h" 31848b8605Smrg#include "r300_screen.h" 32848b8605Smrg 33848b8605Smrg#include "util/u_format.h" 34848b8605Smrg#include "util/u_format_s3tc.h" 35848b8605Smrg#include "util/u_math.h" 36848b8605Smrg#include "util/u_memory.h" 37848b8605Smrg 38848b8605Smrg#include "pipe/p_screen.h" 39848b8605Smrg 40b8e80941Smrg/* These formats are supported by swapping their bytes. 41b8e80941Smrg * The swizzles must be set exactly like their non-swapped counterparts, 42b8e80941Smrg * because byte-swapping is what reverses the component order, not swizzling. 43b8e80941Smrg * 44b8e80941Smrg * This function returns the format that must be used to program CB and TX 45b8e80941Smrg * swizzles. 46b8e80941Smrg */ 47b8e80941Smrgstatic enum pipe_format r300_unbyteswap_array_format(enum pipe_format format) 48b8e80941Smrg{ 49b8e80941Smrg /* FIXME: Disabled on little endian because of a reported regression: 50b8e80941Smrg * https://bugs.freedesktop.org/show_bug.cgi?id=98869 */ 51b8e80941Smrg if (PIPE_ENDIAN_NATIVE != PIPE_ENDIAN_BIG) 52b8e80941Smrg return format; 53b8e80941Smrg 54b8e80941Smrg /* Only BGRA 8888 array formats are supported for simplicity of 55b8e80941Smrg * the implementation. */ 56b8e80941Smrg switch (format) { 57b8e80941Smrg case PIPE_FORMAT_A8R8G8B8_UNORM: 58b8e80941Smrg return PIPE_FORMAT_B8G8R8A8_UNORM; 59b8e80941Smrg case PIPE_FORMAT_A8R8G8B8_SRGB: 60b8e80941Smrg return PIPE_FORMAT_B8G8R8A8_SRGB; 61b8e80941Smrg case PIPE_FORMAT_X8R8G8B8_UNORM: 62b8e80941Smrg return PIPE_FORMAT_B8G8R8X8_UNORM; 63b8e80941Smrg case PIPE_FORMAT_X8R8G8B8_SRGB: 64b8e80941Smrg return PIPE_FORMAT_B8G8R8X8_SRGB; 65b8e80941Smrg default: 66b8e80941Smrg return format; 67b8e80941Smrg } 68b8e80941Smrg} 69b8e80941Smrg 70b8e80941Smrgstatic unsigned r300_get_endian_swap(enum pipe_format format) 71b8e80941Smrg{ 72b8e80941Smrg const struct util_format_description *desc; 73b8e80941Smrg unsigned swap_size; 74b8e80941Smrg 75b8e80941Smrg if (r300_unbyteswap_array_format(format) != format) 76b8e80941Smrg return R300_SURF_DWORD_SWAP; 77b8e80941Smrg 78b8e80941Smrg if (PIPE_ENDIAN_NATIVE != PIPE_ENDIAN_BIG) 79b8e80941Smrg return R300_SURF_NO_SWAP; 80b8e80941Smrg 81b8e80941Smrg desc = util_format_description(format); 82b8e80941Smrg if (!desc) 83b8e80941Smrg return R300_SURF_NO_SWAP; 84b8e80941Smrg 85b8e80941Smrg /* Compressed formats should be in the little endian format. */ 86b8e80941Smrg if (desc->block.width != 1 || desc->block.height != 1) 87b8e80941Smrg return R300_SURF_NO_SWAP; 88b8e80941Smrg 89b8e80941Smrg swap_size = desc->is_array ? desc->channel[0].size : desc->block.bits; 90b8e80941Smrg 91b8e80941Smrg switch (swap_size) { 92b8e80941Smrg default: /* shouldn't happen? */ 93b8e80941Smrg case 8: 94b8e80941Smrg return R300_SURF_NO_SWAP; 95b8e80941Smrg case 16: 96b8e80941Smrg return R300_SURF_WORD_SWAP; 97b8e80941Smrg case 32: 98b8e80941Smrg return R300_SURF_DWORD_SWAP; 99b8e80941Smrg } 100b8e80941Smrg} 101b8e80941Smrg 102848b8605Smrgunsigned r300_get_swizzle_combined(const unsigned char *swizzle_format, 103848b8605Smrg const unsigned char *swizzle_view, 104848b8605Smrg boolean dxtc_swizzle) 105848b8605Smrg{ 106848b8605Smrg unsigned i; 107848b8605Smrg unsigned char swizzle[4]; 108848b8605Smrg unsigned result = 0; 109848b8605Smrg const uint32_t swizzle_shift[4] = { 110848b8605Smrg R300_TX_FORMAT_R_SHIFT, 111848b8605Smrg R300_TX_FORMAT_G_SHIFT, 112848b8605Smrg R300_TX_FORMAT_B_SHIFT, 113848b8605Smrg R300_TX_FORMAT_A_SHIFT 114848b8605Smrg }; 115848b8605Smrg uint32_t swizzle_bit[4] = { 116848b8605Smrg dxtc_swizzle ? R300_TX_FORMAT_Z : R300_TX_FORMAT_X, 117848b8605Smrg R300_TX_FORMAT_Y, 118848b8605Smrg dxtc_swizzle ? R300_TX_FORMAT_X : R300_TX_FORMAT_Z, 119848b8605Smrg R300_TX_FORMAT_W 120848b8605Smrg }; 121848b8605Smrg 122848b8605Smrg if (swizzle_view) { 123848b8605Smrg /* Combine two sets of swizzles. */ 124848b8605Smrg util_format_compose_swizzles(swizzle_format, swizzle_view, swizzle); 125848b8605Smrg } else { 126848b8605Smrg memcpy(swizzle, swizzle_format, 4); 127848b8605Smrg } 128848b8605Smrg 129848b8605Smrg /* Get swizzle. */ 130848b8605Smrg for (i = 0; i < 4; i++) { 131848b8605Smrg switch (swizzle[i]) { 132b8e80941Smrg case PIPE_SWIZZLE_Y: 133848b8605Smrg result |= swizzle_bit[1] << swizzle_shift[i]; 134848b8605Smrg break; 135b8e80941Smrg case PIPE_SWIZZLE_Z: 136848b8605Smrg result |= swizzle_bit[2] << swizzle_shift[i]; 137848b8605Smrg break; 138b8e80941Smrg case PIPE_SWIZZLE_W: 139848b8605Smrg result |= swizzle_bit[3] << swizzle_shift[i]; 140848b8605Smrg break; 141b8e80941Smrg case PIPE_SWIZZLE_0: 142848b8605Smrg result |= R300_TX_FORMAT_ZERO << swizzle_shift[i]; 143848b8605Smrg break; 144b8e80941Smrg case PIPE_SWIZZLE_1: 145848b8605Smrg result |= R300_TX_FORMAT_ONE << swizzle_shift[i]; 146848b8605Smrg break; 147b8e80941Smrg default: /* PIPE_SWIZZLE_X */ 148848b8605Smrg result |= swizzle_bit[0] << swizzle_shift[i]; 149848b8605Smrg } 150848b8605Smrg } 151848b8605Smrg return result; 152848b8605Smrg} 153848b8605Smrg 154848b8605Smrg/* Translate a pipe_format into a useful texture format for sampling. 155848b8605Smrg * 156848b8605Smrg * Some special formats are translated directly using R300_EASY_TX_FORMAT, 157848b8605Smrg * but the majority of them is translated in a generic way, automatically 158848b8605Smrg * supporting all the formats hw can support. 159848b8605Smrg * 160848b8605Smrg * R300_EASY_TX_FORMAT swizzles the texture. 161848b8605Smrg * Note the signature of R300_EASY_TX_FORMAT: 162848b8605Smrg * R300_EASY_TX_FORMAT(B, G, R, A, FORMAT); 163848b8605Smrg * 164848b8605Smrg * The FORMAT specifies how the texture sampler will treat the texture, and 165848b8605Smrg * makes available X, Y, Z, W, ZERO, and ONE for swizzling. */ 166848b8605Smrguint32_t r300_translate_texformat(enum pipe_format format, 167848b8605Smrg const unsigned char *swizzle_view, 168848b8605Smrg boolean is_r500, 169848b8605Smrg boolean dxtc_swizzle) 170848b8605Smrg{ 171848b8605Smrg uint32_t result = 0; 172848b8605Smrg const struct util_format_description *desc; 173848b8605Smrg unsigned i; 174848b8605Smrg boolean uniform = TRUE; 175848b8605Smrg const uint32_t sign_bit[4] = { 176848b8605Smrg R300_TX_FORMAT_SIGNED_W, 177848b8605Smrg R300_TX_FORMAT_SIGNED_Z, 178848b8605Smrg R300_TX_FORMAT_SIGNED_Y, 179848b8605Smrg R300_TX_FORMAT_SIGNED_X, 180848b8605Smrg }; 181848b8605Smrg 182b8e80941Smrg format = r300_unbyteswap_array_format(format); 183848b8605Smrg desc = util_format_description(format); 184848b8605Smrg 185848b8605Smrg /* Colorspace (return non-RGB formats directly). */ 186848b8605Smrg switch (desc->colorspace) { 187848b8605Smrg /* Depth stencil formats. 188848b8605Smrg * Swizzles are added in r300_merge_textures_and_samplers. */ 189848b8605Smrg case UTIL_FORMAT_COLORSPACE_ZS: 190848b8605Smrg switch (format) { 191848b8605Smrg case PIPE_FORMAT_Z16_UNORM: 192848b8605Smrg return R300_TX_FORMAT_X16; 193848b8605Smrg case PIPE_FORMAT_X8Z24_UNORM: 194848b8605Smrg case PIPE_FORMAT_S8_UINT_Z24_UNORM: 195848b8605Smrg if (is_r500) 196848b8605Smrg return R500_TX_FORMAT_Y8X24; 197848b8605Smrg else 198848b8605Smrg return R300_TX_FORMAT_Y16X16; 199848b8605Smrg default: 200848b8605Smrg return ~0; /* Unsupported. */ 201848b8605Smrg } 202848b8605Smrg 203848b8605Smrg /* YUV formats. */ 204848b8605Smrg case UTIL_FORMAT_COLORSPACE_YUV: 205848b8605Smrg result |= R300_TX_FORMAT_YUV_TO_RGB; 206848b8605Smrg 207848b8605Smrg switch (format) { 208848b8605Smrg case PIPE_FORMAT_UYVY: 209848b8605Smrg return R300_EASY_TX_FORMAT(X, Y, Z, ONE, YVYU422) | result; 210848b8605Smrg case PIPE_FORMAT_YUYV: 211848b8605Smrg return R300_EASY_TX_FORMAT(X, Y, Z, ONE, VYUY422) | result; 212848b8605Smrg default: 213848b8605Smrg return ~0; /* Unsupported/unknown. */ 214848b8605Smrg } 215848b8605Smrg 216848b8605Smrg /* Add gamma correction. */ 217848b8605Smrg case UTIL_FORMAT_COLORSPACE_SRGB: 218848b8605Smrg result |= R300_TX_FORMAT_GAMMA; 219848b8605Smrg break; 220848b8605Smrg 221848b8605Smrg default: 222848b8605Smrg switch (format) { 223848b8605Smrg /* Same as YUV but without the YUR->RGB conversion. */ 224848b8605Smrg case PIPE_FORMAT_R8G8_B8G8_UNORM: 225848b8605Smrg return R300_EASY_TX_FORMAT(X, Y, Z, ONE, YVYU422) | result; 226848b8605Smrg case PIPE_FORMAT_G8R8_G8B8_UNORM: 227848b8605Smrg return R300_EASY_TX_FORMAT(X, Y, Z, ONE, VYUY422) | result; 228848b8605Smrg default:; 229848b8605Smrg } 230848b8605Smrg } 231848b8605Smrg 232848b8605Smrg /* Add swizzling. */ 233848b8605Smrg /* The RGTC1_SNORM and LATC1_SNORM swizzle is done in the shader. */ 234b8e80941Smrg if (util_format_is_compressed(format) && 235b8e80941Smrg dxtc_swizzle && 236b8e80941Smrg format != PIPE_FORMAT_RGTC2_UNORM && 237b8e80941Smrg format != PIPE_FORMAT_RGTC2_SNORM && 238b8e80941Smrg format != PIPE_FORMAT_LATC2_UNORM && 239b8e80941Smrg format != PIPE_FORMAT_LATC2_SNORM && 240b8e80941Smrg format != PIPE_FORMAT_RGTC1_UNORM && 241b8e80941Smrg format != PIPE_FORMAT_RGTC1_SNORM && 242b8e80941Smrg format != PIPE_FORMAT_LATC1_UNORM && 243848b8605Smrg format != PIPE_FORMAT_LATC1_SNORM) { 244b8e80941Smrg result |= r300_get_swizzle_combined(desc->swizzle, swizzle_view, 245b8e80941Smrg TRUE); 246b8e80941Smrg } else { 247b8e80941Smrg result |= r300_get_swizzle_combined(desc->swizzle, swizzle_view, 248b8e80941Smrg FALSE); 249848b8605Smrg } 250848b8605Smrg 251848b8605Smrg /* S3TC formats. */ 252848b8605Smrg if (desc->layout == UTIL_FORMAT_LAYOUT_S3TC) { 253848b8605Smrg switch (format) { 254848b8605Smrg case PIPE_FORMAT_DXT1_RGB: 255848b8605Smrg case PIPE_FORMAT_DXT1_RGBA: 256848b8605Smrg case PIPE_FORMAT_DXT1_SRGB: 257848b8605Smrg case PIPE_FORMAT_DXT1_SRGBA: 258848b8605Smrg return R300_TX_FORMAT_DXT1 | result; 259848b8605Smrg case PIPE_FORMAT_DXT3_RGBA: 260848b8605Smrg case PIPE_FORMAT_DXT3_SRGBA: 261848b8605Smrg return R300_TX_FORMAT_DXT3 | result; 262848b8605Smrg case PIPE_FORMAT_DXT5_RGBA: 263848b8605Smrg case PIPE_FORMAT_DXT5_SRGBA: 264848b8605Smrg return R300_TX_FORMAT_DXT5 | result; 265848b8605Smrg default: 266848b8605Smrg return ~0; /* Unsupported/unknown. */ 267848b8605Smrg } 268848b8605Smrg } 269848b8605Smrg 270848b8605Smrg /* RGTC formats. */ 271848b8605Smrg if (desc->layout == UTIL_FORMAT_LAYOUT_RGTC) { 272848b8605Smrg switch (format) { 273848b8605Smrg case PIPE_FORMAT_RGTC1_SNORM: 274848b8605Smrg case PIPE_FORMAT_LATC1_SNORM: 275b8e80941Smrg result |= sign_bit[0]; 276848b8605Smrg case PIPE_FORMAT_LATC1_UNORM: 277848b8605Smrg case PIPE_FORMAT_RGTC1_UNORM: 278848b8605Smrg return R500_TX_FORMAT_ATI1N | result; 279848b8605Smrg 280848b8605Smrg case PIPE_FORMAT_RGTC2_SNORM: 281848b8605Smrg case PIPE_FORMAT_LATC2_SNORM: 282848b8605Smrg result |= sign_bit[1] | sign_bit[0]; 283848b8605Smrg case PIPE_FORMAT_RGTC2_UNORM: 284848b8605Smrg case PIPE_FORMAT_LATC2_UNORM: 285848b8605Smrg return R400_TX_FORMAT_ATI2N | result; 286848b8605Smrg 287848b8605Smrg default: 288848b8605Smrg return ~0; /* Unsupported/unknown. */ 289848b8605Smrg } 290848b8605Smrg } 291848b8605Smrg 292848b8605Smrg /* This is truly a special format. 293848b8605Smrg * It stores R8G8 and B is computed using sqrt(1 - R^2 - G^2) 294848b8605Smrg * in the sampler unit. Also known as D3DFMT_CxV8U8. */ 295848b8605Smrg if (format == PIPE_FORMAT_R8G8Bx_SNORM) { 296848b8605Smrg return R300_TX_FORMAT_CxV8U8 | result; 297848b8605Smrg } 298848b8605Smrg 299848b8605Smrg /* Integer and fixed-point 16.16 textures are not supported. */ 300848b8605Smrg for (i = 0; i < 4; i++) { 301848b8605Smrg if (desc->channel[i].type == UTIL_FORMAT_TYPE_FIXED || 302848b8605Smrg ((desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED || 303848b8605Smrg desc->channel[i].type == UTIL_FORMAT_TYPE_UNSIGNED) && 304848b8605Smrg (!desc->channel[i].normalized || 305848b8605Smrg desc->channel[i].pure_integer))) { 306848b8605Smrg return ~0; /* Unsupported/unknown. */ 307848b8605Smrg } 308848b8605Smrg } 309848b8605Smrg 310848b8605Smrg /* Add sign. */ 311848b8605Smrg for (i = 0; i < desc->nr_channels; i++) { 312848b8605Smrg if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED) { 313848b8605Smrg result |= sign_bit[i]; 314848b8605Smrg } 315848b8605Smrg } 316848b8605Smrg 317848b8605Smrg /* See whether the components are of the same size. */ 318848b8605Smrg for (i = 1; i < desc->nr_channels; i++) { 319848b8605Smrg uniform = uniform && desc->channel[0].size == desc->channel[i].size; 320848b8605Smrg } 321848b8605Smrg 322848b8605Smrg /* Non-uniform formats. */ 323848b8605Smrg if (!uniform) { 324848b8605Smrg switch (desc->nr_channels) { 325848b8605Smrg case 3: 326848b8605Smrg if (desc->channel[0].size == 5 && 327848b8605Smrg desc->channel[1].size == 6 && 328848b8605Smrg desc->channel[2].size == 5) { 329848b8605Smrg return R300_TX_FORMAT_Z5Y6X5 | result; 330848b8605Smrg } 331848b8605Smrg if (desc->channel[0].size == 5 && 332848b8605Smrg desc->channel[1].size == 5 && 333848b8605Smrg desc->channel[2].size == 6) { 334848b8605Smrg return R300_TX_FORMAT_Z6Y5X5 | result; 335848b8605Smrg } 336848b8605Smrg if (desc->channel[0].size == 2 && 337848b8605Smrg desc->channel[1].size == 3 && 338848b8605Smrg desc->channel[2].size == 3) { 339848b8605Smrg return R300_TX_FORMAT_Z3Y3X2 | result; 340848b8605Smrg } 341848b8605Smrg return ~0; /* Unsupported/unknown. */ 342848b8605Smrg 343848b8605Smrg case 4: 344848b8605Smrg if (desc->channel[0].size == 5 && 345848b8605Smrg desc->channel[1].size == 5 && 346848b8605Smrg desc->channel[2].size == 5 && 347848b8605Smrg desc->channel[3].size == 1) { 348848b8605Smrg return R300_TX_FORMAT_W1Z5Y5X5 | result; 349848b8605Smrg } 350848b8605Smrg if (desc->channel[0].size == 10 && 351848b8605Smrg desc->channel[1].size == 10 && 352848b8605Smrg desc->channel[2].size == 10 && 353848b8605Smrg desc->channel[3].size == 2) { 354848b8605Smrg return R300_TX_FORMAT_W2Z10Y10X10 | result; 355848b8605Smrg } 356848b8605Smrg } 357848b8605Smrg return ~0; /* Unsupported/unknown. */ 358848b8605Smrg } 359848b8605Smrg 360848b8605Smrg /* Find the first non-VOID channel. */ 361848b8605Smrg for (i = 0; i < 4; i++) { 362848b8605Smrg if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) { 363848b8605Smrg break; 364848b8605Smrg } 365848b8605Smrg } 366848b8605Smrg 367848b8605Smrg if (i == 4) 368848b8605Smrg return ~0; /* Unsupported/unknown. */ 369848b8605Smrg 370848b8605Smrg /* And finally, uniform formats. */ 371848b8605Smrg switch (desc->channel[i].type) { 372848b8605Smrg case UTIL_FORMAT_TYPE_UNSIGNED: 373848b8605Smrg case UTIL_FORMAT_TYPE_SIGNED: 374848b8605Smrg if (!desc->channel[i].normalized && 375848b8605Smrg desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB) { 376848b8605Smrg return ~0; 377848b8605Smrg } 378848b8605Smrg 379848b8605Smrg switch (desc->channel[i].size) { 380848b8605Smrg case 4: 381848b8605Smrg switch (desc->nr_channels) { 382848b8605Smrg case 2: 383848b8605Smrg return R300_TX_FORMAT_Y4X4 | result; 384848b8605Smrg case 4: 385848b8605Smrg return R300_TX_FORMAT_W4Z4Y4X4 | result; 386848b8605Smrg } 387848b8605Smrg return ~0; 388848b8605Smrg 389848b8605Smrg case 8: 390848b8605Smrg switch (desc->nr_channels) { 391848b8605Smrg case 1: 392848b8605Smrg return R300_TX_FORMAT_X8 | result; 393848b8605Smrg case 2: 394848b8605Smrg return R300_TX_FORMAT_Y8X8 | result; 395848b8605Smrg case 4: 396848b8605Smrg return R300_TX_FORMAT_W8Z8Y8X8 | result; 397848b8605Smrg } 398848b8605Smrg return ~0; 399848b8605Smrg 400848b8605Smrg case 16: 401848b8605Smrg switch (desc->nr_channels) { 402848b8605Smrg case 1: 403848b8605Smrg return R300_TX_FORMAT_X16 | result; 404848b8605Smrg case 2: 405848b8605Smrg return R300_TX_FORMAT_Y16X16 | result; 406848b8605Smrg case 4: 407848b8605Smrg return R300_TX_FORMAT_W16Z16Y16X16 | result; 408848b8605Smrg } 409848b8605Smrg } 410848b8605Smrg return ~0; 411848b8605Smrg 412848b8605Smrg case UTIL_FORMAT_TYPE_FLOAT: 413848b8605Smrg switch (desc->channel[i].size) { 414848b8605Smrg case 16: 415848b8605Smrg switch (desc->nr_channels) { 416848b8605Smrg case 1: 417848b8605Smrg return R300_TX_FORMAT_16F | result; 418848b8605Smrg case 2: 419848b8605Smrg return R300_TX_FORMAT_16F_16F | result; 420848b8605Smrg case 4: 421848b8605Smrg return R300_TX_FORMAT_16F_16F_16F_16F | result; 422848b8605Smrg } 423848b8605Smrg return ~0; 424848b8605Smrg 425848b8605Smrg case 32: 426848b8605Smrg switch (desc->nr_channels) { 427848b8605Smrg case 1: 428848b8605Smrg return R300_TX_FORMAT_32F | result; 429848b8605Smrg case 2: 430848b8605Smrg return R300_TX_FORMAT_32F_32F | result; 431848b8605Smrg case 4: 432848b8605Smrg return R300_TX_FORMAT_32F_32F_32F_32F | result; 433848b8605Smrg } 434848b8605Smrg } 435848b8605Smrg } 436848b8605Smrg 437848b8605Smrg return ~0; /* Unsupported/unknown. */ 438848b8605Smrg} 439848b8605Smrg 440848b8605Smrguint32_t r500_tx_format_msb_bit(enum pipe_format format) 441848b8605Smrg{ 442848b8605Smrg switch (format) { 443848b8605Smrg case PIPE_FORMAT_RGTC1_UNORM: 444848b8605Smrg case PIPE_FORMAT_RGTC1_SNORM: 445848b8605Smrg case PIPE_FORMAT_LATC1_UNORM: 446848b8605Smrg case PIPE_FORMAT_LATC1_SNORM: 447848b8605Smrg case PIPE_FORMAT_X8Z24_UNORM: 448848b8605Smrg case PIPE_FORMAT_S8_UINT_Z24_UNORM: 449848b8605Smrg return R500_TXFORMAT_MSB; 450848b8605Smrg default: 451848b8605Smrg return 0; 452848b8605Smrg } 453848b8605Smrg} 454848b8605Smrg 455848b8605Smrg/* Buffer formats. */ 456848b8605Smrg 457848b8605Smrg/* Colorbuffer formats. This is the unswizzled format of the RB3D block's 458848b8605Smrg * output. For the swizzling of the targets, check the shader's format. */ 459848b8605Smrgstatic uint32_t r300_translate_colorformat(enum pipe_format format) 460848b8605Smrg{ 461b8e80941Smrg format = r300_unbyteswap_array_format(format); 462b8e80941Smrg 463848b8605Smrg switch (format) { 464848b8605Smrg /* 8-bit buffers. */ 465848b8605Smrg case PIPE_FORMAT_A8_UNORM: 466848b8605Smrg case PIPE_FORMAT_A8_SNORM: 467848b8605Smrg case PIPE_FORMAT_I8_UNORM: 468848b8605Smrg case PIPE_FORMAT_I8_SNORM: 469848b8605Smrg case PIPE_FORMAT_L8_UNORM: 470848b8605Smrg case PIPE_FORMAT_L8_SNORM: 471848b8605Smrg case PIPE_FORMAT_R8_UNORM: 472848b8605Smrg case PIPE_FORMAT_R8_SNORM: 473848b8605Smrg return R300_COLOR_FORMAT_I8; 474848b8605Smrg 475848b8605Smrg /* 16-bit buffers. */ 476848b8605Smrg case PIPE_FORMAT_L8A8_UNORM: 477848b8605Smrg case PIPE_FORMAT_L8A8_SNORM: 478848b8605Smrg case PIPE_FORMAT_R8G8_UNORM: 479848b8605Smrg case PIPE_FORMAT_R8G8_SNORM: 480848b8605Smrg case PIPE_FORMAT_R8A8_UNORM: 481848b8605Smrg case PIPE_FORMAT_R8A8_SNORM: 482848b8605Smrg /* These formats work fine with UV88 if US_OUT_FMT is set correctly. */ 483848b8605Smrg case PIPE_FORMAT_A16_UNORM: 484848b8605Smrg case PIPE_FORMAT_A16_SNORM: 485848b8605Smrg case PIPE_FORMAT_A16_FLOAT: 486848b8605Smrg case PIPE_FORMAT_L16_UNORM: 487848b8605Smrg case PIPE_FORMAT_L16_SNORM: 488848b8605Smrg case PIPE_FORMAT_L16_FLOAT: 489848b8605Smrg case PIPE_FORMAT_I16_UNORM: 490848b8605Smrg case PIPE_FORMAT_I16_SNORM: 491848b8605Smrg case PIPE_FORMAT_I16_FLOAT: 492848b8605Smrg case PIPE_FORMAT_R16_UNORM: 493848b8605Smrg case PIPE_FORMAT_R16_SNORM: 494848b8605Smrg case PIPE_FORMAT_R16_FLOAT: 495848b8605Smrg return R300_COLOR_FORMAT_UV88; 496848b8605Smrg 497848b8605Smrg case PIPE_FORMAT_B5G6R5_UNORM: 498848b8605Smrg return R300_COLOR_FORMAT_RGB565; 499848b8605Smrg 500848b8605Smrg case PIPE_FORMAT_B5G5R5A1_UNORM: 501848b8605Smrg case PIPE_FORMAT_B5G5R5X1_UNORM: 502848b8605Smrg return R300_COLOR_FORMAT_ARGB1555; 503848b8605Smrg 504848b8605Smrg case PIPE_FORMAT_B4G4R4A4_UNORM: 505848b8605Smrg case PIPE_FORMAT_B4G4R4X4_UNORM: 506848b8605Smrg return R300_COLOR_FORMAT_ARGB4444; 507848b8605Smrg 508848b8605Smrg /* 32-bit buffers. */ 509848b8605Smrg case PIPE_FORMAT_B8G8R8A8_UNORM: 510848b8605Smrg /*case PIPE_FORMAT_B8G8R8A8_SNORM:*/ 511848b8605Smrg case PIPE_FORMAT_B8G8R8X8_UNORM: 512848b8605Smrg /*case PIPE_FORMAT_B8G8R8X8_SNORM:*/ 513848b8605Smrg case PIPE_FORMAT_R8G8B8A8_UNORM: 514848b8605Smrg case PIPE_FORMAT_R8G8B8A8_SNORM: 515848b8605Smrg case PIPE_FORMAT_R8G8B8X8_UNORM: 516848b8605Smrg case PIPE_FORMAT_R8G8B8X8_SNORM: 517848b8605Smrg /* These formats work fine with ARGB8888 if US_OUT_FMT is set 518848b8605Smrg * correctly. */ 519848b8605Smrg case PIPE_FORMAT_R16G16_UNORM: 520848b8605Smrg case PIPE_FORMAT_R16G16_SNORM: 521848b8605Smrg case PIPE_FORMAT_R16G16_FLOAT: 522848b8605Smrg case PIPE_FORMAT_L16A16_UNORM: 523848b8605Smrg case PIPE_FORMAT_L16A16_SNORM: 524848b8605Smrg case PIPE_FORMAT_L16A16_FLOAT: 525848b8605Smrg case PIPE_FORMAT_R16A16_UNORM: 526848b8605Smrg case PIPE_FORMAT_R16A16_SNORM: 527848b8605Smrg case PIPE_FORMAT_R16A16_FLOAT: 528848b8605Smrg case PIPE_FORMAT_A32_FLOAT: 529848b8605Smrg case PIPE_FORMAT_L32_FLOAT: 530848b8605Smrg case PIPE_FORMAT_I32_FLOAT: 531848b8605Smrg case PIPE_FORMAT_R32_FLOAT: 532848b8605Smrg return R300_COLOR_FORMAT_ARGB8888; 533848b8605Smrg 534848b8605Smrg case PIPE_FORMAT_R10G10B10A2_UNORM: 535848b8605Smrg case PIPE_FORMAT_R10G10B10X2_SNORM: 536848b8605Smrg case PIPE_FORMAT_B10G10R10A2_UNORM: 537848b8605Smrg case PIPE_FORMAT_B10G10R10X2_UNORM: 538848b8605Smrg return R500_COLOR_FORMAT_ARGB2101010; /* R5xx-only? */ 539848b8605Smrg 540848b8605Smrg /* 64-bit buffers. */ 541848b8605Smrg case PIPE_FORMAT_R16G16B16A16_UNORM: 542848b8605Smrg case PIPE_FORMAT_R16G16B16A16_SNORM: 543848b8605Smrg case PIPE_FORMAT_R16G16B16A16_FLOAT: 544848b8605Smrg case PIPE_FORMAT_R16G16B16X16_UNORM: 545848b8605Smrg case PIPE_FORMAT_R16G16B16X16_SNORM: 546848b8605Smrg case PIPE_FORMAT_R16G16B16X16_FLOAT: 547848b8605Smrg /* These formats work fine with ARGB16161616 if US_OUT_FMT is set 548848b8605Smrg * correctly. */ 549848b8605Smrg case PIPE_FORMAT_R32G32_FLOAT: 550848b8605Smrg case PIPE_FORMAT_L32A32_FLOAT: 551848b8605Smrg case PIPE_FORMAT_R32A32_FLOAT: 552848b8605Smrg return R300_COLOR_FORMAT_ARGB16161616; 553848b8605Smrg 554848b8605Smrg /* 128-bit buffers. */ 555848b8605Smrg case PIPE_FORMAT_R32G32B32A32_FLOAT: 556848b8605Smrg case PIPE_FORMAT_R32G32B32X32_FLOAT: 557848b8605Smrg return R300_COLOR_FORMAT_ARGB32323232; 558848b8605Smrg 559848b8605Smrg /* YUV buffers. */ 560848b8605Smrg case PIPE_FORMAT_UYVY: 561848b8605Smrg return R300_COLOR_FORMAT_YVYU; 562848b8605Smrg case PIPE_FORMAT_YUYV: 563848b8605Smrg return R300_COLOR_FORMAT_VYUY; 564848b8605Smrg default: 565848b8605Smrg return ~0; /* Unsupported. */ 566848b8605Smrg } 567848b8605Smrg} 568848b8605Smrg 569848b8605Smrg/* Depthbuffer and stencilbuffer. Thankfully, we only support two flavors. */ 570848b8605Smrgstatic uint32_t r300_translate_zsformat(enum pipe_format format) 571848b8605Smrg{ 572848b8605Smrg switch (format) { 573848b8605Smrg /* 16-bit depth, no stencil */ 574848b8605Smrg case PIPE_FORMAT_Z16_UNORM: 575848b8605Smrg return R300_DEPTHFORMAT_16BIT_INT_Z; 576848b8605Smrg /* 24-bit depth, ignored stencil */ 577848b8605Smrg case PIPE_FORMAT_X8Z24_UNORM: 578848b8605Smrg /* 24-bit depth, 8-bit stencil */ 579848b8605Smrg case PIPE_FORMAT_S8_UINT_Z24_UNORM: 580848b8605Smrg return R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL; 581848b8605Smrg default: 582848b8605Smrg return ~0; /* Unsupported. */ 583848b8605Smrg } 584848b8605Smrg} 585848b8605Smrg 586848b8605Smrg/* Shader output formats. This is essentially the swizzle from the shader 587848b8605Smrg * to the RB3D block. 588848b8605Smrg * 589848b8605Smrg * Note that formats are stored from C3 to C0. */ 590848b8605Smrgstatic uint32_t r300_translate_out_fmt(enum pipe_format format) 591848b8605Smrg{ 592848b8605Smrg uint32_t modifier = 0; 593848b8605Smrg unsigned i; 594848b8605Smrg const struct util_format_description *desc; 595848b8605Smrg boolean uniform_sign; 596848b8605Smrg 597b8e80941Smrg format = r300_unbyteswap_array_format(format); 598848b8605Smrg desc = util_format_description(format); 599848b8605Smrg 600848b8605Smrg /* Find the first non-VOID channel. */ 601848b8605Smrg for (i = 0; i < 4; i++) { 602848b8605Smrg if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) { 603848b8605Smrg break; 604848b8605Smrg } 605848b8605Smrg } 606848b8605Smrg 607848b8605Smrg if (i == 4) 608848b8605Smrg return ~0; /* Unsupported/unknown. */ 609848b8605Smrg 610848b8605Smrg /* Specifies how the shader output is written to the fog unit. */ 611848b8605Smrg switch (desc->channel[i].type) { 612848b8605Smrg case UTIL_FORMAT_TYPE_FLOAT: 613848b8605Smrg switch (desc->channel[i].size) { 614848b8605Smrg case 32: 615848b8605Smrg switch (desc->nr_channels) { 616848b8605Smrg case 1: 617848b8605Smrg modifier |= R300_US_OUT_FMT_C_32_FP; 618848b8605Smrg break; 619848b8605Smrg case 2: 620848b8605Smrg modifier |= R300_US_OUT_FMT_C2_32_FP; 621848b8605Smrg break; 622848b8605Smrg case 4: 623848b8605Smrg modifier |= R300_US_OUT_FMT_C4_32_FP; 624848b8605Smrg break; 625848b8605Smrg } 626848b8605Smrg break; 627848b8605Smrg 628848b8605Smrg case 16: 629848b8605Smrg switch (desc->nr_channels) { 630848b8605Smrg case 1: 631848b8605Smrg modifier |= R300_US_OUT_FMT_C_16_FP; 632848b8605Smrg break; 633848b8605Smrg case 2: 634848b8605Smrg modifier |= R300_US_OUT_FMT_C2_16_FP; 635848b8605Smrg break; 636848b8605Smrg case 4: 637848b8605Smrg modifier |= R300_US_OUT_FMT_C4_16_FP; 638848b8605Smrg break; 639848b8605Smrg } 640848b8605Smrg break; 641848b8605Smrg } 642848b8605Smrg break; 643848b8605Smrg 644848b8605Smrg default: 645848b8605Smrg switch (desc->channel[i].size) { 646848b8605Smrg case 16: 647848b8605Smrg switch (desc->nr_channels) { 648848b8605Smrg case 1: 649848b8605Smrg modifier |= R300_US_OUT_FMT_C_16; 650848b8605Smrg break; 651848b8605Smrg case 2: 652848b8605Smrg modifier |= R300_US_OUT_FMT_C2_16; 653848b8605Smrg break; 654848b8605Smrg case 4: 655848b8605Smrg modifier |= R300_US_OUT_FMT_C4_16; 656848b8605Smrg break; 657848b8605Smrg } 658848b8605Smrg break; 659848b8605Smrg 660848b8605Smrg case 10: 661848b8605Smrg modifier |= R300_US_OUT_FMT_C4_10; 662848b8605Smrg break; 663848b8605Smrg 664848b8605Smrg default: 665848b8605Smrg /* C4_8 seems to be used for the formats whose pixel size 666848b8605Smrg * is <= 32 bits. */ 667848b8605Smrg modifier |= R300_US_OUT_FMT_C4_8; 668848b8605Smrg break; 669848b8605Smrg } 670848b8605Smrg } 671848b8605Smrg 672848b8605Smrg /* Add sign. */ 673848b8605Smrg uniform_sign = TRUE; 674848b8605Smrg for (i = 0; i < desc->nr_channels; i++) 675848b8605Smrg if (desc->channel[i].type != UTIL_FORMAT_TYPE_SIGNED) 676848b8605Smrg uniform_sign = FALSE; 677848b8605Smrg 678848b8605Smrg if (uniform_sign) 679848b8605Smrg modifier |= R300_OUT_SIGN(0xf); 680848b8605Smrg 681848b8605Smrg /* Add swizzles and return. */ 682848b8605Smrg switch (format) { 683848b8605Smrg /*** Special cases (non-standard channel mapping) ***/ 684848b8605Smrg 685848b8605Smrg /* X8 686848b8605Smrg * COLORFORMAT_I8 stores the Z component (C2). */ 687848b8605Smrg case PIPE_FORMAT_A8_UNORM: 688848b8605Smrg case PIPE_FORMAT_A8_SNORM: 689848b8605Smrg return modifier | R300_C2_SEL_A; 690848b8605Smrg case PIPE_FORMAT_I8_UNORM: 691848b8605Smrg case PIPE_FORMAT_I8_SNORM: 692848b8605Smrg case PIPE_FORMAT_L8_UNORM: 693848b8605Smrg case PIPE_FORMAT_L8_SNORM: 694848b8605Smrg case PIPE_FORMAT_R8_UNORM: 695848b8605Smrg case PIPE_FORMAT_R8_SNORM: 696848b8605Smrg return modifier | R300_C2_SEL_R; 697848b8605Smrg 698848b8605Smrg /* X8Y8 699848b8605Smrg * COLORFORMAT_UV88 stores ZX (C2 and C0). */ 700848b8605Smrg case PIPE_FORMAT_L8A8_SNORM: 701848b8605Smrg case PIPE_FORMAT_L8A8_UNORM: 702848b8605Smrg case PIPE_FORMAT_R8A8_SNORM: 703848b8605Smrg case PIPE_FORMAT_R8A8_UNORM: 704848b8605Smrg return modifier | R300_C0_SEL_A | R300_C2_SEL_R; 705848b8605Smrg case PIPE_FORMAT_R8G8_SNORM: 706848b8605Smrg case PIPE_FORMAT_R8G8_UNORM: 707848b8605Smrg return modifier | R300_C0_SEL_G | R300_C2_SEL_R; 708848b8605Smrg 709848b8605Smrg /* X32Y32 710848b8605Smrg * ARGB16161616 stores XZ for RG32F */ 711848b8605Smrg case PIPE_FORMAT_R32G32_FLOAT: 712848b8605Smrg return modifier | R300_C0_SEL_R | R300_C2_SEL_G; 713848b8605Smrg 714848b8605Smrg /*** Generic cases (standard channel mapping) ***/ 715848b8605Smrg 716848b8605Smrg /* BGRA outputs. */ 717848b8605Smrg case PIPE_FORMAT_B5G6R5_UNORM: 718848b8605Smrg case PIPE_FORMAT_B5G5R5A1_UNORM: 719848b8605Smrg case PIPE_FORMAT_B5G5R5X1_UNORM: 720848b8605Smrg case PIPE_FORMAT_B4G4R4A4_UNORM: 721848b8605Smrg case PIPE_FORMAT_B4G4R4X4_UNORM: 722848b8605Smrg case PIPE_FORMAT_B8G8R8A8_UNORM: 723848b8605Smrg /*case PIPE_FORMAT_B8G8R8A8_SNORM:*/ 724848b8605Smrg case PIPE_FORMAT_B8G8R8X8_UNORM: 725848b8605Smrg /*case PIPE_FORMAT_B8G8R8X8_SNORM:*/ 726848b8605Smrg case PIPE_FORMAT_B10G10R10A2_UNORM: 727848b8605Smrg case PIPE_FORMAT_B10G10R10X2_UNORM: 728848b8605Smrg return modifier | 729848b8605Smrg R300_C0_SEL_B | R300_C1_SEL_G | 730848b8605Smrg R300_C2_SEL_R | R300_C3_SEL_A; 731848b8605Smrg 732848b8605Smrg /* ARGB outputs. */ 733848b8605Smrg case PIPE_FORMAT_A16_UNORM: 734848b8605Smrg case PIPE_FORMAT_A16_SNORM: 735848b8605Smrg case PIPE_FORMAT_A16_FLOAT: 736848b8605Smrg case PIPE_FORMAT_A32_FLOAT: 737848b8605Smrg return modifier | 738848b8605Smrg R300_C0_SEL_A | R300_C1_SEL_R | 739848b8605Smrg R300_C2_SEL_G | R300_C3_SEL_B; 740848b8605Smrg 741848b8605Smrg /* RGBA outputs. */ 742848b8605Smrg case PIPE_FORMAT_R8G8B8X8_UNORM: 743848b8605Smrg case PIPE_FORMAT_R8G8B8X8_SNORM: 744848b8605Smrg case PIPE_FORMAT_R8G8B8A8_UNORM: 745848b8605Smrg case PIPE_FORMAT_R8G8B8A8_SNORM: 746848b8605Smrg case PIPE_FORMAT_R10G10B10A2_UNORM: 747848b8605Smrg case PIPE_FORMAT_R10G10B10X2_SNORM: 748848b8605Smrg case PIPE_FORMAT_R16_UNORM: 749848b8605Smrg case PIPE_FORMAT_R16G16_UNORM: 750848b8605Smrg case PIPE_FORMAT_R16G16B16A16_UNORM: 751848b8605Smrg case PIPE_FORMAT_R16_SNORM: 752848b8605Smrg case PIPE_FORMAT_R16G16_SNORM: 753848b8605Smrg case PIPE_FORMAT_R16G16B16A16_SNORM: 754848b8605Smrg case PIPE_FORMAT_R16_FLOAT: 755848b8605Smrg case PIPE_FORMAT_R16G16_FLOAT: 756848b8605Smrg case PIPE_FORMAT_R16G16B16A16_FLOAT: 757848b8605Smrg case PIPE_FORMAT_R32_FLOAT: 758848b8605Smrg case PIPE_FORMAT_R32G32B32A32_FLOAT: 759848b8605Smrg case PIPE_FORMAT_R32G32B32X32_FLOAT: 760848b8605Smrg case PIPE_FORMAT_L16_UNORM: 761848b8605Smrg case PIPE_FORMAT_L16_SNORM: 762848b8605Smrg case PIPE_FORMAT_L16_FLOAT: 763848b8605Smrg case PIPE_FORMAT_L32_FLOAT: 764848b8605Smrg case PIPE_FORMAT_I16_UNORM: 765848b8605Smrg case PIPE_FORMAT_I16_SNORM: 766848b8605Smrg case PIPE_FORMAT_I16_FLOAT: 767848b8605Smrg case PIPE_FORMAT_I32_FLOAT: 768848b8605Smrg case PIPE_FORMAT_R16G16B16X16_UNORM: 769848b8605Smrg case PIPE_FORMAT_R16G16B16X16_SNORM: 770848b8605Smrg case PIPE_FORMAT_R16G16B16X16_FLOAT: 771848b8605Smrg return modifier | 772848b8605Smrg R300_C0_SEL_R | R300_C1_SEL_G | 773848b8605Smrg R300_C2_SEL_B | R300_C3_SEL_A; 774848b8605Smrg 775848b8605Smrg /* LA outputs. */ 776848b8605Smrg case PIPE_FORMAT_L16A16_UNORM: 777848b8605Smrg case PIPE_FORMAT_L16A16_SNORM: 778848b8605Smrg case PIPE_FORMAT_L16A16_FLOAT: 779848b8605Smrg case PIPE_FORMAT_R16A16_UNORM: 780848b8605Smrg case PIPE_FORMAT_R16A16_SNORM: 781848b8605Smrg case PIPE_FORMAT_R16A16_FLOAT: 782848b8605Smrg case PIPE_FORMAT_L32A32_FLOAT: 783848b8605Smrg case PIPE_FORMAT_R32A32_FLOAT: 784848b8605Smrg return modifier | 785848b8605Smrg R300_C0_SEL_R | R300_C1_SEL_A; 786848b8605Smrg 787848b8605Smrg default: 788848b8605Smrg return ~0; /* Unsupported. */ 789848b8605Smrg } 790848b8605Smrg} 791848b8605Smrg 792848b8605Smrgstatic uint32_t r300_translate_colormask_swizzle(enum pipe_format format) 793848b8605Smrg{ 794b8e80941Smrg format = r300_unbyteswap_array_format(format); 795b8e80941Smrg 796848b8605Smrg switch (format) { 797848b8605Smrg case PIPE_FORMAT_A8_UNORM: 798848b8605Smrg case PIPE_FORMAT_A8_SNORM: 799848b8605Smrg case PIPE_FORMAT_A16_UNORM: 800848b8605Smrg case PIPE_FORMAT_A16_SNORM: 801848b8605Smrg case PIPE_FORMAT_A16_FLOAT: 802848b8605Smrg case PIPE_FORMAT_A32_FLOAT: 803848b8605Smrg return COLORMASK_AAAA; 804848b8605Smrg 805848b8605Smrg case PIPE_FORMAT_I8_UNORM: 806848b8605Smrg case PIPE_FORMAT_I8_SNORM: 807848b8605Smrg case PIPE_FORMAT_L8_UNORM: 808848b8605Smrg case PIPE_FORMAT_L8_SNORM: 809848b8605Smrg case PIPE_FORMAT_R8_UNORM: 810848b8605Smrg case PIPE_FORMAT_R8_SNORM: 811848b8605Smrg case PIPE_FORMAT_R32_FLOAT: 812848b8605Smrg case PIPE_FORMAT_L32_FLOAT: 813848b8605Smrg case PIPE_FORMAT_I32_FLOAT: 814848b8605Smrg return COLORMASK_RRRR; 815848b8605Smrg 816848b8605Smrg case PIPE_FORMAT_L8A8_SNORM: 817848b8605Smrg case PIPE_FORMAT_L8A8_UNORM: 818848b8605Smrg case PIPE_FORMAT_R8A8_UNORM: 819848b8605Smrg case PIPE_FORMAT_R8A8_SNORM: 820848b8605Smrg case PIPE_FORMAT_L16A16_UNORM: 821848b8605Smrg case PIPE_FORMAT_L16A16_SNORM: 822848b8605Smrg case PIPE_FORMAT_L16A16_FLOAT: 823848b8605Smrg case PIPE_FORMAT_R16A16_UNORM: 824848b8605Smrg case PIPE_FORMAT_R16A16_SNORM: 825848b8605Smrg case PIPE_FORMAT_R16A16_FLOAT: 826848b8605Smrg case PIPE_FORMAT_L32A32_FLOAT: 827848b8605Smrg case PIPE_FORMAT_R32A32_FLOAT: 828848b8605Smrg return COLORMASK_ARRA; 829848b8605Smrg 830848b8605Smrg case PIPE_FORMAT_R8G8_SNORM: 831848b8605Smrg case PIPE_FORMAT_R8G8_UNORM: 832848b8605Smrg case PIPE_FORMAT_R16G16_UNORM: 833848b8605Smrg case PIPE_FORMAT_R16G16_SNORM: 834848b8605Smrg case PIPE_FORMAT_R16G16_FLOAT: 835848b8605Smrg case PIPE_FORMAT_R32G32_FLOAT: 836848b8605Smrg return COLORMASK_GRRG; 837848b8605Smrg 838848b8605Smrg case PIPE_FORMAT_B5G5R5X1_UNORM: 839848b8605Smrg case PIPE_FORMAT_B4G4R4X4_UNORM: 840848b8605Smrg case PIPE_FORMAT_B8G8R8X8_UNORM: 841848b8605Smrg /*case PIPE_FORMAT_B8G8R8X8_SNORM:*/ 842848b8605Smrg case PIPE_FORMAT_B10G10R10X2_UNORM: 843848b8605Smrg return COLORMASK_BGRX; 844848b8605Smrg 845848b8605Smrg case PIPE_FORMAT_B5G6R5_UNORM: 846848b8605Smrg case PIPE_FORMAT_B5G5R5A1_UNORM: 847848b8605Smrg case PIPE_FORMAT_B4G4R4A4_UNORM: 848848b8605Smrg case PIPE_FORMAT_B8G8R8A8_UNORM: 849848b8605Smrg /*case PIPE_FORMAT_B8G8R8A8_SNORM:*/ 850848b8605Smrg case PIPE_FORMAT_B10G10R10A2_UNORM: 851848b8605Smrg return COLORMASK_BGRA; 852848b8605Smrg 853848b8605Smrg case PIPE_FORMAT_R8G8B8X8_UNORM: 854848b8605Smrg /* RGBX_SNORM formats are broken for an unknown reason */ 855848b8605Smrg /*case PIPE_FORMAT_R8G8B8X8_SNORM:*/ 856848b8605Smrg /*case PIPE_FORMAT_R10G10B10X2_SNORM:*/ 857848b8605Smrg case PIPE_FORMAT_R16G16B16X16_UNORM: 858848b8605Smrg /*case PIPE_FORMAT_R16G16B16X16_SNORM:*/ 859848b8605Smrg case PIPE_FORMAT_R16G16B16X16_FLOAT: 860848b8605Smrg case PIPE_FORMAT_R32G32B32X32_FLOAT: 861848b8605Smrg return COLORMASK_RGBX; 862848b8605Smrg 863848b8605Smrg case PIPE_FORMAT_R8G8B8A8_UNORM: 864848b8605Smrg case PIPE_FORMAT_R8G8B8A8_SNORM: 865848b8605Smrg case PIPE_FORMAT_R10G10B10A2_UNORM: 866848b8605Smrg case PIPE_FORMAT_R16_UNORM: 867848b8605Smrg case PIPE_FORMAT_R16G16B16A16_UNORM: 868848b8605Smrg case PIPE_FORMAT_R16_SNORM: 869848b8605Smrg case PIPE_FORMAT_R16G16B16A16_SNORM: 870848b8605Smrg case PIPE_FORMAT_R16_FLOAT: 871848b8605Smrg case PIPE_FORMAT_R16G16B16A16_FLOAT: 872848b8605Smrg case PIPE_FORMAT_R32G32B32A32_FLOAT: 873848b8605Smrg case PIPE_FORMAT_L16_UNORM: 874848b8605Smrg case PIPE_FORMAT_L16_SNORM: 875848b8605Smrg case PIPE_FORMAT_L16_FLOAT: 876848b8605Smrg case PIPE_FORMAT_I16_UNORM: 877848b8605Smrg case PIPE_FORMAT_I16_SNORM: 878848b8605Smrg case PIPE_FORMAT_I16_FLOAT: 879848b8605Smrg return COLORMASK_RGBA; 880848b8605Smrg 881848b8605Smrg default: 882848b8605Smrg return ~0; /* Unsupported. */ 883848b8605Smrg } 884848b8605Smrg} 885848b8605Smrg 886848b8605Smrgboolean r300_is_colorbuffer_format_supported(enum pipe_format format) 887848b8605Smrg{ 888848b8605Smrg return r300_translate_colorformat(format) != ~0 && 889848b8605Smrg r300_translate_out_fmt(format) != ~0 && 890848b8605Smrg r300_translate_colormask_swizzle(format) != ~0; 891848b8605Smrg} 892848b8605Smrg 893848b8605Smrgboolean r300_is_zs_format_supported(enum pipe_format format) 894848b8605Smrg{ 895848b8605Smrg return r300_translate_zsformat(format) != ~0; 896848b8605Smrg} 897848b8605Smrg 898848b8605Smrgboolean r300_is_sampler_format_supported(enum pipe_format format) 899848b8605Smrg{ 900848b8605Smrg return r300_translate_texformat(format, 0, TRUE, FALSE) != ~0; 901848b8605Smrg} 902848b8605Smrg 903848b8605Smrgvoid r300_texture_setup_format_state(struct r300_screen *screen, 904848b8605Smrg struct r300_resource *tex, 905848b8605Smrg enum pipe_format format, 906848b8605Smrg unsigned level, 907848b8605Smrg unsigned width0_override, 908848b8605Smrg unsigned height0_override, 909848b8605Smrg struct r300_texture_format_state *out) 910848b8605Smrg{ 911848b8605Smrg struct pipe_resource *pt = &tex->b.b; 912848b8605Smrg struct r300_texture_desc *desc = &tex->tex; 913848b8605Smrg boolean is_r500 = screen->caps.is_r500; 914848b8605Smrg unsigned width, height, depth; 915848b8605Smrg unsigned txwidth, txheight, txdepth; 916848b8605Smrg 917848b8605Smrg width = u_minify(width0_override, level); 918848b8605Smrg height = u_minify(height0_override, level); 919848b8605Smrg depth = u_minify(desc->depth0, level); 920848b8605Smrg 921848b8605Smrg txwidth = (width - 1) & 0x7ff; 922848b8605Smrg txheight = (height - 1) & 0x7ff; 923848b8605Smrg txdepth = util_logbase2(depth) & 0xf; 924848b8605Smrg 925848b8605Smrg /* Mask out all the fields we change. */ 926848b8605Smrg out->format0 = 0; 927848b8605Smrg out->format1 &= ~R300_TX_FORMAT_TEX_COORD_TYPE_MASK; 928848b8605Smrg out->format2 &= R500_TXFORMAT_MSB; 929848b8605Smrg out->tile_config = 0; 930848b8605Smrg 931848b8605Smrg /* Set sampler state. */ 932848b8605Smrg out->format0 = 933848b8605Smrg R300_TX_WIDTH(txwidth) | 934848b8605Smrg R300_TX_HEIGHT(txheight) | 935848b8605Smrg R300_TX_DEPTH(txdepth); 936848b8605Smrg 937848b8605Smrg if (desc->uses_stride_addressing) { 938848b8605Smrg unsigned stride = 939848b8605Smrg r300_stride_to_width(format, desc->stride_in_bytes[level]); 940848b8605Smrg /* rectangles love this */ 941848b8605Smrg out->format0 |= R300_TX_PITCH_EN; 942848b8605Smrg out->format2 = (stride - 1) & 0x1fff; 943848b8605Smrg } 944848b8605Smrg 945848b8605Smrg if (pt->target == PIPE_TEXTURE_CUBE) { 946848b8605Smrg out->format1 |= R300_TX_FORMAT_CUBIC_MAP; 947848b8605Smrg } 948848b8605Smrg if (pt->target == PIPE_TEXTURE_3D) { 949848b8605Smrg out->format1 |= R300_TX_FORMAT_3D; 950848b8605Smrg } 951848b8605Smrg 952848b8605Smrg /* large textures on r500 */ 953848b8605Smrg if (is_r500) 954848b8605Smrg { 955848b8605Smrg unsigned us_width = txwidth; 956848b8605Smrg unsigned us_height = txheight; 957848b8605Smrg unsigned us_depth = txdepth; 958848b8605Smrg 959848b8605Smrg if (width > 2048) { 960848b8605Smrg out->format2 |= R500_TXWIDTH_BIT11; 961848b8605Smrg } 962848b8605Smrg if (height > 2048) { 963848b8605Smrg out->format2 |= R500_TXHEIGHT_BIT11; 964848b8605Smrg } 965848b8605Smrg 966848b8605Smrg /* The US_FORMAT register fixes an R500 TX addressing bug. 967848b8605Smrg * Don't ask why it must be set like this. I don't know it either. */ 968848b8605Smrg if (width > 2048) { 969848b8605Smrg us_width = (0x000007FF + us_width) >> 1; 970848b8605Smrg us_depth |= 0x0000000D; 971848b8605Smrg } 972848b8605Smrg if (height > 2048) { 973848b8605Smrg us_height = (0x000007FF + us_height) >> 1; 974848b8605Smrg us_depth |= 0x0000000E; 975848b8605Smrg } 976848b8605Smrg 977848b8605Smrg out->us_format0 = 978848b8605Smrg R300_TX_WIDTH(us_width) | 979848b8605Smrg R300_TX_HEIGHT(us_height) | 980848b8605Smrg R300_TX_DEPTH(us_depth); 981848b8605Smrg } 982848b8605Smrg 983848b8605Smrg out->tile_config = R300_TXO_MACRO_TILE(desc->macrotile[level]) | 984b8e80941Smrg R300_TXO_MICRO_TILE(desc->microtile) | 985b8e80941Smrg R300_TXO_ENDIAN(r300_get_endian_swap(format)); 986848b8605Smrg} 987848b8605Smrg 988848b8605Smrgstatic void r300_texture_setup_fb_state(struct r300_surface *surf) 989848b8605Smrg{ 990848b8605Smrg struct r300_resource *tex = r300_resource(surf->base.texture); 991848b8605Smrg unsigned level = surf->base.u.tex.level; 992848b8605Smrg unsigned stride = 993848b8605Smrg r300_stride_to_width(surf->base.format, tex->tex.stride_in_bytes[level]); 994848b8605Smrg 995848b8605Smrg /* Set framebuffer state. */ 996848b8605Smrg if (util_format_is_depth_or_stencil(surf->base.format)) { 997848b8605Smrg surf->pitch = 998848b8605Smrg stride | 999848b8605Smrg R300_DEPTHMACROTILE(tex->tex.macrotile[level]) | 1000b8e80941Smrg R300_DEPTHMICROTILE(tex->tex.microtile) | 1001b8e80941Smrg R300_DEPTHENDIAN(r300_get_endian_swap(surf->base.format)); 1002848b8605Smrg surf->format = r300_translate_zsformat(surf->base.format); 1003848b8605Smrg surf->pitch_zmask = tex->tex.zmask_stride_in_pixels[level]; 1004848b8605Smrg surf->pitch_hiz = tex->tex.hiz_stride_in_pixels[level]; 1005848b8605Smrg } else { 1006b8e80941Smrg enum pipe_format format = util_format_linear(surf->base.format); 1007b8e80941Smrg 1008848b8605Smrg surf->pitch = 1009848b8605Smrg stride | 1010b8e80941Smrg r300_translate_colorformat(format) | 1011848b8605Smrg R300_COLOR_TILE(tex->tex.macrotile[level]) | 1012b8e80941Smrg R300_COLOR_MICROTILE(tex->tex.microtile) | 1013b8e80941Smrg R300_COLOR_ENDIAN(r300_get_endian_swap(format)); 1014b8e80941Smrg surf->format = r300_translate_out_fmt(format); 1015848b8605Smrg surf->colormask_swizzle = 1016b8e80941Smrg r300_translate_colormask_swizzle(format); 1017848b8605Smrg surf->pitch_cmask = tex->tex.cmask_stride_in_pixels; 1018848b8605Smrg } 1019848b8605Smrg} 1020848b8605Smrg 1021848b8605Smrgstatic void r300_texture_destroy(struct pipe_screen *screen, 1022848b8605Smrg struct pipe_resource* texture) 1023848b8605Smrg{ 1024848b8605Smrg struct r300_screen *rscreen = r300_screen(screen); 1025848b8605Smrg struct r300_resource* tex = (struct r300_resource*)texture; 1026848b8605Smrg 1027848b8605Smrg if (tex->tex.cmask_dwords) { 1028b8e80941Smrg mtx_lock(&rscreen->cmask_mutex); 1029848b8605Smrg if (texture == rscreen->cmask_resource) { 1030848b8605Smrg rscreen->cmask_resource = NULL; 1031848b8605Smrg } 1032b8e80941Smrg mtx_unlock(&rscreen->cmask_mutex); 1033848b8605Smrg } 1034848b8605Smrg pb_reference(&tex->buf, NULL); 1035848b8605Smrg FREE(tex); 1036848b8605Smrg} 1037848b8605Smrg 1038848b8605Smrgboolean r300_resource_get_handle(struct pipe_screen* screen, 1039b8e80941Smrg struct pipe_context *ctx, 1040848b8605Smrg struct pipe_resource *texture, 1041b8e80941Smrg struct winsys_handle *whandle, 1042b8e80941Smrg unsigned usage) 1043848b8605Smrg{ 1044848b8605Smrg struct radeon_winsys *rws = r300_screen(screen)->rws; 1045848b8605Smrg struct r300_resource* tex = (struct r300_resource*)texture; 1046848b8605Smrg 1047848b8605Smrg if (!tex) { 1048848b8605Smrg return FALSE; 1049848b8605Smrg } 1050848b8605Smrg 1051b8e80941Smrg return rws->buffer_get_handle(tex->buf, tex->tex.stride_in_bytes[0], 1052b8e80941Smrg 0, 0, whandle); 1053848b8605Smrg} 1054848b8605Smrg 1055848b8605Smrgstatic const struct u_resource_vtbl r300_texture_vtbl = 1056848b8605Smrg{ 1057848b8605Smrg NULL, /* get_handle */ 1058848b8605Smrg r300_texture_destroy, /* resource_destroy */ 1059848b8605Smrg r300_texture_transfer_map, /* transfer_map */ 1060848b8605Smrg NULL, /* transfer_flush_region */ 1061848b8605Smrg r300_texture_transfer_unmap, /* transfer_unmap */ 1062848b8605Smrg}; 1063848b8605Smrg 1064848b8605Smrg/* The common texture constructor. */ 1065848b8605Smrgstatic struct r300_resource* 1066848b8605Smrgr300_texture_create_object(struct r300_screen *rscreen, 1067848b8605Smrg const struct pipe_resource *base, 1068848b8605Smrg enum radeon_bo_layout microtile, 1069848b8605Smrg enum radeon_bo_layout macrotile, 1070848b8605Smrg unsigned stride_in_bytes_override, 1071848b8605Smrg struct pb_buffer *buffer) 1072848b8605Smrg{ 1073848b8605Smrg struct radeon_winsys *rws = rscreen->rws; 1074848b8605Smrg struct r300_resource *tex = NULL; 1075b8e80941Smrg struct radeon_bo_metadata tiling = {}; 1076848b8605Smrg 1077848b8605Smrg tex = CALLOC_STRUCT(r300_resource); 1078848b8605Smrg if (!tex) { 1079848b8605Smrg goto fail; 1080848b8605Smrg } 1081848b8605Smrg 1082848b8605Smrg pipe_reference_init(&tex->b.b.reference, 1); 1083848b8605Smrg tex->b.b.screen = &rscreen->screen; 1084848b8605Smrg tex->b.b.usage = base->usage; 1085848b8605Smrg tex->b.b.bind = base->bind; 1086848b8605Smrg tex->b.b.flags = base->flags; 1087848b8605Smrg tex->b.vtbl = &r300_texture_vtbl; 1088848b8605Smrg tex->tex.microtile = microtile; 1089848b8605Smrg tex->tex.macrotile[0] = macrotile; 1090848b8605Smrg tex->tex.stride_in_bytes_override = stride_in_bytes_override; 1091848b8605Smrg tex->domain = (base->flags & R300_RESOURCE_FLAG_TRANSFER || 1092848b8605Smrg base->usage == PIPE_USAGE_STAGING) ? RADEON_DOMAIN_GTT : 1093848b8605Smrg base->nr_samples > 1 ? RADEON_DOMAIN_VRAM : 1094848b8605Smrg RADEON_DOMAIN_VRAM | RADEON_DOMAIN_GTT; 1095848b8605Smrg tex->buf = buffer; 1096848b8605Smrg 1097848b8605Smrg r300_texture_desc_init(rscreen, tex, base); 1098848b8605Smrg 1099848b8605Smrg /* Figure out the ideal placement for the texture.. */ 1100848b8605Smrg if (tex->domain & RADEON_DOMAIN_VRAM && 1101848b8605Smrg tex->tex.size_in_bytes >= rscreen->info.vram_size) { 1102848b8605Smrg tex->domain &= ~RADEON_DOMAIN_VRAM; 1103848b8605Smrg tex->domain |= RADEON_DOMAIN_GTT; 1104848b8605Smrg } 1105848b8605Smrg if (tex->domain & RADEON_DOMAIN_GTT && 1106848b8605Smrg tex->tex.size_in_bytes >= rscreen->info.gart_size) { 1107848b8605Smrg tex->domain &= ~RADEON_DOMAIN_GTT; 1108848b8605Smrg } 1109848b8605Smrg /* Just fail if the texture is too large. */ 1110848b8605Smrg if (!tex->domain) { 1111848b8605Smrg goto fail; 1112848b8605Smrg } 1113848b8605Smrg 1114848b8605Smrg /* Create the backing buffer if needed. */ 1115848b8605Smrg if (!tex->buf) { 1116b8e80941Smrg /* Only use the first domain for allocation. Multiple domains are not allowed. */ 1117b8e80941Smrg unsigned alloc_domain = 1118b8e80941Smrg tex->domain & RADEON_DOMAIN_VRAM ? RADEON_DOMAIN_VRAM : 1119b8e80941Smrg RADEON_DOMAIN_GTT; 1120b8e80941Smrg 1121b8e80941Smrg tex->buf = rws->buffer_create(rws, tex->tex.size_in_bytes, 2048, 1122b8e80941Smrg alloc_domain, 1123b8e80941Smrg RADEON_FLAG_NO_SUBALLOC | 1124b8e80941Smrg /* Use the reusable pool: */ 1125b8e80941Smrg RADEON_FLAG_NO_INTERPROCESS_SHARING); 1126848b8605Smrg 1127848b8605Smrg if (!tex->buf) { 1128848b8605Smrg goto fail; 1129848b8605Smrg } 1130848b8605Smrg } 1131848b8605Smrg 1132848b8605Smrg if (SCREEN_DBG_ON(rscreen, DBG_MSAA) && base->nr_samples > 1) { 1133848b8605Smrg fprintf(stderr, "r300: %ix MSAA %s buffer created\n", 1134848b8605Smrg base->nr_samples, 1135848b8605Smrg util_format_is_depth_or_stencil(base->format) ? "depth" : "color"); 1136848b8605Smrg } 1137848b8605Smrg 1138b8e80941Smrg tiling.u.legacy.microtile = tex->tex.microtile; 1139b8e80941Smrg tiling.u.legacy.macrotile = tex->tex.macrotile[0]; 1140b8e80941Smrg tiling.u.legacy.stride = tex->tex.stride_in_bytes[0]; 1141b8e80941Smrg rws->buffer_set_metadata(tex->buf, &tiling); 1142848b8605Smrg 1143848b8605Smrg return tex; 1144848b8605Smrg 1145848b8605Smrgfail: 1146848b8605Smrg FREE(tex); 1147848b8605Smrg if (buffer) 1148848b8605Smrg pb_reference(&buffer, NULL); 1149848b8605Smrg return NULL; 1150848b8605Smrg} 1151848b8605Smrg 1152848b8605Smrg/* Create a new texture. */ 1153848b8605Smrgstruct pipe_resource *r300_texture_create(struct pipe_screen *screen, 1154848b8605Smrg const struct pipe_resource *base) 1155848b8605Smrg{ 1156848b8605Smrg struct r300_screen *rscreen = r300_screen(screen); 1157848b8605Smrg enum radeon_bo_layout microtile, macrotile; 1158848b8605Smrg 1159848b8605Smrg if ((base->flags & R300_RESOURCE_FLAG_TRANSFER) || 1160848b8605Smrg (base->bind & (PIPE_BIND_SCANOUT | PIPE_BIND_LINEAR))) { 1161848b8605Smrg microtile = RADEON_LAYOUT_LINEAR; 1162848b8605Smrg macrotile = RADEON_LAYOUT_LINEAR; 1163848b8605Smrg } else { 1164848b8605Smrg /* This will make the texture_create_function select the layout. */ 1165848b8605Smrg microtile = RADEON_LAYOUT_UNKNOWN; 1166848b8605Smrg macrotile = RADEON_LAYOUT_UNKNOWN; 1167848b8605Smrg } 1168848b8605Smrg 1169848b8605Smrg return (struct pipe_resource*) 1170848b8605Smrg r300_texture_create_object(rscreen, base, microtile, macrotile, 1171848b8605Smrg 0, NULL); 1172848b8605Smrg} 1173848b8605Smrg 1174848b8605Smrgstruct pipe_resource *r300_texture_from_handle(struct pipe_screen *screen, 1175848b8605Smrg const struct pipe_resource *base, 1176b8e80941Smrg struct winsys_handle *whandle, 1177b8e80941Smrg unsigned usage) 1178848b8605Smrg{ 1179848b8605Smrg struct r300_screen *rscreen = r300_screen(screen); 1180848b8605Smrg struct radeon_winsys *rws = rscreen->rws; 1181848b8605Smrg struct pb_buffer *buffer; 1182848b8605Smrg unsigned stride; 1183b8e80941Smrg struct radeon_bo_metadata tiling = {}; 1184848b8605Smrg 1185848b8605Smrg /* Support only 2D textures without mipmaps */ 1186848b8605Smrg if ((base->target != PIPE_TEXTURE_2D && 1187848b8605Smrg base->target != PIPE_TEXTURE_RECT) || 1188848b8605Smrg base->depth0 != 1 || 1189848b8605Smrg base->last_level != 0) { 1190848b8605Smrg return NULL; 1191848b8605Smrg } 1192848b8605Smrg 1193b8e80941Smrg buffer = rws->buffer_from_handle(rws, whandle, 0, &stride, NULL); 1194848b8605Smrg if (!buffer) 1195848b8605Smrg return NULL; 1196848b8605Smrg 1197b8e80941Smrg rws->buffer_get_metadata(buffer, &tiling); 1198848b8605Smrg 1199848b8605Smrg /* Enforce a microtiled zbuffer. */ 1200848b8605Smrg if (util_format_is_depth_or_stencil(base->format) && 1201b8e80941Smrg tiling.u.legacy.microtile == RADEON_LAYOUT_LINEAR) { 1202848b8605Smrg switch (util_format_get_blocksize(base->format)) { 1203848b8605Smrg case 4: 1204b8e80941Smrg tiling.u.legacy.microtile = RADEON_LAYOUT_TILED; 1205848b8605Smrg break; 1206848b8605Smrg 1207848b8605Smrg case 2: 1208b8e80941Smrg tiling.u.legacy.microtile = RADEON_LAYOUT_SQUARETILED; 1209848b8605Smrg break; 1210848b8605Smrg } 1211848b8605Smrg } 1212848b8605Smrg 1213848b8605Smrg return (struct pipe_resource*) 1214b8e80941Smrg r300_texture_create_object(rscreen, base, tiling.u.legacy.microtile, tiling.u.legacy.macrotile, 1215848b8605Smrg stride, buffer); 1216848b8605Smrg} 1217848b8605Smrg 1218848b8605Smrg/* Not required to implement u_resource_vtbl, consider moving to another file: 1219848b8605Smrg */ 1220848b8605Smrgstruct pipe_surface* r300_create_surface_custom(struct pipe_context * ctx, 1221848b8605Smrg struct pipe_resource* texture, 1222848b8605Smrg const struct pipe_surface *surf_tmpl, 1223848b8605Smrg unsigned width0_override, 1224848b8605Smrg unsigned height0_override) 1225848b8605Smrg{ 1226848b8605Smrg struct r300_resource* tex = r300_resource(texture); 1227848b8605Smrg struct r300_surface* surface = CALLOC_STRUCT(r300_surface); 1228848b8605Smrg unsigned level = surf_tmpl->u.tex.level; 1229848b8605Smrg 1230848b8605Smrg assert(surf_tmpl->u.tex.first_layer == surf_tmpl->u.tex.last_layer); 1231848b8605Smrg 1232848b8605Smrg if (surface) { 1233848b8605Smrg uint32_t offset, tile_height; 1234848b8605Smrg 1235848b8605Smrg pipe_reference_init(&surface->base.reference, 1); 1236848b8605Smrg pipe_resource_reference(&surface->base.texture, texture); 1237848b8605Smrg surface->base.context = ctx; 1238848b8605Smrg surface->base.format = surf_tmpl->format; 1239848b8605Smrg surface->base.width = u_minify(width0_override, level); 1240848b8605Smrg surface->base.height = u_minify(height0_override, level); 1241848b8605Smrg surface->base.u.tex.level = level; 1242848b8605Smrg surface->base.u.tex.first_layer = surf_tmpl->u.tex.first_layer; 1243848b8605Smrg surface->base.u.tex.last_layer = surf_tmpl->u.tex.last_layer; 1244848b8605Smrg 1245848b8605Smrg surface->buf = tex->buf; 1246848b8605Smrg 1247848b8605Smrg /* Prefer VRAM if there are multiple domains to choose from. */ 1248848b8605Smrg surface->domain = tex->domain; 1249848b8605Smrg if (surface->domain & RADEON_DOMAIN_VRAM) 1250848b8605Smrg surface->domain &= ~RADEON_DOMAIN_GTT; 1251848b8605Smrg 1252848b8605Smrg surface->offset = r300_texture_get_offset(tex, level, 1253848b8605Smrg surf_tmpl->u.tex.first_layer); 1254848b8605Smrg r300_texture_setup_fb_state(surface); 1255848b8605Smrg 1256848b8605Smrg /* Parameters for the CBZB clear. */ 1257848b8605Smrg surface->cbzb_allowed = tex->tex.cbzb_allowed[level]; 1258848b8605Smrg surface->cbzb_width = align(surface->base.width, 64); 1259848b8605Smrg 1260848b8605Smrg /* Height must be aligned to the size of a tile. */ 1261848b8605Smrg tile_height = r300_get_pixel_alignment(surface->base.format, 1262848b8605Smrg tex->b.b.nr_samples, 1263848b8605Smrg tex->tex.microtile, 1264848b8605Smrg tex->tex.macrotile[level], 1265848b8605Smrg DIM_HEIGHT, 0); 1266848b8605Smrg 1267848b8605Smrg surface->cbzb_height = align((surface->base.height + 1) / 2, 1268848b8605Smrg tile_height); 1269848b8605Smrg 1270848b8605Smrg /* Offset must be aligned to 2K and must point at the beginning 1271848b8605Smrg * of a scanline. */ 1272848b8605Smrg offset = surface->offset + 1273848b8605Smrg tex->tex.stride_in_bytes[level] * surface->cbzb_height; 1274848b8605Smrg surface->cbzb_midpoint_offset = offset & ~2047; 1275848b8605Smrg 1276848b8605Smrg surface->cbzb_pitch = surface->pitch & 0x1ffffc; 1277848b8605Smrg 1278848b8605Smrg if (util_format_get_blocksizebits(surface->base.format) == 32) 1279848b8605Smrg surface->cbzb_format = R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL; 1280848b8605Smrg else 1281848b8605Smrg surface->cbzb_format = R300_DEPTHFORMAT_16BIT_INT_Z; 1282848b8605Smrg 1283848b8605Smrg DBG(r300_context(ctx), DBG_CBZB, 1284848b8605Smrg "CBZB Allowed: %s, Dim: %ix%i, Misalignment: %i, Micro: %s, Macro: %s\n", 1285848b8605Smrg surface->cbzb_allowed ? "YES" : " NO", 1286848b8605Smrg surface->cbzb_width, surface->cbzb_height, 1287848b8605Smrg offset & 2047, 1288848b8605Smrg tex->tex.microtile ? "YES" : " NO", 1289848b8605Smrg tex->tex.macrotile[level] ? "YES" : " NO"); 1290848b8605Smrg } 1291848b8605Smrg 1292848b8605Smrg return &surface->base; 1293848b8605Smrg} 1294848b8605Smrg 1295848b8605Smrgstruct pipe_surface* r300_create_surface(struct pipe_context * ctx, 1296848b8605Smrg struct pipe_resource* texture, 1297848b8605Smrg const struct pipe_surface *surf_tmpl) 1298848b8605Smrg{ 1299848b8605Smrg return r300_create_surface_custom(ctx, texture, surf_tmpl, 1300848b8605Smrg texture->width0, 1301848b8605Smrg texture->height0); 1302848b8605Smrg} 1303848b8605Smrg 1304848b8605Smrg/* Not required to implement u_resource_vtbl, consider moving to another file: 1305848b8605Smrg */ 1306848b8605Smrgvoid r300_surface_destroy(struct pipe_context *ctx, struct pipe_surface* s) 1307848b8605Smrg{ 1308848b8605Smrg pipe_resource_reference(&s->texture, NULL); 1309848b8605Smrg FREE(s); 1310848b8605Smrg} 1311