나는 스트리밍을 위해 매우 효과적 인 GL_ARB_buffer_storage
과 찢어지지 않도록하는 vsync를 사용하여 스크린 스트리밍 (10ms 미만)에 매우 낮은 대기 시간 텍스처가 필요한 프로그램을 작성하고 있습니다.버퍼링 프레임에서 OpenGL 방지
그러나 NVIDIA 파이프 라인이 차단되기 전에 스왑 버퍼를 호출 할 때 NVidia 파이프 라인이 2-8 프레임을 버퍼링한다는 것을 발견했습니다.이를 방지해야합니다. 내가 무슨 짓을
은 다음
다음 추첨 스레드에서 나는 다음을 수행uint64_t detectPresentTime()
{
// warm up first as the GPU driver may have multiple buffers
for(int i = 0; i < 10; ++i)
glxSwapBuffers(state.renderer);
// time 10 iterations and compute the average
const uint64_t start = microtime();
for(int i = 0; i < 10; ++i)
glxSwapBuffers(state.renderer);
const uint64_t t = (microtime() - start)/10;
// ensure all buffers are flushed
glFinish();
DEBUG_INFO("detected: %lu (%f Hz)", t, 1000000.0f/t);
return t;
}
:
uint64_t presentTime = detectPresentTime();
if (presentTime > 1000)
presentTime -= 1000;
while(running)
{
const uint64_t start = microtime();
glClear();
// copy the texture to the screen
glxSwapBuffers();
const uint64_t delta = microtime() - start;
if (delta < presentTime)
{
glFlush();
usleep(delta);
glFinish();
}
}
이 솔루션은 엔비디아 하드웨어에서 잘 작동하지만를 계산하지보고되고있다 AMD GPU에서 적절한 현재 시간.
더 좋은 방법이 있나요? 프로파일을 제외하고는 보통 glFinish
을 응용 프로그램에서 사용하면 안되지만 GPU 파이프 라인이 프레임을 버퍼링하지 않도록하는 다른 방법을 찾을 수 없습니다.
편집 : 관심있는 사람들을 위해 이것은 Linux에서 FastSync를 효과적으로 에뮬레이션하지만 vsync를 비활성화하지 않습니다.
Edit2가 : 다음을 기다릴 것이 가능이를 사용하여, SGI_video_sync
라는 작은 알려진 OpenGL을 확장가,
uint64_t detectPresentTime()
{
glFinish();
// time 10 iterations and compute the average
const uint64_t start = microtime();
for(int i = 0; i < 10; ++i)
{
glxSwapBuffers(state.renderer);
glFinish();
}
const uint64_t t = (microtime() - start)/10;
DEBUG_INFO("detected: %lu (%f Hz)", t, 1000000.0f/t);
return t;
}
는 OpenGL 위키는 이에 대한 흥미로운 기사가 있습니다 https://www.khronos.org/opengl/wiki/Swap_Interval – bernie