#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: CUtlSelfReferencingVector g_commands; CUtlVector m_hBuffers = NULL; }; void CVkCommandBuffer::Reset() { VkCommandBufferAllocateInfo commandBufferAllocInfo = {}; int i = 0; 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++; } g_commands = {}; } void CVkCommandBuffer::AddCommand( CVkCommand *pCommand ) { g_commands.AppendTail(pCommand); } void CVkCommandBuffer::Submit( int iFrameIndex ) { g_vkCommandBuffers.AppendTail(m_hBuffers[iFrameIndex]); }; void CVkCommandBuffer::Render() { uint32_t nNumDependencies; nNumDependencies = 0; for (auto pCommand: g_commands) { nNumDependencies += pCommand->m_depedencies.GetSize(); } // issue vkCmdPipelineBarrier if there are any if (nNumDependencies) { } for (auto hBuffer: m_hBuffers) { for (auto &pCommand: g_commands) { pCommand->Execute(hBuffer); }; } } void CVkCommand::SetUIntParam( const char *szName, uint32_t uintParam ) { for ( auto p: m_parameters ) { if (!V_strcmp(p.m_szName, szName)) p.uint32_Data = uintParam; } } uint32_t CVkCommand::GetUIntParam( const char *szName ) { for ( auto p: m_parameters ) { if (!V_strcmp(p.m_szName, szName)) return p.uint32_Data; } return 0; } void CVkCommand::SetImageParam( const char *szName, IImage *pImageParam ) { for ( auto p: m_parameters ) { if (!V_strcmp(p.m_szName, szName)) p.pImageData = pImageParam; } } IImage *CVkCommand::GetImageParam( const char *szName ) { for ( auto p: m_parameters ) { if (!V_strcmp(p.m_szName, szName)) return p.pImageData; } return 0; } 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; }