2017-12-16 3 views
0

내 컴퓨터 (Lenovo Y40)에 AMD Radeon R9 M275와 일부 내장 그래픽 카드 사이에 이중 그래픽 카드가 설치되어 있지만 사용중인 그래픽 카드와 새 그래픽 카드가 확실하지 않습니다. 컴퓨터 (HP Spectre)에는 Intel HD Graphics 620 카드가 있습니다. 나는 옛날 컴퓨터에 잠시 동안 내 게임 라이브러리를 만들고 있었고 전혀 문제가 없었습니다. 새 컴퓨터를 구해서 코드를 전송하면 속도가 크게 느려졌습니다. 저는 LWJGL 3을 사용하고 있습니다. 시간을 맞추었고 새 컴퓨터에서 "glLinkProgram"을 수행하는 데 약 400ms가 걸리고 기존 컴퓨터에서 약 5ms가 걸렸습니다. 그것은 단지 하드웨어 차이의 원인이 될 수 있지만 실제로 그래픽 카드의 차이는 395ms로 시간을 변경합니까?! 나는 OpenGL과 그래픽 카드를 처음 사용하므로 잘 모르겠습니다. 저는 개인적으로 코드가 필요하다고 생각하지 않습니다. 왜냐하면 그것은 잠시 동안 내 코드가 아니기 때문입니다. LWJGL의 GL20에서 glLinkProgram 메서드입니다. 내가 할 수있는 일이 있습니까, 아니면이 모든 하드웨어 기반입니까?LWJGL glLinkProgram이 처리하는 데 오랜 시간이 걸림

편집

코드

조각 쉐이더

#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; 
    } 
} 

버텍스 쉐이더

#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

그래픽 드라이버는 OpenGL과 같은 API 호출의 런타임 성능과 관련하여 비 결정적 블랙 박스입니다. 이들은 동일한 벤더 드라이버의 여러 버전과 다른 공급 업체 (AMD 대 Intel)에서 다르게 작동 할 수 있습니다. 드라이버는 API 호출 결과가 실제로 사용되거나 필요한 지점 (예 : GL 그리기 호출 또는 스왑 버퍼)까지 수행 할 작업을 연기 할 수 있습니다. 셰이더 코드를 표시하면 다소 도움이됩니다. 주변을 인터넷 검색하는 것은 일부 드라이버는 큰 균일 한 배열/버퍼 크기 문제가 있음을 보여주는 것 같습니다. – httpdigest

+0

도움이됩니다. 고맙습니다. 누구나 볼 수있는 쉐이더 코드를 게시했습니다. 나는 크기가 100 인 유니폼 어레이가 있지만 요즘 개인적으로는 컴퓨터 용량면에서 그렇게 큰 것은 아니지만 잘못 될 수 있습니다. –

답변

0

그래픽 드라이버 코드의 일부인 GLSL 컴파일러의 구현 간에는 분명히 차이가 있습니다. 인텔 컴파일러는 AMD가 수행하는 최적화 작업을 수행하지 못할 수도 있습니다. 이것은 가지고있는 하드웨어의 힘 때문일 수 있습니다. Intels GPU는 여전히 GPU를 해독하지 않으므로 코어 수, 프로세서 수 및 메모리 수가 제한됩니다. 그래서 컴파일러는 최적화를 할 수있는 방법에 의해 제한됩니다. GPU를 버리면 버텍스/조각/텍스처 프로세서가 말할 수있는 전용 비디오 메모리가 없다는 것을 의미합니다. 따라서 모든 것이 마더 보드에서 사용 가능한 버스를 통해 이루어져야하며 기존 램의 작은 부분을 비디오 메모리로 사용합니다. (인텔에서 새 GPU에 대해 잘 모르겠지만 GPU가 의미하는 점은 무엇입니까?)

내부적으로 4 개의 플로트 인 균일 한 라이트 구조가 있습니다. 모든 변수에 대해 uniform 또는 attributes 컴파일러는 일부 메모리 위치 만 제외하고 일부 슬롯을 할당합니다. 100 * 8 -> 많은 메모리 위치와 100 * 8 * sizeof (float) -> 많은 실제 메모리를 고려하십시오.

균일 한 컴파일러 또는 드라이버로 이것을 전달할 때 변수의 값만 런타임에 알 수 있으므로 모든 최적화를 수행 할 수 없습니다. 그래서 당신은 모든 2 개의 조명이 여전히 100 개가 예약되어있을 것입니다. 그리고 이것은 하드웨어 때문에 최적의 링크를 할 수 없기 때문에 드라이버의 한계라고 생각합니다.

당신은 다른 하드웨어에 프로파일을 시도 할 수 있습니다. 또한 조명 배열의 크기를 단지 1로 줄이고 링크 시간이 향상되는지 확인하십시오.

관련 문제