Commit 5611c6d2 by John Kessenich

GLSL/SPV: Implement SPV_EXT_descriptor_indexing and GL_EXT_nonuniform_qualifier

parent 0b5e5da7
...@@ -2331,7 +2331,7 @@ void Builder::accessChainStore(Id rvalue) ...@@ -2331,7 +2331,7 @@ void Builder::accessChainStore(Id rvalue)
} }
// Comments in header // Comments in header
Id Builder::accessChainLoad(Decoration precision, Id resultType) Id Builder::accessChainLoad(Decoration precision, Decoration nonUniform, Id resultType)
{ {
Id id; Id id;
...@@ -2377,6 +2377,7 @@ Id Builder::accessChainLoad(Decoration precision, Id resultType) ...@@ -2377,6 +2377,7 @@ Id Builder::accessChainLoad(Decoration precision, Id resultType)
// load through the access chain // load through the access chain
id = createLoad(collapseAccessChain()); id = createLoad(collapseAccessChain());
setPrecision(id, precision); setPrecision(id, precision);
addDecoration(id, nonUniform);
} }
// Done, unless there are swizzles to do // Done, unless there are swizzles to do
...@@ -2397,6 +2398,7 @@ Id Builder::accessChainLoad(Decoration precision, Id resultType) ...@@ -2397,6 +2398,7 @@ Id Builder::accessChainLoad(Decoration precision, Id resultType)
if (accessChain.component != NoResult) if (accessChain.component != NoResult)
id = setPrecision(createVectorExtractDynamic(id, resultType, accessChain.component), precision); id = setPrecision(createVectorExtractDynamic(id, resultType, accessChain.component), precision);
addDecoration(id, nonUniform);
return id; return id;
} }
......
...@@ -554,7 +554,7 @@ public: ...@@ -554,7 +554,7 @@ public:
void accessChainStore(Id rvalue); void accessChainStore(Id rvalue);
// use accessChain and swizzle to load an r-value // use accessChain and swizzle to load an r-value
Id accessChainLoad(Decoration precision, Id ResultType); Id accessChainLoad(Decoration precision, Decoration nonUniform, Id ResultType);
// get the direct pointer for an l-value // get the direct pointer for an l-value
Id accessChainGetLValue(); Id accessChainGetLValue();
......
...@@ -255,6 +255,7 @@ const char* DecorationString(int decoration) ...@@ -255,6 +255,7 @@ const char* DecorationString(int decoration)
case DecorationSecondaryViewportRelativeNV: return "SecondaryViewportRelativeNV"; case DecorationSecondaryViewportRelativeNV: return "SecondaryViewportRelativeNV";
#endif #endif
case DecorationNonUniformEXT: return "DecorationNonUniformEXT";
case DecorationHlslCounterBufferGOOGLE: return "DecorationHlslCounterBufferGOOGLE"; case DecorationHlslCounterBufferGOOGLE: return "DecorationHlslCounterBufferGOOGLE";
case DecorationHlslSemanticGOOGLE: return "DecorationHlslSemanticGOOGLE"; case DecorationHlslSemanticGOOGLE: return "DecorationHlslSemanticGOOGLE";
} }
...@@ -815,6 +816,19 @@ const char* CapabilityString(int info) ...@@ -815,6 +816,19 @@ const char* CapabilityString(int info)
case CapabilityFragmentFullyCoveredEXT: return "FragmentFullyCoveredEXT"; case CapabilityFragmentFullyCoveredEXT: return "FragmentFullyCoveredEXT";
case CapabilityShaderNonUniformEXT: return "CapabilityShaderNonUniformEXT";
case CapabilityRuntimeDescriptorArrayEXT: return "CapabilityRuntimeDescriptorArrayEXT";
case CapabilityInputAttachmentArrayDynamicIndexingEXT: return "CapabilityInputAttachmentArrayDynamicIndexingEXT";
case CapabilityUniformTexelBufferArrayDynamicIndexingEXT: return "CapabilityUniformTexelBufferArrayDynamicIndexingEXT";
case CapabilityStorageTexelBufferArrayDynamicIndexingEXT: return "CapabilityStorageTexelBufferArrayDynamicIndexingEXT";
case CapabilityUniformBufferArrayNonUniformIndexingEXT: return "CapabilityUniformBufferArrayNonUniformIndexingEXT";
case CapabilitySampledImageArrayNonUniformIndexingEXT: return "CapabilitySampledImageArrayNonUniformIndexingEXT";
case CapabilityStorageBufferArrayNonUniformIndexingEXT: return "CapabilityStorageBufferArrayNonUniformIndexingEXT";
case CapabilityStorageImageArrayNonUniformIndexingEXT: return "CapabilityStorageImageArrayNonUniformIndexingEXT";
case CapabilityInputAttachmentArrayNonUniformIndexingEXT: return "CapabilityInputAttachmentArrayNonUniformIndexingEXT";
case CapabilityUniformTexelBufferArrayNonUniformIndexingEXT: return "CapabilityUniformTexelBufferArrayNonUniformIndexingEXT";
case CapabilityStorageTexelBufferArrayNonUniformIndexingEXT: return "CapabilityStorageTexelBufferArrayNonUniformIndexingEXT";
default: return "Bad"; default: return "Bad";
} }
} }
......
...@@ -393,6 +393,7 @@ enum Decoration { ...@@ -393,6 +393,7 @@ enum Decoration {
DecorationPassthroughNV = 5250, DecorationPassthroughNV = 5250,
DecorationViewportRelativeNV = 5252, DecorationViewportRelativeNV = 5252,
DecorationSecondaryViewportRelativeNV = 5256, DecorationSecondaryViewportRelativeNV = 5256,
DecorationNonUniformEXT = 5300,
DecorationHlslCounterBufferGOOGLE = 5634, DecorationHlslCounterBufferGOOGLE = 5634,
DecorationHlslSemanticGOOGLE = 5635, DecorationHlslSemanticGOOGLE = 5635,
DecorationMax = 0x7fffffff, DecorationMax = 0x7fffffff,
...@@ -692,6 +693,18 @@ enum Capability { ...@@ -692,6 +693,18 @@ enum Capability {
CapabilityPerViewAttributesNV = 5260, CapabilityPerViewAttributesNV = 5260,
CapabilityFragmentFullyCoveredEXT = 5265, CapabilityFragmentFullyCoveredEXT = 5265,
CapabilityGroupNonUniformPartitionedNV = 5297, CapabilityGroupNonUniformPartitionedNV = 5297,
CapabilityShaderNonUniformEXT = 5301,
CapabilityRuntimeDescriptorArrayEXT = 5302,
CapabilityInputAttachmentArrayDynamicIndexingEXT = 5303,
CapabilityUniformTexelBufferArrayDynamicIndexingEXT = 5304,
CapabilityStorageTexelBufferArrayDynamicIndexingEXT = 5305,
CapabilityUniformBufferArrayNonUniformIndexingEXT = 5306,
CapabilitySampledImageArrayNonUniformIndexingEXT = 5307,
CapabilityStorageBufferArrayNonUniformIndexingEXT = 5308,
CapabilityStorageImageArrayNonUniformIndexingEXT = 5309,
CapabilityInputAttachmentArrayNonUniformIndexingEXT = 5310,
CapabilityUniformTexelBufferArrayNonUniformIndexingEXT = 5311,
CapabilityStorageTexelBufferArrayNonUniformIndexingEXT = 5312,
CapabilitySubgroupShuffleINTEL = 5568, CapabilitySubgroupShuffleINTEL = 5568,
CapabilitySubgroupBufferBlockIOINTEL = 5569, CapabilitySubgroupBufferBlockIOINTEL = 5569,
CapabilitySubgroupImageBlockIOINTEL = 5570, CapabilitySubgroupImageBlockIOINTEL = 5570,
......
#version 310 es
precision highp float;
layout(location=0) out float o;
struct S { float f; };
buffer b1 { S s[]; };
buffer b2 { S s[]; } b2name;
buffer b3 { S s[]; } b3name[];
buffer b4 { S s[]; } b4name[4];
void main()
{
o = s[5].f;
o += b2name.s[6].f;
o += b3name[3].s[7].f;
o += b4name[2].s[8].f;
}
310runtimeArray.vert
ERROR: 0:9: '' : array size required
ERROR: 1 compilation errors. No code generated.
Shader version: 310
ERROR: node is still EOpNull!
0:12 Function Definition: main( ( global void)
0:12 Function Parameters:
0:14 Sequence
0:14 move second child to first child ( temp highp float)
0:14 'o' (layout( location=0) smooth out highp float)
0:14 f: direct index for structure ( global highp float)
0:14 direct index (layout( column_major shared) temp structure{ global highp float f})
0:14 s: direct index for structure (layout( column_major shared) buffer unsized 6-element array of structure{ global highp float f})
0:14 'anon@0' (layout( column_major shared) buffer block{layout( column_major shared) buffer unsized 6-element array of structure{ global highp float f} s})
0:14 Constant:
0:14 0 (const uint)
0:14 Constant:
0:14 5 (const int)
0:14 Constant:
0:14 0 (const int)
0:15 add second child into first child ( temp highp float)
0:15 'o' (layout( location=0) smooth out highp float)
0:15 f: direct index for structure ( global highp float)
0:15 direct index (layout( column_major shared) temp structure{ global highp float f})
0:15 s: direct index for structure (layout( column_major shared) buffer unsized 7-element array of structure{ global highp float f})
0:15 'b2name' (layout( column_major shared) buffer block{layout( column_major shared) buffer unsized 7-element array of structure{ global highp float f} s})
0:15 Constant:
0:15 0 (const int)
0:15 Constant:
0:15 6 (const int)
0:15 Constant:
0:15 0 (const int)
0:16 add second child into first child ( temp highp float)
0:16 'o' (layout( location=0) smooth out highp float)
0:16 f: direct index for structure ( global highp float)
0:16 direct index (layout( column_major shared) temp structure{ global highp float f})
0:16 s: direct index for structure (layout( column_major shared) buffer unsized 8-element array of structure{ global highp float f})
0:16 direct index (layout( column_major shared) temp block{layout( column_major shared) buffer unsized 8-element array of structure{ global highp float f} s})
0:16 'b3name' (layout( column_major shared) buffer unsized 4-element array of block{layout( column_major shared) buffer unsized 8-element array of structure{ global highp float f} s})
0:16 Constant:
0:16 3 (const int)
0:16 Constant:
0:16 0 (const int)
0:16 Constant:
0:16 7 (const int)
0:16 Constant:
0:16 0 (const int)
0:17 add second child into first child ( temp highp float)
0:17 'o' (layout( location=0) smooth out highp float)
0:17 f: direct index for structure ( global highp float)
0:17 direct index (layout( column_major shared) temp structure{ global highp float f})
0:17 s: direct index for structure (layout( column_major shared) buffer unsized 9-element array of structure{ global highp float f})
0:17 direct index (layout( column_major shared) temp block{layout( column_major shared) buffer unsized 9-element array of structure{ global highp float f} s})
0:17 'b4name' (layout( column_major shared) buffer 4-element array of block{layout( column_major shared) buffer unsized 9-element array of structure{ global highp float f} s})
0:17 Constant:
0:17 2 (const int)
0:17 Constant:
0:17 0 (const int)
0:17 Constant:
0:17 8 (const int)
0:17 Constant:
0:17 0 (const int)
0:? Linker Objects
0:? 'o' (layout( location=0) smooth out highp float)
0:? 'anon@0' (layout( column_major shared) buffer block{layout( column_major shared) buffer unsized 6-element array of structure{ global highp float f} s})
0:? 'b2name' (layout( column_major shared) buffer block{layout( column_major shared) buffer unsized 7-element array of structure{ global highp float f} s})
0:? 'b3name' (layout( column_major shared) buffer unsized 4-element array of block{layout( column_major shared) buffer unsized 8-element array of structure{ global highp float f} s})
0:? 'b4name' (layout( column_major shared) buffer 4-element array of block{layout( column_major shared) buffer unsized 9-element array of structure{ global highp float f} s})
0:? 'gl_VertexID' ( gl_VertexId highp int VertexId)
0:? 'gl_InstanceID' ( gl_InstanceId highp int InstanceId)
Linked vertex stage:
Shader version: 310
ERROR: node is still EOpNull!
0:12 Function Definition: main( ( global void)
0:12 Function Parameters:
0:14 Sequence
0:14 move second child to first child ( temp highp float)
0:14 'o' (layout( location=0) smooth out highp float)
0:14 f: direct index for structure ( global highp float)
0:14 direct index (layout( column_major shared) temp structure{ global highp float f})
0:14 s: direct index for structure (layout( column_major shared) buffer unsized 6-element array of structure{ global highp float f})
0:14 'anon@0' (layout( column_major shared) buffer block{layout( column_major shared) buffer unsized 6-element array of structure{ global highp float f} s})
0:14 Constant:
0:14 0 (const uint)
0:14 Constant:
0:14 5 (const int)
0:14 Constant:
0:14 0 (const int)
0:15 add second child into first child ( temp highp float)
0:15 'o' (layout( location=0) smooth out highp float)
0:15 f: direct index for structure ( global highp float)
0:15 direct index (layout( column_major shared) temp structure{ global highp float f})
0:15 s: direct index for structure (layout( column_major shared) buffer unsized 7-element array of structure{ global highp float f})
0:15 'b2name' (layout( column_major shared) buffer block{layout( column_major shared) buffer unsized 7-element array of structure{ global highp float f} s})
0:15 Constant:
0:15 0 (const int)
0:15 Constant:
0:15 6 (const int)
0:15 Constant:
0:15 0 (const int)
0:16 add second child into first child ( temp highp float)
0:16 'o' (layout( location=0) smooth out highp float)
0:16 f: direct index for structure ( global highp float)
0:16 direct index (layout( column_major shared) temp structure{ global highp float f})
0:16 s: direct index for structure (layout( column_major shared) buffer unsized 8-element array of structure{ global highp float f})
0:16 direct index (layout( column_major shared) temp block{layout( column_major shared) buffer unsized 8-element array of structure{ global highp float f} s})
0:16 'b3name' (layout( column_major shared) buffer 4-element array of block{layout( column_major shared) buffer unsized 8-element array of structure{ global highp float f} s})
0:16 Constant:
0:16 3 (const int)
0:16 Constant:
0:16 0 (const int)
0:16 Constant:
0:16 7 (const int)
0:16 Constant:
0:16 0 (const int)
0:17 add second child into first child ( temp highp float)
0:17 'o' (layout( location=0) smooth out highp float)
0:17 f: direct index for structure ( global highp float)
0:17 direct index (layout( column_major shared) temp structure{ global highp float f})
0:17 s: direct index for structure (layout( column_major shared) buffer unsized 9-element array of structure{ global highp float f})
0:17 direct index (layout( column_major shared) temp block{layout( column_major shared) buffer unsized 9-element array of structure{ global highp float f} s})
0:17 'b4name' (layout( column_major shared) buffer 4-element array of block{layout( column_major shared) buffer unsized 9-element array of structure{ global highp float f} s})
0:17 Constant:
0:17 2 (const int)
0:17 Constant:
0:17 0 (const int)
0:17 Constant:
0:17 8 (const int)
0:17 Constant:
0:17 0 (const int)
0:? Linker Objects
0:? 'o' (layout( location=0) smooth out highp float)
0:? 'anon@0' (layout( column_major shared) buffer block{layout( column_major shared) buffer unsized 6-element array of structure{ global highp float f} s})
0:? 'b2name' (layout( column_major shared) buffer block{layout( column_major shared) buffer unsized 7-element array of structure{ global highp float f} s})
0:? 'b3name' (layout( column_major shared) buffer 4-element array of block{layout( column_major shared) buffer unsized 8-element array of structure{ global highp float f} s})
0:? 'b4name' (layout( column_major shared) buffer 4-element array of block{layout( column_major shared) buffer unsized 9-element array of structure{ global highp float f} s})
0:? 'gl_VertexID' ( gl_VertexId highp int VertexId)
0:? 'gl_InstanceID' ( gl_InstanceId highp int InstanceId)
...@@ -51,7 +51,7 @@ ERROR: 0:157: 'textureQueryLevels' : no matching overloaded function found ...@@ -51,7 +51,7 @@ ERROR: 0:157: 'textureQueryLevels' : no matching overloaded function found
ERROR: 0:157: 'assign' : cannot convert from ' const float' to ' temp int' ERROR: 0:157: 'assign' : cannot convert from ' const float' to ' temp int'
ERROR: 0:158: 'textureQueryLevels' : no matching overloaded function found ERROR: 0:158: 'textureQueryLevels' : no matching overloaded function found
ERROR: 0:158: 'assign' : cannot convert from ' const float' to ' temp int' ERROR: 0:158: 'assign' : cannot convert from ' const float' to ' temp int'
WARNING: 0:161: '[]' : assuming array size of one for compile-time checking of binding numbers for unsized array WARNING: 0:161: '[]' : assuming binding count of one for compile-time checking of binding numbers for unsized array
ERROR: 51 compilation errors. No code generated. ERROR: 51 compilation errors. No code generated.
......
...@@ -25,7 +25,7 @@ ERROR: 0:101: '[' : array index out of range '5' ...@@ -25,7 +25,7 @@ ERROR: 0:101: '[' : array index out of range '5'
ERROR: 0:104: 'constructor' : array constructor must have at least one argument ERROR: 0:104: 'constructor' : array constructor must have at least one argument
ERROR: 0:104: '=' : cannot convert from ' const float' to ' global unsized 1-element array of int' ERROR: 0:104: '=' : cannot convert from ' const float' to ' global unsized 1-element array of int'
ERROR: 0:106: 'constructor' : array argument must be sized ERROR: 0:106: 'constructor' : array argument must be sized
ERROR: 0:111: '[' : array must be redeclared with a size before being indexed with a variable ERROR: 0:111: 'variable index' : required extension not requested: GL_EXT_nonuniform_qualifier
ERROR: 0:111: 'variable indexing sampler array' : not supported with this profile: none ERROR: 0:111: 'variable indexing sampler array' : not supported with this profile: none
ERROR: 28 compilation errors. No code generated. ERROR: 28 compilation errors. No code generated.
......
nonuniform.frag
ERROR: 0:10: 'nonuniformEXT' : for non-parameter, can only apply to 'in' or no storage qualifier
ERROR: 0:11: 'nonuniformEXT' : for non-parameter, can only apply to 'in' or no storage qualifier
ERROR: 0:12: 'nonuniformEXT' : for non-parameter, can only apply to 'in' or no storage qualifier
ERROR: 0:22: 'nonuniformEXT' : for non-parameter, can only apply to 'in' or no storage qualifier
ERROR: 0:28: 'constructor' : too many arguments
ERROR: 0:28: 'assign' : cannot convert from ' const float' to ' nonuniform temp int'
ERROR: 0:29: 'constructor' : not enough data provided for construction
ERROR: 0:29: 'assign' : cannot convert from ' const float' to ' nonuniform temp int'
ERROR: 0:32: 'nonuniformEXT' : not allowed on block or structure members
ERROR: 0:33: 'nonuniformEXT' : not allowed on block or structure members
ERROR: 10 compilation errors. No code generated.
Shader version: 450
Requested GL_EXT_nonuniform_qualifier
ERROR: node is still EOpNull!
0:14 Function Definition: foo(i1;i1; ( nonuniform temp int)
0:14 Function Parameters:
0:14 'nupi' ( nonuniform in int)
0:14 'f' ( nonuniform out int)
0:16 Sequence
0:16 Branch: Return with expression
0:16 'nupi' ( nonuniform in int)
0:19 Function Definition: main( ( global void)
0:19 Function Parameters:
0:? Sequence
0:24 Function Call: foo(i1;i1; ( nonuniform temp int)
0:24 'nu_li' ( nonuniform temp int)
0:24 'nu_li' ( nonuniform temp int)
0:27 move second child to first child ( temp int)
0:27 'nu_li' ( nonuniform temp int)
0:27 add ( nonuniform temp int)
0:27 'a' ( nonuniform temp int)
0:27 component-wise multiply ( nonuniform temp int)
0:27 'a' ( temp int)
0:27 Constant:
0:27 2 (const int)
0:28 'nu_li' ( nonuniform temp int)
0:29 'nu_li' ( nonuniform temp int)
0:? Linker Objects
0:? 'nonuniformEXT' ( global int)
0:? 'nu_inv4' ( smooth nonuniform in 4-component vector of float)
0:? 'nu_gf' ( nonuniform temp float)
0:? 'nu_outv4' ( nonuniform out 4-component vector of float)
0:? 'nu_uv4' ( nonuniform uniform 4-component vector of float)
0:? 'nu_constf' ( nonuniform const float)
0:? 1.000000
0:? 'ins' (layout( location=1) smooth in structure{ global float a, temp float b})
0:? 'inb' (layout( location=3) in block{ in float a, in float b})
Linked fragment stage:
Shader version: 450
Requested GL_EXT_nonuniform_qualifier
ERROR: node is still EOpNull!
0:14 Function Definition: foo(i1;i1; ( nonuniform temp int)
0:14 Function Parameters:
0:14 'nupi' ( nonuniform in int)
0:14 'f' ( nonuniform out int)
0:16 Sequence
0:16 Branch: Return with expression
0:16 'nupi' ( nonuniform in int)
0:19 Function Definition: main( ( global void)
0:19 Function Parameters:
0:? Sequence
0:24 Function Call: foo(i1;i1; ( nonuniform temp int)
0:24 'nu_li' ( nonuniform temp int)
0:24 'nu_li' ( nonuniform temp int)
0:27 move second child to first child ( temp int)
0:27 'nu_li' ( nonuniform temp int)
0:27 add ( nonuniform temp int)
0:27 'a' ( nonuniform temp int)
0:27 component-wise multiply ( nonuniform temp int)
0:27 'a' ( temp int)
0:27 Constant:
0:27 2 (const int)
0:28 'nu_li' ( nonuniform temp int)
0:29 'nu_li' ( nonuniform temp int)
0:? Linker Objects
0:? 'nonuniformEXT' ( global int)
0:? 'nu_inv4' ( smooth nonuniform in 4-component vector of float)
0:? 'nu_gf' ( nonuniform temp float)
0:? 'nu_outv4' ( nonuniform out 4-component vector of float)
0:? 'nu_uv4' ( nonuniform uniform 4-component vector of float)
0:? 'nu_constf' ( nonuniform const float)
0:? 1.000000
0:? 'ins' (layout( location=1) smooth in structure{ global float a, temp float b})
0:? 'inb' (layout( location=3) in block{ in float a, in float b})
#version 450
int nonuniformEXT;
#extension GL_EXT_nonuniform_qualifier : enable
nonuniformEXT in vec4 nu_inv4;
nonuniformEXT float nu_gf;
nonuniformEXT out vec4 nu_outv4; // ERROR, out
nonuniformEXT uniform vec4 nu_uv4; // ERROR, uniform
nonuniformEXT const float nu_constf = 1.0; // ERROR, const
nonuniformEXT int foo(nonuniformEXT int nupi, nonuniformEXT out int f)
{
return nupi;
}
void main()
{
nonuniformEXT int nu_li;
nonuniformEXT const int nu_ci = 2; // ERROR, const
foo(nu_li, nu_li);
int a;
nu_li = nonuniformEXT(a) + nonuniformEXT(a * 2);
nu_li = nonuniformEXT(a, a); // ERROR, too many arguments
nu_li = nonuniformEXT(); // ERROR, no arguments
}
layout(location=1) in struct S { float a; nonuniformEXT float b; } ins; // ERROR, not on member
layout(location=3) in inbName { float a; nonuniformEXT float b; } inb; // ERROR, not on member
...@@ -30,6 +30,15 @@ uniform aun { ...@@ -30,6 +30,15 @@ uniform aun {
float aub[]; float aub[];
}; };
layout(binding=1) uniform samplerBuffer uniformTexelBufferDyn[];
layout(binding=2, r32f) uniform imageBuffer storageTexelBufferDyn[];
layout(binding=3) uniform uname { float a; } uniformBuffer[];
layout(binding=4) buffer bname { float b; } storageBuffer[];
layout(binding=5) uniform sampler2D sampledImage[];
layout(binding=6, r32f) uniform image2D storageImage[];
layout(binding=8) uniform samplerBuffer uniformTexelBuffer[];
layout(binding=9, r32f) uniform imageBuffer storageTexelBuffer[];
int i; int i;
void main() void main()
...@@ -78,4 +87,22 @@ void main() ...@@ -78,4 +87,22 @@ void main()
aub.length(); // ERROR aub.length(); // ERROR
aba.length(); // ERROR aba.length(); // ERROR
abb.length(); abb.length();
uniformTexelBufferDyn[1];
storageTexelBufferDyn[1];
uniformBuffer[1];
storageBuffer[1];
sampledImage[1];
storageImage[1];
uniformTexelBuffer[1];
storageTexelBuffer[1];
uniformTexelBufferDyn[i]; // ERROR, need extension
storageTexelBufferDyn[i]; // ERROR, need extension
uniformBuffer[i]; // ERROR, need extension
storageBuffer[i]; // ERROR, need extension
sampledImage[i]; // ERROR, need extension
storageImage[i]; // ERROR, need extension
uniformTexelBuffer[i]; // ERROR, need extension
storageTexelBuffer[i]; // ERROR, need extension
} }
#version 450
#extension GL_EXT_nonuniform_qualifier : enable
layout(location=0) nonuniformEXT in vec4 nu_inv4;
nonuniformEXT float nu_gf;
layout(location=1) in nonuniformEXT flat int nu_ii;
layout(binding=0, input_attachment_index = 0) uniform subpassInput inputAttachmentDyn[];
layout(binding=1) uniform samplerBuffer uniformTexelBufferDyn[];
layout(binding=2, r32f) uniform imageBuffer storageTexelBufferDyn[];
layout(binding=3) uniform uname { float a; } uniformBuffer[];
layout(binding=4) buffer bname { float b; } storageBuffer[];
layout(binding=5) uniform sampler2D sampledImage[];
layout(binding=6, r32f) uniform image2D storageImage[];
layout(binding=7, input_attachment_index = 1) uniform subpassInput inputAttachment[];
layout(binding=8) uniform samplerBuffer uniformTexelBuffer[];
layout(binding=9, r32f) uniform imageBuffer storageTexelBuffer[];
nonuniformEXT int foo(nonuniformEXT int nupi, nonuniformEXT out int f)
{
return nupi;
}
void main()
{
nonuniformEXT int nu_li;
int dyn_i;
int a = foo(nu_li, nu_li);
nu_li = nonuniformEXT(a) + nonuniformEXT(a * 2);
float b;
b = nu_inv4.x * nu_gf;
b += subpassLoad(inputAttachmentDyn[dyn_i]).x;
b += texelFetch(uniformTexelBufferDyn[dyn_i], 1).x;
b += imageLoad(storageTexelBufferDyn[dyn_i], 1).x;
b += uniformBuffer[nu_ii].a;
b += storageBuffer[nu_ii].b;
b += texture(sampledImage[nu_ii], vec2(0.5)).x;
b += imageLoad(storageImage[nu_ii], ivec2(1)).x;
b += subpassLoad(inputAttachment[nu_ii]).x;
b += texelFetch(uniformTexelBuffer[nu_ii], 1).x;
b += imageLoad(storageTexelBuffer[nu_ii], 1).x;
nonuniformEXT ivec4 v;
nonuniformEXT mat4 m;
nonuniformEXT struct S { int a; } s;
ivec4 uv;
b += uniformBuffer[v.y].a;
b += uniformBuffer[v[2]].a;
b += uniformBuffer[uv[nu_ii]].a;
b += uniformBuffer[int(m[2].z)].a;
b += uniformBuffer[s.a].a;
}
...@@ -437,6 +437,7 @@ public: ...@@ -437,6 +437,7 @@ public:
clearInterstage(); clearInterstage();
clearMemory(); clearMemory();
specConstant = false; specConstant = false;
nonUniform = false;
clearLayout(); clearLayout();
} }
...@@ -478,6 +479,7 @@ public: ...@@ -478,6 +479,7 @@ public:
{ {
storage = EvqTemporary; storage = EvqTemporary;
specConstant = false; specConstant = false;
nonUniform = false;
} }
const char* semanticName; const char* semanticName;
...@@ -502,6 +504,7 @@ public: ...@@ -502,6 +504,7 @@ public:
bool readonly : 1; bool readonly : 1;
bool writeonly : 1; bool writeonly : 1;
bool specConstant : 1; // having a constant_id is not sufficient: expressions have no id, but are still specConstant bool specConstant : 1; // having a constant_id is not sufficient: expressions have no id, but are still specConstant
bool nonUniform : 1;
bool isMemory() const bool isMemory() const
{ {
...@@ -833,6 +836,10 @@ public: ...@@ -833,6 +836,10 @@ public:
// true front-end constant. // true front-end constant.
return specConstant; return specConstant;
} }
bool isNonUniform() const
{
return nonUniform;
}
bool isFrontEndConstant() const bool isFrontEndConstant() const
{ {
// True if the front-end knows the final constant value. // True if the front-end knows the final constant value.
...@@ -1385,6 +1392,7 @@ public: ...@@ -1385,6 +1392,7 @@ public:
// "Image" is a superset of "Subpass" // "Image" is a superset of "Subpass"
virtual bool isImage() const { return basicType == EbtSampler && getSampler().isImage(); } virtual bool isImage() const { return basicType == EbtSampler && getSampler().isImage(); }
virtual bool isSubpass() const { return basicType == EbtSampler && getSampler().isSubpass(); } virtual bool isSubpass() const { return basicType == EbtSampler && getSampler().isSubpass(); }
virtual bool isTexture() const { return basicType == EbtSampler && getSampler().isTexture(); }
// return true if this type contains any subtype which satisfies the given predicate. // return true if this type contains any subtype which satisfies the given predicate.
template <typename P> template <typename P>
...@@ -1689,6 +1697,8 @@ public: ...@@ -1689,6 +1697,8 @@ public:
appendStr(" writeonly"); appendStr(" writeonly");
if (qualifier.specConstant) if (qualifier.specConstant)
appendStr(" specialization-constant"); appendStr(" specialization-constant");
if (qualifier.nonUniform)
appendStr(" nonuniform");
appendStr(" "); appendStr(" ");
appendStr(getStorageQualifierString()); appendStr(getStorageQualifierString());
if (isArray()) { if (isArray()) {
......
...@@ -729,6 +729,7 @@ enum TOperator { ...@@ -729,6 +729,7 @@ enum TOperator {
EOpConstructF16Mat4x4, EOpConstructF16Mat4x4,
EOpConstructStruct, EOpConstructStruct,
EOpConstructTextureSampler, EOpConstructTextureSampler,
EOpConstructNonuniform, // expected to be transformed away, not present in final AST
EOpConstructGuardEnd, EOpConstructGuardEnd,
// //
......
...@@ -158,6 +158,11 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn ...@@ -158,6 +158,11 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn
if (specConstantPropagates(*node->getLeft(), *node->getRight()) && isSpecializationOperation(*node)) if (specConstantPropagates(*node->getLeft(), *node->getRight()) && isSpecializationOperation(*node))
node->getWritableType().getQualifier().makeSpecConstant(); node->getWritableType().getQualifier().makeSpecConstant();
// If must propagate nonuniform, make a nonuniform.
if ((node->getLeft()->getQualifier().nonUniform || node->getRight()->getQualifier().nonUniform) &&
isNonuniformPropagating(node->getOp()))
node->getWritableType().getQualifier().nonUniform = true;
return node; return node;
} }
...@@ -366,6 +371,10 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermTyped* child, TSo ...@@ -366,6 +371,10 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermTyped* child, TSo
if (node->getOperand()->getType().getQualifier().isSpecConstant() && isSpecializationOperation(*node)) if (node->getOperand()->getType().getQualifier().isSpecConstant() && isSpecializationOperation(*node))
node->getWritableType().getQualifier().makeSpecConstant(); node->getWritableType().getQualifier().makeSpecConstant();
// If must propagate nonuniform, make a nonuniform.
if (node->getOperand()->getQualifier().nonUniform && isNonuniformPropagating(node->getOp()))
node->getWritableType().getQualifier().nonUniform = true;
return node; return node;
} }
...@@ -1748,6 +1757,9 @@ TOperator TIntermediate::mapTypeToConstructorOp(const TType& type) const ...@@ -1748,6 +1757,9 @@ TOperator TIntermediate::mapTypeToConstructorOp(const TType& type) const
{ {
TOperator op = EOpNull; TOperator op = EOpNull;
if (type.getQualifier().nonUniform)
return EOpConstructNonuniform;
switch (type.getBasicType()) { switch (type.getBasicType()) {
case EbtStruct: case EbtStruct:
op = EOpConstructStruct; op = EOpConstructStruct;
...@@ -2800,6 +2812,64 @@ bool TIntermediate::isSpecializationOperation(const TIntermOperator& node) const ...@@ -2800,6 +2812,64 @@ bool TIntermediate::isSpecializationOperation(const TIntermOperator& node) const
} }
} }
// Is the operation one that must propagate nonuniform?
bool TIntermediate::isNonuniformPropagating(TOperator op) const
{
// "* All Operators in Section 5.1 (Operators), except for assignment,
// arithmetic assignment, and sequence
// * Component selection in Section 5.5
// * Matrix components in Section 5.6
// * Structure and Array Operations in Section 5.7, except for the length
// method."
switch (op) {
case EOpPostIncrement:
case EOpPostDecrement:
case EOpPreIncrement:
case EOpPreDecrement:
case EOpNegative:
case EOpLogicalNot:
case EOpVectorLogicalNot:
case EOpBitwiseNot:
case EOpAdd:
case EOpSub:
case EOpMul:
case EOpDiv:
case EOpMod:
case EOpRightShift:
case EOpLeftShift:
case EOpAnd:
case EOpInclusiveOr:
case EOpExclusiveOr:
case EOpEqual:
case EOpNotEqual:
case EOpLessThan:
case EOpGreaterThan:
case EOpLessThanEqual:
case EOpGreaterThanEqual:
case EOpVectorTimesScalar:
case EOpVectorTimesMatrix:
case EOpMatrixTimesVector:
case EOpMatrixTimesScalar:
case EOpLogicalOr:
case EOpLogicalXor:
case EOpLogicalAnd:
case EOpIndexDirect:
case EOpIndexIndirect:
case EOpIndexDirectStruct:
case EOpVectorSwizzle:
return true;
default:
break;
}
return false;
}
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
// //
// Member functions of the nodes used for building the tree. // Member functions of the nodes used for building the tree.
......
...@@ -381,6 +381,8 @@ TIntermTyped* TParseContext::handleBracketDereference(const TSourceLoc& loc, TIn ...@@ -381,6 +381,8 @@ TIntermTyped* TParseContext::handleBracketDereference(const TSourceLoc& loc, TIn
if (index->getQualifier().isFrontEndConstant()) { if (index->getQualifier().isFrontEndConstant()) {
if (base->getType().isUnsizedArray()) if (base->getType().isUnsizedArray())
base->getWritableType().updateImplicitArraySize(indexValue + 1); base->getWritableType().updateImplicitArraySize(indexValue + 1);
else
checkIndex(loc, base->getType(), indexValue);
result = intermediate.addIndex(EOpIndexDirect, base, index, loc); result = intermediate.addIndex(EOpIndexDirect, base, index, loc);
} else { } else {
if (base->getType().isUnsizedArray()) { if (base->getType().isUnsizedArray()) {
...@@ -390,8 +392,7 @@ TIntermTyped* TParseContext::handleBracketDereference(const TSourceLoc& loc, TIn ...@@ -390,8 +392,7 @@ TIntermTyped* TParseContext::handleBracketDereference(const TSourceLoc& loc, TIn
error(loc, "", "[", "array must be sized by a redeclaration or layout qualifier before being indexed with a variable"); error(loc, "", "[", "array must be sized by a redeclaration or layout qualifier before being indexed with a variable");
else { else {
// it is okay for a run-time sized array // it is okay for a run-time sized array
if (!isRuntimeSizable(*base)) checkRuntimeSizable(loc, *base);
error(loc, "", "[", "array must be redeclared with a size before being indexed with a variable");
} }
base->getWritableType().setArrayVariablyIndexed(); base->getWritableType().setArrayVariablyIndexed();
} }
...@@ -434,6 +435,10 @@ TIntermTyped* TParseContext::handleBracketDereference(const TSourceLoc& loc, TIn ...@@ -434,6 +435,10 @@ TIntermTyped* TParseContext::handleBracketDereference(const TSourceLoc& loc, TIn
} }
result->setType(newType); result->setType(newType);
// Propagate nonuniform
if (base->getQualifier().isNonUniform() || index->getQualifier().isNonUniform())
result->getWritableType().getQualifier().nonUniform = true;
if (anyIndexLimits) if (anyIndexLimits)
handleIndexLimits(loc, base, index); handleIndexLimits(loc, base, index);
} }
...@@ -742,6 +747,10 @@ TIntermTyped* TParseContext::handleDotDereference(const TSourceLoc& loc, TInterm ...@@ -742,6 +747,10 @@ TIntermTyped* TParseContext::handleDotDereference(const TSourceLoc& loc, TInterm
if (base->getQualifier().noContraction) if (base->getQualifier().noContraction)
result->getWritableType().getQualifier().noContraction = true; result->getWritableType().getQualifier().noContraction = true;
// Propagate nonuniform
if (base->getQualifier().isNonUniform())
result->getWritableType().getQualifier().nonUniform = true;
return result; return result;
} }
...@@ -2622,6 +2631,10 @@ void TParseContext::memberQualifierCheck(glslang::TPublicType& publicType) ...@@ -2622,6 +2631,10 @@ void TParseContext::memberQualifierCheck(glslang::TPublicType& publicType)
{ {
globalQualifierFixCheck(publicType.loc, publicType.qualifier); globalQualifierFixCheck(publicType.loc, publicType.qualifier);
checkNoShaderLayouts(publicType.loc, publicType.shaderQualifiers); checkNoShaderLayouts(publicType.loc, publicType.shaderQualifiers);
if (publicType.qualifier.isNonUniform()) {
error(publicType.loc, "not allowed on block or structure members", "nonuniformEXT", "");
publicType.qualifier.nonUniform = false;
}
} }
// //
...@@ -2629,12 +2642,15 @@ void TParseContext::memberQualifierCheck(glslang::TPublicType& publicType) ...@@ -2629,12 +2642,15 @@ void TParseContext::memberQualifierCheck(glslang::TPublicType& publicType)
// //
void TParseContext::globalQualifierFixCheck(const TSourceLoc& loc, TQualifier& qualifier) void TParseContext::globalQualifierFixCheck(const TSourceLoc& loc, TQualifier& qualifier)
{ {
bool nonuniformOkay = false;
// move from parameter/unknown qualifiers to pipeline in/out qualifiers // move from parameter/unknown qualifiers to pipeline in/out qualifiers
switch (qualifier.storage) { switch (qualifier.storage) {
case EvqIn: case EvqIn:
profileRequires(loc, ENoProfile, 130, nullptr, "in for stage inputs"); profileRequires(loc, ENoProfile, 130, nullptr, "in for stage inputs");
profileRequires(loc, EEsProfile, 300, nullptr, "in for stage inputs"); profileRequires(loc, EEsProfile, 300, nullptr, "in for stage inputs");
qualifier.storage = EvqVaryingIn; qualifier.storage = EvqVaryingIn;
nonuniformOkay = true;
break; break;
case EvqOut: case EvqOut:
profileRequires(loc, ENoProfile, 130, nullptr, "out for stage outputs"); profileRequires(loc, ENoProfile, 130, nullptr, "out for stage outputs");
...@@ -2645,10 +2661,17 @@ void TParseContext::globalQualifierFixCheck(const TSourceLoc& loc, TQualifier& q ...@@ -2645,10 +2661,17 @@ void TParseContext::globalQualifierFixCheck(const TSourceLoc& loc, TQualifier& q
qualifier.storage = EvqVaryingIn; qualifier.storage = EvqVaryingIn;
error(loc, "cannot use 'inout' at global scope", "", ""); error(loc, "cannot use 'inout' at global scope", "", "");
break; break;
case EvqGlobal:
case EvqTemporary:
nonuniformOkay = true;
break;
default: default:
break; break;
} }
if (!nonuniformOkay && qualifier.nonUniform)
error(loc, "for non-parameter, can only apply to 'in' or no storage qualifier", "nonuniformEXT", "");
invariantCheck(loc, qualifier); invariantCheck(loc, qualifier);
} }
...@@ -2897,6 +2920,7 @@ void TParseContext::mergeQualifiers(const TSourceLoc& loc, TQualifier& dst, cons ...@@ -2897,6 +2920,7 @@ void TParseContext::mergeQualifiers(const TSourceLoc& loc, TQualifier& dst, cons
MERGE_SINGLETON(readonly); MERGE_SINGLETON(readonly);
MERGE_SINGLETON(writeonly); MERGE_SINGLETON(writeonly);
MERGE_SINGLETON(specConstant); MERGE_SINGLETON(specConstant);
MERGE_SINGLETON(nonUniform);
if (repeated) if (repeated)
error(loc, "replicated qualifiers", "", ""); error(loc, "replicated qualifiers", "", "");
...@@ -3268,11 +3292,25 @@ void TParseContext::declareArray(const TSourceLoc& loc, const TString& identifie ...@@ -3268,11 +3292,25 @@ void TParseContext::declareArray(const TSourceLoc& loc, const TString& identifie
checkIoArraysConsistency(loc); checkIoArraysConsistency(loc);
} }
// Policy decision for whether a node could potentially be sized at runtime. // Policy and error check for needing a runtime sized array.
bool TParseContext::isRuntimeSizable(const TIntermTyped& base) const void TParseContext::checkRuntimeSizable(const TSourceLoc& loc, const TIntermTyped& base)
{
// runtime length implies runtime sizeable, so no problem
if (isRuntimeLength(base))
return;
// check for additional things allowed by GL_EXT_nonuniform_qualifier
if (base.getBasicType() == EbtSampler ||
(base.getBasicType() == EbtBlock && base.getType().getQualifier().isUniformOrBuffer()))
requireExtensions(loc, 1, &E_GL_EXT_nonuniform_qualifier, "variable index");
else
error(loc, "", "[", "array must be redeclared with a size before being indexed with a variable");
}
// Policy decision for whether a run-time .length() is allowed.
bool TParseContext::isRuntimeLength(const TIntermTyped& base) const
{ {
const TType& type = base.getType(); if (base.getType().getQualifier().storage == EvqBuffer) {
if (type.getQualifier().storage == EvqBuffer) {
// in a buffer block // in a buffer block
const TIntermBinary* binary = base.getAsBinaryNode(); const TIntermBinary* binary = base.getAsBinaryNode();
if (binary != nullptr && binary->getOp() == EOpIndexDirectStruct) { if (binary != nullptr && binary->getOp() == EOpIndexDirectStruct) {
...@@ -3287,12 +3325,6 @@ bool TParseContext::isRuntimeSizable(const TIntermTyped& base) const ...@@ -3287,12 +3325,6 @@ bool TParseContext::isRuntimeSizable(const TIntermTyped& base) const
return false; return false;
} }
// Policy decision for whether a run-time .length() is allowed.
bool TParseContext::isRuntimeLength(const TIntermTyped& base) const
{
return isRuntimeSizable(base);
}
// Returns true if the first argument to the #line directive is the line number for the next line. // Returns true if the first argument to the #line directive is the line number for the next line.
// //
// Desktop, pre-version 3.30: "After processing this directive // Desktop, pre-version 3.30: "After processing this directive
...@@ -3703,6 +3735,8 @@ void TParseContext::paramCheckFix(const TSourceLoc& loc, const TQualifier& quali ...@@ -3703,6 +3735,8 @@ void TParseContext::paramCheckFix(const TSourceLoc& loc, const TQualifier& quali
else else
warn(loc, "qualifier has no effect on non-output parameters", "precise", ""); warn(loc, "qualifier has no effect on non-output parameters", "precise", "");
} }
if (qualifier.isNonUniform())
type.getQualifier().nonUniform = qualifier.nonUniform;
paramCheckFixStorage(loc, qualifier.storage, type); paramCheckFixStorage(loc, qualifier.storage, type);
} }
...@@ -4680,11 +4714,16 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type) ...@@ -4680,11 +4714,16 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type)
if (type.getBasicType() == EbtSampler) { if (type.getBasicType() == EbtSampler) {
int lastBinding = qualifier.layoutBinding; int lastBinding = qualifier.layoutBinding;
if (type.isArray()) { if (type.isArray()) {
if (spvVersion.vulkan > 0)
lastBinding += 1;
else {
if (type.isSizedArray()) if (type.isSizedArray())
lastBinding += type.getCumulativeArraySize(); lastBinding += type.getCumulativeArraySize();
else { else {
lastBinding += 1; lastBinding += 1;
warn(loc, "assuming array size of one for compile-time checking of binding numbers for unsized array", "[]", ""); if (spvVersion.vulkan == 0)
warn(loc, "assuming binding count of one for compile-time checking of binding numbers for unsized array", "[]", "");
}
} }
} }
if (spvVersion.vulkan == 0 && lastBinding >= resources.maxCombinedTextureImageUnits) if (spvVersion.vulkan == 0 && lastBinding >= resources.maxCombinedTextureImageUnits)
...@@ -5852,6 +5891,11 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T ...@@ -5852,6 +5891,11 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T
basicOp = EOpConstructBool; basicOp = EOpConstructBool;
break; break;
case EOpConstructNonuniform:
node->getWritableType().getQualifier().nonUniform = true;
return node;
break;
default: default:
error(loc, "unsupported construction", "", ""); error(loc, "unsupported construction", "", "");
......
...@@ -427,7 +427,7 @@ protected: ...@@ -427,7 +427,7 @@ protected:
TVariable* makeInternalVariable(const char* name, const TType&) const; TVariable* makeInternalVariable(const char* name, const TType&) const;
TVariable* declareNonArray(const TSourceLoc&, const TString& identifier, const TType&); TVariable* declareNonArray(const TSourceLoc&, const TString& identifier, const TType&);
void declareArray(const TSourceLoc&, const TString& identifier, const TType&, TSymbol*&); void declareArray(const TSourceLoc&, const TString& identifier, const TType&, TSymbol*&);
bool isRuntimeSizable(const TIntermTyped&) const; void checkRuntimeSizable(const TSourceLoc&, const TIntermTyped&);
bool isRuntimeLength(const TIntermTyped&) const; bool isRuntimeLength(const TIntermTyped&) const;
TIntermNode* executeInitializer(const TSourceLoc&, TIntermTyped* initializer, TVariable* variable); TIntermNode* executeInitializer(const TSourceLoc&, TIntermTyped* initializer, TVariable* variable);
TIntermTyped* convertInitializerList(const TSourceLoc&, const TType&, TIntermTyped* initializer); TIntermTyped* convertInitializerList(const TSourceLoc&, const TType&, TIntermTyped* initializer);
......
...@@ -341,6 +341,7 @@ void TScanContext::fillInKeywordMap() ...@@ -341,6 +341,7 @@ void TScanContext::fillInKeywordMap()
(*KeywordMap)["const"] = CONST; (*KeywordMap)["const"] = CONST;
(*KeywordMap)["uniform"] = UNIFORM; (*KeywordMap)["uniform"] = UNIFORM;
(*KeywordMap)["nonuniformEXT"] = NONUNIFORM;
(*KeywordMap)["in"] = IN; (*KeywordMap)["in"] = IN;
(*KeywordMap)["out"] = OUT; (*KeywordMap)["out"] = OUT;
(*KeywordMap)["inout"] = INOUT; (*KeywordMap)["inout"] = INOUT;
...@@ -873,6 +874,12 @@ int TScanContext::tokenizeIdentifier() ...@@ -873,6 +874,12 @@ int TScanContext::tokenizeIdentifier()
case CASE: case CASE:
return keyword; return keyword;
case NONUNIFORM:
if (parseContext.extensionTurnedOn(E_GL_EXT_nonuniform_qualifier))
return keyword;
else
return identifierOrType();
case SWITCH: case SWITCH:
case DEFAULT: case DEFAULT:
if ((parseContext.profile == EEsProfile && parseContext.version < 300) || if ((parseContext.profile == EEsProfile && parseContext.version < 300) ||
......
...@@ -199,6 +199,7 @@ void TParseVersions::initializeExtensionBehavior() ...@@ -199,6 +199,7 @@ void TParseVersions::initializeExtensionBehavior()
extensionBehavior[E_GL_EXT_shader_image_load_formatted] = EBhDisable; extensionBehavior[E_GL_EXT_shader_image_load_formatted] = EBhDisable;
extensionBehavior[E_GL_EXT_post_depth_coverage] = EBhDisable; extensionBehavior[E_GL_EXT_post_depth_coverage] = EBhDisable;
extensionBehavior[E_GL_EXT_control_flow_attributes] = EBhDisable; extensionBehavior[E_GL_EXT_control_flow_attributes] = EBhDisable;
extensionBehavior[E_GL_EXT_nonuniform_qualifier] = EBhDisable;
// #line and #include // #line and #include
extensionBehavior[E_GL_GOOGLE_cpp_style_line_directive] = EBhDisable; extensionBehavior[E_GL_GOOGLE_cpp_style_line_directive] = EBhDisable;
...@@ -360,6 +361,7 @@ void TParseVersions::getPreamble(std::string& preamble) ...@@ -360,6 +361,7 @@ void TParseVersions::getPreamble(std::string& preamble)
"#define GL_EXT_shader_image_load_formatted 1\n" "#define GL_EXT_shader_image_load_formatted 1\n"
"#define GL_EXT_post_depth_coverage 1\n" "#define GL_EXT_post_depth_coverage 1\n"
"#define GL_EXT_control_flow_attributes 1\n" "#define GL_EXT_control_flow_attributes 1\n"
"#define GL_EXT_nonuniform_qualifier 1\n"
// GL_KHR_shader_subgroup // GL_KHR_shader_subgroup
"#define GL_KHR_shader_subgroup_basic 1\n" "#define GL_KHR_shader_subgroup_basic 1\n"
......
...@@ -157,6 +157,7 @@ const char* const E_GL_EXT_device_group = "GL_EXT_device_group"; ...@@ -157,6 +157,7 @@ const char* const E_GL_EXT_device_group = "GL_EXT_device_group";
const char* const E_GL_EXT_multiview = "GL_EXT_multiview"; const char* const E_GL_EXT_multiview = "GL_EXT_multiview";
const char* const E_GL_EXT_post_depth_coverage = "GL_EXT_post_depth_coverage"; const char* const E_GL_EXT_post_depth_coverage = "GL_EXT_post_depth_coverage";
const char* const E_GL_EXT_control_flow_attributes = "GL_EXT_control_flow_attributes"; const char* const E_GL_EXT_control_flow_attributes = "GL_EXT_control_flow_attributes";
const char* const E_GL_EXT_nonuniform_qualifier = "GL_EXT_nonuniform_qualifier";
// Arrays of extensions for the above viewportEXTs duplications // Arrays of extensions for the above viewportEXTs duplications
......
...@@ -140,7 +140,7 @@ extern int yylex(YYSTYPE*, TParseContext&); ...@@ -140,7 +140,7 @@ extern int yylex(YYSTYPE*, TParseContext&);
%token <lex> U8VEC2 U8VEC3 U8VEC4 %token <lex> U8VEC2 U8VEC3 U8VEC4
%token <lex> VEC2 VEC3 VEC4 %token <lex> VEC2 VEC3 VEC4
%token <lex> MAT2 MAT3 MAT4 CENTROID IN OUT INOUT %token <lex> MAT2 MAT3 MAT4 CENTROID IN OUT INOUT
%token <lex> UNIFORM PATCH SAMPLE BUFFER SHARED %token <lex> UNIFORM PATCH SAMPLE BUFFER SHARED NONUNIFORM
%token <lex> COHERENT VOLATILE RESTRICT READONLY WRITEONLY %token <lex> COHERENT VOLATILE RESTRICT READONLY WRITEONLY
%token <lex> DVEC2 DVEC3 DVEC4 DMAT2 DMAT3 DMAT4 %token <lex> DVEC2 DVEC3 DVEC4 DMAT2 DMAT3 DMAT4
%token <lex> F16VEC2 F16VEC3 F16VEC4 F16MAT2 F16MAT3 F16MAT4 %token <lex> F16VEC2 F16VEC3 F16VEC4 F16MAT2 F16MAT3 F16MAT4
...@@ -268,6 +268,7 @@ extern int yylex(YYSTYPE*, TParseContext&); ...@@ -268,6 +268,7 @@ extern int yylex(YYSTYPE*, TParseContext&);
%type <interm> array_specifier %type <interm> array_specifier
%type <interm.type> precise_qualifier invariant_qualifier interpolation_qualifier storage_qualifier precision_qualifier %type <interm.type> precise_qualifier invariant_qualifier interpolation_qualifier storage_qualifier precision_qualifier
%type <interm.type> layout_qualifier layout_qualifier_id_list layout_qualifier_id %type <interm.type> layout_qualifier layout_qualifier_id_list layout_qualifier_id
%type <interm.type> non_uniform_qualifier
%type <interm.type> type_qualifier fully_specified_type type_specifier %type <interm.type> type_qualifier fully_specified_type type_specifier
%type <interm.type> single_type_qualifier %type <interm.type> single_type_qualifier
...@@ -473,6 +474,11 @@ function_identifier ...@@ -473,6 +474,11 @@ function_identifier
$$.function = new TFunction(&empty, TType(EbtVoid), EOpNull); $$.function = new TFunction(&empty, TType(EbtVoid), EOpNull);
} }
} }
| non_uniform_qualifier {
// Constructor
$$.intermNode = 0;
$$.function = parseContext.handleConstructorCall($1.loc, $1);
}
; ;
unary_expression unary_expression
...@@ -1217,6 +1223,9 @@ single_type_qualifier ...@@ -1217,6 +1223,9 @@ single_type_qualifier
// allow inheritance of storage qualifier from block declaration // allow inheritance of storage qualifier from block declaration
$$ = $1; $$ = $1;
} }
| non_uniform_qualifier {
$$ = $1;
}
; ;
storage_qualifier storage_qualifier
...@@ -1337,6 +1346,13 @@ storage_qualifier ...@@ -1337,6 +1346,13 @@ storage_qualifier
} }
; ;
non_uniform_qualifier
: NONUNIFORM {
$$.init($1.loc);
$$.qualifier.nonUniform = true;
}
;
type_name_list type_name_list
: IDENTIFIER { : IDENTIFIER {
// TODO // TODO
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -651,6 +651,7 @@ protected: ...@@ -651,6 +651,7 @@ protected:
TIntermSequence& findLinkerObjects() const; TIntermSequence& findLinkerObjects() const;
bool userOutputUsed() const; bool userOutputUsed() const;
bool isSpecializationOperation(const TIntermOperator&) const; bool isSpecializationOperation(const TIntermOperator&) const;
bool isNonuniformPropagating(TOperator) const;
bool promoteUnary(TIntermUnary&); bool promoteUnary(TIntermUnary&);
bool promoteBinary(TIntermBinary&); bool promoteBinary(TIntermBinary&);
void addSymbolLinkageNode(TIntermAggregate*& linkage, TSymbolTable&, const TString&); void addSymbolLinkageNode(TIntermAggregate*& linkage, TSymbolTable&, const TString&);
......
...@@ -121,6 +121,7 @@ INSTANTIATE_TEST_CASE_P( ...@@ -121,6 +121,7 @@ INSTANTIATE_TEST_CASE_P(
"310.tese", "310.tese",
"310implicitSizeArrayError.vert", "310implicitSizeArrayError.vert",
"310AofA.vert", "310AofA.vert",
"310runtimeArray.vert",
"320.comp", "320.comp",
"320.vert", "320.vert",
"320.geom", "320.geom",
...@@ -200,6 +201,7 @@ INSTANTIATE_TEST_CASE_P( ...@@ -200,6 +201,7 @@ INSTANTIATE_TEST_CASE_P(
"matrix.frag", "matrix.frag",
"matrix2.frag", "matrix2.frag",
"mixedArrayDecls.frag", "mixedArrayDecls.frag",
"nonuniform.frag",
"newTexture.frag", "newTexture.frag",
"Operations.frag", "Operations.frag",
"overlongLiteral.frag", "overlongLiteral.frag",
......
...@@ -282,6 +282,7 @@ INSTANTIATE_TEST_CASE_P( ...@@ -282,6 +282,7 @@ INSTANTIATE_TEST_CASE_P(
"spv.newTexture.frag", "spv.newTexture.frag",
"spv.noDeadDecorations.vert", "spv.noDeadDecorations.vert",
"spv.nonSquare.vert", "spv.nonSquare.vert",
"spv.nonuniform.frag",
"spv.noWorkgroup.comp", "spv.noWorkgroup.comp",
"spv.offsets.frag", "spv.offsets.frag",
"spv.Operations.frag", "spv.Operations.frag",
......
...@@ -844,6 +844,8 @@ TIntermTyped* HlslParseContext::handleBracketDereference(const TSourceLoc& loc, ...@@ -844,6 +844,8 @@ TIntermTyped* HlslParseContext::handleBracketDereference(const TSourceLoc& loc,
if (index->getQualifier().isFrontEndConstant()) { if (index->getQualifier().isFrontEndConstant()) {
if (base->getType().isUnsizedArray()) if (base->getType().isUnsizedArray())
base->getWritableType().updateImplicitArraySize(indexValue + 1); base->getWritableType().updateImplicitArraySize(indexValue + 1);
else
checkIndex(loc, base->getType(), indexValue);
result = intermediate.addIndex(EOpIndexDirect, base, index, loc); result = intermediate.addIndex(EOpIndexDirect, base, index, loc);
} else } else
result = intermediate.addIndex(EOpIndexIndirect, base, index, loc); result = intermediate.addIndex(EOpIndexIndirect, base, index, loc);
...@@ -6551,6 +6553,7 @@ void HlslParseContext::mergeQualifiers(TQualifier& dst, const TQualifier& src) ...@@ -6551,6 +6553,7 @@ void HlslParseContext::mergeQualifiers(TQualifier& dst, const TQualifier& src)
MERGE_SINGLETON(readonly); MERGE_SINGLETON(readonly);
MERGE_SINGLETON(writeonly); MERGE_SINGLETON(writeonly);
MERGE_SINGLETON(specConstant); MERGE_SINGLETON(specConstant);
MERGE_SINGLETON(nonUniform);
} }
// used to flatten the sampler type space into a single dimension // used to flatten the sampler type space into a single dimension
......
{
"commits" : [
{
"name" : "spirv-tools",
"site" : "gitlab",
"subrepo" : "spirv/spirv-tools",
"subdir" : "External/spirv-tools",
"commit" : "d4e2c2eaa6fd2e9f9cd218ea9add9b0c8ae759ba"
},
{
"name" : "spirv-tools/external/spirv-headers",
"site" : "gitlab",
"subrepo" : "spirv/SPIRV-Headers",
"subdir" : "External/spirv-tools/external/spirv-headers",
"commit" : "4082a777bd5df31ed45acf40e64263094e85ed2e"
}
]
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment