update vulkan api
This commit is contained in:
parent
722396f613
commit
6f423500b6
20
engine/modules/engine/render/include/render/asset/material.h
Normal file
20
engine/modules/engine/render/include/render/asset/material.h
Normal file
@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
#include "asset/asset.h"
|
||||
#include "shader.h"
|
||||
namespace api {
|
||||
class Material : public Asset {
|
||||
protected:
|
||||
RscHandle<Shader> mShader;
|
||||
|
||||
friend class Scene;
|
||||
public:
|
||||
Material();
|
||||
~Material();
|
||||
void BeginLoad() {
|
||||
mShader->BeginLoad();
|
||||
}
|
||||
RscHandle<Shader> GetShader() {
|
||||
return mShader;
|
||||
}
|
||||
};
|
||||
};
|
||||
33
engine/modules/engine/render/include/render/asset/mesh.h
Normal file
33
engine/modules/engine/render/include/render/asset/mesh.h
Normal file
@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
#include "material.h"
|
||||
#include "vertex.h"
|
||||
#include "refl/std/parray.h"
|
||||
namespace api {
|
||||
using refl::parray;
|
||||
class Mesh : public Asset {
|
||||
protected:
|
||||
RscHandle<Material> mMaterial;
|
||||
parray<Vertex> mVertices;
|
||||
vector<uint32_t> mIndices;
|
||||
public:
|
||||
Mesh();
|
||||
void BeginLoad();
|
||||
|
||||
public:
|
||||
Guid GetShaderGuid() {
|
||||
return mMaterial->GetShader().guid;
|
||||
}
|
||||
void SetMaterial(RscHandle<Material> material) {
|
||||
mMaterial = material;
|
||||
}
|
||||
RscHandle<Material> GetMaterial() {
|
||||
return mMaterial;
|
||||
}
|
||||
parray<Vertex>& GetVertices() {
|
||||
return mVertices;
|
||||
}
|
||||
vector<uint32_t>& GetIndices() {
|
||||
return mIndices;
|
||||
}
|
||||
};
|
||||
};
|
||||
25
engine/modules/engine/render/include/render/asset/shader.h
Normal file
25
engine/modules/engine/render/include/render/asset/shader.h
Normal file
@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
#include "asset/res/resource_handle.h"
|
||||
namespace api {
|
||||
class ShaderProgram : public Resource<ShaderProgram> {};
|
||||
class Shader : public Asset {
|
||||
private:
|
||||
UPROPERTY()
|
||||
RscHandle<ShaderProgram> mVert;
|
||||
UPROPERTY()
|
||||
RscHandle<ShaderProgram> mFrag;
|
||||
friend class Scene;
|
||||
public:
|
||||
Shader();
|
||||
~Shader();
|
||||
void BeginLoad();
|
||||
template<typename T = ShaderProgram>
|
||||
RscHandle<T> GetVertHandle() {
|
||||
return mVert;
|
||||
}
|
||||
template<typename T = ShaderProgram>
|
||||
RscHandle<T> GetFragHandle() {
|
||||
return mFrag;
|
||||
}
|
||||
};
|
||||
};
|
||||
46
engine/modules/engine/render/include/render/asset/vertex.h
Normal file
46
engine/modules/engine/render/include/render/asset/vertex.h
Normal file
@ -0,0 +1,46 @@
|
||||
#pragma once
|
||||
#include "math/vector3.h"
|
||||
#include "math/vector2.h"
|
||||
#include "refl/pch.h"
|
||||
// 顶点最多关联4个骨骼
|
||||
#define MAX_NUM_BONES_PER_VERTEX 4
|
||||
namespace api {
|
||||
using refl::type_info;
|
||||
struct Vertex {};
|
||||
struct PosVertex : public Vertex {
|
||||
UPROPERTY_gl({}, glVertexMeta{ 3, GL_FLOAT, GL_FALSE })
|
||||
UPROPERTY_vk({}, uint32_t{ VK_FORMAT_R32G32B32_SFLOAT })
|
||||
Vector3 Position = {};
|
||||
};
|
||||
struct TexVertex : public Vertex {
|
||||
UPROPERTY_gl({}, glVertexMeta{ 3, GL_FLOAT, GL_FALSE })
|
||||
UPROPERTY_vk({}, uint32_t{ VK_FORMAT_R32G32B32_SFLOAT })
|
||||
Vector3 Position = {};
|
||||
UPROPERTY_gl({}, glVertexMeta{ 2, GL_FLOAT, GL_FALSE })
|
||||
UPROPERTY_vk()
|
||||
Vector2 TexCoords = {};
|
||||
UPROPERTY_gl({}, glVertexMeta{ 3, GL_FLOAT, GL_FALSE })
|
||||
UPROPERTY_vk()
|
||||
Vector3 Normal = {};
|
||||
};
|
||||
struct BoneVertex : public Vertex
|
||||
{
|
||||
UPROPERTY_gl({}, glVertexMeta{ 3, GL_FLOAT, GL_FALSE })
|
||||
UPROPERTY_vk({}, uint32_t{ VK_FORMAT_R32G32B32_SFLOAT })
|
||||
Vector3 Position = {};
|
||||
UPROPERTY_gl({}, glVertexMeta{ 2, GL_FLOAT, GL_FALSE })
|
||||
UPROPERTY_vk()
|
||||
Vector2 TexCoords = {};
|
||||
UPROPERTY_gl({}, glVertexMeta{ 3, GL_FLOAT, GL_FALSE })
|
||||
UPROPERTY_vk()
|
||||
Vector3 Normal = {};
|
||||
UPROPERTY_gl({}, glVertexMeta{ 3, GL_FLOAT, GL_FALSE })
|
||||
UPROPERTY_vk()
|
||||
Vector3 Tangent = {};
|
||||
// 骨骼蒙皮数据
|
||||
UPROPERTY_vk()
|
||||
float Weights[MAX_NUM_BONES_PER_VERTEX] = {};
|
||||
UPROPERTY_vk()
|
||||
uint32_t BoneIDs[MAX_NUM_BONES_PER_VERTEX] = {};
|
||||
};
|
||||
};
|
||||
@ -12,6 +12,11 @@ namespace api {
|
||||
public:
|
||||
RenderAPI() {};
|
||||
virtual ~RenderAPI() {};
|
||||
public:
|
||||
void* operator new(size_t size) {
|
||||
return ::operator new(size, GlobalPool());
|
||||
}
|
||||
void operator delete(void* p) {}
|
||||
public:
|
||||
virtual void Init() = 0;
|
||||
virtual void Shutdown() = 0;
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
#include <SDL.h>
|
||||
#include "singleton.h"
|
||||
#include "pmr/frame_allocator.h"
|
||||
namespace api {
|
||||
class RENDER_API Window : public Singleton<Window> {
|
||||
protected:
|
||||
@ -13,6 +14,11 @@ namespace api {
|
||||
bool resizeable = true;
|
||||
bool headless = false;
|
||||
};
|
||||
public:
|
||||
void* operator new(size_t size) {
|
||||
return ::operator new(size, GlobalPool());
|
||||
}
|
||||
void operator delete(void* p) {}
|
||||
public:
|
||||
Window(CreatePFN func, const Args& args, int width, int height) noexcept;
|
||||
SDL_Window* GetPtr() { return mPtr; }
|
||||
|
||||
7
engine/modules/engine/render/src/asset/mesh.cpp
Normal file
7
engine/modules/engine/render/src/asset/mesh.cpp
Normal file
@ -0,0 +1,7 @@
|
||||
#include "render/asset/mesh.h"
|
||||
namespace api {
|
||||
Mesh::Mesh() : Asset(type_info<Mesh>())
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
0
engine/modules/engine/render/src/asset/shader.cpp
Normal file
0
engine/modules/engine/render/src/asset/shader.cpp
Normal file
@ -6,6 +6,10 @@
|
||||
#define UPROPERTY(...) __Meta(__VA_ARGS__)
|
||||
#define UFUNCTION(...) __Meta(__VA_ARGS__)
|
||||
|
||||
#define __glMeta(...) __cppast(glMeta=__VA_ARGS__)
|
||||
#define UPROPERTY_gl(...) __glMeta(__VA_ARGS__)
|
||||
#define UFUNCTION_gl(...) __glMeta(__VA_ARGS__)
|
||||
|
||||
#define __vkMeta(...) __cppast(vkMeta=__VA_ARGS__)
|
||||
#define UPROPERTY_vk(...) __vkMeta(__VA_ARGS__)
|
||||
#define UFUNCTION_vk(...) __vkMeta(__VA_ARGS__)
|
||||
|
||||
73
engine/modules/engine/zlib/include/refl/std/parray.h
Normal file
73
engine/modules/engine/zlib/include/refl/std/parray.h
Normal file
@ -0,0 +1,73 @@
|
||||
#include "refl/refl.h"
|
||||
namespace refl {
|
||||
template<typename T>
|
||||
class parray {
|
||||
protected:
|
||||
const UClass* m_cls;
|
||||
T* m_ptr;
|
||||
int m_count;
|
||||
public:
|
||||
parray(): m_cls(nullptr), m_ptr(nullptr),m_count(0) {}
|
||||
template<typename C>
|
||||
requires std::is_base_of_v<T, C>
|
||||
parray(std::vector<C>& vec) : m_cls(&TypeInfo<C>::StaticClass), m_ptr(nullptr){
|
||||
m_count = vec.size();
|
||||
if (m_count > 0) {
|
||||
C* ptr = new C[m_count];
|
||||
m_ptr = ptr;
|
||||
if constexpr (std::is_trivially_copyable_v<C>) {
|
||||
memcpy(m_ptr, vec.data(), m_count * sizeof(C));
|
||||
}
|
||||
else {
|
||||
for (int i = 0; i < m_count; i++) {
|
||||
new(ptr + i) Vertex(vec[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
parray(parray<T>& parr) : m_cls(parr.m_cls)
|
||||
, m_ptr(parr.data()), m_count(parr.size()) {
|
||||
parr.reset();
|
||||
}
|
||||
~parray() {
|
||||
if (!m_count || !m_cls)
|
||||
return;
|
||||
auto dest = m_cls->vtable.Destruct;
|
||||
if (dest) {
|
||||
for (int i = 0; i < m_count; i++) {
|
||||
dest((char*)m_ptr + (i * m_cls->size));
|
||||
}
|
||||
}
|
||||
m_count = 0;
|
||||
m_ptr = nullptr;
|
||||
}
|
||||
T* at(int i)noexcept {
|
||||
if(i < m_count)
|
||||
return (T*)((char*)m_ptr + (i * m_cls->size));
|
||||
return nullptr;
|
||||
}
|
||||
T* data() noexcept{
|
||||
return m_ptr;
|
||||
}
|
||||
void reset() noexcept {
|
||||
m_ptr = nullptr;
|
||||
m_count = 0;
|
||||
}
|
||||
int size() const noexcept {
|
||||
return m_count;
|
||||
}
|
||||
int data_size()const noexcept {
|
||||
return m_count * m_cls->size;
|
||||
}
|
||||
int capicty() const noexcept {
|
||||
return m_count * m_cls->size;
|
||||
}
|
||||
const UClass* uclass()const noexcept {
|
||||
return m_cls;
|
||||
}
|
||||
};
|
||||
template<typename T, typename C>
|
||||
parray<T> ToParray(std::vector<C>& vec){
|
||||
return parray<T>{vec};
|
||||
}
|
||||
}
|
||||
58
engine/modules/engine/zlib/include/std/channel.h
Normal file
58
engine/modules/engine/zlib/include/std/channel.h
Normal file
@ -0,0 +1,58 @@
|
||||
#pragma once
|
||||
#include <condition_variable>
|
||||
#include <semaphore>
|
||||
#include <concepts>
|
||||
namespace zstd {
|
||||
template<std::move_constructible T>
|
||||
class channel {
|
||||
protected:
|
||||
int m_tail;
|
||||
int m_head;
|
||||
int m_size;
|
||||
T* m_buf;
|
||||
std::mutex m_mtx;
|
||||
std::condition_variable m_cv;
|
||||
public:
|
||||
~channel() {
|
||||
reset();
|
||||
free(m_buf);
|
||||
}
|
||||
channel(int size = 1) : 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) {
|
||||
std::unique_lock<std::mutex> lck(m_mtx);
|
||||
while (m_head >= m_tail + m_size) {
|
||||
m_cv.wait(lck);
|
||||
}
|
||||
std::construct_at(m_buf + m_head % m_size, 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 % m_size;
|
||||
if(m_tail++ == m_head - m_size)
|
||||
m_cv.notify_one();
|
||||
return std::move(*(m_buf + tail));
|
||||
};
|
||||
};
|
||||
}
|
||||
@ -1,6 +1,22 @@
|
||||
#pragma once
|
||||
#include "thread/worker.h"
|
||||
namespace vkn {
|
||||
class Device;
|
||||
class Instance;
|
||||
class Backend {
|
||||
protected:
|
||||
Instance* mInstance;
|
||||
Device* mDevice;
|
||||
table<Name, CommandWorker*> mWorkerMap;
|
||||
public:
|
||||
Backend(string_view appName);
|
||||
~Backend();
|
||||
void InitWorker(Name name, VkCommandPoolCreateFlags flag);
|
||||
CommandWorker* GetWorker(Name name);
|
||||
|
||||
public:
|
||||
static CommandWorker* TransferWorker;
|
||||
static CommandWorker* RenderWorker;
|
||||
static CommandWorker* PresentWorker;
|
||||
};
|
||||
}
|
||||
};
|
||||
@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
#include <thread>
|
||||
#include "vkn/type.h"
|
||||
#include <semaphore>
|
||||
namespace vkn {
|
||||
class CommandThreadWorker {
|
||||
protected:
|
||||
std::thread mThread;
|
||||
Name mName;
|
||||
channel<voidFn> mChannel;
|
||||
std::binary_semaphore mSemaphore;
|
||||
protected:
|
||||
void workloop();
|
||||
public:
|
||||
CommandThreadWorker(Name name, int buffer);
|
||||
~CommandThreadWorker();
|
||||
|
||||
void Invoke(const voidFn& fn);
|
||||
void SyncInvoke(const voidFn& fn);
|
||||
};
|
||||
};
|
||||
@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
#include "vkn/wrapper/commandpool.h"
|
||||
#include "thread_worker.h"
|
||||
namespace vkn {
|
||||
class Device;
|
||||
class Queue;
|
||||
class CommandWorker {
|
||||
protected:
|
||||
Device& mDevice;
|
||||
Queue& mQueue;
|
||||
Name mName;
|
||||
CommandThreadWorker mWork;
|
||||
CommandPool mCommandPool;
|
||||
CommandBuffer mImmediateExeCmd;
|
||||
public:
|
||||
CommandWorker(Name name, Device& device, Queue& queue, VkCommandPoolCreateFlags queueFlags);
|
||||
CommandPool& GetCommandPool() {
|
||||
return mCommandPool;
|
||||
}
|
||||
Queue& GetQueue() {
|
||||
return mQueue;
|
||||
}
|
||||
void Invoke(const voidFn& fn);
|
||||
void InvokeBuffer(const commandFn& fn, const voidFn& callback);
|
||||
void Buffer(CommandBuffer& cmd, const commandFn& fn, const voidFn& callback);
|
||||
void Flush();
|
||||
void ImmediatelyExecute(const commandFn& fn, const voidFn callback) {
|
||||
Buffer(mImmediateExeCmd, fn , callback);
|
||||
}
|
||||
bool Present(VkPresentInfoKHR& presentInfo);
|
||||
};
|
||||
};
|
||||
@ -1,10 +1,19 @@
|
||||
#pragma once
|
||||
#include "std/channel.h"
|
||||
#include "pmr/frame_allocator.h"
|
||||
#include "pmr/name.h"
|
||||
#include <Windows.h>
|
||||
#include <functional>
|
||||
#define VK_NO_PROTOTYPES
|
||||
#include "volk/volk.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#define Z_RENDER_DEBUG 1
|
||||
namespace vkn {
|
||||
|
||||
using pmr::Name;
|
||||
using pmr::table;
|
||||
using std::string_view;
|
||||
using zstd::channel;
|
||||
inline constexpr string_view VulkanEngineName = "vulkan";
|
||||
class CommandBuffer;
|
||||
using voidFn = std::function<void()>;
|
||||
using commandFn = std::function<void(CommandBuffer& cmd)>;
|
||||
}
|
||||
@ -1,11 +1,14 @@
|
||||
#pragma once
|
||||
#include "type.h"
|
||||
#include "render/renderapi.h"
|
||||
#include "backend.h"
|
||||
namespace vkn {
|
||||
class Backend;
|
||||
class VulkanWindow;
|
||||
class VulkanAPI : public api::RenderAPI {
|
||||
class VULKAN_API VulkanAPI : public api::RenderAPI {
|
||||
private:
|
||||
VulkanWindow* window;
|
||||
VulkanWindow& window;
|
||||
Backend backend;
|
||||
public:
|
||||
VulkanAPI();
|
||||
|
||||
|
||||
@ -5,8 +5,17 @@ namespace vkn {
|
||||
class VulkanWindow : public api::Window {
|
||||
private:
|
||||
VkSurfaceKHR mSurfaceKHR;
|
||||
public:
|
||||
void* operator new(size_t size) {
|
||||
return ::operator new(size, GlobalPool());
|
||||
}
|
||||
void operator delete(void* p) {}
|
||||
public:
|
||||
using api::Window::Window;
|
||||
void CreateRender();
|
||||
static VulkanWindow* Ptr() {
|
||||
//return dynamic_cast<VulkanWindow*>(api::Window::Ptr());
|
||||
return (VulkanWindow*)api::Window::Ptr();
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
#include "vkn/type.h"
|
||||
namespace vkn {
|
||||
class CommandBuffer {
|
||||
protected:
|
||||
VkCommandBuffer mPtr;
|
||||
public:
|
||||
CommandBuffer(VkCommandBuffer ptr) : mPtr(ptr) {};
|
||||
VkCommandBuffer& Ptr() {
|
||||
return mPtr;
|
||||
};
|
||||
void Reset();
|
||||
void BeginRecord(VkCommandBufferUsageFlags flag);
|
||||
void EndRecord();
|
||||
void CmdCopyBuffer(VkBuffer srcBuffer, VkBuffer dstBuffer, VkDeviceSize size);
|
||||
void Submit(VkQueue& queue,VkFence fence);
|
||||
|
||||
void BindVertexBuffer(VkBuffer buffer, uint32_t offset);
|
||||
void BindIndexBuffers(VkBuffer buffer, uint32_t offset, VkIndexType type);
|
||||
};
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
#include "commandbuffer.h"
|
||||
namespace vkn {
|
||||
class Device;
|
||||
class Queue;
|
||||
class CommandPool {
|
||||
protected:
|
||||
VkCommandPool mPtr;
|
||||
Device& mDevice;
|
||||
pmr::vector<CommandBuffer> mPool;
|
||||
public:
|
||||
CommandPool(Device& device, VkCommandPoolCreateFlags queueFlags, uint32_t queueIndex);
|
||||
~CommandPool();
|
||||
VkCommandBuffer AllocateBuffer(VkCommandBufferLevel level);
|
||||
void FreeBuffer(VkCommandBuffer& buf);
|
||||
VkCommandPool& Ptr() {
|
||||
return mPtr;
|
||||
};
|
||||
CommandBuffer Pop();
|
||||
void Push(CommandBuffer& cmd);
|
||||
};
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
#include "vkn/type.h"
|
||||
namespace vkn {
|
||||
class DeviceCreator;
|
||||
class Queue;
|
||||
class Device {
|
||||
friend class DeviceCreator;
|
||||
protected:
|
||||
VkDevice mPtr{ NULL };
|
||||
VkPhysicalDevice mPhysical{ NULL };
|
||||
table<Name, Queue*> mQueueMap;
|
||||
pmr::vector<VkFence> mFencePool;
|
||||
std::mutex mFenceMutex;
|
||||
public:
|
||||
VkDevice& Ptr() {
|
||||
return mPtr;
|
||||
}
|
||||
VkPhysicalDevice GetPhysical() {
|
||||
return mPhysical;
|
||||
}
|
||||
public:
|
||||
Device(DeviceCreator& Creator);
|
||||
~Device();
|
||||
|
||||
VkFence CreateFence(VkFenceCreateFlags flags);
|
||||
Queue* GetQueue(Name name);
|
||||
VkFence PopFence();
|
||||
void PushWaitFence(VkFence fence);
|
||||
VkSemaphore CreateSemaphore();
|
||||
VkShaderModule CreateShaderModule(pmr::vector<char> code);
|
||||
VkShaderModule CreateShaderModule(pmr::vector<uint32_t> code);
|
||||
};
|
||||
};
|
||||
@ -0,0 +1,50 @@
|
||||
#pragma once
|
||||
#include "vkn/type.h"
|
||||
namespace vkn {
|
||||
class Instance;
|
||||
class DeviceCreator {
|
||||
private:
|
||||
class DesiredQueue final
|
||||
{
|
||||
public:
|
||||
Name name;
|
||||
VkQueueFlags flag;
|
||||
float prioritie;
|
||||
int queueFamilyIndex;
|
||||
DesiredQueue(Name name, VkQueueFlags flag, float prioritie)
|
||||
: name(name), flag(flag), prioritie(prioritie), queueFamilyIndex(0) {}
|
||||
};
|
||||
public:
|
||||
VkPhysicalDeviceFeatures desiredPhysicalDeviceFeatures;
|
||||
VkPhysicalDeviceType desiredPhysicalDeviceType;
|
||||
pmr::vector<pmr::string> desiredExtensions;
|
||||
pmr::vector<DesiredQueue> desiredQueues;
|
||||
int fencePoolCount = 256;
|
||||
Instance& instance;
|
||||
public:
|
||||
DeviceCreator(Instance& instance);
|
||||
|
||||
void AddQueue(Name name, VkQueueFlags flag, float prioritie);
|
||||
void AddExtension(string_view extensionName);
|
||||
void AddWindowExtension();
|
||||
bool CheckProperty(const VkPhysicalDevice device);
|
||||
bool CheckExtension(const VkPhysicalDevice device);
|
||||
bool FindDevice(VkPhysicalDevice& device);
|
||||
void QueueCreateInfos(pmr::vector<VkDeviceQueueCreateInfo>& queue_create_infos,
|
||||
pmr::vector<pmr::vector<float>>& queue_prioritie,
|
||||
pmr::vector<VkQueueFamilyProperties>& queue_families);
|
||||
pmr::vector<char const*> EnabledExtensionNames();
|
||||
void EnableDeviceFeatures();
|
||||
VkPhysicalDeviceFeatures2 GetDeviceFeature2();
|
||||
VkPhysicalDeviceVulkan12Features GetVulkan12Features();
|
||||
#ifdef Z_RENDER_DEBUG
|
||||
public:
|
||||
pmr::vector<pmr::string> desiredLayers;
|
||||
void AddLayer(string_view layerName);
|
||||
bool CheckLayer(const VkPhysicalDevice device);
|
||||
pmr::vector<char const*> EnabledLayerNames();
|
||||
#endif
|
||||
public:
|
||||
static bool CheckAvailableQueueFamilies(VkPhysicalDevice physical_device, pmr::vector<VkQueueFamilyProperties>& queue_families);
|
||||
};
|
||||
};
|
||||
@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
#include "vkn/type.h"
|
||||
|
||||
namespace vkn {
|
||||
class InstanceCreator;
|
||||
class Instance {
|
||||
friend class InstanceCreator;
|
||||
protected:
|
||||
VkInstance mPtr;
|
||||
public:
|
||||
Instance(InstanceCreator& Creator);
|
||||
|
||||
VkInstance& Ptr() {
|
||||
return mPtr;
|
||||
}
|
||||
bool EnumerateAvailablePhysicalDevices(pmr::vector<VkPhysicalDevice>& available_devices);
|
||||
|
||||
static VKAPI_ATTR VkBool32 VKAPI_CALL DebugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT,
|
||||
VkDebugUtilsMessageTypeFlagsEXT,
|
||||
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
|
||||
void*);
|
||||
};
|
||||
};
|
||||
@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
#include "vkn/type.h"
|
||||
namespace vkn {
|
||||
class InstanceCreator {
|
||||
public:
|
||||
pmr::string appName;
|
||||
uint32_t appVersion;
|
||||
pmr::string engineName;
|
||||
uint32_t engineVersion;
|
||||
uint32_t apiVersion;
|
||||
|
||||
pmr::vector<pmr::string> desiredExtensions;
|
||||
pmr::vector<pmr::string> desiredLayers;
|
||||
|
||||
#ifdef Z_RENDER_DEBUG
|
||||
VkDebugUtilsMessageSeverityFlagsEXT messageSeverity;
|
||||
VkDebugUtilsMessageTypeFlagsEXT messageType;
|
||||
PFN_vkDebugUtilsMessengerCallbackEXT debugCallback;
|
||||
|
||||
VkDebugUtilsMessengerCreateInfoEXT DebugUtilsLayerNext();
|
||||
#endif
|
||||
public:
|
||||
InstanceCreator();
|
||||
void AddExtension(string_view extensionName);
|
||||
void AddLayer(string_view layerName);
|
||||
|
||||
void AddWindowExtension();
|
||||
void AddInstanceExtension();
|
||||
void AddDebugExtension();
|
||||
|
||||
pmr::vector<char const*> EnabledExtensionNames();
|
||||
pmr::vector<char const*> EnabledLayerNames();
|
||||
|
||||
private:
|
||||
static bool CheckAvailableInstanceExtensions(pmr::vector<VkExtensionProperties>& available_extensions);
|
||||
static bool CheckAvailableInstanceLayers(pmr::vector<VkLayerProperties>& available_layers);
|
||||
static bool IsExtensionSupported(pmr::vector<VkExtensionProperties> const& available_extensions,
|
||||
char const* const extension);
|
||||
static bool IsLayerSupported(pmr::vector<VkLayerProperties> const& available_layers,
|
||||
char const* const layer);
|
||||
};
|
||||
};
|
||||
26
engine/modules/render/vulkan/include/vkn/wrapper/queue.h
Normal file
26
engine/modules/render/vulkan/include/vkn/wrapper/queue.h
Normal file
@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
#include "vkn/type.h"
|
||||
namespace vkn {
|
||||
class Device;
|
||||
class CommandBuffer;
|
||||
class Queue {
|
||||
protected:
|
||||
VkQueue mPtr;
|
||||
uint32_t mQueueFamilyIndex;
|
||||
const Name mName;
|
||||
public:
|
||||
Queue(Name name, uint32_t queueFamilyIndex, VkQueue queue);
|
||||
uint32_t QueueFamilyIndex()
|
||||
{
|
||||
return mQueueFamilyIndex;
|
||||
}
|
||||
VkQueue& Ptr() {
|
||||
return mPtr;
|
||||
}
|
||||
public:
|
||||
static const Name TransferQueue;
|
||||
static const Name RenderQueue;
|
||||
static const Name ComputeQueue;
|
||||
static const Name PresentQueue;
|
||||
};
|
||||
}
|
||||
@ -0,0 +1,50 @@
|
||||
#include "vkn/backend.h"
|
||||
#include "vkn/wrapper/device.h"
|
||||
#include "vkn/wrapper/device_create.h"
|
||||
#include "vkn/wrapper/instance.h"
|
||||
#include "vkn/wrapper/instance_create.h"
|
||||
#include "vkn/wrapper/queue.h"
|
||||
namespace vkn {
|
||||
Backend::Backend(string_view appName) : mWorkerMap(GlobalPool())
|
||||
{
|
||||
InstanceCreator instanceCreator{};
|
||||
mInstance = new (GlobalPool()) Instance(instanceCreator);
|
||||
|
||||
DeviceCreator deviceCreator = DeviceCreator{ *mInstance };
|
||||
deviceCreator.AddWindowExtension();
|
||||
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 (GlobalPool()) Device(deviceCreator);
|
||||
|
||||
InitWorker(Queue::TransferQueue, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
|
||||
InitWorker(Queue::RenderQueue, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
|
||||
InitWorker(Queue::ComputeQueue, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
|
||||
InitWorker(Queue::PresentQueue, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
|
||||
|
||||
Backend::TransferWorker = GetWorker(Queue::TransferQueue);
|
||||
Backend::RenderWorker = GetWorker(Queue::RenderQueue);
|
||||
}
|
||||
Backend::~Backend()
|
||||
{
|
||||
mInstance->~Instance();
|
||||
mDevice->~Device();
|
||||
}
|
||||
void Backend::InitWorker(Name 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(Name name)
|
||||
{
|
||||
auto it = mWorkerMap.find(name);
|
||||
if (it != mWorkerMap.end()) {
|
||||
return it->second;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
36
engine/modules/render/vulkan/src/thread/thread_worker.cpp
Normal file
36
engine/modules/render/vulkan/src/thread/thread_worker.cpp
Normal file
@ -0,0 +1,36 @@
|
||||
#include "vkn/thread/thread_worker.h"
|
||||
#include "zlog.h"
|
||||
namespace vkn {
|
||||
CommandThreadWorker::CommandThreadWorker(Name name, int buffer)
|
||||
: mName(name)
|
||||
, mChannel(buffer)
|
||||
, mSemaphore(0)
|
||||
{
|
||||
mThread = std::thread(&CommandThreadWorker::workloop, this);
|
||||
}
|
||||
CommandThreadWorker::~CommandThreadWorker() {
|
||||
zlog::info("~CommandThreadWorker");
|
||||
zlog::flush();
|
||||
}
|
||||
void CommandThreadWorker::workloop()
|
||||
{
|
||||
mThread.detach();
|
||||
while (true) {
|
||||
voidFn fn = mChannel.acquire();
|
||||
fn();
|
||||
}
|
||||
}
|
||||
void CommandThreadWorker::Invoke(const voidFn& fn)
|
||||
{
|
||||
mChannel.release(fn);
|
||||
}
|
||||
|
||||
void CommandThreadWorker::SyncInvoke(const voidFn& fn)
|
||||
{
|
||||
Invoke([=,this]() {
|
||||
fn();
|
||||
mSemaphore.release();
|
||||
});
|
||||
mSemaphore.acquire();
|
||||
}
|
||||
}
|
||||
47
engine/modules/render/vulkan/src/thread/worker.cpp
Normal file
47
engine/modules/render/vulkan/src/thread/worker.cpp
Normal file
@ -0,0 +1,47 @@
|
||||
#include "vkn/thread/worker.h"
|
||||
#include "vkn/wrapper/queue.h"
|
||||
#include "vkn/wrapper/device.h"
|
||||
namespace vkn {
|
||||
CommandWorker::CommandWorker(Name name, Device& device, Queue& queue, VkCommandPoolCreateFlags queueFlags)
|
||||
:mName(name)
|
||||
,mDevice(device)
|
||||
,mQueue(queue)
|
||||
,mCommandPool(device, queueFlags, queue.QueueFamilyIndex())
|
||||
,mWork(name, 64)
|
||||
,mImmediateExeCmd(mCommandPool.AllocateBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY))
|
||||
{
|
||||
}
|
||||
void CommandWorker::Invoke(const voidFn& fn)
|
||||
{
|
||||
mWork.Invoke(fn);
|
||||
}
|
||||
|
||||
void CommandWorker::InvokeBuffer(const commandFn& fn, const voidFn& callback)
|
||||
{
|
||||
mWork.Invoke([=, this]() {
|
||||
CommandBuffer cmd = mCommandPool.Pop();
|
||||
Buffer(cmd, fn, callback);
|
||||
mCommandPool.Push(cmd);
|
||||
});
|
||||
}
|
||||
void CommandWorker::Buffer(CommandBuffer& cmd, const commandFn& fn, const voidFn& callback)
|
||||
{
|
||||
cmd.BeginRecord(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
|
||||
fn(cmd);
|
||||
cmd.EndRecord();
|
||||
VkFence fence = mDevice.PopFence();
|
||||
cmd.Submit(mQueue.Ptr(), fence);
|
||||
mDevice.PushWaitFence(fence);
|
||||
callback();
|
||||
}
|
||||
|
||||
void CommandWorker::Flush()
|
||||
{
|
||||
mWork.SyncInvoke([]{});
|
||||
}
|
||||
bool CommandWorker::Present(VkPresentInfoKHR& presentInfo)
|
||||
{
|
||||
VkResult result = vkQueuePresentKHR(mQueue.Ptr(), &presentInfo);
|
||||
return result == VK_SUCCESS;
|
||||
}
|
||||
}
|
||||
@ -1,10 +1,9 @@
|
||||
#include "vkn/vulkan_api.h"
|
||||
#include "vkn/vulkan_window.h"
|
||||
namespace vkn {
|
||||
VulkanAPI::VulkanAPI()
|
||||
VulkanAPI::VulkanAPI() : window(*VulkanWindow::Ptr()), backend(VulkanEngineName)
|
||||
{
|
||||
window = (VulkanWindow*) api::Window::Ptr();
|
||||
window->CreateRender();
|
||||
|
||||
}
|
||||
void VulkanAPI::Init()
|
||||
{
|
||||
|
||||
46
engine/modules/render/vulkan/src/wrapper/commandbuffer.cpp
Normal file
46
engine/modules/render/vulkan/src/wrapper/commandbuffer.cpp
Normal file
@ -0,0 +1,46 @@
|
||||
#include "vkn/wrapper/commandbuffer.h"
|
||||
namespace vkn {
|
||||
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);
|
||||
}
|
||||
void CommandBuffer::CmdCopyBuffer(VkBuffer srcBuffer, VkBuffer dstBuffer, VkDeviceSize size)
|
||||
{
|
||||
VkBufferCopy copy = {};
|
||||
copy.dstOffset = 0;
|
||||
copy.srcOffset = 0;
|
||||
copy.size = size;
|
||||
vkCmdCopyBuffer(mPtr, srcBuffer, dstBuffer, 1, ©);
|
||||
}
|
||||
void CommandBuffer::Submit(VkQueue& queue, VkFence fence)
|
||||
{
|
||||
VkSubmitInfo submitInfo{};
|
||||
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||
submitInfo.commandBufferCount = 1;
|
||||
submitInfo.pCommandBuffers = &mPtr;
|
||||
vkQueueSubmit(queue, 1, &submitInfo, fence);
|
||||
}
|
||||
void CommandBuffer::BindVertexBuffer(VkBuffer buffer, uint32_t offset)
|
||||
{
|
||||
VkDeviceSize offsets[] = { offset };
|
||||
vkCmdBindVertexBuffers(mPtr, 0, 1, &buffer, offsets);
|
||||
}
|
||||
void CommandBuffer::BindIndexBuffers(VkBuffer buffer, uint32_t offset, VkIndexType type)
|
||||
{
|
||||
vkCmdBindIndexBuffer(mPtr, buffer, offset, type);
|
||||
}
|
||||
}
|
||||
|
||||
58
engine/modules/render/vulkan/src/wrapper/commandpool.cpp
Normal file
58
engine/modules/render/vulkan/src/wrapper/commandpool.cpp
Normal file
@ -0,0 +1,58 @@
|
||||
#include "vkn/wrapper/commandpool.h"
|
||||
#include "vkn/wrapper/device.h"
|
||||
#include "vkn/wrapper/queue.h"
|
||||
#include "zlog.h"
|
||||
namespace vkn {
|
||||
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);
|
||||
}
|
||||
CommandPool::~CommandPool()
|
||||
{
|
||||
for (auto cb : mPool) {
|
||||
FreeBuffer(cb.Ptr());
|
||||
}
|
||||
mPool.clear();
|
||||
}
|
||||
VkCommandBuffer CommandPool::AllocateBuffer(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;
|
||||
}
|
||||
void CommandPool::FreeBuffer(VkCommandBuffer& buf)
|
||||
{
|
||||
vkFreeCommandBuffers(mDevice.Ptr(), mPtr, 1, &buf);
|
||||
buf = nullptr;
|
||||
}
|
||||
CommandBuffer CommandPool::Pop()
|
||||
{
|
||||
if (mPool.empty()) {
|
||||
return AllocateBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY);
|
||||
}
|
||||
CommandBuffer buffer = mPool.back();
|
||||
mPool.pop_back();
|
||||
return buffer;
|
||||
}
|
||||
void CommandPool::Push(CommandBuffer& cmd)
|
||||
{
|
||||
cmd.Reset();
|
||||
mPool.push_back(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,124 @@
|
||||
#include "vkn/wrapper/device.h"
|
||||
#include "vkn/wrapper/device_create.h"
|
||||
#include "vkn/wrapper/queue.h"
|
||||
#include "zlog.h"
|
||||
namespace vkn {
|
||||
Device::Device(DeviceCreator& Creator) : mQueueMap(GlobalPool())
|
||||
{
|
||||
//物理设备
|
||||
Creator.FindDevice(mPhysical);
|
||||
//队列信息
|
||||
pmr::vector<VkQueueFamilyProperties> queue_families{FramePool()};
|
||||
Creator.CheckAvailableQueueFamilies(mPhysical, queue_families);
|
||||
pmr::vector<VkDeviceQueueCreateInfo> queue_create_infos{ FramePool() };
|
||||
pmr::vector<pmr::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
|
||||
&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
|
||||
0, // uint32_t enabledLayerCount
|
||||
nullptr, // const char * const * ppEnabledLayerNames
|
||||
static_cast<uint32_t>(extensions.size()), // uint32_t enabledExtensionCount
|
||||
extensions.data(), // const char * const * ppEnabledExtensionNames
|
||||
nullptr // const VkPhysicalDeviceFeatures * pEnabledFeatures
|
||||
};
|
||||
#ifdef Z_USE_GRAPHIC_DEBUG
|
||||
auto layers = Creator.EnabledLayerNames();
|
||||
device_create_info.enabledLayerCount = layers.size();
|
||||
device_create_info.ppEnabledLayerNames = layers.data();
|
||||
#endif // Z_USE_GRAPHIC_DEBUG
|
||||
VkResult result = vkCreateDevice(mPhysical, &device_create_info, nullptr, &mPtr);
|
||||
if ((result != VK_SUCCESS) || (mPtr == VK_NULL_HANDLE)) {
|
||||
zlog::error("Could not create logical device. VkResult {}", (int)result);
|
||||
}
|
||||
volkLoadDevice(mPtr);
|
||||
for (auto& queue : Creator.desiredQueues) {
|
||||
Queue* gq = new (GlobalPool()) Queue(queue.name, queue.queueFamilyIndex, VK_NULL_HANDLE);
|
||||
vkGetDeviceQueue(mPtr, queue.queueFamilyIndex, 0, &(gq->Ptr()));
|
||||
mQueueMap.emplace(queue.name, gq);
|
||||
}
|
||||
}
|
||||
Device::~Device()
|
||||
{
|
||||
for (auto& queue : mQueueMap) {
|
||||
queue.second->~Queue();
|
||||
}
|
||||
mQueueMap.clear();
|
||||
}
|
||||
VkFence Device::CreateFence(VkFenceCreateFlags flags)
|
||||
{
|
||||
VkFenceCreateInfo fenceInfo{};
|
||||
fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
||||
// 创建时立刻设置为signaled状态(否则第一次永远等不到)
|
||||
fenceInfo.flags = flags;
|
||||
VkFence fence;
|
||||
VkResult result = vkCreateFence(mPtr, &fenceInfo, nullptr, &fence);
|
||||
return fence;
|
||||
}
|
||||
Queue* Device::GetQueue(Name name)
|
||||
{
|
||||
auto it = mQueueMap.find(name);
|
||||
if (it != mQueueMap.end()) {
|
||||
return it->second;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
VkFence Device::PopFence()
|
||||
{
|
||||
if (mFencePool.empty()) {
|
||||
return CreateFence(0);
|
||||
}
|
||||
std::lock_guard<std::mutex> lock(mFenceMutex);
|
||||
VkFence fence = mFencePool.back();
|
||||
mFencePool.pop_back();
|
||||
return fence;
|
||||
}
|
||||
void Device::PushWaitFence(VkFence fence)
|
||||
{
|
||||
vkWaitForFences(mPtr, 1, &fence, VK_TRUE, UINT64_MAX);
|
||||
vkResetFences(mPtr, 1, &fence);
|
||||
std::lock_guard<std::mutex> lock(mFenceMutex);
|
||||
mFencePool.push_back(fence);
|
||||
}
|
||||
VkSemaphore Device::CreateSemaphore()
|
||||
{
|
||||
VkSemaphoreCreateInfo semaphoreInfo = {};
|
||||
semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
||||
VkSemaphore semaphore;
|
||||
VkResult result = vkCreateSemaphore(mPtr, &semaphoreInfo, nullptr, &semaphore);
|
||||
return semaphore;
|
||||
}
|
||||
VkShaderModule Device::CreateShaderModule(pmr::vector<char> code)
|
||||
{
|
||||
VkShaderModuleCreateInfo createInfo = {};
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
|
||||
// 这里需要确保数据满足uint32_t的对齐要求,存储在vector中,默认分配器已经确保数据满足最差情况下的对齐要求
|
||||
createInfo.codeSize = code.size();
|
||||
// 转换为Vulkan要求的uint32_t指针
|
||||
createInfo.pCode = reinterpret_cast<const uint32_t*>(code.data());
|
||||
VkShaderModule module;
|
||||
VkResult result = vkCreateShaderModule(mPtr, &createInfo, nullptr, &module);
|
||||
return module;
|
||||
}
|
||||
VkShaderModule Device::CreateShaderModule(pmr::vector<uint32_t> code)
|
||||
{
|
||||
VkShaderModuleCreateInfo createInfo = {};
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
|
||||
//code size 是字节大小,需要 * sizeof
|
||||
createInfo.codeSize = code.size() * sizeof(uint32_t);
|
||||
// 转换为Vulkan要求的uint32_t指针
|
||||
createInfo.pCode = reinterpret_cast<const uint32_t*>(code.data());
|
||||
VkShaderModule module;
|
||||
VkResult result = vkCreateShaderModule(mPtr, &createInfo, nullptr, &module);
|
||||
return module;
|
||||
}
|
||||
}
|
||||
211
engine/modules/render/vulkan/src/wrapper/device_create.cpp
Normal file
211
engine/modules/render/vulkan/src/wrapper/device_create.cpp
Normal file
@ -0,0 +1,211 @@
|
||||
#include "vkn/wrapper/device_create.h"
|
||||
#include "vkn/wrapper/instance.h"
|
||||
#include "zlog.h"
|
||||
namespace vkn {
|
||||
DeviceCreator::DeviceCreator(Instance& instance)
|
||||
: instance(instance)
|
||||
, desiredPhysicalDeviceType(VkPhysicalDeviceType::VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU)
|
||||
, desiredPhysicalDeviceFeatures()
|
||||
, desiredExtensions{FramePool()}
|
||||
, desiredQueues{ FramePool() }
|
||||
#ifdef Z_RENDER_DEBUG
|
||||
, desiredLayers{FramePool()}
|
||||
#endif
|
||||
{
|
||||
}
|
||||
void DeviceCreator::AddQueue(Name name, VkQueueFlags flag, float prioritie)
|
||||
{
|
||||
desiredQueues.emplace_back(name, flag, prioritie);
|
||||
}
|
||||
void DeviceCreator::AddExtension(string_view extensionName)
|
||||
{
|
||||
desiredExtensions.push_back(pmr::string{ extensionName , FramePool()});
|
||||
}
|
||||
void DeviceCreator::AddWindowExtension()
|
||||
{
|
||||
AddExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
|
||||
#ifdef Z_RENDER_DEBUG
|
||||
AddLayer("VK_LAYER_KHRONOS_validation");
|
||||
AddLayer("VK_LAYER_RENDERDOC_Capture");
|
||||
#endif
|
||||
}
|
||||
bool DeviceCreator::CheckProperty(const VkPhysicalDevice device)
|
||||
{
|
||||
VkPhysicalDeviceProperties deviceProperties;
|
||||
vkGetPhysicalDeviceProperties(device, &deviceProperties);
|
||||
return (deviceProperties.deviceType & desiredPhysicalDeviceType) == desiredPhysicalDeviceType;
|
||||
}
|
||||
bool DeviceCreator::CheckExtension(const VkPhysicalDevice device)
|
||||
{
|
||||
uint32_t extensionCount = 0;
|
||||
vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, nullptr);
|
||||
pmr::vector<VkExtensionProperties> availableExtensions{FramePool()};
|
||||
availableExtensions.resize(extensionCount);
|
||||
vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, availableExtensions.data());
|
||||
for (const auto& desiredExtension : desiredExtensions)
|
||||
{
|
||||
bool find = false;
|
||||
for (const auto& availableExtension : availableExtensions)
|
||||
{
|
||||
if (strcmp(availableExtension.extensionName, desiredExtension.c_str()) == 0)
|
||||
{
|
||||
find = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!find)return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool DeviceCreator::FindDevice(VkPhysicalDevice& device)
|
||||
{
|
||||
pmr::vector<VkPhysicalDevice> available_devices{FramePool()};
|
||||
instance.EnumerateAvailablePhysicalDevices(available_devices);
|
||||
for (int i = 0, size = available_devices.size(); i < size; i++)
|
||||
{
|
||||
device = available_devices[i];
|
||||
if (!CheckProperty(device))continue;
|
||||
if (!CheckExtension(device))continue;
|
||||
#ifdef Z_RENDER_DEBUG
|
||||
if (!CheckLayer(device))continue;
|
||||
#endif // Z_RENDER_DEBUG
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void DeviceCreator::QueueCreateInfos(pmr::vector<VkDeviceQueueCreateInfo>& queue_create_infos, pmr::vector<pmr::vector<float>>& queue_prioritie, pmr::vector<VkQueueFamilyProperties>& queue_families)
|
||||
{
|
||||
uint32_t size = queue_families.size();
|
||||
for (uint32_t i = 0; i < size; i++) {
|
||||
VkDeviceQueueCreateInfo queueCreateInfo{};
|
||||
queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
|
||||
queueCreateInfo.queueFamilyIndex = i;
|
||||
queueCreateInfo.queueCount = 0;
|
||||
queue_create_infos.push_back(queueCreateInfo);
|
||||
queue_prioritie.emplace_back(pmr::vector<float>{FramePool()});
|
||||
}
|
||||
uint32_t max_value = 1;
|
||||
for (auto& queue : desiredQueues) {
|
||||
uint32_t index = -1;
|
||||
bool bFind = false;
|
||||
for (uint32_t i = 0; i < size; i++) {
|
||||
auto family = queue_families[i];
|
||||
if ((family.queueFlags & queue.flag) == queue.flag) {
|
||||
index = i;
|
||||
if (queue_create_infos[i].queueCount < max_value * family.queueCount) {
|
||||
bFind = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
if (!bFind)
|
||||
max_value++;
|
||||
}
|
||||
auto it = queue_create_infos.begin();
|
||||
for (uint32_t i = 0; i < size; i++) {
|
||||
if (it->queueCount == 0) {
|
||||
it = queue_create_infos.erase(it);
|
||||
}
|
||||
else {
|
||||
it->pQueuePriorities = queue_prioritie[i].data();
|
||||
it++;
|
||||
}
|
||||
}
|
||||
}
|
||||
pmr::vector<char const*> DeviceCreator::EnabledExtensionNames()
|
||||
{
|
||||
pmr::vector<char const*> _extension;
|
||||
for (int i = 0, l = desiredExtensions.size(); i < l; i++) {
|
||||
_extension.push_back(desiredExtensions[i].c_str());
|
||||
}
|
||||
return _extension;
|
||||
}
|
||||
void DeviceCreator::EnableDeviceFeatures()
|
||||
{
|
||||
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;
|
||||
}
|
||||
#ifdef Z_RENDER_DEBUG
|
||||
void DeviceCreator::AddLayer(string_view layerName)
|
||||
{
|
||||
desiredLayers.push_back(pmr::string{ layerName , FramePool()});
|
||||
}
|
||||
bool DeviceCreator::CheckLayer(const VkPhysicalDevice device)
|
||||
{
|
||||
uint32_t layerCount = 0;
|
||||
vkEnumerateDeviceLayerProperties(device, &layerCount, nullptr);
|
||||
pmr::vector<VkLayerProperties> availableLayers{FramePool()};
|
||||
availableLayers.resize(layerCount);
|
||||
vkEnumerateDeviceLayerProperties(device, &layerCount, availableLayers.data());
|
||||
for (const auto& desiredLayer : desiredLayers)
|
||||
{
|
||||
bool find = false;
|
||||
for (const auto& availableLayer : availableLayers)
|
||||
{
|
||||
if (strcmp(availableLayer.layerName, desiredLayer.c_str()) == 0)
|
||||
{
|
||||
find = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!find)return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
pmr::vector<char const*> DeviceCreator::EnabledLayerNames()
|
||||
{
|
||||
pmr::vector<char const*> _extension{FramePool()};
|
||||
for (int i = 0, l = desiredLayers.size(); i < l; i++) {
|
||||
_extension.push_back(desiredLayers[i].c_str());
|
||||
}
|
||||
return _extension;
|
||||
}
|
||||
#endif // Z_RENDER_DEBUG
|
||||
bool DeviceCreator::CheckAvailableQueueFamilies(VkPhysicalDevice physical_device, pmr::vector<VkQueueFamilyProperties>& queue_families)
|
||||
{
|
||||
uint32_t queue_families_count = 0;
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queue_families_count, nullptr);
|
||||
if (queue_families_count == 0) {
|
||||
zlog::error("Could not get the number of queue families.");
|
||||
return false;
|
||||
}
|
||||
queue_families.resize(queue_families_count);
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queue_families_count, queue_families.data());
|
||||
if (queue_families_count == 0) {
|
||||
zlog::error("Could not acquire properties of queue families.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,73 @@
|
||||
#include "vkn/wrapper/instance.h"
|
||||
#include "vkn/wrapper/instance_create.h"
|
||||
#include "zlog.h"
|
||||
namespace vkn {
|
||||
Instance::Instance(InstanceCreator& Creator)
|
||||
{
|
||||
VkResult res = volkInitialize();
|
||||
if (res != VK_SUCCESS)
|
||||
zlog::error("Could not initialize volk!");
|
||||
VkApplicationInfo application_info = {
|
||||
VK_STRUCTURE_TYPE_APPLICATION_INFO, // VkStructureType sType
|
||||
nullptr, // const void * pNext
|
||||
Creator.appName.c_str(), // const char * pApplicationName
|
||||
Creator.appVersion, // uint32_t applicationVersion
|
||||
Creator.engineName.c_str(), // const char * pEngineName
|
||||
Creator.engineVersion, // uint32_t engineVersion
|
||||
Creator.apiVersion // uint32_t apiVersion
|
||||
};
|
||||
#ifdef Z_RENDER_DEBUG
|
||||
Creator.AddDebugExtension();
|
||||
#endif // Z_RENDER_DEBUG
|
||||
Creator.AddWindowExtension();
|
||||
Creator.AddInstanceExtension();
|
||||
auto extensions = Creator.EnabledExtensionNames();
|
||||
auto layers = Creator.EnabledLayerNames();;
|
||||
VkInstanceCreateInfo instance_create_info = {
|
||||
VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // VkStructureType sType
|
||||
nullptr, // const void * pNext
|
||||
0, // VkInstanceCreateFlags flags
|
||||
&application_info, // const VkApplicationInfo * pApplicationInfo
|
||||
static_cast<uint32_t>(layers.size()), // uint32_t enabledLayerCount
|
||||
layers.data(), // const char * const * ppEnabledLayerNames
|
||||
static_cast<uint32_t>(extensions.size()), // uint32_t enabledExtensionCount
|
||||
extensions.data() // const char * const * ppEnabledExtensionNames
|
||||
};
|
||||
#ifdef Z_RENDER_DEBUG
|
||||
VkDebugUtilsMessengerCreateInfoEXT debugInfo = Creator.DebugUtilsLayerNext();
|
||||
instance_create_info.pNext = &debugInfo;
|
||||
#endif
|
||||
VkResult result = vkCreateInstance(&instance_create_info, nullptr, &mPtr);
|
||||
if (result != VK_SUCCESS) {
|
||||
zlog::error("Failed to create instance.");
|
||||
}
|
||||
volkLoadInstanceOnly(mPtr);
|
||||
}
|
||||
bool Instance::EnumerateAvailablePhysicalDevices(pmr::vector<VkPhysicalDevice>& available_devices)
|
||||
{
|
||||
uint32_t devices_count = 0;
|
||||
VkResult result = VK_SUCCESS;
|
||||
|
||||
result = vkEnumeratePhysicalDevices(mPtr, &devices_count, nullptr);
|
||||
if ((result != VK_SUCCESS) ||
|
||||
(devices_count == 0)) {
|
||||
zlog::error("Could not get the number of available physical devices.");
|
||||
return false;
|
||||
}
|
||||
|
||||
available_devices.resize(devices_count);
|
||||
result = vkEnumeratePhysicalDevices(mPtr, &devices_count, available_devices.data());
|
||||
if ((result != VK_SUCCESS) ||
|
||||
(devices_count == 0)) {
|
||||
zlog::error("Could not enumerate physical devices.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
VKAPI_ATTR VkBool32 VKAPI_CALL Instance::DebugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT, VkDebugUtilsMessageTypeFlagsEXT, const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, void*)
|
||||
{
|
||||
zlog::error("validation layer: {}", pCallbackData->pMessage);
|
||||
return VK_FALSE;
|
||||
}
|
||||
}
|
||||
165
engine/modules/render/vulkan/src/wrapper/instance_create.cpp
Normal file
165
engine/modules/render/vulkan/src/wrapper/instance_create.cpp
Normal file
@ -0,0 +1,165 @@
|
||||
#include "vkn/wrapper/instance_create.h"
|
||||
#include "vkn/wrapper/instance.h"
|
||||
#include "zlog.h"
|
||||
namespace vkn {
|
||||
VkDebugUtilsMessengerCreateInfoEXT InstanceCreator::DebugUtilsLayerNext()
|
||||
{
|
||||
VkDebugUtilsMessengerCreateInfoEXT createInfo{};
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
|
||||
createInfo.messageSeverity =
|
||||
VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
|
||||
createInfo.messageType =
|
||||
VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;
|
||||
createInfo.pfnUserCallback = debugCallback;
|
||||
return createInfo;
|
||||
}
|
||||
InstanceCreator::InstanceCreator()
|
||||
: desiredExtensions(FramePool()), desiredLayers(FramePool())
|
||||
, appName("Vulkan Application")
|
||||
, appVersion(VK_API_VERSION_1_3)
|
||||
, engineName("zengine")
|
||||
, engineVersion(VK_API_VERSION_1_3)
|
||||
, apiVersion(VK_API_VERSION_1_3)
|
||||
#ifdef Z_RENDER_DEBUG
|
||||
, messageSeverity(VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT)
|
||||
, messageType(VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT)
|
||||
, debugCallback(Instance::DebugCallback)
|
||||
#endif
|
||||
{
|
||||
|
||||
}
|
||||
void InstanceCreator::AddExtension(string_view extensionName)
|
||||
{
|
||||
desiredExtensions.push_back(pmr::string{ extensionName, FramePool() });
|
||||
}
|
||||
void InstanceCreator::AddLayer(string_view layerName)
|
||||
{
|
||||
desiredLayers.push_back(pmr::string{ layerName, FramePool() });
|
||||
}
|
||||
void InstanceCreator::AddWindowExtension()
|
||||
{
|
||||
#if defined(__ANDROID__)
|
||||
AddExtension(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME);
|
||||
#elif defined(__linux__) && defined(FILAMENT_SUPPORTS_WAYLAND)
|
||||
AddExtension(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME);
|
||||
#elif defined(LINUX_OR_FREEBSD) && defined(FILAMENT_SUPPORTS_X11)
|
||||
#if defined(FILAMENT_SUPPORTS_XCB)
|
||||
AddExtension(VK_KHR_XCB_SURFACE_EXTENSION_NAME);
|
||||
#endif
|
||||
#if defined(FILAMENT_SUPPORTS_XLIB)
|
||||
AddExtension(VK_KHR_XLIB_SURFACE_EXTENSION_NAME);
|
||||
#endif
|
||||
#elif defined(WIN32)
|
||||
AddExtension(VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
|
||||
#endif
|
||||
}
|
||||
void InstanceCreator::AddInstanceExtension()
|
||||
{
|
||||
AddExtension(VK_KHR_SURFACE_EXTENSION_NAME);
|
||||
AddExtension(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME);
|
||||
AddExtension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
|
||||
}
|
||||
#ifdef Z_RENDER_DEBUG
|
||||
void InstanceCreator::AddDebugExtension()
|
||||
{
|
||||
AddLayer("VK_LAYER_KHRONOS_validation");
|
||||
AddExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
|
||||
AddExtension(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
|
||||
}
|
||||
#endif // Z_RENDER_DEBUG
|
||||
pmr::vector<char const*> InstanceCreator::EnabledExtensionNames()
|
||||
{
|
||||
pmr::vector<VkExtensionProperties> available_extensions{ FramePool() };
|
||||
pmr::vector<char const*> _extension{ FramePool() };
|
||||
if (!CheckAvailableInstanceExtensions(available_extensions)) {
|
||||
return _extension;
|
||||
}
|
||||
for (int i = 0, l = desiredExtensions.size(); i < l; i++) {
|
||||
if (IsExtensionSupported(available_extensions, desiredExtensions[i].c_str())) {
|
||||
_extension.push_back(desiredExtensions[i].c_str());
|
||||
}
|
||||
else {
|
||||
zlog::error("cann't support extension: {}", desiredExtensions[i].c_str());
|
||||
}
|
||||
}
|
||||
return _extension;
|
||||
}
|
||||
pmr::vector<char const*> InstanceCreator::EnabledLayerNames()
|
||||
{
|
||||
pmr::vector<VkLayerProperties> available_layers{ FramePool() };
|
||||
pmr::vector<char const*> _layers{ FramePool() };
|
||||
if (!CheckAvailableInstanceLayers(available_layers)) {
|
||||
return _layers;
|
||||
}
|
||||
for (int i = 0, l = desiredLayers.size(); i < l; i++) {
|
||||
if (IsLayerSupported(available_layers, desiredLayers[i].c_str())) {
|
||||
_layers.push_back(desiredLayers[i].c_str());
|
||||
}
|
||||
else {
|
||||
zlog::error("Could not load instance-level Vulkan function named: {}", desiredLayers[i].c_str());
|
||||
}
|
||||
}
|
||||
return _layers;
|
||||
}
|
||||
bool InstanceCreator::CheckAvailableInstanceExtensions(pmr::vector<VkExtensionProperties>& available_extensions)
|
||||
{
|
||||
uint32_t extensions_count = 0;
|
||||
VkResult result = VK_SUCCESS;
|
||||
|
||||
result = vkEnumerateInstanceExtensionProperties(nullptr, &extensions_count, nullptr);
|
||||
if ((result != VK_SUCCESS) ||
|
||||
(extensions_count == 0)) {
|
||||
zlog::error("Could not get the number of instance extensions.");
|
||||
return false;
|
||||
}
|
||||
|
||||
available_extensions.resize(extensions_count);
|
||||
result = vkEnumerateInstanceExtensionProperties(nullptr, &extensions_count, available_extensions.data());
|
||||
if ((result != VK_SUCCESS) ||
|
||||
(extensions_count == 0)) {
|
||||
zlog::error("Could not enumerate instance extensions.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool InstanceCreator::CheckAvailableInstanceLayers(pmr::vector<VkLayerProperties>& available_layers)
|
||||
{
|
||||
uint32_t extensions_count = 0;
|
||||
VkResult result = VK_SUCCESS;
|
||||
|
||||
result = vkEnumerateInstanceLayerProperties(&extensions_count, nullptr);
|
||||
if ((result != VK_SUCCESS) ||
|
||||
(extensions_count == 0)) {
|
||||
zlog::error("Could not get the number of instance layers.");
|
||||
return false;
|
||||
}
|
||||
|
||||
available_layers.resize(extensions_count);
|
||||
result = vkEnumerateInstanceLayerProperties(&extensions_count, available_layers.data());
|
||||
if ((result != VK_SUCCESS) ||
|
||||
(extensions_count == 0)) {
|
||||
zlog::error("Could not enumerate instance layers.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
bool InstanceCreator::IsExtensionSupported(pmr::vector<VkExtensionProperties> const& available_extensions, char const* const extension)
|
||||
{
|
||||
for (auto& available_extension : available_extensions) {
|
||||
if (strstr(available_extension.extensionName, extension)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool InstanceCreator::IsLayerSupported(pmr::vector<VkLayerProperties> const& available_layers, char const* const layer)
|
||||
{
|
||||
for (auto& available_layer : available_layers) {
|
||||
if (strstr(available_layer.layerName, layer)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
12
engine/modules/render/vulkan/src/wrapper/queue.cpp
Normal file
12
engine/modules/render/vulkan/src/wrapper/queue.cpp
Normal file
@ -0,0 +1,12 @@
|
||||
#include "vkn/wrapper/queue.h"
|
||||
namespace vkn {
|
||||
const Name Queue::TransferQueue = "transfer";
|
||||
const Name Queue::RenderQueue = "render" ;
|
||||
const Name Queue::ComputeQueue = "computer";
|
||||
const Name Queue::PresentQueue = "present" ;
|
||||
Queue::Queue(Name name, uint32_t queueFamilyIndex, VkQueue queue)
|
||||
: mName(name)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@ -2,4 +2,13 @@ shared_module("vulkan","engine")
|
||||
add_headerfiles("include/**.h")
|
||||
add_files("src/**.cpp", "include/volk/volk.c")
|
||||
add_packages("vulkansdk", {public = true})
|
||||
add_dependency("engine", {public = true})
|
||||
add_dependency("engine", {public = true})
|
||||
on_load(function (target)
|
||||
if is_plat("windows") then
|
||||
target:add("defines", "VK_USE_PLATFORM_WIN32_KHR=1")
|
||||
elseif is_plat("linux") then
|
||||
target:add("defines", "VK_USE_PLATFORM_XLIB_KHR=1")
|
||||
elseif is_plat("macosx") then
|
||||
target:add("defines", "VK_USE_PLATFORM_MACOS_MVK=1")
|
||||
end
|
||||
end)
|
||||
@ -6,8 +6,8 @@ using namespace api;
|
||||
void ZWorldModule::OnLoad(int argc, char** argv)
|
||||
{
|
||||
// 创建窗口
|
||||
new (GlobalPool()) vkn::VulkanWindow(&SDL_CreateWindow, { "zengine" }, 1080, 720);
|
||||
new (GlobalPool()) vkn::VulkanAPI();
|
||||
new vkn::VulkanWindow(&SDL_CreateWindow, { "zengine" }, 1080, 720);
|
||||
new vkn::VulkanAPI();
|
||||
}
|
||||
|
||||
void ZWorldModule::OnUnload()
|
||||
|
||||
Loading…
Reference in New Issue
Block a user