2022-03-19 03:14:55 -04:00
|
|
|
#include "ge_vulkan_features.hpp"
|
|
|
|
|
|
|
|
#include "ge_vulkan_driver.hpp"
|
2022-03-20 01:35:22 -04:00
|
|
|
#include "ge_vulkan_shader_manager.hpp"
|
2022-03-19 03:14:55 -04:00
|
|
|
|
2022-07-21 00:26:06 -04:00
|
|
|
#include <algorithm>
|
2022-03-19 03:14:55 -04:00
|
|
|
#include <set>
|
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
#include "../source/Irrlicht/os.h"
|
|
|
|
|
|
|
|
namespace GE
|
|
|
|
{
|
|
|
|
namespace GEVulkanFeatures
|
|
|
|
{
|
|
|
|
// ============================================================================
|
2022-03-20 01:35:22 -04:00
|
|
|
bool g_supports_bind_textures_at_once = false;
|
2022-04-19 00:49:05 -04:00
|
|
|
bool g_supports_rgba8_blit = false;
|
|
|
|
bool g_supports_r8_blit = false;
|
2022-03-19 03:14:55 -04:00
|
|
|
// https://chunkstories.xyz/blog/a-note-on-descriptor-indexing
|
|
|
|
bool g_supports_descriptor_indexing = false;
|
|
|
|
bool g_supports_non_uniform_indexing = false;
|
|
|
|
bool g_supports_partially_bound = false;
|
2022-07-21 00:26:06 -04:00
|
|
|
uint32_t g_max_sampler_supported = 0;
|
2022-03-19 03:14:55 -04:00
|
|
|
} // GEVulkanFeatures
|
|
|
|
|
|
|
|
// ============================================================================
|
|
|
|
void GEVulkanFeatures::init(GEVulkanDriver* vk)
|
|
|
|
{
|
2022-03-20 01:35:22 -04:00
|
|
|
g_supports_bind_textures_at_once = true;
|
2022-04-15 05:05:38 -04:00
|
|
|
bool dynamic_indexing = true;
|
2022-03-20 01:35:22 -04:00
|
|
|
VkPhysicalDeviceLimits limit = vk->getPhysicalDeviceProperties().limits;
|
|
|
|
// https://vulkan.gpuinfo.org/displaydevicelimit.php?name=maxDescriptorSetSamplers&platform=all
|
|
|
|
// https://vulkan.gpuinfo.org/displaydevicelimit.php?name=maxDescriptorSetSampledImages&platform=all
|
|
|
|
// https://vulkan.gpuinfo.org/displaydevicelimit.php?name=maxPerStageDescriptorSamplers&platform=all
|
|
|
|
// https://vulkan.gpuinfo.org/displaydevicelimit.php?name=maxPerStageDescriptorSampledImages&platform=all
|
|
|
|
// We decide 256 (GEVulkanShaderManager::getSamplerSize()) based on those infos
|
2022-07-21 00:26:06 -04:00
|
|
|
g_max_sampler_supported = std::min(
|
|
|
|
{
|
|
|
|
limit.maxDescriptorSetSamplers,
|
|
|
|
limit.maxDescriptorSetSampledImages,
|
|
|
|
limit.maxPerStageDescriptorSamplers,
|
|
|
|
limit.maxPerStageDescriptorSampledImages
|
|
|
|
});
|
2022-04-15 05:05:38 -04:00
|
|
|
const unsigned max_sampler_size = GEVulkanShaderManager::getSamplerSize();
|
2022-07-21 00:26:06 -04:00
|
|
|
if (max_sampler_size > g_max_sampler_supported)
|
2022-03-20 01:35:22 -04:00
|
|
|
g_supports_bind_textures_at_once = false;
|
|
|
|
if (vk->getPhysicalDeviceFeatures().shaderSampledImageArrayDynamicIndexing == VK_FALSE)
|
2022-04-15 05:05:38 -04:00
|
|
|
{
|
|
|
|
dynamic_indexing = false;
|
2022-03-20 01:35:22 -04:00
|
|
|
g_supports_bind_textures_at_once = false;
|
2022-04-15 05:05:38 -04:00
|
|
|
}
|
2022-03-20 01:35:22 -04:00
|
|
|
|
2022-04-19 00:49:05 -04:00
|
|
|
VkFormatProperties format_properties = {};
|
|
|
|
vkGetPhysicalDeviceFormatProperties(vk->getPhysicalDevice(),
|
|
|
|
VK_FORMAT_R8G8B8A8_UNORM, &format_properties);
|
|
|
|
g_supports_rgba8_blit = format_properties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
|
|
|
|
format_properties = {};
|
|
|
|
vkGetPhysicalDeviceFormatProperties(vk->getPhysicalDevice(),
|
|
|
|
VK_FORMAT_R8_UNORM, &format_properties);
|
|
|
|
g_supports_r8_blit = format_properties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
|
|
|
|
|
2022-03-19 03:14:55 -04:00
|
|
|
uint32_t extension_count;
|
|
|
|
vkEnumerateDeviceExtensionProperties(vk->getPhysicalDevice(), NULL,
|
|
|
|
&extension_count, NULL);
|
|
|
|
std::vector<VkExtensionProperties> extensions(extension_count);
|
|
|
|
vkEnumerateDeviceExtensionProperties(vk->getPhysicalDevice(), NULL,
|
|
|
|
&extension_count, &extensions[0]);
|
|
|
|
|
|
|
|
for (VkExtensionProperties& prop : extensions)
|
|
|
|
{
|
|
|
|
if (std::string(prop.extensionName) == "VK_EXT_descriptor_indexing")
|
|
|
|
g_supports_descriptor_indexing = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
VkPhysicalDeviceFeatures2 supported_features = {};
|
|
|
|
supported_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
|
|
|
|
VkPhysicalDeviceDescriptorIndexingFeatures descriptor_indexing_features = {};
|
|
|
|
descriptor_indexing_features.sType =
|
|
|
|
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES;
|
|
|
|
supported_features.pNext = &descriptor_indexing_features;
|
|
|
|
|
2022-04-02 21:55:17 -04:00
|
|
|
if (vk->getPhysicalDeviceProperties().apiVersion < VK_API_VERSION_1_1 ||
|
|
|
|
!vkGetPhysicalDeviceFeatures2)
|
2022-03-19 03:14:55 -04:00
|
|
|
return;
|
|
|
|
vkGetPhysicalDeviceFeatures2(vk->getPhysicalDevice(), &supported_features);
|
|
|
|
if (supported_features.sType !=
|
|
|
|
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2)
|
|
|
|
return;
|
|
|
|
|
|
|
|
g_supports_non_uniform_indexing = (descriptor_indexing_features
|
|
|
|
.shaderSampledImageArrayNonUniformIndexing == VK_TRUE);
|
|
|
|
g_supports_partially_bound = (descriptor_indexing_features
|
|
|
|
.descriptorBindingPartiallyBound == VK_TRUE);
|
2022-04-15 05:05:38 -04:00
|
|
|
|
|
|
|
bool missing_vkGetPhysicalDeviceProperties2 =
|
|
|
|
!vkGetPhysicalDeviceProperties2;
|
|
|
|
if (!missing_vkGetPhysicalDeviceProperties2 &&
|
|
|
|
!g_supports_bind_textures_at_once && dynamic_indexing)
|
|
|
|
{
|
|
|
|
// Required for moltenvk argument buffers
|
|
|
|
VkPhysicalDeviceProperties2 props1 = {};
|
|
|
|
props1.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
|
|
|
|
VkPhysicalDeviceDescriptorIndexingProperties props2 = {};
|
|
|
|
props2.sType =
|
|
|
|
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES;
|
|
|
|
props1.pNext = &props2;
|
|
|
|
vkGetPhysicalDeviceProperties2(vk->getPhysicalDevice(), &props1);
|
|
|
|
if (props2.sType ==
|
|
|
|
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES)
|
|
|
|
{
|
2022-07-21 00:26:06 -04:00
|
|
|
g_max_sampler_supported = std::min(
|
|
|
|
{
|
|
|
|
props2.maxPerStageDescriptorUpdateAfterBindSamplers,
|
|
|
|
props2.maxPerStageDescriptorUpdateAfterBindSampledImages,
|
|
|
|
props2.maxDescriptorSetUpdateAfterBindSamplers,
|
|
|
|
props2.maxDescriptorSetUpdateAfterBindSampledImages
|
|
|
|
});
|
2022-04-15 05:05:38 -04:00
|
|
|
g_supports_bind_textures_at_once =
|
2022-07-21 00:26:06 -04:00
|
|
|
g_max_sampler_supported >= max_sampler_size;
|
2022-04-15 05:05:38 -04:00
|
|
|
}
|
|
|
|
}
|
2022-03-19 03:14:55 -04:00
|
|
|
} // init
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
void GEVulkanFeatures::printStats()
|
|
|
|
{
|
2022-03-20 01:35:22 -04:00
|
|
|
os::Printer::log(
|
|
|
|
"Vulkan can bind textures at once in shader",
|
|
|
|
g_supports_bind_textures_at_once ? "true" : "false");
|
2022-07-21 00:26:06 -04:00
|
|
|
os::Printer::log(
|
|
|
|
"Vulkan can bind mesh textures at once in shader",
|
|
|
|
supportsBindMeshTexturesAtOnce() ? "true" : "false");
|
2022-04-19 00:49:05 -04:00
|
|
|
os::Printer::log(
|
|
|
|
"Vulkan supports linear blitting for rgba8",
|
|
|
|
g_supports_rgba8_blit ? "true" : "false");
|
|
|
|
os::Printer::log(
|
|
|
|
"Vulkan supports linear blitting for r8",
|
|
|
|
g_supports_r8_blit ? "true" : "false");
|
2022-03-19 03:14:55 -04:00
|
|
|
os::Printer::log(
|
|
|
|
"Vulkan supports VK_EXT_descriptor_indexing",
|
|
|
|
g_supports_descriptor_indexing ? "true" : "false");
|
|
|
|
os::Printer::log(
|
|
|
|
"Vulkan descriptor indexes can be dynamically non-uniform",
|
|
|
|
g_supports_non_uniform_indexing ? "true" : "false");
|
|
|
|
os::Printer::log(
|
|
|
|
"Vulkan descriptor can be partially bound",
|
|
|
|
g_supports_partially_bound ? "true" : "false");
|
|
|
|
} // printStats
|
|
|
|
|
2022-03-20 01:35:22 -04:00
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
bool GEVulkanFeatures::supportsBindTexturesAtOnce()
|
|
|
|
{
|
|
|
|
return g_supports_bind_textures_at_once;
|
|
|
|
} // supportsBindTexturesAtOnce
|
|
|
|
|
2022-04-19 00:49:05 -04:00
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
bool GEVulkanFeatures::supportsRGBA8Blit()
|
|
|
|
{
|
|
|
|
return g_supports_rgba8_blit;
|
|
|
|
} // supportsRGBA8Blit
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
bool GEVulkanFeatures::supportsR8Blit()
|
|
|
|
{
|
|
|
|
return g_supports_r8_blit;
|
|
|
|
} // supportsR8Blit
|
|
|
|
|
2022-03-19 03:14:55 -04:00
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
bool GEVulkanFeatures::supportsDescriptorIndexing()
|
|
|
|
{
|
|
|
|
return g_supports_descriptor_indexing;
|
|
|
|
} // supportsDescriptorIndexing
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
bool GEVulkanFeatures::supportsNonUniformIndexing()
|
|
|
|
{
|
|
|
|
return g_supports_non_uniform_indexing;
|
|
|
|
} // supportsNonUniformIndexing
|
|
|
|
|
2022-03-19 04:09:32 -04:00
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
bool GEVulkanFeatures::supportsDifferentTexturePerDraw()
|
|
|
|
{
|
2022-03-20 01:35:22 -04:00
|
|
|
return g_supports_bind_textures_at_once &&
|
|
|
|
g_supports_descriptor_indexing && g_supports_non_uniform_indexing;
|
2022-03-19 04:09:32 -04:00
|
|
|
} // supportsDifferentTexturePerDraw
|
|
|
|
|
2022-03-19 03:14:55 -04:00
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
bool GEVulkanFeatures::supportsPartiallyBound()
|
|
|
|
{
|
|
|
|
return g_supports_partially_bound;
|
|
|
|
} // supportsPartiallyBound
|
|
|
|
|
2022-07-21 00:26:06 -04:00
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
bool GEVulkanFeatures::supportsBindMeshTexturesAtOnce()
|
|
|
|
{
|
|
|
|
if (!g_supports_bind_textures_at_once)
|
|
|
|
return false;
|
|
|
|
const unsigned sampler_count = GEVulkanShaderManager::getSamplerSize() *
|
|
|
|
GEVulkanShaderManager::getMeshTextureLayer();
|
|
|
|
return g_max_sampler_supported >= sampler_count;
|
|
|
|
} // supportsBindMeshTexturesAtOnce
|
|
|
|
|
2022-03-19 03:14:55 -04:00
|
|
|
}
|