Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions lib/DXIL/DxilOperations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4081,6 +4081,7 @@ Function *OP::GetOpFunc(OpCode opCode, Type *pOverloadType) {
#define RRT(_y) A(GetResRetType(_y))
#define CBRT(_y) A(GetCBufferRetType(_y))
#define VEC4(_y) A(GetStructVectorType(4, _y))
#define VEC9(_y) A(VectorType::get(_y, 9))

// Extended Overload types are wrapped in an anonymous struct
#define EXT(_y) A(cast<StructType>(pOverloadType)->getElementType(_y))
Expand Down Expand Up @@ -6310,25 +6311,25 @@ Function *OP::GetOpFunc(OpCode opCode, Type *pOverloadType) {

// Raytracing System Values
case OpCode::TriangleObjectPosition:
A(pETy);
VEC9(pETy);
A(pI32);
break;

// Inline Ray Query
case OpCode::RayQuery_CandidateTriangleObjectPosition:
A(pETy);
VEC9(pETy);
A(pI32);
A(pI32);
break;
case OpCode::RayQuery_CommittedTriangleObjectPosition:
A(pETy);
VEC9(pETy);
A(pI32);
A(pI32);
break;

// Shader Execution Reordering
case OpCode::HitObject_TriangleObjectPosition:
A(pETy);
VEC9(pETy);
A(pI32);
A(pHit);
break;
Expand Down Expand Up @@ -6653,6 +6654,12 @@ llvm::Type *OP::GetOverloadType(OpCode opCode, llvm::Function *F) {
StructType *ST = cast<StructType>(Ty);
return ST->getElementType(0);
}
case OpCode::TriangleObjectPosition:
case OpCode::RayQuery_CandidateTriangleObjectPosition:
case OpCode::RayQuery_CommittedTriangleObjectPosition:
case OpCode::HitObject_TriangleObjectPosition:
// These return <9 x float> vectors directly
return cast<VectorType>(Ty)->getElementType();
case OpCode::MatVecMul:
case OpCode::MatVecMulAdd:
if (FT->getNumParams() < 2)
Expand Down
74 changes: 74 additions & 0 deletions tools/clang/test/DXILValidation/clusterid_passing.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
; RUN: %dxv %s | FileCheck %s

; CHECK: Validation succeeded.

target datalayout = "e-m:e-p:32:32-i1:32-i8:32-i16:32-i32:32-i64:64-f16:32-f32:32-f64:64-n8:16:32:64"
target triple = "dxil-ms-dx"

%dx.types.Handle = type { i8* }
%struct.Payload = type { <4 x float> }
%struct.BuiltInTriangleIntersectionAttributes = type { <2 x float> }
%dx.types.ResourceProperties = type { i32, i32 }
%dx.types.HitObject = type { i8* }

; Function Attrs: nounwind
define void @"\01?test_closesthit@@YAXUPayload@@UBuiltInTriangleIntersectionAttributes@@@Z"(%struct.Payload* noalias nocapture %payload, %struct.BuiltInTriangleIntersectionAttributes* nocapture readnone %attr) #0 {
%1 = call i32 @dx.op.clusterID(i32 2147483651) ; ClusterID()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When this is round-tripped through llvm, i32 2147483651 will become i32 -2147483645. In lowering tests, for example, CHECK lines will need to use i32 -2147483645 instead of the unsigned value.

Using the unsigned value here could create confusion and additional difficulty for updating tests when moving ops to final DXIL because one will need to use two search/replace expressions to update each opcode, in case the unsigned form is used somewhere.

For this reason, I recommend considering the signed i32 form the canonical one to use in all cases for consistency.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
%1 = call i32 @dx.op.clusterID(i32 2147483651) ; ClusterID()
%1 = call i32 @dx.op.clusterID(i32 -2147483645) ; ClusterID()

ret void
}

; Function Attrs: nounwind
define void @"\01?test_raygeneration@@YAXXZ"() #0 {
%1 = call %dx.types.HitObject @dx.op.hitObject_MakeNop(i32 266) ; HitObject_MakeNop()
%2 = call i32 @dx.op.hitObject_StateScalar.i32(i32 2147483654, %dx.types.HitObject %1) ; HitObject_ClusterID(hitObject)
%3 = call i32 @dx.op.allocateRayQuery(i32 178, i32 0) ; AllocateRayQuery(constRayFlags)
%4 = call i32 @dx.op.rayQuery_StateScalar.i32(i32 2147483652, i32 %3) ; RayQuery_CandidateClusterID(rayQueryHandle)
%5 = call i32 @dx.op.rayQuery_StateScalar.i32(i32 2147483653, i32 %3) ; RayQuery_CommittedClusterID(rayQueryHandle)
Comment on lines +22 to +26
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
%1 = call %dx.types.HitObject @dx.op.hitObject_MakeNop(i32 266) ; HitObject_MakeNop()
%2 = call i32 @dx.op.hitObject_StateScalar.i32(i32 2147483654, %dx.types.HitObject %1) ; HitObject_ClusterID(hitObject)
%3 = call i32 @dx.op.allocateRayQuery(i32 178, i32 0) ; AllocateRayQuery(constRayFlags)
%4 = call i32 @dx.op.rayQuery_StateScalar.i32(i32 2147483652, i32 %3) ; RayQuery_CandidateClusterID(rayQueryHandle)
%5 = call i32 @dx.op.rayQuery_StateScalar.i32(i32 2147483653, i32 %3) ; RayQuery_CommittedClusterID(rayQueryHandle)
%1 = call %dx.types.HitObject @dx.op.hitObject_MakeNop(i32 266) ; HitObject_MakeNop()
%2 = call i32 @dx.op.hitObject_StateScalar.i32(i32 -2147483642, %dx.types.HitObject %1) ; HitObject_ClusterID(hitObject)
%3 = call i32 @dx.op.allocateRayQuery(i32 178, i32 0) ; AllocateRayQuery(constRayFlags)
%4 = call i32 @dx.op.rayQuery_StateScalar.i32(i32 -2147483644, i32 %3) ; RayQuery_CandidateClusterID(rayQueryHandle)
%5 = call i32 @dx.op.rayQuery_StateScalar.i32(i32 -2147483643, i32 %3) ; RayQuery_CommittedClusterID(rayQueryHandle)

ret void
}

; Function Attrs: nounwind readnone
declare i32 @dx.op.clusterID(i32) #1

; Function Attrs: nounwind readnone
declare %dx.types.HitObject @dx.op.hitObject_MakeNop(i32) #1

; Function Attrs: nounwind readnone
declare i32 @dx.op.hitObject_StateScalar.i32(i32, %dx.types.HitObject) #1

; Function Attrs: nounwind
declare i32 @dx.op.allocateRayQuery(i32, i32) #0

; Function Attrs: nounwind readonly
declare i32 @dx.op.rayQuery_StateScalar.i32(i32, i32) #2

attributes #0 = { nounwind }
attributes #1 = { nounwind readnone }
attributes #2 = { nounwind readonly }

!dx.version = !{!0}
!dx.valver = !{!0}
!dx.shaderModel = !{!1}
!dx.typeAnnotations = !{!2}
!dx.dxrPayloadAnnotations = !{!9}
!dx.entryPoints = !{!12, !14, !17}

!0 = !{i32 1, i32 10}
!1 = !{!"lib", i32 6, i32 10}
!2 = !{i32 1, void (%struct.Payload*, %struct.BuiltInTriangleIntersectionAttributes*)* @"\01?test_closesthit@@YAXUPayload@@UBuiltInTriangleIntersectionAttributes@@@Z", !3, void ()* @"\01?test_raygeneration@@YAXXZ", !8}
!3 = !{!4, !6, !7}
!4 = !{i32 1, !5, !5}
!5 = !{}
!6 = !{i32 2, !5, !5}
!7 = !{i32 0, !5, !5}
!8 = !{!4}
!9 = !{i32 0, %struct.Payload undef, !10}
!10 = !{!11}
!11 = !{i32 0, i32 33}
!12 = !{null, !"", null, null, !13}
!13 = !{i32 0, i64 33554432}
!14 = !{void (%struct.Payload*, %struct.BuiltInTriangleIntersectionAttributes*)* @"\01?test_closesthit@@YAXUPayload@@UBuiltInTriangleIntersectionAttributes@@@Z", !"\01?test_closesthit@@YAXUPayload@@UBuiltInTriangleIntersectionAttributes@@@Z", null, null, !15}
!15 = !{i32 8, i32 10, i32 6, i32 16, i32 7, i32 8, i32 5, !16}
!16 = !{i32 0}
!17 = !{void ()* @"\01?test_raygeneration@@YAXXZ", !"\01?test_raygeneration@@YAXXZ", null, null, !18}
!18 = !{i32 8, i32 7, i32 5, !16}
77 changes: 77 additions & 0 deletions tools/clang/test/DXILValidation/triangle_position_passing.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
; RUN: %dxv %s | FileCheck %s

; CHECK: Validation succeeded.

target datalayout = "e-m:e-p:32:32-i1:32-i8:32-i16:32-i32:32-i64:64-f16:32-f32:32-f64:64-n8:16:32:64"
target triple = "dxil-ms-dx"

%dx.types.Handle = type { i8* }
%struct.Payload = type { <4 x float> }
%struct.BuiltInTriangleIntersectionAttributes = type { <2 x float> }
%dx.types.ResourceProperties = type { i32, i32 }
%dx.types.HitObject = type { i8* }

; Function Attrs: nounwind
define void @"\01?test_closesthit@@YAXUPayload@@UBuiltInTriangleIntersectionAttributes@@@Z"(%struct.Payload* noalias nocapture %payload, %struct.BuiltInTriangleIntersectionAttributes* nocapture readnone %attr) #0 {
%1 = call <9 x float> @dx.op.triangleObjectPosition.f32(i32 2147483655) ; TriangleObjectPosition()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
%1 = call <9 x float> @dx.op.triangleObjectPosition.f32(i32 2147483655) ; TriangleObjectPosition()
%1 = call <9 x float> @dx.op.triangleObjectPosition.f32(i32 -2147483641) ; TriangleObjectPosition()

ret void
}

; Function Attrs: nounwind
define void @"\01?test_raygeneration@@YAXXZ"() #0 {
%1 = call %dx.types.HitObject @dx.op.hitObject_MakeNop(i32 266) ; HitObject_MakeNop()
%2 = call <9 x float> @dx.op.hitObject_TriangleObjectPosition.f32(i32 2147483658, %dx.types.HitObject %1) ; HitObject_TriangleObjectPosition(hitObject)
%3 = call i32 @dx.op.allocateRayQuery(i32 178, i32 0) ; AllocateRayQuery(constRayFlags)
%4 = call <9 x float> @dx.op.rayQuery_CandidateTriangleObjectPosition.f32(i32 2147483656, i32 %3) ; RayQuery_CandidateTriangleObjectPosition(rayQueryHandle)
%5 = call <9 x float> @dx.op.rayQuery_CommittedTriangleObjectPosition.f32(i32 2147483657, i32 %3) ; RayQuery_CommittedTriangleObjectPosition(rayQueryHandle)
Comment on lines +22 to +26
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
%1 = call %dx.types.HitObject @dx.op.hitObject_MakeNop(i32 266) ; HitObject_MakeNop()
%2 = call <9 x float> @dx.op.hitObject_TriangleObjectPosition.f32(i32 2147483658, %dx.types.HitObject %1) ; HitObject_TriangleObjectPosition(hitObject)
%3 = call i32 @dx.op.allocateRayQuery(i32 178, i32 0) ; AllocateRayQuery(constRayFlags)
%4 = call <9 x float> @dx.op.rayQuery_CandidateTriangleObjectPosition.f32(i32 2147483656, i32 %3) ; RayQuery_CandidateTriangleObjectPosition(rayQueryHandle)
%5 = call <9 x float> @dx.op.rayQuery_CommittedTriangleObjectPosition.f32(i32 2147483657, i32 %3) ; RayQuery_CommittedTriangleObjectPosition(rayQueryHandle)
%1 = call %dx.types.HitObject @dx.op.hitObject_MakeNop(i32 266) ; HitObject_MakeNop()
%2 = call <9 x float> @dx.op.hitObject_TriangleObjectPosition.f32(i32 -2147483638, %dx.types.HitObject %1) ; HitObject_TriangleObjectPosition(hitObject)
%3 = call i32 @dx.op.allocateRayQuery(i32 178, i32 0) ; AllocateRayQuery(constRayFlags)
%4 = call <9 x float> @dx.op.rayQuery_CandidateTriangleObjectPosition.f32(i32 -2147483640, i32 %3) ; RayQuery_CandidateTriangleObjectPosition(rayQueryHandle)
%5 = call <9 x float> @dx.op.rayQuery_CommittedTriangleObjectPosition.f32(i32 -2147483639, i32 %3) ; RayQuery_CommittedTriangleObjectPosition(rayQueryHandle)

ret void
}

; Function Attrs: nounwind readnone
declare <9 x float> @dx.op.triangleObjectPosition.f32(i32) #1

; Function Attrs: nounwind readnone
declare <9 x float> @dx.op.hitObject_TriangleObjectPosition.f32(i32, %dx.types.HitObject) #1

; Function Attrs: nounwind readnone
declare %dx.types.HitObject @dx.op.hitObject_MakeNop(i32) #1

; Function Attrs: nounwind
declare i32 @dx.op.allocateRayQuery(i32, i32) #0

; Function Attrs: nounwind readonly
declare <9 x float> @dx.op.rayQuery_CandidateTriangleObjectPosition.f32(i32, i32) #2

; Function Attrs: nounwind readonly
declare <9 x float> @dx.op.rayQuery_CommittedTriangleObjectPosition.f32(i32, i32) #2

attributes #0 = { nounwind }
attributes #1 = { nounwind readnone }
attributes #2 = { nounwind readonly }

!dx.version = !{!0}
!dx.valver = !{!0}
!dx.shaderModel = !{!1}
!dx.typeAnnotations = !{!2}
!dx.dxrPayloadAnnotations = !{!9}
!dx.entryPoints = !{!12, !14, !17}

!0 = !{i32 1, i32 10}
!1 = !{!"lib", i32 6, i32 10}
!2 = !{i32 1, void (%struct.Payload*, %struct.BuiltInTriangleIntersectionAttributes*)* @"\01?test_closesthit@@YAXUPayload@@UBuiltInTriangleIntersectionAttributes@@@Z", !3, void ()* @"\01?test_raygeneration@@YAXXZ", !8}
!3 = !{!4, !6, !7}
!4 = !{i32 1, !5, !5}
!5 = !{}
!6 = !{i32 2, !5, !5}
!7 = !{i32 0, !5, !5}
!8 = !{!4}
!9 = !{i32 0, %struct.Payload undef, !10}
!10 = !{!11}
!11 = !{i32 0, i32 33}
!12 = !{null, !"", null, null, !13}
!13 = !{i32 0, i64 33554432}
!14 = !{void (%struct.Payload*, %struct.BuiltInTriangleIntersectionAttributes*)* @"\01?test_closesthit@@YAXUPayload@@UBuiltInTriangleIntersectionAttributes@@@Z", !"\01?test_closesthit@@YAXUPayload@@UBuiltInTriangleIntersectionAttributes@@@Z", null, null, !15}
!15 = !{i32 8, i32 10, i32 6, i32 16, i32 7, i32 8, i32 5, !16}
!16 = !{i32 0}
!17 = !{void ()* @"\01?test_raygeneration@@YAXXZ", !"\01?test_raygeneration@@YAXXZ", null, null, !18}
!18 = !{i32 8, i32 7, i32 5, !16}
8 changes: 4 additions & 4 deletions utils/hct/hctdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -6263,7 +6263,7 @@ def populate_ExperimentalOps(self):
"f",
"rn",
[
db_dxil_param(0, "$o", "", "operation result"), # TODO: $vec9
db_dxil_param(0, "$vec9", "", "operation result"),
],
)
add_dxil_op(
Expand All @@ -6273,7 +6273,7 @@ def populate_ExperimentalOps(self):
"f",
"ro",
[
db_dxil_param(0, "$o", "", "operation result"), # TODO: $vec9
db_dxil_param(0, "$vec9", "", "operation result"),
db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"),
],
)
Expand All @@ -6284,7 +6284,7 @@ def populate_ExperimentalOps(self):
"f",
"ro",
[
db_dxil_param(0, "$o", "", "operation result"), # TODO: $vec9
db_dxil_param(0, "$vec9", "", "operation result"),
db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"),
],
)
Expand All @@ -6295,7 +6295,7 @@ def populate_ExperimentalOps(self):
"f",
"rn",
[
db_dxil_param(0, "$o", "", "operation result"), # TODO: $vec9
db_dxil_param(0, "$vec9", "", "operation result"),
db_dxil_param(2, "hit_object", "hitObject", "hit"),
],
)
Expand Down
17 changes: 16 additions & 1 deletion utils/hct/hctdb_instrhelp.py
Original file line number Diff line number Diff line change
Expand Up @@ -630,6 +630,7 @@ def print_opfunc_table(self):
"u8": "A(pI8);",
"v": "A(pV);",
"$vec4": "VEC4(pETy);",
"$vec9": "VEC9(pETy);",
"SamplePos": "A(pPos);",
"$udt": "A(udt);",
"$obj": "A(obj);",
Expand Down Expand Up @@ -683,6 +684,7 @@ def print_opfunc_oload_type(self):
# grouped by the set of overload parameter indices.
extended_dict = collections.OrderedDict()
struct_list = []
vec9_list = [] # For $vec9 operations that return native vectors
extended_list = []

for instr in self.db.get_dxil_ops():
Expand All @@ -705,7 +707,11 @@ def print_opfunc_oload_type(self):
continue

if ret_ty.startswith(vec_ty):
struct_list.append(instr.name)
# $vec9 returns native <9 x float> vectors, not struct wrappers
if ret_ty == "$vec9":
vec9_list.append(instr.name)
else:
struct_list.append(instr.name)
continue

in_param_ty = False
Expand Down Expand Up @@ -822,6 +828,15 @@ def print_opfunc_oload_type(self):
line = line + "}"
print(line)

# Generate code for $vec9 operations (native <9 x float> vectors)
if vec9_list:
line = ""
for opcode in vec9_list:
line = line + "case OpCode::{name}".format(name=opcode + ":\n")
line = line + " // These return <9 x float> vectors directly\n"
line = line + " return cast<VectorType>(Ty)->getElementType();"
print(line)

for instr in extended_list:
# Collect indices for overloaded return and types, make a tuple of
# indices the key, and add the opcode to a list of opcodes for that
Expand Down