Front-end: Fix issue #443: dvec3 uses only 2 components of second location.
This commit is contained in:
parent
34177cd778
commit
426542ba57
@ -23,7 +23,6 @@ ERROR: 0:66: 'component' : doubles cannot start on an odd-numbered component
|
|||||||
ERROR: 0:67: 'component' : type overflows the available 4 components
|
ERROR: 0:67: 'component' : type overflows the available 4 components
|
||||||
ERROR: 0:71: 'location' : overlapping use of location 55
|
ERROR: 0:71: 'location' : overlapping use of location 55
|
||||||
ERROR: 0:75: 'location' : overlapping use of location 57
|
ERROR: 0:75: 'location' : overlapping use of location 57
|
||||||
ERROR: 0:77: 'location' : overlapping use of location 59
|
|
||||||
ERROR: 0:78: 'location' : overlapping use of location 59
|
ERROR: 0:78: 'location' : overlapping use of location 59
|
||||||
ERROR: 0:95: 'xfb layout qualifier' : can only be used on an output
|
ERROR: 0:95: 'xfb layout qualifier' : can only be used on an output
|
||||||
ERROR: 0:101: 'xfb_offset' : cannot declare a default, use a full declaration
|
ERROR: 0:101: 'xfb_offset' : cannot declare a default, use a full declaration
|
||||||
@ -55,7 +54,7 @@ ERROR: 0:187: 'assign' : l-value required "gl_BaseVertexARB" (can't modify shad
|
|||||||
ERROR: 0:188: 'assign' : l-value required "gl_BaseInstanceARB" (can't modify shader input)
|
ERROR: 0:188: 'assign' : l-value required "gl_BaseInstanceARB" (can't modify shader input)
|
||||||
ERROR: 0:189: 'assign' : l-value required "gl_DrawIDARB" (can't modify shader input)
|
ERROR: 0:189: 'assign' : l-value required "gl_DrawIDARB" (can't modify shader input)
|
||||||
ERROR: 0:190: 'glBaseInstanceARB' : undeclared identifier
|
ERROR: 0:190: 'glBaseInstanceARB' : undeclared identifier
|
||||||
ERROR: 55 compilation errors. No code generated.
|
ERROR: 54 compilation errors. No code generated.
|
||||||
|
|
||||||
|
|
||||||
Shader version: 440
|
Shader version: 440
|
||||||
|
@ -2,5 +2,5 @@
|
|||||||
// For the version, it uses the latest git tag followed by the number of commits.
|
// 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).
|
// For the date, it uses the current date (when then script is run).
|
||||||
|
|
||||||
#define GLSLANG_REVISION "SPIRV99.1393"
|
#define GLSLANG_REVISION "SPIRV99.1394"
|
||||||
#define GLSLANG_DATE "08-Aug-2016"
|
#define GLSLANG_DATE "08-Aug-2016"
|
||||||
|
@ -664,37 +664,93 @@ int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& typ
|
|||||||
size = computeTypeLocationSize(type);
|
size = computeTypeLocationSize(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
// locations...
|
// Locations, and components within locations.
|
||||||
TRange locationRange(qualifier.layoutLocation, qualifier.layoutLocation + size - 1);
|
//
|
||||||
|
// Almost always, dealing with components means a single location is involved.
|
||||||
|
// The exception is a dvec3. From the spec:
|
||||||
|
//
|
||||||
|
// "A dvec3 will consume all four components of the first location and components 0 and 1 of
|
||||||
|
// the second location. This leaves components 2 and 3 available for other component-qualified
|
||||||
|
// declarations."
|
||||||
|
//
|
||||||
|
// That means, without ever mentioning a component, a component range
|
||||||
|
// for a different location gets specified, if it's not a vertex shader input. (!)
|
||||||
|
// (A vertex shader input will show using only one location, even for a dvec3/4.)
|
||||||
|
//
|
||||||
|
// So, for the case of dvec3, we need two independent ioRanges.
|
||||||
|
|
||||||
// components in this location slot...
|
int collision = -1; // no collision
|
||||||
TRange componentRange(0, 3);
|
if (size == 2 && type.getBasicType() == EbtDouble && type.getVectorSize() == 3 &&
|
||||||
if (qualifier.hasComponent() || type.getVectorSize() > 0) {
|
(qualifier.isPipeInput() || qualifier.isPipeOutput())) {
|
||||||
int consumedComponents = type.getVectorSize() * (type.getBasicType() == EbtDouble ? 2 : 1);
|
// Dealing with dvec3 in/out split across two locations.
|
||||||
if (qualifier.hasComponent())
|
// Need two io-ranges.
|
||||||
componentRange.start = qualifier.layoutComponent;
|
// The case where the dvec3 doesn't start at component 0 was previously caught as overflow.
|
||||||
componentRange.last = componentRange.start + consumedComponents - 1;
|
|
||||||
|
// First range:
|
||||||
|
TRange locationRange(qualifier.layoutLocation, qualifier.layoutLocation);
|
||||||
|
TRange componentRange(0, 3);
|
||||||
|
TIoRange range(locationRange, componentRange, type.getBasicType(), 0);
|
||||||
|
|
||||||
|
// check for collisions
|
||||||
|
collision = checkLocationRange(set, range, type, typeCollision);
|
||||||
|
if (collision < 0) {
|
||||||
|
usedIo[set].push_back(range);
|
||||||
|
|
||||||
|
// Second range:
|
||||||
|
TRange locationRange2(qualifier.layoutLocation + 1, qualifier.layoutLocation + 1);
|
||||||
|
TRange componentRange2(0, 1);
|
||||||
|
TIoRange range2(locationRange2, componentRange2, type.getBasicType(), 0);
|
||||||
|
|
||||||
|
// check for collisions
|
||||||
|
collision = checkLocationRange(set, range2, type, typeCollision);
|
||||||
|
if (collision < 0)
|
||||||
|
usedIo[set].push_back(range2);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Not a dvec3 in/out split across two locations, generic path.
|
||||||
|
// Need a single IO-range block.
|
||||||
|
|
||||||
|
TRange locationRange(qualifier.layoutLocation, qualifier.layoutLocation + size - 1);
|
||||||
|
TRange componentRange(0, 3);
|
||||||
|
if (qualifier.hasComponent() || type.getVectorSize() > 0) {
|
||||||
|
int consumedComponents = type.getVectorSize() * (type.getBasicType() == EbtDouble ? 2 : 1);
|
||||||
|
if (qualifier.hasComponent())
|
||||||
|
componentRange.start = qualifier.layoutComponent;
|
||||||
|
componentRange.last = componentRange.start + consumedComponents - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// combine location and component ranges
|
||||||
|
TIoRange range(locationRange, componentRange, type.getBasicType(), qualifier.hasIndex() ? qualifier.layoutIndex : 0);
|
||||||
|
|
||||||
|
// check for collisions, except for vertex inputs on desktop
|
||||||
|
if (! (profile != EEsProfile && language == EShLangVertex && qualifier.isPipeInput()))
|
||||||
|
collision = checkLocationRange(set, range, type, typeCollision);
|
||||||
|
|
||||||
|
if (collision < 0)
|
||||||
|
usedIo[set].push_back(range);
|
||||||
}
|
}
|
||||||
|
|
||||||
// both...
|
return collision;
|
||||||
TIoRange range(locationRange, componentRange, type.getBasicType(), qualifier.hasIndex() ? qualifier.layoutIndex : 0);
|
}
|
||||||
|
|
||||||
// check for collisions, except for vertex inputs on desktop
|
// Compare a new (the passed in) 'range' against the existing set, and see
|
||||||
if (! (profile != EEsProfile && language == EShLangVertex && qualifier.isPipeInput())) {
|
// if there are any collisions.
|
||||||
for (size_t r = 0; r < usedIo[set].size(); ++r) {
|
//
|
||||||
if (range.overlap(usedIo[set][r])) {
|
// Returns < 0 if no collision, >= 0 if collision and the value returned is a colliding value.
|
||||||
// there is a collision; pick one
|
//
|
||||||
return std::max(locationRange.start, usedIo[set][r].location.start);
|
int TIntermediate::checkLocationRange(int set, const TIoRange& range, const TType& type, bool& typeCollision)
|
||||||
} else if (locationRange.overlap(usedIo[set][r].location) && type.getBasicType() != usedIo[set][r].basicType) {
|
{
|
||||||
// aliased-type mismatch
|
for (size_t r = 0; r < usedIo[set].size(); ++r) {
|
||||||
typeCollision = true;
|
if (range.overlap(usedIo[set][r])) {
|
||||||
return std::max(locationRange.start, usedIo[set][r].location.start);
|
// there is a collision; pick one
|
||||||
}
|
return std::max(range.location.start, usedIo[set][r].location.start);
|
||||||
|
} else if (range.location.overlap(usedIo[set][r].location) && type.getBasicType() != usedIo[set][r].basicType) {
|
||||||
|
// aliased-type mismatch
|
||||||
|
typeCollision = true;
|
||||||
|
return std::max(range.location.start, usedIo[set][r].location.start);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
usedIo[set].push_back(range);
|
|
||||||
|
|
||||||
return -1; // no collision
|
return -1; // no collision
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -331,6 +331,7 @@ public:
|
|||||||
bool inIoAccessed(const TString& name) const { return ioAccessed.find(name) != ioAccessed.end(); }
|
bool inIoAccessed(const TString& name) const { return ioAccessed.find(name) != ioAccessed.end(); }
|
||||||
|
|
||||||
int addUsedLocation(const TQualifier&, const TType&, bool& typeCollision);
|
int addUsedLocation(const TQualifier&, const TType&, bool& typeCollision);
|
||||||
|
int checkLocationRange(int set, const TIoRange& range, const TType&, bool& typeCollision);
|
||||||
int addUsedOffsets(int binding, int offset, int numOffsets);
|
int addUsedOffsets(int binding, int offset, int numOffsets);
|
||||||
bool addUsedConstantId(int id);
|
bool addUsedConstantId(int id);
|
||||||
int computeTypeLocationSize(const TType&) const;
|
int computeTypeLocationSize(const TType&) const;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user