Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand Down
2 changes: 2 additions & 0 deletions include/common/aglShader.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ class Shader {

void setBinary(const void* shaderBinary);

const void* getShaderBinary() const { return mShaderBinary; }

private:
void* mShaderBinary; // _8
void* _10;
Expand Down
29 changes: 29 additions & 0 deletions include/common/aglShaderLocation.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#pragma once

#include <basis/seadTypes.h>
#include <prim/seadNamable.h>

#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&);
};

} // namespace agl
4 changes: 4 additions & 0 deletions include/common/aglShaderProgram.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <prim/seadSafeString.h>
#include "common/aglDisplayList.h"
#include "common/aglShader.h"
#include "common/aglShaderEnum.h"

namespace sead {
class Heap;
Expand Down Expand Up @@ -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;
Expand Down
73 changes: 73 additions & 0 deletions src/common/aglShaderLocation.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#include "common/aglShaderLocation.h"

#include <cstring>

#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<const ShaderBinary*>(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<ShaderType>(i);
setLocation(type, getLocation(*this, program, type));
}
}

} // namespace agl