Tie "location = " to the right stages/versions/extensions. Also add "#define extension 1" extension support and instructions.

git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@23633 e7fa87d3-cd2b-0410-9028-fcbf551c1848
This commit is contained in:
John Kessenich 2013-10-22 00:21:04 +00:00
parent bf688510a8
commit c78a126ba6
14 changed files with 134 additions and 36 deletions

View file

@ -106,16 +106,6 @@ TParseContext::TParseContext(TSymbolTable& symt, TIntermediate& interm, bool pb,
globalOutputDefaults.clear();
}
// Get code that is not part of a shared symbol table, is specific to this shader,
// or needed by CPP (which does not use a shared symbol table).
const char* TParseContext::getPreamble()
{
if (profile == EEsProfile)
return "#define GL_ES 1\n";
else
return 0;
}
//
// Parse an array of strings using yyparse, going through the
// preprocessor to tokenize the shader strings, then through
@ -2190,8 +2180,50 @@ void TParseContext::layoutCheck(TSourceLoc loc, const TSymbol& symbol)
const TQualifier& qualifier = type.getQualifier();
if (qualifier.hasLocation()) {
// TODO: location = functionality, when is it allowed?
switch (qualifier.storage) {
case EvqVaryingIn:
{
const char* feature = "location qualifier on input";
if (profile == EEsProfile)
requireStage(loc, EShLangVertex, feature);
requireStage(loc, (EShLanguageMask)~EShLangComputeMask, feature);
if (language == EShLangVertex)
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 330, 0, feature);
else
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 410, GL_ARB_separate_shader_objects, feature);
if (type.getBasicType() == EbtBlock)
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 440, 0 /* TODO ARB_enhanced_layouts*/, "location qualifier on input block");
break;
}
case EvqVaryingOut:
{
const char* feature = "location qualifier on output";
if (profile == EEsProfile)
requireStage(loc, EShLangFragment, feature);
requireStage(loc, (EShLanguageMask)~EShLangComputeMask, feature);
if (language == EShLangFragment)
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 330, 0, feature);
else
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 410, GL_ARB_separate_shader_objects, feature);
if (type.getBasicType() == EbtBlock)
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 440, 0 /* TODO ARB_enhanced_layouts*/, "location qualifier on output block");
break;
}
case EvqUniform:
case EvqBuffer:
{
const char* feature = "location qualifier on uniform or buffer";
requireProfile(loc, ECoreProfile | ECompatibilityProfile, feature);
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, 0, feature);
if (symbol.getAsVariable() == 0)
error(loc, "can only be used on variable declaration", feature, "");
break;
}
default:
break;
}
}
if (qualifier.hasBinding()) {
// Binding checking, from the spec:
//
@ -2716,7 +2748,7 @@ void TParseContext::addBlock(TSourceLoc loc, TTypeList& typeList, const TString*
requireProfile(loc, ECoreProfile | ECompatibilityProfile, "output block");
break;
default:
error(loc, "only uniform, in, or out interface blocks are supported", blockName->c_str(), "");
error(loc, "only uniform, buffer, in, or out blocks are supported", blockName->c_str(), "");
return;
}
@ -2911,8 +2943,8 @@ void TParseContext::updateQualifierDefaults(TSourceLoc loc, TQualifier qualifier
}
//
// Update defaults for qualifiers when declared with a type, and optionally an id.
// (But, not the case of just a qualifier; this is called when a type is present.)
// Update defaults for qualifiers when declared with a type, and optionally an identifier.
// (But, not the case of just a qualifier; only when a type is present.)
//
void TParseContext::updateTypedDefaults(TSourceLoc loc, TQualifier qualifier, const TString* id)
{
@ -2925,27 +2957,24 @@ void TParseContext::updateTypedDefaults(TSourceLoc loc, TQualifier qualifier, co
return;
}
if (qualifier.storage == EvqUniform) {
switch (qualifier.storage) {
case EvqBuffer:
case EvqUniform:
if (qualifier.layoutMatrix != ElmNone)
error(loc, "cannot specify matrix layout on a variable declaration", id->c_str(), "");
if (qualifier.layoutPacking != ElpNone)
error(loc, "cannot specify packing on a variable declaration", id->c_str(), "");
} else if (qualifier.storage == EvqVaryingIn) {
if (qualifier.hasLocation()) {
if (profile == EEsProfile)
requireStage(loc, EShLangVertex, "input location layout qualifier");
}
} else if (qualifier.storage == EvqVaryingOut) {
if (qualifier.hasLocation()) {
if (profile == EEsProfile)
requireStage(loc, EShLangFragment, "output location layout qualifier");
}
} else {
break;
case EvqVaryingIn:
break;
case EvqVaryingOut:
break;
default:
if (qualifier.layoutMatrix != ElmNone ||
qualifier.layoutPacking != ElpNone)
error(loc, "layout qualifiers for matrix layout and packing only apply to uniform blocks", id->c_str(), "");
error(loc, "layout qualifiers for matrix layout and packing only apply to uniform or buffer blocks", id->c_str(), "");
else if (qualifier.hasLocation())
error(loc, "location qualifiers only appy to uniform, in, or out storage qualifiers", id->c_str(), "");
error(loc, "location qualifiers only appy to uniform, buffer, in, or out storage qualifiers", id->c_str(), "");
}
if (cantHaveId)

View file

@ -77,8 +77,14 @@
// the first function below:
//
// extensionBehavior[XXX_extension_X] = EBhDisable;
//
// 3) Add any preprocessor directives etc. in the next function, TParseContext::getPreamble():
//
// "#define XXX_extension_X 1\n"
//
// The new-line is important, as that ends preprocess tokens.
//
// 3) Insert a profile check in the feature's path (unless all profiles support the feature,
// 4) Insert a profile check in the feature's path (unless all profiles support the feature,
// for some version level). That is, call requireProfile() to constrain the profiles, e.g.:
//
// // ... in a path specific to Feature F...
@ -86,7 +92,7 @@
// ECoreProfile | ECompatibilityProfile,
// "Feature F");
//
// 4) For each profile that supports the feature, insert version/extension checks:
// 5) For each profile that supports the feature, insert version/extension checks:
//
// The mostly likely scenario is that Feature F can only be used with a
// particular profile if XXX_extension_X is present or the version is
@ -123,7 +129,7 @@
//
// ~EEsProfile
//
// 5) If built-in symbols are added by the extension, add them in Initialize.cpp; see
// 6) If built-in symbols are added by the extension, add them in Initialize.cpp; see
// the comment at the top of that file for where to put them.
//
@ -142,6 +148,23 @@ void TParseContext::initializeExtensionBehavior()
extensionBehavior[GL_3DL_array_objects] = EBhDisable;
extensionBehavior[GL_ARB_shading_language_420pack] = EBhDisable;
extensionBehavior[GL_ARB_texture_gather] = EBhDisable;
extensionBehavior[GL_ARB_separate_shader_objects] = EBhDisable;
}
// Get code that is not part of a shared symbol table, is specific to this shader,
// or needed by the preprocessor (which does not use a shared symbol table).
const char* TParseContext::getPreamble()
{
if (profile == EEsProfile) {
return
"#define GL_ES 1\n";
} else {
return
"#define GL_ARB_texture_rectangle 1\n"
"#define GL_ARB_shading_language_420pack 1\n"
"#define GL_ARB_texture_gather 1\n"
"#define GL_ARB_separate_shader_objects 1\n";
}
}
//

View file

@ -75,6 +75,7 @@ const char* const GL_ARB_texture_rectangle = "GL_ARB_texture_rectangle";
const char* const GL_3DL_array_objects = "GL_3DL_array_objects";
const char* const GL_ARB_shading_language_420pack = "GL_ARB_shading_language_420pack";
const char* const GL_ARB_texture_gather = "GL_ARB_texture_gather";
const char* const GL_ARB_separate_shader_objects = "GL_ARB_separate_shader_objects";
} // end namespace glslang