From d5e4854b63440009c4bcf3638a79159b2ef60dfa Mon Sep 17 00:00:00 2001 From: Yong He Date: Thu, 10 Nov 2022 09:19:55 -0800 Subject: Update documentation on new features (#2508) * Update documentation on new features * Fix. Co-authored-by: Yong He --- docs/user-guide/01-get-started.md | 5 ++ docs/user-guide/03-convenience-features.md | 104 ++++++++++++++++++++++++++++- docs/user-guide/04-interfaces-generics.md | 54 +++++++++++++++ 3 files changed, 162 insertions(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/user-guide/01-get-started.md b/docs/user-guide/01-get-started.md index eafc599f9..fba0cbfec 100644 --- a/docs/user-guide/01-get-started.md +++ b/docs/user-guide/01-get-started.md @@ -31,6 +31,11 @@ void computeMain(uint3 threadId : SV_DispatchThreadID) } ``` +> #### Note #### +> Slang has official language extension support for Visual Studio Code. The extension is powered by the Slang compiler to support a wide range of +> assisting features including auto-completion, function signature hinting, semantic highlighting and more. +> Try it here: https://marketplace.visualstudio.com/items?itemName=shader-slang.slang-language-extension + As you can see, `hello-world.slang` is no different from a normal HLSL shader file. In fact, Slang is compatible with most HLSL code you would write. On top of HLSL, Slang has added many new language and compiler features that simplifies various tasks with shader code, which we will cover in future chapters. For now we will demonstrate one key feature of Slang: cross-compiling to different platforms. Slang supports compiling shaders into many different targets including Direct3D 11, Direct3D 12, Vulkan, CUDA and C++ (for execution on CPU). You can run `slangc` with the following command line to compile `hello-world.slang` into Vulkan SPIRV: diff --git a/docs/user-guide/03-convenience-features.md b/docs/user-guide/03-convenience-features.md index 011939ddb..e67166644 100644 --- a/docs/user-guide/03-convenience-features.md +++ b/docs/user-guide/03-convenience-features.md @@ -217,9 +217,84 @@ int test() return rs.val; // returns 3. } ``` - Slang currently supports overloading the following operators: `+`, `-`, `*`, `/`, `%`, `&`, `|`, `<`, `>`, `<=`, `>=`, `==`, `!=`, unary `-`, `~` and `!`. Please note that the `&&` and `||` operators are not supported. + +## Subscript Operator + +Slang allows overriding `operator[]` with `__subscript` syntax: +```csharp +struct MyType +{ + int val[12]; + __subscript(int x, int y) -> int + { + get { return val[x*3 + y]; } + set { val[x*3+y] = newValue; } + } +} +int test() +{ + MyType rs; + rs[0, 0] = 1; + rs[1, 0] = rs[0, 0] + 1 + return rs[1, 0]; // returns 2. +} +``` + +## `Optional` type + +Slang supports the `Optional` type to represent a value that may not exist. +The dedicated `none` value can be used for any `Optional` to represent no value. +`Optional::value` property can be used to retrieve the value. + +```csharp +struct MyType +{ + int val; +} + +int useVal(Optional p) +{ + if (p == none) // Equivalent to `p.hasValue` + return 0; + return p.value.val; +} + +int caller() +{ + MyType v; + v.val = 0; + useVal(v); // OK to pass `MyType` to `Optional`. + useVal(none); // OK to pass `none` to `Optional`. + return 0; +} +``` + +## `reinterpret` operation + +Sometimes it is useful to reinterpret the bits of one type as another type, for example: +```csharp +struct MyType +{ + int a; + float2 b; + uint c; +} + +MyType myVal; +float4 myPackedVector = packMyTypeToFloat4(myVal); +``` + +The `packMyTypeToFloat4` function is usually implemented by bit casting each field in the source type and assign it into the corresponding field in the target type, +by calling `intAsFloat`, `floatAsInt` and using bit operations to shift things in the right place. +Instead of writing `packMyTypeToFloat4` function yourself, you can use Slang's builtin `reinterpret` to do just that for you: +``` +float4 myPackedVector = reinterpret(myVal); +``` + +`reinterpret` can pack any type into any other type as long as the target type is no smaller than the source type. + ## `struct` inheritance (limited) Slang supports a limited form of inheritance. A derived `struct` type has all the members defined in the base type it is inherited from: @@ -293,6 +368,33 @@ void test() This feature is similar to extensions in Swift and partial classes in C#. +Multi-level break +------------------- + +Slang allows `break` statements with a label to jump into any ancestor control flow break points, and not just the immediate parent. +Example: +``` +outter: +for (int i = 0; i < 5; i++) +{ + inner: + for (int j = 0; j < 10; j++) + { + if (someCondition) + break outter; + } +} +``` + +Force inlining +----------------- +Most of the downstream shader compilers will inline all the function calls. However you can instruct Slang compiler to do the inlining +by using the `[ForceInline]` decoration: +``` +[ForceInline] +int f(int x) { return x + 1; } +``` + Modules ------- diff --git a/docs/user-guide/04-interfaces-generics.md b/docs/user-guide/04-interfaces-generics.md index 65c23d98e..dccaa045f 100644 --- a/docs/user-guide/04-interfaces-generics.md +++ b/docs/user-guide/04-interfaces-generics.md @@ -155,6 +155,26 @@ struct MyObject : IComparable ``` In this example, the `IComparable` interface declares that any conforming type must provide a `comparesTo` method that performs a comparison between an object to another object of the same type. The `MyObject` type satisfies this requirement by providing a `comparesTo` method that accepts a `MyObject` typed argument, since in the scope of `MyObject`, `This` type is equivalent to `MyObject`. +### Static Constants + +You can define static constant requirements in an interface. The constants can be accessed in places where a compile-time constant is needed. +```csharp +interface IMyValue +{ + static const int value; +} +struct MyObject2 : IMyValue +{ + static const int value = 2; +} +struct GetValuePlus1 +{ + static const int value = T.value + 1; +} + +static const int result = GetValuePlus1.value; // result == 3 +``` + ### Initializers Consider a generic method that wants to create and initialize a new instance of generic type `T`: @@ -616,6 +636,40 @@ extension MyObject : IBar, IBar2 } ``` +`is` and `as` Operator +---------------------------- + +You can use `is` operator to test if an interface-typed value is of a specific concrete type, and use `as` operator to downcast the value into a specific type. +The `as` operator returns an `Optional` that is not `none` if the downcast succeeds. + +```csharp +interface IFoo +{ + int foo(); +} +struct MyImpl : IFoo +{ + int foo() { return 0; } +} +void test(IFoo foo) +{ + bool t = foo is MyImpl; // true + Optional optV = foo as MyImpl; + if (t == (optV != none)) + printf("success"); + else + printf("fail"); +} +void main() +{ + MyImpl v; + test(v); +} +// Result: +// "success" +``` + + Extensions to Interfaces ----------------------------- -- cgit v1.2.3