From b8aa36ccc0168f603c9e35c7aa42396a93835af4 Mon Sep 17 00:00:00 2001 From: kotofyt Date: Sat, 13 Jun 2026 01:51:28 +0300 Subject: [PATCH] compute shaders --- engine/openxr.cpp | 28 +++- external/GameNetworkingSockets | 2 +- external/SDL | 2 +- external/Vulkan-Headers | 2 +- external/Vulkan-Utility-Libraries | 2 +- external/VulkanMemoryAllocator | 2 +- external/funnystdlib | 2 +- external/slang | 2 +- external/stb | 2 +- external/volk | 2 +- external/xtool | 2 +- funnyassets/shaders/agx.shader | 33 ++++ funnyassets/shaders/macros.hlsl | 6 + game/client/game.cpp | 23 +-- game/client/worldrender.cpp | 37 ++++- materialsystem/build.cpp | 1 + materialsystem/vulkan/commandbuffer.cpp | 2 +- materialsystem/vulkan/commands.h | 8 +- materialsystem/vulkan/commands/base.cpp | 5 + materialsystem/vulkan/commands/draw.cpp | 37 ++--- materialsystem/vulkan/commands/transfer.cpp | 22 +++ materialsystem/vulkan/csshader.cpp | 81 ++++++++++ materialsystem/vulkan/material.cpp | 122 +++++++++++--- materialsystem/vulkan/rendercommandlist.cpp | 166 ++++++++++++-------- materialsystem/vulkan/rendercontext.cpp | 17 +- materialsystem/vulkan/vulkan_state.h | 14 +- public/materialsystem/imaterialsystem.h | 12 +- shadercompiler/slang/vulkan_spirv.cpp | 34 ++-- 28 files changed, 498 insertions(+), 170 deletions(-) create mode 100644 funnyassets/shaders/agx.shader create mode 100644 materialsystem/vulkan/csshader.cpp diff --git a/engine/openxr.cpp b/engine/openxr.cpp index 7e18338..1cf7042 100644 --- a/engine/openxr.cpp +++ b/engine/openxr.cpp @@ -68,6 +68,7 @@ public: virtual uint32_t GetHeadsetCount() override; virtual IXRHeadset *GetHeadset( uint32_t i ) override; + bool bHasXR = false; IRenderContext *m_pRenderContext; COpenXRHeadset m_headset; @@ -80,7 +81,10 @@ void COpenXRManager::Init() PFN_xrInitializeLoaderKHR fnInitLoader = NULL; XrResult r = xrGetInstanceProcAddr(NULL, "xrInitializeLoaderKHR", (PFN_xrVoidFunction*)&fnInitLoader); if (r != XR_SUCCESS) - Plat_FatalErrorFunc("Failed to load OpenXR"); + { + V_printf("Failed to load OpenXR, we are not running OpenXR\n"); + return; + } XrApplicationInfo appInfo = {}; appInfo.apiVersion = XR_API_VERSION_1_1; V_strncpy(appInfo.applicationName, "funny", XR_MAX_APPLICATION_NAME_SIZE); @@ -106,7 +110,10 @@ void COpenXRManager::Init() createInfo.enabledApiLayerNames = layers; r = xrCreateInstance(&createInfo, &m_instance); if (r != XR_SUCCESS) - Plat_FatalErrorFunc("xrCreateInstance\n"); + { + V_printf("xrCreateInstance failed, we are not running OpenXR\n"); + return; + } m_headset.m_pManager = this; m_headset.Init(); @@ -116,6 +123,8 @@ void COpenXRManager::Init() xrGetInstanceProperties(m_instance, &props); V_printf("OpenXR runtime: %s\n", props.runtimeName); + bHasXR = true; + } void COpenXRManager::Shutdown() @@ -124,21 +133,25 @@ void COpenXRManager::Shutdown() } void COpenXRManager::Frame() { - m_headset.Frame(); + if (bHasXR) + m_headset.Frame(); } void COpenXRManager::PreRender() { - m_headset.BeforeRender(); + if (bHasXR) + m_headset.BeforeRender(); } void COpenXRManager::PostRender() { - m_headset.AfterRender(); + if (bHasXR) + m_headset.AfterRender(); } void COpenXRManager::CopySwapchain() { - m_headset.CopySwapchain(); + if (bHasXR) + m_headset.CopySwapchain(); } @@ -488,6 +501,9 @@ IXRHeadset *COpenXRManager::GetHeadset( uint32_t i ) { if (i) return 0; + if(bHasXR) + return 0; + return &m_headset; } diff --git a/external/GameNetworkingSockets b/external/GameNetworkingSockets index 98d8d95..517fff0 160000 --- a/external/GameNetworkingSockets +++ b/external/GameNetworkingSockets @@ -1 +1 @@ -Subproject commit 98d8d95aa10133c6e44886d7501aaea82ee62ed9 +Subproject commit 517fff0cf6866ba163f4f016b0ef28f365c06c05 diff --git a/external/SDL b/external/SDL index 634dff3..1d08131 160000 --- a/external/SDL +++ b/external/SDL @@ -1 +1 @@ -Subproject commit 634dff3725b8419902b832d1c84363da211a3596 +Subproject commit 1d081314a89eb6bfd22bbc0224b604533ae6156b diff --git a/external/Vulkan-Headers b/external/Vulkan-Headers index 015e25c..29184b9 160000 --- a/external/Vulkan-Headers +++ b/external/Vulkan-Headers @@ -1 +1 @@ -Subproject commit 015e25c3c91b70eb1a754d36fb14c4ba6ad9b0b9 +Subproject commit 29184b98984f6169a5e83e97557a77cff1e5b0ca diff --git a/external/Vulkan-Utility-Libraries b/external/Vulkan-Utility-Libraries index 8383c46..c15a1ac 160000 --- a/external/Vulkan-Utility-Libraries +++ b/external/Vulkan-Utility-Libraries @@ -1 +1 @@ -Subproject commit 8383c46b129c2b3a5f3833e602d946d2fcc57e39 +Subproject commit c15a1ac31670cb2ce61c235f070fb40ec6e42612 diff --git a/external/VulkanMemoryAllocator b/external/VulkanMemoryAllocator index a1d4347..b3cbbb4 160000 --- a/external/VulkanMemoryAllocator +++ b/external/VulkanMemoryAllocator @@ -1 +1 @@ -Subproject commit a1d434708c217b2a6c7b365f1fe41fa03a562e59 +Subproject commit b3cbbb43ea3a506dffe10759e205a41c27c35ae2 diff --git a/external/funnystdlib b/external/funnystdlib index 6137a52..4a2e606 160000 --- a/external/funnystdlib +++ b/external/funnystdlib @@ -1 +1 @@ -Subproject commit 6137a522ac41b5f87f379d38d6959052ff467c3a +Subproject commit 4a2e606e2bf37fb1e5da2bcc4ba1d7709eee4d08 diff --git a/external/slang b/external/slang index 4cfe59c..f267cb7 160000 --- a/external/slang +++ b/external/slang @@ -1 +1 @@ -Subproject commit 4cfe59c88c5a232d501f3c2843ce1ee8e1f04dad +Subproject commit f267cb77a09b0f4cf083a9585bc1ddb3744c310a diff --git a/external/stb b/external/stb index 31c1ad3..e6cd956 160000 --- a/external/stb +++ b/external/stb @@ -1 +1 @@ -Subproject commit 31c1ad37456438565541f4919958214b6e762fb4 +Subproject commit e6cd9561ea6dae43d41633797745789d142b691e diff --git a/external/volk b/external/volk index 47cddf7..e91ceff 160000 --- a/external/volk +++ b/external/volk @@ -1 +1 @@ -Subproject commit 47cddf7ed97b94118a08aacb548a411188e016cc +Subproject commit e91ceff7db05f92ac8b498c9631235a6a73566e2 diff --git a/external/xtool b/external/xtool index e49934c..f12a84e 160000 --- a/external/xtool +++ b/external/xtool @@ -1 +1 @@ -Subproject commit e49934c1fef9c8cf401399dfb17afd93e9e82f69 +Subproject commit f12a84e960fa9bced1249a8d233ab8eafca28f6f diff --git a/funnyassets/shaders/agx.shader b/funnyassets/shaders/agx.shader new file mode 100644 index 0000000..20f2ae4 --- /dev/null +++ b/funnyassets/shaders/agx.shader @@ -0,0 +1,33 @@ +#include "macros.hlsl" + +// https://iolite-engine.com/blog_posts/minimal_agx_implementation +float3 agxDefaultContrastApprox(float3 x) { + float3 x2 = x * x; + float3 x4 = x2 * x2; + float3 x6 = x4 * x2; + + return - 17.86 * x6 * x + + 78.01 * x6 + - 126.7 * x4 * x + + 92.06 * x4 + - 28.72 * x2 * x + + 4.361 * x2 + - 0.1718 * x + + 0.002857; +} + + +CS +{ + Texture2D g_in; + RWTexture2D g_out; + + [numthreads(1,1,1)] + void csMain( int3 threadId : SV_DispatchThreadID ) + { + float4 vColor = g_in.Load(threadId); + vColor.xyz = agxDefaultContrastApprox(vColor.xyz); + g_out.Store(threadId.xy, vColor); + + } +} diff --git a/funnyassets/shaders/macros.hlsl b/funnyassets/shaders/macros.hlsl index 5c53579..8ae2d72 100644 --- a/funnyassets/shaders/macros.hlsl +++ b/funnyassets/shaders/macros.hlsl @@ -15,6 +15,12 @@ #define PS namespace PixelShader_DO_NOT_USE #endif +#ifdef CS_SHADER +#define CS using namespace ComputeShader; namespace ComputeShader +#else +#define CS namespace ComputeShader_DO_NOT_USE +#endif + #ifdef RAY_SHADER #define RAY using namespace RayShader; namespace RayShader #else diff --git a/game/client/game.cpp b/game/client/game.cpp index b35ea31..4ea18f2 100644 --- a/game/client/game.cpp +++ b/game/client/game.cpp @@ -86,17 +86,20 @@ void CFunnyGameBridge::Init() IXRHeadset *pHeadSet = g_pXRManager->GetHeadset(0); - for ( uint32_t i = 0; i < pHeadSet->GetSurfaceCount(); i++ ) + if (pHeadSet) { - XRRenderSurface_t surface = pHeadSet->GetSurface(0); - IImage *pImage = g_pRenderContext->CreateRenderTarget(surface.m_uWidth, surface.m_uHeight, IMAGE_FORMAT_RGBA8_UNORM, MULTISAMPLE_TYPE_1_SAMPLES); - pHeadSet->SetSurfaceImage(i, pImage); - IRenderCommandList *pDoSomething = g_pRenderContext->CreateCommandList(); - pDoSomething->StartRecording(); - pDoSomething->ClearImage(pImage, 1,0,0.5,1); - pDoSomething->EndRecording(); - g_pRenderContext->SubmitCommandList(pDoSomething); - g_pRenderContext->DestroyCommandList(pDoSomething); + for ( uint32_t i = 0; i < pHeadSet->GetSurfaceCount(); i++ ) + { + XRRenderSurface_t surface = pHeadSet->GetSurface(0); + IImage *pImage = g_pRenderContext->CreateRenderTarget(surface.m_uWidth, surface.m_uHeight, IMAGE_FORMAT_RGBA8_UNORM, MULTISAMPLE_TYPE_1_SAMPLES); + pHeadSet->SetSurfaceImage(i, pImage); + IRenderCommandList *pDoSomething = g_pRenderContext->CreateCommandList(); + pDoSomething->StartRecording(); + pDoSomething->ClearImage(pImage, 1,0,0.5,1); + pDoSomething->EndRecording(); + g_pRenderContext->SubmitCommandList(pDoSomething); + g_pRenderContext->DestroyCommandList(pDoSomething); + } } } diff --git a/game/client/worldrender.cpp b/game/client/worldrender.cpp index e9fa751..0eb3813 100644 --- a/game/client/worldrender.cpp +++ b/game/client/worldrender.cpp @@ -147,6 +147,7 @@ private: IImage *m_pDepthImage = NULL; IImage *m_pNormalImage = NULL; IImage *m_pWorldSpaceImage = NULL; + IImage *m_pStorageOutputImage = NULL; IRenderCommandList *m_pRasterCommandList = NULL; IBuffer *m_pViewBuffer; ViewBuffer_t *m_pViewBufferData; @@ -155,6 +156,9 @@ private: IShader *m_pRasterShader; IMaterial *m_pRasterMaterial; + IComputeShader *m_pPostProcessing; + IMaterial *m_pPostProcessingMaterial; + vec3 m_vPos; versor m_vRot; }; @@ -212,13 +216,17 @@ void CFunnyWorldRenderer::Init() IMAGE_FORMAT_D32_SFLOAT, MULTISAMPLE_TYPE_4_SAMPLES ); + m_pStorageOutputImage = g_pRenderContext->CreateStorageImage( + 100, + 100, + IMAGE_FORMAT_RGBA16_SFLOAT, + MULTISAMPLE_TYPE_1_SAMPLES + ); m_pRasterShader = g_pRenderContext->CreateShader("game/core/shaders/mesh_raster.shader_c"); ConfigureShader(m_pRasterShader); m_pRasterShader->Build(); m_pRasterMaterial = g_pRenderContext->CreateMaterial(m_pRasterShader); - g_pMainWindow->SetOutputImage(m_pResolvedOutputImage); - m_pRasterCommandList = g_pRenderContext->CreateCommandList(); m_pViewBuffer = g_pRenderContext->CreateConstantBuffer(sizeof(ViewBuffer_t)); m_pTextures = g_pRenderContext->CreateTextureArray(); @@ -226,6 +234,13 @@ void CFunnyWorldRenderer::Init() IRayTracingShader *prt = g_pRenderContext->CreateRayShader("game/core/shaders/mesh_trace.shader_c"); prt->AddShader("error", "game/core/shaders/funny_error.shader_c"); prt->Build(); + + m_pPostProcessing = g_pRenderContext->CreateComputeShader("game/core/shaders/agx.shader_c"); + m_pPostProcessing->Build(); + + m_pPostProcessingMaterial = g_pRenderContext->CreateMaterial(m_pPostProcessing); + + g_pMainWindow->SetOutputImage(m_pResolvedOutputImage); } void CFunnyWorldRenderer::Tick( float fDelta ) @@ -255,9 +270,11 @@ void CFunnyWorldRenderer::Frame( float fDelta ) if (g_pMainWindow->BRenderSizeUpdated()) { g_pRenderContext->DestroyImage(m_pOutputImage); + g_pRenderContext->DestroyImage(m_pResolvedOutputImage); g_pRenderContext->DestroyImage(m_pNormalImage); g_pRenderContext->DestroyImage(m_pWorldSpaceImage); g_pRenderContext->DestroyImage(m_pDepthImage); + g_pRenderContext->DestroyImage(m_pStorageOutputImage); m_pOutputImage = g_pRenderContext->CreateRenderTarget( g_pMainWindow->GetRenderWidth(), @@ -287,7 +304,13 @@ void CFunnyWorldRenderer::Frame( float fDelta ) g_pMainWindow->GetRenderHeight(), IMAGE_FORMAT_D32_SFLOAT, MULTISAMPLE_TYPE_4_SAMPLES); - g_pMainWindow->SetOutputImage(m_pResolvedOutputImage); + m_pStorageOutputImage = g_pRenderContext->CreateStorageImage( + g_pMainWindow->GetRenderWidth(), + g_pMainWindow->GetRenderHeight(), + IMAGE_FORMAT_RGBA16_SFLOAT, + MULTISAMPLE_TYPE_1_SAMPLES + ); + g_pMainWindow->SetOutputImage(m_pStorageOutputImage); } m_pRasterCommandList->StartRecording(); m_pRasterCommandList->SetRenderResolution(uWidth, uHeight); @@ -329,6 +352,7 @@ void CFunnyWorldRenderer::Frame( float fDelta ) pDataBuffer->Unmap(); pDataBuffer->Unlock(); g_pRenderContext->DestroyBuffer(pDataBuffer); + m_pRasterMaterial->VSSetConstantsBuffer(0, m_pViewBuffer); m_pRasterMaterial->VSSetConstantsBuffer(1, pDataBuffer); m_pRasterMaterial->PSSetTextureArray(1, m_pTextures); @@ -345,6 +369,13 @@ void CFunnyWorldRenderer::Frame( float fDelta ) } m_pRasterCommandList->ResolveImage(m_pOutputImage, m_pResolvedOutputImage); + + m_pPostProcessingMaterial->CSSetTexture(0, 0, m_pResolvedOutputImage); + m_pPostProcessingMaterial->CSSetTexture(1, 0, m_pStorageOutputImage); + m_pRasterCommandList->SetMaterial(m_pPostProcessingMaterial); + m_pRasterCommandList->Barrier(m_pResolvedOutputImage, true, false); + m_pRasterCommandList->Barrier(m_pStorageOutputImage, false, true); + m_pRasterCommandList->DispatchCompute(uWidth, uHeight, 1); m_pRasterCommandList->EndRecording(); g_pRenderContext->SubmitCommandList(m_pRasterCommandList); diff --git a/materialsystem/build.cpp b/materialsystem/build.cpp index 697560c..d4be6b4 100644 --- a/materialsystem/build.cpp +++ b/materialsystem/build.cpp @@ -27,6 +27,7 @@ CUtlVector RenderContextVulkan_CompiledFiles = { "vulkan/vma.cpp", "vulkan/rtlinker.cpp", "vulkan/rtlinker_gen.cpp", + "vulkan/csshader.cpp", "vulkan/commands/draw.cpp", "vulkan/commands/transfer.cpp", "vulkan/commands/base.cpp", diff --git a/materialsystem/vulkan/commandbuffer.cpp b/materialsystem/vulkan/commandbuffer.cpp index 2108cfb..d9cd7e1 100644 --- a/materialsystem/vulkan/commandbuffer.cpp +++ b/materialsystem/vulkan/commandbuffer.cpp @@ -373,7 +373,7 @@ public: private: VkDevice m_hDevice; - CUtlVector m_commands; + CUtlVector m_commands = {}; }; EXPOSE_INTERFACE(CVkCommandBufferManager, IVkCommandBufferManager, VULKAN_COMMAND_BUFFER_MANAGER_INTERFACE_NAME); diff --git a/materialsystem/vulkan/commands.h b/materialsystem/vulkan/commands.h index 8804c57..d099235 100644 --- a/materialsystem/vulkan/commands.h +++ b/materialsystem/vulkan/commands.h @@ -7,6 +7,12 @@ BEGIN_VULKAN_COMMAND(Empty) END_VULKAN_COMMAND(Empty) +BEGIN_VULKAN_COMMAND(Dispatch) + uint32_t uX = 0; + uint32_t uY = 0; + uint32_t uZ = 0; +END_VULKAN_COMMAND(Dispatch) + BEGIN_VULKAN_COMMAND(Blit) VkFrameObject_t stInputImage; VkFrameObject_t stOutputImage; @@ -43,7 +49,7 @@ BEGIN_VULKAN_COMMAND(SetVertexBuffer) END_VULKAN_COMMAND(SetVertexBuffer) BEGIN_VULKAN_COMMAND(SetShader) - IShader *pShader; + IBaseShader *pShader; END_VULKAN_COMMAND(SetShader) BEGIN_VULKAN_COMMAND(SetShaderData) diff --git a/materialsystem/vulkan/commands/base.cpp b/materialsystem/vulkan/commands/base.cpp index ad32b80..c57ed76 100644 --- a/materialsystem/vulkan/commands/base.cpp +++ b/materialsystem/vulkan/commands/base.cpp @@ -5,3 +5,8 @@ DECLARE_VULKAN_COMMAND(Empty) { } + +DECLARE_VULKAN_COMMAND(Dispatch) +{ + vkCmdDispatch(hCommandBuffer, uX, uY, uZ); +} diff --git a/materialsystem/vulkan/commands/draw.cpp b/materialsystem/vulkan/commands/draw.cpp index 66299d2..49f33e8 100644 --- a/materialsystem/vulkan/commands/draw.cpp +++ b/materialsystem/vulkan/commands/draw.cpp @@ -76,13 +76,22 @@ DECLARE_VULKAN_COMMAND(End) DECLARE_VULKAN_COMMAND(SetShader) { - CVkShader *pVkShader = (CVkShader*)pShader; - vkCmdBindPipeline(hCommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pVkShader->m_hPipeline); + CVkShader *pS = dynamic_cast(pShader); + CVkComputeShader *pCS = dynamic_cast(pShader); + if (pS) + vkCmdBindPipeline(hCommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pS->m_hPipeline); + if (pCS) + vkCmdBindPipeline(hCommandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pCS->m_hPipeline); } DECLARE_VULKAN_COMMAND(SetShaderData) { CVkMaterial *pMat = (CVkMaterial*)pShaderData; - vkCmdBindDescriptorSets(hCommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pMat->m_pVkShader->m_hPipelineLayout, 0, pMat->m_hSets.GetSize(), pMat->m_hSets.GetData(), 0, 0 ); + CVkShader *pS = dynamic_cast(pMat->m_pShader); + CVkComputeShader *pCS = dynamic_cast(pMat->m_pShader); + if (pS) + vkCmdBindDescriptorSets(hCommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pS->m_hPipelineLayout, 0, pMat->m_hSets.GetSize(), pMat->m_hSets.GetData(), 0, 0 ); + if (pCS) + vkCmdBindDescriptorSets(hCommandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pCS->m_hPipelineLayout, 0, pMat->m_hSets.GetSize(), pMat->m_hSets.GetData(), 0, 0 ); } DECLARE_VULKAN_COMMAND(SetVertexBuffer) @@ -153,24 +162,4 @@ DECLARE_VULKAN_COMMAND(ResolveImage) }; vkCmdResolveImage2(hCommandBuffer, &i); } -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/commands/transfer.cpp b/materialsystem/vulkan/commands/transfer.cpp index d719b9f..6b27416 100644 --- a/materialsystem/vulkan/commands/transfer.cpp +++ b/materialsystem/vulkan/commands/transfer.cpp @@ -33,3 +33,25 @@ DECLARE_VULKAN_COMMAND(Blit) vkCmdBlitImage(hCommandBuffer, pVkInputImage->m_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, pVkOutputImage->m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &stBlit, VK_FILTER_NEAREST); } + +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/csshader.cpp b/materialsystem/vulkan/csshader.cpp new file mode 100644 index 0000000..0e75f0a --- /dev/null +++ b/materialsystem/vulkan/csshader.cpp @@ -0,0 +1,81 @@ +#include "vulkan_state.h" + +void CVkComputeShader::Build() +{ + VkPipelineShaderStageCreateInfo stage = {}; + VkShaderModuleCreateInfo mod = {}; + ShaderObject_t *s = m_shader.FindShaderObject(SHADER_BACKEND_SPIRV_VULKAN, SHADER_STAGE_COMPUTE); + VulkanInputMetaData_t *pMetaData = (VulkanInputMetaData_t*)m_shader.GetLumpPtr(s->m_nMetadataLump); + VkPipelineLayoutCreateInfo stPipelineLayout = {}; + CUtlVector> bindings = {}; + + for ( int u = 0; u < pMetaData->nDescriptorsCount; u++ ) + { + VulkanDescriptor_t stDescriptor = ((VulkanDescriptor_t*)m_shader.GetLumpPtr(pMetaData->pDescriptorSets))[u]; + bool bFound = false; + if (bindings.GetSize()<=stDescriptor.uSet) + bindings.Resize(stDescriptor.uSet+1); + + uint32_t i = 0; + for ( auto &set: bindings ) + { + for ( auto &b: set ) + { + if (i != stDescriptor.uSet) + continue; + if (b.binding != stDescriptor.uBinding) + continue; + bFound = true; + break; + } + i++; + if (bFound) + break; + } + if (bFound) + continue; + VkDescriptorSetLayoutBinding bind = {}; + bind.binding = stDescriptor.uBinding; + bind.descriptorCount = stDescriptor.uCount; + bind.descriptorType = stDescriptor.eDescriptorType; + bind.stageFlags = VK_SHADER_STAGE_ALL; + bindings[stDescriptor.uSet].AppendTail(bind); + m_bindings.AppendTail(stDescriptor); + } + mod.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; + mod.pCode = (uint32_t*)m_shader.GetLumpPtr(s->m_nDataLump); + mod.codeSize = m_shader.GetLumpSize(s->m_nDataLump); + stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + stage.pNext = &mod; + stage.pName = "main"; + stage.stage = VK_SHADER_STAGE_COMPUTE_BIT; + + if ( bindings.GetSize() >= 0 ) + { + 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(); + } + + stPipelineLayout.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + vkCreatePipelineLayout(m_hDevice, &stPipelineLayout, NULL, &m_hPipelineLayout); + + VkComputePipelineCreateInfo ci = {}; + ci.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO; + ci.layout = m_hPipelineLayout; + ci.stage = stage; + + vkCreateComputePipelines(m_hDevice, NULL, 1, &ci, NULL, &m_hPipeline); + +} diff --git a/materialsystem/vulkan/material.cpp b/materialsystem/vulkan/material.cpp index c172b34..43377ae 100644 --- a/materialsystem/vulkan/material.cpp +++ b/materialsystem/vulkan/material.cpp @@ -1,44 +1,78 @@ #include "vulkan_state.h" -CVkMaterial::CVkMaterial( IShader *pShader ) +CVkMaterial::CVkMaterial( IBaseShader *pShader ) { - m_pVkShader = (CVkShader*)pShader; - if ( m_pVkShader->m_setLayouts.GetSize() == 0 ) - return; + VkDevice hDevice = NULL; - VkDescriptorPoolSize pools[4] = + CVkShader *pS = dynamic_cast(pShader); + CVkComputeShader *pCS = dynamic_cast(pShader); + if ( pS ) + { + if (pS->m_setLayouts.GetSize() == 0 ) + return; + hDevice = pS->m_hDevice; + } + if (pCS) + { + hDevice = pCS->m_hDevice; + } + + VkDescriptorPoolSize pools[5] = { { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - 128, + 1024, }, { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, - 128, + 1024, + }, + { + VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, + 1024, }, { VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, - 128, + 1024, }, { VK_DESCRIPTOR_TYPE_SAMPLER, - 1, + 1024, } }; VkDescriptorPoolCreateInfo stPool = {}; stPool.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; - stPool.poolSizeCount = 4; + stPool.poolSizeCount = 5; stPool.pPoolSizes = pools; stPool.maxSets = 16; stPool.flags = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT; - vkCreateDescriptorPool(m_pVkShader->m_hDevice, &stPool, NULL, &m_hPool); + vkCreateDescriptorPool(hDevice, &stPool, NULL, &m_hPool); - VkDescriptorSetAllocateInfo stInfo = {}; - stInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; - stInfo.descriptorPool = m_hPool; - stInfo.descriptorSetCount = m_pVkShader->m_setLayouts.GetSize(); - stInfo.pSetLayouts = m_pVkShader->m_setLayouts.GetData(); - m_hSets.Resize(m_pVkShader->m_setLayouts.GetSize()); - vkAllocateDescriptorSets(m_pVkShader->m_hDevice, &stInfo, m_hSets.GetData()); + + if ( pS ) + { + VkDescriptorSetAllocateInfo stInfo = {}; + stInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; + stInfo.descriptorPool = m_hPool; + stInfo.descriptorSetCount = pS->m_setLayouts.GetSize(); + stInfo.pSetLayouts = pS->m_setLayouts.GetData(); + m_hSets.Resize(pS->m_setLayouts.GetSize()); + VkResult r = vkAllocateDescriptorSets(hDevice, &stInfo, m_hSets.GetData()); + VULKAN_RESULT_PRINT(r, vkAllocateDescriptorSets); + } + + if ( pCS ) + { + VkDescriptorSetAllocateInfo stInfo = {}; + stInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; + stInfo.descriptorPool = m_hPool; + stInfo.descriptorSetCount = pCS->m_setLayouts.GetSize(); + stInfo.pSetLayouts = pCS->m_setLayouts.GetData(); + m_hSets.Resize(pCS->m_setLayouts.GetSize()); + VkResult r = vkAllocateDescriptorSets(hDevice, &stInfo, m_hSets.GetData()); + VULKAN_RESULT_PRINT(r, vkAllocateDescriptorSets); + } + + m_pShader = pShader; } CVkMaterial::~CVkMaterial() @@ -86,11 +120,49 @@ void CVkMaterial::PSSetSampler( uint32_t uRegister, ISampler *pImage ) SetShaderResource(uRegister, 0, pImage); } +void CVkMaterial::CSSetConstantsBuffer( uint32_t uRegister, uint32_t uSet, IBuffer *pBuffer ) +{ + SetShaderResource(uRegister, uSet, pBuffer); + +} + +void CVkMaterial::CSSetTexture( uint32_t uRegister, uint32_t uSet, IImage *pImage ) +{ + SetShaderResource(uRegister, uSet, pImage); + +} + +void CVkMaterial::CSSetSampler( uint32_t uRegister, uint32_t uSet, ISampler *pSampler ) +{ + SetShaderResource(uRegister, uSet, pSampler); + +} + +void CVkMaterial::CSSetTextureArray( uint32_t uSet, ITextureArray *pArray ) +{ + SetShaderResource(0, uSet, pArray); + +} + + void CVkMaterial::SetShaderResource( uint32_t uRegister, uint32_t uSet, IRenderingObject *pObject) { - if ( m_pVkShader->m_setLayouts.GetSize() == 0 ) - return; + VkDevice hDevice; + CVkShader *pShader = dynamic_cast(m_pShader); + CVkComputeShader *pCS = dynamic_cast(m_pShader); + if ( pShader ) + { + if (pShader->m_setLayouts.GetSize() == 0 ) + return; + hDevice = pShader->m_hDevice; + } + if (pCS) + { + if (pCS->m_setLayouts.GetSize() == 0 ) + return; + hDevice = pCS->m_hDevice; + } union { IRenderingObject *pVkObject; CVkBuffer *pBuffer; @@ -112,7 +184,7 @@ void CVkMaterial::SetShaderResource( uint32_t uRegister, uint32_t uSet, IRenderi write.pBufferInfo = &stInfo; stInfo.buffer = pBuffer->m_buffer; stInfo.range = pBuffer->m_nSize; - vkUpdateDescriptorSets(m_pVkShader->m_hDevice, 1, &write, 0, 0); + vkUpdateDescriptorSets(hDevice, 1, &write, 0, 0); } if (dynamic_cast(pObject)) { @@ -122,12 +194,12 @@ void CVkMaterial::SetShaderResource( uint32_t uRegister, uint32_t uSet, IRenderi write.dstSet = m_hSets[uSet]; write.dstBinding = uRegister; write.dstArrayElement = 0; - write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; + write.descriptorType = pImage->m_eDescriptorType; write.descriptorCount = 1; write.pImageInfo = &stInfo; stInfo.imageView = pImage->m_imageView; stInfo.imageLayout = VK_IMAGE_LAYOUT_GENERAL; - vkUpdateDescriptorSets(m_pVkShader->m_hDevice, 1, &write, 0, 0); + vkUpdateDescriptorSets(hDevice, 1, &write, 0, 0); } if (dynamic_cast(pObject)) @@ -142,7 +214,7 @@ void CVkMaterial::SetShaderResource( uint32_t uRegister, uint32_t uSet, IRenderi write.descriptorCount = 1; write.pImageInfo = &stInfo; stInfo.sampler = pSampler->m_sampler; - vkUpdateDescriptorSets(m_pVkShader->m_hDevice, 1, &write, 0, 0); + vkUpdateDescriptorSets(hDevice, 1, &write, 0, 0); } if (dynamic_cast(pObject)) { @@ -184,7 +256,7 @@ void CVkMaterial::SetShaderResource( uint32_t uRegister, uint32_t uSet, IRenderi 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(hDevice, 2, writes, 0, 0); } } diff --git a/materialsystem/vulkan/rendercommandlist.cpp b/materialsystem/vulkan/rendercommandlist.cpp index 5010633..b0c0583 100644 --- a/materialsystem/vulkan/rendercommandlist.cpp +++ b/materialsystem/vulkan/rendercommandlist.cpp @@ -89,50 +89,69 @@ void CVkRenderCommandList::SetViewport( uint32_t uX, uint32_t uY, uint32_t uWidt 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(m_pCommandBufferManager, Begin); - pBeginCommand->images = m_pOutput; - pBeginCommand->nResolutionX = m_uWidth; - pBeginCommand->nResolutionY = m_uHeight; - for ( auto &i: pBeginCommand->images) - { - pBeginCommand->AddDependency(i.m_stImage.m_pSingle, DEPENDENCY_MODE_DRAWCALL_MIXED_IMAGE); - } - if ( m_bDepthEnabled ) - { - pBeginCommand->AddDependency(m_depth.m_stImage.m_pSingle, DEPENDENCY_MODE_DRAWCALL_OUTPUT_DEPTH_IMAGE); - pBeginCommand->bDepthEnabled = m_bDepthEnabled; - pBeginCommand->stDepthImage = m_depth; + CVkMaterial *pVkMat = (CVkMaterial*)pMaterial; + CVkComputeShader *pCS = dynamic_cast(pVkMat->m_pShader); - } - m_pCurrentMaterialBuffer->AddCommand(pBeginCommand); + if (pCS) + { + SwitchRenderingStage(RENDERING_STAGE_POST_RASTER); CVkSetShaderCommand *pSetShader = CREATE_COMMAND(m_pCommandBufferManager, SetShader); - pSetShader->pShader = ((CVkMaterial*)pMaterial)->m_pVkShader; - m_pCurrentMaterialBuffer->AddCommand(pSetShader); + pSetShader->pShader = pCS; + m_pPostRaster->AddCommand(pSetShader); CVkSetShaderDataCommand *pSetShaderData = CREATE_COMMAND(m_pCommandBufferManager, SetShaderData); pSetShaderData->pShaderData = pMaterial; - m_pCurrentMaterialBuffer->AddCommand(pSetShaderData); + m_pPostRaster->AddCommand(pSetShaderData); + } + else + { + SwitchRenderingStage(RENDERING_STAGE_SETUP_RASTER); + bool bWasCreated = false; + m_pCurrentMaterialBuffer = FindOrCreateMaterialCommandBuffer(pMaterial, &bWasCreated); + if (bWasCreated) + { + m_pCurrentMaterialBuffer->Reset(); + CVkBeginCommand *pBeginCommand = CREATE_COMMAND(m_pCommandBufferManager, Begin); + pBeginCommand->images = m_pOutput; + pBeginCommand->nResolutionX = m_uWidth; + pBeginCommand->nResolutionY = m_uHeight; + for ( auto &i: pBeginCommand->images) + { + pBeginCommand->AddDependency(i.m_stImage.m_pSingle, DEPENDENCY_MODE_DRAWCALL_MIXED_IMAGE); + } + if ( m_bDepthEnabled ) + { + pBeginCommand->AddDependency(m_depth.m_stImage.m_pSingle, DEPENDENCY_MODE_DRAWCALL_OUTPUT_DEPTH_IMAGE); + pBeginCommand->bDepthEnabled = m_bDepthEnabled; + pBeginCommand->stDepthImage = m_depth; - CVkSetScissorsCommand *pScissorsCommand = CREATE_COMMAND(m_pCommandBufferManager, SetScissors); - pScissorsCommand->uWidth = m_uWidth; - pScissorsCommand->uHeight = m_uHeight; - m_pCurrentMaterialBuffer->AddCommand(pScissorsCommand); + } + m_pCurrentMaterialBuffer->AddCommand(pBeginCommand); + + CVkSetShaderCommand *pSetShader = CREATE_COMMAND(m_pCommandBufferManager, SetShader); + pSetShader->pShader = ((CVkMaterial*)pMaterial)->m_pShader; + m_pCurrentMaterialBuffer->AddCommand(pSetShader); + + CVkSetShaderDataCommand *pSetShaderData = CREATE_COMMAND(m_pCommandBufferManager, SetShaderData); + pSetShaderData->pShaderData = pMaterial; + m_pCurrentMaterialBuffer->AddCommand(pSetShaderData); + + CVkSetScissorsCommand *pScissorsCommand = CREATE_COMMAND(m_pCommandBufferManager, SetScissors); + pScissorsCommand->uWidth = m_uWidth; + pScissorsCommand->uHeight = m_uHeight; + m_pCurrentMaterialBuffer->AddCommand(pScissorsCommand); + + CVkSetViewportCommand *pViewportCommand = CREATE_COMMAND(m_pCommandBufferManager, SetViewport); + pViewportCommand->fX = 0; + pViewportCommand->fY = 0; + pViewportCommand->fWidth = m_uWidth; + pViewportCommand->fHeight = m_uHeight; + pViewportCommand->fDepthMin = 0; + pViewportCommand->fDepthMax = 1; + m_pCurrentMaterialBuffer->AddCommand(pViewportCommand); + } - CVkSetViewportCommand *pViewportCommand = CREATE_COMMAND(m_pCommandBufferManager, SetViewport); - pViewportCommand->fX = 0; - pViewportCommand->fY = 0; - pViewportCommand->fWidth = m_uWidth; - pViewportCommand->fHeight = m_uHeight; - pViewportCommand->fDepthMin = 0; - pViewportCommand->fDepthMax = 1; - m_pCurrentMaterialBuffer->AddCommand(pViewportCommand); } } @@ -160,34 +179,8 @@ void CVkRenderCommandList::DrawPrimitives( uint32_t nVertexCount, uint32_t nFirs pCmd->nFirstVertex = nFirstVertex; pCmd->nInstanceCount = nInstanceCount; pCmd->nFirstInstance = nFirstInstance; - for ( auto &b: m_barriers ) - { - if (dynamic_cast(b.pObject)) - { - if (b.m_bIsRead) - if (b.m_bIsWrite) - pCmd->AddDependency(b.pObject, DEPENDENCY_MODE_SHADER_BUFFER_READ_WRITE); - else - pCmd->AddDependency(b.pObject, DEPENDENCY_MODE_SHADER_BUFFER_READ); - else - if (b.m_bIsWrite) - pCmd->AddDependency(b.pObject, DEPENDENCY_MODE_SHADER_BUFFER_WRITE); + FlushBarriers(pCmd); - } - if (dynamic_cast(b.pObject)) - { - if (b.m_bIsRead) - if (b.m_bIsWrite) - pCmd->AddDependency(b.pObject, DEPENDENCY_MODE_SHADER_IMAGE_READ_WRITE); - else - pCmd->AddDependency(b.pObject, DEPENDENCY_MODE_SHADER_IMAGE_READ); - else - if (b.m_bIsWrite) - pCmd->AddDependency(b.pObject, DEPENDENCY_MODE_SHADER_IMAGE_WRITE); - - } - } - m_barriers = {}; m_pCurrentMaterialBuffer->AddCommand(pCmd); } @@ -278,6 +271,18 @@ void CVkRenderCommandList::Barrier( IRenderingObject *pObject, bool bIsRead, boo { m_barriers.AppendTail({pObject, bIsRead, bIsWrite}); } +void CVkRenderCommandList::DispatchCompute( uint32_t uX, uint32_t uY, uint32_t uZ ) +{ + SwitchRenderingStage(RENDERING_STAGE_POST_RASTER); + + CVkDispatchCommand *pCmd = CREATE_COMMAND(m_pCommandBufferManager, Dispatch); + pCmd->uX = uX; + pCmd->uY = uY; + pCmd->uZ = uZ; + FlushBarriers(pCmd); + m_pPostRaster->AddCommand(pCmd); + +} void CVkRenderCommandList::Submit() { @@ -287,6 +292,38 @@ void CVkRenderCommandList::Submit() } } +void CVkRenderCommandList::FlushBarriers( CVkCommand *pCmd ) +{ + for ( auto &b: m_barriers ) + { + if (dynamic_cast(b.pObject)) + { + if (b.m_bIsRead) + if (b.m_bIsWrite) + pCmd->AddDependency(b.pObject, DEPENDENCY_MODE_SHADER_BUFFER_READ_WRITE); + else + pCmd->AddDependency(b.pObject, DEPENDENCY_MODE_SHADER_BUFFER_READ); + else + if (b.m_bIsWrite) + pCmd->AddDependency(b.pObject, DEPENDENCY_MODE_SHADER_BUFFER_WRITE); + + } + if (dynamic_cast(b.pObject)) + { + if (b.m_bIsRead) + if (b.m_bIsWrite) + pCmd->AddDependency(b.pObject, DEPENDENCY_MODE_SHADER_IMAGE_READ_WRITE); + else + pCmd->AddDependency(b.pObject, DEPENDENCY_MODE_SHADER_IMAGE_READ); + else + if (b.m_bIsWrite) + pCmd->AddDependency(b.pObject, DEPENDENCY_MODE_SHADER_IMAGE_WRITE); + + } + } + m_barriers = {}; +} + void CVkRenderCommandList::SwitchRenderingStage( EVulkanRenderingStage eStage ) { if (eStage != RENDERING_STAGE_RASTER) @@ -300,7 +337,7 @@ void CVkRenderCommandList::SwitchRenderingStage( EVulkanRenderingStage eStage ) } m_materials = {}; }; - if (eStage == RENDERING_STAGE_POST_RASTER) + if (eStage == RENDERING_STAGE_POST_RASTER ) { if (m_eCurrentStage != RENDERING_STAGE_POST_RASTER) { @@ -314,6 +351,7 @@ void CVkRenderCommandList::SwitchRenderingStage( EVulkanRenderingStage eStage ) { m_pPostRaster->Render(); m_pCommandBuffers.AppendTail(m_pPostRaster); + m_pPostRaster = NULL; } } m_eCurrentStage = eStage; diff --git a/materialsystem/vulkan/rendercontext.cpp b/materialsystem/vulkan/rendercontext.cpp index e02ce88..482dcdc 100644 --- a/materialsystem/vulkan/rendercontext.cpp +++ b/materialsystem/vulkan/rendercontext.cpp @@ -202,6 +202,11 @@ void CVkImage::CreateImage( uint32_t nWidth, uint32_t nHeight, EImageFormat eFor stAlloc.usage = VMA_MEMORY_USAGE_AUTO; + if (eUsage & VK_IMAGE_USAGE_SAMPLED_BIT) + m_eDescriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; + if (eUsage & VK_IMAGE_USAGE_STORAGE_BIT) + m_eDescriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; + vmaCreateImage(s_vkAllocator, &stCreateInfo, &stAlloc, &m_image, &m_allocation, NULL); } @@ -475,7 +480,7 @@ public: virtual IComputeShader *CreateComputeShader( const char *szName ) override; virtual void DestroyShader( IBaseShader *pShader ) override; - virtual IMaterial *CreateMaterial( IShader *pShader ) override; + virtual IMaterial *CreateMaterial( IBaseShader *pShader ) override; virtual void DestroyMaterial( IMaterial *pMaterial ) override; virtual IRenderCommandList *CreateCommandList() override; @@ -609,6 +614,7 @@ void CVkRenderContext::DestroyBuffer( IBuffer *pBuffer ) void CVkRenderContext::DestroyImage( IImage *pImage ) { + m_scheduledRemovalImages.AppendTail((CVkImage*)pImage); } @@ -617,7 +623,6 @@ IShader *CVkRenderContext::CreateShader( const char *szName ) CVkShader *pShader = new CVkShader(); - VkGraphicsPipelineCreateInfo stPipelineCreateInfo = {}; ICompiledShaderManager *pCompiledShaderManager = (ICompiledShaderManager*)CreateInterface(COMPILED_SHADER_MANAGER_INTERFACE_VERSION, NULL); pCompiledShaderManager->ReadFromFile(&pShader->m_shader, szName); pShader->m_hDevice = s_vkDevice; @@ -627,7 +632,6 @@ IShader *CVkRenderContext::CreateShader( const char *szName ) IRayTracingShader *CVkRenderContext::CreateRayShader( const char *szName ) { CVkRayTracingShader *pShader = new CVkRayTracingShader(); - VkGraphicsPipelineCreateInfo stPipelineCreateInfo = {}; ICompiledShaderManager *pCompiledShaderManager = (ICompiledShaderManager*)CreateInterface(COMPILED_SHADER_MANAGER_INTERFACE_VERSION, NULL); pCompiledShaderManager->ReadFromFile(&pShader->m_shader, szName); pShader->m_hDevice = s_vkDevice; @@ -636,6 +640,11 @@ IRayTracingShader *CVkRenderContext::CreateRayShader( const char *szName ) IComputeShader *CVkRenderContext::CreateComputeShader( const char *szName ) { + CVkComputeShader *pShader = new CVkComputeShader; + ICompiledShaderManager *pCompiledShaderManager = (ICompiledShaderManager*)CreateInterface(COMPILED_SHADER_MANAGER_INTERFACE_VERSION, NULL); + pCompiledShaderManager->ReadFromFile(&pShader->m_shader, szName); + pShader->m_hDevice = s_vkDevice; + return pShader; } void CVkRenderContext::DestroyShader( IBaseShader *pShader ) @@ -643,7 +652,7 @@ void CVkRenderContext::DestroyShader( IBaseShader *pShader ) delete pShader; } -IMaterial *CVkRenderContext::CreateMaterial( IShader *pShader ) +IMaterial *CVkRenderContext::CreateMaterial( IBaseShader *pShader ) { CVkMaterial *pMaterial = new CVkMaterial(pShader); m_pMaterials.AppendTail(pMaterial); diff --git a/materialsystem/vulkan/vulkan_state.h b/materialsystem/vulkan/vulkan_state.h index 286b150..4a575bd 100644 --- a/materialsystem/vulkan/vulkan_state.h +++ b/materialsystem/vulkan/vulkan_state.h @@ -208,6 +208,7 @@ public: VkImageLayout m_eImageLayout = VK_IMAGE_LAYOUT_UNDEFINED; EDependencyMode m_eLastUsage = DEPENDENCY_MODE_JUST_CREATED; + VkDescriptorType m_eDescriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; }; class CVkBuffer: public IBuffer @@ -310,8 +311,6 @@ class CVkComputeShader : public IComputeShader { public: virtual void Build() override; - void BuildCompute(); - void BuildTrace(); VkDevice m_hDevice; CCompiledShader m_shader; @@ -383,7 +382,7 @@ public: class CVkMaterial: public IMaterial { public: - CVkMaterial( IShader *pShader ); + CVkMaterial( IBaseShader *pShader ); virtual ~CVkMaterial() override; void Frame(); @@ -398,7 +397,12 @@ public: virtual void PSSetTexture( uint32_t uRegister, IImage *pImage ) override; virtual void PSSetSampler( uint32_t uRegister, ISampler *pImage ) override; - CVkShader *m_pVkShader; + virtual void CSSetConstantsBuffer( uint32_t uRegister, uint32_t uSet, IBuffer *pBuffer ) override; + virtual void CSSetTexture( uint32_t uRegister, uint32_t uSet, IImage *pImage ) override; + virtual void CSSetSampler( uint32_t uRegister, uint32_t uSet, ISampler *pSampler ) override; + virtual void CSSetTextureArray( uint32_t uSet, ITextureArray *pArray ) override; + + IBaseShader *m_pShader; CUtlVector m_hSets; private: VkDescriptorPool m_hPool; @@ -490,6 +494,7 @@ public: virtual void EndRecording() override; virtual void Barrier( IRenderingObject *pObject, bool bIsRead, bool bIsWrite ) override; + virtual void DispatchCompute( uint32_t uX, uint32_t uY, uint32_t uZ ) override; virtual void CopyImageToImage( IImage *pSrc, IImage *pDst ) override; virtual void BlitImageToImage( IImage *pSrc, ImageSector_t src, IImage *pDst, ImageSector_t dst ) override; @@ -497,6 +502,7 @@ public: virtual void ClearDepth( IImage *pImage, float fVal ) override; void Submit(); + void FlushBarriers( CVkCommand *pCmd ); IVkCommandBufferManager *m_pCommandBufferManager; private: diff --git a/public/materialsystem/imaterialsystem.h b/public/materialsystem/imaterialsystem.h index 11faefc..c95761b 100644 --- a/public/materialsystem/imaterialsystem.h +++ b/public/materialsystem/imaterialsystem.h @@ -253,12 +253,18 @@ abstract_class IMaterial public: virtual ~IMaterial() = default; virtual void VSSetShaderResource( uint32_t uRegister, IRenderingObject *pResource ) = 0; - virtual void PSSetShaderResource( uint32_t uRegister, IRenderingObject *pResource ) = 0; virtual void VSSetConstantsBuffer( uint32_t uRegister, IBuffer *pImage ) = 0; + + virtual void PSSetShaderResource( uint32_t uRegister, IRenderingObject *pResource ) = 0; virtual void PSSetConstantsBuffer( uint32_t uRegister, IBuffer *pImage ) = 0; virtual void PSSetTextureArray( uint32_t uSet, ITextureArray *pArray ) = 0; virtual void PSSetTexture( uint32_t uRegister, IImage *pImage ) = 0; virtual void PSSetSampler( uint32_t uRegister, ISampler *pImage ) = 0; + + virtual void CSSetConstantsBuffer( uint32_t uRegister, uint32_t uSet, IBuffer *pBuffer ) = 0; + virtual void CSSetTexture( uint32_t uRegister, uint32_t uSet, IImage *pImage ) = 0; + virtual void CSSetSampler( uint32_t uRegister, uint32_t uSet, ISampler *pSampler ) = 0; + virtual void CSSetTextureArray( uint32_t uSet, ITextureArray *pArray ) = 0; }; struct ImageSector_t @@ -298,11 +304,11 @@ public: virtual void EndRecording() = 0; virtual void Barrier( IRenderingObject *pObject, bool bIsRead, bool bIsWrite ) = 0; - virtual void CopyImageToImage( IImage *pSrc, IImage *pDst ) = 0; virtual void BlitImageToImage( IImage *pSrc, ImageSector_t src, IImage *pDst, ImageSector_t dst ) = 0; virtual void ClearImage( IImage *pImage, float fR, float fG, float fB, float fA ) = 0; virtual void ClearDepth( IImage *pImage, float fVal ) = 0; + virtual void DispatchCompute( uint32_t uX, uint32_t uY, uint32_t uZ ) = 0; }; //----------------------------------------------------------------------------- @@ -331,7 +337,7 @@ public: virtual IComputeShader *CreateComputeShader( const char *szName ) = 0; virtual void DestroyShader( IBaseShader *pMaterial ) = 0; - virtual IMaterial *CreateMaterial( IShader *pShader ) = 0; + virtual IMaterial *CreateMaterial( IBaseShader *pShader ) = 0; virtual void DestroyMaterial( IMaterial *pMaterial ) = 0; virtual IRenderCommandList *CreateCommandList() = 0; diff --git a/shadercompiler/slang/vulkan_spirv.cpp b/shadercompiler/slang/vulkan_spirv.cpp index 87f6487..d295074 100644 --- a/shadercompiler/slang/vulkan_spirv.cpp +++ b/shadercompiler/slang/vulkan_spirv.cpp @@ -63,6 +63,9 @@ void CSlangVulkanSpirvShaderCompiler::CompileShaderStage( EShaderStage eStage, c case SHADER_STAGE_PIXEL: eSlangStage = SLANG_STAGE_PIXEL; break; + case SHADER_STAGE_COMPUTE: + eSlangStage = SLANG_STAGE_COMPUTE; + break; case SHADER_STAGE_RAYGEN: eSlangStage = SLANG_STAGE_RAY_GENERATION; break; @@ -100,25 +103,22 @@ trygetkind: case slang::TypeReflection::Kind::ConstantBuffer: input.eDescriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; break; - //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::Resource: //V_printf("%s: %i\n", pType->getName(), pType->getResourceShape()); switch(pType->getResourceShape()) { case SLANG_TEXTURE_2D: - input.eDescriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; + switch (pType->getResourceAccess()) + { + case SLANG_RESOURCE_ACCESS_READ: + input.eDescriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; + break; + case SLANG_RESOURCE_ACCESS_READ_WRITE: + input.eDescriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; + break; + default: + break; + } break; case SLANG_STRUCTURED_BUFFER: input.eDescriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; @@ -131,7 +131,7 @@ trygetkind: { size_t uCount = pType->getTotalArrayElementCount(); if (uCount == 0) - input.uCount = 128; + input.uCount = 1024; else input.uCount = uCount; pType = pType->getElementType(); @@ -245,6 +245,10 @@ void CSlangVulkanSpirvShaderCompiler::CompileShader( const char *szInput, CCompi szMainName = "psMain"; stStageMacroDesc[0] = { "PS_SHADER", "Enabled" }; break; + case SHADER_STAGE_COMPUTE: + szMainName = "csMain"; + stStageMacroDesc[0] = { "CS_SHADER", "Enabled" }; + break; case SHADER_STAGE_RAYGEN: szMainName = "rayMain"; stStageMacroDesc[0] = { "RAY_SHADER", "Enabled" };