diff options
| author | Yong He <yonghe@outlook.com> | 2024-01-24 15:36:49 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-01-24 15:36:49 -0800 |
| commit | e7b6de334f320429462a0257e2191ccf3cbc9a0d (patch) | |
| tree | 7e2f6802a2f6fa5217903948efbd994b51e103b7 /source | |
| parent | dd57306d951dbcaf6471659fcd1d2c37738f36d0 (diff) | |
[SPIRV] Support `globallycoherent` and `[vk::index()]`. (#3488)
* [SPIRV] Support `globallycoherent` modifier.
* Fix.
* Disable executable cooperative vector tests.
* Update expected failure.
* [SPIRV] Emit varying output index decoration.
* Add test.
* Update tests.
* Fix test.
* Emit `SpvExecutionModeEarlyFragmentTests`.
* Lower `StructuredBuffer<bool>`.
* Support globallycoherent on ByteAddressBuffer.
---------
Co-authored-by: Yong He <yhe@nvidia.com>
Diffstat (limited to 'source')
| -rw-r--r-- | source/slang/slang-check-modifier.cpp | 6 | ||||
| -rw-r--r-- | source/slang/slang-emit-glsl.cpp | 13 | ||||
| -rw-r--r-- | source/slang/slang-emit-spirv.cpp | 95 | ||||
| -rw-r--r-- | source/slang/slang-ir-byte-address-legalize.cpp | 17 | ||||
| -rw-r--r-- | source/slang/slang-ir-glsl-legalize.cpp | 50 | ||||
| -rw-r--r-- | source/slang/slang-ir-lower-buffer-element-type.cpp | 2 |
6 files changed, 138 insertions, 45 deletions
diff --git a/source/slang/slang-check-modifier.cpp b/source/slang/slang-check-modifier.cpp index c9800b325..413e1c157 100644 --- a/source/slang/slang-check-modifier.cpp +++ b/source/slang/slang-check-modifier.cpp @@ -1033,9 +1033,12 @@ namespace Slang case ASTNodeType::RayPayloadAccessSemantic: case ASTNodeType::RayPayloadReadSemantic: case ASTNodeType::RayPayloadWriteSemantic: - case ASTNodeType::GloballyCoherentModifier: return (as<VarDeclBase>(decl) && isGlobalDecl(decl)) || as<ParamDecl>(decl) || as<GLSLInterfaceBlockDecl>(decl); + case ASTNodeType::GloballyCoherentModifier: + case ASTNodeType::HLSLVolatileModifier: + return as<VarDecl>(decl) && (isGlobalDecl(decl) || as<StructDecl>(getParentDecl(decl)) || as<GLSLInterfaceBlockDecl>(decl)); + // Allowed only on parameters, struct fields and global variables. case ASTNodeType::InterpolationModeModifier: case ASTNodeType::HLSLNoInterpolationModifier: @@ -1090,7 +1093,6 @@ namespace Slang case ASTNodeType::HLSLColumnMajorLayoutModifier: case ASTNodeType::GLSLRowMajorLayoutModifier: case ASTNodeType::HLSLEffectSharedModifier: - case ASTNodeType::HLSLVolatileModifier: return as<VarDeclBase>(decl) || as<GLSLInterfaceBlockDecl>(decl); case ASTNodeType::GLSLPrecisionModifier: diff --git a/source/slang/slang-emit-glsl.cpp b/source/slang/slang-emit-glsl.cpp index bff82acf3..0fc0c855a 100644 --- a/source/slang/slang-emit-glsl.cpp +++ b/source/slang/slang-emit-glsl.cpp @@ -179,7 +179,7 @@ void GLSLSourceEmitter::_emitGLSLStructuredBuffer(IRGlobalParam* varDecl, IRHLSL m_writer->emit(space); } } - + m_writer->emit(") "); /* @@ -194,7 +194,10 @@ void GLSLSourceEmitter::_emitGLSLStructuredBuffer(IRGlobalParam* varDecl, IRHLSL HLSLAppendStructuredBufferType - Write HLSLConsumeStructuredBufferType - TODO (JS): Its possible that this can be readonly, but we currently don't support on GLSL */ - + if (varDecl->findDecoration<IRGloballyCoherentDecoration>()) + { + m_writer->emit("coherent "); + } if (as<IRHLSLStructuredBufferType>(structuredBufferType)) { m_writer->emit("readonly "); @@ -264,9 +267,13 @@ void GLSLSourceEmitter::_emitGLSLByteAddressBuffer(IRGlobalParam* varDecl, IRByt m_writer->emit(space); } } - m_writer->emit(") "); + if (varDecl->findDecoration<IRGloballyCoherentDecoration>()) + { + m_writer->emit("coherent "); + } + /* If the output type is a buffer, and we can determine it is only readonly we can prefix before buffer with 'readonly' diff --git a/source/slang/slang-emit-spirv.cpp b/source/slang/slang-emit-spirv.cpp index a2a0bff58..4e11a7d86 100644 --- a/source/slang/slang-emit-spirv.cpp +++ b/source/slang/slang-emit-spirv.cpp @@ -1836,6 +1836,14 @@ struct SPIRVEmitContext varInst, SpvLiteralInteger::from32(int32_t(index)) ); + if (space != 0) + { + emitOpDecorateIndex( + getSection(SpvLogicalSectionID::Annotations), + nullptr, + varInst, + SpvLiteralInteger::from32(int32_t(space))); + } break; case LayoutResourceKind::VaryingOutput: emitOpDecorateLocation( @@ -1844,6 +1852,14 @@ struct SPIRVEmitContext varInst, SpvLiteralInteger::from32(int32_t(index)) ); + if (space != 0) + { + emitOpDecorateIndex( + getSection(SpvLogicalSectionID::Annotations), + nullptr, + varInst, + SpvLiteralInteger::from32(int32_t(space))); + } break; case LayoutResourceKind::SpecializationConstant: @@ -1988,6 +2004,7 @@ struct SPIRVEmitContext if(layout) emitVarLayout(globalVar, varInst, layout); maybeEmitName(varInst, globalVar); + emitDecorations(globalVar, getID(varInst)); return varInst; } @@ -2743,10 +2760,6 @@ struct SPIRVEmitContext default: break; } - if (entryPointDecor->getProfile().getStage() == Stage::Fragment) - { - maybeEmitEntryPointDepthReplacingExecutionMode(entryPoint, referencedBuiltinIRVars); - } } // Add remaining builtin variables that does not have a corresponding IR global var/param. // These variables could be added from SPIRV ASM blocks. @@ -2769,7 +2782,19 @@ struct SPIRVEmitContext { case Stage::Fragment: //OpExecutionMode %main OriginUpperLeft - emitInst(getSection(SpvLogicalSectionID::ExecutionModes), nullptr, SpvOpExecutionMode, dstID, SpvExecutionModeOriginUpperLeft); + emitOpExecutionMode(getSection(SpvLogicalSectionID::ExecutionModes), nullptr, dstID, SpvExecutionModeOriginUpperLeft); + maybeEmitEntryPointDepthReplacingExecutionMode(entryPoint, referencedBuiltinIRVars); + for (auto decor : entryPoint->getDecorations()) + { + switch (decor->getOp()) + { + case kIROp_EarlyDepthStencilDecoration: + emitOpExecutionMode(getSection(SpvLogicalSectionID::ExecutionModes), nullptr, dstID, SpvExecutionModeEarlyFragmentTests); + break; + default: + break; + } + } break; case Stage::Geometry: requireSPIRVCapability(SpvCapabilityGeometry); @@ -2787,7 +2812,6 @@ struct SPIRVEmitContext } } break; - // > OpExecutionMode // [3.6. Execution Mode]: LocalSize @@ -2937,6 +2961,12 @@ struct SPIRVEmitContext dstID, SpvLiteralInteger::from32(int32_t(getIntVal(decoration->getOperand(0))))); break; + case kIROp_GloballyCoherentDecoration: + emitOpDecorate(getSection(SpvLogicalSectionID::Annotations), + decoration, + dstID, + SpvDecorationCoherent); + break; // ... } @@ -3007,14 +3037,40 @@ struct SPIRVEmitContext int32_t id = 0; for (auto field : structType->getFields()) { - if (auto fieldNameDecor = field->getKey()->findDecoration<IRNameHintDecoration>()) + for (auto decor : field->getKey()->getDecorations()) { - emitOpMemberName( - getSection(SpvLogicalSectionID::DebugNames), - nullptr, - spvStructID, - id, - fieldNameDecor->getName()); + if (auto fieldNameDecor = as<IRNameHintDecoration>(decor)) + { + emitOpMemberName( + getSection(SpvLogicalSectionID::DebugNames), + nullptr, + spvStructID, + id, + fieldNameDecor->getName()); + } + else if (as<IRGloballyCoherentDecoration>(decor)) + { + emitOpMemberDecorate( + getSection(SpvLogicalSectionID::Annotations), + decor, + spvStructID, + SpvLiteralInteger::from32(id), + SpvDecorationCoherent + ); + } + else if (auto semanticDecor = field->getKey()->findDecoration<IRSemanticDecoration>()) + { + if (shouldEmitSPIRVReflectionInfo()) + { + emitOpMemberDecorateString( + getSection(SpvLogicalSectionID::Annotations), + nullptr, + spvStructID, + SpvLiteralInteger::from32(id), + SpvDecorationUserSemantic, + semanticDecor->getSemanticName()); + } + } } IRIntegerValue offset = 0; @@ -3090,19 +3146,6 @@ struct SPIRVEmitContext SpvLiteralInteger::from32(id), SpvLiteralInteger::from32((int32_t)matrixStride)); } - if (shouldEmitSPIRVReflectionInfo()) - { - if (auto semanticDecor = field->getKey()->findDecoration<IRSemanticDecoration>()) - { - emitOpMemberDecorateString( - getSection(SpvLogicalSectionID::Annotations), - nullptr, - spvStructID, - SpvLiteralInteger::from32(id), - SpvDecorationUserSemantic, - semanticDecor->getSemanticName()); - } - } id++; } } diff --git a/source/slang/slang-ir-byte-address-legalize.cpp b/source/slang/slang-ir-byte-address-legalize.cpp index e405dd606..eec620133 100644 --- a/source/slang/slang-ir-byte-address-legalize.cpp +++ b/source/slang/slang-ir-byte-address-legalize.cpp @@ -717,6 +717,21 @@ struct ByteAddressBufferLegalizationContext return structuredBufferParam; } + void cloneBufferDecorations(IRBuilder& builder, IRInst* dest, IRInst* src) + { + for (auto decoration : src->getDecorations()) + { + switch (decoration->getOp()) + { + case kIROp_GloballyCoherentDecoration: + builder.addDecoration(dest, decoration->getOp()); + break; + default: + break; + } + } + } + IRGlobalParam* createEquivalentStructuredBufferParam(IRType* elementType, IRGlobalParam* byteAddressBufferParam) { // When we need to create a new structured buffer to stand in for @@ -751,7 +766,7 @@ struct ByteAddressBufferLegalizationContext { paramBuilder.addLayoutDecoration(structuredBufferParam, layoutDecoration->getLayout()); } - + cloneBufferDecorations(paramBuilder, structuredBufferParam, byteAddressBufferParam); return structuredBufferParam; } diff --git a/source/slang/slang-ir-glsl-legalize.cpp b/source/slang/slang-ir-glsl-legalize.cpp index 65efde214..0d279549c 100644 --- a/source/slang/slang-ir-glsl-legalize.cpp +++ b/source/slang/slang-ir-glsl-legalize.cpp @@ -1023,7 +1023,8 @@ ScalarizedVal createSimpleGLSLGlobalVarying( UInt bindingIndex, UInt bindingSpace, GlobalVaryingDeclarator* declarator, - IRInst* leafVar) + IRInst* leafVar, + StringBuilder& nameHintSB) { // Check if we have a system value on our hands. GLSLSystemValueInfo systemValueInfoStorage; @@ -1221,6 +1222,13 @@ ScalarizedVal createSimpleGLSLGlobalVarying( } } } + else + { + if (nameHintSB.getLength()) + { + builder->addNameHintDecoration(globalParam, nameHintSB.getUnownedSlice()); + } + } createVarLayoutForLegalizedGlobalParam( globalParam, builder, inVarLayout, typeLayout, kind, bindingIndex, bindingSpace, declarator, leafVar, systemValueInfo); @@ -1239,7 +1247,8 @@ ScalarizedVal createGLSLGlobalVaryingsImpl( UInt bindingIndex, UInt bindingSpace, GlobalVaryingDeclarator* declarator, - IRInst* leafVar) + IRInst* leafVar, + StringBuilder& nameHintSB) { if (as<IRVoidType>(type)) { @@ -1250,14 +1259,14 @@ ScalarizedVal createGLSLGlobalVaryingsImpl( return createSimpleGLSLGlobalVarying( context, codeGenContext, - builder, type, varLayout, typeLayout, kind, stage, bindingIndex, bindingSpace, declarator, leafVar); + builder, type, varLayout, typeLayout, kind, stage, bindingIndex, bindingSpace, declarator, leafVar, nameHintSB); } else if( as<IRVectorType>(type) ) { return createSimpleGLSLGlobalVarying( context, codeGenContext, - builder, type, varLayout, typeLayout, kind, stage, bindingIndex, bindingSpace, declarator, leafVar); + builder, type, varLayout, typeLayout, kind, stage, bindingIndex, bindingSpace, declarator, leafVar, nameHintSB); } else if( as<IRMatrixType>(type) ) { @@ -1265,7 +1274,7 @@ ScalarizedVal createGLSLGlobalVaryingsImpl( return createSimpleGLSLGlobalVarying( context, codeGenContext, - builder, type, varLayout, typeLayout, kind, stage, bindingIndex, bindingSpace, declarator, leafVar); + builder, type, varLayout, typeLayout, kind, stage, bindingIndex, bindingSpace, declarator, leafVar, nameHintSB); } else if( auto arrayType = as<IRArrayType>(type) ) { @@ -1294,7 +1303,8 @@ ScalarizedVal createGLSLGlobalVaryingsImpl( bindingIndex, bindingSpace, &arrayDeclarator, - leafVar); + leafVar, + nameHintSB); } else if( auto meshOutputType = as<IRMeshOutputType>(type)) { @@ -1337,7 +1347,8 @@ ScalarizedVal createGLSLGlobalVaryingsImpl( bindingIndex, bindingSpace, &arrayDeclarator, - leafVar); + leafVar, + nameHintSB); } else if( auto streamType = as<IRHLSLStreamOutputType>(type)) { @@ -1358,7 +1369,8 @@ ScalarizedVal createGLSLGlobalVaryingsImpl( bindingIndex, bindingSpace, declarator, - leafVar); + leafVar, + nameHintSB); } else if(auto structType = as<IRStructType>(type)) { @@ -1394,6 +1406,8 @@ ScalarizedVal createGLSLGlobalVaryingsImpl( // Okay, we want to walk through the fields here, and // generate one variable for each. UInt fieldCounter = 0; + auto nameSBLength = nameHintSB.getLength(); + for(auto field : structType->getFields()) { UInt fieldIndex = fieldCounter++; @@ -1407,7 +1421,13 @@ ScalarizedVal createGLSLGlobalVaryingsImpl( fieldBindingIndex += fieldResInfo->getOffset(); fieldBindingSpace += fieldResInfo->getSpace(); } - + nameHintSB.reduceLength(nameSBLength); + if (auto fieldNameHint = field->getKey()->findDecoration<IRNameHintDecoration>()) + { + if (nameHintSB.getLength() != 0) + nameHintSB << "."; + nameHintSB << fieldNameHint->getName(); + } auto fieldVal = createGLSLGlobalVaryingsImpl( context, codeGenContext, @@ -1420,7 +1440,8 @@ ScalarizedVal createGLSLGlobalVaryingsImpl( fieldBindingIndex, fieldBindingSpace, declarator, - field); + field, + nameHintSB); if (fieldVal.flavor != ScalarizedVal::Flavor::none) { ScalarizedTupleValImpl::Element element; @@ -1438,7 +1459,7 @@ ScalarizedVal createGLSLGlobalVaryingsImpl( return createSimpleGLSLGlobalVarying( context, codeGenContext, - builder, type, varLayout, typeLayout, kind, stage, bindingIndex, bindingSpace, declarator, leafVar); + builder, type, varLayout, typeLayout, kind, stage, bindingIndex, bindingSpace, declarator, leafVar, nameHintSB); } ScalarizedVal createGLSLGlobalVaryings( @@ -1458,10 +1479,15 @@ ScalarizedVal createGLSLGlobalVaryings( bindingIndex = rr->getOffset(); bindingSpace = rr->getSpace(); } + StringBuilder namehintSB; + if (auto nameHint = leafVar->findDecoration<IRNameHintDecoration>()) + { + namehintSB << nameHint->getName(); + } return createGLSLGlobalVaryingsImpl( context, codeGenContext, - builder, type, layout, layout->getTypeLayout(), kind, stage, bindingIndex, bindingSpace, nullptr, leafVar); + builder, type, layout, layout->getTypeLayout(), kind, stage, bindingIndex, bindingSpace, nullptr, leafVar, namehintSB); } ScalarizedVal extractField( diff --git a/source/slang/slang-ir-lower-buffer-element-type.cpp b/source/slang/slang-ir-lower-buffer-element-type.cpp index 378201fdb..6cd8495b4 100644 --- a/source/slang/slang-ir-lower-buffer-element-type.cpp +++ b/source/slang/slang-ir-lower-buffer-element-type.cpp @@ -515,7 +515,7 @@ namespace Slang elementType = constBuffer->getElementType(); if (as<IRTextureBufferType>(globalInst)) continue; - if (!as<IRStructType>(elementType) && !as<IRMatrixType>(elementType) && !as<IRArrayType>(elementType)) + if (!as<IRStructType>(elementType) && !as<IRMatrixType>(elementType) && !as<IRArrayType>(elementType) && !as<IRBoolType>(elementType)) continue; bufferTypeInsts.add(BufferTypeInfo{ (IRType*)globalInst, elementType }); } |
