mirror of
https://github.com/tangerineturtle1/NX2navi.git
synced 2026-11-15 19:19:58 -04:00
Start the game when DLSS Frame Generation is on and the chosen graphics card is not an NVIDIA one.
Four players of 0.10.1 could not start the game again after changing settings: "no usable Vulkan device", exit code 70, until nx2navi.ini was edited or removed by hand. One log shows the case: a laptop with an RTX 3050 and Intel Iris Xe graphics, framegen = dlss and gpu_index = 1, the Intel one. With frame generation on, the device is made through Streamline's interposer, which asks it for VK_NV_low_latency2 and failed with VK_ERROR_EXTENSION_NOT_PRESENT, and nothing else was tried. A chosen card of another vendor now counts as not usable while the interposer is in use, so the best usable card is taken, as for a chosen card that is gone. Where the card in use is still not an NVIDIA one, or the interposer fails to make the device for another reason, the loader makes it and frame generation is off for the run: the log says why and the settings menu shows it as unavailable, as it does when Streamline's files are missing. Not run: no PC here has two cards of different vendors. The changed files compile. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
This commit is contained in:
@@ -268,6 +268,14 @@ retry:
|
||||
VK_API_VERSION_MAJOR(p.apiVersion), VK_API_VERSION_MINOR(p.apiVersion), VK_API_VERSION_PATCH(p.apiVersion));
|
||||
if (want >= 0 && (int)i != want) continue;
|
||||
if (name && *name && !name_has(p.deviceName, name)) continue;
|
||||
// A chosen card of another vendor while DLSS Frame Generation is on: the interposer cannot make its device
|
||||
// (vk_dlssg_create_device), and the settings ask for what only an NVIDIA card runs. Not usable, so the best
|
||||
// usable one is taken below, as for a card that is gone; where no NVIDIA card is usable either, the pass
|
||||
// without a choice takes what there is and the device is made without frame generation.
|
||||
if ((want >= 0 || (name && *name)) && vk_dlssg_interposed() && p.vendorID != 0x10de) {
|
||||
rt_log("vk: gpu %u skipped: DLSS Frame Generation is on (framegen = dlss), which only an NVIDIA card runs", i);
|
||||
continue;
|
||||
}
|
||||
if (p.apiVersion < VK_API_VERSION_1_3) { rt_log("vk: gpu %u skipped: Vulkan below 1.3", i); continue; }
|
||||
const char *miss = missing_required(pd[i]);
|
||||
if (miss) { rt_log("vk: gpu %u skipped: missing extension %s", i, miss); continue; }
|
||||
|
||||
@@ -199,9 +199,34 @@ VkResult vk_dlssg_enumerate(VkInstance inst, uint32_t *n, VkPhysicalDevice *pd)
|
||||
return f ? f(inst, n, pd) : vkEnumeratePhysicalDevices(inst, n, pd);
|
||||
}
|
||||
|
||||
int vk_dlssg_interposed(void) { return S.loaded > 0; }
|
||||
|
||||
// Frame generation is off for the run from here on: every later call goes to the loader alone, as when Streamline's
|
||||
// files are missing, and the settings menu says it is unavailable (vk_dlssg_status).
|
||||
static void give_up(const char *why) {
|
||||
S.loaded = -1, S.fail = DLSSG_UNAVAILABLE;
|
||||
rt_log("dlssg: DLSS Frame Generation is off in this run: %s", why);
|
||||
}
|
||||
|
||||
// The interposer's vkCreateDevice asks the device for NVIDIA's extensions (VK_NV_low_latency2 among them) and fails
|
||||
// without them (VK_ERROR_EXTENSION_NOT_PRESENT). On a laptop with an NVIDIA card and Intel graphics, frame generation
|
||||
// set to DLSS and the Graphics card setting on the Intel one, that ended every start with "no usable Vulkan device"
|
||||
// (exit code 70) until nx2navi.ini was edited by hand: four reports on 0.10.1. A device of another vendor is now made
|
||||
// by the loader, without frame generation, and so is one the interposer refuses for any other reason.
|
||||
VkResult vk_dlssg_create_device(VkInstance inst, VkPhysicalDevice pd, const VkDeviceCreateInfo *ci, VkDevice *out) {
|
||||
if (S.loaded > 0) {
|
||||
VkPhysicalDeviceProperties p;
|
||||
vkGetPhysicalDeviceProperties(pd, &p);
|
||||
if (p.vendorID != 0x10de) give_up("the graphics card in use is not an NVIDIA card (the Graphics card setting, gpu_index)");
|
||||
}
|
||||
PFN_vkCreateDevice f = S.loaded > 0 ? (PFN_vkCreateDevice)S.gipa()(inst, "vkCreateDevice") : NULL;
|
||||
return f ? f(pd, ci, NULL, out) : vkCreateDevice(pd, ci, NULL, out);
|
||||
if (!f) return vkCreateDevice(pd, ci, NULL, out);
|
||||
VkResult r = f(pd, ci, NULL, out);
|
||||
if (r == VK_SUCCESS) return r;
|
||||
char why[96];
|
||||
snprintf(why, sizeof why, "Streamline could not make the device (%d)", (int)r);
|
||||
give_up(why);
|
||||
return vkCreateDevice(pd, ci, NULL, out);
|
||||
}
|
||||
|
||||
void vk_dlssg_device_ready(VkPhysicalDevice physical, VkDevice dev) {
|
||||
|
||||
@@ -9,6 +9,9 @@ int vk_dlssg_early(void); // before the instance exists: loads the DLL and St
|
||||
VkResult vk_dlssg_create_instance(const VkInstanceCreateInfo *ci, VkInstance *out);
|
||||
VkResult vk_dlssg_enumerate(VkInstance inst, uint32_t *n, VkPhysicalDevice *pd); // through the interposer too
|
||||
PFN_vkVoidFunction vk_dlssg_instance_proc(VkInstance inst, const char *name); // the interposer's, or NULL
|
||||
int vk_dlssg_interposed(void); // Streamline's proxies are in use (until a device is made without them)
|
||||
// The device through the interposer; by the loader alone, with frame generation off for the run, when the card is not
|
||||
// an NVIDIA one or the interposer fails to make it.
|
||||
VkResult vk_dlssg_create_device(VkInstance inst, VkPhysicalDevice pd, const VkDeviceCreateInfo *ci, VkDevice *out);
|
||||
void vk_dlssg_device_ready(VkPhysicalDevice physical, VkDevice dev); // after the device: checks DLSS-G and takes the swapchain hooks
|
||||
PFN_vkGetDeviceProcAddr vk_dlssg_dpa(void); // Streamline's device entry points, or NULL when it is not in use
|
||||
|
||||
Reference in New Issue
Block a user