diff --git a/backends/CMakeLists.txt b/backends/CMakeLists.txt index a1dc6f7..1decac4 100644 --- a/backends/CMakeLists.txt +++ b/backends/CMakeLists.txt @@ -86,12 +86,5 @@ else() spirv-cross-msl spirv-cross-reflect spirv-cross-util - glslang - glslang-default-resource-limits - #OGLCompiler - OSDependent - SPIRV - #SPVRemapper - #HLSL ) endif() diff --git a/backends/README.md b/backends/README.md new file mode 100644 index 0000000..76d3a55 --- /dev/null +++ b/backends/README.md @@ -0,0 +1,24 @@ +# Backends + +- [Graphics](#graphics) + - [OpenGL2](#opengl2-legacy) + - [OpenGL3](#opengl3-modern-opengl) + - [DirectX9](#directx9-could-potentially-cover-more-then-opengl2) + - [Citro3D](#citro3d-3ds) + +## Graphics + +### OpenGL2 (Legacy) + +> [!NOTE] +> As SPIRV to GLSL 120 translation doesn't work, your'e forced to write separate shaders for this backend + +### OpenGL3+ (Modern OpenGL) + +### DirectX9 (Could potentially cover more than OpenGL2) + +### Citro3D (3DS) + +> [!NOTE] +> This backend requires shaders as binary file, directly in the code or as string for libpicasso +> The Fragment Stage is special and is still wip diff --git a/backends/include/pd_system/gfx_opengl2.hpp b/backends/include/pd_system/gfx_opengl2.hpp index c718d2c..7423093 100644 --- a/backends/include/pd_system/gfx_opengl2.hpp +++ b/backends/include/pd_system/gfx_opengl2.hpp @@ -39,5 +39,7 @@ class GfxOpenGL2 : public GfxDriverBase { int pLocTex = 0; int pLocAlfa = 0; int pLocProjection = 0; + static const char* pVertCode; + static const char* pFragCode; }; } // namespace PD \ No newline at end of file diff --git a/backends/include/pd_system/shaders.hpp b/backends/include/pd_system/shaders.hpp index 9b1a292..75be486 100644 --- a/backends/include/pd_system/shaders.hpp +++ b/backends/include/pd_system/shaders.hpp @@ -1,51 +1,17 @@ #pragma once namespace PD { +/** + * Shader blobs + * Required for OpenGL3, and maybe later for vulkan + * Shaders can be found in /tools/pdsg/shaders + */ namespace Shaders { -inline static const char* VertCode = R"( - #version 460 - - layout(location = 0) in vec2 pos; - layout(location = 1) in vec2 uv; - layout(location = 2) in vec4 color; - - layout(location = 0) out vec2 oUV; - layout(location = 1) out vec4 oColor; - - // Probably forgot about this matrix and - // searched hours for why the rendering isn't working :/ - layout(set = 0, binding = 0) uniform UBO { - mat4 projection; - } ubo; - - void main() { - gl_Position = ubo.projection*vec4(pos, 0.0, 1.0); - oUV = uv; - oColor = color; - } - )"; - -inline static const char* FragCode = R"( - #version 460 - - layout(location = 0) in vec2 oUV; - layout(location = 1) in vec4 oColor; - - uniform sampler2D tex; - layout(push_constant) uniform PushData { - int alfa; - } push; - - out vec4 FragColor; - - void main() { - vec4 tc = texture(tex, oUV); - if (push.alfa != 0) { - FragColor = vec4(oColor.rgb, tc.a * oColor.a); - } else { - FragColor = tc * oColor; - } - } - )"; +// clang-format off +const unsigned int VertexShader[] = { 0x7230203, 0x10000, 0x8000B, 0x2B, 0x0, 0x20011, 0x1, 0x6000B, 0x1, 0x4C534C47, 0x6474732E, 0x3035342E, 0x0, 0x3000E, 0x0, 0x1, 0xB000F, 0x0, 0x4, 0x6E69616D, 0x0, 0xD, 0x19, 0x24, 0x25, 0x27, 0x29, 0x30003, 0x2, 0x1CC, 0x40005, 0x4, 0x6E69616D, 0x0, 0x60005, 0xB, 0x505F6C67, 0x65567265, 0x78657472, 0x0, 0x60006, 0xB, 0x0, 0x505F6C67, 0x7469736F, 0x6E6F69, 0x70006, 0xB, 0x1, 0x505F6C67, 0x746E696F, 0x657A6953, 0x0, 0x70006, 0xB, 0x2, 0x435F6C67, 0x4470696C, 0x61747369, 0x65636E, 0x70006, 0xB, 0x3, 0x435F6C67, 0x446C6C75, 0x61747369, 0x65636E, 0x30005, 0xD, 0x0, 0x30005, 0x11, 0x4F4255, 0x60006, 0x11, 0x0, 0x6A6F7270, 0x69746365, 0x6E6F, 0x30005, 0x13, 0x6F6275, 0x30005, 0x19, 0x736F70, 0x30005, 0x24, 0x56556F, 0x30005, 0x25, 0x7675, 0x40005, 0x27, 0x6C6F436F, 0x726F, 0x40005, 0x29, 0x6F6C6F63, 0x72, 0x30047, 0xB, 0x2, 0x50048, 0xB, 0x0, 0xB, 0x0, 0x50048, 0xB, 0x1, 0xB, 0x1, 0x50048, 0xB, 0x2, 0xB, 0x3, 0x50048, 0xB, 0x3, 0xB, 0x4, 0x30047, 0x11, 0x2, 0x40048, 0x11, 0x0, 0x5, 0x50048, 0x11, 0x0, 0x7, 0x10, 0x50048, 0x11, 0x0, 0x23, 0x0, 0x40047, 0x13, 0x21, 0x0, 0x40047, 0x13, 0x22, 0x0, 0x40047, 0x19, 0x1E, 0x0, 0x40047, 0x24, 0x1E, 0x0, 0x40047, 0x25, 0x1E, 0x1, 0x40047, 0x27, 0x1E, 0x1, 0x40047, 0x29, 0x1E, 0x2, 0x20013, 0x2, 0x30021, 0x3, 0x2, 0x30016, 0x6, 0x20, 0x40017, 0x7, 0x6, 0x4, 0x40015, 0x8, 0x20, 0x0, 0x4002B, 0x8, 0x9, 0x1, 0x4001C, 0xA, 0x6, 0x9, 0x6001E, 0xB, 0x7, 0x6, 0xA, 0xA, 0x40020, 0xC, 0x3, 0xB, 0x4003B, 0xC, 0xD, 0x3, 0x40015, 0xE, 0x20, 0x1, 0x4002B, 0xE, 0xF, 0x0, 0x40018, 0x10, 0x7, 0x4, 0x3001E, 0x11, 0x10, 0x40020, 0x12, 0x2, 0x11, 0x4003B, 0x12, 0x13, 0x2, 0x40020, 0x14, 0x2, 0x10, 0x40017, 0x17, 0x6, 0x2, 0x40020, 0x18, 0x1, 0x17, 0x4003B, 0x18, 0x19, 0x1, 0x4002B, 0x6, 0x1B, 0x0, 0x4002B, 0x6, 0x1C, 0x3F800000, 0x40020, 0x21, 0x3, 0x7, 0x40020, 0x23, 0x3, 0x17, 0x4003B, 0x23, 0x24, 0x3, 0x4003B, 0x18, 0x25, 0x1, 0x4003B, 0x21, 0x27, 0x3, 0x40020, 0x28, 0x1, 0x7, 0x4003B, 0x28, 0x29, 0x1, 0x50036, 0x2, 0x4, 0x0, 0x3, 0x200F8, 0x5, 0x50041, 0x14, 0x15, 0x13, 0xF, 0x4003D, 0x10, 0x16, 0x15, 0x4003D, 0x17, 0x1A, 0x19, 0x50051, 0x6, 0x1D, 0x1A, 0x0, 0x50051, 0x6, 0x1E, 0x1A, 0x1, 0x70050, 0x7, 0x1F, 0x1D, 0x1E, 0x1B, 0x1C, 0x50091, 0x7, 0x20, 0x16, 0x1F, 0x50041, 0x21, 0x22, 0xD, 0xF, 0x3003E, 0x22, 0x20, 0x4003D, 0x17, 0x26, 0x25, 0x3003E, 0x24, 0x26, 0x4003D, 0x7, 0x2A, 0x29, 0x3003E, 0x27, 0x2A, 0x100FD, 0x10038, }; +// clang-format on +// clang-format off +const unsigned int FragmentShader[] = { 0x7230203, 0x10000, 0x8000B, 0x39, 0x0, 0x20011, 0x1, 0x6000B, 0x1, 0x4C534C47, 0x6474732E, 0x3035342E, 0x0, 0x3000E, 0x0, 0x1, 0x8000F, 0x0, 0x4, 0x6E69616D, 0x0, 0x11, 0x22, 0x24, 0x30003, 0x2, 0x1CC, 0x40005, 0x4, 0x6E69616D, 0x0, 0x30005, 0x9, 0x6374, 0x30005, 0xD, 0x786574, 0x30005, 0x11, 0x56556F, 0x50005, 0x16, 0x68737550, 0x61746144, 0x0, 0x50006, 0x16, 0x0, 0x61666C61, 0x0, 0x40005, 0x18, 0x68737570, 0x0, 0x50005, 0x22, 0x67617246, 0x6F6C6F43, 0x72, 0x40005, 0x24, 0x6C6F436F, 0x726F, 0x40047, 0xD, 0x21, 0x0, 0x40047, 0xD, 0x22, 0x0, 0x40047, 0x11, 0x1E, 0x0, 0x30047, 0x16, 0x2, 0x50048, 0x16, 0x0, 0x23, 0x0, 0x40047, 0x24, 0x1E, 0x1, 0x20013, 0x2, 0x30021, 0x3, 0x2, 0x30016, 0x6, 0x20, 0x40017, 0x7, 0x6, 0x4, 0x40020, 0x8, 0x7, 0x7, 0x90019, 0xA, 0x6, 0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x3001B, 0xB, 0xA, 0x40020, 0xC, 0x0, 0xB, 0x4003B, 0xC, 0xD, 0x0, 0x40017, 0xF, 0x6, 0x2, 0x40020, 0x10, 0x1, 0xF, 0x4003B, 0x10, 0x11, 0x1, 0x4002B, 0x6, 0x13, 0x0, 0x40015, 0x15, 0x20, 0x1, 0x3001E, 0x16, 0x15, 0x40020, 0x17, 0x9, 0x16, 0x4003B, 0x17, 0x18, 0x9, 0x4002B, 0x15, 0x19, 0x0, 0x40020, 0x1A, 0x9, 0x15, 0x20014, 0x1D, 0x40020, 0x21, 0x3, 0x7, 0x4003B, 0x21, 0x22, 0x3, 0x40020, 0x23, 0x1, 0x7, 0x4003B, 0x23, 0x24, 0x1, 0x40017, 0x25, 0x6, 0x3, 0x40015, 0x28, 0x20, 0x0, 0x4002B, 0x28, 0x29, 0x3, 0x40020, 0x2A, 0x7, 0x6, 0x40020, 0x2D, 0x1, 0x6, 0x50036, 0x2, 0x4, 0x0, 0x3, 0x200F8, 0x5, 0x4003B, 0x8, 0x9, 0x7, 0x4003D, 0xB, 0xE, 0xD, 0x4003D, 0xF, 0x12, 0x11, 0x70058, 0x7, 0x14, 0xE, 0x12, 0x2, 0x13, 0x3003E, 0x9, 0x14, 0x50041, 0x1A, 0x1B, 0x18, 0x19, 0x4003D, 0x15, 0x1C, 0x1B, 0x500AB, 0x1D, 0x1E, 0x1C, 0x19, 0x300F7, 0x20, 0x0, 0x400FA, 0x1E, 0x1F, 0x35, 0x200F8, 0x1F, 0x4003D, 0x7, 0x26, 0x24, 0x8004F, 0x25, 0x27, 0x26, 0x26, 0x0, 0x1, 0x2, 0x50041, 0x2A, 0x2B, 0x9, 0x29, 0x4003D, 0x6, 0x2C, 0x2B, 0x50041, 0x2D, 0x2E, 0x24, 0x29, 0x4003D, 0x6, 0x2F, 0x2E, 0x50085, 0x6, 0x30, 0x2C, 0x2F, 0x50051, 0x6, 0x31, 0x27, 0x0, 0x50051, 0x6, 0x32, 0x27, 0x1, 0x50051, 0x6, 0x33, 0x27, 0x2, 0x70050, 0x7, 0x34, 0x31, 0x32, 0x33, 0x30, 0x3003E, 0x22, 0x34, 0x200F9, 0x20, 0x200F8, 0x35, 0x4003D, 0x7, 0x36, 0x9, 0x4003D, 0x7, 0x37, 0x24, 0x50085, 0x7, 0x38, 0x36, 0x37, 0x3003E, 0x22, 0x38, 0x200F9, 0x20, 0x200F8, 0x20, 0x100FD, 0x10038, }; +// clang-format on } // namespace Shaders } // namespace PD \ No newline at end of file diff --git a/backends/include/pd_system/spirv-helper.hpp b/backends/include/pd_system/spirv-helper.hpp index 55ff391..12ebfa6 100644 --- a/backends/include/pd_system/spirv-helper.hpp +++ b/backends/include/pd_system/spirv-helper.hpp @@ -1,10 +1,8 @@ #pragma once -#include -#include - #include +struct TBuiltInResource; namespace PD { class SpirvHelper { public: diff --git a/backends/source/gfx_opengl2.cpp b/backends/source/gfx_opengl2.cpp index 1c2f080..91291b8 100644 --- a/backends/source/gfx_opengl2.cpp +++ b/backends/source/gfx_opengl2.cpp @@ -6,11 +6,49 @@ #include #include -#include -#include namespace PD { +const char* GfxOpenGL2::pVertCode = R"( + #version 120 + + attribute vec2 pos; + attribute vec2 uv; + attribute vec4 color; + + varying vec2 oUV; + varying vec4 oColor; + + // Probably forgot about this matrix and + // searched hours for why the rendering isn't working :/ + uniform mat4 projection; + + void main() { + gl_Position = projection*vec4(pos, 0.0, 1.0); + oUV = uv; + oColor = color; + } + )"; + +const char* GfxOpenGL2::pFragCode = R"( + #version 120 + + varying vec2 oUV; + varying vec4 oColor; + + uniform sampler2D tex; + uniform bool alfa; + + void main() { + vec4 tc = texture2D(tex, oUV); + if (alfa) { + gl_FragColor = vec4(oColor.rgb, tc.a * oColor.a); + } else { + gl_FragColor = tc * oColor; + } + } + )"; + void GfxOpenGL2::pSetupShaderAttribs(u32 shader) { GLint _pos = glGetAttribLocation(shader, "pos"); GLint _uv = glGetAttribLocation(shader, "uv"); @@ -30,17 +68,7 @@ void GfxOpenGL2::pSetupShaderAttribs(u32 shader) { } void GfxOpenGL2::SysInit() { - SpirvHelper::Init(); - auto vshader = - SpirvHelper::GLSL2SPV(SpirvHelper::Stage::Vertex, Shaders::VertCode); - auto fshader = - SpirvHelper::GLSL2SPV(SpirvHelper::Stage::Fragment, Shaders::FragCode); - SpirvHelper::Finalize(); - std::string vcode = SpirvHelper::SPV2GLSL(vshader, 110, false); - std::string fcode = SpirvHelper::SPV2GLSL(fshader, 110, false); - PDLOG("Vertex: \n{}", vcode); - PDLOG("Fragment: \n{}", fcode); - pShader = CreateShaderProgram(vcode.c_str(), fcode.c_str()); + pShader = CreateShaderProgram(pVertCode, pFragCode); glUseProgram(pShader); glGenBuffers(1, &VBO); glBindBuffer(GL_ARRAY_BUFFER, VBO); @@ -49,8 +77,8 @@ void GfxOpenGL2::SysInit() { pSetupShaderAttribs(pShader); pLocTex = glGetUniformLocation(pShader, "tex"); - pLocAlfa = glGetUniformLocation(pShader, "push.alfa"); - pLocProjection = glGetUniformLocation(pShader, "ubo.projection"); + pLocAlfa = glGetUniformLocation(pShader, "alfa"); + pLocProjection = glGetUniformLocation(pShader, "projection"); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); diff --git a/backends/source/gfx_opengl3.cpp b/backends/source/gfx_opengl3.cpp index 2e4b812..64bc27a 100644 --- a/backends/source/gfx_opengl3.cpp +++ b/backends/source/gfx_opengl3.cpp @@ -11,14 +11,18 @@ namespace PD { void GfxOpenGL3::SysInit() { - SpirvHelper::Init(); - auto vshader = - SpirvHelper::GLSL2SPV(SpirvHelper::Stage::Vertex, Shaders::VertCode); - auto fshader = - SpirvHelper::GLSL2SPV(SpirvHelper::Stage::Fragment, Shaders::FragCode); - SpirvHelper::Finalize(); - std::string vcode = SpirvHelper::SPV2GLSL(vshader, 330, false); - std::string fcode = SpirvHelper::SPV2GLSL(fshader, 330, false); + std::string vcode = SpirvHelper::SPV2GLSL( + std::vector( + Shaders::VertexShader, + Shaders::VertexShader + + (sizeof(Shaders::VertexShader) / sizeof(unsigned int))), + 330, false); + std::string fcode = SpirvHelper::SPV2GLSL( + std::vector( + Shaders::FragmentShader, + Shaders::FragmentShader + + (sizeof(Shaders::FragmentShader) / sizeof(unsigned int))), + 330, false); PDLOG("Vertex: \n{}", vcode); PDLOG("Fragment: \n{}", fcode); pShader = CreateShaderProgram(vcode.c_str(), fcode.c_str()); diff --git a/backends/source/spirv-helper.cpp b/backends/source/spirv-helper.cpp index 11ba42f..2312c98 100644 --- a/backends/source/spirv-helper.cpp +++ b/backends/source/spirv-helper.cpp @@ -1,17 +1,28 @@ #if defined(PD_ENABLE_SPIRV_HELPER) +#if defined(PD_INCLUDE_GLSLANG) #include - +#include +#include +#else +struct TBuiltInResource {}; +#endif #include #include #include #include namespace PD { +#if defined(PD_INCLUDE_GLSLANG) void SpirvHelper::Init() { glslang::InitializeProcess(); } void SpirvHelper::Finalize() { glslang::FinalizeProcess(); } +#else +void SpirvHelper::Init() {} +void SpirvHelper::Finalize() {} +#endif void SpirvHelper::SetupResources(TBuiltInResource& resources) { +#if defined(PD_INCLUDE_GLSLANG) resources.maxLights = 32; resources.maxClipPlanes = 6; resources.maxTextureUnits = 32; @@ -113,11 +124,13 @@ void SpirvHelper::SetupResources(TBuiltInResource& resources) { resources.limits.generalSamplerIndexing = 1; resources.limits.generalVariableIndexing = 1; resources.limits.generalConstantMatrixVectorIndexing = 1; +#endif } std::vector SpirvHelper::GLSL2SPV(Stage stage, const char* code, bool vulkan_mode) { std::vector spv; +#if defined(PD_INCLUDE_GLSLANG) EShLanguage estage = static_cast(stage); glslang::TShader shader(estage); glslang::TProgram program; @@ -148,6 +161,7 @@ std::vector SpirvHelper::GLSL2SPV(Stage stage, const char* code, } glslang::GlslangToSpv(*program.getIntermediate(estage), spv); +#endif return spv; } @@ -186,6 +200,7 @@ std::string SpirvHelper::SPV2HLSL(const std::vector& spirv, } } // namespace PD #else +struct TBuiltInResource {}; namespace PD { void SpirvHelper::Init() { glslang::InitializeProcess(); } void SpirvHelper::Finalize() { glslang::FinalizeProcess(); } diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 8676f1e..10344a5 100755 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -3,4 +3,5 @@ cmake_minimum_required(VERSION 3.22) add_subdirectory(lazyvec) add_subdirectory(ppam) add_subdirectory(pdlm) -add_subdirectory(pdfm) \ No newline at end of file +add_subdirectory(pdfm) +add_subdirectory(pdsg) \ No newline at end of file diff --git a/tools/pdsg/CMakeLists.txt b/tools/pdsg/CMakeLists.txt new file mode 100644 index 0000000..ca00de3 --- /dev/null +++ b/tools/pdsg/CMakeLists.txt @@ -0,0 +1,29 @@ +cmake_minimum_required(VERSION 3.22) + +project(pdsg LANGUAGES CXX VERSION 1.0.0) + +### Requires C++ 20 +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED true) + +add_executable(pdsg + ${CMAKE_CURRENT_SOURCE_DIR}/source/main.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/source/spirv-helper.cpp +) +target_include_directories(pdsg PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/include +) +target_link_libraries(pdsg PRIVATE + glslang + glslang-default-resource-limits + OSDependent + SPIRV + + spirv-cross-core + spirv-cross-cpp + spirv-cross-glsl + spirv-cross-hlsl + spirv-cross-msl + spirv-cross-reflect + spirv-cross-util +) diff --git a/tools/pdsg/include/spirv-helper.hpp b/tools/pdsg/include/spirv-helper.hpp new file mode 100644 index 0000000..ac462ea --- /dev/null +++ b/tools/pdsg/include/spirv-helper.hpp @@ -0,0 +1,34 @@ +#pragma once + +#include +#include +#include + +struct TBuiltInResource; +class SpirvHelper { + public: + enum class Format { + GLSL, + HLSL, + MSL, // Not supported yet + SPIRV, + }; + + enum class Stage { + Vertex = 0, + Geometry = 3, + Fragment = 4, + }; + + SpirvHelper() = default; + ~SpirvHelper() = default; + + static void Init(); + static void Finalize(); + static void SetupResources(TBuiltInResource& resources); + static std::vector GLSL2SPV(Stage stage, const char* code); + static std::string SPV2GLSL(const std::vector& spirv, + int version, bool es = false); + static std::string SPV2HLSL(const std::vector& spirv, + int version); +}; \ No newline at end of file diff --git a/tools/pdsg/source/main.cpp b/tools/pdsg/source/main.cpp new file mode 100644 index 0000000..00e1496 --- /dev/null +++ b/tools/pdsg/source/main.cpp @@ -0,0 +1,45 @@ +#include +#include +#include +#include +#include + +template +void FmtPrint(std::format_string fmt, Args&&... args) { + std::cout << std::format(fmt, std::forward(args)...); +} + +std::string LoadFile(const std::string& path) { + std::stringstream s; + std::ifstream f(path); + s << f.rdbuf(); + return s.str(); +} + +int main(int argc, char** argv) { + if (argc != 4) return 0; + SpirvHelper::Stage mode = SpirvHelper::Stage::Vertex; + if (std::string(argv[3]) == "vertex") { + mode = SpirvHelper::Stage::Vertex; + } else if (std::string(argv[3]) == "fragment") { + mode = SpirvHelper::Stage::Fragment; + } else if (std::string(argv[3]) == "geometry") { + mode = SpirvHelper::Stage::Geometry; + } + FmtPrint("ProcessingMode: {}\n", (int)mode); + FmtPrint("Loading {}\n", argv[1]); + std::string shader = LoadFile(argv[1]); + FmtPrint("Generating SPIRV...\n"); + auto res = SpirvHelper::GLSL2SPV(SpirvHelper::Stage::Vertex, shader.c_str()); + FmtPrint("Result size: {}\n", res.size()); + std::ofstream ff(argv[2]); + FmtPrint("Writing into {}", argv[2]); + ff << "#pragma once\n\n#include \n\n// clang-format off\nconst " + "unsigned int pShader[] " + "= { "; + for (auto& it : res) { + ff << std::format("0x{:X}, ", it); + } + ff << "};\n// clang-format on\n"; + return 0; +} \ No newline at end of file diff --git a/tools/pdsg/source/spirv-helper.cpp b/tools/pdsg/source/spirv-helper.cpp new file mode 100644 index 0000000..39c703d --- /dev/null +++ b/tools/pdsg/source/spirv-helper.cpp @@ -0,0 +1,184 @@ + +#include +#include +#include + +#include +#include +#include +#include + +void SpirvHelper::Init() { glslang::InitializeProcess(); } +void SpirvHelper::Finalize() { glslang::FinalizeProcess(); } +void SpirvHelper::SetupResources(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 = 1; + resources.limits.whileLoops = 1; + resources.limits.doWhileLoops = 1; + resources.limits.generalUniformIndexing = 1; + resources.limits.generalAttributeMatrixVectorIndexing = 1; + resources.limits.generalVaryingIndexing = 1; + resources.limits.generalSamplerIndexing = 1; + resources.limits.generalVariableIndexing = 1; + resources.limits.generalConstantMatrixVectorIndexing = 1; +} + +std::vector SpirvHelper::GLSL2SPV(Stage stage, const char* code) { + std::vector spv; + EShLanguage estage = static_cast(stage); + glslang::TShader shader(estage); + glslang::TProgram program; + const char* strings[1]; + TBuiltInResource resources = {}; + SetupResources(resources); + + EShMessages messages = (EShMessages)(EShMsgSpvRules | EShMsgVulkanRules); + + strings[0] = code; + shader.setStrings(strings, 1); + shader.setAutoMapBindings(true); + shader.setAutoMapLocations(true); + + if (!shader.parse(&resources, 100, false, messages)) { + puts(shader.getInfoLog()); + puts(shader.getInfoDebugLog()); + return spv; + } + + program.addShader(&shader); + + if (!program.link(messages)) { + puts(shader.getInfoLog()); + puts(shader.getInfoDebugLog()); + fflush(stdout); + return spv; + } + + glslang::GlslangToSpv(*program.getIntermediate(estage), spv); + return spv; +} + +std::string SpirvHelper::SPV2GLSL(const std::vector& spirv, + int version, bool es) { + std::string ret; + spirv_cross::CompilerGLSL glsl(spirv); + spirv_cross::ShaderResources resources = glsl.get_shader_resources(); + for (auto& resource : resources.stage_inputs) { + glsl.unset_decoration(resource.id, spv::DecorationLocation); + } + for (auto& resource : resources.stage_outputs) { + glsl.unset_decoration(resource.id, spv::DecorationLocation); + } + spirv_cross::CompilerGLSL::Options scoptions; + scoptions.version = version; + scoptions.es = es; + scoptions.emit_uniform_buffer_as_plain_uniforms = true; + scoptions.enable_420pack_extension = false; + glsl.set_common_options(scoptions); + ret = glsl.compile(); + return ret; +} + +std::string SpirvHelper::SPV2HLSL(const std::vector& spirv, + int version) { + std::string ret; + spirv_cross::CompilerHLSL hlsl(spirv); + spirv_cross::CompilerHLSL::Options scoptions; + scoptions.shader_model = version; + scoptions.point_size_compat = false; + scoptions.force_storage_buffer_as_uav = false; + hlsl.set_hlsl_options(scoptions); + ret = hlsl.compile(); + return ret; +} \ No newline at end of file diff --git a/vendor/CMakeLists.txt b/vendor/CMakeLists.txt index f1be3b7..9d59a92 100644 --- a/vendor/CMakeLists.txt +++ b/vendor/CMakeLists.txt @@ -5,15 +5,18 @@ if(${CMAKE_SYSTEM_NAME} STREQUAL "Nintendo3DS") else() # GLAD add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/glad) - # GLSLANG - set(ENABLE_OPT OFF CACHE BOOL "" FORCE) - add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/glslang) # SPIRV-Cross set(SPIRV_CROSS_CLI OFF CACHE BOOL "" FORCE) set(SPIRV_CROSS_ENABLE_TESTS OFF CACHE BOOL "" FORCE) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/spirv-cross) endif() +if(PD_BUILD_TOOLS) + # GLSLANG + set(ENABLE_OPT OFF CACHE BOOL "" FORCE) + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/glslang) +endif() + # STB add_library(stb INTERFACE) target_include_directories(stb INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/stb)