diff options
Diffstat (limited to 'source/slang')
28 files changed, 3064 insertions, 163 deletions
diff --git a/source/slang/core.meta.slang b/source/slang/core.meta.slang index e55206ca9..27da512fa 100644 --- a/source/slang/core.meta.slang +++ b/source/slang/core.meta.slang @@ -2338,7 +2338,7 @@ __attributeTarget(DeclBase) attribute_syntax [push_constant] : PushConstantAttribute; __attributeTarget(VarDeclBase) -attribute_syntax [vk_location(locaiton : int)] : GLSLLocationAttribute; +attribute_syntax [vk_location(location : int)] : GLSLLocationAttribute; __attributeTarget(VarDeclBase) attribute_syntax [vk_index(index : int)] : GLSLIndexAttribute; @@ -2476,7 +2476,7 @@ __attributeTarget(Decl) attribute_syntax [allow(diagnostic: String)] : AllowAttribute; __attributeTarget(Decl) -attribute_syntax[require(capability)] : RequireCapabilityAttribute; +attribute_syntax [require(capability)] : RequireCapabilityAttribute; // Linking __attributeTarget(Decl) @@ -2519,7 +2519,7 @@ __attributeTarget(FuncDecl) attribute_syntax [CUDAKernel] : CudaKernelAttribute; __attributeTarget(FuncDecl) -attribute_syntax[AutoPyBindCUDA] : AutoPyBindCudaAttribute; +attribute_syntax [AutoPyBindCUDA] : AutoPyBindCudaAttribute; __attributeTarget(AggTypeDecl) attribute_syntax [PyExport(name: String)] : PyExportAttribute; diff --git a/source/slang/glsl.meta.slang b/source/slang/glsl.meta.slang index 98b7fcd82..d154bd969 100644 --- a/source/slang/glsl.meta.slang +++ b/source/slang/glsl.meta.slang @@ -2821,22 +2821,499 @@ public vec4 shadow2DProjLod(sampler2DShadow sampler, vec4 coord, float lod) return textureProjLod(sampler, coord, lod); } -// -// Ray tracing -// + +//// RayTracing + +// Ray Tracing variables public typealias rayQueryEXT = RayQuery; +public typealias accelerationStructureEXT = RaytracingAccelerationStructure; +public typealias accelerationStructureNV = RaytracingAccelerationStructure; + +public typealias hitObjectNV = HitObject; + +//GL_EXT_ray_tracing BuiltIn's + +void requireGLSLExtForRayTracingBuiltin() +{ + __target_switch + { + case glsl: + __requireGLSLExtension("GL_EXT_ray_tracing"); + __intrinsic_asm ""; + } +} + +__spirv_version(1.4) +void setupExtForRayTracingBuiltIn() +{ + __target_switch + { + case glsl: + requireGLSLExtForRayTracingBuiltin(); + case spirv: + return; + } +} + +[require(glsl, raytracing)] +[require(spirv, raytracing)] +public property uint3 gl_LaunchIDNV +{ + get + { + setupExtForRayTracingBuiltIn(); + __target_switch + { + case glsl: + { + __intrinsic_asm "(gl_LaunchIDNV)"; + } + case spirv: + { + return spirv_asm + { + result:$$uint3 = OpLoad builtin(LaunchIdNV:uint3); + }; + } + } + } +} + +[require(glsl, raytracing)] +[require(spirv, raytracing)] +public property uint3 gl_LaunchIDEXT +{ + get + { + setupExtForRayTracingBuiltIn(); + return DispatchRaysIndex(); + } +} + +[require(glsl, raytracing)] +[require(spirv, raytracing)] +public property uint3 gl_LaunchSizeNV +{ + get + { + setupExtForRayTracingBuiltIn(); + __target_switch + { + case glsl: + { + __intrinsic_asm "(gl_LaunchSizeNV)"; + } + case spirv: + { + return spirv_asm + { + result:$$uint3 = OpLoad builtin(LaunchSizeNV:uint3); + }; + } + } + } +} + +[require(glsl, raytracing)] +[require(spirv, raytracing)] +public property uint3 gl_LaunchSizeEXT +{ + get + { + setupExtForRayTracingBuiltIn(); + return DispatchRaysDimensions(); + } +} + +[require(glsl, raytracing)] +[require(spirv, raytracing)] +public property int gl_PrimitiveID +{ + get + { + setupExtForRayTracingBuiltIn(); + return PrimitiveIndex(); + } +} + +[require(glsl, raytracing)] +[require(spirv, raytracing)] +public property int gl_InstanceID +{ + get + { + setupExtForRayTracingBuiltIn(); + return InstanceIndex(); + } +} + +[require(glsl, raytracing)] +[require(spirv, raytracing)] +public property int gl_InstanceCustomIndexEXT +{ + get + { + setupExtForRayTracingBuiltIn(); + return InstanceID(); + } +} + +[require(glsl, raytracing)] +[require(spirv, raytracing)] +public property int gl_GeometryIndexEXT +{ + get + { + setupExtForRayTracingBuiltIn(); + return GeometryIndex(); + } +} + +[require(glsl, raytracing)] +[require(spirv, raytracing)] +public property vec3 gl_WorldRayOriginEXT +{ + get + { + setupExtForRayTracingBuiltIn(); + return WorldRayOrigin(); + } +} + +[require(glsl, raytracing)] +[require(spirv, raytracing)] +public property vec3 gl_WorldRayDirectionEXT +{ + get + { + setupExtForRayTracingBuiltIn(); + return WorldRayDirection(); + } +} + +[require(glsl, raytracing)] +[require(spirv, raytracing)] +public property vec3 gl_ObjectRayOriginEXT +{ + get + { + setupExtForRayTracingBuiltIn(); + return ObjectRayOrigin(); + } +} + +[require(glsl, raytracing)] +[require(spirv, raytracing)] +public property vec3 gl_ObjectRayDirectionEXT +{ + get + { + setupExtForRayTracingBuiltIn(); + return ObjectRayDirection(); + } +} + +[require(glsl, raytracing)] +[require(spirv, raytracing)] +public property float gl_RayTminEXT +{ + get + { + setupExtForRayTracingBuiltIn(); + return RayTMin(); + } +} + +[require(glsl, raytracing)] +[require(spirv, raytracing)] +public property float gl_RayTmaxEXT +{ + get + { + setupExtForRayTracingBuiltIn(); + return RayTCurrent(); + } +} + +[require(glsl, raytracing)] +[require(spirv, raytracing)] +public property uint gl_IncomingRayFlagsEXT +{ + get + { + setupExtForRayTracingBuiltIn(); + return RayFlags(); + } +} + +[require(glsl, raytracing)] +[require(spirv, raytracing)] +public property float gl_HitTEXT +{ + get + { + setupExtForRayTracingBuiltIn(); + __target_switch + { + case glsl: + { + __intrinsic_asm "(gl_HitTEXT)"; + } + case spirv: + { + return spirv_asm + { + result:$$float = OpLoad builtin(RayTmaxKHR:float); + }; + } + } + } +} + +[require(glsl, raytracing)] +[require(spirv, raytracing)] +public property uint gl_HitKindEXT +{ + get + { + setupExtForRayTracingBuiltIn(); + return HitKind(); + } +} + +[require(glsl, raytracing)] +[require(spirv, raytracing)] +public property mat4x3 gl_ObjectToWorldEXT +{ + get + { + setupExtForRayTracingBuiltIn(); + __target_switch + { + case glsl: + { + __intrinsic_asm "(gl_ObjectToWorldEXT)"; + } + case spirv: + { + return spirv_asm + { + %mat:$$mat3x4 = OpLoad builtin(ObjectToWorldKHR:mat3x4); + result:$$mat4x3 = OpTranspose %mat + }; + } + } + } +} + +[require(glsl, raytracing)] +[require(spirv, raytracing)] +public property mat3x4 gl_ObjectToWorld3x4EXT +{ + get + { + setupExtForRayTracingBuiltIn(); + __target_switch + { + case glsl: + { + __intrinsic_asm "(gl_ObjectToWorld3x4EXT)"; + } + case spirv: + { + return spirv_asm + { + result:$$mat3x4 = OpLoad builtin(ObjectToWorldKHR:mat3x4) + }; + } + } + } +} + +[require(glsl, raytracing)] +[require(spirv, raytracing)] +public property mat4x3 gl_WorldToObjectEXT +{ + get + { + setupExtForRayTracingBuiltIn(); + __target_switch + { + case glsl: + { + __intrinsic_asm "(gl_WorldToObjectEXT)"; + } + case spirv: + { + return spirv_asm + { + %mat:$$mat3x4 = OpLoad builtin(WorldToObjectKHR:mat3x4); + result:$$mat4x3 = OpTranspose %mat + }; + } + } + } +} + +[require(glsl, raytracing)] +[require(spirv, raytracing)] +public property mat3x4 gl_WorldToObject3x4EXT +{ + get + { + setupExtForRayTracingBuiltIn(); + __target_switch + { + case glsl: + { + __intrinsic_asm "(gl_WorldToObject3x4EXT)"; + } + case spirv: + { + return spirv_asm + { + result:$$mat3x4 = OpLoad builtin(WorldToObjectKHR:mat3x4) + }; + } + } + } +} + +// GL_EXT_ray_tracing functions + +__glsl_extension(GL_EXT_ray_query) +[require(glsl, raytracing)] +[require(spirv, raytracing)] +public void traceRayEXT( + accelerationStructureEXT topLevel, + uint rayFlags, + uint cullMask, + uint sbtRecordOffset, + uint sbtRecordStride, + uint missIndex, + vec3 origin, + float Tmin, + vec3 direction, + float Tmax, + constexpr int payload) +{ + __target_switch + { + case glsl: + { + __traceRay( + topLevel, + rayFlags, + cullMask, + sbtRecordOffset, + sbtRecordStride, + missIndex, + origin, + Tmin, + direction, + Tmax, + payload); + } + case spirv: + { + spirv_asm + { + OpTraceRayKHR + /**/ $topLevel + /**/ $rayFlags + /**/ $cullMask + /**/ $sbtRecordOffset + /**/ $sbtRecordStride + /**/ $missIndex + /**/ $origin + /**/ $Tmin + /**/ $direction + /**/ $Tmax + /**/ __rayPayloadFromLocation(payload); + }; + } + } +} + +__glsl_extension(GL_EXT_ray_query) +[require(glsl, raytracing)] +[require(spirv, raytracing)] +public bool reportIntersectionEXT(float hitT, uint hitKind) +{ + return __reportIntersection(hitT, hitKind); +} __glsl_extension(GL_EXT_ray_query) -__glsl_version(460) +[require(glsl, raytracing)] +[require(spirv, raytracing)] +public void executeCallableEXT( + uint sbtRecordIndex, + int callable /*callableDataEXT and callableDataInEXT*/) +{ + __target_switch + { + case glsl: + { + __executeCallable(sbtRecordIndex, callable); + } + case spirv: + { + spirv_asm { + OpExecuteCallableKHR $sbtRecordIndex __rayCallableFromLocation(callable) + }; + } + } +} + +// GL_EXT_ray_tracing constants + +public const uint gl_HitKindFrontFacingTriangleEXT = 0xFEU; +public const uint gl_HitKindBackFacingTriangleEXT = 0xFFU; + +/// GL_EXT_ray_query + +// GL_EXT_ray_query constants + +public const uint gl_RayFlagsNoneEXT = 0U; +public const uint gl_RayFlagsOpaqueEXT = 1U; +public const uint gl_RayFlagsNoOpaqueEXT = 2U; +public const uint gl_RayFlagsTerminateOnFirstHitEXT = 4U; +public const uint gl_RayFlagsSkipClosestHitShaderEXT = 8U; +public const uint gl_RayFlagsCullBackFacingTrianglesEXT = 16U; +public const uint gl_RayFlagsCullFrontFacingTrianglesEXT = 32U; +public const uint gl_RayFlagsCullOpaqueEXT = 64U; +public const uint gl_RayFlagsCullNoOpaqueEXT = 128U; + +public const uint gl_RayQueryCommittedIntersectionNoneEXT = 0U; +public const uint gl_RayQueryCommittedIntersectionTriangleEXT = 1U; +public const uint gl_RayQueryCommittedIntersectionGeneratedEXT = 2U; + +public const uint gl_RayQueryCandidateIntersectionTriangleEXT = 0U; +public const uint gl_RayQueryCandidateIntersectionAABBEXT = 1U; + +// GL_EXT_ray_query functions + +__glsl_extension(GL_EXT_ray_query) +[require(glsl, rayquery)] +[require(spirv, rayquery)] [ForceInline] -public void rayQueryConfirmIntersectionEXT(inout rayQueryEXT q) +public void rayQueryInitializeEXT( + inout rayQueryEXT q, + accelerationStructureEXT topLevel, + uint rayFlags, uint cullMask, vec3 origin, + float tMin, vec3 direction, float tMax) { - q.CommitNonOpaqueTriangleHit(); + q.TraceRayInline( + topLevel, + rayFlags, + cullMask, + { origin, tMin, direction, tMax }); } __glsl_extension(GL_EXT_ray_query) -__glsl_version(460) +[require(glsl, rayquery)] +[require(spirv, rayquery)] [ForceInline] public bool rayQueryProceedEXT(inout rayQueryEXT q) { @@ -2844,24 +3321,1099 @@ public bool rayQueryProceedEXT(inout rayQueryEXT q) } __glsl_extension(GL_EXT_ray_query) -__glsl_version(460) +[require(glsl, rayquery)] +[require(spirv, rayquery)] +[mutating] +[ForceInline] +public void rayQueryTerminateEXT(inout rayQueryEXT q) +{ + q.Abort(); +} + +__glsl_extension(GL_EXT_ray_query) +[require(glsl, rayquery)] +[require(spirv, rayquery)] +[ForceInline] +public void rayQueryGenerateIntersectionEXT(inout rayQueryEXT q, float tHit) +{ + q.CommitProceduralPrimitiveHit(tHit); +} + +__glsl_extension(GL_EXT_ray_query) +[require(glsl, rayquery)] +[require(spirv, rayquery)] +[ForceInline] +public void rayQueryConfirmIntersectionEXT(inout rayQueryEXT q) +{ + q.CommitNonOpaqueTriangleHit(); +} + +__glsl_extension(GL_EXT_ray_query) +[require(glsl, rayquery)] +[require(spirv, rayquery)] [__NoSideEffect] +[ForceInline] public uint rayQueryGetIntersectionTypeEXT(rayQueryEXT q, bool committed) { if (committed) { - q.CommittedStatus(); + return q.CommittedStatus(); } else { - q.CandidateType(); + return q.CandidateType(); } - return 0; } -// TODO: implementation of built-in variables; proper tests; these are stubs -// likley related to the following issue since GLSL adds new -// 'system' variables: https://github.com/shader-slang/slang/issues/411 +__glsl_extension(GL_EXT_ray_query) +[require(glsl, rayquery)] +[require(spirv, rayquery)] +[ForceInline] +public float rayQueryGetRayTMinEXT(rayQueryEXT q) +{ + return q.RayTMin(); +} + +__glsl_extension(GL_EXT_ray_query) +[require(glsl, rayquery)] +[require(spirv, rayquery)] +[ForceInline] +public uint rayQueryGetRayFlagsEXT(rayQueryEXT q) +{ + return q.RayFlags(); +} + +__glsl_extension(GL_EXT_ray_query) +[require(glsl, rayquery)] +[require(spirv, rayquery)] +[ForceInline] +public vec3 rayQueryGetWorldRayOriginEXT(rayQueryEXT q) +{ + return q.WorldRayOrigin(); +} + +__glsl_extension(GL_EXT_ray_query) +[require(glsl, rayquery)] +[require(spirv, rayquery)] +[ForceInline] +public vec3 rayQueryGetWorldRayDirectionEXT(rayQueryEXT q) +{ + return q.WorldRayDirection(); +} + +__glsl_extension(GL_EXT_ray_query) +[require(glsl, rayquery)] +[require(spirv, rayquery)] +[ForceInline] +public float rayQueryGetIntersectionTEXT(rayQueryEXT q, bool committed) +{ + if (committed) + { + return q.CommittedRayT(); + } + else + { + return q.CandidateTriangleRayT(); + } +} + +__glsl_extension(GL_EXT_ray_query) +[require(glsl, rayquery)] +[require(spirv, rayquery)] +[ForceInline] +public int rayQueryGetIntersectionInstanceCustomIndexEXT(rayQueryEXT q, bool committed) +{ + if (committed) + { + return q.CommittedRayInstanceCustomIndex(); + } + else + { + return q.CandidateRayInstanceCustomIndex();; + } +} + +__glsl_extension(GL_EXT_ray_query) +[require(glsl, rayquery)] +[require(spirv, rayquery)] +[ForceInline] +public int rayQueryGetIntersectionInstanceIdEXT(rayQueryEXT q, bool committed) +{ + if (committed) + { + return q.CommittedRayInstanceId(); + } + else + { + return q.CandidateRayInstanceId(); + } +} + +__glsl_extension(GL_EXT_ray_query) +[require(glsl, rayquery)] +[require(spirv, rayquery)] +[ForceInline] +public uint rayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetEXT(rayQueryEXT q, bool committed) +{ + if (committed) + { + return q.CommittedRayInstanceShaderBindingTableRecordOffset(); + } + else + { + return q.CandidateRayInstanceShaderBindingTableRecordOffset(); + } +} + +__glsl_extension(GL_EXT_ray_query) +[require(glsl, rayquery)] +[require(spirv, rayquery)] +[ForceInline] +public int rayQueryGetIntersectionGeometryIndexEXT(rayQueryEXT q, bool committed) +{ + if (committed) + { + return q.CommittedRayGeometryIndex(); + } + else + { + return q.CandidateRayGeometryIndex(); + } +} + +__glsl_extension(GL_EXT_ray_query) +[require(glsl, rayquery)] +[require(spirv, rayquery)] +[ForceInline] +public int rayQueryGetIntersectionPrimitiveIndexEXT(rayQueryEXT q, bool committed) +{ + if (committed) + { + return q.CommittedRayPrimitiveIndex(); + } + else + { + return q.CandidateRayPrimitiveIndex(); + } +} + +__glsl_extension(GL_EXT_ray_query) +[require(glsl, rayquery)] +[require(spirv, rayquery)] +[ForceInline] +public vec2 rayQueryGetIntersectionBarycentricsEXT(rayQueryEXT q, bool committed) +{ + if (committed) + { + return q.CommittedRayBarycentrics(); + } + else + { + return q.CandidateRayBarycentrics(); + } +} + +__glsl_extension(GL_EXT_ray_query) +[require(glsl, rayquery)] +[require(spirv, rayquery)] +[ForceInline] +public bool rayQueryGetIntersectionFrontFaceEXT(rayQueryEXT q, bool committed) +{ + if (committed) + { + return q.CommittedRayFrontFace(); + } + else + { + return q.CandidateRayFrontFace(); + } +} + +__glsl_extension(GL_EXT_ray_query) +[require(glsl, rayquery)] +[require(spirv, rayquery)] +[ForceInline] +public bool rayQueryGetIntersectionCandidateAABBOpaqueEXT(rayQueryEXT q) +{ + return q.CandidateProceduralPrimitiveNonOpaque(); +} + +[require(glsl, rayquery)] +[require(spirv, rayquery)] +[ForceInline] +public vec3 rayQueryGetIntersectionObjectRayDirectionEXT(rayQueryEXT q, bool committed) +{ + if (committed) + { + return q.CommittedRayObjectRayDirection(); + } + else + { + return q.CandidateRayObjectRayDirection(); + } +} + +__glsl_extension(GL_EXT_ray_query) +[require(glsl, rayquery)] +[require(spirv, rayquery)] +[ForceInline] +public vec3 rayQueryGetIntersectionObjectRayOriginEXT(rayQueryEXT q, bool committed) +{ + if (committed) + { + return q.CommittedRayObjectRayOrigin(); + } + else + { + return q.CandidateRayObjectRayOrigin(); + } +} + +__glsl_extension(GL_EXT_ray_query) +[require(glsl, rayquery)] +[require(spirv, rayquery)] +[ForceInline] +public mat4x3 rayQueryGetIntersectionObjectToWorldEXT(rayQueryEXT q, bool committed) +{ + if (committed) + { + return transpose(q.CommittedRayObjectToWorld()); + } + else + { + return transpose(q.CandidateRayObjectToWorld()); + } +} + +__glsl_extension(GL_EXT_ray_query) +[require(glsl, rayquery)] +[require(spirv, rayquery)] +[ForceInline] +public mat4x3 rayQueryGetIntersectionWorldToObjectEXT(rayQueryEXT q, bool committed) +{ + if (committed) + { + return transpose(q.CommittedRayWorldToObject()); + } + else + { + return transpose(q.CandidateRayWorldToObject()); + } +} + +/// GL_NV_shader_invocation_reorder + +__glsl_extension(GL_EXT_ray_tracing) +__glsl_extension(GL_NV_shader_invocation_reorder) +__glsl_extension(GLSL_EXT_buffer_reference_uvec2) +[require(glsl, ser)] +[require(spirv, ser)] +[ForceInline] +public void hitObjectTraceRayNV( + inout hitObjectNV hitObject, + accelerationStructureEXT topLevel, + uint rayFlags, + uint cullMask, + uint sbtRecordOffset, + uint sbtRecordStride, + uint missIndex, + vec3 origin, + float Tmin, + vec3 direction, + float Tmax, + constexpr int payload) + { + __target_switch + { + case glsl: + { + HitObject::__glslTraceRay( + hitObject, + topLevel, + rayFlags, + cullMask, + sbtRecordOffset, + sbtRecordStride, + missIndex, + origin, + Tmin, + direction, + Tmax, + payload); + } + case spirv: + { + spirv_asm + { + OpHitObjectTraceRayNV + &hitObject + /**/ $topLevel + /**/ $rayFlags + /**/ $cullMask + /**/ $sbtRecordOffset + /**/ $sbtRecordStride + /**/ $missIndex + /**/ $origin + /**/ $Tmin + /**/ $direction + /**/ $Tmax + /**/ __rayPayloadFromLocation(payload) + }; + } + } +} + +__glsl_extension(GL_EXT_ray_tracing) +__glsl_extension(GL_NV_shader_invocation_reorder) +__glsl_extension(GLSL_EXT_buffer_reference_uvec2) +__glsl_extension(GL_NV_ray_tracing_motion_blur) +[require(glsl, ser_motion)] +[require(spirv, ser_motion)] +[ForceInline] +public void hitObjectTraceRayMotionNV( + inout hitObjectNV hitObject, + accelerationStructureEXT topLevel, + uint rayFlags, + uint cullMask, + uint sbtRecordOffset, + uint sbtRecordStride, + uint missIndex, + vec3 origin, + float Tmin, + vec3 direction, + float Tmax, + float currentTime, + constexpr int payload) + { + __target_switch + { + case glsl: + { + HitObject::__glslTraceMotionRay( + hitObject, + topLevel, + rayFlags, + cullMask, + sbtRecordOffset, + sbtRecordStride, + missIndex, + origin, + Tmin, + direction, + Tmax, + currentTime, + payload); + } + case spirv: + { + spirv_asm + { + OpCapability RayTracingMotionBlurNV; + OpExtension "SPV_NV_ray_tracing_motion_blur"; + OpHitObjectTraceRayMotionNV + /**/ &hitObject + /**/ $topLevel + /**/ $rayFlags + /**/ $cullMask + /**/ $sbtRecordOffset + /**/ $sbtRecordStride + /**/ $missIndex + /**/ $origin + /**/ $Tmin + /**/ $direction + /**/ $Tmax + /**/ $currentTime + /**/ __rayPayloadFromLocation(payload) + }; + } + } +} + +__glsl_extension(GL_EXT_ray_tracing) +__glsl_extension(GL_NV_shader_invocation_reorder) +__glsl_extension(GLSL_EXT_buffer_reference_uvec2) +[require(glsl, ser)] +[require(spirv, ser)] +[ForceInline] +public void hitObjectRecordHitNV( + inout hitObjectNV hitObject, + accelerationStructureEXT topLevel, + int instanceid, + int primitiveid, + int geometryindex, + uint hitKind, + uint sbtRecordOffset, + uint sbtRecordStride, + vec3 origin, + float Tmin, + vec3 direction, + float Tmax, + constexpr int attributeLocation) + { + __target_switch + { + case glsl: + { + HitObject::__glslMakeHit( + hitObject, + topLevel, + instanceid, + primitiveid, + geometryindex, + hitKind, + sbtRecordOffset, + sbtRecordStride, + origin, + Tmin, + direction, + Tmax, + attributeLocation); + } + case spirv: + { + spirv_asm + { + OpHitObjectRecordHitNV + /**/ &hitObject + /**/ $topLevel + /**/ $instanceid + /**/ $primitiveid + /**/ $geometryindex + /**/ $hitKind + /**/ $sbtRecordOffset + /**/ $sbtRecordStride + /**/ $origin + /**/ $Tmin + /**/ $direction + /**/ $Tmax + /**/ __rayAttributeFromLocation(attributeLocation) + }; + } + } +} + +__glsl_extension(GL_EXT_ray_tracing) +__glsl_extension(GL_NV_shader_invocation_reorder) +__glsl_extension(GLSL_EXT_buffer_reference_uvec2) +__glsl_extension(GL_NV_ray_tracing_motion_blur) +[require(glsl, ser_motion)] +[require(spirv, ser_motion)] +[ForceInline] +public void hitObjectRecordHitMotionNV( + inout hitObjectNV hitObject, + accelerationStructureEXT topLevel, + int instanceid, + int primitiveid, + int geometryindex, + uint hitKind, + uint sbtRecordOffset, + uint sbtRecordStride, + vec3 origin, + float Tmin, + vec3 direction, + float Tmax, + float currentTime, + constexpr int attributeLocation) + { + __target_switch + { + case glsl: + { + HitObject::__glslMakeMotionHit( + hitObject, + topLevel, + instanceid, + primitiveid, + geometryindex, + hitKind, + sbtRecordOffset, + sbtRecordStride, + origin, + Tmin, + direction, + Tmax, + currentTime, + attributeLocation); + } + case spirv: + { + spirv_asm + { + OpHitObjectRecordHitMotionNV + /**/ &hitObject + /**/ $topLevel + /**/ $instanceid + /**/ $primitiveid + /**/ $geometryindex + /**/ $hitKind + /**/ $sbtRecordOffset + /**/ $sbtRecordStride + /**/ $origin + /**/ $Tmin + /**/ $direction + /**/ $Tmax + /**/ $currentTime + /**/ __rayAttributeFromLocation(attributeLocation) + }; + } + } +} + +__glsl_extension(GL_EXT_ray_tracing) +__glsl_extension(GL_NV_shader_invocation_reorder) +__glsl_extension(GLSL_EXT_buffer_reference_uvec2) +[require(glsl, ser)] +[require(spirv, ser)] +[ForceInline] +public void hitObjectRecordHitWithIndexNV( + inout hitObjectNV hitObject, + accelerationStructureEXT topLevel, + int instanceid, + int primitiveid, + int geometryindex, + uint hitKind, + uint sbtRecordIndex, + vec3 origin, + float Tmin, + vec3 direction, + float Tmax, + constexpr int attributeLocation) +{ + __target_switch + { + case glsl: + { + HitObject::__glslMakeHitWithIndex( + hitObject, + topLevel, + instanceid, + primitiveid, + geometryindex, + hitKind, + sbtRecordIndex, + origin, + Tmin, + direction, + Tmax, + attributeLocation); + } + case spirv: + { + spirv_asm + { + OpHitObjectRecordHitWithIndexNV + /**/ &hitObject + /**/ $topLevel + /**/ $instanceid + /**/ $primitiveid + /**/ $geometryindex + /**/ $hitKind + /**/ $sbtRecordIndex + /**/ $origin + /**/ $Tmin + /**/ $direction + /**/ $Tmax + /**/ __rayAttributeFromLocation(attributeLocation) + }; + } + } +} + +__glsl_extension(GL_EXT_ray_tracing) +__glsl_extension(GL_NV_shader_invocation_reorder) +__glsl_extension(GLSL_EXT_buffer_reference_uvec2) +__glsl_extension(GL_NV_ray_tracing_motion_blur) +[require(glsl, ser_motion)] +[require(spirv, ser_motion)] +[ForceInline] +public void hitObjectRecordHitWithIndexMotionNV( + inout hitObjectNV hitObject, + accelerationStructureEXT topLevel, + int instanceid, + int primitiveid, + int geometryindex, + uint hitKind, + uint sbtRecordIndex, + vec3 origin, + float Tmin, + vec3 direction, + float Tmax, + float currentTime, + constexpr int attributeLocation) + { + __target_switch + { + case glsl: + { + HitObject::__glslMakeMotionHitWithIndex( + hitObject, + topLevel, + instanceid, + primitiveid, + geometryindex, + hitKind, + sbtRecordIndex, + origin, + Tmin, + direction, + Tmax, + currentTime, + attributeLocation); + } + case spirv: + { + spirv_asm + { + OpCapability RayTracingMotionBlurNV; + OpExtension "SPV_NV_ray_tracing_motion_blur"; + OpHitObjectRecordHitWithIndexMotionNV + /**/ &hitObject + /**/ $topLevel + /**/ $instanceid + /**/ $primitiveid + /**/ $geometryindex + /**/ $hitKind + /**/ $sbtRecordIndex + /**/ $origin + /**/ $Tmin + /**/ $direction + /**/ $Tmax + /**/ $currentTime + /**/ __rayAttributeFromLocation(attributeLocation) + }; + } + } +} + +__glsl_extension(GL_EXT_ray_tracing) +__glsl_extension(GL_NV_shader_invocation_reorder) +__glsl_extension(GLSL_EXT_buffer_reference_uvec2) +[require(glsl, ser)] +[require(spirv, ser)] +[ForceInline] +public void hitObjectRecordMissNV( + inout hitObjectNV hitObject, + uint sbtRecordIndex, + vec3 origin, + float Tmin, + vec3 direction, + float Tmax) +{ + hitObject = HitObject::MakeMiss( + sbtRecordIndex, + { origin, Tmin, direction, Tmax } + ); +} + +__glsl_extension(GL_EXT_ray_tracing) +__glsl_extension(GL_NV_shader_invocation_reorder) +__glsl_extension(GLSL_EXT_buffer_reference_uvec2) +__glsl_extension(GL_NV_ray_tracing_motion_blur) +[require(glsl, ser_motion)] +[require(spirv, ser_motion)] +[ForceInline] +public void hitObjectRecordMissMotionNV( + inout hitObjectNV hitObject, + uint sbtRecordIndex, + vec3 origin, + float Tmin, + vec3 direction, + float Tmax, + float currentTime) +{ + hitObject = HitObject::MakeMotionMiss( + sbtRecordIndex, + { origin, Tmin, direction, Tmax }, + currentTime + ); +} + +__glsl_extension(GL_EXT_ray_tracing) +__glsl_extension(GL_NV_shader_invocation_reorder) +__glsl_extension(GLSL_EXT_buffer_reference_uvec2) +[require(glsl, ser)] +[require(spirv, ser)] +[ForceInline] +public void hitObjectRecordEmptyNV(hitObjectNV hitObject) +{ + hitObject = HitObject::MakeNop(); +} + +__glsl_extension(GL_EXT_ray_tracing) +__glsl_extension(GL_NV_shader_invocation_reorder) +__glsl_extension(GLSL_EXT_buffer_reference_uvec2) +[require(glsl, ser)] +[require(spirv, ser)] +[ForceInline] +public void hitObjectExecuteShaderNV( + inout hitObjectNV hitObject, + constexpr int payload) +{ + __target_switch + { + case glsl: + { + HitObject::__glslInvoke(hitObject, payload); + } + case spirv: + { + spirv_asm + { + OpHitObjectExecuteShaderNV &hitObject __rayPayloadFromLocation(payload) + }; + } + } +} + +__glsl_extension(GL_EXT_ray_tracing) +__glsl_extension(GL_NV_shader_invocation_reorder) +__glsl_extension(GLSL_EXT_buffer_reference_uvec2) +[require(glsl, ser)] +[require(spirv, ser)] +[ForceInline] +public bool hitObjectIsEmptyNV(hitObjectNV hitObject) +{ + return hitObject.IsNop(); +} + +__glsl_extension(GL_EXT_ray_tracing) +__glsl_extension(GL_NV_shader_invocation_reorder) +__glsl_extension(GLSL_EXT_buffer_reference_uvec2) +[require(glsl, ser)] +[require(spirv, ser)] +[ForceInline] +public bool hitObjectIsMissNV(hitObjectNV hitObject) +{ + return hitObject.IsMiss(); +} + +__glsl_extension(GL_EXT_ray_tracing) +__glsl_extension(GL_NV_shader_invocation_reorder) +__glsl_extension(GLSL_EXT_buffer_reference_uvec2) +[require(glsl, ser)] +[require(spirv, ser)] +[ForceInline] +public bool hitObjectIsHitNV(hitObjectNV hitObject) +{ + return hitObject.IsHit(); +} + +__glsl_extension(GL_EXT_ray_tracing) +__glsl_extension(GL_NV_shader_invocation_reorder) +__glsl_extension(GLSL_EXT_buffer_reference_uvec2) +[require(glsl, ser)] +[require(spirv, ser)] +[ForceInline] +public float hitObjectGetRayTMinNV(hitObjectNV hitObject) +{ + return hitObject.GetRayDesc().TMin; +} + +__glsl_extension(GL_EXT_ray_tracing) +__glsl_extension(GL_NV_shader_invocation_reorder) +__glsl_extension(GLSL_EXT_buffer_reference_uvec2) +[require(glsl, ser)] +[require(spirv, ser)] +[ForceInline] +public float hitObjectGetRayTMaxNV(hitObjectNV hitObject) +{ + return hitObject.GetRayDesc().TMax; +} + +__glsl_extension(GL_EXT_ray_tracing) +__glsl_extension(GL_NV_shader_invocation_reorder) +__glsl_extension(GLSL_EXT_buffer_reference_uvec2) +[require(glsl, ser)] +[require(spirv, ser)] +[ForceInline] +public vec3 hitObjectGetWorldRayOriginNV(hitObjectNV hitObject) +{ + return hitObject.GetRayDesc().Origin; +} + +__glsl_extension(GL_EXT_ray_tracing) +__glsl_extension(GL_NV_shader_invocation_reorder) +__glsl_extension(GLSL_EXT_buffer_reference_uvec2) +[require(glsl, ser)] +[require(spirv, ser)] +[ForceInline] +public vec3 hitObjectGetWorldRayDirectionNV(hitObjectNV hitObject) +{ + return hitObject.GetRayDesc().Direction; +} + +__glsl_extension(GL_EXT_ray_tracing) +__glsl_extension(GL_NV_shader_invocation_reorder) +__glsl_extension(GLSL_EXT_buffer_reference_uvec2) +[require(glsl, ser)] +[require(spirv, ser)] +[ForceInline] +public vec3 hitObjectGetObjectRayOriginNV(hitObjectNV hitObject) +{ + return hitObject.GetObjectRayOrigin(); +} + +__glsl_extension(GL_EXT_ray_tracing) +__glsl_extension(GL_NV_shader_invocation_reorder) +__glsl_extension(GLSL_EXT_buffer_reference_uvec2) +[require(glsl, ser)] +[require(spirv, ser)] +[ForceInline] +public vec3 hitObjectGetObjectRayDirectionNV(hitObjectNV hitObject) +{ + return hitObject.GetObjectRayDirection(); +} + +__glsl_extension(GL_EXT_ray_tracing) +__glsl_extension(GL_NV_shader_invocation_reorder) +__glsl_extension(GLSL_EXT_buffer_reference_uvec2) +[require(glsl, ser)] +[require(spirv, ser)] +[ForceInline] +public mat4x3 hitObjectGetObjectToWorldNV(hitObjectNV hitObject) +{ + return transpose(hitObject.GetObjectToWorld()); +} + +__glsl_extension(GL_EXT_ray_tracing) +__glsl_extension(GL_NV_shader_invocation_reorder) +__glsl_extension(GLSL_EXT_buffer_reference_uvec2) +[require(glsl, ser)] +[require(spirv, ser)] +[ForceInline] +public mat4x3 hitObjectGetWorldToObjectNV(hitObjectNV hitObject) +{ + return transpose(hitObject.GetWorldToObject()); +} + +__glsl_extension(GL_EXT_ray_tracing) +__glsl_extension(GL_NV_shader_invocation_reorder) +__glsl_extension(GLSL_EXT_buffer_reference_uvec2) +[require(glsl, ser)] +[require(spirv, ser)] +[ForceInline] +public int hitObjectGetInstanceCustomIndexNV(hitObjectNV hitObject) +{ + return hitObject.GetInstanceID(); +} + +__glsl_extension(GL_EXT_ray_tracing) +__glsl_extension(GL_NV_shader_invocation_reorder) +__glsl_extension(GLSL_EXT_buffer_reference_uvec2) +[require(glsl, ser)] +[require(spirv, ser)] +[ForceInline] +public int hitObjectGetInstanceIdNV(hitObjectNV hitObject) +{ + return hitObject.GetInstanceIndex(); +} + +[require(glsl, ser)] +[require(spirv, ser)] +[ForceInline] +public int hitObjectGetGeometryIndexNV(hitObjectNV hitObject) +{ + return hitObject.GetGeometryIndex(); +} + +__glsl_extension(GL_EXT_ray_tracing) +__glsl_extension(GL_NV_shader_invocation_reorder) +__glsl_extension(GLSL_EXT_buffer_reference_uvec2) +[require(glsl, ser)] +[require(spirv, ser)] +[ForceInline] +public int hitObjectGetPrimitiveIndexNV(hitObjectNV hitObject) +{ + return hitObject.GetPrimitiveIndex(); +} + +__glsl_extension(GL_EXT_ray_tracing) +__glsl_extension(GL_NV_shader_invocation_reorder) +__glsl_extension(GLSL_EXT_buffer_reference_uvec2) +[require(glsl, ser)] +[require(spirv, ser)] +[ForceInline] +public uint hitObjectGetHitKindNV(hitObjectNV hitObject) +{ + return hitObject.GetHitKind(); +} + +__glsl_extension(GL_EXT_ray_tracing) +__glsl_extension(GL_NV_shader_invocation_reorder) +__glsl_extension(GLSL_EXT_buffer_reference_uvec2) +[require(glsl, ser)] +[require(spirv, ser)] +[ForceInline] +public void hitObjectGetAttributesNV( + inout hitObjectNV hitObject, + constexpr int attributeLocation) +{ + __target_switch + { + case glsl: + { + __intrinsic_asm "hitObjectGetAttributesNV($0, $1)"; + } + case spirv: + { + spirv_asm + { + OpCapability ShaderInvocationReorderNV; + OpHitObjectGetAttributesNV &hitObject __rayAttributeFromLocation(attributeLocation) + }; + } + } +} + +__glsl_extension(GL_EXT_ray_tracing) +__glsl_extension(GL_NV_shader_invocation_reorder) +__glsl_extension(GLSL_EXT_buffer_reference_uvec2) +[require(glsl, ser)] +[require(spirv, ser)] +[ForceInline] +public uvec2 hitObjectGetShaderRecordBufferHandleNV(hitObjectNV hitObject) +{ + return hitObject.GetShaderRecordBufferHandle(); +} + +__glsl_extension(GL_EXT_ray_tracing) +__glsl_extension(GL_NV_shader_invocation_reorder) +__glsl_extension(GLSL_EXT_buffer_reference_uvec2) +[require(glsl, ser)] +[require(spirv, ser)] +[ForceInline] +public uint hitObjectGetShaderBindingTableRecordIndexNV(hitObjectNV hitObject) +{ + return hitObject.GetShaderTableIndex(); +} + +__glsl_extension(GL_EXT_ray_tracing) +__glsl_extension(GL_NV_shader_invocation_reorder) +__glsl_extension(GLSL_EXT_buffer_reference_uvec2) +[require(glsl, ser)] +[require(spirv, ser)] +[ForceInline] +public float hitObjectGetCurrentTimeNV(hitObjectNV hitObject) +{ + return hitObject.GetCurrentTime(); +} + +__glsl_extension(GL_EXT_ray_tracing) +__glsl_extension(GL_NV_shader_invocation_reorder) +__glsl_extension(GLSL_EXT_buffer_reference_uvec2) +[require(glsl, ser)] +[require(spirv, ser)] +[ForceInline] +public void reorderThreadNV(uint hint, uint bits) +{ + ReorderThread(hint, bits); +} + +__glsl_extension(GL_EXT_ray_tracing) +__glsl_extension(GL_NV_shader_invocation_reorder) +__glsl_extension(GLSL_EXT_buffer_reference_uvec2) +[require(glsl, ser)] +[require(spirv, ser)] +[ForceInline] +public void reorderThreadNV(hitObjectNV hitObject) +{ + ReorderThread(hitObject); +} + +__glsl_extension(GL_EXT_ray_tracing) +__glsl_extension(GL_NV_shader_invocation_reorder) +__glsl_extension(GLSL_EXT_buffer_reference_uvec2) +[require(glsl, ser)] +[require(spirv, ser)] +[ForceInline] +public void reorderThreadNV(hitObjectNV hitObject, uint hint, uint bits) +{ + ReorderThread(hitObject, hint, bits); +} + +/// GL_NV_ray_tracing_motion_blur + +[require(glsl, raytracing_motionblur)] +[require(spirv, raytracing_motionblur)] +public property float gl_CurrentRayTimeNV +{ + get + { + __target_switch + { + case glsl: + __intrinsic_asm "(gl_CurrentRayTimeNV)"; + case spirv: + return spirv_asm + { + OpCapability RayTracingMotionBlurNV; + OpExtension "SPV_NV_ray_tracing_motion_blur"; + result:$$float = OpLoad builtin(CurrentRayTimeNV:float); + }; + } + } +} + +__glsl_extension(GL_EXT_ray_tracing) +__glsl_extension(GL_NV_ray_tracing_motion_blur) +[require(glsl, raytracing_motionblur)] +[require(spirv, raytracing_motionblur)] +[ForceInline] +public void traceRayMotionNV( + accelerationStructureEXT topLevel, + uint rayFlags, + uint cullMask, + uint sbtRecordOffset, + uint sbtRecordStride, + uint missIndex, + vec3 origin, + float Tmin, + vec3 direction, + float Tmax, + float currentTime, + constexpr int payload) +{ + __target_switch + { + case glsl: + { + __traceMotionRay( + topLevel, + rayFlags, + cullMask, + sbtRecordOffset, + sbtRecordStride, + missIndex, + origin, + Tmin, + direction, + Tmax, + currentTime, + payload); + } + case spirv: + { + spirv_asm + { + OpCapability RayTracingMotionBlurNV; + OpExtension "SPV_NV_ray_tracing_motion_blur"; + OpTraceRayMotionNV + /**/ $topLevel + /**/ $rayFlags + /**/ $cullMask + /**/ $sbtRecordOffset + /**/ $sbtRecordStride + /**/ $missIndex + /**/ $origin + /**/ $Tmin + /**/ $direction + /**/ $Tmax + /**/ $currentTime + /**/ __rayPayloadFromLocation(payload) + }; + } + } +} __generic<T : __BuiltinType> [ForceInline] diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang index f220a68a5..8df7861ea 100644 --- a/source/slang/hlsl.meta.slang +++ b/source/slang/hlsl.meta.slang @@ -9520,6 +9520,7 @@ struct BuiltInTriangleIntersectionAttributes // `CallShader()` for GLSL-based targets. // __target_intrinsic(_GL_EXT_ray_tracing, "executeCallableEXT") +[require(glsl, raytracing)] void __executeCallable(uint shaderIndex, int payloadLocation); // Next is the custom intrinsic that will compute the payload location @@ -9535,6 +9536,9 @@ int __callablePayloadLocation(__ref Payload payload); // GLSL equivalent. // __generic<Payload> +[require(glsl, raytracing)] +[require(spirv, raytracing)] +[require(hlsl, raytracing)] void CallShader(uint shaderIndex, inout Payload payload) { __target_switch @@ -9555,7 +9559,8 @@ void CallShader(uint shaderIndex, inout Payload payload) static Payload p; p = payload; - spirv_asm { + spirv_asm + { OpExecuteCallableKHR $shaderIndex &p }; payload = p; @@ -9565,7 +9570,9 @@ void CallShader(uint shaderIndex, inout Payload payload) // 10.3.2 + __target_intrinsic(_GL_EXT_ray_tracing, "traceRayEXT") +[require(glsl, raytracing)] void __traceRay( RaytracingAccelerationStructure AccelerationStructure, uint RayFlags, @@ -9590,6 +9597,9 @@ __generic<Payload> __intrinsic_op($(kIROp_GetVulkanRayTracingPayloadLocation)) int __rayPayloadLocation(__ref Payload payload); +[require(glsl, raytracing)] +[require(spirv, raytracing)] +[require(hlsl, raytracing)] __generic<payload_t> void TraceRay( RaytracingAccelerationStructure AccelerationStructure, @@ -9635,7 +9645,8 @@ void TraceRay( let direction = Ray.Direction; let tmin = Ray.TMin; let tmax = Ray.TMax; - spirv_asm { + spirv_asm + { OpTraceRayKHR /**/ $AccelerationStructure /**/ $RayFlags @@ -9660,10 +9671,9 @@ void TraceRay( // // https://github.com/KhronosGroup/GLSL/blob/master/extensions/nv/GLSL_NV_ray_tracing_motion_blur.txt -__target_intrinsic(glsl, "traceRayMotionNV") -__glsl_version(460) __glsl_extension(GL_NV_ray_tracing_motion_blur) -__glsl_extension(GL_EXT_ray_tracing) +__target_intrinsic(glsl, "traceRayMotionNV") +[require(glsl, raytracing_motionblur)] void __traceMotionRay( RaytracingAccelerationStructure AccelerationStructure, uint RayFlags, @@ -9678,6 +9688,9 @@ void __traceMotionRay( float CurrentTime, int PayloadLocation); +[require(glsl, raytracing_motionblur)] +[require(spirv, raytracing_motionblur)] +[require(hlsl, raytracing_motionblur)] __generic<payload_t> void TraceMotionRay( RaytracingAccelerationStructure AccelerationStructure, @@ -9725,7 +9738,8 @@ void TraceMotionRay( let tmax = Ray.TMax; p = Payload; - spirv_asm { + spirv_asm + { OpCapability RayTracingMotionBlurNV; OpExtension "SPV_NV_ray_tracing_motion_blur"; @@ -9750,15 +9764,19 @@ void TraceMotionRay( // 10.3.3 __target_intrinsic(hlsl) +[require(hlsl, raytracing)] bool ReportHit<A>(float tHit, uint hitKind, A attributes); +[require(spirv, raytracing)] +[require(glsl, raytracing)] bool __reportIntersection(float tHit, uint hitKind) { __target_switch { case _GL_EXT_ray_tracing: __intrinsic_asm "reportIntersectionEXT"; case spirv: - return spirv_asm { + return spirv_asm + { result:$$bool = OpReportIntersectionKHR $tHit $hitKind; }; } @@ -9777,6 +9795,9 @@ bool ReportHit(float tHit, uint hitKind, A attributes) } // 10.3.4 +[require(hlsl, raytracing)] +[require(glsl, raytracing)] +[require(spirv, raytracing)] void IgnoreHit() { __target_switch @@ -9784,11 +9805,18 @@ void IgnoreHit() case hlsl: __intrinsic_asm "IgnoreHit"; case _GL_EXT_ray_tracing: __intrinsic_asm "ignoreIntersectionEXT;"; case cuda: __intrinsic_asm "optixIgnoreIntersection"; - case spirv: spirv_asm { OpIgnoreIntersectionKHR; %_ = OpLabel }; + case spirv: + spirv_asm + { + OpIgnoreIntersectionKHR; %_ = OpLabel + }; } } // 10.3.5 +[require(hlsl, raytracing)] +[require(glsl, raytracing)] +[require(spirv, raytracing)] void AcceptHitAndEndSearch() { __target_switch @@ -9796,7 +9824,11 @@ void AcceptHitAndEndSearch() case hlsl: __intrinsic_asm "AcceptHitAndEndSearch"; case _GL_EXT_ray_tracing: __intrinsic_asm "terminateRayEXT;"; case cuda: __intrinsic_asm "optixTerminateRay"; - case spirv: spirv_asm { OpTerminateRayKHR; %_ = OpLabel }; + case spirv: + spirv_asm + { + OpTerminateRayKHR; %_ = OpLabel + }; } } @@ -9808,20 +9840,27 @@ void AcceptHitAndEndSearch() // 10.4.1 - Ray Dispatch System Values [NonUniformReturn] +[require(hlsl, raytracing)] +[require(glsl, raytracing)] +[require(spirv, raytracing)] uint3 DispatchRaysIndex() { __target_switch { - case hlsl: __intrinsic_asm "DispatchRaysIndex"; + case hlsl: __intrinsic_asm "DispatchRaysIndex"; case _GL_EXT_ray_tracing: __intrinsic_asm "(gl_LaunchIDEXT)"; case cuda: __intrinsic_asm "optixGetLaunchIndex"; case spirv: - return spirv_asm { + return spirv_asm + { result:$$uint3 = OpLoad builtin(LaunchIdKHR:uint3); }; } } +[require(hlsl, raytracing)] +[require(glsl, raytracing)] +[require(spirv, raytracing)] uint3 DispatchRaysDimensions() { __target_switch @@ -9830,7 +9869,8 @@ uint3 DispatchRaysDimensions() case _GL_EXT_ray_tracing: __intrinsic_asm "(gl_LaunchSizeEXT)"; case cuda: __intrinsic_asm "optixGetLaunchDimensions"; case spirv: - return spirv_asm { + return spirv_asm + { result:$$uint3 = OpLoad builtin(LaunchSizeKHR:uint3); }; } @@ -9839,6 +9879,9 @@ uint3 DispatchRaysDimensions() // 10.4.2 - Ray System Values [NonUniformReturn] +[require(hlsl, raytracing)] +[require(glsl, raytracing)] +[require(spirv, raytracing)] float3 WorldRayOrigin() { __target_switch @@ -9847,13 +9890,17 @@ float3 WorldRayOrigin() case _GL_EXT_ray_tracing: __intrinsic_asm "(gl_WorldRayOriginEXT)"; case cuda: __intrinsic_asm "optixGetWorldRayOrigin"; case spirv: - return spirv_asm { + return spirv_asm + { result:$$float3 = OpLoad builtin(WorldRayOriginKHR:float3); }; } } [NonUniformReturn] +[require(hlsl, raytracing)] +[require(glsl, raytracing)] +[require(spirv, raytracing)] float3 WorldRayDirection() { __target_switch @@ -9862,13 +9909,17 @@ float3 WorldRayDirection() case _GL_EXT_ray_tracing: __intrinsic_asm "(gl_WorldRayDirectionEXT)"; case cuda: __intrinsic_asm "optixGetWorldRayDirection"; case spirv: - return spirv_asm { + return spirv_asm + { result:$$float3 = OpLoad builtin(WorldRayDirectionKHR:float3); }; } } [NonUniformReturn] +[require(hlsl, raytracing)] +[require(glsl, raytracing)] +[require(spirv, raytracing)] float RayTMin() { __target_switch @@ -9877,7 +9928,8 @@ float RayTMin() case _GL_EXT_ray_tracing: __intrinsic_asm "(gl_RayTminEXT)"; case cuda: __intrinsic_asm "optixGetRayTmin"; case spirv: - return spirv_asm { + return spirv_asm + { result:$$float = OpLoad builtin(RayTminKHR:float); }; } @@ -9894,6 +9946,9 @@ float RayTMin() // to the appropriate Vulkan stages. // [NonUniformReturn] +[require(hlsl, raytracing)] +[require(glsl, raytracing)] +[require(spirv, raytracing)] float RayTCurrent() { __target_switch @@ -9902,12 +9957,16 @@ float RayTCurrent() case _GL_EXT_ray_tracing: __intrinsic_asm "(gl_RayTmaxEXT)"; case cuda: __intrinsic_asm "optixGetRayTmax"; case spirv: - return spirv_asm { + return spirv_asm + { result:$$float = OpLoad builtin(RayTmaxKHR:float); }; } } +[require(hlsl, raytracing)] +[require(glsl, raytracing)] +[require(spirv, raytracing)] uint RayFlags() { __target_switch @@ -9916,7 +9975,8 @@ uint RayFlags() case _GL_EXT_ray_tracing: __intrinsic_asm "(gl_IncomingRayFlagsEXT)"; case cuda: __intrinsic_asm "optixGetRayFlags"; case spirv: - return spirv_asm { + return spirv_asm + { result:$$uint = OpLoad builtin(IncomingRayFlagsKHR:uint); }; } @@ -9925,6 +9985,9 @@ uint RayFlags() // 10.4.3 - Primitive/Object Space System Values [NonUniformReturn] +[require(hlsl, raytracing)] +[require(glsl, raytracing)] +[require(spirv, raytracing)] uint InstanceIndex() { __target_switch @@ -9933,13 +9996,17 @@ uint InstanceIndex() case _GL_EXT_ray_tracing: __intrinsic_asm "(gl_InstanceID)"; case cuda: __intrinsic_asm "optixGetInstanceIndex"; case spirv: - return spirv_asm { + return spirv_asm + { result:$$uint = OpLoad builtin(InstanceId:uint); }; } } [NonUniformReturn] +[require(hlsl, raytracing)] +[require(glsl, raytracing)] +[require(spirv, raytracing)] uint InstanceID() { __target_switch @@ -9948,28 +10015,36 @@ uint InstanceID() case _GL_EXT_ray_tracing: __intrinsic_asm "(gl_InstanceCustomIndexEXT)"; case cuda: __intrinsic_asm "optixGetInstanceId"; case spirv: - return spirv_asm { + return spirv_asm + { result:$$uint = OpLoad builtin(InstanceCustomIndexKHR:uint); }; } } [NonUniformReturn] +[require(hlsl, raytracing)] +[require(glsl, raytracing)] +[require(spirv, raytracing)] uint PrimitiveIndex() { __target_switch { case hlsl: __intrinsic_asm "PrimitiveIndex"; - case _GL_EXT_ray_tracing: __intrinsic_asm "(gl_PrimitiveID)"; + case _GL_EXT_ray_tracing: __intrinsic_asm "(gl_PrimitiveID)"; case cuda: __intrinsic_asm "optixGetPrimitiveIndex"; case spirv: - return spirv_asm { + return spirv_asm + { result:$$uint = OpLoad builtin(PrimitiveId:uint); }; } } [NonUniformReturn] +[require(hlsl, raytracing)] +[require(glsl, raytracing)] +[require(spirv, raytracing)] float3 ObjectRayOrigin() { __target_switch @@ -9978,13 +10053,17 @@ float3 ObjectRayOrigin() case _GL_EXT_ray_tracing: __intrinsic_asm "(gl_ObjectRayOriginEXT)"; case cuda: __intrinsic_asm "optixGetObjectRayOrigin"; case spirv: - return spirv_asm { + return spirv_asm + { result:$$float3 = OpLoad builtin(ObjectRayOriginKHR:float3); }; } } [NonUniformReturn] +[require(hlsl, raytracing)] +[require(glsl, raytracing)] +[require(spirv, raytracing)] float3 ObjectRayDirection() { __target_switch @@ -9993,7 +10072,8 @@ float3 ObjectRayDirection() case _GL_EXT_ray_tracing: __intrinsic_asm "(gl_ObjectRayDirectionEXT)"; case cuda: __intrinsic_asm "optixGetObjectRayDirection"; case spirv: - return spirv_asm { + return spirv_asm + { result:$$float3 = OpLoad builtin(ObjectRayDirectionKHR:float3); }; } @@ -10002,6 +10082,9 @@ float3 ObjectRayDirection() // TODO: optix has an optixGetObjectToWorldTransformMatrix function that returns 12 // floats by reference. [NonUniformReturn] +[require(hlsl, raytracing)] +[require(glsl, raytracing)] +[require(spirv, raytracing)] float3x4 ObjectToWorld3x4() { __target_switch @@ -10009,7 +10092,8 @@ float3x4 ObjectToWorld3x4() case hlsl: __intrinsic_asm "ObjectToWorld3x4"; case _GL_EXT_ray_tracing: __intrinsic_asm "transpose(gl_ObjectToWorldEXT)"; case spirv: - return spirv_asm { + return spirv_asm + { %mat:$$float4x3 = OpLoad builtin(ObjectToWorldKHR:float4x3); result:$$float3x4 = OpTranspose %mat; }; @@ -10017,6 +10101,9 @@ float3x4 ObjectToWorld3x4() } [NonUniformReturn] +[require(hlsl, raytracing)] +[require(glsl, raytracing)] +[require(spirv, raytracing)] float3x4 WorldToObject3x4() { __target_switch @@ -10024,7 +10111,8 @@ float3x4 WorldToObject3x4() case hlsl: __intrinsic_asm "WorldToObject3x4"; case _GL_EXT_ray_tracing: __intrinsic_asm "transpose(gl_WorldToObjectEXT)"; case spirv: - return spirv_asm { + return spirv_asm + { %mat:$$float4x3 = OpLoad builtin(WorldToObjectKHR:float4x3); result:$$float3x4 = OpTranspose %mat; }; @@ -10032,6 +10120,9 @@ float3x4 WorldToObject3x4() } [NonUniformReturn] +[require(hlsl, raytracing)] +[require(glsl, raytracing)] +[require(spirv, raytracing)] float4x3 ObjectToWorld4x3() { __target_switch @@ -10039,13 +10130,17 @@ float4x3 ObjectToWorld4x3() case hlsl: __intrinsic_asm "ObjectToWorld4x3"; case _GL_EXT_ray_tracing: __intrinsic_asm "(gl_ObjectToWorldEXT)"; case spirv: - return spirv_asm { + return spirv_asm + { result:$$float4x3 = OpLoad builtin(ObjectToWorldKHR:float4x3); }; } } [NonUniformReturn] +[require(hlsl, raytracing)] +[require(glsl, raytracing)] +[require(spirv, raytracing)] float4x3 WorldToObject4x3() { __target_switch @@ -10053,7 +10148,8 @@ float4x3 WorldToObject4x3() case hlsl: __intrinsic_asm "WorldToObject4x3"; case _GL_EXT_ray_tracing: __intrinsic_asm "(gl_WorldToObjectEXT)"; case spirv: - return spirv_asm { + return spirv_asm + { result:$$float4x3 = OpLoad builtin(WorldToObjectKHR:float4x3); }; } @@ -10063,10 +10159,12 @@ float4x3 WorldToObject4x3() // The name of the following functions may change when DXR supports // a feature similar to the `GL_NV_ray_tracing_motion_blur` extension -__glsl_version(460) __glsl_extension(GL_NV_ray_tracing_motion_blur) __glsl_extension(GL_EXT_ray_tracing) [NonUniformReturn] +[require(hlsl, raytracing_motionblur)] +[require(glsl, raytracing_motionblur)] +[require(spirv, raytracing_motionblur)] float RayCurrentTime() { __target_switch @@ -10074,7 +10172,8 @@ float RayCurrentTime() case hlsl: __intrinsic_asm "RayCurrentTime"; case glsl: __intrinsic_asm "(gl_CurrentRayTimeNV)"; case spirv: - return spirv_asm { + return spirv_asm + { result:$$float = OpLoad builtin(CurrentRayTimeNV:float); }; } @@ -10094,15 +10193,19 @@ float RayCurrentTime() // 10.4.4 - Hit Specific System values [NonUniformReturn] +[require(hlsl, raytracing)] +[require(glsl, raytracing)] +[require(spirv, raytracing)] uint HitKind() { __target_switch { case hlsl: __intrinsic_asm "HitKind"; - case _GL_EXT_ray_tracing: __intrinsic_asm "(gl_HitKindEXT)"; + case _GL_EXT_ray_tracing: __intrinsic_asm "(gl_HitKindEXT)"; case cuda: __intrinsic_asm "optixGetHitKind"; case spirv: - return spirv_asm { + return spirv_asm + { result:$$uint = OpLoad builtin(HitKindKHR:uint); }; } @@ -10291,6 +10394,9 @@ extension __TextureImpl<T,__Shape2D, 1, 0, 0, $(kStdlibResourceAccessFeedback), // Get the index of the geometry that was hit in an intersection, any-hit, or closest-hit shader __glsl_extension(GL_EXT_ray_tracing) +[require(glsl, raytracing)] +[require(spirv, raytracing)] +[require(hlsl, raytracing)] [NonUniformReturn] uint GeometryIndex() { @@ -10308,7 +10414,8 @@ uint GeometryIndex() // https://github.com/KhronosGroup/GLSL/blob/master/extensions/ext/GLSL_EXT_ray_tracing_position_fetch.txt __glsl_extension(GL_EXT_ray_tracing) __glsl_extension(GL_EXT_ray_tracing_position_fetch) -__glsl_version(460) +[require(glsl, raytracing_pos)] +[require(spirv, raytracing_pos)] [ForceInline] float3 HitTriangleVertexPosition(uint index) { @@ -10392,8 +10499,9 @@ static const CANDIDATE_TYPE CANDIDATE_PROCEDURAL_PRIMITIVE = 1; // In Slang, a parameter like `q` above should be declared `inout`. // HLSL does not care about whether `q` is declared `inout` or not. // +//cannot use a cap for struct with unequal target support +//since it will propegate rules to children __glsl_extension(GL_EXT_ray_query) -__glsl_version(460) [__NonCopyableType] __intrinsic_type($(kIROp_RayQueryType)) struct RayQuery <let rayFlagsGeneric : RAY_FLAG = RAY_FLAG_NONE> @@ -10403,10 +10511,11 @@ struct RayQuery <let rayFlagsGeneric : RAY_FLAG = RAY_FLAG_NONE> __intrinsic_op($(kIROp_AllocateOpaqueHandle)) __init(); - + __target_intrinsic(glsl, "rayQueryInitializeEXT($0, $1, $2, $3, $4, $5, $6, $7)") __glsl_extension(GL_EXT_ray_query) - __glsl_version(460) + [require(glsl, rayquery)] + [require(spirv, rayquery)] [mutating] void __rayQueryInitializeEXT( RaytracingAccelerationStructure accelerationStructure, @@ -10439,6 +10548,9 @@ struct RayQuery <let rayFlagsGeneric : RAY_FLAG = RAY_FLAG_NONE> // `RayQuery` to get the effective ray flags, which // must obey any API-imposed restrictions. // + [require(glsl, rayquery)] + [require(spirv, rayquery)] + [require(hlsl, rayquery)] [__unsafeForceInlineEarly] [mutating] void TraceRayInline( @@ -10478,7 +10590,9 @@ struct RayQuery <let rayFlagsGeneric : RAY_FLAG = RAY_FLAG_NONE> // that was found. // __glsl_extension(GL_EXT_ray_query) - __glsl_version(460) + [require(glsl, rayquery)] + [require(spirv, rayquery)] + [require(hlsl, rayquery)] [mutating] bool Proceed() { @@ -10500,7 +10614,9 @@ struct RayQuery <let rayFlagsGeneric : RAY_FLAG = RAY_FLAG_NONE> // `Proceed()` calls will return `false`. // __glsl_extension(GL_EXT_ray_query) - __glsl_version(460) + [require(glsl, rayquery)] + [require(spirv, rayquery)] + [require(hlsl, rayquery)] [mutating] void Abort() { @@ -10514,7 +10630,9 @@ struct RayQuery <let rayFlagsGeneric : RAY_FLAG = RAY_FLAG_NONE> // Commit the current non-opaque triangle hit. __glsl_extension(GL_EXT_ray_query) - __glsl_version(460) + [require(glsl, rayquery)] + [require(spirv, rayquery)] + [require(hlsl, rayquery)] [__NoSideEffect] [mutating] void CommitNonOpaqueTriangleHit() @@ -10529,7 +10647,9 @@ struct RayQuery <let rayFlagsGeneric : RAY_FLAG = RAY_FLAG_NONE> // Commit the current procedural primitive hit, with hit time `t`. __glsl_extension(GL_EXT_ray_query) - __glsl_version(460) + [require(glsl, rayquery)] + [require(spirv, rayquery)] + [require(hlsl, rayquery)] [__NoSideEffect] [mutating] void CommitProceduralPrimitiveHit(float t) @@ -10552,7 +10672,9 @@ struct RayQuery <let rayFlagsGeneric : RAY_FLAG = RAY_FLAG_NONE> // user code. // __glsl_extension(GL_EXT_ray_query) - __glsl_version(460) + [require(glsl, rayquery)] + [require(spirv, rayquery)] + [require(hlsl, rayquery)] [__NoSideEffect] [NonUniformReturn] CANDIDATE_TYPE CandidateType() @@ -10571,7 +10693,9 @@ struct RayQuery <let rayFlagsGeneric : RAY_FLAG = RAY_FLAG_NONE> // Get the status of the committed (closest) hit, if any. __glsl_extension(GL_EXT_ray_query) - __glsl_version(460) + [require(glsl, rayquery)] + [require(spirv, rayquery)] + [require(hlsl, rayquery)] [__NoSideEffect] [NonUniformReturn] COMMITTED_STATUS CommittedStatus() @@ -10590,7 +10714,9 @@ struct RayQuery <let rayFlagsGeneric : RAY_FLAG = RAY_FLAG_NONE> } __glsl_extension(GL_EXT_ray_query) - __glsl_version(460) + [require(glsl, rayquery)] + [require(spirv, rayquery)] + [require(hlsl, rayquery)] [__NoSideEffect] [NonUniformReturn] bool CandidateProceduralPrimitiveNonOpaque() @@ -10598,7 +10724,7 @@ struct RayQuery <let rayFlagsGeneric : RAY_FLAG = RAY_FLAG_NONE> __target_switch { case hlsl: __intrinsic_asm ".CandidateProceduralPrimitiveNonOpaque"; - case glsl: __intrinsic_asm "(!rayQueryGetIntersectionCandidateAABBOpaqueEXT($0, false))"; + case glsl: __intrinsic_asm "(!rayQueryGetIntersectionCandidateAABBOpaqueEXT($0))"; case spirv: uint iCandidateOrCommitted = 0; return spirv_asm @@ -10610,7 +10736,9 @@ struct RayQuery <let rayFlagsGeneric : RAY_FLAG = RAY_FLAG_NONE> } __glsl_extension(GL_EXT_ray_query) - __glsl_version(460) + [require(glsl, rayquery)] + [require(spirv, rayquery)] + [require(hlsl, rayquery)] [__NoSideEffect] [NonUniformReturn] float CandidateTriangleRayT() @@ -10628,7 +10756,9 @@ struct RayQuery <let rayFlagsGeneric : RAY_FLAG = RAY_FLAG_NONE> } } __glsl_extension(GL_EXT_ray_query) - __glsl_version(460) + [require(glsl, rayquery)] + [require(spirv, rayquery)] + [require(hlsl, rayquery)] [__NoSideEffect] [NonUniformReturn] float CommittedRayT() @@ -10646,6 +10776,404 @@ struct RayQuery <let rayFlagsGeneric : RAY_FLAG = RAY_FLAG_NONE> } } +///missing hlsl equivlent; only implemented for glsl & spirv + __glsl_extension(GL_EXT_ray_query) + [require(glsl, rayquery)] + [require(spirv, rayquery)] + [__NoSideEffect] + int CandidateRayInstanceCustomIndex() + { + __target_switch + { + case glsl: __intrinsic_asm "rayQueryGetIntersectionInstanceCustomIndexEXT($0, false)"; + case spirv: + uint iCandidateOrCommitted = 0; + return spirv_asm + { + result:$$int = OpRayQueryGetIntersectionInstanceCustomIndexKHR &this $iCandidateOrCommitted; + }; + } + } + + __glsl_extension(GL_EXT_ray_query) + [require(glsl, rayquery)] + [require(spirv, rayquery)] + [__NoSideEffect] + int CommittedRayInstanceCustomIndex() + { + __target_switch + { + case glsl: __intrinsic_asm "rayQueryGetIntersectionInstanceCustomIndexEXT($0, true)"; + case spirv: + uint iCandidateOrCommitted = 1; + return spirv_asm + { + result:$$int = OpRayQueryGetIntersectionInstanceCustomIndexKHR &this $iCandidateOrCommitted; + }; + } + } + + __glsl_extension(GL_EXT_ray_query) + [require(glsl, rayquery)] + [require(spirv, rayquery)] + [__NoSideEffect] + int CandidateRayInstanceId() + { + __target_switch + { + case glsl: __intrinsic_asm "rayQueryGetIntersectionInstanceIdEXT($0, false)"; + case spirv: + uint iCandidateOrCommitted = 0; + return spirv_asm + { + result:$$int = OpRayQueryGetIntersectionInstanceIdKHR &this $iCandidateOrCommitted; + }; + } + } + + __glsl_extension(GL_EXT_ray_query) + [require(glsl, rayquery)] + [require(spirv, rayquery)] + [__NoSideEffect] + int CommittedRayInstanceId() + { + __target_switch + { + case glsl: __intrinsic_asm "rayQueryGetIntersectionInstanceIdEXT($0, true)"; + case spirv: + uint iCandidateOrCommitted = 1; + return spirv_asm + { + result:$$int = OpRayQueryGetIntersectionInstanceIdKHR &this $iCandidateOrCommitted; + }; + } + } + + __glsl_extension(GL_EXT_ray_query) + [require(glsl, rayquery)] + [require(spirv, rayquery)] + [__NoSideEffect] + uint CandidateRayInstanceShaderBindingTableRecordOffset() + { + __target_switch + { + case glsl: __intrinsic_asm "rayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetEXT($0, false)"; + case spirv: + uint iCandidateOrCommitted = 0; + return spirv_asm + { + result:$$uint = OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR &this $iCandidateOrCommitted; + }; + } + } + + __glsl_extension(GL_EXT_ray_query) + [require(glsl, rayquery)] + [require(spirv, rayquery)] + [__NoSideEffect] + uint CommittedRayInstanceShaderBindingTableRecordOffset() + { + __target_switch + { + case glsl: __intrinsic_asm "rayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetEXT($0, true)"; + case spirv: + uint iCandidateOrCommitted = 1; + return spirv_asm + { + result:$$uint = OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR &this $iCandidateOrCommitted; + }; + } + } + + __glsl_extension(GL_EXT_ray_query) + [require(glsl, rayquery)] + [require(spirv, rayquery)] + [__NoSideEffect] + int CandidateRayGeometryIndex() + { + __target_switch + { + case glsl: __intrinsic_asm "rayQueryGetIntersectionGeometryIndexEXT($0, false)"; + case spirv: + uint iCandidateOrCommitted = 0; + return spirv_asm + { + result:$$int = OpRayQueryGetIntersectionGeometryIndexKHR &this $iCandidateOrCommitted; + }; + } + } + + __glsl_extension(GL_EXT_ray_query) + [require(glsl, rayquery)] + [require(spirv, rayquery)] + [__NoSideEffect] + int CommittedRayGeometryIndex() + { + __target_switch + { + case glsl: __intrinsic_asm "rayQueryGetIntersectionGeometryIndexEXT($0, true)"; + case spirv: + uint iCandidateOrCommitted = 1; + return spirv_asm + { + result:$$int = OpRayQueryGetIntersectionGeometryIndexKHR &this $iCandidateOrCommitted; + }; + } + } + + __glsl_extension(GL_EXT_ray_query) + [require(glsl, rayquery)] + [require(spirv, rayquery)] + [__NoSideEffect] + int CandidateRayPrimitiveIndex() + { + __target_switch + { + case glsl: __intrinsic_asm "rayQueryGetIntersectionPrimitiveIndexEXT($0, false)"; + case spirv: + uint iCandidateOrCommitted = 0; + return spirv_asm + { + result:$$int = OpRayQueryGetIntersectionPrimitiveIndexKHR &this $iCandidateOrCommitted; + }; + } + } + + __glsl_extension(GL_EXT_ray_query) + [require(glsl, rayquery)] + [require(spirv, rayquery)] + [__NoSideEffect] + int CommittedRayPrimitiveIndex() + { + __target_switch + { + case glsl: __intrinsic_asm "rayQueryGetIntersectionPrimitiveIndexEXT($0, true)"; + case spirv: + uint iCandidateOrCommitted = 1; + return spirv_asm + { + result:$$int = OpRayQueryGetIntersectionPrimitiveIndexKHR &this $iCandidateOrCommitted; + }; + } + } + + __glsl_extension(GL_EXT_ray_query) + [require(glsl, rayquery)] + [require(spirv, rayquery)] + [__NoSideEffect] + float2 CandidateRayBarycentrics() + { + __target_switch + { + case glsl: __intrinsic_asm "rayQueryGetIntersectionBarycentricsEXT($0, false)"; + case spirv: + uint iCandidateOrCommitted = 0; + return spirv_asm + { + result:$$float2 = OpRayQueryGetIntersectionBarycentricsKHR &this $iCandidateOrCommitted; + }; + } + } + + __glsl_extension(GL_EXT_ray_query) + [require(glsl, rayquery)] + [require(spirv, rayquery)] + [__NoSideEffect] + float2 CommittedRayBarycentrics() + { + __target_switch + { + case glsl: __intrinsic_asm "rayQueryGetIntersectionBarycentricsEXT($0, true)"; + case spirv: + uint iCandidateOrCommitted = 1; + return spirv_asm + { + result:$$float2 = OpRayQueryGetIntersectionBarycentricsKHR &this $iCandidateOrCommitted; + }; + } + } + + __glsl_extension(GL_EXT_ray_query) + [require(glsl, rayquery)] + [require(spirv, rayquery)] + [__NoSideEffect] + bool CandidateRayFrontFace() + { + __target_switch + { + case glsl: __intrinsic_asm "rayQueryGetIntersectionFrontFaceEXT($0, false)"; + case spirv: + uint iCandidateOrCommitted = 0; + return spirv_asm + { + result:$$bool = OpRayQueryGetIntersectionFrontFaceKHR &this $iCandidateOrCommitted; + }; + } + } + + __glsl_extension(GL_EXT_ray_query) + [require(glsl, rayquery)] + [require(spirv, rayquery)] + [__NoSideEffect] + bool CommittedRayFrontFace() + { + __target_switch + { + case glsl: __intrinsic_asm "rayQueryGetIntersectionFrontFaceEXT($0, true)"; + case spirv: + uint iCandidateOrCommitted = 1; + return spirv_asm + { + result:$$bool = OpRayQueryGetIntersectionFrontFaceKHR &this $iCandidateOrCommitted; + }; + } + } + + __glsl_extension(GL_EXT_ray_query) + [require(glsl, rayquery)] + [require(spirv, rayquery)] + [__NoSideEffect] + float3 CandidateRayObjectRayDirection() + { + __target_switch + { + case glsl: __intrinsic_asm "rayQueryGetIntersectionObjectRayDirectionEXT($0, false)"; + case spirv: + uint iCandidateOrCommitted = 0; + return spirv_asm + { + result:$$float3 = OpRayQueryGetIntersectionObjectRayDirectionKHR &this $iCandidateOrCommitted; + }; + } + } + + __glsl_extension(GL_EXT_ray_query) + [require(glsl, rayquery)] + [require(spirv, rayquery)] + [__NoSideEffect] + float3 CommittedRayObjectRayDirection() + { + __target_switch + { + case glsl: __intrinsic_asm "rayQueryGetIntersectionObjectRayDirectionEXT($0, true)"; + case spirv: + uint iCandidateOrCommitted = 1; + return spirv_asm + { + result:$$float3 = OpRayQueryGetIntersectionObjectRayDirectionKHR &this $iCandidateOrCommitted; + }; + } + } + + __glsl_extension(GL_EXT_ray_query) + [require(glsl, rayquery)] + [require(spirv, rayquery)] + [__NoSideEffect] + float3 CandidateRayObjectRayOrigin() + { + __target_switch + { + case glsl: __intrinsic_asm "rayQueryGetIntersectionObjectRayOriginEXT($0, false)"; + case spirv: + uint iCandidateOrCommitted = 0; + return spirv_asm + { + result:$$float3 = OpRayQueryGetIntersectionObjectRayOriginKHR &this $iCandidateOrCommitted; + }; + } + } + + __glsl_extension(GL_EXT_ray_query) + [require(glsl, rayquery)] + [require(spirv, rayquery)] + [__NoSideEffect] + float3 CommittedRayObjectRayOrigin() + { + __target_switch + { + case glsl: __intrinsic_asm "rayQueryGetIntersectionObjectRayOriginEXT($0, true)"; + case spirv: + uint iCandidateOrCommitted = 1; + return spirv_asm + { + result:$$float3 = OpRayQueryGetIntersectionObjectRayOriginKHR &this $iCandidateOrCommitted; + }; + } + } + + __glsl_extension(GL_EXT_ray_query) + [require(glsl, rayquery)] + [require(spirv, rayquery)] + [__NoSideEffect] + float4x3 CandidateRayObjectToWorld() + { + __target_switch + { + case glsl: __intrinsic_asm "rayQueryGetIntersectionObjectToWorldEXT($0, false)"; + case spirv: + uint iCandidateOrCommitted = 0; + return spirv_asm + { + result:$$float4x3 = OpRayQueryGetIntersectionObjectToWorldKHR &this $iCandidateOrCommitted; + }; + } + } + + __glsl_extension(GL_EXT_ray_query) + [require(glsl, rayquery)] + [require(spirv, rayquery)] + [__NoSideEffect] + float4x3 CommittedRayObjectToWorld() + { + __target_switch + { + case glsl: __intrinsic_asm "rayQueryGetIntersectionObjectToWorldEXT($0, true)"; + case spirv: + uint iCandidateOrCommitted = 1; + return spirv_asm + { + result:$$float4x3 = OpRayQueryGetIntersectionObjectToWorldKHR &this $iCandidateOrCommitted; + }; + } + } + + __glsl_extension(GL_EXT_ray_query) + [require(glsl, rayquery)] + [require(spirv, rayquery)] + [__NoSideEffect] + float4x3 CandidateRayWorldToObject() + { + __target_switch + { + case glsl: __intrinsic_asm "rayQueryGetIntersectionWorldToObjectEXT($0, false)"; + case spirv: + uint iCandidateOrCommitted = 0; + return spirv_asm + { + result:$$float4x3 = OpRayQueryGetIntersectionWorldToObjectKHR &this $iCandidateOrCommitted; + }; + } + } + + __glsl_extension(GL_EXT_ray_query) + [require(glsl, rayquery)] + [require(spirv, rayquery)] + [__NoSideEffect] + float4x3 CommittedRayWorldToObject() + { + __target_switch + { + case glsl: __intrinsic_asm "rayQueryGetIntersectionWorldToObjectEXT($0, true)"; + case spirv: + uint iCandidateOrCommitted = 1; + return spirv_asm + { + OpRayQueryGetIntersectionWorldToObjectKHR $$float4x3 result &this $iCandidateOrCommitted; + }; + } + } +///~ + ${{{{ const char* kCandidateCommitted[] = {"Candidate", "Committed"}; @@ -10658,7 +11186,7 @@ ${{{{ __glsl_extension(GL_EXT_ray_query) __glsl_extension(GL_EXT_ray_tracing_position_fetch) - __glsl_version(460) + [require(glsl, rayquery_pos)] [__NoSideEffect] void __glslGetIntersectionTriangleVertexPositions$(ccName)(out float3 arr[3]) { @@ -10666,8 +11194,8 @@ ${{{{ }; __glsl_extension(GL_EXT_ray_query) - __glsl_extension(GL_EXT_ray_tracing_position_fetch) - __glsl_version(460) + [require(glsl, rayquery_pos)] + [require(spirv, rayquery_pos)] [__NoSideEffect] float3[3] $(ccName)GetIntersectionTriangleVertexPositions() { @@ -10700,7 +11228,9 @@ ${{{{ }}}} __glsl_extension(GL_EXT_ray_query) - __glsl_version(460) + [require(glsl, rayquery)] + [require(spirv, rayquery)] + [require(hlsl, rayquery)] [__NoSideEffect] [NonUniformReturn] float3x4 $(ccName)$(matName)3x4() @@ -10711,7 +11241,8 @@ ${{{{ case hlsl: __intrinsic_asm ".$(ccName)$(matName)3x4"; case spirv: uint iCandidateOrCommitted = $(candidateOrCommitted); - return spirv_asm { + return spirv_asm + { %m:$$float4x3 = OpRayQueryGetIntersection$(matName)KHR &this $iCandidateOrCommitted; result:$$float3x4 = OpTranspose %m; }; @@ -10719,7 +11250,9 @@ ${{{{ } __glsl_extension(GL_EXT_ray_query) - __glsl_version(460) + [require(glsl, rayquery)] + [require(spirv, rayquery)] + [require(hlsl, rayquery)] [__readNone] [NonUniformReturn] float4x3 $(ccName)$(matName)4x3() @@ -10730,7 +11263,8 @@ ${{{{ case hlsl: __intrinsic_asm ".$(ccName)$(matName)4x3"; case spirv: uint iCandidateOrCommitted = $(candidateOrCommitted); - return spirv_asm { + return spirv_asm + { result:$$float4x3 = OpRayQueryGetIntersection$(matName)KHR &this $iCandidateOrCommitted; }; } @@ -10761,7 +11295,9 @@ ${{{{ }}}} __glsl_extension(GL_EXT_ray_query) - __glsl_version(460) + [require(glsl, rayquery)] + [require(spirv, rayquery)] + [require(hlsl, rayquery)] [__NoSideEffect] [NonUniformReturn] $(method.type) $(ccName)$(method.hlslName)() @@ -10772,7 +11308,8 @@ ${{{{ case glsl: __intrinsic_asm "rayQueryGetIntersection$(method.glslName)EXT($0, $(ccTF))"; case spirv: uint iCandidateOrCommitted = $(candidateOrCommitted); - return spirv_asm { + return spirv_asm + { result:$$$(method.type) = OpRayQueryGetIntersection$(method.glslName)KHR &this $iCandidateOrCommitted; }; } @@ -10785,7 +11322,9 @@ ${{{{ // Access properties of the ray being traced. __glsl_extension(GL_EXT_ray_query) - __glsl_version(460) + [require(glsl, rayquery)] + [require(spirv, rayquery)] + [require(hlsl, rayquery)] [__NoSideEffect] [NonUniformReturn] uint RayFlags() @@ -10795,14 +11334,17 @@ ${{{{ case hlsl: __intrinsic_asm ".RayFlags"; case glsl: __intrinsic_asm "rayQueryGetRayFlagsEXT"; case spirv: - return spirv_asm { + return spirv_asm + { result:$$uint = OpRayQueryGetRayFlagsKHR &this; }; } } __glsl_extension(GL_EXT_ray_query) - __glsl_version(460) + [require(glsl, rayquery)] + [require(spirv, rayquery)] + [require(hlsl, rayquery)] [__NoSideEffect] [NonUniformReturn] float3 WorldRayOrigin() @@ -10812,14 +11354,17 @@ ${{{{ case hlsl: __intrinsic_asm ".WorldRayOrigin"; case glsl: __intrinsic_asm "rayQueryGetWorldRayOriginEXT"; case spirv: - return spirv_asm { + return spirv_asm + { result:$$float3 = OpRayQueryGetWorldRayOriginKHR &this; }; } } __glsl_extension(GL_EXT_ray_query) - __glsl_version(460) + [require(glsl, rayquery)] + [require(spirv, rayquery)] + [require(hlsl, rayquery)] [__NoSideEffect] [NonUniformReturn] float3 WorldRayDirection() @@ -10829,14 +11374,17 @@ ${{{{ case hlsl: __intrinsic_asm ".WorldRayDirection"; case glsl: __intrinsic_asm "rayQueryGetWorldRayDirectionEXT"; case spirv: - return spirv_asm { + return spirv_asm + { result:$$float3 = OpRayQueryGetWorldRayDirectionKHR &this; }; } } __glsl_extension(GL_EXT_ray_query) - __glsl_version(460) + [require(glsl, rayquery)] + [require(spirv, rayquery)] + [require(hlsl, rayquery)] [__NoSideEffect] [NonUniformReturn] float RayTMin() @@ -10846,7 +11394,8 @@ ${{{{ case hlsl: __intrinsic_asm ".RayTMin"; case glsl: __intrinsic_asm "rayQueryGetRayTMinEXT"; case spirv: - return spirv_asm { + return spirv_asm + { result:$$float = OpRayQueryGetRayTMinKHR &this; }; } @@ -10921,7 +11470,6 @@ int __hitObjectAttributesLocation(__ref Attributes attributes); /// Immutable data type representing a ray hit or a miss. Can be used to invoke hit or miss shading, /// or as a key in ReorderThread. Created by one of several methods described below. HitObject /// and its related functions are available in raytracing shader types only. -[__requiresNVAPI] __glsl_extension(GL_NV_shader_invocation_reorder) __glsl_extension(GL_EXT_ray_tracing) [__NonCopyableType] @@ -10933,6 +11481,9 @@ struct HitObject /// Executes ray traversal (including anyhit and intersection shaders) like TraceRay, but returns the /// resulting hit information as a HitObject and does not trigger closesthit or miss shaders. + [require(glsl, ser)] + [require(spirv, ser)] + [require(hlsl, ser)] [ForceInline] static HitObject TraceRay<payload_t>( RaytracingAccelerationStructure AccelerationStructure, @@ -10998,7 +11549,9 @@ struct HitObject let direction = Ray.Direction; let tmin = Ray.TMin; let tmax = Ray.TMax; - spirv_asm { + spirv_asm + { + OpExtension "SPV_NV_shader_invocation_reorder"; OpCapability ShaderInvocationReorderNV; OpHitObjectTraceRayNV /**/ &__return_val @@ -11024,6 +11577,9 @@ struct HitObject /// Executes motion ray traversal (including anyhit and intersection shaders) like TraceRay, but returns the /// resulting hit information as a HitObject and does not trigger closesthit or miss shaders. [ForceInline] + [require(glsl, ser_motion)] + [require(spirv, ser_motion)] + [require(hlsl, ser_motion)] static HitObject TraceMotionRay<payload_t>( RaytracingAccelerationStructure AccelerationStructure, uint RayFlags, @@ -11077,9 +11633,12 @@ struct HitObject let direction = Ray.Direction; let tmin = Ray.TMin; let tmax = Ray.TMax; - spirv_asm { - OpCapability RayTracingMotionBlurNV; + spirv_asm + { + OpExtension "SPV_NV_shader_invocation_reorder"; + OpCapability ShaderInvocationReorderNV; OpExtension "SPV_NV_ray_tracing_motion_blur"; + OpCapability RayTracingMotionBlurNV; OpHitObjectTraceRayMotionNV /**/ &__return_val /**/ $AccelerationStructure @@ -11109,6 +11668,9 @@ struct HitObject /// TraceRay. The computed index must reference a valid hit group record in the shader table. The /// Attributes parameter must either be an attribute struct, such as /// BuiltInTriangleIntersectionAttributes, or another HitObject to copy the attributes from. + [require(glsl, ser)] + [require(spirv, ser)] + [require(hlsl, ser)] [ForceInline] static HitObject MakeHit<attr_t>( RaytracingAccelerationStructure AccelerationStructure, @@ -11168,7 +11730,10 @@ struct HitObject let direction = Ray.Direction; let tmin = Ray.TMin; let tmax = Ray.TMax; - spirv_asm { + spirv_asm + { + OpExtension "SPV_NV_shader_invocation_reorder"; + OpCapability ShaderInvocationReorderNV; OpHitObjectRecordHitNV /**/ &__return_val /**/ $AccelerationStructure @@ -11190,6 +11755,9 @@ struct HitObject /// See MakeHit but handles Motion /// Currently only supported on VK + [require(glsl, ser_motion)] + [require(spirv, ser_motion)] + [require(hlsl, ser_motion)] [ForceInline] static HitObject MakeMotionHit<attr_t>( RaytracingAccelerationStructure AccelerationStructure, @@ -11238,9 +11806,12 @@ struct HitObject let direction = Ray.Direction; let tmin = Ray.TMin; let tmax = Ray.TMax; - spirv_asm { - OpCapability RayTracingMotionBlurNV; + spirv_asm + { OpExtension "SPV_NV_ray_tracing_motion_blur"; + OpCapability RayTracingMotionBlurNV; + OpExtension "SPV_NV_shader_invocation_reorder"; + OpCapability ShaderInvocationReorderNV; OpHitObjectRecordHitMotionNV /**/ &__return_val /**/ $AccelerationStructure @@ -11268,6 +11839,9 @@ struct HitObject /// reference a valid hit group record in the shader table. The Attributes parameter must either be an /// attribute struct, such as BuiltInTriangleIntersectionAttributes, or another HitObject to copy the /// attributes from. + [require(glsl, ser)] + [require(spirv, ser)] + [require(hlsl, ser)] [ForceInline] static HitObject MakeHit<attr_t>( uint HitGroupRecordIndex, @@ -11301,10 +11875,10 @@ struct HitObject __glslMakeHitWithIndex( __return_val, - AccelerationStructure, + AccelerationStructure, InstanceIndex, ///? Same as instanceid ? - GeometryIndex, PrimitiveIndex, + GeometryIndex, HitKind, /// Assuming HitKinds are compatible HitGroupRecordIndex, /// sbtRecordIndex Ray.Origin, @@ -11322,7 +11896,10 @@ struct HitObject let direction = Ray.Direction; let tmin = Ray.TMin; let tmax = Ray.TMax; - spirv_asm { + spirv_asm + { + OpExtension "SPV_NV_shader_invocation_reorder"; + OpCapability ShaderInvocationReorderNV; OpHitObjectRecordHitWithIndexNV /**/ &__return_val /**/ $AccelerationStructure @@ -11342,7 +11919,8 @@ struct HitObject } /// See MakeHit but handles Motion /// Currently only supported on VK - + [require(glsl, ser_motion)] + [require(spirv, ser_motion)] [ForceInline] static HitObject MakeMotionHit<attr_t>( uint HitGroupRecordIndex, @@ -11364,10 +11942,10 @@ struct HitObject __glslMakeMotionHitWithIndex( __return_val, - AccelerationStructure, + AccelerationStructure, InstanceIndex, ///? Same as instanceid ? - GeometryIndex, - PrimitiveIndex, + PrimitiveIndex, + GeometryIndex, HitKind, /// Assuming HitKinds are compatible HitGroupRecordIndex, /// sbtRecordIndex Ray.Origin, @@ -11386,9 +11964,10 @@ struct HitObject let direction = Ray.Direction; let tmin = Ray.TMin; let tmax = Ray.TMax; - spirv_asm { - OpCapability RayTracingMotionBlurNV; + spirv_asm + { OpExtension "SPV_NV_ray_tracing_motion_blur"; + OpCapability RayTracingMotionBlurNV; OpHitObjectRecordHitWithIndexMotionNV /**/ &__return_val /**/ $AccelerationStructure @@ -11412,6 +11991,9 @@ struct HitObject /// tracing a ray. The provided shader table index must reference a valid miss record in the shader /// table. [__requiresNVAPI] + [require(glsl, ser)] + [require(spirv, ser)] + [require(hlsl, ser)] [ForceInline] static HitObject MakeMiss( uint MissShaderIndex, @@ -11428,7 +12010,10 @@ struct HitObject let direction = Ray.Direction; let tmin = Ray.TMin; let tmax = Ray.TMax; - spirv_asm { + spirv_asm + { + OpExtension "SPV_NV_shader_invocation_reorder"; + OpCapability ShaderInvocationReorderNV; OpHitObjectRecordMissNV /**/ &__return_val /**/ $MissShaderIndex @@ -11443,8 +12028,10 @@ struct HitObject /// See MakeMiss but handles Motion /// Currently only supported on VK + [require(glsl, ser_motion)] + [require(spirv, ser_motion)] + [require(hlsl, ser_motion)] [ForceInline] - __specialized_for_target(glsl) static HitObject MakeMotionMiss( uint MissShaderIndex, RayDesc Ray, @@ -11461,9 +12048,12 @@ struct HitObject let direction = Ray.Direction; let tmin = Ray.TMin; let tmax = Ray.TMax; - spirv_asm { - OpCapability RayTracingMotionBlurNV; + spirv_asm + { OpExtension "SPV_NV_ray_tracing_motion_blur"; + OpCapability RayTracingMotionBlurNV; + OpExtension "SPV_NV_shader_invocation_reorder"; + OpCapability ShaderInvocationReorderNV; OpHitObjectRecordMissMotionNV /**/ &__return_val /**/ $MissShaderIndex @@ -11483,6 +12073,9 @@ struct HitObject /// scenarios where future control flow for some threads is known to process neither a hit nor a /// miss. [__requiresNVAPI] + [require(glsl, ser)] + [require(spirv, ser)] + [require(hlsl, ser)] [ForceInline] static HitObject MakeNop() { @@ -11493,7 +12086,10 @@ struct HitObject case glsl: __glslMakeNop(__return_val); case spirv: - spirv_asm { + spirv_asm + { + OpExtension "SPV_NV_shader_invocation_reorder"; + OpCapability ShaderInvocationReorderNV; OpHitObjectRecordEmptyNV /**/ &__return_val; }; @@ -11503,6 +12099,9 @@ struct HitObject /// Invokes closesthit or miss shading for the specified hit object. In case of a NOP HitObject, no /// shader is invoked. [__requiresNVAPI] + [require(glsl, ser)] + [require(spirv, ser)] + [require(hlsl, ser)] [ForceInline] static void Invoke<payload_t>( RaytracingAccelerationStructure AccelerationStructure, @@ -11533,7 +12132,10 @@ struct HitObject // Save the payload p = Payload; - spirv_asm { + spirv_asm + { + OpExtension "SPV_NV_shader_invocation_reorder"; + OpCapability ShaderInvocationReorderNV; OpHitObjectExecuteShaderNV /**/ &HitOrMiss /**/ &p; @@ -11547,15 +12149,21 @@ struct HitObject /// Returns true if the HitObject encodes a miss, otherwise returns false. [__requiresNVAPI] + [require(glsl, ser)] + [require(spirv, ser)] + [require(hlsl, ser)] [ForceInline] - __glsl_extension(GL_EXT_ray_tracing) bool IsMiss() { __target_switch { case hlsl: __intrinsic_asm ".IsMiss"; case glsl: __intrinsic_asm "hitObjectIsMissNV($0)"; - case spirv: return spirv_asm { + case spirv: + return spirv_asm + { + OpExtension "SPV_NV_shader_invocation_reorder"; + OpCapability ShaderInvocationReorderNV; result:$$bool = OpHitObjectIsMissNV &this; }; } @@ -11563,15 +12171,21 @@ struct HitObject /// Returns true if the HitObject encodes a hit, otherwise returns false. [__requiresNVAPI] + [require(glsl, ser)] + [require(spirv, ser)] + [require(hlsl, ser)] [ForceInline] - __glsl_extension(GL_EXT_ray_tracing) bool IsHit() { __target_switch { case hlsl: __intrinsic_asm ".IsHit"; case glsl: __intrinsic_asm "hitObjectIsHitNV($0)"; - case spirv: return spirv_asm { + case spirv: + return spirv_asm + { + OpExtension "SPV_NV_shader_invocation_reorder"; + OpCapability ShaderInvocationReorderNV; result:$$bool = OpHitObjectIsHitNV &this; }; } @@ -11579,15 +12193,21 @@ struct HitObject /// Returns true if the HitObject encodes a nop, otherwise returns false. [__requiresNVAPI] + [require(glsl, ser)] + [require(spirv, ser)] + [require(hlsl, ser)] [ForceInline] - __glsl_extension(GL_EXT_ray_tracing) bool IsNop() { __target_switch { case hlsl: __intrinsic_asm ".IsNop"; case glsl: __intrinsic_asm "hitObjectIsEmptyNV($0)"; - case spirv: return spirv_asm { + case spirv: + return spirv_asm + { + OpExtension "SPV_NV_shader_invocation_reorder"; + OpCapability ShaderInvocationReorderNV; result:$$bool = OpHitObjectIsEmptyNV &this; }; } @@ -11595,8 +12215,10 @@ struct HitObject /// Queries ray properties from HitObject. Valid if the hit object represents a hit or a miss. [__requiresNVAPI] + [require(glsl, ser)] + [require(spirv, ser)] + [require(hlsl, ser)] [ForceInline] - __target_intrinsic(hlsl) RayDesc GetRayDesc() { __target_switch @@ -11609,7 +12231,10 @@ struct HitObject return ray; } case spirv: - return spirv_asm { + return spirv_asm + { + OpExtension "SPV_NV_shader_invocation_reorder"; + OpCapability ShaderInvocationReorderNV; %origin:$$float3 = OpHitObjectGetWorldRayOriginNV &this; %tmin:$$float = OpHitObjectGetRayTMinNV &this; %direction:$$float3 = OpHitObjectGetWorldRayDirectionNV &this; @@ -11621,15 +12246,22 @@ struct HitObject /// Queries shader table index from HitObject. Valid if the hit object represents a hit or a miss. [__requiresNVAPI] - [ForceInline] __glsl_extension(GL_EXT_ray_tracing) + [require(glsl, ser)] + [require(spirv, ser)] + [require(hlsl, ser)] + [ForceInline] uint GetShaderTableIndex() { __target_switch { case hlsl: __intrinsic_asm ".GetShaderTableIndex"; case glsl: __intrinsic_asm "hitObjectGetShaderBindingTableRecordIndexNV($0)"; - case spirv: return spirv_asm { + case spirv: + return spirv_asm + { + OpExtension "SPV_NV_shader_invocation_reorder"; + OpCapability ShaderInvocationReorderNV; result:$$uint = OpHitObjectGetShaderBindingTableRecordIndexNV &this; }; } @@ -11637,15 +12269,22 @@ struct HitObject /// Returns the instance index of a hit. Valid if the hit object represents a hit. [__requiresNVAPI] - [ForceInline] __glsl_extension(GL_EXT_ray_tracing) + [require(glsl, ser)] + [require(spirv, ser)] + [require(hlsl, ser)] + [ForceInline] uint GetInstanceIndex() { __target_switch { case hlsl: __intrinsic_asm ".GetInstanceIndex"; case glsl: __intrinsic_asm "hitObjectGetInstanceIdNV($0)"; - case spirv: return spirv_asm { + case spirv: + return spirv_asm + { + OpExtension "SPV_NV_shader_invocation_reorder"; + OpCapability ShaderInvocationReorderNV; result:$$uint = OpHitObjectGetInstanceIdNV &this; }; } @@ -11653,15 +12292,22 @@ struct HitObject /// Returns the instance ID of a hit. Valid if the hit object represents a hit. [__requiresNVAPI] - [ForceInline] __glsl_extension(GL_EXT_ray_tracing) + [require(glsl, ser)] + [require(spirv, ser)] + [require(hlsl, ser)] + [ForceInline] uint GetInstanceID() { __target_switch { case hlsl: __intrinsic_asm ".GetInstanceID"; case glsl: __intrinsic_asm "hitObjectGetInstanceCustomIndexNV($0)"; - case spirv: return spirv_asm { + case spirv: + return spirv_asm + { + OpExtension "SPV_NV_shader_invocation_reorder"; + OpCapability ShaderInvocationReorderNV; result:$$uint = OpHitObjectGetInstanceCustomIndexNV &this; }; } @@ -11669,15 +12315,22 @@ struct HitObject /// Returns the geometry index of a hit. Valid if the hit object represents a hit. [__requiresNVAPI] - [ForceInline] __glsl_extension(GL_EXT_ray_tracing) + [require(glsl, ser)] + [require(spirv, ser)] + [require(hlsl, ser)] + [ForceInline] uint GetGeometryIndex() { __target_switch { case hlsl: __intrinsic_asm ".GetGeometryIndex"; case glsl: __intrinsic_asm "hitObjectGetGeometryIndexNV($0)"; - case spirv: return spirv_asm { + case spirv: + return spirv_asm + { + OpExtension "SPV_NV_shader_invocation_reorder"; + OpCapability ShaderInvocationReorderNV; result:$$uint = OpHitObjectGetGeometryIndexNV &this; }; } @@ -11685,15 +12338,22 @@ struct HitObject /// Returns the primitive index of a hit. Valid if the hit object represents a hit. [__requiresNVAPI] - [ForceInline] __glsl_extension(GL_EXT_ray_tracing) + [require(glsl, ser)] + [require(spirv, ser)] + [require(hlsl, ser)] + [ForceInline] uint GetPrimitiveIndex() { __target_switch { case hlsl: __intrinsic_asm ".GetPrimitiveIndex"; case glsl: __intrinsic_asm "hitObjectGetPrimitiveIndexNV($0)"; - case spirv: return spirv_asm { + case spirv: + return spirv_asm + { + OpExtension "SPV_NV_shader_invocation_reorder"; + OpCapability ShaderInvocationReorderNV; result:$$uint = OpHitObjectGetPrimitiveIndexNV &this; }; } @@ -11701,51 +12361,147 @@ struct HitObject /// Returns the hit kind. Valid if the hit object represents a hit. [__requiresNVAPI] - [ForceInline] __glsl_extension(GL_EXT_ray_tracing) + [require(glsl, ser)] + [require(spirv, ser)] + [require(hlsl, ser)] + [ForceInline] uint GetHitKind() { __target_switch { case hlsl: __intrinsic_asm ".GetHitKind"; case glsl: __intrinsic_asm "hitObjectGetHitKindNV($0)"; - case spirv: return spirv_asm { + case spirv: + return spirv_asm + { + OpExtension "SPV_NV_shader_invocation_reorder"; + OpCapability ShaderInvocationReorderNV; result:$$uint = OpHitObjectGetHitKindNV &this; }; } } [__requiresNVAPI] - [ForceInline] __glsl_extension(GL_EXT_ray_tracing) + [require(glsl, ser)] + [require(spirv, ser)] + [require(hlsl, ser)] + [ForceInline] float4x3 GetWorldToObject() { __target_switch { case hlsl: __intrinsic_asm ".GetWorldToObject"; case glsl: __intrinsic_asm "hitObjectGetWorldToObjectNV($0)"; - case spirv: return spirv_asm { + case spirv: + return spirv_asm + { + OpExtension "SPV_NV_shader_invocation_reorder"; + OpCapability ShaderInvocationReorderNV; result:$$float4x3 = OpHitObjectGetWorldToObjectNV &this; }; } } [__requiresNVAPI] - [ForceInline] __glsl_extension(GL_EXT_ray_tracing) + [require(glsl, ser)] + [require(spirv, ser)] + [require(hlsl, ser)] + [ForceInline] float4x3 GetObjectToWorld() { __target_switch { case hlsl: __intrinsic_asm ".GetObjectToWorld"; case glsl: __intrinsic_asm "hitObjectGetObjectToWorldNV($0)"; - case spirv: return spirv_asm { + case spirv: + return spirv_asm + { + OpExtension "SPV_NV_shader_invocation_reorder"; + OpCapability ShaderInvocationReorderNV; result:$$float4x3 = OpHitObjectGetObjectToWorldNV &this; }; } } + [require(glsl, ser)] + [require(spirv, ser)] + [ForceInline] + float GetCurrentTime() { + __target_switch + { + case glsl: + __intrinsic_asm "hitObjectGetCurrentTimeNV($0)"; + case spirv: + return spirv_asm + { + OpExtension "SPV_NV_shader_invocation_reorder"; + OpCapability ShaderInvocationReorderNV; + result:$$float = OpHitObjectGetCurrentTimeNV &this + }; + } + } + + [require(glsl, ser)] + [require(spirv, ser)] + [ForceInline] + float3 GetObjectRayOrigin() { + __target_switch + { + case glsl: + __intrinsic_asm "hitObjectGetObjectRayOriginNV($0)"; + case spirv: + return spirv_asm + { + OpExtension "SPV_NV_shader_invocation_reorder"; + OpCapability ShaderInvocationReorderNV; + result:$$float3 = OpHitObjectGetObjectRayOriginNV &this + }; + } + } + + [require(glsl, ser)] + [require(spirv, ser)] + [ForceInline] + float3 GetObjectRayDirection() { + __target_switch + { + case glsl: + __intrinsic_asm "hitObjectGetObjectRayDirectionNV($0)"; + case spirv: + return spirv_asm + { + OpExtension "SPV_NV_shader_invocation_reorder"; + OpCapability ShaderInvocationReorderNV; + result:$$float3 = OpHitObjectGetObjectRayDirectionNV &this + }; + } + } + + [require(glsl, ser)] + [require(spirv, ser)] + [ForceInline] + uint2 GetShaderRecordBufferHandle() { + __target_switch + { + case glsl: + __intrinsic_asm "hitObjectGetShaderRecordBufferHandleNV($0)"; + case spirv: + return spirv_asm + { + OpExtension "SPV_NV_shader_invocation_reorder"; + OpCapability ShaderInvocationReorderNV; + result:$$uint2 = OpHitObjectGetShaderRecordBufferHandleNV &this + }; + } + } + /// Returns the attributes of a hit. Valid if the hit object represents a hit or a miss. + [require(glsl, ser)] + [require(spirv, ser)] + [require(hlsl, ser)] [ForceInline] attr_t GetAttributes<attr_t>() { @@ -11771,7 +12527,10 @@ struct HitObject case spirv: { Ptr<attr_t> attr = __allocHitObjectAttributes<attr_t>(); - spirv_asm { + spirv_asm + { + OpExtension "SPV_NV_shader_invocation_reorder"; + OpCapability ShaderInvocationReorderNV; OpHitObjectGetAttributesNV &this $attr; }; return *attr; @@ -11782,6 +12541,7 @@ struct HitObject /// represents a hit or a miss. RootConstantOffsetInBytes must be a multiple of 4. __target_intrinsic(hlsl) [__requiresNVAPI] + [require(hlsl, ser)] uint LoadLocalRootTableConstant(uint RootConstantOffsetInBytes); /// @@ -11790,10 +12550,12 @@ struct HitObject __target_intrinsic(hlsl, "NvGetAttributesFromHitObject($0, $1)") [__requiresNVAPI] + [require(hlsl, ser)] void __hlslGetAttributesFromHitObject<T>(out T t); __target_intrinsic(hlsl, "NvMakeHitWithRecordIndex") [__requiresNVAPI] + [require(hlsl, ser)] static void __hlslMakeHitWithRecordIndex<attr_t>( uint HitGroupRecordIndex, RaytracingAccelerationStructure AccelerationStructure, @@ -11807,6 +12569,7 @@ struct HitObject __target_intrinsic(hlsl, "NvMakeHit") [__requiresNVAPI] + [require(hlsl, ser)] static void __hlslMakeHit<attr_t>(RaytracingAccelerationStructure AccelerationStructure, uint InstanceIndex, uint GeometryIndex, @@ -11820,6 +12583,7 @@ struct HitObject __target_intrinsic(hlsl, "NvTraceRayHitObject") [__requiresNVAPI] + [require(hlsl, ser)] static void __hlslTraceRay<payload_t>( RaytracingAccelerationStructure AccelerationStructure, uint RayFlags, @@ -11837,7 +12601,7 @@ struct HitObject __glsl_extension(GL_NV_shader_invocation_reorder) __glsl_extension(GL_EXT_ray_tracing) - __glsl_version(460) + [require(glsl, ser)] __target_intrinsic(glsl, "hitObjectRecordMissNV") static void __glslMakeMiss( out HitObject hitObj, @@ -11850,8 +12614,8 @@ struct HitObject // "void hitObjectRecordMissNV(hitObjectNV, uint, vec3, float, vec3, float);" __glsl_extension(GL_NV_shader_invocation_reorder) __glsl_extension(GL_EXT_ray_tracing) - __glsl_extension(GL_NV_ray_tracing_motion_blur) - __glsl_version(460) + __glsl_extension(GL_NV_ray_tracing_motion_blur) + [require(glsl, ser_motion)] __target_intrinsic(glsl, "hitObjectRecordMissMotionNV") static void __glslMakeMotionMiss( out HitObject hitObj, @@ -11862,35 +12626,46 @@ struct HitObject float TMax, float CurrentTime); - __glsl_extension(GL_NV_shader_invocation_reorder) __glsl_extension(GL_EXT_ray_tracing) + __glsl_extension(GL_NV_shader_invocation_reorder) + [require(glsl, ser)] __target_intrinsic(glsl, "hitObjectRecordEmptyNV") static void __glslMakeNop(out HitObject hitObj); + __glsl_extension(GL_EXT_ray_tracing) __glsl_extension(GL_NV_shader_invocation_reorder) + [require(glsl, ser)] __target_intrinsic(glsl, "hitObjectGetObjectRayDirectionNV($0)") float3 __glslGetRayDirection(); - + + __glsl_extension(GL_EXT_ray_tracing) __glsl_extension(GL_NV_shader_invocation_reorder) + [require(glsl, ser)] __target_intrinsic(glsl, "hitObjectGetWorldRayDirectionNV($0)") float3 __glslGetRayWorldDirection(); + __glsl_extension(GL_EXT_ray_tracing) __glsl_extension(GL_NV_shader_invocation_reorder) + [require(glsl, ser)] __target_intrinsic(glsl, "hitObjectGetWorldRayOriginNV($0)") float3 __glslGetRayWorldOrigin(); + __glsl_extension(GL_EXT_ray_tracing) __glsl_extension(GL_NV_shader_invocation_reorder) + [require(glsl, ser)] __target_intrinsic(glsl, "hitObjectGetRayTMaxNV($0)") float __glslGetTMax(); + __glsl_extension(GL_EXT_ray_tracing) __glsl_extension(GL_NV_shader_invocation_reorder) + [require(glsl, ser)] __target_intrinsic(glsl, "hitObjectGetRayTMinNV($0)") float __glslGetTMin(); // "void hitObjectRecordHitWithIndexNV(hitObjectNV, accelerationStructureEXT,int,int,int,uint,uint,vec3,float,vec3,float,int);" - __glsl_extension(GL_NV_shader_invocation_reorder) __glsl_extension(GL_EXT_ray_tracing) - __glsl_version(460) + __glsl_extension(GL_NV_shader_invocation_reorder) + [require(glsl, ser)] __target_intrinsic(glsl, "hitObjectRecordHitWithIndexNV") static void __glslMakeHitWithIndex( out HitObject hitObj, @@ -11907,9 +12682,10 @@ struct HitObject int attributeLocation); // "void hitObjectRecordHitWithIndexMotionNV(hitObjectNV, accelerationStructureEXT,int,int,int,uint,uint,vec3,float,vec3,float,float,int);" - __glsl_extension(GL_NV_shader_invocation_reorder) __glsl_extension(GL_EXT_ray_tracing) + __glsl_extension(GL_NV_shader_invocation_reorder) __glsl_extension(GL_NV_ray_tracing_motion_blur) + [require(glsl, ser_motion)] __target_intrinsic(glsl, "hitObjectRecordHitWithIndexMotionNV") static void __glslMakeMotionHitWithIndex( out HitObject hitObj, @@ -11929,6 +12705,7 @@ struct HitObject // "void hitObjectRecordHitNV(hitObjectNV,accelerationStructureEXT,int,int,int,uint,uint,uint,vec3,float,vec3,float,int);" __glsl_extension(GL_EXT_ray_tracing) __glsl_extension(GL_NV_shader_invocation_reorder) + [require(glsl, ser)] __target_intrinsic(glsl, "hitObjectRecordHitNV") static void __glslMakeHit( out HitObject hitObj, @@ -11949,6 +12726,7 @@ struct HitObject __glsl_extension(GL_EXT_ray_tracing) __glsl_extension(GL_NV_shader_invocation_reorder) __glsl_extension(GL_NV_ray_tracing_motion_blur) + [require(glsl, ser_motion)] __target_intrinsic(glsl, "hitObjectRecordHitMotionNV") static void __glslMakeMotionHit( out HitObject hitObj, @@ -11969,11 +12747,13 @@ struct HitObject __glsl_extension(GL_EXT_ray_tracing) __glsl_extension(GL_NV_shader_invocation_reorder) + [require(glsl, ser)] __target_intrinsic(glsl, "hitObjectGetAttributesNV($0, $1)") void __glslGetAttributes(int attributeLocation); __glsl_extension(GL_EXT_ray_tracing) __glsl_extension(GL_NV_shader_invocation_reorder) + [require(glsl, ser)] __target_intrinsic(glsl, "hitObjectTraceRayNV") static void __glslTraceRay( out HitObject hitObject, @@ -11992,6 +12772,7 @@ struct HitObject __glsl_extension(GL_EXT_ray_tracing) __glsl_extension(GL_NV_shader_invocation_reorder) __glsl_extension(GL_NV_ray_tracing_motion_blur) + [require(glsl, ser_motion)] __target_intrinsic(glsl, "hitObjectTraceRayMotionNV") static void __glslTraceMotionRay( out HitObject hitObject, @@ -12010,6 +12791,7 @@ struct HitObject __glsl_extension(GL_EXT_ray_tracing) __glsl_extension(GL_NV_shader_invocation_reorder) + [require(glsl, ser)] __target_intrinsic(glsl, "hitObjectExecuteShaderNV") static void __glslInvoke( HitObject hitObj, @@ -12024,8 +12806,11 @@ struct HitObject /// Where possible, reordering will also attempt to retain locality in the thread’s launch indices /// (DispatchRaysIndex in DXR). [__requiresNVAPI] -__glsl_extension(GL_NV_shader_invocation_reorder) __glsl_extension(GL_EXT_ray_tracing) +__glsl_extension(GL_NV_shader_invocation_reorder) +[require(glsl, ser)] +[require(spirv, ser)] +[require(hlsl, ser)] void ReorderThread( uint CoherenceHint, uint NumCoherenceHintBitsFromLSB ) { __target_switch @@ -12033,9 +12818,10 @@ void ReorderThread( uint CoherenceHint, uint NumCoherenceHintBitsFromLSB ) case hlsl: __intrinsic_asm "NvReorderThread"; case glsl: __intrinsic_asm "reorderThreadNV"; case spirv: - spirv_asm { - OpCapability ShaderInvocationReorderNV; + spirv_asm + { OpExtension "SPV_NV_shader_invocation_reorder"; + OpCapability ShaderInvocationReorderNV; OpReorderThreadWithHintNV $CoherenceHint $NumCoherenceHintBitsFromLSB; }; } @@ -12056,9 +12842,13 @@ void ReorderThread( uint CoherenceHint, uint NumCoherenceHintBitsFromLSB ) /// same shader ID. (Miss shaders and NOP HitObjects are grouped separately). Within each of these /// groups, it will attempt to order threads by the value of their coherence hints. And within ranges /// of equal coherence hints, it will attempt to maximize locality in 3D space of the ray hit (if any). + [__requiresNVAPI] -__glsl_extension(GL_NV_shader_invocation_reorder) __glsl_extension(GL_EXT_ray_tracing) +__glsl_extension(GL_NV_shader_invocation_reorder) +[require(glsl, ser)] +[require(spirv, ser)] +[require(hlsl, ser)] void ReorderThread( HitObject HitOrMiss, uint CoherenceHint, uint NumCoherenceHintBitsFromLSB ) { __target_switch @@ -12066,7 +12856,10 @@ void ReorderThread( HitObject HitOrMiss, uint CoherenceHint, uint NumCoherenceHi case hlsl: __intrinsic_asm "NvReorderThread"; case glsl: __intrinsic_asm "reorderThreadNV"; case spirv: - spirv_asm { + spirv_asm + { + OpExtension "SPV_NV_shader_invocation_reorder"; + OpCapability ShaderInvocationReorderNV; OpReorderThreadWithHitObjectNV &HitOrMiss $CoherenceHint $NumCoherenceHintBitsFromLSB; }; } @@ -12077,8 +12870,13 @@ void ReorderThread( HitObject HitOrMiss, uint CoherenceHint, uint NumCoherenceHi /// void ReorderThread( HitObject HitOrMiss, uint CoherenceHint, uint NumCoherenceHintBitsFromLSB ); /// ``` /// With CoherenceHint and NumCoherenceHintBitsFromLSB as 0, meaning they are ignored. + [__requiresNVAPI] +__glsl_extension(GL_EXT_ray_tracing) __glsl_extension(GL_NV_shader_invocation_reorder) +[require(glsl, ser)] +[require(spirv, ser)] +[require(hlsl, ser)] void ReorderThread( HitObject HitOrMiss ) { __target_switch @@ -12086,13 +12884,15 @@ void ReorderThread( HitObject HitOrMiss ) case hlsl: __intrinsic_asm "NvReorderThread"; case glsl: __intrinsic_asm "reorderThreadNV"; case spirv: - spirv_asm { + spirv_asm + { + OpExtension "SPV_NV_shader_invocation_reorder"; + OpCapability ShaderInvocationReorderNV; OpReorderThreadWithHitObjectNV &HitOrMiss; }; } } - /// /// DebugBreak support /// diff --git a/source/slang/slang-ast-dump.cpp b/source/slang/slang-ast-dump.cpp index 3bb83f80b..5576d9401 100644 --- a/source/slang/slang-ast-dump.cpp +++ b/source/slang/slang-ast-dump.cpp @@ -666,6 +666,14 @@ struct ASTDumpContext case SPIRVAsmOperand::SlangImmediateValue: m_writer->emit("!"); break; + case SPIRVAsmOperand::RayPayloadFromLocation: + m_writer->emit("__rayPayloadFromLocation"); + break; + case SPIRVAsmOperand::RayAttributeFromLocation: + m_writer->emit("__rayAttributeFromLocation"); + break; + case SPIRVAsmOperand::RayCallableFromLocation: + m_writer->emit("__rayCallableFromLocation"); case SPIRVAsmOperand::BuiltinVar: m_writer->emit("builtin"); break; diff --git a/source/slang/slang-ast-expr.h b/source/slang/slang-ast-expr.h index fa1b27a04..3331b288e 100644 --- a/source/slang/slang-ast-expr.h +++ b/source/slang/slang-ast-expr.h @@ -682,6 +682,9 @@ public: BuiltinVar, GLSL450Set, NonSemanticDebugPrintfExtSet, + RayPayloadFromLocation, //insert from scope of all payloads in the spir-v shader the payload identified by the integer value provided + RayAttributeFromLocation, + RayCallableFromLocation, }; // The flavour and token describes how this was parsed diff --git a/source/slang/slang-ast-modifier.h b/source/slang/slang-ast-modifier.h index 32852496c..5ab7eae3c 100644 --- a/source/slang/slang-ast-modifier.h +++ b/source/slang/slang-ast-modifier.h @@ -901,7 +901,12 @@ class VulkanRayPayloadAttribute : public Attribute int location; }; +class VulkanRayPayloadInAttribute : public Attribute +{ + SLANG_AST_CLASS(VulkanRayPayloadInAttribute) + int location; +}; // A `[__vulkanCallablePayload(location)]` attribute, which is used in the // standard library implementation to indicate that a variable @@ -913,7 +918,12 @@ class VulkanCallablePayloadAttribute : public Attribute int location; }; +class VulkanCallablePayloadInAttribute : public Attribute +{ + SLANG_AST_CLASS(VulkanCallablePayloadInAttribute) + int location; +}; // A `[__vulkanHitAttributes]` attribute, which is used in the // standard library implementation to indicate that a variable diff --git a/source/slang/slang-capabilities.capdef b/source/slang/slang-capabilities.capdef index cf2cd5791..b8d97d021 100644 --- a/source/slang/slang-capabilities.capdef +++ b/source/slang/slang-capabilities.capdef @@ -180,10 +180,12 @@ def _GL_ARB_fragment_shader_interlock : glsl; def _GL_ARB_gpu_shader5 : glsl; def _GL_ARB_sparse_texture_clamp : glsl; def _GL_EXT_buffer_reference : glsl; +def _GL_EXT_buffer_reference_uvec2 : glsl; def _GL_EXT_debug_printf : glsl; def _GL_EXT_fragment_shader_barycentric : glsl; def _GL_EXT_mesh_shader : glsl; def _GL_EXT_nonuniform_qualifier : glsl; +def _GL_EXT_ray_query : glsl_spirv_1_4; def _GL_EXT_ray_tracing : glsl_spirv_1_4; def _GL_EXT_ray_tracing_position_fetch : glsl_spirv_1_4; def _GL_EXT_samplerless_texture_functions : glsl; @@ -214,10 +216,12 @@ alias GL_ARB_fragment_shader_interlock = _GL_ARB_fragment_shader_interlock | spv alias GL_ARB_gpu_shader5 = _GL_ARB_fragment_shader_interlock | spirv_1_0; alias GL_ARB_sparse_texture_clamp = _GL_ARB_fragment_shader_interlock | spirv_1_0; alias GL_EXT_buffer_reference = _GL_ARB_fragment_shader_interlock | spirv_1_5; +alias GL_EXT_buffer_reference_uvec2 = _GL_EXT_buffer_reference_uvec2 | spirv_1_0; alias GL_EXT_debug_printf = _GL_EXT_debug_printf | SPV_KHR_non_semantic_info; alias GL_EXT_fragment_shader_barycentric = _GL_EXT_fragment_shader_barycentric | spvFragmentBarycentricKHR; alias GL_EXT_mesh_shader = _GL_EXT_mesh_shader | spvMeshShadingEXT; alias GL_EXT_nonuniform_qualifier = _GL_EXT_nonuniform_qualifier | spvShaderNonUniform; +alias GL_EXT_ray_query = _GL_EXT_ray_query | spvRayTracingKHR + spvRayQueryKHR; alias GL_EXT_ray_tracing = _GL_EXT_ray_tracing | spvRayTracingKHR + spvRayQueryKHR; alias GL_EXT_ray_tracing_position_fetch = _GL_EXT_ray_tracing_position_fetch | spvRayTracingPositionFetchKHR + spvRayQueryPositionFetchKHR; alias GL_EXT_samplerless_texture_functions = _GL_EXT_samplerless_texture_functions | spirv_1_0; @@ -246,11 +250,16 @@ alias GL_NV_ray_tracing = GL_EXT_ray_tracing; // Define feature names alias nvapi = hlsl_nvapi; -alias raytracing = spvRayTracingKHR + spvRayQueryKHR + spvRayQueryPositionFetchKHR | _GL_EXT_ray_tracing+_GL_EXT_ray_tracing_position_fetch | _sm_6_5 | cuda; -alias ser = spvShaderInvocationReorderNV | _GL_NV_shader_invocation_reorder | _sm_6_6 + hlsl_nvapi; +alias raytracing = GL_EXT_ray_tracing | _sm_6_5 | cuda; +alias raytracing_pos = GL_EXT_ray_tracing + GL_EXT_ray_tracing_position_fetch | _sm_6_5 | cuda; +alias rayquery_pos = GL_EXT_ray_query + GL_EXT_ray_tracing_position_fetch | _sm_6_5 | cuda; +alias rayquery = GL_EXT_ray_query | _sm_6_5 | cuda; +alias ser = GL_EXT_buffer_reference_uvec2 + GL_NV_shader_invocation_reorder + GL_EXT_ray_tracing | _sm_6_6 + hlsl_nvapi; +alias ser_motion = GL_EXT_buffer_reference_uvec2 + GL_NV_shader_invocation_reorder + GL_EXT_ray_tracing + GL_NV_ray_tracing_motion_blur | _sm_6_6 + hlsl_nvapi; alias shaderclock = spvShaderClockKHR | hlsl_nvapi | _GL_EXT_shader_realtime_clock | cpp | cuda; alias meshshading = spvMeshShadingEXT | _sm_6_5 | _GL_EXT_mesh_shader; -alias motionblur = spvRayTracingMotionBlurNV | hlsl_nvapi | _GL_NV_ray_tracing_motion_blur; +alias raytracing_motionblur = GL_EXT_ray_tracing + GL_NV_ray_tracing_motion_blur | hlsl_nvapi + _sm_6_5; +alias motionblur = GL_NV_ray_tracing_motion_blur | hlsl_nvapi; alias texturefootprint = GL_NV_shader_texture_footprint | hlsl_nvapi; alias fragmentshaderinterlock = _GL_ARB_fragment_shader_interlock | hlsl_nvapi | spvFragmentShaderPixelInterlockEXT; alias atomic64 = GL_EXT_shader_atomic_int64 | _sm_6_6 | cpp | cuda; diff --git a/source/slang/slang-check-expr.cpp b/source/slang/slang-check-expr.cpp index 995b5e888..f238550fd 100644 --- a/source/slang/slang-check-expr.cpp +++ b/source/slang/slang-check-expr.cpp @@ -4319,7 +4319,10 @@ namespace Slang || operand.flavor == SPIRVAsmOperand::SlangImmediateValue || operand.flavor == SPIRVAsmOperand::SlangValueAddr || operand.flavor == SPIRVAsmOperand::ImageType - || operand.flavor == SPIRVAsmOperand::SampledImageType) + || operand.flavor == SPIRVAsmOperand::SampledImageType + || operand.flavor == SPIRVAsmOperand::RayPayloadFromLocation + || operand.flavor == SPIRVAsmOperand::RayAttributeFromLocation + || operand.flavor == SPIRVAsmOperand::RayCallableFromLocation) { // This is a $expr operand, check the expr operand.expr = dispatch(operand.expr); diff --git a/source/slang/slang-check-impl.h b/source/slang/slang-check-impl.h index 28c145498..cff5b7028 100644 --- a/source/slang/slang-check-impl.h +++ b/source/slang/slang-check-impl.h @@ -2437,6 +2437,12 @@ namespace Slang Expr* baseExpr, OverloadResolveContext& context); + template<class T> + void trySetGenericToRayTracingWithParamAttribute( + LookupResultItem genericItem, + DeclRef<GenericDecl> genericDeclRef, + OverloadResolveContext& context); + // Add overload candidates based on use of `genericDeclRef` // in an ordinary function-call context (that is, where it // has been applied to arguments using `()` and not `<>`). diff --git a/source/slang/slang-check-modifier.cpp b/source/slang/slang-check-modifier.cpp index eae993dc7..17215d284 100644 --- a/source/slang/slang-check-modifier.cpp +++ b/source/slang/slang-check-modifier.cpp @@ -707,6 +707,13 @@ namespace Slang rayPayloadAttr->location = (int32_t)val->getValue(); } + else if (auto rayPayloadInAttr = as<VulkanRayPayloadInAttribute>(attr)) + { + SLANG_ASSERT(attr->args.getCount() == 1); + auto val = checkConstantIntVal(attr->args[0]); + if (!val) return false; + rayPayloadInAttr->location = (int32_t)val->getValue(); + } else if (auto callablePayloadAttr = as<VulkanCallablePayloadAttribute>(attr)) { SLANG_ASSERT(attr->args.getCount() == 1); @@ -716,6 +723,13 @@ namespace Slang callablePayloadAttr->location = (int32_t)val->getValue(); } + else if (auto callablePayloadInAttr = as<VulkanCallablePayloadInAttribute>(attr)) + { + SLANG_ASSERT(attr->args.getCount() == 1); + auto val = checkConstantIntVal(attr->args[0]); + if (!val) return false; + callablePayloadInAttr->location = (int32_t)val->getValue(); + } else if (auto hitObjectAttributesAttr = as<VulkanHitObjectAttributesAttribute>(attr)) { SLANG_ASSERT(attr->args.getCount() == 1); diff --git a/source/slang/slang-diagnostic-defs.h b/source/slang/slang-diagnostic-defs.h index 47c75ab0c..db17c92a0 100644 --- a/source/slang/slang-diagnostic-defs.h +++ b/source/slang/slang-diagnostic-defs.h @@ -531,6 +531,8 @@ DIAGNOSTIC(39999, Error, expectedIntegerConstantWrongType, "expected integer con DIAGNOSTIC(39999, Error, expectedIntegerConstantNotConstant, "expression does not evaluate to a compile-time constant") DIAGNOSTIC(39999, Error, expectedIntegerConstantNotLiteral, "could not extract value from integer constant") +DIAGNOSTIC(39999, Error, expectedRayTracingPayloadObjectAtLocationButMissing, "raytracing payload expected at location $0 but it is missing") + DIAGNOSTIC(39999, Error, noApplicableOverloadForNameWithArgs, "no overload for '$0' applicable to arguments of type $1") DIAGNOSTIC(39999, Error, noApplicableWithArgs, "no overload applicable to arguments of type $0") diff --git a/source/slang/slang-emit-c-like.cpp b/source/slang/slang-emit-c-like.cpp index 2019bfa8c..af53b545f 100644 --- a/source/slang/slang-emit-c-like.cpp +++ b/source/slang/slang-emit-c-like.cpp @@ -4268,6 +4268,27 @@ void CLikeSourceEmitter::computeEmitActions(IRModule* module, List<EmitAction>& } } + for (auto inst : module->getGlobalInsts()) + { + // After emitting all structure types we need to emit all raytracing objects to + // ensure they are emitted before the layout location is referenced, otherwise, + // this can be a compile error if layout is emitted after location is referenced + // this is required since in GLSL, it is likley in a programs life time a raytracing + // object will never be referenced by name + for (auto dec : inst->getDecorations()) + { + switch (dec->getOp()) + { + case kIROp_VulkanRayPayloadDecoration: + case kIROp_VulkanRayPayloadInDecoration: + case kIROp_VulkanHitObjectAttributesDecoration: + case kIROp_VulkanCallablePayloadDecoration: + case kIROp_VulkanCallablePayloadInDecoration: + case kIROp_VulkanHitAttributesDecoration: + ensureGlobalInst(&ctx, inst, EmitAction::Level::Definition); + }; + } + } for(auto inst : module->getGlobalInsts()) { if( as<IRType>(inst) ) diff --git a/source/slang/slang-emit-glsl.cpp b/source/slang/slang-emit-glsl.cpp index d37a6840b..7e5c84533 100644 --- a/source/slang/slang-emit-glsl.cpp +++ b/source/slang/slang-emit-glsl.cpp @@ -2659,10 +2659,18 @@ void GLSLSourceEmitter::emitVarDecorationsImpl(IRInst* varDecl) prefix = toSlice("callableData"); locationValue = getIntVal(decoration->getOperand(0)); break; + case kIROp_VulkanCallablePayloadInDecoration: + prefix = toSlice("callableDataIn"); + locationValue = getIntVal(decoration->getOperand(0)); + break; case kIROp_VulkanRayPayloadDecoration: prefix = toSlice("rayPayload"); locationValue = getIntVal(decoration->getOperand(0)); break; + case kIROp_VulkanRayPayloadInDecoration: + prefix = toSlice("rayPayloadIn"); + locationValue = getIntVal(decoration->getOperand(0)); + break; case kIROp_VulkanHitObjectAttributesDecoration: prefix = toSlice("hitObjectAttribute"); postfix = toSlice("NV"); diff --git a/source/slang/slang-emit-hlsl.cpp b/source/slang/slang-emit-hlsl.cpp index cf1ca794b..3d45394d3 100644 --- a/source/slang/slang-emit-hlsl.cpp +++ b/source/slang/slang-emit-hlsl.cpp @@ -3,6 +3,7 @@ #include "../core/slang-writer.h" +#include "slang-ir-util.h" #include "slang-emit-source-writer.h" #include "slang-mangled-lexer.h" @@ -987,7 +988,6 @@ void HLSLSourceEmitter::emitSimpleTypeImpl(IRType* type) case kIROp_HLSLRWByteAddressBufferType: m_writer->emit("RWByteAddressBuffer"); break; case kIROp_HLSLRasterizerOrderedByteAddressBufferType: m_writer->emit("RasterizerOrderedByteAddressBuffer"); break; case kIROp_RaytracingAccelerationStructureType: m_writer->emit("RaytracingAccelerationStructure"); break; - default: SLANG_DIAGNOSE_UNEXPECTED(getSink(), SourceLoc(), "unhandled buffer type"); break; diff --git a/source/slang/slang-emit-spirv.cpp b/source/slang/slang-emit-spirv.cpp index 79f324988..afb1b3a63 100644 --- a/source/slang/slang-emit-spirv.cpp +++ b/source/slang/slang-emit-spirv.cpp @@ -2956,6 +2956,7 @@ struct SPIRVEmitContext // We will continue to use the Slang terminology here, since // this code path is a catch-all for stuff that only needs to // be emitted if the owning instruction gets emitted. + bool isRayTracingObject = false; switch( decoration->getOp() ) { @@ -3225,13 +3226,25 @@ struct SPIRVEmitContext } break; + case kIROp_VulkanHitAttributesDecoration: case kIROp_VulkanCallablePayloadDecoration: + case kIROp_VulkanCallablePayloadInDecoration: + ensureExtensionDeclaration(UnownedStringSlice("SPV_KHR_ray_tracing")); + requireSPIRVCapability(SpvCapabilityRayTracingKHR); + isRayTracingObject = true; + break; case kIROp_VulkanHitObjectAttributesDecoration: + // needed since GLSL will not set optypes accordingly, but will keep the decoration + ensureExtensionDeclaration(UnownedStringSlice("SPV_NV_shader_invocation_reorder")); + requireSPIRVCapability(SpvCapabilityShaderInvocationReorderNV); + isRayTracingObject = true; + break; case kIROp_VulkanRayPayloadDecoration: - emitOpDecorateLocation(getSection(SpvLogicalSectionID::Annotations), - decoration, - dstID, - SpvLiteralInteger::from32(int32_t(getIntVal(decoration->getOperand(0))))); + case kIROp_VulkanRayPayloadInDecoration: + // needed since GLSL will not set optypes accordingly, but will keep the decoration + ensureExtensionDeclaration(UnownedStringSlice("SPV_KHR_ray_query")); + requireSPIRVCapability(SpvCapabilityRayQueryKHR); + isRayTracingObject = true; break; case kIROp_GloballyCoherentDecoration: emitOpDecorate(getSection(SpvLogicalSectionID::Annotations), @@ -3242,6 +3255,17 @@ struct SPIRVEmitContext // ... } + if(isRayTracingObject) + { + if (decoration->getOperandCount() > 0) { + //if not greater than 0, this is not a layout decoration (no val) + emitOpDecorateLocation(getSection(SpvLogicalSectionID::Annotations), + decoration, + dstID, + SpvLiteralInteger::from32(int32_t(getIntVal(decoration->getOperand(0))))); + } + } + if (shouldEmitSPIRVReflectionInfo()) { switch (decoration->getOp()) @@ -5823,7 +5847,7 @@ SlangResult emitSPIRVFromIR( SPIRVEmitContext context(irModule, codeGenContext->getTargetProgram(), sink); legalizeIRForSPIRV(&context, irModule, irEntryPoints, codeGenContext); - + #if 0 { DiagnosticSinkWriter writer(codeGenContext->getSink()); diff --git a/source/slang/slang-emit.cpp b/source/slang/slang-emit.cpp index 43f54d04f..ee38996e6 100644 --- a/source/slang/slang-emit.cpp +++ b/source/slang/slang-emit.cpp @@ -17,6 +17,7 @@ #include "slang-ir-defunctionalization.h" #include "slang-ir-dll-export.h" #include "slang-ir-dll-import.h" +#include "slang-ir-early-raytracing-intrinsic-simplification.h" #include "slang-ir-eliminate-phis.h" #include "slang-ir-eliminate-multilevel-break.h" #include "slang-ir-entry-point-uniforms.h" @@ -242,7 +243,7 @@ Result linkAndOptimizeIR( // If the user specified the flag that they want us to dump // IR, then do it here, for the target-specific, but // un-specialized IR. - dumpIRIfEnabled(codeGenContext, irModule); + dumpIRIfEnabled(codeGenContext, irModule, "POST IR VALIDATION"); if(!isKhronosTarget(targetRequest)) lowerGLSLShaderStorageBufferObjectsToStructuredBuffers(irModule, sink); @@ -1038,6 +1039,9 @@ Result linkAndOptimizeIR( } } + replaceLocationIntrinsicsWithRaytracingObject(targetProgram, irModule, sink); + validateIRModuleIfEnabled(codeGenContext, irModule); + // Run a final round of simplifications to clean up unused things after phi-elimination. simplifyNonSSAIR(targetProgram, irModule, IRSimplificationOptions::getFast()); diff --git a/source/slang/slang-ir-early-raytracing-intrinsic-simplification.cpp b/source/slang/slang-ir-early-raytracing-intrinsic-simplification.cpp new file mode 100644 index 000000000..01f49e1c9 --- /dev/null +++ b/source/slang/slang-ir-early-raytracing-intrinsic-simplification.cpp @@ -0,0 +1,169 @@ +// slang-ir-early-raytracing-intrinsic-simplification.cpp +#include "slang-ir-early-raytracing-intrinsic-simplification.h" +#include "slang-ir.h" +#include "../core/slang-performance-profiler.h" +#include "slang-ir-util.h" + +namespace Slang +{ + // ONLY should be used in this compilation unit + struct CacheOfDataToReplaceOps + { + TargetProgram* target; + IRModule* module; + DiagnosticSink* sink; + + Dictionary<int, IRInst*> m_RayLocationToPayloads; + Dictionary<int, IRInst*> m_RayLocationToAttributes; + Dictionary<int, IRInst*> m_RayLocationToCallables; + + List<IRInst*> funcsToSearch; + + IRInst* getRayVariableFromLocation(IRInst* payloadVariable, Slang::IROp op) + { + IRBuilder builder(payloadVariable); + IRInst** varLayoutPointsTo = nullptr; + int intLitValue = -1; + IRIntLit* intLit = as<IRIntLit>(payloadVariable); + if (intLit) + { + intLitValue = int(intLit->getValue()); + if (kIROp_SPIRVAsmOperandRayPayloadFromLocation == op) + { + varLayoutPointsTo = m_RayLocationToPayloads.tryGetValue(intLitValue); + } + else if (kIROp_SPIRVAsmOperandRayAttributeFromLocation == op) + { + varLayoutPointsTo = m_RayLocationToAttributes.tryGetValue(intLitValue); + } + else if (kIROp_SPIRVAsmOperandRayCallableFromLocation == op) + { + SLANG_ASSERT(kIROp_SPIRVAsmOperandRayCallableFromLocation == op); //final case + varLayoutPointsTo = m_RayLocationToCallables.tryGetValue(intLitValue); + } + } + else + { + sink->diagnose(payloadVariable, Diagnostics::expectedIntegerConstantNotConstant); + } + + IRInst* resultVariable; + if (!varLayoutPointsTo) + { + // if somehow the location tied variable is missing and an error was not thrown by the compiler + resultVariable = builder.getIntValue(builder.getIntType(), 0); + sink->diagnose(payloadVariable, Diagnostics::expectedRayTracingPayloadObjectAtLocationButMissing, intLitValue); + } + else + { + resultVariable = *varLayoutPointsTo; + } + return resultVariable; + } + + void searchForGlobalsDataNeededInPass() + { + if (target->getOptionSet().getBoolOption(CompilerOptionName::AllowGLSL)) + { + for (auto i : module->getGlobalInsts()) + { + switch(i->getOp()) + { + + case kIROp_GlobalParam: + case kIROp_GlobalVar: + { + for (auto decoration : i->getDecorations()) + { + auto op = decoration->getOp(); + if (op == kIROp_VulkanRayPayloadDecoration) + { + m_RayLocationToPayloads.set(int(getIntVal(decoration->getOperand(0))), i); + } + else if (op == kIROp_VulkanRayPayloadInDecoration) + { + m_RayLocationToPayloads.set(int(getIntVal(decoration->getOperand(0))), i); + } + else if (op == kIROp_VulkanHitObjectAttributesDecoration) + { + m_RayLocationToAttributes.set(int(getIntVal(decoration->getOperand(0))), i); + } + else if (op == kIROp_VulkanCallablePayloadDecoration) + { + m_RayLocationToCallables.set(int(getIntVal(decoration->getOperand(0))), i); + } + else if (op == kIROp_VulkanCallablePayloadInDecoration) + { + m_RayLocationToCallables.set(int(getIntVal(decoration->getOperand(0))), i); + } + } + break; + } + case kIROp_Func: + { + funcsToSearch.add(i); + break; + } + }; + } + } + } + + CacheOfDataToReplaceOps(TargetProgram* target, IRModule* module, DiagnosticSink* sink) + { + this->target = target; + this->module = module; + this->sink = sink; + } + }; + + void recurseInFuncForOpsToReplace(IRInst* parent, CacheOfDataToReplaceOps* cache) + { + + if (as<IRSPIRVAsm>(parent)) + { + for (auto i : parent->getChildren()) + { + switch (i->getOp()) + { + case kIROp_SPIRVAsmOperandRayPayloadFromLocation: + case kIROp_SPIRVAsmOperandRayAttributeFromLocation: + case kIROp_SPIRVAsmOperandRayCallableFromLocation: + { + auto op = i->getOperand(0); + IRInst* globalVar = cache->getRayVariableFromLocation(op, i->getOp()); + auto builder = IRBuilder(i); + builder.setInsertBefore(i); + auto spirvASM = builder.emitSPIRVAsmOperandInst(globalVar); + i->replaceUsesWith(spirvASM); + i->removeAndDeallocate(); + break; + } + }; + } + } + + for(auto i : parent->getChildren()) + recurseInFuncForOpsToReplace(i, cache); + } + + void recurseAllOpsToReplace(CacheOfDataToReplaceOps* cache) + { + for (auto func : cache->funcsToSearch) + { + recurseInFuncForOpsToReplace(func, cache); + } + } + + void replaceLocationIntrinsicsWithRaytracingObject(TargetProgram* target, IRModule* module, DiagnosticSink* sink) + { + //currently only applies to GLSL syntax + CacheOfDataToReplaceOps cache = CacheOfDataToReplaceOps(target, module, sink); + cache.searchForGlobalsDataNeededInPass(); + + if (target->getOptionSet().getBoolOption(CompilerOptionName::AllowGLSL)) + { + recurseAllOpsToReplace(&cache); + } + } +} diff --git a/source/slang/slang-ir-early-raytracing-intrinsic-simplification.h b/source/slang/slang-ir-early-raytracing-intrinsic-simplification.h new file mode 100644 index 000000000..e2bdc7281 --- /dev/null +++ b/source/slang/slang-ir-early-raytracing-intrinsic-simplification.h @@ -0,0 +1,15 @@ +// slang-ir-early-raytracing-intrinsic-simplification.h +#pragma once + +#include "slang-ir.h" +#include "slang-ir-util.h" + +namespace Slang +{ + struct IRModule; + struct IRGlobalValueWithCode; + class DiagnosticSink; + class TargetProgram; + + void replaceLocationIntrinsicsWithRaytracingObject(TargetProgram* target, IRModule* module, DiagnosticSink* sink); +}
\ No newline at end of file diff --git a/source/slang/slang-ir-glsl-legalize.cpp b/source/slang/slang-ir-glsl-legalize.cpp index c9bc1339b..f51ae7215 100644 --- a/source/slang/slang-ir-glsl-legalize.cpp +++ b/source/slang/slang-ir-glsl-legalize.cpp @@ -2730,46 +2730,108 @@ bool shouldUseOriginalEntryPointName(CodeGenContext* codeGenContext) return false; } +void getAllNullLocationRayObjectsAndUsedLocations( + IRModule* module, + List<IRInst*>* nullRayObjects, + HashSet<IRIntegerValue>* rayPayload, + HashSet<IRIntegerValue>* callablePayload, + HashSet<IRIntegerValue>* hitObjectAttribute) +{ + for (auto inst : module->getGlobalInsts()) + { + auto instOp = inst->getOp(); + IRIntegerValue intLitVal = NULL; + if (instOp != kIROp_GlobalParam && instOp != kIROp_GlobalVar) continue; + for (auto decor : inst->getDecorations()) + { + switch (decor->getOp()) + { + case kIROp_VulkanRayPayloadDecoration: + case kIROp_VulkanRayPayloadInDecoration: + intLitVal = as<IRIntLit>(decor->getOperand(0))->getValue(); + if (intLitVal == -1) { nullRayObjects->add(inst); goto getAllNullLocationRayObjectsAndUsedLocations_end; } + rayPayload->add(intLitVal); + goto getAllNullLocationRayObjectsAndUsedLocations_end; + case kIROp_VulkanCallablePayloadDecoration: + case kIROp_VulkanCallablePayloadInDecoration: + intLitVal = as<IRIntLit>(decor->getOperand(0))->getValue(); + if (intLitVal == -1) { nullRayObjects->add(inst); goto getAllNullLocationRayObjectsAndUsedLocations_end; } + callablePayload->add(intLitVal); + goto getAllNullLocationRayObjectsAndUsedLocations_end; + case kIROp_VulkanHitObjectAttributesDecoration: + intLitVal = as<IRIntLit>(decor->getOperand(0))->getValue(); + if (intLitVal == -1) { nullRayObjects->add(inst); goto getAllNullLocationRayObjectsAndUsedLocations_end; } + hitObjectAttribute->add(intLitVal); + goto getAllNullLocationRayObjectsAndUsedLocations_end; + } + } + getAllNullLocationRayObjectsAndUsedLocations_end:; + } +} void assignRayPayloadHitObjectAttributeLocations(IRModule* module) { + List<IRInst*> nullRayObjects; + HashSet<IRIntegerValue> rayPayloadLocations; + HashSet<IRIntegerValue> callablePayloadLocations; + HashSet<IRIntegerValue> hitObjectAttributeLocations; + getAllNullLocationRayObjectsAndUsedLocations(module, &nullRayObjects, &rayPayloadLocations, &callablePayloadLocations, &hitObjectAttributeLocations); + IRIntegerValue rayPayloadCounter = 0; IRIntegerValue callablePayloadCounter = 0; IRIntegerValue hitObjectAttributeCounter = 0; IRBuilder builder(module); - for (auto inst : module->getGlobalInsts()) + for (auto inst : nullRayObjects) { - auto globalVar = as<IRGlobalVar>(inst); - if (!globalVar) - continue; IRInst* location = nullptr; - for (auto decor : globalVar->getDecorations()) + IRIntegerValue intLitVal = NULL; + for (auto decor : inst->getDecorations()) { switch (decor->getOp()) { case kIROp_VulkanRayPayloadDecoration: + case kIROp_VulkanRayPayloadInDecoration: + intLitVal = as<IRIntLit>(decor->getOperand(0))->getValue(); + if (intLitVal >= 0) goto assignRayPayloadHitObjectAttributeLocations_end; + while(rayPayloadLocations.contains(rayPayloadCounter)) + { + rayPayloadCounter++; + } builder.setInsertBefore(inst); location = builder.getIntValue(builder.getIntType(), rayPayloadCounter); decor->setOperand(0, location); rayPayloadCounter++; - goto end; + goto assignRayPayloadHitObjectAttributeLocations_end; case kIROp_VulkanCallablePayloadDecoration: + case kIROp_VulkanCallablePayloadInDecoration: + intLitVal = as<IRIntLit>(decor->getOperand(0))->getValue(); + if (intLitVal >= 0) goto assignRayPayloadHitObjectAttributeLocations_end; + while (callablePayloadLocations.contains(callablePayloadCounter)) + { + callablePayloadCounter++; + } builder.setInsertBefore(inst); location = builder.getIntValue(builder.getIntType(), callablePayloadCounter); decor->setOperand(0, location); callablePayloadCounter++; - goto end; + goto assignRayPayloadHitObjectAttributeLocations_end; case kIROp_VulkanHitObjectAttributesDecoration: + intLitVal = as<IRIntLit>(decor->getOperand(0))->getValue(); + if (intLitVal >= 0) goto assignRayPayloadHitObjectAttributeLocations_end; + while (hitObjectAttributeLocations.contains(hitObjectAttributeCounter)) + { + hitObjectAttributeCounter++; + } builder.setInsertBefore(inst); location = builder.getIntValue(builder.getIntType(), hitObjectAttributeCounter); decor->setOperand(0, location); hitObjectAttributeCounter++; - goto end; + goto assignRayPayloadHitObjectAttributeLocations_end; default: break; } } - end:; + assignRayPayloadHitObjectAttributeLocations_end:; } } diff --git a/source/slang/slang-ir-inst-defs.h b/source/slang/slang-ir-inst-defs.h index aa0929a57..10df5d0d7 100644 --- a/source/slang/slang-ir-inst-defs.h +++ b/source/slang/slang-ir-inst-defs.h @@ -705,6 +705,7 @@ INST(HighLevelDeclDecoration, highLevelDecl, 1, 0) INST(TransitoryDecoration, transitory, 0, 0) INST(VulkanRayPayloadDecoration, vulkanRayPayload, 0, 0) + INST(VulkanRayPayloadInDecoration, vulkanRayPayloadIn, 0, 0) INST(VulkanHitAttributesDecoration, vulkanHitAttributes, 0, 0) INST(VulkanHitObjectAttributesDecoration, vulkanHitObjectAttributes, 0, 0) @@ -715,6 +716,7 @@ INST(HighLevelDeclDecoration, highLevelDecl, 1, 0) INST(ReadNoneDecoration, readNone, 0, 0) INST(VulkanCallablePayloadDecoration, vulkanCallablePayload, 0, 0) + INST(VulkanCallablePayloadInDecoration, vulkanCallablePayloadIn, 0, 0) INST(EarlyDepthStencilDecoration, earlyDepthStencil, 0, 0) INST(GloballyCoherentDecoration, globallyCoherent, 0, 0) INST(PreciseDecoration, precise, 0, 0) @@ -1148,7 +1150,11 @@ INST(SPIRVAsmInst, SPIRVAsmInst, 1, 0) // A reference to a slang IRInst, either a value or a type // This isn't hoistable, as we sometimes need to change the used value and // instructions around the specific asm block - INST(SPIRVAsmOperandInst, SPIRVAsmOperandInst, 1, 0) + INST(SPIRVAsmOperandInst, SPIRVAsmOperandInst, 1, 0) + //a late resolving type to handle the case of ray objects (resolving late due to constexpr data requirment) + INST(SPIRVAsmOperandRayPayloadFromLocation, SPIRVAsmOperandRayPayloadFromLocation, 1, 0) + INST(SPIRVAsmOperandRayAttributeFromLocation, SPIRVAsmOperandRayAttributeFromLocation, 1, 0) + INST(SPIRVAsmOperandRayCallableFromLocation, SPIRVAsmOperandRayCallableFromLocation, 1, 0) // A named enumerator, the value is stored as a constant operand // It may have a second operand, which if present is a type with which to // construct a constant id to pass, instead of a literal constant diff --git a/source/slang/slang-ir-insts.h b/source/slang/slang-ir-insts.h index 3ae9f04d7..b104baca7 100644 --- a/source/slang/slang-ir-insts.h +++ b/source/slang/slang-ir-insts.h @@ -280,11 +280,13 @@ bool isSimpleDecoration(IROp op); /// a vulkan ray payload, and should have a location assigned /// to it. IR_SIMPLE_DECORATION(VulkanRayPayloadDecoration) +IR_SIMPLE_DECORATION(VulkanRayPayloadInDecoration) /// A decoration that indicates that a variable represents /// a vulkan callable shader payload, and should have a location assigned /// to it. IR_SIMPLE_DECORATION(VulkanCallablePayloadDecoration) +IR_SIMPLE_DECORATION(VulkanCallablePayloadInDecoration) /// A decoration that indicates that a variable represents /// vulkan hit attributes, and should have a location assigned @@ -4167,6 +4169,10 @@ public: IRSPIRVAsmOperand* emitSPIRVAsmOperandLiteral(IRInst* literal); IRSPIRVAsmOperand* emitSPIRVAsmOperandInst(IRInst* inst); + IRSPIRVAsmOperand* createSPIRVAsmOperandInst(IRInst* inst); + IRSPIRVAsmOperand* emitSPIRVAsmOperandRayPayloadFromLocation(IRInst* inst); + IRSPIRVAsmOperand* emitSPIRVAsmOperandRayAttributeFromLocation(IRInst* inst); + IRSPIRVAsmOperand* emitSPIRVAsmOperandRayCallableFromLocation(IRInst* inst); IRSPIRVAsmOperand* emitSPIRVAsmOperandId(IRInst* inst); IRSPIRVAsmOperand* emitSPIRVAsmOperandResult(); IRSPIRVAsmOperand* emitSPIRVAsmOperandEnum(IRInst* inst); @@ -4742,11 +4748,21 @@ public: addDecoration(inst, kIROp_VulkanRayPayloadDecoration, getIntValue(getIntType(), location)); } + void addVulkanRayPayloadInDecoration(IRInst* inst, int location) + { + addDecoration(inst, kIROp_VulkanRayPayloadInDecoration, getIntValue(getIntType(), location)); + } + void addVulkanCallablePayloadDecoration(IRInst* inst, int location) { addDecoration(inst, kIROp_VulkanCallablePayloadDecoration, getIntValue(getIntType(), location)); } + void addVulkanCallablePayloadInDecoration(IRInst* inst, int location) + { + addDecoration(inst, kIROp_VulkanCallablePayloadInDecoration, getIntValue(getIntType(), location)); + } + void addVulkanHitObjectAttributesDecoration(IRInst* inst, int location) { addDecoration(inst, kIROp_VulkanHitObjectAttributesDecoration, getIntValue(getIntType(), location)); diff --git a/source/slang/slang-ir-link.cpp b/source/slang/slang-ir-link.cpp index a74c0c8f2..177cf4e9d 100644 --- a/source/slang/slang-ir-link.cpp +++ b/source/slang/slang-ir-link.cpp @@ -4,6 +4,7 @@ #include "slang-capability.h" #include "slang-ir.h" #include "slang-ir-insts.h" +#include "slang-legalize-types.h" #include "slang-mangle.h" #include "slang-ir-string-hash.h" #include "slang-ir-autodiff.h" diff --git a/source/slang/slang-ir-spirv-legalize.cpp b/source/slang/slang-ir-spirv-legalize.cpp index 4dde2a035..a7c14242b 100644 --- a/source/slang/slang-ir-spirv-legalize.cpp +++ b/source/slang/slang-ir-spirv-legalize.cpp @@ -832,9 +832,15 @@ struct SPIRVLegalizationContext : public SourceEmitterBase case kIROp_VulkanRayPayloadDecoration: storageClass = SpvStorageClassRayPayloadKHR; break; + case kIROp_VulkanRayPayloadInDecoration: + storageClass = SpvStorageClassIncomingRayPayloadKHR; + break; case kIROp_VulkanCallablePayloadDecoration: storageClass = SpvStorageClassCallableDataKHR; break; + case kIROp_VulkanCallablePayloadInDecoration: + storageClass = SpvStorageClassIncomingCallableDataKHR; + break; case kIROp_VulkanHitObjectAttributesDecoration: storageClass = SpvStorageClassHitObjectAttributeNV; break; diff --git a/source/slang/slang-ir-util.cpp b/source/slang/slang-ir-util.cpp index d66c8d0be..2f059d308 100644 --- a/source/slang/slang-ir-util.cpp +++ b/source/slang/slang-ir-util.cpp @@ -1093,7 +1093,9 @@ IRInst* getVulkanPayloadLocation(IRInst* payloadGlobalVar) switch (decor->getOp()) { case kIROp_VulkanRayPayloadDecoration: + case kIROp_VulkanRayPayloadInDecoration: case kIROp_VulkanCallablePayloadDecoration: + case kIROp_VulkanCallablePayloadInDecoration: case kIROp_VulkanHitObjectAttributesDecoration: return decor->getOperand(0); default: diff --git a/source/slang/slang-ir.cpp b/source/slang/slang-ir.cpp index fdc10e774..104735c3e 100644 --- a/source/slang/slang-ir.cpp +++ b/source/slang/slang-ir.cpp @@ -74,8 +74,10 @@ namespace Slang case kIROp_TriangleInputPrimitiveTypeDecoration: case kIROp_UnsafeForceInlineEarlyDecoration: case kIROp_VulkanCallablePayloadDecoration: + case kIROp_VulkanCallablePayloadInDecoration: case kIROp_VulkanHitAttributesDecoration: case kIROp_VulkanRayPayloadDecoration: + case kIROp_VulkanRayPayloadInDecoration: case kIROp_VulkanHitObjectAttributesDecoration: { return true; @@ -5870,6 +5872,53 @@ namespace Slang return i; } + IRSPIRVAsmOperand* IRBuilder::createSPIRVAsmOperandInst(IRInst* inst) + { + SLANG_ASSERT(as<IRSPIRVAsm>(m_insertLoc.getParent())); + auto i = createInst<IRSPIRVAsmOperand>( + this, + kIROp_SPIRVAsmOperandInst, + inst->getFullType(), + inst + ); + return i; + } + IRSPIRVAsmOperand* IRBuilder::emitSPIRVAsmOperandRayPayloadFromLocation(IRInst* inst) + { + SLANG_ASSERT(as<IRSPIRVAsm>(m_insertLoc.getParent())); + auto i = createInst<IRSPIRVAsmOperand>( + this, + kIROp_SPIRVAsmOperandRayPayloadFromLocation, + inst->getFullType(), + inst + ); + addInst(i); + return i; + } + IRSPIRVAsmOperand* IRBuilder::emitSPIRVAsmOperandRayAttributeFromLocation(IRInst* inst) + { + SLANG_ASSERT(as<IRSPIRVAsm>(m_insertLoc.getParent())); + auto i = createInst<IRSPIRVAsmOperand>( + this, + kIROp_SPIRVAsmOperandRayAttributeFromLocation, + inst->getFullType(), + inst + ); + addInst(i); + return i; + } + IRSPIRVAsmOperand* IRBuilder::emitSPIRVAsmOperandRayCallableFromLocation(IRInst* inst) + { + SLANG_ASSERT(as<IRSPIRVAsm>(m_insertLoc.getParent())); + auto i = createInst<IRSPIRVAsmOperand>( + this, + kIROp_SPIRVAsmOperandRayCallableFromLocation, + inst->getFullType(), + inst + ); + addInst(i); + return i; + } IRSPIRVAsmOperand* IRBuilder::emitSPIRVAsmOperandId(IRInst* inst) { SLANG_ASSERT(as<IRSPIRVAsm>(m_insertLoc.getParent())); @@ -6892,6 +6941,21 @@ namespace Slang case kIROp_SPIRVAsmOperandInst: dumpInstExpr(context, inst->getOperand(0)); return; + case kIROp_SPIRVAsmOperandRayPayloadFromLocation: + dump(context, "__rayPayloadFromLocation("); + dumpInstExpr(context, inst->getOperand(0)); + dump(context, ")"); + return; + case kIROp_SPIRVAsmOperandRayAttributeFromLocation: + dump(context, "__rayAttributeFromLocation("); + dumpInstExpr(context, inst->getOperand(0)); + dump(context, ")"); + return; + case kIROp_SPIRVAsmOperandRayCallableFromLocation: + dump(context, "__rayCallableFromLocation("); + dumpInstExpr(context, inst->getOperand(0)); + dump(context, ")"); + return; case kIROp_SPIRVAsmOperandId: dump(context, "%"); dumpInstExpr(context, inst->getOperand(0)); diff --git a/source/slang/slang-ir.h b/source/slang/slang-ir.h index f1c079cae..eb77127c8 100644 --- a/source/slang/slang-ir.h +++ b/source/slang/slang-ir.h @@ -24,6 +24,7 @@ namespace Slang { class Decl; +class DiagnosticSink; class GenericDecl; class FuncType; class Layout; diff --git a/source/slang/slang-lower-to-ir.cpp b/source/slang/slang-lower-to-ir.cpp index 6e6ba6255..4e564f703 100644 --- a/source/slang/slang-lower-to-ir.cpp +++ b/source/slang/slang-lower-to-ir.cpp @@ -2141,18 +2141,38 @@ void addVarDecorations( else if(auto rayPayloadAttr = as<VulkanRayPayloadAttribute>(mod)) { builder->addVulkanRayPayloadDecoration(inst, rayPayloadAttr->location); + // may not be referenced; adding HLSL export modifier force emits + builder->addHLSLExportDecoration(inst); + } + else if(auto rayPayloadInAttr = as<VulkanRayPayloadInAttribute>(mod)) + { + builder->addVulkanRayPayloadInDecoration(inst, rayPayloadInAttr->location); + // may not be referenced; adding HLSL export modifier force emits + builder->addHLSLExportDecoration(inst); } else if(auto callablePayloadAttr = as<VulkanCallablePayloadAttribute>(mod)) { builder->addVulkanCallablePayloadDecoration(inst, callablePayloadAttr->location); + // may not be referenced; adding HLSL export modifier force emits + builder->addHLSLExportDecoration(inst); + } + else if(auto callablePayloadInAttr = as<VulkanCallablePayloadInAttribute>(mod)) + { + builder->addVulkanCallablePayloadInDecoration(inst, callablePayloadInAttr->location); + // may not be referenced; adding HLSL export modifier force emits + builder->addHLSLExportDecoration(inst); } else if (auto hitObjectAttr = as<VulkanHitObjectAttributesAttribute>(mod)) { builder->addVulkanHitObjectAttributesDecoration(inst, hitObjectAttr->location); + // may not be referenced; adding HLSL export modifier force emits + builder->addHLSLExportDecoration(inst); } else if (as<VulkanHitAttributesAttribute>(mod)) { builder->addSimpleDecoration<IRVulkanHitAttributesDecoration>(inst); + // may not be referenced; adding HLSL export modifier force emits + builder->addHLSLExportDecoration(inst); } else if(as<GloballyCoherentModifier>(mod)) { @@ -4063,6 +4083,36 @@ struct ExprLoweringVisitorBase : public ExprVisitor<Derived, LoweredValInfo> { return builder->emitSPIRVAsmOperandEntryPoint(); } + case SPIRVAsmOperand::RayPayloadFromLocation: + { + IRInst* i; + { + IRBuilderInsertLocScope insertScope(builder); + builder->setInsertBefore(spirvAsmInst); + i = getSimpleVal(context, lowerRValueExpr(context, operand.expr)); + } + return builder->emitSPIRVAsmOperandRayPayloadFromLocation(i); + } + case SPIRVAsmOperand::RayAttributeFromLocation: + { + IRInst* i; + { + IRBuilderInsertLocScope insertScope(builder); + builder->setInsertBefore(spirvAsmInst); + i = getSimpleVal(context, lowerRValueExpr(context, operand.expr)); + } + return builder->emitSPIRVAsmOperandRayAttributeFromLocation(i); + } + case SPIRVAsmOperand::RayCallableFromLocation: + { + IRInst* i; + { + IRBuilderInsertLocScope insertScope(builder); + builder->setInsertBefore(spirvAsmInst); + i = getSimpleVal(context, lowerRValueExpr(context, operand.expr)); + } + return builder->emitSPIRVAsmOperandRayCallableFromLocation(i); + } } SLANG_UNREACHABLE("Unhandled case in visitSPIRVAsmExpr"); }; diff --git a/source/slang/slang-parser.cpp b/source/slang/slang-parser.cpp index cc87a3daa..e1dce5731 100644 --- a/source/slang/slang-parser.cpp +++ b/source/slang/slang-parser.cpp @@ -7102,6 +7102,30 @@ namespace Slang { return SPIRVAsmOperand{ SPIRVAsmOperand::NonSemanticDebugPrintfExtSet, parser->ReadToken() }; } + else if (AdvanceIf(parser, "__rayPayloadFromLocation")) + { + // reference a magic number to a layout(location) for late compiler resolution of rayPayload objects + parser->ReadToken(TokenType::LParent); + auto operand = SPIRVAsmOperand{ SPIRVAsmOperand::RayPayloadFromLocation, Token{}, parseAtomicExpr(parser) }; + parser->ReadToken(TokenType::RParent); + return operand; + } + else if (AdvanceIf(parser, "__rayAttributeFromLocation")) + { + // works similar to __rayPayloadFromLocation + parser->ReadToken(TokenType::LParent); + auto operand = SPIRVAsmOperand{ SPIRVAsmOperand::RayAttributeFromLocation, Token{}, parseAtomicExpr(parser) }; + parser->ReadToken(TokenType::RParent); + return operand; + } + else if (AdvanceIf(parser, "__rayCallableFromLocation")) + { + // works similar to __rayPayloadFromLocation + parser->ReadToken(TokenType::LParent); + auto operand = SPIRVAsmOperand{ SPIRVAsmOperand::RayCallableFromLocation, Token{}, parseAtomicExpr(parser) }; + parser->ReadToken(TokenType::RParent); + return operand; + } // A regular identifier else if(parser->LookAheadToken(TokenType::Identifier)) { @@ -7846,6 +7870,7 @@ namespace Slang #define CASE(key, type) if (nameText == #key) { modifier = parser->astBuilder->create<type>(); } else CASE(push_constant, PushConstantAttribute) CASE(shaderRecordNV, ShaderRecordAttribute) + CASE(shaderRecordEXT, ShaderRecordAttribute) CASE(constant_id, GLSLConstantIDLayoutModifier) CASE(std140, GLSLStd140Modifier) CASE(std430, GLSLStd430Modifier) @@ -7893,6 +7918,20 @@ namespace Slang parser->ReadToken(TokenType::Comma); } +#define CASE(key, type) if (AdvanceIf(parser, #key)) { auto modifier = parser->astBuilder->create<type>(); \ + modifier->location = int(getIntegerLiteralValue(listBuilder.find<GLSLLayoutModifier>()->valToken)); listBuilder.add(modifier); } else + + CASE(rayPayloadEXT, VulkanRayPayloadAttribute) + CASE(rayPayloadNV, VulkanRayPayloadAttribute) + CASE(rayPayloadInEXT, VulkanRayPayloadInAttribute) + CASE(rayPayloadInNV, VulkanRayPayloadInAttribute) + CASE(hitObjectAttributeNV, VulkanHitObjectAttributesAttribute) + CASE(callableDataEXT, VulkanCallablePayloadAttribute) + CASE(callableDataInEXT, VulkanCallablePayloadInAttribute) + {} + +#undef CASE + if (numThreadsAttrib) { listBuilder.add(numThreadsAttrib); @@ -7903,6 +7942,12 @@ namespace Slang return listBuilder.getFirst(); } + static NodeBase* parseHitAttributeEXTModifier(Parser* parser, void* /*userData*/) + { + VulkanHitAttributesAttribute* modifier = parser->astBuilder->create<VulkanHitAttributesAttribute>(); + return modifier; + } + static NodeBase* parseBuiltinTypeModifier(Parser* parser, void* /*userData*/) { BuiltinTypeModifier* modifier = parser->astBuilder->create<BuiltinTypeModifier>(); @@ -8131,7 +8176,7 @@ namespace Slang // or expect more tokens after the initial keyword. _makeParseModifier("layout", parseLayoutModifier), - + _makeParseModifier("hitAttributeEXT", parseHitAttributeEXTModifier), _makeParseModifier("__intrinsic_op", parseIntrinsicOpModifier), _makeParseModifier("__target_intrinsic", parseTargetIntrinsicModifier), _makeParseModifier("__specialized_for_target", parseSpecializedForTargetModifier), |
