diff --git a/build.cpp b/build.cpp index fb172e3..37d47d8 100755 --- a/build.cpp +++ b/build.cpp @@ -28,6 +28,7 @@ DECLARE_BUILD_STAGE(install_game) filesystem2->CopyFile(szOutputDir, GET_PROJECT_OBJECT(Server, "server")); filesystem2->CopyFile(szOutputDir, GET_PROJECT_OBJECT(Client, "client")); filesystem2->CopyDirectory(CUtlString("%s/core",szOutputDir.GetString()), "funnyassets/meshes"); + filesystem2->CopyDirectory(CUtlString("%s/core",szOutputDir.GetString()), "funnyassets/textures"); filesystem2->CopyDirectory(CUtlString("%s/core",szOutputDir.GetString()), "build/funnygame/assets/shaders"); if (Target_t::DefaultTarget().kernel == TARGET_KERNEL_WINDOWS) { diff --git a/external/linux/libgfx.so b/external/linux/libgfx.so index 692c920..e0b1e23 100755 Binary files a/external/linux/libgfx.so and b/external/linux/libgfx.so differ diff --git a/external/linux/libgfx.so.0.2025.24.2 b/external/linux/libgfx.so.0.2025.24.2 deleted file mode 100644 index 692c920..0000000 Binary files a/external/linux/libgfx.so.0.2025.24.2 and /dev/null differ diff --git a/external/linux/libgfx.so.0.2026.2.2 b/external/linux/libgfx.so.0.2026.2.2 new file mode 100644 index 0000000..e0b1e23 Binary files /dev/null and b/external/linux/libgfx.so.0.2026.2.2 differ diff --git a/external/linux/libslang-compiler.so b/external/linux/libslang-compiler.so index 3df3d5c..0414e09 100755 Binary files a/external/linux/libslang-compiler.so and b/external/linux/libslang-compiler.so differ diff --git a/external/linux/libslang-compiler.so.0.2025.24.2 b/external/linux/libslang-compiler.so.0.2026.2.2 similarity index 70% rename from external/linux/libslang-compiler.so.0.2025.24.2 rename to external/linux/libslang-compiler.so.0.2026.2.2 index 3df3d5c..0414e09 100644 Binary files a/external/linux/libslang-compiler.so.0.2025.24.2 and b/external/linux/libslang-compiler.so.0.2026.2.2 differ diff --git a/external/linux/libslang-glsl-module-2025.24.2.so b/external/linux/libslang-glsl-module-2025.24.2.so deleted file mode 100644 index 1da6b5f..0000000 Binary files a/external/linux/libslang-glsl-module-2025.24.2.so and /dev/null differ diff --git a/external/linux/libslang-glsl-module-2026.2.2.so b/external/linux/libslang-glsl-module-2026.2.2.so new file mode 100644 index 0000000..840534f Binary files /dev/null and b/external/linux/libslang-glsl-module-2026.2.2.so differ diff --git a/external/linux/libslang-glslang-2025.24.2.so b/external/linux/libslang-glslang-2026.2.2.so similarity index 70% rename from external/linux/libslang-glslang-2025.24.2.so rename to external/linux/libslang-glslang-2026.2.2.so index 9e03bc5..04aa6f2 100644 Binary files a/external/linux/libslang-glslang-2025.24.2.so and b/external/linux/libslang-glslang-2026.2.2.so differ diff --git a/external/linux/libslang-llvm.so b/external/linux/libslang-llvm.so index 5a01092..f349d3d 100644 Binary files a/external/linux/libslang-llvm.so and b/external/linux/libslang-llvm.so differ diff --git a/external/linux/libslang-rt.so b/external/linux/libslang-rt.so index 6f4b26c..becf07b 100755 Binary files a/external/linux/libslang-rt.so and b/external/linux/libslang-rt.so differ diff --git a/external/linux/libslang-rt.so.0.2025.24.2 b/external/linux/libslang-rt.so.0.2026.2.2 similarity index 55% rename from external/linux/libslang-rt.so.0.2025.24.2 rename to external/linux/libslang-rt.so.0.2026.2.2 index 6f4b26c..becf07b 100644 Binary files a/external/linux/libslang-rt.so.0.2025.24.2 and b/external/linux/libslang-rt.so.0.2026.2.2 differ diff --git a/external/linux/libslang.so b/external/linux/libslang.so index 3df3d5c..0414e09 100755 Binary files a/external/linux/libslang.so and b/external/linux/libslang.so differ diff --git a/funnyassets/shaders/mesh_raster.shader b/funnyassets/shaders/mesh_raster.shader index 7abde48..5445c46 100644 --- a/funnyassets/shaders/mesh_raster.shader +++ b/funnyassets/shaders/mesh_raster.shader @@ -10,6 +10,7 @@ COMMON { { float4x4 m_matTranslation; float4x4 m_matRotation; + uint32_t m_uAlbedo; } StructuredBuffer g_modelData; struct PS_INPUT @@ -30,13 +31,13 @@ VS float3 m_vNormal: NORMAL0; } - PS_INPUT vsMain( VS_INPUT input ) + PS_INPUT vsMain( VS_INPUT input, uint uInstance: SV_InstanceID ) { PS_INPUT output = {}; output.m_vScreenPosition = float4(input.m_vPosition, 1); output.m_vScreenPosition = mul( output.m_vScreenPosition, - g_modelData[0].m_matTranslation + g_modelData[uInstance].m_matTranslation ); output.m_vScreenPosition = mul( output.m_vScreenPosition, @@ -44,11 +45,11 @@ VS ); output.m_vWorldPosition = mul( float4(input.m_vPosition, 1), - g_modelData[0].m_matTranslation + g_modelData[uInstance].m_matTranslation ); output.m_vNormal = mul( float4(input.m_vNormal, 1), - g_modelData[0].m_matRotation + g_modelData[uInstance].m_matRotation ); output.m_vTexCoord = float4(input.m_vTexCoord, 0, 0); return output; @@ -57,15 +58,23 @@ VS PS { #include "brdf.hlsl" + #include "textures.hlsl" + + struct PS_OUTPUT { float4 m_vAlbedo: SV_Target0; + float4 m_vNormal: SV_Target1; + float4 m_vWorldPosition: SV_Target2; } - PS_OUTPUT psMain( PS_INPUT input ) + PS_OUTPUT psMain( PS_INPUT input, uint uInstance: SV_InstanceID ) { PS_OUTPUT output = {}; - output.m_vAlbedo = input.m_vNormal; + PerModelData data = g_modelData[uInstance]; + output.m_vAlbedo = g_textures[data.m_uAlbedo].Sample(g_textureSampler, input.m_vTexCoord.xy); + output.m_vWorldPosition = input.m_vWorldPosition; + output.m_vNormal = input.m_vNormal; return output; } } diff --git a/funnyassets/shaders/textures.hlsl b/funnyassets/shaders/textures.hlsl new file mode 100644 index 0000000..afef19d --- /dev/null +++ b/funnyassets/shaders/textures.hlsl @@ -0,0 +1,3 @@ + +SamplerState g_textureSampler: register(s0,space1); +Texture2D g_textures[]: register(t1, space1); diff --git a/funnyassets/textures/error.png b/funnyassets/textures/error.png new file mode 100644 index 0000000..d122952 Binary files /dev/null and b/funnyassets/textures/error.png differ diff --git a/game/client/baseentity.cpp b/game/client/baseentity.cpp index f7d8b42..a06b562 100644 --- a/game/client/baseentity.cpp +++ b/game/client/baseentity.cpp @@ -57,7 +57,6 @@ float C_BaseEntity::GetScale( void ) void C_BaseEntity::SetThinkImpl( fnThink pfnThink ) { m_pfnThink = pfnThink; - V_printf("%p\n", pfnThink); } void C_BaseEntity::SetNextThink( float fThink ) diff --git a/game/client/milmoba/player.cpp b/game/client/milmoba/player.cpp index 81c79af..649301d 100644 --- a/game/client/milmoba/player.cpp +++ b/game/client/milmoba/player.cpp @@ -12,7 +12,7 @@ public: virtual void Think( float fDelta ); IMesh *m_pMesh; - IMeshInstance *m_pMeshInstance; + IMeshInstance *m_pMeshInstances[10]; }; void C_MOBAPlayer::Precache() @@ -21,7 +21,6 @@ void C_MOBAPlayer::Precache() IBuffer *pDataBuffer; IShader *pShader; IMaterial *pMaterial; - g_pWorldRenderer->Init(); pShader = g_pRenderContext->CreateShader("game/core/shaders/mesh_raster.shader_c"); IFileHandle *pHandle = filesystem->Open("game/core/meshes/spot.fmesh_c", FILEMODE_READ); @@ -47,10 +46,13 @@ void C_MOBAPlayer::Precache() m_pMesh->SetVertices(pBuffer); m_pMesh->SetMaterial(pMaterial); - m_pMeshInstance = g_pWorldRenderer->CreateInstance(m_pMesh); - m_pMeshInstance->SetScale({5, 5, 5}); - m_pMeshInstance->SetPosition({0,0,0}); - m_pMeshInstance->SetRotation({1,0,0,0}); + for (int i = 0; i < 10; i++) + { + m_pMeshInstances[i] = g_pWorldRenderer->CreateInstance(m_pMesh); + m_pMeshInstances[i]->SetScale({1, 1, 1}); + m_pMeshInstances[i]->SetPosition({(float)i,0,0}); + m_pMeshInstances[i]->SetRotation({1,0,0,0}); + } } @@ -62,10 +64,13 @@ void C_MOBAPlayer::Spawn() void C_MOBAPlayer::Think( float fDelta ) { - m_pMeshInstance->SetPosition({0,0,-(float)g_pEngineVars->m_fTime}); - versor v; - glm_euler_zxy_quat((vec3){(float)g_pEngineVars->m_fTime,0,0}, v); - m_pMeshInstance->SetRotation({v[0], v[1], v[2], v[3]}); + for (int i = 0; i < 10; i++) + { + m_pMeshInstances[i]->SetPosition({(float)i, 0 ,-(float)g_pEngineVars->m_fTime}); + versor v; + glm_euler_zxy_quat((vec3){(float)g_pEngineVars->m_fTime,0,0}, v); + m_pMeshInstances[i]->SetRotation({v[0], v[1], v[2], v[3]}); + } }; LINK_ENTITY_TO_CLASS(player, C_MOBAPlayer) diff --git a/game/client/worldrender.cpp b/game/client/worldrender.cpp index 1327318..6869b17 100644 --- a/game/client/worldrender.cpp +++ b/game/client/worldrender.cpp @@ -16,6 +16,7 @@ struct PerMeshData_t { mat4 m_matTranslation; mat4 m_matRotation; + uint32_t m_uAlbedo; }; class CFunnyMeshInstance; @@ -43,6 +44,8 @@ void CFunnyMesh::ConfigureShader( IShader *pShader ) pShader->AddAttribute(0, 2, VERTEX_FORMAT_XYZ32_SFLOAT, 20); // albedo pShader->AddOutputImage(0, IMAGE_FORMAT_RGBA8_UNORM); + pShader->AddOutputImage(1, IMAGE_FORMAT_RGBA16_SFLOAT); + pShader->AddOutputImage(2, IMAGE_FORMAT_RGBA32_SFLOAT); pShader->SetMultisampling(MULTISAMPLE_TYPE_1_SAMPLES); @@ -117,6 +120,7 @@ void CFunnyMeshInstance::Frame() v[2] = m_vScale.z; glm_scale_make(m, v); glm_mat4_mul(m_data.m_matTranslation, m, m_data.m_matTranslation); + m_data.m_uAlbedo = 1; } @@ -137,10 +141,14 @@ private: CUtlVector m_pMeshes; IImage *m_pOutputImage = NULL; IImage *m_pDepthImage = NULL; + IImage *m_pNormalImage = NULL; + IImage *m_pWorldSpaceImage = NULL; IRenderCommandList *m_pRasterCommandList = NULL; IBuffer *m_pViewBuffer; ViewBuffer_t *m_pViewBufferData; + ITextureArray *m_pTextures; + vec3 m_vPos; versor m_vRot; }; @@ -156,6 +164,18 @@ void CFunnyWorldRenderer::Init() IMAGE_FORMAT_RGBA8_UNORM, MULTISAMPLE_TYPE_NONE ); + m_pNormalImage = g_pRenderContext->CreateRenderTarget( + 100, + 100, + IMAGE_FORMAT_RGBA16_SFLOAT, + MULTISAMPLE_TYPE_NONE + ); + m_pWorldSpaceImage = g_pRenderContext->CreateRenderTarget( + 100, + 100, + IMAGE_FORMAT_RGBA32_SFLOAT, + MULTISAMPLE_TYPE_NONE + ); m_pDepthImage = g_pRenderContext->CreateRenderTarget( 100, @@ -168,6 +188,7 @@ void CFunnyWorldRenderer::Init() m_pRasterCommandList = g_pRenderContext->CreateCommandList(); m_pViewBuffer = g_pRenderContext->CreateConstantBuffer(sizeof(ViewBuffer_t)); + m_pTextures = g_pRenderContext->CreateTextureArray(); } void CFunnyWorldRenderer::Tick( float fDelta ) @@ -197,12 +218,28 @@ void CFunnyWorldRenderer::Frame( float fDelta ) if (g_pMainWindow->BRenderSizeUpdated()) { g_pRenderContext->DestroyImage(m_pOutputImage); + g_pRenderContext->DestroyImage(m_pNormalImage); + g_pRenderContext->DestroyImage(m_pWorldSpaceImage); + g_pRenderContext->DestroyImage(m_pDepthImage); + m_pOutputImage = g_pRenderContext->CreateRenderTarget( g_pMainWindow->GetRenderWidth(), g_pMainWindow->GetRenderHeight(), IMAGE_FORMAT_RGBA8_UNORM, MULTISAMPLE_TYPE_NONE); - g_pRenderContext->DestroyImage(m_pOutputImage); + + m_pNormalImage = g_pRenderContext->CreateRenderTarget( + g_pMainWindow->GetRenderWidth(), + g_pMainWindow->GetRenderHeight(), + IMAGE_FORMAT_RGBA16_SFLOAT, + MULTISAMPLE_TYPE_NONE + ); + m_pWorldSpaceImage = g_pRenderContext->CreateRenderTarget( + g_pMainWindow->GetRenderWidth(), + g_pMainWindow->GetRenderHeight(), + IMAGE_FORMAT_RGBA32_SFLOAT, + MULTISAMPLE_TYPE_NONE + ); m_pDepthImage = g_pRenderContext->CreateRenderTarget( g_pMainWindow->GetRenderWidth(), g_pMainWindow->GetRenderHeight(), @@ -213,6 +250,8 @@ void CFunnyWorldRenderer::Frame( float fDelta ) m_pRasterCommandList->StartRecording(); m_pRasterCommandList->SetRenderResolution(uWidth, uHeight); m_pRasterCommandList->SetRenderTarget(0, m_pOutputImage); + m_pRasterCommandList->SetRenderTarget(1, m_pNormalImage); + m_pRasterCommandList->SetRenderTarget(2, m_pWorldSpaceImage); m_pRasterCommandList->SetDepthTarget(m_pDepthImage); m_pRasterCommandList->SetViewport(0, 0, uWidth, uHeight, 0, 1); m_pRasterCommandList->SetScissors(0, 0, uWidth, uHeight); @@ -240,6 +279,7 @@ void CFunnyWorldRenderer::Frame( float fDelta ) pDataBuffer->Unlock(); mesh->m_pMaterial->VSSetConstantsBuffer(0, m_pViewBuffer); mesh->m_pMaterial->VSSetConstantsBuffer(1, pDataBuffer); + mesh->m_pMaterial->PSSetTextureArray(1, m_pTextures); g_pRenderContext->DestroyBuffer(pDataBuffer); } for ( auto mesh: m_pMeshes) diff --git a/materialsystem/build.cpp b/materialsystem/build.cpp index cbb57b8..28e7c24 100644 --- a/materialsystem/build.cpp +++ b/materialsystem/build.cpp @@ -28,7 +28,8 @@ CUtlVector RenderContextVulkan_CompiledFiles = { "vulkan/commands/base.cpp", "vulkan/libraries/raster.cpp", EXTERNAL"volk/volk.c", - "gamewindow_sdl.cpp" + "gamewindow_sdl.cpp", + "stb.c", }; DECLARE_BUILD_STAGE(MaterialSystem) diff --git a/materialsystem/compiledshader.cpp b/materialsystem/compiledshader.cpp index 6c2759c..aeb7ced 100644 --- a/materialsystem/compiledshader.cpp +++ b/materialsystem/compiledshader.cpp @@ -74,6 +74,7 @@ void CCompiledShaderManager::WriteToFile( CCompiledShader *pShader, const char * filesystem = (IFileSystem*)pFilesystemFactory(FILESYSTEM_INTERFACE_VERSION, NULL); } pFile = filesystem->Open(szFile, FILEMODE_WRITE); + V_printf("%p\n", pFile); filesystem->Write(pFile, &stHeader, sizeof(ShaderHeader_t)); // We want to get offset for the lump data diff --git a/materialsystem/stb.c b/materialsystem/stb.c new file mode 100644 index 0000000..38c72e9 --- /dev/null +++ b/materialsystem/stb.c @@ -0,0 +1,2 @@ +#define STB_IMAGE_IMPLEMENTATION +#include "stb/stb_image.h" diff --git a/materialsystem/vulkan/commands.h b/materialsystem/vulkan/commands.h index ca914d6..06ee1f2 100644 --- a/materialsystem/vulkan/commands.h +++ b/materialsystem/vulkan/commands.h @@ -74,5 +74,16 @@ BEGIN_VULKAN_COMMAND(SetViewport) float fDepthMax = 1; END_VULKAN_COMMAND(SetViewport) +BEGIN_VULKAN_COMMAND(CopyBufferToImage) + IBuffer *pBuffer; + VkFrameObject_t stOutputImage; + int iOffsetX = 0; + int iOffsetY = 0; + int iOffsetZ = 0; + uint32_t iImageX = 1; + uint32_t iImageY = 1; + uint32_t iImageZ = 1; +END_VULKAN_COMMAND(CopyBufferToImage) + #endif diff --git a/materialsystem/vulkan/commands/draw.cpp b/materialsystem/vulkan/commands/draw.cpp index 4e62b0b..1b053eb 100644 --- a/materialsystem/vulkan/commands/draw.cpp +++ b/materialsystem/vulkan/commands/draw.cpp @@ -80,7 +80,7 @@ DECLARE_VULKAN_COMMAND(SetShader) 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 ); + vkCmdBindDescriptorSets(hCommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pMat->m_pVkShader->m_hPipelineLayout, 0, pMat->m_hSets.GetSize(), pMat->m_hSets.GetData(), 0, 0 ); } DECLARE_VULKAN_COMMAND(SetVertexBuffer) @@ -122,3 +122,24 @@ DECLARE_VULKAN_COMMAND(SetViewport) }; vkCmdSetViewportWithCount(hCommandBuffer, 1, &v); } +DECLARE_VULKAN_COMMAND(CopyBufferToImage) +{ + VkBufferImageCopy2 r = { + .sType = VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2, + .imageSubresource = { + .aspectMask = ((CVkImage*)VulkanGetObject(stOutputImage, iCurrentFrame))->m_range.aspectMask, + .layerCount = 1, + }, + .imageOffset = {iOffsetX, iOffsetY, iOffsetZ}, + .imageExtent = {iImageX, iImageY, iImageZ}, + }; + VkCopyBufferToImageInfo2 c = { + .sType = VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2, + .srcBuffer = ((CVkBuffer*)pBuffer)->m_buffer, + .dstImage = ((CVkImage*)VulkanGetObject(stOutputImage, iCurrentFrame))->m_image, + .dstImageLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + .regionCount = 1, + .pRegions = &r, + }; + vkCmdCopyBufferToImage2(hCommandBuffer, &c); +} diff --git a/materialsystem/vulkan/material.cpp b/materialsystem/vulkan/material.cpp index 8f59f32..896680f 100644 --- a/materialsystem/vulkan/material.cpp +++ b/materialsystem/vulkan/material.cpp @@ -3,7 +3,7 @@ CVkMaterial::CVkMaterial( IShader *pShader ) { m_pVkShader = (CVkShader*)pShader; - VkDescriptorPoolSize pools[2] = + VkDescriptorPoolSize pools[4] = { { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, @@ -12,43 +12,31 @@ CVkMaterial::CVkMaterial( IShader *pShader ) { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 128, + }, + { + VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, + 128, + }, + { + VK_DESCRIPTOR_TYPE_SAMPLER, + 1, } }; VkDescriptorPoolCreateInfo stPool = {}; stPool.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; - stPool.poolSizeCount = 2; + stPool.poolSizeCount = 4; stPool.pPoolSizes = pools; - stPool.maxSets = 1; + stPool.maxSets = 16; 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.descriptorSetCount = m_pVkShader->m_setLayouts.GetSize(); 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: - case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: - write.pBufferInfo = new VkDescriptorBufferInfo; - break; - default: - break; - }; - m_writes.AppendTail(write); - } + m_hSets.Resize(m_pVkShader->m_setLayouts.GetSize()); + vkAllocateDescriptorSets(m_pVkShader->m_hDevice, &stInfo, m_hSets.GetData()); } CVkMaterial::~CVkMaterial() @@ -63,22 +51,27 @@ void CVkMaterial::Frame() void CVkMaterial::VSSetShaderResource( uint32_t uRegister, IRenderingObject *pResource ) { - SetShaderResource(uRegister, SHADER_STAGE_VERTEX, pResource); + SetShaderResource(uRegister, 0, pResource); } void CVkMaterial::PSSetShaderResource( uint32_t uRegister, IRenderingObject *pResource ) { - SetShaderResource(uRegister, SHADER_STAGE_PIXEL, pResource); + SetShaderResource(uRegister, 0, pResource); } void CVkMaterial::VSSetConstantsBuffer( uint32_t uRegister, IBuffer *pConstants ) { - SetShaderResource(uRegister, SHADER_STAGE_VERTEX, pConstants); + SetShaderResource(uRegister, 0, pConstants); } void CVkMaterial::PSSetConstantsBuffer( uint32_t uRegister, IBuffer *pConstants ) { - SetShaderResource(uRegister, SHADER_STAGE_PIXEL, pConstants); + SetShaderResource(uRegister, 0, pConstants); +} + +void CVkMaterial::PSSetTextureArray( uint32_t uSet, ITextureArray *pArray ) +{ + SetShaderResource(0, uSet, pArray); } void CVkMaterial::SetShaderResource( uint32_t uRegister, uint32_t uSet, IRenderingObject *pObject) @@ -86,13 +79,65 @@ void CVkMaterial::SetShaderResource( uint32_t uRegister, uint32_t uSet, IRenderi union { IRenderingObject *pVkObject; CVkBuffer *pBuffer; + CVkTextureArray *pArray; }; pVkObject = pObject; if (dynamic_cast(pObject)) { - ((VkDescriptorBufferInfo*)m_writes[uRegister].pBufferInfo)->buffer = pBuffer->m_buffer; - ((VkDescriptorBufferInfo*)m_writes[uRegister].pBufferInfo)->range = pBuffer->m_nSize; + VkWriteDescriptorSet write = {}; + VkDescriptorBufferInfo stInfo = {}; + write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + write.dstSet = m_hSets[uSet]; + write.dstBinding = uRegister; + write.dstArrayElement = 0; + write.descriptorType = pBuffer->m_eDescriptorType; + write.descriptorCount = 1; + write.pBufferInfo = &stInfo; + stInfo.buffer = pBuffer->m_buffer; + stInfo.range = pBuffer->m_nSize; + vkUpdateDescriptorSets(m_pVkShader->m_hDevice, 1, &write, 0, 0); + } + if (dynamic_cast(pObject)) + { + VkWriteDescriptorSet writes[2] = {}; + VkDescriptorImageInfo stWrites[128]; + VkDescriptorImageInfo stSampler = {}; + + for ( int i = 0; i < 128; i++ ) + { + if (pArray->m_pImages[i] == NULL) + { + stWrites[i] = { + .imageView = pArray->m_pImages[0]->m_imageView, + .imageLayout = VK_IMAGE_LAYOUT_GENERAL, + }; + continue; + } + stWrites[i] = { + .imageView = pArray->m_pImages[i]->m_imageView, + .imageLayout = VK_IMAGE_LAYOUT_GENERAL, + }; + } + + writes[0] = {}; + writes[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + writes[0].dstSet = m_hSets[uSet]; + writes[0].dstBinding = 0; + writes[0].dstArrayElement = 0; + writes[0].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; + writes[0].descriptorCount = 1; + writes[0].pImageInfo = &stSampler; + stSampler.sampler = pArray->m_hSampler; + + writes[1] = {}; + writes[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + writes[1].dstSet = m_hSets[uSet]; + writes[1].dstBinding = 1; + writes[1].dstArrayElement = 0; + writes[1].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; + writes[1].descriptorCount = 128; + writes[1].pImageInfo = stWrites; + vkUpdateDescriptorSets(m_pVkShader->m_hDevice, 2, writes, 0, 0); } - vkUpdateDescriptorSets(m_pVkShader->m_hDevice, 1, &m_writes[uRegister], 0, 0); } diff --git a/materialsystem/vulkan/rendercommandlist.cpp b/materialsystem/vulkan/rendercommandlist.cpp index a5a3d7a..385beaf 100644 --- a/materialsystem/vulkan/rendercommandlist.cpp +++ b/materialsystem/vulkan/rendercommandlist.cpp @@ -84,7 +84,7 @@ void CVkRenderCommandList::SetMaterial( IMaterial *pMaterial ) if (bWasCreated) { m_pCurrentMaterialBuffer->Reset(); - CVkBeginCommand *pBeginCommand = CREATE_COMMAND(Begin); + CVkBeginCommand *pBeginCommand = CREATE_COMMAND(m_pCommandBufferManager, Begin); pBeginCommand->images = m_pOutput; pBeginCommand->nResolutionX = m_uWidth; pBeginCommand->nResolutionY = m_uHeight; @@ -101,20 +101,20 @@ void CVkRenderCommandList::SetMaterial( IMaterial *pMaterial ) } m_pCurrentMaterialBuffer->AddCommand(pBeginCommand); - CVkSetShaderCommand *pSetShader = CREATE_COMMAND(SetShader); + CVkSetShaderCommand *pSetShader = CREATE_COMMAND(m_pCommandBufferManager, SetShader); pSetShader->pShader = ((CVkMaterial*)pMaterial)->m_pVkShader; m_pCurrentMaterialBuffer->AddCommand(pSetShader); - CVkSetShaderDataCommand *pSetShaderData = CREATE_COMMAND(SetShaderData); + CVkSetShaderDataCommand *pSetShaderData = CREATE_COMMAND(m_pCommandBufferManager, SetShaderData); pSetShaderData->pShaderData = pMaterial; m_pCurrentMaterialBuffer->AddCommand(pSetShaderData); - CVkSetScissorsCommand *pScissorsCommand = CREATE_COMMAND(SetScissors); + CVkSetScissorsCommand *pScissorsCommand = CREATE_COMMAND(m_pCommandBufferManager, SetScissors); pScissorsCommand->uWidth = m_uWidth; pScissorsCommand->uHeight = m_uHeight; m_pCurrentMaterialBuffer->AddCommand(pScissorsCommand); - CVkSetViewportCommand *pViewportCommand = CREATE_COMMAND(SetViewport); + CVkSetViewportCommand *pViewportCommand = CREATE_COMMAND(m_pCommandBufferManager, SetViewport); pViewportCommand->fX = 0; pViewportCommand->fY = 0; pViewportCommand->fWidth = m_uWidth; @@ -128,7 +128,7 @@ void CVkRenderCommandList::SetMaterial( IMaterial *pMaterial ) void CVkRenderCommandList::SetVertexBuffer( uint32_t uBinding, IVertexBuffer *pBuffer ) { SwitchRenderingStage(RENDERING_STAGE_RASTER); - CVkSetVertexBufferCommand *pCmd = CREATE_COMMAND(SetVertexBuffer); + CVkSetVertexBufferCommand *pCmd = CREATE_COMMAND(m_pCommandBufferManager, SetVertexBuffer); pCmd->uBinding = uBinding; pCmd->pBuffer = pBuffer; m_pCurrentMaterialBuffer->AddCommand(pCmd); @@ -143,7 +143,7 @@ void CVkRenderCommandList::DrawPrimitives( uint32_t nVertexCount, uint32_t nFirs { SwitchRenderingStage(RENDERING_STAGE_RASTER); - CVkDrawPrimitivesCommand *pCmd = CREATE_COMMAND(DrawPrimitives); + CVkDrawPrimitivesCommand *pCmd = CREATE_COMMAND(m_pCommandBufferManager, DrawPrimitives); pCmd->nVertexCount = nVertexCount; pCmd->nFirstVertex = nFirstVertex; pCmd->nInstanceCount = nInstanceCount; @@ -174,7 +174,7 @@ void CVkRenderCommandList::EndRecording() { for ( auto m: m_materials) { - CVkEndCommand *pEndCommand = CREATE_COMMAND(End); + CVkEndCommand *pEndCommand = CREATE_COMMAND(m_pCommandBufferManager, End); m.m_pCommandBuffer->AddCommand(pEndCommand); m.m_pCommandBuffer->Render(); } diff --git a/materialsystem/vulkan/rendercontext.cpp b/materialsystem/vulkan/rendercontext.cpp index ffe7953..4bd6e3d 100644 --- a/materialsystem/vulkan/rendercontext.cpp +++ b/materialsystem/vulkan/rendercontext.cpp @@ -6,11 +6,13 @@ #include "tier1/interface.h" #include "tier1/utlstring.h" #include "tier1/utlvector.h" +#include "tier2/ifilesystem.h" #define VK_NO_PROTOTYPES #include "vulkan/vulkan_core.h" #include "vulkan_state.h" #include "materialsystem/igamewindow.h" #include "libraries.h" +#include "stb/stb_image.h" #define REQUIRED_EXTENSION(ext) ext##_EXTENSION_NAME, @@ -103,21 +105,64 @@ VkFormat CVkImage::GetImageFormat( enum EImageFormat eImageFormat ) { case IMAGE_FORMAT_R8_UINT: return VK_FORMAT_R8_UINT; + case IMAGE_FORMAT_RGB8_UINT: + return VK_FORMAT_R8G8B8_UINT; + case IMAGE_FORMAT_RGB8_SINT: + return VK_FORMAT_R8G8B8_SINT; + case IMAGE_FORMAT_RGB8_UNORM: + return VK_FORMAT_R8G8B8_UNORM; + case IMAGE_FORMAT_RGB8_SNORM: + return VK_FORMAT_R8G8B8_SNORM; + + case IMAGE_FORMAT_RGB16_UINT: + return VK_FORMAT_R16G16B16_UINT; + case IMAGE_FORMAT_RGB16_SINT: + return VK_FORMAT_R16G16B16_SINT; + case IMAGE_FORMAT_RGB16_UNORM: + return VK_FORMAT_R16G16B16_UNORM; + case IMAGE_FORMAT_RGB16_SNORM: + return VK_FORMAT_R16G16B16_SNORM; + case IMAGE_FORMAT_RGB16_SFLOAT: + return VK_FORMAT_R16G16B16_SFLOAT; + + case IMAGE_FORMAT_RGB32_SFLOAT: + return VK_FORMAT_R32G32B32_SFLOAT; + case IMAGE_FORMAT_RGBA8_UNORM: return VK_FORMAT_R8G8B8A8_UNORM; case IMAGE_FORMAT_BGRA8_UNORM: return VK_FORMAT_B8G8R8A8_UNORM; + case IMAGE_FORMAT_RGBA8_UINT: return VK_FORMAT_R8G8B8A8_UINT; case IMAGE_FORMAT_RGBA8_SINT: return VK_FORMAT_R8G8B8A8_SINT; + + case IMAGE_FORMAT_RGBA16_UINT: + return VK_FORMAT_R16G16B16A16_UINT; + case IMAGE_FORMAT_RGBA16_SINT: + return VK_FORMAT_R16G16B16A16_SINT; + case IMAGE_FORMAT_RGBA16_UNORM: + return VK_FORMAT_R16G16B16A16_UNORM; + case IMAGE_FORMAT_RGBA16_SNORM: + return VK_FORMAT_R16G16B16A16_SNORM; case IMAGE_FORMAT_RGBA16_SFLOAT: return VK_FORMAT_R16G16B16A16_SFLOAT; + case IMAGE_FORMAT_RGBA32_SFLOAT: return VK_FORMAT_R32G32B32A32_SFLOAT; + + case IMAGE_FORMAT_BC1: + return VK_FORMAT_BC1_RGB_UNORM_BLOCK; + case IMAGE_FORMAT_BC3: + return VK_FORMAT_BC3_UNORM_BLOCK; + case IMAGE_FORMAT_BC7: + return VK_FORMAT_BC7_UNORM_BLOCK; + case IMAGE_FORMAT_D32_SFLOAT: return VK_FORMAT_D32_SFLOAT; } + return VK_FORMAT_UNDEFINED; } VkSampleCountFlagBits CVkImage::GetMultisampling( enum EMultisampleType eImageFormat ) @@ -211,6 +256,14 @@ CVkBuffer::CVkBuffer( uint32_t nSize, VkBufferUsageFlags2 eUsage, uint32_t nAlig stUsage.sType = VK_STRUCTURE_TYPE_BUFFER_USAGE_FLAGS_2_CREATE_INFO; stUsage.usage = eUsage | VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT; + if (eUsage & VK_BUFFER_USAGE_2_STORAGE_BUFFER_BIT) + { + m_eDescriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + } + if (eUsage & VK_BUFFER_USAGE_2_UNIFORM_BUFFER_BIT) + { + m_eDescriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + } stBufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; stBufferInfo.size = nSize; @@ -219,7 +272,8 @@ CVkBuffer::CVkBuffer( uint32_t nSize, VkBufferUsageFlags2 eUsage, uint32_t nAlig stAllocInfo.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE; stAllocInfo.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT; - vmaCreateBuffer(s_vkAllocator, &stBufferInfo, &stAllocInfo, &m_buffer, &m_allocation, NULL); + VkResult r = vmaCreateBuffer(s_vkAllocator, &stBufferInfo, &stAllocInfo, &m_buffer, &m_allocation, NULL); + stAddress.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO; stAddress.buffer = m_buffer; @@ -267,6 +321,118 @@ uint32_t CVkBuffer::GetSize() { return m_nSize; } + +CVkTextureArray::~CVkTextureArray() +{ + +} + +CVkTextureArray::CVkTextureArray() +{ + for (uint32_t i = 0; i < 128; i++ ) + m_pImages[i] = NULL; + +} + +void CVkTextureArray::Build() +{ + for (uint32_t i = 0; i < 128; i++ ) + m_pImages[i] = NULL; + + VkSamplerCreateInfo samplerInfo = {}; + samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; + samplerInfo.magFilter = VK_FILTER_LINEAR; + samplerInfo.minFilter = VK_FILTER_LINEAR; + samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT; + samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT; + samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT; + samplerInfo.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK; + samplerInfo.unnormalizedCoordinates = VK_FALSE; + samplerInfo.compareEnable = VK_FALSE; + samplerInfo.compareOp = VK_COMPARE_OP_ALWAYS; + samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; + samplerInfo.mipLodBias = 0.0f; + samplerInfo.minLod = 0.0f; + samplerInfo.maxLod = VK_LOD_CLAMP_NONE; + + vkCreateSampler(m_hDevice, &samplerInfo, nullptr, &m_hSampler); + + LoadTexture("game/core/textures/error.png"); +} + +void CVkTextureArray::SetDebugName( const char *szPath ) +{ + +} + +uint32_t CVkTextureArray::LoadTexture( const char *szPath ) +{ + for (uint32_t i = 0; i < 128; i++ ) + { + if (m_pImages[i] == NULL) + return CreateTexture(i, szPath); + } + return 0; +} + +extern IFileSystem *filesystem; +uint32_t CVkTextureArray::CreateTexture( uint32_t i, const char *szPath ) +{ + if ( filesystem == NULL ) + { + CreateInterfaceFn pFilesystemFactory = Sys_GetFactory("filesystem_std"); + filesystem = (IFileSystem*)pFilesystemFactory(FILESYSTEM_INTERFACE_VERSION, NULL); + } + IFileHandle *pHandle = filesystem->Open(szPath, FILEMODE_READ); + CUtlBuffer data = filesystem->Size(pHandle); + filesystem->Read(pHandle, data.GetMemory(), data.GetSize()); + filesystem->Close(pHandle); + int uWidth = 0; + int uHeight = 0; + int uChannels = 0; + unsigned char *pImg = stbi_load_from_memory(data.GetMemory(), data.GetSize(), &uWidth, &uHeight, &uChannels, 4); + IBuffer *pBuffer = m_pRenderContext->CreateStorageBuffer(uWidth*uHeight*uChannels); + pBuffer->Lock(); + void *pData = pBuffer->Map(); + V_memcpy(pData, pImg, uWidth*uHeight*uChannels); + pBuffer->Unmap(); + pBuffer->Unlock(); + IImage *pImage = m_pRenderContext->CreateTexture(uWidth, uHeight, IMAGE_FORMAT_RGBA8_UNORM, MULTISAMPLE_TYPE_NONE); + IImage *pCompressedImage = m_pRenderContext->CreateTexture(uWidth, uHeight, IMAGE_FORMAT_BC1, MULTISAMPLE_TYPE_NONE); + m_pImages[i] = (CVkImage*)pImage; + stbi_image_free(pImg); + + + CVkCopyBufferToImageCommand *pCopyCommand = NULL; + IVkCommandBuffer *pCommandBuffer = m_pCommandBufferManager->CreateCommandBuffer(); + pCommandBuffer->Reset(); + pCopyCommand = CREATE_COMMAND(m_pCommandBufferManager, CopyBufferToImage); + pCopyCommand->AddDependency((IRenderingObject*)pBuffer, DEPENDENCY_MODE_BUFFER_SOURCE); + pCopyCommand->AddDependency((IRenderingObject*)pImage, DEPENDENCY_MODE_IMAGE_DESTINATION); + pCopyCommand->pBuffer = pBuffer; + pCopyCommand->stOutputImage.m_eObjectType = FRAME_OBJECT_TYPE_SINGLE; + pCopyCommand->stOutputImage.m_pSingle = pImage; + pCopyCommand->iImageX = uWidth; + pCopyCommand->iImageY = uWidth; + pCommandBuffer->AddCommand(pCopyCommand); + pCommandBuffer->Render(); + pCommandBuffer->Submit(); + return i; +} + +uint32_t CVkTextureArray::GetTextureID( const char *szPath ) +{ +} + +void CVkTextureArray::UnloadTexture( uint32_t uTextureID ) +{ + +} +void CVkTextureArray::Frame() +{ +} + + class CVkRenderContext: public IRenderContext { public: @@ -281,6 +447,7 @@ public: virtual void DestroyBuffer( IBuffer *pBuffer ) override; virtual IImage *CreateRenderTarget( uint32_t x, uint32_t y, EImageFormat eFormat, EMultisampleType eMultisampleType ) override; + virtual IImage *CreateTexture( uint32_t x, uint32_t y, EImageFormat eFormat, EMultisampleType eMultisampleType ) override; virtual IImage *CreateStorageImage( uint32_t x, uint32_t y, EImageFormat eFormat, EMultisampleType eMultisampleType ) override; virtual void DestroyImage( IImage *pImage ) override; @@ -302,6 +469,9 @@ public: virtual void RenderGameWindow( IGameWindow *pWindow ) override; virtual void RegisterGameWindow( IGameWindow *pWindow ) override; virtual void UnregisterGameWindow( IGameWindow *pWindow ) override; + + virtual ITextureArray *CreateTextureArray() override; + virtual void DestroyTextureArray() override; private: VkPhysicalDevice SelectPhysicalDevice( CUtlVector physicalDevices ); CUtlVector GetDeviceExtensions(); @@ -313,11 +483,14 @@ private: IGameWindowManager *m_pWindowManager; IVkCommandBufferManager *m_pCommandBufferManager; + IVkCommandBufferManager *m_pAssetsCommandBufferManager; CUtlVector m_renderWindows; CUtlVector m_pMaterials; + CUtlVector m_pTextureArrays; CUtlVector m_scheduledRemovalLists; + CUtlVector m_scheduledRemovalTextureArrays; CUtlVector m_scheduledRemovalBuffers; CUtlVector m_scheduledRemovalImages; }; @@ -382,6 +555,10 @@ IImage *CVkRenderContext::CreateRenderTarget( uint32_t x, uint32_t y, EImageForm else return new CVkImage(x, y, 1, eFormat, eMultisampleType, IMAGE_TYPE_2D, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT); } +IImage *CVkRenderContext::CreateTexture( uint32_t x, uint32_t y, EImageFormat eFormat, EMultisampleType eMultisampleType ) +{ + return new CVkImage(x, y, 1, eFormat, eMultisampleType, IMAGE_TYPE_2D, VK_IMAGE_USAGE_SAMPLED_BIT); +} IImage *CVkRenderContext::CreateStorageImage( uint32_t x, uint32_t y, EImageFormat eFormat, EMultisampleType eMultisampleType ) { @@ -447,7 +624,6 @@ void CVkRenderContext::SubmitCommandList(IRenderCommandList *pList) } void CVkRenderContext::RenderGameWindow( IGameWindow *pWindow ) { - } void CVkRenderContext::SetMainWindowManager( IGameWindowManager *pWindowManager ) @@ -463,9 +639,24 @@ void CVkRenderContext::RegisterGameWindow( IGameWindow *pWindow ) void CVkRenderContext::UnregisterGameWindow( IGameWindow *pWindow ) { - + } +ITextureArray *CVkRenderContext::CreateTextureArray() +{ + CVkTextureArray *pArray = new CVkTextureArray(); + pArray->m_hDevice = s_vkDevice; + pArray->m_pRenderContext = this; + pArray->m_pCommandBufferManager = m_pCommandBufferManager; + pArray->Build(); + return pArray; +} + +void CVkRenderContext::DestroyTextureArray() +{ +} + + VkPipelineLayout g_pLibraryEmptyLayout; static IVkCommandBuffer *s_pPresentCommandBuffer; @@ -576,13 +767,21 @@ void CVkRenderContext::Init() vk12Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES; vk12Features.pNext = &vk13Features; vk12Features.bufferDeviceAddress = VK_TRUE; + vk12Features.runtimeDescriptorArray = VK_TRUE; + vk12Features.descriptorBindingPartiallyBound = VK_TRUE; + vk12Features.descriptorBindingVariableDescriptorCount = VK_TRUE; + VkPhysicalDeviceVulkan11Features vk11Features = {}; + vk11Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES; + vk11Features.pNext = &vk12Features; + vk11Features.shaderDrawParameters = 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 = &vk12Features; + stDeviceCreateInfo.pNext = &vk11Features; r = vkCreateDevice(s_vkPhysicalDevice, &stDeviceCreateInfo, NULL, &s_vkDevice); VULKAN_RESULT_PRINT(r, vkEnumeratePhysicalDevices); for (auto &extension: enabledDeviceExtensions) @@ -631,6 +830,7 @@ void CVkRenderContext::Frame( float fDeltaTime ) for ( auto &m: m_pMaterials) { + m->Frame(); } i = 0; @@ -679,10 +879,11 @@ void CVkRenderContext::Frame( float fDeltaTime ) for ( auto &s: m_renderWindows ) { + CVkBlitCommand *pBlitCommand = NULL; if (s.m_pWindow->GetOutputImage()) { - pBlitCommand = CREATE_COMMAND(Blit); + pBlitCommand = CREATE_COMMAND(m_pCommandBufferManager, Blit); pBlitCommand->AddDependency(s.m_pWindow->GetOutputImage(), DEPENDENCY_MODE_BLIT_IMAGE_SOURCE); pBlitCommand->AddDependency((IRenderingObject*)s.m_images[uSwapchainImageIndexes[i]], DEPENDENCY_MODE_BLIT_IMAGE_DESTINATION); pBlitCommand->stInputImage.m_eObjectType = FRAME_OBJECT_TYPE_SINGLE; diff --git a/materialsystem/vulkan/shader.cpp b/materialsystem/vulkan/shader.cpp index e69cb1f..e0b85ea 100644 --- a/materialsystem/vulkan/shader.cpp +++ b/materialsystem/vulkan/shader.cpp @@ -70,7 +70,7 @@ void CVkShader::Build() VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT, }; VkPipelineLayoutCreateInfo stPipelineLayout = {}; - CUtlVector bindings = {}; + CUtlVector> bindings = {}; // TODO: Filter by vulkan shaders at some points stages.Resize(m_shader.m_objects.GetSize()); @@ -82,21 +82,33 @@ void CVkShader::Build() { VulkanDescriptor_t stDescriptor = ((VulkanDescriptor_t*)m_shader.GetLumpPtr(pMetaData->pDescriptorSets))[u]; bool bFound = false; - for ( auto &b: bindings ) + if (bindings.GetSize()<=stDescriptor.uSet) + bindings.Resize(stDescriptor.uSet+1); + + uint32_t i = 0; + for ( auto &set: bindings ) { - if (b.binding != stDescriptor.uBinding) - continue; - bFound = true; - break; + for ( auto &b: set ) + { + if (i != stDescriptor.uSet) + continue; + if (b.binding != stDescriptor.uBinding) + continue; + bFound = true; + break; + } + i++; + if (bFound) + break; } if (bFound) - break; + continue; VkDescriptorSetLayoutBinding bind = {}; bind.binding = stDescriptor.uBinding; - bind.descriptorCount = 1; + bind.descriptorCount = stDescriptor.uCount; bind.descriptorType = stDescriptor.eDescriptorType; bind.stageFlags = VK_SHADER_STAGE_ALL; - bindings.AppendTail(bind); + bindings[stDescriptor.uSet].AppendTail(bind); m_bindings.AppendTail(stDescriptor); } modules[i].sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; @@ -110,14 +122,19 @@ void CVkShader::Build() 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; + m_setLayouts.Reserve(bindings.GetSize()); + for ( int u = 0; u < bindings.GetSize(); u++ ) + { + VkDescriptorSetLayoutCreateInfo stSetLayoutCreateInfo = {}; + VkDescriptorSetLayout l = NULL; + stSetLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; + stSetLayoutCreateInfo.pBindings = bindings[u].GetData(); + stSetLayoutCreateInfo.bindingCount = bindings[u].GetSize(); + stSetLayoutCreateInfo.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT; + vkCreateDescriptorSetLayout(m_hDevice, &stSetLayoutCreateInfo, NULL, &l); + m_setLayouts.AppendTail(l); + } + stPipelineLayout.setLayoutCount = m_setLayouts.GetSize(); stPipelineLayout.pSetLayouts = m_setLayouts.GetData(); } diff --git a/materialsystem/vulkan/utils.cpp b/materialsystem/vulkan/utils.cpp index c3fc5df..7fc2866 100644 --- a/materialsystem/vulkan/utils.cpp +++ b/materialsystem/vulkan/utils.cpp @@ -23,8 +23,17 @@ VkAccessFlags2 VulkanGetAccessFlags( EDependencyMode eMode ) case DEPENDENCY_MODE_DRAWCALL_OUTPUT_DEPTH_IMAGE: return VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; case DEPENDENCY_MODE_COLOR_CLEAR_DESTINATION: return VK_ACCESS_2_TRANSFER_WRITE_BIT; case DEPENDENCY_MODE_IMAGE_PRESENT: return VK_ACCESS_2_NONE; - case DEPENDENCY_MODE_BLIT_IMAGE_DESTINATION: return VK_ACCESS_2_TRANSFER_WRITE_BIT; - case DEPENDENCY_MODE_BLIT_IMAGE_SOURCE: return VK_ACCESS_2_TRANSFER_READ_BIT; + + case DEPENDENCY_MODE_BLIT_IMAGE_SOURCE: + case DEPENDENCY_MODE_IMAGE_SOURCE: + case DEPENDENCY_MODE_BUFFER_SOURCE: + return VK_ACCESS_2_TRANSFER_READ_BIT; + + case DEPENDENCY_MODE_IMAGE_DESTINATION: + case DEPENDENCY_MODE_BLIT_IMAGE_DESTINATION: + case DEPENDENCY_MODE_BUFFER_DESTINATION: + return VK_ACCESS_2_TRANSFER_WRITE_BIT; + default: return VK_ACCESS_2_NONE; } @@ -39,9 +48,17 @@ VkPipelineStageFlags2 VulkanGetStageFlags( EDependencyMode eMode ) case DEPENDENCY_MODE_DRAWCALL_OUTPUT_DEPTH_IMAGE: return VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT; case DEPENDENCY_MODE_COLOR_CLEAR_DESTINATION: return VK_PIPELINE_STAGE_2_TRANSFER_BIT; case DEPENDENCY_MODE_IMAGE_PRESENT: return VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT; + case DEPENDENCY_MODE_BLIT_IMAGE_DESTINATION: case DEPENDENCY_MODE_BLIT_IMAGE_SOURCE: return VK_PIPELINE_STAGE_2_BLIT_BIT; + + case DEPENDENCY_MODE_BUFFER_SOURCE: + case DEPENDENCY_MODE_BUFFER_DESTINATION: + case DEPENDENCY_MODE_IMAGE_SOURCE: + case DEPENDENCY_MODE_IMAGE_DESTINATION: + return VK_PIPELINE_STAGE_2_COPY_BIT; + default: return VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT; } @@ -56,8 +73,14 @@ VkImageLayout VulkanGetImageLayout( EDependencyMode eMode ) case DEPENDENCY_MODE_DRAWCALL_OUTPUT_DEPTH_IMAGE: return VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL; case DEPENDENCY_MODE_COLOR_CLEAR_DESTINATION: return VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; case DEPENDENCY_MODE_IMAGE_PRESENT: return VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; - case DEPENDENCY_MODE_BLIT_IMAGE_DESTINATION: return VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - case DEPENDENCY_MODE_BLIT_IMAGE_SOURCE: return VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + case DEPENDENCY_MODE_BLIT_IMAGE_SOURCE: + case DEPENDENCY_MODE_IMAGE_SOURCE: + case DEPENDENCY_MODE_BUFFER_SOURCE: + return VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + case DEPENDENCY_MODE_BLIT_IMAGE_DESTINATION: + case DEPENDENCY_MODE_IMAGE_DESTINATION: + case DEPENDENCY_MODE_BUFFER_DESTINATION: + return VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; default: return VK_IMAGE_LAYOUT_UNDEFINED; } diff --git a/materialsystem/vulkan/vulkan_state.h b/materialsystem/vulkan/vulkan_state.h index 3b248e2..842be71 100644 --- a/materialsystem/vulkan/vulkan_state.h +++ b/materialsystem/vulkan/vulkan_state.h @@ -57,8 +57,10 @@ enum EDependencyMode DEPENDENCY_MODE_DRAWCALL_INPUT_IMAGE, DEPENDENCY_MODE_DRAWCALL_MIXED_IMAGE, + DEPENDENCY_MODE_BUFFER_SOURCE, DEPENDENCY_MODE_IMAGE_SOURCE, DEPENDENCY_MODE_IMAGE_DESTINATION, + DEPENDENCY_MODE_BUFFER_DESTINATION, DEPENDENCY_MODE_BLIT_IMAGE_SOURCE, DEPENDENCY_MODE_BLIT_IMAGE_DESTINATION, @@ -140,8 +142,8 @@ class CVkCommandRegistry public: CVkCommandRegistry( const char *szName, fnCreateVulkanCommand_t pfnCreate ); }; -#define CREATE_COMMAND(name) \ -(CVk##name##Command*)m_pCommandBufferManager->CreateCommand(#name) +#define CREATE_COMMAND(cb, name) \ +(CVk##name##Command*)cb->CreateCommand(#name) #define BEGIN_VULKAN_COMMAND( name ) \ class CVk##name##Command : public CVkCommand \ @@ -217,6 +219,7 @@ public: VmaAllocation m_allocation; VkBuffer m_buffer; + VkDescriptorType m_eDescriptorType; VkDeviceAddress m_address; uint32_t m_nSize; }; @@ -287,6 +290,27 @@ private: }; +class CVkTextureArray: public ITextureArray +{ +public: + ~CVkTextureArray(); + CVkTextureArray(); + virtual void Build() override; + virtual void SetDebugName( const char *szName ) override; + virtual uint32_t LoadTexture( const char *szPath ) override; + virtual uint32_t GetTextureID( const char *szPath ) override; + virtual void UnloadTexture( uint32_t uTextureID ) override; + void Frame(); + + uint32_t CreateTexture( uint32_t i, const char *szPath ); + + VkDevice m_hDevice; + IRenderContext *m_pRenderContext; + IVkCommandBufferManager *m_pCommandBufferManager; + VkSampler m_hSampler; + CVkImage *m_pImages[128]; +}; + class CVkMaterial: public IMaterial { public: @@ -300,9 +324,10 @@ public: virtual void PSSetShaderResource( uint32_t uRegister, IRenderingObject *pResource ) override; virtual void PSSetConstantsBuffer( uint32_t uRegister, IBuffer *pConstants ) override; + virtual void PSSetTextureArray( uint32_t uSet, ITextureArray *pArray ) override; CVkShader *m_pVkShader; - VkDescriptorSet m_hSet; + CUtlVector m_hSets; private: VkDescriptorPool m_hPool; CUtlVector m_writes = {}; diff --git a/public/materialsystem/imaterialsystem.h b/public/materialsystem/imaterialsystem.h index 352ff5c..f56ce0a 100644 --- a/public/materialsystem/imaterialsystem.h +++ b/public/materialsystem/imaterialsystem.h @@ -11,16 +11,43 @@ class IGameWindowManager; enum EImageFormat { IMAGE_FORMAT_R8_UINT, + IMAGE_FORMAT_RGB8_UINT, + IMAGE_FORMAT_RGB8_SINT, + IMAGE_FORMAT_RGB8_UNORM, + IMAGE_FORMAT_RGB8_SNORM, + IMAGE_FORMAT_RGB8_SFLOAT, + + IMAGE_FORMAT_RGB16_UINT, + IMAGE_FORMAT_RGB16_SINT, + IMAGE_FORMAT_RGB16_UNORM, + IMAGE_FORMAT_RGB16_SNORM, + IMAGE_FORMAT_RGB16_SFLOAT, + + IMAGE_FORMAT_RGB32_SFLOAT, + IMAGE_FORMAT_RGBA8_UNORM, IMAGE_FORMAT_BGRA8_UNORM, + IMAGE_FORMAT_RGBA8_UINT, IMAGE_FORMAT_RGBA8_SINT, - IMAGE_FORMAT_RGBA16_UNORM, + IMAGE_FORMAT_RGBA16_UINT, IMAGE_FORMAT_RGBA16_SINT, + IMAGE_FORMAT_RGBA16_UNORM, + IMAGE_FORMAT_RGBA16_SNORM, IMAGE_FORMAT_RGBA16_SFLOAT, + IMAGE_FORMAT_RGBA32_SFLOAT, + IMAGE_FORMAT_BC1, + IMAGE_FORMAT_BC2, + IMAGE_FORMAT_BC3, + IMAGE_FORMAT_BC4, + IMAGE_FORMAT_BC5, + IMAGE_FORMAT_BC6, + IMAGE_FORMAT_BC7, + + IMAGE_FORMAT_D32_SFLOAT, IMAGE_FORMAT_WINDOW, @@ -132,6 +159,15 @@ public: virtual EMultisampleType GetMultisampleType() = 0; }; +abstract_class ITextureArray: public IRenderingObject +{ +public: + virtual void Build() = 0; + virtual uint32_t LoadTexture( const char *szPath ) = 0; + virtual uint32_t GetTextureID( const char *szPath ) = 0; + virtual void UnloadTexture( uint32_t uTextureID ) = 0; +}; + //----------------------------------------------------------------------------- // Shader object //----------------------------------------------------------------------------- @@ -155,8 +191,7 @@ public: // Material handle // It allows to specify resources in shaders such as textures, buffers etc. // -// Resources must be updated prior to the frame, which can be done -// prior to the frame. +// Resources must be updated prior to the frame //----------------------------------------------------------------------------- abstract_class IMaterial { @@ -166,6 +201,7 @@ public: virtual void PSSetShaderResource( uint32_t uRegister, IRenderingObject *pResource ) = 0; virtual void VSSetConstantsBuffer( uint32_t uRegister, IBuffer *pImage ) = 0; virtual void PSSetConstantsBuffer( uint32_t uRegister, IBuffer *pImage ) = 0; + virtual void PSSetTextureArray( uint32_t uSet, ITextureArray *pArray ) = 0; }; abstract_class IRenderCommandList @@ -211,6 +247,7 @@ public: virtual IBuffer *CreateConstantBuffer( uint32_t nSize ) = 0; virtual IBuffer *CreateStorageBuffer( uint32_t nSize ) = 0; virtual IImage *CreateRenderTarget( uint32_t x, uint32_t y, EImageFormat eFormat, EMultisampleType eMultisampleType ) = 0; + virtual IImage *CreateTexture( uint32_t x, uint32_t y, EImageFormat eFormat, EMultisampleType eMultisampleType ) = 0; virtual IImage *CreateStorageImage( uint32_t x, uint32_t y, EImageFormat eFormat, EMultisampleType eMultisampleType ) = 0; virtual void DestroyBuffer( IBuffer *pBuffer ) = 0; @@ -231,6 +268,9 @@ public: virtual void RenderGameWindow( IGameWindow *pWindow ) = 0; virtual void RegisterGameWindow( IGameWindow *pWindow ) = 0; virtual void UnregisterGameWindow( IGameWindow *pWindow ) = 0; + + virtual ITextureArray *CreateTextureArray() = 0; + virtual void DestroyTextureArray() = 0; }; #define RENDER_CONTEXT_INTERFACE_VERSION "RenderContext001" diff --git a/public/materialsystem/vulkan_shadermeta.h b/public/materialsystem/vulkan_shadermeta.h index 256f3f0..92effcb 100644 --- a/public/materialsystem/vulkan_shadermeta.h +++ b/public/materialsystem/vulkan_shadermeta.h @@ -10,6 +10,7 @@ struct VulkanDescriptor_t VkDescriptorType eDescriptorType; uint32_t uBinding; uint32_t uSet; + uint32_t uCount; }; struct VulkanInputMetaData_t diff --git a/shadercompiler/build.cpp b/shadercompiler/build.cpp index 6b6adbe..ed95db4 100644 --- a/shadercompiler/build.cpp +++ b/shadercompiler/build.cpp @@ -57,7 +57,7 @@ DECLARE_BUILD_STAGE(shadercompiler) }; stLinkProject.objects.AppendTail({GET_PROJECT_LIBRARY(tier1, "tier1")}); stLinkProject.objects.AppendTail({GET_PROJECT_LIBRARY(tier2, "tier2")}); - stLinkProject.libraries = {"slang-compiler","slang-glslang-2025.24.2"}; + stLinkProject.libraries = {"slang-compiler","slang-glslang-2026.2.2"}; stLinkProject.libraryDirectories = {"../external/linux"}; szOutput = linker->Link(&stLinkProject); filesystem2->MakeDirectory(CUtlString("../build/tools")); @@ -65,8 +65,8 @@ DECLARE_BUILD_STAGE(shadercompiler) filesystem2->CopyFile(CUtlString("../build/tools"), GET_PROJECT_LIBRARY(tier0, "tier0")); filesystem2->CopyFile(CUtlString("../build/tools"), GET_PROJECT_LIBRARY(filesystem_std, "fs")); filesystem2->CopyFile(CUtlString("../build/tools"), GET_PROJECT_LIBRARY(libshadercompiler, "lib")); - filesystem2->CopyFile(CUtlString("../build/tools"), "../external/linux/libslang-compiler.so.0.2025.24.2"); - filesystem2->CopyFile(CUtlString("../build/tools"), "../external/linux/libslang-glslang-2025.24.2.so"); + filesystem2->CopyFile(CUtlString("../build/tools"), "../external/linux/libslang-compiler.so.0.2026.2.2"); + filesystem2->CopyFile(CUtlString("../build/tools"), "../external/linux/libslang-glslang-2026.2.2.so"); ADD_OUTPUT_OBJECT("compiler", szOutput); return 1; diff --git a/shadercompiler/main.cpp b/shadercompiler/main.cpp index dbf11fa..64943b4 100644 --- a/shadercompiler/main.cpp +++ b/shadercompiler/main.cpp @@ -19,6 +19,8 @@ void CompileShader( const char *szShader ) s_pVulkanSpirvCompiler->CompileShader(szShader, &shader); + Plat_MakeDir("../build", 0755); + Plat_MakeDir("../build/funnygame", 0755); Plat_MakeDir("../build/funnygame/assets", 0755); Plat_MakeDir("../build/funnygame/assets/shaders", 0755); diff --git a/shadercompiler/slang/vulkan_spirv.cpp b/shadercompiler/slang/vulkan_spirv.cpp index 026a4ac..158428a 100644 --- a/shadercompiler/slang/vulkan_spirv.cpp +++ b/shadercompiler/slang/vulkan_spirv.cpp @@ -76,13 +76,42 @@ void CSlangVulkanSpirvShaderCompiler::CompileShaderStage( EShaderStage eStage, c { VariableLayoutReflection *pVar = pProgramLayout->getParameterByIndex(u); input = {}; - switch(pVar->getType()->getKind()) + input.uCount = 1; + V_printf("%s %i\n", pVar->getName(), pVar->getType()->getKind()); + TypeReflection *pType = pVar->getType(); +trygetkind: + V_printf("%s %i\n", pType->getName(), pType->getKind()); + switch(pType->getKind()) { case slang::TypeReflection::Kind::ConstantBuffer: input.eDescriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; break; case slang::TypeReflection::Kind::Resource: - input.eDescriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + V_printf("%s: %i\n", pType->getName(), pType->getResourceShape()); + switch(pType->getResourceShape()) + { + case SLANG_TEXTURE_2D: + input.eDescriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; + break; + case SLANG_STRUCTURED_BUFFER: + input.eDescriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + break; + default: + break; + } + break; + case slang::TypeReflection::Kind::Array: + { + size_t uCount = pType->getTotalArrayElementCount(); + if (uCount == 0) + input.uCount = 128; + else + input.uCount = uCount; + pType = pType->getElementType(); + } + goto trygetkind; + case slang::TypeReflection::Kind::SamplerState: + input.eDescriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; break; default: break; @@ -90,6 +119,7 @@ void CSlangVulkanSpirvShaderCompiler::CompileShaderStage( EShaderStage eStage, c V_strncpy(input.szName, pVar->getName(), 32); input.uBinding = pVar->getBindingIndex(); input.uSet = pVar->getBindingSpace(); + V_printf("%i\n", input.uCount); inputs.AppendTail(input); } @@ -174,6 +204,7 @@ void CSlangVulkanSpirvShaderCompiler::CompileShader( const char *szInput, CCompi if ( szMainName == NULL ) continue; pSession = NULL; + V_printf("Cool\n"); s_pGlobalSession->createSession(stSessionDesc, &pSession); pModule = pSession->loadModuleFromSource("main", szInput, pShaderSourceBlob, &m_pDiagnostics); @@ -192,7 +223,6 @@ void CSlangVulkanSpirvShaderCompiler::CheckDiagnostics() if (m_pDiagnostics) { V_printf("%s\n",(const char*)m_pDiagnostics->getBufferPointer()); - Plat_Exit(0); } };