Commit 3ed2db58 by John Kessenich

Put in correct rules for multiple versions of qualification and typing of inputs…

Put in correct rules for multiple versions of qualification and typing of inputs and outputs. Also, removed EvqAttribute, merging it with EvqVaryingIn. git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@21064 e7fa87d3-cd2b-0410-9028-fcbf551c1848
parent ad3663be
......@@ -23,10 +23,19 @@ in vec2 c2D;
in vec3 c3D;
in vec4 c4D;
in int ic1D;
in ivec2 ic2D;
in ivec3 ic3D;
in ivec4 ic4D;
flat in int ic1D;
flat in ivec2 ic2D;
flat in ivec3 ic3D;
flat in ivec4 ic4D;
in sampler2D bads; // ERROR
struct s {
int i;
sampler2D s; // ERROR
};
out s badout; // ERROR
void main()
{
......
......@@ -7,6 +7,8 @@ uniform mat4x4 m44;
in vec3 v3;
in vec2 v2;
in vec4 bad[10];
void main()
{
int id = gl_VertexID + gl_InstanceID;
......
#version 300 es
in uvec2 t;
in uvec2 badu; // ERROR
flat in uvec2 t;
in float f;
in vec2 tc;
in bool bad; // ERROR
uniform uvec4 v;
uniform int i;
uniform bool b;
......
......@@ -62,9 +62,8 @@ enum TStorageQualifier {
EvqTemporary, // For temporaries (within a function), read/write
EvqGlobal, // For globals read/write
EvqConst, // User defined constants and non-output parameters in functions
EvqAttribute, // Readonly
EvqVaryingIn, // readonly, fragment shaders only
EvqVaryingOut, // vertex shaders only read/write
EvqVaryingIn, // pipeline input, read only
EvqVaryingOut, // pipeline ouput, read/write
EvqUniform, // Readonly, vertex and fragment
// parameters
......@@ -103,9 +102,8 @@ __inline const char* getStorageQualifierString(TStorageQualifier q)
case EvqGlobal: return "global"; break;
case EvqConst: return "const"; break;
case EvqConstReadOnly: return "const (read only)"; break;
case EvqAttribute: return "attribute"; break;
case EvqVaryingIn: return "varying in"; break;
case EvqVaryingOut: return "varying out"; break;
case EvqVaryingIn: return "shader in"; break;
case EvqVaryingOut: return "shader out"; break;
case EvqUniform: return "uniform"; break;
case EvqIn: return "in"; break;
case EvqOut: return "out"; break;
......
......@@ -217,6 +217,18 @@ public:
bool restrict : 1;
bool readonly : 1;
bool writeonly : 1;
bool isMemory()
{
return coherent || volatil || restrict || readonly || writeonly;
}
bool isInterpolation()
{
return flat || smooth || nopersp;
}
bool isAuxillary()
{
return centroid || patch || sample;
}
};
class TPublicType {
......
......@@ -328,9 +328,8 @@ bool TParseContext::lValueErrorCheck(int line, const char* op, TIntermTyped* nod
switch (node->getQualifier().storage) {
case EvqConst: message = "can't modify a const"; break;
case EvqConstReadOnly: message = "can't modify a const"; break;
case EvqAttribute: message = "can't modify an attribute"; break;
case EvqVaryingIn: message = "can't modify shader input"; break;
case EvqUniform: message = "can't modify a uniform"; break;
case EvqVaryingIn: message = "can't modify a varying"; break;
case EvqInstanceId: message = "can't modify gl_InstanceID"; break;
case EvqVertexId: message = "can't modify gl_VertexID"; break;
case EvqFace: message = "can't modify gl_FrontFace"; break;
......@@ -617,7 +616,7 @@ bool TParseContext::samplerErrorCheck(int line, const TPublicType& pType, const
{
if (pType.type == EbtStruct) {
if (containsSampler(*pType.userDef)) {
error(line, reason, TType::getBasicString(pType.type), "(structure contains a sampler/image)");
error(line, reason, TType::getBasicString(pType.type), "(structure cannot contain a sampler or image)");
return true;
}
......@@ -632,8 +631,13 @@ bool TParseContext::samplerErrorCheck(int line, const TPublicType& pType, const
return false;
}
bool TParseContext::globalQualifierFixAndErrorCheck(int line, TQualifier& qualifier)
bool TParseContext::globalQualifierFixAndErrorCheck(int line, TQualifier& qualifier, const TPublicType& publicType)
{
if (! symbolTable.atGlobalLevel())
return false;
// First, move from parameter qualifiers to shader in/out qualifiers
switch (qualifier.storage) {
case EvqIn:
profileRequires(line, ENoProfile, 130, 0, "in for stage inputs");
......@@ -645,31 +649,68 @@ bool TParseContext::globalQualifierFixAndErrorCheck(int line, TQualifier& qualif
profileRequires(line, EEsProfile, 300, 0, "out for stage outputs");
qualifier.storage = EvqVaryingOut;
break;
case EvqVaryingIn:
case EvqVaryingOut:
break;
case EvqInOut:
qualifier.storage = EvqVaryingIn;
error(line, "cannot use 'inout' at global scope", "", "");
return true;
default: break; // some compilers want this
default:
break;
}
return false;
}
// Do non in/out error checks
bool TParseContext::structQualifierErrorCheck(int line, const TPublicType& pType)
{
if ((pType.qualifier.storage == EvqVaryingIn ||
pType.qualifier.storage == EvqVaryingOut ||
pType.qualifier.storage == EvqAttribute) &&
pType.type == EbtStruct) {
if (qualifier.storage != EvqUniform && samplerErrorCheck(line, publicType, "samplers and images must be uniform"))
return true;
error(line, "cannot be used with a structure", getStorageQualifierString(pType.qualifier.storage), "");
if (qualifier.storage != EvqVaryingIn && qualifier.storage != EvqVaryingOut)
return false;
// now, knowing it is a shader in/out, do all the in/out semantic checks
if (publicType.type == EbtBool) {
error(line, "cannot be bool", getStorageQualifierString(qualifier.storage), "");
return true;
}
if (pType.qualifier.storage != EvqUniform && samplerErrorCheck(line, pType, "samplers and images must be uniform"))
if (language == EShLangVertex && qualifier.storage == EvqVaryingIn) {
if (publicType.type == EbtStruct) {
error(line, "cannot be a structure or array", getStorageQualifierString(qualifier.storage), "");
return true;
}
if (publicType.arraySizes) {
requireProfile(line, (EProfileMask)~EEsProfileMask, "vertex input arrays");
profileRequires(line, ENoProfile, 150, 0, "vertex input arrays");
}
}
if (language == EShLangFragment && qualifier.storage == EvqVaryingOut) {
profileRequires(line, EEsProfile, 300, 0, "fragment shader output");
if (publicType.type == EbtStruct) {
error(line, "cannot be a structure", getStorageQualifierString(qualifier.storage), "");
return true;
}
}
if (publicType.type == EbtInt || publicType.type == EbtUint || publicType.type == EbtDouble) {
profileRequires(line, EEsProfile, 300, 0, "shader input/output");
if (language != EShLangVertex && qualifier.storage == EvqVaryingIn && ! qualifier.flat ||
language != EShLangFragment && qualifier.storage == EvqVaryingOut && ! qualifier.flat) {
error(line, "must be qualified as 'flat'", getStorageQualifierString(qualifier.storage), TType::getBasicString(publicType.type));
return true;
}
}
if (language == EShLangVertex && qualifier.storage == EvqVaryingIn &&
(qualifier.isAuxillary() || qualifier.isInterpolation() || qualifier.isMemory() || qualifier.buffer || qualifier.invariant)) {
error(line, "vertex input cannot be further qualified", "", "");
return true;
}
return false;
}
......@@ -832,13 +873,8 @@ bool TParseContext::arraySizeErrorCheck(int line, TIntermTyped* expr, int& size)
//
// Returns true if there is an error.
//
bool TParseContext::arrayQualifierErrorCheck(int line, TPublicType type)
bool TParseContext::arrayQualifierErrorCheck(int line, const TPublicType& type)
{
if (type.qualifier.storage == EvqAttribute) {
error(line, "cannot declare arrays of this qualifier", TType(type).getCompleteString().c_str(), "");
return true;
}
if (type.qualifier.storage == EvqConst)
profileRequires(line, ENoProfile, 120, "GL_3DL_array_objects", "const array");
......@@ -870,7 +906,7 @@ bool TParseContext::arraySizeRequiredErrorCheck(int line, int& size)
//
// Returns true if there was an error.
//
bool TParseContext::arrayErrorCheck(int line, TString& identifier, TPublicType type, TVariable*& variable)
bool TParseContext::arrayErrorCheck(int line, TString& identifier, const TPublicType& type, TVariable*& variable)
{
//
// Don't check for reserved word use until after we know it's not in the symbol table,
......
......@@ -112,15 +112,15 @@ struct TParseContext {
bool globalErrorCheck(int line, bool global, const char* token);
bool constructorErrorCheck(int line, TIntermNode*, TFunction&, TOperator, TType*);
bool arraySizeErrorCheck(int line, TIntermTyped* expr, int& size);
bool arrayQualifierErrorCheck(int line, TPublicType type);
bool arrayQualifierErrorCheck(int line, const TPublicType&);
bool arraySizeRequiredErrorCheck(int line, int& size);
bool arrayErrorCheck(int line, TString& identifier, TPublicType type, TVariable*& variable);
bool arrayErrorCheck(int line, TString& identifier, const TPublicType&, TVariable*& variable);
bool insertBuiltInArrayAtGlobalLevel();
bool voidErrorCheck(int, const TString&, const TPublicType&);
bool boolErrorCheck(int, const TIntermTyped*);
bool boolErrorCheck(int, const TPublicType&);
bool samplerErrorCheck(int line, const TPublicType& pType, const char* reason);
bool globalQualifierFixAndErrorCheck(int line, TQualifier&);
bool globalQualifierFixAndErrorCheck(int line, TQualifier&, const TPublicType&);
bool structQualifierErrorCheck(int line, const TPublicType& pType);
bool mergeQualifiersErrorCheck(int line, TPublicType& left, const TPublicType& right);
void setDefaultPrecision(int line, TPublicType&, TPrecisionQualifier);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment