[[TOC]] = 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 === * Read [https://trac.wildfiregames.com/browser/ps/trunk/source/tools/spirv/README.md source/tools/spirv/README.md] and perform required installations * Download rules for SVN or release from https://releases.wildfiregames.com/spir-v/rules.latest.json or https://releases.wildfiregames.com/spir-v/rules.0.0.27.json respectively * Run the script (usually it's necessary to provide modmod dependency as it provides important headers): {{{#!bash python source/tools/spirv/compile.py \ path-to-folder-with-input-mod rules-path mod-output-path [-d dependency-mod] }}} * Example to rebuild shaders inside a repository (it'll create the `binaries/data/mods/public/spirv` folder): {{{#!bash python source/tools/spirv/compile.py \ binaries/data/mods/public rules.json binaries/data/mods/public -d binaries/data/mods/mod }}} === Compiling new shader * Read [https://trac.wildfiregames.com/browser/ps/trunk/source/tools/spirv/README.md source/tools/spirv/README.md] and perform required installations * Create a rules file for the new shader, format: {{{#!json { "shader-program-name": { "combinations": [ [{"name": "DEFINE1", "value": "VALUE1"}, ...], ..., ], "name": "shader-program-name" }, ... } }}} * Example `rules.json` with a single combination for `model_water`: {{{#!json { "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): {{{#!bash 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: {{{#!bash 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 Tools]. == Profiling == Currently we don't support in-game profiling of Vulkan. Only external tools are applicable for now. See [#Tools 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. * '''RenderDoc''' - a free MIT licensed stand-alone graphics debugger (https://renderdoc.org/). It allows to capture frames and do a very simple profiling. * '''NVIDIA® NSight™''' - a free proprietary standalone developer tool that enables you to debug, and do extensive profiling (https://developer.nvidia.com/nsight-graphics, https://developer.nvidia.com/nsight-visual-studio-edition). Currently it doesn't work with Vulkan on Windows because we still build 32-bits application. #2611 should fix that.