Merge pull request #1507 from sparmarNV/fix-SPV_NV_mesh_shader
Add ES 320 support and additional error checks for SPV_NV_mesh_shader
This commit is contained in:
commit
4508a8170a
10 changed files with 1416 additions and 1097 deletions
|
|
@ -4878,7 +4878,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
|||
"void barrier();"
|
||||
);
|
||||
#ifdef NV_EXTENSIONS
|
||||
if ((profile != EEsProfile && version >= 450) || esBarrier) {
|
||||
if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 320)) {
|
||||
stageBuiltins[EShLangMeshNV].append(
|
||||
"void barrier();"
|
||||
);
|
||||
|
|
@ -4903,7 +4903,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
|||
);
|
||||
}
|
||||
#ifdef NV_EXTENSIONS
|
||||
if (profile != EEsProfile && version >= 450) {
|
||||
if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 320)) {
|
||||
stageBuiltins[EShLangMeshNV].append(
|
||||
"void memoryBarrierShared();"
|
||||
"void groupMemoryBarrier();"
|
||||
|
|
@ -5094,7 +5094,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
|||
}
|
||||
|
||||
// Builtins for GL_NV_mesh_shader
|
||||
if (profile != EEsProfile && version >= 450) {
|
||||
if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 320)) {
|
||||
stageBuiltins[EShLangMeshNV].append(
|
||||
"void writePackedPrimitiveIndices4x8NV(uint, uint);"
|
||||
"\n");
|
||||
|
|
@ -5287,7 +5287,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
|||
//
|
||||
//============================================================================
|
||||
|
||||
if (profile != EEsProfile && version >= 450) {
|
||||
if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 320)) {
|
||||
// per-vertex attributes
|
||||
stageBuiltins[EShLangMeshNV].append(
|
||||
"out gl_MeshPerVertexNV {"
|
||||
|
|
@ -5328,17 +5328,8 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
|||
"in highp uvec3 gl_GlobalInvocationID;"
|
||||
"in highp uint gl_LocalInvocationIndex;"
|
||||
|
||||
"in highp int gl_DeviceIndex;" // GL_EXT_device_group
|
||||
"in int gl_DrawIDARB;" // GL_ARB_shader_draw_parameters
|
||||
|
||||
"\n");
|
||||
|
||||
if (version >= 460) {
|
||||
stageBuiltins[EShLangMeshNV].append(
|
||||
"in int gl_DrawID;"
|
||||
);
|
||||
}
|
||||
|
||||
stageBuiltins[EShLangTaskNV].append(
|
||||
"out uint gl_TaskCountNV;"
|
||||
|
||||
|
|
@ -5350,15 +5341,28 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
|||
"in highp uvec3 gl_GlobalInvocationID;"
|
||||
"in highp uint gl_LocalInvocationIndex;"
|
||||
|
||||
"\n");
|
||||
}
|
||||
|
||||
if (profile != EEsProfile && version >= 450) {
|
||||
stageBuiltins[EShLangMeshNV].append(
|
||||
"in highp int gl_DeviceIndex;" // GL_EXT_device_group
|
||||
"in int gl_DrawIDARB;" // GL_ARB_shader_draw_parameters
|
||||
"\n");
|
||||
|
||||
stageBuiltins[EShLangTaskNV].append(
|
||||
"in highp int gl_DeviceIndex;" // GL_EXT_device_group
|
||||
"in int gl_DrawIDARB;" // GL_ARB_shader_draw_parameters
|
||||
"\n");
|
||||
|
||||
if (version >= 460) {
|
||||
stageBuiltins[EShLangMeshNV].append(
|
||||
"in int gl_DrawID;"
|
||||
"\n");
|
||||
|
||||
stageBuiltins[EShLangTaskNV].append(
|
||||
"in int gl_DrawID;"
|
||||
);
|
||||
"\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -7658,7 +7662,7 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf
|
|||
|
||||
#ifdef NV_EXTENSIONS
|
||||
// SPV_NV_mesh_shader
|
||||
if (profile != EEsProfile && version >= 450) {
|
||||
if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 320)) {
|
||||
snprintf(builtInConstant, maxSize, "const int gl_MaxMeshOutputVerticesNV = %d;", resources.maxMeshOutputVerticesNV);
|
||||
s.append(builtInConstant);
|
||||
|
||||
|
|
@ -8633,7 +8637,7 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
|
|||
}
|
||||
break;
|
||||
case EShLangMeshNV:
|
||||
if (profile != EEsProfile && version >= 450) {
|
||||
if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 320)) {
|
||||
// Per-vertex builtins
|
||||
BuiltInVariable("gl_MeshVerticesNV", "gl_Position", EbvPosition, symbolTable);
|
||||
BuiltInVariable("gl_MeshVerticesNV", "gl_PointSize", EbvPointSize, symbolTable);
|
||||
|
|
@ -8681,7 +8685,9 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
|
|||
symbolTable.setFunctionExtensions("barrier", 1, &E_GL_NV_mesh_shader);
|
||||
symbolTable.setFunctionExtensions("memoryBarrierShared", 1, &E_GL_NV_mesh_shader);
|
||||
symbolTable.setFunctionExtensions("groupMemoryBarrier", 1, &E_GL_NV_mesh_shader);
|
||||
}
|
||||
|
||||
if (profile != EEsProfile && version >= 450) {
|
||||
// GL_EXT_device_group
|
||||
symbolTable.setVariableExtensions("gl_DeviceIndex", 1, &E_GL_EXT_device_group);
|
||||
BuiltInVariable("gl_DeviceIndex", EbvDeviceIndex, symbolTable);
|
||||
|
|
@ -8743,7 +8749,7 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
|
|||
break;
|
||||
|
||||
case EShLangTaskNV:
|
||||
if (profile != EEsProfile && version >= 450) {
|
||||
if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 320)) {
|
||||
symbolTable.setVariableExtensions("gl_TaskCountNV", 1, &E_GL_NV_mesh_shader);
|
||||
symbolTable.setVariableExtensions("gl_WorkGroupSize", 1, &E_GL_NV_mesh_shader);
|
||||
symbolTable.setVariableExtensions("gl_WorkGroupID", 1, &E_GL_NV_mesh_shader);
|
||||
|
|
@ -8763,7 +8769,9 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
|
|||
symbolTable.setFunctionExtensions("barrier", 1, &E_GL_NV_mesh_shader);
|
||||
symbolTable.setFunctionExtensions("memoryBarrierShared", 1, &E_GL_NV_mesh_shader);
|
||||
symbolTable.setFunctionExtensions("groupMemoryBarrier", 1, &E_GL_NV_mesh_shader);
|
||||
}
|
||||
|
||||
if (profile != EEsProfile && version >= 450) {
|
||||
// GL_EXT_device_group
|
||||
symbolTable.setVariableExtensions("gl_DeviceIndex", 1, &E_GL_EXT_device_group);
|
||||
BuiltInVariable("gl_DeviceIndex", EbvDeviceIndex, symbolTable);
|
||||
|
|
@ -9379,12 +9387,12 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
|
|||
}
|
||||
break;
|
||||
case EShLangMeshNV:
|
||||
if (profile != EEsProfile && version >= 450) {
|
||||
if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 320)) {
|
||||
symbolTable.relateToOperator("writePackedPrimitiveIndices4x8NV", EOpWritePackedPrimitiveIndices4x8NV);
|
||||
}
|
||||
// fall through
|
||||
case EShLangTaskNV:
|
||||
if (profile != EEsProfile && version >= 450) {
|
||||
if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 320)) {
|
||||
symbolTable.relateToOperator("memoryBarrierShared", EOpMemoryBarrierShared);
|
||||
symbolTable.relateToOperator("groupMemoryBarrier", EOpGroupMemoryBarrier);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -612,7 +612,7 @@ int TParseContext::getIoArrayImplicitSize(bool isPerPrimitive) const
|
|||
return 3; //Number of vertices for Fragment shader is always three.
|
||||
else if (language == EShLangMeshNV) {
|
||||
if (isPerPrimitive) {
|
||||
return intermediate.getPrimitives() != TQualifier::layoutNotSet ? intermediate.getPrimitives() : 0;
|
||||
return intermediate.getPrimitives() != TQualifier::layoutNotSet ? intermediate.getPrimitives() : 0;
|
||||
} else {
|
||||
return intermediate.getVertices() != TQualifier::layoutNotSet ? intermediate.getVertices() : 0;
|
||||
}
|
||||
|
|
@ -3602,6 +3602,14 @@ void TParseContext::arraySizesCheck(const TSourceLoc& loc, const TQualifier& qua
|
|||
extensionsTurnedOn(Num_AEP_tessellation_shader, AEP_tessellation_shader))
|
||||
return;
|
||||
break;
|
||||
#ifdef NV_EXTENSIONS
|
||||
case EShLangMeshNV:
|
||||
if (qualifier.storage == EvqVaryingOut)
|
||||
if ((profile == EEsProfile && version >= 320) ||
|
||||
extensionTurnedOn(E_GL_NV_mesh_shader))
|
||||
return;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -4462,6 +4470,12 @@ void TParseContext::finish()
|
|||
if (profile != EEsProfile && version < 430)
|
||||
requireExtensions(getCurrentLoc(), 1, &E_GL_ARB_compute_shader, "compute shaders");
|
||||
break;
|
||||
#ifdef NV_EXTENSIONS
|
||||
case EShLangTaskNV:
|
||||
case EShLangMeshNV:
|
||||
requireExtensions(getCurrentLoc(), 1, &E_GL_NV_mesh_shader, "mesh shaders");
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -4965,12 +4979,14 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
|
|||
#ifdef NV_EXTENSIONS
|
||||
case EShLangMeshNV:
|
||||
if (id == "max_vertices") {
|
||||
requireExtensions(loc, 1, &E_GL_NV_mesh_shader, "max_vertices");
|
||||
publicType.shaderQualifiers.vertices = value;
|
||||
if (value > resources.maxMeshOutputVerticesNV)
|
||||
error(loc, "too large, must be less than gl_MaxMeshOutputVerticesNV", "max_vertices", "");
|
||||
return;
|
||||
}
|
||||
if (id == "max_primitives") {
|
||||
requireExtensions(loc, 1, &E_GL_NV_mesh_shader, "max_primitives");
|
||||
publicType.shaderQualifiers.primitives = value;
|
||||
if (value > resources.maxMeshOutputPrimitivesNV)
|
||||
error(loc, "too large, must be less than gl_MaxMeshOutputPrimitivesNV", "max_primitives", "");
|
||||
|
|
@ -4985,7 +5001,7 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
|
|||
if (id.compare(0, 11, "local_size_") == 0) {
|
||||
#ifdef NV_EXTENSIONS
|
||||
if (language == EShLangMeshNV || language == EShLangTaskNV) {
|
||||
profileRequires(loc, ~EEsProfile, 450, E_GL_NV_mesh_shader, "gl_WorkGroupSize");
|
||||
requireExtensions(loc, 1, &E_GL_NV_mesh_shader, "gl_WorkGroupSize");
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1591,8 +1591,9 @@ int TScanContext::tokenizeIdentifier()
|
|||
case PERPRIMITIVENV:
|
||||
case PERVIEWNV:
|
||||
case PERTASKNV:
|
||||
if (parseContext.profile != EEsProfile &&
|
||||
(parseContext.version >= 450 || parseContext.extensionTurnedOn(E_GL_NV_mesh_shader)))
|
||||
if ((parseContext.profile != EEsProfile && parseContext.version >= 450) ||
|
||||
(parseContext.profile == EEsProfile && parseContext.version >= 320) ||
|
||||
parseContext.extensionTurnedOn(E_GL_NV_mesh_shader))
|
||||
return keyword;
|
||||
return identifierOrType();
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -361,13 +361,16 @@ bool InitializeSymbolTables(TInfoSink& infoSink, TSymbolTable** commonTable, TS
|
|||
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangMissNV, source,
|
||||
infoSink, commonTable, symbolTables);
|
||||
}
|
||||
|
||||
// check for mesh
|
||||
if (profile != EEsProfile && version >= 450)
|
||||
if ((profile != EEsProfile && version >= 450) ||
|
||||
(profile == EEsProfile && version >= 320))
|
||||
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangMeshNV, source,
|
||||
infoSink, commonTable, symbolTables);
|
||||
|
||||
// check for task
|
||||
if (profile != EEsProfile && version >= 450)
|
||||
if ((profile != EEsProfile && version >= 450) ||
|
||||
(profile == EEsProfile && version >= 320))
|
||||
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangTaskNV, source,
|
||||
infoSink, commonTable, symbolTables);
|
||||
#endif
|
||||
|
|
@ -610,11 +613,11 @@ bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNo
|
|||
break;
|
||||
case EShLangMeshNV:
|
||||
case EShLangTaskNV:
|
||||
if ((profile == EEsProfile) ||
|
||||
if ((profile == EEsProfile && version < 320) ||
|
||||
(profile != EEsProfile && version < 450)) {
|
||||
correct = false;
|
||||
infoSink.info.message(EPrefixError, "#version: mesh/task shaders require non-es profile with version 450 or above");
|
||||
version = 450;
|
||||
infoSink.info.message(EPrefixError, "#version: mesh/task shaders require es profile with version 320 or above, or non-es profile with version 450 or above");
|
||||
version = profile == EEsProfile ? 320 : 450;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -742,6 +742,9 @@ void TParseVersions::updateExtensionBehavior(int line, const char* extension, co
|
|||
return;
|
||||
}
|
||||
|
||||
// check if extension is used with correct shader stage
|
||||
checkExtensionStage(getCurrentLoc(), extension);
|
||||
|
||||
// update the requested extension
|
||||
updateExtensionBehavior(extension, behavior);
|
||||
|
||||
|
|
@ -834,6 +837,17 @@ void TParseVersions::updateExtensionBehavior(const char* extension, TExtensionBe
|
|||
}
|
||||
}
|
||||
|
||||
// Check if extension is used with correct shader stage.
|
||||
void TParseVersions::checkExtensionStage(const TSourceLoc& loc, const char * const extension)
|
||||
{
|
||||
#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),
|
||||
"#extension GL_NV_mesh_shader");
|
||||
#endif
|
||||
}
|
||||
|
||||
// Call for any operation needing full GLSL integer data-type support.
|
||||
void TParseVersions::fullIntegerCheck(const TSourceLoc& loc, const char* op)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1158,7 +1158,9 @@ interpolation_qualifier
|
|||
| PERPRIMITIVENV {
|
||||
#ifdef NV_EXTENSIONS
|
||||
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");
|
||||
$$.init($1.loc);
|
||||
$$.qualifier.perPrimitiveNV = true;
|
||||
#endif
|
||||
|
|
@ -1166,7 +1168,9 @@ interpolation_qualifier
|
|||
| PERVIEWNV {
|
||||
#ifdef NV_EXTENSIONS
|
||||
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
|
||||
|
|
@ -1174,7 +1178,9 @@ interpolation_qualifier
|
|||
| PERTASKNV {
|
||||
#ifdef NV_EXTENSIONS
|
||||
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
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -103,6 +103,7 @@ public:
|
|||
virtual void requireSpv(const TSourceLoc&, const char* op);
|
||||
virtual bool checkExtensionsRequested(const TSourceLoc&, int numExtensions, const char* const extensions[], const char* featureDesc);
|
||||
virtual void updateExtensionBehavior(const char* const extension, TExtensionBehavior);
|
||||
virtual void checkExtensionStage(const TSourceLoc&, const char* const extension);
|
||||
|
||||
virtual void C_DECL error(const TSourceLoc&, const char* szReason, const char* szToken,
|
||||
const char* szExtraInfoFormat, ...) = 0;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue