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