summaryrefslogtreecommitdiffstats
path: root/source/slang/slang-check-decl.cpp
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2024-09-26 09:44:08 -0700
committerGitHub <noreply@github.com>2024-09-26 09:44:08 -0700
commit5a0224a0773f6d7f5eae8515424af5fa8faa9c14 (patch)
treeac14b54ad253d4ac5413a3c86254929f332b9e1a /source/slang/slang-check-decl.cpp
parent7398e1e09312ed4e19195e060de9a2c9a073fcc1 (diff)
Move texture format inference to frontend and add reflection api for it. (#5155)
Diffstat (limited to 'source/slang/slang-check-decl.cpp')
-rw-r--r--source/slang/slang-check-decl.cpp153
1 files changed, 148 insertions, 5 deletions
diff --git a/source/slang/slang-check-decl.cpp b/source/slang/slang-check-decl.cpp
index 2307c1669..4d742d9f4 100644
--- a/source/slang/slang-check-decl.cpp
+++ b/source/slang/slang-check-decl.cpp
@@ -93,7 +93,7 @@ namespace Slang
void checkDerivativeMemberAttributeParent(VarDeclBase* varDecl, DerivativeMemberAttribute* attr);
void checkExtensionExternVarAttribute(VarDeclBase* varDecl, ExtensionExternVarModifier* m);
void checkMeshOutputDecl(VarDeclBase* varDecl);
- void maybeApplyMatrixLayoutModifier(VarDeclBase* varDecl);
+ void maybeApplyLayoutModifier(VarDeclBase* varDecl);
void checkVarDeclCommon(VarDeclBase* varDecl);
void visitVarDecl(VarDecl* varDecl)
@@ -1518,7 +1518,122 @@ namespace Slang
}
}
}
- void SemanticsDeclHeaderVisitor::maybeApplyMatrixLayoutModifier(VarDeclBase* varDecl)
+
+ ImageFormat inferImageFormatFromTextureType(VarDeclBase* varDecl, TextureTypeBase* textureType, bool &outIsInferred)
+ {
+ outIsInferred = false;
+ ImageFormat format = ImageFormat::unknown;
+ if (auto formatVal = as<ConstantIntVal>(textureType->getFormat()))
+ {
+ format = (ImageFormat)formatVal->getValue();
+ }
+ if (format != ImageFormat::unknown)
+ return format;
+
+ if (auto formatAttrib = varDecl->findModifier<FormatAttribute>())
+ {
+ format = formatAttrib->format;
+ }
+ else
+ {
+ // If format is not specified explicitly through format attribute, we will derive a default
+ // value from the element format.
+ outIsInferred = true;
+ auto elementType = textureType->getElementType();
+ Int vectorWidth = 1;
+ if (auto elementVecType = as<VectorExpressionType>(elementType))
+ {
+ if (auto intLitVal = as<ConstantIntVal>(elementVecType->getElementCount()))
+ {
+ vectorWidth = (Int)intLitVal->getValue();
+ }
+ else
+ {
+ vectorWidth = 1;
+ }
+ elementType = elementVecType->getElementType();
+ }
+ if (auto basicType = as<BasicExpressionType>(elementType))
+ {
+ switch (basicType->getBaseType())
+ {
+ case BaseType::UInt:
+ switch (vectorWidth)
+ {
+ case 1: format = ImageFormat::r32ui; break;
+ case 2: format = ImageFormat::rg32ui; break;
+ case 4: format = ImageFormat::rgba32ui; break;
+ }
+ break;
+ case BaseType::Int:
+ switch (vectorWidth)
+ {
+ case 1: format = ImageFormat::r32i; break;
+ case 2: format = ImageFormat::rg32i; break;
+ case 4: format = ImageFormat::rgba32i; break;
+ }
+ break;
+ case BaseType::UInt16:
+ switch (vectorWidth)
+ {
+ case 1: format = ImageFormat::r16ui; break;
+ case 2: format = ImageFormat::rg16ui; break;
+ case 4: format = ImageFormat::rgba16ui; break;
+ }
+ break;
+ case BaseType::Int16:
+ switch (vectorWidth)
+ {
+ case 1: format = ImageFormat::r16i; break;
+ case 2: format = ImageFormat::rg16i; break;
+ case 4: format = ImageFormat::rgba16i; break;
+ }
+ break;
+ case BaseType::UInt8:
+ switch (vectorWidth)
+ {
+ case 1: format = ImageFormat::r8ui; break;
+ case 2: format = ImageFormat::rg8ui; break;
+ case 4: format = ImageFormat::rgba8ui; break;
+ }
+ break;
+ case BaseType::Int8:
+ switch (vectorWidth)
+ {
+ case 1: format = ImageFormat::r8i; break;
+ case 2: format = ImageFormat::rg8i; break;
+ case 4: format = ImageFormat::rgba8i; break;
+ }
+ break;
+ case BaseType::Int64:
+ switch (vectorWidth)
+ {
+ case 1: format = ImageFormat::r64i; break;
+ default: break;
+ }
+ break;
+ case BaseType::UInt64:
+ switch (vectorWidth)
+ {
+ case 1: format = ImageFormat::r64ui; break;
+ default: break;
+ }
+ break;
+ case BaseType::Half:
+ switch (vectorWidth)
+ {
+ case 1: format = ImageFormat::r16f; break;
+ case 2: format = ImageFormat::rg16f; break;
+ case 4: format = ImageFormat::rgba16f; break;
+ }
+ break;
+ }
+ }
+ }
+ return format;
+ }
+
+ void SemanticsDeclHeaderVisitor::maybeApplyLayoutModifier(VarDeclBase* varDecl)
{
if (auto matrixType = as<MatrixExpressionType>(varDecl->type.type))
{
@@ -1533,6 +1648,23 @@ namespace Slang
varDecl->type.type = newMatrixType;
}
}
+ else if (auto textureType = as<TextureTypeBase>(unwrapArrayType(varDecl->type.type)))
+ {
+ if (getLinkage()->m_optionSet.getBoolOption(CompilerOptionName::DefaultImageFormatUnknown))
+ return;
+
+ // For texture types, we will ensure there is a [format] attribute declared on the decl,
+ // if not, we will infer the format from the texture type if it is not specified.
+ //
+ bool isInferred = false;
+ auto format = inferImageFormatFromTextureType(varDecl, textureType, isInferred);
+ if (format != ImageFormat::unknown && isInferred)
+ {
+ auto formatAttrib = m_astBuilder->create<FormatAttribute>();
+ formatAttrib->format = format;
+ addModifier(varDecl, formatAttrib);
+ }
+ }
}
void SemanticsDeclHeaderVisitor::checkVarDeclCommon(VarDeclBase* varDecl)
@@ -1615,8 +1747,8 @@ namespace Slang
validateArraySizeForVariable(varDecl);
}
- // If there is a matrix layout modifier, we will modify the matrix type now.
- maybeApplyMatrixLayoutModifier(varDecl);
+ // If there is a matrix layout modifier or texture format modifier, we will modify the type now.
+ maybeApplyLayoutModifier(varDecl);
if (varDecl->initExpr)
{
@@ -2841,6 +2973,17 @@ namespace Slang
_registerBuiltinDeclsRec(session, decl);
}
+ Type* unwrapArrayType(Type* type)
+ {
+ for (;;)
+ {
+ if (auto arrayType = as<ArrayExpressionType>(type))
+ type = arrayType->getElementType();
+ else
+ return type;
+ }
+ }
+
void discoverExtensionDecls(List<ExtensionDecl*>& decls, Decl* parent)
{
if (auto extDecl = as<ExtensionDecl>(parent))
@@ -8190,7 +8333,7 @@ namespace Slang
}
}
- maybeApplyMatrixLayoutModifier(paramDecl);
+ maybeApplyLayoutModifier(paramDecl);
// Only texture types are allowed to have memory qualifiers on parameters
if(!paramDecl->type || paramDecl->type->astNodeType != ASTNodeType::TextureType)