draw traingle
This commit is contained in:
parent
270ce01887
commit
11590308f9
@ -1,11 +1,10 @@
|
|||||||
#version 450
|
#version 450
|
||||||
layout (location = 0) in vec3 iPos;
|
layout (location = 0) in vec3 iPos;
|
||||||
layout (location = 1) in vec2 iTex;
|
|
||||||
|
|
||||||
layout (location = 0) out vec4 vColor;
|
layout (location = 0) out vec4 vColor;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
gl_Position = vec4(iPos.x, iPos.y, iTex.x, 1.0);
|
gl_Position = vec4(iPos.x, iPos.y, iPos.z, 1.0);
|
||||||
vColor = vec4(gl_Position.x, gl_Position.y, gl_Position.z, 1.0);
|
vColor = vec4(1.0, 0.0, 0.0, 1.0);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,6 +5,7 @@ namespace api {
|
|||||||
IMPLEMENT_STATIC_MODULE(RENDER_API, RenderModule, render);
|
IMPLEMENT_STATIC_MODULE(RENDER_API, RenderModule, render);
|
||||||
void RenderAPI::RenderView(FRenderView& view)
|
void RenderAPI::RenderView(FRenderView& view)
|
||||||
{
|
{
|
||||||
|
view.context = &context;
|
||||||
graph.Compile();
|
graph.Compile();
|
||||||
graph.Execute(view);
|
graph.Execute(view);
|
||||||
graph.Clear();
|
graph.Clear();
|
||||||
@ -22,6 +23,6 @@ namespace api {
|
|||||||
}
|
}
|
||||||
RenderAPI::~RenderAPI()
|
RenderAPI::~RenderAPI()
|
||||||
{
|
{
|
||||||
delete& context;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -7,6 +7,7 @@ namespace api {
|
|||||||
|
|
||||||
friend class Scene;
|
friend class Scene;
|
||||||
public:
|
public:
|
||||||
|
Material(RscHandle<Shader> shader) : Material() { mShader = shader; };
|
||||||
Material();
|
Material();
|
||||||
~Material();
|
~Material();
|
||||||
void BeginLoad() {
|
void BeginLoad() {
|
||||||
|
|||||||
@ -9,33 +9,33 @@ namespace api {
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
concept Vertexs = requires {std::is_base_of_v<Vertex, T>; };
|
concept Vertexs = requires {std::is_base_of_v<Vertex, T>; };
|
||||||
struct PosVertex : public Vertex {
|
struct PosVertex : public Vertex {
|
||||||
//UPROPERTY_gl({}, glVertexMeta{ 3, GL_FLOAT, GL_FALSE })
|
UPROPERTY_gl({}, glVertexMeta{ 3, GL_FLOAT, GL_FALSE })
|
||||||
UPROPERTY_vk({}, uint32_t{ VK_FORMAT_R32G32B32_SFLOAT })
|
UPROPERTY_vk({}, uint32_t{ VK_FORMAT_R32G32B32_SFLOAT })
|
||||||
Vector3 Position = {};
|
Vector3 Position = {};
|
||||||
};
|
};
|
||||||
struct TexVertex : public Vertex {
|
struct TexVertex : public Vertex {
|
||||||
//UPROPERTY_gl({}, glVertexMeta{ 3, GL_FLOAT, GL_FALSE })
|
UPROPERTY_gl({}, glVertexMeta{ 3, GL_FLOAT, GL_FALSE })
|
||||||
UPROPERTY_vk({}, uint32_t{ VK_FORMAT_R32G32B32_SFLOAT })
|
UPROPERTY_vk({}, uint32_t{ VK_FORMAT_R32G32B32_SFLOAT })
|
||||||
Vector3 Position = {};
|
Vector3 Position = {};
|
||||||
//UPROPERTY_gl({}, glVertexMeta{ 2, GL_FLOAT, GL_FALSE })
|
UPROPERTY_gl({}, glVertexMeta{ 2, GL_FLOAT, GL_FALSE })
|
||||||
UPROPERTY_vk()
|
UPROPERTY_vk()
|
||||||
Vector2 TexCoords = {};
|
Vector2 TexCoords = {};
|
||||||
//UPROPERTY_gl({}, glVertexMeta{ 3, GL_FLOAT, GL_FALSE })
|
UPROPERTY_gl({}, glVertexMeta{ 3, GL_FLOAT, GL_FALSE })
|
||||||
UPROPERTY_vk()
|
UPROPERTY_vk()
|
||||||
Vector3 Normal = {};
|
Vector3 Normal = {};
|
||||||
};
|
};
|
||||||
struct BoneVertex : public Vertex
|
struct BoneVertex : public Vertex
|
||||||
{
|
{
|
||||||
//UPROPERTY_gl({}, glVertexMeta{ 3, GL_FLOAT, GL_FALSE })
|
UPROPERTY_gl({}, glVertexMeta{ 3, GL_FLOAT, GL_FALSE })
|
||||||
UPROPERTY_vk({}, uint32_t{ VK_FORMAT_R32G32B32_SFLOAT })
|
UPROPERTY_vk({}, uint32_t{ VK_FORMAT_R32G32B32_SFLOAT })
|
||||||
Vector3 Position = {};
|
Vector3 Position = {};
|
||||||
//UPROPERTY_gl({}, glVertexMeta{ 2, GL_FLOAT, GL_FALSE })
|
UPROPERTY_gl({}, glVertexMeta{ 2, GL_FLOAT, GL_FALSE })
|
||||||
UPROPERTY_vk()
|
UPROPERTY_vk()
|
||||||
Vector2 TexCoords = {};
|
Vector2 TexCoords = {};
|
||||||
//UPROPERTY_gl({}, glVertexMeta{ 3, GL_FLOAT, GL_FALSE })
|
UPROPERTY_gl({}, glVertexMeta{ 3, GL_FLOAT, GL_FALSE })
|
||||||
UPROPERTY_vk()
|
UPROPERTY_vk()
|
||||||
Vector3 Normal = {};
|
Vector3 Normal = {};
|
||||||
//UPROPERTY_gl({}, glVertexMeta{ 3, GL_FLOAT, GL_FALSE })
|
UPROPERTY_gl({}, glVertexMeta{ 3, GL_FLOAT, GL_FALSE })
|
||||||
UPROPERTY_vk()
|
UPROPERTY_vk()
|
||||||
Vector3 Tangent = {};
|
Vector3 Tangent = {};
|
||||||
// 骨骼蒙皮数据
|
// 骨骼蒙皮数据
|
||||||
|
|||||||
@ -4,8 +4,15 @@
|
|||||||
#include "lemon/list_graph.h"
|
#include "lemon/list_graph.h"
|
||||||
#include <functional>
|
#include <functional>
|
||||||
namespace api {
|
namespace api {
|
||||||
|
struct RenderContext;
|
||||||
struct ComputePassContext {};
|
struct ComputePassContext {};
|
||||||
struct RenderPassContext {};
|
struct RenderPassContext {
|
||||||
|
RenderContext* parent;
|
||||||
|
RenderPassContext(RenderContext* parent) : parent(parent) {};
|
||||||
|
RenderContext* operator->() {
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
};
|
||||||
struct CopyPassContext {};
|
struct CopyPassContext {};
|
||||||
|
|
||||||
class FrameGraph;
|
class FrameGraph;
|
||||||
|
|||||||
@ -10,5 +10,11 @@ namespace api {
|
|||||||
TextureDesc surface;
|
TextureDesc surface;
|
||||||
uint32_t frame{ 0 };
|
uint32_t frame{ 0 };
|
||||||
uint32_t presentFrame{ 0 };
|
uint32_t presentFrame{ 0 };
|
||||||
|
virtual void SetViewport(float x, float y, float width, float height, float min_depth, float max_depth) = 0;
|
||||||
|
virtual void SetScissor(uint32_t x, uint32_t y, uint32_t width, uint32_t height) = 0;
|
||||||
|
virtual void BindIndexBuffer(BufferDesc desc, uint32_t index_stride) = 0;
|
||||||
|
virtual void BindVertexBuffer(BufferDesc buffers) = 0;
|
||||||
|
virtual void BindVertexBuffers(uint32_t buffer_count, const BufferDesc* buffers, const uint32_t* offsets) = 0;
|
||||||
|
virtual void DrawIndexed(uint32_t index_count, uint32_t first_index, uint32_t first_vertex) = 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -67,7 +67,9 @@ namespace api {
|
|||||||
};
|
};
|
||||||
using ImagePtr = void*;
|
using ImagePtr = void*;
|
||||||
using ImageViewPtr = void*;
|
using ImageViewPtr = void*;
|
||||||
|
using BufferPtr = void*;
|
||||||
struct BufferDesc {
|
struct BufferDesc {
|
||||||
|
BufferPtr buffer;
|
||||||
static BufferDesc Make() {
|
static BufferDesc Make() {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -88,7 +88,7 @@ namespace api {
|
|||||||
{
|
{
|
||||||
ExecuteResourceBarriers(node);
|
ExecuteResourceBarriers(node);
|
||||||
RenderAPI::Ptr()->BeginRenderPass(node);
|
RenderAPI::Ptr()->BeginRenderPass(node);
|
||||||
RenderPassContext context{};
|
RenderPassContext context{view.context};
|
||||||
std::get<RenderPassExecuteFunction>(node->executor)(*this, context);
|
std::get<RenderPassExecuteFunction>(node->executor)(*this, context);
|
||||||
RenderAPI::Ptr()->EndRenderPass(node);
|
RenderAPI::Ptr()->EndRenderPass(node);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,18 +3,32 @@
|
|||||||
#include "render/asset/material.h"
|
#include "render/asset/material.h"
|
||||||
#include "render/renderapi.h"
|
#include "render/renderapi.h"
|
||||||
#include "asset/resource_system.h"
|
#include "asset/resource_system.h"
|
||||||
|
#include "render/asset/vertex.h"
|
||||||
|
#include "render/asset/mesh.h"
|
||||||
namespace api {
|
namespace api {
|
||||||
|
static RscHandle<Material> material;
|
||||||
|
static RscHandle<Shader> shader;
|
||||||
|
static RscHandle<Mesh> mesh;
|
||||||
bool DemoPass::Setup(FrameGraph& graph, FrameGraph::RenderPassBuilder& builder)
|
bool DemoPass::Setup(FrameGraph& graph, FrameGraph::RenderPassBuilder& builder)
|
||||||
{
|
{
|
||||||
static RscHandle<Shader> shader;
|
|
||||||
if (!shader) {
|
if (!shader) {
|
||||||
shader = ResourceSystem::Ptr()->LoadEmplaceResource<Shader>();
|
shader = ResourceSystem::Ptr()->LoadEmplaceResource<Shader>();
|
||||||
shader->Name("api::PosVertex");
|
shader->Name("api::PosVertex");
|
||||||
auto vert = ResourceSystem::Ptr()->Load<ShaderProgram>("/engine/assets/shader/simple.frag");
|
auto vert = ResourceSystem::Ptr()->Load<ShaderProgram>("/engine/assets/shader/simple.vert");
|
||||||
auto frag = ResourceSystem::Ptr()->Load<ShaderProgram>("/engine/assets/shader/simple.frag");
|
auto frag = ResourceSystem::Ptr()->Load<ShaderProgram>("/engine/assets/shader/simple.frag");
|
||||||
shader->SetVertHandle(vert);
|
shader->SetVertHandle(vert);
|
||||||
shader->SetFragHandle(frag);
|
shader->SetFragHandle(frag);
|
||||||
RenderAPI::Ptr()->LoadShader(*shader);
|
RenderAPI::Ptr()->LoadShader(*shader);
|
||||||
|
vector<PosVertex> vertices = {
|
||||||
|
{.Position = { 0.0f, -0.5f, 0.f}}, // 底部顶点,红色
|
||||||
|
{.Position = { 0.5f, 0.5f, 0.f}}, // 右上顶点,绿色
|
||||||
|
{.Position = {-0.5f, 0.5f, 0.f}} // 左上顶点,蓝色
|
||||||
|
};
|
||||||
|
vector<uint32_t> indices = {0, 1, 2};
|
||||||
|
mesh = ResourceSystem::Ptr()->LoadEmplaceResource<Mesh>(vertices, indices);
|
||||||
|
material = ResourceSystem::Ptr()->LoadEmplaceResource<Material>(shader);
|
||||||
|
mesh->SetMaterial(material);
|
||||||
|
RenderAPI::Ptr()->SetStaticMesh(*mesh);
|
||||||
}
|
}
|
||||||
AttachmentDesc surface{};
|
AttachmentDesc surface{};
|
||||||
surface.FromTexture(graph.mSurface);
|
surface.FromTexture(graph.mSurface);
|
||||||
@ -29,8 +43,11 @@ namespace api {
|
|||||||
.Present(edge, edge.targetState);
|
.Present(edge, edge.targetState);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
void DemoPass::Execute(FrameGraph&, RenderPassContext&)
|
void DemoPass::Execute(FrameGraph& graph, RenderPassContext& ctx)
|
||||||
{
|
{
|
||||||
|
auto& surface = graph.mSurface;
|
||||||
|
ctx->SetViewport(0.0f, 0.0f,(float)surface.width,(float)surface.height, 0.f, 1.f);
|
||||||
|
ctx->SetScissor(0, 0, surface.width, surface.height);
|
||||||
|
RenderAPI::Ptr()->DrawStaticMesh(*mesh);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,6 +11,13 @@ namespace pmr {
|
|||||||
{
|
{
|
||||||
size_t space = capacity - offset;
|
size_t space = capacity - offset;
|
||||||
void* ptr = buffer + offset;
|
void* ptr = buffer + offset;
|
||||||
|
if (bytes > capacity) {
|
||||||
|
if (std::align(alignment, bytes, ptr, space)) {
|
||||||
|
offset = capacity - space + bytes;
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
throw std::bad_alloc();
|
||||||
|
}
|
||||||
if (std::align(alignment, bytes, ptr, space)) {
|
if (std::align(alignment, bytes, ptr, space)) {
|
||||||
offset = capacity - space + bytes;
|
offset = capacity - space + bytes;
|
||||||
return ptr;
|
return ptr;
|
||||||
|
|||||||
@ -6,7 +6,7 @@ namespace refl {
|
|||||||
struct TStr {
|
struct TStr {
|
||||||
std::array<char, N> value{}; // 确切长度的字符数组,不依赖 '\0'
|
std::array<char, N> value{}; // 确切长度的字符数组,不依赖 '\0'
|
||||||
constexpr TStr() {};
|
constexpr TStr() {};
|
||||||
constexpr TStr(const char(&data)[N]) {
|
constexpr TStr(const char(&data)[N + 1]) {
|
||||||
std::copy_n(data, N, value.begin());
|
std::copy_n(data, N, value.begin());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -21,7 +21,7 @@ namespace refl {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <size_t N>
|
template <size_t N>
|
||||||
TStr(const char(&)[N]) -> TStr<N>;
|
TStr(const char(&)[N]) -> TStr<N - 1>;
|
||||||
|
|
||||||
template<auto v>
|
template<auto v>
|
||||||
constexpr auto value_name() noexcept;
|
constexpr auto value_name() noexcept;
|
||||||
|
|||||||
@ -33,7 +33,7 @@ namespace refl {
|
|||||||
}
|
}
|
||||||
template <int N, int Digits = _num_digits(N)>
|
template <int N, int Digits = _num_digits(N)>
|
||||||
constexpr auto num_name() {
|
constexpr auto num_name() {
|
||||||
char data[Digits];
|
char data[Digits + 1];
|
||||||
int n = N;
|
int n = N;
|
||||||
for (int i = Digits - 1; i >= 0; --i) {
|
for (int i = Digits - 1; i >= 0; --i) {
|
||||||
data[i] = static_cast<char>('0' + n % 10);
|
data[i] = static_cast<char>('0' + n % 10);
|
||||||
@ -82,6 +82,18 @@ namespace refl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
template<typename Args1, typename... Args>
|
||||||
|
constexpr auto concat_seq(Args1 args1, Args&&... args) {
|
||||||
|
if constexpr (sizeof...(Args) == 0) {
|
||||||
|
return args1;
|
||||||
|
}
|
||||||
|
else if constexpr (sizeof...(Args) == 1) {
|
||||||
|
return detail::concat(args1, args...);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return detail::concat(args1, concat_seq(args...));
|
||||||
|
}
|
||||||
|
}
|
||||||
template<typename T>
|
template<typename T>
|
||||||
constexpr auto meta_name() noexcept {
|
constexpr auto meta_name() noexcept {
|
||||||
if constexpr (std::is_same_v<T, void>) {
|
if constexpr (std::is_same_v<T, void>) {
|
||||||
@ -90,7 +102,24 @@ namespace refl {
|
|||||||
else if constexpr (std::is_arithmetic_v<T>) {
|
else if constexpr (std::is_arithmetic_v<T>) {
|
||||||
constexpr auto prefix = detail::num_prefix_name<T>();
|
constexpr auto prefix = detail::num_prefix_name<T>();
|
||||||
constexpr auto bit = detail::num_name<8 * sizeof(T)>();
|
constexpr auto bit = detail::num_name<8 * sizeof(T)>();
|
||||||
return detail::concat(prefix, bit);
|
return concat_seq(prefix, bit);
|
||||||
|
}
|
||||||
|
else if constexpr (std::is_array_v<T>) {
|
||||||
|
constexpr auto r = std::rank_v<T>;
|
||||||
|
constexpr auto ex = std::extent_v<T, 0>;
|
||||||
|
if constexpr (r == 1) {
|
||||||
|
if constexpr (ex == 0)
|
||||||
|
return concat_seq(TStr{"[]{"}, meta_name<std::remove_extent_t<T>>(), TStr{"}"});
|
||||||
|
else
|
||||||
|
return concat_seq(TStr{"["}, detail::num_name<ex>(), TStr{"]{"}, meta_name<std::remove_extent_t<T>>(), TStr{"}"});
|
||||||
|
}
|
||||||
|
else { // r > 1
|
||||||
|
static_assert(r > 1);
|
||||||
|
if constexpr (ex == 0)
|
||||||
|
return concat_seq(TStr{"[]"}, type_name<std::remove_extent_t<T>>());
|
||||||
|
else
|
||||||
|
return concat_seq(TStr{"["}, detail::num_name<ex>(), TStr{"]"}, meta_name<std::remove_extent_t<T>>());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return detail::raw_meta_name<T>();
|
return detail::raw_meta_name<T>();
|
||||||
|
|||||||
@ -105,6 +105,10 @@ namespace refl {
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
using args_type_t = detail::args_type<std::remove_cv_t<T>>::type;
|
using args_type_t = detail::args_type<std::remove_cv_t<T>>::type;
|
||||||
};
|
};
|
||||||
|
namespace gen {
|
||||||
|
template<typename T, size_t hash>
|
||||||
|
struct MetaImpl;
|
||||||
|
}
|
||||||
namespace refl {
|
namespace refl {
|
||||||
template<class T>
|
template<class T>
|
||||||
struct Meta {};
|
struct Meta {};
|
||||||
@ -112,6 +116,12 @@ namespace refl {
|
|||||||
template<class T>
|
template<class T>
|
||||||
concept is_meta_v = requires { typename Meta<T>::Impl; };
|
concept is_meta_v = requires { typename Meta<T>::Impl; };
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
concept is_metas_v = requires() { Meta<T>::MetaList(); };
|
||||||
|
|
||||||
|
template <class T, size_t hash>
|
||||||
|
concept have_meta_impl_v = requires() { typename gen::MetaImpl<T, hash>::T; };
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
concept has_parent_v = requires { typename Meta<T>::Parent; };
|
concept has_parent_v = requires { typename Meta<T>::Parent; };
|
||||||
|
|
||||||
@ -124,5 +134,6 @@ namespace refl {
|
|||||||
struct UClass;
|
struct UClass;
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
const UClass* meta_info();
|
const UClass* meta_info();
|
||||||
|
const UClass* find_info(Name name, size_t hash);
|
||||||
constexpr uint32_t MAX_ARGS_LENGTH = 10;
|
constexpr uint32_t MAX_ARGS_LENGTH = 10;
|
||||||
}
|
}
|
||||||
@ -73,8 +73,6 @@ namespace refl {
|
|||||||
}
|
}
|
||||||
//class
|
//class
|
||||||
using GetFields_t = span<const FieldPtr>(*)(const UClass*, EFieldFind find, Name name);
|
using GetFields_t = span<const FieldPtr>(*)(const UClass*, EFieldFind find, Name name);
|
||||||
//class meta
|
|
||||||
using GetMeta_t = const UClass* (*)(Name);
|
|
||||||
//function
|
//function
|
||||||
using GetParams_t = span<const UClass*>(*)(const UClass*);
|
using GetParams_t = span<const UClass*>(*)(const UClass*);
|
||||||
//function args
|
//function args
|
||||||
@ -85,9 +83,6 @@ namespace refl {
|
|||||||
void AddGetFields(GetFields_t func) {
|
void AddGetFields(GetFields_t func) {
|
||||||
Add(string_hash("GetFields"), (void*)func);
|
Add(string_hash("GetFields"), (void*)func);
|
||||||
}
|
}
|
||||||
void AddGetMeta(GetMeta_t func) {
|
|
||||||
Add(string_hash("GetMeta"), (void*)func);
|
|
||||||
}
|
|
||||||
void AddGetParams(GetParams_t func) {
|
void AddGetParams(GetParams_t func) {
|
||||||
Add(string_hash("GetParams"), (void*)func);
|
Add(string_hash("GetParams"), (void*)func);
|
||||||
}
|
}
|
||||||
@ -101,7 +96,6 @@ namespace refl {
|
|||||||
Add(string_hash("Destruct"), (void*)func);
|
Add(string_hash("Destruct"), (void*)func);
|
||||||
}
|
}
|
||||||
GetFields_t GetFields() const { return (GetFields_t) Find(string_hash("GetFields")); }
|
GetFields_t GetFields() const { return (GetFields_t) Find(string_hash("GetFields")); }
|
||||||
GetMeta_t GetMeta() const { return (GetMeta_t) Find(string_hash("GetMeta")); }
|
|
||||||
GetParams_t GetParams() const { return (GetParams_t) Find(string_hash("GetParams")); }
|
GetParams_t GetParams() const { return (GetParams_t) Find(string_hash("GetParams")); }
|
||||||
Call_t Call() const { return (Call_t) Find(string_hash("Call")); }
|
Call_t Call() const { return (Call_t) Find(string_hash("Call")); }
|
||||||
Construct_t Construct() const { return (Construct_t) Find(string_hash("Construct")); }
|
Construct_t Construct() const { return (Construct_t) Find(string_hash("Construct")); }
|
||||||
@ -111,7 +105,7 @@ namespace refl {
|
|||||||
public:
|
public:
|
||||||
Name name;
|
Name name;
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
uint32_t flag{0};
|
uint32_t flag : 16{0};
|
||||||
const UClass* parent;
|
const UClass* parent;
|
||||||
vtable_uclass vtable;
|
vtable_uclass vtable;
|
||||||
UClass(const UClass*) = delete;
|
UClass(const UClass*) = delete;
|
||||||
@ -145,12 +139,8 @@ namespace refl {
|
|||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
const UClass* GetMeta(Name name)const {
|
const UClass* GetMeta(size_t hash)const {
|
||||||
auto func = vtable.GetMeta();
|
return find_info(name, hash);
|
||||||
if (func) {
|
|
||||||
return func(name);
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
bool IsChildOf(const UClass* cls, bool bthis = false) const {
|
bool IsChildOf(const UClass* cls, bool bthis = false) const {
|
||||||
const UClass* _parent = bthis ? this : parent;
|
const UClass* _parent = bthis ? this : parent;
|
||||||
|
|||||||
@ -2,8 +2,6 @@
|
|||||||
#include "name.h"
|
#include "name.h"
|
||||||
#include "type.h"
|
#include "type.h"
|
||||||
namespace refl {
|
namespace refl {
|
||||||
template <class T>
|
|
||||||
concept is_metas_v = requires(const Name & name) { Meta<T>::GetMeta(name); };
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class UClass_Auto : public UClass {
|
class UClass_Auto : public UClass {
|
||||||
public:
|
public:
|
||||||
@ -26,9 +24,6 @@ namespace refl {
|
|||||||
else {
|
else {
|
||||||
vtable.AddConstruct(&UClass::Construct<T>);
|
vtable.AddConstruct(&UClass::Construct<T>);
|
||||||
vtable.AddDestruct(&UClass::Destruct<T>);
|
vtable.AddDestruct(&UClass::Destruct<T>);
|
||||||
if constexpr (is_metas_v<T>) {
|
|
||||||
vtable.AddGetMeta(&Meta<T>::GetMeta);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -173,9 +168,6 @@ namespace refl {
|
|||||||
if constexpr (has_parent_v<T>) {
|
if constexpr (has_parent_v<T>) {
|
||||||
parent = meta_info<parent_t<T>>();
|
parent = meta_info<parent_t<T>>();
|
||||||
}
|
}
|
||||||
if constexpr (is_metas_v<T>) {
|
|
||||||
vtable.AddGetMeta(&Meta<T>::GetMeta);
|
|
||||||
}
|
|
||||||
vtable.AddGetFields(&UClass_Meta::GetFields);
|
vtable.AddGetFields(&UClass_Meta::GetFields);
|
||||||
vtable.AddConstruct(&UClass::Construct<T>);
|
vtable.AddConstruct(&UClass::Construct<T>);
|
||||||
}
|
}
|
||||||
@ -256,8 +248,15 @@ namespace refl {
|
|||||||
return new(MetaGlobalPool()) UClass_Container<T, typename T::value_type>{};
|
return new(MetaGlobalPool()) UClass_Container<T, typename T::value_type>{};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
struct MetaClasses {
|
||||||
|
size_t hash{ 0 };
|
||||||
|
const UClass* cls{nullptr};
|
||||||
|
MetaClasses* next{ nullptr };
|
||||||
|
};
|
||||||
using __tClassTable = table<Name, const UClass*>;
|
using __tClassTable = table<Name, const UClass*>;
|
||||||
UNIQUER_INLINE(__tClassTable, ClassTable, "refl::ClassTable")
|
UNIQUER_INLINE(__tClassTable, ClassTable, "refl::ClassTable")
|
||||||
|
using __tMetaClassTable = table<Name, MetaClasses>;
|
||||||
|
UNIQUER_INLINE(__tMetaClassTable, MetaClassTable, "refl::MetaClassTable")
|
||||||
inline const UClass* find_info(Name name) {
|
inline const UClass* find_info(Name name) {
|
||||||
auto& ClassTable = UNIQUER_VAL(ClassTable);
|
auto& ClassTable = UNIQUER_VAL(ClassTable);
|
||||||
if (auto it = ClassTable.find(name); it != ClassTable.end()) {
|
if (auto it = ClassTable.find(name); it != ClassTable.end()) {
|
||||||
@ -265,6 +264,19 @@ namespace refl {
|
|||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
inline const UClass* find_info(Name name, size_t hash) {
|
||||||
|
auto& MetaClassTable = UNIQUER_VAL(MetaClassTable);
|
||||||
|
if (auto it = MetaClassTable.find(name); it != MetaClassTable.end()) {
|
||||||
|
auto meta = &it->second;
|
||||||
|
while (meta) {
|
||||||
|
if (meta->hash == hash) {
|
||||||
|
return meta->cls;
|
||||||
|
}
|
||||||
|
meta = meta->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
inline const UClass* meta_info()
|
inline const UClass* meta_info()
|
||||||
{
|
{
|
||||||
@ -287,4 +299,46 @@ namespace refl {
|
|||||||
ClassTable[name.view()] = cls;
|
ClassTable[name.view()] = cls;
|
||||||
return cls;
|
return cls;
|
||||||
}
|
}
|
||||||
|
template<typename T, size_t hash>
|
||||||
|
inline const UClass* meta_info()
|
||||||
|
{
|
||||||
|
if constexpr (have_meta_impl_v<T, hash>) {
|
||||||
|
constexpr auto name = meta_name<T>();
|
||||||
|
const UClass* cls = find_info(name.view(), hash);
|
||||||
|
if (cls) {
|
||||||
|
return cls;
|
||||||
|
}
|
||||||
|
cls = new(MetaGlobalPool()) UClass_Meta<T, gen::MetaImpl<T, hash>>{};
|
||||||
|
auto& MetaClassTable = UNIQUER_VAL(MetaClassTable);
|
||||||
|
if (auto it = MetaClassTable.find(name.view()); it != MetaClassTable.end()) {
|
||||||
|
auto meta = &it->second;
|
||||||
|
while (meta) {
|
||||||
|
if (!meta->next) {
|
||||||
|
meta->next = new (MetaGlobalPool()) MetaClasses{ hash, cls };
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
meta = meta->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
MetaClassTable.emplace(name.view(), MetaClasses{hash, cls});
|
||||||
|
}
|
||||||
|
return cls;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return meta_info<T>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
template<typename T, size_t index = 0>
|
||||||
|
inline void register_meta()
|
||||||
|
{
|
||||||
|
if constexpr (is_metas_v<T>) {
|
||||||
|
constexpr auto metaList = Meta<T>::MetaList();
|
||||||
|
meta_info<T, metaList[index]> ();
|
||||||
|
if constexpr (index + 1 < metaList.size()) {
|
||||||
|
register_meta<T, index + 1>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
meta_info<T>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -10,9 +10,10 @@ namespace zstd{
|
|||||||
channel<Element> mChannel;
|
channel<Element> mChannel;
|
||||||
void WorkLoop() {
|
void WorkLoop() {
|
||||||
mThread.detach();
|
mThread.detach();
|
||||||
|
Loop();
|
||||||
}
|
}
|
||||||
void Loop() {
|
void Loop() {
|
||||||
Worker* worker = dynamic_cast<Worker*>(this);
|
Worker* worker = (Worker*)(this);
|
||||||
worker->Loop();
|
worker->Loop();
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
#include "std/thread.h"
|
#include "std/thread.h"
|
||||||
#include "vkn/wrapper/commandpool.h"
|
#include "vkn/wrapper/commandpool.h"
|
||||||
#include "vkn/wrapper/queue.h"
|
#include "vkn/wrapper/queue.h"
|
||||||
|
#include "vkn/wrapper/device.h"
|
||||||
namespace vkn {
|
namespace vkn {
|
||||||
using zstd::channel;
|
using zstd::channel;
|
||||||
template<typename value_type, typename Worker>
|
template<typename value_type, typename Worker>
|
||||||
@ -12,6 +13,7 @@ namespace vkn {
|
|||||||
Queue& mQueue;
|
Queue& mQueue;
|
||||||
CommandPool mCommandPool;
|
CommandPool mCommandPool;
|
||||||
CommandBuffer mImmediateExeCmd;
|
CommandBuffer mImmediateExeCmd;
|
||||||
|
VkFence mImmediateFence;
|
||||||
public:
|
public:
|
||||||
ThreadWorker(Name name, Device& device, Queue& queue, VkCommandPoolCreateFlags queueFlags)
|
ThreadWorker(Name name, Device& device, Queue& queue, VkCommandPoolCreateFlags queueFlags)
|
||||||
: zstd::ThreadWorker<value_type, Worker>(64)
|
: zstd::ThreadWorker<value_type, Worker>(64)
|
||||||
@ -20,6 +22,7 @@ namespace vkn {
|
|||||||
, mQueue(queue)
|
, mQueue(queue)
|
||||||
, mCommandPool(device, queueFlags, queue.QueueFamilyIndex())
|
, mCommandPool(device, queueFlags, queue.QueueFamilyIndex())
|
||||||
, mImmediateExeCmd(mCommandPool.AllocateBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY))
|
, mImmediateExeCmd(mCommandPool.AllocateBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY))
|
||||||
|
, mImmediateFence(device.CreateFence(VK_FENCE_CREATE_SIGNALED_BIT))
|
||||||
{}
|
{}
|
||||||
CommandPool& GetCommandPool() {
|
CommandPool& GetCommandPool() {
|
||||||
return mCommandPool;
|
return mCommandPool;
|
||||||
|
|||||||
@ -28,6 +28,7 @@ namespace vkn {
|
|||||||
constexpr uint8_t MAX_SUPPORTED_RENDER_TARGET_COUNT = 8u;
|
constexpr uint8_t MAX_SUPPORTED_RENDER_TARGET_COUNT = 8u;
|
||||||
constexpr uint32_t SHADER_MODULE_COUNT = 2;
|
constexpr uint32_t SHADER_MODULE_COUNT = 2;
|
||||||
constexpr uint32_t VERTEX_ATTRIBUTE_COUNT = 16;
|
constexpr uint32_t VERTEX_ATTRIBUTE_COUNT = 16;
|
||||||
|
constexpr uint32_t MAX_BUFFER_BIND_NUM = 16;
|
||||||
struct MeshVAO
|
struct MeshVAO
|
||||||
{
|
{
|
||||||
uint32_t indexCount = 0; // 索引数量
|
uint32_t indexCount = 0; // 索引数量
|
||||||
@ -87,60 +88,6 @@ namespace vkn {
|
|||||||
uint16_t inputRate;
|
uint16_t inputRate;
|
||||||
uint32_t stride;
|
uint32_t stride;
|
||||||
};
|
};
|
||||||
//! blending equation function
|
|
||||||
enum class BlendEquation : uint8_t {
|
|
||||||
ADD, //!< the fragment is added to the color buffer
|
|
||||||
SUBTRACT, //!< the fragment is subtracted from the color buffer
|
|
||||||
REVERSE_SUBTRACT, //!< the color buffer is subtracted from the fragment
|
|
||||||
MIN, //!< the min between the fragment and color buffer
|
|
||||||
MAX //!< the max between the fragment and color buffer
|
|
||||||
};
|
|
||||||
//! comparison function for the depth / stencil sampler
|
|
||||||
enum class SamplerCompareFunc : uint8_t {
|
|
||||||
// don't change the enums values
|
|
||||||
LE = 0, //!< Less or equal
|
|
||||||
GE, //!< Greater or equal
|
|
||||||
L, //!< Strictly less than
|
|
||||||
G, //!< Strictly greater than
|
|
||||||
E, //!< Equal
|
|
||||||
NE, //!< Not equal
|
|
||||||
A, //!< Always. Depth / stencil testing is deactivated.
|
|
||||||
N //!< Never. The depth / stencil test always fails.
|
|
||||||
};
|
|
||||||
// >>> depthBiasClamp, polygonMode, lineWidth
|
|
||||||
struct RasterState {
|
|
||||||
VkCullModeFlags cullMode : 2;
|
|
||||||
VkFrontFace frontFace : 2;
|
|
||||||
VkBool32 depthBiasEnable : 1;
|
|
||||||
VkBool32 blendEnable : 1;
|
|
||||||
VkBool32 depthWriteEnable : 1;
|
|
||||||
VkBool32 alphaToCoverageEnable : 1;
|
|
||||||
VkBlendFactor srcColorBlendFactor : 5; // offset = 1 byte
|
|
||||||
VkBlendFactor dstColorBlendFactor : 5;
|
|
||||||
VkBlendFactor srcAlphaBlendFactor : 5;
|
|
||||||
VkBlendFactor dstAlphaBlendFactor : 5;
|
|
||||||
VkColorComponentFlags colorWriteMask : 4;
|
|
||||||
uint8_t rasterizationSamples; // offset = 4 bytes
|
|
||||||
uint8_t colorTargetCount; // offset = 5 bytes
|
|
||||||
BlendEquation colorBlendOp : 4; // offset = 6 bytes
|
|
||||||
BlendEquation alphaBlendOp : 4;
|
|
||||||
SamplerCompareFunc depthCompareOp; // offset = 7 bytes
|
|
||||||
float depthBiasConstantFactor; // offset = 8 bytes
|
|
||||||
float depthBiasSlopeFactor; // offset = 12 bytes
|
|
||||||
};
|
|
||||||
// The pipeline key is a POD that represents all currently bound states that form the immutable
|
|
||||||
// VkPipeline object. The size:offset comments below are expressed in bytes.
|
|
||||||
struct PipelineKey { // size : offset
|
|
||||||
VkShaderModule shaders[SHADER_MODULE_COUNT]; // 16 : 0
|
|
||||||
VkRenderPass renderPass; // 8 : 16
|
|
||||||
uint16_t topology; // 2 : 24
|
|
||||||
uint16_t subpassIndex; // 2 : 26
|
|
||||||
VertexInputAttributeDescription vertexAttributes[VERTEX_ATTRIBUTE_COUNT]; // 128 : 28
|
|
||||||
VertexInputBindingDescription vertexBuffers[VERTEX_ATTRIBUTE_COUNT]; // 128 : 156
|
|
||||||
RasterState rasterState; // 16 : 284
|
|
||||||
uint32_t padding; // 4 : 300
|
|
||||||
VkPipelineLayout layout; // 8 : 304
|
|
||||||
};
|
|
||||||
struct VulkanPipeline
|
struct VulkanPipeline
|
||||||
{
|
{
|
||||||
Name name; // For debug
|
Name name; // For debug
|
||||||
|
|||||||
@ -1,8 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "type.h"
|
#include "vulkan_context.h"
|
||||||
#include "asset/res/guid.h"
|
#include "asset/res/guid.h"
|
||||||
#include "render/renderapi.h"
|
|
||||||
#include "wrapper/commandbuffer.h"
|
|
||||||
#include "backend.h"
|
#include "backend.h"
|
||||||
namespace vkn {
|
namespace vkn {
|
||||||
class Backend;
|
class Backend;
|
||||||
@ -13,12 +11,6 @@ namespace vkn {
|
|||||||
using api::Mesh;
|
using api::Mesh;
|
||||||
using api::Shader;
|
using api::Shader;
|
||||||
using api::RenderPassNode;
|
using api::RenderPassNode;
|
||||||
struct VulkanContext : public api::RenderContext {
|
|
||||||
VkFence surfaceFence;;
|
|
||||||
VkSemaphore surfaceSemaphore;
|
|
||||||
VkSemaphore presentSemaphore;
|
|
||||||
CommandBuffer command;
|
|
||||||
};
|
|
||||||
class VULKAN_API VulkanAPI : public api::RenderAPI {
|
class VULKAN_API VulkanAPI : public api::RenderAPI {
|
||||||
private:
|
private:
|
||||||
VulkanWindow& window;
|
VulkanWindow& window;
|
||||||
|
|||||||
@ -20,6 +20,4 @@ namespace vkn {
|
|||||||
VkImageCreateFlags vkApiGetImageCreateFlag(TextureDimension dimension, uint32_t arraySize);
|
VkImageCreateFlags vkApiGetImageCreateFlag(TextureDimension dimension, uint32_t arraySize);
|
||||||
VkSampleCountFlagBits vkApiGetSmpleCountFlag(SampleCount sample);
|
VkSampleCountFlagBits vkApiGetSmpleCountFlag(SampleCount sample);
|
||||||
|
|
||||||
VkDescriptorSetLayout vkApiCreateDescriptorSetLayout();
|
|
||||||
VkPipelineLayout vkApiCreatePipelineLayout(const pmr::vector<VkDescriptorSetLayout>& descriptorSetLayouts, const pmr::vector<VkPushConstantRange>& pushConstantRanges);
|
|
||||||
}
|
}
|
||||||
20
engine/modules/render/vulkan/include/vkn/vulkan_context.h
Normal file
20
engine/modules/render/vulkan/include/vkn/vulkan_context.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#include "type.h"
|
||||||
|
#include "render/renderapi.h"
|
||||||
|
namespace vkn {
|
||||||
|
using api::BufferDesc;
|
||||||
|
struct VulkanContext : public api::RenderContext {
|
||||||
|
VkFence surfaceFence;
|
||||||
|
VkSemaphore surfaceSemaphore;
|
||||||
|
VkSemaphore presentSemaphore;
|
||||||
|
VkCommandBuffer command;
|
||||||
|
void SetScissor(uint32_t x, uint32_t y, uint32_t width, uint32_t height) override;
|
||||||
|
void SetViewport(float x, float y, float width, float height, float min_depth, float max_depth) override;
|
||||||
|
void BindIndexBuffer(BufferDesc desc, uint32_t index_stride) override;
|
||||||
|
void BindVertexBuffer(BufferDesc desc) override;
|
||||||
|
void BindVertexBuffers(uint32_t buffer_count, const BufferDesc* descs, const uint32_t* offsets)override;
|
||||||
|
void DrawIndexed(uint32_t index_count, uint32_t first_index, uint32_t first_vertex) override;
|
||||||
|
|
||||||
|
void BeginRecord(VkCommandBufferUsageFlags flag);
|
||||||
|
void EndRecord(VkQueue queue);
|
||||||
|
};
|
||||||
|
}
|
||||||
@ -27,7 +27,7 @@ namespace vkn {
|
|||||||
VkFence PopFence();
|
VkFence PopFence();
|
||||||
void PushWaitFence(VkFence fence);
|
void PushWaitFence(VkFence fence);
|
||||||
VkSemaphore CreateSemaphore();
|
VkSemaphore CreateSemaphore();
|
||||||
VkShaderModule CreateShaderModule(pmr::vector<char> code);
|
VkShaderModule CreateShaderModule(const pmr::vector<char>& code);
|
||||||
VkShaderModule CreateShaderModule(pmr::vector<uint32_t> code);
|
VkShaderModule CreateShaderModule(const pmr::vector<uint32_t>& code);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@ -24,8 +24,8 @@ namespace vkn {
|
|||||||
|
|
||||||
DeviceCreator deviceCreator = DeviceCreator{ *mInstance };
|
DeviceCreator deviceCreator = DeviceCreator{ *mInstance };
|
||||||
deviceCreator.AddWindowExtension();
|
deviceCreator.AddWindowExtension();
|
||||||
deviceCreator.AddQueue(Queue::TransferQueue,VkQueueFlagBits::VK_QUEUE_TRANSFER_BIT, 1.0);
|
|
||||||
deviceCreator.AddQueue(Queue::RenderQueue, VkQueueFlagBits::VK_QUEUE_GRAPHICS_BIT, 1.0);
|
deviceCreator.AddQueue(Queue::RenderQueue, VkQueueFlagBits::VK_QUEUE_GRAPHICS_BIT, 1.0);
|
||||||
|
deviceCreator.AddQueue(Queue::TransferQueue, VkQueueFlagBits::VK_QUEUE_TRANSFER_BIT, 1.0);
|
||||||
mDevice = new (GlobalPool()) Device(deviceCreator);
|
mDevice = new (GlobalPool()) Device(deviceCreator);
|
||||||
|
|
||||||
Backend::TransferWorker = InitWorker<BufferWorker>(Queue::TransferQueue, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
|
Backend::TransferWorker = InitWorker<BufferWorker>(Queue::TransferQueue, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
|
||||||
|
|||||||
@ -9,9 +9,9 @@ using namespace api;
|
|||||||
namespace vkn {
|
namespace vkn {
|
||||||
void VulkanGlslLoader::Init()
|
void VulkanGlslLoader::Init()
|
||||||
{
|
{
|
||||||
refl::meta_info<PosVertex>();
|
refl::register_meta<PosVertex>();
|
||||||
refl::meta_info<TexVertex>();
|
refl::register_meta<TexVertex>();
|
||||||
refl::meta_info<BoneVertex>();
|
refl::register_meta<BoneVertex>();
|
||||||
ResourceSystem::Ptr()->RegisterLoader<VulkanGlslLoader>(".geom");
|
ResourceSystem::Ptr()->RegisterLoader<VulkanGlslLoader>(".geom");
|
||||||
ResourceSystem::Ptr()->RegisterLoader<VulkanGlslLoader>(".frag");
|
ResourceSystem::Ptr()->RegisterLoader<VulkanGlslLoader>(".frag");
|
||||||
ResourceSystem::Ptr()->RegisterLoader<VulkanGlslLoader>(".vert");
|
ResourceSystem::Ptr()->RegisterLoader<VulkanGlslLoader>(".vert");
|
||||||
|
|||||||
@ -28,6 +28,7 @@ namespace vkn {
|
|||||||
{
|
{
|
||||||
while (true) {
|
while (true) {
|
||||||
Element elem = mChannel.acquire();
|
Element elem = mChannel.acquire();
|
||||||
|
mImmediateExeCmd.BeginRecord(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
|
||||||
VkBufferCreateInfo bufferInfo = {};
|
VkBufferCreateInfo bufferInfo = {};
|
||||||
bufferInfo.size = elem.size;
|
bufferInfo.size = elem.size;
|
||||||
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
||||||
@ -59,6 +60,11 @@ namespace vkn {
|
|||||||
VkBufferCopy copyRegion = {};
|
VkBufferCopy copyRegion = {};
|
||||||
copyRegion.size = elem.size;
|
copyRegion.size = elem.size;
|
||||||
vkCmdCopyBuffer(mImmediateExeCmd.Ptr(), stagingBuffer, gpuBuffer, 1, ©Region);
|
vkCmdCopyBuffer(mImmediateExeCmd.Ptr(), stagingBuffer, gpuBuffer, 1, ©Region);
|
||||||
|
mImmediateExeCmd.EndRecord();
|
||||||
|
vkResetFences(mDevice.Ptr(), 1, &mImmediateFence);
|
||||||
|
mImmediateExeCmd.Submit(mQueue.Ptr(), mImmediateFence);
|
||||||
|
vkWaitForFences(mDevice.Ptr(), 1, &mImmediateFence, VK_TRUE, UINT64_MAX);
|
||||||
|
vkDestroyBuffer(mDevice.Ptr(), stagingBuffer, nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -74,7 +74,21 @@ namespace vkn {
|
|||||||
}
|
}
|
||||||
void VulkanAPI::DrawStaticMesh(Mesh& mesh)
|
void VulkanAPI::DrawStaticMesh(Mesh& mesh)
|
||||||
{
|
{
|
||||||
|
MeshVAO& vulkanVAO = MeshTable[mesh.GetGuid()];
|
||||||
|
if (!vulkanVAO.indexBuffer || !vulkanVAO.vertexBuffer) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
VulkanPipeline& pipeline = PipelineTable[mesh.GetShaderGuid()];
|
||||||
|
VulkanContext& ctx = *(VulkanContext*)&context;
|
||||||
|
VkCommandBuffer ptr = ctx.command;
|
||||||
|
VkBuffer vertexBuffers[] = { vulkanVAO.vertexBuffer };
|
||||||
|
VkDeviceSize offsets[] = { 0 };
|
||||||
|
vkCmdBindVertexBuffers(ptr, 0, 1, vertexBuffers, offsets);
|
||||||
|
vkCmdBindIndexBuffer(ptr, vulkanVAO.indexBuffer, 0, VK_INDEX_TYPE_UINT32);
|
||||||
|
vkCmdBindPipeline(ptr, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.pipeline);
|
||||||
|
if(pipeline.descriptorSet)
|
||||||
|
vkCmdBindDescriptorSets(ptr, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.pipelineLayout, 0, 1, &pipeline.descriptorSet, 0, VK_NULL_HANDLE);
|
||||||
|
vkCmdDrawIndexed(ptr, vulkanVAO.indexCount, 1, 0, 0, 0);
|
||||||
}
|
}
|
||||||
void VulkanAPI::LoadShader(Shader& shader)
|
void VulkanAPI::LoadShader(Shader& shader)
|
||||||
{
|
{
|
||||||
@ -95,7 +109,7 @@ namespace vkn {
|
|||||||
shaderStages.push_back(shaderStageInfo);
|
shaderStages.push_back(shaderStageInfo);
|
||||||
}
|
}
|
||||||
auto it = refl::find_info(shader.Name());
|
auto it = refl::find_info(shader.Name());
|
||||||
auto meta = it->GetMeta("vkMeta");
|
auto meta = it->GetMeta(string_hash("vkMeta"));
|
||||||
// 设置顶点输入格式
|
// 设置顶点输入格式
|
||||||
VkPipelineVertexInputStateCreateInfo vertexInputInfo = {};
|
VkPipelineVertexInputStateCreateInfo vertexInputInfo = {};
|
||||||
VkVertexInputBindingDescription bindingDescription = {};
|
VkVertexInputBindingDescription bindingDescription = {};
|
||||||
@ -173,7 +187,8 @@ namespace vkn {
|
|||||||
multisampleInfo.alphaToOneEnable = VK_FALSE;
|
multisampleInfo.alphaToOneEnable = VK_FALSE;
|
||||||
|
|
||||||
RenderPassKey config{};
|
RenderPassKey config{};
|
||||||
config.colorFormat[0] = VK_FORMAT_R8G8B8A8_UNORM;
|
config.colorFormat[0] = VK_FORMAT_B8G8R8A8_SRGB;
|
||||||
|
config.samples = vkApiGetSmpleCountFlag(api::SAMPLE_COUNT_1);
|
||||||
VkRenderPass renderpass = GetRenderPass(config);
|
VkRenderPass renderpass = GetRenderPass(config);
|
||||||
// Color Blend
|
// Color Blend
|
||||||
VkPipelineColorBlendAttachmentState colorBlendAttachment{};
|
VkPipelineColorBlendAttachmentState colorBlendAttachment{};
|
||||||
@ -205,8 +220,14 @@ namespace vkn {
|
|||||||
depthStencilInfo.stencilTestEnable = VK_FALSE;
|
depthStencilInfo.stencilTestEnable = VK_FALSE;
|
||||||
depthStencilInfo.front = {};
|
depthStencilInfo.front = {};
|
||||||
depthStencilInfo.back = {};
|
depthStencilInfo.back = {};
|
||||||
auto descriptorSetLayout = vkApiCreateDescriptorSetLayout();
|
VkDescriptorSetLayout descriptorSetLayout{};
|
||||||
auto pipelineLayout = vkApiCreatePipelineLayout({ descriptorSetLayout }, {});
|
VkPipelineLayoutCreateInfo pipelineLayoutInfo = {};
|
||||||
|
pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
||||||
|
pipelineLayoutInfo.setLayoutCount = 0; // 没有描述符集布局时可以设置为0
|
||||||
|
pipelineLayoutInfo.pSetLayouts = nullptr;
|
||||||
|
VkPipelineLayout pipelineLayout;
|
||||||
|
if (vkCreatePipelineLayout(device.Ptr(), &pipelineLayoutInfo, nullptr, &pipelineLayout) != VK_SUCCESS)
|
||||||
|
throw std::runtime_error("failed to create pipeline layout!");
|
||||||
|
|
||||||
VkGraphicsPipelineCreateInfo pipelineInfo{};
|
VkGraphicsPipelineCreateInfo pipelineInfo{};
|
||||||
pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
|
pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
|
||||||
@ -239,7 +260,7 @@ namespace vkn {
|
|||||||
vulkan_pipeline.inUse = true;
|
vulkan_pipeline.inUse = true;
|
||||||
vulkan_pipeline.pipelineLayout = pipelineLayout;
|
vulkan_pipeline.pipelineLayout = pipelineLayout;
|
||||||
vulkan_pipeline.descriptorSetLayout = descriptorSetLayout;
|
vulkan_pipeline.descriptorSetLayout = descriptorSetLayout;
|
||||||
vulkan_pipeline.descriptorSet = backend.GetPool().Allocate(descriptorSetLayout);
|
vulkan_pipeline.descriptorSet = descriptorSetLayout ? backend.GetPool().Allocate(descriptorSetLayout) : nullptr;
|
||||||
}
|
}
|
||||||
ImagePtr VulkanAPI::CreateTexture(TextureDesc desc)
|
ImagePtr VulkanAPI::CreateTexture(TextureDesc desc)
|
||||||
{
|
{
|
||||||
@ -304,27 +325,12 @@ namespace vkn {
|
|||||||
{
|
{
|
||||||
VulkanContext& ctx = *(VulkanContext*)&context;
|
VulkanContext& ctx = *(VulkanContext*)&context;
|
||||||
window.Aquire(ctx);
|
window.Aquire(ctx);
|
||||||
ctx.command.BeginRecord(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
|
ctx.BeginRecord(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
|
||||||
}
|
}
|
||||||
void VulkanAPI::EndFrame()
|
void VulkanAPI::EndFrame()
|
||||||
{
|
{
|
||||||
VulkanContext& ctx = *(VulkanContext*)&context;
|
VulkanContext& ctx = *(VulkanContext*)&context;
|
||||||
ctx.command.EndRecord();
|
ctx.EndRecord(Backend::RenderWorker->GetQueue().Ptr());
|
||||||
VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT }; // 等待渲染阶段
|
|
||||||
VkSemaphore waitSemaphores[] = { ctx.surfaceSemaphore };
|
|
||||||
VkSemaphore signalSemaphores[] = { ctx.presentSemaphore };// 渲染完成信号量
|
|
||||||
VkSubmitInfo submitInfo{};
|
|
||||||
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
|
||||||
submitInfo.commandBufferCount = 1;
|
|
||||||
submitInfo.pCommandBuffers = &ctx.command.Ptr();
|
|
||||||
|
|
||||||
submitInfo.waitSemaphoreCount = 1;
|
|
||||||
submitInfo.pWaitSemaphores = waitSemaphores;
|
|
||||||
submitInfo.pWaitDstStageMask = waitStages;
|
|
||||||
|
|
||||||
submitInfo.signalSemaphoreCount = 1;
|
|
||||||
submitInfo.pSignalSemaphores = signalSemaphores;
|
|
||||||
vkQueueSubmit(Backend::RenderWorker->GetQueue().Ptr(), 1, &submitInfo, ctx.surfaceFence);
|
|
||||||
window.Present(ctx);
|
window.Present(ctx);
|
||||||
}
|
}
|
||||||
void VulkanAPI::ExecuteResourceBarriers(const ResourceBarrierDesc& desc) {
|
void VulkanAPI::ExecuteResourceBarriers(const ResourceBarrierDesc& desc) {
|
||||||
@ -343,7 +349,7 @@ namespace vkn {
|
|||||||
if (dstStageMask == 0) {
|
if (dstStageMask == 0) {
|
||||||
dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
|
dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
|
||||||
}
|
}
|
||||||
vkCmdPipelineBarrier(ctx.command.Ptr(), srcStageMask, dstStageMask, 0, 0, NULL, 0, NULL, imageBarriers.size(), imageBarriers.data());
|
vkCmdPipelineBarrier(ctx.command, srcStageMask, dstStageMask, 0, 0, NULL, 0, NULL, imageBarriers.size(), imageBarriers.data());
|
||||||
}
|
}
|
||||||
void VulkanAPI::BeginRenderPass(RenderPassNode* node)
|
void VulkanAPI::BeginRenderPass(RenderPassNode* node)
|
||||||
{
|
{
|
||||||
@ -401,12 +407,12 @@ namespace vkn {
|
|||||||
.pClearValues = clearValues
|
.pClearValues = clearValues
|
||||||
};
|
};
|
||||||
VulkanContext& ctx = *(VulkanContext*)&context;
|
VulkanContext& ctx = *(VulkanContext*)&context;
|
||||||
vkCmdBeginRenderPass(ctx.command.Ptr(), &beginInfo, VK_SUBPASS_CONTENTS_INLINE);
|
vkCmdBeginRenderPass(ctx.command, &beginInfo, VK_SUBPASS_CONTENTS_INLINE);
|
||||||
}
|
}
|
||||||
void VulkanAPI::EndRenderPass(RenderPassNode* node)
|
void VulkanAPI::EndRenderPass(RenderPassNode* node)
|
||||||
{
|
{
|
||||||
VulkanContext& ctx = *(VulkanContext*)&context;
|
VulkanContext& ctx = *(VulkanContext*)&context;
|
||||||
vkCmdEndRenderPass(ctx.command.Ptr());
|
vkCmdEndRenderPass(ctx.command);
|
||||||
}
|
}
|
||||||
VkRenderPass VulkanAPI::GetRenderPass(RenderPassKey& config) {
|
VkRenderPass VulkanAPI::GetRenderPass(RenderPassKey& config) {
|
||||||
auto it = RenderPassCache.find(config);
|
auto it = RenderPassCache.find(config);
|
||||||
|
|||||||
@ -233,12 +233,4 @@ namespace vkn {
|
|||||||
{
|
{
|
||||||
return (VkSampleCountFlagBits)sample;
|
return (VkSampleCountFlagBits)sample;
|
||||||
}
|
}
|
||||||
VkDescriptorSetLayout vkApiCreateDescriptorSetLayout()
|
|
||||||
{
|
|
||||||
return VkDescriptorSetLayout{};
|
|
||||||
}
|
|
||||||
VkPipelineLayout vkApiCreatePipelineLayout(const pmr::vector<VkDescriptorSetLayout>& descriptorSetLayouts, const pmr::vector<VkPushConstantRange>& pushConstantRanges)
|
|
||||||
{
|
|
||||||
return VkPipelineLayout();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
79
engine/modules/render/vulkan/src/vulkan_context.cpp
Normal file
79
engine/modules/render/vulkan/src/vulkan_context.cpp
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
#include "vkn/vulkan_context.h"
|
||||||
|
#include "vkn/backend.h"
|
||||||
|
namespace vkn {
|
||||||
|
void VulkanContext::SetScissor(uint32_t x, uint32_t y, uint32_t width, uint32_t height)
|
||||||
|
{
|
||||||
|
VkRect2D scissor = {
|
||||||
|
.offset{ .x = (int32_t)x, .y = (int32_t)y},
|
||||||
|
.extent {.width = width,.height = height}
|
||||||
|
};
|
||||||
|
vkCmdSetScissor(command, 0, 1, &scissor);
|
||||||
|
}
|
||||||
|
void VulkanContext::SetViewport(float x, float y, float width, float height, float min_depth, float max_depth)
|
||||||
|
{
|
||||||
|
VkViewport viewport = {
|
||||||
|
.x = x,
|
||||||
|
.y = y,
|
||||||
|
.width = width,
|
||||||
|
.height = height,
|
||||||
|
.minDepth = min_depth,
|
||||||
|
.maxDepth = max_depth
|
||||||
|
};
|
||||||
|
vkCmdSetViewport(command, 0, 1, &viewport);
|
||||||
|
}
|
||||||
|
void VulkanContext::BindIndexBuffer(BufferDesc desc, uint32_t index_stride)
|
||||||
|
{
|
||||||
|
VkIndexType vk_index_type =
|
||||||
|
(sizeof(uint16_t) == index_stride) ?
|
||||||
|
VK_INDEX_TYPE_UINT16 : ((sizeof(uint8_t) == index_stride) ? VK_INDEX_TYPE_UINT8_EXT : VK_INDEX_TYPE_UINT32);
|
||||||
|
vkCmdBindIndexBuffer(command, (VkBuffer)desc.buffer, 0, vk_index_type);
|
||||||
|
}
|
||||||
|
void VulkanContext::BindVertexBuffer(BufferDesc desc)
|
||||||
|
{
|
||||||
|
VkBuffer vertexBuffers[] = { (VkBuffer)desc.buffer };
|
||||||
|
VkDeviceSize offsets[] = { 0 };
|
||||||
|
vkCmdBindVertexBuffers(command, 0, 1, vertexBuffers, offsets);
|
||||||
|
}
|
||||||
|
void VulkanContext::BindVertexBuffers(uint32_t buffer_count, const BufferDesc* descs, const uint32_t* offsets)
|
||||||
|
{
|
||||||
|
VkBuffer vkBuffers[MAX_BUFFER_BIND_NUM] = { 0 };
|
||||||
|
VkDeviceSize vkOffsets[MAX_BUFFER_BIND_NUM] = { 0 };
|
||||||
|
for (uint32_t i = 0; i < buffer_count; i++) {
|
||||||
|
vkBuffers[i] = (VkBuffer)descs[i].buffer;
|
||||||
|
vkOffsets[i] = offsets[i];
|
||||||
|
}
|
||||||
|
vkCmdBindVertexBuffers(command, 0, buffer_count, vkBuffers, vkOffsets);
|
||||||
|
}
|
||||||
|
void VulkanContext::DrawIndexed(uint32_t index_count, uint32_t first_index, uint32_t first_vertex)
|
||||||
|
{
|
||||||
|
vkCmdDrawIndexed(command, index_count, 1, first_index, first_vertex, 0);
|
||||||
|
}
|
||||||
|
void VulkanContext::BeginRecord(VkCommandBufferUsageFlags flag)
|
||||||
|
{
|
||||||
|
VkCommandBufferBeginInfo beginInfo{
|
||||||
|
VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,//sType
|
||||||
|
nullptr, //pNext
|
||||||
|
flag //flags
|
||||||
|
};
|
||||||
|
vkBeginCommandBuffer(command, &beginInfo);
|
||||||
|
}
|
||||||
|
void VulkanContext::EndRecord(VkQueue queue)
|
||||||
|
{
|
||||||
|
vkEndCommandBuffer(command);
|
||||||
|
VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT }; // 等待渲染阶段
|
||||||
|
VkSemaphore waitSemaphores[] = { surfaceSemaphore };
|
||||||
|
VkSemaphore signalSemaphores[] = { presentSemaphore };// 渲染完成信号量
|
||||||
|
VkSubmitInfo submitInfo{};
|
||||||
|
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||||
|
submitInfo.commandBufferCount = 1;
|
||||||
|
submitInfo.pCommandBuffers = &command;
|
||||||
|
|
||||||
|
submitInfo.waitSemaphoreCount = 1;
|
||||||
|
submitInfo.pWaitSemaphores = waitSemaphores;
|
||||||
|
submitInfo.pWaitDstStageMask = waitStages;
|
||||||
|
|
||||||
|
submitInfo.signalSemaphoreCount = 1;
|
||||||
|
submitInfo.pSignalSemaphores = signalSemaphores;
|
||||||
|
vkQueueSubmit(queue, 1, &submitInfo, surfaceFence);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -97,7 +97,7 @@ namespace vkn {
|
|||||||
VkResult result = vkCreateSemaphore(mPtr, &semaphoreInfo, nullptr, &semaphore);
|
VkResult result = vkCreateSemaphore(mPtr, &semaphoreInfo, nullptr, &semaphore);
|
||||||
return semaphore;
|
return semaphore;
|
||||||
}
|
}
|
||||||
VkShaderModule Device::CreateShaderModule(pmr::vector<char> code)
|
VkShaderModule Device::CreateShaderModule(const pmr::vector<char>& code)
|
||||||
{
|
{
|
||||||
VkShaderModuleCreateInfo createInfo = {};
|
VkShaderModuleCreateInfo createInfo = {};
|
||||||
createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
|
createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
|
||||||
@ -109,7 +109,7 @@ namespace vkn {
|
|||||||
VkResult result = vkCreateShaderModule(mPtr, &createInfo, nullptr, &module);
|
VkResult result = vkCreateShaderModule(mPtr, &createInfo, nullptr, &module);
|
||||||
return module;
|
return module;
|
||||||
}
|
}
|
||||||
VkShaderModule Device::CreateShaderModule(pmr::vector<uint32_t> code)
|
VkShaderModule Device::CreateShaderModule(const pmr::vector<uint32_t>& code)
|
||||||
{
|
{
|
||||||
VkShaderModuleCreateInfo createInfo = {};
|
VkShaderModuleCreateInfo createInfo = {};
|
||||||
createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
|
createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
|
||||||
|
|||||||
@ -93,7 +93,7 @@ namespace vkn {
|
|||||||
auto family = queue_families[i];
|
auto family = queue_families[i];
|
||||||
if ((family.queueFlags & queue.flag) == queue.flag) {
|
if ((family.queueFlags & queue.flag) == queue.flag) {
|
||||||
index = i;
|
index = i;
|
||||||
if (queue_create_infos[i].queueCount < max_value * family.queueCount) {
|
if (queue_create_infos[i].queueCount < max_value) {
|
||||||
bFind = true;
|
bFind = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,7 @@ namespace vkn {
|
|||||||
const Name Queue::TransferQueue = "transfer";
|
const Name Queue::TransferQueue = "transfer";
|
||||||
const Name Queue::RenderQueue = "render" ;
|
const Name Queue::RenderQueue = "render" ;
|
||||||
Queue::Queue(Name name, uint32_t queueFamilyIndex, VkQueue queue)
|
Queue::Queue(Name name, uint32_t queueFamilyIndex, VkQueue queue)
|
||||||
: mName(name)
|
: mName(name), mPtr(queue), mQueueFamilyIndex(queueFamilyIndex)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,12 +9,15 @@ using namespace std;
|
|||||||
using namespace refl;
|
using namespace refl;
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void print_name() {
|
void print_name() {
|
||||||
|
auto sf = refl::TStr{ "S" };
|
||||||
|
auto sf2 = refl::TStr{ "void" };
|
||||||
auto aguid = meta_name<T>();
|
auto aguid = meta_name<T>();
|
||||||
auto bguid = aguid.view();
|
auto bguid = aguid.view();
|
||||||
std::cout << bguid << std::endl;
|
std::cout << bguid << std::endl;
|
||||||
}
|
}
|
||||||
int main() {
|
int main() {
|
||||||
print_name<api::Guid>();
|
constexpr auto aa = refl::detail::num_name<32>();
|
||||||
|
print_name<float[4]>();
|
||||||
print_name<decltype(&api::Guid::Multy)>();
|
print_name<decltype(&api::Guid::Multy)>();
|
||||||
std::cout << "hello world" << std::endl;
|
std::cout << "hello world" << std::endl;
|
||||||
}
|
}
|
||||||
@ -39,5 +39,6 @@ void ZWorldModule::MainLoop()
|
|||||||
API->BeginFrame();
|
API->BeginFrame();
|
||||||
API->Render();
|
API->Render();
|
||||||
API->EndFrame();
|
API->EndFrame();
|
||||||
|
FramePool()->reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,6 +6,8 @@ set_languages("cxx20")
|
|||||||
set_project("zengine")
|
set_project("zengine")
|
||||||
set_toolchains("clang")
|
set_toolchains("clang")
|
||||||
set_runtimes("MD","c++_shared")
|
set_runtimes("MD","c++_shared")
|
||||||
|
add_cxflags("-stdlib=libc++")
|
||||||
|
add_ldflags("-stdlib=libc++")
|
||||||
includes("engine")
|
includes("engine")
|
||||||
includes("game/*/xmake.lua")
|
includes("game/*/xmake.lua")
|
||||||
--xmake project -k vsxmake2022 -a x64
|
--xmake project -k vsxmake2022 -a x64
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user