working on rendering
This commit is contained in:
@@ -22,3 +22,6 @@
|
||||
[submodule "external/Vulkan-Utility-Libraries"]
|
||||
path = external/Vulkan-Utility-Libraries
|
||||
url = https://github.com/KhronosGroup/Vulkan-Utility-Libraries
|
||||
[submodule "external/slang"]
|
||||
path = external/slang
|
||||
url = https://github.com/shader-slang/slang.git
|
||||
|
||||
@@ -83,7 +83,7 @@ CUtlString client_lib;
|
||||
|
||||
#include "rapier/__build.cpp"
|
||||
#include "engine/__build.cpp"
|
||||
#include "shadercompiler/__build.cpp"
|
||||
|
||||
#include "launcher/__build.cpp"
|
||||
|
||||
#include "funnyassets/__build.cpp"
|
||||
|
||||
@@ -18,7 +18,63 @@ extern "C" void FunnyMain( int argc, char **argv )
|
||||
|
||||
ServerGameDLL()->Init();
|
||||
|
||||
IShader *pShader = NULL;
|
||||
IBuffer *pCameraInfoBuffer = NULL;
|
||||
IMaterial *pMaterial = NULL;
|
||||
|
||||
IImage *pOutputImage = NULL;
|
||||
IVertexBuffer *pVertices = NULL;
|
||||
|
||||
float vertices[9] = {
|
||||
0,-0.5, 0,
|
||||
0.5,0.5, 0,
|
||||
-0.5,0.5, 0,
|
||||
};
|
||||
|
||||
pVertices = g_pRenderContext->CreateVertexBuffer(36);
|
||||
|
||||
void *pMapped = pVertices->Map();
|
||||
V_memcpy(pMapped, vertices, 36);
|
||||
pVertices->Unmap();
|
||||
|
||||
pCameraInfoBuffer = g_pRenderContext->CreateConstantBuffer(64);
|
||||
|
||||
pShader = g_pRenderContext->CreateShader("funnygame/core/shaders/flat.shader_c");
|
||||
pMaterial = g_pRenderContext->CreateMaterial(pShader);
|
||||
pMaterial->PSSetConstantsBuffer(0, pCameraInfoBuffer);
|
||||
|
||||
pOutputImage = g_pRenderContext->CreateRenderTarget(
|
||||
g_pRenderContext->GetNewOutputImageWidth(),
|
||||
g_pRenderContext->GetNewOutputImageHeight(),
|
||||
IMAGE_FORMAT_RGBA8_UNORM,
|
||||
MULTISAMPLE_TYPE_NONE);
|
||||
|
||||
IRenderCommandList *pCommandList = g_pRenderContext->CreateCommandList();
|
||||
pCommandList->StartRecording();
|
||||
pCommandList->SetRenderTarget(0, pOutputImage);
|
||||
pCommandList->SetMaterial(pMaterial);
|
||||
pCommandList->SetVertexBuffer(0, pVertices);
|
||||
pCommandList->DrawPrimitives(3, 0, 1, 0);
|
||||
pCommandList->EndRecording();
|
||||
|
||||
for (;;) {
|
||||
/*
|
||||
if (g_pRenderContext->BIsOutputImageOutdated())
|
||||
{
|
||||
uint32_t nWidth;
|
||||
uint32_t nHeight;
|
||||
pOutputImage = g_pRenderContext->CreateRenderTarget(
|
||||
g_pRenderContext->GetNewOutputImageWidth(),
|
||||
g_pRenderContext->GetNewOutputImageHeight(),
|
||||
IMAGE_FORMAT_RGBA8_UNORM,
|
||||
MULTISAMPLE_TYPE_NONE);
|
||||
}
|
||||
*/
|
||||
|
||||
g_pRenderContext->SubmitCommandList(pCommandList);
|
||||
|
||||
g_pRenderContext->SetOutputImage(pOutputImage);
|
||||
|
||||
gamewindow->UpdateWindow();
|
||||
Materials()->Frame(0);
|
||||
};
|
||||
|
||||
@@ -83,6 +83,7 @@ public:
|
||||
delete pHandle;
|
||||
}
|
||||
virtual CUtlBuffer<unsigned char> Read( IFileHandle *pFile ) override { return NULL; };
|
||||
virtual const char *ReadString( IFileHandle *pFile ) override { return NULL; };
|
||||
};
|
||||
|
||||
EXPOSE_FILESYSTEM(CPAKFileSystem, "pakfs");
|
||||
|
||||
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
+1
Submodule external/slang added at 5d775e2829
Binary file not shown.
@@ -157,6 +157,7 @@ CUtlString CClangLinker::Link( LinkProject_t *pProject )
|
||||
if (pProject->m_target.kernel == TARGET_KERNEL_LINUX || pProject->m_target.kernel == TARGET_KERNEL_ANDROID)
|
||||
{
|
||||
args.AppendTail("-rdynamic");
|
||||
args.AppendTail("-Wl,-rpath,$ORIGIN");
|
||||
}
|
||||
|
||||
// Dynamic libraries
|
||||
@@ -180,6 +181,11 @@ CUtlString CClangLinker::Link( LinkProject_t *pProject )
|
||||
args.AppendTail("-l");
|
||||
args.AppendTail(lib);
|
||||
}
|
||||
for (auto lib: pProject->libraryDirectories)
|
||||
{
|
||||
args.AppendTail("-L");
|
||||
args.AppendTail(lib);
|
||||
}
|
||||
|
||||
// Apple frameworks
|
||||
for (auto &directory: pProject->frameworkDirectories)
|
||||
|
||||
@@ -63,6 +63,9 @@ void IEngine_Signal(int sig)
|
||||
Plat_Backtrace();
|
||||
Plat_FatalErrorFunc("Fault");
|
||||
break;
|
||||
case SIGINT:
|
||||
Plat_Exit(0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
|
||||
@@ -37,7 +37,6 @@ DECLARE_BUILD_STAGE(assets)
|
||||
filesystem2->CopyDirectory("build", "tools");
|
||||
|
||||
filesystem2->CopyDirectory(CUtlString("build/funnygame/assets"), "funnyassets/maps");
|
||||
filesystem2->CopyDirectory(CUtlString("build/funnygame/assets"), "funnyassets/shaders");
|
||||
filesystem2->CopyDirectory(CUtlString("build/funnygame/assets"), "funnyassets/fonts");
|
||||
filesystem2->CopyDirectory(CUtlString("build/funnygame/assets"), "funnyassets/textures");
|
||||
filesystem2->CopyDirectory(CUtlString("build/funnygame/assets"), "funnyassets/materials");
|
||||
@@ -49,13 +48,14 @@ DECLARE_BUILD_STAGE(assets)
|
||||
build_shader("fgui_text_frag");
|
||||
build_shader("fgui_text_vert");
|
||||
*/
|
||||
build_shader("flat");
|
||||
CUtlVector<CUtlString> python_args = {
|
||||
"build/tools/makepak64.py",
|
||||
CUtlString("build/funnygame/assets"),
|
||||
bStaticBuild ? CUtlString("%s/bin/%s.pak", szOutputDir.GetString(), "rtt") : CUtlString("%s/funnygame/%s.pak", szOutputDir.GetString(), "rtt"),
|
||||
};
|
||||
runner->Run("python3", python_args);
|
||||
filesystem2->CopyDirectory(CUtlString("%s/funnygame/core", szOutputDir.GetString()),"build/funnygame/assets");
|
||||
/*
|
||||
if (Target_t::DefaultTarget().kernel == TARGET_KERNEL_IOS ||Target_t::DefaultTarget().kernel == TARGET_KERNEL_DARWIN)
|
||||
{
|
||||
python_args = {
|
||||
@@ -66,15 +66,14 @@ DECLARE_BUILD_STAGE(assets)
|
||||
runner->Run("python3", python_args);
|
||||
} else {
|
||||
filesystem2->CopyDirectory(CUtlString("%s/funnygame", szOutputDir.GetString()),"build/funnygame/vulkan/shaders");
|
||||
/*
|
||||
python_args = {
|
||||
"build/tools/makepak64.py",
|
||||
CUtlString("build/funnygame/vulkan"),
|
||||
bStaticBuild ? CUtlString("%s/bin/%s.pak", szOutputDir.GetString(), "vulkan") : CUtlString("%s/funnygame/%s.pak", szOutputDir.GetString(), "vulkan"),
|
||||
};
|
||||
runner->Run("python3", python_args);
|
||||
*/
|
||||
}
|
||||
*/
|
||||
runner->Wait();
|
||||
|
||||
if (bStaticBuild)
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
#define COMMON using namespace Common; namespace Common
|
||||
|
||||
#ifdef VS_SHADER
|
||||
#define VS using namespace VertexShader; namespace VertexShader
|
||||
#else
|
||||
#define VS namespace VertexShader_DO_NOT_USE
|
||||
#endif
|
||||
|
||||
#ifdef PS_SHADER
|
||||
#define PS using namespace PixelShader; namespace PixelShader
|
||||
#else
|
||||
#define PS namespace PixelShader_DO_NOT_USE
|
||||
#endif
|
||||
|
||||
COMMON
|
||||
{
|
||||
|
||||
struct PS_INPUT
|
||||
{
|
||||
float4 m_vPosition : SV_Position;
|
||||
}
|
||||
}
|
||||
VS
|
||||
{
|
||||
cbuffer CameraInfo
|
||||
{
|
||||
float4x4 m_viewProj;
|
||||
};
|
||||
|
||||
struct VS_INPUT
|
||||
{
|
||||
float3 m_vPosition: POSITION;
|
||||
}
|
||||
|
||||
PS_INPUT vsMain( VS_INPUT i )
|
||||
{
|
||||
PS_INPUT o;
|
||||
o.m_vPosition = { i.m_vPosition, 1 };
|
||||
return o;
|
||||
}
|
||||
}
|
||||
PS
|
||||
{
|
||||
float4 psMain( PS_INPUT i )
|
||||
{
|
||||
return float4(1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
[Inputs]
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
struct VS_INPUT
|
||||
{
|
||||
float3 m_vPosition;
|
||||
}
|
||||
|
||||
struct PS_INPUT
|
||||
{
|
||||
float4 m_vPosition;
|
||||
}
|
||||
|
||||
[shader("vertex")]
|
||||
PS_INPUT vsMain( VS_INPUT i )
|
||||
{
|
||||
PS_INPUT o;
|
||||
o.m_vPosition = { i.m_vPosition, 1 };
|
||||
return o;
|
||||
}
|
||||
|
||||
[shader("pixel")]
|
||||
float4 psMain( PS_INPUT i )
|
||||
{
|
||||
return float4(1);
|
||||
}
|
||||
@@ -83,7 +83,7 @@ void C_MOBAPlayer::Spawn()
|
||||
pVertexBuffer->Unmap();
|
||||
|
||||
m_pMesh = IMeshRendering::CreateMesh();
|
||||
m_pMesh->SetVertexBuffer(pVertexBuffer);
|
||||
m_pMesh->SetVertexBuffer(0, pVertexBuffer);
|
||||
m_pMeshInstance = m_pMesh->CreateInstance();
|
||||
|
||||
};
|
||||
|
||||
@@ -82,6 +82,7 @@ int main( int argc, char **argv ) {
|
||||
// chdir to right directory
|
||||
dirname(szLauncherPath);
|
||||
chdir(szLauncherPath);
|
||||
printf("%s\n",szLauncherPath);
|
||||
|
||||
pEngineMain(argc, argv);
|
||||
dlclose(pEngineLib);
|
||||
|
||||
@@ -6,11 +6,15 @@
|
||||
|
||||
CUtlVector<CUtlString> MaterialSystem_CompiledFiles = {
|
||||
"materialsystem/materialsystem.cpp",
|
||||
"materialsystem/compiledshader.cpp",
|
||||
"materialsystem/vulkan/shaderparser.cpp",
|
||||
"materialsystem/vulkan/rendercontext.cpp",
|
||||
"materialsystem/vulkan/material.cpp",
|
||||
"materialsystem/vulkan/commandbuffer.cpp",
|
||||
"materialsystem/vulkan/utils.cpp",
|
||||
"materialsystem/vulkan/rendercommandlist.cpp",
|
||||
"materialsystem/vulkan/material.cpp",
|
||||
"materialsystem/vulkan/shader.cpp",
|
||||
"materialsystem/vulkan/utils.cpp",
|
||||
"materialsystem/vulkan/vma.cpp",
|
||||
"materialsystem/vulkan/commands/draw.cpp",
|
||||
"materialsystem/vulkan/commands/base.cpp",
|
||||
"materialsystem/vulkan/libraries/raster.cpp",
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
#include "shadercompiler/icompiler.h"
|
||||
#include "materialsystem/compiledshadermgr.h"
|
||||
#include "tier2/ifilesystem.h"
|
||||
|
||||
uint32_t CCompiledShader::AllocateLump( uint32_t nSize )
|
||||
{
|
||||
m_lumps.AppendTail({V_malloc(nSize),nSize});
|
||||
|
||||
return m_lumps.GetSize()-1;
|
||||
}
|
||||
|
||||
void *CCompiledShader::GetLumpPtr( uint32_t nLump )
|
||||
{
|
||||
return m_lumps[nLump].m_pAddress;
|
||||
}
|
||||
|
||||
uint32_t CCompiledShader::GetLumpSize( uint32_t nLump )
|
||||
{
|
||||
return m_lumps[nLump].m_nSize;
|
||||
}
|
||||
|
||||
ShaderObject_t *CCompiledShader::AllocateShader()
|
||||
{
|
||||
m_objects.AppendTail({});
|
||||
return &m_objects[m_objects.GetSize()-1];
|
||||
}
|
||||
|
||||
ShaderObject_t *CCompiledShader::FindShaderObject( EShaderBackend eBackend, EShaderStage eStage )
|
||||
{
|
||||
for ( auto &o: m_objects )
|
||||
{
|
||||
if ( o.m_eBackend != eBackend )
|
||||
continue;
|
||||
|
||||
if ( o.m_eStage != eStage )
|
||||
continue;
|
||||
|
||||
return &o;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
CCompiledShader::~CCompiledShader()
|
||||
{
|
||||
for ( auto l: m_lumps )
|
||||
V_free(l.m_pAddress);
|
||||
}
|
||||
|
||||
|
||||
class CCompiledShaderManager: public ICompiledShaderManager
|
||||
{
|
||||
public:
|
||||
virtual void WriteToFile( CCompiledShader *pShader, const char *szFile ) override;
|
||||
virtual void ReadFromFile( CCompiledShader *pShader, const char *szFile ) override;
|
||||
};
|
||||
|
||||
void CCompiledShaderManager::WriteToFile( CCompiledShader *pShader, const char *szFile )
|
||||
{
|
||||
IFileHandle *pFile;
|
||||
ShaderHeader_t stHeader = {};
|
||||
uint32_t nTotalSize = sizeof(ShaderHeader_t);
|
||||
|
||||
stHeader.m_cSignature[0] = 'f';
|
||||
stHeader.m_cSignature[1] = 's';
|
||||
stHeader.m_cSignature[2] = 'h';
|
||||
stHeader.m_cSignature[3] = 'o';
|
||||
stHeader.m_nNumLumps = pShader->m_lumps.GetSize();
|
||||
stHeader.m_nNumShaders = pShader->m_objects.GetSize();
|
||||
|
||||
pFile = filesystem->Open(szFile, FILEMODE_WRITE);
|
||||
pFile->Write(&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();
|
||||
|
||||
|
||||
// ShaderLump_t
|
||||
for ( auto l: pShader->m_lumps )
|
||||
{
|
||||
ShaderLump_t stLump = {};
|
||||
stLump.m_nOffset = nTotalSize;
|
||||
stLump.m_nSize = l.m_nSize;
|
||||
pFile->Write(&stLump, sizeof(ShaderLump_t));
|
||||
|
||||
nTotalSize += l.m_nSize;
|
||||
}
|
||||
|
||||
// ShaderObject_t
|
||||
|
||||
for ( auto o: pShader->m_objects )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// Lump Data
|
||||
for ( auto l: pShader->m_lumps )
|
||||
{
|
||||
pFile->Write(l.m_pAddress, l.m_nSize);
|
||||
}
|
||||
|
||||
|
||||
pFile->Close();
|
||||
}
|
||||
|
||||
void CCompiledShaderManager::ReadFromFile( CCompiledShader *pShader, const char *szFile )
|
||||
{
|
||||
IFileHandle *pFile;
|
||||
ShaderHeader_t stHeader = {};
|
||||
int i = 0;
|
||||
CUtlVector<ShaderLump_t> lumps = {};
|
||||
CUtlVector<ShaderObject_t> objects = {};
|
||||
CUtlVector<HostShaderLump_t> lumpsData = {};
|
||||
|
||||
pFile = filesystem->Open(szFile, FILEMODE_READ);
|
||||
pFile->Read(&stHeader, sizeof(ShaderHeader_t));
|
||||
|
||||
objects.Resize(stHeader.m_nNumShaders);
|
||||
lumps.Resize(stHeader.m_nNumLumps);
|
||||
lumpsData.Resize(stHeader.m_nNumLumps);
|
||||
|
||||
pFile->Read(lumps.GetData(), stHeader.m_nNumLumps * sizeof(ShaderLump_t));
|
||||
pFile->Read(objects.GetData(), stHeader.m_nNumShaders * sizeof(ShaderObject_t));
|
||||
|
||||
for ( i = 0; i < stHeader.m_nNumLumps; i++ )
|
||||
{
|
||||
lumpsData[i].m_pAddress = V_malloc(lumps[i].m_nSize);
|
||||
pFile->Seek(SEEKMODE_RELATIVE_START, lumps[i].m_nOffset);
|
||||
pFile->Read(lumpsData[i].m_pAddress, lumps[i].m_nSize);
|
||||
lumpsData[i].m_nSize = lumps[i].m_nSize;
|
||||
};
|
||||
|
||||
pShader->m_objects = objects;
|
||||
pShader->m_lumps = lumpsData;
|
||||
|
||||
pFile->Close();
|
||||
}
|
||||
|
||||
|
||||
ICompiledShaderManager *CompiledShaderManager()
|
||||
{
|
||||
static CCompiledShaderManager s_CompiledShaderManager;
|
||||
return &s_CompiledShaderManager;
|
||||
}
|
||||
@@ -6,31 +6,25 @@ public:
|
||||
virtual void Init() override;
|
||||
virtual void Frame( float fTime ) override;
|
||||
virtual void Shutdown() override;
|
||||
|
||||
virtual IRenderContext *GetRenderContext( void ) override;
|
||||
};
|
||||
|
||||
extern IRenderContext *g_pVkRenderContext;
|
||||
IRenderContext *g_pRenderContext;
|
||||
|
||||
void CMaterialSystem::Init()
|
||||
{
|
||||
GetRenderContext()->Init();
|
||||
g_pRenderContext = (IRenderContext*)CreateInterface(RENDER_CONTEXT_INTERFACE_NAME, NULL);
|
||||
g_pRenderContext->Init();
|
||||
}
|
||||
|
||||
void CMaterialSystem::Frame( float fTime )
|
||||
{
|
||||
GetRenderContext()->Frame(fTime);
|
||||
g_pRenderContext->Frame(fTime);
|
||||
}
|
||||
|
||||
void CMaterialSystem::Shutdown()
|
||||
{
|
||||
GetRenderContext()->Shutdown();
|
||||
}
|
||||
|
||||
extern IRenderContext *g_pVkRenderContext;
|
||||
|
||||
|
||||
IRenderContext *CMaterialSystem::GetRenderContext( void )
|
||||
{
|
||||
return g_pVkRenderContext;
|
||||
g_pRenderContext->Shutdown();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -240,9 +240,9 @@ void CVkCommandBuffer::TryBarrier( int iCurrent, int iCurrentBuffer )
|
||||
imageMemoryBarrier.dstAccessMask = VulkanGetAccessFlags(barrier.m_eNewDependency);
|
||||
if (barrier.m_eOldDependency == DEPENDENCY_MODE_FROM_PREVIOUS)
|
||||
{
|
||||
imageMemoryBarrier.oldLayout = VulkanGetImageLayout(pImage->m_eLastUsage);
|
||||
imageMemoryBarrier.srcStageMask = VulkanGetStageFlags(pImage->m_eLastUsage);
|
||||
imageMemoryBarrier.srcAccessMask = VulkanGetAccessFlags(pImage->m_eLastUsage);
|
||||
imageMemoryBarrier.oldLayout = VulkanGetImageLayout(DEPENDENCY_MODE_ALL_COMMANDS);
|
||||
imageMemoryBarrier.srcStageMask = VulkanGetStageFlags(DEPENDENCY_MODE_ALL_COMMANDS);
|
||||
imageMemoryBarrier.srcAccessMask = VulkanGetAccessFlags(DEPENDENCY_MODE_ALL_COMMANDS);
|
||||
} else {
|
||||
imageMemoryBarrier.oldLayout = VulkanGetImageLayout(barrier.m_eOldDependency);
|
||||
imageMemoryBarrier.srcStageMask = VulkanGetStageFlags(barrier.m_eOldDependency);
|
||||
|
||||
@@ -13,16 +13,6 @@ BEGIN_VULKAN_COMMAND(ClearColor)
|
||||
IImage **ppSwapchainImages = NULL;
|
||||
END_VULKAN_COMMAND(ClearColor)
|
||||
|
||||
struct VulkanRenderOutput_t {
|
||||
EResolveMode m_eResolveMode;
|
||||
|
||||
VkFrameObject_t m_stImage;
|
||||
VkFrameObject_t m_stResolveImage;
|
||||
|
||||
ELoadMode m_eLoadMode;
|
||||
EStoreMode m_eStoreMode;
|
||||
};
|
||||
|
||||
BEGIN_VULKAN_COMMAND(Begin)
|
||||
CUtlVector<VulkanRenderOutput_t> images;
|
||||
VulkanRenderOutput_t stDepthImage;
|
||||
@@ -35,6 +25,36 @@ END_VULKAN_COMMAND(Begin)
|
||||
BEGIN_VULKAN_COMMAND(End)
|
||||
END_VULKAN_COMMAND(End)
|
||||
|
||||
BEGIN_VULKAN_COMMAND(SetVertexBuffer)
|
||||
uint32_t uBinding;
|
||||
IVertexBuffer *pBuffer;
|
||||
END_VULKAN_COMMAND(SetVertexBuffer)
|
||||
|
||||
BEGIN_VULKAN_COMMAND(SetShader)
|
||||
IShader *pShader;
|
||||
END_VULKAN_COMMAND(SetShader)
|
||||
|
||||
BEGIN_VULKAN_COMMAND(DrawPrimitives)
|
||||
uint32_t nVertexCount;
|
||||
uint32_t nFirstVertex;
|
||||
uint32_t nInstanceCount;
|
||||
uint32_t nFirstInstance;
|
||||
END_VULKAN_COMMAND(DrawPrimitives)
|
||||
|
||||
BEGIN_VULKAN_COMMAND(SetScissors)
|
||||
uint32_t uX;
|
||||
uint32_t uY;
|
||||
uint32_t uWidth;
|
||||
uint32_t uHeight;
|
||||
END_VULKAN_COMMAND(SetScissors)
|
||||
|
||||
BEGIN_VULKAN_COMMAND(SetViewport)
|
||||
uint32_t uX;
|
||||
uint32_t uY;
|
||||
uint32_t uWidth;
|
||||
uint32_t uHeight;
|
||||
END_VULKAN_COMMAND(SetViewport)
|
||||
|
||||
BEGIN_VULKAN_COMMAND(Empty)
|
||||
END_VULKAN_COMMAND(Empty)
|
||||
|
||||
|
||||
@@ -31,10 +31,10 @@ DECLARE_VULKAN_COMMAND(ClearColor)
|
||||
DECLARE_VULKAN_COMMAND(Begin)
|
||||
{
|
||||
VkRenderingInfo stRenderingInfo = {};
|
||||
CUtlVector<VkRenderingAttachmentInfo> attachments;
|
||||
CUtlVector<VkRenderingAttachmentInfo> attachments = {};
|
||||
for (auto i: images)
|
||||
{
|
||||
VkRenderingAttachmentInfo a;
|
||||
VkRenderingAttachmentInfo a = {};
|
||||
a.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO;
|
||||
a.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
a.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
@@ -47,6 +47,7 @@ DECLARE_VULKAN_COMMAND(Begin)
|
||||
stRenderingInfo.layerCount = 1;
|
||||
stRenderingInfo.colorAttachmentCount = attachments.GetSize();
|
||||
stRenderingInfo.pColorAttachments = attachments.GetData();
|
||||
stRenderingInfo.renderArea = (VkRect2D){0,0,nResolutionX,nResolutionY};
|
||||
|
||||
vkCmdBeginRendering(hCommandBuffer, &stRenderingInfo);
|
||||
}
|
||||
@@ -55,3 +56,21 @@ DECLARE_VULKAN_COMMAND(End)
|
||||
{
|
||||
vkCmdEndRendering(hCommandBuffer);
|
||||
}
|
||||
|
||||
DECLARE_VULKAN_COMMAND(SetShader)
|
||||
{
|
||||
CVkShader *pVkShader = (CVkShader*)pShader;
|
||||
vkCmdBindPipeline(hCommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pVkShader->m_hPipeline);
|
||||
}
|
||||
|
||||
DECLARE_VULKAN_COMMAND(SetVertexBuffer)
|
||||
{
|
||||
CVkBuffer *pVkBuffer = (CVkBuffer*)pBuffer;
|
||||
VkDeviceSize uOffset = 0;
|
||||
vkCmdBindVertexBuffers(hCommandBuffer, uBinding, 1, &pVkBuffer->m_buffer, &uOffset);
|
||||
}
|
||||
|
||||
DECLARE_VULKAN_COMMAND(DrawPrimitives)
|
||||
{
|
||||
vkCmdDraw(hCommandBuffer, nVertexCount, nInstanceCount, nFirstVertex, nFirstInstance);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
#include "tier1/utlbuffer.h"
|
||||
#include "tier1/utlvector.h"
|
||||
#include "tier2/ifilesystem.h"
|
||||
#include "vulkan/vulkan_core.h"
|
||||
#include "../shaderparser.h"
|
||||
|
||||
|
||||
BEGIN_BUILD_PIPELINE_LIBRARY(VertexDescription)
|
||||
library.flags = VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT;
|
||||
@@ -48,3 +49,250 @@ void CVkVertexDescriptionPipelineLibrary::SetTopology( ETopologyMode eTopology )
|
||||
{
|
||||
m_eTopology = VulkanGetTopology(eTopology);
|
||||
}
|
||||
struct VulkanDescriptorInit_t
|
||||
{
|
||||
CUtlVector<VkDescriptorSetLayoutBinding> m_bindings = {};
|
||||
VkDescriptorSetLayoutCreateInfo m_set = {};
|
||||
};
|
||||
|
||||
BEGIN_BUILD_PIPELINE_LIBRARY(VertexTransform)
|
||||
library.flags = VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT;
|
||||
|
||||
VkPipelineRasterizationStateCreateInfo rasterState = {};
|
||||
VkPipelineViewportStateCreateInfo viewportState = {};
|
||||
int i = 0;
|
||||
|
||||
CUtlVector<VulkanDescriptor_t> vertexDescriptors = ShaderParser()->GetDescriptors(m_pShader, SHADER_STAGE_VERTEX);
|
||||
VulkanDescriptorInit_t inits[SHADER_STAGE_COUNT] = {};
|
||||
CUtlVector<CUtlBuffer<unsigned char>> spirvs = {};
|
||||
CUtlVector<VkPipelineShaderStageCreateInfo> stages = {};
|
||||
CUtlVector<VkShaderModuleCreateInfo> stageShaders = {};
|
||||
|
||||
for ( auto desc: vertexDescriptors )
|
||||
{
|
||||
VkDescriptorSetLayoutBinding binding = {};
|
||||
binding.descriptorCount = 1;
|
||||
binding.descriptorType = desc.eDescriptorType;
|
||||
binding.binding = desc.uBinding;
|
||||
inits[desc.eDescriptorType].m_bindings.AppendTail(binding);
|
||||
}
|
||||
for ( i = 0; i < SHADER_STAGE_COUNT; i++)
|
||||
{
|
||||
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] );
|
||||
}
|
||||
|
||||
for ( i = 0; i < SHADER_STAGE_COUNT; i++)
|
||||
{
|
||||
if ( i == SHADER_STAGE_PIXEL )
|
||||
continue;
|
||||
|
||||
CUtlBuffer<unsigned char> code = ShaderParser()->GetShaderCode(m_pShader, (EShaderStage)i);
|
||||
|
||||
// We may fail loading the specific stage
|
||||
if (code.GetSize() == 0)
|
||||
continue;
|
||||
|
||||
VkShaderModuleCreateInfo mod = {};
|
||||
mod.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
|
||||
mod.codeSize = code.GetSize();
|
||||
|
||||
|
||||
VkPipelineShaderStageCreateInfo shader = {};
|
||||
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);
|
||||
}
|
||||
|
||||
// Fix pointers
|
||||
for ( i = 0; i < stages.GetSize(); i++ )
|
||||
{
|
||||
stageShaders[i].pCode = (uint32_t*)spirvs[i].GetMemory();
|
||||
stages[i].pNext = &stageShaders[i];
|
||||
}
|
||||
|
||||
VkPipelineLayoutCreateInfo stPipelineLayout = {};
|
||||
stPipelineLayout.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
||||
stPipelineLayout.setLayoutCount = SHADER_STAGE_COUNT;
|
||||
stPipelineLayout.pSetLayouts = m_setLayouts;
|
||||
stPipelineLayout.flags = VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT ;
|
||||
vkCreatePipelineLayout(g_vkDevice, &stPipelineLayout, NULL, &m_layout);
|
||||
|
||||
rasterState.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
|
||||
rasterState.polygonMode = VK_POLYGON_MODE_FILL;
|
||||
rasterState.lineWidth = 1;
|
||||
|
||||
viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
|
||||
|
||||
VkDynamicState dynamicStates[] = {
|
||||
VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT,
|
||||
VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT,
|
||||
};
|
||||
VkPipelineDynamicStateCreateInfo dynamicState = {};
|
||||
dynamicState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
|
||||
dynamicState.dynamicStateCount = 2;
|
||||
dynamicState.pDynamicStates = dynamicStates;
|
||||
pipeline.stageCount = stages.GetSize();
|
||||
pipeline.pStages = stages.GetData();
|
||||
pipeline.pDynamicState = &dynamicState;
|
||||
pipeline.pRasterizationState = &rasterState;
|
||||
pipeline.pViewportState = &viewportState;
|
||||
pipeline.layout = m_layout;
|
||||
END_BUILD_PIPELINE_LIBRARY()
|
||||
|
||||
void CVkVertexTransformPipelineLibrary::SetShader( CCompiledShader *pShader )
|
||||
{
|
||||
m_pShader = pShader;
|
||||
}
|
||||
|
||||
BEGIN_BUILD_PIPELINE_LIBRARY(PixelShader)
|
||||
printf("--- PixelShader ---\n");
|
||||
|
||||
VkPipelineDepthStencilStateCreateInfo depthStencil = {};
|
||||
int i = 0;
|
||||
CUtlVector<VulkanDescriptor_t> vertexDescriptors = ShaderParser()->GetDescriptors(m_pShader, SHADER_STAGE_PIXEL);
|
||||
VulkanDescriptorInit_t inits[SHADER_STAGE_COUNT] = {};
|
||||
for ( auto desc: vertexDescriptors )
|
||||
{
|
||||
VkDescriptorSetLayoutBinding binding = {};
|
||||
binding.descriptorCount = 1;
|
||||
binding.descriptorType = desc.eDescriptorType;
|
||||
binding.binding = desc.uBinding;
|
||||
inits[desc.eDescriptorType].m_bindings.AppendTail(binding);
|
||||
}
|
||||
for ( i = 0; i < SHADER_STAGE_COUNT; i++)
|
||||
{
|
||||
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] );
|
||||
}
|
||||
|
||||
VkPipelineLayoutCreateInfo stPipelineLayout = {};
|
||||
stPipelineLayout.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
||||
stPipelineLayout.setLayoutCount = SHADER_STAGE_COUNT;
|
||||
stPipelineLayout.pSetLayouts = m_setLayouts;
|
||||
stPipelineLayout.flags = VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT ;
|
||||
vkCreatePipelineLayout(g_vkDevice, &stPipelineLayout, NULL, &m_layout);
|
||||
|
||||
CUtlBuffer<unsigned char> spirv = {};
|
||||
VkPipelineShaderStageCreateInfo shader = {};
|
||||
VkShaderModuleCreateInfo mod = {};
|
||||
for ( auto desc: vertexDescriptors )
|
||||
{
|
||||
VkDescriptorSetLayoutBinding binding = {};
|
||||
binding.descriptorCount = 1;
|
||||
binding.descriptorType = desc.eDescriptorType;
|
||||
binding.binding = desc.uBinding;
|
||||
inits[desc.eDescriptorType].m_bindings.AppendTail(binding);
|
||||
}
|
||||
for ( i = 0; i < SHADER_STAGE_COUNT; i++)
|
||||
{
|
||||
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] );
|
||||
}
|
||||
|
||||
spirv = ShaderParser()->GetShaderCode(m_pShader, SHADER_STAGE_PIXEL);
|
||||
|
||||
if (spirv.GetSize() == 0)
|
||||
goto skipshader;
|
||||
|
||||
mod.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
|
||||
mod.codeSize = spirv.GetSize();
|
||||
mod.pCode = (uint32_t*)spirv.GetMemory();
|
||||
|
||||
shader.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
||||
shader.pName = "main";
|
||||
shader.stage = VulkanGetShaderStage(SHADER_STAGE_PIXEL);
|
||||
shader.pNext = &mod;
|
||||
|
||||
pipeline.stageCount = 1;
|
||||
pipeline.pStages = &shader;
|
||||
|
||||
depthStencil.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
|
||||
depthStencil.minDepthBounds = 0;
|
||||
depthStencil.maxDepthBounds = 1;
|
||||
depthStencil.depthTestEnable = VK_TRUE;
|
||||
depthStencil.depthWriteEnable = VK_TRUE;
|
||||
depthStencil.depthBoundsTestEnable = VK_FALSE;
|
||||
depthStencil.stencilTestEnable = VK_FALSE;
|
||||
depthStencil.depthCompareOp = VK_COMPARE_OP_LESS;
|
||||
pipeline.pDepthStencilState = &depthStencil;
|
||||
|
||||
skipshader:
|
||||
|
||||
library.flags = VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT;
|
||||
pipeline.layout = m_layout;
|
||||
END_BUILD_PIPELINE_LIBRARY()
|
||||
|
||||
void CVkPixelShaderPipelineLibrary::SetShader( CCompiledShader *pShader )
|
||||
{
|
||||
m_pShader = pShader;
|
||||
}
|
||||
|
||||
BEGIN_BUILD_PIPELINE_LIBRARY(PixelOutput)
|
||||
printf("--- PixelOutput ---\n");
|
||||
VkPipelineMultisampleStateCreateInfo msaa = {};
|
||||
VkPipelineRenderingCreateInfo render = {};
|
||||
VkPipelineDepthStencilStateCreateInfo depthStencil = {};
|
||||
VkPipelineColorBlendStateCreateInfo blend = {};
|
||||
CUtlVector<VkPipelineColorBlendAttachmentState> attachments = {};
|
||||
|
||||
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.colorAttachmentCount = m_eFormats.GetSize();
|
||||
render.pColorAttachmentFormats = m_eFormats.GetData();
|
||||
render.depthAttachmentFormat = VK_FORMAT_D32_SFLOAT;;
|
||||
|
||||
depthStencil.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
|
||||
depthStencil.minDepthBounds = 0;
|
||||
depthStencil.maxDepthBounds = 1;
|
||||
depthStencil.depthTestEnable = VK_TRUE;
|
||||
depthStencil.depthWriteEnable = VK_TRUE;
|
||||
depthStencil.depthBoundsTestEnable = VK_FALSE;
|
||||
depthStencil.stencilTestEnable = VK_FALSE;
|
||||
depthStencil.depthCompareOp = VK_COMPARE_OP_LESS;
|
||||
|
||||
for ( auto e: m_eFormats )
|
||||
{
|
||||
VkPipelineColorBlendAttachmentState a = {};
|
||||
a.blendEnable = VK_TRUE;
|
||||
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;
|
||||
attachments.AppendTail(a);
|
||||
}
|
||||
blend.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
|
||||
blend.attachmentCount = m_eFormats.GetSize();
|
||||
blend.pAttachments = attachments.GetData();
|
||||
|
||||
pipeline.pDepthStencilState = &depthStencil;
|
||||
pipeline.pColorBlendState = &blend;
|
||||
pipeline.pMultisampleState = &msaa;
|
||||
render.pNext = pipeline.pNext;
|
||||
pipeline.pNext = &render;
|
||||
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));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
#include "vulkan_state.h"
|
||||
CVkMaterial::CVkMaterial( IShader *pShader )
|
||||
{
|
||||
m_pVkShader = (CVkShader*)pShader;
|
||||
}
|
||||
|
||||
CVkMaterial::~CVkMaterial()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CVkMaterial::VSSetShaderResource( uint32_t uRegister, IRenderingObject *pResource )
|
||||
{
|
||||
SetShaderResource(uRegister, SHADER_STAGE_VERTEX, pResource);
|
||||
}
|
||||
|
||||
void CVkMaterial::PSSetShaderResource( uint32_t uRegister, IRenderingObject *pResource )
|
||||
{
|
||||
SetShaderResource(uRegister, SHADER_STAGE_PIXEL, pResource);
|
||||
}
|
||||
|
||||
void CVkMaterial::VSSetConstantsBuffer( uint32_t uRegister, IBuffer *pConstants )
|
||||
{
|
||||
SetShaderResource(uRegister, SHADER_STAGE_VERTEX, pConstants);
|
||||
}
|
||||
|
||||
void CVkMaterial::PSSetConstantsBuffer( uint32_t uRegister, IBuffer *pConstants )
|
||||
{
|
||||
SetShaderResource(uRegister, SHADER_STAGE_PIXEL, pConstants);
|
||||
}
|
||||
|
||||
void CVkMaterial::SetShaderResource( uint32_t uRegister, uint32_t uSet, IRenderingObject *pObject)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "materialsystem/imaterialsystem.h"
|
||||
#include "materialsystem/compiledshadermgr.h"
|
||||
#include "tier1/utlvector.h"
|
||||
#include "vulkan_state.h"
|
||||
|
||||
@@ -13,11 +14,28 @@ BEGIN_DEFINE_PIPELINE_LIBRARY(VertexDescription)
|
||||
END_DEFINE_PIPELINE_LIBRARY()
|
||||
|
||||
BEGIN_DEFINE_PIPELINE_LIBRARY(VertexTransform)
|
||||
void SetShader( CCompiledShader *pShader );
|
||||
|
||||
CCompiledShader *m_pShader;
|
||||
|
||||
VkDescriptorSetLayout m_setLayouts[SHADER_STAGE_COUNT];
|
||||
VkPipelineLayout m_layout;
|
||||
END_DEFINE_PIPELINE_LIBRARY()
|
||||
|
||||
BEGIN_DEFINE_PIPELINE_LIBRARY(PixelShade)
|
||||
BEGIN_DEFINE_PIPELINE_LIBRARY(PixelShader)
|
||||
void SetShader( CCompiledShader *pShader );
|
||||
void SetDepthRequired( bool b );
|
||||
|
||||
CCompiledShader *m_pShader;
|
||||
VkDescriptorSetLayout m_setLayouts[SHADER_STAGE_COUNT];
|
||||
VkPipelineLayout m_layout;
|
||||
bool m_bIsDepthRequired = false;
|
||||
END_DEFINE_PIPELINE_LIBRARY()
|
||||
|
||||
BEGIN_DEFINE_PIPELINE_LIBRARY(PixelOutput)
|
||||
void AddAttachment( EImageFormat eFormat );
|
||||
void SetDepthRequired( bool b );
|
||||
|
||||
CUtlVector<VkFormat> m_eFormats = {};
|
||||
bool m_bIsDepthRequired = false;
|
||||
END_DEFINE_PIPELINE_LIBRARY()
|
||||
|
||||
@@ -0,0 +1,193 @@
|
||||
#include "vulkan_state.h"
|
||||
#include "commands.h"
|
||||
|
||||
void CVkRenderCommandList::ResetRendering()
|
||||
{
|
||||
/*
|
||||
for ( auto m: m_materials)
|
||||
{
|
||||
delete m.m_pCommandBuffer;
|
||||
}
|
||||
*/
|
||||
m_materials = {};
|
||||
}
|
||||
|
||||
void CVkRenderCommandList::SetRenderTarget( uint32_t uIndex, IImage *pImage )
|
||||
{
|
||||
SwitchRenderingStage(RENDERING_STAGE_SETUP_RASTER);
|
||||
VulkanRenderOutput_t *pOutput = FindOrCreateRenderOutput(uIndex);
|
||||
pOutput->m_stImage.m_pSingle = pImage;
|
||||
}
|
||||
|
||||
void CVkRenderCommandList::SetClearColor( uint32_t uIndex, float r, float g, float b, float a )
|
||||
{
|
||||
SwitchRenderingStage(RENDERING_STAGE_SETUP_RASTER);
|
||||
VulkanRenderOutput_t *pOutput = FindOrCreateRenderOutput(uIndex);
|
||||
pOutput->m_fClearColor[0] = r;
|
||||
pOutput->m_fClearColor[1] = g;
|
||||
pOutput->m_fClearColor[2] = b;
|
||||
pOutput->m_fClearColor[3] = a;
|
||||
}
|
||||
|
||||
void CVkRenderCommandList::SetDepthTarget( IImage *pDepth )
|
||||
{
|
||||
SwitchRenderingStage(RENDERING_STAGE_SETUP_RASTER);
|
||||
m_depth.m_stImage.m_pSingle = pDepth;
|
||||
|
||||
}
|
||||
void CVkRenderCommandList::SetClearDepth( float fVal)
|
||||
{
|
||||
SwitchRenderingStage(RENDERING_STAGE_SETUP_RASTER);
|
||||
m_depth.m_fClearDepth = fVal;
|
||||
}
|
||||
|
||||
void CVkRenderCommandList::SetRenderResolution( uint32_t iWidth, uint32_t iHeight )
|
||||
{
|
||||
SwitchRenderingStage(RENDERING_STAGE_SETUP_RASTER);
|
||||
}
|
||||
|
||||
|
||||
void CVkRenderCommandList::SetScissors( uint32_t uX, uint32_t uY, uint32_t uWidth, uint32_t uHeight )
|
||||
{
|
||||
SwitchRenderingStage(RENDERING_STAGE_RASTER);
|
||||
}
|
||||
|
||||
void CVkRenderCommandList::SetViewport( uint32_t uX, uint32_t uY, uint32_t uWidth, uint32_t uHeight, float fMinDepth, float fMaxDepth )
|
||||
{
|
||||
SwitchRenderingStage(RENDERING_STAGE_RASTER);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void CVkRenderCommandList::SetMaterial( IMaterial *pMaterial )
|
||||
{
|
||||
SwitchRenderingStage(RENDERING_STAGE_SETUP_RASTER);
|
||||
bool bWasCreated = false;
|
||||
m_pCurrentMaterialBuffer = FindOrCreateMaterialCommandBuffer(pMaterial, &bWasCreated);
|
||||
if (bWasCreated)
|
||||
{
|
||||
m_pCurrentMaterialBuffer->Reset();
|
||||
CVkBeginCommand *pBeginCommand = CREATE_COMMAND(Begin);
|
||||
pBeginCommand->images = m_pOutput;
|
||||
pBeginCommand->nResolutionX = 1280;
|
||||
pBeginCommand->nResolutionY = 720;
|
||||
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);
|
||||
CVkSetViewportCommand *pViewportCommand = CREATE_COMMAND(SetViewport);
|
||||
}
|
||||
}
|
||||
|
||||
void CVkRenderCommandList::SetVertexBuffer( uint32_t uBinding, IVertexBuffer *pBuffer )
|
||||
{
|
||||
SwitchRenderingStage(RENDERING_STAGE_RASTER);
|
||||
CVkSetVertexBufferCommand *pCmd = CREATE_COMMAND(SetVertexBuffer);
|
||||
pCmd->uBinding = uBinding;
|
||||
pCmd->pBuffer = pBuffer;
|
||||
m_pCurrentMaterialBuffer->AddCommand(pCmd);
|
||||
}
|
||||
|
||||
void CVkRenderCommandList::SetIndexBuffer( IVertexBuffer *pBuffer )
|
||||
{
|
||||
SwitchRenderingStage(RENDERING_STAGE_RASTER);
|
||||
}
|
||||
|
||||
void CVkRenderCommandList::DrawPrimitives( uint32_t nVertexCount, uint32_t nFirstVertex, uint32_t nInstanceCount, uint32_t nFirstInstance )
|
||||
{
|
||||
SwitchRenderingStage(RENDERING_STAGE_RASTER);
|
||||
|
||||
CVkDrawPrimitivesCommand *pCmd = CREATE_COMMAND(DrawPrimitives);
|
||||
pCmd->nVertexCount = nVertexCount;
|
||||
pCmd->nFirstVertex = nFirstVertex;
|
||||
pCmd->nInstanceCount = nInstanceCount;
|
||||
pCmd->nFirstInstance = nFirstInstance;
|
||||
m_pCurrentMaterialBuffer->AddCommand(pCmd);
|
||||
}
|
||||
|
||||
void CVkRenderCommandList::DrawPrimitivesIndexed( uint32_t nIndexCount, uint32_t nFirstIndex, uint32_t nVertexOffset, uint32_t nInstanceCount, uint32_t nFirstInstance )
|
||||
{
|
||||
SwitchRenderingStage(RENDERING_STAGE_RASTER);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void CVkRenderCommandList::ResolveImage( IImage *pOriginal, IImage *pResolved )
|
||||
{
|
||||
SwitchRenderingStage(RENDERING_STAGE_POST_RASTER);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void CVkRenderCommandList::StartRecording()
|
||||
{
|
||||
ResetRendering();
|
||||
}
|
||||
|
||||
void CVkRenderCommandList::EndRecording()
|
||||
{
|
||||
for ( auto m: m_materials)
|
||||
{
|
||||
CVkEndCommand *pEndCommand = CREATE_COMMAND(End);
|
||||
m.m_pCommandBuffer->AddCommand(pEndCommand);
|
||||
m.m_pCommandBuffer->Render();
|
||||
}
|
||||
}
|
||||
|
||||
void CVkRenderCommandList::Submit()
|
||||
{
|
||||
for ( auto m: m_materials)
|
||||
{
|
||||
m.m_pCommandBuffer->Submit();
|
||||
}
|
||||
}
|
||||
|
||||
void CVkRenderCommandList::SwitchRenderingStage( EVulkanRenderingStage eStage )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
VulkanRenderOutput_t *CVkRenderCommandList::FindOrCreateRenderOutput( uint32_t uIndex )
|
||||
{
|
||||
for ( auto &v: m_pOutput )
|
||||
{
|
||||
if (v.m_uIndex == uIndex)
|
||||
return &v;
|
||||
}
|
||||
|
||||
VulkanRenderOutput_t output = {};
|
||||
output.m_uIndex = uIndex;
|
||||
m_pOutput.AppendTail(output);
|
||||
return &m_pOutput[m_pOutput.GetSize()-1];
|
||||
}
|
||||
|
||||
IVkCommandBuffer *CVkRenderCommandList::FindOrCreateMaterialCommandBuffer( IMaterial *pMaterial, bool *pbWasCreated )
|
||||
{
|
||||
for (auto &m: m_materials)
|
||||
{
|
||||
if (m.m_pMaterial == pMaterial)
|
||||
{
|
||||
if (pbWasCreated)
|
||||
*pbWasCreated = false;
|
||||
return m.m_pCommandBuffer;
|
||||
}
|
||||
}
|
||||
|
||||
VulkanMaterialCommandBuffer_t mat;
|
||||
mat.m_pCommandBuffer = g_pCommandBufferManager->CreateCommandBuffer();
|
||||
mat.m_pMaterial = pMaterial;
|
||||
m_materials.AppendTail(mat);
|
||||
if (pbWasCreated)
|
||||
*pbWasCreated = true;
|
||||
return m_materials.GetLast().m_pCommandBuffer;
|
||||
}
|
||||
@@ -31,17 +31,18 @@ VkQueue g_vkDrawQueue;
|
||||
VkQueue g_vkPresentQueue;
|
||||
|
||||
VkInstance g_vkInstance;
|
||||
VmaAllocator g_vkAllocator;
|
||||
VkPhysicalDevice g_vkPhysicalDevice;
|
||||
VkDevice g_vkDevice;
|
||||
VkSwapchainKHR g_vkSwapchain;
|
||||
|
||||
CUtlVector<VkFence> g_vkFences;
|
||||
CUtlVector<VkSemaphore> g_vkGraphicsSemaphores;
|
||||
CUtlVector<VkSemaphore> g_vkPresentSemaphores;
|
||||
CUtlVector<VkFence> g_vkFences = {};
|
||||
CUtlVector<VkSemaphore> g_vkGraphicsSemaphores = {};
|
||||
CUtlVector<VkSemaphore> g_vkPresentSemaphores = {};
|
||||
|
||||
CUtlVector<VkCommandPool> g_vkCommandPools;
|
||||
CUtlVector<VkCommandPool> g_vkCommandPools = {};
|
||||
|
||||
CUtlVector<IImage*> g_vkSwapchainImages;
|
||||
CUtlVector<IImage*> g_vkSwapchainImages = {};
|
||||
VkFormat g_vkWindowImageFormat;
|
||||
|
||||
|
||||
@@ -50,9 +51,14 @@ CVkImage::CVkImage()
|
||||
|
||||
}
|
||||
|
||||
CVkImage::CVkImage( uint32_t nWidth, uint32_t nHeight, EImageFormat eFormat, EMultisampleType eMultisampleType)
|
||||
CVkImage::CVkImage( uint32_t nWidth, uint32_t nHeight, uint32_t nDepth, EImageFormat eFormat, EMultisampleType eMultisampleType, EImageType eImageType, VkImageUsageFlagBits eUsage )
|
||||
{
|
||||
CreateImage(nWidth, nHeight, eFormat, eMultisampleType);
|
||||
m_nWidth = nWidth;
|
||||
m_nHeight = nHeight;
|
||||
m_eMultisampleType = eMultisampleType;
|
||||
m_eImageType = eImageType;
|
||||
m_eFormat = eFormat;
|
||||
CreateImage(nWidth, nHeight, eFormat, eMultisampleType, eUsage);
|
||||
CreateImageView();
|
||||
}
|
||||
|
||||
@@ -107,9 +113,26 @@ VkFormat CVkImage::GetImageFormat( enum EImageFormat eImageFormat )
|
||||
}
|
||||
}
|
||||
|
||||
void CVkImage::CreateImage( uint32_t nWidth, uint32_t nHeight, EImageFormat eFormat, EMultisampleType eMultisampleType )
|
||||
void CVkImage::CreateImage( uint32_t nWidth, uint32_t nHeight, EImageFormat eFormat, EMultisampleType eMultisampleType, VkImageUsageFlagBits eUsage )
|
||||
{
|
||||
VkImageCreateInfo stCreateInfo = {};
|
||||
VmaAllocationCreateInfo stAlloc = {};
|
||||
stCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
||||
stCreateInfo.imageType = VK_IMAGE_TYPE_2D;
|
||||
stCreateInfo.extent.width = nWidth;
|
||||
stCreateInfo.extent.height = nHeight;
|
||||
stCreateInfo.extent.depth = 1;
|
||||
stCreateInfo.mipLevels = 1;
|
||||
stCreateInfo.arrayLayers = 1;
|
||||
stCreateInfo.usage = eUsage;
|
||||
stCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
|
||||
stCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
stCreateInfo.format = GetImageFormat(eFormat);
|
||||
stCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
|
||||
stAlloc.usage = VMA_MEMORY_USAGE_AUTO;
|
||||
|
||||
vmaCreateImage(g_vkAllocator, &stCreateInfo, &stAlloc, &m_image, &m_allocation, NULL);
|
||||
}
|
||||
|
||||
void CVkImage::CreateImageView()
|
||||
@@ -159,6 +182,28 @@ EMultisampleType CVkImage::GetMultisampleType()
|
||||
|
||||
CVkBuffer::CVkBuffer( uint32_t nSize, VkBufferUsageFlags2 eUsage, uint32_t nAlignment )
|
||||
{
|
||||
VkBufferUsageFlags2CreateInfo stUsage = {};
|
||||
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;
|
||||
|
||||
stBufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
||||
stBufferInfo.size = nSize;
|
||||
stBufferInfo.pNext = &stUsage;
|
||||
|
||||
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);
|
||||
|
||||
stAddress.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO;
|
||||
stAddress.buffer = m_buffer;
|
||||
m_address = vkGetBufferDeviceAddress(g_vkDevice, &stAddress);
|
||||
|
||||
m_nSize = nSize;
|
||||
}
|
||||
|
||||
CVkBuffer::~CVkBuffer()
|
||||
@@ -169,12 +214,10 @@ CVkBuffer::~CVkBuffer()
|
||||
|
||||
void CVkBuffer::SetDebugName( const char *szName )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CVkBuffer::Lock()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CVkBuffer::Unlock()
|
||||
@@ -184,21 +227,22 @@ void CVkBuffer::Unlock()
|
||||
|
||||
void *CVkBuffer::Map()
|
||||
{
|
||||
void *pData;
|
||||
|
||||
pData = NULL;
|
||||
vmaMapMemory(g_vkAllocator, m_allocation, &pData);
|
||||
return pData;
|
||||
}
|
||||
|
||||
void CVkBuffer::Unmap()
|
||||
{
|
||||
|
||||
vmaUnmapMemory(g_vkAllocator, m_allocation);
|
||||
}
|
||||
|
||||
uint32_t CVkBuffer::GetSize()
|
||||
{
|
||||
|
||||
return m_nSize;
|
||||
}
|
||||
|
||||
|
||||
|
||||
class CVkRenderContext: public IRenderContext
|
||||
{
|
||||
public:
|
||||
@@ -206,8 +250,17 @@ public:
|
||||
virtual void Frame( float fDeltaTime ) override;
|
||||
virtual void Shutdown() override;
|
||||
|
||||
virtual void SetOutputImage( IImage *pImage ) override;
|
||||
|
||||
virtual bool BIsOutputImageOutdated() override;
|
||||
virtual uint32_t GetNewOutputImageWidth() override;
|
||||
virtual uint32_t GetNewOutputImageHeight() override;
|
||||
virtual EImageFormat GetNewOutputImageFormat() 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;
|
||||
@@ -218,16 +271,14 @@ public:
|
||||
IBuffer *CreateBufferAligned( uint32_t nSize, uint32_t nAlignment, VkBufferUsageFlags2 eUsage );
|
||||
|
||||
virtual IShader *CreateShader( const char *szName ) override;
|
||||
virtual void DestroyShader( IShader *pMaterial ) override;
|
||||
virtual void DestroyShader( IShader *pShader ) override;
|
||||
|
||||
virtual IMaterial *CreateMaterial( IShader *pShader ) override;
|
||||
virtual void DestroyMaterial( IMaterial *pMaterial ) override;
|
||||
|
||||
virtual void SetMaterial( IMaterial *pMaterial ) override;
|
||||
virtual void SetVertexBuffer( IVertexBuffer *pBuffer ) override;
|
||||
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 IRenderCommandList *CreateCommandList() override;
|
||||
virtual void DestroyCommandList( IRenderCommandList *pCommandList ) override;
|
||||
virtual void SubmitCommandList(IRenderCommandList *pList) override;
|
||||
private:
|
||||
VkPhysicalDevice SelectPhysicalDevice( CUtlVector<VkPhysicalDevice> physicalDevices );
|
||||
CUtlVector<const char *> GetDeviceExtensions();
|
||||
@@ -236,17 +287,45 @@ private:
|
||||
|
||||
void CreateSwapchain();
|
||||
void DestroySwapchain();
|
||||
};
|
||||
|
||||
CVkRenderContext s_vkRenderContext;
|
||||
IRenderContext *g_pVkRenderContext = &s_vkRenderContext;
|
||||
IImage *m_pOutputImage = NULL;
|
||||
bool m_bOutputImageOutdated = true;
|
||||
};
|
||||
EXPOSE_INTERFACE(CVkRenderContext, IRenderContext, RENDER_CONTEXT_VULKAN_INTERFACE_NAME);
|
||||
|
||||
void CVkRenderContext::SetOutputImage( IImage *pImage )
|
||||
{
|
||||
m_pOutputImage = pImage;
|
||||
}
|
||||
|
||||
|
||||
bool CVkRenderContext::BIsOutputImageOutdated( )
|
||||
{
|
||||
return m_bOutputImageOutdated;
|
||||
}
|
||||
|
||||
uint32_t CVkRenderContext::GetNewOutputImageWidth()
|
||||
{
|
||||
return 1280;
|
||||
}
|
||||
|
||||
uint32_t CVkRenderContext::GetNewOutputImageHeight()
|
||||
{
|
||||
return 720;
|
||||
}
|
||||
|
||||
EImageFormat CVkRenderContext::GetNewOutputImageFormat()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Creates vertex buffer. Wrapper over CreateBuffer
|
||||
//-----------------------------------------------------------------------------
|
||||
IVertexBuffer *CVkRenderContext::CreateVertexBuffer( uint32_t nSize )
|
||||
{
|
||||
return (IVertexBuffer*)CreateBuffer(nSize, VK_BUFFER_USAGE_2_VERTEX_BUFFER_BIT);
|
||||
return (IVertexBuffer*)CreateBuffer(nSize, VK_BUFFER_USAGE_2_VERTEX_BUFFER_BIT |VK_BUFFER_USAGE_2_STORAGE_BUFFER_BIT );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -254,13 +333,28 @@ IVertexBuffer *CVkRenderContext::CreateVertexBuffer( uint32_t nSize )
|
||||
//-----------------------------------------------------------------------------
|
||||
IIndexBuffer *CVkRenderContext::CreateIndexBuffer( uint32_t nSize )
|
||||
{
|
||||
return (IIndexBuffer*)CreateBuffer(nSize, VK_BUFFER_USAGE_2_INDEX_BUFFER_BIT);
|
||||
return (IIndexBuffer*)CreateBuffer(nSize, VK_BUFFER_USAGE_2_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_2_STORAGE_BUFFER_BIT);
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// Creates storage buffer. Wrapper over CreateBuffer
|
||||
//-----------------------------------------------------------------------------
|
||||
IBuffer *CVkRenderContext::CreateStorageBuffer( uint32_t nSize )
|
||||
{
|
||||
return (IVertexBuffer*)CreateBuffer(nSize, VK_BUFFER_USAGE_2_STORAGE_BUFFER_BIT);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Creates constant buffer. Wrapper over CreateBuffer
|
||||
//-----------------------------------------------------------------------------
|
||||
IBuffer *CVkRenderContext::CreateConstantBuffer( uint32_t nSize )
|
||||
{
|
||||
return (IIndexBuffer*)CreateBuffer(nSize, VK_BUFFER_USAGE_2_UNIFORM_BUFFER_BIT);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Creates basic vulkan buffer
|
||||
//-----------------------------------------------------------------------------
|
||||
IBuffer *CreateBuffer( uint32_t nSize, VkBufferUsageFlags2 eUsage )
|
||||
IBuffer *CVkRenderContext::CreateBuffer( uint32_t nSize, VkBufferUsageFlags2 eUsage )
|
||||
{
|
||||
CVkBuffer *pBuffer = new CVkBuffer(nSize, eUsage, 0);
|
||||
return pBuffer;
|
||||
@@ -271,7 +365,7 @@ IBuffer *CreateBuffer( uint32_t nSize, VkBufferUsageFlags2 eUsage )
|
||||
// Useful for everything eg: ray tracing, which requires them to be aligned
|
||||
// to the groupBaseAlignment.
|
||||
//-----------------------------------------------------------------------------
|
||||
IBuffer *CreateBufferAligned( uint32_t nSize, uint32_t nAlignment, VkBufferUsageFlags2 eUsage )
|
||||
IBuffer *CVkRenderContext::CreateBufferAligned( uint32_t nSize, uint32_t nAlignment, VkBufferUsageFlags2 eUsage )
|
||||
{
|
||||
|
||||
}
|
||||
@@ -279,12 +373,15 @@ IBuffer *CreateBufferAligned( uint32_t nSize, uint32_t nAlignment, VkBufferUsage
|
||||
|
||||
IImage *CVkRenderContext::CreateRenderTarget( uint32_t x, uint32_t y, EImageFormat eFormat, EMultisampleType eMultisampleType )
|
||||
{
|
||||
|
||||
if (eFormat == IMAGE_FORMAT_D32_SFLOAT)
|
||||
return new CVkImage(x, y, 1, eFormat, eMultisampleType, IMAGE_TYPE_2D, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
|
||||
else
|
||||
return new CVkImage(x, y, 1, eFormat, eMultisampleType, IMAGE_TYPE_2D, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
|
||||
}
|
||||
|
||||
IImage *CVkRenderContext::CreateStorageImage( uint32_t x, uint32_t y, EImageFormat eFormat, EMultisampleType eMultisampleType )
|
||||
{
|
||||
|
||||
return new CVkImage(x, y, 1, eFormat, eMultisampleType, IMAGE_TYPE_2D, VK_IMAGE_USAGE_STORAGE_BIT);
|
||||
}
|
||||
|
||||
|
||||
@@ -300,49 +397,69 @@ 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);
|
||||
printf("--- general pipeline ---\n");
|
||||
pShader->Build();
|
||||
return pShader;
|
||||
}
|
||||
|
||||
void CVkRenderContext::DestroyShader( IShader *pMaterial )
|
||||
void CVkRenderContext::DestroyShader( IShader *pShader )
|
||||
{
|
||||
|
||||
delete pShader;
|
||||
}
|
||||
|
||||
IMaterial *CVkRenderContext::CreateMaterial( IShader *pShader )
|
||||
{
|
||||
|
||||
return new CVkMaterial(pShader);
|
||||
}
|
||||
|
||||
void CVkRenderContext::DestroyMaterial( IMaterial *pMaterial )
|
||||
{
|
||||
|
||||
delete pMaterial;
|
||||
}
|
||||
void CVkRenderContext::SetMaterial( IMaterial *pMaterial )
|
||||
|
||||
IRenderCommandList *CVkRenderContext::CreateCommandList()
|
||||
{
|
||||
return new CVkRenderCommandList;
|
||||
}
|
||||
|
||||
void CVkRenderContext::DestroyCommandList( IRenderCommandList *pCommandList )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CVkRenderContext::SetVertexBuffer( IVertexBuffer *pBuffer )
|
||||
void CVkRenderContext::SubmitCommandList(IRenderCommandList *pList)
|
||||
{
|
||||
|
||||
CVkRenderCommandList *pVkList = (CVkRenderCommandList*)pList;
|
||||
pVkList->Submit();
|
||||
}
|
||||
|
||||
void CVkRenderContext::SetIndexBuffer( IVertexBuffer *pBuffer )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CVkRenderContext::DrawPrimitives( uint32_t nVertexCount, uint32_t nFirstVertex, uint32_t nInstanceCount, uint32_t nFirstInstance )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CVkRenderContext::DrawPrimitivesIndexed( uint32_t nIndexCount, uint32_t nFirstIndex, uint32_t nVertexOffset, uint32_t nInstanceCount, uint32_t nFirstInstance )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
IVkCommandBuffer *pCommandBuffer;
|
||||
VkPipelineLayout g_pLibraryEmptyLayout;
|
||||
static IVkCommandBuffer *s_pPresentCommandBuffer;
|
||||
void CVkRenderContext::Init()
|
||||
{
|
||||
@@ -436,21 +553,48 @@ void CVkRenderContext::Init()
|
||||
|
||||
VkPhysicalDeviceVulkan13Features vk13Features = {};
|
||||
vk13Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES;
|
||||
vk13Features.synchronization2 = VK_TRUE;
|
||||
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;
|
||||
vk12Features.bufferDeviceAddress = VK_TRUE;
|
||||
|
||||
stDeviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
|
||||
stDeviceCreateInfo.queueCreateInfoCount = 1;
|
||||
stDeviceCreateInfo.pQueueCreateInfos = &stDeviceQueueCreateInfo;
|
||||
stDeviceCreateInfo.enabledExtensionCount = enabledDeviceExtensions.GetSize();
|
||||
stDeviceCreateInfo.ppEnabledExtensionNames = enabledDeviceExtensions.GetData();
|
||||
stDeviceCreateInfo.pNext = &vk13Features;
|
||||
stDeviceCreateInfo.pNext = &vk12Features;
|
||||
r = vkCreateDevice(g_vkPhysicalDevice, &stDeviceCreateInfo, NULL, &g_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);
|
||||
|
||||
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;
|
||||
|
||||
VmaVulkanFunctions vulkanFunctions;
|
||||
vmaImportVulkanFunctionsFromVolk(&stAllocatorInfo, &vulkanFunctions);
|
||||
|
||||
stAllocatorInfo.pVulkanFunctions = &vulkanFunctions;
|
||||
vmaCreateAllocator(&stAllocatorInfo, &g_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);
|
||||
|
||||
CreateSwapchain();
|
||||
|
||||
@@ -468,37 +612,12 @@ void CVkRenderContext::Init()
|
||||
g_pCommandBufferManager = (IVkCommandBufferManager*)CreateInterface(VULKAN_COMMAND_BUFFER_MANAGER_INTERFACE_NAME, NULL);
|
||||
g_pCommandBufferManager->Init();
|
||||
|
||||
pCommandBuffer = g_pCommandBufferManager->CreateCommandBuffer();
|
||||
s_pPresentCommandBuffer = g_pCommandBufferManager->CreateCommandBuffer();
|
||||
|
||||
CVkClearColorCommand *pCommand = (CVkClearColorCommand*)g_pCommandBufferManager->CreateCommand("ClearColor");
|
||||
|
||||
pCommand->pImage = NULL;
|
||||
pCommand->ppSwapchainImages = g_vkSwapchainImages.GetData();
|
||||
pCommand->r = 1;
|
||||
pCommand->b = 1;
|
||||
pCommand->g = 0;
|
||||
pCommand->AddSwapchainDependency( (IRenderingObject**)g_vkSwapchainImages.GetData(), DEPENDENCY_MODE_COLOR_CLEAR_DESTINATION );
|
||||
|
||||
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 = {};
|
||||
|
||||
CVkEmptyCommand *pPresentCommand = (CVkEmptyCommand*)g_pCommandBufferManager->CreateCommand("Empty");
|
||||
pPresentCommand->AddSwapchainDependency( (IRenderingObject**)g_vkSwapchainImages.GetData(), DEPENDENCY_MODE_IMAGE_PRESENT );
|
||||
|
||||
CVkBeginCommand *pBeginCommand = (CVkBeginCommand*)g_pCommandBufferManager->CreateCommand("Empty");
|
||||
pBeginCommand->AddSwapchainDependency((IRenderingObject**)g_vkSwapchainImages.GetData(), DEPENDENCY_MODE_DRAWCALL_OUTPUT_IMAGE);
|
||||
CVkBeginCommand *pEndCommand = (CVkBeginCommand*)g_pCommandBufferManager->CreateCommand("Empty");
|
||||
|
||||
pCommandBuffer->Reset();
|
||||
pCommandBuffer->AddCommand(pCommand);
|
||||
pCommandBuffer->Render();
|
||||
|
||||
s_pPresentCommandBuffer = g_pCommandBufferManager->CreateCommandBuffer();
|
||||
s_pPresentCommandBuffer->Reset();
|
||||
s_pPresentCommandBuffer->AddCommand(pPresentCommand);
|
||||
s_pPresentCommandBuffer->Render();
|
||||
@@ -507,8 +626,7 @@ void CVkRenderContext::Init()
|
||||
void CVkRenderContext::Frame( float fDeltaTime )
|
||||
{
|
||||
vkDeviceWaitIdle(g_vkDevice);
|
||||
pCommandBuffer->Render();
|
||||
s_pPresentCommandBuffer->Render();
|
||||
m_bOutputImageOutdated = false;
|
||||
|
||||
static uint32_t s_nImageIndex = 0;
|
||||
uint32_t nImageIndex = 0;
|
||||
@@ -518,9 +636,7 @@ void CVkRenderContext::Frame( float fDeltaTime )
|
||||
|
||||
vkResetFences(g_vkDevice, 1, &g_vkFences[s_nImageIndex]);
|
||||
|
||||
g_vkCommandBuffers = {};
|
||||
|
||||
pCommandBuffer->Submit(nImageIndex);
|
||||
s_pPresentCommandBuffer->Submit(nImageIndex);
|
||||
|
||||
VkPipelineStageFlags uPipelineStageFlags = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
@@ -550,6 +666,7 @@ void CVkRenderContext::Frame( float fDeltaTime )
|
||||
vkQueuePresentKHR(g_vkPresentQueue, &stPresentInfo);
|
||||
|
||||
s_nImageIndex = (s_nImageIndex + 1) % g_vkSwapchainImages.GetSize();
|
||||
g_vkCommandBuffers = {};
|
||||
}
|
||||
|
||||
void CVkRenderContext::CreateSwapchain()
|
||||
|
||||
@@ -1,3 +1,39 @@
|
||||
#include "vulkan_state.h"
|
||||
void CVkShader::AddShaderLibrary( CVkPipelineLibrary *pLibrary )
|
||||
{
|
||||
m_libraries.AppendTail(pLibrary);
|
||||
}
|
||||
|
||||
void CVkShader::Build()
|
||||
{
|
||||
CUtlVector<VkPipeline> libs = {};
|
||||
VkGraphicsPipelineCreateInfo createInfo = {};
|
||||
VkPipelineLibraryCreateInfoKHR libInfo = {};
|
||||
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
|
||||
for ( auto l: m_libraries )
|
||||
{
|
||||
libs.AppendTail(l->m_hPipeline);
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
// Possibly schedule it?
|
||||
vkCreateGraphicsPipelines(g_vkDevice, NULL, 1, &createInfo, NULL, &m_hPipeline);
|
||||
}
|
||||
|
||||
uint32_t CVkShader::PSGetResourceByName( const char *szName )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
uint32_t CVkShader::VSGetResourceByName( const char *szName )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
#include "shaderparser.h"
|
||||
|
||||
CUtlVector<VulkanDescriptor_t> CVkShaderParser::GetDescriptors( CCompiledShader *pShader, EShaderStage eStage )
|
||||
{
|
||||
CUtlVector<VulkanDescriptor_t> descriptors = {};
|
||||
|
||||
return descriptors;
|
||||
};
|
||||
CUtlBuffer<unsigned char> CVkShaderParser::GetShaderCode( CCompiledShader *pShader, EShaderStage eStage )
|
||||
{
|
||||
for ( auto &o: pShader->m_objects )
|
||||
{
|
||||
if (o.m_eStage != eStage)
|
||||
continue;
|
||||
|
||||
CUtlBuffer<unsigned char> code = CUtlBuffer<unsigned char>(pShader->GetLumpSize(o.m_nDataLump));
|
||||
V_memcpy(code, pShader->GetLumpPtr(o.m_nDataLump), code.GetSize());
|
||||
return code;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
};
|
||||
|
||||
CVkShaderParser *ShaderParser()
|
||||
{
|
||||
static CVkShaderParser s_shaderParser = CVkShaderParser();
|
||||
return &s_shaderParser;
|
||||
};
|
||||
@@ -0,0 +1,17 @@
|
||||
#ifndef VULKAN_SHADER_PARSER_H
|
||||
#define VULKAN_SHADER_PARSER_H
|
||||
|
||||
#include "materialsystem/vulkan_shadermeta.h"
|
||||
#include "materialsystem/compiledshadermgr.h"
|
||||
#include "tier1/utlvector.h"
|
||||
|
||||
class CVkShaderParser
|
||||
{
|
||||
public:
|
||||
CUtlVector<VulkanDescriptor_t> GetDescriptors( CCompiledShader *pShader, EShaderStage eStage );
|
||||
CUtlBuffer<unsigned char> GetShaderCode( CCompiledShader *pShader, EShaderStage eStage );
|
||||
};
|
||||
|
||||
CVkShaderParser *ShaderParser();
|
||||
|
||||
#endif
|
||||
@@ -22,7 +22,7 @@ VkAccessFlags2 VulkanGetAccessFlags( EDependencyMode eMode )
|
||||
case DEPENDENCY_MODE_COLOR_CLEAR_DESTINATION: return VK_ACCESS_2_TRANSFER_WRITE_BIT;
|
||||
case DEPENDENCY_MODE_IMAGE_PRESENT: return VK_ACCESS_2_NONE;
|
||||
default:
|
||||
return 0;
|
||||
return VK_ACCESS_2_MEMORY_READ_BIT | VK_ACCESS_2_MEMORY_WRITE_BIT;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,3 +73,14 @@ VkPrimitiveTopology VulkanGetTopology( ETopologyMode eMode )
|
||||
case TOPOLOGY_MODE_TRIANGLE_STRIP: return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
|
||||
}
|
||||
}
|
||||
VkShaderStageFlagBits VulkanGetShaderStage( EShaderStage eStage )
|
||||
{
|
||||
switch (eStage)
|
||||
{
|
||||
case SHADER_STAGE_VERTEX: return VK_SHADER_STAGE_VERTEX_BIT;
|
||||
case SHADER_STAGE_PIXEL: return VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return VK_SHADER_STAGE_VERTEX_BIT;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
#define VMA_VULKAN_VERSION 1004000
|
||||
#define VMA_IMPLEMENTATION
|
||||
#define VMA_DYNAMIC_VULKAN_FUNCTIONS 0
|
||||
#define VMA_STATIC_VULKAN_FUNCTIONS 0
|
||||
#include "volk.h"
|
||||
#include "vk_mem_alloc.h"
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "tier1/utlvector.h"
|
||||
#include "tier2/iappsystem.h"
|
||||
#include "materialsystem/imaterialsystem.h"
|
||||
#include "materialsystem/shaderinternals.h"
|
||||
#include "vulkan/vulkan_core.h"
|
||||
|
||||
#define REQUIRED_EXTENSION(ext) bool bIsSupported_##ext;
|
||||
@@ -26,6 +27,7 @@ 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;
|
||||
|
||||
@@ -115,7 +117,7 @@ public:
|
||||
virtual void AddCommand( CVkCommand *pCommand ) = 0;
|
||||
|
||||
virtual void Reset() = 0;
|
||||
virtual void Submit( int iFrameIndex ) = 0;
|
||||
virtual void Submit( int iFrameIndex = 0 ) = 0;
|
||||
virtual void Render() = 0;
|
||||
};
|
||||
|
||||
@@ -135,6 +137,8 @@ class CVkCommandRegistry
|
||||
public:
|
||||
CVkCommandRegistry( const char *szName, fnCreateVulkanCommand_t pfnCreate );
|
||||
};
|
||||
#define CREATE_COMMAND(name) \
|
||||
(CVk##name##Command*)g_pCommandBufferManager->CreateCommand(#name)
|
||||
|
||||
#define BEGIN_VULKAN_COMMAND( name ) \
|
||||
class CVk##name##Command : public CVkCommand \
|
||||
@@ -162,7 +166,7 @@ class CVkImage: public IImage
|
||||
{
|
||||
public:
|
||||
CVkImage();
|
||||
CVkImage( uint32_t nWidth, uint32_t nHeight, EImageFormat eFormat, EMultisampleType eMultisampleType );
|
||||
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;
|
||||
@@ -171,7 +175,7 @@ public:
|
||||
virtual EImageFormat GetImageFormat() override;
|
||||
virtual EMultisampleType GetMultisampleType() override;
|
||||
|
||||
void CreateImage( uint32_t nWidth, uint32_t nHeight, EImageFormat eFormat, EMultisampleType eMultisampleType );
|
||||
void CreateImage( uint32_t nWidth, uint32_t nHeight, EImageFormat eFormat, EMultisampleType eMultisampleType, VkImageUsageFlagBits eUsage );
|
||||
void CreateImageView();
|
||||
|
||||
static VkImageViewType GetImageViewType( enum EImageType eImageType );
|
||||
@@ -205,10 +209,10 @@ public:
|
||||
virtual void Unmap() override;
|
||||
virtual uint32_t GetSize() override;
|
||||
|
||||
VmaAllocation allocation;
|
||||
VkBuffer buffer;
|
||||
VkDeviceAddress address;
|
||||
uint32_t nSize;
|
||||
VmaAllocation m_allocation;
|
||||
VkBuffer m_buffer;
|
||||
VkDeviceAddress m_address;
|
||||
uint32_t m_nSize;
|
||||
};
|
||||
|
||||
class CVkPipelineLibrary
|
||||
@@ -228,6 +232,7 @@ public: \
|
||||
#define END_DEFINE_PIPELINE_LIBRARY() \
|
||||
};
|
||||
|
||||
extern VkPipelineLayout g_pLibraryEmptyLayout;
|
||||
#define BEGIN_BUILD_PIPELINE_LIBRARY(name) \
|
||||
void CVk##name##PipelineLibrary::Build() \
|
||||
{ \
|
||||
@@ -236,22 +241,59 @@ void CVk##name##PipelineLibrary::Build() \
|
||||
pipeline.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; \
|
||||
library.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT; \
|
||||
pipeline.pNext = &library; \
|
||||
pipeline.flags = VK_PIPELINE_CREATE_LIBRARY_BIT_KHR; \
|
||||
pipeline.flags = VK_PIPELINE_CREATE_LIBRARY_BIT_KHR | VK_PIPELINE_CREATE_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT; \
|
||||
pipeline.layout = g_pLibraryEmptyLayout;
|
||||
|
||||
#define END_BUILD_PIPELINE_LIBRARY() \
|
||||
vkCreateGraphicsPipelines(g_vkDevice, NULL, 1, &pipeline, NULL, &m_hPipeline); \
|
||||
}
|
||||
|
||||
class CVkShader : IShader
|
||||
class CVkShader : public IShader
|
||||
{
|
||||
public:
|
||||
void AddShaderLibrary( CVkPipelineLibrary *pLibrary );
|
||||
void Build();
|
||||
virtual uint32_t PSGetResourceByName( const char *szName ) override;
|
||||
virtual uint32_t VSGetResourceByName( const char *szName ) override;
|
||||
VkPipeline m_hPipeline = NULL;
|
||||
VkPipelineLayout m_hPipelineLayout;
|
||||
CUtlVector<CVkPipelineLibrary*> m_libraries;
|
||||
};
|
||||
|
||||
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);
|
||||
};
|
||||
|
||||
|
||||
|
||||
enum EVulkanRenderingStage
|
||||
{
|
||||
RENDERING_STAGE_SETUP_RASTER,
|
||||
RENDERING_STAGE_RASTER,
|
||||
RENDERING_STAGE_POST_RASTER,
|
||||
RENDERING_STAGE_FINISHED,
|
||||
};
|
||||
|
||||
struct VulkanMaterialCommandBuffer_t
|
||||
{
|
||||
IMaterial *m_pMaterial;
|
||||
IVkCommandBuffer *m_pCommandBuffer;
|
||||
};
|
||||
|
||||
|
||||
enum EVkFrameObjectType_t
|
||||
{
|
||||
FRAME_OBJECT_TYPE_SINGLE,
|
||||
@@ -267,6 +309,64 @@ struct VkFrameObject_t
|
||||
};
|
||||
};
|
||||
|
||||
struct VulkanRenderOutput_t {
|
||||
VkFrameObject_t m_stImage;
|
||||
VkFrameObject_t m_stResolveImage;
|
||||
|
||||
float m_fClearColor[4];
|
||||
float m_fClearDepth;
|
||||
|
||||
uint32_t m_uIndex;
|
||||
EResolveMode m_eResolveMode;
|
||||
ELoadMode m_eLoadMode;
|
||||
EStoreMode m_eStoreMode;
|
||||
};
|
||||
|
||||
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?
|
||||
virtual void SetScissors( uint32_t uX, uint32_t uY, uint32_t uWidth, uint32_t uHeight ) override;
|
||||
virtual void SetViewport( uint32_t uX, uint32_t uY, uint32_t uWidth, uint32_t uHeight, float fMinDepth, float fMaxDepth ) override;
|
||||
|
||||
virtual void SetMaterial( IMaterial *pMaterial ) override;
|
||||
virtual void SetVertexBuffer( uint32_t uBinding, IVertexBuffer *pBuffer ) override;
|
||||
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();
|
||||
private:
|
||||
void SwitchRenderingStage( EVulkanRenderingStage eStage );
|
||||
|
||||
VulkanRenderOutput_t *FindOrCreateRenderOutput( uint32_t uIndex );
|
||||
IVkCommandBuffer *FindOrCreateMaterialCommandBuffer( IMaterial *pMaterial, bool *pbWasCreated = NULL );
|
||||
|
||||
VulkanRenderOutput_t m_depth;
|
||||
|
||||
CUtlVector<VulkanRenderOutput_t> m_pOutput = {};
|
||||
CUtlSelfReferencingVector<VulkanMaterialCommandBuffer_t> m_materials = {};
|
||||
IVkCommandBuffer *m_pPostRaster;
|
||||
|
||||
IVkCommandBuffer *m_pCurrentMaterialBuffer = NULL;
|
||||
};
|
||||
|
||||
|
||||
IRenderingObject *VulkanGetObject( VkFrameObject_t stObject, int iIndex );
|
||||
|
||||
VkAccessFlags2 VulkanGetAccessFlags( EDependencyMode eMode );
|
||||
@@ -274,4 +374,6 @@ VkPipelineStageFlags2 VulkanGetStageFlags( EDependencyMode eMode );
|
||||
VkImageLayout VulkanGetImageLayout( EDependencyMode eMode );
|
||||
VkFormat VulkanGetVertexFormat( EVertexFormat eFormat );
|
||||
VkPrimitiveTopology VulkanGetTopology( ETopologyMode eMode );
|
||||
VkShaderStageFlagBits VulkanGetShaderStage( EShaderStage eStage );
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
#ifndef SHADER_WRITER_H
|
||||
#define SHADER_WRITER_H
|
||||
|
||||
#include "tier1/interface.h"
|
||||
#include "shadercompiler/icompiler.h"
|
||||
|
||||
|
||||
abstract_class ICompiledShaderManager
|
||||
{
|
||||
public:
|
||||
virtual void WriteToFile( CCompiledShader *pShader, const char *szFile ) = 0;
|
||||
virtual void ReadFromFile( CCompiledShader *pShader, const char *szFile ) = 0;
|
||||
};
|
||||
|
||||
ICompiledShaderManager *CompiledShaderManager();
|
||||
|
||||
#endif
|
||||
@@ -78,18 +78,25 @@ enum ETopologyMode
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Basic rendering object
|
||||
//-----------------------------------------------------------------------------
|
||||
abstract_class IRenderingObject
|
||||
{
|
||||
public:
|
||||
virtual ~IRenderingObject() = 0;
|
||||
virtual void SetDebugName( const char *szName ) = 0;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Buffer object
|
||||
//-----------------------------------------------------------------------------
|
||||
abstract_class IBuffer : public IRenderingObject
|
||||
{
|
||||
public:
|
||||
virtual void Lock() = 0;
|
||||
virtual void Unlock() = 0;
|
||||
virtual void *Map() = 0;
|
||||
virtual void *Map() = 0;
|
||||
virtual void Unmap() = 0;
|
||||
|
||||
virtual uint32_t GetSize() = 0;
|
||||
@@ -98,6 +105,9 @@ virtual void *Map() = 0;
|
||||
typedef IBuffer IVertexBuffer;
|
||||
typedef IBuffer IIndexBuffer;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Image object
|
||||
//-----------------------------------------------------------------------------
|
||||
abstract_class IImage : public IRenderingObject
|
||||
{
|
||||
public:
|
||||
@@ -107,35 +117,83 @@ public:
|
||||
virtual EMultisampleType GetMultisampleType() = 0;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Shader object
|
||||
//-----------------------------------------------------------------------------
|
||||
abstract_class IShader
|
||||
{
|
||||
public:
|
||||
virtual ~IShader() = 0;
|
||||
virtual uint32_t PSGetResourceByName( const char *szName ) = 0;
|
||||
virtual uint32_t VSGetResourceByName( const char *szName ) = 0;
|
||||
};
|
||||
|
||||
|
||||
#define BEGIN_SHADER(name) \
|
||||
class CShader_##name \
|
||||
{
|
||||
|
||||
#define END_SHADER() \
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
abstract_class IMaterial
|
||||
{
|
||||
public:
|
||||
virtual void SetConstants( void *pData ) = 0;
|
||||
|
||||
virtual void SetTexture( const char *szName, IImage *pImage ) = 0;
|
||||
virtual void SetBuffer( const char *szName, IBuffer *pImage ) = 0;
|
||||
virtual ~IMaterial() = 0;
|
||||
virtual void VSSetShaderResource( uint32_t uRegister, IRenderingObject *pResource ) = 0;
|
||||
virtual void PSSetShaderResource( uint32_t uRegister, IRenderingObject *pResource ) = 0;
|
||||
virtual void VSSetConstantsBuffer( uint32_t uRegister, IBuffer *pImage ) = 0;
|
||||
virtual void PSSetConstantsBuffer( uint32_t uRegister, IBuffer *pImage ) = 0;
|
||||
};
|
||||
|
||||
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;
|
||||
virtual void SetViewport( uint32_t uX, uint32_t uY, uint32_t uWidth, uint32_t uHeight, float fMinDepth, float fMaxDepth ) = 0;
|
||||
|
||||
virtual void SetMaterial( IMaterial *pMaterial ) = 0;
|
||||
virtual void SetVertexBuffer( uint32_t uBinding, IVertexBuffer *pBuffer ) = 0;
|
||||
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;
|
||||
virtual void EndRecording() = 0;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Rendering context
|
||||
//
|
||||
// Responsible for the object handling
|
||||
//-----------------------------------------------------------------------------
|
||||
abstract_class IRenderContext: public IAppSystem
|
||||
{
|
||||
public:
|
||||
virtual void Frame( float fTime ) = 0;
|
||||
|
||||
virtual void SetOutputImage( IImage *pImage ) = 0;
|
||||
|
||||
virtual bool BIsOutputImageOutdated() = 0;
|
||||
virtual uint32_t GetNewOutputImageWidth() = 0;
|
||||
virtual uint32_t GetNewOutputImageHeight() = 0;
|
||||
virtual EImageFormat GetNewOutputImageFormat() = 0;
|
||||
|
||||
virtual IVertexBuffer *CreateVertexBuffer( uint32_t nSize ) = 0;
|
||||
virtual IIndexBuffer *CreateIndexBuffer( uint32_t nSize ) = 0;
|
||||
virtual IBuffer *CreateConstantBuffer( uint32_t nSize ) = 0;
|
||||
virtual IBuffer *CreateStorageBuffer( uint32_t nSize ) = 0;
|
||||
virtual IImage *CreateRenderTarget( uint32_t x, uint32_t y, EImageFormat eFormat, EMultisampleType eMultisampleType ) = 0;
|
||||
virtual IImage *CreateStorageImage( uint32_t x, uint32_t y, EImageFormat eFormat, EMultisampleType eMultisampleType ) = 0;
|
||||
|
||||
@@ -148,22 +206,22 @@ public:
|
||||
virtual IMaterial *CreateMaterial( IShader *pShader ) = 0;
|
||||
virtual void DestroyMaterial( IMaterial *pMaterial ) = 0;
|
||||
|
||||
virtual void SetMaterial( IMaterial *pMaterial ) = 0;
|
||||
virtual void SetVertexBuffer( IVertexBuffer *pBuffer ) = 0;
|
||||
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 IRenderCommandList *CreateCommandList() = 0;
|
||||
virtual void DestroyCommandList( IRenderCommandList *pCommandList ) = 0;
|
||||
virtual void SubmitCommandList(IRenderCommandList *pList) = 0;
|
||||
|
||||
};
|
||||
|
||||
#define RENDER_CONTEXT_INTERFACE_NAME "RenderContext001"
|
||||
#define RENDER_CONTEXT_VULKAN_INTERFACE_NAME RENDER_CONTEXT_INTERFACE_NAME
|
||||
|
||||
abstract_class IMaterialSystem: public IAppSystem
|
||||
{
|
||||
public:
|
||||
virtual void Frame( float fTime ) = 0;
|
||||
|
||||
virtual IRenderContext *GetRenderContext( void ) = 0;
|
||||
};
|
||||
|
||||
extern IRenderContext *g_pRenderContext;
|
||||
IMaterialSystem *Materials( void );
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
//================= Copyright kotofyt, All rights reserved ==================//
|
||||
// Purpose: Shader compilers.
|
||||
//
|
||||
// We kinda need to store shader contents in blobs so they can be parsed easily
|
||||
//
|
||||
// For now we store them like this
|
||||
// ShaderHeader_t
|
||||
// ShaderLump_t[m_nNumLump]
|
||||
// ShaderObject_t[m_nNumShaders]
|
||||
// ~An actual shader data~
|
||||
//===========================================================================//
|
||||
|
||||
#ifndef SHADER_INTERNALS_H
|
||||
#define SHADER_INTERNALS_H
|
||||
|
||||
#include "stdint.h"
|
||||
|
||||
enum EShaderBackend: uint32_t
|
||||
{
|
||||
SHADER_BACKEND_SPIRV_VULKAN,
|
||||
SHADER_BACKEND_CODE_METAL,
|
||||
};
|
||||
|
||||
enum EShaderStage: uint32_t
|
||||
{
|
||||
SHADER_STAGE_VERTEX,
|
||||
SHADER_STAGE_TESSELATION_CONTROL,
|
||||
SHADER_STAGE_TESSELATION_EVAL,
|
||||
SHADER_STAGE_GEOMETRY,
|
||||
SHADER_STAGE_PIXEL,
|
||||
|
||||
SHADER_STAGE_COMPUTE,
|
||||
|
||||
SHADER_STAGE_RAYGEN,
|
||||
SHADER_STAGE_ANY_HIT,
|
||||
SHADER_STAGE_CLOSEST_HIT,
|
||||
SHADER_STAGE_MISS,
|
||||
SHADER_STAGE_CALLABLE,
|
||||
|
||||
SHADER_STAGE_TASK,
|
||||
SHADER_STAGE_MESH,
|
||||
|
||||
SHADER_STAGE_COMMON_DATA,
|
||||
|
||||
SHADER_STAGE_MAX,
|
||||
SHADER_STAGE_COUNT = SHADER_STAGE_MAX
|
||||
};
|
||||
|
||||
struct ShaderHeader_t
|
||||
{
|
||||
char m_cSignature[4];
|
||||
uint32_t m_nNumLumps;
|
||||
uint32_t m_nNumShaders;
|
||||
};
|
||||
|
||||
struct ShaderLump_t
|
||||
{
|
||||
uint32_t m_nSize;
|
||||
uint32_t m_nOffset;
|
||||
};
|
||||
|
||||
struct ShaderObject_t
|
||||
{
|
||||
EShaderBackend m_eBackend;
|
||||
EShaderStage m_eStage;
|
||||
uint32_t m_nMetadataLump;
|
||||
uint32_t m_nDataLump;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,20 @@
|
||||
#ifndef VULKAN_METADATA_H
|
||||
#define VULKAN_METADATA_H
|
||||
|
||||
#include "shaderinternals.h"
|
||||
#include "vulkan/vulkan.h"
|
||||
|
||||
struct VulkanDescriptor_t
|
||||
{
|
||||
VkDescriptorType eDescriptorType;
|
||||
uint32_t uBinding;
|
||||
uint32_t uSet;
|
||||
};
|
||||
|
||||
struct VulkanInputMetaData_t
|
||||
{
|
||||
uint32_t nDescriptorsCount;
|
||||
uint32_t pDescriptorSets;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,41 @@
|
||||
#ifndef SHADER_COMPILER_H
|
||||
#define SHADER_COMPILER_H
|
||||
|
||||
#include "tier1/interface.h"
|
||||
#include "tier1/utlvector.h"
|
||||
#include "tier1/utlbuffer.h"
|
||||
#include "tier2/iappsystem.h"
|
||||
#include "materialsystem/shaderinternals.h"
|
||||
|
||||
struct HostShaderLump_t
|
||||
{
|
||||
void *m_pAddress;
|
||||
uint32_t m_nSize;
|
||||
};
|
||||
|
||||
class CCompiledShader
|
||||
{
|
||||
public:
|
||||
CUtlVector<ShaderObject_t> m_objects = {};
|
||||
CUtlVector<HostShaderLump_t> m_lumps = {};
|
||||
|
||||
~CCompiledShader();
|
||||
|
||||
uint32_t AllocateLump( uint32_t nSize );
|
||||
void *GetLumpPtr( uint32_t nLump );
|
||||
uint32_t GetLumpSize( uint32_t nLump );
|
||||
ShaderObject_t *AllocateShader();
|
||||
|
||||
ShaderObject_t *FindShaderObject( EShaderBackend eBackend, EShaderStage eStage );
|
||||
};
|
||||
|
||||
abstract_class IShaderCompiler: public IAppSystem
|
||||
{
|
||||
public:
|
||||
virtual void CompileShader( const char *szInput, CCompiledShader *pShader ) = 0;
|
||||
};
|
||||
|
||||
#define SLANG_SHADER_COMPILER_SPIRV_VULKAN "ShaderCompilerSlangVulkanSpirv"
|
||||
#define SLANG_SHADER_COMPILER_CODE_METAL "ShaderCompilerSlangMetalCode"
|
||||
|
||||
#endif
|
||||
@@ -58,6 +58,9 @@ typedef void( *ListDirCallbackFn )( const char *szPath );
|
||||
PLATFORM_INTERFACE void Plat_ListDirRecursive( const char *szPath, ListDirCallbackFn file, ListDirCallbackFn dir );
|
||||
PLATFORM_INTERFACE void Plat_ListDir( const char *szPath, ListDirCallbackFn file, ListDirCallbackFn dir );
|
||||
PLATFORM_INTERFACE char *Plat_GetExtension( const char *szPath );
|
||||
|
||||
PLATFORM_INTERFACE void Plat_MakeDir( const char *szPath, int iPermissions );
|
||||
|
||||
PLATFORM_INTERFACE void Plat_TrapSignals( void (*pfn)() );
|
||||
PLATFORM_INTERFACE void Plat_Backtrace( void );
|
||||
|
||||
@@ -65,6 +68,24 @@ PLATFORM_INTERFACE void *Plat_LoadLibrary( const char *psz );
|
||||
PLATFORM_INTERFACE void *Plat_GetProc( void *lib, const char *psz );
|
||||
PLATFORM_INTERFACE void Plat_UnloadLibrary( void *psz );
|
||||
|
||||
PLATFORM_INTERFACE void Plat_SetEnv( const char *szVar, const char *psz );
|
||||
PLATFORM_INTERFACE const char *Plat_GetEnv( const char *szVar );
|
||||
|
||||
PLATFORM_INTERFACE void Plat_SetWorkingDir( const char *psz );
|
||||
PLATFORM_INTERFACE const char *Plat_GetWorkingDir( void );
|
||||
|
||||
PLATFORM_INTERFACE const char *Plat_GetExecutablePath( void );
|
||||
PLATFORM_INTERFACE const char *Plat_GetParentDir( const char *psz );
|
||||
|
||||
PLATFORM_INTERFACE const char *Plat_GetUNIXExecutable( const char *psz );
|
||||
PLATFORM_INTERFACE const char *Plat_GetWindowsExecutable( const char *psz );
|
||||
PLATFORM_INTERFACE const char *Plat_GetPlatformExecutable( const char *psz );
|
||||
|
||||
PLATFORM_INTERFACE const char *Plat_GetDarwinSharedLib( const char *psz );
|
||||
PLATFORM_INTERFACE const char *Plat_GetUNIXSharedLib( const char *psz );
|
||||
PLATFORM_INTERFACE const char *Plat_GetWindowsSharedLib( const char *psz );
|
||||
PLATFORM_INTERFACE const char *Plat_GetPlatformSharedLib( const char *psz );
|
||||
|
||||
PLATFORM_INTERFACE double Plat_GetTime( void );
|
||||
PLATFORM_INTERFACE void Plat_Exit( int status );
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
#ifndef APPINIT_H
|
||||
#define APPINIT_H
|
||||
|
||||
|
||||
void AppInitializePath();
|
||||
|
||||
#endif
|
||||
@@ -6,6 +6,8 @@
|
||||
typedef void *( *CreateInterfaceFn )( const char *szName, int *pReturnCode );
|
||||
typedef void *( *InstantiateInterfaceFn )( void );
|
||||
|
||||
CreateInterfaceFn Plat_GetInterfaceFactory( void *lib );
|
||||
|
||||
class CInterfaceRegistry
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -23,6 +23,10 @@ public:
|
||||
void RemoveHead( size_t nCount );
|
||||
void RemoveAt( size_t nPosition, size_t nCount );
|
||||
|
||||
CUtlString GetFileName();
|
||||
CUtlString GetDirectory();
|
||||
CUtlString RemoveHeadFile();
|
||||
|
||||
char *GetString( void );
|
||||
size_t GetLenght( void );
|
||||
operator char*( void );
|
||||
|
||||
@@ -306,6 +306,9 @@ public:
|
||||
void RemoveTail( void );
|
||||
void RemoveAt( size_t nIndex );
|
||||
|
||||
T &GetFirst();
|
||||
T &GetLast();
|
||||
|
||||
size_t GetSize();
|
||||
|
||||
T operator[]( size_t nIndex );
|
||||
@@ -428,4 +431,17 @@ void CUtlSelfReferencingVector<T>::RemoveTail( void )
|
||||
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T &CUtlSelfReferencingVector<T>::GetFirst()
|
||||
{
|
||||
return m_pHead->data;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T &CUtlSelfReferencingVector<T>::GetLast()
|
||||
{
|
||||
return m_pTail->data;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -59,6 +59,10 @@ public:
|
||||
// Some cool stuff
|
||||
virtual CUtlBuffer<unsigned char> Read( IFileHandle *pFile ) = 0;
|
||||
|
||||
// Leaks memory
|
||||
// Should be cleaned by the user
|
||||
virtual const char *ReadString( IFileHandle *pFile ) = 0;
|
||||
|
||||
IFileSystem *m_pNext;
|
||||
|
||||
void RegisterFileSystem();
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
#include "c.h"
|
||||
#include "helper.h"
|
||||
#include "ld.h"
|
||||
#include "target.h"
|
||||
|
||||
CUtlString shadercompiler_lib;
|
||||
CUtlString shadercompiler_exe;
|
||||
DECLARE_BUILD_STAGE(libshadercompiler)
|
||||
{
|
||||
CProject_t stProject;
|
||||
LinkProject_t stLinkProject;
|
||||
CUtlString szOutput;
|
||||
|
||||
stProject.m_szName = "shadercompiler";
|
||||
stProject.m_target = Target_t::HostTarget();
|
||||
stProject.bFPIC = true;
|
||||
stProject.includeDirectories = {
|
||||
"public",
|
||||
"external/slang/include",
|
||||
"external/Vulkan-Headers/include",
|
||||
};
|
||||
stProject.files = {
|
||||
"shadercompiler/slang/vulkan_spirv.cpp",
|
||||
"materialsystem/compiledshader.cpp",
|
||||
};
|
||||
|
||||
stLinkProject = ccompiler->Compile(&stProject);
|
||||
stLinkProject.linkType = ELINK_STATIC_LIBRARY;
|
||||
szOutput = linker->Link(&stLinkProject);
|
||||
shadercompiler_lib = szOutput;
|
||||
|
||||
return 1;
|
||||
}
|
||||
DECLARE_BUILD_STAGE(shadercompiler)
|
||||
{
|
||||
CProject_t stProject;
|
||||
LinkProject_t stLinkProject;
|
||||
CUtlString szOutput;
|
||||
|
||||
stProject.m_szName = "fsc";
|
||||
stProject.m_target = Target_t::HostTarget();
|
||||
stProject.includeDirectories = {"public"};
|
||||
stProject.files = {
|
||||
"shadercompiler/main.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.libraries = {"slang-compiler","slang-glslang-2025.24.2"};
|
||||
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());
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
DECLARE_BUILD_STAGE(compileshaders)
|
||||
{
|
||||
if (CommandLine()->CheckParam("-nofsc"))
|
||||
return 0;
|
||||
|
||||
CUtlVector<CUtlString> args = {"-i", "funnyassets", "-o", "build/funnygame/assets"};
|
||||
|
||||
runner->Run(shadercompiler_exe, args);
|
||||
runner->Wait();
|
||||
return 0;
|
||||
};
|
||||
@@ -0,0 +1,61 @@
|
||||
#include "tier0/lib.h"
|
||||
#include "tier1/commandline.h"
|
||||
#include "tier1/appinit.h"
|
||||
#include "tier1/utlstring.h"
|
||||
#include "tier2/ifilesystem.h"
|
||||
#include "shadercompiler/icompiler.h"
|
||||
#include "materialsystem/compiledshadermgr.h"
|
||||
|
||||
static IShaderCompiler *s_pVulkanSpirvCompiler;
|
||||
static const char *s_szGameRoot;
|
||||
|
||||
void CompileShader( const char *szShader )
|
||||
{
|
||||
CCompiledShader shader;
|
||||
|
||||
if (V_strcmp("shader",Plat_GetExtension(szShader)))
|
||||
return;
|
||||
|
||||
s_pVulkanSpirvCompiler->CompileShader(szShader, &shader);
|
||||
|
||||
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.AppendTail("_c");
|
||||
printf("%s\n",szOutputDirectory.GetString());
|
||||
|
||||
|
||||
CompiledShaderManager()->WriteToFile(&shader, szOutputDirectory);
|
||||
};
|
||||
|
||||
void PrintHelp()
|
||||
{
|
||||
printf("Usage: fsc -i [shader folder] -o [game root]");
|
||||
Plat_Exit(0);
|
||||
}
|
||||
|
||||
int main( int c, char **v )
|
||||
{
|
||||
CUtlString szExePath = Plat_GetExecutablePath();
|
||||
|
||||
CommandLine()->CreateCommandLine(c, v);
|
||||
filesystem->Init();
|
||||
|
||||
s_pVulkanSpirvCompiler = (IShaderCompiler*)CreateInterface(SLANG_SHADER_COMPILER_SPIRV_VULKAN, NULL);
|
||||
s_pVulkanSpirvCompiler->Init();
|
||||
|
||||
const char *szInputDirectory = CommandLine()->ParamValue("-i");
|
||||
if (!szInputDirectory)
|
||||
PrintHelp();
|
||||
s_szGameRoot = szInputDirectory;
|
||||
|
||||
CUtlString szShaderDirectory = CUtlString("%s/shaders\n", szInputDirectory);
|
||||
|
||||
Plat_ListDirRecursive(szInputDirectory, CompileShader, NULL);
|
||||
s_pVulkanSpirvCompiler->Shutdown();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
#include "shadercompiler/icompiler.h"
|
||||
#include "slang.h"
|
||||
#include "tier0/mem.h"
|
||||
#include "tier1/utlstring.h"
|
||||
#include "tier2/ifilesystem.h"
|
||||
#include "vulkan/vulkan.h"
|
||||
|
||||
using namespace slang;
|
||||
|
||||
static IGlobalSession *s_pGlobalSession;
|
||||
static ISession *s_pSession;
|
||||
class CSlangVulkanSpirvShaderCompiler: public IShaderCompiler
|
||||
{
|
||||
public:
|
||||
virtual void Init() override;
|
||||
virtual void Shutdown() override;
|
||||
virtual void CompileShader( const char *szInput, CCompiledShader *pShader ) override;
|
||||
private:
|
||||
IBlob *m_pDiagnostics = NULL;
|
||||
void CheckDiagnostics();
|
||||
|
||||
void CompileShaderStage( EShaderStage eStage, const char *szMain, ISession *pSession, IModule *pModule, CCompiledShader *pShader );
|
||||
};
|
||||
|
||||
EXPOSE_INTERFACE(CSlangVulkanSpirvShaderCompiler, IShaderCompiler, SLANG_SHADER_COMPILER_SPIRV_VULKAN)
|
||||
|
||||
void CSlangVulkanSpirvShaderCompiler::CompileShaderStage( EShaderStage eStage, const char *szMain, ISession *pSession, IModule *pModule, CCompiledShader *pShader )
|
||||
{
|
||||
SlangStage eSlangStage;
|
||||
IEntryPoint *pEntryPoint = NULL;
|
||||
IComponentType *pLinked = NULL;
|
||||
IBlob *pBinary = NULL;
|
||||
ShaderObject_t *pShaderObject = NULL;
|
||||
|
||||
switch (eStage)
|
||||
{
|
||||
case SHADER_STAGE_VERTEX:
|
||||
eSlangStage = SLANG_STAGE_VERTEX;
|
||||
break;
|
||||
case SHADER_STAGE_PIXEL:
|
||||
eSlangStage = SLANG_STAGE_PIXEL;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
pModule->findAndCheckEntryPoint(szMain, eSlangStage, &pEntryPoint, &m_pDiagnostics);
|
||||
CheckDiagnostics();
|
||||
|
||||
pEntryPoint->link(&pLinked, &m_pDiagnostics);
|
||||
CheckDiagnostics();
|
||||
|
||||
pLinked->getEntryPointCode(0, 0, &pBinary, &m_pDiagnostics);
|
||||
CheckDiagnostics();
|
||||
|
||||
pShaderObject = pShader->AllocateShader();
|
||||
pShaderObject->m_eBackend = SHADER_BACKEND_SPIRV_VULKAN;
|
||||
pShaderObject->m_eStage = eStage;
|
||||
pShaderObject->m_nDataLump = pShader->AllocateLump(pBinary->getBufferSize());
|
||||
V_memcpy(pShader->GetLumpPtr(pShaderObject->m_nDataLump), pBinary->getBufferPointer(), pBinary->getBufferSize());
|
||||
|
||||
pEntryPoint->release();
|
||||
}
|
||||
|
||||
void CSlangVulkanSpirvShaderCompiler::CompileShader( const char *szInput, CCompiledShader *pShader )
|
||||
{
|
||||
SessionDesc stSessionDesc = {};
|
||||
TargetDesc stTargetDesc = {};
|
||||
PreprocessorMacroDesc stStageMacroDesc = {};
|
||||
const char *szMainName;
|
||||
IModule *pModule = NULL;
|
||||
ISession *pSession = NULL;
|
||||
IBlob *pShaderSourceBlob = NULL;
|
||||
|
||||
IFileHandle *pFile = filesystem->Open(szInput, FILEMODE_READ);
|
||||
const char *szShaderSource = filesystem->ReadString(pFile);
|
||||
|
||||
int i = 0;
|
||||
|
||||
pShaderSourceBlob = slang_createBlob(szShaderSource, pFile->Size());
|
||||
filesystem->Close(pFile);
|
||||
|
||||
printf(" SLANG %s\n", szInput);
|
||||
|
||||
stSessionDesc.targetCount = 1;
|
||||
stSessionDesc.targets = &stTargetDesc;
|
||||
|
||||
stTargetDesc.format = SLANG_SPIRV;
|
||||
stTargetDesc.profile = s_pGlobalSession->findProfile("spirv_1_6");
|
||||
|
||||
|
||||
for ( i = 0; i<SHADER_STAGE_COUNT; i++ )
|
||||
{
|
||||
szMainName = NULL;
|
||||
switch (i)
|
||||
{
|
||||
case SHADER_STAGE_VERTEX:
|
||||
szMainName = "vsMain";
|
||||
stStageMacroDesc = { "VS_SHADER", "Enabled" };
|
||||
break;
|
||||
case SHADER_STAGE_PIXEL:
|
||||
szMainName = "psMain";
|
||||
stStageMacroDesc = { "PS_SHADER", "Enabled" };
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
stSessionDesc.preprocessorMacroCount = 1;
|
||||
stSessionDesc.preprocessorMacros = &stStageMacroDesc;
|
||||
if ( szMainName == NULL )
|
||||
continue;
|
||||
pSession = NULL;
|
||||
s_pGlobalSession->createSession(stSessionDesc, &pSession);
|
||||
|
||||
pModule = pSession->loadModuleFromSource("main", szInput, pShaderSourceBlob, &m_pDiagnostics);
|
||||
CheckDiagnostics();
|
||||
|
||||
CompileShaderStage((EShaderStage)i, szMainName, pSession, pModule, pShader);
|
||||
pModule->release();
|
||||
pSession->release();
|
||||
}
|
||||
|
||||
V_free((void*)szShaderSource);
|
||||
}
|
||||
void CSlangVulkanSpirvShaderCompiler::CheckDiagnostics()
|
||||
{
|
||||
|
||||
if (m_pDiagnostics)
|
||||
{
|
||||
V_printf("%s\n",(const char*)m_pDiagnostics->getBufferPointer());
|
||||
Plat_Exit(0);
|
||||
}
|
||||
};
|
||||
|
||||
void CSlangVulkanSpirvShaderCompiler::Init()
|
||||
{
|
||||
createGlobalSession(&s_pGlobalSession);
|
||||
}
|
||||
|
||||
void CSlangVulkanSpirvShaderCompiler::Shutdown()
|
||||
{
|
||||
s_pGlobalSession->Release();
|
||||
}
|
||||
|
||||
+14
-10
@@ -15,6 +15,7 @@ DECLARE_BUILD_STAGE(tier0)
|
||||
{
|
||||
CProject_t compileProject = {};
|
||||
LinkProject_t ldProject = {};
|
||||
CUtlString szOutputProject = "";
|
||||
|
||||
compileProject.m_szName = "tier0";
|
||||
compileProject.files = tier0_CompiledFiles;
|
||||
@@ -22,18 +23,21 @@ DECLARE_BUILD_STAGE(tier0)
|
||||
compileProject.bFPIC = true;
|
||||
ldProject = ccompiler->Compile(&compileProject);
|
||||
if (bStaticBuild)
|
||||
ldProject.linkType = ELINK_STATIC_LIBRARY;
|
||||
else
|
||||
ldProject.linkType = ELINK_DYNAMIC_LIBRARY;
|
||||
|
||||
CUtlString outputProject = linker->Link(&ldProject);
|
||||
|
||||
if (!bStaticBuild)
|
||||
{
|
||||
ldProject.linkType = ELINK_STATIC_LIBRARY;
|
||||
szOutputProject = linker->Link(&ldProject);
|
||||
tier0_lib = szOutputProject;
|
||||
}
|
||||
else
|
||||
{
|
||||
ldProject.linkType = ELINK_DYNAMIC_LIBRARY;
|
||||
szOutputProject = linker->Link(&ldProject);
|
||||
filesystem2->MakeDirectory(CUtlString("%s/bin",szOutputDir.GetString()));
|
||||
filesystem2->CopyFile(CUtlString("%s/bin", szOutputDir.GetString()), outputProject);
|
||||
} else {
|
||||
tier0_lib = outputProject;
|
||||
filesystem2->CopyFile(CUtlString("%s/bin", szOutputDir.GetString()), szOutputProject);
|
||||
|
||||
ldProject.linkType = ELINK_STATIC_LIBRARY;
|
||||
szOutputProject = linker->Link(&ldProject);
|
||||
tier0_lib = szOutputProject;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -117,6 +117,10 @@ PLATFORM_INTERFACE char *Plat_GetExtension( const char *szPath )
|
||||
}
|
||||
return last+1;
|
||||
}
|
||||
PLATFORM_INTERFACE void Plat_MakeDir( const char *szPath, int iPermissions )
|
||||
{
|
||||
mkdir(szPath, ACCESSPERMS);
|
||||
}
|
||||
|
||||
PLATFORM_INTERFACE void Plat_Backtrace( void )
|
||||
{
|
||||
@@ -196,6 +200,45 @@ PLATFORM_INTERFACE void *Plat_GetProc( void *lib, const char *psz )
|
||||
return (void*)GetProcAddress((HMODULE)lib, psz);
|
||||
#endif
|
||||
}
|
||||
|
||||
PLATFORM_INTERFACE void Plat_SetEnv( const char *szVar, const char *psz )
|
||||
{
|
||||
setenv(szVar, psz, true);
|
||||
}
|
||||
|
||||
PLATFORM_INTERFACE const char *Plat_GetEnv( const char *szVar )
|
||||
{
|
||||
return getenv(szVar);
|
||||
}
|
||||
|
||||
|
||||
PLATFORM_INTERFACE void Plat_SetWorkingDir( const char *psz )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
PLATFORM_INTERFACE const char *Plat_GetWorkingDir( void )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#ifndef MAX_PATH
|
||||
#define MAX_PATH 4096
|
||||
#endif
|
||||
|
||||
static char s_szExecutablePath[MAX_PATH];
|
||||
#ifdef __linux__
|
||||
static ssize_t s_iExecutablePathSize = readlink("/proc/self/exe", s_szExecutablePath, MAX_PATH);
|
||||
#endif
|
||||
|
||||
PLATFORM_INTERFACE const char *Plat_GetExecutablePath( void )
|
||||
{
|
||||
return s_szExecutablePath;
|
||||
}
|
||||
PLATFORM_INTERFACE const char *Plat_GetParentDir( const char *psz )
|
||||
{
|
||||
}
|
||||
|
||||
PLATFORM_INTERFACE void Plat_UnloadLibrary( void *lib )
|
||||
{
|
||||
#ifdef __linux__
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
CUtlVector<CUtlString> tier1_CompiledFiles = {
|
||||
"tier1/interface.cpp",
|
||||
"tier1/appinit.cpp",
|
||||
"tier1/commandline.cpp",
|
||||
"tier1/utlbuffer.cpp",
|
||||
"tier1/utlmap.cpp",
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
#include "tier1/appinit.h"
|
||||
#include "tier1/utlstring.h"
|
||||
#include "tier0/platform.h"
|
||||
|
||||
void AppInitializePath()
|
||||
{
|
||||
const char *szPath = Plat_GetExecutablePath();
|
||||
CUtlString szEnv = Plat_GetEnv("PATH");
|
||||
printf("%s\n",szEnv.GetString());
|
||||
szEnv.AppendTail(":");
|
||||
szEnv.AppendTail(szPath);
|
||||
Plat_SetEnv("PATH", szEnv);
|
||||
}
|
||||
@@ -27,3 +27,8 @@ void *CreateInterface( const char *szName, int *pReturnCode )
|
||||
*pReturnCode = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
CreateInterfaceFn Plat_GetInterfaceFactory( void *lib )
|
||||
{
|
||||
return (CreateInterfaceFn)Plat_GetProc(lib, "CreateInterface");
|
||||
}
|
||||
|
||||
+69
-2
@@ -62,16 +62,83 @@ void CUtlString::AppendAt( size_t nPosition, const char *psz )
|
||||
|
||||
void CUtlString::RemoveTail( size_t nCount )
|
||||
{
|
||||
|
||||
m_data.RemoveTail(nCount);
|
||||
m_data[m_data.GetSize()-1] = 0;
|
||||
}
|
||||
void CUtlString::RemoveHead( size_t nCount )
|
||||
{
|
||||
|
||||
m_data.RemoveHead(nCount);
|
||||
}
|
||||
void CUtlString::RemoveAt( size_t nPosition, size_t nCount )
|
||||
{
|
||||
|
||||
}
|
||||
CUtlString CUtlString::GetFileName()
|
||||
{
|
||||
CUtlString szFileName = GetString();
|
||||
|
||||
char *pLast = &m_data[GetLenght()-1];
|
||||
while (pLast != m_data.GetData())
|
||||
{
|
||||
if (*pLast=='/')
|
||||
break;
|
||||
pLast--;
|
||||
}
|
||||
|
||||
return pLast;
|
||||
}
|
||||
CUtlString CUtlString::GetDirectory()
|
||||
{
|
||||
if (GetLenght() == 0)
|
||||
return NULL;
|
||||
size_t iNumDeleted = 0;
|
||||
char *pLast = &m_data[GetLenght()-1];
|
||||
CUtlString szDirectory = GetString();
|
||||
while (pLast != m_data.GetData())
|
||||
{
|
||||
if (*pLast=='/')
|
||||
{
|
||||
iNumDeleted++;
|
||||
break;
|
||||
}
|
||||
pLast--;
|
||||
iNumDeleted++;
|
||||
}
|
||||
|
||||
szDirectory.RemoveTail(iNumDeleted);
|
||||
|
||||
return szDirectory;
|
||||
}
|
||||
CUtlString CUtlString::RemoveHeadFile()
|
||||
{
|
||||
size_t iLenght = GetLenght();
|
||||
size_t iNumDeleted = 0;
|
||||
char *pc = GetString();
|
||||
CUtlString szDirectory = pc;
|
||||
|
||||
if (GetLenght() == 0)
|
||||
return NULL;
|
||||
while ( iNumDeleted < iLenght )
|
||||
{
|
||||
if (*pc == '/')
|
||||
goto remove_slashes;
|
||||
pc++;
|
||||
iNumDeleted++;
|
||||
}
|
||||
return NULL;
|
||||
remove_slashes:
|
||||
while ( iNumDeleted < iLenght )
|
||||
{
|
||||
if (*pc != '/')
|
||||
{
|
||||
szDirectory.RemoveHead(iNumDeleted);
|
||||
return szDirectory;
|
||||
}
|
||||
pc++;
|
||||
iNumDeleted++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *CUtlString::GetString( void )
|
||||
{
|
||||
|
||||
@@ -94,6 +94,12 @@ public:
|
||||
|
||||
return buffer;
|
||||
}
|
||||
virtual const char *ReadString( IFileHandle *pFile ) override {
|
||||
char *szString = (char*)V_malloc(Size(pFile)+1);
|
||||
Read(pFile, szString, Size(pFile));
|
||||
szString[Size(pFile)] = 0;
|
||||
return szString;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "tier2/ifilesystem.h"
|
||||
#include "tier1/interface.h"
|
||||
#include "tier0/lib.h"
|
||||
#include "errno.h"
|
||||
|
||||
class CLIBCFileHandle : public IFileHandle
|
||||
{
|
||||
@@ -29,6 +30,9 @@ public:
|
||||
case FILEMODE_READ:
|
||||
szOperation = "rb";
|
||||
break;
|
||||
case FILEMODE_WRITE:
|
||||
szOperation = "wb";
|
||||
break;
|
||||
default:
|
||||
V_printf("Operation is not supported\n");
|
||||
break;
|
||||
@@ -36,7 +40,10 @@ public:
|
||||
|
||||
pFile = V_fopen(szFileName, szOperation);
|
||||
if (!pFile)
|
||||
{
|
||||
Plat_FatalErrorFunc("Failed to open %s: %s\n",strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pHandle = new CLIBCFileHandle;
|
||||
pHandle->m_pFileSystem = this;
|
||||
@@ -48,7 +55,10 @@ public:
|
||||
}
|
||||
virtual size_t Write( IFileHandle *pFile, const void *pData, size_t nDataSize ) override
|
||||
{
|
||||
return 0;
|
||||
CLIBCFileHandle *pHandle = (CLIBCFileHandle*)pFile;
|
||||
if (!pHandle)
|
||||
return 0;
|
||||
return V_fwrite( pData, 1, nDataSize, pHandle->m_pFile);
|
||||
}
|
||||
virtual size_t Read( IFileHandle *pFile, void *pData, size_t nDataSize ) override
|
||||
{
|
||||
@@ -109,6 +119,7 @@ public:
|
||||
}
|
||||
|
||||
virtual CUtlBuffer<unsigned char> Read( IFileHandle *pFile ) override { return NULL; };
|
||||
virtual const char *ReadString( IFileHandle *pFile ) override { return NULL; };
|
||||
};
|
||||
|
||||
EXPOSE_FILESYSTEM(CLIBCFileSystem, "sysfs");
|
||||
|
||||
Reference in New Issue
Block a user