diff --git a/traits.hpp b/traits.hpp index cbde7cb..471e8c1 100644 --- a/traits.hpp +++ b/traits.hpp @@ -21,6 +21,8 @@ #include "./fwd.hpp" #include "./vk.hpp" +#include + #include @@ -84,24 +86,41 @@ namespace cruft::vk { /////////////////////////////////////////////////////////////////////////// template struct id_traits { }; - template <> struct id_traits { using id_t = VkInstance; }; - template <> struct id_traits { using id_t = VkPhysicalDevice; }; - template <> struct id_traits { using id_t = VkDevice; }; - template <> struct id_traits { using id_t = VkQueue; }; - template <> struct id_traits { using id_t = VkCommandPool; }; - template <> struct id_traits { using id_t = VkCommandBuffer; }; - template <> struct id_traits { using id_t = VkFence; }; - template <> struct id_traits { using id_t = VkSemaphore; }; - template <> struct id_traits { using id_t = VkEvent; }; - template <> struct id_traits { using id_t = VkRenderPass; }; - template <> struct id_traits { using id_t = VkFramebuffer; }; - template <> struct id_traits { using id_t = VkShaderModule; }; - template <> struct id_traits { using id_t = VkPipeline; }; - template <> struct id_traits { using id_t = VkPipelineCache; }; - template <> struct id_traits { using id_t = VkDeviceMemory; }; - template <> struct id_traits { using id_t = VkBuffer; }; - template <> struct id_traits { using id_t = VkBufferView; }; - template <> struct id_traits { using id_t = VkSurfaceKHR; }; + + //------------------------------------------------------------------------- + template <> struct id_traits { using type = VkInstance; }; + template <> struct id_traits { using type = VkPhysicalDevice; }; + template <> struct id_traits { using type = VkDevice; }; + template <> struct id_traits { using type = VkQueue; }; + template <> struct id_traits { using type = VkCommandPool; }; + template <> struct id_traits { using type = VkCommandBuffer; }; + template <> struct id_traits { using type = VkFence; }; + template <> struct id_traits { using type = VkSemaphore; }; + template <> struct id_traits { using type = VkEvent; }; + template <> struct id_traits { using type = VkRenderPass; }; + template <> struct id_traits { using type = VkFramebuffer; }; + template <> struct id_traits { using type = VkShaderModule; }; + template <> struct id_traits { using type = VkPipeline; }; + template <> struct id_traits { using type = VkPipelineCache; }; + template <> struct id_traits { using type = VkDeviceMemory; }; + template <> struct id_traits { using type = VkBuffer; }; + template <> struct id_traits { using type = VkBufferView; }; + template <> struct id_traits { using type = VkSurfaceKHR; }; + + + //------------------------------------------------------------------------- + template + using id_t = typename id_traits::type; + + + /////////////////////////////////////////////////////////////////////////// + template struct owner_traits {}; + + template <> struct owner_traits { using type = device; }; + template <> struct owner_traits { using type = instance; }; + + template + using owner_t = typename owner_traits::type; /////////////////////////////////////////////////////////////////////////// @@ -158,7 +177,17 @@ namespace cruft::vk { template <> struct life_traits { - static constexpr auto get = vkGetDeviceQueue; + // clang#18781: we work around an ODR bug in clang which causes + // undefined references by explicitly using a temporary here. ideally + // this causes minimal difference in the generated output. + using create_t = decltype(vkGetDeviceQueue); + static constexpr create_t& create = vkGetDeviceQueue; + + static constexpr auto destroy = ::util::tuple::ignore< + id_t>, + id_t, + const VkAllocationCallbacks* + >; }; template struct create_traits { };