stk-code_catmod/lib/graphics_engine/src/ge_vulkan_features.cpp

265 lines
11 KiB
C++
Raw Normal View History

2022-03-19 03:14:55 -04:00
#include "ge_vulkan_features.hpp"
#include "ge_vulkan_driver.hpp"
#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
{
// ============================================================================
bool g_supports_bind_textures_at_once = false;
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-07-23 02:02:37 -04:00
bool g_supports_multi_draw_indirect = false;
bool g_supports_base_vertex_rendering = true;
2022-08-03 22:56:29 -04:00
bool g_supports_compute_in_main_queue = false;
2022-03-19 03:14:55 -04:00
} // GEVulkanFeatures
// ============================================================================
void GEVulkanFeatures::init(GEVulkanDriver* vk)
{
g_supports_bind_textures_at_once = true;
2022-04-15 05:05:38 -04:00
bool dynamic_indexing = true;
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)
g_supports_bind_textures_at_once = false;
if (vk->getPhysicalDeviceFeatures().shaderSampledImageArrayDynamicIndexing == VK_FALSE)
2022-04-15 05:05:38 -04:00
{
dynamic_indexing = false;
g_supports_bind_textures_at_once = false;
2022-04-15 05:05:38 -04:00
}
2022-07-23 02:02:37 -04:00
g_supports_multi_draw_indirect = vk->getPhysicalDeviceFeatures().multiDrawIndirect &&
vk->getPhysicalDeviceFeatures().drawIndirectFirstInstance;
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;
}
2022-08-03 22:56:29 -04:00
uint32_t queue_family_count = 0;
vkGetPhysicalDeviceQueueFamilyProperties(vk->getPhysicalDevice(),
&queue_family_count, NULL);
if (queue_family_count != 0)
{
std::vector<VkQueueFamilyProperties> queue_families(queue_family_count);
vkGetPhysicalDeviceQueueFamilyProperties(vk->getPhysicalDevice(),
&queue_family_count, &queue_families[0]);
uint32_t main_family = vk->getGraphicsFamily();
if (main_family < queue_families.size())
{
g_supports_compute_in_main_queue =
(queue_families[main_family].queueFlags & VK_QUEUE_COMPUTE_BIT)
!= 0;
}
}
2022-03-19 03:14:55 -04:00
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
}
}
#if defined(__APPLE__)
MVKPhysicalDeviceMetalFeatures mvk_features = {};
size_t mvk_features_size = sizeof(MVKPhysicalDeviceMetalFeatures);
vkGetPhysicalDeviceMetalFeaturesMVK(vk->getPhysicalDevice(), &mvk_features,
&mvk_features_size);
g_supports_base_vertex_rendering = mvk_features.baseVertexInstanceDrawing;
if (!g_supports_base_vertex_rendering)
g_supports_multi_draw_indirect = false;
#endif
2022-03-19 03:14:55 -04:00
} // init
// ----------------------------------------------------------------------------
void GEVulkanFeatures::printStats()
{
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");
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");
2022-07-23 02:02:37 -04:00
os::Printer::log(
"Vulkan supports multi-draw indirect",
g_supports_multi_draw_indirect ? "true" : "false");
os::Printer::log(
"Vulkan supports base vertex rendering",
g_supports_base_vertex_rendering ? "true" : "false");
2022-08-03 22:56:29 -04:00
os::Printer::log(
"Vulkan supports compute in main queue",
g_supports_compute_in_main_queue ? "true" : "false");
2022-03-19 03:14:55 -04:00
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
// ----------------------------------------------------------------------------
bool GEVulkanFeatures::supportsBindTexturesAtOnce()
{
return g_supports_bind_textures_at_once;
} // supportsBindTexturesAtOnce
// ----------------------------------------------------------------------------
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
// ----------------------------------------------------------------------------
bool GEVulkanFeatures::supportsDifferentTexturePerDraw()
{
return g_supports_bind_textures_at_once &&
g_supports_descriptor_indexing && g_supports_non_uniform_indexing;
} // 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-07-23 02:02:37 -04:00
// ----------------------------------------------------------------------------
bool GEVulkanFeatures::supportsMultiDrawIndirect()
{
return g_supports_multi_draw_indirect;
2022-08-03 22:56:29 -04:00
} // supportsMultiDrawIndirect
2022-07-23 02:02:37 -04:00
// ----------------------------------------------------------------------------
bool GEVulkanFeatures::supportsBaseVertexRendering()
{
return g_supports_base_vertex_rendering;
2022-08-03 22:56:29 -04:00
} // supportsBaseVertexRendering
// ----------------------------------------------------------------------------
bool GEVulkanFeatures::supportsComputeInMainQueue()
{
return g_supports_compute_in_main_queue;
} // supportsComputeInMainQueue
2022-03-19 03:14:55 -04:00
}