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