mirror of
https://github.com/denoland/deno.git
synced 2024-12-22 07:14:47 -05:00
fix(ext/webgpu): invalidate GPUAdapter when a device is created (#23752)
This removes the need for using `Deno.resources` to close the gpuadapter resource, while being more spec compliant.
This commit is contained in:
parent
19c0633a94
commit
6066e069d1
3 changed files with 24 additions and 23 deletions
|
@ -417,9 +417,12 @@ function createGPUAdapter(inner) {
|
||||||
return adapter;
|
return adapter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const _invalid = Symbol("[[invalid]]");
|
||||||
class GPUAdapter {
|
class GPUAdapter {
|
||||||
/** @type {InnerGPUAdapter} */
|
/** @type {InnerGPUAdapter} */
|
||||||
[_adapter];
|
[_adapter];
|
||||||
|
/** @type {bool} */
|
||||||
|
[_invalid];
|
||||||
|
|
||||||
/** @returns {GPUSupportedFeatures} */
|
/** @returns {GPUSupportedFeatures} */
|
||||||
get features() {
|
get features() {
|
||||||
|
@ -466,6 +469,12 @@ class GPUAdapter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this[_invalid]) {
|
||||||
|
throw new TypeError(
|
||||||
|
"The adapter cannot be reused, as it has been invalidated by a device creation",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const { rid, queueRid, features, limits } = op_webgpu_request_device(
|
const { rid, queueRid, features, limits } = op_webgpu_request_device(
|
||||||
this[_adapter].rid,
|
this[_adapter].rid,
|
||||||
descriptor.label,
|
descriptor.label,
|
||||||
|
@ -473,6 +482,8 @@ class GPUAdapter {
|
||||||
descriptor.requiredLimits,
|
descriptor.requiredLimits,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this[_invalid] = true;
|
||||||
|
|
||||||
const inner = new InnerGPUDevice({
|
const inner = new InnerGPUDevice({
|
||||||
rid,
|
rid,
|
||||||
adapter: this,
|
adapter: this,
|
||||||
|
@ -496,6 +507,12 @@ class GPUAdapter {
|
||||||
requestAdapterInfo() {
|
requestAdapterInfo() {
|
||||||
webidl.assertBranded(this, GPUAdapterPrototype);
|
webidl.assertBranded(this, GPUAdapterPrototype);
|
||||||
|
|
||||||
|
if (this[_invalid]) {
|
||||||
|
throw new TypeError(
|
||||||
|
"The adapter cannot be reused, as it has been invalidated by a device creation",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const {
|
const {
|
||||||
vendor,
|
vendor,
|
||||||
architecture,
|
architecture,
|
||||||
|
|
|
@ -673,7 +673,7 @@ pub fn op_webgpu_request_device(
|
||||||
) -> Result<GpuDeviceRes, AnyError> {
|
) -> Result<GpuDeviceRes, AnyError> {
|
||||||
let mut state = state.borrow_mut();
|
let mut state = state.borrow_mut();
|
||||||
let adapter_resource =
|
let adapter_resource =
|
||||||
state.resource_table.get::<WebGpuAdapter>(adapter_rid)?;
|
state.resource_table.take::<WebGpuAdapter>(adapter_rid)?;
|
||||||
let adapter = adapter_resource.1;
|
let adapter = adapter_resource.1;
|
||||||
let instance = state.borrow::<Instance>();
|
let instance = state.borrow::<Instance>();
|
||||||
|
|
||||||
|
@ -690,6 +690,7 @@ pub fn op_webgpu_request_device(
|
||||||
None,
|
None,
|
||||||
None
|
None
|
||||||
));
|
));
|
||||||
|
adapter_resource.close();
|
||||||
if let Some(err) = maybe_err {
|
if let Some(err) = maybe_err {
|
||||||
return Err(DomExceptionOperationError::new(&err.to_string()).into());
|
return Err(DomExceptionOperationError::new(&err.to_string()).into());
|
||||||
}
|
}
|
||||||
|
@ -731,13 +732,14 @@ pub fn op_webgpu_request_adapter_info(
|
||||||
state: Rc<RefCell<OpState>>,
|
state: Rc<RefCell<OpState>>,
|
||||||
#[smi] adapter_rid: ResourceId,
|
#[smi] adapter_rid: ResourceId,
|
||||||
) -> Result<GPUAdapterInfo, AnyError> {
|
) -> Result<GPUAdapterInfo, AnyError> {
|
||||||
let state = state.borrow_mut();
|
let mut state = state.borrow_mut();
|
||||||
let adapter_resource =
|
let adapter_resource =
|
||||||
state.resource_table.get::<WebGpuAdapter>(adapter_rid)?;
|
state.resource_table.take::<WebGpuAdapter>(adapter_rid)?;
|
||||||
let adapter = adapter_resource.1;
|
let adapter = adapter_resource.1;
|
||||||
let instance = state.borrow::<Instance>();
|
let instance = state.borrow::<Instance>();
|
||||||
|
|
||||||
let info = gfx_select!(adapter => instance.adapter_get_info(adapter))?;
|
let info = gfx_select!(adapter => instance.adapter_get_info(adapter))?;
|
||||||
|
adapter_resource.close();
|
||||||
|
|
||||||
Ok(GPUAdapterInfo {
|
Ok(GPUAdapterInfo {
|
||||||
vendor: info.vendor.to_string(),
|
vendor: info.vendor.to_string(),
|
||||||
|
|
|
@ -100,11 +100,6 @@ Deno.test({
|
||||||
stagingBuffer.unmap();
|
stagingBuffer.unmap();
|
||||||
|
|
||||||
device.destroy();
|
device.destroy();
|
||||||
|
|
||||||
// TODO(lucacasonato): webgpu spec should add a explicit destroy method for
|
|
||||||
// adapters.
|
|
||||||
const resources = Object.keys(Deno.resources());
|
|
||||||
Deno.close(Number(resources[resources.length - 1]));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Deno.test({
|
Deno.test({
|
||||||
|
@ -210,11 +205,6 @@ Deno.test({
|
||||||
outputBuffer.unmap();
|
outputBuffer.unmap();
|
||||||
|
|
||||||
device.destroy();
|
device.destroy();
|
||||||
|
|
||||||
// TODO(lucacasonato): webgpu spec should add a explicit destroy method for
|
|
||||||
// adapters.
|
|
||||||
const resources = Object.keys(Deno.resources());
|
|
||||||
Deno.close(Number(resources[resources.length - 1]));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Deno.test({
|
Deno.test({
|
||||||
|
@ -223,8 +213,8 @@ Deno.test({
|
||||||
const adapter = await navigator.gpu.requestAdapter();
|
const adapter = await navigator.gpu.requestAdapter();
|
||||||
assert(adapter);
|
assert(adapter);
|
||||||
assert(adapter.features);
|
assert(adapter.features);
|
||||||
const resources = Object.keys(Deno.resources());
|
const device = await adapter.requestDevice();
|
||||||
Deno.close(Number(resources[resources.length - 1]));
|
device.destroy();
|
||||||
});
|
});
|
||||||
|
|
||||||
Deno.test({
|
Deno.test({
|
||||||
|
@ -243,8 +233,6 @@ Deno.test({
|
||||||
);
|
);
|
||||||
|
|
||||||
device.destroy();
|
device.destroy();
|
||||||
const resources = Object.keys(Deno.resources());
|
|
||||||
Deno.close(Number(resources[resources.length - 1]));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Deno.test(function getPreferredCanvasFormat() {
|
Deno.test(function getPreferredCanvasFormat() {
|
||||||
|
@ -313,8 +301,6 @@ Deno.test({
|
||||||
);
|
);
|
||||||
|
|
||||||
device.destroy();
|
device.destroy();
|
||||||
const resources = Object.keys(Deno.resources());
|
|
||||||
Deno.close(Number(resources[resources.length - 1]));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Deno.test({
|
Deno.test({
|
||||||
|
@ -409,8 +395,6 @@ Deno.test({
|
||||||
// NOTE: GPUQueue.copyExternalImageToTexture needs to be validated the argument of copySize property's length when its a sequence, but it is not implemented yet
|
// NOTE: GPUQueue.copyExternalImageToTexture needs to be validated the argument of copySize property's length when its a sequence, but it is not implemented yet
|
||||||
|
|
||||||
device.destroy();
|
device.destroy();
|
||||||
const resources = Object.keys(Deno.resources());
|
|
||||||
Deno.close(Number(resources[resources.length - 1]));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Deno.test({
|
Deno.test({
|
||||||
|
@ -510,8 +494,6 @@ Deno.test({
|
||||||
// NOTE: GPUQueue.copyExternalImageToTexture needs to be validated the argument of destination.origin property's length when its a sequence, but it is not implemented yet
|
// NOTE: GPUQueue.copyExternalImageToTexture needs to be validated the argument of destination.origin property's length when its a sequence, but it is not implemented yet
|
||||||
|
|
||||||
device.destroy();
|
device.destroy();
|
||||||
const resources = Object.keys(Deno.resources());
|
|
||||||
Deno.close(Number(resources[resources.length - 1]));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
async function checkIsWsl() {
|
async function checkIsWsl() {
|
||||||
|
|
Loading…
Reference in a new issue