diff --git a/vulkan_utl.h b/vulkan_utl.h index f2566ee..34fdb57 100644 --- a/vulkan_utl.h +++ b/vulkan_utl.h @@ -73,7 +73,7 @@ struct VulkanContext } template - VkResult CallCreateInstance(const char *engine, const char *app, bool enableValidationLayers, Func instanceCallback) + VkResult CallCreateInstance(const char *engine, const char *app, bool enableValidationLayers, const char **pExtensions, Func instanceCallback) { VkApplicationInfo app_info = { .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO, @@ -83,7 +83,7 @@ struct VulkanContext .engineVersion = 0, .apiVersion = VK_MAKE_VERSION(1, 0, 2), }; - const char * enabledExtensions[16]; + const char * enabledExtensions[256]; uint32_t enabledExtensionsCount = 0; enabledExtensions[enabledExtensionsCount++] = VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME; enabledExtensions[enabledExtensionsCount++] = VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME; @@ -91,6 +91,8 @@ struct VulkanContext enabledExtensions[enabledExtensionsCount++] = VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME; enabledExtensions[enabledExtensionsCount++] = VK_KHR_SURFACE_EXTENSION_NAME; enabledExtensions[enabledExtensionsCount++] = "VK_KHR_xlib_surface"; + while(pExtensions && *pExtensions) + enabledExtensions[enabledExtensionsCount++] = *pExtensions++; if (enableValidationLayers) { /* @@ -179,9 +181,9 @@ struct VulkanContext return res1; } - VkResult Create(const char *engine, const char *app, bool enableValidationLayers) + VkResult Create(const char *engine, const char *app, bool enableValidationLayers, const char **ppExtensions = NULL) { - return CallCreateInstance(engine, app, enableValidationLayers, vkCreateInstance); + return CallCreateInstance(engine, app, enableValidationLayers, ppExtensions, vkCreateInstance); } VkPhysicalDevice FindPhysicalDevice() { @@ -387,7 +389,7 @@ struct VulkanDevice return count; } template - VkResult CallCreateDeviceCallback(VulkanContext &ctx, VkDeviceQueueCreateInfo *pQueueInfo, uint32_t queueInfoCount, Func createCallback) + VkResult CallCreateDeviceCallback(VulkanContext &ctx, VkDeviceQueueCreateInfo *pQueueInfo, uint32_t queueInfoCount, const char **pExtensions, Func createCallback) { const float defaultQueuePriority(1.0f); @@ -402,7 +404,7 @@ struct VulkanDevice pQueueInfo = &queue_info; queueInfoCount = 1; } - const char *deviceExtensions[16]; + const char *deviceExtensions[256]; uint32_t deviceExtensionsCount = 0; uint32_t avCount = 0; vkEnumerateDeviceExtensionProperties(physicalDevice, NULL, &avCount, NULL); @@ -415,6 +417,7 @@ struct VulkanDevice if(!strcmp(Name,props[j].extensionName)) break; } + printf("Adding %s\n", Name); if(j == avCount) printf("Extension %s not availaible\n", Name); else @@ -434,9 +437,8 @@ struct VulkanDevice addExtension(VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME); addExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); addExtension(VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME); - addExtension(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME); - addExtension(VK_KHR_EXTERNAL_FENCE_EXTENSION_NAME); - addExtension(VK_KHR_EXTERNAL_FENCE_FD_EXTENSION_NAME); + while(pExtensions && *pExtensions) + addExtension(*pExtensions++); VkPhysicalDeviceFeatures enabled_features = { .samplerAnisotropy = VK_TRUE }; @@ -467,9 +469,9 @@ struct VulkanDevice return result; } - VkResult CreateDevice(VulkanContext &ctx, VkDeviceQueueCreateInfo *pQueueInfo = NULL, uint32_t queueInfoCount = 0) + VkResult CreateDevice(VulkanContext &ctx, VkDeviceQueueCreateInfo *pQueueInfo = NULL, uint32_t queueInfoCount = 0, const char** pExtensions = NULL) { - return CallCreateDeviceCallback(ctx, pQueueInfo, queueInfoCount, vkCreateDevice); + return CallCreateDeviceCallback(ctx, pQueueInfo, queueInfoCount, pExtensions, vkCreateDevice); } VkResult CreateBuffer(VulkanBuffer &buffer, VkBufferUsageFlags usage, VkMemoryPropertyFlags memory_flags, VkDeviceSize size, const void *data = NULL) diff --git a/xrapp.cpp b/xrapp.cpp index 7288097..a8722d0 100644 --- a/xrapp.cpp +++ b/xrapp.cpp @@ -298,20 +298,31 @@ struct OpenXRContext return CheckGraphicsApiSupport(vulkan2); } - // broken: only prints now, but should add extensions to CreateDevice! - bool GetInstanceExtensions() + bool GetInstanceExtensions(char *output, uint32_t size) { PFN_xrGetVulkanInstanceExtensionsKHR fun = NULL; XRM_XR_RETF(xrGetInstanceProcAddr(instance, "xrGetVulkanInstanceExtensionsKHR", (PFN_xrVoidFunction*)&fun), "Failed to load xrGetVulkanInstanceExtensionsKHR."); - uint32_t size = 0; - fun(instance, system_id, 0, &size, NULL); - char names[size]; - fun(instance, system_id, size, &size, names); - XRM_LOGI("xrGetVulkanInstanceExtensionsKHR: %s", names); + uint32_t osize; + fun(instance, system_id, size, &osize, output); + XRM_LOGI("xrGetVulkanInstanceExtensionsKHR: %s", output); return true; } + + bool GetDeviceExtensions(char *output, uint32_t size) + { + PFN_xrGetVulkanDeviceExtensionsKHR fun = NULL; + XRM_XR_RETF(xrGetInstanceProcAddr(instance, "xrGetVulkanDeviceExtensionsKHR", + (PFN_xrVoidFunction*)&fun), + "Failed to load xrGetVulkanDeviceExtensionsKHR."); + uint32_t osize; + fun(instance, system_id, size, &osize, output); + XRM_LOGI("xrGetVulkanDeviceExtensionsKHR: %s", output); + return true; + } + + VkPhysicalDevice InitDevice(VkInstance inst) { PFN_xrGetVulkanGraphicsDeviceKHR fun = NULL; @@ -367,7 +378,7 @@ struct OpenXRContext "Failed to load xrCreateVulkanInstanceKHR."); XrResult res; - VkResult vk_result = ctx.CallCreateInstance(engine, app, vulkan_validation, [&]( + VkResult vk_result = ctx.CallCreateInstance(engine, app, vulkan_validation, NULL, [&]( const VkInstanceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkInstance* pInstance){ @@ -408,7 +419,7 @@ struct OpenXRContext "Failed to load xrCreateVulkanDeviceKHR."); XrResult res; - VkResult vk_result = dev.CallCreateDeviceCallback(ctx, pQueueInfo, queueInfoCount, [&]( + VkResult vk_result = dev.CallCreateDeviceCallback(ctx, pQueueInfo, queueInfoCount, NULL, [&]( VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, @@ -438,10 +449,23 @@ struct OpenXRContext } else { - // todo: this should be called from app's init before creating device - if(!GetInstanceExtensions()) + char extensions[2048]; + char *pExtensions[256]; + char **ppExt = pExtensions; + char *pStr = extensions, *pOldStr = extensions; + if(!GetInstanceExtensions(extensions, sizeof(extensions))) return VK_NULL_HANDLE; - ctx.Create(engine, app, vulkan_validation); + while((pStr = strchr(pStr, ' '))) + { + *pStr++ = 0; + if(*pOldStr) + *ppExt++ = pOldStr; + pOldStr = pStr; + } + if(*pOldStr) + *ppExt++ = pOldStr; + *ppExt++ = NULL; + ctx.Create(engine, app, vulkan_validation, (const char **)pExtensions); return InitDevice(ctx.instance); } } @@ -802,7 +826,24 @@ struct OpenXRApplication } else { - XRM_VK_RETF(dev.CreateDevice(context, (fidx != dev.defaultQueueIndex)?queue_info:NULL, 2)); + char extensions[2048]; + char *pExtensions[256]; + char **ppExt = pExtensions; + char *pStr = extensions, *pOldStr = extensions; + if(!xr.GetDeviceExtensions(extensions, sizeof(extensions))) + return false; + while((pStr = strchr(pStr, ' '))) + { + *pStr++ = 0; + if(*pOldStr) + *ppExt++ = pOldStr; + pOldStr = pStr; + } + if(*pOldStr) + *ppExt++ = pOldStr; + *ppExt++ = NULL; + + XRM_VK_RETF(dev.CreateDevice(context, (fidx != dev.defaultQueueIndex)?queue_info:NULL, 2, (const char**)pExtensions)); } if(!xr.InitPostVk(context.instance, dev)) XRM_LOGE_RETF("OpenXR initialization failed.");