Implementing Commandbuffers

This commit is contained in:
Dynamitos
2020-03-24 21:05:32 +01:00
parent fda46a7ab8
commit ae92439164
27 changed files with 779 additions and 311 deletions
+8
View File
@@ -0,0 +1,8 @@
{
"C_Cpp.default.configurationProvider": "go2sh.cmake-integration",
"telemetry.enableTelemetry": false,
"cmake.buildDirectory": "${workspaceFolder}/bin/${buildType}",
"files.associations": {
"xstring": "cpp"
}
}
+1
View File
@@ -14,6 +14,7 @@ set(GLFW_ROOT ${EXTERNAL_ROOT}/glfw)
set(CMAKE_BINARY_DIR ${CMAKE_CURRENT_SOURCE_DIR}/bin/${CMAKE_BUILD_TYPE}) set(CMAKE_BINARY_DIR ${CMAKE_CURRENT_SOURCE_DIR}/bin/${CMAKE_BUILD_TYPE})
set(RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) set(RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}) set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR})
set(Boost_DETAILED_FAILURE_MSG TRUE)
# Configuration types # Configuration types
SET(CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING "Configs" FORCE) SET(CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING "Configs" FORCE)
+2
View File
@@ -4,6 +4,8 @@ namespace Seele
{ {
namespace Gfx namespace Gfx
{ {
static bool useAsyncCompute = true;
typedef uint32_t SeFlags; typedef uint32_t SeFlags;
typedef uint32_t SeBool32; typedef uint32_t SeBool32;
typedef uint64_t SeDeviceSize; typedef uint64_t SeDeviceSize;
-3
View File
@@ -54,9 +54,6 @@ namespace Seele
uint32_t offset; uint32_t offset;
uint32_t size; uint32_t size;
}; };
class RenderCommandBase class RenderCommandBase
{ {
-5
View File
@@ -21,11 +21,6 @@ void Seele::RenderCore::init()
void Seele::RenderCore::renderLoop() void Seele::RenderCore::renderLoop()
{ {
while (true)
{
windowManager->beginFrame();
windowManager->endFrame();
}
} }
void Seele::RenderCore::shutdown() void Seele::RenderCore::shutdown()
+10 -1
View File
@@ -2,12 +2,21 @@ target_sources(SeeleEngine
PRIVATE PRIVATE
VulkanAllocator.h VulkanAllocator.h
VulkanAllocator.cpp VulkanAllocator.cpp
VulkanCommandBuffer.h
VulkanCommandBuffer.cpp
VulkanBuffer.cpp VulkanBuffer.cpp
VulkanFramebuffer.h
VulkanFramebuffer.cpp
VulkanGraphics.h VulkanGraphics.h
VulkanGraphics.cpp VulkanGraphics.cpp
VulkanGraphicsResources.h VulkanGraphicsResources.h
VulkanGraphicsResources.cpp
VulkanDescriptorSets.cpp VulkanDescriptorSets.cpp
VulkanGraphicsEnums.h VulkanGraphicsEnums.h
VulkanGraphicsEnums.cpp VulkanGraphicsEnums.cpp
VulkanInitializer.h VulkanInitializer.h
VulkanInitializer.cpp) VulkanInitializer.cpp
VulkanRenderPass.h
VulkanRenderPass.cpp
VulkanQueue.h
VulkanQueue.cpp)
@@ -14,7 +14,7 @@ SubAllocation::SubAllocation(Allocation* owner, uint32 allocatedOffset, uint32 s
{ {
} }
Allocation::Allocation(PGraphics graphics, Allocator* allocator, uint32 size, uint32 memoryTypeIndex, VkMemoryPropertyFlags properties, bool isDedicated) Allocation::Allocation(WGraphics graphics, Allocator* allocator, uint32 size, uint32 memoryTypeIndex, VkMemoryPropertyFlags properties, bool isDedicated)
: device(graphics->getDevice()) : device(graphics->getDevice())
, allocator(allocator) , allocator(allocator)
, bytesAllocated(0) , bytesAllocated(0)
@@ -32,13 +32,13 @@ Allocation::Allocation(PGraphics graphics, Allocator* allocator, uint32 size, ui
freeRanges.add(freeRange); freeRanges.add(freeRange);
} }
PSubAllocation Allocation::getSuballocation(uint32 size, uint32 alignment) PSubAllocation Allocation::getSuballocation(uint32 requestedSize, uint32 alignment)
{ {
if (isDedicated) if (isDedicated)
{ {
if (activeAllocations.size() == 0) if (activeAllocations.size() == 0)
{ {
assert(size == bytesAllocated); assert(requestedSize == bytesAllocated);
activeAllocations.add(freeRanges.back()); activeAllocations.add(freeRanges.back());
freeRanges.clear(); freeRanges.clear();
} }
@@ -53,7 +53,7 @@ PSubAllocation Allocation::getSuballocation(uint32 size, uint32 alignment)
uint32 allocatedOffset = freeAllocation->allocatedOffset; uint32 allocatedOffset = freeAllocation->allocatedOffset;
uint32 alignedOffset = align(allocatedOffset, alignment); uint32 alignedOffset = align(allocatedOffset, alignment);
uint32 alignmentAdjustment = alignedOffset - allocatedOffset; uint32 alignmentAdjustment = alignedOffset - allocatedOffset;
uint32 size = alignmentAdjustment + size; uint32 size = alignmentAdjustment + requestedSize;
if (freeAllocation->size == size) if (freeAllocation->size == size)
{ {
freeRanges.remove(i); freeRanges.remove(i);
@@ -66,7 +66,7 @@ PSubAllocation Allocation::getSuballocation(uint32 size, uint32 alignment)
freeAllocation->allocatedSize -= size; freeAllocation->allocatedSize -= size;
freeAllocation->allocatedOffset += allocatedOffset; freeAllocation->allocatedOffset += allocatedOffset;
freeAllocation->alignedOffset += allocatedOffset; freeAllocation->alignedOffset += allocatedOffset;
PSubAllocation subAlloc = new VulkanSubAllocation(this, allocatedOffset, size, alignedOffset, size); PSubAllocation subAlloc = new SubAllocation(this, allocatedOffset, size, alignedOffset, size);
activeAllocations.add(subAlloc); activeAllocations.add(subAlloc);
return subAlloc; return subAlloc;
} }
@@ -74,7 +74,7 @@ PSubAllocation Allocation::getSuballocation(uint32 size, uint32 alignment)
return nullptr; return nullptr;
} }
Allocator::Allocator(PGraphics graphics) Allocator::Allocator(WGraphics graphics)
: graphics(graphics) : graphics(graphics)
{ {
vkGetPhysicalDeviceMemoryProperties(graphics->getPhysicalDevice(), &memProperties); vkGetPhysicalDeviceMemoryProperties(graphics->getPhysicalDevice(), &memProperties);
+3 -3
View File
@@ -28,7 +28,7 @@ namespace Seele
class Allocation class Allocation
{ {
public: public:
Allocation(PGraphics graphics, Allocator* allocator, uint32 size, uint32 memoryTypeIndex, VkMemoryPropertyFlags properties, bool isDedicated); Allocation(WGraphics graphics, Allocator* allocator, uint32 size, uint32 memoryTypeIndex, VkMemoryPropertyFlags properties, bool isDedicated);
PSubAllocation getSuballocation(uint32 size, uint32 alignment); PSubAllocation getSuballocation(uint32 size, uint32 alignment);
private: private:
Allocator* allocator; Allocator* allocator;
@@ -50,7 +50,7 @@ namespace Seele
class Allocator class Allocator
{ {
public: public:
Allocator(PGraphics graphics); Allocator(WGraphics graphics);
~Allocator(); ~Allocator();
PSubAllocation allocate(uint64 size, const VkMemoryRequirements2& requirements, VkMemoryPropertyFlags props); PSubAllocation allocate(uint64 size, const VkMemoryRequirements2& requirements, VkMemoryPropertyFlags props);
@@ -66,7 +66,7 @@ namespace Seele
}; };
Array<HeapInfo> heaps; Array<HeapInfo> heaps;
VkResult findMemoryType(uint32 typeBits, VkMemoryPropertyFlags properties, uint32* typeIndex); VkResult findMemoryType(uint32 typeBits, VkMemoryPropertyFlags properties, uint32* typeIndex);
PGraphics graphics; WGraphics graphics;
VkPhysicalDeviceMemoryProperties memProperties; VkPhysicalDeviceMemoryProperties memProperties;
}; };
DEFINE_REF(Allocator); DEFINE_REF(Allocator);
+2 -64
View File
@@ -1,67 +1,5 @@
#include "VulkanGraphicsResources.h" #include "VulkanGraphicsResources.h"
#include "VulkanInitializer.h"
using namespace Seele;
using namespace Seele::Vulkan; using namespace Seele::Vulkan;
void Buffer::executeOwnershipBarrier(QueueType newOwner)
{
VkBufferMemoryBarrier barrier =
init::BufferMemoryBarrier();
CommandBufferManager* sourceManager = getCommands();
CommandBufferManager* dstManager = nullptr;
VkPipelineStageFlags srcStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
VkPipelineStageFlags dstStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
if (currentOwner == QueueType::TRANSFER)
{
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
barrier.srcQueueFamilyIndex = device->getTransferQueue()->getFamilyIndex();
srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
}
else if (currentOwner == QueueType::COMPUTE)
{
barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
barrier.srcQueueFamilyIndex = device->getComputeQueue()->getFamilyIndex();
srcStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
}
else if (currentOwner == QueueType::GRAPHICS)
{
barrier.srcAccessMask = getSourceAccessMask();
barrier.srcQueueFamilyIndex = device->getGraphicsQueue()->getFamilyIndex();
srcStage = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
}
if (newOwner == QueueType::TRANSFER)
{
barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
barrier.dstQueueFamilyIndex = device->getTransferQueue()->getFamilyIndex();
dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
dstManager = device->getRHIDevice().getTransferCommands();
}
else if (newOwner == QueueType::COMPUTE)
{
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
barrier.dstQueueFamilyIndex = device->getComputeQueue()->getFamilyIndex();
dstStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
dstManager = device->getRHIDevice().getComputeCommands();
}
else if (newOwner == QueueType::GRAPHICS)
{
barrier.dstAccessMask = getDestAccessMask();
barrier.dstQueueFamilyIndex = device->getGraphicsQueue()->getFamilyIndex();
dstStage = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
dstManager = device->getRHIDevice().getGraphicsCommands();
}
VkCommandBuffer srcCommand = sourceManager->getCmdBuffer()->getHandle();
VkCommandBuffer dstCommand = dstManager->getCmdBuffer()->getHandle();
const bool bDynamic = (rhiUsage & BUF_Dynamic) != 0;
uint32_t numBuffers = bDynamic ? NUM_BUFFERS : 1;
VkBufferMemoryBarrier dynamicBarriers[NUM_BUFFERS];
for (uint32_t i = 0; i < numBuffers; ++i)
{
dynamicBarriers[i] = barrier;
dynamicBarriers[i].buffer = buffers[i]->getHandle();
dynamicBarriers[i].offset = buffers[i]->getOffset();
dynamicBarriers[i].size = buffers[i]->getSize();
}
vkCmdPipelineBarrier(srcCommand, srcStage, dstStage, 0, 0, nullptr, numBuffers, dynamicBarriers, 0, nullptr);
vkCmdPipelineBarrier(dstCommand, srcStage, dstStage, 0, 0, nullptr, numBuffers, dynamicBarriers, 0, nullptr);
sourceManager->submitCommands();
}
@@ -0,0 +1,139 @@
#include "VulkanCommandBuffer.h"
#include "VulkanInitializer.h"
#include "VulkanGraphics.h"
#include "VulkanGraphicsEnums.h"
#include "VulkanFramebuffer.h"
#include "VulkanRenderPass.h"
using namespace Seele;
using namespace Seele::Vulkan;
CmdBufferBase::CmdBufferBase(WGraphics graphics, VkCommandPool cmdPool)
: graphics(graphics)
, owner(cmdPool)
{
}
CmdBufferBase::~CmdBufferBase()
{
}
CmdBuffer::CmdBuffer(WGraphics graphics, VkCommandPool cmdPool)
: CmdBufferBase(graphics, cmdPool)
, renderPass(nullptr)
, framebuffer(nullptr)
, subpassIndex(0)
{
VkCommandBufferAllocateInfo allocInfo =
init::CommandBufferAllocateInfo(cmdPool,
VK_COMMAND_BUFFER_LEVEL_PRIMARY,
1);
VK_CHECK(vkAllocateCommandBuffers(graphics->getDevice(), &allocInfo, &handle))
state = State::ReadyBegin;
}
CmdBuffer::~CmdBuffer()
{
vkFreeCommandBuffers(graphics->getDevice(), owner, 1, &handle);
}
void CmdBuffer::begin()
{
VkCommandBufferBeginInfo beginInfo =
init::CommandBufferBeginInfo();
beginInfo.pInheritanceInfo = nullptr;
VK_CHECK(vkBeginCommandBuffer(handle, &beginInfo));
state = State::InsideBegin;
}
void CmdBuffer::end()
{
VK_CHECK(vkEndCommandBuffer(handle));
state = State::Ended;
}
void CmdBuffer::beginRenderPass(WRenderPass renderPass, WFramebuffer framebuffer)
{
VkRenderPassBeginInfo beginInfo =
init::RenderPassBeginInfo();
beginInfo.clearValueCount = renderPass->getClearValueCount();
beginInfo.pClearValues = renderPass->getClearValues();
beginInfo.renderArea = renderPass->getRenderArea();
beginInfo.renderPass = renderPass->getHandle();
beginInfo.framebuffer = framebuffer->getHandle();
vkCmdBeginRenderPass(handle, &beginInfo, renderPass->getSubpassContents());
}
void CmdBuffer::endRenderPass()
{
vkCmdEndRenderPass(handle);
}
SecondaryCmdBuffer::SecondaryCmdBuffer(WGraphics graphics, VkCommandPool cmdPool)
: CmdBufferBase(graphics, cmdPool)
{
VkCommandBufferAllocateInfo allocInfo =
init::CommandBufferAllocateInfo(cmdPool,
VK_COMMAND_BUFFER_LEVEL_SECONDARY,
1);
VK_CHECK(vkAllocateCommandBuffers(graphics->getDevice(), &allocInfo, &handle));
}
SecondaryCmdBuffer::~SecondaryCmdBuffer()
{
vkFreeCommandBuffers(graphics->getDevice(), owner, 1, &handle);
}
void SecondaryCmdBuffer::begin(WCmdBuffer parent)
{
VkCommandBufferBeginInfo beginInfo =
init::CommandBufferBeginInfo();
VkCommandBufferInheritanceInfo inheritanceInfo =
init::CommandBufferInheritanceInfo();
inheritanceInfo.framebuffer = parent->framebuffer->getHandle();
inheritanceInfo.renderPass = parent->renderPass->getHandle();
inheritanceInfo.subpass = parent->subpassIndex;
beginInfo.pInheritanceInfo = &inheritanceInfo;
VK_CHECK(vkBeginCommandBuffer(handle, &beginInfo));
}
void SecondaryCmdBuffer::end()
{
VK_CHECK(vkEndCommandBuffer(handle));
}
CommandBufferManager::CommandBufferManager(WGraphics graphics, WQueue queue)
: graphics(graphics)
, queue(queue)
{
VkCommandPoolCreateInfo info =
init::CommandPoolCreateInfo();
info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
info.queueFamilyIndex = queue->getFamilyIndex();
VK_CHECK(vkCreateCommandPool(graphics->getDevice(), &info, nullptr, &commandPool));
activeCmdBuffer = new CmdBuffer(graphics, commandPool);
activeCmdBuffer->begin();
}
CommandBufferManager::~CommandBufferManager()
{
vkDestroyCommandPool(graphics->getDevice(), commandPool, nullptr);
}
PCmdBuffer CommandBufferManager::getCommands()
{
return activeCmdBuffer;
}
PSecondaryCmdBuffer CommandBufferManager::createSecondaryCmdBuffer()
{
return PSecondaryCmdBuffer();
}
void Seele::Vulkan::CommandBufferManager::submitCommands(PSemaphore signalSemaphore)
{
}
@@ -1,38 +1,90 @@
#pragma once
#include "VulkanGraphicsResources.h" #include "VulkanGraphicsResources.h"
#include "VulkanQueue.h"
namespace Seele namespace Seele
{ {
namespace Vulkan namespace Vulkan
{ {
class CmdBufferBase : public RenderCommandBase DECLARE_REF(RenderPass);
DECLARE_REF(Framebuffer);
class CmdBufferBase : public Gfx::RenderCommandBase
{ {
public: public:
private: CmdBufferBase(WGraphics graphics, VkCommandPool cmdPool);
virtual ~CmdBufferBase();
inline VkCommandBuffer getHandle()
{
return handle;
}
void reset();
VkViewport currentViewport;
VkRect2D currentScissor;
protected:
WGraphics graphics;
VkCommandBuffer handle; VkCommandBuffer handle;
VkCommandPool owner;
}; };
DEFINE_REF(CmdBuffer); DEFINE_REF(CmdBufferBase);
DECLARE_REF(SecondaryCmdBuffer);
class CmdBuffer : public CmdBufferBase class CmdBuffer : public CmdBufferBase
{ {
public:
CmdBuffer(WGraphics graphics, VkCommandPool cmdPool);
virtual ~CmdBuffer();
void begin();
void end();
void beginRenderPass(WRenderPass renderPass, WFramebuffer framebuffer);
void endRenderPass();
void executeCommands(Array<WSecondaryCmdBuffer> secondaryCommands);
void addWaitSemaphore(VkPipelineStageFlags stages, PSemaphore waitSemaphore);
enum State
{
ReadyBegin,
InsideBegin,
RenderPassActive,
Ended,
Submitted,
};
private:
WRenderPass renderPass;
WFramebuffer framebuffer;
uint32 subpassIndex;
State state;
friend class SecondaryCmdBuffer;
}; };
DEFINE_REF(CmdBuffer); DEFINE_REF(CmdBuffer);
class SecondaryCmdBuffer : public CmdBufferBase
{
public:
SecondaryCmdBuffer(WGraphics graphics, VkCommandPool cmdPool);
virtual ~SecondaryCmdBuffer();
void begin(WCmdBuffer parent);
void end();
private:
};
DEFINE_REF(SecondaryCmdBuffer);
class CommandBufferManager class CommandBufferManager
{ {
public: public:
CommandBufferManager(Vulkan::PGraphics graphics, PVulkanQueue queue); CommandBufferManager(WGraphics graphics, WQueue queue);
virtual ~CommandBufferManager(); virtual ~CommandBufferManager();
PCmdBuffer getCommands(); PCmdBuffer getCommands();
PSecondaryCommandBuffer createSecondaryCmdBuffer(); PSecondaryCmdBuffer createSecondaryCmdBuffer();
void submitCommands(PSemaphore signalSemaphore = nullptr); void submitCommands(PSemaphore signalSemaphore = nullptr);
void waitForBuffer(PCommandbuffer cmdBuffer, float timeToWait = 1.0f); void waitForCommands(PCmdBuffer cmdBuffer, float timeToWait = 1.0f);
private: private:
WGraphics graphics;
VkCommandPool commandPool; VkCommandPool commandPool;
QueueType queueType; WQueue queue;
uint32 queueFamilyIndex; uint32 queueFamilyIndex;
Array<Vulkan::PCmdBuffer> allocatedBuffers; PCmdBuffer activeCmdBuffer;
Array<PCmdBuffer> allocatedBuffers;
}; };
DEFINE_REF(VulkanCommandBufferManager); DEFINE_REF(CommandBufferManager);
} }
} }
@@ -149,7 +149,7 @@ void DescriptorSet::writeChanges()
} }
} }
DescriptorAllocator::DescriptorAllocator(PGraphics graphics, DescriptorLayout& layout) DescriptorAllocator::DescriptorAllocator(WGraphics graphics, DescriptorLayout& layout)
: layout(layout) : layout(layout)
, graphics(graphics) , graphics(graphics)
{ {
@@ -0,0 +1,23 @@
#pragma once
#include "VulkanGraphicsResources.h"
namespace Seele
{
namespace Vulkan
{
class Framebuffer
{
public:
Framebuffer(WGraphics graphics);
virtual ~Framebuffer();
inline VkFramebuffer getHandle() const
{
return handle;
}
private:
WGraphics graphics;
VkFramebuffer handle;
};
DEFINE_REF(Framebuffer);
}
}
+113 -8
View File
@@ -1,16 +1,15 @@
#include "VulkanGraphics.h" #include "VulkanGraphics.h"
#include "VulkanAllocator.h" #include "VulkanAllocator.h"
#include "VulkanQueue.h"
#include "Containers/Array.h" #include "Containers/Array.h"
#include "VulkanInitializer.h" #include "VulkanInitializer.h"
#include "VulkanCommandBuffer.h"
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
using namespace Seele::Vulkan; using namespace Seele::Vulkan;
Graphics::Graphics() Graphics::Graphics()
: callback(VK_NULL_HANDLE) : callback(VK_NULL_HANDLE), handle(VK_NULL_HANDLE), instance(VK_NULL_HANDLE), physicalDevice(VK_NULL_HANDLE)
, handle(VK_NULL_HANDLE)
, instance(VK_NULL_HANDLE)
, physicalDevice(VK_NULL_HANDLE)
{ {
glfwInit(); glfwInit();
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
@@ -18,6 +17,9 @@ Graphics::Graphics()
Graphics::~Graphics() Graphics::~Graphics()
{ {
vkDestroyDevice(handle, nullptr);
DestroyDebugReportCallbackEXT(instance, nullptr, callback);
vkDestroyInstance(instance, nullptr);
glfwTerminate(); glfwTerminate();
} }
@@ -26,7 +28,12 @@ void Graphics::init(GraphicsInitializer initInfo)
initInstance(initInfo); initInstance(initInfo);
setupDebugCallback(); setupDebugCallback();
pickPhysicalDevice(); pickPhysicalDevice();
allocator = new VulkanAllocator(this); createDevice(initInfo);
allocator = new Allocator(this);
graphicsCommands = new CommandBufferManager(this, graphicsQueue);
computeCommands = new CommandBufferManager(this, computeQueue);
transferCommands = new CommandBufferManager(this, transferQueue);
dedicatedTransferCommands = new CommandBufferManager(this, dedicatedTransferQueue);
} }
void Graphics::beginFrame(void *windowHandle) void Graphics::beginFrame(void *windowHandle)
@@ -63,7 +70,8 @@ Array<const char*> Graphics::getRequiredExtensions()
unsigned int glfwExtensionCount = 0; unsigned int glfwExtensionCount = 0;
const char **glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount); const char **glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount);
for (unsigned int i = 0; i < glfwExtensionCount; i++) { for (unsigned int i = 0; i < glfwExtensionCount; i++)
{
extensions.add(glfwExtensions[i]); extensions.add(glfwExtensions[i]);
} }
#ifdef ENABLE_VALIDATION #ifdef ENABLE_VALIDATION
@@ -119,8 +127,8 @@ void Graphics::pickPhysicalDevice()
for (auto physicalDevice : physicalDevices) for (auto physicalDevice : physicalDevices)
{ {
uint32 currentRating = 0; uint32 currentRating = 0;
VkPhysicalDeviceProperties props;
vkGetPhysicalDeviceProperties(physicalDevice, &props); vkGetPhysicalDeviceProperties(physicalDevice, &props);
vkGetPhysicalDeviceFeatures(physicalDevice, &features);
if (props.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) if (props.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU)
{ {
currentRating += 100; currentRating += 100;
@@ -138,7 +146,104 @@ void Graphics::pickPhysicalDevice()
this->physicalDevice = bestDevice; this->physicalDevice = bestDevice;
} }
void Graphics::createDevice() void Graphics::createDevice(GraphicsInitializer initializer)
{ {
uint32_t numQueueFamilies = 0;
vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &numQueueFamilies, nullptr);
Array<VkQueueFamilyProperties> queueProperties(numQueueFamilies);
vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &numQueueFamilies, queueProperties.data());
Array<VkDeviceQueueCreateInfo> queueInfos;
int32_t graphicsQueueFamilyIndex = -1;
int32_t transferQueueFamilyIndex = -1;
int32_t dedicatedTransferQueueFamilyIndex = -1;
int32_t computeQueueFamilyIndex = -1;
int32_t asyncComputeFamilyIndex = -1;
for (int32_t familyIndex = 0; familyIndex < queueProperties.size(); ++familyIndex)
{
const VkQueueFamilyProperties currProps = queueProperties[familyIndex];
if ((currProps.queueFlags & VK_QUEUE_GRAPHICS_BIT) == VK_QUEUE_GRAPHICS_BIT)
{
if (graphicsQueueFamilyIndex == -1)
{
graphicsQueueFamilyIndex = familyIndex;
}
}
if ((currProps.queueFlags & VK_QUEUE_COMPUTE_BIT) == VK_QUEUE_COMPUTE_BIT)
{
if (computeQueueFamilyIndex == -1)
{
computeQueueFamilyIndex = familyIndex;
}
if (Gfx::useAsyncCompute)
{
if (asyncComputeFamilyIndex == -1)
{
if (familyIndex == graphicsQueueFamilyIndex)
{
if (currProps.queueCount > 1)
{
asyncComputeFamilyIndex = familyIndex;
}
}
else
{
asyncComputeFamilyIndex = familyIndex;
}
}
}
}
if ((currProps.queueFlags & VK_QUEUE_TRANSFER_BIT) == VK_QUEUE_TRANSFER_BIT)
{
if (transferQueueFamilyIndex == -1)
{
transferQueueFamilyIndex = familyIndex;
}
if ((currProps.queueFlags ^ VK_QUEUE_TRANSFER_BIT) == 0)
{
dedicatedTransferQueueFamilyIndex = familyIndex;
}
}
VkDeviceQueueCreateInfo info =
init::DeviceQueueCreateInfo(familyIndex, 1);
queueInfos.add(info);
}
VkDeviceCreateInfo deviceInfo = init::DeviceCreateInfo(
queueInfos.data(),
(uint32)queueInfos.size(),
&features);
deviceInfo.enabledExtensionCount = (uint32)initializer.deviceExtensions.size();
deviceInfo.ppEnabledExtensionNames = initializer.deviceExtensions.data();
deviceInfo.enabledLayerCount = (uint32_t)initializer.layers.size();
deviceInfo.ppEnabledLayerNames = initializer.layers.data();
VK_CHECK(vkCreateDevice(physicalDevice, &deviceInfo, nullptr, &handle));
graphicsQueue = new Queue(this, QueueType::GRAPHICS, graphicsQueueFamilyIndex, 0);
if (Gfx::useAsyncCompute && asyncComputeFamilyIndex != -1)
{
if (asyncComputeFamilyIndex == graphicsQueueFamilyIndex)
{
// Same family as graphics, but different queue
computeQueue = new Queue(this, QueueType::COMPUTE, asyncComputeFamilyIndex, 1);
}
else
{
// Different family
computeQueue = new Queue(this, QueueType::COMPUTE, asyncComputeFamilyIndex, 0);
}
}
else
{
computeQueue = new Queue(this, QueueType::COMPUTE, computeQueueFamilyIndex, 0);
}
transferQueue = new Queue(this, QueueType::TRANSFER, transferQueueFamilyIndex, 0);
if (dedicatedTransferQueueFamilyIndex != -1)
{
dedicatedTransferQueue = new Queue(this, QueueType::DEDICATED_TRANSFER, dedicatedTransferQueueFamilyIndex, 0);
}
queueMapping.graphicsFamily = graphicsQueue->getFamilyIndex();
queueMapping.computeFamily = computeQueue->getFamilyIndex();
queueMapping.transferFamily = transferQueue->getFamilyIndex();
queueMapping.dedicatedTransferFamily = dedicatedTransferQueue->getFamilyIndex();
} }
+22 -1
View File
@@ -1,3 +1,4 @@
#pragma once
#include "Graphics/Graphics.h" #include "Graphics/Graphics.h"
#include "VulkanGraphicsResources.h" #include "VulkanGraphicsResources.h"
@@ -6,6 +7,8 @@ namespace Seele
namespace Vulkan namespace Vulkan
{ {
DECLARE_REF(Allocator); DECLARE_REF(Allocator);
DECLARE_REF(CommandBufferManager);
DECLARE_REF(Queue);
class Graphics : public Gfx::Graphics class Graphics : public Gfx::Graphics
{ {
public: public:
@@ -14,6 +17,11 @@ namespace Seele
VkDevice getDevice() const; VkDevice getDevice() const;
VkPhysicalDevice getPhysicalDevice() const; VkPhysicalDevice getPhysicalDevice() const;
PCommandBufferManager getGraphicsCommands();
PCommandBufferManager getComputeCommands();
PCommandBufferManager getTransferCommands();
PCommandBufferManager getDedicatedTransferCommands();
// Inherited via Graphics // Inherited via Graphics
virtual void init(GraphicsInitializer initializer) override; virtual void init(GraphicsInitializer initializer) override;
virtual void beginFrame(void* windowHandle) override; virtual void beginFrame(void* windowHandle) override;
@@ -24,14 +32,27 @@ namespace Seele
void initInstance(GraphicsInitializer initInfo); void initInstance(GraphicsInitializer initInfo);
void setupDebugCallback(); void setupDebugCallback();
void pickPhysicalDevice(); void pickPhysicalDevice();
void createDevice(); void createDevice(GraphicsInitializer initInfo);
VkDevice handle; VkDevice handle;
VkPhysicalDevice physicalDevice; VkPhysicalDevice physicalDevice;
VkInstance instance; VkInstance instance;
WQueue graphicsQueue;
WQueue computeQueue;
WQueue transferQueue;
WQueue dedicatedTransferQueue;
QueueFamilyMapping queueMapping;
PCommandBufferManager graphicsCommands;
PCommandBufferManager computeCommands;
PCommandBufferManager transferCommands;
PCommandBufferManager dedicatedTransferCommands;
VkPhysicalDeviceProperties props;
VkPhysicalDeviceFeatures features;
VkDebugReportCallbackEXT callback; VkDebugReportCallbackEXT callback;
Array<PViewport> viewports; Array<PViewport> viewports;
PAllocator allocator; PAllocator allocator;
friend class Window; friend class Window;
}; };
DEFINE_REF(Graphics); DEFINE_REF(Graphics);
@@ -3,7 +3,7 @@
using namespace Seele::Vulkan; using namespace Seele::Vulkan;
using namespace Seele::Gfx; using namespace Seele::Gfx;
VkDescriptorType cast(const Seele::Gfx::SeDescriptorType& descriptorType) VkDescriptorType Seele::Vulkan::cast(const Seele::Gfx::SeDescriptorType& descriptorType)
{ {
switch (descriptorType) switch (descriptorType)
{ {
@@ -41,7 +41,7 @@ VkDescriptorType cast(const Seele::Gfx::SeDescriptorType& descriptorType)
return VK_DESCRIPTOR_TYPE_MAX_ENUM; return VK_DESCRIPTOR_TYPE_MAX_ENUM;
} }
Seele::Gfx::SeDescriptorType cast(const VkDescriptorType& descriptorType) Seele::Gfx::SeDescriptorType Seele::Vulkan::cast(const VkDescriptorType& descriptorType)
{ {
switch (descriptorType) switch (descriptorType)
{ {
@@ -80,7 +80,7 @@ Seele::Gfx::SeDescriptorType cast(const VkDescriptorType& descriptorType)
return SE_DESCRIPTOR_TYPE_MAX_ENUM; return SE_DESCRIPTOR_TYPE_MAX_ENUM;
} }
VkShaderStageFlagBits cast(const Seele::Gfx::SeShaderStageFlagBits& stage) VkShaderStageFlagBits Seele::Vulkan::cast(const Seele::Gfx::SeShaderStageFlagBits& stage)
{ {
switch (stage) switch (stage)
{ {
@@ -125,7 +125,7 @@ VkShaderStageFlagBits cast(const Seele::Gfx::SeShaderStageFlagBits& stage)
return VK_SHADER_STAGE_ALL; return VK_SHADER_STAGE_ALL;
} }
Seele::Gfx::SeShaderStageFlagBits cast(const VkShaderStageFlagBits& stage) Seele::Gfx::SeShaderStageFlagBits Seele::Vulkan::cast(const VkShaderStageFlagBits& stage)
{ {
switch (stage) switch (stage)
{ {
@@ -0,0 +1,20 @@
#include "VulkanGraphicsResources.h"
#include "VulkanInitializer.h"
#include "VulkanGraphics.h"
#include "VulkanGraphicsEnums.h"
using namespace Seele;
using namespace Seele::Vulkan;
Semaphore::Semaphore(WGraphics graphics)
: graphics(graphics)
{
VkSemaphoreCreateInfo info =
init::SemaphoreCreateInfo();
VK_CHECK(vkCreateSemaphore(graphics->getDevice(), &info, nullptr, &handle));
}
Semaphore::~Semaphore()
{
}
@@ -6,23 +6,38 @@ namespace Seele
{ {
namespace Vulkan namespace Vulkan
{ {
DECLARE_REF(DescriptorAllocator); DECLARE_REF(DescriptorAllocator);
DECLARE_REF(CommandBufferManager);
DECLARE_REF(Graphics); DECLARE_REF(Graphics);
class Semaphore
{
public:
Semaphore(WGraphics graphics);
virtual ~Semaphore();
private:
VkSemaphore handle;
WGraphics graphics;
};
DEFINE_REF(Semaphore);
class DescriptorLayout : public Gfx::DescriptorLayout class DescriptorLayout : public Gfx::DescriptorLayout
{ {
public: public:
DescriptorLayout(PGraphics graphics) DescriptorLayout(WGraphics graphics)
: graphics(graphics) : graphics(graphics), layoutHandle(VK_NULL_HANDLE)
, layoutHandle(VK_NULL_HANDLE) {
{} }
virtual ~DescriptorLayout(); virtual ~DescriptorLayout();
virtual void create(); virtual void create();
inline VkDescriptorSetLayout getHandle() const inline VkDescriptorSetLayout getHandle() const
{ {
return layoutHandle; return layoutHandle;
} }
private: private:
PGraphics graphics; WGraphics graphics;
Array<VkDescriptorSetLayoutBinding> bindings; Array<VkDescriptorSetLayoutBinding> bindings;
VkDescriptorSetLayout layoutHandle; VkDescriptorSetLayout layoutHandle;
friend class PipelineStateCacheManager; friend class PipelineStateCacheManager;
@@ -31,11 +46,10 @@ namespace Seele
class PipelineLayout : public Gfx::PipelineLayout class PipelineLayout : public Gfx::PipelineLayout
{ {
public: public:
PipelineLayout(PGraphics graphics) PipelineLayout(WGraphics graphics)
: graphics(graphics) : graphics(graphics), layoutHash(0), layoutHandle(VK_NULL_HANDLE)
, layoutHash(0) {
, layoutHandle(VK_NULL_HANDLE) }
{}
virtual ~PipelineLayout(); virtual ~PipelineLayout();
virtual void create(); virtual void create();
inline VkPipelineLayout getHandle() const inline VkPipelineLayout getHandle() const
@@ -46,11 +60,12 @@ namespace Seele
{ {
return layoutHash; return layoutHash;
} }
private: private:
Array<VkDescriptorSetLayout> vulkanDescriptorLayouts; Array<VkDescriptorSetLayout> vulkanDescriptorLayouts;
uint32 layoutHash; uint32 layoutHash;
VkPipelineLayout layoutHandle; VkPipelineLayout layoutHandle;
PGraphics graphics; WGraphics graphics;
friend class PipelineStateCacheManager; friend class PipelineStateCacheManager;
}; };
DEFINE_REF(PipelineLayout); DEFINE_REF(PipelineLayout);
@@ -58,11 +73,10 @@ namespace Seele
class DescriptorSet : public Gfx::DescriptorSet class DescriptorSet : public Gfx::DescriptorSet
{ {
public: public:
DescriptorSet(PGraphics graphics, PDescriptorAllocator owner) DescriptorSet(WGraphics graphics, PDescriptorAllocator owner)
: graphics(graphics) : graphics(graphics), owner(owner), setHandle(VK_NULL_HANDLE)
, owner(owner) {
, setHandle(VK_NULL_HANDLE) }
{}
virtual ~DescriptorSet(); virtual ~DescriptorSet();
virtual void updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer); virtual void updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer);
virtual void updateBuffer(uint32_t binding, Gfx::PStructuredBuffer uniformBuffer); virtual void updateBuffer(uint32_t binding, Gfx::PStructuredBuffer uniformBuffer);
@@ -73,6 +87,7 @@ namespace Seele
{ {
return setHandle; return setHandle;
} }
private: private:
virtual void writeChanges(); virtual void writeChanges();
Array<VkDescriptorImageInfo> imageInfos; Array<VkDescriptorImageInfo> imageInfos;
@@ -80,7 +95,7 @@ namespace Seele
Array<VkWriteDescriptorSet> writeDescriptors; Array<VkWriteDescriptorSet> writeDescriptors;
VkDescriptorSet setHandle; VkDescriptorSet setHandle;
PDescriptorAllocator owner; PDescriptorAllocator owner;
PGraphics graphics; WGraphics graphics;
friend class DescriptorAllocator; friend class DescriptorAllocator;
}; };
DEFINE_REF(DescriptorSet); DEFINE_REF(DescriptorSet);
@@ -88,7 +103,7 @@ namespace Seele
class DescriptorAllocator : public Gfx::DescriptorAllocator class DescriptorAllocator : public Gfx::DescriptorAllocator
{ {
public: public:
DescriptorAllocator(PGraphics graphics, DescriptorLayout& layout); DescriptorAllocator(WGraphics graphics, DescriptorLayout &layout);
~DescriptorAllocator(); ~DescriptorAllocator();
virtual void allocateDescriptorSet(Gfx::PDescriptorSet &descriptorSet); virtual void allocateDescriptorSet(Gfx::PDescriptorSet &descriptorSet);
@@ -96,8 +111,9 @@ namespace Seele
{ {
return poolHandle; return poolHandle;
} }
private: private:
PGraphics graphics; WGraphics graphics;
int maxSets = 512; int maxSets = 512;
VkDescriptorPool poolHandle; VkDescriptorPool poolHandle;
DescriptorLayout &layout; DescriptorLayout &layout;
@@ -107,20 +123,52 @@ namespace Seele
{ {
GRAPHICS = 1, GRAPHICS = 1,
COMPUTE = 2, COMPUTE = 2,
TRANSFER = 3 TRANSFER = 3,
DEDICATED_TRANSFER = 4
};
struct QueueFamilyMapping
{
uint32 graphicsFamily;
uint32 computeFamily;
uint32 transferFamily;
uint32 dedicatedTransferFamily;
uint32 getQueueTypeFamilyIndex(QueueType type)
{
switch (type)
{
case QueueType::GRAPHICS:
return graphicsFamily;
case QueueType::COMPUTE:
return computeFamily;
case QueueType::TRANSFER:
return transferFamily;
case QueueType::DEDICATED_TRANSFER:
return dedicatedTransferFamily;
default:
return VK_QUEUE_FAMILY_IGNORED;
}
}
bool needsTransfer(QueueType src, QueueType dst)
{
uint32 srcIndex = getQueueTypeFamilyIndex(src);
uint32 dstIndex = getQueueTypeFamilyIndex(dst);
return srcIndex != dstIndex;
}
}; };
class QueueOwnedResource class QueueOwnedResource
{ {
public: public:
QueueOwnedResource(PGraphics graphics, QueueType startQueueType); QueueOwnedResource(WGraphics graphics, QueueType startQueueType);
~QueueOwnedResource(); ~QueueOwnedResource();
CommandBufferManager* getCommands(); PCommandBufferManager getCommands();
//Preliminary checks to see if the barrier should be executed at all //Preliminary checks to see if the barrier should be executed at all
void transferOwnership(QueueType newOwner); void transferOwnership(QueueType newOwner);
protected: protected:
virtual void executeOwnershipBarrier(QueueType newOwner) = 0; virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
QueueType currentOwner; QueueType currentOwner;
PGraphics graphics; WGraphics graphics;
CommandBufferManager *cachedCmdBufferManager; CommandBufferManager *cachedCmdBufferManager;
}; };
DEFINE_REF(QueueOwnedResource); DEFINE_REF(QueueOwnedResource);
@@ -128,8 +176,9 @@ namespace Seele
class Buffer : public QueueOwnedResource class Buffer : public QueueOwnedResource
{ {
public: public:
Buffer(PGraphics graphics, uint32 size, VkBufferUsageFlags usage); Buffer(WGraphics graphics, uint32 size, VkBufferUsageFlags usage);
virtual ~Buffer(); virtual ~Buffer();
private: private:
virtual VkAccessFlags getSourceAccessMask() = 0; virtual VkAccessFlags getSourceAccessMask() = 0;
virtual VkAccessFlags getDestAccessMask() = 0; virtual VkAccessFlags getDestAccessMask() = 0;
@@ -138,26 +187,28 @@ namespace Seele
}; };
DEFINE_REF(Buffer); DEFINE_REF(Buffer);
class UniformBuffer : public Gfx::UniformBuffer class UniformBuffer : public Buffer, public Gfx::UniformBuffer
{ {
}; };
DEFINE_REF(UniformBuffer); DEFINE_REF(UniformBuffer);
class StructuredBuffer : public Gfx::StructuredBuffer class StructuredBuffer : public Buffer, public Gfx::StructuredBuffer
{ {
}; };
DEFINE_REF(StructuredBuffer); DEFINE_REF(StructuredBuffer);
class TextureBase class TextureBase
{ {
public:
TextureBase();
virtual ~TextureBase();
private: private:
uint32 sizeX; uint32 sizeX;
uint32 sizeY; uint32 sizeY;
uint32 sizeZ; uint32 sizeZ;
uint32 arrayCount; uint32 arrayCount;
uint32 layerCount; uint32 layerCount;
VkImage image;
}; };
DEFINE_REF(TextureBase); DEFINE_REF(TextureBase);
@@ -188,5 +239,5 @@ namespace Seele
void *windowHandle; void *windowHandle;
}; };
DECLARE_REF(Viewport); DECLARE_REF(Viewport);
} } // namespace Vulkan
} } // namespace Seele
@@ -743,11 +743,11 @@ VkPipelineShaderStageCreateInfo init::PipelineShaderStageCreateInfo(VkShaderStag
} }
VkBool32 debugCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t obj, size_t location, int32_t code, const char* layerPrefix, const char* msg, void* userDataManager) { VkBool32 Seele::Vulkan::debugCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t obj, size_t location, int32_t code, const char* layerPrefix, const char* msg, void* userDataManager) {
std::cerr << layerPrefix << ": " << msg << std::endl; std::cerr << layerPrefix << ": " << msg << std::endl;
return VK_FALSE; return VK_FALSE;
} }
VkResult CreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDebugReportCallbackEXT* pCallback) { VkResult Seele::Vulkan::CreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDebugReportCallbackEXT* pCallback) {
auto func = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(instance, "vkCreateDebugReportCallbackEXT"); auto func = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(instance, "vkCreateDebugReportCallbackEXT");
if (func != nullptr) { if (func != nullptr) {
return func(instance, pCreateInfo, pAllocator, pCallback); return func(instance, pCreateInfo, pAllocator, pCallback);
@@ -757,7 +757,7 @@ VkResult CreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCa
} }
} }
void DestroyDebugReportCallbackEXT(VkInstance instance, const VkAllocationCallbacks* pAllocator, VkDebugReportCallbackEXT pCallback) void Seele::Vulkan::DestroyDebugReportCallbackEXT(VkInstance instance, const VkAllocationCallbacks* pAllocator, VkDebugReportCallbackEXT pCallback)
{ {
auto func = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(instance, "vkDestroyDebugReportCallbackEXT"); auto func = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(instance, "vkDestroyDebugReportCallbackEXT");
if (func != nullptr) { if (func != nullptr) {
@@ -1,3 +1,4 @@
#pragma once
#include "Containers/Array.h" #include "Containers/Array.h"
#include <vulkan/vulkan.h> #include <vulkan/vulkan.h>
@@ -0,0 +1,19 @@
#include "VulkanQueue.h"
#include "VulkanInitializer.h"
#include "VulkanGraphics.h"
using namespace Seele;
using namespace Seele::Vulkan;
Queue::Queue(WGraphics graphics, QueueType queueType, uint32 familyIndex, uint32 queueIndex)
: familyIndex(familyIndex)
, graphics(graphics)
, queueType(queueType)
{
vkGetDeviceQueue(graphics->getDevice(), familyIndex, queueIndex, &queue);
}
Queue::~Queue()
{
}
+36
View File
@@ -0,0 +1,36 @@
#pragma once
#include "VulkanGraphicsResources.h"
namespace Seele
{
namespace Vulkan
{
DECLARE_REF(CmdBuffer);
DECLARE_REF(Graphics);
class Queue
{
public:
Queue(WGraphics graphics, QueueType queueType, uint32 familyIndex, uint32 queueIndex);
virtual ~Queue();
void submitCommandBuffer(PCmdBuffer cmdBuffer, uint32 numSignalSemaphores = 0, VkSemaphore* signalSemaphore = nullptr);
inline void submitCommandBuffer(PCmdBuffer cmdBuffer, VkSemaphore signalSemaphore)
{
submitCommandBuffer(cmdBuffer, 1, &signalSemaphore);
}
uint32 getFamilyIndex() const
{
return familyIndex;
}
inline VkQueue getHandle() const
{
return queue;
}
private:
WGraphics graphics;
VkQueue queue;
uint32 familyIndex;
QueueType queueType;
};
DEFINE_REF(Queue)
}
}
@@ -0,0 +1,40 @@
#include "VulkanGraphicsResources.h"
namespace Seele
{
namespace Vulkan
{
class RenderPass
{
public:
RenderPass();
virtual ~RenderPass();
inline VkRenderPass getHandle() const
{
return renderPass;
}
inline uint32 getClearValueCount() const
{
return clearValues.size();
}
inline VkClearValue* getClearValues() const
{
return clearValues.data();
}
inline VkRect2D getRenderArea() const
{
return renderArea;
}
inline VkSubpassContents getSubpassContents() const
{
return subpassContents;
}
private:
VkRenderPass renderPass;
Array<VkClearValue> clearValues;
VkRect2D renderArea;
VkSubpassContents subpassContents;
};
DEFINE_REF(RenderPass);
}
}
+1 -1
View File
@@ -3,7 +3,7 @@
Seele::WindowManager::WindowManager() Seele::WindowManager::WindowManager()
{ {
graphics = new VulkanGraphics(); graphics = new Vulkan::Graphics();
GraphicsInitializer initializer; GraphicsInitializer initializer;
graphics->init(initializer); graphics->init(initializer);
} }
+19 -8
View File
@@ -43,7 +43,6 @@ namespace Seele
{ {
} }
~RefObject() ~RefObject()
{} {}
bool operator==(const RefObject& other) const bool operator==(const RefObject& other) const
@@ -81,6 +80,10 @@ namespace Seele
{ {
object = nullptr; object = nullptr;
} }
RefPtr(nullptr_t)
{
object = nullptr;
}
RefPtr(T* ptr) RefPtr(T* ptr)
{ {
object = new RefObject<T>(ptr); object = new RefObject<T>(ptr);
@@ -160,14 +163,19 @@ namespace Seele
private: private:
RefObject<T>* object; RefObject<T>* object;
}; };
//A weak pointer has no ownership over an object and thus cant delete it
template<typename T> template<typename T>
class WeakPtr class WeakPtr
{ {
public: public:
WeakPtr() WeakPtr()
: pointer(nullptr)
{}
WeakPtr(T* ptr)
: pointer(ptr)
{} {}
WeakPtr(RefPtr<T>& sharedPtr) WeakPtr(RefPtr<T>& sharedPtr)
: pointer(sharedPtr.object) : pointer(sharedPtr.object->handle)
{} {}
WeakPtr& operator=(WeakPtr<T>& weakPtr) WeakPtr& operator=(WeakPtr<T>& weakPtr)
{ {
@@ -176,17 +184,20 @@ namespace Seele
} }
WeakPtr& operator=(RefPtr<T>& sharedPtr) WeakPtr& operator=(RefPtr<T>& sharedPtr)
{ {
pointer = sharedPtr; pointer = sharedPtr.object->handle;
return *this; return *this;
} }
RefPtr<T>& lock() WeakPtr& operator=(T* ptr)
{ {
RefPtr<T> temp; pointer = ptr;
temp.object = pointer; return *this;
return temp; }
inline T* operator->()
{
return pointer;
} }
private: private:
RefObject<T>* pointer; T* pointer;
}; };
template<typename T> template<typename T>
class UniquePtr class UniquePtr