--- /dev/null
+hlsl.buffer.frag
+Shader version: 450
+gl_FragCoord origin is upper left
+0:? Sequence
+0:23 Function Definition: PixelShaderFunction(vf4; (global 4-component vector of float)
+0:20 Function Parameters:
+0:20 'input' (in 4-component vector of float)
+0:? Sequence
+0:21 Branch: Return with expression
+0:21 add (temp 4-component vector of float)
+0:21 add (temp 4-component vector of float)
+0:21 add (temp 4-component vector of float)
+0:21 'input' (in 4-component vector of float)
+0:21 v1: direct index for structure (layout(column_major std140 ) uniform 4-component vector of float)
+0:21 'anon@0' (layout(column_major std140 ) uniform block{layout(column_major std140 ) uniform 4-component vector of float v1})
+0:21 Constant:
+0:21 0 (const uint)
+0:21 add (temp 4-component vector of float)
+0:21 v2: direct index for structure (layout(column_major std430 ) buffer 4-component vector of float)
+0:21 'anon@1' (layout(column_major std430 ) buffer block{layout(column_major std430 ) buffer 4-component vector of float v2})
+0:21 Constant:
+0:21 0 (const uint)
+0:21 v3: direct index for structure (layout(column_major std140 ) uniform 4-component vector of float)
+0:21 'anon@2' (layout(column_major std140 ) uniform block{layout(column_major std140 ) uniform 4-component vector of float v3, layout(column_major std140 ) uniform int i3})
+0:21 Constant:
+0:21 0 (const uint)
+0:21 v4: direct index for structure (layout(column_major std430 ) buffer 4-component vector of float)
+0:21 'anon@3' (layout(column_major std430 ) buffer block{layout(column_major std430 ) buffer 4-component vector of float v4, layout(column_major std430 ) buffer int i4})
+0:21 Constant:
+0:21 0 (const uint)
+0:? Linker Objects
+0:? 'anon@0' (layout(column_major std140 ) uniform block{layout(column_major std140 ) uniform 4-component vector of float v1})
+0:? 'anon@1' (layout(column_major std430 ) buffer block{layout(column_major std430 ) buffer 4-component vector of float v2})
+0:? 'anon@2' (layout(column_major std140 ) uniform block{layout(column_major std140 ) uniform 4-component vector of float v3, layout(column_major std140 ) uniform int i3})
+0:? 'anon@3' (layout(column_major std430 ) buffer block{layout(column_major std430 ) buffer 4-component vector of float v4, layout(column_major std430 ) buffer int i4})
+
+
+Linked fragment stage:
+
+
+Shader version: 450
+gl_FragCoord origin is upper left
+0:? Sequence
+0:23 Function Definition: PixelShaderFunction(vf4; (global 4-component vector of float)
+0:20 Function Parameters:
+0:20 'input' (in 4-component vector of float)
+0:? Sequence
+0:21 Branch: Return with expression
+0:21 add (temp 4-component vector of float)
+0:21 add (temp 4-component vector of float)
+0:21 add (temp 4-component vector of float)
+0:21 'input' (in 4-component vector of float)
+0:21 v1: direct index for structure (layout(column_major std140 ) uniform 4-component vector of float)
+0:21 'anon@0' (layout(column_major std140 ) uniform block{layout(column_major std140 ) uniform 4-component vector of float v1})
+0:21 Constant:
+0:21 0 (const uint)
+0:21 add (temp 4-component vector of float)
+0:21 v2: direct index for structure (layout(column_major std430 ) buffer 4-component vector of float)
+0:21 'anon@1' (layout(column_major std430 ) buffer block{layout(column_major std430 ) buffer 4-component vector of float v2})
+0:21 Constant:
+0:21 0 (const uint)
+0:21 v3: direct index for structure (layout(column_major std140 ) uniform 4-component vector of float)
+0:21 'anon@2' (layout(column_major std140 ) uniform block{layout(column_major std140 ) uniform 4-component vector of float v3, layout(column_major std140 ) uniform int i3})
+0:21 Constant:
+0:21 0 (const uint)
+0:21 v4: direct index for structure (layout(column_major std430 ) buffer 4-component vector of float)
+0:21 'anon@3' (layout(column_major std430 ) buffer block{layout(column_major std430 ) buffer 4-component vector of float v4, layout(column_major std430 ) buffer int i4})
+0:21 Constant:
+0:21 0 (const uint)
+0:? Linker Objects
+0:? 'anon@0' (layout(column_major std140 ) uniform block{layout(column_major std140 ) uniform 4-component vector of float v1})
+0:? 'anon@1' (layout(column_major std430 ) buffer block{layout(column_major std430 ) buffer 4-component vector of float v2})
+0:? 'anon@2' (layout(column_major std140 ) uniform block{layout(column_major std140 ) uniform 4-component vector of float v3, layout(column_major std140 ) uniform int i3})
+0:? 'anon@3' (layout(column_major std430 ) buffer block{layout(column_major std430 ) buffer 4-component vector of float v4, layout(column_major std430 ) buffer int i4})
+
+// Module Version 10000
+// Generated by (magic number): 80001
+// Id's are bound by 39
+
+ Capability Shader
+ 1: ExtInstImport "GLSL.std.450"
+ MemoryModel Logical GLSL450
+ EntryPoint Fragment 4 "PixelShaderFunction" 9
+ ExecutionMode 4 OriginUpperLeft
+ Source HLSL 450
+ Name 4 "PixelShaderFunction"
+ Name 9 "input"
+ Name 11 ""
+ MemberName 11 0 "v1"
+ Name 13 ""
+ Name 20 ""
+ MemberName 20 0 "v2"
+ Name 22 ""
+ Name 25 ""
+ MemberName 25 0 "v3"
+ MemberName 25 1 "i3"
+ Name 27 ""
+ Name 32 ""
+ MemberName 32 0 "v4"
+ MemberName 32 1 "i4"
+ Name 34 ""
+ MemberDecorate 11 0 Offset 0
+ Decorate 11 Block
+ Decorate 13 DescriptorSet 0
+ MemberDecorate 20 0 Offset 0
+ Decorate 20 BufferBlock
+ Decorate 22 DescriptorSet 0
+ MemberDecorate 25 0 Offset 0
+ MemberDecorate 25 1 Offset 16
+ Decorate 25 Block
+ Decorate 27 DescriptorSet 0
+ MemberDecorate 32 0 Offset 0
+ MemberDecorate 32 1 Offset 16
+ Decorate 32 BufferBlock
+ Decorate 34 DescriptorSet 0
+ 2: TypeVoid
+ 3: TypeFunction 2
+ 6: TypeFloat 32
+ 7: TypeVector 6(float) 4
+ 8: TypePointer Input 7(fvec4)
+ 9(input): 8(ptr) Variable Input
+ 11: TypeStruct 7(fvec4)
+ 12: TypePointer Uniform 11(struct)
+ 13: 12(ptr) Variable Uniform
+ 14: TypeInt 32 1
+ 15: 14(int) Constant 0
+ 16: TypePointer Uniform 7(fvec4)
+ 20: TypeStruct 7(fvec4)
+ 21: TypePointer Uniform 20(struct)
+ 22: 21(ptr) Variable Uniform
+ 25: TypeStruct 7(fvec4) 14(int)
+ 26: TypePointer Uniform 25(struct)
+ 27: 26(ptr) Variable Uniform
+ 32: TypeStruct 7(fvec4) 14(int)
+ 33: TypePointer Uniform 32(struct)
+ 34: 33(ptr) Variable Uniform
+4(PixelShaderFunction): 2 Function None 3
+ 5: Label
+ 10: 7(fvec4) Load 9(input)
+ 17: 16(ptr) AccessChain 13 15
+ 18: 7(fvec4) Load 17
+ 19: 7(fvec4) FAdd 10 18
+ 23: 16(ptr) AccessChain 22 15
+ 24: 7(fvec4) Load 23
+ 28: 16(ptr) AccessChain 27 15
+ 29: 7(fvec4) Load 28
+ 30: 7(fvec4) FAdd 24 29
+ 31: 7(fvec4) FAdd 19 30
+ 35: 16(ptr) AccessChain 34 15
+ 36: 7(fvec4) Load 35
+ 37: 7(fvec4) FAdd 31 36
+ ReturnValue 37
+ FunctionEnd
--- /dev/null
+cbuffer {
+ float4 v1;
+};
+
+tbuffer {
+ float4 v2;
+};
+
+cbuffer cbufName : register(b2) {
+ float4 v3;
+ int i3 : packoffset(c1.y);
+};
+
+tbuffer tbufName : register(b8) {
+ float4 v4 : packoffset(c1);
+ int i4 : packoffset(c3);
+};
+
+float4 PixelShaderFunction(float4 input) : COLOR0
+{
+ return input + v1 + v2 + v3 + v4;
+}
// 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 "SPIRV99.1332"
-#define GLSLANG_DATE "21-Jul-2016"
+#define GLSLANG_REVISION "SPIRV99.1337"
+#define GLSLANG_DATE "25-Jul-2016"
{"hlsl.array.frag", "PixelShaderFunction"},
{"hlsl.assoc.frag", "PixelShaderFunction"},
{"hlsl.attribute.frag", "PixelShaderFunction"},
+ {"hlsl.buffer.frag", "PixelShaderFunction"},
{"hlsl.cast.frag", "PixelShaderFunction"},
{"hlsl.discard.frag", "PixelShaderFunction"},
{"hlsl.doLoop.frag", "PixelShaderFunction"},
if (typedefDecl)
parseContext.declareTypedef(idToken.loc, *idToken.string, type, arraySizes);
+ else if (type.getBasicType() == EbtBlock)
+ parseContext.declareBlock(idToken.loc, type, idToken.string);
else {
// Declare the variable and add any initializer code to the AST.
// The top-level node is always made into an aggregate, as that's
TQualifier qualifier;
qualifier.clear();
acceptQualifier(qualifier);
+ TSourceLoc loc = token.loc;
// type_specifier
if (! acceptType(type))
return false;
- type.getQualifier() = qualifier;
+ if (type.getBasicType() == EbtBlock) {
+ // the type was a block, which set some parts of the qualifier
+ parseContext.mergeQualifiers(loc, type.getQualifier(), qualifier, true);
+ // further, it can create an anonymous instance of the block
+ if (peekTokenClass(EHTokSemicolon))
+ parseContext.declareBlock(loc, type);
+ } else
+ type.getQualifier() = qualifier;
return true;
}
break;
case EHTokStruct:
+ case EHTokCBuffer:
+ case EHTokTBuffer:
return acceptStruct(type);
break;
}
// struct
-// : STRUCT IDENTIFIER LEFT_BRACE struct_declaration_list RIGHT_BRACE
-// | STRUCT LEFT_BRACE struct_declaration_list RIGHT_BRACE
+// : struct_type IDENTIFIER post_decls LEFT_BRACE struct_declaration_list RIGHT_BRACE
+// | struct_type post_decls LEFT_BRACE struct_declaration_list RIGHT_BRACE
+//
+// struct_type
+// : STRUCT
+// | CBUFFER
+// | TBUFFER
//
bool HlslGrammar::acceptStruct(TType& type)
{
+ // This qualifier.storage will tell us whether it's an AST block or
+ // just a struct.
+ TQualifier qualifier;
+ qualifier.clear();
+
+ // CBUFFER
+ if (acceptTokenClass(EHTokCBuffer))
+ qualifier.storage = EvqUniform;
+ // TBUFFER
+ else if (acceptTokenClass(EHTokTBuffer))
+ qualifier.storage = EvqBuffer;
// STRUCT
- if (! acceptTokenClass(EHTokStruct))
+ else if (! acceptTokenClass(EHTokStruct))
return false;
// IDENTIFIER
advanceToken();
}
+ // post_decls
+ acceptPostDecls(type);
+
// LEFT_BRACE
if (! acceptTokenClass(EHTokLeftBrace)) {
expected("{");
}
// create the user-defined type
- new(&type) TType(typeList, structName);
-
- // If it was named, which means it can be reused later, add
- // it to the symbol table.
- if (structName.size() > 0) {
+ if (qualifier.storage == EvqTemporary)
+ new(&type) TType(typeList, structName);
+ else
+ new(&type) TType(typeList, structName, qualifier); // sets EbtBlock
+
+ // If it was named, which means the type can be reused later, add
+ // it to the symbol table. (Unless it's a block, in which
+ // case the name is not a type.)
+ if (type.getBasicType() != EbtBlock && structName.size() > 0) {
TVariable* userTypeDef = new TVariable(&structName, type, true);
if (! parseContext.symbolTable.insert(*userTypeDef))
parseContext.error(token.loc, "redefinition", structName.c_str(), "struct");
break;
}
// TODO: process the packoffset information
+ // c1.y means component y of location slot 1
} else if (! acceptIdentifier(idToken)) {
expected("semantic or packoffset or register");
return;
break;
}
// TODO: process the register information
+ // b2 means buffer 2
} else {
// semantic, in idToken.string
parseContext.handleSemantic(type, *idToken.string);
if (dst.storage == EvqTemporary || dst.storage == EvqGlobal)
dst.storage = src.storage;
else if ((dst.storage == EvqIn && src.storage == EvqOut) ||
- (dst.storage == EvqOut && src.storage == EvqIn))
+ (dst.storage == EvqOut && src.storage == EvqIn))
dst.storage = EvqInOut;
else if ((dst.storage == EvqIn && src.storage == EvqConst) ||
- (dst.storage == EvqConst && src.storage == EvqIn))
+ (dst.storage == EvqConst && src.storage == EvqIn))
dst.storage = EvqConstReadOnly;
else if (src.storage != EvqTemporary && src.storage != EvqGlobal)
error(loc, "too many storage qualifiers", GetStorageQualifierString(src.storage), "");
//
// Do everything needed to add an interface block.
//
-void HlslParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, const TString* instanceName, TArraySizes* arraySizes)
+void HlslParseContext::declareBlock(const TSourceLoc& loc, TType& type, const TString* instanceName, TArraySizes* arraySizes)
{
+ assert(type.getWritableStruct() != nullptr);
+
+ TTypeList& typeList = *type.getWritableStruct();
// fix and check for member storage qualifiers and types that don't belong within a block
for (unsigned int member = 0; member < typeList.size(); ++member) {
TType& memberType = *typeList[member].type;
TQualifier& memberQualifier = memberType.getQualifier();
const TSourceLoc& memberLoc = typeList[member].loc;
globalQualifierFix(memberLoc, memberQualifier);
- memberQualifier.storage = currentBlockQualifier.storage;
+ memberQualifier.storage = type.getQualifier().storage;
}
// This might be a redeclaration of a built-in block. If so, redeclareBuiltinBlock() will
// do all the rest.
- if (! symbolTable.atBuiltInLevel() && builtInName(*blockName)) {
- redeclareBuiltinBlock(loc, typeList, *blockName, instanceName, arraySizes);
- return;
- }
+ //if (! symbolTable.atBuiltInLevel() && builtInName(*blockName)) {
+ // redeclareBuiltinBlock(loc, typeList, *blockName, instanceName, arraySizes);
+ // return;
+ //}
// Make default block qualification, and adjust the member qualifications
TQualifier defaultQualification;
- switch (currentBlockQualifier.storage) {
+ switch (type.getQualifier().storage) {
case EvqUniform: defaultQualification = globalUniformDefaults; break;
case EvqBuffer: defaultQualification = globalBufferDefaults; break;
case EvqVaryingIn: defaultQualification = globalInputDefaults; break;
// Special case for "push_constant uniform", which has a default of std430,
// contrary to normal uniform defaults, and can't have a default tracked for it.
- if (currentBlockQualifier.layoutPushConstant && ! currentBlockQualifier.hasPacking())
- currentBlockQualifier.layoutPacking = ElpStd430;
+ if (type.getQualifier().layoutPushConstant && ! type.getQualifier().hasPacking())
+ type.getQualifier().layoutPacking = ElpStd430;
// fix and check for member layout qualifiers
- mergeObjectLayoutQualifiers(defaultQualification, currentBlockQualifier, true);
+ mergeObjectLayoutQualifiers(defaultQualification, type.getQualifier(), true);
bool memberWithLocation = false;
bool memberWithoutLocation = false;
if (memberQualifier.hasPacking())
error(memberLoc, "member of block cannot have a packing layout qualifier", typeList[member].type->getFieldName().c_str(), "");
if (memberQualifier.hasLocation()) {
- switch (currentBlockQualifier.storage) {
+ switch (type.getQualifier().storage) {
case EvqVaryingIn:
case EvqVaryingOut:
memberWithLocation = true;
}
// Process the members
- fixBlockLocations(loc, currentBlockQualifier, typeList, memberWithLocation, memberWithoutLocation);
- fixBlockXfbOffsets(currentBlockQualifier, typeList);
- fixBlockUniformOffsets(currentBlockQualifier, typeList);
+ fixBlockLocations(loc, type.getQualifier(), typeList, memberWithLocation, memberWithoutLocation);
+ fixBlockXfbOffsets(type.getQualifier(), typeList);
+ fixBlockUniformOffsets(type.getQualifier(), typeList);
// reverse merge, so that currentBlockQualifier now has all layout information
// (can't use defaultQualification directly, it's missing other non-layout-default-class qualifiers)
- mergeObjectLayoutQualifiers(currentBlockQualifier, defaultQualification, true);
+ mergeObjectLayoutQualifiers(type.getQualifier(), defaultQualification, true);
//
// Build and add the interface block as a new type named 'blockName'
//
- TType blockType(&typeList, *blockName, currentBlockQualifier);
+ //?? need the block name to be a typename?
+ TType blockType(&typeList, "" /* *blockName */, type.getQualifier());
if (arraySizes)
blockType.newArraySizes(*arraySizes);
// whose type is EbtBlock, but without all the structure; that will come from the type
// the instances point to.
//
- TType blockNameType(EbtBlock, blockType.getQualifier().storage);
- TVariable* blockNameVar = new TVariable(blockName, blockNameType);
- if (! symbolTable.insert(*blockNameVar)) {
- TSymbol* existingName = symbolTable.find(*blockName);
- if (existingName->getType().getBasicType() == EbtBlock) {
- if (existingName->getType().getQualifier().storage == blockType.getQualifier().storage) {
- error(loc, "Cannot reuse block name within the same interface:", blockName->c_str(), blockType.getStorageQualifierString());
- return;
- }
- } else {
- error(loc, "block name cannot redefine a non-block name", blockName->c_str(), "");
- return;
- }
- }
+ //??TType blockNameType(EbtBlock, blockType.getQualifier().storage);
+ //??TVariable* blockNameVar = new TVariable(blockName, blockNameType);
+ //if (! symbolTable.insert(*blockNameVar)) {
+ // TSymbol* existingName = symbolTable.find(*blockName);
+ // if (existingName->getType().getBasicType() == EbtBlock) {
+ // if (existingName->getType().getQualifier().storage == blockType.getQualifier().storage) {
+ // error(loc, "Cannot reuse block name within the same interface:", blockName->c_str(), blockType.getStorageQualifierString());
+ // return;
+ // }
+ // } else {
+ // error(loc, "block name cannot redefine a non-block name", blockName->c_str(), "");
+ // return;
+ // }
+ //}
// Add the variable, as anonymous or named instanceName.
// Make an anonymous variable if no name was provided.
TVariable& variable = *new TVariable(instanceName, blockType);
if (! symbolTable.insert(variable)) {
if (*instanceName == "")
- error(loc, "nameless block contains a member that already has a name at global scope", blockName->c_str(), "");
+ error(loc, "nameless block contains a member that already has a name at global scope", "" /* blockName->c_str() */, "");
else
error(loc, "block instance name redefinition", variable.getName().c_str(), "");
TIntermTyped* addConstructor(const TSourceLoc&, TIntermNode*, const TType&, TOperator);
TIntermTyped* constructAggregate(TIntermNode*, const TType&, int, const TSourceLoc&);
TIntermTyped* constructBuiltIn(const TType&, TOperator, TIntermTyped*, const TSourceLoc&, bool subset);
- void declareBlock(const TSourceLoc&, TTypeList& typeList, const TString* instanceName = 0, TArraySizes* arraySizes = 0);
+ void declareBlock(const TSourceLoc&, TType&, const TString* instanceName = 0, TArraySizes* arraySizes = 0);
void fixBlockLocations(const TSourceLoc&, TQualifier&, TTypeList&, bool memberWithLocation, bool memberWithoutLocation);
void fixBlockXfbOffsets(TQualifier&, TTypeList&);
void fixBlockUniformOffsets(TQualifier&, TTypeList&);
bool postMainReturn; // if inside a function, true if the function is the entry point and this is after a return statement
const TType* currentFunctionType; // the return type of the function that's currently being parsed
bool functionReturnsValue; // true if a non-void function has a return
- const TString* blockName;
- TQualifier currentBlockQualifier;
TBuiltInResource resources;
TLimits& limits;
(*KeywordMap)["Texture2DMSArray"] = EHTokTexture2DMSarray;
(*KeywordMap)["struct"] = EHTokStruct;
+ (*KeywordMap)["cbuffer"] = EHTokCBuffer;
+ (*KeywordMap)["tbuffer"] = EHTokTBuffer;
(*KeywordMap)["typedef"] = EHTokTypedef;
(*KeywordMap)["true"] = EHTokBoolConstant;
// variable, user type, ...
case EHTokStruct:
case EHTokTypedef:
+ case EHTokCBuffer:
+ case EHTokTBuffer:
+ return keyword;
case EHTokBoolConstant:
if (strcmp("true", tokenText) == 0)
EHTokIdentifier,
EHTokTypeName,
EHTokStruct,
+ EHTokCBuffer,
+ EHTokTBuffer,
EHTokTypedef,
// constant