2017-08-17 3 views
-1

Je travaille sur un moteur graphique OpenGL qui peut rendre des maillages transparents avec précision. Le projet complet est disponible here; Il s'agit d'une solution Visual Studio 2017 (il se peut que vous deviez installer le SDK Windows 10), mais également un makefile à compiler sous Linux. Il utilise des listes de fragments liés sur le GPU qui sont ensuite triés et fusionnés de l'avant vers l'avant. Plus spécifiquement, cela se fait avec deux tampons et un compteur atomique: le premier tampon contient, pour chaque pixel, un pointeur vers la tête de sa liste et est atomiquement mis à jour lors du rendu des maillages; le second tampon contient les nœuds réels (un nœud est la couleur du fragment et le pointeur vers le nœud suivant) et le compteur atomique est utilisé pour réserver une position unique dans ce second tampon. Le problème est que tout fonctionne correctement sur mon portable avec des graphismes AMD discrets, mais se bloque sur mon autre PC nVidia (GT 740, très bon marché). Il se bloque à la fois sur Windows et Linux et les deux avec le pilote officiel et la pile open source. Le code qui cause c'est à l'intérieur du shader de tri (s'il vous plaît voir le commentaire TODO):Le shader GLSL avancé fonctionne bien sur AMD mais se bloque sur nVidia

int listBegin = listsHeads[getPixelBufferIndex()]; 

if(listBegin != -1) 
{ 
    // Sort linked list using bubble sort 
    bool swapped; 
    do 
    { 
     // Start at list head 
     swapped = false; 
     int previousNode = listBegin; 
     int currentNode = listsNodes[listBegin].nextNode; 

     // Loop until list end 
     while(currentNode != -1) 
     { 
      // Furthest first 
      float previousDepth = listsNodes[previousNode].depth; 
      float currentDepth = listsNodes[currentNode].depth; 

      // TODO fix crash on nVidia 
      if(previousDepth < currentDepth) 
      { 
       swapped = true; 
       FragmentNode temp; 
       temp.color = listsNodes[currentNode].color; 
       temp.meshId = listsNodes[currentNode].meshId; 

       listsNodes[currentNode].color = listsNodes[previousNode].color; 
       listsNodes[currentNode].depth = previousDepth; 
       listsNodes[currentNode].meshId = listsNodes[previousNode].meshId; 

       listsNodes[previousNode].color = temp.color; 
       listsNodes[previousNode].depth = currentDepth; 
       listsNodes[previousNode].meshId = temp.meshId; 
      } 
      previousNode = currentNode; 
      currentNode = listsNodes[currentNode].nextNode;     
     } 
    } 
    while(swapped); 
} 

Si je retire l'intérieur si le programme ne se bloque plus, mais bien sûr le résultat est incorrect car les listes ne sont pas classés . Je commence à penser qu'il y a un problème avec mon modèle de carte graphique particulier, parce que le plantage à la fois avec le pilote binaire et la pile open source sur la même carte semble suggérer que. Mais peut-être qu'il y a un bug dans le shader que je n'ai pas trouvé.

Une idée? Ceci est la sortie que je veux:

Correct output

+0

Coup aveugle: Remplacez 'FragmentNode temp' par deux variables flottantes. – Ripi2

+0

Malheureusement, cela ne fonctionne pas. – Shepard

Répondre

0

Le passage de tri à bulles à la sélection sorte résolu la question. Aucune idée cependant pourquoi il se brisait le GPU.