Mettre à jour le SDK DirectX

Quand j'ai rejoint Bitsquid il y a un mois, quelqu'un a mentionné vouloir mettre à jour le SDK DirectX pour bénéficier de certaines améliorations, mais que nous avions des dépendances qui posaient problème. Je me suis naïvement portée volontaire pour enquêter. J'ai finalement désentortillé tout ce bazar au cours des dix derniers jours, et réussi la mise à jour. Le but ici est de partager ce que j'ai trouvé pour économiser du temps aux prochains malheureux qui tentent la même chose. À noter: les liens dans cet article sont en anglais.

Étape 1: Exploration

Premier arrêt: l'article dédié sur MSDN. J'avais entendu dire que le SDK DirectX était maintenant inclus dans le SDK Windows, mais n'étais pas certaine de ce que ça impliquait. Cet article résume le sujet. Avec un collègue, nous avons parcouru la liste, et noté ce que nous utilisions ou non. Au final, les seuls composants problématiques étaient XInput, XAudio2, et D3DX9Mesh. La majeure partie du code avait déjà été convertie pour ne plus utiliser D3DX, ce qui nous a fait gagner du temps!

Mais quelques petites choses restaient à clarifier. Notre configuration minimale est toujours Windows 7. Est-ce que ça allait marcher? Heureusement, MSDN avait la réponse. Cet article mentionne que le SDK Windows 8.X est disponible sur Windows 7. Il y a plus de détails sur cette page et cette page.

Étape 2: Bon bah on essaie

J'ai changé les références dans nos fichiers de génération de projets, pour pointer vers le SDK Windows. J'ai également ajouté le SDK DirectX de Juin 2010, mais uniquement pour XAudio2 et D3DX9Mesh (pour XInput, voir plus bas). Après avoir résolu les quelques erreurs de compilation, les choses semblaient fonctionner... jusqu'à un crash à l'exécution lié à ID3D11ShaderReflection. De quoi?

Étape 3: GUIDs et #define magique

J'avais à tort supposé que les erreurs de linkage causées par les changements de références venaient de DX9, parce que j'avais lu trop vite. Linker avec (l'ancienne) dxguid.lib les avait fait disparaître, et je n'y avais pas fait plus attention. Mais une grande part de DirectX fonctionne à base de GUIDs, des identifiants uniques en dur dans le code. En déboguant, j'ai remarqué que IID_ID3D11ShaderReflection n'avait pas la bonne valeur, celle du SDK Windows, ce qui causait le crash. J'ai perdu une journée à la chasse au dahu, à tenter de trouver d'où le changement venait, pensant que c'était une #include incorrecte.

Mais par défaut, ces GUIDs sont des variables extern, et reçoivent leur valeur depuis un fichier .lib. Et je linkais avec une vieille version. Mystère résolu! La solution est de #define INITGUID avant d'inclure windows.h. Mes remerciements aux forums Ogre3D qui m'ont menée à la page dont j'avais besoin, puisqu'ils avaient rencontré le même problème. À ce stade tout marchait bien, hormis les machines de build automatique.

Étape 4: d3dcompiler

Le premier problème n'était pas tout jeune. Nous avions jusque là, sans nous en rendre compte, supposé que la DLL pour d3dcompiler était présente dans System32! Vu que System32 est dans le chemin de recherche par défaut des DLLs, cette erreur est facile à manquer, tout particulièrement quand l'installation du SDK DirectX est un prérequis pour les développeurs. Nous dépendions à présent d'une version plus récente, en théorie incluse dans le SDK Windows. Pourtant ça ne marchait pas... car nous n'avions pas de phase d'installation pour DirectX. Je suis retournée dans les fichiers de génération des projets, et ai ajouté une phase de copie pour cette DLL. Pourtant, les machines de build râlaient toujours.

Étape 5: XInput

XInput est disponible en plusieurs versions dans le SDK Windows. 1.4 est la plus récente au moment où j'écris, et est réservée à Windows 8. Pour utiliser XInput sous Windows 7, il faut utiliser la version 9.1.0. La première étape est de s'assurer que la define magique _WIN32_WINNT reçoit la bonne valeur (voir plus haut sur la page en lien). Il faut aussi linker explicitement avec XInput9_1_0.lib et non XInput.lib, sans quoi Windows 7 crashera à l'exécution en tentant de lire XInput1_4.dll, qui n'existe pas sous Windows 7. Dans mon cas, c'est ce qui cassait les tests automatiques sur des machines Windows 7, mais marchait parfaitement sur ma machine Windows 8.

Étape 6: Champagne?

Pour le moment cela semble être tout, mais l'équipe rendering n'a pas encore commencé à pousser les limites. On verra bien ce qui casse quand ils commencent à jouer avec :)

J'espère que cela vous économise un peu de temps si vous faites une mise à jour similaire, ou vous a convaincu de tenter le coup si vous hésitiez.