Skip to content

Commit

Permalink
implement vulkan pipeline cache.
Browse files Browse the repository at this point in the history
  • Loading branch information
konstatoivanen committed Jan 28, 2022
1 parent 7c94464 commit eee65af
Show file tree
Hide file tree
Showing 13 changed files with 168 additions and 9 deletions.
2 changes: 2 additions & 0 deletions PKRenderer/PKRenderer.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,7 @@ Call "$(SolutionDir)Build\PKAssetTools.exe" "'$(ProjectDir)res\'" "'$(TargetDir)
<ClInclude Include="src\Utilities\BufferView.h" />
<ClInclude Include="src\Core\CommandConfig.h" />
<ClInclude Include="src\Core\ConsoleCommandBinding.h" />
<ClInclude Include="src\Utilities\FileIO.h" />
<ClInclude Include="src\Utilities\PointerMap.h" />
<ClInclude Include="src\Utilities\FixedList.h" />
<ClInclude Include="src\Utilities\IDObject.h" />
Expand Down Expand Up @@ -942,6 +943,7 @@ Call "$(SolutionDir)Build\PKAssetTools.exe" "'$(ProjectDir)res\'" "'$(TargetDir)
<ClCompile Include="src\Rendering\Passes\PassSceneGI.cpp" />
<ClCompile Include="src\Rendering\VulkanRHI\Objects\VulkanSparsePageTable.cpp" />
<ClCompile Include="src\Rendering\VulkanRHI\Systems\VulkanLayoutCache.cpp" />
<ClCompile Include="src\Utilities\FileIO.cpp" />
<ClCompile Include="src\Utilities\HashHelpers.cpp" />
<ClCompile Include="src\Utilities\PropertyBlock.cpp" />
<ClCompile Include="src\Core\Services\Time.cpp" />
Expand Down
6 changes: 6 additions & 0 deletions PKRenderer/PKRenderer.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -1425,6 +1425,9 @@
<ClInclude Include="src\Rendering\Objects\VirtualMesh.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\Utilities\FileIO.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="include\glm\detail\func_common.inl">
Expand Down Expand Up @@ -2182,6 +2185,9 @@
<ClCompile Include="src\Rendering\Objects\VirtualMesh.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\Utilities\FileIO.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Library Include="libs\glfw3.lib" />
Expand Down
3 changes: 2 additions & 1 deletion PKRenderer/src/Core/Application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ namespace PK::Core
auto time = m_services->Create<Time>(sequencer, config->TimeScale);
auto input = m_services->Create<Input>(sequencer);

m_graphicsDriver = GraphicsDriver::Create(APIType::Vulkan);
auto workingDirectory = std::filesystem::path(arguments.args[0]).remove_filename().string();
m_graphicsDriver = GraphicsDriver::Create(workingDirectory, APIType::Vulkan);

m_window = Window::Create(WindowProperties(name, config->InitialWidth, config->InitialHeight, config->EnableVsync, config->EnableCursor));
Window::SetConsole(config->EnableConsole);
Expand Down
1 change: 1 addition & 0 deletions PKRenderer/src/Core/Services/AssetDatabase.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ namespace PK::Core::Services
AssetID m_assetId = 0;
};

// @TODO decouple these from the actual asset classes
template<typename TParams>
class IAssetImport : public NoCopy
{
Expand Down
1 change: 0 additions & 1 deletion PKRenderer/src/ECS/Contextual/Engines/EngineDebug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ namespace PK::ECS::Engines
auto materialMarble = assetDatabase->Load<Material>("res/materials/M_Marble.material");
auto materialPlaster = assetDatabase->Load<Material>("res/materials/M_Plaster.material");


auto minpos = float3(-70, -6, -70);
auto maxpos = float3(70, -4, 70);

Expand Down
3 changes: 2 additions & 1 deletion PKRenderer/src/Rendering/GraphicsAPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ namespace PK::Rendering

static GraphicsDriver* s_currentDriver;

Scope<GraphicsDriver> GraphicsDriver::Create(APIType api)
Scope<GraphicsDriver> GraphicsDriver::Create(const std::string& workingDirectory, APIType api)
{
switch (api)
{
Expand All @@ -39,6 +39,7 @@ namespace PK::Rendering
auto driver = CreateScope<VulkanDriver>(VulkanContextProperties
(
"PK Vulkan Engine",
workingDirectory,
32ull,
&PK_VALIDATION_LAYERS,
&PK_INSTANCE_EXTENTIONS,
Expand Down
2 changes: 1 addition & 1 deletion PKRenderer/src/Rendering/GraphicsAPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ namespace PK::Rendering
virtual size_t GetBufferOffsetAlignment(BufferUsage usage) const = 0;
virtual void GC() = 0;

static Scope<GraphicsDriver> Create(APIType api);
static Scope<GraphicsDriver> Create(const std::string& workingDirectory, APIType api);
};

namespace GraphicsAPI
Expand Down
37 changes: 35 additions & 2 deletions PKRenderer/src/Rendering/VulkanRHI/Systems/VulkanPipelineCache.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,44 @@
#include "PrecompiledHeader.h"
#include "VulkanPipelineCache.h"
#include "Rendering/VulkanRHI/Utilities/VulkanEnumConversion.h"
#include "Rendering/VulkanRHI/Utilities/VulkanUtilities.h"
#include "Utilities/FileIO.h"

namespace PK::Rendering::VulkanRHI::Systems
{
using namespace PK::Utilities;

VulkanPipelineCache::VulkanPipelineCache(VkDevice device, const std::string& workingDirectory, uint64_t pruneDelay) :
m_device(device),
m_workingDirectory(workingDirectory),
m_pruneDelay(pruneDelay)
{
if (!workingDirectory.empty())
{
void* cacheData = nullptr;
size_t cacheSize = 0ull;
FileIO::ReadBinary((workingDirectory + PIPELINE_CACHE_FILENAME).c_str(), &cacheData, &cacheSize);
VkPipelineCacheCreateInfo cacheCreateInfo{ VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO };
cacheCreateInfo.initialDataSize = cacheSize;
cacheCreateInfo.pInitialData = cacheData;
VK_ASSERT_RESULT_CTX(vkCreatePipelineCache(device, &cacheCreateInfo, nullptr, &m_pipelineCache), "Failed to create pipeline cache!");
free(cacheData);
}
}

VulkanPipelineCache::~VulkanPipelineCache()
{
if (m_pipelineCache != VK_NULL_HANDLE && !m_workingDirectory.empty())
{
size_t size = 0ull;
vkGetPipelineCacheData(m_device, m_pipelineCache, &size, nullptr);
void* cacheData = malloc(size);
vkGetPipelineCacheData(m_device, m_pipelineCache, &size, cacheData);
FileIO::WriteBinary((m_workingDirectory + PIPELINE_CACHE_FILENAME).c_str(), cacheData, size);
vkDestroyPipelineCache(m_device, m_pipelineCache, nullptr);
free(cacheData);
}

for (auto& kv : m_graphicsPipelines)
{
if (kv.second.pipeline != nullptr)
Expand Down Expand Up @@ -50,7 +83,7 @@ namespace PK::Rendering::VulkanRHI::Systems
VkComputePipelineCreateInfo pipelineInfo{ VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO };
pipelineInfo.stage = shader->GetModule((int)ShaderStage::Compute)->stageInfo;
pipelineInfo.layout = shader->GetPipelineLayout()->layout;
auto pipeline = new VulkanPipeline(m_device, VK_NULL_HANDLE, pipelineInfo);
auto pipeline = new VulkanPipeline(m_device, m_pipelineCache, pipelineInfo);
m_computePipelines[shader] = { pipeline, nextPruneTick };
return pipeline;
}
Expand Down Expand Up @@ -189,7 +222,7 @@ namespace PK::Rendering::VulkanRHI::Systems
pipelineInfo.basePipelineHandle = VK_NULL_HANDLE;
pipelineInfo.basePipelineIndex = -1;

auto pipeline = new VulkanPipeline(m_device, VK_NULL_HANDLE, pipelineInfo);
auto pipeline = new VulkanPipeline(m_device, m_pipelineCache, pipelineInfo);
m_graphicsPipelines[key] = { pipeline, nextPruneTick };
return pipeline;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ namespace PK::Rendering::VulkanRHI::Systems
private:

public:
VulkanPipelineCache(VkDevice device, uint64_t pruneDelay) : m_device(device), m_pruneDelay(pruneDelay) {}
constexpr const static char* PIPELINE_CACHE_FILENAME = "shadercache.cache";

VulkanPipelineCache(VkDevice device, const std::string& workingDirectory, uint64_t pruneDelay);
~VulkanPipelineCache();

struct PipelineValue
Expand All @@ -56,6 +58,8 @@ namespace PK::Rendering::VulkanRHI::Systems

private:
const VkDevice m_device;
VkPipelineCache m_pipelineCache = VK_NULL_HANDLE;
std::string m_workingDirectory;
std::unordered_map<PipelineKey, PipelineValue, PipelineKeyHash> m_graphicsPipelines;
std::unordered_map<IDHandle<VulkanShader>, PipelineValue, IDHandle<VulkanShader>::Hash> m_computePipelines;
uint64_t m_currentPruneTick = 0;
Expand Down
2 changes: 1 addition & 1 deletion PKRenderer/src/Rendering/VulkanRHI/VulkanDriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ namespace PK::Rendering::VulkanRHI

frameBufferCache = CreateScope<VulkanFrameBufferCache>(device, properties.garbagePruneDelay);
stagingBufferCache = CreateScope<VulkanStagingBufferCache>(device, allocator, properties.garbagePruneDelay);
pipelineCache = CreateScope<VulkanPipelineCache>(device, properties.garbagePruneDelay);
pipelineCache = CreateScope<VulkanPipelineCache>(device, properties.workingDirectory, properties.garbagePruneDelay);
samplerCache = CreateScope<VulkanSamplerCache>(device);
layoutCache = CreateScope<VulkanLayoutCache>(device);
disposer = CreateScope<VulkanDisposer>();
Expand Down
6 changes: 5 additions & 1 deletion PKRenderer/src/Rendering/VulkanRHI/VulkanDriver.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,21 @@ namespace PK::Rendering::VulkanRHI
struct VulkanContextProperties
{
std::string appName;
std::string workingDirectory;
uint64_t garbagePruneDelay;
const std::vector<const char*>* validationLayers;
const std::vector<const char*>* contextualInstanceExtensions;
const std::vector<const char*>* contextualDeviceExtensions;

VulkanContextProperties(const std::string& appName = "Vulkan Engine",
VulkanContextProperties(
const std::string& appName = "Vulkan Engine",
const std::string& workingDirectory = "",
uint64_t garbagePruneDelay = 32ull,
const std::vector<const char*>* validationLayers = nullptr,
const std::vector<const char*>* contextualInstanceExtensions = nullptr,
const std::vector<const char*>* contextualDeviceExtensions = nullptr) :
appName(appName),
workingDirectory(workingDirectory),
garbagePruneDelay(garbagePruneDelay),
validationLayers(validationLayers),
contextualInstanceExtensions(contextualInstanceExtensions),
Expand Down
100 changes: 100 additions & 0 deletions PKRenderer/src/Utilities/FileIO.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
#include "PrecompiledHeader.h"
#include "FileIO.h"
#include <filesystem>

namespace PK::Utilities::FileIO
{
int ReadBinary(const char* filepath, void** data, size_t* size)
{
if (strlen(filepath) == 0)
{
return -1;
}

auto cachepath = std::filesystem::path(std::string(filepath));

if (!std::filesystem::exists(cachepath))
{
return -1;
}

FILE* file = nullptr;

#if _WIN32
auto error = fopen_s(&file, cachepath.string().c_str(), "rb");

if (error != 0)
{
return -1;
}
#else
file = fopen(filepath, "rb");
#endif

if (file == nullptr)
{
return -1;
}

fseek(file, 0, SEEK_END);
*size = ftell(file);
rewind(file);

if (*size == 0)
{
fclose(file);
return -1;
}

*data = malloc(*size);

if (*data == nullptr)
{
fclose(file);
return -1;
}

fread(*data, sizeof(char), *size, file);
fclose(file);
return 0;
}

int WriteBinary(const char* filepath, void* data, size_t size)
{
FILE* file = nullptr;

auto path = std::filesystem::path(filepath).remove_filename().string();
path = path.substr(0, path.length() - 1);

if (!std::filesystem::exists(path))
{
try
{
std::filesystem::create_directories(path);
}
catch (std::exception& e)
{
printf(e.what());
}
}

#if _WIN32
auto error = fopen_s(&file, filepath, "wb");

if (error != 0)
{
return -1;
}
#else
file = fopen(filepath, "wb");
#endif

if (file == nullptr)
{
return -1;
}

fwrite(data, sizeof(char), size, file);
return fclose(file);
}
}
8 changes: 8 additions & 0 deletions PKRenderer/src/Utilities/FileIO.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#pragma once
#include <stdio.h>

namespace PK::Utilities::FileIO
{
int ReadBinary(const char* filepath, void** data, size_t* size);
int WriteBinary(const char* filepath, void* data, size_t size);
}

0 comments on commit eee65af

Please sign in to comment.