diff --git a/engine/.vscode/settings.json b/engine/.vscode/settings.json index a3b2b51..5981459 100644 --- a/engine/.vscode/settings.json +++ b/engine/.vscode/settings.json @@ -1,5 +1,7 @@ { "files.associations": { - "vector": "cpp" + "vector": "cpp", + "chrono": "cpp", + "utility": "cpp" } } \ No newline at end of file diff --git a/engine/3rdparty/zasset/include/asset.h b/engine/3rdparty/zasset/include/zasset/asset.h similarity index 95% rename from engine/3rdparty/zasset/include/asset.h rename to engine/3rdparty/zasset/include/zasset/asset.h index bcbbbfb..2bfba99 100644 --- a/engine/3rdparty/zasset/include/asset.h +++ b/engine/3rdparty/zasset/include/zasset/asset.h @@ -19,6 +19,7 @@ namespace engineapi Asset(std::string& name, uint32_t flags):mName(name),mFlags(flags) {}; virtual void onLoadFinished() { mFlags |= ASSET_LOADED_TYPE; }; virtual void SyncLoad() {}; + virtual void AsyncLoad() {}; public: inline bool IsShared() { return mFlags & ASSET_SHARED_TYPE; diff --git a/engine/3rdparty/zasset/include/asset_manager.h b/engine/3rdparty/zasset/include/zasset/asset_manager.h similarity index 95% rename from engine/3rdparty/zasset/include/asset_manager.h rename to engine/3rdparty/zasset/include/zasset/asset_manager.h index 88c7d44..b2edaff 100644 --- a/engine/3rdparty/zasset/include/asset_manager.h +++ b/engine/3rdparty/zasset/include/zasset/asset_manager.h @@ -41,8 +41,7 @@ namespace engineapi mAssetMap.emplace(asset_path.string(), *asset); } if (asset->IsAsync()) { - //todo: AsyncLoad - asset->SyncLoad(); + asset->AsyncLoad(); } else { asset->SyncLoad(); diff --git a/engine/3rdparty/zasset/src/asset.cpp b/engine/3rdparty/zasset/src/asset.cpp deleted file mode 100644 index ff7af26..0000000 --- a/engine/3rdparty/zasset/src/asset.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "asset.h" -namespace engineapi -{ - -} \ No newline at end of file diff --git a/engine/3rdparty/zasset/src/zasset/asset.cpp b/engine/3rdparty/zasset/src/zasset/asset.cpp new file mode 100644 index 0000000..1831bec --- /dev/null +++ b/engine/3rdparty/zasset/src/zasset/asset.cpp @@ -0,0 +1,5 @@ +#include "zasset/asset.h" +namespace engineapi +{ + +} \ No newline at end of file diff --git a/engine/3rdparty/zasset/src/asset_manager.cpp b/engine/3rdparty/zasset/src/zasset/asset_manager.cpp similarity index 81% rename from engine/3rdparty/zasset/src/asset_manager.cpp rename to engine/3rdparty/zasset/src/zasset/asset_manager.cpp index ab7dfc4..3abc629 100644 --- a/engine/3rdparty/zasset/src/asset_manager.cpp +++ b/engine/3rdparty/zasset/src/zasset/asset_manager.cpp @@ -1,4 +1,4 @@ -#include "asset_manager.h" +#include "zasset/asset_manager.h" std::filesystem::path engineapi::AssetManager::getFullPath(const std::string& relative_path) const { diff --git a/engine/3rdparty/zasset/xmake.lua b/engine/3rdparty/zasset/xmake.lua index 5febd8e..8caea96 100644 --- a/engine/3rdparty/zasset/xmake.lua +++ b/engine/3rdparty/zasset/xmake.lua @@ -3,5 +3,5 @@ target("zasset") set_kind("static") add_includedirs("include", {public = true}) add_deps("zlog",{public = true}) - add_files("src/*.cpp") - add_headerfiles("include/*.h") \ No newline at end of file + add_files("src/**.cpp") + add_headerfiles("include/**.h") \ No newline at end of file diff --git a/engine/src/engine/vulkanapi/asset/asset.cpp b/engine/src/engine/vulkanapi/asset/asset.cpp new file mode 100644 index 0000000..e69de29 diff --git a/engine/src/engine/vulkanapi/asset/asset.h b/engine/src/engine/vulkanapi/asset/asset.h new file mode 100644 index 0000000..831cc85 --- /dev/null +++ b/engine/src/engine/vulkanapi/asset/asset.h @@ -0,0 +1,10 @@ +#pragma once +#include "zasset/asset.h" +#include "../wrapper/commandbuffer.h" +#include"glm/glm.hpp" + +namespace vulkanapi { + class Asset : public engineapi::Asset { + virtual void BindCommand(CommandBuffer& cmd) {}; + }; +}; \ No newline at end of file diff --git a/engine/src/engine/vulkanapi/asset/mesh.cpp b/engine/src/engine/vulkanapi/asset/mesh.cpp index e6be6f3..d443a7d 100644 --- a/engine/src/engine/vulkanapi/asset/mesh.cpp +++ b/engine/src/engine/vulkanapi/asset/mesh.cpp @@ -1,12 +1,84 @@ #include "mesh.h" +#include "../backend.h" +#include "../thread/worker.h" #include "assimp/Importer.hpp" #include "assimp/scene.h" #include "assimp/postprocess.h" +#include "zlog.h" namespace vulkanapi { void Mesh::SyncLoad() { + std::vector vertexPositions = std::vector(); Assimp::Importer importer; const aiScene* scene = importer.ReadFile(mName, aiProcess_Triangulate | aiProcess_GenSmoothNormals | aiProcess_FlipUVs | aiProcess_CalcTangentSpace); + // process ASSIMP's root node recursively + aiMesh* mesh = scene->mMeshes[scene->mRootNode->mMeshes[0]]; + for (unsigned int i = 0; i < mesh->mNumVertices; i++) + { + VertexData vertexData; + glm::vec3 vector; + // positions + vector.x = mesh->mVertices[i].x; + vector.y = mesh->mVertices[i].y; + vector.z = mesh->mVertices[i].z; + vertexData.position = vector; + // normals + if (mesh->HasNormals()) + { + vector.x = mesh->mNormals[i].x; + vector.y = mesh->mNormals[i].y; + vector.z = mesh->mNormals[i].z; + vertexData.normal = vector; + } + // texture coordinates + if (mesh->mTextureCoords[0]) // does the mesh contain texture coordinates? + { + glm::vec2 vec; + // a vertex can contain up to 8 different texture coordinates. We thus make the assumption that we won't + // use models where a vertex can have multiple texture coordinates so we always take the first set (0). + vec.x = mesh->mTextureCoords[0][i].x; + vec.y = mesh->mTextureCoords[0][i].y; + vertexData.texCoords = vec; + // tangent + vector.x = mesh->mTangents[i].x; + vector.y = mesh->mTangents[i].y; + vector.z = mesh->mTangents[i].z; + vertexData.tangent = vector; + // bitangent + vector.x = mesh->mBitangents[i].x; + vector.y = mesh->mBitangents[i].y; + vector.z = mesh->mBitangents[i].z; + vertexData.bitangent = vector; + } + else + { + zlog::info("Mesh do not contains uv."); + } + mVertices.push_back(vertexData); + vertexPositions.emplace_back(vertexData.position); + } + // now wak through each of the mesh's faces (a face is a mesh its triangle) and retrieve the corresponding vertex indices. + for (unsigned int i = 0; i < mesh->mNumFaces; i++) + { + aiFace face = mesh->mFaces[i]; + // retrieve all indices of the face and store them in the indices vector + for (unsigned int j = 0; j < face.mNumIndices; j++) + mIndices.push_back(face.mIndices[j]); + } + importer.FreeScene(); + + Backend::TransferWorker->InvokeBuffer([&](CommandBuffer* cmd) { + cmd->CopyBuffer(&stageVertexBuffer, _vertexBuffer); + cmd->CopyBuffer(&stageIndexBuffer, _indexBuffer); + }); } + void Mesh::AsyncLoad() + { + SyncLoad(); + } + void Mesh::BindCommand(CommandBuffer& cmd) + { + + } } diff --git a/engine/src/engine/vulkanapi/asset/mesh.h b/engine/src/engine/vulkanapi/asset/mesh.h index 4465527..d4ee6d3 100644 --- a/engine/src/engine/vulkanapi/asset/mesh.h +++ b/engine/src/engine/vulkanapi/asset/mesh.h @@ -1,10 +1,25 @@ #pragma once #include "asset.h" #include "../vulkan.h" +#include"glm/glm.hpp" namespace vulkanapi { - class Mesh : public engineapi::Asset{ + class Mesh : public Asset{ + public: + struct VertexData + { + glm::vec3 position; + glm::vec2 texCoords; + glm::vec3 normal; + glm::vec3 tangent; + glm::vec3 bitangent; + }; + private: + std::vector mVertices; + std::vector mIndices; public: void SyncLoad()override; + void AsyncLoad()override; + void BindCommand(CommandBuffer& cmd)override; }; }; \ No newline at end of file diff --git a/engine/src/engine/vulkanapi/backend.cpp b/engine/src/engine/vulkanapi/backend.cpp index 838ef34..1533dfa 100644 --- a/engine/src/engine/vulkanapi/backend.cpp +++ b/engine/src/engine/vulkanapi/backend.cpp @@ -1,7 +1,10 @@ #include "backend.h" +#include "wrapper/queue.h" +#include "thread/worker.h" #include #include "zlog.h" namespace vulkanapi { + CommandWorker* Backend::TransferWorker = nullptr; Backend::Backend(const char* appName, int deviceIndex) { auto instanceCreator = InstanceCreator(); @@ -10,13 +13,18 @@ namespace vulkanapi { auto deviceCreator = DeviceCreator(*mInstance); deviceCreator.AddWindowExtension(); deviceCreator.desiredPhysicalDeviceFeatures.geometryShader = VK_TRUE; - deviceCreator.AddQueue("TransferQueue", VkQueueFlagBits::VK_QUEUE_GRAPHICS_BIT, 1.0); - deviceCreator.AddQueue("RenderQueue", VkQueueFlagBits::VK_QUEUE_GRAPHICS_BIT, 1.0); - deviceCreator.AddQueue("ComputeQueue", VkQueueFlagBits::VK_QUEUE_GRAPHICS_BIT, 1.0); - deviceCreator.AddQueue("PresentQueue", VkQueueFlagBits::VK_QUEUE_GRAPHICS_BIT, 1.0); + deviceCreator.AddQueue(Queue::TransferQueue, VkQueueFlagBits::VK_QUEUE_GRAPHICS_BIT, 1.0); + deviceCreator.AddQueue(Queue::RenderQueue, VkQueueFlagBits::VK_QUEUE_GRAPHICS_BIT, 1.0); + deviceCreator.AddQueue(Queue::ComputeQueue, VkQueueFlagBits::VK_QUEUE_GRAPHICS_BIT, 1.0); + deviceCreator.AddQueue(Queue::PresentQueue, VkQueueFlagBits::VK_QUEUE_GRAPHICS_BIT, 1.0); mDevice = new Device(deviceCreator); + InitWorker(Queue::TransferQueue, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT); + InitWorker(Queue::RenderQueue, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT); + InitWorker(Queue::ComputeQueue, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT); + InitWorker(Queue::PresentQueue, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT); + Backend::TransferWorker = GetWorker(Queue::TransferQueue); } Backend::~Backend() { @@ -27,4 +35,20 @@ namespace vulkanapi { delete mDevice; } } + void Backend::InitWorker(const std::string& name, VkCommandPoolCreateFlags flag) + { + auto queue = mDevice->GetQueue(name); + if (queue) { + auto worker = new CommandWorker(name, *mDevice, *queue, flag); + mWorkerMap.emplace(name, worker); + } + } + CommandWorker* Backend::GetWorker(const std::string& name) + { + auto it = mWorkerMap.find(name); + if (it != mWorkerMap.end()) { + return it->second; + } + return nullptr; + } } diff --git a/engine/src/engine/vulkanapi/backend.h b/engine/src/engine/vulkanapi/backend.h index 0f71ba7..0c690ce 100644 --- a/engine/src/engine/vulkanapi/backend.h +++ b/engine/src/engine/vulkanapi/backend.h @@ -6,10 +6,14 @@ #include "wrapper/device.h" #include "wrapper/device_creator.h" namespace vulkanapi { + class CommandWorker; class Backend{ protected: Instance* mInstance; Device* mDevice; + std::map mWorkerMap; + public: + static CommandWorker* TransferWorker; public: Instance& GetInstance() { return *mInstance; @@ -20,5 +24,8 @@ namespace vulkanapi { public: Backend(const char* appName, int deviceIndex = 0); ~Backend(); + + void InitWorker(const std::string& name, VkCommandPoolCreateFlags flag); + CommandWorker* GetWorker(const std::string& name); }; }; \ No newline at end of file diff --git a/engine/src/engine/vulkanapi/thread/record.cpp b/engine/src/engine/vulkanapi/thread/record.cpp new file mode 100644 index 0000000..21f9945 --- /dev/null +++ b/engine/src/engine/vulkanapi/thread/record.cpp @@ -0,0 +1,19 @@ +#include "record.h" +#include +#include +namespace vulkanapi { + CommandRecord::CommandRecord() + { + mParts.reserve(64); + } + void CommandRecord::Apply(CommandBuffer* buf) + { + for (auto cmd : mParts) { + cmd(buf); + } + } + void CommandRecord::Record(CommandFn cmd) + { + mParts.push_back(cmd); + } +} diff --git a/engine/src/engine/vulkanapi/thread/record.h b/engine/src/engine/vulkanapi/thread/record.h new file mode 100644 index 0000000..bf52795 --- /dev/null +++ b/engine/src/engine/vulkanapi/thread/record.h @@ -0,0 +1,16 @@ +#pragma once +#include +#include +#include "engine/vulkanapi/vulkan.h" +namespace vulkanapi { + class CommandBuffer; + typedef void (*CommandFn)(CommandBuffer* buf); + class CommandRecord { + protected: + std::vector mParts; + public: + CommandRecord(); + void Apply(CommandBuffer* buf); + void Record(CommandFn cmd); + }; +}; \ No newline at end of file diff --git a/engine/src/engine/vulkanapi/thread/thread_worker.cpp b/engine/src/engine/vulkanapi/thread/thread_worker.cpp new file mode 100644 index 0000000..82ae405 --- /dev/null +++ b/engine/src/engine/vulkanapi/thread/thread_worker.cpp @@ -0,0 +1,31 @@ +#include "thread_worker.h" +namespace vulkanapi { + CommandThreadWorker::CommandThreadWorker(const std::string name, int buffer) + : mName(name) + , mChannel(buffer) + , mSemaphore(0) + { + mThread = std::thread(&CommandThreadWorker::workloop, this); + } + void CommandThreadWorker::workloop() + { + mThread.detach(); + while(true){ + voidFn fn = mChannel.acquire(); + fn(); + } + } + void CommandThreadWorker::Invoke(voidFn fn) + { + mChannel.release(fn); + } + + void CommandThreadWorker::SyncInvoke(voidFn fn) + { + Invoke([&]() { + fn(); + mSemaphore.release(); + }); + mSemaphore.acquire(); + } +} diff --git a/engine/src/engine/vulkanapi/thread/thread_worker.h b/engine/src/engine/vulkanapi/thread/thread_worker.h new file mode 100644 index 0000000..1e8c8bc --- /dev/null +++ b/engine/src/engine/vulkanapi/thread/thread_worker.h @@ -0,0 +1,22 @@ +#pragma once +#include +#include +#include +#include "engine/vulkanapi/vulkan.h" +#include "zthread/channel.h" +namespace vulkanapi { + class CommandThreadWorker { + protected: + std::thread mThread; + std::string mName; + zstd::channel mChannel; + std::binary_semaphore mSemaphore; + protected: + void workloop(); + public: + CommandThreadWorker(const std::string name, int buffer); + + void Invoke(voidFn fn); + void SyncInvoke(voidFn fn); + }; +}; diff --git a/engine/src/engine/vulkanapi/thread/worker.cpp b/engine/src/engine/vulkanapi/thread/worker.cpp new file mode 100644 index 0000000..e8cb78e --- /dev/null +++ b/engine/src/engine/vulkanapi/thread/worker.cpp @@ -0,0 +1,52 @@ +#include "worker.h" +#include "thread_worker.h" +#include "../wrapper/queue.h" +#include "../wrapper/device.h" +#include "../wrapper/commandpool.h" +#include "../wrapper/commandbuffer.h" +namespace vulkanapi { + CommandWorker::CommandWorker(const std::string& name, Device& device, Queue& queue, VkCommandPoolCreateFlags queueFlags) + :mName(name) + ,mQueue(queue) + { + mCommandPool = new CommandPool(device, queueFlags, queue.QueueFamilyIndex()); + mWork = new CommandThreadWorker(name, 64); + } + void CommandWorker::Invoke(voidFn fn) + { + mWork->Invoke(fn); + } + + void CommandWorker::InvokeBuffer(commandFn fn) + { + mWork->Invoke([&]() { + Buffer(fn); + }); + } + + void CommandWorker::Buffer(commandFn fn) + { + CommandBuffer* cmd = mCommandPool->Pop(); + cmd->BeginRecord(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); + fn(cmd); + cmd->EndRecord(); + } + + void CommandWorker::InvokeSubmit() + { + mWork->Invoke([&]() { + Submit(); + }); + } + + void CommandWorker::Submit() + { + + } + + void CommandWorker::Flush() + { + mWork->SyncInvoke([]() {}); + } + +} diff --git a/engine/src/engine/vulkanapi/thread/worker.h b/engine/src/engine/vulkanapi/thread/worker.h new file mode 100644 index 0000000..cea84d7 --- /dev/null +++ b/engine/src/engine/vulkanapi/thread/worker.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include "../vulkan.h" +namespace vulkanapi { + class Device; + class CommandThreadWorker; + class CommandPool; + class Queue; + class CommandWorker { + protected: + Queue& mQueue; + const std::string& mName; + CommandThreadWorker* mWork; + CommandPool* mCommandPool; + public: + CommandWorker(const std::string& name, Device& device, Queue& queue, VkCommandPoolCreateFlags queueFlags); + + void Invoke(voidFn fn); + void InvokeBuffer(commandFn fn); + void Buffer(commandFn fn); + void InvokeSubmit(); + void Submit(); + void Flush(); + }; +}; \ No newline at end of file diff --git a/engine/src/engine/vulkanapi/vulkan.h b/engine/src/engine/vulkanapi/vulkan.h index 4f62902..cc31523 100644 --- a/engine/src/engine/vulkanapi/vulkan.h +++ b/engine/src/engine/vulkanapi/vulkan.h @@ -12,8 +12,9 @@ namespace vulkanapi { #define _USE_GRAPHIC_DEBUG +class CommandBuffer; using voidFn = std::function; -using commandFn = std::function; +using commandFn = std::function; //Vulkan Function Addr Variable lg:PFN_##name name; #define EXPORTED_VULKAN_FUNCTION( name ) extern PFN_##name name; diff --git a/engine/src/engine/vulkanapi/wrapper/commandbuffer.cpp b/engine/src/engine/vulkanapi/wrapper/commandbuffer.cpp new file mode 100644 index 0000000..3e36dd8 --- /dev/null +++ b/engine/src/engine/vulkanapi/wrapper/commandbuffer.cpp @@ -0,0 +1,28 @@ +#include "commandbuffer.h" +#include "commandpool.h" +#include "device.h" +namespace vulkanapi { + CommandBuffer::CommandBuffer(CommandPool& commandPool, VkCommandBufferLevel level) + : mPtr(commandPool.Allocate(level)) + { + + } + void CommandBuffer::Reset() + { + vkResetCommandBuffer(mPtr, VkCommandBufferResetFlagBits::VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT); + } + void CommandBuffer::BeginRecord(VkCommandBufferUsageFlags flag) + { + VkCommandBufferBeginInfo beginInfo{ + VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,//sType + nullptr, //pNext + flag //flags + }; + vkBeginCommandBuffer(mPtr, &beginInfo); + } + void CommandBuffer::EndRecord() + { + vkEndCommandBuffer(mPtr); + } +} + diff --git a/engine/src/engine/vulkanapi/wrapper/commandbuffer.h b/engine/src/engine/vulkanapi/wrapper/commandbuffer.h new file mode 100644 index 0000000..dce3af7 --- /dev/null +++ b/engine/src/engine/vulkanapi/wrapper/commandbuffer.h @@ -0,0 +1,17 @@ +#pragma once +#include +#include "../vulkan.h" +namespace vulkanapi { + class Device; + class CommandPool; + class CommandBuffer { + protected: + VkCommandBuffer mPtr; + public: + CommandBuffer(CommandPool& commandPool, VkCommandBufferLevel level); + + void Reset(); + void BeginRecord(VkCommandBufferUsageFlags flag); + void EndRecord(); + }; +} \ No newline at end of file diff --git a/engine/src/engine/vulkanapi/wrapper/commandpool.cpp b/engine/src/engine/vulkanapi/wrapper/commandpool.cpp new file mode 100644 index 0000000..01604cf --- /dev/null +++ b/engine/src/engine/vulkanapi/wrapper/commandpool.cpp @@ -0,0 +1,46 @@ +#include "commandpool.h" +#include "commandbuffer.h" +#include "device.h" +#include "queue.h" +#include "zlog.h" +namespace vulkanapi { + CommandPool::CommandPool(Device& device, VkCommandPoolCreateFlags queueFlags, uint32_t queueIndex) + :mPtr(nullptr) + ,mDevice(device) + { + VkCommandPoolCreateInfo pCreateInfo{ + VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, + nullptr, + queueFlags, + queueIndex + }; + vkCreateCommandPool(device.Ptr(), &pCreateInfo, nullptr, &mPtr); + } + VkCommandBuffer CommandPool::Allocate(VkCommandBufferLevel level) + { + VkCommandBufferAllocateInfo allocInfo{ + VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, //sType + nullptr, //pNext + mPtr, //commandPool + level, //level + 1, //commandBufferCount + }; + VkCommandBuffer cmd; + vkAllocateCommandBuffers(mDevice.Ptr(), &allocInfo, &cmd); + return cmd; + } + CommandBuffer* CommandPool::Pop() + { + if (top < mBufferList.size()) { + auto cmd = mBufferList[top]; + cmd->Reset(); + top++; + return cmd; + } + CommandBuffer* cmd = new CommandBuffer(*this, VK_COMMAND_BUFFER_LEVEL_PRIMARY); + mBufferList.push_back(cmd); + top++; + return cmd; + } +} + diff --git a/engine/src/engine/vulkanapi/wrapper/commandpool.h b/engine/src/engine/vulkanapi/wrapper/commandpool.h new file mode 100644 index 0000000..15159a0 --- /dev/null +++ b/engine/src/engine/vulkanapi/wrapper/commandpool.h @@ -0,0 +1,23 @@ +#pragma once +#include +#include "../vulkan.h" +namespace vulkanapi { + class Device; + class Queue; + class CommandBuffer; + class CommandPool { + protected: + VkCommandPool mPtr; + Device& mDevice; + std::vector mBufferList; + int top = 0; + public: + CommandPool(Device& device, VkCommandPoolCreateFlags queueFlags, uint32_t queueIndex); + + VkCommandBuffer Allocate(VkCommandBufferLevel level); + CommandBuffer* Pop(); + VkCommandPool& Ptr() { + return mPtr; + }; + }; +} \ No newline at end of file diff --git a/engine/src/engine/vulkanapi/wrapper/device.cpp b/engine/src/engine/vulkanapi/wrapper/device.cpp index 06cef48..d202fe2 100644 --- a/engine/src/engine/vulkanapi/wrapper/device.cpp +++ b/engine/src/engine/vulkanapi/wrapper/device.cpp @@ -1,5 +1,6 @@ #include "device.h" #include "device_creator.h" +#include "queue.h" #include "zlog.h" namespace vulkanapi { Device::Device(DeviceCreator& Creator) @@ -32,24 +33,25 @@ namespace vulkanapi { if ((result != VK_SUCCESS) || (mPtr == VK_NULL_HANDLE)) { zlog::error("Could not create logical device."); } + for (auto& queue : Creator.desiredQueues) { + Queue* gq = new Queue(queue.name, queue.queueFamilyIndex, VK_NULL_HANDLE); + vkGetDeviceQueue(mPtr, queue.queueFamilyIndex, 0, &(gq->Ptr())); + mQueueMap.emplace(queue.name, gq); + } } - VkCommandPool Device::CreateCommandPool(const VkCommandPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator) - { - VkCommandPool pCommandPool; - vkCreateCommandPool(mPtr, pCreateInfo, pAllocator, &pCommandPool); - return pCommandPool; + Device::~Device() { + for (auto& queue : mQueueMap) { + delete queue.second; + } + mQueueMap.clear(); } - VkQueue Device::GetQueue(uint32_t familyIndex, uint32_t queueIndex) + Queue* Device::GetQueue(const std::string& name) { - VkQueue pQueue; - vkGetDeviceQueue(mPtr, familyIndex, queueIndex, &pQueue); - return pQueue; - } - VkDescriptorPool Device::CreateDescriptorPool(const VkDescriptorPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator) - { - VkDescriptorPool pDescriptorPool; - vkCreateDescriptorPool(mPtr, pCreateInfo, pAllocator, &pDescriptorPool); - return pDescriptorPool; + auto it = mQueueMap.find(name); + if (it != mQueueMap.end()) { + return it->second; + } + return nullptr; } } diff --git a/engine/src/engine/vulkanapi/wrapper/device.h b/engine/src/engine/vulkanapi/wrapper/device.h index 47a484a..e8b6f5a 100644 --- a/engine/src/engine/vulkanapi/wrapper/device.h +++ b/engine/src/engine/vulkanapi/wrapper/device.h @@ -1,16 +1,19 @@ #pragma once #include +#include #include "../vulkan.h" namespace vulkanapi { class DeviceCreator; + class Queue; class Device{ friend class DeviceCreator; protected: VkDevice mPtr{ NULL }; VkPhysicalDevice mPhysical{NULL}; + std::map mQueueMap; public: - VkDevice Ptr() { + VkDevice& Ptr() { return mPtr; } VkPhysicalDevice GetPhysical() { @@ -18,8 +21,8 @@ namespace vulkanapi { } public: Device(DeviceCreator& Creator); - VkCommandPool CreateCommandPool(const VkCommandPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator); - VkQueue GetQueue(uint32_t familyIndex, uint32_t queueIndex); - VkDescriptorPool CreateDescriptorPool(const VkDescriptorPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator); + ~Device(); + + Queue* GetQueue(const std::string& name); }; }; \ No newline at end of file diff --git a/engine/src/engine/vulkanapi/wrapper/device_creator.cpp b/engine/src/engine/vulkanapi/wrapper/device_creator.cpp index 404fd21..795a59d 100644 --- a/engine/src/engine/vulkanapi/wrapper/device_creator.cpp +++ b/engine/src/engine/vulkanapi/wrapper/device_creator.cpp @@ -11,7 +11,7 @@ namespace vulkanapi { { } - void DeviceCreator::AddQueue(std::string name, VkQueueFlags flag, float prioritie) + void DeviceCreator::AddQueue(const std::string& name, VkQueueFlags flag, float prioritie) { desiredQueues.emplace_back(name, flag, prioritie); } @@ -88,7 +88,7 @@ namespace vulkanapi { queue_prioritie.emplace_back(std::vector{}); } uint32_t max_value = 1; - for (const auto& queue : desiredQueues) { + for (auto& queue : desiredQueues) { uint32_t index = -1; bool bFind = false; for (uint32_t i = 0; i < size; i++) { @@ -102,6 +102,7 @@ namespace vulkanapi { } } if (index != -1 && queue_create_infos[index].queueCount < queue_families[index].queueCount) { + queue.queueFamilyIndex = index; queue_create_infos[index].queueCount++; queue_prioritie[index].push_back(queue.prioritie); } diff --git a/engine/src/engine/vulkanapi/wrapper/device_creator.h b/engine/src/engine/vulkanapi/wrapper/device_creator.h index 1555953..439bbc3 100644 --- a/engine/src/engine/vulkanapi/wrapper/device_creator.h +++ b/engine/src/engine/vulkanapi/wrapper/device_creator.h @@ -12,23 +12,24 @@ namespace vulkanapi { class DesiredQueue final { public: - std::string name; + const std::string& name; VkQueueFlags flag; float prioritie; - DesiredQueue(std::string name, VkQueueFlags flag, float prioritie) - : name(name), flag(flag), prioritie(prioritie) {} + int queueFamilyIndex; + DesiredQueue(const std::string& name, VkQueueFlags flag, float prioritie) + : name(name), flag(flag), prioritie(prioritie), queueFamilyIndex(0){} }; public: VkPhysicalDeviceFeatures desiredPhysicalDeviceFeatures; VkPhysicalDeviceType desiredPhysicalDeviceType; - std::vector desiredExtensions; + std::vector desiredExtensions; std::vector desiredQueues; public: Instance& instance; public: DeviceCreator(Instance& instance); - void AddQueue(std::string name, VkQueueFlags flag, float prioritie); + void AddQueue(const std::string& name, VkQueueFlags flag, float prioritie); void AddExtension(std::string extensionName); void AddWindowExtension(); bool CheckProperty(const VkPhysicalDevice device); diff --git a/engine/src/engine/vulkanapi/wrapper/instance.h b/engine/src/engine/vulkanapi/wrapper/instance.h index 76504c3..498100e 100644 --- a/engine/src/engine/vulkanapi/wrapper/instance.h +++ b/engine/src/engine/vulkanapi/wrapper/instance.h @@ -12,7 +12,7 @@ namespace vulkanapi { public: Instance(InstanceCreator& Creator); - VkInstance Ptr() { + VkInstance& Ptr() { return mPtr; } bool EnumerateAvailablePhysicalDevices(std::vector& available_devices); diff --git a/engine/src/engine/vulkanapi/wrapper/queue.cpp b/engine/src/engine/vulkanapi/wrapper/queue.cpp new file mode 100644 index 0000000..274b27b --- /dev/null +++ b/engine/src/engine/vulkanapi/wrapper/queue.cpp @@ -0,0 +1,13 @@ +#include "queue.h" +namespace vulkanapi { + const std::string Queue::TransferQueue("TransferQueue"); + const std::string Queue::RenderQueue("RenderQueue"); + const std::string Queue::ComputeQueue("ComputeQueue"); + const std::string Queue::PresentQueue("PresentQueue"); + Queue::Queue(const std::string& name, uint32_t queueFamilyIndex, VkQueue queue) + : mName(name), mQueueFamilyIndex(queueFamilyIndex), mPtr(queue), mMtx() + { + + } +} + diff --git a/engine/src/engine/vulkanapi/wrapper/queue.h b/engine/src/engine/vulkanapi/wrapper/queue.h new file mode 100644 index 0000000..664199f --- /dev/null +++ b/engine/src/engine/vulkanapi/wrapper/queue.h @@ -0,0 +1,28 @@ +#pragma once +#include +#include +#include "../vulkan.h" +namespace vulkanapi { + class Device; + class CommandBuffer; + class Queue { + protected: + VkQueue mPtr; + uint32_t mQueueFamilyIndex; + const std::string mName; + public: + Queue(const std::string& name, uint32_t queueFamilyIndex, VkQueue queue); + uint32_t QueueFamilyIndex() + { + return mQueueFamilyIndex; + } + VkQueue& Ptr() { + return mPtr; + } + public: + static const std::string TransferQueue; + static const std::string RenderQueue; + static const std::string ComputeQueue; + static const std::string PresentQueue; + }; +} \ No newline at end of file