HLSL: Correct which things flattening tracks for linkage, based on caller, not type.

Includes related trackLinkage() code removal and name improvements.
This commit is contained in:
John Kessenich 2017-08-06 19:42:42 -06:00
parent 7497e7c9f3
commit d5aedc199f
5 changed files with 126 additions and 205 deletions

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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<int>(flattenData.members.size()));
flattenData.members.push_back(memberVariable);
if (track)
if (linkage)
trackLinkage(*memberVariable);
return static_cast<int>(flattenData.offsets.size())-1; // location of the member reference
return static_cast<int>(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) {

View File

@ -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<const TTypeList*, tIoKinds> ioTypeMap;
// Structure splitting data:
TMap<int, TVariable*> splitIoVars; // variables with the built-in interstage IO removed, indexed by unique ID.
TMap<int, TVariable*> splitNonIoVars; // variables with the built-in interstage IO removed, indexed by unique ID.
// Structuredbuffer shared types. Typically there are only a few.
TVector<TType*> structBufferTypes;