Fix linking issues with dynamic Vulkan functions.
- Ensure Vulkan public symbols are not stripped from the library when statically linked to an app that calls all Vulkan functions dynamically. - Per Vulkan 1.2 spec, support calling vkGetInstanceProcAddr() with a null instance, when vkGetInstanceProcAddr itself is the function name. - Replace uses of strcmp() with mvkStringsAreEqual() to protect against null pointers, and provide a direct bool output (unrelated cleanup).
This commit is contained in:
parent
7a320974d1
commit
682906976d
@ -102,8 +102,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
/** Directive to identify public symbols. */
|
||||
#define MVK_PUBLIC_SYMBOL __attribute__((visibility("default")))
|
||||
|
||||
#define MVK_PUBLIC_SYMBOL __attribute__((visibility("default"))) __attribute__((used))
|
||||
|
||||
/** Directive to make a public alias of another symbol. */
|
||||
#define MVK_PUBLIC_ALIAS(ALIAS, TARGET) asm(".globl _" #ALIAS "\n\t_" #ALIAS " = _" #TARGET)
|
||||
|
@ -22,6 +22,10 @@ Released TBD
|
||||
`MTLCommandBuffer` is finished using it.
|
||||
- Fix memory leak of `MVKFences` and `MVKSemaphores` when
|
||||
a swapchain image is acquired more than it is presented.
|
||||
- Ensure Vulkan public symbols are not stripped from the library when
|
||||
statically linked to an app that calls all Vulkan functions dynamically.
|
||||
- Per Vulkan 1.2 spec, support calling `vkGetInstanceProcAddr()` with a
|
||||
null instance, when `vkGetInstanceProcAddr` itself is the function name.
|
||||
|
||||
|
||||
|
||||
|
@ -449,7 +449,6 @@ void MVKInstance::initProcAddrs() {
|
||||
ADD_INST_ENTRY_POINT(vkGetPhysicalDeviceProperties);
|
||||
ADD_INST_ENTRY_POINT(vkGetPhysicalDeviceQueueFamilyProperties);
|
||||
ADD_INST_ENTRY_POINT(vkGetPhysicalDeviceMemoryProperties);
|
||||
ADD_INST_ENTRY_POINT(vkGetInstanceProcAddr);
|
||||
ADD_INST_ENTRY_POINT(vkCreateDevice);
|
||||
ADD_INST_ENTRY_POINT(vkEnumerateDeviceExtensionProperties);
|
||||
ADD_INST_ENTRY_POINT(vkEnumerateDeviceLayerProperties);
|
||||
|
@ -141,7 +141,7 @@ bool MVKExtensionList::isEnabled(const char* extnName) const {
|
||||
const MVKExtension* extnAry = &extensionArray;
|
||||
for (uint32_t extnIdx = 0; extnIdx < extnCnt; extnIdx++) {
|
||||
const MVKExtension& extn = extnAry[extnIdx];
|
||||
if ( strcmp(extn.pProperties->extensionName, extnName) == 0 ) {
|
||||
if (mvkStringsAreEqual(extn.pProperties->extensionName, extnName)) {
|
||||
return extn.enabled;
|
||||
}
|
||||
}
|
||||
@ -153,7 +153,7 @@ void MVKExtensionList::enable(const char* extnName) {
|
||||
MVKExtension* extnAry = &extensionArray;
|
||||
for (uint32_t extnIdx = 0; extnIdx < extnCnt; extnIdx++) {
|
||||
MVKExtension& extn = extnAry[extnIdx];
|
||||
if ( strcmp(extn.pProperties->extensionName, extnName) == 0 ) {
|
||||
if (mvkStringsAreEqual(extn.pProperties->extensionName, extnName)) {
|
||||
extn.enabled = true;
|
||||
return;
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ MVKLayer* MVKLayerManager::getLayerNamed(const char* pLayerName) {
|
||||
uint32_t layCnt = (uint32_t)_layers.size();
|
||||
for (uint32_t layIdx = 0; layIdx < layCnt; layIdx++) {
|
||||
MVKLayer* pLayer = &_layers[layIdx];
|
||||
if ( strcmp(pLayer->getName(), pLayerName) == 0 ) { return pLayer; }
|
||||
if (mvkStringsAreEqual(pLayer->getName(), pLayerName)) { return pLayer; }
|
||||
}
|
||||
return VK_NULL_HANDLE;
|
||||
}
|
||||
|
@ -549,6 +549,15 @@ bool mvkAreEqual(const T* pV1, const T* pV2, size_t count = 1) {
|
||||
return (pV1 && pV2) ? (memcmp(pV1, pV2, sizeof(T) * count) == 0) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* If both pV1 and pV2 are not null, returns whether the contents of the two strings are equal,
|
||||
* otherwise returns false. This functionality is different than the char version of mvkAreEqual(),
|
||||
* which works on individual chars or char arrays, not strings.
|
||||
*/
|
||||
static inline bool mvkStringsAreEqual(const char* pV1, const char* pV2, size_t count = 1) {
|
||||
return (pV1 && pV2) ? (strcmp(pV1, pV2) == 0) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value referenced by the destination pointer with the value referenced by
|
||||
* the source pointer, and returns whether the value was set.
|
||||
|
@ -284,17 +284,18 @@ MVK_PUBLIC_VULKAN_SYMBOL PFN_vkVoidFunction vkGetInstanceProcAddr(
|
||||
VkInstance instance,
|
||||
const char* pName) {
|
||||
|
||||
MVKTraceVulkanCallStart();
|
||||
|
||||
// Handle the special platform functions where the instance parameter may be NULL.
|
||||
PFN_vkVoidFunction func = nullptr;
|
||||
if (strcmp(pName, "vkCreateInstance") == 0) {
|
||||
MVKTraceVulkanCallStart();
|
||||
if (mvkStringsAreEqual(pName, "vkGetInstanceProcAddr")) {
|
||||
func = (PFN_vkVoidFunction)vkGetInstanceProcAddr;
|
||||
} else if (mvkStringsAreEqual(pName, "vkCreateInstance")) {
|
||||
func = (PFN_vkVoidFunction)vkCreateInstance;
|
||||
} else if (strcmp(pName, "vkEnumerateInstanceExtensionProperties") == 0) {
|
||||
} else if (mvkStringsAreEqual(pName, "vkEnumerateInstanceExtensionProperties")) {
|
||||
func = (PFN_vkVoidFunction)vkEnumerateInstanceExtensionProperties;
|
||||
} else if (strcmp(pName, "vkEnumerateInstanceLayerProperties") == 0) {
|
||||
} else if (mvkStringsAreEqual(pName, "vkEnumerateInstanceLayerProperties")) {
|
||||
func = (PFN_vkVoidFunction)vkEnumerateInstanceLayerProperties;
|
||||
} else if (strcmp(pName, "vkEnumerateInstanceVersion") == 0) {
|
||||
} else if (mvkStringsAreEqual(pName, "vkEnumerateInstanceVersion")) {
|
||||
func = (PFN_vkVoidFunction)vkEnumerateInstanceVersion;
|
||||
} else if (instance) {
|
||||
MVKInstance* mvkInst = MVKInstance::getMVKInstance(instance);
|
||||
@ -3419,9 +3420,9 @@ MVK_PUBLIC_SYMBOL PFN_vkVoidFunction vk_icdGetInstanceProcAddr(
|
||||
MVKTraceVulkanCallStart();
|
||||
|
||||
PFN_vkVoidFunction func = nullptr;
|
||||
if (strcmp(pName, "vk_icdNegotiateLoaderICDInterfaceVersion") == 0) {
|
||||
if (mvkStringsAreEqual(pName, "vk_icdNegotiateLoaderICDInterfaceVersion")) {
|
||||
func = (PFN_vkVoidFunction)vk_icdNegotiateLoaderICDInterfaceVersion;
|
||||
} else if (strcmp(pName, "vk_icdGetPhysicalDeviceProcAddr") == 0) {
|
||||
} else if (mvkStringsAreEqual(pName, "vk_icdGetPhysicalDeviceProcAddr")) {
|
||||
func = (PFN_vkVoidFunction)vk_icdGetPhysicalDeviceProcAddr;
|
||||
} else {
|
||||
func = vkGetInstanceProcAddr(instance, pName);
|
||||
|
Loading…
x
Reference in New Issue
Block a user