diff --git a/Test/300layout.frag b/Test/300layout.frag index 618582d3..7ba7f4ad 100644 --- a/Test/300layout.frag +++ b/Test/300layout.frag @@ -1,29 +1,15 @@ #version 300 es in vec4 pos; -in vec4 color; +layout (location = 2) in vec4 color; // ERROR -layout(location = 7) out vec4 c; +layout(location = 1) out vec4 c; layout(location = 3) out vec4 p; - -//layout(std140) uniform Transform { // layout of this block is std140 -// mat4 M1; // row_major -// layout(column_major) mat4 M2; // column major -// mat3 N1; // row_major -//}; -// -//uniform T2 { // layout of this block is shared -//... -//}; -// -//layout(column_major) uniform T3 { // shared and column_major -// mat4 M3; // column_major -// layout(row_major) mat4 m4; // row major -// mat3 N2; // column_major -//}; +layout(location = 4) out vec4 q[2]; void main() { c = color; p = pos; + q[1] = pos; } diff --git a/Test/300layout.vert b/Test/300layout.vert index 7abbed31..73d3734c 100644 --- a/Test/300layout.vert +++ b/Test/300layout.vert @@ -1,7 +1,11 @@ #version 300 es +struct s { vec4 v; }; + layout(location = 7) in vec3 c; layout(LocatioN = 3) in vec4 p; +layout(LocatioN = 9) in vec4 q[4]; // ERROR, no array +layout(LocatioN = 10) in s r[4]; // ERROR, no struct out vec4 pos; out vec3 color; @@ -32,6 +36,8 @@ out badout { // ERROR float f; }; +layout (location = 10) out vec4 badout; // ERROR + void main() { pos = p * (tblock.M1 + tblock.M2 + M4 + M3 + t2m); diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index dc69bb92..8c24c26e 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -886,6 +886,11 @@ bool TParseContext::arrayQualifierErrorCheck(int line, const TPublicType& type) if (type.qualifier.storage == EvqConst) profileRequires(line, ENoProfile, 120, "GL_3DL_array_objects", "const array"); + if (type.qualifier.storage == EvqVaryingIn && language == EShLangVertex) { + requireProfile(line, (EProfileMask)~EEsProfileMask, "vertex input arrays"); + profileRequires(line, ENoProfile, 150, 0, "vertex input arrays"); + } + return false; } @@ -1135,6 +1140,10 @@ void TParseContext::setLayoutQualifier(int line, TPublicType& publicType, TStrin error(line, "not supported", "binding", ""); else error(line, "there is no such layout identifier taking an assigned value", id.c_str(), ""); + + // TODO: error check: make sure locations are non-overlapping across the whole stage + // TODO: error check: if more than one fragment output, all must have a location + // TODO: error check: output arrays can only be indexed with a constant (es 300) } // Merge any layout qualifier information from src into dst, leaving everything else in dst alone @@ -1569,6 +1578,14 @@ void TParseContext::updateDefaults(int line, const TPublicType& publicType, cons cantHaveId = true; defaultGlobalQualification.layoutPacking = qualifier.layoutPacking; } + } else if (qualifier.storage == EvqVaryingIn) { + if (qualifier.hasLayout() && language != EShLangVertex) { + error(line, "can only use location layout qualifier on a vertex input or fragment output", id->c_str(), ""); + } + } else if (qualifier.storage == EvqVaryingOut) { + if (qualifier.hasLayout() && language != EShLangFragment) { + error(line, "can only use location layout qualifier on a vertex input or fragment output", id->c_str(), ""); + } } if (cantHaveId && id) {