1 /* 2 * Copyright (c) 2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef VULKAN_DEVICE_VK_H 17 #define VULKAN_DEVICE_VK_H 18 19 #include <cstdint> 20 #include <vulkan/vulkan_core.h> 21 22 #include <base/containers/unordered_map.h> 23 #include <base/containers/vector.h> 24 #include <base/util/formats.h> 25 #include <render/device/intf_device.h> 26 #include <render/device/pipeline_state_desc.h> 27 #include <render/namespace.h> 28 #include <render/vulkan/intf_device_vk.h> 29 30 #include "device/device.h" 31 #include "platform_vk.h" 32 #include "vulkan/swapchain_vk.h" 33 34 RENDER_BEGIN_NAMESPACE() 35 class ComputePipelineStateObject; 36 class GraphicsPipelineStateObject; 37 class GpuBuffer; 38 class GpuComputeProgram; 39 class GpuImage; 40 class GpuResourceManager; 41 class GpuSemaphore; 42 class GpuSampler; 43 class GpuShaderProgram; 44 class LowLevelDeviceVk; 45 class NodeContextDescriptorSetManager; 46 class NodeContextPoolManager; 47 class PlatformGpuMemoryAllocator; 48 class RenderFrameSync; 49 class RenderBackend; 50 class RenderContext; 51 class ShaderModule; 52 class Swapchain; 53 54 struct GpuImagePlatformData; 55 struct SwapchainCreateInfo; 56 struct BackendSpecificImageDesc; 57 struct GpuAccelerationStructureDesc; 58 struct GpuBufferDesc; 59 struct GpuComputeProgramCreateData; 60 struct GpuImageDesc; 61 struct GpuSamplerDesc; 62 struct GpuShaderProgramCreateData; 63 struct PipelineLayout; 64 struct RenderHandle; 65 struct ShaderModuleCreateInfo; 66 struct QueueProperties; 67 68 struct LowLevelQueueInfo { 69 VkQueueFlags queueFlags { 0 }; 70 uint32_t queueFamilyIndex { ~0u }; 71 uint32_t queueCount { 0 }; 72 float priority { 1.0f }; 73 }; 74 75 struct LowLevelGpuQueueVk { 76 VkQueue queue { VK_NULL_HANDLE }; 77 78 LowLevelQueueInfo queueInfo; 79 }; 80 81 struct DevicePlatformInternalDataVk { 82 BASE_NS::vector<BASE_NS::Format> supportedDepthFormats; 83 }; 84 85 struct DebugFunctionUtilitiesVk { 86 PFN_vkSetDebugUtilsObjectNameEXT vkSetDebugUtilsObjectNameEXT { nullptr }; 87 PFN_vkCmdBeginDebugUtilsLabelEXT vkCmdBeginDebugUtilsLabelEXT { nullptr }; 88 PFN_vkCmdEndDebugUtilsLabelEXT vkCmdEndDebugUtilsLabelEXT { nullptr }; 89 90 VkDebugUtilsMessengerEXT debugMessenger { VK_NULL_HANDLE }; 91 VkDebugReportCallbackEXT debugCallback { VK_NULL_HANDLE }; 92 }; 93 94 class DeviceVk final : public Device { 95 public: 96 DeviceVk(RenderContext& renderContext, DeviceCreateInfo const& createInfo); 97 ~DeviceVk() override; 98 99 // From IDevice 100 DeviceBackendType GetBackendType() const override; 101 const DevicePlatformData& GetPlatformData() const override; 102 FormatProperties GetFormatProperties(const BASE_NS::Format format) const override; 103 AccelerationStructureBuildSizes GetAccelerationStructureBuildSizes( 104 const AccelerationStructureBuildGeometryInfo& geometry, 105 BASE_NS::array_view<const AccelerationStructureGeometryTrianglesInfo> triangles, 106 BASE_NS::array_view<const AccelerationStructureGeometryAabbsInfo> aabbs, 107 BASE_NS::array_view<const AccelerationStructureGeometryInstancesInfo> instances) const override; 108 ILowLevelDevice& GetLowLevelDevice() const override; 109 void WaitForIdle() override; 110 111 const DevicePlatformInternalDataVk& GetPlatformInternalDataVk() const; 112 const DevicePlatformDataVk& GetPlatformDataVk() const; 113 114 PlatformGpuMemoryAllocator* GetPlatformGpuMemoryAllocator() override; 115 116 BASE_NS::unique_ptr<Swapchain> CreateDeviceSwapchain(const SwapchainCreateInfo& swapchainCreateInfo) override; 117 void DestroyDeviceSwapchain() override; 118 119 void Activate() override; 120 void Deactivate() override; 121 122 bool AllowThreadedProcessing() const override; 123 124 GpuQueue GetValidGpuQueue(const GpuQueue& gpuQueue) const override; 125 uint32_t GetGpuQueueCount() const override; 126 127 void InitializePipelineCache(BASE_NS::array_view<const uint8_t> initialData) override; 128 BASE_NS::vector<uint8_t> GetPipelineCache() const override; 129 130 LowLevelGpuQueueVk GetGpuQueue(const GpuQueue& gpuQueue) const; 131 LowLevelGpuQueueVk GetPresentationGpuQueue() const; 132 BASE_NS::vector<LowLevelGpuQueueVk> GetLowLevelGpuQueues() const; 133 134 BASE_NS::unique_ptr<GpuBuffer> CreateGpuBuffer(const GpuBufferDesc& desc) override; 135 BASE_NS::unique_ptr<GpuBuffer> CreateGpuBuffer(const GpuAccelerationStructureDesc& desc) override; 136 137 BASE_NS::unique_ptr<GpuImage> CreateGpuImage(const GpuImageDesc& desc) override; 138 BASE_NS::unique_ptr<GpuImage> CreateGpuImageView( 139 const GpuImageDesc& desc, const GpuImagePlatformData& platformData) override; 140 BASE_NS::unique_ptr<GpuImage> CreateGpuImageView( 141 const GpuImageDesc& desc, const BackendSpecificImageDesc& platformData) override; 142 BASE_NS::unique_ptr<GpuImage> CreateGpuImageView( 143 const GpuImageDesc& desc, const GpuImagePlatformData& platformData, const uintptr_t hwBuffer); 144 BASE_NS::vector<BASE_NS::unique_ptr<GpuImage>> CreateGpuImageViews(const Swapchain& platformData) override; 145 146 BASE_NS::unique_ptr<GpuSampler> CreateGpuSampler(const GpuSamplerDesc& desc) override; 147 148 BASE_NS::unique_ptr<RenderFrameSync> CreateRenderFrameSync() override; 149 150 BASE_NS::unique_ptr<RenderBackend> CreateRenderBackend( 151 GpuResourceManager& gpuResourceMgr, const CORE_NS::IParallelTaskQueue::Ptr& queue) override; 152 153 BASE_NS::unique_ptr<ShaderModule> CreateShaderModule(const ShaderModuleCreateInfo& data) override; 154 BASE_NS::unique_ptr<ShaderModule> CreateComputeShaderModule(const ShaderModuleCreateInfo& data) override; 155 BASE_NS::unique_ptr<GpuShaderProgram> CreateGpuShaderProgram(const GpuShaderProgramCreateData& data) override; 156 BASE_NS::unique_ptr<GpuComputeProgram> CreateGpuComputeProgram(const GpuComputeProgramCreateData& data) override; 157 158 BASE_NS::unique_ptr<NodeContextDescriptorSetManager> CreateNodeContextDescriptorSetManager() override; 159 BASE_NS::unique_ptr<NodeContextPoolManager> CreateNodeContextPoolManager( 160 class GpuResourceManager& gpuResourceMgr, const GpuQueue& gpuQueue) override; 161 162 BASE_NS::unique_ptr<GraphicsPipelineStateObject> CreateGraphicsPipelineStateObject( 163 const GpuShaderProgram& gpuProgram, const GraphicsState& graphicsState, const PipelineLayout& pipelineLayout, 164 const VertexInputDeclarationView& vertexInputDeclaration, 165 const ShaderSpecializationConstantDataView& specializationConstants, 166 const BASE_NS::array_view<const DynamicStateEnum> dynamicStates, const RenderPassDesc& renderPassDesc, 167 const BASE_NS::array_view<const RenderPassSubpassDesc>& renderPassSubpassDescs, const uint32_t subpassIndex, 168 const LowLevelRenderPassData* renderPassData, const LowLevelPipelineLayoutData* pipelineLayoutData) override; 169 170 BASE_NS::unique_ptr<ComputePipelineStateObject> CreateComputePipelineStateObject( 171 const GpuComputeProgram& gpuProgram, const PipelineLayout& pipelineLayout, 172 const ShaderSpecializationConstantDataView& specializationConstants, 173 const LowLevelPipelineLayoutData* pipelineLayoutData) override; 174 175 BASE_NS::unique_ptr<GpuSemaphore> CreateGpuSemaphore() override; 176 BASE_NS::unique_ptr<GpuSemaphore> CreateGpuSemaphoreView(const uint64_t handle) override; 177 178 struct FeatureConfigurations { 179 float minSampleShading { 0.25f }; 180 }; 181 const FeatureConfigurations& GetFeatureConfigurations() const; 182 183 struct CommonDeviceExtensions { 184 bool swapchain { false }; 185 186 // external_memory and external_memory_capabilities 187 bool externalMemory { false }; 188 bool getMemoryRequirements2 { false }; 189 bool samplerYcbcrConversion { false }; 190 bool queueFamilyForeign { false }; 191 192 bool renderPass2 { false }; 193 bool fragmentShadingRate { false }; 194 bool multiView { false }; 195 bool descriptorIndexing { false }; 196 }; 197 const CommonDeviceExtensions& GetCommonDeviceExtensions() const; 198 const PlatformDeviceExtensions& GetPlatformDeviceExtensions() const; 199 bool HasDeviceExtension(const BASE_NS::string_view extensionName) const; 200 201 const DebugFunctionUtilitiesVk& GetDebugFunctionUtilities() const; 202 void CreateDebugFunctions(); 203 204 struct ExtFunctions { 205 // VK_KHR_sampler_ycbcr_conversion or Vulkan 1.1 206 PFN_vkCreateSamplerYcbcrConversion vkCreateSamplerYcbcrConversion { nullptr }; 207 PFN_vkDestroySamplerYcbcrConversion vkDestroySamplerYcbcrConversion { nullptr }; 208 209 // VK_KHR_get_memory_requirements2 or Vulkan 1.1 210 PFN_vkGetImageMemoryRequirements2 vkGetImageMemoryRequirements2 { nullptr }; 211 // VK_KHR_get_physical_device_properties2 or Vulkan 1.1 212 PFN_vkGetPhysicalDeviceFeatures2 vkGetPhysicalDeviceFeatures2 { nullptr }; 213 PFN_vkGetPhysicalDeviceProperties2 vkGetPhysicalDeviceProperties2 { nullptr }; 214 215 // VK_KHR_create_renderpass2 or Vulkan 1.2 216 PFN_vkCreateRenderPass2KHR vkCreateRenderPass2KHR { nullptr }; 217 218 // VK_KHR_swapchain 219 PFN_vkAcquireNextImageKHR vkAcquireNextImageKHR { nullptr }; 220 221 #if (RENDER_VULKAN_FSR_ENABLED == 1) 222 // VK_KHR_fragment_shading_rate 223 PFN_vkCmdSetFragmentShadingRateKHR vkCmdSetFragmentShadingRateKHR { nullptr }; 224 #endif 225 226 #if (RENDER_VULKAN_RT_ENABLED == 1) 227 // VK_KHR_acceleration_structure 228 PFN_vkGetAccelerationStructureBuildSizesKHR vkGetAccelerationStructureBuildSizesKHR { nullptr }; 229 PFN_vkCmdBuildAccelerationStructuresKHR vkCmdBuildAccelerationStructuresKHR { nullptr }; 230 PFN_vkCreateAccelerationStructureKHR vkCreateAccelerationStructureKHR { nullptr }; 231 PFN_vkDestroyAccelerationStructureKHR vkDestroyAccelerationStructureKHR { nullptr }; 232 PFN_vkGetAccelerationStructureDeviceAddressKHR vkGetAccelerationStructureDeviceAddressKHR { nullptr }; 233 #endif 234 }; 235 const ExtFunctions& GetExtFunctions() const; 236 void CreateExtFunctions(); 237 238 const PlatformExtFunctions& GetPlatformExtFunctions() const; 239 void CreatePlatformExtFunctions(); 240 241 private: 242 BASE_NS::vector<QueueProperties> CheckExternalConfig(const BackendExtraVk* backendConfiguration); 243 void CreateInstance(); 244 void CreatePhysicalDevice(); 245 void CreateDevice(const BackendExtraVk* backendExtra, const BASE_NS::vector<LowLevelQueueInfo>& availableQueues); 246 void SortAvailableQueues(const BASE_NS::vector<LowLevelQueueInfo>& availableQueues); 247 248 BASE_NS::unique_ptr<PlatformGpuMemoryAllocator> platformGpuMemoryAllocator_; 249 250 DevicePlatformDataVk plat_; 251 bool ownInstanceAndDevice_ { true }; 252 DevicePlatformInternalDataVk platInternal_; 253 254 FeatureConfigurations featureConfigurations_; 255 256 struct LowLevelGpuQueues { 257 BASE_NS::vector<LowLevelGpuQueueVk> graphicsQueues; 258 BASE_NS::vector<LowLevelGpuQueueVk> computeQueues; 259 BASE_NS::vector<LowLevelGpuQueueVk> transferQueues; 260 261 LowLevelGpuQueueVk defaultQueue; 262 }; 263 LowLevelGpuQueues lowLevelGpuQueues_; 264 265 uint32_t gpuQueueCount_ { 0 }; 266 267 BASE_NS::unordered_map<BASE_NS::string, uint32_t> extensions_; 268 CommonDeviceExtensions commonDeviceExtensions_; 269 PlatformDeviceExtensions platformDeviceExtensions_; 270 BASE_NS::unique_ptr<LowLevelDeviceVk> lowLevelDevice_; 271 272 BASE_NS::vector<FormatProperties> formatProperties_; 273 274 DebugFunctionUtilitiesVk debugFunctionUtilities_; 275 ExtFunctions extFunctions_; 276 PlatformExtFunctions platformExtFunctions_; 277 }; 278 279 BASE_NS::unique_ptr<Device> CreateDeviceVk(RenderContext& renderContext, DeviceCreateInfo const& createInfo); 280 281 // Wrapper for low level device access 282 class LowLevelDeviceVk final : public ILowLevelDeviceVk { 283 public: 284 explicit LowLevelDeviceVk(DeviceVk& deviceVk); 285 ~LowLevelDeviceVk() = default; 286 287 DeviceBackendType GetBackendType() const override; 288 const DevicePlatformDataVk& GetPlatformDataVk() const override; 289 290 GpuBufferPlatformDataVk GetBuffer(RenderHandle handle) const override; 291 GpuImagePlatformDataVk GetImage(RenderHandle handle) const override; 292 GpuSamplerPlatformDataVk GetSampler(RenderHandle handle) const override; 293 294 private: 295 DeviceVk& deviceVk_; 296 GpuResourceManager& gpuResourceMgr_; 297 }; 298 RENDER_END_NAMESPACE() 299 300 #endif // VULKAN_DEVICE_VK_H 301