[Fix] (MG_Backend/DirectGLES|MG_Impl/Program): Correct UBO binding.

This commit is contained in:
BZLZHH
2025-11-15 21:37:08 +08:00
parent 4cb82e2e50
commit e85b067314
3 changed files with 191 additions and 135 deletions
+151 -110
View File
@@ -12,7 +12,7 @@ namespace MobileGL {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"`shader` is not a value generated by OpenGL."));
std::to_string(shader) + " is not a valid name."));
return false;
}
return true;
@@ -25,7 +25,8 @@ namespace MobileGL {
if (!shaderObject) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "`shader` is not a shader object."));
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
std::to_string(shader) + " is not a shader object."));
return nullptr;
}
return shaderObject;
@@ -36,7 +37,7 @@ namespace MobileGL {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"`program` is not a value generated by OpenGL"));
std::to_string(program) + " is not a valid name."));
return false;
}
return true;
@@ -49,7 +50,8 @@ namespace MobileGL {
if (!programObject) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "`program` is not a program object."));
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
std::to_string(program) + " is not a program object."));
return nullptr;
}
return programObject;
@@ -71,10 +73,11 @@ namespace MobileGL {
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`."));
MG_State::pGLContext->RecordError(ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
std::to_string(shader) +
" is already attached to " +
std::to_string(program) + "."));
return;
}
}
@@ -84,7 +87,8 @@ namespace MobileGL {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"`index` is greater than or equal to `GL_MAX_VERTEX_ATTRIBS`."));
"index " + std::to_string(index) +
" is greater than or equal to `GL_MAX_VERTEX_ATTRIBS`."));
return;
}
@@ -92,7 +96,8 @@ namespace MobileGL {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"`name` starts with the reserved prefix `gl_`."));
"name " + std::string(name) +
" starts with the reserved prefix `gl_`."));
return;
}
@@ -154,7 +159,8 @@ namespace MobileGL {
if (bufSize < 0) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "`bufSize` is less than 0."));
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"bufSize " + std::to_string(bufSize) + " is less than 0."));
return;
}
auto programObject = TryToGetProgramObject(program);
@@ -165,7 +171,9 @@ namespace MobileGL {
ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>(
"MG_Impl/GLImpl", __func__,
"`index` is greater than or equal to the number of active attribute variables in `program`."));
"index " + std::to_string(index) +
" is greater than or equal to the number of active attribute variables in " +
std::to_string(program) + "."));
return;
}
if (type != nullptr) *type = programObject->GetAttribType(index);
@@ -179,7 +187,8 @@ namespace MobileGL {
if (bufSize < 0) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "`bufSize` is less than 0."));
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"bufSize " + std::to_string(bufSize) + " is less than 0."));
return;
}
auto programObject = TryToGetProgramObject(program);
@@ -190,7 +199,9 @@ namespace MobileGL {
ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>(
"MG_Impl/GLImpl", __func__,
"`index` is greater than or equal to the number of active uniform variables in `program`."));
"index " + std::to_string(index) +
" is greater than or equal to the number of active uniform variables in " +
std::to_string(program) + "."));
return;
}
@@ -204,7 +215,8 @@ namespace MobileGL {
if (maxCount < 0) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "`maxCount` is less than 0."));
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"maxCount " + std::to_string(maxCount) + " is less than 0."));
return;
}
auto programObject = TryToGetProgramObject(program);
@@ -296,7 +308,8 @@ namespace MobileGL {
MGLOG_D("%s: %s", __func__, MG_Util::ConvertGLEnumToString(pname).c_str());
MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "`pname` is not an accepted value."));
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"pname " + std::to_string(pname) + " is not an accepted value."));
return;
}
}
@@ -332,7 +345,8 @@ namespace MobileGL {
default:
MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "`pname` is not an accepted value."));
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"pname " + std::to_string(pname) + " is not an accepted value."));
return;
}
}
@@ -349,7 +363,8 @@ namespace MobileGL {
if (bufSize < 0) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "`bufSize` is less than 0."));
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"bufSize " + std::to_string(bufSize) + " is less than 0."));
}
auto shaderObject = TryToGetShaderObject(shader);
@@ -375,7 +390,7 @@ namespace MobileGL {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"`program` has not been successfully linked."));
std::to_string(program) + " has not been successfully linked."));
return;
}
@@ -384,8 +399,9 @@ namespace MobileGL {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"`location` does not correspond to a valid uniform variable location "
"for the specified program object."));
"location " + std::to_string(location) +
" does not correspond to a valid uniform variable location "
"for the specified program object."));
return;
}
@@ -395,8 +411,9 @@ namespace MobileGL {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"`location` does not correspond to a valid uniform variable location "
"for the specified program object."));
"location " + std::to_string(location) +
" does not correspond to a valid uniform variable location "
"for the specified program object."));
return;
}
@@ -446,7 +463,8 @@ namespace MobileGL {
if (count < 0) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "`count` is less than 0."));
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"count " + std::to_string(count) + " is less than 0."));
return;
}
@@ -504,8 +522,10 @@ namespace MobileGL {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"`location` is an invalid uniform location for the current program "
"object and `location` is not equal to -1."));
"location " + std::to_string(location) +
" is an invalid uniform location for the current program "
"object and location " +
std::to_string(location) + " is not equal to -1."));
return;
}
@@ -631,8 +651,10 @@ namespace MobileGL {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"`location` is an invalid uniform location for the current program "
"object and `location` is not equal to -1."));
"location " + std::to_string(location) +
" is an invalid uniform location for the current program "
"object and location " +
std::to_string(location) + " is not equal to -1."));
return;
}
@@ -667,8 +689,10 @@ namespace MobileGL {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"`location` is an invalid uniform location for the current program "
"object and `location` is not equal to -1."));
"location " + std::to_string(location) +
" is an invalid uniform location for the current program "
"object and location " +
std::to_string(location) + " is not equal to -1."));
return;
}
@@ -703,8 +727,10 @@ namespace MobileGL {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"`location` is an invalid uniform location for the current program "
"object and `location` is not equal to -1."));
"location " + std::to_string(location) +
" is an invalid uniform location for the current program "
"object and location " +
std::to_string(location) + " is not equal to -1."));
return;
}
@@ -723,133 +749,147 @@ namespace MobileGL {
}
GLuint GetUniformBlockIndex_State(GLuint program, const GLchar* uniformBlockName) {
auto programObject = TryToGetProgramObject(program);
const auto& programObject = TryToGetProgramObject(program);
if (!programObject) return GL_INVALID_INDEX;
if (!programObject->GetLinkStatus()) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "`program` is not a program object that has been linked."));
ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
std::to_string(program) +
" is not a program object that has been linked."));
return GL_INVALID_INDEX;
}
auto index = programObject->GetUniformBlockIndex(uniformBlockName);
const auto& index = programObject->GetUniformBlockIndex(uniformBlockName);
return index;
}
void UniformBlockBinding_State(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding) {
auto programObject = MG_State::pGLContext->GetCurrentProgram();
if (programObject == nullptr) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "There is no current program object."));
return;
}
const auto& programObject = TryToGetProgramObject(program);
if (!programObject->GetLinkStatus()) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "`program` is not a program object that has been linked."));
MG_State::pGLContext->RecordError(ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"Program object" +
std::to_string(program) +
" that has been linked."));
return;
}
if (!programObject->IsActiveUniformBlock(uniformBlockIndex)) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "`uniformBlockIndex` is greater than or equal to the value of `GL_ACTIVE_UNIFORM_BLOCKS` or is not the index of an active uniform block in program."));
ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>(
"MG_Impl/GLImpl", __func__,
"uniformBlockIndex " + std::to_string(uniformBlockIndex) +
" is greater than or equal to the value of `GL_ACTIVE_UNIFORM_BLOCKS` or is "
"not the index of an active uniform block in program" +
std::to_string(program) + "."));
return;
}
programObject->SetUniformBlockBinding(uniformBlockIndex, uniformBlockBinding);
}
void GetActiveUniformBlockiv_State(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params) {
auto programObject = MG_State::pGLContext->GetCurrentProgram();
if (programObject == nullptr) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "There is no current program object."));
return;
}
const auto& programObject = TryToGetProgramObject(program);
if (!programObject->GetLinkStatus()) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "`program` is not a program object that has been linked."));
MG_State::pGLContext->RecordError(ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"Program object" +
std::to_string(program) +
" that has been linked."));
return;
}
if (!programObject->IsActiveUniformBlock(uniformBlockIndex)) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "`uniformBlockIndex` is greater than or equal to the value of `GL_ACTIVE_UNIFORM_BLOCKS` or is not the index of an active uniform block in program."));
ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>(
"MG_Impl/GLImpl", __func__,
"uniformBlockIndex " + std::to_string(uniformBlockIndex) +
" is greater than or equal to the value of `GL_ACTIVE_UNIFORM_BLOCKS` or is "
"not the index of an active uniform block in program" +
std::to_string(program) + "."));
return;
}
switch (pname) {
case GL_UNIFORM_BLOCK_DATA_SIZE: {
*params = programObject->GetUBOSizeAt(uniformBlockIndex);
MGLOG_D("%s: GL_UNIFORM_BLOCK_DATA_SIZE = %d", __func__, *params);
break;
}
case GL_UNIFORM_BLOCK_NAME_LENGTH: {
*params = programObject->GetUniformBlockName(uniformBlockIndex).length() + 1;
MGLOG_D("%s: GL_UNIFORM_BLOCK_NAME_LENGTH = %d", __func__, *params);
break;
}
case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS: {
// TODO: deduct global ubo?
*params = programObject->GetActiveUniformBlocksCount();
MGLOG_D("%s: GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS = %d", __func__, *params);
break;
}
case GL_UNIFORM_BLOCK_BINDING: {
// TODO
MGLOG_D("%s: GL_UNIFORM_BLOCK_BINDING = <TODO>", __func__, *params);
}
case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
case GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER:
case GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER:
case GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER:
case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
case GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER:
default:
MGLOG_E("%s: unknown pname = %p %s", __func__, pname, MG_Util::ConvertGLEnumToString(pname).c_str());
MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "`pname` is not one of the accepted tokens."));
break;
case GL_UNIFORM_BLOCK_DATA_SIZE: {
*params = programObject->GetUBOSizeAt(uniformBlockIndex);
MGLOG_D("%s: GL_UNIFORM_BLOCK_DATA_SIZE = %d", __func__, *params);
break;
}
case GL_UNIFORM_BLOCK_NAME_LENGTH: {
*params = programObject->GetUniformBlockName(uniformBlockIndex).length() + 1;
MGLOG_D("%s: GL_UNIFORM_BLOCK_NAME_LENGTH = %d", __func__, *params);
break;
}
case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS: {
// TODO: deduct global ubo?
*params = programObject->GetActiveUniformBlocksCount();
MGLOG_D("%s: GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS = %d", __func__, *params);
break;
}
case GL_UNIFORM_BLOCK_BINDING: {
// TODO
MGLOG_D("%s: GL_UNIFORM_BLOCK_BINDING = <TODO>", __func__, *params);
}
case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
case GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER:
case GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER:
case GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER:
case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
case GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER:
default:
MGLOG_E("%s: unknown pname = %p %s", __func__, pname, MG_Util::ConvertGLEnumToString(pname).c_str());
MG_State::pGLContext->RecordError(
ErrorCode::InvalidEnum, MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"pname " + std::to_string(pname) +
" is not one of the accepted tokens."));
break;
}
}
void GetActiveUniformBlockName_State(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName) {
void GetActiveUniformBlockName_State(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length,
GLchar* uniformBlockName) {
auto programObject = TryToGetProgramObject(program);
if (!programObject) return;
if (!programObject->GetLinkStatus()) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "`program` is not a program object that has been linked."));
ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
std::to_string(program) +
" is not a program object that has been linked."));
return;
}
if (!programObject->IsActiveUniformBlock(uniformBlockIndex)) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "`uniformBlockIndex` is greater than or equal to the value of `GL_ACTIVE_UNIFORM_BLOCKS` or is not the index of an active uniform block in program."));
ErrorCode::InvalidValue,
MakeShared<GenericErrorInfo>(
"MG_Impl/GLImpl", __func__,
"uniformBlockIndex " + std::to_string(uniformBlockIndex) +
" is greater than or equal to the value of `GL_ACTIVE_UNIFORM_BLOCKS` or is "
"not the index of an active uniform block in program."));
return;
}
const auto& name = programObject->GetUniformBlockName(uniformBlockIndex);
CopyStr(bufSize, length, uniformBlockName, name.c_str(), name.length());
MGLOG_D("%s: \"%s\" at uniformBlockIndex %02d, length = %d", __func__, uniformBlockName, uniformBlockIndex, *length);
MGLOG_D("%s: \"%s\" at uniformBlockIndex %02d, length = %d", __func__, uniformBlockName, uniformBlockIndex,
*length);
}
void BindFragDataLocation_State(GLuint program, GLuint colorNumber, const char* name) {
auto programObject = TryToGetProgramObject(program);
if (programObject == nullptr) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "`program` is not the name of a program object."));
ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
std::to_string(program) + " is not the name of a program object."));
return;
}
if (strncmp(name, "gl_", 3) == 0) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"`name` starts with the reserved prefix `gl_`."));
ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"name " + std::string(name) +
" starts with the reserved prefix `gl_`."));
return;
}
// TODO: Emit error "if `colorNumber` is greater than or equal to `GL_MAX_DRAW_BUFFERS`"
@@ -862,16 +902,16 @@ namespace MobileGL {
auto programObject = TryToGetProgramObject(program);
if (programObject == nullptr) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__, "`program` is not the name of a program object."));
ErrorCode::InvalidOperation,
MakeShared<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
std::to_string(program) + " is not the name of a program object."));
return -1;
}
return programObject->GetFragmentDataLocation(name);
}
void ValidateProgram_State(GLuint program) {
// THROW_UNIMPL_EXCEPTION;
// THROW_UNIMPL_EXCEPTION;
}
void AttachShader(GLuint program, GLuint shader) {
@@ -1068,7 +1108,8 @@ namespace MobileGL {
GetActiveUniformBlockiv_State(program, uniformBlockIndex, pname, params);
}
void GetActiveUniformBlockName(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName) {
void GetActiveUniformBlockName(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length,
GLchar* uniformBlockName) {
GetActiveUniformBlockName_State(program, uniformBlockIndex, bufSize, length, uniformBlockName);
}