working on rendering
This commit is contained in:
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -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
external/linux/libgfx.so
vendored
Executable file
BIN
external/linux/libgfx.so
vendored
Executable file
Binary file not shown.
BIN
external/linux/libgfx.so.0.2025.24.2
vendored
Normal file
BIN
external/linux/libgfx.so.0.2025.24.2
vendored
Normal file
Binary file not shown.
BIN
external/linux/libslang-compiler.so
vendored
Executable file
BIN
external/linux/libslang-compiler.so
vendored
Executable file
Binary file not shown.
BIN
external/linux/libslang-compiler.so.0.2025.24.2
vendored
Normal file
BIN
external/linux/libslang-compiler.so.0.2025.24.2
vendored
Normal file
Binary file not shown.
BIN
external/linux/libslang-glsl-module-2025.24.2.so
vendored
Normal file
BIN
external/linux/libslang-glsl-module-2025.24.2.so
vendored
Normal file
Binary file not shown.
BIN
external/linux/libslang-glslang-2025.24.2.so
vendored
Normal file
BIN
external/linux/libslang-glslang-2025.24.2.so
vendored
Normal file
Binary file not shown.
BIN
external/linux/libslang-llvm.so
vendored
Normal file
BIN
external/linux/libslang-llvm.so
vendored
Normal file
Binary file not shown.
BIN
external/linux/libslang-rt.so
vendored
Executable file
BIN
external/linux/libslang-rt.so
vendored
Executable file
Binary file not shown.
BIN
external/linux/libslang-rt.so.0.2025.24.2
vendored
Normal file
BIN
external/linux/libslang-rt.so.0.2025.24.2
vendored
Normal file
Binary file not shown.
BIN
external/linux/libslang.so
vendored
Executable file
BIN
external/linux/libslang.so
vendored
Executable file
Binary file not shown.
1
external/slang
vendored
Submodule
1
external/slang
vendored
Submodule
Submodule external/slang added at 5d775e2829
BIN
fpc/fpc_temp
BIN
fpc/fpc_temp
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)
|
||||
|
||||
48
funnyassets/shaders/flat.shader
Normal file
48
funnyassets/shaders/flat.shader
Normal file
@@ -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);
|
||||
}
|
||||
}
|
||||
2
funnyassets/shaders/flat.shadermeta
Normal file
2
funnyassets/shaders/flat.shadermeta
Normal file
@@ -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",
|
||||
|
||||
145
materialsystem/compiledshader.cpp
Normal file
145
materialsystem/compiledshader.cpp
Normal file
@@ -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()
|
||||
|
||||
193
materialsystem/vulkan/rendercommandlist.cpp
Normal file
193
materialsystem/vulkan/rendercommandlist.cpp
Normal file
@@ -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 )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
28
materialsystem/vulkan/shaderparser.cpp
Normal file
28
materialsystem/vulkan/shaderparser.cpp
Normal file
@@ -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;
|
||||
};
|
||||
17
materialsystem/vulkan/shaderparser.h
Normal file
17
materialsystem/vulkan/shaderparser.h
Normal file
@@ -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;
|
||||
}
|
||||
|
||||
6
materialsystem/vulkan/vma.cpp
Normal file
6
materialsystem/vulkan/vma.cpp
Normal file
@@ -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
|
||||
|
||||
17
public/materialsystem/compiledshadermgr.h
Normal file
17
public/materialsystem/compiledshadermgr.h
Normal file
@@ -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
|
||||
|
||||
70
public/materialsystem/shaderinternals.h
Normal file
70
public/materialsystem/shaderinternals.h
Normal file
@@ -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
|
||||
20
public/materialsystem/vulkan_shadermeta.h
Normal file
20
public/materialsystem/vulkan_shadermeta.h
Normal file
@@ -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
|
||||
41
public/shadercompiler/icompiler.h
Normal file
41
public/shadercompiler/icompiler.h
Normal file
@@ -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 );
|
||||
|
||||
|
||||
7
public/tier1/appinit.h
Normal file
7
public/tier1/appinit.h
Normal file
@@ -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();
|
||||
|
||||
75
shadercompiler/__build.cpp
Normal file
75
shadercompiler/__build.cpp
Normal file
@@ -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;
|
||||
};
|
||||
61
shadercompiler/main.cpp
Normal file
61
shadercompiler/main.cpp
Normal file
@@ -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
shadercompiler/slang/metal_code.cpp
Normal file
0
shadercompiler/slang/metal_code.cpp
Normal file
144
shadercompiler/slang/vulkan_spirv.cpp
Normal file
144
shadercompiler/slang/vulkan_spirv.cpp
Normal file
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
|
||||
13
tier1/appinit.cpp
Normal file
13
tier1/appinit.cpp
Normal file
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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