Added Pipeline Caching.
This commit is contained in:
parent
f9517db592
commit
22cbc41af1
|
|
@ -20,7 +20,7 @@ set(HEADER_FILES
|
||||||
physical_device.h
|
physical_device.h
|
||||||
device.h
|
device.h
|
||||||
swapchain.h
|
swapchain.h
|
||||||
"pipeline.h"
|
pipeline.h
|
||||||
queue_allocation.h
|
queue_allocation.h
|
||||||
buffer.h)
|
buffer.h)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,13 @@ constexpr eastl::array DEVICE_EXTENSIONS = {
|
||||||
|
|
||||||
Device::Device(const Context *context, PhysicalDevice *physicalDevice, Features *enabledFeatures,
|
Device::Device(const Context *context, PhysicalDevice *physicalDevice, Features *enabledFeatures,
|
||||||
const eastl::vector<QueueAllocation> &queueAllocations, NameString &&name)
|
const eastl::vector<QueueAllocation> &queueAllocations, NameString &&name)
|
||||||
|
: Device(context, physicalDevice, enabledFeatures, queueAllocations, {}, std::move(name))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Device::Device(const Context *context, PhysicalDevice *physicalDevice, Features *enabledFeatures,
|
||||||
|
const eastl::vector<QueueAllocation> &queueAllocations, eastl::span<u8> &&pipelineCacheData,
|
||||||
|
NameString &&name)
|
||||||
: m_Name(std::move(name))
|
: m_Name(std::move(name))
|
||||||
, m_PhysicalDevice(physicalDevice->m_PhysicalDevice)
|
, m_PhysicalDevice(physicalDevice->m_PhysicalDevice)
|
||||||
{
|
{
|
||||||
|
|
@ -86,11 +93,22 @@ Device::Device(const Context *context, PhysicalDevice *physicalDevice, Features
|
||||||
THEN_ABORT(result)
|
THEN_ABORT(result)
|
||||||
ELSE_VERBOSE("Memory Allocator Created");
|
ELSE_VERBOSE("Memory Allocator Created");
|
||||||
|
|
||||||
DEBUG("Created '{}' Successfully", m_Name);
|
vk::PipelineCacheCreateInfo pipelineCacheCreateInfo = {
|
||||||
|
.initialDataSize = pipelineCacheData.size_bytes(),
|
||||||
|
.pInitialData = pipelineCacheData.data(),
|
||||||
|
};
|
||||||
|
result = m_Device.createPipelineCache(&pipelineCacheCreateInfo, nullptr, &m_PipelineCache);
|
||||||
|
ERROR_IF(Failed(result), "Pipeline Cache creation failed. Cause: {}", result)
|
||||||
|
DO(m_Device.destroy(nullptr))
|
||||||
|
THEN_ABORT(result)
|
||||||
|
ELSE_VERBOSE("Pipeline Cache created.");
|
||||||
|
|
||||||
|
DEBUG("Created Device '{}' Successfully", m_Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
Device::~Device()
|
Device::~Device()
|
||||||
{
|
{
|
||||||
|
m_Device.destroy(m_PipelineCache, nullptr);
|
||||||
if (m_Allocator)
|
if (m_Allocator)
|
||||||
{
|
{
|
||||||
vmaDestroyAllocator(m_Allocator);
|
vmaDestroyAllocator(m_Allocator);
|
||||||
|
|
@ -110,6 +128,19 @@ Device::GetQueue(const u32 familyIndex, const u32 queueIndex) const
|
||||||
return queue;
|
return queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
eastl::vector<u8>
|
||||||
|
Device::DumpPipelineCache() const
|
||||||
|
{
|
||||||
|
usize pipelineCacheSize = 0;
|
||||||
|
vk::Result result = m_Device.getPipelineCacheData(m_PipelineCache, &pipelineCacheSize, nullptr);
|
||||||
|
ERROR_IF(Failed(result), "Pipeline Cache data fetch failed. Cause: {}", result);
|
||||||
|
eastl::vector<u8> pipelineCacheData(pipelineCacheSize);
|
||||||
|
result = m_Device.getPipelineCacheData(m_PipelineCache, &pipelineCacheSize, pipelineCacheData.data());
|
||||||
|
ERROR_IF(Failed(result), "Pipeline Cache data fetch failed. Cause: {}", result);
|
||||||
|
|
||||||
|
return pipelineCacheData;
|
||||||
|
}
|
||||||
|
|
||||||
Device::Device(Device &&other) noexcept
|
Device::Device(Device &&other) noexcept
|
||||||
: m_Name(std::move(other.m_Name))
|
: m_Name(std::move(other.m_Name))
|
||||||
, m_PhysicalDevice(Take(other.m_PhysicalDevice))
|
, m_PhysicalDevice(Take(other.m_PhysicalDevice))
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
|
|
||||||
#include <EASTL/vector.h>
|
#include <EASTL/vector.h>
|
||||||
|
#include <EASTL/span.h>
|
||||||
|
|
||||||
struct QueueAllocation;
|
struct QueueAllocation;
|
||||||
struct Context;
|
struct Context;
|
||||||
|
|
@ -27,14 +28,19 @@ struct Device final
|
||||||
vk::PhysicalDevice m_PhysicalDevice = nullptr;
|
vk::PhysicalDevice m_PhysicalDevice = nullptr;
|
||||||
vk::Device m_Device = nullptr;
|
vk::Device m_Device = nullptr;
|
||||||
VmaAllocator m_Allocator = nullptr;
|
VmaAllocator m_Allocator = nullptr;
|
||||||
|
vk::PipelineCache m_PipelineCache = nullptr;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
requires vk::isVulkanHandleType<T>::value void SetName(const T &object, cstr name) const;
|
requires vk::isVulkanHandleType<T>::value void SetName(const T &object, cstr name) const;
|
||||||
[[nodiscard]] vk::Queue GetQueue(u32 familyIndex, u32 queueIndex) const;
|
[[nodiscard]] vk::Queue GetQueue(u32 familyIndex, u32 queueIndex) const;
|
||||||
|
|
||||||
|
[[nodiscard]] eastl::vector<u8> DumpPipelineCache() const;
|
||||||
|
|
||||||
// Ctor/Dtor
|
// Ctor/Dtor
|
||||||
Device(const Context *context, PhysicalDevice *physicalDevice, Features *enabledFeatures,
|
Device(const Context *context, PhysicalDevice *physicalDevice, Features *enabledFeatures,
|
||||||
const eastl::vector<QueueAllocation> &queueAllocations, NameString &&name);
|
const eastl::vector<QueueAllocation> &queueAllocations, NameString &&name);
|
||||||
|
Device(const Context *context, PhysicalDevice *physicalDevice, Features *enabledFeatures,
|
||||||
|
const eastl::vector<QueueAllocation> &queueAllocations, eastl::span<u8> &&pipelineCacheData, NameString &&name);
|
||||||
~Device();
|
~Device();
|
||||||
|
|
||||||
// Move
|
// Move
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,54 @@ ReadFile(cstr fileName)
|
||||||
outputVec.resize(nextSize);
|
outputVec.resize(nextSize);
|
||||||
memcpy(outputVec.data() + totalRead, buffer.data(), readCount * sizeof *buffer.data());
|
memcpy(outputVec.data() + totalRead, buffer.data(), readCount * sizeof *buffer.data());
|
||||||
totalRead = nextSize;
|
totalRead = nextSize;
|
||||||
} while (readCount == 1024);
|
} while (readCount == buffer.size());
|
||||||
|
|
||||||
return outputVec;
|
return outputVec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
eastl::vector<u8>
|
||||||
|
ReadFileBytes(cstr fileName, bool errorOnFail)
|
||||||
|
{
|
||||||
|
FILE *filePtr = fopen(fileName, "rb");
|
||||||
|
|
||||||
|
if (!filePtr)
|
||||||
|
{
|
||||||
|
ERROR_IF(errorOnFail, "Invalid open (r) of {}. Cause: {}", fileName, errno);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
eastl::vector<u8> outputVec;
|
||||||
|
eastl::array<u8, 4096> buffer{};
|
||||||
|
usize totalRead = 0;
|
||||||
|
usize readCount;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
readCount = fread(buffer.data(), sizeof(u8), buffer.size(), filePtr);
|
||||||
|
const auto nextSize = totalRead + readCount;
|
||||||
|
outputVec.resize(nextSize);
|
||||||
|
memcpy(outputVec.data() + totalRead, buffer.data(), readCount * sizeof *buffer.data());
|
||||||
|
totalRead = nextSize;
|
||||||
|
} while (readCount == buffer.size());
|
||||||
|
|
||||||
|
(void)fclose(filePtr);
|
||||||
|
|
||||||
|
return outputVec;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
WriteFileBytes(cstr fileName, eastl::span<u8> data)
|
||||||
|
{
|
||||||
|
FILE *filePtr = fopen(fileName, "wb");
|
||||||
|
|
||||||
|
if (!filePtr)
|
||||||
|
{
|
||||||
|
ERROR("Invalid open (w) of {}. Cause: {}", fileName, errno);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const usize written = fwrite(data.data(), sizeof(u8), data.size(), filePtr);
|
||||||
|
|
||||||
|
(void)fclose(filePtr);
|
||||||
|
|
||||||
|
return written == data.size();
|
||||||
|
}
|
||||||
|
|
@ -8,6 +8,8 @@
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
|
|
||||||
#include "queue_allocation.h"
|
#include "queue_allocation.h"
|
||||||
|
|
||||||
|
#include "EASTL/span.h"
|
||||||
#include <EASTL/vector.h>
|
#include <EASTL/vector.h>
|
||||||
#include <glm/gtc/matrix_transform.hpp>
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
|
||||||
|
|
@ -17,6 +19,8 @@ class PhysicalDevices;
|
||||||
PhysicalDevice FindSuitableDevice(const PhysicalDevices &physicalDevices);
|
PhysicalDevice FindSuitableDevice(const PhysicalDevices &physicalDevices);
|
||||||
QueueAllocation FindAppropriateQueueAllocation(const PhysicalDevice *physicalDevice);
|
QueueAllocation FindAppropriateQueueAllocation(const PhysicalDevice *physicalDevice);
|
||||||
eastl::vector<u32> ReadFile(cstr fileName);
|
eastl::vector<u32> ReadFile(cstr fileName);
|
||||||
|
eastl::vector<u8> ReadFileBytes(cstr fileName, bool errorOnFail = true);
|
||||||
|
bool WriteFileBytes(cstr fileName, eastl::span<u8> data);
|
||||||
|
|
||||||
#define AbortIfFailed(RESULT) \
|
#define AbortIfFailed(RESULT) \
|
||||||
do \
|
do \
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
|
||||||
constexpr u32 MAX_FRAMES_IN_FLIGHT = 3;
|
constexpr u32 MAX_FRAMES_IN_FLIGHT = 3;
|
||||||
constexpr auto MODEL_FILE = "model/DamagedHelmet.glb";
|
constexpr auto PIPELINE_CACHE_FILE = "PipelineCacheData.bin";
|
||||||
|
|
||||||
struct Camera
|
struct Camera
|
||||||
{
|
{
|
||||||
|
|
@ -127,8 +127,10 @@ main(int, char **)
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
auto pipelineCacheData = ReadFileBytes(PIPELINE_CACHE_FILE, false);
|
||||||
|
|
||||||
QueueAllocation queueAllocation = FindAppropriateQueueAllocation(&deviceToUse);
|
QueueAllocation queueAllocation = FindAppropriateQueueAllocation(&deviceToUse);
|
||||||
Device device = {&context, &deviceToUse, &enabledDeviceFeatures, {queueAllocation}, "Primary Device"};
|
Device device = {&context, &deviceToUse, &enabledDeviceFeatures, {queueAllocation}, pipelineCacheData, "Primary Device"};
|
||||||
vk::Queue commandQueue = device.GetQueue(queueAllocation.m_Family, 0);
|
vk::Queue commandQueue = device.GetQueue(queueAllocation.m_Family, 0);
|
||||||
Swapchain swapchain = {&window, &device, "Primary Chain"};
|
Swapchain swapchain = {&window, &device, "Primary Chain"};
|
||||||
GpuResourceManager resourceManager = {&device, 1000};
|
GpuResourceManager resourceManager = {&device, 1000};
|
||||||
|
|
@ -568,6 +570,9 @@ main(int, char **)
|
||||||
|
|
||||||
AbortIfFailed(device.m_Device.waitIdle());
|
AbortIfFailed(device.m_Device.waitIdle());
|
||||||
|
|
||||||
|
pipelineCacheData = device.DumpPipelineCache();
|
||||||
|
ERROR_IF(!WriteFileBytes(PIPELINE_CACHE_FILE, pipelineCacheData), "Pipeline Cache incorrectly written");
|
||||||
|
|
||||||
gui::Destroy(&device);
|
gui::Destroy(&device);
|
||||||
|
|
||||||
for (auto &depthImage : depthImages)
|
for (auto &depthImage : depthImages)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue