Металлический эквивалент для glCopyTexImage2d - PullRequest
0 голосов
/ 04 февраля 2020

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

то, что я пробовал до сих пор, используя MTLBlitCommandEncoder.

auto commandQueue = [device newCommandQueue];
auto commandBuffer = [commandQueue commandBuffer];
[commandBuffer enqueue];
id<MTLRenderCommandEncoder> renderEncoder = [commandBuffer renderCommandEncoderWithDescriptor:mtlDescriptor];

// perform encoding

[renderEncoder endEncoding];

// now after several render passes i need to commit all the rendering for behind the effect, 
// so that the texture i am grabbing will omit whatever is about to be drawn after this point

[commandBuffer commit];
[commandBuffer waitUntilCompleted];

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

auto commandBuffer = [commandQueue commandBuffer];

id<MTLBlitCommandEncoder> blitEncoder = [commandBuffer blitCommandEncoder];
[blitEncoder enqueue];

[blitEncoder copyFromTexture:drawable.texture sourceSlice:0 sourceLevel:level sourceOrigin:region.origin sourceSize:region.size toTexture:_mtlTexture destinationSlice:0 destinationLevel:level destinationOrigin:{xOffset, yOffset, 0}];

[blitEncoder endEncoding];
.
// continue with more other render encoding

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

mtlDescritpor.depthAttachment.loadAction = MTLLoadActionLoad;
mtlDescritpor.depthAttachment.storeAction = MTLStoreActionStore;

Может кто-нибудь указать мне, где пошло не так?

РЕДАКТИРОВАТЬ: Я пытался использовать 2 буфера команд, один за другим, без выполнения blit, и глубина также отображается неправильно.

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

EDIT2: после дополнительного тестирования, кажется, что есть очень противоречивое поведение, даже при использовании только 1 буфера команд. Некоторое время эффект отображается ниже (неверно), иногда правильно. (часть этого должна быть выше, как проверено на OpenGL) Когда я закомментирую строку кода или добавлю больше строк кода, результат будет меняться случайным образом. В настоящее время я использую функцию глубины MTLCompareFunctionLessEqual. Если я изменю на MTLCompareFunctionNotEqual, все будет всегда нарисовано сверху, что также неправильно.

1 Ответ

0 голосов
/ 05 февраля 2020

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

На основе на этой информации здесь https://github.com/gfx-rs/gfx/issues/2232 Как будто бы любое выполненное кодирование рендеринга уже отрисовано в текстуре. Таким образом, наличие 2 командных буферов вовсе не обязательно.

Что касается проблемы с тестом глубины, то я ошибся, не установив для области просмотра znear и zfar значение MTLRenderCommandEncoder, совпадающее с моделями '.

...