[0042] - Texture Default Templates
| Status | Under Consideration |
|---|---|
| Author |
- PRs: #184207
Introduction
This proposal describes the design and implementation for supporting default
template arguments and shorthand notation for HLSL texture types (e.g.,
Texture2D) in HLSL. This allows these types to be used without template
arguments or with an empty template list (e.g., Texture2D or Texture2D<>),
defaulting to an element type of float4, matching the behavior of the DirectX
Shader Compiler (DXC) in HLSL202x.
Motivation
In HLSL, texture types are frequently used with a default element type of
float4. DXC allows developers to omit the template arguments entirely (e.g.,
Texture2D) or provide an empty template list (e.g., Texture2D<>).
Clang’s current implementation of HLSL resources requires explicit template arguments. Implementing this in Clang using standard C++ features like Class Template Argument Deduction (CTAD) is problematic because:
- HLSL202x does not support user-defined CTAD, and enabling it globally would diverge from DXC’s implementation.
- Resource handling in Clang (such as determining if a type is a resource via its handle and attributes) happens early in the compilation flow. Standard C++ template deduction occurs later, and many parts of the resource-specific semantic analysis expect a concrete type. Supporting “yet-to-be-deduced” resource types would require a significant and pervasive rewrite of the resource handling code in Clang.
The goal is to provide a surgical solution that matches DXC behavior while maintaining the integrity of Clang’s existing resource representation.
Proposed solution
The proposed solution involves two complementary mechanisms:
Default Template Parameter: Update the class template declarations for HLSL texture types in the HLSL External Sema Source to include a default template argument of
float4(represented asvector<float, 4>). This natively enables theTexture2D<>syntax in C++.Shorthand Notation Support: Introduce a special case in Clang’s semantic analysis to intercept the use of a template name without any template arguments. When an identifier for an HLSL texture type is encountered in a context where a type is expected, and it is identified as an HLSL resource template, Clang will automatically instantiate the template with its default parameters.
Detailed design
BuiltinTypeDeclBuilder Enhancements
The BuiltinTypeDeclBuilder utility, used to generate HLSL resource types in
the External Sema Source, is updated to support default template parameters:
BuiltinTypeDeclBuilder &
BuiltinTypeDeclBuilder::addSimpleTemplateParams(ArrayRef<StringRef> Names,
ArrayRef<QualType> DefaultValues,
ConceptDecl *CD);
This allows the registration code to specify float4 as the default for the
element_type parameter of texture types.
HLSLExternalSemaSource Integration
The initialization of texture types in HLSLExternalSemaSource.cpp is modified
to provide the default type. For Texture2D, it would look like:
QualType Float4Ty = AST.getExtVectorType(AST.FloatTy, 4);
Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "Texture2D")
.addSimpleTemplateParams({"element_type"}, {Float4Ty},
TypedBufferConcept)
.finalizeForwardDeclaration();
Semantic Analysis (Sema)
A new method, SemaHLSL::ActOnTemplateShorthand, is added to handle the
conversion of a template name to a concrete type:
- Intercepting Template Names: In
Sema::getTypeName, when an identifier is successfully resolved but identifies a template, and the language is HLSL,ActOnTemplateShorthandis called before falling back to Class Template Argument Deduction (CTAD) or erroring. - Validation: The function verifies that the template belongs to the
hlslnamespace and has default arguments for all its template parameters. - Synthesis: It iterates through the template parameters and retrieves the
default arguments from the declaration to construct a complete
TemplateArgumentListInfo. It then callsSema::CheckTemplateIdTypeto produce a fully qualifiedQualType.
Testing Strategy
- AST Verification: Use
-ast-dumpto ensure thatTexture2D,Texture2D<>, andTexture2D<float4>(and other texture types) all result in aClassTemplateSpecializationDeclwithfloat4as the template argument when shorthand or empty templates are used. - CodeGen Verification: Verify that variables declared with shorthand
notation correctly lower to LLVM IR with the expected target extension types
(e.g.,
target("dx.Texture", <4 x float>, ...)). - Binding and Semantics: Ensure that the shorthand types work correctly
with HLSL-specific features like
registerbindings and member function calls (e.g.,Sample). This tests that the texture can be identified as a resource early in the compilation.
Alternatives considered
Class Template Argument Deduction (CTAD)
As mentioned in the motivation, CTAD was considered but rejected because it is not officially supported in HLSL202x and would require significant architectural changes to handle undeduced resources in early Sema passes.
Type Aliases
We considered using typedef Texture2D<float4> Texture2D; or declaring a
non-template type alongside the template type. This was quickly rejected because
it would break the usual C++ lookup. Creating these types of special cases is
not a good solution.