OpenGL в Windows использует тонны ЦП, когда SwapBuffers вызывается в RenderThread

Хорошо, поэтому я столкнулся с некоторыми проблемами с потоками с OpenGL в Windows. Я использую С# .NET для переноса GL. У меня Windows7 x64.

Итак, я попробовал два разных теста. В каждом тесте я визуализирую нетекстурированный четырехугольник (также известный как два треугольника). Судя по тому, что я могу сказать, сбой ЦП, похоже, связан с SwapBuffers.

Однопоточный тест (отлично работает)::

{
Draw stuff;
SwapBuffers;
Sleep(15);
}

Тест RenderingThread (это съедает весь мой процессор):

{
Draw stuff;
SwapBuffers;
//glFinish(); //<< If used this seems to make the CPU usage normal
Sleep(15);
}

Я знаю, что этот пример упрощен, но реальный вопрос заключается в том, почему OpenGL высасывает весь мой процессор при вызове SwapBuffers в другом потоке, отличном от того, в котором работает поток графического интерфейса Windows ?? И почему glFinish() исправляет это? Все говорят не использовать glFinish, поэтому я не уверен, что я делаю неправильно, или OpenGL просто отстой в Windows...?

Я запускаю тот же тест на OSX, процессор кажется нормальным. Я запускаю тот же тест с D3D9 и D3D10 в Windows, процессор работает нормально. Не тестировал на Linux, так как мой L-box не работает.


person zezba9000    schedule 14.05.2011    source источник
comment
Что вы рендерите? (Насколько это сложно) VSync включен или выключен? Какую частоту кадров вы получаете?   -  person Bart    schedule 14.05.2011
comment
Теперь возникает вопрос: действительно ли это потребляет процессорное время или это просто результат (хорошо известного) просчета. Попробуйте заменить этот (закомментированный) glFinish на Sleep(1); если это также снижает потребление вашего процессора, это просто просчет, потому что теперь вместо бездействующего процесса ваш поток рендеринга получает все свободное время процессора. Также попробуйте запустить несколько сложных вычислительных программ и посмотрите, как они будут конкурировать с вашей программой.   -  person datenwolf    schedule 14.05.2011
comment
Все случаи 60fps. Хм, я не использую wglSwapInterval, может ли это быть проблемой в Windows? Я попробую и посмотрю, что это делает.   -  person zezba9000    schedule 14.05.2011
comment
На самом деле большая часть фактического рендеринга выполняется графическим драйвером только тогда, когда он получает сообщение подкачки. До тех пор он в основном собирает вызовы рендеринга и их параметры. Таким образом, если при замене буферов рендеринга расходуется много процессорного времени, это действительно может указывать на то, что драйвер использует программную эмуляцию для некоторых задач рендеринга. Было бы интересно узнать, на каком оборудовании вы проводите тест, обновлены ли драйверы и какие операции рендеринга выполняет ваша программа.   -  person Razzupaltuff    schedule 21.08.2011


Ответы (1)


Эта проблема решается просто:

glFlush();
glFinish();

Перед вызовом::

wglSwapBuffers(dc); // Windows
glxSwapBuffers(dc, handle); // Linux
cglFlushDrawable(ctx); // OS X

Хотя драйверы имеют большое значение для OpenGL в Windows, Windows по-прежнему работает намного лучше с Direct3D.

person zezba9000    schedule 05.02.2012
comment
Это чрезвычайно зависит от драйвера в любой системе, особенно с задействованным OpenGL, поскольку аппаратная и часто драйверная поддержка этого API может быть паршивой, эмулируемой или полностью переведенной в инструкции D3D для оборудования. - person ssube; 05.02.2012
comment
Как я видел, это кажется очень верным. Вот почему использование D3D в Windows является обязательным, если вы заботитесь о производительности. - person zezba9000; 13.02.2012
comment
@LovelyHanibal IDK, что вы делаете, но я рекомендую вам использовать GL только в основном потоке вашего приложения. Просто отправьте туда вызовы GL, если они у вас есть. Контекст GL просто ломается на некоторых платформах, если вы этого не сделаете. - person zezba9000; 07.07.2020