2017-10-14 12 views
4

J'essaie de créer un cadre qui fonctionne avec METAL Api (iOS). Je suis assez nouveau sur cette plateforme et j'aimerais savoir comment construire le framework pour travailler avec les fichiers .metal (je construis une librairie statique, pas dynamique). Devraient-ils faire partie du fichier .a ou en tant que fichiers de ressources dans le bundle de framework? Ou y a-t-il un autre moyen de le faire? Merci.Métal fichier dans le cadre d'un environnement iOS

Mise à jour: Pour ceux qui s'attaquent - je fini par la suite de l'option proposée de 1 de warrenm - le fichier converti en une chaîne .Complexe métallique et d'appeler newLibraryWithSource:options:error:. Bien que ce ne soit pas le meilleur en termes de performances, il m'a permis d'expédier un seul fichier de structure, sans ressources supplémentaires à importer. Cela pourrait être utile à quiconque crée un framework utilisant Metal, ARKit, etc. avec des fichiers shader.

+0

Content que vous ayez trouvé une approche qui vous convient. Pour la postérité, j'ai commenté ci-dessous et partagé un projet de preuve de concept qui vous permet de conserver l'avantage de la pré-compilation des shaders tout en n'envoyant qu'un seul fichier. Si je faisais cela en production, c'est presque certainement l'approche que je prendrais. – warrenm

Répondre

7

Il existe de nombreuses façons de fournir des shaders Metal avec une bibliothèque statique, toutes avec des compromis différents. Je vais essayer de les énumérer ici.

1) Transformez vos fichiers .metal en chaînes statiques qui sont cuites dans votre bibliothèque statique.

Ceci est probablement la pire option. L'idée est de prétraiter votre code Metal Shader en chaînes qui sont incluses en tant que littéraux de chaîne dans votre bibliothèque statique. Vous utiliserez ensuite l'API newLibraryWithSource:options:error: (ou son frère ou sa sœur asynchrone) pour transformer la source en MTLLibrary et récupérer les fonctions. Cela vous oblige à concevoir un processus pour effectuer la conversion .metal -to-string, et vous perdez l'avantage de la précompilation des shaders, ce qui rend l'application résultante plus lente.

2) fichiers à côté de votre bateau .Complexe métallique bibliothèque statique et exigent que les utilisateurs bibliothèque pour les ajouter à leur application cible

Tout bien considéré, c'est une option décente, mais il place un fardeau plus lourd sur vos utilisateurs et expose votre source Metal Shader (si c'est un problème). Code dans votre bibliothèque statique peut utiliser la "bibliothèque par défaut" (newDefaultLibrary), puisque le code sera automatiquement compilé par Xcode dans default.metallib de l'application, qui est incorporée dans le regroupement d'applications en tant que ressource.

3) Expédier un fichier .metallib à côté de votre bibliothèque statique

Ceci est un bon compromis entre la facilité d'utilisation, les performances et la sécurité (car il ne pas exposer votre source de shaders, que son IR). Fondamentalement, vous pouvez créer une cible "Metal Library" dans votre projet, dans laquelle vous mettez votre code shader. Cela va produire un fichier .metallib, que vous pouvez envoyer avec votre bibliothèque statique et faire en sorte que votre utilisateur soit incorporé en tant que ressource dans la cible de l'application. Votre bibliothèque statique peut charger le .metallib à l'exécution avec l'API ou newLibraryWithURL:error:. Étant donné que vos shaders seront précompilés, la création de bibliothèques sera plus rapide et vous conserverez l'avantage des diagnostics de compilation.

+0

Merci pour votre réponse détaillée. Juste pour clarifier les choses - si je ne veux pas expédier un autre fichier à mes utilisateurs - la première solution est-elle unique? – DocForNoc

+0

Je suppose que vous pourriez intégrer la bibliothèque précompilée en prenant les octets d'un fichier métallib et en les écrivant comme un tableau littéral d'octets dans votre source de bibliothèque statique. Cela répondrait à l'exigence d'un fichier tout en offrant les avantages de la précompilation. – warrenm

+0

Je viens de tester cette dernière approche et cela fonctionne. Voici un projet de preuve de concept qui fait tout: construire un '.metallib', le cuire dans un fichier d'en-tête et créer une «MTLLibrary' à l'exécution à partir de laquelle les pipelines peuvent être créés: https://www.dropbox.com/s/8w30r1gyutj9twc/EmbeddedKernelSample.zip?dl=0. Ce n'est en aucun cas prêt pour la production, mais il devrait bien illustrer l'approche. – warrenm