На стороне процессора у меня есть структура, которую я хочу передать вычислительному ядру:
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).'
На стороне металлического ядра вот соответствующие фрагменты кода:
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.
У кого-нибудь есть идеи по этому вопросу?