четверг, 24 сентября 2009 г.

ID3D11CommandList

Занятно, что в D3D 11 появился этот интерфейс (в 10 его не было, в 9 были какие-то функции для записи/воспроизведения стейтов), в то время как в OpenGL 3.2 дисплейные списки убрали. Слышал, что парни из NVIDIA недовольны таким решением - ещё бы, после стольких лет отладки этих самых списков! Тред на эту тему можно почитать здесь: Siggraph Asia 2008 slides suggestions for OpenGL.

Вся беда в том, что хоть у NVIDIA они и отлажены, но в целом это дикая штуковина. Вот пример:
glNewList(42, GL_COMPILE);
glVertex3f(0,1,0);
glColor3f(1,0,0);
glVertex3f(1,1,1);
glEnd();
glEndList();

glBegin();
glColor3f(0,1,0);
glVertex3f(0,0,0);
glColor3f(0,0,1);
glCallList(42);
// note the lack of glEnd() - it's in the display list!

В общем, комитет отправил эту хрень в преисподнюю, вслед за immediate mode.

В Direct3D 11 схема работы следующая: можно создать один immediate контекст, для которого вызовы складываются в command buffer и выполняются, а можно в дополнение создать множество deferred контекстов, для которых вызовы складываются во внутренний command list, и после вызова ID3D11DeviceContext::FinishCommandList() вы получаете указатель на объект интерфейса ID3D11CommandList, в котором записаны все команды, поданные со времени предыдущего вызова ::FinishCommandList() или со времени создания контекста. Затем этот command list можно выполнить на immediate контексте вызовом ID3D11DeviceContext::ExecuteCommandList().

Сначала я недоумевал, почему есть Finish функция, но нет Begin. Ответ прост - сами по себе любые вызовы для deferred контекста не имеют никакого значения, они не идут в command buffer, а значит, и обрамляющая пара Begin/End - не нужна.

Судя по тому, что написано в SDK, command lists формируются очень быстро (не так медленно, как скажем, стейты через ::Create*State()), их можно формировать каждый кадр, параллельно, на нескольких ядрах в многоядерной системе. Если же драйвер/железо не поддерживают это, то command lists всё равно полезны как средство формирования command buffer, скажем, перед циклом рендеринга. Правда, пока неясно, что именно туда можно складывать - помните, сколько было ограничений в OpenGL с этим: "Certain commands, when called while compiling a display list, are not compiled into the display list but are executed immediately."

Комментариев нет:

Отправить комментарий