mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-07 19:58:32 +09:00
[Fix] (MG_Impl/GLImpl): validate compute program queries [skip ci]
This commit is contained in:
@@ -453,12 +453,12 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
MGLOG_D("%s: %s = %d", __func__, MG_Util::ConvertGLEnumToString(pname).c_str(), *params);
|
||||
break;
|
||||
case GL_COMPUTE_WORK_GROUP_SIZE: { // GL >= 4.3
|
||||
if (!programObject->GetLinkStatus()) {
|
||||
if (!programObject->GetLinkStatus() || programObject->GetShaderIndexByStage(ShaderStage::Compute) < 0) {
|
||||
MG_State::pGLContext->RecordError(
|
||||
ErrorCode::InvalidOperation,
|
||||
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
|
||||
std::to_string(program) +
|
||||
" is not a program object that has been linked."));
|
||||
" is not a linked program object with a compute shader."));
|
||||
return;
|
||||
}
|
||||
params[0] = static_cast<GLint>(programObject->GetComputeLocalSize(0));
|
||||
|
||||
@@ -62,6 +62,40 @@ namespace {
|
||||
return glType;
|
||||
}
|
||||
}
|
||||
|
||||
static bool ComputeShaderDeclaresLocalSize(const MobileGL::String& source) {
|
||||
bool inLineComment = false;
|
||||
bool inBlockComment = false;
|
||||
for (MobileGL::SizeT i = 0; i < source.length(); ++i) {
|
||||
if (inLineComment) {
|
||||
inLineComment = source[i] != '\n';
|
||||
continue;
|
||||
}
|
||||
if (inBlockComment) {
|
||||
if (source[i] == '*' && i + 1 < source.length() && source[i + 1] == '/') {
|
||||
inBlockComment = false;
|
||||
++i;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (source[i] == '/' && i + 1 < source.length()) {
|
||||
if (source[i + 1] == '/') {
|
||||
inLineComment = true;
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
if (source[i + 1] == '*') {
|
||||
inBlockComment = true;
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (source.compare(i, 11, "local_size_") == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
namespace MobileGL::MG_State::GLState {
|
||||
@@ -170,9 +204,6 @@ namespace MobileGL::MG_State::GLState {
|
||||
}
|
||||
m_detachedShaders.clear();
|
||||
|
||||
Vector<GLenum> shaderTypes(m_shaders.size());
|
||||
Vector<SharedPtr<glslang::TShader>> shaders(m_shaders.size());
|
||||
|
||||
if (addDefaultFSIfMissingForRenderingPipelineProgram) {
|
||||
AddDefaultFragmentShaderIfMissing();
|
||||
}
|
||||
@@ -187,6 +218,9 @@ namespace MobileGL::MG_State::GLState {
|
||||
return a->GetShaderStage() < b->GetShaderStage();
|
||||
});
|
||||
|
||||
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] = MG_Util::ConvertShaderStageToGLEnum(m_shaders[i]->GetShaderStage());
|
||||
MGLOG_D("ProgramObject %u: Preparing shader[%zu] stage %s at %p", m_externalIndex, i,
|
||||
@@ -201,6 +235,12 @@ namespace MobileGL::MG_State::GLState {
|
||||
m_externalIndex, i, m_infoLog.c_str());
|
||||
return;
|
||||
}
|
||||
if (m_shaders[i]->GetShaderStage() == ShaderStage::Compute &&
|
||||
!ComputeShaderDeclaresLocalSize(m_shaders[i]->GetShaderSource())) {
|
||||
m_infoLog = "Compute shader is missing a local_size layout declaration.";
|
||||
MGLOG_E("ProgramObject %u: Link failed - %s", m_externalIndex, m_infoLog.c_str());
|
||||
return;
|
||||
}
|
||||
shaders[i] = m_shaders[i]->GetCompiledShader();
|
||||
MGLOG_D("ProgramObject %u: shader[%zu] compiled shader ptr %p, src len %zu", m_externalIndex, i,
|
||||
shaders[i].get(), m_shaders[i]->GetShaderSource().length());
|
||||
|
||||
Reference in New Issue
Block a user