draw traingle

This commit is contained in:
ouczbs 2024-10-30 15:15:25 +08:00
parent 270ce01887
commit 11590308f9
34 changed files with 328 additions and 154 deletions

View File

@ -1,11 +1,10 @@
#version 450
layout (location = 0) in vec3 iPos;
layout (location = 1) in vec2 iTex;
layout (location = 0) out vec4 vColor;
void main()
{
gl_Position = vec4(iPos.x, iPos.y, iTex.x, 1.0);
vColor = vec4(gl_Position.x, gl_Position.y, gl_Position.z, 1.0);
gl_Position = vec4(iPos.x, iPos.y, iPos.z, 1.0);
vColor = vec4(1.0, 0.0, 0.0, 1.0);
}

View File

@ -5,6 +5,7 @@ namespace api {
IMPLEMENT_STATIC_MODULE(RENDER_API, RenderModule, render);
void RenderAPI::RenderView(FRenderView& view)
{
view.context = &context;
graph.Compile();
graph.Execute(view);
graph.Clear();
@ -22,6 +23,6 @@ namespace api {
}
RenderAPI::~RenderAPI()
{
delete& context;
}
}

View File

@ -7,6 +7,7 @@ namespace api {
friend class Scene;
public:
Material(RscHandle<Shader> shader) : Material() { mShader = shader; };
Material();
~Material();
void BeginLoad() {

View File

@ -9,33 +9,33 @@ namespace api {
template<typename T>
concept Vertexs = requires {std::is_base_of_v<Vertex, T>; };
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 })
Vector3 Position = {};
};
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 })
Vector3 Position = {};
//UPROPERTY_gl({}, glVertexMeta{ 2, GL_FLOAT, GL_FALSE })
UPROPERTY_gl({}, glVertexMeta{ 2, GL_FLOAT, GL_FALSE })
UPROPERTY_vk()
Vector2 TexCoords = {};
//UPROPERTY_gl({}, glVertexMeta{ 3, GL_FLOAT, GL_FALSE })
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_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_gl({}, glVertexMeta{ 2, GL_FLOAT, GL_FALSE })
UPROPERTY_vk()
Vector2 TexCoords = {};
//UPROPERTY_gl({}, glVertexMeta{ 3, GL_FLOAT, GL_FALSE })
UPROPERTY_gl({}, glVertexMeta{ 3, GL_FLOAT, GL_FALSE })
UPROPERTY_vk()
Vector3 Normal = {};
//UPROPERTY_gl({}, glVertexMeta{ 3, GL_FLOAT, GL_FALSE })
UPROPERTY_gl({}, glVertexMeta{ 3, GL_FLOAT, GL_FALSE })
UPROPERTY_vk()
Vector3 Tangent = {};
// 骨骼蒙皮数据

View File

@ -4,8 +4,15 @@
#include "lemon/list_graph.h"
#include <functional>
namespace api {
struct RenderContext;
struct ComputePassContext {};
struct RenderPassContext {};
struct RenderPassContext {
RenderContext* parent;
RenderPassContext(RenderContext* parent) : parent(parent) {};
RenderContext* operator->() {
return parent;
}
};
struct CopyPassContext {};
class FrameGraph;

View File

@ -10,5 +10,11 @@ namespace api {
TextureDesc surface;
uint32_t frame{ 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;
};
}

View File

@ -67,7 +67,9 @@ namespace api {
};
using ImagePtr = void*;
using ImageViewPtr = void*;
using BufferPtr = void*;
struct BufferDesc {
BufferPtr buffer;
static BufferDesc Make() {
return {};
}

View File

@ -88,7 +88,7 @@ namespace api {
{
ExecuteResourceBarriers(node);
RenderAPI::Ptr()->BeginRenderPass(node);
RenderPassContext context{};
RenderPassContext context{view.context};
std::get<RenderPassExecuteFunction>(node->executor)(*this, context);
RenderAPI::Ptr()->EndRenderPass(node);
}

View File

@ -3,18 +3,32 @@
#include "render/asset/material.h"
#include "render/renderapi.h"
#include "asset/resource_system.h"
#include "render/asset/vertex.h"
#include "render/asset/mesh.h"
namespace api {
static RscHandle<Material> material;
static RscHandle<Shader> shader;
static RscHandle<Mesh> mesh;
bool DemoPass::Setup(FrameGraph& graph, FrameGraph::RenderPassBuilder& builder)
{
static RscHandle<Shader> shader;
if (!shader) {
shader = ResourceSystem::Ptr()->LoadEmplaceResource<Shader>();
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");
shader->SetVertHandle(vert);
shader->SetFragHandle(frag);
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{};
surface.FromTexture(graph.mSurface);
@ -29,8 +43,11 @@ namespace api {
.Present(edge, edge.targetState);
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);
}
}

View File

@ -11,6 +11,13 @@ namespace pmr {
{
size_t space = capacity - 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)) {
offset = capacity - space + bytes;
return ptr;

View File

@ -6,7 +6,7 @@ namespace refl {
struct TStr {
std::array<char, N> value{}; // 确切长度的字符数组,不依赖 '\0'
constexpr TStr() {};
constexpr TStr(const char(&data)[N]) {
constexpr TStr(const char(&data)[N + 1]) {
std::copy_n(data, N, value.begin());
}
@ -21,7 +21,7 @@ namespace refl {
};
template <size_t N>
TStr(const char(&)[N]) -> TStr<N>;
TStr(const char(&)[N]) -> TStr<N - 1>;
template<auto v>
constexpr auto value_name() noexcept;

View File

@ -33,7 +33,7 @@ namespace refl {
}
template <int N, int Digits = _num_digits(N)>
constexpr auto num_name() {
char data[Digits];
char data[Digits + 1];
int n = N;
for (int i = Digits - 1; i >= 0; --i) {
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>
constexpr auto meta_name() noexcept {
if constexpr (std::is_same_v<T, void>) {
@ -90,7 +102,24 @@ namespace refl {
else if constexpr (std::is_arithmetic_v<T>) {
constexpr auto prefix = detail::num_prefix_name<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 {
return detail::raw_meta_name<T>();

View File

@ -105,6 +105,10 @@ namespace refl {
template<typename T>
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 {
template<class T>
struct Meta {};
@ -112,6 +116,12 @@ namespace refl {
template<class T>
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>
concept has_parent_v = requires { typename Meta<T>::Parent; };
@ -124,5 +134,6 @@ namespace refl {
struct UClass;
template<typename Type>
const UClass* meta_info();
const UClass* find_info(Name name, size_t hash);
constexpr uint32_t MAX_ARGS_LENGTH = 10;
}

View File

@ -73,8 +73,6 @@ namespace refl {
}
//class
using GetFields_t = span<const FieldPtr>(*)(const UClass*, EFieldFind find, Name name);
//class meta
using GetMeta_t = const UClass* (*)(Name);
//function
using GetParams_t = span<const UClass*>(*)(const UClass*);
//function args
@ -85,9 +83,6 @@ namespace refl {
void AddGetFields(GetFields_t func) {
Add(string_hash("GetFields"), (void*)func);
}
void AddGetMeta(GetMeta_t func) {
Add(string_hash("GetMeta"), (void*)func);
}
void AddGetParams(GetParams_t func) {
Add(string_hash("GetParams"), (void*)func);
}
@ -101,7 +96,6 @@ namespace refl {
Add(string_hash("Destruct"), (void*)func);
}
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")); }
Call_t Call() const { return (Call_t) Find(string_hash("Call")); }
Construct_t Construct() const { return (Construct_t) Find(string_hash("Construct")); }
@ -111,7 +105,7 @@ namespace refl {
public:
Name name;
uint32_t size;
uint32_t flag{0};
uint32_t flag : 16{0};
const UClass* parent;
vtable_uclass vtable;
UClass(const UClass*) = delete;
@ -145,12 +139,8 @@ namespace refl {
}
return {};
}
const UClass* GetMeta(Name name)const {
auto func = vtable.GetMeta();
if (func) {
return func(name);
}
return {};
const UClass* GetMeta(size_t hash)const {
return find_info(name, hash);
}
bool IsChildOf(const UClass* cls, bool bthis = false) const {
const UClass* _parent = bthis ? this : parent;

View File

@ -2,8 +2,6 @@
#include "name.h"
#include "type.h"
namespace refl {
template <class T>
concept is_metas_v = requires(const Name & name) { Meta<T>::GetMeta(name); };
template<typename T>
class UClass_Auto : public UClass {
public:
@ -26,9 +24,6 @@ namespace refl {
else {
vtable.AddConstruct(&UClass::Construct<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>) {
parent = meta_info<parent_t<T>>();
}
if constexpr (is_metas_v<T>) {
vtable.AddGetMeta(&Meta<T>::GetMeta);
}
vtable.AddGetFields(&UClass_Meta::GetFields);
vtable.AddConstruct(&UClass::Construct<T>);
}
@ -256,8 +248,15 @@ namespace refl {
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*>;
UNIQUER_INLINE(__tClassTable, ClassTable, "refl::ClassTable")
using __tMetaClassTable = table<Name, MetaClasses>;
UNIQUER_INLINE(__tMetaClassTable, MetaClassTable, "refl::MetaClassTable")
inline const UClass* find_info(Name name) {
auto& ClassTable = UNIQUER_VAL(ClassTable);
if (auto it = ClassTable.find(name); it != ClassTable.end()) {
@ -265,6 +264,19 @@ namespace refl {
}
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>
inline const UClass* meta_info()
{
@ -287,4 +299,46 @@ namespace refl {
ClassTable[name.view()] = 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>();
}
}

View File

@ -10,9 +10,10 @@ namespace zstd{
channel<Element> mChannel;
void WorkLoop() {
mThread.detach();
Loop();
}
void Loop() {
Worker* worker = dynamic_cast<Worker*>(this);
Worker* worker = (Worker*)(this);
worker->Loop();
}
public:

View File

@ -2,6 +2,7 @@
#include "std/thread.h"
#include "vkn/wrapper/commandpool.h"
#include "vkn/wrapper/queue.h"
#include "vkn/wrapper/device.h"
namespace vkn {
using zstd::channel;
template<typename value_type, typename Worker>
@ -12,6 +13,7 @@ namespace vkn {
Queue& mQueue;
CommandPool mCommandPool;
CommandBuffer mImmediateExeCmd;
VkFence mImmediateFence;
public:
ThreadWorker(Name name, Device& device, Queue& queue, VkCommandPoolCreateFlags queueFlags)
: zstd::ThreadWorker<value_type, Worker>(64)
@ -20,6 +22,7 @@ namespace vkn {
, mQueue(queue)
, mCommandPool(device, queueFlags, queue.QueueFamilyIndex())
, mImmediateExeCmd(mCommandPool.AllocateBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY))
, mImmediateFence(device.CreateFence(VK_FENCE_CREATE_SIGNALED_BIT))
{}
CommandPool& GetCommandPool() {
return mCommandPool;

View File

@ -28,6 +28,7 @@ namespace vkn {
constexpr uint8_t MAX_SUPPORTED_RENDER_TARGET_COUNT = 8u;
constexpr uint32_t SHADER_MODULE_COUNT = 2;
constexpr uint32_t VERTEX_ATTRIBUTE_COUNT = 16;
constexpr uint32_t MAX_BUFFER_BIND_NUM = 16;
struct MeshVAO
{
uint32_t indexCount = 0; // 索引数量
@ -87,60 +88,6 @@ namespace vkn {
uint16_t inputRate;
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
{
Name name; // For debug

View File

@ -1,8 +1,6 @@
#pragma once
#include "type.h"
#include "vulkan_context.h"
#include "asset/res/guid.h"
#include "render/renderapi.h"
#include "wrapper/commandbuffer.h"
#include "backend.h"
namespace vkn {
class Backend;
@ -13,12 +11,6 @@ namespace vkn {
using api::Mesh;
using api::Shader;
using api::RenderPassNode;
struct VulkanContext : public api::RenderContext {
VkFence surfaceFence;;
VkSemaphore surfaceSemaphore;
VkSemaphore presentSemaphore;
CommandBuffer command;
};
class VULKAN_API VulkanAPI : public api::RenderAPI {
private:
VulkanWindow& window;

View File

@ -20,6 +20,4 @@ namespace vkn {
VkImageCreateFlags vkApiGetImageCreateFlag(TextureDimension dimension, uint32_t arraySize);
VkSampleCountFlagBits vkApiGetSmpleCountFlag(SampleCount sample);
VkDescriptorSetLayout vkApiCreateDescriptorSetLayout();
VkPipelineLayout vkApiCreatePipelineLayout(const pmr::vector<VkDescriptorSetLayout>& descriptorSetLayouts, const pmr::vector<VkPushConstantRange>& pushConstantRanges);
}

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

View File

@ -27,7 +27,7 @@ namespace vkn {
VkFence PopFence();
void PushWaitFence(VkFence fence);
VkSemaphore CreateSemaphore();
VkShaderModule CreateShaderModule(pmr::vector<char> code);
VkShaderModule CreateShaderModule(pmr::vector<uint32_t> code);
VkShaderModule CreateShaderModule(const pmr::vector<char>& code);
VkShaderModule CreateShaderModule(const pmr::vector<uint32_t>& code);
};
};

View File

@ -24,8 +24,8 @@ namespace vkn {
DeviceCreator deviceCreator = DeviceCreator{ *mInstance };
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::TransferQueue, VkQueueFlagBits::VK_QUEUE_TRANSFER_BIT, 1.0);
mDevice = new (GlobalPool()) Device(deviceCreator);
Backend::TransferWorker = InitWorker<BufferWorker>(Queue::TransferQueue, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);

View File

@ -9,9 +9,9 @@ using namespace api;
namespace vkn {
void VulkanGlslLoader::Init()
{
refl::meta_info<PosVertex>();
refl::meta_info<TexVertex>();
refl::meta_info<BoneVertex>();
refl::register_meta<PosVertex>();
refl::register_meta<TexVertex>();
refl::register_meta<BoneVertex>();
ResourceSystem::Ptr()->RegisterLoader<VulkanGlslLoader>(".geom");
ResourceSystem::Ptr()->RegisterLoader<VulkanGlslLoader>(".frag");
ResourceSystem::Ptr()->RegisterLoader<VulkanGlslLoader>(".vert");

View File

@ -28,6 +28,7 @@ namespace vkn {
{
while (true) {
Element elem = mChannel.acquire();
mImmediateExeCmd.BeginRecord(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
VkBufferCreateInfo bufferInfo = {};
bufferInfo.size = elem.size;
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
@ -59,6 +60,11 @@ namespace vkn {
VkBufferCopy copyRegion = {};
copyRegion.size = elem.size;
vkCmdCopyBuffer(mImmediateExeCmd.Ptr(), stagingBuffer, gpuBuffer, 1, &copyRegion);
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);
}
}
}

View File

@ -74,7 +74,21 @@ namespace vkn {
}
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)
{
@ -95,7 +109,7 @@ namespace vkn {
shaderStages.push_back(shaderStageInfo);
}
auto it = refl::find_info(shader.Name());
auto meta = it->GetMeta("vkMeta");
auto meta = it->GetMeta(string_hash("vkMeta"));
// 设置顶点输入格式
VkPipelineVertexInputStateCreateInfo vertexInputInfo = {};
VkVertexInputBindingDescription bindingDescription = {};
@ -173,7 +187,8 @@ namespace vkn {
multisampleInfo.alphaToOneEnable = VK_FALSE;
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);
// Color Blend
VkPipelineColorBlendAttachmentState colorBlendAttachment{};
@ -205,8 +220,14 @@ namespace vkn {
depthStencilInfo.stencilTestEnable = VK_FALSE;
depthStencilInfo.front = {};
depthStencilInfo.back = {};
auto descriptorSetLayout = vkApiCreateDescriptorSetLayout();
auto pipelineLayout = vkApiCreatePipelineLayout({ descriptorSetLayout }, {});
VkDescriptorSetLayout 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{};
pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
@ -239,7 +260,7 @@ namespace vkn {
vulkan_pipeline.inUse = true;
vulkan_pipeline.pipelineLayout = pipelineLayout;
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)
{
@ -304,27 +325,12 @@ namespace vkn {
{
VulkanContext& ctx = *(VulkanContext*)&context;
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()
{
VulkanContext& ctx = *(VulkanContext*)&context;
ctx.command.EndRecord();
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);
ctx.EndRecord(Backend::RenderWorker->GetQueue().Ptr());
window.Present(ctx);
}
void VulkanAPI::ExecuteResourceBarriers(const ResourceBarrierDesc& desc) {
@ -343,7 +349,7 @@ namespace vkn {
if (dstStageMask == 0) {
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)
{
@ -401,12 +407,12 @@ namespace vkn {
.pClearValues = clearValues
};
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)
{
VulkanContext& ctx = *(VulkanContext*)&context;
vkCmdEndRenderPass(ctx.command.Ptr());
vkCmdEndRenderPass(ctx.command);
}
VkRenderPass VulkanAPI::GetRenderPass(RenderPassKey& config) {
auto it = RenderPassCache.find(config);

View File

@ -233,12 +233,4 @@ namespace vkn {
{
return (VkSampleCountFlagBits)sample;
}
VkDescriptorSetLayout vkApiCreateDescriptorSetLayout()
{
return VkDescriptorSetLayout{};
}
VkPipelineLayout vkApiCreatePipelineLayout(const pmr::vector<VkDescriptorSetLayout>& descriptorSetLayouts, const pmr::vector<VkPushConstantRange>& pushConstantRanges)
{
return VkPipelineLayout();
}
}

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

View File

@ -97,7 +97,7 @@ namespace vkn {
VkResult result = vkCreateSemaphore(mPtr, &semaphoreInfo, nullptr, &semaphore);
return semaphore;
}
VkShaderModule Device::CreateShaderModule(pmr::vector<char> code)
VkShaderModule Device::CreateShaderModule(const pmr::vector<char>& code)
{
VkShaderModuleCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
@ -109,7 +109,7 @@ namespace vkn {
VkResult result = vkCreateShaderModule(mPtr, &createInfo, nullptr, &module);
return module;
}
VkShaderModule Device::CreateShaderModule(pmr::vector<uint32_t> code)
VkShaderModule Device::CreateShaderModule(const pmr::vector<uint32_t>& code)
{
VkShaderModuleCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;

View File

@ -93,7 +93,7 @@ namespace vkn {
auto family = queue_families[i];
if ((family.queueFlags & queue.flag) == queue.flag) {
index = i;
if (queue_create_infos[i].queueCount < max_value * family.queueCount) {
if (queue_create_infos[i].queueCount < max_value) {
bFind = true;
break;
}

View File

@ -3,7 +3,7 @@ namespace vkn {
const Name Queue::TransferQueue = "transfer";
const Name Queue::RenderQueue = "render" ;
Queue::Queue(Name name, uint32_t queueFamilyIndex, VkQueue queue)
: mName(name)
: mName(name), mPtr(queue), mQueueFamilyIndex(queueFamilyIndex)
{
}

View File

@ -9,12 +9,15 @@ using namespace std;
using namespace refl;
template<typename T>
void print_name() {
auto sf = refl::TStr{ "S" };
auto sf2 = refl::TStr{ "void" };
auto aguid = meta_name<T>();
auto bguid = aguid.view();
std::cout << bguid << std::endl;
}
int main() {
print_name<api::Guid>();
constexpr auto aa = refl::detail::num_name<32>();
print_name<float[4]>();
print_name<decltype(&api::Guid::Multy)>();
std::cout << "hello world" << std::endl;
}

View File

@ -39,5 +39,6 @@ void ZWorldModule::MainLoop()
API->BeginFrame();
API->Render();
API->EndFrame();
FramePool()->reset();
}
}

View File

@ -6,6 +6,8 @@ set_languages("cxx20")
set_project("zengine")
set_toolchains("clang")
set_runtimes("MD","c++_shared")
add_cxflags("-stdlib=libc++")
add_ldflags("-stdlib=libc++")
includes("engine")
includes("game/*/xmake.lua")
--xmake project -k vsxmake2022 -a x64