Vulkan

Vulkan is a modern cross-platform API for graphics and computing (similar to D3D12 and Metal). It was added as backend to Pyrogenesis in r27412. Vulkan drivers from different vendors are usually much lighter than GL ones. Vulkan supports multithreading, it means in the future we might try to utilize it after separating graphics and simulation.

Building shaders

Vulkan can't run pure GLSL shaders (which we use for GL), it uses a special binary format for shaders: SPIR-V. A shader program requires rules to be built. It's a JSON file which describes all combinations of shader programs with defines for each combination. Each rules file might contain combinations for a single or multiple shaders.

Recompiling existing shaders

Compiling new shader

  • Read source/tools/spirv/README.md and perform required installations
  • Create a rules file for the new shader, format:
    {
      "shader-program-name":
      {
        "combinations":
        [
          [{"name": "DEFINE1", "value": "VALUE1"}, ...],
          ...,
        ],
        "name": "shader-program-name"
      },
      ...
    }
    
  • Example rules.json with a single combination for model_water:
    {
      "model_water":
      {
        "combinations":
        [
          [{"name": "IGNORE_LOS", "value": "1"}, {"name": "USE_TRANSPARENT", "value": "1"}]
        ],
        "name": "model_water"
      }
    }
    
  • Run the script (usually it's necessary to provide modmod dependency as it provides important headers):
    python source/tools/spirv/compile.py \
      path-to-folder-with-input-mod rules-path mod-output-path -p shader-program-name
     [-d dependency-mod]
    
  • Example to build shader inside a repository:
    python source/tools/spirv/compile.py \
      binaries/data/mods/public rules.json binaries/data/mods/public -p model_waterfall -d binaries/data/mods/mod
    

Debugging

First of all we need to enable lightweight debug helpers:

renderer.backend.debuglabels = "true"
renderer.backend.debugmessages = "true"
renderer.backend.debugscopedlabels = "true"

They're making logs and captures more readable but don't cost performance noticeably.

The next step is to enable basic validation layers (usually it requires to have Vulkan SDK installed). They're making the game much slower but at the same time evaluating much more checks.

renderer.backend.debugcontext = "true"

If it's not enough then it needs to run the game via Vulkan configurator to setup validation layers more precisely (it also allows to enable GPU assist). Note: Currently validation layers might report false-positive hazards with enabled descriptor indexing because it can't properly check descriptor accesses yet: https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/3450. It's possible to hide them by disabling descriptor indexing:

renderer.backend.vulkan.disabledescriptorindexing = "true"

Usually it shouldn't change the game behavior noticeably because descriptor indexing only affects textures binding and not barriers.

Artifacts

Sometimes visual artifacts might caused by a synchronization issue or by missing or incorrect barriers. There're few options which might help to debug such cases.

Adds a strong execution and memory barrier after each framebuffer pass (during EndFramebufferPass):

renderer.backend.vulkan.debugbarrierafterframebufferpass = "true"

Waits GPU to be idle for a particular CPU step (uses vkDeviceWaitIdle under the hood):

renderer.backend.vulkan.debugwaitidlebeforeacquire = "true"
renderer.backend.vulkan.debugwaitidlebeforepresent = "true"
renderer.backend.vulkan.debugwaitidleafterpresent = "true"

See Tools.

Profiling

Currently we don't support in-game profiling of Vulkan. Only external tools are applicable for now.

See Tools.

Tools

A list of tested tools that work or not for Pyrogenesis. It's recommended to enable labels and scoped labels to make it easier to navigate through captures.

Last modified 11 months ago Last modified on Jun 5, 2023, 7:55:00 PM
Note: See TracWiki for help on using the wiki.