aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/layer.cc78
-rw-r--r--src/layer_context.cc11
-rw-r--r--src/layer_context.hh6
3 files changed, 87 insertions, 8 deletions
diff --git a/src/layer.cc b/src/layer.cc
index 5ddae67..91d6a23 100644
--- a/src/layer.cc
+++ b/src/layer.cc
@@ -115,6 +115,7 @@ CreateInstance(const VkInstanceCreateInfo* pCreateInfo,
INSTANCE_VTABLE_LOAD(EnumerateDeviceExtensionProperties);
INSTANCE_VTABLE_LOAD(GetPhysicalDeviceQueueFamilyProperties2);
INSTANCE_VTABLE_LOAD(GetPhysicalDeviceFeatures2);
+ INSTANCE_VTABLE_LOAD(GetPhysicalDeviceSurfaceCapabilities2KHR);
#undef INSTANCE_VTABLE_LOAD
const auto lock = std::scoped_lock{layer_context.mutex};
@@ -207,7 +208,8 @@ static VKAPI_ATTR VkResult VKAPI_CALL CreateDevice(
// explicitly ask for the extension when it creates the device.
const auto was_antilag_requested =
- requested.contains(VK_AMD_ANTI_LAG_EXTENSION_NAME);
+ requested.contains(VK_AMD_ANTI_LAG_EXTENSION_NAME) ||
+ requested.contains(VK_NV_LOW_LATENCY_2_EXTENSION_NAME);
const auto context = layer_context.get_context(physical_device);
if (!context->supports_required_extensions && was_antilag_requested) {
@@ -575,10 +577,19 @@ static VKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceExtensionProperties(
return VK_INCOMPLETE; // They gave us zero space to work with.
}
- pProperties[0] =
- VkExtensionProperties{.extensionName = VK_AMD_ANTI_LAG_EXTENSION_NAME,
- .specVersion = VK_AMD_ANTI_LAG_SPEC_VERSION};
+ // If we're spoofing nvidia we want to provide their extension instead.
+ const auto extension_properties = [&]() -> VkExtensionProperties {
+ if (context->instance.layer.should_spoof_nvidia) {
+ return {.extensionName = VK_NV_LOW_LATENCY_2_EXTENSION_NAME,
+ .specVersion = VK_NV_LOW_LATENCY_2_SPEC_VERSION};
+ }
+ return {.extensionName = VK_AMD_ANTI_LAG_EXTENSION_NAME,
+ .specVersion = VK_AMD_ANTI_LAG_SPEC_VERSION};
+ }();
+
+ pProperties[0] = extension_properties;
count = 1;
+
return VK_SUCCESS;
}
@@ -590,6 +601,13 @@ static VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceFeatures2(
vtable.GetPhysicalDeviceFeatures2(physical_device, pFeatures);
+ // Don't provide AntiLag if we're trying to spoof nvidia.
+ // Nvidia uses VkSurfaceCapabilities2KHR to determine if a surface
+ // is capable of reflex instead of AMD's physical device switch found here.
+ if (context->instance.layer.should_spoof_nvidia) {
+ return;
+ }
+
const auto feature = find_next<VkPhysicalDeviceAntiLagFeaturesAMD>(
pFeatures, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ANTI_LAG_FEATURES_AMD);
@@ -603,6 +621,55 @@ static VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceFeatures2KHR(
return low_latency::GetPhysicalDeviceFeatures2(physical_device, pFeatures);
}
+static VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceSurfaceCapabilities2KHR(
+ VkPhysicalDevice physical_device,
+ const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
+ VkSurfaceCapabilities2KHR* pSurfaceCapabilities) {
+
+ const auto context = layer_context.get_context(physical_device);
+ const auto& vtable = context->instance.vtable;
+
+ vtable.GetPhysicalDeviceSurfaceCapabilities2KHR(
+ physical_device, pSurfaceInfo, pSurfaceCapabilities);
+
+ // Don't do this unless we're spoofing nvidia.
+ if (!context->instance.layer.should_spoof_nvidia) {
+ return;
+ }
+
+ const auto lsc = find_next<VkLatencySurfaceCapabilitiesNV>(
+ pSurfaceCapabilities,
+ VK_STRUCTURE_TYPE_LATENCY_SURFACE_CAPABILITIES_NV);
+
+ if (!lsc) {
+ return;
+ }
+
+ // I kind of eyeballed these!
+ const auto supported_modes = std::vector<VkPresentModeKHR>{
+ VK_PRESENT_MODE_IMMEDIATE_KHR,
+ VK_PRESENT_MODE_MAILBOX_KHR,
+ VK_PRESENT_MODE_FIFO_KHR,
+ };
+ const auto num_supported_modes =
+ static_cast<std::uint32_t>(std::size(supported_modes));
+
+ // They're asking how many we want to return.
+ if (!lsc->pPresentModes) {
+ lsc->presentModeCount = static_cast<std::uint32_t>(num_supported_modes);
+ return;
+ }
+
+ // Finally we can write what surfaces are capable.
+ const auto num_to_write =
+ std::min(lsc->presentModeCount, num_supported_modes);
+
+ std::ranges::copy_n(std::begin(supported_modes), num_to_write,
+ lsc->pPresentModes);
+
+ lsc->presentModeCount = num_to_write;
+}
+
static VKAPI_ATTR void VKAPI_CALL
AntiLagUpdateAMD(VkDevice device, const VkAntiLagDataAMD* pData) {
const auto context = layer_context.get_context(device);
@@ -665,6 +732,9 @@ static const auto instance_functions = func_map_t{
low_latency::GetPhysicalDeviceFeatures2),
HOOK_ENTRY("vkGetPhysicalDeviceFeatures2KHR",
low_latency::GetPhysicalDeviceFeatures2KHR),
+
+ HOOK_ENTRY("vkGetPhysicalDeviceSurfaceCapabilities2KHR",
+ low_latency::GetPhysicalDeviceSurfaceCapabilities2KHR),
};
static const auto device_functions = func_map_t{
diff --git a/src/layer_context.cc b/src/layer_context.cc
index 28a94b5..4699202 100644
--- a/src/layer_context.cc
+++ b/src/layer_context.cc
@@ -4,12 +4,15 @@
#include <string_view>
namespace low_latency {
-
+
LayerContext::LayerContext() {
- this->is_antilag_1_enabled = []() -> auto {
- const auto env = std::getenv(LayerContext::SLEEP_AFTER_PRESENT_ENV);
+ const auto parse_bool_env = [](const auto& name) -> bool {
+ const auto env = std::getenv(name);
return env && std::string_view{env} == "1";
- }();
+ };
+
+ this->is_antilag_1_enabled = parse_bool_env(SLEEP_AFTER_PRESENT_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 316d540..da13dc6 100644
--- a/src/layer_context.hh
+++ b/src/layer_context.hh
@@ -53,11 +53,17 @@ class LayerContext final : public Context {
static constexpr auto SLEEP_AFTER_PRESENT_ENV =
"LOW_LATENCY_LAYER_SLEEP_AFTER_PRESENT";
+ // If this is not null and set to exactly "1", then VK_NV_LOW_LATENCY2
+ // should be provided instead of VK_AMD_anti_lag.
+ static constexpr auto SPOOF_NVIDIA_ENV =
+ "LOW_LATENCY_LAYER_SPOOF_NV_LOWLATENCY2";
+
public:
std::mutex mutex;
std::unordered_map<void*, std::shared_ptr<Context>> contexts;
bool is_antilag_1_enabled = false;
+ bool should_spoof_nvidia = false;
public:
LayerContext();