mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-09 20:58:31 +09:00
[Feat] (MG_Impl/Program, MG_State/Program): initial impl of shader related states
This commit is contained in:
@@ -8,22 +8,22 @@ namespace MobileGL {
|
||||
m_shaders.emplace_back(shader);
|
||||
}
|
||||
|
||||
void ProgramObject::DetachShader(SharedPtr<ShaderObject> shader) {
|
||||
SizeT ProgramObject::DetachShader(SharedPtr<ShaderObject> shader) {
|
||||
auto count = std::erase_if(
|
||||
m_shaders, [shader](const SharedPtr<ShaderObject>& s) { return s.get() == shader.get(); });
|
||||
m_shaders,
|
||||
[shader](const SharedPtr<ShaderObject>& s) {
|
||||
return s.get() == shader.get();
|
||||
});
|
||||
|
||||
if (count == 0) {
|
||||
// FIXME: handle error here
|
||||
THROW_EXCEPTION("Program object does not have such shader object attached");
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
void ProgramObject::Link() {
|
||||
Vector<GLenum> shaderTypes(m_shaders.size());
|
||||
Vector<SharedPtr<glslang::TShader>> shaders(m_shaders.size());
|
||||
for (SizeT i = 0; i < m_shaders.size(); i++) {
|
||||
shaderTypes[i] = GetGLShaderTypeByMGLShaderStage(m_shaders[i]->m_stage);
|
||||
shaders[i] = m_shaders[i]->m_shader;
|
||||
shaderTypes[i] = GetGLShaderTypeByMGLShaderStage(m_shaders[i]->GetShaderStage());
|
||||
shaders[i] = m_shaders[i]->GetCompiledShader();
|
||||
}
|
||||
|
||||
MG_Util::ShaderTranspiler::ProgramAttrib attrib{
|
||||
@@ -44,6 +44,10 @@ namespace MobileGL {
|
||||
THROW_EXCEPTION(e);
|
||||
}
|
||||
}
|
||||
|
||||
void ProgramObject::MarkAsDeleted() {
|
||||
m_deleteStatus = true;
|
||||
}
|
||||
} // namespace GLState
|
||||
} // namespace MG_State
|
||||
} // namespace MobileGL
|
||||
@@ -8,9 +8,9 @@ namespace MobileGL {
|
||||
class ProgramObject {
|
||||
public:
|
||||
void AttachShader(SharedPtr<ShaderObject> shader);
|
||||
void DetachShader(SharedPtr<ShaderObject> shader);
|
||||
SizeT DetachShader(SharedPtr<ShaderObject> shader);
|
||||
void Link();
|
||||
|
||||
void MarkAsDeleted();
|
||||
private:
|
||||
Vector<SharedPtr<ShaderObject>> m_shaders;
|
||||
// basically this contains SPIR-V in binary format
|
||||
|
||||
@@ -5,20 +5,62 @@ namespace MobileGL {
|
||||
namespace GLState {
|
||||
Uint ProgramState::CreateProgram() {
|
||||
Uint programId = 0;
|
||||
m_indexGenerator.Generate(1, &programId);
|
||||
EnsureIndexAvail(programId);
|
||||
m_programObjects[programId] = MakeShared<ProgramObject>();
|
||||
m_programIndexGenerator.Generate(1, &programId);
|
||||
EnsureIndexAvail(programId, m_programObjects);
|
||||
auto programObject = MakeShared<ProgramObject>(programId);
|
||||
if (programObject == nullptr)
|
||||
return 0;
|
||||
m_programObjects[programId] = programObject;
|
||||
return programId;
|
||||
}
|
||||
|
||||
SharedPtr<ProgramObject> ProgramState::GetProgramObject(Uint id) {
|
||||
if (!CheckIndexAvail(id)) return nullptr; // FIXME: add error reporting here
|
||||
SharedPtr<ProgramObject> ProgramState::GetProgramObject(const Uint id) {
|
||||
if (!CheckIndexAvail(id, m_programObjects)) return nullptr; // FIXME: add error reporting here
|
||||
return m_programObjects[id];
|
||||
}
|
||||
|
||||
void ProgramState::DeleteProgram(Uint id) {
|
||||
if (!CheckIndexAvail(id)) return; // FIXME: add error reporting here
|
||||
m_programObjects[id].reset();
|
||||
void ProgramState::MarkProgramObjectForDeletion(const Uint program) {
|
||||
if (!CheckIndexAvail(program, m_programObjects)) return; // FIXME: add error reporting here
|
||||
auto& programObject = m_programObjects[program];
|
||||
if (programObject != nullptr) {
|
||||
programObject->MarkAsDeleted();
|
||||
programObject.reset();
|
||||
m_programIndexGenerator.Delete(program);
|
||||
}
|
||||
}
|
||||
|
||||
Bool ProgramState::ValidateProgramObject(const Uint program) const {
|
||||
return CheckIndexAvail(program, m_programObjects) && m_programObjects[program] != nullptr;
|
||||
}
|
||||
|
||||
Uint ProgramState::CreateShader(ShaderStage stage) {
|
||||
Uint shaderId = 0;
|
||||
m_shaderIndexGenerator.Generate(1, &shaderId);
|
||||
EnsureIndexAvail(shaderId, m_shaderObjects);
|
||||
auto shaderObject = MakeShared<ShaderObject>(stage);
|
||||
if (shaderObject == nullptr)
|
||||
return 0;
|
||||
m_shaderObjects[shaderId] = shaderObject;
|
||||
return shaderId;
|
||||
}
|
||||
|
||||
SharedPtr<ShaderObject> ProgramState::GetShaderObject(const Uint shader) {
|
||||
if (!CheckIndexAvail(shader, m_shaderObjects)) return nullptr;
|
||||
return m_shaderObjects[shader];
|
||||
}
|
||||
|
||||
void ProgramState::MarkShaderObjectForDeletion(Uint shader) {
|
||||
if (!CheckIndexAvail(shader, m_shaderObjects)) return;
|
||||
auto& shaderObject = m_shaderObjects[shader];
|
||||
if (shaderObject != nullptr) {
|
||||
m_shaderObjects[shader]->MarkAsDeleted();
|
||||
m_shaderObjects[shader].reset();
|
||||
m_shaderIndexGenerator.Delete(shader);
|
||||
}
|
||||
}
|
||||
|
||||
Bool ProgramState::ValidateShaderObject(Uint shader) const {
|
||||
return CheckIndexAvail(shader, m_shaderObjects) && m_shaderObjects[shader] != nullptr;
|
||||
}
|
||||
} // namespace GLState
|
||||
} // namespace MG_State
|
||||
|
||||
@@ -12,20 +12,32 @@ namespace MobileGL {
|
||||
// To retrieve created program object, use GetProgramObject()
|
||||
Uint CreateProgram();
|
||||
SharedPtr<ProgramObject> GetProgramObject(Uint id);
|
||||
void DeleteProgram(Uint program);
|
||||
void MarkProgramObjectForDeletion(Uint program);
|
||||
Bool ValidateProgramObject(Uint program) const;
|
||||
|
||||
Uint CreateShader(ShaderStage stage);
|
||||
SharedPtr<ShaderObject> GetShaderObject(Uint shader);
|
||||
void MarkShaderObjectForDeletion(Uint shader);
|
||||
Bool ValidateShaderObject(Uint shader) const;
|
||||
private:
|
||||
Bool CheckIndexAvail(SizeT idx) { return idx < m_programObjects.size(); }
|
||||
|
||||
void EnsureIndexAvail(SizeT idx) {
|
||||
if (CheckIndexAvail(idx)) return;
|
||||
|
||||
m_programObjects.reserve(std::bit_ceil(idx));
|
||||
m_programObjects.resize(idx + 1);
|
||||
template <typename T>
|
||||
static Bool CheckIndexAvail(const SizeT idx, const Vector<T>& vec) {
|
||||
return idx < vec.size();
|
||||
}
|
||||
|
||||
IndexGenerator<Uint> m_indexGenerator;
|
||||
template <typename T>
|
||||
static void EnsureIndexAvail(const SizeT idx, Vector<T>& vec) {
|
||||
if (CheckIndexAvail(idx, vec)) return;
|
||||
|
||||
vec.reserve(std::bit_ceil(idx));
|
||||
vec.resize(idx + 1);
|
||||
}
|
||||
|
||||
IndexGenerator<Uint> m_programIndexGenerator;
|
||||
Vector<SharedPtr<ProgramObject>> m_programObjects;
|
||||
|
||||
IndexGenerator<Uint> m_shaderIndexGenerator;
|
||||
Vector<SharedPtr<ShaderObject>> m_shaderObjects;
|
||||
};
|
||||
} // namespace GLState
|
||||
} // namespace MG_State
|
||||
|
||||
@@ -26,9 +26,12 @@ namespace MobileGL {
|
||||
|
||||
const std::string e = std::format("Shader compilation failed: \nerrc: {}\nmsg: {}\n",
|
||||
result.error().errc, result.error().log);
|
||||
THROW_EXCEPTION(e);
|
||||
}
|
||||
}
|
||||
|
||||
void ShaderObject::MarkAsDeleted() {
|
||||
m_deleteStatus = true;
|
||||
}
|
||||
} // namespace GLState
|
||||
} // namespace MG_State
|
||||
} // namespace MobileGL
|
||||
@@ -59,7 +59,12 @@ namespace MobileGL {
|
||||
ShaderObject(const ShaderStage stage) : m_stage(stage) {}
|
||||
void SetShaderSource(const std::string& source);
|
||||
void Compile();
|
||||
void MarkAsDeleted();
|
||||
|
||||
ShaderStage GetShaderStage() const { return m_stage; }
|
||||
const std::string& GetShaderSource() const { return m_source; }
|
||||
SharedPtr<glslang::TShader> GetCompiledShader() const { return m_shader; }
|
||||
private:
|
||||
const ShaderStage m_stage;
|
||||
std::string m_source;
|
||||
SharedPtr<glslang::TShader> m_shader;
|
||||
|
||||
Reference in New Issue
Block a user