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
This commit is contained in:
parent
816bc4447c
commit
38772c0434
@ -7202,15 +7202,29 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
|
|||||||
void TGlslangToSpvTraverser::addMeshNVDecoration(spv::Id id, int member, const glslang::TQualifier& qualifier)
|
void TGlslangToSpvTraverser::addMeshNVDecoration(spv::Id id, int member, const glslang::TQualifier& qualifier)
|
||||||
{
|
{
|
||||||
if (member >= 0) {
|
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);
|
builder.addMemberDecoration(id, (unsigned)member, spv::DecorationPerPrimitiveNV);
|
||||||
|
}
|
||||||
if (qualifier.perViewNV)
|
if (qualifier.perViewNV)
|
||||||
builder.addMemberDecoration(id, (unsigned)member, spv::DecorationPerViewNV);
|
builder.addMemberDecoration(id, (unsigned)member, spv::DecorationPerViewNV);
|
||||||
if (qualifier.perTaskNV)
|
if (qualifier.perTaskNV)
|
||||||
builder.addMemberDecoration(id, (unsigned)member, spv::DecorationPerTaskNV);
|
builder.addMemberDecoration(id, (unsigned)member, spv::DecorationPerTaskNV);
|
||||||
} else {
|
} 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);
|
builder.addDecoration(id, spv::DecorationPerPrimitiveNV);
|
||||||
|
}
|
||||||
if (qualifier.perViewNV)
|
if (qualifier.perViewNV)
|
||||||
builder.addDecoration(id, spv::DecorationPerViewNV);
|
builder.addDecoration(id, spv::DecorationPerViewNV);
|
||||||
if (qualifier.perTaskNV)
|
if (qualifier.perTaskNV)
|
||||||
|
54
Test/baseResults/spv.perprimitiveNV.frag.out
Normal file
54
Test/baseResults/spv.perprimitiveNV.frag.out
Normal file
@ -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
|
21
Test/spv.perprimitiveNV.frag
Normal file
21
Test/spv.perprimitiveNV.frag
Normal file
@ -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;
|
||||||
|
}
|
@ -4514,6 +4514,8 @@ void TParseContext::finish()
|
|||||||
break;
|
break;
|
||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
case EShLangTaskNV:
|
case EShLangTaskNV:
|
||||||
|
requireExtensions(getCurrentLoc(), 1, &E_GL_NV_mesh_shader, "task shaders");
|
||||||
|
break;
|
||||||
case EShLangMeshNV:
|
case EShLangMeshNV:
|
||||||
requireExtensions(getCurrentLoc(), 1, &E_GL_NV_mesh_shader, "mesh shaders");
|
requireExtensions(getCurrentLoc(), 1, &E_GL_NV_mesh_shader, "mesh shaders");
|
||||||
break;
|
break;
|
||||||
|
@ -842,9 +842,12 @@ void TParseVersions::checkExtensionStage(const TSourceLoc& loc, const char * con
|
|||||||
{
|
{
|
||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
// GL_NV_mesh_shader extension is only allowed in task/mesh shaders
|
// GL_NV_mesh_shader extension is only allowed in task/mesh shaders
|
||||||
if (strcmp(extension, "GL_NV_mesh_shader") == 0)
|
if (strcmp(extension, "GL_NV_mesh_shader") == 0) {
|
||||||
requireStage(loc, (EShLanguageMask)(EShLangTaskNVMask | EShLangMeshNVMask),
|
requireStage(loc, (EShLanguageMask)(EShLangTaskNVMask | EShLangMeshNVMask | EShLangFragmentMask),
|
||||||
"#extension GL_NV_mesh_shader");
|
"#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
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1157,30 +1157,30 @@ interpolation_qualifier
|
|||||||
}
|
}
|
||||||
| PERPRIMITIVENV {
|
| PERPRIMITIVENV {
|
||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
|
// No need for profile version or extension check. Shader stage already checks both.
|
||||||
parseContext.globalCheck($1.loc, "perprimitiveNV");
|
parseContext.globalCheck($1.loc, "perprimitiveNV");
|
||||||
parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangFragmentMask | EShLangMeshNVMask), "perprimitiveNV");
|
parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangFragmentMask | EShLangMeshNVMask), "perprimitiveNV");
|
||||||
parseContext.profileRequires($1.loc, ECoreProfile, 450, E_GL_NV_mesh_shader, "perprimitiveNV");
|
// Fragment shader stage doesn't check for extension. So we explicitly add below extension check.
|
||||||
parseContext.profileRequires($1.loc, EEsProfile, 320, E_GL_NV_mesh_shader, "perprimitiveNV");
|
if (parseContext.language == EShLangFragment)
|
||||||
|
parseContext.requireExtensions($1.loc, 1, &E_GL_NV_mesh_shader, "perprimitiveNV");
|
||||||
$$.init($1.loc);
|
$$.init($1.loc);
|
||||||
$$.qualifier.perPrimitiveNV = true;
|
$$.qualifier.perPrimitiveNV = true;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
| PERVIEWNV {
|
| PERVIEWNV {
|
||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
|
// No need for profile version or extension check. Shader stage already checks both.
|
||||||
parseContext.globalCheck($1.loc, "perviewNV");
|
parseContext.globalCheck($1.loc, "perviewNV");
|
||||||
parseContext.requireStage($1.loc, EShLangMeshNV, "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);
|
$$.init($1.loc);
|
||||||
$$.qualifier.perViewNV = true;
|
$$.qualifier.perViewNV = true;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
| PERTASKNV {
|
| PERTASKNV {
|
||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
|
// No need for profile version or extension check. Shader stage already checks both.
|
||||||
parseContext.globalCheck($1.loc, "taskNV");
|
parseContext.globalCheck($1.loc, "taskNV");
|
||||||
parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangTaskNVMask | EShLangMeshNVMask), "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);
|
$$.init($1.loc);
|
||||||
$$.qualifier.perTaskNV = true;
|
$$.qualifier.perTaskNV = true;
|
||||||
#endif
|
#endif
|
||||||
|
@ -948,7 +948,7 @@ static const yytype_uint16 yyrline[] =
|
|||||||
820, 825, 834, 834, 845, 849, 856, 863, 866, 873,
|
820, 825, 834, 834, 845, 849, 856, 863, 866, 873,
|
||||||
881, 901, 924, 939, 964, 975, 985, 995, 1005, 1014,
|
881, 901, 924, 939, 964, 975, 985, 995, 1005, 1014,
|
||||||
1017, 1021, 1025, 1030, 1038, 1043, 1048, 1053, 1058, 1067,
|
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,
|
1191, 1197, 1200, 1207, 1211, 1215, 1223, 1232, 1235, 1246,
|
||||||
1249, 1252, 1256, 1260, 1264, 1268, 1274, 1278, 1290, 1304,
|
1249, 1252, 1256, 1260, 1264, 1268, 1274, 1278, 1290, 1304,
|
||||||
1309, 1315, 1321, 1328, 1334, 1339, 1344, 1349, 1359, 1369,
|
1309, 1315, 1321, 1328, 1334, 1339, 1344, 1349, 1359, 1369,
|
||||||
@ -5515,40 +5515,40 @@ yyreduce:
|
|||||||
#line 1158 "MachineIndependent/glslang.y" /* yacc.c:1646 */
|
#line 1158 "MachineIndependent/glslang.y" /* yacc.c:1646 */
|
||||||
{
|
{
|
||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
|
// No need for profile version or extension check. Shader stage already checks both.
|
||||||
parseContext.globalCheck((yyvsp[0].lex).loc, "perprimitiveNV");
|
parseContext.globalCheck((yyvsp[0].lex).loc, "perprimitiveNV");
|
||||||
parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangFragmentMask | EShLangMeshNVMask), "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");
|
// Fragment shader stage doesn't check for extension. So we explicitly add below extension check.
|
||||||
parseContext.profileRequires((yyvsp[0].lex).loc, EEsProfile, 320, E_GL_NV_mesh_shader, "perprimitiveNV");
|
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).init((yyvsp[0].lex).loc);
|
||||||
(yyval.interm.type).qualifier.perPrimitiveNV = true;
|
(yyval.interm.type).qualifier.perPrimitiveNV = true;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#line 5527 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */
|
#line 5529 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 138:
|
case 138:
|
||||||
#line 1168 "MachineIndependent/glslang.y" /* yacc.c:1646 */
|
#line 1170 "MachineIndependent/glslang.y" /* yacc.c:1646 */
|
||||||
{
|
{
|
||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
|
// No need for profile version or extension check. Shader stage already checks both.
|
||||||
parseContext.globalCheck((yyvsp[0].lex).loc, "perviewNV");
|
parseContext.globalCheck((yyvsp[0].lex).loc, "perviewNV");
|
||||||
parseContext.requireStage((yyvsp[0].lex).loc, EShLangMeshNV, "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).init((yyvsp[0].lex).loc);
|
||||||
(yyval.interm.type).qualifier.perViewNV = true;
|
(yyval.interm.type).qualifier.perViewNV = true;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#line 5542 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */
|
#line 5543 "MachineIndependent/glslang_tab.cpp" /* yacc.c:1646 */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 139:
|
case 139:
|
||||||
#line 1178 "MachineIndependent/glslang.y" /* yacc.c:1646 */
|
#line 1179 "MachineIndependent/glslang.y" /* yacc.c:1646 */
|
||||||
{
|
{
|
||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
|
// No need for profile version or extension check. Shader stage already checks both.
|
||||||
parseContext.globalCheck((yyvsp[0].lex).loc, "taskNV");
|
parseContext.globalCheck((yyvsp[0].lex).loc, "taskNV");
|
||||||
parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangTaskNVMask | EShLangMeshNVMask), "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).init((yyvsp[0].lex).loc);
|
||||||
(yyval.interm.type).qualifier.perTaskNV = true;
|
(yyval.interm.type).qualifier.perTaskNV = true;
|
||||||
#endif
|
#endif
|
||||||
|
@ -528,6 +528,7 @@ INSTANTIATE_TEST_CASE_P(
|
|||||||
"spv.meshShaderRedeclBuiltins.mesh",
|
"spv.meshShaderRedeclBuiltins.mesh",
|
||||||
"spv.meshShaderRedeclPerViewBuiltins.mesh",
|
"spv.meshShaderRedeclPerViewBuiltins.mesh",
|
||||||
"spv.meshTaskShader.task",
|
"spv.meshTaskShader.task",
|
||||||
|
"spv.perprimitiveNV.frag",
|
||||||
})),
|
})),
|
||||||
FileNameAsCustomTestSuffix
|
FileNameAsCustomTestSuffix
|
||||||
);
|
);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user