1 points par GN⁺ 2024-08-31 | 1 commentaires | Partager sur WhatsApp
  • La nouvelle PR #9312 de l’API GPU de SDL3 a été fusionnée le 29 août 2024 ; alors que SDL 3.0 approchait, l’approche basée sur Refresh a été proposée rapidement afin d’obtenir davantage de relectures
  • La proposition consistait à faire de Refresh, le composant graphique de MoonWorks, le candidat final pour l’API SDL_gpu ; il prenait en charge Vulkan et l’API graphique de la PS5, tandis que la prise en charge des deferred contexts D3D11 était en cours
  • La conception de l’API utilise un modèle de rendu moderne qui sépare les tâches en render pass, compute pass et copy pass, et les écritures sur les ressources peuvent être cyclées en interne afin d’éviter les dépendances entre frames
  • Côté shaders, la proposition initiale centrée sur la compilation hors ligne a été ajustée pour valider la prise en charge de la génération de shaders à l’exécution ; une structure acceptant des formats IR propres à chaque backend a été discutée afin que SDL lui-même n’englobe pas de compilateur de shaders
  • Juste après la fusion, d’autres ajustements ont suivi, notamment les noms de fonctions de l’API, les macros de configuration de build, l’UTF-8 BOM et la limite à 60 FPS du swapchain D3D12 ; des droits de commit ont été ajoutés pour thatcosmonaut

Point de départ de la PR et état de la fusion

  • La PR #9312 a commencé comme une nouvelle proposition d’API GPU destinée à faire relire rapidement SDL_gpu
    • L’objectif était d’obtenir rapidement « davantage de regards » alors que SDL 3.0 approchait
    • Elle a été fusionnée le 29 août 2024, après la confirmation It's merged
  • Juste après la fusion, il a été demandé de suspendre brièvement les changements afin de procéder aux revues et aux ajustements
    • L’état est ensuite passé à everything is merged, avec l’indication qu’il était de nouveau possible de fusionner les changements côté GPU
    • thatcosmonaut a été ajouté aux personnes disposant de droits de commit, car il était probable qu’il relise les incoming changes

Candidat d’API basé sur Refresh

  • Le cœur de la proposition consistait à faire de Refresh, le composant graphique de MoonWorks, le candidat final pour l’API SDL_gpu
    • MoonWorks a été présenté comme un projet plus proche d’un successeur de XNA que d’une réimplémentation de XNA à la manière de FNA
    • Refresh est similaire à FNA3D, mais vise des API modernes comme Vulkan
  • À ce moment-là, Refresh prenait en charge Vulkan et l’API graphique de la PS5
    • La prise en charge des deferred contexts D3D11 était en cours
    • Il a été présenté comme utilisé en production dans Samurai Gunn 2 sur PC et consoles
  • L’auteur de la PR a indiqué que thatcosmonaut serait le principal point de contact et que la core team FNA participerait également au travail

Conception de l’API et gestion des ressources

  • L’API est construite autour d’une API de rendu moderne centrée sur les deferred contexts
    • Les tâches sont réparties entre render pass, compute pass et copy pass
    • Le reste de l’API a été décrit comme une forme standard, proche d’appels de binding, de rendu et de compute dispatch
  • Toutes les opérations écrivant dans des ressources peuvent éviter les dépendances entre frames grâce au cycle
    • Les handles de ressources graphiques comme GpuBuffers jouent le rôle de conteneurs permettant de cycler les références aux ressources internes
    • Par la suite, le concept de cycle a été simplifié en booléen et les différents enums WriteOptions ont été supprimés
  • Au départ, plusieurs enums WriteOptions existaient en raison de problèmes de comportement de l’API de données liés au pilote D3D11 d’AMD
    • Il avait été expliqué que le fait que l’API de données D3D11 ne se comporte pas comme prévu sur AMD n’avait pas pu être entièrement contourné
    • Cette partie a ensuite été simplifiée et le comportement a été documenté dans le code

Discussions sur le système de shaders

  • La solution initiale pour les shaders était un script appelé shaderbuild.py
    • Il servait de façade aux outils de build de shaders hors ligne sur la machine cliente
    • Sa structure consistait à regrouper plusieurs formats pour les transmettre au backend de rendu approprié
  • Cette approche a été décrite comme ne bloquant pas la compilation de shaders en ligne
    • Il a été expliqué qu’une future source SDLSL pourrait être incluse dans le binaire et transformée immédiatement dans CreateShaderModule en bytecode requis par le backend
    • La possibilité d’autoriser la compilation en ligne sans casser l’API publique a été présentée comme un avantage
  • Des retours externes ont exprimé la crainte qu’une compilation purement hors ligne ne convienne pas à certains moteurs
    • Le fait de devoir installer Python, glslc et spirv-cross dans le PATH pouvait être contraignant pour les développeurs
    • Certains avis estimaient qu’un outil de compilation de shaders hors ligne sous forme de satellite library distincte pourrait être plus naturel dans l’écosystème SDL
  • Le système de shaders a ensuite été ajusté pour distinguer les shaders « raw » et « portable »
    • Le portage de FNA3D a été utilisé comme stress test pour la prise en charge de la génération de shaders à l’exécution
    • Une configuration a été mentionnée dans laquelle le MojoShader SPIR-V emitter transmet directement les shaders à Vulkan, tandis que les autres backends passent par SDL_shader, une bibliothèque séparée optionnelle, pour la conversion
    • L’objectif était que SDL lui-même n’ait pas à savoir ni à se soucier de l’origine des shaders

Backends et progression des tests

  • L’implémentation initiale basée sur Refresh a été considérée comme solide grâce à l’existence déjà effective d’un backend Vulkan
    • Certains estimaient que le backend Vulkan était très performant sur la base de Refresh 2.0
    • Le fait que le compute soit une fonctionnalité de premier ordre a aussi été signalé comme une différence importante par rapport au brouillon SDL_GPU existant
  • Plusieurs cas d’exécution de jeux réels ont été partagés entre fin mars et début avril 2024
    • Il a été expliqué qu’un état fonctionnel avait été atteint sans compilation de shaders hors ligne
    • Une révision actuelle permettant de démarrer Streets of Rage 4 a été partagée
    • Wizorb fonctionnait sur Metal
    • Celeste parvenait à entrer en jeu sur une grande partie de la trace database
  • Des fonctionnalités ont aussi été ajoutées en parallèle
    • Il a été mentionné que la prise en charge du hardware instancing serait ajoutée au prochain push
    • L’instancing et les occlusion queries ont ensuite été intégrés, avec l’indication que l’implémentation côté Metal restait à compléter

Problèmes de build, d’API et de plateformes remontés en revue

  • Une erreur de redéfinition des typedefs VkInstance et VkSurfaceKHR se produisait en raison de l’ordre des includes Vulkan
    • Une correction consistant à modifier l’ordre des includes entre les en-têtes Vulkan et SDL_vulkan.h dans SDL_gpu_vulkan.c a été proposée
    • Une autre correction a aussi été proposée pour faire taire un avertissement indiquant que suitableQueueFamilyIndex pouvait ne pas avoir été initialisé, en l’initialisant à 0
  • La nécessité de mettre à jour dynapi a également été signalée
    • Il a été indiqué qu’il suffisait d’exécuter gendynapi.py sous src/dynapi/ pour effectuer la mise à jour
    • Il a toutefois été précisé que l’exécution produisait de nombreux avertissements de documentation manquante
  • Une proposition suggérait de remplacer par size_t le type exprimant les tailles en octets dans les signatures des fonctions de l’API, mais la conclusion a été de conserver Uint32 pour l’API GPU
    • Un avis soulignait qu’il pourrait devenir difficile d’assurer simultanément la compatibilité 32/64 bits lorsque les tailles de buffers deviennent très grandes
    • La possibilité d’utiliser Uint64 a été évoquée comme alternative, mais l’avis final présenté était de conserver Uint32

Ajustements après la fusion

  • Après la fusion, plusieurs tweaks ont été effectués dans #10622
    • Il a été indiqué que les nouveaux noms de fonctions seraient fusionnés en premier afin que les utilisateurs de la bêta puissent les recevoir
    • Le problème dans lequel, dans la configuration de build, les macros de droite devaient être définies, comme SDL_GPU_VULKAN SDL_VIDEO_VULKAN et SDL_GPU_METAL SDL_VIDEO_METAL, a été corrigé dans #10622
    • Le problème d’UTF-8 BOM dans les fichiers source GPU a également été corrigé dans #10622
  • Côté D3D12, il a été constaté que D3D12_ClaimWindow() configurait le swapchain avec VSYNC, ce qui limitait testsprite à 60 FPS
    • Il a été expliqué que le workflow prévu consistait à créer le swapchain à l’étape de claim window avec des paramètres universellement pris en charge, SDR et VSYNC, puis à interroger la prise en charge avant d’appeler SetSwapchainParameters
    • Bien que le render driver appelle SetSwapchainParameters après le claim, la limite à 60 FPS persistait dans le driver D3D12 et restait à investiguer

1 commentaires

 
GN⁺ 2024-08-31
Commentaires sur Hacker News
  • SDL3 est encore en phase de préversion, mais la nouvelle API GPU a été fusionnée dans la branche principale, et les mainteneurs de SDL3 sont en train d’y apporter les derniers ajustements
    Si j’ai bien compris, l’idée centrale de cette nouvelle API GPU est de permettre d’écrire une seule fois le code graphique et les shaders, puis de les faire fonctionner sur plusieurs plateformes, consoles comprises, sans trop de complications. Avant, il fallait passer par Unity, Unreal ou une solution maison
    WebGPU/WGSL est aussi une pile graphique multiplateforme similaire, mais à ma connaissance personne n’a créé de backend pour consoles. À l’inverse, l’API GPU de SDL3 ne semble pas prendre en charge WebGPU comme backend pour le moment

    • Unreal/Unity ne sont pas les seules solutions. Il y a aussi bgfx(https://github.com/bkaradzic/bgfx), qui est assez populaire, et, si je ne me trompe pas, sokol gfx(https://github.com/floooh/sokol). Et bien sûr, il existe aussi beaucoup d’options moins connues
    • J’ai déjà intégré bgfx [1], qui permet aussi d’écrire une seule fois le code graphique et les shaders tout en prenant en charge les consoles, avec une pile SDL2 et Swift [2]. Même sans avoir jamais utilisé ce genre d’outil auparavant, l’expérience était plutôt bonne
      SDL3 introduit une abstraction des consoles, ce qui évite d’avoir besoin d’une dépendance supplémentaire pour l’API GPU, donc c’est prometteur. En plus, Godot prend officiellement en charge le Steam Deck, et j’espère qu’il prendra aussi en charge davantage de consoles à l’avenir. À ce sujet, Miguel de Icaza pousse l’adoption de Swift dans Godot et travaille aussi au portage de l’éditeur sur iPad avec SwiftUI. L’avancement [3] est intéressant
      [1] https://bkaradzic.github.io/bgfx/overview.html
      [2] https://github.com/bgbernovici/myndsmith
      [3] https://blog.la-terminal.net/xogot-code-editing/
    • Il vaut aussi la peine de noter que Godot dispose lui aussi de shaders multiplateformes. Le langage GDShader est fortement basé sur le langage de shaders OpenGL, sans en être une copie 1:1, et il est compilé selon la plateforme cible. En revanche, pour PS5 et Xbox, il faut collaborer avec des prestataires tiers. Quelqu’un a aussi publié des builds Nintendo pour les personnes ayant signé un NDA Nintendo
    • Mais pourquoi aurait-on besoin de l’API SDL plutôt que de gfx-rs / wgpu ? Je me demande s’il était vraiment nécessaire de créer encore autre chose
  • Il y a davantage de contexte ici : https://icculus.org/finger/flibitijibibo?date=2024-06-15&time=13-14-16

  • J’ai hâte de voir comment cette dynamique va s’installer. Au final, plus il y a de choix pour créer des moteurs de jeu et des applications custom, mieux c’est
    En ce moment, je creuse Vulkan en profondeur, et même si l’apprentissage est intéressant et riche en découvertes, la nature même de Vulkan donne l’impression d’avancer lentement. Si SDL3 avait existé quand j’ai commencé, je l’aurais probablement choisi sans hésiter, et j’aurais sans doute eu plus de résultats à montrer pour le temps investi

  • Il faudra voir avec le temps si cette API est réellement utilisable en pratique. La question de la synchronisation des ressources et de la manière de renommer les objets sera particulièrement importante
    Il faudra aussi voir si les performances seront meilleures que celles de WebGPU ou d’autres abstractions. Et il faudra observer si elle restera légère même lorsqu’il faudra contourner des bugs de pilotes
    Je suis aussi sceptique à propos du nouveau bytecode pour le langage de shading. Avec WebGPU, l’analyse des shaders à l’exécution n’a jamais été un sujet d’inquiétude et elle est très rapide. La génération de shaders natifs est elle aussi rapide [1]. Ce qui est lent, c’est la création de pipelines, et ce bytecode n’aide pas sur ce point
    [1] http://kvark.github.io/naga/shader/2022/02/17/shader-translation-benchmark.html

  • Je me demande comment ils ont réussi à faire ça aussi vite. WebGPU native a eu un long cycle de développement et n’est toujours pas finalisé, alors que l’API GPU de SDL prend en charge encore plus de plateformes, donc on aurait plutôt pensé que cela prendrait plus longtemps.

    • Si WebGPU a pris autant de temps, c’est parce qu’ils ont décidé de créer leur propre langage de shading au lieu d’utiliser SPIR-V. SDL n’a pas fait cette erreur, et laisse à l’utilisateur le soin d’apporter le compilateur de shaders et les outils de conversion.
      Il existe un projet compagnon [1] pour un langage de shading cross-platform, ainsi qu’un autre projet [2] pour convertir des langages existants entre eux, mais ils seront prêts quand ils seront prêts, et le reste de l’API n’a pas besoin de les attendre.
      WebGPU est le produit d’un comité composé de vendors et de juristes du langage, ou plutôt des standards, façonné par la politique et la bureaucratie, et ça se voit. SDL_GPU, lui, a été conçu avant tout par des développeurs de jeux focalisés sur le pragmatisme, et c’est pour cela qu’il est parfois méprisé dans les tours d’ivoire.
      [1]: https://github.com/libsdl-org/SDL_shader_tools
      [2]: https://github.com/flibitijibibo/SDL_gpu_shadercross
    • Les principaux contributeurs du projet GPU de SDL3 ont déjà de l’expérience avec deux couches d’abstraction GPU cross-platform, FNA3D et Refresh, visant à la fois PC et consoles. Ces connaissances, ainsi que le code open source existant, leur ont servi de base pour assembler quelque chose de rapide et de bonne qualité.
    • Parce qu’il n’y avait pas de comité, et qu’il y avait des développeurs motivés qui avaient besoin du résultat pour leurs propres projets. En particulier les gens de FNA.
    • C’est simple. SDL GPU laisse de côté le reste de la chouette, c’est-à-dire la partie qui convertit des shaders dans un format commun vers une représentation intermédiaire propre à chaque API.
  • Heureux d’avoir contribué à la partie dx12 :)

    • Super. L’objectif sera de viser du HLSL moderne, donc j’utiliserai probablement ce backend au début. J’espère que DXC produira du SPIR-V correct à la fin.
    • Quelles ressources recommanderiez-vous pour apprendre DX12 ?
  • Je me dis que je vais peut-être essayer. J’ai toujours trouvé que SDL était un logiciel de qualité. Ça compile vite, facilement sur plusieurs plateformes, et ça fonctionne toujours bien. Donc j’ai aussi des attentes pour cette nouvelle API.

  • Globalement, je suis un grand fan de SDL.
    Quand j’ai cherché une bibliothèque de jeu cross-platform, SDL et ses API m’ont semblé offrir le bon équilibre. Je voulais juste une bibliothèque C/C++ que je puisse appeler pour créer une fenêtre et un contexte graphique, ainsi qu’un framework de rendu de sprites rapide. Je n’avais pas besoin d’un IDE complet ni d’une bibliothèque massive, et je n’avais pas envie d’apprendre un nouveau langage.

  • J’ai l’impression que SDL3 subit l’effet du deuxième système. SDL2 ressemblait surtout à SDL1 avec des handles de fenêtre explicites, donc SDL3 est le deuxième système, pas le troisième. SDL1/2 étaient une fine couche enveloppant le boilerplate spécifique à chaque plateforme pour ouvrir une fenêtre et gérer les événements d’entrée, ce qui permettait d’arriver rapidement au code de rendu OpenGL qu’on voulait vraiment écrire.

    • On peut soutenir que l’API GPU de SDL est inutilement volumineuse si l’on ne vise que Windows/Linux/Android.
      Mais si l’on veut aussi prendre en charge les systèmes Apple, on se retrouve bloqué sur OpenGL 4.1. Apple l’a officiellement marqué comme obsolète il y a cinq ans, donc impossible d’utiliser des fonctionnalités GPU modernes comme les compute shaders.
      On peut aussi passer par Vulkan et utiliser MoltenVK sur les systèmes Apple, mais Vulkan est nettement plus complexe qu’OpenGL. Comme on l’entend souvent, on en est au niveau « 1000 lignes de code pour un seul triangle ». L’objectif de l’API GPU de SDL3 est d’offrir une alternative plus accessible tout en restant suffisamment flexible.
      Ce sera probablement la même histoire pour les consoles.
      Beaucoup de gens demandaient souvent : « Est-ce qu’on pourrait avoir quelque chose comme SDL_render, mais avec la prise en charge des shaders sur toutes les plateformes ? », et apparemment c’est de là que tout est parti.
      SDL3 ajoute aussi une API audio de plus haut niveau, mais j’en vois mal l’intérêt.
    • SDL2 ne se résumait pas à « SDL1 avec des handles de fenêtre explicites ». Il y a eu toutes sortes de changements d’API et de nouvelles fonctionnalités dans l’ensemble, et comme SDL3, il y a eu de gros changements dans le sous-système graphique. SDL1 utilisait le rendu logiciel, et SDL2 a ajouté l’accélération matérielle.
      De plus, SDL2 a beaucoup évolué depuis la 2.0.0, et SDL3 poursuit cette évolution en s’autorisant des changements cassant la compatibilité API. SDL3 n’a pas été réécrit depuis zéro, et du point de vue d’un utilisateur de SDL, passer de SDL2 à SDL3 ne devrait pas être si difficile.
      Et SDL1/2 n’ont jamais été seulement « fins » au point de ne pas avoir leur propre système graphique de haut niveau. Il est utile d’avoir quelque chose d’intégré qui permette aux nouveaux utilisateurs, ou à ceux qui ont des besoins basiques, d’afficher immédiatement quelque chose à l’écran.
      Comme l’a noté ahefner, SDL1 était assez « fin » selon les standards actuels, mais il offrait tout de même assez de fonctionnalités pour dessiner des choses basiques à l’écran sans avoir à écrire soi-même toute la logique pixel par pixel, et dans les années 90 c’était déjà bien utile.
    • Le problème, c’est qu’OpenGL est en pratique mort, et que Vulkan est un piètre remplaçant d’OpenGL du point de vue de la facilité d’utilisation.
    • L’API de rendu aussi était déjà un embonpoint inutile pour beaucoup d’utilisateurs de SDL. SDL2 était déjà nettement plus gros que SDL1 en taille binaire.
      Cela dit, cette abstraction pourrait répondre à des besoins qui vont au-delà du simple jeu 2D, tout en permettant de viser un écosystème d’API graphiques de plus en plus fragmenté, ce qui est regrettable. Le rêve d’un futur OpenGL(Next) universel a disparu. En revanche, la partie la plus difficile, la conversion des shaders, semble encore manquer.
  • Je n’ai jamais utilisé cette bibliothèque, mais si j’ai bien compris le fil lié, j’aimerais maintenant voir des exemples de la fonctionnalité cross-platform GPU compute désormais proposée. Je serais curieux de savoir par où commencer et si vous avez des recommandations.