2017-12-16 6 views
0

Mein alter Computer (Lenovo Y40) hatte eine Dual-Grafikkarte zwischen einer AMD Radeon R9 M275 und einer Intel integrierten Grafikkarte, aber ich bin mir nicht sicher, welche Grafikkarte er verwendet hat und meine neue Computer (HP Spectre) verfügt über eine Intel HD Graphics 620-Karte. Ich habe meine eigene Spielebibliothek für eine Weile auf meinem alten Computer erstellt und hatte nie irgendwelche Probleme. Als ich meinen neuen Computer bekam und den Code übertrug, lief er deutlich langsamer. Ich verwende LWJGL 3. Ich habe es zeitlich festgelegt und es dauert etwa 400ms, um "glLinkProgram" auf meinem neuen Computer zu machen, und es dauert ungefähr 5ms auf meinem alten Computer. Es könnte nur eine Ursache für Hardware-Unterschiede sein, aber würde es wirklich nur der Unterschied zwischen einer Grafikkarte sein, die die Zeit um 395ms ändert ?! Ich bin neu in der Verwendung von OpenGL und Grafikkarten, also bin ich mir nicht sicher. Ich persönlich glaube nicht, dass Code hier benötigt wird, weil es nicht mein eigener Code ist, der eine Weile dauert. Es ist die glLinkProgram-Methode in GL20 von LWJGL. Gibt es etwas, was ich tun kann oder ist das alles Hardware basiert?LWJGL glLinkProgram dauert sehr lange

EDIT

-Code

Fragment Shader

#version 330 core 

layout (location = 0) out vec4 color; 


in DATA 
{ 
    vec2 tc; 
    vec3 position; 
} fs_in; 

struct Light 
{ 
    vec2 pos; 
    float size; 
    float lowLightValue; 
}; 

uniform Light lights[100]; 
uniform sampler2D tex; 
uniform int enabled =0; 

float high = 0; 
float average =0; 
bool isInsideLight = false; 
vec4 highcol = vec4(0); 


bool greater(vec4 l, vec4 r) 
{ 
    float lbright = sqrt(0.2126*pow(l.r,2))+(0.7152*pow(l.g,2))+(0.0722*pow(l.b,2)); 
    float rbright = sqrt(0.2126*pow(r.r,2))+(0.7152*pow(r.g,2))+(0.0722*pow(r.b,2)); 
    if(lbright > rbright) 
    { 
     return true; 
    } 
    return false; 
} 

void main() 
{ 
    color = texture(tex,fs_in.tc); 
    if(enabled == 1) 
    { 
//  float len = length(fs_in.position.xy-lights[0].pos); 
//  float lenr = len/lights[0].size; 
//  float llv = lights[0].lowLightValue; 
//  if(len > lights[0].size) 
//  { 
//   color *= llv; 
//  } 
//  else 
//  { 
//   color *= 1-((1 - llv)/lights[0].size)*len; 
//  } 
//  vec4 color2; 
     for(int i =0;i<lights.length();i++) 
     { 
      if(lights[i].lowLightValue != 0) 
      { 
       float len = length(fs_in.position.xy-lights[i].pos); 
       if(len <= lights[i].size) 
       { 
        isInsideLight = true; 
        break; 
       } 
      } 
     } 
     int numLights=0; 
     average =0; 
     for(int i = 0;i < lights.length();i++) 
     { 

      if(lights[i].lowLightValue != 0) 
      { 
       float len = length(fs_in.position.xy-lights[i].pos); 
       float llv = lights[i].lowLightValue; 
       if(!isInsideLight) 
       { 
        average += llv; 
        numLights++; 
       } 
       else 
       { 
        if(len <= lights[i].size) 
        { 
         float num = 1-((1-llv)/lights[i].size)*len; 
         if(num > average)//Getting the highest 
         { 
          average = num; 
         } 
        } 
       } 
//    if((1/lenr) > 1) 
//    { 
//     lenr = 0; 
//    } 
//    float col = (lenr*llv)+llv; 
//    vec4 ncol = color*col; 
//    if(greater(ncol,highcol)) 
//    { 
//     highcol = ncol; 
//    } 
       //if(col>high) 
       //{ 
       // high = col; 
       //} 
      } 
      else 
      { 
       break; 
      } 
     } 

     if(!isInsideLight) 
      color *= average/numLights; 
     else 
      color *= average; 
//  color = highcol; 
    } 
} 

Vertex Shader

#version 330 core 

layout (location = 0) in vec4 position; 
layout (location = 1) in vec2 tc; 

uniform mat4 pr_matrix; 
uniform mat4 ml_matrix = mat4(1.0); 
uniform mat4 vw_matrix = mat4(1.0); 

out DATA 
{ 
    vec2 tc; 
    vec3 position; 
} vs_out; 

void main() 
{ 
    gl_Position = pr_matrix * vw_matrix * ml_matrix * position; 
    vs_out.tc = tc; 
    vs_out.position = vec3(ml_matrix*position); 
} 
+0

Grafiktreiber sind undeterministische Black Boxes, wenn es um die Laufzeitleistung von API-Aufrufen wie OpenGL geht. Sie können sich über mehrere Versionen desselben Lieferantentreibers und zwischen verschiedenen Anbietern (AMD vs. Intel) unterschiedlich verhalten. Treiber können die auszuführende Arbeit bis zu dem Punkt verschieben, an dem das Ergebnis des API-Aufrufs tatsächlich verwendet wird/benötigt wird (z. B. bei einem GL-Zeichenaufruf oder sogar bei Auslagerungspuffern). Es wäre hilfreich, deinen Shader-Code anzuzeigen. Googlen herum scheint zu zeigen, dass einige Treiber Probleme mit großen einheitlichen Array/Puffergrößen haben. – httpdigest

+0

Dies ist hilfreich. Vielen Dank. Ich habe meinen Code für meine Shader gepostet, damit jeder ihn sehen kann. Ich habe ein einheitliches Array der Größe 100, aber ich persönlich würde in Bezug auf Computerkapazität heutzutage nicht so groß nennen, aber ich könnte falsch liegen. –

Antwort

0

Es gibt definitiv einen Unterschied zwischen der Implementierung des GLSL-Compilers, der Teil des Grafiktreibercodes ist. Intel-Compiler ist möglicherweise nicht in der Lage, die von AMD vorgenommene Optimierung durchzuführen. Dies könnte wegen der Macht der Hardware sein, die Sie haben. Intels GPU sind immer noch keine getrennten GPUs, so dass die Anzahl der Kerne, die Anzahl der Prozessoren und die Anzahl der Speicher begrenzt sind. Daher ist der Compiler durch die Art und Weise, wie er Optimierungen vornehmen kann, eingeschränkt. Durch diskrete GPU bedeutet das auch, dass sie keinen dedizierten Videospeicher haben, mit dem Vertex-/Fragment-/Textur-Prozessoren sprechen können. Also muss das alles über den Bus geschehen, der auf dem Motherboard verfügbar ist, und es wird einen kleinen Teil des existierenden RAM als Videospeicher nehmen. (Ich bin nicht sicher über neue GPU von Intel, aber das ist was auf Chip GPU bedeutet)

Sie haben einheitliche Array von Light-Struktur, die intern 4 Floats ist. Für alle Variablen uniform oder Attribute wird der Compiler einige Slots zuweisen, die nichts anderes als einige Speicherplätze sind. Wenn Sie 100 * 8 -> so viele Speicherplätze und 100 * 8 * sizeof (float) -> so viel tatsächlichen Speicher betrachten.

Da Sie dies als einheitliche Compiler oder Treiber übergeben können keine Optimierungen wie der Wert der Variablen wird nur zur Laufzeit wissen. Es könnte also sein, dass nur noch 2 Lichter übrig bleiben, denn alle 100 sind reserviert, und ich denke, das ist eine Einschränkung des Treibers aufgrund der Hardware, die es nicht optimal verbinden kann.

Sie könnten versuchen, es auf anderer Hardware zu profilieren. Versuchen Sie auch, die Größe des Licht-Arrays auf nur 1 zu reduzieren und sehen Sie, ob sich die Link-Zeit verbessert.

Verwandte Themen