r300_texture_desc.c revision c92d232061c1aef6f5f56cbd815625778db2fd8c
1/* 2 * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> 3 * Copyright 2010 Marek Olšák <maraeo@gmail.com> 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * on the rights to use, copy, modify, merge, publish, distribute, sub 9 * license, and/or sell copies of the Software, and to permit persons to whom 10 * the Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the next 13 * paragraph) shall be included in all copies or substantial portions of the 14 * Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 22 * USE OR OTHER DEALINGS IN THE SOFTWARE. */ 23 24#include "r300_texture_desc.h" 25 26#include "r300_context.h" 27#include "r300_winsys.h" 28 29#include "util/u_format.h" 30 31/* Returns the number of pixels that the texture should be aligned to 32 * in the given dimension. */ 33unsigned r300_get_pixel_alignment(enum pipe_format format, 34 unsigned num_samples, 35 enum r300_buffer_tiling microtile, 36 enum r300_buffer_tiling macrotile, 37 enum r300_dim dim) 38{ 39 static const unsigned table[2][5][3][2] = 40 { 41 { 42 /* Macro: linear linear linear 43 Micro: linear tiled square-tiled */ 44 {{ 32, 1}, { 8, 4}, { 0, 0}}, /* 8 bits per pixel */ 45 {{ 16, 1}, { 8, 2}, { 4, 4}}, /* 16 bits per pixel */ 46 {{ 8, 1}, { 4, 2}, { 0, 0}}, /* 32 bits per pixel */ 47 {{ 4, 1}, { 0, 0}, { 2, 2}}, /* 64 bits per pixel */ 48 {{ 2, 1}, { 0, 0}, { 0, 0}} /* 128 bits per pixel */ 49 }, 50 { 51 /* Macro: tiled tiled tiled 52 Micro: linear tiled square-tiled */ 53 {{256, 8}, {64, 32}, { 0, 0}}, /* 8 bits per pixel */ 54 {{128, 8}, {64, 16}, {32, 32}}, /* 16 bits per pixel */ 55 {{ 64, 8}, {32, 16}, { 0, 0}}, /* 32 bits per pixel */ 56 {{ 32, 8}, { 0, 0}, {16, 16}}, /* 64 bits per pixel */ 57 {{ 16, 8}, { 0, 0}, { 0, 0}} /* 128 bits per pixel */ 58 } 59 }; 60 static const unsigned aa_block[2] = {4, 8}; 61 unsigned tile = 0; 62 unsigned pixsize = util_format_get_blocksize(format); 63 64 assert(macrotile <= R300_BUFFER_TILED); 65 assert(microtile <= R300_BUFFER_SQUARETILED); 66 assert(pixsize <= 16); 67 assert(dim <= DIM_HEIGHT); 68 69 if (num_samples > 1) { 70 /* Multisampled textures have their own alignment scheme. */ 71 if (pixsize == 4) 72 tile = aa_block[dim]; 73 /* XXX FP16 AA. */ 74 } else { 75 /* Standard alignment. */ 76 tile = table[macrotile][util_logbase2(pixsize)][microtile][dim]; 77 } 78 79 assert(tile); 80 return tile; 81} 82 83/* Return true if macrotiling should be enabled on the miplevel. */ 84static boolean r300_texture_macro_switch(struct r300_texture_desc *desc, 85 unsigned level, 86 boolean rv350_mode, 87 enum r300_dim dim) 88{ 89 unsigned tile, texdim; 90 91 tile = r300_get_pixel_alignment(desc->b.b.format, desc->b.b.nr_samples, 92 desc->microtile, R300_BUFFER_TILED, dim); 93 if (dim == DIM_WIDTH) { 94 texdim = u_minify(desc->b.b.width0, level); 95 } else { 96 texdim = u_minify(desc->b.b.height0, level); 97 } 98 99 /* See TX_FILTER1_n.MACRO_SWITCH. */ 100 if (rv350_mode) { 101 return texdim >= tile; 102 } else { 103 return texdim > tile; 104 } 105} 106 107/** 108 * Return the stride, in bytes, of the texture image of the given texture 109 * at the given level. 110 */ 111static unsigned r300_texture_get_stride(struct r300_screen *screen, 112 struct r300_texture_desc *desc, 113 unsigned level) 114{ 115 unsigned tile_width, width, stride; 116 117 if (desc->stride_in_bytes_override) 118 return desc->stride_in_bytes_override; 119 120 /* Check the level. */ 121 if (level > desc->b.b.last_level) { 122 SCREEN_DBG(screen, DBG_TEX, "%s: level (%u) > last_level (%u)\n", 123 __FUNCTION__, level, desc->b.b.last_level); 124 return 0; 125 } 126 127 width = u_minify(desc->b.b.width0, level); 128 129 if (util_format_is_plain(desc->b.b.format)) { 130 tile_width = r300_get_pixel_alignment(desc->b.b.format, 131 desc->b.b.nr_samples, 132 desc->microtile, 133 desc->macrotile[level], 134 DIM_WIDTH); 135 width = align(width, tile_width); 136 137 stride = util_format_get_stride(desc->b.b.format, width); 138 139 /* Some IGPs need a minimum stride of 64 bytes, hmm... 140 * This doesn't seem to apply to tiled textures, according to r300c. */ 141 if (!desc->microtile && !desc->macrotile[level] && 142 (screen->caps.family == CHIP_FAMILY_RS600 || 143 screen->caps.family == CHIP_FAMILY_RS690 || 144 screen->caps.family == CHIP_FAMILY_RS740)) { 145 return stride < 64 ? 64 : stride; 146 } 147 148 /* The alignment to 32 bytes is sort of implied by the layout... */ 149 return stride; 150 } else { 151 return align(util_format_get_stride(desc->b.b.format, width), 32); 152 } 153} 154 155static unsigned r300_texture_get_nblocksy(struct r300_texture_desc *desc, 156 unsigned level, 157 boolean align_for_cbzb) 158{ 159 unsigned height, tile_height; 160 161 height = u_minify(desc->b.b.height0, level); 162 163 if (util_format_is_plain(desc->b.b.format)) { 164 tile_height = r300_get_pixel_alignment(desc->b.b.format, 165 desc->b.b.nr_samples, 166 desc->microtile, 167 desc->macrotile[level], 168 DIM_HEIGHT); 169 height = align(height, tile_height); 170 171 /* This is needed for the kernel checker, unfortunately. */ 172 if ((desc->b.b.target != PIPE_TEXTURE_1D && 173 desc->b.b.target != PIPE_TEXTURE_2D) || 174 desc->b.b.last_level != 0) { 175 height = util_next_power_of_two(height); 176 } 177 178 /* Allocate an even number of macrotiles for the CBZB clear. 179 * Do so for 3 or more macrotiles in the Y direction. */ 180 if (align_for_cbzb && 181 level == 0 && desc->b.b.last_level == 0 && 182 desc->macrotile[0] && height >= tile_height * 3) { 183 height = align(height, tile_height * 2); 184 } 185 } 186 187 return util_format_get_nblocksy(desc->b.b.format, height); 188} 189 190static void r300_texture_3d_fix_mipmapping(struct r300_screen *screen, 191 struct r300_texture_desc *desc) 192{ 193 /* The kernels <= 2.6.34-rc4 compute the size of mipmapped 3D textures 194 * incorrectly. This is a workaround to prevent CS from being rejected. */ 195 196 unsigned i, size; 197 198 if (!screen->rws->get_value(screen->rws, R300_VID_DRM_2_3_0) && 199 desc->b.b.target == PIPE_TEXTURE_3D && 200 desc->b.b.last_level > 0) { 201 size = 0; 202 203 for (i = 0; i <= desc->b.b.last_level; i++) { 204 size += desc->stride_in_bytes[i] * 205 r300_texture_get_nblocksy(desc, i, FALSE); 206 } 207 208 size *= desc->b.b.depth0; 209 desc->size_in_bytes = size; 210 } 211} 212 213/* Get a width in pixels from a stride in bytes. */ 214static unsigned stride_to_width(enum pipe_format format, 215 unsigned stride_in_bytes) 216{ 217 return (stride_in_bytes / util_format_get_blocksize(format)) * 218 util_format_get_blockwidth(format); 219} 220 221static void r300_setup_miptree(struct r300_screen *screen, 222 struct r300_texture_desc *desc) 223{ 224 struct pipe_resource *base = &desc->b.b; 225 unsigned stride, size, layer_size, nblocksy, i; 226 boolean rv350_mode = screen->caps.is_rv350; 227 228 SCREEN_DBG(screen, DBG_TEXALLOC, 229 "r300: Making miptree for texture, format %s\n", 230 util_format_short_name(base->format)); 231 232 for (i = 0; i <= base->last_level; i++) { 233 /* Let's see if this miplevel can be macrotiled. */ 234 desc->macrotile[i] = 235 (desc->macrotile[0] == R300_BUFFER_TILED && 236 r300_texture_macro_switch(desc, i, rv350_mode, DIM_WIDTH) && 237 r300_texture_macro_switch(desc, i, rv350_mode, DIM_HEIGHT)) ? 238 R300_BUFFER_TILED : R300_BUFFER_LINEAR; 239 240 stride = r300_texture_get_stride(screen, desc, i); 241 nblocksy = r300_texture_get_nblocksy(desc, i, desc->stride_in_bytes_override == 0); 242 layer_size = stride * nblocksy; 243 244 if (base->nr_samples) { 245 layer_size *= base->nr_samples; 246 } 247 248 if (base->target == PIPE_TEXTURE_CUBE) 249 size = layer_size * 6; 250 else 251 size = layer_size * u_minify(base->depth0, i); 252 253 desc->offset_in_bytes[i] = desc->size_in_bytes; 254 desc->size_in_bytes = desc->offset_in_bytes[i] + size; 255 desc->layer_size_in_bytes[i] = layer_size; 256 desc->stride_in_bytes[i] = stride; 257 desc->stride_in_pixels[i] = stride_to_width(desc->b.b.format, stride); 258 259 SCREEN_DBG(screen, DBG_TEXALLOC, "r300: Texture miptree: Level %d " 260 "(%dx%dx%d px, pitch %d bytes) %d bytes total, macrotiled %s\n", 261 i, u_minify(base->width0, i), u_minify(base->height0, i), 262 u_minify(base->depth0, i), stride, desc->size_in_bytes, 263 desc->macrotile[i] ? "TRUE" : "FALSE"); 264 } 265} 266 267static void r300_setup_flags(struct r300_texture_desc *desc) 268{ 269 desc->uses_stride_addressing = 270 !util_is_power_of_two(desc->b.b.width0) || 271 !util_is_power_of_two(desc->b.b.height0) || 272 (desc->stride_in_bytes_override && 273 stride_to_width(desc->b.b.format, 274 desc->stride_in_bytes_override) != desc->b.b.width0); 275} 276 277static void r300_setup_cbzb_flags(struct r300_screen *rscreen, 278 struct r300_texture_desc *desc) 279{ 280 unsigned i, bpp; 281 boolean first_level_valid; 282 283 bpp = util_format_get_blocksizebits(desc->b.b.format); 284 285 /* 1) The texture must be point-sampled, 286 * 2) The depth must be 16 or 32 bits. 287 * 3) If the midpoint ZB offset is not aligned to 2048, it returns garbage 288 * with certain texture sizes. Macrotiling ensures the alignment. */ 289 first_level_valid = desc->b.b.nr_samples <= 1 && 290 (bpp == 16 || bpp == 32) && 291 desc->macrotile[0]; 292 293 for (i = 0; i <= desc->b.b.last_level; i++) 294 desc->cbzb_allowed[i] = first_level_valid && desc->macrotile[i]; 295 return; 296#if 0 297 /* When clearing, the layer (width*height) is horizontally split 298 * into two, and the upper and lower halves are cleared by the CB 299 * and ZB units, respectively. Therefore, the number of macrotiles 300 * in the Y direction must be even. */ 301 302 if (desc->b.b.last_level > 0 || 303 desc->b.b.target == PIPE_TEXTURE_3D || 304 desc->b.b.target == PIPE_TEXTURE_CUBE) { 305 /* For mipmapped, 3D, or cube textures, just check if there are 306 * enough macrotiles per layer. */ 307 for (i = 0; i <= desc->b.b.last_level; i++) { 308 desc->cbzb_allowed[i] = FALSE; 309 310 if (first_level_valid && desc->macrotile[i]) { 311 unsigned height, tile_height, num_macrotiles; 312 313 /* Compute the number of macrotiles in the Y direction. */ 314 tile_height = r300_get_pixel_alignment(desc->b.b.format, 315 desc->b.b.nr_samples, 316 desc->microtile, 317 R300_BUFFER_TILED, 318 DIM_HEIGHT); 319 height = r300_texture_get_height(desc, i); 320 num_macrotiles = height / tile_height; 321 322 desc->cbzb_allowed[i] = num_macrotiles % 2 == 0; 323 } 324 } 325 } else { 326 /* For 1D and 2D non-mipmapped textures */ 327 unsigned layer_size; 328 329 layer_size = desc->stride_in_bytes[0] * 330 r300_texture_get_nblocksy(desc, 0, TRUE); 331 } 332#endif 333} 334 335static void r300_setup_tiling(struct r300_screen *screen, 336 struct r300_texture_desc *desc) 337{ 338 struct r300_winsys_screen *rws = screen->rws; 339 enum pipe_format format = desc->b.b.format; 340 boolean rv350_mode = screen->caps.is_rv350; 341 boolean is_zb = util_format_is_depth_or_stencil(format); 342 boolean dbg_no_tiling = SCREEN_DBG_ON(screen, DBG_NO_TILING); 343 344 if (!util_format_is_plain(format)) { 345 return; 346 } 347 348 /* If height == 1, disable microtiling except for zbuffer. */ 349 if (!is_zb && (desc->b.b.height0 == 1 || dbg_no_tiling)) { 350 return; 351 } 352 353 /* Set microtiling. */ 354 switch (util_format_get_blocksize(format)) { 355 case 1: 356 case 4: 357 desc->microtile = R300_BUFFER_TILED; 358 break; 359 360 case 2: 361 case 8: 362 if (rws->get_value(rws, R300_VID_SQUARE_TILING_SUPPORT)) { 363 desc->microtile = R300_BUFFER_SQUARETILED; 364 } 365 break; 366 } 367 368 if (dbg_no_tiling) { 369 return; 370 } 371 372 /* Set macrotiling. */ 373 if (r300_texture_macro_switch(desc, 0, rv350_mode, DIM_WIDTH) && 374 r300_texture_macro_switch(desc, 0, rv350_mode, DIM_HEIGHT)) { 375 desc->macrotile[0] = R300_BUFFER_TILED; 376 } 377} 378 379static void r300_tex_print_info(struct r300_screen *rscreen, 380 struct r300_texture_desc *desc, 381 const char *func) 382{ 383 fprintf(stderr, 384 "r300: %s: Macro: %s, Micro: %s, Pitch: %i, Dim: %ix%ix%i, " 385 "LastLevel: %i, Size: %i, Format: %s\n", 386 func, 387 desc->macrotile[0] ? "YES" : " NO", 388 desc->microtile ? "YES" : " NO", 389 desc->stride_in_pixels[0], 390 desc->b.b.width0, desc->b.b.height0, desc->b.b.depth0, 391 desc->b.b.last_level, desc->size_in_bytes, 392 util_format_short_name(desc->b.b.format)); 393} 394 395boolean r300_texture_desc_init(struct r300_screen *rscreen, 396 struct r300_texture_desc *desc, 397 const struct pipe_resource *base, 398 enum r300_buffer_tiling microtile, 399 enum r300_buffer_tiling macrotile, 400 unsigned stride_in_bytes_override, 401 unsigned max_buffer_size) 402{ 403 desc->b.b = *base; 404 desc->b.b.screen = &rscreen->screen; 405 406 desc->stride_in_bytes_override = stride_in_bytes_override; 407 408 r300_setup_flags(desc); 409 410 if (microtile == R300_BUFFER_SELECT_LAYOUT || 411 macrotile == R300_BUFFER_SELECT_LAYOUT) { 412 r300_setup_tiling(rscreen, desc); 413 } else { 414 desc->microtile = microtile; 415 desc->macrotile[0] = macrotile; 416 assert(desc->b.b.last_level == 0); 417 } 418 419 r300_setup_miptree(rscreen, desc); 420 r300_texture_3d_fix_mipmapping(rscreen, desc); 421 r300_setup_cbzb_flags(rscreen, desc); 422 423 if (max_buffer_size) { 424 /* Make sure the buffer we got is large enough. */ 425 if (desc->size_in_bytes > max_buffer_size) { 426 fprintf(stderr, "r300: texture_from_handle: The buffer is not " 427 "large enough. Got: %i, Need: %i, Info:\n", 428 max_buffer_size, desc->size_in_bytes); 429 r300_tex_print_info(rscreen, desc, "texture_from_handle"); 430 return FALSE; 431 } 432 433 desc->buffer_size_in_bytes = max_buffer_size; 434 } else { 435 desc->buffer_size_in_bytes = desc->size_in_bytes; 436 437 } 438 439 if (SCREEN_DBG_ON(rscreen, DBG_TEX)) 440 r300_tex_print_info(rscreen, desc, "texture_from_handle"); 441 442 return TRUE; 443} 444 445unsigned r300_texture_get_offset(struct r300_texture_desc *desc, 446 unsigned level, unsigned zslice, 447 unsigned face) 448{ 449 unsigned offset = desc->offset_in_bytes[level]; 450 451 switch (desc->b.b.target) { 452 case PIPE_TEXTURE_3D: 453 assert(face == 0); 454 return offset + zslice * desc->layer_size_in_bytes[level]; 455 456 case PIPE_TEXTURE_CUBE: 457 assert(zslice == 0); 458 return offset + face * desc->layer_size_in_bytes[level]; 459 460 default: 461 assert(zslice == 0 && face == 0); 462 return offset; 463 } 464} 465