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