Initial implementation of layout qualifiers. More to come after uniform blocks are in place.
git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@21078 e7fa87d3-cd2b-0410-9028-fcbf551c1848
This commit is contained in:
parent
3ed2db58f1
commit
e9942d26f5
8 changed files with 215 additions and 17 deletions
|
|
@ -38,6 +38,7 @@
|
|||
#include "Include/InitializeParseContext.h"
|
||||
#include "osinclude.h"
|
||||
#include <stdarg.h>
|
||||
#include <algorithm>
|
||||
|
||||
TParseContext::TParseContext(TSymbolTable& symt, TIntermediate& interm, int v, EProfile p, EShLanguage L, TInfoSink& is,
|
||||
bool fc, EShMessages m) :
|
||||
|
|
@ -706,7 +707,7 @@ bool TParseContext::globalQualifierFixAndErrorCheck(int line, TQualifier& qualif
|
|||
}
|
||||
|
||||
if (language == EShLangVertex && qualifier.storage == EvqVaryingIn &&
|
||||
(qualifier.isAuxillary() || qualifier.isInterpolation() || qualifier.isMemory() || qualifier.buffer || qualifier.invariant)) {
|
||||
(qualifier.isAuxillary() || qualifier.isInterpolation() || qualifier.isMemory() || qualifier.invariant)) {
|
||||
error(line, "vertex input cannot be further qualified", "", "");
|
||||
|
||||
return true;
|
||||
|
|
@ -748,9 +749,11 @@ bool TParseContext::mergeQualifiersErrorCheck(int line, TPublicType& left, const
|
|||
bad = true;
|
||||
}
|
||||
|
||||
// Layout qualifiers
|
||||
mergeLayoutQualifiers(line, left, right);
|
||||
|
||||
// other qualifiers
|
||||
#define MERGE_SINGLETON(field) bad |= left.qualifier.field && right.qualifier.field; left.qualifier.field |= right.qualifier.field;
|
||||
MERGE_SINGLETON(buffer);
|
||||
MERGE_SINGLETON(invariant);
|
||||
MERGE_SINGLETON(centroid);
|
||||
MERGE_SINGLETON(smooth);
|
||||
|
|
@ -1086,6 +1089,62 @@ bool TParseContext::paramErrorCheck(int line, TStorageQualifier qualifier, TType
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Layout qualifier stuff.
|
||||
//
|
||||
|
||||
// Put the id's layout qualification into the public type.
|
||||
void TParseContext::setLayoutQualifier(int line, TPublicType& publicType, TString& id)
|
||||
{
|
||||
std::transform(id.begin(), id.end(), id.begin(), ::tolower);
|
||||
if (id == TQualifier::getLayoutMatrixString(ElmColumnMajor))
|
||||
publicType.qualifier.layoutMatrix = ElmColumnMajor;
|
||||
else if (id == TQualifier::getLayoutMatrixString(ElmRowMajor))
|
||||
publicType.qualifier.layoutMatrix = ElmRowMajor;
|
||||
else if (id == TQualifier::getLayoutPackingString(ElpPacked))
|
||||
publicType.qualifier.layoutPacking = ElpPacked;
|
||||
else if (id == TQualifier::getLayoutPackingString(ElpShared))
|
||||
publicType.qualifier.layoutPacking = ElpShared;
|
||||
else if (id == TQualifier::getLayoutPackingString(ElpStd140))
|
||||
publicType.qualifier.layoutPacking = ElpStd140;
|
||||
else if (id == TQualifier::getLayoutPackingString(ElpStd430))
|
||||
publicType.qualifier.layoutPacking = ElpStd430;
|
||||
else if (id == "location")
|
||||
error(line, "requires an integer assignment (e.g., location = 4)", "location", "");
|
||||
else if (id == "binding")
|
||||
error(line, "requires an integer assignment (e.g., binding = 4)", "binding", "");
|
||||
else
|
||||
error(line, "unrecognized layout identifier", id.c_str(), "");
|
||||
}
|
||||
|
||||
// Put the id's layout qualifier value into the public type.
|
||||
void TParseContext::setLayoutQualifier(int line, TPublicType& publicType, TString& id, int value)
|
||||
{
|
||||
std::transform(id.begin(), id.end(), id.begin(), ::tolower);
|
||||
if (id == "location") {
|
||||
if ((unsigned int)value >= TQualifier::layoutLocationEnd)
|
||||
error(line, "value is too large", id.c_str(), "");
|
||||
else
|
||||
publicType.qualifier.layoutSlotLocation = value;
|
||||
} else if (id == "binding")
|
||||
error(line, "not supported", "binding", "");
|
||||
else
|
||||
error(line, "there is no such layout identifier taking an assigned value", id.c_str(), "");
|
||||
}
|
||||
|
||||
// Merge any layout qualifier information from src into dst, leaving everything else in dst alone
|
||||
void TParseContext::mergeLayoutQualifiers(int line, TPublicType& dst, const TPublicType& src)
|
||||
{
|
||||
if (src.qualifier.layoutMatrix != ElmNone)
|
||||
dst.qualifier.layoutMatrix = src.qualifier.layoutMatrix;
|
||||
|
||||
if (src.qualifier.layoutPacking != ElpNone)
|
||||
dst.qualifier.layoutPacking = src.qualifier.layoutPacking;
|
||||
|
||||
if (src.qualifier.hasLocation())
|
||||
dst.qualifier.layoutSlotLocation = src.qualifier.layoutSlotLocation;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Non-Errors.
|
||||
|
|
|
|||
|
|
@ -129,6 +129,11 @@ struct TParseContext {
|
|||
bool nonInitConstErrorCheck(int line, TString& identifier, TPublicType& type);
|
||||
bool nonInitErrorCheck(int line, TString& identifier, TPublicType& type);
|
||||
bool paramErrorCheck(int line, TStorageQualifier qualifier, TType* type);
|
||||
|
||||
void setLayoutQualifier(int line, TPublicType&, TString&);
|
||||
void setLayoutQualifier(int line, TPublicType&, TString&, int);
|
||||
void mergeLayoutQualifiers(int line, TPublicType& dest, const TPublicType& src);
|
||||
|
||||
const TFunction* findFunction(int line, TFunction* pfnCall, bool *builtIn = 0);
|
||||
bool executeInitializer(TSourceLoc line, TString& identifier, TPublicType& pType,
|
||||
TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable = 0);
|
||||
|
|
|
|||
|
|
@ -201,7 +201,7 @@ extern void yyerror(const char*);
|
|||
|
||||
%type <interm> array_specifier
|
||||
%type <interm.type> precise_qualifier invariant_qualifier interpolation_qualifier storage_qualifier precision_qualifier
|
||||
%type <interm.type> layout_qualifier layout_qualifier_id_list
|
||||
%type <interm.type> layout_qualifier layout_qualifier_id_list layout_qualifier_id
|
||||
|
||||
%type <interm.type> type_qualifier fully_specified_type type_specifier
|
||||
%type <interm.type> single_type_qualifier
|
||||
|
|
@ -1622,22 +1622,31 @@ interpolation_qualifier
|
|||
|
||||
layout_qualifier
|
||||
: LAYOUT LEFT_PAREN layout_qualifier_id_list RIGHT_PAREN {
|
||||
$$.init($1.line);
|
||||
$$ = $3;
|
||||
}
|
||||
;
|
||||
|
||||
layout_qualifier_id_list
|
||||
: layout_qualifier_id {
|
||||
$$ = $1;
|
||||
}
|
||||
| layout_qualifier_id_list COMMA layout_qualifier_id {
|
||||
$$ = $1;
|
||||
parseContext.mergeLayoutQualifiers($2.line, $$, $3);
|
||||
}
|
||||
|
||||
layout_qualifier_id
|
||||
: IDENTIFIER {
|
||||
$$.init($1.line);
|
||||
parseContext.setLayoutQualifier($1.line, $$, *$1.string);
|
||||
}
|
||||
| IDENTIFIER EQUAL INTCONSTANT {
|
||||
$$.init($1.line);
|
||||
parseContext.setLayoutQualifier($1.line, $$, *$1.string, $3.i);
|
||||
}
|
||||
| SHARED {
|
||||
| SHARED { // because "shared" is both an identifier and a keyword
|
||||
$$.init($1.line);
|
||||
parseContext.setLayoutQualifier($1.line, $$, TString("shared"));
|
||||
}
|
||||
;
|
||||
|
||||
|
|
@ -1766,8 +1775,7 @@ storage_qualifier
|
|||
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "buffer"))
|
||||
parseContext.recover();
|
||||
$$.init($1.line);
|
||||
$$.qualifier.storage = EvqUniform;
|
||||
$$.qualifier.buffer = true;
|
||||
$$.qualifier.storage = EvqUniform; // TODO: functionality: implement BUFFER
|
||||
}
|
||||
| SHARED {
|
||||
$$.init($1.line);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue