Металл newBufferWithBytes использование

У меня основной вопрос о выделении новых буферов устройств Metal. Большинство примеров кодов, которые я вижу, создают MTLBuffer во время установки и не изменяют его. Но мне интересно, меняются ли данные вершин при каждом вызове рендеринга, нормально ли каждый раз создавать новый MTLBuffer (используя - [MTLBuffer newBufferWithBytes: length: option]) для отправки данных шейдерам, работающим на GPU, ИЛИ, если MTLBuffer равен заданный размер может быть создан один раз, но байты изменяются при каждом вызове рендеринга? Какой рекомендуемый способ в соответствии с передовой практикой?


person Deepak Sharma    schedule 05.04.2018    source источник


Ответы (1)


Если это небольшой объем данных (менее 4K), я считаю, что вы можете использовать setVertexBytes () и setFragmentBytes (): https://developer.apple.com/documentation/metal/mtlrendercommandencoder/1515846-setvertexbytes

Для больших объемов данных, которые изменяют каждый кадр, они рекомендуют использовать подход с тройной буферизацией, чтобы последовательный доступ кадров к буферу не мешал: https://developer.apple.com/library/content/documentation/3DDrawing/Conceptual/MTLBestPracticesGuide/TriplemlBuffering.html

В этом руководстве показано, как настроить тройную буферизацию: https://www.raywenderlich.com/146418/metal-tutorial-swift-3-part-3-adding-texture

На самом деле это похоже на третью часть учебника, но в этой части показана настройка тройной буферизации в разделе «Повторное использование унифицированных буферов».

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

person bsabiston    schedule 05.04.2018
comment
Спасибо за ответ. Это было просто для передачи массива вершин. Как использовать тот же подход для передачи структуры с помощью setFragmentBytes? - person Deepak Sharma; 05.04.2018
comment
Вы можете сделать это точно так же - передать адрес структуры: renderEncoder.setFragmentBytes (& myStruct, length: MemoryLayout ‹myStruct› .stride, index: uniforms_index) - person bsabiston; 05.04.2018
comment
Он вылетает при отправке вершин, ошибочное утверждение «Байты привязаны с индексом 0 к аргументу шейдера с разрешенным доступом на запись». - person Deepak Sharma; 05.04.2018
comment
Измените адресное пространство параметра буфера на constant вместо device. - person warrenm; 06.04.2018