Add flags for local size values ( compute shader )

Purpose :

According to GLSL SPEC 4.6 ( 4.4.1.4 Compute Shader Inputs), for compute shader input qualifiers, we should declare such qualifiers with same values in the same shader (local_size_x, y and z).
"If such a layout qualifier is declared more than once in the same shader, all those declarations must set the same set of local work-group sizes and set them to the same values; otherwise a compile-time error results."

Why this fix:

If we manually set "local_size_x = 1" and directly following a declaration like "local_size_x = 2", this would not be detected. That is because currently we treat all the '1' as default value and could not restrictly detect whether those are default values.

Test case:
......
layout(local_size_x=1) in;
layout(local_size_x=2) in;
......

So I add test cases for this fix:
1. set local_size_y = 1 => success
2. set local_size_y = 2 => error
3. set local_size_y = 1 => success
This commit is contained in:
Chow 2019-09-09 13:24:24 +08:00
parent 664ad418f8
commit 352e668a6d
5 changed files with 98 additions and 79 deletions

View File

@ -48,6 +48,9 @@ shared vec4 s;
layout(location = 2) shared vec4 sl; // ERROR
shared float fs = 4.2; // ERROR
layout(local_size_y = 1) in;
layout(local_size_y = 2) in; // ERROR, changing
layout(local_size_y = 1) in;
layout(local_size_x = 2, local_size_y = 3, local_size_z = 4) out; // ERROR
int arrX[gl_WorkGroupSize.x];

View File

@ -8,14 +8,15 @@ ERROR: 0:45: 'out' : global storage output qualifier cannot be used in a compute
ERROR: 0:48: 'shared' : cannot apply layout qualifiers to a shared variable
ERROR: 0:48: 'location' : can only apply to uniform, buffer, in, or out storage qualifiers
ERROR: 0:49: 'shared' : cannot initialize this type of qualifier
ERROR: 0:51: 'local_size' : can only apply to 'in'
ERROR: 0:51: 'local_size' : can only apply to 'in'
ERROR: 0:51: 'local_size' : can only apply to 'in'
ERROR: 0:65: 'assign' : l-value required "ro" (can't modify a readonly buffer)
ERROR: 0:77: '=' : cannot convert from ' temp double' to ' temp int'
ERROR: 0:81: 'input block' : not supported in this stage: compute
ERROR: 0:85: 'output block' : not supported in this stage: compute
ERROR: 16 compilation errors. No code generated.
ERROR: 0:52: 'local_size' : cannot change previously set size
ERROR: 0:54: 'local_size' : can only apply to 'in'
ERROR: 0:54: 'local_size' : can only apply to 'in'
ERROR: 0:54: 'local_size' : can only apply to 'in'
ERROR: 0:68: 'assign' : l-value required "ro" (can't modify a readonly buffer)
ERROR: 0:80: '=' : cannot convert from ' temp double' to ' temp int'
ERROR: 0:84: 'input block' : not supported in this stage: compute
ERROR: 0:88: 'output block' : not supported in this stage: compute
ERROR: 17 compilation errors. No code generated.
Shader version: 430
@ -51,77 +52,77 @@ ERROR: node is still EOpNull!
0:39 10 (const int)
0:39 true case
0:40 Barrier ( global void)
0:63 Function Definition: foo( ( global void)
0:63 Function Parameters:
0:65 Sequence
0:65 move second child to first child ( temp float)
0:65 direct index (layout( column_major shared) readonly temp float)
0:65 values: direct index for structure (layout( column_major shared) readonly buffer unsized 3-element array of float)
0:65 'ro' (layout( column_major shared) readonly buffer block{layout( column_major shared) readonly buffer int value, layout( column_major shared) readonly buffer unsized 3-element array of float values})
0:65 Constant:
0:65 1 (const int)
0:65 Constant:
0:65 2 (const int)
0:65 Constant:
0:65 4.700000
0:66 array length ( temp int)
0:66 values: direct index for structure (layout( column_major shared) readonly buffer unsized 3-element array of float)
0:66 'ro' (layout( column_major shared) readonly buffer block{layout( column_major shared) readonly buffer int value, layout( column_major shared) readonly buffer unsized 3-element array of float values})
0:66 Constant:
0:66 1 (const int)
0:67 Barrier ( global void)
0:72 Function Definition: fooaoeu( ( global void)
0:72 Function Parameters:
0:73 Sequence
0:73 Sequence
0:73 move second child to first child ( temp 2-component vector of int)
0:73 'storePos' ( temp 2-component vector of int)
0:73 Convert uint to int ( temp 2-component vector of int)
0:73 vector swizzle ( temp 2-component vector of uint)
0:73 'gl_GlobalInvocationID' ( in 3-component vector of uint GlobalInvocationID)
0:73 Sequence
0:73 Constant:
0:73 0 (const int)
0:73 Constant:
0:73 1 (const int)
0:74 Sequence
0:74 move second child to first child ( temp double)
0:74 'localCoef' ( temp double)
0:74 Convert float to double ( temp double)
0:74 length ( global float)
0:74 divide ( temp 2-component vector of float)
0:74 Convert int to float ( temp 2-component vector of float)
0:74 subtract ( temp 2-component vector of int)
0:74 Convert uint to int ( temp 2-component vector of int)
0:74 vector swizzle ( temp 2-component vector of uint)
0:74 'gl_LocalInvocationID' ( in 3-component vector of uint LocalInvocationID)
0:74 Sequence
0:74 Constant:
0:74 0 (const int)
0:74 Constant:
0:74 1 (const int)
0:74 Constant:
0:74 8 (const int)
0:74 Constant:
0:74 8.000000
0:75 Sequence
0:75 move second child to first child ( temp 4-component vector of double)
0:75 'aa' ( temp 4-component vector of double)
0:75 Constant:
0:75 0.400000
0:75 0.200000
0:75 0.300000
0:75 0.400000
0:66 Function Definition: foo( ( global void)
0:66 Function Parameters:
0:68 Sequence
0:68 move second child to first child ( temp float)
0:68 direct index (layout( column_major shared) readonly temp float)
0:68 values: direct index for structure (layout( column_major shared) readonly buffer unsized 3-element array of float)
0:68 'ro' (layout( column_major shared) readonly buffer block{layout( column_major shared) readonly buffer int value, layout( column_major shared) readonly buffer unsized 3-element array of float values})
0:68 Constant:
0:68 1 (const int)
0:68 Constant:
0:68 2 (const int)
0:68 Constant:
0:68 4.700000
0:69 array length ( temp int)
0:69 values: direct index for structure (layout( column_major shared) readonly buffer unsized 3-element array of float)
0:69 'ro' (layout( column_major shared) readonly buffer block{layout( column_major shared) readonly buffer int value, layout( column_major shared) readonly buffer unsized 3-element array of float values})
0:69 Constant:
0:69 1 (const int)
0:70 Barrier ( global void)
0:75 Function Definition: fooaoeu( ( global void)
0:75 Function Parameters:
0:76 Sequence
0:76 Sequence
0:76 move second child to first child ( temp double)
0:76 'globalCoef' ( temp double)
0:76 Constant:
0:76 1.000000
0:76 move second child to first child ( temp 2-component vector of int)
0:76 'storePos' ( temp 2-component vector of int)
0:76 Convert uint to int ( temp 2-component vector of int)
0:76 vector swizzle ( temp 2-component vector of uint)
0:76 'gl_GlobalInvocationID' ( in 3-component vector of uint GlobalInvocationID)
0:76 Sequence
0:76 Constant:
0:76 0 (const int)
0:76 Constant:
0:76 1 (const int)
0:77 Sequence
0:77 move second child to first child ( temp double)
0:77 'localCoef' ( temp double)
0:77 Convert float to double ( temp double)
0:77 length ( global float)
0:77 divide ( temp 2-component vector of float)
0:77 Convert int to float ( temp 2-component vector of float)
0:77 subtract ( temp 2-component vector of int)
0:77 Convert uint to int ( temp 2-component vector of int)
0:77 vector swizzle ( temp 2-component vector of uint)
0:77 'gl_LocalInvocationID' ( in 3-component vector of uint LocalInvocationID)
0:77 Sequence
0:77 Constant:
0:77 0 (const int)
0:77 Constant:
0:77 1 (const int)
0:77 Constant:
0:77 8 (const int)
0:77 Constant:
0:77 8.000000
0:78 Sequence
0:78 move second child to first child ( temp double)
0:78 'di' ( temp double)
0:78 Convert int to double ( temp double)
0:78 'i' ( temp int)
0:78 move second child to first child ( temp 4-component vector of double)
0:78 'aa' ( temp 4-component vector of double)
0:78 Constant:
0:78 0.400000
0:78 0.200000
0:78 0.300000
0:78 0.400000
0:79 Sequence
0:79 move second child to first child ( temp double)
0:79 'globalCoef' ( temp double)
0:79 Constant:
0:79 1.000000
0:81 Sequence
0:81 move second child to first child ( temp double)
0:81 'di' ( temp double)
0:81 Convert int to double ( temp double)
0:81 'i' ( temp int)
0:? Linker Objects
0:? 'gl_WorkGroupSize' ( const 3-component vector of uint WorkGroupSize)
0:? 2 (const uint)

View File

@ -1195,6 +1195,7 @@ struct TShaderQualifiers {
TVertexOrder order;
bool pointMode;
int localSize[3]; // compute shader
bool localSizeNotDefault[3]; // compute shader
int localSizeSpecId[3]; // compute shader specialization id for gl_WorkGroupSize
#ifndef GLSLANG_WEB
bool earlyFragmentTests; // fragment input
@ -1225,6 +1226,9 @@ struct TShaderQualifiers {
localSize[0] = 1;
localSize[1] = 1;
localSize[2] = 1;
localSizeNotDefault[0] = false;
localSizeNotDefault[1] = false;
localSizeNotDefault[2] = false;
localSizeSpecId[0] = TQualifier::layoutNotSet;
localSizeSpecId[1] = TQualifier::layoutNotSet;
localSizeSpecId[2] = TQualifier::layoutNotSet;
@ -1272,6 +1276,9 @@ struct TShaderQualifiers {
if (src.localSize[i] > 1)
localSize[i] = src.localSize[i];
}
for (int i = 0; i < 3; ++i) {
localSizeNotDefault[i] = src.localSizeNotDefault[i] || localSizeNotDefault[i];
}
for (int i = 0; i < 3; ++i) {
if (src.localSizeSpecId[i] != TQualifier::layoutNotSet)
localSizeSpecId[i] = src.localSizeSpecId[i];

View File

@ -5360,14 +5360,17 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
}
if (id == "local_size_x") {
publicType.shaderQualifiers.localSize[0] = value;
publicType.shaderQualifiers.localSizeNotDefault[0] = true;
return;
}
if (id == "local_size_y") {
publicType.shaderQualifiers.localSize[1] = value;
publicType.shaderQualifiers.localSizeNotDefault[1] = true;
return;
}
if (id == "local_size_z") {
publicType.shaderQualifiers.localSize[2] = value;
publicType.shaderQualifiers.localSizeNotDefault[2] = true;
return;
}
if (spvVersion.spv != 0) {
@ -7945,7 +7948,7 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con
error(loc, "can only apply to 'in'", "point_mode", "");
}
for (int i = 0; i < 3; ++i) {
if (publicType.shaderQualifiers.localSize[i] > 1) {
if (publicType.shaderQualifiers.localSizeNotDefault[i]) {
if (publicType.qualifier.storage == EvqVaryingIn) {
if (! intermediate.setLocalSize(i, publicType.shaderQualifiers.localSize[i]))
error(loc, "cannot change previously set size", "local_size", "");

View File

@ -271,6 +271,9 @@ public:
localSize[0] = 1;
localSize[1] = 1;
localSize[2] = 1;
localSizeNotDefault[0] = false;
localSizeNotDefault[1] = false;
localSizeNotDefault[2] = false;
localSizeSpecId[0] = TQualifier::layoutNotSet;
localSizeSpecId[1] = TQualifier::layoutNotSet;
localSizeSpecId[2] = TQualifier::layoutNotSet;
@ -648,8 +651,9 @@ public:
bool setLocalSize(int dim, int size)
{
if (localSize[dim] > 1)
if (localSizeNotDefault[dim])
return size == localSize[dim];
localSizeNotDefault[dim] = true;
localSize[dim] = size;
return true;
}
@ -921,6 +925,7 @@ protected:
TInterlockOrdering interlockOrdering;
bool pointMode;
int localSize[3];
bool localSizeNotDefault[3];
int localSizeSpecId[3];
bool earlyFragmentTests;
bool postDepthCoverage;