KhronosGroup / MoltenVK

MoltenVK is a Vulkan Portability implementation. It layers a subset of the high-performance, industry-standard Vulkan graphics and compute API over Apple's Metal graphics framework, enabling Vulkan applications to run on macOS, iOS and tvOS.

Repository from Github https://github.comKhronosGroup/MoltenVKRepository from Github https://github.comKhronosGroup/MoltenVK

vkGetPerformanceStatisticsMVK() is no longer visible for dynamic proc addr lookups

SRSaunders opened this issue · comments

It seems that vkGetPerformanceStatisticsMVK() is no longer visible for dynamic lookups as follows:

vkGetPerformanceStatisticsMVK = ( PFN_vkGetPerformanceStatisticsMVK )vkGetInstanceProcAddr( m_VulkanInstance, "vkGetPerformanceStatisticsMVK" );

This operation now returns a null pointer. I suspect the recent PR #2526 has introduced a regression here.

I can reference vkGetPerformanceStatisticsMVK() via linking at build time, but this is not what I want.

@billhollings would it be possible to return dynamic lookup functionality for this private API function?

Note that vkGetPhysicalDeviceMetalFeaturesMVK() may suffer from the same problem, but I have not tested.

Looking at the code, a possible solution is: The problem is because of the following:

typedef struct MVKEntryPoint {
	PFN_vkVoidFunction functionPointer;
	const char* extName;
	uint32_t apiVersion;
	bool isDevice;

	bool isCore() { return apiVersion > 0; }
#define ADD_INST_OPEN_ENTRY_POINT(func)		ADD_ENTRY_POINT(func, 0, nullptr, false)
#define ADD_DVC_OPEN_ENTRY_POINT(func)		ADD_ENTRY_POINT(func, 0, nullptr, true)

// MoltenVK-specific instannce functions, not tied to a Vulkan API version or an extension.
ADD_INST_OPEN_ENTRY_POINT(vkGetPhysicalDeviceMetalFeaturesMVK);
ADD_INST_OPEN_ENTRY_POINT(vkGetPerformanceStatisticsMVK);

I see two possible solutions:

  1. Change the ADD_INST_OPEN_ENTRY_POINT and ADD_DVC_OPEN_ENTRY_POINT definitions to arbitrarily be VK_API_VERSION_1_0, or
  2. Change the isEnabled() logic to be something like:
bool isEnabled(uint32_t enabledVersion, const MVKExtensionList& extList, const MVKExtensionList* instExtList = nullptr) {
	return ((isCore() && MVK_VULKAN_API_VERSION_CONFORM(enabledVersion) >= apiVersion) ||
		extList.isEnabled(this->extName) ||
		(instExtList && instExtList->isEnabled(this->extName)) ||
		(apiVersion == 0 && this->extName == nullptr));
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}

where the last condition is true only in the case of these private API functions (*_OPEN_ENTRY_POINT).

Uggh. You're right. In that change, I neglected the ADD_INST_OPEN_ENTRY_POINT functions.

Thanks for the detective work, I'll sort this out and push a patch.

PR #2538 fixes this. See comments there. Please retest with that fix and close this issue if it meets needs, or comment on #2538 if it doesn't.