![]() |
Страницы (3): « 1 [2] 3 » Показать все 31 сообщений этой темы на одной странице |
HLFX.Ru Forum (https://hlfx.ru/forum/index.php)
- OpenGL (https://hlfx.ru/forum/forumdisplay.php?forumid=7)
-- OpenGL vs Direct3D (https://hlfx.ru/forum/showthread.php?threadid=4400)
OpenGL помогает сажать баги, Direct3D - находить их
Нет, речь пойдёт не о замечательной штуке под названием Direct3D Debug Runtime, и даже не о инструменте PIX. Речь пойдёт о многопоточности и банальных race conditions.
Столкнулся я вчера с удивительной, неописуемой проблемой. Периодически перестаёт применяться вертексный шейдер к отдельным полигонам, и они начинают мерцать. В OpenGL - всё идеально, а в D3D - мерцание. И только при включенной многопоточности. Выключаю статическое кэширование - мерцания нет. Выключаю шейдеры - мерцания нет. Отключаю вызов SetVertexShader( NULL ) (т.е. отключение однажды забинденного шейдера) - мерцания нет. Включаю Debug Runtime - мерцания нет. А так - есть. Гугл, разумеется, был перерыт, и я быстро убедился, что такая проблема возникает только у меня. Я и на драйвер грешил (обновил), и на версию дхсдк (обновил). Ничего не помогало. Мерцает, зараза, и всё тут, словно вертекс-шейдер с перепою и раз в пару сотен кадров просто не хочет биндиться.
Раз дело связано с многопоточностью - остаётся только вариант с race condition, но вот где? Первая мысль, традиционно - не у меня, а у "говнокодеров", написавших директх/драйверы/венду (говнокодерам эта мысль всегда приходит первой ), но я её быстро отогнал. И вот методом многочасового ковыряния в отладчике проблема таки была найдена. Выглядела она в общем случае так:
effect->shader = NULL; |
if ( true ) effect->shader = pshader; |
__________________
__________________
__________________
Минутка полезного:
Бесплатный UT-подобный Half-Life mod.
Бесплатный редактор для 32-битных текстур. Без дотнета.
Бесплатный IDE для любых компиляторов и ЯП.
Бесплатная Windows-подобная ОС.
Проверка грамматики русского языка.
Чат по hl[fx]: [email protected]
Ещё немного о том, за что я ненавижу OpenGL.
В нём трёхкомпонентный secondary color!
Тут надо пояснить. Когда шейдеров не было, вторичный цвет задавал цвет спекуляра, а его альфа-компонент не использовался и считался равным 0. В D3D он игнорировался на этапе обработки данных пользователя (там цвета засылаются как DWORD), а мерзкий OpenGL в функции glSecondaryColorPointer дал чёткую установку: кол-во компонентов, переданное пользователем, всегда 3, иначе ошибка! Типа, смотрите на меня, я OpenGL, я самый умный, а вы тупые юзеры.
Появились шейдеры. Появился резон использовать альфа-компоненту вторичного цвета. Что изменилось в D3D? Он перестал игнорировать альфа-байт, переданный пользователем, и передаёт его в шейдер. Что изменилось в OpenGL? НИЧЕГО! Задать 4-компонентный вторичный цвет нельзя. Ну то есть как? Некоторые драйверы (например, NVIDIA) принимают size = 4 у glSecondaryColorPointer. Но формально это нарушение спеки, а значит, на каком-нибудь интеле может быть ошибка и цвет не будет передан вообще. А самое, блин, интересное - нет никакой возможности проверить, поддерживает ли драйвер size = 4 (ну кроме как вызвать функцию и посмотреть glGetError).
Конечно, некоторые скажут - зачем тебе glSecondaryColorPointer, если есть glVertexAttribArray? Ответ: для ARB_vertex_program те же самые ограничения, а использование GLSL у меня опционально, т.к. он ухитряется глючить на некоторых видеокартах (особенно интелах).
И ещё. Железо, разумеется, использовало все 4 байта вторичного цвета. Альфа-компонент часто хранил Fog coordinate. Однако от пользователя это скрывалось. Следовательно, никаких препятствий задавать 4-компонентный вторичный цвет технически нет и быть не могло.
__________________
Однако, здравствуйте.
Сегодня речь пойдёт о Радеонах - да, мы словно снова в 2005 году. Но не о Direct3D (хотя наверняка под ним всё было бы отлично!), а о кривых OpenGL-драйверах (или какой-то ещё НЁХ??) в 2018 году, Карл.
Имеется макбук с ОС High Sierra, Radeon Pro 555.
Запускаю движок и с изумлением замечаю, что отвалились многие эффекты, как-то вода, софт-партикли, некоторые постфильтры. Начинаю смотреть внимательно и быстро прихожу к выводу, что проблема в том, что в шейдеры попадает неправильная текстура глубины экрана.
А конкретно - вызов glCopyTexSubImage2D не отрабатывает и ничего не копирует. При этом не возникает никаких ошибок! Та же ситуация - с glCopyTexImage2D. Безуспешно перепробовал все мыслимые форматы depth-текстуры - включая depth-stencil - обнаружил, что единственное, что работает - это связка glReadPixels + glTexImage2D. А копирование текстуры - ни в какую! Как тебе такое, Стив Джобс?
Понятное дело, что на другом макбуке с GeForce GT 750M всё работает без каких-либо багов, и полностью соответствует картинке десктопа (где у меня тоже GeForce)...
__________________
Обычные текстуры тоже не копируются?
ncuxonaT
Обычные превосходно копируются. Проблема только с копированием глубины и только через glCopyTex(Sub)Image.
Попробую подкостылить для мобильных радеонов копирование через glReadPixels-> PBO ->glTexSubImage, по скорости должно быть сопоставимо, но не удивлюсь, если и оно не работает.
Самое мерзкое тут то, что glGetError не возвращает никаких ошибок.
__________________
__________________
My Projects: download page
F.A.Q по XashNT
Блог разработчика в телеграме
C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'
Это не может быть связано с тем, что на радеонах с GCN-архитектурой текстуры глубины хранятся сжатыми, пока из них не начнешь читать?
ncuxonaT теперь увяжи в эту теорию GL_POLYGON_OFFSET.
__________________
My Projects: download page
F.A.Q по XashNT
Блог разработчика в телеграме
C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'
Дядя Миша на форумах пишут, что старые радеоны не поддерживают gl_FragCoord хардварно, оно как-то эмулируется через varying. Видимо, с оффсетом сэмулировать не получается, и всё идёт по одному месту.
ncuxonaT это я тоже читал, но связи как-то не уловил. Полигоноффсет это просто оффсет такой.
__________________
My Projects: download page
F.A.Q по XashNT
Блог разработчика в телеграме
C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'
Временная зона GMT. Текущее время 14:13. | Страницы (3): « 1 [2] 3 » Показать все 31 сообщений этой темы на одной странице |
На основе vBulletin версии 2.3.0
Авторское право © Jelsoft Enterprises Limited 2000 - 2002.
Дизайн и программирование: Crystice Softworks © 2005 - 2024