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