working on rendering

This commit is contained in:
2025-12-23 15:03:44 +02:00
parent 5a71b3023a
commit 3b4e2eea32
65 changed files with 1971 additions and 190 deletions

View File

@@ -6,11 +6,15 @@
CUtlVector<CUtlString> MaterialSystem_CompiledFiles = {
"materialsystem/materialsystem.cpp",
"materialsystem/compiledshader.cpp",
"materialsystem/vulkan/shaderparser.cpp",
"materialsystem/vulkan/rendercontext.cpp",
"materialsystem/vulkan/material.cpp",
"materialsystem/vulkan/commandbuffer.cpp",
"materialsystem/vulkan/utils.cpp",
"materialsystem/vulkan/rendercommandlist.cpp",
"materialsystem/vulkan/material.cpp",
"materialsystem/vulkan/shader.cpp",
"materialsystem/vulkan/utils.cpp",
"materialsystem/vulkan/vma.cpp",
"materialsystem/vulkan/commands/draw.cpp",
"materialsystem/vulkan/commands/base.cpp",
"materialsystem/vulkan/libraries/raster.cpp",

View File

@@ -0,0 +1,145 @@
#include "shadercompiler/icompiler.h"
#include "materialsystem/compiledshadermgr.h"
#include "tier2/ifilesystem.h"
uint32_t CCompiledShader::AllocateLump( uint32_t nSize )
{
m_lumps.AppendTail({V_malloc(nSize),nSize});
return m_lumps.GetSize()-1;
}
void *CCompiledShader::GetLumpPtr( uint32_t nLump )
{
return m_lumps[nLump].m_pAddress;
}
uint32_t CCompiledShader::GetLumpSize( uint32_t nLump )
{
return m_lumps[nLump].m_nSize;
}
ShaderObject_t *CCompiledShader::AllocateShader()
{
m_objects.AppendTail({});
return &m_objects[m_objects.GetSize()-1];
}
ShaderObject_t *CCompiledShader::FindShaderObject( EShaderBackend eBackend, EShaderStage eStage )
{
for ( auto &o: m_objects )
{
if ( o.m_eBackend != eBackend )
continue;
if ( o.m_eStage != eStage )
continue;
return &o;
}
return NULL;
}
CCompiledShader::~CCompiledShader()
{
for ( auto l: m_lumps )
V_free(l.m_pAddress);
}
class CCompiledShaderManager: public ICompiledShaderManager
{
public:
virtual void WriteToFile( CCompiledShader *pShader, const char *szFile ) override;
virtual void ReadFromFile( CCompiledShader *pShader, const char *szFile ) override;
};
void CCompiledShaderManager::WriteToFile( CCompiledShader *pShader, const char *szFile )
{
IFileHandle *pFile;
ShaderHeader_t stHeader = {};
uint32_t nTotalSize = sizeof(ShaderHeader_t);
stHeader.m_cSignature[0] = 'f';
stHeader.m_cSignature[1] = 's';
stHeader.m_cSignature[2] = 'h';
stHeader.m_cSignature[3] = 'o';
stHeader.m_nNumLumps = pShader->m_lumps.GetSize();
stHeader.m_nNumShaders = pShader->m_objects.GetSize();
pFile = filesystem->Open(szFile, FILEMODE_WRITE);
pFile->Write(&stHeader, sizeof(ShaderHeader_t));
// We want to get offset for the lump data
nTotalSize += sizeof(ShaderLump_t) * pShader->m_lumps.GetSize();
nTotalSize += sizeof(ShaderObject_t) * pShader->m_objects.GetSize();
// ShaderLump_t
for ( auto l: pShader->m_lumps )
{
ShaderLump_t stLump = {};
stLump.m_nOffset = nTotalSize;
stLump.m_nSize = l.m_nSize;
pFile->Write(&stLump, sizeof(ShaderLump_t));
nTotalSize += l.m_nSize;
}
// ShaderObject_t
for ( auto o: pShader->m_objects )
{
}
// Lump Data
for ( auto l: pShader->m_lumps )
{
pFile->Write(l.m_pAddress, l.m_nSize);
}
pFile->Close();
}
void CCompiledShaderManager::ReadFromFile( CCompiledShader *pShader, const char *szFile )
{
IFileHandle *pFile;
ShaderHeader_t stHeader = {};
int i = 0;
CUtlVector<ShaderLump_t> lumps = {};
CUtlVector<ShaderObject_t> objects = {};
CUtlVector<HostShaderLump_t> lumpsData = {};
pFile = filesystem->Open(szFile, FILEMODE_READ);
pFile->Read(&stHeader, sizeof(ShaderHeader_t));
objects.Resize(stHeader.m_nNumShaders);
lumps.Resize(stHeader.m_nNumLumps);
lumpsData.Resize(stHeader.m_nNumLumps);
pFile->Read(lumps.GetData(), stHeader.m_nNumLumps * sizeof(ShaderLump_t));
pFile->Read(objects.GetData(), stHeader.m_nNumShaders * sizeof(ShaderObject_t));
for ( i = 0; i < stHeader.m_nNumLumps; i++ )
{
lumpsData[i].m_pAddress = V_malloc(lumps[i].m_nSize);
pFile->Seek(SEEKMODE_RELATIVE_START, lumps[i].m_nOffset);
pFile->Read(lumpsData[i].m_pAddress, lumps[i].m_nSize);
lumpsData[i].m_nSize = lumps[i].m_nSize;
};
pShader->m_objects = objects;
pShader->m_lumps = lumpsData;
pFile->Close();
}
ICompiledShaderManager *CompiledShaderManager()
{
static CCompiledShaderManager s_CompiledShaderManager;
return &s_CompiledShaderManager;
}

View File

@@ -6,31 +6,25 @@ public:
virtual void Init() override;
virtual void Frame( float fTime ) override;
virtual void Shutdown() override;
virtual IRenderContext *GetRenderContext( void ) override;
};
extern IRenderContext *g_pVkRenderContext;
IRenderContext *g_pRenderContext;
void CMaterialSystem::Init()
{
GetRenderContext()->Init();
g_pRenderContext = (IRenderContext*)CreateInterface(RENDER_CONTEXT_INTERFACE_NAME, NULL);
g_pRenderContext->Init();
}
void CMaterialSystem::Frame( float fTime )
{
GetRenderContext()->Frame(fTime);
g_pRenderContext->Frame(fTime);
}
void CMaterialSystem::Shutdown()
{
GetRenderContext()->Shutdown();
}
extern IRenderContext *g_pVkRenderContext;
IRenderContext *CMaterialSystem::GetRenderContext( void )
{
return g_pVkRenderContext;
g_pRenderContext->Shutdown();
}

View File

@@ -240,9 +240,9 @@ void CVkCommandBuffer::TryBarrier( int iCurrent, int iCurrentBuffer )
imageMemoryBarrier.dstAccessMask = VulkanGetAccessFlags(barrier.m_eNewDependency);
if (barrier.m_eOldDependency == DEPENDENCY_MODE_FROM_PREVIOUS)
{
imageMemoryBarrier.oldLayout = VulkanGetImageLayout(pImage->m_eLastUsage);
imageMemoryBarrier.srcStageMask = VulkanGetStageFlags(pImage->m_eLastUsage);
imageMemoryBarrier.srcAccessMask = VulkanGetAccessFlags(pImage->m_eLastUsage);
imageMemoryBarrier.oldLayout = VulkanGetImageLayout(DEPENDENCY_MODE_ALL_COMMANDS);
imageMemoryBarrier.srcStageMask = VulkanGetStageFlags(DEPENDENCY_MODE_ALL_COMMANDS);
imageMemoryBarrier.srcAccessMask = VulkanGetAccessFlags(DEPENDENCY_MODE_ALL_COMMANDS);
} else {
imageMemoryBarrier.oldLayout = VulkanGetImageLayout(barrier.m_eOldDependency);
imageMemoryBarrier.srcStageMask = VulkanGetStageFlags(barrier.m_eOldDependency);

View File

@@ -13,16 +13,6 @@ BEGIN_VULKAN_COMMAND(ClearColor)
IImage **ppSwapchainImages = NULL;
END_VULKAN_COMMAND(ClearColor)
struct VulkanRenderOutput_t {
EResolveMode m_eResolveMode;
VkFrameObject_t m_stImage;
VkFrameObject_t m_stResolveImage;
ELoadMode m_eLoadMode;
EStoreMode m_eStoreMode;
};
BEGIN_VULKAN_COMMAND(Begin)
CUtlVector<VulkanRenderOutput_t> images;
VulkanRenderOutput_t stDepthImage;
@@ -35,6 +25,36 @@ END_VULKAN_COMMAND(Begin)
BEGIN_VULKAN_COMMAND(End)
END_VULKAN_COMMAND(End)
BEGIN_VULKAN_COMMAND(SetVertexBuffer)
uint32_t uBinding;
IVertexBuffer *pBuffer;
END_VULKAN_COMMAND(SetVertexBuffer)
BEGIN_VULKAN_COMMAND(SetShader)
IShader *pShader;
END_VULKAN_COMMAND(SetShader)
BEGIN_VULKAN_COMMAND(DrawPrimitives)
uint32_t nVertexCount;
uint32_t nFirstVertex;
uint32_t nInstanceCount;
uint32_t nFirstInstance;
END_VULKAN_COMMAND(DrawPrimitives)
BEGIN_VULKAN_COMMAND(SetScissors)
uint32_t uX;
uint32_t uY;
uint32_t uWidth;
uint32_t uHeight;
END_VULKAN_COMMAND(SetScissors)
BEGIN_VULKAN_COMMAND(SetViewport)
uint32_t uX;
uint32_t uY;
uint32_t uWidth;
uint32_t uHeight;
END_VULKAN_COMMAND(SetViewport)
BEGIN_VULKAN_COMMAND(Empty)
END_VULKAN_COMMAND(Empty)

View File

@@ -31,10 +31,10 @@ DECLARE_VULKAN_COMMAND(ClearColor)
DECLARE_VULKAN_COMMAND(Begin)
{
VkRenderingInfo stRenderingInfo = {};
CUtlVector<VkRenderingAttachmentInfo> attachments;
CUtlVector<VkRenderingAttachmentInfo> attachments = {};
for (auto i: images)
{
VkRenderingAttachmentInfo a;
VkRenderingAttachmentInfo a = {};
a.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO;
a.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
a.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
@@ -47,6 +47,7 @@ DECLARE_VULKAN_COMMAND(Begin)
stRenderingInfo.layerCount = 1;
stRenderingInfo.colorAttachmentCount = attachments.GetSize();
stRenderingInfo.pColorAttachments = attachments.GetData();
stRenderingInfo.renderArea = (VkRect2D){0,0,nResolutionX,nResolutionY};
vkCmdBeginRendering(hCommandBuffer, &stRenderingInfo);
}
@@ -55,3 +56,21 @@ DECLARE_VULKAN_COMMAND(End)
{
vkCmdEndRendering(hCommandBuffer);
}
DECLARE_VULKAN_COMMAND(SetShader)
{
CVkShader *pVkShader = (CVkShader*)pShader;
vkCmdBindPipeline(hCommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pVkShader->m_hPipeline);
}
DECLARE_VULKAN_COMMAND(SetVertexBuffer)
{
CVkBuffer *pVkBuffer = (CVkBuffer*)pBuffer;
VkDeviceSize uOffset = 0;
vkCmdBindVertexBuffers(hCommandBuffer, uBinding, 1, &pVkBuffer->m_buffer, &uOffset);
}
DECLARE_VULKAN_COMMAND(DrawPrimitives)
{
vkCmdDraw(hCommandBuffer, nVertexCount, nInstanceCount, nFirstVertex, nFirstInstance);
}

View File

@@ -3,7 +3,8 @@
#include "tier1/utlbuffer.h"
#include "tier1/utlvector.h"
#include "tier2/ifilesystem.h"
#include "vulkan/vulkan_core.h"
#include "../shaderparser.h"
BEGIN_BUILD_PIPELINE_LIBRARY(VertexDescription)
library.flags = VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT;
@@ -48,3 +49,250 @@ void CVkVertexDescriptionPipelineLibrary::SetTopology( ETopologyMode eTopology )
{
m_eTopology = VulkanGetTopology(eTopology);
}
struct VulkanDescriptorInit_t
{
CUtlVector<VkDescriptorSetLayoutBinding> m_bindings = {};
VkDescriptorSetLayoutCreateInfo m_set = {};
};
BEGIN_BUILD_PIPELINE_LIBRARY(VertexTransform)
library.flags = VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT;
VkPipelineRasterizationStateCreateInfo rasterState = {};
VkPipelineViewportStateCreateInfo viewportState = {};
int i = 0;
CUtlVector<VulkanDescriptor_t> vertexDescriptors = ShaderParser()->GetDescriptors(m_pShader, SHADER_STAGE_VERTEX);
VulkanDescriptorInit_t inits[SHADER_STAGE_COUNT] = {};
CUtlVector<CUtlBuffer<unsigned char>> spirvs = {};
CUtlVector<VkPipelineShaderStageCreateInfo> stages = {};
CUtlVector<VkShaderModuleCreateInfo> stageShaders = {};
for ( auto desc: vertexDescriptors )
{
VkDescriptorSetLayoutBinding binding = {};
binding.descriptorCount = 1;
binding.descriptorType = desc.eDescriptorType;
binding.binding = desc.uBinding;
inits[desc.eDescriptorType].m_bindings.AppendTail(binding);
}
for ( i = 0; i < SHADER_STAGE_COUNT; i++)
{
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] );
}
for ( i = 0; i < SHADER_STAGE_COUNT; i++)
{
if ( i == SHADER_STAGE_PIXEL )
continue;
CUtlBuffer<unsigned char> code = ShaderParser()->GetShaderCode(m_pShader, (EShaderStage)i);
// We may fail loading the specific stage
if (code.GetSize() == 0)
continue;
VkShaderModuleCreateInfo mod = {};
mod.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
mod.codeSize = code.GetSize();
VkPipelineShaderStageCreateInfo shader = {};
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);
}
// Fix pointers
for ( i = 0; i < stages.GetSize(); i++ )
{
stageShaders[i].pCode = (uint32_t*)spirvs[i].GetMemory();
stages[i].pNext = &stageShaders[i];
}
VkPipelineLayoutCreateInfo stPipelineLayout = {};
stPipelineLayout.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
stPipelineLayout.setLayoutCount = SHADER_STAGE_COUNT;
stPipelineLayout.pSetLayouts = m_setLayouts;
stPipelineLayout.flags = VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT ;
vkCreatePipelineLayout(g_vkDevice, &stPipelineLayout, NULL, &m_layout);
rasterState.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
rasterState.polygonMode = VK_POLYGON_MODE_FILL;
rasterState.lineWidth = 1;
viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
VkDynamicState dynamicStates[] = {
VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT,
VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT,
};
VkPipelineDynamicStateCreateInfo dynamicState = {};
dynamicState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
dynamicState.dynamicStateCount = 2;
dynamicState.pDynamicStates = dynamicStates;
pipeline.stageCount = stages.GetSize();
pipeline.pStages = stages.GetData();
pipeline.pDynamicState = &dynamicState;
pipeline.pRasterizationState = &rasterState;
pipeline.pViewportState = &viewportState;
pipeline.layout = m_layout;
END_BUILD_PIPELINE_LIBRARY()
void CVkVertexTransformPipelineLibrary::SetShader( CCompiledShader *pShader )
{
m_pShader = pShader;
}
BEGIN_BUILD_PIPELINE_LIBRARY(PixelShader)
printf("--- PixelShader ---\n");
VkPipelineDepthStencilStateCreateInfo depthStencil = {};
int i = 0;
CUtlVector<VulkanDescriptor_t> vertexDescriptors = ShaderParser()->GetDescriptors(m_pShader, SHADER_STAGE_PIXEL);
VulkanDescriptorInit_t inits[SHADER_STAGE_COUNT] = {};
for ( auto desc: vertexDescriptors )
{
VkDescriptorSetLayoutBinding binding = {};
binding.descriptorCount = 1;
binding.descriptorType = desc.eDescriptorType;
binding.binding = desc.uBinding;
inits[desc.eDescriptorType].m_bindings.AppendTail(binding);
}
for ( i = 0; i < SHADER_STAGE_COUNT; i++)
{
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] );
}
VkPipelineLayoutCreateInfo stPipelineLayout = {};
stPipelineLayout.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
stPipelineLayout.setLayoutCount = SHADER_STAGE_COUNT;
stPipelineLayout.pSetLayouts = m_setLayouts;
stPipelineLayout.flags = VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT ;
vkCreatePipelineLayout(g_vkDevice, &stPipelineLayout, NULL, &m_layout);
CUtlBuffer<unsigned char> spirv = {};
VkPipelineShaderStageCreateInfo shader = {};
VkShaderModuleCreateInfo mod = {};
for ( auto desc: vertexDescriptors )
{
VkDescriptorSetLayoutBinding binding = {};
binding.descriptorCount = 1;
binding.descriptorType = desc.eDescriptorType;
binding.binding = desc.uBinding;
inits[desc.eDescriptorType].m_bindings.AppendTail(binding);
}
for ( i = 0; i < SHADER_STAGE_COUNT; i++)
{
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] );
}
spirv = ShaderParser()->GetShaderCode(m_pShader, SHADER_STAGE_PIXEL);
if (spirv.GetSize() == 0)
goto skipshader;
mod.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
mod.codeSize = spirv.GetSize();
mod.pCode = (uint32_t*)spirv.GetMemory();
shader.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
shader.pName = "main";
shader.stage = VulkanGetShaderStage(SHADER_STAGE_PIXEL);
shader.pNext = &mod;
pipeline.stageCount = 1;
pipeline.pStages = &shader;
depthStencil.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
depthStencil.minDepthBounds = 0;
depthStencil.maxDepthBounds = 1;
depthStencil.depthTestEnable = VK_TRUE;
depthStencil.depthWriteEnable = VK_TRUE;
depthStencil.depthBoundsTestEnable = VK_FALSE;
depthStencil.stencilTestEnable = VK_FALSE;
depthStencil.depthCompareOp = VK_COMPARE_OP_LESS;
pipeline.pDepthStencilState = &depthStencil;
skipshader:
library.flags = VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT;
pipeline.layout = m_layout;
END_BUILD_PIPELINE_LIBRARY()
void CVkPixelShaderPipelineLibrary::SetShader( CCompiledShader *pShader )
{
m_pShader = pShader;
}
BEGIN_BUILD_PIPELINE_LIBRARY(PixelOutput)
printf("--- PixelOutput ---\n");
VkPipelineMultisampleStateCreateInfo msaa = {};
VkPipelineRenderingCreateInfo render = {};
VkPipelineDepthStencilStateCreateInfo depthStencil = {};
VkPipelineColorBlendStateCreateInfo blend = {};
CUtlVector<VkPipelineColorBlendAttachmentState> attachments = {};
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.colorAttachmentCount = m_eFormats.GetSize();
render.pColorAttachmentFormats = m_eFormats.GetData();
render.depthAttachmentFormat = VK_FORMAT_D32_SFLOAT;;
depthStencil.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
depthStencil.minDepthBounds = 0;
depthStencil.maxDepthBounds = 1;
depthStencil.depthTestEnable = VK_TRUE;
depthStencil.depthWriteEnable = VK_TRUE;
depthStencil.depthBoundsTestEnable = VK_FALSE;
depthStencil.stencilTestEnable = VK_FALSE;
depthStencil.depthCompareOp = VK_COMPARE_OP_LESS;
for ( auto e: m_eFormats )
{
VkPipelineColorBlendAttachmentState a = {};
a.blendEnable = VK_TRUE;
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;
attachments.AppendTail(a);
}
blend.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
blend.attachmentCount = m_eFormats.GetSize();
blend.pAttachments = attachments.GetData();
pipeline.pDepthStencilState = &depthStencil;
pipeline.pColorBlendState = &blend;
pipeline.pMultisampleState = &msaa;
render.pNext = pipeline.pNext;
pipeline.pNext = &render;
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));
}

View File

@@ -0,0 +1,36 @@
#include "vulkan_state.h"
CVkMaterial::CVkMaterial( IShader *pShader )
{
m_pVkShader = (CVkShader*)pShader;
}
CVkMaterial::~CVkMaterial()
{
}
void CVkMaterial::VSSetShaderResource( uint32_t uRegister, IRenderingObject *pResource )
{
SetShaderResource(uRegister, SHADER_STAGE_VERTEX, pResource);
}
void CVkMaterial::PSSetShaderResource( uint32_t uRegister, IRenderingObject *pResource )
{
SetShaderResource(uRegister, SHADER_STAGE_PIXEL, pResource);
}
void CVkMaterial::VSSetConstantsBuffer( uint32_t uRegister, IBuffer *pConstants )
{
SetShaderResource(uRegister, SHADER_STAGE_VERTEX, pConstants);
}
void CVkMaterial::PSSetConstantsBuffer( uint32_t uRegister, IBuffer *pConstants )
{
SetShaderResource(uRegister, SHADER_STAGE_PIXEL, pConstants);
}
void CVkMaterial::SetShaderResource( uint32_t uRegister, uint32_t uSet, IRenderingObject *pObject)
{
}

View File

@@ -1,4 +1,5 @@
#include "materialsystem/imaterialsystem.h"
#include "materialsystem/compiledshadermgr.h"
#include "tier1/utlvector.h"
#include "vulkan_state.h"
@@ -13,11 +14,28 @@ BEGIN_DEFINE_PIPELINE_LIBRARY(VertexDescription)
END_DEFINE_PIPELINE_LIBRARY()
BEGIN_DEFINE_PIPELINE_LIBRARY(VertexTransform)
void SetShader( CCompiledShader *pShader );
CCompiledShader *m_pShader;
VkDescriptorSetLayout m_setLayouts[SHADER_STAGE_COUNT];
VkPipelineLayout m_layout;
END_DEFINE_PIPELINE_LIBRARY()
BEGIN_DEFINE_PIPELINE_LIBRARY(PixelShade)
BEGIN_DEFINE_PIPELINE_LIBRARY(PixelShader)
void SetShader( CCompiledShader *pShader );
void SetDepthRequired( bool b );
CCompiledShader *m_pShader;
VkDescriptorSetLayout m_setLayouts[SHADER_STAGE_COUNT];
VkPipelineLayout m_layout;
bool m_bIsDepthRequired = false;
END_DEFINE_PIPELINE_LIBRARY()
BEGIN_DEFINE_PIPELINE_LIBRARY(PixelOutput)
void AddAttachment( EImageFormat eFormat );
void SetDepthRequired( bool b );
CUtlVector<VkFormat> m_eFormats = {};
bool m_bIsDepthRequired = false;
END_DEFINE_PIPELINE_LIBRARY()

View File

@@ -0,0 +1,193 @@
#include "vulkan_state.h"
#include "commands.h"
void CVkRenderCommandList::ResetRendering()
{
/*
for ( auto m: m_materials)
{
delete m.m_pCommandBuffer;
}
*/
m_materials = {};
}
void CVkRenderCommandList::SetRenderTarget( uint32_t uIndex, IImage *pImage )
{
SwitchRenderingStage(RENDERING_STAGE_SETUP_RASTER);
VulkanRenderOutput_t *pOutput = FindOrCreateRenderOutput(uIndex);
pOutput->m_stImage.m_pSingle = pImage;
}
void CVkRenderCommandList::SetClearColor( uint32_t uIndex, float r, float g, float b, float a )
{
SwitchRenderingStage(RENDERING_STAGE_SETUP_RASTER);
VulkanRenderOutput_t *pOutput = FindOrCreateRenderOutput(uIndex);
pOutput->m_fClearColor[0] = r;
pOutput->m_fClearColor[1] = g;
pOutput->m_fClearColor[2] = b;
pOutput->m_fClearColor[3] = a;
}
void CVkRenderCommandList::SetDepthTarget( IImage *pDepth )
{
SwitchRenderingStage(RENDERING_STAGE_SETUP_RASTER);
m_depth.m_stImage.m_pSingle = pDepth;
}
void CVkRenderCommandList::SetClearDepth( float fVal)
{
SwitchRenderingStage(RENDERING_STAGE_SETUP_RASTER);
m_depth.m_fClearDepth = fVal;
}
void CVkRenderCommandList::SetRenderResolution( uint32_t iWidth, uint32_t iHeight )
{
SwitchRenderingStage(RENDERING_STAGE_SETUP_RASTER);
}
void CVkRenderCommandList::SetScissors( uint32_t uX, uint32_t uY, uint32_t uWidth, uint32_t uHeight )
{
SwitchRenderingStage(RENDERING_STAGE_RASTER);
}
void CVkRenderCommandList::SetViewport( uint32_t uX, uint32_t uY, uint32_t uWidth, uint32_t uHeight, float fMinDepth, float fMaxDepth )
{
SwitchRenderingStage(RENDERING_STAGE_RASTER);
}
void CVkRenderCommandList::SetMaterial( IMaterial *pMaterial )
{
SwitchRenderingStage(RENDERING_STAGE_SETUP_RASTER);
bool bWasCreated = false;
m_pCurrentMaterialBuffer = FindOrCreateMaterialCommandBuffer(pMaterial, &bWasCreated);
if (bWasCreated)
{
m_pCurrentMaterialBuffer->Reset();
CVkBeginCommand *pBeginCommand = CREATE_COMMAND(Begin);
pBeginCommand->images = m_pOutput;
pBeginCommand->nResolutionX = 1280;
pBeginCommand->nResolutionY = 720;
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);
CVkSetViewportCommand *pViewportCommand = CREATE_COMMAND(SetViewport);
}
}
void CVkRenderCommandList::SetVertexBuffer( uint32_t uBinding, IVertexBuffer *pBuffer )
{
SwitchRenderingStage(RENDERING_STAGE_RASTER);
CVkSetVertexBufferCommand *pCmd = CREATE_COMMAND(SetVertexBuffer);
pCmd->uBinding = uBinding;
pCmd->pBuffer = pBuffer;
m_pCurrentMaterialBuffer->AddCommand(pCmd);
}
void CVkRenderCommandList::SetIndexBuffer( IVertexBuffer *pBuffer )
{
SwitchRenderingStage(RENDERING_STAGE_RASTER);
}
void CVkRenderCommandList::DrawPrimitives( uint32_t nVertexCount, uint32_t nFirstVertex, uint32_t nInstanceCount, uint32_t nFirstInstance )
{
SwitchRenderingStage(RENDERING_STAGE_RASTER);
CVkDrawPrimitivesCommand *pCmd = CREATE_COMMAND(DrawPrimitives);
pCmd->nVertexCount = nVertexCount;
pCmd->nFirstVertex = nFirstVertex;
pCmd->nInstanceCount = nInstanceCount;
pCmd->nFirstInstance = nFirstInstance;
m_pCurrentMaterialBuffer->AddCommand(pCmd);
}
void CVkRenderCommandList::DrawPrimitivesIndexed( uint32_t nIndexCount, uint32_t nFirstIndex, uint32_t nVertexOffset, uint32_t nInstanceCount, uint32_t nFirstInstance )
{
SwitchRenderingStage(RENDERING_STAGE_RASTER);
}
void CVkRenderCommandList::ResolveImage( IImage *pOriginal, IImage *pResolved )
{
SwitchRenderingStage(RENDERING_STAGE_POST_RASTER);
}
void CVkRenderCommandList::StartRecording()
{
ResetRendering();
}
void CVkRenderCommandList::EndRecording()
{
for ( auto m: m_materials)
{
CVkEndCommand *pEndCommand = CREATE_COMMAND(End);
m.m_pCommandBuffer->AddCommand(pEndCommand);
m.m_pCommandBuffer->Render();
}
}
void CVkRenderCommandList::Submit()
{
for ( auto m: m_materials)
{
m.m_pCommandBuffer->Submit();
}
}
void CVkRenderCommandList::SwitchRenderingStage( EVulkanRenderingStage eStage )
{
}
VulkanRenderOutput_t *CVkRenderCommandList::FindOrCreateRenderOutput( uint32_t uIndex )
{
for ( auto &v: m_pOutput )
{
if (v.m_uIndex == uIndex)
return &v;
}
VulkanRenderOutput_t output = {};
output.m_uIndex = uIndex;
m_pOutput.AppendTail(output);
return &m_pOutput[m_pOutput.GetSize()-1];
}
IVkCommandBuffer *CVkRenderCommandList::FindOrCreateMaterialCommandBuffer( IMaterial *pMaterial, bool *pbWasCreated )
{
for (auto &m: m_materials)
{
if (m.m_pMaterial == pMaterial)
{
if (pbWasCreated)
*pbWasCreated = false;
return m.m_pCommandBuffer;
}
}
VulkanMaterialCommandBuffer_t mat;
mat.m_pCommandBuffer = g_pCommandBufferManager->CreateCommandBuffer();
mat.m_pMaterial = pMaterial;
m_materials.AppendTail(mat);
if (pbWasCreated)
*pbWasCreated = true;
return m_materials.GetLast().m_pCommandBuffer;
}

View File

@@ -31,17 +31,18 @@ VkQueue g_vkDrawQueue;
VkQueue g_vkPresentQueue;
VkInstance g_vkInstance;
VmaAllocator g_vkAllocator;
VkPhysicalDevice g_vkPhysicalDevice;
VkDevice g_vkDevice;
VkSwapchainKHR g_vkSwapchain;
CUtlVector<VkFence> g_vkFences;
CUtlVector<VkSemaphore> g_vkGraphicsSemaphores;
CUtlVector<VkSemaphore> g_vkPresentSemaphores;
CUtlVector<VkFence> g_vkFences = {};
CUtlVector<VkSemaphore> g_vkGraphicsSemaphores = {};
CUtlVector<VkSemaphore> g_vkPresentSemaphores = {};
CUtlVector<VkCommandPool> g_vkCommandPools;
CUtlVector<VkCommandPool> g_vkCommandPools = {};
CUtlVector<IImage*> g_vkSwapchainImages;
CUtlVector<IImage*> g_vkSwapchainImages = {};
VkFormat g_vkWindowImageFormat;
@@ -50,9 +51,14 @@ CVkImage::CVkImage()
}
CVkImage::CVkImage( uint32_t nWidth, uint32_t nHeight, EImageFormat eFormat, EMultisampleType eMultisampleType)
CVkImage::CVkImage( uint32_t nWidth, uint32_t nHeight, uint32_t nDepth, EImageFormat eFormat, EMultisampleType eMultisampleType, EImageType eImageType, VkImageUsageFlagBits eUsage )
{
CreateImage(nWidth, nHeight, eFormat, eMultisampleType);
m_nWidth = nWidth;
m_nHeight = nHeight;
m_eMultisampleType = eMultisampleType;
m_eImageType = eImageType;
m_eFormat = eFormat;
CreateImage(nWidth, nHeight, eFormat, eMultisampleType, eUsage);
CreateImageView();
}
@@ -107,9 +113,26 @@ VkFormat CVkImage::GetImageFormat( enum EImageFormat eImageFormat )
}
}
void CVkImage::CreateImage( uint32_t nWidth, uint32_t nHeight, EImageFormat eFormat, EMultisampleType eMultisampleType )
void CVkImage::CreateImage( uint32_t nWidth, uint32_t nHeight, EImageFormat eFormat, EMultisampleType eMultisampleType, VkImageUsageFlagBits eUsage )
{
VkImageCreateInfo stCreateInfo = {};
VmaAllocationCreateInfo stAlloc = {};
stCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
stCreateInfo.imageType = VK_IMAGE_TYPE_2D;
stCreateInfo.extent.width = nWidth;
stCreateInfo.extent.height = nHeight;
stCreateInfo.extent.depth = 1;
stCreateInfo.mipLevels = 1;
stCreateInfo.arrayLayers = 1;
stCreateInfo.usage = eUsage;
stCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
stCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
stCreateInfo.format = GetImageFormat(eFormat);
stCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
stAlloc.usage = VMA_MEMORY_USAGE_AUTO;
vmaCreateImage(g_vkAllocator, &stCreateInfo, &stAlloc, &m_image, &m_allocation, NULL);
}
void CVkImage::CreateImageView()
@@ -159,6 +182,28 @@ EMultisampleType CVkImage::GetMultisampleType()
CVkBuffer::CVkBuffer( uint32_t nSize, VkBufferUsageFlags2 eUsage, uint32_t nAlignment )
{
VkBufferUsageFlags2CreateInfo stUsage = {};
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;
stBufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
stBufferInfo.size = nSize;
stBufferInfo.pNext = &stUsage;
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);
stAddress.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO;
stAddress.buffer = m_buffer;
m_address = vkGetBufferDeviceAddress(g_vkDevice, &stAddress);
m_nSize = nSize;
}
CVkBuffer::~CVkBuffer()
@@ -169,12 +214,10 @@ CVkBuffer::~CVkBuffer()
void CVkBuffer::SetDebugName( const char *szName )
{
}
void CVkBuffer::Lock()
{
}
void CVkBuffer::Unlock()
@@ -184,21 +227,22 @@ void CVkBuffer::Unlock()
void *CVkBuffer::Map()
{
void *pData;
pData = NULL;
vmaMapMemory(g_vkAllocator, m_allocation, &pData);
return pData;
}
void CVkBuffer::Unmap()
{
vmaUnmapMemory(g_vkAllocator, m_allocation);
}
uint32_t CVkBuffer::GetSize()
{
return m_nSize;
}
class CVkRenderContext: public IRenderContext
{
public:
@@ -206,8 +250,17 @@ public:
virtual void Frame( float fDeltaTime ) override;
virtual void Shutdown() override;
virtual void SetOutputImage( IImage *pImage ) override;
virtual bool BIsOutputImageOutdated() override;
virtual uint32_t GetNewOutputImageWidth() override;
virtual uint32_t GetNewOutputImageHeight() override;
virtual EImageFormat GetNewOutputImageFormat() 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;
@@ -218,16 +271,14 @@ public:
IBuffer *CreateBufferAligned( uint32_t nSize, uint32_t nAlignment, VkBufferUsageFlags2 eUsage );
virtual IShader *CreateShader( const char *szName ) override;
virtual void DestroyShader( IShader *pMaterial ) override;
virtual void DestroyShader( IShader *pShader ) override;
virtual IMaterial *CreateMaterial( IShader *pShader ) override;
virtual void DestroyMaterial( IMaterial *pMaterial ) override;
virtual void SetMaterial( IMaterial *pMaterial ) override;
virtual void SetVertexBuffer( IVertexBuffer *pBuffer ) override;
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 IRenderCommandList *CreateCommandList() override;
virtual void DestroyCommandList( IRenderCommandList *pCommandList ) override;
virtual void SubmitCommandList(IRenderCommandList *pList) override;
private:
VkPhysicalDevice SelectPhysicalDevice( CUtlVector<VkPhysicalDevice> physicalDevices );
CUtlVector<const char *> GetDeviceExtensions();
@@ -236,17 +287,45 @@ private:
void CreateSwapchain();
void DestroySwapchain();
};
CVkRenderContext s_vkRenderContext;
IRenderContext *g_pVkRenderContext = &s_vkRenderContext;
IImage *m_pOutputImage = NULL;
bool m_bOutputImageOutdated = true;
};
EXPOSE_INTERFACE(CVkRenderContext, IRenderContext, RENDER_CONTEXT_VULKAN_INTERFACE_NAME);
void CVkRenderContext::SetOutputImage( IImage *pImage )
{
m_pOutputImage = pImage;
}
bool CVkRenderContext::BIsOutputImageOutdated( )
{
return m_bOutputImageOutdated;
}
uint32_t CVkRenderContext::GetNewOutputImageWidth()
{
return 1280;
}
uint32_t CVkRenderContext::GetNewOutputImageHeight()
{
return 720;
}
EImageFormat CVkRenderContext::GetNewOutputImageFormat()
{
}
//-----------------------------------------------------------------------------
// Creates vertex buffer. Wrapper over CreateBuffer
//-----------------------------------------------------------------------------
IVertexBuffer *CVkRenderContext::CreateVertexBuffer( uint32_t nSize )
{
return (IVertexBuffer*)CreateBuffer(nSize, VK_BUFFER_USAGE_2_VERTEX_BUFFER_BIT);
return (IVertexBuffer*)CreateBuffer(nSize, VK_BUFFER_USAGE_2_VERTEX_BUFFER_BIT |VK_BUFFER_USAGE_2_STORAGE_BUFFER_BIT );
}
//-----------------------------------------------------------------------------
@@ -254,13 +333,28 @@ IVertexBuffer *CVkRenderContext::CreateVertexBuffer( uint32_t nSize )
//-----------------------------------------------------------------------------
IIndexBuffer *CVkRenderContext::CreateIndexBuffer( uint32_t nSize )
{
return (IIndexBuffer*)CreateBuffer(nSize, VK_BUFFER_USAGE_2_INDEX_BUFFER_BIT);
return (IIndexBuffer*)CreateBuffer(nSize, VK_BUFFER_USAGE_2_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_2_STORAGE_BUFFER_BIT);
}
//-----------------------------------------------------------------------------
// Creates storage buffer. Wrapper over CreateBuffer
//-----------------------------------------------------------------------------
IBuffer *CVkRenderContext::CreateStorageBuffer( uint32_t nSize )
{
return (IVertexBuffer*)CreateBuffer(nSize, VK_BUFFER_USAGE_2_STORAGE_BUFFER_BIT);
}
//-----------------------------------------------------------------------------
// Creates constant buffer. Wrapper over CreateBuffer
//-----------------------------------------------------------------------------
IBuffer *CVkRenderContext::CreateConstantBuffer( uint32_t nSize )
{
return (IIndexBuffer*)CreateBuffer(nSize, VK_BUFFER_USAGE_2_UNIFORM_BUFFER_BIT);
}
//-----------------------------------------------------------------------------
// Creates basic vulkan buffer
//-----------------------------------------------------------------------------
IBuffer *CreateBuffer( uint32_t nSize, VkBufferUsageFlags2 eUsage )
IBuffer *CVkRenderContext::CreateBuffer( uint32_t nSize, VkBufferUsageFlags2 eUsage )
{
CVkBuffer *pBuffer = new CVkBuffer(nSize, eUsage, 0);
return pBuffer;
@@ -271,7 +365,7 @@ IBuffer *CreateBuffer( uint32_t nSize, VkBufferUsageFlags2 eUsage )
// Useful for everything eg: ray tracing, which requires them to be aligned
// to the groupBaseAlignment.
//-----------------------------------------------------------------------------
IBuffer *CreateBufferAligned( uint32_t nSize, uint32_t nAlignment, VkBufferUsageFlags2 eUsage )
IBuffer *CVkRenderContext::CreateBufferAligned( uint32_t nSize, uint32_t nAlignment, VkBufferUsageFlags2 eUsage )
{
}
@@ -279,12 +373,15 @@ IBuffer *CreateBufferAligned( uint32_t nSize, uint32_t nAlignment, VkBufferUsage
IImage *CVkRenderContext::CreateRenderTarget( uint32_t x, uint32_t y, EImageFormat eFormat, EMultisampleType eMultisampleType )
{
if (eFormat == IMAGE_FORMAT_D32_SFLOAT)
return new CVkImage(x, y, 1, eFormat, eMultisampleType, IMAGE_TYPE_2D, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
else
return new CVkImage(x, y, 1, eFormat, eMultisampleType, IMAGE_TYPE_2D, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
}
IImage *CVkRenderContext::CreateStorageImage( uint32_t x, uint32_t y, EImageFormat eFormat, EMultisampleType eMultisampleType )
{
return new CVkImage(x, y, 1, eFormat, eMultisampleType, IMAGE_TYPE_2D, VK_IMAGE_USAGE_STORAGE_BIT);
}
@@ -300,49 +397,69 @@ 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);
printf("--- general pipeline ---\n");
pShader->Build();
return pShader;
}
void CVkRenderContext::DestroyShader( IShader *pMaterial )
void CVkRenderContext::DestroyShader( IShader *pShader )
{
delete pShader;
}
IMaterial *CVkRenderContext::CreateMaterial( IShader *pShader )
{
return new CVkMaterial(pShader);
}
void CVkRenderContext::DestroyMaterial( IMaterial *pMaterial )
{
delete pMaterial;
}
void CVkRenderContext::SetMaterial( IMaterial *pMaterial )
IRenderCommandList *CVkRenderContext::CreateCommandList()
{
return new CVkRenderCommandList;
}
void CVkRenderContext::DestroyCommandList( IRenderCommandList *pCommandList )
{
}
void CVkRenderContext::SetVertexBuffer( IVertexBuffer *pBuffer )
void CVkRenderContext::SubmitCommandList(IRenderCommandList *pList)
{
CVkRenderCommandList *pVkList = (CVkRenderCommandList*)pList;
pVkList->Submit();
}
void CVkRenderContext::SetIndexBuffer( IVertexBuffer *pBuffer )
{
}
void CVkRenderContext::DrawPrimitives( uint32_t nVertexCount, uint32_t nFirstVertex, uint32_t nInstanceCount, uint32_t nFirstInstance )
{
}
void CVkRenderContext::DrawPrimitivesIndexed( uint32_t nIndexCount, uint32_t nFirstIndex, uint32_t nVertexOffset, uint32_t nInstanceCount, uint32_t nFirstInstance )
{
}
IVkCommandBuffer *pCommandBuffer;
VkPipelineLayout g_pLibraryEmptyLayout;
static IVkCommandBuffer *s_pPresentCommandBuffer;
void CVkRenderContext::Init()
{
@@ -436,21 +553,48 @@ void CVkRenderContext::Init()
VkPhysicalDeviceVulkan13Features vk13Features = {};
vk13Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES;
vk13Features.synchronization2 = VK_TRUE;
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;
vk12Features.bufferDeviceAddress = VK_TRUE;
stDeviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
stDeviceCreateInfo.queueCreateInfoCount = 1;
stDeviceCreateInfo.pQueueCreateInfos = &stDeviceQueueCreateInfo;
stDeviceCreateInfo.enabledExtensionCount = enabledDeviceExtensions.GetSize();
stDeviceCreateInfo.ppEnabledExtensionNames = enabledDeviceExtensions.GetData();
stDeviceCreateInfo.pNext = &vk13Features;
stDeviceCreateInfo.pNext = &vk12Features;
r = vkCreateDevice(g_vkPhysicalDevice, &stDeviceCreateInfo, NULL, &g_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);
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;
VmaVulkanFunctions vulkanFunctions;
vmaImportVulkanFunctionsFromVolk(&stAllocatorInfo, &vulkanFunctions);
stAllocatorInfo.pVulkanFunctions = &vulkanFunctions;
vmaCreateAllocator(&stAllocatorInfo, &g_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);
CreateSwapchain();
@@ -468,37 +612,12 @@ void CVkRenderContext::Init()
g_pCommandBufferManager = (IVkCommandBufferManager*)CreateInterface(VULKAN_COMMAND_BUFFER_MANAGER_INTERFACE_NAME, NULL);
g_pCommandBufferManager->Init();
pCommandBuffer = g_pCommandBufferManager->CreateCommandBuffer();
s_pPresentCommandBuffer = g_pCommandBufferManager->CreateCommandBuffer();
CVkClearColorCommand *pCommand = (CVkClearColorCommand*)g_pCommandBufferManager->CreateCommand("ClearColor");
pCommand->pImage = NULL;
pCommand->ppSwapchainImages = g_vkSwapchainImages.GetData();
pCommand->r = 1;
pCommand->b = 1;
pCommand->g = 0;
pCommand->AddSwapchainDependency( (IRenderingObject**)g_vkSwapchainImages.GetData(), DEPENDENCY_MODE_COLOR_CLEAR_DESTINATION );
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 = {};
CVkEmptyCommand *pPresentCommand = (CVkEmptyCommand*)g_pCommandBufferManager->CreateCommand("Empty");
pPresentCommand->AddSwapchainDependency( (IRenderingObject**)g_vkSwapchainImages.GetData(), DEPENDENCY_MODE_IMAGE_PRESENT );
CVkBeginCommand *pBeginCommand = (CVkBeginCommand*)g_pCommandBufferManager->CreateCommand("Empty");
pBeginCommand->AddSwapchainDependency((IRenderingObject**)g_vkSwapchainImages.GetData(), DEPENDENCY_MODE_DRAWCALL_OUTPUT_IMAGE);
CVkBeginCommand *pEndCommand = (CVkBeginCommand*)g_pCommandBufferManager->CreateCommand("Empty");
pCommandBuffer->Reset();
pCommandBuffer->AddCommand(pCommand);
pCommandBuffer->Render();
s_pPresentCommandBuffer = g_pCommandBufferManager->CreateCommandBuffer();
s_pPresentCommandBuffer->Reset();
s_pPresentCommandBuffer->AddCommand(pPresentCommand);
s_pPresentCommandBuffer->Render();
@@ -507,8 +626,7 @@ void CVkRenderContext::Init()
void CVkRenderContext::Frame( float fDeltaTime )
{
vkDeviceWaitIdle(g_vkDevice);
pCommandBuffer->Render();
s_pPresentCommandBuffer->Render();
m_bOutputImageOutdated = false;
static uint32_t s_nImageIndex = 0;
uint32_t nImageIndex = 0;
@@ -518,9 +636,7 @@ void CVkRenderContext::Frame( float fDeltaTime )
vkResetFences(g_vkDevice, 1, &g_vkFences[s_nImageIndex]);
g_vkCommandBuffers = {};
pCommandBuffer->Submit(nImageIndex);
s_pPresentCommandBuffer->Submit(nImageIndex);
VkPipelineStageFlags uPipelineStageFlags = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
@@ -550,6 +666,7 @@ void CVkRenderContext::Frame( float fDeltaTime )
vkQueuePresentKHR(g_vkPresentQueue, &stPresentInfo);
s_nImageIndex = (s_nImageIndex + 1) % g_vkSwapchainImages.GetSize();
g_vkCommandBuffers = {};
}
void CVkRenderContext::CreateSwapchain()

View File

@@ -1,3 +1,39 @@
#include "vulkan_state.h"
void CVkShader::AddShaderLibrary( CVkPipelineLibrary *pLibrary )
{
m_libraries.AppendTail(pLibrary);
}
void CVkShader::Build()
{
CUtlVector<VkPipeline> libs = {};
VkGraphicsPipelineCreateInfo createInfo = {};
VkPipelineLibraryCreateInfoKHR libInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
for ( auto l: m_libraries )
{
libs.AppendTail(l->m_hPipeline);
};
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;
// Possibly schedule it?
vkCreateGraphicsPipelines(g_vkDevice, NULL, 1, &createInfo, NULL, &m_hPipeline);
}
uint32_t CVkShader::PSGetResourceByName( const char *szName )
{
}
uint32_t CVkShader::VSGetResourceByName( const char *szName )
{
}

View File

@@ -0,0 +1,28 @@
#include "shaderparser.h"
CUtlVector<VulkanDescriptor_t> CVkShaderParser::GetDescriptors( CCompiledShader *pShader, EShaderStage eStage )
{
CUtlVector<VulkanDescriptor_t> descriptors = {};
return descriptors;
};
CUtlBuffer<unsigned char> CVkShaderParser::GetShaderCode( CCompiledShader *pShader, EShaderStage eStage )
{
for ( auto &o: pShader->m_objects )
{
if (o.m_eStage != eStage)
continue;
CUtlBuffer<unsigned char> code = CUtlBuffer<unsigned char>(pShader->GetLumpSize(o.m_nDataLump));
V_memcpy(code, pShader->GetLumpPtr(o.m_nDataLump), code.GetSize());
return code;
}
return NULL;
};
CVkShaderParser *ShaderParser()
{
static CVkShaderParser s_shaderParser = CVkShaderParser();
return &s_shaderParser;
};

View File

@@ -0,0 +1,17 @@
#ifndef VULKAN_SHADER_PARSER_H
#define VULKAN_SHADER_PARSER_H
#include "materialsystem/vulkan_shadermeta.h"
#include "materialsystem/compiledshadermgr.h"
#include "tier1/utlvector.h"
class CVkShaderParser
{
public:
CUtlVector<VulkanDescriptor_t> GetDescriptors( CCompiledShader *pShader, EShaderStage eStage );
CUtlBuffer<unsigned char> GetShaderCode( CCompiledShader *pShader, EShaderStage eStage );
};
CVkShaderParser *ShaderParser();
#endif

View File

@@ -22,7 +22,7 @@ VkAccessFlags2 VulkanGetAccessFlags( EDependencyMode eMode )
case DEPENDENCY_MODE_COLOR_CLEAR_DESTINATION: return VK_ACCESS_2_TRANSFER_WRITE_BIT;
case DEPENDENCY_MODE_IMAGE_PRESENT: return VK_ACCESS_2_NONE;
default:
return 0;
return VK_ACCESS_2_MEMORY_READ_BIT | VK_ACCESS_2_MEMORY_WRITE_BIT;
}
}
@@ -73,3 +73,14 @@ VkPrimitiveTopology VulkanGetTopology( ETopologyMode eMode )
case TOPOLOGY_MODE_TRIANGLE_STRIP: return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
}
}
VkShaderStageFlagBits VulkanGetShaderStage( EShaderStage eStage )
{
switch (eStage)
{
case SHADER_STAGE_VERTEX: return VK_SHADER_STAGE_VERTEX_BIT;
case SHADER_STAGE_PIXEL: return VK_SHADER_STAGE_FRAGMENT_BIT;
default:
break;
}
return VK_SHADER_STAGE_VERTEX_BIT;
}

View File

@@ -0,0 +1,6 @@
#define VMA_VULKAN_VERSION 1004000
#define VMA_IMPLEMENTATION
#define VMA_DYNAMIC_VULKAN_FUNCTIONS 0
#define VMA_STATIC_VULKAN_FUNCTIONS 0
#include "volk.h"
#include "vk_mem_alloc.h"

View File

@@ -8,6 +8,7 @@
#include "tier1/utlvector.h"
#include "tier2/iappsystem.h"
#include "materialsystem/imaterialsystem.h"
#include "materialsystem/shaderinternals.h"
#include "vulkan/vulkan_core.h"
#define REQUIRED_EXTENSION(ext) bool bIsSupported_##ext;
@@ -26,6 +27,7 @@ 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;
@@ -115,7 +117,7 @@ public:
virtual void AddCommand( CVkCommand *pCommand ) = 0;
virtual void Reset() = 0;
virtual void Submit( int iFrameIndex ) = 0;
virtual void Submit( int iFrameIndex = 0 ) = 0;
virtual void Render() = 0;
};
@@ -135,6 +137,8 @@ class CVkCommandRegistry
public:
CVkCommandRegistry( const char *szName, fnCreateVulkanCommand_t pfnCreate );
};
#define CREATE_COMMAND(name) \
(CVk##name##Command*)g_pCommandBufferManager->CreateCommand(#name)
#define BEGIN_VULKAN_COMMAND( name ) \
class CVk##name##Command : public CVkCommand \
@@ -162,7 +166,7 @@ class CVkImage: public IImage
{
public:
CVkImage();
CVkImage( uint32_t nWidth, uint32_t nHeight, EImageFormat eFormat, EMultisampleType eMultisampleType );
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;
@@ -171,7 +175,7 @@ public:
virtual EImageFormat GetImageFormat() override;
virtual EMultisampleType GetMultisampleType() override;
void CreateImage( uint32_t nWidth, uint32_t nHeight, EImageFormat eFormat, EMultisampleType eMultisampleType );
void CreateImage( uint32_t nWidth, uint32_t nHeight, EImageFormat eFormat, EMultisampleType eMultisampleType, VkImageUsageFlagBits eUsage );
void CreateImageView();
static VkImageViewType GetImageViewType( enum EImageType eImageType );
@@ -205,10 +209,10 @@ public:
virtual void Unmap() override;
virtual uint32_t GetSize() override;
VmaAllocation allocation;
VkBuffer buffer;
VkDeviceAddress address;
uint32_t nSize;
VmaAllocation m_allocation;
VkBuffer m_buffer;
VkDeviceAddress m_address;
uint32_t m_nSize;
};
class CVkPipelineLibrary
@@ -228,6 +232,7 @@ public: \
#define END_DEFINE_PIPELINE_LIBRARY() \
};
extern VkPipelineLayout g_pLibraryEmptyLayout;
#define BEGIN_BUILD_PIPELINE_LIBRARY(name) \
void CVk##name##PipelineLibrary::Build() \
{ \
@@ -236,22 +241,59 @@ void CVk##name##PipelineLibrary::Build() \
pipeline.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; \
library.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT; \
pipeline.pNext = &library; \
pipeline.flags = VK_PIPELINE_CREATE_LIBRARY_BIT_KHR; \
pipeline.flags = VK_PIPELINE_CREATE_LIBRARY_BIT_KHR | VK_PIPELINE_CREATE_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT; \
pipeline.layout = g_pLibraryEmptyLayout;
#define END_BUILD_PIPELINE_LIBRARY() \
vkCreateGraphicsPipelines(g_vkDevice, NULL, 1, &pipeline, NULL, &m_hPipeline); \
}
class CVkShader : IShader
class CVkShader : public IShader
{
public:
void AddShaderLibrary( CVkPipelineLibrary *pLibrary );
void Build();
virtual uint32_t PSGetResourceByName( const char *szName ) override;
virtual uint32_t VSGetResourceByName( const char *szName ) override;
VkPipeline m_hPipeline = NULL;
VkPipelineLayout m_hPipelineLayout;
CUtlVector<CVkPipelineLibrary*> m_libraries;
};
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);
};
enum EVulkanRenderingStage
{
RENDERING_STAGE_SETUP_RASTER,
RENDERING_STAGE_RASTER,
RENDERING_STAGE_POST_RASTER,
RENDERING_STAGE_FINISHED,
};
struct VulkanMaterialCommandBuffer_t
{
IMaterial *m_pMaterial;
IVkCommandBuffer *m_pCommandBuffer;
};
enum EVkFrameObjectType_t
{
FRAME_OBJECT_TYPE_SINGLE,
@@ -267,6 +309,64 @@ struct VkFrameObject_t
};
};
struct VulkanRenderOutput_t {
VkFrameObject_t m_stImage;
VkFrameObject_t m_stResolveImage;
float m_fClearColor[4];
float m_fClearDepth;
uint32_t m_uIndex;
EResolveMode m_eResolveMode;
ELoadMode m_eLoadMode;
EStoreMode m_eStoreMode;
};
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?
virtual void SetScissors( uint32_t uX, uint32_t uY, uint32_t uWidth, uint32_t uHeight ) override;
virtual void SetViewport( uint32_t uX, uint32_t uY, uint32_t uWidth, uint32_t uHeight, float fMinDepth, float fMaxDepth ) override;
virtual void SetMaterial( IMaterial *pMaterial ) override;
virtual void SetVertexBuffer( uint32_t uBinding, IVertexBuffer *pBuffer ) override;
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();
private:
void SwitchRenderingStage( EVulkanRenderingStage eStage );
VulkanRenderOutput_t *FindOrCreateRenderOutput( uint32_t uIndex );
IVkCommandBuffer *FindOrCreateMaterialCommandBuffer( IMaterial *pMaterial, bool *pbWasCreated = NULL );
VulkanRenderOutput_t m_depth;
CUtlVector<VulkanRenderOutput_t> m_pOutput = {};
CUtlSelfReferencingVector<VulkanMaterialCommandBuffer_t> m_materials = {};
IVkCommandBuffer *m_pPostRaster;
IVkCommandBuffer *m_pCurrentMaterialBuffer = NULL;
};
IRenderingObject *VulkanGetObject( VkFrameObject_t stObject, int iIndex );
VkAccessFlags2 VulkanGetAccessFlags( EDependencyMode eMode );
@@ -274,4 +374,6 @@ VkPipelineStageFlags2 VulkanGetStageFlags( EDependencyMode eMode );
VkImageLayout VulkanGetImageLayout( EDependencyMode eMode );
VkFormat VulkanGetVertexFormat( EVertexFormat eFormat );
VkPrimitiveTopology VulkanGetTopology( ETopologyMode eMode );
VkShaderStageFlagBits VulkanGetShaderStage( EShaderStage eStage );
#endif