Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/drivers/r300/r300_texture_desc.c
4570 views
1
/*
2
* Copyright 2008 Corbin Simpson <[email protected]>
3
* Copyright 2010 Marek Olšák <[email protected]>
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/format/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. */
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. */
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.nr_samples > 1) {
91
return TRUE;
92
}
93
94
tile = r300_get_pixel_alignment(tex->b.format, tex->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
*/
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.last_level) {
128
SCREEN_DBG(screen, DBG_TEX, "%s: level (%u) > last_level (%u)\n",
129
__FUNCTION__, level, tex->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.format)) {
136
tile_width = r300_get_pixel_alignment(tex->b.format,
137
tex->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.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.format, width), is_rs690 ? 64 : 32);
148
}
149
}
150
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.target != PIPE_TEXTURE_1D &&
161
tex->b.target != PIPE_TEXTURE_2D &&
162
tex->b.target != PIPE_TEXTURE_RECT) ||
163
tex->b.last_level != 0) {
164
height = util_next_power_of_two(height);
165
}
166
167
if (util_format_is_plain(tex->b.format)) {
168
tile_height = r300_get_pixel_alignment(tex->b.format,
169
tex->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.last_level == 0 &&
187
(tex->b.target == PIPE_TEXTURE_1D ||
188
tex->b.target == PIPE_TEXTURE_2D ||
189
tex->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.format, height);
202
}
203
204
/* Get a width in pixels from a 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
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;
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
270
static void r300_setup_flags(struct r300_resource *tex)
271
{
272
tex->tex.uses_stride_addressing =
273
!util_is_power_of_two_or_zero(tex->b.width0) ||
274
(tex->tex.stride_in_bytes_override &&
275
r300_stride_to_width(tex->b.format,
276
tex->tex.stride_in_bytes_override) != tex->b.width0);
277
278
tex->tex.is_npot =
279
tex->tex.uses_stride_addressing ||
280
!util_is_power_of_two_or_zero(tex->b.height0) ||
281
!util_is_power_of_two_or_zero(tex->b.depth0);
282
}
283
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.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.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.last_level; i++)
304
tex->tex.cbzb_allowed[i] = first_level_valid && tex->tex.macrotile[i];
305
}
306
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
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.format) &&
353
util_format_get_blocksizebits(tex->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.last_level; i++) {
364
unsigned zcomp_numdw, zcompsize, hiz_numdw, stride, height;
365
366
stride = r300_stride_to_width(tex->b.format,
367
tex->tex.stride_in_bytes[i]);
368
stride = align(stride, 16);
369
height = u_minify(tex->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.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.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
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.nr_samples <= 1 ||
427
tex->b.last_level > 0 ||
428
util_format_is_depth_or_stencil(tex->b.format)) {
429
return;
430
}
431
432
/* FP16 AA needs R500 and a fairly new DRM. */
433
if ((tex->b.format == PIPE_FORMAT_R16G16B16A16_FLOAT ||
434
tex->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.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.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
467
static void r300_setup_tiling(struct r300_screen *screen,
468
struct r300_resource *tex)
469
{
470
enum pipe_format format = tex->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.flags & R300_RESOURCE_FORCE_MICROTILING) != 0;
476
477
if (tex->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.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.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
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.format, tex->tex.stride_in_bytes[0]),
534
tex->b.width0, tex->b.height0, tex->b.depth0,
535
tex->b.last_level, tex->tex.size_in_bytes,
536
util_format_short_name(tex->b.format),
537
tex->b.nr_samples);
538
}
539
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.target = base->target;
545
tex->b.format = base->format;
546
tex->b.width0 = base->width0;
547
tex->b.height0 = base->height0;
548
tex->b.depth0 = base->depth0;
549
tex->b.array_size = base->array_size;
550
tex->b.last_level = base->last_level;
551
tex->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.format == PIPE_FORMAT_R16G16B16A16_FLOAT ||
568
tex->b.format == PIPE_FORMAT_R16G16B16X16_FLOAT) &&
569
tex->b.nr_samples == 6 && tex->b.width0 > 1360) {
570
tex->b.nr_samples = 4;
571
}
572
573
/* FP16 4x MSAA buffers are limited to a width of 2048 pixels. */
574
if ((tex->b.format == PIPE_FORMAT_R16G16B16A16_FLOAT ||
575
tex->b.format == PIPE_FORMAT_R16G16B16X16_FLOAT) &&
576
tex->b.nr_samples == 4 && tex->b.width0 > 2048) {
577
tex->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.format) == 32 &&
584
!util_format_is_depth_or_stencil(tex->b.format) &&
585
tex->b.nr_samples == 6 && tex->b.width0 > 2720) {
586
tex->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
/* Oops, 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
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.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
649