Платформа iOS: MTLLibrary newFunctionWithName завершается с ошибкой, когда в клиентском коде установлен флаг cikernel

У меня есть фреймворк iOS, использующий Metal; он устанавливает дескриптор конвейера следующим образом:

...
_metalVars.mtlLibrary = [_metalVars.mtlDevice newLibraryWithFile:libraryPath error:&error];

id <MTLFunction> vertexFunction = [_metalVars.mtlLibrary newFunctionWithName:@"vertexShader"];
id <MTLFunction> fragmentFunction = [_metalVars.mtlLibrary newFunctionWithName:@"fragmentShader"];

MTLRenderPipelineDescriptor *pipelineStateDescriptor = [[MTLRenderPipelineDescriptor alloc] init];

MTLRenderPipelineDescriptor *pipelineStateDescriptor = [[MTLRenderPipelineDescriptor alloc] init];
pipelineStateDescriptor.label = @"MyPipeline";
pipelineStateDescriptor.vertexFunction = vertexFunction;
pipelineStateDescriptor.fragmentFunction = fragmentFunction;
pipelineStateDescriptor.vertexDescriptor = mtlVertexDescriptor;
pipelineStateDescriptor.colorAttachments[0].pixelFormat = MTLPixelFormatRGBA8Unorm; 

_metalVars.mtlPipelineState = [_metalVars.mtlDevice newRenderPipelineStateWithDescriptor:pipelineStateDescriptor error:&error];
...

Этот фреймворк используется приложением для iOS и работал нормально, пока не был установлен флажок

-fcikernel

был установлен под другими флагами металлического компилятора, и

-cikernel

в разделе «Другие флаги металлического компоновщика» в настройках сборки клиентского приложения. (флаги установлены на клиенте, согласно https://developer.apple.com/documentation/coreimage/cikernel/2880194-kernelwithfunctionname.)

С этими изменениями в клиентском приложении приведенный выше фрагмент кода фреймворка теперь дает сбой в последней строке приведенного выше фрагмента кода при вызове newRenderPipelineStateWithDescriptor с ошибкой

validateWithDevice:2556: failed assertion `Render Pipeline Descriptor Validation
vertexFunction must not be nil

и я проверил, что фреймворк теперь возвращает nil для вершинной функции в

id <MTLFunction> vertexFunction = [_metalVars.mtlLibrary newFunctionWithName:@"vertexShader"];

но отлично работает, если я удалю флаги в клиентском приложении.

Вопросы: 1.) Я так понял, что металлические шейдеры были предварительно скомпилированы; почему изменение параметра сборки в клиентском коде может привести к сбою во время выполнения в неизменной среде? 2.) Как это можно решить?

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
650
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Эти флаги предназначены для использования при компиляции ядер Core Image, написанных на Metal. Они изменяют способ перевода кода таким образом, что он несовместим с «обычным» кодом шейдера Metal.

Проблема с установкой флагов Core Image на уровне проекта заключается в том, что затрагиваются все файлы .metal, независимо от того, содержат ли они ядра Core Image или обычный код шейдера.

Лучший способ обойти это — использовать другое расширение файла для файлов, содержащих ядра Core Image Metal, например .ci.metal. Затем можно использовать специальные правила сборки для компиляции этих ядер отдельно от остальной части кодовой базы Metal. Я рекомендую эту сессию с WWDC 2020, в которой подробно описан процесс.

Идеально - это исправило.

bphi 14.12.2020 19:32

Другие вопросы по теме