update zlib.zstd.pool
This commit is contained in:
parent
e7c702113f
commit
5e9b0bb305
51
engine/3rdparty/zlib/include/zstd/pool.h
vendored
Normal file
51
engine/3rdparty/zlib/include/zstd/pool.h
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
#include <concepts>
|
||||
namespace zstd {
|
||||
template<std::move_constructible T>
|
||||
class pool {
|
||||
using NewFn = std::function<T()>;
|
||||
protected:
|
||||
int m_tail;
|
||||
int m_head;
|
||||
int m_size;
|
||||
T* m_buf;
|
||||
NewFn newT;
|
||||
public:
|
||||
~pool() {
|
||||
reset();
|
||||
free(m_buf);
|
||||
}
|
||||
pool(NewFn newT, int size = 1) : newT(newT), m_tail(0), m_head(0), m_buf((T*)malloc(sizeof(T)* size)), m_size(size) {}
|
||||
int head() {
|
||||
return m_head;
|
||||
}
|
||||
int tail() {
|
||||
return m_tail;
|
||||
}
|
||||
int count() {
|
||||
return m_head - m_tail;
|
||||
}
|
||||
void reset() {
|
||||
for (int i = m_tail; i < m_head; i++) {
|
||||
std::destroy_at(m_buf + (m_tail % m_size));
|
||||
}
|
||||
m_tail = 0;
|
||||
m_head = 0;
|
||||
}
|
||||
template<typename... Args>
|
||||
void release(Args... args) {
|
||||
if (m_head >= m_tail + m_size) {
|
||||
return;
|
||||
}
|
||||
std::construct_at(m_buf + m_head % m_size, std::forward<Args>(args)...);
|
||||
m_head++;
|
||||
};
|
||||
T acquire() {
|
||||
if (m_tail == m_head) {
|
||||
return std::move(newT());
|
||||
}
|
||||
int tail = m_tail % m_size;
|
||||
m_tail++;
|
||||
return std::move(*(m_buf + tail));
|
||||
};
|
||||
};
|
||||
}
|
||||
58
engine/3rdparty/zlib/include/zstd/pool_static.h
vendored
Normal file
58
engine/3rdparty/zlib/include/zstd/pool_static.h
vendored
Normal file
@ -0,0 +1,58 @@
|
||||
#include <concepts>
|
||||
namespace zstd {
|
||||
template<size_t T>
|
||||
struct static_buffer {
|
||||
char data[T];
|
||||
};
|
||||
template<std::move_constructible T, size_t T_capacity = 1>
|
||||
class channel_static {
|
||||
static_assert(T_capacity != 0);
|
||||
protected:
|
||||
int m_tail;
|
||||
int m_head;
|
||||
static_buffer<sizeof(T)> m_buf[T_capacity];
|
||||
std::mutex m_mtx;
|
||||
std::condition_variable m_cv;
|
||||
public:
|
||||
~channel_static() {
|
||||
reset();
|
||||
}
|
||||
channel_static() : m_tail(0), m_head(0), m_buf() {}
|
||||
int head() {
|
||||
return m_head;
|
||||
}
|
||||
int tail() {
|
||||
return m_tail;
|
||||
}
|
||||
int count() {
|
||||
return m_head - m_tail;
|
||||
}
|
||||
void reset() {
|
||||
for (int i = m_tail; i < m_head; i++) {
|
||||
std::destroy_at((T*)(m_buf + m_tail % T_capacity));
|
||||
}
|
||||
m_tail = 0;
|
||||
m_head = 0;
|
||||
}
|
||||
template<typename... Args>
|
||||
void release(Args... args) {
|
||||
std::unique_lock<std::mutex> lck(m_mtx);
|
||||
while (m_head >= m_tail + T_capacity) {
|
||||
m_cv.wait(lck);
|
||||
}
|
||||
std::construct_at((T*)(m_buf + m_head % T_capacity), std::forward<Args>(args)...);
|
||||
if (m_head++ == m_tail)
|
||||
m_cv.notify_one();
|
||||
};
|
||||
T acquire() {
|
||||
std::unique_lock<std::mutex> lck(m_mtx);
|
||||
while (m_tail >= m_head) {
|
||||
m_cv.wait(lck);
|
||||
}
|
||||
int tail = m_tail % T_capacity;
|
||||
if (m_tail++ == m_head - T_capacity)
|
||||
m_cv.notify_one();
|
||||
return std::move(*(T*)(m_buf + tail));
|
||||
};
|
||||
};
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
#include <condition_variable>
|
||||
#include <semaphore>
|
||||
#include <iostream>
|
||||
#include <concepts>
|
||||
namespace zstd {
|
||||
template<std::move_constructible T>
|
||||
class channel {
|
||||
@ -1,6 +1,6 @@
|
||||
#include <condition_variable>
|
||||
#include <semaphore>
|
||||
#include <iostream>
|
||||
#include <concepts>
|
||||
namespace zstd {
|
||||
template<size_t T>
|
||||
struct static_buffer {
|
||||
@ -1,29 +1,29 @@
|
||||
set_languages("cxx20")
|
||||
target("zcoro")
|
||||
target("zlib")
|
||||
set_kind("static")
|
||||
add_includedirs("include", {public = true})
|
||||
add_files("src/**/*.cpp")
|
||||
add_headerfiles("include/**/*.h")
|
||||
target("zcoro_test")
|
||||
target("zlib_test")
|
||||
set_kind("binary")
|
||||
add_deps("zcoro")
|
||||
add_deps("zlib")
|
||||
add_files("main.cpp")
|
||||
-- target("zcoro_test01_mutex")
|
||||
-- target("zlib_test01_mutex")
|
||||
-- set_kind("binary")
|
||||
-- add_deps("zcoro")
|
||||
-- add_deps("zlib")
|
||||
-- add_files("test/01mutex.cpp")
|
||||
|
||||
-- target("zcoro_test02_condition")
|
||||
-- target("zlib_test02_condition")
|
||||
-- set_kind("binary")
|
||||
-- add_deps("zcoro")
|
||||
-- add_deps("zlib")
|
||||
-- add_files("test/02condition.cpp")
|
||||
|
||||
target("zcoro_test03_semaphore")
|
||||
target("zlib_test03_semaphore")
|
||||
set_kind("binary")
|
||||
add_deps("zcoro")
|
||||
add_deps("zlib")
|
||||
add_files("test/03semaphore.cpp")
|
||||
|
||||
-- target("zcoro_test04_promise")
|
||||
-- target("zlib_test04_promise")
|
||||
-- set_kind("binary")
|
||||
-- add_deps("zcoro")
|
||||
-- add_deps("zlib")
|
||||
-- add_files("test/04promise.cpp")
|
||||
@ -24,16 +24,8 @@ namespace engineapi
|
||||
string mName;
|
||||
public:
|
||||
Asset(string name, uint32_t flags):mName(name),mFlags(flags) {};
|
||||
virtual void SyncLoad() {};
|
||||
virtual void AsyncLoad() {};
|
||||
virtual void BeginLoad() {
|
||||
mFlags |= ASSET_LOADING_FLAG;
|
||||
if (IsAsync()) {
|
||||
AsyncLoad();
|
||||
}
|
||||
else {
|
||||
SyncLoad();
|
||||
}
|
||||
};
|
||||
virtual void EndLoad() {
|
||||
mFlags &= ~ASSET_LOADING_FLAG;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
#include "asset.h"
|
||||
#include "../asset.h"
|
||||
#include "math/math.h"
|
||||
#include "asset_enum.h"
|
||||
// 顶点最多关联4个骨骼
|
||||
@ -1,2 +0,0 @@
|
||||
#pragma once
|
||||
#include "asset/asset_struct.h"
|
||||
2
engine/src/engine/render/asset/asset_render.h
Normal file
2
engine/src/engine/render/asset/asset_render.h
Normal file
@ -0,0 +1,2 @@
|
||||
#pragma once
|
||||
#include "asset/render/asset_struct.h"
|
||||
@ -1,4 +1,4 @@
|
||||
#include "asset.h"
|
||||
#include "asset_render.h"
|
||||
|
||||
namespace engineapi {
|
||||
class Material : public Asset {
|
||||
|
||||
@ -8,8 +8,9 @@ namespace engineapi {
|
||||
{
|
||||
BeginLoad();
|
||||
}
|
||||
void Mesh::SyncLoad()
|
||||
void Mesh::BeginLoad()
|
||||
{
|
||||
RenderAPI::GetInstance()->SetStaticMesh(VAO, mVertices, mIndices, IsAsync());
|
||||
Asset::BeginLoad();
|
||||
RenderAPI::GetInstance()->SetStaticMesh(this);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
#pragma once
|
||||
#include "asset.h"
|
||||
#include "asset_render.h"
|
||||
namespace engineapi {
|
||||
class Texture;
|
||||
class Material;
|
||||
class Mesh : public Asset {
|
||||
friend class RenderVulkanAPI;
|
||||
protected:
|
||||
uint32_t VAO = 0;
|
||||
vector<Vertex> mVertices;
|
||||
@ -11,6 +12,6 @@ namespace engineapi {
|
||||
|
||||
public:
|
||||
Mesh(string name, uint32_t flags, vector<Vertex>& vertices, vector<uint32_t>& indices);
|
||||
void SyncLoad()override;
|
||||
void BeginLoad()override;
|
||||
};
|
||||
};
|
||||
@ -1,12 +1,14 @@
|
||||
#include "model.h"
|
||||
#include "zlog.h"
|
||||
#include "mesh.h"
|
||||
#include "assimp/Importer.hpp"
|
||||
#include "assimp/scene.h"
|
||||
#include "assimp/postprocess.h"
|
||||
#include "asset/asset_manager.h"
|
||||
namespace engineapi {
|
||||
void Model::SyncLoad()
|
||||
void Model::BeginLoad()
|
||||
{
|
||||
Asset::BeginLoad();
|
||||
// 用ASSIMP加载模型文件
|
||||
Assimp::Importer importer;
|
||||
const aiScene* scene = importer.ReadFile(mName, aiProcess_Triangulate | aiProcess_FlipUVs | aiProcess_CalcTangentSpace
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
#include "mesh.h"
|
||||
#include "asset_render.h"
|
||||
class aiNode;
|
||||
class aiMesh;
|
||||
class aiScene;
|
||||
@ -10,7 +10,7 @@ namespace engineapi {
|
||||
|
||||
public:
|
||||
using Asset::Asset;
|
||||
void SyncLoad()override;
|
||||
void BeginLoad()override;
|
||||
void ProcessNode(const aiNode* pNode, const aiScene* pScene);
|
||||
Mesh* ProcessMesh(const aiMesh* mesh);
|
||||
};
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
#include "asset.h"
|
||||
#include "asset_render.h"
|
||||
|
||||
namespace engineapi {
|
||||
class Texture : public Asset {
|
||||
|
||||
@ -10,7 +10,7 @@ namespace engineapi {
|
||||
void RenderAPI::MakeInstance()
|
||||
{
|
||||
#ifdef VULKAN_API
|
||||
Instance = new vulkanapi::RenderVulkanAPI();
|
||||
Instance = new RenderVulkanAPI();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -1,13 +1,14 @@
|
||||
#pragma once
|
||||
#include "asset/asset_struct.h"
|
||||
#include "asset/asset_render.h"
|
||||
namespace engineapi
|
||||
{
|
||||
class Mesh;
|
||||
class RenderAPI
|
||||
{
|
||||
public:
|
||||
virtual void BeginFrame() = 0;
|
||||
virtual void EndFrame() = 0;
|
||||
virtual void SetStaticMesh(uint32_t& VAO, vector<Vertex>& vertices, vector<uint32_t>& indices, bool Async) = 0;
|
||||
virtual void SetStaticMesh(Mesh* mesh) = 0;
|
||||
public:
|
||||
static RenderAPI* Instance;
|
||||
static void MakeInstance();
|
||||
|
||||
@ -12,9 +12,6 @@ namespace vulkanapi {
|
||||
|
||||
auto deviceCreator = DeviceCreator(*mInstance);
|
||||
deviceCreator.AddWindowExtension();
|
||||
deviceCreator.desiredPhysicalDeviceFeatures.independentBlend = true;
|
||||
deviceCreator.desiredPhysicalDeviceFeatures.depthClamp = true;
|
||||
deviceCreator.desiredPhysicalDeviceFeatures.geometryShader = VK_TRUE;
|
||||
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);
|
||||
|
||||
@ -1,52 +1,43 @@
|
||||
#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 string& name, Device& device, Queue& queue, VkCommandPoolCreateFlags queueFlags)
|
||||
:mName(name)
|
||||
,mDevice(device)
|
||||
,mQueue(queue)
|
||||
,mCommandPool(CommandPool(device, queueFlags, queue.QueueFamilyIndex()))
|
||||
,mWork(CommandThreadWorker(name, 64))
|
||||
,mImmediateExeCmd(CommandBuffer(mCommandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY))
|
||||
{
|
||||
mCommandPool = new CommandPool(device, queueFlags, queue.QueueFamilyIndex());
|
||||
mWork = new CommandThreadWorker(name, 64);
|
||||
|
||||
}
|
||||
void CommandWorker::Invoke(voidFn fn)
|
||||
{
|
||||
mWork->Invoke(fn);
|
||||
mWork.Invoke(fn);
|
||||
}
|
||||
|
||||
void CommandWorker::InvokeBuffer(commandFn fn)
|
||||
void CommandWorker::InvokeBuffer(commandFn fn, voidFn callback)
|
||||
{
|
||||
mWork->Invoke([=]() {
|
||||
Buffer(fn);
|
||||
mWork.Invoke([=]() {
|
||||
CommandBuffer cmd = mCommandPool.Pop();
|
||||
Buffer(cmd, fn, callback);
|
||||
});
|
||||
}
|
||||
|
||||
void CommandWorker::Buffer(commandFn fn)
|
||||
void CommandWorker::Buffer(CommandBuffer& cmd, commandFn fn, voidFn callback)
|
||||
{
|
||||
CommandBuffer* cmd = mCommandPool->Pop();
|
||||
cmd->BeginRecord(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
|
||||
cmd.BeginRecord(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
|
||||
fn(cmd);
|
||||
cmd->EndRecord();
|
||||
}
|
||||
|
||||
void CommandWorker::InvokeSubmit()
|
||||
{
|
||||
mWork->Invoke([=]() {
|
||||
Submit();
|
||||
});
|
||||
}
|
||||
|
||||
void CommandWorker::Submit()
|
||||
{
|
||||
|
||||
cmd.EndRecord();
|
||||
cmd.Submit(mQueue.Ptr());
|
||||
cmd.WaitFofFence(mDevice.Ptr());
|
||||
mCommandPool.Push(cmd);
|
||||
callback();
|
||||
}
|
||||
|
||||
void CommandWorker::Flush()
|
||||
{
|
||||
mWork->SyncInvoke([]() {});
|
||||
mWork.SyncInvoke([]() {});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,24 +1,28 @@
|
||||
#pragma once
|
||||
#include "../vulkan.h"
|
||||
#include "thread_worker.h"
|
||||
#include "../wrapper/commandpool.h"
|
||||
#include "../wrapper/commandbuffer.h"
|
||||
namespace vulkanapi {
|
||||
class Device;
|
||||
class CommandThreadWorker;
|
||||
class CommandPool;
|
||||
class Queue;
|
||||
class CommandWorker {
|
||||
protected:
|
||||
Device& mDevice;
|
||||
Queue& mQueue;
|
||||
const string& mName;
|
||||
CommandThreadWorker* mWork;
|
||||
CommandPool* mCommandPool;
|
||||
CommandThreadWorker mWork;
|
||||
CommandPool mCommandPool;
|
||||
CommandBuffer mImmediateExeCmd;
|
||||
public:
|
||||
CommandWorker(const 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 InvokeBuffer(commandFn fn, voidFn callback);
|
||||
void Buffer(CommandBuffer& cmd,commandFn fn, voidFn callback);
|
||||
void Flush();
|
||||
void ImmediatelyExecute(commandFn fn, voidFn callback) {
|
||||
Buffer(mImmediateExeCmd, fn , callback);
|
||||
}
|
||||
};
|
||||
};
|
||||
@ -13,5 +13,5 @@ using std::string;
|
||||
using std::vector;
|
||||
using std::map;
|
||||
using voidFn = std::function<void()>;
|
||||
using commandFn = std::function<void(CommandBuffer* cmd)>;
|
||||
using commandFn = std::function<void(CommandBuffer& cmd)>;
|
||||
}
|
||||
@ -3,7 +3,7 @@
|
||||
// AMD写的Vulkan内存分配器
|
||||
#include "vk_mem_alloc.h"
|
||||
#include "math/matrix4.h"
|
||||
#include "asset/asset_struct.h"
|
||||
#include "render/asset/asset_render.h"
|
||||
using engineapi::Matrix4;
|
||||
using engineapi::FrameBufferType;
|
||||
using engineapi::ClearInfo;
|
||||
|
||||
@ -3,7 +3,8 @@
|
||||
#include "wrapper/buffer.h"
|
||||
#include "wrapper/commandbuffer.h"
|
||||
#include "thread/worker.h"
|
||||
namespace vulkanapi {
|
||||
#include "render/asset/mesh.h"
|
||||
namespace engineapi {
|
||||
RenderVulkanAPI::RenderVulkanAPI()
|
||||
:backend("vulkan")
|
||||
{
|
||||
@ -17,14 +18,14 @@ namespace vulkanapi {
|
||||
{
|
||||
|
||||
}
|
||||
void RenderVulkanAPI::SetStaticMesh(uint32_t& VAO, vector<Vertex>& vertices, vector<uint32_t>& indices, bool Async)
|
||||
void RenderVulkanAPI::SetStaticMesh(Mesh* mesh)
|
||||
{
|
||||
auto meshBuffer = GetNextVAO(VAO);
|
||||
meshBuffer->indexCount = indices.size();
|
||||
meshBuffer->vertexCount = vertices.size();
|
||||
auto meshBuffer = GetNextVAO(mesh->VAO);
|
||||
meshBuffer->indexCount = mesh->mIndices.size();
|
||||
meshBuffer->vertexCount = mesh->mVertices.size();
|
||||
|
||||
// ----------------------------------------------- Vertex Buffer -----------------------------------------------
|
||||
VkDeviceSize vertexBufferSize = sizeof(Vertex) * vertices.size();
|
||||
VkDeviceSize vertexBufferSize = sizeof(Vertex) * mesh->mVertices.size();
|
||||
VmaAllocationCreateInfo vertexStagingAllocInfo = {};
|
||||
VkBufferCreateInfo vertexStagingBufferInfo = Buffer::MakeStageInfo(vertexStagingAllocInfo, vertexBufferSize);
|
||||
|
||||
@ -32,20 +33,25 @@ namespace vulkanapi {
|
||||
VkBuffer vertexStagingBuffer = Buffer::CreateBuffer(vertexStagingBufferInfo, vertexStagingAllocInfo, vertexStagingBufferAlloc);
|
||||
|
||||
// 拷贝数据到StagingBuffer
|
||||
Buffer::CopyData(vertexStagingBufferAlloc, vertices.data(), vertexBufferSize);
|
||||
Buffer::CopyData(vertexStagingBufferAlloc, mesh->mVertices.data(), vertexBufferSize);
|
||||
|
||||
VkBufferUsageFlags flags = 0;//加入光线追踪
|
||||
VmaAllocationCreateInfo vertexBufferAllocInfo = {};
|
||||
VkBufferCreateInfo vertexBufferInfo = Buffer::MakeDeviceInfo(vertexBufferAllocInfo, vertexBufferSize, flags);
|
||||
meshBuffer->vertexBuffer = Buffer::CreateBuffer(vertexBufferInfo, vertexBufferAllocInfo, meshBuffer->vertexBufferAlloc);
|
||||
auto fn = [=](CommandBuffer* cmd) {
|
||||
cmd->CmdCopyBuffer(vertexStagingBuffer, meshBuffer->vertexBuffer, vertexBufferSize);
|
||||
auto fn = [=](CommandBuffer& cmd) {
|
||||
cmd.CmdCopyBuffer(vertexStagingBuffer, meshBuffer->vertexBuffer, vertexBufferSize);
|
||||
};
|
||||
if (Async) {
|
||||
Backend::TransferWorker->InvokeBuffer(fn);
|
||||
auto callback = [=]() {
|
||||
// 销毁StagingBuffer
|
||||
Buffer::DestroyBuffer(vertexStagingBuffer, vertexStagingBufferAlloc);
|
||||
mesh->EndLoad();
|
||||
};
|
||||
if (mesh->IsAsync()) {
|
||||
Backend::TransferWorker->InvokeBuffer(fn, callback);
|
||||
}
|
||||
else {
|
||||
Backend::TransferWorker->InvokeBuffer(fn);
|
||||
Backend::TransferWorker->ImmediatelyExecute(fn, callback);
|
||||
}
|
||||
}
|
||||
VulkanVAO* RenderVulkanAPI::GetNextVAO(uint32_t& VAO_index)
|
||||
|
||||
@ -2,10 +2,10 @@
|
||||
#include "backend.h"
|
||||
#include "render/renderapi.h"
|
||||
#include "vulkan_struct.h"
|
||||
using engineapi::Vertex;
|
||||
namespace vulkanapi
|
||||
using namespace vulkanapi;
|
||||
namespace engineapi
|
||||
{
|
||||
class RenderVulkanAPI : public engineapi::RenderAPI
|
||||
class RenderVulkanAPI : public RenderAPI
|
||||
{
|
||||
public:
|
||||
Backend backend;
|
||||
@ -15,13 +15,12 @@ namespace vulkanapi
|
||||
|
||||
virtual void BeginFrame()override;
|
||||
virtual void EndFrame()override;
|
||||
|
||||
virtual void SetStaticMesh(uint32_t& VAO, vector<Vertex>& vertices, vector<uint32_t>& indices, bool Async)override;
|
||||
virtual void SetStaticMesh(Mesh* mesh)override;
|
||||
public:
|
||||
VulkanVAO* GetNextVAO(uint32_t& VAO_index);
|
||||
public:
|
||||
static RenderVulkanAPI* GetInstance() {
|
||||
return (RenderVulkanAPI*)engineapi::RenderAPI::GetInstance();
|
||||
return (RenderVulkanAPI*)RenderAPI::GetInstance();
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -6,6 +6,7 @@
|
||||
#include "wrapper/swapchain_creator.h"
|
||||
#include "vulkanapi.h"
|
||||
#include "zlog.h"
|
||||
using engineapi::RenderVulkanAPI;
|
||||
namespace vulkanapi {
|
||||
Window::Window(int frames, uint32_t width, uint32_t height, const char* title)
|
||||
:engineapi::Window(width, height , title)
|
||||
|
||||
@ -5,7 +5,7 @@ namespace vulkanapi {
|
||||
class Swapchain;
|
||||
class Window : public engineapi::Window {
|
||||
protected:
|
||||
VkSurfaceKHR mSurfaceKHR{NULL};
|
||||
VkSurfaceKHR mSurfaceKHR;
|
||||
Swapchain* mSwapchain;
|
||||
public:
|
||||
Window(int frames, uint32_t width, uint32_t height, const char* title);
|
||||
|
||||
@ -59,4 +59,9 @@ namespace vulkanapi {
|
||||
memcpy(vertexData, data, size);
|
||||
vmaUnmapMemory(vmaAllocator, allocation);
|
||||
}
|
||||
void Buffer::DestroyBuffer(VkBuffer buffer, VmaAllocation bufferAlloc)
|
||||
{
|
||||
// 销毁StagingBuffer
|
||||
vmaDestroyBuffer(vmaAllocator, buffer, bufferAlloc);
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,5 +14,6 @@ namespace vulkanapi {
|
||||
VmaAllocationCreateInfo& allocationCreateInfo,
|
||||
VmaAllocation& allocation);
|
||||
static void CopyData(VmaAllocation& allocation,void* data, VkDeviceSize size);
|
||||
static void DestroyBuffer(VkBuffer buffer, VmaAllocation bufferAlloc);
|
||||
};
|
||||
}
|
||||
@ -3,9 +3,30 @@
|
||||
#include "device.h"
|
||||
namespace vulkanapi {
|
||||
CommandBuffer::CommandBuffer(CommandPool& commandPool, VkCommandBufferLevel level)
|
||||
: mPtr(commandPool.Allocate(level))
|
||||
:mPool(commandPool)
|
||||
,mPtr(commandPool.AllocateBuffer(level))
|
||||
,mFence(commandPool.AllocateFence())
|
||||
{
|
||||
|
||||
}
|
||||
CommandBuffer::~CommandBuffer()
|
||||
{
|
||||
zlog::info("CommandBuffer Destruct {:#x} isNull = {}", (uint64_t)this, mPtr == nullptr || mFence == nullptr);
|
||||
if (mPtr) {
|
||||
mPool.FreeBuffer(mPtr);
|
||||
}
|
||||
if (mFence) {
|
||||
mPool.FreeFence(mFence);
|
||||
}
|
||||
}
|
||||
CommandBuffer::CommandBuffer(CommandBuffer&& other)noexcept
|
||||
: mPtr(other.mPtr)
|
||||
, mFence(other.mFence)
|
||||
, mPool(other.mPool)
|
||||
{
|
||||
other.mPtr = nullptr;
|
||||
other.mFence = nullptr;
|
||||
zlog::info("CommandBuffer MoveConstruct {:#x} => {:#x}", (uint64_t)&other, (uint64_t)this);
|
||||
}
|
||||
void CommandBuffer::Reset()
|
||||
{
|
||||
@ -32,5 +53,17 @@ namespace vulkanapi {
|
||||
copy.size = size;
|
||||
vkCmdCopyBuffer(mPtr, srcBuffer, dstBuffer, 1, ©);
|
||||
}
|
||||
void CommandBuffer::Submit(VkQueue& queue)
|
||||
{
|
||||
VkSubmitInfo submitInfo{};
|
||||
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||
submitInfo.commandBufferCount = 1;
|
||||
submitInfo.pCommandBuffers = &mPtr;
|
||||
vkQueueSubmit(queue, 1, &submitInfo, mFence);
|
||||
}
|
||||
void CommandBuffer::WaitFofFence(VkDevice& device)
|
||||
{
|
||||
vkWaitForFences(device, 1, &mFence, VK_TRUE, UINT64_MAX);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -5,13 +5,24 @@ namespace vulkanapi {
|
||||
class CommandPool;
|
||||
class CommandBuffer {
|
||||
protected:
|
||||
CommandPool& mPool;
|
||||
VkCommandBuffer mPtr;
|
||||
VkFence mFence;
|
||||
public:
|
||||
CommandBuffer(CommandPool& commandPool, VkCommandBufferLevel level);
|
||||
|
||||
~CommandBuffer();
|
||||
CommandBuffer(CommandBuffer&& other)noexcept;
|
||||
VkCommandBuffer& Ptr() {
|
||||
return mPtr;
|
||||
};
|
||||
VkFence& Fence() {
|
||||
return mFence;
|
||||
};
|
||||
void Reset();
|
||||
void BeginRecord(VkCommandBufferUsageFlags flag);
|
||||
void EndRecord();
|
||||
void CmdCopyBuffer(VkBuffer srcBuffer, VkBuffer dstBuffer, VkDeviceSize size);
|
||||
void Submit(VkQueue& queue);
|
||||
void WaitFofFence(VkDevice& device);
|
||||
};
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
#include "commandpool.h"
|
||||
#include "commandbuffer.h"
|
||||
|
||||
#include "device.h"
|
||||
#include "queue.h"
|
||||
#include "zlog.h"
|
||||
@ -7,6 +7,9 @@ namespace vulkanapi {
|
||||
CommandPool::CommandPool(Device& device, VkCommandPoolCreateFlags queueFlags, uint32_t queueIndex)
|
||||
:mPtr(nullptr)
|
||||
,mDevice(device)
|
||||
,mPool([=]()->CommandBuffer {
|
||||
return std::move(CommandBuffer(*this, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
|
||||
}, 256)
|
||||
{
|
||||
VkCommandPoolCreateInfo pCreateInfo{
|
||||
VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
|
||||
@ -16,7 +19,7 @@ namespace vulkanapi {
|
||||
};
|
||||
vkCreateCommandPool(device.Ptr(), &pCreateInfo, nullptr, &mPtr);
|
||||
}
|
||||
VkCommandBuffer CommandPool::Allocate(VkCommandBufferLevel level)
|
||||
VkCommandBuffer CommandPool::AllocateBuffer(VkCommandBufferLevel level)
|
||||
{
|
||||
VkCommandBufferAllocateInfo allocInfo{
|
||||
VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, //sType
|
||||
@ -29,18 +32,21 @@ namespace vulkanapi {
|
||||
vkAllocateCommandBuffers(mDevice.Ptr(), &allocInfo, &cmd);
|
||||
return cmd;
|
||||
}
|
||||
CommandBuffer* CommandPool::Pop()
|
||||
void CommandPool::FreeBuffer(VkCommandBuffer& buf)
|
||||
{
|
||||
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;
|
||||
vkFreeCommandBuffers(mDevice.Ptr(), mPtr, 1, &buf);
|
||||
buf = nullptr;
|
||||
}
|
||||
void CommandPool::FreeFence(VkFence& fence)
|
||||
{
|
||||
vkDestroyFence(mDevice.Ptr(), fence, NULL);
|
||||
fence = nullptr;
|
||||
}
|
||||
VkFence CommandPool::AllocateFence()
|
||||
{
|
||||
VkFence fence;
|
||||
mDevice.CreateFence(fence);
|
||||
return fence;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,22 +1,33 @@
|
||||
#pragma once
|
||||
#include "../vulkan.h"
|
||||
#include "zstd/pool.h"
|
||||
#include "zlog.h"
|
||||
#include "commandbuffer.h"
|
||||
namespace vulkanapi {
|
||||
class Device;
|
||||
class Queue;
|
||||
class CommandBuffer;
|
||||
class CommandPool {
|
||||
protected:
|
||||
VkCommandPool mPtr;
|
||||
Device& mDevice;
|
||||
vector<CommandBuffer*> mBufferList;
|
||||
int top = 0;
|
||||
zstd::pool<CommandBuffer> mPool;
|
||||
public:
|
||||
CommandPool(Device& device, VkCommandPoolCreateFlags queueFlags, uint32_t queueIndex);
|
||||
|
||||
VkCommandBuffer Allocate(VkCommandBufferLevel level);
|
||||
CommandBuffer* Pop();
|
||||
VkCommandBuffer AllocateBuffer(VkCommandBufferLevel level);
|
||||
void FreeBuffer(VkCommandBuffer& buf);
|
||||
void FreeFence(VkFence& fence);
|
||||
VkFence AllocateFence();
|
||||
VkCommandPool& Ptr() {
|
||||
return mPtr;
|
||||
};
|
||||
CommandBuffer Pop()
|
||||
{
|
||||
return std::move(mPool.acquire());
|
||||
}
|
||||
void Push(CommandBuffer& cmd)
|
||||
{
|
||||
mPool.release(std::forward<CommandBuffer>(cmd));
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -5,16 +5,23 @@
|
||||
namespace vulkanapi {
|
||||
Device::Device(DeviceCreator& Creator)
|
||||
{
|
||||
//物理设备
|
||||
Creator.FindDevice(mPhysical);
|
||||
//队列信息
|
||||
vector<VkQueueFamilyProperties> queue_families;
|
||||
Creator.CheckAvailableQueueFamilies(mPhysical, queue_families);
|
||||
vector<VkDeviceQueueCreateInfo> queue_create_infos;
|
||||
vector<vector<float>> queue_prioritie;
|
||||
Creator.QueueCreateInfos(queue_create_infos, queue_prioritie, queue_families);
|
||||
//扩展
|
||||
auto extensions = Creator.EnabledExtensionNames();
|
||||
//特性
|
||||
VkPhysicalDeviceFeatures2 deviceFeatures = Creator.GetDeviceFeature2();
|
||||
VkPhysicalDeviceVulkan12Features deviceVulkan12Features = Creator.GetVulkan12Features();
|
||||
deviceFeatures.pNext = &deviceVulkan12Features;
|
||||
VkDeviceCreateInfo device_create_info = {
|
||||
VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // VkStructureType sType
|
||||
nullptr, // const void * pNext
|
||||
&deviceFeatures, // const void * pNext
|
||||
0, // VkDeviceCreateFlags flags
|
||||
static_cast<uint32_t>(queue_create_infos.size()), // uint32_t queueCreateInfoCount
|
||||
queue_create_infos.data(), // const VkDeviceQueueCreateInfo * pQueueCreateInfos
|
||||
@ -22,7 +29,7 @@ namespace vulkanapi {
|
||||
nullptr, // const char * const * ppEnabledLayerNames
|
||||
static_cast<uint32_t>(extensions.size()), // uint32_t enabledExtensionCount
|
||||
extensions.data(), // const char * const * ppEnabledExtensionNames
|
||||
&Creator.desiredPhysicalDeviceFeatures // const VkPhysicalDeviceFeatures * pEnabledFeatures
|
||||
nullptr // const VkPhysicalDeviceFeatures * pEnabledFeatures
|
||||
};
|
||||
#ifdef Z_USE_GRAPHIC_DEBUG
|
||||
auto layers = Creator.EnabledLayerNames();
|
||||
@ -54,5 +61,14 @@ namespace vulkanapi {
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
bool Device::CreateFence(VkFence& fence)
|
||||
{
|
||||
VkFenceCreateInfo fenceInfo{};
|
||||
fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
||||
// 创建时立刻设置为signaled状态(否则第一次永远等不到)
|
||||
fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
|
||||
VkResult result = vkCreateFence(mPtr, &fenceInfo, nullptr, &fence);
|
||||
return result == VK_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -22,5 +22,6 @@ namespace vulkanapi {
|
||||
~Device();
|
||||
|
||||
Queue* GetQueue(const string& name);
|
||||
bool CreateFence(VkFence& fence);
|
||||
};
|
||||
};
|
||||
@ -119,6 +119,38 @@ namespace vulkanapi {
|
||||
}
|
||||
}
|
||||
}
|
||||
void DeviceCreator::EnableDeviceFeatures()
|
||||
{
|
||||
//pEnabledFeatures 和 pNext是冲突的吗? pNext
|
||||
desiredPhysicalDeviceFeatures.independentBlend = true;
|
||||
desiredPhysicalDeviceFeatures.depthClamp = true;
|
||||
desiredPhysicalDeviceFeatures.geometryShader = VK_TRUE;
|
||||
}
|
||||
VkPhysicalDeviceFeatures2 DeviceCreator::GetDeviceFeature2()
|
||||
{
|
||||
// 明确设备要使用的功能特性
|
||||
VkPhysicalDeviceFeatures2 deviceFeatures = {};
|
||||
deviceFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
|
||||
// 启用对各向异性采样的支持
|
||||
deviceFeatures.features.samplerAnisotropy = VK_TRUE;
|
||||
deviceFeatures.features.geometryShader = VK_TRUE;
|
||||
deviceFeatures.features.sampleRateShading = VK_TRUE;
|
||||
deviceFeatures.features.shaderInt64 = VK_TRUE;
|
||||
return deviceFeatures;
|
||||
}
|
||||
VkPhysicalDeviceVulkan12Features DeviceCreator::GetVulkan12Features()
|
||||
{
|
||||
// 添加Vulkan 1.2的特性
|
||||
VkPhysicalDeviceVulkan12Features deviceVulkan12Features = {};
|
||||
deviceVulkan12Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES;
|
||||
// 启用对Device Address的支持
|
||||
deviceVulkan12Features.bufferDeviceAddress = VK_TRUE;
|
||||
deviceVulkan12Features.runtimeDescriptorArray = VK_TRUE;
|
||||
deviceVulkan12Features.shaderSampledImageArrayNonUniformIndexing = VK_TRUE;
|
||||
deviceVulkan12Features.hostQueryReset = VK_TRUE;
|
||||
deviceVulkan12Features.pNext = nullptr;
|
||||
return deviceVulkan12Features;
|
||||
}
|
||||
void DeviceCreator::AddExtension(string extensionName)
|
||||
{
|
||||
desiredExtensions.push_back(extensionName);
|
||||
|
||||
@ -37,6 +37,9 @@ namespace vulkanapi {
|
||||
void QueueCreateInfos(vector<VkDeviceQueueCreateInfo>& queue_create_infos,
|
||||
vector<vector<float>>& queue_prioritie,
|
||||
vector<VkQueueFamilyProperties>& queue_families);
|
||||
void EnableDeviceFeatures();
|
||||
VkPhysicalDeviceFeatures2 GetDeviceFeature2();
|
||||
VkPhysicalDeviceVulkan12Features GetVulkan12Features();
|
||||
#ifdef Z_USE_GRAPHIC_DEBUG
|
||||
public:
|
||||
vector<string> desiredLayers;
|
||||
|
||||
@ -15,7 +15,7 @@ int main(int argc, char** argv)
|
||||
auto wnd = vulkanapi::Window(3, 640, 720, name);
|
||||
ActorProperty property;
|
||||
property.id = 1;
|
||||
property.flags = Asset::ASSET_SHARED_FLAG;
|
||||
property.flags = Asset::ASSET_SHARED_FLAG | Asset::ASSET_ASYNC_FLAG;
|
||||
property.path = "assets/models/cube.obj";
|
||||
AssetManager instance;
|
||||
AssetManager::Instance = &instance;
|
||||
|
||||
@ -6,7 +6,7 @@ target("zengine")
|
||||
set_kind("binary")
|
||||
set_rundir(".")
|
||||
add_rules("volk.env")
|
||||
add_deps("zcoro","zlog")
|
||||
add_deps("zlib","zlog")
|
||||
add_packages("vulkansdk","tinyobjloader","assimp")
|
||||
add_includedirs("src/engine")
|
||||
add_includedirs("src/3rdparty/volk", "src/3rdparty/vulkan-memory-allocator")
|
||||
|
||||
Loading…
Reference in New Issue
Block a user