r300g: reorder parts of translate_texformat
[platform/upstream/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 /* Always include headers in the reverse order!! ~ M. */
25 #include "r300_texture.h"
26
27 #include "r300_context.h"
28 #include "r300_reg.h"
29 #include "r300_texture_desc.h"
30 #include "r300_transfer.h"
31 #include "r300_screen.h"
32 #include "r300_winsys.h"
33
34 #include "util/u_format.h"
35 #include "util/u_format_s3tc.h"
36 #include "util/u_math.h"
37 #include "util/u_memory.h"
38 #include "util/u_mm.h"
39
40 #include "pipe/p_screen.h"
41
42 unsigned r300_get_swizzle_combined(const unsigned char *swizzle_format,
43                                    const unsigned char *swizzle_view,
44                                    boolean dxtc_swizzle)
45 {
46     unsigned i;
47     unsigned char swizzle[4];
48     unsigned result = 0;
49     const uint32_t swizzle_shift[4] = {
50         R300_TX_FORMAT_R_SHIFT,
51         R300_TX_FORMAT_G_SHIFT,
52         R300_TX_FORMAT_B_SHIFT,
53         R300_TX_FORMAT_A_SHIFT
54     };
55     uint32_t swizzle_bit[4] = {
56         dxtc_swizzle ? R300_TX_FORMAT_Z : R300_TX_FORMAT_X,
57         R300_TX_FORMAT_Y,
58         dxtc_swizzle ? R300_TX_FORMAT_X : R300_TX_FORMAT_Z,
59         R300_TX_FORMAT_W
60     };
61
62     if (swizzle_view) {
63         /* Combine two sets of swizzles. */
64         for (i = 0; i < 4; i++) {
65             swizzle[i] = swizzle_view[i] <= UTIL_FORMAT_SWIZZLE_W ?
66                          swizzle_format[swizzle_view[i]] : swizzle_view[i];
67         }
68     } else {
69         memcpy(swizzle, swizzle_format, 4);
70     }
71
72     /* Get swizzle. */
73     for (i = 0; i < 4; i++) {
74         switch (swizzle[i]) {
75             case UTIL_FORMAT_SWIZZLE_Y:
76                 result |= swizzle_bit[1] << swizzle_shift[i];
77                 break;
78             case UTIL_FORMAT_SWIZZLE_Z:
79                 result |= swizzle_bit[2] << swizzle_shift[i];
80                 break;
81             case UTIL_FORMAT_SWIZZLE_W:
82                 result |= swizzle_bit[3] << swizzle_shift[i];
83                 break;
84             case UTIL_FORMAT_SWIZZLE_0:
85                 result |= R300_TX_FORMAT_ZERO << swizzle_shift[i];
86                 break;
87             case UTIL_FORMAT_SWIZZLE_1:
88                 result |= R300_TX_FORMAT_ONE << swizzle_shift[i];
89                 break;
90             default: /* UTIL_FORMAT_SWIZZLE_X */
91                 result |= swizzle_bit[0] << swizzle_shift[i];
92         }
93     }
94     return result;
95 }
96
97 /* Translate a pipe_format into a useful texture format for sampling.
98  *
99  * Some special formats are translated directly using R300_EASY_TX_FORMAT,
100  * but the majority of them is translated in a generic way, automatically
101  * supporting all the formats hw can support.
102  *
103  * R300_EASY_TX_FORMAT swizzles the texture.
104  * Note the signature of R300_EASY_TX_FORMAT:
105  *   R300_EASY_TX_FORMAT(B, G, R, A, FORMAT);
106  *
107  * The FORMAT specifies how the texture sampler will treat the texture, and
108  * makes available X, Y, Z, W, ZERO, and ONE for swizzling. */
109 uint32_t r300_translate_texformat(enum pipe_format format,
110                                   const unsigned char *swizzle_view,
111                                   boolean is_r500,
112                                   boolean dxtc_swizzle)
113 {
114     uint32_t result = 0;
115     const struct util_format_description *desc;
116     unsigned i;
117     boolean uniform = TRUE;
118     const uint32_t sign_bit[4] = {
119         R300_TX_FORMAT_SIGNED_X,
120         R300_TX_FORMAT_SIGNED_Y,
121         R300_TX_FORMAT_SIGNED_Z,
122         R300_TX_FORMAT_SIGNED_W,
123     };
124
125     desc = util_format_description(format);
126
127     /* Colorspace (return non-RGB formats directly). */
128     switch (desc->colorspace) {
129         /* Depth stencil formats.
130          * Swizzles are added in r300_merge_textures_and_samplers. */
131         case UTIL_FORMAT_COLORSPACE_ZS:
132             switch (format) {
133                 case PIPE_FORMAT_Z16_UNORM:
134                     return R300_TX_FORMAT_X16;
135                 case PIPE_FORMAT_X8Z24_UNORM:
136                 case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
137                     if (is_r500)
138                         return R500_TX_FORMAT_Y8X24;
139                     else
140                         return R300_TX_FORMAT_Y16X16;
141                 default:
142                     return ~0; /* Unsupported. */
143             }
144
145         /* YUV formats. */
146         case UTIL_FORMAT_COLORSPACE_YUV:
147             result |= R300_TX_FORMAT_YUV_TO_RGB;
148
149             switch (format) {
150                 case PIPE_FORMAT_UYVY:
151                     return R300_EASY_TX_FORMAT(X, Y, Z, ONE, YVYU422) | result;
152                 case PIPE_FORMAT_YUYV:
153                     return R300_EASY_TX_FORMAT(X, Y, Z, ONE, VYUY422) | result;
154                 default:
155                     return ~0; /* Unsupported/unknown. */
156             }
157
158         /* Add gamma correction. */
159         case UTIL_FORMAT_COLORSPACE_SRGB:
160             result |= R300_TX_FORMAT_GAMMA;
161             break;
162
163         default:
164             switch (format) {
165                 /* Same as YUV but without the YUR->RGB conversion. */
166                 case PIPE_FORMAT_R8G8_B8G8_UNORM:
167                     return R300_EASY_TX_FORMAT(X, Y, Z, ONE, YVYU422) | result;
168                 case PIPE_FORMAT_G8R8_G8B8_UNORM:
169                     return R300_EASY_TX_FORMAT(X, Y, Z, ONE, VYUY422) | result;
170                 default:;
171             }
172     }
173
174     if (util_format_is_compressed(format) &&
175         dxtc_swizzle &&
176         format != PIPE_FORMAT_RGTC2_UNORM &&
177         format != PIPE_FORMAT_RGTC2_SNORM) {
178         result |= r300_get_swizzle_combined(desc->swizzle, swizzle_view,
179                                             dxtc_swizzle);
180     } else {
181         result |= r300_get_swizzle_combined(desc->swizzle, swizzle_view,
182                                             FALSE);
183     }
184
185     /* S3TC formats. */
186     if (desc->layout == UTIL_FORMAT_LAYOUT_S3TC) {
187         if (!util_format_s3tc_enabled) {
188             return ~0; /* Unsupported. */
189         }
190
191         switch (format) {
192             case PIPE_FORMAT_DXT1_RGB:
193             case PIPE_FORMAT_DXT1_RGBA:
194             case PIPE_FORMAT_DXT1_SRGB:
195             case PIPE_FORMAT_DXT1_SRGBA:
196                 return R300_TX_FORMAT_DXT1 | result;
197             case PIPE_FORMAT_DXT3_RGBA:
198             case PIPE_FORMAT_DXT3_SRGBA:
199                 return R300_TX_FORMAT_DXT3 | result;
200             case PIPE_FORMAT_DXT5_RGBA:
201             case PIPE_FORMAT_DXT5_SRGBA:
202                 return R300_TX_FORMAT_DXT5 | result;
203             default:
204                 return ~0; /* Unsupported/unknown. */
205         }
206     }
207
208     /* RGTC formats. */
209     if (desc->layout == UTIL_FORMAT_LAYOUT_RGTC) {
210         switch (format) {
211             case PIPE_FORMAT_RGTC1_SNORM:
212                 result |= sign_bit[1];
213             case PIPE_FORMAT_RGTC1_UNORM:
214                 return R500_TX_FORMAT_ATI1N | result;
215             case PIPE_FORMAT_RGTC2_SNORM:
216                 result |= sign_bit[0] | sign_bit[1];
217             case PIPE_FORMAT_RGTC2_UNORM:
218                 return R400_TX_FORMAT_ATI2N | result;
219             default:
220                 return ~0; /* Unsupported/unknown. */
221         }
222     }
223
224     /* This is truly a special format.
225      * It stores R8G8 and B is computed using sqrt(1 - R^2 - G^2)
226      * in the sampler unit. Also known as D3DFMT_CxV8U8. */
227     if (format == PIPE_FORMAT_R8G8Bx_SNORM) {
228         return R300_TX_FORMAT_CxV8U8 | result;
229     }
230
231     /* Add sign. */
232     for (i = 0; i < desc->nr_channels; i++) {
233         if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED) {
234             result |= sign_bit[i];
235         }
236     }
237
238     /* See whether the components are of the same size. */
239     for (i = 1; i < desc->nr_channels; i++) {
240         uniform = uniform && desc->channel[0].size == desc->channel[i].size;
241     }
242
243     /* Non-uniform formats. */
244     if (!uniform) {
245         switch (desc->nr_channels) {
246             case 3:
247                 if (desc->channel[0].size == 5 &&
248                     desc->channel[1].size == 6 &&
249                     desc->channel[2].size == 5) {
250                     return R300_TX_FORMAT_Z5Y6X5 | result;
251                 }
252                 if (desc->channel[0].size == 5 &&
253                     desc->channel[1].size == 5 &&
254                     desc->channel[2].size == 6) {
255                     return R300_TX_FORMAT_Z6Y5X5 | result;
256                 }
257                 if (desc->channel[0].size == 2 &&
258                     desc->channel[1].size == 3 &&
259                     desc->channel[2].size == 3) {
260                     return R300_TX_FORMAT_Z3Y3X2 | result;
261                 }
262                 return ~0; /* Unsupported/unknown. */
263
264             case 4:
265                 if (desc->channel[0].size == 5 &&
266                     desc->channel[1].size == 5 &&
267                     desc->channel[2].size == 5 &&
268                     desc->channel[3].size == 1) {
269                     return R300_TX_FORMAT_W1Z5Y5X5 | result;
270                 }
271                 if (desc->channel[0].size == 10 &&
272                     desc->channel[1].size == 10 &&
273                     desc->channel[2].size == 10 &&
274                     desc->channel[3].size == 2) {
275                     return R300_TX_FORMAT_W2Z10Y10X10 | result;
276                 }
277         }
278         return ~0; /* Unsupported/unknown. */
279     }
280
281     /* Find the first non-VOID channel. */
282     for (i = 0; i < 4; i++) {
283         if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) {
284             break;
285         }
286     }
287
288     if (i == 4)
289         return ~0; /* Unsupported/unknown. */
290
291     /* And finally, uniform formats. */
292     switch (desc->channel[i].type) {
293         case UTIL_FORMAT_TYPE_UNSIGNED:
294         case UTIL_FORMAT_TYPE_SIGNED:
295             if (!desc->channel[i].normalized &&
296                 desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB) {
297                 return ~0;
298             }
299
300             switch (desc->channel[i].size) {
301                 case 4:
302                     switch (desc->nr_channels) {
303                         case 2:
304                             return R300_TX_FORMAT_Y4X4 | result;
305                         case 4:
306                             return R300_TX_FORMAT_W4Z4Y4X4 | result;
307                     }
308                     return ~0;
309
310                 case 8:
311                     switch (desc->nr_channels) {
312                         case 1:
313                             return R300_TX_FORMAT_X8 | result;
314                         case 2:
315                             return R300_TX_FORMAT_Y8X8 | result;
316                         case 4:
317                             return R300_TX_FORMAT_W8Z8Y8X8 | result;
318                     }
319                     return ~0;
320
321                 case 16:
322                     switch (desc->nr_channels) {
323                         case 1:
324                             return R300_TX_FORMAT_X16 | result;
325                         case 2:
326                             return R300_TX_FORMAT_Y16X16 | result;
327                         case 4:
328                             return R300_TX_FORMAT_W16Z16Y16X16 | result;
329                     }
330             }
331             return ~0;
332
333         case UTIL_FORMAT_TYPE_FLOAT:
334             switch (desc->channel[i].size) {
335                 case 16:
336                     switch (desc->nr_channels) {
337                         case 1:
338                             return R300_TX_FORMAT_16F | result;
339                         case 2:
340                             return R300_TX_FORMAT_16F_16F | result;
341                         case 4:
342                             return R300_TX_FORMAT_16F_16F_16F_16F | result;
343                     }
344                     return ~0;
345
346                 case 32:
347                     switch (desc->nr_channels) {
348                         case 1:
349                             return R300_TX_FORMAT_32F | result;
350                         case 2:
351                             return R300_TX_FORMAT_32F_32F | result;
352                         case 4:
353                             return R300_TX_FORMAT_32F_32F_32F_32F | result;
354                     }
355             }
356     }
357
358     return ~0; /* Unsupported/unknown. */
359 }
360
361 uint32_t r500_tx_format_msb_bit(enum pipe_format format)
362 {
363     switch (format) {
364         case PIPE_FORMAT_RGTC1_UNORM:
365         case PIPE_FORMAT_RGTC1_SNORM:
366         case PIPE_FORMAT_X8Z24_UNORM:
367         case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
368             return R500_TXFORMAT_MSB;
369         default:
370             return 0;
371     }
372 }
373
374 /* Buffer formats. */
375
376 /* Colorbuffer formats. This is the unswizzled format of the RB3D block's
377  * output. For the swizzling of the targets, check the shader's format. */
378 static uint32_t r300_translate_colorformat(enum pipe_format format)
379 {
380     switch (format) {
381         /* 8-bit buffers. */
382         case PIPE_FORMAT_A8_UNORM:
383         /*case PIPE_FORMAT_A8_SNORM:*/
384         case PIPE_FORMAT_I8_UNORM:
385         /*case PIPE_FORMAT_I8_SNORM:*/
386         case PIPE_FORMAT_L8_UNORM:
387         /*case PIPE_FORMAT_L8_SNORM:*/
388         case PIPE_FORMAT_R8_UNORM:
389         case PIPE_FORMAT_R8_SNORM:
390             return R300_COLOR_FORMAT_I8;
391
392         /* 16-bit buffers. */
393         case PIPE_FORMAT_L8A8_UNORM:
394         /*case PIPE_FORMAT_L8A8_SNORM:*/
395         case PIPE_FORMAT_R8G8_UNORM:
396         case PIPE_FORMAT_R8G8_SNORM:
397             return R300_COLOR_FORMAT_UV88;
398
399         case PIPE_FORMAT_B5G6R5_UNORM:
400             return R300_COLOR_FORMAT_RGB565;
401
402         case PIPE_FORMAT_B5G5R5A1_UNORM:
403         case PIPE_FORMAT_B5G5R5X1_UNORM:
404             return R300_COLOR_FORMAT_ARGB1555;
405
406         case PIPE_FORMAT_B4G4R4A4_UNORM:
407         case PIPE_FORMAT_B4G4R4X4_UNORM:
408             return R300_COLOR_FORMAT_ARGB4444;
409
410         /* 32-bit buffers. */
411         case PIPE_FORMAT_B8G8R8A8_UNORM:
412         /*case PIPE_FORMAT_B8G8R8A8_SNORM:*/
413         case PIPE_FORMAT_B8G8R8X8_UNORM:
414         /*case PIPE_FORMAT_B8G8R8X8_SNORM:*/
415         case PIPE_FORMAT_A8R8G8B8_UNORM:
416         /*case PIPE_FORMAT_A8R8G8B8_SNORM:*/
417         case PIPE_FORMAT_X8R8G8B8_UNORM:
418         /*case PIPE_FORMAT_X8R8G8B8_SNORM:*/
419         case PIPE_FORMAT_A8B8G8R8_UNORM:
420         /*case PIPE_FORMAT_A8B8G8R8_SNORM:*/
421         case PIPE_FORMAT_R8G8B8A8_UNORM:
422         case PIPE_FORMAT_R8G8B8A8_SNORM:
423         case PIPE_FORMAT_X8B8G8R8_UNORM:
424         /*case PIPE_FORMAT_X8B8G8R8_SNORM:*/
425         case PIPE_FORMAT_R8G8B8X8_UNORM:
426         /*case PIPE_FORMAT_R8G8B8X8_SNORM:*/
427         case PIPE_FORMAT_R8SG8SB8UX8U_NORM:
428             return R300_COLOR_FORMAT_ARGB8888;
429
430         case PIPE_FORMAT_R10G10B10A2_UNORM:
431         case PIPE_FORMAT_R10G10B10X2_SNORM:
432         case PIPE_FORMAT_B10G10R10A2_UNORM:
433         case PIPE_FORMAT_R10SG10SB10SA2U_NORM:
434             return R500_COLOR_FORMAT_ARGB2101010;  /* R5xx-only? */
435
436         /* 64-bit buffers. */
437         case PIPE_FORMAT_R16G16B16A16_UNORM:
438         case PIPE_FORMAT_R16G16B16A16_SNORM:
439         case PIPE_FORMAT_R16G16B16A16_FLOAT:
440             return R300_COLOR_FORMAT_ARGB16161616;
441
442         /* 128-bit buffers. */
443         case PIPE_FORMAT_R32G32B32A32_FLOAT:
444             return R300_COLOR_FORMAT_ARGB32323232;
445
446         /* YUV buffers. */
447         case PIPE_FORMAT_UYVY:
448             return R300_COLOR_FORMAT_YVYU;
449         case PIPE_FORMAT_YUYV:
450             return R300_COLOR_FORMAT_VYUY;
451         default:
452             return ~0; /* Unsupported. */
453     }
454 }
455
456 /* Depthbuffer and stencilbuffer. Thankfully, we only support two flavors. */
457 static uint32_t r300_translate_zsformat(enum pipe_format format)
458 {
459     switch (format) {
460         /* 16-bit depth, no stencil */
461         case PIPE_FORMAT_Z16_UNORM:
462             return R300_DEPTHFORMAT_16BIT_INT_Z;
463         /* 24-bit depth, ignored stencil */
464         case PIPE_FORMAT_X8Z24_UNORM:
465         /* 24-bit depth, 8-bit stencil */
466         case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
467             return R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL;
468         default:
469             return ~0; /* Unsupported. */
470     }
471 }
472
473 /* Shader output formats. This is essentially the swizzle from the shader
474  * to the RB3D block.
475  *
476  * Note that formats are stored from C3 to C0. */
477 static uint32_t r300_translate_out_fmt(enum pipe_format format)
478 {
479     uint32_t modifier = 0;
480     unsigned i;
481     const struct util_format_description *desc;
482     static const uint32_t sign_bit[4] = {
483         R300_OUT_SIGN(0x1),
484         R300_OUT_SIGN(0x2),
485         R300_OUT_SIGN(0x4),
486         R300_OUT_SIGN(0x8),
487     };
488
489     desc = util_format_description(format);
490
491     /* Find the first non-VOID channel. */
492     for (i = 0; i < 4; i++) {
493         if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) {
494             break;
495         }
496     }
497
498     if (i == 4)
499         return ~0; /* Unsupported/unknown. */
500
501     /* Specifies how the shader output is written to the fog unit. */
502     if (desc->channel[i].type == UTIL_FORMAT_TYPE_FLOAT) {
503         if (desc->channel[i].size == 32) {
504             modifier |= R300_US_OUT_FMT_C4_32_FP;
505         } else {
506             modifier |= R300_US_OUT_FMT_C4_16_FP;
507         }
508     } else {
509         if (desc->channel[i].size == 16) {
510             modifier |= R300_US_OUT_FMT_C4_16;
511         } else if (desc->channel[i].size == 10) {
512             modifier |= R300_US_OUT_FMT_C4_10;
513         } else {
514             /* C4_8 seems to be used for the formats whose pixel size
515              * is <= 32 bits. */
516             modifier |= R300_US_OUT_FMT_C4_8;
517         }
518     }
519
520     /* Add sign. */
521     for (i = 0; i < 4; i++)
522         if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED) {
523             modifier |= sign_bit[i];
524         }
525
526     /* Add swizzles and return. */
527     switch (format) {
528         /* 8-bit outputs, one channel.
529          * COLORFORMAT_I8 stores the C2 component. */
530         case PIPE_FORMAT_A8_UNORM:
531         /*case PIPE_FORMAT_A8_SNORM:*/
532             return modifier | R300_C2_SEL_A;
533         case PIPE_FORMAT_I8_UNORM:
534         /*case PIPE_FORMAT_I8_SNORM:*/
535         case PIPE_FORMAT_L8_UNORM:
536         /*case PIPE_FORMAT_L8_SNORM:*/
537         case PIPE_FORMAT_R8_UNORM:
538         case PIPE_FORMAT_R8_SNORM:
539             return modifier | R300_C2_SEL_R;
540
541         /* 16-bit outputs, two channels.
542          * COLORFORMAT_UV88 stores C2 and C0. */
543         case PIPE_FORMAT_L8A8_UNORM:
544         /*case PIPE_FORMAT_L8A8_SNORM:*/
545             return modifier | R300_C0_SEL_A | R300_C2_SEL_R;
546         case PIPE_FORMAT_R8G8_UNORM:
547         case PIPE_FORMAT_R8G8_SNORM:
548             return modifier | R300_C0_SEL_G | R300_C2_SEL_R;
549
550         /* BGRA outputs. */
551         case PIPE_FORMAT_B5G6R5_UNORM:
552         case PIPE_FORMAT_B5G5R5A1_UNORM:
553         case PIPE_FORMAT_B5G5R5X1_UNORM:
554         case PIPE_FORMAT_B4G4R4A4_UNORM:
555         case PIPE_FORMAT_B4G4R4X4_UNORM:
556         case PIPE_FORMAT_B8G8R8A8_UNORM:
557         /*case PIPE_FORMAT_B8G8R8A8_SNORM:*/
558         case PIPE_FORMAT_B8G8R8X8_UNORM:
559         /*case PIPE_FORMAT_B8G8R8X8_SNORM:*/
560         case PIPE_FORMAT_B10G10R10A2_UNORM:
561             return modifier |
562                 R300_C0_SEL_B | R300_C1_SEL_G |
563                 R300_C2_SEL_R | R300_C3_SEL_A;
564
565         /* ARGB outputs. */
566         case PIPE_FORMAT_A8R8G8B8_UNORM:
567         /*case PIPE_FORMAT_A8R8G8B8_SNORM:*/
568         case PIPE_FORMAT_X8R8G8B8_UNORM:
569         /*case PIPE_FORMAT_X8R8G8B8_SNORM:*/
570             return modifier |
571                 R300_C0_SEL_A | R300_C1_SEL_R |
572                 R300_C2_SEL_G | R300_C3_SEL_B;
573
574         /* ABGR outputs. */
575         case PIPE_FORMAT_A8B8G8R8_UNORM:
576         /*case PIPE_FORMAT_A8B8G8R8_SNORM:*/
577         case PIPE_FORMAT_X8B8G8R8_UNORM:
578         /*case PIPE_FORMAT_X8B8G8R8_SNORM:*/
579             return modifier |
580                 R300_C0_SEL_A | R300_C1_SEL_B |
581                 R300_C2_SEL_G | R300_C3_SEL_R;
582
583         /* RGBA outputs. */
584         case PIPE_FORMAT_R8G8B8X8_UNORM:
585         /*case PIPE_FORMAT_R8G8B8X8_SNORM:*/
586         case PIPE_FORMAT_R8G8B8A8_UNORM:
587         case PIPE_FORMAT_R8G8B8A8_SNORM:
588         case PIPE_FORMAT_R8SG8SB8UX8U_NORM:
589         case PIPE_FORMAT_R10G10B10A2_UNORM:
590         case PIPE_FORMAT_R10G10B10X2_SNORM:
591         case PIPE_FORMAT_R10SG10SB10SA2U_NORM:
592         case PIPE_FORMAT_R16G16B16A16_UNORM:
593         case PIPE_FORMAT_R16G16B16A16_SNORM:
594         case PIPE_FORMAT_R16G16B16A16_FLOAT:
595         case PIPE_FORMAT_R32G32B32A32_FLOAT:
596             return modifier |
597                 R300_C0_SEL_R | R300_C1_SEL_G |
598                 R300_C2_SEL_B | R300_C3_SEL_A;
599
600         default:
601             return ~0; /* Unsupported. */
602     }
603 }
604
605 boolean r300_is_colorbuffer_format_supported(enum pipe_format format)
606 {
607     return r300_translate_colorformat(format) != ~0 &&
608            r300_translate_out_fmt(format) != ~0;
609 }
610
611 boolean r300_is_zs_format_supported(enum pipe_format format)
612 {
613     return r300_translate_zsformat(format) != ~0;
614 }
615
616 boolean r300_is_sampler_format_supported(enum pipe_format format)
617 {
618     return r300_translate_texformat(format, 0, TRUE, FALSE) != ~0;
619 }
620
621 void r300_texture_setup_format_state(struct r300_screen *screen,
622                                      struct r300_resource *tex,
623                                      unsigned level,
624                                      struct r300_texture_format_state *out)
625 {
626     struct pipe_resource *pt = &tex->b.b.b;
627     struct r300_texture_desc *desc = &tex->tex;
628     boolean is_r500 = screen->caps.is_r500;
629
630     /* Mask out all the fields we change. */
631     out->format0 = 0;
632     out->format1 &= ~R300_TX_FORMAT_TEX_COORD_TYPE_MASK;
633     out->format2 &= R500_TXFORMAT_MSB;
634     out->tile_config = 0;
635
636     /* Set sampler state. */
637     out->format0 =
638         R300_TX_WIDTH((u_minify(desc->width0, level) - 1) & 0x7ff) |
639         R300_TX_HEIGHT((u_minify(desc->height0, level) - 1) & 0x7ff) |
640         R300_TX_DEPTH(util_logbase2(u_minify(desc->depth0, level)) & 0xf);
641
642     if (desc->uses_stride_addressing) {
643         /* rectangles love this */
644         out->format0 |= R300_TX_PITCH_EN;
645         out->format2 = (desc->stride_in_pixels[level] - 1) & 0x1fff;
646     }
647
648     if (pt->target == PIPE_TEXTURE_CUBE) {
649         out->format1 |= R300_TX_FORMAT_CUBIC_MAP;
650     }
651     if (pt->target == PIPE_TEXTURE_3D) {
652         out->format1 |= R300_TX_FORMAT_3D;
653     }
654
655     /* large textures on r500 */
656     if (is_r500)
657     {
658         if (desc->width0 > 2048) {
659             out->format2 |= R500_TXWIDTH_BIT11;
660         }
661         if (desc->height0 > 2048) {
662             out->format2 |= R500_TXHEIGHT_BIT11;
663         }
664     }
665
666     out->tile_config = R300_TXO_MACRO_TILE(desc->macrotile[level]) |
667                        R300_TXO_MICRO_TILE(desc->microtile);
668 }
669
670 static void r300_texture_setup_fb_state(struct r300_surface *surf)
671 {
672     struct r300_resource *tex = r300_resource(surf->base.texture);
673     unsigned level = surf->base.u.tex.level;
674
675     /* Set framebuffer state. */
676     if (util_format_is_depth_or_stencil(surf->base.format)) {
677         surf->pitch =
678                 tex->tex.stride_in_pixels[level] |
679                 R300_DEPTHMACROTILE(tex->tex.macrotile[level]) |
680                 R300_DEPTHMICROTILE(tex->tex.microtile);
681         surf->format = r300_translate_zsformat(surf->base.format);
682         surf->pitch_zmask = tex->tex.zmask_stride_in_pixels[level];
683         surf->pitch_hiz = tex->tex.hiz_stride_in_pixels[level];
684     } else {
685         surf->pitch =
686                 tex->tex.stride_in_pixels[level] |
687                 r300_translate_colorformat(surf->base.format) |
688                 R300_COLOR_TILE(tex->tex.macrotile[level]) |
689                 R300_COLOR_MICROTILE(tex->tex.microtile);
690         surf->format = r300_translate_out_fmt(surf->base.format);
691     }
692 }
693
694 boolean r300_resource_set_properties(struct pipe_screen *screen,
695                                      struct pipe_resource *tex,
696                                      unsigned offset,
697                                      const struct pipe_resource *new_properties)
698 {
699     struct r300_screen *rscreen = r300_screen(screen);
700     struct r300_resource *res = r300_resource(tex);
701
702     SCREEN_DBG(rscreen, DBG_TEX,
703         "r300: texture_set_properties: %s -> %s\n",
704         util_format_short_name(tex->format),
705         util_format_short_name(new_properties->format));
706
707     if (!r300_texture_desc_init(rscreen, res, new_properties)) {
708         fprintf(stderr, "r300: ERROR: Cannot set texture properties.\n");
709         return FALSE;
710     }
711     res->tex_offset = offset;
712     r300_texture_setup_format_state(rscreen, res, 0, &res->tx_format);
713
714     return TRUE;
715 }
716
717 static void r300_texture_destroy(struct pipe_screen *screen,
718                                  struct pipe_resource* texture)
719 {
720     struct r300_resource* tex = (struct r300_resource*)texture;
721
722     r300_winsys_bo_reference(&tex->buf, NULL);
723     FREE(tex);
724 }
725
726 boolean r300_resource_get_handle(struct pipe_screen* screen,
727                                  struct pipe_resource *texture,
728                                  struct winsys_handle *whandle)
729 {
730     struct r300_winsys_screen *rws = (struct r300_winsys_screen *)screen->winsys;
731     struct r300_resource* tex = (struct r300_resource*)texture;
732
733     if (!tex) {
734         return FALSE;
735     }
736
737     return rws->buffer_get_handle(tex->buf,
738                                   tex->tex.stride_in_bytes[0], whandle);
739 }
740
741 static const struct u_resource_vtbl r300_texture_vtbl =
742 {
743     NULL,                           /* get_handle */
744     r300_texture_destroy,           /* resource_destroy */
745     NULL,                           /* is_resource_referenced */
746     r300_texture_get_transfer,      /* get_transfer */
747     r300_texture_transfer_destroy,  /* transfer_destroy */
748     r300_texture_transfer_map,      /* transfer_map */
749     NULL,                           /* transfer_flush_region */
750     r300_texture_transfer_unmap,    /* transfer_unmap */
751     u_default_transfer_inline_write /* transfer_inline_write */
752 };
753
754 /* The common texture constructor. */
755 static struct r300_resource*
756 r300_texture_create_object(struct r300_screen *rscreen,
757                            const struct pipe_resource *base,
758                            enum r300_buffer_tiling microtile,
759                            enum r300_buffer_tiling macrotile,
760                            unsigned stride_in_bytes_override,
761                            unsigned max_buffer_size,
762                            struct r300_winsys_bo *buffer)
763 {
764     struct r300_winsys_screen *rws = rscreen->rws;
765     struct r300_resource *tex = CALLOC_STRUCT(r300_resource);
766     if (!tex) {
767         if (buffer)
768             r300_winsys_bo_reference(&buffer, NULL);
769         return NULL;
770     }
771
772     pipe_reference_init(&tex->b.b.b.reference, 1);
773     tex->b.b.b.screen = &rscreen->screen;
774     tex->b.b.b.usage = base->usage;
775     tex->b.b.b.bind = base->bind;
776     tex->b.b.b.flags = base->flags;
777     tex->b.b.vtbl = &r300_texture_vtbl;
778     tex->tex.microtile = microtile;
779     tex->tex.macrotile[0] = macrotile;
780     tex->tex.stride_in_bytes_override = stride_in_bytes_override;
781     tex->domain = base->flags & R300_RESOURCE_FLAG_TRANSFER ?
782                   R300_DOMAIN_GTT :
783                   R300_DOMAIN_VRAM | R300_DOMAIN_GTT;
784     tex->buf_size = max_buffer_size;
785
786     if (!r300_resource_set_properties(&rscreen->screen, &tex->b.b.b, 0, base)) {
787         if (buffer)
788             r300_winsys_bo_reference(&buffer, NULL);
789         FREE(tex);
790         return NULL;
791     }
792
793     /* Create the backing buffer if needed. */
794     if (!buffer) {
795         tex->buf_size = tex->tex.size_in_bytes;
796         tex->buf = rws->buffer_create(rws, tex->tex.size_in_bytes, 2048,
797                                          base->bind, base->usage, tex->domain);
798
799         if (!tex->buf) {
800             FREE(tex);
801             return NULL;
802         }
803     } else {
804         tex->buf = buffer;
805     }
806
807     tex->cs_buf = rws->buffer_get_cs_handle(tex->buf);
808
809     rws->buffer_set_tiling(tex->buf, NULL,
810             tex->tex.microtile, tex->tex.macrotile[0],
811             tex->tex.stride_in_bytes[0]);
812
813     return tex;
814 }
815
816 /* Create a new texture. */
817 struct pipe_resource *r300_texture_create(struct pipe_screen *screen,
818                                           const struct pipe_resource *base)
819 {
820     struct r300_screen *rscreen = r300_screen(screen);
821     enum r300_buffer_tiling microtile, macrotile;
822
823     if ((base->flags & R300_RESOURCE_FLAG_TRANSFER) ||
824         (base->bind & PIPE_BIND_SCANOUT)) {
825         microtile = R300_BUFFER_LINEAR;
826         macrotile = R300_BUFFER_LINEAR;
827     } else {
828         microtile = R300_BUFFER_SELECT_LAYOUT;
829         macrotile = R300_BUFFER_SELECT_LAYOUT;
830     }
831
832     return (struct pipe_resource*)
833            r300_texture_create_object(rscreen, base, microtile, macrotile,
834                                       0, 0, NULL);
835 }
836
837 struct pipe_resource *r300_texture_from_handle(struct pipe_screen *screen,
838                                                const struct pipe_resource *base,
839                                                struct winsys_handle *whandle)
840 {
841     struct r300_winsys_screen *rws = (struct r300_winsys_screen*)screen->winsys;
842     struct r300_screen *rscreen = r300_screen(screen);
843     struct r300_winsys_bo *buffer;
844     enum r300_buffer_tiling microtile, macrotile;
845     unsigned stride, size;
846
847     /* Support only 2D textures without mipmaps */
848     if ((base->target != PIPE_TEXTURE_2D &&
849           base->target != PIPE_TEXTURE_RECT) ||
850         base->depth0 != 1 ||
851         base->last_level != 0) {
852         return NULL;
853     }
854
855     buffer = rws->buffer_from_handle(rws, whandle, &stride, &size);
856     if (!buffer)
857         return NULL;
858
859     rws->buffer_get_tiling(buffer, &microtile, &macrotile);
860
861     /* Enforce a microtiled zbuffer. */
862     if (util_format_is_depth_or_stencil(base->format) &&
863         microtile == R300_BUFFER_LINEAR) {
864         switch (util_format_get_blocksize(base->format)) {
865             case 4:
866                 microtile = R300_BUFFER_TILED;
867                 break;
868
869             case 2:
870                 if (rws->get_value(rws, R300_VID_DRM_2_1_0))
871                     microtile = R300_BUFFER_SQUARETILED;
872                 break;
873         }
874     }
875
876     return (struct pipe_resource*)
877            r300_texture_create_object(rscreen, base, microtile, macrotile,
878                                       stride, size, buffer);
879 }
880
881 /* Not required to implement u_resource_vtbl, consider moving to another file:
882  */
883 struct pipe_surface* r300_create_surface(struct pipe_context * ctx,
884                                          struct pipe_resource* texture,
885                                          const struct pipe_surface *surf_tmpl)
886 {
887     struct r300_resource* tex = r300_resource(texture);
888     struct r300_surface* surface = CALLOC_STRUCT(r300_surface);
889     unsigned level = surf_tmpl->u.tex.level;
890
891     assert(surf_tmpl->u.tex.first_layer == surf_tmpl->u.tex.last_layer);
892
893     if (surface) {
894         uint32_t offset, tile_height;
895
896         pipe_reference_init(&surface->base.reference, 1);
897         pipe_resource_reference(&surface->base.texture, texture);
898         surface->base.context = ctx;
899         surface->base.format = surf_tmpl->format;
900         surface->base.width = u_minify(texture->width0, level);
901         surface->base.height = u_minify(texture->height0, level);
902         surface->base.usage = surf_tmpl->usage;
903         surface->base.u.tex.level = level;
904         surface->base.u.tex.first_layer = surf_tmpl->u.tex.first_layer;
905         surface->base.u.tex.last_layer = surf_tmpl->u.tex.last_layer;
906
907         surface->buf = tex->buf;
908         surface->cs_buf = tex->cs_buf;
909
910         /* Prefer VRAM if there are multiple domains to choose from. */
911         surface->domain = tex->domain;
912         if (surface->domain & R300_DOMAIN_VRAM)
913             surface->domain &= ~R300_DOMAIN_GTT;
914
915         surface->offset = r300_texture_get_offset(tex, level,
916                                                   surf_tmpl->u.tex.first_layer);
917         r300_texture_setup_fb_state(surface);
918
919         /* Parameters for the CBZB clear. */
920         surface->cbzb_allowed = tex->tex.cbzb_allowed[level];
921         surface->cbzb_width = align(surface->base.width, 64);
922
923         /* Height must be aligned to the size of a tile. */
924         tile_height = r300_get_pixel_alignment(tex->b.b.b.format,
925                                                tex->b.b.b.nr_samples,
926                                                tex->tex.microtile,
927                                                tex->tex.macrotile[level],
928                                                DIM_HEIGHT, 0);
929
930         surface->cbzb_height = align((surface->base.height + 1) / 2,
931                                      tile_height);
932
933         /* Offset must be aligned to 2K and must point at the beginning
934          * of a scanline. */
935         offset = surface->offset +
936                  tex->tex.stride_in_bytes[level] * surface->cbzb_height;
937         surface->cbzb_midpoint_offset = offset & ~2047;
938
939         surface->cbzb_pitch = surface->pitch & 0x1ffffc;
940
941         if (util_format_get_blocksizebits(surface->base.format) == 32)
942             surface->cbzb_format = R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL;
943         else
944             surface->cbzb_format = R300_DEPTHFORMAT_16BIT_INT_Z;
945
946         DBG(r300_context(ctx), DBG_CBZB,
947             "CBZB Allowed: %s, Dim: %ix%i, Misalignment: %i, Micro: %s, Macro: %s\n",
948             surface->cbzb_allowed ? "YES" : " NO",
949             surface->cbzb_width, surface->cbzb_height,
950             offset & 2047,
951             tex->tex.microtile ? "YES" : " NO",
952             tex->tex.macrotile[level] ? "YES" : " NO");
953     }
954
955     return &surface->base;
956 }
957
958 /* Not required to implement u_resource_vtbl, consider moving to another file:
959  */
960 void r300_surface_destroy(struct pipe_context *ctx, struct pipe_surface* s)
961 {
962     pipe_resource_reference(&s->texture, NULL);
963     FREE(s);
964 }