aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNicolas James <nj3ahxac@gmail.com>2026-03-12 19:13:55 +1100
committerNicolas James <nj3ahxac@gmail.com>2026-03-12 19:13:55 +1100
commit8fb45371b8a0d47a387f9e0c50e7700af14e3a7e (patch)
treedb18874ca2547777783bc1acf20bcb08f22ed7b1 /src
parent44d88e25df14b7e191a15bfbe002a875d7c67056 (diff)
Check for bad returns on vulkan calls (lol!)
Diffstat (limited to 'src')
-rw-r--r--src/context.hh10
-rw-r--r--src/device_context.cc8
-rw-r--r--src/layer.cc5
-rw-r--r--src/layer_context.hh2
-rw-r--r--src/physical_device_context.cc10
-rw-r--r--src/queue_context.cc4
-rw-r--r--src/timestamp_pool.cc29
7 files changed, 39 insertions, 29 deletions
diff --git a/src/context.hh b/src/context.hh
index 91fbf91..6524984 100644
--- a/src/context.hh
+++ b/src/context.hh
@@ -3,6 +3,11 @@
namespace low_latency {
+#define THROW_NON_VKSUCCESS(x) \
+ if (const auto result = x; result != VK_SUCCESS) { \
+ throw result; \
+ }
+
// A context class doesn't do much by itself. We just use it to provide a
// virtual destructor so we can store a bunch of shared_ptrs in the same
// container and rely on RTTI in the layer context. It also deletes the copy and
@@ -10,10 +15,9 @@ namespace low_latency {
//
// We _could_ do something weird and complicated where we define virtual pure
// hashing and equality functions so we can store them in an unordered_set, but
-// it's just unnecessary complexity and doesn't allow us to perform 'do you exist'
-// lookups without creating an object.
+// it's just unnecessary complexity and doesn't allow us to perform 'do you
+// exist' lookups without creating an object.
class Context {
-
public:
Context();
Context(const Context& context) = delete;
diff --git a/src/device_context.cc b/src/device_context.cc
index c192ec6..0f606b5 100644
--- a/src/device_context.cc
+++ b/src/device_context.cc
@@ -48,9 +48,11 @@ void DeviceContext::Clock::calibrate() {
std::uint64_t host;
};
auto calibrated_result = CalibratedResult{};
- device.vtable.GetCalibratedTimestampsKHR(device.device, 2, std::data(infos),
- &calibrated_result.device,
- &this->error_bound);
+
+ THROW_NON_VKSUCCESS(device.vtable.GetCalibratedTimestampsKHR(
+ device.device, 2, std::data(infos), &calibrated_result.device,
+ &this->error_bound));
+
this->device_ticks = calibrated_result.device;
this->host_ns = calibrated_result.host;
}
diff --git a/src/layer.cc b/src/layer.cc
index d547888..24898a3 100644
--- a/src/layer.cc
+++ b/src/layer.cc
@@ -394,7 +394,6 @@ vkQueueSubmit(VkQueue queue, std::uint32_t submit_count,
const VkSubmitInfo* submit_infos, VkFence fence) {
const auto context = layer_context.get_context(queue);
-
const auto& vtable = context->device_context.vtable;
if (!submit_count || !context->should_inject_timestamps()) {
@@ -479,7 +478,6 @@ vkQueueSubmit2(VkQueue queue, std::uint32_t submit_count,
const VkSubmitInfo2* submit_infos, VkFence fence) {
const auto context = layer_context.get_context(queue);
-
const auto& vtable = context->device_context.vtable;
if (!submit_count || !context->should_inject_timestamps()) {
@@ -542,7 +540,6 @@ static VKAPI_ATTR VkResult VKAPI_CALL
vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR* present_info) {
const auto context = layer_context.get_context(queue);
-
const auto& vtable = context->device_context.vtable;
if (const auto res = vtable.QueuePresentKHR(queue, present_info);
@@ -561,7 +558,6 @@ static VKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceExtensionProperties(
std::uint32_t* pPropertyCount, VkExtensionProperties* pProperties) {
const auto context = layer_context.get_context(physical_device);
-
const auto& vtable = context->instance.vtable;
// Not asking about our layer - just forward it.
@@ -592,7 +588,6 @@ static VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceFeatures2(
VkPhysicalDevice physical_device, VkPhysicalDeviceFeatures2* pFeatures) {
const auto context = layer_context.get_context(physical_device);
-
const auto& vtable = context->instance.vtable;
vtable.GetPhysicalDeviceFeatures2(physical_device, pFeatures);
diff --git a/src/layer_context.hh b/src/layer_context.hh
index c98768b..316d540 100644
--- a/src/layer_context.hh
+++ b/src/layer_context.hh
@@ -46,7 +46,7 @@ template <> struct context_for_t<VkQueue> {
template <DispatchableType D>
using dispatch_context_t = typename context_for_t<D>::context;
-struct LayerContext final : public Context {
+class LayerContext final : public Context {
private:
// If this is not null and set to exactly "1", then we should sleep after
// present.
diff --git a/src/physical_device_context.cc b/src/physical_device_context.cc
index 29b4ca3..66940f5 100644
--- a/src/physical_device_context.cc
+++ b/src/physical_device_context.cc
@@ -38,12 +38,12 @@ PhysicalDeviceContext::PhysicalDeviceContext(
this->supports_required_extensions = [&]() {
auto count = std::uint32_t{};
- vtable.EnumerateDeviceExtensionProperties(physical_device, nullptr,
- &count, nullptr);
-
+ THROW_NON_VKSUCCESS(vtable.EnumerateDeviceExtensionProperties(
+ physical_device, nullptr, &count, nullptr));
auto supported_extensions = std::vector<VkExtensionProperties>(count);
- vtable.EnumerateDeviceExtensionProperties(
- physical_device, nullptr, &count, std::data(supported_extensions));
+ THROW_NON_VKSUCCESS(vtable.EnumerateDeviceExtensionProperties(
+ physical_device, nullptr, &count,
+ std::data(supported_extensions)));
const auto supported =
supported_extensions |
diff --git a/src/queue_context.cc b/src/queue_context.cc
index 63615f4..6367e16 100644
--- a/src/queue_context.cc
+++ b/src/queue_context.cc
@@ -29,8 +29,8 @@ QueueContext::QueueContext(DeviceContext& device_context, const VkQueue& queue,
};
auto command_pool = VkCommandPool{};
- device_context.vtable.CreateCommandPool(device_context.device, &cpci,
- nullptr, &command_pool);
+ THROW_NON_VKSUCCESS(device_context.vtable.CreateCommandPool(
+ device_context.device, &cpci, nullptr, &command_pool));
return command_pool;
}();
diff --git a/src/timestamp_pool.cc b/src/timestamp_pool.cc
index 5d2335a..4ca1d5a 100644
--- a/src/timestamp_pool.cc
+++ b/src/timestamp_pool.cc
@@ -21,7 +21,8 @@ TimestampPool::QueryChunk::QueryChunk(const QueueContext& queue_context) {
.queryCount = QueryChunk::CHUNK_SIZE};
auto qp = VkQueryPool{};
- vtable.CreateQueryPool(device_context.device, &qpci, nullptr, &qp);
+ THROW_NON_VKSUCCESS(
+ vtable.CreateQueryPool(device_context.device, &qpci, nullptr, &qp));
return qp;
}();
@@ -38,8 +39,8 @@ TimestampPool::QueryChunk::QueryChunk(const QueueContext& queue_context) {
.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
.commandBufferCount = static_cast<std::uint32_t>(std::size(*cbs)),
};
- vtable.AllocateCommandBuffers(device_context.device, &cbai,
- std::data(*cbs));
+ THROW_NON_VKSUCCESS(vtable.AllocateCommandBuffers(
+ device_context.device, &cbai, std::data(*cbs)));
return cbs;
}();
}
@@ -110,20 +111,26 @@ void TimestampPool::Handle::setup_command_buffers(
vtable.ResetQueryPoolEXT(device_context.device, this->query_pool,
static_cast<std::uint32_t>(this->query_index), 1);
- vtable.BeginCommandBuffer(this->command_buffer, &cbbi);
+ THROW_NON_VKSUCCESS(vtable.ResetCommandBuffer(this->command_buffer, 0));
+ THROW_NON_VKSUCCESS(vtable.BeginCommandBuffer(this->command_buffer, &cbbi));
+
vtable.CmdWriteTimestamp2KHR(
this->command_buffer, VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT,
this->query_pool, static_cast<std::uint32_t>(this->query_index));
- vtable.EndCommandBuffer(this->command_buffer);
+
+ THROW_NON_VKSUCCESS(vtable.EndCommandBuffer(this->command_buffer));
vtable.ResetQueryPoolEXT(device_context.device, tail.query_pool,
static_cast<std::uint32_t>(tail.query_index), 1);
- vtable.ResetCommandBuffer(tail.command_buffer, 0);
- vtable.BeginCommandBuffer(tail.command_buffer, &cbbi);
+
+ THROW_NON_VKSUCCESS(vtable.ResetCommandBuffer(tail.command_buffer, 0));
+ THROW_NON_VKSUCCESS(vtable.BeginCommandBuffer(tail.command_buffer, &cbbi));
+
vtable.CmdWriteTimestamp2KHR(
tail.command_buffer, VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT,
tail.query_pool, static_cast<std::uint32_t>(tail.query_index));
- vtable.EndCommandBuffer(tail.command_buffer);
+
+ THROW_NON_VKSUCCESS(vtable.EndCommandBuffer(tail.command_buffer));
}
std::optional<DeviceContext::Clock::time_point_t>
@@ -137,13 +144,15 @@ TimestampPool::Handle::get_time() {
};
auto query_result = QueryResult{};
- const auto r = vtable.GetQueryPoolResults(
+ const auto result = vtable.GetQueryPoolResults(
device_ctx.device, query_pool,
static_cast<std::uint32_t>(this->query_index), 1, sizeof(query_result),
&query_result, sizeof(query_result),
VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT);
- assert(r == VK_SUCCESS || r == VK_NOT_READY);
+ if (result != VK_SUCCESS && result != VK_NOT_READY) {
+ throw result;
+ }
if (!query_result.available) {
return std::nullopt;