1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "device.h"
17
18 #include <algorithm>
19 #include <cstdint>
20 #if (RENDER_VALIDATION_ENABLED == 1)
21 #include <cinttypes>
22 #endif
23
24 #include <base/containers/array_view.h>
25 #include <base/containers/fixed_string.h>
26 #include <base/containers/string.h>
27 #include <base/containers/string_view.h>
28 #include <base/containers/type_traits.h>
29 #include <base/containers/unique_ptr.h>
30 #include <base/containers/vector.h>
31 #include <base/util/formats.h>
32 #include <render/datastore/intf_render_data_store_manager.h>
33 #include <render/datastore/render_data_store_render_pods.h>
34 #include <render/device/intf_device.h>
35 #include <render/device/pipeline_state_desc.h>
36 #include <render/namespace.h>
37 #include <render/resource_handle.h>
38
39 #include "datastore/render_data_store_pod.h"
40 #include "default_engine_constants.h"
41 #include "device/gpu_resource_manager.h"
42 #include "device/shader_manager.h"
43 #include "device/swapchain.h"
44 #include "nodecontext/node_context_descriptor_set_manager.h"
45 #include "render_context.h"
46 #include "util/log.h"
47 #include "util/string_util.h"
48
49 #if (RENDER_HAS_VULKAN_BACKEND)
50 #include "vulkan/device_vk.h"
51 #include "vulkan/swapchain_vk.h"
52 #endif
53
54 #if (RENDER_HAS_GL_BACKEND) || (RENDER_HAS_GLES_BACKEND)
55 #include "gles/device_gles.h"
56 #include "gles/swapchain_gles.h"
57 #endif
58
59 using namespace BASE_NS;
60
61 RENDER_BEGIN_NAMESPACE()
62 class IGpuResourceManager;
63 class IShaderManager;
64 PLUGIN_STATIC_ASSERT(BASE_NS::Format::BASE_FORMAT_ASTC_12x12_SRGB_BLOCK == 184u);
65 PLUGIN_STATIC_ASSERT(BASE_NS::Format::BASE_FORMAT_G8B8G8R8_422_UNORM == 1000156000u);
66
67 namespace {
68 constexpr uint32_t MIN_BUFFERING_COUNT { 2U };
69 // definitely a bit high number, prefer e.g. 3.
70 constexpr uint32_t MAX_BUFFERING_COUNT { 6U };
71
72 constexpr const Format FALLBACK_FORMATS[] = {
73 BASE_FORMAT_UNDEFINED,
74
75 // R4G4 UNORM PACK8
76 BASE_FORMAT_R8_UNORM,
77
78 // R4G4B4A4 UNORM PACK16
79 BASE_FORMAT_R16_UNORM,
80 // B4G4R4A4 UNORM PACK16
81 BASE_FORMAT_R4G4B4A4_UNORM_PACK16,
82
83 // R5G6B5 UNORM PACK16
84 BASE_FORMAT_R16_UNORM,
85 // B5G6R5 UNORM PACK16
86 BASE_FORMAT_R5G6B5_UNORM_PACK16,
87
88 // R5G5B5A1 UNORM PACK16
89 BASE_FORMAT_R5G6B5_UNORM_PACK16,
90 // B5G5R5A1 UNORM PACK16
91 BASE_FORMAT_R5G5B5A1_UNORM_PACK16,
92 // A1R5G5B5 UNORM PACK16
93 BASE_FORMAT_R5G5B5A1_UNORM_PACK16,
94
95 // R8 UNORM
96 BASE_FORMAT_UNDEFINED, // undefined
97 // R8 SNORM
98 BASE_FORMAT_R8_UNORM,
99 // R8 USCALED
100 BASE_FORMAT_R8_UNORM,
101 // R8 SSCALED
102 BASE_FORMAT_R8_SNORM,
103 // R8 UINT
104 BASE_FORMAT_R8_UNORM,
105 // R8 SINT
106 BASE_FORMAT_R8_UINT,
107 // R8 SRGB
108 BASE_FORMAT_R8_UNORM,
109
110 // R8G8 UNORM
111 BASE_FORMAT_R8G8B8A8_UNORM, // fallback to 32 bits
112 // R8G8 SNORM
113 BASE_FORMAT_R8G8_UNORM,
114 // R8G8 USCALED
115 BASE_FORMAT_R8G8_UNORM,
116 // R8G8 SSCALED
117 BASE_FORMAT_R8G8_SNORM,
118 // R8G8 UINT
119 BASE_FORMAT_R8G8_UNORM,
120 // R8G8 SINT
121 BASE_FORMAT_R8G8_UINT,
122 // R8G8 SRGB
123 BASE_FORMAT_R8G8_UNORM,
124
125 // R8G8B8 UNORM
126 BASE_FORMAT_R8G8B8A8_UNORM, // fallback to 32 bits
127 // R8G8B8 SNORM
128 BASE_FORMAT_R8G8B8_UNORM,
129 // R8G8B8 USCALED
130 BASE_FORMAT_R8G8B8_UNORM,
131 // R8G8B8 SSCALED
132 BASE_FORMAT_R8G8B8_SNORM,
133 // R8G8B8 UINT
134 BASE_FORMAT_R8G8B8_UNORM,
135 // R8G8B8 SINT
136 BASE_FORMAT_R8G8B8_UINT,
137 // R8G8B8 SRGB
138 BASE_FORMAT_R8G8B8_UNORM,
139
140 // B8G8R8 UNORM
141 BASE_FORMAT_B8G8R8A8_UNORM, // fallback to 32 bits
142 // B8G8R8 SNORM
143 BASE_FORMAT_B8G8R8_UNORM,
144 // B8G8R8 USCALED
145 BASE_FORMAT_B8G8R8_UNORM,
146 // B8G8R8 SSCALED
147 BASE_FORMAT_B8G8R8_SNORM,
148 // B8G8R8 UINT
149 BASE_FORMAT_B8G8R8_UNORM,
150 // B8G8R8 SINT
151 BASE_FORMAT_B8G8R8_UINT,
152 // B8G8R8 SRGB
153 BASE_FORMAT_B8G8R8_UNORM,
154
155 // R8G8B8A8 UNORM
156 BASE_FORMAT_UNDEFINED, // undefined
157 // R8G8B8A8 SNORM
158 BASE_FORMAT_R8G8B8A8_UNORM,
159 // R8G8B8A8 USCALED
160 BASE_FORMAT_R8G8B8A8_UNORM,
161 // R8G8B8A8 SSCALED
162 BASE_FORMAT_R8G8B8A8_SNORM,
163 // R8G8B8A8 UINT
164 BASE_FORMAT_R8G8B8A8_UNORM,
165 // R8G8B8A8 SINT
166 BASE_FORMAT_R8G8B8A8_UINT,
167 // R8G8B8A8 SRGB
168 BASE_FORMAT_R8G8B8A8_UNORM,
169
170 // B8G8R8A8 UNORM
171 BASE_FORMAT_R8G8B8A8_UNORM,
172 // B8G8R8A8 SNORM
173 BASE_FORMAT_B8G8R8A8_UNORM,
174 // B8G8R8A8 USCALED
175 BASE_FORMAT_B8G8R8A8_UNORM,
176 // B8G8R8A8 SSCALED
177 BASE_FORMAT_B8G8R8A8_SNORM,
178 // B8G8R8A8 UINT
179 BASE_FORMAT_B8G8R8A8_UNORM,
180 // B8G8R8A8 SINT
181 BASE_FORMAT_B8G8R8A8_UINT,
182 // FORMAT B8G8R8A8 SRGB
183 BASE_FORMAT_B8G8R8A8_SRGB,
184
185 // A8B8G8R8 UNORM PACK32
186 BASE_FORMAT_R8G8B8A8_UNORM,
187 // A8B8G8R8 SNORM PACK32
188 BASE_FORMAT_A8B8G8R8_UNORM_PACK32,
189 // A8B8G8R8 USCALED PACK32
190 BASE_FORMAT_A8B8G8R8_UNORM_PACK32,
191 // A8B8G8R8 SSCALED PACK32
192 BASE_FORMAT_A8B8G8R8_SNORM_PACK32,
193 // A8B8G8R8 UINT PACK32
194 BASE_FORMAT_A8B8G8R8_UNORM_PACK32,
195 // A8B8G8R8 SINT PACK32
196 BASE_FORMAT_A8B8G8R8_UINT_PACK32,
197 // A8B8G8R8 SRGB PACK32
198 BASE_FORMAT_A8B8G8R8_UNORM_PACK32,
199
200 // A2R10G10B10 UNORM PACK32
201 BASE_FORMAT_R8G8B8A8_UNORM,
202 // A2R10G10B10 SNORM PACK32
203 BASE_FORMAT_A2R10G10B10_UNORM_PACK32,
204 // A2R10G10B10 USCALED PACK32
205 BASE_FORMAT_A2R10G10B10_UNORM_PACK32,
206 // A2R10G10B10 SSCALED PACK32
207 BASE_FORMAT_A2R10G10B10_SNORM_PACK32,
208 // A2R10G10B10 UINT PACK32
209 BASE_FORMAT_A2R10G10B10_UNORM_PACK32,
210 // A2R10G10B10 SINT PACK32
211 BASE_FORMAT_A2R10G10B10_UINT_PACK32,
212
213 // A2B10G10R10 UNORM PACK32
214 BASE_FORMAT_R8G8B8A8_UNORM,
215 // A2B10G10R10 SNORM PACK32
216 BASE_FORMAT_A2B10G10R10_UNORM_PACK32,
217 // A2B10G10R10 USCALED PACK32
218 BASE_FORMAT_A2B10G10R10_UNORM_PACK32,
219 // A2B10G10R10 SSCALED PACK32
220 BASE_FORMAT_A2B10G10R10_SNORM_PACK32,
221 // A2B10G10R10 UINT PACK32
222 BASE_FORMAT_A2B10G10R10_UNORM_PACK32,
223 // A2B10G10R10 SINT PACK32
224 BASE_FORMAT_A2B10G10R10_UINT_PACK32,
225
226 // R16 UNORM
227 BASE_FORMAT_R8_UNORM, // fallback to 8 bit channel
228 // R16 SNORM
229 BASE_FORMAT_R16_UNORM,
230 // R16 USCALED
231 BASE_FORMAT_R16_UNORM,
232 // R16 SSCALED
233 BASE_FORMAT_R16_SNORM,
234 // R16 UINT
235 BASE_FORMAT_R16_UNORM,
236 // R16 SINT
237 BASE_FORMAT_R16_UINT,
238 // R16 SFLOAT
239 BASE_FORMAT_R16_UNORM,
240
241 // R16G16 UNORM
242 BASE_FORMAT_R16G16B16A16_UNORM, // fallback to 4 channel
243 // R16G16 SNORM
244 BASE_FORMAT_R16G16_UNORM,
245 // R16G16 USCALED
246 BASE_FORMAT_R16G16_UNORM,
247 // R16G16 SSCALED
248 BASE_FORMAT_R16G16_SNORM,
249 // R16G16 UINT
250 BASE_FORMAT_R16G16_UNORM,
251 // R16G16 SINT
252 BASE_FORMAT_R16G16_UINT,
253 // R16G16 SFLOAT
254 BASE_FORMAT_R16G16_UNORM,
255
256 // R16G16B16 UNORM
257 BASE_FORMAT_R16G16B16A16_UNORM, // fallback to 4 channel
258 // R16G16B16 SNORM
259 BASE_FORMAT_R16G16B16_UNORM,
260 // R16G16B16 USCALED
261 BASE_FORMAT_R16G16B16_UNORM,
262 // R16G16B16 SSCALED
263 BASE_FORMAT_R16G16B16_SNORM,
264 // R16G16B16 UINT
265 BASE_FORMAT_R16G16B16_UNORM,
266 // R16G16B16 SINT
267 BASE_FORMAT_R16G16B16_UINT,
268 // R16G16B16 SFLOAT
269 BASE_FORMAT_R16G16B16_UNORM,
270
271 // R16G16B16A16 UNORM
272 BASE_FORMAT_R8G8B8A8_UNORM, // fallback to 8 bit channels
273 // R16G16B16A16 SNORM
274 BASE_FORMAT_R16G16B16A16_UNORM,
275 // R16G16B16A16 USCALED
276 BASE_FORMAT_R16G16B16A16_UNORM,
277 // R16G16B16A16 SSCALED
278 BASE_FORMAT_R16G16B16A16_SNORM,
279 // R16G16B16A16 UINT
280 BASE_FORMAT_R16G16B16A16_UNORM,
281 // R16G16B16A16 SINT
282 BASE_FORMAT_R16G16B16A16_UINT,
283 // R16G16B16A16 SFLOAT
284 BASE_FORMAT_R16G16B16A16_UNORM,
285
286 // R32 UINT
287 BASE_FORMAT_R16_UINT, // fallback to 16 bit channel
288 // R32 SINT
289 BASE_FORMAT_R32_UINT,
290 // R32 SFLOAT
291 BASE_FORMAT_R32_UINT,
292
293 // R32G32 UINT
294 BASE_FORMAT_R16G16_UINT, // fallback to 16 bit channels
295 // R32G32 SINT
296 BASE_FORMAT_R32G32_UINT,
297 // R32G32 SFLOAT
298 BASE_FORMAT_R32G32_UINT,
299
300 // R32G32B32 UINT
301 BASE_FORMAT_R32G32B32A32_UINT, // fallback to 4 channels
302 // R32G32B32 SINT
303 BASE_FORMAT_R32G32B32_UINT,
304 // R32G32B32 SFLOAT
305 BASE_FORMAT_R32G32B32_UINT,
306
307 // R32G32B32A32 UINT
308 BASE_FORMAT_R16G16B16A16_UINT, // fallback to 16 bit channels
309 // R32G32B32A32 SINT
310 BASE_FORMAT_R32G32B32A32_UINT,
311 // R32G32B32A32 SFLOAT
312 BASE_FORMAT_R32G32B32A32_UINT,
313
314 // R64 UINT
315 BASE_FORMAT_R32_UINT, // fallback to 32 bit channel
316 // R64 SINT
317 BASE_FORMAT_R64_UINT,
318 // R64 SFLOAT
319 BASE_FORMAT_R64_UINT,
320
321 // R64G64 UINT
322 BASE_FORMAT_R64G64B64A64_UINT, // fallback to 4 channels
323 // R64G64 SINT
324 BASE_FORMAT_R64G64_UINT,
325 // R64G64 SFLOAT
326 BASE_FORMAT_R64G64_UINT,
327
328 // R64G64B64 UINT
329 BASE_FORMAT_R64G64B64A64_UINT, // fallback to 4 channels
330 // R64G64B64 SINT
331 BASE_FORMAT_R64G64B64_UINT,
332 // R64G64B64 SFLOAT
333 BASE_FORMAT_R64G64B64_UINT,
334
335 // R64G64B64A64 UINT
336 BASE_FORMAT_R32G32B32A32_UINT, // fallback to 32 bit channels
337 // R64G64B64A64 SINT
338 BASE_FORMAT_R64G64B64A64_UINT,
339 // R32G32B32A32 SFLOAT
340 BASE_FORMAT_R64G64B64A64_UINT,
341
342 // B10G11R11 UFLOAT PACK32
343 BASE_FORMAT_R16G16B16A16_SFLOAT, // fallback to 4 channel, 16 bit HDR
344
345 // E5B9G9R9 UFLOAT PACK32
346 BASE_FORMAT_R16G16B16A16_SFLOAT, // fallback to 4 channel, 16 bit HDR
347
348 // D16 UNORM
349 BASE_FORMAT_D32_SFLOAT, // fallback to 32 bit depth only
350 // X8 D24 UNORM PACK32
351 BASE_FORMAT_D32_SFLOAT,
352 // D32 SFLOAT
353 BASE_FORMAT_X8_D24_UNORM_PACK32,
354 // S8 UINT
355 BASE_FORMAT_D24_UNORM_S8_UINT,
356 // D16 UNORM S8 UINT
357 BASE_FORMAT_D24_UNORM_S8_UINT,
358 // D24 UNORM S8 UINT
359 BASE_FORMAT_D32_SFLOAT_S8_UINT,
360 // D32 SFLOAT S8 UINT
361 BASE_FORMAT_D24_UNORM_S8_UINT,
362
363 // BC1 RGB UNORM BLOCK
364 BASE_FORMAT_UNDEFINED, // undefined
365 // BC1 RGB SRGB BLOCK
366 BASE_FORMAT_BC1_RGB_UNORM_BLOCK,
367 // BC1 RGBA UNORM BLOCK
368 BASE_FORMAT_UNDEFINED, // undefined
369 // BC1 RGBA SRGB BLOCK
370 BASE_FORMAT_BC1_RGBA_UNORM_BLOCK,
371 // BC2 UNORM BLOCK
372 BASE_FORMAT_UNDEFINED, // undefined
373 // BC2 SRGB BLOCK
374 BASE_FORMAT_BC2_UNORM_BLOCK,
375 // BC3 UNORM BLOCK
376 BASE_FORMAT_UNDEFINED, // undefined
377 // BC3 SRGB BLOCK
378 BASE_FORMAT_BC3_UNORM_BLOCK,
379 // BC4 UNORM BLOCK
380 BASE_FORMAT_UNDEFINED, // undefined
381 // BC4 SNORM BLOCK
382 BASE_FORMAT_BC4_UNORM_BLOCK,
383 // BC5 UNORM BLOCK
384 BASE_FORMAT_UNDEFINED, // undefined
385 // BC5 SNORM BLOCK
386 BASE_FORMAT_BC5_UNORM_BLOCK,
387 // BC6H UFLOAT BLOCK
388 BASE_FORMAT_UNDEFINED, // undefined
389 // BC6H SFLOAT BLOCK
390 BASE_FORMAT_BC6H_UFLOAT_BLOCK,
391 // BC7 UNORM BLOCK
392 BASE_FORMAT_UNDEFINED, // undefined
393 // BC7 SRGB BLOCK
394 BASE_FORMAT_BC7_UNORM_BLOCK,
395
396 // ETC2 R8G8B8 UNORM BLOCK
397 BASE_FORMAT_UNDEFINED, // undefined
398 // ETC2 R8G8B8 SRGB BLOCK
399 BASE_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
400 // ETC2 R8G8B8A1 UNORM BLOCK
401 BASE_FORMAT_UNDEFINED,
402 // ETC2 R8G8B8A1 SRGB BLOCK
403 BASE_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
404 // ETC2 R8G8B8A8 UNORM BLOCK
405 BASE_FORMAT_UNDEFINED,
406 // ETC2 R8G8B8A8 SRGB BLOCK
407 BASE_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
408
409 // EAC R11 UNORM BLOCK
410 BASE_FORMAT_UNDEFINED, // undefined
411 // EAC R11 SNORM BLOCK
412 BASE_FORMAT_EAC_R11_UNORM_BLOCK,
413 // EAC R11G11 UNORM BLOCK
414 BASE_FORMAT_UNDEFINED, // undefined
415 // EAC R11G11 SNORM BLOCK
416 BASE_FORMAT_EAC_R11G11_UNORM_BLOCK,
417
418 // ASTC 4x4 UNORM BLOCK
419 BASE_FORMAT_UNDEFINED, // undefined
420 // ASTC 4x4 SRGB BLOCK
421 BASE_FORMAT_ASTC_4x4_UNORM_BLOCK,
422 // ASTC 5x4 UNORM BLOCK
423 BASE_FORMAT_UNDEFINED, // undefined
424 // ASTC 5x4 SRGB BLOCK
425 BASE_FORMAT_ASTC_5x4_UNORM_BLOCK,
426 // ASTC 5x5 UNORM BLOCK
427 BASE_FORMAT_UNDEFINED, // undefined
428 // ASTC 5x5 SRGB BLOCK
429 BASE_FORMAT_ASTC_5x5_UNORM_BLOCK,
430 // ASTC 6x5 UNORM BLOCK
431 BASE_FORMAT_UNDEFINED, // undefined
432 // ASTC 6x5 SRGB BLOCK
433 BASE_FORMAT_ASTC_6x5_UNORM_BLOCK,
434 // ASTC 6x6 UNORM BLOCK
435 BASE_FORMAT_UNDEFINED, // undefined
436 // ASTC 6x6 SRGB BLOCK
437 BASE_FORMAT_ASTC_6x6_UNORM_BLOCK,
438 // ASTC 8x5 UNORM BLOCK
439 BASE_FORMAT_UNDEFINED, // undefined
440 // ASTC 8x5 SRGB BLOCK
441 BASE_FORMAT_ASTC_8x5_UNORM_BLOCK,
442 // ASTC 8x6 UNORM BLOCK
443 BASE_FORMAT_UNDEFINED, // undefined
444 // ASTC 8x6 SRGB BLOCK
445 BASE_FORMAT_ASTC_8x6_UNORM_BLOCK,
446 // ASTC 8x8 UNORM BLOCK
447 BASE_FORMAT_UNDEFINED, // undefined
448 // ASTC 8x8 SRGB BLOCK
449 BASE_FORMAT_ASTC_8x8_UNORM_BLOCK,
450 // ASTC 10x5 UNORM BLOCK
451 BASE_FORMAT_UNDEFINED, // undefined
452 // ASTC 10x5 SRGB BLOCK
453 BASE_FORMAT_ASTC_10x5_UNORM_BLOCK,
454 // ASTC 10x6 UNORM BLOCK
455 BASE_FORMAT_UNDEFINED, // undefined
456 // ASTC 10x6 SRGB BLOCK
457 BASE_FORMAT_ASTC_10x6_UNORM_BLOCK,
458 // ASTC 10x8 UNORM BLOCK
459 BASE_FORMAT_UNDEFINED, // undefined
460 // ASTC 10x8 SRGB BLOCK
461 BASE_FORMAT_ASTC_10x8_UNORM_BLOCK,
462 // ASTC 10x10 UNORM BLOCK
463 BASE_FORMAT_UNDEFINED, // undefined
464 // ASTC 10x10 SRGB BLOCK
465 BASE_FORMAT_ASTC_10x10_UNORM_BLOCK,
466 // ASTC 12x10 UNORM BLOCK
467 BASE_FORMAT_UNDEFINED, // undefined
468 // ASTC 12x10 SRGB BLOCK
469 BASE_FORMAT_ASTC_12x10_UNORM_BLOCK,
470 // ASTC 12x12 UNORM BLOCK
471 BASE_FORMAT_UNDEFINED, // undefined
472 // ASTC 12x12 SRGB BLOCK
473 BASE_FORMAT_ASTC_12x12_UNORM_BLOCK,
474 };
475
476 constexpr const auto LINEAR_FORMAT_COUNT = BASE_NS::Format::BASE_FORMAT_ASTC_12x12_SRGB_BLOCK + 1u;
477 PLUGIN_STATIC_ASSERT(BASE_NS::countof(FALLBACK_FORMATS) == LINEAR_FORMAT_COUNT);
478
FillColorSpaceSrgbAsLinearFormats(unordered_map<Format,Format> & formats)479 void FillColorSpaceSrgbAsLinearFormats(unordered_map<Format, Format>& formats)
480 {
481 formats[BASE_FORMAT_R8_SRGB] = BASE_FORMAT_R8_UNORM;
482 formats[BASE_FORMAT_R8G8_SRGB] = BASE_FORMAT_R8G8_UNORM;
483 formats[BASE_FORMAT_R8G8B8_SRGB] = BASE_FORMAT_R8G8B8_UNORM;
484 formats[BASE_FORMAT_B8G8R8_SRGB] = BASE_FORMAT_B8G8R8_UNORM;
485 formats[BASE_FORMAT_R8G8B8A8_SRGB] = BASE_FORMAT_R8G8B8A8_UNORM;
486 formats[BASE_FORMAT_B8G8R8A8_SRGB] = BASE_FORMAT_B8G8R8A8_UNORM;
487 formats[BASE_FORMAT_A8B8G8R8_SRGB_PACK32] = BASE_FORMAT_A8B8G8R8_UNORM_PACK32;
488 formats[BASE_FORMAT_BC1_RGB_SRGB_BLOCK] = BASE_FORMAT_BC1_RGB_UNORM_BLOCK;
489 formats[BASE_FORMAT_BC1_RGBA_SRGB_BLOCK] = BASE_FORMAT_BC1_RGBA_UNORM_BLOCK;
490 formats[BASE_FORMAT_BC2_SRGB_BLOCK] = BASE_FORMAT_BC2_UNORM_BLOCK;
491 formats[BASE_FORMAT_BC3_SRGB_BLOCK] = BASE_FORMAT_BC3_UNORM_BLOCK;
492 formats[BASE_FORMAT_BC7_SRGB_BLOCK] = BASE_FORMAT_BC7_UNORM_BLOCK;
493 formats[BASE_FORMAT_ETC2_R8G8B8_SRGB_BLOCK] = BASE_FORMAT_ETC2_R8G8B8_UNORM_BLOCK;
494 formats[BASE_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK] = BASE_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK;
495 formats[BASE_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK] = BASE_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK;
496 formats[BASE_FORMAT_ASTC_4x4_SRGB_BLOCK] = BASE_FORMAT_ASTC_4x4_UNORM_BLOCK;
497 formats[BASE_FORMAT_ASTC_5x4_SRGB_BLOCK] = BASE_FORMAT_ASTC_5x4_UNORM_BLOCK;
498 formats[BASE_FORMAT_ASTC_5x5_SRGB_BLOCK] = BASE_FORMAT_ASTC_5x5_UNORM_BLOCK;
499 formats[BASE_FORMAT_ASTC_6x5_SRGB_BLOCK] = BASE_FORMAT_ASTC_6x5_UNORM_BLOCK;
500 formats[BASE_FORMAT_ASTC_6x6_SRGB_BLOCK] = BASE_FORMAT_ASTC_6x6_UNORM_BLOCK;
501 formats[BASE_FORMAT_ASTC_8x5_SRGB_BLOCK] = BASE_FORMAT_ASTC_8x5_UNORM_BLOCK;
502 formats[BASE_FORMAT_ASTC_8x6_SRGB_BLOCK] = BASE_FORMAT_ASTC_8x6_UNORM_BLOCK;
503 formats[BASE_FORMAT_ASTC_8x8_SRGB_BLOCK] = BASE_FORMAT_ASTC_8x8_UNORM_BLOCK;
504 formats[BASE_FORMAT_ASTC_10x5_SRGB_BLOCK] = BASE_FORMAT_ASTC_10x5_UNORM_BLOCK;
505 formats[BASE_FORMAT_ASTC_10x6_SRGB_BLOCK] = BASE_FORMAT_ASTC_10x6_UNORM_BLOCK;
506 formats[BASE_FORMAT_ASTC_10x8_SRGB_BLOCK] = BASE_FORMAT_ASTC_10x8_UNORM_BLOCK;
507 formats[BASE_FORMAT_ASTC_10x10_SRGB_BLOCK] = BASE_FORMAT_ASTC_10x10_UNORM_BLOCK;
508 formats[BASE_FORMAT_ASTC_12x10_SRGB_BLOCK] = BASE_FORMAT_ASTC_12x10_UNORM_BLOCK;
509 formats[BASE_FORMAT_ASTC_12x12_SRGB_BLOCK] = BASE_FORMAT_ASTC_12x12_UNORM_BLOCK;
510 }
511
FillColorSpaceLinearFormats(unordered_map<Format,Format> & formats)512 void FillColorSpaceLinearFormats(unordered_map<Format, Format>& formats)
513 {
514 formats[BASE_FORMAT_R8_UNORM] = BASE_FORMAT_R8_SRGB;
515 formats[BASE_FORMAT_R8G8_UNORM] = BASE_FORMAT_R8G8_SRGB;
516 formats[BASE_FORMAT_R8G8B8_UNORM] = BASE_FORMAT_R8G8B8_SRGB;
517 formats[BASE_FORMAT_B8G8R8_UNORM] = BASE_FORMAT_B8G8R8_SRGB;
518 formats[BASE_FORMAT_R8G8B8A8_UNORM] = BASE_FORMAT_R8G8B8A8_SRGB;
519 formats[BASE_FORMAT_B8G8R8A8_UNORM] = BASE_FORMAT_B8G8R8A8_SRGB;
520 formats[BASE_FORMAT_A8B8G8R8_UNORM_PACK32] = BASE_FORMAT_A8B8G8R8_SRGB_PACK32;
521 formats[BASE_FORMAT_BC1_RGB_UNORM_BLOCK] = BASE_FORMAT_BC1_RGB_SRGB_BLOCK;
522 formats[BASE_FORMAT_BC1_RGBA_UNORM_BLOCK] = BASE_FORMAT_BC1_RGBA_SRGB_BLOCK;
523 formats[BASE_FORMAT_BC2_UNORM_BLOCK] = BASE_FORMAT_BC2_SRGB_BLOCK;
524 formats[BASE_FORMAT_BC3_UNORM_BLOCK] = BASE_FORMAT_BC3_SRGB_BLOCK;
525 formats[BASE_FORMAT_BC7_UNORM_BLOCK] = BASE_FORMAT_BC7_SRGB_BLOCK;
526 formats[BASE_FORMAT_ETC2_R8G8B8_UNORM_BLOCK] = BASE_FORMAT_ETC2_R8G8B8_SRGB_BLOCK;
527 formats[BASE_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK] = BASE_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK;
528 formats[BASE_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK] = BASE_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK;
529 formats[BASE_FORMAT_ASTC_4x4_UNORM_BLOCK] = BASE_FORMAT_ASTC_4x4_SRGB_BLOCK;
530 formats[BASE_FORMAT_ASTC_5x4_UNORM_BLOCK] = BASE_FORMAT_ASTC_5x4_SRGB_BLOCK;
531 formats[BASE_FORMAT_ASTC_5x5_UNORM_BLOCK] = BASE_FORMAT_ASTC_5x5_SRGB_BLOCK;
532 formats[BASE_FORMAT_ASTC_6x5_UNORM_BLOCK] = BASE_FORMAT_ASTC_6x5_SRGB_BLOCK;
533 formats[BASE_FORMAT_ASTC_6x6_UNORM_BLOCK] = BASE_FORMAT_ASTC_6x6_SRGB_BLOCK;
534 formats[BASE_FORMAT_ASTC_8x5_UNORM_BLOCK] = BASE_FORMAT_ASTC_8x5_SRGB_BLOCK;
535 formats[BASE_FORMAT_ASTC_8x6_UNORM_BLOCK] = BASE_FORMAT_ASTC_8x6_SRGB_BLOCK;
536 formats[BASE_FORMAT_ASTC_8x8_UNORM_BLOCK] = BASE_FORMAT_ASTC_8x8_SRGB_BLOCK;
537 formats[BASE_FORMAT_ASTC_10x5_UNORM_BLOCK] = BASE_FORMAT_ASTC_10x5_SRGB_BLOCK;
538 formats[BASE_FORMAT_ASTC_10x6_UNORM_BLOCK] = BASE_FORMAT_ASTC_10x6_SRGB_BLOCK;
539 formats[BASE_FORMAT_ASTC_10x8_UNORM_BLOCK] = BASE_FORMAT_ASTC_10x8_SRGB_BLOCK;
540 formats[BASE_FORMAT_ASTC_10x10_UNORM_BLOCK] = BASE_FORMAT_ASTC_10x10_SRGB_BLOCK;
541 formats[BASE_FORMAT_ASTC_12x10_UNORM_BLOCK] = BASE_FORMAT_ASTC_12x10_SRGB_BLOCK;
542 formats[BASE_FORMAT_ASTC_12x12_UNORM_BLOCK] = BASE_FORMAT_ASTC_12x12_SRGB_BLOCK;
543 }
544
CreateDepthBuffer(const Swapchain & swapchain,GpuResourceManager & gpuResourceManager,Device::InternalSwapchainData & swapchainData)545 void CreateDepthBuffer(
546 const Swapchain& swapchain, GpuResourceManager& gpuResourceManager, Device::InternalSwapchainData& swapchainData)
547 {
548 #if (RENDER_VALIDATION_ENABLED == 1)
549 PLUGIN_LOG_I("RENDER_VALIDATION: Default swapchain depth buffer created.");
550 #endif
551 swapchainData.additionalDepthBufferHandle = gpuResourceManager.Create(
552 DefaultEngineGpuResourceConstants::CORE_DEFAULT_BACKBUFFER_DEPTH, swapchain.GetDescDepthBuffer());
553 }
554 } // namespace
555
Device(RenderContext & renderContext,const DeviceCreateInfo & deviceCreateInfo)556 Device::Device(RenderContext& renderContext, const DeviceCreateInfo& deviceCreateInfo)
557 : renderContext_(renderContext), deviceConfiguration_(deviceCreateInfo.deviceConfiguration)
558 {
559 if ((deviceConfiguration_.bufferingCount < MIN_BUFFERING_COUNT) ||
560 (deviceConfiguration_.bufferingCount > MAX_BUFFERING_COUNT)) {
561 deviceConfiguration_.bufferingCount =
562 std::clamp(deviceConfiguration_.bufferingCount, MIN_BUFFERING_COUNT, MAX_BUFFERING_COUNT);
563 PLUGIN_LOG_D("buffering count clamped to: %u", deviceConfiguration_.bufferingCount);
564 }
565 FillColorSpaceLinearFormats(colorSpaceLinearFormats_);
566 FillColorSpaceSrgbAsLinearFormats(colorSpaceSrgbAsLinearFormats_);
567 }
568
CreateSwapchainImpl(const SwapchainCreateInfo & swapchainCreateInfo,const RenderHandleReference & replacedHandle,const string_view name)569 RenderHandleReference Device::CreateSwapchainImpl(
570 const SwapchainCreateInfo& swapchainCreateInfo, const RenderHandleReference& replacedHandle, const string_view name)
571 {
572 Activate();
573 // NOTE: with optimal implementation shouldn't be needed here
574 WaitForIdle();
575
576 auto swapchainIdx = static_cast<uint32_t>(swapchains_.size());
577 bool replace = false;
578 // check if the handle needs to be replaced
579 RenderHandleReference finalReplaceHandle = replacedHandle;
580 {
581 const RenderHandle rawReplaceHandle = finalReplaceHandle.GetHandle();
582 const bool checkReplaceHandle = RenderHandleUtil::IsValid(rawReplaceHandle);
583 const bool checkReplaceWindow = (swapchainCreateInfo.window.window != 0);
584 const bool checkReplaceSurface = (swapchainCreateInfo.surfaceHandle != 0);
585 for (uint32_t idx = 0; idx < swapchains_.size(); ++idx) {
586 const auto& cmpSwap = swapchains_[idx];
587 // if window is the same, or surface is the same, or handle is the same
588 // -> re-use the old handle
589 replace = replace || (checkReplaceWindow && (cmpSwap.window == swapchainCreateInfo.window.window));
590 replace = replace || (checkReplaceSurface && (cmpSwap.surfaceHandle == swapchainCreateInfo.surfaceHandle));
591 replace = replace ||
592 (checkReplaceHandle && ((cmpSwap.remappableSwapchainImage.GetHandle() == rawReplaceHandle) ||
593 (cmpSwap.remappableAdditionalSwapchainImage == rawReplaceHandle)));
594 if (replace) {
595 #if (RENDER_VALIDATION_ENABLED == 1)
596 {
597 RenderHandle printHandle = cmpSwap.remappableSwapchainImage.GetHandle();
598 if (!RenderHandleUtil::IsValid(printHandle)) {
599 printHandle = cmpSwap.remappableAdditionalSwapchainImage;
600 }
601 PLUGIN_LOG_I("RENDER_VALIDATION: Replacing old swapchain handle %" PRIx64, printHandle.id);
602 }
603 #endif
604 swapchainIdx = idx;
605 finalReplaceHandle = swapchains_[swapchainIdx].remappableSwapchainImage;
606 swapchains_[swapchainIdx] = {};
607 DestroyDeviceSwapchain(); // NOTE: GLES handling
608 break;
609 }
610 }
611 }
612
613 if ((!replace) && (swapchains_.size() == DeviceConstants::MAX_SWAPCHAIN_COUNT)) {
614 PLUGIN_LOG_W("Only (%u) swapchains supported.", DeviceConstants::MAX_SWAPCHAIN_COUNT);
615 Deactivate();
616 return {};
617 }
618
619 if (!replace) {
620 swapchains_.push_back({});
621 }
622 auto& swapchainData = swapchains_[swapchainIdx];
623 swapchainData = {};
624 swapchainData.swapchain = CreateDeviceSwapchain(swapchainCreateInfo);
625 if (!swapchainData.swapchain) {
626 Deactivate();
627 return {};
628 }
629
630 {
631 vector<unique_ptr<GpuImage>> swapchainGpuImages = CreateGpuImageViews(*swapchainData.swapchain);
632 Deactivate();
633
634 // create shallow handle with handle in the name
635 GpuImageDesc shallowDesc = swapchainData.swapchain->GetDesc();
636 shallowDesc.width = 2u;
637 shallowDesc.height = 2u;
638 swapchainData.surfaceHandle = swapchainCreateInfo.surfaceHandle;
639 swapchainData.window = swapchainCreateInfo.window.window;
640 swapchainData.globalName = name;
641 swapchainData.name = DefaultEngineGpuResourceConstants::CORE_DEFAULT_SWAPCHAIN +
642 to_hex(swapchainData.swapchain->GetSurfaceHandle()) + '_';
643 swapchainData.remappableSwapchainImage =
644 gpuResourceMgr_->CreateSwapchainImage(finalReplaceHandle, name, shallowDesc);
645 PLUGIN_ASSERT(SwapchainData::MAX_IMAGE_VIEW_COUNT >= static_cast<uint32_t>(swapchainGpuImages.size()));
646 swapchainData.imageViewCount = static_cast<uint32_t>(swapchainGpuImages.size());
647 for (uint32_t idx = 0; idx < swapchainGpuImages.size(); ++idx) {
648 const auto& ref = swapchainGpuImages[idx];
649 swapchainData.imageViews[idx] = gpuResourceMgr_->CreateView(
650 swapchainData.name + to_string(idx), ref->GetDesc(), ref->GetBasePlatformData());
651 }
652
653 Activate();
654 }
655 {
656 Deactivate();
657 if (swapchainData.imageViewCount > 0U) {
658 const RenderHandle firstSwapchain = swapchainData.imageViews[0U].GetHandle();
659 gpuResourceMgr_->RemapGpuImageHandle(swapchainData.remappableSwapchainImage.GetHandle(), firstSwapchain);
660 // check for default swapchain existance and remap
661 if (!defaultSwapchainHandle_) {
662 const RenderHandle shallowHandle =
663 gpuResourceMgr_->GetImageRawHandle(DefaultEngineGpuResourceConstants::CORE_DEFAULT_BACKBUFFER);
664 gpuResourceMgr_->RemapGpuImageHandle(shallowHandle, firstSwapchain);
665 swapchainData.remappableAdditionalSwapchainImage = shallowHandle;
666 // store, that we use default built-in swapchain for backbuffer
667 defaultSwapchainHandle_ = swapchainData.remappableSwapchainImage;
668 }
669 }
670 }
671
672 // configure automatically backbuffer as swapchain
673 {
674 IRenderDataStoreManager& rdsm = renderContext_.GetRenderDataStoreManager();
675 refcnt_ptr<IRenderDataStorePod> dataStorePod = rdsm.GetRenderDataStore(RenderDataStorePod::TYPE_NAME);
676 if (dataStorePod) {
677 auto const dataView = dataStorePod->Get("NodeGraphBackBufferConfiguration");
678 PLUGIN_ASSERT(dataView.size_bytes() == sizeof(NodeGraphBackBufferConfiguration));
679 NodeGraphBackBufferConfiguration ngbbc = *(const NodeGraphBackBufferConfiguration*)dataView.data();
680 StringUtil::CopyStringToArray(DefaultEngineGpuResourceConstants::CORE_DEFAULT_BACKBUFFER,
681 ngbbc.backBufferName, NodeGraphBackBufferConfiguration::CORE_MAX_BACK_BUFFER_NAME_LENGTH);
682 ngbbc.backBufferType = NodeGraphBackBufferConfiguration::BackBufferType::SWAPCHAIN;
683 ngbbc.present = true;
684 dataStorePod->Set("NodeGraphBackBufferConfiguration", arrayviewU8(ngbbc));
685 }
686 }
687 if ((defaultSwapchainHandle_.GetHandle() == swapchainData.remappableSwapchainImage.GetHandle()) &&
688 (swapchainCreateInfo.swapchainFlags & SwapchainFlagBits::CORE_SWAPCHAIN_DEPTH_BUFFER_BIT)) {
689 CreateDepthBuffer(*swapchainData.swapchain, *gpuResourceMgr_, swapchainData);
690 }
691 #if (RENDER_VALIDATION_ENABLED == 1)
692 if ((defaultSwapchainHandle_.GetHandle() != swapchainData.remappableSwapchainImage.GetHandle()) &&
693 (swapchainCreateInfo.swapchainFlags & SwapchainFlagBits::CORE_SWAPCHAIN_DEPTH_BUFFER_BIT)) {
694 PLUGIN_LOG_W("RENDER_VALIDATION: Automatic swapchain depth buffer creation supported for default swapchain.");
695 }
696 #endif
697
698 return swapchainData.remappableSwapchainImage;
699 }
700
CreateSwapchainHandle(const SwapchainCreateInfo & swapchainCreateInfo,const RenderHandleReference & replacedHandle,const string_view name)701 RenderHandleReference Device::CreateSwapchainHandle(
702 const SwapchainCreateInfo& swapchainCreateInfo, const RenderHandleReference& replacedHandle, const string_view name)
703 {
704 if (replacedHandle.GetHandle() == defaultSwapchainHandle_.GetHandle()) {
705 // first safety destroy for legacy default swapchain
706 DestroySwapchainImpl(defaultSwapchainHandle_);
707 }
708 return CreateSwapchainImpl(swapchainCreateInfo, replacedHandle, name);
709 }
710
CreateSwapchainHandle(const SwapchainCreateInfo & swapchainCreateInfo)711 RenderHandleReference Device::CreateSwapchainHandle(const SwapchainCreateInfo& swapchainCreateInfo)
712 {
713 // first safety destroy for legacy default swapchain
714 DestroySwapchainImpl(defaultSwapchainHandle_);
715 return CreateSwapchainImpl(swapchainCreateInfo, {}, {});
716 }
717
CreateSwapchain(const SwapchainCreateInfo & swapchainCreateInfo)718 void Device::CreateSwapchain(const SwapchainCreateInfo& swapchainCreateInfo)
719 {
720 // first safety destroy for legacy default swapchain
721 DestroySwapchainImpl(defaultSwapchainHandle_);
722 CreateSwapchainImpl(swapchainCreateInfo, {}, {});
723 }
724
DestroySwapchainImpl(const RenderHandleReference & handle)725 void Device::DestroySwapchainImpl(const RenderHandleReference& handle)
726 {
727 // NOTE: the destruction should be deferred, but we expect this to be called from rendering thread
728 if (isRenderbackendRunning_) {
729 // NOTE: we are currently only sending error message and not trying to prevent
730 PLUGIN_LOG_E("DestroySwapchain called while RenderFrame is running");
731 }
732
733 if (handle) {
734 const RenderHandle rawHandle = handle.GetHandle();
735 for (auto iter = swapchains_.cbegin(); iter != swapchains_.cend(); ++iter) {
736 if (iter->remappableSwapchainImage.GetHandle() == rawHandle) {
737 Activate();
738 WaitForIdle();
739
740 swapchains_.erase(iter);
741
742 DestroyDeviceSwapchain();
743 // remove swapchain configuration from the backbuffer
744 if ((handle.GetHandle() == defaultSwapchainHandle_.GetHandle()) || (!handle)) {
745 IRenderDataStoreManager& rdsm = renderContext_.GetRenderDataStoreManager();
746 refcnt_ptr<IRenderDataStorePod> dataStorePod =
747 rdsm.GetRenderDataStore(RenderDataStorePod::TYPE_NAME);
748 if (dataStorePod) {
749 auto const dataView = dataStorePod->Get("NodeGraphBackBufferConfiguration");
750 PLUGIN_ASSERT(dataView.size_bytes() == sizeof(NodeGraphBackBufferConfiguration));
751 NodeGraphBackBufferConfiguration ngbbc =
752 *(const NodeGraphBackBufferConfiguration*)dataView.data();
753 if (ngbbc.backBufferType == NodeGraphBackBufferConfiguration::BackBufferType::SWAPCHAIN) {
754 ngbbc.backBufferType = NodeGraphBackBufferConfiguration::BackBufferType::UNDEFINED;
755 ngbbc.present = false;
756 }
757 dataStorePod->Set("NodeGraphBackBufferConfiguration", arrayviewU8(ngbbc));
758 }
759 }
760 Deactivate();
761
762 // destroy default swapchain handle if it was in use
763 if (handle.GetHandle() == defaultSwapchainHandle_.GetHandle()) {
764 defaultSwapchainHandle_ = {};
765 }
766
767 // element erased -> break
768 break;
769 }
770 }
771 }
772 }
773
DestroySwapchain()774 void Device::DestroySwapchain()
775 {
776 DestroySwapchainImpl(defaultSwapchainHandle_);
777 }
778
DestroySwapchain(const RenderHandleReference & handle)779 void Device::DestroySwapchain(const RenderHandleReference& handle)
780 {
781 DestroySwapchainImpl(handle);
782 }
783
GetSurfaceTransformFlags(const RenderHandle & handle) const784 SurfaceTransformFlags Device::GetSurfaceTransformFlags(const RenderHandle& handle) const
785 {
786 // NOTE: Would need additional locks
787 // the flags should be stored, and the data should not be locked for every frame access
788 if (RenderHandleUtil::IsSwapchain(handle)) {
789 for (const auto& swapchain : swapchains_) {
790 if (((swapchain.remappableSwapchainImage.GetHandle() == handle) ||
791 (swapchain.remappableAdditionalSwapchainImage == handle)) &&
792 (swapchain.swapchain)) {
793 return swapchain.swapchain->GetSurfaceTransformFlags();
794 }
795 }
796 }
797 return 0U;
798 }
799
FrameStart()800 void Device::FrameStart()
801 {
802 ++frameCount_;
803 }
804
FrameEnd()805 void Device::FrameEnd() {}
806
SetDeviceStatus(const bool status)807 void Device::SetDeviceStatus(const bool status)
808 {
809 deviceStatus_.store(status);
810 }
811
GetDeviceStatus() const812 bool Device::GetDeviceStatus() const
813 {
814 return deviceStatus_.load();
815 }
816
GetFrameCount() const817 uint64_t Device::GetFrameCount() const
818 {
819 return frameCount_;
820 }
821
GetCommonDeviceProperties() const822 const CommonDeviceProperties& Device::GetCommonDeviceProperties() const
823 {
824 return commonDeviceProperties_;
825 }
826
GetSharedMemoryPropertyFlags() const827 MemoryPropertyFlags Device::GetSharedMemoryPropertyFlags() const
828 {
829 return deviceSharedMemoryPropertyFlags_;
830 }
831
GetDeviceConfiguration() const832 DeviceConfiguration Device::GetDeviceConfiguration() const
833 {
834 return deviceConfiguration_;
835 }
836
GetCommandBufferingCount() const837 uint32_t Device::GetCommandBufferingCount() const
838 {
839 return deviceConfiguration_.bufferingCount;
840 }
841
HasSwapchain() const842 bool Device::HasSwapchain() const
843 {
844 return (!swapchains_.empty());
845 }
846
GetSwapchain(const RenderHandle handle) const847 const Swapchain* Device::GetSwapchain(const RenderHandle handle) const
848 {
849 const RenderHandle cmpHandle = RenderHandleUtil::IsValid(handle) ? handle : defaultSwapchainHandle_.GetHandle();
850 // NOTE: returns a pointer to data which could be destroyed
851 // if the API documentation and restrictions are not applied by the user
852 for (const auto& swapData : swapchains_) {
853 if (((swapData.remappableSwapchainImage.GetHandle() == cmpHandle) ||
854 (swapData.remappableAdditionalSwapchainImage == cmpHandle)) &&
855 (swapData.swapchain)) {
856 return swapData.swapchain.get();
857 }
858 }
859 return nullptr;
860 }
861
GetSwapchainData(const RenderHandle handle) const862 Device::SwapchainData Device::GetSwapchainData(const RenderHandle handle) const
863 {
864 PLUGIN_ASSERT(isRenderbackendRunning_);
865
866 const RenderHandle cmpHandle = RenderHandleUtil::IsValid(handle) ? handle : defaultSwapchainHandle_.GetHandle();
867 for (const auto& swapData : swapchains_) {
868 if (((swapData.remappableSwapchainImage.GetHandle() == cmpHandle) ||
869 (swapData.remappableAdditionalSwapchainImage == cmpHandle)) &&
870 (swapData.swapchain)) {
871 SwapchainData sd;
872 // comparison handle should be a valid handle here and is used in image re-mapping
873 sd.remappableSwapchainImage = cmpHandle;
874 PLUGIN_ASSERT(swapData.imageViewCount <= SwapchainData::MAX_IMAGE_VIEW_COUNT);
875 sd.imageViewCount = swapData.imageViewCount;
876 for (uint32_t idx = 0; idx < swapData.imageViewCount; ++idx) {
877 sd.imageViews[idx] = swapData.imageViews[idx].GetHandle();
878 }
879 return sd;
880 }
881 }
882 return {};
883 }
884
SetLockResourceBackendAccess(const bool value)885 void Device::SetLockResourceBackendAccess(const bool value)
886 {
887 isBackendResourceAccessLocked_ = value;
888 }
889
GetLockResourceBackendAccess() const890 bool Device::GetLockResourceBackendAccess() const
891 {
892 return isBackendResourceAccessLocked_;
893 }
894
SetRenderBackendRunning(const bool value)895 void Device::SetRenderBackendRunning(const bool value)
896 {
897 isRenderbackendRunning_ = value;
898 }
899
SetRenderFrameRunning(const bool value)900 void Device::SetRenderFrameRunning(const bool value)
901 {
902 isRenderFrameRunning_ = value;
903 }
904
GetRenderFrameRunning() const905 bool Device::GetRenderFrameRunning() const
906 {
907 return isRenderFrameRunning_;
908 }
909
GetGpuResourceManager() const910 IGpuResourceManager& Device::GetGpuResourceManager() const
911 {
912 return *gpuResourceMgr_;
913 }
914
GetShaderManager() const915 IShaderManager& Device::GetShaderManager() const
916 {
917 return *shaderMgr_;
918 }
919
GetDescriptorSetManager() const920 DescriptorSetManager& Device::GetDescriptorSetManager() const
921 {
922 return *globalDescriptorSetMgr_;
923 }
924
SetBackendConfig(const BackendConfig & config)925 void Device::SetBackendConfig(const BackendConfig& config) {}
926
GetFormatOrFallback(const Format inputFormat) const927 Format Device::GetFormatOrFallback(const Format inputFormat) const
928 {
929 Format format = inputFormat;
930 if (static_cast<uint32_t>(format) < LINEAR_FORMAT_COUNT) {
931 auto properties = GetFormatProperties(format);
932 #if (RENDER_VALIDATION_ENABLED == 1)
933 uint32_t fallbackCount = 0U;
934 #endif
935 while (format != Format::BASE_FORMAT_UNDEFINED && !properties.linearTilingFeatures &&
936 !properties.optimalTilingFeatures) {
937 format = FALLBACK_FORMATS[format];
938 properties = GetFormatProperties(format);
939 #if (RENDER_VALIDATION_ENABLED == 1)
940 fallbackCount++;
941 #endif
942 }
943 #if (RENDER_VALIDATION_ENABLED == 1)
944 if (fallbackCount > 0U) {
945 PLUGIN_LOG_I("RENDER_VALIDATION: input format (%u) fallback format (%u)",
946 static_cast<uint32_t>(inputFormat), static_cast<uint32_t>(format));
947 }
948 #endif
949 }
950 return format;
951 }
952
GetColorSpaceFlags() const953 ColorSpaceFlags Device::GetColorSpaceFlags() const
954 {
955 return renderContext_.GetColorSpaceFlags();
956 }
957
GetColorSpaceFormat(const Format inputFormat,const ColorSpaceFlags flags) const958 Format Device::GetColorSpaceFormat(const Format inputFormat, const ColorSpaceFlags flags) const
959 {
960 Format format = inputFormat;
961 const auto& formats = (flags & ColorSpaceFlagBits::COLOR_SPACE_SRGB_AS_LINEAR_BIT) ? colorSpaceSrgbAsLinearFormats_
962 : colorSpaceLinearFormats_;
963 if (auto iter = formats.find(format); iter != formats.cend()) {
964 format = iter->second;
965 }
966 return format;
967 }
968 RENDER_END_NAMESPACE()
969