From 4bfd35c7871e9314495b3f0ce445fb55f54ca616 Mon Sep 17 00:00:00 2001 From: MonsterDruide1 <5958456@gmail.com> Date: Wed, 21 Jan 2026 01:07:05 +0100 Subject: [PATCH 1/4] 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 24b22df1bf090d3b053dab985dcf087df121a7df Mon Sep 17 00:00:00 2001 From: MonsterDruide1 <5958456@gmail.com> Date: Wed, 21 Jan 2026 01:11:14 +0100 Subject: [PATCH 2/4] 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 From dd0e689ca92a70afa8b1bd280b8af890e6637696 Mon Sep 17 00:00:00 2001 From: MonsterDruide1 <5958456@gmail.com> Date: Fri, 15 May 2026 21:16:43 +0200 Subject: [PATCH 3/4] review fixes --- include/common/aglShaderLocation.h | 2 +- src/common/aglShaderLocation.cpp | 15 +++++---------- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/include/common/aglShaderLocation.h b/include/common/aglShaderLocation.h index 1d304ce..ea351a5 100644 --- a/include/common/aglShaderLocation.h +++ b/include/common/aglShaderLocation.h @@ -22,7 +22,7 @@ class ShaderLocation { }; class UniformBlockLocation : public ShaderLocation, public sead::INamable { - ~UniformBlockLocation(); + ~UniformBlockLocation() = default; void search(const ShaderProgram&); }; diff --git a/src/common/aglShaderLocation.cpp b/src/common/aglShaderLocation.cpp index 6b29605..3ae0499 100644 --- a/src/common/aglShaderLocation.cpp +++ b/src/common/aglShaderLocation.cpp @@ -20,15 +20,12 @@ 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(); + const void* data = program.getShader(type).getShaderBinary(); if (!data) return -1; @@ -49,14 +46,12 @@ static s32 getLocation(const UniformBlockLocation& loc, const ShaderProgram& pro 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; + if (strcmp(shaderBinary->uniformBlocks[i].name, name) == 0) { + if (&shaderBinary->uniformBlocks[i]) + return shaderBinary->uniformBlocks[i].location; + break; } } From aa9418976d2ef14cf5f5e3fece13f7e054a15656 Mon Sep 17 00:00:00 2001 From: MonsterDruide1 <5958456@gmail.com> Date: Fri, 15 May 2026 21:27:23 +0200 Subject: [PATCH 4/4] review comments --- src/common/aglShaderLocation.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/common/aglShaderLocation.cpp b/src/common/aglShaderLocation.cpp index 3ae0499..379aecd 100644 --- a/src/common/aglShaderLocation.cpp +++ b/src/common/aglShaderLocation.cpp @@ -42,12 +42,9 @@ static s32 getLocation(const UniformBlockLocation& loc, const ShaderProgram& pro const ShaderBinary* shaderBinary = reinterpret_cast(data); const char* name = loc.getName().cstr(); - u32 numUniformBlocks = shaderBinary->numUniformBlocks; - if (numUniformBlocks == 0) - return -1; // TODO: probably an inlined search function returning UniformBlock* - for (u32 i = 0; i < numUniformBlocks; i++) { + for (u32 i = 0; i < shaderBinary->numUniformBlocks; i++) { if (strcmp(shaderBinary->uniformBlocks[i].name, name) == 0) { if (&shaderBinary->uniformBlocks[i]) return shaderBinary->uniformBlocks[i].location;