made rendering work

This commit is contained in:
2026-02-05 11:10:40 +02:00
parent faae0bdcc7
commit 4bfbcaa4a6
22 changed files with 737 additions and 483 deletions

View File

@@ -10,8 +10,9 @@ ADD_DEPENDENCY_BUILD_FILE(engine, "engine/build.cpp");
ADD_DEPENDENCY_BUILD_FILE(ms, "materialsystem/build.cpp"); ADD_DEPENDENCY_BUILD_FILE(ms, "materialsystem/build.cpp");
ADD_DEPENDENCY_BUILD_FILE(fs, "external/funnystdlib/stdfilesystems/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(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->MakeDirectory(szOutputDir);
filesystem2->CopyFile(szOutputDir, GET_PROJECT_OBJECT(launcher, "launcher")); 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(RenderSystemVulkan, "RenderSystemVulkan"));
filesystem2->CopyFile(szOutputDir, GET_PROJECT_OBJECT(tier0, "tier0")); filesystem2->CopyFile(szOutputDir, GET_PROJECT_OBJECT(tier0, "tier0"));
filesystem2->CopyFile(szOutputDir, GET_PROJECT_OBJECT(filesystem_std, "fs")); 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; return 0;
} }

View File

@@ -1,65 +0,0 @@
#include "helper.h"
#include "c.h"
#include "ld.h"
#include "tier1/utlstring.h"
CUtlVector<CUtlString> 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<CUtlString> 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;
};

View File

@@ -11,11 +11,6 @@ ADD_DEPENDENCY_BUILD_FILE(tier2, FUNNYSTDLIB"tier2/build.cpp");
DECLARE_BUILD_STAGE(engine) DECLARE_BUILD_STAGE(engine)
{ {
bool bUsesSDL = true;
if (Target_t::DefaultTarget().cpu == TARGET_CPU_WASM32)
{
bUsesSDL = false;
}
CProject_t compileProject = {}; CProject_t compileProject = {};
LinkProject_t ldProject = {}; LinkProject_t ldProject = {};
@@ -27,8 +22,6 @@ DECLARE_BUILD_STAGE(engine)
"sv_dll.cpp", "sv_dll.cpp",
"cl_dll.cpp", "cl_dll.cpp",
}; };
if (bUsesSDL)
compileProject.files.AppendTail("gamewindow_sdl.cpp");
compileProject.includeDirectories = { compileProject.includeDirectories = {
"../public", "../public",
@@ -46,8 +39,6 @@ DECLARE_BUILD_STAGE(engine)
ldProject.objects.AppendTail({GET_PROJECT_LIBRARY(tier1, "tier1")}); ldProject.objects.AppendTail({GET_PROJECT_LIBRARY(tier1, "tier1")});
ldProject.objects.AppendTail({GET_PROJECT_LIBRARY(tier2, "tier2")}); ldProject.objects.AppendTail({GET_PROJECT_LIBRARY(tier2, "tier2")});
if (bUsesSDL)
ldProject.libraries.AppendTail("SDL3");
if (ldProject.m_target.kernel & TARGET_KERNEL_WINDOWS_DEVICES) if (ldProject.m_target.kernel & TARGET_KERNEL_WINDOWS_DEVICES)
{ {
ldProject.libraryDirectories = {"../external/windows"}; ldProject.libraryDirectories = {"../external/windows"};

View File

@@ -1,6 +1,6 @@
#include "tier2/ifilesystem.h" #include "tier2/ifilesystem.h"
#include "igamewindow.h" #include "materialsystem/igamewindow.h"
#include "materialsystem/imaterialsystem.h" #include "materialsystem/imaterialsystem.h"
#include "tier1/interface.h" #include "tier1/interface.h"
#include "tier0/commandline.h" #include "tier0/commandline.h"
@@ -9,21 +9,34 @@
IRenderContext *g_pRenderContext; IRenderContext *g_pRenderContext;
IFileSystem *filesystem; IFileSystem *filesystem;
IGameWindowManager *g_pWindowManager;
extern "C" void FunnyMain( int argc, char **argv ) extern "C" void FunnyMain( int argc, char **argv )
{ {
CommandLine()->CreateCommandLine(argc, argv); CommandLine()->CreateCommandLine(argc, argv);
CreateInterfaceFn pFilesystemFactory = Sys_GetFactory("filesystem_std"); CreateInterfaceFn pFilesystemFactory = Sys_GetFactory("filesystem_std");
CreateInterfaceFn pMaterialSystemFactory = Sys_GetFactory("MaterialSystem");
CreateInterfaceFn pRenderSystemFactory = Sys_GetFactory("RenderSystemVulkan");
filesystem = (IFileSystem*)pFilesystemFactory(FILESYSTEM_INTERFACE_VERSION, NULL); filesystem = (IFileSystem*)pFilesystemFactory(FILESYSTEM_INTERFACE_VERSION, NULL);
filesystem->Init(); filesystem->Init();
CreateInterfaceFn pMaterialSystemFactory = Sys_GetFactory("MaterialSystem"); g_pWindowManager = (IGameWindowManager*)pRenderSystemFactory(GAME_WINDOW_MANAGER_INTERFACE_VERSION, NULL);
CreateInterfaceFn pRenderSystemFactory = Sys_GetFactory("RenderSystemVulkan"); 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 = (IRenderContext*)pRenderSystemFactory(RENDER_CONTEXT_INTERFACE_VERSION, NULL);
g_pRenderContext->SetMainWindowManager(g_pWindowManager);
g_pRenderContext->Init(); g_pRenderContext->Init();
g_pRenderContext->RegisterGameWindow(pWindow);
ServerGameDLL()->Init(); ServerGameDLL()->Init();
IShader *pShader = NULL; IShader *pShader = NULL;
@@ -33,54 +46,68 @@ extern "C" void FunnyMain( int argc, char **argv )
IImage *pOutputImage = NULL; IImage *pOutputImage = NULL;
IVertexBuffer *pVertices = NULL; IVertexBuffer *pVertices = NULL;
float vertices[9] = { float vertices[18] = {
0,-0.5, 0.5, -0.5, -0.5, 0,
0.5,0.5, 0.5, 0.5, -0.5, 0,
-0.5,0.5, 0.5, -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(); void *pMapped = pVertices->Map();
V_memcpy(pMapped, vertices, 36); V_memcpy(pMapped, vertices, 72);
pVertices->Unmap(); pVertices->Unmap();
pCameraInfoBuffer = g_pRenderContext->CreateConstantBuffer(64); pCameraInfoBuffer = g_pRenderContext->CreateConstantBuffer(64);
/* pShader = g_pRenderContext->CreateShader("game/core/shaders/flat.shader_c");
pShader = g_pRenderContext->CreateShader("funnygame/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 = g_pRenderContext->CreateMaterial(pShader);
pMaterial->PSSetConstantsBuffer(0, pCameraInfoBuffer); pMaterial->PSSetConstantsBuffer(0, pCameraInfoBuffer);
*/
pOutputImage = g_pRenderContext->CreateRenderTarget( pOutputImage = g_pRenderContext->CreateRenderTarget(
1280, 100,
720, 100,
IMAGE_FORMAT_RGBA8_UNORM, IMAGE_FORMAT_RGBA8_UNORM,
MULTISAMPLE_TYPE_NONE); MULTISAMPLE_TYPE_NONE);
IRenderCommandList *pCommandList = g_pRenderContext->CreateCommandList();
pCommandList->StartRecording();
pCommandList->SetRenderTarget(0, pOutputImage);
pCommandList->SetClearColor(0, 1,0,0,0);
pCommandList->EndRecording();
for (;;) { for (;;) {
/* g_pWindowManager->Frame(0);
if (g_pRenderContext->BIsOutputImageOutdated()) if (pWindow->BRenderSizeUpdated())
{ {
uint32_t nWidth; g_pRenderContext->DestroyImage(pOutputImage);
uint32_t nHeight;
pOutputImage = g_pRenderContext->CreateRenderTarget( pOutputImage = g_pRenderContext->CreateRenderTarget(
g_pRenderContext->GetNewOutputImageWidth(), pWindow->GetRenderWidth(),
g_pRenderContext->GetNewOutputImageHeight(), pWindow->GetRenderHeight(),
IMAGE_FORMAT_RGBA8_UNORM, IMAGE_FORMAT_RGBA8_UNORM,
MULTISAMPLE_TYPE_NONE); 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->SubmitCommandList(pCommandList);
g_pRenderContext->Frame(0); g_pRenderContext->Frame(0);
g_pRenderContext->DestroyCommandList(pCommandList);
}; };
}; };

View File

@@ -22,11 +22,6 @@ COMMON
} }
VS VS
{ {
cbuffer CameraInfo
{
float4x4 m_viewProj;
};
struct VS_INPUT struct VS_INPUT
{ {
float3 m_vPosition: POSITION; float3 m_vPosition: POSITION;

View File

@@ -27,6 +27,7 @@ CUtlVector<CUtlString> RenderContextVulkan_CompiledFiles = {
"vulkan/commands/base.cpp", "vulkan/commands/base.cpp",
"vulkan/libraries/raster.cpp", "vulkan/libraries/raster.cpp",
"../external/volk/volk.c", "../external/volk/volk.c",
"gamewindow_sdl.cpp"
}; };
DECLARE_BUILD_STAGE(MaterialSystem) DECLARE_BUILD_STAGE(MaterialSystem)
@@ -87,6 +88,7 @@ DECLARE_BUILD_STAGE(RenderSystemVulkan)
{ {
ldProject.libraries.AppendTail("pthread"); ldProject.libraries.AppendTail("pthread");
}; };
ldProject.libraries.AppendTail("SDL3");
CUtlString outputProject = linker->Link(&ldProject); CUtlString outputProject = linker->Link(&ldProject);
ADD_OUTPUT_OBJECT("RenderSystemVulkan", outputProject); ADD_OUTPUT_OBJECT("RenderSystemVulkan", outputProject);

View File

@@ -1,5 +1,6 @@
#include "shadercompiler/icompiler.h" #include "shadercompiler/icompiler.h"
#include "materialsystem/compiledshadermgr.h" #include "materialsystem/compiledshadermgr.h"
#include "tier0/lib.h"
#include "tier2/ifilesystem.h" #include "tier2/ifilesystem.h"
uint32_t CCompiledShader::AllocateLump( uint32_t nSize ) uint32_t CCompiledShader::AllocateLump( uint32_t nSize )
@@ -43,8 +44,6 @@ ShaderObject_t *CCompiledShader::FindShaderObject( EShaderBackend eBackend, ESha
CCompiledShader::~CCompiledShader() CCompiledShader::~CCompiledShader()
{ {
for ( auto l: m_lumps )
V_free(l.m_pAddress);
} }
@@ -73,7 +72,6 @@ void CCompiledShaderManager::WriteToFile( CCompiledShader *pShader, const char *
{ {
CreateInterfaceFn pFilesystemFactory = Sys_GetFactory("filesystem_std"); CreateInterfaceFn pFilesystemFactory = Sys_GetFactory("filesystem_std");
filesystem = (IFileSystem*)pFilesystemFactory(FILESYSTEM_INTERFACE_VERSION, NULL); filesystem = (IFileSystem*)pFilesystemFactory(FILESYSTEM_INTERFACE_VERSION, NULL);
} }
pFile = filesystem->Open(szFile, FILEMODE_WRITE); pFile = filesystem->Open(szFile, FILEMODE_WRITE);
filesystem->Write(pFile, &stHeader, sizeof(ShaderHeader_t)); filesystem->Write(pFile, &stHeader, sizeof(ShaderHeader_t));
@@ -95,9 +93,9 @@ void CCompiledShaderManager::WriteToFile( CCompiledShader *pShader, const char *
} }
// ShaderObject_t // ShaderObject_t
for ( auto o: pShader->m_objects ) for ( auto o: pShader->m_objects )
{ {
filesystem->Write(pFile, &o, sizeof(o));
} }
@@ -120,8 +118,14 @@ void CCompiledShaderManager::ReadFromFile( CCompiledShader *pShader, const char
CUtlVector<ShaderObject_t> objects = {}; CUtlVector<ShaderObject_t> objects = {};
CUtlVector<HostShaderLump_t> lumpsData = {}; CUtlVector<HostShaderLump_t> lumpsData = {};
if ( filesystem == NULL )
{
CreateInterfaceFn pFilesystemFactory = Sys_GetFactory("filesystem_std");
filesystem = (IFileSystem*)pFilesystemFactory(FILESYSTEM_INTERFACE_VERSION, NULL);
}
pFile = filesystem->Open(szFile, FILEMODE_READ); 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); objects.Resize(stHeader.m_nNumShaders);
lumps.Resize(stHeader.m_nNumLumps); lumps.Resize(stHeader.m_nNumLumps);
@@ -150,3 +154,4 @@ ICompiledShaderManager *CompiledShaderManager()
static CCompiledShaderManager s_CompiledShaderManager; static CCompiledShaderManager s_CompiledShaderManager;
return &s_CompiledShaderManager; return &s_CompiledShaderManager;
} }
EXPOSE_INTERFACE_FN(CompiledShaderManager, ICompiledShaderManager, COMPILED_SHADER_MANAGER_INTERFACE_VERSION)

View File

@@ -1,5 +1,5 @@
#include "SDL3/SDL_error.h" #include "SDL3/SDL_error.h"
#include "igamewindow.h" #include "materialsystem/igamewindow.h"
#include "tier0/lib.h" #include "tier0/lib.h"
#include "tier0/platform.h" #include "tier0/platform.h"
#include "tier1/interface.h" #include "tier1/interface.h"
@@ -17,28 +17,39 @@ class CSDLGameWindow: public IGameWindow
public: public:
virtual void Init() override; virtual void Init() override;
virtual void Shutdown() override; virtual void Shutdown() override;
virtual void Tick( float fDelta ) override;
virtual void Frame( float fDelta ) override; virtual void Frame( float fDelta ) override;
virtual uint32_t GetRenderWidth() override; virtual uint32_t GetRenderWidth() override;
virtual uint32_t GetRenderHeight() 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 *CreateVulkanSurface( void *pInstance ) override;
virtual void DestroyVulkanSurface( void *pInstance ) override; virtual void DestroyVulkanSurface( void *pInstance ) override;
SDL_WindowID WindowID();
bool m_bWindowSizeUpdated;
uint32_t m_uRenderWidth;
uint32_t m_uRenderHeight;
private: private:
VkSurfaceKHR m_hSurface; VkSurfaceKHR m_hSurface;
SDL_Window *m_pWindow; SDL_Window *m_pWindow;
IImage *m_pOutputImage;
}; };
void CSDLGameWindow::Init() 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); m_pWindow = SDL_CreateWindow("funnygame", 1280, 720, SDL_WINDOW_VULKAN | SDL_WINDOW_RESIZABLE);
if (!m_pWindow) if (!m_pWindow)
Plat_FatalErrorFunc("SDL_CreateWindow: %s\n", SDL_GetError()); Plat_FatalErrorFunc("SDL_CreateWindow: %s\n", SDL_GetError());
m_uRenderWidth = 1280;
m_uRenderWidth = 720;
} }
void CSDLGameWindow::Shutdown() void CSDLGameWindow::Shutdown()
@@ -48,37 +59,35 @@ void CSDLGameWindow::Shutdown()
void CSDLGameWindow::Frame( float fDelta ) 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() uint32_t CSDLGameWindow::GetRenderWidth()
{ {
return 0; return m_uRenderWidth;
} }
uint32_t CSDLGameWindow::GetRenderHeight() 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 ) void *CSDLGameWindow::CreateVulkanSurface( void *pInstance )
{ {
@@ -90,12 +99,16 @@ void CSDLGameWindow::DestroyVulkanSurface( void *pInstance )
{ {
SDL_Vulkan_DestroySurface((VkInstance)pInstance, (VkSurfaceKHR)m_hSurface, NULL); SDL_Vulkan_DestroySurface((VkInstance)pInstance, (VkSurfaceKHR)m_hSurface, NULL);
} }
SDL_WindowID CSDLGameWindow::WindowID()
{
return SDL_GetWindowID(m_pWindow);
}
class CSDLGameWindowManager: public IGameWindowManager class CSDLGameWindowManager: public IGameWindowManager
{ {
public:
virtual void Init() override; virtual void Init() override;
virtual void Tick( float fDelta ) override;
virtual void Frame( float fDelta ) override; virtual void Frame( float fDelta ) override;
virtual void Shutdown() override; virtual void Shutdown() override;
@@ -104,21 +117,56 @@ class CSDLGameWindowManager: public IGameWindowManager
virtual int GetVulkanInstanceExtensionCount() override; virtual int GetVulkanInstanceExtensionCount() override;
virtual const char **GetVulkanInstanceExtensions() override; virtual const char **GetVulkanInstanceExtensions() override;
private:
CUtlVector<CSDLGameWindow*> m_pWindows;
}; };
IGameWindowManager *GameWindowManager()
{
static CSDLGameWindowManager mgr;
return &mgr;
}
EXPOSE_INTERFACE_FN(GameWindowManager, IGameWindowManager, GAME_WINDOW_MANAGER_INTERFACE_VERSION)
void CSDLGameWindowManager::Init() void CSDLGameWindowManager::Init()
{ {
if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS | SDL_INIT_GAMEPAD))
} Plat_FatalErrorFunc("SDL_Init: %s\n", SDL_GetError());
void CSDLGameWindowManager::Tick( float fDelta )
{
} }
void CSDLGameWindowManager::Frame( float fDelta ) 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() void CSDLGameWindowManager::Shutdown()
@@ -129,12 +177,14 @@ void CSDLGameWindowManager::Shutdown()
IGameWindow *CSDLGameWindowManager::CreateWindow() IGameWindow *CSDLGameWindowManager::CreateWindow()
{ {
CSDLGameWindow *pWindow = new CSDLGameWindow;
m_pWindows.AppendTail(pWindow);
return pWindow;
} }
void CSDLGameWindowManager::DestroyWindow( IGameWindow* pWindow ) void CSDLGameWindowManager::DestroyWindow( IGameWindow* pWindow )
{ {
delete (CSDLGameWindow*)pWindow;
} }

View File

@@ -1,5 +1,5 @@
#include "materialsystem/imaterialsystem.h" #include "materialsystem/imaterialsystem.h"
#include "igamewindow.h" #include "materialsystem/igamewindow.h"
class CMaterialSystem: public IMaterialSystem class CMaterialSystem: public IMaterialSystem
{ {

View File

@@ -4,9 +4,6 @@
#include "tier1/utlvector.h" #include "tier1/utlvector.h"
#include "vulkan_state.h" #include "vulkan_state.h"
CUtlVector<VkCommandBuffer> g_vkCommandBuffers;
IVkCommandBufferManager *g_pCommandBufferManager;
struct VulkanCommandLastUsage_t struct VulkanCommandLastUsage_t
{ {
uint32_t m_nLastUsedCommand; uint32_t m_nLastUsedCommand;
@@ -24,6 +21,7 @@ struct VulkanSwapchainCommandLastUsage_t
class CVkCommandBuffer: public IVkCommandBuffer class CVkCommandBuffer: public IVkCommandBuffer
{ {
public: public:
virtual void SetVulkanHandlers( VkDevice hDevice, IVkCommandBufferManager *pManager ) override;
virtual void AddCommand( CVkCommand *pCommand ) override; virtual void AddCommand( CVkCommand *pCommand ) override;
virtual void Reset() override; virtual void Reset() override;
virtual void Submit( int iFrameIndex ) override; virtual void Submit( int iFrameIndex ) override;
@@ -39,25 +37,34 @@ private:
CUtlVector<CUtlVector<VulkanCommandLastUsage_t>> m_dependencies; CUtlVector<CUtlVector<VulkanCommandLastUsage_t>> m_dependencies;
CUtlVector<VulkanSwapchainCommandLastUsage_t> m_usedSwapchainDependencies; CUtlVector<VulkanSwapchainCommandLastUsage_t> m_usedSwapchainDependencies;
CUtlVector<CUtlVector<VulkanSwapchainCommandLastUsage_t>> m_swapchainDependencies; CUtlVector<CUtlVector<VulkanSwapchainCommandLastUsage_t>> 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() void CVkCommandBuffer::Reset()
{ {
VkCommandBufferAllocateInfo commandBufferAllocInfo = {}; 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 = {};
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.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
commandBufferAllocInfo.commandPool = pool; commandBufferAllocInfo.commandPool = m_hPool;
commandBufferAllocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; commandBufferAllocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
commandBufferAllocInfo.commandBufferCount = 1; commandBufferAllocInfo.commandBufferCount = FRAMES_IN_FLIGHT;
vkAllocateCommandBuffers(g_vkDevice, &commandBufferAllocInfo, &m_hBuffers[i]); vkAllocateCommandBuffers(m_hDevice, &commandBufferAllocInfo, m_hBuffers.GetData());
i++;
}
m_commands = {}; m_commands = {};
} }
@@ -69,7 +76,7 @@ void CVkCommandBuffer::AddCommand( CVkCommand *pCommand )
void CVkCommandBuffer::Submit( int iFrameIndex ) void CVkCommandBuffer::Submit( int iFrameIndex )
{ {
g_vkCommandBuffers.AppendTail(m_hBuffers[iFrameIndex]); m_pMgr->GetVulkanCommands().AppendTail(m_hBuffers[iFrameIndex]);
}; };
struct VulkanBarrierObjects_t struct VulkanBarrierObjects_t
@@ -332,8 +339,15 @@ class CVkCommandBufferManager: public IVkCommandBufferManager
public: public:
virtual void Init() override; virtual void Init() override;
virtual void Shutdown() override; virtual void Shutdown() override;
virtual void SetVulkanHandlers( VkInstance hInstance, VkDevice hDevice ) override;
virtual IVkCommandBuffer *CreateCommandBuffer() override; virtual IVkCommandBuffer *CreateCommandBuffer() override;
virtual CVkCommand *CreateCommand( const char *szName ) override; virtual CVkCommand *CreateCommand( const char *szName ) override;
virtual CUtlVector<VkCommandBuffer> &GetVulkanCommands() override;
virtual void RenderingFinished() override;
private:
VkDevice m_hDevice;
CUtlVector<VkCommandBuffer> m_commands;
}; };
EXPOSE_INTERFACE(CVkCommandBufferManager, IVkCommandBufferManager, VULKAN_COMMAND_BUFFER_MANAGER_INTERFACE_NAME); 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() 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; return NULL;
} }
CUtlVector<VkCommandBuffer> &CVkCommandBufferManager::GetVulkanCommands()
{
return m_commands;
}
void CVkCommandBufferManager::RenderingFinished()
{
m_commands = {};
}
CVkCommandRegistry::CVkCommandRegistry( const char *szName, fnCreateVulkanCommand_t pfnCreate ) CVkCommandRegistry::CVkCommandRegistry( const char *szName, fnCreateVulkanCommand_t pfnCreate )
{ {
VulkanCommandRegistry_t *pCommand = new VulkanCommandRegistry_t; VulkanCommandRegistry_t *pCommand = new VulkanCommandRegistry_t;

View File

@@ -38,7 +38,10 @@ DECLARE_VULKAN_COMMAND(Begin)
a.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO; a.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO;
a.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; a.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
a.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; 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.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
a.imageView = ((CVkImage*)VulkanGetObject(i.m_stImage, iCurrentFrame))->m_imageView; a.imageView = ((CVkImage*)VulkanGetObject(i.m_stImage, iCurrentFrame))->m_imageView;
attachments.AppendTail(a); attachments.AppendTail(a);

View File

@@ -82,7 +82,7 @@ BEGIN_BUILD_PIPELINE_LIBRARY(VertexTransform)
inits[i].m_set.bindingCount = inits[i].m_bindings.GetSize(); inits[i].m_set.bindingCount = inits[i].m_bindings.GetSize();
inits[i].m_set.pBindings = inits[i].m_bindings.GetData(); 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++) for ( i = 0; i < SHADER_STAGE_COUNT; i++)
@@ -92,6 +92,7 @@ BEGIN_BUILD_PIPELINE_LIBRARY(VertexTransform)
CUtlBuffer<unsigned char> code = ShaderParser()->GetShaderCode(m_pShader, (EShaderStage)i); CUtlBuffer<unsigned char> code = ShaderParser()->GetShaderCode(m_pShader, (EShaderStage)i);
// We may fail loading the specific stage // We may fail loading the specific stage
if (code.GetSize() == 0) if (code.GetSize() == 0)
continue; continue;
@@ -125,11 +126,13 @@ BEGIN_BUILD_PIPELINE_LIBRARY(VertexTransform)
stPipelineLayout.pSetLayouts = m_setLayouts; stPipelineLayout.pSetLayouts = m_setLayouts;
*/ */
stPipelineLayout.flags = VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT ; 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.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
rasterState.polygonMode = VK_POLYGON_MODE_FILL; rasterState.polygonMode = VK_POLYGON_MODE_FILL;
rasterState.lineWidth = 1; 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; viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
@@ -176,7 +179,7 @@ BEGIN_BUILD_PIPELINE_LIBRARY(PixelShader)
inits[i].m_set.bindingCount = inits[i].m_bindings.GetSize(); inits[i].m_set.bindingCount = inits[i].m_bindings.GetSize();
inits[i].m_set.pBindings = inits[i].m_bindings.GetData(); 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 = {}; VkPipelineLayoutCreateInfo stPipelineLayout = {};
@@ -186,7 +189,7 @@ BEGIN_BUILD_PIPELINE_LIBRARY(PixelShader)
stPipelineLayout.pSetLayouts = m_setLayouts; stPipelineLayout.pSetLayouts = m_setLayouts;
*/ */
stPipelineLayout.flags = VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT ; 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<unsigned char> spirv = {}; CUtlBuffer<unsigned char> spirv = {};
VkPipelineShaderStageCreateInfo shader = {}; VkPipelineShaderStageCreateInfo shader = {};
@@ -205,7 +208,7 @@ BEGIN_BUILD_PIPELINE_LIBRARY(PixelShader)
inits[i].m_set.bindingCount = inits[i].m_bindings.GetSize(); inits[i].m_set.bindingCount = inits[i].m_bindings.GetSize();
inits[i].m_set.pBindings = inits[i].m_bindings.GetData(); 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); spirv = ShaderParser()->GetShaderCode(m_pShader, SHADER_STAGE_PIXEL);
@@ -264,18 +267,13 @@ BEGIN_BUILD_PIPELINE_LIBRARY(PixelOutput)
{ {
VkPipelineColorBlendAttachmentState a = {}; 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.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.blendEnable = VK_FALSE;
a.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
a.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
a.colorBlendOp = VK_BLEND_OP_ADD;
a.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
a.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
a.alphaBlendOp = VK_BLEND_OP_ADD;
attachments.AppendTail(a); attachments.AppendTail(a);
} }
blend.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; blend.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
blend.attachmentCount = m_eFormats.GetSize(); blend.attachmentCount = m_eFormats.GetSize();
blend.pAttachments = attachments.GetData(); blend.pAttachments = attachments.GetData();
blend.logicOp = VK_LOGIC_OP_COPY;
pipeline.pDepthStencilState = &depthStencil; pipeline.pDepthStencilState = &depthStencil;
pipeline.pColorBlendState = &blend; pipeline.pColorBlendState = &blend;

View File

@@ -16,6 +16,7 @@ void CVkRenderCommandList::SetRenderTarget( uint32_t uIndex, IImage *pImage )
{ {
SwitchRenderingStage(RENDERING_STAGE_SETUP_RASTER); SwitchRenderingStage(RENDERING_STAGE_SETUP_RASTER);
VulkanRenderOutput_t *pOutput = FindOrCreateRenderOutput(uIndex); VulkanRenderOutput_t *pOutput = FindOrCreateRenderOutput(uIndex);
pOutput->m_stImage.m_eObjectType = FRAME_OBJECT_TYPE_SINGLE;
pOutput->m_stImage.m_pSingle = pImage; pOutput->m_stImage.m_pSingle = pImage;
} }
@@ -44,6 +45,8 @@ void CVkRenderCommandList::SetClearDepth( float fVal)
void CVkRenderCommandList::SetRenderResolution( uint32_t iWidth, uint32_t iHeight ) void CVkRenderCommandList::SetRenderResolution( uint32_t iWidth, uint32_t iHeight )
{ {
SwitchRenderingStage(RENDERING_STAGE_SETUP_RASTER); SwitchRenderingStage(RENDERING_STAGE_SETUP_RASTER);
m_uWidth = iWidth;
m_uHeight = iHeight;
} }
@@ -71,8 +74,8 @@ void CVkRenderCommandList::SetMaterial( IMaterial *pMaterial )
m_pCurrentMaterialBuffer->Reset(); m_pCurrentMaterialBuffer->Reset();
CVkBeginCommand *pBeginCommand = CREATE_COMMAND(Begin); CVkBeginCommand *pBeginCommand = CREATE_COMMAND(Begin);
pBeginCommand->images = m_pOutput; pBeginCommand->images = m_pOutput;
pBeginCommand->nResolutionX = 1280; pBeginCommand->nResolutionX = m_uWidth;
pBeginCommand->nResolutionY = 720; pBeginCommand->nResolutionY = m_uHeight;
pBeginCommand->stDepthImage = m_depth; pBeginCommand->stDepthImage = m_depth;
for ( auto &i: pBeginCommand->images) for ( auto &i: pBeginCommand->images)
{ {
@@ -85,12 +88,17 @@ void CVkRenderCommandList::SetMaterial( IMaterial *pMaterial )
m_pCurrentMaterialBuffer->AddCommand(pSetShader); m_pCurrentMaterialBuffer->AddCommand(pSetShader);
CVkSetScissorsCommand *pScissorsCommand = CREATE_COMMAND(SetScissors); CVkSetScissorsCommand *pScissorsCommand = CREATE_COMMAND(SetScissors);
pScissorsCommand->uWidth = 1280; pScissorsCommand->uWidth = m_uWidth;
pScissorsCommand->uHeight = 720; pScissorsCommand->uHeight = m_uHeight;
m_pCurrentMaterialBuffer->AddCommand(pScissorsCommand); m_pCurrentMaterialBuffer->AddCommand(pScissorsCommand);
CVkSetViewportCommand *pViewportCommand = CREATE_COMMAND(SetViewport); CVkSetViewportCommand *pViewportCommand = CREATE_COMMAND(SetViewport);
pViewportCommand->fWidth = 1280; pViewportCommand->fX = 0;
pViewportCommand->fHeight = 720; pViewportCommand->fY = 0;
pViewportCommand->fWidth = m_uWidth;
pViewportCommand->fHeight = m_uHeight;
pViewportCommand->fDepthMin = 0;
pViewportCommand->fDepthMax = 1;
m_pCurrentMaterialBuffer->AddCommand(pViewportCommand); m_pCurrentMaterialBuffer->AddCommand(pViewportCommand);
} }
} }
@@ -190,7 +198,7 @@ IVkCommandBuffer *CVkRenderCommandList::FindOrCreateMaterialCommandBuffer( IMate
} }
VulkanMaterialCommandBuffer_t mat; VulkanMaterialCommandBuffer_t mat;
mat.m_pCommandBuffer = g_pCommandBufferManager->CreateCommandBuffer(); mat.m_pCommandBuffer = m_pCommandBufferManager->CreateCommandBuffer();
mat.m_pMaterial = pMaterial; mat.m_pMaterial = pMaterial;
m_materials.AppendTail(mat); m_materials.AppendTail(mat);
if (pbWasCreated) if (pbWasCreated)

View File

@@ -1,5 +1,6 @@
#include "commands.h" #include "commands.h"
#include "materialsystem/imaterialsystem.h" #include "materialsystem/imaterialsystem.h"
#include "shadercompiler/icompiler.h"
#include "tier0/lib.h" #include "tier0/lib.h"
#include "tier0/platform.h" #include "tier0/platform.h"
#include "tier1/interface.h" #include "tier1/interface.h"
@@ -8,13 +9,13 @@
#define VK_NO_PROTOTYPES #define VK_NO_PROTOTYPES
#include "vulkan/vulkan_core.h" #include "vulkan/vulkan_core.h"
#include "vulkan_state.h" #include "vulkan_state.h"
#include "igamewindow.h" #include "materialsystem/igamewindow.h"
#include "libraries.h" #include "libraries.h"
#define REQUIRED_EXTENSION(ext) ext##_EXTENSION_NAME, #define REQUIRED_EXTENSION(ext) ext##_EXTENSION_NAME,
#define OPTIONAL_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" #include "device_extensions.h"
}; };
#undef REQUIRED_EXTENSION #undef REQUIRED_EXTENSION
@@ -26,23 +27,27 @@ SupportedVulkanExtensions_t g_vkAvailableExtensions;
uint32_t g_iDrawFamily; uint32_t g_iDrawFamily;
uint32_t g_iPresentFamily; uint32_t g_iPresentFamily;
VkQueue g_vkDrawQueue; VkQueue s_vkDrawQueue;
VkQueue g_vkPresentQueue; VkQueue s_vkPresentQueue;
VkInstance g_vkInstance; VkInstance s_vkInstance;
VmaAllocator g_vkAllocator; VmaAllocator s_vkAllocator;
VkPhysicalDevice g_vkPhysicalDevice; VkPhysicalDevice s_vkPhysicalDevice;
VkDevice g_vkDevice; VkDevice s_vkDevice;
VkSwapchainKHR g_vkSwapchain; VkSwapchainKHR s_vkSwapchain;
CUtlVector<VkFence> g_vkFences = {}; struct VulkanWindow_t
CUtlVector<VkSemaphore> g_vkGraphicsSemaphores = {}; {
CUtlVector<VkSemaphore> g_vkPresentSemaphores = {}; IGameWindow *m_pWindow;
VkSurfaceKHR m_surface;
CUtlVector<VkCommandPool> g_vkCommandPools = {}; VkSwapchainKHR m_swapchain;
VkFormat m_eFormat;
CUtlVector<IImage*> g_vkSwapchainImages = {}; VkFence m_fences[FRAMES_IN_FLIGHT];
VkFormat g_vkWindowImageFormat; VkSemaphore m_imageAvailable[FRAMES_IN_FLIGHT];
VkSemaphore m_renderFinished[FRAMES_IN_FLIGHT];
CUtlVector<IImage*> m_images;
uint32_t m_uCurrentFrame;
};
CVkImage::CVkImage() CVkImage::CVkImage()
@@ -108,8 +113,6 @@ VkFormat CVkImage::GetImageFormat( enum EImageFormat eImageFormat )
return VK_FORMAT_R32G32B32A32_SFLOAT; return VK_FORMAT_R32G32B32A32_SFLOAT;
case IMAGE_FORMAT_D32_SFLOAT: case IMAGE_FORMAT_D32_SFLOAT:
return VK_FORMAT_D32_SFLOAT; return VK_FORMAT_D32_SFLOAT;
case IMAGE_FORMAT_WINDOW:
return g_vkWindowImageFormat;
} }
} }
@@ -132,7 +135,7 @@ void CVkImage::CreateImage( uint32_t nWidth, uint32_t nHeight, EImageFormat eFor
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() void CVkImage::CreateImageView()
@@ -151,7 +154,7 @@ void CVkImage::CreateImageView()
stImageViewCreateInfo.subresourceRange.layerCount = 1; stImageViewCreateInfo.subresourceRange.layerCount = 1;
stImageViewCreateInfo.subresourceRange.levelCount = 1; stImageViewCreateInfo.subresourceRange.levelCount = 1;
m_range = stImageViewCreateInfo.subresourceRange; m_range = stImageViewCreateInfo.subresourceRange;
vkCreateImageView(g_vkDevice, &stImageViewCreateInfo, NULL, &m_imageView); vkCreateImageView(s_vkDevice, &stImageViewCreateInfo, NULL, &m_imageView);
} }
void CVkImage::SetDebugName( const char *szName ) void CVkImage::SetDebugName( const char *szName )
{ {
@@ -197,11 +200,11 @@ CVkBuffer::CVkBuffer( uint32_t nSize, VkBufferUsageFlags2 eUsage, uint32_t nAlig
stAllocInfo.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE; stAllocInfo.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE;
stAllocInfo.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT; 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.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO;
stAddress.buffer = m_buffer; stAddress.buffer = m_buffer;
m_address = vkGetBufferDeviceAddress(g_vkDevice, &stAddress); m_address = vkGetBufferDeviceAddress(s_vkDevice, &stAddress);
m_nSize = nSize; m_nSize = nSize;
} }
@@ -230,13 +233,13 @@ void *CVkBuffer::Map()
void *pData; void *pData;
pData = NULL; pData = NULL;
vmaMapMemory(g_vkAllocator, m_allocation, &pData); vmaMapMemory(s_vkAllocator, m_allocation, &pData);
return pData; return pData;
} }
void CVkBuffer::Unmap() void CVkBuffer::Unmap()
{ {
vmaUnmapMemory(g_vkAllocator, m_allocation); vmaUnmapMemory(s_vkAllocator, m_allocation);
} }
uint32_t CVkBuffer::GetSize() uint32_t CVkBuffer::GetSize()
@@ -284,10 +287,13 @@ private:
VkCommandBuffer GetCommandBuffer(); VkCommandBuffer GetCommandBuffer();
void CreateSwapchain( IGameWindow *pWindow ); VulkanWindow_t CreateSwapchain( IGameWindow *pWindow );
void DestroySwapchain( IGameWindow *pWindow ); void DestroySwapchain( uint32_t uIndex );
IGameWindowManager *m_pWindowManager; IGameWindowManager *m_pWindowManager;
IVkCommandBufferManager *m_pCommandBufferManager;
CUtlVector<VulkanWindow_t> m_renderWindows;
}; };
EXPOSE_INTERFACE(CVkRenderContext, IRenderContext, RENDER_CONTEXT_INTERFACE_VERSION); EXPOSE_INTERFACE(CVkRenderContext, IRenderContext, RENDER_CONTEXT_INTERFACE_VERSION);
@@ -369,33 +375,13 @@ void CVkRenderContext::DestroyImage( IImage *pImage )
IShader *CVkRenderContext::CreateShader( const char *szName ) 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(); CVkShader *pShader = new CVkShader();
pShader->AddShaderLibrary(&vertexDescription); VkGraphicsPipelineCreateInfo stPipelineCreateInfo = {};
pShader->AddShaderLibrary(&vertexTransform); ICompiledShaderManager *pCompiledShaderManager = (ICompiledShaderManager*)CreateInterface(COMPILED_SHADER_MANAGER_INTERFACE_VERSION, NULL);
pShader->AddShaderLibrary(&pixelShader); pCompiledShaderManager->ReadFromFile(&pShader->m_shader, szName);
pShader->AddShaderLibrary(&pixelOutput); pShader->m_hDevice = s_vkDevice;
pShader->Build();
return pShader; return pShader;
} }
@@ -416,7 +402,9 @@ void CVkRenderContext::DestroyMaterial( IMaterial *pMaterial )
IRenderCommandList *CVkRenderContext::CreateCommandList() IRenderCommandList *CVkRenderContext::CreateCommandList()
{ {
return new CVkRenderCommandList; CVkRenderCommandList *pList = new CVkRenderCommandList;
pList->m_pCommandBufferManager = m_pCommandBufferManager;
return pList;
} }
void CVkRenderContext::DestroyCommandList( IRenderCommandList *pCommandList ) void CVkRenderContext::DestroyCommandList( IRenderCommandList *pCommandList )
@@ -441,7 +429,8 @@ void CVkRenderContext::SetMainWindowManager( IGameWindowManager *pWindowManager
void CVkRenderContext::RegisterGameWindow( IGameWindow *pWindow ) void CVkRenderContext::RegisterGameWindow( IGameWindow *pWindow )
{ {
VulkanWindow_t window = CreateSwapchain(pWindow);
m_renderWindows.AppendTail(window);
} }
void CVkRenderContext::UnregisterGameWindow( IGameWindow *pWindow ) void CVkRenderContext::UnregisterGameWindow( IGameWindow *pWindow )
@@ -501,33 +490,33 @@ void CVkRenderContext::Init()
stInstanceCreateInfo.enabledExtensionCount = enabledInstanceExtensions.GetSize(); stInstanceCreateInfo.enabledExtensionCount = enabledInstanceExtensions.GetSize();
stInstanceCreateInfo.ppEnabledExtensionNames = enabledInstanceExtensions.GetData(); stInstanceCreateInfo.ppEnabledExtensionNames = enabledInstanceExtensions.GetData();
r = vkCreateInstance(&stInstanceCreateInfo, NULL, &g_vkInstance); r = vkCreateInstance(&stInstanceCreateInfo, NULL, &s_vkInstance);
VULKAN_RESULT_PRINT(r, vkCreateInstance); VULKAN_RESULT_PRINT(r, vkCreateInstance);
// volk requires to load instance this way // volk requires to load instance this way
volkLoadInstance(g_vkInstance); volkLoadInstance(s_vkInstance);
// Get amount of physical devices // Get amount of physical devices
r = vkEnumeratePhysicalDevices(g_vkInstance, &nPhysicalDevicesCount, NULL); r = vkEnumeratePhysicalDevices(s_vkInstance, &nPhysicalDevicesCount, NULL);
VULKAN_RESULT_PRINT(r, vkEnumeratePhysicalDevices); VULKAN_RESULT_PRINT(r, vkEnumeratePhysicalDevices);
physicalDevices.Resize(nPhysicalDevicesCount); physicalDevices.Resize(nPhysicalDevicesCount);
// Read all physical devices // Read all physical devices
r = vkEnumeratePhysicalDevices(g_vkInstance, &nPhysicalDevicesCount, physicalDevices.GetData()); r = vkEnumeratePhysicalDevices(s_vkInstance, &nPhysicalDevicesCount, physicalDevices.GetData());
VULKAN_RESULT_PRINT(r, vkEnumeratePhysicalDevices); VULKAN_RESULT_PRINT(r, vkEnumeratePhysicalDevices);
g_vkPhysicalDevice = SelectPhysicalDevice(physicalDevices); s_vkPhysicalDevice = SelectPhysicalDevice(physicalDevices);
enabledDeviceExtensions = GetDeviceExtensions(); enabledDeviceExtensions = GetDeviceExtensions();
// Get all queues // Get all queues
vkGetPhysicalDeviceQueueFamilyProperties(g_vkPhysicalDevice, &nNumQueueFamilies, NULL); vkGetPhysicalDeviceQueueFamilyProperties(s_vkPhysicalDevice, &nNumQueueFamilies, NULL);
queueFamilyProperties.Resize(nNumQueueFamilies); queueFamilyProperties.Resize(nNumQueueFamilies);
uint32_t i = 0; uint32_t i = 0;
vkGetPhysicalDeviceQueueFamilyProperties(g_vkPhysicalDevice, &nNumQueueFamilies, queueFamilyProperties.GetData()); vkGetPhysicalDeviceQueueFamilyProperties(s_vkPhysicalDevice, &nNumQueueFamilies, queueFamilyProperties.GetData());
for (auto &family: queueFamilyProperties) for (auto &family: queueFamilyProperties)
{ {
@@ -566,123 +555,158 @@ void CVkRenderContext::Init()
stDeviceCreateInfo.enabledExtensionCount = enabledDeviceExtensions.GetSize(); stDeviceCreateInfo.enabledExtensionCount = enabledDeviceExtensions.GetSize();
stDeviceCreateInfo.ppEnabledExtensionNames = enabledDeviceExtensions.GetData(); stDeviceCreateInfo.ppEnabledExtensionNames = enabledDeviceExtensions.GetData();
stDeviceCreateInfo.pNext = &vk12Features; stDeviceCreateInfo.pNext = &vk12Features;
r = vkCreateDevice(g_vkPhysicalDevice, &stDeviceCreateInfo, NULL, &g_vkDevice); r = vkCreateDevice(s_vkPhysicalDevice, &stDeviceCreateInfo, NULL, &s_vkDevice);
VULKAN_RESULT_PRINT(r, vkEnumeratePhysicalDevices); VULKAN_RESULT_PRINT(r, vkEnumeratePhysicalDevices);
for (auto &extension: enabledDeviceExtensions) for (auto &extension: enabledDeviceExtensions)
V_printf("%s\n", extension); V_printf("%s\n", extension);
vkGetDeviceQueue(g_vkDevice, g_iDrawFamily, 0, &g_vkDrawQueue); vkGetDeviceQueue(s_vkDevice, g_iDrawFamily, 0, &s_vkDrawQueue);
vkGetDeviceQueue(g_vkDevice, g_iPresentFamily, 0, &g_vkPresentQueue); vkGetDeviceQueue(s_vkDevice, g_iPresentFamily, 0, &s_vkPresentQueue);
volkLoadDevice(g_vkDevice); volkLoadDevice(s_vkDevice);
VmaAllocatorCreateInfo stAllocatorInfo = {}; VmaAllocatorCreateInfo stAllocatorInfo = {};
stAllocatorInfo.flags = VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT stAllocatorInfo.flags = VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT
| VMA_ALLOCATOR_CREATE_KHR_MAINTENANCE5_BIT | VMA_ALLOCATOR_CREATE_KHR_MAINTENANCE5_BIT
; ;
stAllocatorInfo.vulkanApiVersion = VK_API_VERSION_1_4; stAllocatorInfo.vulkanApiVersion = VK_API_VERSION_1_4;
stAllocatorInfo.physicalDevice = g_vkPhysicalDevice; stAllocatorInfo.physicalDevice = s_vkPhysicalDevice;
stAllocatorInfo.device = g_vkDevice; stAllocatorInfo.device = s_vkDevice;
stAllocatorInfo.instance = g_vkInstance; stAllocatorInfo.instance = s_vkInstance;
VmaVulkanFunctions vulkanFunctions; VmaVulkanFunctions vulkanFunctions;
vmaImportVulkanFunctionsFromVolk(&stAllocatorInfo, &vulkanFunctions); vmaImportVulkanFunctionsFromVolk(&stAllocatorInfo, &vulkanFunctions);
stAllocatorInfo.pVulkanFunctions = &vulkanFunctions; stAllocatorInfo.pVulkanFunctions = &vulkanFunctions;
vmaCreateAllocator(&stAllocatorInfo, &g_vkAllocator); vmaCreateAllocator(&stAllocatorInfo, &s_vkAllocator);
VkPipelineLayoutCreateInfo stPipelineLayout = {}; VkPipelineLayoutCreateInfo stPipelineLayout = {};
stPipelineLayout.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; stPipelineLayout.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
stPipelineLayout.flags = VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT; stPipelineLayout.flags = VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT;
vkCreatePipelineLayout(g_vkDevice, &stPipelineLayout, NULL, &g_pLibraryEmptyLayout); vkCreatePipelineLayout(s_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();
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 ) void CVkRenderContext::Frame( float fDeltaTime )
{ {
/*
uint32_t i;
CUtlVector<VkFence> fences = {};
CUtlVector<VkSemaphore> imageReady = {};
CUtlVector<VkSemaphore> renderFinish = {};
CUtlVector<VkSwapchainKHR> swapchains = {};
CUtlVector<uint32_t> uImageIndexes = {};
CUtlVector<uint32_t> uSwapchainImageIndexes = {};
CUtlVector<VulkanWindow_t> recreatedWindows = {};
vkDeviceWaitIdle(s_vkDevice);
i = 0;
for ( auto &s: m_renderWindows)
{
if ( !s.m_pWindow->BRenderSizeUpdated() )
{
i++;
continue;
}
DestroySwapchain(i);
m_renderWindows.RemoveAt(i);
recreatedWindows.AppendTail(CreateSwapchain(s.m_pWindow));
}
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();
i = 0;
for ( auto &s: m_renderWindows )
{
CVkBlitCommand *pBlitCommand = NULL; CVkBlitCommand *pBlitCommand = NULL;
if (m_pOutputImage) if (s.m_pWindow->GetOutputImage())
{ {
pBlitCommand = CREATE_COMMAND(Blit); pBlitCommand = CREATE_COMMAND(Blit);
pBlitCommand->AddDependency(m_pOutputImage, DEPENDENCY_MODE_BLIT_IMAGE_SOURCE); pBlitCommand->AddDependency(s.m_pWindow->GetOutputImage(), DEPENDENCY_MODE_BLIT_IMAGE_SOURCE);
pBlitCommand->AddSwapchainDependency((IRenderingObject**)g_vkSwapchainImages.GetData(), DEPENDENCY_MODE_BLIT_IMAGE_DESTINATION); pBlitCommand->AddDependency((IRenderingObject*)s.m_images[uSwapchainImageIndexes[i]], DEPENDENCY_MODE_BLIT_IMAGE_DESTINATION);
pBlitCommand->stInputImage.m_eObjectType = FRAME_OBJECT_TYPE_SINGLE; pBlitCommand->stInputImage.m_eObjectType = FRAME_OBJECT_TYPE_SINGLE;
pBlitCommand->stInputImage.m_pSingle = m_pOutputImage; pBlitCommand->stInputImage.m_pSingle = s.m_pWindow->GetOutputImage();
pBlitCommand->stOutputImage.m_eObjectType = FRAME_OBJECT_TYPE_SWAPPED; pBlitCommand->stOutputImage.m_eObjectType = FRAME_OBJECT_TYPE_SINGLE;
pBlitCommand->stOutputImage.m_ppSwapped = (IRenderingObject**)g_vkSwapchainImages.GetData(); pBlitCommand->stOutputImage.m_pSingle = (IRenderingObject*)s.m_images[uSwapchainImageIndexes[i]];
pBlitCommand->iSrcMax[0] = 1280; pBlitCommand->iSrcMax[0] = s.m_pWindow->GetOutputImage()->GetImageWidth();
pBlitCommand->iSrcMax[1] = 720; pBlitCommand->iSrcMax[1] = s.m_pWindow->GetOutputImage()->GetImageHeight();
pBlitCommand->iSrcMax[2] = 1; pBlitCommand->iSrcMax[2] = 1;
pBlitCommand->iDstMax[0] = 1280; pBlitCommand->iDstMax[0] = s.m_pWindow->GetRenderWidth();
pBlitCommand->iDstMax[1] = 720; pBlitCommand->iDstMax[1] = s.m_pWindow->GetRenderHeight();
pBlitCommand->iDstMax[2] = 1; pBlitCommand->iDstMax[2] = 1;
} }
s_pPresentCommandBuffer = g_pCommandBufferManager->CreateCommandBuffer();
s_pPresentCommandBuffer->Reset();
if (pBlitCommand != NULL) if (pBlitCommand != NULL)
s_pPresentCommandBuffer->AddCommand(pBlitCommand); s_pPresentCommandBuffer->AddCommand(pBlitCommand);
i++;
}
s_pPresentCommandBuffer->Render(); s_pPresentCommandBuffer->Render();
s_pPresentCommandBuffer->Submit(0);
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(nImageIndex);
VkPipelineStageFlags uPipelineStageFlags = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; VkPipelineStageFlags uPipelineStageFlags = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
VkSubmitInfo stSubmitInfo = {}; VkSubmitInfo stSubmitInfo = {};
stSubmitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; stSubmitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
stSubmitInfo.waitSemaphoreCount = 1; stSubmitInfo.waitSemaphoreCount = imageReady.GetSize();
stSubmitInfo.pWaitSemaphores = &g_vkGraphicsSemaphores[s_nImageIndex]; stSubmitInfo.pWaitSemaphores = imageReady.GetData();
stSubmitInfo.pWaitDstStageMask = &uPipelineStageFlags; stSubmitInfo.pWaitDstStageMask = &uPipelineStageFlags;
stSubmitInfo.commandBufferCount = g_vkCommandBuffers.GetSize(); stSubmitInfo.commandBufferCount = m_pCommandBufferManager->GetVulkanCommands().GetSize();
stSubmitInfo.pCommandBuffers = g_vkCommandBuffers.GetData(); stSubmitInfo.pCommandBuffers = m_pCommandBufferManager->GetVulkanCommands().GetData();
stSubmitInfo.signalSemaphoreCount = 1; stSubmitInfo.signalSemaphoreCount = renderFinish.GetSize();
stSubmitInfo.pSignalSemaphores = &g_vkPresentSemaphores[nImageIndex]; stSubmitInfo.pSignalSemaphores = renderFinish.GetData();
vkQueueSubmit(g_vkDrawQueue, 1, &stSubmitInfo, g_vkFences[s_nImageIndex]); vkQueueSubmit(s_vkDrawQueue, 1, &stSubmitInfo, fences[0]);
VkPresentInfoKHR stPresentInfo = {}; VkPresentInfoKHR stPresentInfo = {};
stPresentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; stPresentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
stPresentInfo.waitSemaphoreCount = 1; stPresentInfo.waitSemaphoreCount = renderFinish.GetSize();
stPresentInfo.pWaitSemaphores = &g_vkPresentSemaphores[nImageIndex]; stPresentInfo.pWaitSemaphores = renderFinish.GetData();
stPresentInfo.swapchainCount = 1; stPresentInfo.swapchainCount = swapchains.GetSize();
stPresentInfo.pSwapchains = &g_vkSwapchain; stPresentInfo.pSwapchains = swapchains.GetData();
stPresentInfo.pImageIndices = &nImageIndex; stPresentInfo.pImageIndices = uImageIndexes.GetData();
vkQueuePresentKHR(g_vkPresentQueue, &stPresentInfo); vkQueuePresentKHR(s_vkPresentQueue, &stPresentInfo);
s_nImageIndex = (s_nImageIndex + 1) % g_vkSwapchainImages.GetSize(); for ( auto &s: m_renderWindows )
g_vkCommandBuffers = {}; {
*/ 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; uint32_t numSurfaceFormats = 0;
CUtlVector<VkSurfaceFormatKHR> surfaceFormats; CUtlVector<VkSurfaceFormatKHR> surfaceFormats;
@@ -704,17 +728,18 @@ void CVkRenderContext::CreateSwapchain( IGameWindow *pWindow )
uint32_t nSwapchainImages; uint32_t nSwapchainImages;
CUtlVector<VkImage> swapchainImages; CUtlVector<VkImage> 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); surfaceFormats.Resize(numSurfaceFormats);
vkGetPhysicalDeviceSurfaceFormatsKHR(g_vkPhysicalDevice, (VkSurfaceKHR)hSurface, &numSurfaceFormats, surfaceFormats.GetData()); vkGetPhysicalDeviceSurfaceFormatsKHR(s_vkPhysicalDevice, (VkSurfaceKHR)window.m_surface, &numSurfaceFormats, surfaceFormats.GetData());
stSelectedFormat = surfaceFormats[0]; stSelectedFormat = surfaceFormats[0];
@@ -731,12 +756,12 @@ void CVkRenderContext::CreateSwapchain( IGameWindow *pWindow )
} }
formatPicked: formatPicked:
vkGetPhysicalDeviceSurfacePresentModesKHR(g_vkPhysicalDevice, hSurface, &nSurfacePresentModes, NULL); vkGetPhysicalDeviceSurfacePresentModesKHR(s_vkPhysicalDevice, window.m_surface, &nSurfacePresentModes, NULL);
surfacePresentModes.Resize(nSurfacePresentModes); 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.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
stSwapchainCreateInfo.surface = hSurface; stSwapchainCreateInfo.surface = window.m_surface;
stSwapchainCreateInfo.imageFormat = stSelectedFormat.format; stSwapchainCreateInfo.imageFormat = stSelectedFormat.format;
stSwapchainCreateInfo.imageColorSpace = stSelectedFormat.colorSpace; stSwapchainCreateInfo.imageColorSpace = stSelectedFormat.colorSpace;
stSwapchainCreateInfo.presentMode = VK_PRESENT_MODE_IMMEDIATE_KHR; stSwapchainCreateInfo.presentMode = VK_PRESENT_MODE_IMMEDIATE_KHR;
@@ -744,19 +769,20 @@ formatPicked:
stSwapchainCreateInfo.preTransform = surfaceCapatibilities.currentTransform; stSwapchainCreateInfo.preTransform = surfaceCapatibilities.currentTransform;
stSwapchainCreateInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; stSwapchainCreateInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
stSwapchainCreateInfo.imageArrayLayers = 1; 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; 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); vkGetSwapchainImagesKHR(s_vkDevice, window.m_swapchain, &nSwapchainImages, NULL);
g_vkSwapchainImages.Resize(nSwapchainImages); window.m_images.Resize(nSwapchainImages);
swapchainImages.Resize(nSwapchainImages); swapchainImages.Resize(nSwapchainImages);
g_vkFences.Resize(nSwapchainImages); vkGetSwapchainImagesKHR(s_vkDevice, window.m_swapchain, &nSwapchainImages, swapchainImages.GetData());
g_vkGraphicsSemaphores.Resize(nSwapchainImages);
g_vkPresentSemaphores.Resize(nSwapchainImages);
vkGetSwapchainImagesKHR(g_vkDevice, g_vkSwapchain, &nSwapchainImages, swapchainImages.GetData());
for ( int i = 0; i < swapchainImages.GetSize(); i++ ) for ( int i = 0; i < swapchainImages.GetSize(); i++ )
{ {
@@ -765,28 +791,43 @@ formatPicked:
pImage->m_image = swapchainImages[i]; pImage->m_image = swapchainImages[i];
pImage->m_eImageType = IMAGE_TYPE_2D; pImage->m_eImageType = IMAGE_TYPE_2D;
pImage->m_eMultisampleType = MULTISAMPLE_TYPE_NONE; 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_nHeight = 1280;
pImage->m_nWidth = 720; pImage->m_nWidth = 720;
pImage->m_ePreferredLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; pImage->m_ePreferredLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
pImage->CreateImageView(); 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.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
stFenceCreateInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT; 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; stSemaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
vkCreateSemaphore(g_vkDevice, &stSemaphoreCreateInfo, NULL, &g_vkGraphicsSemaphores[i]); vkCreateSemaphore(s_vkDevice, &stSemaphoreCreateInfo, NULL, &window.m_imageAvailable[i]);
vkCreateSemaphore(g_vkDevice, &stSemaphoreCreateInfo, NULL, &g_vkPresentSemaphores[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); for ( auto i: m_renderWindows[uIndex].m_images )
pWindow->DestroyVulkanSurface(g_vkInstance); {
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() void CVkRenderContext::Shutdown()
{ {
vkDestroyInstance(g_vkInstance, NULL); vkDestroyInstance(s_vkInstance, NULL);
} }
@@ -854,11 +895,11 @@ CUtlVector<const char *> CVkRenderContext::GetDeviceExtensions()
const char *szExtensionName; const char *szExtensionName;
r = vkEnumerateDeviceExtensionProperties(g_vkPhysicalDevice, NULL, &nExtensionCount, NULL); r = vkEnumerateDeviceExtensionProperties(s_vkPhysicalDevice, NULL, &nExtensionCount, NULL);
VULKAN_RESULT_PRINT(r, vkEnumeratePhysicalDevices); VULKAN_RESULT_PRINT(r, vkEnumeratePhysicalDevices);
extensions.Resize(nExtensionCount); extensions.Resize(nExtensionCount);
r = vkEnumerateDeviceExtensionProperties(g_vkPhysicalDevice, NULL, &nExtensionCount, extensions.GetData()); r = vkEnumerateDeviceExtensionProperties(s_vkPhysicalDevice, NULL, &nExtensionCount, extensions.GetData());
VULKAN_RESULT_PRINT(r, vkEnumeratePhysicalDevices); VULKAN_RESULT_PRINT(r, vkEnumeratePhysicalDevices);
@@ -875,4 +916,3 @@ CUtlVector<const char *> CVkRenderContext::GetDeviceExtensions()
return enabledExtensions; return enabledExtensions;
} }

View File

@@ -1,38 +1,147 @@
#include "materialsystem/shaderinternals.h"
#include "tier1/utlvector.h"
#include "vulkan_state.h" #include "vulkan_state.h"
#include "shaderparser.h"
CVkShader::~CVkShader() 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() void CVkShader::Build()
{ {
CUtlVector<VkPipeline> libs = {}; VkPipelineLayoutCreateInfo layoutInfo = {};
VkGraphicsPipelineCreateInfo createInfo = {}; VkGraphicsPipelineCreateInfo createInfo = {};
VkPipelineLibraryCreateInfoKHR libInfo = {}; CUtlVector<VkPipelineShaderStageCreateInfo> stages = {};
CUtlVector<VkShaderModuleCreateInfo> modules = {};
VkPipelineVertexInputStateCreateInfo vertexInput = {};
VkPipelineInputAssemblyStateCreateInfo inputAssembly = {};
VkPipelineDynamicStateCreateInfo dynamicState = {};
VkPipelineRasterizationStateCreateInfo rasterState = {};
VkPipelineViewportStateCreateInfo viewportState = {};
VkPipelineMultisampleStateCreateInfo msaa = {};
VkPipelineDepthStencilStateCreateInfo depthStencil = {};
VkPipelineColorBlendStateCreateInfo blend = {};
VkPipelineRenderingCreateInfo render = {}; VkPipelineRenderingCreateInfo render = {};
CUtlVector<VkPipelineColorBlendAttachmentState> attachments = {};
createInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; VkDynamicState dynamicStates[] = {
for ( auto l: m_libraries ) VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT,
{ VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT,
libs.AppendTail(l->m_hPipeline);
}; };
VkPipelineLayoutCreateInfo stPipelineLayout = {};
libInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LIBRARY_CREATE_INFO_KHR; stPipelineLayout.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
libInfo.libraryCount = libs.GetSize(); vkCreatePipelineLayout(m_hDevice, &stPipelineLayout, NULL, &m_hPipelineLayout);
libInfo.pLibraries = libs.GetData();
createInfo.pNext = &libInfo; // TODO: Filter by vulkan shaders at some points
createInfo.flags = VK_PIPELINE_CREATE_LINK_TIME_OPTIMIZATION_BIT_EXT; stages.Resize(m_shader.m_objects.GetSize());
createInfo.layout = g_pLibraryEmptyLayout; 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.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; createInfo.pNext = &render;
// Possibly schedule it? vkCreateGraphicsPipelines(m_hDevice, NULL, 1, &createInfo, NULL, &m_hPipeline);
vkCreateGraphicsPipelines(g_vkDevice, NULL, 1, &createInfo, NULL, &m_hPipeline);
} }
uint32_t CVkShader::PSGetResourceByName( const char *szName ) uint32_t CVkShader::PSGetResourceByName( const char *szName )
@@ -44,4 +153,3 @@ uint32_t CVkShader::VSGetResourceByName( const char *szName )
{ {
} }

View File

@@ -2,6 +2,7 @@
#define VULKAN_STATE_H #define VULKAN_STATE_H
#include "shadercompiler/icompiler.h"
#include "volk.h" #include "volk.h"
#include "vk_mem_alloc.h" #include "vk_mem_alloc.h"
#include "tier0/platform.h" #include "tier0/platform.h"
@@ -20,16 +21,7 @@ extern struct SupportedVulkanExtensions_t
#undef REQUIRED_EXTENSION #undef REQUIRED_EXTENSION
#undef OPTIONAL_EXTENSION #undef OPTIONAL_EXTENSION
extern CUtlVector<IImage*> g_vkSwapchainImages; #define FRAMES_IN_FLIGHT 2
extern CUtlVector<VkCommandPool> g_vkCommandPools;
extern CUtlVector<VkCommandBuffer> g_vkCommandBuffers;
extern VkInstance g_vkInstance;
extern VmaAllocator g_vkAllocator;
extern VkPhysicalDevice g_vkPhysicalDevice;
extern VkDevice g_vkDevice;
enum EVulkanCommandType enum EVulkanCommandType
{ {
@@ -114,9 +106,11 @@ public:
void AddSwapchainDependency( IRenderingObject **ppObjects, EDependencyMode eDependencyMode ); void AddSwapchainDependency( IRenderingObject **ppObjects, EDependencyMode eDependencyMode );
}; };
class IVkCommandBufferManager;
abstract_class IVkCommandBuffer abstract_class IVkCommandBuffer
{ {
public: public:
virtual void SetVulkanHandlers( VkDevice hDevice, IVkCommandBufferManager *pManager ) = 0;
virtual void AddCommand( CVkCommand *pCommand ) = 0; virtual void AddCommand( CVkCommand *pCommand ) = 0;
virtual void Reset() = 0; virtual void Reset() = 0;
@@ -129,11 +123,13 @@ typedef CVkCommand *(*fnCreateVulkanCommand_t)();
abstract_class IVkCommandBufferManager: public IAppSystem abstract_class IVkCommandBufferManager: public IAppSystem
{ {
public: public:
virtual void SetVulkanHandlers( VkInstance hInstance, VkDevice hDevice ) = 0;
virtual IVkCommandBuffer *CreateCommandBuffer() = 0; virtual IVkCommandBuffer *CreateCommandBuffer() = 0;
virtual CVkCommand *CreateCommand( const char *szName ) = 0; virtual CVkCommand *CreateCommand( const char *szName ) = 0;
virtual CUtlVector<VkCommandBuffer> &GetVulkanCommands() = 0;
virtual void RenderingFinished() = 0;
}; };
#define VULKAN_COMMAND_BUFFER_MANAGER_INTERFACE_NAME "VulkanCommandBufferManager" #define VULKAN_COMMAND_BUFFER_MANAGER_INTERFACE_NAME "VulkanCommandBufferManager"
extern IVkCommandBufferManager *g_pCommandBufferManager;
class CVkCommandRegistry class CVkCommandRegistry
{ {
@@ -141,7 +137,7 @@ public:
CVkCommandRegistry( const char *szName, fnCreateVulkanCommand_t pfnCreate ); CVkCommandRegistry( const char *szName, fnCreateVulkanCommand_t pfnCreate );
}; };
#define CREATE_COMMAND(name) \ #define CREATE_COMMAND(name) \
(CVk##name##Command*)g_pCommandBufferManager->CreateCommand(#name) (CVk##name##Command*)m_pCommandBufferManager->CreateCommand(#name)
#define BEGIN_VULKAN_COMMAND( name ) \ #define BEGIN_VULKAN_COMMAND( name ) \
class CVk##name##Command : public CVkCommand \ class CVk##name##Command : public CVkCommand \
@@ -226,6 +222,7 @@ public:
virtual void Build() = 0; virtual void Build() = 0;
VkPipeline m_hPipeline = NULL; VkPipeline m_hPipeline = NULL;
VkDevice m_hDevice;
}; };
#define BEGIN_DEFINE_PIPELINE_LIBRARY(name) \ #define BEGIN_DEFINE_PIPELINE_LIBRARY(name) \
@@ -250,20 +247,32 @@ void CVk##name##PipelineLibrary::Build() \
pipeline.layout = g_pLibraryEmptyLayout; pipeline.layout = g_pLibraryEmptyLayout;
#define END_BUILD_PIPELINE_LIBRARY() \ #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 class CVkShader : public IShader
{ {
public: public:
~CVkShader(); ~CVkShader();
void AddShaderLibrary( CVkPipelineLibrary *pLibrary );
void Build();
virtual uint32_t PSGetResourceByName( const char *szName ) override; virtual uint32_t PSGetResourceByName( const char *szName ) override;
virtual uint32_t VSGetResourceByName( 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; VkPipeline m_hPipeline = NULL;
VkPipelineLayout m_hPipelineLayout; VkPipelineLayout m_hPipelineLayout;
CUtlVector<CVkPipelineLibrary*> m_libraries; CUtlVector<CVkPipelineLibrary*> m_libraries;
VkDevice m_hDevice;
CCompiledShader m_shader;
private:
CUtlVector<VkVertexInputAttributeDescription> m_attributes;
CUtlVector<VkVertexInputBindingDescription> m_layouts;
CUtlVector<VkFormat> m_eFormats;
}; };
class CVkMaterial: public IMaterial class CVkMaterial: public IMaterial
@@ -357,6 +366,8 @@ public:
virtual void EndRecording() override; virtual void EndRecording() override;
void Submit(); void Submit();
IVkCommandBufferManager *m_pCommandBufferManager;
private: private:
void SwitchRenderingStage( EVulkanRenderingStage eStage ); void SwitchRenderingStage( EVulkanRenderingStage eStage );
@@ -370,6 +381,9 @@ private:
IVkCommandBuffer *m_pPostRaster; IVkCommandBuffer *m_pPostRaster;
IVkCommandBuffer *m_pCurrentMaterialBuffer = NULL; IVkCommandBuffer *m_pCurrentMaterialBuffer = NULL;
uint32_t m_uWidth;
uint32_t m_uHeight;
}; };

View File

@@ -12,6 +12,6 @@ public:
virtual void ReadFromFile( CCompiledShader *pShader, const char *szFile ) = 0; virtual void ReadFromFile( CCompiledShader *pShader, const char *szFile ) = 0;
}; };
ICompiledShaderManager *CompiledShaderManager(); #define COMPILED_SHADER_MANAGER_INTERFACE_VERSION "CompiledShaderManager001"
#endif #endif

View File

@@ -1,23 +1,31 @@
#ifndef GAME_WINDOW_H #ifndef GAME_WINDOW_H
#define GAME_WINDOW_H #define GAME_WINDOW_H
#include "gamesystem.h"
#include "tier0/platform.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: public:
virtual void Frame( float fDelta ) = 0;
virtual uint32_t GetRenderWidth() = 0; virtual uint32_t GetRenderWidth() = 0;
virtual uint32_t GetRenderHeight() = 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 *CreateVulkanSurface( void *pInstance ) = 0;
virtual void DestroyVulkanSurface( void *pInstance ) = 0; virtual void DestroyVulkanSurface( void *pInstance ) = 0;
}; };
abstract_class IGameWindowManager: public IGameSystem abstract_class IGameWindowManager: public IAppSystem
{ {
public: public:
virtual void Frame( float fDelta ) = 0;
virtual IGameWindow *CreateWindow() = 0; virtual IGameWindow *CreateWindow() = 0;
virtual void DestroyWindow( IGameWindow* pWindow ) = 0; virtual void DestroyWindow( IGameWindow* pWindow ) = 0;
@@ -25,4 +33,7 @@ public:
virtual const char **GetVulkanInstanceExtensions() = 0; virtual const char **GetVulkanInstanceExtensions() = 0;
}; };
IGameWindowManager *GameWindowManager();
#define GAME_WINDOW_MANAGER_INTERFACE_VERSION "GameWindowMgr001"
#endif #endif

View File

@@ -131,6 +131,12 @@ public:
virtual ~IShader() = default; virtual ~IShader() = default;
virtual uint32_t PSGetResourceByName( const char *szName ) = 0; virtual uint32_t PSGetResourceByName( const char *szName ) = 0;
virtual uint32_t VSGetResourceByName( 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;
}; };
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View File

@@ -3,6 +3,9 @@
#include "ld.h" #include "ld.h"
#include "target.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) DECLARE_BUILD_STAGE(libshadercompiler)
{ {
CProject_t stProject; CProject_t stProject;
@@ -13,6 +16,7 @@ DECLARE_BUILD_STAGE(libshadercompiler)
stProject.bFPIC = true; stProject.bFPIC = true;
stProject.includeDirectories = { stProject.includeDirectories = {
"../public", "../public",
"../external/funnystdlib/public",
"../external/slang/include", "../external/slang/include",
"../external/Vulkan-Headers/include", "../external/Vulkan-Headers/include",
}; };
@@ -22,7 +26,11 @@ DECLARE_BUILD_STAGE(libshadercompiler)
}; };
stLinkProject = ccompiler->Compile(&stProject); 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); szOutput = linker->Link(&stLinkProject);
ADD_OUTPUT_OBJECT("lib", szOutput); ADD_OUTPUT_OBJECT("lib", szOutput);
@@ -36,42 +44,45 @@ DECLARE_BUILD_STAGE(shadercompiler)
CUtlString szOutput; CUtlString szOutput;
stProject.m_szName = "fsc"; stProject.m_szName = "fsc";
stProject.m_target = Target_t::HostTarget(); stProject.includeDirectories = {"../public", "../external/funnystdlib/public"};
stProject.includeDirectories = {"public"};
stProject.files = { stProject.files = {
"main.cpp", "main.cpp",
"../materialsystem/compiledshader.cpp",
}; };
stLinkProject = ccompiler->Compile(&stProject); stLinkProject = ccompiler->Compile(&stProject);
stLinkProject.linkType = ELINK_EXECUTABLE; stLinkProject.linkType = ELINK_EXECUTABLE;
stLinkProject.objects.AppendTail((Object_t){tier0_lib}); stLinkProject.libraryObjects = {
stLinkProject.objects.AppendTail((Object_t){tier1_lib}); GET_PROJECT_LIBRARY(tier0, "tier0"),
stLinkProject.objects.AppendTail((Object_t){tier2_lib}); };
stLinkProject.objects.AppendTail((Object_t){shadercompiler_lib}); stLinkProject.objects.AppendTail({GET_PROJECT_LIBRARY(tier1, "tier1")});
stLinkProject.objects.AppendTail({GET_PROJECT_LIBRARY(tier2, "tier2")});
stLinkProject.libraries = {"slang-compiler","slang-glslang-2025.24.2"}; stLinkProject.libraries = {"slang-compiler","slang-glslang-2025.24.2"};
stLinkProject.libraryDirectories = {"external/linux"}; stLinkProject.libraryDirectories = {"../external/linux"};
szOutput = linker->Link(&stLinkProject); szOutput = linker->Link(&stLinkProject);
/* filesystem2->MakeDirectory(CUtlString("../build/tools"));
filesystem2->MakeDirectory(CUtlString("%s/bin/tools", szOutputDir.GetString())); filesystem2->CopyFile(CUtlString("../build/tools"), szOutput);
filesystem2->CopyFile(CUtlString("%s/bin/tools", szOutputDir.GetString()), szOutput); filesystem2->CopyFile(CUtlString("../build/tools"), GET_PROJECT_LIBRARY(tier0, "tier0"));
filesystem2->CopyFile(CUtlString("%s/bin/tools", szOutputDir.GetString()), "external/linux/libslang-compiler.so.0.2025.24.2"); filesystem2->CopyFile(CUtlString("../build/tools"), GET_PROJECT_LIBRARY(filesystem_std, "fs"));
filesystem2->CopyFile(CUtlString("%s/bin/tools", szOutputDir.GetString()), "external/linux/libslang-glslang-2025.24.2.so"); filesystem2->CopyFile(CUtlString("../build/tools"), GET_PROJECT_LIBRARY(libshadercompiler, "lib"));
shadercompiler_exe = CUtlString("%s/bin/tools/fsc", szOutputDir.GetString()); 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; return 1;
} }
/*
DECLARE_BUILD_STAGE(compileshaders) DECLARE_BUILD_STAGE(compileshaders)
{ {
CUtlString szShaderCompiler = "../build/tools/fsc";
if (CommandLine()->CheckParam("-nofsc")) if (CommandLine()->CheckParam("-nofsc"))
return 0; return 0;
CUtlVector<CUtlString> args = {"-i", "funnyassets", "-o", "build/funnygame/assets"}; filesystem2->MakeDirectory(CUtlString("../build/funnygame/assets"));
CUtlVector<CUtlString> args = {"-i", "../funnyassets", "-o", "../build/funnygame/assets"};
runner->Run(shadercompiler_exe, args); runner->Run(szShaderCompiler, args);
runner->Wait(); runner->Wait();
V_printf("Cool\n");
return 0; return 0;
}; };
*/

View File

@@ -1,5 +1,5 @@
#include "tier0/lib.h" #include "tier0/lib.h"
#include "tier1/commandline.h" #include "tier0/commandline.h"
#include "tier1/appinit.h" #include "tier1/appinit.h"
#include "tier1/utlstring.h" #include "tier1/utlstring.h"
#include "tier2/ifilesystem.h" #include "tier2/ifilesystem.h"
@@ -8,6 +8,7 @@
static IShaderCompiler *s_pVulkanSpirvCompiler; static IShaderCompiler *s_pVulkanSpirvCompiler;
static const char *s_szGameRoot; static const char *s_szGameRoot;
ICompiledShaderManager *g_pShaderManager;
void CompileShader( const char *szShader ) void CompileShader( const char *szShader )
{ {
@@ -18,17 +19,16 @@ void CompileShader( const char *szShader )
s_pVulkanSpirvCompiler->CompileShader(szShader, &shader); s_pVulkanSpirvCompiler->CompileShader(szShader, &shader);
Plat_MakeDir("build/funnygame/assets", 0755); Plat_MakeDir("../build/funnygame/assets", 0755);
Plat_MakeDir("build/funnygame/assets/shaders", 0755); Plat_MakeDir("../build/funnygame/assets/shaders", 0755);
CUtlString szOutputDirectory = szShader; CUtlString szOutputDirectory = szShader;
szOutputDirectory.RemoveHead(strlen(s_szGameRoot)+1); szOutputDirectory.RemoveHead(strlen(s_szGameRoot)+1);
szOutputDirectory.AppendHead("build/funnygame/assets/"); szOutputDirectory.AppendHead("../build/funnygame/assets/");
szOutputDirectory.AppendTail("_c"); szOutputDirectory.AppendTail("_c");
printf("%s\n",szOutputDirectory.GetString()); printf("%s\n",szOutputDirectory.GetString());
g_pShaderManager->WriteToFile(&shader, szOutputDirectory);
CompiledShaderManager()->WriteToFile(&shader, szOutputDirectory);
}; };
void PrintHelp() void PrintHelp()
@@ -40,11 +40,21 @@ void PrintHelp()
int main( int c, char **v ) int main( int c, char **v )
{ {
CUtlString szExePath = Plat_GetExecutablePath(); CUtlString szExePath = Plat_GetExecutablePath();
CUtlString szOriginalPath = Plat_GetWorkingDir();
CommandLine()->CreateCommandLine(c, v); 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(); 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(); s_pVulkanSpirvCompiler->Init();
const char *szInputDirectory = CommandLine()->ParamValue("-i"); const char *szInputDirectory = CommandLine()->ParamValue("-i");

View File

@@ -72,12 +72,19 @@ void CSlangVulkanSpirvShaderCompiler::CompileShader( const char *szInput, CCompi
ISession *pSession = NULL; ISession *pSession = NULL;
IBlob *pShaderSourceBlob = 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); IFileHandle *pFile = filesystem->Open(szInput, FILEMODE_READ);
const char *szShaderSource = filesystem->ReadString(pFile); const char *szShaderSource = filesystem->ReadString(pFile);
int i = 0; int i = 0;
pShaderSourceBlob = slang_createBlob(szShaderSource, pFile->Size()); pShaderSourceBlob = slang_createBlob(szShaderSource, filesystem->Size(pFile));
filesystem->Close(pFile); filesystem->Close(pFile);
printf(" SLANG %s\n", szInput); printf(" SLANG %s\n", szInput);