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 #include "r300_context.h"
26
27 #include "util/u_format.h"
28 #include <inttypes.h>
29
30 /* Returns the number of pixels that the texture should be aligned to
31 * in the given dimension. */
r300_get_pixel_alignment(enum pipe_format format,unsigned num_samples,enum radeon_bo_layout microtile,enum radeon_bo_layout macrotile,enum r300_dim dim,boolean is_rs690)32 unsigned r300_get_pixel_alignment(enum pipe_format format,
33 unsigned num_samples,
34 enum radeon_bo_layout microtile,
35 enum radeon_bo_layout macrotile,
36 enum r300_dim dim, boolean is_rs690)
37 {
38 static const unsigned table[2][5][3][2] =
39 {
40 {
41 /* Macro: linear linear linear
42 Micro: linear tiled square-tiled */
43 {{ 32, 1}, { 8, 4}, { 0, 0}}, /* 8 bits per pixel */
44 {{ 16, 1}, { 8, 2}, { 4, 4}}, /* 16 bits per pixel */
45 {{ 8, 1}, { 4, 2}, { 0, 0}}, /* 32 bits per pixel */
46 {{ 4, 1}, { 2, 2}, { 0, 0}}, /* 64 bits per pixel */
47 {{ 2, 1}, { 0, 0}, { 0, 0}} /* 128 bits per pixel */
48 },
49 {
50 /* Macro: tiled tiled tiled
51 Micro: linear tiled square-tiled */
52 {{256, 8}, {64, 32}, { 0, 0}}, /* 8 bits per pixel */
53 {{128, 8}, {64, 16}, {32, 32}}, /* 16 bits per pixel */
54 {{ 64, 8}, {32, 16}, { 0, 0}}, /* 32 bits per pixel */
55 {{ 32, 8}, {16, 16}, { 0, 0}}, /* 64 bits per pixel */
56 {{ 16, 8}, { 0, 0}, { 0, 0}} /* 128 bits per pixel */
57 }
58 };
59
60 unsigned tile = 0;
61 unsigned pixsize = util_format_get_blocksize(format);
62
63 assert(macrotile <= RADEON_LAYOUT_TILED);
64 assert(microtile <= RADEON_LAYOUT_SQUARETILED);
65 assert(pixsize <= 16);
66 assert(dim <= DIM_HEIGHT);
67
68 tile = table[macrotile][util_logbase2(pixsize)][microtile][dim];
69 if (macrotile == 0 && is_rs690 && dim == DIM_WIDTH) {
70 int align;
71 int h_tile;
72 h_tile = table[macrotile][util_logbase2(pixsize)][microtile][DIM_HEIGHT];
73 align = 64 / (pixsize * h_tile);
74 if (tile < align)
75 tile = align;
76 }
77
78 assert(tile);
79 return tile;
80 }
81
82 /* Return true if macrotiling should be enabled on the miplevel. */
r300_texture_macro_switch(struct r300_resource * tex,unsigned level,boolean rv350_mode,enum r300_dim dim)83 static boolean r300_texture_macro_switch(struct r300_resource *tex,
84 unsigned level,
85 boolean rv350_mode,
86 enum r300_dim dim)
87 {
88 unsigned tile, texdim;
89
90 if (tex->b.b.nr_samples > 1) {
91 return TRUE;
92 }
93
94 tile = r300_get_pixel_alignment(tex->b.b.format, tex->b.b.nr_samples,
95 tex->tex.microtile, RADEON_LAYOUT_TILED, dim, 0);
96 if (dim == DIM_WIDTH) {
97 texdim = u_minify(tex->tex.width0, level);
98 } else {
99 texdim = u_minify(tex->tex.height0, level);
100 }
101
102 /* See TX_FILTER1_n.MACRO_SWITCH. */
103 if (rv350_mode) {
104 return texdim >= tile;
105 } else {
106 return texdim > tile;
107 }
108 }
109
110 /**
111 * Return the stride, in bytes, of the texture image of the given texture
112 * at the given level.
113 */
r300_texture_get_stride(struct r300_screen * screen,struct r300_resource * tex,unsigned level)114 static unsigned r300_texture_get_stride(struct r300_screen *screen,
115 struct r300_resource *tex,
116 unsigned level)
117 {
118 unsigned tile_width, width, stride;
119 boolean is_rs690 = (screen->caps.family == CHIP_RS600 ||
120 screen->caps.family == CHIP_RS690 ||
121 screen->caps.family == CHIP_RS740);
122
123 if (tex->tex.stride_in_bytes_override)
124 return tex->tex.stride_in_bytes_override;
125
126 /* Check the level. */
127 if (level > tex->b.b.last_level) {
128 SCREEN_DBG(screen, DBG_TEX, "%s: level (%u) > last_level (%u)\n",
129 __FUNCTION__, level, tex->b.b.last_level);
130 return 0;
131 }
132
133 width = u_minify(tex->tex.width0, level);
134
135 if (util_format_is_plain(tex->b.b.format)) {
136 tile_width = r300_get_pixel_alignment(tex->b.b.format,
137 tex->b.b.nr_samples,
138 tex->tex.microtile,
139 tex->tex.macrotile[level],
140 DIM_WIDTH, is_rs690);
141 width = align(width, tile_width);
142
143 stride = util_format_get_stride(tex->b.b.format, width);
144 /* The alignment to 32 bytes is sort of implied by the layout... */
145 return stride;
146 } else {
147 return align(util_format_get_stride(tex->b.b.format, width), is_rs690 ? 64 : 32);
148 }
149 }
150
r300_texture_get_nblocksy(struct r300_resource * tex,unsigned level,boolean * out_aligned_for_cbzb)151 static unsigned r300_texture_get_nblocksy(struct r300_resource *tex,
152 unsigned level,
153 boolean *out_aligned_for_cbzb)
154 {
155 unsigned height, tile_height;
156
157 height = u_minify(tex->tex.height0, level);
158
159 /* Mipmapped and 3D textures must have their height aligned to POT. */
160 if ((tex->b.b.target != PIPE_TEXTURE_1D &&
161 tex->b.b.target != PIPE_TEXTURE_2D &&
162 tex->b.b.target != PIPE_TEXTURE_RECT) ||
163 tex->b.b.last_level != 0) {
164 height = util_next_power_of_two(height);
165 }
166
167 if (util_format_is_plain(tex->b.b.format)) {
168 tile_height = r300_get_pixel_alignment(tex->b.b.format,
169 tex->b.b.nr_samples,
170 tex->tex.microtile,
171 tex->tex.macrotile[level],
172 DIM_HEIGHT, 0);
173 height = align(height, tile_height);
174
175 /* See if the CBZB clear can be used on the buffer,
176 * taking the texture size into account. */
177 if (out_aligned_for_cbzb) {
178 if (tex->tex.macrotile[level]) {
179 /* When clearing, the layer (width*height) is horizontally split
180 * into two, and the upper and lower halves are cleared by the CB
181 * and ZB units, respectively. Therefore, the number of macrotiles
182 * in the Y direction must be even. */
183
184 /* Align the height so that there is an even number of macrotiles.
185 * Do so for 3 or more macrotiles in the Y direction. */
186 if (level == 0 && tex->b.b.last_level == 0 &&
187 (tex->b.b.target == PIPE_TEXTURE_1D ||
188 tex->b.b.target == PIPE_TEXTURE_2D ||
189 tex->b.b.target == PIPE_TEXTURE_RECT) &&
190 height >= tile_height * 3) {
191 height = align(height, tile_height * 2);
192 }
193
194 *out_aligned_for_cbzb = height % (tile_height * 2) == 0;
195 } else {
196 *out_aligned_for_cbzb = FALSE;
197 }
198 }
199 }
200
201 return util_format_get_nblocksy(tex->b.b.format, height);
202 }
203
204 /* Get a width in pixels from a stride in bytes. */
r300_stride_to_width(enum pipe_format format,unsigned stride_in_bytes)205 unsigned r300_stride_to_width(enum pipe_format format,
206 unsigned stride_in_bytes)
207 {
208 return (stride_in_bytes / util_format_get_blocksize(format)) *
209 util_format_get_blockwidth(format);
210 }
211
r300_setup_miptree(struct r300_screen * screen,struct r300_resource * tex,boolean align_for_cbzb)212 static void r300_setup_miptree(struct r300_screen *screen,
213 struct r300_resource *tex,
214 boolean align_for_cbzb)
215 {
216 struct pipe_resource *base = &tex->b.b;
217 unsigned stride, size, layer_size, nblocksy, i;
218 boolean rv350_mode = screen->caps.family >= CHIP_R350;
219 boolean aligned_for_cbzb;
220
221 tex->tex.size_in_bytes = 0;
222
223 SCREEN_DBG(screen, DBG_TEXALLOC,
224 "r300: Making miptree for texture, format %s\n",
225 util_format_short_name(base->format));
226
227 for (i = 0; i <= base->last_level; i++) {
228 /* Let's see if this miplevel can be macrotiled. */
229 tex->tex.macrotile[i] =
230 (tex->tex.macrotile[0] == RADEON_LAYOUT_TILED &&
231 r300_texture_macro_switch(tex, i, rv350_mode, DIM_WIDTH) &&
232 r300_texture_macro_switch(tex, i, rv350_mode, DIM_HEIGHT)) ?
233 RADEON_LAYOUT_TILED : RADEON_LAYOUT_LINEAR;
234
235 stride = r300_texture_get_stride(screen, tex, i);
236
237 /* Compute the number of blocks in Y, see if the CBZB clear can be
238 * used on the texture. */
239 aligned_for_cbzb = FALSE;
240 if (align_for_cbzb && tex->tex.cbzb_allowed[i])
241 nblocksy = r300_texture_get_nblocksy(tex, i, &aligned_for_cbzb);
242 else
243 nblocksy = r300_texture_get_nblocksy(tex, i, NULL);
244
245 layer_size = stride * nblocksy;
246
247 if (base->nr_samples > 1) {
248 layer_size *= base->nr_samples;
249 }
250
251 if (base->target == PIPE_TEXTURE_CUBE)
252 size = layer_size * 6;
253 else
254 size = layer_size * u_minify(tex->tex.depth0, i);
255
256 tex->tex.offset_in_bytes[i] = tex->tex.size_in_bytes;
257 tex->tex.size_in_bytes = tex->tex.offset_in_bytes[i] + size;
258 tex->tex.layer_size_in_bytes[i] = layer_size;
259 tex->tex.stride_in_bytes[i] = stride;
260 tex->tex.cbzb_allowed[i] = tex->tex.cbzb_allowed[i] && aligned_for_cbzb;
261
262 SCREEN_DBG(screen, DBG_TEXALLOC, "r300: Texture miptree: Level %d "
263 "(%dx%dx%d px, pitch %d bytes) %d bytes total, macrotiled %s\n",
264 i, u_minify(tex->tex.width0, i), u_minify(tex->tex.height0, i),
265 u_minify(tex->tex.depth0, i), stride, tex->tex.size_in_bytes,
266 tex->tex.macrotile[i] ? "TRUE" : "FALSE");
267 }
268 }
269
r300_setup_flags(struct r300_resource * tex)270 static void r300_setup_flags(struct r300_resource *tex)
271 {
272 tex->tex.uses_stride_addressing =
273 !util_is_power_of_two(tex->b.b.width0) ||
274 (tex->tex.stride_in_bytes_override &&
275 r300_stride_to_width(tex->b.b.format,
276 tex->tex.stride_in_bytes_override) != tex->b.b.width0);
277
278 tex->tex.is_npot =
279 tex->tex.uses_stride_addressing ||
280 !util_is_power_of_two(tex->b.b.height0) ||
281 !util_is_power_of_two(tex->b.b.depth0);
282 }
283
r300_setup_cbzb_flags(struct r300_screen * rscreen,struct r300_resource * tex)284 static void r300_setup_cbzb_flags(struct r300_screen *rscreen,
285 struct r300_resource *tex)
286 {
287 unsigned i, bpp;
288 boolean first_level_valid;
289
290 bpp = util_format_get_blocksizebits(tex->b.b.format);
291
292 /* 1) The texture must be point-sampled,
293 * 2) The depth must be 16 or 32 bits.
294 * 3) If the midpoint ZB offset is not aligned to 2048, it returns garbage
295 * with certain texture sizes. Macrotiling ensures the alignment. */
296 first_level_valid = tex->b.b.nr_samples <= 1 &&
297 (bpp == 16 || bpp == 32) &&
298 tex->tex.macrotile[0];
299
300 if (SCREEN_DBG_ON(rscreen, DBG_NO_CBZB))
301 first_level_valid = FALSE;
302
303 for (i = 0; i <= tex->b.b.last_level; i++)
304 tex->tex.cbzb_allowed[i] = first_level_valid && tex->tex.macrotile[i];
305 }
306
r300_pixels_to_dwords(unsigned stride,unsigned height,unsigned xblock,unsigned yblock)307 static unsigned r300_pixels_to_dwords(unsigned stride,
308 unsigned height,
309 unsigned xblock, unsigned yblock)
310 {
311 return (util_align_npot(stride, xblock) * align(height, yblock)) / (xblock * yblock);
312 }
313
r300_setup_hyperz_properties(struct r300_screen * screen,struct r300_resource * tex)314 static void r300_setup_hyperz_properties(struct r300_screen *screen,
315 struct r300_resource *tex)
316 {
317 /* The tile size of 1 DWORD in ZMASK RAM is:
318 *
319 * GPU Pipes 4x4 mode 8x8 mode
320 * ------------------------------------------
321 * R580 4P/1Z 32x32 64x64
322 * RV570 3P/1Z 48x16 96x32
323 * RV530 1P/2Z 32x16 64x32
324 * 1P/1Z 16x16 32x32
325 */
326 static unsigned zmask_blocks_x_per_dw[4] = {4, 8, 12, 8};
327 static unsigned zmask_blocks_y_per_dw[4] = {4, 4, 4, 8};
328
329 /* In HIZ RAM, one dword is always 8x8 pixels (each byte is 4x4 pixels),
330 * but the blocks have very weird ordering.
331 *
332 * With 2 pipes and an image of size 8xY, where Y >= 1,
333 * clearing 4 dwords clears blocks like this:
334 *
335 * 01012323
336 *
337 * where numbers correspond to dword indices. The blocks are interleaved
338 * in the X direction, so the alignment must be 4x1 blocks (32x8 pixels).
339 *
340 * With 4 pipes and an image of size 8xY, where Y >= 4,
341 * clearing 8 dwords clears blocks like this:
342 * 01012323
343 * 45456767
344 * 01012323
345 * 45456767
346 * where numbers correspond to dword indices. The blocks are interleaved
347 * in both directions, so the alignment must be 4x4 blocks (32x32 pixels)
348 */
349 static unsigned hiz_align_x[4] = {8, 32, 48, 32};
350 static unsigned hiz_align_y[4] = {8, 8, 8, 32};
351
352 if (util_format_is_depth_or_stencil(tex->b.b.format) &&
353 util_format_get_blocksizebits(tex->b.b.format) == 32 &&
354 tex->tex.microtile) {
355 unsigned i, pipes;
356
357 if (screen->caps.family == CHIP_RV530) {
358 pipes = screen->info.r300_num_z_pipes;
359 } else {
360 pipes = screen->info.r300_num_gb_pipes;
361 }
362
363 for (i = 0; i <= tex->b.b.last_level; i++) {
364 unsigned zcomp_numdw, zcompsize, hiz_numdw, stride, height;
365
366 stride = r300_stride_to_width(tex->b.b.format,
367 tex->tex.stride_in_bytes[i]);
368 stride = align(stride, 16);
369 height = u_minify(tex->b.b.height0, i);
370
371 /* The 8x8 compression mode needs macrotiling. */
372 zcompsize = screen->caps.z_compress == R300_ZCOMP_8X8 &&
373 tex->tex.macrotile[i] &&
374 tex->b.b.nr_samples <= 1 ? 8 : 4;
375
376 /* Get the ZMASK buffer size in dwords. */
377 zcomp_numdw = r300_pixels_to_dwords(stride, height,
378 zmask_blocks_x_per_dw[pipes-1] * zcompsize,
379 zmask_blocks_y_per_dw[pipes-1] * zcompsize);
380
381 /* Check whether we have enough ZMASK memory. */
382 if (util_format_get_blocksizebits(tex->b.b.format) == 32 &&
383 zcomp_numdw <= screen->caps.zmask_ram * pipes) {
384 tex->tex.zmask_dwords[i] = zcomp_numdw;
385 tex->tex.zcomp8x8[i] = zcompsize == 8;
386
387 tex->tex.zmask_stride_in_pixels[i] =
388 util_align_npot(stride, zmask_blocks_x_per_dw[pipes-1] * zcompsize);
389 } else {
390 tex->tex.zmask_dwords[i] = 0;
391 tex->tex.zcomp8x8[i] = FALSE;
392 tex->tex.zmask_stride_in_pixels[i] = 0;
393 }
394
395 /* Now setup HIZ. */
396 stride = util_align_npot(stride, hiz_align_x[pipes-1]);
397 height = align(height, hiz_align_y[pipes-1]);
398
399 /* Get the HIZ buffer size in dwords. */
400 hiz_numdw = (stride * height) / (8*8 * pipes);
401
402 /* Check whether we have enough HIZ memory. */
403 if (hiz_numdw <= screen->caps.hiz_ram * pipes) {
404 tex->tex.hiz_dwords[i] = hiz_numdw;
405 tex->tex.hiz_stride_in_pixels[i] = stride;
406 } else {
407 tex->tex.hiz_dwords[i] = 0;
408 tex->tex.hiz_stride_in_pixels[i] = 0;
409 }
410 }
411 }
412 }
413
r300_setup_cmask_properties(struct r300_screen * screen,struct r300_resource * tex)414 static void r300_setup_cmask_properties(struct r300_screen *screen,
415 struct r300_resource *tex)
416 {
417 static unsigned cmask_align_x[4] = {16, 32, 48, 32};
418 static unsigned cmask_align_y[4] = {16, 16, 16, 32};
419 unsigned pipes, stride, cmask_num_dw, cmask_max_size;
420
421 if (!screen->caps.has_cmask) {
422 return;
423 }
424
425 /* We need an AA colorbuffer, no mipmaps. */
426 if (tex->b.b.nr_samples <= 1 ||
427 tex->b.b.last_level > 0 ||
428 util_format_is_depth_or_stencil(tex->b.b.format)) {
429 return;
430 }
431
432 /* FP16 AA needs R500 and a fairly new DRM. */
433 if ((tex->b.b.format == PIPE_FORMAT_R16G16B16A16_FLOAT ||
434 tex->b.b.format == PIPE_FORMAT_R16G16B16X16_FLOAT) &&
435 (!screen->caps.is_r500 || screen->info.drm_minor < 29)) {
436 return;
437 }
438
439 if (SCREEN_DBG_ON(screen, DBG_NO_CMASK)) {
440 return;
441 }
442
443 /* CMASK is part of raster pipes. The number of Z pipes doesn't matter. */
444 pipes = screen->info.r300_num_gb_pipes;
445
446 /* The single-pipe cards have 5120 dwords of CMASK RAM,
447 * the other cards have 4096 dwords of CMASK RAM per pipe. */
448 cmask_max_size = pipes == 1 ? 5120 : pipes * 4096;
449
450 stride = r300_stride_to_width(tex->b.b.format,
451 tex->tex.stride_in_bytes[0]);
452 stride = align(stride, 16);
453
454 /* Get the CMASK size in dwords. */
455 cmask_num_dw = r300_pixels_to_dwords(stride, tex->b.b.height0,
456 cmask_align_x[pipes-1],
457 cmask_align_y[pipes-1]);
458
459 /* Check the CMASK size against the CMASK memory limit. */
460 if (cmask_num_dw <= cmask_max_size) {
461 tex->tex.cmask_dwords = cmask_num_dw;
462 tex->tex.cmask_stride_in_pixels =
463 util_align_npot(stride, cmask_align_x[pipes-1]);
464 }
465 }
466
r300_setup_tiling(struct r300_screen * screen,struct r300_resource * tex)467 static void r300_setup_tiling(struct r300_screen *screen,
468 struct r300_resource *tex)
469 {
470 enum pipe_format format = tex->b.b.format;
471 boolean rv350_mode = screen->caps.family >= CHIP_R350;
472 boolean is_zb = util_format_is_depth_or_stencil(format);
473 boolean dbg_no_tiling = SCREEN_DBG_ON(screen, DBG_NO_TILING);
474 boolean force_microtiling =
475 (tex->b.b.flags & R300_RESOURCE_FORCE_MICROTILING) != 0;
476
477 if (tex->b.b.nr_samples > 1) {
478 tex->tex.microtile = RADEON_LAYOUT_TILED;
479 tex->tex.macrotile[0] = RADEON_LAYOUT_TILED;
480 return;
481 }
482
483 tex->tex.microtile = RADEON_LAYOUT_LINEAR;
484 tex->tex.macrotile[0] = RADEON_LAYOUT_LINEAR;
485
486 if (tex->b.b.usage == PIPE_USAGE_STAGING) {
487 return;
488 }
489
490 if (!util_format_is_plain(format)) {
491 return;
492 }
493
494 /* If height == 1, disable microtiling except for zbuffer. */
495 if (!force_microtiling && !is_zb &&
496 (tex->b.b.height0 == 1 || dbg_no_tiling)) {
497 return;
498 }
499
500 /* Set microtiling. */
501 switch (util_format_get_blocksize(format)) {
502 case 1:
503 case 4:
504 case 8:
505 tex->tex.microtile = RADEON_LAYOUT_TILED;
506 break;
507
508 case 2:
509 tex->tex.microtile = RADEON_LAYOUT_SQUARETILED;
510 break;
511 }
512
513 if (dbg_no_tiling) {
514 return;
515 }
516
517 /* Set macrotiling. */
518 if (r300_texture_macro_switch(tex, 0, rv350_mode, DIM_WIDTH) &&
519 r300_texture_macro_switch(tex, 0, rv350_mode, DIM_HEIGHT)) {
520 tex->tex.macrotile[0] = RADEON_LAYOUT_TILED;
521 }
522 }
523
r300_tex_print_info(struct r300_resource * tex,const char * func)524 static void r300_tex_print_info(struct r300_resource *tex,
525 const char *func)
526 {
527 fprintf(stderr,
528 "r300: %s: Macro: %s, Micro: %s, Pitch: %i, Dim: %ix%ix%i, "
529 "LastLevel: %i, Size: %i, Format: %s, Samples: %i\n",
530 func,
531 tex->tex.macrotile[0] ? "YES" : " NO",
532 tex->tex.microtile ? "YES" : " NO",
533 r300_stride_to_width(tex->b.b.format, tex->tex.stride_in_bytes[0]),
534 tex->b.b.width0, tex->b.b.height0, tex->b.b.depth0,
535 tex->b.b.last_level, tex->tex.size_in_bytes,
536 util_format_short_name(tex->b.b.format),
537 tex->b.b.nr_samples);
538 }
539
r300_texture_desc_init(struct r300_screen * rscreen,struct r300_resource * tex,const struct pipe_resource * base)540 void r300_texture_desc_init(struct r300_screen *rscreen,
541 struct r300_resource *tex,
542 const struct pipe_resource *base)
543 {
544 tex->b.b.target = base->target;
545 tex->b.b.format = base->format;
546 tex->b.b.width0 = base->width0;
547 tex->b.b.height0 = base->height0;
548 tex->b.b.depth0 = base->depth0;
549 tex->b.b.array_size = base->array_size;
550 tex->b.b.last_level = base->last_level;
551 tex->b.b.nr_samples = base->nr_samples;
552 tex->tex.width0 = base->width0;
553 tex->tex.height0 = base->height0;
554 tex->tex.depth0 = base->depth0;
555
556 /* There is a CB memory addressing hardware bug that limits the width
557 * of the MSAA buffer in some cases in R520. In order to get around it,
558 * the following code lowers the sample count depending on the format and
559 * the width.
560 *
561 * The only catch is that all MSAA colorbuffers and a zbuffer which are
562 * supposed to be used together should always be bound together. Only
563 * then the correct minimum sample count of all bound buffers is used
564 * for rendering. */
565 if (rscreen->caps.is_r500) {
566 /* FP16 6x MSAA buffers are limited to a width of 1360 pixels. */
567 if ((tex->b.b.format == PIPE_FORMAT_R16G16B16A16_FLOAT ||
568 tex->b.b.format == PIPE_FORMAT_R16G16B16X16_FLOAT) &&
569 tex->b.b.nr_samples == 6 && tex->b.b.width0 > 1360) {
570 tex->b.b.nr_samples = 4;
571 }
572
573 /* FP16 4x MSAA buffers are limited to a width of 2048 pixels. */
574 if ((tex->b.b.format == PIPE_FORMAT_R16G16B16A16_FLOAT ||
575 tex->b.b.format == PIPE_FORMAT_R16G16B16X16_FLOAT) &&
576 tex->b.b.nr_samples == 4 && tex->b.b.width0 > 2048) {
577 tex->b.b.nr_samples = 2;
578 }
579 }
580
581 /* 32-bit 6x MSAA buffers are limited to a width of 2720 pixels.
582 * This applies to all R300-R500 cards. */
583 if (util_format_get_blocksizebits(tex->b.b.format) == 32 &&
584 !util_format_is_depth_or_stencil(tex->b.b.format) &&
585 tex->b.b.nr_samples == 6 && tex->b.b.width0 > 2720) {
586 tex->b.b.nr_samples = 4;
587 }
588
589 r300_setup_flags(tex);
590
591 /* Align a 3D NPOT texture to POT. */
592 if (base->target == PIPE_TEXTURE_3D && tex->tex.is_npot) {
593 tex->tex.width0 = util_next_power_of_two(tex->tex.width0);
594 tex->tex.height0 = util_next_power_of_two(tex->tex.height0);
595 tex->tex.depth0 = util_next_power_of_two(tex->tex.depth0);
596 }
597
598 /* Setup tiling. */
599 if (tex->tex.microtile == RADEON_LAYOUT_UNKNOWN) {
600 r300_setup_tiling(rscreen, tex);
601 }
602
603 r300_setup_cbzb_flags(rscreen, tex);
604
605 /* Setup the miptree description. */
606 r300_setup_miptree(rscreen, tex, TRUE);
607 /* If the required buffer size is larger than the given max size,
608 * try again without the alignment for the CBZB clear. */
609 if (tex->buf && tex->tex.size_in_bytes > tex->buf->size) {
610 r300_setup_miptree(rscreen, tex, FALSE);
611
612 /* Make sure the buffer we got is large enough. */
613 if (tex->tex.size_in_bytes > tex->buf->size) {
614 fprintf(stderr,
615 "r300: I got a pre-allocated buffer to use it as a texture "
616 "storage, but the buffer is too small. I'll use the buffer "
617 "anyway, because I can't crash here, but it's dangerous. "
618 "This can be a DDX bug. Got: %"PRIu64"B, Need: %uB, Info:\n",
619 tex->buf->size, tex->tex.size_in_bytes);
620 r300_tex_print_info(tex, "texture_desc_init");
621 /* Ooops, what now. Apps will break if we fail this,
622 * so just pretend everything's okay. */
623 }
624 }
625
626 r300_setup_hyperz_properties(rscreen, tex);
627 r300_setup_cmask_properties(rscreen, tex);
628
629 if (SCREEN_DBG_ON(rscreen, DBG_TEX))
630 r300_tex_print_info(tex, "texture_desc_init");
631 }
632
r300_texture_get_offset(struct r300_resource * tex,unsigned level,unsigned layer)633 unsigned r300_texture_get_offset(struct r300_resource *tex,
634 unsigned level, unsigned layer)
635 {
636 unsigned offset = tex->tex.offset_in_bytes[level];
637
638 switch (tex->b.b.target) {
639 case PIPE_TEXTURE_3D:
640 case PIPE_TEXTURE_CUBE:
641 return offset + layer * tex->tex.layer_size_in_bytes[level];
642
643 default:
644 assert(layer == 0);
645 return offset;
646 }
647 }
648