mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-11 21:58:31 +09:00
Merge remote-tracking branch 'origin/dev' into dev
This commit is contained in:
@@ -1,9 +1,75 @@
|
|||||||
#include "GL_Program.h"
|
#include "GL_Program.h"
|
||||||
|
|
||||||
|
#include "MG_State/GLState/Core.h"
|
||||||
|
|
||||||
namespace MobileGL {
|
namespace MobileGL {
|
||||||
namespace MG_Impl::GLImpl {
|
namespace MG_Impl::GLImpl {
|
||||||
|
static bool CheckShaderNameValidity(Uint shader) {
|
||||||
|
if (!MG_State::pGLContext->ValidateShaderName(shader)) {
|
||||||
|
MG_State::pGLContext->RecordError(
|
||||||
|
ErrorCode::InvalidValue,
|
||||||
|
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
||||||
|
"`shader` is not a value generated by OpenGL."));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SharedPtr<MG_State::GLState::ShaderObject> TryToGetShaderObject(Uint shader) {
|
||||||
|
if (!CheckShaderNameValidity(shader))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
auto shaderObject = MG_State::pGLContext->GetShaderObject(shader);
|
||||||
|
if (!shaderObject) {
|
||||||
|
MG_State::pGLContext->RecordError(
|
||||||
|
ErrorCode::InvalidOperation,
|
||||||
|
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
||||||
|
"`shader` is not a shader object."));
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return shaderObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool CheckProgramNameValidity(GLuint program) {
|
||||||
|
if (!MG_State::pGLContext->ValidateProgramName(program)) {
|
||||||
|
MG_State::pGLContext->RecordError(
|
||||||
|
ErrorCode::InvalidValue,
|
||||||
|
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
||||||
|
"`program` is not a value generated by OpenGL"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SharedPtr<MG_State::GLState::ProgramObject> TryToGetProgramObject(GLuint program) {
|
||||||
|
if (!CheckProgramNameValidity(program))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
auto programObject = MG_State::pGLContext->GetProgramObject(program);
|
||||||
|
if (!programObject) {
|
||||||
|
MG_State::pGLContext->RecordError(
|
||||||
|
ErrorCode::InvalidOperation,
|
||||||
|
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
||||||
|
"`program` is not a program object."));
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return programObject;
|
||||||
|
}
|
||||||
|
|
||||||
void AttachShader_State(GLuint program, GLuint shader) {
|
void AttachShader_State(GLuint program, GLuint shader) {
|
||||||
THROW_UNIMPL_EXCEPTION;
|
auto programObject = TryToGetProgramObject(program);
|
||||||
|
if (!programObject)
|
||||||
|
return;
|
||||||
|
auto shaderObject = TryToGetShaderObject(shader);
|
||||||
|
if (!shaderObject)
|
||||||
|
return;
|
||||||
|
if (!programObject->AttachShader(shaderObject)) {
|
||||||
|
MG_State::pGLContext->RecordError(
|
||||||
|
ErrorCode::InvalidOperation,
|
||||||
|
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
||||||
|
"`shader` is already attached to `program`."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BindAttribLocation_State(GLuint program, GLuint index, const GLchar* name) {
|
void BindAttribLocation_State(GLuint program, GLuint index, const GLchar* name) {
|
||||||
@@ -11,27 +77,56 @@ namespace MobileGL {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CompileShader_State(GLuint shader) {
|
void CompileShader_State(GLuint shader) {
|
||||||
THROW_UNIMPL_EXCEPTION;
|
auto shaderObject = TryToGetShaderObject(shader);
|
||||||
|
if (!shaderObject)
|
||||||
|
return;
|
||||||
|
shaderObject->Compile();
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint CreateProgram_State(void) {
|
GLuint CreateProgram_State(void) {
|
||||||
THROW_UNIMPL_EXCEPTION;
|
return MG_State::pGLContext->CreateProgram();
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint CreateShader_State(GLenum type) {
|
GLuint CreateShader_State(GLenum type) {
|
||||||
THROW_UNIMPL_EXCEPTION;
|
auto shaderId = MG_State::pGLContext->CreateShader(MG_State::GLState::GetMGLShaderStageByGLShaderType(type));
|
||||||
|
if (shaderId == 0) {
|
||||||
|
MG_State::pGLContext->RecordError(
|
||||||
|
ErrorCode::InvalidValue,
|
||||||
|
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
||||||
|
"`shaderType` is not an accepted value."));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return shaderId;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeleteProgram_State(GLuint program) {
|
void DeleteProgram_State(GLuint program) {
|
||||||
THROW_UNIMPL_EXCEPTION;
|
if (!CheckProgramNameValidity(program))
|
||||||
|
return;
|
||||||
|
MG_State::pGLContext->MarkProgramForDeletion(program);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeleteShader_State(GLuint shader) {
|
void DeleteShader_State(GLuint shader) {
|
||||||
THROW_UNIMPL_EXCEPTION;
|
if (!CheckProgramNameValidity(shader))
|
||||||
|
return;
|
||||||
|
MG_State::pGLContext->MarkShaderForDeletion(shader);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DetachShader_State(GLuint program, GLuint shader) {
|
void DetachShader_State(GLuint program, GLuint shader) {
|
||||||
THROW_UNIMPL_EXCEPTION;
|
auto shaderObject = TryToGetShaderObject(shader);
|
||||||
|
if (!shaderObject)
|
||||||
|
return;
|
||||||
|
auto programObject = TryToGetProgramObject(program);
|
||||||
|
if (!programObject)
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto count = programObject->DetachShader(shaderObject);
|
||||||
|
if (count <= 0) {
|
||||||
|
MG_State::pGLContext->RecordError(
|
||||||
|
ErrorCode::InvalidOperation,
|
||||||
|
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
||||||
|
"Shader is not attached to program."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetActiveAttrib_State(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLint* size,
|
void GetActiveAttrib_State(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLint* size,
|
||||||
@@ -85,15 +180,26 @@ namespace MobileGL {
|
|||||||
}
|
}
|
||||||
|
|
||||||
GLboolean IsProgram_State(GLuint program) {
|
GLboolean IsProgram_State(GLuint program) {
|
||||||
THROW_UNIMPL_EXCEPTION;
|
/* FIXME: Handle situations that:
|
||||||
|
* A program object marked for deletion with glDeleteProgram but still in use as part of current
|
||||||
|
* rendering state is still considered a program object and glIsProgram will return GL_TRUE.
|
||||||
|
*/
|
||||||
|
return CheckProgramNameValidity(program);
|
||||||
}
|
}
|
||||||
|
|
||||||
GLboolean IsShader_State(GLuint shader) {
|
GLboolean IsShader_State(GLuint shader) {
|
||||||
THROW_UNIMPL_EXCEPTION;
|
/* FIXME: Handle situations that:
|
||||||
|
* A shader object marked for deletion with glDeleteShader but still attached to a program object is still
|
||||||
|
* considered a shader object and glIsShader will return GL_TRUE.
|
||||||
|
*/
|
||||||
|
return CheckShaderNameValidity(shader);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LinkProgram_State(GLuint program) {
|
void LinkProgram_State(GLuint program) {
|
||||||
THROW_UNIMPL_EXCEPTION;
|
auto programObject = TryToGetProgramObject(program);
|
||||||
|
if (!programObject)
|
||||||
|
return;
|
||||||
|
programObject->Link();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShaderSource_State(GLuint shader, GLsizei count, const GLchar* const* string, const GLint* length) {
|
void ShaderSource_State(GLuint shader, GLsizei count, const GLchar* const* string, const GLint* length) {
|
||||||
@@ -227,8 +333,9 @@ namespace MobileGL {
|
|||||||
void GetAttachedShaders(GLuint program, GLsizei maxCount, GLsizei* count, GLuint* shaders) {
|
void GetAttachedShaders(GLuint program, GLsizei maxCount, GLsizei* count, GLuint* shaders) {
|
||||||
GetAttachedShaders_State(program, maxCount, count, shaders);
|
GetAttachedShaders_State(program, maxCount, count, shaders);
|
||||||
}
|
}
|
||||||
|
|
||||||
GLint GetAttribLocation(GLuint program, const GLchar* name) {
|
GLint GetAttribLocation(GLuint program, const GLchar* name) {
|
||||||
GetAttribLocation_State(program, name);
|
return GetAttribLocation_State(program, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetProgramiv(GLuint program, GLenum pname, GLint* params) {
|
void GetProgramiv(GLuint program, GLenum pname, GLint* params) {
|
||||||
@@ -250,8 +357,9 @@ namespace MobileGL {
|
|||||||
void GetShaderSource(GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* source) {
|
void GetShaderSource(GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* source) {
|
||||||
GetShaderSource_State(shader, bufSize, length, source);
|
GetShaderSource_State(shader, bufSize, length, source);
|
||||||
}
|
}
|
||||||
|
|
||||||
GLint GetUniformLocation(GLuint program, const GLchar* name) {
|
GLint GetUniformLocation(GLuint program, const GLchar* name) {
|
||||||
GetUniformLocation_State(program, name);
|
return GetUniformLocation_State(program, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetUniformfv(GLuint program, GLint location, GLfloat* params) {
|
void GetUniformfv(GLuint program, GLint location, GLfloat* params) {
|
||||||
|
|||||||
@@ -156,6 +156,37 @@ namespace MobileGL {
|
|||||||
m_textureState.SetActiveTextureUnit(unit);
|
m_textureState.SetActiveTextureUnit(unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Uint GLContext::CreateProgram() {
|
||||||
|
return m_programState.CreateProgram();
|
||||||
|
}
|
||||||
|
|
||||||
|
Uint GLContext::CreateShader(const ShaderStage stage) {
|
||||||
|
return m_programState.CreateShader(stage);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLContext::MarkProgramForDeletion(const Uint index) {
|
||||||
|
return m_programState.MarkProgramObjectForDeletion(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLContext::MarkShaderForDeletion(const Uint index) {
|
||||||
|
return m_programState.MarkShaderObjectForDeletion(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
Bool GLContext::ValidateProgramName(const Uint index) const {
|
||||||
|
return m_programState.ValidateProgramObject(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
Bool GLContext::ValidateShaderName(const Uint index) const {
|
||||||
|
return m_programState.ValidateShaderObject(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
SharedPtr<ProgramObject> GLContext::GetProgramObject(const Uint index) {
|
||||||
|
return m_programState.GetProgramObject(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
SharedPtr<ShaderObject> GLContext::GetShaderObject(const Uint index) {
|
||||||
|
return m_programState.GetShaderObject(index);
|
||||||
|
}
|
||||||
} // namespace GLState
|
} // namespace GLState
|
||||||
|
|
||||||
GLState::GLContext* pGLContext;
|
GLState::GLContext* pGLContext;
|
||||||
|
|||||||
@@ -54,6 +54,15 @@ namespace MobileGL {
|
|||||||
Int GetActiveTextureUnit() const;
|
Int GetActiveTextureUnit() const;
|
||||||
void SetActiveTextureUnit(Int unit);
|
void SetActiveTextureUnit(Int unit);
|
||||||
|
|
||||||
|
// Program
|
||||||
|
Uint CreateProgram();
|
||||||
|
Uint CreateShader(ShaderStage stage);
|
||||||
|
void MarkProgramForDeletion(Uint index);
|
||||||
|
void MarkShaderForDeletion(Uint index);
|
||||||
|
Bool ValidateProgramName(Uint index) const;
|
||||||
|
Bool ValidateShaderName(Uint index) const;
|
||||||
|
SharedPtr<ProgramObject> GetProgramObject(Uint index);
|
||||||
|
SharedPtr<ShaderObject> GetShaderObject(Uint index);
|
||||||
private:
|
private:
|
||||||
// Error
|
// Error
|
||||||
ErrorState m_errorState;
|
ErrorState m_errorState;
|
||||||
@@ -66,6 +75,9 @@ namespace MobileGL {
|
|||||||
|
|
||||||
// Texture
|
// Texture
|
||||||
TextureState m_textureState;
|
TextureState m_textureState;
|
||||||
|
|
||||||
|
// Program
|
||||||
|
ProgramState m_programState;
|
||||||
};
|
};
|
||||||
} // namespace GLState
|
} // namespace GLState
|
||||||
|
|
||||||
|
|||||||
@@ -4,26 +4,37 @@
|
|||||||
namespace MobileGL {
|
namespace MobileGL {
|
||||||
namespace MG_State {
|
namespace MG_State {
|
||||||
namespace GLState {
|
namespace GLState {
|
||||||
void ProgramObject::AttachShader(SharedPtr<ShaderObject> shader) {
|
bool ProgramObject::ShaderIsAttached(SharedPtr<ShaderObject> shader) {
|
||||||
m_shaders.emplace_back(shader);
|
auto it = std::find_if(m_shaders.begin(), m_shaders.end(),
|
||||||
|
[shader](const SharedPtr<ShaderObject>& s) {
|
||||||
|
return s.get() == shader.get();
|
||||||
|
});
|
||||||
|
return it != m_shaders.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProgramObject::DetachShader(SharedPtr<ShaderObject> shader) {
|
bool ProgramObject::AttachShader(SharedPtr<ShaderObject> shader) {
|
||||||
auto count = std::erase_if(
|
if (ShaderIsAttached(shader))
|
||||||
m_shaders, [shader](const SharedPtr<ShaderObject>& s) { return s.get() == shader.get(); });
|
return false;
|
||||||
|
m_shaders.emplace_back(shader);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (count == 0) {
|
SizeT ProgramObject::DetachShader(SharedPtr<ShaderObject> shader) {
|
||||||
// FIXME: handle error here
|
auto count = std::erase_if(
|
||||||
THROW_EXCEPTION("Program object does not have such shader object attached");
|
m_shaders,
|
||||||
}
|
[shader](const SharedPtr<ShaderObject>& s) {
|
||||||
|
return s.get() == shader.get();
|
||||||
|
});
|
||||||
|
|
||||||
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProgramObject::Link() {
|
void ProgramObject::Link() {
|
||||||
Vector<GLenum> shaderTypes(m_shaders.size());
|
Vector<GLenum> shaderTypes(m_shaders.size());
|
||||||
Vector<SharedPtr<glslang::TShader>> shaders(m_shaders.size());
|
Vector<SharedPtr<glslang::TShader>> shaders(m_shaders.size());
|
||||||
for (SizeT i = 0; i < m_shaders.size(); i++) {
|
for (SizeT i = 0; i < m_shaders.size(); i++) {
|
||||||
shaderTypes[i] = GetGLShaderTypeByMGLShaderStage(m_shaders[i]->m_stage);
|
shaderTypes[i] = GetGLShaderTypeByMGLShaderStage(m_shaders[i]->GetShaderStage());
|
||||||
shaders[i] = m_shaders[i]->m_shader;
|
shaders[i] = m_shaders[i]->GetCompiledShader();
|
||||||
}
|
}
|
||||||
|
|
||||||
MG_Util::ShaderTranspiler::ProgramAttrib attrib{
|
MG_Util::ShaderTranspiler::ProgramAttrib attrib{
|
||||||
@@ -44,6 +55,10 @@ namespace MobileGL {
|
|||||||
THROW_EXCEPTION(e);
|
THROW_EXCEPTION(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ProgramObject::MarkAsDeleted() {
|
||||||
|
m_deleteStatus = true;
|
||||||
|
}
|
||||||
} // namespace GLState
|
} // namespace GLState
|
||||||
} // namespace MG_State
|
} // namespace MG_State
|
||||||
} // namespace MobileGL
|
} // namespace MobileGL
|
||||||
@@ -7,10 +7,11 @@ namespace MobileGL {
|
|||||||
namespace GLState {
|
namespace GLState {
|
||||||
class ProgramObject {
|
class ProgramObject {
|
||||||
public:
|
public:
|
||||||
void AttachShader(SharedPtr<ShaderObject> shader);
|
bool ShaderIsAttached(SharedPtr<ShaderObject> shader);
|
||||||
void DetachShader(SharedPtr<ShaderObject> shader);
|
bool AttachShader(SharedPtr<ShaderObject> shader);
|
||||||
|
SizeT DetachShader(SharedPtr<ShaderObject> shader);
|
||||||
void Link();
|
void Link();
|
||||||
|
void MarkAsDeleted();
|
||||||
private:
|
private:
|
||||||
Vector<SharedPtr<ShaderObject>> m_shaders;
|
Vector<SharedPtr<ShaderObject>> m_shaders;
|
||||||
// basically this contains SPIR-V in binary format
|
// basically this contains SPIR-V in binary format
|
||||||
|
|||||||
@@ -5,20 +5,62 @@ namespace MobileGL {
|
|||||||
namespace GLState {
|
namespace GLState {
|
||||||
Uint ProgramState::CreateProgram() {
|
Uint ProgramState::CreateProgram() {
|
||||||
Uint programId = 0;
|
Uint programId = 0;
|
||||||
m_indexGenerator.Generate(1, &programId);
|
m_programIndexGenerator.Generate(1, &programId);
|
||||||
EnsureIndexAvail(programId);
|
EnsureIndexAvail(programId, m_programObjects);
|
||||||
m_programObjects[programId] = MakeShared<ProgramObject>();
|
auto programObject = MakeShared<ProgramObject>(programId);
|
||||||
|
if (programObject == nullptr)
|
||||||
|
return 0;
|
||||||
|
m_programObjects[programId] = programObject;
|
||||||
return programId;
|
return programId;
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedPtr<ProgramObject> ProgramState::GetProgramObject(Uint id) {
|
SharedPtr<ProgramObject> ProgramState::GetProgramObject(const Uint id) {
|
||||||
if (!CheckIndexAvail(id)) return nullptr; // FIXME: add error reporting here
|
if (!CheckIndexAvail(id, m_programObjects)) return nullptr; // FIXME: add error reporting here
|
||||||
return m_programObjects[id];
|
return m_programObjects[id];
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProgramState::DeleteProgram(Uint id) {
|
void ProgramState::MarkProgramObjectForDeletion(const Uint program) {
|
||||||
if (!CheckIndexAvail(id)) return; // FIXME: add error reporting here
|
if (!CheckIndexAvail(program, m_programObjects)) return; // FIXME: add error reporting here
|
||||||
m_programObjects[id].reset();
|
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 GLState
|
||||||
} // namespace MG_State
|
} // namespace MG_State
|
||||||
|
|||||||
@@ -12,20 +12,32 @@ namespace MobileGL {
|
|||||||
// To retrieve created program object, use GetProgramObject()
|
// To retrieve created program object, use GetProgramObject()
|
||||||
Uint CreateProgram();
|
Uint CreateProgram();
|
||||||
SharedPtr<ProgramObject> GetProgramObject(Uint id);
|
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:
|
private:
|
||||||
Bool CheckIndexAvail(SizeT idx) { return idx < m_programObjects.size(); }
|
template <typename T>
|
||||||
|
static Bool CheckIndexAvail(const SizeT idx, const Vector<T>& vec) {
|
||||||
void EnsureIndexAvail(SizeT idx) {
|
return idx < vec.size();
|
||||||
if (CheckIndexAvail(idx)) return;
|
|
||||||
|
|
||||||
m_programObjects.reserve(std::bit_ceil(idx));
|
|
||||||
m_programObjects.resize(idx + 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
Vector<SharedPtr<ProgramObject>> m_programObjects;
|
||||||
|
|
||||||
|
IndexGenerator<Uint> m_shaderIndexGenerator;
|
||||||
|
Vector<SharedPtr<ShaderObject>> m_shaderObjects;
|
||||||
};
|
};
|
||||||
} // namespace GLState
|
} // namespace GLState
|
||||||
} // namespace MG_State
|
} // namespace MG_State
|
||||||
|
|||||||
@@ -26,9 +26,12 @@ namespace MobileGL {
|
|||||||
|
|
||||||
const std::string e = std::format("Shader compilation failed: \nerrc: {}\nmsg: {}\n",
|
const std::string e = std::format("Shader compilation failed: \nerrc: {}\nmsg: {}\n",
|
||||||
result.error().errc, result.error().log);
|
result.error().errc, result.error().log);
|
||||||
THROW_EXCEPTION(e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ShaderObject::MarkAsDeleted() {
|
||||||
|
m_deleteStatus = true;
|
||||||
|
}
|
||||||
} // namespace GLState
|
} // namespace GLState
|
||||||
} // namespace MG_State
|
} // namespace MG_State
|
||||||
} // namespace MobileGL
|
} // namespace MobileGL
|
||||||
@@ -59,7 +59,12 @@ namespace MobileGL {
|
|||||||
ShaderObject(const ShaderStage stage) : m_stage(stage) {}
|
ShaderObject(const ShaderStage stage) : m_stage(stage) {}
|
||||||
void SetShaderSource(const std::string& source);
|
void SetShaderSource(const std::string& source);
|
||||||
void Compile();
|
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;
|
const ShaderStage m_stage;
|
||||||
std::string m_source;
|
std::string m_source;
|
||||||
SharedPtr<glslang::TShader> m_shader;
|
SharedPtr<glslang::TShader> m_shader;
|
||||||
|
|||||||
Reference in New Issue
Block a user