summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--slang.h6
-rw-r--r--source/slang/check.cpp16
-rw-r--r--source/slang/emit.cpp25
-rw-r--r--source/slang/hlsl.meta.slang109
-rw-r--r--source/slang/hlsl.meta.slang.h109
-rw-r--r--source/slang/profile-defs.h33
-rw-r--r--source/slang/profile.h11
-rw-r--r--source/slang/slang.cpp35
8 files changed, 314 insertions, 30 deletions
diff --git a/slang.h b/slang.h
index f1293f0e0..c3c87e9a8 100644
--- a/slang.h
+++ b/slang.h
@@ -626,6 +626,12 @@ extern "C"
SLANG_STAGE_GEOMETRY,
SLANG_STAGE_FRAGMENT,
SLANG_STAGE_COMPUTE,
+ SLANG_STAGE_RAY_GENERATION,
+ SLANG_STAGE_INTERSECTION,
+ SLANG_STAGE_ANY_HIT,
+ SLANG_STAGE_CLOSEST_HIT,
+ SLANG_STAGE_MISS,
+ SLANG_STAGE_CALLABLE,
// alias:
SLANG_STAGE_PIXEL = SLANG_STAGE_FRAGMENT,
diff --git a/source/slang/check.cpp b/source/slang/check.cpp
index 070d4c606..dbd9b37b7 100644
--- a/source/slang/check.cpp
+++ b/source/slang/check.cpp
@@ -1488,15 +1488,13 @@ namespace Slang
Stage stage;
} kStages[] =
{
- { "vertex", Stage::Vertex },
- { "hull", Stage::Hull },
- { "domain", Stage::Domain },
- { "geometry", Stage::Geometry },
- { "fragment", Stage::Fragment },
- { "compute", Stage::Compute },
-
- // Allow `pixel` as an alias of `fragment`
- { "pixel", Stage::Fragment },
+ #define PROFILE_STAGE(ID, NAME, ENUM) \
+ { #NAME, Stage::ID },
+
+ #define PROFILE_STAGE_ALIAS(ID, NAME, VAL) \
+ { #NAME, Stage::ID },
+
+ #include "profile-defs.h"
};
for(auto entry : kStages)
diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp
index ace8a1559..98ce61b74 100644
--- a/source/slang/emit.cpp
+++ b/source/slang/emit.cpp
@@ -127,7 +127,7 @@ struct SharedEmitContext
// The "effective" profile that is being used to emit code,
// combining information from the target and entry point.
- Profile effctiveProfile;
+ Profile effectiveProfile;
};
struct EmitContext
@@ -4368,10 +4368,10 @@ struct EmitVisitor
}
#endif
- auto effctiveProfile = context->shared->effctiveProfile;
- if(effctiveProfile.getFamily() == ProfileFamily::GLSL)
+ auto effectiveProfile = context->shared->effectiveProfile;
+ if(effectiveProfile.getFamily() == ProfileFamily::GLSL)
{
- requireGLSLVersion(effctiveProfile.GetVersion());
+ requireGLSLVersion(effectiveProfile.GetVersion());
}
// HACK: We aren't picking GLSL versions carefully right now,
@@ -6746,10 +6746,10 @@ emitDeclImpl(decl, nullptr);
}
void emitIREntryPointAttributes_HLSL(
- EmitContext* /*ctx*/,
+ EmitContext* ctx,
EntryPointLayout* entryPointLayout)
{
- auto profile = entryPointLayout->profile;
+ auto profile = ctx->shared->effectiveProfile;
auto stage = profile.GetStage();
if(profile.getFamily() == ProfileFamily::DX)
@@ -6759,12 +6759,11 @@ emitDeclImpl(decl, nullptr);
char const* stageName = nullptr;
switch(stage)
{
- case Stage::Compute: stageName = "compute";
- case Stage::Vertex: stageName = "vertex";
- case Stage::Hull: stageName = "hull";
- case Stage::Domain: stageName = "domain";
- case Stage::Geometry: stageName = "geometry";
- case Stage::Fragment: stageName = "pixel";
+ #define PROFILE_STAGE(ID, NAME, ENUM) \
+ case Stage::ID: stageName = #NAME; break;
+
+ #include "profile-defs.h"
+
default:
break;
}
@@ -8230,7 +8229,7 @@ String emitEntryPoint(
sharedContext.target = target;
sharedContext.finalTarget = targetRequest->target;
sharedContext.entryPoint = entryPoint;
- sharedContext.effctiveProfile = getEffectiveProfile(entryPoint, targetRequest);
+ sharedContext.effectiveProfile = getEffectiveProfile(entryPoint, targetRequest);
if (entryPoint)
{
diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang
index 15579e512..7356eccbe 100644
--- a/source/slang/hlsl.meta.slang
+++ b/source/slang/hlsl.meta.slang
@@ -1121,3 +1121,112 @@ for (int aa = 0; aa < kBaseBufferAccessLevelCount; ++aa)
sb << "};\n";
}
}}}}
+
+
+// DirectX Raytracing (DXR) Support
+//
+// The following is based on the experimental DXR SDK v0.09.01.
+//
+// Numbering follows the sections in the "D3D12 Raytracing Functional Spec" v0.09 (2018-03-12)
+//
+
+// 10.1.1 - Ray Flags
+
+typedef uint RAY_FLAG;
+
+static const RAY_FLAG RAY_FLAG_NONE = 0x00;
+static const RAY_FLAG RAY_FLAG_FORCE_OPAQUE = 0x01;
+static const RAY_FLAG RAY_FLAG_FORCE_NON_OPAQUE = 0x02;
+static const RAY_FLAG RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH = 0x04;
+static const RAY_FLAG RAY_FLAG_SKIP_CLOSEST_HIT_SHADER = 0x08;
+static const RAY_FLAG RAY_FLAG_CULL_BACK_FACING_TRIANGLES = 0x10;
+static const RAY_FLAG RAY_FLAG_CULL_FRONT_FACING_TRIANGLES = 0x20;
+static const RAY_FLAG RAY_FLAG_CULL_OPAQUE = 0x40;
+static const RAY_FLAG RAY_FLAG_CULL_NON_OPAQUE = 0x80;
+
+// 10.1.2 - Ray Description Structure
+
+__builtin struct RayDesc
+{
+ float3 Origin;
+ float TMin;
+ float3 Direction;
+ float TMax;
+};
+
+// 10.1.3 - Ray Acceleration Structure
+
+__builtin __magic_type(UntypedBufferResourceType)
+struct RaytracingAccelerationStructure {};
+
+// 10.1.4 - Subobject Definitions
+
+// TODO: We may decide to support these, but their reliance on C++ implicit
+// constructor call syntax (`SomeType someVar(arg0, arg1);`) makes them
+// annoying for the current Slang parsing strategy, and using global variables
+// for this stuff comes across as a kludge rather than the best possible design.
+
+// 10.1.5 - Intersection Attributes Structure
+
+__builtin struct BuiltInTriangleIntersectionAttributes
+{
+ float2 barycentrics;
+};
+
+// 10.2 Shaders
+
+// Right now new shader stages need to be added directly to the compiler
+// implementation, rather than being something that can be declared in the stdlib.
+
+// 10.3 - Intrinsics
+
+// 10.3.1
+void CallShader<param_t>(uint ShaderIndex, inout param_t Parameter);
+
+// 10.3.2
+void TraceRay<payload_t>(
+ RaytracingAccelerationStructure AccelerationStructure,
+ uint RayFlags,
+ uint InstanceInclusionMask,
+ uint RayContributionToHitGroupIndex,
+ uint MultiplierForGeometryContributionToHitGroupIndex,
+ uint MissShaderIndex,
+ RayDesc Ray,
+ inout payload_t Payload);
+
+// 10.3.3
+bool ReportHit<attr_t>(float THit, uint HitKind, attr_t Attributes);
+
+// 10.3.4
+void IgnoreHit();
+
+// 10.3.5
+void AcceptHitAndEndSearch();
+
+// 10.4 - System Values and Special Semantics
+
+// TODO: Many of these functions need to be restricted so that
+// they can only be accessed from specific stages.
+
+// 10.4.1 - Ray Dispatch System Values
+uint2 DispatchRaysIndex();
+uint2 DispatchRaysDimensions();
+
+// 10.4.2 - Ray System Values
+float3 WorldRayOrigin();
+float3 WorldRayDirection();
+float RayTMin();
+float RayTCurrent();
+uint RayFlags();
+
+// 10.4.3 - Primitive/Object Space System Values
+uint InstanceIndex();
+uint InstanceID();
+uint PrimitiveIndex();
+float3 ObjectRayOrigin();
+float3 ObjectRayDirection();
+float3x4 ObjectToWorld();
+float3x4 WorldToObject();
+
+// 10.4.4 - Hit Specific System values
+uint HitKind();
diff --git a/source/slang/hlsl.meta.slang.h b/source/slang/hlsl.meta.slang.h
index d35f96ba3..134a3172f 100644
--- a/source/slang/hlsl.meta.slang.h
+++ b/source/slang/hlsl.meta.slang.h
@@ -1127,3 +1127,112 @@ for (int aa = 0; aa < kBaseBufferAccessLevelCount; ++aa)
sb << "};\n";
}
SLANG_RAW("\n")
+SLANG_RAW("\n")
+SLANG_RAW("\n")
+SLANG_RAW("// DirectX Raytracing (DXR) Support\n")
+SLANG_RAW("//\n")
+SLANG_RAW("// The following is based on the experimental DXR SDK v0.09.01.\n")
+SLANG_RAW("//\n")
+SLANG_RAW("// Numbering follows the sections in the \"D3D12 Raytracing Functional Spec\" v0.09 (2018-03-12)\n")
+SLANG_RAW("//\n")
+SLANG_RAW("\n")
+SLANG_RAW("// 10.1.1 - Ray Flags\n")
+SLANG_RAW("\n")
+SLANG_RAW("typedef uint RAY_FLAG;\n")
+SLANG_RAW("\n")
+SLANG_RAW("static const RAY_FLAG RAY_FLAG_NONE = 0x00;\n")
+SLANG_RAW("static const RAY_FLAG RAY_FLAG_FORCE_OPAQUE = 0x01;\n")
+SLANG_RAW("static const RAY_FLAG RAY_FLAG_FORCE_NON_OPAQUE = 0x02;\n")
+SLANG_RAW("static const RAY_FLAG RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH = 0x04;\n")
+SLANG_RAW("static const RAY_FLAG RAY_FLAG_SKIP_CLOSEST_HIT_SHADER = 0x08;\n")
+SLANG_RAW("static const RAY_FLAG RAY_FLAG_CULL_BACK_FACING_TRIANGLES = 0x10;\n")
+SLANG_RAW("static const RAY_FLAG RAY_FLAG_CULL_FRONT_FACING_TRIANGLES = 0x20;\n")
+SLANG_RAW("static const RAY_FLAG RAY_FLAG_CULL_OPAQUE = 0x40;\n")
+SLANG_RAW("static const RAY_FLAG RAY_FLAG_CULL_NON_OPAQUE = 0x80;\n")
+SLANG_RAW("\n")
+SLANG_RAW("// 10.1.2 - Ray Description Structure\n")
+SLANG_RAW("\n")
+SLANG_RAW("__builtin struct RayDesc\n")
+SLANG_RAW("{\n")
+SLANG_RAW(" float3 Origin;\n")
+SLANG_RAW(" float TMin;\n")
+SLANG_RAW(" float3 Direction;\n")
+SLANG_RAW(" float TMax;\n")
+SLANG_RAW("};\n")
+SLANG_RAW("\n")
+SLANG_RAW("// 10.1.3 - Ray Acceleration Structure\n")
+SLANG_RAW("\n")
+SLANG_RAW("__builtin __magic_type(UntypedBufferResourceType)\n")
+SLANG_RAW("struct RaytracingAccelerationStructure {};\n")
+SLANG_RAW("\n")
+SLANG_RAW("// 10.1.4 - Subobject Definitions\n")
+SLANG_RAW("\n")
+SLANG_RAW("// TODO: We may decide to support these, but their reliance on C++ implicit\n")
+SLANG_RAW("// constructor call syntax (`SomeType someVar(arg0, arg1);`) makes them\n")
+SLANG_RAW("// annoying for the current Slang parsing strategy, and using global variables\n")
+SLANG_RAW("// for this stuff comes across as a kludge rather than the best possible design.\n")
+SLANG_RAW("\n")
+SLANG_RAW("// 10.1.5 - Intersection Attributes Structure\n")
+SLANG_RAW("\n")
+SLANG_RAW("__builtin struct BuiltInTriangleIntersectionAttributes\n")
+SLANG_RAW("{\n")
+SLANG_RAW(" float2 barycentrics;\n")
+SLANG_RAW("};\n")
+SLANG_RAW("\n")
+SLANG_RAW("// 10.2 Shaders\n")
+SLANG_RAW("\n")
+SLANG_RAW("// Right now new shader stages need to be added directly to the compiler\n")
+SLANG_RAW("// implementation, rather than being something that can be declared in the stdlib.\n")
+SLANG_RAW("\n")
+SLANG_RAW("// 10.3 - Intrinsics\n")
+SLANG_RAW("\n")
+SLANG_RAW("// 10.3.1\n")
+SLANG_RAW("void CallShader<param_t>(uint ShaderIndex, inout param_t Parameter);\n")
+SLANG_RAW("\n")
+SLANG_RAW("// 10.3.2\n")
+SLANG_RAW("void TraceRay<payload_t>(\n")
+SLANG_RAW(" RaytracingAccelerationStructure AccelerationStructure,\n")
+SLANG_RAW(" uint RayFlags,\n")
+SLANG_RAW(" uint InstanceInclusionMask,\n")
+SLANG_RAW(" uint RayContributionToHitGroupIndex,\n")
+SLANG_RAW(" uint MultiplierForGeometryContributionToHitGroupIndex,\n")
+SLANG_RAW(" uint MissShaderIndex,\n")
+SLANG_RAW(" RayDesc Ray,\n")
+SLANG_RAW(" inout payload_t Payload);\n")
+SLANG_RAW("\n")
+SLANG_RAW("// 10.3.3\n")
+SLANG_RAW("bool ReportHit<attr_t>(float THit, uint HitKind, attr_t Attributes);\n")
+SLANG_RAW("\n")
+SLANG_RAW("// 10.3.4\n")
+SLANG_RAW("void IgnoreHit();\n")
+SLANG_RAW("\n")
+SLANG_RAW("// 10.3.5\n")
+SLANG_RAW("void AcceptHitAndEndSearch();\n")
+SLANG_RAW("\n")
+SLANG_RAW("// 10.4 - System Values and Special Semantics\n")
+SLANG_RAW("\n")
+SLANG_RAW("// TODO: Many of these functions need to be restricted so that\n")
+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("uint2 DispatchRaysIndex();\n")
+SLANG_RAW("uint2 DispatchRaysDimensions();\n")
+SLANG_RAW("\n")
+SLANG_RAW("// 10.4.2 - Ray System Values\n")
+SLANG_RAW("float3 WorldRayOrigin();\n")
+SLANG_RAW("float3 WorldRayDirection();\n")
+SLANG_RAW("float RayTMin();\n")
+SLANG_RAW("float RayTCurrent();\n")
+SLANG_RAW("uint RayFlags();\n")
+SLANG_RAW("\n")
+SLANG_RAW("// 10.4.3 - Primitive/Object Space System Values\n")
+SLANG_RAW("uint InstanceIndex();\n")
+SLANG_RAW("uint InstanceID();\n")
+SLANG_RAW("uint PrimitiveIndex();\n")
+SLANG_RAW("float3 ObjectRayOrigin();\n")
+SLANG_RAW("float3 ObjectRayDirection();\n")
+SLANG_RAW("float3x4 ObjectToWorld();\n")
+SLANG_RAW("float3x4 WorldToObject();\n")
+SLANG_RAW("\n")
+SLANG_RAW("// 10.4.4 - Hit Specific System values\n")
+SLANG_RAW("uint HitKind();\n")
diff --git a/source/slang/profile-defs.h b/source/slang/profile-defs.h
index 177c4a0c5..e7000bfa2 100644
--- a/source/slang/profile-defs.h
+++ b/source/slang/profile-defs.h
@@ -23,7 +23,7 @@
#endif
#ifndef PROFILE_STAGE_ALIAS
-#define PROFILE_STAGE_ALIAS(TAG, NAME) /* empty */
+#define PROFILE_STAGE_ALIAS(TAG, NAME, VAL) /* empty */
#endif
@@ -57,10 +57,25 @@ PROFILE_STAGE(Vertex, vertex, SLANG_STAGE_VERTEX)
PROFILE_STAGE(Hull, hull, SLANG_STAGE_HULL)
PROFILE_STAGE(Domain, domain, SLANG_STAGE_DOMAIN)
PROFILE_STAGE(Geometry, geometry, SLANG_STAGE_GEOMETRY)
-PROFILE_STAGE(Fragment, fragment, SLANG_STAGE_FRAGMENT)
+PROFILE_STAGE(Pixel, pixel, SLANG_STAGE_FRAGMENT)
PROFILE_STAGE(Compute, compute, SLANG_STAGE_COMPUTE)
-PROFILE_STAGE_ALIAS(Fragment, pixel)
+PROFILE_STAGE(RayGeneration, raygeneration, SLANG_STAGE_RAY_GENERATION)
+PROFILE_STAGE(Intersection, intersection, SLANG_STAGE_INTERSECTION)
+PROFILE_STAGE(AnyHit, anyhit, SLANG_STAGE_ANY_HIT)
+PROFILE_STAGE(ClosestHit, closesthit, SLANG_STAGE_CLOSEST_HIT)
+PROFILE_STAGE(Miss, miss, SLANG_STAGE_MISS)
+PROFILE_STAGE(Callable, callable, SLANG_STAGE_CALLABLE)
+
+
+// Note: HLSL and Direct3D convention erroneously uses the term "Pixel Shader"
+// for the thing that shades *fragments*. Slang strives to treat the more correct
+// term "Fragment Shader" as the primary one, but in order to be compatible with
+// existing HLSL conventions, we need to treat `pixel` as the official stage
+// name and `fragment` as an alias for it here, because the lower-case stage
+// names are used to drive output HLSL generation.
+//
+PROFILE_STAGE_ALIAS(Fragment, fragment, Pixel)
// Profile families
@@ -151,6 +166,18 @@ PROFILE(DX_Vertex_6_0, vs_6_0, Vertex, DX_6_0)
PROFILE(DX_Vertex_6_1, vs_6_1, Vertex, DX_6_1)
PROFILE(DX_Vertex_6_2, vs_6_2, Vertex, DX_6_2)
+// TODO: consider making `lib_*_*` alias these...
+PROFILE(DX_None_4_0, sm_4_0, Unknown, DX_4_0)
+PROFILE(DX_None_4_0_Level_9_0, sm_4_0_level_9_0, Unknown, DX_4_0_Level_9_0)
+PROFILE(DX_None_4_0_Level_9_1, sm_4_0_level_9_1, Unknown, DX_4_0_Level_9_1)
+PROFILE(DX_None_4_0_Level_9_3, sm_4_0_level_9_3, Unknown, DX_4_0_Level_9_3)
+PROFILE(DX_None_4_1, sm_4_1, Unknown, DX_4_1)
+PROFILE(DX_None_5_0, sm_5_0, Unknown, DX_5_0)
+PROFILE(DX_None_5_1, sm_5_1, Unknown, DX_5_1)
+PROFILE(DX_None_6_0, sm_6_0, Unknown, DX_6_0)
+PROFILE(DX_None_6_1, sm_6_1, Unknown, DX_6_1)
+PROFILE(DX_None_6_2, sm_6_2, Unknown, DX_6_2)
+
// Define all the GLSL profiles
#define P(UPPER, LOWER, VERSION) \
diff --git a/source/slang/profile.h b/source/slang/profile.h
index d6a2a39af..ceccf20a9 100644
--- a/source/slang/profile.h
+++ b/source/slang/profile.h
@@ -41,6 +41,7 @@ namespace Slang
{
Unknown = SLANG_STAGE_NONE,
#define PROFILE_STAGE(TAG, NAME, VAL) TAG = VAL,
+#define PROFILE_STAGE_ALIAS(TAG, NAME, VAL) TAG = VAL,
#include "profile-defs.h"
};
@@ -53,7 +54,7 @@ namespace Slang
{
Unknown,
-#define PROFILE(TAG, NAME, STAGE, VERSION) TAG = (uint32_t(Stage::STAGE) << 16) | uint32_t(ProfileVersion::VERSION),
+#define PROFILE(TAG, NAME, STAGE, VERSION) TAG = (uint32_t(ProfileVersion::VERSION) << 16) | uint32_t(Stage::STAGE),
#define PROFILE_ALIAS(TAG, DEF, NAME) TAG = DEF,
#include "profile-defs.h"
};
@@ -66,16 +67,16 @@ namespace Slang
bool operator==(Profile const& other) const { return raw == other.raw; }
bool operator!=(Profile const& other) const { return raw != other.raw; }
- Stage GetStage() const { return Stage((uint32_t(raw) >> 16) & 0xFFFF); }
+ Stage GetStage() const { return Stage(uint32_t(raw) & 0xFFFF); }
void setStage(Stage stage)
{
- raw = (raw & 0x0000FFFF) | (uint32_t(stage) << 16);
+ raw = (raw & ~0xFFFF) | uint32_t(stage);
}
- ProfileVersion GetVersion() const { return ProfileVersion(uint32_t(raw) & 0xFFFF); }
+ ProfileVersion GetVersion() const { return ProfileVersion((uint32_t(raw) >> 16) & 0xFFFF); }
void setVersion(ProfileVersion version)
{
- raw = (raw & ~0xFFFF) | uint32_t(version);
+ raw = (raw & 0x0000FFFF) | (uint32_t(version) << 16);
}
ProfileFamily getFamily() const { return getProfileFamily(GetVersion()); }
diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp
index 4fa6f5130..2861b82ca 100644
--- a/source/slang/slang.cpp
+++ b/source/slang/slang.cpp
@@ -138,6 +138,41 @@ Profile getEffectiveProfile(EntryPointRequest* entryPoint, TargetRequest* target
}
}
+ // Now consider the possibility that the chosen stage might force an "upgrade"
+ // to the profile level.
+ ProfileVersion stageMinVersion = ProfileVersion::Unknown;
+ switch( effectiveProfile.getFamily() )
+ {
+ case ProfileFamily::DX:
+ switch(effectiveProfile.GetStage())
+ {
+ default:
+ break;
+
+ case Stage::RayGeneration:
+ case Stage::Intersection:
+ case Stage::ClosestHit:
+ case Stage::AnyHit:
+ case Stage::Miss:
+ case Stage::Callable:
+ stageMinVersion = ProfileVersion::DX_6_1;
+ break;
+
+ // TODO: Add equivalent logic for geometry, tessellation, and compute stages.
+ }
+ break;
+
+ // TODO: Add equivalent logic for the GL/VK case.
+
+ default:
+ break;
+ }
+
+ if( stageMinVersion > effectiveProfile.GetVersion() )
+ {
+ effectiveProfile.setVersion(stageMinVersion);
+ }
+
return effectiveProfile;
}