Skip to content

Commit 1967900

Browse files
andyleisersonWumpf
andauthored
Encode commands on finish (#8220)
Co-authored-by: Andreas Reich <[email protected]>
1 parent 990aef9 commit 1967900

File tree

17 files changed

+1367
-995
lines changed

17 files changed

+1367
-995
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ By @cwfitzgerald in [#8162](https://github.com/gfx-rs/wgpu/pull/8162).
170170

171171
#### General
172172

173+
- Command encoding now happens when `CommandEncoder::finish` is called, not when the individual operations are requested. This does not affect the API, but may affect performance characteristics. By @andyleiserson in [#8220](https://github.com/gfx-rs/wgpu/pull/8220).
173174
- Prevent resources for acceleration structures being created if acceleration structures are not enabled. By @Vecvec in [#8036](https://github.com/gfx-rs/wgpu/pull/8036).
174175
- Validate that each `push_debug_group` pairs with exactly one `pop_debug_group`. By @andyleiserson in [#8048](https://github.com/gfx-rs/wgpu/pull/8048).
175176
- `set_viewport` now requires that the supplied minimum depth value is less than the maximum depth value. By @andyleiserson in [#8040](https://github.com/gfx-rs/wgpu/pull/8040).

deno_webgpu/queue.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ impl GPUQueue {
140140
#[webidl] data_layout: GPUTexelCopyBufferLayout,
141141
#[webidl] size: GPUExtent3D,
142142
) {
143-
let destination = wgpu_core::command::TexelCopyTextureInfo {
143+
let destination = wgpu_types::TexelCopyTextureInfo {
144144
texture: destination.texture.id,
145145
mip_level: destination.mip_level,
146146
origin: destination.origin.into(),

tests/tests/wgpu-gpu/life_cycle.rs

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
use wgpu::{util::DeviceExt, Backends};
2-
use wgpu_test::{
3-
fail, gpu_test, FailureCase, GpuTestConfiguration, GpuTestInitializer, TestParameters,
4-
};
1+
use wgpu::util::DeviceExt;
2+
use wgpu_test::{fail, gpu_test, GpuTestConfiguration, GpuTestInitializer, TestParameters};
53

64
pub fn all_tests(vec: &mut Vec<GpuTestInitializer>) {
75
vec.extend([
@@ -118,12 +116,7 @@ static TEXTURE_DESTROY: GpuTestConfiguration = GpuTestConfiguration::new()
118116
// submission fails gracefully.
119117
#[gpu_test]
120118
static BUFFER_DESTROY_BEFORE_SUBMIT: GpuTestConfiguration = GpuTestConfiguration::new()
121-
.parameters(
122-
// https://github.com/gfx-rs/wgpu/issues/7854
123-
TestParameters::default()
124-
.skip(FailureCase::backend_adapter(Backends::VULKAN, "llvmpipe"))
125-
.enable_noop(),
126-
)
119+
.parameters(TestParameters::default().enable_noop())
127120
.run_sync(|ctx| {
128121
let buffer_source = ctx
129122
.device
@@ -160,12 +153,7 @@ static BUFFER_DESTROY_BEFORE_SUBMIT: GpuTestConfiguration = GpuTestConfiguration
160153
// submission fails gracefully.
161154
#[gpu_test]
162155
static TEXTURE_DESTROY_BEFORE_SUBMIT: GpuTestConfiguration = GpuTestConfiguration::new()
163-
.parameters(
164-
// https://github.com/gfx-rs/wgpu/issues/7854
165-
TestParameters::default()
166-
.skip(FailureCase::backend_adapter(Backends::VULKAN, "llvmpipe"))
167-
.enable_noop(),
168-
)
156+
.parameters(TestParameters::default().enable_noop())
169157
.run_sync(|ctx| {
170158
let descriptor = wgpu::TextureDescriptor {
171159
label: None,

wgpu-core/src/command/clear.rs

Lines changed: 51 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@ use core::ops::Range;
55
use crate::command::Command as TraceCommand;
66
use crate::{
77
api_log,
8-
command::{CommandBufferMutable, CommandEncoder, EncoderStateError},
8+
command::{encoder::EncodingState, ArcCommand, EncoderStateError},
99
device::{DeviceError, MissingFeatures},
1010
get_lowest_common_denom,
1111
global::Global,
1212
hal_label,
1313
id::{BufferId, CommandEncoderId, TextureId},
1414
init_tracker::{MemoryInitKind, TextureInitRange},
1515
resource::{
16-
DestroyedResourceError, InvalidResourceError, Labeled, MissingBufferUsageError,
16+
Buffer, DestroyedResourceError, InvalidResourceError, Labeled, MissingBufferUsageError,
1717
ParentDevice, RawResourceAccess, ResourceErrorIdent, Texture, TextureClearMode,
1818
},
1919
snatch::SnatchGuard,
@@ -118,8 +118,18 @@ impl Global {
118118

119119
let cmd_enc = hub.command_encoders.get(command_encoder_id);
120120
let mut cmd_buf_data = cmd_enc.data.lock();
121-
cmd_buf_data.record_with(|cmd_buf_data| -> Result<(), ClearError> {
122-
clear_buffer(cmd_buf_data, hub, &cmd_enc, dst, offset, size)
121+
122+
#[cfg(feature = "trace")]
123+
if let Some(ref mut list) = cmd_buf_data.trace() {
124+
list.push(TraceCommand::ClearBuffer { dst, offset, size });
125+
}
126+
127+
cmd_buf_data.push_with(|| -> Result<_, ClearError> {
128+
Ok(ArcCommand::ClearBuffer {
129+
dst: self.resolve_buffer_id(dst)?,
130+
offset,
131+
size,
132+
})
123133
})
124134
}
125135

@@ -136,38 +146,38 @@ impl Global {
136146

137147
let cmd_enc = hub.command_encoders.get(command_encoder_id);
138148
let mut cmd_buf_data = cmd_enc.data.lock();
139-
cmd_buf_data.record_with(|cmd_buf_data| -> Result<(), ClearError> {
140-
clear_texture_cmd(cmd_buf_data, hub, &cmd_enc, dst, subresource_range)
149+
150+
#[cfg(feature = "trace")]
151+
if let Some(ref mut list) = cmd_buf_data.trace() {
152+
list.push(TraceCommand::ClearTexture {
153+
dst,
154+
subresource_range: *subresource_range,
155+
});
156+
}
157+
158+
cmd_buf_data.push_with(|| -> Result<_, ClearError> {
159+
Ok(ArcCommand::ClearTexture {
160+
dst: self.resolve_texture_id(dst)?,
161+
subresource_range: *subresource_range,
162+
})
141163
})
142164
}
143165
}
144166

145167
pub(super) fn clear_buffer(
146-
cmd_buf_data: &mut CommandBufferMutable,
147-
hub: &crate::hub::Hub,
148-
cmd_enc: &Arc<CommandEncoder>,
149-
dst: BufferId,
168+
state: &mut EncodingState,
169+
dst_buffer: Arc<Buffer>,
150170
offset: BufferAddress,
151171
size: Option<BufferAddress>,
152172
) -> Result<(), ClearError> {
153-
#[cfg(feature = "trace")]
154-
if let Some(ref mut list) = cmd_buf_data.trace_commands {
155-
list.push(TraceCommand::ClearBuffer { dst, offset, size });
156-
}
157-
158-
cmd_enc.device.check_is_valid()?;
159-
160-
let dst_buffer = hub.buffers.get(dst).get()?;
173+
dst_buffer.same_device(state.device)?;
161174

162-
dst_buffer.same_device_as(cmd_enc.as_ref())?;
163-
164-
let dst_pending = cmd_buf_data
165-
.trackers
175+
let dst_pending = state
176+
.tracker
166177
.buffers
167178
.set_single(&dst_buffer, wgt::BufferUses::COPY_DST);
168179

169-
let snatch_guard = dst_buffer.device.snatchable_lock.read();
170-
let dst_raw = dst_buffer.try_raw(&snatch_guard)?;
180+
let dst_raw = dst_buffer.try_raw(state.snatch_guard)?;
171181
dst_buffer.check_usage(BufferUsages::COPY_DST)?;
172182

173183
// Check if offset & size are valid.
@@ -200,20 +210,19 @@ pub(super) fn clear_buffer(
200210
}
201211

202212
// Mark dest as initialized.
203-
cmd_buf_data.buffer_memory_init_actions.extend(
204-
dst_buffer.initialization_status.read().create_action(
213+
state
214+
.buffer_memory_init_actions
215+
.extend(dst_buffer.initialization_status.read().create_action(
205216
&dst_buffer,
206217
offset..end_offset,
207218
MemoryInitKind::ImplicitlyInitialized,
208-
),
209-
);
219+
));
210220

211221
// actual hal barrier & operation
212-
let dst_barrier = dst_pending.map(|pending| pending.into_hal(&dst_buffer, &snatch_guard));
213-
let cmd_buf_raw = cmd_buf_data.encoder.open()?;
222+
let dst_barrier = dst_pending.map(|pending| pending.into_hal(&dst_buffer, state.snatch_guard));
214223
unsafe {
215-
cmd_buf_raw.transition_buffers(dst_barrier.as_slice());
216-
cmd_buf_raw.clear_buffer(dst_raw, offset..end_offset);
224+
state.raw_encoder.transition_buffers(dst_barrier.as_slice());
225+
state.raw_encoder.clear_buffer(dst_raw, offset..end_offset);
217226
}
218227

219228
Ok(())
@@ -227,30 +236,15 @@ pub(super) fn clear_buffer(
227236
/// this function, is a lower-level function that encodes a texture clear
228237
/// operation without validating it.
229238
pub(super) fn clear_texture_cmd(
230-
cmd_buf_data: &mut CommandBufferMutable,
231-
hub: &crate::hub::Hub,
232-
cmd_enc: &Arc<CommandEncoder>,
233-
dst: TextureId,
239+
state: &mut EncodingState,
240+
dst_texture: Arc<Texture>,
234241
subresource_range: &ImageSubresourceRange,
235242
) -> Result<(), ClearError> {
236-
#[cfg(feature = "trace")]
237-
if let Some(ref mut list) = cmd_buf_data.trace_commands {
238-
list.push(TraceCommand::ClearTexture {
239-
dst,
240-
subresource_range: *subresource_range,
241-
});
242-
}
243-
244-
cmd_enc.device.check_is_valid()?;
245-
246-
cmd_enc
243+
dst_texture.same_device(state.device)?;
244+
state
247245
.device
248246
.require_features(wgt::Features::CLEAR_TEXTURE)?;
249247

250-
let dst_texture = hub.textures.get(dst).get()?;
251-
252-
dst_texture.same_device_as(cmd_enc.as_ref())?;
253-
254248
// Check if subresource aspects are valid.
255249
let clear_aspects = hal::FormatAspects::new(dst_texture.desc.format, subresource_range.aspect);
256250
if clear_aspects.is_empty() {
@@ -283,23 +277,18 @@ pub(super) fn clear_texture_cmd(
283277
});
284278
}
285279

286-
let device = &cmd_enc.device;
287-
device.check_is_valid()?;
288-
let (encoder, tracker) = cmd_buf_data.open_encoder_and_tracker()?;
289-
290-
let snatch_guard = device.snatchable_lock.read();
291280
clear_texture(
292281
&dst_texture,
293282
TextureInitRange {
294283
mip_range: subresource_mip_range,
295284
layer_range: subresource_layer_range,
296285
},
297-
encoder,
298-
&mut tracker.textures,
299-
&device.alignments,
300-
device.zero_buffer.as_ref(),
301-
&snatch_guard,
302-
device.instance_flags,
286+
state.raw_encoder,
287+
&mut state.tracker.textures,
288+
&state.device.alignments,
289+
state.device.zero_buffer.as_ref(),
290+
state.snatch_guard,
291+
state.device.instance_flags,
303292
)?;
304293

305294
Ok(())

0 commit comments

Comments
 (0)