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_vk.h" 178bf80f4bSopenharmony_ci 188bf80f4bSopenharmony_ci#include <algorithm> 198bf80f4bSopenharmony_ci#include <cinttypes> 208bf80f4bSopenharmony_ci#include <cstdint> 218bf80f4bSopenharmony_ci#include <vulkan/vulkan_core.h> 228bf80f4bSopenharmony_ci 238bf80f4bSopenharmony_ci#include <base/containers/vector.h> 248bf80f4bSopenharmony_ci#include <base/math/mathf.h> 258bf80f4bSopenharmony_ci#include <core/engine_info.h> 268bf80f4bSopenharmony_ci#include <render/intf_render_context.h> 278bf80f4bSopenharmony_ci#include <render/namespace.h> 288bf80f4bSopenharmony_ci 298bf80f4bSopenharmony_ci#include "device/device.h" 308bf80f4bSopenharmony_ci#include "device/gpu_program_util.h" 318bf80f4bSopenharmony_ci#include "device/gpu_resource_manager.h" 328bf80f4bSopenharmony_ci#include "device/shader_manager.h" 338bf80f4bSopenharmony_ci#include "device/shader_module.h" 348bf80f4bSopenharmony_ci#include "platform_vk.h" 358bf80f4bSopenharmony_ci#include "util/log.h" 368bf80f4bSopenharmony_ci#include "vulkan/create_functions_vk.h" 378bf80f4bSopenharmony_ci#include "vulkan/gpu_buffer_vk.h" 388bf80f4bSopenharmony_ci#include "vulkan/gpu_image_vk.h" 398bf80f4bSopenharmony_ci#include "vulkan/gpu_memory_allocator_vk.h" 408bf80f4bSopenharmony_ci#include "vulkan/gpu_program_vk.h" 418bf80f4bSopenharmony_ci#include "vulkan/gpu_query_vk.h" 428bf80f4bSopenharmony_ci#include "vulkan/gpu_sampler_vk.h" 438bf80f4bSopenharmony_ci#include "vulkan/gpu_semaphore_vk.h" 448bf80f4bSopenharmony_ci#include "vulkan/node_context_descriptor_set_manager_vk.h" 458bf80f4bSopenharmony_ci#include "vulkan/node_context_pool_manager_vk.h" 468bf80f4bSopenharmony_ci#include "vulkan/pipeline_state_object_vk.h" 478bf80f4bSopenharmony_ci#include "vulkan/render_backend_vk.h" 488bf80f4bSopenharmony_ci#include "vulkan/render_frame_sync_vk.h" 498bf80f4bSopenharmony_ci#include "vulkan/shader_module_vk.h" 508bf80f4bSopenharmony_ci#include "vulkan/swapchain_vk.h" 518bf80f4bSopenharmony_ci#include "vulkan/validate_vk.h" 528bf80f4bSopenharmony_ci 538bf80f4bSopenharmony_ciusing namespace BASE_NS; 548bf80f4bSopenharmony_ci 558bf80f4bSopenharmony_ciRENDER_BEGIN_NAMESPACE() 568bf80f4bSopenharmony_cinamespace { 578bf80f4bSopenharmony_cistatic constexpr string_view DEVICE_EXTENSION_SWAPCHAIN { VK_KHR_SWAPCHAIN_EXTENSION_NAME }; 588bf80f4bSopenharmony_ci 598bf80f4bSopenharmony_ci// promoted to 1.2, requires VK_KHR_create_renderpass2 608bf80f4bSopenharmony_cistatic constexpr string_view DEVICE_EXTENSION_DEPTH_STENCIL_RESOLVE { VK_KHR_DEPTH_STENCIL_RESOLVE_EXTENSION_NAME }; 618bf80f4bSopenharmony_cistatic constexpr string_view DEVICE_EXTENSION_CREATE_RENDERPASS2 { VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME }; 628bf80f4bSopenharmony_ci 638bf80f4bSopenharmony_cistatic constexpr string_view DEVICE_EXTENSION_EXTERNAL_MEMORY { VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME }; 648bf80f4bSopenharmony_cistatic constexpr string_view DEVICE_EXTENSION_GET_MEMORY_REQUIREMENTS2 { 658bf80f4bSopenharmony_ci VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME 668bf80f4bSopenharmony_ci}; 678bf80f4bSopenharmony_cistatic constexpr string_view DEVICE_EXTENSION_SAMPLER_YCBCR_CONVERSION { 688bf80f4bSopenharmony_ci VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME 698bf80f4bSopenharmony_ci}; 708bf80f4bSopenharmony_cistatic constexpr string_view DEVICE_EXTENSION_QUEUE_FAMILY_FOREIGN { VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME }; 718bf80f4bSopenharmony_cistatic constexpr string_view DEVICE_EXTENSION_MULTIVIEW { VK_KHR_MULTIVIEW_EXTENSION_NAME }; 728bf80f4bSopenharmony_cistatic constexpr string_view DEVICE_EXTENSION_MAINTENANCE4 = VK_KHR_MAINTENANCE_4_EXTENSION_NAME; 738bf80f4bSopenharmony_cistatic constexpr string_view DEVICE_EXTENSION_DESCRIPTOR_INDEXING = VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME; 748bf80f4bSopenharmony_ci 758bf80f4bSopenharmony_cistruct ChainWrapper { 768bf80f4bSopenharmony_ci void** ppNextFeatures { nullptr }; 778bf80f4bSopenharmony_ci void** ppNextProperties { nullptr }; 788bf80f4bSopenharmony_ci}; 798bf80f4bSopenharmony_ci 808bf80f4bSopenharmony_cistruct PhysicalDeviceYcbcrStructsVk { 818bf80f4bSopenharmony_ci VkPhysicalDeviceSamplerYcbcrConversionFeatures ycbcrConversionFeatures {}; 828bf80f4bSopenharmony_ci}; 838bf80f4bSopenharmony_ci 848bf80f4bSopenharmony_ci#if (RENDER_VULKAN_FSR_ENABLED == 1) 858bf80f4bSopenharmony_cistruct PhysicalDeviceFragmentShadingRateStructsVk { 868bf80f4bSopenharmony_ci VkPhysicalDeviceFragmentShadingRateFeaturesKHR physicalDeviceFragmentShadingRateFeatures; 878bf80f4bSopenharmony_ci VkPhysicalDeviceFragmentShadingRatePropertiesKHR physicalDeviceFragmentShadingRateProperties; 888bf80f4bSopenharmony_ci}; 898bf80f4bSopenharmony_ci#endif 908bf80f4bSopenharmony_ci 918bf80f4bSopenharmony_ci#if (RENDER_VULKAN_RT_ENABLED == 1) 928bf80f4bSopenharmony_cistruct PhysicalDeviceRayTracingStructsVk { 938bf80f4bSopenharmony_ci VkPhysicalDeviceBufferDeviceAddressFeatures physicalDeviceBufferDeviceAddressFeatures; 948bf80f4bSopenharmony_ci VkPhysicalDeviceRayTracingPipelineFeaturesKHR physicalDeviceRayTracingPipelineFeatures; 958bf80f4bSopenharmony_ci VkPhysicalDeviceAccelerationStructureFeaturesKHR physicalDeviceAccelerationStructureFeatures; 968bf80f4bSopenharmony_ci VkPhysicalDeviceRayQueryFeaturesKHR physicalDeviceRayQueryFeatures; 978bf80f4bSopenharmony_ci}; 988bf80f4bSopenharmony_ci#endif 998bf80f4bSopenharmony_ci 1008bf80f4bSopenharmony_cistruct PhysicalDeviceMultiviewStructsVk { 1018bf80f4bSopenharmony_ci VkPhysicalDeviceMultiviewFeaturesKHR physicalDeviceMultiviewFeatures; 1028bf80f4bSopenharmony_ci VkPhysicalDeviceMultiviewPropertiesKHR physicalDeviceMultiviewProperties; 1038bf80f4bSopenharmony_ci}; 1048bf80f4bSopenharmony_ci 1058bf80f4bSopenharmony_cistruct PhysicalDeviceDesciptorIndexingStructsVk { 1068bf80f4bSopenharmony_ci VkPhysicalDeviceDescriptorIndexingFeatures physicalDeviceDescriptorIndexingFeatures; 1078bf80f4bSopenharmony_ci VkPhysicalDeviceDescriptorIndexingProperties physicalDeviceDescriptorIndexingProperties; 1088bf80f4bSopenharmony_ci}; 1098bf80f4bSopenharmony_ci 1108bf80f4bSopenharmony_cistruct PhysicalDeviceMaintenance4Vk { 1118bf80f4bSopenharmony_ci VkPhysicalDeviceMaintenance4Features maintenance4Features {}; 1128bf80f4bSopenharmony_ci}; 1138bf80f4bSopenharmony_ci 1148bf80f4bSopenharmony_cistruct ChainObjects { 1158bf80f4bSopenharmony_ci unique_ptr<PhysicalDeviceYcbcrStructsVk> ycbcr; 1168bf80f4bSopenharmony_ci#if (RENDER_VULKAN_RT_ENABLED == 1) 1178bf80f4bSopenharmony_ci unique_ptr<PhysicalDeviceRayTracingStructsVk> rt; 1188bf80f4bSopenharmony_ci#endif 1198bf80f4bSopenharmony_ci#if (RENDER_VULKAN_FSR_ENABLED == 1) 1208bf80f4bSopenharmony_ci unique_ptr<PhysicalDeviceFragmentShadingRateStructsVk> fsr; 1218bf80f4bSopenharmony_ci#endif 1228bf80f4bSopenharmony_ci unique_ptr<PhysicalDeviceMultiviewStructsVk> mv; 1238bf80f4bSopenharmony_ci unique_ptr<PhysicalDeviceDesciptorIndexingStructsVk> di; 1248bf80f4bSopenharmony_ci unique_ptr<PhysicalDeviceMaintenance4Vk> maintenance4; 1258bf80f4bSopenharmony_ci}; 1268bf80f4bSopenharmony_ci 1278bf80f4bSopenharmony_ci// fragment shading rate 1288bf80f4bSopenharmony_ci#if (RENDER_VULKAN_FSR_ENABLED == 1) 1298bf80f4bSopenharmony_ci// VK_KHR_fragment_shading_rate, requires VK_KHR_create_renderpass2, requires VK_KHR_get_physical_device_properties2 1308bf80f4bSopenharmony_cistatic constexpr string_view DEVICE_EXTENSION_FRAGMENT_SHADING_RATE { VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME }; 1318bf80f4bSopenharmony_ci 1328bf80f4bSopenharmony_civoid GetPhysicalDeviceFragmentShadingRateStructs(ChainObjects& co, ChainWrapper& cw) 1338bf80f4bSopenharmony_ci{ 1348bf80f4bSopenharmony_ci co.fsr = make_unique<PhysicalDeviceFragmentShadingRateStructsVk>(); 1358bf80f4bSopenharmony_ci auto& fsr = co.fsr; 1368bf80f4bSopenharmony_ci fsr->physicalDeviceFragmentShadingRateFeatures = { 1378bf80f4bSopenharmony_ci VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_FEATURES_KHR, // sType 1388bf80f4bSopenharmony_ci nullptr, // pNext 1398bf80f4bSopenharmony_ci VK_FALSE, // pipelineFragmentShadingRate 1408bf80f4bSopenharmony_ci VK_FALSE, // primitiveFragmentShadingRate 1418bf80f4bSopenharmony_ci VK_FALSE, // attachmentFragmentShadingRate 1428bf80f4bSopenharmony_ci }; 1438bf80f4bSopenharmony_ci *cw.ppNextFeatures = &fsr->physicalDeviceFragmentShadingRateFeatures; 1448bf80f4bSopenharmony_ci cw.ppNextFeatures = &fsr->physicalDeviceFragmentShadingRateFeatures.pNext; 1458bf80f4bSopenharmony_ci 1468bf80f4bSopenharmony_ci fsr->physicalDeviceFragmentShadingRateProperties = { 1478bf80f4bSopenharmony_ci VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_PROPERTIES_KHR, // sType 1488bf80f4bSopenharmony_ci nullptr, // pNext 1498bf80f4bSopenharmony_ci }; 1508bf80f4bSopenharmony_ci *cw.ppNextProperties = &fsr->physicalDeviceFragmentShadingRateProperties; 1518bf80f4bSopenharmony_ci cw.ppNextProperties = &fsr->physicalDeviceFragmentShadingRateProperties.pNext; 1528bf80f4bSopenharmony_ci} 1538bf80f4bSopenharmony_ci#endif 1548bf80f4bSopenharmony_ci 1558bf80f4bSopenharmony_civoid GetPhysicalDeviceMultiviewFeaturesStructs(ChainObjects& co, ChainWrapper& cw) 1568bf80f4bSopenharmony_ci{ 1578bf80f4bSopenharmony_ci co.mv = make_unique<PhysicalDeviceMultiviewStructsVk>(); 1588bf80f4bSopenharmony_ci auto& mv = co.mv; 1598bf80f4bSopenharmony_ci mv->physicalDeviceMultiviewFeatures = { 1608bf80f4bSopenharmony_ci VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES_KHR, // sType 1618bf80f4bSopenharmony_ci nullptr, // pNext 1628bf80f4bSopenharmony_ci VK_FALSE, // multiview 1638bf80f4bSopenharmony_ci VK_FALSE, // multiviewGeometryShader 1648bf80f4bSopenharmony_ci VK_FALSE, // multiviewTessellationShader 1658bf80f4bSopenharmony_ci }; 1668bf80f4bSopenharmony_ci *cw.ppNextFeatures = &mv->physicalDeviceMultiviewFeatures; 1678bf80f4bSopenharmony_ci cw.ppNextFeatures = &mv->physicalDeviceMultiviewFeatures.pNext; 1688bf80f4bSopenharmony_ci 1698bf80f4bSopenharmony_ci mv->physicalDeviceMultiviewProperties = { 1708bf80f4bSopenharmony_ci VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES_KHR, // sType 1718bf80f4bSopenharmony_ci nullptr, // pNext 1728bf80f4bSopenharmony_ci 0, // maxMultiviewViewCount 1738bf80f4bSopenharmony_ci 0, // maxMultiviewInstanceIndex 1748bf80f4bSopenharmony_ci }; 1758bf80f4bSopenharmony_ci *cw.ppNextProperties = &mv->physicalDeviceMultiviewProperties; 1768bf80f4bSopenharmony_ci cw.ppNextProperties = &mv->physicalDeviceMultiviewProperties.pNext; 1778bf80f4bSopenharmony_ci} 1788bf80f4bSopenharmony_ci 1798bf80f4bSopenharmony_civoid GetPhysicalDeviceDescriptorIndexingFeaturesStructs(ChainObjects& co, ChainWrapper& cw) 1808bf80f4bSopenharmony_ci{ 1818bf80f4bSopenharmony_ci co.di = make_unique<PhysicalDeviceDesciptorIndexingStructsVk>(); 1828bf80f4bSopenharmony_ci auto& di = co.di; 1838bf80f4bSopenharmony_ci di->physicalDeviceDescriptorIndexingFeatures = { 1848bf80f4bSopenharmony_ci VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES, // sType 1858bf80f4bSopenharmony_ci nullptr, // pNext 1868bf80f4bSopenharmony_ci VK_FALSE, // shaderInputAttachmentArrayDynamicIndexing 1878bf80f4bSopenharmony_ci VK_FALSE, // shaderUniformTexelBufferArrayDynamicIndexing 1888bf80f4bSopenharmony_ci VK_FALSE, // shaderStorageTexelBufferArrayDynamicIndexing 1898bf80f4bSopenharmony_ci VK_FALSE, // shaderUniformBufferArrayNonUniformIndexing 1908bf80f4bSopenharmony_ci VK_FALSE, // shaderSampledImageArrayNonUniformIndexing 1918bf80f4bSopenharmony_ci VK_FALSE, // shaderStorageBufferArrayNonUniformIndexing 1928bf80f4bSopenharmony_ci VK_FALSE, // shaderStorageImageArrayNonUniformIndexing 1938bf80f4bSopenharmony_ci VK_FALSE, // shaderInputAttachmentArrayNonUniformIndexing 1948bf80f4bSopenharmony_ci VK_FALSE, // shaderUniformTexelBufferArrayNonUniformIndexing 1958bf80f4bSopenharmony_ci VK_FALSE, // shaderStorageTexelBufferArrayNonUniformIndexing 1968bf80f4bSopenharmony_ci VK_FALSE, // descriptorBindingUniformBufferUpdateAfterBind 1978bf80f4bSopenharmony_ci VK_FALSE, // descriptorBindingSampledImageUpdateAsfterBind 1988bf80f4bSopenharmony_ci VK_FALSE, // descriptorBindingStorageImageUpdateAfterBind 1998bf80f4bSopenharmony_ci VK_FALSE, // descriptorBindingStorageBufferUpdateAfterBind 2008bf80f4bSopenharmony_ci VK_FALSE, // descriptorBindingUniformTexelBufferUpdateAfterBind 2018bf80f4bSopenharmony_ci VK_FALSE, // descriptorBindingStorageTexelBufferUpdateAfterBind 2028bf80f4bSopenharmony_ci VK_FALSE, // descriptorBindingUpdateUnusedWhilePending 2038bf80f4bSopenharmony_ci VK_FALSE, // descriptorBindingPartiallyBound 2048bf80f4bSopenharmony_ci VK_FALSE, // descriptorBindingVariableDescriptorCount 2058bf80f4bSopenharmony_ci VK_FALSE, // runtimeDescriptorArray 2068bf80f4bSopenharmony_ci }; 2078bf80f4bSopenharmony_ci *cw.ppNextFeatures = &di->physicalDeviceDescriptorIndexingFeatures; 2088bf80f4bSopenharmony_ci cw.ppNextFeatures = &di->physicalDeviceDescriptorIndexingFeatures.pNext; 2098bf80f4bSopenharmony_ci 2108bf80f4bSopenharmony_ci di->physicalDeviceDescriptorIndexingProperties = { 2118bf80f4bSopenharmony_ci VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES, // sType 2128bf80f4bSopenharmony_ci nullptr, // pNext 2138bf80f4bSopenharmony_ci 0U, // maxUpdateAfterBindDescriptorsInAllPools 2148bf80f4bSopenharmony_ci VK_FALSE, // shaderUniformBufferArrayNonUniformIndexingNative 2158bf80f4bSopenharmony_ci VK_FALSE, // shaderSampledImageArrayNonUniformIndexingNative 2168bf80f4bSopenharmony_ci VK_FALSE, // shaderStorageBufferArrayNonUniformIndexingNative 2178bf80f4bSopenharmony_ci VK_FALSE, // shaderStorageImageArrayNonUniformIndexingNative 2188bf80f4bSopenharmony_ci VK_FALSE, // shaderInputAttachmentArrayNonUniformIndexingNative 2198bf80f4bSopenharmony_ci VK_FALSE, // robustBufferAccessUpdateAfterBind 2208bf80f4bSopenharmony_ci VK_FALSE, // quadDivergentImplicitLod 2218bf80f4bSopenharmony_ci 0U, // maxPerStageDescriptorUpdateAfterBindSamplers 2228bf80f4bSopenharmony_ci 0U, // maxPerStageDescriptorUpdateAfterBindUniformBuffers 2238bf80f4bSopenharmony_ci 0U, // maxPerStageDescriptorUpdateAfterBindStorageBuffers 2248bf80f4bSopenharmony_ci 0U, // maxPerStageDescriptorUpdateAfterBindSampledImages 2258bf80f4bSopenharmony_ci 0U, // maxPerStageDescriptorUpdateAfterBindStorageImages 2268bf80f4bSopenharmony_ci 0U, // maxPerStageDescriptorUpdateAfterBindInputAttachments 2278bf80f4bSopenharmony_ci 0U, // maxPerStageUpdateAfterBindResources 2288bf80f4bSopenharmony_ci 0U, // maxDescriptorSetUpdateAfterBindSamplers 2298bf80f4bSopenharmony_ci 0U, // maxDescriptorSetUpdateAfterBindUniformBuffers 2308bf80f4bSopenharmony_ci 0U, // maxDescriptorSetUpdateAfterBindUniformBuffersDynamic 2318bf80f4bSopenharmony_ci 0U, // maxDescriptorSetUpdateAfterBindStorageBuffers 2328bf80f4bSopenharmony_ci 0U, // maxDescriptorSetUpdateAfterBindStorageBuffersDynamic 2338bf80f4bSopenharmony_ci 0U, // maxDescriptorSetUpdateAfterBindSampledImages 2348bf80f4bSopenharmony_ci 0U, // maxDescriptorSetUpdateAfterBindStorageImages 2358bf80f4bSopenharmony_ci 0U, // maxDescriptorSetUpdateAfterBindInputAttachments 2368bf80f4bSopenharmony_ci }; 2378bf80f4bSopenharmony_ci *cw.ppNextProperties = &di->physicalDeviceDescriptorIndexingProperties; 2388bf80f4bSopenharmony_ci cw.ppNextProperties = &di->physicalDeviceDescriptorIndexingProperties.pNext; 2398bf80f4bSopenharmony_ci} 2408bf80f4bSopenharmony_ci 2418bf80f4bSopenharmony_ci// ray-tracing 2428bf80f4bSopenharmony_ci#if (RENDER_VULKAN_RT_ENABLED == 1) 2438bf80f4bSopenharmony_cistatic constexpr string_view DEVICE_EXTENSION_ACCELERATION_STRUCTURE { "VK_KHR_acceleration_structure" }; 2448bf80f4bSopenharmony_cistatic constexpr string_view DEVICE_EXTENSION_RAY_QUERY { "VK_KHR_ray_query" }; 2458bf80f4bSopenharmony_cistatic constexpr string_view DEVICE_EXTENSION_DEFERRED_HOST_OPERATIONS { "VK_KHR_deferred_host_operations" }; 2468bf80f4bSopenharmony_cistatic constexpr string_view DEVICE_EXTENSION_RAY_TRACING_PIPELINE { "VK_KHR_ray_tracing_pipeline" }; 2478bf80f4bSopenharmony_cistatic constexpr string_view DEVICE_EXTENSION_PIPELINE_LIBRARY { "VK_KHR_pipeline_library" }; 2488bf80f4bSopenharmony_ci 2498bf80f4bSopenharmony_civoid GetPhysicalDeviceRayTracingStructs(ChainObjects& co, ChainWrapper& cw) 2508bf80f4bSopenharmony_ci{ 2518bf80f4bSopenharmony_ci co.rt = make_unique<PhysicalDeviceRayTracingStructsVk>(); 2528bf80f4bSopenharmony_ci auto& rt = co.rt; 2538bf80f4bSopenharmony_ci rt->physicalDeviceBufferDeviceAddressFeatures = { 2548bf80f4bSopenharmony_ci VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES, // sType 2558bf80f4bSopenharmony_ci nullptr, // pNext 2568bf80f4bSopenharmony_ci VK_FALSE, // bufferDeviceAddress; 2578bf80f4bSopenharmony_ci VK_FALSE, // bufferDeviceAddressCaptureReplay 2588bf80f4bSopenharmony_ci VK_FALSE, // bufferDeviceAddressMultiDevice 2598bf80f4bSopenharmony_ci }; 2608bf80f4bSopenharmony_ci rt->physicalDeviceRayTracingPipelineFeatures = { 2618bf80f4bSopenharmony_ci VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR, // sType 2628bf80f4bSopenharmony_ci &rt->physicalDeviceBufferDeviceAddressFeatures, // pNext 2638bf80f4bSopenharmony_ci VK_FALSE, // rayTracingPipeline; 2648bf80f4bSopenharmony_ci VK_FALSE, // rayTracingPipelineShaderGroupHandleCaptureReplay; 2658bf80f4bSopenharmony_ci VK_FALSE, // rayTracingPipelineShaderGroupHandleCaptureReplayMixed; 2668bf80f4bSopenharmony_ci VK_FALSE, // rayTracingPipelineTraceRaysIndirect; 2678bf80f4bSopenharmony_ci VK_FALSE, // rayTraversalPrimitiveCulling; 2688bf80f4bSopenharmony_ci }; 2698bf80f4bSopenharmony_ci rt->physicalDeviceAccelerationStructureFeatures = { 2708bf80f4bSopenharmony_ci VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR, // sType 2718bf80f4bSopenharmony_ci &rt->physicalDeviceRayTracingPipelineFeatures, // pNext 2728bf80f4bSopenharmony_ci VK_FALSE, // accelerationStructure; 2738bf80f4bSopenharmony_ci VK_FALSE, // accelerationStructureCaptureReplay 2748bf80f4bSopenharmony_ci VK_FALSE, // accelerationStructureIndirectBuild 2758bf80f4bSopenharmony_ci VK_FALSE, // accelerationStructureHostCommands 2768bf80f4bSopenharmony_ci VK_FALSE, // descriptorBindingAccelerationStructureUpdateAfterBind 2778bf80f4bSopenharmony_ci }; 2788bf80f4bSopenharmony_ci rt->physicalDeviceRayQueryFeatures = { 2798bf80f4bSopenharmony_ci VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_QUERY_FEATURES_KHR, // sType 2808bf80f4bSopenharmony_ci &rt->physicalDeviceAccelerationStructureFeatures, // pNext 2818bf80f4bSopenharmony_ci true, // rayQuery 2828bf80f4bSopenharmony_ci }; 2838bf80f4bSopenharmony_ci 2848bf80f4bSopenharmony_ci *cw.ppNextFeatures = &rt->physicalDeviceRayQueryFeatures; 2858bf80f4bSopenharmony_ci cw.ppNextFeatures = &rt->physicalDeviceBufferDeviceAddressFeatures.pNext; 2868bf80f4bSopenharmony_ci} 2878bf80f4bSopenharmony_ci#endif 2888bf80f4bSopenharmony_ci 2898bf80f4bSopenharmony_civoid GetPhysicalDeviceYcbcrStructs(ChainObjects& co, ChainWrapper& cw) 2908bf80f4bSopenharmony_ci{ 2918bf80f4bSopenharmony_ci co.ycbcr = make_unique<PhysicalDeviceYcbcrStructsVk>(); 2928bf80f4bSopenharmony_ci auto& ycbcr = co.ycbcr; 2938bf80f4bSopenharmony_ci ycbcr->ycbcrConversionFeatures = { 2948bf80f4bSopenharmony_ci VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES, // sType 2958bf80f4bSopenharmony_ci nullptr, // pNext 2968bf80f4bSopenharmony_ci VK_FALSE, // samplerYcbcrConversion 2978bf80f4bSopenharmony_ci }; 2988bf80f4bSopenharmony_ci 2998bf80f4bSopenharmony_ci *cw.ppNextFeatures = &ycbcr->ycbcrConversionFeatures; 3008bf80f4bSopenharmony_ci cw.ppNextFeatures = &ycbcr->ycbcrConversionFeatures.pNext; 3018bf80f4bSopenharmony_ci} 3028bf80f4bSopenharmony_ci 3038bf80f4bSopenharmony_civoid GetYcbcrExtFunctions(const VkInstance instance, DeviceVk::ExtFunctions& extFunctions) 3048bf80f4bSopenharmony_ci{ 3058bf80f4bSopenharmony_ci extFunctions.vkCreateSamplerYcbcrConversion = 3068bf80f4bSopenharmony_ci (PFN_vkCreateSamplerYcbcrConversion)(void*)vkGetInstanceProcAddr(instance, "vkCreateSamplerYcbcrConversion"); 3078bf80f4bSopenharmony_ci if (!extFunctions.vkCreateSamplerYcbcrConversion) { 3088bf80f4bSopenharmony_ci PLUGIN_LOG_E("vkGetInstanceProcAddr failed for vkCreateSamplerYcbcrConversion"); 3098bf80f4bSopenharmony_ci } 3108bf80f4bSopenharmony_ci extFunctions.vkDestroySamplerYcbcrConversion = 3118bf80f4bSopenharmony_ci (PFN_vkDestroySamplerYcbcrConversion)vkGetInstanceProcAddr(instance, "vkDestroySamplerYcbcrConversion"); 3128bf80f4bSopenharmony_ci if (!extFunctions.vkDestroySamplerYcbcrConversion) { 3138bf80f4bSopenharmony_ci PLUGIN_LOG_E("vkGetInstanceProcAddr failed for vkDestroySamplerYcbcrConversion"); 3148bf80f4bSopenharmony_ci } 3158bf80f4bSopenharmony_ci} 3168bf80f4bSopenharmony_ci 3178bf80f4bSopenharmony_civoid GetPhysicalDeviceMaintenance4Structs(ChainObjects& co, ChainWrapper& cw) 3188bf80f4bSopenharmony_ci{ 3198bf80f4bSopenharmony_ci co.maintenance4 = make_unique<PhysicalDeviceMaintenance4Vk>(); 3208bf80f4bSopenharmony_ci auto& m4 = co.maintenance4; 3218bf80f4bSopenharmony_ci m4->maintenance4Features = { 3228bf80f4bSopenharmony_ci VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES, // sType 3238bf80f4bSopenharmony_ci nullptr, // pNext 3248bf80f4bSopenharmony_ci true, // maintenance4 3258bf80f4bSopenharmony_ci }; 3268bf80f4bSopenharmony_ci 3278bf80f4bSopenharmony_ci *cw.ppNextFeatures = &m4->maintenance4Features; 3288bf80f4bSopenharmony_ci cw.ppNextFeatures = &m4->maintenance4Features.pNext; 3298bf80f4bSopenharmony_ci} 3308bf80f4bSopenharmony_ci 3318bf80f4bSopenharmony_ciconstexpr uint32_t MIN_ALLOCATION_BLOCK_SIZE { 4u * 1024u * 1024u }; 3328bf80f4bSopenharmony_ciconstexpr uint32_t MAX_ALLOCATION_BLOCK_SIZE { 1024u * 1024u * 1024u }; 3338bf80f4bSopenharmony_cistatic constexpr const QueueProperties DEFAULT_QUEUE { 3348bf80f4bSopenharmony_ci VK_QUEUE_GRAPHICS_BIT, // requiredFlags 3358bf80f4bSopenharmony_ci 1, // count 3368bf80f4bSopenharmony_ci 1.0f, // priority 3378bf80f4bSopenharmony_ci false, // explicitFlags 3388bf80f4bSopenharmony_ci true, // canPresent 3398bf80f4bSopenharmony_ci}; 3408bf80f4bSopenharmony_ci 3418bf80f4bSopenharmony_ciPlatformGpuMemoryAllocator::GpuMemoryAllocatorCreateInfo GetAllocatorCreateInfo(const BackendExtraVk* backendExtra) 3428bf80f4bSopenharmony_ci{ 3438bf80f4bSopenharmony_ci // create default pools 3448bf80f4bSopenharmony_ci PlatformGpuMemoryAllocator::GpuMemoryAllocatorCreateInfo createInfo; 3458bf80f4bSopenharmony_ci uint32_t dynamicUboByteSize = 16u * 1024u * 1024u; 3468bf80f4bSopenharmony_ci if (backendExtra) { 3478bf80f4bSopenharmony_ci const auto& sizes = backendExtra->gpuMemoryAllocatorSizes; 3488bf80f4bSopenharmony_ci if (sizes.defaultAllocationBlockSize != ~0u) { 3498bf80f4bSopenharmony_ci createInfo.preferredLargeHeapBlockSize = Math::min( 3508bf80f4bSopenharmony_ci MAX_ALLOCATION_BLOCK_SIZE, Math::max(sizes.defaultAllocationBlockSize, MIN_ALLOCATION_BLOCK_SIZE)); 3518bf80f4bSopenharmony_ci } 3528bf80f4bSopenharmony_ci if (sizes.customAllocationDynamicUboBlockSize != ~0u) { 3538bf80f4bSopenharmony_ci dynamicUboByteSize = Math::min(MAX_ALLOCATION_BLOCK_SIZE, 3548bf80f4bSopenharmony_ci Math::max(sizes.customAllocationDynamicUboBlockSize, MIN_ALLOCATION_BLOCK_SIZE)); 3558bf80f4bSopenharmony_ci } 3568bf80f4bSopenharmony_ci } 3578bf80f4bSopenharmony_ci 3588bf80f4bSopenharmony_ci // staging 3598bf80f4bSopenharmony_ci { 3608bf80f4bSopenharmony_ci GpuBufferDesc desc; 3618bf80f4bSopenharmony_ci desc.engineCreationFlags = EngineBufferCreationFlagBits::CORE_ENGINE_BUFFER_CREATION_SINGLE_SHOT_STAGING; 3628bf80f4bSopenharmony_ci desc.memoryPropertyFlags = MemoryPropertyFlagBits::CORE_MEMORY_PROPERTY_HOST_COHERENT_BIT | 3638bf80f4bSopenharmony_ci MemoryPropertyFlagBits::CORE_MEMORY_PROPERTY_HOST_VISIBLE_BIT; 3648bf80f4bSopenharmony_ci desc.usageFlags = BufferUsageFlagBits::CORE_BUFFER_USAGE_TRANSFER_SRC_BIT; 3658bf80f4bSopenharmony_ci createInfo.customPools.push_back({ 3668bf80f4bSopenharmony_ci "STAGING_GPU_BUFFER", 3678bf80f4bSopenharmony_ci PlatformGpuMemoryAllocator::MemoryAllocatorResourceType::GPU_BUFFER, 3688bf80f4bSopenharmony_ci 0u, 3698bf80f4bSopenharmony_ci // if linear allocator is used, depending clients usage pattern, memory can be easily wasted. 3708bf80f4bSopenharmony_ci false, 3718bf80f4bSopenharmony_ci { move(desc) }, 3728bf80f4bSopenharmony_ci }); 3738bf80f4bSopenharmony_ci } 3748bf80f4bSopenharmony_ci // dynamic uniform ring buffers 3758bf80f4bSopenharmony_ci { 3768bf80f4bSopenharmony_ci GpuBufferDesc desc; 3778bf80f4bSopenharmony_ci desc.engineCreationFlags = EngineBufferCreationFlagBits::CORE_ENGINE_BUFFER_CREATION_DYNAMIC_RING_BUFFER; 3788bf80f4bSopenharmony_ci desc.memoryPropertyFlags = MemoryPropertyFlagBits::CORE_MEMORY_PROPERTY_HOST_COHERENT_BIT | 3798bf80f4bSopenharmony_ci MemoryPropertyFlagBits::CORE_MEMORY_PROPERTY_HOST_VISIBLE_BIT; 3808bf80f4bSopenharmony_ci desc.usageFlags = BufferUsageFlagBits::CORE_BUFFER_USAGE_UNIFORM_BUFFER_BIT; 3818bf80f4bSopenharmony_ci createInfo.customPools.push_back({ 3828bf80f4bSopenharmony_ci "DYNAMIC_UNIFORM_GPU_BUFFER", 3838bf80f4bSopenharmony_ci PlatformGpuMemoryAllocator::MemoryAllocatorResourceType::GPU_BUFFER, 3848bf80f4bSopenharmony_ci dynamicUboByteSize, 3858bf80f4bSopenharmony_ci false, 3868bf80f4bSopenharmony_ci { move(desc) }, 3878bf80f4bSopenharmony_ci }); 3888bf80f4bSopenharmony_ci } 3898bf80f4bSopenharmony_ci 3908bf80f4bSopenharmony_ci return createInfo; 3918bf80f4bSopenharmony_ci} 3928bf80f4bSopenharmony_ci 3938bf80f4bSopenharmony_ciVkBool32 VKAPI_PTR DebugMessengerCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, 3948bf80f4bSopenharmony_ci VkDebugUtilsMessageTypeFlagsEXT messageTypes, const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, 3958bf80f4bSopenharmony_ci void* pUserData) 3968bf80f4bSopenharmony_ci{ 3978bf80f4bSopenharmony_ci if (pCallbackData && pCallbackData->pMessage) { 3988bf80f4bSopenharmony_ci if ((VkDebugUtilsMessageSeverityFlagsEXT)messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) { 3998bf80f4bSopenharmony_ci PLUGIN_LOG_E("%s: %s", pCallbackData->pMessageIdName, pCallbackData->pMessage); 4008bf80f4bSopenharmony_ci } else if ((VkDebugUtilsMessageSeverityFlagsEXT)messageSeverity & 4018bf80f4bSopenharmony_ci (VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT)) { 4028bf80f4bSopenharmony_ci PLUGIN_LOG_W("%s: %s", pCallbackData->pMessageIdName, pCallbackData->pMessage); 4038bf80f4bSopenharmony_ci } else if ((VkDebugUtilsMessageSeverityFlagsEXT)messageSeverity & 4048bf80f4bSopenharmony_ci VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT) { 4058bf80f4bSopenharmony_ci PLUGIN_LOG_I("%s: %s", pCallbackData->pMessageIdName, pCallbackData->pMessage); 4068bf80f4bSopenharmony_ci } else if ((VkDebugUtilsMessageSeverityFlagsEXT)messageSeverity & 4078bf80f4bSopenharmony_ci VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT) { 4088bf80f4bSopenharmony_ci PLUGIN_LOG_V("%s: %s", pCallbackData->pMessageIdName, pCallbackData->pMessage); 4098bf80f4bSopenharmony_ci } 4108bf80f4bSopenharmony_ci } 4118bf80f4bSopenharmony_ci 4128bf80f4bSopenharmony_ci // The application should always return VK_FALSE. 4138bf80f4bSopenharmony_ci return VK_FALSE; 4148bf80f4bSopenharmony_ci} 4158bf80f4bSopenharmony_ci 4168bf80f4bSopenharmony_ciVkBool32 VKAPI_PTR DebugReportCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT, uint64_t, size_t, 4178bf80f4bSopenharmony_ci int32_t, const char*, const char* pMessage, void*) 4188bf80f4bSopenharmony_ci{ 4198bf80f4bSopenharmony_ci if (flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) { 4208bf80f4bSopenharmony_ci PLUGIN_LOG_E("%s", pMessage); 4218bf80f4bSopenharmony_ci } else if (flags & (VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT)) { 4228bf80f4bSopenharmony_ci PLUGIN_LOG_W("%s", pMessage); 4238bf80f4bSopenharmony_ci } else if (flags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT) { 4248bf80f4bSopenharmony_ci PLUGIN_LOG_I("%s", pMessage); 4258bf80f4bSopenharmony_ci } else if (flags & VK_DEBUG_REPORT_DEBUG_BIT_EXT) { 4268bf80f4bSopenharmony_ci PLUGIN_LOG_D("%s", pMessage); 4278bf80f4bSopenharmony_ci } 4288bf80f4bSopenharmony_ci return VK_FALSE; 4298bf80f4bSopenharmony_ci} 4308bf80f4bSopenharmony_ci 4318bf80f4bSopenharmony_civoid EmplaceDeviceQueue( 4328bf80f4bSopenharmony_ci const VkDevice device, const LowLevelQueueInfo& aQueueInfo, vector<LowLevelGpuQueueVk>& aLowLevelQueues) 4338bf80f4bSopenharmony_ci{ 4348bf80f4bSopenharmony_ci for (uint32_t idx = 0; idx < aQueueInfo.queueCount; ++idx) { 4358bf80f4bSopenharmony_ci VkQueue queue = VK_NULL_HANDLE; 4368bf80f4bSopenharmony_ci vkGetDeviceQueue(device, // device 4378bf80f4bSopenharmony_ci aQueueInfo.queueFamilyIndex, // queueFamilyIndex 4388bf80f4bSopenharmony_ci idx, // queueIndex 4398bf80f4bSopenharmony_ci &queue); // pQueue 4408bf80f4bSopenharmony_ci aLowLevelQueues.push_back(LowLevelGpuQueueVk { queue, aQueueInfo }); 4418bf80f4bSopenharmony_ci } 4428bf80f4bSopenharmony_ci} 4438bf80f4bSopenharmony_ci 4448bf80f4bSopenharmony_civoid CheckValidDepthFormats(const DevicePlatformDataVk& devicePlat, DevicePlatformInternalDataVk& dataInternal) 4458bf80f4bSopenharmony_ci{ 4468bf80f4bSopenharmony_ci constexpr uint32_t DEPTH_FORMAT_COUNT { 4 }; 4478bf80f4bSopenharmony_ci constexpr Format DEPTH_FORMATS[DEPTH_FORMAT_COUNT] = { BASE_FORMAT_D24_UNORM_S8_UINT, BASE_FORMAT_D32_SFLOAT, 4488bf80f4bSopenharmony_ci BASE_FORMAT_D16_UNORM, BASE_FORMAT_X8_D24_UNORM_PACK32 }; 4498bf80f4bSopenharmony_ci for (uint32_t idx = 0; idx < DEPTH_FORMAT_COUNT; ++idx) { 4508bf80f4bSopenharmony_ci VkFormatProperties formatProperties; 4518bf80f4bSopenharmony_ci Format format = DEPTH_FORMATS[idx]; 4528bf80f4bSopenharmony_ci vkGetPhysicalDeviceFormatProperties(devicePlat.physicalDevice, // physicalDevice 4538bf80f4bSopenharmony_ci (VkFormat)format, // format 4548bf80f4bSopenharmony_ci &formatProperties); // pFormatProperties 4558bf80f4bSopenharmony_ci const VkFormatFeatureFlags optimalTilingFeatureFlags = formatProperties.optimalTilingFeatures; 4568bf80f4bSopenharmony_ci if (optimalTilingFeatureFlags & VkFormatFeatureFlagBits::VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) { 4578bf80f4bSopenharmony_ci dataInternal.supportedDepthFormats.push_back(format); 4588bf80f4bSopenharmony_ci } 4598bf80f4bSopenharmony_ci } 4608bf80f4bSopenharmony_ci} 4618bf80f4bSopenharmony_ci 4628bf80f4bSopenharmony_civector<string_view> GetPreferredDeviceExtensions(const BackendExtraVk* backendExtra, DevicePlatformDataVk& plat) 4638bf80f4bSopenharmony_ci{ 4648bf80f4bSopenharmony_ci vector<string_view> extensions { DEVICE_EXTENSION_SWAPCHAIN }; 4658bf80f4bSopenharmony_ci extensions.push_back(DEVICE_EXTENSION_CREATE_RENDERPASS2); 4668bf80f4bSopenharmony_ci extensions.push_back(DEVICE_EXTENSION_DEPTH_STENCIL_RESOLVE); 4678bf80f4bSopenharmony_ci extensions.push_back(DEVICE_EXTENSION_MAINTENANCE4); 4688bf80f4bSopenharmony_ci GetPlatformDeviceExtensions(extensions); 4698bf80f4bSopenharmony_ci#if (RENDER_VULKAN_FSR_ENABLED == 1) 4708bf80f4bSopenharmony_ci extensions.push_back(DEVICE_EXTENSION_FRAGMENT_SHADING_RATE); 4718bf80f4bSopenharmony_ci#endif 4728bf80f4bSopenharmony_ci#if (RENDER_VULKAN_RT_ENABLED == 1) 4738bf80f4bSopenharmony_ci extensions.push_back(DEVICE_EXTENSION_ACCELERATION_STRUCTURE); 4748bf80f4bSopenharmony_ci extensions.push_back(DEVICE_EXTENSION_RAY_TRACING_PIPELINE); 4758bf80f4bSopenharmony_ci extensions.push_back(DEVICE_EXTENSION_RAY_QUERY); 4768bf80f4bSopenharmony_ci extensions.push_back(DEVICE_EXTENSION_PIPELINE_LIBRARY); 4778bf80f4bSopenharmony_ci extensions.push_back(DEVICE_EXTENSION_DEFERRED_HOST_OPERATIONS); 4788bf80f4bSopenharmony_ci#endif 4798bf80f4bSopenharmony_ci if (plat.deviceApiMinor >= 1) { // enable only for 1.1+ 4808bf80f4bSopenharmony_ci extensions.push_back(DEVICE_EXTENSION_MULTIVIEW); 4818bf80f4bSopenharmony_ci } 4828bf80f4bSopenharmony_ci if (plat.deviceApiMinor >= 2) { // enable only for 1.2+ 4838bf80f4bSopenharmony_ci extensions.push_back(DEVICE_EXTENSION_DESCRIPTOR_INDEXING); 4848bf80f4bSopenharmony_ci } 4858bf80f4bSopenharmony_ci if (backendExtra) { 4868bf80f4bSopenharmony_ci for (const auto str : backendExtra->extensions.extensionNames) { 4878bf80f4bSopenharmony_ci extensions.push_back(str); 4888bf80f4bSopenharmony_ci } 4898bf80f4bSopenharmony_ci } 4908bf80f4bSopenharmony_ci return extensions; 4918bf80f4bSopenharmony_ci} 4928bf80f4bSopenharmony_ci 4938bf80f4bSopenharmony_ciDeviceVk::CommonDeviceExtensions GetEnabledCommonDeviceExtensions( 4948bf80f4bSopenharmony_ci const unordered_map<string, uint32_t>& enabledDeviceExtensions) 4958bf80f4bSopenharmony_ci{ 4968bf80f4bSopenharmony_ci DeviceVk::CommonDeviceExtensions extensions; 4978bf80f4bSopenharmony_ci extensions.swapchain = enabledDeviceExtensions.contains(DEVICE_EXTENSION_SWAPCHAIN); 4988bf80f4bSopenharmony_ci // renderpass2 required on 1.2, we only use renderpass 2 when we need depth stencil resolve 4998bf80f4bSopenharmony_ci extensions.renderPass2 = enabledDeviceExtensions.contains(DEVICE_EXTENSION_DEPTH_STENCIL_RESOLVE) && 5008bf80f4bSopenharmony_ci enabledDeviceExtensions.contains(DEVICE_EXTENSION_CREATE_RENDERPASS2); 5018bf80f4bSopenharmony_ci extensions.externalMemory = enabledDeviceExtensions.contains(DEVICE_EXTENSION_EXTERNAL_MEMORY); 5028bf80f4bSopenharmony_ci extensions.getMemoryRequirements2 = enabledDeviceExtensions.contains(DEVICE_EXTENSION_GET_MEMORY_REQUIREMENTS2); 5038bf80f4bSopenharmony_ci extensions.queueFamilyForeign = enabledDeviceExtensions.contains(DEVICE_EXTENSION_QUEUE_FAMILY_FOREIGN); 5048bf80f4bSopenharmony_ci extensions.samplerYcbcrConversion = enabledDeviceExtensions.contains(DEVICE_EXTENSION_SAMPLER_YCBCR_CONVERSION); 5058bf80f4bSopenharmony_ci extensions.multiView = enabledDeviceExtensions.contains(DEVICE_EXTENSION_MULTIVIEW); 5068bf80f4bSopenharmony_ci extensions.descriptorIndexing = enabledDeviceExtensions.contains(DEVICE_EXTENSION_DESCRIPTOR_INDEXING); 5078bf80f4bSopenharmony_ci#if (RENDER_VULKAN_FSR_ENABLED == 1) 5088bf80f4bSopenharmony_ci extensions.fragmentShadingRate = enabledDeviceExtensions.contains(DEVICE_EXTENSION_FRAGMENT_SHADING_RATE); 5098bf80f4bSopenharmony_ci#endif 5108bf80f4bSopenharmony_ci 5118bf80f4bSopenharmony_ci return extensions; 5128bf80f4bSopenharmony_ci} 5138bf80f4bSopenharmony_ci 5148bf80f4bSopenharmony_ciCommonDeviceProperties GetCommonDevicePropertiesFunc(const ChainObjects& co) 5158bf80f4bSopenharmony_ci{ 5168bf80f4bSopenharmony_ci CommonDeviceProperties cdp; 5178bf80f4bSopenharmony_ci#if (RENDER_VULKAN_FSR_ENABLED == 1) 5188bf80f4bSopenharmony_ci if (co.fsr) { 5198bf80f4bSopenharmony_ci const auto& fsrVk = co.fsr->physicalDeviceFragmentShadingRateProperties; 5208bf80f4bSopenharmony_ci cdp.fragmentShadingRateProperties.minFragmentShadingRateAttachmentTexelSize = { 5218bf80f4bSopenharmony_ci fsrVk.minFragmentShadingRateAttachmentTexelSize.width, 5228bf80f4bSopenharmony_ci fsrVk.minFragmentShadingRateAttachmentTexelSize.height 5238bf80f4bSopenharmony_ci }; 5248bf80f4bSopenharmony_ci cdp.fragmentShadingRateProperties.maxFragmentShadingRateAttachmentTexelSize = { 5258bf80f4bSopenharmony_ci fsrVk.maxFragmentShadingRateAttachmentTexelSize.width, 5268bf80f4bSopenharmony_ci fsrVk.maxFragmentShadingRateAttachmentTexelSize.height 5278bf80f4bSopenharmony_ci }; 5288bf80f4bSopenharmony_ci cdp.fragmentShadingRateProperties.maxFragmentSize = { fsrVk.maxFragmentSize.width, 5298bf80f4bSopenharmony_ci fsrVk.maxFragmentSize.height }; 5308bf80f4bSopenharmony_ci } 5318bf80f4bSopenharmony_ci#endif 5328bf80f4bSopenharmony_ci return cdp; 5338bf80f4bSopenharmony_ci} 5348bf80f4bSopenharmony_ci 5358bf80f4bSopenharmony_civoid PreparePhysicalDeviceFeaturesForEnabling(const BackendExtraVk* backendExtra, DevicePlatformDataVk& plat) 5368bf80f4bSopenharmony_ci{ 5378bf80f4bSopenharmony_ci // enable all by default and then disable few 5388bf80f4bSopenharmony_ci plat.enabledPhysicalDeviceFeatures = plat.physicalDeviceProperties.physicalDeviceFeatures; 5398bf80f4bSopenharmony_ci // prepare feature disable for core engine 5408bf80f4bSopenharmony_ci plat.enabledPhysicalDeviceFeatures.geometryShader = VK_FALSE; 5418bf80f4bSopenharmony_ci plat.enabledPhysicalDeviceFeatures.tessellationShader = VK_FALSE; 5428bf80f4bSopenharmony_ci plat.enabledPhysicalDeviceFeatures.sampleRateShading = VK_FALSE; 5438bf80f4bSopenharmony_ci plat.enabledPhysicalDeviceFeatures.occlusionQueryPrecise = VK_FALSE; 5448bf80f4bSopenharmony_ci plat.enabledPhysicalDeviceFeatures.pipelineStatisticsQuery = VK_FALSE; 5458bf80f4bSopenharmony_ci plat.enabledPhysicalDeviceFeatures.shaderTessellationAndGeometryPointSize = VK_FALSE; 5468bf80f4bSopenharmony_ci plat.enabledPhysicalDeviceFeatures.inheritedQueries = VK_FALSE; 5478bf80f4bSopenharmony_ci if (backendExtra) { 5488bf80f4bSopenharmony_ci // check for support and prepare enabling 5498bf80f4bSopenharmony_ci if (backendExtra->extensions.physicalDeviceFeaturesToEnable) { 5508bf80f4bSopenharmony_ci const size_t valueCount = sizeof(VkPhysicalDeviceFeatures) / sizeof(VkBool32); 5518bf80f4bSopenharmony_ci const array_view<const VkBool32> supported( 5528bf80f4bSopenharmony_ci reinterpret_cast<VkBool32*>(&plat.physicalDeviceProperties.physicalDeviceFeatures), valueCount); 5538bf80f4bSopenharmony_ci VkPhysicalDeviceFeatures* wantedFeatures = 5548bf80f4bSopenharmony_ci (&backendExtra->extensions.physicalDeviceFeaturesToEnable->features); 5558bf80f4bSopenharmony_ci const array_view<const VkBool32> wanted(reinterpret_cast<VkBool32*>(wantedFeatures), valueCount); 5568bf80f4bSopenharmony_ci 5578bf80f4bSopenharmony_ci array_view<VkBool32> enabledPhysicalDeviceFeatures( 5588bf80f4bSopenharmony_ci reinterpret_cast<VkBool32*>(&plat.enabledPhysicalDeviceFeatures), valueCount); 5598bf80f4bSopenharmony_ci for (size_t idx = 0; idx < valueCount; ++idx) { 5608bf80f4bSopenharmony_ci if (supported[idx] && wanted[idx]) { 5618bf80f4bSopenharmony_ci enabledPhysicalDeviceFeatures[idx] = VK_TRUE; 5628bf80f4bSopenharmony_ci } else if (wanted[idx]) { 5638bf80f4bSopenharmony_ci PLUGIN_LOG_W( 5648bf80f4bSopenharmony_ci "physical device feature not supported/enabled from idx: %u", static_cast<uint32_t>(idx)); 5658bf80f4bSopenharmony_ci } 5668bf80f4bSopenharmony_ci } 5678bf80f4bSopenharmony_ci } 5688bf80f4bSopenharmony_ci } 5698bf80f4bSopenharmony_ci} 5708bf80f4bSopenharmony_ci 5718bf80f4bSopenharmony_ciFormatProperties FillDeviceFormatSupport(VkPhysicalDevice physicalDevice, const Format format) 5728bf80f4bSopenharmony_ci{ 5738bf80f4bSopenharmony_ci VkFormatProperties formatProperties; 5748bf80f4bSopenharmony_ci vkGetPhysicalDeviceFormatProperties(physicalDevice, // physicalDevice 5758bf80f4bSopenharmony_ci (VkFormat)format, // format 5768bf80f4bSopenharmony_ci &formatProperties); // pFormatProperties 5778bf80f4bSopenharmony_ci return FormatProperties { 5788bf80f4bSopenharmony_ci (FormatFeatureFlags)formatProperties.linearTilingFeatures, 5798bf80f4bSopenharmony_ci (FormatFeatureFlags)formatProperties.optimalTilingFeatures, 5808bf80f4bSopenharmony_ci (FormatFeatureFlags)formatProperties.bufferFeatures, 5818bf80f4bSopenharmony_ci GpuProgramUtil::FormatByteSize(format), 5828bf80f4bSopenharmony_ci }; 5838bf80f4bSopenharmony_ci} 5848bf80f4bSopenharmony_ci 5858bf80f4bSopenharmony_civoid FillFormatSupport(VkPhysicalDevice physicalDevice, vector<FormatProperties>& formats) 5868bf80f4bSopenharmony_ci{ 5878bf80f4bSopenharmony_ci const uint32_t fullSize = DeviceFormatSupportConstants::LINEAR_FORMAT_MAX_COUNT + 5888bf80f4bSopenharmony_ci DeviceFormatSupportConstants::ADDITIONAL_FORMAT_MAX_COUNT; 5898bf80f4bSopenharmony_ci formats.resize(fullSize); 5908bf80f4bSopenharmony_ci for (uint32_t idx = 0; idx < DeviceFormatSupportConstants::LINEAR_FORMAT_MAX_COUNT; ++idx) { 5918bf80f4bSopenharmony_ci formats[idx] = FillDeviceFormatSupport(physicalDevice, static_cast<Format>(idx)); 5928bf80f4bSopenharmony_ci } 5938bf80f4bSopenharmony_ci // pre-build additional formats 5948bf80f4bSopenharmony_ci for (uint32_t idx = 0; idx < DeviceFormatSupportConstants::ADDITIONAL_FORMAT_MAX_COUNT; ++idx) { 5958bf80f4bSopenharmony_ci const uint32_t currIdx = idx + DeviceFormatSupportConstants::ADDITIONAL_FORMAT_BASE_IDX; 5968bf80f4bSopenharmony_ci PLUGIN_ASSERT(currIdx < static_cast<uint32_t>(formats.size())); 5978bf80f4bSopenharmony_ci const uint32_t formatIdx = idx + DeviceFormatSupportConstants::ADDITIONAL_FORMAT_START_NUMBER; 5988bf80f4bSopenharmony_ci formats[currIdx] = FillDeviceFormatSupport(physicalDevice, static_cast<Format>(formatIdx)); 5998bf80f4bSopenharmony_ci } 6008bf80f4bSopenharmony_ci} 6018bf80f4bSopenharmony_ci} // namespace 6028bf80f4bSopenharmony_ci 6038bf80f4bSopenharmony_ciDeviceVk::DeviceVk(RenderContext& renderContext, DeviceCreateInfo const& createInfo) : Device(renderContext, createInfo) 6048bf80f4bSopenharmony_ci{ 6058bf80f4bSopenharmony_ci // assume instance and device will be created internally 6068bf80f4bSopenharmony_ci ownInstanceAndDevice_ = true; 6078bf80f4bSopenharmony_ci 6088bf80f4bSopenharmony_ci const BackendExtraVk* backendExtra = static_cast<const BackendExtraVk*>(createInfo.backendConfiguration); 6098bf80f4bSopenharmony_ci // update internal state based the optional backend configuration given by the client. the size of queuProperties 6108bf80f4bSopenharmony_ci // will depend on the enableMultiQueue setting. 6118bf80f4bSopenharmony_ci const auto queueProperties = CheckExternalConfig(backendExtra); 6128bf80f4bSopenharmony_ci 6138bf80f4bSopenharmony_ci // these check internally ownInstanceAndDevice_ and skip creation if provided by user 6148bf80f4bSopenharmony_ci CreateInstance(); 6158bf80f4bSopenharmony_ci CreatePhysicalDevice(); 6168bf80f4bSopenharmony_ci 6178bf80f4bSopenharmony_ci const auto availableQueues = CreateFunctionsVk::GetAvailableQueues(plat_.physicalDevice, queueProperties); 6188bf80f4bSopenharmony_ci 6198bf80f4bSopenharmony_ci // own device creation does a lot of work for figuring out what to create, but for external device 6208bf80f4bSopenharmony_ci // CheckExternalConfig stored the enabled extensions and features, and we just need to check what is available 6218bf80f4bSopenharmony_ci if (ownInstanceAndDevice_) { 6228bf80f4bSopenharmony_ci CreateDevice(backendExtra, availableQueues); 6238bf80f4bSopenharmony_ci } else { 6248bf80f4bSopenharmony_ci commonDeviceExtensions_ = GetEnabledCommonDeviceExtensions(extensions_); 6258bf80f4bSopenharmony_ci platformDeviceExtensions_ = GetEnabledPlatformDeviceExtensions(extensions_); 6268bf80f4bSopenharmony_ci // filling commonDeviceProperties_ isn't done, but at the moment that only contains fragment rate shading 6278bf80f4bSopenharmony_ci // should walk through BackendExtraVk::extensions::physicalDeviceFeaturesToEnable::pNext and see what's 6288bf80f4bSopenharmony_ci // available. 6298bf80f4bSopenharmony_ci } 6308bf80f4bSopenharmony_ci 6318bf80f4bSopenharmony_ci CreateDebugFunctions(); 6328bf80f4bSopenharmony_ci CreateExtFunctions(); 6338bf80f4bSopenharmony_ci CreatePlatformExtFunctions(); 6348bf80f4bSopenharmony_ci SortAvailableQueues(availableQueues); 6358bf80f4bSopenharmony_ci 6368bf80f4bSopenharmony_ci CheckValidDepthFormats(plat_, platInternal_); 6378bf80f4bSopenharmony_ci FillFormatSupport(plat_.physicalDevice, formatProperties_); 6388bf80f4bSopenharmony_ci 6398bf80f4bSopenharmony_ci PLUGIN_ASSERT_MSG(!lowLevelGpuQueues_.graphicsQueues.empty(), "default queue not initialized"); 6408bf80f4bSopenharmony_ci if (!lowLevelGpuQueues_.graphicsQueues.empty()) { 6418bf80f4bSopenharmony_ci lowLevelGpuQueues_.defaultQueue = lowLevelGpuQueues_.graphicsQueues[0]; 6428bf80f4bSopenharmony_ci } else { 6438bf80f4bSopenharmony_ci PLUGIN_LOG_E("default vulkan queue not initialized"); 6448bf80f4bSopenharmony_ci } 6458bf80f4bSopenharmony_ci 6468bf80f4bSopenharmony_ci gpuQueueCount_ = 6478bf80f4bSopenharmony_ci static_cast<uint32_t>(lowLevelGpuQueues_.computeQueues.size() + lowLevelGpuQueues_.graphicsQueues.size() + 6488bf80f4bSopenharmony_ci lowLevelGpuQueues_.transferQueues.size()); 6498bf80f4bSopenharmony_ci 6508bf80f4bSopenharmony_ci const PlatformGpuMemoryAllocator::GpuMemoryAllocatorCreateInfo allocatorCreateInfo = 6518bf80f4bSopenharmony_ci GetAllocatorCreateInfo(backendExtra); 6528bf80f4bSopenharmony_ci platformGpuMemoryAllocator_ = make_unique<PlatformGpuMemoryAllocator>( 6538bf80f4bSopenharmony_ci plat_.instance, plat_.physicalDevice, plat_.device, allocatorCreateInfo); 6548bf80f4bSopenharmony_ci 6558bf80f4bSopenharmony_ci if (queueProperties.size() > 1) { 6568bf80f4bSopenharmony_ci PLUGIN_LOG_I("gpu queue count: %u", gpuQueueCount_); 6578bf80f4bSopenharmony_ci } 6588bf80f4bSopenharmony_ci 6598bf80f4bSopenharmony_ci SetDeviceStatus(true); 6608bf80f4bSopenharmony_ci 6618bf80f4bSopenharmony_ci const GpuResourceManager::CreateInfo grmCreateInfo { 6628bf80f4bSopenharmony_ci GpuResourceManager::GPU_RESOURCE_MANAGER_OPTIMIZE_STAGING_MEMORY, 6638bf80f4bSopenharmony_ci }; 6648bf80f4bSopenharmony_ci gpuResourceMgr_ = make_unique<GpuResourceManager>(*this, grmCreateInfo); 6658bf80f4bSopenharmony_ci shaderMgr_ = make_unique<ShaderManager>(*this); 6668bf80f4bSopenharmony_ci 6678bf80f4bSopenharmony_ci lowLevelDevice_ = make_unique<LowLevelDeviceVk>(*this); 6688bf80f4bSopenharmony_ci} 6698bf80f4bSopenharmony_ci 6708bf80f4bSopenharmony_ciDeviceVk::~DeviceVk() 6718bf80f4bSopenharmony_ci{ 6728bf80f4bSopenharmony_ci WaitForIdle(); 6738bf80f4bSopenharmony_ci 6748bf80f4bSopenharmony_ci // must release handles before taking down gpu resource manager. 6758bf80f4bSopenharmony_ci swapchains_.clear(); 6768bf80f4bSopenharmony_ci 6778bf80f4bSopenharmony_ci gpuResourceMgr_.reset(); 6788bf80f4bSopenharmony_ci shaderMgr_.reset(); 6798bf80f4bSopenharmony_ci 6808bf80f4bSopenharmony_ci platformGpuMemoryAllocator_.reset(); 6818bf80f4bSopenharmony_ci 6828bf80f4bSopenharmony_ci if (plat_.pipelineCache) { 6838bf80f4bSopenharmony_ci CreateFunctionsVk::DestroyPipelineCache(plat_.device, plat_.pipelineCache); 6848bf80f4bSopenharmony_ci } 6858bf80f4bSopenharmony_ci 6868bf80f4bSopenharmony_ci if (ownInstanceAndDevice_) { 6878bf80f4bSopenharmony_ci CreateFunctionsVk::DestroyDevice(plat_.device); 6888bf80f4bSopenharmony_ci CreateFunctionsVk::DestroyDebugMessenger(plat_.instance, debugFunctionUtilities_.debugMessenger); 6898bf80f4bSopenharmony_ci CreateFunctionsVk::DestroyDebugCallback(plat_.instance, debugFunctionUtilities_.debugCallback); 6908bf80f4bSopenharmony_ci CreateFunctionsVk::DestroyInstance(plat_.instance); 6918bf80f4bSopenharmony_ci } 6928bf80f4bSopenharmony_ci} 6938bf80f4bSopenharmony_ci 6948bf80f4bSopenharmony_civoid DeviceVk::CreateInstance() 6958bf80f4bSopenharmony_ci{ 6968bf80f4bSopenharmony_ci const auto instanceWrapper = (plat_.instance == VK_NULL_HANDLE) ? 6978bf80f4bSopenharmony_ci CreateFunctionsVk::CreateInstance(VersionInfo { "core_renderer", 0, 1, 0}, 6988bf80f4bSopenharmony_ci VersionInfo { "core_renderer_app", 0, 1, 0 }) : CreateFunctionsVk::GetWrapper(plat_.instance); 6998bf80f4bSopenharmony_ci 7008bf80f4bSopenharmony_ci plat_.instance = instanceWrapper.instance; 7018bf80f4bSopenharmony_ci // update with physical device creation 7028bf80f4bSopenharmony_ci plat_.deviceApiMajor = instanceWrapper.apiMajor; 7038bf80f4bSopenharmony_ci plat_.deviceApiMinor = instanceWrapper.apiMinor; 7048bf80f4bSopenharmony_ci if (instanceWrapper.debugUtilsSupported) { 7058bf80f4bSopenharmony_ci debugFunctionUtilities_.debugMessenger = 7068bf80f4bSopenharmony_ci CreateFunctionsVk::CreateDebugMessenger(plat_.instance, DebugMessengerCallback); 7078bf80f4bSopenharmony_ci } 7088bf80f4bSopenharmony_ci if (!debugFunctionUtilities_.debugMessenger && instanceWrapper.debugReportSupported) { 7098bf80f4bSopenharmony_ci debugFunctionUtilities_.debugCallback = 7108bf80f4bSopenharmony_ci CreateFunctionsVk::CreateDebugCallback(plat_.instance, DebugReportCallback); 7118bf80f4bSopenharmony_ci } 7128bf80f4bSopenharmony_ci 7138bf80f4bSopenharmony_ci extFunctions_.vkAcquireNextImageKHR = 7148bf80f4bSopenharmony_ci (PFN_vkAcquireNextImageKHR)(void*)vkGetInstanceProcAddr(plat_.instance, "vkAcquireNextImageKHR"); 7158bf80f4bSopenharmony_ci if ((plat_.deviceApiMajor >= 1) && (plat_.deviceApiMinor >= 1)) { 7168bf80f4bSopenharmony_ci extFunctions_.vkGetPhysicalDeviceFeatures2 = 7178bf80f4bSopenharmony_ci (PFN_vkGetPhysicalDeviceFeatures2)vkGetInstanceProcAddr(plat_.instance, "vkGetPhysicalDeviceFeatures2"); 7188bf80f4bSopenharmony_ci extFunctions_.vkGetPhysicalDeviceProperties2 = 7198bf80f4bSopenharmony_ci (PFN_vkGetPhysicalDeviceProperties2)vkGetInstanceProcAddr(plat_.instance, "vkGetPhysicalDeviceProperties2"); 7208bf80f4bSopenharmony_ci } 7218bf80f4bSopenharmony_ci} 7228bf80f4bSopenharmony_ci 7238bf80f4bSopenharmony_civoid DeviceVk::CreatePhysicalDevice() 7248bf80f4bSopenharmony_ci{ 7258bf80f4bSopenharmony_ci auto physicalDeviceWrapper = (plat_.physicalDevice == VK_NULL_HANDLE) ? 7268bf80f4bSopenharmony_ci CreateFunctionsVk::CreatePhysicalDevice(plat_.instance, DEFAULT_QUEUE ) : 7278bf80f4bSopenharmony_ci CreateFunctionsVk::GetWrapper(plat_.physicalDevice); 7288bf80f4bSopenharmony_ci const uint32_t physicalDeviceApiMajor = 7298bf80f4bSopenharmony_ci VK_VERSION_MAJOR(physicalDeviceWrapper.physicalDeviceProperties.physicalDeviceProperties.apiVersion); 7308bf80f4bSopenharmony_ci const uint32_t physicalDeviceApiMinor = 7318bf80f4bSopenharmony_ci VK_VERSION_MINOR(physicalDeviceWrapper.physicalDeviceProperties.physicalDeviceProperties.apiVersion); 7328bf80f4bSopenharmony_ci plat_.deviceApiMajor = Math::min(plat_.deviceApiMajor, physicalDeviceApiMajor); 7338bf80f4bSopenharmony_ci plat_.deviceApiMinor = Math::min(plat_.deviceApiMinor, physicalDeviceApiMinor); 7348bf80f4bSopenharmony_ci PLUGIN_LOG_D("device api version %u.%u", plat_.deviceApiMajor, plat_.deviceApiMinor); 7358bf80f4bSopenharmony_ci 7368bf80f4bSopenharmony_ci plat_.physicalDevice = physicalDeviceWrapper.physicalDevice; 7378bf80f4bSopenharmony_ci plat_.physicalDeviceProperties = move(physicalDeviceWrapper.physicalDeviceProperties); 7388bf80f4bSopenharmony_ci plat_.physicalDeviceExtensions = move(physicalDeviceWrapper.physicalDeviceExtensions); 7398bf80f4bSopenharmony_ci const auto& memoryProperties = plat_.physicalDeviceProperties.physicalDeviceMemoryProperties; 7408bf80f4bSopenharmony_ci deviceSharedMemoryPropertyFlags_ = 7418bf80f4bSopenharmony_ci (memoryProperties.memoryTypeCount > 0) ? (MemoryPropertyFlags)memoryProperties.memoryTypes[0].propertyFlags : 0; 7428bf80f4bSopenharmony_ci for (uint32_t idx = 1; idx < memoryProperties.memoryTypeCount; ++idx) { 7438bf80f4bSopenharmony_ci const MemoryPropertyFlags memoryPropertyFlags = 7448bf80f4bSopenharmony_ci (MemoryPropertyFlags)memoryProperties.memoryTypes[idx].propertyFlags; 7458bf80f4bSopenharmony_ci // do not compare lazily allocated or protected memory blocks 7468bf80f4bSopenharmony_ci if ((memoryPropertyFlags & (CORE_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT | CORE_MEMORY_PROPERTY_PROTECTED_BIT)) == 7478bf80f4bSopenharmony_ci 0) { 7488bf80f4bSopenharmony_ci deviceSharedMemoryPropertyFlags_ &= memoryPropertyFlags; 7498bf80f4bSopenharmony_ci } 7508bf80f4bSopenharmony_ci } 7518bf80f4bSopenharmony_ci} 7528bf80f4bSopenharmony_ci 7538bf80f4bSopenharmony_civoid DeviceVk::CreateDevice(const BackendExtraVk* backendExtra, const vector<LowLevelQueueInfo>& availableQueues) 7548bf80f4bSopenharmony_ci{ 7558bf80f4bSopenharmony_ci vector<string_view> preferredExtensions = GetPreferredDeviceExtensions(backendExtra, plat_); 7568bf80f4bSopenharmony_ci PreparePhysicalDeviceFeaturesForEnabling(backendExtra, plat_); 7578bf80f4bSopenharmony_ci 7588bf80f4bSopenharmony_ci ChainWrapper chainWrapper; 7598bf80f4bSopenharmony_ci ChainObjects chainObjects; 7608bf80f4bSopenharmony_ci 7618bf80f4bSopenharmony_ci VkPhysicalDeviceFeatures2* physicalDeviceFeatures2Ptr = nullptr; 7628bf80f4bSopenharmony_ci VkPhysicalDeviceFeatures2 physicalDeviceFeatures2 { 7638bf80f4bSopenharmony_ci VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2, // sType 7648bf80f4bSopenharmony_ci nullptr, // pNext 7658bf80f4bSopenharmony_ci {}, // features 7668bf80f4bSopenharmony_ci }; 7678bf80f4bSopenharmony_ci chainWrapper.ppNextFeatures = &physicalDeviceFeatures2.pNext; 7688bf80f4bSopenharmony_ci 7698bf80f4bSopenharmony_ci VkPhysicalDeviceProperties2 physicalDeviceProperties2 { 7708bf80f4bSopenharmony_ci VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2, // sType 7718bf80f4bSopenharmony_ci nullptr, // pNext 7728bf80f4bSopenharmony_ci {}, // properties 7738bf80f4bSopenharmony_ci }; 7748bf80f4bSopenharmony_ci chainWrapper.ppNextProperties = &physicalDeviceProperties2.pNext; 7758bf80f4bSopenharmony_ci 7768bf80f4bSopenharmony_ci GetPhysicalDeviceYcbcrStructs(chainObjects, chainWrapper); 7778bf80f4bSopenharmony_ci#if (RENDER_VULKAN_RT_ENABLED == 1) 7788bf80f4bSopenharmony_ci GetPhysicalDeviceRayTracingStructs(chainObjects, chainWrapper); 7798bf80f4bSopenharmony_ci#endif 7808bf80f4bSopenharmony_ci#if (RENDER_VULKAN_FSR_ENABLED == 1) 7818bf80f4bSopenharmony_ci if (CreateFunctionsVk::HasExtension(plat_.physicalDeviceExtensions, DEVICE_EXTENSION_FRAGMENT_SHADING_RATE)) { 7828bf80f4bSopenharmony_ci GetPhysicalDeviceFragmentShadingRateStructs(chainObjects, chainWrapper); 7838bf80f4bSopenharmony_ci } 7848bf80f4bSopenharmony_ci#endif 7858bf80f4bSopenharmony_ci if (plat_.deviceApiMinor >= 1) { // enable only for 1.1 + for now 7868bf80f4bSopenharmony_ci GetPhysicalDeviceMultiviewFeaturesStructs(chainObjects, chainWrapper); 7878bf80f4bSopenharmony_ci } 7888bf80f4bSopenharmony_ci if (plat_.deviceApiMinor >= 2) { // enable only for 1.2 + for now 7898bf80f4bSopenharmony_ci GetPhysicalDeviceDescriptorIndexingFeaturesStructs(chainObjects, chainWrapper); 7908bf80f4bSopenharmony_ci } 7918bf80f4bSopenharmony_ci if (CreateFunctionsVk::HasExtension(plat_.physicalDeviceExtensions, DEVICE_EXTENSION_MAINTENANCE4)) { 7928bf80f4bSopenharmony_ci GetPhysicalDeviceMaintenance4Structs(chainObjects, chainWrapper); 7938bf80f4bSopenharmony_ci } 7948bf80f4bSopenharmony_ci if ((plat_.deviceApiMajor >= 1) && (plat_.deviceApiMinor >= 1)) { 7958bf80f4bSopenharmony_ci // pipe user extension physical device features 7968bf80f4bSopenharmony_ci if (backendExtra) { 7978bf80f4bSopenharmony_ci if (backendExtra->extensions.physicalDeviceFeaturesToEnable) { 7988bf80f4bSopenharmony_ci *chainWrapper.ppNextFeatures = backendExtra->extensions.physicalDeviceFeaturesToEnable->pNext; 7998bf80f4bSopenharmony_ci } 8008bf80f4bSopenharmony_ci } 8018bf80f4bSopenharmony_ci if (extFunctions_.vkGetPhysicalDeviceFeatures2) { 8028bf80f4bSopenharmony_ci extFunctions_.vkGetPhysicalDeviceFeatures2(plat_.physicalDevice, &physicalDeviceFeatures2); 8038bf80f4bSopenharmony_ci } 8048bf80f4bSopenharmony_ci if (extFunctions_.vkGetPhysicalDeviceProperties2) { 8058bf80f4bSopenharmony_ci extFunctions_.vkGetPhysicalDeviceProperties2(plat_.physicalDevice, &physicalDeviceProperties2); 8068bf80f4bSopenharmony_ci } 8078bf80f4bSopenharmony_ci 8088bf80f4bSopenharmony_ci // vkGetPhysicalDeviceFeatures has already filled this and PreparePhysicalDeviceFeaturesForEnabling 8098bf80f4bSopenharmony_ci // disabled/ enabled some features. 8108bf80f4bSopenharmony_ci physicalDeviceFeatures2.features = plat_.enabledPhysicalDeviceFeatures; 8118bf80f4bSopenharmony_ci physicalDeviceFeatures2Ptr = &physicalDeviceFeatures2; 8128bf80f4bSopenharmony_ci } 8138bf80f4bSopenharmony_ci const DeviceWrapper deviceWrapper = 8148bf80f4bSopenharmony_ci CreateFunctionsVk::CreateDevice(plat_.instance, plat_.physicalDevice, plat_.physicalDeviceExtensions, 8158bf80f4bSopenharmony_ci plat_.enabledPhysicalDeviceFeatures, physicalDeviceFeatures2Ptr, availableQueues, preferredExtensions); 8168bf80f4bSopenharmony_ci plat_.device = deviceWrapper.device; 8178bf80f4bSopenharmony_ci for (const auto& ref : deviceWrapper.extensions) { 8188bf80f4bSopenharmony_ci extensions_[ref] = 1u; 8198bf80f4bSopenharmony_ci } 8208bf80f4bSopenharmony_ci commonDeviceExtensions_ = GetEnabledCommonDeviceExtensions(extensions_); 8218bf80f4bSopenharmony_ci platformDeviceExtensions_ = GetEnabledPlatformDeviceExtensions(extensions_); 8228bf80f4bSopenharmony_ci commonDeviceProperties_ = GetCommonDevicePropertiesFunc(chainObjects); 8238bf80f4bSopenharmony_ci} 8248bf80f4bSopenharmony_ci 8258bf80f4bSopenharmony_civector<QueueProperties> DeviceVk::CheckExternalConfig(const BackendExtraVk* backendConfiguration) 8268bf80f4bSopenharmony_ci{ 8278bf80f4bSopenharmony_ci vector<QueueProperties> queueProperties; 8288bf80f4bSopenharmony_ci queueProperties.push_back(DEFAULT_QUEUE); 8298bf80f4bSopenharmony_ci 8308bf80f4bSopenharmony_ci if (!backendConfiguration) { 8318bf80f4bSopenharmony_ci return queueProperties; 8328bf80f4bSopenharmony_ci } 8338bf80f4bSopenharmony_ci 8348bf80f4bSopenharmony_ci const auto& extra = *backendConfiguration; 8358bf80f4bSopenharmony_ci if (extra.enableMultiQueue) { 8368bf80f4bSopenharmony_ci queueProperties.push_back(QueueProperties { 8378bf80f4bSopenharmony_ci VK_QUEUE_COMPUTE_BIT, // requiredFlags 8388bf80f4bSopenharmony_ci 1, // count 8398bf80f4bSopenharmony_ci 1.0f, // priority 8408bf80f4bSopenharmony_ci true, // explicitFlags 8418bf80f4bSopenharmony_ci false, // canPresent 8428bf80f4bSopenharmony_ci }); 8438bf80f4bSopenharmony_ci PLUGIN_LOG_I("trying to enable gpu multi-queue, with queue count: %u", (uint32_t)queueProperties.size()); 8448bf80f4bSopenharmony_ci } 8458bf80f4bSopenharmony_ci 8468bf80f4bSopenharmony_ci if (extra.instance != VK_NULL_HANDLE) { 8478bf80f4bSopenharmony_ci PLUGIN_LOG_D("trying to use application given vulkan instance, device, and physical device"); 8488bf80f4bSopenharmony_ci PLUGIN_ASSERT((extra.instance && extra.physicalDevice && extra.device)); 8498bf80f4bSopenharmony_ci plat_.instance = extra.instance; 8508bf80f4bSopenharmony_ci plat_.physicalDevice = extra.physicalDevice; 8518bf80f4bSopenharmony_ci plat_.device = extra.device; 8528bf80f4bSopenharmony_ci if (extra.extensions.physicalDeviceFeaturesToEnable) { 8538bf80f4bSopenharmony_ci plat_.enabledPhysicalDeviceFeatures = extra.extensions.physicalDeviceFeaturesToEnable->features; 8548bf80f4bSopenharmony_ci } 8558bf80f4bSopenharmony_ci ownInstanceAndDevice_ = false; // everything given from the application 8568bf80f4bSopenharmony_ci 8578bf80f4bSopenharmony_ci const auto myDevice = plat_.physicalDevice; 8588bf80f4bSopenharmony_ci auto& myProperties = plat_.physicalDeviceProperties; 8598bf80f4bSopenharmony_ci vkGetPhysicalDeviceProperties(myDevice, &myProperties.physicalDeviceProperties); 8608bf80f4bSopenharmony_ci vkGetPhysicalDeviceFeatures(myDevice, &myProperties.physicalDeviceFeatures); 8618bf80f4bSopenharmony_ci vkGetPhysicalDeviceMemoryProperties(myDevice, &myProperties.physicalDeviceMemoryProperties); 8628bf80f4bSopenharmony_ci 8638bf80f4bSopenharmony_ci for (const auto& extension : extra.extensions.extensionNames) { 8648bf80f4bSopenharmony_ci extensions_[extension] = 1u; 8658bf80f4bSopenharmony_ci } 8668bf80f4bSopenharmony_ci } 8678bf80f4bSopenharmony_ci return queueProperties; 8688bf80f4bSopenharmony_ci} 8698bf80f4bSopenharmony_ci 8708bf80f4bSopenharmony_civoid DeviceVk::SortAvailableQueues(const vector<LowLevelQueueInfo>& availableQueues) 8718bf80f4bSopenharmony_ci{ 8728bf80f4bSopenharmony_ci for (const auto& ref : availableQueues) { 8738bf80f4bSopenharmony_ci if (ref.queueFlags == VkQueueFlagBits::VK_QUEUE_COMPUTE_BIT) { 8748bf80f4bSopenharmony_ci EmplaceDeviceQueue(plat_.device, ref, lowLevelGpuQueues_.computeQueues); 8758bf80f4bSopenharmony_ci } else if (ref.queueFlags == VkQueueFlagBits::VK_QUEUE_GRAPHICS_BIT) { 8768bf80f4bSopenharmony_ci EmplaceDeviceQueue(plat_.device, ref, lowLevelGpuQueues_.graphicsQueues); 8778bf80f4bSopenharmony_ci } else if (ref.queueFlags == VkQueueFlagBits::VK_QUEUE_TRANSFER_BIT) { 8788bf80f4bSopenharmony_ci EmplaceDeviceQueue(plat_.device, ref, lowLevelGpuQueues_.transferQueues); 8798bf80f4bSopenharmony_ci } 8808bf80f4bSopenharmony_ci } 8818bf80f4bSopenharmony_ci} 8828bf80f4bSopenharmony_ci 8838bf80f4bSopenharmony_ciDeviceBackendType DeviceVk::GetBackendType() const 8848bf80f4bSopenharmony_ci{ 8858bf80f4bSopenharmony_ci return DeviceBackendType::VULKAN; 8868bf80f4bSopenharmony_ci} 8878bf80f4bSopenharmony_ci 8888bf80f4bSopenharmony_ciconst DevicePlatformData& DeviceVk::GetPlatformData() const 8898bf80f4bSopenharmony_ci{ 8908bf80f4bSopenharmony_ci return plat_; 8918bf80f4bSopenharmony_ci} 8928bf80f4bSopenharmony_ci 8938bf80f4bSopenharmony_ciconst DevicePlatformDataVk& DeviceVk::GetPlatformDataVk() const 8948bf80f4bSopenharmony_ci{ 8958bf80f4bSopenharmony_ci return plat_; 8968bf80f4bSopenharmony_ci} 8978bf80f4bSopenharmony_ci 8988bf80f4bSopenharmony_ciconst DevicePlatformInternalDataVk& DeviceVk::GetPlatformInternalDataVk() const 8998bf80f4bSopenharmony_ci{ 9008bf80f4bSopenharmony_ci return platInternal_; 9018bf80f4bSopenharmony_ci} 9028bf80f4bSopenharmony_ci 9038bf80f4bSopenharmony_ciILowLevelDevice& DeviceVk::GetLowLevelDevice() const 9048bf80f4bSopenharmony_ci{ 9058bf80f4bSopenharmony_ci return *lowLevelDevice_; 9068bf80f4bSopenharmony_ci} 9078bf80f4bSopenharmony_ci 9088bf80f4bSopenharmony_ciFormatProperties DeviceVk::GetFormatProperties(const Format format) const 9098bf80f4bSopenharmony_ci{ 9108bf80f4bSopenharmony_ci const uint32_t formatSupportSize = static_cast<uint32_t>(formatProperties_.size()); 9118bf80f4bSopenharmony_ci const uint32_t formatIdx = static_cast<uint32_t>(format); 9128bf80f4bSopenharmony_ci if (formatIdx < formatSupportSize) { 9138bf80f4bSopenharmony_ci return formatProperties_[formatIdx]; 9148bf80f4bSopenharmony_ci } else if ((formatIdx >= DeviceFormatSupportConstants::ADDITIONAL_FORMAT_START_NUMBER) && 9158bf80f4bSopenharmony_ci (formatIdx <= DeviceFormatSupportConstants::ADDITIONAL_FORMAT_END_NUMBER)) { 9168bf80f4bSopenharmony_ci const uint32_t currIdx = formatIdx - DeviceFormatSupportConstants::ADDITIONAL_FORMAT_START_NUMBER; 9178bf80f4bSopenharmony_ci PLUGIN_UNUSED(currIdx); 9188bf80f4bSopenharmony_ci PLUGIN_ASSERT(currIdx < formatSupportSize); 9198bf80f4bSopenharmony_ci return formatProperties_[currIdx]; 9208bf80f4bSopenharmony_ci } 9218bf80f4bSopenharmony_ci return {}; 9228bf80f4bSopenharmony_ci} 9238bf80f4bSopenharmony_ci 9248bf80f4bSopenharmony_ciAccelerationStructureBuildSizes DeviceVk::GetAccelerationStructureBuildSizes( 9258bf80f4bSopenharmony_ci const AccelerationStructureBuildGeometryInfo& geometry, 9268bf80f4bSopenharmony_ci BASE_NS::array_view<const AccelerationStructureGeometryTrianglesInfo> triangles, 9278bf80f4bSopenharmony_ci BASE_NS::array_view<const AccelerationStructureGeometryAabbsInfo> aabbs, 9288bf80f4bSopenharmony_ci BASE_NS::array_view<const AccelerationStructureGeometryInstancesInfo> instances) const 9298bf80f4bSopenharmony_ci{ 9308bf80f4bSopenharmony_ci#if (RENDER_VULKAN_RT_ENABLED == 1) 9318bf80f4bSopenharmony_ci const VkDevice device = plat_.device; 9328bf80f4bSopenharmony_ci 9338bf80f4bSopenharmony_ci const size_t arraySize = triangles.size() + aabbs.size() + instances.size(); 9348bf80f4bSopenharmony_ci vector<VkAccelerationStructureGeometryKHR> geometryData(arraySize); 9358bf80f4bSopenharmony_ci vector<uint32_t> maxPrimitiveCounts(arraySize); 9368bf80f4bSopenharmony_ci uint32_t arrayIndex = 0; 9378bf80f4bSopenharmony_ci for (const auto& trianglesRef : triangles) { 9388bf80f4bSopenharmony_ci geometryData[arrayIndex] = VkAccelerationStructureGeometryKHR { 9398bf80f4bSopenharmony_ci VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR, // sType 9408bf80f4bSopenharmony_ci nullptr, // pNext 9418bf80f4bSopenharmony_ci VkGeometryTypeKHR::VK_GEOMETRY_TYPE_TRIANGLES_KHR, // geometryType 9428bf80f4bSopenharmony_ci {}, // geometry; 9438bf80f4bSopenharmony_ci VkGeometryFlagsKHR(trianglesRef.geometryFlags), // flags 9448bf80f4bSopenharmony_ci }; 9458bf80f4bSopenharmony_ci geometryData[arrayIndex].geometry.triangles = VkAccelerationStructureGeometryTrianglesDataKHR { 9468bf80f4bSopenharmony_ci VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR, // sType 9478bf80f4bSopenharmony_ci nullptr, // pNext 9488bf80f4bSopenharmony_ci VkFormat(trianglesRef.vertexFormat), // vertexFormat 9498bf80f4bSopenharmony_ci {}, // vertexData 9508bf80f4bSopenharmony_ci VkDeviceSize(trianglesRef.vertexStride), // vertexStride 9518bf80f4bSopenharmony_ci trianglesRef.maxVertex, // maxVertex 9528bf80f4bSopenharmony_ci VkIndexType(trianglesRef.indexType), // indexType 9538bf80f4bSopenharmony_ci {}, // indexData 9548bf80f4bSopenharmony_ci {}, // transformData 9558bf80f4bSopenharmony_ci }; 9568bf80f4bSopenharmony_ci maxPrimitiveCounts[arrayIndex] = trianglesRef.indexCount / 3u; // triangles; 9578bf80f4bSopenharmony_ci arrayIndex++; 9588bf80f4bSopenharmony_ci } 9598bf80f4bSopenharmony_ci for (const auto& aabbsRef : aabbs) { 9608bf80f4bSopenharmony_ci geometryData[arrayIndex] = VkAccelerationStructureGeometryKHR { 9618bf80f4bSopenharmony_ci VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR, // sType 9628bf80f4bSopenharmony_ci nullptr, // pNext 9638bf80f4bSopenharmony_ci VkGeometryTypeKHR::VK_GEOMETRY_TYPE_AABBS_KHR, // geometryType 9648bf80f4bSopenharmony_ci {}, // geometry; 9658bf80f4bSopenharmony_ci 0, // flags 9668bf80f4bSopenharmony_ci }; 9678bf80f4bSopenharmony_ci geometryData[arrayIndex].geometry.aabbs = VkAccelerationStructureGeometryAabbsDataKHR { 9688bf80f4bSopenharmony_ci VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_AABBS_DATA_KHR, // sType 9698bf80f4bSopenharmony_ci nullptr, // pNext 9708bf80f4bSopenharmony_ci {}, // data 9718bf80f4bSopenharmony_ci aabbsRef.stride, // stride 9728bf80f4bSopenharmony_ci }; 9738bf80f4bSopenharmony_ci maxPrimitiveCounts[arrayIndex] = 1u; 9748bf80f4bSopenharmony_ci arrayIndex++; 9758bf80f4bSopenharmony_ci } 9768bf80f4bSopenharmony_ci for (const auto& instancesRef : instances) { 9778bf80f4bSopenharmony_ci geometryData[arrayIndex] = VkAccelerationStructureGeometryKHR { 9788bf80f4bSopenharmony_ci VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR, // sType 9798bf80f4bSopenharmony_ci nullptr, // pNext 9808bf80f4bSopenharmony_ci VkGeometryTypeKHR::VK_GEOMETRY_TYPE_INSTANCES_KHR, // geometryType 9818bf80f4bSopenharmony_ci {}, // geometry; 9828bf80f4bSopenharmony_ci 0, // flags 9838bf80f4bSopenharmony_ci }; 9848bf80f4bSopenharmony_ci geometryData[arrayIndex].geometry.instances = VkAccelerationStructureGeometryInstancesDataKHR { 9858bf80f4bSopenharmony_ci VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_INSTANCES_DATA_KHR, // sType 9868bf80f4bSopenharmony_ci nullptr, // pNext 9878bf80f4bSopenharmony_ci instancesRef.arrayOfPointers, // arrayOfPointers 9888bf80f4bSopenharmony_ci {}, // data 9898bf80f4bSopenharmony_ci }; 9908bf80f4bSopenharmony_ci maxPrimitiveCounts[arrayIndex] = 1u; 9918bf80f4bSopenharmony_ci arrayIndex++; 9928bf80f4bSopenharmony_ci } 9938bf80f4bSopenharmony_ci 9948bf80f4bSopenharmony_ci const VkAccelerationStructureBuildGeometryInfoKHR geometryInfoVk { 9958bf80f4bSopenharmony_ci VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR, // sType 9968bf80f4bSopenharmony_ci nullptr, // pNext 9978bf80f4bSopenharmony_ci VkAccelerationStructureTypeKHR(geometry.type), // type 9988bf80f4bSopenharmony_ci VkBuildAccelerationStructureFlagsKHR(geometry.flags), // flags 9998bf80f4bSopenharmony_ci VkBuildAccelerationStructureModeKHR(geometry.mode), // mode 10008bf80f4bSopenharmony_ci VK_NULL_HANDLE, // srcAccelerationStructure 10018bf80f4bSopenharmony_ci VK_NULL_HANDLE, // dstAccelerationStructure 10028bf80f4bSopenharmony_ci arrayIndex, // geometryCount 10038bf80f4bSopenharmony_ci geometryData.data(), // pGeometries 10048bf80f4bSopenharmony_ci nullptr, // ppGeometries 10058bf80f4bSopenharmony_ci {}, // scratchData 10068bf80f4bSopenharmony_ci }; 10078bf80f4bSopenharmony_ci 10088bf80f4bSopenharmony_ci VkAccelerationStructureBuildSizesInfoKHR buildSizesInfo { 10098bf80f4bSopenharmony_ci VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR, // sType 10108bf80f4bSopenharmony_ci nullptr, // pNext 10118bf80f4bSopenharmony_ci 0, // accelerationStructureSize 10128bf80f4bSopenharmony_ci 0, // updateScratchSize 10138bf80f4bSopenharmony_ci 0, // buildScratchSize 10148bf80f4bSopenharmony_ci }; 10158bf80f4bSopenharmony_ci if ((arrayIndex > 0) && extFunctions_.vkGetAccelerationStructureBuildSizesKHR) { 10168bf80f4bSopenharmony_ci extFunctions_.vkGetAccelerationStructureBuildSizesKHR(device, // device 10178bf80f4bSopenharmony_ci VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, // buildType, 10188bf80f4bSopenharmony_ci &geometryInfoVk, // pBuildInfo 10198bf80f4bSopenharmony_ci maxPrimitiveCounts.data(), // pMaxPrimitiveCounts 10208bf80f4bSopenharmony_ci &buildSizesInfo); // pSizeInfo 10218bf80f4bSopenharmony_ci } 10228bf80f4bSopenharmony_ci 10238bf80f4bSopenharmony_ci return AccelerationStructureBuildSizes { 10248bf80f4bSopenharmony_ci static_cast<uint32_t>(buildSizesInfo.accelerationStructureSize), 10258bf80f4bSopenharmony_ci static_cast<uint32_t>(buildSizesInfo.updateScratchSize), 10268bf80f4bSopenharmony_ci static_cast<uint32_t>(buildSizesInfo.buildScratchSize), 10278bf80f4bSopenharmony_ci }; 10288bf80f4bSopenharmony_ci#else 10298bf80f4bSopenharmony_ci return AccelerationStructureBuildSizes { 0, 0, 0 }; 10308bf80f4bSopenharmony_ci#endif 10318bf80f4bSopenharmony_ci} 10328bf80f4bSopenharmony_ci 10338bf80f4bSopenharmony_ciunique_ptr<Swapchain> DeviceVk::CreateDeviceSwapchain(const SwapchainCreateInfo& swapchainCreateInfo) 10348bf80f4bSopenharmony_ci{ 10358bf80f4bSopenharmony_ci return make_unique<SwapchainVk>(*this, swapchainCreateInfo); 10368bf80f4bSopenharmony_ci} 10378bf80f4bSopenharmony_ci 10388bf80f4bSopenharmony_civoid DeviceVk::DestroyDeviceSwapchain() {} 10398bf80f4bSopenharmony_ci 10408bf80f4bSopenharmony_ciPlatformGpuMemoryAllocator* DeviceVk::GetPlatformGpuMemoryAllocator() 10418bf80f4bSopenharmony_ci{ 10428bf80f4bSopenharmony_ci return platformGpuMemoryAllocator_.get(); 10438bf80f4bSopenharmony_ci} 10448bf80f4bSopenharmony_ci 10458bf80f4bSopenharmony_ciGpuQueue DeviceVk::GetValidGpuQueue(const GpuQueue& gpuQueue) const 10468bf80f4bSopenharmony_ci{ 10478bf80f4bSopenharmony_ci const auto getSpecificQueue = [](const uint32_t queueIndex, const GpuQueue::QueueType queueType, 10488bf80f4bSopenharmony_ci const vector<LowLevelGpuQueueVk>& specificQueues, const GpuQueue& defaultQueue) { 10498bf80f4bSopenharmony_ci const uint32_t queueCount = (uint32_t)specificQueues.size(); 10508bf80f4bSopenharmony_ci if (queueIndex < queueCount) { 10518bf80f4bSopenharmony_ci return GpuQueue { queueType, queueIndex }; 10528bf80f4bSopenharmony_ci } else if (queueCount > 0) { 10538bf80f4bSopenharmony_ci return GpuQueue { queueType, 0 }; 10548bf80f4bSopenharmony_ci } 10558bf80f4bSopenharmony_ci return defaultQueue; 10568bf80f4bSopenharmony_ci }; 10578bf80f4bSopenharmony_ci 10588bf80f4bSopenharmony_ci GpuQueue defaultQueue { GpuQueue::QueueType::GRAPHICS, 0 }; 10598bf80f4bSopenharmony_ci if (gpuQueue.type == GpuQueue::QueueType::COMPUTE) { 10608bf80f4bSopenharmony_ci return getSpecificQueue( 10618bf80f4bSopenharmony_ci gpuQueue.index, GpuQueue::QueueType::COMPUTE, lowLevelGpuQueues_.computeQueues, defaultQueue); 10628bf80f4bSopenharmony_ci } else if (gpuQueue.type == GpuQueue::QueueType::GRAPHICS) { 10638bf80f4bSopenharmony_ci return getSpecificQueue( 10648bf80f4bSopenharmony_ci gpuQueue.index, GpuQueue::QueueType::GRAPHICS, lowLevelGpuQueues_.graphicsQueues, defaultQueue); 10658bf80f4bSopenharmony_ci } else if (gpuQueue.type == GpuQueue::QueueType::TRANSFER) { 10668bf80f4bSopenharmony_ci return getSpecificQueue( 10678bf80f4bSopenharmony_ci gpuQueue.index, GpuQueue::QueueType::TRANSFER, lowLevelGpuQueues_.transferQueues, defaultQueue); 10688bf80f4bSopenharmony_ci } else { 10698bf80f4bSopenharmony_ci return defaultQueue; 10708bf80f4bSopenharmony_ci } 10718bf80f4bSopenharmony_ci} 10728bf80f4bSopenharmony_ci 10738bf80f4bSopenharmony_ciuint32_t DeviceVk::GetGpuQueueCount() const 10748bf80f4bSopenharmony_ci{ 10758bf80f4bSopenharmony_ci return gpuQueueCount_; 10768bf80f4bSopenharmony_ci} 10778bf80f4bSopenharmony_ci 10788bf80f4bSopenharmony_civoid DeviceVk::InitializePipelineCache(array_view<const uint8_t> initialData) 10798bf80f4bSopenharmony_ci{ 10808bf80f4bSopenharmony_ci if (plat_.pipelineCache) { 10818bf80f4bSopenharmony_ci CreateFunctionsVk::DestroyPipelineCache(plat_.device, plat_.pipelineCache); 10828bf80f4bSopenharmony_ci } 10838bf80f4bSopenharmony_ci struct CacheHeader { 10848bf80f4bSopenharmony_ci uint32_t bytes; 10858bf80f4bSopenharmony_ci uint32_t version; 10868bf80f4bSopenharmony_ci uint32_t vendorId; 10878bf80f4bSopenharmony_ci uint32_t deviceId; 10888bf80f4bSopenharmony_ci uint8_t pipelineCacheUUID[VK_UUID_SIZE]; 10898bf80f4bSopenharmony_ci }; 10908bf80f4bSopenharmony_ci if (initialData.size() > sizeof(CacheHeader)) { 10918bf80f4bSopenharmony_ci CacheHeader header; 10928bf80f4bSopenharmony_ci CloneData(&header, sizeof(header), initialData.data(), sizeof(header)); 10938bf80f4bSopenharmony_ci const auto& props = plat_.physicalDeviceProperties.physicalDeviceProperties; 10948bf80f4bSopenharmony_ci if (header.version != VkPipelineCacheHeaderVersion::VK_PIPELINE_CACHE_HEADER_VERSION_ONE || 10958bf80f4bSopenharmony_ci header.vendorId != props.vendorID || header.deviceId != props.deviceID || 10968bf80f4bSopenharmony_ci memcmp(header.pipelineCacheUUID, props.pipelineCacheUUID, VK_UUID_SIZE)) { 10978bf80f4bSopenharmony_ci initialData = {}; 10988bf80f4bSopenharmony_ci } 10998bf80f4bSopenharmony_ci } 11008bf80f4bSopenharmony_ci 11018bf80f4bSopenharmony_ci plat_.pipelineCache = CreateFunctionsVk::CreatePipelineCache(plat_.device, initialData); 11028bf80f4bSopenharmony_ci} 11038bf80f4bSopenharmony_ci 11048bf80f4bSopenharmony_civector<uint8_t> DeviceVk::GetPipelineCache() const 11058bf80f4bSopenharmony_ci{ 11068bf80f4bSopenharmony_ci vector<uint8_t> deviceData; 11078bf80f4bSopenharmony_ci if (plat_.pipelineCache) { 11088bf80f4bSopenharmony_ci size_t dataSize = 0u; 11098bf80f4bSopenharmony_ci if (auto result = vkGetPipelineCacheData(plat_.device, plat_.pipelineCache, &dataSize, nullptr); 11108bf80f4bSopenharmony_ci result == VK_SUCCESS && dataSize) { 11118bf80f4bSopenharmony_ci deviceData.resize(dataSize); 11128bf80f4bSopenharmony_ci dataSize = deviceData.size(); 11138bf80f4bSopenharmony_ci result = vkGetPipelineCacheData(plat_.device, plat_.pipelineCache, &dataSize, deviceData.data()); 11148bf80f4bSopenharmony_ci if (result == VK_SUCCESS) { 11158bf80f4bSopenharmony_ci deviceData.resize(dataSize); 11168bf80f4bSopenharmony_ci } else { 11178bf80f4bSopenharmony_ci deviceData.clear(); 11188bf80f4bSopenharmony_ci } 11198bf80f4bSopenharmony_ci } 11208bf80f4bSopenharmony_ci } 11218bf80f4bSopenharmony_ci return deviceData; 11228bf80f4bSopenharmony_ci} 11238bf80f4bSopenharmony_ci 11248bf80f4bSopenharmony_ciLowLevelGpuQueueVk DeviceVk::GetGpuQueue(const GpuQueue& gpuQueue) const 11258bf80f4bSopenharmony_ci{ 11268bf80f4bSopenharmony_ci // 1. tries to return the typed queue with given index 11278bf80f4bSopenharmony_ci // 2. tries to return the typed queue with an index 0 11288bf80f4bSopenharmony_ci // 3. returns the default queue 11298bf80f4bSopenharmony_ci const auto getSpecificQueue = [](const uint32_t queueIndex, const vector<LowLevelGpuQueueVk>& specificQueues, 11308bf80f4bSopenharmony_ci const LowLevelGpuQueueVk& defaultQueue) { 11318bf80f4bSopenharmony_ci const uint32_t queueCount = (uint32_t)specificQueues.size(); 11328bf80f4bSopenharmony_ci if (queueIndex < queueCount) { 11338bf80f4bSopenharmony_ci return specificQueues[queueIndex]; 11348bf80f4bSopenharmony_ci } else if (queueCount > 0) { 11358bf80f4bSopenharmony_ci return specificQueues[0]; 11368bf80f4bSopenharmony_ci } 11378bf80f4bSopenharmony_ci return defaultQueue; 11388bf80f4bSopenharmony_ci }; 11398bf80f4bSopenharmony_ci 11408bf80f4bSopenharmony_ci if (gpuQueue.type == GpuQueue::QueueType::COMPUTE) { 11418bf80f4bSopenharmony_ci return getSpecificQueue(gpuQueue.index, lowLevelGpuQueues_.computeQueues, lowLevelGpuQueues_.defaultQueue); 11428bf80f4bSopenharmony_ci } else if (gpuQueue.type == GpuQueue::QueueType::GRAPHICS) { 11438bf80f4bSopenharmony_ci return getSpecificQueue(gpuQueue.index, lowLevelGpuQueues_.graphicsQueues, lowLevelGpuQueues_.defaultQueue); 11448bf80f4bSopenharmony_ci } else if (gpuQueue.type == GpuQueue::QueueType::TRANSFER) { 11458bf80f4bSopenharmony_ci return getSpecificQueue(gpuQueue.index, lowLevelGpuQueues_.transferQueues, lowLevelGpuQueues_.defaultQueue); 11468bf80f4bSopenharmony_ci } else { 11478bf80f4bSopenharmony_ci return lowLevelGpuQueues_.defaultQueue; 11488bf80f4bSopenharmony_ci } 11498bf80f4bSopenharmony_ci} 11508bf80f4bSopenharmony_ci 11518bf80f4bSopenharmony_ciLowLevelGpuQueueVk DeviceVk::GetPresentationGpuQueue() const 11528bf80f4bSopenharmony_ci{ 11538bf80f4bSopenharmony_ci // NOTE: expected presentation 11548bf80f4bSopenharmony_ci return GetGpuQueue(GpuQueue { GpuQueue::QueueType::GRAPHICS, 0 }); 11558bf80f4bSopenharmony_ci} 11568bf80f4bSopenharmony_ci 11578bf80f4bSopenharmony_civector<LowLevelGpuQueueVk> DeviceVk::GetLowLevelGpuQueues() const 11588bf80f4bSopenharmony_ci{ 11598bf80f4bSopenharmony_ci vector<LowLevelGpuQueueVk> gpuQueues; 11608bf80f4bSopenharmony_ci gpuQueues.reserve(gpuQueueCount_); 11618bf80f4bSopenharmony_ci gpuQueues.insert(gpuQueues.end(), lowLevelGpuQueues_.computeQueues.begin(), lowLevelGpuQueues_.computeQueues.end()); 11628bf80f4bSopenharmony_ci gpuQueues.insert( 11638bf80f4bSopenharmony_ci gpuQueues.end(), lowLevelGpuQueues_.graphicsQueues.begin(), lowLevelGpuQueues_.graphicsQueues.end()); 11648bf80f4bSopenharmony_ci gpuQueues.insert( 11658bf80f4bSopenharmony_ci gpuQueues.end(), lowLevelGpuQueues_.transferQueues.begin(), lowLevelGpuQueues_.transferQueues.end()); 11668bf80f4bSopenharmony_ci return gpuQueues; 11678bf80f4bSopenharmony_ci} 11688bf80f4bSopenharmony_ci 11698bf80f4bSopenharmony_civoid DeviceVk::WaitForIdle() 11708bf80f4bSopenharmony_ci{ 11718bf80f4bSopenharmony_ci if (plat_.device) { 11728bf80f4bSopenharmony_ci if (!isRenderbackendRunning_) { 11738bf80f4bSopenharmony_ci PLUGIN_LOG_D("Device - WaitForIdle"); 11748bf80f4bSopenharmony_ci vkDeviceWaitIdle(plat_.device); // device 11758bf80f4bSopenharmony_ci } else { 11768bf80f4bSopenharmony_ci PLUGIN_LOG_E("Device WaitForIdle can only called when render backend is not running"); 11778bf80f4bSopenharmony_ci } 11788bf80f4bSopenharmony_ci } 11798bf80f4bSopenharmony_ci} 11808bf80f4bSopenharmony_ci 11818bf80f4bSopenharmony_civoid DeviceVk::Activate() {} 11828bf80f4bSopenharmony_ci 11838bf80f4bSopenharmony_civoid DeviceVk::Deactivate() {} 11848bf80f4bSopenharmony_ci 11858bf80f4bSopenharmony_cibool DeviceVk::AllowThreadedProcessing() const 11868bf80f4bSopenharmony_ci{ 11878bf80f4bSopenharmony_ci return true; 11888bf80f4bSopenharmony_ci} 11898bf80f4bSopenharmony_ci 11908bf80f4bSopenharmony_ciconst DeviceVk::FeatureConfigurations& DeviceVk::GetFeatureConfigurations() const 11918bf80f4bSopenharmony_ci{ 11928bf80f4bSopenharmony_ci return featureConfigurations_; 11938bf80f4bSopenharmony_ci} 11948bf80f4bSopenharmony_ci 11958bf80f4bSopenharmony_ciconst DeviceVk::CommonDeviceExtensions& DeviceVk::GetCommonDeviceExtensions() const 11968bf80f4bSopenharmony_ci{ 11978bf80f4bSopenharmony_ci return commonDeviceExtensions_; 11988bf80f4bSopenharmony_ci} 11998bf80f4bSopenharmony_ci 12008bf80f4bSopenharmony_ciconst PlatformDeviceExtensions& DeviceVk::GetPlatformDeviceExtensions() const 12018bf80f4bSopenharmony_ci{ 12028bf80f4bSopenharmony_ci return platformDeviceExtensions_; 12038bf80f4bSopenharmony_ci} 12048bf80f4bSopenharmony_ci 12058bf80f4bSopenharmony_cibool DeviceVk::HasDeviceExtension(const string_view extensionName) const 12068bf80f4bSopenharmony_ci{ 12078bf80f4bSopenharmony_ci return extensions_.contains(extensionName); 12088bf80f4bSopenharmony_ci} 12098bf80f4bSopenharmony_ci 12108bf80f4bSopenharmony_ciunique_ptr<Device> CreateDeviceVk(RenderContext& renderContext, DeviceCreateInfo const& createInfo) 12118bf80f4bSopenharmony_ci{ 12128bf80f4bSopenharmony_ci return make_unique<DeviceVk>(renderContext, createInfo); 12138bf80f4bSopenharmony_ci} 12148bf80f4bSopenharmony_ci 12158bf80f4bSopenharmony_ciunique_ptr<GpuBuffer> DeviceVk::CreateGpuBuffer(const GpuBufferDesc& desc) 12168bf80f4bSopenharmony_ci{ 12178bf80f4bSopenharmony_ci return make_unique<GpuBufferVk>(*this, desc); 12188bf80f4bSopenharmony_ci} 12198bf80f4bSopenharmony_ci 12208bf80f4bSopenharmony_ciunique_ptr<GpuBuffer> DeviceVk::CreateGpuBuffer(const GpuAccelerationStructureDesc& descAccel) 12218bf80f4bSopenharmony_ci{ 12228bf80f4bSopenharmony_ci return make_unique<GpuBufferVk>(*this, descAccel); 12238bf80f4bSopenharmony_ci} 12248bf80f4bSopenharmony_ci 12258bf80f4bSopenharmony_ciunique_ptr<GpuImage> DeviceVk::CreateGpuImage(const GpuImageDesc& desc) 12268bf80f4bSopenharmony_ci{ 12278bf80f4bSopenharmony_ci return make_unique<GpuImageVk>(*this, desc); 12288bf80f4bSopenharmony_ci} 12298bf80f4bSopenharmony_ci 12308bf80f4bSopenharmony_ciunique_ptr<GpuImage> DeviceVk::CreateGpuImageView( 12318bf80f4bSopenharmony_ci const GpuImageDesc& desc, const GpuImagePlatformData& platformData, const uintptr_t hwBuffer) 12328bf80f4bSopenharmony_ci{ 12338bf80f4bSopenharmony_ci return make_unique<GpuImageVk>(*this, desc, platformData, hwBuffer); 12348bf80f4bSopenharmony_ci} 12358bf80f4bSopenharmony_ci 12368bf80f4bSopenharmony_ciunique_ptr<GpuImage> DeviceVk::CreateGpuImageView(const GpuImageDesc& desc, const GpuImagePlatformData& platformData) 12378bf80f4bSopenharmony_ci{ 12388bf80f4bSopenharmony_ci return CreateGpuImageView(desc, platformData, 0); 12398bf80f4bSopenharmony_ci} 12408bf80f4bSopenharmony_ci 12418bf80f4bSopenharmony_civector<unique_ptr<GpuImage>> DeviceVk::CreateGpuImageViews(const Swapchain& swapchain) 12428bf80f4bSopenharmony_ci{ 12438bf80f4bSopenharmony_ci const GpuImageDesc& desc = swapchain.GetDesc(); 12448bf80f4bSopenharmony_ci const auto& swapchainPlat = static_cast<const SwapchainVk&>(swapchain).GetPlatformData(); 12458bf80f4bSopenharmony_ci 12468bf80f4bSopenharmony_ci vector<unique_ptr<GpuImage>> gpuImages(swapchainPlat.swapchainImages.images.size()); 12478bf80f4bSopenharmony_ci for (size_t idx = 0; idx < gpuImages.size(); ++idx) { 12488bf80f4bSopenharmony_ci GpuImagePlatformDataVk gpuImagePlat; 12498bf80f4bSopenharmony_ci gpuImagePlat.image = swapchainPlat.swapchainImages.images[idx]; 12508bf80f4bSopenharmony_ci gpuImagePlat.imageView = swapchainPlat.swapchainImages.imageViews[idx]; 12518bf80f4bSopenharmony_ci gpuImages[idx] = this->CreateGpuImageView(desc, gpuImagePlat); 12528bf80f4bSopenharmony_ci } 12538bf80f4bSopenharmony_ci return gpuImages; 12548bf80f4bSopenharmony_ci} 12558bf80f4bSopenharmony_ci 12568bf80f4bSopenharmony_ciunique_ptr<GpuImage> DeviceVk::CreateGpuImageView( 12578bf80f4bSopenharmony_ci const GpuImageDesc& desc, const BackendSpecificImageDesc& platformData) 12588bf80f4bSopenharmony_ci{ 12598bf80f4bSopenharmony_ci const ImageDescVk& imageDesc = (const ImageDescVk&)platformData; 12608bf80f4bSopenharmony_ci GpuImagePlatformDataVk platData; 12618bf80f4bSopenharmony_ci platData.image = imageDesc.image; 12628bf80f4bSopenharmony_ci platData.imageView = imageDesc.imageView; 12638bf80f4bSopenharmony_ci return CreateGpuImageView(desc, platData, imageDesc.platformHwBuffer); 12648bf80f4bSopenharmony_ci} 12658bf80f4bSopenharmony_ci 12668bf80f4bSopenharmony_ciunique_ptr<GpuSampler> DeviceVk::CreateGpuSampler(const GpuSamplerDesc& desc) 12678bf80f4bSopenharmony_ci{ 12688bf80f4bSopenharmony_ci return make_unique<GpuSamplerVk>(*this, desc); 12698bf80f4bSopenharmony_ci} 12708bf80f4bSopenharmony_ci 12718bf80f4bSopenharmony_ciunique_ptr<RenderFrameSync> DeviceVk::CreateRenderFrameSync() 12728bf80f4bSopenharmony_ci{ 12738bf80f4bSopenharmony_ci return make_unique<RenderFrameSyncVk>(*this); 12748bf80f4bSopenharmony_ci} 12758bf80f4bSopenharmony_ci 12768bf80f4bSopenharmony_ciunique_ptr<RenderBackend> DeviceVk::CreateRenderBackend( 12778bf80f4bSopenharmony_ci GpuResourceManager& gpuResourceMgr, const CORE_NS::IParallelTaskQueue::Ptr& queue) 12788bf80f4bSopenharmony_ci{ 12798bf80f4bSopenharmony_ci return make_unique<RenderBackendVk>(*this, gpuResourceMgr, queue); 12808bf80f4bSopenharmony_ci} 12818bf80f4bSopenharmony_ci 12828bf80f4bSopenharmony_ciunique_ptr<ShaderModule> DeviceVk::CreateShaderModule(const ShaderModuleCreateInfo& data) 12838bf80f4bSopenharmony_ci{ 12848bf80f4bSopenharmony_ci return make_unique<ShaderModuleVk>(*this, data); 12858bf80f4bSopenharmony_ci} 12868bf80f4bSopenharmony_ci 12878bf80f4bSopenharmony_ciunique_ptr<ShaderModule> DeviceVk::CreateComputeShaderModule(const ShaderModuleCreateInfo& data) 12888bf80f4bSopenharmony_ci{ 12898bf80f4bSopenharmony_ci return make_unique<ShaderModuleVk>(*this, data); 12908bf80f4bSopenharmony_ci} 12918bf80f4bSopenharmony_ci 12928bf80f4bSopenharmony_ciunique_ptr<GpuShaderProgram> DeviceVk::CreateGpuShaderProgram(const GpuShaderProgramCreateData& data) 12938bf80f4bSopenharmony_ci{ 12948bf80f4bSopenharmony_ci return make_unique<GpuShaderProgramVk>(*this, data); 12958bf80f4bSopenharmony_ci} 12968bf80f4bSopenharmony_ci 12978bf80f4bSopenharmony_ciunique_ptr<GpuComputeProgram> DeviceVk::CreateGpuComputeProgram(const GpuComputeProgramCreateData& data) 12988bf80f4bSopenharmony_ci{ 12998bf80f4bSopenharmony_ci return make_unique<GpuComputeProgramVk>(*this, data); 13008bf80f4bSopenharmony_ci} 13018bf80f4bSopenharmony_ci 13028bf80f4bSopenharmony_ciunique_ptr<NodeContextDescriptorSetManager> DeviceVk::CreateNodeContextDescriptorSetManager() 13038bf80f4bSopenharmony_ci{ 13048bf80f4bSopenharmony_ci return make_unique<NodeContextDescriptorSetManagerVk>(*this); 13058bf80f4bSopenharmony_ci} 13068bf80f4bSopenharmony_ci 13078bf80f4bSopenharmony_ciunique_ptr<NodeContextPoolManager> DeviceVk::CreateNodeContextPoolManager( 13088bf80f4bSopenharmony_ci GpuResourceManager& gpuResourceMgr, const GpuQueue& gpuQueue) 13098bf80f4bSopenharmony_ci{ 13108bf80f4bSopenharmony_ci return make_unique<NodeContextPoolManagerVk>(*this, gpuResourceMgr, gpuQueue); 13118bf80f4bSopenharmony_ci} 13128bf80f4bSopenharmony_ci 13138bf80f4bSopenharmony_ciunique_ptr<GraphicsPipelineStateObject> DeviceVk::CreateGraphicsPipelineStateObject(const GpuShaderProgram& gpuProgram, 13148bf80f4bSopenharmony_ci const GraphicsState& graphicsState, const PipelineLayout& pipelineLayout, 13158bf80f4bSopenharmony_ci const VertexInputDeclarationView& vertexInputDeclaration, 13168bf80f4bSopenharmony_ci const ShaderSpecializationConstantDataView& specializationConstants, 13178bf80f4bSopenharmony_ci const array_view<const DynamicStateEnum> dynamicStates, const RenderPassDesc& renderPassDesc, 13188bf80f4bSopenharmony_ci const array_view<const RenderPassSubpassDesc>& renderPassSubpassDescs, const uint32_t subpassIndex, 13198bf80f4bSopenharmony_ci const LowLevelRenderPassData* renderPassData, const LowLevelPipelineLayoutData* pipelineLayoutData) 13208bf80f4bSopenharmony_ci{ 13218bf80f4bSopenharmony_ci PLUGIN_ASSERT(renderPassData); 13228bf80f4bSopenharmony_ci PLUGIN_ASSERT(pipelineLayoutData); 13238bf80f4bSopenharmony_ci return make_unique<GraphicsPipelineStateObjectVk>(*this, gpuProgram, graphicsState, pipelineLayout, 13248bf80f4bSopenharmony_ci vertexInputDeclaration, specializationConstants, dynamicStates, renderPassDesc, renderPassSubpassDescs, 13258bf80f4bSopenharmony_ci subpassIndex, *renderPassData, *pipelineLayoutData); 13268bf80f4bSopenharmony_ci} 13278bf80f4bSopenharmony_ci 13288bf80f4bSopenharmony_ciunique_ptr<ComputePipelineStateObject> DeviceVk::CreateComputePipelineStateObject(const GpuComputeProgram& gpuProgram, 13298bf80f4bSopenharmony_ci const PipelineLayout& pipelineLayout, const ShaderSpecializationConstantDataView& specializationConstants, 13308bf80f4bSopenharmony_ci const LowLevelPipelineLayoutData* pipelineLayoutData) 13318bf80f4bSopenharmony_ci{ 13328bf80f4bSopenharmony_ci PLUGIN_ASSERT(pipelineLayoutData); 13338bf80f4bSopenharmony_ci return make_unique<ComputePipelineStateObjectVk>( 13348bf80f4bSopenharmony_ci *this, gpuProgram, pipelineLayout, specializationConstants, *pipelineLayoutData); 13358bf80f4bSopenharmony_ci} 13368bf80f4bSopenharmony_ci 13378bf80f4bSopenharmony_ciunique_ptr<GpuSemaphore> DeviceVk::CreateGpuSemaphore() 13388bf80f4bSopenharmony_ci{ 13398bf80f4bSopenharmony_ci return make_unique<GpuSemaphoreVk>(*this); 13408bf80f4bSopenharmony_ci} 13418bf80f4bSopenharmony_ci 13428bf80f4bSopenharmony_ciunique_ptr<GpuSemaphore> DeviceVk::CreateGpuSemaphoreView(const uint64_t handle) 13438bf80f4bSopenharmony_ci{ 13448bf80f4bSopenharmony_ci return make_unique<GpuSemaphoreVk>(*this, handle); 13458bf80f4bSopenharmony_ci} 13468bf80f4bSopenharmony_ci 13478bf80f4bSopenharmony_ciconst DebugFunctionUtilitiesVk& DeviceVk::GetDebugFunctionUtilities() const 13488bf80f4bSopenharmony_ci{ 13498bf80f4bSopenharmony_ci return debugFunctionUtilities_; 13508bf80f4bSopenharmony_ci} 13518bf80f4bSopenharmony_ci 13528bf80f4bSopenharmony_civoid DeviceVk::CreateDebugFunctions() 13538bf80f4bSopenharmony_ci{ 13548bf80f4bSopenharmony_ci#if (RENDER_VULKAN_VALIDATION_ENABLED == 1) 13558bf80f4bSopenharmony_ci debugFunctionUtilities_.vkSetDebugUtilsObjectNameEXT = 13568bf80f4bSopenharmony_ci (PFN_vkSetDebugUtilsObjectNameEXT)(void*)vkGetDeviceProcAddr(plat_.device, "vkSetDebugUtilsObjectNameEXT"); 13578bf80f4bSopenharmony_ci#endif 13588bf80f4bSopenharmony_ci#if (RENDER_DEBUG_MARKERS_ENABLED == 1) || (RENDER_DEBUG_COMMAND_MARKERS_ENABLED == 1) 13598bf80f4bSopenharmony_ci debugFunctionUtilities_.vkCmdBeginDebugUtilsLabelEXT = 13608bf80f4bSopenharmony_ci (PFN_vkCmdBeginDebugUtilsLabelEXT)vkGetInstanceProcAddr(plat_.instance, "vkCmdBeginDebugUtilsLabelEXT"); 13618bf80f4bSopenharmony_ci debugFunctionUtilities_.vkCmdEndDebugUtilsLabelEXT = 13628bf80f4bSopenharmony_ci (PFN_vkCmdEndDebugUtilsLabelEXT)vkGetInstanceProcAddr(plat_.instance, "vkCmdEndDebugUtilsLabelEXT"); 13638bf80f4bSopenharmony_ci#endif 13648bf80f4bSopenharmony_ci} 13658bf80f4bSopenharmony_ci 13668bf80f4bSopenharmony_ciconst DeviceVk::ExtFunctions& DeviceVk::GetExtFunctions() const 13678bf80f4bSopenharmony_ci{ 13688bf80f4bSopenharmony_ci return extFunctions_; 13698bf80f4bSopenharmony_ci} 13708bf80f4bSopenharmony_ci 13718bf80f4bSopenharmony_ciconst PlatformExtFunctions& DeviceVk::GetPlatformExtFunctions() const 13728bf80f4bSopenharmony_ci{ 13738bf80f4bSopenharmony_ci return platformExtFunctions_; 13748bf80f4bSopenharmony_ci} 13758bf80f4bSopenharmony_ci 13768bf80f4bSopenharmony_civoid DeviceVk::CreateExtFunctions() 13778bf80f4bSopenharmony_ci{ 13788bf80f4bSopenharmony_ci if (commonDeviceExtensions_.renderPass2) { 13798bf80f4bSopenharmony_ci extFunctions_.vkCreateRenderPass2KHR = 13808bf80f4bSopenharmony_ci (PFN_vkCreateRenderPass2KHR)(void*)vkGetInstanceProcAddr(plat_.instance, "vkCreateRenderPass2KHR"); 13818bf80f4bSopenharmony_ci if (!extFunctions_.vkCreateRenderPass2KHR) { 13828bf80f4bSopenharmony_ci commonDeviceExtensions_.renderPass2 = false; 13838bf80f4bSopenharmony_ci PLUGIN_LOG_E("vkGetInstanceProcAddr failed for vkCreateRenderPass2KHR"); 13848bf80f4bSopenharmony_ci } 13858bf80f4bSopenharmony_ci } 13868bf80f4bSopenharmony_ci if (commonDeviceExtensions_.getMemoryRequirements2) { 13878bf80f4bSopenharmony_ci extFunctions_.vkGetImageMemoryRequirements2 = (PFN_vkGetImageMemoryRequirements2)vkGetInstanceProcAddr( 13888bf80f4bSopenharmony_ci plat_.instance, "vkGetImageMemoryRequirements2KHR"); 13898bf80f4bSopenharmony_ci if (!extFunctions_.vkGetImageMemoryRequirements2) { 13908bf80f4bSopenharmony_ci PLUGIN_LOG_E("vkGetInstanceProcAddr failed for vkGetImageMemoryRequirements2"); 13918bf80f4bSopenharmony_ci } 13928bf80f4bSopenharmony_ci } 13938bf80f4bSopenharmony_ci if (commonDeviceExtensions_.samplerYcbcrConversion) { 13948bf80f4bSopenharmony_ci GetYcbcrExtFunctions(plat_.instance, extFunctions_); 13958bf80f4bSopenharmony_ci } 13968bf80f4bSopenharmony_ci#if (RENDER_VULKAN_FSR_ENABLED == 1) 13978bf80f4bSopenharmony_ci if (commonDeviceExtensions_.fragmentShadingRate) { 13988bf80f4bSopenharmony_ci extFunctions_.vkCmdSetFragmentShadingRateKHR = 13998bf80f4bSopenharmony_ci (PFN_vkCmdSetFragmentShadingRateKHR)vkGetInstanceProcAddr(plat_.instance, "vkCmdSetFragmentShadingRateKHR"); 14008bf80f4bSopenharmony_ci } 14018bf80f4bSopenharmony_ci#endif 14028bf80f4bSopenharmony_ci 14038bf80f4bSopenharmony_ci#if (RENDER_VULKAN_RT_ENABLED == 1) 14048bf80f4bSopenharmony_ci extFunctions_.vkGetAccelerationStructureBuildSizesKHR = 14058bf80f4bSopenharmony_ci (PFN_vkGetAccelerationStructureBuildSizesKHR)vkGetInstanceProcAddr( 14068bf80f4bSopenharmony_ci plat_.instance, "vkGetAccelerationStructureBuildSizesKHR"); 14078bf80f4bSopenharmony_ci if (!extFunctions_.vkGetAccelerationStructureBuildSizesKHR) { 14088bf80f4bSopenharmony_ci PLUGIN_LOG_E("vkGetInstanceProcAddr failed for vkGetAccelerationStructureBuildSizesKHR"); 14098bf80f4bSopenharmony_ci } 14108bf80f4bSopenharmony_ci extFunctions_.vkCmdBuildAccelerationStructuresKHR = (PFN_vkCmdBuildAccelerationStructuresKHR)vkGetInstanceProcAddr( 14118bf80f4bSopenharmony_ci plat_.instance, "vkCmdBuildAccelerationStructuresKHR"); 14128bf80f4bSopenharmony_ci if (!extFunctions_.vkCmdBuildAccelerationStructuresKHR) { 14138bf80f4bSopenharmony_ci PLUGIN_LOG_E("vkGetInstanceProcAddr failed for vkCmdBuildAccelerationStructuresKHR"); 14148bf80f4bSopenharmony_ci } 14158bf80f4bSopenharmony_ci extFunctions_.vkCreateAccelerationStructureKHR = 14168bf80f4bSopenharmony_ci (PFN_vkCreateAccelerationStructureKHR)vkGetInstanceProcAddr(plat_.instance, "vkCreateAccelerationStructureKHR"); 14178bf80f4bSopenharmony_ci if (!extFunctions_.vkCreateAccelerationStructureKHR) { 14188bf80f4bSopenharmony_ci PLUGIN_LOG_E("vkGetInstanceProcAddr failed for vkCreateAccelerationStructureKHR"); 14198bf80f4bSopenharmony_ci } 14208bf80f4bSopenharmony_ci extFunctions_.vkDestroyAccelerationStructureKHR = (PFN_vkDestroyAccelerationStructureKHR)vkGetInstanceProcAddr( 14218bf80f4bSopenharmony_ci plat_.instance, "vkDestroyAccelerationStructureKHR"); 14228bf80f4bSopenharmony_ci if (!extFunctions_.vkDestroyAccelerationStructureKHR) { 14238bf80f4bSopenharmony_ci PLUGIN_LOG_E("vkGetInstanceProcAddr failed for vkDestroyAccelerationStructureKHR"); 14248bf80f4bSopenharmony_ci } 14258bf80f4bSopenharmony_ci extFunctions_.vkGetAccelerationStructureDeviceAddressKHR = 14268bf80f4bSopenharmony_ci (PFN_vkGetAccelerationStructureDeviceAddressKHR)vkGetInstanceProcAddr( 14278bf80f4bSopenharmony_ci plat_.instance, "vkGetAccelerationStructureDeviceAddressKHR"); 14288bf80f4bSopenharmony_ci if (!extFunctions_.vkGetAccelerationStructureDeviceAddressKHR) { 14298bf80f4bSopenharmony_ci PLUGIN_LOG_E("vkGetInstanceProcAddr failed for vkGetAccelerationStructureDeviceAddressKHR"); 14308bf80f4bSopenharmony_ci } 14318bf80f4bSopenharmony_ci#endif 14328bf80f4bSopenharmony_ci} 14338bf80f4bSopenharmony_ci 14348bf80f4bSopenharmony_ciLowLevelDeviceVk::LowLevelDeviceVk(DeviceVk& deviceVk) 14358bf80f4bSopenharmony_ci : deviceVk_(deviceVk), gpuResourceMgr_(static_cast<GpuResourceManager&>(deviceVk_.GetGpuResourceManager())) 14368bf80f4bSopenharmony_ci{} 14378bf80f4bSopenharmony_ci 14388bf80f4bSopenharmony_ciDeviceBackendType LowLevelDeviceVk::GetBackendType() const 14398bf80f4bSopenharmony_ci{ 14408bf80f4bSopenharmony_ci return DeviceBackendType::VULKAN; 14418bf80f4bSopenharmony_ci} 14428bf80f4bSopenharmony_ci 14438bf80f4bSopenharmony_ciconst DevicePlatformDataVk& LowLevelDeviceVk::GetPlatformDataVk() const 14448bf80f4bSopenharmony_ci{ 14458bf80f4bSopenharmony_ci return deviceVk_.GetPlatformDataVk(); 14468bf80f4bSopenharmony_ci} 14478bf80f4bSopenharmony_ci 14488bf80f4bSopenharmony_ciGpuBufferPlatformDataVk LowLevelDeviceVk::GetBuffer(RenderHandle handle) const 14498bf80f4bSopenharmony_ci{ 14508bf80f4bSopenharmony_ci if (deviceVk_.GetLockResourceBackendAccess()) { 14518bf80f4bSopenharmony_ci GpuBufferVk* buffer = gpuResourceMgr_.GetBuffer<GpuBufferVk>(handle); 14528bf80f4bSopenharmony_ci if (buffer) { 14538bf80f4bSopenharmony_ci return buffer->GetPlatformData(); 14548bf80f4bSopenharmony_ci } 14558bf80f4bSopenharmony_ci } else { 14568bf80f4bSopenharmony_ci PLUGIN_LOG_E("low level device methods can only be used within specific methods"); 14578bf80f4bSopenharmony_ci } 14588bf80f4bSopenharmony_ci return {}; 14598bf80f4bSopenharmony_ci} 14608bf80f4bSopenharmony_ci 14618bf80f4bSopenharmony_ciGpuImagePlatformDataVk LowLevelDeviceVk::GetImage(RenderHandle handle) const 14628bf80f4bSopenharmony_ci{ 14638bf80f4bSopenharmony_ci if (deviceVk_.GetLockResourceBackendAccess()) { 14648bf80f4bSopenharmony_ci GpuImageVk* image = gpuResourceMgr_.GetImage<GpuImageVk>(handle); 14658bf80f4bSopenharmony_ci if (image) { 14668bf80f4bSopenharmony_ci return image->GetPlatformData(); 14678bf80f4bSopenharmony_ci } 14688bf80f4bSopenharmony_ci } else { 14698bf80f4bSopenharmony_ci PLUGIN_LOG_E("low level device methods can only be used within specific methods"); 14708bf80f4bSopenharmony_ci } 14718bf80f4bSopenharmony_ci return {}; 14728bf80f4bSopenharmony_ci} 14738bf80f4bSopenharmony_ci 14748bf80f4bSopenharmony_ciGpuSamplerPlatformDataVk LowLevelDeviceVk::GetSampler(RenderHandle handle) const 14758bf80f4bSopenharmony_ci{ 14768bf80f4bSopenharmony_ci if (deviceVk_.GetLockResourceBackendAccess()) { 14778bf80f4bSopenharmony_ci GpuSamplerVk* sampler = gpuResourceMgr_.GetSampler<GpuSamplerVk>(handle); 14788bf80f4bSopenharmony_ci if (sampler) { 14798bf80f4bSopenharmony_ci return sampler->GetPlatformData(); 14808bf80f4bSopenharmony_ci } 14818bf80f4bSopenharmony_ci } else { 14828bf80f4bSopenharmony_ci PLUGIN_LOG_E("low level device methods can be only used within specific methods"); 14838bf80f4bSopenharmony_ci } 14848bf80f4bSopenharmony_ci return {}; 14858bf80f4bSopenharmony_ci} 14868bf80f4bSopenharmony_ciRENDER_END_NAMESPACE() 1487