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

107 lines
3.2 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"
2021-04-01 16:40:14 +02:00
//#include "spirv_cross/spirv_reflect.hpp"
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;
}
uint32 Seele::Vulkan::Shader::getShaderHash() const
{
return hash;
}
2020-06-02 11:46:18 +02:00
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
2021-03-31 12:18:16 +02:00
spSetGlobalGenericArgs(request, (int)createInfo.typeParameter.size(), createInfo.typeParameter.data());
2020-06-02 11:46:18 +02:00
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);
2021-05-06 17:02:10 +02:00
std::cout << "Compile error for shader " << createInfo.name << std::endl;
2020-09-19 14:36:50 +02:00
std::cout << diagnostics << std::endl;
2021-05-10 23:57:55 +02:00
return;
2020-06-02 11:46:18 +02:00
}
size_t dataSize = 0;
2020-10-03 11:00:10 +02:00
const uint32* data = reinterpret_cast<const uint32*>(spGetEntryPointCode(request, entryPointIndex, &dataSize));
2020-06-02 11:46:18 +02:00
VkShaderModuleCreateInfo moduleInfo;
moduleInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
moduleInfo.pNext = nullptr;
moduleInfo.flags = 0;
moduleInfo.codeSize = dataSize;
2020-10-03 11:00:10 +02:00
moduleInfo.pCode = data;
2020-06-02 11:46:18 +02:00
VK_CHECK(vkCreateShaderModule(graphics->getDevice(), &moduleInfo, nullptr, &module));
boost::crc_32_type result;
result.process_bytes(entryPointName.data(), entryPointName.size());
result.process_bytes(data, dataSize);
hash = result.checksum();
2020-06-02 11:46:18 +02:00
}