files/en-us/web/api/gpuadapter/requestdevice/index.md
{{APIRef("WebGPU API")}}{{SecureContext_Header}}{{AvailableInWorkers}}
The requestDevice() method of the
{{domxref("GPUAdapter")}} interface returns a {{jsxref("Promise")}} that fulfills with a {{domxref("GPUDevice")}} object, which is the primary interface for communicating with the GPU.
requestDevice()
requestDevice(descriptor)
descriptor {{optional_inline}}
defaultQueue {{optional_inline}}
label — which provides the default queue with a {{domxref("GPUQueue.label", "label")}} value. If no value is provided, this defaults to an empty object, and the default queue's label will be an empty string.label {{optional_inline}}
requiredFeatures {{optional_inline}}
requestDevice() call will fail if the GPUAdapter cannot provide these features. See {{domxref("GPUSupportedFeatures")}} for a full list of possible features. This defaults to an empty array if no value is provided.requiredLimits {{optional_inline}}
requestDevice() call will fail if the GPUAdapter cannot provide these limits. Each key with a non-undefined value must be the name of a member of {{domxref("GPUSupportedLimits")}}.
[!NOTE] You can request unknown limits when requesting a GPU device without causing an error. Such limits will be
undefined. This is useful because it makes WebGPU code less brittle — a codebase won't stop working because a limit no longer exists in the adapter.
Not all features and limits will be available to WebGPU in all browsers that support it, even if they are supported by the underlying hardware. See the {{domxref("GPUAdapter.features", "features")}} and {{domxref("GPUAdapter.limits", "limits")}} pages for more information.
A {{jsxref("Promise")}} that fulfills with a {{domxref("GPUDevice")}} object instance.
If you make a duplicate call, i.e., call requestDevice() on a {{domxref("GPUAdapter")}} that requestDevice() was already called on, the promise rejects with an OperationError because the associated GPUAdapter is consumed when a GPUDevice is created.
OperationError {{domxref("DOMException")}}
OperationError if either:
requiredLimits property are not supported by the {{domxref("GPUAdapter")}}, either because they are not valid limits, or because their values are higher than the adapter's values for those limits.GPUAdapter has been consumed by having requestDevice() called on it previously.TypeError {{domxref("DOMException")}}
TypeError if the features included in the requiredFeatures property are not supported by the {{domxref("GPUAdapter")}}.async function init() {
if (!navigator.gpu) {
throw Error("WebGPU not supported.");
}
const adapter = await navigator.gpu.requestAdapter();
if (!adapter) {
throw Error("Couldn't request WebGPU adapter.");
}
const device = await adapter.requestDevice();
// …
}
In the following code we:
texture-compression-astc feature available. If so, we push it into the array of requiredFeatures.GPUAdapter.limits value of maxBindGroups to see if it is equal to or greater than 6. Our theoretical example app ideally needs 6 bind groups, so if the returned value is >= 6, we add a maximum limit of 6 to the requiredLimits object.defaultQueue label.async function init() {
if (!navigator.gpu) {
throw Error("WebGPU not supported.");
}
const adapter = await navigator.gpu.requestAdapter();
if (!adapter) {
throw Error("Couldn't request WebGPU adapter.");
}
const requiredFeatures = [];
if (adapter.features.has("texture-compression-astc")) {
requiredFeatures.push("texture-compression-astc");
}
const requiredLimits = {};
// App ideally needs 6 bind groups, so we'll try to request what the app needs
if (adapter.limits.maxBindGroups >= 6) {
requiredLimits.maxBindGroups = 6;
}
const device = await adapter.requestDevice({
defaultQueue: {
label: "my_queue",
},
requiredFeatures,
requiredLimits,
});
// …
}
{{Specifications}}
{{Compat}}