aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas James <Eele1Ephe7uZahRie@tutanota.com>2026-03-30 18:02:21 +1100
committerNicolas James <Eele1Ephe7uZahRie@tutanota.com>2026-03-30 18:02:21 +1100
commit7b17b60786d00c592f0ef18c8481148143baacbd (patch)
tree42ea87f660b42149d805e25b38086c4da68d9a6e
parent22f8e5196508c7075493c246edb9cb9cad097c45 (diff)
Add nvidia spoofing via LOW_LATENCY_LAYER_SPOOF_NVIDIA=1
-rw-r--r--src/layer.cc53
-rw-r--r--src/layer_context.cc1
-rw-r--r--src/layer_context.hh11
-rw-r--r--src/queue_context.cc1
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;