Skip to content

Commit f80a13d

Browse files
committed
TextureInner::Surface can now be zero initialized
1 parent 4b74c4f commit f80a13d

File tree

3 files changed

+59
-11
lines changed

3 files changed

+59
-11
lines changed

wgpu-core/src/device/mod.rs

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3465,17 +3465,16 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
34653465

34663466
let last_submit_index = texture.life_guard.life_count();
34673467

3468+
let clear_views =
3469+
match std::mem::replace(&mut texture.clear_mode, resource::TextureClearMode::None) {
3470+
resource::TextureClearMode::BufferCopy => SmallVec::new(),
3471+
resource::TextureClearMode::RenderPass { clear_views, .. } => clear_views,
3472+
resource::TextureClearMode::None => SmallVec::new(),
3473+
};
3474+
34683475
match texture.inner {
34693476
resource::TextureInner::Native { ref mut raw } => {
34703477
let raw = raw.take().ok_or(resource::DestroyError::AlreadyDestroyed)?;
3471-
let clear_views = match std::mem::replace(
3472-
&mut texture.clear_mode,
3473-
resource::TextureClearMode::None,
3474-
) {
3475-
resource::TextureClearMode::BufferCopy => SmallVec::new(),
3476-
resource::TextureClearMode::RenderPass { clear_views, .. } => clear_views,
3477-
resource::TextureClearMode::None => SmallVec::new(),
3478-
};
34793478
let temp = queue::TempResource::Texture(raw, clear_views);
34803479

34813480
if device.pending_writes.dst_textures.contains(&texture_id) {
@@ -3487,7 +3486,14 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
34873486
.schedule_resource_destruction(temp, last_submit_index);
34883487
}
34893488
}
3490-
resource::TextureInner::Surface { .. } => {} //TODO
3489+
resource::TextureInner::Surface { .. } => {
3490+
for clear_view in clear_views {
3491+
unsafe {
3492+
device.raw.destroy_texture_view(clear_view);
3493+
}
3494+
}
3495+
// TODO?
3496+
}
34913497
}
34923498

34933499
Ok(())

wgpu-core/src/present.rs

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ When this texture is presented, we remove it from the device tracker as well as
99
extract it from the hub.
1010
!*/
1111

12+
use std::{borrow::Borrow, num::NonZeroU32};
13+
1214
#[cfg(feature = "trace")]
1315
use crate::device::trace::Action;
1416
use crate::{
@@ -125,6 +127,31 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
125127
let suf = A::get_surface_mut(surface);
126128
let (texture_id, status) = match unsafe { suf.raw.acquire_texture(FRAME_TIMEOUT_MS) } {
127129
Ok(Some(ast)) => {
130+
let clear_view_desc = hal::TextureViewDescriptor {
131+
label: Some("clear texture view"),
132+
format: config.format,
133+
dimension: wgt::TextureViewDimension::D2,
134+
usage: hal::TextureUses::COLOR_TARGET,
135+
range: wgt::ImageSubresourceRange {
136+
aspect: wgt::TextureAspect::All,
137+
base_mip_level: 0,
138+
mip_level_count: NonZeroU32::new(1),
139+
base_array_layer: 0,
140+
array_layer_count: NonZeroU32::new(1),
141+
},
142+
};
143+
let mut clear_views = smallvec::SmallVec::new();
144+
clear_views.push(
145+
unsafe {
146+
hal::Device::create_texture_view(
147+
&device.raw,
148+
&ast.texture.borrow(),
149+
&clear_view_desc,
150+
)
151+
}
152+
.map_err(DeviceError::from)?,
153+
);
154+
128155
let present = surface.presentation.as_mut().unwrap();
129156
let texture = resource::Texture {
130157
inner: resource::TextureInner::Surface {
@@ -158,7 +185,10 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
158185
levels: 0..1,
159186
},
160187
life_guard: LifeGuard::new("<Surface>"),
161-
clear_mode: resource::TextureClearMode::None, // TODO: Shouldn't there be a view?
188+
clear_mode: resource::TextureClearMode::RenderPass {
189+
clear_views,
190+
is_color: true,
191+
},
162192
};
163193

164194
let ref_count = texture.life_guard.add_ref();
@@ -240,6 +270,16 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
240270

241271
let (texture, _) = hub.textures.unregister(texture_id.value.0, &mut token);
242272
if let Some(texture) = texture {
273+
if let resource::TextureClearMode::RenderPass { clear_views, .. } =
274+
texture.clear_mode
275+
{
276+
for clear_view in clear_views {
277+
unsafe {
278+
hal::Device::destroy_texture_view(&device.raw, clear_view);
279+
}
280+
}
281+
}
282+
243283
let suf = A::get_surface_mut(surface);
244284
match texture.inner {
245285
resource::TextureInner::Surface {

wgpu/examples/boids/main.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,9 @@ impl framework::Example for Example {
279279
view,
280280
resolve_target: None,
281281
ops: wgpu::Operations {
282-
load: wgpu::LoadOp::Clear(wgpu::Color::BLACK),
282+
// Not clearing here in order to test wgpu's zero texture initialization on a surface texture.
283+
// Users should avoid loading uninitialized memory since this can cause additional overhead.
284+
load: wgpu::LoadOp::Load,
283285
store: true,
284286
},
285287
}];

0 commit comments

Comments
 (0)