made rendering work

This commit is contained in:
2026-02-05 11:10:40 +02:00
parent faae0bdcc7
commit 4bfbcaa4a6
22 changed files with 737 additions and 483 deletions

View File

@@ -1,5 +1,6 @@
#include "commands.h"
#include "materialsystem/imaterialsystem.h"
#include "shadercompiler/icompiler.h"
#include "tier0/lib.h"
#include "tier0/platform.h"
#include "tier1/interface.h"
@@ -8,13 +9,13 @@
#define VK_NO_PROTOTYPES
#include "vulkan/vulkan_core.h"
#include "vulkan_state.h"
#include "igamewindow.h"
#include "materialsystem/igamewindow.h"
#include "libraries.h"
#define REQUIRED_EXTENSION(ext) ext##_EXTENSION_NAME,
#define OPTIONAL_EXTENSION(ext) ext##_EXTENSION_NAME,
const char *g_vkDeviceExtensions[] = {
static const char *s_vkDeviceExtensions[] = {
#include "device_extensions.h"
};
#undef REQUIRED_EXTENSION
@@ -26,23 +27,27 @@ SupportedVulkanExtensions_t g_vkAvailableExtensions;
uint32_t g_iDrawFamily;
uint32_t g_iPresentFamily;
VkQueue g_vkDrawQueue;
VkQueue g_vkPresentQueue;
VkQueue s_vkDrawQueue;
VkQueue s_vkPresentQueue;
VkInstance g_vkInstance;
VmaAllocator g_vkAllocator;
VkPhysicalDevice g_vkPhysicalDevice;
VkDevice g_vkDevice;
VkSwapchainKHR g_vkSwapchain;
VkInstance s_vkInstance;
VmaAllocator s_vkAllocator;
VkPhysicalDevice s_vkPhysicalDevice;
VkDevice s_vkDevice;
VkSwapchainKHR s_vkSwapchain;
CUtlVector<VkFence> g_vkFences = {};
CUtlVector<VkSemaphore> g_vkGraphicsSemaphores = {};
CUtlVector<VkSemaphore> g_vkPresentSemaphores = {};
CUtlVector<VkCommandPool> g_vkCommandPools = {};
CUtlVector<IImage*> g_vkSwapchainImages = {};
VkFormat g_vkWindowImageFormat;
struct VulkanWindow_t
{
IGameWindow *m_pWindow;
VkSurfaceKHR m_surface;
VkSwapchainKHR m_swapchain;
VkFormat m_eFormat;
VkFence m_fences[FRAMES_IN_FLIGHT];
VkSemaphore m_imageAvailable[FRAMES_IN_FLIGHT];
VkSemaphore m_renderFinished[FRAMES_IN_FLIGHT];
CUtlVector<IImage*> m_images;
uint32_t m_uCurrentFrame;
};
CVkImage::CVkImage()
@@ -57,7 +62,7 @@ CVkImage::CVkImage( uint32_t nWidth, uint32_t nHeight, uint32_t nDepth, EImageFo
m_eMultisampleType = eMultisampleType;
m_eImageType = eImageType;
m_eFormat = eFormat;
m_ePreferredLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
m_ePreferredLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
CreateImage(nWidth, nHeight, eFormat, eMultisampleType, eUsage);
CreateImageView();
}
@@ -103,13 +108,11 @@ VkFormat CVkImage::GetImageFormat( enum EImageFormat eImageFormat )
case IMAGE_FORMAT_RGBA8_SINT:
return VK_FORMAT_R8G8B8A8_SINT;
case IMAGE_FORMAT_RGBA16_SFLOAT:
return VK_FORMAT_R16G16B16A16_SFLOAT;
return VK_FORMAT_R16G16B16A16_SFLOAT;
case IMAGE_FORMAT_RGBA32_SFLOAT:
return VK_FORMAT_R32G32B32A32_SFLOAT;
case IMAGE_FORMAT_D32_SFLOAT:
return VK_FORMAT_D32_SFLOAT;
case IMAGE_FORMAT_WINDOW:
return g_vkWindowImageFormat;
}
}
@@ -130,9 +133,9 @@ void CVkImage::CreateImage( uint32_t nWidth, uint32_t nHeight, EImageFormat eFor
stCreateInfo.format = GetImageFormat(eFormat);
stCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
stAlloc.usage = VMA_MEMORY_USAGE_AUTO;
stAlloc.usage = VMA_MEMORY_USAGE_AUTO;
vmaCreateImage(g_vkAllocator, &stCreateInfo, &stAlloc, &m_image, &m_allocation, NULL);
vmaCreateImage(s_vkAllocator, &stCreateInfo, &stAlloc, &m_image, &m_allocation, NULL);
}
void CVkImage::CreateImageView()
@@ -151,7 +154,7 @@ void CVkImage::CreateImageView()
stImageViewCreateInfo.subresourceRange.layerCount = 1;
stImageViewCreateInfo.subresourceRange.levelCount = 1;
m_range = stImageViewCreateInfo.subresourceRange;
vkCreateImageView(g_vkDevice, &stImageViewCreateInfo, NULL, &m_imageView);
vkCreateImageView(s_vkDevice, &stImageViewCreateInfo, NULL, &m_imageView);
}
void CVkImage::SetDebugName( const char *szName )
{
@@ -186,7 +189,7 @@ CVkBuffer::CVkBuffer( uint32_t nSize, VkBufferUsageFlags2 eUsage, uint32_t nAlig
VkBufferCreateInfo stBufferInfo = {};
VmaAllocationCreateInfo stAllocInfo = {};
VkBufferDeviceAddressInfo stAddress = {};
stUsage.sType = VK_STRUCTURE_TYPE_BUFFER_USAGE_FLAGS_2_CREATE_INFO;
stUsage.usage = eUsage | VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT;
@@ -197,12 +200,12 @@ CVkBuffer::CVkBuffer( uint32_t nSize, VkBufferUsageFlags2 eUsage, uint32_t nAlig
stAllocInfo.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE;
stAllocInfo.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT;
vmaCreateBuffer(g_vkAllocator, &stBufferInfo, &stAllocInfo, &m_buffer, &m_allocation, NULL);
vmaCreateBuffer(s_vkAllocator, &stBufferInfo, &stAllocInfo, &m_buffer, &m_allocation, NULL);
stAddress.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO;
stAddress.buffer = m_buffer;
m_address = vkGetBufferDeviceAddress(g_vkDevice, &stAddress);
m_address = vkGetBufferDeviceAddress(s_vkDevice, &stAddress);
m_nSize = nSize;
}
@@ -230,13 +233,13 @@ void *CVkBuffer::Map()
void *pData;
pData = NULL;
vmaMapMemory(g_vkAllocator, m_allocation, &pData);
vmaMapMemory(s_vkAllocator, m_allocation, &pData);
return pData;
}
void CVkBuffer::Unmap()
{
vmaUnmapMemory(g_vkAllocator, m_allocation);
vmaUnmapMemory(s_vkAllocator, m_allocation);
}
uint32_t CVkBuffer::GetSize()
@@ -249,20 +252,20 @@ public:
virtual void Init() override;
virtual void Frame( float fDeltaTime ) override;
virtual void Shutdown() override;
virtual IVertexBuffer *CreateVertexBuffer( uint32_t nSize ) override;
virtual IIndexBuffer *CreateIndexBuffer( uint32_t nSize ) override;
virtual IBuffer *CreateConstantBuffer( uint32_t nSize ) override;
virtual IBuffer *CreateStorageBuffer( uint32_t nSize ) override;
virtual void DestroyBuffer( IBuffer *pBuffer ) override;
virtual IImage *CreateRenderTarget( uint32_t x, uint32_t y, EImageFormat eFormat, EMultisampleType eMultisampleType ) override;
virtual IImage *CreateStorageImage( uint32_t x, uint32_t y, EImageFormat eFormat, EMultisampleType eMultisampleType ) override;
virtual void DestroyImage( IImage *pImage ) override;
IBuffer *CreateBuffer( uint32_t nSize, VkBufferUsageFlags2 eUsage );
IBuffer *CreateBufferAligned( uint32_t nSize, uint32_t nAlignment, VkBufferUsageFlags2 eUsage );
virtual IShader *CreateShader( const char *szName ) override;
virtual void DestroyShader( IShader *pShader ) override;
@@ -272,7 +275,7 @@ public:
virtual IRenderCommandList *CreateCommandList() override;
virtual void DestroyCommandList( IRenderCommandList *pCommandList ) override;
virtual void SubmitCommandList(IRenderCommandList *pList) override;
virtual void SetMainWindowManager( IGameWindowManager *pWindowManager ) override;
virtual void RenderGameWindow( IGameWindow *pWindow ) override;
@@ -284,16 +287,19 @@ private:
VkCommandBuffer GetCommandBuffer();
void CreateSwapchain( IGameWindow *pWindow );
void DestroySwapchain( IGameWindow *pWindow );
VulkanWindow_t CreateSwapchain( IGameWindow *pWindow );
void DestroySwapchain( uint32_t uIndex );
IGameWindowManager *m_pWindowManager;
IVkCommandBufferManager *m_pCommandBufferManager;
CUtlVector<VulkanWindow_t> m_renderWindows;
};
EXPOSE_INTERFACE(CVkRenderContext, IRenderContext, RENDER_CONTEXT_INTERFACE_VERSION);
//-----------------------------------------------------------------------------
// Creates vertex buffer. Wrapper over CreateBuffer
// Creates vertex buffer. Wrapper over CreateBuffer
//-----------------------------------------------------------------------------
IVertexBuffer *CVkRenderContext::CreateVertexBuffer( uint32_t nSize )
{
@@ -301,14 +307,14 @@ IVertexBuffer *CVkRenderContext::CreateVertexBuffer( uint32_t nSize )
}
//-----------------------------------------------------------------------------
// Creates index buffer. Wrapper over CreateBuffer
// Creates index buffer. Wrapper over CreateBuffer
//-----------------------------------------------------------------------------
IIndexBuffer *CVkRenderContext::CreateIndexBuffer( uint32_t nSize )
{
return (IIndexBuffer*)CreateBuffer(nSize, VK_BUFFER_USAGE_2_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_2_STORAGE_BUFFER_BIT);
}
//-----------------------------------------------------------------------------
// Creates storage buffer. Wrapper over CreateBuffer
// Creates storage buffer. Wrapper over CreateBuffer
//-----------------------------------------------------------------------------
IBuffer *CVkRenderContext::CreateStorageBuffer( uint32_t nSize )
{
@@ -316,7 +322,7 @@ IBuffer *CVkRenderContext::CreateStorageBuffer( uint32_t nSize )
}
//-----------------------------------------------------------------------------
// Creates constant buffer. Wrapper over CreateBuffer
// Creates constant buffer. Wrapper over CreateBuffer
//-----------------------------------------------------------------------------
IBuffer *CVkRenderContext::CreateConstantBuffer( uint32_t nSize )
{
@@ -334,7 +340,7 @@ IBuffer *CVkRenderContext::CreateBuffer( uint32_t nSize, VkBufferUsageFlags2 eUs
//-----------------------------------------------------------------------------
// Creates vulkan buffer aligned to the nAlignment
// Useful for everything eg: ray tracing, which requires them to be aligned
// Useful for everything eg: ray tracing, which requires them to be aligned
// to the groupBaseAlignment.
//-----------------------------------------------------------------------------
IBuffer *CVkRenderContext::CreateBufferAligned( uint32_t nSize, uint32_t nAlignment, VkBufferUsageFlags2 eUsage )
@@ -369,33 +375,13 @@ void CVkRenderContext::DestroyImage( IImage *pImage )
IShader *CVkRenderContext::CreateShader( const char *szName )
{
CCompiledShader stShader = {};
CompiledShaderManager()->ReadFromFile(&stShader, szName);
CVkVertexDescriptionPipelineLibrary vertexDescription = {};
vertexDescription.AddAttribute(0, 0, VERTEX_FORMAT_XYZ32_SFLOAT, 0);
vertexDescription.AddLayout(0, 12);
vertexDescription.SetTopology(TOPOLOGY_MODE_TRIANGLE_LIST);
vertexDescription.Build();
CVkVertexTransformPipelineLibrary vertexTransform = {};
vertexTransform.SetShader(&stShader);
vertexTransform.Build();
CVkPixelShaderPipelineLibrary pixelShader = {};
pixelShader.SetShader(&stShader);
pixelShader.Build();
CVkPixelOutputPipelineLibrary pixelOutput = {};
pixelOutput.AddAttachment(IMAGE_FORMAT_RGBA8_UNORM);
pixelOutput.Build();
CVkShader *pShader = new CVkShader();
pShader->AddShaderLibrary(&vertexDescription);
pShader->AddShaderLibrary(&vertexTransform);
pShader->AddShaderLibrary(&pixelShader);
pShader->AddShaderLibrary(&pixelOutput);
pShader->Build();
VkGraphicsPipelineCreateInfo stPipelineCreateInfo = {};
ICompiledShaderManager *pCompiledShaderManager = (ICompiledShaderManager*)CreateInterface(COMPILED_SHADER_MANAGER_INTERFACE_VERSION, NULL);
pCompiledShaderManager->ReadFromFile(&pShader->m_shader, szName);
pShader->m_hDevice = s_vkDevice;
return pShader;
}
@@ -416,7 +402,9 @@ void CVkRenderContext::DestroyMaterial( IMaterial *pMaterial )
IRenderCommandList *CVkRenderContext::CreateCommandList()
{
return new CVkRenderCommandList;
CVkRenderCommandList *pList = new CVkRenderCommandList;
pList->m_pCommandBufferManager = m_pCommandBufferManager;
return pList;
}
void CVkRenderContext::DestroyCommandList( IRenderCommandList *pCommandList )
@@ -441,7 +429,8 @@ void CVkRenderContext::SetMainWindowManager( IGameWindowManager *pWindowManager
void CVkRenderContext::RegisterGameWindow( IGameWindow *pWindow )
{
VulkanWindow_t window = CreateSwapchain(pWindow);
m_renderWindows.AppendTail(window);
}
void CVkRenderContext::UnregisterGameWindow( IGameWindow *pWindow )
@@ -463,16 +452,16 @@ void CVkRenderContext::Init()
uint32_t nPhysicalDevicesCount;
CUtlVector<VkPhysicalDevice> physicalDevices;
uint32_t nNumQueueFamilies = 0;
CUtlVector<VkQueueFamilyProperties> queueFamilyProperties;
VkApplicationInfo stApplicationInfo = {};
VkInstanceCreateInfo stInstanceCreateInfo = {};
VkDeviceQueueCreateInfo stDeviceQueueCreateInfo = {};
VkDeviceCreateInfo stDeviceCreateInfo = {};
float fPriority = 1.0;
r = volkInitialize();
@@ -501,33 +490,33 @@ void CVkRenderContext::Init()
stInstanceCreateInfo.enabledExtensionCount = enabledInstanceExtensions.GetSize();
stInstanceCreateInfo.ppEnabledExtensionNames = enabledInstanceExtensions.GetData();
r = vkCreateInstance(&stInstanceCreateInfo, NULL, &g_vkInstance);
r = vkCreateInstance(&stInstanceCreateInfo, NULL, &s_vkInstance);
VULKAN_RESULT_PRINT(r, vkCreateInstance);
// volk requires to load instance this way
volkLoadInstance(g_vkInstance);
volkLoadInstance(s_vkInstance);
// Get amount of physical devices
r = vkEnumeratePhysicalDevices(g_vkInstance, &nPhysicalDevicesCount, NULL);
r = vkEnumeratePhysicalDevices(s_vkInstance, &nPhysicalDevicesCount, NULL);
VULKAN_RESULT_PRINT(r, vkEnumeratePhysicalDevices);
physicalDevices.Resize(nPhysicalDevicesCount);
// Read all physical devices
r = vkEnumeratePhysicalDevices(g_vkInstance, &nPhysicalDevicesCount, physicalDevices.GetData());
r = vkEnumeratePhysicalDevices(s_vkInstance, &nPhysicalDevicesCount, physicalDevices.GetData());
VULKAN_RESULT_PRINT(r, vkEnumeratePhysicalDevices);
g_vkPhysicalDevice = SelectPhysicalDevice(physicalDevices);
s_vkPhysicalDevice = SelectPhysicalDevice(physicalDevices);
enabledDeviceExtensions = GetDeviceExtensions();
// Get all queues
vkGetPhysicalDeviceQueueFamilyProperties(g_vkPhysicalDevice, &nNumQueueFamilies, NULL);
vkGetPhysicalDeviceQueueFamilyProperties(s_vkPhysicalDevice, &nNumQueueFamilies, NULL);
queueFamilyProperties.Resize(nNumQueueFamilies);
uint32_t i = 0;
vkGetPhysicalDeviceQueueFamilyProperties(g_vkPhysicalDevice, &nNumQueueFamilies, queueFamilyProperties.GetData());
vkGetPhysicalDeviceQueueFamilyProperties(s_vkPhysicalDevice, &nNumQueueFamilies, queueFamilyProperties.GetData());
for (auto &family: queueFamilyProperties)
{
@@ -544,7 +533,7 @@ void CVkRenderContext::Init()
stDeviceQueueCreateInfo.queueCount = 1;
stDeviceQueueCreateInfo.pQueuePriorities = &fPriority;
stDeviceQueueCreateInfo.queueFamilyIndex = g_iDrawFamily;
VkPhysicalDeviceGraphicsPipelineLibraryFeaturesEXT gplFeatures = {};
gplFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_FEATURES_EXT;
gplFeatures.graphicsPipelineLibrary = VK_TRUE;
@@ -554,7 +543,7 @@ void CVkRenderContext::Init()
vk13Features.pNext = &gplFeatures;
vk13Features.synchronization2 = VK_TRUE;
vk13Features.dynamicRendering = VK_TRUE;
VkPhysicalDeviceVulkan12Features vk12Features = {};
vk12Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES;
vk12Features.pNext = &vk13Features;
@@ -566,132 +555,167 @@ void CVkRenderContext::Init()
stDeviceCreateInfo.enabledExtensionCount = enabledDeviceExtensions.GetSize();
stDeviceCreateInfo.ppEnabledExtensionNames = enabledDeviceExtensions.GetData();
stDeviceCreateInfo.pNext = &vk12Features;
r = vkCreateDevice(g_vkPhysicalDevice, &stDeviceCreateInfo, NULL, &g_vkDevice);
r = vkCreateDevice(s_vkPhysicalDevice, &stDeviceCreateInfo, NULL, &s_vkDevice);
VULKAN_RESULT_PRINT(r, vkEnumeratePhysicalDevices);
for (auto &extension: enabledDeviceExtensions)
V_printf("%s\n", extension);
vkGetDeviceQueue(g_vkDevice, g_iDrawFamily, 0, &g_vkDrawQueue);
vkGetDeviceQueue(g_vkDevice, g_iPresentFamily, 0, &g_vkPresentQueue);
volkLoadDevice(g_vkDevice);
vkGetDeviceQueue(s_vkDevice, g_iDrawFamily, 0, &s_vkDrawQueue);
vkGetDeviceQueue(s_vkDevice, g_iPresentFamily, 0, &s_vkPresentQueue);
volkLoadDevice(s_vkDevice);
VmaAllocatorCreateInfo stAllocatorInfo = {};
stAllocatorInfo.flags = VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT
| VMA_ALLOCATOR_CREATE_KHR_MAINTENANCE5_BIT
;
stAllocatorInfo.vulkanApiVersion = VK_API_VERSION_1_4;
stAllocatorInfo.physicalDevice = g_vkPhysicalDevice;
stAllocatorInfo.device = g_vkDevice;
stAllocatorInfo.instance = g_vkInstance;
stAllocatorInfo.physicalDevice = s_vkPhysicalDevice;
stAllocatorInfo.device = s_vkDevice;
stAllocatorInfo.instance = s_vkInstance;
VmaVulkanFunctions vulkanFunctions;
vmaImportVulkanFunctionsFromVolk(&stAllocatorInfo, &vulkanFunctions);
stAllocatorInfo.pVulkanFunctions = &vulkanFunctions;
vmaCreateAllocator(&stAllocatorInfo, &g_vkAllocator);
vmaCreateAllocator(&stAllocatorInfo, &s_vkAllocator);
VkPipelineLayoutCreateInfo stPipelineLayout = {};
stPipelineLayout.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
stPipelineLayout.flags = VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT;
vkCreatePipelineLayout(g_vkDevice, &stPipelineLayout, NULL, &g_pLibraryEmptyLayout);
g_vkCommandPools.Resize(g_vkSwapchainImages.GetSize());
for (auto &pool: g_vkCommandPools)
{
VkCommandPoolCreateInfo commandPoolCreateInfo = {};
commandPoolCreateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
commandPoolCreateInfo.queueFamilyIndex = g_iDrawFamily;
commandPoolCreateInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
vkCreateCommandPool(g_vkDevice, &commandPoolCreateInfo, NULL, &pool);
}
g_pCommandBufferManager = (IVkCommandBufferManager*)CreateInterface(VULKAN_COMMAND_BUFFER_MANAGER_INTERFACE_NAME, NULL);
g_pCommandBufferManager->Init();
vkCreatePipelineLayout(s_vkDevice, &stPipelineLayout, NULL, &g_pLibraryEmptyLayout);
m_pCommandBufferManager = (IVkCommandBufferManager*)CreateInterface(VULKAN_COMMAND_BUFFER_MANAGER_INTERFACE_NAME, NULL);
m_pCommandBufferManager->SetVulkanHandlers(s_vkInstance, s_vkDevice);
m_pCommandBufferManager->Init();
}
void CVkRenderContext::Frame( float fDeltaTime )
{
/*
CVkBlitCommand *pBlitCommand = NULL;
if (m_pOutputImage)
uint32_t i;
CUtlVector<VkFence> fences = {};
CUtlVector<VkSemaphore> imageReady = {};
CUtlVector<VkSemaphore> renderFinish = {};
CUtlVector<VkSwapchainKHR> swapchains = {};
CUtlVector<uint32_t> uImageIndexes = {};
CUtlVector<uint32_t> uSwapchainImageIndexes = {};
CUtlVector<VulkanWindow_t> recreatedWindows = {};
vkDeviceWaitIdle(s_vkDevice);
i = 0;
for ( auto &s: m_renderWindows)
{
pBlitCommand = CREATE_COMMAND(Blit);
pBlitCommand->AddDependency(m_pOutputImage, DEPENDENCY_MODE_BLIT_IMAGE_SOURCE);
pBlitCommand->AddSwapchainDependency((IRenderingObject**)g_vkSwapchainImages.GetData(), DEPENDENCY_MODE_BLIT_IMAGE_DESTINATION);
pBlitCommand->stInputImage.m_eObjectType = FRAME_OBJECT_TYPE_SINGLE;
pBlitCommand->stInputImage.m_pSingle = m_pOutputImage;
pBlitCommand->stOutputImage.m_eObjectType = FRAME_OBJECT_TYPE_SWAPPED;
pBlitCommand->stOutputImage.m_ppSwapped = (IRenderingObject**)g_vkSwapchainImages.GetData();
pBlitCommand->iSrcMax[0] = 1280;
pBlitCommand->iSrcMax[1] = 720;
pBlitCommand->iSrcMax[2] = 1;
pBlitCommand->iDstMax[0] = 1280;
pBlitCommand->iDstMax[1] = 720;
pBlitCommand->iDstMax[2] = 1;
if ( !s.m_pWindow->BRenderSizeUpdated() )
{
i++;
continue;
}
DestroySwapchain(i);
m_renderWindows.RemoveAt(i);
recreatedWindows.AppendTail(CreateSwapchain(s.m_pWindow));
}
s_pPresentCommandBuffer = g_pCommandBufferManager->CreateCommandBuffer();
for ( auto &s: recreatedWindows)
{
m_renderWindows.AppendTail(s);
}
vkDeviceWaitIdle(s_vkDevice);
for ( auto &s: m_renderWindows)
{
fences.AppendTail(s.m_fences[s.m_uCurrentFrame]);
imageReady.AppendTail(s.m_imageAvailable[s.m_uCurrentFrame]);
renderFinish.AppendTail(s.m_renderFinished[s.m_uCurrentFrame]);
swapchains.AppendTail(s.m_swapchain);
uImageIndexes.AppendTail(s.m_uCurrentFrame);
}
uSwapchainImageIndexes.Resize(m_renderWindows.GetSize());
vkWaitForFences(s_vkDevice, fences.GetSize(), fences.GetData(), VK_TRUE, UINT64_MAX);
vkResetFences(s_vkDevice, fences.GetSize(), fences.GetData());
i = 0;
for ( auto &s: m_renderWindows )
{
VkResult r = vkAcquireNextImageKHR(s_vkDevice, s.m_swapchain, UINT64_MAX, s.m_imageAvailable[s.m_uCurrentFrame], NULL, &uSwapchainImageIndexes[i]);
i++;
}
s_pPresentCommandBuffer = m_pCommandBufferManager->CreateCommandBuffer();
s_pPresentCommandBuffer->Reset();
if (pBlitCommand != NULL)
s_pPresentCommandBuffer->AddCommand(pBlitCommand);
i = 0;
for ( auto &s: m_renderWindows )
{
CVkBlitCommand *pBlitCommand = NULL;
if (s.m_pWindow->GetOutputImage())
{
pBlitCommand = CREATE_COMMAND(Blit);
pBlitCommand->AddDependency(s.m_pWindow->GetOutputImage(), DEPENDENCY_MODE_BLIT_IMAGE_SOURCE);
pBlitCommand->AddDependency((IRenderingObject*)s.m_images[uSwapchainImageIndexes[i]], DEPENDENCY_MODE_BLIT_IMAGE_DESTINATION);
pBlitCommand->stInputImage.m_eObjectType = FRAME_OBJECT_TYPE_SINGLE;
pBlitCommand->stInputImage.m_pSingle = s.m_pWindow->GetOutputImage();
pBlitCommand->stOutputImage.m_eObjectType = FRAME_OBJECT_TYPE_SINGLE;
pBlitCommand->stOutputImage.m_pSingle = (IRenderingObject*)s.m_images[uSwapchainImageIndexes[i]];
pBlitCommand->iSrcMax[0] = s.m_pWindow->GetOutputImage()->GetImageWidth();
pBlitCommand->iSrcMax[1] = s.m_pWindow->GetOutputImage()->GetImageHeight();
pBlitCommand->iSrcMax[2] = 1;
pBlitCommand->iDstMax[0] = s.m_pWindow->GetRenderWidth();
pBlitCommand->iDstMax[1] = s.m_pWindow->GetRenderHeight();
pBlitCommand->iDstMax[2] = 1;
}
if (pBlitCommand != NULL)
s_pPresentCommandBuffer->AddCommand(pBlitCommand);
i++;
}
s_pPresentCommandBuffer->Render();
vkDeviceWaitIdle(g_vkDevice);
static uint32_t s_nImageIndex = 0;
uint32_t nImageIndex = 0;
vkWaitForFences(g_vkDevice, 1, &g_vkFences[s_nImageIndex], VK_TRUE, UINT64_MAX);
VkResult r = vkAcquireNextImageKHR(g_vkDevice, g_vkSwapchain, UINT64_MAX, g_vkGraphicsSemaphores[s_nImageIndex], NULL, &nImageIndex);
vkResetFences(g_vkDevice, 1, &g_vkFences[s_nImageIndex]);
s_pPresentCommandBuffer->Submit(0);
s_pPresentCommandBuffer->Submit(nImageIndex);
VkPipelineStageFlags uPipelineStageFlags = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
VkSubmitInfo stSubmitInfo = {};
stSubmitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
stSubmitInfo.waitSemaphoreCount = 1;
stSubmitInfo.pWaitSemaphores = &g_vkGraphicsSemaphores[s_nImageIndex];
stSubmitInfo.waitSemaphoreCount = imageReady.GetSize();
stSubmitInfo.pWaitSemaphores = imageReady.GetData();
stSubmitInfo.pWaitDstStageMask = &uPipelineStageFlags;
stSubmitInfo.commandBufferCount = g_vkCommandBuffers.GetSize();
stSubmitInfo.pCommandBuffers = g_vkCommandBuffers.GetData();
stSubmitInfo.signalSemaphoreCount = 1;
stSubmitInfo.pSignalSemaphores = &g_vkPresentSemaphores[nImageIndex];
stSubmitInfo.commandBufferCount = m_pCommandBufferManager->GetVulkanCommands().GetSize();
stSubmitInfo.pCommandBuffers = m_pCommandBufferManager->GetVulkanCommands().GetData();
stSubmitInfo.signalSemaphoreCount = renderFinish.GetSize();
stSubmitInfo.pSignalSemaphores = renderFinish.GetData();
vkQueueSubmit(g_vkDrawQueue, 1, &stSubmitInfo, g_vkFences[s_nImageIndex]);
vkQueueSubmit(s_vkDrawQueue, 1, &stSubmitInfo, fences[0]);
VkPresentInfoKHR stPresentInfo = {};
stPresentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
stPresentInfo.waitSemaphoreCount = 1;
stPresentInfo.pWaitSemaphores = &g_vkPresentSemaphores[nImageIndex];
stPresentInfo.swapchainCount = 1;
stPresentInfo.pSwapchains = &g_vkSwapchain;
stPresentInfo.pImageIndices = &nImageIndex;
stPresentInfo.waitSemaphoreCount = renderFinish.GetSize();
stPresentInfo.pWaitSemaphores = renderFinish.GetData();
stPresentInfo.swapchainCount = swapchains.GetSize();
stPresentInfo.pSwapchains = swapchains.GetData();
stPresentInfo.pImageIndices = uImageIndexes.GetData();
vkQueuePresentKHR(g_vkPresentQueue, &stPresentInfo);
vkQueuePresentKHR(s_vkPresentQueue, &stPresentInfo);
s_nImageIndex = (s_nImageIndex + 1) % g_vkSwapchainImages.GetSize();
g_vkCommandBuffers = {};
*/
for ( auto &s: m_renderWindows )
{
s.m_uCurrentFrame = (s.m_uCurrentFrame + 1) % FRAMES_IN_FLIGHT;
}
m_pCommandBufferManager->RenderingFinished();
}
void CVkRenderContext::CreateSwapchain( IGameWindow *pWindow )
VulkanWindow_t CVkRenderContext::CreateSwapchain( IGameWindow *pWindow )
{
uint32_t numSurfaceFormats = 0;
CUtlVector<VkSurfaceFormatKHR> surfaceFormats;
VkSurfaceCapabilitiesKHR surfaceCapatibilities = {};
VkSurfaceCapabilitiesKHR surfaceCapatibilities = {};
uint32_t nSurfacePresentModes = 0;
CUtlVector<VkPresentModeKHR> surfacePresentModes;
const VkFormat preferedSurfaceFormats[] = {
VK_FORMAT_B8G8R8A8_UNORM,
VK_FORMAT_R8G8B8A8_UNORM,
@@ -699,22 +723,23 @@ void CVkRenderContext::CreateSwapchain( IGameWindow *pWindow )
VkSurfaceFormatKHR stSelectedFormat;
VkSwapchainCreateInfoKHR stSwapchainCreateInfo = {};
VkFenceCreateInfo stFenceCreateInfo = {};
VkFenceCreateInfo stFenceCreateInfo = {};
VkSemaphoreCreateInfo stSemaphoreCreateInfo = {};
uint32_t nSwapchainImages;
CUtlVector<VkImage> swapchainImages;
VkSurfaceKHR hSurface;
hSurface = (VkSurfaceKHR)pWindow->CreateVulkanSurface(g_vkInstance);
VulkanWindow_t window = {};
window.m_surface = (VkSurfaceKHR)pWindow->CreateVulkanSurface(s_vkInstance);
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(g_vkPhysicalDevice, (VkSurfaceKHR)hSurface, &surfaceCapatibilities);
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(s_vkPhysicalDevice, (VkSurfaceKHR)window.m_surface, &surfaceCapatibilities);
vkGetPhysicalDeviceSurfaceFormatsKHR(g_vkPhysicalDevice, (VkSurfaceKHR)hSurface, &numSurfaceFormats, NULL);
vkGetPhysicalDeviceSurfaceFormatsKHR(s_vkPhysicalDevice, (VkSurfaceKHR)window.m_surface, &numSurfaceFormats, NULL);
surfaceFormats.Resize(numSurfaceFormats);
vkGetPhysicalDeviceSurfaceFormatsKHR(g_vkPhysicalDevice, (VkSurfaceKHR)hSurface, &numSurfaceFormats, surfaceFormats.GetData());
vkGetPhysicalDeviceSurfaceFormatsKHR(s_vkPhysicalDevice, (VkSurfaceKHR)window.m_surface, &numSurfaceFormats, surfaceFormats.GetData());
stSelectedFormat = surfaceFormats[0];
@@ -731,12 +756,12 @@ void CVkRenderContext::CreateSwapchain( IGameWindow *pWindow )
}
formatPicked:
vkGetPhysicalDeviceSurfacePresentModesKHR(g_vkPhysicalDevice, hSurface, &nSurfacePresentModes, NULL);
vkGetPhysicalDeviceSurfacePresentModesKHR(s_vkPhysicalDevice, window.m_surface, &nSurfacePresentModes, NULL);
surfacePresentModes.Resize(nSurfacePresentModes);
vkGetPhysicalDeviceSurfacePresentModesKHR(g_vkPhysicalDevice, hSurface, &nSurfacePresentModes, surfacePresentModes.GetData());
vkGetPhysicalDeviceSurfacePresentModesKHR(s_vkPhysicalDevice, window.m_surface, &nSurfacePresentModes, surfacePresentModes.GetData());
stSwapchainCreateInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
stSwapchainCreateInfo.surface = hSurface;
stSwapchainCreateInfo.surface = window.m_surface;
stSwapchainCreateInfo.imageFormat = stSelectedFormat.format;
stSwapchainCreateInfo.imageColorSpace = stSelectedFormat.colorSpace;
stSwapchainCreateInfo.presentMode = VK_PRESENT_MODE_IMMEDIATE_KHR;
@@ -744,19 +769,20 @@ formatPicked:
stSwapchainCreateInfo.preTransform = surfaceCapatibilities.currentTransform;
stSwapchainCreateInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
stSwapchainCreateInfo.imageArrayLayers = 1;
stSwapchainCreateInfo.imageExtent = surfaceCapatibilities.minImageExtent;
stSwapchainCreateInfo.imageExtent = {pWindow->GetRenderWidth(), pWindow->GetRenderHeight()};
if (stSwapchainCreateInfo.imageExtent.width == 0)
stSwapchainCreateInfo.imageExtent.width = 1;
if (stSwapchainCreateInfo.imageExtent.height == 0)
stSwapchainCreateInfo.imageExtent.height = 1;
stSwapchainCreateInfo.minImageCount = surfaceCapatibilities.minImageCount;
vkCreateSwapchainKHR(g_vkDevice, &stSwapchainCreateInfo, NULL, &g_vkSwapchain);
vkCreateSwapchainKHR(s_vkDevice, &stSwapchainCreateInfo, NULL, &window.m_swapchain);
g_vkWindowImageFormat = stSwapchainCreateInfo.imageFormat;
window.m_eFormat = stSwapchainCreateInfo.imageFormat;
vkGetSwapchainImagesKHR(g_vkDevice, g_vkSwapchain, &nSwapchainImages, NULL);
g_vkSwapchainImages.Resize(nSwapchainImages);
vkGetSwapchainImagesKHR(s_vkDevice, window.m_swapchain, &nSwapchainImages, NULL);
window.m_images.Resize(nSwapchainImages);
swapchainImages.Resize(nSwapchainImages);
g_vkFences.Resize(nSwapchainImages);
g_vkGraphicsSemaphores.Resize(nSwapchainImages);
g_vkPresentSemaphores.Resize(nSwapchainImages);
vkGetSwapchainImagesKHR(g_vkDevice, g_vkSwapchain, &nSwapchainImages, swapchainImages.GetData());
vkGetSwapchainImagesKHR(s_vkDevice, window.m_swapchain, &nSwapchainImages, swapchainImages.GetData());
for ( int i = 0; i < swapchainImages.GetSize(); i++ )
{
@@ -765,28 +791,43 @@ formatPicked:
pImage->m_image = swapchainImages[i];
pImage->m_eImageType = IMAGE_TYPE_2D;
pImage->m_eMultisampleType = MULTISAMPLE_TYPE_NONE;
pImage->m_eFormat = IMAGE_FORMAT_WINDOW;
pImage->m_eFormat = IMAGE_FORMAT_BGRA8_UNORM;
pImage->m_nHeight = 1280;
pImage->m_nWidth = 720;
pImage->m_ePreferredLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
pImage->m_ePreferredLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
pImage->CreateImageView();
g_vkSwapchainImages[i] = pImage;
window.m_images[i] = pImage;
}
for ( int i = 0; i < FRAMES_IN_FLIGHT; i++ )
{
stFenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
stFenceCreateInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
vkCreateFence(g_vkDevice, &stFenceCreateInfo, NULL, &g_vkFences[i]);
vkCreateFence(s_vkDevice, &stFenceCreateInfo, NULL, &window.m_fences[i]);
stSemaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
vkCreateSemaphore(g_vkDevice, &stSemaphoreCreateInfo, NULL, &g_vkGraphicsSemaphores[i]);
vkCreateSemaphore(g_vkDevice, &stSemaphoreCreateInfo, NULL, &g_vkPresentSemaphores[i]);
vkCreateSemaphore(s_vkDevice, &stSemaphoreCreateInfo, NULL, &window.m_imageAvailable[i]);
vkCreateSemaphore(s_vkDevice, &stSemaphoreCreateInfo, NULL, &window.m_renderFinished[i]);
}
window.m_pWindow = pWindow;
return window;
}
void CVkRenderContext::DestroySwapchain( IGameWindow *pWindow )
void CVkRenderContext::DestroySwapchain( uint32_t uIndex )
{
vkDestroySwapchainKHR(g_vkDevice, g_vkSwapchain, NULL);
pWindow->DestroyVulkanSurface(g_vkInstance);
for ( auto i: m_renderWindows[uIndex].m_images )
{
CVkImage *pImage = (CVkImage*)i;
vkDestroyImageView(s_vkDevice, pImage->m_imageView, NULL);
}
vkDestroySwapchainKHR(s_vkDevice, m_renderWindows[uIndex].m_swapchain, NULL);
m_renderWindows[uIndex].m_pWindow->DestroyVulkanSurface(s_vkInstance);
for ( int i = 0; i < FRAMES_IN_FLIGHT; i++ )
{
vkDestroyFence(s_vkDevice, m_renderWindows[uIndex].m_fences[i], NULL);
vkDestroySemaphore(s_vkDevice, m_renderWindows[uIndex].m_imageAvailable[i], NULL);
vkDestroySemaphore(s_vkDevice, m_renderWindows[uIndex].m_renderFinished[i], NULL);
}
}
//-----------------------------------------------------------------------------
@@ -794,7 +835,7 @@ void CVkRenderContext::DestroySwapchain( IGameWindow *pWindow )
//-----------------------------------------------------------------------------
void CVkRenderContext::Shutdown()
{
vkDestroyInstance(g_vkInstance, NULL);
vkDestroyInstance(s_vkInstance, NULL);
}
@@ -820,7 +861,7 @@ VkPhysicalDevice CVkRenderContext::SelectPhysicalDevice( CUtlVector<VkPhysicalDe
r = vkEnumerateDeviceExtensionProperties(device, NULL, &nExtensionCount, NULL);
VULKAN_RESULT_PRINT(r, vkEnumeratePhysicalDevices);
extensions.Resize(nExtensionCount);
r = vkEnumerateDeviceExtensionProperties(device, NULL, &nExtensionCount, extensions.GetData());
VULKAN_RESULT_PRINT(r, vkEnumeratePhysicalDevices);
@@ -854,11 +895,11 @@ CUtlVector<const char *> CVkRenderContext::GetDeviceExtensions()
const char *szExtensionName;
r = vkEnumerateDeviceExtensionProperties(g_vkPhysicalDevice, NULL, &nExtensionCount, NULL);
r = vkEnumerateDeviceExtensionProperties(s_vkPhysicalDevice, NULL, &nExtensionCount, NULL);
VULKAN_RESULT_PRINT(r, vkEnumeratePhysicalDevices);
extensions.Resize(nExtensionCount);
r = vkEnumerateDeviceExtensionProperties(g_vkPhysicalDevice, NULL, &nExtensionCount, extensions.GetData());
r = vkEnumerateDeviceExtensionProperties(s_vkPhysicalDevice, NULL, &nExtensionCount, extensions.GetData());
VULKAN_RESULT_PRINT(r, vkEnumeratePhysicalDevices);
@@ -875,4 +916,3 @@ CUtlVector<const char *> CVkRenderContext::GetDeviceExtensions()
return enabledExtensions;
}