From f2dcc87c6aa5a9ded87edb15119d73677f83f3ea Mon Sep 17 00:00:00 2001 From: Sahil Parmar Date: Mon, 15 Jul 2019 16:05:18 -0700 Subject: [PATCH] Allow unsized view array dimension for non-block perviewNV attributes --- .../spv.meshShaderPerViewUserDefined.mesh.out | 50 ++++++++++++++++++- .../spv.meshShaderPerView_Errors.mesh.out | 11 ++++ Test/spv.meshShaderPerViewUserDefined.mesh | 20 ++++++-- Test/spv.meshShaderPerView_Errors.mesh | 32 ++++++++++++ glslang/MachineIndependent/ParseHelper.cpp | 36 +++++++------ glslang/MachineIndependent/ParseHelper.h | 2 +- gtests/Spv.FromFile.cpp | 1 + 7 files changed, 131 insertions(+), 21 deletions(-) create mode 100644 Test/baseResults/spv.meshShaderPerView_Errors.mesh.out create mode 100644 Test/spv.meshShaderPerView_Errors.mesh diff --git a/Test/baseResults/spv.meshShaderPerViewUserDefined.mesh.out b/Test/baseResults/spv.meshShaderPerViewUserDefined.mesh.out index 7e7a37db..266f662d 100644 --- a/Test/baseResults/spv.meshShaderPerViewUserDefined.mesh.out +++ b/Test/baseResults/spv.meshShaderPerViewUserDefined.mesh.out @@ -1,13 +1,13 @@ spv.meshShaderPerViewUserDefined.mesh // Module Version 10000 // Generated by (magic number): 80007 -// Id's are bound by 90 +// Id's are bound by 108 Capability MeshShadingNV Extension "SPV_NV_mesh_shader" 1: ExtInstImport "GLSL.std.450" MemoryModel Logical GLSL450 - EntryPoint MeshNV 4 "main" 11 20 21 35 67 + EntryPoint MeshNV 4 "main" 11 20 21 35 67 92 95 96 97 102 105 106 107 ExecutionMode 4 LocalSize 32 1 1 ExecutionMode 4 OutputVertices 81 ExecutionMode 4 OutputPrimitivesNV 32 @@ -32,6 +32,14 @@ spv.meshShaderPerViewUserDefined.mesh MemberName 64(perviewBlock) 2 "color7" MemberName 64(perviewBlock) 3 "color8" Name 67 "b2" + Name 92 "nonBlk1" + Name 95 "nonBlk2" + Name 96 "nonBlk3" + Name 97 "nonBlk4" + Name 102 "nonBlkArr1" + Name 105 "nonBlkArr2" + Name 106 "nonBlkArr3" + Name 107 "nonBlkArr4" Decorate 11(gl_LocalInvocationID) BuiltIn LocalInvocationId Decorate 20(gl_MeshViewIndicesNV) BuiltIn MeshViewIndicesNV Decorate 21(gl_MeshViewCountNV) BuiltIn MeshViewCountNV @@ -50,6 +58,26 @@ spv.meshShaderPerViewUserDefined.mesh Decorate 64(perviewBlock) Block Decorate 67(b2) Location 10 Decorate 89 BuiltIn WorkgroupSize + Decorate 92(nonBlk1) PerViewNV + Decorate 92(nonBlk1) Location 18 + Decorate 95(nonBlk2) PerPrimitiveNV + Decorate 95(nonBlk2) PerViewNV + Decorate 95(nonBlk2) Location 19 + Decorate 96(nonBlk3) PerViewNV + Decorate 96(nonBlk3) Location 20 + Decorate 97(nonBlk4) PerPrimitiveNV + Decorate 97(nonBlk4) PerViewNV + Decorate 97(nonBlk4) Location 21 + Decorate 102(nonBlkArr1) PerViewNV + Decorate 102(nonBlkArr1) Location 22 + Decorate 105(nonBlkArr2) PerPrimitiveNV + Decorate 105(nonBlkArr2) PerViewNV + Decorate 105(nonBlkArr2) Location 24 + Decorate 106(nonBlkArr3) PerViewNV + Decorate 106(nonBlkArr3) Location 26 + Decorate 107(nonBlkArr4) PerPrimitiveNV + Decorate 107(nonBlkArr4) PerViewNV + Decorate 107(nonBlkArr4) Location 28 2: TypeVoid 3: TypeFunction 2 6: TypeInt 32 0 @@ -106,6 +134,24 @@ spv.meshShaderPerViewUserDefined.mesh 86: 27(fvec4) ConstantComposite 85 85 85 85 88: 6(int) Constant 32 89: 9(ivec3) ConstantComposite 88 60 60 + 90: TypeArray 63 32 + 91: TypePointer Output 90 + 92(nonBlk1): 91(ptr) Variable Output + 93: TypeArray 63 88 + 94: TypePointer Output 93 + 95(nonBlk2): 94(ptr) Variable Output + 96(nonBlk3): 91(ptr) Variable Output + 97(nonBlk4): 94(ptr) Variable Output + 98: TypeArray 27(fvec4) 62 + 99: TypeArray 98 17 + 100: TypeArray 99 32 + 101: TypePointer Output 100 + 102(nonBlkArr1): 101(ptr) Variable Output + 103: TypeArray 99 88 + 104: TypePointer Output 103 + 105(nonBlkArr2): 104(ptr) Variable Output + 106(nonBlkArr3): 101(ptr) Variable Output + 107(nonBlkArr4): 104(ptr) Variable Output 4(main): 2 Function None 3 5: Label 8(iid): 7(ptr) Variable Function diff --git a/Test/baseResults/spv.meshShaderPerView_Errors.mesh.out b/Test/baseResults/spv.meshShaderPerView_Errors.mesh.out new file mode 100644 index 00000000..aa0b99ee --- /dev/null +++ b/Test/baseResults/spv.meshShaderPerView_Errors.mesh.out @@ -0,0 +1,11 @@ +spv.meshShaderPerView_Errors.mesh +ERROR: 0:19: '[]' : only outermost dimension of an array of arrays can be implicitly sized +ERROR: 0:20: '[]' : mesh view output array size must be gl_MaxMeshViewCountNV or implicitly sized +ERROR: 0:21: 'perviewNV' : requires a view array dimension +ERROR: 0:25: '[]' : only outermost dimension of an array of arrays can be implicitly sized +ERROR: 0:26: '[]' : mesh view output array size must be gl_MaxMeshViewCountNV or implicitly sized +ERROR: 0:27: 'perviewNV' : requires a view array dimension +ERROR: 6 compilation errors. No code generated. + + +SPIR-V is not generated for failed compile or link diff --git a/Test/spv.meshShaderPerViewUserDefined.mesh b/Test/spv.meshShaderPerViewUserDefined.mesh index 4a316eb2..262504dd 100644 --- a/Test/spv.meshShaderPerViewUserDefined.mesh +++ b/Test/spv.meshShaderPerViewUserDefined.mesh @@ -22,18 +22,30 @@ layout(triangles) out; layout(location=0) out block { perprimitiveNV perviewNV vec4 color1[][3]; // Implicitly sized perprimitiveNV vec4 color2[3]; - perviewNV vec4 color3[MAX_VIEWS][3]; // Explicitly sized + perviewNV vec4 color3[MAX_VIEWS][3]; // Explicitly sized vec4 color4; } b[]; -// per-view block +// per-view block attributes perviewNV layout(location=10) out perviewBlock { perprimitiveNV vec4 color5[]; // Implicitly sized perprimitiveNV vec4 color6[MAX_VIEWS][3]; // Explicitly sized - vec4 color7[][3]; // Implicitly sized - vec4 color8[MAX_VIEWS]; // Explicitly sized + vec4 color7[][3]; // Implicitly sized + vec4 color8[MAX_VIEWS]; // Explicitly sized } b2[]; +// per-view non-block attributes +perviewNV layout(location=18) out vec4 nonBlk1[MAX_VER][MAX_VIEWS]; // Explicit+Explicit +perviewNV perprimitiveNV layout(location=19) out vec4 nonBlk2[MAX_PRIM][]; // Explicit+Implicit +perviewNV layout(location=20) out vec4 nonBlk3[][MAX_VIEWS]; // Implicit+Explicit +perviewNV perprimitiveNV layout(location=21) out vec4 nonBlk4[][]; // Implicit+Implicit + +// per-view non-block array attributes +perviewNV layout(location=22) out vec4 nonBlkArr1[MAX_VER][MAX_VIEWS][2]; // Explicit+Explicit +perviewNV perprimitiveNV layout(location=24) out vec4 nonBlkArr2[MAX_PRIM][][2]; // Explicit+Implicit +perviewNV layout(location=26) out vec4 nonBlkArr3[][MAX_VIEWS][2]; // Implicit+Explicit +perviewNV perprimitiveNV layout(location=28) out vec4 nonBlkArr4[][][2]; // Implicit+Implicit + void main() { uint iid = gl_LocalInvocationID.x; diff --git a/Test/spv.meshShaderPerView_Errors.mesh b/Test/spv.meshShaderPerView_Errors.mesh new file mode 100644 index 00000000..77190ef0 --- /dev/null +++ b/Test/spv.meshShaderPerView_Errors.mesh @@ -0,0 +1,32 @@ +#version 450 + +#define MAX_VER 81 +#define MAX_PRIM 32 +#define MAX_VIEWS gl_MaxMeshViewCountNV + +#extension GL_NV_mesh_shader : enable + +layout(local_size_x = 32) in; + +layout(max_vertices=MAX_VER) out; +layout(max_primitives=MAX_PRIM) out; +layout(triangles) out; + +// test error checks for use of incorrect per-view attributes + +// per-view block attributes +perviewNV layout(location=0) out perviewBlock { + vec4 missingInnermostDimSize1[][]; + vec4 incorrectViewDimSize1[MAX_VIEWS+1]; + vec4 missingViewDim1; +} b2[]; + +// per-view non-block attributes +perviewNV layout(location=10) out vec4 missingInnermostDimSize2[][][]; +perviewNV layout(location=11) out vec4 incorrectViewDimSize2[][MAX_VIEWS-1]; +perviewNV layout(location=12) out vec4 missingViewDim2[]; + +void main() +{ +} + diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index 276f4b75..6df25f0e 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -3976,23 +3976,30 @@ bool TParseContext::isRuntimeLength(const TIntermTyped& base) const } #ifdef NV_EXTENSIONS -// Fix mesh view output array dimension -void TParseContext::resizeMeshViewDimension(const TSourceLoc& loc, TType& type) +// Check if mesh perviewNV attributes have a view dimension +// and resize it to gl_MaxMeshViewCountNV when implicitly sized. +void TParseContext::checkAndResizeMeshViewDim(const TSourceLoc& loc, TType& type, bool isBlockMember) { // see if member is a per-view attribute - if (type.getQualifier().isPerView()) { - // since we don't have the maxMeshViewCountNV set during parsing builtins, we hardcode the value - int maxViewCount = parsingBuiltins ? 4 : resources.maxMeshViewCountNV; + if (!type.getQualifier().isPerView()) + return; - if (! type.isArray()) { - error(loc, "requires an view array dimension", "perviewNV", ""); - } - else if (!type.isUnsizedArray() && type.getOuterArraySize() != maxViewCount) { + if ((isBlockMember && type.isArray()) || (!isBlockMember && type.isArrayOfArrays())) { + // since we don't have the maxMeshViewCountNV set during parsing builtins, we hardcode the value. + int maxViewCount = parsingBuiltins ? 4 : resources.maxMeshViewCountNV; + // For block members, outermost array dimension is the view dimension. + // For non-block members, outermost array dimension is the vertex/primitive dimension + // and 2nd outermost is the view dimension. + int viewDim = isBlockMember ? 0 : 1; + int viewDimSize = type.getArraySizes()->getDimSize(viewDim); + + if (viewDimSize != UnsizedArraySize && viewDimSize != maxViewCount) error(loc, "mesh view output array size must be gl_MaxMeshViewCountNV or implicitly sized", "[]", ""); - } - else if (type.isUnsizedArray()) { - type.changeOuterArraySize(maxViewCount); - } + else if (viewDimSize == UnsizedArraySize) + type.getArraySizes()->setDimSize(viewDim, maxViewCount); + } + else { + error(loc, "requires a view array dimension", "perviewNV", ""); } } #endif @@ -6427,6 +6434,7 @@ TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& iden transparentOpaqueCheck(loc, type, identifier); #ifdef NV_EXTENSIONS accStructNVCheck(loc, type, identifier); + checkAndResizeMeshViewDim(loc, type, /*isBlockMember*/ false); #endif if (type.getQualifier().storage == EvqConst && type.containsBasicType(EbtReference)) { error(loc, "variables with reference type can't have qualifier 'const'", "qualifier", ""); @@ -7342,7 +7350,7 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con #ifdef NV_EXTENSIONS if (memberWithPerViewQualifier) { for (unsigned int member = 0; member < typeList.size(); ++member) { - resizeMeshViewDimension(typeList[member].loc, *typeList[member].type); + checkAndResizeMeshViewDim(typeList[member].loc, *typeList[member].type, /*isBlockMember*/ true); } } #endif diff --git a/glslang/MachineIndependent/ParseHelper.h b/glslang/MachineIndependent/ParseHelper.h index 04ede1e3..3619437c 100644 --- a/glslang/MachineIndependent/ParseHelper.h +++ b/glslang/MachineIndependent/ParseHelper.h @@ -429,7 +429,7 @@ public: // Determine loop control from attributes void handleLoopAttributes(const TAttributes& attributes, TIntermNode*); - void resizeMeshViewDimension(const TSourceLoc&, TType&); + void checkAndResizeMeshViewDim(const TSourceLoc&, TType&, bool isBlockMember); protected: void nonInitConstCheck(const TSourceLoc&, TString& identifier, TType& type); diff --git a/gtests/Spv.FromFile.cpp b/gtests/Spv.FromFile.cpp index 167adaa0..e630f56f 100644 --- a/gtests/Spv.FromFile.cpp +++ b/gtests/Spv.FromFile.cpp @@ -625,6 +625,7 @@ INSTANTIATE_TEST_CASE_P( "spv.meshShaderUserDefined.mesh", "spv.meshShaderPerViewBuiltins.mesh", "spv.meshShaderPerViewUserDefined.mesh", + "spv.meshShaderPerView_Errors.mesh", "spv.meshShaderSharedMem.mesh", "spv.meshShaderTaskMem.mesh", "spv.320.meshShaderUserDefined.mesh",