xref: /aosp_15_r20/external/mesa3d/src/imagination/vulkan/pvr_formats.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright © 2022 Imagination Technologies Ltd.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to deal
6  * in the Software without restriction, including without limitation the rights
7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
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
13  * Software.
14  *
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 THE
18  * 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
21  * SOFTWARE.
22  */
23 
24 #include <assert.h>
25 #include <stdbool.h>
26 #include <stddef.h>
27 #include <stdint.h>
28 #include <vulkan/vulkan.h>
29 
30 #include "hwdef/rogue_hw_utils.h"
31 #include "pvr_common.h"
32 #include "pvr_formats.h"
33 #include "pvr_private.h"
34 #include "util/bitpack_helpers.h"
35 #include "util/compiler.h"
36 #include "util/format/format_utils.h"
37 #include "util/format/u_formats.h"
38 #include "util/half_float.h"
39 #include "util/log.h"
40 #include "util/macros.h"
41 #include "util/u_math.h"
42 #include "vk_enum_defines.h"
43 #include "vk_enum_to_str.h"
44 #include "vk_format.h"
45 #include "vk_log.h"
46 #include "vk_util.h"
47 
48 #define FORMAT(vk, tex_fmt, pack_mode, accum_format)           \
49    [VK_FORMAT_##vk] = {                                        \
50       .vk_format = VK_FORMAT_##vk,                             \
51       .tex_format = ROGUE_TEXSTATE_FORMAT_##tex_fmt,           \
52       .depth_tex_format = ROGUE_TEXSTATE_FORMAT_INVALID,       \
53       .stencil_tex_format = ROGUE_TEXSTATE_FORMAT_INVALID,     \
54       .pbe_packmode = ROGUE_PBESTATE_PACKMODE_##pack_mode,     \
55       .pbe_accum_format = PVR_PBE_ACCUM_FORMAT_##accum_format, \
56       .supported = true,                                       \
57    }
58 
59 #define FORMAT_COMPRESSED(vk, tex_fmt)                          \
60    [VK_FORMAT_##vk] = {                                         \
61       .vk_format = VK_FORMAT_##vk,                              \
62       .tex_format = ROGUE_TEXSTATE_FORMAT_COMPRESSED_##tex_fmt, \
63       .depth_tex_format = ROGUE_TEXSTATE_FORMAT_INVALID,        \
64       .stencil_tex_format = ROGUE_TEXSTATE_FORMAT_INVALID,      \
65       .pbe_packmode = ROGUE_PBESTATE_PACKMODE_INVALID,          \
66       .pbe_accum_format = PVR_PBE_ACCUM_FORMAT_INVALID,         \
67       .supported = true,                                        \
68    }
69 
70 #define FORMAT_DEPTH_STENCIL(vk, combined_fmt, d_fmt, s_fmt)  \
71    [VK_FORMAT_##vk] = {                                       \
72       .vk_format = VK_FORMAT_##vk,                            \
73       .tex_format = ROGUE_TEXSTATE_FORMAT_##combined_fmt,     \
74       .depth_tex_format = ROGUE_TEXSTATE_FORMAT_##d_fmt,      \
75       .stencil_tex_format = ROGUE_TEXSTATE_FORMAT_##s_fmt,    \
76       .pbe_packmode = ROGUE_PBESTATE_PACKMODE_##combined_fmt, \
77       .pbe_accum_format = PVR_PBE_ACCUM_FORMAT_INVALID,       \
78       .supported = true,                                      \
79    }
80 
81 struct pvr_format {
82    VkFormat vk_format;
83    uint32_t tex_format;
84    uint32_t depth_tex_format;
85    uint32_t stencil_tex_format;
86    uint32_t pbe_packmode;
87    enum pvr_pbe_accum_format pbe_accum_format;
88    bool supported;
89 };
90 
91 static const struct pvr_format pvr_format_table[] = {
92    /* VK_FORMAT_B4G4R4A4_UNORM_PACK16 = 3. */
93    FORMAT(B4G4R4A4_UNORM_PACK16, A4R4G4B4, A4R4G4B4, U8),
94    /* VK_FORMAT_R5G6B5_UNORM_PACK16 = 4. */
95    FORMAT(R5G6B5_UNORM_PACK16, R5G6B5, R5G6B5, U8),
96    /* VK_FORMAT_A1R5G5B5_UNORM_PACK16 = 8. */
97    FORMAT(A1R5G5B5_UNORM_PACK16, A1R5G5B5, A1R5G5B5, U8),
98    /* VK_FORMAT_R8_UNORM = 9. */
99    FORMAT(R8_UNORM, U8, U8, U8),
100    /* VK_FORMAT_R8_SNORM = 10. */
101    FORMAT(R8_SNORM, S8, S8, S8),
102    /* VK_FORMAT_R8_UINT = 13. */
103    FORMAT(R8_UINT, U8, U8, UINT8),
104    /* VK_FORMAT_R8_SINT = 14. */
105    FORMAT(R8_SINT, S8, S8, SINT8),
106    /* VK_FORMAT_R8G8_UNORM = 16. */
107    FORMAT(R8G8_UNORM, U8U8, U8U8, U8),
108    /* VK_FORMAT_R8G8_SNORM = 17. */
109    FORMAT(R8G8_SNORM, S8S8, S8S8, S8),
110    /* VK_FORMAT_R8G8_UINT = 20. */
111    FORMAT(R8G8_UINT, U8U8, U8U8, UINT8),
112    /* VK_FORMAT_R8G8_SINT = 21. */
113    FORMAT(R8G8_SINT, S8S8, S8S8, SINT8),
114    /* VK_FORMAT_R8G8B8A8_UNORM = 37. */
115    FORMAT(R8G8B8A8_UNORM, U8U8U8U8, U8U8U8U8, U8),
116    /* VK_FORMAT_R8G8B8A8_SNORM = 38. */
117    FORMAT(R8G8B8A8_SNORM, S8S8S8S8, S8S8S8S8, S8),
118    /* VK_FORMAT_R8G8B8A8_UINT = 41. */
119    FORMAT(R8G8B8A8_UINT, U8U8U8U8, U8U8U8U8, UINT8),
120    /* VK_FORMAT_R8G8B8A8_SINT = 42. */
121    FORMAT(R8G8B8A8_SINT, S8S8S8S8, S8S8S8S8, SINT8),
122    /* VK_FORMAT_R8G8B8A8_SRGB = 43. */
123    FORMAT(R8G8B8A8_SRGB, U8U8U8U8, U8U8U8U8, F16),
124    /* VK_FORMAT_B8G8R8A8_UNORM = 44. */
125    FORMAT(B8G8R8A8_UNORM, U8U8U8U8, U8U8U8U8, U8),
126    /* VK_FORMAT_B8G8R8A8_SRGB = 50. */
127    FORMAT(B8G8R8A8_SRGB, U8U8U8U8, U8U8U8U8, F16),
128    /* VK_FORMAT_A8B8G8R8_UNORM_PACK32 = 51. */
129    FORMAT(A8B8G8R8_UNORM_PACK32, U8U8U8U8, U8U8U8U8, U8),
130    /* VK_FORMAT_A8B8G8R8_SNORM_PACK32 = 52. */
131    FORMAT(A8B8G8R8_SNORM_PACK32, S8S8S8S8, S8S8S8S8, S8),
132    /* VK_FORMAT_A8B8G8R8_UINT_PACK32 = 55. */
133    FORMAT(A8B8G8R8_UINT_PACK32, U8U8U8U8, U8U8U8U8, UINT8),
134    /* VK_FORMAT_A8B8G8R8_SINT_PACK32 = 56. */
135    FORMAT(A8B8G8R8_SINT_PACK32, S8S8S8S8, S8S8S8S8, SINT8),
136    /* VK_FORMAT_A8B8G8R8_SRGB_PACK32 = 57. */
137    FORMAT(A8B8G8R8_SRGB_PACK32, U8U8U8U8, U8U8U8U8, F16),
138    /* VK_FORMAT_A2B10G10R10_UNORM_PACK32 = 64. */
139    FORMAT(A2B10G10R10_UNORM_PACK32, A2R10B10G10, A2R10B10G10, F16),
140    /* VK_FORMAT_A2B10G10R10_UINT_PACK32 = 68. */
141    FORMAT(A2B10G10R10_UINT_PACK32, A2R10B10G10, U32, UINT32),
142    /* VK_FORMAT_R16_UNORM = 70. */
143    FORMAT(R16_UNORM, U16, U16, U16),
144    /* VK_FORMAT_R16_SNORM = 71. */
145    FORMAT(R16_SNORM, S16, S16, S16),
146    /* VK_FORMAT_R16_UINT = 74. */
147    FORMAT(R16_UINT, U16, U16, UINT16),
148    /* VK_FORMAT_R16_SINT = 75. */
149    FORMAT(R16_SINT, S16, S16, SINT16),
150    /* VK_FORMAT_R16_SFLOAT = 76. */
151    FORMAT(R16_SFLOAT, F16, F16, F16),
152    /* VK_FORMAT_R16G16_UNORM = 77. */
153    FORMAT(R16G16_UNORM, U16U16, U16U16, U16),
154    /* VK_FORMAT_R16G16_SNORM = 78. */
155    FORMAT(R16G16_SNORM, S16S16, S16S16, S16),
156    /* VK_FORMAT_R16G16_UINT = 81. */
157    FORMAT(R16G16_UINT, U16U16, U16U16, UINT16),
158    /* VK_FORMAT_R16G16_SINT = 82. */
159    FORMAT(R16G16_SINT, S16S16, S16S16, SINT16),
160    /* VK_FORMAT_R16G16_SFLOAT = 83. */
161    FORMAT(R16G16_SFLOAT, F16F16, F16F16, F16),
162    /* VK_FORMAT_R16G16B16A16_UNORM = 91. */
163    FORMAT(R16G16B16A16_UNORM, U16U16U16U16, U16U16U16U16, U16),
164    /* VK_FORMAT_R16G16B16A16_SNORM = 92. */
165    FORMAT(R16G16B16A16_SNORM, S16S16S16S16, S16S16S16S16, S16),
166    /* VK_FORMAT_R16G16B16A16_UINT = 95. */
167    FORMAT(R16G16B16A16_UINT, U16U16U16U16, U16U16U16U16, UINT16),
168    /* VK_FORMAT_R16G16B16A16_SINT = 96 */
169    FORMAT(R16G16B16A16_SINT, S16S16S16S16, S16S16S16S16, SINT16),
170    /* VK_FORMAT_R16G16B16A16_SFLOAT = 97. */
171    FORMAT(R16G16B16A16_SFLOAT, F16F16F16F16, F16F16F16F16, F16),
172    /* VK_FORMAT_R32_UINT = 98. */
173    FORMAT(R32_UINT, U32, U32, UINT32),
174    /* VK_FORMAT_R32_SINT = 99. */
175    FORMAT(R32_SINT, S32, S32, SINT32),
176    /* VK_FORMAT_R32_SFLOAT = 100. */
177    FORMAT(R32_SFLOAT, F32, F32, F32),
178    /* VK_FORMAT_R32G32_UINT = 101. */
179    FORMAT(R32G32_UINT, U32U32, U32U32, UINT32),
180    /* VK_FORMAT_R32G32_SINT = 102. */
181    FORMAT(R32G32_SINT, S32S32, S32S32, SINT32),
182    /* VK_FORMAT_R32G32_SFLOAT = 103. */
183    FORMAT(R32G32_SFLOAT, F32F32, F32F32, F32),
184    /* VK_FORMAT_R32G32B32_UINT = 104. */
185    FORMAT(R32G32B32_UINT, U32U32U32, U32U32U32, UINT32),
186    /* VK_FORMAT_R32G32B32_SINT = 105. */
187    FORMAT(R32G32B32_SINT, S32S32S32, S32S32S32, SINT32),
188    /* VK_FORMAT_R32G32B32_SFLOAT = 106. */
189    FORMAT(R32G32B32_SFLOAT, F32F32F32, F32F32F32, F32),
190    /* VK_FORMAT_R32G32B32A32_UINT = 107. */
191    FORMAT(R32G32B32A32_UINT, U32U32U32U32, U32U32U32U32, UINT32),
192    /* VK_FORMAT_R32G32B32A32_SINT = 108. */
193    FORMAT(R32G32B32A32_SINT, S32S32S32S32, S32S32S32S32, SINT32),
194    /* VK_FORMAT_R32G32B32A32_SFLOAT = 109. */
195    FORMAT(R32G32B32A32_SFLOAT, F32F32F32F32, F32F32F32F32, F32),
196    /* VK_FORMAT_B10G11R11_UFLOAT_PACK32 = 122. */
197    FORMAT(B10G11R11_UFLOAT_PACK32, F10F11F11, F10F11F11, F16),
198    /* VK_FORMAT_E5B9G9R9_UFLOAT_PACK32 = 123. */
199    FORMAT(E5B9G9R9_UFLOAT_PACK32, SE9995, SE9995, INVALID),
200    /* VK_FORMAT_D16_UNORM = 124. */
201    FORMAT_DEPTH_STENCIL(D16_UNORM, U16, U16, INVALID),
202    /* VK_FORMAT_D32_SFLOAT = 126. */
203    FORMAT_DEPTH_STENCIL(D32_SFLOAT, F32, F32, INVALID),
204    /* VK_FORMAT_S8_UINT = 127. */
205    FORMAT_DEPTH_STENCIL(S8_UINT, U8, INVALID, U8),
206    /* VK_FORMAT_D24_UNORM_S8_UINT = 129. */
207    FORMAT_DEPTH_STENCIL(D24_UNORM_S8_UINT, ST8U24, X8U24, U8X24),
208    /* VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK = 147. */
209    FORMAT_COMPRESSED(ETC2_R8G8B8_UNORM_BLOCK, ETC2_RGB),
210    /* VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK = 148. */
211    FORMAT_COMPRESSED(ETC2_R8G8B8_SRGB_BLOCK, ETC2_RGB),
212    /* VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK = 149. */
213    FORMAT_COMPRESSED(ETC2_R8G8B8A1_UNORM_BLOCK, ETC2_PUNCHTHROUGHA),
214    /* VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK = 150. */
215    FORMAT_COMPRESSED(ETC2_R8G8B8A1_SRGB_BLOCK, ETC2_PUNCHTHROUGHA),
216    /* VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK = 150. */
217    FORMAT_COMPRESSED(ETC2_R8G8B8A8_UNORM_BLOCK, ETC2A_RGBA),
218    /* VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK = 152. */
219    FORMAT_COMPRESSED(ETC2_R8G8B8A8_SRGB_BLOCK, ETC2A_RGBA),
220    /* VK_FORMAT_EAC_R11_UNORM_BLOCK = 153. */
221    FORMAT_COMPRESSED(EAC_R11_UNORM_BLOCK, EAC_R11_UNSIGNED),
222    /* VK_FORMAT_EAC_R11_SNORM_BLOCK = 154. */
223    FORMAT_COMPRESSED(EAC_R11_SNORM_BLOCK, EAC_R11_SIGNED),
224    /* VK_FORMAT_EAC_R11G11_UNORM_BLOCK = 155. */
225    FORMAT_COMPRESSED(EAC_R11G11_UNORM_BLOCK, EAC_RG11_UNSIGNED),
226    /* VK_FORMAT_EAC_R11G11_SNORM_BLOCK = 156. */
227    FORMAT_COMPRESSED(EAC_R11G11_SNORM_BLOCK, EAC_RG11_SIGNED),
228 };
229 
230 #undef FORMAT
231 #undef FORMAT_DEPTH_STENCIL
232 #undef FORMAT_COMPRESSED
233 
234 #define FORMAT(tex_fmt, pipe_fmt_int, pipe_fmt_float) \
235    [PVRX(TEXSTATE_FORMAT_##tex_fmt)] = {                    \
236       .desc = {                                             \
237          .tex_format = PVRX(TEXSTATE_FORMAT_##tex_fmt),     \
238          .pipe_format_int = PIPE_FORMAT_##pipe_fmt_int,     \
239          .pipe_format_float = PIPE_FORMAT_##pipe_fmt_float, \
240       },                                                    \
241       .present = true,                                      \
242    }
243 
244 static const struct pvr_tex_format_table_entry {
245    struct pvr_tex_format_description desc;
246    bool present;
247 } pvr_tex_format_table[PVR_TEX_FORMAT_COUNT] = {
248    /*   0 */ FORMAT(U8, R8_UINT, R8_UNORM),
249    /*   1 */ FORMAT(S8, R8_SINT, R8_SNORM),
250    /*   2 */ FORMAT(A4R4G4B4, NONE, A4R4G4B4_UNORM),
251    /*   4 */ FORMAT(A1R5G5B5, NONE, B5G5R5A1_UNORM),
252    /*   5 */ FORMAT(R5G6B5, NONE, B5G6R5_UNORM),
253    /*   7 */ FORMAT(U8U8, R8G8_UINT, R8G8_UNORM),
254    /*   8 */ FORMAT(S8S8, R8G8_SINT, R8G8_SNORM),
255    /*   9 */ FORMAT(U16, R16_UINT, R16_UNORM),
256    /*  10 */ FORMAT(S16, R16_SINT, R16_SNORM),
257    /*  11 */ FORMAT(F16, NONE, R16_FLOAT),
258    /*  12 */ FORMAT(U8U8U8U8, R8G8B8A8_UINT, R8G8B8A8_UNORM),
259    /*  13 */ FORMAT(S8S8S8S8, R8G8B8A8_SINT, R8G8B8A8_SNORM),
260    /*  14 */ FORMAT(A2R10B10G10, R10G10B10A2_UINT, R10G10B10A2_UNORM),
261    /*  15 */ FORMAT(U16U16, R16G16_UINT, R16G16_UNORM),
262    /*  16 */ FORMAT(S16S16, R16G16_SINT, R16G16_SNORM),
263    /*  17 */ FORMAT(F16F16, NONE, R16G16_FLOAT),
264    /*  18 */ FORMAT(F32, NONE, R32_FLOAT),
265    /*  22 */ FORMAT(ST8U24, Z24_UNORM_S8_UINT, Z24_UNORM_S8_UINT),
266    /*  24 */ FORMAT(U32, R32_UINT, NONE),
267    /*  25 */ FORMAT(S32, R32_SINT, NONE),
268    /*  26 */ FORMAT(SE9995, NONE, R9G9B9E5_FLOAT),
269    /*  28 */ FORMAT(F16F16F16F16, NONE, R16G16B16A16_FLOAT),
270    /*  29 */ FORMAT(U16U16U16U16, R16G16B16A16_UINT, R16G16B16A16_UNORM),
271    /*  30 */ FORMAT(S16S16S16S16, R16G16B16A16_SINT, R16G16B16A16_SNORM),
272    /*  34 */ FORMAT(F32F32, NONE, R32G32_FLOAT),
273    /*  35 */ FORMAT(U32U32, R32G32_UINT, NONE),
274    /*  36 */ FORMAT(S32S32, R32G32_SINT, NONE),
275    /*  61 */ FORMAT(F32F32F32F32, NONE, R32G32B32A32_FLOAT),
276    /*  62 */ FORMAT(U32U32U32U32, R32G32B32A32_UINT, NONE),
277    /*  63 */ FORMAT(S32S32S32S32, R32G32B32A32_SINT, NONE),
278    /*  64 */ FORMAT(F32F32F32, NONE, R32G32B32_FLOAT),
279    /*  65 */ FORMAT(U32U32U32, R32G32B32_UINT, NONE),
280    /*  66 */ FORMAT(S32S32S32, R32G32B32_SINT, NONE),
281    /*  88 */ FORMAT(F10F11F11, NONE, R11G11B10_FLOAT),
282 };
283 
284 #undef FORMAT
285 
286 #define FORMAT(tex_fmt, pipe_fmt, tex_fmt_simple) \
287    [PVRX(TEXSTATE_FORMAT_COMPRESSED_##tex_fmt)] = {                   \
288       .desc = {                                                       \
289          .tex_format = PVRX(TEXSTATE_FORMAT_COMPRESSED_##tex_fmt),    \
290          .pipe_format = PIPE_FORMAT_##pipe_fmt,                       \
291          .tex_format_simple = PVRX(TEXSTATE_FORMAT_##tex_fmt_simple), \
292       },                                                              \
293       .present = true,                                                \
294    }
295 
296 static const struct pvr_tex_format_compressed_table_entry {
297    struct pvr_tex_format_compressed_description desc;
298    bool present;
299 } pvr_tex_format_compressed_table[PVR_TEX_FORMAT_COUNT] = {
300    /*  68 */ FORMAT(ETC2_RGB, ETC2_RGB8, U8U8U8U8),
301    /*  69 */ FORMAT(ETC2A_RGBA, ETC2_RGBA8, U8U8U8U8),
302    /*  70 */ FORMAT(ETC2_PUNCHTHROUGHA, ETC2_RGB8A1, U8U8U8U8),
303    /*  71 */ FORMAT(EAC_R11_UNSIGNED, ETC2_R11_UNORM, U16U16U16U16),
304    /*  72 */ FORMAT(EAC_R11_SIGNED, ETC2_R11_SNORM, S16S16S16S16),
305    /*  73 */ FORMAT(EAC_RG11_UNSIGNED, ETC2_RG11_UNORM, U16U16U16U16),
306    /*  74 */ FORMAT(EAC_RG11_SIGNED, ETC2_RG11_SNORM, S16S16S16S16),
307 };
308 
309 #undef FORMAT
310 
pvr_get_format(VkFormat vk_format)311 static inline const struct pvr_format *pvr_get_format(VkFormat vk_format)
312 {
313    if (vk_format < ARRAY_SIZE(pvr_format_table) &&
314        pvr_format_table[vk_format].supported) {
315       return &pvr_format_table[vk_format];
316    }
317 
318    mesa_logd("Format %s(%d) not supported\n",
319              vk_Format_to_str(vk_format),
320              vk_format);
321 
322    return NULL;
323 }
324 
pvr_tex_format_is_supported(const uint32_t tex_format)325 bool pvr_tex_format_is_supported(const uint32_t tex_format)
326 {
327    return tex_format < ARRAY_SIZE(pvr_tex_format_table) &&
328           pvr_tex_format_table[tex_format].present;
329 }
330 
331 const struct pvr_tex_format_description *
pvr_get_tex_format_description(const uint32_t tex_format)332 pvr_get_tex_format_description(const uint32_t tex_format)
333 {
334    if (pvr_tex_format_is_supported(tex_format))
335       return &pvr_tex_format_table[tex_format].desc;
336 
337    mesa_logd("Tex format %s (%d) not supported\n",
338              PVRX(TEXSTATE_FORMAT_to_str)(tex_format),
339              tex_format);
340 
341    return NULL;
342 }
343 
pvr_tex_format_compressed_is_supported(uint32_t tex_format)344 bool pvr_tex_format_compressed_is_supported(uint32_t tex_format)
345 {
346    /* In some contexts, the sequence of compressed tex format ids are appended
347     * to the normal tex format ids; in that case, we need to remove that offset
348     * before lookup.
349     */
350    if (tex_format >= PVR_TEX_FORMAT_COUNT)
351       tex_format -= PVR_TEX_FORMAT_COUNT;
352 
353    return tex_format < ARRAY_SIZE(pvr_tex_format_compressed_table) &&
354           pvr_tex_format_compressed_table[tex_format].present;
355 }
356 
357 const struct pvr_tex_format_compressed_description *
pvr_get_tex_format_compressed_description(uint32_t tex_format)358 pvr_get_tex_format_compressed_description(uint32_t tex_format)
359 {
360    /* In some contexts, the sequence of compressed tex format ids are appended
361     * to the normal tex format ids; in that case, we need to remove that offset
362     * before lookup.
363     */
364    if (tex_format >= PVR_TEX_FORMAT_COUNT)
365       tex_format -= PVR_TEX_FORMAT_COUNT;
366 
367    if (pvr_tex_format_compressed_is_supported(tex_format))
368       return &pvr_tex_format_compressed_table[tex_format].desc;
369 
370    mesa_logd("Compressed tex format %s (%d) not supported\n",
371              PVRX(TEXSTATE_FORMAT_COMPRESSED_to_str)(tex_format),
372              tex_format);
373 
374    return NULL;
375 }
376 
pvr_get_tex_format(VkFormat vk_format)377 uint32_t pvr_get_tex_format(VkFormat vk_format)
378 {
379    const struct pvr_format *pvr_format = pvr_get_format(vk_format);
380    if (pvr_format) {
381       return pvr_format->tex_format;
382    }
383 
384    return ROGUE_TEXSTATE_FORMAT_INVALID;
385 }
386 
pvr_get_tex_format_aspect(VkFormat vk_format,VkImageAspectFlags aspect_mask)387 uint32_t pvr_get_tex_format_aspect(VkFormat vk_format,
388                                    VkImageAspectFlags aspect_mask)
389 {
390    const struct pvr_format *pvr_format = pvr_get_format(vk_format);
391    if (pvr_format) {
392       if (aspect_mask == VK_IMAGE_ASPECT_DEPTH_BIT)
393          return pvr_format->depth_tex_format;
394       else if (aspect_mask == VK_IMAGE_ASPECT_STENCIL_BIT)
395          return pvr_format->stencil_tex_format;
396 
397       return pvr_format->tex_format;
398    }
399 
400    return PVRX(TEXSTATE_FORMAT_INVALID);
401 }
402 
pvr_get_pbe_packmode(VkFormat vk_format)403 uint32_t pvr_get_pbe_packmode(VkFormat vk_format)
404 {
405    const struct pvr_format *pvr_format = pvr_get_format(vk_format);
406    if (pvr_format)
407       return pvr_format->pbe_packmode;
408 
409    return ROGUE_PBESTATE_PACKMODE_INVALID;
410 }
411 
pvr_get_pbe_accum_format(VkFormat vk_format)412 uint32_t pvr_get_pbe_accum_format(VkFormat vk_format)
413 {
414    const struct pvr_format *pvr_format = pvr_get_format(vk_format);
415    if (pvr_format)
416       return pvr_format->pbe_accum_format;
417 
418    return PVR_PBE_ACCUM_FORMAT_INVALID;
419 }
420 
pvr_get_pbe_accum_format_size_in_bytes(VkFormat vk_format)421 uint32_t pvr_get_pbe_accum_format_size_in_bytes(VkFormat vk_format)
422 {
423    enum pvr_pbe_accum_format pbe_accum_format;
424    uint32_t nr_components;
425 
426    /* FIXME: Can we encode this in the format table somehow? */
427    if (vk_format == VK_FORMAT_A2B10G10R10_UINT_PACK32)
428       return 4;
429 
430    pbe_accum_format = pvr_get_pbe_accum_format(vk_format);
431    nr_components = vk_format_get_nr_components(vk_format);
432 
433    switch (pbe_accum_format) {
434    case PVR_PBE_ACCUM_FORMAT_U8:
435    case PVR_PBE_ACCUM_FORMAT_S8:
436    case PVR_PBE_ACCUM_FORMAT_UINT8:
437    case PVR_PBE_ACCUM_FORMAT_SINT8:
438       return nr_components * 1;
439 
440    case PVR_PBE_ACCUM_FORMAT_U16:
441    case PVR_PBE_ACCUM_FORMAT_S16:
442    case PVR_PBE_ACCUM_FORMAT_F16:
443    case PVR_PBE_ACCUM_FORMAT_UINT16:
444    case PVR_PBE_ACCUM_FORMAT_SINT16:
445       return nr_components * 2;
446 
447    case PVR_PBE_ACCUM_FORMAT_F32:
448    case PVR_PBE_ACCUM_FORMAT_UINT32:
449    case PVR_PBE_ACCUM_FORMAT_SINT32:
450    case PVR_PBE_ACCUM_FORMAT_UINT32_MEDP:
451    case PVR_PBE_ACCUM_FORMAT_SINT32_MEDP:
452    case PVR_PBE_ACCUM_FORMAT_U1010102:
453    case PVR_PBE_ACCUM_FORMAT_U24:
454       return nr_components * 4;
455 
456    default:
457       unreachable("Unknown pbe accum format. Implementation error");
458    }
459 }
460 
461 /**
462  * \brief Packs VK_FORMAT_A2B10G10R10_UINT_PACK32 or A2R10G10B10.
463  *
464  * \param[in] values   RGBA ordered values to pack.
465  * \param[in] swap_rb  If true pack A2B10G10R10 else pack A2R10G10B10.
466  */
pvr_pack_a2x10y10z10_uint(const uint32_t values[static const PVR_CLEAR_COLOR_ARRAY_SIZE],bool swap_rb)467 static inline uint32_t pvr_pack_a2x10y10z10_uint(
468    const uint32_t values[static const PVR_CLEAR_COLOR_ARRAY_SIZE],
469    bool swap_rb)
470 {
471    const uint32_t blue = swap_rb ? values[0] : values[2];
472    const uint32_t red = swap_rb ? values[2] : values[0];
473    uint32_t packed_val;
474 
475    /* The user is allowed to specify a value which is over the range
476     * representable for a component so we need to AND before packing.
477     */
478 
479    packed_val = util_bitpack_uint(values[3] & BITSET_MASK(2), 30, 31);
480    packed_val |= util_bitpack_uint(red & BITSET_MASK(10), 20, 29);
481    packed_val |= util_bitpack_uint(values[1] & BITSET_MASK(10), 10, 19);
482    packed_val |= util_bitpack_uint(blue & BITSET_MASK(10), 0, 9);
483 
484    return packed_val;
485 }
486 
487 #define APPLY_FUNC_4V(DST, FUNC, ARG) \
488    ASSIGN_4V(DST, FUNC(ARG[0]), FUNC(ARG[1]), FUNC(ARG[2]), FUNC(ARG[3]))
489 
490 #define f32_to_unorm8(val) _mesa_float_to_unorm(val, 8)
491 #define f32_to_unorm16(val) _mesa_float_to_unorm(val, 16)
492 #define f32_to_snorm8(val) _mesa_float_to_snorm(val, 8)
493 #define f32_to_snorm16(val) _mesa_float_to_snorm(val, 16)
494 #define f32_to_f16(val) _mesa_float_to_half(val)
495 
496 /**
497  * \brief Packs clear color input values into the appropriate accum format.
498  *
499  * The input value array must have zeroed out elements for components not
500  * present in the format. E.g. R8G8B8 has no A component so [3] must be 0.
501  *
502  * Note: the output is not swizzled so it's packed in RGBA order no matter the
503  * component order specified by the vk_format.
504  *
505  * \param[in] vk_format   Vulkan format of the input color value.
506  * \param[in] value       Unpacked RGBA input color values.
507  * \param[out] packed_out Accum format packed values.
508  */
pvr_get_hw_clear_color(VkFormat vk_format,VkClearColorValue value,uint32_t packed_out[static const PVR_CLEAR_COLOR_ARRAY_SIZE])509 void pvr_get_hw_clear_color(
510    VkFormat vk_format,
511    VkClearColorValue value,
512    uint32_t packed_out[static const PVR_CLEAR_COLOR_ARRAY_SIZE])
513 {
514    union {
515       uint32_t u32[PVR_CLEAR_COLOR_ARRAY_SIZE];
516       int32_t i32[PVR_CLEAR_COLOR_ARRAY_SIZE];
517       uint16_t u16[PVR_CLEAR_COLOR_ARRAY_SIZE * 2];
518       int16_t i16[PVR_CLEAR_COLOR_ARRAY_SIZE * 2];
519       uint8_t u8[PVR_CLEAR_COLOR_ARRAY_SIZE * 4];
520       int8_t i8[PVR_CLEAR_COLOR_ARRAY_SIZE * 4];
521    } packed_val = { 0 };
522 
523    const enum pvr_pbe_accum_format pbe_accum_format =
524       pvr_get_pbe_accum_format(vk_format);
525 
526    static_assert(ARRAY_SIZE(value.uint32) == PVR_CLEAR_COLOR_ARRAY_SIZE,
527                  "Size mismatch. Unknown/unhandled extra values.");
528 
529    /* TODO: Right now we pack all RGBA values. Would we get any benefit in
530     * packing just the components required by the format?
531     */
532 
533    switch (pbe_accum_format) {
534    case PVR_PBE_ACCUM_FORMAT_U8:
535       APPLY_FUNC_4V(packed_val.u8, f32_to_unorm8, value.float32);
536       break;
537    case PVR_PBE_ACCUM_FORMAT_S8:
538       APPLY_FUNC_4V(packed_val.i8, f32_to_snorm8, value.float32);
539       break;
540    case PVR_PBE_ACCUM_FORMAT_UINT8:
541       COPY_4V(packed_val.u8, value.uint32);
542       break;
543    case PVR_PBE_ACCUM_FORMAT_SINT8:
544       COPY_4V(packed_val.i8, value.int32);
545       break;
546 
547    case PVR_PBE_ACCUM_FORMAT_U16:
548       APPLY_FUNC_4V(packed_val.u16, f32_to_unorm16, value.float32);
549       break;
550    case PVR_PBE_ACCUM_FORMAT_S16:
551       APPLY_FUNC_4V(packed_val.i16, f32_to_snorm16, value.float32);
552       break;
553    case PVR_PBE_ACCUM_FORMAT_F16:
554       APPLY_FUNC_4V(packed_val.u16, f32_to_f16, value.float32);
555       break;
556    case PVR_PBE_ACCUM_FORMAT_UINT16:
557       COPY_4V(packed_val.u16, value.uint32);
558       break;
559    case PVR_PBE_ACCUM_FORMAT_SINT16:
560       COPY_4V(packed_val.i16, value.int32);
561       break;
562 
563    case PVR_PBE_ACCUM_FORMAT_F32:
564       COPY_4V(packed_val.u32, value.uint32);
565       break;
566    case PVR_PBE_ACCUM_FORMAT_UINT32:
567       /* The PBE can't pack 1010102 UINT. */
568       if (vk_format == VK_FORMAT_A2B10G10R10_UINT_PACK32) {
569          packed_val.u32[0] = pvr_pack_a2x10y10z10_uint(value.uint32, true);
570          break;
571       } else if (vk_format == VK_FORMAT_A2R10G10B10_UINT_PACK32) {
572          packed_val.u32[0] = pvr_pack_a2x10y10z10_uint(value.uint32, false);
573          break;
574       }
575       COPY_4V(packed_val.u32, value.uint32);
576       break;
577    case PVR_PBE_ACCUM_FORMAT_SINT32:
578       COPY_4V(packed_val.i32, value.int32);
579       break;
580 
581    default:
582       unreachable("Packing not supported for the accum format.");
583       break;
584    }
585 
586    COPY_4V(packed_out, packed_val.u32);
587 }
588 
589 #undef APPLY_FUNC_4V
590 #undef f32_to_unorm8
591 #undef f32_to_unorm16
592 #undef f32_to_snorm8
593 #undef f32_to_snorm16
594 #undef f32_to_f16
595 
596 static VkFormatFeatureFlags2
pvr_get_image_format_features2(const struct pvr_format * pvr_format,VkImageTiling vk_tiling)597 pvr_get_image_format_features2(const struct pvr_format *pvr_format,
598                                VkImageTiling vk_tiling)
599 {
600    VkFormatFeatureFlags2 flags = 0;
601    VkFormat vk_format;
602 
603    if (!pvr_format)
604       return 0;
605 
606    assert(pvr_format->supported);
607 
608    vk_format = pvr_format->vk_format;
609 
610    if (pvr_get_tex_format(vk_format) != ROGUE_TEXSTATE_FORMAT_INVALID) {
611       if (vk_tiling == VK_IMAGE_TILING_OPTIMAL) {
612          const uint32_t first_component_size =
613             vk_format_get_component_bits(vk_format,
614                                          UTIL_FORMAT_COLORSPACE_RGB,
615                                          0);
616 
617          flags |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT |
618                   VK_FORMAT_FEATURE_2_BLIT_SRC_BIT;
619 
620          if (!vk_format_is_int(vk_format) &&
621              !vk_format_is_depth_or_stencil(vk_format) &&
622              (first_component_size < 32 ||
623               vk_format_is_block_compressed(vk_format))) {
624             flags |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
625          }
626       } else if (!vk_format_is_block_compressed(vk_format)) {
627          flags |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT |
628                   VK_FORMAT_FEATURE_2_BLIT_SRC_BIT;
629       }
630    }
631 
632    if (pvr_get_pbe_accum_format(vk_format) != PVR_PBE_ACCUM_FORMAT_INVALID) {
633       if (vk_format_is_color(vk_format)) {
634          flags |= VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT |
635                   VK_FORMAT_FEATURE_2_BLIT_DST_BIT;
636 
637          if (!vk_format_is_int(vk_format)) {
638             flags |= VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BLEND_BIT;
639          }
640       }
641    } else if (vk_format_is_depth_or_stencil(vk_format)) {
642       flags |= VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT |
643                VK_FORMAT_FEATURE_2_BLIT_DST_BIT |
644                VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT;
645    }
646 
647    if (vk_tiling == VK_IMAGE_TILING_OPTIMAL) {
648       if (vk_format_is_color(vk_format) &&
649           vk_format_get_nr_components(vk_format) == 1 &&
650           vk_format_get_blocksizebits(vk_format) == 32 &&
651           vk_format_is_int(vk_format)) {
652          flags |= VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT |
653                   VK_FORMAT_FEATURE_2_STORAGE_IMAGE_ATOMIC_BIT;
654       }
655 
656       switch (vk_format) {
657       case VK_FORMAT_R8_UNORM:
658       case VK_FORMAT_R8_SNORM:
659       case VK_FORMAT_R8_UINT:
660       case VK_FORMAT_R8_SINT:
661       case VK_FORMAT_R8G8_UNORM:
662       case VK_FORMAT_R8G8_SNORM:
663       case VK_FORMAT_R8G8_UINT:
664       case VK_FORMAT_R8G8_SINT:
665       case VK_FORMAT_R8G8B8A8_UNORM:
666       case VK_FORMAT_R8G8B8A8_SNORM:
667       case VK_FORMAT_R8G8B8A8_UINT:
668       case VK_FORMAT_R8G8B8A8_SINT:
669       case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
670       case VK_FORMAT_A2B10G10R10_UINT_PACK32:
671       case VK_FORMAT_R16_UNORM:
672       case VK_FORMAT_R16_SNORM:
673       case VK_FORMAT_R16_UINT:
674       case VK_FORMAT_R16_SINT:
675       case VK_FORMAT_R16_SFLOAT:
676       case VK_FORMAT_R16G16_UNORM:
677       case VK_FORMAT_R16G16_SNORM:
678       case VK_FORMAT_R16G16_UINT:
679       case VK_FORMAT_R16G16_SINT:
680       case VK_FORMAT_R16G16_SFLOAT:
681       case VK_FORMAT_R16G16B16A16_UNORM:
682       case VK_FORMAT_R16G16B16A16_SNORM:
683       case VK_FORMAT_R16G16B16A16_UINT:
684       case VK_FORMAT_R16G16B16A16_SINT:
685       case VK_FORMAT_R16G16B16A16_SFLOAT:
686       case VK_FORMAT_R32_SFLOAT:
687       case VK_FORMAT_R32G32_UINT:
688       case VK_FORMAT_R32G32_SINT:
689       case VK_FORMAT_R32G32_SFLOAT:
690       case VK_FORMAT_R32G32B32A32_UINT:
691       case VK_FORMAT_R32G32B32A32_SINT:
692       case VK_FORMAT_R32G32B32A32_SFLOAT:
693       case VK_FORMAT_B10G11R11_UFLOAT_PACK32:
694          flags |= VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT;
695          break;
696       default:
697          break;
698       }
699    }
700 
701    if (flags & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT) {
702       flags |= VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT |
703                VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT;
704    }
705 
706    return flags;
707 }
708 
pvr_get_format_swizzle(VkFormat vk_format)709 const uint8_t *pvr_get_format_swizzle(VkFormat vk_format)
710 {
711    const struct util_format_description *vf = vk_format_description(vk_format);
712 
713    return vf->swizzle;
714 }
715 
716 static VkFormatFeatureFlags2
pvr_get_buffer_format_features2(const struct pvr_format * pvr_format)717 pvr_get_buffer_format_features2(const struct pvr_format *pvr_format)
718 {
719    const struct util_format_description *desc;
720    VkFormatFeatureFlags2 flags = 0;
721    VkFormat vk_format;
722 
723    if (!pvr_format)
724       return 0;
725 
726    assert(pvr_format->supported);
727 
728    vk_format = pvr_format->vk_format;
729 
730    if (!vk_format_is_color(vk_format))
731       return 0;
732 
733    desc = vk_format_description(vk_format);
734 
735    if (desc->layout == UTIL_FORMAT_LAYOUT_PLAIN &&
736        desc->colorspace == UTIL_FORMAT_COLORSPACE_RGB) {
737       flags |= VK_FORMAT_FEATURE_2_VERTEX_BUFFER_BIT;
738 
739       if (desc->is_array && vk_format != VK_FORMAT_R32G32B32_UINT &&
740           vk_format != VK_FORMAT_R32G32B32_SINT &&
741           vk_format != VK_FORMAT_R32G32B32_SFLOAT) {
742          flags |= VK_FORMAT_FEATURE_2_UNIFORM_TEXEL_BUFFER_BIT;
743       } else if (vk_format == VK_FORMAT_A2B10G10R10_UNORM_PACK32 ||
744                  vk_format == VK_FORMAT_A2B10G10R10_UINT_PACK32) {
745          flags |= VK_FORMAT_FEATURE_2_UNIFORM_TEXEL_BUFFER_BIT;
746       }
747    } else if (vk_format == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32) {
748       flags |= VK_FORMAT_FEATURE_2_VERTEX_BUFFER_BIT;
749    }
750 
751    if (vk_format_is_color(vk_format) &&
752        vk_format_get_nr_components(vk_format) == 1 &&
753        vk_format_get_blocksizebits(vk_format) == 32 &&
754        vk_format_is_int(vk_format)) {
755       flags |= VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT |
756                VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_ATOMIC_BIT;
757    }
758 
759    switch (vk_format) {
760    case VK_FORMAT_R8G8B8A8_UNORM:
761    case VK_FORMAT_R8G8B8A8_SNORM:
762    case VK_FORMAT_R8G8B8A8_UINT:
763    case VK_FORMAT_R8G8B8A8_SINT:
764    case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
765    case VK_FORMAT_A8B8G8R8_SNORM_PACK32:
766    case VK_FORMAT_A8B8G8R8_UINT_PACK32:
767    case VK_FORMAT_A8B8G8R8_SINT_PACK32:
768    case VK_FORMAT_R16G16B16A16_UINT:
769    case VK_FORMAT_R16G16B16A16_SINT:
770    case VK_FORMAT_R16G16B16A16_SFLOAT:
771    case VK_FORMAT_R32_SFLOAT:
772    case VK_FORMAT_R32G32_UINT:
773    case VK_FORMAT_R32G32_SINT:
774    case VK_FORMAT_R32G32_SFLOAT:
775    case VK_FORMAT_R32G32B32A32_UINT:
776    case VK_FORMAT_R32G32B32A32_SINT:
777    case VK_FORMAT_R32G32B32A32_SFLOAT:
778       flags |= VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT;
779       break;
780 
781    case VK_FORMAT_B10G11R11_UFLOAT_PACK32:
782       flags |= VK_FORMAT_FEATURE_2_UNIFORM_TEXEL_BUFFER_BIT;
783       break;
784 
785    default:
786       break;
787    }
788 
789    if (flags & VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT) {
790       flags |= VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT |
791                VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT;
792    }
793 
794    return flags;
795 }
796 
pvr_GetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice,VkFormat format,VkFormatProperties2 * pFormatProperties)797 void pvr_GetPhysicalDeviceFormatProperties2(
798    VkPhysicalDevice physicalDevice,
799    VkFormat format,
800    VkFormatProperties2 *pFormatProperties)
801 {
802    const struct pvr_format *pvr_format = pvr_get_format(format);
803    VkFormatFeatureFlags2 linear2, optimal2, buffer2;
804 
805    linear2 = pvr_get_image_format_features2(pvr_format, VK_IMAGE_TILING_LINEAR);
806    optimal2 =
807       pvr_get_image_format_features2(pvr_format, VK_IMAGE_TILING_OPTIMAL);
808    buffer2 = pvr_get_buffer_format_features2(pvr_format);
809 
810    pFormatProperties->formatProperties = (VkFormatProperties){
811       .linearTilingFeatures = vk_format_features2_to_features(linear2),
812       .optimalTilingFeatures = vk_format_features2_to_features(optimal2),
813       .bufferFeatures = vk_format_features2_to_features(buffer2),
814    };
815 
816    vk_foreach_struct (ext, pFormatProperties->pNext) {
817       switch (ext->sType) {
818       case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3: {
819          VkFormatProperties3 *pFormatProperties3 = (VkFormatProperties3 *)ext;
820          pFormatProperties3->linearTilingFeatures = linear2;
821          pFormatProperties3->optimalTilingFeatures = optimal2;
822          pFormatProperties3->bufferFeatures = buffer2;
823          break;
824       }
825       default:
826          vk_debug_ignored_stype(ext->sType);
827          break;
828       }
829    }
830 }
831 
832 static VkResult
pvr_get_image_format_properties(struct pvr_physical_device * pdevice,const VkPhysicalDeviceImageFormatInfo2 * info,VkImageFormatProperties * pImageFormatProperties)833 pvr_get_image_format_properties(struct pvr_physical_device *pdevice,
834                                 const VkPhysicalDeviceImageFormatInfo2 *info,
835                                 VkImageFormatProperties *pImageFormatProperties)
836 {
837    /* Input attachments aren't rendered but they must have the same size
838     * restrictions as any framebuffer attachment.
839     */
840    const VkImageUsageFlags render_usage =
841       VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_STORAGE_BIT |
842       VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT |
843       VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
844       VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
845    const struct pvr_format *pvr_format = pvr_get_format(info->format);
846    VkFormatFeatureFlags2 tiling_features2;
847    VkResult result;
848 
849    if (!pvr_format) {
850       result = vk_error(pdevice, VK_ERROR_FORMAT_NOT_SUPPORTED);
851       goto err_unsupported_format;
852    }
853 
854    tiling_features2 = pvr_get_image_format_features2(pvr_format, info->tiling);
855    if (tiling_features2 == 0) {
856       result = vk_error(pdevice, VK_ERROR_FORMAT_NOT_SUPPORTED);
857       goto err_unsupported_format;
858    }
859 
860    if (info->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) {
861       result = vk_error(pdevice, VK_ERROR_FORMAT_NOT_SUPPORTED);
862       goto err_unsupported_format;
863    }
864 
865    /* If VK_IMAGE_CREATE_EXTENDED_USAGE_BIT is set, the driver can't decide if a
866     * specific format isn't supported based on the usage.
867     */
868    if ((info->flags & VK_IMAGE_CREATE_EXTENDED_USAGE_BIT) == 0 &&
869        info->usage & (VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT |
870                       VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) &&
871        pvr_format->pbe_accum_format == PVR_PBE_ACCUM_FORMAT_INVALID) {
872       result = vk_error(pdevice, VK_ERROR_FORMAT_NOT_SUPPORTED);
873       goto err_unsupported_format;
874    }
875 
876    if (info->type == VK_IMAGE_TYPE_3D) {
877       const VkImageUsageFlags transfer_usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
878                                                VK_IMAGE_USAGE_TRANSFER_DST_BIT;
879 
880       /* We don't support 3D depth/stencil images. */
881       if (tiling_features2 & VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT) {
882          result = vk_error(pdevice, VK_ERROR_FORMAT_NOT_SUPPORTED);
883          goto err_unsupported_format;
884       }
885 
886       /* Linear tiled 3D images may only be used for transfer or blit
887        * operations.
888        */
889       if (info->tiling == VK_IMAGE_TILING_LINEAR &&
890           info->usage & ~transfer_usage) {
891          result = vk_error(pdevice, VK_ERROR_FORMAT_NOT_SUPPORTED);
892          goto err_unsupported_format;
893       }
894 
895       /* Block compressed with 3D layout not supported */
896       if (vk_format_is_block_compressed(info->format)) {
897          result = vk_error(pdevice, VK_ERROR_FORMAT_NOT_SUPPORTED);
898          goto err_unsupported_format;
899       }
900    }
901 
902    if (info->usage & render_usage) {
903       const uint32_t max_render_size =
904          rogue_get_render_size_max(&pdevice->dev_info);
905 
906       pImageFormatProperties->maxExtent.width = max_render_size;
907       pImageFormatProperties->maxExtent.height = max_render_size;
908       pImageFormatProperties->maxExtent.depth = PVR_MAX_TEXTURE_EXTENT_Z;
909    } else {
910       const uint32_t max_texture_extent_xy =
911          PVRX(TEXSTATE_IMAGE_WORD0_WIDTH_MAX_SIZE) + 1U;
912 
913       pImageFormatProperties->maxExtent.width = max_texture_extent_xy;
914       pImageFormatProperties->maxExtent.height = max_texture_extent_xy;
915       pImageFormatProperties->maxExtent.depth = PVR_MAX_TEXTURE_EXTENT_Z;
916    }
917 
918    if (info->tiling == VK_IMAGE_TILING_LINEAR) {
919       pImageFormatProperties->maxExtent.depth = 1;
920       pImageFormatProperties->maxArrayLayers = 1;
921       pImageFormatProperties->sampleCounts = VK_SAMPLE_COUNT_1_BIT;
922    } else {
923       /* Default value is the minimum value found in all existing cores. */
924       const uint32_t max_multisample =
925          PVR_GET_FEATURE_VALUE(&pdevice->dev_info, max_multisample, 4);
926 
927       const uint32_t max_sample_bits = ((max_multisample << 1) - 1);
928 
929       pImageFormatProperties->maxArrayLayers = PVR_MAX_ARRAY_LAYERS;
930       pImageFormatProperties->sampleCounts = max_sample_bits;
931    }
932 
933    if (!(tiling_features2 & VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT ||
934          tiling_features2 & VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT)) {
935       pImageFormatProperties->sampleCounts = VK_SAMPLE_COUNT_1_BIT;
936    }
937 
938    switch (info->type) {
939    case VK_IMAGE_TYPE_1D:
940       pImageFormatProperties->maxExtent.height = 1;
941       pImageFormatProperties->maxExtent.depth = 1;
942       pImageFormatProperties->sampleCounts = VK_SAMPLE_COUNT_1_BIT;
943       break;
944 
945    case VK_IMAGE_TYPE_2D:
946       pImageFormatProperties->maxExtent.depth = 1;
947 
948       /* If a 2D image is created to be used in a cube map, then the sample
949        * count must be restricted to 1 sample.
950        */
951       if (info->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)
952          pImageFormatProperties->sampleCounts = VK_SAMPLE_COUNT_1_BIT;
953 
954       break;
955 
956    case VK_IMAGE_TYPE_3D:
957       pImageFormatProperties->maxArrayLayers = 1;
958       pImageFormatProperties->sampleCounts = VK_SAMPLE_COUNT_1_BIT;
959       break;
960 
961    default:
962       unreachable("Invalid image type.");
963    }
964 
965    /* The spec says maxMipLevels may be 1 when tiling is VK_IMAGE_TILING_LINEAR
966     * or VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT, so for simplicity don't
967     * support miplevels for these tilings.
968     */
969    if (info->tiling == VK_IMAGE_TILING_LINEAR) {
970       pImageFormatProperties->maxMipLevels = 1;
971    } else {
972       const uint32_t max_size = MAX3(pImageFormatProperties->maxExtent.width,
973                                      pImageFormatProperties->maxExtent.height,
974                                      pImageFormatProperties->maxExtent.depth);
975 
976       pImageFormatProperties->maxMipLevels = util_logbase2(max_size) + 1U;
977    }
978 
979    /* Return 2GB (minimum required from spec).
980     *
981     * From the Vulkan spec:
982     *
983     *    maxResourceSize is an upper bound on the total image size in bytes,
984     *    inclusive of all image subresources. Implementations may have an
985     *    address space limit on total size of a resource, which is advertised by
986     *    this property. maxResourceSize must be at least 2^31.
987     */
988    pImageFormatProperties->maxResourceSize = 2ULL * 1024 * 1024 * 1024;
989 
990    return VK_SUCCESS;
991 
992 err_unsupported_format:
993    /* From the Vulkan 1.0.42 spec:
994     *
995     *    If the combination of parameters to
996     *    vkGetPhysicalDeviceImageFormatProperties2 is not supported by the
997     *    implementation for use in vkCreateImage, then all members of
998     *    imageFormatProperties will be filled with zero.
999     */
1000    *pImageFormatProperties = (VkImageFormatProperties){ 0 };
1001 
1002    return result;
1003 }
1004 
1005 /* FIXME: Should this be returning VK_ERROR_FORMAT_NOT_SUPPORTED when tiling is
1006  * linear and the image type is 3D or flags contains
1007  * VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT? This should avoid well behaved apps
1008  * attempting to create invalid image views, as pvr_pack_tex_state() will return
1009  * VK_ERROR_FORMAT_NOT_SUPPORTED in these cases.
1010  */
pvr_GetPhysicalDeviceImageFormatProperties2(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceImageFormatInfo2 * pImageFormatInfo,VkImageFormatProperties2 * pImageFormatProperties)1011 VkResult pvr_GetPhysicalDeviceImageFormatProperties2(
1012    VkPhysicalDevice physicalDevice,
1013    const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo,
1014    VkImageFormatProperties2 *pImageFormatProperties)
1015 {
1016    const VkPhysicalDeviceExternalImageFormatInfo *external_info = NULL;
1017    PVR_FROM_HANDLE(pvr_physical_device, pdevice, physicalDevice);
1018    VkExternalImageFormatProperties *external_props = NULL;
1019    VkResult result;
1020 
1021    result = pvr_get_image_format_properties(
1022       pdevice,
1023       pImageFormatInfo,
1024       &pImageFormatProperties->imageFormatProperties);
1025    if (result != VK_SUCCESS)
1026       return result;
1027 
1028    /* Extract input structs */
1029    vk_foreach_struct_const (ext, pImageFormatInfo->pNext) {
1030       switch (ext->sType) {
1031       case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO:
1032          external_info = (const void *)ext;
1033          break;
1034       case VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO:
1035          break;
1036       default:
1037          vk_debug_ignored_stype(ext->sType);
1038          break;
1039       }
1040    }
1041 
1042    /* Extract output structs */
1043    vk_foreach_struct (ext, pImageFormatProperties->pNext) {
1044       switch (ext->sType) {
1045       case VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES:
1046          external_props = (void *)ext;
1047          break;
1048       default:
1049          vk_debug_ignored_stype(ext->sType);
1050          break;
1051       }
1052    }
1053 
1054    /* From the Vulkan 1.0.42 spec:
1055     *
1056     *    If handleType is 0, vkGetPhysicalDeviceImageFormatProperties2 will
1057     *    behave as if VkPhysicalDeviceExternalImageFormatInfo was not
1058     *    present and VkExternalImageFormatProperties will be ignored.
1059     */
1060    if (external_info && external_info->handleType != 0) {
1061       switch (external_info->handleType) {
1062       case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT:
1063       case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT:
1064          if (!external_props)
1065             break;
1066 
1067          external_props->externalMemoryProperties.externalMemoryFeatures =
1068             VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT |
1069             VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
1070          external_props->externalMemoryProperties.compatibleHandleTypes =
1071             VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT |
1072             VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
1073          external_props->externalMemoryProperties.exportFromImportedHandleTypes =
1074             VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT |
1075             VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
1076          break;
1077       default:
1078          return vk_error(pdevice, VK_ERROR_FORMAT_NOT_SUPPORTED);
1079       }
1080    }
1081 
1082    return VK_SUCCESS;
1083 }
1084 
pvr_GetPhysicalDeviceSparseImageFormatProperties(VkPhysicalDevice physicalDevice,VkFormat format,VkImageType type,VkSampleCountFlagBits samples,VkImageUsageFlags usage,VkImageTiling tiling,uint32_t * pNumProperties,VkSparseImageFormatProperties * pProperties)1085 void pvr_GetPhysicalDeviceSparseImageFormatProperties(
1086    VkPhysicalDevice physicalDevice,
1087    VkFormat format,
1088    VkImageType type,
1089    VkSampleCountFlagBits samples,
1090    VkImageUsageFlags usage,
1091    VkImageTiling tiling,
1092    uint32_t *pNumProperties,
1093    VkSparseImageFormatProperties *pProperties)
1094 {
1095    /* Sparse images are not yet supported. */
1096    *pNumProperties = 0;
1097 }
1098 
pvr_GetPhysicalDeviceSparseImageFormatProperties2(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceSparseImageFormatInfo2 * pFormatInfo,uint32_t * pPropertyCount,VkSparseImageFormatProperties2 * pProperties)1099 void pvr_GetPhysicalDeviceSparseImageFormatProperties2(
1100    VkPhysicalDevice physicalDevice,
1101    const VkPhysicalDeviceSparseImageFormatInfo2 *pFormatInfo,
1102    uint32_t *pPropertyCount,
1103    VkSparseImageFormatProperties2 *pProperties)
1104 {
1105    /* Sparse images are not yet supported. */
1106    *pPropertyCount = 0;
1107 }
1108 
pvr_GetPhysicalDeviceExternalBufferProperties(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceExternalBufferInfo * pExternalBufferInfo,VkExternalBufferProperties * pExternalBufferProperties)1109 void pvr_GetPhysicalDeviceExternalBufferProperties(
1110    VkPhysicalDevice physicalDevice,
1111    const VkPhysicalDeviceExternalBufferInfo *pExternalBufferInfo,
1112    VkExternalBufferProperties *pExternalBufferProperties)
1113 {
1114    /* The Vulkan 1.0.42 spec says "handleType must be a valid
1115     * VkExternalMemoryHandleTypeFlagBits value" in
1116     * VkPhysicalDeviceExternalBufferInfo. This differs from
1117     * VkPhysicalDeviceExternalImageFormatInfo, which surprisingly permits
1118     * handleType == 0.
1119     */
1120    assert(pExternalBufferInfo->handleType != 0);
1121 
1122    /* All of the current flags are for sparse which we don't support. */
1123    if (pExternalBufferInfo->flags)
1124       goto unsupported;
1125 
1126    switch (pExternalBufferInfo->handleType) {
1127    case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT:
1128    case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT:
1129       /* clang-format off */
1130       pExternalBufferProperties->externalMemoryProperties.externalMemoryFeatures =
1131          VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT |
1132          VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
1133       pExternalBufferProperties->externalMemoryProperties.exportFromImportedHandleTypes =
1134          VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT |
1135          VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
1136       pExternalBufferProperties->externalMemoryProperties.compatibleHandleTypes =
1137          VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT |
1138          VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
1139       /* clang-format on */
1140       return;
1141    default:
1142       break;
1143    }
1144 
1145 unsupported:
1146    /* From the Vulkan 1.1.113 spec:
1147     *
1148     *    compatibleHandleTypes must include at least handleType.
1149     */
1150    pExternalBufferProperties->externalMemoryProperties =
1151       (VkExternalMemoryProperties){
1152          .compatibleHandleTypes = pExternalBufferInfo->handleType,
1153       };
1154 }
1155 
pvr_format_is_pbe_downscalable(VkFormat vk_format)1156 bool pvr_format_is_pbe_downscalable(VkFormat vk_format)
1157 {
1158    if (vk_format_is_int(vk_format)) {
1159       /* PBE downscale behavior for integer formats does not match Vulkan
1160        * spec. Vulkan requires a single sample to be chosen instead of
1161        * taking the average sample color.
1162        */
1163       return false;
1164    }
1165 
1166    switch (pvr_get_pbe_packmode(vk_format)) {
1167    default:
1168       return true;
1169 
1170    case ROGUE_PBESTATE_PACKMODE_U16U16U16U16:
1171    case ROGUE_PBESTATE_PACKMODE_S16S16S16S16:
1172    case ROGUE_PBESTATE_PACKMODE_U32U32U32U32:
1173    case ROGUE_PBESTATE_PACKMODE_S32S32S32S32:
1174    case ROGUE_PBESTATE_PACKMODE_F32F32F32F32:
1175    case ROGUE_PBESTATE_PACKMODE_U16U16U16:
1176    case ROGUE_PBESTATE_PACKMODE_S16S16S16:
1177    case ROGUE_PBESTATE_PACKMODE_U32U32U32:
1178    case ROGUE_PBESTATE_PACKMODE_S32S32S32:
1179    case ROGUE_PBESTATE_PACKMODE_F32F32F32:
1180    case ROGUE_PBESTATE_PACKMODE_U16U16:
1181    case ROGUE_PBESTATE_PACKMODE_S16S16:
1182    case ROGUE_PBESTATE_PACKMODE_U32U32:
1183    case ROGUE_PBESTATE_PACKMODE_S32S32:
1184    case ROGUE_PBESTATE_PACKMODE_F32F32:
1185    case ROGUE_PBESTATE_PACKMODE_U24ST8:
1186    case ROGUE_PBESTATE_PACKMODE_ST8U24:
1187    case ROGUE_PBESTATE_PACKMODE_U16:
1188    case ROGUE_PBESTATE_PACKMODE_S16:
1189    case ROGUE_PBESTATE_PACKMODE_U32:
1190    case ROGUE_PBESTATE_PACKMODE_S32:
1191    case ROGUE_PBESTATE_PACKMODE_F32:
1192    case ROGUE_PBESTATE_PACKMODE_X24U8F32:
1193    case ROGUE_PBESTATE_PACKMODE_X24X8F32:
1194    case ROGUE_PBESTATE_PACKMODE_X24G8X32:
1195    case ROGUE_PBESTATE_PACKMODE_X8U24:
1196    case ROGUE_PBESTATE_PACKMODE_U8X24:
1197    case ROGUE_PBESTATE_PACKMODE_PBYTE:
1198    case ROGUE_PBESTATE_PACKMODE_PWORD:
1199    case ROGUE_PBESTATE_PACKMODE_INVALID:
1200       return false;
1201    }
1202 }
1203 
pvr_pbe_pixel_num_loads(enum pvr_transfer_pbe_pixel_src pbe_format)1204 uint32_t pvr_pbe_pixel_num_loads(enum pvr_transfer_pbe_pixel_src pbe_format)
1205 {
1206    switch (pbe_format) {
1207    case PVR_TRANSFER_PBE_PIXEL_SRC_UU8888:
1208    case PVR_TRANSFER_PBE_PIXEL_SRC_US8888:
1209    case PVR_TRANSFER_PBE_PIXEL_SRC_UU16U16:
1210    case PVR_TRANSFER_PBE_PIXEL_SRC_US16S16:
1211    case PVR_TRANSFER_PBE_PIXEL_SRC_SU8888:
1212    case PVR_TRANSFER_PBE_PIXEL_SRC_SS8888:
1213    case PVR_TRANSFER_PBE_PIXEL_SRC_SU16U16:
1214    case PVR_TRANSFER_PBE_PIXEL_SRC_SS16S16:
1215    case PVR_TRANSFER_PBE_PIXEL_SRC_UU1010102:
1216    case PVR_TRANSFER_PBE_PIXEL_SRC_SU1010102:
1217    case PVR_TRANSFER_PBE_PIXEL_SRC_RBSWAP_UU1010102:
1218    case PVR_TRANSFER_PBE_PIXEL_SRC_RBSWAP_SU1010102:
1219    case PVR_TRANSFER_PBE_PIXEL_SRC_SU32U32:
1220    case PVR_TRANSFER_PBE_PIXEL_SRC_S4XU32:
1221    case PVR_TRANSFER_PBE_PIXEL_SRC_US32S32:
1222    case PVR_TRANSFER_PBE_PIXEL_SRC_U4XS32:
1223    case PVR_TRANSFER_PBE_PIXEL_SRC_F16F16:
1224    case PVR_TRANSFER_PBE_PIXEL_SRC_U16NORM:
1225    case PVR_TRANSFER_PBE_PIXEL_SRC_S16NORM:
1226    case PVR_TRANSFER_PBE_PIXEL_SRC_F32:
1227    case PVR_TRANSFER_PBE_PIXEL_SRC_F32X2:
1228    case PVR_TRANSFER_PBE_PIXEL_SRC_F32X4:
1229    case PVR_TRANSFER_PBE_PIXEL_SRC_RAW32:
1230    case PVR_TRANSFER_PBE_PIXEL_SRC_RAW64:
1231    case PVR_TRANSFER_PBE_PIXEL_SRC_RAW128:
1232    case PVR_TRANSFER_PBE_PIXEL_SRC_F16_U8:
1233    case PVR_TRANSFER_PBE_PIXEL_SRC_SWAP_LMSB:
1234    case PVR_TRANSFER_PBE_PIXEL_SRC_MOV_BY45:
1235    case PVR_TRANSFER_PBE_PIXEL_SRC_D24S8:
1236    case PVR_TRANSFER_PBE_PIXEL_SRC_S8D24:
1237    case PVR_TRANSFER_PBE_PIXEL_SRC_D32S8:
1238 
1239    case PVR_TRANSFER_PBE_PIXEL_SRC_CONV_D24_D32:
1240    case PVR_TRANSFER_PBE_PIXEL_SRC_CONV_D32U_D32F:
1241    case PVR_TRANSFER_PBE_PIXEL_SRC_CONV_D32_D24S8:
1242    case PVR_TRANSFER_PBE_PIXEL_SRC_CONV_S8D24_D24S8:
1243    case PVR_TRANSFER_PBE_PIXEL_SRC_SMRG_S8_D32S8:
1244 
1245    case PVR_TRANSFER_PBE_PIXEL_SRC_SMRG_D24S8_D32S8:
1246    case PVR_TRANSFER_PBE_PIXEL_SRC_SMRG_D32S8_D32S8:
1247    case PVR_TRANSFER_PBE_PIXEL_SRC_DMRG_D32S8_D32S8:
1248    case PVR_TRANSFER_PBE_PIXEL_SRC_SMRG_S8_D24S8:
1249    case PVR_TRANSFER_PBE_PIXEL_SRC_SMRG_D24S8_D24S8:
1250    case PVR_TRANSFER_PBE_PIXEL_SRC_DMRG_D24S8_D24S8:
1251    case PVR_TRANSFER_PBE_PIXEL_SRC_DMRG_D32_D24S8:
1252    case PVR_TRANSFER_PBE_PIXEL_SRC_DMRG_D32U_D24S8:
1253    case PVR_TRANSFER_PBE_PIXEL_SRC_Y_UV_INTERLEAVED:
1254    case PVR_TRANSFER_PBE_PIXEL_SRC_Y_U_V:
1255    case PVR_TRANSFER_PBE_PIXEL_SRC_YUV_PACKED:
1256    case PVR_TRANSFER_PBE_PIXEL_SRC_YVU_PACKED:
1257       return 1U;
1258 
1259    case PVR_TRANSFER_PBE_PIXEL_SRC_NUM:
1260    default:
1261       return 0U;
1262    }
1263 }
1264