diff --git a/build.cpp b/build.cpp index 6bbfab3..c7fb5f4 100755 --- a/build.cpp +++ b/build.cpp @@ -10,8 +10,9 @@ ADD_DEPENDENCY_BUILD_FILE(engine, "engine/build.cpp"); ADD_DEPENDENCY_BUILD_FILE(ms, "materialsystem/build.cpp"); ADD_DEPENDENCY_BUILD_FILE(fs, "external/funnystdlib/stdfilesystems/build.cpp"); ADD_DEPENDENCY_BUILD_FILE(tier0, "external/funnystdlib/tier0/build.cpp"); +ADD_DEPENDENCY_BUILD_FILE(fsc, "shadercompiler/build.cpp"); -DECLARE_BUILD_STAGE(install) +DECLARE_BUILD_STAGE(install_game) { filesystem2->MakeDirectory(szOutputDir); filesystem2->CopyFile(szOutputDir, GET_PROJECT_OBJECT(launcher, "launcher")); @@ -20,8 +21,7 @@ DECLARE_BUILD_STAGE(install) filesystem2->CopyFile(szOutputDir, GET_PROJECT_OBJECT(RenderSystemVulkan, "RenderSystemVulkan")); filesystem2->CopyFile(szOutputDir, GET_PROJECT_OBJECT(tier0, "tier0")); filesystem2->CopyFile(szOutputDir, GET_PROJECT_OBJECT(filesystem_std, "fs")); - if (Target_t::DefaultTarget().kernel & TARGET_KERNEL_WINDOWS_DEVICES) - { - } + filesystem2->CopyFile(szOutputDir, GET_PROJECT_OBJECT(shadercompiler, "fs")); + filesystem2->CopyDirectory(CUtlString("%s/core",szOutputDir.GetString()), "build/funnygame/assets/shaders"); return 0; } diff --git a/engine/__build.cpp b/engine/__build.cpp deleted file mode 100644 index 14b95e8..0000000 --- a/engine/__build.cpp +++ /dev/null @@ -1,65 +0,0 @@ -#include "helper.h" -#include "c.h" -#include "ld.h" -#include "tier1/utlstring.h" - -CUtlVector engine_CompiledFiles = { - "engine/engine.cpp", - "engine/cvar.cpp", - "engine/filesystem_pak.cpp", - - "engine/gamewindow_sdl.cpp", - - "engine/sv_dll.cpp", - "engine/cl_dll.cpp", -}; - -CUtlVector engine_Libraries = { - "c", - "SDL3", -}; - -DECLARE_BUILD_STAGE(engine) -{ - CProject_t compileProject = {}; - LinkProject_t ldProject = {}; - - compileProject.m_szName = "engine"; - compileProject.files = engine_CompiledFiles; - compileProject.includeDirectories = {"public"}; - compileProject.bFPIC = true; - ldProject = ccompiler->Compile(&compileProject); - - /* - if (bStaticBuild) - ldProject.linkType = ELINK_STATIC_LIBRARY; - else - { - ldProject.objects.AppendTail((Object_t){tier1_lib}); - ldProject.objects.AppendTail((Object_t){tier2_lib}); - ldProject.objects.AppendTail((Object_t){rapier_lib}); - ldProject.objects.AppendTail((Object_t){material_lib}); - if (bSteam) - ldProject.objects.AppendTail((Object_t){steam_lib}); - } - */ - ldProject.linkType = ELINK_DYNAMIC_LIBRARY; - - - ldProject.libraries = engine_Libraries; - CUtlString szOutputDir = linker->Link(&ldProject); - - /* - if (!bStaticBuild) - { - */ - filesystem2->MakeDirectory(CUtlString("%s/bin",szOutputDir.GetString())); - filesystem2->CopyFile(CUtlString("%s/bin", szOutputDir.GetString()), szOutputDir); - /* - } else { - engine_lib = outputProject; - } - */ - - return 0; -}; diff --git a/engine/build.cpp b/engine/build.cpp index 52fe9d7..a30ae4b 100644 --- a/engine/build.cpp +++ b/engine/build.cpp @@ -11,11 +11,6 @@ ADD_DEPENDENCY_BUILD_FILE(tier2, FUNNYSTDLIB"tier2/build.cpp"); DECLARE_BUILD_STAGE(engine) { - bool bUsesSDL = true; - if (Target_t::DefaultTarget().cpu == TARGET_CPU_WASM32) - { - bUsesSDL = false; - } CProject_t compileProject = {}; LinkProject_t ldProject = {}; @@ -27,8 +22,6 @@ DECLARE_BUILD_STAGE(engine) "sv_dll.cpp", "cl_dll.cpp", }; - if (bUsesSDL) - compileProject.files.AppendTail("gamewindow_sdl.cpp"); compileProject.includeDirectories = { "../public", @@ -46,8 +39,6 @@ DECLARE_BUILD_STAGE(engine) ldProject.objects.AppendTail({GET_PROJECT_LIBRARY(tier1, "tier1")}); ldProject.objects.AppendTail({GET_PROJECT_LIBRARY(tier2, "tier2")}); - if (bUsesSDL) - ldProject.libraries.AppendTail("SDL3"); if (ldProject.m_target.kernel & TARGET_KERNEL_WINDOWS_DEVICES) { ldProject.libraryDirectories = {"../external/windows"}; diff --git a/engine/engine.cpp b/engine/engine.cpp index 8a5cfbb..87c202a 100644 --- a/engine/engine.cpp +++ b/engine/engine.cpp @@ -1,6 +1,6 @@ #include "tier2/ifilesystem.h" -#include "igamewindow.h" +#include "materialsystem/igamewindow.h" #include "materialsystem/imaterialsystem.h" #include "tier1/interface.h" #include "tier0/commandline.h" @@ -9,21 +9,34 @@ IRenderContext *g_pRenderContext; IFileSystem *filesystem; +IGameWindowManager *g_pWindowManager; extern "C" void FunnyMain( int argc, char **argv ) { CommandLine()->CreateCommandLine(argc, argv); CreateInterfaceFn pFilesystemFactory = Sys_GetFactory("filesystem_std"); + CreateInterfaceFn pMaterialSystemFactory = Sys_GetFactory("MaterialSystem"); + CreateInterfaceFn pRenderSystemFactory = Sys_GetFactory("RenderSystemVulkan"); filesystem = (IFileSystem*)pFilesystemFactory(FILESYSTEM_INTERFACE_VERSION, NULL); filesystem->Init(); - CreateInterfaceFn pMaterialSystemFactory = Sys_GetFactory("MaterialSystem"); - CreateInterfaceFn pRenderSystemFactory = Sys_GetFactory("RenderSystemVulkan"); + g_pWindowManager = (IGameWindowManager*)pRenderSystemFactory(GAME_WINDOW_MANAGER_INTERFACE_VERSION, NULL); + V_printf("%s\n", GAME_WINDOW_MANAGER_INTERFACE_VERSION); + g_pWindowManager->Init(); + + IGameWindow *pWindow = g_pWindowManager->CreateWindow(); + pWindow->Init(); + + g_pRenderContext = (IRenderContext*)pRenderSystemFactory(RENDER_CONTEXT_INTERFACE_VERSION, NULL); + g_pRenderContext->SetMainWindowManager(g_pWindowManager); g_pRenderContext->Init(); + g_pRenderContext->RegisterGameWindow(pWindow); + + ServerGameDLL()->Init(); IShader *pShader = NULL; @@ -33,54 +46,68 @@ extern "C" void FunnyMain( int argc, char **argv ) IImage *pOutputImage = NULL; IVertexBuffer *pVertices = NULL; - float vertices[9] = { - 0,-0.5, 0.5, - 0.5,0.5, 0.5, - -0.5,0.5, 0.5, + float vertices[18] = { + -0.5, -0.5, 0, + 0.5, -0.5, 0, + -0.5, 0.5, 0, + -0.5, 0.5, 0, + 0.5, -0.5, 0, + 0.5, 0.5, 0 + }; - pVertices = g_pRenderContext->CreateVertexBuffer(36); + pVertices = g_pRenderContext->CreateVertexBuffer(72); void *pMapped = pVertices->Map(); - V_memcpy(pMapped, vertices, 36); + V_memcpy(pMapped, vertices, 72); pVertices->Unmap(); pCameraInfoBuffer = g_pRenderContext->CreateConstantBuffer(64); - /* - pShader = g_pRenderContext->CreateShader("funnygame/core/shaders/flat.shader_c"); + pShader = g_pRenderContext->CreateShader("game/core/shaders/flat.shader_c"); + pShader->AddLayout(0, 12); + pShader->AddAttribute(0, 0, VERTEX_FORMAT_XYZ32_SFLOAT, 0); + pShader->AddOutputImage(0, IMAGE_FORMAT_RGBA8_UNORM); + pShader->Build(); pMaterial = g_pRenderContext->CreateMaterial(pShader); pMaterial->PSSetConstantsBuffer(0, pCameraInfoBuffer); - */ - + pOutputImage = g_pRenderContext->CreateRenderTarget( - 1280, - 720, + 100, + 100, IMAGE_FORMAT_RGBA8_UNORM, MULTISAMPLE_TYPE_NONE); - IRenderCommandList *pCommandList = g_pRenderContext->CreateCommandList(); - pCommandList->StartRecording(); - pCommandList->SetRenderTarget(0, pOutputImage); - pCommandList->SetClearColor(0, 1,0,0,0); - pCommandList->EndRecording(); for (;;) { - /* - if (g_pRenderContext->BIsOutputImageOutdated()) + g_pWindowManager->Frame(0); + if (pWindow->BRenderSizeUpdated()) { - uint32_t nWidth; - uint32_t nHeight; + g_pRenderContext->DestroyImage(pOutputImage); pOutputImage = g_pRenderContext->CreateRenderTarget( - g_pRenderContext->GetNewOutputImageWidth(), - g_pRenderContext->GetNewOutputImageHeight(), + pWindow->GetRenderWidth(), + pWindow->GetRenderHeight(), IMAGE_FORMAT_RGBA8_UNORM, MULTISAMPLE_TYPE_NONE); } - */ + + IRenderCommandList *pCommandList = g_pRenderContext->CreateCommandList(); + pCommandList->StartRecording(); + + pCommandList->SetRenderResolution(pWindow->GetRenderWidth(), pWindow->GetRenderHeight()); + pCommandList->SetRenderTarget(0, pOutputImage); + pCommandList->SetClearColor(0, 0, 0, 0, 0); + + pCommandList->SetMaterial(pMaterial); + pCommandList->SetVertexBuffer(0, pVertices); + pCommandList->DrawPrimitives(6, 0, 1, 0); + + pCommandList->EndRecording(); + pWindow->SetOutputImage(pOutputImage); g_pRenderContext->SubmitCommandList(pCommandList); g_pRenderContext->Frame(0); + g_pRenderContext->DestroyCommandList(pCommandList); }; }; diff --git a/funnyassets/shaders/flat.shader b/funnyassets/shaders/flat.shader index 7a9ee69..2559580 100644 --- a/funnyassets/shaders/flat.shader +++ b/funnyassets/shaders/flat.shader @@ -22,11 +22,6 @@ COMMON } VS { - cbuffer CameraInfo - { - float4x4 m_viewProj; - }; - struct VS_INPUT { float3 m_vPosition: POSITION; diff --git a/materialsystem/build.cpp b/materialsystem/build.cpp index 7571ac1..4b92a9b 100644 --- a/materialsystem/build.cpp +++ b/materialsystem/build.cpp @@ -27,6 +27,7 @@ CUtlVector RenderContextVulkan_CompiledFiles = { "vulkan/commands/base.cpp", "vulkan/libraries/raster.cpp", "../external/volk/volk.c", + "gamewindow_sdl.cpp" }; DECLARE_BUILD_STAGE(MaterialSystem) @@ -87,6 +88,7 @@ DECLARE_BUILD_STAGE(RenderSystemVulkan) { ldProject.libraries.AppendTail("pthread"); }; + ldProject.libraries.AppendTail("SDL3"); CUtlString outputProject = linker->Link(&ldProject); ADD_OUTPUT_OBJECT("RenderSystemVulkan", outputProject); diff --git a/materialsystem/compiledshader.cpp b/materialsystem/compiledshader.cpp index 2736ce4..def163a 100644 --- a/materialsystem/compiledshader.cpp +++ b/materialsystem/compiledshader.cpp @@ -1,5 +1,6 @@ #include "shadercompiler/icompiler.h" #include "materialsystem/compiledshadermgr.h" +#include "tier0/lib.h" #include "tier2/ifilesystem.h" uint32_t CCompiledShader::AllocateLump( uint32_t nSize ) @@ -31,10 +32,10 @@ ShaderObject_t *CCompiledShader::FindShaderObject( EShaderBackend eBackend, ESha { if ( o.m_eBackend != eBackend ) continue; - + if ( o.m_eStage != eStage ) continue; - + return &o; } return NULL; @@ -43,8 +44,6 @@ ShaderObject_t *CCompiledShader::FindShaderObject( EShaderBackend eBackend, ESha CCompiledShader::~CCompiledShader() { - for ( auto l: m_lumps ) - V_free(l.m_pAddress); } @@ -73,11 +72,10 @@ void CCompiledShaderManager::WriteToFile( CCompiledShader *pShader, const char * { CreateInterfaceFn pFilesystemFactory = Sys_GetFactory("filesystem_std"); filesystem = (IFileSystem*)pFilesystemFactory(FILESYSTEM_INTERFACE_VERSION, NULL); - } pFile = filesystem->Open(szFile, FILEMODE_WRITE); filesystem->Write(pFile, &stHeader, sizeof(ShaderHeader_t)); - + // We want to get offset for the lump data nTotalSize += sizeof(ShaderLump_t) * pShader->m_lumps.GetSize(); nTotalSize += sizeof(ShaderObject_t) * pShader->m_objects.GetSize(); @@ -95,9 +93,9 @@ void CCompiledShaderManager::WriteToFile( CCompiledShader *pShader, const char * } // ShaderObject_t - for ( auto o: pShader->m_objects ) { + filesystem->Write(pFile, &o, sizeof(o)); } @@ -120,8 +118,14 @@ void CCompiledShaderManager::ReadFromFile( CCompiledShader *pShader, const char CUtlVector objects = {}; CUtlVector lumpsData = {}; + if ( filesystem == NULL ) + { + CreateInterfaceFn pFilesystemFactory = Sys_GetFactory("filesystem_std"); + filesystem = (IFileSystem*)pFilesystemFactory(FILESYSTEM_INTERFACE_VERSION, NULL); + } pFile = filesystem->Open(szFile, FILEMODE_READ); - filesystem->Read(pFile, &stHeader, sizeof(ShaderHeader_t)); + uint32_t u = filesystem->Read(pFile, &stHeader, sizeof(ShaderHeader_t)); + V_printf("Read %s %s\n", szFile, Plat_GetWorkingDir()); objects.Resize(stHeader.m_nNumShaders); lumps.Resize(stHeader.m_nNumLumps); @@ -140,7 +144,7 @@ void CCompiledShaderManager::ReadFromFile( CCompiledShader *pShader, const char pShader->m_objects = objects; pShader->m_lumps = lumpsData; - + filesystem->Close(pFile); } @@ -150,3 +154,4 @@ ICompiledShaderManager *CompiledShaderManager() static CCompiledShaderManager s_CompiledShaderManager; return &s_CompiledShaderManager; } +EXPOSE_INTERFACE_FN(CompiledShaderManager, ICompiledShaderManager, COMPILED_SHADER_MANAGER_INTERFACE_VERSION) diff --git a/engine/gamewindow_sdl.cpp b/materialsystem/gamewindow_sdl.cpp similarity index 65% rename from engine/gamewindow_sdl.cpp rename to materialsystem/gamewindow_sdl.cpp index 0d5154d..e4b25eb 100644 --- a/engine/gamewindow_sdl.cpp +++ b/materialsystem/gamewindow_sdl.cpp @@ -1,5 +1,5 @@ #include "SDL3/SDL_error.h" -#include "igamewindow.h" +#include "materialsystem/igamewindow.h" #include "tier0/lib.h" #include "tier0/platform.h" #include "tier1/interface.h" @@ -17,28 +17,39 @@ class CSDLGameWindow: public IGameWindow public: virtual void Init() override; virtual void Shutdown() override; - virtual void Tick( float fDelta ) override; virtual void Frame( float fDelta ) override; + virtual uint32_t GetRenderWidth() override; virtual uint32_t GetRenderHeight() override; + virtual bool BRenderSizeUpdated() override; + + virtual void SetOutputImage( IImage *pImage ) override; + virtual IImage *GetOutputImage() override; virtual void *CreateVulkanSurface( void *pInstance ) override; virtual void DestroyVulkanSurface( void *pInstance ) override; + + SDL_WindowID WindowID(); + + bool m_bWindowSizeUpdated; + uint32_t m_uRenderWidth; + uint32_t m_uRenderHeight; + private: VkSurfaceKHR m_hSurface; SDL_Window *m_pWindow; + IImage *m_pOutputImage; }; void CSDLGameWindow::Init() { - if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS | SDL_INIT_GAMEPAD)) - Plat_FatalErrorFunc("SDL_Init: %s\n", SDL_GetError()); - m_pWindow = SDL_CreateWindow("funnygame", 1280, 720, SDL_WINDOW_VULKAN | SDL_WINDOW_RESIZABLE); if (!m_pWindow) Plat_FatalErrorFunc("SDL_CreateWindow: %s\n", SDL_GetError()); + m_uRenderWidth = 1280; + m_uRenderWidth = 720; } void CSDLGameWindow::Shutdown() @@ -48,37 +59,35 @@ void CSDLGameWindow::Shutdown() void CSDLGameWindow::Frame( float fDelta ) { - SDL_Event event; - while (SDL_PollEvent(&event)) - { - switch (event.type) - { - case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED: - break; - case SDL_EVENT_QUIT: - SDL_Quit(); - Plat_Exit(0); - break; - default: - break; - } - } } -void CSDLGameWindow::Tick( float fDelta ) -{ - -}; uint32_t CSDLGameWindow::GetRenderWidth() { - return 0; + return m_uRenderWidth; } uint32_t CSDLGameWindow::GetRenderHeight() { - return 0; + return m_uRenderHeight; } +bool CSDLGameWindow::BRenderSizeUpdated() +{ + return m_bWindowSizeUpdated; +} + +void CSDLGameWindow::SetOutputImage( IImage *pImage ) +{ + m_pOutputImage = pImage; +} + +IImage *CSDLGameWindow::GetOutputImage() +{ + return m_pOutputImage; + +} + + void *CSDLGameWindow::CreateVulkanSurface( void *pInstance ) { @@ -90,12 +99,16 @@ void CSDLGameWindow::DestroyVulkanSurface( void *pInstance ) { SDL_Vulkan_DestroySurface((VkInstance)pInstance, (VkSurfaceKHR)m_hSurface, NULL); } +SDL_WindowID CSDLGameWindow::WindowID() +{ + + return SDL_GetWindowID(m_pWindow); +} class CSDLGameWindowManager: public IGameWindowManager { - +public: virtual void Init() override; - virtual void Tick( float fDelta ) override; virtual void Frame( float fDelta ) override; virtual void Shutdown() override; @@ -104,21 +117,56 @@ class CSDLGameWindowManager: public IGameWindowManager virtual int GetVulkanInstanceExtensionCount() override; virtual const char **GetVulkanInstanceExtensions() override; +private: + CUtlVector m_pWindows; }; +IGameWindowManager *GameWindowManager() +{ + static CSDLGameWindowManager mgr; + return &mgr; +} +EXPOSE_INTERFACE_FN(GameWindowManager, IGameWindowManager, GAME_WINDOW_MANAGER_INTERFACE_VERSION) + void CSDLGameWindowManager::Init() { - -} - -void CSDLGameWindowManager::Tick( float fDelta ) -{ - + if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS | SDL_INIT_GAMEPAD)) + Plat_FatalErrorFunc("SDL_Init: %s\n", SDL_GetError()); } void CSDLGameWindowManager::Frame( float fDelta ) { + SDL_Event event; + CSDLGameWindow *pWindow; + pWindow = NULL; + for (auto a: m_pWindows) + { + a->m_bWindowSizeUpdated = false; + } + while (SDL_PollEvent(&event)) + { + switch (event.type) + { + case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED: + for (auto a: m_pWindows) + { + if (a->WindowID() != event.window.windowID) + break; + pWindow = a; + break; + } + pWindow->m_bWindowSizeUpdated = true; + pWindow->m_uRenderWidth = event.window.data1; + pWindow->m_uRenderHeight = event.window.data2; + break; + case SDL_EVENT_QUIT: + Plat_Exit(0); + break; + default: + break; + } + } } void CSDLGameWindowManager::Shutdown() @@ -129,12 +177,14 @@ void CSDLGameWindowManager::Shutdown() IGameWindow *CSDLGameWindowManager::CreateWindow() { - + CSDLGameWindow *pWindow = new CSDLGameWindow; + m_pWindows.AppendTail(pWindow); + return pWindow; } void CSDLGameWindowManager::DestroyWindow( IGameWindow* pWindow ) { - + delete (CSDLGameWindow*)pWindow; } diff --git a/materialsystem/materialsystem.cpp b/materialsystem/materialsystem.cpp index 461d99a..58c5524 100644 --- a/materialsystem/materialsystem.cpp +++ b/materialsystem/materialsystem.cpp @@ -1,5 +1,5 @@ #include "materialsystem/imaterialsystem.h" -#include "igamewindow.h" +#include "materialsystem/igamewindow.h" class CMaterialSystem: public IMaterialSystem { diff --git a/materialsystem/vulkan/commandbuffer.cpp b/materialsystem/vulkan/commandbuffer.cpp index 8d8cd0f..60ec347 100644 --- a/materialsystem/vulkan/commandbuffer.cpp +++ b/materialsystem/vulkan/commandbuffer.cpp @@ -4,9 +4,6 @@ #include "tier1/utlvector.h" #include "vulkan_state.h" -CUtlVector g_vkCommandBuffers; -IVkCommandBufferManager *g_pCommandBufferManager; - struct VulkanCommandLastUsage_t { uint32_t m_nLastUsedCommand; @@ -24,6 +21,7 @@ struct VulkanSwapchainCommandLastUsage_t class CVkCommandBuffer: public IVkCommandBuffer { public: + virtual void SetVulkanHandlers( VkDevice hDevice, IVkCommandBufferManager *pManager ) override; virtual void AddCommand( CVkCommand *pCommand ) override; virtual void Reset() override; virtual void Submit( int iFrameIndex ) override; @@ -39,25 +37,34 @@ private: CUtlVector> m_dependencies; CUtlVector m_usedSwapchainDependencies; CUtlVector> m_swapchainDependencies; + + VkDevice m_hDevice; + IVkCommandBufferManager *m_pMgr; + VkCommandPool m_hPool; }; +void CVkCommandBuffer::SetVulkanHandlers( VkDevice hDevice, IVkCommandBufferManager *pManager ) +{ + m_hDevice = hDevice; + m_pMgr = pManager; +} + void CVkCommandBuffer::Reset() { VkCommandBufferAllocateInfo commandBufferAllocInfo = {}; - int i = 0; + VkCommandPoolCreateInfo stCreateInfo = {}; + stCreateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; + stCreateInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; + vkCreateCommandPool(m_hDevice, &stCreateInfo, NULL, &m_hPool); m_hBuffers = {}; - m_hBuffers.Resize(g_vkCommandPools.GetSize()); + m_hBuffers.Resize(FRAMES_IN_FLIGHT); - for ( auto pool: g_vkCommandPools) - { - commandBufferAllocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; - commandBufferAllocInfo.commandPool = pool; - commandBufferAllocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; - commandBufferAllocInfo.commandBufferCount = 1; - vkAllocateCommandBuffers(g_vkDevice, &commandBufferAllocInfo, &m_hBuffers[i]); - i++; - } + commandBufferAllocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; + commandBufferAllocInfo.commandPool = m_hPool; + commandBufferAllocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; + commandBufferAllocInfo.commandBufferCount = FRAMES_IN_FLIGHT; + vkAllocateCommandBuffers(m_hDevice, &commandBufferAllocInfo, m_hBuffers.GetData()); m_commands = {}; } @@ -69,7 +76,7 @@ void CVkCommandBuffer::AddCommand( CVkCommand *pCommand ) void CVkCommandBuffer::Submit( int iFrameIndex ) { - g_vkCommandBuffers.AppendTail(m_hBuffers[iFrameIndex]); + m_pMgr->GetVulkanCommands().AppendTail(m_hBuffers[iFrameIndex]); }; struct VulkanBarrierObjects_t @@ -332,8 +339,15 @@ class CVkCommandBufferManager: public IVkCommandBufferManager public: virtual void Init() override; virtual void Shutdown() override; + virtual void SetVulkanHandlers( VkInstance hInstance, VkDevice hDevice ) override; virtual IVkCommandBuffer *CreateCommandBuffer() override; virtual CVkCommand *CreateCommand( const char *szName ) override; + virtual CUtlVector &GetVulkanCommands() override; + virtual void RenderingFinished() override; +private: + + VkDevice m_hDevice; + CUtlVector m_commands; }; EXPOSE_INTERFACE(CVkCommandBufferManager, IVkCommandBufferManager, VULKAN_COMMAND_BUFFER_MANAGER_INTERFACE_NAME); @@ -348,9 +362,17 @@ void CVkCommandBufferManager::Shutdown() } +void CVkCommandBufferManager::SetVulkanHandlers( VkInstance hInstance, VkDevice hDevice ) +{ + m_hDevice = hDevice; +} + + IVkCommandBuffer *CVkCommandBufferManager::CreateCommandBuffer() { - return new CVkCommandBuffer; + IVkCommandBuffer *pBuffer = new CVkCommandBuffer; + pBuffer->SetVulkanHandlers(m_hDevice, this); + return pBuffer; } @@ -373,6 +395,17 @@ CVkCommand *CVkCommandBufferManager::CreateCommand( const char *szName ) return NULL; } +CUtlVector &CVkCommandBufferManager::GetVulkanCommands() +{ + return m_commands; +} + +void CVkCommandBufferManager::RenderingFinished() +{ + m_commands = {}; +} + + CVkCommandRegistry::CVkCommandRegistry( const char *szName, fnCreateVulkanCommand_t pfnCreate ) { VulkanCommandRegistry_t *pCommand = new VulkanCommandRegistry_t; diff --git a/materialsystem/vulkan/commands/draw.cpp b/materialsystem/vulkan/commands/draw.cpp index 60d5d3e..7636731 100644 --- a/materialsystem/vulkan/commands/draw.cpp +++ b/materialsystem/vulkan/commands/draw.cpp @@ -38,7 +38,10 @@ DECLARE_VULKAN_COMMAND(Begin) a.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO; a.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; a.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - a.clearValue.color.float32[1] = 1; + a.clearValue.color.float32[0] = i.m_fClearColor[0]; + a.clearValue.color.float32[1] = i.m_fClearColor[1]; + a.clearValue.color.float32[2] = i.m_fClearColor[2]; + a.clearValue.color.float32[3] = i.m_fClearColor[3]; a.storeOp = VK_ATTACHMENT_STORE_OP_STORE; a.imageView = ((CVkImage*)VulkanGetObject(i.m_stImage, iCurrentFrame))->m_imageView; attachments.AppendTail(a); diff --git a/materialsystem/vulkan/libraries/raster.cpp b/materialsystem/vulkan/libraries/raster.cpp index 1dccd69..d50ca80 100644 --- a/materialsystem/vulkan/libraries/raster.cpp +++ b/materialsystem/vulkan/libraries/raster.cpp @@ -8,7 +8,7 @@ BEGIN_BUILD_PIPELINE_LIBRARY(VertexDescription) library.flags = VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT; - + VkPipelineVertexInputStateCreateInfo vertexInput = {}; VkPipelineInputAssemblyStateCreateInfo inputAssembly = {}; @@ -81,8 +81,8 @@ BEGIN_BUILD_PIPELINE_LIBRARY(VertexTransform) inits[i].m_set.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; inits[i].m_set.bindingCount = inits[i].m_bindings.GetSize(); inits[i].m_set.pBindings = inits[i].m_bindings.GetData(); - - vkCreateDescriptorSetLayout(g_vkDevice, &inits[i].m_set, NULL, &m_setLayouts[i] ); + + vkCreateDescriptorSetLayout(m_hDevice, &inits[i].m_set, NULL, &m_setLayouts[i] ); } for ( i = 0; i < SHADER_STAGE_COUNT; i++) @@ -92,6 +92,7 @@ BEGIN_BUILD_PIPELINE_LIBRARY(VertexTransform) CUtlBuffer code = ShaderParser()->GetShaderCode(m_pShader, (EShaderStage)i); + // We may fail loading the specific stage if (code.GetSize() == 0) continue; @@ -105,7 +106,7 @@ BEGIN_BUILD_PIPELINE_LIBRARY(VertexTransform) shader.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; shader.pName = "main"; shader.stage = VulkanGetShaderStage((EShaderStage)i); - + spirvs.AppendTail(code); stageShaders.AppendTail(mod); stages.AppendTail(shader); @@ -125,11 +126,13 @@ BEGIN_BUILD_PIPELINE_LIBRARY(VertexTransform) stPipelineLayout.pSetLayouts = m_setLayouts; */ stPipelineLayout.flags = VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT ; - vkCreatePipelineLayout(g_vkDevice, &stPipelineLayout, NULL, &m_layout); + vkCreatePipelineLayout(m_hDevice, &stPipelineLayout, NULL, &m_layout); rasterState.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; rasterState.polygonMode = VK_POLYGON_MODE_FILL; rasterState.lineWidth = 1; + rasterState.cullMode = VK_CULL_MODE_NONE; + rasterState.frontFace = VK_FRONT_FACE_CLOCKWISE; viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; @@ -156,7 +159,7 @@ void CVkVertexTransformPipelineLibrary::SetShader( CCompiledShader *pShader ) BEGIN_BUILD_PIPELINE_LIBRARY(PixelShader) printf("--- PixelShader ---\n"); - + VkPipelineDepthStencilStateCreateInfo depthStencil = {}; VkPipelineRenderingCreateInfo render = {}; int i = 0; @@ -175,10 +178,10 @@ BEGIN_BUILD_PIPELINE_LIBRARY(PixelShader) inits[i].m_set.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; inits[i].m_set.bindingCount = inits[i].m_bindings.GetSize(); inits[i].m_set.pBindings = inits[i].m_bindings.GetData(); - - vkCreateDescriptorSetLayout(g_vkDevice, &inits[i].m_set, NULL, &m_setLayouts[i] ); + + vkCreateDescriptorSetLayout(m_hDevice, &inits[i].m_set, NULL, &m_setLayouts[i] ); } - + VkPipelineLayoutCreateInfo stPipelineLayout = {}; stPipelineLayout.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; /* @@ -186,7 +189,7 @@ BEGIN_BUILD_PIPELINE_LIBRARY(PixelShader) stPipelineLayout.pSetLayouts = m_setLayouts; */ stPipelineLayout.flags = VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT ; - vkCreatePipelineLayout(g_vkDevice, &stPipelineLayout, NULL, &m_layout); + vkCreatePipelineLayout(m_hDevice, &stPipelineLayout, NULL, &m_layout); CUtlBuffer spirv = {}; VkPipelineShaderStageCreateInfo shader = {}; @@ -204,8 +207,8 @@ BEGIN_BUILD_PIPELINE_LIBRARY(PixelShader) inits[i].m_set.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; inits[i].m_set.bindingCount = inits[i].m_bindings.GetSize(); inits[i].m_set.pBindings = inits[i].m_bindings.GetData(); - - vkCreateDescriptorSetLayout(g_vkDevice, &inits[i].m_set, NULL, &m_setLayouts[i] ); + + vkCreateDescriptorSetLayout(m_hDevice, &inits[i].m_set, NULL, &m_setLayouts[i] ); } spirv = ShaderParser()->GetShaderCode(m_pShader, SHADER_STAGE_PIXEL); @@ -257,25 +260,20 @@ BEGIN_BUILD_PIPELINE_LIBRARY(PixelOutput) render.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO; render.colorAttachmentCount = m_eFormats.GetSize(); render.pColorAttachmentFormats = m_eFormats.GetData(); - + depthStencil.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; for ( auto e: m_eFormats ) { VkPipelineColorBlendAttachmentState a = {}; a.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; - a.blendEnable = VK_TRUE; - a.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA; - a.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; - a.colorBlendOp = VK_BLEND_OP_ADD; - a.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE; - a.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; - a.alphaBlendOp = VK_BLEND_OP_ADD; + a.blendEnable = VK_FALSE; attachments.AppendTail(a); } blend.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; blend.attachmentCount = m_eFormats.GetSize(); blend.pAttachments = attachments.GetData(); + blend.logicOp = VK_LOGIC_OP_COPY; pipeline.pDepthStencilState = &depthStencil; pipeline.pColorBlendState = &blend; @@ -285,8 +283,8 @@ BEGIN_BUILD_PIPELINE_LIBRARY(PixelOutput) library.flags = VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT; END_BUILD_PIPELINE_LIBRARY() - + void CVkPixelOutputPipelineLibrary::AddAttachment( EImageFormat eFormat ) { - m_eFormats.AppendTail(CVkImage::GetImageFormat(eFormat)); + m_eFormats.AppendTail(CVkImage::GetImageFormat(eFormat)); } diff --git a/materialsystem/vulkan/rendercommandlist.cpp b/materialsystem/vulkan/rendercommandlist.cpp index 9fd60c9..5a0b4fb 100644 --- a/materialsystem/vulkan/rendercommandlist.cpp +++ b/materialsystem/vulkan/rendercommandlist.cpp @@ -16,6 +16,7 @@ void CVkRenderCommandList::SetRenderTarget( uint32_t uIndex, IImage *pImage ) { SwitchRenderingStage(RENDERING_STAGE_SETUP_RASTER); VulkanRenderOutput_t *pOutput = FindOrCreateRenderOutput(uIndex); + pOutput->m_stImage.m_eObjectType = FRAME_OBJECT_TYPE_SINGLE; pOutput->m_stImage.m_pSingle = pImage; } @@ -44,6 +45,8 @@ void CVkRenderCommandList::SetClearDepth( float fVal) void CVkRenderCommandList::SetRenderResolution( uint32_t iWidth, uint32_t iHeight ) { SwitchRenderingStage(RENDERING_STAGE_SETUP_RASTER); + m_uWidth = iWidth; + m_uHeight = iHeight; } @@ -71,26 +74,31 @@ void CVkRenderCommandList::SetMaterial( IMaterial *pMaterial ) m_pCurrentMaterialBuffer->Reset(); CVkBeginCommand *pBeginCommand = CREATE_COMMAND(Begin); pBeginCommand->images = m_pOutput; - pBeginCommand->nResolutionX = 1280; - pBeginCommand->nResolutionY = 720; + pBeginCommand->nResolutionX = m_uWidth; + pBeginCommand->nResolutionY = m_uHeight; pBeginCommand->stDepthImage = m_depth; for ( auto &i: pBeginCommand->images) { pBeginCommand->AddDependency(i.m_stImage.m_pSingle, DEPENDENCY_MODE_DRAWCALL_OUTPUT_IMAGE); } m_pCurrentMaterialBuffer->AddCommand(pBeginCommand); - + CVkSetShaderCommand *pSetShader = CREATE_COMMAND(SetShader); pSetShader->pShader = ((CVkMaterial*)pMaterial)->m_pVkShader; m_pCurrentMaterialBuffer->AddCommand(pSetShader); CVkSetScissorsCommand *pScissorsCommand = CREATE_COMMAND(SetScissors); - pScissorsCommand->uWidth = 1280; - pScissorsCommand->uHeight = 720; + pScissorsCommand->uWidth = m_uWidth; + pScissorsCommand->uHeight = m_uHeight; m_pCurrentMaterialBuffer->AddCommand(pScissorsCommand); + CVkSetViewportCommand *pViewportCommand = CREATE_COMMAND(SetViewport); - pViewportCommand->fWidth = 1280; - pViewportCommand->fHeight = 720; + pViewportCommand->fX = 0; + pViewportCommand->fY = 0; + pViewportCommand->fWidth = m_uWidth; + pViewportCommand->fHeight = m_uHeight; + pViewportCommand->fDepthMin = 0; + pViewportCommand->fDepthMax = 1; m_pCurrentMaterialBuffer->AddCommand(pViewportCommand); } } @@ -190,7 +198,7 @@ IVkCommandBuffer *CVkRenderCommandList::FindOrCreateMaterialCommandBuffer( IMate } VulkanMaterialCommandBuffer_t mat; - mat.m_pCommandBuffer = g_pCommandBufferManager->CreateCommandBuffer(); + mat.m_pCommandBuffer = m_pCommandBufferManager->CreateCommandBuffer(); mat.m_pMaterial = pMaterial; m_materials.AppendTail(mat); if (pbWasCreated) diff --git a/materialsystem/vulkan/rendercontext.cpp b/materialsystem/vulkan/rendercontext.cpp index 11e6d9a..0c1579e 100644 --- a/materialsystem/vulkan/rendercontext.cpp +++ b/materialsystem/vulkan/rendercontext.cpp @@ -1,5 +1,6 @@ #include "commands.h" #include "materialsystem/imaterialsystem.h" +#include "shadercompiler/icompiler.h" #include "tier0/lib.h" #include "tier0/platform.h" #include "tier1/interface.h" @@ -8,13 +9,13 @@ #define VK_NO_PROTOTYPES #include "vulkan/vulkan_core.h" #include "vulkan_state.h" -#include "igamewindow.h" +#include "materialsystem/igamewindow.h" #include "libraries.h" #define REQUIRED_EXTENSION(ext) ext##_EXTENSION_NAME, #define OPTIONAL_EXTENSION(ext) ext##_EXTENSION_NAME, -const char *g_vkDeviceExtensions[] = { +static const char *s_vkDeviceExtensions[] = { #include "device_extensions.h" }; #undef REQUIRED_EXTENSION @@ -26,23 +27,27 @@ SupportedVulkanExtensions_t g_vkAvailableExtensions; uint32_t g_iDrawFamily; uint32_t g_iPresentFamily; -VkQueue g_vkDrawQueue; -VkQueue g_vkPresentQueue; +VkQueue s_vkDrawQueue; +VkQueue s_vkPresentQueue; -VkInstance g_vkInstance; -VmaAllocator g_vkAllocator; -VkPhysicalDevice g_vkPhysicalDevice; -VkDevice g_vkDevice; -VkSwapchainKHR g_vkSwapchain; +VkInstance s_vkInstance; +VmaAllocator s_vkAllocator; +VkPhysicalDevice s_vkPhysicalDevice; +VkDevice s_vkDevice; +VkSwapchainKHR s_vkSwapchain; -CUtlVector g_vkFences = {}; -CUtlVector g_vkGraphicsSemaphores = {}; -CUtlVector g_vkPresentSemaphores = {}; - -CUtlVector g_vkCommandPools = {}; - -CUtlVector g_vkSwapchainImages = {}; -VkFormat g_vkWindowImageFormat; +struct VulkanWindow_t +{ + IGameWindow *m_pWindow; + VkSurfaceKHR m_surface; + VkSwapchainKHR m_swapchain; + VkFormat m_eFormat; + VkFence m_fences[FRAMES_IN_FLIGHT]; + VkSemaphore m_imageAvailable[FRAMES_IN_FLIGHT]; + VkSemaphore m_renderFinished[FRAMES_IN_FLIGHT]; + CUtlVector m_images; + uint32_t m_uCurrentFrame; +}; CVkImage::CVkImage() @@ -57,7 +62,7 @@ CVkImage::CVkImage( uint32_t nWidth, uint32_t nHeight, uint32_t nDepth, EImageFo m_eMultisampleType = eMultisampleType; m_eImageType = eImageType; m_eFormat = eFormat; - m_ePreferredLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + m_ePreferredLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; CreateImage(nWidth, nHeight, eFormat, eMultisampleType, eUsage); CreateImageView(); } @@ -103,13 +108,11 @@ VkFormat CVkImage::GetImageFormat( enum EImageFormat eImageFormat ) case IMAGE_FORMAT_RGBA8_SINT: return VK_FORMAT_R8G8B8A8_SINT; case IMAGE_FORMAT_RGBA16_SFLOAT: - return VK_FORMAT_R16G16B16A16_SFLOAT; + return VK_FORMAT_R16G16B16A16_SFLOAT; case IMAGE_FORMAT_RGBA32_SFLOAT: return VK_FORMAT_R32G32B32A32_SFLOAT; case IMAGE_FORMAT_D32_SFLOAT: return VK_FORMAT_D32_SFLOAT; - case IMAGE_FORMAT_WINDOW: - return g_vkWindowImageFormat; } } @@ -130,9 +133,9 @@ void CVkImage::CreateImage( uint32_t nWidth, uint32_t nHeight, EImageFormat eFor stCreateInfo.format = GetImageFormat(eFormat); stCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT; - stAlloc.usage = VMA_MEMORY_USAGE_AUTO; + stAlloc.usage = VMA_MEMORY_USAGE_AUTO; - vmaCreateImage(g_vkAllocator, &stCreateInfo, &stAlloc, &m_image, &m_allocation, NULL); + vmaCreateImage(s_vkAllocator, &stCreateInfo, &stAlloc, &m_image, &m_allocation, NULL); } void CVkImage::CreateImageView() @@ -151,7 +154,7 @@ void CVkImage::CreateImageView() stImageViewCreateInfo.subresourceRange.layerCount = 1; stImageViewCreateInfo.subresourceRange.levelCount = 1; m_range = stImageViewCreateInfo.subresourceRange; - vkCreateImageView(g_vkDevice, &stImageViewCreateInfo, NULL, &m_imageView); + vkCreateImageView(s_vkDevice, &stImageViewCreateInfo, NULL, &m_imageView); } void CVkImage::SetDebugName( const char *szName ) { @@ -186,7 +189,7 @@ CVkBuffer::CVkBuffer( uint32_t nSize, VkBufferUsageFlags2 eUsage, uint32_t nAlig VkBufferCreateInfo stBufferInfo = {}; VmaAllocationCreateInfo stAllocInfo = {}; VkBufferDeviceAddressInfo stAddress = {}; - + stUsage.sType = VK_STRUCTURE_TYPE_BUFFER_USAGE_FLAGS_2_CREATE_INFO; stUsage.usage = eUsage | VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT; @@ -197,12 +200,12 @@ 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(g_vkAllocator, &stBufferInfo, &stAllocInfo, &m_buffer, &m_allocation, NULL); + vmaCreateBuffer(s_vkAllocator, &stBufferInfo, &stAllocInfo, &m_buffer, &m_allocation, NULL); stAddress.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO; stAddress.buffer = m_buffer; - m_address = vkGetBufferDeviceAddress(g_vkDevice, &stAddress); - + m_address = vkGetBufferDeviceAddress(s_vkDevice, &stAddress); + m_nSize = nSize; } @@ -230,13 +233,13 @@ void *CVkBuffer::Map() void *pData; pData = NULL; - vmaMapMemory(g_vkAllocator, m_allocation, &pData); + vmaMapMemory(s_vkAllocator, m_allocation, &pData); return pData; } void CVkBuffer::Unmap() { - vmaUnmapMemory(g_vkAllocator, m_allocation); + vmaUnmapMemory(s_vkAllocator, m_allocation); } uint32_t CVkBuffer::GetSize() @@ -249,20 +252,20 @@ public: virtual void Init() override; virtual void Frame( float fDeltaTime ) override; virtual void Shutdown() override; - + virtual IVertexBuffer *CreateVertexBuffer( uint32_t nSize ) override; virtual IIndexBuffer *CreateIndexBuffer( uint32_t nSize ) override; virtual IBuffer *CreateConstantBuffer( uint32_t nSize ) override; virtual IBuffer *CreateStorageBuffer( uint32_t nSize ) override; virtual void DestroyBuffer( IBuffer *pBuffer ) override; - + virtual IImage *CreateRenderTarget( uint32_t x, uint32_t y, EImageFormat eFormat, EMultisampleType eMultisampleType ) override; virtual IImage *CreateStorageImage( uint32_t x, uint32_t y, EImageFormat eFormat, EMultisampleType eMultisampleType ) override; virtual void DestroyImage( IImage *pImage ) override; IBuffer *CreateBuffer( uint32_t nSize, VkBufferUsageFlags2 eUsage ); IBuffer *CreateBufferAligned( uint32_t nSize, uint32_t nAlignment, VkBufferUsageFlags2 eUsage ); - + virtual IShader *CreateShader( const char *szName ) override; virtual void DestroyShader( IShader *pShader ) override; @@ -272,7 +275,7 @@ public: virtual IRenderCommandList *CreateCommandList() override; virtual void DestroyCommandList( IRenderCommandList *pCommandList ) override; virtual void SubmitCommandList(IRenderCommandList *pList) override; - + virtual void SetMainWindowManager( IGameWindowManager *pWindowManager ) override; virtual void RenderGameWindow( IGameWindow *pWindow ) override; @@ -284,16 +287,19 @@ private: VkCommandBuffer GetCommandBuffer(); - void CreateSwapchain( IGameWindow *pWindow ); - void DestroySwapchain( IGameWindow *pWindow ); + VulkanWindow_t CreateSwapchain( IGameWindow *pWindow ); + void DestroySwapchain( uint32_t uIndex ); IGameWindowManager *m_pWindowManager; + IVkCommandBufferManager *m_pCommandBufferManager; + + CUtlVector m_renderWindows; }; EXPOSE_INTERFACE(CVkRenderContext, IRenderContext, RENDER_CONTEXT_INTERFACE_VERSION); //----------------------------------------------------------------------------- -// Creates vertex buffer. Wrapper over CreateBuffer +// Creates vertex buffer. Wrapper over CreateBuffer //----------------------------------------------------------------------------- IVertexBuffer *CVkRenderContext::CreateVertexBuffer( uint32_t nSize ) { @@ -301,14 +307,14 @@ IVertexBuffer *CVkRenderContext::CreateVertexBuffer( uint32_t nSize ) } //----------------------------------------------------------------------------- -// Creates index buffer. Wrapper over CreateBuffer +// Creates index buffer. Wrapper over CreateBuffer //----------------------------------------------------------------------------- IIndexBuffer *CVkRenderContext::CreateIndexBuffer( uint32_t nSize ) { return (IIndexBuffer*)CreateBuffer(nSize, VK_BUFFER_USAGE_2_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_2_STORAGE_BUFFER_BIT); } //----------------------------------------------------------------------------- -// Creates storage buffer. Wrapper over CreateBuffer +// Creates storage buffer. Wrapper over CreateBuffer //----------------------------------------------------------------------------- IBuffer *CVkRenderContext::CreateStorageBuffer( uint32_t nSize ) { @@ -316,7 +322,7 @@ IBuffer *CVkRenderContext::CreateStorageBuffer( uint32_t nSize ) } //----------------------------------------------------------------------------- -// Creates constant buffer. Wrapper over CreateBuffer +// Creates constant buffer. Wrapper over CreateBuffer //----------------------------------------------------------------------------- IBuffer *CVkRenderContext::CreateConstantBuffer( uint32_t nSize ) { @@ -334,7 +340,7 @@ IBuffer *CVkRenderContext::CreateBuffer( uint32_t nSize, VkBufferUsageFlags2 eUs //----------------------------------------------------------------------------- // Creates vulkan buffer aligned to the nAlignment -// Useful for everything eg: ray tracing, which requires them to be aligned +// Useful for everything eg: ray tracing, which requires them to be aligned // to the groupBaseAlignment. //----------------------------------------------------------------------------- IBuffer *CVkRenderContext::CreateBufferAligned( uint32_t nSize, uint32_t nAlignment, VkBufferUsageFlags2 eUsage ) @@ -369,33 +375,13 @@ void CVkRenderContext::DestroyImage( IImage *pImage ) IShader *CVkRenderContext::CreateShader( const char *szName ) { - CCompiledShader stShader = {}; - CompiledShaderManager()->ReadFromFile(&stShader, szName); - CVkVertexDescriptionPipelineLibrary vertexDescription = {}; - vertexDescription.AddAttribute(0, 0, VERTEX_FORMAT_XYZ32_SFLOAT, 0); - vertexDescription.AddLayout(0, 12); - vertexDescription.SetTopology(TOPOLOGY_MODE_TRIANGLE_LIST); - vertexDescription.Build(); - CVkVertexTransformPipelineLibrary vertexTransform = {}; - vertexTransform.SetShader(&stShader); - vertexTransform.Build(); - - CVkPixelShaderPipelineLibrary pixelShader = {}; - pixelShader.SetShader(&stShader); - pixelShader.Build(); - - CVkPixelOutputPipelineLibrary pixelOutput = {}; - pixelOutput.AddAttachment(IMAGE_FORMAT_RGBA8_UNORM); - pixelOutput.Build(); - CVkShader *pShader = new CVkShader(); - pShader->AddShaderLibrary(&vertexDescription); - pShader->AddShaderLibrary(&vertexTransform); - pShader->AddShaderLibrary(&pixelShader); - pShader->AddShaderLibrary(&pixelOutput); - pShader->Build(); + VkGraphicsPipelineCreateInfo stPipelineCreateInfo = {}; + ICompiledShaderManager *pCompiledShaderManager = (ICompiledShaderManager*)CreateInterface(COMPILED_SHADER_MANAGER_INTERFACE_VERSION, NULL); + pCompiledShaderManager->ReadFromFile(&pShader->m_shader, szName); + pShader->m_hDevice = s_vkDevice; return pShader; } @@ -416,7 +402,9 @@ void CVkRenderContext::DestroyMaterial( IMaterial *pMaterial ) IRenderCommandList *CVkRenderContext::CreateCommandList() { - return new CVkRenderCommandList; + CVkRenderCommandList *pList = new CVkRenderCommandList; + pList->m_pCommandBufferManager = m_pCommandBufferManager; + return pList; } void CVkRenderContext::DestroyCommandList( IRenderCommandList *pCommandList ) @@ -441,7 +429,8 @@ void CVkRenderContext::SetMainWindowManager( IGameWindowManager *pWindowManager void CVkRenderContext::RegisterGameWindow( IGameWindow *pWindow ) { - + VulkanWindow_t window = CreateSwapchain(pWindow); + m_renderWindows.AppendTail(window); } void CVkRenderContext::UnregisterGameWindow( IGameWindow *pWindow ) @@ -463,16 +452,16 @@ void CVkRenderContext::Init() uint32_t nPhysicalDevicesCount; CUtlVector physicalDevices; - + uint32_t nNumQueueFamilies = 0; CUtlVector queueFamilyProperties; - + VkApplicationInfo stApplicationInfo = {}; VkInstanceCreateInfo stInstanceCreateInfo = {}; VkDeviceQueueCreateInfo stDeviceQueueCreateInfo = {}; VkDeviceCreateInfo stDeviceCreateInfo = {}; - + float fPriority = 1.0; r = volkInitialize(); @@ -501,33 +490,33 @@ void CVkRenderContext::Init() stInstanceCreateInfo.enabledExtensionCount = enabledInstanceExtensions.GetSize(); stInstanceCreateInfo.ppEnabledExtensionNames = enabledInstanceExtensions.GetData(); - r = vkCreateInstance(&stInstanceCreateInfo, NULL, &g_vkInstance); + r = vkCreateInstance(&stInstanceCreateInfo, NULL, &s_vkInstance); VULKAN_RESULT_PRINT(r, vkCreateInstance); - + // volk requires to load instance this way - volkLoadInstance(g_vkInstance); + volkLoadInstance(s_vkInstance); // Get amount of physical devices - r = vkEnumeratePhysicalDevices(g_vkInstance, &nPhysicalDevicesCount, NULL); + r = vkEnumeratePhysicalDevices(s_vkInstance, &nPhysicalDevicesCount, NULL); VULKAN_RESULT_PRINT(r, vkEnumeratePhysicalDevices); physicalDevices.Resize(nPhysicalDevicesCount); // Read all physical devices - r = vkEnumeratePhysicalDevices(g_vkInstance, &nPhysicalDevicesCount, physicalDevices.GetData()); + r = vkEnumeratePhysicalDevices(s_vkInstance, &nPhysicalDevicesCount, physicalDevices.GetData()); VULKAN_RESULT_PRINT(r, vkEnumeratePhysicalDevices); - g_vkPhysicalDevice = SelectPhysicalDevice(physicalDevices); + s_vkPhysicalDevice = SelectPhysicalDevice(physicalDevices); enabledDeviceExtensions = GetDeviceExtensions(); // Get all queues - vkGetPhysicalDeviceQueueFamilyProperties(g_vkPhysicalDevice, &nNumQueueFamilies, NULL); + vkGetPhysicalDeviceQueueFamilyProperties(s_vkPhysicalDevice, &nNumQueueFamilies, NULL); queueFamilyProperties.Resize(nNumQueueFamilies); uint32_t i = 0; - vkGetPhysicalDeviceQueueFamilyProperties(g_vkPhysicalDevice, &nNumQueueFamilies, queueFamilyProperties.GetData()); + vkGetPhysicalDeviceQueueFamilyProperties(s_vkPhysicalDevice, &nNumQueueFamilies, queueFamilyProperties.GetData()); for (auto &family: queueFamilyProperties) { @@ -544,7 +533,7 @@ void CVkRenderContext::Init() stDeviceQueueCreateInfo.queueCount = 1; stDeviceQueueCreateInfo.pQueuePriorities = &fPriority; stDeviceQueueCreateInfo.queueFamilyIndex = g_iDrawFamily; - + VkPhysicalDeviceGraphicsPipelineLibraryFeaturesEXT gplFeatures = {}; gplFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_FEATURES_EXT; gplFeatures.graphicsPipelineLibrary = VK_TRUE; @@ -554,7 +543,7 @@ void CVkRenderContext::Init() vk13Features.pNext = &gplFeatures; vk13Features.synchronization2 = VK_TRUE; vk13Features.dynamicRendering = VK_TRUE; - + VkPhysicalDeviceVulkan12Features vk12Features = {}; vk12Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES; vk12Features.pNext = &vk13Features; @@ -566,132 +555,167 @@ void CVkRenderContext::Init() stDeviceCreateInfo.enabledExtensionCount = enabledDeviceExtensions.GetSize(); stDeviceCreateInfo.ppEnabledExtensionNames = enabledDeviceExtensions.GetData(); stDeviceCreateInfo.pNext = &vk12Features; - r = vkCreateDevice(g_vkPhysicalDevice, &stDeviceCreateInfo, NULL, &g_vkDevice); + r = vkCreateDevice(s_vkPhysicalDevice, &stDeviceCreateInfo, NULL, &s_vkDevice); VULKAN_RESULT_PRINT(r, vkEnumeratePhysicalDevices); for (auto &extension: enabledDeviceExtensions) V_printf("%s\n", extension); - vkGetDeviceQueue(g_vkDevice, g_iDrawFamily, 0, &g_vkDrawQueue); - vkGetDeviceQueue(g_vkDevice, g_iPresentFamily, 0, &g_vkPresentQueue); - volkLoadDevice(g_vkDevice); + vkGetDeviceQueue(s_vkDevice, g_iDrawFamily, 0, &s_vkDrawQueue); + vkGetDeviceQueue(s_vkDevice, g_iPresentFamily, 0, &s_vkPresentQueue); + volkLoadDevice(s_vkDevice); VmaAllocatorCreateInfo stAllocatorInfo = {}; stAllocatorInfo.flags = VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT | VMA_ALLOCATOR_CREATE_KHR_MAINTENANCE5_BIT ; stAllocatorInfo.vulkanApiVersion = VK_API_VERSION_1_4; - stAllocatorInfo.physicalDevice = g_vkPhysicalDevice; - stAllocatorInfo.device = g_vkDevice; - stAllocatorInfo.instance = g_vkInstance; + stAllocatorInfo.physicalDevice = s_vkPhysicalDevice; + stAllocatorInfo.device = s_vkDevice; + stAllocatorInfo.instance = s_vkInstance; VmaVulkanFunctions vulkanFunctions; vmaImportVulkanFunctionsFromVolk(&stAllocatorInfo, &vulkanFunctions); stAllocatorInfo.pVulkanFunctions = &vulkanFunctions; - vmaCreateAllocator(&stAllocatorInfo, &g_vkAllocator); + vmaCreateAllocator(&stAllocatorInfo, &s_vkAllocator); VkPipelineLayoutCreateInfo stPipelineLayout = {}; stPipelineLayout.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; stPipelineLayout.flags = VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT; - vkCreatePipelineLayout(g_vkDevice, &stPipelineLayout, NULL, &g_pLibraryEmptyLayout); - - g_vkCommandPools.Resize(g_vkSwapchainImages.GetSize()); - - for (auto &pool: g_vkCommandPools) - { - VkCommandPoolCreateInfo commandPoolCreateInfo = {}; - commandPoolCreateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; - commandPoolCreateInfo.queueFamilyIndex = g_iDrawFamily; - commandPoolCreateInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; - vkCreateCommandPool(g_vkDevice, &commandPoolCreateInfo, NULL, &pool); - } - - g_pCommandBufferManager = (IVkCommandBufferManager*)CreateInterface(VULKAN_COMMAND_BUFFER_MANAGER_INTERFACE_NAME, NULL); - g_pCommandBufferManager->Init(); - - + vkCreatePipelineLayout(s_vkDevice, &stPipelineLayout, NULL, &g_pLibraryEmptyLayout); + m_pCommandBufferManager = (IVkCommandBufferManager*)CreateInterface(VULKAN_COMMAND_BUFFER_MANAGER_INTERFACE_NAME, NULL); + m_pCommandBufferManager->SetVulkanHandlers(s_vkInstance, s_vkDevice); + m_pCommandBufferManager->Init(); } void CVkRenderContext::Frame( float fDeltaTime ) { - /* - CVkBlitCommand *pBlitCommand = NULL; - if (m_pOutputImage) + + uint32_t i; + CUtlVector fences = {}; + CUtlVector imageReady = {}; + CUtlVector renderFinish = {}; + CUtlVector swapchains = {}; + CUtlVector uImageIndexes = {}; + CUtlVector uSwapchainImageIndexes = {}; + CUtlVector recreatedWindows = {}; + vkDeviceWaitIdle(s_vkDevice); + + i = 0; + for ( auto &s: m_renderWindows) { - pBlitCommand = CREATE_COMMAND(Blit); - pBlitCommand->AddDependency(m_pOutputImage, DEPENDENCY_MODE_BLIT_IMAGE_SOURCE); - pBlitCommand->AddSwapchainDependency((IRenderingObject**)g_vkSwapchainImages.GetData(), DEPENDENCY_MODE_BLIT_IMAGE_DESTINATION); - pBlitCommand->stInputImage.m_eObjectType = FRAME_OBJECT_TYPE_SINGLE; - pBlitCommand->stInputImage.m_pSingle = m_pOutputImage; - pBlitCommand->stOutputImage.m_eObjectType = FRAME_OBJECT_TYPE_SWAPPED; - pBlitCommand->stOutputImage.m_ppSwapped = (IRenderingObject**)g_vkSwapchainImages.GetData(); - pBlitCommand->iSrcMax[0] = 1280; - pBlitCommand->iSrcMax[1] = 720; - pBlitCommand->iSrcMax[2] = 1; - pBlitCommand->iDstMax[0] = 1280; - pBlitCommand->iDstMax[1] = 720; - pBlitCommand->iDstMax[2] = 1; + if ( !s.m_pWindow->BRenderSizeUpdated() ) + { + i++; + continue; + } + DestroySwapchain(i); + m_renderWindows.RemoveAt(i); + recreatedWindows.AppendTail(CreateSwapchain(s.m_pWindow)); } - s_pPresentCommandBuffer = g_pCommandBufferManager->CreateCommandBuffer(); + for ( auto &s: recreatedWindows) + { + m_renderWindows.AppendTail(s); + } + vkDeviceWaitIdle(s_vkDevice); + + for ( auto &s: m_renderWindows) + { + fences.AppendTail(s.m_fences[s.m_uCurrentFrame]); + imageReady.AppendTail(s.m_imageAvailable[s.m_uCurrentFrame]); + renderFinish.AppendTail(s.m_renderFinished[s.m_uCurrentFrame]); + swapchains.AppendTail(s.m_swapchain); + uImageIndexes.AppendTail(s.m_uCurrentFrame); + } + uSwapchainImageIndexes.Resize(m_renderWindows.GetSize()); + + vkWaitForFences(s_vkDevice, fences.GetSize(), fences.GetData(), VK_TRUE, UINT64_MAX); + vkResetFences(s_vkDevice, fences.GetSize(), fences.GetData()); + + i = 0; + for ( auto &s: m_renderWindows ) + { + VkResult r = vkAcquireNextImageKHR(s_vkDevice, s.m_swapchain, UINT64_MAX, s.m_imageAvailable[s.m_uCurrentFrame], NULL, &uSwapchainImageIndexes[i]); + i++; + } + + + s_pPresentCommandBuffer = m_pCommandBufferManager->CreateCommandBuffer(); s_pPresentCommandBuffer->Reset(); - if (pBlitCommand != NULL) - s_pPresentCommandBuffer->AddCommand(pBlitCommand); + + i = 0; + for ( auto &s: m_renderWindows ) + { + + CVkBlitCommand *pBlitCommand = NULL; + if (s.m_pWindow->GetOutputImage()) + { + pBlitCommand = CREATE_COMMAND(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; + pBlitCommand->stInputImage.m_pSingle = s.m_pWindow->GetOutputImage(); + pBlitCommand->stOutputImage.m_eObjectType = FRAME_OBJECT_TYPE_SINGLE; + pBlitCommand->stOutputImage.m_pSingle = (IRenderingObject*)s.m_images[uSwapchainImageIndexes[i]]; + pBlitCommand->iSrcMax[0] = s.m_pWindow->GetOutputImage()->GetImageWidth(); + pBlitCommand->iSrcMax[1] = s.m_pWindow->GetOutputImage()->GetImageHeight(); + pBlitCommand->iSrcMax[2] = 1; + pBlitCommand->iDstMax[0] = s.m_pWindow->GetRenderWidth(); + pBlitCommand->iDstMax[1] = s.m_pWindow->GetRenderHeight(); + pBlitCommand->iDstMax[2] = 1; + } + if (pBlitCommand != NULL) + s_pPresentCommandBuffer->AddCommand(pBlitCommand); + i++; + } + s_pPresentCommandBuffer->Render(); - - vkDeviceWaitIdle(g_vkDevice); - - static uint32_t s_nImageIndex = 0; - uint32_t nImageIndex = 0; - - vkWaitForFences(g_vkDevice, 1, &g_vkFences[s_nImageIndex], VK_TRUE, UINT64_MAX); - VkResult r = vkAcquireNextImageKHR(g_vkDevice, g_vkSwapchain, UINT64_MAX, g_vkGraphicsSemaphores[s_nImageIndex], NULL, &nImageIndex); - - vkResetFences(g_vkDevice, 1, &g_vkFences[s_nImageIndex]); + s_pPresentCommandBuffer->Submit(0); - s_pPresentCommandBuffer->Submit(nImageIndex); - VkPipelineStageFlags uPipelineStageFlags = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; VkSubmitInfo stSubmitInfo = {}; stSubmitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - stSubmitInfo.waitSemaphoreCount = 1; - stSubmitInfo.pWaitSemaphores = &g_vkGraphicsSemaphores[s_nImageIndex]; + stSubmitInfo.waitSemaphoreCount = imageReady.GetSize(); + stSubmitInfo.pWaitSemaphores = imageReady.GetData(); stSubmitInfo.pWaitDstStageMask = &uPipelineStageFlags; - - stSubmitInfo.commandBufferCount = g_vkCommandBuffers.GetSize(); - stSubmitInfo.pCommandBuffers = g_vkCommandBuffers.GetData(); - - stSubmitInfo.signalSemaphoreCount = 1; - stSubmitInfo.pSignalSemaphores = &g_vkPresentSemaphores[nImageIndex]; + + stSubmitInfo.commandBufferCount = m_pCommandBufferManager->GetVulkanCommands().GetSize(); + stSubmitInfo.pCommandBuffers = m_pCommandBufferManager->GetVulkanCommands().GetData(); + + stSubmitInfo.signalSemaphoreCount = renderFinish.GetSize(); + stSubmitInfo.pSignalSemaphores = renderFinish.GetData(); - vkQueueSubmit(g_vkDrawQueue, 1, &stSubmitInfo, g_vkFences[s_nImageIndex]); + vkQueueSubmit(s_vkDrawQueue, 1, &stSubmitInfo, fences[0]); VkPresentInfoKHR stPresentInfo = {}; stPresentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; - stPresentInfo.waitSemaphoreCount = 1; - stPresentInfo.pWaitSemaphores = &g_vkPresentSemaphores[nImageIndex]; - stPresentInfo.swapchainCount = 1; - stPresentInfo.pSwapchains = &g_vkSwapchain; - stPresentInfo.pImageIndices = &nImageIndex; + stPresentInfo.waitSemaphoreCount = renderFinish.GetSize(); + stPresentInfo.pWaitSemaphores = renderFinish.GetData(); + stPresentInfo.swapchainCount = swapchains.GetSize(); + stPresentInfo.pSwapchains = swapchains.GetData(); + stPresentInfo.pImageIndices = uImageIndexes.GetData(); - vkQueuePresentKHR(g_vkPresentQueue, &stPresentInfo); + vkQueuePresentKHR(s_vkPresentQueue, &stPresentInfo); - s_nImageIndex = (s_nImageIndex + 1) % g_vkSwapchainImages.GetSize(); - g_vkCommandBuffers = {}; - */ + for ( auto &s: m_renderWindows ) + { + s.m_uCurrentFrame = (s.m_uCurrentFrame + 1) % FRAMES_IN_FLIGHT; + } + m_pCommandBufferManager->RenderingFinished(); } -void CVkRenderContext::CreateSwapchain( IGameWindow *pWindow ) +VulkanWindow_t CVkRenderContext::CreateSwapchain( IGameWindow *pWindow ) { uint32_t numSurfaceFormats = 0; CUtlVector surfaceFormats; - VkSurfaceCapabilitiesKHR surfaceCapatibilities = {}; - + VkSurfaceCapabilitiesKHR surfaceCapatibilities = {}; + uint32_t nSurfacePresentModes = 0; CUtlVector surfacePresentModes; - + const VkFormat preferedSurfaceFormats[] = { VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM, @@ -699,22 +723,23 @@ void CVkRenderContext::CreateSwapchain( IGameWindow *pWindow ) VkSurfaceFormatKHR stSelectedFormat; VkSwapchainCreateInfoKHR stSwapchainCreateInfo = {}; - VkFenceCreateInfo stFenceCreateInfo = {}; + VkFenceCreateInfo stFenceCreateInfo = {}; VkSemaphoreCreateInfo stSemaphoreCreateInfo = {}; uint32_t nSwapchainImages; CUtlVector swapchainImages; - VkSurfaceKHR hSurface; - - hSurface = (VkSurfaceKHR)pWindow->CreateVulkanSurface(g_vkInstance); + + VulkanWindow_t window = {}; + + window.m_surface = (VkSurfaceKHR)pWindow->CreateVulkanSurface(s_vkInstance); - vkGetPhysicalDeviceSurfaceCapabilitiesKHR(g_vkPhysicalDevice, (VkSurfaceKHR)hSurface, &surfaceCapatibilities); + vkGetPhysicalDeviceSurfaceCapabilitiesKHR(s_vkPhysicalDevice, (VkSurfaceKHR)window.m_surface, &surfaceCapatibilities); - vkGetPhysicalDeviceSurfaceFormatsKHR(g_vkPhysicalDevice, (VkSurfaceKHR)hSurface, &numSurfaceFormats, NULL); + vkGetPhysicalDeviceSurfaceFormatsKHR(s_vkPhysicalDevice, (VkSurfaceKHR)window.m_surface, &numSurfaceFormats, NULL); surfaceFormats.Resize(numSurfaceFormats); - vkGetPhysicalDeviceSurfaceFormatsKHR(g_vkPhysicalDevice, (VkSurfaceKHR)hSurface, &numSurfaceFormats, surfaceFormats.GetData()); + vkGetPhysicalDeviceSurfaceFormatsKHR(s_vkPhysicalDevice, (VkSurfaceKHR)window.m_surface, &numSurfaceFormats, surfaceFormats.GetData()); stSelectedFormat = surfaceFormats[0]; @@ -731,12 +756,12 @@ void CVkRenderContext::CreateSwapchain( IGameWindow *pWindow ) } formatPicked: - vkGetPhysicalDeviceSurfacePresentModesKHR(g_vkPhysicalDevice, hSurface, &nSurfacePresentModes, NULL); + vkGetPhysicalDeviceSurfacePresentModesKHR(s_vkPhysicalDevice, window.m_surface, &nSurfacePresentModes, NULL); surfacePresentModes.Resize(nSurfacePresentModes); - vkGetPhysicalDeviceSurfacePresentModesKHR(g_vkPhysicalDevice, hSurface, &nSurfacePresentModes, surfacePresentModes.GetData()); + vkGetPhysicalDeviceSurfacePresentModesKHR(s_vkPhysicalDevice, window.m_surface, &nSurfacePresentModes, surfacePresentModes.GetData()); stSwapchainCreateInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; - stSwapchainCreateInfo.surface = hSurface; + stSwapchainCreateInfo.surface = window.m_surface; stSwapchainCreateInfo.imageFormat = stSelectedFormat.format; stSwapchainCreateInfo.imageColorSpace = stSelectedFormat.colorSpace; stSwapchainCreateInfo.presentMode = VK_PRESENT_MODE_IMMEDIATE_KHR; @@ -744,19 +769,20 @@ formatPicked: stSwapchainCreateInfo.preTransform = surfaceCapatibilities.currentTransform; stSwapchainCreateInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; stSwapchainCreateInfo.imageArrayLayers = 1; - stSwapchainCreateInfo.imageExtent = surfaceCapatibilities.minImageExtent; + stSwapchainCreateInfo.imageExtent = {pWindow->GetRenderWidth(), pWindow->GetRenderHeight()}; + if (stSwapchainCreateInfo.imageExtent.width == 0) + stSwapchainCreateInfo.imageExtent.width = 1; + if (stSwapchainCreateInfo.imageExtent.height == 0) + stSwapchainCreateInfo.imageExtent.height = 1; stSwapchainCreateInfo.minImageCount = surfaceCapatibilities.minImageCount; - vkCreateSwapchainKHR(g_vkDevice, &stSwapchainCreateInfo, NULL, &g_vkSwapchain); + vkCreateSwapchainKHR(s_vkDevice, &stSwapchainCreateInfo, NULL, &window.m_swapchain); - g_vkWindowImageFormat = stSwapchainCreateInfo.imageFormat; + window.m_eFormat = stSwapchainCreateInfo.imageFormat; - vkGetSwapchainImagesKHR(g_vkDevice, g_vkSwapchain, &nSwapchainImages, NULL); - g_vkSwapchainImages.Resize(nSwapchainImages); + vkGetSwapchainImagesKHR(s_vkDevice, window.m_swapchain, &nSwapchainImages, NULL); + window.m_images.Resize(nSwapchainImages); swapchainImages.Resize(nSwapchainImages); - g_vkFences.Resize(nSwapchainImages); - g_vkGraphicsSemaphores.Resize(nSwapchainImages); - g_vkPresentSemaphores.Resize(nSwapchainImages); - vkGetSwapchainImagesKHR(g_vkDevice, g_vkSwapchain, &nSwapchainImages, swapchainImages.GetData()); + vkGetSwapchainImagesKHR(s_vkDevice, window.m_swapchain, &nSwapchainImages, swapchainImages.GetData()); for ( int i = 0; i < swapchainImages.GetSize(); i++ ) { @@ -765,28 +791,43 @@ formatPicked: pImage->m_image = swapchainImages[i]; pImage->m_eImageType = IMAGE_TYPE_2D; pImage->m_eMultisampleType = MULTISAMPLE_TYPE_NONE; - pImage->m_eFormat = IMAGE_FORMAT_WINDOW; + pImage->m_eFormat = IMAGE_FORMAT_BGRA8_UNORM; pImage->m_nHeight = 1280; pImage->m_nWidth = 720; - pImage->m_ePreferredLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; + pImage->m_ePreferredLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; pImage->CreateImageView(); - g_vkSwapchainImages[i] = pImage; - + window.m_images[i] = pImage; + } + for ( int i = 0; i < FRAMES_IN_FLIGHT; i++ ) + { stFenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; stFenceCreateInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT; - vkCreateFence(g_vkDevice, &stFenceCreateInfo, NULL, &g_vkFences[i]); + vkCreateFence(s_vkDevice, &stFenceCreateInfo, NULL, &window.m_fences[i]); stSemaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; - vkCreateSemaphore(g_vkDevice, &stSemaphoreCreateInfo, NULL, &g_vkGraphicsSemaphores[i]); - vkCreateSemaphore(g_vkDevice, &stSemaphoreCreateInfo, NULL, &g_vkPresentSemaphores[i]); + vkCreateSemaphore(s_vkDevice, &stSemaphoreCreateInfo, NULL, &window.m_imageAvailable[i]); + vkCreateSemaphore(s_vkDevice, &stSemaphoreCreateInfo, NULL, &window.m_renderFinished[i]); } + window.m_pWindow = pWindow; + return window; } -void CVkRenderContext::DestroySwapchain( IGameWindow *pWindow ) +void CVkRenderContext::DestroySwapchain( uint32_t uIndex ) { - vkDestroySwapchainKHR(g_vkDevice, g_vkSwapchain, NULL); - pWindow->DestroyVulkanSurface(g_vkInstance); + for ( auto i: m_renderWindows[uIndex].m_images ) + { + CVkImage *pImage = (CVkImage*)i; + vkDestroyImageView(s_vkDevice, pImage->m_imageView, NULL); + } + vkDestroySwapchainKHR(s_vkDevice, m_renderWindows[uIndex].m_swapchain, NULL); + m_renderWindows[uIndex].m_pWindow->DestroyVulkanSurface(s_vkInstance); + for ( int i = 0; i < FRAMES_IN_FLIGHT; i++ ) + { + vkDestroyFence(s_vkDevice, m_renderWindows[uIndex].m_fences[i], NULL); + vkDestroySemaphore(s_vkDevice, m_renderWindows[uIndex].m_imageAvailable[i], NULL); + vkDestroySemaphore(s_vkDevice, m_renderWindows[uIndex].m_renderFinished[i], NULL); + } } //----------------------------------------------------------------------------- @@ -794,7 +835,7 @@ void CVkRenderContext::DestroySwapchain( IGameWindow *pWindow ) //----------------------------------------------------------------------------- void CVkRenderContext::Shutdown() { - vkDestroyInstance(g_vkInstance, NULL); + vkDestroyInstance(s_vkInstance, NULL); } @@ -820,7 +861,7 @@ VkPhysicalDevice CVkRenderContext::SelectPhysicalDevice( CUtlVector CVkRenderContext::GetDeviceExtensions() const char *szExtensionName; - r = vkEnumerateDeviceExtensionProperties(g_vkPhysicalDevice, NULL, &nExtensionCount, NULL); + r = vkEnumerateDeviceExtensionProperties(s_vkPhysicalDevice, NULL, &nExtensionCount, NULL); VULKAN_RESULT_PRINT(r, vkEnumeratePhysicalDevices); extensions.Resize(nExtensionCount); - r = vkEnumerateDeviceExtensionProperties(g_vkPhysicalDevice, NULL, &nExtensionCount, extensions.GetData()); + r = vkEnumerateDeviceExtensionProperties(s_vkPhysicalDevice, NULL, &nExtensionCount, extensions.GetData()); VULKAN_RESULT_PRINT(r, vkEnumeratePhysicalDevices); @@ -875,4 +916,3 @@ CUtlVector CVkRenderContext::GetDeviceExtensions() return enabledExtensions; } - diff --git a/materialsystem/vulkan/shader.cpp b/materialsystem/vulkan/shader.cpp index b8710d2..f46c93b 100644 --- a/materialsystem/vulkan/shader.cpp +++ b/materialsystem/vulkan/shader.cpp @@ -1,38 +1,147 @@ +#include "materialsystem/shaderinternals.h" +#include "tier1/utlvector.h" #include "vulkan_state.h" +#include "shaderparser.h" CVkShader::~CVkShader() { } -void CVkShader::AddShaderLibrary( CVkPipelineLibrary *pLibrary ) +void CVkShader::AddLayout( int iIndex, int iStride ) { - m_libraries.AppendTail(pLibrary); + VkVertexInputBindingDescription layout = {}; + layout.binding = iIndex; + layout.inputRate = VK_VERTEX_INPUT_RATE_VERTEX; + layout.stride = iStride; + m_layouts.AppendTail(layout); } +void CVkShader::AddAttribute( int iBufferIndex, int iLocation, EVertexFormat eFormat, int iOffset ) +{ + VkVertexInputAttributeDescription attribute = {}; + attribute.binding = iBufferIndex; + attribute.location = iLocation; + attribute.format = VulkanGetVertexFormat(eFormat); + attribute.offset = iOffset; + m_attributes.AppendTail(attribute); +} + +void CVkShader::SetTopology( ETopologyMode eTopology ) +{ + +} + +void CVkShader::AddOutputImage( int iImageIndex, EImageFormat eFormat ) +{ + m_eFormats.AppendTail(CVkImage::GetImageFormat(eFormat)); +} + +void CVkShader::SetDepthImage( EImageFormat eFormat ) +{ +} + + void CVkShader::Build() { - CUtlVector libs = {}; + VkPipelineLayoutCreateInfo layoutInfo = {}; VkGraphicsPipelineCreateInfo createInfo = {}; - VkPipelineLibraryCreateInfoKHR libInfo = {}; + CUtlVector stages = {}; + CUtlVector modules = {}; + VkPipelineVertexInputStateCreateInfo vertexInput = {}; + VkPipelineInputAssemblyStateCreateInfo inputAssembly = {}; + VkPipelineDynamicStateCreateInfo dynamicState = {}; + VkPipelineRasterizationStateCreateInfo rasterState = {}; + VkPipelineViewportStateCreateInfo viewportState = {}; + VkPipelineMultisampleStateCreateInfo msaa = {}; + VkPipelineDepthStencilStateCreateInfo depthStencil = {}; + VkPipelineColorBlendStateCreateInfo blend = {}; VkPipelineRenderingCreateInfo render = {}; - - createInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; - for ( auto l: m_libraries ) - { - libs.AppendTail(l->m_hPipeline); + CUtlVector attachments = {}; + VkDynamicState dynamicStates[] = { + VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT, + VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT, }; - - libInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LIBRARY_CREATE_INFO_KHR; - libInfo.libraryCount = libs.GetSize(); - libInfo.pLibraries = libs.GetData(); - createInfo.pNext = &libInfo; - createInfo.flags = VK_PIPELINE_CREATE_LINK_TIME_OPTIMIZATION_BIT_EXT; - createInfo.layout = g_pLibraryEmptyLayout; + VkPipelineLayoutCreateInfo stPipelineLayout = {}; + + stPipelineLayout.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + vkCreatePipelineLayout(m_hDevice, &stPipelineLayout, NULL, &m_hPipelineLayout); + + // TODO: Filter by vulkan shaders at some points + stages.Resize(m_shader.m_objects.GetSize()); + modules.Resize(m_shader.m_objects.GetSize()); + for ( int i = 0; i < m_shader.m_objects.GetSize(); i++ ) + { + V_printf("a: %p\n", m_shader.m_lumps[i].m_pAddress); + + modules[i].sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; + modules[i].pCode = (uint32_t*)m_shader.GetLumpPtr(m_shader.m_objects[i].m_nDataLump); + modules[i].codeSize = m_shader.GetLumpSize(m_shader.m_objects[i].m_nDataLump); + stages[i].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + stages[i].pNext = &modules[i]; + stages[i].pName = "main"; + stages[i].stage = VulkanGetShaderStage(m_shader.m_objects[i].m_eStage); + } + + vertexInput.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; + vertexInput.vertexBindingDescriptionCount = m_layouts.GetSize(); + vertexInput.pVertexBindingDescriptions = m_layouts.GetData(); + vertexInput.vertexAttributeDescriptionCount = m_attributes.GetSize(); + vertexInput.pVertexAttributeDescriptions = m_attributes.GetData(); + + inputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; + inputAssembly.primitiveRestartEnable = VK_FALSE; + inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + + dynamicState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; + dynamicState.dynamicStateCount = 2; + dynamicState.pDynamicStates = dynamicStates; + + rasterState.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; + rasterState.polygonMode = VK_POLYGON_MODE_FILL; + rasterState.lineWidth = 1; + rasterState.cullMode = VK_CULL_MODE_NONE; + rasterState.frontFace = VK_FRONT_FACE_CLOCKWISE; + + viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; + + msaa.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; + msaa.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; render.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO; - render.pNext = createInfo.pNext; + render.colorAttachmentCount = m_eFormats.GetSize(); + render.pColorAttachmentFormats = m_eFormats.GetData(); + + depthStencil.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; + + for ( auto e: m_eFormats ) + { + VkPipelineColorBlendAttachmentState a = {}; + a.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; + a.blendEnable = VK_FALSE; + attachments.AppendTail(a); + } + + blend.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; + blend.attachmentCount = attachments.GetSize(); + blend.pAttachments = attachments.GetData(); + + render.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO; + render.colorAttachmentCount = m_eFormats.GetSize(); + render.pColorAttachmentFormats = m_eFormats.GetData(); + + createInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; + createInfo.stageCount = stages.GetSize(); + createInfo.pStages = stages.GetData(); + createInfo.layout = m_hPipelineLayout; + createInfo.pVertexInputState = &vertexInput; + createInfo.pInputAssemblyState = &inputAssembly; + createInfo.pDynamicState = &dynamicState; + createInfo.pRasterizationState = &rasterState; + createInfo.pViewportState = &viewportState; + createInfo.pDepthStencilState = &depthStencil; + createInfo.pColorBlendState = &blend; + createInfo.pMultisampleState = &msaa; createInfo.pNext = &render; - // Possibly schedule it? - vkCreateGraphicsPipelines(g_vkDevice, NULL, 1, &createInfo, NULL, &m_hPipeline); + vkCreateGraphicsPipelines(m_hDevice, NULL, 1, &createInfo, NULL, &m_hPipeline); } uint32_t CVkShader::PSGetResourceByName( const char *szName ) @@ -44,4 +153,3 @@ uint32_t CVkShader::VSGetResourceByName( const char *szName ) { } - diff --git a/materialsystem/vulkan/vulkan_state.h b/materialsystem/vulkan/vulkan_state.h index 04db708..d85e3db 100644 --- a/materialsystem/vulkan/vulkan_state.h +++ b/materialsystem/vulkan/vulkan_state.h @@ -2,6 +2,7 @@ #define VULKAN_STATE_H +#include "shadercompiler/icompiler.h" #include "volk.h" #include "vk_mem_alloc.h" #include "tier0/platform.h" @@ -20,16 +21,7 @@ extern struct SupportedVulkanExtensions_t #undef REQUIRED_EXTENSION #undef OPTIONAL_EXTENSION -extern CUtlVector g_vkSwapchainImages; - - -extern CUtlVector g_vkCommandPools; -extern CUtlVector g_vkCommandBuffers; - -extern VkInstance g_vkInstance; -extern VmaAllocator g_vkAllocator; -extern VkPhysicalDevice g_vkPhysicalDevice; -extern VkDevice g_vkDevice; +#define FRAMES_IN_FLIGHT 2 enum EVulkanCommandType { @@ -56,7 +48,7 @@ enum EDependencyMode DEPENDENCY_MODE_SHADER_IMAGE_WRITE, DEPENDENCY_MODE_SHADER_BUFFER_WRITE, DEPENDENCY_MODE_SHADER_ACCELERATION_STRUCTURE, - + DEPENDENCY_MODE_DRAWCALL_VERTEX_BUFFER, DEPENDENCY_MODE_DRAWCALL_INDEX_BUFFER, DEPENDENCY_MODE_DRAWCALL_OUTPUT_IMAGE, @@ -65,13 +57,13 @@ enum EDependencyMode DEPENDENCY_MODE_IMAGE_SOURCE, DEPENDENCY_MODE_IMAGE_DESTINATION, - + DEPENDENCY_MODE_BLIT_IMAGE_SOURCE, DEPENDENCY_MODE_BLIT_IMAGE_DESTINATION, - + DEPENDENCY_MODE_COLOR_CLEAR_SOURCE, DEPENDENCY_MODE_COLOR_CLEAR_DESTINATION, - + DEPENDENCY_MODE_ALL_COMMANDS, DEPENDENCY_MODE_IMAGE_PRESENT, @@ -109,14 +101,16 @@ public: CUtlVector m_dependencies = {}; CUtlVector m_swapchainDependencies = {}; EVulkanCommandType m_eType; - + void AddDependency( IRenderingObject *pObject, EDependencyMode eDependencyMode ); void AddSwapchainDependency( IRenderingObject **ppObjects, EDependencyMode eDependencyMode ); }; +class IVkCommandBufferManager; abstract_class IVkCommandBuffer { public: + virtual void SetVulkanHandlers( VkDevice hDevice, IVkCommandBufferManager *pManager ) = 0; virtual void AddCommand( CVkCommand *pCommand ) = 0; virtual void Reset() = 0; @@ -129,11 +123,13 @@ typedef CVkCommand *(*fnCreateVulkanCommand_t)(); abstract_class IVkCommandBufferManager: public IAppSystem { public: + virtual void SetVulkanHandlers( VkInstance hInstance, VkDevice hDevice ) = 0; virtual IVkCommandBuffer *CreateCommandBuffer() = 0; virtual CVkCommand *CreateCommand( const char *szName ) = 0; + virtual CUtlVector &GetVulkanCommands() = 0; + virtual void RenderingFinished() = 0; }; #define VULKAN_COMMAND_BUFFER_MANAGER_INTERFACE_NAME "VulkanCommandBufferManager" -extern IVkCommandBufferManager *g_pCommandBufferManager; class CVkCommandRegistry { @@ -141,7 +137,7 @@ public: CVkCommandRegistry( const char *szName, fnCreateVulkanCommand_t pfnCreate ); }; #define CREATE_COMMAND(name) \ -(CVk##name##Command*)g_pCommandBufferManager->CreateCommand(#name) +(CVk##name##Command*)m_pCommandBufferManager->CreateCommand(#name) #define BEGIN_VULKAN_COMMAND( name ) \ class CVk##name##Command : public CVkCommand \ @@ -171,7 +167,7 @@ public: CVkImage(); CVkImage( uint32_t nWidth, uint32_t nHeight, uint32_t nDepth, EImageFormat eFormat, EMultisampleType eMultisampleType, EImageType eImageType, VkImageUsageFlagBits eUsage ); ~CVkImage(); - + virtual void SetDebugName( const char *szName ) override; virtual uint32_t GetImageWidth() override; virtual uint32_t GetImageHeight() override; @@ -194,7 +190,7 @@ public: VkImageView m_imageView; VmaAllocation m_allocation; VkImageSubresourceRange m_range; - + VkImageLayout m_ePreferredLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; VkImageLayout m_eImageLayout = VK_IMAGE_LAYOUT_UNDEFINED; @@ -226,6 +222,7 @@ public: virtual void Build() = 0; VkPipeline m_hPipeline = NULL; + VkDevice m_hDevice; }; #define BEGIN_DEFINE_PIPELINE_LIBRARY(name) \ @@ -250,20 +247,32 @@ void CVk##name##PipelineLibrary::Build() \ pipeline.layout = g_pLibraryEmptyLayout; #define END_BUILD_PIPELINE_LIBRARY() \ - vkCreateGraphicsPipelines(g_vkDevice, NULL, 1, &pipeline, NULL, &m_hPipeline); \ + vkCreateGraphicsPipelines(m_hDevice, NULL, 1, &pipeline, NULL, &m_hPipeline); \ } class CVkShader : public IShader { public: ~CVkShader(); - void AddShaderLibrary( CVkPipelineLibrary *pLibrary ); - void Build(); virtual uint32_t PSGetResourceByName( const char *szName ) override; virtual uint32_t VSGetResourceByName( const char *szName ) override; + virtual void AddLayout( int iIndex, int iStride ) override; + virtual void AddAttribute( int iBufferIndex, int iLocation, EVertexFormat eFormat, int iOffset ) override; + virtual void SetTopology( ETopologyMode eTopology ) override; + virtual void AddOutputImage( int iImageIndex, EImageFormat eFormat ) override; + virtual void SetDepthImage( EImageFormat eFormat ) override; + virtual void Build() override; + VkPipeline m_hPipeline = NULL; VkPipelineLayout m_hPipelineLayout; CUtlVector m_libraries; + VkDevice m_hDevice; + CCompiledShader m_shader; +private: + CUtlVector m_attributes; + CUtlVector m_layouts; + CUtlVector m_eFormats; + }; class CVkMaterial: public IMaterial @@ -271,13 +280,13 @@ class CVkMaterial: public IMaterial public: CVkMaterial( IShader *pShader ); virtual ~CVkMaterial() override; - + virtual void VSSetShaderResource( uint32_t uRegister, IRenderingObject *pResource ) override; virtual void VSSetConstantsBuffer( uint32_t uRegister, IBuffer *pConstants ) override; - + virtual void PSSetShaderResource( uint32_t uRegister, IRenderingObject *pResource ) override; virtual void PSSetConstantsBuffer( uint32_t uRegister, IBuffer *pConstants ) override; - + CVkShader *m_pVkShader; private: void SetShaderResource( uint32_t uRegister, uint32_t uSet, IRenderingObject *pObject); @@ -332,13 +341,13 @@ class CVkRenderCommandList: public IRenderCommandList { public: virtual void ResetRendering() override; - + virtual void SetRenderTarget( uint32_t uIndex, IImage *pImage ) override; virtual void SetClearColor( uint32_t uIndex, float r, float g, float b, float a ) override; - + virtual void SetDepthTarget( IImage *pDepth ) override; virtual void SetClearDepth( float fVal ) override; - + virtual void SetRenderResolution( uint32_t iWidth, uint32_t iHeight ) override; // Should they apply per material or for all? @@ -350,13 +359,15 @@ public: virtual void SetIndexBuffer( IVertexBuffer *pBuffer ) override; virtual void DrawPrimitives( uint32_t nVertexCount, uint32_t nFirstVertex, uint32_t nInstanceCount, uint32_t nFirstInstance ) override; virtual void DrawPrimitivesIndexed( uint32_t nIndexCount, uint32_t nFirstIndex, uint32_t nVertexOffset, uint32_t nInstanceCount, uint32_t nFirstInstance ) override; - + virtual void ResolveImage( IImage *pOriginal, IImage *pResolved ) override; virtual void StartRecording() override; virtual void EndRecording() override; - + void Submit(); + + IVkCommandBufferManager *m_pCommandBufferManager; private: void SwitchRenderingStage( EVulkanRenderingStage eStage ); @@ -370,6 +381,9 @@ private: IVkCommandBuffer *m_pPostRaster; IVkCommandBuffer *m_pCurrentMaterialBuffer = NULL; + + uint32_t m_uWidth; + uint32_t m_uHeight; }; diff --git a/public/materialsystem/compiledshadermgr.h b/public/materialsystem/compiledshadermgr.h index bcce6cb..dacf16a 100644 --- a/public/materialsystem/compiledshadermgr.h +++ b/public/materialsystem/compiledshadermgr.h @@ -12,6 +12,6 @@ public: virtual void ReadFromFile( CCompiledShader *pShader, const char *szFile ) = 0; }; -ICompiledShaderManager *CompiledShaderManager(); +#define COMPILED_SHADER_MANAGER_INTERFACE_VERSION "CompiledShaderManager001" #endif diff --git a/public/igamewindow.h b/public/materialsystem/igamewindow.h similarity index 52% rename from public/igamewindow.h rename to public/materialsystem/igamewindow.h index ce24c3a..c257f8e 100644 --- a/public/igamewindow.h +++ b/public/materialsystem/igamewindow.h @@ -1,23 +1,31 @@ #ifndef GAME_WINDOW_H #define GAME_WINDOW_H -#include "gamesystem.h" #include "tier0/platform.h" -#include "materialsystem/imaterialsystem.h" +#include "tier2/iappsystem.h" -abstract_class IGameWindow: public IGameSystem +class IImage; +abstract_class IGameWindow: public IAppSystem { public: + virtual void Frame( float fDelta ) = 0; + virtual uint32_t GetRenderWidth() = 0; virtual uint32_t GetRenderHeight() = 0; + virtual bool BRenderSizeUpdated() = 0; + + virtual void SetOutputImage( IImage *pImage ) = 0; + virtual IImage *GetOutputImage() = 0; virtual void *CreateVulkanSurface( void *pInstance ) = 0; virtual void DestroyVulkanSurface( void *pInstance ) = 0; }; -abstract_class IGameWindowManager: public IGameSystem +abstract_class IGameWindowManager: public IAppSystem { public: + virtual void Frame( float fDelta ) = 0; + virtual IGameWindow *CreateWindow() = 0; virtual void DestroyWindow( IGameWindow* pWindow ) = 0; @@ -25,4 +33,7 @@ public: virtual const char **GetVulkanInstanceExtensions() = 0; }; +IGameWindowManager *GameWindowManager(); +#define GAME_WINDOW_MANAGER_INTERFACE_VERSION "GameWindowMgr001" + #endif diff --git a/public/materialsystem/imaterialsystem.h b/public/materialsystem/imaterialsystem.h index 35f7d55..90da3cf 100644 --- a/public/materialsystem/imaterialsystem.h +++ b/public/materialsystem/imaterialsystem.h @@ -131,12 +131,18 @@ public: virtual ~IShader() = default; virtual uint32_t PSGetResourceByName( const char *szName ) = 0; virtual uint32_t VSGetResourceByName( const char *szName ) = 0; + virtual void AddLayout( int iIndex, int iStride ) = 0; + virtual void AddAttribute( int iBufferIndex, int iLocation, EVertexFormat eFormat, int iOffset ) = 0; + virtual void SetTopology( ETopologyMode eTopology ) = 0; + virtual void AddOutputImage( int iImageIndex, EImageFormat eFormat ) = 0; + virtual void SetDepthImage( EImageFormat eFormat ) = 0; + virtual void Build() = 0; }; //----------------------------------------------------------------------------- // 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. //----------------------------------------------------------------------------- @@ -154,13 +160,13 @@ abstract_class IRenderCommandList { public: virtual void ResetRendering() = 0; - + virtual void SetRenderTarget( uint32_t uIndex, IImage *pImage ) = 0; virtual void SetClearColor( uint32_t uIndex, float r, float g, float b, float a ) = 0; - + virtual void SetDepthTarget( IImage *pDepth ) = 0; virtual void SetClearDepth( float fVal ) = 0; - + virtual void SetRenderResolution( uint32_t iWidth, uint32_t iHeight ) = 0; virtual void SetScissors( uint32_t uX, uint32_t uY, uint32_t uWidth, uint32_t uHeight ) = 0; @@ -171,7 +177,7 @@ public: virtual void SetIndexBuffer( IVertexBuffer *pBuffer ) = 0; virtual void DrawPrimitives( uint32_t nVertexCount, uint32_t nFirstVertex, uint32_t nInstanceCount, uint32_t nFirstInstance ) = 0; virtual void DrawPrimitivesIndexed( uint32_t nIndexCount, uint32_t nFirstIndex, uint32_t nVertexOffset, uint32_t nInstanceCount, uint32_t nFirstInstance ) = 0; - + virtual void ResolveImage( IImage *pOriginal, IImage *pResolved ) = 0; virtual void StartRecording() = 0; @@ -207,7 +213,7 @@ public: virtual IRenderCommandList *CreateCommandList() = 0; virtual void DestroyCommandList( IRenderCommandList *pCommandList ) = 0; virtual void SubmitCommandList(IRenderCommandList *pList) = 0; - + virtual void SetMainWindowManager( IGameWindowManager *pWindowManager ) = 0; virtual void RenderGameWindow( IGameWindow *pWindow ) = 0; diff --git a/shadercompiler/build.cpp b/shadercompiler/build.cpp index 3edaefd..6b6adbe 100644 --- a/shadercompiler/build.cpp +++ b/shadercompiler/build.cpp @@ -3,6 +3,9 @@ #include "ld.h" #include "target.h" +ADD_DEPENDENCY_BUILD_FILE(tier0, "../external/funnystdlib/tier0/build.cpp") +ADD_DEPENDENCY_BUILD_FILE(tier1, "../external/funnystdlib/tier1/build.cpp") +ADD_DEPENDENCY_BUILD_FILE(tier2, "../external/funnystdlib/tier2/build.cpp") DECLARE_BUILD_STAGE(libshadercompiler) { CProject_t stProject; @@ -13,6 +16,7 @@ DECLARE_BUILD_STAGE(libshadercompiler) stProject.bFPIC = true; stProject.includeDirectories = { "../public", + "../external/funnystdlib/public", "../external/slang/include", "../external/Vulkan-Headers/include", }; @@ -22,7 +26,11 @@ DECLARE_BUILD_STAGE(libshadercompiler) }; stLinkProject = ccompiler->Compile(&stProject); - stLinkProject.linkType = ELINK_STATIC_LIBRARY; + stLinkProject.libraryObjects = { + GET_PROJECT_LIBRARY(tier0, "tier0"), + }; + stLinkProject.objects.AppendTail({GET_PROJECT_LIBRARY(tier1, "tier1")}); + stLinkProject.linkType = ELINK_DYNAMIC_LIBRARY; szOutput = linker->Link(&stLinkProject); ADD_OUTPUT_OBJECT("lib", szOutput); @@ -36,42 +44,45 @@ DECLARE_BUILD_STAGE(shadercompiler) CUtlString szOutput; stProject.m_szName = "fsc"; - stProject.m_target = Target_t::HostTarget(); - stProject.includeDirectories = {"public"}; + stProject.includeDirectories = {"../public", "../external/funnystdlib/public"}; stProject.files = { "main.cpp", + "../materialsystem/compiledshader.cpp", }; stLinkProject = ccompiler->Compile(&stProject); stLinkProject.linkType = ELINK_EXECUTABLE; - stLinkProject.objects.AppendTail((Object_t){tier0_lib}); - stLinkProject.objects.AppendTail((Object_t){tier1_lib}); - stLinkProject.objects.AppendTail((Object_t){tier2_lib}); - stLinkProject.objects.AppendTail((Object_t){shadercompiler_lib}); + stLinkProject.libraryObjects = { + GET_PROJECT_LIBRARY(tier0, "tier0"), + }; + 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.libraryDirectories = {"external/linux"}; + stLinkProject.libraryDirectories = {"../external/linux"}; szOutput = linker->Link(&stLinkProject); - /* - filesystem2->MakeDirectory(CUtlString("%s/bin/tools", szOutputDir.GetString())); - filesystem2->CopyFile(CUtlString("%s/bin/tools", szOutputDir.GetString()), szOutput); - filesystem2->CopyFile(CUtlString("%s/bin/tools", szOutputDir.GetString()), "external/linux/libslang-compiler.so.0.2025.24.2"); - filesystem2->CopyFile(CUtlString("%s/bin/tools", szOutputDir.GetString()), "external/linux/libslang-glslang-2025.24.2.so"); - shadercompiler_exe = CUtlString("%s/bin/tools/fsc", szOutputDir.GetString()); - */ + filesystem2->MakeDirectory(CUtlString("../build/tools")); + filesystem2->CopyFile(CUtlString("../build/tools"), szOutput); + 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"); + ADD_OUTPUT_OBJECT("compiler", szOutput); return 1; } -/* DECLARE_BUILD_STAGE(compileshaders) { + CUtlString szShaderCompiler = "../build/tools/fsc"; if (CommandLine()->CheckParam("-nofsc")) return 0; - CUtlVector args = {"-i", "funnyassets", "-o", "build/funnygame/assets"}; + filesystem2->MakeDirectory(CUtlString("../build/funnygame/assets")); + CUtlVector args = {"-i", "../funnyassets", "-o", "../build/funnygame/assets"}; - runner->Run(shadercompiler_exe, args); + runner->Run(szShaderCompiler, args); runner->Wait(); + V_printf("Cool\n"); return 0; }; -*/ diff --git a/shadercompiler/main.cpp b/shadercompiler/main.cpp index 33e56c2..dbf11fa 100644 --- a/shadercompiler/main.cpp +++ b/shadercompiler/main.cpp @@ -1,5 +1,5 @@ #include "tier0/lib.h" -#include "tier1/commandline.h" +#include "tier0/commandline.h" #include "tier1/appinit.h" #include "tier1/utlstring.h" #include "tier2/ifilesystem.h" @@ -8,6 +8,7 @@ static IShaderCompiler *s_pVulkanSpirvCompiler; static const char *s_szGameRoot; +ICompiledShaderManager *g_pShaderManager; void CompileShader( const char *szShader ) { @@ -18,17 +19,16 @@ void CompileShader( const char *szShader ) s_pVulkanSpirvCompiler->CompileShader(szShader, &shader); - Plat_MakeDir("build/funnygame/assets", 0755); - Plat_MakeDir("build/funnygame/assets/shaders", 0755); + Plat_MakeDir("../build/funnygame/assets", 0755); + Plat_MakeDir("../build/funnygame/assets/shaders", 0755); CUtlString szOutputDirectory = szShader; szOutputDirectory.RemoveHead(strlen(s_szGameRoot)+1); - szOutputDirectory.AppendHead("build/funnygame/assets/"); + szOutputDirectory.AppendHead("../build/funnygame/assets/"); szOutputDirectory.AppendTail("_c"); printf("%s\n",szOutputDirectory.GetString()); - - CompiledShaderManager()->WriteToFile(&shader, szOutputDirectory); + g_pShaderManager->WriteToFile(&shader, szOutputDirectory); }; void PrintHelp() @@ -40,11 +40,21 @@ void PrintHelp() int main( int c, char **v ) { CUtlString szExePath = Plat_GetExecutablePath(); + CUtlString szOriginalPath = Plat_GetWorkingDir(); + CommandLine()->CreateCommandLine(c, v); + + Plat_SetWorkingDir(szExePath.GetDirectory()); + CreateInterfaceFn g_pCompilerFactory = Sys_GetFactory("ShaderCompiler"); + Plat_SetWorkingDir(szOriginalPath); + g_pShaderManager = (ICompiledShaderManager*)g_pCompilerFactory(COMPILED_SHADER_MANAGER_INTERFACE_VERSION, NULL); + + CreateInterfaceFn pFilesystemFactory = Sys_GetFactory("filesystem_std"); + filesystem = (IFileSystem*)pFilesystemFactory(FILESYSTEM_INTERFACE_VERSION, NULL); filesystem->Init(); - s_pVulkanSpirvCompiler = (IShaderCompiler*)CreateInterface(SLANG_SHADER_COMPILER_SPIRV_VULKAN, NULL); + s_pVulkanSpirvCompiler = (IShaderCompiler*)g_pCompilerFactory(SLANG_SHADER_COMPILER_SPIRV_VULKAN, NULL); s_pVulkanSpirvCompiler->Init(); const char *szInputDirectory = CommandLine()->ParamValue("-i"); diff --git a/shadercompiler/slang/vulkan_spirv.cpp b/shadercompiler/slang/vulkan_spirv.cpp index 302284f..af303a4 100644 --- a/shadercompiler/slang/vulkan_spirv.cpp +++ b/shadercompiler/slang/vulkan_spirv.cpp @@ -72,12 +72,19 @@ void CSlangVulkanSpirvShaderCompiler::CompileShader( const char *szInput, CCompi ISession *pSession = NULL; IBlob *pShaderSourceBlob = NULL; + if (filesystem == NULL) + { + + CreateInterfaceFn pFilesystemFactory = Sys_GetFactory("filesystem_std"); + filesystem = (IFileSystem*)pFilesystemFactory(FILESYSTEM_INTERFACE_VERSION, NULL); + filesystem->Init(); + } IFileHandle *pFile = filesystem->Open(szInput, FILEMODE_READ); const char *szShaderSource = filesystem->ReadString(pFile); int i = 0; - pShaderSourceBlob = slang_createBlob(szShaderSource, pFile->Size()); + pShaderSourceBlob = slang_createBlob(szShaderSource, filesystem->Size(pFile)); filesystem->Close(pFile); printf(" SLANG %s\n", szInput);