-
Notifications
You must be signed in to change notification settings - Fork 17
GLSL tutorial #19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
GLSL tutorial #19
Changes from 9 commits
8c19b34
de0ccfa
0188a3e
aa03e86
de484c4
eacd7cd
66ae663
ad22aa5
cb83769
f2bec5d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,4 +8,145 @@ intro_image_hide_on_mobile: false | |
--- | ||
|
||
|
||
[//]: # (TODO: write documentation on GLSL onramp here, and update link in docs/index.md) | ||
## Overview | ||
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. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. … when migrating a glsl shader code base to Slang. |
||
|
||
jkwak-work marked this conversation as resolved.
Show resolved
Hide resolved
|
||
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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add a section on the support level of glsl input: The support for GLSL input in the slang compiler is best-effort rather than spec-complete. The Slang compiler understands many but not all GLSL syntax. Slang is not a drop-in replacement for any existing GLSL compiler. Instead, the intention is to make transition from glsl to Slang easy by allowing mixing GLSL syntax and Slang syntax so the user does not need to modify every line of code before they can use Slang features. The user is still expected to migrate from unsupported GLSL syntax before they can be accepted by the Slang compiler. Most of the unsupported areas of GLSL syntax are around global parameter or layout declarations. We expect most functions written in GLSL to just work in Slang. |
||
By default, Slang doesn't recognize GLSL syntax. You need to explicitly enable it with an option, `-allow-glsl` or `-lang glsl`. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's the options for Curious, is it necessary to add There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I could give a try and see what the actual behaviors are. I am not clear on what There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don’t think you need -allow-glsl if you have #version 450 declaration in the source file. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. -lang glsl does nothing right now so let’s not mention it. |
||
|
||
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[0].name = slang::CompilerOptionName::AllowGLSL; | ||
compilerOptions[0].value.intValue0 = 1; | ||
|
||
slang::SessionDesc sessionDesc = {}; | ||
sessionDesc.targets = &targetDesc; | ||
sessionDesc.targetCount = 1; | ||
|
||
sessionDesc.compilerOptionEntries = compilerOptions; | ||
sessionDesc.compilerOptionEntryCount = 1; | ||
|
||
Slang::ComPtr<slang::ISession> 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. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not true. Uniform buffer defaults to std140, shader storage buffers and structured buffers default to std430. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The example below is using HLSL syntax but this doc is for glsl users, so it seems inappropriate, unless we start with some explanation, such as “to explicitly specify the layout of individual buffers, you can use the Slang syntax when declaring the buffer.” |
||
|
||
Some examples are as follows: | ||
``` | ||
StructuredBuffer<T, Std140DataLayout> std140Layout; | ||
StructuredBuffer<T, Std430DataLayout> std430Layout; | ||
StructuredBuffer<T, ScalarDataLayout> scalarLayout; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add a case for specifying layout for a ConstantBuffer<>. |
||
``` | ||
|
||
The layout rule can also be changed with options like `-force-glsl-scalar-layout` or `-fvk-use-scalar-layout`. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is also -fvk-use-dx-layout now. See dxc documentation for what it means. |
||
|
||
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. For this reason, `matXxY` and `floatXxY` can be used interchangeably in Slang. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can just say matNxM is a typedef to floatNxM. |
||
|
||
Here is an example that shows the difference between GLSL and HLSL. | ||
<table> | ||
<tr><td>GLSL shader</td><td>HLSL shader</td></tr> | ||
<tr><td> | ||
|
||
```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 | ||
``` | ||
</td><td> | ||
|
||
```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 | ||
``` | ||
</td></tr></table> | ||
|
||
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 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). | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also need a section to talk about the difference of operator ==, * between glsl and HLSL, and how -allow-glsl/#version/import glsl changes that default behavior. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And a section on how shader storage buffers are parsed and supported. Show the glsl syntax and equivalent slang code for constant buffers, structured buffers and storage buffers, so people know how to migrate the code to slang if they want to do so. |
||
## Precision qualifiers are ignored | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also mention that the actual version number after #version is ignored by the compiler. The only difference made by a #version 450 line is to convey to the slang compiler that the module is in glsl syntax, that is, it has the same effect as import glsl; or -allow-glsl. |
||
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 the `double` type with extensions and restrictions, HLSL and WGSL don't support the `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 `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 the same shader file. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Talk about -fvk-use-EntryPoint-name here. |
||
|
||
## Texture-combined sampler | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Isn’t it called combined texture sampler in Vulkan? |
||
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. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not true if you are targeting spirv and Vulkan, where there is a direct translation. The legalization only take place for targets that does not natively support combined texture samplers. |
||
|
||
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. | ||
|
||
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 | | ||
|
||
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. | ||
cheneym2 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
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. |
Uh oh!
There was an error while loading. Please reload this page.