Fix issue with remapping global uniform blocks
Avoid adding global uniform blocks to stages that don't already have it. Otherwise multiple stages point to the same block object, and a remapping that occurs later on will change the mapping on multiple stages.
This commit is contained in:
parent
48f08c60e2
commit
5340752190
7 changed files with 332 additions and 6 deletions
|
|
@ -2124,7 +2124,12 @@ bool TProgram::crossStageCheck(EShMessages) {
|
|||
|
||||
// copy final definition of global block back into each stage
|
||||
for (unsigned int i = 0; i < activeStages.size(); ++i) {
|
||||
activeStages[i]->mergeGlobalUniformBlocks(*infoSink, uniforms);
|
||||
// We only want to merge into already existing global uniform blocks.
|
||||
// A stage that doesn't already know about the global doesn't care about it's content.
|
||||
// Otherwise we end up pointing to the same object between different stages
|
||||
// and that will break binding/set remappings
|
||||
bool mergeExistingOnly = true;
|
||||
activeStages[i]->mergeGlobalUniformBlocks(*infoSink, uniforms, mergeExistingOnly);
|
||||
}
|
||||
|
||||
// compare cross stage symbols for each stage boundary
|
||||
|
|
|
|||
|
|
@ -108,7 +108,8 @@ void TIntermediate::mergeUniformObjects(TInfoSink& infoSink, TIntermediate& unit
|
|||
unitLinkerObjects.resize(end - unitLinkerObjects.begin());
|
||||
|
||||
// merge uniforms and do error checking
|
||||
mergeGlobalUniformBlocks(infoSink, unit);
|
||||
bool mergeExistingOnly = false;
|
||||
mergeGlobalUniformBlocks(infoSink, unit, mergeExistingOnly);
|
||||
mergeLinkerObjects(infoSink, linkerObjects, unitLinkerObjects, unit.getStage());
|
||||
}
|
||||
|
||||
|
|
@ -362,7 +363,8 @@ void TIntermediate::mergeTrees(TInfoSink& infoSink, TIntermediate& unit)
|
|||
remapIds(idMaps, idShift + 1, unit);
|
||||
|
||||
mergeBodies(infoSink, globals, unitGlobals);
|
||||
mergeGlobalUniformBlocks(infoSink, unit);
|
||||
bool mergeExistingOnly = false;
|
||||
mergeGlobalUniformBlocks(infoSink, unit, mergeExistingOnly);
|
||||
mergeLinkerObjects(infoSink, linkerObjects, unitLinkerObjects, unit.getStage());
|
||||
ioAccessed.insert(unit.ioAccessed.begin(), unit.ioAccessed.end());
|
||||
}
|
||||
|
|
@ -525,7 +527,7 @@ static inline bool isSameInterface(TIntermSymbol* symbol, EShLanguage stage, TIn
|
|||
// merge the members of different stages to allow them to be linked properly
|
||||
// as a single block
|
||||
//
|
||||
void TIntermediate::mergeGlobalUniformBlocks(TInfoSink& infoSink, TIntermediate& unit)
|
||||
void TIntermediate::mergeGlobalUniformBlocks(TInfoSink& infoSink, TIntermediate& unit, bool mergeExistingOnly)
|
||||
{
|
||||
TIntermSequence& linkerObjects = findLinkerObjects()->getSequence();
|
||||
TIntermSequence& unitLinkerObjects = unit.findLinkerObjects()->getSequence();
|
||||
|
|
@ -552,7 +554,7 @@ void TIntermediate::mergeGlobalUniformBlocks(TInfoSink& infoSink, TIntermediate&
|
|||
auto itUnitBlock = unitDefaultBlocks.begin();
|
||||
for (; itUnitBlock != unitDefaultBlocks.end(); itUnitBlock++) {
|
||||
|
||||
bool add = true;
|
||||
bool add = !mergeExistingOnly;
|
||||
auto itBlock = defaultBlocks.begin();
|
||||
|
||||
for (; itBlock != defaultBlocks.end(); itBlock++) {
|
||||
|
|
|
|||
|
|
@ -915,7 +915,7 @@ public:
|
|||
void merge(TInfoSink&, TIntermediate&);
|
||||
void finalCheck(TInfoSink&, bool keepUncalled);
|
||||
|
||||
void mergeGlobalUniformBlocks(TInfoSink& infoSink, TIntermediate& unit);
|
||||
void mergeGlobalUniformBlocks(TInfoSink& infoSink, TIntermediate& unit, bool mergeExistingOnly);
|
||||
void mergeUniformObjects(TInfoSink& infoSink, TIntermediate& unit);
|
||||
void checkStageIO(TInfoSink&, TIntermediate&);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue