【问题标题】:How to use Metal argument buffer?如何使用 Metal 参数缓冲区?
【发布时间】:2021-05-01 20:31:29
【问题描述】:

我正在尝试使用 Metal 参数缓冲区来访问 Metal 计算内核中的数据。 当我打印出 CPU 端的值时,缓冲区有一个条目,但 Xcode 调试器在 GPU 上显示我的参数缓冲区为空。

我可以在调试器中看到带有标记值的缓冲区作为间接资源,但在参数缓冲区中没有指向它的指针。

这是 Swift 代码:

import MetalKit

do {
    let device = MTLCreateSystemDefaultDevice()!
    let capture_manager = MTLCaptureManager.shared()
    let capture_desc = MTLCaptureDescriptor()
    capture_desc.captureObject = device
    try capture_manager.startCapture(with: capture_desc)
    
    let argument_desc = MTLArgumentDescriptor()
    argument_desc.dataType = MTLDataType.pointer
    argument_desc.index = 0
    argument_desc.arrayLength = 1024
    
    let argument_encoder = device.makeArgumentEncoder(arguments: [argument_desc])!
    
    let argument_buffer = device.makeBuffer(length: argument_encoder.encodedLength, options: MTLResourceOptions())
    argument_encoder.setArgumentBuffer(argument_buffer, offset: 0)
    
    var sentinel: UInt32 = 12345
    let ptr = UnsafeRawPointer.init(&sentinel)
    
    let buffer = device.makeBuffer(bytes: ptr, length: 4, options: MTLResourceOptions.storageModeShared)!
    argument_encoder.setBuffer(buffer, offset: 0, index: 0)
    
    let source = try String(contentsOf: URL.init(fileURLWithPath: "/path/to/kernel.metal"))
    let library = try device.makeLibrary(source: source, options: MTLCompileOptions())
    let function = library.makeFunction(name: "main0")!
    
    let pipeline = try device.makeComputePipelineState(function: function)
    
    let queue = device.makeCommandQueue()!
    let encoder = queue.makeCommandBuffer()!
    
    let compute_encoder = encoder.makeComputeCommandEncoder()!
    
    compute_encoder.setComputePipelineState(pipeline)
    compute_encoder.setBuffer(argument_buffer, offset: 0, index: 0)
    compute_encoder.useResource(buffer, usage: MTLResourceUsage.read)
    compute_encoder.dispatchThreads(MTLSize.init(width: 1, height: 1, depth: 1), threadsPerThreadgroup: MTLSize.init(width: 1, height: 1, depth: 1))
    
    compute_encoder.endEncoding()
    
    encoder.commit()
    encoder.waitUntilCompleted()

    capture_manager.stopCapture()
} catch {
    print(error)
    exit(1)
}

还有计算内核:

#include <metal_stdlib>
#include <simd/simd.h>

using namespace metal;

struct Argument {
    constant uint32_t *ptr [[id(0)]];
};

kernel void main0(
    constant Argument *bufferArray [[buffer(0)]]
) {
    constant uint32_t *ptr = bufferArray[0].ptr;
    uint32_t y = *ptr;
}

如果有人有任何想法,我将不胜感激!

【问题讨论】:

  • 你能提供这个问题吗?

标签: swift graphics gpu metal


【解决方案1】:

似乎 Metal 优化了内核或类似的东西,因为它只执行读取操作。

更改内核以写入缓冲区使一切正常并在 Xcode 调试器中正确显示。

【讨论】:

    猜你喜欢
    • 2022-11-11
    • 2017-09-27
    • 1970-01-01
    • 2016-09-26
    • 2017-10-08
    • 2019-07-29
    • 2016-05-07
    • 2016-02-06
    • 1970-01-01
    相关资源
    最近更新 更多