18bf80f4bSopenharmony_ci/*
28bf80f4bSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd.
38bf80f4bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
48bf80f4bSopenharmony_ci * you may not use this file except in compliance with the License.
58bf80f4bSopenharmony_ci * You may obtain a copy of the License at
68bf80f4bSopenharmony_ci *
78bf80f4bSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
88bf80f4bSopenharmony_ci *
98bf80f4bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
108bf80f4bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
118bf80f4bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
128bf80f4bSopenharmony_ci * See the License for the specific language governing permissions and
138bf80f4bSopenharmony_ci * limitations under the License.
148bf80f4bSopenharmony_ci */
158bf80f4bSopenharmony_ci
168bf80f4bSopenharmony_ci#include "device.h"
178bf80f4bSopenharmony_ci
188bf80f4bSopenharmony_ci#include <algorithm>
198bf80f4bSopenharmony_ci#include <cinttypes>
208bf80f4bSopenharmony_ci#include <cstdint>
218bf80f4bSopenharmony_ci
228bf80f4bSopenharmony_ci#include <base/containers/array_view.h>
238bf80f4bSopenharmony_ci#include <base/containers/fixed_string.h>
248bf80f4bSopenharmony_ci#include <base/containers/string.h>
258bf80f4bSopenharmony_ci#include <base/containers/string_view.h>
268bf80f4bSopenharmony_ci#include <base/containers/type_traits.h>
278bf80f4bSopenharmony_ci#include <base/containers/unique_ptr.h>
288bf80f4bSopenharmony_ci#include <base/containers/vector.h>
298bf80f4bSopenharmony_ci#include <base/util/formats.h>
308bf80f4bSopenharmony_ci#include <render/datastore/intf_render_data_store_manager.h>
318bf80f4bSopenharmony_ci#include <render/datastore/render_data_store_render_pods.h>
328bf80f4bSopenharmony_ci#include <render/device/intf_device.h>
338bf80f4bSopenharmony_ci#include <render/device/pipeline_state_desc.h>
348bf80f4bSopenharmony_ci#include <render/namespace.h>
358bf80f4bSopenharmony_ci#include <render/resource_handle.h>
368bf80f4bSopenharmony_ci
378bf80f4bSopenharmony_ci#include "datastore/render_data_store_pod.h"
388bf80f4bSopenharmony_ci#include "default_engine_constants.h"
398bf80f4bSopenharmony_ci#include "device/gpu_resource_manager.h"
408bf80f4bSopenharmony_ci#include "device/shader_manager.h"
418bf80f4bSopenharmony_ci#include "device/swapchain.h"
428bf80f4bSopenharmony_ci#include "render_context.h"
438bf80f4bSopenharmony_ci#include "util/log.h"
448bf80f4bSopenharmony_ci#include "util/string_util.h"
458bf80f4bSopenharmony_ci
468bf80f4bSopenharmony_ci#if (RENDER_HAS_VULKAN_BACKEND)
478bf80f4bSopenharmony_ci#include "vulkan/device_vk.h"
488bf80f4bSopenharmony_ci#include "vulkan/swapchain_vk.h"
498bf80f4bSopenharmony_ci#endif
508bf80f4bSopenharmony_ci
518bf80f4bSopenharmony_ci#if (RENDER_HAS_GL_BACKEND) || (RENDER_HAS_GLES_BACKEND)
528bf80f4bSopenharmony_ci#include "gles/device_gles.h"
538bf80f4bSopenharmony_ci#include "gles/swapchain_gles.h"
548bf80f4bSopenharmony_ci#endif
558bf80f4bSopenharmony_ci
568bf80f4bSopenharmony_ciusing namespace BASE_NS;
578bf80f4bSopenharmony_ci
588bf80f4bSopenharmony_ciRENDER_BEGIN_NAMESPACE()
598bf80f4bSopenharmony_ciclass IGpuResourceManager;
608bf80f4bSopenharmony_ciclass IShaderManager;
618bf80f4bSopenharmony_ciPLUGIN_STATIC_ASSERT(BASE_NS::Format::BASE_FORMAT_ASTC_12x12_SRGB_BLOCK == 184u);
628bf80f4bSopenharmony_ciPLUGIN_STATIC_ASSERT(BASE_NS::Format::BASE_FORMAT_G8B8G8R8_422_UNORM == 1000156000u);
638bf80f4bSopenharmony_ci
648bf80f4bSopenharmony_cinamespace {
658bf80f4bSopenharmony_cistatic constexpr uint32_t MIN_BUFFERING_COUNT { 2 };
668bf80f4bSopenharmony_cistatic constexpr uint32_t MAX_BUFFERING_COUNT { 4 };
678bf80f4bSopenharmony_ci
688bf80f4bSopenharmony_ciconstexpr const Format FALLBACK_FORMATS[] = {
698bf80f4bSopenharmony_ci    BASE_FORMAT_UNDEFINED,
708bf80f4bSopenharmony_ci
718bf80f4bSopenharmony_ci    // R4G4 UNORM PACK8
728bf80f4bSopenharmony_ci    BASE_FORMAT_R8_UNORM,
738bf80f4bSopenharmony_ci
748bf80f4bSopenharmony_ci    // R4G4B4A4 UNORM PACK16
758bf80f4bSopenharmony_ci    BASE_FORMAT_R16_UNORM,
768bf80f4bSopenharmony_ci    // B4G4R4A4 UNORM PACK16
778bf80f4bSopenharmony_ci    BASE_FORMAT_R4G4B4A4_UNORM_PACK16,
788bf80f4bSopenharmony_ci
798bf80f4bSopenharmony_ci    // R5G6B5 UNORM PACK16
808bf80f4bSopenharmony_ci    BASE_FORMAT_R16_UNORM,
818bf80f4bSopenharmony_ci    // B5G6R5 UNORM PACK16
828bf80f4bSopenharmony_ci    BASE_FORMAT_R5G6B5_UNORM_PACK16,
838bf80f4bSopenharmony_ci
848bf80f4bSopenharmony_ci    // R5G5B5A1 UNORM PACK16
858bf80f4bSopenharmony_ci    BASE_FORMAT_R5G6B5_UNORM_PACK16,
868bf80f4bSopenharmony_ci    // B5G5R5A1 UNORM PACK16
878bf80f4bSopenharmony_ci    BASE_FORMAT_R5G5B5A1_UNORM_PACK16,
888bf80f4bSopenharmony_ci    // A1R5G5B5 UNORM PACK16
898bf80f4bSopenharmony_ci    BASE_FORMAT_R5G5B5A1_UNORM_PACK16,
908bf80f4bSopenharmony_ci
918bf80f4bSopenharmony_ci    // R8 UNORM
928bf80f4bSopenharmony_ci    BASE_FORMAT_UNDEFINED, // undefined
938bf80f4bSopenharmony_ci    // R8 SNORM
948bf80f4bSopenharmony_ci    BASE_FORMAT_R8_UNORM,
958bf80f4bSopenharmony_ci    // R8 USCALED
968bf80f4bSopenharmony_ci    BASE_FORMAT_R8_UNORM,
978bf80f4bSopenharmony_ci    // R8 SSCALED
988bf80f4bSopenharmony_ci    BASE_FORMAT_R8_SNORM,
998bf80f4bSopenharmony_ci    // R8 UINT
1008bf80f4bSopenharmony_ci    BASE_FORMAT_R8_UNORM,
1018bf80f4bSopenharmony_ci    // R8 SINT
1028bf80f4bSopenharmony_ci    BASE_FORMAT_R8_UINT,
1038bf80f4bSopenharmony_ci    // R8 SRGB
1048bf80f4bSopenharmony_ci    BASE_FORMAT_R8_UNORM,
1058bf80f4bSopenharmony_ci
1068bf80f4bSopenharmony_ci    // R8G8 UNORM
1078bf80f4bSopenharmony_ci    BASE_FORMAT_R8G8B8A8_UNORM, // fallback to 32 bits
1088bf80f4bSopenharmony_ci    // R8G8 SNORM
1098bf80f4bSopenharmony_ci    BASE_FORMAT_R8G8_UNORM,
1108bf80f4bSopenharmony_ci    // R8G8 USCALED
1118bf80f4bSopenharmony_ci    BASE_FORMAT_R8G8_UNORM,
1128bf80f4bSopenharmony_ci    // R8G8 SSCALED
1138bf80f4bSopenharmony_ci    BASE_FORMAT_R8G8_SNORM,
1148bf80f4bSopenharmony_ci    // R8G8 UINT
1158bf80f4bSopenharmony_ci    BASE_FORMAT_R8G8_UNORM,
1168bf80f4bSopenharmony_ci    // R8G8 SINT
1178bf80f4bSopenharmony_ci    BASE_FORMAT_R8G8_UINT,
1188bf80f4bSopenharmony_ci    // R8G8 SRGB
1198bf80f4bSopenharmony_ci    BASE_FORMAT_R8G8_UNORM,
1208bf80f4bSopenharmony_ci
1218bf80f4bSopenharmony_ci    // R8G8B8 UNORM
1228bf80f4bSopenharmony_ci    BASE_FORMAT_R8G8B8A8_UNORM, // fallback to 32 bits
1238bf80f4bSopenharmony_ci    // R8G8B8 SNORM
1248bf80f4bSopenharmony_ci    BASE_FORMAT_R8G8B8_UNORM,
1258bf80f4bSopenharmony_ci    // R8G8B8 USCALED
1268bf80f4bSopenharmony_ci    BASE_FORMAT_R8G8B8_UNORM,
1278bf80f4bSopenharmony_ci    // R8G8B8 SSCALED
1288bf80f4bSopenharmony_ci    BASE_FORMAT_R8G8B8_SNORM,
1298bf80f4bSopenharmony_ci    // R8G8B8 UINT
1308bf80f4bSopenharmony_ci    BASE_FORMAT_R8G8B8_UNORM,
1318bf80f4bSopenharmony_ci    // R8G8B8 SINT
1328bf80f4bSopenharmony_ci    BASE_FORMAT_R8G8B8_UINT,
1338bf80f4bSopenharmony_ci    // R8G8B8 SRGB
1348bf80f4bSopenharmony_ci    BASE_FORMAT_R8G8B8_UNORM,
1358bf80f4bSopenharmony_ci
1368bf80f4bSopenharmony_ci    // B8G8R8 UNORM
1378bf80f4bSopenharmony_ci    BASE_FORMAT_B8G8R8A8_UNORM, // fallback to 32 bits
1388bf80f4bSopenharmony_ci    // B8G8R8 SNORM
1398bf80f4bSopenharmony_ci    BASE_FORMAT_B8G8R8_UNORM,
1408bf80f4bSopenharmony_ci    // B8G8R8 USCALED
1418bf80f4bSopenharmony_ci    BASE_FORMAT_B8G8R8_UNORM,
1428bf80f4bSopenharmony_ci    // B8G8R8 SSCALED
1438bf80f4bSopenharmony_ci    BASE_FORMAT_B8G8R8_SNORM,
1448bf80f4bSopenharmony_ci    // B8G8R8 UINT
1458bf80f4bSopenharmony_ci    BASE_FORMAT_B8G8R8_UNORM,
1468bf80f4bSopenharmony_ci    // B8G8R8 SINT
1478bf80f4bSopenharmony_ci    BASE_FORMAT_B8G8R8_UINT,
1488bf80f4bSopenharmony_ci    // B8G8R8 SRGB
1498bf80f4bSopenharmony_ci    BASE_FORMAT_B8G8R8_UNORM,
1508bf80f4bSopenharmony_ci
1518bf80f4bSopenharmony_ci    // R8G8B8A8 UNORM
1528bf80f4bSopenharmony_ci    BASE_FORMAT_UNDEFINED, // undefined
1538bf80f4bSopenharmony_ci    // R8G8B8A8 SNORM
1548bf80f4bSopenharmony_ci    BASE_FORMAT_R8G8B8A8_UNORM,
1558bf80f4bSopenharmony_ci    // R8G8B8A8 USCALED
1568bf80f4bSopenharmony_ci    BASE_FORMAT_R8G8B8A8_UNORM,
1578bf80f4bSopenharmony_ci    // R8G8B8A8 SSCALED
1588bf80f4bSopenharmony_ci    BASE_FORMAT_R8G8B8A8_SNORM,
1598bf80f4bSopenharmony_ci    // R8G8B8A8 UINT
1608bf80f4bSopenharmony_ci    BASE_FORMAT_R8G8B8A8_UNORM,
1618bf80f4bSopenharmony_ci    // R8G8B8A8 SINT
1628bf80f4bSopenharmony_ci    BASE_FORMAT_R8G8B8A8_UINT,
1638bf80f4bSopenharmony_ci    // R8G8B8A8 SRGB
1648bf80f4bSopenharmony_ci    BASE_FORMAT_R8G8B8A8_UNORM,
1658bf80f4bSopenharmony_ci
1668bf80f4bSopenharmony_ci    // B8G8R8A8 UNORM
1678bf80f4bSopenharmony_ci    BASE_FORMAT_R8G8B8A8_UNORM,
1688bf80f4bSopenharmony_ci    // B8G8R8A8 SNORM
1698bf80f4bSopenharmony_ci    BASE_FORMAT_B8G8R8A8_UNORM,
1708bf80f4bSopenharmony_ci    // B8G8R8A8 USCALED
1718bf80f4bSopenharmony_ci    BASE_FORMAT_B8G8R8A8_UNORM,
1728bf80f4bSopenharmony_ci    // B8G8R8A8 SSCALED
1738bf80f4bSopenharmony_ci    BASE_FORMAT_B8G8R8A8_SNORM,
1748bf80f4bSopenharmony_ci    // B8G8R8A8 UINT
1758bf80f4bSopenharmony_ci    BASE_FORMAT_B8G8R8A8_UNORM,
1768bf80f4bSopenharmony_ci    // B8G8R8A8 SINT
1778bf80f4bSopenharmony_ci    BASE_FORMAT_B8G8R8A8_UINT,
1788bf80f4bSopenharmony_ci    // FORMAT B8G8R8A8 SRGB
1798bf80f4bSopenharmony_ci    BASE_FORMAT_B8G8R8A8_SRGB,
1808bf80f4bSopenharmony_ci
1818bf80f4bSopenharmony_ci    // A8B8G8R8 UNORM PACK32
1828bf80f4bSopenharmony_ci    BASE_FORMAT_R8G8B8A8_UNORM,
1838bf80f4bSopenharmony_ci    // A8B8G8R8 SNORM PACK32
1848bf80f4bSopenharmony_ci    BASE_FORMAT_A8B8G8R8_UNORM_PACK32,
1858bf80f4bSopenharmony_ci    // A8B8G8R8 USCALED PACK32
1868bf80f4bSopenharmony_ci    BASE_FORMAT_A8B8G8R8_UNORM_PACK32,
1878bf80f4bSopenharmony_ci    // A8B8G8R8 SSCALED PACK32
1888bf80f4bSopenharmony_ci    BASE_FORMAT_A8B8G8R8_SNORM_PACK32,
1898bf80f4bSopenharmony_ci    // A8B8G8R8 UINT PACK32
1908bf80f4bSopenharmony_ci    BASE_FORMAT_A8B8G8R8_UNORM_PACK32,
1918bf80f4bSopenharmony_ci    // A8B8G8R8 SINT PACK32
1928bf80f4bSopenharmony_ci    BASE_FORMAT_A8B8G8R8_UINT_PACK32,
1938bf80f4bSopenharmony_ci    // A8B8G8R8 SRGB PACK32
1948bf80f4bSopenharmony_ci    BASE_FORMAT_A8B8G8R8_UNORM_PACK32,
1958bf80f4bSopenharmony_ci
1968bf80f4bSopenharmony_ci    // A2R10G10B10 UNORM PACK32
1978bf80f4bSopenharmony_ci    BASE_FORMAT_R8G8B8A8_UNORM,
1988bf80f4bSopenharmony_ci    // A2R10G10B10 SNORM PACK32
1998bf80f4bSopenharmony_ci    BASE_FORMAT_A2R10G10B10_UNORM_PACK32,
2008bf80f4bSopenharmony_ci    // A2R10G10B10 USCALED PACK32
2018bf80f4bSopenharmony_ci    BASE_FORMAT_A2R10G10B10_UNORM_PACK32,
2028bf80f4bSopenharmony_ci    // A2R10G10B10 SSCALED PACK32
2038bf80f4bSopenharmony_ci    BASE_FORMAT_A2R10G10B10_SNORM_PACK32,
2048bf80f4bSopenharmony_ci    // A2R10G10B10 UINT PACK32
2058bf80f4bSopenharmony_ci    BASE_FORMAT_A2R10G10B10_UNORM_PACK32,
2068bf80f4bSopenharmony_ci    // A2R10G10B10 SINT PACK32
2078bf80f4bSopenharmony_ci    BASE_FORMAT_A2R10G10B10_UINT_PACK32,
2088bf80f4bSopenharmony_ci
2098bf80f4bSopenharmony_ci    // A2B10G10R10 UNORM PACK32
2108bf80f4bSopenharmony_ci    BASE_FORMAT_R8G8B8A8_UNORM,
2118bf80f4bSopenharmony_ci    // A2B10G10R10 SNORM PACK32
2128bf80f4bSopenharmony_ci    BASE_FORMAT_A2B10G10R10_UNORM_PACK32,
2138bf80f4bSopenharmony_ci    // A2B10G10R10 USCALED PACK32
2148bf80f4bSopenharmony_ci    BASE_FORMAT_A2B10G10R10_UNORM_PACK32,
2158bf80f4bSopenharmony_ci    // A2B10G10R10 SSCALED PACK32
2168bf80f4bSopenharmony_ci    BASE_FORMAT_A2B10G10R10_SNORM_PACK32,
2178bf80f4bSopenharmony_ci    // A2B10G10R10 UINT PACK32
2188bf80f4bSopenharmony_ci    BASE_FORMAT_A2B10G10R10_UNORM_PACK32,
2198bf80f4bSopenharmony_ci    // A2B10G10R10 SINT PACK32
2208bf80f4bSopenharmony_ci    BASE_FORMAT_A2B10G10R10_UINT_PACK32,
2218bf80f4bSopenharmony_ci
2228bf80f4bSopenharmony_ci    // R16 UNORM
2238bf80f4bSopenharmony_ci    BASE_FORMAT_R8_UNORM, // fallback to 8 bit channel
2248bf80f4bSopenharmony_ci    // R16 SNORM
2258bf80f4bSopenharmony_ci    BASE_FORMAT_R16_UNORM,
2268bf80f4bSopenharmony_ci    // R16 USCALED
2278bf80f4bSopenharmony_ci    BASE_FORMAT_R16_UNORM,
2288bf80f4bSopenharmony_ci    // R16 SSCALED
2298bf80f4bSopenharmony_ci    BASE_FORMAT_R16_SNORM,
2308bf80f4bSopenharmony_ci    // R16 UINT
2318bf80f4bSopenharmony_ci    BASE_FORMAT_R16_UNORM,
2328bf80f4bSopenharmony_ci    // R16 SINT
2338bf80f4bSopenharmony_ci    BASE_FORMAT_R16_UINT,
2348bf80f4bSopenharmony_ci    // R16 SFLOAT
2358bf80f4bSopenharmony_ci    BASE_FORMAT_R16_UNORM,
2368bf80f4bSopenharmony_ci
2378bf80f4bSopenharmony_ci    // R16G16 UNORM
2388bf80f4bSopenharmony_ci    BASE_FORMAT_R16G16B16A16_UNORM, // fallback to 4 channel
2398bf80f4bSopenharmony_ci    // R16G16 SNORM
2408bf80f4bSopenharmony_ci    BASE_FORMAT_R16G16_UNORM,
2418bf80f4bSopenharmony_ci    // R16G16 USCALED
2428bf80f4bSopenharmony_ci    BASE_FORMAT_R16G16_UNORM,
2438bf80f4bSopenharmony_ci    // R16G16 SSCALED
2448bf80f4bSopenharmony_ci    BASE_FORMAT_R16G16_SNORM,
2458bf80f4bSopenharmony_ci    // R16G16 UINT
2468bf80f4bSopenharmony_ci    BASE_FORMAT_R16G16_UNORM,
2478bf80f4bSopenharmony_ci    // R16G16 SINT
2488bf80f4bSopenharmony_ci    BASE_FORMAT_R16G16_UINT,
2498bf80f4bSopenharmony_ci    // R16G16 SFLOAT
2508bf80f4bSopenharmony_ci    BASE_FORMAT_R16G16_UNORM,
2518bf80f4bSopenharmony_ci
2528bf80f4bSopenharmony_ci    // R16G16B16 UNORM
2538bf80f4bSopenharmony_ci    BASE_FORMAT_R16G16B16A16_UNORM, // fallback to 4 channel
2548bf80f4bSopenharmony_ci    // R16G16B16 SNORM
2558bf80f4bSopenharmony_ci    BASE_FORMAT_R16G16B16_UNORM,
2568bf80f4bSopenharmony_ci    // R16G16B16 USCALED
2578bf80f4bSopenharmony_ci    BASE_FORMAT_R16G16B16_UNORM,
2588bf80f4bSopenharmony_ci    // R16G16B16 SSCALED
2598bf80f4bSopenharmony_ci    BASE_FORMAT_R16G16B16_SNORM,
2608bf80f4bSopenharmony_ci    // R16G16B16 UINT
2618bf80f4bSopenharmony_ci    BASE_FORMAT_R16G16B16_UNORM,
2628bf80f4bSopenharmony_ci    // R16G16B16 SINT
2638bf80f4bSopenharmony_ci    BASE_FORMAT_R16G16B16_UINT,
2648bf80f4bSopenharmony_ci    // R16G16B16 SFLOAT
2658bf80f4bSopenharmony_ci    BASE_FORMAT_R16G16B16_UNORM,
2668bf80f4bSopenharmony_ci
2678bf80f4bSopenharmony_ci    // R16G16B16A16 UNORM
2688bf80f4bSopenharmony_ci    BASE_FORMAT_R8G8B8A8_UNORM, // fallback to 8 bit channels
2698bf80f4bSopenharmony_ci    // R16G16B16A16 SNORM
2708bf80f4bSopenharmony_ci    BASE_FORMAT_R16G16B16A16_UNORM,
2718bf80f4bSopenharmony_ci    // R16G16B16A16 USCALED
2728bf80f4bSopenharmony_ci    BASE_FORMAT_R16G16B16A16_UNORM,
2738bf80f4bSopenharmony_ci    // R16G16B16A16 SSCALED
2748bf80f4bSopenharmony_ci    BASE_FORMAT_R16G16B16A16_SNORM,
2758bf80f4bSopenharmony_ci    // R16G16B16A16 UINT
2768bf80f4bSopenharmony_ci    BASE_FORMAT_R16G16B16A16_UNORM,
2778bf80f4bSopenharmony_ci    // R16G16B16A16 SINT
2788bf80f4bSopenharmony_ci    BASE_FORMAT_R16G16B16A16_UINT,
2798bf80f4bSopenharmony_ci    // R16G16B16A16 SFLOAT
2808bf80f4bSopenharmony_ci    BASE_FORMAT_R16G16B16A16_UNORM,
2818bf80f4bSopenharmony_ci
2828bf80f4bSopenharmony_ci    // R32 UINT
2838bf80f4bSopenharmony_ci    BASE_FORMAT_R16_UINT, // fallback to 16 bit channel
2848bf80f4bSopenharmony_ci    // R32 SINT
2858bf80f4bSopenharmony_ci    BASE_FORMAT_R32_UINT,
2868bf80f4bSopenharmony_ci    // R32 SFLOAT
2878bf80f4bSopenharmony_ci    BASE_FORMAT_R32_UINT,
2888bf80f4bSopenharmony_ci
2898bf80f4bSopenharmony_ci    // R32G32 UINT
2908bf80f4bSopenharmony_ci    BASE_FORMAT_R16G16_UINT, // fallback to 16 bit channels
2918bf80f4bSopenharmony_ci    // R32G32 SINT
2928bf80f4bSopenharmony_ci    BASE_FORMAT_R32G32_UINT,
2938bf80f4bSopenharmony_ci    // R32G32 SFLOAT
2948bf80f4bSopenharmony_ci    BASE_FORMAT_R32G32_UINT,
2958bf80f4bSopenharmony_ci
2968bf80f4bSopenharmony_ci    // R32G32B32 UINT
2978bf80f4bSopenharmony_ci    BASE_FORMAT_R32G32B32A32_UINT, // fallback to 4 channels
2988bf80f4bSopenharmony_ci    // R32G32B32 SINT
2998bf80f4bSopenharmony_ci    BASE_FORMAT_R32G32B32_UINT,
3008bf80f4bSopenharmony_ci    // R32G32B32 SFLOAT
3018bf80f4bSopenharmony_ci    BASE_FORMAT_R32G32B32_UINT,
3028bf80f4bSopenharmony_ci
3038bf80f4bSopenharmony_ci    // R32G32B32A32 UINT
3048bf80f4bSopenharmony_ci    BASE_FORMAT_R16G16B16A16_UINT, // fallback to 16 bit channels
3058bf80f4bSopenharmony_ci    // R32G32B32A32 SINT
3068bf80f4bSopenharmony_ci    BASE_FORMAT_R32G32B32A32_UINT,
3078bf80f4bSopenharmony_ci    // R32G32B32A32 SFLOAT
3088bf80f4bSopenharmony_ci    BASE_FORMAT_R32G32B32A32_UINT,
3098bf80f4bSopenharmony_ci
3108bf80f4bSopenharmony_ci    // R64 UINT
3118bf80f4bSopenharmony_ci    BASE_FORMAT_R32_UINT, // fallback to 32 bit channel
3128bf80f4bSopenharmony_ci    // R64 SINT
3138bf80f4bSopenharmony_ci    BASE_FORMAT_R64_UINT,
3148bf80f4bSopenharmony_ci    // R64 SFLOAT
3158bf80f4bSopenharmony_ci    BASE_FORMAT_R64_UINT,
3168bf80f4bSopenharmony_ci
3178bf80f4bSopenharmony_ci    // R64G64 UINT
3188bf80f4bSopenharmony_ci    BASE_FORMAT_R64G64B64A64_UINT, // fallback to 4 channels
3198bf80f4bSopenharmony_ci    // R64G64 SINT
3208bf80f4bSopenharmony_ci    BASE_FORMAT_R64G64_UINT,
3218bf80f4bSopenharmony_ci    // R64G64 SFLOAT
3228bf80f4bSopenharmony_ci    BASE_FORMAT_R64G64_UINT,
3238bf80f4bSopenharmony_ci
3248bf80f4bSopenharmony_ci    // R64G64B64 UINT
3258bf80f4bSopenharmony_ci    BASE_FORMAT_R64G64B64A64_UINT, // fallback to 4 channels
3268bf80f4bSopenharmony_ci    // R64G64B64 SINT
3278bf80f4bSopenharmony_ci    BASE_FORMAT_R64G64B64_UINT,
3288bf80f4bSopenharmony_ci    // R64G64B64 SFLOAT
3298bf80f4bSopenharmony_ci    BASE_FORMAT_R64G64B64_UINT,
3308bf80f4bSopenharmony_ci
3318bf80f4bSopenharmony_ci    // R64G64B64A64 UINT
3328bf80f4bSopenharmony_ci    BASE_FORMAT_R32G32B32A32_UINT, // fallback to 32 bit channels
3338bf80f4bSopenharmony_ci    // R64G64B64A64 SINT
3348bf80f4bSopenharmony_ci    BASE_FORMAT_R64G64B64A64_UINT,
3358bf80f4bSopenharmony_ci    // R32G32B32A32 SFLOAT
3368bf80f4bSopenharmony_ci    BASE_FORMAT_R64G64B64A64_UINT,
3378bf80f4bSopenharmony_ci
3388bf80f4bSopenharmony_ci    // B10G11R11 UFLOAT PACK32
3398bf80f4bSopenharmony_ci    BASE_FORMAT_R16G16B16A16_SFLOAT, // fallback to 4 channel, 16 bit HDR
3408bf80f4bSopenharmony_ci
3418bf80f4bSopenharmony_ci    // E5B9G9R9 UFLOAT PACK32
3428bf80f4bSopenharmony_ci    BASE_FORMAT_R16G16B16A16_SFLOAT, // fallback to 4 channel, 16 bit HDR
3438bf80f4bSopenharmony_ci
3448bf80f4bSopenharmony_ci    // D16 UNORM
3458bf80f4bSopenharmony_ci    BASE_FORMAT_D32_SFLOAT, // fallback to 32 bit depth only
3468bf80f4bSopenharmony_ci    // X8 D24 UNORM PACK32
3478bf80f4bSopenharmony_ci    BASE_FORMAT_D32_SFLOAT,
3488bf80f4bSopenharmony_ci    // D32 SFLOAT
3498bf80f4bSopenharmony_ci    BASE_FORMAT_X8_D24_UNORM_PACK32,
3508bf80f4bSopenharmony_ci    // S8 UINT
3518bf80f4bSopenharmony_ci    BASE_FORMAT_D24_UNORM_S8_UINT,
3528bf80f4bSopenharmony_ci    // D16 UNORM S8 UINT
3538bf80f4bSopenharmony_ci    BASE_FORMAT_D24_UNORM_S8_UINT,
3548bf80f4bSopenharmony_ci    // D24 UNORM S8 UINT
3558bf80f4bSopenharmony_ci    BASE_FORMAT_D32_SFLOAT_S8_UINT,
3568bf80f4bSopenharmony_ci    // D32 SFLOAT S8 UINT
3578bf80f4bSopenharmony_ci    BASE_FORMAT_D24_UNORM_S8_UINT,
3588bf80f4bSopenharmony_ci
3598bf80f4bSopenharmony_ci    // BC1 RGB UNORM BLOCK
3608bf80f4bSopenharmony_ci    BASE_FORMAT_UNDEFINED, // undefined
3618bf80f4bSopenharmony_ci    // BC1 RGB SRGB BLOCK
3628bf80f4bSopenharmony_ci    BASE_FORMAT_BC1_RGB_UNORM_BLOCK,
3638bf80f4bSopenharmony_ci    // BC1 RGBA UNORM BLOCK
3648bf80f4bSopenharmony_ci    BASE_FORMAT_UNDEFINED, // undefined
3658bf80f4bSopenharmony_ci    // BC1 RGBA SRGB BLOCK
3668bf80f4bSopenharmony_ci    BASE_FORMAT_BC1_RGBA_UNORM_BLOCK,
3678bf80f4bSopenharmony_ci    // BC2 UNORM BLOCK
3688bf80f4bSopenharmony_ci    BASE_FORMAT_UNDEFINED, // undefined
3698bf80f4bSopenharmony_ci    // BC2 SRGB BLOCK
3708bf80f4bSopenharmony_ci    BASE_FORMAT_BC2_UNORM_BLOCK,
3718bf80f4bSopenharmony_ci    // BC3 UNORM BLOCK
3728bf80f4bSopenharmony_ci    BASE_FORMAT_UNDEFINED, // undefined
3738bf80f4bSopenharmony_ci    // BC3 SRGB BLOCK
3748bf80f4bSopenharmony_ci    BASE_FORMAT_BC3_UNORM_BLOCK,
3758bf80f4bSopenharmony_ci    // BC4 UNORM BLOCK
3768bf80f4bSopenharmony_ci    BASE_FORMAT_UNDEFINED, // undefined
3778bf80f4bSopenharmony_ci    // BC4 SNORM BLOCK
3788bf80f4bSopenharmony_ci    BASE_FORMAT_BC4_UNORM_BLOCK,
3798bf80f4bSopenharmony_ci    // BC5 UNORM BLOCK
3808bf80f4bSopenharmony_ci    BASE_FORMAT_UNDEFINED, // undefined
3818bf80f4bSopenharmony_ci    // BC5 SNORM BLOCK
3828bf80f4bSopenharmony_ci    BASE_FORMAT_BC5_UNORM_BLOCK,
3838bf80f4bSopenharmony_ci    // BC6H UFLOAT BLOCK
3848bf80f4bSopenharmony_ci    BASE_FORMAT_UNDEFINED, // undefined
3858bf80f4bSopenharmony_ci    // BC6H SFLOAT BLOCK
3868bf80f4bSopenharmony_ci    BASE_FORMAT_BC6H_UFLOAT_BLOCK,
3878bf80f4bSopenharmony_ci    // BC7 UNORM BLOCK
3888bf80f4bSopenharmony_ci    BASE_FORMAT_UNDEFINED, // undefined
3898bf80f4bSopenharmony_ci    // BC7 SRGB BLOCK
3908bf80f4bSopenharmony_ci    BASE_FORMAT_BC7_UNORM_BLOCK,
3918bf80f4bSopenharmony_ci
3928bf80f4bSopenharmony_ci    // ETC2 R8G8B8 UNORM BLOCK
3938bf80f4bSopenharmony_ci    BASE_FORMAT_UNDEFINED, // undefined
3948bf80f4bSopenharmony_ci    // ETC2 R8G8B8 SRGB BLOCK
3958bf80f4bSopenharmony_ci    BASE_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
3968bf80f4bSopenharmony_ci    // ETC2 R8G8B8A1 UNORM BLOCK
3978bf80f4bSopenharmony_ci    BASE_FORMAT_UNDEFINED,
3988bf80f4bSopenharmony_ci    // ETC2 R8G8B8A1 SRGB BLOCK
3998bf80f4bSopenharmony_ci    BASE_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
4008bf80f4bSopenharmony_ci    // ETC2 R8G8B8A8 UNORM BLOCK
4018bf80f4bSopenharmony_ci    BASE_FORMAT_UNDEFINED,
4028bf80f4bSopenharmony_ci    // ETC2 R8G8B8A8 SRGB BLOCK
4038bf80f4bSopenharmony_ci    BASE_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
4048bf80f4bSopenharmony_ci
4058bf80f4bSopenharmony_ci    // EAC R11 UNORM BLOCK
4068bf80f4bSopenharmony_ci    BASE_FORMAT_UNDEFINED, // undefined
4078bf80f4bSopenharmony_ci    // EAC R11 SNORM BLOCK
4088bf80f4bSopenharmony_ci    BASE_FORMAT_EAC_R11_UNORM_BLOCK,
4098bf80f4bSopenharmony_ci    // EAC R11G11 UNORM BLOCK
4108bf80f4bSopenharmony_ci    BASE_FORMAT_UNDEFINED, // undefined
4118bf80f4bSopenharmony_ci    // EAC R11G11 SNORM BLOCK
4128bf80f4bSopenharmony_ci    BASE_FORMAT_EAC_R11G11_UNORM_BLOCK,
4138bf80f4bSopenharmony_ci
4148bf80f4bSopenharmony_ci    // ASTC 4x4 UNORM BLOCK
4158bf80f4bSopenharmony_ci    BASE_FORMAT_UNDEFINED, // undefined
4168bf80f4bSopenharmony_ci    // ASTC 4x4 SRGB BLOCK
4178bf80f4bSopenharmony_ci    BASE_FORMAT_ASTC_4x4_UNORM_BLOCK,
4188bf80f4bSopenharmony_ci    // ASTC 5x4 UNORM BLOCK
4198bf80f4bSopenharmony_ci    BASE_FORMAT_UNDEFINED, // undefined
4208bf80f4bSopenharmony_ci    // ASTC 5x4 SRGB BLOCK
4218bf80f4bSopenharmony_ci    BASE_FORMAT_ASTC_5x4_UNORM_BLOCK,
4228bf80f4bSopenharmony_ci    // ASTC 5x5 UNORM BLOCK
4238bf80f4bSopenharmony_ci    BASE_FORMAT_UNDEFINED, // undefined
4248bf80f4bSopenharmony_ci    // ASTC 5x5 SRGB BLOCK
4258bf80f4bSopenharmony_ci    BASE_FORMAT_ASTC_5x5_UNORM_BLOCK,
4268bf80f4bSopenharmony_ci    // ASTC 6x5 UNORM BLOCK
4278bf80f4bSopenharmony_ci    BASE_FORMAT_UNDEFINED, // undefined
4288bf80f4bSopenharmony_ci    // ASTC 6x5 SRGB BLOCK
4298bf80f4bSopenharmony_ci    BASE_FORMAT_ASTC_6x5_UNORM_BLOCK,
4308bf80f4bSopenharmony_ci    // ASTC 6x6 UNORM BLOCK
4318bf80f4bSopenharmony_ci    BASE_FORMAT_UNDEFINED, // undefined
4328bf80f4bSopenharmony_ci    // ASTC 6x6 SRGB BLOCK
4338bf80f4bSopenharmony_ci    BASE_FORMAT_ASTC_6x6_UNORM_BLOCK,
4348bf80f4bSopenharmony_ci    // ASTC 8x5 UNORM BLOCK
4358bf80f4bSopenharmony_ci    BASE_FORMAT_UNDEFINED, // undefined
4368bf80f4bSopenharmony_ci    // ASTC 8x5 SRGB BLOCK
4378bf80f4bSopenharmony_ci    BASE_FORMAT_ASTC_8x5_UNORM_BLOCK,
4388bf80f4bSopenharmony_ci    // ASTC 8x6 UNORM BLOCK
4398bf80f4bSopenharmony_ci    BASE_FORMAT_UNDEFINED, // undefined
4408bf80f4bSopenharmony_ci    // ASTC 8x6 SRGB BLOCK
4418bf80f4bSopenharmony_ci    BASE_FORMAT_ASTC_8x6_UNORM_BLOCK,
4428bf80f4bSopenharmony_ci    // ASTC 8x8 UNORM BLOCK
4438bf80f4bSopenharmony_ci    BASE_FORMAT_UNDEFINED, // undefined
4448bf80f4bSopenharmony_ci    // ASTC 8x8 SRGB BLOCK
4458bf80f4bSopenharmony_ci    BASE_FORMAT_ASTC_8x8_UNORM_BLOCK,
4468bf80f4bSopenharmony_ci    // ASTC 10x5 UNORM BLOCK
4478bf80f4bSopenharmony_ci    BASE_FORMAT_UNDEFINED, // undefined
4488bf80f4bSopenharmony_ci    // ASTC 10x5 SRGB BLOCK
4498bf80f4bSopenharmony_ci    BASE_FORMAT_ASTC_10x5_UNORM_BLOCK,
4508bf80f4bSopenharmony_ci    // ASTC 10x6 UNORM BLOCK
4518bf80f4bSopenharmony_ci    BASE_FORMAT_UNDEFINED, // undefined
4528bf80f4bSopenharmony_ci    // ASTC 10x6 SRGB BLOCK
4538bf80f4bSopenharmony_ci    BASE_FORMAT_ASTC_10x6_UNORM_BLOCK,
4548bf80f4bSopenharmony_ci    // ASTC 10x8 UNORM BLOCK
4558bf80f4bSopenharmony_ci    BASE_FORMAT_UNDEFINED, // undefined
4568bf80f4bSopenharmony_ci    // ASTC 10x8 SRGB BLOCK
4578bf80f4bSopenharmony_ci    BASE_FORMAT_ASTC_10x8_UNORM_BLOCK,
4588bf80f4bSopenharmony_ci    // ASTC 10x10 UNORM BLOCK
4598bf80f4bSopenharmony_ci    BASE_FORMAT_UNDEFINED, // undefined
4608bf80f4bSopenharmony_ci    // ASTC 10x10 SRGB BLOCK
4618bf80f4bSopenharmony_ci    BASE_FORMAT_ASTC_10x10_UNORM_BLOCK,
4628bf80f4bSopenharmony_ci    // ASTC 12x10 UNORM BLOCK
4638bf80f4bSopenharmony_ci    BASE_FORMAT_UNDEFINED, // undefined
4648bf80f4bSopenharmony_ci    // ASTC 12x10 SRGB BLOCK
4658bf80f4bSopenharmony_ci    BASE_FORMAT_ASTC_12x10_UNORM_BLOCK,
4668bf80f4bSopenharmony_ci    // ASTC 12x12 UNORM BLOCK
4678bf80f4bSopenharmony_ci    BASE_FORMAT_UNDEFINED, // undefined
4688bf80f4bSopenharmony_ci    // ASTC 12x12 SRGB BLOCK
4698bf80f4bSopenharmony_ci    BASE_FORMAT_ASTC_12x12_UNORM_BLOCK,
4708bf80f4bSopenharmony_ci};
4718bf80f4bSopenharmony_ci
4728bf80f4bSopenharmony_ciconstexpr const auto LINEAR_FORMAT_COUNT = BASE_NS::Format::BASE_FORMAT_ASTC_12x12_SRGB_BLOCK + 1u;
4738bf80f4bSopenharmony_ciPLUGIN_STATIC_ASSERT(BASE_NS::countof(FALLBACK_FORMATS) == LINEAR_FORMAT_COUNT);
4748bf80f4bSopenharmony_ci
4758bf80f4bSopenharmony_civoid CreateDepthBuffer(const DeviceBackendType backendType, const Swapchain& swapchain,
4768bf80f4bSopenharmony_ci    GpuResourceManager& gpuResourceManager, Device::InternalSwapchainData& swapchainData)
4778bf80f4bSopenharmony_ci{
4788bf80f4bSopenharmony_ci#if (RENDER_VALIDATION_ENABLED == 1)
4798bf80f4bSopenharmony_ci    PLUGIN_LOG_I("RENDER_VALIDATION: Default swapchain depth buffer created.");
4808bf80f4bSopenharmony_ci#endif
4818bf80f4bSopenharmony_ci    swapchainData.additionalDepthBufferHandle = gpuResourceManager.Create(
4828bf80f4bSopenharmony_ci        DefaultEngineGpuResourceConstants::CORE_DEFAULT_BACKBUFFER_DEPTH, swapchain.GetDescDepthBuffer());
4838bf80f4bSopenharmony_ci}
4848bf80f4bSopenharmony_ci} // namespace
4858bf80f4bSopenharmony_ci
4868bf80f4bSopenharmony_ciDevice::Device(RenderContext& renderContext, const DeviceCreateInfo& deviceCreateInfo) : renderContext_(renderContext)
4878bf80f4bSopenharmony_ci{
4888bf80f4bSopenharmony_ci    if ((deviceConfiguration_.bufferingCount < MIN_BUFFERING_COUNT) ||
4898bf80f4bSopenharmony_ci        (deviceConfiguration_.bufferingCount > MAX_BUFFERING_COUNT)) {
4908bf80f4bSopenharmony_ci        deviceConfiguration_.bufferingCount =
4918bf80f4bSopenharmony_ci            std::clamp(deviceConfiguration_.bufferingCount, MIN_BUFFERING_COUNT, MAX_BUFFERING_COUNT);
4928bf80f4bSopenharmony_ci        PLUGIN_LOG_D("buffering count clamped to: %u", deviceConfiguration_.bufferingCount);
4938bf80f4bSopenharmony_ci    }
4948bf80f4bSopenharmony_ci}
4958bf80f4bSopenharmony_ci
4968bf80f4bSopenharmony_ciRenderHandleReference Device::CreateSwapchainImpl(
4978bf80f4bSopenharmony_ci    const SwapchainCreateInfo& swapchainCreateInfo, const RenderHandleReference& replacedHandle, const string_view name)
4988bf80f4bSopenharmony_ci{
4998bf80f4bSopenharmony_ci    Activate();
5008bf80f4bSopenharmony_ci    // NOTE: with optimal implementation shouldn't be needed here
5018bf80f4bSopenharmony_ci    WaitForIdle();
5028bf80f4bSopenharmony_ci
5038bf80f4bSopenharmony_ci    uint32_t swapchainIdx = static_cast<uint32_t>(swapchains_.size());
5048bf80f4bSopenharmony_ci    bool replace = false;
5058bf80f4bSopenharmony_ci    // check if the handle needs to be replaced
5068bf80f4bSopenharmony_ci    RenderHandleReference finalReplaceHandle = replacedHandle;
5078bf80f4bSopenharmony_ci    {
5088bf80f4bSopenharmony_ci        const RenderHandle rawReplaceHandle = finalReplaceHandle.GetHandle();
5098bf80f4bSopenharmony_ci        const bool checkReplaceHandle = RenderHandleUtil::IsValid(rawReplaceHandle);
5108bf80f4bSopenharmony_ci        const bool checkReplaceWindow = (swapchainCreateInfo.window.window != 0);
5118bf80f4bSopenharmony_ci        const bool checkReplaceSurface = (swapchainCreateInfo.surfaceHandle != 0);
5128bf80f4bSopenharmony_ci        for (uint32_t idx = 0; idx < swapchains_.size(); ++idx) {
5138bf80f4bSopenharmony_ci            const auto& cmpSwap = swapchains_[idx];
5148bf80f4bSopenharmony_ci            // if window is the same, or surface is the same, or handle is the same
5158bf80f4bSopenharmony_ci            // -> re-use the old handle
5168bf80f4bSopenharmony_ci            replace = replace || (checkReplaceWindow && (cmpSwap.window == swapchainCreateInfo.window.window));
5178bf80f4bSopenharmony_ci            replace = replace || (checkReplaceSurface && (cmpSwap.surfaceHandle == swapchainCreateInfo.surfaceHandle));
5188bf80f4bSopenharmony_ci            replace = replace ||
5198bf80f4bSopenharmony_ci                      (checkReplaceHandle && ((cmpSwap.remappableSwapchainImage.GetHandle() == rawReplaceHandle) ||
5208bf80f4bSopenharmony_ci                                                 (cmpSwap.remappableAdditionalSwapchainImage == rawReplaceHandle)));
5218bf80f4bSopenharmony_ci            if (replace) {
5228bf80f4bSopenharmony_ci#if (RENDER_VALIDATION_ENABLED == 1)
5238bf80f4bSopenharmony_ci                {
5248bf80f4bSopenharmony_ci                    RenderHandle printHandle = cmpSwap.remappableSwapchainImage.GetHandle();
5258bf80f4bSopenharmony_ci                    if (!RenderHandleUtil::IsValid(printHandle)) {
5268bf80f4bSopenharmony_ci                        printHandle = cmpSwap.remappableAdditionalSwapchainImage;
5278bf80f4bSopenharmony_ci                    }
5288bf80f4bSopenharmony_ci                    PLUGIN_LOG_I("RENDER_VALIDATION: Replacing old swapchain handle %" PRIx64, printHandle.id);
5298bf80f4bSopenharmony_ci                }
5308bf80f4bSopenharmony_ci#endif
5318bf80f4bSopenharmony_ci                swapchainIdx = idx;
5328bf80f4bSopenharmony_ci                finalReplaceHandle = swapchains_[swapchainIdx].remappableSwapchainImage;
5338bf80f4bSopenharmony_ci                swapchains_[swapchainIdx] = {};
5348bf80f4bSopenharmony_ci                DestroyDeviceSwapchain(); // NOTE: GLES handling
5358bf80f4bSopenharmony_ci                break;
5368bf80f4bSopenharmony_ci            }
5378bf80f4bSopenharmony_ci        }
5388bf80f4bSopenharmony_ci    }
5398bf80f4bSopenharmony_ci
5408bf80f4bSopenharmony_ci    if ((!replace) && (swapchains_.size() == DeviceConstants::MAX_SWAPCHAIN_COUNT)) {
5418bf80f4bSopenharmony_ci        PLUGIN_LOG_W("Only (%u) swapchains supported.", DeviceConstants::MAX_SWAPCHAIN_COUNT);
5428bf80f4bSopenharmony_ci        Deactivate();
5438bf80f4bSopenharmony_ci        return {};
5448bf80f4bSopenharmony_ci    }
5458bf80f4bSopenharmony_ci
5468bf80f4bSopenharmony_ci    if (!replace) {
5478bf80f4bSopenharmony_ci        swapchains_.push_back({});
5488bf80f4bSopenharmony_ci    }
5498bf80f4bSopenharmony_ci    auto& swapchainData = swapchains_[swapchainIdx];
5508bf80f4bSopenharmony_ci    swapchainData = {};
5518bf80f4bSopenharmony_ci    swapchainData.swapchain = CreateDeviceSwapchain(swapchainCreateInfo);
5528bf80f4bSopenharmony_ci    if (!swapchainData.swapchain) {
5538bf80f4bSopenharmony_ci        Deactivate();
5548bf80f4bSopenharmony_ci        return {};
5558bf80f4bSopenharmony_ci    }
5568bf80f4bSopenharmony_ci
5578bf80f4bSopenharmony_ci    {
5588bf80f4bSopenharmony_ci        vector<unique_ptr<GpuImage>> swapchainGpuImages = CreateGpuImageViews(*swapchainData.swapchain);
5598bf80f4bSopenharmony_ci        Deactivate();
5608bf80f4bSopenharmony_ci
5618bf80f4bSopenharmony_ci        // create shallow handle with handle in the name
5628bf80f4bSopenharmony_ci        GpuImageDesc shallowDesc = swapchainData.swapchain->GetDesc();
5638bf80f4bSopenharmony_ci        shallowDesc.width = 2u;
5648bf80f4bSopenharmony_ci        shallowDesc.height = 2u;
5658bf80f4bSopenharmony_ci        swapchainData.surfaceHandle = swapchainCreateInfo.surfaceHandle;
5668bf80f4bSopenharmony_ci        swapchainData.window = swapchainCreateInfo.window.window;
5678bf80f4bSopenharmony_ci        swapchainData.globalName = name;
5688bf80f4bSopenharmony_ci        swapchainData.name = DefaultEngineGpuResourceConstants::CORE_DEFAULT_SWAPCHAIN +
5698bf80f4bSopenharmony_ci                             to_hex(swapchainData.swapchain->GetSurfaceHandle()) + '_';
5708bf80f4bSopenharmony_ci        swapchainData.remappableSwapchainImage =
5718bf80f4bSopenharmony_ci            gpuResourceMgr_->CreateSwapchainImage(finalReplaceHandle, name, shallowDesc);
5728bf80f4bSopenharmony_ci        PLUGIN_ASSERT(SwapchainData::MAX_IMAGE_VIEW_COUNT >= static_cast<uint32_t>(swapchainGpuImages.size()));
5738bf80f4bSopenharmony_ci        swapchainData.imageViewCount = static_cast<uint32_t>(swapchainGpuImages.size());
5748bf80f4bSopenharmony_ci        for (uint32_t idx = 0; idx < swapchainGpuImages.size(); ++idx) {
5758bf80f4bSopenharmony_ci            const auto& ref = swapchainGpuImages[idx];
5768bf80f4bSopenharmony_ci            swapchainData.imageViews[idx] = gpuResourceMgr_->CreateView(
5778bf80f4bSopenharmony_ci                swapchainData.name + to_string(idx), ref->GetDesc(), ref->GetBasePlatformData());
5788bf80f4bSopenharmony_ci        }
5798bf80f4bSopenharmony_ci
5808bf80f4bSopenharmony_ci        Activate();
5818bf80f4bSopenharmony_ci    }
5828bf80f4bSopenharmony_ci    {
5838bf80f4bSopenharmony_ci        Deactivate();
5848bf80f4bSopenharmony_ci        if (swapchainData.imageViewCount > 0U) {
5858bf80f4bSopenharmony_ci            const RenderHandle firstSwapchain = swapchainData.imageViews[0U].GetHandle();
5868bf80f4bSopenharmony_ci            gpuResourceMgr_->RemapGpuImageHandle(swapchainData.remappableSwapchainImage.GetHandle(), firstSwapchain);
5878bf80f4bSopenharmony_ci            // check for default swapchain existance and remap
5888bf80f4bSopenharmony_ci            if (!defaultSwapchainHandle_) {
5898bf80f4bSopenharmony_ci                const RenderHandle shallowHandle =
5908bf80f4bSopenharmony_ci                    gpuResourceMgr_->GetImageRawHandle(DefaultEngineGpuResourceConstants::CORE_DEFAULT_BACKBUFFER);
5918bf80f4bSopenharmony_ci                gpuResourceMgr_->RemapGpuImageHandle(shallowHandle, firstSwapchain);
5928bf80f4bSopenharmony_ci                swapchainData.remappableAdditionalSwapchainImage = shallowHandle;
5938bf80f4bSopenharmony_ci                // store, that we use default built-in swapchain for backbuffer
5948bf80f4bSopenharmony_ci                defaultSwapchainHandle_ = swapchainData.remappableSwapchainImage;
5958bf80f4bSopenharmony_ci            }
5968bf80f4bSopenharmony_ci        }
5978bf80f4bSopenharmony_ci    }
5988bf80f4bSopenharmony_ci
5998bf80f4bSopenharmony_ci    // configure automatically backbuffer as swapchain
6008bf80f4bSopenharmony_ci    {
6018bf80f4bSopenharmony_ci        IRenderDataStoreManager& rdsm = renderContext_.GetRenderDataStoreManager();
6028bf80f4bSopenharmony_ci        auto dataStorePod = static_cast<IRenderDataStorePod*>(rdsm.GetRenderDataStore(RenderDataStorePod::TYPE_NAME));
6038bf80f4bSopenharmony_ci        if (dataStorePod) {
6048bf80f4bSopenharmony_ci            auto const dataView = dataStorePod->Get("NodeGraphBackBufferConfiguration");
6058bf80f4bSopenharmony_ci            PLUGIN_ASSERT(dataView.size_bytes() == sizeof(NodeGraphBackBufferConfiguration));
6068bf80f4bSopenharmony_ci            NodeGraphBackBufferConfiguration ngbbc = *(const NodeGraphBackBufferConfiguration*)dataView.data();
6078bf80f4bSopenharmony_ci            StringUtil::CopyStringToArray(DefaultEngineGpuResourceConstants::CORE_DEFAULT_BACKBUFFER,
6088bf80f4bSopenharmony_ci                ngbbc.backBufferName, NodeGraphBackBufferConfiguration::CORE_MAX_BACK_BUFFER_NAME_LENGTH);
6098bf80f4bSopenharmony_ci            ngbbc.backBufferType = NodeGraphBackBufferConfiguration::BackBufferType::SWAPCHAIN;
6108bf80f4bSopenharmony_ci            ngbbc.present = true;
6118bf80f4bSopenharmony_ci            dataStorePod->Set("NodeGraphBackBufferConfiguration", arrayviewU8(ngbbc));
6128bf80f4bSopenharmony_ci        }
6138bf80f4bSopenharmony_ci    }
6148bf80f4bSopenharmony_ci    if ((defaultSwapchainHandle_.GetHandle() == swapchainData.remappableSwapchainImage.GetHandle()) &&
6158bf80f4bSopenharmony_ci        (swapchainCreateInfo.swapchainFlags & SwapchainFlagBits::CORE_SWAPCHAIN_DEPTH_BUFFER_BIT)) {
6168bf80f4bSopenharmony_ci        CreateDepthBuffer(GetBackendType(), *swapchainData.swapchain, *gpuResourceMgr_, swapchainData);
6178bf80f4bSopenharmony_ci    }
6188bf80f4bSopenharmony_ci#if (RENDER_VALIDATION_ENABLED == 1)
6198bf80f4bSopenharmony_ci    if ((defaultSwapchainHandle_.GetHandle() != swapchainData.remappableSwapchainImage.GetHandle()) &&
6208bf80f4bSopenharmony_ci        (swapchainCreateInfo.swapchainFlags & SwapchainFlagBits::CORE_SWAPCHAIN_DEPTH_BUFFER_BIT)) {
6218bf80f4bSopenharmony_ci        PLUGIN_LOG_W("RENDER_VALIDATION: Automatic swapchain depth buffer creation supported for default swapchain.");
6228bf80f4bSopenharmony_ci    }
6238bf80f4bSopenharmony_ci#endif
6248bf80f4bSopenharmony_ci
6258bf80f4bSopenharmony_ci    return swapchainData.remappableSwapchainImage;
6268bf80f4bSopenharmony_ci}
6278bf80f4bSopenharmony_ci
6288bf80f4bSopenharmony_ciRenderHandleReference Device::CreateSwapchainHandle(
6298bf80f4bSopenharmony_ci    const SwapchainCreateInfo& swapchainCreateInfo, const RenderHandleReference& replacedHandle, const string_view name)
6308bf80f4bSopenharmony_ci{
6318bf80f4bSopenharmony_ci    if (replacedHandle.GetHandle() == defaultSwapchainHandle_.GetHandle()) {
6328bf80f4bSopenharmony_ci        // first safety destroy for legacy default swapchain
6338bf80f4bSopenharmony_ci        DestroySwapchainImpl(defaultSwapchainHandle_);
6348bf80f4bSopenharmony_ci    }
6358bf80f4bSopenharmony_ci    return CreateSwapchainImpl(swapchainCreateInfo, replacedHandle, name);
6368bf80f4bSopenharmony_ci}
6378bf80f4bSopenharmony_ci
6388bf80f4bSopenharmony_ciRenderHandleReference Device::CreateSwapchainHandle(const SwapchainCreateInfo& swapchainCreateInfo)
6398bf80f4bSopenharmony_ci{
6408bf80f4bSopenharmony_ci    // first safety destroy for legacy default swapchain
6418bf80f4bSopenharmony_ci    DestroySwapchainImpl(defaultSwapchainHandle_);
6428bf80f4bSopenharmony_ci    return CreateSwapchainImpl(swapchainCreateInfo, {}, {});
6438bf80f4bSopenharmony_ci}
6448bf80f4bSopenharmony_ci
6458bf80f4bSopenharmony_civoid Device::CreateSwapchain(const SwapchainCreateInfo& swapchainCreateInfo)
6468bf80f4bSopenharmony_ci{
6478bf80f4bSopenharmony_ci    // first safety destroy for legacy default swapchain
6488bf80f4bSopenharmony_ci    DestroySwapchainImpl(defaultSwapchainHandle_);
6498bf80f4bSopenharmony_ci    CreateSwapchainImpl(swapchainCreateInfo, {}, {});
6508bf80f4bSopenharmony_ci}
6518bf80f4bSopenharmony_ci
6528bf80f4bSopenharmony_civoid Device::DestroySwapchainImpl(const RenderHandleReference& handle)
6538bf80f4bSopenharmony_ci{
6548bf80f4bSopenharmony_ci    // NOTE: the destruction should be deferred, but we expect this to be called from rendering thread
6558bf80f4bSopenharmony_ci    if (isRenderbackendRunning_) {
6568bf80f4bSopenharmony_ci        // NOTE: we are currently only sending error message and not trying to prevent
6578bf80f4bSopenharmony_ci        PLUGIN_LOG_E("DestroySwapchain called while RenderFrame is running");
6588bf80f4bSopenharmony_ci    }
6598bf80f4bSopenharmony_ci
6608bf80f4bSopenharmony_ci    if (handle) {
6618bf80f4bSopenharmony_ci        const RenderHandle rawHandle = handle.GetHandle();
6628bf80f4bSopenharmony_ci        for (auto iter = swapchains_.cbegin(); iter != swapchains_.cend(); ++iter) {
6638bf80f4bSopenharmony_ci            if (iter->remappableSwapchainImage.GetHandle() == rawHandle) {
6648bf80f4bSopenharmony_ci                Activate();
6658bf80f4bSopenharmony_ci                WaitForIdle();
6668bf80f4bSopenharmony_ci
6678bf80f4bSopenharmony_ci                swapchains_.erase(iter);
6688bf80f4bSopenharmony_ci
6698bf80f4bSopenharmony_ci                DestroyDeviceSwapchain();
6708bf80f4bSopenharmony_ci                // remove swapchain configuration from the backbuffer
6718bf80f4bSopenharmony_ci                if ((handle.GetHandle() == defaultSwapchainHandle_.GetHandle()) || (!handle)) {
6728bf80f4bSopenharmony_ci                    IRenderDataStoreManager& rdsm = renderContext_.GetRenderDataStoreManager();
6738bf80f4bSopenharmony_ci                    auto dataStorePod =
6748bf80f4bSopenharmony_ci                        static_cast<IRenderDataStorePod*>(rdsm.GetRenderDataStore(RenderDataStorePod::TYPE_NAME));
6758bf80f4bSopenharmony_ci                    if (dataStorePod) {
6768bf80f4bSopenharmony_ci                        auto const dataView = dataStorePod->Get("NodeGraphBackBufferConfiguration");
6778bf80f4bSopenharmony_ci                        PLUGIN_ASSERT(dataView.size_bytes() == sizeof(NodeGraphBackBufferConfiguration));
6788bf80f4bSopenharmony_ci                        NodeGraphBackBufferConfiguration ngbbc =
6798bf80f4bSopenharmony_ci                            *(const NodeGraphBackBufferConfiguration*)dataView.data();
6808bf80f4bSopenharmony_ci                        if (ngbbc.backBufferType == NodeGraphBackBufferConfiguration::BackBufferType::SWAPCHAIN) {
6818bf80f4bSopenharmony_ci                            ngbbc.backBufferType = NodeGraphBackBufferConfiguration::BackBufferType::UNDEFINED;
6828bf80f4bSopenharmony_ci                            ngbbc.present = false;
6838bf80f4bSopenharmony_ci                        }
6848bf80f4bSopenharmony_ci                        dataStorePod->Set("NodeGraphBackBufferConfiguration", arrayviewU8(ngbbc));
6858bf80f4bSopenharmony_ci                    }
6868bf80f4bSopenharmony_ci                }
6878bf80f4bSopenharmony_ci                Deactivate();
6888bf80f4bSopenharmony_ci
6898bf80f4bSopenharmony_ci                // destroy default swapchain handle if it was in use
6908bf80f4bSopenharmony_ci                if (handle.GetHandle() == defaultSwapchainHandle_.GetHandle()) {
6918bf80f4bSopenharmony_ci                    defaultSwapchainHandle_ = {};
6928bf80f4bSopenharmony_ci                }
6938bf80f4bSopenharmony_ci
6948bf80f4bSopenharmony_ci                // element erased -> break
6958bf80f4bSopenharmony_ci                break;
6968bf80f4bSopenharmony_ci            }
6978bf80f4bSopenharmony_ci        }
6988bf80f4bSopenharmony_ci    }
6998bf80f4bSopenharmony_ci}
7008bf80f4bSopenharmony_ci
7018bf80f4bSopenharmony_civoid Device::DestroySwapchain()
7028bf80f4bSopenharmony_ci{
7038bf80f4bSopenharmony_ci    DestroySwapchainImpl(defaultSwapchainHandle_);
7048bf80f4bSopenharmony_ci}
7058bf80f4bSopenharmony_ci
7068bf80f4bSopenharmony_civoid Device::DestroySwapchain(const RenderHandleReference& handle)
7078bf80f4bSopenharmony_ci{
7088bf80f4bSopenharmony_ci    DestroySwapchainImpl(handle);
7098bf80f4bSopenharmony_ci}
7108bf80f4bSopenharmony_ci
7118bf80f4bSopenharmony_ciSurfaceTransformFlags Device::GetSurfaceTransformFlags(const RenderHandle& handle) const
7128bf80f4bSopenharmony_ci{
7138bf80f4bSopenharmony_ci    // NOTE: we lock data hear to check for the transforms flags
7148bf80f4bSopenharmony_ci    // the flags should be stored, and the data should not be locked for every frame access
7158bf80f4bSopenharmony_ci    if (RenderHandleUtil::IsSwapchain(handle)) {
7168bf80f4bSopenharmony_ci        for (const auto& swapchain : swapchains_) {
7178bf80f4bSopenharmony_ci            if (((swapchain.remappableSwapchainImage.GetHandle() == handle) ||
7188bf80f4bSopenharmony_ci                    (swapchain.remappableAdditionalSwapchainImage == handle)) &&
7198bf80f4bSopenharmony_ci                (swapchain.swapchain)) {
7208bf80f4bSopenharmony_ci                return swapchain.swapchain->GetSurfaceTransformFlags();
7218bf80f4bSopenharmony_ci            }
7228bf80f4bSopenharmony_ci        }
7238bf80f4bSopenharmony_ci    }
7248bf80f4bSopenharmony_ci    return 0u;
7258bf80f4bSopenharmony_ci}
7268bf80f4bSopenharmony_ci
7278bf80f4bSopenharmony_civoid Device::FrameStart()
7288bf80f4bSopenharmony_ci{
7298bf80f4bSopenharmony_ci    ++frameCount_;
7308bf80f4bSopenharmony_ci}
7318bf80f4bSopenharmony_ci
7328bf80f4bSopenharmony_civoid Device::FrameEnd() {}
7338bf80f4bSopenharmony_ci
7348bf80f4bSopenharmony_civoid Device::SetDeviceStatus(const bool status)
7358bf80f4bSopenharmony_ci{
7368bf80f4bSopenharmony_ci    deviceStatus_.store(status);
7378bf80f4bSopenharmony_ci}
7388bf80f4bSopenharmony_ci
7398bf80f4bSopenharmony_cibool Device::GetDeviceStatus() const
7408bf80f4bSopenharmony_ci{
7418bf80f4bSopenharmony_ci    return deviceStatus_.load();
7428bf80f4bSopenharmony_ci};
7438bf80f4bSopenharmony_ciuint64_t Device::GetFrameCount() const
7448bf80f4bSopenharmony_ci{
7458bf80f4bSopenharmony_ci    return frameCount_;
7468bf80f4bSopenharmony_ci}
7478bf80f4bSopenharmony_ci
7488bf80f4bSopenharmony_ciconst CommonDeviceProperties& Device::GetCommonDeviceProperties() const
7498bf80f4bSopenharmony_ci{
7508bf80f4bSopenharmony_ci    return commonDeviceProperties_;
7518bf80f4bSopenharmony_ci}
7528bf80f4bSopenharmony_ci
7538bf80f4bSopenharmony_ciMemoryPropertyFlags Device::GetSharedMemoryPropertyFlags() const
7548bf80f4bSopenharmony_ci{
7558bf80f4bSopenharmony_ci    return deviceSharedMemoryPropertyFlags_;
7568bf80f4bSopenharmony_ci}
7578bf80f4bSopenharmony_ci
7588bf80f4bSopenharmony_ciDeviceConfiguration Device::GetDeviceConfiguration() const
7598bf80f4bSopenharmony_ci{
7608bf80f4bSopenharmony_ci    return deviceConfiguration_;
7618bf80f4bSopenharmony_ci}
7628bf80f4bSopenharmony_ci
7638bf80f4bSopenharmony_ciuint32_t Device::GetCommandBufferingCount() const
7648bf80f4bSopenharmony_ci{
7658bf80f4bSopenharmony_ci    return deviceConfiguration_.bufferingCount;
7668bf80f4bSopenharmony_ci}
7678bf80f4bSopenharmony_ci
7688bf80f4bSopenharmony_cibool Device::HasSwapchain() const
7698bf80f4bSopenharmony_ci{
7708bf80f4bSopenharmony_ci    return (!swapchains_.empty());
7718bf80f4bSopenharmony_ci}
7728bf80f4bSopenharmony_ci
7738bf80f4bSopenharmony_ciconst Swapchain* Device::GetSwapchain(const RenderHandle handle) const
7748bf80f4bSopenharmony_ci{
7758bf80f4bSopenharmony_ci    const RenderHandle cmpHandle = RenderHandleUtil::IsValid(handle) ? handle : defaultSwapchainHandle_.GetHandle();
7768bf80f4bSopenharmony_ci    // NOTE: returns a pointer to data which could be destroyed
7778bf80f4bSopenharmony_ci    // if the API documentation and restrictions are not applied by the user
7788bf80f4bSopenharmony_ci    for (const auto& swapData : swapchains_) {
7798bf80f4bSopenharmony_ci        if (((swapData.remappableSwapchainImage.GetHandle() == cmpHandle) ||
7808bf80f4bSopenharmony_ci                (swapData.remappableAdditionalSwapchainImage == cmpHandle)) &&
7818bf80f4bSopenharmony_ci            (swapData.swapchain)) {
7828bf80f4bSopenharmony_ci            return swapData.swapchain.get();
7838bf80f4bSopenharmony_ci        }
7848bf80f4bSopenharmony_ci    }
7858bf80f4bSopenharmony_ci    return nullptr;
7868bf80f4bSopenharmony_ci}
7878bf80f4bSopenharmony_ci
7888bf80f4bSopenharmony_ciDevice::SwapchainData Device::GetSwapchainData(const RenderHandle handle) const
7898bf80f4bSopenharmony_ci{
7908bf80f4bSopenharmony_ci    PLUGIN_ASSERT(isRenderbackendRunning_);
7918bf80f4bSopenharmony_ci
7928bf80f4bSopenharmony_ci    const RenderHandle cmpHandle = RenderHandleUtil::IsValid(handle) ? handle : defaultSwapchainHandle_.GetHandle();
7938bf80f4bSopenharmony_ci    for (const auto& swapData : swapchains_) {
7948bf80f4bSopenharmony_ci        if (((swapData.remappableSwapchainImage.GetHandle() == cmpHandle) ||
7958bf80f4bSopenharmony_ci                (swapData.remappableAdditionalSwapchainImage == cmpHandle)) &&
7968bf80f4bSopenharmony_ci            (swapData.swapchain)) {
7978bf80f4bSopenharmony_ci            SwapchainData sd;
7988bf80f4bSopenharmony_ci            // comparison handle should be a valid handle here and is used in image re-mapping
7998bf80f4bSopenharmony_ci            sd.remappableSwapchainImage = cmpHandle;
8008bf80f4bSopenharmony_ci            PLUGIN_ASSERT(swapData.imageViewCount <= SwapchainData::MAX_IMAGE_VIEW_COUNT);
8018bf80f4bSopenharmony_ci            sd.imageViewCount = swapData.imageViewCount;
8028bf80f4bSopenharmony_ci            for (uint32_t idx = 0; idx < swapData.imageViewCount; ++idx) {
8038bf80f4bSopenharmony_ci                sd.imageViews[idx] = swapData.imageViews[idx].GetHandle();
8048bf80f4bSopenharmony_ci            }
8058bf80f4bSopenharmony_ci            return sd;
8068bf80f4bSopenharmony_ci        }
8078bf80f4bSopenharmony_ci    }
8088bf80f4bSopenharmony_ci    return {};
8098bf80f4bSopenharmony_ci}
8108bf80f4bSopenharmony_ci
8118bf80f4bSopenharmony_civoid Device::SetLockResourceBackendAccess(const bool value)
8128bf80f4bSopenharmony_ci{
8138bf80f4bSopenharmony_ci    isBackendResourceAccessLocked_ = value;
8148bf80f4bSopenharmony_ci}
8158bf80f4bSopenharmony_ci
8168bf80f4bSopenharmony_cibool Device::GetLockResourceBackendAccess() const
8178bf80f4bSopenharmony_ci{
8188bf80f4bSopenharmony_ci    return isBackendResourceAccessLocked_;
8198bf80f4bSopenharmony_ci}
8208bf80f4bSopenharmony_ci
8218bf80f4bSopenharmony_civoid Device::SetRenderBackendRunning(const bool value)
8228bf80f4bSopenharmony_ci{
8238bf80f4bSopenharmony_ci    isRenderbackendRunning_ = value;
8248bf80f4bSopenharmony_ci}
8258bf80f4bSopenharmony_ci
8268bf80f4bSopenharmony_civoid Device::SetRenderFrameRunning(const bool value)
8278bf80f4bSopenharmony_ci{
8288bf80f4bSopenharmony_ci    isRenderFrameRunning_ = value;
8298bf80f4bSopenharmony_ci}
8308bf80f4bSopenharmony_ci
8318bf80f4bSopenharmony_cibool Device::GetRenderFrameRunning() const
8328bf80f4bSopenharmony_ci{
8338bf80f4bSopenharmony_ci    return isRenderFrameRunning_;
8348bf80f4bSopenharmony_ci}
8358bf80f4bSopenharmony_ci
8368bf80f4bSopenharmony_ciIGpuResourceManager& Device::GetGpuResourceManager() const
8378bf80f4bSopenharmony_ci{
8388bf80f4bSopenharmony_ci    return *gpuResourceMgr_;
8398bf80f4bSopenharmony_ci}
8408bf80f4bSopenharmony_ci
8418bf80f4bSopenharmony_ciIShaderManager& Device::GetShaderManager() const
8428bf80f4bSopenharmony_ci{
8438bf80f4bSopenharmony_ci    return *shaderMgr_;
8448bf80f4bSopenharmony_ci}
8458bf80f4bSopenharmony_ci
8468bf80f4bSopenharmony_civoid Device::SetBackendConfig(const BackendConfig& config) {}
8478bf80f4bSopenharmony_ci
8488bf80f4bSopenharmony_ciFormat Device::GetFormatOrFallback(const Format inputFormat) const
8498bf80f4bSopenharmony_ci{
8508bf80f4bSopenharmony_ci    Format format = inputFormat;
8518bf80f4bSopenharmony_ci    if (static_cast<uint32_t>(format) < LINEAR_FORMAT_COUNT) {
8528bf80f4bSopenharmony_ci        auto properties = GetFormatProperties(format);
8538bf80f4bSopenharmony_ci#if (RENDER_VALIDATION_ENABLED == 1)
8548bf80f4bSopenharmony_ci        uint32_t fallbackCount = 0U;
8558bf80f4bSopenharmony_ci#endif
8568bf80f4bSopenharmony_ci        while (format != Format::BASE_FORMAT_UNDEFINED && !properties.linearTilingFeatures &&
8578bf80f4bSopenharmony_ci               !properties.optimalTilingFeatures) {
8588bf80f4bSopenharmony_ci            format = FALLBACK_FORMATS[format];
8598bf80f4bSopenharmony_ci            properties = GetFormatProperties(format);
8608bf80f4bSopenharmony_ci#if (RENDER_VALIDATION_ENABLED == 1)
8618bf80f4bSopenharmony_ci            fallbackCount++;
8628bf80f4bSopenharmony_ci#endif
8638bf80f4bSopenharmony_ci        }
8648bf80f4bSopenharmony_ci#if (RENDER_VALIDATION_ENABLED == 1)
8658bf80f4bSopenharmony_ci        if (fallbackCount > 0U) {
8668bf80f4bSopenharmony_ci            PLUGIN_LOG_I("RENDER_VALIDATION: input format (%u) fallback format (%u)",
8678bf80f4bSopenharmony_ci                static_cast<uint32_t>(inputFormat), static_cast<uint32_t>(format));
8688bf80f4bSopenharmony_ci        }
8698bf80f4bSopenharmony_ci#endif
8708bf80f4bSopenharmony_ci    }
8718bf80f4bSopenharmony_ci    return format;
8728bf80f4bSopenharmony_ci}
8738bf80f4bSopenharmony_ciRENDER_END_NAMESPACE()
874