2
0
Эх сурвалжийг харах

Support user define type for dxil operation.
Add RayTracingAccelerationStructure to dxil resource.
Lower ReportIntersection and TraceRay.

Xiang Li 7 жил өмнө
parent
commit
eb4b0ae768

+ 164 - 145
docs/DXIL.rst

@@ -1993,151 +1993,170 @@ Opcodes are defined on a dense range and will be provided as enum in a header fi
 .. <py::lines('OPCODES-RST')>hctdb_instrhelp.get_opcodes_rst()</py>
 .. <py::lines('OPCODES-RST')>hctdb_instrhelp.get_opcodes_rst()</py>
 .. OPCODES-RST:BEGIN
 .. OPCODES-RST:BEGIN
 
 
-=== ============================= =================================================================================================================
-ID  Name                          Description
-=== ============================= =================================================================================================================
-0   TempRegLoad_                  Helper load operation
-1   TempRegStore_                 Helper store operation
-2   MinPrecXRegLoad_              Helper load operation for minprecision
-3   MinPrecXRegStore_             Helper store operation for minprecision
-4   LoadInput_                    Loads the value from shader input
-5   StoreOutput_                  Stores the value to shader output
-6   FAbs_                         returns the absolute value of the input value.
-7   Saturate_                     clamps the result of a single or double precision floating point value to [0.0f...1.0f]
-8   IsNaN_                        Returns true if x is NAN or QNAN, false otherwise.
-9   IsInf_                        Returns true if x is +INF or -INF, false otherwise.
-10  IsFinite_                     Returns true if x is finite, false otherwise.
-11  IsNormal_                     returns IsNormal
-12  Cos_                          returns cosine(theta) for theta in radians.
-13  Sin_                          returns sine(theta) for theta in radians.
-14  Tan_                          returns tan(theta) for theta in radians.
-15  Acos_                         Returns the arccosine of the specified value. Input should be a floating-point value within the range of -1 to 1.
-16  Asin_                         Returns the arccosine of the specified value. Input should be a floating-point value within the range of -1 to 1
-17  Atan_                         Returns the arctangent of the specified value. The return value is within the range of -PI/2 to PI/2.
-18  Hcos_                         returns the hyperbolic cosine of the specified value.
-19  Hsin_                         returns the hyperbolic sine of the specified value.
-20  Htan_                         returns the hyperbolic tangent of the specified value.
-21  Exp_                          returns 2^exponent
-22  Frc_                          extract fracitonal component.
-23  Log_                          returns log base 2.
-24  Sqrt_                         returns square root
-25  Rsqrt_                        returns reciprocal square root (1 / sqrt(src)
-26  Round_ne_                     floating-point round to integral float.
-27  Round_ni_                     floating-point round to integral float.
-28  Round_pi_                     floating-point round to integral float.
-29  Round_z_                      floating-point round to integral float.
-30  Bfrev_                        Reverses the order of the bits.
-31  Countbits_                    Counts the number of bits in the input integer.
-32  FirstbitLo_                   Returns the location of the first set bit starting from the lowest order bit and working upward.
-33  FirstbitHi_                   Returns the location of the first set bit starting from the highest order bit and working downward.
-34  FirstbitSHi_                  Returns the location of the first set bit from the highest order bit based on the sign.
-35  FMax_                         returns a if a >= b, else b
-36  FMin_                         returns a if a < b, else b
-37  IMax_                         IMax(a,b) returns a if a > b, else b
-38  IMin_                         IMin(a,b) returns a if a < b, else b
-39  UMax_                         unsigned integer maximum. UMax(a,b) = a > b ? a : b
-40  UMin_                         unsigned integer minimum. UMin(a,b) = a < b ? a : b
-41  IMul_                         multiply of 32-bit operands to produce the correct full 64-bit result.
-42  UMul_                         multiply of 32-bit operands to produce the correct full 64-bit result.
-43  UDiv_                         unsigned divide of the 32-bit operand src0 by the 32-bit operand src1.
-44  UAddc_                        unsigned add of 32-bit operand with the carry
-45  USubb_                        unsigned subtract of 32-bit operands with the borrow
-46  FMad_                         floating point multiply & add
-47  Fma_                          fused multiply-add
-48  IMad_                         Signed integer multiply & add
-49  UMad_                         Unsigned integer multiply & add
-50  Msad_                         masked Sum of Absolute Differences.
-51  Ibfe_                         Integer bitfield extract
-52  Ubfe_                         Unsigned integer bitfield extract
-53  Bfi_                          Given a bit range from the LSB of a number, places that number of bits in another number at any offset
-54  Dot2_                         Two-dimensional vector dot-product
-55  Dot3_                         Three-dimensional vector dot-product
-56  Dot4_                         Four-dimensional vector dot-product
-57  CreateHandle                  creates the handle to a resource
-58  CBufferLoad                   loads a value from a constant buffer resource
-59  CBufferLoadLegacy             loads a value from a constant buffer resource
-60  Sample                        samples a texture
-61  SampleBias                    samples a texture after applying the input bias to the mipmap level
-62  SampleLevel                   samples a texture using a mipmap-level offset
-63  SampleGrad                    samples a texture using a gradient to influence the way the sample location is calculated
-64  SampleCmp                     samples a texture and compares a single component against the specified comparison value
-65  SampleCmpLevelZero            samples a texture and compares a single component against the specified comparison value
-66  TextureLoad                   reads texel data without any filtering or sampling
-67  TextureStore                  reads texel data without any filtering or sampling
-68  BufferLoad                    reads from a TypedBuffer
-69  BufferStore                   writes to a RWTypedBuffer
-70  BufferUpdateCounter           atomically increments/decrements the hidden 32-bit counter stored with a Count or Append UAV
-71  CheckAccessFullyMapped        determines whether all values from a Sample, Gather, or Load operation accessed mapped tiles in a tiled resource
-72  GetDimensions                 gets texture size information
-73  TextureGather                 gathers the four texels that would be used in a bi-linear filtering operation
-74  TextureGatherCmp              same as TextureGather, except this instrution performs comparison on texels, similar to SampleCmp
-75  Texture2DMSGetSamplePosition  gets the position of the specified sample
-76  RenderTargetGetSamplePosition gets the position of the specified sample
-77  RenderTargetGetSampleCount    gets the number of samples for a render target
-78  AtomicBinOp                   performs an atomic operation on two operands
-79  AtomicCompareExchange         atomic compare and exchange to memory
-80  Barrier                       inserts a memory barrier in the shader
-81  CalculateLOD                  calculates the level of detail
-82  Discard                       discard the current pixel
-83  DerivCoarseX_                 computes the rate of change per stamp in x direction.
-84  DerivCoarseY_                 computes the rate of change per stamp in y direction.
-85  DerivFineX_                   computes the rate of change per pixel in x direction.
-86  DerivFineY_                   computes the rate of change per pixel in y direction.
-87  EvalSnapped                   evaluates an input attribute at pixel center with an offset
-88  EvalSampleIndex               evaluates an input attribute at a sample location
-89  EvalCentroid                  evaluates an input attribute at pixel center
-90  SampleIndex                   returns the sample index in a sample-frequency pixel shader
-91  Coverage                      returns the coverage mask input in a pixel shader
-92  InnerCoverage                 returns underestimated coverage input from conservative rasterization in a pixel shader
-93  ThreadId                      reads the thread ID
-94  GroupId                       reads the group ID (SV_GroupID)
-95  ThreadIdInGroup               reads the thread ID within the group (SV_GroupThreadID)
-96  FlattenedThreadIdInGroup      provides a flattened index for a given thread within a given group (SV_GroupIndex)
-97  EmitStream                    emits a vertex to a given stream
-98  CutStream                     completes the current primitive topology at the specified stream
-99  EmitThenCutStream             equivalent to an EmitStream followed by a CutStream
-100 GSInstanceID                  GSInstanceID
-101 MakeDouble                    creates a double value
-102 SplitDouble                   splits a double into low and high parts
-103 LoadOutputControlPoint        LoadOutputControlPoint
-104 LoadPatchConstant             LoadPatchConstant
-105 DomainLocation                DomainLocation
-106 StorePatchConstant            StorePatchConstant
-107 OutputControlPointID          OutputControlPointID
-108 PrimitiveID                   PrimitiveID
-109 CycleCounterLegacy            CycleCounterLegacy
-110 WaveIsFirstLane               returns 1 for the first lane in the wave
-111 WaveGetLaneIndex              returns the index of the current lane in the wave
-112 WaveGetLaneCount              returns the number of lanes in the wave
-113 WaveAnyTrue                   returns 1 if any of the lane evaluates the value to true
-114 WaveAllTrue                   returns 1 if all the lanes evaluate the value to true
-115 WaveActiveAllEqual            returns 1 if all the lanes have the same value
-116 WaveActiveBallot              returns a struct with a bit set for each lane where the condition is true
-117 WaveReadLaneAt                returns the value from the specified lane
-118 WaveReadLaneFirst             returns the value from the first lane
-119 WaveActiveOp                  returns the result the operation across waves
-120 WaveActiveBit                 returns the result of the operation across all lanes
-121 WavePrefixOp                  returns the result of the operation on prior lanes
-122 QuadReadLaneAt                reads from a lane in the quad
-123 QuadOp                        returns the result of a quad-level operation
-124 BitcastI16toF16               bitcast between different sizes
-125 BitcastF16toI16               bitcast between different sizes
-126 BitcastI32toF32               bitcast between different sizes
-127 BitcastF32toI32               bitcast between different sizes
-128 BitcastI64toF64               bitcast between different sizes
-129 BitcastF64toI64               bitcast between different sizes
-130 LegacyF32ToF16                legacy fuction to convert float (f32) to half (f16) (this is not related to min-precision)
-131 LegacyF16ToF32                legacy fuction to convert half (f16) to float (f32) (this is not related to min-precision)
-132 LegacyDoubleToFloat           legacy fuction to convert double to float
-133 LegacyDoubleToSInt32          legacy fuction to convert double to int32
-134 LegacyDoubleToUInt32          legacy fuction to convert double to uint32
-135 WaveAllBitCount               returns the count of bits set to 1 across the wave
-136 WavePrefixBitCount            returns the count of bits set to 1 on prior lanes
-137 AttributeAtVertex_            returns the values of the attributes at the vertex.
-138 ViewID                        returns the view index
-139 RawBufferLoad                 reads from a raw buffer and structured buffer
-140 RawBufferStore                writes to a RWByteAddressBuffer or RWStructuredBuffer
-=== ============================= =================================================================================================================
+=== ============================================ =======================================================================================================================================================================================================================
+ID  Name                                         Description
+=== ============================================ =======================================================================================================================================================================================================================
+0   TempRegLoad_                                 Helper load operation
+1   TempRegStore_                                Helper store operation
+2   MinPrecXRegLoad_                             Helper load operation for minprecision
+3   MinPrecXRegStore_                            Helper store operation for minprecision
+4   LoadInput_                                   Loads the value from shader input
+5   StoreOutput_                                 Stores the value to shader output
+6   FAbs_                                        returns the absolute value of the input value.
+7   Saturate_                                    clamps the result of a single or double precision floating point value to [0.0f...1.0f]
+8   IsNaN_                                       Returns true if x is NAN or QNAN, false otherwise.
+9   IsInf_                                       Returns true if x is +INF or -INF, false otherwise.
+10  IsFinite_                                    Returns true if x is finite, false otherwise.
+11  IsNormal_                                    returns IsNormal
+12  Cos_                                         returns cosine(theta) for theta in radians.
+13  Sin_                                         returns sine(theta) for theta in radians.
+14  Tan_                                         returns tan(theta) for theta in radians.
+15  Acos_                                        Returns the arccosine of the specified value. Input should be a floating-point value within the range of -1 to 1.
+16  Asin_                                        Returns the arccosine of the specified value. Input should be a floating-point value within the range of -1 to 1
+17  Atan_                                        Returns the arctangent of the specified value. The return value is within the range of -PI/2 to PI/2.
+18  Hcos_                                        returns the hyperbolic cosine of the specified value.
+19  Hsin_                                        returns the hyperbolic sine of the specified value.
+20  Htan_                                        returns the hyperbolic tangent of the specified value.
+21  Exp_                                         returns 2^exponent
+22  Frc_                                         extract fracitonal component.
+23  Log_                                         returns log base 2.
+24  Sqrt_                                        returns square root
+25  Rsqrt_                                       returns reciprocal square root (1 / sqrt(src)
+26  Round_ne_                                    floating-point round to integral float.
+27  Round_ni_                                    floating-point round to integral float.
+28  Round_pi_                                    floating-point round to integral float.
+29  Round_z_                                     floating-point round to integral float.
+30  Bfrev_                                       Reverses the order of the bits.
+31  Countbits_                                   Counts the number of bits in the input integer.
+32  FirstbitLo_                                  Returns the location of the first set bit starting from the lowest order bit and working upward.
+33  FirstbitHi_                                  Returns the location of the first set bit starting from the highest order bit and working downward.
+34  FirstbitSHi_                                 Returns the location of the first set bit from the highest order bit based on the sign.
+35  FMax_                                        returns a if a >= b, else b
+36  FMin_                                        returns a if a < b, else b
+37  IMax_                                        IMax(a,b) returns a if a > b, else b
+38  IMin_                                        IMin(a,b) returns a if a < b, else b
+39  UMax_                                        unsigned integer maximum. UMax(a,b) = a > b ? a : b
+40  UMin_                                        unsigned integer minimum. UMin(a,b) = a < b ? a : b
+41  IMul_                                        multiply of 32-bit operands to produce the correct full 64-bit result.
+42  UMul_                                        multiply of 32-bit operands to produce the correct full 64-bit result.
+43  UDiv_                                        unsigned divide of the 32-bit operand src0 by the 32-bit operand src1.
+44  UAddc_                                       unsigned add of 32-bit operand with the carry
+45  USubb_                                       unsigned subtract of 32-bit operands with the borrow
+46  FMad_                                        floating point multiply & add
+47  Fma_                                         fused multiply-add
+48  IMad_                                        Signed integer multiply & add
+49  UMad_                                        Unsigned integer multiply & add
+50  Msad_                                        masked Sum of Absolute Differences.
+51  Ibfe_                                        Integer bitfield extract
+52  Ubfe_                                        Unsigned integer bitfield extract
+53  Bfi_                                         Given a bit range from the LSB of a number, places that number of bits in another number at any offset
+54  Dot2_                                        Two-dimensional vector dot-product
+55  Dot3_                                        Three-dimensional vector dot-product
+56  Dot4_                                        Four-dimensional vector dot-product
+57  CreateHandle                                 creates the handle to a resource
+58  CBufferLoad                                  loads a value from a constant buffer resource
+59  CBufferLoadLegacy                            loads a value from a constant buffer resource
+60  Sample                                       samples a texture
+61  SampleBias                                   samples a texture after applying the input bias to the mipmap level
+62  SampleLevel                                  samples a texture using a mipmap-level offset
+63  SampleGrad                                   samples a texture using a gradient to influence the way the sample location is calculated
+64  SampleCmp                                    samples a texture and compares a single component against the specified comparison value
+65  SampleCmpLevelZero                           samples a texture and compares a single component against the specified comparison value
+66  TextureLoad                                  reads texel data without any filtering or sampling
+67  TextureStore                                 reads texel data without any filtering or sampling
+68  BufferLoad                                   reads from a TypedBuffer
+69  BufferStore                                  writes to a RWTypedBuffer
+70  BufferUpdateCounter                          atomically increments/decrements the hidden 32-bit counter stored with a Count or Append UAV
+71  CheckAccessFullyMapped                       determines whether all values from a Sample, Gather, or Load operation accessed mapped tiles in a tiled resource
+72  GetDimensions                                gets texture size information
+73  TextureGather                                gathers the four texels that would be used in a bi-linear filtering operation
+74  TextureGatherCmp                             same as TextureGather, except this instrution performs comparison on texels, similar to SampleCmp
+75  Texture2DMSGetSamplePosition                 gets the position of the specified sample
+76  RenderTargetGetSamplePosition                gets the position of the specified sample
+77  RenderTargetGetSampleCount                   gets the number of samples for a render target
+78  AtomicBinOp                                  performs an atomic operation on two operands
+79  AtomicCompareExchange                        atomic compare and exchange to memory
+80  Barrier                                      inserts a memory barrier in the shader
+81  CalculateLOD                                 calculates the level of detail
+82  Discard                                      discard the current pixel
+83  DerivCoarseX_                                computes the rate of change per stamp in x direction.
+84  DerivCoarseY_                                computes the rate of change per stamp in y direction.
+85  DerivFineX_                                  computes the rate of change per pixel in x direction.
+86  DerivFineY_                                  computes the rate of change per pixel in y direction.
+87  EvalSnapped                                  evaluates an input attribute at pixel center with an offset
+88  EvalSampleIndex                              evaluates an input attribute at a sample location
+89  EvalCentroid                                 evaluates an input attribute at pixel center
+90  SampleIndex                                  returns the sample index in a sample-frequency pixel shader
+91  Coverage                                     returns the coverage mask input in a pixel shader
+92  InnerCoverage                                returns underestimated coverage input from conservative rasterization in a pixel shader
+93  ThreadId                                     reads the thread ID
+94  GroupId                                      reads the group ID (SV_GroupID)
+95  ThreadIdInGroup                              reads the thread ID within the group (SV_GroupThreadID)
+96  FlattenedThreadIdInGroup                     provides a flattened index for a given thread within a given group (SV_GroupIndex)
+97  EmitStream                                   emits a vertex to a given stream
+98  CutStream                                    completes the current primitive topology at the specified stream
+99  EmitThenCutStream                            equivalent to an EmitStream followed by a CutStream
+100 GSInstanceID                                 GSInstanceID
+101 MakeDouble                                   creates a double value
+102 SplitDouble                                  splits a double into low and high parts
+103 LoadOutputControlPoint                       LoadOutputControlPoint
+104 LoadPatchConstant                            LoadPatchConstant
+105 DomainLocation                               DomainLocation
+106 StorePatchConstant                           StorePatchConstant
+107 OutputControlPointID                         OutputControlPointID
+108 PrimitiveID                                  PrimitiveID
+109 CycleCounterLegacy                           CycleCounterLegacy
+110 WaveIsFirstLane                              returns 1 for the first lane in the wave
+111 WaveGetLaneIndex                             returns the index of the current lane in the wave
+112 WaveGetLaneCount                             returns the number of lanes in the wave
+113 WaveAnyTrue                                  returns 1 if any of the lane evaluates the value to true
+114 WaveAllTrue                                  returns 1 if all the lanes evaluate the value to true
+115 WaveActiveAllEqual                           returns 1 if all the lanes have the same value
+116 WaveActiveBallot                             returns a struct with a bit set for each lane where the condition is true
+117 WaveReadLaneAt                               returns the value from the specified lane
+118 WaveReadLaneFirst                            returns the value from the first lane
+119 WaveActiveOp                                 returns the result the operation across waves
+120 WaveActiveBit                                returns the result of the operation across all lanes
+121 WavePrefixOp                                 returns the result of the operation on prior lanes
+122 QuadReadLaneAt                               reads from a lane in the quad
+123 QuadOp                                       returns the result of a quad-level operation
+124 BitcastI16toF16                              bitcast between different sizes
+125 BitcastF16toI16                              bitcast between different sizes
+126 BitcastI32toF32                              bitcast between different sizes
+127 BitcastF32toI32                              bitcast between different sizes
+128 BitcastI64toF64                              bitcast between different sizes
+129 BitcastF64toI64                              bitcast between different sizes
+130 LegacyF32ToF16                               legacy fuction to convert float (f32) to half (f16) (this is not related to min-precision)
+131 LegacyF16ToF32                               legacy fuction to convert half (f16) to float (f32) (this is not related to min-precision)
+132 LegacyDoubleToFloat                          legacy fuction to convert double to float
+133 LegacyDoubleToSInt32                         legacy fuction to convert double to int32
+134 LegacyDoubleToUInt32                         legacy fuction to convert double to uint32
+135 WaveAllBitCount                              returns the count of bits set to 1 across the wave
+136 WavePrefixBitCount                           returns the count of bits set to 1 on prior lanes
+137 AttributeAtVertex_                           returns the values of the attributes at the vertex.
+138 ViewID                                       returns the view index
+139 RawBufferLoad                                reads from a raw buffer and structured buffer
+140 RawBufferStore                               writes to a RWByteAddressBuffer or RWStructuredBuffer
+141 InstanceIndex                                The autogenerated index of the current instance in the top-level structure
+142 HitKind                                      Returns the value passed as HitKind in ReportIntersection().  If intersection was reported by fixed-function triangle intersection, HitKind will be one of HIT_KIND_TRIANGLE_FRONT_FACE or HIT_KIND_TRIANGLE_BACK_FACE.
+143 RayFlag                                      uint containing the current ray flags.
+144 RayDispatchIndex                             The current x and y location within the Width and Height
+145 RayDispatchDimension                         The Width and Height values from the D3D12_DISPATCH_RAYS_DESC structure provided to the originating DispatchRays() call.
+146 WorldRayOrigin                               The world-space origin for the current ray.
+147 WorldRayDirection                            The world-space direction for the current ray.
+148 ObjectRayOrigin                              Object-space origin for the current ray.
+149 ObjectRayDirection                           Object-space direction for the current ray.
+150 ObjectToWorld                                Matrix for transforming from object-space to world-space.
+151 WorldToObject                                Matrix for transforming from world-space to object-space.
+152 RayTMin                                      float representing the parametric starting point for the ray.
+153 CurrentRayT                                  float representing the current parametric ending point for the ray
+154 IgnoreIntersection                           returns the view index
+155 TerminateRay                                 returns the view index
+156 TraceRay                                     returns the view index
+157 ReportIntersection                           returns true if hit was accepted
+158 CallShader                                   returns the view index
+159 ReservedForLibCreateHandleFromResourceStruct returns the view index
+=== ============================================ =======================================================================================================================================================================================================================
 
 
 
 
 Acos
 Acos

+ 53 - 2
include/dxc/HLSL/DxilConstants.h

@@ -278,6 +278,7 @@ namespace DXIL {
     CBuffer,
     CBuffer,
     Sampler,
     Sampler,
     TBuffer,
     TBuffer,
+    RTAccelerationStructure,
     NumEntries,
     NumEntries,
   };
   };
 
 
@@ -381,6 +382,27 @@ namespace DXIL {
     // Quaternary
     // Quaternary
     Bfi = 53, // Given a bit range from the LSB of a number, places that number of bits in another number at any offset
     Bfi = 53, // Given a bit range from the LSB of a number, places that number of bits in another number at any offset
   
   
+    // Ray Tracing
+    CallShader = 158, // returns the view index
+    CurrentRayT = 153, // float representing the current parametric ending point for the ray
+    HitKind = 142, // Returns the value passed as HitKind in ReportIntersection().  If intersection was reported by fixed-function triangle intersection, HitKind will be one of HIT_KIND_TRIANGLE_FRONT_FACE or HIT_KIND_TRIANGLE_BACK_FACE.
+    IgnoreIntersection = 154, // returns the view index
+    InstanceIndex = 141, // The autogenerated index of the current instance in the top-level structure
+    ObjectRayDirection = 149, // Object-space direction for the current ray.
+    ObjectRayOrigin = 148, // Object-space origin for the current ray.
+    ObjectToWorld = 150, // Matrix for transforming from object-space to world-space.
+    RayDispatchDimension = 145, // The Width and Height values from the D3D12_DISPATCH_RAYS_DESC structure provided to the originating DispatchRays() call.
+    RayDispatchIndex = 144, // The current x and y location within the Width and Height
+    RayFlag = 143, // uint containing the current ray flags.
+    RayTMin = 152, // float representing the parametric starting point for the ray.
+    ReportIntersection = 157, // returns true if hit was accepted
+    ReservedForLibCreateHandleFromResourceStruct = 159, // returns the view index
+    TerminateRay = 155, // returns the view index
+    TraceRay = 156, // returns the view index
+    WorldRayDirection = 147, // The world-space direction for the current ray.
+    WorldRayOrigin = 146, // The world-space origin for the current ray.
+    WorldToObject = 151, // Matrix for transforming from world-space to object-space.
+  
     // Resources - gather
     // Resources - gather
     TextureGather = 73, // gathers the four texels that would be used in a bi-linear filtering operation
     TextureGather = 73, // gathers the four texels that would be used in a bi-linear filtering operation
     TextureGatherCmp = 74, // same as TextureGather, except this instrution performs comparison on texels, similar to SampleCmp
     TextureGatherCmp = 74, // same as TextureGather, except this instrution performs comparison on texels, similar to SampleCmp
@@ -494,8 +516,9 @@ namespace DXIL {
     NumOpCodes_Dxil_1_0 = 137,
     NumOpCodes_Dxil_1_0 = 137,
     NumOpCodes_Dxil_1_1 = 139,
     NumOpCodes_Dxil_1_1 = 139,
     NumOpCodes_Dxil_1_2 = 141,
     NumOpCodes_Dxil_1_2 = 141,
+    NumOpCodes_Dxil_1_3 = 160,
   
   
-    NumOpCodes = 141 // exclusive last value of enumeration
+    NumOpCodes = 160 // exclusive last value of enumeration
   };
   };
   // OPCODE-ENUM:END
   // OPCODE-ENUM:END
 
 
@@ -584,6 +607,27 @@ namespace DXIL {
     // Quaternary
     // Quaternary
     Quaternary,
     Quaternary,
   
   
+    // Ray Tracing
+    CallShader,
+    CurrentRayT,
+    HitKind,
+    IgnoreIntersection,
+    InstanceIndex,
+    ObjectRayDirection,
+    ObjectRayOrigin,
+    ObjectToWorld,
+    RayDispatchDimension,
+    RayDispatchIndex,
+    RayFlag,
+    RayTMin,
+    ReportIntersection,
+    ReservedForLibCreateHandleFromResourceStruct,
+    TerminateRay,
+    TraceRay,
+    WorldRayDirection,
+    WorldRayOrigin,
+    WorldToObject,
+  
     // Resources - gather
     // Resources - gather
     TextureGather,
     TextureGather,
     TextureGatherCmp,
     TextureGatherCmp,
@@ -655,8 +699,9 @@ namespace DXIL {
     NumOpClasses_Dxil_1_0 = 93,
     NumOpClasses_Dxil_1_0 = 93,
     NumOpClasses_Dxil_1_1 = 95,
     NumOpClasses_Dxil_1_1 = 95,
     NumOpClasses_Dxil_1_2 = 97,
     NumOpClasses_Dxil_1_2 = 97,
+    NumOpClasses_Dxil_1_3 = 116,
   
   
-    NumOpClasses = 97 // exclusive last value of enumeration
+    NumOpClasses = 116 // exclusive last value of enumeration
   };
   };
   // OPCODECLASS-ENUM:END
   // OPCODECLASS-ENUM:END
 
 
@@ -778,6 +823,12 @@ namespace DXIL {
     const unsigned kCreateHandleResIndexOpIdx = 3;
     const unsigned kCreateHandleResIndexOpIdx = 3;
     const unsigned kCreateHandleIsUniformOpIdx = 4;
     const unsigned kCreateHandleIsUniformOpIdx = 4;
 
 
+    // TraceRay
+    const unsigned kTraceRayRayDescOpIdx = 7;
+    const unsigned kTraceRayPayloadOpIdx = 15;
+    const unsigned kTraceRayNumOp = 16;
+
+
     // Emit/Cut
     // Emit/Cut
     const unsigned kStreamEmitCutIDOpIdx = 1;
     const unsigned kStreamEmitCutIDOpIdx = 1;
     // TODO: add operand index for all the OpCodeClass.
     // TODO: add operand index for all the OpCodeClass.

+ 438 - 0
include/dxc/HLSL/DxilInstructions.h

@@ -4540,5 +4540,443 @@ struct DxilInst_RawBufferStore {
   int32_t get_alignment_val() const { return (int32_t)(llvm::dyn_cast<llvm::ConstantInt>(Instr->getOperand(9))->getZExtValue()); }
   int32_t get_alignment_val() const { return (int32_t)(llvm::dyn_cast<llvm::ConstantInt>(Instr->getOperand(9))->getZExtValue()); }
   void set_alignment_val(int32_t val) { Instr->setOperand(9, llvm::Constant::getIntegerValue(llvm::IntegerType::get(Instr->getContext(), 32), llvm::APInt(32, (uint64_t)val))); }
   void set_alignment_val(int32_t val) { Instr->setOperand(9, llvm::Constant::getIntegerValue(llvm::IntegerType::get(Instr->getContext(), 32), llvm::APInt(32, (uint64_t)val))); }
 };
 };
+
+/// This instruction The autogenerated index of the current instance in the top-level structure
+struct DxilInst_InstanceIndex {
+  llvm::Instruction *Instr;
+  // Construction and identification
+  DxilInst_InstanceIndex(llvm::Instruction *pInstr) : Instr(pInstr) {}
+  operator bool() const {
+    return hlsl::OP::IsDxilOpFuncCallInst(Instr, hlsl::OP::OpCode::InstanceIndex);
+  }
+  // Validation support
+  bool isAllowed() const { return true; }
+  bool isArgumentListValid() const {
+    if (1 != llvm::dyn_cast<llvm::CallInst>(Instr)->getNumArgOperands()) return false;
+    return true;
+  }
+};
+
+/// This instruction Returns the value passed as HitKind in ReportIntersection().  If intersection was reported by fixed-function triangle intersection, HitKind will be one of HIT_KIND_TRIANGLE_FRONT_FACE or HIT_KIND_TRIANGLE_BACK_FACE.
+struct DxilInst_HitKind {
+  llvm::Instruction *Instr;
+  // Construction and identification
+  DxilInst_HitKind(llvm::Instruction *pInstr) : Instr(pInstr) {}
+  operator bool() const {
+    return hlsl::OP::IsDxilOpFuncCallInst(Instr, hlsl::OP::OpCode::HitKind);
+  }
+  // Validation support
+  bool isAllowed() const { return true; }
+  bool isArgumentListValid() const {
+    if (1 != llvm::dyn_cast<llvm::CallInst>(Instr)->getNumArgOperands()) return false;
+    return true;
+  }
+};
+
+/// This instruction uint containing the current ray flags.
+struct DxilInst_RayFlag {
+  llvm::Instruction *Instr;
+  // Construction and identification
+  DxilInst_RayFlag(llvm::Instruction *pInstr) : Instr(pInstr) {}
+  operator bool() const {
+    return hlsl::OP::IsDxilOpFuncCallInst(Instr, hlsl::OP::OpCode::RayFlag);
+  }
+  // Validation support
+  bool isAllowed() const { return true; }
+  bool isArgumentListValid() const {
+    if (1 != llvm::dyn_cast<llvm::CallInst>(Instr)->getNumArgOperands()) return false;
+    return true;
+  }
+};
+
+/// This instruction The current x and y location within the Width and Height
+struct DxilInst_RayDispatchIndex {
+  llvm::Instruction *Instr;
+  // Construction and identification
+  DxilInst_RayDispatchIndex(llvm::Instruction *pInstr) : Instr(pInstr) {}
+  operator bool() const {
+    return hlsl::OP::IsDxilOpFuncCallInst(Instr, hlsl::OP::OpCode::RayDispatchIndex);
+  }
+  // Validation support
+  bool isAllowed() const { return true; }
+  bool isArgumentListValid() const {
+    if (2 != llvm::dyn_cast<llvm::CallInst>(Instr)->getNumArgOperands()) return false;
+    return true;
+  }
+  // Operand indexes
+  enum OperandIdx {
+    arg_col = 1,
+  };
+  // Accessors
+  llvm::Value *get_col() const { return Instr->getOperand(1); }
+  void set_col(llvm::Value *val) { Instr->setOperand(1, val); }
+};
+
+/// This instruction The Width and Height values from the D3D12_DISPATCH_RAYS_DESC structure provided to the originating DispatchRays() call.
+struct DxilInst_RayDispatchDimension {
+  llvm::Instruction *Instr;
+  // Construction and identification
+  DxilInst_RayDispatchDimension(llvm::Instruction *pInstr) : Instr(pInstr) {}
+  operator bool() const {
+    return hlsl::OP::IsDxilOpFuncCallInst(Instr, hlsl::OP::OpCode::RayDispatchDimension);
+  }
+  // Validation support
+  bool isAllowed() const { return true; }
+  bool isArgumentListValid() const {
+    if (2 != llvm::dyn_cast<llvm::CallInst>(Instr)->getNumArgOperands()) return false;
+    return true;
+  }
+  // Operand indexes
+  enum OperandIdx {
+    arg_col = 1,
+  };
+  // Accessors
+  llvm::Value *get_col() const { return Instr->getOperand(1); }
+  void set_col(llvm::Value *val) { Instr->setOperand(1, val); }
+};
+
+/// This instruction The world-space origin for the current ray.
+struct DxilInst_WorldRayOrigin {
+  llvm::Instruction *Instr;
+  // Construction and identification
+  DxilInst_WorldRayOrigin(llvm::Instruction *pInstr) : Instr(pInstr) {}
+  operator bool() const {
+    return hlsl::OP::IsDxilOpFuncCallInst(Instr, hlsl::OP::OpCode::WorldRayOrigin);
+  }
+  // Validation support
+  bool isAllowed() const { return true; }
+  bool isArgumentListValid() const {
+    if (2 != llvm::dyn_cast<llvm::CallInst>(Instr)->getNumArgOperands()) return false;
+    return true;
+  }
+  // Operand indexes
+  enum OperandIdx {
+    arg_col = 1,
+  };
+  // Accessors
+  llvm::Value *get_col() const { return Instr->getOperand(1); }
+  void set_col(llvm::Value *val) { Instr->setOperand(1, val); }
+};
+
+/// This instruction The world-space direction for the current ray.
+struct DxilInst_WorldRayDirection {
+  llvm::Instruction *Instr;
+  // Construction and identification
+  DxilInst_WorldRayDirection(llvm::Instruction *pInstr) : Instr(pInstr) {}
+  operator bool() const {
+    return hlsl::OP::IsDxilOpFuncCallInst(Instr, hlsl::OP::OpCode::WorldRayDirection);
+  }
+  // Validation support
+  bool isAllowed() const { return true; }
+  bool isArgumentListValid() const {
+    if (2 != llvm::dyn_cast<llvm::CallInst>(Instr)->getNumArgOperands()) return false;
+    return true;
+  }
+  // Operand indexes
+  enum OperandIdx {
+    arg_col = 1,
+  };
+  // Accessors
+  llvm::Value *get_col() const { return Instr->getOperand(1); }
+  void set_col(llvm::Value *val) { Instr->setOperand(1, val); }
+};
+
+/// This instruction Object-space origin for the current ray.
+struct DxilInst_ObjectRayOrigin {
+  llvm::Instruction *Instr;
+  // Construction and identification
+  DxilInst_ObjectRayOrigin(llvm::Instruction *pInstr) : Instr(pInstr) {}
+  operator bool() const {
+    return hlsl::OP::IsDxilOpFuncCallInst(Instr, hlsl::OP::OpCode::ObjectRayOrigin);
+  }
+  // Validation support
+  bool isAllowed() const { return true; }
+  bool isArgumentListValid() const {
+    if (2 != llvm::dyn_cast<llvm::CallInst>(Instr)->getNumArgOperands()) return false;
+    return true;
+  }
+  // Operand indexes
+  enum OperandIdx {
+    arg_col = 1,
+  };
+  // Accessors
+  llvm::Value *get_col() const { return Instr->getOperand(1); }
+  void set_col(llvm::Value *val) { Instr->setOperand(1, val); }
+};
+
+/// This instruction Object-space direction for the current ray.
+struct DxilInst_ObjectRayDirection {
+  llvm::Instruction *Instr;
+  // Construction and identification
+  DxilInst_ObjectRayDirection(llvm::Instruction *pInstr) : Instr(pInstr) {}
+  operator bool() const {
+    return hlsl::OP::IsDxilOpFuncCallInst(Instr, hlsl::OP::OpCode::ObjectRayDirection);
+  }
+  // Validation support
+  bool isAllowed() const { return true; }
+  bool isArgumentListValid() const {
+    if (2 != llvm::dyn_cast<llvm::CallInst>(Instr)->getNumArgOperands()) return false;
+    return true;
+  }
+  // Operand indexes
+  enum OperandIdx {
+    arg_col = 1,
+  };
+  // Accessors
+  llvm::Value *get_col() const { return Instr->getOperand(1); }
+  void set_col(llvm::Value *val) { Instr->setOperand(1, val); }
+};
+
+/// This instruction Matrix for transforming from object-space to world-space.
+struct DxilInst_ObjectToWorld {
+  llvm::Instruction *Instr;
+  // Construction and identification
+  DxilInst_ObjectToWorld(llvm::Instruction *pInstr) : Instr(pInstr) {}
+  operator bool() const {
+    return hlsl::OP::IsDxilOpFuncCallInst(Instr, hlsl::OP::OpCode::ObjectToWorld);
+  }
+  // Validation support
+  bool isAllowed() const { return true; }
+  bool isArgumentListValid() const {
+    if (3 != llvm::dyn_cast<llvm::CallInst>(Instr)->getNumArgOperands()) return false;
+    return true;
+  }
+  // Operand indexes
+  enum OperandIdx {
+    arg_row = 1,
+    arg_col = 2,
+  };
+  // Accessors
+  llvm::Value *get_row() const { return Instr->getOperand(1); }
+  void set_row(llvm::Value *val) { Instr->setOperand(1, val); }
+  llvm::Value *get_col() const { return Instr->getOperand(2); }
+  void set_col(llvm::Value *val) { Instr->setOperand(2, val); }
+};
+
+/// This instruction Matrix for transforming from world-space to object-space.
+struct DxilInst_WorldToObject {
+  llvm::Instruction *Instr;
+  // Construction and identification
+  DxilInst_WorldToObject(llvm::Instruction *pInstr) : Instr(pInstr) {}
+  operator bool() const {
+    return hlsl::OP::IsDxilOpFuncCallInst(Instr, hlsl::OP::OpCode::WorldToObject);
+  }
+  // Validation support
+  bool isAllowed() const { return true; }
+  bool isArgumentListValid() const {
+    if (3 != llvm::dyn_cast<llvm::CallInst>(Instr)->getNumArgOperands()) return false;
+    return true;
+  }
+  // Operand indexes
+  enum OperandIdx {
+    arg_row = 1,
+    arg_col = 2,
+  };
+  // Accessors
+  llvm::Value *get_row() const { return Instr->getOperand(1); }
+  void set_row(llvm::Value *val) { Instr->setOperand(1, val); }
+  llvm::Value *get_col() const { return Instr->getOperand(2); }
+  void set_col(llvm::Value *val) { Instr->setOperand(2, val); }
+};
+
+/// This instruction float representing the parametric starting point for the ray.
+struct DxilInst_RayTMin {
+  llvm::Instruction *Instr;
+  // Construction and identification
+  DxilInst_RayTMin(llvm::Instruction *pInstr) : Instr(pInstr) {}
+  operator bool() const {
+    return hlsl::OP::IsDxilOpFuncCallInst(Instr, hlsl::OP::OpCode::RayTMin);
+  }
+  // Validation support
+  bool isAllowed() const { return true; }
+  bool isArgumentListValid() const {
+    if (1 != llvm::dyn_cast<llvm::CallInst>(Instr)->getNumArgOperands()) return false;
+    return true;
+  }
+};
+
+/// This instruction float representing the current parametric ending point for the ray
+struct DxilInst_CurrentRayT {
+  llvm::Instruction *Instr;
+  // Construction and identification
+  DxilInst_CurrentRayT(llvm::Instruction *pInstr) : Instr(pInstr) {}
+  operator bool() const {
+    return hlsl::OP::IsDxilOpFuncCallInst(Instr, hlsl::OP::OpCode::CurrentRayT);
+  }
+  // Validation support
+  bool isAllowed() const { return true; }
+  bool isArgumentListValid() const {
+    if (1 != llvm::dyn_cast<llvm::CallInst>(Instr)->getNumArgOperands()) return false;
+    return true;
+  }
+};
+
+/// This instruction returns the view index
+struct DxilInst_IgnoreIntersection {
+  llvm::Instruction *Instr;
+  // Construction and identification
+  DxilInst_IgnoreIntersection(llvm::Instruction *pInstr) : Instr(pInstr) {}
+  operator bool() const {
+    return hlsl::OP::IsDxilOpFuncCallInst(Instr, hlsl::OP::OpCode::IgnoreIntersection);
+  }
+  // Validation support
+  bool isAllowed() const { return true; }
+  bool isArgumentListValid() const {
+    if (1 != llvm::dyn_cast<llvm::CallInst>(Instr)->getNumArgOperands()) return false;
+    return true;
+  }
+};
+
+/// This instruction returns the view index
+struct DxilInst_TerminateRay {
+  llvm::Instruction *Instr;
+  // Construction and identification
+  DxilInst_TerminateRay(llvm::Instruction *pInstr) : Instr(pInstr) {}
+  operator bool() const {
+    return hlsl::OP::IsDxilOpFuncCallInst(Instr, hlsl::OP::OpCode::TerminateRay);
+  }
+  // Validation support
+  bool isAllowed() const { return true; }
+  bool isArgumentListValid() const {
+    if (1 != llvm::dyn_cast<llvm::CallInst>(Instr)->getNumArgOperands()) return false;
+    return true;
+  }
+};
+
+/// This instruction returns the view index
+struct DxilInst_TraceRay {
+  llvm::Instruction *Instr;
+  // Construction and identification
+  DxilInst_TraceRay(llvm::Instruction *pInstr) : Instr(pInstr) {}
+  operator bool() const {
+    return hlsl::OP::IsDxilOpFuncCallInst(Instr, hlsl::OP::OpCode::TraceRay);
+  }
+  // Validation support
+  bool isAllowed() const { return true; }
+  bool isArgumentListValid() const {
+    if (16 != llvm::dyn_cast<llvm::CallInst>(Instr)->getNumArgOperands()) return false;
+    return true;
+  }
+  // Operand indexes
+  enum OperandIdx {
+    arg_AccelerationStructure = 1,
+    arg_RayFlags = 2,
+    arg_InstanceInclusionMask = 3,
+    arg_RayContributionToHitGroupIndex = 4,
+    arg_MultiplierForGeometryContributionToShaderIndex = 5,
+    arg_MissShaderIndex = 6,
+    arg_Origin_X = 7,
+    arg_Origin_Y = 8,
+    arg_Origin_Z = 9,
+    arg_TMin = 10,
+    arg_Direction_X = 11,
+    arg_Direction_Y = 12,
+    arg_Direction_Z = 13,
+    arg_TMax = 14,
+    arg_payload = 15,
+  };
+  // Accessors
+  llvm::Value *get_AccelerationStructure() const { return Instr->getOperand(1); }
+  void set_AccelerationStructure(llvm::Value *val) { Instr->setOperand(1, val); }
+  llvm::Value *get_RayFlags() const { return Instr->getOperand(2); }
+  void set_RayFlags(llvm::Value *val) { Instr->setOperand(2, val); }
+  llvm::Value *get_InstanceInclusionMask() const { return Instr->getOperand(3); }
+  void set_InstanceInclusionMask(llvm::Value *val) { Instr->setOperand(3, val); }
+  llvm::Value *get_RayContributionToHitGroupIndex() const { return Instr->getOperand(4); }
+  void set_RayContributionToHitGroupIndex(llvm::Value *val) { Instr->setOperand(4, val); }
+  llvm::Value *get_MultiplierForGeometryContributionToShaderIndex() const { return Instr->getOperand(5); }
+  void set_MultiplierForGeometryContributionToShaderIndex(llvm::Value *val) { Instr->setOperand(5, val); }
+  llvm::Value *get_MissShaderIndex() const { return Instr->getOperand(6); }
+  void set_MissShaderIndex(llvm::Value *val) { Instr->setOperand(6, val); }
+  llvm::Value *get_Origin_X() const { return Instr->getOperand(7); }
+  void set_Origin_X(llvm::Value *val) { Instr->setOperand(7, val); }
+  llvm::Value *get_Origin_Y() const { return Instr->getOperand(8); }
+  void set_Origin_Y(llvm::Value *val) { Instr->setOperand(8, val); }
+  llvm::Value *get_Origin_Z() const { return Instr->getOperand(9); }
+  void set_Origin_Z(llvm::Value *val) { Instr->setOperand(9, val); }
+  llvm::Value *get_TMin() const { return Instr->getOperand(10); }
+  void set_TMin(llvm::Value *val) { Instr->setOperand(10, val); }
+  llvm::Value *get_Direction_X() const { return Instr->getOperand(11); }
+  void set_Direction_X(llvm::Value *val) { Instr->setOperand(11, val); }
+  llvm::Value *get_Direction_Y() const { return Instr->getOperand(12); }
+  void set_Direction_Y(llvm::Value *val) { Instr->setOperand(12, val); }
+  llvm::Value *get_Direction_Z() const { return Instr->getOperand(13); }
+  void set_Direction_Z(llvm::Value *val) { Instr->setOperand(13, val); }
+  llvm::Value *get_TMax() const { return Instr->getOperand(14); }
+  void set_TMax(llvm::Value *val) { Instr->setOperand(14, val); }
+  llvm::Value *get_payload() const { return Instr->getOperand(15); }
+  void set_payload(llvm::Value *val) { Instr->setOperand(15, val); }
+};
+
+/// This instruction returns true if hit was accepted
+struct DxilInst_ReportIntersection {
+  llvm::Instruction *Instr;
+  // Construction and identification
+  DxilInst_ReportIntersection(llvm::Instruction *pInstr) : Instr(pInstr) {}
+  operator bool() const {
+    return hlsl::OP::IsDxilOpFuncCallInst(Instr, hlsl::OP::OpCode::ReportIntersection);
+  }
+  // Validation support
+  bool isAllowed() const { return true; }
+  bool isArgumentListValid() const {
+    if (4 != llvm::dyn_cast<llvm::CallInst>(Instr)->getNumArgOperands()) return false;
+    return true;
+  }
+  // Operand indexes
+  enum OperandIdx {
+    arg_THit = 1,
+    arg_HitKind = 2,
+    arg_Attributes = 3,
+  };
+  // Accessors
+  llvm::Value *get_THit() const { return Instr->getOperand(1); }
+  void set_THit(llvm::Value *val) { Instr->setOperand(1, val); }
+  llvm::Value *get_HitKind() const { return Instr->getOperand(2); }
+  void set_HitKind(llvm::Value *val) { Instr->setOperand(2, val); }
+  llvm::Value *get_Attributes() const { return Instr->getOperand(3); }
+  void set_Attributes(llvm::Value *val) { Instr->setOperand(3, val); }
+};
+
+/// This instruction returns the view index
+struct DxilInst_CallShader {
+  llvm::Instruction *Instr;
+  // Construction and identification
+  DxilInst_CallShader(llvm::Instruction *pInstr) : Instr(pInstr) {}
+  operator bool() const {
+    return hlsl::OP::IsDxilOpFuncCallInst(Instr, hlsl::OP::OpCode::CallShader);
+  }
+  // Validation support
+  bool isAllowed() const { return true; }
+  bool isArgumentListValid() const {
+    if (3 != llvm::dyn_cast<llvm::CallInst>(Instr)->getNumArgOperands()) return false;
+    return true;
+  }
+  // Operand indexes
+  enum OperandIdx {
+    arg_ShaderIndex = 1,
+    arg_Parameter = 2,
+  };
+  // Accessors
+  llvm::Value *get_ShaderIndex() const { return Instr->getOperand(1); }
+  void set_ShaderIndex(llvm::Value *val) { Instr->setOperand(1, val); }
+  llvm::Value *get_Parameter() const { return Instr->getOperand(2); }
+  void set_Parameter(llvm::Value *val) { Instr->setOperand(2, val); }
+};
+
+/// This instruction returns the view index
+struct DxilInst_ReservedForLibCreateHandleFromResourceStruct {
+  llvm::Instruction *Instr;
+  // Construction and identification
+  DxilInst_ReservedForLibCreateHandleFromResourceStruct(llvm::Instruction *pInstr) : Instr(pInstr) {}
+  operator bool() const {
+    return hlsl::OP::IsDxilOpFuncCallInst(Instr, hlsl::OP::OpCode::ReservedForLibCreateHandleFromResourceStruct);
+  }
+  // Validation support
+  bool isAllowed() const { return true; }
+  bool isArgumentListValid() const {
+    if (1 != llvm::dyn_cast<llvm::CallInst>(Instr)->getNumArgOperands()) return false;
+    return true;
+  }
+};
 // INSTR-HELPER:END
 // INSTR-HELPER:END
 } // namespace hlsl
 } // namespace hlsl

+ 8 - 5
include/dxc/HLSL/DxilOperations.h

@@ -23,6 +23,7 @@ class Instruction;
 };
 };
 #include "llvm/IR/Attributes.h"
 #include "llvm/IR/Attributes.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/DenseMap.h"
 
 
 #include "DxilConstants.h"
 #include "DxilConstants.h"
 #include <unordered_map>
 #include <unordered_map>
@@ -42,7 +43,7 @@ public:
   void RefreshCache();
   void RefreshCache();
 
 
   llvm::Function *GetOpFunc(OpCode OpCode, llvm::Type *pOverloadType);
   llvm::Function *GetOpFunc(OpCode OpCode, llvm::Type *pOverloadType);
-  llvm::ArrayRef<llvm::Function *> GetOpFuncList(OpCode OpCode) const;
+  const llvm::SmallDenseMap<llvm::Type *, llvm::Function *, 8> &GetOpFuncList(OpCode OpCode) const;
   void RemoveFunction(llvm::Function *F);
   void RemoveFunction(llvm::Function *F);
   llvm::Type *GetOverloadType(OpCode OpCode, llvm::Function *F);
   llvm::Type *GetOverloadType(OpCode OpCode, llvm::Function *F);
   llvm::LLVMContext &GetCtx() { return m_Ctx; }
   llvm::LLVMContext &GetCtx() { return m_Ctx; }
@@ -115,17 +116,18 @@ private:
 
 
   DXIL::LowPrecisionMode m_LowPrecisionMode;
   DXIL::LowPrecisionMode m_LowPrecisionMode;
 
 
-  static const unsigned kNumTypeOverloads = 9;
+  static const unsigned kUserDefineTypeSlot = 9;
+  static const unsigned kNumTypeOverloads = 10; // void, h,f,d, i1, i8,i16,i32,i64, udt
 
 
   llvm::Type *m_pResRetType[kNumTypeOverloads];
   llvm::Type *m_pResRetType[kNumTypeOverloads];
   llvm::Type *m_pCBufferRetType[kNumTypeOverloads];
   llvm::Type *m_pCBufferRetType[kNumTypeOverloads];
 
 
   struct OpCodeCacheItem {
   struct OpCodeCacheItem {
-    llvm::Function *pOverloads[kNumTypeOverloads];
+    llvm::SmallDenseMap<llvm::Type *, llvm::Function *, 8> pOverloads;
   };
   };
   OpCodeCacheItem m_OpCodeClassCache[(unsigned)OpCodeClass::NumOpClasses];
   OpCodeCacheItem m_OpCodeClassCache[(unsigned)OpCodeClass::NumOpClasses];
   std::unordered_map<const llvm::Function *, OpCodeClass> m_FunctionToOpClass;
   std::unordered_map<const llvm::Function *, OpCodeClass> m_FunctionToOpClass;
-  void UpdateCache(OpCodeClass opClass, unsigned typeSlot, llvm::Function *F);
+  void UpdateCache(OpCodeClass opClass, llvm::Type * Ty, llvm::Function *F);
 private:
 private:
   // Static properties.
   // Static properties.
   struct OpCodeProperty {
   struct OpCodeProperty {
@@ -133,7 +135,7 @@ private:
     const char *pOpCodeName;
     const char *pOpCodeName;
     OpCodeClass OpCodeClass;
     OpCodeClass OpCodeClass;
     const char *pOpCodeClassName;
     const char *pOpCodeClassName;
-    bool bAllowOverload[kNumTypeOverloads];   // void, h,f,d, i1, i8,i16,i32,i64
+    bool bAllowOverload[kNumTypeOverloads];   // void, h,f,d, i1, i8,i16,i32,i64, udt
     llvm::Attribute::AttrKind FuncAttr;
     llvm::Attribute::AttrKind FuncAttr;
   };
   };
   static const OpCodeProperty m_OpCodeProps[(unsigned)OpCode::NumOpCodes];
   static const OpCodeProperty m_OpCodeProps[(unsigned)OpCode::NumOpCodes];
@@ -144,6 +146,7 @@ private:
   static const char *m_MatrixTypePrefix;
   static const char *m_MatrixTypePrefix;
   static unsigned GetTypeSlot(llvm::Type *pType);
   static unsigned GetTypeSlot(llvm::Type *pType);
   static const char *GetOverloadTypeName(unsigned TypeSlot);
   static const char *GetOverloadTypeName(unsigned TypeSlot);
+  static const char *GetTypeName(llvm::Type *Ty, std::string &str);
 };
 };
 
 
 } // namespace hlsl
 } // namespace hlsl

+ 7 - 0
include/dxc/HLSL/HLOperations.h

@@ -329,6 +329,13 @@ const unsigned kWaveAllEqualValueOpIdx = 1;
 const unsigned kCreateHandleResourceOpIdx = 1;
 const unsigned kCreateHandleResourceOpIdx = 1;
 const unsigned kCreateHandleIndexOpIdx = 2; // Only for array of cbuffer.
 const unsigned kCreateHandleIndexOpIdx = 2; // Only for array of cbuffer.
 
 
+// TraceRay.
+const unsigned kTraceRayRayDescOpIdx = 7;
+const unsigned kTraceRayPayLoadOpIdx = 8;
+
+// ReportIntersection.
+const unsigned kReportIntersectionAttributeOpIdx = 3;
+
 } // namespace HLOperandIndex
 } // namespace HLOperandIndex
 
 
 llvm::Function *GetOrCreateHLFunction(llvm::Module &M,
 llvm::Function *GetOrCreateHLFunction(llvm::Module &M,

+ 3 - 2
lib/HLSL/DxilEliminateOutputDynamicIndexing.cpp

@@ -100,11 +100,12 @@ public:
 bool DxilEliminateOutputDynamicIndexing::EliminateDynamicOutput(
 bool DxilEliminateOutputDynamicIndexing::EliminateDynamicOutput(
     hlsl::OP *hlslOP, DXIL::OpCode opcode, DxilSignature &outputSig,
     hlsl::OP *hlslOP, DXIL::OpCode opcode, DxilSignature &outputSig,
     Function *Entry) {
     Function *Entry) {
-  ArrayRef<llvm::Function *> storeOutputs =
+  auto &storeOutputs =
       hlslOP->GetOpFuncList(opcode);
       hlslOP->GetOpFuncList(opcode);
 
 
   MapVector<Value *, Type *> dynamicSigSet;
   MapVector<Value *, Type *> dynamicSigSet;
-  for (Function *F : storeOutputs) {
+  for (auto it : storeOutputs) {
+    Function *F = it.second;
     // Skip overload not used.
     // Skip overload not used.
     if (!F)
     if (!F)
       continue;
       continue;

+ 3 - 2
lib/HLSL/DxilLegalizeSampleOffsetPass.cpp

@@ -182,8 +182,9 @@ void DxilLegalizeSampleOffsetPass::CollectIllegalOffsets(
 void DxilLegalizeSampleOffsetPass::CollectIllegalOffsets(
 void DxilLegalizeSampleOffsetPass::CollectIllegalOffsets(
     std::vector<Instruction *> &illegalOffsets, Function &CurF,
     std::vector<Instruction *> &illegalOffsets, Function &CurF,
     DXIL::OpCode opcode, hlsl::OP *hlslOP) {
     DXIL::OpCode opcode, hlsl::OP *hlslOP) {
-  ArrayRef<Function *> intrFuncList = hlslOP->GetOpFuncList(opcode);
-  for (Function *intrFunc : intrFuncList) {
+  auto &intrFuncList = hlslOP->GetOpFuncList(opcode);
+  for (auto it : intrFuncList) {
+    Function *intrFunc = it.second;
     if (!intrFunc)
     if (!intrFunc)
       continue;
       continue;
     for (User *U : intrFunc->users()) {
     for (User *U : intrFunc->users()) {

+ 322 - 239
lib/HLSL/DxilOperations.cpp

@@ -41,234 +41,255 @@ import hctdb_instrhelp
 /* <py::lines('OPCODE-OLOADS')>hctdb_instrhelp.get_oloads_props()</py>*/
 /* <py::lines('OPCODE-OLOADS')>hctdb_instrhelp.get_oloads_props()</py>*/
 // OPCODE-OLOADS:BEGIN
 // OPCODE-OLOADS:BEGIN
 const OP::OpCodeProperty OP::m_OpCodeProps[(unsigned)OP::OpCode::NumOpCodes] = {
 const OP::OpCodeProperty OP::m_OpCodeProps[(unsigned)OP::OpCode::NumOpCodes] = {
-//   OpCode                       OpCode name,                OpCodeClass                    OpCodeClass name,              void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64  function attribute
-  // Temporary, indexable, input, output registers                                                                          void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64  function attribute
-  {  OC::TempRegLoad,             "TempRegLoad",              OCC::TempRegLoad,              "tempRegLoad",                false,  true,  true, false, false, false,  true,  true, false, Attribute::ReadOnly, },
-  {  OC::TempRegStore,            "TempRegStore",             OCC::TempRegStore,             "tempRegStore",               false,  true,  true, false, false, false,  true,  true, false, Attribute::None,     },
-  {  OC::MinPrecXRegLoad,         "MinPrecXRegLoad",          OCC::MinPrecXRegLoad,          "minPrecXRegLoad",            false,  true, false, false, false, false,  true, false, false, Attribute::ReadOnly, },
-  {  OC::MinPrecXRegStore,        "MinPrecXRegStore",         OCC::MinPrecXRegStore,         "minPrecXRegStore",           false,  true, false, false, false, false,  true, false, false, Attribute::None,     },
-  {  OC::LoadInput,               "LoadInput",                OCC::LoadInput,                "loadInput",                  false,  true,  true, false, false, false,  true,  true, false, Attribute::ReadNone, },
-  {  OC::StoreOutput,             "StoreOutput",              OCC::StoreOutput,              "storeOutput",                false,  true,  true, false, false, false,  true,  true, false, Attribute::None,     },
-
-  // Unary float                                                                                                            void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64  function attribute
-  {  OC::FAbs,                    "FAbs",                     OCC::Unary,                    "unary",                      false,  true,  true,  true, false, false, false, false, false, Attribute::ReadNone, },
-  {  OC::Saturate,                "Saturate",                 OCC::Unary,                    "unary",                      false,  true,  true,  true, false, false, false, false, false, Attribute::ReadNone, },
-  {  OC::IsNaN,                   "IsNaN",                    OCC::IsSpecialFloat,           "isSpecialFloat",             false,  true,  true, false, false, false, false, false, false, Attribute::ReadNone, },
-  {  OC::IsInf,                   "IsInf",                    OCC::IsSpecialFloat,           "isSpecialFloat",             false,  true,  true, false, false, false, false, false, false, Attribute::ReadNone, },
-  {  OC::IsFinite,                "IsFinite",                 OCC::IsSpecialFloat,           "isSpecialFloat",             false,  true,  true, false, false, false, false, false, false, Attribute::ReadNone, },
-  {  OC::IsNormal,                "IsNormal",                 OCC::IsSpecialFloat,           "isSpecialFloat",             false,  true,  true, false, false, false, false, false, false, Attribute::ReadNone, },
-  {  OC::Cos,                     "Cos",                      OCC::Unary,                    "unary",                      false,  true,  true, false, false, false, false, false, false, Attribute::ReadNone, },
-  {  OC::Sin,                     "Sin",                      OCC::Unary,                    "unary",                      false,  true,  true, false, false, false, false, false, false, Attribute::ReadNone, },
-  {  OC::Tan,                     "Tan",                      OCC::Unary,                    "unary",                      false,  true,  true, false, false, false, false, false, false, Attribute::ReadNone, },
-  {  OC::Acos,                    "Acos",                     OCC::Unary,                    "unary",                      false,  true,  true, false, false, false, false, false, false, Attribute::ReadNone, },
-  {  OC::Asin,                    "Asin",                     OCC::Unary,                    "unary",                      false,  true,  true, false, false, false, false, false, false, Attribute::ReadNone, },
-  {  OC::Atan,                    "Atan",                     OCC::Unary,                    "unary",                      false,  true,  true, false, false, false, false, false, false, Attribute::ReadNone, },
-  {  OC::Hcos,                    "Hcos",                     OCC::Unary,                    "unary",                      false,  true,  true, false, false, false, false, false, false, Attribute::ReadNone, },
-  {  OC::Hsin,                    "Hsin",                     OCC::Unary,                    "unary",                      false,  true,  true, false, false, false, false, false, false, Attribute::ReadNone, },
-  {  OC::Htan,                    "Htan",                     OCC::Unary,                    "unary",                      false,  true,  true, false, false, false, false, false, false, Attribute::ReadNone, },
-  {  OC::Exp,                     "Exp",                      OCC::Unary,                    "unary",                      false,  true,  true, false, false, false, false, false, false, Attribute::ReadNone, },
-  {  OC::Frc,                     "Frc",                      OCC::Unary,                    "unary",                      false,  true,  true, false, false, false, false, false, false, Attribute::ReadNone, },
-  {  OC::Log,                     "Log",                      OCC::Unary,                    "unary",                      false,  true,  true, false, false, false, false, false, false, Attribute::ReadNone, },
-  {  OC::Sqrt,                    "Sqrt",                     OCC::Unary,                    "unary",                      false,  true,  true, false, false, false, false, false, false, Attribute::ReadNone, },
-  {  OC::Rsqrt,                   "Rsqrt",                    OCC::Unary,                    "unary",                      false,  true,  true, false, false, false, false, false, false, Attribute::ReadNone, },
-
-  // Unary float - rounding                                                                                                 void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64  function attribute
-  {  OC::Round_ne,                "Round_ne",                 OCC::Unary,                    "unary",                      false,  true,  true, false, false, false, false, false, false, Attribute::ReadNone, },
-  {  OC::Round_ni,                "Round_ni",                 OCC::Unary,                    "unary",                      false,  true,  true, false, false, false, false, false, false, Attribute::ReadNone, },
-  {  OC::Round_pi,                "Round_pi",                 OCC::Unary,                    "unary",                      false,  true,  true, false, false, false, false, false, false, Attribute::ReadNone, },
-  {  OC::Round_z,                 "Round_z",                  OCC::Unary,                    "unary",                      false,  true,  true, false, false, false, false, false, false, Attribute::ReadNone, },
-
-  // Unary int                                                                                                              void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64  function attribute
-  {  OC::Bfrev,                   "Bfrev",                    OCC::Unary,                    "unary",                      false, false, false, false, false, false,  true,  true,  true, Attribute::ReadNone, },
-  {  OC::Countbits,               "Countbits",                OCC::UnaryBits,                "unaryBits",                  false, false, false, false, false, false,  true,  true,  true, Attribute::ReadNone, },
-  {  OC::FirstbitLo,              "FirstbitLo",               OCC::UnaryBits,                "unaryBits",                  false, false, false, false, false, false,  true,  true,  true, Attribute::ReadNone, },
-
-  // Unary uint                                                                                                             void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64  function attribute
-  {  OC::FirstbitHi,              "FirstbitHi",               OCC::UnaryBits,                "unaryBits",                  false, false, false, false, false, false,  true,  true,  true, Attribute::ReadNone, },
-
-  // Unary int                                                                                                              void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64  function attribute
-  {  OC::FirstbitSHi,             "FirstbitSHi",              OCC::UnaryBits,                "unaryBits",                  false, false, false, false, false, false,  true,  true,  true, Attribute::ReadNone, },
-
-  // Binary float                                                                                                           void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64  function attribute
-  {  OC::FMax,                    "FMax",                     OCC::Binary,                   "binary",                     false,  true,  true,  true, false, false, false, false, false, Attribute::ReadNone, },
-  {  OC::FMin,                    "FMin",                     OCC::Binary,                   "binary",                     false,  true,  true,  true, false, false, false, false, false, Attribute::ReadNone, },
-
-  // Binary int                                                                                                             void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64  function attribute
-  {  OC::IMax,                    "IMax",                     OCC::Binary,                   "binary",                     false, false, false, false, false, false,  true,  true,  true, Attribute::ReadNone, },
-  {  OC::IMin,                    "IMin",                     OCC::Binary,                   "binary",                     false, false, false, false, false, false,  true,  true,  true, Attribute::ReadNone, },
-
-  // Binary uint                                                                                                            void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64  function attribute
-  {  OC::UMax,                    "UMax",                     OCC::Binary,                   "binary",                     false, false, false, false, false, false,  true,  true,  true, Attribute::ReadNone, },
-  {  OC::UMin,                    "UMin",                     OCC::Binary,                   "binary",                     false, false, false, false, false, false,  true,  true,  true, Attribute::ReadNone, },
-
-  // Binary int with two outputs                                                                                            void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64  function attribute
-  {  OC::IMul,                    "IMul",                     OCC::BinaryWithTwoOuts,        "binaryWithTwoOuts",          false, false, false, false, false, false, false,  true, false, Attribute::ReadNone, },
-
-  // Binary uint with two outputs                                                                                           void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64  function attribute
-  {  OC::UMul,                    "UMul",                     OCC::BinaryWithTwoOuts,        "binaryWithTwoOuts",          false, false, false, false, false, false, false,  true, false, Attribute::ReadNone, },
-  {  OC::UDiv,                    "UDiv",                     OCC::BinaryWithTwoOuts,        "binaryWithTwoOuts",          false, false, false, false, false, false, false,  true, false, Attribute::ReadNone, },
-
-  // Binary uint with carry or borrow                                                                                       void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64  function attribute
-  {  OC::UAddc,                   "UAddc",                    OCC::BinaryWithCarryOrBorrow,  "binaryWithCarryOrBorrow",    false, false, false, false, false, false, false,  true, false, Attribute::ReadNone, },
-  {  OC::USubb,                   "USubb",                    OCC::BinaryWithCarryOrBorrow,  "binaryWithCarryOrBorrow",    false, false, false, false, false, false, false,  true, false, Attribute::ReadNone, },
-
-  // Tertiary float                                                                                                         void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64  function attribute
-  {  OC::FMad,                    "FMad",                     OCC::Tertiary,                 "tertiary",                   false,  true,  true,  true, false, false, false, false, false, Attribute::ReadNone, },
-  {  OC::Fma,                     "Fma",                      OCC::Tertiary,                 "tertiary",                   false, false, false,  true, false, false, false, false, false, Attribute::ReadNone, },
-
-  // Tertiary int                                                                                                           void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64  function attribute
-  {  OC::IMad,                    "IMad",                     OCC::Tertiary,                 "tertiary",                   false, false, false, false, false, false,  true,  true,  true, Attribute::ReadNone, },
-
-  // Tertiary uint                                                                                                          void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64  function attribute
-  {  OC::UMad,                    "UMad",                     OCC::Tertiary,                 "tertiary",                   false, false, false, false, false, false,  true,  true,  true, Attribute::ReadNone, },
-
-  // Tertiary int                                                                                                           void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64  function attribute
-  {  OC::Msad,                    "Msad",                     OCC::Tertiary,                 "tertiary",                   false, false, false, false, false, false, false,  true,  true, Attribute::ReadNone, },
-  {  OC::Ibfe,                    "Ibfe",                     OCC::Tertiary,                 "tertiary",                   false, false, false, false, false, false, false,  true,  true, Attribute::ReadNone, },
-
-  // Tertiary uint                                                                                                          void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64  function attribute
-  {  OC::Ubfe,                    "Ubfe",                     OCC::Tertiary,                 "tertiary",                   false, false, false, false, false, false, false,  true,  true, Attribute::ReadNone, },
-
-  // Quaternary                                                                                                             void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64  function attribute
-  {  OC::Bfi,                     "Bfi",                      OCC::Quaternary,               "quaternary",                 false, false, false, false, false, false, false,  true, false, Attribute::ReadNone, },
-
-  // Dot                                                                                                                    void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64  function attribute
-  {  OC::Dot2,                    "Dot2",                     OCC::Dot2,                     "dot2",                       false,  true,  true, false, false, false, false, false, false, Attribute::ReadNone, },
-  {  OC::Dot3,                    "Dot3",                     OCC::Dot3,                     "dot3",                       false,  true,  true, false, false, false, false, false, false, Attribute::ReadNone, },
-  {  OC::Dot4,                    "Dot4",                     OCC::Dot4,                     "dot4",                       false,  true,  true, false, false, false, false, false, false, Attribute::ReadNone, },
-
-  // Resources                                                                                                              void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64  function attribute
-  {  OC::CreateHandle,            "CreateHandle",             OCC::CreateHandle,             "createHandle",                true, false, false, false, false, false, false, false, false, Attribute::ReadOnly, },
-  {  OC::CBufferLoad,             "CBufferLoad",              OCC::CBufferLoad,              "cbufferLoad",                false,  true,  true,  true, false,  true,  true,  true,  true, Attribute::ReadOnly, },
-  {  OC::CBufferLoadLegacy,       "CBufferLoadLegacy",        OCC::CBufferLoadLegacy,        "cbufferLoadLegacy",          false,  true,  true,  true, false, false,  true,  true,  true, Attribute::ReadOnly, },
-
-  // Resources - sample                                                                                                     void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64  function attribute
-  {  OC::Sample,                  "Sample",                   OCC::Sample,                   "sample",                     false,  true,  true, false, false, false, false, false, false, Attribute::ReadOnly, },
-  {  OC::SampleBias,              "SampleBias",               OCC::SampleBias,               "sampleBias",                 false,  true,  true, false, false, false, false, false, false, Attribute::ReadOnly, },
-  {  OC::SampleLevel,             "SampleLevel",              OCC::SampleLevel,              "sampleLevel",                false,  true,  true, false, false, false, false, false, false, Attribute::ReadOnly, },
-  {  OC::SampleGrad,              "SampleGrad",               OCC::SampleGrad,               "sampleGrad",                 false,  true,  true, false, false, false, false, false, false, Attribute::ReadOnly, },
-  {  OC::SampleCmp,               "SampleCmp",                OCC::SampleCmp,                "sampleCmp",                  false,  true,  true, false, false, false, false, false, false, Attribute::ReadOnly, },
-  {  OC::SampleCmpLevelZero,      "SampleCmpLevelZero",       OCC::SampleCmpLevelZero,       "sampleCmpLevelZero",         false,  true,  true, false, false, false, false, false, false, Attribute::ReadOnly, },
-
-  // Resources                                                                                                              void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64  function attribute
-  {  OC::TextureLoad,             "TextureLoad",              OCC::TextureLoad,              "textureLoad",                false,  true,  true, false, false, false,  true,  true, false, Attribute::ReadOnly, },
-  {  OC::TextureStore,            "TextureStore",             OCC::TextureStore,             "textureStore",               false,  true,  true, false, false, false,  true,  true, false, Attribute::None,     },
-  {  OC::BufferLoad,              "BufferLoad",               OCC::BufferLoad,               "bufferLoad",                 false,  true,  true, false, false, false,  true,  true, false, Attribute::ReadOnly, },
-  {  OC::BufferStore,             "BufferStore",              OCC::BufferStore,              "bufferStore",                false,  true,  true, false, false, false,  true,  true, false, Attribute::None,     },
-  {  OC::BufferUpdateCounter,     "BufferUpdateCounter",      OCC::BufferUpdateCounter,      "bufferUpdateCounter",         true, false, false, false, false, false, false, false, false, Attribute::None,     },
-  {  OC::CheckAccessFullyMapped,  "CheckAccessFullyMapped",   OCC::CheckAccessFullyMapped,   "checkAccessFullyMapped",     false, false, false, false, false, false, false,  true, false, Attribute::ReadOnly, },
-  {  OC::GetDimensions,           "GetDimensions",            OCC::GetDimensions,            "getDimensions",               true, false, false, false, false, false, false, false, false, Attribute::ReadOnly, },
-
-  // Resources - gather                                                                                                     void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64  function attribute
-  {  OC::TextureGather,           "TextureGather",            OCC::TextureGather,            "textureGather",              false, false,  true, false, false, false, false,  true, false, Attribute::ReadOnly, },
-  {  OC::TextureGatherCmp,        "TextureGatherCmp",         OCC::TextureGatherCmp,         "textureGatherCmp",           false, false,  true, false, false, false, false,  true, false, Attribute::ReadOnly, },
-
-  // Resources - sample                                                                                                     void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64  function attribute
-  {  OC::Texture2DMSGetSamplePosition, "Texture2DMSGetSamplePosition", OCC::Texture2DMSGetSamplePosition, "texture2DMSGetSamplePosition",   true, false, false, false, false, false, false, false, false, Attribute::ReadOnly, },
-  {  OC::RenderTargetGetSamplePosition, "RenderTargetGetSamplePosition", OCC::RenderTargetGetSamplePosition, "renderTargetGetSamplePosition",   true, false, false, false, false, false, false, false, false, Attribute::ReadOnly, },
-  {  OC::RenderTargetGetSampleCount, "RenderTargetGetSampleCount", OCC::RenderTargetGetSampleCount, "renderTargetGetSampleCount",   true, false, false, false, false, false, false, false, false, Attribute::ReadOnly, },
-
-  // Synchronization                                                                                                        void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64  function attribute
-  {  OC::AtomicBinOp,             "AtomicBinOp",              OCC::AtomicBinOp,              "atomicBinOp",                false, false, false, false, false, false, false,  true, false, Attribute::None,     },
-  {  OC::AtomicCompareExchange,   "AtomicCompareExchange",    OCC::AtomicCompareExchange,    "atomicCompareExchange",      false, false, false, false, false, false, false,  true, false, Attribute::None,     },
-  {  OC::Barrier,                 "Barrier",                  OCC::Barrier,                  "barrier",                     true, false, false, false, false, false, false, false, false, Attribute::NoDuplicate, },
-
-  // Pixel shader                                                                                                           void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64  function attribute
-  {  OC::CalculateLOD,            "CalculateLOD",             OCC::CalculateLOD,             "calculateLOD",               false, false,  true, false, false, false, false, false, false, Attribute::ReadOnly, },
-  {  OC::Discard,                 "Discard",                  OCC::Discard,                  "discard",                     true, false, false, false, false, false, false, false, false, Attribute::None,     },
-  {  OC::DerivCoarseX,            "DerivCoarseX",             OCC::Unary,                    "unary",                      false,  true,  true, false, false, false, false, false, false, Attribute::ReadNone, },
-  {  OC::DerivCoarseY,            "DerivCoarseY",             OCC::Unary,                    "unary",                      false,  true,  true, false, false, false, false, false, false, Attribute::ReadNone, },
-  {  OC::DerivFineX,              "DerivFineX",               OCC::Unary,                    "unary",                      false,  true,  true, false, false, false, false, false, false, Attribute::ReadNone, },
-  {  OC::DerivFineY,              "DerivFineY",               OCC::Unary,                    "unary",                      false,  true,  true, false, false, false, false, false, false, Attribute::ReadNone, },
-  {  OC::EvalSnapped,             "EvalSnapped",              OCC::EvalSnapped,              "evalSnapped",                false,  true,  true, false, false, false, false, false, false, Attribute::ReadNone, },
-  {  OC::EvalSampleIndex,         "EvalSampleIndex",          OCC::EvalSampleIndex,          "evalSampleIndex",            false,  true,  true, false, false, false, false, false, false, Attribute::ReadNone, },
-  {  OC::EvalCentroid,            "EvalCentroid",             OCC::EvalCentroid,             "evalCentroid",               false,  true,  true, false, false, false, false, false, false, Attribute::ReadNone, },
-  {  OC::SampleIndex,             "SampleIndex",              OCC::SampleIndex,              "sampleIndex",                false, false, false, false, false, false, false,  true, false, Attribute::ReadNone, },
-  {  OC::Coverage,                "Coverage",                 OCC::Coverage,                 "coverage",                   false, false, false, false, false, false, false,  true, false, Attribute::ReadNone, },
-  {  OC::InnerCoverage,           "InnerCoverage",            OCC::InnerCoverage,            "innerCoverage",              false, false, false, false, false, false, false,  true, false, Attribute::ReadNone, },
-
-  // Compute shader                                                                                                         void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64  function attribute
-  {  OC::ThreadId,                "ThreadId",                 OCC::ThreadId,                 "threadId",                   false, false, false, false, false, false, false,  true, false, Attribute::ReadNone, },
-  {  OC::GroupId,                 "GroupId",                  OCC::GroupId,                  "groupId",                    false, false, false, false, false, false, false,  true, false, Attribute::ReadNone, },
-  {  OC::ThreadIdInGroup,         "ThreadIdInGroup",          OCC::ThreadIdInGroup,          "threadIdInGroup",            false, false, false, false, false, false, false,  true, false, Attribute::ReadNone, },
-  {  OC::FlattenedThreadIdInGroup, "FlattenedThreadIdInGroup", OCC::FlattenedThreadIdInGroup, "flattenedThreadIdInGroup",   false, false, false, false, false, false, false,  true, false, Attribute::ReadNone, },
-
-  // Geometry shader                                                                                                        void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64  function attribute
-  {  OC::EmitStream,              "EmitStream",               OCC::EmitStream,               "emitStream",                  true, false, false, false, false, false, false, false, false, Attribute::None,     },
-  {  OC::CutStream,               "CutStream",                OCC::CutStream,                "cutStream",                   true, false, false, false, false, false, false, false, false, Attribute::None,     },
-  {  OC::EmitThenCutStream,       "EmitThenCutStream",        OCC::EmitThenCutStream,        "emitThenCutStream",           true, false, false, false, false, false, false, false, false, Attribute::None,     },
-  {  OC::GSInstanceID,            "GSInstanceID",             OCC::GSInstanceID,             "gsInstanceID",               false, false, false, false, false, false, false,  true, false, Attribute::ReadNone, },
-
-  // Double precision                                                                                                       void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64  function attribute
-  {  OC::MakeDouble,              "MakeDouble",               OCC::MakeDouble,               "makeDouble",                 false, false, false,  true, false, false, false, false, false, Attribute::ReadNone, },
-  {  OC::SplitDouble,             "SplitDouble",              OCC::SplitDouble,              "splitDouble",                false, false, false,  true, false, false, false, false, false, Attribute::ReadNone, },
-
-  // Domain and hull shader                                                                                                 void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64  function attribute
-  {  OC::LoadOutputControlPoint,  "LoadOutputControlPoint",   OCC::LoadOutputControlPoint,   "loadOutputControlPoint",     false,  true,  true, false, false, false,  true,  true, false, Attribute::ReadNone, },
-  {  OC::LoadPatchConstant,       "LoadPatchConstant",        OCC::LoadPatchConstant,        "loadPatchConstant",          false,  true,  true, false, false, false,  true,  true, false, Attribute::ReadNone, },
-
-  // Domain shader                                                                                                          void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64  function attribute
-  {  OC::DomainLocation,          "DomainLocation",           OCC::DomainLocation,           "domainLocation",             false, false,  true, false, false, false, false, false, false, Attribute::ReadNone, },
-
-  // Hull shader                                                                                                            void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64  function attribute
-  {  OC::StorePatchConstant,      "StorePatchConstant",       OCC::StorePatchConstant,       "storePatchConstant",         false,  true,  true, false, false, false,  true,  true, false, Attribute::None,     },
-  {  OC::OutputControlPointID,    "OutputControlPointID",     OCC::OutputControlPointID,     "outputControlPointID",       false, false, false, false, false, false, false,  true, false, Attribute::ReadNone, },
-  {  OC::PrimitiveID,             "PrimitiveID",              OCC::PrimitiveID,              "primitiveID",                false, false, false, false, false, false, false,  true, false, Attribute::ReadNone, },
-
-  // Other                                                                                                                  void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64  function attribute
-  {  OC::CycleCounterLegacy,      "CycleCounterLegacy",       OCC::CycleCounterLegacy,       "cycleCounterLegacy",          true, false, false, false, false, false, false, false, false, Attribute::None,     },
-
-  // Wave                                                                                                                   void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64  function attribute
-  {  OC::WaveIsFirstLane,         "WaveIsFirstLane",          OCC::WaveIsFirstLane,          "waveIsFirstLane",             true, false, false, false, false, false, false, false, false, Attribute::None,     },
-  {  OC::WaveGetLaneIndex,        "WaveGetLaneIndex",         OCC::WaveGetLaneIndex,         "waveGetLaneIndex",            true, false, false, false, false, false, false, false, false, Attribute::ReadNone, },
-  {  OC::WaveGetLaneCount,        "WaveGetLaneCount",         OCC::WaveGetLaneCount,         "waveGetLaneCount",            true, false, false, false, false, false, false, false, false, Attribute::ReadNone, },
-  {  OC::WaveAnyTrue,             "WaveAnyTrue",              OCC::WaveAnyTrue,              "waveAnyTrue",                 true, false, false, false, false, false, false, false, false, Attribute::None,     },
-  {  OC::WaveAllTrue,             "WaveAllTrue",              OCC::WaveAllTrue,              "waveAllTrue",                 true, false, false, false, false, false, false, false, false, Attribute::None,     },
-  {  OC::WaveActiveAllEqual,      "WaveActiveAllEqual",       OCC::WaveActiveAllEqual,       "waveActiveAllEqual",         false,  true,  true,  true,  true,  true,  true,  true,  true, Attribute::None,     },
-  {  OC::WaveActiveBallot,        "WaveActiveBallot",         OCC::WaveActiveBallot,         "waveActiveBallot",            true, false, false, false, false, false, false, false, false, Attribute::None,     },
-  {  OC::WaveReadLaneAt,          "WaveReadLaneAt",           OCC::WaveReadLaneAt,           "waveReadLaneAt",             false,  true,  true,  true,  true,  true,  true,  true,  true, Attribute::None,     },
-  {  OC::WaveReadLaneFirst,       "WaveReadLaneFirst",        OCC::WaveReadLaneFirst,        "waveReadLaneFirst",          false,  true,  true, false,  true,  true,  true,  true,  true, Attribute::None,     },
-  {  OC::WaveActiveOp,            "WaveActiveOp",             OCC::WaveActiveOp,             "waveActiveOp",               false,  true,  true,  true,  true,  true,  true,  true,  true, Attribute::None,     },
-  {  OC::WaveActiveBit,           "WaveActiveBit",            OCC::WaveActiveBit,            "waveActiveBit",              false, false, false, false, false,  true,  true,  true,  true, Attribute::None,     },
-  {  OC::WavePrefixOp,            "WavePrefixOp",             OCC::WavePrefixOp,             "wavePrefixOp",               false,  true,  true,  true, false,  true,  true,  true,  true, Attribute::None,     },
-  {  OC::QuadReadLaneAt,          "QuadReadLaneAt",           OCC::QuadReadLaneAt,           "quadReadLaneAt",             false,  true,  true,  true,  true,  true,  true,  true,  true, Attribute::None,     },
-  {  OC::QuadOp,                  "QuadOp",                   OCC::QuadOp,                   "quadOp",                     false,  true,  true,  true, false,  true,  true,  true,  true, Attribute::None,     },
-
-  // Bitcasts with different sizes                                                                                          void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64  function attribute
-  {  OC::BitcastI16toF16,         "BitcastI16toF16",          OCC::BitcastI16toF16,          "bitcastI16toF16",             true, false, false, false, false, false, false, false, false, Attribute::ReadNone, },
-  {  OC::BitcastF16toI16,         "BitcastF16toI16",          OCC::BitcastF16toI16,          "bitcastF16toI16",             true, false, false, false, false, false, false, false, false, Attribute::ReadNone, },
-  {  OC::BitcastI32toF32,         "BitcastI32toF32",          OCC::BitcastI32toF32,          "bitcastI32toF32",             true, false, false, false, false, false, false, false, false, Attribute::ReadNone, },
-  {  OC::BitcastF32toI32,         "BitcastF32toI32",          OCC::BitcastF32toI32,          "bitcastF32toI32",             true, false, false, false, false, false, false, false, false, Attribute::ReadNone, },
-  {  OC::BitcastI64toF64,         "BitcastI64toF64",          OCC::BitcastI64toF64,          "bitcastI64toF64",             true, false, false, false, false, false, false, false, false, Attribute::ReadNone, },
-  {  OC::BitcastF64toI64,         "BitcastF64toI64",          OCC::BitcastF64toI64,          "bitcastF64toI64",             true, false, false, false, false, false, false, false, false, Attribute::ReadNone, },
-
-  // Legacy floating-point                                                                                                  void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64  function attribute
-  {  OC::LegacyF32ToF16,          "LegacyF32ToF16",           OCC::LegacyF32ToF16,           "legacyF32ToF16",              true, false, false, false, false, false, false, false, false, Attribute::ReadNone, },
-  {  OC::LegacyF16ToF32,          "LegacyF16ToF32",           OCC::LegacyF16ToF32,           "legacyF16ToF32",              true, false, false, false, false, false, false, false, false, Attribute::ReadNone, },
-
-  // Double precision                                                                                                       void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64  function attribute
-  {  OC::LegacyDoubleToFloat,     "LegacyDoubleToFloat",      OCC::LegacyDoubleToFloat,      "legacyDoubleToFloat",         true, false, false, false, false, false, false, false, false, Attribute::ReadNone, },
-  {  OC::LegacyDoubleToSInt32,    "LegacyDoubleToSInt32",     OCC::LegacyDoubleToSInt32,     "legacyDoubleToSInt32",        true, false, false, false, false, false, false, false, false, Attribute::ReadNone, },
-  {  OC::LegacyDoubleToUInt32,    "LegacyDoubleToUInt32",     OCC::LegacyDoubleToUInt32,     "legacyDoubleToUInt32",        true, false, false, false, false, false, false, false, false, Attribute::ReadNone, },
-
-  // Wave                                                                                                                   void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64  function attribute
-  {  OC::WaveAllBitCount,         "WaveAllBitCount",          OCC::WaveAllOp,                "waveAllOp",                   true, false, false, false, false, false, false, false, false, Attribute::None,     },
-  {  OC::WavePrefixBitCount,      "WavePrefixBitCount",       OCC::WavePrefixOp,             "wavePrefixOp",                true, false, false, false, false, false, false, false, false, Attribute::None,     },
-
-  // Pixel shader                                                                                                           void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64  function attribute
-  {  OC::AttributeAtVertex,       "AttributeAtVertex",        OCC::AttributeAtVertex,        "attributeAtVertex",          false,  true,  true, false, false, false, false, false, false, Attribute::ReadNone, },
-
-  // Graphics shader                                                                                                        void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64  function attribute
-  {  OC::ViewID,                  "ViewID",                   OCC::ViewID,                   "viewID",                     false, false, false, false, false, false, false,  true, false, Attribute::ReadNone, },
-
-  // Resources                                                                                                              void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64  function attribute
-  {  OC::RawBufferLoad,           "RawBufferLoad",            OCC::RawBufferLoad,            "rawBufferLoad",              false,  true,  true, false, false, false,  true,  true, false, Attribute::ReadOnly, },
-  {  OC::RawBufferStore,          "RawBufferStore",           OCC::RawBufferStore,           "rawBufferStore",             false,  true,  true, false, false, false,  true,  true, false, Attribute::None,     },
+//   OpCode                       OpCode name,                OpCodeClass                    OpCodeClass name,              void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64,   udt,  function attribute
+  // Temporary, indexable, input, output registers                                                                          void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64,   udt,  function attribute
+  {  OC::TempRegLoad,             "TempRegLoad",              OCC::TempRegLoad,              "tempRegLoad",                false,  true,  true, false, false, false,  true,  true, false, false, Attribute::ReadOnly, },
+  {  OC::TempRegStore,            "TempRegStore",             OCC::TempRegStore,             "tempRegStore",               false,  true,  true, false, false, false,  true,  true, false, false, Attribute::None,     },
+  {  OC::MinPrecXRegLoad,         "MinPrecXRegLoad",          OCC::MinPrecXRegLoad,          "minPrecXRegLoad",            false,  true, false, false, false, false,  true, false, false, false, Attribute::ReadOnly, },
+  {  OC::MinPrecXRegStore,        "MinPrecXRegStore",         OCC::MinPrecXRegStore,         "minPrecXRegStore",           false,  true, false, false, false, false,  true, false, false, false, Attribute::None,     },
+  {  OC::LoadInput,               "LoadInput",                OCC::LoadInput,                "loadInput",                  false,  true,  true, false, false, false,  true,  true, false, false, Attribute::ReadNone, },
+  {  OC::StoreOutput,             "StoreOutput",              OCC::StoreOutput,              "storeOutput",                false,  true,  true, false, false, false,  true,  true, false, false, Attribute::None,     },
+
+  // Unary float                                                                                                            void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64,   udt,  function attribute
+  {  OC::FAbs,                    "FAbs",                     OCC::Unary,                    "unary",                      false,  true,  true,  true, false, false, false, false, false, false, Attribute::ReadNone, },
+  {  OC::Saturate,                "Saturate",                 OCC::Unary,                    "unary",                      false,  true,  true,  true, false, false, false, false, false, false, Attribute::ReadNone, },
+  {  OC::IsNaN,                   "IsNaN",                    OCC::IsSpecialFloat,           "isSpecialFloat",             false,  true,  true, false, false, false, false, false, false, false, Attribute::ReadNone, },
+  {  OC::IsInf,                   "IsInf",                    OCC::IsSpecialFloat,           "isSpecialFloat",             false,  true,  true, false, false, false, false, false, false, false, Attribute::ReadNone, },
+  {  OC::IsFinite,                "IsFinite",                 OCC::IsSpecialFloat,           "isSpecialFloat",             false,  true,  true, false, false, false, false, false, false, false, Attribute::ReadNone, },
+  {  OC::IsNormal,                "IsNormal",                 OCC::IsSpecialFloat,           "isSpecialFloat",             false,  true,  true, false, false, false, false, false, false, false, Attribute::ReadNone, },
+  {  OC::Cos,                     "Cos",                      OCC::Unary,                    "unary",                      false,  true,  true, false, false, false, false, false, false, false, Attribute::ReadNone, },
+  {  OC::Sin,                     "Sin",                      OCC::Unary,                    "unary",                      false,  true,  true, false, false, false, false, false, false, false, Attribute::ReadNone, },
+  {  OC::Tan,                     "Tan",                      OCC::Unary,                    "unary",                      false,  true,  true, false, false, false, false, false, false, false, Attribute::ReadNone, },
+  {  OC::Acos,                    "Acos",                     OCC::Unary,                    "unary",                      false,  true,  true, false, false, false, false, false, false, false, Attribute::ReadNone, },
+  {  OC::Asin,                    "Asin",                     OCC::Unary,                    "unary",                      false,  true,  true, false, false, false, false, false, false, false, Attribute::ReadNone, },
+  {  OC::Atan,                    "Atan",                     OCC::Unary,                    "unary",                      false,  true,  true, false, false, false, false, false, false, false, Attribute::ReadNone, },
+  {  OC::Hcos,                    "Hcos",                     OCC::Unary,                    "unary",                      false,  true,  true, false, false, false, false, false, false, false, Attribute::ReadNone, },
+  {  OC::Hsin,                    "Hsin",                     OCC::Unary,                    "unary",                      false,  true,  true, false, false, false, false, false, false, false, Attribute::ReadNone, },
+  {  OC::Htan,                    "Htan",                     OCC::Unary,                    "unary",                      false,  true,  true, false, false, false, false, false, false, false, Attribute::ReadNone, },
+  {  OC::Exp,                     "Exp",                      OCC::Unary,                    "unary",                      false,  true,  true, false, false, false, false, false, false, false, Attribute::ReadNone, },
+  {  OC::Frc,                     "Frc",                      OCC::Unary,                    "unary",                      false,  true,  true, false, false, false, false, false, false, false, Attribute::ReadNone, },
+  {  OC::Log,                     "Log",                      OCC::Unary,                    "unary",                      false,  true,  true, false, false, false, false, false, false, false, Attribute::ReadNone, },
+  {  OC::Sqrt,                    "Sqrt",                     OCC::Unary,                    "unary",                      false,  true,  true, false, false, false, false, false, false, false, Attribute::ReadNone, },
+  {  OC::Rsqrt,                   "Rsqrt",                    OCC::Unary,                    "unary",                      false,  true,  true, false, false, false, false, false, false, false, Attribute::ReadNone, },
+
+  // Unary float - rounding                                                                                                 void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64,   udt,  function attribute
+  {  OC::Round_ne,                "Round_ne",                 OCC::Unary,                    "unary",                      false,  true,  true, false, false, false, false, false, false, false, Attribute::ReadNone, },
+  {  OC::Round_ni,                "Round_ni",                 OCC::Unary,                    "unary",                      false,  true,  true, false, false, false, false, false, false, false, Attribute::ReadNone, },
+  {  OC::Round_pi,                "Round_pi",                 OCC::Unary,                    "unary",                      false,  true,  true, false, false, false, false, false, false, false, Attribute::ReadNone, },
+  {  OC::Round_z,                 "Round_z",                  OCC::Unary,                    "unary",                      false,  true,  true, false, false, false, false, false, false, false, Attribute::ReadNone, },
+
+  // Unary int                                                                                                              void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64,   udt,  function attribute
+  {  OC::Bfrev,                   "Bfrev",                    OCC::Unary,                    "unary",                      false, false, false, false, false, false,  true,  true,  true, false, Attribute::ReadNone, },
+  {  OC::Countbits,               "Countbits",                OCC::UnaryBits,                "unaryBits",                  false, false, false, false, false, false,  true,  true,  true, false, Attribute::ReadNone, },
+  {  OC::FirstbitLo,              "FirstbitLo",               OCC::UnaryBits,                "unaryBits",                  false, false, false, false, false, false,  true,  true,  true, false, Attribute::ReadNone, },
+
+  // Unary uint                                                                                                             void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64,   udt,  function attribute
+  {  OC::FirstbitHi,              "FirstbitHi",               OCC::UnaryBits,                "unaryBits",                  false, false, false, false, false, false,  true,  true,  true, false, Attribute::ReadNone, },
+
+  // Unary int                                                                                                              void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64,   udt,  function attribute
+  {  OC::FirstbitSHi,             "FirstbitSHi",              OCC::UnaryBits,                "unaryBits",                  false, false, false, false, false, false,  true,  true,  true, false, Attribute::ReadNone, },
+
+  // Binary float                                                                                                           void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64,   udt,  function attribute
+  {  OC::FMax,                    "FMax",                     OCC::Binary,                   "binary",                     false,  true,  true,  true, false, false, false, false, false, false, Attribute::ReadNone, },
+  {  OC::FMin,                    "FMin",                     OCC::Binary,                   "binary",                     false,  true,  true,  true, false, false, false, false, false, false, Attribute::ReadNone, },
+
+  // Binary int                                                                                                             void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64,   udt,  function attribute
+  {  OC::IMax,                    "IMax",                     OCC::Binary,                   "binary",                     false, false, false, false, false, false,  true,  true,  true, false, Attribute::ReadNone, },
+  {  OC::IMin,                    "IMin",                     OCC::Binary,                   "binary",                     false, false, false, false, false, false,  true,  true,  true, false, Attribute::ReadNone, },
+
+  // Binary uint                                                                                                            void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64,   udt,  function attribute
+  {  OC::UMax,                    "UMax",                     OCC::Binary,                   "binary",                     false, false, false, false, false, false,  true,  true,  true, false, Attribute::ReadNone, },
+  {  OC::UMin,                    "UMin",                     OCC::Binary,                   "binary",                     false, false, false, false, false, false,  true,  true,  true, false, Attribute::ReadNone, },
+
+  // Binary int with two outputs                                                                                            void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64,   udt,  function attribute
+  {  OC::IMul,                    "IMul",                     OCC::BinaryWithTwoOuts,        "binaryWithTwoOuts",          false, false, false, false, false, false, false,  true, false, false, Attribute::ReadNone, },
+
+  // Binary uint with two outputs                                                                                           void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64,   udt,  function attribute
+  {  OC::UMul,                    "UMul",                     OCC::BinaryWithTwoOuts,        "binaryWithTwoOuts",          false, false, false, false, false, false, false,  true, false, false, Attribute::ReadNone, },
+  {  OC::UDiv,                    "UDiv",                     OCC::BinaryWithTwoOuts,        "binaryWithTwoOuts",          false, false, false, false, false, false, false,  true, false, false, Attribute::ReadNone, },
+
+  // Binary uint with carry or borrow                                                                                       void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64,   udt,  function attribute
+  {  OC::UAddc,                   "UAddc",                    OCC::BinaryWithCarryOrBorrow,  "binaryWithCarryOrBorrow",    false, false, false, false, false, false, false,  true, false, false, Attribute::ReadNone, },
+  {  OC::USubb,                   "USubb",                    OCC::BinaryWithCarryOrBorrow,  "binaryWithCarryOrBorrow",    false, false, false, false, false, false, false,  true, false, false, Attribute::ReadNone, },
+
+  // Tertiary float                                                                                                         void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64,   udt,  function attribute
+  {  OC::FMad,                    "FMad",                     OCC::Tertiary,                 "tertiary",                   false,  true,  true,  true, false, false, false, false, false, false, Attribute::ReadNone, },
+  {  OC::Fma,                     "Fma",                      OCC::Tertiary,                 "tertiary",                   false, false, false,  true, false, false, false, false, false, false, Attribute::ReadNone, },
+
+  // Tertiary int                                                                                                           void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64,   udt,  function attribute
+  {  OC::IMad,                    "IMad",                     OCC::Tertiary,                 "tertiary",                   false, false, false, false, false, false,  true,  true,  true, false, Attribute::ReadNone, },
+
+  // Tertiary uint                                                                                                          void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64,   udt,  function attribute
+  {  OC::UMad,                    "UMad",                     OCC::Tertiary,                 "tertiary",                   false, false, false, false, false, false,  true,  true,  true, false, Attribute::ReadNone, },
+
+  // Tertiary int                                                                                                           void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64,   udt,  function attribute
+  {  OC::Msad,                    "Msad",                     OCC::Tertiary,                 "tertiary",                   false, false, false, false, false, false, false,  true,  true, false, Attribute::ReadNone, },
+  {  OC::Ibfe,                    "Ibfe",                     OCC::Tertiary,                 "tertiary",                   false, false, false, false, false, false, false,  true,  true, false, Attribute::ReadNone, },
+
+  // Tertiary uint                                                                                                          void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64,   udt,  function attribute
+  {  OC::Ubfe,                    "Ubfe",                     OCC::Tertiary,                 "tertiary",                   false, false, false, false, false, false, false,  true,  true, false, Attribute::ReadNone, },
+
+  // Quaternary                                                                                                             void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64,   udt,  function attribute
+  {  OC::Bfi,                     "Bfi",                      OCC::Quaternary,               "quaternary",                 false, false, false, false, false, false, false,  true, false, false, Attribute::ReadNone, },
+
+  // Dot                                                                                                                    void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64,   udt,  function attribute
+  {  OC::Dot2,                    "Dot2",                     OCC::Dot2,                     "dot2",                       false,  true,  true, false, false, false, false, false, false, false, Attribute::ReadNone, },
+  {  OC::Dot3,                    "Dot3",                     OCC::Dot3,                     "dot3",                       false,  true,  true, false, false, false, false, false, false, false, Attribute::ReadNone, },
+  {  OC::Dot4,                    "Dot4",                     OCC::Dot4,                     "dot4",                       false,  true,  true, false, false, false, false, false, false, false, Attribute::ReadNone, },
+
+  // Resources                                                                                                              void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64,   udt,  function attribute
+  {  OC::CreateHandle,            "CreateHandle",             OCC::CreateHandle,             "createHandle",                true, false, false, false, false, false, false, false, false, false, Attribute::ReadOnly, },
+  {  OC::CBufferLoad,             "CBufferLoad",              OCC::CBufferLoad,              "cbufferLoad",                false,  true,  true,  true, false,  true,  true,  true,  true, false, Attribute::ReadOnly, },
+  {  OC::CBufferLoadLegacy,       "CBufferLoadLegacy",        OCC::CBufferLoadLegacy,        "cbufferLoadLegacy",          false,  true,  true,  true, false, false,  true,  true,  true, false, Attribute::ReadOnly, },
+
+  // Resources - sample                                                                                                     void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64,   udt,  function attribute
+  {  OC::Sample,                  "Sample",                   OCC::Sample,                   "sample",                     false,  true,  true, false, false, false, false, false, false, false, Attribute::ReadOnly, },
+  {  OC::SampleBias,              "SampleBias",               OCC::SampleBias,               "sampleBias",                 false,  true,  true, false, false, false, false, false, false, false, Attribute::ReadOnly, },
+  {  OC::SampleLevel,             "SampleLevel",              OCC::SampleLevel,              "sampleLevel",                false,  true,  true, false, false, false, false, false, false, false, Attribute::ReadOnly, },
+  {  OC::SampleGrad,              "SampleGrad",               OCC::SampleGrad,               "sampleGrad",                 false,  true,  true, false, false, false, false, false, false, false, Attribute::ReadOnly, },
+  {  OC::SampleCmp,               "SampleCmp",                OCC::SampleCmp,                "sampleCmp",                  false,  true,  true, false, false, false, false, false, false, false, Attribute::ReadOnly, },
+  {  OC::SampleCmpLevelZero,      "SampleCmpLevelZero",       OCC::SampleCmpLevelZero,       "sampleCmpLevelZero",         false,  true,  true, false, false, false, false, false, false, false, Attribute::ReadOnly, },
+
+  // Resources                                                                                                              void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64,   udt,  function attribute
+  {  OC::TextureLoad,             "TextureLoad",              OCC::TextureLoad,              "textureLoad",                false,  true,  true, false, false, false,  true,  true, false, false, Attribute::ReadOnly, },
+  {  OC::TextureStore,            "TextureStore",             OCC::TextureStore,             "textureStore",               false,  true,  true, false, false, false,  true,  true, false, false, Attribute::None,     },
+  {  OC::BufferLoad,              "BufferLoad",               OCC::BufferLoad,               "bufferLoad",                 false,  true,  true, false, false, false,  true,  true, false, false, Attribute::ReadOnly, },
+  {  OC::BufferStore,             "BufferStore",              OCC::BufferStore,              "bufferStore",                false,  true,  true, false, false, false,  true,  true, false, false, Attribute::None,     },
+  {  OC::BufferUpdateCounter,     "BufferUpdateCounter",      OCC::BufferUpdateCounter,      "bufferUpdateCounter",         true, false, false, false, false, false, false, false, false, false, Attribute::None,     },
+  {  OC::CheckAccessFullyMapped,  "CheckAccessFullyMapped",   OCC::CheckAccessFullyMapped,   "checkAccessFullyMapped",     false, false, false, false, false, false, false,  true, false, false, Attribute::ReadOnly, },
+  {  OC::GetDimensions,           "GetDimensions",            OCC::GetDimensions,            "getDimensions",               true, false, false, false, false, false, false, false, false, false, Attribute::ReadOnly, },
+
+  // Resources - gather                                                                                                     void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64,   udt,  function attribute
+  {  OC::TextureGather,           "TextureGather",            OCC::TextureGather,            "textureGather",              false, false,  true, false, false, false, false,  true, false, false, Attribute::ReadOnly, },
+  {  OC::TextureGatherCmp,        "TextureGatherCmp",         OCC::TextureGatherCmp,         "textureGatherCmp",           false, false,  true, false, false, false, false,  true, false, false, Attribute::ReadOnly, },
+
+  // Resources - sample                                                                                                     void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64,   udt,  function attribute
+  {  OC::Texture2DMSGetSamplePosition, "Texture2DMSGetSamplePosition", OCC::Texture2DMSGetSamplePosition, "texture2DMSGetSamplePosition",   true, false, false, false, false, false, false, false, false, false, Attribute::ReadOnly, },
+  {  OC::RenderTargetGetSamplePosition, "RenderTargetGetSamplePosition", OCC::RenderTargetGetSamplePosition, "renderTargetGetSamplePosition",   true, false, false, false, false, false, false, false, false, false, Attribute::ReadOnly, },
+  {  OC::RenderTargetGetSampleCount, "RenderTargetGetSampleCount", OCC::RenderTargetGetSampleCount, "renderTargetGetSampleCount",   true, false, false, false, false, false, false, false, false, false, Attribute::ReadOnly, },
+
+  // Synchronization                                                                                                        void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64,   udt,  function attribute
+  {  OC::AtomicBinOp,             "AtomicBinOp",              OCC::AtomicBinOp,              "atomicBinOp",                false, false, false, false, false, false, false,  true, false, false, Attribute::None,     },
+  {  OC::AtomicCompareExchange,   "AtomicCompareExchange",    OCC::AtomicCompareExchange,    "atomicCompareExchange",      false, false, false, false, false, false, false,  true, false, false, Attribute::None,     },
+  {  OC::Barrier,                 "Barrier",                  OCC::Barrier,                  "barrier",                     true, false, false, false, false, false, false, false, false, false, Attribute::NoDuplicate, },
+
+  // Pixel shader                                                                                                           void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64,   udt,  function attribute
+  {  OC::CalculateLOD,            "CalculateLOD",             OCC::CalculateLOD,             "calculateLOD",               false, false,  true, false, false, false, false, false, false, false, Attribute::ReadOnly, },
+  {  OC::Discard,                 "Discard",                  OCC::Discard,                  "discard",                     true, false, false, false, false, false, false, false, false, false, Attribute::None,     },
+  {  OC::DerivCoarseX,            "DerivCoarseX",             OCC::Unary,                    "unary",                      false,  true,  true, false, false, false, false, false, false, false, Attribute::ReadNone, },
+  {  OC::DerivCoarseY,            "DerivCoarseY",             OCC::Unary,                    "unary",                      false,  true,  true, false, false, false, false, false, false, false, Attribute::ReadNone, },
+  {  OC::DerivFineX,              "DerivFineX",               OCC::Unary,                    "unary",                      false,  true,  true, false, false, false, false, false, false, false, Attribute::ReadNone, },
+  {  OC::DerivFineY,              "DerivFineY",               OCC::Unary,                    "unary",                      false,  true,  true, false, false, false, false, false, false, false, Attribute::ReadNone, },
+  {  OC::EvalSnapped,             "EvalSnapped",              OCC::EvalSnapped,              "evalSnapped",                false,  true,  true, false, false, false, false, false, false, false, Attribute::ReadNone, },
+  {  OC::EvalSampleIndex,         "EvalSampleIndex",          OCC::EvalSampleIndex,          "evalSampleIndex",            false,  true,  true, false, false, false, false, false, false, false, Attribute::ReadNone, },
+  {  OC::EvalCentroid,            "EvalCentroid",             OCC::EvalCentroid,             "evalCentroid",               false,  true,  true, false, false, false, false, false, false, false, Attribute::ReadNone, },
+  {  OC::SampleIndex,             "SampleIndex",              OCC::SampleIndex,              "sampleIndex",                false, false, false, false, false, false, false,  true, false, false, Attribute::ReadNone, },
+  {  OC::Coverage,                "Coverage",                 OCC::Coverage,                 "coverage",                   false, false, false, false, false, false, false,  true, false, false, Attribute::ReadNone, },
+  {  OC::InnerCoverage,           "InnerCoverage",            OCC::InnerCoverage,            "innerCoverage",              false, false, false, false, false, false, false,  true, false, false, Attribute::ReadNone, },
+
+  // Compute shader                                                                                                         void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64,   udt,  function attribute
+  {  OC::ThreadId,                "ThreadId",                 OCC::ThreadId,                 "threadId",                   false, false, false, false, false, false, false,  true, false, false, Attribute::ReadNone, },
+  {  OC::GroupId,                 "GroupId",                  OCC::GroupId,                  "groupId",                    false, false, false, false, false, false, false,  true, false, false, Attribute::ReadNone, },
+  {  OC::ThreadIdInGroup,         "ThreadIdInGroup",          OCC::ThreadIdInGroup,          "threadIdInGroup",            false, false, false, false, false, false, false,  true, false, false, Attribute::ReadNone, },
+  {  OC::FlattenedThreadIdInGroup, "FlattenedThreadIdInGroup", OCC::FlattenedThreadIdInGroup, "flattenedThreadIdInGroup",   false, false, false, false, false, false, false,  true, false, false, Attribute::ReadNone, },
+
+  // Geometry shader                                                                                                        void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64,   udt,  function attribute
+  {  OC::EmitStream,              "EmitStream",               OCC::EmitStream,               "emitStream",                  true, false, false, false, false, false, false, false, false, false, Attribute::None,     },
+  {  OC::CutStream,               "CutStream",                OCC::CutStream,                "cutStream",                   true, false, false, false, false, false, false, false, false, false, Attribute::None,     },
+  {  OC::EmitThenCutStream,       "EmitThenCutStream",        OCC::EmitThenCutStream,        "emitThenCutStream",           true, false, false, false, false, false, false, false, false, false, Attribute::None,     },
+  {  OC::GSInstanceID,            "GSInstanceID",             OCC::GSInstanceID,             "gsInstanceID",               false, false, false, false, false, false, false,  true, false, false, Attribute::ReadNone, },
+
+  // Double precision                                                                                                       void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64,   udt,  function attribute
+  {  OC::MakeDouble,              "MakeDouble",               OCC::MakeDouble,               "makeDouble",                 false, false, false,  true, false, false, false, false, false, false, Attribute::ReadNone, },
+  {  OC::SplitDouble,             "SplitDouble",              OCC::SplitDouble,              "splitDouble",                false, false, false,  true, false, false, false, false, false, false, Attribute::ReadNone, },
+
+  // Domain and hull shader                                                                                                 void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64,   udt,  function attribute
+  {  OC::LoadOutputControlPoint,  "LoadOutputControlPoint",   OCC::LoadOutputControlPoint,   "loadOutputControlPoint",     false,  true,  true, false, false, false,  true,  true, false, false, Attribute::ReadNone, },
+  {  OC::LoadPatchConstant,       "LoadPatchConstant",        OCC::LoadPatchConstant,        "loadPatchConstant",          false,  true,  true, false, false, false,  true,  true, false, false, Attribute::ReadNone, },
+
+  // Domain shader                                                                                                          void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64,   udt,  function attribute
+  {  OC::DomainLocation,          "DomainLocation",           OCC::DomainLocation,           "domainLocation",             false, false,  true, false, false, false, false, false, false, false, Attribute::ReadNone, },
+
+  // Hull shader                                                                                                            void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64,   udt,  function attribute
+  {  OC::StorePatchConstant,      "StorePatchConstant",       OCC::StorePatchConstant,       "storePatchConstant",         false,  true,  true, false, false, false,  true,  true, false, false, Attribute::None,     },
+  {  OC::OutputControlPointID,    "OutputControlPointID",     OCC::OutputControlPointID,     "outputControlPointID",       false, false, false, false, false, false, false,  true, false, false, Attribute::ReadNone, },
+  {  OC::PrimitiveID,             "PrimitiveID",              OCC::PrimitiveID,              "primitiveID",                false, false, false, false, false, false, false,  true, false, false, Attribute::ReadNone, },
+
+  // Other                                                                                                                  void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64,   udt,  function attribute
+  {  OC::CycleCounterLegacy,      "CycleCounterLegacy",       OCC::CycleCounterLegacy,       "cycleCounterLegacy",          true, false, false, false, false, false, false, false, false, false, Attribute::None,     },
+
+  // Wave                                                                                                                   void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64,   udt,  function attribute
+  {  OC::WaveIsFirstLane,         "WaveIsFirstLane",          OCC::WaveIsFirstLane,          "waveIsFirstLane",             true, false, false, false, false, false, false, false, false, false, Attribute::None,     },
+  {  OC::WaveGetLaneIndex,        "WaveGetLaneIndex",         OCC::WaveGetLaneIndex,         "waveGetLaneIndex",            true, false, false, false, false, false, false, false, false, false, Attribute::ReadNone, },
+  {  OC::WaveGetLaneCount,        "WaveGetLaneCount",         OCC::WaveGetLaneCount,         "waveGetLaneCount",            true, false, false, false, false, false, false, false, false, false, Attribute::ReadNone, },
+  {  OC::WaveAnyTrue,             "WaveAnyTrue",              OCC::WaveAnyTrue,              "waveAnyTrue",                 true, false, false, false, false, false, false, false, false, false, Attribute::None,     },
+  {  OC::WaveAllTrue,             "WaveAllTrue",              OCC::WaveAllTrue,              "waveAllTrue",                 true, false, false, false, false, false, false, false, false, false, Attribute::None,     },
+  {  OC::WaveActiveAllEqual,      "WaveActiveAllEqual",       OCC::WaveActiveAllEqual,       "waveActiveAllEqual",         false,  true,  true,  true,  true,  true,  true,  true,  true, false, Attribute::None,     },
+  {  OC::WaveActiveBallot,        "WaveActiveBallot",         OCC::WaveActiveBallot,         "waveActiveBallot",            true, false, false, false, false, false, false, false, false, false, Attribute::None,     },
+  {  OC::WaveReadLaneAt,          "WaveReadLaneAt",           OCC::WaveReadLaneAt,           "waveReadLaneAt",             false,  true,  true,  true,  true,  true,  true,  true,  true, false, Attribute::None,     },
+  {  OC::WaveReadLaneFirst,       "WaveReadLaneFirst",        OCC::WaveReadLaneFirst,        "waveReadLaneFirst",          false,  true,  true, false,  true,  true,  true,  true,  true, false, Attribute::None,     },
+  {  OC::WaveActiveOp,            "WaveActiveOp",             OCC::WaveActiveOp,             "waveActiveOp",               false,  true,  true,  true,  true,  true,  true,  true,  true, false, Attribute::None,     },
+  {  OC::WaveActiveBit,           "WaveActiveBit",            OCC::WaveActiveBit,            "waveActiveBit",              false, false, false, false, false,  true,  true,  true,  true, false, Attribute::None,     },
+  {  OC::WavePrefixOp,            "WavePrefixOp",             OCC::WavePrefixOp,             "wavePrefixOp",               false,  true,  true,  true, false,  true,  true,  true,  true, false, Attribute::None,     },
+  {  OC::QuadReadLaneAt,          "QuadReadLaneAt",           OCC::QuadReadLaneAt,           "quadReadLaneAt",             false,  true,  true,  true,  true,  true,  true,  true,  true, false, Attribute::None,     },
+  {  OC::QuadOp,                  "QuadOp",                   OCC::QuadOp,                   "quadOp",                     false,  true,  true,  true, false,  true,  true,  true,  true, false, Attribute::None,     },
+
+  // Bitcasts with different sizes                                                                                          void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64,   udt,  function attribute
+  {  OC::BitcastI16toF16,         "BitcastI16toF16",          OCC::BitcastI16toF16,          "bitcastI16toF16",             true, false, false, false, false, false, false, false, false, false, Attribute::ReadNone, },
+  {  OC::BitcastF16toI16,         "BitcastF16toI16",          OCC::BitcastF16toI16,          "bitcastF16toI16",             true, false, false, false, false, false, false, false, false, false, Attribute::ReadNone, },
+  {  OC::BitcastI32toF32,         "BitcastI32toF32",          OCC::BitcastI32toF32,          "bitcastI32toF32",             true, false, false, false, false, false, false, false, false, false, Attribute::ReadNone, },
+  {  OC::BitcastF32toI32,         "BitcastF32toI32",          OCC::BitcastF32toI32,          "bitcastF32toI32",             true, false, false, false, false, false, false, false, false, false, Attribute::ReadNone, },
+  {  OC::BitcastI64toF64,         "BitcastI64toF64",          OCC::BitcastI64toF64,          "bitcastI64toF64",             true, false, false, false, false, false, false, false, false, false, Attribute::ReadNone, },
+  {  OC::BitcastF64toI64,         "BitcastF64toI64",          OCC::BitcastF64toI64,          "bitcastF64toI64",             true, false, false, false, false, false, false, false, false, false, Attribute::ReadNone, },
+
+  // Legacy floating-point                                                                                                  void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64,   udt,  function attribute
+  {  OC::LegacyF32ToF16,          "LegacyF32ToF16",           OCC::LegacyF32ToF16,           "legacyF32ToF16",              true, false, false, false, false, false, false, false, false, false, Attribute::ReadNone, },
+  {  OC::LegacyF16ToF32,          "LegacyF16ToF32",           OCC::LegacyF16ToF32,           "legacyF16ToF32",              true, false, false, false, false, false, false, false, false, false, Attribute::ReadNone, },
+
+  // Double precision                                                                                                       void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64,   udt,  function attribute
+  {  OC::LegacyDoubleToFloat,     "LegacyDoubleToFloat",      OCC::LegacyDoubleToFloat,      "legacyDoubleToFloat",         true, false, false, false, false, false, false, false, false, false, Attribute::ReadNone, },
+  {  OC::LegacyDoubleToSInt32,    "LegacyDoubleToSInt32",     OCC::LegacyDoubleToSInt32,     "legacyDoubleToSInt32",        true, false, false, false, false, false, false, false, false, false, Attribute::ReadNone, },
+  {  OC::LegacyDoubleToUInt32,    "LegacyDoubleToUInt32",     OCC::LegacyDoubleToUInt32,     "legacyDoubleToUInt32",        true, false, false, false, false, false, false, false, false, false, Attribute::ReadNone, },
+
+  // Wave                                                                                                                   void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64,   udt,  function attribute
+  {  OC::WaveAllBitCount,         "WaveAllBitCount",          OCC::WaveAllOp,                "waveAllOp",                   true, false, false, false, false, false, false, false, false, false, Attribute::None,     },
+  {  OC::WavePrefixBitCount,      "WavePrefixBitCount",       OCC::WavePrefixOp,             "wavePrefixOp",                true, false, false, false, false, false, false, false, false, false, Attribute::None,     },
+
+  // Pixel shader                                                                                                           void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64,   udt,  function attribute
+  {  OC::AttributeAtVertex,       "AttributeAtVertex",        OCC::AttributeAtVertex,        "attributeAtVertex",          false,  true,  true, false, false, false, false, false, false, false, Attribute::ReadNone, },
+
+  // Graphics shader                                                                                                        void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64,   udt,  function attribute
+  {  OC::ViewID,                  "ViewID",                   OCC::ViewID,                   "viewID",                     false, false, false, false, false, false, false,  true, false, false, Attribute::ReadNone, },
+
+  // Resources                                                                                                              void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64,   udt,  function attribute
+  {  OC::RawBufferLoad,           "RawBufferLoad",            OCC::RawBufferLoad,            "rawBufferLoad",              false,  true,  true, false, false, false,  true,  true, false, false, Attribute::ReadOnly, },
+  {  OC::RawBufferStore,          "RawBufferStore",           OCC::RawBufferStore,           "rawBufferStore",             false,  true,  true, false, false, false,  true,  true, false, false, Attribute::None,     },
+
+  // Ray Tracing                                                                                                            void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64,   udt,  function attribute
+  {  OC::InstanceIndex,           "InstanceIndex",            OCC::InstanceIndex,            "instanceIndex",              false, false, false, false, false, false, false,  true, false, false, Attribute::ReadNone, },
+  {  OC::HitKind,                 "HitKind",                  OCC::HitKind,                  "hitKind",                    false, false, false, false, false, false, false,  true, false, false, Attribute::ReadNone, },
+  {  OC::RayFlag,                 "RayFlag",                  OCC::RayFlag,                  "rayFlag",                    false, false, false, false, false, false, false,  true, false, false, Attribute::ReadNone, },
+  {  OC::RayDispatchIndex,        "RayDispatchIndex",         OCC::RayDispatchIndex,         "rayDispatchIndex",           false, false, false, false, false, false, false,  true, false, false, Attribute::ReadNone, },
+  {  OC::RayDispatchDimension,    "RayDispatchDimension",     OCC::RayDispatchDimension,     "rayDispatchDimension",       false, false, false, false, false, false, false,  true, false, false, Attribute::ReadNone, },
+  {  OC::WorldRayOrigin,          "WorldRayOrigin",           OCC::WorldRayOrigin,           "worldRayOrigin",             false, false,  true, false, false, false, false, false, false, false, Attribute::ReadNone, },
+  {  OC::WorldRayDirection,       "WorldRayDirection",        OCC::WorldRayDirection,        "worldRayDirection",          false, false,  true, false, false, false, false, false, false, false, Attribute::ReadNone, },
+  {  OC::ObjectRayOrigin,         "ObjectRayOrigin",          OCC::ObjectRayOrigin,          "objectRayOrigin",            false, false,  true, false, false, false, false, false, false, false, Attribute::ReadNone, },
+  {  OC::ObjectRayDirection,      "ObjectRayDirection",       OCC::ObjectRayDirection,       "objectRayDirection",         false, false,  true, false, false, false, false, false, false, false, Attribute::ReadNone, },
+  {  OC::ObjectToWorld,           "ObjectToWorld",            OCC::ObjectToWorld,            "objectToWorld",              false, false,  true, false, false, false, false, false, false, false, Attribute::ReadNone, },
+  {  OC::WorldToObject,           "WorldToObject",            OCC::WorldToObject,            "worldToObject",              false, false,  true, false, false, false, false, false, false, false, Attribute::ReadNone, },
+  {  OC::RayTMin,                 "RayTMin",                  OCC::RayTMin,                  "rayTMin",                    false, false,  true, false, false, false, false, false, false, false, Attribute::ReadNone, },
+  {  OC::CurrentRayT,             "CurrentRayT",              OCC::CurrentRayT,              "currentRayT",                false, false,  true, false, false, false, false, false, false, false, Attribute::ReadNone, },
+  {  OC::IgnoreIntersection,      "IgnoreIntersection",       OCC::IgnoreIntersection,       "ignoreIntersection",          true, false, false, false, false, false, false, false, false, false, Attribute::ReadNone, },
+  {  OC::TerminateRay,            "TerminateRay",             OCC::TerminateRay,             "terminateRay",                true, false, false, false, false, false, false, false, false, false, Attribute::ReadNone, },
+  {  OC::TraceRay,                "TraceRay",                 OCC::TraceRay,                 "traceRay",                   false, false, false, false, false, false, false, false, false,  true, Attribute::None,     },
+  {  OC::ReportIntersection,      "ReportIntersection",       OCC::ReportIntersection,       "reportIntersection",         false, false, false, false, false, false, false, false, false,  true, Attribute::ReadOnly, },
+  {  OC::CallShader,              "CallShader",               OCC::CallShader,               "callShader",                  true, false, false, false, false, false, false, false, false, false, Attribute::None,     },
+  {  OC::ReservedForLibCreateHandleFromResourceStruct, "ReservedForLibCreateHandleFromResourceStruct", OCC::ReservedForLibCreateHandleFromResourceStruct, "reservedForLibCreateHandleFromResourceStruct",  false, false, false, false, false, false, false,  true, false, false, Attribute::ReadNone, },
 };
 };
 // OPCODE-OLOADS:END
 // OPCODE-OLOADS:END
 
 
 const char *OP::m_OverloadTypeName[kNumTypeOverloads] = {
 const char *OP::m_OverloadTypeName[kNumTypeOverloads] = {
-  "void", "f16", "f32", "f64", "i1", "i8", "i16", "i32", "i64"
+  "void", "f16", "f32", "f64", "i1", "i8", "i16", "i32", "i64", "udt",
 };
 };
 
 
 const char *OP::m_NamePrefix = "dx.op.";
 const char *OP::m_NamePrefix = "dx.op.";
@@ -307,6 +328,7 @@ unsigned OP::GetTypeSlot(Type *pType) {
     case 64:              return 8;
     case 64:              return 8;
     }
     }
   }
   }
+  case Type::PointerTyID: return 9;
   default:
   default:
     break;
     break;
   }
   }
@@ -314,10 +336,22 @@ unsigned OP::GetTypeSlot(Type *pType) {
 }
 }
 
 
 const char *OP::GetOverloadTypeName(unsigned TypeSlot) {
 const char *OP::GetOverloadTypeName(unsigned TypeSlot) {
-  DXASSERT(TypeSlot < kNumTypeOverloads, "otherwise caller passed OOB index");
+  DXASSERT(TypeSlot < kUserDefineTypeSlot, "otherwise caller passed OOB index");
   return m_OverloadTypeName[TypeSlot];
   return m_OverloadTypeName[TypeSlot];
 }
 }
 
 
+const char * OP::GetTypeName(Type *Ty, std::string &str) {
+  unsigned TypeSlot = OP::GetTypeSlot(Ty);
+  if (TypeSlot < kUserDefineTypeSlot) {
+    return GetOverloadTypeName(TypeSlot);
+  } else {
+    raw_string_ostream os(str);
+    Ty->print(os);
+    os.flush();
+    return str.c_str();
+  }
+}
+
 const char *OP::GetOpCodeName(OpCode OpCode) {
 const char *OP::GetOpCodeName(OpCode OpCode) {
   DXASSERT(0 <= (unsigned)OpCode && OpCode < OpCode::NumOpCodes, "otherwise caller passed OOB index");
   DXASSERT(0 <= (unsigned)OpCode && OpCode < OpCode::NumOpCodes, "otherwise caller passed OOB index");
   return m_OpCodeProps[(unsigned)OpCode].pOpCodeName;
   return m_OpCodeProps[(unsigned)OpCode].pOpCodeName;
@@ -498,8 +532,8 @@ void OP::RefreshCache() {
   }
   }
 }
 }
 
 
-void OP::UpdateCache(OpCodeClass opClass, unsigned typeSlot, llvm::Function *F) {
-  m_OpCodeClassCache[(unsigned)opClass].pOverloads[typeSlot] = F;
+void OP::UpdateCache(OpCodeClass opClass, Type * Ty, llvm::Function *F) {
+  m_OpCodeClassCache[(unsigned)opClass].pOverloads[Ty] = F;
   m_FunctionToOpClass[F] = opClass;
   m_FunctionToOpClass[F] = opClass;
 }
 }
 
 
@@ -507,11 +541,10 @@ Function *OP::GetOpFunc(OpCode OpCode, Type *pOverloadType) {
   DXASSERT(0 <= (unsigned)OpCode && OpCode < OpCode::NumOpCodes, "otherwise caller passed OOB OpCode");
   DXASSERT(0 <= (unsigned)OpCode && OpCode < OpCode::NumOpCodes, "otherwise caller passed OOB OpCode");
   _Analysis_assume_(0 <= (unsigned)OpCode && OpCode < OpCode::NumOpCodes);
   _Analysis_assume_(0 <= (unsigned)OpCode && OpCode < OpCode::NumOpCodes);
   DXASSERT(IsOverloadLegal(OpCode, pOverloadType), "otherwise the caller requested illegal operation overload (eg HLSL function with unsupported types for mapped intrinsic function)");
   DXASSERT(IsOverloadLegal(OpCode, pOverloadType), "otherwise the caller requested illegal operation overload (eg HLSL function with unsupported types for mapped intrinsic function)");
-  unsigned TypeSlot = GetTypeSlot(pOverloadType);
   OpCodeClass opClass = m_OpCodeProps[(unsigned)OpCode].OpCodeClass;
   OpCodeClass opClass = m_OpCodeProps[(unsigned)OpCode].OpCodeClass;
-  Function *&F = m_OpCodeClassCache[(unsigned)opClass].pOverloads[TypeSlot];
+  Function *&F = m_OpCodeClassCache[(unsigned)opClass].pOverloads[pOverloadType];
   if (F != nullptr) {
   if (F != nullptr) {
-    UpdateCache(opClass, TypeSlot, F);
+    UpdateCache(opClass, pOverloadType, F);
     return F;
     return F;
   }
   }
 
 
@@ -535,16 +568,18 @@ Function *OP::GetOpFunc(OpCode OpCode, Type *pOverloadType) {
   Type *pF64 = Type::getDoubleTy(m_Ctx);
   Type *pF64 = Type::getDoubleTy(m_Ctx);
   Type *pSDT = GetSplitDoubleType();  // Split double type.
   Type *pSDT = GetSplitDoubleType();  // Split double type.
   Type *pI4S = GetInt4Type(); // 4 i32s in a struct.
   Type *pI4S = GetInt4Type(); // 4 i32s in a struct.
+  Type *udt = pOverloadType;
 
 
   std::string funcName = (Twine(OP::m_NamePrefix) + Twine(GetOpCodeClassName(OpCode))).str();
   std::string funcName = (Twine(OP::m_NamePrefix) + Twine(GetOpCodeClassName(OpCode))).str();
   // Add ret type to the name.
   // Add ret type to the name.
   if (pOverloadType != pV) {
   if (pOverloadType != pV) {
-    funcName = Twine(funcName).concat(".").concat(GetOverloadTypeName(TypeSlot)).str();
+    std::string typeName;
+    funcName = Twine(funcName).concat(".").concat(GetTypeName(pOverloadType, typeName)).str();
   } 
   } 
   // Try to find exist function with the same name in the module.
   // Try to find exist function with the same name in the module.
   if (Function *existF = m_pModule->getFunction(funcName)) {
   if (Function *existF = m_pModule->getFunction(funcName)) {
     F = existF;
     F = existF;
-    UpdateCache(opClass, TypeSlot, F);
+    UpdateCache(opClass, pOverloadType, F);
     return F;
     return F;
   }
   }
 
 
@@ -777,6 +812,27 @@ Function *OP::GetOpFunc(OpCode OpCode, Type *pOverloadType) {
     // Resources
     // Resources
   case OpCode::RawBufferLoad:          RRT(pETy);   A(pI32); A(pRes); A(pI32); A(pI32); A(pI8);  A(pI32); break;
   case OpCode::RawBufferLoad:          RRT(pETy);   A(pI32); A(pRes); A(pI32); A(pI32); A(pI8);  A(pI32); break;
   case OpCode::RawBufferStore:         A(pV);       A(pI32); A(pRes); A(pI32); A(pI32); A(pETy); A(pETy); A(pETy); A(pETy); A(pI8);  A(pI32); break;
   case OpCode::RawBufferStore:         A(pV);       A(pI32); A(pRes); A(pI32); A(pI32); A(pETy); A(pETy); A(pETy); A(pETy); A(pI8);  A(pI32); break;
+
+    // Ray Tracing
+  case OpCode::InstanceIndex:          A(pI32);     A(pI32); break;
+  case OpCode::HitKind:                A(pI32);     A(pI32); break;
+  case OpCode::RayFlag:                A(pI32);     A(pI32); break;
+  case OpCode::RayDispatchIndex:       A(pI32);     A(pI32); A(pI8);  break;
+  case OpCode::RayDispatchDimension:   A(pI32);     A(pI32); A(pI8);  break;
+  case OpCode::WorldRayOrigin:         A(pF32);     A(pI32); A(pI8);  break;
+  case OpCode::WorldRayDirection:      A(pF32);     A(pI32); A(pI8);  break;
+  case OpCode::ObjectRayOrigin:        A(pF32);     A(pI32); A(pI8);  break;
+  case OpCode::ObjectRayDirection:     A(pF32);     A(pI32); A(pI8);  break;
+  case OpCode::ObjectToWorld:          A(pF32);     A(pI32); A(pI32); A(pI8);  break;
+  case OpCode::WorldToObject:          A(pF32);     A(pI32); A(pI32); A(pI8);  break;
+  case OpCode::RayTMin:                A(pF32);     A(pI32); break;
+  case OpCode::CurrentRayT:            A(pF32);     A(pI32); break;
+  case OpCode::IgnoreIntersection:     A(pV);       A(pI32); break;
+  case OpCode::TerminateRay:           A(pV);       A(pI32); break;
+  case OpCode::TraceRay:               A(pV);       A(pI32); A(pRes); A(pI32); A(pI32); A(pI32); A(pI32); A(pI32); A(pF32); A(pF32); A(pF32); A(pF32); A(pF32); A(pF32); A(pF32); A(pF32); A(udt);  break;
+  case OpCode::ReportIntersection:     A(pI1);      A(pI32); A(pF32); A(pI32); A(udt);  break;
+  case OpCode::CallShader:             A(pV);       A(pI32); A(pI32); A(udt);  break;
+  case OpCode::ReservedForLibCreateHandleFromResourceStruct:A(pI32);     A(pI32); break;
   // OPCODE-OLOAD-FUNCS:END
   // OPCODE-OLOAD-FUNCS:END
   default: DXASSERT(false, "otherwise unhandled case"); break;
   default: DXASSERT(false, "otherwise unhandled case"); break;
   }
   }
@@ -789,7 +845,7 @@ Function *OP::GetOpFunc(OpCode OpCode, Type *pOverloadType) {
 
 
   F = cast<Function>(m_pModule->getOrInsertFunction(funcName, pFT));
   F = cast<Function>(m_pModule->getOrInsertFunction(funcName, pFT));
 
 
-  UpdateCache(opClass, TypeSlot, F);
+  UpdateCache(opClass, pOverloadType, F);
   F->setCallingConv(CallingConv::C);
   F->setCallingConv(CallingConv::C);
   F->addFnAttr(Attribute::NoUnwind);
   F->addFnAttr(Attribute::NoUnwind);
   if (m_OpCodeProps[(unsigned)OpCode].FuncAttr != Attribute::None)
   if (m_OpCodeProps[(unsigned)OpCode].FuncAttr != Attribute::None)
@@ -798,18 +854,22 @@ Function *OP::GetOpFunc(OpCode OpCode, Type *pOverloadType) {
   return F;
   return F;
 }
 }
 
 
-llvm::ArrayRef<llvm::Function *> OP::GetOpFuncList(OpCode OpCode) const {
-  DXASSERT(0 <= (unsigned)OpCode && OpCode < OpCode::NumOpCodes, "otherwise caller passed OOB OpCode");
+const SmallDenseMap<llvm::Type *, llvm::Function *, 8> &
+OP::GetOpFuncList(OpCode OpCode) const {
+  DXASSERT(0 <= (unsigned)OpCode && OpCode < OpCode::NumOpCodes,
+           "otherwise caller passed OOB OpCode");
   _Analysis_assume_(0 <= (unsigned)OpCode && OpCode < OpCode::NumOpCodes);
   _Analysis_assume_(0 <= (unsigned)OpCode && OpCode < OpCode::NumOpCodes);
-  return m_OpCodeClassCache[(unsigned)m_OpCodeProps[(unsigned)OpCode].OpCodeClass].pOverloads;
+  return m_OpCodeClassCache[(unsigned)m_OpCodeProps[(unsigned)OpCode]
+                                .OpCodeClass]
+      .pOverloads;
 }
 }
 
 
 void OP::RemoveFunction(Function *F) {
 void OP::RemoveFunction(Function *F) {
   if (OP::IsDxilOpFunc(F)) {
   if (OP::IsDxilOpFunc(F)) {
     OpCodeClass opClass = m_FunctionToOpClass[F];
     OpCodeClass opClass = m_FunctionToOpClass[F];
-    for (unsigned i=0;i<kNumTypeOverloads;i++) {
-      if (F == m_OpCodeClassCache[(unsigned)opClass].pOverloads[i]) {
-        m_OpCodeClassCache[(unsigned)opClass].pOverloads[i] = nullptr;
+    for (auto it : m_OpCodeClassCache[(unsigned)opClass].pOverloads) {
+      if (it.second == F) {
+        m_OpCodeClassCache[(unsigned)opClass].pOverloads.erase(it.first);
         m_FunctionToOpClass.erase(F);
         m_FunctionToOpClass.erase(F);
         break;
         break;
       }
       }
@@ -856,6 +916,7 @@ llvm::Type *OP::GetOverloadType(OpCode OpCode, llvm::Function *F) {
   switch (OpCode) {            // return     OpCode
   switch (OpCode) {            // return     OpCode
   // OPCODE-OLOAD-TYPES:BEGIN
   // OPCODE-OLOAD-TYPES:BEGIN
   case OpCode::TempRegStore:
   case OpCode::TempRegStore:
+  case OpCode::CallShader:
     DXASSERT_NOMSG(FT->getNumParams() > 2);
     DXASSERT_NOMSG(FT->getNumParams() > 2);
     return FT->getParamType(2);
     return FT->getParamType(2);
   case OpCode::MinPrecXRegStore:
   case OpCode::MinPrecXRegStore:
@@ -884,6 +945,12 @@ llvm::Type *OP::GetOverloadType(OpCode OpCode, llvm::Function *F) {
   case OpCode::TextureStore:
   case OpCode::TextureStore:
     DXASSERT_NOMSG(FT->getNumParams() > 5);
     DXASSERT_NOMSG(FT->getNumParams() > 5);
     return FT->getParamType(5);
     return FT->getParamType(5);
+  case OpCode::TraceRay:
+    DXASSERT_NOMSG(FT->getNumParams() > 15);
+    return FT->getParamType(15);
+  case OpCode::ReportIntersection:
+    DXASSERT_NOMSG(FT->getNumParams() > 3);
+    return FT->getParamType(3);
   case OpCode::CreateHandle:
   case OpCode::CreateHandle:
   case OpCode::BufferUpdateCounter:
   case OpCode::BufferUpdateCounter:
   case OpCode::GetDimensions:
   case OpCode::GetDimensions:
@@ -915,6 +982,8 @@ llvm::Type *OP::GetOverloadType(OpCode OpCode, llvm::Function *F) {
   case OpCode::LegacyDoubleToUInt32:
   case OpCode::LegacyDoubleToUInt32:
   case OpCode::WaveAllBitCount:
   case OpCode::WaveAllBitCount:
   case OpCode::WavePrefixBitCount:
   case OpCode::WavePrefixBitCount:
+  case OpCode::IgnoreIntersection:
+  case OpCode::TerminateRay:
     return Type::getVoidTy(m_Ctx);
     return Type::getVoidTy(m_Ctx);
   case OpCode::CheckAccessFullyMapped:
   case OpCode::CheckAccessFullyMapped:
   case OpCode::AtomicBinOp:
   case OpCode::AtomicBinOp:
@@ -930,9 +999,23 @@ llvm::Type *OP::GetOverloadType(OpCode OpCode, llvm::Function *F) {
   case OpCode::OutputControlPointID:
   case OpCode::OutputControlPointID:
   case OpCode::PrimitiveID:
   case OpCode::PrimitiveID:
   case OpCode::ViewID:
   case OpCode::ViewID:
+  case OpCode::InstanceIndex:
+  case OpCode::HitKind:
+  case OpCode::RayFlag:
+  case OpCode::RayDispatchIndex:
+  case OpCode::RayDispatchDimension:
+  case OpCode::ReservedForLibCreateHandleFromResourceStruct:
     return IntegerType::get(m_Ctx, 32);
     return IntegerType::get(m_Ctx, 32);
   case OpCode::CalculateLOD:
   case OpCode::CalculateLOD:
   case OpCode::DomainLocation:
   case OpCode::DomainLocation:
+  case OpCode::WorldRayOrigin:
+  case OpCode::WorldRayDirection:
+  case OpCode::ObjectRayOrigin:
+  case OpCode::ObjectRayDirection:
+  case OpCode::ObjectToWorld:
+  case OpCode::WorldToObject:
+  case OpCode::RayTMin:
+  case OpCode::CurrentRayT:
     return Type::getFloatTy(m_Ctx);
     return Type::getFloatTy(m_Ctx);
   case OpCode::MakeDouble:
   case OpCode::MakeDouble:
   case OpCode::SplitDouble:
   case OpCode::SplitDouble:

+ 4 - 0
lib/HLSL/DxilResource.cpp

@@ -141,6 +141,7 @@ unsigned DxilResource::GetNumCoords(Kind ResourceKind) {
       0, // CBuffer,
       0, // CBuffer,
       0, // Sampler,
       0, // Sampler,
       1, // TBuffer,
       1, // TBuffer,
+      0, // RayTracingAccelerationStructure,
   };
   };
   static_assert(_countof(CoordSizeTab) == (unsigned)Kind::NumEntries, "check helper array size");
   static_assert(_countof(CoordSizeTab) == (unsigned)Kind::NumEntries, "check helper array size");
   DXASSERT(ResourceKind > Kind::Invalid && ResourceKind < Kind::NumEntries, "otherwise the caller passed wrong resource type");
   DXASSERT(ResourceKind > Kind::Invalid && ResourceKind < Kind::NumEntries, "otherwise the caller passed wrong resource type");
@@ -165,6 +166,7 @@ unsigned DxilResource::GetNumDimensions(Kind ResourceKind) {
       0, // CBuffer,
       0, // CBuffer,
       0, // Sampler,
       0, // Sampler,
       1, // TBuffer,
       1, // TBuffer,
+      0, // RayTracingAccelerationStructure,
   };
   };
   static_assert(_countof(NumDimTab) == (unsigned)Kind::NumEntries, "check helper array size");
   static_assert(_countof(NumDimTab) == (unsigned)Kind::NumEntries, "check helper array size");
   DXASSERT(ResourceKind > Kind::Invalid && ResourceKind < Kind::NumEntries, "otherwise the caller passed wrong resource type");
   DXASSERT(ResourceKind > Kind::Invalid && ResourceKind < Kind::NumEntries, "otherwise the caller passed wrong resource type");
@@ -189,6 +191,7 @@ unsigned DxilResource::GetNumDimensionsForCalcLOD(Kind ResourceKind) {
       0, // CBuffer,
       0, // CBuffer,
       0, // Sampler,
       0, // Sampler,
       1, // TBuffer,
       1, // TBuffer,
+      0, // RayTracingAccelerationStructure,
   };
   };
   static_assert(_countof(NumDimTab) == (unsigned)Kind::NumEntries, "check helper array size");
   static_assert(_countof(NumDimTab) == (unsigned)Kind::NumEntries, "check helper array size");
   DXASSERT(ResourceKind > Kind::Invalid && ResourceKind < Kind::NumEntries, "otherwise the caller passed wrong resource type");
   DXASSERT(ResourceKind > Kind::Invalid && ResourceKind < Kind::NumEntries, "otherwise the caller passed wrong resource type");
@@ -213,6 +216,7 @@ unsigned DxilResource::GetNumOffsets(Kind ResourceKind) {
       0, // CBuffer,
       0, // CBuffer,
       0, // Sampler,
       0, // Sampler,
       1, // TBuffer,
       1, // TBuffer,
+      0, // RayTracingAccelerationStructure,
   };
   };
   static_assert(_countof(OffsetSizeTab) == (unsigned)Kind::NumEntries, "check helper array size");
   static_assert(_countof(OffsetSizeTab) == (unsigned)Kind::NumEntries, "check helper array size");
   DXASSERT(ResourceKind > Kind::Invalid && ResourceKind < Kind::NumEntries, "otherwise the caller passed wrong resource type");
   DXASSERT(ResourceKind > Kind::Invalid && ResourceKind < Kind::NumEntries, "otherwise the caller passed wrong resource type");

+ 1 - 1
lib/HLSL/DxilResourceBase.cpp

@@ -84,7 +84,7 @@ static const char *s_ResourceDimNames[(unsigned)DxilResourceBase::Kind::NumEntri
         "invalid", "1d",        "2d",      "2dMS",      "3d",
         "invalid", "1d",        "2d",      "2dMS",      "3d",
         "cube",    "1darray",   "2darray", "2darrayMS", "cubearray",
         "cube",    "1darray",   "2darray", "2darrayMS", "cubearray",
         "buf",     "rawbuf",    "structbuf", "cbuffer", "sampler",
         "buf",     "rawbuf",    "structbuf", "cbuffer", "sampler",
-        "tbuffer",
+        "tbuffer", "rtacceleration",
 };
 };
 
 
 const char *DxilResourceBase::GetResDimName() const {
 const char *DxilResourceBase::GetResDimName() const {

+ 10 - 0
lib/HLSL/DxilValidation.cpp

@@ -603,6 +603,16 @@ static bool ValidateOpcodeInProfile(DXIL::OpCode opcode,
   // Instructions: RawBufferLoad=139, RawBufferStore=140
   // Instructions: RawBufferLoad=139, RawBufferStore=140
   if (139 <= op && op <= 140)
   if (139 <= op && op <= 140)
     return (pSM->GetMajor() > 6 || (pSM->GetMajor() == 6 && pSM->GetMinor() >= 2));
     return (pSM->GetMajor() > 6 || (pSM->GetMajor() == 6 && pSM->GetMinor() >= 2));
+  // Instructions: InstanceIndex=141, HitKind=142, RayFlag=143,
+  // RayDispatchIndex=144, RayDispatchDimension=145, WorldRayOrigin=146,
+  // WorldRayDirection=147, ObjectRayOrigin=148, ObjectRayDirection=149,
+  // ObjectToWorld=150, WorldToObject=151, RayTMin=152, CurrentRayT=153,
+  // IgnoreIntersection=154, TerminateRay=155, TraceRay=156,
+  // ReportIntersection=157, CallShader=158,
+  // ReservedForLibCreateHandleFromResourceStruct=159
+  if (141 <= op && op <= 159)
+    return (pSM->GetMajor() > 6 || (pSM->GetMajor() == 6 && pSM->GetMinor() >= 3))
+        && (pSM->IsLib());
   return true;
   return true;
   // VALOPCODESM-TEXT:END
   // VALOPCODESM-TEXT:END
 }
 }

+ 78 - 2
lib/HLSL/HLOperationLower.cpp

@@ -4229,6 +4229,82 @@ Value *TranslateProcessTessFactors(CallInst *CI, IntrinsicOp IOP, OP::OpCode opc
 
 
 }
 }
 
 
+// Ray Tracing.
+namespace {
+Value *TranslateReportIntersection(CallInst *CI, IntrinsicOp IOP,
+                                   OP::OpCode opcode,
+                                   HLOperationLowerHelper &helper,
+                                   HLObjectOperationLowerHelper *pObjHelper,
+                                   bool &Translated) {
+  hlsl::OP *hlslOP = &helper.hlslOP;
+  Value *THit = CI->getArgOperand(HLOperandIndex::kTrinaryOpSrc0Idx);
+  Value *HitKind = CI->getArgOperand(HLOperandIndex::kTrinaryOpSrc1Idx);
+  Value *Attr = CI->getArgOperand(HLOperandIndex::kTrinaryOpSrc2Idx);
+  Value *opArg = hlslOP->GetU32Const(static_cast<unsigned>(opcode));
+
+  Type *Ty = Attr->getType();
+  Function *F = hlslOP->GetOpFunc(opcode, Ty);
+
+  IRBuilder<> Builder(CI);
+  return Builder.CreateCall(F, {opArg, THit, HitKind, Attr});
+}
+Value *TranslateTraceRay(CallInst *CI, IntrinsicOp IOP, OP::OpCode opcode,
+                         HLOperationLowerHelper &helper,
+                         HLObjectOperationLowerHelper *pObjHelper,
+                         bool &Translated) {
+  hlsl::OP *hlslOP = &helper.hlslOP;
+
+  Value *rayDesc = CI->getArgOperand(HLOperandIndex::kTraceRayRayDescOpIdx);
+  Value *payLoad = CI->getArgOperand(HLOperandIndex::kTraceRayPayLoadOpIdx);
+
+  Value *opArg = hlslOP->GetU32Const(static_cast<unsigned>(opcode));
+
+  Value *Args[DXIL::OperandIndex::kTraceRayNumOp];
+  Args[0] = opArg;
+  for (unsigned i = 1; i < HLOperandIndex::kTraceRayRayDescOpIdx; i++) {
+    Args[i] = CI->getArgOperand(i);
+  }
+  IRBuilder<> Builder(CI);
+  // struct RayDesc
+  //{
+  //    float3 Origin;
+  //    float  TMin;
+  //    float3 Direction;
+  //    float  TMax;
+  //};
+  Value *zeroIdx = hlslOP->GetU32Const(0);
+  Value *origin = Builder.CreateGEP(rayDesc, {zeroIdx, zeroIdx});
+  origin = Builder.CreateLoad(origin);
+  unsigned index = DXIL::OperandIndex::kTraceRayRayDescOpIdx;
+  Args[index++] = Builder.CreateExtractElement(origin, (uint64_t)0);
+  Args[index++] = Builder.CreateExtractElement(origin, 1);
+  Args[index++] = Builder.CreateExtractElement(origin, 2);
+
+  Value *tmin = Builder.CreateGEP(rayDesc, {zeroIdx, hlslOP->GetU32Const(1)});
+  tmin = Builder.CreateLoad(tmin);
+  Args[index++] = tmin;
+
+  Value *direction = Builder.CreateGEP(rayDesc, {zeroIdx, hlslOP->GetU32Const(2)});
+  direction = Builder.CreateLoad(direction);
+
+  Args[index++] = Builder.CreateExtractElement(direction, (uint64_t)0);
+  Args[index++] = Builder.CreateExtractElement(direction, 1);
+  Args[index++] = Builder.CreateExtractElement(direction, 2);
+
+  Value *tmax = Builder.CreateGEP(rayDesc, {zeroIdx, hlslOP->GetU32Const(3)});
+  tmax = Builder.CreateLoad(tmax);
+  Args[index++] = tmax;
+
+  Args[DXIL::OperandIndex::kTraceRayPayloadOpIdx] = payLoad;
+
+  Type *Ty = payLoad->getType();
+  Function *F = hlslOP->GetOpFunc(opcode, Ty);
+
+
+  return Builder.CreateCall(F, Args);
+}
+} // namespace
+
 // Lower table.
 // Lower table.
 namespace {
 namespace {
 
 
@@ -4301,8 +4377,8 @@ IntrinsicLower gLowerTable[static_cast<unsigned>(IntrinsicOp::Num_Intrinsics)] =
     {IntrinsicOp::IOP_QuadReadAcrossX, TranslateQuadReadAcross, DXIL::OpCode::QuadOp},
     {IntrinsicOp::IOP_QuadReadAcrossX, TranslateQuadReadAcross, DXIL::OpCode::QuadOp},
     {IntrinsicOp::IOP_QuadReadAcrossY, TranslateQuadReadAcross, DXIL::OpCode::QuadOp},
     {IntrinsicOp::IOP_QuadReadAcrossY, TranslateQuadReadAcross, DXIL::OpCode::QuadOp},
     {IntrinsicOp::IOP_QuadReadLaneAt,  TranslateQuadReadLaneAt, DXIL::OpCode::NumOpCodes},
     {IntrinsicOp::IOP_QuadReadLaneAt,  TranslateQuadReadLaneAt, DXIL::OpCode::NumOpCodes},
-    {IntrinsicOp::IOP_ReportIntersection, EmptyLower, DXIL::OpCode::NumOpCodes},
-    {IntrinsicOp::IOP_TraceRay, EmptyLower, DXIL::OpCode::NumOpCodes},
+    {IntrinsicOp::IOP_ReportIntersection, TranslateReportIntersection, DXIL::OpCode::ReportIntersection},
+    {IntrinsicOp::IOP_TraceRay, TranslateTraceRay, DXIL::OpCode::TraceRay},
     {IntrinsicOp::IOP_WaveActiveAllEqual, TranslateWaveAllEqual, DXIL::OpCode::WaveActiveAllEqual},
     {IntrinsicOp::IOP_WaveActiveAllEqual, TranslateWaveAllEqual, DXIL::OpCode::WaveActiveAllEqual},
     {IntrinsicOp::IOP_WaveActiveAllTrue, TranslateWaveA2B, DXIL::OpCode::WaveAllTrue},
     {IntrinsicOp::IOP_WaveActiveAllTrue, TranslateWaveA2B, DXIL::OpCode::WaveAllTrue},
     {IntrinsicOp::IOP_WaveActiveAnyTrue, TranslateWaveA2B, DXIL::OpCode::WaveAnyTrue},
     {IntrinsicOp::IOP_WaveActiveAnyTrue, TranslateWaveA2B, DXIL::OpCode::WaveAnyTrue},

+ 52 - 5
lib/Transforms/Scalar/ScalarReplAggregatesHLSL.cpp

@@ -107,9 +107,10 @@ private:
   void RewriteForGEP(GEPOperator *GEP, IRBuilder<> &Builder);
   void RewriteForGEP(GEPOperator *GEP, IRBuilder<> &Builder);
   void RewriteForLoad(LoadInst *loadInst);
   void RewriteForLoad(LoadInst *loadInst);
   void RewriteForStore(StoreInst *storeInst);
   void RewriteForStore(StoreInst *storeInst);
-  void RewriteMemIntrin(MemIntrinsic *MI, Instruction *Inst);
+  void RewriteMemIntrin(MemIntrinsic *MI, Value *OldV);
   void RewriteCall(CallInst *CI);
   void RewriteCall(CallInst *CI);
   void RewriteBitCast(BitCastInst *BCI);
   void RewriteBitCast(BitCastInst *BCI);
+  void RewriteCallArg(CallInst *CI, unsigned ArgIdx, bool bIn, bool bOut);
 };
 };
 
 
 struct SROA_HLSL : public FunctionPass {
 struct SROA_HLSL : public FunctionPass {
@@ -2818,7 +2819,7 @@ void SROA_Helper::RewriteForStore(StoreInst *SI) {
 }
 }
 /// RewriteMemIntrin - MI is a memcpy/memset/memmove from or to AI.
 /// RewriteMemIntrin - MI is a memcpy/memset/memmove from or to AI.
 /// Rewrite it to copy or set the elements of the scalarized memory.
 /// Rewrite it to copy or set the elements of the scalarized memory.
-void SROA_Helper::RewriteMemIntrin(MemIntrinsic *MI, Instruction *Inst) {
+void SROA_Helper::RewriteMemIntrin(MemIntrinsic *MI, Value *OldV) {
   // If this is a memcpy/memmove, construct the other pointer as the
   // If this is a memcpy/memmove, construct the other pointer as the
   // appropriate type.  The "Other" pointer is the pointer that goes to memory
   // appropriate type.  The "Other" pointer is the pointer that goes to memory
   // that doesn't have anything to do with the alloca that we are promoting. For
   // that doesn't have anything to do with the alloca that we are promoting. For
@@ -2826,10 +2827,10 @@ void SROA_Helper::RewriteMemIntrin(MemIntrinsic *MI, Instruction *Inst) {
   Value *OtherPtr = nullptr;
   Value *OtherPtr = nullptr;
   unsigned MemAlignment = MI->getAlignment();
   unsigned MemAlignment = MI->getAlignment();
   if (MemTransferInst *MTI = dyn_cast<MemTransferInst>(MI)) { // memmove/memcopy
   if (MemTransferInst *MTI = dyn_cast<MemTransferInst>(MI)) { // memmove/memcopy
-    if (Inst == MTI->getRawDest())
+    if (OldV == MTI->getRawDest())
       OtherPtr = MTI->getRawSource();
       OtherPtr = MTI->getRawSource();
     else {
     else {
-      assert(Inst == MTI->getRawSource());
+      assert(OldV == MTI->getRawSource());
       OtherPtr = MTI->getRawDest();
       OtherPtr = MTI->getRawDest();
     }
     }
   }
   }
@@ -2871,7 +2872,7 @@ void SROA_Helper::RewriteMemIntrin(MemIntrinsic *MI, Instruction *Inst) {
   }
   }
 
 
   // Process each element of the aggregate.
   // Process each element of the aggregate.
-  bool SROADest = MI->getRawDest() == Inst;
+  bool SROADest = MI->getRawDest() == OldV;
 
 
   Constant *Zero = Constant::getNullValue(Type::getInt32Ty(MI->getContext()));
   Constant *Zero = Constant::getNullValue(Type::getInt32Ty(MI->getContext()));
   const DataLayout &DL = MI->getModule()->getDataLayout();
   const DataLayout &DL = MI->getModule()->getDataLayout();
@@ -3050,6 +3051,35 @@ void SROA_Helper::RewriteBitCast(BitCastInst *BCI) {
   RewriteForGEP(cast<GEPOperator>(GEP), GEPBuilder);
   RewriteForGEP(cast<GEPOperator>(GEP), GEPBuilder);
 }
 }
 
 
+/// RewriteCallArg - For Functions which don't flat,
+///                  replace OldVal with alloca and
+///                  copy in copy out data between alloca and flattened NewElts
+///                  in CallInst.
+void SROA_Helper::RewriteCallArg(CallInst *CI, unsigned ArgIdx, bool bIn,
+                                 bool bOut) {
+  Function *F = CI->getParent()->getParent();
+  IRBuilder<> AllocaBuilder(F->getEntryBlock().getFirstInsertionPt());
+  const DataLayout &DL = F->getParent()->getDataLayout();
+
+  Value *userTyV = CI->getArgOperand(ArgIdx);
+  PointerType *userTy = cast<PointerType>(userTyV->getType());
+  Type *userTyElt = userTy->getElementType();
+  Value *Alloca = AllocaBuilder.CreateAlloca(userTyElt);
+  IRBuilder<> Builder(CI);
+  if (bIn) {
+    MemCpyInst *cpy = cast<MemCpyInst>(Builder.CreateMemCpy(
+        Alloca, userTyV, DL.getTypeAllocSize(userTyElt), false));
+    RewriteMemIntrin(cpy, cpy->getRawSource());
+  }
+  CI->setArgOperand(ArgIdx, Alloca);
+  if (bOut) {
+    Builder.SetInsertPoint(CI->getNextNode());
+    MemCpyInst *cpy = cast<MemCpyInst>(Builder.CreateMemCpy(
+        userTyV, Alloca, DL.getTypeAllocSize(userTyElt), false));
+    RewriteMemIntrin(cpy, cpy->getRawSource());
+  }
+}
+
 /// RewriteCall - Replace OldVal with flattened NewElts in CallInst.
 /// RewriteCall - Replace OldVal with flattened NewElts in CallInst.
 void SROA_Helper::RewriteCall(CallInst *CI) {
 void SROA_Helper::RewriteCall(CallInst *CI) {
   HLOpcodeGroup group = GetHLOpcodeGroupByName(CI->getCalledFunction());
   HLOpcodeGroup group = GetHLOpcodeGroupByName(CI->getCalledFunction());
@@ -3088,6 +3118,23 @@ void SROA_Helper::RewriteCall(CallInst *CI) {
 
 
         DeadInsts.push_back(CI);
         DeadInsts.push_back(CI);
       } break;
       } break;
+      case IntrinsicOp::IOP_TraceRay: {
+        if (OldVal ==
+            CI->getArgOperand(HLOperandIndex::kTraceRayRayDescOpIdx)) {
+          RewriteCallArg(CI, HLOperandIndex::kTraceRayRayDescOpIdx,
+                         /*bIn*/ true, /*bOut*/ false);
+        } else {
+          DXASSERT(OldVal ==
+                       CI->getArgOperand(HLOperandIndex::kTraceRayPayLoadOpIdx),
+                   "else invalid TraceRay");
+          RewriteCallArg(CI, HLOperandIndex::kTraceRayPayLoadOpIdx,
+                         /*bIn*/ true, /*bOut*/ true);
+        }
+      } break;
+      case IntrinsicOp::IOP_ReportIntersection: {
+        RewriteCallArg(CI, HLOperandIndex::kReportIntersectionAttributeOpIdx,
+                       /*bIn*/ true, /*bOut*/ false);
+      } break;
       default:
       default:
         DXASSERT(0, "cannot flatten hlsl intrinsic.");
         DXASSERT(0, "cannot flatten hlsl intrinsic.");
       }
       }

+ 25 - 0
tools/clang/test/CodeGenHLSL/quick-test/ray_trace1.hlsl

@@ -0,0 +1,25 @@
+// RUN: %dxc -T lib_6_2 %s | FileCheck %s
+
+// CHECK: call void @"dx.op.traceRay.%struct.Payload*"(i32 156,
+
+struct Payload {
+   float2 t;
+   int3 t2;
+};
+
+RayTracingAccelerationStructure Acc;
+
+uint RayFlags;
+uint InstanceInclusionMask;
+uint RayContributionToHitGroupIndex;
+uint MultiplierForGeometryContributionToHitGroupIndex;
+uint MissShaderIndex;
+
+
+float4 emit(inout float2 f2, RayDesc Ray:R, inout Payload p )  {
+  TraceRay(Acc,RayFlags,InstanceInclusionMask,
+           RayContributionToHitGroupIndex,
+           MultiplierForGeometryContributionToHitGroupIndex,MissShaderIndex, Ray, p);
+
+   return 2.6;
+}

+ 12 - 0
tools/clang/test/CodeGenHLSL/quick-test/ray_trace3.hlsl

@@ -0,0 +1,12 @@
+// RUN: %dxc -T lib_6_2 %s | FileCheck %s
+
+// CHECK: call i1 @"dx.op.reportIntersection.%struct.Attr*"(i32 157
+
+struct Attr {
+   float2 t;
+   int3 t2;
+};
+
+float emit(float THit : t, uint HitKind : h, Attr a : A) {
+  return ReportIntersection(THit, HitKind, a);
+}

+ 20 - 1
tools/clang/tools/dxcompiler/dxcdisassembler.cpp

@@ -966,7 +966,26 @@ static const char *OpCodeSignatures[] = {
   "(inputSigId,inputRowIndex,inputColIndex,VertexID)",  // AttributeAtVertex
   "(inputSigId,inputRowIndex,inputColIndex,VertexID)",  // AttributeAtVertex
   "()",  // ViewID
   "()",  // ViewID
   "(srv,index,elementOffset,mask,alignment)",  // RawBufferLoad
   "(srv,index,elementOffset,mask,alignment)",  // RawBufferLoad
-  "(uav,index,elementOffset,value0,value1,value2,value3,mask,alignment)"  // RawBufferStore
+  "(uav,index,elementOffset,value0,value1,value2,value3,mask,alignment)",  // RawBufferStore
+  "()",  // InstanceIndex
+  "()",  // HitKind
+  "()",  // RayFlag
+  "(col)",  // RayDispatchIndex
+  "(col)",  // RayDispatchDimension
+  "(col)",  // WorldRayOrigin
+  "(col)",  // WorldRayDirection
+  "(col)",  // ObjectRayOrigin
+  "(col)",  // ObjectRayDirection
+  "(row,col)",  // ObjectToWorld
+  "(row,col)",  // WorldToObject
+  "()",  // RayTMin
+  "()",  // CurrentRayT
+  "()",  // IgnoreIntersection
+  "()",  // TerminateRay
+  "(AccelerationStructure,RayFlags,InstanceInclusionMask,RayContributionToHitGroupIndex,MultiplierForGeometryContributionToShaderIndex,MissShaderIndex,Origin_X,Origin_Y,Origin_Z,TMin,Direction_X,Direction_Y,Direction_Z,TMax,payload)",  // TraceRay
+  "(THit,HitKind,Attributes)",  // ReportIntersection
+  "(ShaderIndex,Parameter)",  // CallShader
+  "()"  // ReservedForLibCreateHandleFromResourceStruct
 };
 };
 // OPCODE-SIGS:END
 // OPCODE-SIGS:END
 
 

+ 114 - 0
utils/hct/hctdb.py

@@ -293,6 +293,10 @@ class db_dxil(object):
             self.name_idx[i].shader_model = 6,1
             self.name_idx[i].shader_model = 6,1
         for i in "RawBufferLoad,RawBufferStore".split(","):
         for i in "RawBufferLoad,RawBufferStore".split(","):
             self.name_idx[i].shader_model = 6,2
             self.name_idx[i].shader_model = 6,2
+        for i in "InstanceIndex,HitKind,RayFlag,RayDispatchIndex,RayDispatchDimension,WorldRayOrigin,WorldRayDirection,ObjectRayOrigin,ObjectRayDirection,ObjectToWorld,WorldToObject,RayTMin,CurrentRayT,IgnoreIntersection,TerminateRay,TraceRay,ReportIntersection,CallShader,ReservedForLibCreateHandleFromResourceStruct".split(","):
+            self.name_idx[i].category = "Ray Tracing"
+            self.name_idx[i].shader_stages = "lib"
+            self.name_idx[i].shader_model = 6,3
 
 
     def populate_llvm_instructions(self):
     def populate_llvm_instructions(self):
         # Add instructions that map to LLVM instructions.
         # Add instructions that map to LLVM instructions.
@@ -1108,6 +1112,116 @@ class db_dxil(object):
         self.set_op_count_for_version(1, 2, next_op_idx)
         self.set_op_count_for_version(1, 2, next_op_idx)
         assert next_op_idx == 141, "next operation index is %d rather than 141 and thus opcodes are broken" % next_op_idx
         assert next_op_idx == 141, "next operation index is %d rather than 141 and thus opcodes are broken" % next_op_idx
 
 
+        self.add_dxil_op("InstanceIndex", next_op_idx, "InstanceIndex", "The autogenerated index of the current instance in the top-level structure", "i", "rn", [
+            db_dxil_param(0, "i32", "", "result")])
+        next_op_idx += 1
+
+        self.add_dxil_op("HitKind", next_op_idx, "HitKind", "Returns the value passed as HitKind in ReportIntersection().  If intersection was reported by fixed-function triangle intersection, HitKind will be one of HIT_KIND_TRIANGLE_FRONT_FACE or HIT_KIND_TRIANGLE_BACK_FACE.", "i", "rn", [
+            db_dxil_param(0, "i32", "", "result")])
+        next_op_idx += 1
+
+        self.add_dxil_op("RayFlag", next_op_idx, "RayFlag", "uint containing the current ray flags.", "i", "rn", [
+            db_dxil_param(0, "i32", "", "result")])
+        next_op_idx += 1
+
+        self.add_dxil_op("RayDispatchIndex", next_op_idx, "RayDispatchIndex", "The current x and y location within the Width and Height", "i", "rn", [
+            db_dxil_param(0, "i32", "", "result"),
+            db_dxil_param(2, "i8", "col", "column, relative to the element")])
+        next_op_idx += 1
+
+        self.add_dxil_op("RayDispatchDimension", next_op_idx, "RayDispatchDimension", "The Width and Height values from the D3D12_DISPATCH_RAYS_DESC structure provided to the originating DispatchRays() call.", "i", "rn", [
+            db_dxil_param(0, "i32", "", "result"),
+            db_dxil_param(2, "i8", "col", "column, relative to the element")])
+        next_op_idx += 1
+
+        self.add_dxil_op("WorldRayOrigin", next_op_idx, "WorldRayOrigin", "The world-space origin for the current ray.", "f", "rn", [
+            db_dxil_param(0, "f", "", "result"),
+            db_dxil_param(2, "i8", "col", "column, relative to the element")])
+        next_op_idx += 1
+
+        self.add_dxil_op("WorldRayDirection", next_op_idx, "WorldRayDirection", "The world-space direction for the current ray.", "f", "rn", [
+            db_dxil_param(0, "f", "", "result"),
+            db_dxil_param(2, "i8", "col", "column, relative to the element")])
+        next_op_idx += 1
+
+        self.add_dxil_op("ObjectRayOrigin", next_op_idx, "ObjectRayOrigin", "Object-space origin for the current ray.", "f", "rn", [
+            db_dxil_param(0, "f", "", "result"),
+            db_dxil_param(2, "i8", "col", "column, relative to the element")])
+        next_op_idx += 1
+
+        self.add_dxil_op("ObjectRayDirection", next_op_idx, "ObjectRayDirection", "Object-space direction for the current ray.", "f", "rn", [
+            db_dxil_param(0, "f", "", "result"),
+            db_dxil_param(2, "i8", "col", "column, relative to the element")])
+        next_op_idx += 1
+
+        self.add_dxil_op("ObjectToWorld", next_op_idx, "ObjectToWorld", "Matrix for transforming from object-space to world-space.", "f", "rn", [
+            db_dxil_param(0, "f", "", "result"),
+            db_dxil_param(2, "i32", "row", "row, relative to the element"),
+            db_dxil_param(3, "i8", "col", "column, relative to the element")])
+        next_op_idx += 1
+
+        self.add_dxil_op("WorldToObject", next_op_idx, "WorldToObject", "Matrix for transforming from world-space to object-space.", "f", "rn", [
+            db_dxil_param(0, "f", "", "result"),
+            db_dxil_param(2, "i32", "row", "row, relative to the element"),
+            db_dxil_param(3, "i8", "col", "column, relative to the element")])
+        next_op_idx += 1
+
+        self.add_dxil_op("RayTMin", next_op_idx, "RayTMin", "float representing the parametric starting point for the ray.", "f", "rn", [
+            db_dxil_param(0, "f", "", "result")])
+        next_op_idx += 1
+
+        self.add_dxil_op("CurrentRayT", next_op_idx, "CurrentRayT", "float representing the current parametric ending point for the ray", "f", "rn", [
+            db_dxil_param(0, "f", "", "result")])
+        next_op_idx += 1
+
+        self.add_dxil_op("IgnoreIntersection", next_op_idx, "IgnoreIntersection", "returns the view index", "v", "rn", [
+            db_dxil_param(0, "v", "", "")])
+        next_op_idx += 1
+
+        self.add_dxil_op("TerminateRay", next_op_idx, "TerminateRay", "returns the view index", "v", "rn", [
+            db_dxil_param(0, "v", "", "")])
+        next_op_idx += 1
+
+        self.add_dxil_op("TraceRay", next_op_idx, "TraceRay", "returns the view index", "u", "", [
+            db_dxil_param(0, "v", "", ""),
+            db_dxil_param(2, "res", "AccelerationStructure", "Top-level acceleration structure to use"),
+            db_dxil_param(3, "i32", "RayFlags", "Valid combination of Ray_flags"),
+            db_dxil_param(4, "i32", "InstanceInclusionMask", "Bottom 8 bits of InstanceInclusionMask are used to include/rejectgeometry instances based on the InstanceMask in each instance: if(!((InstanceInclusionMask & InstanceMask) & 0xff)) { ignore intersection }"),
+            db_dxil_param(5, "i32", "RayContributionToHitGroupIndex", "Offset to add into Addressing calculations within shader tables for hit group indexing.  Only the bottom 4 bits of this value are used"),
+            db_dxil_param(6, "i32", "MultiplierForGeometryContributionToShaderIndex", "Stride to multiply by per-geometry GeometryContributionToHitGroupIndex in Addressing calculations within shader tables for hit group indexing.  Only the bottom 4 bits of this value are used"),
+            db_dxil_param(7, "i32", "MissShaderIndex", "Miss shader index in Addressing calculations within shader tables.  Only the bottom 16 bits of this value are used"),
+            db_dxil_param(8, "f", "Origin_X", "Origin x of the ray"),
+            db_dxil_param(9, "f", "Origin_Y", "Origin y of the ray"),
+            db_dxil_param(10, "f", "Origin_Z", "Origin z of the ray"),
+            db_dxil_param(11, "f", "TMin", "Tmin of the ray"),
+            db_dxil_param(12, "f", "Direction_X", "Direction x of the ray"),
+            db_dxil_param(13, "f", "Direction_Y", "Direction y of the ray"),
+            db_dxil_param(14, "f", "Direction_Z", "Direction z of the ray"),
+            db_dxil_param(15, "f", "TMax", "Tmax of the ray"),
+            db_dxil_param(16, "udt", "payload", "User-defined intersection attribute structure")])
+        next_op_idx += 1
+
+        self.add_dxil_op("ReportIntersection", next_op_idx, "ReportIntersection", "returns true if hit was accepted", "u", "ro", [
+            db_dxil_param(0, "i1", "", "result"),
+            db_dxil_param(2, "f", "THit", "parametric distance of the intersection"),
+            db_dxil_param(3, "i32", "HitKind", "User-specified value in range of 0-127 to identify the type of hit. Read by any_hit or closes_hit shaders with HitKind()"),
+            db_dxil_param(4, "udt", "Attributes", "User-defined intersection attribute structure")])
+        next_op_idx += 1
+
+        self.add_dxil_op("CallShader", next_op_idx, "CallShader", "returns the view index", "v", "", [
+            db_dxil_param(0, "v", "", "result"),
+            db_dxil_param(2, "i32", "ShaderIndex", "Provides index into the callable shader table supplied through the DispatchRays() API"),
+            db_dxil_param(3, "udt", "Parameter", "User-defined parameters to pass to the callable shader,This parameter structure must match the parameter structure used in the callable shader pointed to in the shader table")])
+        next_op_idx += 1
+
+        self.add_dxil_op("ReservedForLibCreateHandleFromResourceStruct", next_op_idx, "ReservedForLibCreateHandleFromResourceStruct", "returns the view index", "i", "rn", [
+            db_dxil_param(0, "i32", "", "result")])
+        next_op_idx += 1
+
+        # End of DXIL 1.3 opcodes.
+        self.set_op_count_for_version(1, 3, next_op_idx)
+        assert next_op_idx == 160, "next operation index is %d rather than 160 and thus opcodes are broken" % next_op_idx
+
         # Set interesting properties.
         # Set interesting properties.
         self.build_indices()
         self.build_indices()
         for i in "CalculateLOD,DerivCoarseX,DerivCoarseY,DerivFineX,DerivFineY,Sample,SampleBias,SampleCmp,TextureGather,TextureGatherCmp".split(","):
         for i in "CalculateLOD,DerivCoarseX,DerivCoarseY,DerivFineX,DerivFineY,Sample,SampleBias,SampleCmp,TextureGather,TextureGatherCmp".split(","):

+ 21 - 6
utils/hct/hctdb_instrhelp.py

@@ -350,14 +350,14 @@ class db_oload_gen:
 
 
     def print_opfunc_props(self):
     def print_opfunc_props(self):
         print("const OP::OpCodeProperty OP::m_OpCodeProps[(unsigned)OP::OpCode::NumOpCodes] = {")
         print("const OP::OpCodeProperty OP::m_OpCodeProps[(unsigned)OP::OpCode::NumOpCodes] = {")
-        print("//   OpCode                       OpCode name,                OpCodeClass                    OpCodeClass name,              void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64  function attribute")
+        print("//   OpCode                       OpCode name,                OpCodeClass                    OpCodeClass name,              void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64,   udt,  function attribute")
         # Example formatted string:
         # Example formatted string:
         #   {  OC::TempRegLoad,             "TempRegLoad",              OCC::TempRegLoad,              "tempRegLoad",                false,  true,  true, false,  true, false,  true,  true, false, Attribute::ReadOnly, },
         #   {  OC::TempRegLoad,             "TempRegLoad",              OCC::TempRegLoad,              "tempRegLoad",                false,  true,  true, false,  true, false,  true,  true, false, Attribute::ReadOnly, },
         # 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
         # 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
         # 0         1         2         3         4         5         6         7         8         9         0         1         2         3         4         5         6         7         8         9         0
         # 0         1         2         3         4         5         6         7         8         9         0         1         2         3         4         5         6         7         8         9         0
 
 
         last_category = None
         last_category = None
-        # overload types are a string of (v)oid, (h)alf, (f)loat, (d)ouble, (1)-bit, (8)-bit, (w)ord, (i)nt, (l)ong
+        # overload types are a string of (v)oid, (h)alf, (f)loat, (d)ouble, (1)-bit, (8)-bit, (w)ord, (i)nt, (l)ong, u(dt)
         f = lambda i,c : "true," if i.oload_types.find(c) >= 0 else "false,"
         f = lambda i,c : "true," if i.oload_types.find(c) >= 0 else "false,"
         lower_exceptions = { "CBufferLoad" : "cbufferLoad", "CBufferLoadLegacy" : "cbufferLoadLegacy", "GSInstanceID" : "gsInstanceID" }
         lower_exceptions = { "CBufferLoad" : "cbufferLoad", "CBufferLoadLegacy" : "cbufferLoadLegacy", "GSInstanceID" : "gsInstanceID" }
         lower_fn = lambda t: lower_exceptions[t] if t in lower_exceptions else t[:1].lower() + t[1:]
         lower_fn = lambda t: lower_exceptions[t] if t in lower_exceptions else t[:1].lower() + t[1:]
@@ -367,11 +367,11 @@ class db_oload_gen:
             if last_category != i.category:
             if last_category != i.category:
                 if last_category != None:
                 if last_category != None:
                     print("")
                     print("")
-                print("  // {category:118} void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64  function attribute".format(category=i.category))
+                print("  // {category:118} void,     h,     f,     d,    i1,    i8,   i16,   i32,   i64,   udt,  function attribute".format(category=i.category))
                 last_category = i.category
                 last_category = i.category
-            print("  {{  OC::{name:24} {quotName:27} OCC::{className:25} {classNameQuot:28} {v:>7}{h:>7}{f:>7}{d:>7}{b:>7}{e:>7}{w:>7}{i:>7}{l:>7} {attr:20} }},".format(
+            print("  {{  OC::{name:24} {quotName:27} OCC::{className:25} {classNameQuot:28} {v:>7}{h:>7}{f:>7}{d:>7}{b:>7}{e:>7}{w:>7}{i:>7}{l:>7}{u:>7} {attr:20} }},".format(
                 name=i.name+",", quotName='"'+i.name+'",', className=i.dxil_class+",", classNameQuot='"'+lower_fn(i.dxil_class)+'",',
                 name=i.name+",", quotName='"'+i.name+'",', className=i.dxil_class+",", classNameQuot='"'+lower_fn(i.dxil_class)+'",',
-                v=f(i,"v"), h=f(i,"h"), f=f(i,"f"), d=f(i,"d"), b=f(i,"1"), e=f(i,"8"), w=f(i,"w"), i=f(i,"i"), l=f(i,"l"), attr=attr_fn(i)))
+                v=f(i,"v"), h=f(i,"h"), f=f(i,"f"), d=f(i,"d"), b=f(i,"1"), e=f(i,"8"), w=f(i,"w"), i=f(i,"i"), l=f(i,"l"), u=f(i,"u"), attr=attr_fn(i)))
         print("};")
         print("};")
 
 
     def print_opfunc_table(self):
     def print_opfunc_table(self):
@@ -404,6 +404,7 @@ class db_oload_gen:
             "v": "A(pV);",
             "v": "A(pV);",
             "w": "A(pWav);",
             "w": "A(pWav);",
             "SamplePos": "A(pPos);",
             "SamplePos": "A(pPos);",
+            "udt": "A(udt);",
         }
         }
         last_category = None
         last_category = None
         for i in self.instrs:
         for i in self.instrs:
@@ -428,6 +429,7 @@ class db_oload_gen:
         elt_ty = "$o"
         elt_ty = "$o"
         res_ret_ty = "$r"
         res_ret_ty = "$r"
         cb_ret_ty = "$cb"
         cb_ret_ty = "$cb"
+        udt_ty = "udt"
 
 
         last_category = None
         last_category = None
 
 
@@ -469,6 +471,15 @@ class db_oload_gen:
                         index_dict[index].append(instr.name)
                         index_dict[index].append(instr.name)
                     in_param_ty = True
                     in_param_ty = True
                     break
                     break
+                if (op_type == udt_ty):
+                    # Skip return op
+                    index = index - 1
+                    if index not in index_dict:
+                        index_dict[index] = [instr.name]
+                    else:
+                        index_dict[index].append(instr.name)
+                    in_param_ty = True
+
 
 
             if in_param_ty:
             if in_param_ty:
                 continue
                 continue
@@ -486,6 +497,7 @@ class db_oload_gen:
             "i": "IntegerType::get(m_Ctx, 32)",
             "i": "IntegerType::get(m_Ctx, 32)",
             "l": "IntegerType::get(m_Ctx, 64)",
             "l": "IntegerType::get(m_Ctx, 64)",
             "v": "Type::getVoidTy(m_Ctx)",
             "v": "Type::getVoidTy(m_Ctx)",
+            "u": "Type::getInt32PtrTy(m_Ctx)",
             }
             }
             assert ty in type_code_texts, "llvm type %s is unknown" % (ty)
             assert ty in type_code_texts, "llvm type %s is unknown" % (ty)
             ty_code = type_code_texts[ty]
             ty_code = type_code_texts[ty]
@@ -924,7 +936,10 @@ def get_valopcode_sm_text():
             model_cond = "pSM->GetMajor() > %d || (pSM->GetMajor() == %d && pSM->GetMinor() >= %d)" % (
             model_cond = "pSM->GetMajor() > %d || (pSM->GetMajor() == %d && pSM->GetMinor() >= %d)" % (
                 last_model[0], last_model[0], last_model[1])
                 last_model[0], last_model[0], last_model[1])
         if last_stage != "*":
         if last_stage != "*":
-            stage_cond = ' || '.join(["pSM->Is%sS()" % c.upper() for c in last_stage])
+            if last_stage != "lib":
+                stage_cond = ' || '.join(["pSM->Is%sS()" % c.upper() for c in last_stage])
+            else:
+                stage_cond = ' || '.join(["pSM->IsLib()"])
         if model_cond or stage_cond:
         if model_cond or stage_cond:
             result += '\n      && '.join(
             result += '\n      && '.join(
                 ["(%s)" % expr for expr in (model_cond, stage_cond) if expr] )
                 ["(%s)" % expr for expr in (model_cond, stage_cond) if expr] )