mirror of
https://github.com/tangerineturtle1/NX2navi.git
synced 2026-11-15 19:19:58 -04:00
Turn graphics pipeline libraries off by default on AMD's Windows driver for RX 5000 and RX 6000 cards.
That driver faults inside vkCreateGraphicsPipelines when it links the stage libraries of a burst of new pipelines. The game asks for one when an enemy dies and its effects are drawn for the first time, so the game ended with code 71 at every kill on an RX 6700 XT and an RX 5700 XT (issue #418), and the player who reported it found that gpl = 0 stops it. Unset, the setting is now off with that driver (vk_caps.amd_sc) and on everywhere else; gpl = 1 turns it on there, gpl = 0 off anywhere, and the caps line of the log says why it is off. The price on those cards is that a new pipeline is built whole on the draw's path. Not run here: there is no AMD card. On an RTX 5090 the device probe reads "gpl yes" as before and "off by NX2NAVI_GPL=0" with the setting. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
This commit is contained in:
@@ -33,6 +33,13 @@ Draft notes for the release after 0.7.1. The version number is not decided yet.
|
||||
shader compiler"); with it each NaN test is now made on the bits of the number instead, which no compiler can drop.
|
||||
It is on by default only with that driver (`vk_nan_bits`); the first start after the update compiles the pipelines
|
||||
again. Untested on those cards before this release: please report whether the blocks are gone.
|
||||
- AMD RX 5000 and RX 6000 cards: the game no longer ends (code 71) when an enemy is killed. The Windows driver for
|
||||
these cards faults when it links a burst of new pipelines from shader libraries, which is what the first kill of a
|
||||
session asks for; players with an RX 6700 XT and an RX 5700 XT had it at every kill, and one of them found that
|
||||
`gpl = 0` stops it. That is now the default with this driver (the log reads "gpl no ... off by default on AMD's
|
||||
driver for RDNA 1 and 2"). The price: a pipeline the game needs for the first time is built whole while its draw
|
||||
waits, so a new area hitches more on these cards. `gpl = 1` in `nx2navi.ini` turns the libraries back on. A
|
||||
contributor's change, checked on their card; none of us has such a card.
|
||||
- The older installer's last step no longer writes `nx2navi.ini` again as a whole to set the language: it changes the
|
||||
`lang` line and keeps every other byte (it turned Windows line ends into Unix ones and dropped a byte order mark).
|
||||
|
||||
|
||||
@@ -184,7 +184,9 @@
|
||||
# the new translator cannot translate keeps its old translation. 0: shaders the new translator has not translated yet
|
||||
# are translated before they are used (at start or when the game first draws them), as earlier versions did.
|
||||
# shader_carry = 1
|
||||
# Vulkan graphics pipeline library, 0 or 1. Default: on.
|
||||
# Vulkan graphics pipeline library, 0 or 1. Default: on, except with AMD's Windows driver for RX 5000 and RX 6000
|
||||
# cards, which faults when it links a burst of new pipelines (the game ended at every enemy killed); there it is off,
|
||||
# new pipelines are built whole, and gpl = 1 turns it on again.
|
||||
# gpl = 1
|
||||
|
||||
# Textures and memory.
|
||||
|
||||
@@ -246,7 +246,7 @@ static const CfgMeta metas[] = {
|
||||
{"GATE_WAIT_MS", "10", "0..100", RESTART}, // vk_exec.c vk_exec_gate_wait
|
||||
{"LIB_PREBUILD", "1", "0|1", RESTART}, {"LIB_PREBUILD_THREADS", "", "1..64", RESTART},
|
||||
{"LIB_WARM", "1", "0|1|force", RESTART}, // vk_pipeline.c lw_start: the driver's cache of stage libraries, warmed when cold
|
||||
{"PIPE_PREBUILD", "1", "0|1", RESTART}, {"PREWARM_XLATE", "", "1..64", RESTART}, {"GPL", "1", "0|1", RESTART},
|
||||
{"PIPE_PREBUILD", "1", "0|1", RESTART}, {"PREWARM_XLATE", "", "1..64", RESTART}, {"GPL", "", "0|1", RESTART}, // vk_caps.c vk_caps_gpl: by the driver, off with AMD's for RDNA 1 and 2
|
||||
{"LIB_PREBUILD_BIG_BG", "1", "0|1", RESTART}, {"PIPE_FEEDBACK", "1", "0|1|2", RESTART},
|
||||
{"PIPELINE_CACHE_MAX_MB", "512", "0..65536", RESTART}, {"PIPE_BINARIES", "0", "0|1", RESTART}, {"ONESHOT_WAIT_MS", "30000", "0..60000", RESTART}, {"ONESHOT_BUDGET", "1", "0|1", RESTART}, {"PIPE_BINARIES_MAX_MB", "1024", "0..65536", RESTART}, {"BIG_BUILD_FREE_MB", "8192", "0..262144", RESTART},
|
||||
{"BIG_BUILD_MAX_MB", "4096", "0..262144", RESTART},
|
||||
|
||||
@@ -423,7 +423,8 @@ static const char *const text_en[UI_TEXT_COUNT] = {
|
||||
[UI_MENU_PREWARM_XLATE] = "Translator prewarm",
|
||||
[UI_MENU_PREWARM_XLATE_DESC] = "Threads that translate known shaders at start; Automatic takes half the CPU threads, at most 16.",
|
||||
[UI_MENU_GPL] = "Graphics pipeline library",
|
||||
[UI_MENU_GPL_DESC] = "Uses the Vulkan pipeline library extension; turn off if your driver misbehaves with it.",
|
||||
[UI_MENU_GPL_DESC] = "Uses the Vulkan pipeline library extension. Default: off on AMD's driver for RDNA 1 and 2, "
|
||||
"which crashes when it links a burst of new pipelines, on elsewhere.",
|
||||
[UI_MENU_ASTC] = "ASTC texture decoding", [UI_MENU_ASTC_DESC] = "Where compressed ASTC textures are decoded.",
|
||||
[UI_MENU_ASTC_AUTO] = "Automatic", [UI_MENU_ASTC_GPU] = "GPU shader", [UI_MENU_ASTC_NATIVE] = "Native",
|
||||
[UI_MENU_ASTC_CPU] = "CPU",
|
||||
@@ -985,7 +986,8 @@ static const char *const text_ru[UI_TEXT_COUNT] = {
|
||||
[UI_MENU_PREWARM_XLATE] = "Прогрев транслятора",
|
||||
[UI_MENU_PREWARM_XLATE_DESC] = "Потоки, которые при запуске переводят известные шейдеры; «Автоматически» — половина потоков процессора, не больше 16.",
|
||||
[UI_MENU_GPL] = "Библиотека графических конвейеров",
|
||||
[UI_MENU_GPL_DESC] = "Использует расширение Vulkan для библиотек конвейеров; выключите, если драйвер с ним сбоит.",
|
||||
[UI_MENU_GPL_DESC] = "Использует расширение Vulkan для библиотек конвейеров. По умолчанию выключено на драйвере AMD "
|
||||
"для RDNA 1 и 2, который падает, когда связывает много новых конвейеров, включено везде.",
|
||||
[UI_MENU_ASTC] = "Распаковка текстур ASTC", [UI_MENU_ASTC_DESC] = "Где распаковываются сжатые текстуры ASTC.",
|
||||
[UI_MENU_ASTC_AUTO] = "Автоматически", [UI_MENU_ASTC_GPU] = "Шейдер GPU", [UI_MENU_ASTC_NATIVE] = "Аппаратно",
|
||||
[UI_MENU_ASTC_CPU] = "Процессор",
|
||||
@@ -1375,7 +1377,8 @@ static const char *const text_pt_br[UI_TEXT_COUNT] = {
|
||||
[UI_MENU_PREWARM_XLATE] = "Pré-aquecimento do tradutor",
|
||||
[UI_MENU_PREWARM_XLATE_DESC] = "Threads que traduzem os shaders conhecidos ao iniciar; Automático usa metade das threads da CPU, no máximo 16.",
|
||||
[UI_MENU_GPL] = "Biblioteca de pipelines gráficos",
|
||||
[UI_MENU_GPL_DESC] = "Usa a extensão de biblioteca de pipelines do Vulkan; desligue se o seu driver tiver problemas com ela.",
|
||||
[UI_MENU_GPL_DESC] = "Usa a extensão de biblioteca de pipelines do Vulkan. Padrão: desligado no driver da AMD para "
|
||||
"RDNA 1 e 2, que trava ao vincular uma rajada de pipelines novos, ligado nos demais.",
|
||||
[UI_MENU_ASTC] = "Decodificação de texturas ASTC",
|
||||
[UI_MENU_ASTC_DESC] = "Onde as texturas comprimidas em ASTC são decodificadas.",
|
||||
[UI_MENU_ASTC_AUTO] = "Automático", [UI_MENU_ASTC_GPU] = "Shader da GPU", [UI_MENU_ASTC_NATIVE] = "Nativo",
|
||||
@@ -2025,7 +2028,8 @@ static const char *const text_zh_hans[UI_TEXT_COUNT] = {
|
||||
[UI_MENU_PREWARM_XLATE_DESC] = "启动时转译已知着色器的线程数;自动取 CPU 线程数的一半,"
|
||||
"最多 16。",
|
||||
[UI_MENU_GPL] = "图形管线库",
|
||||
[UI_MENU_GPL_DESC] = "使用 Vulkan 管线库扩展;驱动对此有问题时请关闭。",
|
||||
[UI_MENU_GPL_DESC] = "使用 Vulkan 管线库扩展。默认:在 AMD RDNA 1 和 2 驱动上关闭,因为驱动在链接大量新管线时会崩溃,"
|
||||
"其他平台默认开启。",
|
||||
[UI_MENU_ASTC] = "ASTC 纹理解码",
|
||||
[UI_MENU_ASTC_DESC] = "压缩的 ASTC 纹理在哪里解码。",
|
||||
[UI_MENU_ASTC_AUTO] = "自动",
|
||||
|
||||
@@ -58,7 +58,7 @@ typedef struct {
|
||||
uint32_t sbuf_align; // nonzero: storage buffers bind at their address rounded down to this
|
||||
uint32_t sg_size; // requiredSubgroupSize on sg_pin_stages (32)
|
||||
VkShaderStageFlags sg_pin_stages; // 0: no pin, stages run at the device's subgroupSize
|
||||
int gpl; // VK_EXT_graphics_pipeline_library enabled with fast linking (NX2NAVI_GPL=0: off)
|
||||
int gpl; // VK_EXT_graphics_pipeline_library enabled with fast linking (NX2NAVI_GPL=0/1; unset: off on AMD RDNA 1/2)
|
||||
int amd; // an AMD GPU (vendor 0x1002), any driver
|
||||
int amd_sc; // AMD's Windows driver branch for RDNA 1 and 2 ("AMD proprietary shader compiler")
|
||||
int amd_llpc; // AMD's own driver for RDNA 3 and newer (its driverInfo names LLPC)
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
// - minStorageBufferOffsetAlignment above 4 (NX2NAVI_VK_SSBO_ALIGN=<power of two> raises it): the translator computes
|
||||
// storage offsets from the guest address rounded down to that alignment (the translator's unaligned storage path), and
|
||||
// vk_exec_draw.c ssbo_info binds the rounded-down address, so shader writes reach guest memory instead of a copy.
|
||||
// - no graphics pipeline library with fast linking (NX2NAVI_GPL=0 forces it): vk_caps.gpl = 0, the extension stays disabled, and pipelines are built whole.
|
||||
// - no graphics pipeline library with fast linking (NX2NAVI_GPL=0 forces it; it also defaults off on AMD's RDNA 1/2
|
||||
// Windows driver branch, see vk_caps_gpl): vk_caps.gpl = 0, the extension stays disabled, and pipelines are built whole.
|
||||
// - no 32-lane pin (no subgroupSizeControl, 32 outside min..max, or NX2NAVI_VK_SUBGROUP_PIN=0): stages run at the
|
||||
// device's subgroupSize (SPIR-V 1.3 without a required size) and the translator is told that size.
|
||||
// NX2NAVI_VK_SUBGROUP=<n> pins n instead of 32 where the driver allows it.
|
||||
@@ -24,6 +25,7 @@
|
||||
VkCaps vk_caps = {.float64 = 1, .sg_size = 32};
|
||||
static int f64_supported;
|
||||
static VkBool32 gpl_lib, gpl_fast; // the driver's graphicsPipelineLibrary (feature), ...FastLinking (property)
|
||||
static const char *gpl_off; // why gpl is off, for the boot report; NULL when it is on
|
||||
static char summary[832]; // vk_caps_summary: written once, in vk_caps_init, before any other thread reads it
|
||||
|
||||
const char *vk_caps_summary(void) { return summary; }
|
||||
@@ -53,18 +55,26 @@ void vk_caps_driver(VkPhysicalDevice p) {
|
||||
drv.driverID == VK_DRIVER_ID_MESA_NVK;
|
||||
}
|
||||
|
||||
// NX2NAVI_GPL=0 turns graphics pipeline libraries off; they are on wherever the driver has fast linking. AMD's RDNA 1/2
|
||||
// driver branch had them off for a while: its device losses at boot (issue #5) came with a cold pipeline cache, but
|
||||
// their cause was GPU writes past 3D BC images (vk_exec.c, "3D BC render targets"). With that fixed, the RDNA 1/2
|
||||
// driver boots with GPL from a cold cache and fast-links without a failure, while with GPL off every new pipeline is
|
||||
// built whole on the draw's path (frames of 0.5-1.2 s on an RX 6600, issue #381). RDNA 4 under RADV is reported to
|
||||
// hang the GPU at the title screen with GPL.
|
||||
// NX2NAVI_GPL=0 turns graphics pipeline libraries off and 1 turns them on; unset, they are on wherever the driver has
|
||||
// fast linking, except on AMD's Windows driver for RDNA 1 and 2 (vk_caps.amd_sc). That driver faults inside
|
||||
// vkCreateGraphicsPipelines when it links the stage libraries of a burst of new pipelines, which the game asks for when
|
||||
// an enemy dies and its effects are drawn for the first time: the game ended with code 71 at every kill on an RX 6700 XT
|
||||
// and an RX 5700 XT (issue #418), and no longer with gpl = 0. The price there is that a new pipeline is built whole on
|
||||
// the draw's path (frames of 0.5-1.2 s on an RX 6600 while an area is new). The same driver had libraries off before,
|
||||
// for device losses at boot (issue #5), whose cause was GPU writes past 3D BC images (vk_exec.c, "3D BC render
|
||||
// targets"); it boots with them since that was fixed, so gpl = 1 is there to try on a newer driver. RDNA 4 under RADV
|
||||
// is reported to hang the GPU at the title screen with GPL.
|
||||
int vk_caps_gpl(const VkPhysicalDeviceGraphicsPipelineLibraryFeaturesEXT *f,
|
||||
const VkPhysicalDeviceGraphicsPipelineLibraryPropertiesEXT *p) {
|
||||
gpl_lib = f->graphicsPipelineLibrary;
|
||||
gpl_fast = p->graphicsPipelineLibraryFastLinking;
|
||||
const char *e = cfg_get("NX2NAVI_GPL");
|
||||
vk_caps.gpl = gpl_lib && gpl_fast && !(e && !strcmp(e, "0"));
|
||||
int want = !e || !*e ? !vk_caps.amd_sc : strcmp(e, "0") != 0;
|
||||
vk_caps.gpl = gpl_lib && gpl_fast && want;
|
||||
gpl_off = vk_caps.gpl ? NULL
|
||||
: !gpl_lib || !gpl_fast ? "the driver has no fast linking"
|
||||
: e && *e ? "NX2NAVI_GPL=0"
|
||||
: "default on AMD's driver for RDNA 1 and 2 (NX2NAVI_GPL=1 turns it on)";
|
||||
return vk_caps.gpl;
|
||||
}
|
||||
|
||||
@@ -158,8 +168,11 @@ void vk_caps_init(VkCtx *c) {
|
||||
has_ext(ep, ne, "VK_EXT_graphics_pipeline_library"), depth_ok(p, VK_FORMAT_D16_UNORM),
|
||||
depth_ok(p, VK_FORMAT_D24_UNORM_S8_UINT), depth_ok(p, VK_FORMAT_X8_D24_UNORM_PACK32), depth_ok(p, VK_FORMAT_D32_SFLOAT),
|
||||
depth_ok(p, VK_FORMAT_D32_SFLOAT_S8_UINT));
|
||||
char gpl_note[128];
|
||||
if (gpl_off) snprintf(gpl_note, sizeof gpl_note, ", off by %s", gpl_off);
|
||||
else gpl_note[0] = '\0';
|
||||
rt_log("vk caps: gpl %s fast-link %s (graphicsPipelineLibrary %u%s)", vk_caps.gpl ? "yes" : "no",
|
||||
gpl_fast ? "yes" : "no", (unsigned)gpl_lib, !gpl_lib || !gpl_fast || vk_caps.gpl ? "" : ", off by NX2NAVI_GPL=0");
|
||||
gpl_fast ? "yes" : "no", (unsigned)gpl_lib, gpl_note);
|
||||
rt_log("vk caps: fallbacks: float64 %s, storage buffers %s %u, subgroup pin %u on stages %#x, translator subgroup vs/fs/cs %u/%u/%u",
|
||||
vk_caps.float64 ? "native" : "softfloat64", vk_caps.sbuf_align ? "rounded down to" : "exact, alignment",
|
||||
(unsigned)l->minStorageBufferOffsetAlignment, want, (unsigned)vk_caps.sg_pin_stages, told[0], told[1], told[2]);
|
||||
|
||||
Reference in New Issue
Block a user