From 8c16ab39e31b23e0eef26a9e42d2c718f0b1d441 Mon Sep 17 00:00:00 2001 From: MonsterDruide1 <5958456@gmail.com> Date: Wed, 21 Jan 2026 01:07:05 +0100 Subject: [PATCH 1/2] common: Implement `ShaderLocation` Co-authored-by: tetraxile --- CMakeLists.txt | 3 ++ include/common/aglShader.h | 2 + include/common/aglShaderLocation.h | 29 ++++++++++++ include/common/aglShaderProgram.h | 4 ++ src/common/aglShaderLocation.cpp | 73 ++++++++++++++++++++++++++++++ 5 files changed, 111 insertions(+) create mode 100644 include/common/aglShaderLocation.h create mode 100644 src/common/aglShaderLocation.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 2b5cd3e..29321bc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,6 +21,7 @@ add_library(agl OBJECT include/common/aglShader.h include/common/aglShaderCompileInfo.h include/common/aglShaderEnum.h + include/common/aglShaderLocation.h include/common/aglShaderProgram.h include/common/aglShaderProgramArchive.h include/common/aglTextureData.h @@ -72,6 +73,8 @@ add_library(agl OBJECT include/utility/aglParameterStringMgr.h include/utility/aglResParameter.h include/utility/aglScreenShotMgr.h + + src/common/aglShaderLocation.cpp src/detail/aglGPUMemBlockMgr.cpp diff --git a/include/common/aglShader.h b/include/common/aglShader.h index b312f1e..5377353 100644 --- a/include/common/aglShader.h +++ b/include/common/aglShader.h @@ -16,6 +16,8 @@ class Shader { void setBinary(const void* shaderBinary); + const void* getShaderBinary() const { return mShaderBinary; } + private: void* mShaderBinary; // _8 void* _10; diff --git a/include/common/aglShaderLocation.h b/include/common/aglShaderLocation.h new file mode 100644 index 0000000..0076eb0 --- /dev/null +++ b/include/common/aglShaderLocation.h @@ -0,0 +1,29 @@ +#pragma once + +#include +#include + +#include "common/aglShaderEnum.h" + +namespace agl { +class ShaderProgram; + +class ShaderLocation { +public: + void setLocation(s32); + void setLocation(ShaderType, s32); + void setRegisterLocation(ShaderType, s32); + +private: + union { + s8 mLocation[cShaderType_Num]; + s16 mRegisterLocation[2]; + }; +}; + +class UniformBlockLocation : public ShaderLocation, public sead::INamable { + ~UniformBlockLocation(); + void search(const ShaderProgram&); +}; + +} diff --git a/include/common/aglShaderProgram.h b/include/common/aglShaderProgram.h index c56e527..4e5d6e0 100644 --- a/include/common/aglShaderProgram.h +++ b/include/common/aglShaderProgram.h @@ -3,6 +3,7 @@ #include #include "common/aglDisplayList.h" #include "common/aglShader.h" +#include "common/aglShaderEnum.h" namespace sead { class Heap; @@ -31,6 +32,9 @@ class ShaderProgram { sead::Heap*); void setVariationMacroValue(s32, s32, const sead::SafeString&); void createVariation(sead::Heap*); + bool hasStage(ShaderType) const; + const Shader& getShader(ShaderType) const; + Shader* getShader(ShaderType); private: u64* _8; diff --git a/src/common/aglShaderLocation.cpp b/src/common/aglShaderLocation.cpp new file mode 100644 index 0000000..6b29605 --- /dev/null +++ b/src/common/aglShaderLocation.cpp @@ -0,0 +1,73 @@ +#include "common/aglShaderLocation.h" + +#include + +#include "common/aglShaderProgram.h" + +namespace agl { + +void ShaderLocation::setLocation(s32 location) { + for (s32 i = 0; i < cShaderType_Num; ++i) { + mLocation[i] = location; + } +} + +void ShaderLocation::setLocation(ShaderType type, s32 location) { + mLocation[type] = location; +} + +void ShaderLocation::setRegisterLocation(ShaderType type, s32 location) { + mRegisterLocation[type != cShaderType_Vertex] = location; +} + +UniformBlockLocation::~UniformBlockLocation() = default; + +static s32 getLocation(const UniformBlockLocation& loc, const ShaderProgram& program, + ShaderType type) { + if (!program.hasStage(type)) + return -1; + + const Shader& shader = program.getShader(type); + const void* data = shader.getShaderBinary(); + if (!data) + return -1; + + // TODO: replace with proper types in headers + using UniformBlock = struct { + const char* name; + u32 location; + }; + using ShaderBinary = struct { + u8 _0[0x14]; + u32 numUniformBlocks; + UniformBlock* uniformBlocks; + }; + + const ShaderBinary* shaderBinary = reinterpret_cast(data); + const char* name = loc.getName().cstr(); + u32 numUniformBlocks = shaderBinary->numUniformBlocks; + if (numUniformBlocks == 0) + return -1; + + UniformBlock* uniformBlocks = shaderBinary->uniformBlocks; + + // TODO: probably an inlined search function returning UniformBlock* + for (u32 i = 0; i < numUniformBlocks; i++) { + if (strcmp(uniformBlocks[i].name, name) == 0) { + if (&uniformBlocks[i]) + return uniformBlocks[i].location; + return -1; + } + } + + return -1; +} + +void UniformBlockLocation::search(const ShaderProgram& program) { + for (s32 i = 0; i < cShaderType_Num; ++i) { + ShaderType type = static_cast(i); + setLocation(type, getLocation(*this, program, type)); + } +} + +} // namespace agl From 737cfaab0c41eb866368bea99236e1866ec9dae1 Mon Sep 17 00:00:00 2001 From: MonsterDruide1 <5958456@gmail.com> Date: Wed, 21 Jan 2026 01:11:14 +0100 Subject: [PATCH 2/2] clang format --- include/common/aglShaderLocation.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/common/aglShaderLocation.h b/include/common/aglShaderLocation.h index 0076eb0..1d304ce 100644 --- a/include/common/aglShaderLocation.h +++ b/include/common/aglShaderLocation.h @@ -26,4 +26,4 @@ class UniformBlockLocation : public ShaderLocation, public sead::INamable { void search(const ShaderProgram&); }; -} +} // namespace agl