180 lines
4.3 KiB
C++
180 lines
4.3 KiB
C++
#include "materialsystem/imaterialsystem.h"
|
|
#include "tier0/platform.h"
|
|
#include "tier1/interface.h"
|
|
#include "tier1/utlvector.h"
|
|
#include "vulkan_state.h"
|
|
|
|
CUtlVector<VkCommandBuffer> 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<CVkCommand*> m_commands;
|
|
CUtlVector<VkCommandBuffer> m_hBuffers = NULL;
|
|
CUtlVector<VulkanCommandDepenency_t> 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<VulkanCommandBarrier_t> 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 });
|
|
}
|