This commit is contained in:
ouczbs 2024-10-27 22:37:35 +08:00
parent 658a016602
commit 270ce01887
18 changed files with 217 additions and 46 deletions

View File

@ -1,2 +1 @@
add_requires("spdlog", "lemon", "libsdl", "vulkansdk")
includes("*/xmake.lua")
add_requires("spdlog", "lemon", "libsdl", "vulkansdk","shaderc")

View File

@ -15,7 +15,7 @@ namespace api {
{
if (h)
{
metadatas.emplace_back(SerializedMeta{ h.guid, h->Name(), meta_name<Asset>().View(), h->Meta()});
metadatas.emplace_back(SerializedMeta{ h.guid, h->Name(), meta_name<Asset>().view(), h->Meta()});
}
}
}

View File

@ -4,7 +4,7 @@ namespace api
template<typename T>
inline const SerializedMeta* MetaBundle::FetchMeta() const
{
string_view name = meta_name<typename T::BaseResource>().View();
string_view name = meta_name<typename T::BaseResource>().view();
for (auto& elem : metadatas)
{
if (elem.t_hash == name)
@ -15,7 +15,7 @@ namespace api
template<typename T>
inline const SerializedMeta* MetaBundle::FetchMeta(string_view asset_name) const
{
string_view name = meta_name<typename T::BaseResource>().View();
string_view name = meta_name<typename T::BaseResource>().view();
for (auto& elem : metadatas)
{
if (elem.t_hash == name && asset_name == elem.name)
@ -28,7 +28,7 @@ namespace api
{
if (h)
{
metadatas.emplace_back(SerializedMeta{ h.guid, h->Name(), meta_name<T>().View() });
metadatas.emplace_back(SerializedMeta{ h.guid, h->Name(), meta_name<T>().view() });
}
}
}

View File

@ -5,6 +5,6 @@ static_component("render","engine")
add_includedirs("3rdparty", {public = true})
add_headerfiles("include/**.h", "include/**.inl")
add_files("src/**.cpp")
add_deps("asset", "zlib", "core","shaderc")
add_deps("asset", "zlib", "core")
add_syslinks("user32", {public = true})
add_packages("lemon", "libsdl", {public = true})
add_packages("lemon", "libsdl","shaderc", {public = true})

View File

@ -2,22 +2,26 @@
#include <array>
#include <string_view>
namespace refl {
template<size_t N>
struct TStr {
std::array<char, N> value;
constexpr TStr() {};
constexpr TStr(const char(&data)[N]) : value{} {
std::copy(data, data + N, value.begin());
}
constexpr TStr(std::string_view data) : value{} {
std::copy(data.begin(), data.end(), value.begin());
}
constexpr std::string_view View()const {
return std::string_view(value.data(), N - 1);
}
};
template<size_t N>
TStr(const char(&)[N]) -> TStr<N>;
template <size_t N>
struct TStr {
std::array<char, N> value{}; // 确切长度的字符数组,不依赖 '\0'
constexpr TStr() {};
constexpr TStr(const char(&data)[N]) {
std::copy_n(data, N, value.begin());
}
constexpr TStr(std::string_view data) {
std::copy_n(data.begin(), std::min(N, data.size()), value.begin());
}
// 直接返回 std::string_view 类型,无需额外处理末尾字符
constexpr std::string_view view() const {
return std::string_view(value.data(), N);
}
};
template <size_t N>
TStr(const char(&)[N]) -> TStr<N>;
template<auto v>
constexpr auto value_name() noexcept;

View File

@ -5,7 +5,7 @@ namespace refl {
constexpr std::string_view func_signature() noexcept {
# if defined(__clang__)
auto sign = std::string_view{ __PRETTY_FUNCTION__ };
return sign.substr(47, sign.size() - 47);
return sign.substr(53, sign.size() - 54);
# elif defined(__GNUC__)
auto sign = std::string_view{ __PRETTY_FUNCTION__ };
return sign.substr(62, sign.size() - 62);
@ -22,9 +22,9 @@ namespace refl {
}
template<size_t N, size_t M>
constexpr auto concat(const TStr<N>& lhs, const TStr<M>& rhs) {
TStr<N + M - 1> result;
std::copy(lhs.value.begin(), lhs.value.end() - 1, result.value.begin());
std::copy(rhs.value.begin(), rhs.value.end(), result.value.begin() + N - 1);
TStr<N + M> result;
std::copy(lhs.value.begin(), lhs.value.end(), result.value.begin());
std::copy(rhs.value.begin(), rhs.value.end(), result.value.begin() + N);
return result;
}
@ -33,13 +33,12 @@ namespace refl {
}
template <int N, int Digits = _num_digits(N)>
constexpr auto num_name() {
char data[Digits + 1];
char data[Digits];
int n = N;
for (int i = Digits - 1; i >= 0; --i) {
data[i] = static_cast<char>('0' + n % 10);
n /= 10;
}
data[Digits] = '\0'; // null-terminated string
return TStr{ data };
}
template<typename T>

View File

@ -7,7 +7,7 @@ namespace refl {
template<typename T>
class UClass_Auto : public UClass {
public:
UClass_Auto() : UClass(meta_name<T>().View(), sizeof(T)) {
UClass_Auto() : UClass(meta_name<T>().view(), sizeof(T)) {
if constexpr (std::is_pointer_v<T>) {
using RT = std::remove_pointer_t<T>;
flag |= CLASS_POINTER_FLAG;
@ -43,7 +43,7 @@ namespace refl {
using MethodType = R(*)(Args...);
public:
std::array<const UClass*, sizeof...(Args) + 1> UList{};
UMethod_Auto() : UClass(meta_name<MethodType>().View(), sizeof(MethodType)) {
UMethod_Auto() : UClass(meta_name<MethodType>().view(), sizeof(MethodType)) {
flag = CLASS_TRIVIAL_FLAG;
vtable.AddGetParams(&UMethod_Auto::GetParams);
vtable.AddCall(&UMethod_Auto::Call);
@ -142,7 +142,7 @@ namespace refl {
memcpy(pit, &it, sizeof(it));
pit->val = &*it;
}
UClass_Container() : UClass_Container_Impl(meta_name<T>().View(), sizeof(T)) {
UClass_Container() : UClass_Container_Impl(meta_name<T>().view(), sizeof(T)) {
parent = meta_info<value_type>();
flag = CLASS_CONTAINER_FLAG;
vtable.AddConstruct(&UClass_Container::construct);
@ -169,7 +169,7 @@ namespace refl {
using FieldsType = decltype(MetaImpl::MakeFields());
public:
FieldsType Fields{ MetaImpl::MakeFields() };
UClass_Meta() : UClass(meta_name<T>().View(), sizeof(T)) {
UClass_Meta() : UClass(meta_name<T>().view(), sizeof(T)) {
if constexpr (has_parent_v<T>) {
parent = meta_info<parent_t<T>>();
}
@ -270,7 +270,7 @@ namespace refl {
{
using T = real_type_t<Type>;
constexpr auto name = meta_name<T>();
if (auto cls = find_info(name.View())) {
if (auto cls = find_info(name.view())) {
return cls;
}
UClass* cls;
@ -278,13 +278,13 @@ namespace refl {
cls = new(MetaGlobalPool()) UClass_Meta<T, meta_t<T>>{};
}
else if constexpr (std::is_same_v<T, void>) {
cls = new(MetaGlobalPool()) UClass{ name.View(), 0 };
cls = new(MetaGlobalPool()) UClass{ name.view(), 0 };
}
else {
cls = meta_info_impl<T>::create();
}
auto& ClassTable = UNIQUER_VAL(ClassTable);
ClassTable[name.View()] = cls;
ClassTable[name.view()] = cls;
return cls;
}
}

View File

@ -1,5 +1,6 @@
#pragma once
#include "vkn/type.h"
#include "wrapper/descriptorpool.h"
namespace vkn {
class Device;
class Instance;
@ -7,6 +8,7 @@ namespace vkn {
protected:
Instance* mInstance;
Device* mDevice;
DescriptorPool* mPool;
public:
Backend(string_view appName);
~Backend();
@ -18,6 +20,9 @@ namespace vkn {
Device& GetDevice() {
return *mDevice;
}
DescriptorPool& GetPool() {
return *mPool;
}
public:
static struct BufferWorker* TransferWorker;
static struct CommandWorker* RenderWorker;

View File

@ -26,6 +26,8 @@ namespace vkn {
constexpr string_view VulkanEngineName = "vulkan";
constexpr uint8_t MAX_SUPPORTED_RENDER_TARGET_COUNT = 8u;
constexpr uint32_t SHADER_MODULE_COUNT = 2;
constexpr uint32_t VERTEX_ATTRIBUTE_COUNT = 16;
struct MeshVAO
{
uint32_t indexCount = 0; // 索引数量
@ -53,6 +55,92 @@ namespace vkn {
uint32_t height;
uint32_t layers;
};
// Equivalent to VkVertexInputAttributeDescription but half as big.
struct VertexInputAttributeDescription {
VertexInputAttributeDescription& operator=(const VkVertexInputAttributeDescription& that) {
location = that.location;
binding = that.binding;
format = that.format;
offset = that.offset;
return *this;
}
operator VkVertexInputAttributeDescription() const {
return { location, binding, VkFormat(format), offset };
}
uint8_t location;
uint8_t binding;
uint16_t format;
uint32_t offset;
};
// Equivalent to VkVertexInputBindingDescription but not as big.
struct VertexInputBindingDescription {
VertexInputBindingDescription& operator=(const VkVertexInputBindingDescription& that) {
binding = that.binding;
stride = that.stride;
inputRate = that.inputRate;
return *this;
}
operator VkVertexInputBindingDescription() const {
return { binding, stride, (VkVertexInputRate)inputRate };
}
uint16_t binding;
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

@ -19,4 +19,7 @@ namespace vkn {
VkImageType vkApiGetImageType(TextureDimension dimension);
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,25 @@
#pragma once
#include "vkn/type.h"
#include "commandbuffer.h"
namespace vkn {
class Device;
class Queue;
class DescriptorPool {
protected:
VkDescriptorPool mPtr;
Device& mDevice;
public:
DescriptorPool(Device& device, pmr::vector<VkDescriptorPoolSize>& pPoolSizes,uint32_t maxSets);
VkDescriptorSet Allocate(VkDescriptorSetLayout& descriptorSetLayout);
public:
static pmr::vector<VkDescriptorPoolSize> DefaultDescriptorPoolSize() {
return pmr::vector<VkDescriptorPoolSize>{
{VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 10000},
{VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 10000},
{VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 10000},
{VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 10000}
};
}
};
}

View File

@ -6,6 +6,7 @@
#include "vkn/wrapper/queue.h"
#include "vkn/thread/buffer_worker.h"
#include "vkn/thread/command_worker.h"
#include "vkn/wrapper/descriptorpool.h"
namespace vkn {
BufferWorker* Backend::TransferWorker;
CommandWorker* Backend::RenderWorker;
@ -30,6 +31,9 @@ namespace vkn {
Backend::TransferWorker = InitWorker<BufferWorker>(Queue::TransferQueue, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
Backend::RenderWorker = InitWorker<CommandWorker>(Queue::RenderQueue, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
Backend::TransferWorker->InitVmaAllocator(mInstance->Ptr());
auto poolSizes = DescriptorPool::DefaultDescriptorPoolSize();
mPool = new DescriptorPool(*mDevice, poolSizes, 1000);
}
Backend::~Backend()
{

View File

@ -94,8 +94,6 @@ namespace vkn {
shaderStageInfo.pName = "main";
shaderStages.push_back(shaderStageInfo);
}
RenderPassKey config{};
VkRenderPass renderpass;
auto it = refl::find_info(shader.Name());
auto meta = it->GetMeta("vkMeta");
// 设置顶点输入格式
@ -174,6 +172,9 @@ namespace vkn {
multisampleInfo.alphaToCoverageEnable = VK_FALSE;
multisampleInfo.alphaToOneEnable = VK_FALSE;
RenderPassKey config{};
config.colorFormat[0] = VK_FORMAT_R8G8B8A8_UNORM;
VkRenderPass renderpass = GetRenderPass(config);
// Color Blend
VkPipelineColorBlendAttachmentState colorBlendAttachment{};
colorBlendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
@ -190,7 +191,6 @@ namespace vkn {
colorBlending.logicOp = VK_LOGIC_OP_COPY;
colorBlending.pAttachments = &colorBlendAttachment;
colorBlending.attachmentCount = 1;
// 深度和模板配置
VkPipelineDepthStencilStateCreateInfo depthStencilInfo = {};
depthStencilInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
@ -205,9 +205,8 @@ namespace vkn {
depthStencilInfo.stencilTestEnable = VK_FALSE;
depthStencilInfo.front = {};
depthStencilInfo.back = {};
/*
auto descriptorSetLayout = VulkanContext::CreateDescriptorSetLayout(shader.GetInfo());
auto pipelineLayout = VulkanContext::CreatePipelineLayout({ descriptorSetLayout }, {});
auto descriptorSetLayout = vkApiCreateDescriptorSetLayout();
auto pipelineLayout = vkApiCreatePipelineLayout({ descriptorSetLayout }, {});
VkGraphicsPipelineCreateInfo pipelineInfo{};
pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
@ -241,7 +240,6 @@ namespace vkn {
vulkan_pipeline.pipelineLayout = pipelineLayout;
vulkan_pipeline.descriptorSetLayout = descriptorSetLayout;
vulkan_pipeline.descriptorSet = backend.GetPool().Allocate(descriptorSetLayout);
*/
}
ImagePtr VulkanAPI::CreateTexture(TextureDesc desc)
{

View File

@ -233,4 +233,12 @@ 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,30 @@
#include "vkn/wrapper/descriptorpool.h"
#include "vkn/wrapper/device.h"
namespace vkn {
DescriptorPool::DescriptorPool(Device& device, pmr::vector<VkDescriptorPoolSize>& PoolSizes, uint32_t maxSets)
: mPtr(nullptr)
, mDevice(device)
{
VkDescriptorPoolCreateInfo descriptorPoolInfo{};
descriptorPoolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
descriptorPoolInfo.poolSizeCount = PoolSizes.size();
descriptorPoolInfo.pPoolSizes = PoolSizes.data();
descriptorPoolInfo.maxSets = maxSets;
vkCreateDescriptorPool(mDevice.Ptr(), &descriptorPoolInfo, nullptr, &mPtr);
}
VkDescriptorSet DescriptorPool::Allocate(VkDescriptorSetLayout& descriptorSetLayout)
{
VkDescriptorSet descriptorSet;
VkDescriptorSetAllocateInfo allocInfo{};
allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
allocInfo.descriptorPool = mPtr;
allocInfo.descriptorSetCount = 1;
allocInfo.pSetLayouts = &descriptorSetLayout;
vkAllocateDescriptorSets(mDevice.Ptr(), &allocInfo, &descriptorSet);
return descriptorSet;
}
}

View File

@ -0,0 +1 @@
[]

View File

@ -7,8 +7,14 @@
using namespace api;
using namespace std;
using namespace refl;
template<typename T>
void print_name() {
auto aguid = meta_name<T>();
auto bguid = aguid.view();
std::cout << bguid << std::endl;
}
int main() {
auto aguid = meta_name<api::Guid>();
auto bguid = aguid.View();
print_name<api::Guid>();
print_name<decltype(&api::Guid::Multy)>();
std::cout << "hello world" << std::endl;
}

View File

@ -1,3 +1,4 @@
add_repositories("local_repo F:\\xmake.repo")
add_rules("mode.debug", "mode.release")
set_version("1.0.1", {soname = true})
set_arch("x64")