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