Skip to content

Commit

Permalink
Add more location aliasing checks
Browse files Browse the repository at this point in the history
When location aliasing, the aliases sharing the location must have the same underlying numerical type and bit width (floating-point or integer, 32-bit versus 64-bit, etc.) and the same auxiliary storage and interpolation qualification.
This adds checks for the "patch" and "sample" qualifiers, and also relaxes the checks when the signedness of integer types differs.
  • Loading branch information
jimihem authored Jul 17, 2024
1 parent 48eaea6 commit 52f68dc
Show file tree
Hide file tree
Showing 9 changed files with 201 additions and 8 deletions.
47 changes: 47 additions & 0 deletions Test/baseResults/ps_sample.frag.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
ps_sample.frag
ERROR: 0:5: 'location' : the aliases sharing the location 1 must be the same basic type and interpolation qualification
ERROR: 1 compilation errors. No code generated.


Shader version: 430
Requested GL_ARB_enhanced_layouts
ERROR: node is still EOpNull!
0:10 Function Definition: main( ( global void)
0:10 Function Parameters:
0:12 Sequence
0:12 Sequence
0:12 move second child to first child ( temp 4-component vector of float)
0:12 'result' ( temp 4-component vector of float)
0:12 'gs_fs' ( smooth in 4-component vector of float)
0:16 move second child to first child ( temp 4-component vector of float)
0:16 'fs_out' ( out 4-component vector of float)
0:16 'result' ( temp 4-component vector of float)
0:? Linker Objects
0:? 'gohan' (layout( location=1 component=0) flat in uint)
0:? 'goten' (layout( location=1 component=2) flat sample in 2-component vector of uint)
0:? 'gs_fs' ( smooth in 4-component vector of float)
0:? 'fs_out' ( out 4-component vector of float)


Linked fragment stage:


Shader version: 430
Requested GL_ARB_enhanced_layouts
ERROR: node is still EOpNull!
0:10 Function Definition: main( ( global void)
0:10 Function Parameters:
0:12 Sequence
0:12 Sequence
0:12 move second child to first child ( temp 4-component vector of float)
0:12 'result' ( temp 4-component vector of float)
0:12 'gs_fs' ( smooth in 4-component vector of float)
0:16 move second child to first child ( temp 4-component vector of float)
0:16 'fs_out' ( out 4-component vector of float)
0:16 'result' ( temp 4-component vector of float)
0:? Linker Objects
0:? 'gohan' (layout( location=1 component=0) flat in uint)
0:? 'goten' (layout( location=1 component=2) flat sample in 2-component vector of uint)
0:? 'gs_fs' ( smooth in 4-component vector of float)
0:? 'fs_out' ( out 4-component vector of float)

21 changes: 21 additions & 0 deletions Test/baseResults/ps_uint_int.frag.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
ps_uint_int.frag
Shader version: 450
0:? Sequence
0:6 Function Definition: main( ( global void)
0:6 Function Parameters:
0:? Linker Objects
0:? 'u' (layout( location=0 component=0) flat in uint)
0:? 'i' (layout( location=0 component=1) flat in int)


Linked fragment stage:


Shader version: 450
0:? Sequence
0:6 Function Definition: main( ( global void)
0:6 Function Parameters:
0:? Linker Objects
0:? 'u' (layout( location=0 component=0) flat in uint)
0:? 'i' (layout( location=0 component=1) flat in int)

61 changes: 61 additions & 0 deletions Test/baseResults/tes_patch.tese.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
tes_patch.tese
ERROR: 0:7: 'location' : the aliases sharing the location 1 must be the same basic type and interpolation qualification
ERROR: 1 compilation errors. No code generated.


Shader version: 430
Requested GL_ARB_enhanced_layouts
input primitive = isolines
vertex spacing = none
triangle order = none
using point mode
ERROR: node is still EOpNull!
0:12 Function Definition: main( ( global void)
0:12 Function Parameters:
0:14 Sequence
0:14 Sequence
0:14 move second child to first child ( temp 4-component vector of float)
0:14 'result' ( temp 4-component vector of float)
0:14 direct index ( temp 4-component vector of float)
0:14 'tcs_tes' ( in 32-element array of 4-component vector of float)
0:14 Constant:
0:14 0 (const int)
0:18 add second child into first child ( temp 4-component vector of float)
0:18 'tes_gs' ( out 4-component vector of float)
0:18 'result' ( temp 4-component vector of float)
0:? Linker Objects
0:? 'gohan' (layout( location=1 component=0) in 32-element array of 2-component vector of float)
0:? 'goten' (layout( location=1 component=2) patch in 2-component vector of float)
0:? 'tcs_tes' ( in 32-element array of 4-component vector of float)
0:? 'tes_gs' ( out 4-component vector of float)


Linked tessellation evaluation stage:


Shader version: 430
Requested GL_ARB_enhanced_layouts
input primitive = isolines
vertex spacing = equal_spacing
triangle order = ccw
using point mode
ERROR: node is still EOpNull!
0:12 Function Definition: main( ( global void)
0:12 Function Parameters:
0:14 Sequence
0:14 Sequence
0:14 move second child to first child ( temp 4-component vector of float)
0:14 'result' ( temp 4-component vector of float)
0:14 direct index ( temp 4-component vector of float)
0:14 'tcs_tes' ( in 32-element array of 4-component vector of float)
0:14 Constant:
0:14 0 (const int)
0:18 add second child into first child ( temp 4-component vector of float)
0:18 'tes_gs' ( out 4-component vector of float)
0:18 'result' ( temp 4-component vector of float)
0:? Linker Objects
0:? 'gohan' (layout( location=1 component=0) in 32-element array of 2-component vector of float)
0:? 'goten' (layout( location=1 component=2) patch in 2-component vector of float)
0:? 'tcs_tes' ( in 32-element array of 4-component vector of float)
0:? 'tes_gs' ( out 4-component vector of float)

17 changes: 17 additions & 0 deletions Test/ps_sample.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#version 430 core
#extension GL_ARB_enhanced_layouts : require

layout (location = 1, component = 0) flat in uint gohan;
layout (location = 1, component = 2) sample flat in uvec2 goten;

in vec4 gs_fs;
out vec4 fs_out;

void main()
{
vec4 result = gs_fs;



fs_out = result;
}
7 changes: 7 additions & 0 deletions Test/ps_uint_int.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#version 450

layout(location=0, component=0) flat in uint u;
layout(location=0, component=1) flat in int i;

void main() {
}
19 changes: 19 additions & 0 deletions Test/tes_patch.tese
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#version 430 core
#extension GL_ARB_enhanced_layouts : require

layout(isolines, point_mode) in;

layout (location = 1, component = 0) in vec2 gohan[];
layout (location = 1, component = 2) patch in vec2 goten;

in vec4 tcs_tes[];
out vec4 tes_gs;

void main()
{
vec4 result = tcs_tes[0];



tes_gs += result;
}
28 changes: 22 additions & 6 deletions glslang/MachineIndependent/linkValidate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1689,7 +1689,7 @@ int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& typ
// First range:
TRange locationRange(qualifier.layoutLocation, qualifier.layoutLocation);
TRange componentRange(0, 3);
TIoRange range(locationRange, componentRange, type.getBasicType(), 0, qualifier.centroid, qualifier.smooth, qualifier.flat);
TIoRange range(locationRange, componentRange, type.getBasicType(), 0, qualifier.centroid, qualifier.smooth, qualifier.flat, qualifier.sample, qualifier.patch);

// check for collisions
collision = checkLocationRange(set, range, type, typeCollision);
Expand All @@ -1699,7 +1699,7 @@ int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& typ
// Second range:
TRange locationRange2(qualifier.layoutLocation + 1, qualifier.layoutLocation + 1);
TRange componentRange2(0, 1);
TIoRange range2(locationRange2, componentRange2, type.getBasicType(), 0, qualifier.centroid, qualifier.smooth, qualifier.flat);
TIoRange range2(locationRange2, componentRange2, type.getBasicType(), 0, qualifier.centroid, qualifier.smooth, qualifier.flat, qualifier.sample, qualifier.patch);

// check for collisions
collision = checkLocationRange(set, range2, type, typeCollision);
Expand All @@ -1725,7 +1725,7 @@ int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& typ
TBasicType basicTy = type.getBasicType();
if (basicTy == EbtSampler && type.getSampler().isAttachmentEXT())
basicTy = type.getSampler().type;
TIoRange range(locationRange, componentRange, basicTy, qualifier.hasIndex() ? qualifier.getIndex() : 0, qualifier.centroid, qualifier.smooth, qualifier.flat);
TIoRange range(locationRange, componentRange, basicTy, qualifier.hasIndex() ? qualifier.getIndex() : 0, qualifier.centroid, qualifier.smooth, qualifier.flat, qualifier.sample, qualifier.patch);

// check for collisions, except for vertex inputs on desktop targeting OpenGL
if (! (!isEsProfile() && language == EShLangVertex && qualifier.isPipeInput()) || spvVersion.vulkan > 0)
Expand All @@ -1736,7 +1736,21 @@ int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& typ

return collision;
}

static bool checkType(TBasicType t1, TBasicType t2) {
if (t1 != t2) {
if ((t1 == EbtInt8 && t2 == EbtUint8) ||
(t2 == EbtInt8 && t1 == EbtUint8) ||
(t1 == EbtInt16 && t2 == EbtUint16) ||
(t2 == EbtInt16 && t1 == EbtUint16)||
(t1 == EbtInt && t2 == EbtUint) ||
(t2 == EbtInt && t1 == EbtUint)||
(t1 == EbtInt64 && t2 == EbtUint64) ||
(t2 == EbtInt64 && t1 == EbtUint64)) {
return true;
}
}
return t1 == t2;
}
// Compare a new (the passed in) 'range' against the existing set, and see
// if there are any collisions.
//
Expand All @@ -1749,10 +1763,12 @@ int TIntermediate::checkLocationRange(int set, const TIoRange& range, const TTyp
// 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 ||
(!checkType(type.getBasicType(), usedIo[set][r].basicType) ||
type.getQualifier().centroid != usedIo[set][r].centroid ||
type.getQualifier().smooth != usedIo[set][r].smooth ||
type.getQualifier().flat != usedIo[set][r].flat)) {
type.getQualifier().flat != usedIo[set][r].flat ||
type.getQualifier().sample != usedIo[set][r].sample ||
type.getQualifier().patch != usedIo[set][r].patch)) {
// aliased-type mismatch
typeCollision = true;
return std::max(range.location.start, usedIo[set][r].location.start);
Expand Down
6 changes: 4 additions & 2 deletions glslang/MachineIndependent/localintermediate.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,8 @@ struct TRange {
// within the same location range, component range, and index value. Locations don't alias unless
// all other dimensions of their range overlap.
struct TIoRange {
TIoRange(TRange location, TRange component, TBasicType basicType, int index, bool centroid, bool smooth, bool flat)
: location(location), component(component), basicType(basicType), index(index), centroid(centroid), smooth(smooth), flat(flat)
TIoRange(TRange location, TRange component, TBasicType basicType, int index, bool centroid, bool smooth, bool flat, bool sample, bool patch)
: location(location), component(component), basicType(basicType), index(index), centroid(centroid), smooth(smooth), flat(flat), sample(sample), patch(patch)
{
}
bool overlap(const TIoRange& rhs) const
Expand All @@ -139,6 +139,8 @@ struct TIoRange {
bool centroid;
bool smooth;
bool flat;
bool sample;
bool patch;
};

// An offset range is a 2-D rectangle; the set of (binding, offset) pairs all lying
Expand Down
3 changes: 3 additions & 0 deletions gtests/AST.FromFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,9 @@ INSTANTIATE_TEST_SUITE_P(
"index_outside_sample_mask_range.frag",
"positive_infinity.frag",
"matrixCompMult.vert",
"ps_uint_int.frag",
"ps_sample.frag",
"tes_patch.tese",
})),
FileNameAsCustomTestSuffix
);
Expand Down

0 comments on commit 52f68dc

Please sign in to comment.