From 8c19b34e85f43c4f66acb3649c0cce332db8bb4c Mon Sep 17 00:00:00 2001 From: Jay Kwak <82421531+jkwak-work@users.noreply.github.com> Date: Wed, 20 Nov 2024 16:23:51 -0800 Subject: [PATCH 1/8] Initial writing --- docs/coming-from-glsl.md | 65 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/docs/coming-from-glsl.md b/docs/coming-from-glsl.md index 4de6ca9..6e55808 100644 --- a/docs/coming-from-glsl.md +++ b/docs/coming-from-glsl.md @@ -1,3 +1,66 @@ # Migrating to Slang from GLSL -[//]: # (TODO: write documentation on GLSL onramp here, and update link in docs/index.md) \ No newline at end of file +## Overview +Slang allows the developers to use GLSL syntax as the input shader. But this feature is intended to provide an easy transition from your existing GLSL based system to Slang system. The GLSL support is not meant to be complete and it may not be up-to-date with the GLSL spec. + +## How to use GLSL shaders as the input +By default, Slang doesn't recognize GLSL syntax. You need to explicitly enable it with an option, `-allow-glsl` or `-lang glsl`. + +With these options, Slang will import an extra module for GLSL and the GLSL specific intrinsics will be recognized. + +It means that all of Slang syntax is still available and you can use both Slang and GLSL syntax in a same shader file. + +## Layout rules +By default, Slang uses `std140` as the layout rule. You can explicitly specify to use `std430` whenever needed. + +Some examples are follows: +``` +StructuredBuffer std140Layout; +StructuredBuffer std430Layout; +StructuredBuffer scalarLayout; +``` + +The layout rule can also be changed with options like `-force-glsl-scalar-layout` or `-fvk-use-scalar-layout`. + +With those options, Slang will align all aggregrate types according to their elements' natural alignment as a rule described in `VK_EXT_scalar_block_layout`, aka `ScalarLayout`. + +## Matrix layout +By default, GLSL uses column-major matrix layout. +TODO: + +## Precision qualifiers are ignored +Slang doesn't respect the precision qualifiers such as `lowp`, `mediump`, and `highp`. All `float` type will be treated as a high precision float. + +## `double` type may not be supported depending on the target or target profile +While GLSL supports `double` type with extensions and restrictions, HLSL and WGSL don't support `double` type. + +The precision could be lost when using GLSL shader with those targets that don't support `double` type. + +## Multiple entry-points are allowed +GLSL requires an entry point to be named as `main`. It prevents a shader file from having more than one entry-point like how other shading languages allow such as HLSL and Metal. + +But this requirement doesn't apply when using Slang with the option `-allow-glsl`. In other words, you can define multiple entry-points in a same shader file. + +## Texture-combined sampler +GLSL has types called "Texture-combined sampler" such as `sampler2D`, `sampler3D` and so on. Slang will "legalize" it into two objects: a texture object and a sampler object. + +For example, `sampler2D` will be split into `Texture2D` and `SamplerState` when translated to `HLSL`. + +## `mod` in GLSL is Modulus not Remainder +It is important to understand that there are two ways to perform the `mod` operation. + 1. **Modulus**: modulus returns `x - y * floor(x / y)` + 2. **Remainder**: remainder is calculated such that x = i * y + f, where i is an integer, f has the same sign as x, and the absolute value of f is less than the absolute value of y. + +| Shading Language | Function name | What it does | +|------------------|----------------|--------------| +| CPP | fmod | Remainder | +| HLSL | fmod | Remainder | +| GLSL | mod, operator% | Modulus | +| Metal | fmod | Modulus | +| WGSL | operator% | Remainder | + +For this reason, the function `mod` is not translated to `fmod` when targeting HLSL, as an example. And it is translated to `x - y * floor(x / y)`. + +## Request a support +Please feel free to [report](github.com/shader-slang/slang/issues) issues regarding the GLSL support. + From de0ccfaba22be4bd923863f339ef37f720d61bf4 Mon Sep 17 00:00:00 2001 From: Jay Kwak <82421531+jkwak-work@users.noreply.github.com> Date: Tue, 10 Dec 2024 15:00:27 -0800 Subject: [PATCH 2/8] Adding explanations about the matrix --- docs/coming-from-glsl.md | 58 +++++++++++++++++++++++++++++++++++----- docs/coming-from-hlsl.md | 14 ++++++++++ 2 files changed, 66 insertions(+), 6 deletions(-) diff --git a/docs/coming-from-glsl.md b/docs/coming-from-glsl.md index 6e55808..3d9a6e8 100644 --- a/docs/coming-from-glsl.md +++ b/docs/coming-from-glsl.md @@ -11,13 +11,13 @@ With these options, Slang will import an extra module for GLSL and the GLSL spec It means that all of Slang syntax is still available and you can use both Slang and GLSL syntax in a same shader file. ## Layout rules -By default, Slang uses `std140` as the layout rule. You can explicitly specify to use `std430` whenever needed. +By default, Slang uses `std430` as the layout rule. You can explicitly specify to use `std140` whenever needed. Some examples are follows: ``` -StructuredBuffer std140Layout; -StructuredBuffer std430Layout; -StructuredBuffer scalarLayout; +StructuredBuffer std140Layout; +StructuredBuffer std430Layout; +StructuredBuffer scalarLayout; ``` The layout rule can also be changed with options like `-force-glsl-scalar-layout` or `-fvk-use-scalar-layout`. @@ -25,8 +25,54 @@ The layout rule can also be changed with options like `-force-glsl-scalar-layout With those options, Slang will align all aggregrate types according to their elements' natural alignment as a rule described in `VK_EXT_scalar_block_layout`, aka `ScalarLayout`. ## Matrix layout -By default, GLSL uses column-major matrix layout. -TODO: +Even though GLSL claims to use "Column-major", it is mostly nomenclature when it comes to the shader side implementation. + +Here is an example that shows the difference between GLSL and HLSL. + + +
HLSL shaderSlang shader
+ +```glsl +// GLSL +mat3x4 m; // 3 columns and 4 rows +for (int c = 0; c < 3; ++c) +{ + for (int r = 0; r < 4; ++r) + { + m[c][r] = c * 4 + r; + } +} + +vec4 takeFirstColumn = { 1, 0, 0, 0 }; +vec3 result; +result.x = dot(takeFirstColumn, m[0]); // 0 +result.y = dot(takeFirstColumn, m[1]); // 4 +result.z = dot(takeFirstColumn, m[2]); // 8 +``` + + +```hlsl +// HLSL +float3x4 m; // 3 rows and 4 columns +for (int r = 0; r < 3; ++r) +{ + for (int c = 0; c < 4; ++c) + { + m[r][c] = r * 4 + c; + } +} + +float4 takeFirstColumn = { 1, 0, 0, 0 }; +float3 result; +result.x = dot(takeFirstColumn, m[0]); // 0 +result.y = dot(takeFirstColumn, m[1]); // 4 +result.z = dot(takeFirstColumn, m[2]); // 8 +``` +
+ +The real difference is on the data "Layout" where CPU stores the data on the memory in a certain order and the shader interprets it in the same way. + +For more detailed explanation about the matrix layout, please check another document, [Handling Matrix Layout Differences on Different Platforms](https://shader-slang.com/slang/user-guide/a1-01-matrix-layout.html). ## Precision qualifiers are ignored Slang doesn't respect the precision qualifiers such as `lowp`, `mediump`, and `highp`. All `float` type will be treated as a high precision float. diff --git a/docs/coming-from-hlsl.md b/docs/coming-from-hlsl.md index 65ec5d3..afd0b33 100644 --- a/docs/coming-from-hlsl.md +++ b/docs/coming-from-hlsl.md @@ -8,6 +8,20 @@ While the languages share similarities, paying close attention to specific synta ## Key Syntax and Feature Differences +### `operator*` performs a column-wise matrix multiplication not the component-wise multiplication +In HLSL, `operator*` for matrices performs the component-wise multiplication as described in a document, [Per-Component Math Operations](https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-per-component-math?redirectedfrom=MSDN). + +However, `operator*` is for the column-major matrix multiplication in Slang, which is same as the `operator*` in GLSL. + +There is `mul()` function in Slang for the row-major matrix multiplication, which is same as `mul()` function in HLSL. + +Due to the differences on row/column-majorness, the order of the operands are different for `mul()` and `operator*`. +``` +// In Slang, the following condition is true +float4x4 m1, m2; +bool isSame = (mul(m1, m2) == (m2 * m1)); // evaluates to true +``` + ### `enum` is scoped in Slang In HLSL, `enum` is unscoped, which means the enum values can be referred to without the enum's name. In Slang, `enum` is scoped, requiring explicit reference to the enum's name along with its values. From 0188a3e2ee6f5bce3a7dc260ef547060c701390c Mon Sep 17 00:00:00 2001 From: Jay Kwak <82421531+jkwak-work@users.noreply.github.com> Date: Tue, 10 Dec 2024 15:01:34 -0800 Subject: [PATCH 3/8] Fix typo --- docs/coming-from-glsl.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/coming-from-glsl.md b/docs/coming-from-glsl.md index 3d9a6e8..eda18f7 100644 --- a/docs/coming-from-glsl.md +++ b/docs/coming-from-glsl.md @@ -29,11 +29,10 @@ Even though GLSL claims to use "Column-major", it is mostly nomenclature when it Here is an example that shows the difference between GLSL and HLSL. - +
HLSL shaderSlang shader
GLSL shaderHLSL shader
```glsl -// GLSL mat3x4 m; // 3 columns and 4 rows for (int c = 0; c < 3; ++c) { @@ -52,7 +51,6 @@ result.z = dot(takeFirstColumn, m[2]); // 8 ```hlsl -// HLSL float3x4 m; // 3 rows and 4 columns for (int r = 0; r < 3; ++r) { From de484c412cb00279a8230b9527b7ab70edb76956 Mon Sep 17 00:00:00 2001 From: Jay Kwak <82421531+jkwak-work@users.noreply.github.com> Date: Tue, 10 Dec 2024 15:09:11 -0800 Subject: [PATCH 4/8] Rename the subtitle "Matrix layout" to "Matrix" --- docs/coming-from-glsl.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/coming-from-glsl.md b/docs/coming-from-glsl.md index eda18f7..63511b4 100644 --- a/docs/coming-from-glsl.md +++ b/docs/coming-from-glsl.md @@ -24,7 +24,7 @@ The layout rule can also be changed with options like `-force-glsl-scalar-layout With those options, Slang will align all aggregrate types according to their elements' natural alignment as a rule described in `VK_EXT_scalar_block_layout`, aka `ScalarLayout`. -## Matrix layout +## Matrix Even though GLSL claims to use "Column-major", it is mostly nomenclature when it comes to the shader side implementation. Here is an example that shows the difference between GLSL and HLSL. From 66ae66354658b053b901616e9fdfc574b845cef2 Mon Sep 17 00:00:00 2001 From: Jay Kwak <82421531+jkwak-work@users.noreply.github.com> Date: Tue, 10 Dec 2024 15:58:24 -0800 Subject: [PATCH 5/8] Remove the incorrect HLSL document change --- docs/coming-from-hlsl.md | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/docs/coming-from-hlsl.md b/docs/coming-from-hlsl.md index 5d2c8be..361eecc 100644 --- a/docs/coming-from-hlsl.md +++ b/docs/coming-from-hlsl.md @@ -15,20 +15,6 @@ While the languages share similarities, paying close attention to specific synta ### Key Syntax and Feature Differences -#### `operator*` performs a column-wise matrix multiplication not the component-wise multiplication -In HLSL, `operator*` for matrices performs the component-wise multiplication as described in a document, [Per-Component Math Operations](https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-per-component-math?redirectedfrom=MSDN). - -However, `operator*` is for the column-major matrix multiplication in Slang, which is same as the `operator*` in GLSL. - -There is `mul()` function in Slang for the row-major matrix multiplication, which is same as `mul()` function in HLSL. - -Due to the differences on row/column-majorness, the order of the operands are different for `mul()` and `operator*`. -``` -// In Slang, the following condition is true -float4x4 m1, m2; -bool isSame = (mul(m1, m2) == (m2 * m1)); // evaluates to true -``` - #### `enum` is scoped in Slang In HLSL, `enum` is unscoped, which means the enum values can be referred to without the enum's name. In Slang, `enum` is scoped, requiring explicit reference to the enum's name along with its values. From ad22aa503e5857bf7fc1f19c44ea42e129511edb Mon Sep 17 00:00:00 2001 From: Jay Kwak <82421531+jkwak-work@users.noreply.github.com> Date: Wed, 11 Dec 2024 10:35:22 -0800 Subject: [PATCH 6/8] Changes based on review --- docs/coming-from-glsl.md | 84 ++++++++++++++++++++++++++++------------ 1 file changed, 59 insertions(+), 25 deletions(-) diff --git a/docs/coming-from-glsl.md b/docs/coming-from-glsl.md index 9f125c4..7a0a22d 100644 --- a/docs/coming-from-glsl.md +++ b/docs/coming-from-glsl.md @@ -9,19 +9,46 @@ intro_image_hide_on_mobile: false ## Overview -Slang allows the developers to use GLSL syntax as the input shader. But this feature is intended to provide an easy transition from your existing GLSL based system to Slang system. The GLSL support is not meant to be complete and it may not be up-to-date with the GLSL spec. +Slang allows developers to use GLSL syntax as input shaders. It provides an easy transition from your existing GLSL-based system to the Slang system. This document provides information that users may want to know when migrating from a GLSL-based system to the Slang system. -## How to use GLSL shaders as the input +Note that the GLSL support is not meant to be complete and it may not be up-to-date with the GLSL spec. + +For people who are interested in more details of how GLSL functions are translated, please refer to [glsl.meta.slang](https://github.com/shader-slang/slang/blob/master/source/slang/glsl.meta.slang). + +## How to use GLSL shaders as input By default, Slang doesn't recognize GLSL syntax. You need to explicitly enable it with an option, `-allow-glsl` or `-lang glsl`. -With these options, Slang will import an extra module for GLSL and the GLSL specific intrinsics will be recognized. +With these options, Slang will import an extra module for GLSL, and the GLSL-specific intrinsics will be recognized. + +It means that all of Slang syntax is still available, and you can use both Slang and GLSL syntax in the same shader file. + +For the compilation API, you can use `slang::CompilerOptionName::AllowGLSL` on `slang::CompilerOptionEntry` when you create a session. + +Here is an example code snippet for the compilation API: +```cpp +slang::TargetDesc targetDesc = {}; +targetDesc.format = SLANG_SPIRV; +targetDesc.profile = globalSession->findProfile("glsl_460"); + +slang::CompilerOptionEntry compilerOptions[1]; +compilerOptions[optoinCount].name = slang::CompilerOptionName::AllowGLSL; +compilerOptions[optoinCount].value.intValue0 = 1; -It means that all of Slang syntax is still available and you can use both Slang and GLSL syntax in a same shader file. +slang::SessionDesc sessionDesc = {}; +sessionDesc.targets = &targetDesc; +sessionDesc.targetCount = 1; + +sessionDesc.compilerOptionEntries = compilerOptions; +sessionDesc.compilerOptionEntryCount = 1; + +Slang::ComPtr session; +globalSession->createSession(sessionDesc, session.writeRef()); +``` ## Layout rules By default, Slang uses `std430` as the layout rule. You can explicitly specify to use `std140` whenever needed. -Some examples are follows: +Some examples are as follows: ``` StructuredBuffer std140Layout; StructuredBuffer std430Layout; @@ -30,10 +57,10 @@ StructuredBuffer scalarLayout; The layout rule can also be changed with options like `-force-glsl-scalar-layout` or `-fvk-use-scalar-layout`. -With those options, Slang will align all aggregrate types according to their elements' natural alignment as a rule described in `VK_EXT_scalar_block_layout`, aka `ScalarLayout`. +With those options, Slang will align all aggregate types according to their elements' natural alignment as described in `VK_EXT_scalar_block_layout`, aka `ScalarLayout`. ## Matrix -Even though GLSL claims to use "Column-major", it is mostly nomenclature when it comes to the shader side implementation. +Even though GLSL claims to use "Column-major", it is mostly nomenclature when it comes to the shader-side implementation. For this reason, `matXxY` and `floatXxY` can be used interchangeably in Slang. Here is an example that shows the difference between GLSL and HLSL. @@ -76,25 +103,25 @@ result.z = dot(takeFirstColumn, m[2]); // 8 ```
-The real difference is on the data "Layout" where CPU stores the data on the memory in a certain order and the shader interprets it in the same way. +The real difference is in the data "Layout," where the CPU stores the data in memory in a certain order, and the shader interprets it in the same way. -For more detailed explanation about the matrix layout, please check another document, [Handling Matrix Layout Differences on Different Platforms](https://shader-slang.com/slang/user-guide/a1-01-matrix-layout.html). +For a more detailed explanation about the matrix layout, please check another document, [Handling Matrix Layout Differences on Different Platforms](https://shader-slang.com/slang/user-guide/a1-01-matrix-layout.html). ## Precision qualifiers are ignored -Slang doesn't respect the precision qualifiers such as `lowp`, `mediump`, and `highp`. All `float` type will be treated as a high precision float. +Slang doesn't respect the precision qualifiers such as `lowp`, `mediump`, and `highp`. All `float` types will be treated as high-precision floats. ## `double` type may not be supported depending on the target or target profile -While GLSL supports `double` type with extensions and restrictions, HLSL and WGSL don't support `double` type. +While GLSL supports the `double` type with extensions and restrictions, HLSL and WGSL don't support the `double` type. -The precision could be lost when using GLSL shader with those targets that don't support `double` type. +The precision will be lost when using GLSL shaders with those targets that don't support the `double` type. ## Multiple entry-points are allowed -GLSL requires an entry point to be named as `main`. It prevents a shader file from having more than one entry-point like how other shading languages allow such as HLSL and Metal. +GLSL requires an entry point to be named `main`. This requirement prevents a shader file from having more than one entry point, unlike other shading languages such as HLSL and Metal. -But this requirement doesn't apply when using Slang with the option `-allow-glsl`. In other words, you can define multiple entry-points in a same shader file. +But this requirement doesn't apply when using Slang with the option `-allow-glsl`. In other words, you can define multiple entry points in the same shader file. ## Texture-combined sampler -GLSL has types called "Texture-combined sampler" such as `sampler2D`, `sampler3D` and so on. Slang will "legalize" it into two objects: a texture object and a sampler object. +GLSL has types called "Texture-combined sampler" such as `sampler2D`, `sampler3D`, and so on. Slang will "legalize" it into two objects: a texture object and a sampler object. For example, `sampler2D` will be split into `Texture2D` and `SamplerState` when translated to `HLSL`. @@ -103,16 +130,23 @@ It is important to understand that there are two ways to perform the `mod` opera 1. **Modulus**: modulus returns `x - y * floor(x / y)` 2. **Remainder**: remainder is calculated such that x = i * y + f, where i is an integer, f has the same sign as x, and the absolute value of f is less than the absolute value of y. -| Shading Language | Function name | What it does | -|------------------|----------------|--------------| -| CPP | fmod | Remainder | -| HLSL | fmod | Remainder | -| GLSL | mod, operator% | Modulus | -| Metal | fmod | Modulus | -| WGSL | operator% | Remainder | +The `mod` function in GLSL performs Modulus. When translating from GLSL to other targets, the behavior will remain the same. When the target doesn't have a native intrinsic function for Modulus, `x - y * floor(x / y)` will be emitted. + +See the table below for what native functions are available for each target: + +| Target | Native functions | What it does | +|--------|------------------|--------------| +| CPP | fmod, remainder | Remainder | +| HLSL | fmod | Remainder | +| GLSL | mod, operator% | Modulus | +| Metal | fmod | Modulus | +| WGSL | operator% | Remainder | +| SPIRV | OpFRem | Remainder | +| SPIRV | OpFMod | Modulus | -For this reason, the function `mod` is not translated to `fmod` when targeting HLSL, as an example. And it is translated to `x - y * floor(x / y)`. +As an example, when targeting HLSL, Slang will translate `mod` in GLSL to `x - y * floor(x / y)` in HLSL and not `fmod` in HLSL, because the result from `fmod` in HLSL is different from `mod` in GLSL. -## Request a support -Please feel free to [report](github.com/shader-slang/slang/issues) issues regarding the GLSL support. +As another example, when targeting SPIRV, Slang will emit `OpFMod` not `x - y * floor(x / y)`, because using the native intrinsic is more efficient. +## Requesting support +Please feel free to [report](https://github.com/shader-slang/slang/issues) issues regarding the GLSL support. \ No newline at end of file From cb83769b36919abd11f2dd5a81ceda8d2d92aaa5 Mon Sep 17 00:00:00 2001 From: Jay Kwak <82421531+jkwak-work@users.noreply.github.com> Date: Wed, 11 Dec 2024 11:12:05 -0800 Subject: [PATCH 7/8] Fix a bug on the code snippet --- docs/coming-from-glsl.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/coming-from-glsl.md b/docs/coming-from-glsl.md index 7a0a22d..0574e2e 100644 --- a/docs/coming-from-glsl.md +++ b/docs/coming-from-glsl.md @@ -31,8 +31,8 @@ targetDesc.format = SLANG_SPIRV; targetDesc.profile = globalSession->findProfile("glsl_460"); slang::CompilerOptionEntry compilerOptions[1]; -compilerOptions[optoinCount].name = slang::CompilerOptionName::AllowGLSL; -compilerOptions[optoinCount].value.intValue0 = 1; +compilerOptions[0].name = slang::CompilerOptionName::AllowGLSL; +compilerOptions[0].value.intValue0 = 1; slang::SessionDesc sessionDesc = {}; sessionDesc.targets = &targetDesc; @@ -149,4 +149,4 @@ As an example, when targeting HLSL, Slang will translate `mod` in GLSL to `x - y As another example, when targeting SPIRV, Slang will emit `OpFMod` not `x - y * floor(x / y)`, because using the native intrinsic is more efficient. ## Requesting support -Please feel free to [report](https://github.com/shader-slang/slang/issues) issues regarding the GLSL support. \ No newline at end of file +Please feel free to [report](https://github.com/shader-slang/slang/issues) issues regarding the GLSL support. From f2bec5d2e740061cddcae47fad93571c2b76826c Mon Sep 17 00:00:00 2001 From: Jay Kwak <82421531+jkwak-work@users.noreply.github.com> Date: Wed, 11 Dec 2024 15:33:30 -0800 Subject: [PATCH 8/8] Add a link to the doc, migrating-from-glsl --- _data/documentation.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/_data/documentation.yaml b/_data/documentation.yaml index f4ec65f..ba87396 100644 --- a/_data/documentation.yaml +++ b/_data/documentation.yaml @@ -63,3 +63,7 @@ tutorials: description: "Main things to know if you are coming to Slang as an HLSL developer." link_url: "/docs/coming-from-hlsl/" link_label: "Coming from HLSL" + - title: "Migrating from GLSL to Slang" + description: "Main things to know if you are coming to Slang as a GLSL developer." + link_url: "/docs/coming-from-glsl/" + link_label: "Coming from GLSL"