r300g,u_blitter: use u_framebuffer
[mesa.git] / src / gallium / drivers / r300 / r300_texture_desc.c
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. */
33 unsigned 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. */
84 static 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 */
111 static 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 if (!desc->macrotile[level] &&
141 (screen->caps.family == CHIP_FAMILY_RS600 ||
142 screen->caps.family == CHIP_FAMILY_RS690 ||
143 screen->caps.family == CHIP_FAMILY_RS740)) {
144 unsigned min_stride;
145
146 if (desc->microtile) {
147 unsigned tile_height =
148 r300_get_pixel_alignment(desc->b.b.format,
149 desc->b.b.nr_samples,
150 desc->microtile,
151 desc->macrotile[level],
152 DIM_HEIGHT);
153
154 min_stride = 64 / tile_height;
155 } else {
156 min_stride = 64;
157 }
158
159 return stride < min_stride ? min_stride : stride;
160 }
161
162 /* The alignment to 32 bytes is sort of implied by the layout... */
163 return stride;
164 } else {
165 return align(util_format_get_stride(desc->b.b.format, width), 32);
166 }
167 }
168
169 static unsigned r300_texture_get_nblocksy(struct r300_texture_desc *desc,
170 unsigned level,
171 boolean *out_aligned_for_cbzb)
172 {
173 unsigned height, tile_height;
174
175 height = u_minify(desc->b.b.height0, level);
176
177 if (util_format_is_plain(desc->b.b.format)) {
178 tile_height = r300_get_pixel_alignment(desc->b.b.format,
179 desc->b.b.nr_samples,
180 desc->microtile,
181 desc->macrotile[level],
182 DIM_HEIGHT);
183 height = align(height, tile_height);
184
185 /* This is needed for the kernel checker, unfortunately. */
186 if ((desc->b.b.target != PIPE_TEXTURE_1D &&
187 desc->b.b.target != PIPE_TEXTURE_2D &&
188 desc->b.b.target != PIPE_TEXTURE_RECT) ||
189 desc->b.b.last_level != 0) {
190 height = util_next_power_of_two(height);
191 }
192
193 /* See if the CBZB clear can be used on the buffer,
194 * taking the texture size into account. */
195 if (out_aligned_for_cbzb) {
196 if (desc->macrotile[level]) {
197 /* When clearing, the layer (width*height) is horizontally split
198 * into two, and the upper and lower halves are cleared by the CB
199 * and ZB units, respectively. Therefore, the number of macrotiles
200 * in the Y direction must be even. */
201
202 /* Align the height so that there is an even number of macrotiles.
203 * Do so for 3 or more macrotiles in the Y direction. */
204 if (level == 0 && desc->b.b.last_level == 0 &&
205 (desc->b.b.target == PIPE_TEXTURE_1D ||
206 desc->b.b.target == PIPE_TEXTURE_2D ||
207 desc->b.b.target == PIPE_TEXTURE_RECT) &&
208 height >= tile_height * 3) {
209 height = align(height, tile_height * 2);
210 }
211
212 *out_aligned_for_cbzb = height % (tile_height * 2) == 0;
213 } else {
214 *out_aligned_for_cbzb = FALSE;
215 }
216 }
217 }
218
219 return util_format_get_nblocksy(desc->b.b.format, height);
220 }
221
222 static void r300_texture_3d_fix_mipmapping(struct r300_screen *screen,
223 struct r300_texture_desc *desc)
224 {
225 /* The kernels <= 2.6.34-rc4 compute the size of mipmapped 3D textures
226 * incorrectly. This is a workaround to prevent CS from being rejected. */
227
228 unsigned i, size;
229
230 if (!screen->rws->get_value(screen->rws, R300_VID_DRM_2_3_0) &&
231 desc->b.b.target == PIPE_TEXTURE_3D &&
232 desc->b.b.last_level > 0) {
233 size = 0;
234
235 for (i = 0; i <= desc->b.b.last_level; i++) {
236 size += desc->stride_in_bytes[i] *
237 r300_texture_get_nblocksy(desc, i, FALSE);
238 }
239
240 size *= desc->b.b.depth0;
241 desc->size_in_bytes = size;
242 }
243 }
244
245 /* Get a width in pixels from a stride in bytes. */
246 static unsigned stride_to_width(enum pipe_format format,
247 unsigned stride_in_bytes)
248 {
249 return (stride_in_bytes / util_format_get_blocksize(format)) *
250 util_format_get_blockwidth(format);
251 }
252
253 static void r300_setup_miptree(struct r300_screen *screen,
254 struct r300_texture_desc *desc,
255 boolean align_for_cbzb)
256 {
257 struct pipe_resource *base = &desc->b.b;
258 unsigned stride, size, layer_size, nblocksy, i;
259 boolean rv350_mode = screen->caps.is_rv350;
260 boolean aligned_for_cbzb;
261
262 desc->size_in_bytes = 0;
263
264 SCREEN_DBG(screen, DBG_TEXALLOC,
265 "r300: Making miptree for texture, format %s\n",
266 util_format_short_name(base->format));
267
268 for (i = 0; i <= base->last_level; i++) {
269 /* Let's see if this miplevel can be macrotiled. */
270 desc->macrotile[i] =
271 (desc->macrotile[0] == R300_BUFFER_TILED &&
272 r300_texture_macro_switch(desc, i, rv350_mode, DIM_WIDTH) &&
273 r300_texture_macro_switch(desc, i, rv350_mode, DIM_HEIGHT)) ?
274 R300_BUFFER_TILED : R300_BUFFER_LINEAR;
275
276 stride = r300_texture_get_stride(screen, desc, i);
277
278 /* Compute the number of blocks in Y, see if the CBZB clear can be
279 * used on the texture. */
280 aligned_for_cbzb = FALSE;
281 if (align_for_cbzb && desc->cbzb_allowed[i])
282 nblocksy = r300_texture_get_nblocksy(desc, i, &aligned_for_cbzb);
283 else
284 nblocksy = r300_texture_get_nblocksy(desc, i, NULL);
285
286 layer_size = stride * nblocksy;
287
288 if (base->nr_samples) {
289 layer_size *= base->nr_samples;
290 }
291
292 if (base->target == PIPE_TEXTURE_CUBE)
293 size = layer_size * 6;
294 else
295 size = layer_size * u_minify(base->depth0, i);
296
297 desc->offset_in_bytes[i] = desc->size_in_bytes;
298 desc->size_in_bytes = desc->offset_in_bytes[i] + size;
299 desc->layer_size_in_bytes[i] = layer_size;
300 desc->stride_in_bytes[i] = stride;
301 desc->stride_in_pixels[i] = stride_to_width(desc->b.b.format, stride);
302 desc->cbzb_allowed[i] = desc->cbzb_allowed[i] && aligned_for_cbzb;
303
304 SCREEN_DBG(screen, DBG_TEXALLOC, "r300: Texture miptree: Level %d "
305 "(%dx%dx%d px, pitch %d bytes) %d bytes total, macrotiled %s\n",
306 i, u_minify(base->width0, i), u_minify(base->height0, i),
307 u_minify(base->depth0, i), stride, desc->size_in_bytes,
308 desc->macrotile[i] ? "TRUE" : "FALSE");
309 }
310 }
311
312 static void r300_setup_flags(struct r300_texture_desc *desc)
313 {
314 desc->uses_stride_addressing =
315 !util_is_power_of_two(desc->b.b.width0) ||
316 !util_is_power_of_two(desc->b.b.height0) ||
317 (desc->stride_in_bytes_override &&
318 stride_to_width(desc->b.b.format,
319 desc->stride_in_bytes_override) != desc->b.b.width0);
320
321 desc->is_npot =
322 desc->uses_stride_addressing ||
323 !util_is_power_of_two(desc->b.b.height0);
324 }
325
326 static void r300_setup_cbzb_flags(struct r300_screen *rscreen,
327 struct r300_texture_desc *desc)
328 {
329 unsigned i, bpp;
330 boolean first_level_valid;
331
332 bpp = util_format_get_blocksizebits(desc->b.b.format);
333
334 /* 1) The texture must be point-sampled,
335 * 2) The depth must be 16 or 32 bits.
336 * 3) If the midpoint ZB offset is not aligned to 2048, it returns garbage
337 * with certain texture sizes. Macrotiling ensures the alignment. */
338 first_level_valid = desc->b.b.nr_samples <= 1 &&
339 (bpp == 16 || bpp == 32) &&
340 desc->macrotile[0];
341
342 for (i = 0; i <= desc->b.b.last_level; i++)
343 desc->cbzb_allowed[i] = first_level_valid && desc->macrotile[i];
344 }
345
346 static void r300_setup_tiling(struct r300_screen *screen,
347 struct r300_texture_desc *desc)
348 {
349 struct r300_winsys_screen *rws = screen->rws;
350 enum pipe_format format = desc->b.b.format;
351 boolean rv350_mode = screen->caps.is_rv350;
352 boolean is_zb = util_format_is_depth_or_stencil(format);
353 boolean dbg_no_tiling = SCREEN_DBG_ON(screen, DBG_NO_TILING);
354
355 if (!util_format_is_plain(format)) {
356 return;
357 }
358
359 /* If height == 1, disable microtiling except for zbuffer. */
360 if (!is_zb && (desc->b.b.height0 == 1 || dbg_no_tiling)) {
361 return;
362 }
363
364 /* Set microtiling. */
365 switch (util_format_get_blocksize(format)) {
366 case 1:
367 case 4:
368 desc->microtile = R300_BUFFER_TILED;
369 break;
370
371 case 2:
372 case 8:
373 if (rws->get_value(rws, R300_VID_SQUARE_TILING_SUPPORT)) {
374 desc->microtile = R300_BUFFER_SQUARETILED;
375 }
376 break;
377 }
378
379 if (dbg_no_tiling) {
380 return;
381 }
382
383 /* Set macrotiling. */
384 if (r300_texture_macro_switch(desc, 0, rv350_mode, DIM_WIDTH) &&
385 r300_texture_macro_switch(desc, 0, rv350_mode, DIM_HEIGHT)) {
386 desc->macrotile[0] = R300_BUFFER_TILED;
387 }
388 }
389
390 static void r300_tex_print_info(struct r300_screen *rscreen,
391 struct r300_texture_desc *desc,
392 const char *func)
393 {
394 fprintf(stderr,
395 "r300: %s: Macro: %s, Micro: %s, Pitch: %i, Dim: %ix%ix%i, "
396 "LastLevel: %i, Size: %i, Format: %s\n",
397 func,
398 desc->macrotile[0] ? "YES" : " NO",
399 desc->microtile ? "YES" : " NO",
400 desc->stride_in_pixels[0],
401 desc->b.b.width0, desc->b.b.height0, desc->b.b.depth0,
402 desc->b.b.last_level, desc->size_in_bytes,
403 util_format_short_name(desc->b.b.format));
404 }
405
406 boolean r300_texture_desc_init(struct r300_screen *rscreen,
407 struct r300_texture_desc *desc,
408 const struct pipe_resource *base,
409 enum r300_buffer_tiling microtile,
410 enum r300_buffer_tiling macrotile,
411 unsigned stride_in_bytes_override,
412 unsigned max_buffer_size)
413 {
414 desc->b.b = *base;
415 desc->b.b.screen = &rscreen->screen;
416
417 desc->stride_in_bytes_override = stride_in_bytes_override;
418
419 if (microtile == R300_BUFFER_SELECT_LAYOUT ||
420 macrotile == R300_BUFFER_SELECT_LAYOUT) {
421 r300_setup_tiling(rscreen, desc);
422 } else {
423 desc->microtile = microtile;
424 desc->macrotile[0] = macrotile;
425 assert(desc->b.b.last_level == 0);
426 }
427
428 r300_setup_flags(desc);
429 r300_setup_cbzb_flags(rscreen, desc);
430
431 /* Setup the miptree description. */
432 r300_setup_miptree(rscreen, desc, TRUE);
433 /* If the required buffer size is larger the given max size,
434 * try again without the alignment for the CBZB clear. */
435 if (max_buffer_size && desc->size_in_bytes > max_buffer_size) {
436 r300_setup_miptree(rscreen, desc, FALSE);
437 }
438
439 r300_texture_3d_fix_mipmapping(rscreen, desc);
440
441 if (max_buffer_size) {
442 /* Make sure the buffer we got is large enough. */
443 if (desc->size_in_bytes > max_buffer_size) {
444 fprintf(stderr, "r300: texture_from_handle: The buffer is not "
445 "large enough. Got: %i, Need: %i, Info:\n",
446 max_buffer_size, desc->size_in_bytes);
447 r300_tex_print_info(rscreen, desc, "texture_from_handle");
448 return FALSE;
449 }
450
451 desc->buffer_size_in_bytes = max_buffer_size;
452 } else {
453 desc->buffer_size_in_bytes = desc->size_in_bytes;
454 }
455
456 if (SCREEN_DBG_ON(rscreen, DBG_TEX))
457 r300_tex_print_info(rscreen, desc, "texture_from_handle");
458
459 return TRUE;
460 }
461
462 unsigned r300_texture_get_offset(struct r300_texture_desc *desc,
463 unsigned level, unsigned zslice,
464 unsigned face)
465 {
466 unsigned offset = desc->offset_in_bytes[level];
467
468 switch (desc->b.b.target) {
469 case PIPE_TEXTURE_3D:
470 assert(face == 0);
471 return offset + zslice * desc->layer_size_in_bytes[level];
472
473 case PIPE_TEXTURE_CUBE:
474 assert(zslice == 0);
475 return offset + face * desc->layer_size_in_bytes[level];
476
477 default:
478 assert(zslice == 0 && face == 0);
479 return offset;
480 }
481 }