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": {
|
"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) {};
|
Asset(std::string& name, uint32_t flags):mName(name),mFlags(flags) {};
|
||||||
virtual void onLoadFinished() { mFlags |= ASSET_LOADED_TYPE; };
|
virtual void onLoadFinished() { mFlags |= ASSET_LOADED_TYPE; };
|
||||||
virtual void SyncLoad() {};
|
virtual void SyncLoad() {};
|
||||||
|
virtual void AsyncLoad() {};
|
||||||
public:
|
public:
|
||||||
inline bool IsShared() {
|
inline bool IsShared() {
|
||||||
return mFlags & ASSET_SHARED_TYPE;
|
return mFlags & ASSET_SHARED_TYPE;
|
||||||
@ -41,8 +41,7 @@ namespace engineapi
|
|||||||
mAssetMap.emplace(asset_path.string(), *asset);
|
mAssetMap.emplace(asset_path.string(), *asset);
|
||||||
}
|
}
|
||||||
if (asset->IsAsync()) {
|
if (asset->IsAsync()) {
|
||||||
//todo: AsyncLoad
|
asset->AsyncLoad();
|
||||||
asset->SyncLoad();
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
asset->SyncLoad();
|
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
|
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")
|
set_kind("static")
|
||||||
add_includedirs("include", {public = true})
|
add_includedirs("include", {public = true})
|
||||||
add_deps("zlog",{public = true})
|
add_deps("zlog",{public = true})
|
||||||
add_files("src/*.cpp")
|
add_files("src/**.cpp")
|
||||||
add_headerfiles("include/*.h")
|
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 "mesh.h"
|
||||||
|
#include "../backend.h"
|
||||||
|
#include "../thread/worker.h"
|
||||||
#include "assimp/Importer.hpp"
|
#include "assimp/Importer.hpp"
|
||||||
#include "assimp/scene.h"
|
#include "assimp/scene.h"
|
||||||
#include "assimp/postprocess.h"
|
#include "assimp/postprocess.h"
|
||||||
|
#include "zlog.h"
|
||||||
namespace vulkanapi {
|
namespace vulkanapi {
|
||||||
void Mesh::SyncLoad()
|
void Mesh::SyncLoad()
|
||||||
{
|
{
|
||||||
|
std::vector<glm::vec3> vertexPositions = std::vector<glm::vec3>();
|
||||||
Assimp::Importer importer;
|
Assimp::Importer importer;
|
||||||
const aiScene* scene = importer.ReadFile(mName, aiProcess_Triangulate | aiProcess_GenSmoothNormals | aiProcess_FlipUVs | aiProcess_CalcTangentSpace);
|
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
|
#pragma once
|
||||||
#include "asset.h"
|
#include "asset.h"
|
||||||
#include "../vulkan.h"
|
#include "../vulkan.h"
|
||||||
|
#include"glm/glm.hpp"
|
||||||
|
|
||||||
namespace vulkanapi {
|
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:
|
public:
|
||||||
void SyncLoad()override;
|
void SyncLoad()override;
|
||||||
|
void AsyncLoad()override;
|
||||||
|
void BindCommand(CommandBuffer& cmd)override;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@ -1,7 +1,10 @@
|
|||||||
#include "backend.h"
|
#include "backend.h"
|
||||||
|
#include "wrapper/queue.h"
|
||||||
|
#include "thread/worker.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "zlog.h"
|
#include "zlog.h"
|
||||||
namespace vulkanapi {
|
namespace vulkanapi {
|
||||||
|
CommandWorker* Backend::TransferWorker = nullptr;
|
||||||
Backend::Backend(const char* appName, int deviceIndex)
|
Backend::Backend(const char* appName, int deviceIndex)
|
||||||
{
|
{
|
||||||
auto instanceCreator = InstanceCreator();
|
auto instanceCreator = InstanceCreator();
|
||||||
@ -10,13 +13,18 @@ namespace vulkanapi {
|
|||||||
auto deviceCreator = DeviceCreator(*mInstance);
|
auto deviceCreator = DeviceCreator(*mInstance);
|
||||||
deviceCreator.AddWindowExtension();
|
deviceCreator.AddWindowExtension();
|
||||||
deviceCreator.desiredPhysicalDeviceFeatures.geometryShader = VK_TRUE;
|
deviceCreator.desiredPhysicalDeviceFeatures.geometryShader = VK_TRUE;
|
||||||
deviceCreator.AddQueue("TransferQueue", VkQueueFlagBits::VK_QUEUE_GRAPHICS_BIT, 1.0);
|
deviceCreator.AddQueue(Queue::TransferQueue, VkQueueFlagBits::VK_QUEUE_GRAPHICS_BIT, 1.0);
|
||||||
deviceCreator.AddQueue("RenderQueue", VkQueueFlagBits::VK_QUEUE_GRAPHICS_BIT, 1.0);
|
deviceCreator.AddQueue(Queue::RenderQueue, VkQueueFlagBits::VK_QUEUE_GRAPHICS_BIT, 1.0);
|
||||||
deviceCreator.AddQueue("ComputeQueue", VkQueueFlagBits::VK_QUEUE_GRAPHICS_BIT, 1.0);
|
deviceCreator.AddQueue(Queue::ComputeQueue, VkQueueFlagBits::VK_QUEUE_GRAPHICS_BIT, 1.0);
|
||||||
deviceCreator.AddQueue("PresentQueue", VkQueueFlagBits::VK_QUEUE_GRAPHICS_BIT, 1.0);
|
deviceCreator.AddQueue(Queue::PresentQueue, VkQueueFlagBits::VK_QUEUE_GRAPHICS_BIT, 1.0);
|
||||||
mDevice = new Device(deviceCreator);
|
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()
|
Backend::~Backend()
|
||||||
{
|
{
|
||||||
@ -27,4 +35,20 @@ namespace vulkanapi {
|
|||||||
delete mDevice;
|
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.h"
|
||||||
#include "wrapper/device_creator.h"
|
#include "wrapper/device_creator.h"
|
||||||
namespace vulkanapi {
|
namespace vulkanapi {
|
||||||
|
class CommandWorker;
|
||||||
class Backend{
|
class Backend{
|
||||||
protected:
|
protected:
|
||||||
Instance* mInstance;
|
Instance* mInstance;
|
||||||
Device* mDevice;
|
Device* mDevice;
|
||||||
|
std::map<const std::string&, CommandWorker*> mWorkerMap;
|
||||||
|
public:
|
||||||
|
static CommandWorker* TransferWorker;
|
||||||
public:
|
public:
|
||||||
Instance& GetInstance() {
|
Instance& GetInstance() {
|
||||||
return *mInstance;
|
return *mInstance;
|
||||||
@ -20,5 +24,8 @@ namespace vulkanapi {
|
|||||||
public:
|
public:
|
||||||
Backend(const char* appName, int deviceIndex = 0);
|
Backend(const char* appName, int deviceIndex = 0);
|
||||||
~Backend();
|
~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
|
#define _USE_GRAPHIC_DEBUG
|
||||||
|
|
||||||
|
class CommandBuffer;
|
||||||
using voidFn = std::function<void()>;
|
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;
|
//Vulkan Function Addr Variable lg:PFN_##name name;
|
||||||
#define EXPORTED_VULKAN_FUNCTION( name ) extern 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.h"
|
||||||
#include "device_creator.h"
|
#include "device_creator.h"
|
||||||
|
#include "queue.h"
|
||||||
#include "zlog.h"
|
#include "zlog.h"
|
||||||
namespace vulkanapi {
|
namespace vulkanapi {
|
||||||
Device::Device(DeviceCreator& Creator)
|
Device::Device(DeviceCreator& Creator)
|
||||||
@ -32,24 +33,25 @@ namespace vulkanapi {
|
|||||||
if ((result != VK_SUCCESS) || (mPtr == VK_NULL_HANDLE)) {
|
if ((result != VK_SUCCESS) || (mPtr == VK_NULL_HANDLE)) {
|
||||||
zlog::error("Could not create logical device.");
|
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)
|
Device::~Device() {
|
||||||
{
|
for (auto& queue : mQueueMap) {
|
||||||
VkCommandPool pCommandPool;
|
delete queue.second;
|
||||||
vkCreateCommandPool(mPtr, pCreateInfo, pAllocator, &pCommandPool);
|
}
|
||||||
return pCommandPool;
|
mQueueMap.clear();
|
||||||
}
|
}
|
||||||
VkQueue Device::GetQueue(uint32_t familyIndex, uint32_t queueIndex)
|
Queue* Device::GetQueue(const std::string& name)
|
||||||
{
|
{
|
||||||
VkQueue pQueue;
|
auto it = mQueueMap.find(name);
|
||||||
vkGetDeviceQueue(mPtr, familyIndex, queueIndex, &pQueue);
|
if (it != mQueueMap.end()) {
|
||||||
return pQueue;
|
return it->second;
|
||||||
}
|
}
|
||||||
VkDescriptorPool Device::CreateDescriptorPool(const VkDescriptorPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator)
|
return nullptr;
|
||||||
{
|
|
||||||
VkDescriptorPool pDescriptorPool;
|
|
||||||
vkCreateDescriptorPool(mPtr, pCreateInfo, pAllocator, &pDescriptorPool);
|
|
||||||
return pDescriptorPool;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,16 +1,19 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <map>
|
||||||
#include "../vulkan.h"
|
#include "../vulkan.h"
|
||||||
|
|
||||||
namespace vulkanapi {
|
namespace vulkanapi {
|
||||||
class DeviceCreator;
|
class DeviceCreator;
|
||||||
|
class Queue;
|
||||||
class Device{
|
class Device{
|
||||||
friend class DeviceCreator;
|
friend class DeviceCreator;
|
||||||
protected:
|
protected:
|
||||||
VkDevice mPtr{ NULL };
|
VkDevice mPtr{ NULL };
|
||||||
VkPhysicalDevice mPhysical{NULL};
|
VkPhysicalDevice mPhysical{NULL};
|
||||||
|
std::map<const std::string&, Queue*> mQueueMap;
|
||||||
public:
|
public:
|
||||||
VkDevice Ptr() {
|
VkDevice& Ptr() {
|
||||||
return mPtr;
|
return mPtr;
|
||||||
}
|
}
|
||||||
VkPhysicalDevice GetPhysical() {
|
VkPhysicalDevice GetPhysical() {
|
||||||
@ -18,8 +21,8 @@ namespace vulkanapi {
|
|||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
Device(DeviceCreator& Creator);
|
Device(DeviceCreator& Creator);
|
||||||
VkCommandPool CreateCommandPool(const VkCommandPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator);
|
~Device();
|
||||||
VkQueue GetQueue(uint32_t familyIndex, uint32_t queueIndex);
|
|
||||||
VkDescriptorPool CreateDescriptorPool(const VkDescriptorPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator);
|
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);
|
desiredQueues.emplace_back(name, flag, prioritie);
|
||||||
}
|
}
|
||||||
@ -88,7 +88,7 @@ namespace vulkanapi {
|
|||||||
queue_prioritie.emplace_back(std::vector<float>{});
|
queue_prioritie.emplace_back(std::vector<float>{});
|
||||||
}
|
}
|
||||||
uint32_t max_value = 1;
|
uint32_t max_value = 1;
|
||||||
for (const auto& queue : desiredQueues) {
|
for (auto& queue : desiredQueues) {
|
||||||
uint32_t index = -1;
|
uint32_t index = -1;
|
||||||
bool bFind = false;
|
bool bFind = false;
|
||||||
for (uint32_t i = 0; i < size; i++) {
|
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) {
|
if (index != -1 && queue_create_infos[index].queueCount < queue_families[index].queueCount) {
|
||||||
|
queue.queueFamilyIndex = index;
|
||||||
queue_create_infos[index].queueCount++;
|
queue_create_infos[index].queueCount++;
|
||||||
queue_prioritie[index].push_back(queue.prioritie);
|
queue_prioritie[index].push_back(queue.prioritie);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,23 +12,24 @@ namespace vulkanapi {
|
|||||||
class DesiredQueue final
|
class DesiredQueue final
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
std::string name;
|
const std::string& name;
|
||||||
VkQueueFlags flag;
|
VkQueueFlags flag;
|
||||||
float prioritie;
|
float prioritie;
|
||||||
DesiredQueue(std::string name, VkQueueFlags flag, float prioritie)
|
int queueFamilyIndex;
|
||||||
: name(name), flag(flag), prioritie(prioritie) {}
|
DesiredQueue(const std::string& name, VkQueueFlags flag, float prioritie)
|
||||||
|
: name(name), flag(flag), prioritie(prioritie), queueFamilyIndex(0){}
|
||||||
};
|
};
|
||||||
public:
|
public:
|
||||||
VkPhysicalDeviceFeatures desiredPhysicalDeviceFeatures;
|
VkPhysicalDeviceFeatures desiredPhysicalDeviceFeatures;
|
||||||
VkPhysicalDeviceType desiredPhysicalDeviceType;
|
VkPhysicalDeviceType desiredPhysicalDeviceType;
|
||||||
std::vector<std::string> desiredExtensions;
|
std::vector<const std::string> desiredExtensions;
|
||||||
std::vector<DesiredQueue> desiredQueues;
|
std::vector<DesiredQueue> desiredQueues;
|
||||||
public:
|
public:
|
||||||
Instance& instance;
|
Instance& instance;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DeviceCreator(Instance& instance);
|
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 AddExtension(std::string extensionName);
|
||||||
void AddWindowExtension();
|
void AddWindowExtension();
|
||||||
bool CheckProperty(const VkPhysicalDevice device);
|
bool CheckProperty(const VkPhysicalDevice device);
|
||||||
|
|||||||
@ -12,7 +12,7 @@ namespace vulkanapi {
|
|||||||
public:
|
public:
|
||||||
Instance(InstanceCreator& Creator);
|
Instance(InstanceCreator& Creator);
|
||||||
|
|
||||||
VkInstance Ptr() {
|
VkInstance& Ptr() {
|
||||||
return mPtr;
|
return mPtr;
|
||||||
}
|
}
|
||||||
bool EnumerateAvailablePhysicalDevices(std::vector<VkPhysicalDevice>& available_devices);
|
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