Выбор между буферами в металлическом шейдере - PullRequest
0 голосов
/ 04 октября 2018

Я борюсь с переносом приложения OpenGL на Metal.В моем старом приложении я связывал два буфера, один с вершинами и соответствующими цветами, а другой с вершинами и соответствующими текстурами, и переключался между ними на основе некоторой логики приложения.Теперь в Metal я начал с примера Hello Triangle , где я попытался запустить этот вершинный шейдер

vertex RasterizerData
vertexShader(uint vertexID [[vertex_id]],
             constant AAPLVertex1 *vertices1 [[buffer(AAPLVertexInputIndexVertices1)]],
             constant AAPLVertex2 *vertices2 [[buffer(AAPLVertexInputIndexVertices2)]],
             constant bool &useFirstBuffer [[buffer(AAPLVertexInputIndexUseFirstBuffer)]])
{
    float2 pixelSpacePosition;
    if (useFirstBuffer) {
        pixelSpacePosition = vertices1[vertexID].position.xy;
    } else {
        pixelSpacePosition = vertices2[vertexID].position.xy;
    }
    ...

и этот код Objective-C

bool useFirstBuffer = true;
[renderEncoder setVertexBytes:&useFirstBuffer
                       length:sizeof(bool)
                      atIndex:AAPLVertexInputIndexUseFirstBuffer];
[renderEncoder setVertexBytes:triangleVertices
                       length:sizeof(triangleVertices)
                      atIndex:AAPLVertexInputIndexVertices1];

(где AAPLVertexInputIndexVertices1 = 0, AAPLVertexInputIndexVertices2 = 1 и AAPLVertexInputIndexUseFirstBuffer = 3), что должно привести к тому, что vertices2 никогда не будет получен доступ, но все равно я получаю ошибку: failed assertion 'Vertex Function(vertexShader): missing buffer binding at index 1 for vertices2[0].'

Все работает, если я заменяю if (useFirstBuffer)if (true) в Металлическом коде.Что не так?

Ответы [ 2 ]

0 голосов
/ 06 октября 2018

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

Поскольку все объявленные параметры буфера должны быть связаны, оставляя несвязанный буфер без привязок отключает уровень проверки.Вы можете связать несколько «фиктивных» байтов в слоте Vertices2 (используя -setVertexBytes:length:atIndex:), если не идете по этому пути, чтобы обойти это.Не важно, что буферы имеют одинаковую длину, так как, в конце концов, фиктивный буфер никогда не будет доступен.

0 голосов
/ 04 октября 2018

В аргументе atIndex вы вызываете код со значениями AAPLVertexInputIndexUseFirstBuffer и AAPLVertexInputIndexVertices1, но в коде Metal значения AAPLVertexInputIndexVertices1 и AAPLVertexInputIndexVertices2 появляются (в буфере спецификаций 2).Похоже, вам нужно использовать AAPLVertexInputIndexVertices1 вместо AAPLVertexInputIndexUseFirstBuffer в вызывающем коде.

...