Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 01/05/2015, à 17:43

Lolichou

Développer un driver graphique. (Pour exécuter du code avec le GPU)

Salut, je voudrais développé un driver graphique pour ma carte graphique.

Exactement comme le fait l'api openCL mais le problème c'est que openCL ne supporte que les nouvelles cartes graphique.

Comment faire cela avec ubuntu ?

Merci d'avance pour votre aide.

Dernière modification par Lolichou (Le 01/05/2015, à 17:43)

Hors ligne

#2 Le 02/05/2015, à 10:03

tiramiseb

Re : Développer un driver graphique. (Pour exécuter du code avec le GPU)

Salut,

Développer un pilote, c'est pas une mince affaire.
Mais j'ai l'impression que tu n'utilises pas le bon vocabulaire en fait...

Peux-tu préciser quel est ton objectif, en faisant ça ?

Hors ligne

#3 Le 02/05/2015, à 14:28

Lolichou

Re : Développer un driver graphique. (Pour exécuter du code avec le GPU)

tiramiseb a écrit :

Salut,

Développer un pilote, c'est pas une mince affaire.
Mais j'ai l'impression que tu n'utilises pas le bon vocabulaire en fait...

Peux-tu préciser quel est ton objectif, en faisant ça ?

Mon objectif est de faire mon propre rasteriseur, car, celui par défaut proposé par l'api opengl ne me convient pas.
Il y a de nouvelles apis comme openCL qui permettent de faire les calculs soit même en parallèle avec le CPU.
Mais ces nouvelles apis ne sont pas supportés par mon ancienne carte graphique.

Avec openCL je n'aurai aucune difficulté à intégrer ce code et le faire exécuter par le GPU :

for (unsigned int i = 0; i < m_instances.size(); i++) {
                for (unsigned int j = 0; j < m_instances[i]->getVertexArrays().size(); j++) {
                    TransformMatrix& tm = m_instances[i]->getTransforms()[j].get();
                    for (unsigned int k = 0; k < m_instances[i]->getVertexArrays()[j]->getVertexCount(); k++) {
                        math::Matrix4f texM;
                        math::Matrix4f invTexM;
                        if (m_instances[i]->getMaterial().getTexture() != nullptr) {
                            texM = m_instances[i]->getMaterial().getTexture()->getTextureMatrix();
                            invTexM = texM.inverse();
                        }
                        if (m_instances[i]->getVertexArrays()[j]->getPrimitiveType() == sf::TrianglesFan
                            && m_instances[i]->getVertexArrays()[j]->getVertexCount() >= 3
                            && k < m_instances[i]->getVertexArrays()[j]->getVertexCount() - 2) {
                            math::Vec3f p1 = math::Vec3f((*m_instances[i]->getVertexArrays()[j])[0].position.x,(*m_instances[i]->getVertexArrays()[j])[0].position.y,(*m_instances[i]->getVertexArrays()[j])[0].position.z);
                            math::Vec3f p2 = math::Vec3f((*m_instances[i]->getVertexArrays()[j])[k+1].position.x,(*m_instances[i]->getVertexArrays()[j])[k+1].position.y,(*m_instances[i]->getVertexArrays()[j])[k+1].position.z);
                            math::Vec3f p3 = math::Vec3f((*m_instances[i]->getVertexArrays()[j])[k+2].position.x,(*m_instances[i]->getVertexArrays()[j])[k+2].position.y,(*m_instances[i]->getVertexArrays()[j])[k+2].position.z);
                            p1 = tm.transform(p1);
                            p2 = tm.transform(p2);
                            p3 = tm.transform(p3);
                            p1 = window.mapCoordsToPixel(p1, view);
                            p2 = window.mapCoordsToPixel(p2, view);
                            p3 = window.mapCoordsToPixel(p3, view);
                            sf::Color c1 = (*m_instances[i]->getVertexArrays()[j])[0].color;
                            sf::Color c2 = (*m_instances[i]->getVertexArrays()[j])[k+1].color;
                            sf::Color c3 = (*m_instances[i]->getVertexArrays()[j])[k+2].color;
                            math::Vec3f ct1 = texM * math::Vec3f((*m_instances[i]->getVertexArrays()[j])[0].texCoords.x,(*m_instances[i]->getVertexArrays()[j])[0].texCoords.y, 1.f);
                            math::Vec3f ct2 = texM * math::Vec3f((*m_instances[i]->getVertexArrays()[j])[k+1].texCoords.x,(*m_instances[i]->getVertexArrays()[j])[k+1].texCoords.y, 1.f);
                            math::Vec3f ct3 = texM * math::Vec3f((*m_instances[i]->getVertexArrays()[j])[k+2].texCoords.x,(*m_instances[i]->getVertexArrays()[j])[k+2].texCoords.y, 1.f);
                            std::array<math::Vec3f, 3> vertices = {math::Vec3f(p1.x, p1.y, 0),math::Vec3f(p2.x, p2.y, 0), math::Vec3f(p3.x, p3.y, 0)};
                            std::array<std::array<float, 2>, 3> extends = math::Computer::getExtends(vertices);
                            int minX = (extends[0][0] < 0) ? 0 : extends[0][0];
                            int minY = (extends[1][0] < 0) ? 0 : extends[1][0];
                            int maxX = (extends[0][1] >= size.x) ? size.x-1 : extends[0][1];
                            int maxY = (extends[1][0] >= size.y) ? size.y-1 : extends[1][1];
                            math::Vec2f p(minX, minY);
                            Edge e01, e12, e20;
                            math::Vec3f w0_row = e12.init(p2, p3, p);
                            math::Vec3f w1_row = e20.init(p3, p1, p);
                            math::Vec3f w2_row = e01.init(p1, p2, p);
                            for (p.y = minY; p.y < maxY; p.y += Edge::stepYSize) {
                                math::Vec3f w0 = w0_row;
                                math::Vec3f w1 = w1_row;
                                math::Vec3f w2 = w2_row;
                                for (p.x = minX; p.x <= maxX; p.x += Edge::stepXSize) {
                                    math::Vec3f mask ((int) w0.x | (int) w1.x | (int) w2.x,
                                                      (int) w0.y | (int) w1.y | (int) w2.y,
                                                      (int) w0.z | (int) w1.z | (int) w2.z,
                                                      (int) w0.w | (int) w1.w | (int) w2.w);
                                    if (mask.x < 0 || mask.y < 0 || mask.z < 0 || mask.w < 0) {
                                        for (unsigned int y = p.y; y < p.y + Edge::stepYSize; y++) {
                                            for (unsigned int x = p.x; x < p.x + Edge::stepXSize; x++) {
                                                math::Matrix2f m1(p1.x - p3.x, p2.x - p3.x,
                                                                  p1.y - p3.y, p2.y - p3.y);
                                                float u = ((p2.y - p3.y) * (x - p3.x) + (p3.x - p2.x) * (y - p3.y)) / m1.getDet();
                                                float v = ((p3.y - p1.y) * (x - p3.x) + (p1.x - p3.x) * (y - p3.y)) / m1.getDet();
                                                float w = 1 - u - v;
                                                math::Vec3f z (p1.z, p2.z, p3.z);
                                                float bz = z.x * u + z.y * v + z.z * w;
                                                float actualZ = depthBuffer[y * size.x + x].z;

                                                if (bz >= view.getViewport().getPosition().z && bz <= view.getViewport().getSize().z) {
                                                    math::Vec3f tcx = math::Vec3f(ct1.x, ct2.x, ct3.x);
                                                    math::Vec3f tcy = math::Vec3f(ct1.y, ct2.y, ct3.y);
                                                    math::Vec3f tc = invTexM * math::Vec3f(tcx.x * u + tcx.y * v + tcx.z * w,
                                                                                 tcy.x * u + tcy.y * v + tcy.z * w, 1.f);
                                                    math::Vec3f texColor(1.f, 1.f, 1.f, 1.f);
                                                    if (m_instances[i]->getMaterial().getTexture() != nullptr) {
                                                        const sf::Image& texImg = m_instances[i]->getMaterial().getTexture()->getImage();
                                                        tc.x = math::Math::clamp(tc.x, 0, texImg.getSize().x);
                                                        tc.y = math::Math::clamp(tc.y, 0, texImg.getSize().y);
                                                        sf::Color color = texImg.getPixel(tc.x, tc.y);
                                                        texColor = math::Vec3f (color.r / 255.f, color.g / 255.f, color.b / 255.f, color.a / 255.f);
                                                    }
                                                    math::Vec3f r = math::Vec3f (c1.r / 255.f, c2.r / 255.f, c3.r / 255.f);
                                                    math::Vec3f g = math::Vec3f (c1.g / 255.f, c2.g / 255.f, c3.g / 255.f);
                                                    math::Vec3f b = math::Vec3f (c1.b / 255.f, c2.b / 255.f, c3.b / 255.f);
                                                    math::Vec3f a = math::Vec3f (c1.a / 255.f, c2.a / 255.f, c3.a / 255.f);
                                                    std::array<math::Vec3f, 2> colors;
                                                    colors[0] = math::Vec3f(frameBuffer[(y * size.x + x)*4] / 255.f,
                                                                                       frameBuffer[(y * size.x + x)*4+1] / 255.f,
                                                                                       frameBuffer[(y * size.x + x)*4+2] / 255.f,
                                                                                       depthBuffer[y * size.x + x].w);
                                                    colors[1] = math::Vec3f(r.x * u + r.y * v + r.z * w,
                                                                            g.x * u + g.y * v + g.z * w,
                                                                            b.x * u + b.y * v + b.z * w,
                                                                            a.x * u + a.y * v + a.z * w) * texColor;
                                                    bool src=(bz >= actualZ);
                                                    float z[2];
                                                    z[0] = actualZ;
                                                    z[1] = bz;
                                                    if (colors[1].w != 0) {
                                                        math::Vec3f finalColor = colors[src] * colors[src].w + colors[!src] * (1 - colors[src].w);
                                                        depthBuffer[y * size.x + x] = math::Vec3f(0, 0, z[src], colors[src].w);
                                                        frameBuffer[(y * size.x + x) * 4] = finalColor.x * 255;
                                                        frameBuffer[(y * size.x + x) * 4 + 1] = finalColor.y * 255;
                                                        frameBuffer[(y * size.x + x) * 4 + 2] = finalColor.z * 255;
                                                        frameBuffer[(y * size.x + x) * 4 + 3] = finalColor.w * 255;
                                                    }
                                                }
                                            }
                                        }
                                    }
                                    w0 += e12.oneStepX;
                                    w1 += e20.oneStepX;
                                    w2 += e01.oneStepX;
                                }
                                w0_row += e12.oneStepY;
                                w1_row += e20.oneStepY;
                                w2_row += e01.oneStepY;
                            }
                        }
                    }
                }
            }
            winFrameBuffer.create(size.x, size.y, &frameBuffer[0]);
            fbTexture.loadFromImage(winFrameBuffer);

Mais sans openCL il faudrait carrément recoder un driver et ce n'est pas une mince affaire.

J'ai tout essayé pour trouver un alternative mais en vain :

-Installer le driver propriétaire d'ati pour faire de l'opengl moderne mais il ne fonctionne pas.
-Instanced Rendering mais le soucis c'est que si je fais ça les données dans mon shader ne sont remise à jour que lorsque j'ai dessiné tout le terrain hors que j'ai besoin de les données soit remise à jour à chaque dessin d'une tile dans mon shader.
-OpenCL mais non supportée par ma nouvelle carte graphique, je n'arrive donc à à créer un contexte pour mon GPU.

Le but final est donc d'améliorer nettement les performances de mon jeux en modifiant le driver de ma carte graphique.
Le but est de dessiner les pixels dans n'importe quel ordre, peu importe la transparence des pixels et leur valeur z, et ce de manière parallèle afin que le CPU puisse effectuer les traitements physique pendant le dessin. (Pour l'instant le CPU attend que le GPU aie dessiné toute la scène avant de pouvoir effectuer les traitements physique et les appels consécutif à draw pour remettre à jour les données dans mes shaders n'arrangent pas les choses. hmm)

Mais comme tu le dis si bien ce n'est pas une mince affaire! hmm

Dernière modification par Lolichou (Le 02/05/2015, à 14:31)

Hors ligne

#4 Le 02/05/2015, à 14:53

alius

Re : Développer un driver graphique. (Pour exécuter du code avec le GPU)

OpenCL n'est pas un driver graphique, c'est une API bas niveau pour faire du GPU computing, pour le graphisme il faut voir du coté de openGL.

Pour ce faire il te faut les spécifications de la carte graphique. Si c'est une carte récente, ça m'étonnerait que tu puisses les trouver.  Tu aura plus de chance avec un vieux modèle dont les spec on étaient ouvertes par le fabricant.

Si tu trouves les spécifications là tout devient possible, mais c'est un gros projet car il faut en amont déchiffrer, comprendre les spécifications avant de pouvoir écrire les premières ligne de C.


Alius

Hors ligne

#5 Le 02/05/2015, à 14:55

alius

Re : Développer un driver graphique. (Pour exécuter du code avec le GPU)

EDIT : j'avais pas vu la réponse de Lolichou

ah d'accord !
eh bien dans ce cas précis, la solution la plus simple est de télécharger les sources de la dernières version de openGL qui supporte ta carte, et de recompiler après avoir apporté les modifications que tu souhaites.

Dernière modification par alius (Le 02/05/2015, à 14:56)


Alius

Hors ligne

#6 Le 02/05/2015, à 15:08

Lolichou

Re : Développer un driver graphique. (Pour exécuter du code avec le GPU)

Ha, ok, donc les sources de mesa-driver dans ce cas.

Il faudrait déjà que je m'y retrouve dans tout ce code et ensuite je pourrai apporter les modifications que je souhaite.

Hors ligne

#7 Le 02/05/2015, à 15:15

alius

Re : Développer un driver graphique. (Pour exécuter du code avec le GPU)

oui en jetant un œil (ou deux) dans mesa3d tu devrais pouvoir trouver quelque chose d'intéressant.
En parallèle tu peux t'aider de la spécification openGL qui traite du rasterizer pour t'y retrouver plus ~facilement surtout pour comprendre l'implémentation


Alius

Hors ligne

#8 Le 02/05/2015, à 17:16

Lolichou

Re : Développer un driver graphique. (Pour exécuter du code avec le GPU)

Ok, mais le soucis c'est que openGL est déjà trop haut niveau pour moi.

En fait le problème est que j'ai besoin de faire un test de profondeur personnalisé (ça pas de problème en modifiant le code de mesa), mais j'ai aussi besoin d'un nouveau buffer (un alpha buffer) et ensuite je me sert de ces buffers pour calculer l'éclairage, bref..., jusqu'à maintenant j'ai toujours utilisé des framebuffers objects avec des shaders mais ceci est lent, car, voici le procéder :

Pour toutes les tiles :
        -Dessine moi une tile et remet moi à jour la texture du framebuffer en lisant la texture du dephbuffer et du framebuffer.
        -Dessine moi de nouveau cette tile et remet moi à jour la texture du depthbuffer en lisant la texture du dephbuffer.

Les textures ne se remettent à jour qu'à la fin de l'exécution de mes shaders, et, je ne peux pas non plus écrire dans plusieurs textures à la fois avec un seul shader sinon ça donnerait :

Dessine moi toutes les tiles et remet moi à jour le framebuffer et le dephtbuffer avec le shader. (Chose que je souhaiterais faire!)

Donc je recherche une api qui marche sur une carte graphique ATI Mobility Radeon HD 5470 et qui serait capable de faire ceci :

-Allouer de la mémoire sur la carte graphique. (des buffers)
-Exécuter un programme avec le processeur de la carte graphique qui mets à jour ces buffers. (Car le processeur de la carte graphique est beaucoup plus rapide que celui de l'ordinateur pour effectuer du traitement graphique!)
-Copier le résultat dans une ou plusieurs textures afin que je puisse m'en resservir pour d'autres traitements graphique ou bien pour afficher la scene finale sur la fenêtre.

Si quelqu'un connait une api comme ça ou bien comment en créer une, cela m'aiderait beaucoup!

Dernière modification par Lolichou (Le 02/05/2015, à 17:17)

Hors ligne

#9 Le 02/05/2015, à 17:33

Lolichou

Re : Développer un driver graphique. (Pour exécuter du code avec le GPU)

Bon, apparemment, openCL fonctionne avec mon GPU, c'était juste que je n'avais pas choppé le bon tutoriel, et il est possible de copier le résultat dans une texture openGL, il ne reste donc plus qu'à rechercher des tutoriels pour savoir comment utiliser cette api de bas niveau.

Hors ligne

#10 Le 02/05/2015, à 20:43

tiramiseb

Re : Développer un driver graphique. (Pour exécuter du code avec le GPU)

Là je sèche, désolé smile

Hors ligne

#11 Le 02/05/2015, à 22:30

alius

Re : Développer un driver graphique. (Pour exécuter du code avec le GPU)

Est-ce que tous les objets que tu manipules (surtout ceux sur lesquels tu itères) sont contiguës en mémoire ?


Alius

Hors ligne