понедельник, 10 ноября 2008 г.

Добавлен встроенный профайл

Добавил в движок встроенный профайл. По очень простой схеме,
некий класс содержащий данные о текущей строке имени файла и имени функции. Этот класс имеет конструктор с такими параметрами. С помощью макроса
#define PROFILE Profile::ProfileData data(__FILE__, __LINE__, __FUNCTION__);
можно в начале любой функции добавлять отсчёт времени. В конструкторе запоминается стартовое время работы. В деструкторе формируется строка в виде "File, line, function, time"
и рассчитывается время работы функции, данные добавляются с список. Все банально и просто. Нужно ещё решить как-то проблему мигания значение цифр, что происходит из-за разброса значений времени.

12 комментариев:

orange комментирует...

Правильно, давно пора!
Способ я такой подсмотрел давно в исходниках UT и активно использую не только для профайлеров.

Хотелось бы узнать как боролся с проблемой установки текстурных самплеров в GLSL.

Andrey комментирует...

orange
Итак насчёт работы с самплерами в GLSL, полученного из Cg кода. Пока в GLSL я не передаю никакие самплеры. Потому у меня и не все шейдеры работают которые я хотел переделать на профили glslv/glslf. Пока был сделан переход из GL_ARB_vertex_program/GL_ARB_fragment_program для шейдеров использующихся для от рисовки объектов в ShadowMap, и то те которые не используют текстур. Например деревья используют текстуру что-бы не рисовать пиксели с каким-то значением альфы.
В будущем я думаю сделать передачу самплеров в GLSL, полученный из Cg кода. Но есть 1 проблема, после вызова cgProgram, из созданной программы через профили glslf никак нельзя вытянуть имя uniform переменной определяющий текстурный самплер. Я не могу понять почему так. Так что я пока думаю что это нужно делать ручками, разбирая GLSL код. Я думаю это будет не проблема. Ну и потом получить index через glGetUniformLocationARB
и по порядку записать в массив. При установке шейдера все текстуры выставить по порядку, перебирая имена uniform переменных.К примеру у меня в рендере все выставленные текстуры записываются в массив. В общем очень плохо сделали при проектировании GLSL требование выставлять текстуру по имени. Это очень неудобно. Да простят меня фанаты/поклонники OpenGL API.

orange комментирует...

В общем очень плохо сделали при проектировании GLSL требование выставлять текстуру по имени. Это очень неудобно. Да простят меня фанаты/поклонники OpenGL API.

Прощаю =)
Здесь полностью с тобой согласен, неудобно, однако легко объяснимо - таким образом облегчается Run-Time часть драйвера отвечающего за GLSL. Ведь в конечном итоге мы имеем дело с sampler-unit. Я думаю что и в D3D тоже в конечном итоге привязка идет к sampler-unit, только делается это уже в Run-Time'е облегчая жизнь программиста. Скорее всего ARB сделала такой выбор для того чтобы программисты четко представляли что происходит.

Andrey комментирует...

Ну к примеру в Direct3D9/Direct3D10
текстуры попадают в текстурные самплеры - текстурные регистры s0..sn
и можно работать без всяких имен.
Это если не использовать ID3DXEffec/ID3D10Effect, а использовать напрямую IDirect3DPixelShader9/ID3D10PixelShader
тоже самое в GL_ARB_vertex_program.

Neill комментирует...

неплохо придумал с профайлером, а мог объяснить что за такой разброс значений времени?
> Нужно ещё решить как-то проблему мигания значение цифр, что происходит из-за разброса значений времени.

Andrey комментирует...

neill
Ну очень быстро меняются значения что трудно понять что за цифра в данный момент. Причем изменения значений разное по ходу дела в разных кадрах. Нужно как-то это усреднять n значений за время t и тогда выводить. Тем более я пользуюсь высокоточным Win32 таймером
функции используя функции: QueryPeformanceFrequency/QueryPerformanceCounter
Ну под Unix системами есть аналог gettimeofday, если надумаю портировать. Само собой может прыгать. Возможно проблема где-то ещё. FPS кстати так не прыгает. Но дробные значения у него меняются. Речь идет о долях мили секунд, поэтому возможно было это ожидать.

Neill комментирует...

ясно, теперь понял о чем ты... да это известная проблема, ну думаю её не будет сложно побороть. например вычислять среднее значение для каждого счетчика и выводить через определенный промежуток времени...

Andrey комментирует...

Да, именно так я и планирую сделать.
Еще думаю добавить число вызовов для текущей функции, думаю тоже будет полезная информация.

Arseny Kapoulkine комментирует...

Про семплеры в glsl.

В pre D3D10 железе (про d3d10 железо не знаю ничего) есть такая штука, семплер. У нее есть какие-то настройки - настройки, которые типично называются sampler state (фильтрация, maxlod, etc.), и настройки которые типично называются texture (адрес данных текстуры, кол-во мипов, размерность, формат).

В D3D9 эта штука повторяется - есть для каждого, хм, стейджа семплер стейт и текстура, в коде шейдера семплер статически привязан к номеру стейджа либо явным указанием register(s0), либо аллокацией регистров при компиляции.

В GL, насколько я помню, можно в любой момент перепривязать семплер к другой текстурной стадии, вызвав glUniform1i на нужный параметр.

Железо такого не умеет. По крайней мере, железо которое я знаю. Боюсь, радости драйверописателям это не прибавляет - скорее всего такой glUniform1i приводит к перефигачиванию собранного микрокода шейдера...

orange комментирует...

Arseny Kapoulkine
В GL, насколько я помню, можно в любой момент перепривязать семплер к другой текстурной стадии, вызвав glUniform1i на нужный параметр.

Железо такого не умеет. По крайней мере, железо которое я знаю. Боюсь, радости драйверописателям это не прибавляет - скорее всего такой glUniform1i приводит к перефигачиванию собранного микрокода шейдера...


Позвольте не согласиться.
Вы написали "можно в любой момент перепривязать семплер к другой текстурной стадии". По моему здесь как-раз наоборот - мы именно привязываем текстуру к текстурному блоку, да у блока есть sampler-state, но смена текстуры на этот sampler-state не влияет, и при непосредственно выборке sampler-state расскажет КАК нужно семплировать текстуру. Поэтому tex2D абсолютно пофигу откуда делать выборку, ибо glUniform1i задает просто int - номер текстурного блока из которого на момент выборки брать текстуру и параметры самплера. Зачем пересобирать микрокод?

С ув. =[ 0r@ngE ]=

Arseny Kapoulkine комментирует...

Ну, либо пересобирать микрокод, либо в момент скажем DrawElements брать настройки из source слота (значение параметра glsl семплера) и переставлять в target (индекс семплера, выборка из которого прописана в микрокод).

orange комментирует...

Arseny Kapoulkine
либо в момент скажем DrawElements брать настройки из source слота (значение параметра glsl семплера) и переставлять в target (индекс семплера, выборка из которого прописана в микрокод)

Этот вариант мне кажется более логичным, т.к. разработка GLSL велась ARB в тесном сотрудничестве с IHV (nVidia, ATI etc.) поэтому не думаю что они бы разрешили такой вариант чтобы потом страдать с написанием драйверов и уж тем более если бы это противоречило устройству железок.

ЗЫ. Очень приятно общаться с людьми Вашего уровня, я всегда стараюсь почерпнуть много для себя интересного, с огромным удовольствием читаю Ваш блог, спасибо Вам.

С ув. =[ 0r@ngE ]=