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
|
#endif
|
||||||
|
|
||||||
/** Directive to identify public symbols. */
|
/** 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. */
|
/** Directive to make a public alias of another symbol. */
|
||||||
#define MVK_PUBLIC_ALIAS(ALIAS, TARGET) asm(".globl _" #ALIAS "\n\t_" #ALIAS " = _" #TARGET)
|
#define MVK_PUBLIC_ALIAS(ALIAS, TARGET) asm(".globl _" #ALIAS "\n\t_" #ALIAS " = _" #TARGET)
|
||||||
|
@ -22,6 +22,10 @@ Released TBD
|
|||||||
`MTLCommandBuffer` is finished using it.
|
`MTLCommandBuffer` is finished using it.
|
||||||
- Fix memory leak of `MVKFences` and `MVKSemaphores` when
|
- Fix memory leak of `MVKFences` and `MVKSemaphores` when
|
||||||
a swapchain image is acquired more than it is presented.
|
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(vkGetPhysicalDeviceProperties);
|
||||||
ADD_INST_ENTRY_POINT(vkGetPhysicalDeviceQueueFamilyProperties);
|
ADD_INST_ENTRY_POINT(vkGetPhysicalDeviceQueueFamilyProperties);
|
||||||
ADD_INST_ENTRY_POINT(vkGetPhysicalDeviceMemoryProperties);
|
ADD_INST_ENTRY_POINT(vkGetPhysicalDeviceMemoryProperties);
|
||||||
ADD_INST_ENTRY_POINT(vkGetInstanceProcAddr);
|
|
||||||
ADD_INST_ENTRY_POINT(vkCreateDevice);
|
ADD_INST_ENTRY_POINT(vkCreateDevice);
|
||||||
ADD_INST_ENTRY_POINT(vkEnumerateDeviceExtensionProperties);
|
ADD_INST_ENTRY_POINT(vkEnumerateDeviceExtensionProperties);
|
||||||
ADD_INST_ENTRY_POINT(vkEnumerateDeviceLayerProperties);
|
ADD_INST_ENTRY_POINT(vkEnumerateDeviceLayerProperties);
|
||||||
|
@ -141,7 +141,7 @@ bool MVKExtensionList::isEnabled(const char* extnName) const {
|
|||||||
const MVKExtension* extnAry = &extensionArray;
|
const MVKExtension* extnAry = &extensionArray;
|
||||||
for (uint32_t extnIdx = 0; extnIdx < extnCnt; extnIdx++) {
|
for (uint32_t extnIdx = 0; extnIdx < extnCnt; extnIdx++) {
|
||||||
const MVKExtension& extn = extnAry[extnIdx];
|
const MVKExtension& extn = extnAry[extnIdx];
|
||||||
if ( strcmp(extn.pProperties->extensionName, extnName) == 0 ) {
|
if (mvkStringsAreEqual(extn.pProperties->extensionName, extnName)) {
|
||||||
return extn.enabled;
|
return extn.enabled;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -153,7 +153,7 @@ void MVKExtensionList::enable(const char* extnName) {
|
|||||||
MVKExtension* extnAry = &extensionArray;
|
MVKExtension* extnAry = &extensionArray;
|
||||||
for (uint32_t extnIdx = 0; extnIdx < extnCnt; extnIdx++) {
|
for (uint32_t extnIdx = 0; extnIdx < extnCnt; extnIdx++) {
|
||||||
MVKExtension& extn = extnAry[extnIdx];
|
MVKExtension& extn = extnAry[extnIdx];
|
||||||
if ( strcmp(extn.pProperties->extensionName, extnName) == 0 ) {
|
if (mvkStringsAreEqual(extn.pProperties->extensionName, extnName)) {
|
||||||
extn.enabled = true;
|
extn.enabled = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,7 @@ MVKLayer* MVKLayerManager::getLayerNamed(const char* pLayerName) {
|
|||||||
uint32_t layCnt = (uint32_t)_layers.size();
|
uint32_t layCnt = (uint32_t)_layers.size();
|
||||||
for (uint32_t layIdx = 0; layIdx < layCnt; layIdx++) {
|
for (uint32_t layIdx = 0; layIdx < layCnt; layIdx++) {
|
||||||
MVKLayer* pLayer = &_layers[layIdx];
|
MVKLayer* pLayer = &_layers[layIdx];
|
||||||
if ( strcmp(pLayer->getName(), pLayerName) == 0 ) { return pLayer; }
|
if (mvkStringsAreEqual(pLayer->getName(), pLayerName)) { return pLayer; }
|
||||||
}
|
}
|
||||||
return VK_NULL_HANDLE;
|
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;
|
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
|
* Sets the value referenced by the destination pointer with the value referenced by
|
||||||
* the source pointer, and returns whether the value was set.
|
* the source pointer, and returns whether the value was set.
|
||||||
|
@ -284,17 +284,18 @@ MVK_PUBLIC_VULKAN_SYMBOL PFN_vkVoidFunction vkGetInstanceProcAddr(
|
|||||||
VkInstance instance,
|
VkInstance instance,
|
||||||
const char* pName) {
|
const char* pName) {
|
||||||
|
|
||||||
MVKTraceVulkanCallStart();
|
|
||||||
|
|
||||||
// Handle the special platform functions where the instance parameter may be NULL.
|
// Handle the special platform functions where the instance parameter may be NULL.
|
||||||
PFN_vkVoidFunction func = nullptr;
|
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;
|
func = (PFN_vkVoidFunction)vkCreateInstance;
|
||||||
} else if (strcmp(pName, "vkEnumerateInstanceExtensionProperties") == 0) {
|
} else if (mvkStringsAreEqual(pName, "vkEnumerateInstanceExtensionProperties")) {
|
||||||
func = (PFN_vkVoidFunction)vkEnumerateInstanceExtensionProperties;
|
func = (PFN_vkVoidFunction)vkEnumerateInstanceExtensionProperties;
|
||||||
} else if (strcmp(pName, "vkEnumerateInstanceLayerProperties") == 0) {
|
} else if (mvkStringsAreEqual(pName, "vkEnumerateInstanceLayerProperties")) {
|
||||||
func = (PFN_vkVoidFunction)vkEnumerateInstanceLayerProperties;
|
func = (PFN_vkVoidFunction)vkEnumerateInstanceLayerProperties;
|
||||||
} else if (strcmp(pName, "vkEnumerateInstanceVersion") == 0) {
|
} else if (mvkStringsAreEqual(pName, "vkEnumerateInstanceVersion")) {
|
||||||
func = (PFN_vkVoidFunction)vkEnumerateInstanceVersion;
|
func = (PFN_vkVoidFunction)vkEnumerateInstanceVersion;
|
||||||
} else if (instance) {
|
} else if (instance) {
|
||||||
MVKInstance* mvkInst = MVKInstance::getMVKInstance(instance);
|
MVKInstance* mvkInst = MVKInstance::getMVKInstance(instance);
|
||||||
@ -3419,9 +3420,9 @@ MVK_PUBLIC_SYMBOL PFN_vkVoidFunction vk_icdGetInstanceProcAddr(
|
|||||||
MVKTraceVulkanCallStart();
|
MVKTraceVulkanCallStart();
|
||||||
|
|
||||||
PFN_vkVoidFunction func = nullptr;
|
PFN_vkVoidFunction func = nullptr;
|
||||||
if (strcmp(pName, "vk_icdNegotiateLoaderICDInterfaceVersion") == 0) {
|
if (mvkStringsAreEqual(pName, "vk_icdNegotiateLoaderICDInterfaceVersion")) {
|
||||||
func = (PFN_vkVoidFunction)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;
|
func = (PFN_vkVoidFunction)vk_icdGetPhysicalDeviceProcAddr;
|
||||||
} else {
|
} else {
|
||||||
func = vkGetInstanceProcAddr(instance, pName);
|
func = vkGetInstanceProcAddr(instance, pName);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user