현대 게임에서 더블 또는 트리플 버퍼링으로 어떤 문제가 해결됩니까?


31

이중 (또는 삼중) 버퍼링을 사용하는 원인에 대한 이해가 올바른지 확인하고 싶습니다.

60Hz 새로 고침이있는 모니터는 초당 60 회 모니터 디스플레이를 표시합니다. 모니터가 모니터 디스플레이를 새로 고치면 픽셀 픽셀과 라인 라인을 업데이트합니다. 모니터는 비디오 메모리에서 픽셀의 색상 값을 요청합니다.

지금 게임을 실행하면이 게임은이 비디오 메모리를 지속적으로 조작합니다.

이 게임에서 버퍼 전략 (더블 버퍼링 등)을 사용하지 않으면 다음과 같은 문제가 발생할 수 있습니다.

모니터가 모니터 디스플레이를 새로 고칩니다. 이 시점에서 모니터는 이미 전반 모니터 디스플레이를 새로 고쳤습니다. 동시에 게임은 새로운 데이터로 비디오 메모리를 조작했습니다. 이제 모니터가 후반 모니터에 액세스하여 비디오 메모리에서이 새로운 조작 된 데이터를 표시합니다. 문제가 찢어 지거나 깜빡 일 수 있습니다.

버퍼 전략 사용 사례에 대한 이해가 정확합니까? 다른 이유가 있습니까?

답변:


62

기본적으로 렌더링의 핵심 목표는 모니터에 표시되는 각 프레임이 단일의 일관된 이미지를 나타내는 것입니다. 이를 달성하기 위해 사용되었거나 사용 된 여러 가지 전략이 있습니다.

다음에서는 "vsync"에 대해 언급합니다. Vsync는 모니터가 새로운 화면 이미지를 그리기 시작하는 순간입니다. 그것은 전형적인 CRT 스크린에서 "vblank"가 시작되는 지점입니다. 여기서 스캔 라인은 일시적으로 그리기를 멈추고 모니터의 상단으로 돌아갑니다. 이 순간은 프레임 일관성에 대한 많은 접근 방식에 매우 중요합니다.

"테어 링"은 스크린이 단일 프레임 내에서 두 개의 서로 다른 이미지로 렌더링 될 때 호출되는 것입니다. 예를 들어, 두 개의 화면 이미지를 차례로 표시하려고했지만 모니터가 대신 프레임 1의 위쪽 절반과 프레임 2의 아래쪽 절반을 표시 한 경우 "찢어짐"입니다. 이것은 빈 화면이 아닌 모니터를 그리는 동안 모니터가 읽는 데이터를 변경하기 때문에 발생합니다. (현대 프로그램에서는 일반적으로 사용자가 드라이버 설정에서 vsync 대기를 비활성화했기 때문에 발생합니다)

제로 버퍼

가장 오래된 하드웨어에는 전체 화면 이미지를 담을 수있는 메모리가 부족한 경우가 많으므로 화면 이미지를 그리는 대신 모니터가 해당 선을 그리는 동안 각 스캔 라인의 색상을 개별적으로 지정해야했습니다. 예를 들어, Atari 2600에서는 텔레비전이 실제로 스캔 라인을 그리기 시작하기 전에 스캔 라인의 각 픽셀에 어떤 색이 들어갈 지 지정하기 위해 76 개의 기계 명령 사이클이있었습니다. 그리고 다음 스캔 라인에 대한 내용을 제공하기 위해 76 개의 명령주기를 가졌 습니다.

단일 버퍼

"싱글 버퍼"컨텍스트에서 그릴 때는 모니터에서 읽은 VRAM으로 곧바로 그립니다. 이 접근 방식에서는 "스캔 라인을 경주"합니다. 스캔 라인이 화면 상단에서 이전 프레임의 내용을 그리기 시작하면 그 뒤에 VRAM 그 립니다 . 스캔 라인이 마지막 프레임의 화면 이미지를 그리는 동안 스캔 라인 뒤에 다음 프레임을 그리고 있습니다.

일반적으로, 스캔 라인 이전에 다음 프레임 이미지 그리기를 마치려고합니다. 다시 돌아와서 그리는 픽셀을 추월 하여 스캔 라인 보다 앞서 거나 새로운 것을 넘어서는 것은 아닙니다. 프레임은 이전 프레임이었던 것으로 그릴 수 있습니다.

이러한 이유로 단일 버퍼 렌더링은 일반적으로 스캔 라인을 위에서 아래로 그리고 왼쪽에서 오른쪽으로 그려서 작동했습니다. 다른 순서로 그림을 그리면 스캔 라인이 다시 돌아와서 아직 그리지 않은 "다음"이미지의 비트를 발견 할 수 있습니다.

현대 운영 체제에서는 일반적으로 단일 버퍼를 그릴 수있는 기회가 없지만 30 년 전에는 일반적이었습니다. (지금은 나이가 들었다고 생각합니다. 게임 개발을 처음 시작했을 때의 일입니다.)

더블 버퍼

이것은 이전의 전략 중 하나보다 훨씬 간단합니다.

이중 버퍼링 시스템에는 두 개의 서로 다른 화면 이미지를 저장하기에 충분한 메모리가 있으므로이 중 하나를 "전면 버퍼"와 다른 하나를 "백 버퍼"로 지정합니다. "프론트 버퍼"는 현재 표시되고 있으며 "백 버퍼"는 현재 우리가 그리는 곳입니다.

화면 이미지를 백 버퍼로 그리기를 완료 한 후 vsync가 나올 때까지 기다린 다음 두 버퍼를 서로 바꿉니다. 이런 식으로, 백 버퍼는 프론트 버퍼가되고 그 반대도 마찬가지입니다. 모니터가 아무것도 그리는 동안 전체 스왑이 발생했습니다.

트리플 버퍼

이중 버퍼 접근 방식에서 종종 발생하는 한 가지 문제는 백 버퍼로 그리기를 완료 한 후 버퍼를 교환하고 작업을 계속하기 전에 vsync를 기다리는 것만으로 문제가 발생한다는 것입니다. 우리는 그 시간 동안 계산을 할 수있었습니다! 또한 버퍼간에 스왑을 기다리는 동안 항상 백 버퍼의 이미지가 점점 오래되어 사용자의 인식 대기 시간이 증가합니다.

트리플 버퍼 시스템에서 우리는 하나의 프론트 버퍼와 두 개의 백 버퍼로 세 개의 버퍼를 만듭니다. 아이디어는 이것입니다 :

모니터에 전면 버퍼가 표시되고 후면 버퍼 # 1에 그려집니다. 모니터가 전면 버퍼 그리기를 마치기 전에 백 버퍼 # 1에 그리기를 마치면 vsync를 기다리는 대신 즉시 다음 프레임을 다시 백 버퍼 # 2에 그리기 시작합니다. 완료하고 vsync가 여전히 오지 않으면 백 버퍼 # 1로 다시 그리기 시작합니다. 아이디어는 vsync가 결국 발생하면 백 버퍼 중 하나가 완료되고 하나는 프론트 버퍼로 교체 될 수 있다는 것입니다.

트리플 버퍼링의 이점은 더블 버퍼링 방식에서 vsync를 기다리는 데 걸리는 시간을 잃지 않고 프론트 버퍼로 스와핑 된 이미지가 vsync를 기다린 이미지보다 "더 신선한"것일 수 있다는 것입니다. 8ms. 트리플 버퍼링의 단점은 여분의 화면 이미지를 저장하기 위해 추가 메모리가 필요하고 CPU / GPU 사용량이 증가한다는 것입니다 (vsync를 기다리기 위해 속도를 늦추지 않기 때문에).

일반적으로 최신 드라이버는 종종 배후에서 트리플 버퍼링을 투명하게 수행합니다. 이중 버퍼링을 수행하기 위해 코드를 작성하면 드라이버는 실제로 초기에 제어를 반환하고 코드에서 인식하지 않고도 사용하려는 많은 백 버퍼 간의 스와핑을 내부적으로 처리합니다.

GPU 공급 업체는 현재 트리플 버퍼링을 직접 구현하지 않는 것이 좋습니다. 드라이버가 자동으로 처리합니다.


7
이것은 엄청나게 상세한 답변이며, 화면 좌표 공간과 같은 많은 일들이 그 방식대로 수행되는 이유를 설명합니다. 또한 내 질문에 "왜 4 중 버퍼가 아닌가? Quintuple?" 버퍼 스와핑이 백그라운드에서 발생했음을 알지 못했습니다. 즉, 두 개의 백 버퍼가 최대로 필요하다는 것을 의미합니다. 공감.
lunchmeat317317 년

실제로 쿼드 버퍼링이 있습니다. 입체 영상을위한 이중 버퍼링입니다. swiftless.com/tutorials/opengl/smooth_rotation.html
Narek

@Narek No. 링크에서 인용 : "실제 포인트가 없기 때문에 컴퓨터 그래픽 환경에서 실제로 쿼드 버퍼링을 활성화 할 수 없습니다". 두 개의 서로 다른 뷰에서 동시에 이중 버퍼링을 수행하는 것이 "쿼드 버퍼링"이라고 제안하는 것은 단어 놀이에 지나지 않습니다. 진짜가 아닙니다.
트레버 파월

@TrevorPowell 포함하는 것을 잊어 버린 부분 추가 ​​: "일반적으로 쿼드 버퍼링은 입체 환경에서의 이중 버퍼링을 의미합니다. 예 : 일반적으로 3D 목적을 위해 두 개의 디스플레이가 있으며 각 눈은 이중 버퍼링됩니다." 이제 상황이 더 명확 할 수 있습니다.
Narek

@TrevorPowell 당신의 요점은 완전히 분명합니다. 하나의 렌더 버퍼에 대해 3 개 이상의 버퍼를 갖는 것은 의미가 없습니다.
Narek
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.