From 3cd0024ea86b0cae26f412c6d40effa1d3062f9c Mon Sep 17 00:00:00 2001 From: John Kessenich Date: Wed, 30 Sep 2015 18:57:47 -0600 Subject: [PATCH] GLSL front-end: Check recursively for opaque types in a block; these are all illegal. --- Test/300block.frag | 4 ++-- Test/baseResults/300block.frag.out | 5 +++-- Test/baseResults/310.vert.out | 2 +- glslang/Include/Types.h | 13 +++++++++++++ glslang/Include/revision.h | 4 ++-- glslang/MachineIndependent/ParseHelper.cpp | 5 ++--- 6 files changed, 23 insertions(+), 10 deletions(-) diff --git a/Test/300block.frag b/Test/300block.frag index e665b5e7..9820e2a9 100644 --- a/Test/300block.frag +++ b/Test/300block.frag @@ -18,10 +18,10 @@ uniform fooBlock { uvec4 bv; uniform mat2 bm2; lowp isampler2D sampler; // ERROR - struct T2 { // ERROR + struct T2 { // ERROR int a; } t; - S fbs; + S fbs; // ERROR, contains a sampler }; uniform barBlock { diff --git a/Test/baseResults/300block.frag.out b/Test/baseResults/300block.frag.out index 1704845a..67801a44 100644 --- a/Test/baseResults/300block.frag.out +++ b/Test/baseResults/300block.frag.out @@ -1,7 +1,8 @@ 300block.frag ERROR: 0:10: '' : cannot nest a structure definition inside a structure or block ERROR: 0:21: '' : cannot nest a structure definition inside a structure or block -ERROR: 0:20: 'sampler' : member of block cannot be a sampler type +ERROR: 0:20: 'sampler' : member of block cannot be or contain a sampler, image, or atomic_uint type +ERROR: 0:24: 'fbs' : member of block cannot be or contain a sampler, image, or atomic_uint type ERROR: 0:45: 'variable indexing uniform block array' : not supported for this version or the enabled extensions ERROR: 0:46: 'fooBlock' : cannot be used (maybe an instance name is needed) ERROR: 0:46: 'fooBlock' : undeclared identifier @@ -15,7 +16,7 @@ ERROR: 0:55: 'barBlockArray' : cannot be used (maybe an instance name is needed) ERROR: 0:55: 'barBlockArray' : undeclared identifier ERROR: 0:55: '*' : wrong operand types: no operation '*' exists that takes a left-hand operand of type 'const int' and a right operand of type 'temp float' (or there is no acceptable conversion) ERROR: 0:58: 'fooBlock' : redefinition -ERROR: 16 compilation errors. No code generated. +ERROR: 17 compilation errors. No code generated. Shader version: 300 diff --git a/Test/baseResults/310.vert.out b/Test/baseResults/310.vert.out index 3833d754..c03ee82b 100644 --- a/Test/baseResults/310.vert.out +++ b/Test/baseResults/310.vert.out @@ -15,7 +15,7 @@ ERROR: 0:79: 'vertex-shader array-of-struct output' : not supported with this pr ERROR: 0:81: 'vertex-shader struct output containing an array' : not supported with this profile: es ERROR: 0:83: 'vertex-shader struct output containing structure' : not supported with this profile: es ERROR: 0:85: 'std430 on a uniform block' : not supported with this profile: es -ERROR: 0:97: 's' : member of block cannot be a sampler type +ERROR: 0:97: 's' : member of block cannot be or contain a sampler, image, or atomic_uint type ERROR: 0:105: 'location' : overlapping use of location 12 ERROR: 0:107: 'input block' : not supported in this stage: vertex ERROR: 0:109: 'gl_PerVertex' : block redeclaration has extra members diff --git a/glslang/Include/Types.h b/glslang/Include/Types.h index 9d7c2807..efab2d85 100644 --- a/glslang/Include/Types.h +++ b/glslang/Include/Types.h @@ -1161,6 +1161,19 @@ public: return false; } + virtual bool containsOpaque() const + { + if (basicType == EbtSampler || basicType == EbtAtomicUint) + return true; + if (! structure) + return false; + for (unsigned int i = 0; i < structure->size(); ++i) { + if ((*structure)[i].type->containsOpaque()) + return true; + } + return false; + } + // Array editing methods. Array descriptors can be shared across // type instances. This allows all uses of the same array // to be updated at once. E.g., all nodes can be explicitly sized diff --git a/glslang/Include/revision.h b/glslang/Include/revision.h index 3a82635b..d3f11caa 100644 --- a/glslang/Include/revision.h +++ b/glslang/Include/revision.h @@ -2,5 +2,5 @@ // For the version, it uses the latest git tag followed by the number of commits. // For the date, it uses the current date (when then script is run). -#define GLSLANG_REVISION "3.0.775" -#define GLSLANG_DATE "21-Sep-2015" +#define GLSLANG_REVISION "3.0.776" +#define GLSLANG_DATE "30-Sep-2015" diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index f91d93d8..b4f0c0b6 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -4981,9 +4981,8 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con profileRequires(memberLoc, ~EEsProfile, 440, E_GL_ARB_enhanced_layouts, "offset on block member"); } - TBasicType basicType = memberType.getBasicType(); - if (basicType == EbtSampler) - error(memberLoc, "member of block cannot be a sampler type", typeList[member].type->getFieldName().c_str(), ""); + if (memberType.containsOpaque()) + error(memberLoc, "member of block cannot be or contain a sampler, image, or atomic_uint type", typeList[member].type->getFieldName().c_str(), ""); } // This might be a redeclaration of a built-in block. If so, redeclareBuiltinBlock() will