我正在使用 Chrome 在高端 Mac 笔记本电脑上开发一个基于 WebGPU 的库。 该库主要设计用于实现计算着色器管道以进行操作 显微镜和其他 3D 体积数据 (https://github.com/AaronWatters/webgpu_volume)。
根据https://webgpureport.org/我应该能够分配4GB缓冲区 基于报告的 maxBufferSize 和 maxStorageBufferBindingSize。
但是,当我尝试分配较大的缓冲区时,我收到此错误消息:
Binding size (138331344) of [Buffer] is larger than the maximum binding size (134217728).
为什么报告的最大缓冲区大小是4GB,而执行时实际限制是134M?
有什么办法可以要求更高的限额吗?这是怎么回事?
请注意,以下问题类似,但没有任何有用的答案:绑定大小“...”大于最大绑定大小 (134217728)
(编辑)我尝试过这个:
const twoGig = 2147483648;
const required_limits = {};
// https://developer.mozilla.org/en-US/docs/Web/API/GPUDevice/limits
required_limits.maxStorageBufferBindingSize = twoGig;
required_limits.maxBufferSize = twoGig;
this.device = await this.adapter.requestDevice(required_limits);
但到目前为止,required_limits 似乎被忽略了。
您的问题是由
requestDevice
调用中对象的布局不正确引起的。正确的对象格式如下:
const twoGig = 2147483648;
const required_limits = {};
// https://developer.mozilla.org/en-US/docs/Web/API/GPUDevice/limits
required_limits.maxStorageBufferBindingSize = twoGig;
required_limits.maxBufferSize = twoGig;
this.device = await this.adapter.requestDevice({
"requiredLimits": required_limits
});
请注意,您所需的限制实际上需要是作为参数传入的对象内部的属性。这些是标准的相关部分:
requestDevice
函数,以及其参数对象。
另一方面,在生产应用程序中,我建议验证您的限制是否超过适配器实际支持的数量 - 如果超过,那么您的
requestDevice
调用将抛出 TypeError
, 如标准。由于大多数接受调查的设备仅支持 maxStorageBufferBindingSize
2147483644(略低于 2GiB),因此您的代码可能无法在大多数设备上运行。您可以通过检查其 limits
属性轻松查询适配器的限制,例如adapter.limits.maxStorageBufferBindingSize
,并在调用 requestDevice
时使用该值。
添加到@Permille 的答案
这样就变得更简单了
const twoGig = 2147483648;
const requiredLimits = {};
requiredLimits.maxStorageBufferBindingSize = twoGig;
requiredLimits.maxBufferSize = twoGig;
this.device = await this.adapter.requestDevice({
requiredLimits
});
或者这个
const twoGig = 2147483648;
const requiredLimits = {
maxStorageBufferBindingSize: twoGig,
maxBufferSize: twoGig,
};
this.device = await this.adapter.requestDevice({
requiredLimits
});
或者这个
const twoGig = 2147483648;
this.device = await this.adapter.requestDevice({
requiredLimits: {
maxStorageBufferBindingSize: twoGig,
maxBufferSize: twoGig,
},
});
正如@Permille 回答的那样,您可能想检查适配器是否支持您想要/需要的尺寸
const twoGig = 2147483648;
const { maxBufferSize, maxStorageBufferBindingSize } = this.adapter.limits;
if (maxBufferSize < twoGig ||
maxStorageBufferBindingSize < twoGig) {
// tell the user they're out of luck or refactor your code
// to work with smaller sizes. (like maybe multiple buffers?)
}
// request the adapter's maximum sizes
this.device = await this.adapter.requestDevice({
requiredLimits: {
maxStorageBufferBindingSize,
maxBufferSize,
},
});
注意:您可以自由地使用任何您想要的样式,但一般来说,大多数 JS 代码使用
camelCase
(包括所有浏览器 API)而不是 snake_case