【发布时间】: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;
}
如果有人有任何想法,我将不胜感激!
【问题讨论】:
-
你能提供这个问题吗?