We are working with interlaced HD video. The metal color attachment I use for rendering has the dimensions of one field (1920*540 RGBA). When I try to copy two rendered fields into the same MTLBuffer that has the size of 1920*1080*4 = 8294400 bytes it works only if the destination offset is zero.
let commandBuffer = commandQueue.makeCommandBuffer()
let blitEncoder = commandBuffer.makeBlitCommandEncoder()
blitEncoder.copy(from: attachmentTexture,
sourceSlice: 0,
sourceLevel: 0,
sourceOrigin: MTLOriginMake(0, 0, 0),
sourceSize: MTLSizeMake(attachmentTexture.width, attachmentTexture.height, 1),
to: destinationBuffer,
destinationOffset: 1920*4,
destinationBytesPerRow: 1920*4*2,
destinationBytesPerImage: destinationBuffer.length)
blitEncoder.endEncoding()
commandBuffer.commit()
For the first field where the destination offset is zero the function works well. The destination buffer is filled for every second row.
But when I want to write the second field with the same code into the same MTLBuffer object only with the destinationOffset set to 1920*4 like you see in the code above (to start with the second row in the buffer) then I get an assertion like this:
-[MTLDebugBlitCommandEncoder validateCopyFromTexture:sourceSlice:sourceLevel:sourceOrigin:sourceSize:toBuffer:destinationOffset:destinationBytesPerRow:destinationBytesPerImage:options:]:677: failed assertion `totalBytesUsed(8302080) must be <= destinationBuffer length.'
The totalBytesUsed are exactly the destination buffer length in bytes plus the offset. So every offset I use in this function will result in this assertion error.
Can someone explain me how to use this function correctly because the other way around like creating two MTLTexture objects (odd and even fields) for an incoming video frame works well with similar parameters.