aboutsummaryrefslogtreecommitdiff
path: root/src/layer_context.hh
diff options
context:
space:
mode:
Diffstat (limited to 'src/layer_context.hh')
-rw-r--r--src/layer_context.hh72
1 files changed, 35 insertions, 37 deletions
diff --git a/src/layer_context.hh b/src/layer_context.hh
index 228efa3..59861a7 100644
--- a/src/layer_context.hh
+++ b/src/layer_context.hh
@@ -2,10 +2,13 @@
#define LAYER_CONTEXT_HH_
#include <mutex>
-#include <variant>
+#include <unordered_map>
+#include <vulkan/vulkan_core.h>
+#include "context.hh"
#include "device_context.hh"
#include "instance_context.hh"
+#include "physical_device_context.hh"
#include "queue_context.hh"
// The purpose of this file is to provide a definition for the highest level
@@ -19,63 +22,58 @@
namespace low_latency {
+// All these templates do is make it so we can go from some DispatchableType
+// to their respective context's with nice syntax.
+
template <typename T>
concept DispatchableType =
std::same_as<std::remove_cvref_t<T>, VkInstance> ||
- std::same_as<std::remove_cvref_t<T>, VkDevice> ||
std::same_as<std::remove_cvref_t<T>, VkPhysicalDevice> ||
+ std::same_as<std::remove_cvref_t<T>, VkDevice> ||
std::same_as<std::remove_cvref_t<T>, VkQueue>;
-struct LayerContext {
- public:
- using ContextVariant = std::variant<std::unique_ptr<DeviceContext>,
- std::unique_ptr<InstanceContext>>;
+template <class D> struct context_for_t;
+template <> struct context_for_t<VkInstance> {
+ using context = InstanceContext;
+};
+template <> struct context_for_t<VkPhysicalDevice> {
+ using context = PhysicalDeviceContext;
+};
+template <> struct context_for_t<VkDevice> {
+ using context = DeviceContext;
+};
+template <> struct context_for_t<VkQueue> {
+ using context = QueueContext;
+};
+template <DispatchableType D>
+using dispatch_context_t = typename context_for_t<D>::context;
+struct LayerContext final : public Context {
public:
std::mutex mutex;
- std::unordered_map<void*, ContextVariant> contexts;
- std::uint64_t current_frame = 0;
+ std::unordered_map<void*, std::shared_ptr<Context>> contexts;
public:
LayerContext();
- LayerContext(const LayerContext&) = delete;
- LayerContext(LayerContext&&) = delete;
- LayerContext operator==(const LayerContext&) = delete;
- LayerContext operator==(LayerContext&&) = delete;
- ~LayerContext();
+ virtual ~LayerContext();
public:
- template <DispatchableType T> static void* get_key(const T& dt) {
- return *reinterpret_cast<void**>(dt);
+ template <DispatchableType DT> static void* get_key(const DT& dt) {
+ return reinterpret_cast<void*>(dt);
}
- template <typename T, DispatchableType DispatchableType>
- requires(!std::same_as<T, QueueContext>)
- T& get_context(const DispatchableType& dt) {
+ template <DispatchableType DT>
+ std::shared_ptr<dispatch_context_t<DT>> get_context(const DT& dt) {
const auto key = get_key(dt);
+ const auto lock = std::scoped_lock(this->mutex);
const auto it = this->contexts.find(key);
assert(it != std::end(this->contexts));
- const auto ptr = std::get_if<std::unique_ptr<T>>(&it->second);
- assert(ptr && *ptr);
-
- return **ptr;
- }
-
- // QueueContext's are actually owned by a device so look there instead.
- template <typename T, DispatchableType DispatchableType>
- requires(std::same_as<T, QueueContext>)
- T& get_context(const DispatchableType& dt) {
-
- const auto& device_context = this->get_context<DeviceContext>(dt);
- const auto& queue_context = device_context.queue_contexts;
-
- const auto it = device_context.queue_contexts.find(dt);
- assert(it != std::end(queue_context));
-
- const auto& ptr = it->second;
- return *ptr;
+ using context_t = dispatch_context_t<DT>;
+ auto ptr = std::dynamic_pointer_cast<context_t>(it->second);
+ assert(ptr);
+ return ptr;
}
};