mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-12 06:08:30 +09:00
[Feat] (MG_Util/ShaderTranspiler): Implement simple shader compile
This commit is contained in:
+4
-1
@@ -4,7 +4,7 @@ project("MobileGL")
|
|||||||
|
|
||||||
enable_language(CXX)
|
enable_language(CXX)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 20)
|
set(CMAKE_CXX_STANDARD 23)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
@@ -21,6 +21,7 @@ add_library(${CMAKE_PROJECT_NAME} SHARED
|
|||||||
|
|
||||||
MobileGL/MG_Util/Converters/GLToStr/GLEnumConverter.cpp
|
MobileGL/MG_Util/Converters/GLToStr/GLEnumConverter.cpp
|
||||||
MobileGL/MG_Util/Converters/MGToStr/GLExtensionConverter.cpp
|
MobileGL/MG_Util/Converters/MGToStr/GLExtensionConverter.cpp
|
||||||
|
MobileGL/MG_Util/Converters/GLToGlslang/GLShaderLangConverter.cpp
|
||||||
|
|
||||||
MobileGL/MG_Impl/GLXImpl/Exporting/Definitions.cpp
|
MobileGL/MG_Impl/GLXImpl/Exporting/Definitions.cpp
|
||||||
MobileGL/MG_Impl/GLXImpl/LookUp/LookUp.cpp
|
MobileGL/MG_Impl/GLXImpl/LookUp/LookUp.cpp
|
||||||
@@ -36,6 +37,8 @@ add_library(${CMAKE_PROJECT_NAME} SHARED
|
|||||||
MobileGL/MG_Util/Pipelines/ShaderCompilationPipeline.cpp
|
MobileGL/MG_Util/Pipelines/ShaderCompilationPipeline.cpp
|
||||||
MobileGL/MG_Util/Pipelines/ProgramLinkingPipeline.cpp
|
MobileGL/MG_Util/Pipelines/ProgramLinkingPipeline.cpp
|
||||||
|
|
||||||
|
MobileGL/MG_Util/ShaderTranspiler/ShaderCompiler.cpp
|
||||||
|
|
||||||
MobileGL/MG_State/GLState/Core.cpp
|
MobileGL/MG_State/GLState/Core.cpp
|
||||||
MobileGL/MG_State/GLState/BufferState/BufferState.cpp
|
MobileGL/MG_State/GLState/BufferState/BufferState.cpp
|
||||||
)
|
)
|
||||||
|
|||||||
+7
-2
@@ -41,7 +41,9 @@
|
|||||||
#include <queue>
|
#include <queue>
|
||||||
#include <format>
|
#include <format>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <bit>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <expected>
|
||||||
|
|
||||||
#include <glslang/Public/ShaderLang.h>
|
#include <glslang/Public/ShaderLang.h>
|
||||||
#include <glslang/Include/Types.h>
|
#include <glslang/Include/Types.h>
|
||||||
@@ -97,6 +99,7 @@ int __android_log_print(int prio, const char *tag, const char *fmt, ...);
|
|||||||
#include "MG_Util/Debug/Log.h"
|
#include "MG_Util/Debug/Log.h"
|
||||||
#include "MG_Util/Converters/GLToStr/GLEnumConverter.h"
|
#include "MG_Util/Converters/GLToStr/GLEnumConverter.h"
|
||||||
#include "MG_Util/Converters/MGToStr/GLExtensionConverter.h"
|
#include "MG_Util/Converters/MGToStr/GLExtensionConverter.h"
|
||||||
|
#include "MG_Util/Converters/GLToGlslang/GLShaderLangConverter.h"
|
||||||
|
|
||||||
#include "MG_Backend/Backends.h"
|
#include "MG_Backend/Backends.h"
|
||||||
|
|
||||||
@@ -107,9 +110,11 @@ int __android_log_print(int prio, const char *tag, const char *fmt, ...);
|
|||||||
|
|
||||||
#include "MG_Impl/GLImpl/Getter/GL_Getter.h"
|
#include "MG_Impl/GLImpl/Getter/GL_Getter.h"
|
||||||
|
|
||||||
#include "MG_Util/Pipelines/PipelineExecutor.hpp"
|
//#include "MG_Util/Pipelines/PipelineExecutor.hpp"
|
||||||
|
|
||||||
#include "MG_Util/Pipelines/ShaderCompilationPipeline.h"
|
//#include "MG_Util/Pipelines/ShaderCompilationPipeline.h"
|
||||||
|
|
||||||
|
#include "MG_Util/ShaderTranspiler/glslang/UniformTraverser.h"
|
||||||
|
|
||||||
#include "MG_State/GLState/BufferState/BufferObject.h"
|
#include "MG_State/GLState/BufferState/BufferObject.h"
|
||||||
#include "MG_State/GLState/BufferState/BufferState.h"
|
#include "MG_State/GLState/BufferState/BufferState.h"
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
cmake_minimum_required(VERSION 3.14)
|
cmake_minimum_required(VERSION 3.14)
|
||||||
project(MobileGLTest)
|
project(MobileGLTest)
|
||||||
|
|
||||||
# GoogleTest requires at least C++17
|
set(CMAKE_CXX_STANDARD 23)
|
||||||
set(CMAKE_CXX_STANDARD 20)
|
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
include(FetchContent)
|
include(FetchContent)
|
||||||
@@ -31,4 +30,4 @@ include(GoogleTest)
|
|||||||
gtest_discover_tests(SanityTest)
|
gtest_discover_tests(SanityTest)
|
||||||
|
|
||||||
add_subdirectory(Buffer)
|
add_subdirectory(Buffer)
|
||||||
#add_subdirectory(Program)
|
add_subdirectory(Program)
|
||||||
|
|||||||
@@ -12,8 +12,10 @@ add_executable(
|
|||||||
ProgramTest.cpp
|
ProgramTest.cpp
|
||||||
|
|
||||||
${MGL_ROOT}/MobileGL/MG_Util/Converters/GLToStr/GLEnumConverter.cpp
|
${MGL_ROOT}/MobileGL/MG_Util/Converters/GLToStr/GLEnumConverter.cpp
|
||||||
${MGL_ROOT}/MobileGL/MG_Util/Pipelines/ShaderCompilationPipeline.cpp
|
# ${MGL_ROOT}/MobileGL/MG_Util/Pipelines/ShaderCompilationPipeline.cpp
|
||||||
${MGL_ROOT}/MobileGL/MG_Util/Pipelines/ProgramLinkingPipeline.cpp
|
# ${MGL_ROOT}/MobileGL/MG_Util/Pipelines/ProgramLinkingPipeline.cpp
|
||||||
|
${MGL_ROOT}/MobileGL/MG_Util/Converters/GLToGlslang/GLShaderLangConverter.cpp
|
||||||
|
${MGL_ROOT}/MobileGL/MG_Util/ShaderTranspiler/ShaderCompiler.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_include_directories(ProgramTest PRIVATE
|
target_include_directories(ProgramTest PRIVATE
|
||||||
|
|||||||
@@ -14,3 +14,35 @@ protected:
|
|||||||
TEST_F(ProgramTest, Sanity) {
|
TEST_F(ProgramTest, Sanity) {
|
||||||
ASSERT_TRUE(true);
|
ASSERT_TRUE(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* vs = R"(#version 150
|
||||||
|
|
||||||
|
in vec3 Position;
|
||||||
|
in vec2 UV;
|
||||||
|
in vec4 Color;
|
||||||
|
|
||||||
|
uniform mat4 ModelViewMat;
|
||||||
|
uniform mat4 ProjMat;
|
||||||
|
|
||||||
|
out vec2 texCoord;
|
||||||
|
out vec4 vertexColor;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_Position = ProjMat * ModelViewMat * vec4(Position, 1.0);
|
||||||
|
|
||||||
|
texCoord = UV;
|
||||||
|
vertexColor = Color;
|
||||||
|
})";
|
||||||
|
|
||||||
|
TEST_F(ProgramTest, CompileSimpleVertexShader) {
|
||||||
|
using namespace MG_Util::ShaderTranspiler;
|
||||||
|
ShaderAttrib attrib {
|
||||||
|
.shaderType = GL_VERTEX_SHADER,
|
||||||
|
.sourceStr = vs
|
||||||
|
};
|
||||||
|
auto res = ShaderCompiler::CompileShader(attrib);
|
||||||
|
if (!res) {
|
||||||
|
ASSERT_NE(res.error().errc, 0);
|
||||||
|
FAIL() << "errc: " << res.error().errc << "\nlog: " << res.error().log;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
//
|
||||||
|
// Created by Swung 0x48 on 2025/7/20.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "Includes.h"
|
||||||
|
|
||||||
|
namespace MobileGL {
|
||||||
|
namespace MG_Util {
|
||||||
|
EShLanguage ConvertGLEnumToEShLanguage(GLenum shaderType) {
|
||||||
|
switch (shaderType) {
|
||||||
|
case GL_VERTEX_SHADER:
|
||||||
|
return EShLanguage::EShLangVertex;
|
||||||
|
case GL_FRAGMENT_SHADER:
|
||||||
|
return EShLanguage::EShLangFragment;
|
||||||
|
case GL_COMPUTE_SHADER:
|
||||||
|
return EShLanguage::EShLangCompute;
|
||||||
|
case GL_TESS_CONTROL_SHADER:
|
||||||
|
return EShLanguage::EShLangTessControl;
|
||||||
|
case GL_TESS_EVALUATION_SHADER:
|
||||||
|
return EShLanguage::EShLangTessEvaluation;
|
||||||
|
case GL_GEOMETRY_SHADER:
|
||||||
|
return EShLanguage::EShLangGeometry;
|
||||||
|
default:
|
||||||
|
return EShLanguage::EShLangCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
//
|
||||||
|
// Created by Swung 0x48 on 2025/7/20.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef MOBILEGL_GLSHADERLANGCONVERTER_H
|
||||||
|
#define MOBILEGL_GLSHADERLANGCONVERTER_H
|
||||||
|
|
||||||
|
namespace MobileGL {
|
||||||
|
namespace MG_Util {
|
||||||
|
EShLanguage ConvertGLEnumToEShLanguage(GLenum shaderType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif //MOBILEGL_GLSHADERLANGCONVERTER_H
|
||||||
@@ -0,0 +1,158 @@
|
|||||||
|
//
|
||||||
|
// Created by Swung 0x48 on 2025/7/20.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "Includes.h"
|
||||||
|
|
||||||
|
namespace MobileGL {
|
||||||
|
namespace MG_Util {
|
||||||
|
namespace ShaderTranspiler {
|
||||||
|
TBuiltInResource& GetTBuiltInResourceInstance()
|
||||||
|
{
|
||||||
|
static TBuiltInResource Resources{};
|
||||||
|
Resources.maxLights = 32;
|
||||||
|
Resources.maxClipPlanes = 6;
|
||||||
|
Resources.maxTextureUnits = 32;
|
||||||
|
Resources.maxTextureCoords = 32;
|
||||||
|
Resources.maxVertexAttribs = 64;
|
||||||
|
Resources.maxVertexUniformComponents = 4096;
|
||||||
|
Resources.maxVaryingFloats = 64;
|
||||||
|
Resources.maxVertexTextureImageUnits = 32;
|
||||||
|
Resources.maxCombinedTextureImageUnits = 80;
|
||||||
|
Resources.maxTextureImageUnits = 32;
|
||||||
|
Resources.maxFragmentUniformComponents = 4096;
|
||||||
|
Resources.maxDrawBuffers = 32;
|
||||||
|
Resources.maxVertexUniformVectors = 128;
|
||||||
|
Resources.maxVaryingVectors = 8;
|
||||||
|
Resources.maxFragmentUniformVectors = 16;
|
||||||
|
Resources.maxVertexOutputVectors = 16;
|
||||||
|
Resources.maxFragmentInputVectors = 15;
|
||||||
|
Resources.minProgramTexelOffset = -8;
|
||||||
|
Resources.maxProgramTexelOffset = 7;
|
||||||
|
Resources.maxClipDistances = 8;
|
||||||
|
Resources.maxComputeWorkGroupCountX = 65535;
|
||||||
|
Resources.maxComputeWorkGroupCountY = 65535;
|
||||||
|
Resources.maxComputeWorkGroupCountZ = 65535;
|
||||||
|
Resources.maxComputeWorkGroupSizeX = 1024;
|
||||||
|
Resources.maxComputeWorkGroupSizeY = 1024;
|
||||||
|
Resources.maxComputeWorkGroupSizeZ = 64;
|
||||||
|
Resources.maxComputeUniformComponents = 1024;
|
||||||
|
Resources.maxComputeTextureImageUnits = 16;
|
||||||
|
Resources.maxComputeImageUniforms = 8;
|
||||||
|
Resources.maxComputeAtomicCounters = 8;
|
||||||
|
Resources.maxComputeAtomicCounterBuffers = 1;
|
||||||
|
Resources.maxVaryingComponents = 60;
|
||||||
|
Resources.maxVertexOutputComponents = 64;
|
||||||
|
Resources.maxGeometryInputComponents = 64;
|
||||||
|
Resources.maxGeometryOutputComponents = 128;
|
||||||
|
Resources.maxFragmentInputComponents = 128;
|
||||||
|
Resources.maxImageUnits = 8;
|
||||||
|
Resources.maxCombinedImageUnitsAndFragmentOutputs = 8;
|
||||||
|
Resources.maxCombinedShaderOutputResources = 8;
|
||||||
|
Resources.maxImageSamples = 0;
|
||||||
|
Resources.maxVertexImageUniforms = 0;
|
||||||
|
Resources.maxTessControlImageUniforms = 0;
|
||||||
|
Resources.maxTessEvaluationImageUniforms = 0;
|
||||||
|
Resources.maxGeometryImageUniforms = 0;
|
||||||
|
Resources.maxFragmentImageUniforms = 8;
|
||||||
|
Resources.maxCombinedImageUniforms = 8;
|
||||||
|
Resources.maxGeometryTextureImageUnits = 16;
|
||||||
|
Resources.maxGeometryOutputVertices = 256;
|
||||||
|
Resources.maxGeometryTotalOutputComponents = 1024;
|
||||||
|
Resources.maxGeometryUniformComponents = 1024;
|
||||||
|
Resources.maxGeometryVaryingComponents = 64;
|
||||||
|
Resources.maxTessControlInputComponents = 128;
|
||||||
|
Resources.maxTessControlOutputComponents = 128;
|
||||||
|
Resources.maxTessControlTextureImageUnits = 16;
|
||||||
|
Resources.maxTessControlUniformComponents = 1024;
|
||||||
|
Resources.maxTessControlTotalOutputComponents = 4096;
|
||||||
|
Resources.maxTessEvaluationInputComponents = 128;
|
||||||
|
Resources.maxTessEvaluationOutputComponents = 128;
|
||||||
|
Resources.maxTessEvaluationTextureImageUnits = 16;
|
||||||
|
Resources.maxTessEvaluationUniformComponents = 1024;
|
||||||
|
Resources.maxTessPatchComponents = 120;
|
||||||
|
Resources.maxPatchVertices = 32;
|
||||||
|
Resources.maxTessGenLevel = 64;
|
||||||
|
Resources.maxViewports = 16;
|
||||||
|
Resources.maxVertexAtomicCounters = 0;
|
||||||
|
Resources.maxTessControlAtomicCounters = 0;
|
||||||
|
Resources.maxTessEvaluationAtomicCounters = 0;
|
||||||
|
Resources.maxGeometryAtomicCounters = 0;
|
||||||
|
Resources.maxFragmentAtomicCounters = 8;
|
||||||
|
Resources.maxCombinedAtomicCounters = 8;
|
||||||
|
Resources.maxAtomicCounterBindings = 1;
|
||||||
|
Resources.maxVertexAtomicCounterBuffers = 0;
|
||||||
|
Resources.maxTessControlAtomicCounterBuffers = 0;
|
||||||
|
Resources.maxTessEvaluationAtomicCounterBuffers = 0;
|
||||||
|
Resources.maxGeometryAtomicCounterBuffers = 0;
|
||||||
|
Resources.maxFragmentAtomicCounterBuffers = 1;
|
||||||
|
Resources.maxCombinedAtomicCounterBuffers = 1;
|
||||||
|
Resources.maxAtomicCounterBufferSize = 16384;
|
||||||
|
Resources.maxTransformFeedbackBuffers = 4;
|
||||||
|
Resources.maxTransformFeedbackInterleavedComponents = 64;
|
||||||
|
Resources.maxCullDistances = 8;
|
||||||
|
Resources.maxCombinedClipAndCullDistances = 8;
|
||||||
|
Resources.maxSamples = 4;
|
||||||
|
Resources.maxMeshOutputVerticesNV = 256;
|
||||||
|
Resources.maxMeshOutputPrimitivesNV = 512;
|
||||||
|
Resources.maxMeshWorkGroupSizeX_NV = 32;
|
||||||
|
Resources.maxMeshWorkGroupSizeY_NV = 1;
|
||||||
|
Resources.maxMeshWorkGroupSizeZ_NV = 1;
|
||||||
|
Resources.maxTaskWorkGroupSizeX_NV = 32;
|
||||||
|
Resources.maxTaskWorkGroupSizeY_NV = 1;
|
||||||
|
Resources.maxTaskWorkGroupSizeZ_NV = 1;
|
||||||
|
Resources.maxMeshViewCountNV = 4;
|
||||||
|
|
||||||
|
Resources.limits.nonInductiveForLoops = true;
|
||||||
|
Resources.limits.whileLoops = true;
|
||||||
|
Resources.limits.doWhileLoops = true;
|
||||||
|
Resources.limits.generalUniformIndexing = true;
|
||||||
|
Resources.limits.generalAttributeMatrixVectorIndexing = true;
|
||||||
|
Resources.limits.generalVaryingIndexing = true;
|
||||||
|
Resources.limits.generalSamplerIndexing = true;
|
||||||
|
Resources.limits.generalVariableIndexing = true;
|
||||||
|
Resources.limits.generalConstantMatrixVectorIndexing = true;
|
||||||
|
|
||||||
|
return Resources;
|
||||||
|
}
|
||||||
|
|
||||||
|
CompilerResult ShaderCompiler::CompileShader(const ShaderAttrib& attrib) {
|
||||||
|
auto shaderType = attrib.shaderType;
|
||||||
|
auto sourceStr = attrib.sourceStr;
|
||||||
|
|
||||||
|
auto lang = GetEShLanguageByShaderType(shaderType);
|
||||||
|
if (lang == EShLanguage::EShLangCount) {
|
||||||
|
ShaderCompileResult<false> r;
|
||||||
|
r.log += "Error: [Preprocess] Unsupported shader type: " +
|
||||||
|
ConvertGLEnumToString(shaderType);
|
||||||
|
r.errc = -1;
|
||||||
|
return std::unexpected(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderCompileResult<true> res;
|
||||||
|
auto& tshader = res.TShader;
|
||||||
|
tshader = MakeUnique<glslang::TShader>(lang);
|
||||||
|
const char* src[] = { sourceStr.c_str() };
|
||||||
|
tshader->setStrings(src, 1);
|
||||||
|
tshader->setInvertY(true);
|
||||||
|
tshader->setEnvInput(glslang::EShSourceGlsl, lang, glslang::EShClientVulkan, 450);
|
||||||
|
tshader->setEnvClient(glslang::EShClientOpenGL, glslang::EShTargetOpenGL_450);
|
||||||
|
tshader->setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetSpv_1_6);
|
||||||
|
tshader->setAutoMapLocations(true);
|
||||||
|
tshader->setAutoMapBindings(true);
|
||||||
|
tshader->setEnvInputVulkanRulesRelaxed(); // using EXT_vulkan_glsl_relaxed for gl_VertexID and gl_InstanceID?
|
||||||
|
if (!tshader->parse(&GetTBuiltInResourceInstance(), 150, ECompatibilityProfile,
|
||||||
|
/*forceDefaultVersionAndProfile: */false,
|
||||||
|
/*forwardCompatible: */true, EShMsgDefault)) {
|
||||||
|
ShaderCompileResult<false> r;
|
||||||
|
r.log += "Error: [glslang] Cannot compile " + ConvertGLEnumToString(shaderType) + ":\n"
|
||||||
|
+ std::string(tshader->getInfoLog());
|
||||||
|
r.errc = -2;
|
||||||
|
return std::unexpected(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
//
|
||||||
|
// Created by Swung 0x48 on 2025/7/20.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef MOBILEGLTEST_SHADERCOMPILER_H
|
||||||
|
#define MOBILEGLTEST_SHADERCOMPILER_H
|
||||||
|
|
||||||
|
namespace MobileGL {
|
||||||
|
namespace MG_Util {
|
||||||
|
namespace ShaderTranspiler {
|
||||||
|
class ShaderCompiler {
|
||||||
|
public:
|
||||||
|
static CompilerResult CompileShader(const ShaderAttrib& attrib);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif //MOBILEGLTEST_SHADERCOMPILER_H
|
||||||
@@ -0,0 +1,109 @@
|
|||||||
|
//
|
||||||
|
// Created by Swung 0x48 on 2025/7/20.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef MG_UTIL_SHADERTRANSPILER_TYPES_H
|
||||||
|
#define MG_UTIL_SHADERTRANSPILER_TYPES_H
|
||||||
|
|
||||||
|
namespace MobileGL {
|
||||||
|
namespace MG_Util {
|
||||||
|
namespace ShaderTranspiler {
|
||||||
|
enum class TUniformType {
|
||||||
|
Uniform,
|
||||||
|
Sampler
|
||||||
|
};
|
||||||
|
|
||||||
|
template <TUniformType T>
|
||||||
|
struct TUniform {
|
||||||
|
static_assert(false, "TUniform<T> does not accept this enum");
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct TUniform<TUniformType::Uniform> {
|
||||||
|
String name;
|
||||||
|
|
||||||
|
glslang::TStorageQualifier storageQualifier;
|
||||||
|
Uint layoutLocation = 0;
|
||||||
|
Uint layoutBinding = 0;
|
||||||
|
glslang::TLayoutPacking layoutPacking;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct TUniform<TUniformType::Sampler> {
|
||||||
|
String name;
|
||||||
|
|
||||||
|
glslang::TSampler sampler;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct EmptyType {};
|
||||||
|
|
||||||
|
struct ShaderAttrib {
|
||||||
|
GLenum shaderType;
|
||||||
|
String sourceStr;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CompiledTShader {
|
||||||
|
UniquePtr<glslang::TShader> TShader;
|
||||||
|
Vector<TUniform<TUniformType::Uniform>> uniforms;
|
||||||
|
Vector<TUniform<TUniformType::Sampler>> samplers;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <bool Succeeded>
|
||||||
|
struct ShaderCompileResult:
|
||||||
|
public std::conditional_t<Succeeded, CompiledTShader, EmptyType> {
|
||||||
|
Int errc = 0;
|
||||||
|
String log;
|
||||||
|
};
|
||||||
|
|
||||||
|
using CompilerResult = std::expected<ShaderCompileResult<true>, ShaderCompileResult<false>>;
|
||||||
|
|
||||||
|
struct ShaderPayload {
|
||||||
|
// In
|
||||||
|
GLenum shaderType;
|
||||||
|
String sourceStr;
|
||||||
|
|
||||||
|
// Out
|
||||||
|
UniquePtr<glslang::TShader> TShader;
|
||||||
|
Vector<TUniform<TUniformType::Uniform>> uniforms;
|
||||||
|
Vector<TUniform<TUniformType::Sampler>> samplers;
|
||||||
|
Int errc = 0;
|
||||||
|
String log;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ProgramPayload {
|
||||||
|
// In
|
||||||
|
Vector<GLenum> shaderTypes;
|
||||||
|
Vector<UniquePtr<glslang::TShader>> shadersToLink;
|
||||||
|
|
||||||
|
// Out
|
||||||
|
glslang::TProgram linkedProgram;
|
||||||
|
Vector<Vector<Uint>> programSpirv;
|
||||||
|
Int errc = 0;
|
||||||
|
String log;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline static EShLanguage GetEShLanguageByShaderType(GLenum shaderType) {
|
||||||
|
switch (shaderType) {
|
||||||
|
case GL_VERTEX_SHADER:
|
||||||
|
return EShLanguage::EShLangVertex;
|
||||||
|
case GL_FRAGMENT_SHADER:
|
||||||
|
return EShLanguage::EShLangFragment;
|
||||||
|
case GL_COMPUTE_SHADER:
|
||||||
|
return EShLanguage::EShLangCompute;
|
||||||
|
case GL_TESS_CONTROL_SHADER:
|
||||||
|
return EShLanguage::EShLangTessControl;
|
||||||
|
case GL_TESS_EVALUATION_SHADER:
|
||||||
|
return EShLanguage::EShLangTessEvaluation;
|
||||||
|
case GL_GEOMETRY_SHADER:
|
||||||
|
return EShLanguage::EShLangGeometry;
|
||||||
|
default:
|
||||||
|
return EShLanguage::EShLangCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "ShaderCompiler.h"
|
||||||
|
|
||||||
|
#endif //MG_UTIL_SHADERTRANSPILER_TYPES_H
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
//
|
||||||
|
// Created by Swung 0x48 on 2025/7/20.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "Includes.h"
|
||||||
|
|
||||||
|
namespace MobileGL {
|
||||||
|
namespace MG_Util {
|
||||||
|
namespace ShaderTranspiler {
|
||||||
|
void UniformTraverser::visitSymbol(glslang::TIntermSymbol *symbol) {
|
||||||
|
const auto &type = symbol->getType();
|
||||||
|
if (symbol->getQualifier().isUniform()) {
|
||||||
|
auto name = symbol->getName();
|
||||||
|
auto qualifier = symbol->getQualifier();
|
||||||
|
|
||||||
|
auto &uniform = uniforms.emplace_back();
|
||||||
|
uniform.name = name;
|
||||||
|
uniform.storageQualifier = qualifier.storage;
|
||||||
|
uniform.layoutLocation = qualifier.layoutLocation;
|
||||||
|
uniform.layoutBinding = qualifier.layoutBinding;
|
||||||
|
uniform.layoutPacking = qualifier.layoutPacking;
|
||||||
|
} else if (type.getBasicType() == glslang::EbtSampler) {
|
||||||
|
auto &uniform = samplers.emplace_back();
|
||||||
|
uniform.name = symbol->getName();
|
||||||
|
uniform.sampler = type.getSampler();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
//
|
||||||
|
// Created by Swung 0x48 on 2025/7/20.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef MOBILEGL_UNIFORMTRAVERSER_H
|
||||||
|
#define MOBILEGL_UNIFORMTRAVERSER_H
|
||||||
|
|
||||||
|
namespace MobileGL {
|
||||||
|
namespace MG_Util {
|
||||||
|
namespace ShaderTranspiler {
|
||||||
|
class UniformTraverser : public glslang::TIntermTraverser {
|
||||||
|
public:
|
||||||
|
UniformTraverser(Vector<TUniform<TUniformType::Uniform>> &u, Vector<TUniform<TUniformType::Sampler>> &s)
|
||||||
|
: uniforms(u), samplers(s) {}
|
||||||
|
|
||||||
|
void visitSymbol(glslang::TIntermSymbol *symbol) override;
|
||||||
|
|
||||||
|
Vector<TUniform<TUniformType::Uniform>> &uniforms;
|
||||||
|
Vector<TUniform<TUniformType::Sampler>> &samplers;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //MOBILEGL_UNIFORMTRAVERSER_H
|
||||||
@@ -162,4 +162,4 @@ namespace MobileGL {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "Pipelines/Types.h"
|
#include "MG_Util/ShaderTranspiler/Types.h"
|
||||||
|
|||||||
Reference in New Issue
Block a user