diff options
| author | Nicolas James <Eele1Ephe7uZahRie@tutanota.com> | 2026-03-30 18:02:21 +1100 |
|---|---|---|
| committer | Nicolas James <Eele1Ephe7uZahRie@tutanota.com> | 2026-03-30 18:02:21 +1100 |
| commit | 7b17b60786d00c592f0ef18c8481148143baacbd (patch) | |
| tree | 42ea87f660b42149d805e25b38086c4da68d9a6e | |
| parent | 22f8e5196508c7075493c246edb9cb9cad097c45 (diff) | |
Add nvidia spoofing via LOW_LATENCY_LAYER_SPOOF_NVIDIA=1
| -rw-r--r-- | src/layer.cc | 53 | ||||
| -rw-r--r-- | src/layer_context.cc | 1 | ||||
| -rw-r--r-- | src/layer_context.hh | 11 | ||||
| -rw-r--r-- | src/queue_context.cc | 1 |
4 files changed, 66 insertions, 0 deletions
diff --git a/src/layer.cc b/src/layer.cc index 3f31979..78a63d3 100644 --- a/src/layer.cc +++ b/src/layer.cc @@ -72,6 +72,8 @@ CreateInstance(const VkInstanceCreateInfo* pCreateInfo, INSTANCE_VTABLE_LOAD(DestroyInstance); INSTANCE_VTABLE_LOAD(EnumeratePhysicalDevices); INSTANCE_VTABLE_LOAD(GetPhysicalDeviceProperties); + INSTANCE_VTABLE_LOAD(GetPhysicalDeviceProperties2); + INSTANCE_VTABLE_LOAD(GetPhysicalDeviceProperties2KHR); INSTANCE_VTABLE_LOAD(GetInstanceProcAddr); INSTANCE_VTABLE_LOAD(CreateDevice); INSTANCE_VTABLE_LOAD(EnumerateDeviceExtensionProperties); @@ -634,6 +636,50 @@ static VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceFeatures2KHR( return GetPhysicalDeviceFeatures2(physical_device, pFeatures); } +static VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceProperties( + VkPhysicalDevice physical_device, VkPhysicalDeviceProperties* pProperties) { + + const auto context = layer_context.get_context(physical_device); + const auto& vtable = context->instance.vtable; + + vtable.GetPhysicalDeviceProperties(physical_device, pProperties); + + if (layer_context.should_spoof_nvidia) { + pProperties->vendorID = LayerContext::NVIDIA_VENDOR_ID; + pProperties->deviceID = LayerContext::NVIDIA_DEVICE_ID; + + // Most games seem happy without doing this, but I don't see why we + // shouldn't. I could see an application checking this. + std::strncpy(pProperties->deviceName, LayerContext::NVIDIA_DEVICE_NAME, + VK_MAX_PHYSICAL_DEVICE_NAME_SIZE); + } +} + +// Identical logic to GetPhysicalDeviceProperties. +static VKAPI_ATTR void VKAPI_CALL +GetPhysicalDeviceProperties2(VkPhysicalDevice physical_device, + VkPhysicalDeviceProperties2* pProperties) { + + const auto context = layer_context.get_context(physical_device); + const auto& vtable = context->instance.vtable; + + vtable.GetPhysicalDeviceProperties2(physical_device, pProperties); + + if (layer_context.should_spoof_nvidia) { + pProperties->properties.vendorID = LayerContext::NVIDIA_VENDOR_ID; + pProperties->properties.deviceID = LayerContext::NVIDIA_DEVICE_ID; + std::strncpy(pProperties->properties.deviceName, + LayerContext::NVIDIA_DEVICE_NAME, + VK_MAX_PHYSICAL_DEVICE_NAME_SIZE); + } +} + +static VKAPI_ATTR void VKAPI_CALL +GetPhysicalDeviceProperties2KHR(VkPhysicalDevice physical_device, + VkPhysicalDeviceProperties2* pProperties) { + return GetPhysicalDeviceProperties2(physical_device, pProperties); +} + static VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceSurfaceCapabilities2KHR( VkPhysicalDevice physical_device, const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, @@ -872,6 +918,13 @@ static const auto instance_functions = func_map_t{ HOOK_ENTRY("vkGetPhysicalDeviceFeatures2KHR", low_latency::GetPhysicalDeviceFeatures2KHR), + HOOK_ENTRY("vkGetPhysicalDeviceProperties", + low_latency::GetPhysicalDeviceProperties), + HOOK_ENTRY("vkGetPhysicalDeviceProperties2KHR", + low_latency::GetPhysicalDeviceProperties2KHR), + HOOK_ENTRY("vkGetPhysicalDeviceProperties2", + low_latency::GetPhysicalDeviceProperties2), + HOOK_ENTRY("vkGetPhysicalDeviceSurfaceCapabilities2KHR", low_latency::GetPhysicalDeviceSurfaceCapabilities2KHR), }; diff --git a/src/layer_context.cc b/src/layer_context.cc index 4399338..93f4a26 100644 --- a/src/layer_context.cc +++ b/src/layer_context.cc @@ -12,6 +12,7 @@ LayerContext::LayerContext() { }; this->should_expose_reflex = parse_bool_env(EXPOSE_REFLEX_ENV); + this->should_spoof_nvidia = parse_bool_env(SPOOF_NVIDIA_ENV); } LayerContext::~LayerContext() {} diff --git a/src/layer_context.hh b/src/layer_context.hh index 731b273..4979379 100644 --- a/src/layer_context.hh +++ b/src/layer_context.hh @@ -52,11 +52,22 @@ class LayerContext final : public Context { // provided instead of VK_AMD_anti_lag. static constexpr auto EXPOSE_REFLEX_ENV = "LOW_LATENCY_LAYER_EXPOSE_REFLEX"; + // If this is not null and set to 1 then the card's vendor and id will be + // spoofed to appear as a NVIDIA card. + static constexpr auto SPOOF_NVIDIA_ENV = "LOW_LATENCY_LAYER_SPOOF_NVIDIA"; + + public: + // Constants for spoofing. + static constexpr auto NVIDIA_VENDOR_ID = 0x10DE; + static constexpr auto NVIDIA_DEVICE_ID = 0x2B85; // 5090 + static constexpr auto NVIDIA_DEVICE_NAME = "NVIDIA GeForce RTX 5090"; + public: std::mutex mutex; std::unordered_map<void*, std::shared_ptr<Context>> contexts; bool should_expose_reflex = false; + bool should_spoof_nvidia = false; public: LayerContext(); diff --git a/src/queue_context.cc b/src/queue_context.cc index 1192bb6..437a183 100644 --- a/src/queue_context.cc +++ b/src/queue_context.cc @@ -76,6 +76,7 @@ void QueueContext::notify_submit( void QueueContext::notify_present(const VkSwapchainKHR& swapchain, const present_id_t& present_id) { + // Notify the device that this swapchain was just presented to. // We're avoiding a double hash here - don't use operator[] and erase. auto iter = this->unpresented_submissions.try_emplace(present_id).first; |
