summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2024-01-24 15:36:49 -0800
committerGitHub <noreply@github.com>2024-01-24 15:36:49 -0800
commite7b6de334f320429462a0257e2191ccf3cbc9a0d (patch)
tree7e2f6802a2f6fa5217903948efbd994b51e103b7 /source
parentdd57306d951dbcaf6471659fcd1d2c37738f36d0 (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.cpp6
-rw-r--r--source/slang/slang-emit-glsl.cpp13
-rw-r--r--source/slang/slang-emit-spirv.cpp95
-rw-r--r--source/slang/slang-ir-byte-address-legalize.cpp17
-rw-r--r--source/slang/slang-ir-glsl-legalize.cpp50
-rw-r--r--source/slang/slang-ir-lower-buffer-element-type.cpp2
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 });
}