From 0f5e3ad23cb69c46bfbeff9c61047e6ceccfa62e Mon Sep 17 00:00:00 2001 From: John Kessenich <cepheus@frii.com> Date: Sun, 29 May 2016 18:24:31 -0600 Subject: [PATCH] Fix issue #313: Catch internal attempts to modify built-in symbols that don't exist. Also beefed up support for running compute shaders is #version 420, but this work is only partially done. --- Test/420.comp | 7 +++++ Test/baseResults/420.comp.out | 32 ++++++++++++++++++++++ glslang/MachineIndependent/Initialize.cpp | 11 +++++++- glslang/MachineIndependent/ParseHelper.cpp | 20 ++++++++++++-- glslang/MachineIndependent/ShaderLang.cpp | 6 ++-- gtests/AST.FromFile.cpp | 1 + 6 files changed, 70 insertions(+), 7 deletions(-) create mode 100755 Test/420.comp create mode 100755 Test/baseResults/420.comp.out diff --git a/Test/420.comp b/Test/420.comp new file mode 100755 index 000000000..4e6885bea --- /dev/null +++ b/Test/420.comp @@ -0,0 +1,7 @@ +#version 420 + +layout(local_size_x = 2) in; // ERROR, no compute + +#extension GL_ARB_compute_shader : enable + +layout(local_size_x = 2) in; diff --git a/Test/baseResults/420.comp.out b/Test/baseResults/420.comp.out new file mode 100755 index 000000000..c21df0769 --- /dev/null +++ b/Test/baseResults/420.comp.out @@ -0,0 +1,32 @@ +420.comp +Warning, version 420 is not yet complete; most version-specific features are present, but some are missing. +ERROR: 0:3: 'gl_WorkgroupSize' : not supported for this version or the enabled extensions +WARNING: 0:5: '#extension' : extension is only partially supported: GL_ARB_compute_shader +ERROR: 1 compilation errors. No code generated. + + +Shader version: 420 +Requested GL_ARB_compute_shader +local_size = (2, 1, 1) +ERROR: node is still EOpNull! +0:? Linker Objects +0:? 'gl_WorkGroupSize' (const 3-component vector of uint WorkGroupSize) +0:? 2 (const uint) +0:? 1 (const uint) +0:? 1 (const uint) + + +Linked compute stage: + +ERROR: Linking compute stage: Missing entry point: Each stage requires one "void main()" entry point + +Shader version: 420 +Requested GL_ARB_compute_shader +local_size = (2, 1, 1) +ERROR: node is still EOpNull! +0:? Linker Objects +0:? 'gl_WorkGroupSize' (const 3-component vector of uint WorkGroupSize) +0:? 2 (const uint) +0:? 1 (const uint) +0:? 1 (const uint) + diff --git a/glslang/MachineIndependent/Initialize.cpp b/glslang/MachineIndependent/Initialize.cpp index 034962a27..c4ffdf204 100644 --- a/glslang/MachineIndependent/Initialize.cpp +++ b/glslang/MachineIndependent/Initialize.cpp @@ -1871,7 +1871,7 @@ void TBuiltIns::initialize(int version, EProfile profile, int spv, int vulkan) // //============================================================================ - if ((profile != EEsProfile && version >= 430) || + if ((profile != EEsProfile && version >= 420) || (profile == EEsProfile && version >= 310)) { stageBuiltins[EShLangCompute].append( "in highp uvec3 gl_NumWorkGroups;" @@ -3896,6 +3896,15 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, int spv, int vul BuiltInVariable("gl_LocalInvocationID", EbvLocalInvocationId, symbolTable); BuiltInVariable("gl_GlobalInvocationID", EbvGlobalInvocationId, symbolTable); BuiltInVariable("gl_LocalInvocationIndex", EbvLocalInvocationIndex, symbolTable); + + if (profile != EEsProfile && version < 430) { + symbolTable.setVariableExtensions("gl_NumWorkGroups", 1, &E_GL_ARB_compute_shader); + symbolTable.setVariableExtensions("gl_WorkGroupSize", 1, &E_GL_ARB_compute_shader); + symbolTable.setVariableExtensions("gl_WorkGroupID", 1, &E_GL_ARB_compute_shader); + symbolTable.setVariableExtensions("gl_LocalInvocationID", 1, &E_GL_ARB_compute_shader); + symbolTable.setVariableExtensions("gl_GlobalInvocationID", 1, &E_GL_ARB_compute_shader); + symbolTable.setVariableExtensions("gl_LocalInvocationIndex", 1, &E_GL_ARB_compute_shader); + } break; default: diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index 15d0dae31..39344cf5d 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -622,10 +622,20 @@ void TParseContext::makeEditable(TSymbol*& symbol) intermediate.addSymbolLinkageNode(linkage, *symbol); } +// Return a writable version of the variable 'name'. +// +// Return nullptr if 'name' is not found. This should mean +// something is seriously wrong (e.g., compiler asking self for +// built-in that doesn't exist). TVariable* TParseContext::getEditableVariable(const char* name) { bool builtIn; TSymbol* symbol = symbolTable.find(name, &builtIn); + + assert(symbol != nullptr); + if (symbol == nullptr) + return nullptr; + if (builtIn) makeEditable(symbol); @@ -3844,7 +3854,7 @@ void TParseContext::finalErrorCheck() break; case EShLangCompute: if (profile != EEsProfile && version < 430) - requireExtensions(getCurrentLoc(), 1, &E_GL_ARB_compute_shader, "tessellation shaders"); + requireExtensions(getCurrentLoc(), 1, &E_GL_ARB_compute_shader, "compute shaders"); break; default: break; @@ -4222,6 +4232,8 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi case EShLangCompute: if (id.compare(0, 11, "local_size_") == 0) { + profileRequires(loc, EEsProfile, 310, 0, "gl_WorkgroupSize"); + profileRequires(loc, ~EEsProfile, 430, E_GL_ARB_compute_shader, "gl_WorkgroupSize"); if (id == "local_size_x") { publicType.shaderQualifiers.localSize[0] = value; return; @@ -5967,7 +5979,8 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con // Fix the existing constant gl_WorkGroupSize with this new information. TVariable* workGroupSize = getEditableVariable("gl_WorkGroupSize"); - workGroupSize->getWritableConstArray()[i].setUConst(intermediate.getLocalSize(i)); + if (workGroupSize != nullptr) + workGroupSize->getWritableConstArray()[i].setUConst(intermediate.getLocalSize(i)); } } else error(loc, "can only apply to 'in'", "local_size", ""); @@ -5980,7 +5993,8 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con error(loc, "can only apply to 'in'", "local_size id", ""); // Set the workgroup built-in variable as a specialization constant TVariable* workGroupSize = getEditableVariable("gl_WorkGroupSize"); - workGroupSize->getWritableType().getQualifier().specConstant = true; + if (workGroupSize != nullptr) + workGroupSize->getWritableType().getQualifier().specConstant = true; } } if (publicType.shaderQualifiers.earlyFragmentTests) { diff --git a/glslang/MachineIndependent/ShaderLang.cpp b/glslang/MachineIndependent/ShaderLang.cpp index 1446298ce..1abb55357 100644 --- a/glslang/MachineIndependent/ShaderLang.cpp +++ b/glslang/MachineIndependent/ShaderLang.cpp @@ -235,10 +235,10 @@ bool InitializeSymbolTables(TInfoSink& infoSink, TSymbolTable** commonTable, TS InitializeStageSymbolTable(*builtInParseables, version, profile, spv, vulkan, EShLangGeometry, infoSink, commonTable, symbolTables); // check for compute - if ((profile != EEsProfile && version >= 430) || + if ((profile != EEsProfile && version >= 420) || (profile == EEsProfile && version >= 310)) InitializeStageSymbolTable(*builtInParseables, version, profile, spv, vulkan, EShLangCompute, infoSink, commonTable, symbolTables); - + return true; } @@ -417,7 +417,7 @@ bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNo (profile != EEsProfile && version < 420)) { correct = false; infoSink.info.message(EPrefixError, "#version: compute shaders require es profile with version 310 or above, or non-es profile with version 420 or above"); - version = profile == EEsProfile ? 310 : 430; // 420 supports the extension, correction is to 430 which does not + version = profile == EEsProfile ? 310 : 420; } break; default: diff --git a/gtests/AST.FromFile.cpp b/gtests/AST.FromFile.cpp index 3f4819a30..08ec919b0 100644 --- a/gtests/AST.FromFile.cpp +++ b/gtests/AST.FromFile.cpp @@ -113,6 +113,7 @@ INSTANTIATE_TEST_CASE_P( "110scope.vert", "300scope.vert", "400.frag", + "420.comp", "420.frag", "420.vert", "420.geom", -- GitLab