Unify standalone and runtime shader compiler, rename old ShaderCompiler to MaterialCompiler
This commit is contained in:
parent
9cd7860ab9
commit
80fd8a375b
16 changed files with 411 additions and 455 deletions
|
@ -1,9 +1,9 @@
|
|||
macro(compile_shader src)
|
||||
string(REGEX REPLACE "\\.[^.]*$" "" MYFILE_WITHOUT_EXT ${src})
|
||||
|
||||
set(SHADER_COMPILER_COMMAND $<TARGET_FILE:ShaderCompiler>)
|
||||
set(SHADER_COMPILER_COMMAND $<TARGET_FILE:ShaderCompilerTool>)
|
||||
if(ENABLE_IOS)
|
||||
set(SHADER_COMPILER_COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/../build/bin/Debug/ShaderCompiler")
|
||||
set(SHADER_COMPILER_COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/../build/bin/Debug/ShaderCompilerTool")
|
||||
endif()
|
||||
|
||||
set(EXTRA_PLATFORM_ARG "0")
|
||||
|
@ -36,7 +36,7 @@ function(add_shader)
|
|||
|
||||
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/shaders)
|
||||
|
||||
add_custom_target(BuildShaders DEPENDS ${SPV_FILES} ShaderCompiler)
|
||||
add_custom_target(BuildShaders DEPENDS ${SPV_FILES} ShaderCompilerTool)
|
||||
add_dependencies(${add_shader_TARGET} BuildShaders)
|
||||
|
||||
set(ALL_SHADER_FILES ${SPV_FILES} CACHE INTERNAL "" FORCE)
|
||||
|
|
|
@ -5,6 +5,7 @@ add_subdirectory(gfx)
|
|||
add_subdirectory(math)
|
||||
add_subdirectory(log)
|
||||
add_subdirectory(asset)
|
||||
add_subdirectory(shadercompiler)
|
||||
|
||||
if(NOT ENABLE_IOS AND NOT ENABLE_TVOS)
|
||||
add_subdirectory(audio)
|
||||
|
|
|
@ -7,8 +7,7 @@ set(SRC
|
|||
include/imguipass.hpp
|
||||
include/smaapass.hpp
|
||||
include/scenecapture.hpp
|
||||
include/shadercompiler.hpp
|
||||
include/DirStackIncluder.h
|
||||
include/materialcompiler.hpp
|
||||
include/dofpass.hpp
|
||||
|
||||
src/renderer.cpp
|
||||
|
@ -17,7 +16,7 @@ set(SRC
|
|||
src/imguipass.cpp
|
||||
src/smaapass.cpp
|
||||
src/scenecapture.cpp
|
||||
src/shadercompiler.cpp
|
||||
src/materialcompiler.cpp
|
||||
src/dofpass.cpp)
|
||||
|
||||
add_library(Renderer STATIC ${SRC})
|
||||
|
@ -32,11 +31,9 @@ target_link_libraries(Renderer
|
|||
Core
|
||||
imgui
|
||||
SMAA::SMAA
|
||||
${CROSS_LIBS})
|
||||
ShaderCompiler)
|
||||
target_include_directories(Renderer PUBLIC include)
|
||||
set_target_properties(Renderer PROPERTIES CXX_STANDARD 17)
|
||||
target_compile_features(Renderer PUBLIC cxx_std_17)
|
||||
set_target_properties(Renderer PROPERTIES CXX_EXTENSIONS OFF)
|
||||
set_engine_properties(Renderer)
|
||||
|
||||
include(../../cmake/BuildShaders.cmake)
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ constexpr int tangent_buffer_index = 5;
|
|||
constexpr int bitangent_buffer_index = 6;
|
||||
constexpr int bone_buffer_index = 7;
|
||||
|
||||
class ShaderCompiler {
|
||||
class MaterialCompiler {
|
||||
public:
|
||||
GFXPipeline* create_static_pipeline(GFXGraphicsPipelineCreateInfo createInfo, bool positions_only = false, bool cubemap = false);
|
||||
GFXPipeline* create_skinned_pipeline(GFXGraphicsPipelineCreateInfo createInfo, bool positions_only = false);
|
||||
|
@ -24,4 +24,4 @@ public:
|
|||
std::variant<std::string, std::vector<uint32_t>> compile_material_fragment(Material& material, bool use_ibl = true);
|
||||
};
|
||||
|
||||
static ShaderCompiler shader_compiler;
|
||||
static MaterialCompiler material_compiler;
|
|
@ -1,181 +1,10 @@
|
|||
#include "shadercompiler.hpp"
|
||||
|
||||
#include <spirv_cpp.hpp>
|
||||
#include <spirv_msl.hpp>
|
||||
#include <SPIRV/GlslangToSpv.h>
|
||||
#include "materialcompiler.hpp"
|
||||
|
||||
#include "file.hpp"
|
||||
#include "log.hpp"
|
||||
#include "engine.hpp"
|
||||
#include "string_utils.hpp"
|
||||
#include "DirStackIncluder.h"
|
||||
|
||||
const TBuiltInResource DefaultTBuiltInResource = {
|
||||
/* .MaxLights = */ 32,
|
||||
/* .MaxClipPlanes = */ 6,
|
||||
/* .MaxTextureUnits = */ 32,
|
||||
/* .MaxTextureCoords = */ 32,
|
||||
/* .MaxVertexAttribs = */ 64,
|
||||
/* .MaxVertexUniformComponents = */ 4096,
|
||||
/* .MaxVaryingFloats = */ 64,
|
||||
/* .MaxVertexTextureImageUnits = */ 32,
|
||||
/* .MaxCombinedTextureImageUnits = */ 80,
|
||||
/* .MaxTextureImageUnits = */ 32,
|
||||
/* .MaxFragmentUniformComponents = */ 4096,
|
||||
/* .MaxDrawBuffers = */ 32,
|
||||
/* .MaxVertexUniformVectors = */ 128,
|
||||
/* .MaxVaryingVectors = */ 8,
|
||||
/* .MaxFragmentUniformVectors = */ 16,
|
||||
/* .MaxVertexOutputVectors = */ 16,
|
||||
/* .MaxFragmentInputVectors = */ 15,
|
||||
/* .MinProgramTexelOffset = */ -8,
|
||||
/* .MaxProgramTexelOffset = */ 7,
|
||||
/* .MaxClipDistances = */ 8,
|
||||
/* .MaxComputeWorkGroupCountX = */ 65535,
|
||||
/* .MaxComputeWorkGroupCountY = */ 65535,
|
||||
/* .MaxComputeWorkGroupCountZ = */ 65535,
|
||||
/* .MaxComputeWorkGroupSizeX = */ 1024,
|
||||
/* .MaxComputeWorkGroupSizeY = */ 1024,
|
||||
/* .MaxComputeWorkGroupSizeZ = */ 64,
|
||||
/* .MaxComputeUniformComponents = */ 1024,
|
||||
/* .MaxComputeTextureImageUnits = */ 16,
|
||||
/* .MaxComputeImageUniforms = */ 8,
|
||||
/* .MaxComputeAtomicCounters = */ 8,
|
||||
/* .MaxComputeAtomicCounterBuffers = */ 1,
|
||||
/* .MaxVaryingComponents = */ 60,
|
||||
/* .MaxVertexOutputComponents = */ 64,
|
||||
/* .MaxGeometryInputComponents = */ 64,
|
||||
/* .MaxGeometryOutputComponents = */ 128,
|
||||
/* .MaxFragmentInputComponents = */ 128,
|
||||
/* .MaxImageUnits = */ 8,
|
||||
/* .MaxCombinedImageUnitsAndFragmentOutputs = */ 8,
|
||||
/* .MaxCombinedShaderOutputResources = */ 8,
|
||||
/* .MaxImageSamples = */ 0,
|
||||
/* .MaxVertexImageUniforms = */ 0,
|
||||
/* .MaxTessControlImageUniforms = */ 0,
|
||||
/* .MaxTessEvaluationImageUniforms = */ 0,
|
||||
/* .MaxGeometryImageUniforms = */ 0,
|
||||
/* .MaxFragmentImageUniforms = */ 8,
|
||||
/* .MaxCombinedImageUniforms = */ 8,
|
||||
/* .MaxGeometryTextureImageUnits = */ 16,
|
||||
/* .MaxGeometryOutputVertices = */ 256,
|
||||
/* .MaxGeometryTotalOutputComponents = */ 1024,
|
||||
/* .MaxGeometryUniformComponents = */ 1024,
|
||||
/* .MaxGeometryVaryingComponents = */ 64,
|
||||
/* .MaxTessControlInputComponents = */ 128,
|
||||
/* .MaxTessControlOutputComponents = */ 128,
|
||||
/* .MaxTessControlTextureImageUnits = */ 16,
|
||||
/* .MaxTessControlUniformComponents = */ 1024,
|
||||
/* .MaxTessControlTotalOutputComponents = */ 4096,
|
||||
/* .MaxTessEvaluationInputComponents = */ 128,
|
||||
/* .MaxTessEvaluationOutputComponents = */ 128,
|
||||
/* .MaxTessEvaluationTextureImageUnits = */ 16,
|
||||
/* .MaxTessEvaluationUniformComponents = */ 1024,
|
||||
/* .MaxTessPatchComponents = */ 120,
|
||||
/* .MaxPatchVertices = */ 32,
|
||||
/* .MaxTessGenLevel = */ 64,
|
||||
/* .MaxViewports = */ 16,
|
||||
/* .MaxVertexAtomicCounters = */ 0,
|
||||
/* .MaxTessControlAtomicCounters = */ 0,
|
||||
/* .MaxTessEvaluationAtomicCounters = */ 0,
|
||||
/* .MaxGeometryAtomicCounters = */ 0,
|
||||
/* .MaxFragmentAtomicCounters = */ 8,
|
||||
/* .MaxCombinedAtomicCounters = */ 8,
|
||||
/* .MaxAtomicCounterBindings = */ 1,
|
||||
/* .MaxVertexAtomicCounterBuffers = */ 0,
|
||||
/* .MaxTessControlAtomicCounterBuffers = */ 0,
|
||||
/* .MaxTessEvaluationAtomicCounterBuffers = */ 0,
|
||||
/* .MaxGeometryAtomicCounterBuffers = */ 0,
|
||||
/* .MaxFragmentAtomicCounterBuffers = */ 1,
|
||||
/* .MaxCombinedAtomicCounterBuffers = */ 1,
|
||||
/* .MaxAtomicCounterBufferSize = */ 16384,
|
||||
/* .MaxTransformFeedbackBuffers = */ 4,
|
||||
/* .MaxTransformFeedbackInterleavedComponents = */ 64,
|
||||
/* .MaxCullDistances = */ 8,
|
||||
/* .MaxCombinedClipAndCullDistances = */ 8,
|
||||
/* .MaxSamples = */ 4,
|
||||
/* .maxMeshOutputVerticesNV = */ 256,
|
||||
/* .maxMeshOutputPrimitivesNV = */ 512,
|
||||
/* .maxMeshWorkGroupSizeX_NV = */ 32,
|
||||
/* .maxMeshWorkGroupSizeY_NV = */ 1,
|
||||
/* .maxMeshWorkGroupSizeZ_NV = */ 1,
|
||||
/* .maxTaskWorkGroupSizeX_NV = */ 32,
|
||||
/* .maxTaskWorkGroupSizeY_NV = */ 1,
|
||||
/* .maxTaskWorkGroupSizeZ_NV = */ 1,
|
||||
/* .maxMeshViewCountNV = */ 4,
|
||||
/* .maxDualSourceDrawBuffersEXT = */ 4,
|
||||
|
||||
/* .limits = */ TLimits{
|
||||
/* .nonInductiveForLoops = */ true,
|
||||
/* .whileLoops = */ true,
|
||||
/* .doWhileLoops = */ true,
|
||||
/* .generalUniformIndexing = */ true,
|
||||
/* .generalAttributeMatrixVectorIndexing = */ true,
|
||||
/* .generalVaryingIndexing = */ true,
|
||||
/* .generalSamplerIndexing = */ true,
|
||||
/* .generalVariableIndexing = */ true,
|
||||
/* .generalConstantMatrixVectorIndexing = */ true,
|
||||
}};
|
||||
|
||||
|
||||
const std::vector<unsigned int> CompileGLSL(const std::string& filename, EShLanguage ShaderType, bool skinned, bool cubemap) {
|
||||
std::string newString = "#version 430 core\n";
|
||||
|
||||
newString += "#extension GL_GOOGLE_include_directive : enable\n";
|
||||
newString += "#extension GL_GOOGLE_cpp_style_line_directive : enable\n";
|
||||
|
||||
if(skinned)
|
||||
newString += "#define BONE\n";
|
||||
|
||||
if(cubemap)
|
||||
newString += "#define CUBEMAP\n";
|
||||
|
||||
newString += "#line 1\n";
|
||||
|
||||
newString += filename;
|
||||
|
||||
const char* InputCString = newString.c_str();
|
||||
|
||||
glslang::TShader Shader(ShaderType);
|
||||
|
||||
Shader.setStrings(&InputCString, 1);
|
||||
|
||||
int ClientInputSemanticsVersion = 100; // maps to, say, #define VULKAN 100
|
||||
glslang::EShTargetClientVersion VulkanClientVersion = glslang::EShTargetVulkan_1_1;
|
||||
glslang::EShTargetLanguageVersion TargetVersion = glslang::EShTargetSpv_1_0;
|
||||
|
||||
Shader.setEnvInput(glslang::EShSourceGlsl, ShaderType, glslang::EShClientVulkan, ClientInputSemanticsVersion);
|
||||
Shader.setEnvClient(glslang::EShClientVulkan, VulkanClientVersion);
|
||||
Shader.setEnvTarget(glslang::EShTargetSpv, TargetVersion);
|
||||
|
||||
TBuiltInResource Resources = DefaultTBuiltInResource;
|
||||
EShMessages messages = (EShMessages) (EShMsgSpvRules);
|
||||
|
||||
DirStackFileIncluder includer;
|
||||
includer.pushExternalLocalDirectory(file::get_domain_path(file::Domain::Internal).string());
|
||||
|
||||
if (!Shader.parse(&Resources, 100, false, (EShMessages)0, includer)) {
|
||||
console::error(System::Renderer, "{}", Shader.getInfoLog());
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
glslang::TProgram Program;
|
||||
Program.addShader(&Shader);
|
||||
|
||||
if(!Program.link(messages)) {
|
||||
console::error(System::None, "Failed to link shader: {} {} {}", filename, Shader.getInfoLog(), Shader.getInfoDebugLog());
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<unsigned int> SpirV;
|
||||
spv::SpvBuildLogger logger;
|
||||
glslang::SpvOptions spvOptions;
|
||||
glslang::GlslangToSpv(*Program.getIntermediate(ShaderType), SpirV, &logger, &spvOptions);
|
||||
|
||||
return SpirV;
|
||||
}
|
||||
#include "shadercompiler.hpp"
|
||||
|
||||
std::variant<std::string, std::vector<uint32_t>> get_shader(std::string filename, bool skinned, bool cubemap) {
|
||||
auto shader_file = file::open(file::internal_domain / filename);
|
||||
|
@ -184,31 +13,24 @@ std::variant<std::string, std::vector<uint32_t>> get_shader(std::string filename
|
|||
return "";
|
||||
}
|
||||
|
||||
EShLanguage lang;
|
||||
ShaderStage stage;
|
||||
if(filename.find("vert") != std::string::npos) {
|
||||
lang = EShLangVertex;
|
||||
stage = ShaderStage::Vertex;
|
||||
} else {
|
||||
lang = EShLangFragment;
|
||||
stage = ShaderStage::Fragment;
|
||||
}
|
||||
|
||||
auto vertexSPIRV = CompileGLSL(shader_file->read_as_string(), lang, skinned, cubemap);
|
||||
CompileOptions options;
|
||||
if(skinned)
|
||||
options.add_definition("BONE");
|
||||
|
||||
#ifdef PLATFORM_MACOS
|
||||
spirv_cross::CompilerMSL msl(std::move(vertexSPIRV));
|
||||
if(cubemap)
|
||||
options.add_definition("CUBEMAP");
|
||||
|
||||
spirv_cross::CompilerMSL::Options opts;
|
||||
opts.platform = spirv_cross::CompilerMSL::Options::Platform::macOS;
|
||||
opts.enable_decoration_binding = true;
|
||||
|
||||
msl.set_msl_options(opts);
|
||||
|
||||
return msl.compile();
|
||||
#else
|
||||
return vertexSPIRV;
|
||||
#endif
|
||||
return shader_compiler.compile(ShaderLanguage::GLSL, stage, shader_file->read_as_string(), ShaderLanguage::MSL, options)->source;
|
||||
}
|
||||
|
||||
GFXPipeline* ShaderCompiler::create_static_pipeline(GFXGraphicsPipelineCreateInfo createInfo, bool positions_only, bool cubemap) {
|
||||
GFXPipeline* MaterialCompiler::create_static_pipeline(GFXGraphicsPipelineCreateInfo createInfo, bool positions_only, bool cubemap) {
|
||||
// take vertex src
|
||||
std::string vertex_path = createInfo.shaders.vertex_path.data();
|
||||
vertex_path += ".glsl";
|
||||
|
@ -245,7 +67,7 @@ GFXPipeline* ShaderCompiler::create_static_pipeline(GFXGraphicsPipelineCreateInf
|
|||
return engine->get_gfx()->create_graphics_pipeline(createInfo);
|
||||
}
|
||||
|
||||
GFXPipeline* ShaderCompiler::create_skinned_pipeline(GFXGraphicsPipelineCreateInfo createInfo, bool positions_only) {
|
||||
GFXPipeline* MaterialCompiler::create_skinned_pipeline(GFXGraphicsPipelineCreateInfo createInfo, bool positions_only) {
|
||||
createInfo.label += " (Skinned)";
|
||||
|
||||
// take vertex src
|
||||
|
@ -290,9 +112,7 @@ GFXPipeline* ShaderCompiler::create_skinned_pipeline(GFXGraphicsPipelineCreateIn
|
|||
return engine->get_gfx()->create_graphics_pipeline(createInfo);
|
||||
}
|
||||
|
||||
std::tuple<GFXPipeline*, GFXPipeline*> ShaderCompiler::create_pipeline_permutations(GFXGraphicsPipelineCreateInfo& createInfo, bool positions_only) {
|
||||
glslang::InitializeProcess();
|
||||
|
||||
std::tuple<GFXPipeline*, GFXPipeline*> MaterialCompiler::create_pipeline_permutations(GFXGraphicsPipelineCreateInfo& createInfo, bool positions_only) {
|
||||
auto st = create_static_pipeline(createInfo, positions_only);
|
||||
auto ss = create_skinned_pipeline(createInfo, positions_only);
|
||||
|
||||
|
@ -364,7 +184,7 @@ layout(push_constant, binding = 0) uniform PushConstant {\n \
|
|||
int materialOffset;\n \
|
||||
};\n";
|
||||
|
||||
std::variant<std::string, std::vector<uint32_t>> ShaderCompiler::compile_material_fragment(Material& material, bool use_ibl) {
|
||||
std::variant<std::string, std::vector<uint32_t>> MaterialCompiler::compile_material_fragment(Material& material, bool use_ibl) {
|
||||
walked_nodes.clear();
|
||||
|
||||
if(!render_options.enable_ibl)
|
||||
|
@ -567,19 +387,5 @@ std::variant<std::string, std::vector<uint32_t>> ShaderCompiler::compile_materia
|
|||
|
||||
src += "}\n";
|
||||
|
||||
auto vertexSPIRV = CompileGLSL(src, EShLangFragment, false, false);
|
||||
|
||||
#ifdef PLATFORM_MACOS
|
||||
spirv_cross::CompilerMSL msl(std::move(vertexSPIRV));
|
||||
|
||||
spirv_cross::CompilerMSL::Options opts;
|
||||
opts.platform = spirv_cross::CompilerMSL::Options::Platform::macOS;
|
||||
opts.enable_decoration_binding = true;
|
||||
|
||||
msl.set_msl_options(opts);
|
||||
|
||||
return msl.compile();
|
||||
#else
|
||||
return vertexSPIRV;
|
||||
#endif
|
||||
return shader_compiler.compile(ShaderLanguage::GLSL, ShaderStage::Fragment, src, ShaderLanguage::MSL)->source;
|
||||
}
|
|
@ -18,10 +18,11 @@
|
|||
#include "shadowpass.hpp"
|
||||
#include "smaapass.hpp"
|
||||
#include "scenecapture.hpp"
|
||||
#include "shadercompiler.hpp"
|
||||
#include "materialcompiler.hpp"
|
||||
#include "assertions.hpp"
|
||||
#include "dofpass.hpp"
|
||||
#include "frustum.hpp"
|
||||
#include "shadercompiler.hpp"
|
||||
|
||||
struct ElementInstance {
|
||||
Vector4 color;
|
||||
|
@ -83,6 +84,8 @@ struct UIPushConstant {
|
|||
Renderer::Renderer(GFX* gfx, const bool enable_imgui) : gfx(gfx) {
|
||||
Expects(gfx != nullptr);
|
||||
|
||||
shader_compiler.set_include_path(file::get_domain_path(file::Domain::Internal).string());
|
||||
|
||||
createDummyTexture();
|
||||
|
||||
shadow_pass = std::make_unique<ShadowPass>(gfx);
|
||||
|
@ -691,19 +694,19 @@ void Renderer::create_mesh_pipeline(Material& material) {
|
|||
pipelineInfo.blending.src_rgb = GFXBlendFactor::SrcAlpha;
|
||||
pipelineInfo.blending.dst_rgb = GFXBlendFactor::OneMinusSrcAlpha;
|
||||
|
||||
pipelineInfo.shaders.fragment_src = shader_compiler.compile_material_fragment(material);
|
||||
pipelineInfo.shaders.fragment_src = material_compiler.compile_material_fragment(material);
|
||||
pipelineInfo.shaders.fragment_path = "";
|
||||
|
||||
auto [static_pipeline, skinned_pipeline] = shader_compiler.create_pipeline_permutations(pipelineInfo);
|
||||
auto [static_pipeline, skinned_pipeline] = material_compiler.create_pipeline_permutations(pipelineInfo);
|
||||
|
||||
material.static_pipeline = static_pipeline;
|
||||
material.skinned_pipeline = skinned_pipeline;
|
||||
|
||||
pipelineInfo.render_pass = scene_capture->renderPass;
|
||||
|
||||
pipelineInfo.shaders.fragment_src = shader_compiler.compile_material_fragment(material, false); // scene capture does not use IBL
|
||||
pipelineInfo.shaders.fragment_src = material_compiler.compile_material_fragment(material, false); // scene capture does not use IBL
|
||||
|
||||
material.capture_pipeline = shader_compiler.create_static_pipeline(pipelineInfo, false, true);
|
||||
material.capture_pipeline = material_compiler.create_static_pipeline(pipelineInfo, false, true);
|
||||
}
|
||||
|
||||
void Renderer::createDummyTexture() {
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#include "engine.hpp"
|
||||
#include "renderer.hpp"
|
||||
#include "shadowpass.hpp"
|
||||
#include "shadercompiler.hpp"
|
||||
#include "materialcompiler.hpp"
|
||||
#include "frustum.hpp"
|
||||
|
||||
struct PushConstant {
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include "gfx.hpp"
|
||||
#include "log.hpp"
|
||||
#include "engine.hpp"
|
||||
#include "shadercompiler.hpp"
|
||||
#include "materialcompiler.hpp"
|
||||
#include "assertions.hpp"
|
||||
#include "frustum.hpp"
|
||||
|
||||
|
@ -325,7 +325,7 @@ void ShadowPass::create_pipelines() {
|
|||
{
|
||||
pipelineInfo.label = "Sun Shadow";
|
||||
|
||||
auto [static_pipeline, skinned_pipeline] = shader_compiler.create_pipeline_permutations(pipelineInfo, true);
|
||||
auto [static_pipeline, skinned_pipeline] = material_compiler.create_pipeline_permutations(pipelineInfo, true);
|
||||
|
||||
static_sun_pipeline = static_pipeline;
|
||||
skinned_sun_pipeline = skinned_pipeline;
|
||||
|
@ -337,7 +337,7 @@ void ShadowPass::create_pipelines() {
|
|||
|
||||
pipelineInfo.render_pass = cube_render_pass;
|
||||
|
||||
auto [static_pipeline, skinned_pipeline] = shader_compiler.create_pipeline_permutations(pipelineInfo, true);
|
||||
auto [static_pipeline, skinned_pipeline] = material_compiler.create_pipeline_permutations(pipelineInfo, true);
|
||||
|
||||
static_spot_pipeline = static_pipeline;
|
||||
skinned_spot_pipeline = skinned_pipeline;
|
||||
|
@ -349,7 +349,7 @@ void ShadowPass::create_pipelines() {
|
|||
|
||||
pipelineInfo.shaders.fragment_path = "omnishadow.frag";
|
||||
|
||||
auto [static_pipeline, skinned_pipeline] = shader_compiler.create_pipeline_permutations(pipelineInfo, true);
|
||||
auto [static_pipeline, skinned_pipeline] = material_compiler.create_pipeline_permutations(pipelineInfo, true);
|
||||
|
||||
static_point_pipeline = static_pipeline;
|
||||
skinned_point_pipeline = skinned_pipeline;
|
||||
|
|
15
engine/shadercompiler/CMakeLists.txt
Executable file
15
engine/shadercompiler/CMakeLists.txt
Executable file
|
@ -0,0 +1,15 @@
|
|||
set(SRC
|
||||
include/shadercompiler.hpp
|
||||
|
||||
src/shadercompiler.cpp
|
||||
src/includer.hpp
|
||||
src/defaultresources.hpp)
|
||||
|
||||
add_library(ShaderCompiler STATIC ${SRC})
|
||||
target_link_libraries(ShaderCompiler
|
||||
PRIVATE
|
||||
Utility
|
||||
Log
|
||||
${CROSS_LIBS})
|
||||
target_include_directories(ShaderCompiler PUBLIC include PRIVATE src)
|
||||
set_engine_properties(ShaderCompiler)
|
59
engine/shadercompiler/include/shadercompiler.hpp
Executable file
59
engine/shadercompiler/include/shadercompiler.hpp
Executable file
|
@ -0,0 +1,59 @@
|
|||
#pragma once
|
||||
|
||||
#include <variant>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <string_view>
|
||||
#include <optional>
|
||||
|
||||
enum class ShaderStage {
|
||||
Vertex,
|
||||
Fragment
|
||||
};
|
||||
|
||||
enum class ShaderLanguage {
|
||||
GLSL,
|
||||
MSL,
|
||||
SPIRV
|
||||
};
|
||||
|
||||
class CompileOptions {
|
||||
public:
|
||||
void add_definition(const std::string_view name) {
|
||||
definitions.emplace_back(name);
|
||||
}
|
||||
|
||||
std::vector<std::string> definitions;
|
||||
|
||||
bool is_apple_mobile = false;
|
||||
};
|
||||
|
||||
class ShaderSource {
|
||||
public:
|
||||
ShaderSource(const std::string source_string) : source(source_string) {}
|
||||
ShaderSource(const std::vector<uint32_t> source_bytecode) : source(source_bytecode) {}
|
||||
|
||||
std::variant<std::string, std::vector<uint32_t>> source;
|
||||
|
||||
std::string_view as_string() const {
|
||||
return std::get<std::string>(source);
|
||||
}
|
||||
|
||||
std::vector<uint32_t> as_bytecode() const {
|
||||
return std::get<std::vector<uint32_t>>(source);
|
||||
}
|
||||
};
|
||||
|
||||
class ShaderCompiler {
|
||||
public:
|
||||
ShaderCompiler();
|
||||
|
||||
void set_include_path(const std::string_view path);
|
||||
|
||||
/**
|
||||
Compiles from one shader language to another shader language.
|
||||
*/
|
||||
std::optional<ShaderSource> compile(const ShaderLanguage from_language, const ShaderStage shader_stage, const ShaderSource& shader_source, const ShaderLanguage to_language, const CompileOptions& options = CompileOptions());
|
||||
};
|
||||
|
||||
static inline ShaderCompiler shader_compiler;
|
108
engine/shadercompiler/src/defaultresources.hpp
Executable file
108
engine/shadercompiler/src/defaultresources.hpp
Executable file
|
@ -0,0 +1,108 @@
|
|||
#pragma once
|
||||
|
||||
const TBuiltInResource DefaultTBuiltInResource = {
|
||||
/* .MaxLights = */ 32,
|
||||
/* .MaxClipPlanes = */ 6,
|
||||
/* .MaxTextureUnits = */ 32,
|
||||
/* .MaxTextureCoords = */ 32,
|
||||
/* .MaxVertexAttribs = */ 64,
|
||||
/* .MaxVertexUniformComponents = */ 4096,
|
||||
/* .MaxVaryingFloats = */ 64,
|
||||
/* .MaxVertexTextureImageUnits = */ 32,
|
||||
/* .MaxCombinedTextureImageUnits = */ 80,
|
||||
/* .MaxTextureImageUnits = */ 32,
|
||||
/* .MaxFragmentUniformComponents = */ 4096,
|
||||
/* .MaxDrawBuffers = */ 32,
|
||||
/* .MaxVertexUniformVectors = */ 128,
|
||||
/* .MaxVaryingVectors = */ 8,
|
||||
/* .MaxFragmentUniformVectors = */ 16,
|
||||
/* .MaxVertexOutputVectors = */ 16,
|
||||
/* .MaxFragmentInputVectors = */ 15,
|
||||
/* .MinProgramTexelOffset = */ -8,
|
||||
/* .MaxProgramTexelOffset = */ 7,
|
||||
/* .MaxClipDistances = */ 8,
|
||||
/* .MaxComputeWorkGroupCountX = */ 65535,
|
||||
/* .MaxComputeWorkGroupCountY = */ 65535,
|
||||
/* .MaxComputeWorkGroupCountZ = */ 65535,
|
||||
/* .MaxComputeWorkGroupSizeX = */ 1024,
|
||||
/* .MaxComputeWorkGroupSizeY = */ 1024,
|
||||
/* .MaxComputeWorkGroupSizeZ = */ 64,
|
||||
/* .MaxComputeUniformComponents = */ 1024,
|
||||
/* .MaxComputeTextureImageUnits = */ 16,
|
||||
/* .MaxComputeImageUniforms = */ 8,
|
||||
/* .MaxComputeAtomicCounters = */ 8,
|
||||
/* .MaxComputeAtomicCounterBuffers = */ 1,
|
||||
/* .MaxVaryingComponents = */ 60,
|
||||
/* .MaxVertexOutputComponents = */ 64,
|
||||
/* .MaxGeometryInputComponents = */ 64,
|
||||
/* .MaxGeometryOutputComponents = */ 128,
|
||||
/* .MaxFragmentInputComponents = */ 128,
|
||||
/* .MaxImageUnits = */ 8,
|
||||
/* .MaxCombinedImageUnitsAndFragmentOutputs = */ 8,
|
||||
/* .MaxCombinedShaderOutputResources = */ 8,
|
||||
/* .MaxImageSamples = */ 0,
|
||||
/* .MaxVertexImageUniforms = */ 0,
|
||||
/* .MaxTessControlImageUniforms = */ 0,
|
||||
/* .MaxTessEvaluationImageUniforms = */ 0,
|
||||
/* .MaxGeometryImageUniforms = */ 0,
|
||||
/* .MaxFragmentImageUniforms = */ 8,
|
||||
/* .MaxCombinedImageUniforms = */ 8,
|
||||
/* .MaxGeometryTextureImageUnits = */ 16,
|
||||
/* .MaxGeometryOutputVertices = */ 256,
|
||||
/* .MaxGeometryTotalOutputComponents = */ 1024,
|
||||
/* .MaxGeometryUniformComponents = */ 1024,
|
||||
/* .MaxGeometryVaryingComponents = */ 64,
|
||||
/* .MaxTessControlInputComponents = */ 128,
|
||||
/* .MaxTessControlOutputComponents = */ 128,
|
||||
/* .MaxTessControlTextureImageUnits = */ 16,
|
||||
/* .MaxTessControlUniformComponents = */ 1024,
|
||||
/* .MaxTessControlTotalOutputComponents = */ 4096,
|
||||
/* .MaxTessEvaluationInputComponents = */ 128,
|
||||
/* .MaxTessEvaluationOutputComponents = */ 128,
|
||||
/* .MaxTessEvaluationTextureImageUnits = */ 16,
|
||||
/* .MaxTessEvaluationUniformComponents = */ 1024,
|
||||
/* .MaxTessPatchComponents = */ 120,
|
||||
/* .MaxPatchVertices = */ 32,
|
||||
/* .MaxTessGenLevel = */ 64,
|
||||
/* .MaxViewports = */ 16,
|
||||
/* .MaxVertexAtomicCounters = */ 0,
|
||||
/* .MaxTessControlAtomicCounters = */ 0,
|
||||
/* .MaxTessEvaluationAtomicCounters = */ 0,
|
||||
/* .MaxGeometryAtomicCounters = */ 0,
|
||||
/* .MaxFragmentAtomicCounters = */ 8,
|
||||
/* .MaxCombinedAtomicCounters = */ 8,
|
||||
/* .MaxAtomicCounterBindings = */ 1,
|
||||
/* .MaxVertexAtomicCounterBuffers = */ 0,
|
||||
/* .MaxTessControlAtomicCounterBuffers = */ 0,
|
||||
/* .MaxTessEvaluationAtomicCounterBuffers = */ 0,
|
||||
/* .MaxGeometryAtomicCounterBuffers = */ 0,
|
||||
/* .MaxFragmentAtomicCounterBuffers = */ 1,
|
||||
/* .MaxCombinedAtomicCounterBuffers = */ 1,
|
||||
/* .MaxAtomicCounterBufferSize = */ 16384,
|
||||
/* .MaxTransformFeedbackBuffers = */ 4,
|
||||
/* .MaxTransformFeedbackInterleavedComponents = */ 64,
|
||||
/* .MaxCullDistances = */ 8,
|
||||
/* .MaxCombinedClipAndCullDistances = */ 8,
|
||||
/* .MaxSamples = */ 4,
|
||||
/* .maxMeshOutputVerticesNV = */ 256,
|
||||
/* .maxMeshOutputPrimitivesNV = */ 512,
|
||||
/* .maxMeshWorkGroupSizeX_NV = */ 32,
|
||||
/* .maxMeshWorkGroupSizeY_NV = */ 1,
|
||||
/* .maxMeshWorkGroupSizeZ_NV = */ 1,
|
||||
/* .maxTaskWorkGroupSizeX_NV = */ 32,
|
||||
/* .maxTaskWorkGroupSizeY_NV = */ 1,
|
||||
/* .maxTaskWorkGroupSizeZ_NV = */ 1,
|
||||
/* .maxMeshViewCountNV = */ 4,
|
||||
/* .maxDualSourceDrawBuffersEXT = */ 4,
|
||||
|
||||
/* .limits = */ TLimits{
|
||||
/* .nonInductiveForLoops = */ true,
|
||||
/* .whileLoops = */ true,
|
||||
/* .doWhileLoops = */ true,
|
||||
/* .generalUniformIndexing = */ true,
|
||||
/* .generalAttributeMatrixVectorIndexing = */ true,
|
||||
/* .generalVaryingIndexing = */ true,
|
||||
/* .generalSamplerIndexing = */ true,
|
||||
/* .generalVariableIndexing = */ true,
|
||||
/* .generalConstantMatrixVectorIndexing = */ true,
|
||||
}};
|
|
@ -43,8 +43,6 @@
|
|||
|
||||
#include <glslang/Public/ShaderLang.h>
|
||||
|
||||
#include "file.hpp"
|
||||
|
||||
// Default include class for normal include convention of search backward
|
||||
// through the stack of active include paths (for nested includes).
|
||||
// Can be overridden to customize.
|
||||
|
@ -136,6 +134,7 @@ protected:
|
|||
// If no path markers, return current working directory.
|
||||
// Otherwise, strip file name and return path leading up to it.
|
||||
virtual std::string getDirectory(const std::string) const {
|
||||
return file::get_domain_path(file::Domain::Internal).string();
|
||||
//return file::get_domain_path(file::Domain::Internal).string();
|
||||
return "";
|
||||
}
|
||||
};
|
117
engine/shadercompiler/src/shadercompiler.cpp
Executable file
117
engine/shadercompiler/src/shadercompiler.cpp
Executable file
|
@ -0,0 +1,117 @@
|
|||
#include "shadercompiler.hpp"
|
||||
|
||||
#include <spirv_cpp.hpp>
|
||||
#include <spirv_msl.hpp>
|
||||
#include <SPIRV/GlslangToSpv.h>
|
||||
|
||||
#include "log.hpp"
|
||||
#include "string_utils.hpp"
|
||||
#include "includer.hpp"
|
||||
#include "defaultresources.hpp"
|
||||
|
||||
static inline std::string include_path;
|
||||
|
||||
ShaderCompiler::ShaderCompiler() {
|
||||
glslang::InitializeProcess();
|
||||
}
|
||||
|
||||
void ShaderCompiler::set_include_path(const std::string_view path) {
|
||||
include_path = path;
|
||||
}
|
||||
|
||||
const std::vector<uint32_t> compile_glsl_to_spv(const std::string_view source_string, const EShLanguage shader_language, const CompileOptions& options) {
|
||||
std::string newString = "#version 430 core\n";
|
||||
|
||||
newString += "#extension GL_GOOGLE_include_directive : enable\n";
|
||||
newString += "#extension GL_GOOGLE_cpp_style_line_directive : enable\n";
|
||||
|
||||
for(auto& definition : options.definitions)
|
||||
newString += "#define " + definition + "\n";
|
||||
|
||||
newString += "#line 1\n";
|
||||
|
||||
newString += source_string;
|
||||
|
||||
const char* InputCString = newString.c_str();
|
||||
|
||||
glslang::TShader Shader(shader_language);
|
||||
|
||||
Shader.setStrings(&InputCString, 1);
|
||||
|
||||
int ClientInputSemanticsVersion = 100; // maps to, say, #define VULKAN 100
|
||||
glslang::EShTargetClientVersion VulkanClientVersion = glslang::EShTargetVulkan_1_1;
|
||||
glslang::EShTargetLanguageVersion TargetVersion = glslang::EShTargetSpv_1_0;
|
||||
|
||||
Shader.setEnvInput(glslang::EShSourceGlsl, shader_language, glslang::EShClientVulkan, ClientInputSemanticsVersion);
|
||||
Shader.setEnvClient(glslang::EShClientVulkan, VulkanClientVersion);
|
||||
Shader.setEnvTarget(glslang::EShTargetSpv, TargetVersion);
|
||||
|
||||
TBuiltInResource Resources = DefaultTBuiltInResource;
|
||||
EShMessages messages = (EShMessages) (EShMsgSpvRules);
|
||||
|
||||
DirStackFileIncluder includer;
|
||||
includer.pushExternalLocalDirectory(include_path);
|
||||
|
||||
if (!Shader.parse(&Resources, 100, false, (EShMessages)0, includer)) {
|
||||
console::error(System::Renderer, "{}", Shader.getInfoLog());
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
glslang::TProgram Program;
|
||||
Program.addShader(&Shader);
|
||||
|
||||
if(!Program.link(messages)) {
|
||||
console::error(System::None, "Failed to link shader: {} {} {}", source_string.data(), Shader.getInfoLog(), Shader.getInfoDebugLog());
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<unsigned int> SpirV;
|
||||
spv::SpvBuildLogger logger;
|
||||
glslang::SpvOptions spvOptions;
|
||||
glslang::GlslangToSpv(*Program.getIntermediate(shader_language), SpirV, &logger, &spvOptions);
|
||||
|
||||
return SpirV;
|
||||
}
|
||||
|
||||
std::optional<ShaderSource> ShaderCompiler::compile(const ShaderLanguage from_language, const ShaderStage shader_stage, const ShaderSource& shader_source, const ShaderLanguage to_language, const CompileOptions& options) {
|
||||
if(from_language != ShaderLanguage::GLSL) {
|
||||
console::error(System::Renderer, "Non-supported input language!");
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
EShLanguage lang = EShLangMiss;
|
||||
switch(shader_stage) {
|
||||
case ShaderStage::Vertex:
|
||||
lang = EShLangVertex;
|
||||
break;
|
||||
case ShaderStage::Fragment:
|
||||
lang = EShLangFragment;
|
||||
break;
|
||||
}
|
||||
|
||||
auto spirv = compile_glsl_to_spv(shader_source.as_string(), lang, options);
|
||||
if(spirv.empty()) {
|
||||
console::error(System::Renderer, "SPIRV generation failed!");
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
#ifdef PLATFORM_MACOS
|
||||
spirv_cross::CompilerMSL msl(std::move(spirv));
|
||||
|
||||
spirv_cross::CompilerMSL::Options opts;
|
||||
if(options.is_apple_mobile) {
|
||||
opts.platform = spirv_cross::CompilerMSL::Options::Platform::macOS;
|
||||
} else {
|
||||
opts.platform = spirv_cross::CompilerMSL::Options::Platform::iOS;
|
||||
}
|
||||
opts.enable_decoration_binding = true;
|
||||
|
||||
msl.set_msl_options(opts);
|
||||
|
||||
return msl.compile();
|
||||
#else
|
||||
return spirv;
|
||||
#endif
|
||||
}
|
|
@ -8,7 +8,7 @@
|
|||
#include "gfx.hpp"
|
||||
#include "asset.hpp"
|
||||
#include "log.hpp"
|
||||
#include "shadercompiler.hpp"
|
||||
#include "materialcompiler.hpp"
|
||||
|
||||
struct BillPushConstant {
|
||||
Matrix4x4 view, mvp;
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
add_executable(ShaderCompiler main.cpp)
|
||||
target_link_libraries(ShaderCompiler
|
||||
PUBLIC
|
||||
${CROSS_LIBS}
|
||||
Log)
|
||||
set_engine_properties(ShaderCompiler)
|
||||
set_output_dir(ShaderCompiler)
|
||||
add_executable(ShaderCompilerTool main.cpp)
|
||||
target_link_libraries(ShaderCompilerTool
|
||||
PRIVATE
|
||||
ShaderCompiler
|
||||
Log
|
||||
Utility)
|
||||
set_engine_properties(ShaderCompilerTool)
|
||||
set_output_dir(ShaderCompilerTool)
|
||||
|
|
|
@ -1,236 +1,86 @@
|
|||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
#include <spirv_cpp.hpp>
|
||||
#include <spirv_msl.hpp>
|
||||
#include <glslang/Public/ShaderLang.h>
|
||||
#include <SPIRV/GlslangToSpv.h>
|
||||
|
||||
#include "DirStackIncluder.h"
|
||||
#include "shadercompiler.hpp"
|
||||
#include "log.hpp"
|
||||
#include "string_utils.hpp"
|
||||
|
||||
const TBuiltInResource DefaultTBuiltInResource = {
|
||||
/* .MaxLights = */ 32,
|
||||
/* .MaxClipPlanes = */ 6,
|
||||
/* .MaxTextureUnits = */ 32,
|
||||
/* .MaxTextureCoords = */ 32,
|
||||
/* .MaxVertexAttribs = */ 64,
|
||||
/* .MaxVertexUniformComponents = */ 4096,
|
||||
/* .MaxVaryingFloats = */ 64,
|
||||
/* .MaxVertexTextureImageUnits = */ 32,
|
||||
/* .MaxCombinedTextureImageUnits = */ 80,
|
||||
/* .MaxTextureImageUnits = */ 32,
|
||||
/* .MaxFragmentUniformComponents = */ 4096,
|
||||
/* .MaxDrawBuffers = */ 32,
|
||||
/* .MaxVertexUniformVectors = */ 128,
|
||||
/* .MaxVaryingVectors = */ 8,
|
||||
/* .MaxFragmentUniformVectors = */ 16,
|
||||
/* .MaxVertexOutputVectors = */ 16,
|
||||
/* .MaxFragmentInputVectors = */ 15,
|
||||
/* .MinProgramTexelOffset = */ -8,
|
||||
/* .MaxProgramTexelOffset = */ 7,
|
||||
/* .MaxClipDistances = */ 8,
|
||||
/* .MaxComputeWorkGroupCountX = */ 65535,
|
||||
/* .MaxComputeWorkGroupCountY = */ 65535,
|
||||
/* .MaxComputeWorkGroupCountZ = */ 65535,
|
||||
/* .MaxComputeWorkGroupSizeX = */ 1024,
|
||||
/* .MaxComputeWorkGroupSizeY = */ 1024,
|
||||
/* .MaxComputeWorkGroupSizeZ = */ 64,
|
||||
/* .MaxComputeUniformComponents = */ 1024,
|
||||
/* .MaxComputeTextureImageUnits = */ 16,
|
||||
/* .MaxComputeImageUniforms = */ 8,
|
||||
/* .MaxComputeAtomicCounters = */ 8,
|
||||
/* .MaxComputeAtomicCounterBuffers = */ 1,
|
||||
/* .MaxVaryingComponents = */ 60,
|
||||
/* .MaxVertexOutputComponents = */ 64,
|
||||
/* .MaxGeometryInputComponents = */ 64,
|
||||
/* .MaxGeometryOutputComponents = */ 128,
|
||||
/* .MaxFragmentInputComponents = */ 128,
|
||||
/* .MaxImageUnits = */ 8,
|
||||
/* .MaxCombinedImageUnitsAndFragmentOutputs = */ 8,
|
||||
/* .MaxCombinedShaderOutputResources = */ 8,
|
||||
/* .MaxImageSamples = */ 0,
|
||||
/* .MaxVertexImageUniforms = */ 0,
|
||||
/* .MaxTessControlImageUniforms = */ 0,
|
||||
/* .MaxTessEvaluationImageUniforms = */ 0,
|
||||
/* .MaxGeometryImageUniforms = */ 0,
|
||||
/* .MaxFragmentImageUniforms = */ 8,
|
||||
/* .MaxCombinedImageUniforms = */ 8,
|
||||
/* .MaxGeometryTextureImageUnits = */ 16,
|
||||
/* .MaxGeometryOutputVertices = */ 256,
|
||||
/* .MaxGeometryTotalOutputComponents = */ 1024,
|
||||
/* .MaxGeometryUniformComponents = */ 1024,
|
||||
/* .MaxGeometryVaryingComponents = */ 64,
|
||||
/* .MaxTessControlInputComponents = */ 128,
|
||||
/* .MaxTessControlOutputComponents = */ 128,
|
||||
/* .MaxTessControlTextureImageUnits = */ 16,
|
||||
/* .MaxTessControlUniformComponents = */ 1024,
|
||||
/* .MaxTessControlTotalOutputComponents = */ 4096,
|
||||
/* .MaxTessEvaluationInputComponents = */ 128,
|
||||
/* .MaxTessEvaluationOutputComponents = */ 128,
|
||||
/* .MaxTessEvaluationTextureImageUnits = */ 16,
|
||||
/* .MaxTessEvaluationUniformComponents = */ 1024,
|
||||
/* .MaxTessPatchComponents = */ 120,
|
||||
/* .MaxPatchVertices = */ 32,
|
||||
/* .MaxTessGenLevel = */ 64,
|
||||
/* .MaxViewports = */ 16,
|
||||
/* .MaxVertexAtomicCounters = */ 0,
|
||||
/* .MaxTessControlAtomicCounters = */ 0,
|
||||
/* .MaxTessEvaluationAtomicCounters = */ 0,
|
||||
/* .MaxGeometryAtomicCounters = */ 0,
|
||||
/* .MaxFragmentAtomicCounters = */ 8,
|
||||
/* .MaxCombinedAtomicCounters = */ 8,
|
||||
/* .MaxAtomicCounterBindings = */ 1,
|
||||
/* .MaxVertexAtomicCounterBuffers = */ 0,
|
||||
/* .MaxTessControlAtomicCounterBuffers = */ 0,
|
||||
/* .MaxTessEvaluationAtomicCounterBuffers = */ 0,
|
||||
/* .MaxGeometryAtomicCounterBuffers = */ 0,
|
||||
/* .MaxFragmentAtomicCounterBuffers = */ 1,
|
||||
/* .MaxCombinedAtomicCounterBuffers = */ 1,
|
||||
/* .MaxAtomicCounterBufferSize = */ 16384,
|
||||
/* .MaxTransformFeedbackBuffers = */ 4,
|
||||
/* .MaxTransformFeedbackInterleavedComponents = */ 64,
|
||||
/* .MaxCullDistances = */ 8,
|
||||
/* .MaxCombinedClipAndCullDistances = */ 8,
|
||||
/* .MaxSamples = */ 4,
|
||||
/* .maxMeshOutputVerticesNV = */ 256,
|
||||
/* .maxMeshOutputPrimitivesNV = */ 512,
|
||||
/* .maxMeshWorkGroupSizeX_NV = */ 32,
|
||||
/* .maxMeshWorkGroupSizeY_NV = */ 1,
|
||||
/* .maxMeshWorkGroupSizeZ_NV = */ 1,
|
||||
/* .maxTaskWorkGroupSizeX_NV = */ 32,
|
||||
/* .maxTaskWorkGroupSizeY_NV = */ 1,
|
||||
/* .maxTaskWorkGroupSizeZ_NV = */ 1,
|
||||
/* .maxMeshViewCountNV = */ 4,
|
||||
/* .maxDualSourceDrawBuffersEXT = */ 4,
|
||||
|
||||
/* .limits = */ TLimits{
|
||||
/* .nonInductiveForLoops = */ true,
|
||||
/* .whileLoops = */ true,
|
||||
/* .doWhileLoops = */ true,
|
||||
/* .generalUniformIndexing = */ true,
|
||||
/* .generalAttributeMatrixVectorIndexing = */ true,
|
||||
/* .generalVaryingIndexing = */ true,
|
||||
/* .generalSamplerIndexing = */ true,
|
||||
/* .generalVariableIndexing = */ true,
|
||||
/* .generalConstantMatrixVectorIndexing = */ true,
|
||||
}};
|
||||
|
||||
const std::vector<unsigned int> CompileGLSL(const std::string& filename, EShLanguage ShaderType) {
|
||||
std::string newString = "#version 430 core\n";
|
||||
|
||||
newString += "#extension GL_GOOGLE_include_directive : enable\n";
|
||||
newString += "#extension GL_GOOGLE_cpp_style_line_directive : enable\n";
|
||||
|
||||
newString += "#line 1\n";
|
||||
|
||||
newString += filename;
|
||||
|
||||
const char* InputCString = newString.c_str();
|
||||
|
||||
glslang::TShader Shader(ShaderType);
|
||||
|
||||
Shader.setStrings(&InputCString, 1);
|
||||
|
||||
int ClientInputSemanticsVersion = 100; // maps to, say, #define VULKAN 100
|
||||
glslang::EShTargetClientVersion VulkanClientVersion = glslang::EShTargetVulkan_1_1;
|
||||
glslang::EShTargetLanguageVersion TargetVersion = glslang::EShTargetSpv_1_0;
|
||||
|
||||
Shader.setEnvInput(glslang::EShSourceGlsl, ShaderType, glslang::EShClientVulkan, ClientInputSemanticsVersion);
|
||||
Shader.setEnvClient(glslang::EShClientVulkan, VulkanClientVersion);
|
||||
Shader.setEnvTarget(glslang::EShTargetSpv, TargetVersion);
|
||||
|
||||
TBuiltInResource Resources = DefaultTBuiltInResource;
|
||||
EShMessages messages = (EShMessages) (EShMsgSpvRules);
|
||||
|
||||
DirStackFileIncluder includer;
|
||||
|
||||
if (!Shader.parse(&Resources, 100, false, messages, includer)) {
|
||||
console::error(System::None, "Failed to parse shader: {} {} {}", filename, Shader.getInfoLog(), Shader.getInfoDebugLog());
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
glslang::TProgram Program;
|
||||
Program.addShader(&Shader);
|
||||
|
||||
if(!Program.link(messages)) {
|
||||
console::error(System::None, "Failed to link shader: {} {} {}", filename, Shader.getInfoLog(), Shader.getInfoDebugLog());
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<unsigned int> SpirV;
|
||||
spv::SpvBuildLogger logger;
|
||||
glslang::SpvOptions spvOptions;
|
||||
glslang::GlslangToSpv(*Program.getIntermediate(ShaderType), SpirV, &logger, &spvOptions);
|
||||
|
||||
return SpirV;
|
||||
bool has_extension(const std::filesystem::path path, const std::string_view extension) {
|
||||
return string_contains(path.filename().string(), extension);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if(argc < 2)
|
||||
if(argc < 2) {
|
||||
console::error(System::Core, "Not enough arguments!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
glslang::InitializeProcess();
|
||||
shader_compiler.set_include_path(std::filesystem::current_path().string());
|
||||
|
||||
std::ifstream t(argv[1]);
|
||||
std::filesystem::path source_path = argv[1];
|
||||
std::filesystem::path destination_path = argv[2];
|
||||
|
||||
std::ifstream t(source_path);
|
||||
std::stringstream buffer;
|
||||
buffer << t.rdbuf();
|
||||
|
||||
if(std::string(argv[1]).find("nocompile") != std::string::npos) {
|
||||
if(has_extension(source_path, "nocompile")) {
|
||||
std::string outname = argv[2];
|
||||
outname = outname.substr(0, outname.length() - 5); // remove .glsl
|
||||
outname = outname.substr(0, outname.length() - 10); // remove .nocompile
|
||||
|
||||
std::ofstream out(outname + ".glsl");
|
||||
out << buffer.rdbuf();
|
||||
|
||||
console::info(System::Core, "Successfully written {} to {}.", source_path, destination_path);
|
||||
|
||||
return 0;
|
||||
} else {
|
||||
EShLanguage lang;
|
||||
if (std::string(argv[1]).find("vert") != std::string::npos) {
|
||||
lang = EShLangVertex;
|
||||
}
|
||||
else {
|
||||
lang = EShLangFragment;
|
||||
ShaderStage stage;
|
||||
if(has_extension(source_path, ".vert"))
|
||||
stage = ShaderStage::Vertex;
|
||||
else
|
||||
stage = ShaderStage::Fragment;
|
||||
|
||||
ShaderLanguage language;
|
||||
CompileOptions options;
|
||||
#ifdef PLATFORM_MACOS
|
||||
options.is_apple_mobile = (bool)argv[3];
|
||||
|
||||
language = ShaderLanguage::MSL;
|
||||
destination_path.replace_extension(".msl");
|
||||
#else
|
||||
language = ShaderLanguage::SPIRV;
|
||||
destination_path.replace_extension(".spv");
|
||||
#endif
|
||||
|
||||
const auto compiled_source = shader_compiler.compile(ShaderLanguage::GLSL, stage, buffer.str(), language, options);
|
||||
if(!compiled_source.has_value()) {
|
||||
console::error(System::Core, "Error when compiling {}!", source_path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::string outname = argv[2];
|
||||
outname = outname.substr(0, outname.length() - 5);
|
||||
switch(language) {
|
||||
case ShaderLanguage::SPIRV:
|
||||
{
|
||||
const auto spirv = compiled_source->as_bytecode();
|
||||
|
||||
// generate msl
|
||||
#ifdef PLATFORM_MACOS
|
||||
bool is_ios = (bool)argv[3];
|
||||
|
||||
{
|
||||
auto vertexSPIRV = CompileGLSL(buffer.str(), lang);
|
||||
if (vertexSPIRV.size() == 0)
|
||||
return -1;
|
||||
|
||||
spirv_cross::CompilerMSL msl(std::move(vertexSPIRV));
|
||||
|
||||
spirv_cross::CompilerMSL::Options opts;
|
||||
opts.platform = is_ios ? spirv_cross::CompilerMSL::Options::Platform::iOS : spirv_cross::CompilerMSL::Options::Platform::macOS;
|
||||
opts.enable_decoration_binding = true;
|
||||
|
||||
msl.set_msl_options(opts);
|
||||
|
||||
std::string s = msl.compile();
|
||||
|
||||
std::ofstream out(outname + ".msl"); // remove .glsl
|
||||
out << s;
|
||||
std::ofstream out(destination_path, std::ios::binary); // remove .glsl
|
||||
out.write((char*)spirv.data(), spirv.size() * sizeof(uint32_t));
|
||||
}
|
||||
break;
|
||||
case ShaderLanguage::MSL:
|
||||
{
|
||||
std::ofstream out(destination_path); // remove .glsl
|
||||
out << compiled_source->as_string();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#else
|
||||
// generate spv
|
||||
{
|
||||
auto vertexSPIRV = CompileGLSL(buffer.str(), lang);
|
||||
if (vertexSPIRV.size() == 0)
|
||||
return -1;
|
||||
|
||||
std::ofstream out(outname + ".spv", std::ios::binary); // remove .glsl
|
||||
out.write((char*)vertexSPIRV.data(), vertexSPIRV.size() * sizeof(uint32_t));
|
||||
}
|
||||
#endif
|
||||
console::info(System::Core, "Successfully written shader from {} to {}.", source_path, destination_path);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Reference in a new issue