init thread
This commit is contained in:
parent
f6e3b52dca
commit
1bf3f23303
4
engine/.vscode/settings.json
vendored
4
engine/.vscode/settings.json
vendored
@ -1,5 +1,7 @@
|
||||
{
|
||||
"files.associations": {
|
||||
"vector": "cpp"
|
||||
"vector": "cpp",
|
||||
"chrono": "cpp",
|
||||
"utility": "cpp"
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
@ -41,8 +41,7 @@ namespace engineapi
|
||||
mAssetMap.emplace(asset_path.string(), *asset);
|
||||
}
|
||||
if (asset->IsAsync()) {
|
||||
//todo: AsyncLoad
|
||||
asset->SyncLoad();
|
||||
asset->AsyncLoad();
|
||||
}
|
||||
else {
|
||||
asset->SyncLoad();
|
||||
5
engine/3rdparty/zasset/src/asset.cpp
vendored
5
engine/3rdparty/zasset/src/asset.cpp
vendored
@ -1,5 +0,0 @@
|
||||
#include "asset.h"
|
||||
namespace engineapi
|
||||
{
|
||||
|
||||
}
|
||||
5
engine/3rdparty/zasset/src/zasset/asset.cpp
vendored
Normal file
5
engine/3rdparty/zasset/src/zasset/asset.cpp
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
#include "zasset/asset.h"
|
||||
namespace engineapi
|
||||
{
|
||||
|
||||
}
|
||||
@ -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
|
||||
{
|
||||
4
engine/3rdparty/zasset/xmake.lua
vendored
4
engine/3rdparty/zasset/xmake.lua
vendored
@ -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")
|
||||
add_files("src/**.cpp")
|
||||
add_headerfiles("include/**.h")
|
||||
0
engine/src/engine/vulkanapi/asset/asset.cpp
Normal file
0
engine/src/engine/vulkanapi/asset/asset.cpp
Normal file
10
engine/src/engine/vulkanapi/asset/asset.h
Normal file
10
engine/src/engine/vulkanapi/asset/asset.h
Normal file
@ -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) {};
|
||||
};
|
||||
};
|
||||
@ -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<glm::vec3> vertexPositions = std::vector<glm::vec3>();
|
||||
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)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -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<VertexData> mVertices;
|
||||
std::vector<uint32_t> mIndices;
|
||||
public:
|
||||
void SyncLoad()override;
|
||||
void AsyncLoad()override;
|
||||
void BindCommand(CommandBuffer& cmd)override;
|
||||
};
|
||||
};
|
||||
@ -1,7 +1,10 @@
|
||||
#include "backend.h"
|
||||
#include "wrapper/queue.h"
|
||||
#include "thread/worker.h"
|
||||
#include <iostream>
|
||||
#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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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<const std::string&, CommandWorker*> 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);
|
||||
};
|
||||
};
|
||||
19
engine/src/engine/vulkanapi/thread/record.cpp
Normal file
19
engine/src/engine/vulkanapi/thread/record.cpp
Normal file
@ -0,0 +1,19 @@
|
||||
#include "record.h"
|
||||
#include <iostream>
|
||||
#include <engine/vulkanapi/device/device.h>
|
||||
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);
|
||||
}
|
||||
}
|
||||
16
engine/src/engine/vulkanapi/thread/record.h
Normal file
16
engine/src/engine/vulkanapi/thread/record.h
Normal file
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "engine/vulkanapi/vulkan.h"
|
||||
namespace vulkanapi {
|
||||
class CommandBuffer;
|
||||
typedef void (*CommandFn)(CommandBuffer* buf);
|
||||
class CommandRecord {
|
||||
protected:
|
||||
std::vector<CommandFn> mParts;
|
||||
public:
|
||||
CommandRecord();
|
||||
void Apply(CommandBuffer* buf);
|
||||
void Record(CommandFn cmd);
|
||||
};
|
||||
};
|
||||
31
engine/src/engine/vulkanapi/thread/thread_worker.cpp
Normal file
31
engine/src/engine/vulkanapi/thread/thread_worker.cpp
Normal file
@ -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();
|
||||
}
|
||||
}
|
||||
22
engine/src/engine/vulkanapi/thread/thread_worker.h
Normal file
22
engine/src/engine/vulkanapi/thread/thread_worker.h
Normal file
@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <thread>
|
||||
#include "engine/vulkanapi/vulkan.h"
|
||||
#include "zthread/channel.h"
|
||||
namespace vulkanapi {
|
||||
class CommandThreadWorker {
|
||||
protected:
|
||||
std::thread mThread;
|
||||
std::string mName;
|
||||
zstd::channel<voidFn> mChannel;
|
||||
std::binary_semaphore mSemaphore;
|
||||
protected:
|
||||
void workloop();
|
||||
public:
|
||||
CommandThreadWorker(const std::string name, int buffer);
|
||||
|
||||
void Invoke(voidFn fn);
|
||||
void SyncInvoke(voidFn fn);
|
||||
};
|
||||
};
|
||||
52
engine/src/engine/vulkanapi/thread/worker.cpp
Normal file
52
engine/src/engine/vulkanapi/thread/worker.cpp
Normal file
@ -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([]() {});
|
||||
}
|
||||
|
||||
}
|
||||
25
engine/src/engine/vulkanapi/thread/worker.h
Normal file
25
engine/src/engine/vulkanapi/thread/worker.h
Normal file
@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#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();
|
||||
};
|
||||
};
|
||||
@ -12,8 +12,9 @@ namespace vulkanapi {
|
||||
|
||||
#define _USE_GRAPHIC_DEBUG
|
||||
|
||||
class CommandBuffer;
|
||||
using voidFn = std::function<void()>;
|
||||
using commandFn = std::function<void()>;
|
||||
using commandFn = std::function<void(CommandBuffer* cmd)>;
|
||||
|
||||
//Vulkan Function Addr Variable lg:PFN_##name name;
|
||||
#define EXPORTED_VULKAN_FUNCTION( name ) extern PFN_##name name;
|
||||
|
||||
28
engine/src/engine/vulkanapi/wrapper/commandbuffer.cpp
Normal file
28
engine/src/engine/vulkanapi/wrapper/commandbuffer.cpp
Normal file
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
17
engine/src/engine/vulkanapi/wrapper/commandbuffer.h
Normal file
17
engine/src/engine/vulkanapi/wrapper/commandbuffer.h
Normal file
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#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();
|
||||
};
|
||||
}
|
||||
46
engine/src/engine/vulkanapi/wrapper/commandpool.cpp
Normal file
46
engine/src/engine/vulkanapi/wrapper/commandpool.cpp
Normal file
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
23
engine/src/engine/vulkanapi/wrapper/commandpool.h
Normal file
23
engine/src/engine/vulkanapi/wrapper/commandpool.h
Normal file
@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include "../vulkan.h"
|
||||
namespace vulkanapi {
|
||||
class Device;
|
||||
class Queue;
|
||||
class CommandBuffer;
|
||||
class CommandPool {
|
||||
protected:
|
||||
VkCommandPool mPtr;
|
||||
Device& mDevice;
|
||||
std::vector<CommandBuffer*> mBufferList;
|
||||
int top = 0;
|
||||
public:
|
||||
CommandPool(Device& device, VkCommandPoolCreateFlags queueFlags, uint32_t queueIndex);
|
||||
|
||||
VkCommandBuffer Allocate(VkCommandBufferLevel level);
|
||||
CommandBuffer* Pop();
|
||||
VkCommandPool& Ptr() {
|
||||
return mPtr;
|
||||
};
|
||||
};
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
VkQueue Device::GetQueue(uint32_t familyIndex, uint32_t queueIndex)
|
||||
{
|
||||
VkQueue pQueue;
|
||||
vkGetDeviceQueue(mPtr, familyIndex, queueIndex, &pQueue);
|
||||
return pQueue;
|
||||
Device::~Device() {
|
||||
for (auto& queue : mQueueMap) {
|
||||
delete queue.second;
|
||||
}
|
||||
VkDescriptorPool Device::CreateDescriptorPool(const VkDescriptorPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator)
|
||||
mQueueMap.clear();
|
||||
}
|
||||
Queue* Device::GetQueue(const std::string& name)
|
||||
{
|
||||
VkDescriptorPool pDescriptorPool;
|
||||
vkCreateDescriptorPool(mPtr, pCreateInfo, pAllocator, &pDescriptorPool);
|
||||
return pDescriptorPool;
|
||||
auto it = mQueueMap.find(name);
|
||||
if (it != mQueueMap.end()) {
|
||||
return it->second;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,16 +1,19 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include "../vulkan.h"
|
||||
|
||||
namespace vulkanapi {
|
||||
class DeviceCreator;
|
||||
class Queue;
|
||||
class Device{
|
||||
friend class DeviceCreator;
|
||||
protected:
|
||||
VkDevice mPtr{ NULL };
|
||||
VkPhysicalDevice mPhysical{NULL};
|
||||
std::map<const std::string&, Queue*> 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);
|
||||
};
|
||||
};
|
||||
@ -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<float>{});
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
@ -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<std::string> desiredExtensions;
|
||||
std::vector<const std::string> desiredExtensions;
|
||||
std::vector<DesiredQueue> 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);
|
||||
|
||||
@ -12,7 +12,7 @@ namespace vulkanapi {
|
||||
public:
|
||||
Instance(InstanceCreator& Creator);
|
||||
|
||||
VkInstance Ptr() {
|
||||
VkInstance& Ptr() {
|
||||
return mPtr;
|
||||
}
|
||||
bool EnumerateAvailablePhysicalDevices(std::vector<VkPhysicalDevice>& available_devices);
|
||||
|
||||
13
engine/src/engine/vulkanapi/wrapper/queue.cpp
Normal file
13
engine/src/engine/vulkanapi/wrapper/queue.cpp
Normal file
@ -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()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
28
engine/src/engine/vulkanapi/wrapper/queue.h
Normal file
28
engine/src/engine/vulkanapi/wrapper/queue.h
Normal file
@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <mutex>
|
||||
#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;
|
||||
};
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user