OpenGL은 최하위 수준에서 어떻게 작동합니까? [닫은]


84

OpenGL / DirectX 프로그램을 작성하는 방법을 이해하고 그 뒤에있는 수학 및 개념적 내용을 알고 있지만 GPU-CPU 통신이 낮은 수준에서 어떻게 작동하는지 궁금합니다.

삼각형을 표시하고 카메라를 45도 회전시키는 C로 작성된 OpenGL 프로그램이 있다고 가정 해 보겠습니다. 이 프로그램을 컴파일하면 일련의 ioctl-calls로 바뀌고 gpu 드라이버는 적절한 명령을 gpu에 보냅니다. 여기에서 삼각형을 회전하고 적절한 색상으로 적절한 픽셀을 설정하는 모든 논리가 연결됩니다. 에? 아니면 프로그램이 GPU에로드되고 회전 등을 계산하는 "gpu 프로그램"으로 컴파일됩니까? 아니면 완전히 다른 것이 있습니까?

편집 : 며칠 후 나는 기본적으로 질문에 답하는이 기사 시리즈를 찾았습니다. http://fgiesen.wordpress.com/2011/07/01/a-trip-through-the-graphics-pipeline-2011-part- 1/


OpenGL 사양은 명령이 클라이언트 / 서버 모드로 전송된다는 것을 명시합니다. 사양이 너무 광범위하여 OpenGL 구현에 사용되는 특정 기술을 결정할 수 없습니다.
Luca

답변:


86

OpenGL 자체는 프론트 엔드 API 일 뿐이며 구현이 사양을 준수하고 결과가 이에 부합하는 한 원하는 방식으로 수행 할 수 있기 때문에이 질문에 답하기가 거의 불가능합니다.

질문은 다음과 같을 수 있습니다. OpenGL 드라이버가 최하위 수준에서 어떻게 작동합니까? 이제 드라이버가 일부 하드웨어에 밀접하게 연결되어 있기 때문에 일반적으로 대답 할 수 없습니다. 개발자가 설계 한대로 작업을 다시 수행 할 수 있습니다.

따라서 질문은 "OpenGL과 그래픽 시스템 뒤에서 평균적으로 어떻게 보이는가?"여야합니다. 아래에서 위로 살펴 보겠습니다.

  1. 가장 낮은 수준에는 일부 그래픽 장치가 있습니다. 요즘 이들은 동작을 제어하는 ​​레지스터 세트 (정확히 장치에 따라 달라짐)를 제공하는 GPU로 셰이더 용 프로그램 메모리, 입력 데이터 (정점, 텍스처 등) 용 대량 메모리 및 나머지에 대한 I / O 채널이 있습니다. 데이터 및 명령 스트림을 수신 / 전송하는 시스템의.

  2. 그래픽 드라이버는 GPU 상태 및 GPU를 사용하는 모든 리소스 응용 프로그램을 추적합니다. 또한 응용 프로그램에서 보낸 데이터를 변환하거나 다른 처리를 담당합니다 (텍스처를 GPU에서 지원하는 픽셀 형식으로 변환하고 GPU의 기계어 코드에서 셰이더를 컴파일합니다). 또한 응용 프로그램에 대한 추상적 인 드라이버 종속 인터페이스를 제공합니다.

  3. 그런 다음 드라이버 종속 OpenGL 클라이언트 라이브러리 / 드라이버가 있습니다. Windows에서는 opengl32.dll을 통해 프록시에 의해로드되며 Unix 시스템에서는 다음 두 위치에 있습니다.

    • X11 GLX 모듈 및 드라이버 종속 GLX 드라이버
    • 및 /usr/lib/libGL.so에는 직접 렌더링을위한 드라이버 종속 항목이 포함될 수 있습니다.

    MacOS X에서 이것은 "OpenGL 프레임 워크"입니다.

    OpenGL 호출을 (2)에 설명 된 드라이버 부분의 드라이버 특정 기능에 대한 호출로 변환하는 것은이 부분입니다.

  4. 마지막으로 실제 OpenGL API 라이브러리, Windows의 opengl32.dll 및 Unix /usr/lib/libGL.so; 이것은 대부분 명령을 OpenGL 구현에 적절하게 전달합니다.

실제 의사 소통이 어떻게 발생하는지 일반화 할 수 없습니다.

Unix에서 3 <-> 4 연결은 소켓 (예, 원하는 경우 네트워크를 통해) 또는 공유 메모리를 통해 발생할 수 있습니다. Windows에서 인터페이스 라이브러리와 드라이버 클라이언트는 둘 다 프로세스 주소 공간에로드되므로 그렇게 많은 통신이 아니라 간단한 함수 호출과 변수 / 포인터 전달입니다. MacOS X에서 이것은 Windows와 유사합니다. 단지 OpenGL 인터페이스와 드라이버 클라이언트 사이에 분리가 없다는 점만 있습니다 (MacOS X가 새로운 OpenGL 버전을 따라 잡는 데 너무 느리기 때문에 항상 새로운 버전을 제공하려면 전체 운영 체제 업그레이드가 필요합니다.) 뼈대).

3 <-> 2 사이의 통신은 ioctl, 읽기 / 쓰기 또는 일부 메모리를 프로세스 주소 공간에 매핑하고 해당 메모리가 변경 될 때마다 일부 드라이버 코드를 트리거하도록 MMU를 구성 할 수 있습니다. 이것은 커널 / 유저 랜드 경계를 항상 넘어야하기 때문에 모든 운영 체제에서 매우 유사합니다. 궁극적으로 시스템 호출을 거치게됩니다.

시스템과 GPU 간의 통신은 주변 버스와 정의 된 액세스 방법을 통해 이루어집니다. 따라서 PCI, AGP, PCI-E 등은 Port-I / O, Memory Mapped I / O, DMA, IRQ를 통해 작동합니다.


1
이 설명은 OpenGL 특성이 거의없는 너무 낮고 일반적 일 수 있습니다. 대략 컴퓨터에있는 모든 하드웨어 구성 요소에 적용됩니다.
v.shashenko 2016

1
@ v.shashenko : 물론입니다. 어떤 하드웨어 구성 요소와 관계없이이 일반적인 체계를 따릅니다. 그러나 OpenGL은 그냥 사양하고있어, 소프트웨어의 특정 부분 아니다 아무것도 사양에 맞는 올바른 구현입니다. 그리고 결국 OpenGL 구현은 GPU와 통신하기 때문에 하드웨어 대면 API가 구현되는 것과 거의 동일한 스크립트를 따릅니다. " The ONE "OpenGL 구현 없기 때문에 이보다 더 구체적이되는 것은 불가능합니다 . 그리고 모든 구현은 조금씩 다릅니다.
datenwolf

1
@ v.shashenko : 더 자세한 정보를 원하면 특정 구현에 대해 문의해야합니다. 예를 들어 X11 + GLX + DRI → Mesa / AMDGPU → Linux-KMS + DRM (Direct Rendering Manager)이라고합니다. 그리고 이러한 각 구성 요소는 매우 많은 세부 사항을 포함하는 다소 복잡한 짐승이므로 각 구성 요소의 작동 방식에 대한 세부 정보로 책을 채울 수 있습니다. 그러나 그것은 Linux-AMDGPU 구현을 설명합니다. 그러나 Linux + NVidia는 완전히 다른 짐승입니다. 그리고 Windows에서는 다시 다릅니다.
datenwolf

우리가 며칠 동안 대화를 나눴다는 것을 기억하십니까? 뭔가 알고 싶을 때 연락하는 방법을 알고 싶었습니다.?
Suraj Jain

그날 당신이 가르친 것은 많은 의심을 없애고 새로운 것을 만들었지 만 전반적으로 저는 우리가 화면에 창과 아이콘을 그리는 것이 마술이라고 생각하지 않습니다.
Suraj Jain

23

이 프로그램을 컴파일하면 일련의 ioctl-calls로 바뀌고 gpu 드라이버는 적절한 명령을 gpu에 보냅니다. 여기에서 삼각형을 회전하고 적절한 색상으로 적절한 픽셀을 설정하는 모든 논리가 연결됩니다. 에? 아니면 프로그램이 GPU에로드되고 회전 등을 계산하는 "gpu 프로그램"으로 컴파일됩니까?

당신은 멀지 않습니다. 프로그램은 설치 가능한 클라이언트 드라이버를 호출합니다 (실제로는 드라이버가 아니며 사용자 공간 공유 라이브러리입니다). 이는 ioctl 또는 유사한 메커니즘을 사용하여 데이터를 커널 드라이버에 전달합니다.

다음 부분에서는 하드웨어에 따라 다릅니다. 오래된 비디오 카드에는 "고정 기능 파이프 라인"이라는 것이있었습니다. 비디오 카드에는 매트릭스를위한 전용 메모리 공간과 텍스처 조회, 블렌딩 등을위한 전용 하드웨어가있었습니다. 비디오 드라이버는 이러한 각 장치에 대해 올바른 데이터와 플래그를로드 한 다음 DMA를 설정하여 정점 데이터 (위치 , 색상, 텍스처 좌표 등).

최신 하드웨어에는 비디오 카드 내부에 프로세서 코어 ( "셰이더")가 있으며, CPU와는 각각 훨씬 느리게 실행되지만 병렬로 작동하는 프로세서 코어가 더 많습니다. 이러한 비디오 카드의 경우 드라이버는 GPU 셰이더에서 실행할 프로그램 바이너리를 준비합니다.


20

프로그램은 특정 GPU 용으로 컴파일되지 않았습니다. OpenGL을 구현할 라이브러리에 동적으로 연결됩니다. 실제 구현에는 OpenGL 명령을 GPU로 전송하고, 소프트웨어 폴백을 실행하고, 셰이더를 컴파일하여 GPU로 전송하거나, OpenGL 명령에 대한 셰이더 폴백을 사용하는 것이 포함될 수 있습니다. 그래픽 환경은 상당히 복잡합니다. 고맙게도 링크는 대부분의 드라이버의 복잡성으로부터 당신을 격리시켜 드라이버 구현자가 자신이 적합하다고 생각하는 기술을 자유롭게 사용할 수 있도록합니다.


18

C / C ++ 컴파일러 / 링커는 정확히 한 가지를 수행합니다. 즉, 텍스트 파일을 CPU에서 실행되는 일련의 기계 별 opcode로 변환합니다. OpenGL과 Direct3D는 C / C ++ API 일뿐입니다. 그들은 당신의 C / C ++ 컴파일러 / 링커를 GPU 용 컴파일러 / 링커로 마술처럼 변환 할 수 없습니다.

작성하는 모든 C / C ++ 코드는 CPU에서 실행됩니다. OpenGL / Direct3D에 대한 호출은 경우에 따라 정적 또는 동적 C / C ++ 라이브러리를 호출합니다.

"gpu 프로그램"이 작동하는 유일한 장소는 코드가 명시 적으로 셰이더를 생성하는 경우입니다. 즉, 셰이더의 컴파일 및 링크를 유발하는 OpenGL / D3D로 API 호출을 수행하는 경우입니다. 이를 위해 C / C ++ 컴파일 타임이 아닌 런타임에 일부 셰이더 언어로 셰이더를 나타내는 문자열을 생성하거나로드합니다. 그런 다음 셰이더 컴파일러를 통해이를 밀어 내고 해당 셰이더를 나타내는 해당 API의 개체를 다시 가져옵니다. 그런 다음 특정 렌더링 명령에 하나 이상의 셰이더를 적용합니다. 이러한 각 단계는 앞서 언급 한대로 CPU에서 실행되는 C / C ++ 코드의 방향으로 명시 적으로 발생합니다.

많은 셰이더 언어는 C / C ++와 유사한 구문을 사용합니다. 그러나 이것이 C / C ++와 동등하게 만들지는 않습니다.


나는 늦게 OpenGL을 배우고 있는데 왜이 모든 "셰이더 프로그램"이 리터럴 문자열로 쓰여진 코드에서 보이는지 궁금해했습니다. 당신이 말했듯이, 그들은 런타임에 컴파일됩니다. 일부 Android OpenGL ES 코드에서 몇 가지 예를 보았습니다. 그런 다음 iPhone 용 코드도 보았습니다. 분명히 iPhone에는 iPhone의 CPU보다 훨씬 빠르게 부동 소수점 연산을 수행 할 수있는 4 개의 벡터 프로세서가 있습니다.
eggie5

1
대부분의 "고정 함수 파이프 라인"은 이제 기본 셰이더 프로그램 집합에 의해 구현됩니다. 셰이더를 얻기 위해 명시 적으로 셰이더를 요청할 필요는 없습니다.
Ben Voigt 2011-06-19

1
@Ben Voigt : 맞습니다.하지만 아무도 말하지 않으면 그 차이를 말할 수 없습니다.
Nicol Bolas 2011 년

1
이 질문이 숨겨진 세부 사항에 관한 것이 아니라면 어떤 태도를 취하는 것이 합리적 일 수 있습니다.
Ben Voigt 2011-06-19
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.