#ifndef VULKAN_STATE_H #define VULKAN_STATE_H #include "volk.h" #include "vk_mem_alloc.h" #include "tier0/platform.h" #include "tier1/utlvector.h" #include "tier2/iappsystem.h" #include "materialsystem/imaterialsystem.h" #include "vulkan/vulkan_core.h" #define REQUIRED_EXTENSION(ext) bool bIsSupported_##ext; #define OPTIONAL_EXTENSION(ext) bool bIsSupported_##ext; extern struct SupportedVulkanExtensions_t { #include "device_extensions.h" } g_vkAvailableExtensions; #undef REQUIRED_EXTENSION #undef OPTIONAL_EXTENSION extern CUtlVector g_vkSwapchainImages; extern CUtlVector g_vkCommandPools; extern CUtlVector g_vkCommandBuffers; extern VkInstance g_vkInstance; extern VkPhysicalDevice g_vkPhysicalDevice; extern VkDevice g_vkDevice; enum EVulkanCommandType { COMMAND_TYPE_GENERAL, COMMAND_TYPE_BEGIN, COMMAND_TYPE_DRAW, COMMAND_TYPE_END, }; enum EVulkanCommandParameterType { VULKAN_PARAMETER_TYPE_UINT32, VULKAN_PARAMETER_TYPE_FLOAT, VULKAN_PARAMETER_TYPE_BUFFER, VULKAN_PARAMETER_TYPE_IMAGE, }; enum EDependencyMode { DEPENDENCY_MODE_SHADER_IMAGE_READ, DEPENDENCY_MODE_SHADER_BUFFER_READ, DEPENDENCY_MODE_SHADER_IMAGE_WRITE, DEPENDENCY_MODE_SHADER_BUFFER_WRITE, DEPENDENCY_MODE_SHADER_ACCELERATION_STRUCTURE, DEPENDENCY_MODE_DRAWCALL_VERTEX_BUFFER, DEPENDENCY_MODE_DRAWCALL_INDEX_BUFFER, DEPENDENCY_MODE_DRAWCALL_OUTPUT_IMAGE, DEPENDENCY_MODE_DRAWCALL_INPUT_IMAGE, DEPENDENCY_MODE_DRAWCALL_MIXED_IMAGE, DEPENDENCY_MODE_IMAGE_SOURCE, DEPENDENCY_MODE_IMAGE_DESTINATION, DEPENDENCY_MODE_COLOR_CLEAR_SOURCE, DEPENDENCY_MODE_COLOR_CLEAR_DESTINATION, DEPENDENCY_MODE_ALL_COMMANDS, DEPENDENCY_MODE_IMAGE_PRESENT, DEPENDENCY_MODE_FROM_PREVIOUS, DEPENDENCY_MODE_COUNT, }; struct VulkanCommandDepenency_t { IRenderingObject *m_pObject; EDependencyMode m_eDependencyMode; }; struct VulkanCommandSwapchainDepenency_t { IRenderingObject **m_ppObjects; EDependencyMode m_eDependencyMode; }; struct VulkanCommandParameter_t { const char *m_szName; const EVulkanCommandParameterType m_eParameterType; union { uint32_t uint32_Data; IImage *pImageData; }; }; abstract_class CVkCommand { public: virtual void Execute( VkCommandBuffer hCommandBuffer, int iCurrentFrame ) = 0; //virtual const char *GetName(); CUtlVector m_dependencies = {}; CUtlVector m_swapchainDependencies = {}; EVulkanCommandType m_eType; void AddDependency( IRenderingObject *pObject, EDependencyMode eDependencyMode ); void AddSwapchainDependency( IRenderingObject **ppObjects, EDependencyMode eDependencyMode ); }; abstract_class IVkCommandBuffer { public: virtual void AddCommand( CVkCommand *pCommand ) = 0; virtual void Reset() = 0; virtual void Submit( int iFrameIndex ) = 0; virtual void Render() = 0; }; typedef CVkCommand *(*fnCreateVulkanCommand_t)(); abstract_class IVkCommandBufferManager: public IAppSystem { public: virtual IVkCommandBuffer *CreateCommandBuffer() = 0; virtual CVkCommand *CreateCommand( const char *szName ) = 0; }; #define VULKAN_COMMAND_BUFFER_MANAGER_INTERFACE_NAME "VulkanCommandBufferManager" extern IVkCommandBufferManager *g_pCommandBufferManager; class CVkCommandRegistry { public: CVkCommandRegistry( const char *szName, fnCreateVulkanCommand_t pfnCreate ); }; #define BEGIN_VULKAN_COMMAND( name ) \ class CVk##name##Command : public CVkCommand \ { \ public: \ virtual void Execute( VkCommandBuffer hCommandBuffer, int iCurrentFrame ) override; \ #define END_VULKAN_COMMAND( name ) \ }; \ #define DECLARE_VULKAN_COMMAND(name) \ CVkCommand *_VulkanCommandCreate_##name() { return new CVk##name##Command; } \ CVkCommandRegistry _VulkanCommandRegistry_##name( #name, _VulkanCommandCreate_##name ); \ void CVk##name##Command::Execute( VkCommandBuffer hCommandBuffer, int iCurrentFrame ) \ #undef __cplusplus #include "vulkan/vk_enum_string_helper.h" #define __cplusplus 202400L #define VULKAN_RESULT_PRINT(r, func) \ if (r != VK_SUCCESS) \ Plat_FatalErrorFunc(#func " failed: %s\n", string_VkResult(r)) class CVkImage: public IImage { public: CVkImage(); CVkImage( uint32_t nWidth, uint32_t nHeight, EImageFormat eFormat, EMultisampleType eMultisampleType ); ~CVkImage(); virtual void SetDebugName( const char *szName ) override; virtual uint32_t GetImageWidth() override; virtual uint32_t GetImageHeight() override; virtual EImageFormat GetImageFormat() override; virtual EMultisampleType GetMultisampleType() override; void CreateImage( uint32_t nWidth, uint32_t nHeight, EImageFormat eFormat, EMultisampleType eMultisampleType ); void CreateImageView(); static VkImageViewType GetImageViewType( enum EImageType eImageType ); static VkFormat GetImageFormat( enum EImageFormat eImageFormat ); uint32_t m_nWidth; uint32_t m_nHeight; EImageFormat m_eFormat; EMultisampleType m_eMultisampleType; EImageType m_eImageType; VkImage m_image; VkImageView m_imageView; VmaAllocation m_allocation; VkImageSubresourceRange m_range; VkImageLayout m_eImageLayout = VK_IMAGE_LAYOUT_UNDEFINED; EDependencyMode m_eLastUsage; }; class CVkBuffer: public IBuffer { public: CVkBuffer( uint32_t nSize, VkBufferUsageFlags2 eUsage, uint32_t nAlignment ); ~CVkBuffer(); virtual void SetDebugName( const char *szName ) override; virtual void Lock() override; virtual void Unlock() override; virtual void *Map() override; virtual void Unmap() override; virtual uint32_t GetSize() override; VmaAllocation allocation; VkBuffer buffer; VkDeviceAddress address; uint32_t nSize; }; class CVkPipelineLibrary { public: virtual void Build() = 0; VkPipeline m_hPipeline = NULL; }; #define BEGIN_DEFINE_PIPELINE_LIBRARY(name) \ class CVk##name##PipelineLibrary: public CVkPipelineLibrary \ { \ public: \ virtual void Build() override; \ #define END_DEFINE_PIPELINE_LIBRARY() \ }; #define BEGIN_BUILD_PIPELINE_LIBRARY(name) \ void CVk##name##PipelineLibrary::Build() \ { \ VkGraphicsPipelineCreateInfo pipeline = {}; \ pipeline.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; \ #define END_BUILD_PIPELINE_LIBRARY() \ vkCreateGraphicsPipelines(g_vkDevice, NULL, 1, &pipeline, NULL, &m_hPipeline); \ } class CVkShader : IShader { public: void AddShaderLibrary( CVkPipelineLibrary *pLibrary ); void Build(); VkPipeline m_hPipeline = NULL; VkPipelineLayout m_hPipelineLayout; CUtlVector m_libraries; }; enum EVkFrameObjectType_t { FRAME_OBJECT_TYPE_SINGLE, FRAME_OBJECT_TYPE_SWAPPED, }; struct VkFrameObject_t { EVkFrameObjectType_t m_eObjectType; union { IRenderingObject *m_pSingle; IRenderingObject **m_ppSwapped; }; }; IRenderingObject *VulkanGetObject( VkFrameObject_t stObject, int iIndex ); VkAccessFlags2 VulkanGetAccessFlags( EDependencyMode eMode ); VkPipelineStageFlags2 VulkanGetStageFlags( EDependencyMode eMode ); VkImageLayout VulkanGetImageLayout( EDependencyMode eMode ); #endif