Fixing memory leak with RefPtr

This commit is contained in:
Dynamitos
2020-04-01 02:17:49 +02:00
parent 62c2d37cb3
commit 3ba8f2c2a0
37 changed files with 1675 additions and 270 deletions
+30
View File
@@ -0,0 +1,30 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Engine",
"type": "cppvsdbg",
"request": "launch",
"program": "${workspaceRoot}/bin/Debug/SeeleEngine.exe",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}/bin/Debug",
"environment": [],
"externalConsole": false
},
{
"name": "Test",
"type": "cppvsdbg",
"request": "launch",
"program": "${workspaceRoot}/bin/Debug/test/Seele_unit_tests.exe",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceRoot}/bin/Debug/test",
"environment": [],
"externalConsole": false
}
]
}
+9 -1
View File
@@ -2,7 +2,15 @@
"C_Cpp.default.configurationProvider": "go2sh.cmake-integration",
"telemetry.enableTelemetry": false,
"cmake.buildDirectory": "${workspaceFolder}/bin/${buildType}",
"git.autofetch": false,
"files.associations": {
"xstring": "cpp"
"*.h": "cpp",
"xstring": "cpp",
"list": "cpp",
"xhash": "cpp",
"xiosbase": "cpp",
"xmemory": "cpp",
"xtree": "cpp",
"type_traits": "cpp"
}
}
+2 -4
View File
@@ -61,9 +61,8 @@ if(WIN32)
ExternalProject_Add(slang
SOURCE_DIR ${SLANG_ROOT}
BINARY_DIR ${CMAKE_BINARY_DIR}/lib
CONFIGURE_COMMAND ""
BUILD_COMMAND devenv /upgrade ${SLANG_ROOT}/source/slang/slang.vcxproj
COMMAND msbuild -p:Configuration=${CMAKE_BUILD_TYPE} -p:Platform=${CMAKE_PLATFORM} -p:WindowsTargetPlatformVersion=10.0 ${SLANG_ROOT}/source/slang/slang.vcxproj
CONFIGURE_COMMAND devenv /upgrade ${SLANG_ROOT}/source/slang/slang.vcxproj
BUILD_COMMAND msbuild -p:Configuration=${CMAKE_BUILD_TYPE} -p:Platform=${CMAKE_PLATFORM} -p:WindowsTargetPlatformVersion=10.0 ${SLANG_ROOT}/source/slang/slang.vcxproj
INSTALL_COMMAND "")
string(TOLOWER bin/windows-${CMAKE_PLATFORM}/${CMAKE_BUILD_TYPE}/slang.dll SLANG_BINARY)
@@ -79,7 +78,6 @@ ExternalProject_Add(slang
string(TOLOWER bin/linux-${CMAKE_PLATFORM}/${CMAKE_BUILD_TYPE}/libslang.so SLANG_BINARY)
set(SLANG_LIB_PATH)
endif()
+1
View File
@@ -1,6 +1,7 @@
target_sources(SeeleEngine
PRIVATE
MinimalEngine.h
MinimalEngine.cpp
main.cpp)
add_subdirectory(Graphics/)
+36 -6
View File
@@ -1,5 +1,7 @@
#pragma once
#include "MinimalEngine.h"
#include "EngineTypes.h"
#include <initializer_list>
#include <iterator>
#include <assert.h>
#ifndef DEFAULT_ALLOC_SIZE
@@ -95,11 +97,15 @@ namespace Seele
_data = other._data;
other._data = nullptr;
}
return *this;
}
~Array()
{
free(_data);
_data = nullptr;
if(_data)
{
free(_data);
_data = nullptr;
}
}
template<typename X>
class IteratorBase {
@@ -132,7 +138,7 @@ namespace Seele
{
return p == other.p;
}
inline bool operator-(const IteratorBase& other)
inline int operator-(const IteratorBase& other)
{
return p - other.p;
}
@@ -140,17 +146,36 @@ namespace Seele
p++;
return *this;
}
IteratorBase& operator--() {
p--;
return *this;
}
IteratorBase operator++(int) {
IteratorBase tmp(*this);
++*this;
return tmp;
}
IteratorBase operator--(int) {
IteratorBase tmp(*this);
--*this;
return tmp;
}
private:
X* p;
};
typedef IteratorBase<T> Iterator;
typedef IteratorBase<const T> ConstIterator;
bool operator==(const Array& other)
{
return _data == other._data;
}
bool operator!=(const Array& other)
{
return !(*this == other);
}
Iterator find(const T& item)
{
for (int i = 0; i < arraySize; ++i)
@@ -179,8 +204,8 @@ namespace Seele
allocated = calculateGrowth(newSize);
void* tempArray = malloc(sizeof(T) * allocated);
assert(tempArray != nullptr);
std::memset(tempArray, 0, sizeof(T) * allocated);
std::memcpy(tempArray, _data, arraySize * sizeof(T));
memset(tempArray, 0, sizeof(T) * allocated);
delete _data;
_data = (T*)tempArray;
}
@@ -218,7 +243,8 @@ namespace Seele
}
else
{
T* newData = new T[newSize];
T* newData = (T*)malloc(newSize * sizeof(T));
assert(newData != nullptr);
allocated = newSize;
std::memcpy(newData, _data, sizeof(T) * arraySize);
arraySize = newSize;
@@ -243,6 +269,10 @@ namespace Seele
{
return _data[arraySize - 1];
}
void pop()
{
arraySize--;
}
T& operator[](int index) const
{
assert(index >= 0 && index < arraySize);
+93 -19
View File
@@ -37,6 +37,17 @@ namespace Seele
, rightChild(nullptr)
, pair(K(), V())
{}
~Node()
{
if(leftChild != nullptr)
{
delete leftChild;
}
if(rightChild != nullptr)
{
delete rightChild;
}
}
};
public:
@@ -44,16 +55,8 @@ namespace Seele
: root(nullptr)
{}
~Map()
{}
V& operator[](const K& key)
{
root = splay(root, key);
if (root == nullptr || root->pair.key < key || key < root->pair.key)
{
root = insert(root, key);
}
refreshIterators();
return root->pair.value;
delete root;
}
class Iterator {
public:
@@ -65,10 +68,14 @@ namespace Seele
Iterator(Node* x = nullptr)
: node(x)
{
}
{}
Iterator(Node* x, Array<Node*>&& beginIt)
: node(x)
, traversal(std::move(beginIt))
{}
Iterator(const Iterator& i)
: node(i.node)
, traversal(i.traversal)
{}
reference operator*() const
{
@@ -87,11 +94,31 @@ namespace Seele
return node == other.node;
}
Iterator& operator++() {
node++;
node = node->rightChild;
while(node != nullptr && node->leftChild != nullptr)
{
traversal.add(node);
node = node->leftChild;
}
if(node == nullptr && traversal.size() > 0)
{
node = traversal.back();
traversal.pop();
}
return *this;
}
Iterator& operator--() {
node--;
node = node->leftChild;
while(node != nullptr && node->rightchild != nullptr)
{
traversal.add(node);
node = node->rightChild;
}
if(node == nullptr && traversal.size() > 0)
{
node = traversal.back();
traversal.pop();
}
return *this;
}
Iterator operator--(int) {
@@ -106,7 +133,18 @@ namespace Seele
}
private:
Node* node;
Array<Node*> traversal;
};
V& operator[](const K& key)
{
root = splay(root, key);
if (root == nullptr || root->pair.key < key || key < root->pair.key)
{
root = insert(root, key);
}
refreshIterators();
return root->pair.value;
}
Iterator find(const K& key)
{
root = splay(root, key);
@@ -116,6 +154,12 @@ namespace Seele
}
return Iterator(root);
}
Iterator erase(const K& key)
{
root = remove(root, key);
refreshIterators();
return Iterator(root);
}
bool exists(const K& key)
{
return find(key) != endIt;
@@ -131,11 +175,40 @@ namespace Seele
private:
void refreshIterators()
{
beginIt = Iterator(&nodes[0]);
endIt = Iterator(&nodes[0] + nodes.size());
Node* beginNode = root;
if(root == nullptr)
{
beginIt = Iterator(nullptr);
}
else
{
Array<Node*> beginTraversal;
while(beginNode != nullptr)
{
beginTraversal.add(beginNode);
beginNode = beginNode->leftChild;
}
beginNode = beginTraversal.back();
beginTraversal.pop();
beginIt = Iterator(beginNode, std::move(beginTraversal));
}
Node* endNode = root;
if(root == nullptr)
{
endIt = Iterator(nullptr);
}
else
{
Array<Node*> endTraversal;
while(endNode != nullptr)
{
endTraversal.add(endNode);
endNode = endNode->rightChild;
}
endIt = Iterator(endNode, std::move(endTraversal));
}
}
Node* root;
Array<Node> nodes;
Iterator beginIt;
Iterator endIt;
Node* rotateRight(Node* node)
@@ -154,7 +227,7 @@ namespace Seele
}
Node* makeNode(const K& key)
{
return &nodes.add(Node(key));
return new Node(key);
}
Node* insert(Node* root, const K& key)
{
@@ -188,7 +261,7 @@ namespace Seele
root = splay(root, key);
if (key != root->pair.key)
if (root->pair.key < key || key < root->pair.key)
return root;
if (!root->leftChild)
@@ -203,7 +276,8 @@ namespace Seele
root = splay(root->leftChild, key);
root->rightChild = temp->rightChild;
}
nodes.remove(temp);
temp->leftChild = nullptr;
temp->rightChild = nullptr;
delete temp;
return root;
}
+14
View File
@@ -0,0 +1,14 @@
#include <stdint.h>
namespace Seele
{
typedef uint64_t uint64;
typedef uint32_t uint32;
typedef uint16_t uint16;
typedef uint8_t uint8;
typedef int64_t int64;
typedef int32_t int32;
typedef int16_t int16;
typedef int8_t int8;
}
+37
View File
@@ -52,3 +52,40 @@ void PipelineLayout::addPushConstants(const SePushConstantRange& pushConstant)
{
pushConstants.add(pushConstant);
}
RenderTargetLayout::RenderTargetLayout()
: inputAttachments()
, colorAttachments()
, depthAttachment()
{
}
RenderTargetLayout::RenderTargetLayout(PTexture2D depthAttachment)
: inputAttachments()
, colorAttachments()
, depthAttachment(depthAttachment)
{
}
RenderTargetLayout::RenderTargetLayout(PTexture2D colorAttachment, PTexture2D depthAttachment)
: inputAttachments()
, depthAttachment(depthAttachment)
{
colorAttachments.add(colorAttachment);
}
RenderTargetLayout::RenderTargetLayout(Array<PTexture2D> colorAttachments, PTexture2D depthAttachmet)
: inputAttachments()
, colorAttachments(colorAttachments)
, depthAttachment(depthAttachment)
{
}
RenderTargetLayout::RenderTargetLayout(Array<PTexture2D> inputAttachments, Array<PTexture2D> colorAttachments, PTexture2D depthAttachment)
: inputAttachments(inputAttachments)
, colorAttachments(colorAttachments)
, depthAttachment(depthAttachment)
{
}
+19
View File
@@ -212,9 +212,28 @@ namespace Seele
DEFINE_REF(Texture);
class Texture2D : public Texture
{
public:
virtual ~Texture2D()
{
}
};
DEFINE_REF(Texture2D);
class RenderTargetLayout
{
public:
RenderTargetLayout();
RenderTargetLayout(PTexture2D depthAttachment);
RenderTargetLayout(PTexture2D colorAttachment, PTexture2D depthAttachment);
RenderTargetLayout(Array<PTexture2D> colorAttachments, PTexture2D depthAttachmet);
RenderTargetLayout(Array<PTexture2D> inputAttachments, Array<PTexture2D> colorAttachments, PTexture2D depthAttachment);
Array<PTexture2D> inputAttachments;
Array<PTexture2D> colorAttachments;
PTexture2D depthAttachment;
};
DEFINE_REF(RenderTargetLayout);
class RenderPass
{
+5
View File
@@ -21,6 +21,11 @@ void Seele::RenderCore::init()
void Seele::RenderCore::renderLoop()
{
while(windowManager->isActive())
{
windowManager->beginFrame();
windowManager->endFrame();
}
}
void Seele::RenderCore::shutdown()
@@ -18,5 +18,6 @@ target_sources(SeeleEngine
VulkanInitializer.cpp
VulkanRenderPass.h
VulkanRenderPass.cpp
VulkanTexture.cpp
VulkanQueue.h
VulkanQueue.cpp)
@@ -14,7 +14,7 @@ SubAllocation::SubAllocation(Allocation* owner, uint32 allocatedOffset, uint32 s
{
}
Allocation::Allocation(WGraphics graphics, Allocator* allocator, uint32 size, uint32 memoryTypeIndex, VkMemoryPropertyFlags properties, bool isDedicated)
Allocation::Allocation(PGraphics graphics, Allocator* allocator, uint32 size, uint32 memoryTypeIndex, VkMemoryPropertyFlags properties, bool isDedicated)
: device(graphics->getDevice())
, allocator(allocator)
, bytesAllocated(0)
@@ -74,7 +74,7 @@ PSubAllocation Allocation::getSuballocation(uint32 requestedSize, uint32 alignme
return nullptr;
}
Allocator::Allocator(WGraphics graphics)
Allocator::Allocator(PGraphics graphics)
: graphics(graphics)
{
vkGetPhysicalDeviceMemoryProperties(graphics->getPhysicalDevice(), &memProperties);
@@ -119,5 +119,6 @@ VkResult Allocator::findMemoryType(uint32 typeBits, VkMemoryPropertyFlags proper
}
typeBits >>= 1;
}
return VK_ERROR_FORMAT_NOT_SUPPORTED;
}
+3 -3
View File
@@ -28,7 +28,7 @@ namespace Seele
class Allocation
{
public:
Allocation(WGraphics graphics, Allocator* allocator, uint32 size, uint32 memoryTypeIndex, VkMemoryPropertyFlags properties, bool isDedicated);
Allocation(PGraphics graphics, Allocator* allocator, uint32 size, uint32 memoryTypeIndex, VkMemoryPropertyFlags properties, bool isDedicated);
PSubAllocation getSuballocation(uint32 size, uint32 alignment);
private:
Allocator* allocator;
@@ -50,7 +50,7 @@ namespace Seele
class Allocator
{
public:
Allocator(WGraphics graphics);
Allocator(PGraphics graphics);
~Allocator();
PSubAllocation allocate(uint64 size, const VkMemoryRequirements2& requirements, VkMemoryPropertyFlags props);
@@ -66,7 +66,7 @@ namespace Seele
};
Array<HeapInfo> heaps;
VkResult findMemoryType(uint32 typeBits, VkMemoryPropertyFlags properties, uint32* typeIndex);
WGraphics graphics;
PGraphics graphics;
VkPhysicalDeviceMemoryProperties memProperties;
};
DEFINE_REF(Allocator);
+2 -2
View File
@@ -4,7 +4,7 @@
using namespace Seele;
using namespace Seele::Vulkan;
QueueOwnedResource::QueueOwnedResource(WGraphics graphics, QueueType startQueueType)
QueueOwnedResource::QueueOwnedResource(PGraphics graphics, QueueType startQueueType)
: graphics(graphics)
, currentOwner(startQueueType)
{
@@ -14,7 +14,7 @@ QueueOwnedResource::~QueueOwnedResource()
{
}
Buffer::Buffer(WGraphics graphics, uint32 size, VkBufferUsageFlags usage, QueueType queueType)
Buffer::Buffer(PGraphics graphics, uint32 size, VkBufferUsageFlags usage, QueueType queueType)
: QueueOwnedResource(graphics, queueType)
{
}
@@ -8,7 +8,7 @@
using namespace Seele;
using namespace Seele::Vulkan;
CmdBufferBase::CmdBufferBase(WGraphics graphics, VkCommandPool cmdPool)
CmdBufferBase::CmdBufferBase(PGraphics graphics, VkCommandPool cmdPool)
: graphics(graphics)
, owner(cmdPool)
{
@@ -19,7 +19,7 @@ CmdBufferBase::~CmdBufferBase()
{
}
CmdBuffer::CmdBuffer(WGraphics graphics, VkCommandPool cmdPool)
CmdBuffer::CmdBuffer(PGraphics graphics, VkCommandPool cmdPool)
: CmdBufferBase(graphics, cmdPool)
, renderPass(nullptr)
, framebuffer(nullptr)
@@ -54,7 +54,7 @@ void CmdBuffer::end()
state = State::Ended;
}
void CmdBuffer::beginRenderPass(WRenderPass renderPass, WFramebuffer framebuffer)
void CmdBuffer::beginRenderPass(PRenderPass renderPass, PFramebuffer framebuffer)
{
VkRenderPassBeginInfo beginInfo =
init::RenderPassBeginInfo();
@@ -71,7 +71,7 @@ void CmdBuffer::endRenderPass()
vkCmdEndRenderPass(handle);
}
SecondaryCmdBuffer::SecondaryCmdBuffer(WGraphics graphics, VkCommandPool cmdPool)
SecondaryCmdBuffer::SecondaryCmdBuffer(PGraphics graphics, VkCommandPool cmdPool)
: CmdBufferBase(graphics, cmdPool)
{
VkCommandBufferAllocateInfo allocInfo =
@@ -86,7 +86,7 @@ SecondaryCmdBuffer::~SecondaryCmdBuffer()
vkFreeCommandBuffers(graphics->getDevice(), owner, 1, &handle);
}
void SecondaryCmdBuffer::begin(WCmdBuffer parent)
void SecondaryCmdBuffer::begin(PCmdBuffer parent)
{
VkCommandBufferBeginInfo beginInfo =
init::CommandBufferBeginInfo();
@@ -104,7 +104,7 @@ void SecondaryCmdBuffer::end()
VK_CHECK(vkEndCommandBuffer(handle));
}
CommandBufferManager::CommandBufferManager(WGraphics graphics, WQueue queue)
CommandBufferManager::CommandBufferManager(PGraphics graphics, PQueue queue)
: graphics(graphics)
, queue(queue)
{
@@ -131,9 +131,45 @@ PCmdBuffer CommandBufferManager::getCommands()
PSecondaryCmdBuffer CommandBufferManager::createSecondaryCmdBuffer()
{
return PSecondaryCmdBuffer();
return new SecondaryCmdBuffer(graphics, commandPool);
}
void Seele::Vulkan::CommandBufferManager::submitCommands(PSemaphore signalSemaphore)
void CommandBufferManager::submitCommands(PSemaphore signalSemaphore)
{
if(activeCmdBuffer->state == CmdBuffer::State::InsideBegin
|| activeCmdBuffer->state == CmdBuffer::State::RenderPassActive)
{
if(!activeCmdBuffer->state == CmdBuffer::State::RenderPassActive)
{
std::cout << "End of renderpass forced" << std::endl;
activeCmdBuffer->endRenderPass();
}
activeCmdBuffer->end();
if(signalSemaphore != nullptr)
{
queue->submitCommandBuffer(activeCmdBuffer, signalSemaphore->getHandle());
}
else
{
queue->submitCommandBuffer(activeCmdBuffer);
}
}
for(int32_t i = 0; i < allocatedBuffers.size(); ++i)
{
PCmdBuffer cmdBuffer = allocatedBuffers[i];
cmdBuffer->refreshFences();
if(cmdBuffer->state == CmdBuffer::State::ReadyBegin)
{
activeCmdBuffer = cmdBuffer;
activeCmdBuffer->begin();
return;
}
else
{
assert(cmdBuffer->state == CmdBuffer::State::Submitted);
}
}
activeCmdBuffer = new CmdBuffer(graphics, commandPool);
allocatedBuffers.add(activeCmdBuffer);
activeCmdBuffer->begin();
}
@@ -11,7 +11,7 @@ namespace Seele
class CmdBufferBase : public Gfx::RenderCommandBase
{
public:
CmdBufferBase(WGraphics graphics, VkCommandPool cmdPool);
CmdBufferBase(PGraphics graphics, VkCommandPool cmdPool);
virtual ~CmdBufferBase();
inline VkCommandBuffer getHandle()
{
@@ -21,7 +21,7 @@ namespace Seele
VkViewport currentViewport;
VkRect2D currentScissor;
protected:
WGraphics graphics;
PGraphics graphics;
VkCommandBuffer handle;
VkCommandPool owner;
};
@@ -31,13 +31,13 @@ namespace Seele
class CmdBuffer : public CmdBufferBase
{
public:
CmdBuffer(WGraphics graphics, VkCommandPool cmdPool);
CmdBuffer(PGraphics graphics, VkCommandPool cmdPool);
virtual ~CmdBuffer();
void begin();
void end();
void beginRenderPass(WRenderPass renderPass, WFramebuffer framebuffer);
void beginRenderPass(PRenderPass renderPass, PFramebuffer framebuffer);
void endRenderPass();
void executeCommands(Array<WSecondaryCmdBuffer> secondaryCommands);
void executeCommands(Array<PSecondaryCmdBuffer> secondaryCommands);
void addWaitSemaphore(VkPipelineStageFlags stages, PSemaphore waitSemaphore);
enum State
{
@@ -49,20 +49,21 @@ namespace Seele
};
private:
WRenderPass renderPass;
WFramebuffer framebuffer;
PRenderPass renderPass;
PFramebuffer framebuffer;
uint32 subpassIndex;
State state;
friend class SecondaryCmdBuffer;
friend class CommandBufferManager;
};
DEFINE_REF(CmdBuffer);
class SecondaryCmdBuffer : public CmdBufferBase
{
public:
SecondaryCmdBuffer(WGraphics graphics, VkCommandPool cmdPool);
SecondaryCmdBuffer(PGraphics graphics, VkCommandPool cmdPool);
virtual ~SecondaryCmdBuffer();
void begin(WCmdBuffer parent);
void begin(PCmdBuffer parent);
void end();
private:
};
@@ -71,16 +72,16 @@ namespace Seele
class CommandBufferManager
{
public:
CommandBufferManager(WGraphics graphics, WQueue queue);
CommandBufferManager(PGraphics graphics, PQueue queue);
virtual ~CommandBufferManager();
PCmdBuffer getCommands();
PSecondaryCmdBuffer createSecondaryCmdBuffer();
void submitCommands(PSemaphore signalSemaphore = nullptr);
void waitForCommands(PCmdBuffer cmdBuffer, float timeToWait = 1.0f);
private:
WGraphics graphics;
PGraphics graphics;
VkCommandPool commandPool;
WQueue queue;
PQueue queue;
uint32 queueFamilyIndex;
PCmdBuffer activeCmdBuffer;
Array<PCmdBuffer> allocatedBuffers;
@@ -149,7 +149,7 @@ void DescriptorSet::writeChanges()
}
}
DescriptorAllocator::DescriptorAllocator(WGraphics graphics, DescriptorLayout& layout)
DescriptorAllocator::DescriptorAllocator(PGraphics graphics, DescriptorLayout& layout)
: layout(layout)
, graphics(graphics)
{
@@ -0,0 +1,47 @@
#include "VulkanFramebuffer.h"
#include "VulkanGraphicsEnums.h"
#include "VulkanInitializer.h"
#include "VulkanRenderPass.h"
#include "VulkanGraphics.h"
using namespace Seele;
using namespace Seele::Vulkan;
Framebuffer::Framebuffer(PGraphics graphics, PRenderPass renderPass, Gfx::PRenderTargetLayout renderTargetLayout)
: graphics(graphics)
, layout(renderTargetLayout)
, renderPass(renderPass)
{
Array<VkImageView> attachments;
for(auto inputAttachment : layout->inputAttachments)
{
PTexture2D vkInputAttachment = inputAttachment.cast<Texture2D>();
attachments.add(vkInputAttachment->getView());
}
for(auto colorAttachment : layout->colorAttachments)
{
PTexture2D vkColorAttachment = colorAttachment.cast<Texture2D>();
attachments.add(vkColorAttachment->getView());
}
if(layout->depthAttachment != nullptr)
{
PTexture2D vkDepthAttachment = layout->depthAttachment.cast<Texture2D>();
attachments.add(vkDepthAttachment->getView());
}
VkFramebufferCreateInfo createInfo =
init::FramebufferCreateInfo(
renderPass->getHandle(),
attachments.size(),
attachments.data(),
renderPass->getRenderArea().extent.width,
renderPass->getRenderArea().extent.height,
1
);
VK_CHECK(vkCreateFramebuffer(graphics->getDevice(), &createInfo, nullptr, &handle));
}
Framebuffer::~Framebuffer()
{
vkDestroyFramebuffer(graphics->getDevice(), handle, nullptr);
}
@@ -5,18 +5,21 @@ namespace Seele
{
namespace Vulkan
{
DECLARE_REF(RenderPass);
class Framebuffer
{
public:
Framebuffer(WGraphics graphics);
Framebuffer(PGraphics graphics, PRenderPass renderpass, Gfx::PRenderTargetLayout renderTargetLayout);
virtual ~Framebuffer();
inline VkFramebuffer getHandle() const
{
return handle;
}
private:
WGraphics graphics;
PGraphics graphics;
VkFramebuffer handle;
Gfx::PRenderTargetLayout layout;
PRenderPass renderPass;
};
DEFINE_REF(Framebuffer);
}
+35 -4
View File
@@ -63,6 +63,27 @@ VkPhysicalDevice Graphics::getPhysicalDevice() const
return physicalDevice;
}
PCommandBufferManager Graphics::getGraphicsCommands()
{
return graphicsCommands;
}
PCommandBufferManager Graphics::getComputeCommands()
{
return computeCommands;
}
PCommandBufferManager Graphics::getTransferCommands()
{
return transferCommands;
}
PCommandBufferManager Graphics::getDedicatedTransferCommands()
{
return dedicatedTransferCommands;
}
PAllocator Graphics::getAllocator()
{
return allocator;
}
Array<const char *> Graphics::getRequiredExtensions()
{
Array<const char *> extensions;
@@ -161,12 +182,16 @@ void Graphics::createDevice(GraphicsInitializer initializer)
int32_t asyncComputeFamilyIndex = -1;
for (int32_t familyIndex = 0; familyIndex < queueProperties.size(); ++familyIndex)
{
const VkQueueFamilyProperties currProps = queueProperties[familyIndex];
uint32 numQueuesForFamily = 0;
VkQueueFamilyProperties currProps = queueProperties[familyIndex];
bool bSparse = currProps.queueFlags & VK_QUEUE_SPARSE_BINDING_BIT;
currProps.queueFlags = currProps.queueFlags ^ VK_QUEUE_SPARSE_BINDING_BIT;
if ((currProps.queueFlags & VK_QUEUE_GRAPHICS_BIT) == VK_QUEUE_GRAPHICS_BIT)
{
if (graphicsQueueFamilyIndex == -1)
{
graphicsQueueFamilyIndex = familyIndex;
numQueuesForFamily++;
}
}
if ((currProps.queueFlags & VK_QUEUE_COMPUTE_BIT) == VK_QUEUE_COMPUTE_BIT)
@@ -184,6 +209,7 @@ void Graphics::createDevice(GraphicsInitializer initializer)
if (currProps.queueCount > 1)
{
asyncComputeFamilyIndex = familyIndex;
numQueuesForFamily++;
}
}
else
@@ -198,15 +224,20 @@ void Graphics::createDevice(GraphicsInitializer initializer)
if (transferQueueFamilyIndex == -1)
{
transferQueueFamilyIndex = familyIndex;
numQueuesForFamily++;
}
if ((currProps.queueFlags ^ VK_QUEUE_TRANSFER_BIT) == 0)
{
dedicatedTransferQueueFamilyIndex = familyIndex;
numQueuesForFamily++;
}
}
VkDeviceQueueCreateInfo info =
init::DeviceQueueCreateInfo(familyIndex, 1);
queueInfos.add(info);
if(numQueuesForFamily > 0)
{
VkDeviceQueueCreateInfo info =
init::DeviceQueueCreateInfo(familyIndex, numQueuesForFamily);
queueInfos.add(info);
}
}
VkDeviceCreateInfo deviceInfo = init::DeviceCreateInfo(
queueInfos.data(),
+6 -4
View File
@@ -22,6 +22,8 @@ namespace Seele
PCommandBufferManager getTransferCommands();
PCommandBufferManager getDedicatedTransferCommands();
PAllocator getAllocator();
// Inherited via Graphics
virtual void init(GraphicsInitializer initializer) override;
virtual void beginFrame(void* windowHandle) override;
@@ -38,10 +40,10 @@ namespace Seele
VkPhysicalDevice physicalDevice;
VkInstance instance;
WQueue graphicsQueue;
WQueue computeQueue;
WQueue transferQueue;
WQueue dedicatedTransferQueue;
PQueue graphicsQueue;
PQueue computeQueue;
PQueue transferQueue;
PQueue dedicatedTransferQueue;
QueueFamilyMapping queueMapping;
PCommandBufferManager graphicsCommands;
PCommandBufferManager computeCommands;
File diff suppressed because it is too large Load Diff
@@ -20,5 +20,7 @@ namespace Seele
Gfx::SeDescriptorType cast(const VkDescriptorType& descriptorType);
VkShaderStageFlagBits cast(const Gfx::SeShaderStageFlagBits& stage);
Gfx::SeShaderStageFlagBits cast(const VkShaderStageFlagBits& stage);
VkFormat cast(const Gfx::SeFormat& format);
Gfx::SeFormat cast(const VkFormat& format);
}
}
@@ -6,7 +6,7 @@
using namespace Seele;
using namespace Seele::Vulkan;
Semaphore::Semaphore(WGraphics graphics)
Semaphore::Semaphore(PGraphics graphics)
: graphics(graphics)
{
VkSemaphoreCreateInfo info =
@@ -16,5 +16,5 @@ Semaphore::Semaphore(WGraphics graphics)
Semaphore::~Semaphore()
{
vkDestroySemaphore(graphics->getDevice(), handle, nullptr);
}
@@ -13,19 +13,22 @@ DECLARE_REF(Graphics);
class Semaphore
{
public:
Semaphore(WGraphics graphics);
Semaphore(PGraphics graphics);
virtual ~Semaphore();
inline VkSemaphore getHandle() const
{
return handle;
}
private:
VkSemaphore handle;
WGraphics graphics;
PGraphics graphics;
};
DEFINE_REF(Semaphore);
class DescriptorLayout : public Gfx::DescriptorLayout
{
public:
DescriptorLayout(WGraphics graphics)
DescriptorLayout(PGraphics graphics)
: graphics(graphics), layoutHandle(VK_NULL_HANDLE)
{
}
@@ -37,7 +40,7 @@ public:
}
private:
WGraphics graphics;
PGraphics graphics;
Array<VkDescriptorSetLayoutBinding> bindings;
VkDescriptorSetLayout layoutHandle;
friend class PipelineStateCacheManager;
@@ -46,7 +49,7 @@ DEFINE_REF(DescriptorLayout);
class PipelineLayout : public Gfx::PipelineLayout
{
public:
PipelineLayout(WGraphics graphics)
PipelineLayout(PGraphics graphics)
: graphics(graphics), layoutHash(0), layoutHandle(VK_NULL_HANDLE)
{
}
@@ -65,7 +68,7 @@ private:
Array<VkDescriptorSetLayout> vulkanDescriptorLayouts;
uint32 layoutHash;
VkPipelineLayout layoutHandle;
WGraphics graphics;
PGraphics graphics;
friend class PipelineStateCacheManager;
};
DEFINE_REF(PipelineLayout);
@@ -73,7 +76,7 @@ DEFINE_REF(PipelineLayout);
class DescriptorSet : public Gfx::DescriptorSet
{
public:
DescriptorSet(WGraphics graphics, PDescriptorAllocator owner)
DescriptorSet(PGraphics graphics, PDescriptorAllocator owner)
: graphics(graphics), owner(owner), setHandle(VK_NULL_HANDLE)
{
}
@@ -95,7 +98,7 @@ private:
Array<VkWriteDescriptorSet> writeDescriptors;
VkDescriptorSet setHandle;
PDescriptorAllocator owner;
WGraphics graphics;
PGraphics graphics;
friend class DescriptorAllocator;
};
DEFINE_REF(DescriptorSet);
@@ -103,7 +106,7 @@ DEFINE_REF(DescriptorSet);
class DescriptorAllocator : public Gfx::DescriptorAllocator
{
public:
DescriptorAllocator(WGraphics graphics, DescriptorLayout &layout);
DescriptorAllocator(PGraphics graphics, DescriptorLayout &layout);
~DescriptorAllocator();
virtual void allocateDescriptorSet(Gfx::PDescriptorSet &descriptorSet);
@@ -113,7 +116,7 @@ public:
}
private:
WGraphics graphics;
PGraphics graphics;
int maxSets = 512;
VkDescriptorPool poolHandle;
DescriptorLayout &layout;
@@ -159,7 +162,7 @@ struct QueueFamilyMapping
class QueueOwnedResource
{
public:
QueueOwnedResource(WGraphics graphics, QueueType startQueueType);
QueueOwnedResource(PGraphics graphics, QueueType startQueueType);
~QueueOwnedResource();
PCommandBufferManager getCommands();
//Preliminary checks to see if the barrier should be executed at all
@@ -168,7 +171,7 @@ public:
protected:
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
QueueType currentOwner;
WGraphics graphics;
PGraphics graphics;
CommandBufferManager *cachedCmdBufferManager;
};
DEFINE_REF(QueueOwnedResource);
@@ -176,7 +179,7 @@ DEFINE_REF(QueueOwnedResource);
class Buffer : public QueueOwnedResource
{
public:
Buffer(WGraphics graphics, uint32 size, VkBufferUsageFlags usage, QueueType queueType = QueueType::GRAPHICS);
Buffer(PGraphics graphics, uint32 size, VkBufferUsageFlags usage, QueueType queueType = QueueType::GRAPHICS);
virtual ~Buffer();
private:
@@ -200,21 +203,51 @@ DEFINE_REF(StructuredBuffer);
class TextureBase
{
public:
TextureBase();
TextureBase(PGraphics graphics, VkImageViewType viewType, uint32 sizeX, uint32 sizeY, uint32 sizeZ,
bool bArray, uint32 arraySize, uint32 mipLevels, Gfx::SeFormat format,
uint32 samples, Gfx::SeImageUsageFlags usage);
virtual ~TextureBase();
private:
PGraphics graphics;
uint32 sizeX;
uint32 sizeY;
uint32 sizeZ;
uint32 arrayCount;
uint32 layerCount;
uint32 mipLevels;
Gfx::SeFormat format;
VkImage image;
VkImageView defaultView;
VkImageAspectFlags aspect;
};
DEFINE_REF(TextureBase);
class Texture2D : public Gfx::Texture2D
{
public:
Texture2D(PGraphics graphics, uint32 sizeX, uint32 sizeY,
bool bArray, uint32 arraySize, uint32 mipLevels,
Gfx::SeFormat format, uint32 samples, Gfx::SeImageUsageFlags usage);
virtual ~Texture2D();
inline uint32 getSizeX() const
{
return textureHandle->sizeX;
}
inline uint32 getSizeY() const
{
return textureHandle->sizeY;
}
inline Gfx::SeFormat getFormat() const
{
return textureHandle->format;
}
inline VkImage getHandle() const
{
return textureHandle->image;
}
inline VkImageView getView() const
{
return textureHandle->defaultView;
}
private:
PTextureBase textureHandle;
};
@@ -1,4 +1,5 @@
#include "VulkanInitializer.h"
#include <iostream>
using namespace Seele::Vulkan;
@@ -45,7 +46,7 @@ VkDeviceQueueCreateInfo init::DeviceQueueCreateInfo(int queueFamilyIndex, int qu
VkDeviceQueueCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
createInfo.queueFamilyIndex = queueFamilyIndex;
createInfo.queueCount = 1;
createInfo.queueCount = queueCount;
createInfo.pQueuePriorities = queuePriority;
return createInfo;
}
+1 -1
View File
@@ -5,7 +5,7 @@
using namespace Seele;
using namespace Seele::Vulkan;
Queue::Queue(WGraphics graphics, QueueType queueType, uint32 familyIndex, uint32 queueIndex)
Queue::Queue(PGraphics graphics, QueueType queueType, uint32 familyIndex, uint32 queueIndex)
: familyIndex(familyIndex)
, graphics(graphics)
, queueType(queueType)
+2 -2
View File
@@ -10,7 +10,7 @@ namespace Seele
class Queue
{
public:
Queue(WGraphics graphics, QueueType queueType, uint32 familyIndex, uint32 queueIndex);
Queue(PGraphics 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)
@@ -26,7 +26,7 @@ namespace Seele
return queue;
}
private:
WGraphics graphics;
PGraphics graphics;
VkQueue queue;
uint32 familyIndex;
QueueType queueType;
@@ -0,0 +1,91 @@
#include "VulkanGraphicsResources.h"
#include "VulkanGraphics.h"
#include "VulkanInitializer.h"
#include "VulkanGraphicsEnums.h"
#include <math.h>
using namespace Seele;
using namespace Seele::Vulkan;
TextureBase::TextureBase(PGraphics graphics, VkImageViewType viewType, uint32 sizeX, uint32 sizeY, uint32 sizeZ,
bool bArray, uint32 arraySize, uint32 mipLevel,
Gfx::SeFormat format, uint32 samples, Gfx::SeImageUsageFlags usage)
: graphics(graphics)
, sizeX(sizeX)
, sizeY(sizeY)
, sizeZ(sizeZ)
, mipLevels(mipLevel)
, format(format)
, arrayCount(bArray ? arraySize : 1)
{
PAllocator allocator = graphics->getAllocator();
VkImageCreateInfo info =
init::ImageCreateInfo();
info.extent.width = sizeX;
info.extent.height = sizeY;
info.extent.depth = sizeZ;
info.arrayLayers = arraySize;
info.format = cast(format);
VkImageViewCreateInfo viewInfo =
init::ImageViewCreateInfo();
viewInfo.subresourceRange = init::ImageSubresourceRange(aspect);
viewInfo.viewType = viewType;
uint32 layerCount = 1;
switch (viewType)
{
case VK_IMAGE_VIEW_TYPE_1D:
case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
info.imageType = VK_IMAGE_TYPE_1D;
break;
case VK_IMAGE_VIEW_TYPE_2D:
case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
info.imageType = VK_IMAGE_TYPE_2D;
break;
case VK_IMAGE_VIEW_TYPE_3D:
info.imageType = VK_IMAGE_TYPE_3D;
break;
case VK_IMAGE_VIEW_TYPE_CUBE:
info.imageType = VK_IMAGE_TYPE_2D;
layerCount = 6 * arrayCount;
break;
default:
break;
}
info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
info.mipLevels = mipLevel;
info.arrayLayers = arrayCount * layerCount;
info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
info.samples = (VkSampleCountFlagBits)samples;
info.tiling = VK_IMAGE_TILING_OPTIMAL;
info.usage = usage;
VK_CHECK(vkCreateImage(graphics->getDevice(), &info, nullptr, &image));
viewInfo.image = image;
viewInfo.format = cast(format);
viewInfo.subresourceRange.layerCount = layerCount;
viewInfo.subresourceRange.levelCount = mipLevels;
VK_CHECK(vkCreateImageView(graphics->getDevice(), &viewInfo, nullptr, &defaultView));
}
TextureBase::~TextureBase()
{
vkDestroyImageView(graphics->getDevice(), defaultView, nullptr);
vkDestroyImage(graphics->getDevice(), image, nullptr);
}
Texture2D::Texture2D(PGraphics graphics, uint32 sizeX, uint32 sizeY,
bool bArray, uint32 arraySize, uint32 mipLevels,
Gfx::SeFormat format, uint32 samples, Gfx::SeImageUsageFlags usage)
{
textureHandle = new TextureBase(graphics, bArray ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D,
sizeX, sizeY, 1, bArray, arraySize, mipLevels, format, samples, usage);
}
Texture2D::~Texture2D()
{
}
+11 -4
View File
@@ -1,7 +1,9 @@
#include "Window.h"
#include "SceneView.h"
Seele::Window::Window(const WindowCreateInfo& createInfo, Gfx::PGraphics graphics)
using namespace Seele;
Window::Window(const WindowCreateInfo& createInfo, Gfx::PGraphics graphics)
: width(createInfo.width)
, height(createInfo.height)
, graphics(graphics)
@@ -12,17 +14,22 @@ Seele::Window::Window(const WindowCreateInfo& createInfo, Gfx::PGraphics graphic
windowHandle = graphics->createWindow(createInfo);
}
Seele::Window::~Window()
Window::~Window()
{
}
void Seele::Window::beginFrame()
void Window::onWindowCloseEvent()
{
}
void Window::beginFrame()
{
graphics->beginFrame(windowHandle);
center->beginFrame();
}
void Seele::Window::endFrame()
void Window::endFrame()
{
graphics->endFrame(windowHandle);
}
+1
View File
@@ -55,6 +55,7 @@ namespace Seele {
public:
Window(const WindowCreateInfo& createInfo, Gfx::PGraphics graphics);
~Window();
void onWindowCloseEvent();
void beginFrame();
void endFrame();
private:
+4
View File
@@ -13,6 +13,10 @@ namespace Seele
void addWindow(const WindowCreateInfo& createInfo);
void beginFrame();
void endFrame();
inline bool isActive() const
{
return windows.size();
}
private:
Array<PWindow> windows;
Gfx::PGraphics graphics;
+3
View File
@@ -0,0 +1,3 @@
#include "MinimalEngine.h"
Seele::Map<void*, void*> registeredObjects;
+26 -32
View File
@@ -1,10 +1,11 @@
#pragma once
#include <stdint.h>
#include <assert.h>
#include <memory>
#include <atomic>
#include <cstring>
#include <iostream>
#include "Containers/Map.h"
#include "EngineTypes.h"
#include "Math/Math.h"
#define DEFINE_REF(x) typedef RefPtr<x> P##x; \
@@ -16,18 +17,9 @@
typedef UniquePtr<x> UP##x; \
typedef WeakPtr<x> W##x;
extern Seele::Map<void*, void*> registeredObjects;
namespace Seele
{
typedef uint64_t uint64;
typedef uint32_t uint32;
typedef uint16_t uint16;
typedef uint8_t uint8;
typedef int64_t int64;
typedef int32_t int32;
typedef int16_t int16;
typedef int8_t int8;
template<typename T>
class RefObject
{
@@ -36,18 +28,25 @@ namespace Seele
: handle(ptr)
, refCount(1)
{
registeredObjects[ptr] = this;
}
RefObject(const RefObject& rhs)
: handle(rhs.handle)
, refCount(rhs.refCount)
{
}
~RefObject()
{}
{
registeredObjects.erase(handle);
delete handle;
}
bool operator==(const RefObject& other) const
{
return handle == other.handle && refCount == other.refCount;
return handle == other.handle;
}
bool operator<(const RefObject& other) const
{
return handle < other.handle;
}
void addRef()
{
@@ -58,8 +57,6 @@ namespace Seele
refCount--;
if (refCount.load() <= 0)
{
delete handle;
handle = nullptr;
delete this;
}
}
@@ -72,6 +69,7 @@ namespace Seele
std::atomic_uint64_t refCount;
};
template<typename T>
class RefPtr
{
@@ -86,7 +84,15 @@ namespace Seele
}
RefPtr(T* ptr)
{
object = new RefObject<T>(ptr);
auto registeredObj = registeredObjects.find(ptr);
if(registeredObj == registeredObjects.end())
{
object = new RefObject<T>(ptr);
}
else
{
object = (RefObject<T>*)registeredObj->value;
}
}
explicit RefPtr(RefObject<T>* other)
: object(other)
@@ -171,11 +177,8 @@ namespace Seele
WeakPtr()
: pointer(nullptr)
{}
WeakPtr(T* ptr)
: pointer(ptr)
{}
WeakPtr(RefPtr<T>& sharedPtr)
: pointer(sharedPtr.object->handle)
: pointer(sharedPtr)
{}
WeakPtr& operator=(WeakPtr<T>& weakPtr)
{
@@ -184,20 +187,11 @@ namespace Seele
}
WeakPtr& operator=(RefPtr<T>& sharedPtr)
{
pointer = sharedPtr.object->handle;
pointer = sharedPtr;
return *this;
}
WeakPtr& operator=(T* ptr)
{
pointer = ptr;
return *this;
}
inline T* operator->()
{
return pointer;
}
private:
T* pointer;
RefPtr<T> pointer;
};
template<typename T>
class UniquePtr
+1
View File
@@ -1,5 +1,6 @@
target_sources(Seele_unit_tests
PRIVATE
../../src/Engine/MinimalEngine.cpp
EngineTest.h
EngineTest.cpp)
target_include_directories(Seele_unit_tests PUBLIC ./)
+2 -2
View File
@@ -112,7 +112,7 @@ BOOST_AUTO_TEST_CASE(random_access)
BOOST_CHECK_EQUAL(array[0], 4);
}
BOOST_AUTO_TEST_CASE(benchmark)
/*BOOST_AUTO_TEST_CASE(benchmark)
{
using namespace std::chrono;
srand(time(NULL));
@@ -160,7 +160,7 @@ BOOST_AUTO_TEST_CASE(benchmark)
std::cout << "Vector: " << time_vector << "ms Array: " << time_array << "ms" << std::endl;
std::cout << "Vector remove: " << remove_vector << "ms Array remove: " << remove_array << "ms" << std::endl;
delete[] testSet;
}
}*/
BOOST_AUTO_TEST_SUITE_END()
+6 -1
View File
@@ -31,10 +31,13 @@ BOOST_AUTO_TEST_CASE(for_each)
map[6] = 4;
map[4] = 7;
int count = 0;
for (auto entry : map)
std::cout << "Map start" << std::endl;
for(auto it = map.begin(); it != map.end(); ++it)
{
std::cout << (*it).key << std::endl;
count++;
}
std::cout << "Map end" << std::endl;
BOOST_REQUIRE_EQUAL(count, 4);
}
@@ -44,6 +47,8 @@ BOOST_AUTO_TEST_CASE(key_exists)
map[2] = 3;
BOOST_REQUIRE_EQUAL(map.exists(2), true);
BOOST_REQUIRE_EQUAL(map.exists(4), false);
map.erase(2);
BOOST_REQUIRE_EQUAL(map.exists(2), false);
}
BOOST_AUTO_TEST_CASE(custom_key)