MoltenVK driver calls the wrong functions for some Vulkan function calls - vulkan

I'm trying to use Vulkan on MacOS, with the eventual goal of making a cross platform program. My program worked when I statically linked MoltenVK (with the vulkan headers copied into it).
My current setup statically links vulkan.framework, and uses an ICD to load libMoltenVK.dylib. This initially appeared to work: in the logs, I can see "INFO: Found ICD manifest file [expected path to my manifest file]". All the extensions I expect are then found and listed, including VK_KHR_surface. I enable it when I create my VkInstance.
I can call various vulkan functions successfully, including vkCreateMacOSSurfaceMVK. However, when I try to call vkGetPhysicalDeviceSurfaceCapabilitiesKHR, my program crashes.
With no validation layers, it seems like vulkan loads the wrong function: the next symbol in the call stack is vkCreateQueryPool instead of the expected vkGetPhysicalDeviceSurfaceCapabilitiesKHR, and MoltenVK prints [***MoltenVK ERROR***] VK_ERROR_INITIALIZATION_FAILED: vkCreateQueryPool: Unsupported query pool type: -1094795586. The program crashes on the next vulkan call, which happens to be vkGetPhysicalDeviceSurfaceFormatsKHR, but which actually calls into MVKDevice::destoryQueryPool.
With validation layers on, the program crashes on vkGetPhysicalDeviceSurfaceCapabilitiesKHR, which tries to call 0x0. There are no errors printed about validation failing for any of them.
I tried turning on Dynamic Linker API usage/ Dynamic Library loads in Xcode's scheme editor, but I didn't find the information they provided helpful.
Why would vulkan/dyld not hook up some functions correctly? How can I debug this?

You are actually using the Vulkan Loader, not an "ICD", to load libMoltenVK.dylib. libMoltenVK.dylib itself is considered an Installable Client Driver (ICD).
Are you using vkGetInstanceProcAddr() to get the function address of vkGetPhysicalDeviceSurfaceCapabilitiesKHR() ? The Vulkan Loader only exports the core (and some WSI) functions. You'll need to get the addresses of other extension functions with vkGetInstanceProcAddr().
See this code for an example of using GIPA. Search for "vkGetPhysicalDeviceSurfaceCapabilitiesKHR". vulkaninfo calls this extension successfully on MacOS.
I suspect that the MoltenVK lib exports this extension function directly, which is why it worked when you statically linked MoltenVK. Also, when using the Vulkan loader, you should not be linking the MoltenVK library to your application. The Vulkan loader loads it for you.

Related

How to load .dll file which returns assembly in Objective-C?

Is it possible to load .dll or static library(.a) file programmatially which returns assembly in objective-c for mac os x?
How assembly loading & unloading done in objective-c for mac osx?
I'll admit that even after reading Microsoft's documentation on the Assembly Class, it's still not clear to me what an Assembly is. They say:
Represents an assembly, which is a reusable, versionable, and self-describing building block of a common language runtime application.
The "reusable, versionable and self-describing" part sounds like a framework.
If indeed that's what you want to load, then you have a number of options. Your best best is to just link against the framework. The OS will automatically load it for you when your app starts up.
If you want to load it manually, there are a number of ways to do that. If it's a framework you're going to ship with your application, then you can simply put it into your app bundle's Frameworks folder, and then use:
NSBundle* frameworkBundle = [NSBundle bundleWithIdentifier:#"<your bundle's identifier>"];
if (frameworkBundle != NULL)
{
[frameworkBundle load];
}
You can also use dlopen() (see man dlopen(3) for details). This will load a dynamic library into your process space.
I have never had a reason to use dlopen() directly. I usually just link against the framework. On those rare occasions where my app may need to run on an older OS that doesn't support the framework, I have used the manual loading described above via NSBundle.

Interacting with a specific COM DLL

I'm trying to interact with a .dll which will allow me to receive information from a variety of devices (Eye Gaze to be specific). The .dll is called ETUDriver and can be found at http://www.sis.uta.fi/~csolsp/projects.php however it does not come with an accompanying .h file.
I am struggling to actually load, interact and invoke functions from the .dll. A manual is supplied but it is of no help whatsoever with regards to actually setting up the code to start it off. There are three accompanying example apps (with source code) but only two of these work and one of which is in C# so is not helpful. The one that works however loads up the .dll via MFC and this is not a viable option with my code (which is intended to be used with many other projects and as such can't enforce MFC or any other libraries that are not as standard to projects).
Essentially, within the .dll is a series of classes which I need to create within my code and invoke the relevant functions of that class.
I've tried to use HRESULT hr = CoInitialize(NULL);
hr = CoCreateInstance(__uuidof(ETUDSink), NULL, CLSCTX_INPROC, __uuidof(IETUDSink), (LPVOID*)&pETUDSink);
if(pETUDSink)
{
pETUDSink->Start();
} however it always returns an error saying that the class is not registered. I can't use MFC to call the relevant .rgs file and am completely stuck on how to get this to work otherwise.
Is there a given format to doing this that I am unaware of and has anyone had experience in using the ETUDriver (or is able to get it working in C++ without use of MFC)?
Thank you for any help you can provide on this subject :)
I am not familiar with the specific DLL in question, but it sounds like you did not register the DLL on the target machine. You can do this by running regsvr32.exe or by calling the DLL's exported DllRegisterServer function or by using side-by-side assemblies. You need to do register the DLL on each machine that needs to leverage the COM functionality within it, so when you distribute your application, make sure that your installer registers the DLL if you go the regsvr32.exe route.
You can use the #import directive in Microsoft Visual C++ to load the information contained within the DLL without using a header file or rewriting it yourself based on documentation.

difference between dynamic loading and dynamic linking?

Routine is not loaded until it is called. All routines are kept on disk in a re-locatable load format. The main program is loaded into memory & is executed. This is called Dynamic Linking.
Why this is called Dynamic Linking? Shouldn't it be Dynamic Loading because Routine is not loaded until it is called in dynamic loading where as in dynamic linking, Linking postponed until execution time.
This answer assumes that you know basic Linux command.
In Linux, there are two types of libraries: static or shared.
In order to call functions in a static library you need to statically link the library into your executable, resulting in a static binary.
While to call functions in a shared library, you have two options.
First option is dynamic linking, which is commonly used - when compiling your executable you must specify the shared library your program uses, otherwise it won't even compile. When your program starts it's the system's job to open these libraries, which can be listed using the ldd command.
The other option is dynamic loading - when your program runs, it's the program's job to open that library. Such programs are usually linked with libdl, which provides the ability to open a shared library.
Excerpt from Wikipedia:
Dynamic loading is a mechanism by which a computer program can, at run
time, load a library (or other binary) into memory, retrieve the
addresses of functions and variables contained in the library, execute
those functions or access those variables, and unload the library from
memory. It is one of the 3 mechanisms by which a computer program can
use some other software; the other two are static linking and dynamic
linking. Unlike static linking and dynamic linking, dynamic loading
allows a computer program to start up in the absence of these
libraries, to discover available libraries, and to potentially gain
additional functionality.
If you are still in confusion, first read this awesome article: Anatomy of Linux dynamic libraries and build the dynamic loading example to get a feel of it, then come back to this answer.
Here is my output of ldd ./dl:
linux-vdso.so.1 => (0x00007fffe6b94000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f400f1e0000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f400ee10000)
/lib64/ld-linux-x86-64.so.2 (0x00007f400f400000)
As you can see, dl is a dynamic executable that depends on libdl, which is dynamically linked by ld.so, the Linux dynamic linker when you run dl. Same is true for the other 3 libraries in the list.
libm doesn't show in this list, because it is used as a dynamically loaded library. It isn't loaded until ld is asked to load it.
Dynamic loading means loading the library (or any other binary for that matter) into the memory during load or run-time.
Dynamic loading can be imagined to be similar to plugins , that is an exe can actually execute before the dynamic loading happens(The dynamic loading for example can be created using LoadLibrary call in C or C++)
Dynamic linking refers to the linking that is done during load or run-time and not when the exe is created.
In case of dynamic linking the linker while creating the exe does minimal work.For the dynamic linker to work it actually has to load the libraries too.Hence it's also called linking loader.
Hence the sentences you refer may make sense but they are still quite ambiguous as we cannot infer the context in which it is referring in.Can you inform us where did you find these lines and at what context is the author talking about?
Dynamic loading refers to mapping (or less often copying) an executable or library into a process's memory after it has started. Dynamic linking refers to resolving symbols - associating their names with addresses or offsets - after compile time.
Here is the link to the full answer by Jeff Darcy at quora
http://www.quora.com/Systems-Programming/What-is-the-exact-difference-between-Dynamic-loading-and-dynamic-linking/answer/Jeff-Darcy
I am also reading the "dinosaur book" and was confused with the loading and linking concept. Here is my understanding:
Both dynamic loading and linking happen at runtime, and load whatever they need into memory.
The key difference is that dynamic loading checks if the routine was loaded by the loader while dynamic linking checks if the routine is in the memory.
Therefore, for dynamic linking, there is only one copy of the library code in the memory, which may be not true for dynamic loading. That's why dynamic linking needs OS support to check the memory of other processes. This feature is very important for language subroutine libraries, which are shared by many programs.
Dynamic linker is a run time program that loads and binds all of the dynamic dependencies of a program before starting to execute that program. Dynamic linker will find what dynamic libraries a program requires, what libraries those libraries require (and so on), then it will load all those libraries and make sure that all references to functions then correctly point to the right place. For example, even the most basic “hello world” program will usually require the C library to display the output and so the dynamic linker will load the C library before loading the hello world program and will make sure that any calls to printf() go to the right code.
Dynamic Loading: Load routine in main memory on call.
Dynamic Linking: Load routine in main memory during execution time,if call happens before execution time it is postponed till execution time.
Dynamic loading does not require special support from Operating system, it is the responsibility of the programmer to check whether the routine that is to be loaded does not exist in main memory.
Dynamic Linking requires special support from operating system, the routine loaded through dynamic linking can be shared across various processes.
Routine is not loaded until it is called. All routines are kept on disk in a re-locatable load format. The main program is loaded into memory & is executed. This is called Dynamic Linking.
The statement is incomplete."The main program is loaded into main memory & is executed." does not specify when the program is loaded.
If we consider that it is loaded on call as 1st statement specifies then its Dynamic Loading
We use dynamic loading to achieve better space utilization
With dynamic loading a program is not loaded until it is called.All routines are kept on a disk in a relocatable load format.The main program is loaded into memory and is executed.
When a routine needs to call another routine, the calling routine first checks to see whether has been loaded.If not , the relocatable linking loader is called to load the desired routine into memory and update program's address tables to reflect this change.Then control is passed to newly loaded routine
Advantages
An unused routine is never loaded .This is most useful when the program code
is large where infrequently occurring cases are needed to handle such as
error routines.In this case although the program code is large ,used code
will be small.
Dynamic loading doesn't need special support from O.S.It is the
responsibility of user to design their program to take advantage of
method.However, O.S can provide libraries to help the programmer
There are two types of Linking Static And Dynamic ,when output file is executed without any dependencies(files=Library) at run time this type of linking is called Static where as Dynamic is of Two types 1.Dynamic Loading Linking 2.Dynamic Runtime Linking.These are Described Below
Dynamic linking refers to linking while runtime where library files are brought to primary memory and linked ..(Irrespective of Function call these are linked).
Dynamic Runtime Linking refers to linking when required,that means whenever there is a function call happening at that time linking During runtime..Not all Functions are linked and this differs in Code writing .

Running arbitrary code at runtime

I know this is an odd question, but I'm wondering if this is possible. Is there any method by which code (which would be typed by a user) could be run during runtime? For example, suppose I would allow the user to type in some Core Graphics drawing code. I would want this code to be run in a drawRect method of my preview pane.
So what I would have to do would be to convert this group of strings into actual runtime code.
Is this even possible, or am I just wasting my time?
I see a few solutions:
Create a language of your own, and parse it in-application
If on mac, you could theoretically, create a function stub from what they enter in, and use GCC shipped with the application to compile the code at runtime into a dylib, and then use dylib functions to run the function you created.
On a Mac, you can have your app send text to the compiler (several come with Xcode), have the code compiled, and run the compiled result as a slave app (controlled via a socket, for instance, and copying the preview pane image pixels back via a pipe). If needed you could convert the source code text using some sort of preprocessor and wrap it in your own run-time shell.
Alternatively you could write or port a C language interpreter (there are several open source interpreters for various subsets of C), and plug Core Graphics library calls into the C interpreter's parser and run-time engine.
I do not know of a full interpreter for Objective C.

Cocoa/Objective-C Plugins Collisions

My application has a plugin system that allows my users to write their own plugins that get loaded at runtime. Usually this is fine but in some cases two plugins use the same libraries that will cause a collision between those two.
Example:
Plugin A wants to use TouchJSON for working with JSON and thus the creator adds the TouchJSON code to the plugin source and it gets compiled and linked into the plugin binary. Later Plugin B also wants to use that same library and does exactly the same. Now when my app loads these two different plugins it detects this and spits out an warning like this:
Class CJSONScanner is implemented in
both [path_to_plugin_a] and
[path_to_plugin_b]. One of the two
will be used. Which one is undefined.
Since my app just loads plugins and makes sure they conform to a certain protocol I have no control over which plugins are loaded and if two or more use the same library.
As long as both plugins use the exact same version of the library this will probably work but as soon as the API changes in one plugin a bunch of problems will arise.
Is there anything I can do about this?
The bundle loading system provides no mean to pacifically resolve name conflicts. In fact, we're told to ensure ourselves that the problem doesn't happen, rather than what to do if it happens. (Obviously, in your case, that's not possible).
You could file a bug report with this issue.
If this is absolutely critical to your application, you may want to have bundles live in separate processes and use some kind of IPC, possibly NSDistantObject, to pass the data from your program to the plugin hosts. However, I'm fairly sure this is a bag of hurt, so if you don't have very clearly-defined interfaces that allow for distribution into different processes, it might be quite an undertaking.
In a single-process model, the only way to deal with this is to ensure that the shared code (more precisely, the shared Objective-C classes) is loaded once. There are two ways to do this:
Put the shared code in a framework.
Put the shared code in a loadable bundle, and load the bundle when the plug-in is loaded if the relevant classes aren’t already available (check using NSClassFromString()). The client code would also have to use NSClassFromString() rather than referring to classes directly.
Of course, if you aren’t in control of the plug-ins you can’t enforce either of these schemes. The best you can do is provide appropriate guidelines and possibly infrastructure; for instance, in the second case the loading could be handled by the application, perhaps by specifying a class to check for and the name of an embedded bundle to load if it isn’t available in the plug-in’s Info.plist.