Commit 035cbbe3 by Sahil Parmar

Allow redeclaration of builtin interface blocks in mesh shader

Apart from allowing redeclaration of gl_MeshPerVertexNV and gl_MeshPerPrimitiveNV blocks, this change also - - Resize clip/cull perview distances based on static index use - Error out use of both single-view and per-view builtins - Add new gtests with redeclared blocks and edit existing test output - Fix couple of typos
parent ca042a0f
...@@ -1222,6 +1222,8 @@ int C_DECL main(int argc, char* argv[]) ...@@ -1222,6 +1222,8 @@ int C_DECL main(int argc, char* argv[])
// .rchit = ray closest hit // .rchit = ray closest hit
// .rmiss = ray miss // .rmiss = ray miss
// .rcall = ray callable // .rcall = ray callable
// .mesh = mesh
// .task = task
// Additionally, the file names may end in .<stage>.glsl and .<stage>.hlsl // Additionally, the file names may end in .<stage>.glsl and .<stage>.hlsl
// where <stage> is one of the stages listed above. // where <stage> is one of the stages listed above.
// //
...@@ -1360,7 +1362,7 @@ void usage() ...@@ -1360,7 +1362,7 @@ void usage()
" .rahit for a ray any hit shader\n" " .rahit for a ray any hit shader\n"
" .rchit for a ray closest hit shader\n" " .rchit for a ray closest hit shader\n"
" .rmiss for a ray miss shader\n" " .rmiss for a ray miss shader\n"
" .rcall for a ray callable shader" " .rcall for a ray callable shader\n"
#endif #endif
" .glsl for .vert.glsl, .tesc.glsl, ..., .comp.glsl compound suffixes\n" " .glsl for .vert.glsl, .tesc.glsl, ..., .comp.glsl compound suffixes\n"
" .hlsl for .vert.hlsl, .tesc.hlsl, ..., .comp.hlsl compound suffixes\n" " .hlsl for .vert.hlsl, .tesc.hlsl, ..., .comp.hlsl compound suffixes\n"
......
spv.meshShaderUserDefined.mesh spv.320.meshShaderUserDefined.mesh
// Module Version 10000 // Module Version 10000
// Generated by (magic number): 80007 // Generated by (magic number): 80007
// Id's are bound by 140 // Id's are bound by 140
......
#version 460
#define MAX_VER 81
#define MAX_PRIM 32
#define BARRIER() \
memoryBarrierShared(); \
barrier();
#extension GL_NV_mesh_shader : enable
layout(local_size_x = 32) in;
layout(max_vertices=MAX_VER) out;
layout(max_primitives=MAX_PRIM) out;
layout(triangles) out;
// test use of redeclared single-view builtins in mesh shaders:
out gl_MeshPerVertexNV {
vec4 gl_Position;
float gl_PointSize;
float gl_ClipDistance[4];
float gl_CullDistance[4];
} gl_MeshVerticesNV[];
perprimitiveNV out gl_MeshPerPrimitiveNV {
int gl_PrimitiveID;
int gl_Layer;
int gl_ViewportIndex;
int gl_ViewportMask[];
} gl_MeshPrimitivesNV[];
void main()
{
uint iid = gl_LocalInvocationID.x;
uint gid = gl_WorkGroupID.x;
gl_MeshVerticesNV[iid].gl_Position = vec4(1.0);
gl_MeshVerticesNV[iid].gl_PointSize = 2.0;
gl_MeshVerticesNV[iid].gl_ClipDistance[3] = 3.0;
gl_MeshVerticesNV[iid].gl_CullDistance[2] = 4.0;
BARRIER();
gl_MeshVerticesNV[iid+1].gl_Position = gl_MeshVerticesNV[iid].gl_Position;
gl_MeshVerticesNV[iid+1].gl_PointSize = gl_MeshVerticesNV[iid].gl_PointSize;
gl_MeshVerticesNV[iid+1].gl_ClipDistance[3] = gl_MeshVerticesNV[iid].gl_ClipDistance[3];
gl_MeshVerticesNV[iid+1].gl_CullDistance[2] = gl_MeshVerticesNV[iid].gl_CullDistance[2];
BARRIER();
gl_MeshPrimitivesNV[iid].gl_PrimitiveID = 6;
gl_MeshPrimitivesNV[iid].gl_Layer = 7;
gl_MeshPrimitivesNV[iid].gl_ViewportIndex = 8;
gl_MeshPrimitivesNV[iid].gl_ViewportMask[0] = 9;
BARRIER();
gl_MeshPrimitivesNV[iid+1].gl_PrimitiveID = gl_MeshPrimitivesNV[iid].gl_PrimitiveID;
gl_MeshPrimitivesNV[iid+1].gl_Layer = gl_MeshPrimitivesNV[iid].gl_Layer;
gl_MeshPrimitivesNV[iid+1].gl_ViewportIndex = gl_MeshPrimitivesNV[iid].gl_ViewportIndex;
gl_MeshPrimitivesNV[iid+1].gl_ViewportMask[0] = gl_MeshPrimitivesNV[iid].gl_ViewportMask[0];
BARRIER();
}
#version 450
#define MAX_VER 81
#define MAX_PRIM 32
#define MAX_VIEWS gl_MaxMeshViewCountNV
#define BARRIER() \
memoryBarrierShared(); \
barrier();
#extension GL_NV_mesh_shader : enable
layout(local_size_x = 32) in;
layout(max_vertices=MAX_VER) out;
layout(max_primitives=MAX_PRIM) out;
layout(triangles) out;
// test use of redeclared per-view builtin attributes
out gl_MeshPerVertexNV {
perviewNV vec4 gl_PositionPerViewNV[MAX_VIEWS]; // explicitly sized view dim
perviewNV float gl_ClipDistancePerViewNV[MAX_VIEWS][4]; // explicitly sized view dim
perviewNV float gl_CullDistancePerViewNV[MAX_VIEWS][4]; // explicitly sized view dim
} gl_MeshVerticesNV[];
perprimitiveNV out gl_MeshPerPrimitiveNV {
perviewNV int gl_LayerPerViewNV[]; // implicitly sized view dim
perviewNV int gl_ViewportMaskPerViewNV[][1]; // implicitly sized view dim
} gl_MeshPrimitivesNV[];
void main()
{
uint iid = gl_LocalInvocationID.x;
uint viewID = gl_MeshViewIndicesNV[gl_MeshViewCountNV%MAX_VIEWS];
gl_MeshVerticesNV[iid].gl_PositionPerViewNV[viewID] = vec4(1.0, 2.0, 3.0, 4.0);
gl_MeshVerticesNV[iid].gl_ClipDistancePerViewNV[viewID][2] = 5.0;
gl_MeshVerticesNV[iid].gl_CullDistancePerViewNV[viewID][3] = 6.0;
gl_MeshPrimitivesNV[iid].gl_LayerPerViewNV[viewID] = 7;
gl_MeshPrimitivesNV[iid].gl_ViewportMaskPerViewNV[viewID][0] = 8;
BARRIER();
gl_MeshVerticesNV[iid+1].gl_PositionPerViewNV[viewID] = gl_MeshVerticesNV[iid].gl_PositionPerViewNV[viewID];
gl_MeshVerticesNV[iid+1].gl_ClipDistancePerViewNV[viewID][2] = gl_MeshVerticesNV[iid].gl_ClipDistancePerViewNV[viewID][2];
gl_MeshVerticesNV[iid+1].gl_CullDistancePerViewNV[viewID][3] = gl_MeshVerticesNV[iid].gl_CullDistancePerViewNV[viewID][3];
gl_MeshPrimitivesNV[iid+1].gl_LayerPerViewNV[viewID] = gl_MeshPrimitivesNV[iid].gl_LayerPerViewNV[viewID];
gl_MeshPrimitivesNV[iid+1].gl_ViewportMaskPerViewNV[viewID][0] = gl_MeshPrimitivesNV[iid].gl_ViewportMaskPerViewNV[viewID][0];
BARRIER();
}
...@@ -1644,6 +1644,11 @@ public: ...@@ -1644,6 +1644,11 @@ public:
{ {
if (isUnsizedArray() && !(skipNonvariablyIndexed || isArrayVariablyIndexed())) if (isUnsizedArray() && !(skipNonvariablyIndexed || isArrayVariablyIndexed()))
changeOuterArraySize(getImplicitArraySize()); changeOuterArraySize(getImplicitArraySize());
#ifdef NV_EXTENSIONS
// For multi-dim per-view arrays, set unsized inner dimension size to 1
if (qualifier.isPerView() && arraySizes && arraySizes->isInnerUnsized())
arraySizes->clearInnerUnsized();
#endif
if (isStruct() && structure->size() > 0) { if (isStruct() && structure->size() > 0) {
int lastMember = (int)structure->size() - 1; int lastMember = (int)structure->size() - 1;
for (int i = 0; i < lastMember; ++i) for (int i = 0; i < lastMember; ++i)
......
...@@ -5296,8 +5296,8 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV ...@@ -5296,8 +5296,8 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"float gl_ClipDistance[];" "float gl_ClipDistance[];"
"float gl_CullDistance[];" "float gl_CullDistance[];"
"perviewNV vec4 gl_PositionPerViewNV[];" "perviewNV vec4 gl_PositionPerViewNV[];"
"perviewNV float gl_ClipDistancePerViewNV[][8];" "perviewNV float gl_ClipDistancePerViewNV[][];"
"perviewNV float gl_CullDistancePerViewNV[][8];" "perviewNV float gl_CullDistancePerViewNV[][];"
"} gl_MeshVerticesNV[];" "} gl_MeshVerticesNV[];"
); );
...@@ -5309,7 +5309,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV ...@@ -5309,7 +5309,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"int gl_ViewportIndex;" "int gl_ViewportIndex;"
"int gl_ViewportMask[];" "int gl_ViewportMask[];"
"perviewNV int gl_LayerPerViewNV[];" "perviewNV int gl_LayerPerViewNV[];"
"perviewNV int gl_ViewportMaskPerViewNV[][1];" "perviewNV int gl_ViewportMaskPerViewNV[][];"
"} gl_MeshPrimitivesNV[];" "} gl_MeshPrimitivesNV[];"
); );
......
...@@ -400,9 +400,21 @@ TIntermTyped* TParseContext::handleBracketDereference(const TSourceLoc& loc, TIn ...@@ -400,9 +400,21 @@ TIntermTyped* TParseContext::handleBracketDereference(const TSourceLoc& loc, TIn
handleIoResizeArrayAccess(loc, base); handleIoResizeArrayAccess(loc, base);
if (index->getQualifier().isFrontEndConstant()) { if (index->getQualifier().isFrontEndConstant()) {
if (base->getType().isUnsizedArray()) if (base->getType().isUnsizedArray()) {
base->getWritableType().updateImplicitArraySize(indexValue + 1); base->getWritableType().updateImplicitArraySize(indexValue + 1);
else #ifdef NV_EXTENSIONS
// For 2D per-view builtin arrays, update the inner dimension size in parent type
if (base->getQualifier().isPerView() && base->getQualifier().builtIn != EbvNone) {
TIntermBinary* binaryNode = base->getAsBinaryNode();
if (binaryNode) {
TType& leftType = binaryNode->getLeft()->getWritableType();
TArraySizes& arraySizes = *leftType.getArraySizes();
assert(arraySizes.getNumDims() == 2);
arraySizes.setDimSize(1, std::max(arraySizes.getDimSize(1), indexValue + 1));
}
}
#endif
} else
checkIndex(loc, base->getType(), indexValue); checkIndex(loc, base->getType(), indexValue);
result = intermediate.addIndex(EOpIndexDirect, base, index, loc); result = intermediate.addIndex(EOpIndexDirect, base, index, loc);
} else { } else {
...@@ -813,6 +825,8 @@ TIntermTyped* TParseContext::handleDotDereference(const TSourceLoc& loc, TInterm ...@@ -813,6 +825,8 @@ TIntermTyped* TParseContext::handleDotDereference(const TSourceLoc& loc, TInterm
TIntermTyped* index = intermediate.addConstantUnion(member, loc); TIntermTyped* index = intermediate.addConstantUnion(member, loc);
result = intermediate.addIndex(EOpIndexDirectStruct, base, index, loc); result = intermediate.addIndex(EOpIndexDirectStruct, base, index, loc);
result->setType(*(*fields)[member].type); result->setType(*(*fields)[member].type);
if ((*fields)[member].type->getQualifier().isIo())
intermediate.addIoAccessed(field);
} }
} else } else
error(loc, "no such field in structure", field.c_str(), ""); error(loc, "no such field in structure", field.c_str(), "");
...@@ -4059,10 +4073,31 @@ void TParseContext::redeclareBuiltinBlock(const TSourceLoc& loc, TTypeList& newT ...@@ -4059,10 +4073,31 @@ void TParseContext::redeclareBuiltinBlock(const TSourceLoc& loc, TTypeList& newT
error(memberLoc, "cannot redeclare block member with a different type", member->type->getFieldName().c_str(), ""); error(memberLoc, "cannot redeclare block member with a different type", member->type->getFieldName().c_str(), "");
if (oldType.isArray() != newType.isArray()) if (oldType.isArray() != newType.isArray())
error(memberLoc, "cannot change arrayness of redeclared block member", member->type->getFieldName().c_str(), ""); error(memberLoc, "cannot change arrayness of redeclared block member", member->type->getFieldName().c_str(), "");
else if (! oldType.sameArrayness(newType) && oldType.isSizedArray()) else if (! oldType.getQualifier().isPerView() && ! oldType.sameArrayness(newType) && oldType.isSizedArray())
error(memberLoc, "cannot change array size of redeclared block member", member->type->getFieldName().c_str(), ""); error(memberLoc, "cannot change array size of redeclared block member", member->type->getFieldName().c_str(), "");
else if (newType.isArray()) else if (! oldType.getQualifier().isPerView() && newType.isArray())
arrayLimitCheck(loc, member->type->getFieldName(), newType.getOuterArraySize()); arrayLimitCheck(loc, member->type->getFieldName(), newType.getOuterArraySize());
#ifdef NV_EXTENSIONS
if (oldType.getQualifier().isPerView() && ! newType.getQualifier().isPerView())
error(memberLoc, "missing perviewNV qualifier to redeclared block member", member->type->getFieldName().c_str(), "");
else if (! oldType.getQualifier().isPerView() && newType.getQualifier().isPerView())
error(memberLoc, "cannot add perviewNV qualifier to redeclared block member", member->type->getFieldName().c_str(), "");
else if (newType.getQualifier().isPerView()) {
if (oldType.getArraySizes()->getNumDims() != newType.getArraySizes()->getNumDims())
error(memberLoc, "cannot change arrayness of redeclared block member", member->type->getFieldName().c_str(), "");
else if (! newType.isUnsizedArray() && newType.getOuterArraySize() != resources.maxMeshViewCountNV)
error(loc, "mesh view output array size must be gl_MaxMeshViewCountNV or implicitly sized", "[]", "");
else if (newType.getArraySizes()->getNumDims() == 2) {
int innerDimSize = newType.getArraySizes()->getDimSize(1);
arrayLimitCheck(memberLoc, member->type->getFieldName(), innerDimSize);
oldType.getArraySizes()->setDimSize(1, innerDimSize);
}
}
if (oldType.getQualifier().isPerPrimitive() && ! newType.getQualifier().isPerPrimitive())
error(memberLoc, "missing perprimitiveNV qualifier to redeclared block member", member->type->getFieldName().c_str(), "");
else if (! oldType.getQualifier().isPerPrimitive() && newType.getQualifier().isPerPrimitive())
error(memberLoc, "cannot add perprimitiveNV qualifier to redeclared block member", member->type->getFieldName().c_str(), "");
#endif
if (newType.getQualifier().isMemory()) if (newType.getQualifier().isMemory())
error(memberLoc, "cannot add memory qualifier to redeclared block member", member->type->getFieldName().c_str(), ""); error(memberLoc, "cannot add memory qualifier to redeclared block member", member->type->getFieldName().c_str(), "");
if (newType.getQualifier().hasNonXfbLayout()) if (newType.getQualifier().hasNonXfbLayout())
...@@ -4421,6 +4456,12 @@ void TParseContext::arrayLimitCheck(const TSourceLoc& loc, const TString& identi ...@@ -4421,6 +4456,12 @@ void TParseContext::arrayLimitCheck(const TSourceLoc& loc, const TString& identi
limitCheck(loc, size, "gl_MaxClipDistances", "gl_ClipDistance array size"); limitCheck(loc, size, "gl_MaxClipDistances", "gl_ClipDistance array size");
else if (identifier.compare("gl_CullDistance") == 0) else if (identifier.compare("gl_CullDistance") == 0)
limitCheck(loc, size, "gl_MaxCullDistances", "gl_CullDistance array size"); limitCheck(loc, size, "gl_MaxCullDistances", "gl_CullDistance array size");
#ifdef NV_EXTENSIONS
else if (identifier.compare("gl_ClipDistancePerViewNV") == 0)
limitCheck(loc, size, "gl_MaxClipDistances", "gl_ClipDistancePerViewNV array size");
else if (identifier.compare("gl_CullDistancePerViewNV") == 0)
limitCheck(loc, size, "gl_MaxCullDistances", "gl_CullDistancePerViewNV array size");
#endif
} }
// See if the provided value is less than or equal to the symbol indicated by limit, // See if the provided value is less than or equal to the symbol indicated by limit,
......
...@@ -723,6 +723,17 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled) ...@@ -723,6 +723,17 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled)
error(infoSink, "Only one shaderRecordNVX buffer block is allowed per stage"); error(infoSink, "Only one shaderRecordNVX buffer block is allowed per stage");
break; break;
case EShLangMeshNV: case EShLangMeshNV:
// 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");
if (inIoAccessed("gl_ClipDistance") && inIoAccessed("gl_ClipDistancePerViewNV"))
error(infoSink, "Can only use one of gl_ClipDistance or gl_ClipDistancePerViewNV");
if (inIoAccessed("gl_CullDistance") && inIoAccessed("gl_CullDistancePerViewNV"))
error(infoSink, "Can only use one of gl_CullDistance or gl_CullDistancePerViewNV");
if (inIoAccessed("gl_Layer") && inIoAccessed("gl_LayerPerViewNV"))
error(infoSink, "Can only use one of gl_Layer or gl_LayerPerViewNV");
if (inIoAccessed("gl_ViewportMask") && inIoAccessed("gl_ViewportMaskPerViewNV"))
error(infoSink, "Can only use one of gl_ViewportMask or gl_ViewportMaskPerViewNV");
if (outputPrimitive == ElgNone) if (outputPrimitive == ElgNone)
error(infoSink, "At least one shader must specify an output layout primitive"); error(infoSink, "At least one shader must specify an output layout primitive");
if (vertices == TQualifier::layoutNotSet) if (vertices == TQualifier::layoutNotSet)
......
...@@ -524,6 +524,9 @@ INSTANTIATE_TEST_CASE_P( ...@@ -524,6 +524,9 @@ INSTANTIATE_TEST_CASE_P(
"spv.meshShaderPerViewUserDefined.mesh", "spv.meshShaderPerViewUserDefined.mesh",
"spv.meshShaderSharedMem.mesh", "spv.meshShaderSharedMem.mesh",
"spv.meshShaderTaskMem.mesh", "spv.meshShaderTaskMem.mesh",
"spv.320.meshShaderUserDefined.mesh",
"spv.meshShaderRedeclBuiltins.mesh",
"spv.meshShaderRedeclPerViewBuiltins.mesh",
"spv.meshTaskShader.task", "spv.meshTaskShader.task",
})), })),
FileNameAsCustomTestSuffix FileNameAsCustomTestSuffix
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment