Vulkan improvements. (#316)

* Vulkan: Cleanup core 1.2 feature checks.

* Vulkan: Improve SwapChain creation logic and handle capabilities in better way.

* Vulkan: VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME depends on VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME (which is Core 1.2)

* VK_KHR_get_physical_device_properties2 is core in 1.1 and no need to enable on instance extension.

* Vulkan: FIX checks with core 1.2 features.
This commit is contained in:
Amer Koleci
2021-09-21 11:07:23 +02:00
committed by GitHub
parent 72fc0fd453
commit 7a4ea17e4e
+74 -50
View File
@@ -905,9 +905,6 @@ namespace Vulkan_Internal
RenderPass renderpass;
VkSurfaceKHR surface = VK_NULL_HANDLE;
VkSurfaceCapabilitiesKHR swapchain_capabilities;
std::vector<VkSurfaceFormatKHR> swapchain_formats;
std::vector<VkPresentModeKHR> swapchain_presentModes;
uint32_t swapChainImageIndex = 0;
VkSemaphore swapchainAcquireSemaphore = VK_NULL_HANDLE;
@@ -2025,15 +2022,10 @@ using namespace Vulkan_Internal;
enabled_deviceExtensions = required_deviceExtensions;
if (checkExtensionSupport(VK_KHR_SPIRV_1_4_EXTENSION_NAME, available_deviceExtensions))
{
enabled_deviceExtensions.push_back(VK_KHR_SPIRV_1_4_EXTENSION_NAME);
}
if (checkExtensionSupport(VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME, available_deviceExtensions))
{
enabled_deviceExtensions.push_back(VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME);
}
// Core 1.2
enabled_deviceExtensions.push_back(VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME);
enabled_deviceExtensions.push_back(VK_KHR_SPIRV_1_4_EXTENSION_NAME);
enabled_deviceExtensions.push_back(VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME);
if (checkExtensionSupport(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, available_deviceExtensions))
{
@@ -2070,6 +2062,8 @@ using namespace Vulkan_Internal;
if (checkExtensionSupport(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME, available_deviceExtensions))
{
assert(checkExtensionSupport(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME, available_deviceExtensions));
enabled_deviceExtensions.push_back(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME);
enabled_deviceExtensions.push_back(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME);
fragment_shading_rate_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_FEATURES_KHR;
*features_chain = &fragment_shading_rate_features;
@@ -2120,6 +2114,8 @@ using namespace Vulkan_Internal;
assert(features2.features.shaderClipDistance == VK_TRUE);
assert(features2.features.textureCompressionBC == VK_TRUE);
assert(features2.features.occlusionQueryPrecise == VK_TRUE);
assert(features_1_2.descriptorIndexing == VK_TRUE);
if (features2.features.tessellationShader == VK_TRUE)
{
capabilities |= GRAPHICSDEVICE_CAPABILITY_TESSELLATION;
@@ -2137,8 +2133,7 @@ using namespace Vulkan_Internal;
raytracing_features.rayTracingPipeline == VK_TRUE &&
raytracing_query_features.rayQuery == VK_TRUE &&
acceleration_structure_features.accelerationStructure == VK_TRUE &&
features_1_2.bufferDeviceAddress == VK_TRUE
)
features_1_2.bufferDeviceAddress == VK_TRUE)
{
capabilities |= GRAPHICSDEVICE_CAPABILITY_RAYTRACING;
SHADER_IDENTIFIER_SIZE = raytracing_properties.shaderGroupHandleSize;
@@ -2157,8 +2152,6 @@ using namespace Vulkan_Internal;
VARIABLE_RATE_SHADING_TILE_SIZE = std::min(fragment_shading_rate_properties.maxFragmentShadingRateAttachmentTexelSize.width, fragment_shading_rate_properties.maxFragmentShadingRateAttachmentTexelSize.height);
}
assert(features_1_2.descriptorIndexing == VK_TRUE);
VkFormatProperties formatProperties = {};
vkGetPhysicalDeviceFormatProperties(physicalDevice, _ConvertFormat(FORMAT_R11G11B10_FLOAT), &formatProperties);
if (formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT)
@@ -2513,30 +2506,31 @@ using namespace Vulkan_Internal;
dynamicStateInfo.dynamicStateCount = (uint32_t)pso_dynamicStates.size();
dynamicStateInfo.pDynamicStates = pso_dynamicStates.data();
if (features_1_2.descriptorBindingSampledImageUpdateAfterBind)
if (features_1_2.descriptorBindingSampledImageUpdateAfterBind == VK_TRUE)
{
allocationhandler->bindlessSampledImages.init(device, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, properties_1_2.maxDescriptorSetUpdateAfterBindSampledImages / 4);
}
if (features_1_2.descriptorBindingUniformTexelBufferUpdateAfterBind)
if (features_1_2.descriptorBindingUniformTexelBufferUpdateAfterBind == VK_TRUE)
{
allocationhandler->bindlessUniformTexelBuffers.init(device, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, properties_1_2.maxDescriptorSetUpdateAfterBindSampledImages / 4);
}
if (features_1_2.descriptorBindingStorageBufferUpdateAfterBind)
if (features_1_2.descriptorBindingStorageBufferUpdateAfterBind == VK_TRUE)
{
allocationhandler->bindlessStorageBuffers.init(device, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, properties_1_2.maxDescriptorSetUpdateAfterBindStorageBuffers / 4);
}
if (features_1_2.descriptorBindingStorageImageUpdateAfterBind)
if (features_1_2.descriptorBindingStorageImageUpdateAfterBind == VK_TRUE)
{
allocationhandler->bindlessStorageImages.init(device, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, properties_1_2.maxDescriptorSetUpdateAfterBindStorageImages / 4);
}
if (features_1_2.descriptorBindingStorageTexelBufferUpdateAfterBind)
if (features_1_2.descriptorBindingStorageTexelBufferUpdateAfterBind == VK_TRUE)
{
allocationhandler->bindlessStorageTexelBuffers.init(device, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, properties_1_2.maxDescriptorSetUpdateAfterBindStorageImages / 4);
}
if (features_1_2.descriptorBindingSampledImageUpdateAfterBind)
if (features_1_2.descriptorBindingSampledImageUpdateAfterBind == VK_TRUE)
{
allocationhandler->bindlessSamplers.init(device, VK_DESCRIPTOR_TYPE_SAMPLER, 256);
}
if (CheckCapability(GRAPHICSDEVICE_CAPABILITY_RAYTRACING))
{
allocationhandler->bindlessAccelerationStructures.init(device, VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 32);
@@ -2654,52 +2648,55 @@ using namespace Vulkan_Internal;
#endif // _WIN32
}
int presentFamily = -1;
int familyIndex = 0;
uint32_t presentFamily = VK_QUEUE_FAMILY_IGNORED;
uint32_t familyIndex = 0;
for (const auto& queueFamily : queueFamilies)
{
VkBool32 presentSupport = false;
res = vkGetPhysicalDeviceSurfaceSupportKHR(physicalDevice, (uint32_t)familyIndex, internal_state->surface, &presentSupport);
assert(res == VK_SUCCESS);
if (presentFamily < 0 && queueFamily.queueCount > 0 && presentSupport)
if (presentFamily == VK_QUEUE_FAMILY_IGNORED && queueFamily.queueCount > 0 && presentSupport)
{
presentFamily = familyIndex;
break;
}
familyIndex++;
}
res = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, internal_state->surface, &internal_state->swapchain_capabilities);
// Present family not found, we cannot create SwapChain
if (presentFamily == VK_QUEUE_FAMILY_IGNORED)
{
return false;
}
VkSurfaceCapabilitiesKHR swapchain_capabilities;
res = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, internal_state->surface, &swapchain_capabilities);
assert(res == VK_SUCCESS);
uint32_t formatCount;
res = vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, internal_state->surface, &formatCount, nullptr);
assert(res == VK_SUCCESS);
if (formatCount != 0)
{
internal_state->swapchain_formats.resize(formatCount);
res = vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, internal_state->surface, &formatCount, internal_state->swapchain_formats.data());
assert(res == VK_SUCCESS);
}
std::vector<VkSurfaceFormatKHR> swapchain_formats(formatCount);
res = vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, internal_state->surface, &formatCount, swapchain_formats.data());
assert(res == VK_SUCCESS);
uint32_t presentModeCount;
res = vkGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, internal_state->surface, &presentModeCount, nullptr);
assert(res == VK_SUCCESS);
if (presentModeCount != 0)
{
internal_state->swapchain_presentModes.resize(presentModeCount);
res = vkGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, internal_state->surface, &presentModeCount, internal_state->swapchain_presentModes.data());
assert(res == VK_SUCCESS);
}
std::vector<VkPresentModeKHR> swapchain_presentModes(presentModeCount);
swapchain_presentModes.resize(presentModeCount);
res = vkGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, internal_state->surface, &presentModeCount, swapchain_presentModes.data());
assert(res == VK_SUCCESS);
VkSurfaceFormatKHR surfaceFormat = {};
surfaceFormat.format = _ConvertFormat(pDesc->format);
bool valid = false;
for (const auto& format : internal_state->swapchain_formats)
for (const auto& format : swapchain_formats)
{
if (format.format == surfaceFormat.format)
{
@@ -2714,11 +2711,14 @@ using namespace Vulkan_Internal;
}
internal_state->swapChainExtent = { pDesc->width, pDesc->height };
internal_state->swapChainExtent.width = std::max(internal_state->swapchain_capabilities.minImageExtent.width, std::min(internal_state->swapchain_capabilities.maxImageExtent.width, internal_state->swapChainExtent.width));
internal_state->swapChainExtent.height = std::max(internal_state->swapchain_capabilities.minImageExtent.height, std::min(internal_state->swapchain_capabilities.maxImageExtent.height, internal_state->swapChainExtent.height));
internal_state->swapChainExtent.width = std::max(swapchain_capabilities.minImageExtent.width, std::min(swapchain_capabilities.maxImageExtent.width, internal_state->swapChainExtent.width));
internal_state->swapChainExtent.height = std::max(swapchain_capabilities.minImageExtent.height, std::min(swapchain_capabilities.maxImageExtent.height, internal_state->swapChainExtent.height));
uint32_t imageCount = pDesc->buffercount;
if ((swapchain_capabilities.maxImageCount > 0) && (imageCount > swapchain_capabilities.maxImageCount))
{
imageCount = swapchain_capabilities.maxImageCount;
}
VkSwapchainCreateInfoKHR createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
@@ -2731,18 +2731,42 @@ using namespace Vulkan_Internal;
createInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
createInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
createInfo.preTransform = internal_state->swapchain_capabilities.currentTransform;
createInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
// Transform
if(swapchain_capabilities.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR)
createInfo.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
else
createInfo.preTransform = swapchain_capabilities.currentTransform;
// Composite alpha
std::vector<VkCompositeAlphaFlagBitsKHR> compositeAlphaFlags = {
VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR,
VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR,
VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR,
};
for (auto& compositeAlphaFlag : compositeAlphaFlags)
{
if (swapchain_capabilities.supportedCompositeAlpha & compositeAlphaFlag)
{
createInfo.compositeAlpha = compositeAlphaFlag;
break;
};
}
createInfo.presentMode = VK_PRESENT_MODE_FIFO_KHR; // The only one that is always supported
if (!pDesc->vsync)
{
// The immediate present mode is not necessarily supported:
for (auto& presentmode : internal_state->swapchain_presentModes)
// The mailbox/immediate present mode is not necessarily supported:
for (auto& presentMode : swapchain_presentModes)
{
if (presentmode == VK_PRESENT_MODE_IMMEDIATE_KHR)
if (presentMode == VK_PRESENT_MODE_MAILBOX_KHR)
{
createInfo.presentMode = VK_PRESENT_MODE_MAILBOX_KHR;
break;
}
if (presentMode == VK_PRESENT_MODE_IMMEDIATE_KHR)
{
createInfo.presentMode = VK_PRESENT_MODE_IMMEDIATE_KHR;
break;
}
}
}
@@ -2765,12 +2789,12 @@ using namespace Vulkan_Internal;
assert(res == VK_SUCCESS);
internal_state->swapChainImageFormat = surfaceFormat.format;
if (vkSetDebugUtilsObjectNameEXT != nullptr)
if (debugUtils)
{
VkDebugUtilsObjectNameInfoEXT info = {};
info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT;
info.pObjectName = "SWAPCHAIN";
info.objectType = VK_OBJECT_TYPE_IMAGE;
info.pObjectName = "SWAPCHAIN";
for (auto& x : internal_state->swapChainImages)
{
info.objectHandle = (uint64_t)x;