added swapchain
This commit is contained in:
@@ -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<VkPhysicalDevice> physicalDevices );
|
||||
CUtlVector<const char *> GetDeviceExtensions();
|
||||
|
||||
void CreateSwapchain();
|
||||
void DestroySwapchain();
|
||||
@@ -117,7 +120,9 @@ void CVkRenderContext::Init()
|
||||
VkResult r;
|
||||
|
||||
int nExtensionCount;
|
||||
CUtlVector<const char *> extensions = {};
|
||||
|
||||
CUtlVector<const char *> enabledInstanceExtensions;
|
||||
CUtlVector<const char *> enabledDeviceExtensions;
|
||||
|
||||
uint32_t nPhysicalDevicesCount;
|
||||
CUtlVector<VkPhysicalDevice> 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<VkSurfaceFormatKHR> surfaceFormats;
|
||||
|
||||
VkSurfaceCapabilitiesKHR surfaceCapatibilities = {};
|
||||
|
||||
uint32_t nSurfacePresentModes = 0;
|
||||
CUtlVector<VkPresentModeKHR> 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<VkPhysicalDe
|
||||
uint32_t uScore = 0;
|
||||
|
||||
r = vkEnumerateDeviceExtensionProperties(device, NULL, &nExtensionCount, NULL);
|
||||
VULKAN_RESULT_PRINT(r, vkEnumeratePhysicalDevices)
|
||||
VULKAN_RESULT_PRINT(r, vkEnumeratePhysicalDevices);
|
||||
extensions.Resize(nExtensionCount);
|
||||
|
||||
r = vkEnumerateDeviceExtensionProperties(device, NULL, &nExtensionCount, extensions.GetData());
|
||||
VULKAN_RESULT_PRINT(r, vkEnumeratePhysicalDevices)
|
||||
VULKAN_RESULT_PRINT(r, vkEnumeratePhysicalDevices);
|
||||
|
||||
vkGetPhysicalDeviceProperties(device, &stPhysicalDeviceProperties);
|
||||
vkGetPhysicalDeviceFeatures(device, &stPhysicalDeviceFeatures);
|
||||
@@ -281,4 +336,37 @@ VkPhysicalDevice CVkRenderContext::SelectPhysicalDevice( CUtlVector<VkPhysicalDe
|
||||
return selectedDevice;
|
||||
}
|
||||
|
||||
CUtlVector<const char *> CVkRenderContext::GetDeviceExtensions()
|
||||
{
|
||||
VkResult r;
|
||||
int i;
|
||||
|
||||
uint32_t nExtensionCount;
|
||||
CUtlVector<VkExtensionProperties> extensions;
|
||||
|
||||
CUtlVector<const char *> 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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user