update
This commit is contained in:
parent
658a016602
commit
270ce01887
3
engine/3rdparty/xmake.lua
vendored
3
engine/3rdparty/xmake.lua
vendored
@ -1,2 +1 @@
|
||||
add_requires("spdlog", "lemon", "libsdl", "vulkansdk")
|
||||
includes("*/xmake.lua")
|
||||
add_requires("spdlog", "lemon", "libsdl", "vulkansdk","shaderc")
|
||||
@ -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()});
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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() });
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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})
|
||||
@ -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;
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
}
|
||||
@ -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}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -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()
|
||||
{
|
||||
|
||||
@ -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)
|
||||
{
|
||||
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
30
engine/modules/render/vulkan/src/wrapper/descriptorpool.cpp
Normal file
30
engine/modules/render/vulkan/src/wrapper/descriptorpool.cpp
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
1
game/zworld/assets/file_flag.meta
Normal file
1
game/zworld/assets/file_flag.meta
Normal file
@ -0,0 +1 @@
|
||||
[]
|
||||
@ -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;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user