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