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

140 lines
4.5 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-10-03 11:00:10 +02:00
#include "spirv_cross/spirv_reflect.hpp"
#include <fstream>
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;
}
}
2020-10-03 11:00:10 +02:00
/*static void createMixedDescriptorLayout(PDescriptorLayout layout, VariableLayoutReflection* parameter)
{
//std::cout << "category: " << (uint32)parameter->ge << std::endl;
uint32 categoryCount = parameter->getCategoryCount();
std::cout << "Mixed parameter " << parameter->getName() << " with categories: " << std::endl;
for(uint32 i = 0; i < categoryCount; ++i)
{
ParameterCategory category = parameter->getCategoryByIndex(i);
uint32 offset = parameter->getOffset(category);
uint32 space = parameter->getBindingSpace(category);
std::cout << "category: " << category << std::endl << " offset: " << offset << std::endl << " space: " << space << std::endl;
}
}
static Gfx::SeDescriptorType getTypeFromKind(slang::TypeReflection::Kind kind)
{
switch (kind)
{
case slang::TypeReflection::Kind::ConstantBuffer:
case slang::TypeReflection::Kind::GenericTypeParameter:
case slang::TypeReflection::Kind::ParameterBlock:
return Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
case slang::TypeReflection::Kind::ShaderStorageBuffer:
return Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER;
case slang::TypeReflection::Kind::TextureBuffer:
return Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
case slang::TypeReflection::Kind::SamplerState:
return Gfx::SE_DESCRIPTOR_TYPE_SAMPLER;
default:
return Gfx::SE_DESCRIPTOR_TYPE_MAX_ENUM;
}
}*/
2020-06-02 11:46:18 +02:00
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);
std::cout << diagnostics << std::endl;
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
}