This commit is contained in:
ouczbs 2024-11-02 17:55:55 +08:00
parent fe8a28c8b0
commit 622a0936b1
15 changed files with 247 additions and 28 deletions

View File

@ -1 +1 @@
add_requires("spdlog", "lemon", "libsdl", "vulkansdk","shaderc") add_requires("spdlog", "lemon", "libsdl", "vulkansdk","shaderc","spirv","spirv-cross")

View File

@ -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 颜色
} }

View File

@ -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()

View File

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

View File

@ -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*;

View File

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

View File

@ -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})

View File

@ -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>

View File

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

View File

@ -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;
}; };
} }

View File

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

View File

@ -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() {

View File

@ -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();
}
} }
} }

View File

@ -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)
{ {

View File

@ -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;
}
} }