diff options
| -rw-r--r-- | slang.h | 6 | ||||
| -rw-r--r-- | source/slang/check.cpp | 16 | ||||
| -rw-r--r-- | source/slang/emit.cpp | 25 | ||||
| -rw-r--r-- | source/slang/hlsl.meta.slang | 109 | ||||
| -rw-r--r-- | source/slang/hlsl.meta.slang.h | 109 | ||||
| -rw-r--r-- | source/slang/profile-defs.h | 33 | ||||
| -rw-r--r-- | source/slang/profile.h | 11 | ||||
| -rw-r--r-- | source/slang/slang.cpp | 35 |
8 files changed, 314 insertions, 30 deletions
@@ -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; } |
