Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Shader Execution Reordering implementation #7094

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 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
138 changes: 138 additions & 0 deletions docs/HitObject.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
// == Prototype header for Shader Execution Reordering
//
// This is a partial implementation of the HitObject API building on lower-level
// Clang builtin functions and types. It is intended to inform the design and
// highlight challenges in implementing the HitObject API for HLSL in Clang,
// that is github.com/llvm/llvm-project. Limitations of the HLSL language make a
// complete header-only implementation impossible. Comments in the code discuss
// missing functions and why the header cannot implement them.

struct HitObject {
// Lower-level builtin type that lowers to %dx.types.HitObject in DXIL.
__builtin_HitObject handle;

// HLSL does not support constructors but HitObject needs adequate
// default initialization:
//
// HitObject() : handle(__builtin_HitObject_MakeNop())
// {}

template <typename payload_t>
static HitObject
TraceRay(RaytracingAccelerationStructure AccelerationStructure, uint RayFlags,
uint InstanceInclusionMask, uint RayContributionToHitGroupIndex,
uint MultiplierForGeometryContributionToHitGroupIndex,
uint MissShaderIndex, RayDesc Ray, inout payload_t Payload) {
HitObject ho;
ho.handle = __builtin_HitObject_TraceRay(
AccelerationStructure, RayFlags, InstanceInclusionMask,
RayContributionToHitGroupIndex,
MultiplierForGeometryContributionToHitGroupIndex, MissShaderIndex, Ray,
Payload);
return ho;
}
template <typename payload_t>
static void Invoke(in HitObject ho, inout payload_t Payload) {
__builtin_HitObject_Invoke(ho.handle, Payload);
}
template <uint rayFlags>
static HitObject FromRayQuery(in RayQuery<rayFlags> rq) {
HitObject ho;
ho.handle = __builtin_HitObject_FromRayQuery(rq);
return ho;
}
template <uint rayFlags, typename attr_t>
static HitObject FromRayQuery(in RayQuery<rayFlags> rq,
attr_t CommittedCustomAttribs) {
HitObject ho;
ho.handle = __builtin_HitObject_FromRayQuery(rq, CommittedCustomAttribs);
return ho;
}
static HitObject MakeMiss(in uint rayFlags, in uint missShaderIndex,
in RayDesc ray) {
HitObject ho;
ho.handle = __builtin_HitObject_MakeMiss(rayFlags, missShaderIndex, ray);
return ho;
}
static HitObject MakeNop() {
HitObject ho;
ho.handle = __builtin_HitObject_MakeNop();
return ho;
}
bool IsMiss() { return __builtin_HitObject_IsMiss(handle); }
bool IsHit() { return __builtin_HitObject_IsHit(handle); }
bool IsNop() { return __builtin_HitObject_IsNop(handle); }
uint GetRayFlags() { return __builtin_HitObject_GetRayFlags(handle); }
float GetRayTMin() { return __builtin_HitObject_GetRayTMin(handle); }
float GetRayTCurrent() { return __builtin_HitObject_GetRayTCurrent(handle); }
float3 GetWorldRayOrigin() {
return __builtin_HitObject_GetWorldRayOrigin(handle);
}
float3 GetWorldRayDirection() {
return __builtin_HitObject_GetWorldRayDirection(handle);
}
float3 GetObjectRayOrigin() {
return __builtin_HitObject_GetObjectRayOrigin(handle);
}
float3 GetObjectRayDirection() {
return __builtin_HitObject_GetObjectRayDirection(handle);
}
float3x4 GetObjectToWorld3x4() {
return __builtin_HitObject_GetObjectToWorld3x4(handle);
}
float4x3 GetObjectToWorld4x3() {
return __builtin_HitObject_GetObjectToWorld4x3(handle);
}
float3x4 GetWorldToObject3x4() {
return __builtin_HitObject_GetWorldToObject3x4(handle);
}
float4x3 GetWorldToObject4x3() {
return __builtin_HitObject_GetWorldToObject4x3(handle);
}
uint GetInstanceIndex() {
return __builtin_HitObject_GetInstanceIndex(handle);
}
uint GetInstanceID() { return __builtin_HitObject_GetInstanceID(handle); }
uint GetGeometryIndex() {
return __builtin_HitObject_GetGeometryIndex(handle);
}
uint GetPrimitiveIndex() {
return __builtin_HitObject_GetPrimitiveIndex(handle);
}
uint GetHitKind() { return __builtin_HitObject_GetHitKind(handle); }
template <typename attr_t> attr_t GetAttributes() {
// Any builtin that HitObject::GetAttribute() lowers to needs to have attr_t
// in its signature or Clang cannot infer attr_t for the builtins return
// type. This means the following does not work:
//
// return __builtin_HitObject_GetAttributes();
//
// One way to workaround is to make attrs an 'out' parameter of the builtin.
attr_t attrs;
__builtin_HitObject_GetAttributes(handle, attrs);
return attrs;
}
uint GetShaderTableIndex() {
return __builtin_HitObject_GetShaderTableIndex(handle);
}
void SetShaderTableIndex(in uint sbtRecordIdx) {
__builtin_HitObject_SetShaderTableIndex(handle, sbtRecordIdx);
}
uint LoadLocalRootTableConstant(in uint RootConstantOffsetInBytes) {
return __builtin_HitObject_LoadLocalRootTableConstant(
handle, RootConstantOffsetInBytes);
}
};
static void ReorderThread(in HitObject ho) {
__builtin_HitObject_ReorderThread(ho.handle);
}
static void ReorderThread(in uint CoherenceHint,
in uint NumCoherentsBitsFromLSB) {
__builtin_HitObject_ReorderThread(ho.handle, CoherenceHint,
NumCoherentsBitsFromLSB);
}
static void ReorderThread(in HitObject ho, in uint CoherenceHint,
in uint NumCoherentsBitsFromLSB) {
__builtin_HitObject_ReorderThread(ho.handle, CoherenceHint,
NumCoherentsBitsFromLSB);
}
95 changes: 87 additions & 8 deletions include/dxc/DXIL/DxilConstants.h
Original file line number Diff line number Diff line change
Expand Up @@ -857,6 +857,54 @@ enum class OpCode : unsigned {
WriteSamplerFeedbackLevel = 176, // updates a feedback texture for a sampling
// operation with a mipmap-level offset

// Shader Execution Reordering
HitObject_Attributes = 287, // Returns the attributes set for this HitObject
HitObject_FromRayQuery = 259, // Creates a new HitObject representing a
// committed hit from a RayQuery
HitObject_FromRayQueryWithAttrs =
260, // Creates a new HitObject representing a committed hit from a
// RayQuery and committed attributes
HitObject_GeometryIndex = 279, // Returns the geometry index committed on hit
HitObject_HitKind = 283, // Returns the HitKind of the hit
HitObject_InstanceID = 281, // Returns the instance id committed on hit
HitObject_InstanceIndex = 280, // Returns the instance index committed on hit
HitObject_Invoke = 263, // Represents the invocation of the CH/MS shader
// represented by the HitObject
HitObject_IsHit = 266, // Returns `true` if the HitObject is a NOP-HitObject
HitObject_IsMiss = 265, // Returns `true` if the HitObject represents a miss
HitObject_IsNop = 267, // Returns `true` if the HitObject represents a nop
HitObject_LoadLocalRootTableConstant =
286, // Returns the root table constant for this HitObject and offset
HitObject_MakeMiss = 261, // Creates a new HitObject representing a miss
HitObject_MakeNop = 262, // Creates an empty nop HitObject
HitObject_ObjectRayDirection =
274, // Returns the ray direction in object space
HitObject_ObjectRayOrigin = 273, // Returns the ray origin in object space
HitObject_ObjectToWorld3x4 = 275, // Returns the object to world space
// transformation matrix in 3x4 form
HitObject_ObjectToWorld4x3 = 276, // Returns the object to world space
// transformation matrix in 4x3 form
HitObject_PrimitiveIndex =
282, // Returns the primitive index committed on hit
HitObject_RayFlags = 268, // Returns the ray flags set in the HitObject
HitObject_RayTCurrent =
270, // Returns the current T value set in the HitObject
HitObject_RayTMin = 269, // Returns the TMin value set in the HitObject
HitObject_SetShaderTableIndex =
285, // Returns a HitObject with updated shader table index
HitObject_ShaderTableIndex =
284, // Returns the shader table index set for this HitObject
HitObject_TraceRay = 258, // Analogous to TraceRay but without invoking CH/MS
// and returns the intermediate state as a HitObject
HitObject_WorldRayDirection = 272, // Returns the ray direction in world space
HitObject_WorldRayOrigin = 271, // Returns the ray origin in world space
HitObject_WorldToObject3x4 = 277, // Returns the world to object space
// transformation matrix in 3x4 form
HitObject_WorldToObject4x3 = 278, // Returns the world to object space
// transformation matrix in 4x3 form
ReorderThread = 264, // Reorders the current thread. Optionally accepts a
// HitObject arg, or undef

// Synchronization
AtomicBinOp = 78, // performs an atomic operation on two operands
AtomicCompareExchange = 79, // atomic compare and exchange to memory
Expand Down Expand Up @@ -983,9 +1031,9 @@ enum class OpCode : unsigned {
NumOpCodes_Dxil_1_5 = 216,
NumOpCodes_Dxil_1_6 = 222,
NumOpCodes_Dxil_1_7 = 226,
NumOpCodes_Dxil_1_8 = 258,
NumOpCodes_Dxil_1_8 = 288,

NumOpCodes = 258 // exclusive last value of enumeration
NumOpCodes = NumOpCodes_Dxil_1_8 // exclusive last value of enumeration
};
// OPCODE-ENUM:END

Expand Down Expand Up @@ -1282,6 +1330,21 @@ enum class OpCodeClass : unsigned {
NodeOutputIsValid,
OutputComplete,

// Shader Execution Reordering
HitObject_Attributes,
HitObject_FromRayQuery,
HitObject_FromRayQueryWithAttrs,
HitObject_Invoke,
HitObject_LoadLocalRootTableConstant,
HitObject_MakeMiss,
HitObject_MakeNop,
HitObject_SetShaderTableIndex,
HitObject_StateMatrix,
HitObject_StateScalar,
HitObject_StateVector,
HitObject_TraceRay,
ReorderThread,

NumOpClasses_Dxil_1_0 = 93,
NumOpClasses_Dxil_1_1 = 95,
NumOpClasses_Dxil_1_2 = 97,
Expand All @@ -1290,9 +1353,9 @@ enum class OpCodeClass : unsigned {
NumOpClasses_Dxil_1_5 = 143,
NumOpClasses_Dxil_1_6 = 149,
NumOpClasses_Dxil_1_7 = 153,
NumOpClasses_Dxil_1_8 = 174,
NumOpClasses_Dxil_1_8 = 196,

NumOpClasses = 174 // exclusive last value of enumeration
NumOpClasses = NumOpClasses_Dxil_1_8 // exclusive last value of enumeration
};
// OPCODECLASS-ENUM:END

Expand Down Expand Up @@ -1450,6 +1513,21 @@ const unsigned kMSStoreOutputColOpIdx = 3;
const unsigned kMSStoreOutputVIdxOpIdx = 4;
const unsigned kMSStoreOutputValOpIdx = 5;

// HitObject::TraceRay
const unsigned kHitObjectTraceRay_RayDescOpIdx = 7;
const unsigned kHitObjectTraceRay_PayloadOpIdx = 15;
const unsigned kHitObjectTraceRay_NumOp = 16;

// HitObject::MakeMiss
const unsigned kHitObjectMakeMiss_RayDescOpIdx = 3;
const unsigned kHitObjectMakeMiss_NumOp = 11;

// ReorderThread
const unsigned kReorderThreadHitObjectOpIdx = 1;
const unsigned kReorderThreadCoherenceHintOpIdx = 2;
const unsigned kReorderThreadNumCoherenceHintBitsOpIdx = 3;
const unsigned kReorderThreadNumOp = 4;

// TODO: add operand index for all the OpCodeClass.
} // namespace OperandIndex

Expand Down Expand Up @@ -1816,10 +1894,11 @@ enum class MemoryTypeFlag : uint32_t {

// Corresponds to SEMANTIC_FLAG enums in HLSL
enum class BarrierSemanticFlag : uint32_t {
GroupSync = 0x00000001, // GROUP_SYNC
GroupScope = 0x00000002, // GROUP_SCOPE
DeviceScope = 0x00000004, // DEVICE_SCOPE
ValidMask = 0x00000007,
GroupSync = 0x00000001, // GROUP_SYNC
GroupScope = 0x00000002, // GROUP_SCOPE
DeviceScope = 0x00000004, // DEVICE_SCOPE
ReorderScope = 0x00000008, // REORDER_SCOPE
ValidMask = 0x0000000F,
GroupFlags = GroupSync | GroupScope,
};

Expand Down
Loading
Loading