Skip to content

Commit 2b71b1f

Browse files
feat(deno): accept GPUTexture as GPUBindingResource
1 parent 375095f commit 2b71b1f

File tree

7 files changed

+110
-13
lines changed

7 files changed

+110
-13
lines changed

cts_runner/test.lst

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -110,14 +110,12 @@ webgpu:api,validation,image_copy,layout_related:copy_end_overflows_u64:*
110110
fails-if(dx12) webgpu:api,validation,image_copy,layout_related:offset_alignment:*
111111
webgpu:api,validation,image_copy,texture_related:format:dimension="1d";*
112112
webgpu:api,validation,queue,submit:command_buffer,*
113-
// `GPUTexture` as `GPUTextureView` not supported by Deno. https://github.com/gfx-rs/wgpu/issues/8200
114-
//FAIL: webgpu:api,validation,render_pass,render_pass_descriptor:attachments,one_color_attachment:
115-
//FAIL: webgpu:api,validation,render_pass,render_pass_descriptor:attachments,one_depth_stencil_attachment:
116-
webgpu:api,validation,render_pass,render_pass_descriptor:attachments,same_size:
117-
webgpu:api,validation,render_pass,render_pass_descriptor:attachments,color_depth_mismatch:
118-
webgpu:api,validation,render_pass,render_pass_descriptor:attachments,layer_count:*
119-
webgpu:api,validation,render_pass,render_pass_descriptor:attachments,mip_level_count:*
113+
webgpu:api,validation,render_pass,render_pass_descriptor:attachments,*
114+
webgpu:api,validation,render_pass,render_pass_descriptor:color_attachments,depthSlice,bound_check:*
115+
// Fails due to missing validation.
116+
// FAIL: webgpu:api,validation,render_pass,render_pass_descriptor:color_attachments,depthSlice,overlaps,diff_miplevel:*
120117
webgpu:api,validation,render_pass,render_pass_descriptor:resolveTarget,*
118+
webgpu:api,validation,render_pass,resolve:resolve_attachment:*
121119
webgpu:api,validation,texture,rg11b10ufloat_renderable:*
122120
webgpu:api,operation,render_pipeline,overrides:*
123121
webgpu:api,operation,rendering,basic:clear:*

deno_webgpu/bind_group.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use deno_core::WebIDL;
1717
use crate::buffer::GPUBuffer;
1818
use crate::error::GPUGenericError;
1919
use crate::sampler::GPUSampler;
20+
use crate::texture::GPUTexture;
2021
use crate::texture::GPUTextureView;
2122
use crate::Instance;
2223

@@ -93,6 +94,7 @@ pub(crate) struct GPUBufferBinding {
9394

9495
pub(crate) enum GPUBindingResource {
9596
Sampler(Ptr<GPUSampler>),
97+
Texture(Ptr<GPUTexture>),
9698
TextureView(Ptr<GPUTextureView>),
9799
Buffer(Ptr<GPUBuffer>),
98100
BufferBinding(GPUBufferBinding),
@@ -116,6 +118,16 @@ impl<'a> WebIdlConverter<'a> for GPUBindingResource {
116118
options,
117119
)
118120
.map(Self::Sampler)
121+
.or_else(|_| {
122+
<Ptr<GPUTexture>>::convert(
123+
scope,
124+
value,
125+
prefix.clone(),
126+
context.borrowed(),
127+
options,
128+
)
129+
.map(Self::Texture)
130+
})
119131
.or_else(|_| {
120132
<Ptr<GPUTextureView>>::convert(
121133
scope,

deno_webgpu/command_encoder.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,11 @@ impl GPUCommandEncoder {
7575
.map(|attachment| {
7676
attachment.into_option().map(|attachment| {
7777
wgpu_core::command::RenderPassColorAttachment {
78-
view: attachment.view.id,
78+
view: attachment.view.to_view_id(),
7979
depth_slice: attachment.depth_slice,
80-
resolve_target: attachment.resolve_target.map(|target| target.id),
80+
resolve_target: attachment
81+
.resolve_target
82+
.map(|target| target.to_view_id()),
8183
load_op: attachment
8284
.load_op
8385
.with_default_value(attachment.clear_value.map(Into::into)),
@@ -103,7 +105,7 @@ impl GPUCommandEncoder {
103105
}
104106

105107
Ok(wgpu_core::command::RenderPassDepthStencilAttachment {
106-
view: attachment.view.id,
108+
view: attachment.view.to_view_id(),
107109
depth: PassChannel {
108110
load_op: attachment
109111
.depth_load_op

deno_webgpu/device.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@ impl GPUDevice {
230230
instance: self.instance.clone(),
231231
error_handler: self.error_handler.clone(),
232232
id,
233+
default_view_id: Default::default(),
233234
label: descriptor.label,
234235
size: wgpu_descriptor.size,
235236
mip_level_count: wgpu_descriptor.mip_level_count,
@@ -403,6 +404,9 @@ impl GPUDevice {
403404
GPUBindingResource::Sampler(sampler) => {
404405
BindingResource::Sampler(sampler.id)
405406
}
407+
GPUBindingResource::Texture(texture) => {
408+
BindingResource::TextureView(texture.default_view_id())
409+
}
406410
GPUBindingResource::TextureView(texture_view) => {
407411
BindingResource::TextureView(texture_view.id)
408412
}

deno_webgpu/render_pass.rs

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ use std::num::NonZeroU64;
77
use deno_core::cppgc::Ptr;
88
use deno_core::op2;
99
use deno_core::v8;
10+
use deno_core::v8::HandleScope;
11+
use deno_core::v8::Local;
12+
use deno_core::v8::Value;
13+
use deno_core::webidl::ContextFn;
1014
use deno_core::webidl::IntOptions;
1115
use deno_core::webidl::Nullable;
1216
use deno_core::webidl::WebIdlConverter;
@@ -17,6 +21,7 @@ use deno_core::WebIDL;
1721
use crate::buffer::GPUBuffer;
1822
use crate::error::GPUGenericError;
1923
use crate::render_bundle::GPURenderBundle;
24+
use crate::texture::GPUTexture;
2025
use crate::texture::GPUTextureView;
2126
use crate::webidl::GPUColor;
2227
use crate::Instance;
@@ -441,10 +446,10 @@ pub(crate) struct GPURenderPassDescriptor {
441446
#[derive(WebIDL)]
442447
#[webidl(dictionary)]
443448
pub(crate) struct GPURenderPassColorAttachment {
444-
pub view: Ptr<GPUTextureView>,
449+
pub view: GPUTextureOrView,
445450
#[options(enforce_range = true)]
446451
pub depth_slice: Option<u32>,
447-
pub resolve_target: Option<Ptr<GPUTextureView>>,
452+
pub resolve_target: Option<GPUTextureOrView>,
448453
pub clear_value: Option<GPUColor>,
449454
pub load_op: GPULoadOp,
450455
pub store_op: GPUStoreOp,
@@ -495,7 +500,7 @@ impl From<GPUStoreOp> for wgpu_core::command::StoreOp {
495500
#[derive(WebIDL)]
496501
#[webidl(dictionary)]
497502
pub(crate) struct GPURenderPassDepthStencilAttachment {
498-
pub view: Ptr<GPUTextureView>,
503+
pub view: GPUTextureOrView,
499504
pub depth_clear_value: Option<f32>,
500505
pub depth_load_op: Option<GPULoadOp>,
501506
pub depth_store_op: Option<GPUStoreOp>,
@@ -519,3 +524,48 @@ pub(crate) struct GPURenderPassTimestampWrites {
519524
#[options(enforce_range = true)]
520525
pub end_of_pass_write_index: Option<u32>,
521526
}
527+
528+
pub(crate) enum GPUTextureOrView {
529+
Texture(Ptr<GPUTexture>),
530+
TextureView(Ptr<GPUTextureView>),
531+
}
532+
533+
impl GPUTextureOrView {
534+
pub(crate) fn to_view_id(&self) -> wgpu_core::id::TextureViewId {
535+
match self {
536+
Self::Texture(texture) => texture.default_view_id(),
537+
Self::TextureView(texture_view) => texture_view.id,
538+
}
539+
}
540+
}
541+
542+
impl<'a> WebIdlConverter<'a> for GPUTextureOrView {
543+
type Options = ();
544+
545+
fn convert<'b>(
546+
scope: &mut HandleScope<'a>,
547+
value: Local<'a, Value>,
548+
prefix: Cow<'static, str>,
549+
context: ContextFn<'b>,
550+
options: &Self::Options,
551+
) -> Result<Self, WebIdlError> {
552+
<Ptr<GPUTexture>>::convert(
553+
scope,
554+
value,
555+
prefix.clone(),
556+
context.borrowed(),
557+
options,
558+
)
559+
.map(Self::Texture)
560+
.or_else(|_| {
561+
<Ptr<GPUTextureView>>::convert(
562+
scope,
563+
value,
564+
prefix.clone(),
565+
context.borrowed(),
566+
options,
567+
)
568+
.map(Self::TextureView)
569+
})
570+
}
571+
}

deno_webgpu/surface.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ impl GPUCanvasContext {
146146
instance: config.device.instance.clone(),
147147
error_handler: config.device.error_handler.clone(),
148148
id,
149+
default_view_id: Default::default(),
149150
label: "".to_string(),
150151
size: wgpu_types::Extent3d {
151152
width: *self.width.borrow(),

deno_webgpu/texture.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
// Copyright 2018-2025 the Deno authors. MIT license.
22

3+
use std::sync::OnceLock;
4+
35
use deno_core::op2;
46
use deno_core::webidl::WebIdlInterfaceConverter;
57
use deno_core::GarbageCollected;
@@ -43,6 +45,7 @@ pub struct GPUTexture {
4345
pub error_handler: super::error::ErrorHandler,
4446

4547
pub id: wgpu_core::id::TextureId,
48+
pub default_view_id: OnceLock<wgpu_core::id::TextureViewId>,
4649

4750
pub label: String,
4851

@@ -54,8 +57,35 @@ pub struct GPUTexture {
5457
pub usage: u32,
5558
}
5659

60+
impl GPUTexture {
61+
pub(crate) fn default_view_id(&self) -> wgpu_core::id::TextureViewId {
62+
*self.default_view_id.get_or_init(|| {
63+
let (id, err) =
64+
self
65+
.instance
66+
.texture_create_view(self.id, &Default::default(), None);
67+
if let Some(err) = err {
68+
use wgpu_types::error::WebGpuError;
69+
assert_ne!(
70+
err.webgpu_error_type(),
71+
wgpu_types::error::ErrorType::Validation,
72+
concat!(
73+
"getting default view for a texture ",
74+
"caused a validation error (!?)"
75+
)
76+
);
77+
self.error_handler.push_error(Some(err));
78+
}
79+
id
80+
})
81+
}
82+
}
83+
5784
impl Drop for GPUTexture {
5885
fn drop(&mut self) {
86+
if let Some(id) = self.default_view_id.take() {
87+
self.instance.texture_view_drop(id).unwrap();
88+
}
5989
self.instance.texture_drop(self.id);
6090
}
6191
}

0 commit comments

Comments
 (0)