git push
This commit is contained in:
parent
fe8a28c8b0
commit
622a0936b1
2
engine/3rdparty/xmake.lua
vendored
2
engine/3rdparty/xmake.lua
vendored
@ -1 +1 @@
|
|||||||
add_requires("spdlog", "lemon", "libsdl", "vulkansdk","shaderc")
|
add_requires("spdlog", "lemon", "libsdl", "vulkansdk","shaderc","spirv","spirv-cross")
|
||||||
@ -1,10 +1,13 @@
|
|||||||
#version 450
|
#version 450
|
||||||
layout (location = 0) in vec3 iPos;
|
layout (location = 0) in vec3 iPos;
|
||||||
|
|
||||||
|
layout(set = 0, binding = 0) uniform ColorData {
|
||||||
|
vec4 uColor; // 从 uniform buffer 获取颜色
|
||||||
|
};
|
||||||
layout (location = 0) out vec4 vColor;
|
layout (location = 0) out vec4 vColor;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
gl_Position = vec4(iPos.x, iPos.y, iPos.z, 1.0);
|
gl_Position = vec4(iPos, 1.0);
|
||||||
vColor = vec4(1.0, 0.0, 0.0, 1.0);
|
vColor = uColor; // 使用 uniform 颜色
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,16 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "asset/asset.h"
|
#include "asset/asset.h"
|
||||||
|
#include "render/type.h"
|
||||||
namespace api {
|
namespace api {
|
||||||
class ShaderProgram : public Resource<ShaderProgram> {};
|
class ShaderProgram : public Resource<ShaderProgram> {
|
||||||
|
protected:
|
||||||
|
ShaderStage mStage;
|
||||||
|
public:
|
||||||
|
ShaderProgram(ShaderStage stage) : mStage(stage) {};
|
||||||
|
ShaderStage GetStage() {
|
||||||
|
return mStage;
|
||||||
|
}
|
||||||
|
};
|
||||||
class Shader : public Asset {
|
class Shader : public Asset {
|
||||||
private:
|
private:
|
||||||
UPROPERTY()
|
UPROPERTY()
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "pmr/name.h"
|
#include "pmr/name.h"
|
||||||
|
#include "render/asset/shader.h"
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <shaderc/shaderc.h>
|
#include <shaderc/shaderc.h>
|
||||||
namespace api
|
namespace api
|
||||||
@ -11,6 +12,9 @@ namespace api
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static shaderc_shader_kind GetShaderKind(Name name);
|
static shaderc_shader_kind GetShaderKind(Name name);
|
||||||
|
static ShaderStage GetShaderStage(shaderc_shader_kind kind);
|
||||||
static optional<pmr::vector<uint32_t>> ToSpirv(const pmr::string& glsl, shaderc_shader_kind kind, string_view code_id = "unknown_shader");
|
static optional<pmr::vector<uint32_t>> ToSpirv(const pmr::string& glsl, shaderc_shader_kind kind, string_view code_id = "unknown_shader");
|
||||||
|
static void LoadShaderLayout(ShaderProgram* program, const pmr::vector<uint32_t>& spirv);
|
||||||
|
static void GetShaderLayout(ShaderDescriptorSet& descriptorSet, pmr::vector<ShaderProgram*>& programList);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -65,6 +65,23 @@ namespace api {
|
|||||||
TEX_3D = 0x04,
|
TEX_3D = 0x04,
|
||||||
TEX_CUBE = 0x08,
|
TEX_CUBE = 0x08,
|
||||||
};
|
};
|
||||||
|
enum class ShaderDescriptorType : uint8_t{
|
||||||
|
UNIFORM_BUFFER,
|
||||||
|
SAMPLER,
|
||||||
|
};
|
||||||
|
enum class ShaderStage : uint32_t {
|
||||||
|
NONE = 0,
|
||||||
|
VERTEX = 0x1,
|
||||||
|
FRAGMENT = 0x2,
|
||||||
|
};
|
||||||
|
struct ShaderDescriptorLayout {
|
||||||
|
uint32_t set : 8;
|
||||||
|
uint32_t binding : 8;
|
||||||
|
uint32_t size : 16;
|
||||||
|
ShaderDescriptorType type;
|
||||||
|
ShaderStage stageFlags;
|
||||||
|
};
|
||||||
|
using ShaderDescriptorSet = pmr::vector<ShaderDescriptorLayout>;
|
||||||
using ImagePtr = void*;
|
using ImagePtr = void*;
|
||||||
using ImageViewPtr = void*;
|
using ImageViewPtr = void*;
|
||||||
using BufferPtr = void*;
|
using BufferPtr = void*;
|
||||||
|
|||||||
@ -1,8 +1,12 @@
|
|||||||
#include "render/tool/glsl_to_spirv.h"
|
#include "render/tool/glsl_to_spirv.h"
|
||||||
#include <shaderc/shaderc.hpp>
|
#include "render/type.h"
|
||||||
#include "zlog.h"
|
#include "zlog.h"
|
||||||
|
#include "meta/enum.h"
|
||||||
|
#include <shaderc/shaderc.hpp>
|
||||||
|
#include <spirv_cross/spirv_reflect.hpp>
|
||||||
namespace api
|
namespace api
|
||||||
{
|
{
|
||||||
|
static pmr::table<Guid, ShaderDescriptorSet> ShaderLayoutTable;
|
||||||
optional<pmr::vector<uint32_t>> GlslToSpirv::ToSpirv(const pmr::string& glsl, shaderc_shader_kind kind, string_view code_id)
|
optional<pmr::vector<uint32_t>> GlslToSpirv::ToSpirv(const pmr::string& glsl, shaderc_shader_kind kind, string_view code_id)
|
||||||
{
|
{
|
||||||
optional<pmr::vector<uint32_t>> spirv_out{FramePool()};
|
optional<pmr::vector<uint32_t>> spirv_out{FramePool()};
|
||||||
@ -34,5 +38,78 @@ namespace api
|
|||||||
default: return shaderc_shader_kind::shaderc_miss_shader;
|
default: return shaderc_shader_kind::shaderc_miss_shader;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ShaderStage GlslToSpirv::GetShaderStage(shaderc_shader_kind kind)
|
||||||
|
{
|
||||||
|
switch (kind)
|
||||||
|
{
|
||||||
|
case shaderc_shader_kind::shaderc_vertex_shader:
|
||||||
|
return ShaderStage::VERTEX;
|
||||||
|
case shaderc_shader_kind::shaderc_fragment_shader:
|
||||||
|
return ShaderStage::FRAGMENT;
|
||||||
|
default:
|
||||||
|
return ShaderStage::NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void GlslToSpirv::LoadShaderLayout(ShaderProgram* program, const pmr::vector<uint32_t>& spirv) {
|
||||||
|
ShaderStage stage = program->GetStage();
|
||||||
|
spirv_cross::Compiler compiler(spirv.data(), spirv.size());
|
||||||
|
auto resources = compiler.get_shader_resources();
|
||||||
|
ShaderDescriptorSet descriptorSet;
|
||||||
|
// 遍历 uniform buffers (UBO)
|
||||||
|
for (auto& res : resources.uniform_buffers)
|
||||||
|
{
|
||||||
|
ShaderDescriptorLayout layout{};
|
||||||
|
layout.set = compiler.get_decoration(res.id, spv::Decoration::DecorationDescriptorSet);
|
||||||
|
layout.binding = compiler.get_decoration(res.id, spv::Decoration::DecorationBinding);
|
||||||
|
auto type = compiler.get_type(res.type_id);
|
||||||
|
uint32_t size = type.width;
|
||||||
|
uint32_t i = 0;
|
||||||
|
for (auto& member_type : type.member_types)
|
||||||
|
{
|
||||||
|
auto tmp = compiler.get_type(member_type);
|
||||||
|
size += (uint32_t)(compiler.get_declared_struct_member_size(type, i++));
|
||||||
|
}
|
||||||
|
layout.size = size;
|
||||||
|
layout.stageFlags = stage;
|
||||||
|
layout.type = ShaderDescriptorType::UNIFORM_BUFFER;
|
||||||
|
descriptorSet.push_back(layout);
|
||||||
|
}
|
||||||
|
// 遍历 sampled images (采样器/纹理)
|
||||||
|
for (const auto& res : resources.sampled_images) {
|
||||||
|
ShaderDescriptorLayout layout{};
|
||||||
|
layout.set = compiler.get_decoration(res.id, spv::Decoration::DecorationDescriptorSet);
|
||||||
|
layout.binding = compiler.get_decoration(res.id, spv::Decoration::DecorationBinding);
|
||||||
|
layout.size = 0;
|
||||||
|
layout.stageFlags = stage;
|
||||||
|
layout.type = ShaderDescriptorType::SAMPLER;
|
||||||
|
descriptorSet.push_back(layout);
|
||||||
|
}
|
||||||
|
ShaderLayoutTable.emplace(program->GetGuid(), descriptorSet);
|
||||||
|
}
|
||||||
|
void GlslToSpirv::GetShaderLayout(ShaderDescriptorSet& descriptorSet, pmr::vector<ShaderProgram*>& programList)
|
||||||
|
{
|
||||||
|
table<uint32_t, uint32_t> idTable{ FramePool() };
|
||||||
|
for (auto program : programList) {
|
||||||
|
auto& itSet = ShaderLayoutTable[program->GetGuid()];
|
||||||
|
for (ShaderDescriptorLayout& layout : itSet) {
|
||||||
|
uint32_t id = (layout.set << 8) + layout.binding;
|
||||||
|
auto itId = idTable.find(id);
|
||||||
|
if (itId == idTable.end()) {
|
||||||
|
descriptorSet.emplace_back(layout);
|
||||||
|
idTable[id] = descriptorSet.size() - 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
using ::operator|=;
|
||||||
|
ShaderDescriptorLayout& desc = descriptorSet[itId->second];
|
||||||
|
desc.stageFlags |= layout.stageFlags;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::sort(descriptorSet.begin(), descriptorSet.end(), [](auto& k1, auto& k2) {
|
||||||
|
if (k1.set != k2.set) {
|
||||||
|
return k1.set < k2.set;
|
||||||
|
}
|
||||||
|
return k1.binding < k2.binding;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,4 +7,4 @@ static_component("render","engine")
|
|||||||
add_files("src/**.cpp")
|
add_files("src/**.cpp")
|
||||||
add_deps("asset", "zlib", "core")
|
add_deps("asset", "zlib", "core")
|
||||||
add_syslinks("user32", {public = true})
|
add_syslinks("user32", {public = true})
|
||||||
add_packages("lemon", "libsdl","shaderc", {public = true})
|
add_packages("lemon", "libsdl","shaderc","spirv-cross", {public = true})
|
||||||
@ -1,12 +1,15 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include <type_traits>
|
||||||
namespace meta {
|
namespace meta {
|
||||||
template<typename Enum>
|
template<typename Enum>
|
||||||
concept is_enum_t = requires { std::is_enum_v<Enum>; };
|
concept is_enum_t = std::is_enum_v<Enum>;
|
||||||
}
|
}
|
||||||
|
template<typename Enum>
|
||||||
|
concept is_enum_t = std::is_enum_v<Enum>;
|
||||||
template<meta::is_enum_t Enum>
|
template<meta::is_enum_t Enum>
|
||||||
inline constexpr Enum operator|=(Enum& lhs, Enum rhs) noexcept {
|
inline constexpr Enum& operator|=(Enum& lhs, Enum rhs) noexcept {
|
||||||
using underlying = std::underlying_type_t<Enum>;
|
using underlying = std::underlying_type_t<Enum>;
|
||||||
lhs = Enum(underlying(lhs) | underlying(rhs));
|
lhs = static_cast<Enum>(static_cast<underlying>(lhs) | static_cast<underlying>(rhs));
|
||||||
return lhs;
|
return lhs;
|
||||||
}
|
}
|
||||||
template<meta::is_enum_t Enum>
|
template<meta::is_enum_t Enum>
|
||||||
|
|||||||
@ -3,14 +3,17 @@
|
|||||||
#include "asset/resource_system.h"
|
#include "asset/resource_system.h"
|
||||||
#include "vkn/vulkan_api.h"
|
#include "vkn/vulkan_api.h"
|
||||||
namespace vkn {
|
namespace vkn {
|
||||||
|
using api::ShaderDescriptorSet;
|
||||||
class vkShaderProgram : public api::ShaderProgram {
|
class vkShaderProgram : public api::ShaderProgram {
|
||||||
private:
|
private:
|
||||||
VkShaderModule mPtr;
|
VkShaderModule mPtr;
|
||||||
public:
|
public:
|
||||||
|
using api::ShaderProgram::ShaderProgram;
|
||||||
VkShaderModule Ptr() {
|
VkShaderModule Ptr() {
|
||||||
return mPtr;
|
return mPtr;
|
||||||
}
|
}
|
||||||
void Load(const pmr::vector<uint32_t>& spirv);
|
void Load(const pmr::vector<uint32_t>& spirv);
|
||||||
|
VkShaderStageFlagBits GetVkStage();
|
||||||
};
|
};
|
||||||
class VulkanGlslLoader : public api::IFileLoader
|
class VulkanGlslLoader : public api::IFileLoader
|
||||||
{
|
{
|
||||||
@ -18,5 +21,6 @@ namespace vkn {
|
|||||||
public:
|
public:
|
||||||
static void Init();
|
static void Init();
|
||||||
api::ResourceBundle LoadFile(api::PackagePath handle, const api::MetaBundle& meta) override;
|
api::ResourceBundle LoadFile(api::PackagePath handle, const api::MetaBundle& meta) override;
|
||||||
|
static uint32_t GetShaderLayout(VkDescriptorSetLayoutList& layoutList, pmr::vector<api::ShaderProgram*>& programList);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -29,6 +29,9 @@ namespace vkn {
|
|||||||
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;
|
constexpr uint32_t MAX_BUFFER_BIND_NUM = 16;
|
||||||
|
constexpr uint32_t MAX_SHADER_DESCRIPTOR_SET_COUNT = 3;
|
||||||
|
using VkDescriptorSetLayoutList = VkDescriptorSetLayout[MAX_SHADER_DESCRIPTOR_SET_COUNT];
|
||||||
|
using VkDescriptorSetList = VkDescriptorSet[MAX_SHADER_DESCRIPTOR_SET_COUNT];
|
||||||
struct MeshVAO
|
struct MeshVAO
|
||||||
{
|
{
|
||||||
uint32_t indexCount = 0; // 索引数量
|
uint32_t indexCount = 0; // 索引数量
|
||||||
@ -96,10 +99,10 @@ namespace vkn {
|
|||||||
{
|
{
|
||||||
Name name; // For debug
|
Name name; // For debug
|
||||||
VkPipeline pipeline = VK_NULL_HANDLE;
|
VkPipeline pipeline = VK_NULL_HANDLE;
|
||||||
VkDescriptorSet descriptorSet = VK_NULL_HANDLE;
|
|
||||||
VkPipelineLayout pipelineLayout = VK_NULL_HANDLE;
|
VkPipelineLayout pipelineLayout = VK_NULL_HANDLE;
|
||||||
VkDescriptorSetLayout descriptorSetLayout = VK_NULL_HANDLE;
|
VkDescriptorSetList descList{};
|
||||||
VkDescriptorSetLayout sceneDescriptorSetLayout = VK_NULL_HANDLE; // For ray tracing
|
VkDescriptorSetLayoutList descLayoutList{};
|
||||||
|
uint32_t descCount = 0;
|
||||||
bool inUse = false;
|
bool inUse = false;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,8 @@
|
|||||||
namespace vkn {
|
namespace vkn {
|
||||||
using api::ResourceState;
|
using api::ResourceState;
|
||||||
using api::TextureBarrier;
|
using api::TextureBarrier;
|
||||||
|
using api::ShaderDescriptorType;
|
||||||
|
using api::ShaderStage;
|
||||||
struct VkTextureTransitionDesc {
|
struct VkTextureTransitionDesc {
|
||||||
VkAccessFlags srcAccessMask;
|
VkAccessFlags srcAccessMask;
|
||||||
VkAccessFlags dstAccessMask;
|
VkAccessFlags dstAccessMask;
|
||||||
@ -20,4 +22,6 @@ namespace vkn {
|
|||||||
VkImageCreateFlags vkApiGetImageCreateFlag(TextureDimension dimension, uint32_t arraySize);
|
VkImageCreateFlags vkApiGetImageCreateFlag(TextureDimension dimension, uint32_t arraySize);
|
||||||
VkSampleCountFlagBits vkApiGetSmpleCountFlag(SampleCount sample);
|
VkSampleCountFlagBits vkApiGetSmpleCountFlag(SampleCount sample);
|
||||||
|
|
||||||
|
VkDescriptorType vkApiGetDescriptorType(ShaderDescriptorType type);
|
||||||
|
VkShaderStageFlags vkApiGetShaderStageFlags(ShaderStage stage);
|
||||||
}
|
}
|
||||||
@ -11,6 +11,9 @@ namespace vkn {
|
|||||||
public:
|
public:
|
||||||
DescriptorPool(Device& device, pmr::vector<VkDescriptorPoolSize>& pPoolSizes,uint32_t maxSets);
|
DescriptorPool(Device& device, pmr::vector<VkDescriptorPoolSize>& pPoolSizes,uint32_t maxSets);
|
||||||
|
|
||||||
|
VkDescriptorPool Ptr() {
|
||||||
|
return mPtr;
|
||||||
|
}
|
||||||
VkDescriptorSet Allocate(VkDescriptorSetLayout& descriptorSetLayout);
|
VkDescriptorSet Allocate(VkDescriptorSetLayout& descriptorSetLayout);
|
||||||
public:
|
public:
|
||||||
static pmr::vector<VkDescriptorPoolSize> DefaultDescriptorPoolSize() {
|
static pmr::vector<VkDescriptorPoolSize> DefaultDescriptorPoolSize() {
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
#include "vkn/loader/vulkan_glsl_loader.h"
|
#include "vkn/loader/vulkan_glsl_loader.h"
|
||||||
#include "vkn/vulkan_api.h"
|
#include "vkn/vulkan_api.h"
|
||||||
#include "vkn/wrapper/device.h"
|
#include "vkn/wrapper/device.h"
|
||||||
|
#include "vkn/vulkan_api_help.h"
|
||||||
#include "render/tool/glsl_to_spirv.h"
|
#include "render/tool/glsl_to_spirv.h"
|
||||||
#include "render/asset/vertex.h"
|
#include "render/asset/vertex.h"
|
||||||
#include "os/file_handle.h"
|
#include "os/file_handle.h"
|
||||||
@ -19,8 +20,10 @@ namespace vkn {
|
|||||||
ResourceBundle VulkanGlslLoader::LoadFile(PackagePath path, const MetaBundle& meta)
|
ResourceBundle VulkanGlslLoader::LoadFile(PackagePath path, const MetaBundle& meta)
|
||||||
{
|
{
|
||||||
auto m = meta.FetchMeta<ShaderProgram>();
|
auto m = meta.FetchMeta<ShaderProgram>();
|
||||||
auto program = m ? ResourceSystem::Ptr()->LoadEmplaceResource<vkShaderProgram>(m->guid)
|
auto shader_kind = GlslToSpirv::GetShaderKind(path.GetExtension().ToStringView());
|
||||||
: ResourceSystem::Ptr()->LoadEmplaceResource<vkShaderProgram>();
|
auto shader_stage = GlslToSpirv::GetShaderStage(shader_kind);
|
||||||
|
auto program = m ? ResourceSystem::Ptr()->LoadEmplaceResource<vkShaderProgram>(m->guid, shader_stage)
|
||||||
|
: ResourceSystem::Ptr()->LoadEmplaceResource<vkShaderProgram>(shader_stage);
|
||||||
FileHandle handle(path);
|
FileHandle handle(path);
|
||||||
if (!handle.Open(FILE_OP::READ, mFileFlag & FileFlag::File_Binary)) {
|
if (!handle.Open(FILE_OP::READ, mFileFlag & FileFlag::File_Binary)) {
|
||||||
return program;
|
return program;
|
||||||
@ -34,7 +37,6 @@ namespace vkn {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
pmr::string glsl = handle.ReadAll<pmr::string>();
|
pmr::string glsl = handle.ReadAll<pmr::string>();
|
||||||
auto shader_kind = GlslToSpirv::GetShaderKind(path.GetExtension().ToStringView());
|
|
||||||
auto spirv = GlslToSpirv::ToSpirv(glsl, shader_kind, path.GetFileName());
|
auto spirv = GlslToSpirv::ToSpirv(glsl, shader_kind, path.GetFileName());
|
||||||
if (spirv) {
|
if (spirv) {
|
||||||
program->Load(*spirv);
|
program->Load(*spirv);
|
||||||
@ -43,10 +45,67 @@ namespace vkn {
|
|||||||
}
|
}
|
||||||
return program;
|
return program;
|
||||||
}
|
}
|
||||||
|
VkDescriptorSetLayout CreateShaderLayout(std::span<ShaderDescriptorLayout> descList, pmr::vector<VkDescriptorSetLayoutBinding>& bindingList) {
|
||||||
|
VkDescriptorSetLayout layout;
|
||||||
|
bindingList.resize(descList.size());
|
||||||
|
uint32_t i = 0;
|
||||||
|
for (auto& desc : descList) {
|
||||||
|
VkDescriptorSetLayoutBinding binding = {};
|
||||||
|
binding.binding = desc.binding;
|
||||||
|
binding.descriptorType = vkApiGetDescriptorType(desc.type);
|
||||||
|
binding.descriptorCount = 1;
|
||||||
|
binding.stageFlags = vkApiGetShaderStageFlags(desc.stageFlags);
|
||||||
|
bindingList[i++] = binding;
|
||||||
|
}
|
||||||
|
VkDescriptorSetLayoutCreateInfo layoutInfo = {};
|
||||||
|
layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
|
||||||
|
layoutInfo.pBindings = bindingList.data();
|
||||||
|
layoutInfo.bindingCount = static_cast<uint32_t>(bindingList.size());
|
||||||
|
vkCreateDescriptorSetLayout(VulkanAPI::Ptr()->GetBackend().GetDevice().Ptr(), &layoutInfo, nullptr, &layout);
|
||||||
|
return layout;
|
||||||
|
}
|
||||||
|
uint32_t VulkanGlslLoader::GetShaderLayout(VkDescriptorSetLayoutList& layoutList, pmr::vector<api::ShaderProgram*>& programList)
|
||||||
|
{
|
||||||
|
ShaderDescriptorSet descList{FramePool()};
|
||||||
|
GlslToSpirv::GetShaderLayout(descList, programList);
|
||||||
|
if (descList.empty()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
descList.push_back(ShaderDescriptorLayout{.set = 0xff});
|
||||||
|
pmr::vector<VkDescriptorSetLayoutBinding> bindingList{FramePool()};
|
||||||
|
uint32_t set = 0, binding = 0, count = 0;
|
||||||
|
for (auto it = descList.begin(), itEnd = descList.end(); it != itEnd; it++) {
|
||||||
|
if (set == it->set) {
|
||||||
|
binding++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (binding > 0) {
|
||||||
|
assert(count < MAX_SHADER_DESCRIPTOR_SET_COUNT);
|
||||||
|
std::span<ShaderDescriptorLayout> spanList{ it - binding, binding };
|
||||||
|
layoutList[count++] = CreateShaderLayout(spanList, bindingList);
|
||||||
|
}
|
||||||
|
set = it->set;
|
||||||
|
binding = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
void vkShaderProgram::Load(const pmr::vector<uint32_t>& spirv)
|
void vkShaderProgram::Load(const pmr::vector<uint32_t>& spirv)
|
||||||
{
|
{
|
||||||
VulkanAPI* API = VulkanAPI::Ptr();
|
VulkanAPI* API = VulkanAPI::Ptr();
|
||||||
mPtr = API->GetBackend().GetDevice().CreateShaderModule(spirv);
|
mPtr = API->GetBackend().GetDevice().CreateShaderModule(spirv);
|
||||||
|
GlslToSpirv::LoadShaderLayout(this, spirv);
|
||||||
|
}
|
||||||
|
VkShaderStageFlagBits vkShaderProgram::GetVkStage()
|
||||||
|
{
|
||||||
|
switch (mStage) {
|
||||||
|
case ShaderStage::VERTEX:
|
||||||
|
return VK_SHADER_STAGE_VERTEX_BIT;
|
||||||
|
case ShaderStage::FRAGMENT:
|
||||||
|
return VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||||
|
default:
|
||||||
|
return VkShaderStageFlagBits();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -72,8 +72,8 @@ namespace vkn {
|
|||||||
vkCmdBindVertexBuffers(ptr, 0, 1, vertexBuffers, offsets);
|
vkCmdBindVertexBuffers(ptr, 0, 1, vertexBuffers, offsets);
|
||||||
vkCmdBindIndexBuffer(ptr, vulkanVAO.indexBuffer, 0, VK_INDEX_TYPE_UINT32);
|
vkCmdBindIndexBuffer(ptr, vulkanVAO.indexBuffer, 0, VK_INDEX_TYPE_UINT32);
|
||||||
vkCmdBindPipeline(ptr, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.pipeline);
|
vkCmdBindPipeline(ptr, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.pipeline);
|
||||||
if(pipeline.descriptorSet)
|
if(pipeline.descCount > 0)
|
||||||
vkCmdBindDescriptorSets(ptr, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.pipelineLayout, 0, 1, &pipeline.descriptorSet, 0, VK_NULL_HANDLE);
|
vkCmdBindDescriptorSets(ptr, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.pipelineLayout, 0, pipeline.descCount, pipeline.descList, 0, VK_NULL_HANDLE);
|
||||||
vkCmdDrawIndexed(ptr, vulkanVAO.indexCount, 1, 0, 0, 0);
|
vkCmdDrawIndexed(ptr, vulkanVAO.indexCount, 1, 0, 0, 0);
|
||||||
}
|
}
|
||||||
void VulkanAPI::LoadShader(Shader& shader, size_t passKey)
|
void VulkanAPI::LoadShader(Shader& shader, size_t passKey)
|
||||||
@ -86,10 +86,14 @@ namespace vkn {
|
|||||||
pmr::vector<VkPipelineShaderStageCreateInfo> shaderStages;
|
pmr::vector<VkPipelineShaderStageCreateInfo> shaderStages;
|
||||||
std::map<VkShaderStageFlagBits, VkShaderModule> shaderModules;
|
std::map<VkShaderStageFlagBits, VkShaderModule> shaderModules;
|
||||||
auto& device = backend.GetDevice();
|
auto& device = backend.GetDevice();
|
||||||
auto vertModule = shader.GetVertHandle<vkShaderProgram>()->Ptr();
|
pmr::vector<api::ShaderProgram*> programList;
|
||||||
shaderModules.insert(std::make_pair(VK_SHADER_STAGE_VERTEX_BIT, vertModule));
|
programList.push_back(shader.GetVertHandle().Ptr());
|
||||||
auto fragModule = shader.GetFragHandle<vkShaderProgram>()->Ptr();
|
programList.push_back(shader.GetFragHandle().Ptr());
|
||||||
shaderModules.insert(std::make_pair(VK_SHADER_STAGE_FRAGMENT_BIT, fragModule));
|
for (auto program : programList) {
|
||||||
|
vkShaderProgram* vkProgram = (vkShaderProgram*)program;
|
||||||
|
auto shaderModule = vkProgram->Ptr();
|
||||||
|
shaderModules.insert(std::make_pair(vkProgram->GetVkStage(), shaderModule));
|
||||||
|
}
|
||||||
for (auto& shaderModule : shaderModules)
|
for (auto& shaderModule : shaderModules)
|
||||||
{
|
{
|
||||||
VkPipelineShaderStageCreateInfo shaderStageInfo = {};
|
VkPipelineShaderStageCreateInfo shaderStageInfo = {};
|
||||||
@ -205,11 +209,21 @@ namespace vkn {
|
|||||||
depthStencilInfo.stencilTestEnable = VK_FALSE;
|
depthStencilInfo.stencilTestEnable = VK_FALSE;
|
||||||
depthStencilInfo.front = {};
|
depthStencilInfo.front = {};
|
||||||
depthStencilInfo.back = {};
|
depthStencilInfo.back = {};
|
||||||
VkDescriptorSetLayout descriptorSetLayout{};
|
|
||||||
|
VulkanPipeline& vulkan_pipeline = PipelineTable[shader.GetGuid()];
|
||||||
|
vulkan_pipeline.descCount = VulkanGlslLoader::GetShaderLayout(vulkan_pipeline.descLayoutList, programList);
|
||||||
|
VkDescriptorSet descriptorSet;
|
||||||
|
VkDescriptorSetAllocateInfo allocInfo{};
|
||||||
|
allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
|
||||||
|
allocInfo.descriptorPool = backend.GetPool().Ptr();
|
||||||
|
allocInfo.descriptorSetCount = vulkan_pipeline.descCount;
|
||||||
|
allocInfo.pSetLayouts = vulkan_pipeline.descLayoutList;
|
||||||
|
vkAllocateDescriptorSets(device.Ptr(), &allocInfo, vulkan_pipeline.descList);
|
||||||
|
|
||||||
VkPipelineLayoutCreateInfo pipelineLayoutInfo = {};
|
VkPipelineLayoutCreateInfo pipelineLayoutInfo = {};
|
||||||
pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
||||||
pipelineLayoutInfo.setLayoutCount = 0; // 没有描述符集布局时可以设置为0
|
pipelineLayoutInfo.setLayoutCount = vulkan_pipeline.descCount;
|
||||||
pipelineLayoutInfo.pSetLayouts = nullptr;
|
pipelineLayoutInfo.pSetLayouts = vulkan_pipeline.descLayoutList;
|
||||||
VkPipelineLayout pipelineLayout;
|
VkPipelineLayout pipelineLayout;
|
||||||
if (vkCreatePipelineLayout(device.Ptr(), &pipelineLayoutInfo, nullptr, &pipelineLayout) != VK_SUCCESS)
|
if (vkCreatePipelineLayout(device.Ptr(), &pipelineLayoutInfo, nullptr, &pipelineLayout) != VK_SUCCESS)
|
||||||
throw std::runtime_error("failed to create pipeline layout!");
|
throw std::runtime_error("failed to create pipeline layout!");
|
||||||
@ -239,13 +253,10 @@ namespace vkn {
|
|||||||
for (auto& shaderModule : shaderModules)
|
for (auto& shaderModule : shaderModules)
|
||||||
vkDestroyShaderModule(device.Ptr(), shaderModule.second, nullptr);
|
vkDestroyShaderModule(device.Ptr(), shaderModule.second, nullptr);
|
||||||
|
|
||||||
VulkanPipeline& vulkan_pipeline = PipelineTable[shader.GetGuid()];
|
|
||||||
vulkan_pipeline.name = shader.Name();
|
vulkan_pipeline.name = shader.Name();
|
||||||
vulkan_pipeline.pipeline = pipeLine;
|
vulkan_pipeline.pipeline = pipeLine;
|
||||||
vulkan_pipeline.inUse = true;
|
vulkan_pipeline.inUse = true;
|
||||||
vulkan_pipeline.pipelineLayout = pipelineLayout;
|
vulkan_pipeline.pipelineLayout = pipelineLayout;
|
||||||
vulkan_pipeline.descriptorSetLayout = descriptorSetLayout;
|
|
||||||
vulkan_pipeline.descriptorSet = descriptorSetLayout ? backend.GetPool().Allocate(descriptorSetLayout) : nullptr;
|
|
||||||
}
|
}
|
||||||
ImagePtr VulkanAPI::CreateTexture(TextureDesc desc)
|
ImagePtr VulkanAPI::CreateTexture(TextureDesc desc)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -233,4 +233,26 @@ namespace vkn {
|
|||||||
{
|
{
|
||||||
return (VkSampleCountFlagBits)sample;
|
return (VkSampleCountFlagBits)sample;
|
||||||
}
|
}
|
||||||
|
VkDescriptorType vkApiGetDescriptorType(ShaderDescriptorType type)
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
case ShaderDescriptorType::SAMPLER:
|
||||||
|
return VK_DESCRIPTOR_TYPE_SAMPLER;
|
||||||
|
case ShaderDescriptorType::UNIFORM_BUFFER:
|
||||||
|
return VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||||
|
default:
|
||||||
|
return VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
VkShaderStageFlags vkApiGetShaderStageFlags(ShaderStage stage)
|
||||||
|
{
|
||||||
|
VkShaderStageFlags flags{};
|
||||||
|
if (any(stage & ShaderStage::FRAGMENT)) {
|
||||||
|
flags |= VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||||
|
}
|
||||||
|
if (any(stage & ShaderStage::VERTEX)) {
|
||||||
|
flags |= VK_SHADER_STAGE_VERTEX_BIT;
|
||||||
|
}
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user