#include "materialsystem/imaterialsystem.h" #include "tier0/platform.h" #include "tier1/interface.h" #include "tier1/utlvector.h" #include "vulkan_state.h" CUtlVector g_vkCommandBuffers; IVkCommandBufferManager *g_pCommandBufferManager; class CVkCommandBuffer: public IVkCommandBuffer { public: virtual void AddCommand( CVkCommand *pCommand ) override; virtual void Reset() override; virtual void Submit( int iFrameIndex ) override; virtual void Render() override; private: void SortDependencies(); void TryBarrier(); VulkanCommandDepenency_t *FindLastObjectDependency( IRenderingObject *pObject ); CUtlSelfReferencingVector m_commands; CUtlVector m_hBuffers = NULL; CUtlVector m_usedDependencies; }; void CVkCommandBuffer::Reset() { VkCommandBufferAllocateInfo commandBufferAllocInfo = {}; int i = 0; m_hBuffers = {}; m_hBuffers.Resize(g_vkCommandPools.GetSize()); for ( auto pool: g_vkCommandPools) { commandBufferAllocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; commandBufferAllocInfo.commandPool = pool; commandBufferAllocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; commandBufferAllocInfo.commandBufferCount = 1; vkAllocateCommandBuffers(g_vkDevice, &commandBufferAllocInfo, &m_hBuffers[i]); i++; } m_commands = {}; } void CVkCommandBuffer::AddCommand( CVkCommand *pCommand ) { m_commands.AppendTail(pCommand); } void CVkCommandBuffer::Submit( int iFrameIndex ) { g_vkCommandBuffers.AppendTail(m_hBuffers[iFrameIndex]); }; struct VulkanBarrierObjects_t { VulkanCommandDepenency_t m_dependency; }; void CVkCommandBuffer::Render() { uint32_t nNumDependencies; int i = 0; for (auto hBuffer: m_hBuffers) { VkCommandBufferBeginInfo stCommandBufferBeginInfo = {}; stCommandBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; vkBeginCommandBuffer(hBuffer, &stCommandBufferBeginInfo); for (auto &pCommand: m_commands) { TryBarrier(); pCommand->Execute(hBuffer, i); }; vkEndCommandBuffer(hBuffer); i++; } } struct VulkanCommandBarrier_t { EDependencyMode m_eOldDependency; EDependencyMode m_eNewDependency; IRenderingObject *m_pObject; }; void CVkCommandBuffer::SortDependencies() { } void CVkCommandBuffer::TryBarrier() { CUtlVector barriers; for (auto &pCommand: m_commands) { for ( auto dependency: pCommand->m_depedencies) { VulkanCommandDepenency_t *pLastDependency = FindLastObjectDependency(dependency.m_pObject); } } }; VulkanCommandDepenency_t *CVkCommandBuffer::FindLastObjectDependency( IRenderingObject *pObject ) { VulkanCommandDepenency_t *pDependency = NULL; for ( auto &dependency: m_usedDependencies ) { if ( dependency.m_pObject == pObject ) pDependency = &dependency; } return pDependency; } class CVkCommandBufferManager: public IVkCommandBufferManager { public: virtual void Init() override; virtual void Shutdown() override; virtual IVkCommandBuffer *CreateCommandBuffer() override; virtual CVkCommand *CreateCommand( const char *szName ) override; }; EXPOSE_INTERFACE(CVkCommandBufferManager, IVkCommandBufferManager, VULKAN_COMMAND_BUFFER_MANAGER_INTERFACE_NAME); void CVkCommandBufferManager::Init() { } void CVkCommandBufferManager::Shutdown() { } IVkCommandBuffer *CVkCommandBufferManager::CreateCommandBuffer() { return new CVkCommandBuffer; } struct VulkanCommandRegistry_t { const char *m_szName; fnCreateVulkanCommand_t m_pfnCreate; struct VulkanCommandRegistry_t *m_pNext; } *s_pVulkanCommands = NULL; CVkCommand *CVkCommandBufferManager::CreateCommand( const char *szName ) { VulkanCommandRegistry_t *pCommand; for ( pCommand = s_pVulkanCommands; pCommand; pCommand = pCommand->m_pNext ) { if (!V_strcmp(pCommand->m_szName, szName)) return pCommand->m_pfnCreate(); } Plat_FatalErrorFunc("Command %s not found\n", szName); return NULL; } CVkCommandRegistry::CVkCommandRegistry( const char *szName, fnCreateVulkanCommand_t pfnCreate ) { VulkanCommandRegistry_t *pCommand = new VulkanCommandRegistry_t; pCommand->m_szName = szName; pCommand->m_pfnCreate = pfnCreate; pCommand->m_pNext = s_pVulkanCommands; s_pVulkanCommands = pCommand; } void CVkCommand::AddDependency( IRenderingObject *pObject, EDependencyMode eDependencyMode ) { m_depedencies.AppendTail({ pObject, eDependencyMode }); }