working on rendering
This commit is contained in:
@@ -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",
|
||||
|
||||
145
materialsystem/compiledshader.cpp
Normal file
145
materialsystem/compiledshader.cpp
Normal 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;
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
193
materialsystem/vulkan/rendercommandlist.cpp
Normal file
193
materialsystem/vulkan/rendercommandlist.cpp
Normal 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;
|
||||
}
|
||||
@@ -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()
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
28
materialsystem/vulkan/shaderparser.cpp
Normal file
28
materialsystem/vulkan/shaderparser.cpp
Normal 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;
|
||||
};
|
||||
17
materialsystem/vulkan/shaderparser.h
Normal file
17
materialsystem/vulkan/shaderparser.h
Normal 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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
6
materialsystem/vulkan/vma.cpp
Normal file
6
materialsystem/vulkan/vma.cpp
Normal 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"
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user