xref: /aosp_15_r20/external/mesa3d/src/gallium/drivers/freedreno/a2xx/fd2_util.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright © 2012 Rob Clark <[email protected]>
3  * SPDX-License-Identifier: MIT
4  *
5  * Authors:
6  *    Rob Clark <[email protected]>
7  */
8 
9 #include "pipe/p_defines.h"
10 #include "util/format/u_format.h"
11 
12 #include "fd2_util.h"
13 
14 static enum a2xx_sq_surfaceformat
pipe2surface(enum pipe_format format,struct surface_format * fmt)15 pipe2surface(enum pipe_format format, struct surface_format *fmt)
16 {
17    const struct util_format_description *desc = util_format_description(format);
18 
19    if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN) {
20       switch (format) {
21       /* Compressed textures. */
22       case PIPE_FORMAT_ETC1_RGB8:
23          return FMT_ETC1_RGB;
24       case PIPE_FORMAT_DXT1_RGB:
25       case PIPE_FORMAT_DXT1_RGBA:
26          return FMT_DXT1;
27       case PIPE_FORMAT_DXT3_RGBA:
28          return FMT_DXT2_3;
29       case PIPE_FORMAT_DXT5_RGBA:
30          return FMT_DXT4_5;
31       case PIPE_FORMAT_ATC_RGB:
32          return FMT_ATI_TC_555_565_RGB;
33       case PIPE_FORMAT_ATC_RGBA_EXPLICIT:
34          return FMT_ATI_TC_555_565_RGBA;
35       case PIPE_FORMAT_ATC_RGBA_INTERPOLATED:
36          return FMT_ATI_TC_555_565_RGBA_INTERP;
37       /* YUV buffers. */
38       case PIPE_FORMAT_UYVY:
39          return FMT_Y1_Cr_Y0_Cb;
40       case PIPE_FORMAT_YUYV:
41          return FMT_Cr_Y1_Cb_Y0;
42       default:
43          return ~0;
44       }
45    }
46 
47    uint32_t channel_size = 0;
48    for (unsigned i = 0; i < 4; i++)
49       channel_size |= desc->channel[i].size << i * 8;
50 
51    unsigned i = util_format_get_first_non_void_channel(format);
52    if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED ||
53        desc->channel[i].type == UTIL_FORMAT_TYPE_FIXED)
54       fmt->sign = SQ_TEX_SIGN_SIGNED;
55    if (!desc->channel[i].normalized)
56       fmt->num_format = SQ_TEX_NUM_FORMAT_INT;
57    if (desc->channel[i].type == UTIL_FORMAT_TYPE_FIXED)
58       fmt->exp_adjust = -16;
59 
60       /* Note: the 3 channel 24bpp/48bpp/96bpp formats are only for vertex fetch
61        * we can use the 4 channel format and ignore the 4th component just isn't
62        * used
63        * XXX: is it possible for the extra loaded component to cause a MMU fault?
64        */
65 
66 #define CASE(r, g, b, a) case (r | g << 8 | b << 16 | a << 24)
67 
68    /* clang-format off */
69    if (desc->channel[0].type == UTIL_FORMAT_TYPE_FLOAT) {
70       switch (channel_size) {
71       CASE(16,  0,  0,  0): return FMT_16_FLOAT;
72       CASE(16, 16,  0,  0): return FMT_16_16_FLOAT;
73       CASE(16, 16, 16,  0): return FMT_16_16_16_16_FLOAT; /* Note: only for vertex */
74       CASE(16, 16, 16, 16): return FMT_16_16_16_16_FLOAT;
75       CASE(32,  0,  0,  0): return FMT_32_FLOAT;
76       CASE(32, 32,  0,  0): return FMT_32_32_FLOAT;
77       CASE(32, 32, 32,  0): return FMT_32_32_32_FLOAT;
78       CASE(32, 32, 32, 32): return FMT_32_32_32_32_FLOAT;
79       }
80    } else {
81       switch (channel_size) {
82       CASE( 8,  0,  0,  0): return FMT_8;
83       CASE( 8,  8,  0,  0): return FMT_8_8;
84       CASE( 8,  8,  8,  0): return FMT_8_8_8_8; /* Note: only for vertex */
85       CASE( 8,  8,  8,  8): return FMT_8_8_8_8;
86       CASE(16,  0,  0,  0): return FMT_16;
87       CASE(16, 16,  0,  0): return FMT_16_16;
88       CASE(16, 16, 16,  0): return FMT_16_16_16_16; /* Note: only for vertex */
89       CASE(16, 16, 16, 16): return FMT_16_16_16_16;
90       CASE(32,  0,  0,  0): return FMT_32;
91       CASE(32, 32,  0,  0): return FMT_32_32;
92       CASE(32, 32, 32,  0): return FMT_32_32_32_32; /* Note: only for vertex */
93       CASE(32, 32, 32, 32): return FMT_32_32_32_32;
94       CASE( 4,  4,  4,  4): return FMT_4_4_4_4;
95       CASE( 5,  5,  5,  1): return FMT_1_5_5_5;
96       CASE( 5,  6,  5,  0): return FMT_5_6_5;
97       CASE(10, 10, 10,  2): return FMT_2_10_10_10;
98       CASE( 8, 24,  0,  0): return FMT_24_8;
99       CASE( 2,  3,  3,  0): return FMT_2_3_3; /* Note: R/B swapped */
100       }
101    }
102    /* clang-format on */
103 #undef CASE
104 
105    return ~0;
106 }
107 
108 struct surface_format
fd2_pipe2surface(enum pipe_format format)109 fd2_pipe2surface(enum pipe_format format)
110 {
111    struct surface_format fmt = {
112       .sign = SQ_TEX_SIGN_UNSIGNED,
113       .num_format = SQ_TEX_NUM_FORMAT_FRAC,
114       .exp_adjust = 0,
115    };
116    fmt.format = pipe2surface(format, &fmt);
117    return fmt;
118 }
119 
120 enum a2xx_colorformatx
fd2_pipe2color(enum pipe_format format)121 fd2_pipe2color(enum pipe_format format)
122 {
123    switch (format) {
124    /* 8-bit buffers. */
125    case PIPE_FORMAT_R8_UNORM:
126       return COLORX_8;
127    case PIPE_FORMAT_B2G3R3_UNORM:
128       return COLORX_2_3_3; /* note: untested */
129 
130    /* 16-bit buffers. */
131    case PIPE_FORMAT_B5G6R5_UNORM:
132       return COLORX_5_6_5;
133    case PIPE_FORMAT_B5G5R5A1_UNORM:
134    case PIPE_FORMAT_B5G5R5X1_UNORM:
135       return COLORX_1_5_5_5;
136    case PIPE_FORMAT_B4G4R4A4_UNORM:
137    case PIPE_FORMAT_B4G4R4X4_UNORM:
138       return COLORX_4_4_4_4;
139    case PIPE_FORMAT_R8G8_UNORM:
140       return COLORX_8_8;
141 
142    /* 32-bit buffers. */
143    case PIPE_FORMAT_B8G8R8A8_UNORM:
144    case PIPE_FORMAT_B8G8R8X8_UNORM:
145    case PIPE_FORMAT_R8G8B8A8_UNORM:
146    case PIPE_FORMAT_R8G8B8X8_UNORM:
147       return COLORX_8_8_8_8;
148    /* Note: snorm untested */
149    case PIPE_FORMAT_R8G8B8A8_SNORM:
150    case PIPE_FORMAT_R8G8B8X8_SNORM:
151       return COLORX_S8_8_8_8;
152 
153    /* float buffers */
154    case PIPE_FORMAT_R16_FLOAT:
155       return COLORX_16_FLOAT;
156    case PIPE_FORMAT_R16G16_FLOAT:
157       return COLORX_16_16_FLOAT;
158    case PIPE_FORMAT_R16G16B16A16_FLOAT:
159       return COLORX_16_16_16_16_FLOAT;
160    case PIPE_FORMAT_R32_FLOAT:
161       return COLORX_32_FLOAT;
162    case PIPE_FORMAT_R32G32_FLOAT:
163       return COLORX_32_32_FLOAT;
164    case PIPE_FORMAT_R32G32B32A32_FLOAT:
165       return COLORX_32_32_32_32_FLOAT;
166 
167    default:
168       return ~0;
169    }
170 }
171 
172 static inline enum sq_tex_swiz
tex_swiz(unsigned swiz)173 tex_swiz(unsigned swiz)
174 {
175    switch (swiz) {
176    default:
177    case PIPE_SWIZZLE_X:
178       return SQ_TEX_X;
179    case PIPE_SWIZZLE_Y:
180       return SQ_TEX_Y;
181    case PIPE_SWIZZLE_Z:
182       return SQ_TEX_Z;
183    case PIPE_SWIZZLE_W:
184       return SQ_TEX_W;
185    case PIPE_SWIZZLE_0:
186       return SQ_TEX_ZERO;
187    case PIPE_SWIZZLE_1:
188       return SQ_TEX_ONE;
189    }
190 }
191 
192 uint32_t
fd2_tex_swiz(enum pipe_format format,unsigned swizzle_r,unsigned swizzle_g,unsigned swizzle_b,unsigned swizzle_a)193 fd2_tex_swiz(enum pipe_format format, unsigned swizzle_r, unsigned swizzle_g,
194              unsigned swizzle_b, unsigned swizzle_a)
195 {
196    const struct util_format_description *desc = util_format_description(format);
197    unsigned char swiz[4] = {
198       swizzle_r,
199       swizzle_g,
200       swizzle_b,
201       swizzle_a,
202    }, rswiz[4];
203 
204    util_format_compose_swizzles(desc->swizzle, swiz, rswiz);
205 
206    return A2XX_SQ_TEX_3_SWIZ_X(tex_swiz(rswiz[0])) |
207           A2XX_SQ_TEX_3_SWIZ_Y(tex_swiz(rswiz[1])) |
208           A2XX_SQ_TEX_3_SWIZ_Z(tex_swiz(rswiz[2])) |
209           A2XX_SQ_TEX_3_SWIZ_W(tex_swiz(rswiz[3]));
210 }
211 
212 uint32_t
fd2_vtx_swiz(enum pipe_format format,unsigned swizzle)213 fd2_vtx_swiz(enum pipe_format format, unsigned swizzle)
214 {
215    const struct util_format_description *desc = util_format_description(format);
216    unsigned char swiz[4], rswiz[4];
217 
218    for (unsigned i = 0; i < 4; i++)
219       swiz[i] = (swizzle >> i * 3) & 7;
220 
221    util_format_compose_swizzles(desc->swizzle, swiz, rswiz);
222 
223    return rswiz[0] | rswiz[1] << 3 | rswiz[2] << 6 | rswiz[3] << 9;
224 }
225