2 * Copyright (C) 2019 Collabora, Ltd.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 * Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
28 #include "panfrost-job.h"
29 #include "pan_texture.h"
32 panfrost_translate_channel_width(unsigned size
)
36 return MALI_CHANNEL_4
;
38 return MALI_CHANNEL_8
;
40 return MALI_CHANNEL_16
;
42 return MALI_CHANNEL_32
;
44 unreachable("Invalid format width\n");
49 panfrost_translate_channel_type(unsigned type
, unsigned size
, bool norm
)
52 case UTIL_FORMAT_TYPE_UNSIGNED
:
53 return norm
? MALI_FORMAT_UNORM
: MALI_FORMAT_UINT
;
55 case UTIL_FORMAT_TYPE_SIGNED
:
56 return norm
? MALI_FORMAT_SNORM
: MALI_FORMAT_SINT
;
58 case UTIL_FORMAT_TYPE_FLOAT
:
59 /* fp16 -- SINT, fp32 -- UNORM ... gotta use those bits */
62 return MALI_FORMAT_SINT
;
64 return MALI_FORMAT_UNORM
;
66 unreachable("Invalid float size");
69 unreachable("Invalid type");
73 /* Constructs a mali_format satisfying the specified Gallium format
77 panfrost_find_format(const struct util_format_description
*desc
)
79 /* Find first non-VOID channel */
80 struct util_format_channel_description chan
= desc
->channel
[0];
82 for (unsigned c
= 0; c
< 4; ++c
)
84 if (desc
->channel
[c
].type
== UTIL_FORMAT_TYPE_VOID
)
87 chan
= desc
->channel
[c
];
91 /* Check for special formats */
94 case PIPE_FORMAT_NV12
:
97 case PIPE_FORMAT_R10G10B10X2_UNORM
:
98 case PIPE_FORMAT_B10G10R10X2_UNORM
:
99 case PIPE_FORMAT_R10G10B10A2_UNORM
:
100 case PIPE_FORMAT_B10G10R10A2_UNORM
:
101 return MALI_RGB10_A2_UNORM
;
103 case PIPE_FORMAT_R10G10B10X2_SNORM
:
104 case PIPE_FORMAT_R10G10B10A2_SNORM
:
105 case PIPE_FORMAT_B10G10R10A2_SNORM
:
106 return MALI_RGB10_A2_SNORM
;
108 case PIPE_FORMAT_R10G10B10A2_UINT
:
109 case PIPE_FORMAT_B10G10R10A2_UINT
:
110 case PIPE_FORMAT_R10G10B10A2_USCALED
:
111 case PIPE_FORMAT_B10G10R10A2_USCALED
:
112 return MALI_RGB10_A2UI
;
114 case PIPE_FORMAT_R10G10B10A2_SSCALED
:
115 case PIPE_FORMAT_B10G10R10A2_SSCALED
:
116 return MALI_RGB10_A2I
;
118 case PIPE_FORMAT_Z32_UNORM
:
119 case PIPE_FORMAT_Z24X8_UNORM
:
120 case PIPE_FORMAT_Z24_UNORM_S8_UINT
:
121 return MALI_Z32_UNORM
;
123 case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT
:
124 /* Z32F = R32F to the hardware */
127 case PIPE_FORMAT_B5G6R5_UNORM
:
130 case PIPE_FORMAT_B5G5R5X1_UNORM
:
131 return MALI_RGB5_X1_UNORM
;
133 case PIPE_FORMAT_B5G5R5A1_UNORM
:
134 return MALI_RGB5_A1_UNORM
;
136 case PIPE_FORMAT_A1B5G5R5_UNORM
:
137 case PIPE_FORMAT_X1B5G5R5_UNORM
:
138 /* Not supported - this is backwards from OpenGL! */
142 case PIPE_FORMAT_R32_FIXED
:
143 return MALI_R32_FIXED
;
144 case PIPE_FORMAT_R32G32_FIXED
:
145 return MALI_RG32_FIXED
;
146 case PIPE_FORMAT_R32G32B32_FIXED
:
147 return MALI_RGB32_FIXED
;
148 case PIPE_FORMAT_R32G32B32A32_FIXED
:
149 return MALI_RGBA32_FIXED
;
151 case PIPE_FORMAT_R11G11B10_FLOAT
:
152 return MALI_R11F_G11F_B10F
;
153 case PIPE_FORMAT_R9G9B9E5_FLOAT
:
154 return MALI_R9F_G9F_B9F_E5F
;
156 case PIPE_FORMAT_ETC1_RGB8
:
157 case PIPE_FORMAT_ETC2_RGB8
:
158 case PIPE_FORMAT_ETC2_SRGB8
:
159 return MALI_ETC2_RGB8
;
161 case PIPE_FORMAT_ETC2_RGB8A1
:
162 case PIPE_FORMAT_ETC2_SRGB8A1
:
163 return MALI_ETC2_RGB8A1
;
165 case PIPE_FORMAT_ETC2_RGBA8
:
166 case PIPE_FORMAT_ETC2_SRGBA8
:
167 return MALI_ETC2_RGBA8
;
169 case PIPE_FORMAT_ETC2_R11_UNORM
:
170 return MALI_ETC2_R11_UNORM
;
171 case PIPE_FORMAT_ETC2_R11_SNORM
:
172 return MALI_ETC2_R11_SNORM
;
174 case PIPE_FORMAT_ETC2_RG11_UNORM
:
175 return MALI_ETC2_RG11_UNORM
;
176 case PIPE_FORMAT_ETC2_RG11_SNORM
:
177 return MALI_ETC2_RG11_SNORM
;
180 /* Fallthrough to default */
184 if (desc
->layout
== UTIL_FORMAT_LAYOUT_ASTC
) {
185 if (desc
->colorspace
== UTIL_FORMAT_COLORSPACE_SRGB
)
186 return MALI_ASTC_SRGB_SUPP
;
188 return MALI_ASTC_HDR_SUPP
;
191 /* Formats must match in channel count */
192 assert(desc
->nr_channels
>= 1 && desc
->nr_channels
<= 4);
193 unsigned format
= MALI_NR_CHANNELS(desc
->nr_channels
);
197 case UTIL_FORMAT_TYPE_UNSIGNED
:
198 case UTIL_FORMAT_TYPE_SIGNED
:
199 case UTIL_FORMAT_TYPE_FIXED
:
201 format
|= panfrost_translate_channel_width(chan
.size
);
204 format
|= panfrost_translate_channel_type(chan
.type
, chan
.size
, chan
.normalized
);
207 case UTIL_FORMAT_TYPE_FLOAT
:
208 /* Float formats use a special width and encode width
211 format
|= MALI_CHANNEL_FLOAT
;
212 format
|= panfrost_translate_channel_type(chan
.type
, chan
.size
, chan
.normalized
);
216 fprintf(stderr
, "%s\n", util_format_name(desc
->format
));
217 unreachable("Invalid format type");
220 return (enum mali_format
) format
;
223 /* Is a format encoded like Z24S8 and therefore compatible for render? */
226 panfrost_is_z24s8_variant(enum pipe_format fmt
)
229 case PIPE_FORMAT_Z24_UNORM_S8_UINT
:
230 case PIPE_FORMAT_Z24X8_UNORM
:
237 /* Translate a PIPE swizzle quad to a 12-bit Mali swizzle code. PIPE
238 * swizzles line up with Mali swizzles for the XYZW01, but PIPE swizzles have
239 * an additional "NONE" field that we have to mask out to zero. Additionally,
240 * PIPE swizzles are sparse but Mali swizzles are packed */
243 panfrost_translate_swizzle_4(const unsigned char swizzle
[4])
247 for (unsigned i
= 0; i
< 4; ++i
) {
248 unsigned translated
= (swizzle
[i
] > PIPE_SWIZZLE_1
) ? PIPE_SWIZZLE_0
: swizzle
[i
];
249 out
|= (translated
<< (3*i
));
256 panfrost_invert_swizzle(const unsigned char *in
, unsigned char *out
)
258 /* First, default to all zeroes to prevent uninitialized junk */
260 for (unsigned c
= 0; c
< 4; ++c
)
261 out
[c
] = PIPE_SWIZZLE_0
;
263 /* Now "do" what the swizzle says */
265 for (unsigned c
= 0; c
< 4; ++c
) {
266 unsigned char i
= in
[c
];
269 assert(PIPE_SWIZZLE_X
== 0);
270 if (i
> PIPE_SWIZZLE_W
)
274 unsigned idx
= i
- PIPE_SWIZZLE_X
;
275 out
[idx
] = PIPE_SWIZZLE_X
+ c
;