воскресенье, 20 декабря 2009 г.

Пров

Поставил безлимитку - ну и провайдер попался! amd.com и nvidia.com блокируют, code.google.com блокирует... Приходится выходить через прокси-сервер.

Не любят нас за кордоном :(

Direct3D 11 and Text Drawing

В 9 и 10 D3DX были классы для вывода текста (конкретно в 10 это ID3DXFont10). Замечательно так работали: задаём параметры шрифта (аналогично структуре LOGFONT), шрифт рендерится в текстуру, потом делаем Font->DrawText() и всё. В Direct3D 11 D3DX совершил очередной round-trip: если при переходе с 9 на 10 Effect FX перекочевал в ядро, то в 11 - обратно в D3DX :) Кроме того, фреймворк доступен в виде исходного кода, а не библиотеки (посмотрев, сколько там говна, я вообще решил не юзать FX). А вместе с изменениями в FX Microsoft убрал такие классы как ID3DXFont10, ID3DXMesh10, ID3DXSprite10 и т. д. Почти ничего этого я не использовал, но вот быстрый вывод шрифта в маленьких аппах через ID3DXFont10 был полезен.

Озадачившись выводом шрифта с новым SDK, я решил выводить его через GDI. Но напрямую GDI и D3D не дружат - текст ужасно мерцает. Полазив по SDK, я нашёл, как делать правильно.

1) При создании swap chain указываем флаг DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE.
2) Формат back-буфера должен быть DXGI_FORMAT_B8G8R8A8_UNORM_SRGB или DXGI_FORMAT_B8G8R8A8_UNORM (порядок RGBA не поддерживается).
3) Количество отсчётов в back-буфере должно быть равным 1.
4) Далее необходимо получить интерфейс поверхности (новый интерфейс в DXGI 1.1):

IDXGISurface1* pSurface1 = NULL;
pSwapChain->GetBuffer(0, __uuidof(IDXGISurface1), (void**)&pSurface1);

У этого интерфейса есть методы GetDC() и ReleaseDC(). Вывод текста средствами GDI можно делать между этими двумя вызовами:

HDC hDC;
pSurface1->GetDC(FALSE, &hDC);
...
//Draw on the DC using GDI
...
//When finish drawing relase the DC
pSurface1->ReleaseDC(NULL);

5) После необходимо заново прицепить render target окна, т. к. он отвязывается. У меня, если этого не делать, рантайм падает в D3D11SDKLayers.dll.

пятница, 18 декабря 2009 г.

Direct3D 11 Inspection

Нашёл несколько интересных мест в Direct3D 11.

Первое - D3D11_DEPTH_STENCIL_VIEW_DESC. У этой структуры появилось дополнительное поле UINT Flags (в 10 версии его не было). Я обнаружил это, когда прямой копипаст DX10-кода в DX11 не заработал (в дополнительном поле был мусор и рантайм возвращал ошибку). В SDK по этому поводу написано следующее:
A value that describes whether the texture is read only. Pass 0 to specify that it is not read only; otherwise, pass one of the members of the D3D11_DSV_FLAG enumerated type:

D3D11_DSV_READ_ONLY_DEPTH
Indicates that depth values are read only.
D3D11_DSV_READ_ONLY_STENCIL
Indicates that stencil values are read only.
В пояснении написано:
Limiting a depth-stencil buffer to read-only access allows more than one depth-stencil view to be bound to the pipeline simultaneously, since it is not possible to have a read/write conflicts between separate views.
Я так понимаю, это сделано для того, чтобы можно было одну и ту же depth/stencil текстуру одновременно прицепить как render target на запись и как shader resource view на чтение в шейдере, при этом разбросав чтение и запись по depth/stencil. Иначе непонятна формулировка "allows more than one depth-stencil view to be bound to the pipeline simultaneously", т. к. методы ID3D11DeviceContext::OMSetRenderTargets() и ID3D11..Context::OMSetRenderTargetsAndUnorderedAccessViews() принимают только ОДИН depth/stencil view. (кстати, о последнем методе: в SDK опять напортачили секретарши майкрософта, типы параметров отличаются от таковых в D3D11.h). К тому же неясно, зачем вообще подключать одновременно два depth/stencil view (буфера) к пайплайну. Получается, речь идёт именно о OM/PS конфликте. Но и в этом свете приведённая формулировка туманна, т. к. PS принимает именно resource view, а не depth-stencil view.

В общем, как-то всё туманно и неясно, как конкретно использовать новое преимущество. Пишем в depth, а в шейдере читаем только stencil из того же самого буфера? Пишем в stencil, в шейдере читаем только depth?

Ещё один интересный найдёныш из Direct3D 11, на этот раз в HLSL attributes. Помимо прочих, появился новый атрибут earlydepthstencil. Назначение - ФОРСИРОВАТЬ выполнение early z/stencil тестов до пиксельного шейдера. Как известно, железо может это делать только при соблюдении определённых условий (например, из шейдера не пишется глубина), а если они нарушаются, то early тесты отключаются.

Кстати, вот мои мысли, высказанные два года назад по этому поводу:


Так что мои мысли оказались в каком-то роде пророческими. Интересно, насколько новый атрибут устойчив к различного рода пакостям? Например, если попытаться писать в глубину, кто кого сломает? :)

пятница, 11 декабря 2009 г.

Inverse in PS

Я ждал, когда это случится! И наконец-то это произошло. Передо мною встала простая задача - инвертировать матрицу 3x3 в пиксельном шейдере.

Update

Нашёл в Сети и протестировал, похоже, оптимальный вариант.
Вот код: invert. Проверки det == 0 нет, для PS это роскошь.

вторник, 8 декабря 2009 г.

Пуф-ф-ф!

Всё, сдулся Larrabee...

воскресенье, 6 декабря 2009 г.

Всё, что имеет начало, имеет и конец

Наткнулся на запись боя между Дэнни Грином и Роем Джонсом младшим, который прошёл на днях:

Danny Green vs Roy Jones Jr from Sydney, Australia 02/12/09

Очень грустное зрелище, конечно. Вот так заканчивают Великие Атлеты (действительно великие), если не знают, когда пора уйти со сцены (или же не хотят этого делать).

пятница, 4 декабря 2009 г.

Ньютон

Я иногда перечитываю биографии великих физиков и математиков, стараясь понять, какие личностные качества помогали им добиваться успеха. Очень интересным оказался один случай из биографии Исаака Ньютона (вычитал в Википедии):

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