aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNicolas James <nj3ahxac@gmail.com>2026-03-11 23:17:09 +1100
committerNicolas James <nj3ahxac@gmail.com>2026-03-11 23:17:09 +1100
commit6c7c4770e840a467ec55266bedb20eaa21a9ae86 (patch)
treeac26f6d1e374486204cbeb6c1dc6a2ad5c28728c /src
parentdcfcd17a2b38c4efd50063a8c84821ac5fce5b1d (diff)
Don't inject timestamps when we have no reason to
Diffstat (limited to 'src')
-rw-r--r--src/device_context.cc4
-rw-r--r--src/device_context.hh5
-rw-r--r--src/layer.cc42
-rw-r--r--src/layer_context.hh2
-rw-r--r--src/queue_context.cc8
5 files changed, 43 insertions, 18 deletions
diff --git a/src/device_context.cc b/src/device_context.cc
index d246d73..273a958 100644
--- a/src/device_context.cc
+++ b/src/device_context.cc
@@ -9,9 +9,11 @@ namespace low_latency {
DeviceContext::DeviceContext(InstanceContext& parent_instance,
PhysicalDeviceContext& parent_physical_device,
const VkDevice& device,
+ const bool was_antilag_requested,
VkuDeviceDispatchTable&& vtable)
: instance(parent_instance), physical_device(parent_physical_device),
- device(device), vtable(std::move(vtable)) {
+ device(device), was_antilag_requested(was_antilag_requested),
+ vtable(std::move(vtable)) {
// Only create our clock if we can support creating it.
if (this->physical_device.supports_required_extensions) {
diff --git a/src/device_context.hh b/src/device_context.hh
index 7ec54d9..18b89be 100644
--- a/src/device_context.hh
+++ b/src/device_context.hh
@@ -23,6 +23,8 @@ struct DeviceContext final : public Context {
InstanceContext& instance;
PhysicalDeviceContext& physical_device;
+ const bool was_antilag_requested;
+
const VkDevice device;
const VkuDeviceDispatchTable vtable;
@@ -61,7 +63,8 @@ struct DeviceContext final : public Context {
public:
DeviceContext(InstanceContext& parent_instance,
PhysicalDeviceContext& parent_physical,
- const VkDevice& device, VkuDeviceDispatchTable&& vtable);
+ const VkDevice& device, const bool was_antilag_requested,
+ VkuDeviceDispatchTable&& vtable);
virtual ~DeviceContext();
public:
diff --git a/src/layer.cc b/src/layer.cc
index 126f465..6b91005 100644
--- a/src/layer.cc
+++ b/src/layer.cc
@@ -186,16 +186,31 @@ static VKAPI_ATTR VkResult VKAPI_CALL CreateDevice(
std::span{pCreateInfo->ppEnabledExtensionNames,
pCreateInfo->enabledExtensionCount};
- // Hook logic after create device looks like this.
- // !PHYS_SUPPORT && AL2_REQUESTED -> return INITIALIZATION_FAILED here.
- // !PHYS_SUPPORT && !AL2_REQUESTED -> hooks are no-ops
- // PHYS_SUPPORT -> hooks inject timestamps regardless
- // because AL1 might be used and it
- // costs virtually nothing to do.
+ const auto requested =
+ enabled_extensions |
+ std::ranges::to<std::unordered_set<std::string_view>>();
+
+ // There's the antilag extension that might be requested here - Antilag2.
+ // Then there's the other thing we provide, which is our AntiLag1
+ // equivalent. Calling them AL1 and AL2, where AL1 is requested via
+ // an env var and AL2 is requested at the device level via the extension,
+ // the cases where we exit with a bad code or deliberately no-op are:
+ //
+ // !SUPPORTED && !AL2 && !AL1 -> No-op hooks
+ // !SUPPORTED && !AL2 && AL1 -> No-op hooks
+ // !SUPPORTED && AL2 && !AL1 -> VK_ERROR_INITIALIZATION_FAILED
+ // !SUPPORTED && AL2 && AL1 -> VK_ERROR_INITIALIZATION_FAILED
+ // SUPPORTED && !AL2 && !AL1 -> No-op hooks.
+ //
+ // Note that even though the user has explicitly enabled AL1 via an env var,
+ // failing hard here by returning INIT_FAILED if the device doesn't support
+ // it is wrong. The vulkan application could just be creating a device that
+ // cannot support it which is unrelated to anything present related. This
+ // is not the case with AL2, because the vulkan application has to
+ // explicitly ask for the extension when it creates the device.
+
const auto was_antilag_requested =
- std::ranges::any_of(enabled_extensions, [](const auto& ext) {
- return std::string_view{ext} == VK_AMD_ANTI_LAG_EXTENSION_NAME;
- });
+ requested.contains(VK_AMD_ANTI_LAG_EXTENSION_NAME);
const auto context = layer_context.get_context(physical_device);
if (!context->supports_required_extensions && was_antilag_requested) {
@@ -225,13 +240,9 @@ static VKAPI_ATTR VkResult VKAPI_CALL CreateDevice(
return next_extensions;
}
- const auto already_requested =
- next_extensions |
- std::ranges::to<std::unordered_set<std::string_view>>();
-
// Only append the extra extension if it wasn't already asked for.
for (const auto& wanted : PhysicalDeviceContext::required_extensions) {
- if (already_requested.contains(wanted)) {
+ if (requested.contains(wanted)) {
continue;
}
@@ -290,7 +301,8 @@ static VKAPI_ATTR VkResult VKAPI_CALL CreateDevice(
assert(!layer_context.contexts.contains(key));
layer_context.contexts.try_emplace(
key, std::make_shared<DeviceContext>(context->instance, *context,
- *pDevice, std::move(vtable)));
+ *pDevice, was_antilag_requested,
+ std::move(vtable)));
return VK_SUCCESS;
}
diff --git a/src/layer_context.hh b/src/layer_context.hh
index c98768b..133fda8 100644
--- a/src/layer_context.hh
+++ b/src/layer_context.hh
@@ -69,7 +69,7 @@ struct LayerContext final : public Context {
}
template <DispatchableType DT>
- std::shared_ptr<dispatch_context_t<DT>> get_context(const DT& dt) {
+ std::shared_ptr<dispatch_context_t<DT>> get_context(const DT& dt) const {
const auto key = get_key(dt);
const auto lock = std::scoped_lock(this->mutex);
diff --git a/src/queue_context.cc b/src/queue_context.cc
index 9fe25b3..a3ff8a3 100644
--- a/src/queue_context.cc
+++ b/src/queue_context.cc
@@ -390,6 +390,14 @@ bool QueueContext::should_inject_timestamps() const {
return false;
}
+ // Don't bother injecting timestamps during queue submission if both AL1 and
+ // AL2 are disabled.
+ if (!this->device_context.was_antilag_requested &&
+ !pd.instance.layer.is_antilag_1_enabled) {
+
+ return false;
+ }
+
assert(pd.queue_properties);
const auto& queue_props = *pd.queue_properties;
assert(this->queue_family_index < std::size(queue_props));