Enable vulkan 1.2 and ray tracing extensions, if available

This commit is contained in:
Magnus Norddahl 2022-06-05 23:24:00 +02:00 committed by Christoph Oelckers
parent c6416a2afe
commit bf1732904f
3 changed files with 121 additions and 22 deletions

View file

@ -217,7 +217,9 @@ void VulkanDevice::CreateAllocator()
{
VmaAllocatorCreateInfo allocinfo = {};
if (SupportsDeviceExtension(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME) && SupportsDeviceExtension(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME))
allocinfo.flags = VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT;
allocinfo.flags |= VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT;
if (SupportsDeviceExtension(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME))
allocinfo.flags |= VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT;
allocinfo.physicalDevice = PhysicalDevice.Device;
allocinfo.device = device;
allocinfo.instance = instance;
@ -245,14 +247,47 @@ void VulkanDevice::CreateDevice()
queueCreateInfos.push_back(queueCreateInfo);
}
VkDeviceCreateInfo deviceCreateInfo = {};
deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
VkDeviceCreateInfo deviceCreateInfo = { VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO };
VkPhysicalDeviceFeatures2 deviceFeatures2 = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2 };
VkPhysicalDeviceBufferDeviceAddressFeatures deviceAddressFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES };
VkPhysicalDeviceAccelerationStructureFeaturesKHR deviceAccelFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR };
VkPhysicalDeviceRayQueryFeaturesKHR rayQueryFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_QUERY_FEATURES_KHR };
deviceCreateInfo.queueCreateInfoCount = (uint32_t)queueCreateInfos.size();
deviceCreateInfo.pQueueCreateInfos = queueCreateInfos.data();
deviceCreateInfo.pEnabledFeatures = &UsedDeviceFeatures;
deviceCreateInfo.enabledExtensionCount = (uint32_t)EnabledDeviceExtensions.size();
deviceCreateInfo.ppEnabledExtensionNames = EnabledDeviceExtensions.data();
deviceCreateInfo.enabledLayerCount = 0;
deviceFeatures2.features = UsedDeviceFeatures;
deviceAddressFeatures.bufferDeviceAddress = true;
deviceAccelFeatures.accelerationStructure = true;
rayQueryFeatures.rayQuery = true;
void** next = const_cast<void**>(&deviceCreateInfo.pNext);
if (SupportsDeviceExtension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME))
{
*next = &deviceFeatures2;
void** next = &deviceFeatures2.pNext;
}
else // vulkan 1.0 specified features in a different way
{
deviceCreateInfo.pEnabledFeatures = &deviceFeatures2.features;
}
if (SupportsDeviceExtension(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME))
{
*next = &deviceAddressFeatures;
next = &deviceAddressFeatures.pNext;
}
if (SupportsDeviceExtension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME))
{
*next = &deviceAccelFeatures;
next = &deviceAccelFeatures.pNext;
}
if (SupportsDeviceExtension(VK_KHR_RAY_QUERY_EXTENSION_NAME))
{
*next = &rayQueryFeatures;
next = &rayQueryFeatures.pNext;
}
VkResult result = vkCreateDevice(PhysicalDevice.Device, &deviceCreateInfo, nullptr, &device);
CheckVulkanError(result, "Could not create vulkan device");
@ -306,23 +341,30 @@ void VulkanDevice::CreateInstance()
}
}
VkApplicationInfo appInfo = {};
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
appInfo.pApplicationName = "GZDoom";
appInfo.applicationVersion = VK_MAKE_VERSION(VER_MAJOR, VER_MINOR, VER_REVISION);
appInfo.pEngineName = "GZDoom";
appInfo.engineVersion = VK_MAKE_VERSION(ENG_MAJOR, ENG_MINOR, ENG_REVISION);
appInfo.apiVersion = VK_API_VERSION_1_0;
// Try get the highest vulkan version we can get
VkResult result = VK_ERROR_INITIALIZATION_FAILED;
for (int apiVersion : { VK_API_VERSION_1_2, VK_API_VERSION_1_1, VK_API_VERSION_1_0 })
{
VkApplicationInfo appInfo = {};
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
appInfo.pApplicationName = "GZDoom";
appInfo.applicationVersion = VK_MAKE_VERSION(VER_MAJOR, VER_MINOR, VER_REVISION);
appInfo.pEngineName = "GZDoom";
appInfo.engineVersion = VK_MAKE_VERSION(ENG_MAJOR, ENG_MINOR, ENG_REVISION);
appInfo.apiVersion = apiVersion;
VkInstanceCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
createInfo.pApplicationInfo = &appInfo;
createInfo.enabledExtensionCount = (uint32_t)EnabledExtensions.size();
createInfo.enabledLayerCount = (uint32_t)EnabledValidationLayers.size();
createInfo.ppEnabledLayerNames = EnabledValidationLayers.data();
createInfo.ppEnabledExtensionNames = EnabledExtensions.data();
VkInstanceCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
createInfo.pApplicationInfo = &appInfo;
createInfo.enabledExtensionCount = (uint32_t)EnabledExtensions.size();
createInfo.enabledLayerCount = (uint32_t)EnabledValidationLayers.size();
createInfo.ppEnabledLayerNames = EnabledValidationLayers.data();
createInfo.ppEnabledExtensionNames = EnabledExtensions.data();
VkResult result = vkCreateInstance(&createInfo, nullptr, &instance);
result = vkCreateInstance(&createInfo, nullptr, &instance);
if (result >= VK_SUCCESS)
break;
}
CheckVulkanError(result, "Could not create vulkan instance");
volkLoadInstance(instance);

View file

@ -64,7 +64,17 @@ public:
// Device setup
VkPhysicalDeviceFeatures UsedDeviceFeatures = {};
std::vector<const char *> EnabledDeviceExtensions = { VK_KHR_SWAPCHAIN_EXTENSION_NAME };
std::vector<const char *> OptionalDeviceExtensions = { VK_EXT_HDR_METADATA_EXTENSION_NAME, VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME };
std::vector<const char *> OptionalDeviceExtensions =
{
VK_EXT_HDR_METADATA_EXTENSION_NAME,
VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME,
VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME,
VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME,
VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME,
VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME,
VK_KHR_RAY_QUERY_EXTENSION_NAME
};
VulkanPhysicalDevice PhysicalDevice;
bool DebugLayerActive = false;
@ -80,6 +90,8 @@ public:
int presentFamily = -1;
bool graphicsTimeQueries = false;
bool SupportsDeviceExtension(const char* ext) const;
private:
void CreateInstance();
void CreateSurface();
@ -89,8 +101,6 @@ private:
void CreateAllocator();
void ReleaseResources();
bool SupportsDeviceExtension(const char *ext) const;
static bool CheckRequiredFeatures(const VkPhysicalDeviceFeatures &f);
VkDebugUtilsMessengerEXT debugMessenger = VK_NULL_HANDLE;

View file

@ -222,6 +222,22 @@ private:
VulkanQueryPool &operator=(const VulkanQueryPool &) = delete;
};
class VulkanAccelerationStructure
{
public:
VulkanAccelerationStructure(VulkanDevice* device, VkAccelerationStructureKHR accelstruct);
~VulkanAccelerationStructure();
void SetDebugName(const char* name) { device->SetDebugObjectName(name, (uint64_t)accelstruct, VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_KHR); }
VulkanDevice* device;
VkAccelerationStructureKHR accelstruct;
private:
VulkanAccelerationStructure(const VulkanAccelerationStructure&) = delete;
VulkanAccelerationStructure& operator=(const VulkanAccelerationStructure&) = delete;
};
class VulkanPipeline
{
public:
@ -355,6 +371,10 @@ public:
void endRenderPass();
void executeCommands(uint32_t commandBufferCount, const VkCommandBuffer* pCommandBuffers);
void buildAccelerationStructures(uint32_t infoCount, const VkAccelerationStructureBuildGeometryInfoKHR* pInfos, const VkAccelerationStructureBuildRangeInfoKHR* const* ppBuildRangeInfos);
void traceRays(const VkStridedDeviceAddressRegionKHR* pRaygenShaderBindingTable, const VkStridedDeviceAddressRegionKHR* pMissShaderBindingTable, const VkStridedDeviceAddressRegionKHR* pHitShaderBindingTable, const VkStridedDeviceAddressRegionKHR* pCallableShaderBindingTable, uint32_t width, uint32_t height, uint32_t depth);
void writeAccelerationStructuresProperties(uint32_t accelerationStructureCount, const VkAccelerationStructureKHR* pAccelerationStructures, VkQueryType queryType, VkQueryPool queryPool, uint32_t firstQuery);
void debugFullPipelineBarrier();
VkCommandBuffer buffer = nullptr;
@ -879,6 +899,21 @@ inline void VulkanCommandBuffer::executeCommands(uint32_t commandBufferCount, co
vkCmdExecuteCommands(buffer, commandBufferCount, pCommandBuffers);
}
inline void VulkanCommandBuffer::buildAccelerationStructures(uint32_t infoCount, const VkAccelerationStructureBuildGeometryInfoKHR* pInfos, const VkAccelerationStructureBuildRangeInfoKHR* const* ppBuildRangeInfos)
{
vkCmdBuildAccelerationStructuresKHR(buffer, infoCount, pInfos, ppBuildRangeInfos);
}
inline void VulkanCommandBuffer::traceRays(const VkStridedDeviceAddressRegionKHR* pRaygenShaderBindingTable, const VkStridedDeviceAddressRegionKHR* pMissShaderBindingTable, const VkStridedDeviceAddressRegionKHR* pHitShaderBindingTable, const VkStridedDeviceAddressRegionKHR* pCallableShaderBindingTable, uint32_t width, uint32_t height, uint32_t depth)
{
vkCmdTraceRaysKHR(buffer, pRaygenShaderBindingTable, pMissShaderBindingTable, pHitShaderBindingTable, pCallableShaderBindingTable, width, height, depth);
}
inline void VulkanCommandBuffer::writeAccelerationStructuresProperties(uint32_t accelerationStructureCount, const VkAccelerationStructureKHR* pAccelerationStructures, VkQueryType queryType, VkQueryPool queryPool, uint32_t firstQuery)
{
vkCmdWriteAccelerationStructuresPropertiesKHR(buffer, accelerationStructureCount, pAccelerationStructures, queryType, queryPool, firstQuery);
}
inline void VulkanCommandBuffer::SetDebugName(const char *name)
{
pool->device->SetDebugObjectName(name, (uint64_t)buffer, VK_OBJECT_TYPE_COMMAND_BUFFER);
@ -1035,6 +1070,18 @@ inline VulkanSampler::~VulkanSampler()
/////////////////////////////////////////////////////////////////////////////
inline VulkanAccelerationStructure::VulkanAccelerationStructure(VulkanDevice* device, VkAccelerationStructureKHR accelstruct)
: device(device), accelstruct(accelstruct)
{
}
inline VulkanAccelerationStructure::~VulkanAccelerationStructure()
{
vkDestroyAccelerationStructureKHR(device->device, accelstruct, nullptr);
}
/////////////////////////////////////////////////////////////////////////////
inline VulkanPipeline::VulkanPipeline(VulkanDevice *device, VkPipeline pipeline) : device(device), pipeline(pipeline)
{
}