/* * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Copyright: * 2016-2017, Danny Robson */ #ifndef CRUFT_VK_TRAITS_HPP #define CRUFT_VK_TRAITS_HPP #include "./fwd.hpp" #include "./vk.hpp" #include #include namespace cruft::vk { /////////////////////////////////////////////////////////////////////////// /// describes the corresponding value for sType in native structures template struct structure_type {}; //------------------------------------------------------------------------- #define DEFINE_STRUCTURE_TYPE(KLASS,VALUE) \ template <> \ struct structure_type : \ public std::integral_constant< \ VkStructureType, \ PASTE(VK_STRUCTURE_TYPE_,VALUE) \ > \ { } DEFINE_STRUCTURE_TYPE (VkInstanceCreateInfo, INSTANCE_CREATE_INFO); DEFINE_STRUCTURE_TYPE (VkApplicationInfo, APPLICATION_INFO); DEFINE_STRUCTURE_TYPE (VkDeviceQueueCreateInfo, DEVICE_QUEUE_CREATE_INFO); DEFINE_STRUCTURE_TYPE (VkDeviceCreateInfo, DEVICE_CREATE_INFO); DEFINE_STRUCTURE_TYPE (VkSwapchainCreateInfoKHR, SWAPCHAIN_CREATE_INFO_KHR); DEFINE_STRUCTURE_TYPE (VkImageViewCreateInfo, IMAGE_VIEW_CREATE_INFO); DEFINE_STRUCTURE_TYPE (VkShaderModuleCreateInfo, SHADER_MODULE_CREATE_INFO); DEFINE_STRUCTURE_TYPE (VkPipelineShaderStageCreateInfo, PIPELINE_SHADER_STAGE_CREATE_INFO); DEFINE_STRUCTURE_TYPE (VkDebugReportCallbackCreateInfoEXT, DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT); #undef DEFINE_STRUCTURE_TYPE //------------------------------------------------------------------------- template constexpr auto structure_type_v = structure_type::value; /////////////////////////////////////////////////////////////////////////// /// describes the parameter struct used to create a given vulkan type. /// /// explicitly does not operate on vk-cruft types, only native types. template struct create_info { }; //------------------------------------------------------------------------- #define DEFINE_CREATE_INFO(TARGET,INFO) \ template <> \ struct create_info \ { using type = INFO; } DEFINE_CREATE_INFO (VkImageViewCreateInfo, VkImageViewCreateInfo); DEFINE_CREATE_INFO (VkShaderModule, VkShaderModuleCreateInfo); #undef DEFINE_CREATE_INFO //------------------------------------------------------------------------- template using create_info_t = typename create_info::type; /////////////////////////////////////////////////////////////////////////// /// describes the native type that corresponds to a given vk-cruft type. template struct id_traits { }; //------------------------------------------------------------------------- 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; /////////////////////////////////////////////////////////////////////////// /// describes the native type that owns a given native type, and hence /// forms part of the create/destroy process. /// /// undefined for types that aren't `owned' types. 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; /////////////////////////////////////////////////////////////////////////// /// lists the `create' and `destroy' methods for a given native type. /// /// XXX: if such a function does not exist anywhere then we currently use /// tuple::ignore to simplify implementation elsewhere. we should probably /// investigate std::is_detected for these cases though. /// /// clang#18781: we make use of references types extensively here to /// workaround a potential ODR bug in clang which results in undefined /// references. /// or potentially i'm being too clever for my own good, but it works fine /// in gcc... template struct life_traits { }; //------------------------------------------------------------------------- template <> struct life_traits { static constexpr auto& create = vkCreateInstance; static constexpr auto& destroy = vkDestroyInstance; }; template <> struct life_traits { static constexpr auto& create = vkCreateDevice; static constexpr auto& destroy = vkDestroyDevice; }; template <> struct life_traits { static constexpr auto& create = vkCreateCommandPool; static constexpr auto& destroy = vkDestroyCommandPool; }; template <> struct life_traits { static constexpr auto& create = vkCreateFence; static constexpr auto& destroy = vkDestroyFence; }; template <> struct life_traits { static constexpr auto& create = vkCreateSemaphore; static constexpr auto& destroy = vkDestroySemaphore; }; template <> struct life_traits { static constexpr auto& create = vkCreateEvent; static constexpr auto& destroy = vkDestroyEvent; }; template <> struct life_traits { static constexpr auto& create = vkCreateRenderPass; static constexpr auto& destroy = vkDestroyRenderPass; }; template <> struct life_traits { static constexpr auto& create = vkCreateFramebuffer; static constexpr auto& destroy = vkDestroyFramebuffer; }; template <> struct life_traits { static constexpr auto& create = vkCreateShaderModule; static constexpr auto& destroy = vkDestroyShaderModule; }; template <> struct life_traits { static constexpr auto& destroy = vkDestroySurfaceKHR; }; template <> struct life_traits { static constexpr auto& create = vkGetDeviceQueue; static constexpr auto destroy = ::util::tuple::ignore< id_t>, id_t, const VkAllocationCallbacks* >; }; template struct create_traits { }; template <> struct create_traits { static constexpr auto func = vkCreateComputePipelines; }; template <> struct create_traits { static constexpr auto func = vkCreateGraphicsPipelines; }; // XXX: Currently causes a segfault under gcc-5.3.0 when stabs debgging is // enabled. See gcc#71058 // //template <> struct life_traits { // template // static constexpr auto create = create_traits

::func; // static constexpr auto destroy = vkDestroyPipeline; //}; template <> struct life_traits { static constexpr auto& create = vkCreatePipelineCache; static constexpr auto& destroy = vkDestroyPipelineCache; }; template <> struct life_traits { static constexpr auto& create = vkAllocateMemory; static constexpr auto& destroy = vkFreeMemory; }; template <> struct life_traits { static constexpr auto& create = vkCreateBuffer; static constexpr auto& destroy = vkDestroyBuffer; }; template <> struct life_traits { static constexpr auto& create = vkCreateBufferView; }; /////////////////////////////////////////////////////////////////////////// /// describes the functions required to enumerate native types template struct enum_traits { }; template <> struct enum_traits { static constexpr auto enumerate = vkEnumeratePhysicalDevices; }; } #endif