Войти
ФлеймФорумПроЭкты

FrameGraph (7 стр)

Страницы: 14 5 6 7 8 9 Следующая »
#90
5:31, 27 фев. 2019

kas
> ну нет. просто есть "дефолтное" состояние. когда надо не оно - переводишь в то
> которое надо и сразу после - назад. работает отлично, на перф чтобы влияло не
> похоже, причем и для дх12 тоже самое все
ну да, особенно если у тебя дефолтное состояние — рендертаргет, но есть 10 пассов подряд, которые из него читают в шейдере. тогда у тебя будет 10 подряд барьеров, которые будут маслать лейаут взад-вперёд.

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

#91
7:47, 27 фев. 2019

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

#92
(Правка: 8:23) 8:17, 27 фев. 2019

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

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

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

#93
8:51, 27 фев. 2019

Suslik
> я говорю о случае, когда дефолтное для ресурса состояние — например,
> рендертаргет
а я говорю о случае - когда нет такого дефолтного состояния. можно придумывать проблемы и героически их решать, а можно нет.

Suslik
> можно подумать, ты будешь что-то понимать, когда у тебя количество рендерпассов
> перейдёт хотя бы за несколько десятков. напомню, во фростбайте их — несколько
> сотен и при этом многие из них — опциональные, которые включаются только при
> определённых условиях.
> да и как бы можно подумать, я тебя убедить пытаюсь, почему все дороги ведут к
> фреймграфам. мне от этого ни тепло ни холодно, разобраться в этом — в твоих
> интересах, поэтому сам гугли доклады по фреймграфам и втыкай, почему люди о них
> заморачиваются.
доклады я читал - у меня стойкое ощущение что там основная мотивация память сэкономить а вовсе не то что вы пишите. поетому и спрашиваю!

#94
11:26, 27 фев. 2019

kas
> у меня стойкое ощущение что там основная мотивация память сэкономить
Для этого использовался первый фреймграф, но тогда памяти было намного меньше.
С фреймграфом ты можешь оптимизировать некоторые участки, например выкинуть лишнее рисование или копирование, если результат нигде не используется. Можешь заменить несколько тасков одним оптимизированым с каким-нибудь вендорским расширением.

#95
(Правка: 13:46) 13:43, 27 фев. 2019

kas
> просто есть "дефолтное" состояние
kas
> а я говорю о случае - когда нет такого дефолтного состояния
так ты определишься, может? есть у тебя дефолтное состояние или нет? я говорю, что если есть — это наивное решение по типу легаси API, которое при определённых условиях использования может выродиться в кучу перекладываний лейаута. а если нет, то ты не будешь знать, в какое состояние переводить ресурс при инициализации пасса, так как ты не знаешь, как он будет использоваться после него.

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

#96
14:10, 27 фев. 2019

Suslik
> так ты определишься, может? есть у тебя дефолтное состояние или нет?
я то определен. там слово _такого_ не просто так. дефолтное состояние текстуры - это текстура. проблемы будут если несколько раз подряд бегин енд пасс делать в одну и туже, тут фреймграф может помочь безусловно

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

#97
16:58, 22 мар. 2019

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

Выглядит это так:

class ICommandBuffer
{
  // это новое
  virtual void AddDependency (CommandBufferPtr) = 0;

  // тут все попрежнему
  virtual Task AddTask (...) = 0;
};

class IFrameGraph
{
  virtual CommandBufferPtr  Begin (...) = 0;

  // добавляем командный буфер в очередь, так как vkQueueSubmit дорогая операция,
  // то команды будут отправляться батчами
  virtual void Execute (CommandBufferPtr) = 0;

  // принудительно отправляем команды и ожидаем fence
  virtual bool Wait (ArrayView<CommandBufferPtr>) = 0;

  // отправляем все командны на ГПУ
  virtual void Flush () = 0;

  // отправляем все команды и ожидаем их завершения
  virtual void WaitIdle () = 0;
};

void main ()
{
  // какая-то генерация
  auto cmd1 = fg->Begin( EQueue::AsyncCompute );
  cmd1->AddTask( Dispatch{}... );
  fg->Execute( cmd1 );
  ...
  ...
  // рисование
  auto cmd2 = fg->Begin( EQueue::Graphics );
  ...
  // проверяем, что команды генерации уже записаны  
  if ( ... )
  {
    cmd2->AddDependency( cmd1 );

    // рисуем то что сгенерировали
    cmd2->AddTask( ... );
  }

  fg->Execute( cmd2 );
}

#98
19:55, 7 апр. 2019

Стабилизировал версию 0.9, как раз тот новый интерфейс из предыдущего поста.
Также давно уже выложен сэмпл с рейтрейсом на RTX, но там пока еще примитивно все.

#99
15:48, 11 апр. 2019

Suslik
>// массив ресурсов на чтение. если к началу исполнения таска ресурс находится не в
> том layout'е, то он автоматически переводится в eShaderRead барьером.
Я попробовал такой же подход - в начале рендер пасса указывать все ресурсы, которые могут быть не в том лейауте, который ожидается. И на шрифтах получился облом - текстуры с атласами запрятаны где-то далеко, а новый глиф может создаться на любом кадре. Вариантов остается два: делать отдельный командный буфер, куда будут записаны команды копирования и в конце лейаут перейдет в дефолтное состояние как раз для чтения. Либо оставить как было, пройтись по всем дескриптор сетам и выставить барьеры, с имутабельностью получается достаточно быстро.

#100
(Правка: 16:21) 16:11, 11 апр. 2019

/A\
> И на шрифтах получился облом - текстуры с атласами запрятаны где-то далеко, а
> новый глиф может создаться на любом кадре.
не понял, в чём проблема. вообще текстуры со шрифтами обычно по кодовым страницам распределены и ты просто загружаешь всю страницу, тут в принципе переводы лейаутов не нужны.

> Я попробовал такой же подход - в начале рендер пасса указывать все ресурсы, которые могут быть не в том лейауте, который ожидается
я, кстати, ещё дальше этого подхода пошёл. если раньше я хранил для каждого ресурса его текущее состояние, то теперь даже этого не делаю, а нахожу состояние ресурса перед началом исполнения таска как состояние этого ресурса на момент выполнения последнего таска, использовавшего этот ресурс. например, если последний раз этот ресурс фигурировал в каком-то таске, как ресурс на чтение из шейдера, то он будет в состоянии eShaderReadOptimal. получается полностью stateless модель.

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

ещё я реализовал автоматический сабмит рендерпассов в graphics queue, компьют пассов в compute queue и трасфер пассов в transfer queue, автоматически передаю владение над ресурсами, расставляю семафоры, всё такое, пользуясь той же самой философией — последний пасс, использовавший ресурс, однозначно определяет, в каком он будет лейауте и какой queue им будет владеть.

#101
16:22, 11 апр. 2019

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

> вообще текстуры со шрифтами обычно по кодовым страницам распределены и ты
> просто загружаешь всю страницу, тут в принципе переводы лейаутов не нужны.
У меня только используемые глифы загружаются. По крайней мере такой вариант использовался в навигаторе, где отображался весь мир с кучей юникод символов и с разными размерами шрифтов. Заранее хоть что-то загружать достаточно дорого.

#102
(Правка: 16:29) 16:27, 11 апр. 2019

Suslik
> автоматически передаю владение над ресурсами
А как разруливаешь ситуации когда ресурс захвачен compute queue, а используется в graphics queue, тут получается или заранее передавать или записывать командный буфер чтоб освободить ресурс в compute queue.
Или как быть с чтением ресурса из разных очередей? Тут только concurrent режим подходит.

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

#103
(Правка: 16:32) 16:28, 11 апр. 2019

/A\
> Там же один таск может использовать один диапазон, второй - другой диапазон и
> тебе придется их все учитывать.
именно так, потому что владение определяется не для ресурса, а для сабресурса. то есть сабпасс говорит, что использует такой-то image view, которому соответствует subresource range, поэтому именно этот subresource range будет в соответствующем лейауте. далее я конструирую барьеры для каждого сабресурса отдельно, но по возможности объединяю их все в один барьер с более широким диапазоном сабресурсов.

/A\
> У меня только используемые глифы загружаются. По крайней мере такой вариант
> использовался в навигаторе, где отображался весь мир с кучей юникод символов и
> с разными размерами шрифтов. Заранее хоть что-то загружать достаточно дорого.
>
>
если честно, я с трудом представляю себе ситуацию, когда тебе одновременно нужно выводить на экране символы из более чем ~5 юникодных страниц. пожалуй, рендеринг карты мира — одно из редких исключений, но даже если очень хочется собирать атлас шрифтов из отдельных глифов, я всё равно не понимаю, в чём проблема.

> А как разруливаешь ситуации когда ресурс захвачен compute queue, а используется в graphics queue, тут получается или заранее передавать или записывать командный буфер чтоб освободить ресурс в compute queue.
> Или как быть с чтением ресурса из разных очередей? Тут только concurrent режим подходит.
при расстановке барьеров я автоматически меняю лейаут и передаю владение, если необходимо. однако, ремарка: у меня сейчас compute и graphics queue используют один и тот же queue family index, поэтому я пока не тестировал, если они действительно разные. может быть какой-то баг, о котором я пока не догадываюсь.

#104
16:31, 11 апр. 2019

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

Страницы: 14 5 6 7 8 9 Следующая »
ФлеймФорумПроЭкты