Правильный способ сделать закадровый рендеринг в металле - PullRequest
0 голосов
/ 06 ноября 2019

Я изучаю металл и пытаюсь реализовать пост-эффект с помощью рендеринга вне экрана. Для этого я рисую свою сцену в качестве цели рендеринга, как в этом вопросе .

  • Создать MTLCommandBuffer
  • Создать MTLRenderCommandEncoder (установить в MTLRenderPassDescription мою целевую текстуру)
  • Запись команд рисования в кодировщик
  • Завершение кодирования и фиксация буфера команд в очереди команд

Затем я хочу нарисовать свою текстуру в буфере кадра (currentDrawable).

Полагаю, моя текстура готова для рисования, и я могу ее использовать. Но когда я рисую текстуру в буфер кадра, я вижу мусор. Похоже, текстура не готова. Для исправления я вызываю waitUntilCompleted для моего буфера команд на экране. Это помогает. Но согласно документации Apple :

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

Так что я ожидаю, что смогу сделать это без вызова функции блокировки waitUntilCompleted. Но это не работает для меня. Смотрите пример:

var device = MTLDevice.SystemDefault;
var commandQueue = device.CreateCommandQueue();

//Create texture for renderTarget
var textDesc = MTLTextureDescriptor.CreateTexture2DDescriptor(pixelFormat, Width, Height, 1);
textDesc.Usage = MTLTextureUsage.RenderTarget | MTLTextureUsage.ShaderRead;
textDesc.StorageMode = MTLStorageMode.Private;
IMTLTexture texture = device.CreateTexture(textDesc);

var textPassDesc = new MTLRenderPassDescriptor();
textPassDesc.ColorAttachments[0].LoadAction = MTLLoadAction.Clear;
textPassDesc.ColorAttachments[0].StoreAction = MTLStoreAction.Store;
textPassDesc.ColorAttachments[0].Texture = texture;

var commandBuffer = commandQueue.CommandBuffer();
var commandEncoder = commandBuffer.CreateRenderCommandEncoder(textPassDesc);

//Drawing scene. I guess It's not interesting now
{
...
}

//Finish command
commandEncoder.EndEncoding();
commandBuffer.Commit();
//The main goal of the question, can I escape this calling ? 
commandBuffer.WaitUntilCompleted();

var finalPassDesc = MTKView.CurrentRenderPassDescriptor;
commandBuffer = commandQueue.CommandBuffer();
commandEncoder = commandBuffer.CreateRenderCommandEncoder(finalPassDesc);

//Drawing the frame with texture
{
commandEncoder.SetFragmentTexture(texture, 0);
commandEncoder.SetFragmentSamplerState(defaultSamplerState, 0);
...
}
commandEncoder.EndEncoding();
commandBuffer.PresentDrawable(MTKView.CurrentDrawable);
commandBuffer.Commit();

Какой правильный способ сделать закадровый рендеринг с использованием металла?

...