Bonjour !
Je reviens sur ce thread car j'ai toujours des soucis de compatibilité ATI et/ou 2.0 que j'ai absolument besoin de corriger.
J'ai testé un peu cette histoire de RAM graphique et normale. Il semble que le programme charge les nouvelles images en RAM normale lorsque la RAM graphique est pleine.
J'avais parlé plus tôt dans ce thread d'un bug sur les Threads avec les cartes ATI ( nécessité de déclarer un contexte explicitement, contrairement à Nvidia, sinon les images ne s'affichent pas ). J'ai l'impression que les images ne sont pas correctement déchargées au bout d'un moment. Sur un PC ATI ( Windows 7-64 ), la ram graphique augmente jusqu'a un point proche du max ( ~960/1024 ). Pendant un petit moment à charger/décharger des images, la RAM graphique oscille et la normale ne bouge pas. Au bout d'un moment, c'est la ram normale qui augmente, mais ne diminue plus lorsque les images sont détruites. lorsque la ram normale atteint un chiffre élevé ( ~1go ), le programme bloque dans la dll openGL d'ati ( pendant le rendu ou pendant un bind texture ).
Je n'ai pas réussi à reproduire ce comportement sur un pc Nvidia ( Windows 7 64 ).
Pour le moment je n'ai pas trouvé la source du problème ( et je galère un peu ). J'ai essayé de déclarer un contexte au moment de la destruction des textures ( et non plus uniquement à la création ), mais j'avais d'autres problèmes...
Petites questions au passage :
- Est-ce qu'une image chargée dans un thread doit être détruire dans le même thread ( même contexte ) ?
- J'ai vu dans les sources SFML qu'il y a une liste de internalContexts qui s'empilent pour chaque nouveau thread, et qui sont détruites uniquement dans la fonction de cleanUp global. C'est probablement de la que vient une partie de la fuite décrite dans ce bug :
https://github.com/SFML/SFML/issues/120, et je me demandais si ça pouvait avoir un rapport avec mon problème.
je vais essayer de résumer le fonctionnement, au cas ou quelqu'un détecterait un problème potentiel :
on a un main thread qui fait quasiment tout ( affichage, physique... ). Lorsque le joueur change de map, on a un premier thread qui effectue l'initialisation des nouvelles maps, et qui envoie des requêtes de chargement de textures, effectuées par un troisième thread ( tout ça pendant que le jeu tourne dans le main ). Lorsqu'on s'éloigne d'une map, le premier thread désinitialise les maps et il détruit les textures.
Depuis le passage à la 2.0, on a aussi des chutes de framerate brutales ( localisées principalement dans l'affichage ), que nous n'avions pas sur la 1.6.
Je vais poursuivre mes investigations, et je mettrai a jour si je trouve quelque chose.
Je prends toute info ou suggestion pour essayer de localiser/corriger ce bug ( dans SFML si nécessaire ).
Merci de votre aide.
ps : Lorsque j'ai créé ce thread, j'ai pris le snapshot 2.0-rc-42-[...].
Actuellement c'est le 74 je crois. Serais-ce une bonne idée de mettre a jour au passage ?
ps2 : question "hors sujet" : Est ce qu'il y a déjà eu des jeux commerciaux sortis utilisant SFML ?
edit rapide : J'ai repris et modifié légèrement le code proposé par Ceylo (
https://github.com/SFML/SFML/issues/120 ) de la façon suivante :
#define TEX_SIZE 2048
sf::Image sharedImage;
void thread_func(void *data)
{
// Reuse the same texture object
sf::Texture** tex = ((sf::Texture **)data);
(*tex) = new sf::Texture();
//sf::Context ctx;
// Should just erase the previous data
(*tex)->loadFromImage(sharedImage);
}
int main()
{
sf::Texture* tex = NULL;
sharedImage.create(TEX_SIZE, TEX_SIZE, sf::Color::Red);
sf::Thread th(thread_func, (void *)(&tex));
sf::RenderWindow window;
window.create(sf::VideoMode(256,256,32), "test");
// Create one thread/sec
while (true)
{
th.launch();
th.wait();
window.clear();
sf::Sprite sprite;
sprite.setTexture(*tex,true);
window.draw(sprite);
window.display();
sprite.setTexture(sf::Texture(), true);
delete tex;
}
return 0;
}
Résultat ( toujours sur mon pc win7 64 ATI ) : si je commente la déclaration du contexte dans le thread, j'ai une leak beaucoup plus importante ( ~16 Mo par itération ) contre beaucoup moins si je déclare le contexte dans le thread... C'est probablement lié a la nécessite de déclarer un contexte pour charger les images sur ATI. Si ça peut aider...