Files
NX2navi/tests/mesh_path_check.c
chrg6 46d71da8aa Draw task and mesh programs through the mesh fallback by default on AMD's Windows driver for RDNA 1 and 2, where native mesh pipelines lost the device in play; mesh_fallback = 0 draws them natively again.
Every RX 6000 loss whose pass marks named a pass was in one that starts with a native mesh draw, on every version from 0.6.0 to 0.9.2 and with every other setting tried each way; RDNA 1 cards on the same driver draw through the fallback and RDNA 3 and 4 on AMD's other driver draw natively, and neither has such a report. That the native mesh path is the cause is not shown. The decision moves into vk_mesh_path.h with a test of each device kind and setting; has_mesh_shader keeps saying what the hardware has, so the recorder thread and the low-end card test do not change. On those cards no native mesh pipeline is built any more: the seed list and the boot prewarm skip them. The early tail stays off with the fallback, a combination never measured. The fatal line names the mesh path, and NX2NAVI_VK_NOOPT's default applies with mesh_fallback = 0 alone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-13 12:54:24 -05:00

51 lines
3.2 KiB
C

// runtime/vk_mesh_path.h: how the game's task and mesh programs are drawn (vk_device.c create_device): natively, through
// the mesh fallback, the mesh emulation or not at all, for each device kind and setting. Built and run by
// tests/mesh_path_check.py; prints each failed check and exits 1 on any.
#include <stdio.h>
#include <string.h>
#include "vk_mesh_path.h"
static int fails;
#define CHECK(c, ...) do { if (!(c)) { fails++; printf("FAIL line %d: ", __LINE__); printf(__VA_ARGS__); printf("\n"); } } while (0)
static const char *const names[] = {"native", "fallback", "emulation", "none"};
static void expect(int has_mesh, int amd_sc, const char *mf, const char *me, int want, const char *what) {
const char *why = NULL;
int got = mesh_path_decide(has_mesh, amd_sc, mf, me, &why);
CHECK(got == want, "%s (mesh shaders %d, AMD RDNA 1/2 driver %d, mesh_fallback %s, mesh_emulation %s): %s, not %s",
what, has_mesh, amd_sc, mf, me, names[got], names[want]);
CHECK(why && *why, "%s: no reason for the boot line", what);
}
int main(void) {
// ---- the default (auto, emulation off) by device
expect(1, 0, "auto", "0", MESH_PATH_NATIVE, "NVIDIA, Intel, Mesa or AMD's RDNA 3/4 driver with mesh shaders");
expect(1, 1, "auto", "0", MESH_PATH_FALLBACK, "an RX 6000 card on AMD's RDNA 1/2 driver");
expect(0, 1, "auto", "0", MESH_PATH_FALLBACK, "an RX 5000 card on AMD's RDNA 1/2 driver (no mesh shaders)");
expect(0, 0, "auto", "0", MESH_PATH_FALLBACK, "a GTX 10 card (no mesh shaders)");
// ---- mesh_fallback = 0 gives an RX 6000 card native mesh pipelines back, as 0.10.1 drew them
expect(1, 1, "0", "0", MESH_PATH_NATIVE, "an RX 6000 card with mesh_fallback = 0");
expect(1, 0, "0", "0", MESH_PATH_NATIVE, "a card with mesh shaders and mesh_fallback = 0");
expect(0, 0, "0", "0", MESH_PATH_NONE, "a card without mesh shaders and mesh_fallback = 0");
// ---- mesh_fallback = 1 on every device
expect(1, 0, "1", "0", MESH_PATH_FALLBACK, "an NVIDIA card with mesh_fallback = 1");
expect(1, 1, "1", "0", MESH_PATH_FALLBACK, "an RX 6000 card with mesh_fallback = 1");
// ---- the mesh emulation acts only without mesh shaders, and then before the fallback
expect(0, 0, "auto", "1", MESH_PATH_EMULATION, "no mesh shaders, mesh_emulation = 1");
expect(0, 1, "1", "1", MESH_PATH_EMULATION, "no mesh shaders, both set");
expect(1, 1, "auto", "1", MESH_PATH_FALLBACK, "an RX 6000 card with mesh_emulation = 1 (low_end_gpu)");
expect(1, 0, "auto", "1", MESH_PATH_NATIVE, "a card with mesh shaders and mesh_emulation = 1");
// ---- a value the settings table does not list reads as auto
expect(1, 1, "", "0", MESH_PATH_FALLBACK, "an RX 6000 card with an empty mesh_fallback");
expect(1, 0, "yes", "0", MESH_PATH_NATIVE, "a card with mesh shaders and mesh_fallback = yes");
// ---- the reason names the driver default, and how to turn it off
const char *why = NULL;
mesh_path_decide(1, 1, "auto", "0", &why);
CHECK(why && strstr(why, "mesh_fallback = 0"), "the RX 6000 default's reason does not say how to turn it off: %s", why ? why : "(none)");
printf("mesh_path_check: %s\n", fails ? "FAILED" : "passed");
return fails ? 1 : 0;
}