Skip to content

Commit

Permalink
Add-support-for-SPV_NV_mesh_shader
Browse files Browse the repository at this point in the history
  • Loading branch information
chaocNV committed Sep 19, 2018
1 parent 3a13796 commit 3c36699
Show file tree
Hide file tree
Showing 41 changed files with 6,403 additions and 3,664 deletions.
5 changes: 4 additions & 1 deletion SPIRV/GLSL.ext.NV.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ enum Op;
enum Capability;

static const int GLSLextNVVersion = 100;
static const int GLSLextNVRevision = 8;
static const int GLSLextNVRevision = 9;

//SPV_NV_sample_mask_override_coverage
const char* const E_SPV_NV_sample_mask_override_coverage = "SPV_NV_sample_mask_override_coverage";
Expand Down Expand Up @@ -63,4 +63,7 @@ const char* const E_SPV_NV_compute_shader_derivatives = "SPV_NV_compute_shader_d
//SPV_NV_shader_image_footprint
const char* const E_SPV_NV_shader_image_footprint = "SPV_NV_shader_image_footprint";

//SPV_NV_mesh_shader
const char* const E_SPV_NV_mesh_shader = "SPV_NV_mesh_shader";

#endif // #ifndef GLSLextNV_H
146 changes: 134 additions & 12 deletions SPIRV/GlslangToSpv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,9 @@ class TGlslangToSpvTraverser : public glslang::TIntermTraverser {
spv::Id createMiscOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, std::vector<spv::Id>& operands, glslang::TBasicType typeProxy);
spv::Id createNoArgOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId);
spv::Id getSymbolId(const glslang::TIntermSymbol* node);
#ifdef NV_EXTENSIONS
void addMeshNVDecoration(spv::Id id, int member, const glslang::TQualifier & qualifier);
#endif
spv::Id createSpvConstant(const glslang::TIntermTyped&);
spv::Id createSpvConstantFromConstUnionArray(const glslang::TType& type, const glslang::TConstUnionArray&, int& nextConst, bool specConstant);
bool isTrivialLeaf(const glslang::TIntermTyped* node);
Expand Down Expand Up @@ -272,6 +275,10 @@ spv::ExecutionModel TranslateExecutionModel(EShLanguage stage)
case EShLangGeometry: return spv::ExecutionModelGeometry;
case EShLangFragment: return spv::ExecutionModelFragment;
case EShLangCompute: return spv::ExecutionModelGLCompute;
#ifdef NV_EXTENSIONS
case EShLangTaskNV: return spv::ExecutionModelTaskNV;
case EShLangMeshNV: return spv::ExecutionModelMeshNV;
#endif
default:
assert(0);
return spv::ExecutionModelFragment;
Expand Down Expand Up @@ -379,7 +386,15 @@ spv::Decoration TranslateLayoutDecoration(const glslang::TType& type, glslang::T
}
case glslang::EvqVaryingIn:
case glslang::EvqVaryingOut:
assert(type.getQualifier().layoutPacking == glslang::ElpNone);
if (type.getQualifier().isTaskMemory()) {
switch (type.getQualifier().layoutPacking) {
case glslang::ElpShared: return spv::DecorationGLSLShared;
case glslang::ElpPacked: return spv::DecorationGLSLPacked;
default: break;
}
} else {
assert(type.getQualifier().layoutPacking == glslang::ElpNone);
}
return spv::DecorationMax;
default:
assert(0);
Expand Down Expand Up @@ -619,6 +634,11 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI
return spv::BuiltInSampleMask;

case glslang::EbvLayer:
#ifdef NV_EXTENSIONS
if (glslangIntermediate->getStage() == EShLangMeshNV) {
return spv::BuiltInLayer;
}
#endif
builder.addCapability(spv::CapabilityGeometry);
if (glslangIntermediate->getStage() == EShLangVertex ||
glslangIntermediate->getStage() == EShLangTessControl ||
Expand Down Expand Up @@ -835,6 +855,22 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI
builder.addExtension(spv::E_SPV_NV_fragment_shader_barycentric);
builder.addCapability(spv::CapabilityFragmentBarycentricNV);
return spv::BuiltInBaryCoordNoPerspNV;
case glslang::EbvTaskCountNV:
return spv::BuiltInTaskCountNV;
case glslang::EbvPrimitiveCountNV:
return spv::BuiltInPrimitiveCountNV;
case glslang::EbvPrimitiveIndicesNV:
return spv::BuiltInPrimitiveIndicesNV;
case glslang::EbvClipDistancePerViewNV:
return spv::BuiltInClipDistancePerViewNV;
case glslang::EbvCullDistancePerViewNV:
return spv::BuiltInCullDistancePerViewNV;
case glslang::EbvLayerPerViewNV:
return spv::BuiltInLayerPerViewNV;
case glslang::EbvMeshViewCountNV:
return spv::BuiltInMeshViewCountNV;
case glslang::EbvMeshViewIndicesNV:
return spv::BuiltInMeshViewIndicesNV;
#endif
default:
return spv::BuiltInMax;
Expand Down Expand Up @@ -1110,6 +1146,14 @@ void InheritQualifiers(glslang::TQualifier& child, const glslang::TQualifier& pa
child.readonly = true;
if (parent.writeonly)
child.writeonly = true;
#ifdef NV_EXTENSIONS
if (parent.perPrimitiveNV)
child.perPrimitiveNV = true;
if (parent.perViewNV)
child.perViewNV = true;
if (parent.perTaskNV)
child.perTaskNV = true;
#endif
}

bool HasNonLayoutQualifiers(const glslang::TType& type, const glslang::TQualifier& qualifier)
Expand Down Expand Up @@ -1313,6 +1357,30 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, const gl
#endif
break;

#ifdef NV_EXTENSIONS
case EShLangTaskNV:
case EShLangMeshNV:
builder.addCapability(spv::CapabilityMeshShadingNV);
builder.addExtension(spv::E_SPV_NV_mesh_shader);
builder.addExecutionMode(shaderEntry, spv::ExecutionModeLocalSize, glslangIntermediate->getLocalSize(0),
glslangIntermediate->getLocalSize(1),
glslangIntermediate->getLocalSize(2));
if (glslangIntermediate->getStage() == EShLangMeshNV) {
builder.addExecutionMode(shaderEntry, spv::ExecutionModeOutputVertices, glslangIntermediate->getVertices());
builder.addExecutionMode(shaderEntry, spv::ExecutionModeOutputPrimitivesNV, glslangIntermediate->getPrimitives());

switch (glslangIntermediate->getOutputPrimitive()) {
case glslang::ElgPoints: mode = spv::ExecutionModeOutputPoints; break;
case glslang::ElgLines: mode = spv::ExecutionModeOutputLinesNV; break;
case glslang::ElgTriangles: mode = spv::ExecutionModeOutputTrianglesNV; break;
default: mode = spv::ExecutionModeMax; break;
}
if (mode != spv::ExecutionModeMax)
builder.addExecutionMode(shaderEntry, (spv::ExecutionMode)mode);
}
break;
#endif

default:
break;
}
Expand Down Expand Up @@ -2120,6 +2188,12 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
atomic = true;
break;

#ifdef NV_EXTENSIONS
case glslang::EOpWritePackedPrimitiveIndices4x8NV:
noReturnValue = true;
break;
#endif

default:
break;
}
Expand Down Expand Up @@ -2892,23 +2966,28 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
//
bool TGlslangToSpvTraverser::filterMember(const glslang::TType& member)
{
#ifdef NV_EXTENSIONS
auto& extensions = glslangIntermediate->getRequestedExtensions();

if (member.getFieldName() == "gl_ViewportMask" &&
extensions.find("GL_NV_viewport_array2") == extensions.end())
return true;
if (member.getFieldName() == "gl_SecondaryViewportMaskNV" &&
extensions.find("GL_NV_stereo_view_rendering") == extensions.end())
return true;
if (member.getFieldName() == "gl_SecondaryPositionNV" &&
extensions.find("GL_NV_stereo_view_rendering") == extensions.end())
return true;
if (member.getFieldName() == "gl_PositionPerViewNV" &&
extensions.find("GL_NVX_multiview_per_view_attributes") == extensions.end())
return true;
if (member.getFieldName() == "gl_ViewportMaskPerViewNV" &&
extensions.find("GL_NVX_multiview_per_view_attributes") == extensions.end())
return true;

if (glslangIntermediate->getStage() != EShLangMeshNV) {
if (member.getFieldName() == "gl_ViewportMask" &&
extensions.find("GL_NV_viewport_array2") == extensions.end())
return true;
if (member.getFieldName() == "gl_PositionPerViewNV" &&
extensions.find("GL_NVX_multiview_per_view_attributes") == extensions.end())
return true;
if (member.getFieldName() == "gl_ViewportMaskPerViewNV" &&
extensions.find("GL_NVX_multiview_per_view_attributes") == extensions.end())
return true;
}
#endif

return false;
};
Expand Down Expand Up @@ -3001,6 +3080,9 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type,
glslangIntermediate->getSource() == glslang::EShSourceHlsl) {
builder.addMemberDecoration(spvType, member, TranslateInterpolationDecoration(memberQualifier));
builder.addMemberDecoration(spvType, member, TranslateAuxiliaryStorageDecoration(memberQualifier));
#ifdef NV_EXTENSIONS
addMeshNVDecoration(spvType, member, memberQualifier);
#endif
}
}
builder.addMemberDecoration(spvType, member, TranslateInvariantDecoration(memberQualifier));
Expand Down Expand Up @@ -3272,9 +3354,10 @@ glslang::TLayoutPacking TGlslangToSpvTraverser::getExplicitLayout(const glslang:
if (type.getBasicType() != glslang::EbtBlock)
return glslang::ElpNone;

// has to be a uniform or buffer block
// has to be a uniform or buffer block or task in/out blocks
if (type.getQualifier().storage != glslang::EvqUniform &&
type.getQualifier().storage != glslang::EvqBuffer)
type.getQualifier().storage != glslang::EvqBuffer &&
!type.getQualifier().isTaskMemory())
return glslang::ElpNone;

// return the layout to use
Expand Down Expand Up @@ -3388,6 +3471,14 @@ void TGlslangToSpvTraverser::declareUseOfStructMember(const glslang::TTypeList&
case glslang::EbvSecondaryViewportMaskNV:
case glslang::EbvPositionPerViewNV:
case glslang::EbvViewportMaskPerViewNV:
case glslang::EbvTaskCountNV:
case glslang::EbvPrimitiveCountNV:
case glslang::EbvPrimitiveIndicesNV:
case glslang::EbvClipDistancePerViewNV:
case glslang::EbvCullDistancePerViewNV:
case glslang::EbvLayerPerViewNV:
case glslang::EbvMeshViewCountNV:
case glslang::EbvMeshViewIndicesNV:
#endif
// Generate the associated capability. Delegate to TranslateBuiltInDecoration.
// Alternately, we could just call this for any glslang built-in, since the
Expand Down Expand Up @@ -6691,6 +6782,12 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv::
return 0;
}
break;

#ifdef NV_EXTENSIONS
case glslang::EOpWritePackedPrimitiveIndices4x8NV:
builder.createNoResultOp(spv::OpWritePackedPrimitiveIndices4x8NV, operands);
return 0;
#endif
default:
return 0;
}
Expand Down Expand Up @@ -6888,6 +6985,9 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
builder.addDecoration(id, TranslatePrecisionDecoration(symbol->getType()));
builder.addDecoration(id, TranslateInterpolationDecoration(symbol->getType().getQualifier()));
builder.addDecoration(id, TranslateAuxiliaryStorageDecoration(symbol->getType().getQualifier()));
#ifdef NV_EXTENSIONS
addMeshNVDecoration(id, /*member*/ -1, symbol->getType().getQualifier());
#endif
if (symbol->getType().getQualifier().hasSpecConstantId())
builder.addDecoration(id, spv::DecorationSpecId, symbol->getType().getQualifier().layoutSpecConstantId);
if (symbol->getQualifier().hasIndex())
Expand Down Expand Up @@ -6994,6 +7094,28 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
return id;
}

#ifdef NV_EXTENSIONS
// add per-primitive, per-view. per-task decorations to a struct member (member >= 0) or an object
void TGlslangToSpvTraverser::addMeshNVDecoration(spv::Id id, int member, const glslang::TQualifier& qualifier)
{
if (member >= 0) {
if (qualifier.perPrimitiveNV)
builder.addMemberDecoration(id, (unsigned)member, spv::DecorationPerPrimitiveNV);
if (qualifier.perViewNV)
builder.addMemberDecoration(id, (unsigned)member, spv::DecorationPerViewNV);
if (qualifier.perTaskNV)
builder.addMemberDecoration(id, (unsigned)member, spv::DecorationPerTaskNV);
} else {
if (qualifier.perPrimitiveNV)
builder.addDecoration(id, spv::DecorationPerPrimitiveNV);
if (qualifier.perViewNV)
builder.addDecoration(id, spv::DecorationPerViewNV);
if (qualifier.perTaskNV)
builder.addDecoration(id, spv::DecorationPerTaskNV);
}
}
#endif

// Make a full tree of instructions to build a SPIR-V specialization constant,
// or regular constant if possible.
//
Expand Down
42 changes: 31 additions & 11 deletions SPIRV/disassemble.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -511,7 +511,8 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
strcmp(spv::E_SPV_NV_geometry_shader_passthrough, name) == 0 ||
strcmp(spv::E_SPV_NV_viewport_array2, name) == 0 ||
strcmp(spv::E_SPV_NVX_multiview_per_view_attributes, name) == 0 ||
strcmp(spv::E_SPV_NV_fragment_shader_barycentric, name) == 0) {
strcmp(spv::E_SPV_NV_fragment_shader_barycentric, name) == 0 ||
strcmp(spv::E_SPV_NV_mesh_shader, name) == 0) {
extInstSet = GLSLextNVInst;
#endif
}
Expand Down Expand Up @@ -693,25 +694,44 @@ static const char* GLSLextNVGetDebugNames(const char* name, unsigned entrypoint)
strcmp(name, spv::E_ARB_shader_viewport_layer_array) == 0 ||
strcmp(name, spv::E_SPV_NV_viewport_array2) == 0 ||
strcmp(spv::E_SPV_NVX_multiview_per_view_attributes, name) == 0 ||
strcmp(spv::E_SPV_NV_fragment_shader_barycentric, name) == 0) {
strcmp(spv::E_SPV_NV_fragment_shader_barycentric, name) == 0 ||
strcmp(name, spv::E_SPV_NV_mesh_shader) == 0) {
switch (entrypoint) {
case DecorationOverrideCoverageNV: return "OverrideCoverageNV";
case DecorationPassthroughNV: return "PassthroughNV";
case CapabilityGeometryShaderPassthroughNV: return "GeometryShaderPassthroughNV";
case DecorationViewportRelativeNV: return "ViewportRelativeNV";
// NV builtins
case BuiltInViewportMaskNV: return "ViewportMaskNV";
case CapabilityShaderViewportMaskNV: return "ShaderViewportMaskNV";
case DecorationSecondaryViewportRelativeNV: return "SecondaryViewportRelativeNV";
case BuiltInSecondaryPositionNV: return "SecondaryPositionNV";
case BuiltInSecondaryViewportMaskNV: return "SecondaryViewportMaskNV";
case CapabilityShaderStereoViewNV: return "ShaderStereoViewNV";
case BuiltInPositionPerViewNV: return "PositionPerViewNV";
case BuiltInViewportMaskPerViewNV: return "ViewportMaskPerViewNV";
case BuiltInBaryCoordNV: return "BaryCoordNV";
case BuiltInBaryCoordNoPerspNV: return "BaryCoordNoPerspNV";
case BuiltInTaskCountNV: return "TaskCountNV";
case BuiltInPrimitiveCountNV: return "PrimitiveCountNV";
case BuiltInPrimitiveIndicesNV: return "PrimitiveIndicesNV";
case BuiltInClipDistancePerViewNV: return "ClipDistancePerViewNV";
case BuiltInCullDistancePerViewNV: return "CullDistancePerViewNV";
case BuiltInLayerPerViewNV: return "LayerPerViewNV";
case BuiltInMeshViewCountNV: return "MeshViewCountNV";
case BuiltInMeshViewIndicesNV: return "MeshViewIndicesNV";

// NV Capabilities
case CapabilityGeometryShaderPassthroughNV: return "GeometryShaderPassthroughNV";
case CapabilityShaderViewportMaskNV: return "ShaderViewportMaskNV";
case CapabilityShaderStereoViewNV: return "ShaderStereoViewNV";
case CapabilityPerViewAttributesNV: return "PerViewAttributesNV";
case CapabilityFragmentBarycentricNV: return "FragmentBarycentricNV";
case CapabilityMeshShadingNV: return "MeshShadingNV";

// NV Decorations
case DecorationOverrideCoverageNV: return "OverrideCoverageNV";
case DecorationPassthroughNV: return "PassthroughNV";
case DecorationViewportRelativeNV: return "ViewportRelativeNV";
case DecorationSecondaryViewportRelativeNV: return "SecondaryViewportRelativeNV";
case DecorationPerVertexNV: return "PerVertexNV";
case BuiltInBaryCoordNV: return "BaryCoordNV";
case BuiltInBaryCoordNoPerspNV: return "BaryCoordNoPerspNV";
case DecorationPerPrimitiveNV: return "PerPrimitiveNV";
case DecorationPerViewNV: return "PerViewNV";
case DecorationPerTaskNV: return "PerTaskNV";

default: return "Bad";
}
}
Expand Down
Loading

0 comments on commit 3c36699

Please sign in to comment.