summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
m---------external/glslang0
-rw-r--r--source/slang/core.meta.slang6
-rw-r--r--source/slang/core.meta.slang.h6
-rw-r--r--source/slang/emit.cpp20
-rw-r--r--source/slang/hlsl.meta.slang47
-rw-r--r--source/slang/hlsl.meta.slang.h47
-rw-r--r--source/slang/ir-insts.h10
-rw-r--r--source/slang/ir-serialize.cpp7
-rw-r--r--source/slang/ir.cpp54
-rw-r--r--source/slang/ir.h13
-rw-r--r--source/slang/lower-to-ir.cpp5
-rw-r--r--source/slang/modifier-defs.h8
-rw-r--r--tests/vkray/anyhit.slang.glsl10
-rw-r--r--tests/vkray/closesthit.slang.glsl14
-rw-r--r--tests/vkray/intersection.slang.glsl14
-rw-r--r--tests/vkray/miss.slang.glsl4
-rw-r--r--tests/vkray/raygen.slang.glsl146
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;
}