vkCreateShaderModule bugfix

This commit is contained in:
ouczbs 2024-07-02 22:17:53 +08:00
parent 9d09dee27f
commit e6d4313f90
18 changed files with 85 additions and 103 deletions

View File

@ -44,7 +44,7 @@ namespace refl {
}
}
bool Check(const UClass* toClass)const;
constexpr bool IsValid() const{
constexpr operator bool() const{
return cls != nullptr && ptr != nullptr;
}
constexpr int Size()const;

View File

@ -58,6 +58,24 @@ namespace refl {
Data data{};
uint32_t flag{};
Offset GetOffset() const{
if (flag & FIELD_ATTRIBUTE_FLAG) {
return data.member.offset;
}
return 0;
}
Any GetValue()const {
if (flag & FIELD_ATTRIBUTE_FLAG)
return data.member.value;
return {};
}
Any GetMeta()const {
if (flag & FIELD_ATTRIBUTE_FLAG)
return data.member.meta;
if(flag & FIELD_METHOD_FLAG)
return data.method.meta;
return {};
}
//unsafe
bool Invoke(const sarray<Any>& ArgsList)const;
//safe

View File

@ -19,7 +19,7 @@ namespace refl {
method.value = args.ToSArray();
memory += args.Size();
}
if (data.meta.IsValid()) {
if (data.meta) {
method.meta = data.meta.Change(memory);
Convert::Construct(method.meta, data.meta);
memory += data.meta.Size();
@ -33,12 +33,12 @@ namespace refl {
MemberData member;
auto cls = &TypeInfo<T>::StaticClass;
member.offset = reinterpret_cast<std::size_t>(&(reinterpret_cast<const Obj*>(0)->*ptr));
if (data.value.IsValid()) {
if (data.value) {
member.value = Any(memory, cls);
assert(Convert::Construct(member.value, data.value));
memory += member.value.Size();
}
if (data.meta.IsValid()) {
if (data.meta) {
member.meta = data.meta.Change(memory);
Convert::Construct(member.meta, data.meta);
memory += data.meta.Size();
@ -58,7 +58,7 @@ namespace refl {
method.value = args.ToSArray();
memory += args.Size();
}
if (data.meta.IsValid()) {
if (data.meta) {
method.meta = data.meta.Change(memory);
Convert::Construct(method.meta, data.meta);
memory += data.meta.Size();
@ -78,7 +78,7 @@ namespace refl {
method.value = args.ToSArray();
memory += args.Size();
}
if (data.meta.IsValid()) {
if (data.meta) {
method.meta = data.meta.Change(memory);
Convert::Construct(method.meta, data.meta);
memory += data.meta.Size();
@ -98,7 +98,7 @@ namespace refl {
method.value = args.ToSArray();
memory += args.Size();
}
if (data.meta.IsValid()) {
if (data.meta) {
method.meta = data.meta.Change(memory);
Convert::Construct(method.meta, data.meta);
memory += data.meta.Size();

View File

@ -27,6 +27,7 @@
#define USING_OVERLOAD_FUNC(R, ...) using USING_FUNC_NAME = R(*)(__VA_ARGS__);
#define USING_OVERLOAD_CLASS_FUNC(R, Class, ...) using USING_FUNC_NAME = R(Class::*)(__VA_ARGS__);
#define REGISTER_META_TABLE(Class) refl::UClass::MetaTable.emplace(type_name<Class>().View(), &refl::TypeInfo<Class>::StaticClass);
/*
struct vec3{
USING_OVERLOAD_CTOR(vec3)

View File

@ -11,7 +11,7 @@ namespace refl {
consteval FieldPtr StaticCtorField(T(*ptr)(Args...), const MethodData& data = {}) {
uint32_t flag = FIELD_CTOR_FLAG;
Offset offset = AnyArgs::GetArgsSize<void,void*, Args...>(data.value);
if (data.meta.IsValid()) {
if (data.meta) {
offset += data.meta.Size();
}
FieldPtr::Data method(offset);
@ -19,8 +19,8 @@ namespace refl {
}
template<typename T, typename Obj>
consteval FieldPtr StaticMemberField(T Obj::* ptr, const Name& name, const MemberData& data = {}) {
Offset offset = data.value.IsValid() ? sizeof(T) : 0;
if (data.meta.IsValid()) {
Offset offset = data.value ? sizeof(T) : 0;
if (data.meta) {
offset += data.meta.Size();
}
FieldPtr::Data member(offset);
@ -31,7 +31,7 @@ namespace refl {
consteval FieldPtr StaticMethodField(R(*ptr)(Args...), const Name& name, const MethodData& data = {}) {
uint32_t flag = FIELD_METHOD_FLAG;
Offset offset = AnyArgs::GetArgsSize<R, Args...>(data.value);
if (data.meta.IsValid()) {
if (data.meta) {
offset += data.meta.Size();
}
FieldPtr::Data method(offset);
@ -41,7 +41,7 @@ namespace refl {
consteval FieldPtr StaticMethodField(R(T::* ptr)(Args...), const Name& name, const MethodData& data = {}) {
uint32_t flag = FIELD_MEMBER_FLAG | FIELD_METHOD_FLAG;
Offset offset = AnyArgs::GetArgsSize<R,void*, Args...>(data.value);
if (data.meta.IsValid()) {
if (data.meta) {
offset += data.meta.Size();
}
FieldPtr::Data method(offset);
@ -51,7 +51,7 @@ namespace refl {
consteval FieldPtr StaticMethodField(R(T::* ptr)(Args...)const, const Name& name, const MethodData& data = {}) {
uint32_t flag = FIELD_MEMBER_FLAG | FIELD_METHOD_FLAG;
Offset offset = AnyArgs::GetArgsSize<R, void*, Args...>(data.value);
if (data.meta.IsValid()) {
if (data.meta) {
offset += data.meta.Size();
}
FieldPtr::Data method(offset);

View File

@ -50,7 +50,7 @@ namespace YAML
}
inline Node TextArchive::Serialize(const Any& any)
{
if (!any.IsValid()) {
if (!any) {
return {};
}
auto it = FuncMap.find(any.cls);
@ -81,7 +81,7 @@ namespace YAML
}
inline bool TextArchive::Unserialize(const Node& res, const Any& any)
{
if (!any.IsValid()) {
if (!any) {
return false;
}
if (res.IsNull()) {

View File

@ -50,7 +50,7 @@ namespace zstd {
}
return nullptr;
}
constexpr bool IsValid() const noexcept {
constexpr operator bool() const noexcept {
return m_count > 0;
}
constexpr bool empty() const noexcept {
@ -78,7 +78,6 @@ namespace zstd {
++ptr;
return *this;
}
//这里其实是--it,而不是it--
constexpr iterator& operator--(int) noexcept {
--ptr;
return *this;

View File

@ -25,7 +25,7 @@ namespace zstd {
m_count++;
}
}
constexpr bool IsValid() const noexcept {
constexpr operator bool() const noexcept {
return m_count > 0;
}
constexpr bool empty() const noexcept {

View File

@ -1,7 +0,0 @@
#pragma once
#include "refl/refl.h"
namespace engineapi {
struct VertexMeta {
uint32_t format;
};
}

View File

@ -1,18 +1,17 @@
#pragma once
#include "math/vector3.h"
#include "math/vector2.h"
#include "meta.h"
#include "refl/refl.h"
// 顶点最多关联4个骨骼
#define MAX_NUM_BONES_PER_VERTEX 4
namespace engineapi {
struct Vertex {};
struct PosVertex : public Vertex {
UPROPERTY_vk({}, VertexMeta{ VK_FORMAT_R32G32B32_SFLOAT })
UPROPERTY_vk({}, uint32_t{ VK_FORMAT_R32G32B32_SFLOAT })
Vector3 Position = {};
};
struct TexVertex : public Vertex {
UPROPERTY_vk({}, VertexMeta{ VK_FORMAT_R32G32B32_SFLOAT })
UPROPERTY_vk({}, uint32_t{ VK_FORMAT_R32G32B32_SFLOAT })
Vector3 Position = {};
UPROPERTY_vk()
Vector3 Normal = {};
@ -21,7 +20,7 @@ namespace engineapi {
};
struct BoneVertex : public Vertex
{
UPROPERTY_vk({}, VertexMeta{ VK_FORMAT_R32G32B32_SFLOAT })
UPROPERTY_vk({}, uint32_t{ VK_FORMAT_R32G32B32_SFLOAT })
Vector3 Position = {};
UPROPERTY_vk()
Vector2 TexCoords = {};

View File

@ -4,6 +4,7 @@
#include "asset/file_manager.h"
#include "render/meta/vertex.h"
#include "vkmeta_vertex_gen.inl"
#include <spirv_cross/spirv_reflect.hpp>
using namespace engineapi;
namespace vulkanapi {
vk::ShaderStageFlagBits GetShaderType(string_view ext)
@ -21,16 +22,23 @@ namespace vulkanapi {
}
void VulkanGlslLoader::Init()
{
REGISTER_META_TABLE(PosVertex);
REGISTER_META_TABLE(TexVertex);
REGISTER_META_TABLE(BoneVertex);
ResourceManager::GetSingleton().RegisterLoader<VulkanGlslLoader>(".geom");
ResourceManager::GetSingleton().RegisterLoader<VulkanGlslLoader>(".frag");
ResourceManager::GetSingleton().RegisterLoader<VulkanGlslLoader>(".vert");
}
void VulkanGlslLoader::LoadShaderInfo(const std::string_view& name)
void VulkanGlslLoader::LoadShaderInfo(const engineapi::Guid& guid, const std::vector<uint32_t>& spirv)
{
auto it = refl::UClass::MetaTable.find(Name(name));
auto meta = it->second->vtable.GetMeta("vkMeta");
int x = 1;
int y = 2;
spirv_cross::Compiler compiler(spirv);
auto resources = compiler.get_shader_resources();
for (auto& ub : resources.uniform_buffers)
{
auto type = compiler.get_type(ub.type_id);
auto binding = compiler.get_decoration(ub.id, spv::Decoration::DecorationBinding);
auto set = compiler.get_decoration(ub.id, spv::Decoration::DecorationDescriptorSet);
}
}
ResourceBundle VulkanGlslLoader::LoadFile(PackagePath handle, const MetaBundle& meta)
{
@ -45,10 +53,10 @@ namespace vulkanapi {
if (res) {
string glsl = res.value();
auto shader_enum = GetShaderType(handle.GetExtension());
//glsl = GlslToSpirv::PreprocessGlsl(glsl);
auto spirv = GlslToSpirv::spirv(glsl, shader_enum, handle.GetFileName());
if (spirv) {
program->Load(*spirv);
LoadShaderInfo(program->GetHandle().guid, *spirv);
}
}
}

View File

@ -14,9 +14,10 @@ namespace vulkanapi {
};
class VulkanGlslLoader : public engineapi::IFileLoader
{
inline static table<engineapi::Guid, void*> ShaderTable;
public:
static void Init();
static void LoadShaderInfo(const std::string_view& name);
static void LoadShaderInfo(const engineapi::Guid& guid, const std::vector<unsigned int>& spirv);
engineapi::ResourceBundle LoadFile(engineapi::PackagePath handle, const engineapi::MetaBundle& meta) override;
};
}

View File

@ -8,18 +8,6 @@ namespace vulkanapi
{
using std::vector;
using zstd::hash_table;
constexpr auto replacer = R"(
#ifdef OGL
#define U_LAYOUT(SET, BIND)
#define S_LAYOUT(SET, BIND)
#define BLOCK(X) struct X
#endif
#ifdef VULKAN
#define U_LAYOUT(SET, BIND) layout(std140, set = SET, binding = BIND)
#define S_LAYOUT(SET, BIND) layout(set = SET, binding = BIND)
#define BLOCK(X) X
#endif
)";
shaderc_shader_kind ConvertStageSC(vk::ShaderStageFlagBits stage)
{
static hash_table< vk::ShaderStageFlagBits, shaderc_shader_kind> conv
@ -33,29 +21,18 @@ namespace vulkanapi
auto itr = conv.find(stage);
return itr->second;
}
string GlslToSpirv::PreprocessGlsl(string glsl)
std::optional<std::vector<uint32_t>> GlslToSpirv::spirv(const string& glsl, vk::ShaderStageFlagBits v_stage, string_view code_id)
{
string shader_code = glsl;
//shader_code = ProcessIncludes(shader_code);
auto version_pos = shader_code.find("#version");
auto version_end = shader_code.find("\n", version_pos);
return shader_code.substr(0, version_end) + replacer + shader_code.substr(version_end, shader_code.size() - version_end);
}
std::optional<std::vector<unsigned int>> GlslToSpirv::spirv(const string& glsl, vk::ShaderStageFlagBits v_stage, string_view code_id)
{
std::optional<std::vector<unsigned int>> spirv_out;
std::optional<std::vector<uint32_t>> spirv_out;
{
shaderc::Compiler compiler;
shaderc::CompileOptions options;
options.SetOptimizationLevel(shaderc_optimization_level_performance);
options.SetTargetEnvironment(shaderc_target_env::shaderc_target_env_vulkan, shaderc_env_version_vulkan_1_2);
options.SetTargetEnvironment(shaderc_target_env::shaderc_target_env_vulkan, shaderc_env_version_vulkan_1_3);
auto result = compiler.CompileGlslToSpv(glsl, ConvertStageSC(v_stage), code_id.data(), options);
if (result.GetCompilationStatus() != shaderc_compilation_status::shaderc_compilation_status_success)
return spirv_out;
spirv_out = vector<unsigned int>{ result.begin(),result.end() };
spirv_out = vector<uint32_t>{ result.cbegin(),result.cend() };
}
return spirv_out;
}

View File

@ -10,7 +10,6 @@ namespace vulkanapi
class GlslToSpirv
{
public:
static string PreprocessGlsl(string glsl);
static std::optional<std::vector<unsigned int>> spirv(const string& glsl, vk::ShaderStageFlagBits v_stage, string_view code_id = "unknown_shader");
static std::optional<std::vector<uint32_t>> spirv(const string& glsl, vk::ShaderStageFlagBits v_stage, string_view code_id = "unknown_shader");
};
}

View File

@ -151,7 +151,6 @@ namespace vulkanapi {
}
void RenderVulkanAPI::LoadShader(Shader* shader)
{
VulkanGlslLoader::LoadShaderInfo(shader->GetVertexName());
vector<VkPipelineShaderStageCreateInfo> shaderStages;
std::map<VkShaderStageFlagBits, VkShaderModule> shaderModules;
auto device = backend.GetDevice();
@ -168,43 +167,31 @@ namespace vulkanapi {
shaderStageInfo.pName = "main";
shaderStages.push_back(shaderStageInfo);
}
auto it = refl::UClass::MetaTable.find(shader->GetVertexName());
auto meta = it->second->vtable.GetMeta("vkMeta");
// 设置顶点输入格式
VkPipelineVertexInputStateCreateInfo vertexInputInfo = {};
VkVertexInputBindingDescription bindingDescription = {};
bindingDescription.binding = 0;
bindingDescription.stride = sizeof(Vertex);
bindingDescription.stride = meta->size;
bindingDescription.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
array<VkVertexInputAttributeDescription, 6> attributeDescriptions = { };
attributeDescriptions[0].binding = 0;
attributeDescriptions[0].location = 0;
attributeDescriptions[0].format = VK_FORMAT_R32G32B32_SFLOAT;
attributeDescriptions[0].offset = offsetof(BoneVertex, Position);
attributeDescriptions[1].binding = 0;
attributeDescriptions[1].location = 1;
attributeDescriptions[1].format = VK_FORMAT_R32G32_SFLOAT;
attributeDescriptions[1].offset = offsetof(BoneVertex, TexCoords);
attributeDescriptions[2].binding = 0;
attributeDescriptions[2].location = 2;
attributeDescriptions[2].format = VK_FORMAT_R32G32B32_SFLOAT;
attributeDescriptions[2].offset = offsetof(BoneVertex, Normal);
attributeDescriptions[3].binding = 0;
attributeDescriptions[3].location = 3;
attributeDescriptions[3].format = VK_FORMAT_R32G32B32_SFLOAT;
attributeDescriptions[3].offset = offsetof(BoneVertex, Tangent);
attributeDescriptions[4].binding = 0;
attributeDescriptions[4].location = 4;
attributeDescriptions[4].format = VK_FORMAT_R32G32B32A32_SFLOAT;
attributeDescriptions[4].offset = offsetof(BoneVertex, Weights);
attributeDescriptions[5].binding = 0;
attributeDescriptions[5].location = 5;
attributeDescriptions[5].format = VK_FORMAT_R32G32B32A32_UINT;
attributeDescriptions[5].offset = offsetof(BoneVertex, BoneIDs);
VkPipelineVertexInputStateCreateInfo vertexInputInfo = {};
//这里顶点属性不能大余16
array<VkVertexInputAttributeDescription, 16> attributeDescriptions = { };
{
uint32_t count = 0;
for (auto& field : meta->GetFields(refl::FIND_ALL_MEMBER, FName(""))) {
auto& attr = attributeDescriptions[count];
attr.binding = 0;
attr.location = count++;
attr.format = field.GetMeta() ? (VkFormat)field.GetMeta().CastTo<uint32_t>() : VK_FORMAT_R32G32B32_SFLOAT;
attr.offset = field.GetOffset();
}
vertexInputInfo.vertexAttributeDescriptionCount = count;
}
vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
vertexInputInfo.pVertexBindingDescriptions = &bindingDescription;
vertexInputInfo.vertexBindingDescriptionCount = 1;
vertexInputInfo.pVertexAttributeDescriptions = attributeDescriptions.data();
vertexInputInfo.vertexAttributeDescriptionCount = static_cast<uint32_t>(attributeDescriptions.size());
vertexInputInfo.vertexBindingDescriptionCount = 1;
// 设置图元
VkPipelineInputAssemblyStateCreateInfo inputAssemblyInfo = {};
@ -315,8 +302,8 @@ namespace vulkanapi {
if (vkCreateGraphicsPipelines(device.Ptr(), VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &pipeLine) != VK_SUCCESS)
throw std::runtime_error("failed to create graphics pipeline!");
for (auto& shaderModule : shaderModules)
vkDestroyShaderModule(device.Ptr(), shaderModule.second, nullptr);
//for (auto& shaderModule : shaderModules)
//vkDestroyShaderModule(device.Ptr(), shaderModule.second, nullptr);
auto vulkan_pipeline = GetNextPipeline(shader->GetID());
vulkan_pipeline->name = "";//shader->GetName();

View File

@ -91,12 +91,12 @@ namespace vulkanapi {
VkResult result = vkCreateShaderModule(mPtr, &createInfo, nullptr, &module);
return module;
}
VkShaderModule Device::CreateShaderModule(vector<unsigned int> code)
VkShaderModule Device::CreateShaderModule(vector<uint32_t> code)
{
VkShaderModuleCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
// 这里需要确保数据满足uint32_t的对齐要求,存储在vector中默认分配器已经确保数据满足最差情况下的对齐要求
createInfo.codeSize = code.size();
//code size 是字节大小,需要 * sizeof
createInfo.codeSize = code.size() * sizeof(uint32_t);
// 转换为Vulkan要求的uint32_t指针
createInfo.pCode = reinterpret_cast<const uint32_t*>(code.data());
VkShaderModule module;

View File

@ -25,6 +25,6 @@ namespace vulkanapi {
VkFence CreateFence();
VkSemaphore CreateSemaphore();
VkShaderModule CreateShaderModule(vector<char> code);
VkShaderModule CreateShaderModule(vector<unsigned int> code);
VkShaderModule CreateShaderModule(vector<uint32_t> code);
};
};