2017-12-07 13 views
6

ストリーミング(10ms未満)には非常に短い待ち時間のテクスチャを必要とするプログラムを作成しています。これはストリーミングにはうってつけのGL_ARB_buffer_storageを使用して実装しました。OpenGLによるバッファリングの防止

しかし、ブロックする前にスワップバッファを呼び出すときに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(); 
    } 
} 

このソリューションは、NVIDIAのハードウェア上で素晴らしい作品が、計算しないと報告されていますAMD GPUでの適切な現在の時間。

これを行うより良い方法はありますか?私はglFinishが通常はプロファイリング以外のアプリケーションでは使用されるべきではないことを知っていますが、GPUパイプラインがフレームをバッファリングしないようにする別の方法はありません。

編集:興味のある人にとって、これはLinux上でFastSyncを効果的にエミュレートしますが、vsyncを無効にすることはありません。

EDIT2:おそらく現時点機能が少し異なる実装する必要があります。

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; 
} 
+0

OpenGLのウィキがこのことについて興味深い記事があります。https://www.khronos.org/opengl/wiki/Swap_Interval – bernie

答えて

2

私は答えを見つけ、あまり知られていないOpenGLの拡張機能がありますが、次を待つことが可能である、これを使用して、SGI_video_syncと呼ばれますフレーム。

すなわち:

glFlush(); 
uint remainder; 
glXWaitVideoSyncSGI(1, 0, &remainder); 
関連する問題