diff options
| m--------- | external/glslang | 0 | ||||
| -rw-r--r-- | source/slang/core.meta.slang | 6 | ||||
| -rw-r--r-- | source/slang/core.meta.slang.h | 6 | ||||
| -rw-r--r-- | source/slang/emit.cpp | 20 | ||||
| -rw-r--r-- | source/slang/hlsl.meta.slang | 47 | ||||
| -rw-r--r-- | source/slang/hlsl.meta.slang.h | 47 | ||||
| -rw-r--r-- | source/slang/ir-insts.h | 10 | ||||
| -rw-r--r-- | source/slang/ir-serialize.cpp | 7 | ||||
| -rw-r--r-- | source/slang/ir.cpp | 54 | ||||
| -rw-r--r-- | source/slang/ir.h | 13 | ||||
| -rw-r--r-- | source/slang/lower-to-ir.cpp | 5 | ||||
| -rw-r--r-- | source/slang/modifier-defs.h | 8 | ||||
| -rw-r--r-- | tests/vkray/anyhit.slang.glsl | 10 | ||||
| -rw-r--r-- | tests/vkray/closesthit.slang.glsl | 14 | ||||
| -rw-r--r-- | tests/vkray/intersection.slang.glsl | 14 | ||||
| -rw-r--r-- | tests/vkray/miss.slang.glsl | 4 | ||||
| -rw-r--r-- | tests/vkray/raygen.slang.glsl | 146 |
17 files changed, 253 insertions, 158 deletions
diff --git a/external/glslang b/external/glslang -Subproject a8453d4bc00998049db0d448764784a6a076753 +Subproject 4207c97b938078818140edad101a032cf768191 diff --git a/source/slang/core.meta.slang b/source/slang/core.meta.slang index 0502c9bf6..26bf1112d 100644 --- a/source/slang/core.meta.slang +++ b/source/slang/core.meta.slang @@ -1238,3 +1238,9 @@ attribute_syntax [__vulkanHitAttributes] : VulkanHitAttributesAttribute; __attributeTarget(FunctionDeclBase) attribute_syntax [mutating] : MutatingAttribute; + + /// Indicates that a function computes its result as a function of its arguments without loading/storing any memory or other state. + /// + /// This is equivalent to the LLVM `readnone` function attribute. +__attributeTarget(FunctionDeclBase) +attribute_syntax [__readNone] : ReadNoneAttribute; diff --git a/source/slang/core.meta.slang.h b/source/slang/core.meta.slang.h index 97a2d1edd..5380bd90f 100644 --- a/source/slang/core.meta.slang.h +++ b/source/slang/core.meta.slang.h @@ -1256,3 +1256,9 @@ SLANG_RAW("attribute_syntax [__vulkanHitAttributes] : VulkanHitAttributesAttribu SLANG_RAW("\n") SLANG_RAW("__attributeTarget(FunctionDeclBase)\n") SLANG_RAW("attribute_syntax [mutating] : MutatingAttribute;\n") +SLANG_RAW("\n") +SLANG_RAW(" /// Indicates that a function computes its result as a function of its arguments without loading/storing any memory or other state.\n") +SLANG_RAW(" ///\n") +SLANG_RAW(" /// This is equivalent to the LLVM `readnone` function attribute.\n") +SLANG_RAW("__attributeTarget(FunctionDeclBase)\n") +SLANG_RAW("attribute_syntax [__readNone] : ReadNoneAttribute;\n") diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp index bb9a6ad8b..5c39dd50c 100644 --- a/source/slang/emit.cpp +++ b/source/slang/emit.cpp @@ -1168,8 +1168,8 @@ struct EmitVisitor switch (type->op) { case kIROp_RaytracingAccelerationStructureType: - requireGLSLExtension("GL_NVX_raytracing"); - Emit("accelerationStructureNVX"); + requireGLSLExtension("GL_NV_ray_tracing"); + Emit("accelerationStructureNV"); break; // TODO: These "translations" are obviously wrong for GLSL. @@ -3332,17 +3332,17 @@ struct EmitVisitor case 'T': { // The `$XT` case handles selecting between - // the `gl_HitTNVX` and `gl_RayTmaxNVX` builtins, + // the `gl_HitTNV` and `gl_RayTmaxNV` builtins, // based on what stage we are using: switch( ctx->shared->entryPoint->getStage() ) { default: - Emit("gl_RayTmaxNVX"); + Emit("gl_RayTmaxNV"); break; case Stage::AnyHit: case Stage::ClosestHit: - Emit("gl_HitTNVX"); + Emit("gl_HitTNV"); break; } } @@ -5363,11 +5363,11 @@ struct EmitVisitor emit("layout(location = "); Emit(getRayPayloadLocation(ctx, varDecl)); emit(")\n"); - emit("rayPayloadNVX\n"); + emit("rayPayloadNV\n"); } if(varDecl->findDecoration<IRVulkanHitAttributesDecoration>()) { - emit("hitAttributeNVX\n"); + emit("hitAttributeNV\n"); } if (!layout) @@ -5516,13 +5516,13 @@ struct EmitVisitor case LayoutResourceKind::RayPayload: { - emit("rayPayloadInNVX "); + emit("rayPayloadInNV "); } break; case LayoutResourceKind::HitAttributes: { - emit("hitAttributeNVX "); + emit("hitAttributeNV "); } break; @@ -6535,7 +6535,7 @@ String emitEntryPoint( case Stage::RayGeneration: if( target == CodeGenTarget::GLSL ) { - requireGLSLExtension(&context.shared->extensionUsageTracker, "GL_NVX_raytracing"); + requireGLSLExtension(&context.shared->extensionUsageTracker, "GL_NV_ray_tracing"); requireGLSLVersionImpl(&context.shared->extensionUsageTracker, ProfileVersion::GLSL_460); } break; diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang index c666dadd3..56741f6b3 100644 --- a/source/slang/hlsl.meta.slang +++ b/source/slang/hlsl.meta.slang @@ -1369,8 +1369,8 @@ void TraceRay<payload_t>( RayDesc Ray,
inout payload_t Payload);
-__target_intrinsic(glsl, "traceNVX")
-void __traceNVX(
+__target_intrinsic(glsl, "traceNV")
+void __traceNV(
RaytracingAccelerationStructure AccelerationStructure,
uint RayFlags,
uint InstanceInclusionMask,
@@ -1391,6 +1391,7 @@ void __traceNVX( //
__generic<Payload>
__target_intrinsic(glsl, "$XP")
+[__readNone]
int __rayPayloadLocation(Payload payload);
__generic<payload_t>
@@ -1409,7 +1410,7 @@ void TraceRay( static payload_t p;
p = Payload;
- __traceNVX(
+ __traceNV(
AccelerationStructure,
RayFlags,
InstanceInclusionMask,
@@ -1427,8 +1428,8 @@ void TraceRay( // 10.3.3
bool ReportHit<A>(float tHit, uint hitKind, A attributes);
-__target_intrinsic(glsl, "reportIntersectionNVX")
-bool __reportIntersectionNVX(float tHit, uint hitKind);
+__target_intrinsic(glsl, "reportIntersectionNV")
+bool __reportIntersectionNV(float tHit, uint hitKind);
__generic<A>
__specialized_for_target(glsl)
@@ -1438,15 +1439,15 @@ bool ReportHit(float tHit, uint hitKind, A attributes) static A a;
a = attributes;
- return __reportIntersectionNVX(tHit, hitKind);
+ return __reportIntersectionNV(tHit, hitKind);
}
// 10.3.4
-__target_intrinsic(glsl, ignoreIntersectionNVX)
+__target_intrinsic(glsl, ignoreIntersectionNV)
void IgnoreHit();
// 10.3.5
-__target_intrinsic(glsl, terminateRayNVX)
+__target_intrinsic(glsl, terminateRayNV)
void AcceptHitAndEndSearch();
// 10.4 - System Values and Special Semantics
@@ -1456,25 +1457,25 @@ void AcceptHitAndEndSearch(); // 10.4.1 - Ray Dispatch System Values
-__target_intrinsic(glsl, "uvec3(gl_LaunchIDNVX, 0)")
+__target_intrinsic(glsl, "(gl_LaunchIDNV)")
uint3 DispatchRaysIndex();
-__target_intrinsic(glsl, "uvec3(gl_LaunchSizeNVX, 0)")
+__target_intrinsic(glsl, "(gl_LaunchSizeNV)")
uint3 DispatchRaysDimensions();
// 10.4.2 - Ray System Values
-__target_intrinsic(glsl, "(gl_WorldRayOriginNVX)")
+__target_intrinsic(glsl, "(gl_WorldRayOriginNV)")
float3 WorldRayOrigin();
-__target_intrinsic(glsl, "(gl_WorldRayDirectionNVX)")
+__target_intrinsic(glsl, "(gl_WorldRayDirectionNV)")
float3 WorldRayDirection();
-__target_intrinsic(glsl, "(gl_RayTminNVX)")
+__target_intrinsic(glsl, "(gl_RayTminNV)")
float RayTMin();
// Note: The `RayTCurrent()` intrinsic should translate to
-// either `gl_HitTNVX` (for hit shaders) or `gl_RayTmaxNVX`
+// either `gl_HitTNV` (for hit shaders) or `gl_RayTmaxNV`
// (for intersection shaders). Right now we are handling this
// during code emission, for simplicity.
//
@@ -1486,12 +1487,12 @@ float RayTMin(); __target_intrinsic(glsl, "$XT")
float RayTCurrent();
-__target_intrinsic(glsl, "(gl_RayFlagsNVX)")
+__target_intrinsic(glsl, "(gl_IncomingRayFlagsNV)")
uint RayFlags();
// 10.4.3 - Primitive/Object Space System Values
-__target_intrinsic(glsl, "(gl_InstanceCustomIndexNVX)")
+__target_intrinsic(glsl, "(gl_InstanceCustomIndexNV)")
uint InstanceIndex();
__target_intrinsic(glsl, "(gl_InstanceID)")
@@ -1500,22 +1501,22 @@ uint InstanceID(); __target_intrinsic(glsl, "(gl_PrimitiveID)")
uint PrimitiveIndex();
-__target_intrinsic(glsl, "(gl_ObjectRayOriginNVX)")
+__target_intrinsic(glsl, "(gl_ObjectRayOriginNV)")
float3 ObjectRayOrigin();
-__target_intrinsic(glsl, "(gl_ObjectRayDirectionNVX)")
+__target_intrinsic(glsl, "(gl_ObjectRayDirectionNV)")
float3 ObjectRayDirection();
-__target_intrinsic(glsl, "transpose(gl_ObjectToWorldNVX)")
+__target_intrinsic(glsl, "transpose(gl_ObjectToWorldNV)")
float3x4 ObjectToWorld3x4();
-__target_intrinsic(glsl, "transpose(gl_WorldToObjectNVX)")
+__target_intrinsic(glsl, "transpose(gl_WorldToObjectNV)")
float3x4 WorldToObject3x4();
-__target_intrinsic(glsl, "(gl_ObjectToWorldNVX)")
+__target_intrinsic(glsl, "(gl_ObjectToWorldNV)")
float4x3 ObjectToWorld4x3();
-__target_intrinsic(glsl, "(gl_WorldToObjectNVX)")
+__target_intrinsic(glsl, "(gl_WorldToObjectNV)")
float4x3 WorldToObject4x3();
// Note: The provisional DXR spec included these unadorned
@@ -1531,5 +1532,5 @@ float3x4 ObjectToWorld() { return ObjectToWorld3x4(); } float3x4 WorldToObject() { return WorldToObject3x4(); }
// 10.4.4 - Hit Specific System values
-__target_intrinsic(glsl, "(gl_HitKindNVX)")
+__target_intrinsic(glsl, "(gl_HitKindNV)")
uint HitKind();
diff --git a/source/slang/hlsl.meta.slang.h b/source/slang/hlsl.meta.slang.h index 2db710ccb..5e00c2719 100644 --- a/source/slang/hlsl.meta.slang.h +++ b/source/slang/hlsl.meta.slang.h @@ -1417,8 +1417,8 @@ SLANG_RAW(" uint MissShaderIndex,\n") SLANG_RAW(" RayDesc Ray,\n") SLANG_RAW(" inout payload_t Payload);\n") SLANG_RAW("\n") -SLANG_RAW("__target_intrinsic(glsl, \"traceNVX\")\n") -SLANG_RAW("void __traceNVX(\n") +SLANG_RAW("__target_intrinsic(glsl, \"traceNV\")\n") +SLANG_RAW("void __traceNV(\n") SLANG_RAW(" RaytracingAccelerationStructure AccelerationStructure,\n") SLANG_RAW(" uint RayFlags,\n") SLANG_RAW(" uint InstanceInclusionMask,\n") @@ -1439,6 +1439,7 @@ SLANG_RAW("// syntax works in a pinch.\n") SLANG_RAW("//\n") SLANG_RAW("__generic<Payload>\n") SLANG_RAW("__target_intrinsic(glsl, \"$XP\")\n") +SLANG_RAW("[__readNone]\n") SLANG_RAW("int __rayPayloadLocation(Payload payload);\n") SLANG_RAW("\n") SLANG_RAW("__generic<payload_t>\n") @@ -1457,7 +1458,7 @@ SLANG_RAW(" [__vulkanRayPayload]\n") SLANG_RAW(" static payload_t p;\n") SLANG_RAW("\n") SLANG_RAW(" p = Payload;\n") -SLANG_RAW(" __traceNVX(\n") +SLANG_RAW(" __traceNV(\n") SLANG_RAW(" AccelerationStructure,\n") SLANG_RAW(" RayFlags,\n") SLANG_RAW(" InstanceInclusionMask,\n") @@ -1475,8 +1476,8 @@ SLANG_RAW("\n") SLANG_RAW("// 10.3.3\n") SLANG_RAW("bool ReportHit<A>(float tHit, uint hitKind, A attributes);\n") SLANG_RAW("\n") -SLANG_RAW("__target_intrinsic(glsl, \"reportIntersectionNVX\")\n") -SLANG_RAW("bool __reportIntersectionNVX(float tHit, uint hitKind);\n") +SLANG_RAW("__target_intrinsic(glsl, \"reportIntersectionNV\")\n") +SLANG_RAW("bool __reportIntersectionNV(float tHit, uint hitKind);\n") SLANG_RAW("\n") SLANG_RAW("__generic<A>\n") SLANG_RAW("__specialized_for_target(glsl)\n") @@ -1486,15 +1487,15 @@ SLANG_RAW(" [__vulkanHitAttributes]\n") SLANG_RAW(" static A a;\n") SLANG_RAW("\n") SLANG_RAW(" a = attributes;\n") -SLANG_RAW(" return __reportIntersectionNVX(tHit, hitKind);\n") +SLANG_RAW(" return __reportIntersectionNV(tHit, hitKind);\n") SLANG_RAW("}\n") SLANG_RAW("\n") SLANG_RAW("// 10.3.4\n") -SLANG_RAW("__target_intrinsic(glsl, ignoreIntersectionNVX)\n") +SLANG_RAW("__target_intrinsic(glsl, ignoreIntersectionNV)\n") SLANG_RAW("void IgnoreHit();\n") SLANG_RAW("\n") SLANG_RAW("// 10.3.5\n") -SLANG_RAW("__target_intrinsic(glsl, terminateRayNVX)\n") +SLANG_RAW("__target_intrinsic(glsl, terminateRayNV)\n") SLANG_RAW("void AcceptHitAndEndSearch();\n") SLANG_RAW("\n") SLANG_RAW("// 10.4 - System Values and Special Semantics\n") @@ -1504,25 +1505,25 @@ SLANG_RAW("// they can only be accessed from specific stages.\n") SLANG_RAW("\n") SLANG_RAW("// 10.4.1 - Ray Dispatch System Values\n") SLANG_RAW("\n") -SLANG_RAW("__target_intrinsic(glsl, \"uvec3(gl_LaunchIDNVX, 0)\")\n") +SLANG_RAW("__target_intrinsic(glsl, \"(gl_LaunchIDNV)\")\n") SLANG_RAW("uint3 DispatchRaysIndex();\n") SLANG_RAW("\n") -SLANG_RAW("__target_intrinsic(glsl, \"uvec3(gl_LaunchSizeNVX, 0)\")\n") +SLANG_RAW("__target_intrinsic(glsl, \"(gl_LaunchSizeNV)\")\n") SLANG_RAW("uint3 DispatchRaysDimensions();\n") SLANG_RAW("\n") SLANG_RAW("// 10.4.2 - Ray System Values\n") SLANG_RAW("\n") -SLANG_RAW("__target_intrinsic(glsl, \"(gl_WorldRayOriginNVX)\")\n") +SLANG_RAW("__target_intrinsic(glsl, \"(gl_WorldRayOriginNV)\")\n") SLANG_RAW("float3 WorldRayOrigin();\n") SLANG_RAW("\n") -SLANG_RAW("__target_intrinsic(glsl, \"(gl_WorldRayDirectionNVX)\")\n") +SLANG_RAW("__target_intrinsic(glsl, \"(gl_WorldRayDirectionNV)\")\n") SLANG_RAW("float3 WorldRayDirection();\n") SLANG_RAW("\n") -SLANG_RAW("__target_intrinsic(glsl, \"(gl_RayTminNVX)\")\n") +SLANG_RAW("__target_intrinsic(glsl, \"(gl_RayTminNV)\")\n") SLANG_RAW("float RayTMin();\n") SLANG_RAW("\n") SLANG_RAW("// Note: The `RayTCurrent()` intrinsic should translate to\n") -SLANG_RAW("// either `gl_HitTNVX` (for hit shaders) or `gl_RayTmaxNVX`\n") +SLANG_RAW("// either `gl_HitTNV` (for hit shaders) or `gl_RayTmaxNV`\n") SLANG_RAW("// (for intersection shaders). Right now we are handling this\n") SLANG_RAW("// during code emission, for simplicity.\n") SLANG_RAW("//\n") @@ -1534,12 +1535,12 @@ SLANG_RAW("//\n") SLANG_RAW("__target_intrinsic(glsl, \"$XT\")\n") SLANG_RAW("float RayTCurrent();\n") SLANG_RAW("\n") -SLANG_RAW("__target_intrinsic(glsl, \"(gl_RayFlagsNVX)\")\n") +SLANG_RAW("__target_intrinsic(glsl, \"(gl_IncomingRayFlagsNV)\")\n") SLANG_RAW("uint RayFlags();\n") SLANG_RAW("\n") SLANG_RAW("// 10.4.3 - Primitive/Object Space System Values\n") SLANG_RAW("\n") -SLANG_RAW("__target_intrinsic(glsl, \"(gl_InstanceCustomIndexNVX)\")\n") +SLANG_RAW("__target_intrinsic(glsl, \"(gl_InstanceCustomIndexNV)\")\n") SLANG_RAW("uint InstanceIndex();\n") SLANG_RAW("\n") SLANG_RAW("__target_intrinsic(glsl, \"(gl_InstanceID)\")\n") @@ -1548,22 +1549,22 @@ SLANG_RAW("\n") SLANG_RAW("__target_intrinsic(glsl, \"(gl_PrimitiveID)\")\n") SLANG_RAW("uint PrimitiveIndex();\n") SLANG_RAW("\n") -SLANG_RAW("__target_intrinsic(glsl, \"(gl_ObjectRayOriginNVX)\")\n") +SLANG_RAW("__target_intrinsic(glsl, \"(gl_ObjectRayOriginNV)\")\n") SLANG_RAW("float3 ObjectRayOrigin();\n") SLANG_RAW("\n") -SLANG_RAW("__target_intrinsic(glsl, \"(gl_ObjectRayDirectionNVX)\")\n") +SLANG_RAW("__target_intrinsic(glsl, \"(gl_ObjectRayDirectionNV)\")\n") SLANG_RAW("float3 ObjectRayDirection();\n") SLANG_RAW("\n") -SLANG_RAW("__target_intrinsic(glsl, \"transpose(gl_ObjectToWorldNVX)\")\n") +SLANG_RAW("__target_intrinsic(glsl, \"transpose(gl_ObjectToWorldNV)\")\n") SLANG_RAW("float3x4 ObjectToWorld3x4();\n") SLANG_RAW("\n") -SLANG_RAW("__target_intrinsic(glsl, \"transpose(gl_WorldToObjectNVX)\")\n") +SLANG_RAW("__target_intrinsic(glsl, \"transpose(gl_WorldToObjectNV)\")\n") SLANG_RAW("float3x4 WorldToObject3x4();\n") SLANG_RAW("\n") -SLANG_RAW("__target_intrinsic(glsl, \"(gl_ObjectToWorldNVX)\")\n") +SLANG_RAW("__target_intrinsic(glsl, \"(gl_ObjectToWorldNV)\")\n") SLANG_RAW("float4x3 ObjectToWorld4x3();\n") SLANG_RAW("\n") -SLANG_RAW("__target_intrinsic(glsl, \"(gl_WorldToObjectNVX)\")\n") +SLANG_RAW("__target_intrinsic(glsl, \"(gl_WorldToObjectNV)\")\n") SLANG_RAW("float4x3 WorldToObject4x3();\n") SLANG_RAW("\n") SLANG_RAW("// Note: The provisional DXR spec included these unadorned\n") @@ -1579,5 +1580,5 @@ SLANG_RAW("float3x4 ObjectToWorld() { return ObjectToWorld3x4(); }\n") SLANG_RAW("float3x4 WorldToObject() { return WorldToObject3x4(); }\n") SLANG_RAW("\n") SLANG_RAW("// 10.4.4 - Hit Specific System values\n") -SLANG_RAW("__target_intrinsic(glsl, \"(gl_HitKindNVX)\")\n") +SLANG_RAW("__target_intrinsic(glsl, \"(gl_HitKindNV)\")\n") SLANG_RAW("uint HitKind();\n") diff --git a/source/slang/ir-insts.h b/source/slang/ir-insts.h index 6075c247c..db61cae88 100644 --- a/source/slang/ir-insts.h +++ b/source/slang/ir-insts.h @@ -147,6 +147,11 @@ struct IRRequireGLSLExtensionDecoration : IRDecoration StringRepresentation* extensionName; }; +struct IRReadNoneDecoration : IRDecoration +{ + enum { kDecorationOp = kIRDecorationOp_ReadNone }; +}; + // An instruction that specializes another IR value // (representing a generic) to a particular set of generic arguments // (instructions representing types, witness tables, etc.) @@ -187,6 +192,11 @@ struct IRLookupWitnessTable : IRInst struct IRCall : IRInst { IRUse func; + + IRInst* getCallee() { return getOperand(0); } + + UInt getArgCount() { return getOperandCount() - 1; } + IRInst* getArg(UInt index) { return getOperand(index + 1); } }; struct IRLoad : IRInst diff --git a/source/slang/ir-serialize.cpp b/source/slang/ir-serialize.cpp index e2fd6d3f8..7cc3d6384 100644 --- a/source/slang/ir-serialize.cpp +++ b/source/slang/ir-serialize.cpp @@ -705,6 +705,7 @@ Result IRSerialWriter::write(IRModule* module, SourceManager* sourceManager, Opt } case kIRDecorationOp_VulkanRayPayload: case kIRDecorationOp_VulkanHitAttributes: + case kIRDecorationOp_ReadNone: { dstInst.m_payloadType = PayloadType::Empty; break; @@ -1579,6 +1580,12 @@ IRDecoration* IRSerialReader::_createDecoration(const Ser::Inst& srcInst) decor->languageVersion = Int(srcInst.m_payload.m_uint32); return decor; } + case kIRDecorationOp_ReadNone: + { + auto decor = createEmptyDecoration<IRReadNoneDecoration>(m_module); + SLANG_ASSERT(srcInst.m_payloadType == PayloadType::Empty); + return decor; + } default: { SLANG_ASSERT(!"Unhandled decoration type"); diff --git a/source/slang/ir.cpp b/source/slang/ir.cpp index cc3350aef..a66b26e93 100644 --- a/source/slang/ir.cpp +++ b/source/slang/ir.cpp @@ -2939,6 +2939,11 @@ namespace Slang dump(context, "\n[__vulkanHitAttributes]"); } break; + case kIRDecorationOp_ReadNone: + { + dump(context, "\n[__readNone]"); + } + break; } } } @@ -3521,7 +3526,30 @@ namespace Slang return true; case kIROp_Call: - // This is the most interesting. + { + // In the general case, a function call must be assumed to + // have almost arbitrary side effects. + // + // However, it is possible that the callee can be identified, + // and it may be a function with an attribute that explicitly + // limits the side effects it is allowed to have. + // + // For now, we will explicitly check for the `[__readNone]` + // attribute, which was used to mark functions that compute + // their result strictly as a function of the arguments (and + // not anything they point to, or other non-argument state). + // Calls to such functions cannot have side effects (except + // for things like stack overflow that abstract language models + // tend to ignore), and can be subject to dead code elimination, + // common subexpression elimination, etc. + // + auto call = cast<IRCall>(this); + auto callee = getResolvedInstForDecorations(call->getCallee()); + if(callee->findDecoration<IRReadNoneDecoration>()) + { + return false; + } + } return true; case kIROp_Nop: @@ -5371,6 +5399,12 @@ namespace Slang } break; + case kIRDecorationOp_ReadNone: + { + context->builder->addDecoration<IRReadNoneDecoration>(clonedValue); + } + break; + default: // Don't clone any decorations we don't understand. break; @@ -6005,6 +6039,24 @@ namespace Slang return val; } + IRInst* getResolvedInstForDecorations(IRInst* inst) + { + IRInst* candidate = inst; + while(auto specInst = as<IRSpecialize>(candidate)) + { + auto genericInst = as<IRGeneric>(specInst->getBase()); + if(!genericInst) + break; + + auto returnVal = findGenericReturnVal(genericInst); + if(!returnVal) + break; + + candidate = returnVal; + } + return candidate; + } + bool isDefinition( IRGlobalValue* inVal) { diff --git a/source/slang/ir.h b/source/slang/ir.h index 41c9ab6ab..def68098d 100644 --- a/source/slang/ir.h +++ b/source/slang/ir.h @@ -157,8 +157,9 @@ enum IRDecorationOp : uint16_t kIRDecorationOp_VulkanHitAttributes, kIRDecorationOp_RequireGLSLVersion, kIRDecorationOp_RequireGLSLExtension, - - kIRDecorationOp_CountOf + kIRDecorationOp_ReadNone, + + kIRDecorationOp_CountOf }; // represents an object allocated in an IR memory arena @@ -1048,6 +1049,14 @@ struct IRGeneric : IRGlobalValueWithParams // a pass can glean information from it. IRInst* findGenericReturnVal(IRGeneric* generic); +// Resolve an instruction that might reference a static definition +// to the most specific IR node possible, so that we can read +// decorations from it (e.g., if this is a `specialize` instruction, +// then try to chase down the generic being specialized, and what +// it seems to return). +// +IRInst* getResolvedInstForDecorations(IRInst* inst); + // The IR module itself is represented as an instruction, which // serves at the root of the tree of all instructions in the module. struct IRModuleInst : IRParentInst diff --git a/source/slang/lower-to-ir.cpp b/source/slang/lower-to-ir.cpp index 806654ccb..815822495 100644 --- a/source/slang/lower-to-ir.cpp +++ b/source/slang/lower-to-ir.cpp @@ -5137,6 +5137,11 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo> decoration->languageVersion = Int(getIntegerLiteralValue(versionMod->versionNumberToken)); } + if(decl->FindModifier<ReadNoneAttribute>()) + { + getBuilder()->addDecoration<IRReadNoneDecoration>(irFunc); + } + // For convenience, ensure that any additional global // values that were emitted while outputting the function // body appear before the function itself in the list diff --git a/source/slang/modifier-defs.h b/source/slang/modifier-defs.h index dc4e99cdd..bb9aefcb7 100644 --- a/source/slang/modifier-defs.h +++ b/source/slang/modifier-defs.h @@ -405,6 +405,14 @@ SIMPLE_SYNTAX_CLASS(VulkanHitAttributesAttribute, Attribute) // SIMPLE_SYNTAX_CLASS(MutatingAttribute, Attribute) +// A `[__readNone]` attribute, which indicates that a function +// computes its results strictly based on argument values, without +// reading or writing through any pointer arguments, or any other +// state that could be observed by a caller. +// +SIMPLE_SYNTAX_CLASS(ReadNoneAttribute, Attribute) + + // HLSL modifiers for geometry shader input topology SIMPLE_SYNTAX_CLASS(HLSLGeometryShaderInputPrimitiveTypeModifier, Modifier) SIMPLE_SYNTAX_CLASS(HLSLPointModifier , HLSLGeometryShaderInputPrimitiveTypeModifier) diff --git a/tests/vkray/anyhit.slang.glsl b/tests/vkray/anyhit.slang.glsl index 7fb9ac553..43fd29e01 100644 --- a/tests/vkray/anyhit.slang.glsl +++ b/tests/vkray/anyhit.slang.glsl @@ -1,6 +1,6 @@ // anyhit.slang.glsl #version 460 -#extension GL_NVX_raytracing : require +#extension GL_NV_ray_tracing : require struct Params_0 { @@ -23,13 +23,13 @@ struct SphereHitAttributes_0 { vec3 normal_0; }; -hitAttributeNVX SphereHitAttributes_0 _S2; +hitAttributeNV SphereHitAttributes_0 _S2; struct ShadowRay_0 { vec4 hitDistance_0; }; -rayPayloadInNVX ShadowRay_0 _S3; +rayPayloadInNV ShadowRay_0 _S3; void main() { @@ -45,11 +45,11 @@ void main() if(val_0 > float(0)) { - terminateRayNVX(); + terminateRayNV(); } else { - ignoreIntersectionNVX(); + ignoreIntersectionNV(); } } diff --git a/tests/vkray/closesthit.slang.glsl b/tests/vkray/closesthit.slang.glsl index 2db319a7f..d4b9e7a6a 100644 --- a/tests/vkray/closesthit.slang.glsl +++ b/tests/vkray/closesthit.slang.glsl @@ -1,6 +1,6 @@ // closesthit.slang.glsl #version 460 -#extension GL_NVX_raytracing : require +#extension GL_NV_ray_tracing : require layout(std430) buffer _S1 { @@ -12,32 +12,32 @@ struct BuiltInTriangleIntersectionAttributes_0 vec2 barycentrics_0; }; -hitAttributeNVX BuiltInTriangleIntersectionAttributes_0 _S2; +hitAttributeNV BuiltInTriangleIntersectionAttributes_0 _S2; struct ReflectionRay_0 { vec4 color_0; }; -rayPayloadInNVX ReflectionRay_0 _S3; +rayPayloadInNV ReflectionRay_0 _S3; void main() { BuiltInTriangleIntersectionAttributes_0 _S4 = _S2; - uint _S5 = gl_InstanceCustomIndexNVX; + uint _S5 = gl_InstanceCustomIndexNV; uint _S6 = gl_InstanceID; uint _S7 = _S5 + _S6; uint _S8 = gl_PrimitiveID; uint _S9 = _S7 + _S8; - uint _S10 = gl_HitKindNVX; + uint _S10 = gl_HitKindNV; vec4 color_1 = colors_0[_S9 + _S10]; - float _S11 = gl_HitTNVX; - float _S12 = gl_RayTminNVX; + float _S11 = gl_HitTNV; + float _S12 = gl_RayTminNV; _S3.color_0 = color_1 * (_S11 - _S12); diff --git a/tests/vkray/intersection.slang.glsl b/tests/vkray/intersection.slang.glsl index 2fb999947..cfa53efa7 100644 --- a/tests/vkray/intersection.slang.glsl +++ b/tests/vkray/intersection.slang.glsl @@ -1,7 +1,7 @@ //TEST_IGNORE_FILE: #version 460 -#extension GL_NVX_raytracing : require +#extension GL_NV_ray_tracing : require struct Sphere_0 { @@ -40,28 +40,28 @@ bool rayIntersectsSphere_0( return tHit_0 >= ray_0.TMin_0; } -hitAttributeNVX SphereHitAttributes_0 a_0; +hitAttributeNV SphereHitAttributes_0 a_0; bool ReportHit_0(float tHit_1, uint hitKind_0, SphereHitAttributes_0 attributes_0) { a_0 = attributes_0; - bool _S1 = reportIntersectionNVX(tHit_1, hitKind_0); + bool _S1 = reportIntersectionNV(tHit_1, hitKind_0); return _S1; } void main() { RayDesc_0 ray_1; - vec3 _S2 = gl_ObjectRayOriginNVX; + vec3 _S2 = gl_ObjectRayOriginNV; ray_1.Origin_0 = _S2; - vec3 _S3 = gl_ObjectRayDirectionNVX; + vec3 _S3 = gl_ObjectRayDirectionNV; ray_1.Direction_0 = _S3; - float _S4 = gl_RayTminNVX; + float _S4 = gl_RayTminNV; ray_1.TMin_0 = _S4; - float _S5 = gl_RayTmaxNVX; + float _S5 = gl_RayTmaxNV; ray_1.TMax_0 = _S5; diff --git a/tests/vkray/miss.slang.glsl b/tests/vkray/miss.slang.glsl index 7ced92c24..33cff4a34 100644 --- a/tests/vkray/miss.slang.glsl +++ b/tests/vkray/miss.slang.glsl @@ -1,14 +1,14 @@ //TEST_IGNORE_FILE: #version 460 -#extension GL_NVX_raytracing : require +#extension GL_NV_ray_tracing : require struct ShadowRay_0 { float hitDistance_0; }; -rayPayloadInNVX ShadowRay_0 _S1; +rayPayloadInNV ShadowRay_0 _S1; void main() { diff --git a/tests/vkray/raygen.slang.glsl b/tests/vkray/raygen.slang.glsl index 2df4b9219..512215a73 100644 --- a/tests/vkray/raygen.slang.glsl +++ b/tests/vkray/raygen.slang.glsl @@ -1,7 +1,7 @@ //TEST_IGNORE_FILE: #version 460 -#extension GL_NVX_raytracing : require +#extension GL_NV_ray_tracing : require #define TRACING_EPSILON 1e-6 @@ -26,19 +26,19 @@ layout(std140) uniform ubo_0 layout(row_major) mat4x4 model_0; }; -layout(binding = 5) uniform accelerationStructureNVX as_0; +layout(binding = 5) uniform accelerationStructureNV as_0; struct ShadowRay_0 { float hitDistance_0; }; -layout(location = 0) rayPayloadNVX ShadowRay_0 p_0; +layout(location = 0) rayPayloadNV ShadowRay_0 p_0; struct ReflectionRay_0 { float color_1; }; -layout(location = 1) rayPayloadNVX ReflectionRay_0 p_1; +layout(location = 1) rayPayloadNV ReflectionRay_0 p_1; layout(rgba32f) layout(binding = 4) uniform image2D outputImage_0; @@ -51,7 +51,7 @@ struct RayDesc_0 }; void TraceRay_0( - accelerationStructureNVX AccelerationStructure_0, + accelerationStructureNV AccelerationStructure_0, uint RayFlags_0, uint InstanceInclusionMask_0, uint RayContributionToHitGroupIndex_0, @@ -61,35 +61,30 @@ void TraceRay_0( inout ShadowRay_0 Payload_0) { p_0 = Payload_0; - vec3 _S1 = Ray_0.Origin_0; - float _S2 = Ray_0.TMin_0; - vec3 _S3 = Ray_0.Direction_0; - float _S4 = Ray_0.TMax_0; - int _S5 = 0; - traceNVX( + traceNV( AccelerationStructure_0, RayFlags_0, InstanceInclusionMask_0, RayContributionToHitGroupIndex_0, MultiplierForGeometryContributionToHitGroupIndex_0, MissShaderIndex_0, - _S1, - _S2, - _S3, - _S4, - _S5); + Ray_0.Origin_0, + Ray_0.TMin_0, + Ray_0.Direction_0, + Ray_0.TMax_0, + 0); Payload_0 = p_0; return; } float saturate_0(float x_0) { - float _S6 = clamp(x_0, float(0), float(1)); - return _S6; + float _S1 = clamp(x_0, float(0), float(1)); + return _S1; } void TraceRay_1( - accelerationStructureNVX AccelerationStructure_1, + accelerationStructureNV AccelerationStructure_1, uint RayFlags_1, uint InstanceInclusionMask_1, uint RayContributionToHitGroupIndex_1, @@ -99,23 +94,18 @@ void TraceRay_1( inout ReflectionRay_0 Payload_1) { p_1 = Payload_1; - vec3 _S7 = Ray_1.Origin_0; - float _S8 = Ray_1.TMin_0; - vec3 _S9 = Ray_1.Direction_0; - float _S10 = Ray_1.TMax_0; - int _S11 = 1; - traceNVX( + traceNV( AccelerationStructure_1, RayFlags_1, InstanceInclusionMask_1, RayContributionToHitGroupIndex_1, MultiplierForGeometryContributionToHitGroupIndex_1, MissShaderIndex_1, - _S7, - _S8, - _S9, - _S10, - _S11); + Ray_1.Origin_0, + Ray_1.TMin_0, + Ray_1.Direction_0, + Ray_1.TMax_0, + 1); Payload_1 = p_1; return; } @@ -124,27 +114,27 @@ void main() { float atten_0; - uvec3 _S12 = uvec3(gl_LaunchIDNVX, 0); - float _S13 = float(_S12.x) + 0.5; - uvec3 _S14 = uvec3(gl_LaunchSizeNVX, 0); - float _S15 = _S13 / float(_S14.x); - uvec3 _S16 = uvec3(gl_LaunchIDNVX, 0); - float _S17 = float(_S16.y) + 0.5; - uvec3 _S18 = uvec3(gl_LaunchSizeNVX, 0); - float _S19 = _S17 / float(_S18.y); - vec2 inUV_0 = vec2(_S15, _S19); + uvec3 _S2 = gl_LaunchIDNV; + float _S3 = float(_S2.x) + 0.5; + uvec3 _S4 = gl_LaunchSizeNV; + float _S5 = _S3 / float(_S4.x); + uvec3 _S6 = gl_LaunchIDNV; + float _S7 = float(_S6.y) + 0.5; + uvec3 _S8 = gl_LaunchSizeNV; + float _S9 = _S7 / float(_S8.y); + vec2 inUV_0 = vec2(_S5, _S9); - vec4 _S20 = texture(sampler2D(samplerPosition_0, sampler_0), inUV_0); - vec3 P_0 = _S20.xyz; + vec4 _S10 = texture(sampler2D(samplerPosition_0, sampler_0), inUV_0); + vec3 P_0 = _S10.xyz; - vec4 _S21 = texture(sampler2D(samplerNormal_0, sampler_0), inUV_0); - vec3 N_0 = _S21.xyz * 2.0 - 1.0; + vec4 _S11 = texture(sampler2D(samplerNormal_0, sampler_0), inUV_0); + vec3 N_0 = _S11.xyz * 2.0 - 1.0; vec3 lightDelta_0 = light_0.position_0.xyz - P_0; float lightDist_0 = length(lightDelta_0); vec3 L_0 = normalize(lightDelta_0); - float _S22 = 1.0 / (lightDist_0 * lightDist_0); + float _S12 = 1.0 / (lightDist_0 * lightDist_0); RayDesc_0 ray_0; ray_0.Origin_0 = P_0; @@ -154,47 +144,47 @@ void main() ShadowRay_0 shadowRay_0; shadowRay_0.hitDistance_0 = float(0); - const uint _S23 = uint(1); - const uint _S24 = uint(0xFF); - const uint _S25 = uint(0); - const uint _S26 = uint(0); - const uint _S27 = uint(2); - - RayDesc_0 _S28 = ray_0; - ShadowRay_0 _S29; - _S29 = shadowRay_0; - TraceRay_0(as_0, _S23, _S24, _S25, _S26, _S27, _S28, _S29); - shadowRay_0 = _S29; - - bool _S30 = shadowRay_0.hitDistance_0 < lightDist_0; + const uint _S13 = uint(1); + const uint _S14 = uint(0xFF); + const uint _S15 = uint(0); + const uint _S16 = uint(0); + const uint _S17 = uint(2); + + RayDesc_0 _S18 = ray_0; + ShadowRay_0 _S19; + _S19 = shadowRay_0; + TraceRay_0(as_0, _S13, _S14, _S15, _S16, _S17, _S18, _S19); + shadowRay_0 = _S19; + + bool _S20 = shadowRay_0.hitDistance_0 < lightDist_0; ReflectionRay_0 reflectionRay_0; - if(_S30) + if(_S20) { atten_0 = (0.00000000000000000000); } else { - atten_0 = _S22; + atten_0 = _S12; } - vec3 _S31 = light_0.color_0.xyz; - float _S32 = dot(N_0, L_0); - float _S33 = saturate_0(_S32); - vec3 color_2 = (_S31 * _S33) * atten_0; - - const uint _S34 = uint(1); - const uint _S35 = uint(255); - const uint _S36 = uint(0); - const uint _S37 = uint(0); - const uint _S38 = uint(2); - RayDesc_0 _S39 = ray_0; - ReflectionRay_0 _S40; - _S40 = reflectionRay_0; - TraceRay_1(as_0, _S34, _S35, _S36, _S37, _S38, _S39, _S40); - - vec3 color_3 = color_2 + _S40.color_1; - - uvec3 _S41 = uvec3(gl_LaunchIDNVX, 0); - imageStore(outputImage_0, ivec2(uvec2(ivec2(_S41.xy))), vec4(color_3, 1.0)); + vec3 _S21 = light_0.color_0.xyz; + float _S22 = dot(N_0, L_0); + float _S23 = saturate_0(_S22); + vec3 color_2 = (_S21 * _S23) * atten_0; + + const uint _S24 = uint(1); + const uint _S25 = uint(255); + const uint _S26 = uint(0); + const uint _S27 = uint(0); + const uint _S28 = uint(2); + RayDesc_0 _S29 = ray_0; + ReflectionRay_0 _S30; + _S30 = reflectionRay_0; + TraceRay_1(as_0, _S24, _S25, _S26, _S27, _S28, _S29, _S30); + + vec3 color_3 = color_2 + _S30.color_1; + + uvec3 _S31 = gl_LaunchIDNV; + imageStore(outputImage_0, ivec2(uvec2(ivec2(_S31.xy))), vec4(color_3, 1.0)); return; } |
