From 1c57b923e5e7c426fd567e12e57e9c4c4767f24d Mon Sep 17 00:00:00 2001 From: Jacob Lifshay Date: Sun, 10 Sep 2017 04:23:29 -0700 Subject: [PATCH] working on adding VK_KHR_surface support; breaks using with vulkaninfo --- src/vulkan/CMakeLists.txt | 6 ++ src/vulkan/api_objects.cpp | 13 ++- src/vulkan/api_objects.h | 40 +++++++- src/vulkan_icd/vulkan_icd.cpp | 172 +++++++++++++++++++++++++++++++++- src/vulkan_icd/vulkan_icd.h | 4 +- 5 files changed, 226 insertions(+), 9 deletions(-) diff --git a/src/vulkan/CMakeLists.txt b/src/vulkan/CMakeLists.txt index 3ef1a80..0a259c3 100644 --- a/src/vulkan/CMakeLists.txt +++ b/src/vulkan/CMakeLists.txt @@ -23,3 +23,9 @@ set(sources vulkan.cpp api_objects.cpp) add_library(kazan_vulkan STATIC ${sources}) target_compile_definitions(kazan_vulkan PUBLIC VK_NO_PROTOTYPES) +if(UNIX AND NOT CYGWIN AND NOT CMAKE_SYSTEM_NAME STREQUAL "Android") + target_compile_definitions(kazan_vulkan PUBLIC VK_USE_PLATFORM_XCB_KHR) + target_compile_definitions(kazan_vulkan PUBLIC VK_USE_PLATFORM_WAYLAND_KHR) +elseif(WIN32) + target_compile_definitions(kazan_vulkan PUBLIC VK_USE_PLATFORM_WIN32_KHR) +endif() diff --git a/src/vulkan/api_objects.cpp b/src/vulkan/api_objects.cpp index d57e645..55e7d12 100644 --- a/src/vulkan/api_objects.cpp +++ b/src/vulkan/api_objects.cpp @@ -38,7 +38,11 @@ util::variant, VkResult> Vulkan_instance::creat { auto extension = parse_extension_name(create_info.ppEnabledExtensionNames[i]); if(extension == Supported_extension::Not_supported) + { + std::cerr << "Error: unsupported extension passed to vkCreateInstance: " + << create_info.ppEnabledExtensionNames[i] << std::endl; return VK_ERROR_EXTENSION_NOT_PRESENT; + } if(get_extension_scope(extension) != Extension_scope::Instance) { std::cerr << "Error: device extension passed to vkCreateInstance: " @@ -96,7 +100,11 @@ util::variant, VkResult> Vulkan_device::create( { auto extension = parse_extension_name(create_info.ppEnabledExtensionNames[i]); if(extension == Supported_extension::Not_supported) + { + std::cerr << "Error: unsupported extension passed to vkCreateDevice: " + << create_info.ppEnabledExtensionNames[i] << std::endl; return VK_ERROR_EXTENSION_NOT_PRESENT; + } if(get_extension_scope(extension) != Extension_scope::Device) { std::cerr << "Error: instance extension passed to vkCreateDevice: " @@ -126,6 +134,9 @@ util::variant, VkResult> Vulkan_device::create( } } } + // add enabled instance extensions + for(auto extension : physical_device.instance.extensions) + extensions.insert(extension); VkPhysicalDeviceFeatures enabled_features = {}; if(create_info.pEnabledFeatures) enabled_features = *create_info.pEnabledFeatures; @@ -344,7 +355,7 @@ util::variant, VkResult> Vulkan_device::create( assert(create_info.pQueueCreateInfos[0].sType == VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO); assert(create_info.pQueueCreateInfos[0].queueFamilyIndex == 0); assert(create_info.pQueueCreateInfos[0].queueCount == 1); - return std::make_unique(physical_device, enabled_features); + return std::make_unique(physical_device, enabled_features, extensions); } } } diff --git a/src/vulkan/api_objects.h b/src/vulkan/api_objects.h index ee05913..8cb1bcc 100644 --- a/src/vulkan/api_objects.h +++ b/src/vulkan/api_objects.h @@ -42,9 +42,14 @@ namespace vulkan enum class Supported_extension { Not_supported, + KHR_surface, + KHR_xcb_surface, }; -kazan_util_generate_enum_traits(Supported_extension, Supported_extension::Not_supported); +kazan_util_generate_enum_traits(Supported_extension, + Supported_extension::Not_supported, + Supported_extension::KHR_surface, + Supported_extension::KHR_xcb_surface); typedef util::Enum_set Supported_extensions; @@ -61,6 +66,14 @@ constexpr Extension_scope get_extension_scope(Supported_extension extension) noe { case Supported_extension::Not_supported: return Extension_scope::Not_supported; + case Supported_extension::KHR_surface: + return Extension_scope::Instance; + case Supported_extension::KHR_xcb_surface: +#ifdef VK_USE_PLATFORM_XCB_KHR + return Extension_scope::Instance; +#else + return Extension_scope::Not_supported; +#endif } assert(!"unknown extension"); return Extension_scope::Not_supported; @@ -72,6 +85,20 @@ constexpr VkExtensionProperties get_extension_properties(Supported_extension ext { case Supported_extension::Not_supported: return {}; + case Supported_extension::KHR_surface: + return { + .extensionName = VK_KHR_SURFACE_EXTENSION_NAME, + .specVersion = VK_KHR_SURFACE_SPEC_VERSION, + }; + case Supported_extension::KHR_xcb_surface: +#ifdef VK_USE_PLATFORM_XCB_KHR + return { + .extensionName = VK_KHR_XCB_SURFACE_EXTENSION_NAME, + .specVersion = VK_KHR_XCB_SURFACE_SPEC_VERSION, + }; +#else + return {}; +#endif } assert(!"unknown extension"); return {}; @@ -105,6 +132,10 @@ constexpr Supported_extensions get_extension_dependencies(Supported_extension ex { case Supported_extension::Not_supported: return {}; + case Supported_extension::KHR_surface: + return {}; + case Supported_extension::KHR_xcb_surface: + return {Supported_extension::KHR_surface}; } assert(!"unknown extension"); return {}; @@ -1446,11 +1477,14 @@ struct Vulkan_device : public Vulkan_dispatchable_objectget_procedure_address( - name, vulkan_icd::Vulkan_loader_interface::Procedure_address_scope::Device); + name, + vulkan_icd::Vulkan_loader_interface::Procedure_address_scope::Device, + &device_pointer->instance, + device_pointer); } extern "C" VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice(VkPhysicalDevice physical_device, @@ -212,6 +217,20 @@ extern "C" VKAPI_ATTR VkResult VKAPI_CALL physical_device, layer_name, property_count, properties); } +extern "C" VKAPI_ATTR VkResult VKAPI_CALL + vkEnumerateInstanceLayerProperties(uint32_t *pPropertyCount, VkLayerProperties *pProperties) +{ +#warning finish implementing vkEnumerateInstanceLayerProperties + assert(!"vkEnumerateInstanceLayerProperties is not implemented"); +} + +extern "C" VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceLayerProperties( + VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount, VkLayerProperties *pProperties) +{ +#warning finish implementing vkEnumerateDeviceLayerProperties + assert(!"vkEnumerateDeviceLayerProperties is not implemented"); +} + extern "C" VKAPI_ATTR void VKAPI_CALL vkGetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, @@ -1344,6 +1363,77 @@ extern "C" VKAPI_ATTR void VKAPI_CALL vkCmdExecuteCommands(VkCommandBuffer comma #warning finish implementing vkCmdExecuteCommands assert(!"vkCmdExecuteCommands is not implemented"); } + +extern "C" VKAPI_ATTR void VKAPI_CALL vkDestroySurfaceKHR(VkInstance instance, + VkSurfaceKHR surface, + const VkAllocationCallbacks *allocator) +{ + validate_allocator(allocator); +#warning finish implementing vkDestroySurfaceKHR + assert(!"vkDestroySurfaceKHR is not implemented"); +} + +extern "C" VKAPI_ATTR VkResult VKAPI_CALL + vkGetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice, + uint32_t queueFamilyIndex, + VkSurfaceKHR surface, + VkBool32 *pSupported) +{ +#warning finish implementing vkGetPhysicalDeviceSurfaceSupportKHR + assert(!"vkGetPhysicalDeviceSurfaceSupportKHR is not implemented"); +} + +extern "C" VKAPI_ATTR VkResult VKAPI_CALL + vkGetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice, + VkSurfaceKHR surface, + VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) +{ +#warning finish implementing vkGetPhysicalDeviceSurfaceCapabilitiesKHR + assert(!"vkGetPhysicalDeviceSurfaceCapabilitiesKHR is not implemented"); +} + +extern "C" VKAPI_ATTR VkResult VKAPI_CALL + vkGetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice, + VkSurfaceKHR surface, + uint32_t *pSurfaceFormatCount, + VkSurfaceFormatKHR *pSurfaceFormats) +{ +#warning finish implementing vkGetPhysicalDeviceSurfaceFormatsKHR + assert(!"vkGetPhysicalDeviceSurfaceFormatsKHR is not implemented"); +} + +extern "C" VKAPI_ATTR VkResult VKAPI_CALL + vkGetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice, + VkSurfaceKHR surface, + uint32_t *pPresentModeCount, + VkPresentModeKHR *pPresentModes) +{ +#warning finish implementing vkGetPhysicalDeviceSurfacePresentModesKHR + assert(!"vkGetPhysicalDeviceSurfacePresentModesKHR is not implemented"); +} + +#ifdef VK_USE_PLATFORM_XCB_KHR +extern "C" VKAPI_ATTR VkResult VKAPI_CALL + vkCreateXcbSurfaceKHR(VkInstance instance, + const VkXcbSurfaceCreateInfoKHR *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkSurfaceKHR *pSurface) +{ +#warning finish implementing vkCreateXcbSurfaceKHR + assert(!"vkCreateXcbSurfaceKHR is not implemented"); +} + +extern "C" VKAPI_ATTR VkBool32 VKAPI_CALL + vkGetPhysicalDeviceXcbPresentationSupportKHR(VkPhysicalDevice physicalDevice, + uint32_t queueFamilyIndex, + xcb_connection_t *connection, + xcb_visualid_t visual_id) +{ +#warning finish implementing vkGetPhysicalDeviceXcbPresentationSupportKHR + assert(!"vkGetPhysicalDeviceXcbPresentationSupportKHR is not implemented"); +} +#endif + namespace kazan { namespace vulkan_icd @@ -1355,13 +1445,40 @@ Vulkan_loader_interface *Vulkan_loader_interface::get() noexcept } PFN_vkVoidFunction Vulkan_loader_interface::get_procedure_address( - const char *name, Procedure_address_scope scope) noexcept + const char *name, + Procedure_address_scope scope, + vulkan::Vulkan_instance *instance, + vulkan::Vulkan_device *device) noexcept { using namespace util::string_view_literals; assert(name != "vkEnumerateInstanceLayerProperties"_sv && "shouldn't be called, implemented by the vulkan loader"); assert(name != "vkEnumerateDeviceLayerProperties"_sv && "shouldn't be called, implemented by the vulkan loader"); + vulkan::Supported_extensions enabled_or_available_extensions{}; + switch(scope) + { + case Procedure_address_scope::Library: + assert(!instance); + assert(!device); + // can't use any extension functions at library scope + break; + case Procedure_address_scope::Instance: + assert(instance); + assert(!device); + enabled_or_available_extensions = instance->extensions; + for(auto extension : util::Enum_traits::values) + if(vulkan::get_extension_scope(extension) == vulkan::Extension_scope::Device) + enabled_or_available_extensions.insert(extension); + break; + case Procedure_address_scope::Device: + assert(instance); + assert(device); + enabled_or_available_extensions = device->extensions; + break; + } + +// INSTANCE_SCOPE_* is used for device scope functions as well #define LIBRARY_SCOPE_FUNCTION(function_name) \ do \ @@ -1377,9 +1494,41 @@ PFN_vkVoidFunction Vulkan_loader_interface::get_procedure_address( return reinterpret_cast( \ static_cast(function_name)); \ } while(0) +#define INSTANCE_SCOPE_EXTENSION_FUNCTION(function_name, extension) \ + do \ + { \ + if(scope != Procedure_address_scope::Library \ + && enabled_or_available_extensions.count(vulkan::Supported_extension::extension) != 0 \ + && name == #function_name##_sv) \ + return reinterpret_cast( \ + static_cast(function_name)); \ + } while(0) +// for functions implemented by the vulkan loader that shouldn't reach the ICD +#define LIBRARY_SCOPE_FUNCTION_IN_LOADER(function_name) \ + do \ + { \ + assert(name != #function_name##_sv \ + && "shouldn't be called, implemented by the vulkan loader"); \ + } while(0) +#define INSTANCE_SCOPE_FUNCTION_IN_LOADER(function_name) \ + do \ + { \ + assert((scope == Procedure_address_scope::Library || name != #function_name##_sv) \ + && "shouldn't be called, implemented by the vulkan loader"); \ + } while(0) +#define INSTANCE_SCOPE_EXTENSION_FUNCTION_IN_LOADER(function_name, extension) \ + do \ + { \ + assert( \ + (scope == Procedure_address_scope::Library \ + || enabled_or_available_extensions.count(vulkan::Supported_extension::extension) == 0 \ + || name != #function_name##_sv) \ + && "shouldn't be called, implemented by the vulkan loader"); \ + } while(0) LIBRARY_SCOPE_FUNCTION(vkEnumerateInstanceExtensionProperties); LIBRARY_SCOPE_FUNCTION(vkCreateInstance); + LIBRARY_SCOPE_FUNCTION(vkEnumerateInstanceLayerProperties); INSTANCE_SCOPE_FUNCTION(vkDestroyInstance); INSTANCE_SCOPE_FUNCTION(vkEnumeratePhysicalDevices); INSTANCE_SCOPE_FUNCTION(vkGetPhysicalDeviceFeatures); @@ -1393,6 +1542,7 @@ PFN_vkVoidFunction Vulkan_loader_interface::get_procedure_address( INSTANCE_SCOPE_FUNCTION(vkCreateDevice); INSTANCE_SCOPE_FUNCTION(vkDestroyDevice); INSTANCE_SCOPE_FUNCTION(vkEnumerateDeviceExtensionProperties); + INSTANCE_SCOPE_FUNCTION(vkEnumerateDeviceLayerProperties); INSTANCE_SCOPE_FUNCTION(vkGetDeviceQueue); INSTANCE_SCOPE_FUNCTION(vkQueueSubmit); INSTANCE_SCOPE_FUNCTION(vkQueueWaitIdle); @@ -1513,9 +1663,20 @@ PFN_vkVoidFunction Vulkan_loader_interface::get_procedure_address( INSTANCE_SCOPE_FUNCTION(vkCmdNextSubpass); INSTANCE_SCOPE_FUNCTION(vkCmdEndRenderPass); INSTANCE_SCOPE_FUNCTION(vkCmdExecuteCommands); + INSTANCE_SCOPE_EXTENSION_FUNCTION(vkDestroySurfaceKHR, KHR_surface); + INSTANCE_SCOPE_EXTENSION_FUNCTION(vkGetPhysicalDeviceSurfaceSupportKHR, KHR_surface); + INSTANCE_SCOPE_EXTENSION_FUNCTION(vkGetPhysicalDeviceSurfaceCapabilitiesKHR, KHR_surface); + INSTANCE_SCOPE_EXTENSION_FUNCTION(vkGetPhysicalDeviceSurfaceFormatsKHR, KHR_surface); + INSTANCE_SCOPE_EXTENSION_FUNCTION(vkGetPhysicalDeviceSurfacePresentModesKHR, KHR_surface); +#ifdef VK_USE_PLATFORM_XCB_KHR + INSTANCE_SCOPE_EXTENSION_FUNCTION(vkCreateXcbSurfaceKHR, KHR_xcb_surface); + INSTANCE_SCOPE_EXTENSION_FUNCTION(vkGetPhysicalDeviceXcbPresentationSupportKHR, + KHR_xcb_surface); +#endif #undef LIBRARY_SCOPE_FUNCTION #undef INSTANCE_SCOPE_FUNCTION +#undef INSTANCE_SCOPE_EXTENSION_FUNCTION return nullptr; } @@ -1523,8 +1684,11 @@ PFN_vkVoidFunction Vulkan_loader_interface::get_instance_proc_addr(VkInstance in const char *name) noexcept { if(!instance) - return get_procedure_address(name, Procedure_address_scope::Library); - return get_procedure_address(name, Procedure_address_scope::Instance); + return get_procedure_address(name, Procedure_address_scope::Library, nullptr, nullptr); + return get_procedure_address(name, + Procedure_address_scope::Instance, + vulkan::Vulkan_instance::from_handle(instance), + nullptr); } VkResult Vulkan_loader_interface::create_instance(const VkInstanceCreateInfo *create_info, diff --git a/src/vulkan_icd/vulkan_icd.h b/src/vulkan_icd/vulkan_icd.h index df28c8e..d3ebc13 100644 --- a/src/vulkan_icd/vulkan_icd.h +++ b/src/vulkan_icd/vulkan_icd.h @@ -79,7 +79,9 @@ public: Device }; PFN_vkVoidFunction get_procedure_address(const char *name, - Procedure_address_scope scope) noexcept; + Procedure_address_scope scope, + vulkan::Vulkan_instance *instance, + vulkan::Vulkan_device *device) noexcept; PFN_vkVoidFunction get_instance_proc_addr(VkInstance instance, const char *name) noexcept; VkResult create_instance(const VkInstanceCreateInfo *create_info, const VkAllocationCallbacks *allocator, -- 2.30.2