現在MTLTexture
、入力用があり、20 ~ 30 個の頂点のセットを使用して断片的にレンダリングしています。drawRect
これは現在、私のハンドラの末尾で行われていますMTKView
:
[encoder setVertexBuffer:mBuff offset:0 atIndex:0]; // buffer of vertices
[encoder setVertexBytes:&_viewportSize length:sizeof(_viewportSize) atIndex:1];
[encoder setFragmentTexture:inputTexture atIndex:0];
[encoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:_vertexInfo.metalVertexCount];
[encoder endEncoding];
[commandBuffer presentDrawable:self.currentDrawable];
[commandBuffer commit];
ただし、最終的な処理を行う前にpresentDrawable
、結果のテクスチャをインターセプトしたいと思います (その領域を別の に送信しますMTKView
)。つまり、呼び出しMTLTexture
後に何らかの出力にアクセスする必要があります。drawPrimitives
これを行う最も効率的な方法は何ですか?
1 つのアイデアは、代わりにdrawPrimitives
中間出力に追加のレンダリングを導入することです。MTLTexture
これを行う方法はわかりませんが、その過程でその出力テクスチャをスクープします。これは他の場所(つまり、画面外)でも行われるのではないかと思います。
次にdrawPrimitives
、その outputTexture を使用して 1 つの大規模なテクスチャ クワッドを使用して 2 番目を発行し、次にそのpresentDrawable
上に を発行します。そのコードは、以前のコードがあった場所に存在します。
の出力テクスチャをキャプチャできるようにする単純なメソッドが Metal API にある可能性があります (私が見逃しています) drawPrimitives
。
の使用を検討しましたMTLBlitCommandEncoder
が、特定の MacOSX ハードウェアではいくつかの問題があります。
更新#1: idoogy、これがあなたが要求していたコードです:
ここで、最初の「輝度出力」テクスチャを作成します...これを行うために、頂点シェーダーで飛行中です。
...
[encoder setFragmentTexture:brightnessOutput atIndex:0];
[encoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:_vertexInfo.metalVertexCount];
[encoder endEncoding];
for (AltMonitorMTKView *v in self.downstreamOutputs). // ancillary MTKViews
[v setInputTexture:brightnessOutput];
__block dispatch_semaphore_t block_sema = d.hostedAssetsSemaphore;
[commandBuffer addCompletedHandler:^(id<MTLCommandBuffer> buffer) {
dispatch_semaphore_signal(block_sema);
}];
[commandBuffer presentDrawable:self.currentDrawable];
[commandBuffer commit];
以下では、補助ビューのdrawRect
ハンドラーでinputTexture
、転送されるテクスチャとして、そのサブ領域を表示しています。これは、内部タイマーではなくMTKView
、結果として描画されるように構成されていることに注意してください。setNeedsDisplay
id<MTLRenderCommandEncoder> encoder = [commandBuffer renderCommandEncoderWithDescriptor:renderPassDescriptor];
encoder.label = @"Vertex Render Encoder";
[encoder setRenderPipelineState:metalVertexPipelineState];
// draw main content
NSUInteger vSize = _vertexInfo.metalVertexCount*sizeof(AAPLVertex);
id<MTLBuffer> mBuff = [self.device newBufferWithBytes:_vertexInfo.metalVertices
length:vSize
options:MTLResourceStorageModeShared];
[encoder setVertexBuffer:mBuff offset:0 atIndex:0];
[encoder setVertexBytes:&_viewportSize length:sizeof(_viewportSize) atIndex:1];
[encoder setFragmentTexture:self.inputTexture atIndex:0];
[encoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:_vertexInfo.metalVertexCount];
[encoder endEncoding];
[commandBuffer presentDrawable:self.currentDrawable];
[commandBuffer commit];
上記のコードは問題なく動作するようです。そうは言っても、Xcode デバッガーでは別の話をしていると思います。この方法で膨大な時間を無駄にしていることは明らかです...その長いコマンドバッファは、多くの待機を行う補助的なモニタービューです...