GL_EXT_mesh_shader/SPV_EXT_mesh_shader implementation

Added following updates to GL_EXT_mesh_shader implementation:

1. Added SPIRV and GLSL test cases
2. Added checks to ensure NV and EXT mesh shader builtins cannot be used interchangeably.
3. Updated the language name by removing the postfix "NV" to MeshShader and TaskShader.
4. Added checks for grammar checking to comply with the spec.

5. Added gl_NumWorkGroups builtin to Mesh shader
6. Fixed data type of gl_PrimitiveLineIndicesEXT and gl_PrimitiveTriangleIndicesEXT
7. Added new constants to the resources table
8. Updates to handle new storage qualifier "taskPayloadSharedEXT"
9. Updated test cases by replacing "taskEXT" with storage qualifier "taskPayloadSharedEXT"

Addressed  Review comments
1. Fixed instruction description used by glslang disassembly.
2. Updated OpEmitMeshTasksEXT as per spec update
3. Fixed implementation that errors out if there are more then one taskPayloadSharedEXT varjables.
4. Fixed miscellaneous error logs and removed unwanted code.

SPIRV 1.6 related build failure fixes
- Update SPIRV header to 1.6
- Fix conflict wiht SPIRV 1.6 change, where localSizeId is used for execution mode for mesh/task shaders

Enable SPIRV generated for EXT_mesh_shader to be version 1.4

GL_EXT_mesh_shader: Add checks for atomic support and corresponding test cases
This commit is contained in:
Pankaj Mistry 2021-08-25 13:41:32 -07:00
parent 69ae9e7460
commit 228c67228a
52 changed files with 8937 additions and 4185 deletions

View file

@ -192,10 +192,10 @@ static EShLanguage c_shader_stage(glslang_stage_t stage)
return EShLangMiss;
case GLSLANG_STAGE_CALLABLE_NV:
return EShLangCallable;
case GLSLANG_STAGE_TASK_NV:
return EShLangTaskNV;
case GLSLANG_STAGE_MESH_NV:
return EShLangMeshNV;
case GLSLANG_STAGE_TASK:
return EShLangTask;
case GLSLANG_STAGE_MESH:
return EShLangMesh;
default:
break;
}

View file

@ -105,6 +105,8 @@ enum TStorageQualifier {
EvqCallableData,
EvqCallableDataIn,
EvqtaskPayloadSharedEXT,
// parameters
EvqIn, // also, for 'in' in the grammar before we know if it's a pipeline input or an 'in' parameter
EvqOut, // also, for 'out' in the grammar before we know if it's a pipeline output or an 'out' parameter
@ -287,6 +289,11 @@ enum TBuiltInVariable {
EbvLayerPerViewNV,
EbvMeshViewCountNV,
EbvMeshViewIndicesNV,
//GL_EXT_mesh_shader
EbvPrimitivePointIndicesEXT,
EbvPrimitiveLineIndicesEXT,
EbvPrimitiveTriangleIndicesEXT,
EbvCullPrimitiveEXT,
// sm builtins
EbvWarpsPerSM,
@ -360,6 +367,7 @@ __inline const char* GetStorageQualifierString(TStorageQualifier q)
case EvqHitAttr: return "hitAttributeNV"; break;
case EvqCallableData: return "callableDataNV"; break;
case EvqCallableDataIn: return "callableDataInNV"; break;
case EvqtaskPayloadSharedEXT: return "taskPayloadSharedEXT"; break;
default: return "unknown qualifier";
}
}
@ -496,6 +504,11 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v)
case EbvLayerPerViewNV: return "LayerPerViewNV";
case EbvMeshViewCountNV: return "MeshViewCountNV";
case EbvMeshViewIndicesNV: return "MeshViewIndicesNV";
// GL_EXT_mesh_shader
case EbvPrimitivePointIndicesEXT: return "PrimitivePointIndicesEXT";
case EbvPrimitiveLineIndicesEXT: return "PrimitiveLineIndicesEXT";
case EbvPrimitiveTriangleIndicesEXT: return "PrimitiveTriangleIndicesEXT";
case EbvCullPrimitiveEXT: return "CullPrimitiveEXT";
case EbvWarpsPerSM: return "WarpsPerSMNV";
case EbvSMCount: return "SMCountNV";

View file

@ -142,6 +142,15 @@ struct TBuiltInResource {
int maxTaskWorkGroupSizeY_NV;
int maxTaskWorkGroupSizeZ_NV;
int maxMeshViewCountNV;
int maxMeshOutputVerticesEXT;
int maxMeshOutputPrimitivesEXT;
int maxMeshWorkGroupSizeX_EXT;
int maxMeshWorkGroupSizeY_EXT;
int maxMeshWorkGroupSizeZ_EXT;
int maxTaskWorkGroupSizeX_EXT;
int maxTaskWorkGroupSizeY_EXT;
int maxTaskWorkGroupSizeZ_EXT;
int maxMeshViewCountEXT;
int maxDualSourceDrawBuffersEXT;
TLimits limits;

View file

@ -833,7 +833,7 @@ public:
}
storage = EvqUniform;
break;
case EbsStorageBuffer :
case EbsStorageBuffer :
storage = EvqBuffer;
break;
#ifndef GLSLANG_WEB
@ -856,6 +856,7 @@ public:
bool isPerPrimitive() const { return perPrimitiveNV; }
bool isPerView() const { return perViewNV; }
bool isTaskMemory() const { return perTaskNV; }
bool isTaskPayload() const { return storage == EvqtaskPayloadSharedEXT; }
bool isAnyPayload() const {
return storage == EvqPayload || storage == EvqPayloadIn;
}
@ -874,8 +875,8 @@ public:
case EShLangTessEvaluation:
return ! patch && isPipeInput();
case EShLangFragment:
return (pervertexNV || pervertexEXT) && isPipeInput();
case EShLangMeshNV:
return pervertexNV && isPipeInput();
case EShLangMesh:
return ! perTaskNV && isPipeOutput();
default:
@ -2543,7 +2544,7 @@ public:
void setStruct(TTypeList* s) { assert(isStruct()); structure = s; }
TTypeList* getWritableStruct() const { assert(isStruct()); return structure; } // This should only be used when known to not be sharing with other threads
void setBasicType(const TBasicType& t) { basicType = t; }
int computeNumComponents() const
{
int components = 0;

View file

@ -148,6 +148,15 @@ typedef struct glslang_resource_s {
int max_task_work_group_size_y_nv;
int max_task_work_group_size_z_nv;
int max_mesh_view_count_nv;
int max_mesh_output_vertices_ext;
int max_mesh_output_primitives_ext;
int max_mesh_work_group_size_x_ext;
int max_mesh_work_group_size_y_ext;
int max_mesh_work_group_size_z_ext;
int max_task_work_group_size_x_ext;
int max_task_work_group_size_y_ext;
int max_task_work_group_size_z_ext;
int max_mesh_view_count_ext;
int maxDualSourceDrawBuffersEXT;
glslang_limits_t limits;

View file

@ -49,8 +49,10 @@ typedef enum {
GLSLANG_STAGE_CLOSESTHIT_NV,
GLSLANG_STAGE_MISS_NV,
GLSLANG_STAGE_CALLABLE_NV,
GLSLANG_STAGE_TASK_NV,
GLSLANG_STAGE_MESH_NV,
GLSLANG_STAGE_TASK,
GLSLANG_STAGE_TASK_NV = GLSLANG_STAGE_TASK,
GLSLANG_STAGE_MESH,
GLSLANG_STAGE_MESH_NV = GLSLANG_STAGE_MESH,
LAST_ELEMENT_MARKER(GLSLANG_STAGE_COUNT),
} glslang_stage_t; // would be better as stage, but this is ancient now
@ -68,8 +70,10 @@ typedef enum {
GLSLANG_STAGE_CLOSESTHIT_NV_MASK = (1 << GLSLANG_STAGE_CLOSESTHIT_NV),
GLSLANG_STAGE_MISS_NV_MASK = (1 << GLSLANG_STAGE_MISS_NV),
GLSLANG_STAGE_CALLABLE_NV_MASK = (1 << GLSLANG_STAGE_CALLABLE_NV),
GLSLANG_STAGE_TASK_NV_MASK = (1 << GLSLANG_STAGE_TASK_NV),
GLSLANG_STAGE_MESH_NV_MASK = (1 << GLSLANG_STAGE_MESH_NV),
GLSLANG_STAGE_TASK_MASK = (1 << GLSLANG_STAGE_TASK),
GLSLANG_STAGE_TASK_NV_MASK = GLSLANG_STAGE_TASK_MASK,
GLSLANG_STAGE_MESH_MASK = (1 << GLSLANG_STAGE_MESH),
GLSLANG_STAGE_MESH_NV_MASK = GLSLANG_STAGE_MESH_MASK,
LAST_ELEMENT_MARKER(GLSLANG_STAGE_MASK_COUNT),
} glslang_stage_mask_t;

View file

@ -934,6 +934,8 @@ enum TOperator {
EOpExecuteCallableNV,
EOpExecuteCallableKHR,
EOpWritePackedPrimitiveIndices4x8NV,
EOpEmitMeshTasksEXT,
EOpSetMeshOutputsEXT,
//
// GL_EXT_ray_query operations

View file

@ -2268,11 +2268,11 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"\n"
);
stageBuiltins[EShLangMeshNV].append(
stageBuiltins[EShLangMesh].append(
"void subgroupMemoryBarrierShared();"
"\n"
);
stageBuiltins[EShLangTaskNV].append(
stageBuiltins[EShLangTask].append(
"void subgroupMemoryBarrierShared();"
"\n"
);
@ -4298,10 +4298,10 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"void barrier();"
);
if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 320)) {
stageBuiltins[EShLangMeshNV].append(
stageBuiltins[EShLangMesh].append(
"void barrier();"
);
stageBuiltins[EShLangTaskNV].append(
stageBuiltins[EShLangTask].append(
"void barrier();"
);
}
@ -4326,11 +4326,11 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
commonBuiltins.append("void memoryBarrierImage();");
}
if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 320)) {
stageBuiltins[EShLangMeshNV].append(
stageBuiltins[EShLangMesh].append(
"void memoryBarrierShared();"
"void groupMemoryBarrier();"
);
stageBuiltins[EShLangTaskNV].append(
stageBuiltins[EShLangTask].append(
"void memoryBarrierShared();"
"void groupMemoryBarrier();"
);
@ -4655,10 +4655,21 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
// Builtins for GL_NV_mesh_shader
if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 320)) {
stageBuiltins[EShLangMeshNV].append(
stageBuiltins[EShLangMesh].append(
"void writePackedPrimitiveIndices4x8NV(uint, uint);"
"\n");
}
// Builtins for GL_EXT_mesh_shader
if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 320)) {
// Builtins for GL_EXT_mesh_shader
stageBuiltins[EShLangTask].append(
"void EmitMeshTasksEXT(uint, uint, uint);"
"\n");
stageBuiltins[EShLangMesh].append(
"void SetMeshOutputsEXT(uint, uint);"
"\n");
}
#endif // !GLSLANG_ANGLE
#endif // !GLSLANG_WEB
@ -4855,7 +4866,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 320)) {
// per-vertex attributes
stageBuiltins[EShLangMeshNV].append(
stageBuiltins[EShLangMesh].append(
"out gl_MeshPerVertexNV {"
"vec4 gl_Position;"
"float gl_PointSize;"
@ -4868,7 +4879,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
);
// per-primitive attributes
stageBuiltins[EShLangMeshNV].append(
stageBuiltins[EShLangMesh].append(
"perprimitiveNV out gl_MeshPerPrimitiveNV {"
"int gl_PrimitiveID;"
"int gl_Layer;"
@ -4879,7 +4890,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"} gl_MeshPrimitivesNV[];"
);
stageBuiltins[EShLangMeshNV].append(
stageBuiltins[EShLangMesh].append(
"out uint gl_PrimitiveCountNV;"
"out uint gl_PrimitiveIndicesNV[];"
@ -4893,10 +4904,38 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"in highp uvec3 gl_GlobalInvocationID;"
"in highp uint gl_LocalInvocationIndex;"
"\n");
stageBuiltins[EShLangTaskNV].append(
// GL_EXT_mesh_shader
stageBuiltins[EShLangMesh].append(
"out uint gl_PrimitivePointIndicesEXT[];"
"out uvec2 gl_PrimitiveLineIndicesEXT[];"
"out uvec3 gl_PrimitiveTriangleIndicesEXT[];"
"in highp uvec3 gl_NumWorkGroups;"
"\n");
// per-vertex attributes
stageBuiltins[EShLangMesh].append(
"out gl_MeshPerVertexEXT {"
"vec4 gl_Position;"
"float gl_PointSize;"
"float gl_ClipDistance[];"
"float gl_CullDistance[];"
"} gl_MeshVerticesEXT[];"
);
// per-primitive attributes
stageBuiltins[EShLangMesh].append(
"perprimitiveEXT out gl_MeshPerPrimitiveEXT {"
"int gl_PrimitiveID;"
"int gl_Layer;"
"int gl_ViewportIndex;"
"bool gl_CullPrimitiveEXT;"
"int gl_PrimitiveShadingRateEXT;"
"} gl_MeshPrimitivesEXT[];"
);
stageBuiltins[EShLangTask].append(
"out uint gl_TaskCountNV;"
"const highp uvec3 gl_WorkGroupSize = uvec3(1,1,1);"
@ -4909,27 +4948,28 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"in uint gl_MeshViewCountNV;"
"in uint gl_MeshViewIndicesNV[4];"
"in highp uvec3 gl_NumWorkGroups;"
"\n");
}
if (profile != EEsProfile && version >= 450) {
stageBuiltins[EShLangMeshNV].append(
stageBuiltins[EShLangMesh].append(
"in highp int gl_DeviceIndex;" // GL_EXT_device_group
"in int gl_DrawIDARB;" // GL_ARB_shader_draw_parameters
"in int gl_ViewIndex;" // GL_EXT_multiview
"\n");
stageBuiltins[EShLangTaskNV].append(
stageBuiltins[EShLangTask].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(
stageBuiltins[EShLangMesh].append(
"in int gl_DrawID;"
"\n");
stageBuiltins[EShLangTaskNV].append(
stageBuiltins[EShLangTask].append(
"in int gl_DrawID;"
"\n");
}
@ -5704,8 +5744,8 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
stageBuiltins[EShLangGeometry] .append(ballotDecls);
stageBuiltins[EShLangCompute] .append(ballotDecls);
stageBuiltins[EShLangFragment] .append(fragmentBallotDecls);
stageBuiltins[EShLangMeshNV] .append(ballotDecls);
stageBuiltins[EShLangTaskNV] .append(ballotDecls);
stageBuiltins[EShLangMesh] .append(ballotDecls);
stageBuiltins[EShLangTask] .append(ballotDecls);
stageBuiltins[EShLangRayGen] .append(rtBallotDecls);
stageBuiltins[EShLangIntersect] .append(rtBallotDecls);
// No volatile qualifier on these builtins in any-hit
@ -5773,10 +5813,10 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
stageBuiltins[EShLangCompute] .append(subgroupDecls);
stageBuiltins[EShLangCompute] .append(computeSubgroupDecls);
stageBuiltins[EShLangFragment] .append(fragmentSubgroupDecls);
stageBuiltins[EShLangMeshNV] .append(subgroupDecls);
stageBuiltins[EShLangMeshNV] .append(computeSubgroupDecls);
stageBuiltins[EShLangTaskNV] .append(subgroupDecls);
stageBuiltins[EShLangTaskNV] .append(computeSubgroupDecls);
stageBuiltins[EShLangMesh] .append(subgroupDecls);
stageBuiltins[EShLangMesh] .append(computeSubgroupDecls);
stageBuiltins[EShLangTask] .append(subgroupDecls);
stageBuiltins[EShLangTask] .append(computeSubgroupDecls);
stageBuiltins[EShLangRayGen] .append(rtSubgroupDecls);
stageBuiltins[EShLangIntersect] .append(rtSubgroupDecls);
// No volatile qualifier on these builtins in any-hit
@ -8883,7 +8923,7 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
}
break;
case EShLangMeshNV:
case EShLangMesh:
if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 320)) {
// per-vertex builtins
symbolTable.setVariableExtensions("gl_MeshVerticesNV", "gl_Position", 1, &E_GL_NV_mesh_shader);
@ -8927,12 +8967,19 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
symbolTable.setVariableExtensions("gl_PrimitiveIndicesNV", 1, &E_GL_NV_mesh_shader);
symbolTable.setVariableExtensions("gl_MeshViewCountNV", 1, &E_GL_NV_mesh_shader);
symbolTable.setVariableExtensions("gl_MeshViewIndicesNV", 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);
symbolTable.setVariableExtensions("gl_LocalInvocationID", 1, &E_GL_NV_mesh_shader);
symbolTable.setVariableExtensions("gl_GlobalInvocationID", 1, &E_GL_NV_mesh_shader);
symbolTable.setVariableExtensions("gl_LocalInvocationIndex", 1, &E_GL_NV_mesh_shader);
if (profile != EEsProfile) {
symbolTable.setVariableExtensions("gl_WorkGroupSize", Num_AEP_mesh_shader, AEP_mesh_shader);
symbolTable.setVariableExtensions("gl_WorkGroupID", Num_AEP_mesh_shader, AEP_mesh_shader);
symbolTable.setVariableExtensions("gl_LocalInvocationID", Num_AEP_mesh_shader, AEP_mesh_shader);
symbolTable.setVariableExtensions("gl_GlobalInvocationID", Num_AEP_mesh_shader, AEP_mesh_shader);
symbolTable.setVariableExtensions("gl_LocalInvocationIndex", Num_AEP_mesh_shader, AEP_mesh_shader);
} else {
symbolTable.setVariableExtensions("gl_WorkGroupSize", 1, &E_GL_NV_mesh_shader);
symbolTable.setVariableExtensions("gl_WorkGroupID", 1, &E_GL_NV_mesh_shader);
symbolTable.setVariableExtensions("gl_LocalInvocationID", 1, &E_GL_NV_mesh_shader);
symbolTable.setVariableExtensions("gl_GlobalInvocationID", 1, &E_GL_NV_mesh_shader);
symbolTable.setVariableExtensions("gl_LocalInvocationIndex", 1, &E_GL_NV_mesh_shader);
}
BuiltInVariable("gl_PrimitiveCountNV", EbvPrimitiveCountNV, symbolTable);
BuiltInVariable("gl_PrimitiveIndicesNV", EbvPrimitiveIndicesNV, symbolTable);
BuiltInVariable("gl_MeshViewCountNV", EbvMeshViewCountNV, symbolTable);
@ -8950,12 +8997,54 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
symbolTable.setVariableExtensions("gl_MaxMeshViewCountNV", 1, &E_GL_NV_mesh_shader);
// builtin functions
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) {
symbolTable.setFunctionExtensions("barrier", Num_AEP_mesh_shader, AEP_mesh_shader);
symbolTable.setFunctionExtensions("memoryBarrierShared", Num_AEP_mesh_shader, AEP_mesh_shader);
symbolTable.setFunctionExtensions("groupMemoryBarrier", Num_AEP_mesh_shader, AEP_mesh_shader);
} else {
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);
}
symbolTable.setFunctionExtensions("writePackedPrimitiveIndices4x8NV", 1, &E_GL_NV_mesh_shader);
}
if (profile != EEsProfile && version >= 450) {
// GL_EXT_Mesh_shader
symbolTable.setVariableExtensions("gl_PrimitivePointIndicesEXT", 1, &E_GL_EXT_mesh_shader);
symbolTable.setVariableExtensions("gl_PrimitiveLineIndicesEXT", 1, &E_GL_EXT_mesh_shader);
symbolTable.setVariableExtensions("gl_PrimitiveTriangleIndicesEXT", 1, &E_GL_EXT_mesh_shader);
symbolTable.setVariableExtensions("gl_NumWorkGroups", 1, &E_GL_EXT_mesh_shader);
BuiltInVariable("gl_PrimitivePointIndicesEXT", EbvPrimitivePointIndicesEXT, symbolTable);
BuiltInVariable("gl_PrimitiveLineIndicesEXT", EbvPrimitiveLineIndicesEXT, symbolTable);
BuiltInVariable("gl_PrimitiveTriangleIndicesEXT", EbvPrimitiveTriangleIndicesEXT, symbolTable);
BuiltInVariable("gl_NumWorkGroups", EbvNumWorkGroups, symbolTable);
symbolTable.setVariableExtensions("gl_MeshVerticesEXT", "gl_Position", 1, &E_GL_EXT_mesh_shader);
symbolTable.setVariableExtensions("gl_MeshVerticesEXT", "gl_PointSize", 1, &E_GL_EXT_mesh_shader);
symbolTable.setVariableExtensions("gl_MeshVerticesEXT", "gl_ClipDistance", 1, &E_GL_EXT_mesh_shader);
symbolTable.setVariableExtensions("gl_MeshVerticesEXT", "gl_CullDistance", 1, &E_GL_EXT_mesh_shader);
BuiltInVariable("gl_MeshVerticesEXT", "gl_Position", EbvPosition, symbolTable);
BuiltInVariable("gl_MeshVerticesEXT", "gl_PointSize", EbvPointSize, symbolTable);
BuiltInVariable("gl_MeshVerticesEXT", "gl_ClipDistance", EbvClipDistance, symbolTable);
BuiltInVariable("gl_MeshVerticesEXT", "gl_CullDistance", EbvCullDistance, symbolTable);
symbolTable.setVariableExtensions("gl_MeshPrimitivesEXT", "gl_PrimitiveID", 1, &E_GL_EXT_mesh_shader);
symbolTable.setVariableExtensions("gl_MeshPrimitivesEXT", "gl_Layer", 1, &E_GL_EXT_mesh_shader);
symbolTable.setVariableExtensions("gl_MeshPrimitivesEXT", "gl_ViewportIndex", 1, &E_GL_EXT_mesh_shader);
symbolTable.setVariableExtensions("gl_MeshPrimitivesEXT", "gl_CullPrimitiveEXT", 1, &E_GL_EXT_mesh_shader);
symbolTable.setVariableExtensions("gl_MeshPrimitivesEXT", "gl_PrimitiveShadingRateEXT", 1, &E_GL_EXT_mesh_shader);
BuiltInVariable("gl_MeshPrimitivesEXT", "gl_PrimitiveID", EbvPrimitiveId, symbolTable);
BuiltInVariable("gl_MeshPrimitivesEXT", "gl_Layer", EbvLayer, symbolTable);
BuiltInVariable("gl_MeshPrimitivesEXT", "gl_ViewportIndex", EbvViewportIndex, symbolTable);
BuiltInVariable("gl_MeshPrimitivesEXT", "gl_CullPrimitiveEXT", EbvCullPrimitiveEXT, symbolTable);
BuiltInVariable("gl_MeshPrimitivesEXT", "gl_PrimitiveShadingRateEXT", EbvPrimitiveShadingRateKHR, symbolTable);
symbolTable.setFunctionExtensions("SetMeshOutputsEXT", 1, &E_GL_EXT_mesh_shader);
// GL_EXT_device_group
symbolTable.setVariableExtensions("gl_DeviceIndex", 1, &E_GL_EXT_device_group);
BuiltInVariable("gl_DeviceIndex", EbvDeviceIndex, symbolTable);
@ -8966,6 +9055,9 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
if (version >= 460) {
BuiltInVariable("gl_DrawID", EbvDrawId, symbolTable);
}
// GL_EXT_multiview
BuiltInVariable("gl_ViewIndex", EbvViewIndex, symbolTable);
symbolTable.setVariableExtensions("gl_ViewIndex", 1, &E_GL_EXT_multiview);
// GL_ARB_shader_ballot
symbolTable.setVariableExtensions("gl_SubGroupSizeARB", 1, &E_GL_ARB_shader_ballot);
@ -9035,16 +9127,24 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
}
break;
case EShLangTaskNV:
case EShLangTask:
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);
symbolTable.setVariableExtensions("gl_LocalInvocationID", 1, &E_GL_NV_mesh_shader);
symbolTable.setVariableExtensions("gl_GlobalInvocationID", 1, &E_GL_NV_mesh_shader);
symbolTable.setVariableExtensions("gl_LocalInvocationIndex", 1, &E_GL_NV_mesh_shader);
symbolTable.setVariableExtensions("gl_MeshViewCountNV", 1, &E_GL_NV_mesh_shader);
symbolTable.setVariableExtensions("gl_MeshViewIndicesNV", 1, &E_GL_NV_mesh_shader);
if (profile != EEsProfile) {
symbolTable.setVariableExtensions("gl_WorkGroupSize", Num_AEP_mesh_shader, AEP_mesh_shader);
symbolTable.setVariableExtensions("gl_WorkGroupID", Num_AEP_mesh_shader, AEP_mesh_shader);
symbolTable.setVariableExtensions("gl_LocalInvocationID", Num_AEP_mesh_shader, AEP_mesh_shader);
symbolTable.setVariableExtensions("gl_GlobalInvocationID", Num_AEP_mesh_shader, AEP_mesh_shader);
symbolTable.setVariableExtensions("gl_LocalInvocationIndex", Num_AEP_mesh_shader, AEP_mesh_shader);
} else {
symbolTable.setVariableExtensions("gl_WorkGroupSize", 1, &E_GL_NV_mesh_shader);
symbolTable.setVariableExtensions("gl_WorkGroupID", 1, &E_GL_NV_mesh_shader);
symbolTable.setVariableExtensions("gl_LocalInvocationID", 1, &E_GL_NV_mesh_shader);
symbolTable.setVariableExtensions("gl_GlobalInvocationID", 1, &E_GL_NV_mesh_shader);
symbolTable.setVariableExtensions("gl_LocalInvocationIndex", 1, &E_GL_NV_mesh_shader);
}
BuiltInVariable("gl_TaskCountNV", EbvTaskCountNV, symbolTable);
BuiltInVariable("gl_WorkGroupSize", EbvWorkGroupSize, symbolTable);
@ -9058,12 +9158,23 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
symbolTable.setVariableExtensions("gl_MaxTaskWorkGroupSizeNV", 1, &E_GL_NV_mesh_shader);
symbolTable.setVariableExtensions("gl_MaxMeshViewCountNV", 1, &E_GL_NV_mesh_shader);
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) {
symbolTable.setFunctionExtensions("barrier", Num_AEP_mesh_shader, AEP_mesh_shader);
symbolTable.setFunctionExtensions("memoryBarrierShared", Num_AEP_mesh_shader, AEP_mesh_shader);
symbolTable.setFunctionExtensions("groupMemoryBarrier", Num_AEP_mesh_shader, AEP_mesh_shader);
} else {
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_mesh_shader
symbolTable.setFunctionExtensions("EmitMeshTasksEXT", 1, &E_GL_EXT_mesh_shader);
symbolTable.setVariableExtensions("gl_NumWorkGroups", 1, &E_GL_EXT_mesh_shader);
BuiltInVariable("gl_NumWorkGroups", EbvNumWorkGroups, symbolTable);
// GL_EXT_device_group
symbolTable.setVariableExtensions("gl_DeviceIndex", 1, &E_GL_EXT_device_group);
BuiltInVariable("gl_DeviceIndex", EbvDeviceIndex, symbolTable);
@ -9687,17 +9798,27 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
symbolTable.relateToOperator("executeCallableEXT", EOpExecuteCallableKHR);
}
break;
case EShLangMeshNV:
case EShLangMesh:
if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 320)) {
symbolTable.relateToOperator("writePackedPrimitiveIndices4x8NV", EOpWritePackedPrimitiveIndices4x8NV);
symbolTable.relateToOperator("memoryBarrierShared", EOpMemoryBarrierShared);
symbolTable.relateToOperator("groupMemoryBarrier", EOpGroupMemoryBarrier);
symbolTable.relateToOperator("subgroupMemoryBarrierShared", EOpSubgroupMemoryBarrierShared);
}
// fall through
case EShLangTaskNV:
if (profile != EEsProfile && version >= 450) {
symbolTable.relateToOperator("SetMeshOutputsEXT", EOpSetMeshOutputsEXT);
}
break;
case EShLangTask:
if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 320)) {
symbolTable.relateToOperator("memoryBarrierShared", EOpMemoryBarrierShared);
symbolTable.relateToOperator("groupMemoryBarrier", EOpGroupMemoryBarrier);
symbolTable.relateToOperator("subgroupMemoryBarrierShared", EOpSubgroupMemoryBarrierShared);
}
if (profile != EEsProfile && version >= 450) {
symbolTable.relateToOperator("EmitMeshTasksEXT", EOpEmitMeshTasksEXT);
}
break;
default:

View file

@ -502,6 +502,16 @@ TIntermTyped* TParseContext::handleVariable(const TSourceLoc& loc, TSymbol* symb
error(loc, "cannot be used (maybe an instance name is needed)", string->c_str(), "");
variable = nullptr;
}
if (language == EShLangMesh && variable) {
TLayoutGeometry primitiveType = intermediate.getOutputPrimitive();
if ((variable->getMangledName() == "gl_PrimitiveTriangleIndicesEXT" && primitiveType != ElgTriangles) ||
(variable->getMangledName() == "gl_PrimitiveLineIndicesEXT" && primitiveType != ElgLines) ||
(variable->getMangledName() == "gl_PrimitivePointIndicesEXT" && primitiveType != ElgPoints)) {
error(loc, "cannot be used (ouput primitive type mismatch)", string->c_str(), "");
variable = nullptr;
}
}
} else {
if (symbol)
error(loc, "variable name expected", string->c_str(), "");
@ -717,7 +727,7 @@ bool TParseContext::isIoResizeArray(const TType& type) const
! type.getQualifier().patch) ||
(language == EShLangFragment && type.getQualifier().storage == EvqVaryingIn &&
(type.getQualifier().pervertexNV || type.getQualifier().pervertexEXT)) ||
(language == EShLangMeshNV && type.getQualifier().storage == EvqVaryingOut &&
(language == EShLangMesh && type.getQualifier().storage == EvqVaryingOut &&
!type.getQualifier().perTaskNV));
}
@ -794,7 +804,7 @@ void TParseContext::checkIoArraysConsistency(const TSourceLoc &loc, bool tailOnl
// As I/O array sizes don't change, fetch requiredSize only once,
// except for mesh shaders which could have different I/O array sizes based on type qualifiers.
if (firstIteration || (language == EShLangMeshNV)) {
if (firstIteration || (language == EShLangMesh)) {
requiredSize = getIoArrayImplicitSize(type.getQualifier(), &featureString);
if (requiredSize == 0)
break;
@ -823,10 +833,11 @@ int TParseContext::getIoArrayImplicitSize(const TQualifier &qualifier, TString *
// Number of vertices for Fragment shader is always three.
expectedSize = 3;
str = "vertices";
} else if (language == EShLangMeshNV) {
} else if (language == EShLangMesh) {
unsigned int maxPrimitives =
intermediate.getPrimitives() != TQualifier::layoutNotSet ? intermediate.getPrimitives() : 0;
if (qualifier.builtIn == EbvPrimitiveIndicesNV) {
if (qualifier.builtIn == EbvPrimitiveIndicesNV || qualifier.builtIn == EbvPrimitiveTriangleIndicesEXT ||
qualifier.builtIn == EbvPrimitiveLineIndicesEXT || qualifier.builtIn == EbvPrimitivePointIndicesEXT) {
expectedSize = maxPrimitives * TQualifier::mapGeometryToSize(intermediate.getOutputPrimitive());
str = "max_primitives*";
str += TQualifier::getGeometryString(intermediate.getOutputPrimitive());
@ -858,7 +869,7 @@ void TParseContext::checkIoArrayConsistency(const TSourceLoc& loc, int requiredS
if (type.getOuterArraySize() > requiredSize)
error(loc, " cannot be greater than 3 for pervertexEXT", feature, name.c_str());
}
else if (language == EShLangMeshNV)
else if (language == EShLangMesh)
error(loc, "inconsistent output array size of", feature, name.c_str());
else
assert(0);
@ -2000,18 +2011,18 @@ void TParseContext::memorySemanticsCheck(const TSourceLoc& loc, const TFunction&
break;
}
if ((semantics & gl_SemanticsAcquire) &&
if ((semantics & gl_SemanticsAcquire) &&
(callNode.getOp() == EOpAtomicStore || callNode.getOp() == EOpImageAtomicStore)) {
error(loc, "gl_SemanticsAcquire must not be used with (image) atomic store",
fnCandidate.getName().c_str(), "");
}
if ((semantics & gl_SemanticsRelease) &&
if ((semantics & gl_SemanticsRelease) &&
(callNode.getOp() == EOpAtomicLoad || callNode.getOp() == EOpImageAtomicLoad)) {
error(loc, "gl_SemanticsRelease must not be used with (image) atomic load",
fnCandidate.getName().c_str(), "");
}
if ((semantics & gl_SemanticsAcquireRelease) &&
(callNode.getOp() == EOpAtomicStore || callNode.getOp() == EOpImageAtomicStore ||
if ((semantics & gl_SemanticsAcquireRelease) &&
(callNode.getOp() == EOpAtomicStore || callNode.getOp() == EOpImageAtomicStore ||
callNode.getOp() == EOpAtomicLoad || callNode.getOp() == EOpImageAtomicLoad)) {
error(loc, "gl_SemanticsAcquireRelease must not be used with (image) atomic load/store",
fnCandidate.getName().c_str(), "");
@ -2462,7 +2473,7 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
const TIntermTyped* base = TIntermediate::findLValueBase(arg0, true , true);
const TType* refType = (base->getType().isReference()) ? base->getType().getReferentType() : nullptr;
const TQualifier& qualifier = (refType != nullptr) ? refType->getQualifier() : base->getType().getQualifier();
if (qualifier.storage != EvqShared && qualifier.storage != EvqBuffer)
if (qualifier.storage != EvqShared && qualifier.storage != EvqBuffer && qualifier.storage != EvqtaskPayloadSharedEXT)
error(loc,"Atomic memory function can only be used for shader storage block member or shared variable.",
fnCandidate.getName().c_str(), "");
@ -2560,7 +2571,7 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
}
if (profile != EEsProfile && version < 450) {
if ((*argp)[0]->getAsTyped()->getBasicType() != EbtFloat &&
if ((*argp)[0]->getAsTyped()->getBasicType() != EbtFloat &&
(*argp)[0]->getAsTyped()->getBasicType() != EbtDouble &&
(*argp)[1]->getAsTyped()->getBasicType() != EbtFloat &&
(*argp)[1]->getAsTyped()->getBasicType() != EbtDouble &&
@ -2995,6 +3006,10 @@ bool TParseContext::lValueErrorCheck(const TSourceLoc& loc, const char* op, TInt
message = "can't modify EvqFragStencil if using early_fragment_tests";
break;
case EvqtaskPayloadSharedEXT:
if (language == EShLangMesh)
message = "can't modify variable with storage qualifier taskPayloadSharedEXT in mesh shaders";
break;
default:
break;
}
@ -3033,7 +3048,7 @@ void TParseContext::rValueErrorCheck(const TSourceLoc& loc, const char* op, TInt
if (symNode && symNode->getQualifier().isExplicitInterpolation())
error(loc, "can't read from explicitly-interpolated object: ", op, symNode->getName().c_str());
// local_size_{xyz} must be assigned or specialized before gl_WorkGroupSize can be assigned.
// local_size_{xyz} must be assigned or specialized before gl_WorkGroupSize can be assigned.
if(node->getQualifier().builtIn == EbvWorkGroupSize &&
!(intermediate.isLocalSizeSet() || intermediate.isLocalSizeSpecialized()))
error(loc, "can't read from gl_WorkGroupSize before a fixed workgroup size has been declared", op, "");
@ -3831,6 +3846,9 @@ void TParseContext::globalQualifierTypeCheck(const TSourceLoc& loc, const TQuali
if (qualifier.isPatch() && qualifier.isInterpolation())
error(loc, "cannot use interpolation qualifiers with patch", "patch", "");
if (qualifier.isTaskPayload() && publicType.basicType == EbtBlock)
error(loc, "taskPayloadSharedEXT variables should not be declared as interface blocks", "taskPayloadSharedEXT", "");
if (qualifier.isTaskMemory() && publicType.basicType != EbtBlock)
error(loc, "taskNV variables can be declared only as blocks", "taskNV", "");
@ -3988,7 +4006,7 @@ void TParseContext::mergeQualifiers(const TSourceLoc& loc, TQualifier& dst, cons
(src.workgroupcoherent && (dst.coherent || dst.devicecoherent || dst.queuefamilycoherent || dst.subgroupcoherent || dst.shadercallcoherent)) ||
(src.subgroupcoherent && (dst.coherent || dst.devicecoherent || dst.queuefamilycoherent || dst.workgroupcoherent || dst.shadercallcoherent)) ||
(src.shadercallcoherent && (dst.coherent || dst.devicecoherent || dst.queuefamilycoherent || dst.workgroupcoherent || dst.subgroupcoherent)))) {
error(loc, "only one coherent/devicecoherent/queuefamilycoherent/workgroupcoherent/subgroupcoherent/shadercallcoherent qualifier allowed",
error(loc, "only one coherent/devicecoherent/queuefamilycoherent/workgroupcoherent/subgroupcoherent/shadercallcoherent qualifier allowed",
GetPrecisionQualifierString(src.precision), "");
}
#endif
@ -4346,10 +4364,10 @@ void TParseContext::arraySizesCheck(const TSourceLoc& loc, const TQualifier& qua
extensionsTurnedOn(Num_AEP_tessellation_shader, AEP_tessellation_shader))
return;
break;
case EShLangMeshNV:
case EShLangMesh:
if (qualifier.storage == EvqVaryingOut)
if ((isEsProfile() && version >= 320) ||
extensionTurnedOn(E_GL_NV_mesh_shader))
extensionsTurnedOn(Num_AEP_mesh_shader, AEP_mesh_shader))
return;
break;
default:
@ -4633,6 +4651,9 @@ TSymbol* TParseContext::redeclareBuiltinVariable(const TSourceLoc& loc, const TS
identifier == "gl_SampleMask" ||
identifier == "gl_Layer" ||
identifier == "gl_PrimitiveIndicesNV" ||
identifier == "gl_PrimitivePointIndicesEXT" ||
identifier == "gl_PrimitiveLineIndicesEXT" ||
identifier == "gl_PrimitiveTriangleIndicesEXT" ||
identifier == "gl_TexCoord") {
// Find the existing symbol, if any.
@ -4771,7 +4792,8 @@ void TParseContext::redeclareBuiltinBlock(const TSourceLoc& loc, TTypeList& newT
profileRequires(loc, ~EEsProfile, 410, E_GL_ARB_separate_shader_objects, feature);
if (blockName != "gl_PerVertex" && blockName != "gl_PerFragment" &&
blockName != "gl_MeshPerVertexNV" && blockName != "gl_MeshPerPrimitiveNV") {
blockName != "gl_MeshPerVertexNV" && blockName != "gl_MeshPerPrimitiveNV" &&
blockName != "gl_MeshPerVertexEXT" && blockName != "gl_MeshPerPrimitiveEXT") {
error(loc, "cannot redeclare block: ", "block declaration", blockName.c_str());
return;
}
@ -5340,11 +5362,11 @@ void TParseContext::finish()
if (!isEsProfile() && version < 430)
requireExtensions(getCurrentLoc(), 1, &E_GL_ARB_compute_shader, "compute shaders");
break;
case EShLangTaskNV:
requireExtensions(getCurrentLoc(), 1, &E_GL_NV_mesh_shader, "task shaders");
case EShLangTask:
requireExtensions(getCurrentLoc(), Num_AEP_mesh_shader, AEP_mesh_shader, "task shaders");
break;
case EShLangMeshNV:
requireExtensions(getCurrentLoc(), 1, &E_GL_NV_mesh_shader, "mesh shaders");
case EShLangMesh:
requireExtensions(getCurrentLoc(), Num_AEP_mesh_shader, AEP_mesh_shader, "mesh shaders");
break;
default:
break;
@ -5454,12 +5476,12 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
intermediate.setUsePhysicalStorageBuffer();
return;
}
if (language == EShLangGeometry || language == EShLangTessEvaluation || language == EShLangMeshNV) {
if (language == EShLangGeometry || language == EShLangTessEvaluation || language == EShLangMesh) {
if (id == TQualifier::getGeometryString(ElgTriangles)) {
publicType.shaderQualifiers.geometry = ElgTriangles;
return;
}
if (language == EShLangGeometry || language == EShLangMeshNV) {
if (language == EShLangGeometry || language == EShLangMesh) {
if (id == TQualifier::getGeometryString(ElgPoints)) {
publicType.shaderQualifiers.geometry = ElgPoints;
return;
@ -5737,7 +5759,7 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
return;
} else if (id == "location") {
profileRequires(loc, EEsProfile, 300, nullptr, "location");
const char* exts[2] = { E_GL_ARB_separate_shader_objects, E_GL_ARB_explicit_attrib_location };
const char* exts[2] = { E_GL_ARB_separate_shader_objects, E_GL_ARB_explicit_attrib_location };
// GL_ARB_explicit_uniform_location requires 330 or GL_ARB_explicit_attrib_location we do not need to add it here
profileRequires(loc, ~EEsProfile, 330, 2, exts, "location");
if ((unsigned int)value >= TQualifier::layoutLocationEnd)
@ -5947,9 +5969,9 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
}
break;
case EShLangMeshNV:
case EShLangMesh:
if (id == "max_vertices") {
requireExtensions(loc, 1, &E_GL_NV_mesh_shader, "max_vertices");
requireExtensions(loc, Num_AEP_mesh_shader, AEP_mesh_shader, "max_vertices");
publicType.shaderQualifiers.vertices = value;
if (value > resources.maxMeshOutputVerticesNV)
error(loc, "too large, must be less than gl_MaxMeshOutputVerticesNV", "max_vertices", "");
@ -5958,7 +5980,7 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
return;
}
if (id == "max_primitives") {
requireExtensions(loc, 1, &E_GL_NV_mesh_shader, "max_primitives");
requireExtensions(loc, Num_AEP_mesh_shader, AEP_mesh_shader, "max_primitives");
publicType.shaderQualifiers.primitives = value;
if (value > resources.maxMeshOutputPrimitivesNV)
error(loc, "too large, must be less than gl_MaxMeshOutputPrimitivesNV", "max_primitives", "");
@ -5968,14 +5990,14 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
}
// Fall through
case EShLangTaskNV:
case EShLangTask:
// Fall through
#endif
case EShLangCompute:
if (id.compare(0, 11, "local_size_") == 0) {
#ifndef GLSLANG_WEB
if (language == EShLangMeshNV || language == EShLangTaskNV) {
requireExtensions(loc, 1, &E_GL_NV_mesh_shader, "gl_WorkGroupSize");
if (language == EShLangMesh || language == EShLangTask) {
requireExtensions(loc, Num_AEP_mesh_shader, AEP_mesh_shader, "gl_WorkGroupSize");
} else {
profileRequires(loc, EEsProfile, 310, 0, "gl_WorkGroupSize");
profileRequires(loc, ~EEsProfile, 430, E_GL_ARB_compute_shader, "gl_WorkGroupSize");
@ -6251,6 +6273,9 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type)
if (type.getBasicType() == EbtBlock)
error(loc, "cannot apply to uniform or buffer block", "location", "");
break;
case EvqtaskPayloadSharedEXT:
error(loc, "cannot apply to taskPayloadSharedEXT", "location", "");
break;
#ifndef GLSLANG_WEB
case EvqPayload:
case EvqPayloadIn:
@ -6612,7 +6637,7 @@ void TParseContext::checkNoShaderLayouts(const TSourceLoc& loc, const TShaderQua
error(loc, message, "local_size id", "");
}
if (shaderQualifiers.vertices != TQualifier::layoutNotSet) {
if (language == EShLangGeometry || language == EShLangMeshNV)
if (language == EShLangGeometry || language == EShLangMesh)
error(loc, message, "max_vertices", "");
else if (language == EShLangTessControl)
error(loc, message, "vertices", "");
@ -6624,7 +6649,7 @@ void TParseContext::checkNoShaderLayouts(const TSourceLoc& loc, const TShaderQua
if (shaderQualifiers.postDepthCoverage)
error(loc, message, "post_depth_coverage", "");
if (shaderQualifiers.primitives != TQualifier::layoutNotSet) {
if (language == EShLangMeshNV)
if (language == EShLangMesh)
error(loc, message, "max_primitives", "");
else
assert(0);
@ -7270,6 +7295,8 @@ TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& iden
requireInt8Arithmetic(loc, "qualifier", "(u)int8 types can only be in uniform block or buffer storage");
}
if (type.getQualifier().storage == EvqtaskPayloadSharedEXT)
intermediate.addTaskPayloadEXTCount();
if (type.getQualifier().storage == EvqShared && type.containsCoopMat())
error(loc, "qualifier", "Cooperative matrix types must not be used in shared memory", "");
@ -8236,6 +8263,8 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con
memberQualifier.perViewNV = currentBlockQualifier.perViewNV;
if (currentBlockQualifier.perTaskNV)
memberQualifier.perTaskNV = currentBlockQualifier.perTaskNV;
if (currentBlockQualifier.storage == EvqtaskPayloadSharedEXT)
memberQualifier.storage = EvqtaskPayloadSharedEXT;
if (memberQualifier.storage == EvqSpirvStorageClass)
error(memberLoc, "member cannot have a spirv_storage_class qualifier", memberType.getFieldName().c_str(), "");
if (memberQualifier.hasSprivDecorate() && !memberQualifier.getSpirvDecorate().decorateIds.empty())
@ -8536,23 +8565,23 @@ void TParseContext::blockStageIoCheck(const TSourceLoc& loc, const TQualifier& q
// It is a compile-time error to have an input block in a vertex shader or an output block in a fragment shader
// "Compute shaders do not permit user-defined input variables..."
requireStage(loc, (EShLanguageMask)(EShLangTessControlMask|EShLangTessEvaluationMask|EShLangGeometryMask|
EShLangFragmentMask|EShLangMeshNVMask), "input block");
EShLangFragmentMask|EShLangMeshMask), "input block");
if (language == EShLangFragment) {
profileRequires(loc, EEsProfile, 320, Num_AEP_shader_io_blocks, AEP_shader_io_blocks, "fragment input block");
} else if (language == EShLangMeshNV && ! qualifier.isTaskMemory()) {
} else if (language == EShLangMesh && ! qualifier.isTaskMemory()) {
error(loc, "input blocks cannot be used in a mesh shader", "out", "");
}
break;
case EvqVaryingOut:
profileRequires(loc, ~EEsProfile, 150, E_GL_ARB_separate_shader_objects, "output block");
requireStage(loc, (EShLanguageMask)(EShLangVertexMask|EShLangTessControlMask|EShLangTessEvaluationMask|
EShLangGeometryMask|EShLangMeshNVMask|EShLangTaskNVMask), "output block");
EShLangGeometryMask|EShLangMeshMask|EShLangTaskMask), "output block");
// ES 310 can have a block before shader_io is turned on, so skip this test for built-ins
if (language == EShLangVertex && ! parsingBuiltins) {
profileRequires(loc, EEsProfile, 320, Num_AEP_shader_io_blocks, AEP_shader_io_blocks, "vertex output block");
} else if (language == EShLangMeshNV && qualifier.isTaskMemory()) {
} else if (language == EShLangMesh && qualifier.isTaskMemory()) {
error(loc, "can only use on input blocks in mesh shader", "taskNV", "");
} else if (language == EShLangTaskNV && ! qualifier.isTaskMemory()) {
} else if (language == EShLangTask && ! qualifier.isTaskMemory()) {
error(loc, "output blocks cannot be used in a task shader", "out", "");
}
break;
@ -8966,7 +8995,7 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con
{
#ifndef GLSLANG_WEB
if (publicType.shaderQualifiers.vertices != TQualifier::layoutNotSet) {
assert(language == EShLangTessControl || language == EShLangGeometry || language == EShLangMeshNV);
assert(language == EShLangTessControl || language == EShLangGeometry || language == EShLangMesh);
const char* id = (language == EShLangTessControl) ? "vertices" : "max_vertices";
if (publicType.qualifier.storage != EvqVaryingOut)
@ -8978,7 +9007,7 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con
checkIoArraysConsistency(loc);
}
if (publicType.shaderQualifiers.primitives != TQualifier::layoutNotSet) {
assert(language == EShLangMeshNV);
assert(language == EShLangMesh);
const char* id = "max_primitives";
if (publicType.qualifier.storage != EvqVaryingOut)
@ -9002,7 +9031,7 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con
case ElgTrianglesAdjacency:
case ElgQuads:
case ElgIsolines:
if (language == EShLangMeshNV) {
if (language == EShLangMesh) {
error(loc, "cannot apply to input", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), "");
break;
}
@ -9019,7 +9048,7 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con
switch (publicType.shaderQualifiers.geometry) {
case ElgLines:
case ElgTriangles:
if (language != EShLangMeshNV) {
if (language != EShLangMesh) {
error(loc, "cannot apply to 'out'", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), "");
break;
}
@ -9075,24 +9104,56 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con
error(loc, "too large; see gl_MaxComputeWorkGroupSize", "local_size", "");
}
#ifndef GLSLANG_WEB
else if (language == EShLangMeshNV) {
else if (language == EShLangMesh) {
switch (i) {
case 0: max = resources.maxMeshWorkGroupSizeX_NV; break;
case 1: max = resources.maxMeshWorkGroupSizeY_NV; break;
case 2: max = resources.maxMeshWorkGroupSizeZ_NV; break;
case 0:
max = extensionTurnedOn(E_GL_EXT_mesh_shader) ?
resources.maxMeshWorkGroupSizeX_EXT :
resources.maxMeshWorkGroupSizeX_NV;
break;
case 1:
max = extensionTurnedOn(E_GL_EXT_mesh_shader) ?
resources.maxMeshWorkGroupSizeY_EXT :
resources.maxMeshWorkGroupSizeY_NV ;
break;
case 2:
max = extensionTurnedOn(E_GL_EXT_mesh_shader) ?
resources.maxMeshWorkGroupSizeZ_EXT :
resources.maxMeshWorkGroupSizeZ_NV ;
break;
default: break;
}
if (intermediate.getLocalSize(i) > (unsigned int)max)
error(loc, "too large; see gl_MaxMeshWorkGroupSizeNV", "local_size", "");
} else if (language == EShLangTaskNV) {
if (intermediate.getLocalSize(i) > (unsigned int)max) {
TString maxsErrtring = "too large, see ";
maxsErrtring.append(extensionTurnedOn(E_GL_EXT_mesh_shader) ?
"gl_MaxMeshWorkGroupSizeEXT" : "gl_MaxMeshWorkGroupSizeNV");
error(loc, maxsErrtring.c_str(), "local_size", "");
}
} else if (language == EShLangTask) {
switch (i) {
case 0: max = resources.maxTaskWorkGroupSizeX_NV; break;
case 1: max = resources.maxTaskWorkGroupSizeY_NV; break;
case 2: max = resources.maxTaskWorkGroupSizeZ_NV; break;
case 0:
max = extensionTurnedOn(E_GL_EXT_mesh_shader) ?
resources.maxTaskWorkGroupSizeX_EXT :
resources.maxTaskWorkGroupSizeX_NV;
break;
case 1:
max = extensionTurnedOn(E_GL_EXT_mesh_shader) ?
resources.maxTaskWorkGroupSizeY_EXT:
resources.maxTaskWorkGroupSizeY_NV;
break;
case 2:
max = extensionTurnedOn(E_GL_EXT_mesh_shader) ?
resources.maxTaskWorkGroupSizeZ_EXT:
resources.maxTaskWorkGroupSizeZ_NV;
break;
default: break;
}
if (intermediate.getLocalSize(i) > (unsigned int)max)
error(loc, "too large; see gl_MaxTaskWorkGroupSizeNV", "local_size", "");
if (intermediate.getLocalSize(i) > (unsigned int)max) {
TString maxsErrtring = "too large, see ";
maxsErrtring.append(extensionTurnedOn(E_GL_EXT_mesh_shader) ?
"gl_MaxTaskWorkGroupSizeEXT" : "gl_MaxTaskWorkGroupSizeNV");
error(loc, maxsErrtring.c_str(), "local_size", "");
}
}
#endif
else {
@ -9181,7 +9242,7 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con
error(loc, "can only apply to 'in'", "derivative_group_linearNV", "");
}
// Check mesh out array sizes, once all the necessary out qualifiers are defined.
if ((language == EShLangMeshNV) &&
if ((language == EShLangMesh) &&
(intermediate.getVertices() != TQualifier::layoutNotSet) &&
(intermediate.getPrimitives() != TQualifier::layoutNotSet) &&
(intermediate.getOutputPrimitive() != ElgNone))
@ -9198,7 +9259,7 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con
// Exit early as further checks are not valid
return;
}
#endif
#endif
const TQualifier& qualifier = publicType.qualifier;
if (qualifier.isAuxiliary() ||
@ -9396,4 +9457,3 @@ const TTypeList* TParseContext::recordStructCopy(TStructRecord& record, const TT
}
} // end namespace glslang

View file

@ -758,6 +758,8 @@ void TScanContext::fillInKeywordMap()
(*KeywordMap)["perprimitiveNV"] = PERPRIMITIVENV;
(*KeywordMap)["perviewNV"] = PERVIEWNV;
(*KeywordMap)["taskNV"] = PERTASKNV;
(*KeywordMap)["perprimitiveEXT"] = PERPRIMITIVEEXT;
(*KeywordMap)["taskPayloadSharedEXT"] = TASKPAYLOADWORKGROUPEXT;
(*KeywordMap)["fcoopmatNV"] = FCOOPMATNV;
(*KeywordMap)["icoopmatNV"] = ICOOPMATNV;
@ -1740,12 +1742,18 @@ int TScanContext::tokenizeIdentifier()
case PERPRIMITIVENV:
case PERVIEWNV:
case PERTASKNV:
if ((!parseContext.isEsProfile() && parseContext.version >= 450) ||
(parseContext.isEsProfile() && parseContext.version >= 320) ||
if (parseContext.symbolTable.atBuiltInLevel() ||
parseContext.extensionTurnedOn(E_GL_NV_mesh_shader))
return keyword;
return identifierOrType();
case PERPRIMITIVEEXT:
case TASKPAYLOADWORKGROUPEXT:
if (parseContext.symbolTable.atBuiltInLevel() ||
parseContext.extensionTurnedOn(E_GL_EXT_mesh_shader))
return keyword;
return identifierOrType();
case FCOOPMATNV:
afterType = true;
if (parseContext.symbolTable.atBuiltInLevel() ||

View file

@ -391,13 +391,13 @@ bool InitializeSymbolTables(TInfoSink& infoSink, TSymbolTable** commonTable, TS
// check for mesh
if ((profile != EEsProfile && version >= 450) ||
(profile == EEsProfile && version >= 320))
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangMeshNV, source,
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangMesh, source,
infoSink, commonTable, symbolTables);
// check for task
if ((profile != EEsProfile && version >= 450) ||
(profile == EEsProfile && version >= 320))
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangTaskNV, source,
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangTask, source,
infoSink, commonTable, symbolTables);
#endif // !GLSLANG_ANGLE
#endif // !GLSLANG_WEB
@ -650,8 +650,8 @@ bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNo
version = 460;
}
break;
case EShLangMeshNV:
case EShLangTaskNV:
case EShLangMesh:
case EShLangTask:
if ((profile == EEsProfile && version < 320) ||
(profile != EEsProfile && version < 450)) {
correct = false;

View file

@ -166,7 +166,8 @@ void TParseVersions::initializeExtensionBehavior()
} extensionData;
const extensionData exts[] = { {E_GL_EXT_ray_tracing, EShTargetSpv_1_4},
{E_GL_NV_ray_tracing_motion_blur, EShTargetSpv_1_4}
{E_GL_NV_ray_tracing_motion_blur, EShTargetSpv_1_4},
{E_GL_EXT_mesh_shader, EShTargetSpv_1_4}
};
for (size_t ii = 0; ii < sizeof(exts) / sizeof(exts[0]); ii++) {
@ -345,6 +346,7 @@ void TParseVersions::initializeExtensionBehavior()
extensionBehavior[E_GL_EXT_terminate_invocation] = EBhDisable;
extensionBehavior[E_GL_EXT_shared_memory_block] = EBhDisable;
extensionBehavior[E_GL_EXT_spirv_intrinsics] = EBhDisable;
extensionBehavior[E_GL_EXT_mesh_shader] = EBhDisable;
// OVR extensions
extensionBehavior[E_GL_OVR_multiview] = EBhDisable;
@ -511,6 +513,7 @@ void TParseVersions::getPreamble(std::string& preamble)
"#define GL_EXT_ray_flags_primitive_culling 1\n"
"#define GL_EXT_ray_cull_mask 1\n"
"#define GL_EXT_spirv_intrinsics 1\n"
"#define GL_EXT_mesh_shader 1\n"
"#define GL_AMD_shader_ballot 1\n"
"#define GL_AMD_shader_trinary_minmax 1\n"
@ -641,8 +644,8 @@ void TParseVersions::getPreamble(std::string& preamble)
case EShLangClosestHit: preamble += "#define GL_CLOSEST_HIT_SHADER_EXT 1 \n"; break;
case EShLangMiss: preamble += "#define GL_MISS_SHADER_EXT 1 \n"; break;
case EShLangCallable: preamble += "#define GL_CALLABLE_SHADER_EXT 1 \n"; break;
case EShLangTaskNV: preamble += "#define GL_TASK_SHADER_NV 1 \n"; break;
case EShLangMeshNV: preamble += "#define GL_MESH_SHADER_NV 1 \n"; break;
case EShLangTask: preamble += "#define GL_TASK_SHADER_NV 1 \n"; break;
case EShLangMesh: preamble += "#define GL_MESH_SHADER_NV 1 \n"; break;
default: break;
}
}
@ -668,8 +671,8 @@ const char* StageName(EShLanguage stage)
case EShLangClosestHit: return "closest-hit";
case EShLangMiss: return "miss";
case EShLangCallable: return "callable";
case EShLangMeshNV: return "mesh";
case EShLangTaskNV: return "task";
case EShLangMesh: return "mesh";
case EShLangTask: return "task";
#endif
default: return "unknown stage";
}
@ -1060,10 +1063,22 @@ void TParseVersions::checkExtensionStage(const TSourceLoc& loc, const char * con
{
// 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 | EShLangFragmentMask),
requireStage(loc, (EShLanguageMask)(EShLangTaskMask | EShLangMeshMask | 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");
if (extensionTurnedOn(E_GL_EXT_mesh_shader)) {
error(loc, "GL_EXT_mesh_shader is already turned on, and not allowed with", "#extension", extension);
}
}
else if (strcmp(extension, "GL_EXT_mesh_shader") == 0) {
requireStage(loc, (EShLanguageMask)(EShLangTaskMask | EShLangMeshMask | EShLangFragmentMask),
"#extension GL_EXT_mesh_shader");
profileRequires(loc, ECoreProfile, 450, 0, "#extension GL_EXT_mesh_shader");
profileRequires(loc, EEsProfile, 320, 0, "#extension GL_EXT_mesh_shader");
if (extensionTurnedOn(E_GL_NV_mesh_shader)) {
error(loc, "GL_NV_mesh_shader is already turned on, and not allowed with", "#extension", extension);
}
}
}

View file

@ -211,6 +211,7 @@ const char* const E_GL_EXT_shared_memory_block = "GL_EXT_shared_mem
const char* const E_GL_EXT_subgroup_uniform_control_flow = "GL_EXT_subgroup_uniform_control_flow";
const char* const E_GL_EXT_spirv_intrinsics = "GL_EXT_spirv_intrinsics";
const char* const E_GL_EXT_fragment_shader_barycentric = "GL_EXT_fragment_shader_barycentric";
const char* const E_GL_EXT_mesh_shader = "GL_EXT_mesh_shader";
// Arrays of extensions for the above viewportEXTs duplications
@ -288,7 +289,7 @@ const char* const E_GL_EXT_tessellation_shader = "GL_EXT_tessel
const char* const E_GL_EXT_tessellation_point_size = "GL_EXT_tessellation_point_size";
const char* const E_GL_EXT_texture_buffer = "GL_EXT_texture_buffer";
const char* const E_GL_EXT_texture_cube_map_array = "GL_EXT_texture_cube_map_array";
const char* const E_GL_EXT_shader_integer_mix = "GL_EXT_shader_integer_mix";
const char* const E_GL_EXT_shader_integer_mix = "GL_EXT_shader_integer_mix";
// OES matching AEP
const char* const E_GL_OES_geometry_shader = "GL_OES_geometry_shader";
@ -349,6 +350,9 @@ const int Num_AEP_texture_buffer = sizeof(AEP_texture_buffer)/sizeof(AEP_texture
const char* const AEP_texture_cube_map_array[] = { E_GL_EXT_texture_cube_map_array, E_GL_OES_texture_cube_map_array };
const int Num_AEP_texture_cube_map_array = sizeof(AEP_texture_cube_map_array)/sizeof(AEP_texture_cube_map_array[0]);
const char* const AEP_mesh_shader[] = { E_GL_NV_mesh_shader, E_GL_EXT_mesh_shader };
const int Num_AEP_mesh_shader = sizeof(AEP_mesh_shader)/sizeof(AEP_mesh_shader[0]);
} // end namespace glslang
#endif // _VERSIONS_INCLUDED_

View file

@ -315,7 +315,7 @@ GLSLANG_WEB_EXCLUDE_ON
%token <lex> PATCH SAMPLE NONUNIFORM
%token <lex> COHERENT VOLATILE RESTRICT READONLY WRITEONLY DEVICECOHERENT QUEUEFAMILYCOHERENT WORKGROUPCOHERENT
%token <lex> SUBGROUPCOHERENT NONPRIVATE SHADERCALLCOHERENT
%token <lex> NOPERSPECTIVE EXPLICITINTERPAMD PERVERTEXEXT PERVERTEXNV PERPRIMITIVENV PERVIEWNV PERTASKNV
%token <lex> NOPERSPECTIVE EXPLICITINTERPAMD PERVERTEXEXT PERVERTEXNV PERPRIMITIVENV PERVIEWNV PERTASKNV PERPRIMITIVEEXT TASKPAYLOADWORKGROUPEXT
%token <lex> PRECISE
GLSLANG_WEB_EXCLUDE_OFF
@ -1301,24 +1301,34 @@ GLSLANG_WEB_EXCLUDE_ON
| PERPRIMITIVENV {
// 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.requireStage($1.loc, (EShLanguageMask)(EShLangFragmentMask | EShLangMeshMask), "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;
}
| PERPRIMITIVEEXT {
// No need for profile version or extension check. Shader stage already checks both.
parseContext.globalCheck($1.loc, "perprimitiveEXT");
parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangFragmentMask | EShLangMeshMask), "perprimitiveEXT");
// 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_EXT_mesh_shader, "perprimitiveEXT");
$$.init($1.loc);
$$.qualifier.perPrimitiveNV = true;
}
| PERVIEWNV {
// 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.requireStage($1.loc, EShLangMesh, "perviewNV");
$$.init($1.loc);
$$.qualifier.perViewNV = true;
}
| PERTASKNV {
// 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.requireStage($1.loc, (EShLanguageMask)(EShLangTaskMask | EShLangMeshMask), "taskNV");
$$.init($1.loc);
$$.qualifier.perTaskNV = true;
}
@ -1469,7 +1479,7 @@ storage_qualifier
parseContext.globalCheck($1.loc, "shared");
parseContext.profileRequires($1.loc, ECoreProfile | ECompatibilityProfile, 430, E_GL_ARB_compute_shader, "shared");
parseContext.profileRequires($1.loc, EEsProfile, 310, 0, "shared");
parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangComputeMask | EShLangMeshNVMask | EShLangTaskNVMask), "shared");
parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangComputeMask | EShLangMeshMask | EShLangTaskMask), "shared");
$$.init($1.loc);
$$.qualifier.storage = EvqShared;
}
@ -1656,6 +1666,13 @@ GLSLANG_WEB_EXCLUDE_ON
parseContext.unimplemented($1.loc, "subroutine");
$$.init($1.loc);
}
| TASKPAYLOADWORKGROUPEXT {
// No need for profile version or extension check. Shader stage already checks both.
parseContext.globalCheck($1.loc, "taskPayloadSharedEXT");
parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangTaskMask | EShLangMeshMask), "taskPayloadSharedEXT ");
$$.init($1.loc);
$$.qualifier.storage = EvqtaskPayloadSharedEXT;
}
GLSLANG_WEB_EXCLUDE_OFF
;

View file

@ -315,7 +315,7 @@ extern int yylex(YYSTYPE*, TParseContext&);
%token <lex> PATCH SAMPLE NONUNIFORM
%token <lex> COHERENT VOLATILE RESTRICT READONLY WRITEONLY DEVICECOHERENT QUEUEFAMILYCOHERENT WORKGROUPCOHERENT
%token <lex> SUBGROUPCOHERENT NONPRIVATE SHADERCALLCOHERENT
%token <lex> NOPERSPECTIVE EXPLICITINTERPAMD PERVERTEXEXT PERVERTEXNV PERPRIMITIVENV PERVIEWNV PERTASKNV
%token <lex> NOPERSPECTIVE EXPLICITINTERPAMD PERVERTEXEXT PERVERTEXNV PERPRIMITIVENV PERVIEWNV PERTASKNV PERPRIMITIVEEXT TASKPAYLOADWORKGROUPEXT
%token <lex> PRECISE
@ -1301,24 +1301,34 @@ interpolation_qualifier
| PERPRIMITIVENV {
// 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.requireStage($1.loc, (EShLanguageMask)(EShLangFragmentMask | EShLangMeshMask), "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;
}
| PERPRIMITIVEEXT {
// No need for profile version or extension check. Shader stage already checks both.
parseContext.globalCheck($1.loc, "perprimitiveEXT");
parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangFragmentMask | EShLangMeshMask), "perprimitiveEXT");
// 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_EXT_mesh_shader, "perprimitiveEXT");
$$.init($1.loc);
$$.qualifier.perPrimitiveNV = true;
}
| PERVIEWNV {
// 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.requireStage($1.loc, EShLangMesh, "perviewNV");
$$.init($1.loc);
$$.qualifier.perViewNV = true;
}
| PERTASKNV {
// 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.requireStage($1.loc, (EShLanguageMask)(EShLangTaskMask | EShLangMeshMask), "taskNV");
$$.init($1.loc);
$$.qualifier.perTaskNV = true;
}
@ -1469,7 +1479,7 @@ storage_qualifier
parseContext.globalCheck($1.loc, "shared");
parseContext.profileRequires($1.loc, ECoreProfile | ECompatibilityProfile, 430, E_GL_ARB_compute_shader, "shared");
parseContext.profileRequires($1.loc, EEsProfile, 310, 0, "shared");
parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangComputeMask | EShLangMeshNVMask | EShLangTaskNVMask), "shared");
parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangComputeMask | EShLangMeshMask | EShLangTaskMask), "shared");
$$.init($1.loc);
$$.qualifier.storage = EvqShared;
}
@ -1656,6 +1666,13 @@ storage_qualifier
parseContext.unimplemented($1.loc, "subroutine");
$$.init($1.loc);
}
| TASKPAYLOADWORKGROUPEXT {
// No need for profile version or extension check. Shader stage already checks both.
parseContext.globalCheck($1.loc, "taskPayloadSharedEXT");
parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangTaskMask | EShLangMeshMask), "taskPayloadSharedEXT ");
$$.init($1.loc);
$$.qualifier.storage = EvqtaskPayloadSharedEXT;
}
;

File diff suppressed because it is too large Load diff

View file

@ -506,7 +506,9 @@ extern int yydebug;
PERPRIMITIVENV = 707, /* PERPRIMITIVENV */
PERVIEWNV = 708, /* PERVIEWNV */
PERTASKNV = 709, /* PERTASKNV */
PRECISE = 710 /* PRECISE */
PERPRIMITIVEEXT = 710, /* PERPRIMITIVEEXT */
TASKPAYLOADWORKGROUPEXT = 711, /* TASKPAYLOADWORKGROUPEXT */
PRECISE = 712 /* PRECISE */
};
typedef enum yytokentype yytoken_kind_t;
#endif
@ -554,7 +556,7 @@ union YYSTYPE
glslang::TArraySizes* typeParameters;
} interm;
#line 558 "MachineIndependent/glslang_tab.cpp.h"
#line 560 "MachineIndependent/glslang_tab.cpp.h"
};
typedef union YYSTYPE YYSTYPE;

View file

@ -1068,6 +1068,8 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
case EOpExecuteCallableNV: out.debug << "executeCallableNV"; break;
case EOpExecuteCallableKHR: out.debug << "executeCallableKHR"; break;
case EOpWritePackedPrimitiveIndices4x8NV: out.debug << "writePackedPrimitiveIndices4x8NV"; break;
case EOpEmitMeshTasksEXT: out.debug << "EmitMeshTasksEXT"; break;
case EOpSetMeshOutputsEXT: out.debug << "SetMeshOutputsEXT"; break;
case EOpRayQueryInitialize: out.debug << "rayQueryInitializeEXT"; break;
case EOpRayQueryTerminate: out.debug << "rayQueryTerminateEXT"; break;
@ -1522,12 +1524,12 @@ void TIntermediate::output(TInfoSink& infoSink, bool tree)
infoSink.debug << "interlock ordering = " << TQualifier::getInterlockOrderingString(interlockOrdering) << "\n";
break;
case EShLangMeshNV:
case EShLangMesh:
infoSink.debug << "max_vertices = " << vertices << "\n";
infoSink.debug << "max_primitives = " << primitives << "\n";
infoSink.debug << "output primitive = " << TQualifier::getGeometryString(outputPrimitive) << "\n";
// Fall through
case EShLangTaskNV:
case EShLangTask:
// Fall through
case EShLangCompute:
infoSink.debug << "local_size = (" << localSize[0] << ", " << localSize[1] << ", " << localSize[2] << ")\n";

View file

@ -120,7 +120,7 @@ void TIntermediate::mergeUniformObjects(TInfoSink& infoSink, TIntermediate& unit
}
//
// do error checking on the shader boundary in / out vars
// do error checking on the shader boundary in / out vars
//
void TIntermediate::checkStageIO(TInfoSink& infoSink, TIntermediate& unit) {
if (unit.treeRoot == nullptr || treeRoot == nullptr)
@ -212,7 +212,7 @@ void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit)
if (vertices == TQualifier::layoutNotSet)
vertices = unit.vertices;
else if (unit.vertices != TQualifier::layoutNotSet && vertices != unit.vertices) {
if (language == EShLangGeometry || language == EShLangMeshNV)
if (language == EShLangGeometry || language == EShLangMesh)
error(infoSink, "Contradictory layout max_vertices values");
else if (language == EShLangTessControl)
error(infoSink, "Contradictory layout vertices values");
@ -222,7 +222,7 @@ void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit)
if (primitives == TQualifier::layoutNotSet)
primitives = unit.primitives;
else if (primitives != unit.primitives) {
if (language == EShLangMeshNV)
if (language == EShLangMesh)
error(infoSink, "Contradictory layout max_primitives values");
else
assert(0);
@ -692,7 +692,7 @@ void TIntermediate::mergeBlockDefinitions(TInfoSink& infoSink, TIntermSymbol* bl
TMergeBlockTraverser finalLinkTraverser(block);
getTreeRoot()->traverse(&finalLinkTraverser);
// The 'unit' intermediate needs the block structures update, but also structure entry indices
// The 'unit' intermediate needs the block structures update, but also structure entry indices
// may have changed from the old block to the new one that it was merged into, so update those
// in 'visitBinary'
TType unitType;
@ -1012,7 +1012,7 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
}
// Auxiliary and interpolation...
// "interpolation qualification (e.g., flat) and auxiliary qualification (e.g. centroid) may differ.
// "interpolation qualification (e.g., flat) and auxiliary qualification (e.g. centroid) may differ.
// These mismatches are allowed between any pair of stages ...
// those provided in the fragment shader supersede those provided in previous stages."
if (!crossStage &&
@ -1294,8 +1294,8 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled)
error(infoSink, "At least one shader must specify a layout(max_vertices = value)");
break;
case EShLangFragment:
// for GL_ARB_post_depth_coverage, EarlyFragmentTest is set automatically in
// ParseHelper.cpp. So if we reach here, this must be GL_EXT_post_depth_coverage
// for GL_ARB_post_depth_coverage, EarlyFragmentTest is set automatically in
// ParseHelper.cpp. So if we reach here, this must be GL_EXT_post_depth_coverage
// requiring explicit early_fragment_tests
if (getPostDepthCoverage() && !getEarlyFragmentTests())
error(infoSink, "post_depth_coverage requires early_fragment_tests");
@ -1312,7 +1312,7 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled)
if (numShaderRecordBlocks > 1)
error(infoSink, "Only one shaderRecordNV buffer block is allowed per stage");
break;
case EShLangMeshNV:
case EShLangMesh:
// NV_mesh_shader doesn't allow use of both single-view and per-view builtins.
if (inIoAccessed("gl_Position") && inIoAccessed("gl_PositionPerViewNV"))
error(infoSink, "Can only use one of gl_Position or gl_PositionPerViewNV");
@ -1331,9 +1331,11 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled)
if (primitives == TQualifier::layoutNotSet)
error(infoSink, "At least one shader must specify a layout(max_primitives = value)");
// fall through
case EShLangTaskNV:
case EShLangTask:
if (numTaskNVBlocks > 1)
error(infoSink, "Only one taskNV interface block is allowed per shader");
if (numTaskEXTPayloads > 1)
error(infoSink, "Only single variable of type taskPayloadSharedEXT is allowed per shader");
sharedBlockCheck(infoSink);
break;
default:
@ -2226,7 +2228,7 @@ int TIntermediate::getScalarAlignment(const TType& type, int& size, int& stride,
if (type.isVector()) {
int scalarAlign = getBaseAlignmentScalar(type, size);
size *= type.getVectorSize();
return scalarAlign;
}
@ -2247,7 +2249,7 @@ int TIntermediate::getScalarAlignment(const TType& type, int& size, int& stride,
assert(0); // all cases should be covered above
size = 1;
return 1;
return 1;
}
int TIntermediate::getMemberAlignment(const TType& type, int& size, int& stride, TLayoutPacking layoutPacking, bool rowMajor)
@ -2338,7 +2340,7 @@ bool TIntermediate::isIoResizeArray(const TType& type, EShLanguage language) {
(language == EShLangTessEvaluation && type.getQualifier().storage == EvqVaryingIn) ||
(language == EShLangFragment && type.getQualifier().storage == EvqVaryingIn &&
(type.getQualifier().pervertexNV || type.getQualifier().pervertexEXT)) ||
(language == EShLangMeshNV && type.getQualifier().storage == EvqVaryingOut &&
(language == EShLangMesh && type.getQualifier().storage == EvqVaryingOut &&
!type.getQualifier().perTaskNV));
}
#endif // not GLSLANG_WEB

View file

@ -322,6 +322,7 @@ public:
primitives(TQualifier::layoutNotSet),
numTaskNVBlocks(0),
layoutPrimitiveCulling(false),
numTaskEXTPayloads(0),
autoMapBindings(false),
autoMapLocations(false),
flattenUniformArrays(false),
@ -639,6 +640,7 @@ public:
int getNumPushConstants() const { return 0; }
void addShaderRecordCount() { }
void addTaskNVCount() { }
void addTaskPayloadEXTCount() { }
void setUseVulkanMemoryModel() { }
bool usingVulkanMemoryModel() const { return false; }
bool usingPhysicalStorageBuffer() const { return false; }
@ -756,6 +758,7 @@ public:
int getNumPushConstants() const { return numPushConstants; }
void addShaderRecordCount() { ++numShaderRecordBlocks; }
void addTaskNVCount() { ++numTaskNVBlocks; }
void addTaskPayloadEXTCount() { ++numTaskEXTPayloads; }
bool setInvocations(int i)
{
@ -1160,6 +1163,7 @@ protected:
int primitives;
int numTaskNVBlocks;
bool layoutPrimitiveCulling;
int numTaskEXTPayloads;
// Base shift values
std::array<unsigned int, EResCount> shiftBinding;

View file

@ -108,8 +108,10 @@ typedef enum {
EShLangMissNV = EShLangMiss,
EShLangCallable,
EShLangCallableNV = EShLangCallable,
EShLangTaskNV,
EShLangMeshNV,
EShLangTask,
EShLangTaskNV = EShLangTask,
EShLangMesh,
EShLangMeshNV = EShLangMesh,
LAST_ELEMENT_MARKER(EShLangCount),
} EShLanguage; // would be better as stage, but this is ancient now
@ -132,8 +134,10 @@ typedef enum : unsigned {
EShLangMissNVMask = EShLangMissMask,
EShLangCallableMask = (1 << EShLangCallable),
EShLangCallableNVMask = EShLangCallableMask,
EShLangTaskNVMask = (1 << EShLangTaskNV),
EShLangMeshNVMask = (1 << EShLangMeshNV),
EShLangTaskMask = (1 << EShLangTask),
EShLangTaskNVMask = EShLangTaskMask,
EShLangMeshMask = (1 << EShLangMesh),
EShLangMeshNVMask = EShLangMeshMask,
LAST_ELEMENT_MARKER(EShLanguageMaskCount),
} EShLanguageMask;