diff --git a/src/dawn/asset/loader/ShaderLoader.cpp b/src/dawn/asset/loader/ShaderLoader.cpp index 2c5c3ca0..c354e3dd 100644 --- a/src/dawn/asset/loader/ShaderLoader.cpp +++ b/src/dawn/asset/loader/ShaderLoader.cpp @@ -17,7 +17,8 @@ ShaderLoader::ShaderLoader( const std::string name ) : AssetLoader(assetManager, name), - state(ShaderLoaderState::INITIAL) + state(ShaderLoaderState::INITIAL), + shader(std::make_shared()) { } @@ -26,10 +27,10 @@ void ShaderLoader::updateAsync() { void ShaderLoader::updateSync() { if(state != ShaderLoaderState::INITIAL) return; - this->state = ShaderLoaderState::LOADING; assertFalse(loaded, "ShaderLoader already loaded."); + // Shorthand. auto sm = this->getAssetManager()->getGame()->shaderManager; // Load the shader string @@ -43,21 +44,13 @@ void ShaderLoader::updateSync() { int32_t definedEntryPointCount = module->getDefinedEntryPointCount(); IComponentType** components = new IComponentType*[definedEntryPointCount + 1]; int32_t componentCount = 0; + components[componentCount++] = module;// First component is module. - components[componentCount++] = module; - + // Get the entry point info and append to components list. for(auto i = 0; i < definedEntryPointCount; i++) { Slang::ComPtr ep; auto result = module->getDefinedEntryPoint(i, ep.writeRef()); - - if(result != SLANG_OK) { - assertUnreachable("Failed to get entry point."); - return; - } - - auto name = ep->getFunctionReflection()->getName(); - std::cout << "Found entry point: " << name << std::endl; - entryPoints.push_back(std::string(name)); + if(result != SLANG_OK) assertUnreachable("Failed to get entry point."); components[componentCount++] = ep; } @@ -80,6 +73,42 @@ void ShaderLoader::updateSync() { return; } + // Create the shader program. + Slang::ComPtr blob; + slang::ProgramLayout* layout = program->getLayout(); + std::vector> shaderEntries; + for(auto i = 0; i < definedEntryPointCount; i++) { + // Get the code + auto result = linkedProgram->getEntryPointCode( + i, + 0, + blob.writeRef(), + diagnostics.writeRef() + ); + + if(diagnostics) { + assertUnreachable("%s\n", (const char*) diagnostics->getBufferPointer()); + } + + // Get the stage information + auto entryPointReflection = layout->getEntryPointByIndex(0); + auto stage = entryPointReflection->getStage(); + + // Create the shader entry + auto shaderEntry = std::make_shared(); + shaderEntry->init( + stage, + std::string((const char*)blob->getBufferPointer()) + ); + + // Add to the list + shaderEntries.push_back(shaderEntry); + } + + // Create the shader program. + shader->init(shaderEntries); + + // Finished loading. delete [] components; this->state = ShaderLoaderState::LOADED; this->loaded = true; @@ -89,38 +118,14 @@ std::string ShaderLoader::getAssetType() const { return ShaderLoader::ASSET_TYPE; } -std::string ShaderLoader::getEntryPointCode(const std::string &entryPoint) { - assertTrue(loaded, "ShaderLoader not loaded."); - assertNotNull(linkedProgram, "ShaderLoader linkedProgram is null."); - - // Get the entry point index - int32_t entryIndex = -1; - for(auto i = 0; i < entryPoints.size(); i++) { - if(entryPoints[i] != entryPoint) continue; - entryIndex = i; - break; - } - assertTrue(entryIndex != -1, "EntryPoint not found."); - - // Find the entry point code - Slang::ComPtr blob; - Slang::ComPtr diagnostics; - auto result = linkedProgram->getEntryPointCode( - entryIndex, - 0, - blob.writeRef(), - diagnostics.writeRef() - ); - - if(diagnostics) { - assertUnreachable("%s\n", (const char*) diagnostics->getBufferPointer()); - return ""; - } - - return std::string((const char*)blob->getBufferPointer()); +std::shared_ptr ShaderLoader::getShader() { + assertNotNull(shader, "ShaderLoader shader is null."); + return shader; } ShaderLoader::~ShaderLoader() { + shader = nullptr; + if(linkedProgram) { linkedProgram->release(); linkedProgram = nullptr; diff --git a/src/dawn/asset/loader/ShaderLoader.hpp b/src/dawn/asset/loader/ShaderLoader.hpp index 0e5c04f7..cad59ff7 100644 --- a/src/dawn/asset/loader/ShaderLoader.hpp +++ b/src/dawn/asset/loader/ShaderLoader.hpp @@ -7,6 +7,7 @@ #include "asset/AssetLoader.hpp" #include "asset/AssetDataLoader.hpp" #include "display/shader/ShaderManager.hpp" +#include "display/shader/ShaderProgram2.hpp" namespace Dawn { enum class ShaderLoaderState { @@ -18,13 +19,14 @@ namespace Dawn { class ShaderLoader : public AssetLoader { protected: enum ShaderLoaderState state; + std::shared_ptr shader; public: const static std::string ASSET_TYPE; - std::vector entryPoints; Slang::ComPtr linkedProgram; Slang::ComPtr program; + IModule* module; ShaderLoader( @@ -34,7 +36,14 @@ namespace Dawn { void updateSync() override; void updateAsync() override; std::string getAssetType() const override; - std::string getEntryPointCode(const std::string &entryPoint); + + /** + * Retreives the shader program for this loader. + * + * @return std::shared_ptr + */ + std::shared_ptr getShader(); + ~ShaderLoader(); }; } \ No newline at end of file diff --git a/src/dawn/display/shader/CMakeLists.txt b/src/dawn/display/shader/CMakeLists.txt index 7bf594f0..b36cc917 100644 --- a/src/dawn/display/shader/CMakeLists.txt +++ b/src/dawn/display/shader/CMakeLists.txt @@ -10,4 +10,5 @@ target_sources(${DAWN_TARGET_NAME} IShaderStage.cpp ShaderManager.cpp ShaderManagerSlangFileSystem.cpp + IShaderProgram2.cpp ) \ No newline at end of file diff --git a/src/dawn/display/shader/IShaderProgram2.cpp b/src/dawn/display/shader/IShaderProgram2.cpp new file mode 100644 index 00000000..4b026660 --- /dev/null +++ b/src/dawn/display/shader/IShaderProgram2.cpp @@ -0,0 +1,21 @@ +// Copyright (c) 2024 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#include "IShaderProgram2.hpp" + +using namespace Dawn; + +IShaderEntry::~IShaderEntry() { +} + +void IShaderProgram2::init( + const std::vector> &entries +) { + this->entries = entries; +} + +IShaderProgram2::~IShaderProgram2() { + +} \ No newline at end of file diff --git a/src/dawn/display/shader/IShaderProgram2.hpp b/src/dawn/display/shader/IShaderProgram2.hpp index df79dbc9..00f87c32 100644 --- a/src/dawn/display/shader/IShaderProgram2.hpp +++ b/src/dawn/display/shader/IShaderProgram2.hpp @@ -5,19 +5,49 @@ #pragma once #include "dawn.hpp" +#include "slang.h" + +using namespace slang; namespace Dawn { - class IShaderEntry { + class ShaderEntry; + class IShaderEntry { + public: + /** + * Initialize the IShaderEntry object + * + * @param stage The stage of the shader entry. + * @param code The code of the shader entry. + */ + virtual void init( + const SlangStage &stage, + const std::string &code + ) = 0; + + /** + * Destroy the IShaderEntry object + */ + virtual ~IShaderEntry(); }; class IShaderProgram2 { - private: - std::vector entries; - protected: + std::vector> entries; public: + /** + * Initialize the IShaderProgram2 object + * + * @param entries The list of shader entries to initialize with. + */ + virtual void init( + const std::vector> &entries + ) = 0; + /** + * Destroy the IShaderProgram2 object + */ + virtual ~IShaderProgram2(); }; } \ No newline at end of file diff --git a/src/dawnopengl/display/shader/CMakeLists.txt b/src/dawnopengl/display/shader/CMakeLists.txt index 2407fb33..d855f60b 100644 --- a/src/dawnopengl/display/shader/CMakeLists.txt +++ b/src/dawnopengl/display/shader/CMakeLists.txt @@ -11,4 +11,5 @@ target_sources(${DAWN_TARGET_NAME} SimpleTexturedShader.cpp UIShader.cpp ShaderParameter.cpp + ShaderProgram2.cpp ) \ No newline at end of file diff --git a/src/dawnopengl/display/shader/ShaderProgram2.cpp b/src/dawnopengl/display/shader/ShaderProgram2.cpp new file mode 100644 index 00000000..dc5e2b74 --- /dev/null +++ b/src/dawnopengl/display/shader/ShaderProgram2.cpp @@ -0,0 +1,28 @@ +// Copyright (c) 2024 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#include "ShaderProgram2.hpp" + +using namespace Dawn; + +void ShaderEntry::init( + const SlangStage &stage, + const std::string &code +) { +} + +ShaderEntry::~ShaderEntry() { +} + +// // // + +void ShaderProgram2::init( + const std::vector> &entries +) { + IShaderProgram2::init(entries); +} + +ShaderProgram2::~ShaderProgram2() { +} \ No newline at end of file diff --git a/src/dawnopengl/display/shader/ShaderProgram2.hpp b/src/dawnopengl/display/shader/ShaderProgram2.hpp new file mode 100644 index 00000000..dac3a161 --- /dev/null +++ b/src/dawnopengl/display/shader/ShaderProgram2.hpp @@ -0,0 +1,28 @@ +// Copyright (c) 2024 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#pragma once +#include "display/shader/IShaderProgram2.hpp" + +namespace Dawn { + class ShaderEntry { + protected: + + public: + void init( + const SlangStage &stage, + const std::string &code + ); + ~ShaderEntry(); + }; + + class ShaderProgram2 : public IShaderProgram2 { + public: + void init( + const std::vector> &entries + ) override; + ~ShaderProgram2(); + }; +} \ No newline at end of file diff --git a/src/dawnrpg/game/Game.cpp b/src/dawnrpg/game/Game.cpp index abf9bbc3..220c89a6 100644 --- a/src/dawnrpg/game/Game.cpp +++ b/src/dawnrpg/game/Game.cpp @@ -34,15 +34,15 @@ void Game::initManagers() { auto sl = assetManager->get("shaders/hello-world.slang"); sl->loadImmediately(); - auto code1 = sl->getEntryPointCode("vertexMain"); - std::fstream file("vertexMain.glsl", std::ios::out); - file << code1; - file.close(); + // auto code1 = sl->getEntryPointCode("vertexMain"); + // std::fstream file("vertexMain.glsl", std::ios::out); + // file << code1; + // file.close(); - auto code2 = sl->getEntryPointCode("fragmentMain"); - std::fstream file2("fragmentMain.glsl", std::ios::out); - file2 << code2; - file2.close(); + // auto code2 = sl->getEntryPointCode("fragmentMain"); + // std::fstream file2("fragmentMain.glsl", std::ios::out); + // file2 << code2; + // file2.close(); } Game::~Game() {