update zlib.zstd.pool

This commit is contained in:
ouczbs 2024-03-13 22:29:47 +08:00
parent e7c702113f
commit 5e9b0bb305
48 changed files with 343 additions and 120 deletions

View 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));
};
};
}

View 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));
};
};
}

View File

@ -1,6 +1,6 @@
#include <condition_variable>
#include <semaphore>
#include <iostream>
#include <concepts>
namespace zstd {
template<std::move_constructible T>
class channel {

View File

@ -1,6 +1,6 @@
#include <condition_variable>
#include <semaphore>
#include <iostream>
#include <concepts>
namespace zstd {
template<size_t T>
struct static_buffer {

View File

@ -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")

View File

@ -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;

View File

@ -1,5 +1,5 @@
#pragma once
#include "asset.h"
#include "../asset.h"
#include "math/math.h"
#include "asset_enum.h"
// 顶点最多关联4个骨骼

View File

@ -1,2 +0,0 @@
#pragma once
#include "asset/asset_struct.h"

View File

@ -0,0 +1,2 @@
#pragma once
#include "asset/render/asset_struct.h"

View File

@ -1,4 +1,4 @@
#include "asset.h"
#include "asset_render.h"
namespace engineapi {
class Material : public Asset {

View File

@ -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);
}
}

View File

@ -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;
};
};

View File

@ -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

View File

@ -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);
};

View File

@ -1,4 +1,4 @@
#include "asset.h"
#include "asset_render.h"
namespace engineapi {
class Texture : public Asset {

View File

@ -10,7 +10,7 @@ namespace engineapi {
void RenderAPI::MakeInstance()
{
#ifdef VULKAN_API
Instance = new vulkanapi::RenderVulkanAPI();
Instance = new RenderVulkanAPI();
#endif
}
}

View File

@ -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();

View File

@ -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);

View File

@ -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([]() {});
}
}

View File

@ -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);
}
};
};

View File

@ -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)>;
}

View File

@ -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;

View File

@ -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,35 +18,40 @@ 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);
VmaAllocation vertexStagingBufferAlloc;
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)

View File

@ -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();
}
};
}

View File

@ -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)

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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);
};
}

View File

@ -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, &copy);
}
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);
}
}

View File

@ -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);
};
}

View File

@ -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;
}
}

View File

@ -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));
}
};
}

View File

@ -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;
}
}

View File

@ -22,5 +22,6 @@ namespace vulkanapi {
~Device();
Queue* GetQueue(const string& name);
bool CreateFence(VkFence& fence);
};
};

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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")