diff --git a/materialsystem/vulkan/device_extensions.h b/materialsystem/vulkan/device_extensions.h index 41747d8..cd52f8c 100644 --- a/materialsystem/vulkan/device_extensions.h +++ b/materialsystem/vulkan/device_extensions.h @@ -1,2 +1,4 @@ REQUIRED_EXTENSION(VK_KHR_SWAPCHAIN) OPTIONAL_EXTENSION(VK_KHR_RAY_TRACING_PIPELINE) +OPTIONAL_EXTENSION(VK_KHR_ACCELERATION_STRUCTURE) +OPTIONAL_EXTENSION(VK_KHR_DEFERRED_HOST_OPERATIONS) diff --git a/materialsystem/vulkan/rendercontext.cpp b/materialsystem/vulkan/rendercontext.cpp index 19aaa45..819055b 100644 --- a/materialsystem/vulkan/rendercontext.cpp +++ b/materialsystem/vulkan/rendercontext.cpp @@ -1,5 +1,6 @@ #include "SDL3/SDL_vulkan.h" #include "materialsystem/materialsystem.h" +#include "tier0/lib.h" #include "tier0/platform.h" #include "tier1/utlstring.h" #include "tier1/utlvector.h" @@ -17,6 +18,7 @@ const char *g_vkDeviceExtensions[] = { #undef REQUIRED_EXTENSION #undef OPTIONAL_EXTENSION +SupportedVulkanExtensions_t g_vkAvailableExtensions; class CVkRenderContext: public IRenderContext @@ -38,6 +40,7 @@ private: IBuffer *CreateBufferAligned( uint32_t nSize, uint32_t nAlignment, VkBufferUsageFlags2 eUsage ); VkPhysicalDevice SelectPhysicalDevice( CUtlVector physicalDevices ); + CUtlVector GetDeviceExtensions(); void CreateSwapchain(); void DestroySwapchain(); @@ -117,7 +120,9 @@ void CVkRenderContext::Init() VkResult r; int nExtensionCount; - CUtlVector extensions = {}; + + CUtlVector enabledInstanceExtensions; + CUtlVector enabledDeviceExtensions; uint32_t nPhysicalDevicesCount; CUtlVector physicalDevices; @@ -134,12 +139,12 @@ void CVkRenderContext::Init() float fPriority = 1.0; r = volkInitialize(); - VULKAN_RESULT_PRINT(r, volkInitialize) + VULKAN_RESULT_PRINT(r, volkInitialize); // Get extensions required by game window nExtensionCount = gamewindow->GetVulkanInstanceExtensionCount(); - extensions.Resize(nExtensionCount); - V_memcpy(extensions.GetData(), gamewindow->GetVulkanInstanceExtensions(), extensions.GetSize()*sizeof(const char*)); + enabledInstanceExtensions.Resize(nExtensionCount); + V_memcpy(enabledInstanceExtensions.GetData(), gamewindow->GetVulkanInstanceExtensions(), enabledInstanceExtensions.GetSize()*sizeof(const char*)); // Create instance stApplicationInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; @@ -149,11 +154,11 @@ void CVkRenderContext::Init() stInstanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; stInstanceCreateInfo.pApplicationInfo = &stApplicationInfo; - stInstanceCreateInfo.enabledExtensionCount = extensions.GetSize(); - stInstanceCreateInfo.ppEnabledExtensionNames = extensions.GetData(); + stInstanceCreateInfo.enabledExtensionCount = enabledInstanceExtensions.GetSize(); + stInstanceCreateInfo.ppEnabledExtensionNames = enabledInstanceExtensions.GetData(); r = vkCreateInstance(&stInstanceCreateInfo, NULL, &g_vkInstance); - VULKAN_RESULT_PRINT(r, vkCreateInstance) + VULKAN_RESULT_PRINT(r, vkCreateInstance); // volk requires to load instance this way volkLoadInstance(g_vkInstance); @@ -161,15 +166,17 @@ void CVkRenderContext::Init() // Get amount of physical devices r = vkEnumeratePhysicalDevices(g_vkInstance, &nPhysicalDevicesCount, NULL); - VULKAN_RESULT_PRINT(r, vkEnumeratePhysicalDevices) + VULKAN_RESULT_PRINT(r, vkEnumeratePhysicalDevices); physicalDevices.Resize(nPhysicalDevicesCount); // Read all physical devices r = vkEnumeratePhysicalDevices(g_vkInstance, &nPhysicalDevicesCount, physicalDevices.GetData()); - VULKAN_RESULT_PRINT(r, vkEnumeratePhysicalDevices) + VULKAN_RESULT_PRINT(r, vkEnumeratePhysicalDevices); g_vkPhysicalDevice = SelectPhysicalDevice(physicalDevices); + enabledDeviceExtensions = GetDeviceExtensions(); + // Get all queues vkGetPhysicalDeviceQueueFamilyProperties(g_vkPhysicalDevice, &nNumQueueFamilies, NULL); @@ -198,6 +205,8 @@ void CVkRenderContext::Init() stDeviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; stDeviceCreateInfo.queueCreateInfoCount = 1; stDeviceCreateInfo.pQueueCreateInfos = &stDeviceQueueCreateInfo; + stDeviceCreateInfo.enabledExtensionCount = enabledDeviceExtensions.GetSize(); + stDeviceCreateInfo.ppEnabledExtensionNames = enabledDeviceExtensions.GetData(); vkCreateDevice(g_vkPhysicalDevice, &stDeviceCreateInfo, NULL, &g_vkDevice); CreateSwapchain(); @@ -210,15 +219,61 @@ void CVkRenderContext::Frame( float fDeltaTime ) void CVkRenderContext::CreateSwapchain() { + uint32_t numSurfaceFormats = 0; CUtlVector surfaceFormats; + + VkSurfaceCapabilitiesKHR surfaceCapatibilities = {}; + + uint32_t nSurfacePresentModes = 0; + CUtlVector surfacePresentModes; gamewindow->CreateVulkanSurface(g_vkInstance); - VkSwapchainCreateInfoKHR stSwapchainCreateInfo = {}; - stSwapchainCreateInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; - stSwapchainCreateInfo.surface = (VkSurfaceKHR)gamewindow->GetVulkanSurface(); - vkCreateSwapchainKHR(g_vkDevice, &stSwapchainCreateInfo, NULL, &g_vkSwapchain); + vkGetPhysicalDeviceSurfaceCapabilitiesKHR(g_vkPhysicalDevice, (VkSurfaceKHR)gamewindow->GetVulkanSurface(), &surfaceCapatibilities); + + const VkFormat preferedSurfaceFormats[] = { + VK_FORMAT_B8G8R8A8_UNORM, + VK_FORMAT_R8G8B8A8_UNORM, + }; + + vkGetPhysicalDeviceSurfaceFormatsKHR(g_vkPhysicalDevice, (VkSurfaceKHR)gamewindow->GetVulkanSurface(), &numSurfaceFormats, NULL); + surfaceFormats.Resize(numSurfaceFormats); + vkGetPhysicalDeviceSurfaceFormatsKHR(g_vkPhysicalDevice, (VkSurfaceKHR)gamewindow->GetVulkanSurface(), &numSurfaceFormats, surfaceFormats.GetData()); + + VkSurfaceFormatKHR selectedFormat = surfaceFormats[0]; + + for (auto &format: surfaceFormats) + { + for (int i = 0; i < sizeof(preferedSurfaceFormats)/sizeof(VkFormat); i++) + { + if (format.format == preferedSurfaceFormats[i]) + { + selectedFormat = format; + goto formatPicked; + } + } + } +formatPicked: + + vkGetPhysicalDeviceSurfacePresentModesKHR(g_vkPhysicalDevice, (VkSurfaceKHR)gamewindow->GetVulkanSurface(), &nSurfacePresentModes, NULL); + surfacePresentModes.Resize(nSurfacePresentModes); + vkGetPhysicalDeviceSurfacePresentModesKHR(g_vkPhysicalDevice, (VkSurfaceKHR)gamewindow->GetVulkanSurface(), &nSurfacePresentModes, surfacePresentModes.GetData()); + + VkSwapchainCreateInfoKHR swapchainCreateInfo = {}; + swapchainCreateInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; + swapchainCreateInfo.surface = (VkSurfaceKHR)gamewindow->GetVulkanSurface(); + swapchainCreateInfo.imageFormat = selectedFormat.format; + swapchainCreateInfo.imageColorSpace = selectedFormat.colorSpace; + swapchainCreateInfo.presentMode = VK_PRESENT_MODE_IMMEDIATE_KHR; + swapchainCreateInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; + swapchainCreateInfo.preTransform = surfaceCapatibilities.currentTransform; + swapchainCreateInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; + swapchainCreateInfo.imageArrayLayers = 1; + swapchainCreateInfo.imageExtent = surfaceCapatibilities.minImageExtent; + swapchainCreateInfo.minImageCount = surfaceCapatibilities.minImageCount; + vkCreateSwapchainKHR(g_vkDevice, &swapchainCreateInfo, NULL, &g_vkSwapchain); + } @@ -257,11 +312,11 @@ VkPhysicalDevice CVkRenderContext::SelectPhysicalDevice( CUtlVector CVkRenderContext::GetDeviceExtensions() +{ + VkResult r; + int i; + + uint32_t nExtensionCount; + CUtlVector extensions; + + CUtlVector enabledExtensions; + + const char *szExtensionName; + + r = vkEnumerateDeviceExtensionProperties(g_vkPhysicalDevice, NULL, &nExtensionCount, NULL); + VULKAN_RESULT_PRINT(r, vkEnumeratePhysicalDevices); + extensions.Resize(nExtensionCount); + + r = vkEnumerateDeviceExtensionProperties(g_vkPhysicalDevice, NULL, &nExtensionCount, extensions.GetData()); + VULKAN_RESULT_PRINT(r, vkEnumeratePhysicalDevices); + + +#define REQUIRED_EXTENSION(ext) if (!V_strcmp(extension.extensionName, ext##_EXTENSION_NAME)) { g_vkAvailableExtensions.bIsSupported_##ext = true; enabledExtensions.AppendTail(ext##_EXTENSION_NAME); continue; }; +#define OPTIONAL_EXTENSION(ext) REQUIRED_EXTENSION(ext); + + + for ( auto extension: extensions ) + { +#include "device_extensions.h" + } +#undef REQUIRED_EXTENSION +#undef OPTIONAL_EXTENSION + + return enabledExtensions; +} diff --git a/materialsystem/vulkan/vulkan_state.h b/materialsystem/vulkan/vulkan_state.h index f6fdb92..eb4286b 100644 --- a/materialsystem/vulkan/vulkan_state.h +++ b/materialsystem/vulkan/vulkan_state.h @@ -10,10 +10,10 @@ #define REQUIRED_EXTENSION(ext) bool bIsSupported_##ext; #define OPTIONAL_EXTENSION(ext) bool bIsSupported_##ext; -struct SupportedVulkanExtensions_t +extern struct SupportedVulkanExtensions_t { #include "device_extensions.h" -}; +} g_vkAvailableExtensions; #undef REQUIRED_EXTENSION #undef OPTIONAL_EXTENSION @@ -52,6 +52,6 @@ extern IVkCommandBuffer *vkcommandbuffer; #define VULKAN_RESULT_PRINT(r, func) \ if (r != VK_SUCCESS) \ - Plat_FatalErrorFunc(#func " failed: %s\n", string_VkResult(r)); + Plat_FatalErrorFunc(#func " failed: %s\n", string_VkResult(r)) #endif