Basic shader compilation
This commit is contained in:
@@ -22,16 +22,6 @@ namespace Seele
|
||||
{
|
||||
namespace Vulkan
|
||||
{
|
||||
|
||||
enum class ShaderType
|
||||
{
|
||||
VERTEX = 0,
|
||||
FRAGMENT = 1,
|
||||
COMPUTE = 2,
|
||||
TASK = 3,
|
||||
MESH = 4,
|
||||
};
|
||||
|
||||
VkDescriptorType cast(const Gfx::SeDescriptorType &descriptorType);
|
||||
Gfx::SeDescriptorType cast(const VkDescriptorType &descriptorType);
|
||||
VkShaderStageFlagBits cast(const Gfx::SeShaderStageFlagBits &stage);
|
||||
|
||||
@@ -8,9 +8,8 @@
|
||||
using namespace Seele;
|
||||
using namespace Seele::Vulkan;
|
||||
|
||||
Shader::Shader(PGraphics graphics, ShaderType shaderType, VkShaderStageFlags stage)
|
||||
Shader::Shader(PGraphics graphics, VkShaderStageFlags stage)
|
||||
: graphics(graphics)
|
||||
, type(shaderType)
|
||||
, stage(stage)
|
||||
{
|
||||
}
|
||||
@@ -28,91 +27,8 @@ uint32 Seele::Vulkan::Shader::getShaderHash() const
|
||||
return hash;
|
||||
}
|
||||
|
||||
#define CHECK_RESULT(x) {SlangResult r = x; if(r != 0) {throw std::runtime_error(fmt::format("Error: {0}", r));}}
|
||||
#define CHECK_DIAGNOSTICS() {if(diagnostics) {std::cout << (const char*)diagnostics->getBufferPointer() << std::endl; assert(false);}}
|
||||
|
||||
void Shader::create(const ShaderCreateInfo& createInfo)
|
||||
{
|
||||
entryPointName = createInfo.entryPoint;
|
||||
thread_local Slang::ComPtr<slang::IGlobalSession> globalSession;
|
||||
if(!globalSession)
|
||||
{
|
||||
slang::createGlobalSession(globalSession.writeRef());
|
||||
}
|
||||
slang::SessionDesc sessionDesc;
|
||||
sessionDesc.flags = 0;
|
||||
sessionDesc.defaultMatrixLayoutMode = SLANG_MATRIX_LAYOUT_COLUMN_MAJOR;
|
||||
Array<slang::PreprocessorMacroDesc> macros;
|
||||
for(const auto& [key, val] : createInfo.defines)
|
||||
{
|
||||
macros.add(slang::PreprocessorMacroDesc{
|
||||
.name = key,
|
||||
.value = val,
|
||||
});
|
||||
}
|
||||
sessionDesc.preprocessorMacroCount = macros.size();
|
||||
sessionDesc.preprocessorMacros = macros.data();
|
||||
slang::TargetDesc vulkan;
|
||||
vulkan.profile = globalSession->findProfile("sm_6_6");
|
||||
vulkan.format = SLANG_SPIRV;
|
||||
sessionDesc.targetCount = 1;
|
||||
sessionDesc.targets = &vulkan;
|
||||
StaticArray<const char*, 3> searchPaths = {"shaders/", "shaders/lib/", "shaders/generated/"};
|
||||
sessionDesc.searchPaths = searchPaths.data();
|
||||
sessionDesc.searchPathCount = searchPaths.size();
|
||||
|
||||
Slang::ComPtr<slang::ISession> session;
|
||||
CHECK_RESULT(globalSession->createSession(sessionDesc, session.writeRef()));
|
||||
Slang::ComPtr<slang::IBlob> diagnostics;
|
||||
Array<slang::IComponentType*> modules;
|
||||
Slang::ComPtr<slang::IEntryPoint> entrypoint;
|
||||
slang::IModule* mainModule = nullptr;
|
||||
for (const auto& moduleName : createInfo.additionalModules)
|
||||
{
|
||||
modules.add(session->loadModule(moduleName.c_str(), diagnostics.writeRef()));
|
||||
if (moduleName == createInfo.mainModule)
|
||||
{
|
||||
mainModule = (slang::IModule*)modules.back();
|
||||
}
|
||||
CHECK_DIAGNOSTICS();
|
||||
}
|
||||
|
||||
CHECK_DIAGNOSTICS();
|
||||
|
||||
mainModule->findEntryPointByName(createInfo.entryPoint.c_str(), entrypoint.writeRef());
|
||||
modules.add(entrypoint);
|
||||
|
||||
Slang::ComPtr<slang::IComponentType> moduleComposition;
|
||||
session->createCompositeComponentType(modules.data(), modules.size(), moduleComposition.writeRef(), diagnostics.writeRef());
|
||||
|
||||
CHECK_DIAGNOSTICS();
|
||||
|
||||
Slang::ComPtr<slang::IComponentType> linkedProgram;
|
||||
moduleComposition->link(linkedProgram.writeRef(), diagnostics.writeRef());
|
||||
|
||||
CHECK_DIAGNOSTICS();
|
||||
|
||||
slang::ProgramLayout* reflection = linkedProgram->getLayout(0, diagnostics.writeRef());
|
||||
|
||||
CHECK_DIAGNOSTICS();
|
||||
|
||||
Array<slang::SpecializationArg> specialization;
|
||||
for(const auto& [key, value] : createInfo.typeParameter)
|
||||
{
|
||||
specialization.add(slang::SpecializationArg::fromType(reflection->findTypeByName(value)));
|
||||
}
|
||||
Slang::ComPtr<slang::IComponentType> specializedComponent;
|
||||
linkedProgram->specialize(specialization.data(), specialization.size(), specializedComponent.writeRef(), diagnostics.writeRef());
|
||||
CHECK_DIAGNOSTICS();
|
||||
|
||||
Slang::ComPtr<slang::IBlob> kernelBlob;
|
||||
specializedComponent->getEntryPointCode(
|
||||
0,
|
||||
0,
|
||||
kernelBlob.writeRef(),
|
||||
diagnostics.writeRef()
|
||||
);
|
||||
CHECK_DIAGNOSTICS();
|
||||
|
||||
VkShaderModuleCreateInfo moduleInfo =
|
||||
{
|
||||
|
||||
@@ -12,7 +12,7 @@ DECLARE_REF(DescriptorLayout)
|
||||
class Shader
|
||||
{
|
||||
public:
|
||||
Shader(PGraphics graphics, ShaderType shaderType, VkShaderStageFlags stage);
|
||||
Shader(PGraphics graphics, VkShaderStageFlags stage);
|
||||
virtual ~Shader();
|
||||
|
||||
void create(const ShaderCreateInfo& createInfo);
|
||||
@@ -26,44 +26,36 @@ public:
|
||||
//SLang renames all entry points to main, so we dont need that
|
||||
return "main";//entryPointName.c_str();
|
||||
}
|
||||
constexpr ShaderType getShaderType() const
|
||||
{
|
||||
return type;
|
||||
}
|
||||
constexpr VkShaderStageFlags getStage() const
|
||||
{
|
||||
return stage;
|
||||
}
|
||||
//Map<uint32, PDescriptorLayout> getDescriptorLayouts();
|
||||
uint32 getShaderHash() const;
|
||||
private:
|
||||
PGraphics graphics;
|
||||
//Map<uint32, PDescriptorLayout> descriptorSets;
|
||||
VkShaderModule module;
|
||||
ShaderType type;
|
||||
VkShaderStageFlags stage;
|
||||
std::string entryPointName;
|
||||
uint32 hash;
|
||||
};
|
||||
DEFINE_REF(Shader)
|
||||
|
||||
template <typename Base, ShaderType shaderType, VkShaderStageFlags stageFlags>
|
||||
template <typename Base, VkShaderStageFlags stageFlags>
|
||||
class ShaderBase : public Base, public Shader
|
||||
{
|
||||
public:
|
||||
ShaderBase(PGraphics graphics)
|
||||
: Shader(graphics, shaderType, stageFlags)
|
||||
: Shader(graphics, stageFlags)
|
||||
{
|
||||
}
|
||||
virtual ~ShaderBase()
|
||||
{
|
||||
}
|
||||
};
|
||||
typedef ShaderBase<Gfx::VertexShader, ShaderType::VERTEX, VK_SHADER_STAGE_VERTEX_BIT> VertexShader;
|
||||
typedef ShaderBase<Gfx::FragmentShader, ShaderType::FRAGMENT, VK_SHADER_STAGE_FRAGMENT_BIT> FragmentShader;
|
||||
typedef ShaderBase<Gfx::ComputeShader, ShaderType::COMPUTE, VK_SHADER_STAGE_COMPUTE_BIT> ComputeShader;
|
||||
typedef ShaderBase<Gfx::TaskShader, ShaderType::TASK, VK_SHADER_STAGE_TASK_BIT_EXT> TaskShader;
|
||||
typedef ShaderBase<Gfx::MeshShader, ShaderType::MESH, VK_SHADER_STAGE_MESH_BIT_EXT> MeshShader;
|
||||
using VertexShader = ShaderBase<Gfx::VertexShader, VK_SHADER_STAGE_VERTEX_BIT>;
|
||||
using FragmentShader = ShaderBase<Gfx::FragmentShader, VK_SHADER_STAGE_FRAGMENT_BIT>;
|
||||
using ComputeShader = ShaderBase<Gfx::ComputeShader, VK_SHADER_STAGE_COMPUTE_BIT>;
|
||||
using TaskShader = ShaderBase<Gfx::TaskShader, VK_SHADER_STAGE_TASK_BIT_EXT>;
|
||||
using MeshShader = ShaderBase<Gfx::MeshShader, VK_SHADER_STAGE_MESH_BIT_EXT>;
|
||||
|
||||
DEFINE_REF(VertexShader)
|
||||
DEFINE_REF(FragmentShader)
|
||||
|
||||
Reference in New Issue
Block a user