diff options
| author | Yong He <yonghe@outlook.com> | 2024-09-05 15:12:52 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-09-05 15:12:52 -0700 |
| commit | 5f1ba7b614b64d24fb45a3815a9867c68dace466 (patch) | |
| tree | 40407853a5147e415ca3ad35ed03e1dadfb75cb1 /docs | |
| parent | 313677160a186efebf83fab4df7d08dd119a5cd2 (diff) | |
Various documentation improvements. (#5017)
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/proposals/001-where-clauses.md | 144 | ||||
| -rw-r--r-- | docs/proposals/legacy/001-basic-interfaces.md (renamed from docs/proposals/001-basic-interfaces.md) | 0 | ||||
| -rw-r--r-- | docs/proposals/legacy/002-api-headers.md (renamed from docs/proposals/002-api-headers.md) | 0 | ||||
| -rw-r--r-- | docs/proposals/legacy/003-error-handling.md (renamed from docs/proposals/003-error-handling.md) | 0 | ||||
| -rw-r--r-- | docs/proposals/legacy/004-com-support.md (renamed from docs/proposals/004-com-support.md) | 0 | ||||
| -rw-r--r-- | docs/proposals/legacy/005-components.md (renamed from docs/proposals/005-components.md) | 0 | ||||
| -rw-r--r-- | docs/proposals/legacy/006-artifact-container-format.md (renamed from docs/proposals/006-artifact-container-format.md) | 0 | ||||
| -rw-r--r-- | docs/user-guide/06-interfaces-generics.md | 71 | ||||
| -rw-r--r-- | docs/user-guide/09-targets.md | 6 | ||||
| -rw-r--r-- | docs/user-guide/a2-01-spirv-target-specific.md | 30 | ||||
| -rw-r--r-- | docs/user-guide/toc.html | 4 |
11 files changed, 168 insertions, 87 deletions
diff --git a/docs/proposals/001-where-clauses.md b/docs/proposals/001-where-clauses.md index c16d283b5..086248386 100644 --- a/docs/proposals/001-where-clauses.md +++ b/docs/proposals/001-where-clauses.md @@ -6,7 +6,12 @@ We propose to allow generic declarations in Slang to move the constraints on gen Status ------ -Unimplemented. +Status: Partially implemented. The only unimplemented case is the canonicalization of generic constraints. + +Implementation: [PR 4986](https://github.com/shader-slang/slang/pull/4986) + +Reviewed by: Theresa Foley, Yong He + Background ---------- @@ -24,18 +29,17 @@ Introducing `where` clauses allows a programmer to state the constraints *after* void resolve<T, U, V>(ResolutionContext<U> context, List<T> stuffToResolve, out V destination) where T : IResolvable, - U : IResolver<T>, - V : IResolveDestination<T> + where U : IResolver<T>, + where V : IResolveDestination<T> { ... } This latter form makes it easier to quickly glean the overall shape of the function signature. -A second important benefit of `where` clauses is that they open the door to expressing more complicated constraints on and between type parameters. -While this document does not propose to allow any new forms of constraints right away, we can imagine things like allowing constraints on *associated types*, e.g.: +A second important benefit of `where` clauses is that they open the door to expressing more complicated constraints on and between type parameters, such as allowing constraints on *associated types*, e.g.: void writePackedData<T, U>(T src, out U dst) where T : IPackable, - T.Packed : IWritable<U> + where T.Packed : IWritable<U> { .. } Related Work @@ -92,12 +96,13 @@ Proposed Approach For any kind of declaration that Slang allows to have generic parameters, we will allow a `where` clause to appear after the *header* of that declaration. A `where` clause consists of the (contextual) keyword `where`, following by a comma-separated list of *constraints*: - - struct MyStuff<T> : Base, IFoo - where T : IFoo, - T : IBar +```csharp + struct MyStuff<T, U> : IFoo + where T : IFoo, IBar + where T : IBaz + where U : IArray<T> { ... } - +``` A `where` clause is only allowed after the header of a declaration that has one or more generic parameters. Each constraint must take the form of one of the type parameters from the immediately enclosing generic parameter list, followed by a colon (`:`), and then followed by a type expression that names an interface or a conjunction of interfaces. @@ -105,33 +110,49 @@ Multiple constraints can be defined for the same parameter. We haven't previously defined what the header of a declaration is, so we briefly illustrate what we mean by showing where the split between the header and the *body* of a declaration is for each of the major kinds of declarations that are supported. In each case a comment `/****/` is placed between the header and body: - // variables: - let v : Int /****/ = 99; - var v : Int /****/ = 99; - Int v /****/ = 99; - - // simple type declarations: - typealias X : IFoo /****/ = Y; - associatedtype X : IFoo /****/; - - // functions and other callables: - Int f(Float y) /****/ { ... } - func f(Float y) -> Int /****/ { ... } - init(Float y) /****/ { ... } - subscript(Int idx) -> Float /****/ { ... } - - // properties - property p : Int /****/ { ... } - - // aggregates - extension Int : IFoo /****/ { ... } - struct Thing : Base /****/ { ... } - class Thing : Base /****/ { ... } - interface IThing : IBase /****/ { ... } - enum Stuff : Int /****/ { ... } - +```csharp +// variables: +let v : Int /****/ = 99; +var v : Int /****/ = 99; +Int v /****/ = 99; + +// simple type declarations: +typealias X : IFoo /****/ = Y; +associatedtype X : IFoo /****/; + +// functions and other callables: +Int f(Float y) /****/ { ... } +func f(Float y) -> Int /****/ { ... } +init(Float y) /****/ { ... } +subscript(Int idx) -> Float /****/ { ... } + +// properties +property p : Int /****/ { ... } + +// aggregates +extension Int : IFoo /****/ { ... } +struct Thing : Base /****/ { ... } +class Thing : Base /****/ { ... } +interface IThing : IBase /****/ { ... } +enum Stuff : Int /****/ { ... } +``` In practice, the body of a declaration starts at the `=` for declarations with an initial-value expression, at the opening `{` for declarations with a `{}`-enclosed body, or at the closing `;` for any other declarations. +With introduction of `where` clauses, we can extend type system to allow more kinds of type constraints. In this proposal, +we allow type constraints followed by `where` to be one of: +- Type conformance constraint, in the form of `T : IBase` +- Type equality constraint, in the form of `T == X` + +In both cases, the left hand side of a constraint can be a simple generic type parameter, or any types that are dependent on some +generic type parameter. For example, the following is allowed: +```csharp +interface IFoo { associatedtype A; } +struct S<T, U> + where T : IFoo + where T.A == U +{} +``` + Detailed Explanation -------------------- @@ -241,37 +262,18 @@ Alternatives Considered There really aren't any compelling alternatives to `where` clauses among the languages that Slang takes design influence from. We could try to design something to solve the same problems from first principles, but the hypothetical benefits of doing so are unclear. -When it comes to the syntactic details, we could consider allowing for *multiple* `where` clauses (matching the C# syntax) as an alternative to the comma-separated list: +When it comes to the syntactic details, we could consider disallow type lists in the right hand side of a conformance constraint, and return allow multiple constraints to be separated with comma and sharing with one `where` keyword: struct MyStuff<T> : Base, IFoo - where T : IFoo - where T : IBar + where T : IFoo, + T : IBar { ... } -This alternative form may result in more compact and tidy diffs when editing the constraints on declarations, at the cost of repeating the `where` keyword many times. +This alternative form may result in more compact code without needing duplicated `where` clause, but may be harder to achieve tidy diffs when editing the constraints on declarations. Future Directions ----------------- -### Allow more general types on the left-hand side of `:` - -There are many cases where it would be helpful to be able to introduce constraints on associated types. -As a contrived example: - - interface IPrintable { ... } - interface ISequence - { - associatedtype Element; - ... - } - extention<T> T : IPrintable - where T : ISequence, - T.Element : IPrintable - { ... } - -In this example, an `extension` is used to declare that sequences are printable if their elements are printable. - - ### Allow more general types on the right-hand side of `:` Currently, the only constraints allowed using `:` have a concrete (non-`interface`) type on the left-hand side, and an `interface` (or conjunction of interfaces) on the right-hand side. @@ -284,30 +286,6 @@ In the context of `class`-based hierarchies, we can also consider having constra where T : Base { ... } -### Equality Constraints - -One future direction that we already intend to pursue is allowing exact equality constraints. -The primary use case envisioned for equality constraints is to express restrictions on associated types of type parameters. -As a contrived example: - - interface IProducer - { - associatedtype Element; - // ... - } - interface IConsumer - { - associatedtype Element; - // ... - } - void runPipeline<P, C>(P producer, C consumer) - where P : IProducer, - C : IConsumer, - P.Element == C.Element - { ... } - -An equality constraint could either constrain an associated type to be equal to some concrete type, or to some other associated type. - ### Allow `where` clauses on non-generic declarations We could consider allowing `where` clauses to appear on any declaration nested under a generic, such that those declarations are only usable when certain additinal constraints are met. diff --git a/docs/proposals/001-basic-interfaces.md b/docs/proposals/legacy/001-basic-interfaces.md index 4d04cbe04..4d04cbe04 100644 --- a/docs/proposals/001-basic-interfaces.md +++ b/docs/proposals/legacy/001-basic-interfaces.md diff --git a/docs/proposals/002-api-headers.md b/docs/proposals/legacy/002-api-headers.md index 66b649228..66b649228 100644 --- a/docs/proposals/002-api-headers.md +++ b/docs/proposals/legacy/002-api-headers.md diff --git a/docs/proposals/003-error-handling.md b/docs/proposals/legacy/003-error-handling.md index 28652824f..28652824f 100644 --- a/docs/proposals/003-error-handling.md +++ b/docs/proposals/legacy/003-error-handling.md diff --git a/docs/proposals/004-com-support.md b/docs/proposals/legacy/004-com-support.md index dc0bd52d3..dc0bd52d3 100644 --- a/docs/proposals/004-com-support.md +++ b/docs/proposals/legacy/004-com-support.md diff --git a/docs/proposals/005-components.md b/docs/proposals/legacy/005-components.md index b257140a7..b257140a7 100644 --- a/docs/proposals/005-components.md +++ b/docs/proposals/legacy/005-components.md diff --git a/docs/proposals/006-artifact-container-format.md b/docs/proposals/legacy/006-artifact-container-format.md index 81910151b..81910151b 100644 --- a/docs/proposals/006-artifact-container-format.md +++ b/docs/proposals/legacy/006-artifact-container-format.md diff --git a/docs/user-guide/06-interfaces-generics.md b/docs/user-guide/06-interfaces-generics.md index 61bc43f89..df51ac950 100644 --- a/docs/user-guide/06-interfaces-generics.md +++ b/docs/user-guide/06-interfaces-generics.md @@ -104,6 +104,22 @@ Generic value parameters can also be defined using the traditional C-style synta void g1<typename T, int n>() { ... } ``` +Slang allows multiple `where` clauses, and multiple interface types in a single `where` clause: +```csharp +struct MyType<T, U> + where T: IFoo, IBar + where U : IBaz<T> +{ +} +// equivalent to: +struct MyType<T, U> + where T: IFoo + where T : IBar + where U : IBaz<T> +{ +} +``` + Supported Constructs in Interface Definitions ----------------------------------------------------- @@ -793,6 +809,61 @@ void main() See [if-let syntax](convenience-features.html#if_let-syntax) for more details. +Generic Interfaces +------------------ + +Slang allows interfaces themselves to be generic. A common use of generic interfaces is to define the `IEnumerable` type: +```csharp +interface IEnumerator<T> +{ + This moveNext(); + bool isEnd(); + T getValue(); +} + +interface IEnumerable<T> +{ + assoicatedtype Enumerator : IEnumerator<T>; + Enumerator getEnumerator(); +} +``` + +You can constrain a generic type parameter to conform to a generic interface: +```csharp +void traverse<TElement, TCollection>(TCollection c) + where TCollection : IEnumerable<TElement> +{ + ... +} +``` + + +Generic Extensions +---------------------- +You can use generic extensions to extend a generic type. For example, +```csharp +interface IFoo { void foo(); } +interface IBar { void bar(); } + +struct MyType<T : IFoo> +{ + void foo() { ... } +} + +// Extend `MyType<T>` so it conforms to `IBar`. +extension<T:IFoo> MyType<T> : IBar +{ + void bar() { ... } +} +// Equivalent to: +__generic<T:IFoo> +extension MyType<T> : IBar +{ + void bar() { ... } +} +``` + + Extensions to Interfaces ----------------------------- diff --git a/docs/user-guide/09-targets.md b/docs/user-guide/09-targets.md index e1219a39d..d6aebab0c 100644 --- a/docs/user-guide/09-targets.md +++ b/docs/user-guide/09-targets.md @@ -302,14 +302,14 @@ Metal > #### Note #### > Slang support for Metal is a work in progress. -Metal is a shading language exclusive on Apple slicons. The functionality from Metal is similar to DX12 or Vulkan with more or less features. +Metal is a shading language exclusive on Apple platforms. The functionality from Metal is similar to DX12 or Vulkan with more or less features. ### Pipelines -Metal includes rasterization, compute, and ray tracing pipelines with the same set of stages as described for D3D12 above. +Metal includes vertex, fragment, task, mesh and tessellation stages for rasterization, as well as compute, and ray tracing stages. > #### Note #### -> Ray-tracing and Mesh support for Metal is a work in progress. +> Ray-tracing support for Metal is a work in progress. ### Parameter Passing diff --git a/docs/user-guide/a2-01-spirv-target-specific.md b/docs/user-guide/a2-01-spirv-target-specific.md index a1ecbfefd..e0d6fd69b 100644 --- a/docs/user-guide/a2-01-spirv-target-specific.md +++ b/docs/user-guide/a2-01-spirv-target-specific.md @@ -134,7 +134,7 @@ SPIR-V 1.5 with [SPV_EXT_shader_atomic_float16_add](https://github.com/KhronosGr ConstantBuffer, (RW/RasterizerOrdered)StructuredBuffer, (RW/RasterizerOrdered)ByteAddressBuffer ----------------------------------------------------------------------------------------------- -Each member in a `ConstantBuffer` will be emitted as `uniform` parameter. +Each member in a `ConstantBuffer` will be emitted as `uniform` parameter in a uniform block. StructuredBuffer and ByteAddressBuffer are translated to a shader storage buffer with `readonly` layout. RWStructuredBuffer and RWByteAddressBuffer are translated to a shader storage buffer with `read-write` layout. RasterizerOrderedStructuredBuffer and RasterizerOrderedByteAddressBuffer will use an extension, `SPV_EXT_fragment_shader_interlock`. @@ -156,6 +156,34 @@ It is similar to `ConstantBuffer` in HLSL, and `ParameterBlock` can include not When both ordinary data fields and resource typed fields exist in a parameter block, all ordinary data fields will be grouped together into a uniform buffer and appear as a binding 0 of the resulting descriptor set. +Push Constants +--------------------- + +By default, a `uniform` parameter defined in the parameter list of an entrypoint function is translated to a push constant in SPIRV, if the type of the parameter is ordinary data type (no resources/textures). +All `uniform` parameter defined in global scope are grouped together and placed in a default constant bbuffer. You can make a global uniform parameter laid out as a push constant by using the `[vk::push_constant]` attribute +on the uniform parameter. + +Specialization Constants +------------------------ + +You can specify a global constant to translate into a SPIRV specialization constant with the `[SpecializationConstant]` attribute. +For example: +```csharp +[SpecializationConstant] +const int myConst = 1; // Maps to a SPIRV specialization constant +``` + +By default, Slang will automatically assign `constant_id` number for specialization constants. If you wish to explicitly specify them, use `[vk::constant_id]` attribute: +```csharp +[vk::constant_id(1)] +const int myConst = 1; +``` + +Alternatively, the GLSL `layout` syntax is also supported by Slang: +```glsl +layout(constant_id = 1) const int MyConst = 1; +``` + SPIR-V specific Compiler options -------------------------------- diff --git a/docs/user-guide/toc.html b/docs/user-guide/toc.html index df1b4ba9d..77c4f16d8 100644 --- a/docs/user-guide/toc.html +++ b/docs/user-guide/toc.html @@ -83,6 +83,8 @@ <li data-link="interfaces-generics#interface-typed-values"><span>Interface-typed Values</span></li> <li data-link="interfaces-generics#extending-a-type-with-additional-interface-conformances"><span>Extending a Type with Additional Interface Conformances</span></li> <li data-link="interfaces-generics#is-and-as-operator"><span>`is` and `as` Operator</span></li> +<li data-link="interfaces-generics#generic-interfaces"><span>Generic Interfaces</span></li> +<li data-link="interfaces-generics#generic-extensions"><span>Generic Extensions</span></li> <li data-link="interfaces-generics#extensions-to-interfaces"><span>Extensions to Interfaces</span></li> <li data-link="interfaces-generics#variadic-generics"><span>Variadic Generics</span></li> <li data-link="interfaces-generics#builtin-interfaces"><span>Builtin Interfaces</span></li> @@ -207,6 +209,8 @@ <li data-link="spirv-target-specific#supported-atomic-types-for-each-target"><span>Supported atomic types for each target</span></li> <li data-link="spirv-target-specific#constantbuffer-rwrasterizerorderedstructuredbuffer-rwrasterizerorderedbyteaddressbuffer"><span>ConstantBuffer, (RW/RasterizerOrdered)StructuredBuffer, (RW/RasterizerOrdered)ByteAddressBuffer</span></li> <li data-link="spirv-target-specific#parameterblock-for-spir-v-target"><span>ParameterBlock for SPIR-V target</span></li> +<li data-link="spirv-target-specific#push-constants"><span>Push Constants</span></li> +<li data-link="spirv-target-specific#specialization-constants"><span>Specialization Constants</span></li> <li data-link="spirv-target-specific#spir-v-specific-compiler-options"><span>SPIR-V specific Compiler options</span></li> <li data-link="spirv-target-specific#spir-v-specific-attributes"><span>SPIR-V specific Attributes </span></li> <li data-link="spirv-target-specific#multiple-entry-points-support"><span>Multiple entry points support</span></li> |
