Tag: 金属

CAMetalLayer可绘制纹理在某些设备上很奇怪

我正在使用下面的代码来从金属层获取和追加像素缓冲区。 在某些非特定设备上,输出如下所示,并且可绘制纹理pixelFormat为.invalid static func make(with currentDrawable: CAMetalDrawable, usingBuffer pool: CVPixelBufferPool) -> (CVPixelBuffer?, UIImage) { let destinationTexture = currentDrawable.texture var pixelBuffer: CVPixelBuffer? _ = CVPixelBufferPoolCreatePixelBuffer(kCFAllocatorDefault, pool, &pixelBuffer) if let pixelBuffer = pixelBuffer { CVPixelBufferLockBaseAddress(pixelBuffer, CVPixelBufferLockFlags.init(rawValue: 0)) let region = MTLRegionMake2D(0, 0, Int(currentDrawable.layer.drawableSize.width), Int(currentDrawable.layer.drawableSize.height)) let bytesPerRow = CVPixelBufferGetBytesPerRow(pixelBuffer) let tempBuffer = CVPixelBufferGetBaseAddress(pixelBuffer) destinationTexture.getBytes(tempBuffer!, bytesPerRow: Int(bytesPerRow), from: region, […]

SpriteKit /金属内存泄漏没有任何事情发生

我有一个内存泄漏,我似乎无法追查。 仪器看到它,并将其报告为jet_buffer_Metal,但我不知道这是什么具体指向我。 它经常发生。 我已经尝试了一切。 删除所有我的节点,删除physicsBody,但它似乎仍然在那里。 我没有任何更新或任何其他的游戏循环方法。 我可以在那里发布所有的代码,但实际上我只添加了两个节点,只能移动。 我没有触摸屏幕,内存泄漏仍然存在。 我的一个节点有一个CircleOfRadius的PhysicsBody,我听说之前可能有一些types的泄漏,但是如果我用这个physicsBody去除节点,泄漏仍然存在。 最后,我在debugging窗口中得到这个: <SKMetalLayer: 0x14ce28da0>: calling -display has no effect. 我有一个相关的预感,但不能find它来自哪里。 我正在使用当前为空的SKS文件。 节点现在添加在代码中。

iOS上的数组的Swift金属并行计算

基于@Kametrixom的答案 ,我已经做了一些testing应用程序并行计算总和在一个数组中。 我的testing应用程序如下所示: import UIKit import Metal class ViewController: UIViewController { // Data type, has to be the same as in the shader typealias DataType = CInt override func viewDidLoad() { super.viewDidLoad() let data = (0..<10000000).map{ _ in DataType(200) } // Our data, randomly generated var start, end : UInt64 var result:DataType = 0 start […]

我可以从我的金属着色器中获得缓冲区的大小吗?

在我用Swift编写的iOS应用程序中,我生成一个Metal缓冲区: vertexBuffer = device.newBufferWithBytes(vertices, length: vertices.count * sizeofValue(vertices[0]), options: nil) 并将其绑定到我的着色器程序: renderCommandEncoder.setVertexBuffer(vertexBuffer, offset: 0, atIndex: 1) 在我使用Metal着色语言编写的着色器程序中,我可以访问缓冲区的大小吗? 我想访问我的缓冲区中的下一个顶点做一些差分计算。 就像是: vertex float4 my_vertex(const device packed_float3* vertices [[buffer(1)]], unsigned int vid[[vertex_id]]) { float4 vertex = vertices[vid]; // Need to clamp this to not go beyond buffer, // but how do I know the max value of vid? […]

裁剪和缩放MTLTexture

我可以创build一个现有MTLTexture区域x1/y1/w1/h1的尺寸为w2/h2的新MTLTexture吗? PS:我想过使用MTLTexture.buffer?.makeTexture但偏移量需要为64个字节。 为什么?

在Metal中手动设置一维纹理

我试图用值手动填充一维纹理 ,并将纹理传递给计算着色器(这些是我想通过代码设置的2个像素,它们不代表任何图像)。 由于目前less量的金属例子,我能find的所有例子都处理2D纹理 ,通过将加载的UIImage转换为原始字节数据来加载纹理,但是创build一个虚拟UIImage对我来说就像是黑客。 这是我开始的“天真”的方式 – … var manualTextureData: [Float] = [ 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0 ]; let region: MTLRegion = MTLRegionMake1D(0, textureDescriptor.width); myTexture.replaceRegion(region, mipmapLevel: 0, withBytes: &manualTextureData, bytesPerRow: 0); 但是Metal没有在着色器中识别这些值(除了第一个值,它会得到一个空的纹理)。 我很快意识到,浮点数组可能必须转换成一个字节数组(例如UInt8 ),但无法find一种方法从[Float]转换为[UInt8] 。 我考虑的另一个可能的select是使用一个CVPixelBuffer对象,但是这也是解决问题的办法。 那么最好的解决方法是什么? 提前致谢。 请注意,我不熟悉Objective-C ,因此我不确定使用CVPixelBuffer / UIImage是否夸大了某些应该是直截了当的事情。

捕获金属MTKView作为电影实时?

什么是从MTKView捕获帧的最有效的方法? 如果可能的话,我想实时保存帧中的.mov文件。 是否有可能渲染成一个AVPlayer框架或东西? 目前正在使用此代码(基于@warrenm PerformanceShaders 项目 )进行绘制: func draw(in view: MTKView) { _ = inflightSemaphore.wait(timeout: DispatchTime.distantFuture) updateBuffers() let commandBuffer = commandQueue.makeCommandBuffer() commandBuffer.addCompletedHandler{ [weak self] commandBuffer in if let strongSelf = self { strongSelf.inflightSemaphore.signal() } } // Dispatch the current kernel to perform the selected image filter selectedKernel.encode(commandBuffer: commandBuffer, sourceTexture: kernelSourceTexture!, destinationTexture: kernelDestTexture!) if let renderPassDescriptor […]

有效地将Swift Array复制到iOS Metal的内存缓冲区

我正在使用Apple的新Metal框架编写iOS应用程序。 我有一个Matrix4对象的数组(请参阅Ray Wenderlich的教程 ),我需要通过MTLDevice.newBufferWithLength()方法将其传递给着色器。 Matrix4对象利用了Apple的GLKit(它包含一个GLKMatrix4对象)。 我正在利用GPU调用的实例。 稍后我会将其更改为一个包含每个实例更多数据的结构(超出了Matrix4对象的范围)。 如何有效地将[Matrix4]对象的数组复制到此缓冲区? 有一个更好的方法吗? 再次,我将展开这个使用未来更多数据的结构。 以下是我的代码的一个子集: let sizeofMatrix4 = sizeof(Float) * Matrix4.numberofElements() // This returns an array of [Matrix4] objects. let boxArray = createBoxArray(parentModelViewMatrix) let sizeOfUniformBuffer = boxArray.count * sizeOfMatrix4 var uniformBuffer = device.newBufferWithLength(sizeofUniformBuffer, options: .CPUCacheModeDefaultCache) let bufferPointer = uniformBuffer?.contents() // Ouch – way too slow. How can I optimize? […]

内存写入性能 – GPU CPU共享内存

我将根据MTLBuffer提供的共享GPU / CPU文档,使用posix_memalign来分配input和输出MTLBuffer。 另外:使用最新的API比posix_memalign更容易 let metalBuffer = self.metalDevice.newBufferWithLength(byteCount, options: .StorageModeShared) 我的内核函数在大约一千六百万个复杂的价值结构上运行,并写出相同数量的复数值结构来存储。 我已经执行了一些实验,我的金属内核'复杂的math部分'在0.003秒内执行(是!),但是将结果写入缓冲区需要> 0.05(No!)秒。 在我的实验中,我注释了math部分,只是把零分配给内存,它需要0.05秒,注释掉这个任务,并把算术加回去0.003秒。 在这种情况下共享内存是否缓慢,或者我可能会尝试一些其他的提示或技巧? 额外的细节 testing平台 iPhone 6S – 每帧约0.039秒 iPad Air 2 – 每帧〜0.130秒 stream数据 对着色器的每次更新都会以结构中一对floattypes的forms接收大约50000个复数。 struct ComplexNumber { float real; float imaginary; }; 内核签名 kernel void processChannelData(const device Parameters *parameters [[ buffer(0) ]], const device ComplexNumber *inputSampleData [[ buffer(1) ]], const device […]

金属屏幕撕裂和相机捕获

为了避免同时从gpu和cpu写入一个常量缓冲区,Applebuild议在信号量的帮助下使用一个三重缓冲系统,以防止cpu在gpu之前过多(这是很好的,并且覆盖在现阶段至less有三个金属video)。 但是,当常量资源是MTLTexture并且AVCaptureVideoDataOutput委托单独运行而不是渲染循环(CADisplaylink)时,类似的三重缓冲系统(如Apple的示例代码MetalVideoCapture中所用的)如何保证同步? 如果使用MetalVideoCapture代码,只需渲染全屏四边形并将预设更改为AVCaptureSessionPresetHigh(在撕裂被旋转四边形和低质量预设遮挡的时刻),则可以观察到撕裂(纹理撕裂)。 我意识到渲染循环和captureOutput委托方法(在这种情况下)都在主线程上,并且信号量(在渲染循环中)保持_constantDataBufferIndex整数被检查(哪些索引进入MTLTexture进行创build和编码),但仍然可以观察到屏幕撕裂,这是令人费解的(如果纹理的GPU写入不是编码后的下一帧,而是2或3帧之后,这是有意义的,但我不认为这是事实)。 此外,只是一个小点:渲染循环和captureOutput不应该有一个缓冲的纹理系统相同的帧率,所以旧的帧不交替与最近的交错。 任何想法或澄清这个问题将不胜感激; McZonk还有另外一个例子,它没有使用三重缓冲系统,但是我也观察到这种方法(但不那么重要)。 显然,如果我使用waitUntilCompleted(相当于Open GL的glfinish),那么就不会有撕裂的痕迹,但是就像在背后系着一只arm来演奏手风琴一样!