r300_texture.c revision b8e80941
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
33#include "util/u_format.h"
34#include "util/u_format_s3tc.h"
35#include "util/u_math.h"
36#include "util/u_memory.h"
37
38#include "pipe/p_screen.h"
39
40/* These formats are supported by swapping their bytes.
41 * The swizzles must be set exactly like their non-swapped counterparts,
42 * because byte-swapping is what reverses the component order, not swizzling.
43 *
44 * This function returns the format that must be used to program CB and TX
45 * swizzles.
46 */
47static enum pipe_format r300_unbyteswap_array_format(enum pipe_format format)
48{
49    /* FIXME: Disabled on little endian because of a reported regression:
50     * https://bugs.freedesktop.org/show_bug.cgi?id=98869 */
51    if (PIPE_ENDIAN_NATIVE != PIPE_ENDIAN_BIG)
52        return format;
53
54    /* Only BGRA 8888 array formats are supported for simplicity of
55     * the implementation. */
56    switch (format) {
57    case PIPE_FORMAT_A8R8G8B8_UNORM:
58        return PIPE_FORMAT_B8G8R8A8_UNORM;
59    case PIPE_FORMAT_A8R8G8B8_SRGB:
60        return PIPE_FORMAT_B8G8R8A8_SRGB;
61    case PIPE_FORMAT_X8R8G8B8_UNORM:
62        return PIPE_FORMAT_B8G8R8X8_UNORM;
63    case PIPE_FORMAT_X8R8G8B8_SRGB:
64        return PIPE_FORMAT_B8G8R8X8_SRGB;
65    default:
66        return format;
67    }
68}
69
70static unsigned r300_get_endian_swap(enum pipe_format format)
71{
72    const struct util_format_description *desc;
73    unsigned swap_size;
74
75    if (r300_unbyteswap_array_format(format) != format)
76        return R300_SURF_DWORD_SWAP;
77
78    if (PIPE_ENDIAN_NATIVE != PIPE_ENDIAN_BIG)
79        return R300_SURF_NO_SWAP;
80
81    desc = util_format_description(format);
82    if (!desc)
83        return R300_SURF_NO_SWAP;
84
85    /* Compressed formats should be in the little endian format. */
86    if (desc->block.width != 1 || desc->block.height != 1)
87        return R300_SURF_NO_SWAP;
88
89    swap_size = desc->is_array ? desc->channel[0].size : desc->block.bits;
90
91    switch (swap_size) {
92    default: /* shouldn't happen? */
93    case 8:
94        return R300_SURF_NO_SWAP;
95    case 16:
96        return R300_SURF_WORD_SWAP;
97    case 32:
98        return R300_SURF_DWORD_SWAP;
99    }
100}
101
102unsigned r300_get_swizzle_combined(const unsigned char *swizzle_format,
103                                   const unsigned char *swizzle_view,
104                                   boolean dxtc_swizzle)
105{
106    unsigned i;
107    unsigned char swizzle[4];
108    unsigned result = 0;
109    const uint32_t swizzle_shift[4] = {
110        R300_TX_FORMAT_R_SHIFT,
111        R300_TX_FORMAT_G_SHIFT,
112        R300_TX_FORMAT_B_SHIFT,
113        R300_TX_FORMAT_A_SHIFT
114    };
115    uint32_t swizzle_bit[4] = {
116        dxtc_swizzle ? R300_TX_FORMAT_Z : R300_TX_FORMAT_X,
117        R300_TX_FORMAT_Y,
118        dxtc_swizzle ? R300_TX_FORMAT_X : R300_TX_FORMAT_Z,
119        R300_TX_FORMAT_W
120    };
121
122    if (swizzle_view) {
123        /* Combine two sets of swizzles. */
124        util_format_compose_swizzles(swizzle_format, swizzle_view, swizzle);
125    } else {
126        memcpy(swizzle, swizzle_format, 4);
127    }
128
129    /* Get swizzle. */
130    for (i = 0; i < 4; i++) {
131        switch (swizzle[i]) {
132            case PIPE_SWIZZLE_Y:
133                result |= swizzle_bit[1] << swizzle_shift[i];
134                break;
135            case PIPE_SWIZZLE_Z:
136                result |= swizzle_bit[2] << swizzle_shift[i];
137                break;
138            case PIPE_SWIZZLE_W:
139                result |= swizzle_bit[3] << swizzle_shift[i];
140                break;
141            case PIPE_SWIZZLE_0:
142                result |= R300_TX_FORMAT_ZERO << swizzle_shift[i];
143                break;
144            case PIPE_SWIZZLE_1:
145                result |= R300_TX_FORMAT_ONE << swizzle_shift[i];
146                break;
147            default: /* PIPE_SWIZZLE_X */
148                result |= swizzle_bit[0] << swizzle_shift[i];
149        }
150    }
151    return result;
152}
153
154/* Translate a pipe_format into a useful texture format for sampling.
155 *
156 * Some special formats are translated directly using R300_EASY_TX_FORMAT,
157 * but the majority of them is translated in a generic way, automatically
158 * supporting all the formats hw can support.
159 *
160 * R300_EASY_TX_FORMAT swizzles the texture.
161 * Note the signature of R300_EASY_TX_FORMAT:
162 *   R300_EASY_TX_FORMAT(B, G, R, A, FORMAT);
163 *
164 * The FORMAT specifies how the texture sampler will treat the texture, and
165 * makes available X, Y, Z, W, ZERO, and ONE for swizzling. */
166uint32_t r300_translate_texformat(enum pipe_format format,
167                                  const unsigned char *swizzle_view,
168                                  boolean is_r500,
169                                  boolean dxtc_swizzle)
170{
171    uint32_t result = 0;
172    const struct util_format_description *desc;
173    unsigned i;
174    boolean uniform = TRUE;
175    const uint32_t sign_bit[4] = {
176        R300_TX_FORMAT_SIGNED_W,
177        R300_TX_FORMAT_SIGNED_Z,
178        R300_TX_FORMAT_SIGNED_Y,
179        R300_TX_FORMAT_SIGNED_X,
180    };
181
182    format = r300_unbyteswap_array_format(format);
183    desc = util_format_description(format);
184
185    /* Colorspace (return non-RGB formats directly). */
186    switch (desc->colorspace) {
187        /* Depth stencil formats.
188         * Swizzles are added in r300_merge_textures_and_samplers. */
189        case UTIL_FORMAT_COLORSPACE_ZS:
190            switch (format) {
191                case PIPE_FORMAT_Z16_UNORM:
192                    return R300_TX_FORMAT_X16;
193                case PIPE_FORMAT_X8Z24_UNORM:
194                case PIPE_FORMAT_S8_UINT_Z24_UNORM:
195                    if (is_r500)
196                        return R500_TX_FORMAT_Y8X24;
197                    else
198                        return R300_TX_FORMAT_Y16X16;
199                default:
200                    return ~0; /* Unsupported. */
201            }
202
203        /* YUV formats. */
204        case UTIL_FORMAT_COLORSPACE_YUV:
205            result |= R300_TX_FORMAT_YUV_TO_RGB;
206
207            switch (format) {
208                case PIPE_FORMAT_UYVY:
209                    return R300_EASY_TX_FORMAT(X, Y, Z, ONE, YVYU422) | result;
210                case PIPE_FORMAT_YUYV:
211                    return R300_EASY_TX_FORMAT(X, Y, Z, ONE, VYUY422) | result;
212                default:
213                    return ~0; /* Unsupported/unknown. */
214            }
215
216        /* Add gamma correction. */
217        case UTIL_FORMAT_COLORSPACE_SRGB:
218            result |= R300_TX_FORMAT_GAMMA;
219            break;
220
221        default:
222            switch (format) {
223                /* Same as YUV but without the YUR->RGB conversion. */
224                case PIPE_FORMAT_R8G8_B8G8_UNORM:
225                    return R300_EASY_TX_FORMAT(X, Y, Z, ONE, YVYU422) | result;
226                case PIPE_FORMAT_G8R8_G8B8_UNORM:
227                    return R300_EASY_TX_FORMAT(X, Y, Z, ONE, VYUY422) | result;
228                default:;
229            }
230    }
231
232    /* Add swizzling. */
233    /* The RGTC1_SNORM and LATC1_SNORM swizzle is done in the shader. */
234    if (util_format_is_compressed(format) &&
235        dxtc_swizzle &&
236        format != PIPE_FORMAT_RGTC2_UNORM &&
237        format != PIPE_FORMAT_RGTC2_SNORM &&
238        format != PIPE_FORMAT_LATC2_UNORM &&
239        format != PIPE_FORMAT_LATC2_SNORM &&
240        format != PIPE_FORMAT_RGTC1_UNORM &&
241        format != PIPE_FORMAT_RGTC1_SNORM &&
242        format != PIPE_FORMAT_LATC1_UNORM &&
243        format != PIPE_FORMAT_LATC1_SNORM) {
244        result |= r300_get_swizzle_combined(desc->swizzle, swizzle_view,
245                                            TRUE);
246    } else {
247        result |= r300_get_swizzle_combined(desc->swizzle, swizzle_view,
248                                            FALSE);
249    }
250
251    /* S3TC formats. */
252    if (desc->layout == UTIL_FORMAT_LAYOUT_S3TC) {
253        switch (format) {
254            case PIPE_FORMAT_DXT1_RGB:
255            case PIPE_FORMAT_DXT1_RGBA:
256            case PIPE_FORMAT_DXT1_SRGB:
257            case PIPE_FORMAT_DXT1_SRGBA:
258                return R300_TX_FORMAT_DXT1 | result;
259            case PIPE_FORMAT_DXT3_RGBA:
260            case PIPE_FORMAT_DXT3_SRGBA:
261                return R300_TX_FORMAT_DXT3 | result;
262            case PIPE_FORMAT_DXT5_RGBA:
263            case PIPE_FORMAT_DXT5_SRGBA:
264                return R300_TX_FORMAT_DXT5 | result;
265            default:
266                return ~0; /* Unsupported/unknown. */
267        }
268    }
269
270    /* RGTC formats. */
271    if (desc->layout == UTIL_FORMAT_LAYOUT_RGTC) {
272        switch (format) {
273            case PIPE_FORMAT_RGTC1_SNORM:
274            case PIPE_FORMAT_LATC1_SNORM:
275                result |= sign_bit[0];
276            case PIPE_FORMAT_LATC1_UNORM:
277            case PIPE_FORMAT_RGTC1_UNORM:
278                return R500_TX_FORMAT_ATI1N | result;
279
280            case PIPE_FORMAT_RGTC2_SNORM:
281            case PIPE_FORMAT_LATC2_SNORM:
282                result |= sign_bit[1] | sign_bit[0];
283            case PIPE_FORMAT_RGTC2_UNORM:
284            case PIPE_FORMAT_LATC2_UNORM:
285                return R400_TX_FORMAT_ATI2N | result;
286
287            default:
288                return ~0; /* Unsupported/unknown. */
289        }
290    }
291
292    /* This is truly a special format.
293     * It stores R8G8 and B is computed using sqrt(1 - R^2 - G^2)
294     * in the sampler unit. Also known as D3DFMT_CxV8U8. */
295    if (format == PIPE_FORMAT_R8G8Bx_SNORM) {
296        return R300_TX_FORMAT_CxV8U8 | result;
297    }
298
299    /* Integer and fixed-point 16.16 textures are not supported. */
300    for (i = 0; i < 4; i++) {
301        if (desc->channel[i].type == UTIL_FORMAT_TYPE_FIXED ||
302            ((desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED ||
303              desc->channel[i].type == UTIL_FORMAT_TYPE_UNSIGNED) &&
304             (!desc->channel[i].normalized ||
305              desc->channel[i].pure_integer))) {
306            return ~0; /* Unsupported/unknown. */
307        }
308    }
309
310    /* Add sign. */
311    for (i = 0; i < desc->nr_channels; i++) {
312        if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED) {
313            result |= sign_bit[i];
314        }
315    }
316
317    /* See whether the components are of the same size. */
318    for (i = 1; i < desc->nr_channels; i++) {
319        uniform = uniform && desc->channel[0].size == desc->channel[i].size;
320    }
321
322    /* Non-uniform formats. */
323    if (!uniform) {
324        switch (desc->nr_channels) {
325            case 3:
326                if (desc->channel[0].size == 5 &&
327                    desc->channel[1].size == 6 &&
328                    desc->channel[2].size == 5) {
329                    return R300_TX_FORMAT_Z5Y6X5 | result;
330                }
331                if (desc->channel[0].size == 5 &&
332                    desc->channel[1].size == 5 &&
333                    desc->channel[2].size == 6) {
334                    return R300_TX_FORMAT_Z6Y5X5 | result;
335                }
336                if (desc->channel[0].size == 2 &&
337                    desc->channel[1].size == 3 &&
338                    desc->channel[2].size == 3) {
339                    return R300_TX_FORMAT_Z3Y3X2 | result;
340                }
341                return ~0; /* Unsupported/unknown. */
342
343            case 4:
344                if (desc->channel[0].size == 5 &&
345                    desc->channel[1].size == 5 &&
346                    desc->channel[2].size == 5 &&
347                    desc->channel[3].size == 1) {
348                    return R300_TX_FORMAT_W1Z5Y5X5 | result;
349                }
350                if (desc->channel[0].size == 10 &&
351                    desc->channel[1].size == 10 &&
352                    desc->channel[2].size == 10 &&
353                    desc->channel[3].size == 2) {
354                    return R300_TX_FORMAT_W2Z10Y10X10 | result;
355                }
356        }
357        return ~0; /* Unsupported/unknown. */
358    }
359
360    /* Find the first non-VOID channel. */
361    for (i = 0; i < 4; i++) {
362        if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) {
363            break;
364        }
365    }
366
367    if (i == 4)
368        return ~0; /* Unsupported/unknown. */
369
370    /* And finally, uniform formats. */
371    switch (desc->channel[i].type) {
372        case UTIL_FORMAT_TYPE_UNSIGNED:
373        case UTIL_FORMAT_TYPE_SIGNED:
374            if (!desc->channel[i].normalized &&
375                desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB) {
376                return ~0;
377            }
378
379            switch (desc->channel[i].size) {
380                case 4:
381                    switch (desc->nr_channels) {
382                        case 2:
383                            return R300_TX_FORMAT_Y4X4 | result;
384                        case 4:
385                            return R300_TX_FORMAT_W4Z4Y4X4 | result;
386                    }
387                    return ~0;
388
389                case 8:
390                    switch (desc->nr_channels) {
391                        case 1:
392                            return R300_TX_FORMAT_X8 | result;
393                        case 2:
394                            return R300_TX_FORMAT_Y8X8 | result;
395                        case 4:
396                            return R300_TX_FORMAT_W8Z8Y8X8 | result;
397                    }
398                    return ~0;
399
400                case 16:
401                    switch (desc->nr_channels) {
402                        case 1:
403                            return R300_TX_FORMAT_X16 | result;
404                        case 2:
405                            return R300_TX_FORMAT_Y16X16 | result;
406                        case 4:
407                            return R300_TX_FORMAT_W16Z16Y16X16 | result;
408                    }
409            }
410            return ~0;
411
412        case UTIL_FORMAT_TYPE_FLOAT:
413            switch (desc->channel[i].size) {
414                case 16:
415                    switch (desc->nr_channels) {
416                        case 1:
417                            return R300_TX_FORMAT_16F | result;
418                        case 2:
419                            return R300_TX_FORMAT_16F_16F | result;
420                        case 4:
421                            return R300_TX_FORMAT_16F_16F_16F_16F | result;
422                    }
423                    return ~0;
424
425                case 32:
426                    switch (desc->nr_channels) {
427                        case 1:
428                            return R300_TX_FORMAT_32F | result;
429                        case 2:
430                            return R300_TX_FORMAT_32F_32F | result;
431                        case 4:
432                            return R300_TX_FORMAT_32F_32F_32F_32F | result;
433                    }
434            }
435    }
436
437    return ~0; /* Unsupported/unknown. */
438}
439
440uint32_t r500_tx_format_msb_bit(enum pipe_format format)
441{
442    switch (format) {
443        case PIPE_FORMAT_RGTC1_UNORM:
444        case PIPE_FORMAT_RGTC1_SNORM:
445        case PIPE_FORMAT_LATC1_UNORM:
446        case PIPE_FORMAT_LATC1_SNORM:
447        case PIPE_FORMAT_X8Z24_UNORM:
448        case PIPE_FORMAT_S8_UINT_Z24_UNORM:
449            return R500_TXFORMAT_MSB;
450        default:
451            return 0;
452    }
453}
454
455/* Buffer formats. */
456
457/* Colorbuffer formats. This is the unswizzled format of the RB3D block's
458 * output. For the swizzling of the targets, check the shader's format. */
459static uint32_t r300_translate_colorformat(enum pipe_format format)
460{
461    format = r300_unbyteswap_array_format(format);
462
463    switch (format) {
464        /* 8-bit buffers. */
465        case PIPE_FORMAT_A8_UNORM:
466        case PIPE_FORMAT_A8_SNORM:
467        case PIPE_FORMAT_I8_UNORM:
468        case PIPE_FORMAT_I8_SNORM:
469        case PIPE_FORMAT_L8_UNORM:
470        case PIPE_FORMAT_L8_SNORM:
471        case PIPE_FORMAT_R8_UNORM:
472        case PIPE_FORMAT_R8_SNORM:
473            return R300_COLOR_FORMAT_I8;
474
475        /* 16-bit buffers. */
476        case PIPE_FORMAT_L8A8_UNORM:
477        case PIPE_FORMAT_L8A8_SNORM:
478        case PIPE_FORMAT_R8G8_UNORM:
479        case PIPE_FORMAT_R8G8_SNORM:
480        case PIPE_FORMAT_R8A8_UNORM:
481        case PIPE_FORMAT_R8A8_SNORM:
482        /* These formats work fine with UV88 if US_OUT_FMT is set correctly. */
483        case PIPE_FORMAT_A16_UNORM:
484        case PIPE_FORMAT_A16_SNORM:
485        case PIPE_FORMAT_A16_FLOAT:
486        case PIPE_FORMAT_L16_UNORM:
487        case PIPE_FORMAT_L16_SNORM:
488        case PIPE_FORMAT_L16_FLOAT:
489        case PIPE_FORMAT_I16_UNORM:
490        case PIPE_FORMAT_I16_SNORM:
491        case PIPE_FORMAT_I16_FLOAT:
492        case PIPE_FORMAT_R16_UNORM:
493        case PIPE_FORMAT_R16_SNORM:
494        case PIPE_FORMAT_R16_FLOAT:
495            return R300_COLOR_FORMAT_UV88;
496
497        case PIPE_FORMAT_B5G6R5_UNORM:
498            return R300_COLOR_FORMAT_RGB565;
499
500        case PIPE_FORMAT_B5G5R5A1_UNORM:
501        case PIPE_FORMAT_B5G5R5X1_UNORM:
502            return R300_COLOR_FORMAT_ARGB1555;
503
504        case PIPE_FORMAT_B4G4R4A4_UNORM:
505        case PIPE_FORMAT_B4G4R4X4_UNORM:
506            return R300_COLOR_FORMAT_ARGB4444;
507
508        /* 32-bit buffers. */
509        case PIPE_FORMAT_B8G8R8A8_UNORM:
510        /*case PIPE_FORMAT_B8G8R8A8_SNORM:*/
511        case PIPE_FORMAT_B8G8R8X8_UNORM:
512        /*case PIPE_FORMAT_B8G8R8X8_SNORM:*/
513        case PIPE_FORMAT_R8G8B8A8_UNORM:
514        case PIPE_FORMAT_R8G8B8A8_SNORM:
515        case PIPE_FORMAT_R8G8B8X8_UNORM:
516        case PIPE_FORMAT_R8G8B8X8_SNORM:
517        /* These formats work fine with ARGB8888 if US_OUT_FMT is set
518         * correctly. */
519        case PIPE_FORMAT_R16G16_UNORM:
520        case PIPE_FORMAT_R16G16_SNORM:
521        case PIPE_FORMAT_R16G16_FLOAT:
522        case PIPE_FORMAT_L16A16_UNORM:
523        case PIPE_FORMAT_L16A16_SNORM:
524        case PIPE_FORMAT_L16A16_FLOAT:
525        case PIPE_FORMAT_R16A16_UNORM:
526        case PIPE_FORMAT_R16A16_SNORM:
527        case PIPE_FORMAT_R16A16_FLOAT:
528        case PIPE_FORMAT_A32_FLOAT:
529        case PIPE_FORMAT_L32_FLOAT:
530        case PIPE_FORMAT_I32_FLOAT:
531        case PIPE_FORMAT_R32_FLOAT:
532            return R300_COLOR_FORMAT_ARGB8888;
533
534        case PIPE_FORMAT_R10G10B10A2_UNORM:
535        case PIPE_FORMAT_R10G10B10X2_SNORM:
536        case PIPE_FORMAT_B10G10R10A2_UNORM:
537        case PIPE_FORMAT_B10G10R10X2_UNORM:
538            return R500_COLOR_FORMAT_ARGB2101010;  /* R5xx-only? */
539
540        /* 64-bit buffers. */
541        case PIPE_FORMAT_R16G16B16A16_UNORM:
542        case PIPE_FORMAT_R16G16B16A16_SNORM:
543        case PIPE_FORMAT_R16G16B16A16_FLOAT:
544        case PIPE_FORMAT_R16G16B16X16_UNORM:
545        case PIPE_FORMAT_R16G16B16X16_SNORM:
546        case PIPE_FORMAT_R16G16B16X16_FLOAT:
547        /* These formats work fine with ARGB16161616 if US_OUT_FMT is set
548         * correctly. */
549        case PIPE_FORMAT_R32G32_FLOAT:
550        case PIPE_FORMAT_L32A32_FLOAT:
551        case PIPE_FORMAT_R32A32_FLOAT:
552            return R300_COLOR_FORMAT_ARGB16161616;
553
554        /* 128-bit buffers. */
555        case PIPE_FORMAT_R32G32B32A32_FLOAT:
556        case PIPE_FORMAT_R32G32B32X32_FLOAT:
557            return R300_COLOR_FORMAT_ARGB32323232;
558
559        /* YUV buffers. */
560        case PIPE_FORMAT_UYVY:
561            return R300_COLOR_FORMAT_YVYU;
562        case PIPE_FORMAT_YUYV:
563            return R300_COLOR_FORMAT_VYUY;
564        default:
565            return ~0; /* Unsupported. */
566    }
567}
568
569/* Depthbuffer and stencilbuffer. Thankfully, we only support two flavors. */
570static uint32_t r300_translate_zsformat(enum pipe_format format)
571{
572    switch (format) {
573        /* 16-bit depth, no stencil */
574        case PIPE_FORMAT_Z16_UNORM:
575            return R300_DEPTHFORMAT_16BIT_INT_Z;
576        /* 24-bit depth, ignored stencil */
577        case PIPE_FORMAT_X8Z24_UNORM:
578        /* 24-bit depth, 8-bit stencil */
579        case PIPE_FORMAT_S8_UINT_Z24_UNORM:
580            return R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL;
581        default:
582            return ~0; /* Unsupported. */
583    }
584}
585
586/* Shader output formats. This is essentially the swizzle from the shader
587 * to the RB3D block.
588 *
589 * Note that formats are stored from C3 to C0. */
590static uint32_t r300_translate_out_fmt(enum pipe_format format)
591{
592    uint32_t modifier = 0;
593    unsigned i;
594    const struct util_format_description *desc;
595    boolean uniform_sign;
596
597    format = r300_unbyteswap_array_format(format);
598    desc = util_format_description(format);
599
600    /* Find the first non-VOID channel. */
601    for (i = 0; i < 4; i++) {
602        if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) {
603            break;
604        }
605    }
606
607    if (i == 4)
608        return ~0; /* Unsupported/unknown. */
609
610    /* Specifies how the shader output is written to the fog unit. */
611    switch (desc->channel[i].type) {
612    case UTIL_FORMAT_TYPE_FLOAT:
613        switch (desc->channel[i].size) {
614        case 32:
615            switch (desc->nr_channels) {
616            case 1:
617                modifier |= R300_US_OUT_FMT_C_32_FP;
618                break;
619            case 2:
620                modifier |= R300_US_OUT_FMT_C2_32_FP;
621                break;
622            case 4:
623                modifier |= R300_US_OUT_FMT_C4_32_FP;
624                break;
625            }
626            break;
627
628        case 16:
629            switch (desc->nr_channels) {
630            case 1:
631                modifier |= R300_US_OUT_FMT_C_16_FP;
632                break;
633            case 2:
634                modifier |= R300_US_OUT_FMT_C2_16_FP;
635                break;
636            case 4:
637                modifier |= R300_US_OUT_FMT_C4_16_FP;
638                break;
639            }
640            break;
641        }
642        break;
643
644    default:
645        switch (desc->channel[i].size) {
646        case 16:
647            switch (desc->nr_channels) {
648            case 1:
649                modifier |= R300_US_OUT_FMT_C_16;
650                break;
651            case 2:
652                modifier |= R300_US_OUT_FMT_C2_16;
653                break;
654            case 4:
655                modifier |= R300_US_OUT_FMT_C4_16;
656                break;
657            }
658            break;
659
660        case 10:
661            modifier |= R300_US_OUT_FMT_C4_10;
662            break;
663
664        default:
665            /* C4_8 seems to be used for the formats whose pixel size
666             * is <= 32 bits. */
667            modifier |= R300_US_OUT_FMT_C4_8;
668            break;
669        }
670    }
671
672    /* Add sign. */
673    uniform_sign = TRUE;
674    for (i = 0; i < desc->nr_channels; i++)
675        if (desc->channel[i].type != UTIL_FORMAT_TYPE_SIGNED)
676            uniform_sign = FALSE;
677
678    if (uniform_sign)
679        modifier |= R300_OUT_SIGN(0xf);
680
681    /* Add swizzles and return. */
682    switch (format) {
683        /*** Special cases (non-standard channel mapping) ***/
684
685        /* X8
686         * COLORFORMAT_I8 stores the Z component (C2). */
687        case PIPE_FORMAT_A8_UNORM:
688        case PIPE_FORMAT_A8_SNORM:
689            return modifier | R300_C2_SEL_A;
690        case PIPE_FORMAT_I8_UNORM:
691        case PIPE_FORMAT_I8_SNORM:
692        case PIPE_FORMAT_L8_UNORM:
693        case PIPE_FORMAT_L8_SNORM:
694        case PIPE_FORMAT_R8_UNORM:
695        case PIPE_FORMAT_R8_SNORM:
696            return modifier | R300_C2_SEL_R;
697
698        /* X8Y8
699         * COLORFORMAT_UV88 stores ZX (C2 and C0). */
700        case PIPE_FORMAT_L8A8_SNORM:
701        case PIPE_FORMAT_L8A8_UNORM:
702        case PIPE_FORMAT_R8A8_SNORM:
703        case PIPE_FORMAT_R8A8_UNORM:
704            return modifier | R300_C0_SEL_A | R300_C2_SEL_R;
705        case PIPE_FORMAT_R8G8_SNORM:
706        case PIPE_FORMAT_R8G8_UNORM:
707            return modifier | R300_C0_SEL_G | R300_C2_SEL_R;
708
709        /* X32Y32
710         * ARGB16161616 stores XZ for RG32F */
711        case PIPE_FORMAT_R32G32_FLOAT:
712            return modifier | R300_C0_SEL_R | R300_C2_SEL_G;
713
714        /*** Generic cases (standard channel mapping) ***/
715
716        /* BGRA outputs. */
717        case PIPE_FORMAT_B5G6R5_UNORM:
718        case PIPE_FORMAT_B5G5R5A1_UNORM:
719        case PIPE_FORMAT_B5G5R5X1_UNORM:
720        case PIPE_FORMAT_B4G4R4A4_UNORM:
721        case PIPE_FORMAT_B4G4R4X4_UNORM:
722        case PIPE_FORMAT_B8G8R8A8_UNORM:
723        /*case PIPE_FORMAT_B8G8R8A8_SNORM:*/
724        case PIPE_FORMAT_B8G8R8X8_UNORM:
725        /*case PIPE_FORMAT_B8G8R8X8_SNORM:*/
726        case PIPE_FORMAT_B10G10R10A2_UNORM:
727        case PIPE_FORMAT_B10G10R10X2_UNORM:
728            return modifier |
729                R300_C0_SEL_B | R300_C1_SEL_G |
730                R300_C2_SEL_R | R300_C3_SEL_A;
731
732        /* ARGB outputs. */
733        case PIPE_FORMAT_A16_UNORM:
734        case PIPE_FORMAT_A16_SNORM:
735        case PIPE_FORMAT_A16_FLOAT:
736        case PIPE_FORMAT_A32_FLOAT:
737            return modifier |
738                R300_C0_SEL_A | R300_C1_SEL_R |
739                R300_C2_SEL_G | R300_C3_SEL_B;
740
741        /* RGBA outputs. */
742        case PIPE_FORMAT_R8G8B8X8_UNORM:
743        case PIPE_FORMAT_R8G8B8X8_SNORM:
744        case PIPE_FORMAT_R8G8B8A8_UNORM:
745        case PIPE_FORMAT_R8G8B8A8_SNORM:
746        case PIPE_FORMAT_R10G10B10A2_UNORM:
747        case PIPE_FORMAT_R10G10B10X2_SNORM:
748        case PIPE_FORMAT_R16_UNORM:
749        case PIPE_FORMAT_R16G16_UNORM:
750        case PIPE_FORMAT_R16G16B16A16_UNORM:
751        case PIPE_FORMAT_R16_SNORM:
752        case PIPE_FORMAT_R16G16_SNORM:
753        case PIPE_FORMAT_R16G16B16A16_SNORM:
754        case PIPE_FORMAT_R16_FLOAT:
755        case PIPE_FORMAT_R16G16_FLOAT:
756        case PIPE_FORMAT_R16G16B16A16_FLOAT:
757        case PIPE_FORMAT_R32_FLOAT:
758        case PIPE_FORMAT_R32G32B32A32_FLOAT:
759        case PIPE_FORMAT_R32G32B32X32_FLOAT:
760        case PIPE_FORMAT_L16_UNORM:
761        case PIPE_FORMAT_L16_SNORM:
762        case PIPE_FORMAT_L16_FLOAT:
763        case PIPE_FORMAT_L32_FLOAT:
764        case PIPE_FORMAT_I16_UNORM:
765        case PIPE_FORMAT_I16_SNORM:
766        case PIPE_FORMAT_I16_FLOAT:
767        case PIPE_FORMAT_I32_FLOAT:
768        case PIPE_FORMAT_R16G16B16X16_UNORM:
769        case PIPE_FORMAT_R16G16B16X16_SNORM:
770        case PIPE_FORMAT_R16G16B16X16_FLOAT:
771            return modifier |
772                R300_C0_SEL_R | R300_C1_SEL_G |
773                R300_C2_SEL_B | R300_C3_SEL_A;
774
775        /* LA outputs. */
776        case PIPE_FORMAT_L16A16_UNORM:
777        case PIPE_FORMAT_L16A16_SNORM:
778        case PIPE_FORMAT_L16A16_FLOAT:
779        case PIPE_FORMAT_R16A16_UNORM:
780        case PIPE_FORMAT_R16A16_SNORM:
781        case PIPE_FORMAT_R16A16_FLOAT:
782        case PIPE_FORMAT_L32A32_FLOAT:
783        case PIPE_FORMAT_R32A32_FLOAT:
784            return modifier |
785                R300_C0_SEL_R | R300_C1_SEL_A;
786
787        default:
788            return ~0; /* Unsupported. */
789    }
790}
791
792static uint32_t r300_translate_colormask_swizzle(enum pipe_format format)
793{
794    format = r300_unbyteswap_array_format(format);
795
796    switch (format) {
797    case PIPE_FORMAT_A8_UNORM:
798    case PIPE_FORMAT_A8_SNORM:
799    case PIPE_FORMAT_A16_UNORM:
800    case PIPE_FORMAT_A16_SNORM:
801    case PIPE_FORMAT_A16_FLOAT:
802    case PIPE_FORMAT_A32_FLOAT:
803        return COLORMASK_AAAA;
804
805    case PIPE_FORMAT_I8_UNORM:
806    case PIPE_FORMAT_I8_SNORM:
807    case PIPE_FORMAT_L8_UNORM:
808    case PIPE_FORMAT_L8_SNORM:
809    case PIPE_FORMAT_R8_UNORM:
810    case PIPE_FORMAT_R8_SNORM:
811    case PIPE_FORMAT_R32_FLOAT:
812    case PIPE_FORMAT_L32_FLOAT:
813    case PIPE_FORMAT_I32_FLOAT:
814        return COLORMASK_RRRR;
815
816    case PIPE_FORMAT_L8A8_SNORM:
817    case PIPE_FORMAT_L8A8_UNORM:
818    case PIPE_FORMAT_R8A8_UNORM:
819    case PIPE_FORMAT_R8A8_SNORM:
820    case PIPE_FORMAT_L16A16_UNORM:
821    case PIPE_FORMAT_L16A16_SNORM:
822    case PIPE_FORMAT_L16A16_FLOAT:
823    case PIPE_FORMAT_R16A16_UNORM:
824    case PIPE_FORMAT_R16A16_SNORM:
825    case PIPE_FORMAT_R16A16_FLOAT:
826    case PIPE_FORMAT_L32A32_FLOAT:
827    case PIPE_FORMAT_R32A32_FLOAT:
828        return COLORMASK_ARRA;
829
830    case PIPE_FORMAT_R8G8_SNORM:
831    case PIPE_FORMAT_R8G8_UNORM:
832    case PIPE_FORMAT_R16G16_UNORM:
833    case PIPE_FORMAT_R16G16_SNORM:
834    case PIPE_FORMAT_R16G16_FLOAT:
835    case PIPE_FORMAT_R32G32_FLOAT:
836        return COLORMASK_GRRG;
837
838    case PIPE_FORMAT_B5G5R5X1_UNORM:
839    case PIPE_FORMAT_B4G4R4X4_UNORM:
840    case PIPE_FORMAT_B8G8R8X8_UNORM:
841    /*case PIPE_FORMAT_B8G8R8X8_SNORM:*/
842    case PIPE_FORMAT_B10G10R10X2_UNORM:
843        return COLORMASK_BGRX;
844
845    case PIPE_FORMAT_B5G6R5_UNORM:
846    case PIPE_FORMAT_B5G5R5A1_UNORM:
847    case PIPE_FORMAT_B4G4R4A4_UNORM:
848    case PIPE_FORMAT_B8G8R8A8_UNORM:
849    /*case PIPE_FORMAT_B8G8R8A8_SNORM:*/
850    case PIPE_FORMAT_B10G10R10A2_UNORM:
851        return COLORMASK_BGRA;
852
853    case PIPE_FORMAT_R8G8B8X8_UNORM:
854    /* RGBX_SNORM formats are broken for an unknown reason */
855    /*case PIPE_FORMAT_R8G8B8X8_SNORM:*/
856    /*case PIPE_FORMAT_R10G10B10X2_SNORM:*/
857    case PIPE_FORMAT_R16G16B16X16_UNORM:
858    /*case PIPE_FORMAT_R16G16B16X16_SNORM:*/
859    case PIPE_FORMAT_R16G16B16X16_FLOAT:
860    case PIPE_FORMAT_R32G32B32X32_FLOAT:
861        return COLORMASK_RGBX;
862
863    case PIPE_FORMAT_R8G8B8A8_UNORM:
864    case PIPE_FORMAT_R8G8B8A8_SNORM:
865    case PIPE_FORMAT_R10G10B10A2_UNORM:
866    case PIPE_FORMAT_R16_UNORM:
867    case PIPE_FORMAT_R16G16B16A16_UNORM:
868    case PIPE_FORMAT_R16_SNORM:
869    case PIPE_FORMAT_R16G16B16A16_SNORM:
870    case PIPE_FORMAT_R16_FLOAT:
871    case PIPE_FORMAT_R16G16B16A16_FLOAT:
872    case PIPE_FORMAT_R32G32B32A32_FLOAT:
873    case PIPE_FORMAT_L16_UNORM:
874    case PIPE_FORMAT_L16_SNORM:
875    case PIPE_FORMAT_L16_FLOAT:
876    case PIPE_FORMAT_I16_UNORM:
877    case PIPE_FORMAT_I16_SNORM:
878    case PIPE_FORMAT_I16_FLOAT:
879        return COLORMASK_RGBA;
880
881    default:
882        return ~0; /* Unsupported. */
883    }
884}
885
886boolean r300_is_colorbuffer_format_supported(enum pipe_format format)
887{
888    return r300_translate_colorformat(format) != ~0 &&
889           r300_translate_out_fmt(format) != ~0 &&
890           r300_translate_colormask_swizzle(format) != ~0;
891}
892
893boolean r300_is_zs_format_supported(enum pipe_format format)
894{
895    return r300_translate_zsformat(format) != ~0;
896}
897
898boolean r300_is_sampler_format_supported(enum pipe_format format)
899{
900    return r300_translate_texformat(format, 0, TRUE, FALSE) != ~0;
901}
902
903void r300_texture_setup_format_state(struct r300_screen *screen,
904                                     struct r300_resource *tex,
905                                     enum pipe_format format,
906                                     unsigned level,
907                                     unsigned width0_override,
908                                     unsigned height0_override,
909                                     struct r300_texture_format_state *out)
910{
911    struct pipe_resource *pt = &tex->b.b;
912    struct r300_texture_desc *desc = &tex->tex;
913    boolean is_r500 = screen->caps.is_r500;
914    unsigned width, height, depth;
915    unsigned txwidth, txheight, txdepth;
916
917    width = u_minify(width0_override, level);
918    height = u_minify(height0_override, level);
919    depth = u_minify(desc->depth0, level);
920
921    txwidth = (width - 1) & 0x7ff;
922    txheight = (height - 1) & 0x7ff;
923    txdepth = util_logbase2(depth) & 0xf;
924
925    /* Mask out all the fields we change. */
926    out->format0 = 0;
927    out->format1 &= ~R300_TX_FORMAT_TEX_COORD_TYPE_MASK;
928    out->format2 &= R500_TXFORMAT_MSB;
929    out->tile_config = 0;
930
931    /* Set sampler state. */
932    out->format0 =
933        R300_TX_WIDTH(txwidth) |
934        R300_TX_HEIGHT(txheight) |
935        R300_TX_DEPTH(txdepth);
936
937    if (desc->uses_stride_addressing) {
938        unsigned stride =
939            r300_stride_to_width(format, desc->stride_in_bytes[level]);
940        /* rectangles love this */
941        out->format0 |= R300_TX_PITCH_EN;
942        out->format2 = (stride - 1) & 0x1fff;
943    }
944
945    if (pt->target == PIPE_TEXTURE_CUBE) {
946        out->format1 |= R300_TX_FORMAT_CUBIC_MAP;
947    }
948    if (pt->target == PIPE_TEXTURE_3D) {
949        out->format1 |= R300_TX_FORMAT_3D;
950    }
951
952    /* large textures on r500 */
953    if (is_r500)
954    {
955        unsigned us_width = txwidth;
956        unsigned us_height = txheight;
957        unsigned us_depth = txdepth;
958
959        if (width > 2048) {
960            out->format2 |= R500_TXWIDTH_BIT11;
961        }
962        if (height > 2048) {
963            out->format2 |= R500_TXHEIGHT_BIT11;
964        }
965
966        /* The US_FORMAT register fixes an R500 TX addressing bug.
967         * Don't ask why it must be set like this. I don't know it either. */
968        if (width > 2048) {
969            us_width = (0x000007FF + us_width) >> 1;
970            us_depth |= 0x0000000D;
971        }
972        if (height > 2048) {
973            us_height = (0x000007FF + us_height) >> 1;
974            us_depth |= 0x0000000E;
975        }
976
977        out->us_format0 =
978            R300_TX_WIDTH(us_width) |
979            R300_TX_HEIGHT(us_height) |
980            R300_TX_DEPTH(us_depth);
981    }
982
983    out->tile_config = R300_TXO_MACRO_TILE(desc->macrotile[level]) |
984                       R300_TXO_MICRO_TILE(desc->microtile) |
985                       R300_TXO_ENDIAN(r300_get_endian_swap(format));
986}
987
988static void r300_texture_setup_fb_state(struct r300_surface *surf)
989{
990    struct r300_resource *tex = r300_resource(surf->base.texture);
991    unsigned level = surf->base.u.tex.level;
992    unsigned stride =
993      r300_stride_to_width(surf->base.format, tex->tex.stride_in_bytes[level]);
994
995    /* Set framebuffer state. */
996    if (util_format_is_depth_or_stencil(surf->base.format)) {
997        surf->pitch =
998                stride |
999                R300_DEPTHMACROTILE(tex->tex.macrotile[level]) |
1000                R300_DEPTHMICROTILE(tex->tex.microtile) |
1001                R300_DEPTHENDIAN(r300_get_endian_swap(surf->base.format));
1002        surf->format = r300_translate_zsformat(surf->base.format);
1003        surf->pitch_zmask = tex->tex.zmask_stride_in_pixels[level];
1004        surf->pitch_hiz = tex->tex.hiz_stride_in_pixels[level];
1005    } else {
1006        enum pipe_format format = util_format_linear(surf->base.format);
1007
1008        surf->pitch =
1009                stride |
1010                r300_translate_colorformat(format) |
1011                R300_COLOR_TILE(tex->tex.macrotile[level]) |
1012                R300_COLOR_MICROTILE(tex->tex.microtile) |
1013                R300_COLOR_ENDIAN(r300_get_endian_swap(format));
1014        surf->format = r300_translate_out_fmt(format);
1015        surf->colormask_swizzle =
1016            r300_translate_colormask_swizzle(format);
1017        surf->pitch_cmask = tex->tex.cmask_stride_in_pixels;
1018    }
1019}
1020
1021static void r300_texture_destroy(struct pipe_screen *screen,
1022                                 struct pipe_resource* texture)
1023{
1024    struct r300_screen *rscreen = r300_screen(screen);
1025    struct r300_resource* tex = (struct r300_resource*)texture;
1026
1027    if (tex->tex.cmask_dwords) {
1028        mtx_lock(&rscreen->cmask_mutex);
1029        if (texture == rscreen->cmask_resource) {
1030            rscreen->cmask_resource = NULL;
1031        }
1032        mtx_unlock(&rscreen->cmask_mutex);
1033    }
1034    pb_reference(&tex->buf, NULL);
1035    FREE(tex);
1036}
1037
1038boolean r300_resource_get_handle(struct pipe_screen* screen,
1039                                 struct pipe_context *ctx,
1040                                 struct pipe_resource *texture,
1041                                 struct winsys_handle *whandle,
1042                                 unsigned usage)
1043{
1044    struct radeon_winsys *rws = r300_screen(screen)->rws;
1045    struct r300_resource* tex = (struct r300_resource*)texture;
1046
1047    if (!tex) {
1048        return FALSE;
1049    }
1050
1051    return rws->buffer_get_handle(tex->buf, tex->tex.stride_in_bytes[0],
1052                                  0, 0, whandle);
1053}
1054
1055static const struct u_resource_vtbl r300_texture_vtbl =
1056{
1057    NULL,                           /* get_handle */
1058    r300_texture_destroy,           /* resource_destroy */
1059    r300_texture_transfer_map,      /* transfer_map */
1060    NULL,                           /* transfer_flush_region */
1061    r300_texture_transfer_unmap,    /* transfer_unmap */
1062};
1063
1064/* The common texture constructor. */
1065static struct r300_resource*
1066r300_texture_create_object(struct r300_screen *rscreen,
1067                           const struct pipe_resource *base,
1068                           enum radeon_bo_layout microtile,
1069                           enum radeon_bo_layout macrotile,
1070                           unsigned stride_in_bytes_override,
1071                           struct pb_buffer *buffer)
1072{
1073    struct radeon_winsys *rws = rscreen->rws;
1074    struct r300_resource *tex = NULL;
1075    struct radeon_bo_metadata tiling = {};
1076
1077    tex = CALLOC_STRUCT(r300_resource);
1078    if (!tex) {
1079        goto fail;
1080    }
1081
1082    pipe_reference_init(&tex->b.b.reference, 1);
1083    tex->b.b.screen = &rscreen->screen;
1084    tex->b.b.usage = base->usage;
1085    tex->b.b.bind = base->bind;
1086    tex->b.b.flags = base->flags;
1087    tex->b.vtbl = &r300_texture_vtbl;
1088    tex->tex.microtile = microtile;
1089    tex->tex.macrotile[0] = macrotile;
1090    tex->tex.stride_in_bytes_override = stride_in_bytes_override;
1091    tex->domain = (base->flags & R300_RESOURCE_FLAG_TRANSFER ||
1092                   base->usage == PIPE_USAGE_STAGING) ? RADEON_DOMAIN_GTT :
1093                  base->nr_samples > 1 ? RADEON_DOMAIN_VRAM :
1094                                         RADEON_DOMAIN_VRAM | RADEON_DOMAIN_GTT;
1095    tex->buf = buffer;
1096
1097    r300_texture_desc_init(rscreen, tex, base);
1098
1099    /* Figure out the ideal placement for the texture.. */
1100    if (tex->domain & RADEON_DOMAIN_VRAM &&
1101        tex->tex.size_in_bytes >= rscreen->info.vram_size) {
1102        tex->domain &= ~RADEON_DOMAIN_VRAM;
1103        tex->domain |= RADEON_DOMAIN_GTT;
1104    }
1105    if (tex->domain & RADEON_DOMAIN_GTT &&
1106        tex->tex.size_in_bytes >= rscreen->info.gart_size) {
1107        tex->domain &= ~RADEON_DOMAIN_GTT;
1108    }
1109    /* Just fail if the texture is too large. */
1110    if (!tex->domain) {
1111        goto fail;
1112    }
1113
1114    /* Create the backing buffer if needed. */
1115    if (!tex->buf) {
1116        /* Only use the first domain for allocation. Multiple domains are not allowed. */
1117        unsigned alloc_domain =
1118            tex->domain & RADEON_DOMAIN_VRAM ? RADEON_DOMAIN_VRAM :
1119                                               RADEON_DOMAIN_GTT;
1120
1121        tex->buf = rws->buffer_create(rws, tex->tex.size_in_bytes, 2048,
1122                                      alloc_domain,
1123                                      RADEON_FLAG_NO_SUBALLOC |
1124                                      /* Use the reusable pool: */
1125                                      RADEON_FLAG_NO_INTERPROCESS_SHARING);
1126
1127        if (!tex->buf) {
1128            goto fail;
1129        }
1130    }
1131
1132    if (SCREEN_DBG_ON(rscreen, DBG_MSAA) && base->nr_samples > 1) {
1133        fprintf(stderr, "r300: %ix MSAA %s buffer created\n",
1134                base->nr_samples,
1135                util_format_is_depth_or_stencil(base->format) ? "depth" : "color");
1136    }
1137
1138    tiling.u.legacy.microtile = tex->tex.microtile;
1139    tiling.u.legacy.macrotile = tex->tex.macrotile[0];
1140    tiling.u.legacy.stride = tex->tex.stride_in_bytes[0];
1141    rws->buffer_set_metadata(tex->buf, &tiling);
1142
1143    return tex;
1144
1145fail:
1146    FREE(tex);
1147    if (buffer)
1148        pb_reference(&buffer, NULL);
1149    return NULL;
1150}
1151
1152/* Create a new texture. */
1153struct pipe_resource *r300_texture_create(struct pipe_screen *screen,
1154                                          const struct pipe_resource *base)
1155{
1156    struct r300_screen *rscreen = r300_screen(screen);
1157    enum radeon_bo_layout microtile, macrotile;
1158
1159    if ((base->flags & R300_RESOURCE_FLAG_TRANSFER) ||
1160        (base->bind & (PIPE_BIND_SCANOUT | PIPE_BIND_LINEAR))) {
1161        microtile = RADEON_LAYOUT_LINEAR;
1162        macrotile = RADEON_LAYOUT_LINEAR;
1163    } else {
1164        /* This will make the texture_create_function select the layout. */
1165        microtile = RADEON_LAYOUT_UNKNOWN;
1166        macrotile = RADEON_LAYOUT_UNKNOWN;
1167    }
1168
1169    return (struct pipe_resource*)
1170           r300_texture_create_object(rscreen, base, microtile, macrotile,
1171                                      0, NULL);
1172}
1173
1174struct pipe_resource *r300_texture_from_handle(struct pipe_screen *screen,
1175                                               const struct pipe_resource *base,
1176                                               struct winsys_handle *whandle,
1177                                               unsigned usage)
1178{
1179    struct r300_screen *rscreen = r300_screen(screen);
1180    struct radeon_winsys *rws = rscreen->rws;
1181    struct pb_buffer *buffer;
1182    unsigned stride;
1183    struct radeon_bo_metadata tiling = {};
1184
1185    /* Support only 2D textures without mipmaps */
1186    if ((base->target != PIPE_TEXTURE_2D &&
1187          base->target != PIPE_TEXTURE_RECT) ||
1188        base->depth0 != 1 ||
1189        base->last_level != 0) {
1190        return NULL;
1191    }
1192
1193    buffer = rws->buffer_from_handle(rws, whandle, 0, &stride, NULL);
1194    if (!buffer)
1195        return NULL;
1196
1197    rws->buffer_get_metadata(buffer, &tiling);
1198
1199    /* Enforce a microtiled zbuffer. */
1200    if (util_format_is_depth_or_stencil(base->format) &&
1201        tiling.u.legacy.microtile == RADEON_LAYOUT_LINEAR) {
1202        switch (util_format_get_blocksize(base->format)) {
1203            case 4:
1204                tiling.u.legacy.microtile = RADEON_LAYOUT_TILED;
1205                break;
1206
1207            case 2:
1208                tiling.u.legacy.microtile = RADEON_LAYOUT_SQUARETILED;
1209                break;
1210        }
1211    }
1212
1213    return (struct pipe_resource*)
1214           r300_texture_create_object(rscreen, base, tiling.u.legacy.microtile, tiling.u.legacy.macrotile,
1215                                      stride, buffer);
1216}
1217
1218/* Not required to implement u_resource_vtbl, consider moving to another file:
1219 */
1220struct pipe_surface* r300_create_surface_custom(struct pipe_context * ctx,
1221                                         struct pipe_resource* texture,
1222                                         const struct pipe_surface *surf_tmpl,
1223                                         unsigned width0_override,
1224					 unsigned height0_override)
1225{
1226    struct r300_resource* tex = r300_resource(texture);
1227    struct r300_surface* surface = CALLOC_STRUCT(r300_surface);
1228    unsigned level = surf_tmpl->u.tex.level;
1229
1230    assert(surf_tmpl->u.tex.first_layer == surf_tmpl->u.tex.last_layer);
1231
1232    if (surface) {
1233        uint32_t offset, tile_height;
1234
1235        pipe_reference_init(&surface->base.reference, 1);
1236        pipe_resource_reference(&surface->base.texture, texture);
1237        surface->base.context = ctx;
1238        surface->base.format = surf_tmpl->format;
1239        surface->base.width = u_minify(width0_override, level);
1240        surface->base.height = u_minify(height0_override, level);
1241        surface->base.u.tex.level = level;
1242        surface->base.u.tex.first_layer = surf_tmpl->u.tex.first_layer;
1243        surface->base.u.tex.last_layer = surf_tmpl->u.tex.last_layer;
1244
1245        surface->buf = tex->buf;
1246
1247        /* Prefer VRAM if there are multiple domains to choose from. */
1248        surface->domain = tex->domain;
1249        if (surface->domain & RADEON_DOMAIN_VRAM)
1250            surface->domain &= ~RADEON_DOMAIN_GTT;
1251
1252        surface->offset = r300_texture_get_offset(tex, level,
1253                                                  surf_tmpl->u.tex.first_layer);
1254        r300_texture_setup_fb_state(surface);
1255
1256        /* Parameters for the CBZB clear. */
1257        surface->cbzb_allowed = tex->tex.cbzb_allowed[level];
1258        surface->cbzb_width = align(surface->base.width, 64);
1259
1260        /* Height must be aligned to the size of a tile. */
1261        tile_height = r300_get_pixel_alignment(surface->base.format,
1262                                               tex->b.b.nr_samples,
1263                                               tex->tex.microtile,
1264                                               tex->tex.macrotile[level],
1265                                               DIM_HEIGHT, 0);
1266
1267        surface->cbzb_height = align((surface->base.height + 1) / 2,
1268                                     tile_height);
1269
1270        /* Offset must be aligned to 2K and must point at the beginning
1271         * of a scanline. */
1272        offset = surface->offset +
1273                 tex->tex.stride_in_bytes[level] * surface->cbzb_height;
1274        surface->cbzb_midpoint_offset = offset & ~2047;
1275
1276        surface->cbzb_pitch = surface->pitch & 0x1ffffc;
1277
1278        if (util_format_get_blocksizebits(surface->base.format) == 32)
1279            surface->cbzb_format = R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL;
1280        else
1281            surface->cbzb_format = R300_DEPTHFORMAT_16BIT_INT_Z;
1282
1283        DBG(r300_context(ctx), DBG_CBZB,
1284            "CBZB Allowed: %s, Dim: %ix%i, Misalignment: %i, Micro: %s, Macro: %s\n",
1285            surface->cbzb_allowed ? "YES" : " NO",
1286            surface->cbzb_width, surface->cbzb_height,
1287            offset & 2047,
1288            tex->tex.microtile ? "YES" : " NO",
1289            tex->tex.macrotile[level] ? "YES" : " NO");
1290    }
1291
1292    return &surface->base;
1293}
1294
1295struct pipe_surface* r300_create_surface(struct pipe_context * ctx,
1296                                         struct pipe_resource* texture,
1297                                         const struct pipe_surface *surf_tmpl)
1298{
1299    return r300_create_surface_custom(ctx, texture, surf_tmpl,
1300                                      texture->width0,
1301                                      texture->height0);
1302}
1303
1304/* Not required to implement u_resource_vtbl, consider moving to another file:
1305 */
1306void r300_surface_destroy(struct pipe_context *ctx, struct pipe_surface* s)
1307{
1308    pipe_resource_reference(&s->texture, NULL);
1309    FREE(s);
1310}
1311