From: Sahil Parmar Date: Fri, 26 Oct 2018 06:50:59 +0000 (-0700) Subject: Allow GL_NV_mesh_shader in fragment shaders for perprimitiveNV X-Git-Tag: upstream/11.4.0~631^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=38772c04349c24e4c4e8eb05ed87ceff38aa211a;p=platform%2Fupstream%2Fglslang.git Allow GL_NV_mesh_shader in fragment shaders for perprimitiveNV - Emit relevant capability/extension for use of perprimitiveNV in fragment shader - Remove redundant checks for mesh shader qualifiers in glslang.y - Add profile version check for use of extension GL_NV_mesh_shader - Add a new gtest for use of perprimitiveNV in fragment shader --- diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp index c222ccb..e1ae7b4 100644 --- a/SPIRV/GlslangToSpv.cpp +++ b/SPIRV/GlslangToSpv.cpp @@ -7202,15 +7202,29 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol void TGlslangToSpvTraverser::addMeshNVDecoration(spv::Id id, int member, const glslang::TQualifier& qualifier) { if (member >= 0) { - if (qualifier.perPrimitiveNV) + if (qualifier.perPrimitiveNV) { + // Need to add capability/extension for fragment shader. + // Mesh shader already adds this by default. + if (glslangIntermediate->getStage() == EShLangFragment) { + builder.addCapability(spv::CapabilityMeshShadingNV); + builder.addExtension(spv::E_SPV_NV_mesh_shader); + } builder.addMemberDecoration(id, (unsigned)member, spv::DecorationPerPrimitiveNV); + } if (qualifier.perViewNV) builder.addMemberDecoration(id, (unsigned)member, spv::DecorationPerViewNV); if (qualifier.perTaskNV) builder.addMemberDecoration(id, (unsigned)member, spv::DecorationPerTaskNV); } else { - if (qualifier.perPrimitiveNV) + if (qualifier.perPrimitiveNV) { + // Need to add capability/extension for fragment shader. + // Mesh shader already adds this by default. + if (glslangIntermediate->getStage() == EShLangFragment) { + builder.addCapability(spv::CapabilityMeshShadingNV); + builder.addExtension(spv::E_SPV_NV_mesh_shader); + } builder.addDecoration(id, spv::DecorationPerPrimitiveNV); + } if (qualifier.perViewNV) builder.addDecoration(id, spv::DecorationPerViewNV); if (qualifier.perTaskNV) diff --git a/Test/baseResults/spv.perprimitiveNV.frag.out b/Test/baseResults/spv.perprimitiveNV.frag.out new file mode 100644 index 0000000..eaff400 --- /dev/null +++ b/Test/baseResults/spv.perprimitiveNV.frag.out @@ -0,0 +1,54 @@ +spv.perprimitiveNV.frag +// Module Version 10000 +// Generated by (magic number): 80007 +// Id's are bound by 23 + + Capability Shader + Capability MeshShadingNV + Extension "SPV_NV_mesh_shader" + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint Fragment 4 "main" 8 11 19 + ExecutionMode 4 OriginUpperLeft + Source GLSL 460 + SourceExtension "GL_NV_mesh_shader" + Name 4 "main" + Name 8 "g" + Name 9 "B" + MemberName 9(B) 0 "f" + Name 11 "" + Name 17 "C" + MemberName 17(C) 0 "h" + Name 19 "" + Decorate 8(g) Location 8 + MemberDecorate 9(B) 0 PerPrimitiveNV + Decorate 9(B) Block + Decorate 11 Location 0 + MemberDecorate 17(C) 0 Flat + MemberDecorate 17(C) 0 Centroid + Decorate 17(C) Block + Decorate 19 Location 4 + 2: TypeVoid + 3: TypeFunction 2 + 6: TypeFloat 32 + 7: TypePointer Output 6(float) + 8(g): 7(ptr) Variable Output + 9(B): TypeStruct 6(float) + 10: TypePointer Input 9(B) + 11: 10(ptr) Variable Input + 12: TypeInt 32 1 + 13: 12(int) Constant 0 + 14: TypePointer Input 6(float) + 17(C): TypeStruct 6(float) + 18: TypePointer Input 17(C) + 19: 18(ptr) Variable Input + 4(main): 2 Function None 3 + 5: Label + 15: 14(ptr) AccessChain 11 13 + 16: 6(float) Load 15 + 20: 14(ptr) AccessChain 19 13 + 21: 6(float) Load 20 + 22: 6(float) FAdd 16 21 + Store 8(g) 22 + Return + FunctionEnd diff --git a/Test/spv.perprimitiveNV.frag b/Test/spv.perprimitiveNV.frag new file mode 100644 index 0000000..56e00f5 --- /dev/null +++ b/Test/spv.perprimitiveNV.frag @@ -0,0 +1,21 @@ +#version 460 + +#extension GL_NV_mesh_shader: require + +layout(location=0) +in B { + perprimitiveNV float f; +}; + +layout(location=4) +in C { + flat centroid float h; +}; + +layout(location=8) +out float g; + +void main() +{ + g = f + h; +} diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index 4c2d69f..bb0fe93 100755 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -4514,6 +4514,8 @@ void TParseContext::finish() break; #ifdef NV_EXTENSIONS case EShLangTaskNV: + requireExtensions(getCurrentLoc(), 1, &E_GL_NV_mesh_shader, "task shaders"); + break; case EShLangMeshNV: requireExtensions(getCurrentLoc(), 1, &E_GL_NV_mesh_shader, "mesh shaders"); break; diff --git a/glslang/MachineIndependent/Versions.cpp b/glslang/MachineIndependent/Versions.cpp index 9ca20a5..b26bc3e 100644 --- a/glslang/MachineIndependent/Versions.cpp +++ b/glslang/MachineIndependent/Versions.cpp @@ -842,9 +842,12 @@ void TParseVersions::checkExtensionStage(const TSourceLoc& loc, const char * con { #ifdef NV_EXTENSIONS // GL_NV_mesh_shader extension is only allowed in task/mesh shaders - if (strcmp(extension, "GL_NV_mesh_shader") == 0) - requireStage(loc, (EShLanguageMask)(EShLangTaskNVMask | EShLangMeshNVMask), + if (strcmp(extension, "GL_NV_mesh_shader") == 0) { + requireStage(loc, (EShLanguageMask)(EShLangTaskNVMask | EShLangMeshNVMask | EShLangFragmentMask), "#extension GL_NV_mesh_shader"); + profileRequires(loc, ECoreProfile, 450, 0, "#extension GL_NV_mesh_shader"); + profileRequires(loc, EEsProfile, 320, 0, "#extension GL_NV_mesh_shader"); + } #endif } diff --git a/glslang/MachineIndependent/glslang.y b/glslang/MachineIndependent/glslang.y index cd4256d..f6e33c6 100644 --- a/glslang/MachineIndependent/glslang.y +++ b/glslang/MachineIndependent/glslang.y @@ -1157,30 +1157,30 @@ interpolation_qualifier } | PERPRIMITIVENV { #ifdef NV_EXTENSIONS + // No need for profile version or extension check. Shader stage already checks both. parseContext.globalCheck($1.loc, "perprimitiveNV"); parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangFragmentMask | EShLangMeshNVMask), "perprimitiveNV"); - parseContext.profileRequires($1.loc, ECoreProfile, 450, E_GL_NV_mesh_shader, "perprimitiveNV"); - parseContext.profileRequires($1.loc, EEsProfile, 320, E_GL_NV_mesh_shader, "perprimitiveNV"); + // Fragment shader stage doesn't check for extension. So we explicitly add below extension check. + if (parseContext.language == EShLangFragment) + parseContext.requireExtensions($1.loc, 1, &E_GL_NV_mesh_shader, "perprimitiveNV"); $$.init($1.loc); $$.qualifier.perPrimitiveNV = true; #endif } | PERVIEWNV { #ifdef NV_EXTENSIONS + // No need for profile version or extension check. Shader stage already checks both. parseContext.globalCheck($1.loc, "perviewNV"); parseContext.requireStage($1.loc, EShLangMeshNV, "perviewNV"); - parseContext.profileRequires($1.loc, ECoreProfile, 450, E_GL_NV_mesh_shader, "perviewNV"); - parseContext.profileRequires($1.loc, EEsProfile, 320, E_GL_NV_mesh_shader, "perviewNV"); $$.init($1.loc); $$.qualifier.perViewNV = true; #endif } | PERTASKNV { #ifdef NV_EXTENSIONS + // No need for profile version or extension check. Shader stage already checks both. parseContext.globalCheck($1.loc, "taskNV"); parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangTaskNVMask | EShLangMeshNVMask), "taskNV"); - parseContext.profileRequires($1.loc, ECoreProfile, 450, E_GL_NV_mesh_shader, "taskNV"); - parseContext.profileRequires($1.loc, EEsProfile, 320, E_GL_NV_mesh_shader, "taskNV"); $$.init($1.loc); $$.qualifier.perTaskNV = true; #endif diff --git a/glslang/MachineIndependent/glslang_tab.cpp b/glslang/MachineIndependent/glslang_tab.cpp index 9b9df51..4b70ee3 100644 --- a/glslang/MachineIndependent/glslang_tab.cpp +++ b/glslang/MachineIndependent/glslang_tab.cpp @@ -948,7 +948,7 @@ static const yytype_uint16 yyrline[] = 820, 825, 834, 834, 845, 849, 856, 863, 866, 873, 881, 901, 924, 939, 964, 975, 985, 995, 1005, 1014, 1017, 1021, 1025, 1030, 1038, 1043, 1048, 1053, 1058, 1067, - 1078, 1105, 1114, 1121, 1128, 1139, 1148, 1158, 1168, 1178, + 1078, 1105, 1114, 1121, 1128, 1139, 1148, 1158, 1170, 1179, 1191, 1197, 1200, 1207, 1211, 1215, 1223, 1232, 1235, 1246, 1249, 1252, 1256, 1260, 1264, 1268, 1274, 1278, 1290, 1304, 1309, 1315, 1321, 1328, 1334, 1339, 1344, 1349, 1359, 1369, @@ -5515,40 +5515,40 @@ yyreduce: #line 1158 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { #ifdef NV_EXTENSIONS + // No need for profile version or extension check. Shader stage already checks both. parseContext.globalCheck((yyvsp[0].lex).loc, "perprimitiveNV"); parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangFragmentMask | EShLangMeshNVMask), "perprimitiveNV"); - parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile, 450, E_GL_NV_mesh_shader, "perprimitiveNV"); - parseContext.profileRequires((yyvsp[0].lex).loc, EEsProfile, 320, E_GL_NV_mesh_shader, "perprimitiveNV"); + // Fragment shader stage doesn't check for extension. So we explicitly add below extension check. + if (parseContext.language == EShLangFragment) + parseContext.requireExtensions((yyvsp[0].lex).loc, 1, &E_GL_NV_mesh_shader, "perprimitiveNV"); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.perPrimitiveNV = true; #endif } -#line 5527 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5529 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 138: -#line 1168 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 1170 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { #ifdef NV_EXTENSIONS + // No need for profile version or extension check. Shader stage already checks both. parseContext.globalCheck((yyvsp[0].lex).loc, "perviewNV"); parseContext.requireStage((yyvsp[0].lex).loc, EShLangMeshNV, "perviewNV"); - parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile, 450, E_GL_NV_mesh_shader, "perviewNV"); - parseContext.profileRequires((yyvsp[0].lex).loc, EEsProfile, 320, E_GL_NV_mesh_shader, "perviewNV"); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.perViewNV = true; #endif } -#line 5542 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ +#line 5543 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */ break; case 139: -#line 1178 "MachineIndependent/glslang.y" /* yacc.c:1646 */ +#line 1179 "MachineIndependent/glslang.y" /* yacc.c:1646 */ { #ifdef NV_EXTENSIONS + // No need for profile version or extension check. Shader stage already checks both. parseContext.globalCheck((yyvsp[0].lex).loc, "taskNV"); parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangTaskNVMask | EShLangMeshNVMask), "taskNV"); - parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile, 450, E_GL_NV_mesh_shader, "taskNV"); - parseContext.profileRequires((yyvsp[0].lex).loc, EEsProfile, 320, E_GL_NV_mesh_shader, "taskNV"); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.perTaskNV = true; #endif diff --git a/gtests/Spv.FromFile.cpp b/gtests/Spv.FromFile.cpp index 8158391..ece5e69 100644 --- a/gtests/Spv.FromFile.cpp +++ b/gtests/Spv.FromFile.cpp @@ -528,6 +528,7 @@ INSTANTIATE_TEST_CASE_P( "spv.meshShaderRedeclBuiltins.mesh", "spv.meshShaderRedeclPerViewBuiltins.mesh", "spv.meshTaskShader.task", + "spv.perprimitiveNV.frag", })), FileNameAsCustomTestSuffix );