Add moltenvk argument buffers support

This commit is contained in:
Benau 2022-04-15 17:05:38 +08:00
parent a469d501f9
commit 99f1a2e03f
6 changed files with 1436 additions and 4 deletions

File diff suppressed because it is too large Load Diff

View File

@ -3,8 +3,22 @@
#if !defined(__APPLE__) || defined(DLOPEN_MOLTENVK)
#include <glad/vulkan.h>
#ifdef DLOPEN_MOLTENVK
#define VK_NO_PROTOTYPES 1
#include <vk_mvk_moltenvk.h>
extern PFN_vkGetMoltenVKConfigurationMVK vkGetMoltenVKConfigurationMVK;
extern PFN_vkSetMoltenVKConfigurationMVK vkSetMoltenVKConfigurationMVK;
extern PFN_vkGetPhysicalDeviceMetalFeaturesMVK vkGetPhysicalDeviceMetalFeaturesMVK;
#endif
#else
#include <vulkan/vulkan.h>
#if defined(__APPLE__)
#include <MoltenVK/vk_mvk_moltenvk.h>
#endif
#endif
#endif

View File

@ -472,6 +472,15 @@ GEVulkanDriver::GEVulkanDriver(const SIrrlichtCreationParameters& params,
g_paused_rendering.store(false);
g_device_created.store(true);
#if defined(__APPLE__)
MVKConfiguration cfg = {};
size_t cfg_size = sizeof(MVKConfiguration);
vkGetMoltenVKConfigurationMVK(VK_NULL_HANDLE, &cfg, &cfg_size);
// Enable to allow binding all textures at once
cfg.useMetalArgumentBuffers = VK_TRUE;
vkSetMoltenVKConfigurationMVK(VK_NULL_HANDLE, &cfg, &cfg_size);
#endif
createInstance(window);
#if !defined(__APPLE__) || defined(DLOPEN_MOLTENVK)
@ -495,6 +504,14 @@ GEVulkanDriver::GEVulkanDriver(const SIrrlichtCreationParameters& params,
m_device_extensions.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
findPhysicalDevice();
vkGetPhysicalDeviceProperties(m_physical_device, &m_properties);
#if defined(__APPLE__)
// Debug usage only
MVKPhysicalDeviceMetalFeatures mvk_features = {};
size_t mvk_features_size = sizeof(MVKPhysicalDeviceMetalFeatures);
vkGetPhysicalDeviceMetalFeaturesMVK(m_physical_device, &mvk_features, &mvk_features_size);
#endif
GEVulkanFeatures::init(this);
createDevice();

View File

@ -25,22 +25,27 @@ bool g_supports_partially_bound = false;
void GEVulkanFeatures::init(GEVulkanDriver* vk)
{
g_supports_bind_textures_at_once = true;
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
if (limit.maxDescriptorSetSamplers < GEVulkanShaderManager::getSamplerSize())
const unsigned max_sampler_size = GEVulkanShaderManager::getSamplerSize();
if (limit.maxDescriptorSetSamplers < max_sampler_size)
g_supports_bind_textures_at_once = false;
if (limit.maxDescriptorSetSampledImages < GEVulkanShaderManager::getSamplerSize())
if (limit.maxDescriptorSetSampledImages < max_sampler_size)
g_supports_bind_textures_at_once = false;
if (limit.maxPerStageDescriptorSamplers < GEVulkanShaderManager::getSamplerSize())
if (limit.maxPerStageDescriptorSamplers < max_sampler_size)
g_supports_bind_textures_at_once = false;
if (limit.maxPerStageDescriptorSampledImages < GEVulkanShaderManager::getSamplerSize())
if (limit.maxPerStageDescriptorSampledImages < max_sampler_size)
g_supports_bind_textures_at_once = false;
if (vk->getPhysicalDeviceFeatures().shaderSampledImageArrayDynamicIndexing == VK_FALSE)
{
dynamic_indexing = false;
g_supports_bind_textures_at_once = false;
}
uint32_t extension_count;
vkEnumerateDeviceExtensionProperties(vk->getPhysicalDevice(), NULL,
@ -74,6 +79,30 @@ void GEVulkanFeatures::init(GEVulkanDriver* vk)
.shaderSampledImageArrayNonUniformIndexing == VK_TRUE);
g_supports_partially_bound = (descriptor_indexing_features
.descriptorBindingPartiallyBound == VK_TRUE);
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)
{
g_supports_bind_textures_at_once =
props2.maxPerStageDescriptorUpdateAfterBindSamplers > max_sampler_size &&
props2.maxPerStageDescriptorUpdateAfterBindSampledImages > max_sampler_size &&
props2.maxDescriptorSetUpdateAfterBindSamplers > max_sampler_size &&
props2.maxDescriptorSetUpdateAfterBindSampledImages > max_sampler_size;
}
}
} // init
// ----------------------------------------------------------------------------

View File

@ -8,6 +8,7 @@ class MoltenVK
{
private:
bool m_loaded;
void* m_handle;
public:
// ------------------------------------------------------------------------
MoltenVK();

View File

@ -1,8 +1,14 @@
#include "MoltenVK.h"
#include "SDL_vulkan.h"
#include "vulkan_wrapper.h"
#include <dlfcn.h>
#import <AppKit/NSApplication.h>
#ifdef DLOPEN_MOLTENVK
PFN_vkGetMoltenVKConfigurationMVK vkGetMoltenVKConfigurationMVK = NULL;
PFN_vkSetMoltenVKConfigurationMVK vkSetMoltenVKConfigurationMVK = NULL;
PFN_vkGetPhysicalDeviceMetalFeaturesMVK vkGetPhysicalDeviceMetalFeaturesMVK = NULL;
namespace irr
{
@ -10,6 +16,7 @@ namespace irr
MoltenVK::MoltenVK()
{
m_loaded = false;
m_handle = NULL;
// MacOSX 10.11 or later supports Metal (MoltenVK)
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_10_Max)
return;
@ -25,6 +32,26 @@ MoltenVK::MoltenVK()
{
if (SDL_Vulkan_LoadLibrary(paths[i]) == 0)
{
// Following SDL/src/loadso/dlopen/SDL_sysloadso.c
m_handle = dlopen(paths[i], RTLD_NOW|RTLD_LOCAL);
if (!m_handle)
{
SDL_Vulkan_UnloadLibrary();
return;
}
vkGetMoltenVKConfigurationMVK = (PFN_vkGetMoltenVKConfigurationMVK)
dlsym(m_handle, "vkGetMoltenVKConfigurationMVK");
vkSetMoltenVKConfigurationMVK = (PFN_vkSetMoltenVKConfigurationMVK)
dlsym(m_handle, "vkSetMoltenVKConfigurationMVK");
vkGetPhysicalDeviceMetalFeaturesMVK = (PFN_vkGetPhysicalDeviceMetalFeaturesMVK)
dlsym(m_handle, "vkGetPhysicalDeviceMetalFeaturesMVK");
if (!vkGetMoltenVKConfigurationMVK ||
!vkSetMoltenVKConfigurationMVK ||
!vkGetPhysicalDeviceMetalFeaturesMVK)
{
SDL_Vulkan_UnloadLibrary();
return;
}
m_loaded = true;
break;
}
@ -35,7 +62,10 @@ MoltenVK::MoltenVK()
MoltenVK::~MoltenVK()
{
if (m_loaded)
{
dlclose(m_handle);
SDL_Vulkan_UnloadLibrary();
}
} // ~MoltenVK
#endif