IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Threads & Processus C++ Discussion :

Comment lancer un thread au niveau du GPU ?


Sujet :

Threads & Processus C++

  1. #1
    Inactif  
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    avril 2019
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur de jeux vidéo

    Informations forums :
    Inscription : avril 2019
    Messages : 7
    Points : 0
    Points
    0
    Par défaut Comment lancer un thread au niveau du GPU ?
    Salut! Tout d'abord je tiens à préciser que je ne savais pas très bien ou poster ce sujet.

    Je voudrais lancer un programme que j'ai compilé avec mon propre compilateur pour le GPU.

    Mais je ne sais pas de trop comment m'y prendre et apparemment ça ne fonctionne pas comme je le pense.

    -Je pensais qu'il fallait écrire à un endroit précis dans la VRAM, envoyer l'id tu thread avec une instruction marche/arrêt et puis l'adresse de la fonction qui doit être appelée par le thread. Mais ça n'a pas l'air d'être commce ça d'après le code source de mesa 3D trouvé ici :

    https://github.com/mesa3d/mesa

    Apparemment il utilise les threads de c11 pour lancer des threads au niveau du GPU, pourtant g++ et gcc ne peuvent pas générer de code binaire pour des GPU.

    Alors je ne sais pas très bien comment dois je m'y prendre.

    Merci.

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    juin 2010
    Messages
    6 674
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : juin 2010
    Messages : 6 674
    Points : 30 457
    Points
    30 457
    Billets dans le blog
    4
    Par défaut
    Je suis pas expert en 3D ou GPU mais il me semble qu'il se contrôle uniquement via des commandes, que OpenGL ou DirectX poussent.
    Donc les threads GPU, c'est pas ton problème. Tu utilises les API Direct3D ou OpenGL qui permettent de le manipuler et faire le rendu.
    Et un programme GPU c'est un Shader. Avec OpenGL ce sont les combos glCreateShader/glCompileShader.
    Si tu le compiles toi-même (pourquoi donc faire ça ? Comment ? C'est quoi ta sortie ?), tu réalises ces étapes mais il reste les étapes suivantes pour l'envoyer sur la carte graphique et là ça dépasse mes connaissances. Et ça dépend peut-être du modèle de carte graphique.
    Je ne vois absolument aucune raison de ne pas simplement écrire du glsl et utiliser OpenGL ?
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  3. #3
    Membre éprouvé
    Avatar de Garvelienn
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    septembre 2016
    Messages
    233
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : septembre 2016
    Messages : 233
    Points : 949
    Points
    949
    Par défaut
    Bonjour,

    Je complète la réponse précédente.
    Vous pouvez également utiliser OpenCL ou CUDA si vous avez une carte Nvidia. Ces deux API sont faites pour du calcul brut (traitement d'image, machine learning, etc) contrairement à OpenGL et DirectX qui sont plus pour du rendu graphique (bien qu'on puisse les utiliser pour autre chose). Dans la même philosophie que ces deux dernières, vous avez Vulkan qui permet d'avoir plus de contrôle sur ce qui est fait au niveau du GPU (allocation mémoire, etc).
    Je ne connais pas d'autres moyens de travailler sur le GPU. Si vous trouvez, cela m’intéresse, svp
    «Le management, tel qu’on l’apprend dans les écoles et tel qu’on l’applique ensuite, sous prétexte de «motivation du personnel», organise exactement le contraire, à savoir la démotivation organisée.» - Bernard Stiegler

  4. #4
    Inactif  
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    avril 2019
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur de jeux vidéo

    Informations forums :
    Inscription : avril 2019
    Messages : 7
    Points : 0
    Points
    0
    Par défaut
    D'après les spécifications techniques de ma carte graphique, il faut coder un kernel pour envoyer des commandes dans un registre pour demander au GPU de charger des données depuis la RAM et dans un autre registre pour les traiter, mais c'est le GPU qui gère lui même les threads au niveau du hardware, on ne peut pas les contrôler.
    Mesa 3D passe par une lib (libdrm) pour faire cela mais je ne sais pas quel code taper pour faire ça car il n'y a que les spécifications techniques et le code open source de mesa est trop dense, surtout pour quelqu'un comme moi qui n'a jamais fait ça.

    Normalement, tout le monde passe par OpenGL pour du rendu ou bien OpenCL/Cuda pour du calcul, cependant, je ne comprend pas très bien ce qui se passe derrière de ce fait, je n'arrive pas à les utiliser.

    Donc je voudrais faire ça pour mieux comprendre comment opengl fonctionne et surtout, les fonctionnalités d'opengl 4.5, que je n'arrive absolument pas à maîtriser, surtout au niveau de la synchronisation des données avec les images et en plus de ça, le rendu est trop lent.
    J'ai déjà recoder quelques libs/moteurs de rendu pour essayer de comprendre comment cela fonctionne parce que je n'arrivais pas à réutiliser l'existant (chose qui pose vraiment problème chez moi), et ça a plutôt bien porté ses fruits, mais, pour un driver graphique, ça à l'air d'être une tout autre histoire, et puis, je manque cruellement d'infos.

    J'ai essayé plusieurs techniques pour éviter de devoir utiliser des images :

    -Utiliser de très grandes textures et faire un tri, mais, les grandes textures font ramer le logiciel de traitement d'images.
    -Utiliser des bindless textures mais, mon GPU ne supporte pas GL_ARB_bindless_texture dans le fragment shader.
    -Utiliser des per pixels linked list mais je n'arrive pas à les utiliser correctement, l'affichage n'est pas synchronisé, et en plus, ce n'est pas performant.
    -Utiliser du weighted blending OIT mais là encore ça ne fonctionne pas.

    Sinon j'ai déjà pensé à d'autres solutions comme :

    -Diviser la carte en plusieurs zones et n'utiliser que les même images par zone.
    -Faire une couche de rendu pour le sol, une autre pour les modèles et une autre pour les sorts.

    Cependant, comme j'ai le temps, et que je n'ai rien de spécial à faire (je ne peux plus avancer sur mon projet car je n'ai pas d'équipe pour le graphisme et tout ça), je me suis un peu penché sur l'écriture d'un compilateur GLSL et d'un driver pour renforcer mes connaissances au niveau programmation, mais aussi, pour mieux comprendre comment le hardware fonctionne.

    Mais si je manque d'informations je vais devoir laisser tomber.
    Le plus crucial ça va être de savoir comment charger des données dans la VRAM et les traiter, une fois que je saurai comment faire ça, le reste, ça ne devrait pas être trop compliqué.
    Avec libdrm on peut le faire mais tout ce que j'ai trouvé c'est un code qui charge des données dans la VRAM mais pas des instructions, ni des commandes.

  5. #5
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    juin 2010
    Messages
    6 674
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : juin 2010
    Messages : 6 674
    Points : 30 457
    Points
    30 457
    Billets dans le blog
    4
    Par défaut
    Ha le retour de Laurent...
    "je ne sais pas utiliser OpenGl 4.5" => "mon rendu est trop lent" => "je vais recoder le drivers graphique". Parce que c'est tout à fait la chose à faire bien sûr
    Ce ne sont pas les sources, tutos et exemples qui manquent sur internet il me semble. Et le nombre de personnes qui l'utilisent, amateurs et pros, sont la preuve que ça fonctionne.
    Y'en a même pas mal dispos ici-même https://jeux.developpez.com/tutoriels/OpenGL-ogldev/ pour OpenGL 3+.
    Ton problème est toujours de l'ordre de l'interface homme-machine. Ne pas savoir utiliser une brouette ne se résoud pas en changeant la roue pour un carré en bois bricolé dans son garage.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  6. #6
    Inactif  
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    avril 2019
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur de jeux vidéo

    Informations forums :
    Inscription : avril 2019
    Messages : 7
    Points : 0
    Points
    0
    Par défaut
    Je m'attendais à ce genre de réponse. Déjà je ne vois pas de tutoriels sur opengl 4.5 et les per pixels linked list.
    Et sans les per pixels linked lists mon rendu fonctionne bien et tout ce qui est écrit dans ce tutoriel je l'ai déjà implémenter.
    C'est dans la manie des gens de toujours rejeter la faute sur les autres ?
    Bien sûr que j'ai déjà été voir sur Internet.
    Ça me fait penser au développeur de la SFML qui a supprimé mon compte parce que j'ai dit que sa librairie était bugué. Quelque jours après je recode le module fenêtre de la sfml et le programme ne crash plus.

    Je report le bug à mesa 3D et on un gaz me dit que c'est pas leurs bugs et que c'est moi qui ne sait pas utiliser opengl.
    Ho mais le code c'est un code que j'ai repris sur Internet et qui fonctionne. Mais pas chez moi. C'est pas parce que qu'un code fonctionne sur une carte graphique et un driver récent qu'il va fonctionner sur une carte graphique plus ancienne et un driver opensource.
    Non, toujours crasher la faute, sur les autres.

    Et je suis sûr, leur code est tellement danse, qu'ils ne savent même pas ce qu'ils font. Ou ce que fait l'autre car ils sont à plusieurs sur le projet.

    Quand il y a un bug, ils ne savent pas comment faire alors ils rejettent la faute sur les autres.

    Les gens sont devenus égoïstes et je pense que c'est aussi le cas des développeurs.

    Si ça tombe je vais faire ça moi même et ça va fonctionner comme le module fenêtre de SFML.

    Mais bon je vais me débrouiller tout seul, ce genre de réponse ça n'aide pas et en plus ça ne répond pas à ma question. C'est dans le seul but de me moinser.
    Par contre si j'y arrive, je ne ferai pas de portabilité pour les autres plateformes. Les développeurs n'auront qu'à se débrouiller eux même. Car personellement je commence à être saturé.
    Je fais un moteur de jeux qui tourne sur ma plateforme (truc pas simple à faire) parce que unity ne tournait pas.
    On vient dire que je code mal. C'était peut être vrai au départ parce que je n'ai fais que l'optimisation à la fin. Mais de là, à dire ce genre de choses, ça c'est quelque chose que je n'accepte pas.

  7. #7
    Responsable Systèmes


    Homme Profil pro
    Technicien maintenance
    Inscrit en
    août 2011
    Messages
    14 160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : août 2011
    Messages : 14 160
    Points : 32 353
    Points
    32 353
    Par défaut
    Mais je ne sais pas de trop comment m'y prendre et apparemment ça ne fonctionne pas comme je le pense.

    Le problème est là.

    maitriser OpenGL, CUDA et autres ne se fait pas en un claquement de doigt.

    Je voudrais lancer un programme que j'ai compilé avec mon propre compilateur pour le GPU.
    ???

    Tu ne peux pas créer de compilateur pour un GPU dont la documentation technique n'est pas disponible, à moins de faire de la rétro-ingénierie , ce qui est de la haute voltige. C'est justement le rôle des API 3D de faire le lien avec les cartes 3D en passant par leurs pilotes.

    Comment lancer un thread GPU ? En passant par OpenGL et autres API justement. Ce sont à ces API de gérer, pas à toi. Surtout que les API, optimisées, le feront bienmieux que toi. Tout comme un compilateur, génèrera un meilleur langage machine que toi.

    La seule chose que tu peux faire de "bas niveau",c'est de créer une surcouche aux API existantes, ce qui me parait inutile.

    Et ne pas dire qu'il n'y a pas de docs sur les API.
    Un point de départ non exhaustif :
    https://jeux.developpez.com/tutoriels/?page=prog-3d

    Je report le bug à mesa 3D et on un gaz me dit que c'est pas leurs bugs et que c'est moi qui ne sait pas utiliser opengl.
    Me considérant comme débutant en programmation (ce n'est pas mon cœur de métier), avant de remettre en question une API déjà testée et approuvé et ayant pignon sur rue, je commences par remettre en question on code. Il y a 99,99 % de chance qu ele problème ne vienne pas de l'API.

    mais le code c'est un code que j'ai repris sur Internet et qui fonctionne.
    Qu'est ce qui te garantit qu'un code repris sur Internet fonctionne ? La preuve, comme tu le dis toi-même, il ne fonctionne pas, ou peut-être dans un contexte précis qui n'est pas le tien.
    Ma page sur developpez.com : http://chrtophe.developpez.com/ (avec mes articles)
    Mon article sur la création d'un système : http://chrtophe.developpez.com/tutoriels/minisysteme/
    Mon article sur le P2V : http://chrtophe.developpez.com/tutoriels/p2v/
    Consultez nos FAQ : Windows, Linux, Virtualisation

  8. #8
    Inactif  
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    avril 2019
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur de jeux vidéo

    Informations forums :
    Inscription : avril 2019
    Messages : 7
    Points : 0
    Points
    0
    Par défaut
    Bon, c'est glMemoryBarrier qui ne fonctionne pas.

    Cette fonction est sensée attendre que toutes les données soit écrites avant que l'autre shader ne puisse les lire, mais, il n'attend pas.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
     
    const std::string fragmentShader =
                    R"(#version 140
                       #extension GL_ARB_shader_atomic_counters : require
                       #extension GL_ARB_shading_language_420pack : require
                       #extension GL_ARB_shader_image_load_store : require
                       #extension GL_ARB_shader_storage_buffer_object : require
                       #define MAX_FRAGMENTS 75
                       struct NodeType {
                          vec4 color;
                          float depth;
                          uint next;
                       };
                       layout(binding = 0, offset = 0) uniform atomic_uint nextNodeCounter;
                       layout(binding = 0, r32ui) coherent uniform uimage2D headPointers;
                       layout(binding = 0, std430) coherent buffer linkedLists {
                           NodeType nodes[];
                       };
                       uniform uint maxNodes;
                       uniform float haveTexture;
                       uniform sampler2D texture;
                       void main() {
                           vec4 texel = texture2D(texture, gl_TexCoord[0].xy);
                           vec4 color = (haveTexture > 0.9) ? gl_Color * texel : gl_Color;
                           if (color.a > 0) {
                               uint nodeIdx = atomicCounterIncrement(nextNodeCounter) + 1u;
                               if (nodeIdx < maxNodes) {
                                    uint prevHead = imageAtomicExchange(headPointers, ivec2(gl_FragCoord.xy), nodeIdx);
                                    nodes[nodeIdx].color = color;
                                    nodes[nodeIdx].depth = gl_FragCoord.z;
                                    nodes[nodeIdx].next = prevHead;
                               }
                           }
                       })";
                       const std::string fragmentShader2 =
                       R"(
                       #version 140
                       #extension GL_ARB_shader_atomic_counters : require
                       #extension GL_ARB_shading_language_420pack : require
                       #extension GL_ARB_shader_image_load_store : require
                       #extension GL_ARB_shader_storage_buffer_object : require
                       #define MAX_FRAGMENTS 75
                       struct NodeType {
                          vec4 color;
                          float depth;
                          uint next;
                       };
                       layout(binding = 0, r32ui) coherent uniform uimage2D headPointers;
                       layout(binding = 0, std430) coherent buffer linkedLists {
                           NodeType nodes[];
                       };
                       void main() {
                          NodeType frags[MAX_FRAGMENTS];
                          int count = 0;
                          uint n = imageLoad(headPointers, ivec2(gl_FragCoord.xy)).r;
                          while( n != 0u && count < MAX_FRAGMENTS) {
                               frags[count] = nodes[n];
                               n = frags[count].next;
                               imageStore(headPointers, ivec2(gl_FragCoord.xy), uvec4(n, 0, 0, 0));
                               count++;
                          }
                          //merge sort
                          int i, j1, j2, k;
                          int a, b, c;
                          int step = 1;
                          NodeType leftArray[MAX_FRAGMENTS/2]; //for merge sort
     
                          while (step <= count)
                          {
                              i = 0;
                              while (i < count - step)
                              {
                                  ////////////////////////////////////////////////////////////////////////
                                  //merge(step, i, i + step, min(i + step + step, count));
                                  a = i;
                                  b = i + step;
                                  c = (i + step + step) >= count ? count : (i + step + step);
     
                                  for (k = 0; k < step; k++)
                                      leftArray[k] = frags[a + k];
     
                                  j1 = 0;
                                  j2 = 0;
                                  for (k = a; k < c; k++)
                                  {
                                      if (b + j1 >= c || (j2 < step && leftArray[j2].depth > frags[b + j1].depth))
                                          frags[k] = leftArray[j2++];
                                      else
                                          frags[k] = frags[b + j1++];
                                  }
                                  ////////////////////////////////////////////////////////////////////////
                                  i += 2 * step;
                              }
                              step *= 2;
                          }
                          vec4 color = vec4(0, 0, 0, 0);
                          for( int i = 0; i < count; i++ )
                          {
                              color = mix( color, frags[i].color, frags[i].color.a);
                          }
                          gl_FragColor = color;
                       })";
    Lorsque j'écris la valeur de prevHead dans l'image (headptr) dans le premier shader et que je lis les valeurs dans la texture headptr liée à l'image headptr, c'est bon, par contre, lorsque je lis la valeur de n dans le second shader, celle-ci n'est pas bonne, ça me lit bien la valeur de la tête de la liste, mais pour le fragment suivant, la valeur de n est toujours égale à 0, malgré que j'ai écrit cette ligne de code entre les deux passes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    glCheck(glMemoryBarrier( GL_SHADER_STORAGE_BARRIER_BIT ));
    Il y a deux possibilités :

    -Bug au niveau du driver.
    -Bug au niveau du hardware.

    Donc j'ai deux choix :

    -Soit je cherche dans le code source de mesa 3D pour voir si je ne vois pas un bug, chose insensée vu la densité du code source.
    -Soit je refais un driver pour voir si le bug provient du hardware ou du software et si ça provient du hardware je rachète une nouvelle carte (ou un nouveau PC si on ne peut pas changer de carte graphique sur un PC portable)

  9. #9
    Membre éprouvé
    Avatar de Garvelienn
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    septembre 2016
    Messages
    233
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : septembre 2016
    Messages : 233
    Points : 949
    Points
    949
    Par défaut
    LaurentDur, faites un effort lorsque vous expliquer votre problème. Nous ne comprenons rien à ce que vous dites. Votre code est illisible : pas de commentaire, des variables nommées n'importe comment, etc. Nous ne sommes pas dans votre tête. Si vous voulez de l'aide, faites l'effort, s'il-vous-plaît.

    Donnez un peu plus de contexte. Quel est le but/pourquoi faire ? Quel sont les vertex shaders ? Quelle version d'OpenGL et/ou pourquoi "#version 140" en GLSL ?

    Et je rejoins chrtophe et Bousk, vous remettez vous en question ? Avant d'affirmer qu'il y a un bug dans l'API, avez vous des preuves (et pas du "mon code ne marche pas") ?

    Évitez la situation suivante, par exemple

    Nom : static1.squarespace.com.png
Affichages : 103
Taille : 122,3 Ko
    «Le management, tel qu’on l’apprend dans les écoles et tel qu’on l’applique ensuite, sous prétexte de «motivation du personnel», organise exactement le contraire, à savoir la démotivation organisée.» - Bernard Stiegler

  10. #10
    Inactif  
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    avril 2019
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur de jeux vidéo

    Informations forums :
    Inscription : avril 2019
    Messages : 7
    Points : 0
    Points
    0
    Par défaut
    D'accord je vais envoyer un code plus commenté mais, je suis pratiquement sûr que c'est glMemoryBarrier qui ne fonctionne pas.

  11. #11
    Inactif  
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    avril 2019
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur de jeux vidéo

    Informations forums :
    Inscription : avril 2019
    Messages : 7
    Points : 0
    Points
    0
    Par défaut
    Bon, j'ai trouvé une solution (temporaire) pour corriger ce bug.

    J'ai rajouté des instructions inutiles dans le shader pour ralentir l'exécution du shader. (J'ai du mettre un if à la fin ici)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
     
     const std::string fragmentShader2 =
                   R"(
                   #version 140
                   #extension GL_ARB_shader_atomic_counters : require
                   #extension GL_ARB_shading_language_420pack : require
                   #extension GL_ARB_shader_image_load_store : require
                   #extension GL_ARB_shader_storage_buffer_object : require
                   #define MAX_FRAGMENTS 75
                   struct NodeType {
                      vec4 color;
                      float depth;
                      uint next;
                   };
                   layout(binding = 0, r32ui) coherent uniform uimage2D headPointers;
                   layout(binding = 0, std430) coherent buffer linkedLists {
                       NodeType nodes[];
                   };
                   void main() {
                      NodeType frags[MAX_FRAGMENTS];
                      NodeType frags2[MAX_FRAGMENTS];
                      int count = 0;
                      uint n = imageLoad(headPointers, ivec2(gl_FragCoord.xy)).r;
                      while( n != 0u && count < MAX_FRAGMENTS) {
                           frags[count] = nodes[n];
                           frags2[count] = frags[count];
                           n = nodes[n].next;
                           count++;
                      }
                      //merge sort
                      int i, j1, j2, k;
                      int a, b, c;
                      int step = 1;
                      NodeType leftArray[MAX_FRAGMENTS/2]; //for merge sort
     
                      while (step <= count)
                      {
                          i = 0;
                          while (i < count - step)
                          {
                              ////////////////////////////////////////////////////////////////////////
                              //merge(step, i, i + step, min(i + step + step, count));
                              a = i;
                              b = i + step;
                              c = (i + step + step) >= count ? count : (i + step + step);
     
                              for (k = 0; k < step; k++)
                                  leftArray[k] = frags[a + k];
     
                              j1 = 0;
                              j2 = 0;
                              for (k = a; k < c; k++)
                              {
                                  if (b + j1 >= c || (j2 < step && leftArray[j2].depth > frags[b + j1].depth))
                                      frags[k] = leftArray[j2++];
                                  else
                                      frags[k] = frags[b + j1++];
                              }
                              ////////////////////////////////////////////////////////////////////////
                              i += 2 * step;
                          }
                          step *= 2;
                      }
                      vec4 color = vec4(0, 0, 0, 0);
                      for( int i = 0; i < count; i++ )
                      {
                          color = mix( color, frags[i].color, frags[i].color.a);
                          if (frags2[i].color.r > 1 || frags2[i].color.g > 1 || frags2[i].color.b > 1)
                            color = vec4(1, 1, 1, 1);
                      }
                      gl_FragColor = color;
    On dirait que le driver met à jour le contenu de la fenêtre trop tôt, alors du coup si j'enlève le if à la fin, j'ai une fenêtre toute noire!!!

    Mais bon il y a moyen de trouver des solutions sans devoir recoder un driver.. (et heureusement)

Discussions similaires

  1. comment lancer un programme dans un nouveau thread
    Par Yihaa dans le forum Multithreading
    Réponses: 13
    Dernier message: 16/09/2009, 17h35
  2. comment lancer son thread audio ?
    Par olivier1209 dans le forum Multimédia
    Réponses: 0
    Dernier message: 18/05/2009, 12h15
  3. Comment lancer Word dans un thread séparé
    Par Tony49 dans le forum C++Builder
    Réponses: 3
    Dernier message: 22/03/2009, 12h43
  4. [VC++] Comment lancer un Thread
    Par ksoft dans le forum MFC
    Réponses: 5
    Dernier message: 30/05/2006, 14h19
  5. [Débutant][Thread] Comment lancer en boucle un affichage
    Par comme de bien entendu dans le forum Général Java
    Réponses: 6
    Dernier message: 03/02/2006, 10h20

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo