为什么 mac 上的 webgpu“最大绑定大小”比报告的“最大缓冲区大小”小得多?

问题描述 投票:0回答:2

我正在使用 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 似乎被忽略了。

google-chrome gpu gpgpu metal webgpu
2个回答
0
投票

您的问题是由

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
时使用该值。


0
投票

添加到@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

© www.soinside.com 2019 - 2024. All rights reserved.