CPU 側では、計算カーネルに渡したい構造があります。
private struct BoundingBoxParameters {
var x: Float = 0
var y: Float = 0
var width: Float = 0
var height: Float = 0
var levelOfDetail: Float = 1.0
var dummy: Float = 1.0 // Needed for success
}
カーネルを実行する前に、データを MTLComputeCommandEncoder に渡します。
オプション 1 (直接):
commandEncoder!.setBytes(¶ms, length: MemoryLayout<BoundingBoxParameters>.size, index: 0)
オプション 2 (MTLBuffer 経由で間接的に):
boundingBoxBuffer.contents().copyBytes(from: ¶ms, count: MemoryLayout<BoundingBoxParameters>.size)
commandEncoder!.setBuffer(boundingBoxBuffer, offset: 0, index: 0)
「ダミー」変数が構造体に存在する場合、どちらのオプションも正常に機能しますが、「ダミー」変数が存在しない場合は失敗します。コードは次の呼び出しで失敗します。
commandEncoder!.dispatchThreadgroups(threadGroups, threadsPerThreadgroup: threadGroupCount)
エラーで:
validateComputeFunctionArguments:820: failed assertion `Compute Function(resizeImage): argument params[0] from buffer(0) with offset(0) and length(20) has space for 20 bytes, but argument has a length(24).'
Metal Kernel 側では、関連するコード スニペットを次に示します。
struct BoundingBoxParameters {
float2 topLeft;
float2 size;
float levelOfDetail;
};
kernel void resizeImage(constant BoundingBoxParameters *params [[buffer(0)]],
texture2d<half, access::sample> sourceTexture [[texture(0)]],
texture2d<half, access::write> destTexture [[texture(1)]],
sampler samp [[sampler(0)]],
uint2 gridPosition [[thread_position_in_grid]]) {
float2 destSize = float2(destTexture.get_width(0), destTexture.get_height(0));
float2 sourceCoords = float2(gridPosition) / destSize;
sourceCoords *= params->size;
sourceCoords += params->topLeft;
float lod = params->levelOfDetail;
half4 color = sourceTexture.sample(samp, sourceCoords, level(lod));
destTexture.write(color, gridPosition);
}
3x3 マトリックスを別の計算カーネルに渡そうとすると、同様の問題が発生します。36 バイトが提供されているが、48 バイトが期待されていると不平を言っています。
この問題に関するアイデアはありますか?