创建后更改 MTLBuffer 的值
Changing values of MTLBuffer after created
我希望能够定义一个 MTLBuffer 并将数据直接填充到缓冲区(或尽可能高效)。
如果我执行以下操作,着色器中使用的值是 1.0 和 2.0(分别用于 X 和 Y),而不是在创建 MTLBuffer
之后设置的 3.0 和 4.0。
int bufferLength = 128 * 128;
float pointBuffer[bufferLength * 2]; // 2 for X and Y
//Populate array with test values
for (int i = 0; i < (bufferLength * 2); i += 2) {
pointBuffer[i] = 1.0; //X
pointBuffer[i + 1] = 2.0; //Y
}
id<MTLBuffer> pointDataBuffer = [device newBufferWithBytes:&pointBuffer length:sizeof(pointBuffer) options:MTLResourceOptionCPUCacheModeDefault];
//Populate array with updated test values
for (int i = 0; i < (bufferLength * 2); i += 2) {
pointBuffer[i] = 3.0; //X
pointBuffer[i + 1] = 4.0; //Y
}
//In the (Swift) class with the pipeline:
commandEncoder!.setBuffer(pointDataBuffer, offset: 0, index: 4)
根据文档,我似乎需要调用 didModifyRange:
,但 pointDataBuffer
似乎无法识别选择器。
有没有无需重新创建 MTLBuffer 即可更新数组的方法?
-newBufferWithBytes:...
复制传入的字节。它不会一直引用它们。因此,对 pointBuffer
的后续更改不会影响它。
但是,像这样的缓冲区(其存储模式不是私有的)通过 -contents
方法提供对其存储的访问。所以,你可以这样做:
float *points = pointDataBuffer.contents;
for (int i = 0; i < (bufferLength * 2); i += 2) {
points[i] = 3.0; //X
points[i + 1] = 4.0; //Y
}
不过要小心。 CPU 和 GPU 相对于彼此异步操作。如果 GPU 正在处理引用缓冲区的命令,则从 CPU 修改它可能会干扰这些命令的操作。因此,您需要采取措施同步对缓冲区的访问,或者避免同时访问 CPU 和 GPU。
我希望能够定义一个 MTLBuffer 并将数据直接填充到缓冲区(或尽可能高效)。
如果我执行以下操作,着色器中使用的值是 1.0 和 2.0(分别用于 X 和 Y),而不是在创建 MTLBuffer
之后设置的 3.0 和 4.0。
int bufferLength = 128 * 128;
float pointBuffer[bufferLength * 2]; // 2 for X and Y
//Populate array with test values
for (int i = 0; i < (bufferLength * 2); i += 2) {
pointBuffer[i] = 1.0; //X
pointBuffer[i + 1] = 2.0; //Y
}
id<MTLBuffer> pointDataBuffer = [device newBufferWithBytes:&pointBuffer length:sizeof(pointBuffer) options:MTLResourceOptionCPUCacheModeDefault];
//Populate array with updated test values
for (int i = 0; i < (bufferLength * 2); i += 2) {
pointBuffer[i] = 3.0; //X
pointBuffer[i + 1] = 4.0; //Y
}
//In the (Swift) class with the pipeline:
commandEncoder!.setBuffer(pointDataBuffer, offset: 0, index: 4)
根据文档,我似乎需要调用 didModifyRange:
,但 pointDataBuffer
似乎无法识别选择器。
有没有无需重新创建 MTLBuffer 即可更新数组的方法?
-newBufferWithBytes:...
复制传入的字节。它不会一直引用它们。因此,对 pointBuffer
的后续更改不会影响它。
但是,像这样的缓冲区(其存储模式不是私有的)通过 -contents
方法提供对其存储的访问。所以,你可以这样做:
float *points = pointDataBuffer.contents;
for (int i = 0; i < (bufferLength * 2); i += 2) {
points[i] = 3.0; //X
points[i + 1] = 4.0; //Y
}
不过要小心。 CPU 和 GPU 相对于彼此异步操作。如果 GPU 正在处理引用缓冲区的命令,则从 CPU 修改它可能会干扰这些命令的操作。因此,您需要采取措施同步对缓冲区的访问,或者避免同时访问 CPU 和 GPU。