From 898bf905042f2604cda28b20042ee8bbbbbc387c Mon Sep 17 00:00:00 2001 From: kotofyt Date: Fri, 6 Feb 2026 15:43:22 +0200 Subject: [PATCH] somewhat working material system --- engine/build.cpp | 1 + engine/engine.cpp | 19 ++++--- materialsystem/vulkan/commands.h | 4 ++ materialsystem/vulkan/commands/draw.cpp | 5 ++ materialsystem/vulkan/material.cpp | 59 ++++++++++++++++++++- materialsystem/vulkan/rendercommandlist.cpp | 4 ++ materialsystem/vulkan/rendercontext.cpp | 9 +++- materialsystem/vulkan/shader.cpp | 45 ++++++++++++++-- materialsystem/vulkan/vulkan_state.h | 11 ++-- 9 files changed, 140 insertions(+), 17 deletions(-) diff --git a/engine/build.cpp b/engine/build.cpp index a30ae4b..a453dbe 100644 --- a/engine/build.cpp +++ b/engine/build.cpp @@ -26,6 +26,7 @@ DECLARE_BUILD_STAGE(engine) compileProject.includeDirectories = { "../public", "../external/SDL/include", + "../external/cglm/include", FUNNYSTDLIB"public", }; compileProject.bFPIC = true; diff --git a/engine/engine.cpp b/engine/engine.cpp index 87c202a..46739c9 100644 --- a/engine/engine.cpp +++ b/engine/engine.cpp @@ -6,6 +6,7 @@ #include "tier0/commandline.h" #include "tier0/mem.h" #include "sv_dll.h" +#include "cglm/cglm.h" IRenderContext *g_pRenderContext; IFileSystem *filesystem; @@ -47,14 +48,15 @@ extern "C" void FunnyMain( int argc, char **argv ) IVertexBuffer *pVertices = NULL; float vertices[18] = { - -0.5, -0.5, 0, - 0.5, -0.5, 0, - -0.5, 0.5, 0, - -0.5, 0.5, 0, - 0.5, -0.5, 0, - 0.5, 0.5, 0 - + -0.5, -0.5, 0.5, + 0.5, -0.5, 0.5, + -0.5, 0.5, 0.5, + -0.5, 0.5, 0.5, + 0.5, -0.5, 0.5, + 0.5, 0.5, 0.5 }; + mat4 mat; + glm_mat4_identity(mat); pVertices = g_pRenderContext->CreateVertexBuffer(72); @@ -63,6 +65,9 @@ extern "C" void FunnyMain( int argc, char **argv ) pVertices->Unmap(); pCameraInfoBuffer = g_pRenderContext->CreateConstantBuffer(64); + pMapped = pCameraInfoBuffer->Map(); + V_memcpy(pMapped, mat, 64); + pCameraInfoBuffer->Unmap(); pShader = g_pRenderContext->CreateShader("game/core/shaders/flat.shader_c"); pShader->AddLayout(0, 12); diff --git a/materialsystem/vulkan/commands.h b/materialsystem/vulkan/commands.h index 7da7d04..e2d1eb3 100644 --- a/materialsystem/vulkan/commands.h +++ b/materialsystem/vulkan/commands.h @@ -46,6 +46,10 @@ BEGIN_VULKAN_COMMAND(SetShader) IShader *pShader; END_VULKAN_COMMAND(SetShader) +BEGIN_VULKAN_COMMAND(SetShaderData) + IMaterial *pShaderData; +END_VULKAN_COMMAND(SetShaderData) + BEGIN_VULKAN_COMMAND(DrawPrimitives) uint32_t nVertexCount; uint32_t nFirstVertex; diff --git a/materialsystem/vulkan/commands/draw.cpp b/materialsystem/vulkan/commands/draw.cpp index 7636731..aeed740 100644 --- a/materialsystem/vulkan/commands/draw.cpp +++ b/materialsystem/vulkan/commands/draw.cpp @@ -66,6 +66,11 @@ DECLARE_VULKAN_COMMAND(SetShader) CVkShader *pVkShader = (CVkShader*)pShader; vkCmdBindPipeline(hCommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pVkShader->m_hPipeline); } +DECLARE_VULKAN_COMMAND(SetShaderData) +{ + CVkMaterial *pMat = (CVkMaterial*)pShaderData; + vkCmdBindDescriptorSets(hCommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pMat->m_pVkShader->m_hPipelineLayout, 0, 1, &pMat->m_hSet, 0, 0 ); +} DECLARE_VULKAN_COMMAND(SetVertexBuffer) { diff --git a/materialsystem/vulkan/material.cpp b/materialsystem/vulkan/material.cpp index 0aac008..2aaac4b 100644 --- a/materialsystem/vulkan/material.cpp +++ b/materialsystem/vulkan/material.cpp @@ -2,6 +2,48 @@ CVkMaterial::CVkMaterial( IShader *pShader ) { m_pVkShader = (CVkShader*)pShader; + + VkDescriptorPoolSize pools[1] = + { + { + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + 128, + } + }; + VkDescriptorPoolCreateInfo stPool = {}; + stPool.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; + stPool.poolSizeCount = 1; + stPool.pPoolSizes = pools; + stPool.maxSets = 1; + stPool.flags = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT; + vkCreateDescriptorPool(m_pVkShader->m_hDevice, &stPool, NULL, &m_hPool); + + VkDescriptorSetAllocateInfo stInfo = {}; + stInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; + stInfo.descriptorSetCount = 1; + stInfo.descriptorPool = m_hPool; + stInfo.pSetLayouts = m_pVkShader->m_setLayouts.GetData(); + vkAllocateDescriptorSets(m_pVkShader->m_hDevice, &stInfo, &m_hSet); + + for ( auto b: m_pVkShader->m_bindings ) + { + VkWriteDescriptorSet write = {}; + write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + write.dstSet = m_hSet; + write.dstBinding = b.uBinding; + write.dstArrayElement = 0; + write.descriptorType = b.eDescriptorType; + write.descriptorCount = 1; + switch (b.eDescriptorType) + { + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: + write.pBufferInfo = new VkDescriptorBufferInfo; + break; + default: + break; + }; + m_writes.AppendTail(write); + } } CVkMaterial::~CVkMaterial() @@ -9,6 +51,11 @@ CVkMaterial::~CVkMaterial() } +void CVkMaterial::Frame() +{ + vkUpdateDescriptorSets(m_pVkShader->m_hDevice, m_writes.GetSize(), m_writes.GetData(), 0, 0); +}; + void CVkMaterial::VSSetShaderResource( uint32_t uRegister, IRenderingObject *pResource ) { SetShaderResource(uRegister, SHADER_STAGE_VERTEX, pResource); @@ -31,6 +78,16 @@ void CVkMaterial::PSSetConstantsBuffer( uint32_t uRegister, IBuffer *pConstants void CVkMaterial::SetShaderResource( uint32_t uRegister, uint32_t uSet, IRenderingObject *pObject) { - + union { + IRenderingObject *pVkObject; + CVkBuffer *pBuffer; + }; + pVkObject = pObject; + if (dynamic_cast(pObject)) + { + ((VkDescriptorBufferInfo*)m_writes[uRegister].pBufferInfo)->buffer = pBuffer->m_buffer; + ((VkDescriptorBufferInfo*)m_writes[uRegister].pBufferInfo)->range = pBuffer->m_nSize; + } + Frame(); } diff --git a/materialsystem/vulkan/rendercommandlist.cpp b/materialsystem/vulkan/rendercommandlist.cpp index 5a0b4fb..53ec43b 100644 --- a/materialsystem/vulkan/rendercommandlist.cpp +++ b/materialsystem/vulkan/rendercommandlist.cpp @@ -87,6 +87,10 @@ void CVkRenderCommandList::SetMaterial( IMaterial *pMaterial ) pSetShader->pShader = ((CVkMaterial*)pMaterial)->m_pVkShader; m_pCurrentMaterialBuffer->AddCommand(pSetShader); + CVkSetShaderDataCommand *pSetShaderData = CREATE_COMMAND(SetShaderData); + pSetShaderData->pShaderData = pMaterial; + m_pCurrentMaterialBuffer->AddCommand(pSetShaderData); + CVkSetScissorsCommand *pScissorsCommand = CREATE_COMMAND(SetScissors); pScissorsCommand->uWidth = m_uWidth; pScissorsCommand->uHeight = m_uHeight; diff --git a/materialsystem/vulkan/rendercontext.cpp b/materialsystem/vulkan/rendercontext.cpp index 0c1579e..71a23b3 100644 --- a/materialsystem/vulkan/rendercontext.cpp +++ b/materialsystem/vulkan/rendercontext.cpp @@ -294,6 +294,7 @@ private: IVkCommandBufferManager *m_pCommandBufferManager; CUtlVector m_renderWindows; + CUtlVector m_pMaterials; }; EXPOSE_INTERFACE(CVkRenderContext, IRenderContext, RENDER_CONTEXT_INTERFACE_VERSION); @@ -392,7 +393,9 @@ void CVkRenderContext::DestroyShader( IShader *pShader ) IMaterial *CVkRenderContext::CreateMaterial( IShader *pShader ) { - return new CVkMaterial(pShader); + CVkMaterial *pMaterial = new CVkMaterial(pShader); + m_pMaterials.AppendTail(pMaterial); + return pMaterial; } void CVkRenderContext::DestroyMaterial( IMaterial *pMaterial ) @@ -601,6 +604,10 @@ void CVkRenderContext::Frame( float fDeltaTime ) CUtlVector recreatedWindows = {}; vkDeviceWaitIdle(s_vkDevice); + for ( auto &m: m_pMaterials) + { + } + i = 0; for ( auto &s: m_renderWindows) { diff --git a/materialsystem/vulkan/shader.cpp b/materialsystem/vulkan/shader.cpp index f46c93b..58260f6 100644 --- a/materialsystem/vulkan/shader.cpp +++ b/materialsystem/vulkan/shader.cpp @@ -61,17 +61,36 @@ void CVkShader::Build() VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT, }; VkPipelineLayoutCreateInfo stPipelineLayout = {}; - - stPipelineLayout.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; - vkCreatePipelineLayout(m_hDevice, &stPipelineLayout, NULL, &m_hPipelineLayout); + CUtlVector bindings = {}; // TODO: Filter by vulkan shaders at some points stages.Resize(m_shader.m_objects.GetSize()); modules.Resize(m_shader.m_objects.GetSize()); for ( int i = 0; i < m_shader.m_objects.GetSize(); i++ ) { - V_printf("a: %p\n", m_shader.m_lumps[i].m_pAddress); - + VulkanInputMetaData_t *pMetaData = (VulkanInputMetaData_t*)m_shader.GetLumpPtr(m_shader.m_objects[i].m_nMetadataLump); + for ( int u = 0; u < pMetaData->nDescriptorsCount; u++ ) + { + VulkanDescriptor_t *pDescriptor = (VulkanDescriptor_t*)m_shader.GetLumpPtr(pMetaData->pDescriptorSets); + V_printf("%s\n" ,pDescriptor->szName); + bool bFound = false; + for ( auto &b: bindings ) + { + if (b.binding != pDescriptor->uBinding) + continue; + bFound = true; + break; + } + if (bFound) + break; + VkDescriptorSetLayoutBinding bind = {}; + bind.binding = pDescriptor->uBinding; + bind.descriptorCount = 1; + bind.descriptorType = pDescriptor->eDescriptorType; + bind.stageFlags = VK_SHADER_STAGE_ALL; + bindings.AppendTail(bind); + m_bindings.AppendTail(*pDescriptor); + } modules[i].sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; modules[i].pCode = (uint32_t*)m_shader.GetLumpPtr(m_shader.m_objects[i].m_nDataLump); modules[i].codeSize = m_shader.GetLumpSize(m_shader.m_objects[i].m_nDataLump); @@ -81,6 +100,22 @@ void CVkShader::Build() stages[i].stage = VulkanGetShaderStage(m_shader.m_objects[i].m_eStage); } + if ( bindings.GetSize() >= 0 ) + { + m_setLayouts.Resize(1); + VkDescriptorSetLayoutCreateInfo stSetLayoutCreateInfo = {}; + stSetLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; + stSetLayoutCreateInfo.pBindings = bindings.GetData(); + stSetLayoutCreateInfo.bindingCount = bindings.GetSize(); + stSetLayoutCreateInfo.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT; + vkCreateDescriptorSetLayout(m_hDevice, &stSetLayoutCreateInfo, NULL, m_setLayouts.GetData()); + stPipelineLayout.setLayoutCount = 1; + stPipelineLayout.pSetLayouts = m_setLayouts.GetData(); + } + + stPipelineLayout.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + vkCreatePipelineLayout(m_hDevice, &stPipelineLayout, NULL, &m_hPipelineLayout); + vertexInput.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; vertexInput.vertexBindingDescriptionCount = m_layouts.GetSize(); vertexInput.pVertexBindingDescriptions = m_layouts.GetData(); diff --git a/materialsystem/vulkan/vulkan_state.h b/materialsystem/vulkan/vulkan_state.h index 7d1ea2c..10401d4 100644 --- a/materialsystem/vulkan/vulkan_state.h +++ b/materialsystem/vulkan/vulkan_state.h @@ -10,7 +10,7 @@ #include "tier2/iappsystem.h" #include "materialsystem/imaterialsystem.h" #include "materialsystem/shaderinternals.h" -#include "vulkan/vulkan_core.h" +#include "materialsystem/vulkan_shadermeta.h" #define REQUIRED_EXTENSION(ext) bool bIsSupported_##ext; #define OPTIONAL_EXTENSION(ext) bool bIsSupported_##ext; @@ -268,9 +268,11 @@ public: CUtlVector m_libraries; VkDevice m_hDevice; CCompiledShader m_shader; + CUtlVector m_setLayouts; + CUtlVector m_bindings; private: - CUtlVector m_attributes; CUtlVector m_layouts; + CUtlVector m_attributes; CUtlVector m_eFormats; }; @@ -281,7 +283,7 @@ public: CVkMaterial( IShader *pShader ); virtual ~CVkMaterial() override; - virtual uint32_t GetResourceByName( const char *szString ); + void Frame(); virtual void VSSetShaderResource( uint32_t uRegister, IRenderingObject *pResource ) override; virtual void VSSetConstantsBuffer( uint32_t uRegister, IBuffer *pConstants ) override; @@ -290,7 +292,10 @@ public: virtual void PSSetConstantsBuffer( uint32_t uRegister, IBuffer *pConstants ) override; CVkShader *m_pVkShader; + VkDescriptorSet m_hSet; private: + VkDescriptorPool m_hPool; + CUtlVector m_writes = {}; void SetShaderResource( uint32_t uRegister, uint32_t uSet, IRenderingObject *pObject); };