-
Notifications
You must be signed in to change notification settings - Fork 526
FSL Integration Guide
When integrating FSL shader generator tool into a project, Python 3.6 is required. In The Forge, we include a no-install python3.6 in Tools/python-3.6.0-embed-amd64.
FSL can be integrated into Visual Studio, XCode and CodeLite projects, or any possible build system. The generator tool can also be called directly from the python script fsl.py.
We provide a target file fsl.target found in Common_3\Tools\ForgeShadingLanguage to be added to visual studio project files (.vcxproj)
To add the build customization right-click the project in VS and choose "Build Dependencies" -> "Build Customizations..." -> "Find Existing..." and choose the fsl.target file.
The customization can than be enabled per-project from the same menu.
inside the project file, this section is added:
<ImportGroup Label="ExtensionTargets">
<Import Project="..\..\..\Common_3\Tools\ForgeShadingLanguage\VS\fsl.targets" />
</ImportGroup>
This adds to the visual studio project support for FSL files .fsl which adds to the property pages a new section FSLShader that contains configuration properties, and allows compiling the .fsl files using the provided tool.
Once added to a project, any added *.fsl is assigned the <FSLShader>
item type.
In fsl.target custom target we prepend the provided python path to PATH, such that the build system uses that binary.
For XCode, we use a custom build rule for .fsl resources and directly generate the metal shaders
into the the target package. You can find this in a shell script in the Build Phases
section of the XCode project settings.
Similarly the integration in Code Light project is by adding a custom build target that invokes the FSL generator tool.
The generator tool can be called directly from the python script fsl.py.
usage: fsl.py [-h] -d DESTINATION -b BINARYDESTINATION
[-i INTERMEDIATEDESTINATION] [-l LANGUAGE]
[-I INCLUDES [INCLUDES ...]] [--verbose] [--compile] [--debug]
[--rootSignature ROOTSIGNATURE] [--incremental] [--mp MP]
[--reloadServerPort RELOADSERVERPORT] [--cache-args]
fsl_input
-h : Used to display help about the command arguments.
-d : Required Specify the destination folder for the generated shaders.
-b : Required Specify the destination folder compiled binary shaders that will be used at runtime.
fsl_input : Required Specifies the input .fsl file.
-i : Optional Specify the intermediate destination folder.
-l : Optional Specify the target language or platform, which will use default if not passed.
-I : Optional Specify include paths which may contained shared shader headers.
--verbose : Optional Outputs detailed information when generating shaders.
--compile : Optional To compile final binary that will be used at run time.
--compile : Optional To compile shaders with debug information which allows.
--rootSignature : Optional Direct3D12 only provide the name of root signature.
--incremental : Optional compile only non existing files at destination.
--mp : Optional Specify number of processes to use.
--reloadServerPort : Optional Specify port that reload server would use.
--cache-args : Optional Caches arguments used to invoke fsl.py
and also generate reload-server.txt
used by ReloadServer client application.
If compilation is requested, the tool will attempt to locate appropriate compilers using env variables:
DIRECT3D12: $(FSL_COMPILER_DXC) (if not set, will default to "The-Forge/ThirdParty/OpenSource/DirectXShaderCompiler/bin/x64/dxc.exe")
METAL: $(FSL_COMPILER_METAL) (if not set, will default to "'C:/Program Files/METAL Developer Tools/macos/bin/metal.exe'")
ORBIS: $(SCE_ORBIS_SDK_DIR)/host_tools/bin/orbis-wave-psslc.exe
PROSPERO: $(SCE_PROSPERO_SDK_DIR)/host_tools/bin/prospero-wave-psslc.exe
VULKAN: $(VULKAN_SDK)/Bin/glslangValidator.exe
XBOX: $(GXDKLATEST)/bin/XboxOne/dxc.exe
SCARLETT: $(GXDKLATEST)/bin/Scarlett/dxc.exe
ReloadServer allows you to dynamically recompile FSL shaders at runtime by clicking the Reload shaders
button in the Debug UI.
It works by running a socket server on the host PC that is waiting for the device to send a shader recompile request.
Upon receiving this request, ReloadServer only recompiles shaders that have been modified for the requested project, and sends them back to the device where they are reloaded after being received.
In the case of a compilation/connection error, the message will be printed to the device logs so that the issue can quickly be inspected.
ReloadServer is intended to work automatically, and will at most require the user to run a script once per session in order to use it. It is already integrated into all of our projects on all platforms, so no setup is required. See Manually running ReloadServer for details on how to integrate ReloadServer into a new project.
ReloadServer is run automatically on PC during App init, and killed during App exit. There is no input required from the user, it works completely automatically.
For Console/Mobile projects, ReloadServer must be run manually on the host PC in order to allow dynamic recompilation of shaders on the device. See Manually running ReloadServer for details on how to run the server manually.
The basic workflow is as follows:
- (Non-PC only) Run
Common_3/Tools/ReloadServer/ReloadServer.sh
orReloadServer.bat
in a terminal - Run
App
- Modify FSL file
- Click
Reload shaders
button - (if success) Observe updated shaders in
App
(if failure) Error is printed inApp
logs
ReloadServer has only one configuration option - the server port. The default port is 6543. The port can also be configured in the following ways:
You can configure ReloadServer port using the DevicePort
option in the FSLShader
IDE configuration panel of your project settings. If DevicePort
is empty, then the default port is used.
On XCode/CodeLite, ReloadServer can be configured via the invocation of fsl.py
in the build script located in the project settings. If no port is provided, then the default port is used. See fsl.py integration for details.
ReloadServer on Android uses adb reverse tcp:PORT tcp:PORT
in order to forward recompile requests from the device to the host PC via the USB cable, which avoids requiring a network connection. This is done automatically and requires no user input.
ReloadServer on iOS requires the device to be connected to the same network as the host PC on which the ReloadServer daemon is running.
ReloadServer can easily be run manually by using the platform-specific batch/shell script located at Common_3/Tools/ReloadServer
.
.\Common_3\Tools\ForgeShadingLanguage\server\ReloadServer.bat
./Common_3/Tools/ReloadServer/ReloadServer.sh
The ReloadServer python script can be run from any directory, and is located at Common_3/Tools/ReloadServer/ReloadServer.py
.
usage: ReloadServer.py [--port PORT] [--daemon] [--kill]
--port PORT : Choose port used by ReloadServer
--kill : Kill currently running ReloadServer (--daemon is ignored if this is passed).
--daemon : Run ReloadServer as a daemon process instead of directly in the terminal.
Only one server can run on a given port (regardless if running as daemon process or not).
If there is already a server running on the given port, the server script will print a message and exit instead of running another server on that port.
This can be useful when debugging potential issues.
When an error occurs during shader recompilation, the error message is sent to 3 different locations:
- Printed to
stdout
inReloadServer.py
script - useful for debugging when running directly from terminal - Written to
server-log.txt
next toReloadServer.py
- useful for debugging the daemon process - Sent to
App
and printed to device/IDE logs - useful for debugging errors in shader code
This error message can be one of two things:
- Generic error message returned by
ReloadServer.py
(i.e. path sent by device does not exist). - Shader compile error returned by
fsl.py
. In this case the entire outputstdout
is the error message.
ReloadServer is designed to be as fast and responsive as possible, so errors in shader compilation do not cause App
to stop running.
The reasoning is that compiling/running App
might take very long, whereas fixing ReloadServer issues can be done very quickly (and maybe can be done several times before App
can restart even once).
In the case of every failure, ReloadServer prints a detailed message to the App
logs about what might have gone wrong and how to fix it, which the developer can use to fix the issue (often in much less time than it takes to restart App
). The following most common issues can all quickly be fixed by glancing at device logs:
- User programming error in shader code (most commonly a typo)
- ReloadServer is not running when requesting shader recompile (usually only on XCode/Codelite where it needs to be run manually)