Merge commit 'origin/7.8'
[mesa.git] / src / gallium / drivers / r300 / r300_texture.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 "pipe/p_screen.h"
25
26 #include "util/u_format.h"
27 #include "util/u_math.h"
28 #include "util/u_memory.h"
29
30 #include "r300_context.h"
31 #include "r300_reg.h"
32 #include "r300_texture.h"
33 #include "r300_transfer.h"
34 #include "r300_screen.h"
35 #include "r300_winsys.h"
36
37 /* XXX Enable float textures here. */
38 /*#define ENABLE_FLOAT_TEXTURES*/
39
40 #define TILE_WIDTH 0
41 #define TILE_HEIGHT 1
42
43 static const unsigned microblock_table[5][3][2] = {
44 /*linear tiled square-tiled */
45 {{32, 1}, {8, 4}, {0, 0}}, /* 8 bits per pixel */
46 {{16, 1}, {8, 2}, {4, 4}}, /* 16 bits per pixel */
47 {{ 8, 1}, {4, 2}, {0, 0}}, /* 32 bits per pixel */
48 {{ 4, 1}, {0, 0}, {2, 2}}, /* 64 bits per pixel */
49 {{ 2, 1}, {0, 0}, {0, 0}} /* 128 bits per pixel */
50 };
51
52 /* Return true for non-compressed and non-YUV formats. */
53 static boolean r300_format_is_plain(enum pipe_format format)
54 {
55 const struct util_format_description *desc = util_format_description(format);
56
57 if (!format) {
58 return FALSE;
59 }
60
61 return desc->layout == UTIL_FORMAT_LAYOUT_PLAIN;
62 }
63
64 /* Translate a pipe_format into a useful texture format for sampling.
65 *
66 * Some special formats are translated directly using R300_EASY_TX_FORMAT,
67 * but the majority of them is translated in a generic way, automatically
68 * supporting all the formats hw can support.
69 *
70 * R300_EASY_TX_FORMAT swizzles the texture.
71 * Note the signature of R300_EASY_TX_FORMAT:
72 * R300_EASY_TX_FORMAT(B, G, R, A, FORMAT);
73 *
74 * The FORMAT specifies how the texture sampler will treat the texture, and
75 * makes available X, Y, Z, W, ZERO, and ONE for swizzling. */
76 uint32_t r300_translate_texformat(enum pipe_format format,
77 const unsigned char *swizzle)
78 {
79 uint32_t result = 0;
80 const struct util_format_description *desc;
81 unsigned i;
82 boolean uniform = TRUE;
83 const uint32_t swizzle_shift[4] = {
84 R300_TX_FORMAT_R_SHIFT,
85 R300_TX_FORMAT_G_SHIFT,
86 R300_TX_FORMAT_B_SHIFT,
87 R300_TX_FORMAT_A_SHIFT
88 };
89 const uint32_t swizzle_bit[4] = {
90 R300_TX_FORMAT_X,
91 R300_TX_FORMAT_Y,
92 R300_TX_FORMAT_Z,
93 R300_TX_FORMAT_W
94 };
95 const uint32_t sign_bit[4] = {
96 R300_TX_FORMAT_SIGNED_X,
97 R300_TX_FORMAT_SIGNED_Y,
98 R300_TX_FORMAT_SIGNED_Z,
99 R300_TX_FORMAT_SIGNED_W,
100 };
101
102 desc = util_format_description(format);
103
104 /* Colorspace (return non-RGB formats directly). */
105 switch (desc->colorspace) {
106 /* Depth stencil formats. */
107 case UTIL_FORMAT_COLORSPACE_ZS:
108 switch (format) {
109 case PIPE_FORMAT_Z16_UNORM:
110 return R300_EASY_TX_FORMAT(X, X, X, X, X16);
111 case PIPE_FORMAT_X8Z24_UNORM:
112 case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
113 return R300_EASY_TX_FORMAT(X, X, X, X, W24_FP);
114 default:
115 return ~0; /* Unsupported. */
116 }
117
118 /* YUV formats. */
119 case UTIL_FORMAT_COLORSPACE_YUV:
120 result |= R300_TX_FORMAT_YUV_TO_RGB;
121
122 switch (format) {
123 case PIPE_FORMAT_UYVY:
124 return R300_EASY_TX_FORMAT(X, Y, Z, ONE, YVYU422) | result;
125 case PIPE_FORMAT_YUYV:
126 return R300_EASY_TX_FORMAT(X, Y, Z, ONE, VYUY422) | result;
127 default:
128 return ~0; /* Unsupported/unknown. */
129 }
130
131 /* Add gamma correction. */
132 case UTIL_FORMAT_COLORSPACE_SRGB:
133 result |= R300_TX_FORMAT_GAMMA;
134 break;
135
136 default:
137 switch (format) {
138 /* Same as YUV but without the YUR->RGB conversion. */
139 case PIPE_FORMAT_R8G8_B8G8_UNORM:
140 return R300_EASY_TX_FORMAT(X, Y, Z, ONE, YVYU422) | result;
141 case PIPE_FORMAT_G8R8_G8B8_UNORM:
142 return R300_EASY_TX_FORMAT(X, Y, Z, ONE, VYUY422) | result;
143 default:;
144 }
145 }
146
147 /* Add swizzle. */
148 if (!swizzle) {
149 swizzle = desc->swizzle;
150 } /*else {
151 if (swizzle[0] != desc->swizzle[0] ||
152 swizzle[1] != desc->swizzle[1] ||
153 swizzle[2] != desc->swizzle[2] ||
154 swizzle[3] != desc->swizzle[3])
155 {
156 const char n[6] = "RGBA01";
157 fprintf(stderr, "Got different swizzling! Format: %c%c%c%c, "
158 "View: %c%c%c%c\n",
159 n[desc->swizzle[0]], n[desc->swizzle[1]],
160 n[desc->swizzle[2]], n[desc->swizzle[3]],
161 n[swizzle[0]], n[swizzle[1]], n[swizzle[2]],
162 n[swizzle[3]]);
163 }
164 }*/
165
166 for (i = 0; i < 4; i++) {
167 switch (swizzle[i]) {
168 case UTIL_FORMAT_SWIZZLE_X:
169 case UTIL_FORMAT_SWIZZLE_NONE:
170 result |= swizzle_bit[0] << swizzle_shift[i];
171 break;
172 case UTIL_FORMAT_SWIZZLE_Y:
173 result |= swizzle_bit[1] << swizzle_shift[i];
174 break;
175 case UTIL_FORMAT_SWIZZLE_Z:
176 result |= swizzle_bit[2] << swizzle_shift[i];
177 break;
178 case UTIL_FORMAT_SWIZZLE_W:
179 result |= swizzle_bit[3] << swizzle_shift[i];
180 break;
181 case UTIL_FORMAT_SWIZZLE_0:
182 result |= R300_TX_FORMAT_ZERO << swizzle_shift[i];
183 break;
184 case UTIL_FORMAT_SWIZZLE_1:
185 result |= R300_TX_FORMAT_ONE << swizzle_shift[i];
186 break;
187 default:
188 return ~0; /* Unsupported. */
189 }
190 }
191
192 /* S3TC formats. */
193 if (desc->layout == UTIL_FORMAT_LAYOUT_S3TC) {
194 switch (format) {
195 case PIPE_FORMAT_DXT1_RGB:
196 case PIPE_FORMAT_DXT1_RGBA:
197 case PIPE_FORMAT_DXT1_SRGB:
198 case PIPE_FORMAT_DXT1_SRGBA:
199 return R300_TX_FORMAT_DXT1 | result;
200 case PIPE_FORMAT_DXT3_RGBA:
201 case PIPE_FORMAT_DXT3_SRGBA:
202 return R300_TX_FORMAT_DXT3 | result;
203 case PIPE_FORMAT_DXT5_RGBA:
204 case PIPE_FORMAT_DXT5_SRGBA:
205 return R300_TX_FORMAT_DXT5 | result;
206 default:
207 return ~0; /* Unsupported/unknown. */
208 }
209 }
210
211 /* Add sign. */
212 for (i = 0; i < desc->nr_channels; i++) {
213 if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED) {
214 result |= sign_bit[i];
215 }
216 }
217
218 /* This is truly a special format.
219 * It stores R8G8 and B is computed using sqrt(1 - R^2 - G^2)
220 * in the sampler unit. Also known as D3DFMT_CxV8U8. */
221 if (format == PIPE_FORMAT_R8G8Bx_SNORM) {
222 return R300_TX_FORMAT_CxV8U8 | result;
223 }
224
225 /* RGTC formats. */
226 if (desc->layout == UTIL_FORMAT_LAYOUT_RGTC) {
227 switch (format) {
228 case PIPE_FORMAT_RGTC1_UNORM:
229 case PIPE_FORMAT_RGTC1_SNORM:
230 return R500_TX_FORMAT_ATI1N | result;
231 case PIPE_FORMAT_RGTC2_UNORM:
232 case PIPE_FORMAT_RGTC2_SNORM:
233 return R400_TX_FORMAT_ATI2N | result;
234 default:
235 return ~0; /* Unsupported/unknown. */
236 }
237 }
238
239 /* See whether the components are of the same size. */
240 for (i = 1; i < desc->nr_channels; i++) {
241 uniform = uniform && desc->channel[0].size == desc->channel[i].size;
242 }
243
244 /* Non-uniform formats. */
245 if (!uniform) {
246 switch (desc->nr_channels) {
247 case 3:
248 if (desc->channel[0].size == 5 &&
249 desc->channel[1].size == 6 &&
250 desc->channel[2].size == 5) {
251 return R300_TX_FORMAT_Z5Y6X5 | result;
252 }
253 if (desc->channel[0].size == 5 &&
254 desc->channel[1].size == 5 &&
255 desc->channel[2].size == 6) {
256 return R300_TX_FORMAT_Z6Y5X5 | result;
257 }
258 return ~0; /* Unsupported/unknown. */
259
260 case 4:
261 if (desc->channel[0].size == 5 &&
262 desc->channel[1].size == 5 &&
263 desc->channel[2].size == 5 &&
264 desc->channel[3].size == 1) {
265 return R300_TX_FORMAT_W1Z5Y5X5 | result;
266 }
267 if (desc->channel[0].size == 10 &&
268 desc->channel[1].size == 10 &&
269 desc->channel[2].size == 10 &&
270 desc->channel[3].size == 2) {
271 return R300_TX_FORMAT_W2Z10Y10X10 | result;
272 }
273 }
274 return ~0; /* Unsupported/unknown. */
275 }
276
277 /* And finally, uniform formats. */
278 switch (desc->channel[0].type) {
279 case UTIL_FORMAT_TYPE_UNSIGNED:
280 case UTIL_FORMAT_TYPE_SIGNED:
281 if (!desc->channel[0].normalized &&
282 desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB) {
283 return ~0;
284 }
285
286 switch (desc->channel[0].size) {
287 case 4:
288 switch (desc->nr_channels) {
289 case 2:
290 return R300_TX_FORMAT_Y4X4 | result;
291 case 4:
292 return R300_TX_FORMAT_W4Z4Y4X4 | result;
293 }
294 return ~0;
295
296 case 8:
297 switch (desc->nr_channels) {
298 case 1:
299 return R300_TX_FORMAT_X8 | result;
300 case 2:
301 return R300_TX_FORMAT_Y8X8 | result;
302 case 4:
303 return R300_TX_FORMAT_W8Z8Y8X8 | result;
304 }
305 return ~0;
306
307 case 16:
308 switch (desc->nr_channels) {
309 case 1:
310 return R300_TX_FORMAT_X16 | result;
311 case 2:
312 return R300_TX_FORMAT_Y16X16 | result;
313 case 4:
314 return R300_TX_FORMAT_W16Z16Y16X16 | result;
315 }
316 }
317 return ~0;
318
319 #if defined(ENABLE_FLOAT_TEXTURES)
320 case UTIL_FORMAT_TYPE_FLOAT:
321 switch (desc->channel[0].size) {
322 case 16:
323 switch (desc->nr_channels) {
324 case 1:
325 return R300_TX_FORMAT_16F | result;
326 case 2:
327 return R300_TX_FORMAT_16F_16F | result;
328 case 4:
329 return R300_TX_FORMAT_16F_16F_16F_16F | result;
330 }
331 return ~0;
332
333 case 32:
334 switch (desc->nr_channels) {
335 case 1:
336 return R300_TX_FORMAT_32F | result;
337 case 2:
338 return R300_TX_FORMAT_32F_32F | result;
339 case 4:
340 return R300_TX_FORMAT_32F_32F_32F_32F | result;
341 }
342 }
343 #endif
344 }
345
346 return ~0; /* Unsupported/unknown. */
347 }
348
349 uint32_t r500_tx_format_msb_bit(enum pipe_format format)
350 {
351 switch (format) {
352 case PIPE_FORMAT_RGTC1_UNORM:
353 case PIPE_FORMAT_RGTC1_SNORM:
354 return R500_TXFORMAT_MSB;
355 default:
356 return 0;
357 }
358 }
359
360 /* Buffer formats. */
361
362 /* Colorbuffer formats. This is the unswizzled format of the RB3D block's
363 * output. For the swizzling of the targets, check the shader's format. */
364 static uint32_t r300_translate_colorformat(enum pipe_format format)
365 {
366 switch (format) {
367 /* 8-bit buffers. */
368 case PIPE_FORMAT_A8_UNORM:
369 case PIPE_FORMAT_I8_UNORM:
370 case PIPE_FORMAT_L8_UNORM:
371 case PIPE_FORMAT_R8_UNORM:
372 case PIPE_FORMAT_R8_SNORM:
373 return R300_COLOR_FORMAT_I8;
374
375 /* 16-bit buffers. */
376 case PIPE_FORMAT_B5G6R5_UNORM:
377 return R300_COLOR_FORMAT_RGB565;
378
379 case PIPE_FORMAT_B5G5R5A1_UNORM:
380 case PIPE_FORMAT_B5G5R5X1_UNORM:
381 return R300_COLOR_FORMAT_ARGB1555;
382
383 case PIPE_FORMAT_B4G4R4A4_UNORM:
384 case PIPE_FORMAT_B4G4R4X4_UNORM:
385 return R300_COLOR_FORMAT_ARGB4444;
386
387 /* 32-bit buffers. */
388 case PIPE_FORMAT_B8G8R8A8_UNORM:
389 case PIPE_FORMAT_B8G8R8X8_UNORM:
390 case PIPE_FORMAT_A8R8G8B8_UNORM:
391 case PIPE_FORMAT_X8R8G8B8_UNORM:
392 case PIPE_FORMAT_A8B8G8R8_UNORM:
393 case PIPE_FORMAT_R8G8B8A8_SNORM:
394 case PIPE_FORMAT_X8B8G8R8_UNORM:
395 case PIPE_FORMAT_R8G8B8X8_UNORM:
396 case PIPE_FORMAT_R8SG8SB8UX8U_NORM:
397 return R300_COLOR_FORMAT_ARGB8888;
398
399 case PIPE_FORMAT_R10G10B10A2_UNORM:
400 case PIPE_FORMAT_R10G10B10X2_SNORM:
401 case PIPE_FORMAT_B10G10R10A2_UNORM:
402 case PIPE_FORMAT_R10SG10SB10SA2U_NORM:
403 return R500_COLOR_FORMAT_ARGB2101010; /* R5xx-only? */
404
405 /* 64-bit buffers. */
406 case PIPE_FORMAT_R16G16B16A16_UNORM:
407 case PIPE_FORMAT_R16G16B16A16_SNORM:
408 #if defined(ENABLE_FLOAT_TEXTURES)
409 case PIPE_FORMAT_R16G16B16A16_FLOAT:
410 #endif
411 return R300_COLOR_FORMAT_ARGB16161616;
412
413 /* 128-bit buffers. */
414 #if defined(ENABLE_FLOAT_TEXTURES)
415 case PIPE_FORMAT_R32G32B32A32_FLOAT:
416 return R300_COLOR_FORMAT_ARGB32323232;
417 #endif
418
419 /* YUV buffers. */
420 case PIPE_FORMAT_UYVY:
421 return R300_COLOR_FORMAT_YVYU;
422 case PIPE_FORMAT_YUYV:
423 return R300_COLOR_FORMAT_VYUY;
424 default:
425 return ~0; /* Unsupported. */
426 }
427 }
428
429 /* Depthbuffer and stencilbuffer. Thankfully, we only support two flavors. */
430 static uint32_t r300_translate_zsformat(enum pipe_format format)
431 {
432 switch (format) {
433 /* 16-bit depth, no stencil */
434 case PIPE_FORMAT_Z16_UNORM:
435 return R300_DEPTHFORMAT_16BIT_INT_Z;
436 /* 24-bit depth, ignored stencil */
437 case PIPE_FORMAT_X8Z24_UNORM:
438 /* 24-bit depth, 8-bit stencil */
439 case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
440 return R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL;
441 default:
442 return ~0; /* Unsupported. */
443 }
444 }
445
446 /* Shader output formats. This is essentially the swizzle from the shader
447 * to the RB3D block.
448 *
449 * Note that formats are stored from C3 to C0. */
450 static uint32_t r300_translate_out_fmt(enum pipe_format format)
451 {
452 uint32_t modifier = 0;
453 unsigned i;
454 const struct util_format_description *desc;
455 static const uint32_t sign_bit[4] = {
456 R300_OUT_SIGN(0x1),
457 R300_OUT_SIGN(0x2),
458 R300_OUT_SIGN(0x4),
459 R300_OUT_SIGN(0x8),
460 };
461
462 desc = util_format_description(format);
463
464 /* Specifies how the shader output is written to the fog unit. */
465 if (desc->channel[0].type == UTIL_FORMAT_TYPE_FLOAT) {
466 if (desc->channel[0].size == 32) {
467 modifier |= R300_US_OUT_FMT_C4_32_FP;
468 } else {
469 modifier |= R300_US_OUT_FMT_C4_16_FP;
470 }
471 } else {
472 if (desc->channel[0].size == 16) {
473 modifier |= R300_US_OUT_FMT_C4_16;
474 } else {
475 /* C4_8 seems to be used for the formats whose pixel size
476 * is <= 32 bits. */
477 modifier |= R300_US_OUT_FMT_C4_8;
478 }
479 }
480
481 /* Add sign. */
482 for (i = 0; i < 4; i++)
483 if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED) {
484 modifier |= sign_bit[i];
485 }
486
487 /* Add swizzles and return. */
488 switch (format) {
489 /* 8-bit outputs.
490 * COLORFORMAT_I8 stores the C2 component. */
491 case PIPE_FORMAT_A8_UNORM:
492 return modifier | R300_C2_SEL_A;
493 case PIPE_FORMAT_I8_UNORM:
494 case PIPE_FORMAT_L8_UNORM:
495 case PIPE_FORMAT_R8_UNORM:
496 case PIPE_FORMAT_R8_SNORM:
497 return modifier | R300_C2_SEL_R;
498
499 /* BGRA outputs. */
500 case PIPE_FORMAT_B5G6R5_UNORM:
501 case PIPE_FORMAT_B5G5R5A1_UNORM:
502 case PIPE_FORMAT_B5G5R5X1_UNORM:
503 case PIPE_FORMAT_B4G4R4A4_UNORM:
504 case PIPE_FORMAT_B4G4R4X4_UNORM:
505 case PIPE_FORMAT_B8G8R8A8_UNORM:
506 case PIPE_FORMAT_B8G8R8X8_UNORM:
507 case PIPE_FORMAT_B10G10R10A2_UNORM:
508 return modifier |
509 R300_C0_SEL_B | R300_C1_SEL_G |
510 R300_C2_SEL_R | R300_C3_SEL_A;
511
512 /* ARGB outputs. */
513 case PIPE_FORMAT_A8R8G8B8_UNORM:
514 case PIPE_FORMAT_X8R8G8B8_UNORM:
515 return modifier |
516 R300_C0_SEL_A | R300_C1_SEL_R |
517 R300_C2_SEL_G | R300_C3_SEL_B;
518
519 /* ABGR outputs. */
520 case PIPE_FORMAT_A8B8G8R8_UNORM:
521 case PIPE_FORMAT_X8B8G8R8_UNORM:
522 return modifier |
523 R300_C0_SEL_A | R300_C1_SEL_B |
524 R300_C2_SEL_G | R300_C3_SEL_R;
525
526 /* RGBA outputs. */
527 case PIPE_FORMAT_R8G8B8X8_UNORM:
528 case PIPE_FORMAT_R8G8B8A8_SNORM:
529 case PIPE_FORMAT_R8SG8SB8UX8U_NORM:
530 case PIPE_FORMAT_R10G10B10A2_UNORM:
531 case PIPE_FORMAT_R10G10B10X2_SNORM:
532 case PIPE_FORMAT_R10SG10SB10SA2U_NORM:
533 case PIPE_FORMAT_R16G16B16A16_UNORM:
534 case PIPE_FORMAT_R16G16B16A16_SNORM:
535 //case PIPE_FORMAT_R16G16B16A16_FLOAT: /* not in pipe_format */
536 case PIPE_FORMAT_R32G32B32A32_FLOAT:
537 return modifier |
538 R300_C0_SEL_R | R300_C1_SEL_G |
539 R300_C2_SEL_B | R300_C3_SEL_A;
540
541 default:
542 return ~0; /* Unsupported. */
543 }
544 }
545
546 boolean r300_is_colorbuffer_format_supported(enum pipe_format format)
547 {
548 return r300_translate_colorformat(format) != ~0 &&
549 r300_translate_out_fmt(format) != ~0;
550 }
551
552 boolean r300_is_zs_format_supported(enum pipe_format format)
553 {
554 return r300_translate_zsformat(format) != ~0;
555 }
556
557 boolean r300_is_sampler_format_supported(enum pipe_format format)
558 {
559 return r300_translate_texformat(format, 0) != ~0;
560 }
561
562 static void r300_texture_setup_immutable_state(struct r300_screen* screen,
563 struct r300_texture* tex)
564 {
565 struct r300_texture_format_state* f = &tex->tx_format;
566 struct pipe_resource *pt = &tex->b.b;
567 boolean is_r500 = screen->caps.is_r500;
568
569 /* Set sampler state. */
570 f->format0 = R300_TX_WIDTH((pt->width0 - 1) & 0x7ff) |
571 R300_TX_HEIGHT((pt->height0 - 1) & 0x7ff);
572
573 if (tex->uses_pitch) {
574 /* rectangles love this */
575 f->format0 |= R300_TX_PITCH_EN;
576 f->format2 = (tex->pitch[0] - 1) & 0x1fff;
577 } else {
578 /* power of two textures (3D, mipmaps, and no pitch) */
579 f->format0 |= R300_TX_DEPTH(util_logbase2(pt->depth0) & 0xf);
580 }
581
582 f->format1 = 0;
583 if (pt->target == PIPE_TEXTURE_CUBE) {
584 f->format1 |= R300_TX_FORMAT_CUBIC_MAP;
585 }
586 if (pt->target == PIPE_TEXTURE_3D) {
587 f->format1 |= R300_TX_FORMAT_3D;
588 }
589
590 /* large textures on r500 */
591 if (is_r500)
592 {
593 if (pt->width0 > 2048) {
594 f->format2 |= R500_TXWIDTH_BIT11;
595 }
596 if (pt->height0 > 2048) {
597 f->format2 |= R500_TXHEIGHT_BIT11;
598 }
599 }
600
601 f->tile_config = R300_TXO_MACRO_TILE(tex->macrotile) |
602 R300_TXO_MICRO_TILE(tex->microtile);
603
604 SCREEN_DBG(screen, DBG_TEX, "r300: Set texture state (%dx%d, %d levels)\n",
605 pt->width0, pt->height0, pt->last_level);
606 }
607
608 static void r300_texture_setup_fb_state(struct r300_screen* screen,
609 struct r300_texture* tex)
610 {
611 unsigned i;
612
613 /* Set framebuffer state. */
614 if (util_format_is_depth_or_stencil(tex->b.b.format)) {
615 for (i = 0; i <= tex->b.b.last_level; i++) {
616 tex->fb_state.depthpitch[i] =
617 tex->pitch[i] |
618 R300_DEPTHMACROTILE(tex->mip_macrotile[i]) |
619 R300_DEPTHMICROTILE(tex->microtile);
620 }
621 tex->fb_state.zb_format = r300_translate_zsformat(tex->b.b.format);
622 } else {
623 for (i = 0; i <= tex->b.b.last_level; i++) {
624 tex->fb_state.colorpitch[i] =
625 tex->pitch[i] |
626 r300_translate_colorformat(tex->b.b.format) |
627 R300_COLOR_TILE(tex->mip_macrotile[i]) |
628 R300_COLOR_MICROTILE(tex->microtile);
629 }
630 tex->fb_state.us_out_fmt = r300_translate_out_fmt(tex->b.b.format);
631 }
632 }
633
634 void r300_texture_reinterpret_format(struct pipe_screen *screen,
635 struct pipe_resource *tex,
636 enum pipe_format new_format)
637 {
638 struct r300_screen *r300screen = r300_screen(screen);
639
640 SCREEN_DBG(r300screen, DBG_TEX, "r300: Reinterpreting format: %s -> %s\n",
641 util_format_name(tex->format), util_format_name(new_format));
642
643 tex->format = new_format;
644
645 r300_texture_setup_fb_state(r300_screen(screen), r300_texture(tex));
646 }
647
648 unsigned r300_texture_get_offset(struct r300_texture* tex, unsigned level,
649 unsigned zslice, unsigned face)
650 {
651 unsigned offset = tex->offset[level];
652
653 switch (tex->b.b.target) {
654 case PIPE_TEXTURE_3D:
655 assert(face == 0);
656 return offset + zslice * tex->layer_size[level];
657
658 case PIPE_TEXTURE_CUBE:
659 assert(zslice == 0);
660 return offset + face * tex->layer_size[level];
661
662 default:
663 assert(zslice == 0 && face == 0);
664 return offset;
665 }
666 }
667
668 /**
669 * Return the width (dim==TILE_WIDTH) or height (dim==TILE_HEIGHT) of one tile
670 * of the given texture.
671 */
672 static unsigned r300_texture_get_tile_size(struct r300_texture* tex,
673 int dim, boolean macrotile)
674 {
675 unsigned pixsize, tile_size;
676
677 pixsize = util_format_get_blocksize(tex->b.b.format);
678 tile_size = microblock_table[util_logbase2(pixsize)][tex->microtile][dim];
679
680 if (macrotile) {
681 tile_size *= 8;
682 }
683
684 assert(tile_size);
685 return tile_size;
686 }
687
688 /* Return true if macrotiling should be enabled on the miplevel. */
689 static boolean r300_texture_macro_switch(struct r300_texture *tex,
690 unsigned level,
691 boolean rv350_mode,
692 int dim)
693 {
694 unsigned tile, texdim;
695
696 tile = r300_texture_get_tile_size(tex, dim, TRUE);
697 if (dim == TILE_WIDTH) {
698 texdim = u_minify(tex->b.b.width0, level);
699 } else {
700 texdim = u_minify(tex->b.b.height0, level);
701 }
702
703 /* See TX_FILTER1_n.MACRO_SWITCH. */
704 if (rv350_mode) {
705 return texdim >= tile;
706 } else {
707 return texdim > tile;
708 }
709 }
710
711 /**
712 * Return the stride, in bytes, of the texture images of the given texture
713 * at the given level.
714 */
715 unsigned r300_texture_get_stride(struct r300_screen* screen,
716 struct r300_texture* tex, unsigned level)
717 {
718 unsigned tile_width, width;
719
720 if (tex->stride_override)
721 return tex->stride_override;
722
723 /* Check the level. */
724 if (level > tex->b.b.last_level) {
725 SCREEN_DBG(screen, DBG_TEX, "%s: level (%u) > last_level (%u)\n",
726 __FUNCTION__, level, tex->b.b.last_level);
727 return 0;
728 }
729
730 width = u_minify(tex->b.b.width0, level);
731
732 if (r300_format_is_plain(tex->b.b.format)) {
733 tile_width = r300_texture_get_tile_size(tex, TILE_WIDTH,
734 tex->mip_macrotile[level]);
735 width = align(width, tile_width);
736
737 return util_format_get_stride(tex->b.b.format, width);
738 } else {
739 return align(util_format_get_stride(tex->b.b.format, width), 32);
740 }
741 }
742
743 static unsigned r300_texture_get_nblocksy(struct r300_texture* tex,
744 unsigned level)
745 {
746 unsigned height, tile_height;
747
748 height = u_minify(tex->b.b.height0, level);
749
750 if (r300_format_is_plain(tex->b.b.format)) {
751 tile_height = r300_texture_get_tile_size(tex, TILE_HEIGHT,
752 tex->mip_macrotile[level]);
753 height = align(height, tile_height);
754
755 /* This is needed for the kernel checker, unfortunately. */
756 height = util_next_power_of_two(height);
757 }
758
759 return util_format_get_nblocksy(tex->b.b.format, height);
760 }
761
762 static void r300_texture_3d_fix_mipmapping(struct r300_screen *screen,
763 struct r300_texture *tex)
764 {
765 /* The kernels <= 2.6.34-rc3 compute the size of mipmapped 3D textures
766 * incorrectly. This is a workaround to prevent CS from being rejected. */
767
768 unsigned i, size;
769
770 if (screen->rws->get_value(screen->rws, R300_VID_TEX3D_MIP_BUG) &&
771 tex->b.b.target == PIPE_TEXTURE_3D &&
772 tex->b.b.last_level > 0) {
773 size = 0;
774
775 for (i = 0; i <= tex->b.b.last_level; i++) {
776 size += r300_texture_get_stride(screen, tex, i) *
777 r300_texture_get_nblocksy(tex, i);
778 }
779
780 size *= tex->b.b.depth0;
781 tex->size = size;
782 }
783 }
784
785 static void r300_setup_miptree(struct r300_screen* screen,
786 struct r300_texture* tex)
787 {
788 struct pipe_resource* base = &tex->b.b;
789 unsigned stride, size, layer_size, nblocksy, i;
790 boolean rv350_mode = screen->caps.family >= CHIP_FAMILY_RV350;
791
792 SCREEN_DBG(screen, DBG_TEX, "r300: Making miptree for texture, format %s\n",
793 util_format_name(base->format));
794
795 for (i = 0; i <= base->last_level; i++) {
796 /* Let's see if this miplevel can be macrotiled. */
797 tex->mip_macrotile[i] =
798 (tex->macrotile == R300_BUFFER_TILED &&
799 r300_texture_macro_switch(tex, i, rv350_mode, TILE_WIDTH) &&
800 r300_texture_macro_switch(tex, i, rv350_mode, TILE_HEIGHT)) ?
801 R300_BUFFER_TILED : R300_BUFFER_LINEAR;
802
803 stride = r300_texture_get_stride(screen, tex, i);
804 nblocksy = r300_texture_get_nblocksy(tex, i);
805 layer_size = stride * nblocksy;
806
807 if (base->target == PIPE_TEXTURE_CUBE)
808 size = layer_size * 6;
809 else
810 size = layer_size * u_minify(base->depth0, i);
811
812 tex->offset[i] = tex->size;
813 tex->size = tex->offset[i] + size;
814 tex->layer_size[i] = layer_size;
815 tex->pitch[i] = stride / util_format_get_blocksize(base->format);
816
817 SCREEN_DBG(screen, DBG_TEX, "r300: Texture miptree: Level %d "
818 "(%dx%dx%d px, pitch %d bytes) %d bytes total, macrotiled %s\n",
819 i, u_minify(base->width0, i), u_minify(base->height0, i),
820 u_minify(base->depth0, i), stride, tex->size,
821 tex->mip_macrotile[i] ? "TRUE" : "FALSE");
822 }
823 }
824
825 static void r300_setup_flags(struct r300_texture* tex)
826 {
827 tex->uses_pitch = !util_is_power_of_two(tex->b.b.width0) ||
828 !util_is_power_of_two(tex->b.b.height0) ||
829 tex->stride_override;
830 }
831
832 static void r300_setup_tiling(struct pipe_screen *screen,
833 struct r300_texture *tex)
834 {
835 struct r300_winsys_screen *rws = (struct r300_winsys_screen *)screen->winsys;
836 enum pipe_format format = tex->b.b.format;
837 boolean rv350_mode = r300_screen(screen)->caps.family >= CHIP_FAMILY_RV350;
838
839 if (!r300_format_is_plain(format)) {
840 return;
841 }
842
843 if (tex->b.b.width0 == 1 ||
844 tex->b.b.height0 == 1) {
845 return;
846 }
847
848 /* Set microtiling. */
849 switch (util_format_get_blocksize(format)) {
850 case 1:
851 case 4:
852 tex->microtile = R300_BUFFER_TILED;
853 break;
854
855 case 2:
856 case 8:
857 if (rws->get_value(rws, R300_VID_SQUARE_TILING_SUPPORT)) {
858 tex->microtile = R300_BUFFER_SQUARETILED;
859 }
860 break;
861 }
862
863 /* Set macrotiling. */
864 if (r300_texture_macro_switch(tex, 0, rv350_mode, TILE_WIDTH) &&
865 r300_texture_macro_switch(tex, 0, rv350_mode, TILE_HEIGHT)) {
866 tex->macrotile = R300_BUFFER_TILED;
867 }
868 }
869
870 static unsigned r300_texture_is_referenced(struct pipe_context *context,
871 struct pipe_resource *texture,
872 unsigned face, unsigned level)
873 {
874 struct r300_context *r300 = r300_context(context);
875 struct r300_texture *rtex = (struct r300_texture *)texture;
876
877 if (r300->rws->is_buffer_referenced(r300->rws, rtex->buffer))
878 return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
879
880 return PIPE_UNREFERENCED;
881 }
882
883 static void r300_texture_destroy(struct pipe_screen *screen,
884 struct pipe_resource* texture)
885 {
886 struct r300_texture* tex = (struct r300_texture*)texture;
887 struct r300_winsys_screen *rws = (struct r300_winsys_screen *)texture->screen->winsys;
888
889 rws->buffer_reference(rws, &tex->buffer, NULL);
890 FREE(tex);
891 }
892
893
894
895
896 static boolean
897 r300_texture_get_handle(struct pipe_screen* screen,
898 struct pipe_resource *texture,
899 struct winsys_handle *whandle)
900 {
901 struct r300_winsys_screen *rws = (struct r300_winsys_screen *)screen->winsys;
902 struct r300_texture* tex = (struct r300_texture*)texture;
903 unsigned stride;
904
905 if (!tex) {
906 return FALSE;
907 }
908
909 stride = r300_texture_get_stride(r300_screen(screen), tex, 0);
910
911 rws->buffer_get_handle(rws, tex->buffer, stride, whandle);
912
913 return TRUE;
914 }
915
916
917
918 struct u_resource_vtbl r300_texture_vtbl =
919 {
920 r300_texture_get_handle, /* get_handle */
921 r300_texture_destroy, /* resource_destroy */
922 r300_texture_is_referenced, /* is_resource_referenced */
923 r300_texture_get_transfer, /* get_transfer */
924 r300_texture_transfer_destroy, /* transfer_destroy */
925 r300_texture_transfer_map, /* transfer_map */
926 u_default_transfer_flush_region, /* transfer_flush_region */
927 r300_texture_transfer_unmap, /* transfer_unmap */
928 u_default_transfer_inline_write /* transfer_inline_write */
929 };
930
931
932
933 /* Create a new texture. */
934 struct pipe_resource* r300_texture_create(struct pipe_screen* screen,
935 const struct pipe_resource* base)
936 {
937 struct r300_texture* tex = CALLOC_STRUCT(r300_texture);
938 struct r300_screen* rscreen = r300_screen(screen);
939 struct r300_winsys_screen *rws = (struct r300_winsys_screen *)screen->winsys;
940
941 if (!tex) {
942 return NULL;
943 }
944
945 tex->b.b = *base;
946 tex->b.vtbl = &r300_texture_vtbl;
947 pipe_reference_init(&tex->b.b.reference, 1);
948 tex->b.b.screen = screen;
949
950 r300_setup_flags(tex);
951 if (!(base->flags & R300_RESOURCE_FLAG_TRANSFER) &&
952 !(base->bind & PIPE_BIND_SCANOUT)) {
953 r300_setup_tiling(screen, tex);
954 }
955 r300_setup_miptree(rscreen, tex);
956 r300_texture_3d_fix_mipmapping(rscreen, tex);
957 r300_texture_setup_immutable_state(rscreen, tex);
958 r300_texture_setup_fb_state(rscreen, tex);
959
960 tex->buffer = rws->buffer_create(rws, 2048,
961 PIPE_BIND_SAMPLER_VIEW, /* XXX */
962 tex->size);
963 rws->buffer_set_tiling(rws, tex->buffer,
964 tex->pitch[0],
965 tex->microtile,
966 tex->macrotile);
967
968 if (!tex->buffer) {
969 FREE(tex);
970 return NULL;
971 }
972
973 return (struct pipe_resource*)tex;
974 }
975
976
977
978 /* Not required to implement u_resource_vtbl, consider moving to another file:
979 */
980 struct pipe_surface* r300_get_tex_surface(struct pipe_screen* screen,
981 struct pipe_resource* texture,
982 unsigned face,
983 unsigned level,
984 unsigned zslice,
985 unsigned flags)
986 {
987 struct r300_texture* tex = r300_texture(texture);
988 struct pipe_surface* surface = CALLOC_STRUCT(pipe_surface);
989 unsigned offset;
990
991 offset = r300_texture_get_offset(tex, level, zslice, face);
992
993 if (surface) {
994 pipe_reference_init(&surface->reference, 1);
995 pipe_resource_reference(&surface->texture, texture);
996 surface->format = texture->format;
997 surface->width = u_minify(texture->width0, level);
998 surface->height = u_minify(texture->height0, level);
999 surface->offset = offset;
1000 surface->usage = flags;
1001 surface->zslice = zslice;
1002 surface->texture = texture;
1003 surface->face = face;
1004 surface->level = level;
1005 }
1006
1007 return surface;
1008 }
1009
1010 /* Not required to implement u_resource_vtbl, consider moving to another file:
1011 */
1012 void r300_tex_surface_destroy(struct pipe_surface* s)
1013 {
1014 pipe_resource_reference(&s->texture, NULL);
1015 FREE(s);
1016 }
1017
1018 struct pipe_resource*
1019 r300_texture_from_handle(struct pipe_screen* screen,
1020 const struct pipe_resource* base,
1021 struct winsys_handle *whandle)
1022 {
1023 struct r300_winsys_screen *rws = (struct r300_winsys_screen*)screen->winsys;
1024 struct r300_screen* rscreen = r300_screen(screen);
1025 struct r300_winsys_buffer *buffer;
1026 struct r300_texture* tex;
1027 unsigned stride;
1028 boolean override_zb_flags;
1029
1030 /* Support only 2D textures without mipmaps */
1031 if (base->target != PIPE_TEXTURE_2D ||
1032 base->depth0 != 1 ||
1033 base->last_level != 0) {
1034 return NULL;
1035 }
1036
1037 buffer = rws->buffer_from_handle(rws, screen, whandle, &stride);
1038 if (!buffer) {
1039 return NULL;
1040 }
1041
1042 tex = CALLOC_STRUCT(r300_texture);
1043 if (!tex) {
1044 return NULL;
1045 }
1046
1047 tex->b.b = *base;
1048 tex->b.vtbl = &r300_texture_vtbl;
1049 pipe_reference_init(&tex->b.b.reference, 1);
1050 tex->b.b.screen = screen;
1051
1052 tex->stride_override = stride;
1053
1054 /* one ref already taken */
1055 tex->buffer = buffer;
1056
1057 rws->buffer_get_tiling(rws, buffer, &tex->microtile, &tex->macrotile);
1058 r300_setup_flags(tex);
1059
1060 /* Enforce microtiled zbuffer. */
1061 override_zb_flags = util_format_is_depth_or_stencil(base->format) &&
1062 tex->microtile == R300_BUFFER_LINEAR;
1063
1064 if (override_zb_flags) {
1065 switch (util_format_get_blocksize(base->format)) {
1066 case 4:
1067 tex->microtile = R300_BUFFER_TILED;
1068 break;
1069
1070 case 2:
1071 if (rws->get_value(rws, R300_VID_SQUARE_TILING_SUPPORT)) {
1072 tex->microtile = R300_BUFFER_SQUARETILED;
1073 break;
1074 }
1075 /* Pass through. */
1076
1077 default:
1078 override_zb_flags = FALSE;
1079 }
1080 }
1081
1082 r300_setup_miptree(rscreen, tex);
1083 r300_texture_setup_immutable_state(rscreen, tex);
1084 r300_texture_setup_fb_state(rscreen, tex);
1085
1086 if (override_zb_flags) {
1087 rws->buffer_set_tiling(rws, tex->buffer,
1088 tex->pitch[0],
1089 tex->microtile,
1090 tex->macrotile);
1091 }
1092 return (struct pipe_resource*)tex;
1093 }
1094