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);
}
}
+123 -18
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,23 +28,28 @@ 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)
{ {
GLFWwindow* window = static_cast<GLFWwindow*>(windowHandle); GLFWwindow *window = static_cast<GLFWwindow *>(windowHandle);
glfwPollEvents(); glfwPollEvents();
} }
void Graphics::endFrame(void* windowHandle) void Graphics::endFrame(void *windowHandle)
{ {
GLFWwindow* window = static_cast<GLFWwindow*>(windowHandle); GLFWwindow *window = static_cast<GLFWwindow *>(windowHandle);
} }
void* Graphics::createWindow(const WindowCreateInfo& createInfo) void *Graphics::createWindow(const WindowCreateInfo &createInfo)
{ {
GLFWwindow* window = glfwCreateWindow(createInfo.width, createInfo.height, createInfo.title, createInfo.bFullscreen ? glfwGetPrimaryMonitor() : nullptr, nullptr); GLFWwindow *window = glfwCreateWindow(createInfo.width, createInfo.height, createInfo.title, createInfo.bFullscreen ? glfwGetPrimaryMonitor() : nullptr, nullptr);
return window; return window;
} }
@@ -56,14 +63,15 @@ VkPhysicalDevice Graphics::getPhysicalDevice() const
return physicalDevice; return physicalDevice;
} }
Array<const char*> Graphics::getRequiredExtensions() Array<const char *> Graphics::getRequiredExtensions()
{ {
Array<const char*> extensions; Array<const char *> extensions;
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
@@ -84,7 +92,7 @@ void Graphics::initInstance(GraphicsInitializer initInfo)
VkInstanceCreateInfo info = {}; VkInstanceCreateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
info.pApplicationInfo = &appInfo; info.pApplicationInfo = &appInfo;
Array<const char*> extensions = getRequiredExtensions(); Array<const char *> extensions = getRequiredExtensions();
for (uint32 i = 0; i < initInfo.instanceExtensions.size(); ++i) for (uint32 i = 0; i < initInfo.instanceExtensions.size(); ++i)
{ {
extensions.add(initInfo.instanceExtensions[i]); extensions.add(initInfo.instanceExtensions[i]);
@@ -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()
{
}
@@ -4,189 +4,240 @@
namespace Seele namespace Seele
{ {
namespace Vulkan namespace Vulkan
{
DECLARE_REF(DescriptorAllocator);
DECLARE_REF(CommandBufferManager);
DECLARE_REF(Graphics);
class Semaphore
{
public:
Semaphore(WGraphics graphics);
virtual ~Semaphore();
private:
VkSemaphore handle;
WGraphics graphics;
};
DEFINE_REF(Semaphore);
class DescriptorLayout : public Gfx::DescriptorLayout
{
public:
DescriptorLayout(WGraphics graphics)
: graphics(graphics), layoutHandle(VK_NULL_HANDLE)
{ {
DECLARE_REF(DescriptorAllocator);
DECLARE_REF(Graphics);
class DescriptorLayout : public Gfx::DescriptorLayout
{
public:
DescriptorLayout(PGraphics graphics)
: graphics(graphics)
, layoutHandle(VK_NULL_HANDLE)
{}
virtual ~DescriptorLayout();
virtual void create();
inline VkDescriptorSetLayout getHandle() const
{
return layoutHandle;
}
private:
PGraphics graphics;
Array<VkDescriptorSetLayoutBinding> bindings;
VkDescriptorSetLayout layoutHandle;
friend class PipelineStateCacheManager;
};
DEFINE_REF(DescriptorLayout);
class PipelineLayout : public Gfx::PipelineLayout
{
public:
PipelineLayout(PGraphics graphics)
: graphics(graphics)
, layoutHash(0)
, layoutHandle(VK_NULL_HANDLE)
{}
virtual ~PipelineLayout();
virtual void create();
inline VkPipelineLayout getHandle() const
{
return layoutHandle;
}
virtual uint32 getHash() const
{
return layoutHash;
}
private:
Array<VkDescriptorSetLayout> vulkanDescriptorLayouts;
uint32 layoutHash;
VkPipelineLayout layoutHandle;
PGraphics graphics;
friend class PipelineStateCacheManager;
};
DEFINE_REF(PipelineLayout);
class DescriptorSet : public Gfx::DescriptorSet
{
public:
DescriptorSet(PGraphics graphics, PDescriptorAllocator owner)
: graphics(graphics)
, owner(owner)
, setHandle(VK_NULL_HANDLE)
{}
virtual ~DescriptorSet();
virtual void updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer);
virtual void updateBuffer(uint32_t binding, Gfx::PStructuredBuffer uniformBuffer);
virtual void updateSampler(uint32_t binding, Gfx::PSamplerState samplerState);
virtual void updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSamplerState sampler = nullptr);
virtual bool operator<(Gfx::PDescriptorSet other);
inline VkDescriptorSet getHandle() const
{
return setHandle;
}
private:
virtual void writeChanges();
Array<VkDescriptorImageInfo> imageInfos;
Array<VkDescriptorBufferInfo> bufferInfos;
Array<VkWriteDescriptorSet> writeDescriptors;
VkDescriptorSet setHandle;
PDescriptorAllocator owner;
PGraphics graphics;
friend class DescriptorAllocator;
};
DEFINE_REF(DescriptorSet);
class DescriptorAllocator : public Gfx::DescriptorAllocator
{
public:
DescriptorAllocator(PGraphics graphics, DescriptorLayout& layout);
~DescriptorAllocator();
virtual void allocateDescriptorSet(Gfx::PDescriptorSet& descriptorSet);
inline VkDescriptorPool getHandle()
{
return poolHandle;
}
private:
PGraphics graphics;
int maxSets = 512;
VkDescriptorPool poolHandle;
DescriptorLayout& layout;
};
DEFINE_REF(DescriptorAllocator);
enum class QueueType
{
GRAPHICS = 1,
COMPUTE = 2,
TRANSFER = 3
};
class QueueOwnedResource
{
public:
QueueOwnedResource(PGraphics graphics, QueueType startQueueType);
~QueueOwnedResource();
CommandBufferManager* getCommands();
//Preliminary checks to see if the barrier should be executed at all
void transferOwnership(QueueType newOwner);
protected:
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
QueueType currentOwner;
PGraphics graphics;
CommandBufferManager* cachedCmdBufferManager;
};
DEFINE_REF(QueueOwnedResource);
class Buffer : public QueueOwnedResource
{
public:
Buffer(PGraphics graphics, uint32 size, VkBufferUsageFlags usage);
virtual ~Buffer();
private:
virtual VkAccessFlags getSourceAccessMask() = 0;
virtual VkAccessFlags getDestAccessMask() = 0;
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(QueueType newOwner);
};
DEFINE_REF(Buffer);
class UniformBuffer : public Gfx::UniformBuffer
{
};
DEFINE_REF(UniformBuffer);
class StructuredBuffer : public Gfx::StructuredBuffer
{
};
DEFINE_REF(StructuredBuffer);
class TextureBase
{
private:
uint32 sizeX;
uint32 sizeY;
uint32 sizeZ;
uint32 arrayCount;
uint32 layerCount;
};
DEFINE_REF(TextureBase);
class Texture2D : public Gfx::Texture2D
{
public:
private:
PTextureBase textureHandle;
};
DEFINE_REF(Texture2D);
class SamplerState
{
public:
VkSampler sampler;
};
DEFINE_REF(SamplerState);
class Viewport : public Gfx::Viewport
{
public:
private:
uint32 sizeX;
uint32 sizeY;
uint32 offsetX;
uint32 offsetY;
VkSwapchainKHR swapchain;
void* windowHandle;
};
DECLARE_REF(Viewport);
} }
} virtual ~DescriptorLayout();
virtual void create();
inline VkDescriptorSetLayout getHandle() const
{
return layoutHandle;
}
private:
WGraphics graphics;
Array<VkDescriptorSetLayoutBinding> bindings;
VkDescriptorSetLayout layoutHandle;
friend class PipelineStateCacheManager;
};
DEFINE_REF(DescriptorLayout);
class PipelineLayout : public Gfx::PipelineLayout
{
public:
PipelineLayout(WGraphics graphics)
: graphics(graphics), layoutHash(0), layoutHandle(VK_NULL_HANDLE)
{
}
virtual ~PipelineLayout();
virtual void create();
inline VkPipelineLayout getHandle() const
{
return layoutHandle;
}
virtual uint32 getHash() const
{
return layoutHash;
}
private:
Array<VkDescriptorSetLayout> vulkanDescriptorLayouts;
uint32 layoutHash;
VkPipelineLayout layoutHandle;
WGraphics graphics;
friend class PipelineStateCacheManager;
};
DEFINE_REF(PipelineLayout);
class DescriptorSet : public Gfx::DescriptorSet
{
public:
DescriptorSet(WGraphics graphics, PDescriptorAllocator owner)
: graphics(graphics), owner(owner), setHandle(VK_NULL_HANDLE)
{
}
virtual ~DescriptorSet();
virtual void updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer);
virtual void updateBuffer(uint32_t binding, Gfx::PStructuredBuffer uniformBuffer);
virtual void updateSampler(uint32_t binding, Gfx::PSamplerState samplerState);
virtual void updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSamplerState sampler = nullptr);
virtual bool operator<(Gfx::PDescriptorSet other);
inline VkDescriptorSet getHandle() const
{
return setHandle;
}
private:
virtual void writeChanges();
Array<VkDescriptorImageInfo> imageInfos;
Array<VkDescriptorBufferInfo> bufferInfos;
Array<VkWriteDescriptorSet> writeDescriptors;
VkDescriptorSet setHandle;
PDescriptorAllocator owner;
WGraphics graphics;
friend class DescriptorAllocator;
};
DEFINE_REF(DescriptorSet);
class DescriptorAllocator : public Gfx::DescriptorAllocator
{
public:
DescriptorAllocator(WGraphics graphics, DescriptorLayout &layout);
~DescriptorAllocator();
virtual void allocateDescriptorSet(Gfx::PDescriptorSet &descriptorSet);
inline VkDescriptorPool getHandle()
{
return poolHandle;
}
private:
WGraphics graphics;
int maxSets = 512;
VkDescriptorPool poolHandle;
DescriptorLayout &layout;
};
DEFINE_REF(DescriptorAllocator);
enum class QueueType
{
GRAPHICS = 1,
COMPUTE = 2,
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
{
public:
QueueOwnedResource(WGraphics graphics, QueueType startQueueType);
~QueueOwnedResource();
PCommandBufferManager getCommands();
//Preliminary checks to see if the barrier should be executed at all
void transferOwnership(QueueType newOwner);
protected:
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
QueueType currentOwner;
WGraphics graphics;
CommandBufferManager *cachedCmdBufferManager;
};
DEFINE_REF(QueueOwnedResource);
class Buffer : public QueueOwnedResource
{
public:
Buffer(WGraphics graphics, uint32 size, VkBufferUsageFlags usage);
virtual ~Buffer();
private:
virtual VkAccessFlags getSourceAccessMask() = 0;
virtual VkAccessFlags getDestAccessMask() = 0;
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(QueueType newOwner);
};
DEFINE_REF(Buffer);
class UniformBuffer : public Buffer, public Gfx::UniformBuffer
{
};
DEFINE_REF(UniformBuffer);
class StructuredBuffer : public Buffer, public Gfx::StructuredBuffer
{
};
DEFINE_REF(StructuredBuffer);
class TextureBase
{
public:
TextureBase();
virtual ~TextureBase();
private:
uint32 sizeX;
uint32 sizeY;
uint32 sizeZ;
uint32 arrayCount;
uint32 layerCount;
VkImage image;
};
DEFINE_REF(TextureBase);
class Texture2D : public Gfx::Texture2D
{
public:
private:
PTextureBase textureHandle;
};
DEFINE_REF(Texture2D);
class SamplerState
{
public:
VkSampler sampler;
};
DEFINE_REF(SamplerState);
class Viewport : public Gfx::Viewport
{
public:
private:
uint32 sizeX;
uint32 sizeY;
uint32 offsetX;
uint32 offsetY;
VkSwapchainKHR swapchain;
void *windowHandle;
};
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