made rendering work
This commit is contained in:
@@ -4,9 +4,6 @@
|
||||
#include "tier1/utlvector.h"
|
||||
#include "vulkan_state.h"
|
||||
|
||||
CUtlVector<VkCommandBuffer> g_vkCommandBuffers;
|
||||
IVkCommandBufferManager *g_pCommandBufferManager;
|
||||
|
||||
struct VulkanCommandLastUsage_t
|
||||
{
|
||||
uint32_t m_nLastUsedCommand;
|
||||
@@ -24,6 +21,7 @@ struct VulkanSwapchainCommandLastUsage_t
|
||||
class CVkCommandBuffer: public IVkCommandBuffer
|
||||
{
|
||||
public:
|
||||
virtual void SetVulkanHandlers( VkDevice hDevice, IVkCommandBufferManager *pManager ) override;
|
||||
virtual void AddCommand( CVkCommand *pCommand ) override;
|
||||
virtual void Reset() override;
|
||||
virtual void Submit( int iFrameIndex ) override;
|
||||
@@ -39,25 +37,34 @@ private:
|
||||
CUtlVector<CUtlVector<VulkanCommandLastUsage_t>> m_dependencies;
|
||||
CUtlVector<VulkanSwapchainCommandLastUsage_t> m_usedSwapchainDependencies;
|
||||
CUtlVector<CUtlVector<VulkanSwapchainCommandLastUsage_t>> m_swapchainDependencies;
|
||||
|
||||
VkDevice m_hDevice;
|
||||
IVkCommandBufferManager *m_pMgr;
|
||||
VkCommandPool m_hPool;
|
||||
};
|
||||
|
||||
void CVkCommandBuffer::SetVulkanHandlers( VkDevice hDevice, IVkCommandBufferManager *pManager )
|
||||
{
|
||||
m_hDevice = hDevice;
|
||||
m_pMgr = pManager;
|
||||
}
|
||||
|
||||
void CVkCommandBuffer::Reset()
|
||||
{
|
||||
VkCommandBufferAllocateInfo commandBufferAllocInfo = {};
|
||||
int i = 0;
|
||||
VkCommandPoolCreateInfo stCreateInfo = {};
|
||||
|
||||
stCreateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
||||
stCreateInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
|
||||
vkCreateCommandPool(m_hDevice, &stCreateInfo, NULL, &m_hPool);
|
||||
m_hBuffers = {};
|
||||
m_hBuffers.Resize(g_vkCommandPools.GetSize());
|
||||
m_hBuffers.Resize(FRAMES_IN_FLIGHT);
|
||||
|
||||
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++;
|
||||
}
|
||||
commandBufferAllocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
||||
commandBufferAllocInfo.commandPool = m_hPool;
|
||||
commandBufferAllocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
||||
commandBufferAllocInfo.commandBufferCount = FRAMES_IN_FLIGHT;
|
||||
vkAllocateCommandBuffers(m_hDevice, &commandBufferAllocInfo, m_hBuffers.GetData());
|
||||
|
||||
m_commands = {};
|
||||
}
|
||||
@@ -69,7 +76,7 @@ void CVkCommandBuffer::AddCommand( CVkCommand *pCommand )
|
||||
|
||||
void CVkCommandBuffer::Submit( int iFrameIndex )
|
||||
{
|
||||
g_vkCommandBuffers.AppendTail(m_hBuffers[iFrameIndex]);
|
||||
m_pMgr->GetVulkanCommands().AppendTail(m_hBuffers[iFrameIndex]);
|
||||
};
|
||||
|
||||
struct VulkanBarrierObjects_t
|
||||
@@ -332,8 +339,15 @@ class CVkCommandBufferManager: public IVkCommandBufferManager
|
||||
public:
|
||||
virtual void Init() override;
|
||||
virtual void Shutdown() override;
|
||||
virtual void SetVulkanHandlers( VkInstance hInstance, VkDevice hDevice ) override;
|
||||
virtual IVkCommandBuffer *CreateCommandBuffer() override;
|
||||
virtual CVkCommand *CreateCommand( const char *szName ) override;
|
||||
virtual CUtlVector<VkCommandBuffer> &GetVulkanCommands() override;
|
||||
virtual void RenderingFinished() override;
|
||||
private:
|
||||
|
||||
VkDevice m_hDevice;
|
||||
CUtlVector<VkCommandBuffer> m_commands;
|
||||
};
|
||||
|
||||
EXPOSE_INTERFACE(CVkCommandBufferManager, IVkCommandBufferManager, VULKAN_COMMAND_BUFFER_MANAGER_INTERFACE_NAME);
|
||||
@@ -348,9 +362,17 @@ void CVkCommandBufferManager::Shutdown()
|
||||
|
||||
}
|
||||
|
||||
void CVkCommandBufferManager::SetVulkanHandlers( VkInstance hInstance, VkDevice hDevice )
|
||||
{
|
||||
m_hDevice = hDevice;
|
||||
}
|
||||
|
||||
|
||||
IVkCommandBuffer *CVkCommandBufferManager::CreateCommandBuffer()
|
||||
{
|
||||
return new CVkCommandBuffer;
|
||||
IVkCommandBuffer *pBuffer = new CVkCommandBuffer;
|
||||
pBuffer->SetVulkanHandlers(m_hDevice, this);
|
||||
return pBuffer;
|
||||
}
|
||||
|
||||
|
||||
@@ -373,6 +395,17 @@ CVkCommand *CVkCommandBufferManager::CreateCommand( const char *szName )
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CUtlVector<VkCommandBuffer> &CVkCommandBufferManager::GetVulkanCommands()
|
||||
{
|
||||
return m_commands;
|
||||
}
|
||||
|
||||
void CVkCommandBufferManager::RenderingFinished()
|
||||
{
|
||||
m_commands = {};
|
||||
}
|
||||
|
||||
|
||||
CVkCommandRegistry::CVkCommandRegistry( const char *szName, fnCreateVulkanCommand_t pfnCreate )
|
||||
{
|
||||
VulkanCommandRegistry_t *pCommand = new VulkanCommandRegistry_t;
|
||||
|
||||
@@ -38,7 +38,10 @@ DECLARE_VULKAN_COMMAND(Begin)
|
||||
a.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO;
|
||||
a.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
a.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
a.clearValue.color.float32[1] = 1;
|
||||
a.clearValue.color.float32[0] = i.m_fClearColor[0];
|
||||
a.clearValue.color.float32[1] = i.m_fClearColor[1];
|
||||
a.clearValue.color.float32[2] = i.m_fClearColor[2];
|
||||
a.clearValue.color.float32[3] = i.m_fClearColor[3];
|
||||
a.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
a.imageView = ((CVkImage*)VulkanGetObject(i.m_stImage, iCurrentFrame))->m_imageView;
|
||||
attachments.AppendTail(a);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
BEGIN_BUILD_PIPELINE_LIBRARY(VertexDescription)
|
||||
library.flags = VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT;
|
||||
|
||||
|
||||
VkPipelineVertexInputStateCreateInfo vertexInput = {};
|
||||
VkPipelineInputAssemblyStateCreateInfo inputAssembly = {};
|
||||
|
||||
@@ -81,8 +81,8 @@ BEGIN_BUILD_PIPELINE_LIBRARY(VertexTransform)
|
||||
inits[i].m_set.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
|
||||
inits[i].m_set.bindingCount = inits[i].m_bindings.GetSize();
|
||||
inits[i].m_set.pBindings = inits[i].m_bindings.GetData();
|
||||
|
||||
vkCreateDescriptorSetLayout(g_vkDevice, &inits[i].m_set, NULL, &m_setLayouts[i] );
|
||||
|
||||
vkCreateDescriptorSetLayout(m_hDevice, &inits[i].m_set, NULL, &m_setLayouts[i] );
|
||||
}
|
||||
|
||||
for ( i = 0; i < SHADER_STAGE_COUNT; i++)
|
||||
@@ -92,6 +92,7 @@ BEGIN_BUILD_PIPELINE_LIBRARY(VertexTransform)
|
||||
|
||||
CUtlBuffer<unsigned char> code = ShaderParser()->GetShaderCode(m_pShader, (EShaderStage)i);
|
||||
|
||||
|
||||
// We may fail loading the specific stage
|
||||
if (code.GetSize() == 0)
|
||||
continue;
|
||||
@@ -105,7 +106,7 @@ BEGIN_BUILD_PIPELINE_LIBRARY(VertexTransform)
|
||||
shader.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
||||
shader.pName = "main";
|
||||
shader.stage = VulkanGetShaderStage((EShaderStage)i);
|
||||
|
||||
|
||||
spirvs.AppendTail(code);
|
||||
stageShaders.AppendTail(mod);
|
||||
stages.AppendTail(shader);
|
||||
@@ -125,11 +126,13 @@ BEGIN_BUILD_PIPELINE_LIBRARY(VertexTransform)
|
||||
stPipelineLayout.pSetLayouts = m_setLayouts;
|
||||
*/
|
||||
stPipelineLayout.flags = VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT ;
|
||||
vkCreatePipelineLayout(g_vkDevice, &stPipelineLayout, NULL, &m_layout);
|
||||
vkCreatePipelineLayout(m_hDevice, &stPipelineLayout, NULL, &m_layout);
|
||||
|
||||
rasterState.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
|
||||
rasterState.polygonMode = VK_POLYGON_MODE_FILL;
|
||||
rasterState.lineWidth = 1;
|
||||
rasterState.cullMode = VK_CULL_MODE_NONE;
|
||||
rasterState.frontFace = VK_FRONT_FACE_CLOCKWISE;
|
||||
|
||||
viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
|
||||
|
||||
@@ -156,7 +159,7 @@ void CVkVertexTransformPipelineLibrary::SetShader( CCompiledShader *pShader )
|
||||
|
||||
BEGIN_BUILD_PIPELINE_LIBRARY(PixelShader)
|
||||
printf("--- PixelShader ---\n");
|
||||
|
||||
|
||||
VkPipelineDepthStencilStateCreateInfo depthStencil = {};
|
||||
VkPipelineRenderingCreateInfo render = {};
|
||||
int i = 0;
|
||||
@@ -175,10 +178,10 @@ BEGIN_BUILD_PIPELINE_LIBRARY(PixelShader)
|
||||
inits[i].m_set.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
|
||||
inits[i].m_set.bindingCount = inits[i].m_bindings.GetSize();
|
||||
inits[i].m_set.pBindings = inits[i].m_bindings.GetData();
|
||||
|
||||
vkCreateDescriptorSetLayout(g_vkDevice, &inits[i].m_set, NULL, &m_setLayouts[i] );
|
||||
|
||||
vkCreateDescriptorSetLayout(m_hDevice, &inits[i].m_set, NULL, &m_setLayouts[i] );
|
||||
}
|
||||
|
||||
|
||||
VkPipelineLayoutCreateInfo stPipelineLayout = {};
|
||||
stPipelineLayout.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
||||
/*
|
||||
@@ -186,7 +189,7 @@ BEGIN_BUILD_PIPELINE_LIBRARY(PixelShader)
|
||||
stPipelineLayout.pSetLayouts = m_setLayouts;
|
||||
*/
|
||||
stPipelineLayout.flags = VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT ;
|
||||
vkCreatePipelineLayout(g_vkDevice, &stPipelineLayout, NULL, &m_layout);
|
||||
vkCreatePipelineLayout(m_hDevice, &stPipelineLayout, NULL, &m_layout);
|
||||
|
||||
CUtlBuffer<unsigned char> spirv = {};
|
||||
VkPipelineShaderStageCreateInfo shader = {};
|
||||
@@ -204,8 +207,8 @@ BEGIN_BUILD_PIPELINE_LIBRARY(PixelShader)
|
||||
inits[i].m_set.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
|
||||
inits[i].m_set.bindingCount = inits[i].m_bindings.GetSize();
|
||||
inits[i].m_set.pBindings = inits[i].m_bindings.GetData();
|
||||
|
||||
vkCreateDescriptorSetLayout(g_vkDevice, &inits[i].m_set, NULL, &m_setLayouts[i] );
|
||||
|
||||
vkCreateDescriptorSetLayout(m_hDevice, &inits[i].m_set, NULL, &m_setLayouts[i] );
|
||||
}
|
||||
|
||||
spirv = ShaderParser()->GetShaderCode(m_pShader, SHADER_STAGE_PIXEL);
|
||||
@@ -257,25 +260,20 @@ BEGIN_BUILD_PIPELINE_LIBRARY(PixelOutput)
|
||||
render.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO;
|
||||
render.colorAttachmentCount = m_eFormats.GetSize();
|
||||
render.pColorAttachmentFormats = m_eFormats.GetData();
|
||||
|
||||
|
||||
depthStencil.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
|
||||
|
||||
for ( auto e: m_eFormats )
|
||||
{
|
||||
VkPipelineColorBlendAttachmentState a = {};
|
||||
a.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
|
||||
a.blendEnable = VK_TRUE;
|
||||
a.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
|
||||
a.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
|
||||
a.colorBlendOp = VK_BLEND_OP_ADD;
|
||||
a.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
|
||||
a.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
|
||||
a.alphaBlendOp = VK_BLEND_OP_ADD;
|
||||
a.blendEnable = VK_FALSE;
|
||||
attachments.AppendTail(a);
|
||||
}
|
||||
blend.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
|
||||
blend.attachmentCount = m_eFormats.GetSize();
|
||||
blend.pAttachments = attachments.GetData();
|
||||
blend.logicOp = VK_LOGIC_OP_COPY;
|
||||
|
||||
pipeline.pDepthStencilState = &depthStencil;
|
||||
pipeline.pColorBlendState = &blend;
|
||||
@@ -285,8 +283,8 @@ BEGIN_BUILD_PIPELINE_LIBRARY(PixelOutput)
|
||||
library.flags = VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT;
|
||||
|
||||
END_BUILD_PIPELINE_LIBRARY()
|
||||
|
||||
|
||||
void CVkPixelOutputPipelineLibrary::AddAttachment( EImageFormat eFormat )
|
||||
{
|
||||
m_eFormats.AppendTail(CVkImage::GetImageFormat(eFormat));
|
||||
m_eFormats.AppendTail(CVkImage::GetImageFormat(eFormat));
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ void CVkRenderCommandList::SetRenderTarget( uint32_t uIndex, IImage *pImage )
|
||||
{
|
||||
SwitchRenderingStage(RENDERING_STAGE_SETUP_RASTER);
|
||||
VulkanRenderOutput_t *pOutput = FindOrCreateRenderOutput(uIndex);
|
||||
pOutput->m_stImage.m_eObjectType = FRAME_OBJECT_TYPE_SINGLE;
|
||||
pOutput->m_stImage.m_pSingle = pImage;
|
||||
}
|
||||
|
||||
@@ -44,6 +45,8 @@ void CVkRenderCommandList::SetClearDepth( float fVal)
|
||||
void CVkRenderCommandList::SetRenderResolution( uint32_t iWidth, uint32_t iHeight )
|
||||
{
|
||||
SwitchRenderingStage(RENDERING_STAGE_SETUP_RASTER);
|
||||
m_uWidth = iWidth;
|
||||
m_uHeight = iHeight;
|
||||
}
|
||||
|
||||
|
||||
@@ -71,26 +74,31 @@ void CVkRenderCommandList::SetMaterial( IMaterial *pMaterial )
|
||||
m_pCurrentMaterialBuffer->Reset();
|
||||
CVkBeginCommand *pBeginCommand = CREATE_COMMAND(Begin);
|
||||
pBeginCommand->images = m_pOutput;
|
||||
pBeginCommand->nResolutionX = 1280;
|
||||
pBeginCommand->nResolutionY = 720;
|
||||
pBeginCommand->nResolutionX = m_uWidth;
|
||||
pBeginCommand->nResolutionY = m_uHeight;
|
||||
pBeginCommand->stDepthImage = m_depth;
|
||||
for ( auto &i: pBeginCommand->images)
|
||||
{
|
||||
pBeginCommand->AddDependency(i.m_stImage.m_pSingle, DEPENDENCY_MODE_DRAWCALL_OUTPUT_IMAGE);
|
||||
}
|
||||
m_pCurrentMaterialBuffer->AddCommand(pBeginCommand);
|
||||
|
||||
|
||||
CVkSetShaderCommand *pSetShader = CREATE_COMMAND(SetShader);
|
||||
pSetShader->pShader = ((CVkMaterial*)pMaterial)->m_pVkShader;
|
||||
m_pCurrentMaterialBuffer->AddCommand(pSetShader);
|
||||
|
||||
CVkSetScissorsCommand *pScissorsCommand = CREATE_COMMAND(SetScissors);
|
||||
pScissorsCommand->uWidth = 1280;
|
||||
pScissorsCommand->uHeight = 720;
|
||||
pScissorsCommand->uWidth = m_uWidth;
|
||||
pScissorsCommand->uHeight = m_uHeight;
|
||||
m_pCurrentMaterialBuffer->AddCommand(pScissorsCommand);
|
||||
|
||||
CVkSetViewportCommand *pViewportCommand = CREATE_COMMAND(SetViewport);
|
||||
pViewportCommand->fWidth = 1280;
|
||||
pViewportCommand->fHeight = 720;
|
||||
pViewportCommand->fX = 0;
|
||||
pViewportCommand->fY = 0;
|
||||
pViewportCommand->fWidth = m_uWidth;
|
||||
pViewportCommand->fHeight = m_uHeight;
|
||||
pViewportCommand->fDepthMin = 0;
|
||||
pViewportCommand->fDepthMax = 1;
|
||||
m_pCurrentMaterialBuffer->AddCommand(pViewportCommand);
|
||||
}
|
||||
}
|
||||
@@ -190,7 +198,7 @@ IVkCommandBuffer *CVkRenderCommandList::FindOrCreateMaterialCommandBuffer( IMate
|
||||
}
|
||||
|
||||
VulkanMaterialCommandBuffer_t mat;
|
||||
mat.m_pCommandBuffer = g_pCommandBufferManager->CreateCommandBuffer();
|
||||
mat.m_pCommandBuffer = m_pCommandBufferManager->CreateCommandBuffer();
|
||||
mat.m_pMaterial = pMaterial;
|
||||
m_materials.AppendTail(mat);
|
||||
if (pbWasCreated)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,38 +1,147 @@
|
||||
#include "materialsystem/shaderinternals.h"
|
||||
#include "tier1/utlvector.h"
|
||||
#include "vulkan_state.h"
|
||||
#include "shaderparser.h"
|
||||
CVkShader::~CVkShader()
|
||||
{
|
||||
|
||||
}
|
||||
void CVkShader::AddShaderLibrary( CVkPipelineLibrary *pLibrary )
|
||||
void CVkShader::AddLayout( int iIndex, int iStride )
|
||||
{
|
||||
m_libraries.AppendTail(pLibrary);
|
||||
VkVertexInputBindingDescription layout = {};
|
||||
layout.binding = iIndex;
|
||||
layout.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
|
||||
layout.stride = iStride;
|
||||
m_layouts.AppendTail(layout);
|
||||
}
|
||||
|
||||
void CVkShader::AddAttribute( int iBufferIndex, int iLocation, EVertexFormat eFormat, int iOffset )
|
||||
{
|
||||
VkVertexInputAttributeDescription attribute = {};
|
||||
attribute.binding = iBufferIndex;
|
||||
attribute.location = iLocation;
|
||||
attribute.format = VulkanGetVertexFormat(eFormat);
|
||||
attribute.offset = iOffset;
|
||||
m_attributes.AppendTail(attribute);
|
||||
}
|
||||
|
||||
void CVkShader::SetTopology( ETopologyMode eTopology )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CVkShader::AddOutputImage( int iImageIndex, EImageFormat eFormat )
|
||||
{
|
||||
m_eFormats.AppendTail(CVkImage::GetImageFormat(eFormat));
|
||||
}
|
||||
|
||||
void CVkShader::SetDepthImage( EImageFormat eFormat )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void CVkShader::Build()
|
||||
{
|
||||
CUtlVector<VkPipeline> libs = {};
|
||||
VkPipelineLayoutCreateInfo layoutInfo = {};
|
||||
VkGraphicsPipelineCreateInfo createInfo = {};
|
||||
VkPipelineLibraryCreateInfoKHR libInfo = {};
|
||||
CUtlVector<VkPipelineShaderStageCreateInfo> stages = {};
|
||||
CUtlVector<VkShaderModuleCreateInfo> modules = {};
|
||||
VkPipelineVertexInputStateCreateInfo vertexInput = {};
|
||||
VkPipelineInputAssemblyStateCreateInfo inputAssembly = {};
|
||||
VkPipelineDynamicStateCreateInfo dynamicState = {};
|
||||
VkPipelineRasterizationStateCreateInfo rasterState = {};
|
||||
VkPipelineViewportStateCreateInfo viewportState = {};
|
||||
VkPipelineMultisampleStateCreateInfo msaa = {};
|
||||
VkPipelineDepthStencilStateCreateInfo depthStencil = {};
|
||||
VkPipelineColorBlendStateCreateInfo blend = {};
|
||||
VkPipelineRenderingCreateInfo render = {};
|
||||
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
|
||||
for ( auto l: m_libraries )
|
||||
{
|
||||
libs.AppendTail(l->m_hPipeline);
|
||||
CUtlVector<VkPipelineColorBlendAttachmentState> attachments = {};
|
||||
VkDynamicState dynamicStates[] = {
|
||||
VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT,
|
||||
VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT,
|
||||
};
|
||||
|
||||
libInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LIBRARY_CREATE_INFO_KHR;
|
||||
libInfo.libraryCount = libs.GetSize();
|
||||
libInfo.pLibraries = libs.GetData();
|
||||
createInfo.pNext = &libInfo;
|
||||
createInfo.flags = VK_PIPELINE_CREATE_LINK_TIME_OPTIMIZATION_BIT_EXT;
|
||||
createInfo.layout = g_pLibraryEmptyLayout;
|
||||
VkPipelineLayoutCreateInfo stPipelineLayout = {};
|
||||
|
||||
stPipelineLayout.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
||||
vkCreatePipelineLayout(m_hDevice, &stPipelineLayout, NULL, &m_hPipelineLayout);
|
||||
|
||||
// TODO: Filter by vulkan shaders at some points
|
||||
stages.Resize(m_shader.m_objects.GetSize());
|
||||
modules.Resize(m_shader.m_objects.GetSize());
|
||||
for ( int i = 0; i < m_shader.m_objects.GetSize(); i++ )
|
||||
{
|
||||
V_printf("a: %p\n", m_shader.m_lumps[i].m_pAddress);
|
||||
|
||||
modules[i].sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
|
||||
modules[i].pCode = (uint32_t*)m_shader.GetLumpPtr(m_shader.m_objects[i].m_nDataLump);
|
||||
modules[i].codeSize = m_shader.GetLumpSize(m_shader.m_objects[i].m_nDataLump);
|
||||
stages[i].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
||||
stages[i].pNext = &modules[i];
|
||||
stages[i].pName = "main";
|
||||
stages[i].stage = VulkanGetShaderStage(m_shader.m_objects[i].m_eStage);
|
||||
}
|
||||
|
||||
vertexInput.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
|
||||
vertexInput.vertexBindingDescriptionCount = m_layouts.GetSize();
|
||||
vertexInput.pVertexBindingDescriptions = m_layouts.GetData();
|
||||
vertexInput.vertexAttributeDescriptionCount = m_attributes.GetSize();
|
||||
vertexInput.pVertexAttributeDescriptions = m_attributes.GetData();
|
||||
|
||||
inputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
|
||||
inputAssembly.primitiveRestartEnable = VK_FALSE;
|
||||
inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
|
||||
|
||||
dynamicState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
|
||||
dynamicState.dynamicStateCount = 2;
|
||||
dynamicState.pDynamicStates = dynamicStates;
|
||||
|
||||
rasterState.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
|
||||
rasterState.polygonMode = VK_POLYGON_MODE_FILL;
|
||||
rasterState.lineWidth = 1;
|
||||
rasterState.cullMode = VK_CULL_MODE_NONE;
|
||||
rasterState.frontFace = VK_FRONT_FACE_CLOCKWISE;
|
||||
|
||||
viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
|
||||
|
||||
msaa.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
|
||||
msaa.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
|
||||
|
||||
render.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO;
|
||||
render.pNext = createInfo.pNext;
|
||||
render.colorAttachmentCount = m_eFormats.GetSize();
|
||||
render.pColorAttachmentFormats = m_eFormats.GetData();
|
||||
|
||||
depthStencil.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
|
||||
|
||||
for ( auto e: m_eFormats )
|
||||
{
|
||||
VkPipelineColorBlendAttachmentState a = {};
|
||||
a.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
|
||||
a.blendEnable = VK_FALSE;
|
||||
attachments.AppendTail(a);
|
||||
}
|
||||
|
||||
blend.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
|
||||
blend.attachmentCount = attachments.GetSize();
|
||||
blend.pAttachments = attachments.GetData();
|
||||
|
||||
render.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO;
|
||||
render.colorAttachmentCount = m_eFormats.GetSize();
|
||||
render.pColorAttachmentFormats = m_eFormats.GetData();
|
||||
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
|
||||
createInfo.stageCount = stages.GetSize();
|
||||
createInfo.pStages = stages.GetData();
|
||||
createInfo.layout = m_hPipelineLayout;
|
||||
createInfo.pVertexInputState = &vertexInput;
|
||||
createInfo.pInputAssemblyState = &inputAssembly;
|
||||
createInfo.pDynamicState = &dynamicState;
|
||||
createInfo.pRasterizationState = &rasterState;
|
||||
createInfo.pViewportState = &viewportState;
|
||||
createInfo.pDepthStencilState = &depthStencil;
|
||||
createInfo.pColorBlendState = &blend;
|
||||
createInfo.pMultisampleState = &msaa;
|
||||
createInfo.pNext = &render;
|
||||
// Possibly schedule it?
|
||||
vkCreateGraphicsPipelines(g_vkDevice, NULL, 1, &createInfo, NULL, &m_hPipeline);
|
||||
vkCreateGraphicsPipelines(m_hDevice, NULL, 1, &createInfo, NULL, &m_hPipeline);
|
||||
}
|
||||
|
||||
uint32_t CVkShader::PSGetResourceByName( const char *szName )
|
||||
@@ -44,4 +153,3 @@ uint32_t CVkShader::VSGetResourceByName( const char *szName )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define VULKAN_STATE_H
|
||||
|
||||
|
||||
#include "shadercompiler/icompiler.h"
|
||||
#include "volk.h"
|
||||
#include "vk_mem_alloc.h"
|
||||
#include "tier0/platform.h"
|
||||
@@ -20,16 +21,7 @@ extern struct SupportedVulkanExtensions_t
|
||||
#undef REQUIRED_EXTENSION
|
||||
#undef OPTIONAL_EXTENSION
|
||||
|
||||
extern CUtlVector<IImage*> g_vkSwapchainImages;
|
||||
|
||||
|
||||
extern CUtlVector<VkCommandPool> g_vkCommandPools;
|
||||
extern CUtlVector<VkCommandBuffer> g_vkCommandBuffers;
|
||||
|
||||
extern VkInstance g_vkInstance;
|
||||
extern VmaAllocator g_vkAllocator;
|
||||
extern VkPhysicalDevice g_vkPhysicalDevice;
|
||||
extern VkDevice g_vkDevice;
|
||||
#define FRAMES_IN_FLIGHT 2
|
||||
|
||||
enum EVulkanCommandType
|
||||
{
|
||||
@@ -56,7 +48,7 @@ enum EDependencyMode
|
||||
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,
|
||||
@@ -65,13 +57,13 @@ enum EDependencyMode
|
||||
|
||||
DEPENDENCY_MODE_IMAGE_SOURCE,
|
||||
DEPENDENCY_MODE_IMAGE_DESTINATION,
|
||||
|
||||
|
||||
DEPENDENCY_MODE_BLIT_IMAGE_SOURCE,
|
||||
DEPENDENCY_MODE_BLIT_IMAGE_DESTINATION,
|
||||
|
||||
|
||||
DEPENDENCY_MODE_COLOR_CLEAR_SOURCE,
|
||||
DEPENDENCY_MODE_COLOR_CLEAR_DESTINATION,
|
||||
|
||||
|
||||
DEPENDENCY_MODE_ALL_COMMANDS,
|
||||
DEPENDENCY_MODE_IMAGE_PRESENT,
|
||||
|
||||
@@ -109,14 +101,16 @@ public:
|
||||
CUtlVector<VulkanCommandDepenency_t> m_dependencies = {};
|
||||
CUtlVector<VulkanCommandSwapchainDepenency_t> m_swapchainDependencies = {};
|
||||
EVulkanCommandType m_eType;
|
||||
|
||||
|
||||
void AddDependency( IRenderingObject *pObject, EDependencyMode eDependencyMode );
|
||||
void AddSwapchainDependency( IRenderingObject **ppObjects, EDependencyMode eDependencyMode );
|
||||
};
|
||||
|
||||
class IVkCommandBufferManager;
|
||||
abstract_class IVkCommandBuffer
|
||||
{
|
||||
public:
|
||||
virtual void SetVulkanHandlers( VkDevice hDevice, IVkCommandBufferManager *pManager ) = 0;
|
||||
virtual void AddCommand( CVkCommand *pCommand ) = 0;
|
||||
|
||||
virtual void Reset() = 0;
|
||||
@@ -129,11 +123,13 @@ typedef CVkCommand *(*fnCreateVulkanCommand_t)();
|
||||
abstract_class IVkCommandBufferManager: public IAppSystem
|
||||
{
|
||||
public:
|
||||
virtual void SetVulkanHandlers( VkInstance hInstance, VkDevice hDevice ) = 0;
|
||||
virtual IVkCommandBuffer *CreateCommandBuffer() = 0;
|
||||
virtual CVkCommand *CreateCommand( const char *szName ) = 0;
|
||||
virtual CUtlVector<VkCommandBuffer> &GetVulkanCommands() = 0;
|
||||
virtual void RenderingFinished() = 0;
|
||||
};
|
||||
#define VULKAN_COMMAND_BUFFER_MANAGER_INTERFACE_NAME "VulkanCommandBufferManager"
|
||||
extern IVkCommandBufferManager *g_pCommandBufferManager;
|
||||
|
||||
class CVkCommandRegistry
|
||||
{
|
||||
@@ -141,7 +137,7 @@ public:
|
||||
CVkCommandRegistry( const char *szName, fnCreateVulkanCommand_t pfnCreate );
|
||||
};
|
||||
#define CREATE_COMMAND(name) \
|
||||
(CVk##name##Command*)g_pCommandBufferManager->CreateCommand(#name)
|
||||
(CVk##name##Command*)m_pCommandBufferManager->CreateCommand(#name)
|
||||
|
||||
#define BEGIN_VULKAN_COMMAND( name ) \
|
||||
class CVk##name##Command : public CVkCommand \
|
||||
@@ -171,7 +167,7 @@ public:
|
||||
CVkImage();
|
||||
CVkImage( uint32_t nWidth, uint32_t nHeight, uint32_t nDepth, EImageFormat eFormat, EMultisampleType eMultisampleType, EImageType eImageType, VkImageUsageFlagBits eUsage );
|
||||
~CVkImage();
|
||||
|
||||
|
||||
virtual void SetDebugName( const char *szName ) override;
|
||||
virtual uint32_t GetImageWidth() override;
|
||||
virtual uint32_t GetImageHeight() override;
|
||||
@@ -194,7 +190,7 @@ public:
|
||||
VkImageView m_imageView;
|
||||
VmaAllocation m_allocation;
|
||||
VkImageSubresourceRange m_range;
|
||||
|
||||
|
||||
VkImageLayout m_ePreferredLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
|
||||
VkImageLayout m_eImageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
@@ -226,6 +222,7 @@ public:
|
||||
virtual void Build() = 0;
|
||||
|
||||
VkPipeline m_hPipeline = NULL;
|
||||
VkDevice m_hDevice;
|
||||
};
|
||||
|
||||
#define BEGIN_DEFINE_PIPELINE_LIBRARY(name) \
|
||||
@@ -250,20 +247,32 @@ void CVk##name##PipelineLibrary::Build() \
|
||||
pipeline.layout = g_pLibraryEmptyLayout;
|
||||
|
||||
#define END_BUILD_PIPELINE_LIBRARY() \
|
||||
vkCreateGraphicsPipelines(g_vkDevice, NULL, 1, &pipeline, NULL, &m_hPipeline); \
|
||||
vkCreateGraphicsPipelines(m_hDevice, NULL, 1, &pipeline, NULL, &m_hPipeline); \
|
||||
}
|
||||
|
||||
class CVkShader : public IShader
|
||||
{
|
||||
public:
|
||||
~CVkShader();
|
||||
void AddShaderLibrary( CVkPipelineLibrary *pLibrary );
|
||||
void Build();
|
||||
virtual uint32_t PSGetResourceByName( const char *szName ) override;
|
||||
virtual uint32_t VSGetResourceByName( const char *szName ) override;
|
||||
virtual void AddLayout( int iIndex, int iStride ) override;
|
||||
virtual void AddAttribute( int iBufferIndex, int iLocation, EVertexFormat eFormat, int iOffset ) override;
|
||||
virtual void SetTopology( ETopologyMode eTopology ) override;
|
||||
virtual void AddOutputImage( int iImageIndex, EImageFormat eFormat ) override;
|
||||
virtual void SetDepthImage( EImageFormat eFormat ) override;
|
||||
virtual void Build() override;
|
||||
|
||||
VkPipeline m_hPipeline = NULL;
|
||||
VkPipelineLayout m_hPipelineLayout;
|
||||
CUtlVector<CVkPipelineLibrary*> m_libraries;
|
||||
VkDevice m_hDevice;
|
||||
CCompiledShader m_shader;
|
||||
private:
|
||||
CUtlVector<VkVertexInputAttributeDescription> m_attributes;
|
||||
CUtlVector<VkVertexInputBindingDescription> m_layouts;
|
||||
CUtlVector<VkFormat> m_eFormats;
|
||||
|
||||
};
|
||||
|
||||
class CVkMaterial: public IMaterial
|
||||
@@ -271,13 +280,13 @@ class CVkMaterial: public IMaterial
|
||||
public:
|
||||
CVkMaterial( IShader *pShader );
|
||||
virtual ~CVkMaterial() override;
|
||||
|
||||
|
||||
virtual void VSSetShaderResource( uint32_t uRegister, IRenderingObject *pResource ) override;
|
||||
virtual void VSSetConstantsBuffer( uint32_t uRegister, IBuffer *pConstants ) override;
|
||||
|
||||
|
||||
virtual void PSSetShaderResource( uint32_t uRegister, IRenderingObject *pResource ) override;
|
||||
virtual void PSSetConstantsBuffer( uint32_t uRegister, IBuffer *pConstants ) override;
|
||||
|
||||
|
||||
CVkShader *m_pVkShader;
|
||||
private:
|
||||
void SetShaderResource( uint32_t uRegister, uint32_t uSet, IRenderingObject *pObject);
|
||||
@@ -332,13 +341,13 @@ class CVkRenderCommandList: public IRenderCommandList
|
||||
{
|
||||
public:
|
||||
virtual void ResetRendering() override;
|
||||
|
||||
|
||||
virtual void SetRenderTarget( uint32_t uIndex, IImage *pImage ) override;
|
||||
virtual void SetClearColor( uint32_t uIndex, float r, float g, float b, float a ) override;
|
||||
|
||||
|
||||
virtual void SetDepthTarget( IImage *pDepth ) override;
|
||||
virtual void SetClearDepth( float fVal ) override;
|
||||
|
||||
|
||||
virtual void SetRenderResolution( uint32_t iWidth, uint32_t iHeight ) override;
|
||||
|
||||
// Should they apply per material or for all?
|
||||
@@ -350,13 +359,15 @@ public:
|
||||
virtual void SetIndexBuffer( IVertexBuffer *pBuffer ) override;
|
||||
virtual void DrawPrimitives( uint32_t nVertexCount, uint32_t nFirstVertex, uint32_t nInstanceCount, uint32_t nFirstInstance ) override;
|
||||
virtual void DrawPrimitivesIndexed( uint32_t nIndexCount, uint32_t nFirstIndex, uint32_t nVertexOffset, uint32_t nInstanceCount, uint32_t nFirstInstance ) override;
|
||||
|
||||
|
||||
virtual void ResolveImage( IImage *pOriginal, IImage *pResolved ) override;
|
||||
|
||||
virtual void StartRecording() override;
|
||||
virtual void EndRecording() override;
|
||||
|
||||
|
||||
void Submit();
|
||||
|
||||
IVkCommandBufferManager *m_pCommandBufferManager;
|
||||
private:
|
||||
void SwitchRenderingStage( EVulkanRenderingStage eStage );
|
||||
|
||||
@@ -370,6 +381,9 @@ private:
|
||||
IVkCommandBuffer *m_pPostRaster;
|
||||
|
||||
IVkCommandBuffer *m_pCurrentMaterialBuffer = NULL;
|
||||
|
||||
uint32_t m_uWidth;
|
||||
uint32_t m_uHeight;
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user