2013-11-30 9 views
3

Все книги и руководства по DirectX настоятельно рекомендуют сократить выделение ресурсов между вызовами ничьей до минимума - пока я не могу найти никаких рекомендаций, которые будут более подробными. Просмотрев много примеров кода, найденных в Интернете, я пришел к выводу, что у программистов есть совершенно разные принципы кодирования в отношении этого предмета. Некоторые даже включение и отключениеСуществуют ли правила DirectX для связывания и развязывания ресурсов между вызовами рисования?

VS/PS 
VS/PS ResourceViews 
RasterizerStage 
DepthStencilState 
PrimitiveTopology 
... 

до и после каждого Жеребьевки вызова (хотя установка остается неизменной), а другие нет.

Я предполагаю, что это немного преувеличено ...

Из моих собственных экспериментов, я обнаружил, что только ресурсы, которые я должен связать на каждом розыгрыше вызова являются ShaderResourceViews (для VS и PS в моем случае). Это требование может быть вызвано использованием вычислительных шейдеров, так как я связываю/отвязываю UAVs с буферами, привязанными к VS/PS позже.

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

Вопрос 1: Есть ли хотя бы некоторые эмпирические положения, касающиеся этой проблемы?

Вопрос 2: Возможно ли, что мой ShaderResourceViews обязан VS/PS развязан ядро ​​/ DirectX драйвера, потому что я связываю UAVs к тем же буфера перед отправка вызова CS (я не отвязать SRVs сам)?

Вопрос 3: Я даже не установил VS/PS в значение null, прежде чем использовать вычислительные шейдеры. Работает без проблем, но я постоянно чувствую неуверенность в том, что я копаю свою следующую ловушку, используя такой «ленивый» подход.

ответ

0

Ответ 1: меньше.

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

Ответ 3: все в порядке.

+0

Я создаю swapchain с установленным флагом отладки, но я никогда не получаю отладочные сообщения от DirectX. Я использую VS Express для Web 2012 (включен F #), эта версия не позволяет использовать собственный код и отлаживать графику. –

+0

Флаг для 'D3D11CreateDevice' и называется' D3D11_CREATE_DEVICE_DEBUG'. Из визуального меню отладки вы также можете заставить его отключить сообщение и даже сломать их. – galop1n

+0

Прежде всего, я должен добавить, что я использую SharpDX в качестве оболочки, и что я уже использую флаг отладки. Поскольку моя версия VS имеет ограниченные возможности, на вкладке «debug» нет опции, кроме «Включить процесс хостинга VS». Я попытался использовать PIX (64-разрядный), но проблема с несовместимостью с SharpDX (хотя я установил 'SharpDX.Direct3D.PixHelper.AllowProfiling' в true) - программа вылетает (без уважительной причины), когда' RenderTargetView' создано. Это действительно беспорядок. –

5

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

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

1/Пробоотборники и государство

У вас есть 16 слотов и, как правило, 4-5 пробоотборников, вы используете 90% времени (линейный/точечный/анизотропный/теневой).

Итак, при запуске приложения создайте эти состояния и привяжите их к каждой стадии шейдера, которая вам нужна (старайтесь не начинать с нулевого слота, так как они могут быть легко преодолены по ошибке). Создайте файл заголовка шейдера с отображением SamplerState -> slot и используйте его в ваших шейдерах, чтобы любое обновление слота автоматически отражалось.

Повторно используйте это как можно больше, и только привязывайте пользовательские пробоотборники.

Для стандартных состояний (Blend/Depth/Rasterizer) создание небольшой коллекции общих состояний при запуске приложения и привязка по мере необходимости является обычной практикой.

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

2/Постоянные Буферы

У вас есть 14 слотов, которые довольно много, это довольно редко (по крайней мере, в моем случае использования), чтобы использовать все из них, особенно теперь вы можете также использовать буферы/структурированных буферов.

Один простых общий случай установка зарезервированных слотов для камеры (со всеми данными, которые вам нужны, вид/проекция/viewprojection, плюс их обратные, так что вам могут понадобиться, что тоже.

Bind ней (все, если это необходимо) этап шейдер слотов, и единственное, что вам нужно сделать, это обновить cbuffer каждый кадр, он готов к использованию в любом месте.

3/Shader этапы

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

С другой стороны, для стадии трубопровода, а не для развязывания, достаточно хорошей практикой является установка всех необходимых вам и установка нулевого значения, которые у вас нет.

Если вы не следуете этому примеру и визуализируете карту теней (только буфер глубины), пиксельный шейдер может быть привязан.

Если вы забыли удалить геометрию Shader, которую вы ранее использовали, вы можете получить недопустимую комбинацию макета, и ваш объект не будет отображаться (ошибка будет отображаться только в режиме отладки во время выполнения).

Таким образом, установка полной шейдерной сцены добавляет немного накладных расходов, но сбой в области безопасности очень далек от незначительного.

В вашем случае использования (используя только VS/PS и CS для сборки), вы можете смело игнорировать это.

4/БЛА-RenderTargets-DepthStencil

Для ресурсов записи, всегда снята с охраны, когда вы сделали с единицей работы. В рамках одной и той же процедуры вы можете оптимизировать внутри, но в конце вашей функции визуализации/вычисления-шейдера верните свой вывод в нуль, поскольку конвейер не позволит ничего отскочить, как ShaderResource, пока он находится на выходе.

Не сбрасывая ресурс записи в конце вашей функции, это рецепт катастрофы.

5/ShaderResourceView

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

Одним из возможных является сброс нулевых входных ресурсов шейдерных ресурсов в начале кадра, чтобы избежать привязки буфера, связанного в VS, к примеру, как БПЛА в CS, это обойдется вам в 6 конвейерных вызовов на кадр, но это вообще того стоит.

Если у вас достаточно запасных регистров и некоторых постоянных ресурсов, вы также можете установить их в некоторых зарезервированных слотах и ​​связать их раз и навсегда.

связанные

6/IA ресурсы

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

Я считаю, что топология имеет решающее значение для правильной установки, поскольку недопустимая топология (например, с использованием списка треугольников с конвейером, включая тесселяцию), ничего не даст и даст вам предупреждение о запуске, но очень часто, что на AMD карта, это просто приведет к краху вашего драйвера, поэтому лучше избегать этого, поскольку его довольно сложно отлаживать.

Как правило, никогда не отменяются вершинные/индексные буферы (поскольку их просто переписывают, а макет ввода указывает, как получить в любом случае). Единственное исключение из этого правила, если в случае, если эти буферы генерируются в вычислении/потоке, чтобы избежать вышеупомянутого предупреждения времени выполнения.

+0

Нужно ли «отключить» 'SetVertexBuffers()' VertexBufferBindings? Когда это делается с их рендерингом. –

+0

Я лично никогда этого не делаю и просто переопределяю при привязке новой геометрии. У меня есть несколько редких случаев, когда необходимо сделать tho (вычислить шейдерную геометрию) – catflier