From d5aedc199f127a1f8bda8079244a1cc275c1a12d Mon Sep 17 00:00:00 2001 From: John Kessenich Date: Sun, 6 Aug 2017 19:42:42 -0600 Subject: [PATCH] HLSL: Correct which things flattening tracks for linkage, based on caller, not type. Includes related trackLinkage() code removal and name improvements. --- Test/baseResults/hlsl.flattenOpaque.frag.out | 6 + .../hlsl.structarray.flatten.frag.out | 119 ++++++++--- Test/baseResults/hlsl.structin.vert.out | 4 - hlsl/hlslParseHelper.cpp | 185 +++--------------- hlsl/hlslParseHelper.h | 17 +- 5 files changed, 126 insertions(+), 205 deletions(-) diff --git a/Test/baseResults/hlsl.flattenOpaque.frag.out b/Test/baseResults/hlsl.flattenOpaque.frag.out index 392ff722..90b28c4d 100755 --- a/Test/baseResults/hlsl.flattenOpaque.frag.out +++ b/Test/baseResults/hlsl.flattenOpaque.frag.out @@ -81,6 +81,9 @@ gl_FragCoord origin is upper left 0:35 Function Call: @main( ( temp 4-component vector of float) 0:? Linker Objects 0:? 'tex' ( uniform texture2D) +0:? 's2D' ( uniform sampler) +0:? 's2D' ( uniform sampler) +0:? 'tex' ( uniform texture2D) 0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float) @@ -169,6 +172,9 @@ gl_FragCoord origin is upper left 0:35 Function Call: @main( ( temp 4-component vector of float) 0:? Linker Objects 0:? 'tex' ( uniform texture2D) +0:? 's2D' ( uniform sampler) +0:? 's2D' ( uniform sampler) +0:? 'tex' ( uniform texture2D) 0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float) // Module Version 10000 diff --git a/Test/baseResults/hlsl.structarray.flatten.frag.out b/Test/baseResults/hlsl.structarray.flatten.frag.out index d70af800..c58f6b80 100644 --- a/Test/baseResults/hlsl.structarray.flatten.frag.out +++ b/Test/baseResults/hlsl.structarray.flatten.frag.out @@ -46,18 +46,33 @@ gl_FragCoord origin is upper left 0:? Linker Objects 0:? 'g_samp' ( uniform sampler) 0:? 'g_tex' ( uniform texture1D) +0:? 'samp' ( uniform sampler) +0:? 'tex' ( uniform texture1D) +0:? 'nonopaque_thing' ( uniform int) +0:? 'g_texdata_array[0].samp' ( uniform sampler) +0:? 'g_texdata_array[0].tex' ( uniform texture1D) +0:? 'g_texdata_array[0].nonopaque_thing' ( uniform int) +0:? 'g_texdata_array[1].samp' ( uniform sampler) +0:? 'g_texdata_array[1].tex' ( uniform texture1D) +0:? 'g_texdata_array[1].nonopaque_thing' ( uniform int) +0:? 'g_texdata_array[2].samp' ( uniform sampler) +0:? 'g_texdata_array[2].tex' ( uniform texture1D) +0:? 'g_texdata_array[2].nonopaque_thing' ( uniform int) 0:? 'g_texdata_array2[0].samp[0]' ( uniform sampler) 0:? 'g_texdata_array2[0].samp[1]' ( uniform sampler) 0:? 'g_texdata_array2[0].tex[0]' ( uniform texture1D) 0:? 'g_texdata_array2[0].tex[1]' ( uniform texture1D) +0:? 'g_texdata_array2[0].nonopaque_thing' ( uniform int) 0:? 'g_texdata_array2[1].samp[0]' ( uniform sampler) 0:? 'g_texdata_array2[1].samp[1]' ( uniform sampler) 0:? 'g_texdata_array2[1].tex[0]' ( uniform texture1D) 0:? 'g_texdata_array2[1].tex[1]' ( uniform texture1D) +0:? 'g_texdata_array2[1].nonopaque_thing' ( uniform int) 0:? 'g_texdata_array2[2].samp[0]' ( uniform sampler) 0:? 'g_texdata_array2[2].samp[1]' ( uniform sampler) 0:? 'g_texdata_array2[2].tex[0]' ( uniform texture1D) 0:? 'g_texdata_array2[2].tex[1]' ( uniform texture1D) +0:? 'g_texdata_array2[2].nonopaque_thing' ( uniform int) 0:? 'color' (layout( location=0) out 4-component vector of float) @@ -111,23 +126,38 @@ gl_FragCoord origin is upper left 0:? Linker Objects 0:? 'g_samp' ( uniform sampler) 0:? 'g_tex' ( uniform texture1D) +0:? 'samp' ( uniform sampler) +0:? 'tex' ( uniform texture1D) +0:? 'nonopaque_thing' ( uniform int) +0:? 'g_texdata_array[0].samp' ( uniform sampler) +0:? 'g_texdata_array[0].tex' ( uniform texture1D) +0:? 'g_texdata_array[0].nonopaque_thing' ( uniform int) +0:? 'g_texdata_array[1].samp' ( uniform sampler) +0:? 'g_texdata_array[1].tex' ( uniform texture1D) +0:? 'g_texdata_array[1].nonopaque_thing' ( uniform int) +0:? 'g_texdata_array[2].samp' ( uniform sampler) +0:? 'g_texdata_array[2].tex' ( uniform texture1D) +0:? 'g_texdata_array[2].nonopaque_thing' ( uniform int) 0:? 'g_texdata_array2[0].samp[0]' ( uniform sampler) 0:? 'g_texdata_array2[0].samp[1]' ( uniform sampler) 0:? 'g_texdata_array2[0].tex[0]' ( uniform texture1D) 0:? 'g_texdata_array2[0].tex[1]' ( uniform texture1D) +0:? 'g_texdata_array2[0].nonopaque_thing' ( uniform int) 0:? 'g_texdata_array2[1].samp[0]' ( uniform sampler) 0:? 'g_texdata_array2[1].samp[1]' ( uniform sampler) 0:? 'g_texdata_array2[1].tex[0]' ( uniform texture1D) 0:? 'g_texdata_array2[1].tex[1]' ( uniform texture1D) +0:? 'g_texdata_array2[1].nonopaque_thing' ( uniform int) 0:? 'g_texdata_array2[2].samp[0]' ( uniform sampler) 0:? 'g_texdata_array2[2].samp[1]' ( uniform sampler) 0:? 'g_texdata_array2[2].tex[0]' ( uniform texture1D) 0:? 'g_texdata_array2[2].tex[1]' ( uniform texture1D) +0:? 'g_texdata_array2[2].nonopaque_thing' ( uniform int) 0:? 'color' (layout( location=0) out 4-component vector of float) // Module Version 10000 // Generated by (magic number): 80001 -// Id's are bound by 66 +// Id's are bound by 78 Capability Shader Capability Sampled1D @@ -152,16 +182,27 @@ gl_FragCoord origin is upper left Name 51 "color" Name 54 "g_samp" Name 55 "g_tex" - Name 56 "g_texdata_array2[0].samp[0]" - Name 57 "g_texdata_array2[0].samp[1]" - Name 58 "g_texdata_array2[0].tex[0]" - Name 59 "g_texdata_array2[0].tex[1]" - Name 60 "g_texdata_array2[1].samp[1]" - Name 61 "g_texdata_array2[1].tex[1]" - Name 62 "g_texdata_array2[2].samp[0]" - Name 63 "g_texdata_array2[2].samp[1]" - Name 64 "g_texdata_array2[2].tex[0]" - Name 65 "g_texdata_array2[2].tex[1]" + Name 57 "nonopaque_thing" + Name 58 "g_texdata_array[0].samp" + Name 59 "g_texdata_array[0].tex" + Name 60 "g_texdata_array[0].nonopaque_thing" + Name 61 "g_texdata_array[1].nonopaque_thing" + Name 62 "g_texdata_array[2].samp" + Name 63 "g_texdata_array[2].tex" + Name 64 "g_texdata_array[2].nonopaque_thing" + Name 65 "g_texdata_array2[0].samp[0]" + Name 66 "g_texdata_array2[0].samp[1]" + Name 67 "g_texdata_array2[0].tex[0]" + Name 68 "g_texdata_array2[0].tex[1]" + Name 69 "g_texdata_array2[0].nonopaque_thing" + Name 70 "g_texdata_array2[1].samp[1]" + Name 71 "g_texdata_array2[1].tex[1]" + Name 72 "g_texdata_array2[1].nonopaque_thing" + Name 73 "g_texdata_array2[2].samp[0]" + Name 74 "g_texdata_array2[2].samp[1]" + Name 75 "g_texdata_array2[2].tex[0]" + Name 76 "g_texdata_array2[2].tex[1]" + Name 77 "g_texdata_array2[2].nonopaque_thing" Decorate 18(tex) DescriptorSet 0 Decorate 22(samp) DescriptorSet 0 Decorate 28(g_texdata_array[1].tex) DescriptorSet 0 @@ -171,16 +212,20 @@ gl_FragCoord origin is upper left Decorate 51(color) Location 0 Decorate 54(g_samp) DescriptorSet 0 Decorate 55(g_tex) DescriptorSet 0 - Decorate 56(g_texdata_array2[0].samp[0]) DescriptorSet 0 - Decorate 57(g_texdata_array2[0].samp[1]) DescriptorSet 0 - Decorate 58(g_texdata_array2[0].tex[0]) DescriptorSet 0 - Decorate 59(g_texdata_array2[0].tex[1]) DescriptorSet 0 - Decorate 60(g_texdata_array2[1].samp[1]) DescriptorSet 0 - Decorate 61(g_texdata_array2[1].tex[1]) DescriptorSet 0 - Decorate 62(g_texdata_array2[2].samp[0]) DescriptorSet 0 - Decorate 63(g_texdata_array2[2].samp[1]) DescriptorSet 0 - Decorate 64(g_texdata_array2[2].tex[0]) DescriptorSet 0 - Decorate 65(g_texdata_array2[2].tex[1]) DescriptorSet 0 + Decorate 58(g_texdata_array[0].samp) DescriptorSet 0 + Decorate 59(g_texdata_array[0].tex) DescriptorSet 0 + Decorate 62(g_texdata_array[2].samp) DescriptorSet 0 + Decorate 63(g_texdata_array[2].tex) DescriptorSet 0 + Decorate 65(g_texdata_array2[0].samp[0]) DescriptorSet 0 + Decorate 66(g_texdata_array2[0].samp[1]) DescriptorSet 0 + Decorate 67(g_texdata_array2[0].tex[0]) DescriptorSet 0 + Decorate 68(g_texdata_array2[0].tex[1]) DescriptorSet 0 + Decorate 70(g_texdata_array2[1].samp[1]) DescriptorSet 0 + Decorate 71(g_texdata_array2[1].tex[1]) DescriptorSet 0 + Decorate 73(g_texdata_array2[2].samp[0]) DescriptorSet 0 + Decorate 74(g_texdata_array2[2].samp[1]) DescriptorSet 0 + Decorate 75(g_texdata_array2[2].tex[0]) DescriptorSet 0 + Decorate 76(g_texdata_array2[2].tex[1]) DescriptorSet 0 2: TypeVoid 3: TypeFunction 2 6: TypeFloat 32 @@ -209,16 +254,28 @@ gl_FragCoord origin is upper left 51(color): 50(ptr) Variable Output 54(g_samp): 21(ptr) Variable UniformConstant 55(g_tex): 17(ptr) Variable UniformConstant -56(g_texdata_array2[0].samp[0]): 21(ptr) Variable UniformConstant -57(g_texdata_array2[0].samp[1]): 21(ptr) Variable UniformConstant -58(g_texdata_array2[0].tex[0]): 17(ptr) Variable UniformConstant -59(g_texdata_array2[0].tex[1]): 17(ptr) Variable UniformConstant -60(g_texdata_array2[1].samp[1]): 21(ptr) Variable UniformConstant -61(g_texdata_array2[1].tex[1]): 17(ptr) Variable UniformConstant -62(g_texdata_array2[2].samp[0]): 21(ptr) Variable UniformConstant -63(g_texdata_array2[2].samp[1]): 21(ptr) Variable UniformConstant -64(g_texdata_array2[2].tex[0]): 17(ptr) Variable UniformConstant -65(g_texdata_array2[2].tex[1]): 17(ptr) Variable UniformConstant + 56: TypePointer UniformConstant 14(int) +57(nonopaque_thing): 56(ptr) Variable UniformConstant +58(g_texdata_array[0].samp): 21(ptr) Variable UniformConstant +59(g_texdata_array[0].tex): 17(ptr) Variable UniformConstant +60(g_texdata_array[0].nonopaque_thing): 56(ptr) Variable UniformConstant +61(g_texdata_array[1].nonopaque_thing): 56(ptr) Variable UniformConstant +62(g_texdata_array[2].samp): 21(ptr) Variable UniformConstant +63(g_texdata_array[2].tex): 17(ptr) Variable UniformConstant +64(g_texdata_array[2].nonopaque_thing): 56(ptr) Variable UniformConstant +65(g_texdata_array2[0].samp[0]): 21(ptr) Variable UniformConstant +66(g_texdata_array2[0].samp[1]): 21(ptr) Variable UniformConstant +67(g_texdata_array2[0].tex[0]): 17(ptr) Variable UniformConstant +68(g_texdata_array2[0].tex[1]): 17(ptr) Variable UniformConstant +69(g_texdata_array2[0].nonopaque_thing): 56(ptr) Variable UniformConstant +70(g_texdata_array2[1].samp[1]): 21(ptr) Variable UniformConstant +71(g_texdata_array2[1].tex[1]): 17(ptr) Variable UniformConstant +72(g_texdata_array2[1].nonopaque_thing): 56(ptr) Variable UniformConstant +73(g_texdata_array2[2].samp[0]): 21(ptr) Variable UniformConstant +74(g_texdata_array2[2].samp[1]): 21(ptr) Variable UniformConstant +75(g_texdata_array2[2].tex[0]): 17(ptr) Variable UniformConstant +76(g_texdata_array2[2].tex[1]): 17(ptr) Variable UniformConstant +77(g_texdata_array2[2].nonopaque_thing): 56(ptr) Variable UniformConstant 4(main): 2 Function None 3 5: Label 46(ps_output): 9(ptr) Variable Function diff --git a/Test/baseResults/hlsl.structin.vert.out b/Test/baseResults/hlsl.structin.vert.out index 1256eec9..87749e20 100755 --- a/Test/baseResults/hlsl.structin.vert.out +++ b/Test/baseResults/hlsl.structin.vert.out @@ -155,8 +155,6 @@ Shader version: 500 0:? 'd' (layout( location=0) in 4-component vector of float) 0:? 'm[0]' (layout( location=1) in 4-component vector of float) 0:? 'm[1]' (layout( location=2) in 4-component vector of float) -0:? 'm[0]' (layout( location=1) in 4-component vector of float) -0:? 'm[1]' (layout( location=2) in 4-component vector of float) 0:? 'coord' (layout( location=3) in 4-component vector of float) 0:? 'b' (layout( location=4) in 4-component vector of float) 0:? 'e' (layout( location=5) in 4-component vector of float) @@ -321,8 +319,6 @@ Shader version: 500 0:? 'd' (layout( location=0) in 4-component vector of float) 0:? 'm[0]' (layout( location=1) in 4-component vector of float) 0:? 'm[1]' (layout( location=2) in 4-component vector of float) -0:? 'm[0]' (layout( location=1) in 4-component vector of float) -0:? 'm[1]' (layout( location=2) in 4-component vector of float) 0:? 'coord' (layout( location=3) in 4-component vector of float) 0:? 'b' (layout( location=4) in 4-component vector of float) 0:? 'e' (layout( location=5) in 4-component vector of float) diff --git a/hlsl/hlslParseHelper.cpp b/hlsl/hlslParseHelper.cpp index 4f4d87a7..5c88db21 100755 --- a/hlsl/hlslParseHelper.cpp +++ b/hlsl/hlslParseHelper.cpp @@ -1106,7 +1106,7 @@ void HlslParseContext::split(const TVariable& variable) { // Create a new variable: TType& splitType = split(*variable.getType().clone(), variable.getName()); - splitIoVars[variable.getUniqueId()] = makeInternalVariable(variable.getName(), splitType); + splitNonIoVars[variable.getUniqueId()] = makeInternalVariable(variable.getName(), splitType); } // Recursive implementation of split(). @@ -1169,7 +1169,7 @@ bool HlslParseContext::shouldFlatten(const TType& type) const } // Top level variable flattening: construct data -void HlslParseContext::flatten(const TVariable& variable) +void HlslParseContext::flatten(const TVariable& variable, bool linkage) { const TType& type = variable.getType(); @@ -1178,7 +1178,7 @@ void HlslParseContext::flatten(const TVariable& variable) type.getQualifier().layoutLocation))); // the item is a map pair, so first->second is the TFlattenData itself. - flatten(variable, type, entry.first->second, ""); + flatten(variable, type, entry.first->second, "", linkage); } // Recursively flatten the given variable at the provided type, building the flattenData as we go. @@ -1209,14 +1209,14 @@ void HlslParseContext::flatten(const TVariable& variable) // so the 4th flattened member in traversal order is ours. // int HlslParseContext::flatten(const TVariable& variable, const TType& type, - TFlattenData& flattenData, TString name) + TFlattenData& flattenData, TString name, bool linkage) { // If something is an arrayed struct, the array flattener will recursively call flatten() // to then flatten the struct, so this is an "if else": we don't do both. if (type.isArray()) - return flattenArray(variable, type, flattenData, name); + return flattenArray(variable, type, flattenData, name, linkage); else if (type.isStruct()) - return flattenStruct(variable, type, flattenData, name); + return flattenStruct(variable, type, flattenData, name, linkage); else { assert(0); // should never happen return -1; @@ -1226,7 +1226,7 @@ int HlslParseContext::flatten(const TVariable& variable, const TType& type, // Add a single flattened member to the flattened data being tracked for the composite // Returns true for the final flattening level. int HlslParseContext::addFlattenedMember(const TVariable& variable, const TType& type, TFlattenData& flattenData, - const TString& memberName, bool track) + const TString& memberName, bool linkage) { if (isFinalFlattening(type)) { // This is as far as we flatten. Insert the variable. @@ -1252,13 +1252,13 @@ int HlslParseContext::addFlattenedMember(const TVariable& variable, const TType& flattenData.offsets.push_back(static_cast(flattenData.members.size())); flattenData.members.push_back(memberVariable); - if (track) + if (linkage) trackLinkage(*memberVariable); - return static_cast(flattenData.offsets.size())-1; // location of the member reference + return static_cast(flattenData.offsets.size()) - 1; // location of the member reference } else { // Further recursion required - return flatten(variable, type, flattenData, memberName); + return flatten(variable, type, flattenData, memberName, linkage); } } @@ -1267,7 +1267,7 @@ int HlslParseContext::addFlattenedMember(const TVariable& variable, const TType& // // Assumes shouldFlatten() or equivalent was called first. int HlslParseContext::flattenStruct(const TVariable& variable, const TType& type, - TFlattenData& flattenData, TString name) + TFlattenData& flattenData, TString name, bool linkage) { assert(type.isStruct()); @@ -1282,7 +1282,7 @@ int HlslParseContext::flattenStruct(const TVariable& variable, const TType& type TType& dereferencedType = *members[member].type; const TString memberName = name + (name.empty() ? "" : ".") + dereferencedType.getFieldName(); - const int mpos = addFlattenedMember(variable, dereferencedType, flattenData, memberName, false); + const int mpos = addFlattenedMember(variable, dereferencedType, flattenData, memberName, linkage); flattenData.offsets[pos++] = mpos; } @@ -1294,7 +1294,7 @@ int HlslParseContext::flattenStruct(const TVariable& variable, const TType& type // // Assumes shouldFlatten() or equivalent was called first. int HlslParseContext::flattenArray(const TVariable& variable, const TType& type, - TFlattenData& flattenData, TString name) + TFlattenData& flattenData, TString name, bool linkage) { assert(type.isArray() && !type.isImplicitlySizedArray()); @@ -1313,7 +1313,7 @@ int HlslParseContext::flattenArray(const TVariable& variable, const TType& type, char elementNumBuf[20]; // sufficient for MAXINT snprintf(elementNumBuf, sizeof(elementNumBuf)-1, "[%d]", element); const int mpos = addFlattenedMember(variable, dereferencedType, flattenData, - name + elementNumBuf, true); + name + elementNumBuf, linkage); flattenData.offsets[pos++] = mpos; } @@ -1375,13 +1375,13 @@ TIntermTyped* HlslParseContext::flattenAccess(int uniqueId, int member, const TT } // Find and return the split IO TVariable for id, or nullptr if none. -TVariable* HlslParseContext::getSplitIoVar(int id) const +TVariable* HlslParseContext::getSplitNonIoVar(int id) const { - const auto splitIoVar = splitIoVars.find(id); - if (splitIoVar == splitIoVars.end()) + const auto splitNonIoVar = splitNonIoVars.find(id); + if (splitNonIoVar == splitNonIoVars.end()) return nullptr; - return splitIoVar->second; + return splitNonIoVar->second; } // Pass through to base class after remembering built-in mappings. @@ -1491,7 +1491,7 @@ void HlslParseContext::assignToInterface(TVariable& variable) for (auto member = memberList.begin(); member != memberList.end(); ++member) assignLocation(**member); } else if (wasSplit(variable.getUniqueId())) { - TVariable* splitIoVar = getSplitIoVar(variable.getUniqueId()); + TVariable* splitIoVar = getSplitNonIoVar(variable.getUniqueId()); assignLocation(*splitIoVar); } else { assignLocation(variable); @@ -1626,7 +1626,7 @@ TIntermAggregate* HlslParseContext::handleFunctionDefinition(const TSourceLoc& l if (shouldFlatten(variable->getType())) { // Expand the AST parameter nodes (but not the name mangling or symbol table view) // for structures that need to be flattened. - flatten(*variable); + flatten(*variable, false); const TTypeList* structure = variable->getType().getStruct(); for (int mem = 0; mem < (int)structure->size(); ++mem) { paramNodes = intermediate.growAggregate(paramNodes, @@ -1876,12 +1876,12 @@ TIntermNode* HlslParseContext::transformEntryPoint(const TSourceLoc& loc, TFunct // struct inputs to the vertex stage and outputs from the fragment stage must be flattened if ((language == EShLangVertex && qualifier == EvqVaryingIn) || (language == EShLangFragment && qualifier == EvqVaryingOut)) - flatten(variable); + flatten(variable, false /* don't track linkage here, it will be tracked in assignToInterface() */); // Structs containing built-ins must be split else if (variable.getType().containsBuiltIn()) split(variable); else if (!variable.getType().getQualifier().isArrayedIo(language)) - flatten(variable); + flatten(variable, false); //else // TODO: unify split and flatten, so all paths can create flattened I/O } @@ -2652,10 +2652,10 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op // If either left or right was a split structure, we must read or write it, but still have to // parallel-recurse through the unsplit structure to identify the built-in IO vars. if (isSplitLeft) - splitLeft = intermediate.addSymbol(*getSplitIoVar(left->getAsSymbolNode()->getId()), loc); + splitLeft = intermediate.addSymbol(*getSplitNonIoVar(left->getAsSymbolNode()->getId()), loc); if (isSplitRight) - splitRight = intermediate.addSymbol(*getSplitIoVar(right->getAsSymbolNode()->getId()), loc); + splitRight = intermediate.addSymbol(*getSplitNonIoVar(right->getAsSymbolNode()->getId()), loc); // This makes the whole assignment, recursing through subtypes as needed. traverse(left, right, splitLeft, splitRight); @@ -6120,133 +6120,6 @@ TSymbol* HlslParseContext::redeclareBuiltinVariable(const TSourceLoc& /*loc*/, c return nullptr; } -// -// Either redeclare the requested block, or give an error message why it can't be done. -// -// TODO: functionality: explicitly sizing members of redeclared blocks is not giving them an explicit size -void HlslParseContext::redeclareBuiltinBlock(const TSourceLoc& loc, TTypeList& newTypeList, const TString& blockName, - const TString* instanceName, TArraySizes* arraySizes) -{ - // Redeclaring a built-in block... - - // Blocks with instance names are easy to find, lookup the instance name, - // Anonymous blocks need to be found via a member. - bool builtIn; - TSymbol* block; - if (instanceName) - block = symbolTable.find(*instanceName, &builtIn); - else - block = symbolTable.find(newTypeList.front().type->getFieldName(), &builtIn); - - // If the block was not found, this must be a version/profile/stage - // that doesn't have it, or the instance name is wrong. - const char* errorName = instanceName ? instanceName->c_str() : newTypeList.front().type->getFieldName().c_str(); - if (block == nullptr) { - error(loc, "no declaration found for redeclaration", errorName, ""); - return; - } - // Built-in blocks cannot be redeclared more than once, which if happened, - // we'd be finding the already redeclared one here, rather than the built in. - if (! builtIn) { - error(loc, "can only redeclare a built-in block once, and before any use", blockName.c_str(), ""); - return; - } - - // Copy the block to make a writable version, to insert into the block table after editing. - block = symbolTable.copyUpDeferredInsert(block); - - if (block->getType().getBasicType() != EbtBlock) { - error(loc, "cannot redeclare a non block as a block", errorName, ""); - return; - } - - // Edit and error check the container against the redeclaration - // - remove unused members - // - ensure remaining qualifiers/types match - TType& type = block->getWritableType(); - TTypeList::iterator member = type.getWritableStruct()->begin(); - size_t numOriginalMembersFound = 0; - while (member != type.getStruct()->end()) { - // look for match - bool found = false; - TTypeList::const_iterator newMember; - TSourceLoc memberLoc; - memberLoc.init(); - for (newMember = newTypeList.begin(); newMember != newTypeList.end(); ++newMember) { - if (member->type->getFieldName() == newMember->type->getFieldName()) { - found = true; - memberLoc = newMember->loc; - break; - } - } - - if (found) { - ++numOriginalMembersFound; - // - ensure match between redeclared members' types - // - check for things that can't be changed - // - update things that can be changed - TType& oldType = *member->type; - const TType& newType = *newMember->type; - if (! newType.sameElementType(oldType)) - error(memberLoc, "cannot redeclare block member with a different type", - member->type->getFieldName().c_str(), ""); - if (oldType.isArray() != newType.isArray()) - error(memberLoc, "cannot change arrayness of redeclared block member", - member->type->getFieldName().c_str(), ""); - else if (! oldType.sameArrayness(newType) && oldType.isExplicitlySizedArray()) - error(memberLoc, "cannot change array size of redeclared block member", - member->type->getFieldName().c_str(), ""); - if (newType.getQualifier().isMemory()) - error(memberLoc, "cannot add memory qualifier to redeclared block member", - member->type->getFieldName().c_str(), ""); - if (newType.getQualifier().hasLayout()) - error(memberLoc, "cannot add layout to redeclared block member", - member->type->getFieldName().c_str(), ""); - if (newType.getQualifier().patch) - error(memberLoc, "cannot add patch to redeclared block member", - member->type->getFieldName().c_str(), ""); - oldType.getQualifier().centroid = newType.getQualifier().centroid; - oldType.getQualifier().sample = newType.getQualifier().sample; - oldType.getQualifier().invariant = newType.getQualifier().invariant; - oldType.getQualifier().noContraction = newType.getQualifier().noContraction; - oldType.getQualifier().smooth = newType.getQualifier().smooth; - oldType.getQualifier().flat = newType.getQualifier().flat; - oldType.getQualifier().nopersp = newType.getQualifier().nopersp; - - // go to next member - ++member; - } else { - // For missing members of anonymous blocks that have been redeclared, - // hide the original (shared) declaration. - // Instance-named blocks can just have the member removed. - if (instanceName) - member = type.getWritableStruct()->erase(member); - else { - member->type->hideMember(); - ++member; - } - } - } - - if (numOriginalMembersFound < newTypeList.size()) - error(loc, "block redeclaration has extra members", blockName.c_str(), ""); - if (type.isArray() != (arraySizes != nullptr)) - error(loc, "cannot change arrayness of redeclared block", blockName.c_str(), ""); - else if (type.isArray()) { - if (type.isExplicitlySizedArray() && arraySizes->getOuterSize() == UnsizedArraySize) - error(loc, "block already declared with size, can't redeclare as implicitly-sized", blockName.c_str(), ""); - else if (type.isExplicitlySizedArray() && type.getArraySizes() != *arraySizes) - error(loc, "cannot change array size of redeclared block", blockName.c_str(), ""); - else if (type.isImplicitlySizedArray() && arraySizes->getOuterSize() != UnsizedArraySize) - type.changeOuterArraySize(arraySizes->getOuterSize()); - } - - symbolTable.insert(*block); - - // Save it in the AST for linker use. - trackLinkage(*block); -} - // // Generate index to the array element in a structure buffer (SSBO) // @@ -7287,7 +7160,7 @@ TIntermNode* HlslParseContext::declareVariable(const TSourceLoc& loc, const TStr return nullptr; if (flattenVar) - flatten(*symbol->getAsVariable()); + flatten(*symbol->getAsVariable(), symbolTable.atGlobalLevel()); if (initializer == nullptr) return nullptr; @@ -8028,13 +7901,6 @@ void HlslParseContext::declareBlock(const TSourceLoc& loc, TType& type, const TS } } - // 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; - //} - // Make default block qualification, and adjust the member qualifications TQualifier defaultQualification; @@ -8897,7 +8763,6 @@ void HlslParseContext::addPatchConstantInvocation() } }; - // If we synthesize a built-in interface variable, we must add it to the linkage. const auto addToLinkage = [&](const TType& type, const TString* name, TIntermSymbol** symbolNode) { if (name == nullptr) { diff --git a/hlsl/hlslParseHelper.h b/hlsl/hlslParseHelper.h index f4abea33..b615a13e 100755 --- a/hlsl/hlslParseHelper.h +++ b/hlsl/hlslParseHelper.h @@ -133,7 +133,6 @@ public: void mergeQualifiers(TQualifier& dst, const TQualifier& src); int computeSamplerTypeIndex(TSampler&); TSymbol* redeclareBuiltinVariable(const TSourceLoc&, const TString&, const TQualifier&, const TShaderQualifiers&); - void redeclareBuiltinBlock(const TSourceLoc&, TTypeList& typeList, const TString& blockName, const TString* instanceName, TArraySizes* arraySizes); void paramFix(TType& type); void specializationCheck(const TSourceLoc&, const TType&, const char* op); @@ -256,19 +255,17 @@ protected: TType& split(TType& type, TString name, const TType* outerStructType = nullptr); void split(const TVariable&); bool wasSplit(const TIntermTyped* node) const; - bool wasSplit(int id) const { return splitIoVars.find(id) != splitIoVars.end(); } - TVariable* getSplitIoVar(const TIntermTyped* node) const; - TVariable* getSplitIoVar(const TVariable* var) const; - TVariable* getSplitIoVar(int id) const; + bool wasSplit(int id) const { return splitNonIoVars.find(id) != splitNonIoVars.end(); } + TVariable* getSplitNonIoVar(int id) const; void addPatchConstantInvocation(); TIntermTyped* makeIntegerIndex(TIntermTyped*); void fixBuiltInIoType(TType&); - void flatten(const TVariable& variable); - int flatten(const TVariable& variable, const TType&, TFlattenData&, TString name); - int flattenStruct(const TVariable& variable, const TType&, TFlattenData&, TString name); - int flattenArray(const TVariable& variable, const TType&, TFlattenData&, TString name); + void flatten(const TVariable& variable, bool linkage); + int flatten(const TVariable& variable, const TType&, TFlattenData&, TString name, bool linkage); + int flattenStruct(const TVariable& variable, const TType&, TFlattenData&, TString name, bool linkage); + int flattenArray(const TVariable& variable, const TType&, TFlattenData&, TString name, bool linkage); bool hasUniform(const TQualifier& qualifier) const; void clearUniform(TQualifier& qualifier); @@ -382,7 +379,7 @@ protected: TMap ioTypeMap; // Structure splitting data: - TMap splitIoVars; // variables with the built-in interstage IO removed, indexed by unique ID. + TMap splitNonIoVars; // variables with the built-in interstage IO removed, indexed by unique ID. // Structuredbuffer shared types. Typically there are only a few. TVector structBufferTypes;