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