Using binary shaders

Use binary shaders to reduce the loading time of a Kanzi application. By default Kanzi uses online shaders, which Kanzi Studio exports to a kzb file as source code. When you start a Kanzi application on a target device, the application loads and compiles the shaders using the GL driver. This compilation increases the loading time of the application. When you use binary shaders, Kanzi Studio compiles the shaders when you export the kzb file and exports the shaders in a binary format that you set. Your target device can use binary shaders immediately.

You can use binary shaders only on GPUs that have driver support for binary shaders. If the GPU does not support binary shaders, Kanzi Engine compiles shaders from the source. Even though the manufacturer of a device claims support for a specific binary shader format, this does not always mean that the device supports all binary shaders.

You can:

Using a common binary shader format

To use a common binary shader format:

  1. Identify the GPU vendor, GPU core version, and GPU driver version for the GPU used by your target device, and get the correct offline binary shader compiler from the GPU vendor.

  2. In Kanzi Studio in the Library, press Alt and right-click Materials and Textures > Shader Formats and select Binary Shader Format.

    ../../_images/create-binary-shader-format.png
  3. Name the binary shader format after the GPU used by your target device:

    GPU vendor

    Name

    Imagination Technologies

    SGX_BINARY_IMG, or IMG

    ARM Mali

    MALI_SHADER_BINARY_ARM

    Vivante

    SHADER_BINARY_VIV

    Digital Media Professionals

    SHADER_BINARY_DMP

    Fujitsu Semiconductor

    GCCSO_SHADER_BINARY_FJ

    NVidia

    NVIDIA_PLATFORM_BINARY_NV, or Tegra

    Various

    SPIR-V

    If your target device uses any other GPU and you have the offline shader compiler for that GPU, use for the name the decimal value of the shader format GL constant value.

  4. In the Properties, set:

    • Enabled property to take the binary shader format into use.

      When you enable the Enabled property, Kanzi Studio compiles the shaders in your Kanzi Studio project. Kanzi Studio shows in the Log window whether the compilers you use successfully compiled the shaders.

    • (Optional) Theme to the baked theme created for the target device which requires this binary shader format.

      When you deploy your application to different devices with different GPUs that support binary shaders, use themes to include in a kzb file the binary shaders only in the format required by the hardware of a specific target device. See Setting binary shaders in a project for multiple target devices.

    • Shader Compile to the shader compiler executable and command line for your target device GPU.

      Kanzi prepends this to the individual shader stages. You can use this to set common options for all shader stages.

      Use the Kanzi Studio macros to tell the compiler where to store the shader binary. For example, BinaryShaderCompilerExecutable <vertexshadercode> <vertexshaderbinary>.

      The shader code and shader binary are temporary files on the file system. The shader compiler reads from the <shadercode> and writes to <outputfile>. If your compiler outputs a binary with a suffix, use a wrapper script to output only the binary without the suffix.

      The <shadertype> macro expands to the type of the shader that is currently compiled:

      Shader type

      Expands to

      Vertex shader

      vertex

      Fragment shader

      fragment

      Geometry shader

      geometry

      Tessellation control shader

      tesscontrol

      Tessellation evaluation shader

      tesseval

      These values map directly to the shader stage types expected by the glslc -fshader-stage option.

      For example:

      glslc --target-env=opengl -fshader-stage=<shadertype> -o <outputfile> <shadercode>
      
    • These properties to set the options that are specific to the compiler executable of a specific shader type on your target device GPU:

      • Vertex Shader Compile to the options that are specific to the vertex shader compiler executable.

      • Fragment Shader Compile to the options that are specific to the fragment shader compiler executable.

      • Geometry Shader Compile to the options that are specific to the geometry shader compiler executable.

      • Tessellation Control Shader Compile to the options that are specific to the tessellation control shader compiler executable.

      • Tessellation Evaluation Shader Compile to the options that are specific to the tessellation evaluation shader compiler executable.

      For each shader type, use the Kanzi Studio macros to tell the compiler where to store the shader binary. For example, BinaryShaderCompilerExecutable <shadercode> <outputfile>.

      The shader code and shader binary are temporary files on the file system. The shader compiler reads from the <shadercode> and writes to <outputfile>. If your compiler outputs a binary with a suffix, use a wrapper script to output only the binary without the suffix.

    • When a GPU vendor provides a compiler that combines all types of shaders, set Combined Compile to the shader compiler location and options.

      For optimal use of resources, use either Vertex Shader Compile and Fragment Shader Compile or Combined Compile, but not both. You can find the details for your extension in the Khronos OpenGL registry.

      You can use the <vertexshadercode> and <fragmentshadercode> macros to point to individual sources and the <shaderbinary> macro for the combined output file.

      When you set the Combined Compile property, use these names:

      GPU vendor

      Name

      Imagination Technologies

      SGX_PROGRAM_BINARY_IMG

      ARM Mali

      MALI_PROGRAM_BINARY_ARM

      Vivante

      PROGRAM_BINARY_VIV

      Digital Media Professionals

      • SMAPHS30_PROGRAM_BINARY_DMP

      • SMAPHS_PROGRAM_BINARY_DMP

      • DMP_PROGRAM_BINARY_DMP

      NVidia

      NVIDIA_PROGRAM_BINARY_NV

      AMD

      Z400_BINARY_AMD

  5. Test whether the binary shaders work on your target device:

    1. Select File > Export > Export KZB.

      ../../_images/export-kzb-binary.png
    2. Start your Kanzi application on your target device and check the application log. If there are no errors related to binary shaders, the binary shaders work. See Deploying Kanzi applications.

Overriding Kanzi shaders with binary shaders

Kanzi comes with a set of default material types that it uses to perform basic rendering operations, such as rendering text or blitting a texture. Kanzi stores the default material types in dedicated kzb files which are embedded in the Kanzi kzcoreui and kzui libraries. The default material types only have source shaders, which is why Kanzi takes some time to compile the shaders during application startup or when it acquires the shaders during application runtime. To reduce the startup time of your Kanzi application, you can override the built-in source shaders of the default material types with the binary shaders for your target device.

To override Kanzi shaders with binary shaders:

  1. In Kanzi Studio open either:

    • The <KanziWorkspace>/Assets/RuntimeAssets/Tool_project/RuntimeAssets.kzproj Kanzi Studio project.

    • The main project of your Kanzi application, in the Library press Alt and right-click Project References, select Existing Project, and select the <KanziWorkspace>/Assets/RuntimeAssets/Tool_project/RuntimeAssets.kzproj Kanzi Studio project. See Combining Kanzi Studio projects into a Kanzi application. Kanzi Studio loads the RuntimeAssets project in a new tab.

      ../../_images/project-reference-create-existing-project.png ../../_images/runtimeassets-project-tab.png
  2. (Optional) If you do not want to override all Kanzi default shaders with binary shaders, in the RuntimeAssets project delete:

    • The materials whose shaders you do not want to override with binary shaders.

    • The material types and shader files used by those materials.

  3. Create the binary shader format for your target device. See Using a common binary shader format.

  4. In the RuntimeAssets project:

    1. In the main menu select Project > Properties and in the Properties:

      • Disable the Export Shader Source Code property.

        To reduce the size of the kzb file, do not export the shader source code.

      • Make sure that Property Namespace is empty

      ../../_images/runtimeassets-project-menu.png ../../_images/disable-export-shader-source-code.png
    2. In the Node Tree select the RuntimeAssetsScreen node and in the Properties make sure that the Disable KZB Export property is enabled.

      ../../_images/runtimeassetsscreen-disable-kzb-export.png
  5. Select File > Export > Export KZB.

    Kanzi Studio creates in the <KanziWorkspace>/Assets/RuntimeAssets/Tool_project/Binary directory the RuntimeAssets.kzb file.

    ../../_images/export-kzb-binary.png
  6. Register the RuntimeAssets.kzb file in the resource manager of your Kanzi application in one of these ways:

    • If your Kanzi application loads startup kzb files using a kzb configuration file, add the RuntimeAssets.kzb to the kzb configuration file <project_name>.kzb.cfg of the main project of your application.

    • If you added the RuntimeAssets.kzproj as a project reference to the main Kanzi Studio project of your application, when you export the kzb file of the main project, Kanzi Studio automatically adds the RuntimeAssets.kzb to the kzb configuration file of the main project.

    • If you manually load the startup kzb files, add the RuntimeAssets.kzb file to the resource manager of your Kanzi application using the ResourceManager::addKzbFile function.

      // At application startup register the RuntimeAssets.kzb file to the resource manager.
      void onStartup() override
      {
          getResourceManager()->addKzbFile("RuntimeAssets.kzb");
      }
      
  7. If your application contains 3D text, repeat the procedure using the <KanziWorkspace>/Assets/kzuiassets/Tool_project/kzuiassets.kzproj Kanzi Studio project.

    The kzuiassets project contains the material type that Kanzi by default uses to render 3D text.

When you run your Kanzi application, it loads the binary shaders from your RuntimeAssets.kzb and kzuiassets.kzb files, instead of using the built-in source shaders. This reduces the startup time of your Kanzi application, because Kanzi Engine does not need to compile the source shaders.

Setting binary shaders in a project for multiple target devices

In your Kanzi solution each Kanzi Studio project that contains shaders needs only one binary shader format for each type of a target device. In Kanzi Studio you can use themes to include in each kzb file only the binary shaders required by a specific target device. When your Kanzi Studio solution contains several projects, you can store the shaders, material types, and materials in a dedicated resource project. This enables you to manage the content for different target devices in a single project.

To set binary shaders in a project for multiple target devices:

  1. In the Library > Themes create a Theme Group and in the Properties enable the Export Baked Usages property.

    You use this Theme Group where you create themes for each target device that requires a different binary shader format.

    When you enable the Export Baked Usages property you can bake the resources from themes in this theme group.

    See Baked Themes.

    ../../_images/target-hardware-theme-group-in-library.png ../../_images/target-hardware-theme-group-properties.png
  2. In the Library > Themes double-click the Theme Group that you created in the previous step and in the Theme Editor create a theme for each target device that requires a different binary shader format. See Using Themes.

    ../../_images/create-themes-for-target-hardware.png
  3. In the Library > Materials and Textures > Shader Formats select each Binary Shader Format that you want to use and in the Properties set the Theme property to the theme that you created in the previous step for the target device which requires this binary shader format.

    This way you set Kanzi Studio to export this Binary Shader Format with this baked theme.

    ../../_images/sgx_binary_img-properties.png
  4. Select File > Export > Export Baked Theme Binaries and in the Themes and Locales to Bake on Export window for the Theme Group that you created select either < All > to bake all themes in that Theme Group or a specific theme that you want to bake. See Exporting baked Themes.

    ../../_images/export-baked-theme-binaries.png ../../_images/export-baked-target-hardware-themes.png

When you export the baked themes, Kanzi Studio includes in each kzb file material types that have only the type of binary shaders that you set for that baked theme.

Caching shader binaries

On performance-constrained platforms, shader compilations can considerably slow down the application startup and decrease runtime performance. If your platform does not offer offline shader compilation tools, you can use a shader binary cache primed with the set of shaders that your application requires. This way, your application does not have to compile shaders from source at runtime.

To cache shader binaries, in the application configuration:

  1. Set the directory where you want to store the shader binary cache. See ShaderBinaryCacheDirectory.

  2. Enable the caching. See ShaderBinaryCacheEnabled.

  3. (Optional) To guard against hash collisions, during development, you can set your application to store the shader source code and perform a full string comparison to make sure that the shaders are identical. If two shaders produce the same hash value, the application logs a warning. See ShaderBinaryCacheCollisionCheck.

  4. (Optional) When your application is ready for production, you can make the shader binary cache read-only. See ShaderBinaryCacheReadOnly.

For example, either:

  • In the application.cfg configuration file, add

    # Set the shader binary cache directory to /tmp/shader-cache/.
    ShaderBinaryCacheDirectory = "/tmp/shader-cache/"
    
    # Enable the caching of shader binaries.
    ShaderBinaryCacheEnabled = true
    
    # Enable checking for hash collisions in cached shaders.
    # Use this only during development.
    ShaderBinaryCacheCollisionCheck = true
    
  • In the C++ application in the Application::onConfigure function, add

    // Set the shader binary cache directory to /tmp/shader-cache/.
    configuration.shaderBinaryCacheDirectory = "/tmp/shader-cache/";
    
    // Enable the caching of shader binaries.
    configuration.shaderBinaryCacheEnabled = true;
    
    // Enable checking for hash collisions in cached shaders.
    // Use this only during development.
    configuration.shaderBinaryCacheCollisionCheck = true;
    

See also

Deploying Kanzi applications

Reducing shader switches

Optimizing fragment shaders

Loading resources in parallel

Shaders best practices

Troubleshooting the performance of your application

Best practices

Combining Kanzi Studio projects into a Kanzi application

Theming your applications

Using Themes

Exporting Themes

Application development

Application configuration reference