Skip to content

Commit 8b406b5

Browse files
authored
Fix detection of builtin UDT DXR struct types (#7452)
Built-in DXR struct types RayDesc and BuiltInTriangleIntersectionAttributes were not treated identically to other UDT types. This caused differences in intrinsic codegen when one of these types is returned. This change corrects this difference so these builtin structs are handled in the same way as other UDTs. Fixes #7450.
1 parent f5214f1 commit 8b406b5

File tree

3 files changed

+54
-17
lines changed

3 files changed

+54
-17
lines changed

tools/clang/include/clang/AST/HlslTypes.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -494,7 +494,6 @@ DXIL::NodeIOKind GetNodeIOType(clang::QualType type);
494494

495495
bool IsHLSLStructuredBufferType(clang::QualType type);
496496
bool IsHLSLNumericOrAggregateOfNumericType(clang::QualType type);
497-
bool IsHLSLNumericUserDefinedType(clang::QualType type);
498497
bool IsHLSLCopyableAnnotatableRecord(clang::QualType QT);
499498
bool IsHLSLBuiltinRayAttributeStruct(clang::QualType QT);
500499
bool IsHLSLAggregateType(clang::QualType type);

tools/clang/lib/AST/HlslTypes.cpp

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -103,31 +103,26 @@ bool IsHLSLNumericOrAggregateOfNumericType(clang::QualType type) {
103103
BuiltinTy->getKind() != BuiltinType::Kind::Char_S;
104104
}
105105

106-
bool IsHLSLNumericUserDefinedType(clang::QualType type) {
107-
const clang::Type *Ty = type.getCanonicalType().getTypePtr();
106+
// In some cases we need record types that are annotatable and trivially
107+
// copyable from outside the shader. This excludes resource types which may be
108+
// trivially copyable inside the shader, and builtin matrix and vector types
109+
// which can't be annotated. But includes UDTs of trivially copyable data and
110+
// the builtin trivially copyable raytracing structs.
111+
bool IsHLSLCopyableAnnotatableRecord(clang::QualType QT) {
112+
const clang::Type *Ty = QT.getCanonicalType().getTypePtr();
108113
if (const RecordType *RT = dyn_cast<RecordType>(Ty)) {
109114
const RecordDecl *RD = RT->getDecl();
110-
if (!IsUserDefinedRecordType(type))
115+
if (!IsUserDefinedRecordType(QT))
111116
return false;
112-
for (auto member : RD->fields()) {
113-
if (!IsHLSLNumericOrAggregateOfNumericType(member->getType()))
117+
for (auto Member : RD->fields()) {
118+
if (!IsHLSLNumericOrAggregateOfNumericType(Member->getType()))
114119
return false;
115120
}
116121
return true;
117122
}
118123
return false;
119124
}
120125

121-
// In some cases we need record types that are annotatable and trivially
122-
// copyable from outside the shader. This excludes resource types which may be
123-
// trivially copyable inside the shader, and builtin matrix and vector types
124-
// which can't be annotated. But includes UDTs of trivially copyable data and
125-
// the builtin trivially copyable raytracing structs.
126-
bool IsHLSLCopyableAnnotatableRecord(clang::QualType QT) {
127-
return IsHLSLNumericUserDefinedType(QT) ||
128-
IsHLSLBuiltinRayAttributeStruct(QT);
129-
}
130-
131126
bool IsHLSLBuiltinRayAttributeStruct(clang::QualType QT) {
132127
QT = QT.getCanonicalType();
133128
const clang::Type *Ty = QT.getTypePtr();
@@ -609,7 +604,8 @@ bool IsUserDefinedRecordType(clang::QualType QT) {
609604
const clang::Type *Ty = QT.getCanonicalType().getTypePtr();
610605
if (const RecordType *RT = dyn_cast<RecordType>(Ty)) {
611606
const RecordDecl *RD = RT->getDecl();
612-
if (RD->isImplicit())
607+
// Built-in ray tracing struct types are considered user defined types.
608+
if (RD->isImplicit() && !IsHLSLBuiltinRayAttributeStruct(QT))
613609
return false;
614610
if (auto TD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
615611
if (TD->getSpecializedTemplate()->isImplicit())
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// RUN: %dxc /Tlib_6_9 %s | FileCheck %s
2+
// RUN: %dxc /Tlib_6_9 -fcgl %s | FileCheck %s -check-prefix=FCGL
3+
4+
// Make sure that we can use the BuiltInTriangleIntersectionAttributes struct
5+
// as a template argument to GetAttributes.
6+
7+
// For -fcgl, just check the form of the HL call.
8+
// FCGL: %{{[^ ]+}} = call %struct.BuiltInTriangleIntersectionAttributes* @"dx.hl.op..%struct.BuiltInTriangleIntersectionAttributes* (i32, %dx.types.HitObject*)"(i32 364, %dx.types.HitObject* %{{[^ ]+}})
9+
10+
// CHECK: %[[ATTR:[^ ]+]] = alloca %struct.BuiltInTriangleIntersectionAttributes
11+
// CHECK: call void @dx.op.hitObject_Attributes.struct.BuiltInTriangleIntersectionAttributes(i32 289, %dx.types.HitObject %{{[^ ]+}}, %struct.BuiltInTriangleIntersectionAttributes* nonnull %[[ATTR]])
12+
13+
RaytracingAccelerationStructure Scene : register(t0, space0);
14+
RWTexture2D<float4> RenderTarget : register(u0);
15+
16+
struct [raypayload] RayPayload
17+
{
18+
float4 color : write(caller, closesthit, miss) : read(caller);
19+
};
20+
21+
typedef BuiltInTriangleIntersectionAttributes MyAttribs;
22+
23+
[shader("raygeneration")]
24+
void MyRaygenShader()
25+
{
26+
RayDesc ray;
27+
ray.Origin = float3(0,0,0);
28+
ray.Direction = float3(0, 0, 1);
29+
ray.TMin = 0.001;
30+
ray.TMax = 10000.0;
31+
32+
RayPayload payload = { float4(0, 0, 0, 0) };
33+
float4 color = float4(1,1,1,1);
34+
35+
dx::HitObject hit = dx::HitObject::TraceRay(Scene, RAY_FLAG_NONE, ~0, 0, 1, 0, ray, payload);
36+
37+
MyAttribs attr = hit.GetAttributes<MyAttribs>();
38+
payload.color += float4(attr,0,1);
39+
40+
// Write the raytraced color to the output texture.
41+
RenderTarget[DispatchRaysIndex().xy] = payload.color;
42+
}

0 commit comments

Comments
 (0)