Files
Seele/src/Engine/Graphics/Vulkan/VulkanShader.cpp
T

109 lines
3.4 KiB
C++
Raw Normal View History

2020-05-05 01:51:13 +02:00
#include "VulkanShader.h"
2020-06-02 11:46:18 +02:00
#include "VulkanGraphics.h"
#include "VulkanDescriptorSets.h"
#include "slang.h"
2020-05-05 01:51:13 +02:00
2020-06-02 11:46:18 +02:00
using namespace slang;
2020-05-05 01:51:13 +02:00
using namespace Seele;
2020-06-02 11:46:18 +02:00
using namespace Seele::Vulkan;
Shader::Shader(PGraphics graphics, ShaderType shaderType, VkShaderStageFlags stage)
: graphics(graphics)
, type(shaderType)
, stage(stage)
{
}
Shader::~Shader()
{
if(module != VK_NULL_HANDLE)
{
vkDestroyShaderModule(graphics->getDevice(), module, nullptr);
}
}
Map<uint32, PDescriptorLayout> Shader::getDescriptorLayouts()
{
return descriptorSets;
}
static SlangStage getStageFromShaderType(ShaderType type)
{
switch (type)
{
case ShaderType::VERTEX:
return SLANG_STAGE_VERTEX;
case ShaderType::CONTROL:
return SLANG_STAGE_HULL;
case ShaderType::EVALUATION:
return SLANG_STAGE_DOMAIN;
case ShaderType::GEOMETRY:
return SLANG_STAGE_GEOMETRY;
case ShaderType::FRAGMENT:
return SLANG_STAGE_PIXEL;
default:
return SLANG_STAGE_NONE;
}
}
void Shader::create(const ShaderCreateInfo& createInfo)
{
entryPointName = createInfo.entryPoint;
static SlangSession* session = spCreateSession(NULL);
SlangCompileRequest* request = spCreateCompileRequest(session);
int targetIndex = spAddCodeGenTarget(request, SLANG_SPIRV);
spSetTargetProfile(request, targetIndex, spFindProfile(session, "glsl_vk"));
spSetDumpIntermediates(request, true);
int translationUnitIndex = spAddTranslationUnit(request, SLANG_SOURCE_LANGUAGE_SLANG, "");
for(auto code : createInfo.shaderCode)
{
spAddTranslationUnitSourceString(
request,
translationUnitIndex,
entryPointName.c_str(),
code.data()
);
}
2020-09-19 14:36:50 +02:00
for(auto define : createInfo.defines)
{
spAddPreprocessorDefine(request, define.key, define.value);
}
2020-06-02 11:46:18 +02:00
spAddSearchPath(request, "shaders/lib/");
2020-09-19 14:36:50 +02:00
spAddSearchPath(request, "shaders/generated/");
2020-06-02 11:46:18 +02:00
spSetGlobalGenericArgs(request, createInfo.typeParameter.size(), createInfo.typeParameter.data());
int entryPointIndex = spAddEntryPoint(request, translationUnitIndex, entryPointName.c_str(), getStageFromShaderType(type));
if(spCompile(request))
{
2020-09-19 14:36:50 +02:00
char const* diagnostics = spGetDiagnosticOutput(request);
std::cout << diagnostics << std::endl;
2020-06-02 11:46:18 +02:00
}
ShaderReflection* reflection = slang::ShaderReflection::get(request);
uint32 parameterCount = reflection->getParameterCount();
for(uint32 i = 0; i < parameterCount; ++i)
{
VariableLayoutReflection* parameter =
reflection->getParameterByIndex(i);
uint32 descriptorIndex = parameter->getBindingSpace();
uint32 descriptorBinding = parameter->getBindingIndex();
PDescriptorLayout& layout = descriptorSets[descriptorIndex];
std::cout << parameter->getTypeLayout()->getName() << std::endl;
//layout->addDescriptorBinding(descriptorBinding, parame)
}
size_t dataSize = 0;
const void* data = spGetEntryPointCode(request, entryPointIndex, &dataSize);
VkShaderModuleCreateInfo moduleInfo;
moduleInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
moduleInfo.pNext = nullptr;
moduleInfo.flags = 0;
moduleInfo.codeSize = dataSize;
moduleInfo.pCode = static_cast<const uint32*>(data);
VK_CHECK(vkCreateShaderModule(graphics->getDevice(), &moduleInfo, nullptr, &module));
}