From 352e668a6d6c38fab39ed823824a6c55c6bb049d Mon Sep 17 00:00:00 2001 From: Chow Date: Mon, 9 Sep 2019 13:24:24 +0800 Subject: [PATCH] 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 --- Test/430.comp | 3 + Test/baseResults/430.comp.out | 155 +++++++++--------- glslang/Include/Types.h | 7 + glslang/MachineIndependent/ParseHelper.cpp | 5 +- .../MachineIndependent/localintermediate.h | 7 +- 5 files changed, 98 insertions(+), 79 deletions(-) diff --git a/Test/430.comp b/Test/430.comp index 0929432b..178b9942 100644 --- a/Test/430.comp +++ b/Test/430.comp @@ -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]; diff --git a/Test/baseResults/430.comp.out b/Test/baseResults/430.comp.out index ef8d19e1..55c82388 100644 --- a/Test/baseResults/430.comp.out +++ b/Test/baseResults/430.comp.out @@ -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) diff --git a/glslang/Include/Types.h b/glslang/Include/Types.h index a419cb0f..9961c943 100644 --- a/glslang/Include/Types.h +++ b/glslang/Include/Types.h @@ -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]; diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index 08fa610c..c6943918 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -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", ""); diff --git a/glslang/MachineIndependent/localintermediate.h b/glslang/MachineIndependent/localintermediate.h index 77ed7c39..1bd06339 100644 --- a/glslang/MachineIndependent/localintermediate.h +++ b/glslang/MachineIndependent/localintermediate.h @@ -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;