Skip to content
Snippets Groups Projects
Verified Commit 5d9f0972 authored by Tobias Frisch's avatar Tobias Frisch
Browse files

[#49] Changed handles to be class with restricted access and convenient operators

parent b69b166b
No related branches found
No related tags found
1 merge request!38Resolve "Consistent handles"
Pipeline #25229 passed
......@@ -5,13 +5,63 @@
* @brief Central header file for all possible handles that the framework will hand out.
*/
#include <cstdint>
#include <iostream>
namespace vkcv
{
class Handle {
friend std::ostream& operator << (std::ostream& out, const Handle& handle);
private:
uint64_t m_id;
protected:
Handle();
explicit Handle(uint64_t id);
[[nodiscard]]
uint64_t getId() const;
public:
virtual ~Handle() = default;
Handle(const Handle& other) = default;
Handle(Handle&& other) = default;
Handle& operator=(const Handle& other) = default;
Handle& operator=(Handle&& other) = default;
explicit operator bool() const;
bool operator!() const;
};
std::ostream& operator << (std::ostream& out, const Handle& handle);
// Handle returned for any buffer created with the core/context objects
struct BufferHandle {uint64_t id;};
struct PassHandle {uint64_t id;};
struct PipelineHandle {uint64_t id;};
struct ResourcesHandle {uint64_t id;};
class BufferHandle : public Handle {
friend class BufferManager;
private:
using Handle::Handle;
};
class PassHandle : public Handle {
friend class PassManager;
private:
using Handle::Handle;
};
class PipelineHandle : public Handle {
friend class PipelineManager;
private:
using Handle::Handle;
};
class ResourcesHandle : public Handle {
friend class DescriptorManager;
private:
using Handle::Handle;
};
}
......@@ -78,7 +78,7 @@ int main(int argc, const char** argv) {
vkcv::PassConfig trianglePassDefinition({present_color_attachment});
vkcv::PassHandle trianglePass = core.createPass(trianglePassDefinition);
if (trianglePass.id == 0)
if (!trianglePass)
{
std::cout << "Error. Could not create renderpass. Exiting." << std::endl;
return EXIT_FAILURE;
......@@ -90,7 +90,8 @@ int main(int argc, const char** argv) {
const vkcv::PipelineConfig trianglePipelineDefinition(triangleShaderProgram, windowWidth, windowHeight, trianglePass);
vkcv::PipelineHandle trianglePipeline = core.createGraphicsPipeline(trianglePipelineDefinition);
if (trianglePipeline.id == 0)
if (!trianglePipeline)
{
std::cout << "Error. Could not create graphics pipeline. Exiting." << std::endl;
return EXIT_FAILURE;
......@@ -111,7 +112,7 @@ int main(int argc, const char** argv) {
sets.push_back(set);
auto resourceHandle = core.createResourceDescription(sets);
std::cout << "Resource " << resourceHandle.id << " created." << std::endl;
std::cout << "Resource " << resourceHandle << " created." << std::endl;
}
/*
......
......@@ -9,7 +9,7 @@
namespace vkcv {
BufferManager::BufferManager() noexcept :
m_core(nullptr), m_buffers(), m_stagingBuffer(BufferHandle{ UINT64_MAX })
m_core(nullptr), m_buffers(), m_stagingBuffer(BufferHandle())
{
}
......@@ -22,8 +22,8 @@ namespace vkcv {
}
BufferManager::~BufferManager() noexcept {
for (size_t id = 0; id < m_buffers.size(); id++) {
destroyBuffer(BufferHandle{ id });
for (uint64_t id = 0; id < m_buffers.size(); id++) {
destroyBuffer(BufferHandle(id));
}
}
......@@ -179,7 +179,7 @@ namespace vkcv {
}
vk::Buffer BufferManager::getBuffer(const BufferHandle& handle) const {
const uint64_t id = handle.id;
const uint64_t id = handle.getId();
if (id >= m_buffers.size()) {
return nullptr;
......@@ -191,7 +191,7 @@ namespace vkcv {
}
vk::DeviceMemory BufferManager::getDeviceMemory(const BufferHandle& handle) const {
const uint64_t id = handle.id;
const uint64_t id = handle.getId();
if (id >= m_buffers.size()) {
return nullptr;
......@@ -203,7 +203,7 @@ namespace vkcv {
}
void BufferManager::fillBuffer(const BufferHandle& handle, void *data, size_t size, size_t offset) {
const uint64_t id = handle.id;
const uint64_t id = handle.getId();
if (size == 0) {
size = SIZE_MAX;
......@@ -232,7 +232,7 @@ namespace vkcv {
memcpy(mapped, data, max_size);
device.unmapMemory(buffer.m_memory);
} else {
auto& stagingBuffer = m_buffers[ m_stagingBuffer.id ];
auto& stagingBuffer = m_buffers[ m_stagingBuffer.getId() ];
StagingStepInfo info;
info.data = data;
......@@ -253,7 +253,7 @@ namespace vkcv {
}
void* BufferManager::mapBuffer(const BufferHandle& handle, size_t offset, size_t size) {
const uint64_t id = handle.id;
const uint64_t id = handle.getId();
if (size == 0) {
size = SIZE_MAX;
......@@ -281,7 +281,7 @@ namespace vkcv {
}
void BufferManager::unmapBuffer(const BufferHandle& handle) {
const uint64_t id = handle.id;
const uint64_t id = handle.getId();
if (id >= m_buffers.size()) {
return;
......@@ -300,7 +300,7 @@ namespace vkcv {
}
void BufferManager::destroyBuffer(const BufferHandle& handle) {
const uint64_t id = handle.id;
const uint64_t id = handle.getId();
if (id >= m_buffers.size()) {
return;
......
......@@ -8,7 +8,7 @@ namespace vkcv
descriptorSetLayouts{std::move(layouts)}
{}
DescriptorManager::DescriptorManager(vk::Device device) noexcept:
m_Device{ device }, m_NextResourceDescriptionID{ 1 }
m_Device{ device }, m_NextResourceDescriptionID{ 0 }
{
/**
* Allocate a set size for the initial pool, namely 1000 units of each descriptor type below.
......@@ -64,7 +64,7 @@ namespace vkcv
if(m_Device.createDescriptorSetLayout(&layoutInfo, nullptr, &layout) != vk::Result::eSuccess)
{
std::cout << "FAILED TO CREATE DESCRIPTOR SET LAYOUT" << std::endl;
return ResourcesHandle{0};
return ResourcesHandle();
};
vk_setLayouts.push_back(layout);
}
......@@ -79,11 +79,11 @@ namespace vkcv
for(const auto &layout : vk_setLayouts)
m_Device.destroy(layout);
return ResourcesHandle{0};
return ResourcesHandle();
};
m_ResourceDescriptions.emplace_back(vk_sets, vk_setLayouts);
return ResourcesHandle{m_NextResourceDescriptionID++};
return ResourcesHandle(m_NextResourceDescriptionID++);
}
vk::DescriptorType DescriptorManager::convertDescriptorTypeFlag(DescriptorType type) {
......
#include "vkcv/Handles.hpp"
namespace vkcv {
Handle::Handle() :
m_id(UINT64_MAX)
{}
Handle::Handle(uint64_t id) :
m_id(id)
{}
uint64_t Handle::getId() const {
return m_id;
}
Handle::operator bool() const {
return (m_id < UINT64_MAX);
}
bool Handle::operator!() const {
return (m_id == UINT64_MAX);
}
std::ostream& operator << (std::ostream& out, const Handle& handle) {
if (handle) {
return out << "[Handle: " << handle.getId() << "]";
} else {
return out << "[Handle: none]";
}
}
}
......@@ -50,7 +50,7 @@ namespace vkcv
PassManager::PassManager(vk::Device device) noexcept :
m_Device{device},
m_RenderPasses{},
m_NextPassId{1}
m_NextPassId(0)
{}
PassManager::~PassManager() noexcept
......@@ -59,7 +59,7 @@ namespace vkcv
m_Device.destroy(pass);
m_RenderPasses.clear();
m_NextPassId = 1;
m_NextPassId = 0;
}
PassHandle PassManager::createPass(const PassConfig &config)
......@@ -122,14 +122,14 @@ namespace vkcv
vk::RenderPass vkObject{nullptr};
if(m_Device.createRenderPass(&passInfo, nullptr, &vkObject) != vk::Result::eSuccess)
return PassHandle{0};
return PassHandle();
m_RenderPasses.push_back(vkObject);
return PassHandle{m_NextPassId++};
return PassHandle(m_NextPassId++);
}
vk::RenderPass PassManager::getVkPass(const PassHandle &handle) const
{
return m_RenderPasses[handle.id - 1];
return m_RenderPasses[handle.getId()];
}
}
......@@ -7,7 +7,7 @@ namespace vkcv
m_Device{device},
m_Pipelines{},
m_PipelineLayouts{},
m_NextPipelineId{1}
m_NextPipelineId{0}
{}
PipelineManager::~PipelineManager() noexcept
......@@ -20,7 +20,7 @@ namespace vkcv
m_Pipelines.clear();
m_PipelineLayouts.clear();
m_NextPipelineId = 1;
m_NextPipelineId = 0;
}
PipelineHandle PipelineManager::createPipeline(const PipelineConfig &config, const vk::RenderPass &pass)
......@@ -30,7 +30,7 @@ namespace vkcv
if (!(existsVertexShader && existsFragmentShader))
{
std::cout << "Core::createGraphicsPipeline requires vertex and fragment shader code" << std::endl;
return PipelineHandle{0};
return PipelineHandle();
}
// vertex shader stage
......@@ -38,7 +38,7 @@ namespace vkcv
vk::ShaderModuleCreateInfo vertexModuleInfo({}, vertexCode.size(), reinterpret_cast<uint32_t*>(vertexCode.data()));
vk::ShaderModule vertexModule{};
if (m_Device.createShaderModule(&vertexModuleInfo, nullptr, &vertexModule) != vk::Result::eSuccess)
return PipelineHandle{0};
return PipelineHandle();
vk::PipelineShaderStageCreateInfo pipelineVertexShaderStageInfo(
{},
......@@ -55,7 +55,7 @@ namespace vkcv
if (m_Device.createShaderModule(&fragmentModuleInfo, nullptr, &fragmentModule) != vk::Result::eSuccess)
{
m_Device.destroy(vertexModule);
return PipelineHandle{0};
return PipelineHandle();
}
vk::PipelineShaderStageCreateInfo pipelineFragmentShaderStageInfo(
......@@ -153,7 +153,7 @@ namespace vkcv
{
m_Device.destroy(vertexModule);
m_Device.destroy(fragmentModule);
return PipelineHandle{0};
return PipelineHandle();
}
// graphics pipeline create
......@@ -183,7 +183,7 @@ namespace vkcv
{
m_Device.destroy(vertexModule);
m_Device.destroy(fragmentModule);
return PipelineHandle{0};
return PipelineHandle();
}
m_Device.destroy(vertexModule);
......@@ -191,16 +191,16 @@ namespace vkcv
m_Pipelines.push_back(vkPipeline);
m_PipelineLayouts.push_back(vkPipelineLayout);
return PipelineHandle{m_NextPipelineId++};
return PipelineHandle(m_NextPipelineId++);
}
vk::Pipeline PipelineManager::getVkPipeline(const PipelineHandle &handle) const
{
return m_Pipelines.at(handle.id -1);
return m_Pipelines.at(handle.getId());
}
vk::PipelineLayout PipelineManager::getVkPipelineLayout(const PipelineHandle &handle) const
{
return m_PipelineLayouts.at(handle.id - 1);
return m_PipelineLayouts.at(handle.getId());
}
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment