1 /*
2 * Copyright © 2023 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 <stdint.h>
25 #include <vulkan/vulkan_core.h>
26
27 #include "pvr_bo.h"
28 #include "pvr_private.h"
29 #include "pvr_robustness.h"
30 #include "util/u_math.h"
31
32 enum pvr_robustness_buffer_format {
33 PVR_ROBUSTNESS_BUFFER_FORMAT_UINT64,
34 PVR_ROBUSTNESS_BUFFER_FORMAT_UINT32,
35 PVR_ROBUSTNESS_BUFFER_FORMAT_UINT16,
36 PVR_ROBUSTNESS_BUFFER_FORMAT_UINT8,
37 PVR_ROBUSTNESS_BUFFER_FORMAT_SINT64,
38 PVR_ROBUSTNESS_BUFFER_FORMAT_SINT32,
39 PVR_ROBUSTNESS_BUFFER_FORMAT_SINT16,
40 PVR_ROBUSTNESS_BUFFER_FORMAT_SINT8,
41 PVR_ROBUSTNESS_BUFFER_FORMAT_SFLOAT64,
42 PVR_ROBUSTNESS_BUFFER_FORMAT_SFLOAT32,
43 PVR_ROBUSTNESS_BUFFER_FORMAT_SFLOAT16,
44 PVR_ROBUSTNESS_BUFFER_FORMAT_A8B8G8R8_UINT,
45 PVR_ROBUSTNESS_BUFFER_FORMAT_A8B8G8R8_SINT,
46 PVR_ROBUSTNESS_BUFFER_FORMAT_A2R10G10B10_UINT,
47 PVR_ROBUSTNESS_BUFFER_FORMAT_A2R10G10B10_SINT,
48 PVR_ROBUSTNESS_BUFFER_FORMAT_R4G4B4A4_UNORM,
49 PVR_ROBUSTNESS_BUFFER_FORMAT_R5G5B5A1_UNORM,
50 PVR_ROBUSTNESS_BUFFER_FORMAT_A1R5G5B5_UNORM,
51 PVR_ROBUSTNESS_BUFFER_FORMAT_COUNT
52 };
53
54 /* Offsets in bytes of the [0, 0, 0, 1] vectors within the robustness buffer */
55 static uint16_t robustness_buffer_offsets[PVR_ROBUSTNESS_BUFFER_FORMAT_COUNT];
56
pvr_init_robustness_buffer(struct pvr_device * device)57 VkResult pvr_init_robustness_buffer(struct pvr_device *device)
58 {
59 uint16_t offset = 0;
60 uint8_t *robustness_buffer_map;
61 VkResult result;
62
63 #define ROBUSTNESS_BUFFER_OFFSET_ALIGN16(cur_offset, add) \
64 ((uint16_t)ALIGN((cur_offset + (uint16_t)(add)), 16))
65
66 robustness_buffer_offsets[PVR_ROBUSTNESS_BUFFER_FORMAT_UINT64] = offset;
67 offset = ROBUSTNESS_BUFFER_OFFSET_ALIGN16(offset, sizeof(uint64_t) * 4);
68
69 robustness_buffer_offsets[PVR_ROBUSTNESS_BUFFER_FORMAT_UINT32] = offset;
70 offset = ROBUSTNESS_BUFFER_OFFSET_ALIGN16(offset, sizeof(uint32_t) * 4);
71
72 robustness_buffer_offsets[PVR_ROBUSTNESS_BUFFER_FORMAT_UINT16] = offset;
73 offset = ROBUSTNESS_BUFFER_OFFSET_ALIGN16(offset, sizeof(uint16_t) * 4);
74
75 robustness_buffer_offsets[PVR_ROBUSTNESS_BUFFER_FORMAT_UINT8] = offset;
76 offset = ROBUSTNESS_BUFFER_OFFSET_ALIGN16(offset, sizeof(uint8_t) * 4);
77
78 robustness_buffer_offsets[PVR_ROBUSTNESS_BUFFER_FORMAT_SINT64] = offset;
79 offset = ROBUSTNESS_BUFFER_OFFSET_ALIGN16(offset, sizeof(int64_t) * 4);
80
81 robustness_buffer_offsets[PVR_ROBUSTNESS_BUFFER_FORMAT_SINT32] = offset;
82 offset = ROBUSTNESS_BUFFER_OFFSET_ALIGN16(offset, sizeof(int32_t) * 4);
83
84 robustness_buffer_offsets[PVR_ROBUSTNESS_BUFFER_FORMAT_SINT16] = offset;
85 offset = ROBUSTNESS_BUFFER_OFFSET_ALIGN16(offset, sizeof(int16_t) * 4);
86
87 robustness_buffer_offsets[PVR_ROBUSTNESS_BUFFER_FORMAT_SINT8] = offset;
88 offset = ROBUSTNESS_BUFFER_OFFSET_ALIGN16(offset, sizeof(int8_t) * 4);
89
90 robustness_buffer_offsets[PVR_ROBUSTNESS_BUFFER_FORMAT_SFLOAT64] = offset;
91 offset = ROBUSTNESS_BUFFER_OFFSET_ALIGN16(offset, sizeof(double) * 4);
92
93 robustness_buffer_offsets[PVR_ROBUSTNESS_BUFFER_FORMAT_SFLOAT32] = offset;
94 offset = ROBUSTNESS_BUFFER_OFFSET_ALIGN16(offset, sizeof(float) * 4);
95
96 robustness_buffer_offsets[PVR_ROBUSTNESS_BUFFER_FORMAT_SFLOAT16] = offset;
97 offset = ROBUSTNESS_BUFFER_OFFSET_ALIGN16(offset, sizeof(uint16_t) * 4);
98
99 robustness_buffer_offsets[PVR_ROBUSTNESS_BUFFER_FORMAT_A8B8G8R8_UINT] =
100 offset;
101 offset = ROBUSTNESS_BUFFER_OFFSET_ALIGN16(offset, 4);
102
103 robustness_buffer_offsets[PVR_ROBUSTNESS_BUFFER_FORMAT_A8B8G8R8_SINT] =
104 offset;
105 offset = ROBUSTNESS_BUFFER_OFFSET_ALIGN16(offset, 4);
106
107 robustness_buffer_offsets[PVR_ROBUSTNESS_BUFFER_FORMAT_A2R10G10B10_UINT] =
108 offset;
109 offset = ROBUSTNESS_BUFFER_OFFSET_ALIGN16(offset, 4);
110
111 robustness_buffer_offsets[PVR_ROBUSTNESS_BUFFER_FORMAT_A2R10G10B10_SINT] =
112 offset;
113 offset = ROBUSTNESS_BUFFER_OFFSET_ALIGN16(offset, 4);
114
115 robustness_buffer_offsets[PVR_ROBUSTNESS_BUFFER_FORMAT_R4G4B4A4_UNORM] =
116 offset;
117 offset = ROBUSTNESS_BUFFER_OFFSET_ALIGN16(offset, 2);
118
119 robustness_buffer_offsets[PVR_ROBUSTNESS_BUFFER_FORMAT_R5G5B5A1_UNORM] =
120 offset;
121 offset = ROBUSTNESS_BUFFER_OFFSET_ALIGN16(offset, 2);
122
123 robustness_buffer_offsets[PVR_ROBUSTNESS_BUFFER_FORMAT_A1R5G5B5_UNORM] =
124 offset;
125 offset = ROBUSTNESS_BUFFER_OFFSET_ALIGN16(offset, 2);
126
127 #undef ROBUSTNESS_BUFFER_OFFSET_ALIGN16
128
129 result = pvr_bo_alloc(device,
130 device->heaps.general_heap,
131 offset,
132 16,
133 PVR_BO_ALLOC_FLAG_CPU_MAPPED,
134 &device->robustness_buffer);
135 if (result != VK_SUCCESS)
136 return result;
137
138 robustness_buffer_map = device->robustness_buffer->bo->map;
139
140 #define ROBUSTNESS_BUFFER_RGBA(format, type, zero, one) \
141 do { \
142 type *const buffer = \
143 (type *)robustness_buffer_map + robustness_buffer_offsets[format]; \
144 buffer[0] = (type)zero; \
145 buffer[1] = (type)zero; \
146 buffer[2] = (type)zero; \
147 buffer[3] = (type)one; \
148 } while (0)
149
150 #define ROBUSTNESS_BUFFER_ABGR(format, type, zero, one) \
151 do { \
152 type *const buffer = \
153 (type *)robustness_buffer_map + robustness_buffer_offsets[format]; \
154 buffer[0] = (type)one; \
155 buffer[1] = (type)zero; \
156 buffer[2] = (type)zero; \
157 buffer[3] = (type)zero; \
158 } while (0)
159
160 #define ROBUSTNESS_BUFFER_PACKED(format, type, val) \
161 do { \
162 type *const buffer = \
163 (type *)robustness_buffer_map + robustness_buffer_offsets[format]; \
164 *buffer = (type)val; \
165 } while (0)
166
167 ROBUSTNESS_BUFFER_RGBA(PVR_ROBUSTNESS_BUFFER_FORMAT_UINT64,
168 uint64_t,
169 0ull,
170 UINT64_MAX);
171 ROBUSTNESS_BUFFER_RGBA(PVR_ROBUSTNESS_BUFFER_FORMAT_UINT32,
172 uint32_t,
173 0ul,
174 UINT32_MAX);
175 ROBUSTNESS_BUFFER_RGBA(PVR_ROBUSTNESS_BUFFER_FORMAT_UINT16,
176 uint16_t,
177 0u,
178 UINT16_MAX);
179 ROBUSTNESS_BUFFER_RGBA(PVR_ROBUSTNESS_BUFFER_FORMAT_UINT8,
180 uint8_t,
181 0u,
182 UINT8_MAX);
183
184 ROBUSTNESS_BUFFER_RGBA(PVR_ROBUSTNESS_BUFFER_FORMAT_SINT64,
185 int64_t,
186 0ull,
187 INT64_MAX);
188 ROBUSTNESS_BUFFER_RGBA(PVR_ROBUSTNESS_BUFFER_FORMAT_SINT32,
189 int32_t,
190 0ul,
191 INT32_MAX);
192 ROBUSTNESS_BUFFER_RGBA(PVR_ROBUSTNESS_BUFFER_FORMAT_SINT16,
193 int16_t,
194 0u,
195 INT16_MAX);
196 ROBUSTNESS_BUFFER_RGBA(PVR_ROBUSTNESS_BUFFER_FORMAT_SINT8,
197 int8_t,
198 0u,
199 INT8_MAX);
200
201 ROBUSTNESS_BUFFER_RGBA(PVR_ROBUSTNESS_BUFFER_FORMAT_SFLOAT64,
202 uint64_t,
203 0x0000000000000000ull,
204 0x3ff0000000000000ull);
205 ROBUSTNESS_BUFFER_RGBA(PVR_ROBUSTNESS_BUFFER_FORMAT_SFLOAT32,
206 float,
207 0.0f,
208 1.0f);
209 ROBUSTNESS_BUFFER_RGBA(PVR_ROBUSTNESS_BUFFER_FORMAT_SFLOAT16,
210 uint16_t,
211 0x0000,
212 0x3c00);
213
214 ROBUSTNESS_BUFFER_ABGR(PVR_ROBUSTNESS_BUFFER_FORMAT_A8B8G8R8_UINT,
215 uint8_t,
216 0u,
217 UINT8_MAX);
218 ROBUSTNESS_BUFFER_ABGR(PVR_ROBUSTNESS_BUFFER_FORMAT_A8B8G8R8_UINT,
219 int8_t,
220 0u,
221 INT8_MAX);
222
223 ROBUSTNESS_BUFFER_PACKED(PVR_ROBUSTNESS_BUFFER_FORMAT_A2R10G10B10_UINT,
224 uint32_t,
225 0xC0000000u);
226 ROBUSTNESS_BUFFER_PACKED(PVR_ROBUSTNESS_BUFFER_FORMAT_A2R10G10B10_SINT,
227 uint32_t,
228 0x40000000u);
229 ROBUSTNESS_BUFFER_PACKED(PVR_ROBUSTNESS_BUFFER_FORMAT_R4G4B4A4_UNORM,
230 uint16_t,
231 0x000Fu);
232 ROBUSTNESS_BUFFER_PACKED(PVR_ROBUSTNESS_BUFFER_FORMAT_R5G5B5A1_UNORM,
233 uint16_t,
234 0x0001u);
235 ROBUSTNESS_BUFFER_PACKED(PVR_ROBUSTNESS_BUFFER_FORMAT_A1R5G5B5_UNORM,
236 uint16_t,
237 0x8000u);
238
239 #undef ROBUSTNESS_BUFFER_RGBA
240 #undef ROBUSTNESS_BUFFER_ABGR
241 #undef ROBUSTNESS_BUFFER_PACKED
242
243 return VK_SUCCESS;
244 }
245
pvr_robustness_buffer_finish(struct pvr_device * device)246 void pvr_robustness_buffer_finish(struct pvr_device *device)
247 {
248 pvr_bo_free(device, device->robustness_buffer);
249 }
250
pvr_get_robustness_buffer_format_offset(VkFormat format)251 uint16_t pvr_get_robustness_buffer_format_offset(VkFormat format)
252 {
253 switch (format) {
254 case VK_FORMAT_R64G64B64A64_SFLOAT:
255 return robustness_buffer_offsets[PVR_ROBUSTNESS_BUFFER_FORMAT_SFLOAT64];
256
257 case VK_FORMAT_R32G32B32A32_SFLOAT:
258 return robustness_buffer_offsets[PVR_ROBUSTNESS_BUFFER_FORMAT_SFLOAT32];
259
260 case VK_FORMAT_R16G16B16A16_SFLOAT:
261 return robustness_buffer_offsets[PVR_ROBUSTNESS_BUFFER_FORMAT_SFLOAT16];
262
263 case VK_FORMAT_R64G64B64A64_UINT:
264 return robustness_buffer_offsets[PVR_ROBUSTNESS_BUFFER_FORMAT_UINT64];
265
266 case VK_FORMAT_R32G32B32A32_UINT:
267 return robustness_buffer_offsets[PVR_ROBUSTNESS_BUFFER_FORMAT_UINT32];
268
269 case VK_FORMAT_R16G16B16A16_UNORM:
270 case VK_FORMAT_R16G16B16A16_USCALED:
271 case VK_FORMAT_R16G16B16A16_UINT:
272 return robustness_buffer_offsets[PVR_ROBUSTNESS_BUFFER_FORMAT_UINT16];
273
274 case VK_FORMAT_R8G8B8A8_UNORM:
275 case VK_FORMAT_R8G8B8A8_USCALED:
276 case VK_FORMAT_R8G8B8A8_UINT:
277 case VK_FORMAT_R8G8B8A8_SRGB:
278 case VK_FORMAT_B8G8R8A8_UNORM:
279 case VK_FORMAT_B8G8R8A8_USCALED:
280 case VK_FORMAT_B8G8R8A8_UINT:
281 case VK_FORMAT_B8G8R8A8_SRGB:
282 return robustness_buffer_offsets[PVR_ROBUSTNESS_BUFFER_FORMAT_UINT8];
283
284 case VK_FORMAT_R64G64B64A64_SINT:
285 return robustness_buffer_offsets[PVR_ROBUSTNESS_BUFFER_FORMAT_SINT64];
286
287 case VK_FORMAT_R32G32B32A32_SINT:
288 return robustness_buffer_offsets[PVR_ROBUSTNESS_BUFFER_FORMAT_SINT32];
289
290 case VK_FORMAT_R16G16B16A16_SNORM:
291 case VK_FORMAT_R16G16B16A16_SSCALED:
292 case VK_FORMAT_R16G16B16A16_SINT:
293 return robustness_buffer_offsets[PVR_ROBUSTNESS_BUFFER_FORMAT_SINT16];
294
295 case VK_FORMAT_R8G8B8A8_SNORM:
296 case VK_FORMAT_R8G8B8A8_SSCALED:
297 case VK_FORMAT_R8G8B8A8_SINT:
298 case VK_FORMAT_B8G8R8A8_SNORM:
299 case VK_FORMAT_B8G8R8A8_SSCALED:
300 case VK_FORMAT_B8G8R8A8_SINT:
301 return robustness_buffer_offsets[PVR_ROBUSTNESS_BUFFER_FORMAT_SINT8];
302
303 case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
304 case VK_FORMAT_A8B8G8R8_USCALED_PACK32:
305 case VK_FORMAT_A8B8G8R8_UINT_PACK32:
306 case VK_FORMAT_A8B8G8R8_SRGB_PACK32:
307 return robustness_buffer_offsets
308 [PVR_ROBUSTNESS_BUFFER_FORMAT_A8B8G8R8_UINT];
309
310 case VK_FORMAT_A8B8G8R8_SNORM_PACK32:
311 case VK_FORMAT_A8B8G8R8_SSCALED_PACK32:
312 case VK_FORMAT_A8B8G8R8_SINT_PACK32:
313 return robustness_buffer_offsets
314 [PVR_ROBUSTNESS_BUFFER_FORMAT_A8B8G8R8_SINT];
315
316 case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
317 case VK_FORMAT_A2R10G10B10_USCALED_PACK32:
318 case VK_FORMAT_A2R10G10B10_UINT_PACK32:
319 case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
320 case VK_FORMAT_A2B10G10R10_USCALED_PACK32:
321 case VK_FORMAT_A2B10G10R10_UINT_PACK32:
322 return robustness_buffer_offsets
323 [PVR_ROBUSTNESS_BUFFER_FORMAT_A2R10G10B10_UINT];
324
325 case VK_FORMAT_A2R10G10B10_SNORM_PACK32:
326 case VK_FORMAT_A2R10G10B10_SSCALED_PACK32:
327 case VK_FORMAT_A2R10G10B10_SINT_PACK32:
328 case VK_FORMAT_A2B10G10R10_SNORM_PACK32:
329 case VK_FORMAT_A2B10G10R10_SSCALED_PACK32:
330 case VK_FORMAT_A2B10G10R10_SINT_PACK32:
331 return robustness_buffer_offsets
332 [PVR_ROBUSTNESS_BUFFER_FORMAT_A2R10G10B10_SINT];
333
334 case VK_FORMAT_R4G4B4A4_UNORM_PACK16:
335 case VK_FORMAT_B4G4R4A4_UNORM_PACK16:
336 return robustness_buffer_offsets
337 [PVR_ROBUSTNESS_BUFFER_FORMAT_R4G4B4A4_UNORM];
338
339 case VK_FORMAT_R5G5B5A1_UNORM_PACK16:
340 case VK_FORMAT_B5G5R5A1_UNORM_PACK16:
341 return robustness_buffer_offsets
342 [PVR_ROBUSTNESS_BUFFER_FORMAT_R5G5B5A1_UNORM];
343
344 case VK_FORMAT_A1R5G5B5_UNORM_PACK16:
345 return robustness_buffer_offsets
346 [PVR_ROBUSTNESS_BUFFER_FORMAT_A1R5G5B5_UNORM];
347
348 default:
349 return robustness_buffer_offsets[PVR_ROBUSTNESS_BUFFER_FORMAT_UINT64];
350 }
351 }
352