Skip to content

Expose gpu allocation configuration options #5875

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jul 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,11 @@ By @teoxoy in [#5901](https://github.com/gfx-rs/wgpu/pull/5901)

- Added `as_hal` for `Buffer` to access wgpu created buffers form wgpu-hal. By @JasondeWolff in [#5724](https://github.com/gfx-rs/wgpu/pull/5724)
- Unconsumed vertex outputs are now always allowed. Removed `StageError::InputNotConsumed`, `Features::SHADER_UNUSED_VERTEX_OUTPUT`, and associated validation. By @Imberflur in [#5531](https://github.com/gfx-rs/wgpu/pull/5531)
- Added memory allocation hints to `DeviceDescriptor` by @nical in [#5875](https://github.com/gfx-rs/wgpu/pull/5875)
- `MemoryHints::Performance`, the default, favors performance over memory usage and will likely cause large amounts of VRAM to be allocated up-front. This hint is typically good for games.
- `MemoryHints::MemoryUsage` favors memory usage over performance. This hint is typically useful for smaller applications or UI libraries.
- `MemoryHints::Manual` allows the user to specify parameters for the underlying GPU memory allocator. These parameters are subject to change.
- These hints may be ignored by some backends. Currently only the Vulkan and D3D12 backends take them into account.

#### Naga

Expand Down
1 change: 1 addition & 0 deletions benches/benches/root.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ impl DeviceState {
&wgpu::DeviceDescriptor {
required_features: adapter.features(),
required_limits: adapter.limits(),
memory_hints: wgpu::MemoryHints::Performance,
label: Some("RenderPass Device"),
},
None,
Expand Down
1 change: 1 addition & 0 deletions deno_webgpu/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -668,6 +668,7 @@ pub fn op_webgpu_request_device(
label: Some(Cow::Owned(label)),
required_features: required_features.into(),
required_limits: required_limits.unwrap_or_default(),
memory_hints: wgpu_types::MemoryHints::default(),
};

let (device, queue, maybe_err) = gfx_select!(adapter => instance.adapter_request_device(
Expand Down
1 change: 1 addition & 0 deletions examples/src/framework.rs
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,7 @@ impl ExampleContext {
label: None,
required_features: (optional_features & adapter_features) | required_features,
required_limits: needed_limits,
memory_hints: wgpu::MemoryHints::MemoryUsage,
},
trace_dir.ok().as_ref().map(std::path::Path::new),
)
Expand Down
1 change: 1 addition & 0 deletions examples/src/hello_compute/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ async fn execute_gpu(numbers: &[u32]) -> Option<Vec<u32>> {
label: None,
required_features: wgpu::Features::empty(),
required_limits: wgpu::Limits::downlevel_defaults(),
memory_hints: wgpu::MemoryHints::MemoryUsage,
},
None,
)
Expand Down
1 change: 1 addition & 0 deletions examples/src/hello_synchronization/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ async fn run() {
label: None,
required_features: wgpu::Features::empty(),
required_limits: wgpu::Limits::downlevel_defaults(),
memory_hints: wgpu::MemoryHints::Performance,
},
None,
)
Expand Down
1 change: 1 addition & 0 deletions examples/src/hello_triangle/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ async fn run(event_loop: EventLoop<()>, window: Window) {
// Make sure we use the texture resolution limits from the adapter, so we can support images the size of the swapchain.
required_limits: wgpu::Limits::downlevel_webgl2_defaults()
.using_resolution(adapter.limits()),
memory_hints: wgpu::MemoryHints::MemoryUsage,
},
None,
)
Expand Down
1 change: 1 addition & 0 deletions examples/src/hello_windows/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ async fn run(event_loop: EventLoop<()>, viewports: Vec<(Arc<Window>, wgpu::Color
label: None,
required_features: wgpu::Features::empty(),
required_limits: wgpu::Limits::downlevel_defaults(),
memory_hints: wgpu::MemoryHints::MemoryUsage,
},
None,
)
Expand Down
1 change: 1 addition & 0 deletions examples/src/hello_workgroups/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ async fn run() {
label: None,
required_features: wgpu::Features::empty(),
required_limits: wgpu::Limits::downlevel_defaults(),
memory_hints: wgpu::MemoryHints::MemoryUsage,
},
None,
)
Expand Down
1 change: 1 addition & 0 deletions examples/src/render_to_texture/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ async fn run(_path: Option<String>) {
label: None,
required_features: wgpu::Features::empty(),
required_limits: wgpu::Limits::downlevel_defaults(),
memory_hints: wgpu::MemoryHints::MemoryUsage,
},
None,
)
Expand Down
1 change: 1 addition & 0 deletions examples/src/repeated_compute/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ impl WgpuContext {
label: None,
required_features: wgpu::Features::empty(),
required_limits: wgpu::Limits::downlevel_defaults(),
memory_hints: wgpu::MemoryHints::Performance,
},
None,
)
Expand Down
1 change: 1 addition & 0 deletions examples/src/storage_texture/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ async fn run(_path: Option<String>) {
label: None,
required_features: wgpu::Features::empty(),
required_limits: wgpu::Limits::downlevel_defaults(),
memory_hints: wgpu::MemoryHints::MemoryUsage,
},
None,
)
Expand Down
1 change: 1 addition & 0 deletions examples/src/timestamp_queries/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ async fn run() {
label: None,
required_features: features,
required_limits: wgpu::Limits::downlevel_defaults(),
memory_hints: wgpu::MemoryHints::MemoryUsage,
},
None,
)
Expand Down
1 change: 1 addition & 0 deletions examples/src/uniform_values/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ impl WgpuContext {
label: None,
required_features: wgpu::Features::empty(),
required_limits: wgpu::Limits::downlevel_defaults(),
memory_hints: wgpu::MemoryHints::MemoryUsage,
},
None,
)
Expand Down
1 change: 1 addition & 0 deletions player/tests/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ impl Test<'_> {
label: None,
required_features: self.features,
required_limits: wgt::Limits::default(),
memory_hints: wgt::MemoryHints::default(),
},
None,
Some(device_id),
Expand Down
1 change: 1 addition & 0 deletions tests/src/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ pub async fn initialize_device(
label: None,
required_features: features,
required_limits: limits,
memory_hints: wgpu::MemoryHints::MemoryUsage,
},
None,
)
Expand Down
8 changes: 5 additions & 3 deletions wgpu-core/src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -351,9 +351,11 @@ impl<A: HalApi> Adapter<A> {
}

let open = unsafe {
self.raw
.adapter
.open(desc.required_features, &desc.required_limits)
self.raw.adapter.open(
desc.required_features,
&desc.required_limits,
&desc.memory_hints,
)
}
.map_err(|err| match err {
hal::DeviceError::Lost => RequestDeviceError::DeviceLost,
Expand Down
6 changes: 5 additions & 1 deletion wgpu-hal/examples/halmark/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,11 @@ impl<A: hal::Api> Example<A> {

let hal::OpenDevice { device, queue } = unsafe {
adapter
.open(wgt::Features::empty(), &wgt::Limits::default())
.open(
wgt::Features::empty(),
&wgt::Limits::default(),
&wgt::MemoryHints::default(),
)
.unwrap()
};

Expand Down
8 changes: 5 additions & 3 deletions wgpu-hal/examples/raw-gles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,11 @@ fn fill_screen(exposed: &hal::ExposedAdapter<hal::api::Gles>, width: u32, height
use hal::{Adapter as _, CommandEncoder as _, Device as _, Queue as _};

let od = unsafe {
exposed
.adapter
.open(wgt::Features::empty(), &wgt::Limits::downlevel_defaults())
exposed.adapter.open(
wgt::Features::empty(),
&wgt::Limits::downlevel_defaults(),
&wgt::MemoryHints::default(),
)
}
.unwrap();

Expand Down
11 changes: 9 additions & 2 deletions wgpu-hal/examples/ray-traced-triangle/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,8 +249,15 @@ impl<A: hal::Api> Example<A> {
.expect("Surface doesn't support presentation");
log::info!("Surface caps: {:#?}", surface_caps);

let hal::OpenDevice { device, queue } =
unsafe { adapter.open(features, &wgt::Limits::default()).unwrap() };
let hal::OpenDevice { device, queue } = unsafe {
adapter
.open(
features,
&wgt::Limits::default(),
&wgt::MemoryHints::Performance,
)
.unwrap()
};

let window_size: (u32, u32) = window.inner_size().into();
dbg!(&surface_caps.formats);
Expand Down
2 changes: 2 additions & 0 deletions wgpu-hal/src/dx12/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,7 @@ impl crate::Adapter for super::Adapter {
&self,
_features: wgt::Features,
limits: &wgt::Limits,
memory_hints: &wgt::MemoryHints,
) -> Result<crate::OpenDevice<super::Api>, crate::DeviceError> {
let queue = {
profiling::scope!("ID3D12Device::CreateCommandQueue");
Expand All @@ -520,6 +521,7 @@ impl crate::Adapter for super::Adapter {
self.device.clone(),
queue.clone(),
limits,
memory_hints,
self.private_caps,
&self.library,
self.dxc_container.clone(),
Expand Down
3 changes: 2 additions & 1 deletion wgpu-hal/src/dx12/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,13 @@ impl super::Device {
raw: d3d12::Device,
present_queue: d3d12::CommandQueue,
limits: &wgt::Limits,
memory_hints: &wgt::MemoryHints,
private_caps: super::PrivateCapabilities,
library: &Arc<d3d12::D3D12Lib>,
dxc_container: Option<Arc<shader_compilation::DxcContainer>>,
) -> Result<Self, DeviceError> {
let mem_allocator = if private_caps.suballocation_supported {
super::suballocation::create_allocator_wrapper(&raw)?
super::suballocation::create_allocator_wrapper(&raw, memory_hints)?
} else {
None
};
Expand Down
21 changes: 20 additions & 1 deletion wgpu-hal/src/dx12/suballocation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,31 @@ mod placed {

pub(crate) fn create_allocator_wrapper(
raw: &d3d12::Device,
memory_hints: &wgt::MemoryHints,
) -> Result<Option<Mutex<GpuAllocatorWrapper>>, crate::DeviceError> {
let device = raw.as_ptr();

// TODO: the allocator's configuration should take hardware capability into
// account.
let mb = 1024 * 1024;
let allocation_sizes = match memory_hints {
wgt::MemoryHints::Performance => gpu_allocator::AllocationSizes::default(),
wgt::MemoryHints::MemoryUsage => gpu_allocator::AllocationSizes::new(8 * mb, 4 * mb),
wgt::MemoryHints::Manual {
suballocated_device_memory_block_size,
} => {
// TODO: Would it be useful to expose the host size in memory hints
// instead of always using half of the device size?
let device_size = suballocated_device_memory_block_size.start;
let host_size = device_size / 2;
gpu_allocator::AllocationSizes::new(device_size, host_size)
}
};

match gpu_allocator::d3d12::Allocator::new(&gpu_allocator::d3d12::AllocatorCreateDesc {
device: gpu_allocator::d3d12::ID3D12DeviceVersion::Device(device.as_windows().clone()),
debug_settings: Default::default(),
allocation_sizes: gpu_allocator::AllocationSizes::default(),
allocation_sizes,
}) {
Ok(allocator) => Ok(Some(Mutex::new(GpuAllocatorWrapper { allocator }))),
Err(e) => {
Expand Down Expand Up @@ -279,6 +297,7 @@ mod committed {
#[allow(unused)]
pub(crate) fn create_allocator_wrapper(
_raw: &d3d12::Device,
_memory_hints: &wgt::MemoryHints,
) -> Result<Option<Mutex<GpuAllocatorWrapper>>, crate::DeviceError> {
Ok(None)
}
Expand Down
1 change: 1 addition & 0 deletions wgpu-hal/src/empty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ impl crate::Adapter for Context {
&self,
features: wgt::Features,
_limits: &wgt::Limits,
_memory_hints: &wgt::MemoryHints,
) -> DeviceResult<crate::OpenDevice<Api>> {
Err(crate::DeviceError::Lost)
}
Expand Down
1 change: 1 addition & 0 deletions wgpu-hal/src/gles/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -929,6 +929,7 @@ impl crate::Adapter for super::Adapter {
&self,
features: wgt::Features,
_limits: &wgt::Limits,
_memory_hints: &wgt::MemoryHints,
) -> Result<crate::OpenDevice<super::Api>, crate::DeviceError> {
let gl = &self.shared.context.lock();
unsafe { gl.pixel_store_i32(glow::UNPACK_ALIGNMENT, 1) };
Expand Down
1 change: 1 addition & 0 deletions wgpu-hal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,7 @@ pub trait Adapter: WasmNotSendSync {
&self,
features: wgt::Features,
limits: &wgt::Limits,
memory_hints: &wgt::MemoryHints,
) -> Result<OpenDevice<Self::A>, DeviceError>;

/// Return the set of supported capabilities for a texture format.
Expand Down
1 change: 1 addition & 0 deletions wgpu-hal/src/metal/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ impl crate::Adapter for super::Adapter {
&self,
features: wgt::Features,
_limits: &wgt::Limits,
_memory_hints: &wgt::MemoryHints,
) -> Result<crate::OpenDevice<super::Api>, crate::DeviceError> {
let queue = self
.shared
Expand Down
52 changes: 51 additions & 1 deletion wgpu-hal/src/vulkan/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1583,6 +1583,7 @@ impl super::Adapter {
handle_is_owned: bool,
enabled_extensions: &[&'static CStr],
features: wgt::Features,
memory_hints: &wgt::MemoryHints,
family_index: u32,
queue_index: u32,
) -> Result<crate::OpenDevice<super::Api>, crate::DeviceError> {
Expand Down Expand Up @@ -1833,7 +1834,54 @@ impl super::Adapter {

let mem_allocator = {
let limits = self.phd_capabilities.properties.limits;
let config = gpu_alloc::Config::i_am_prototyping(); //TODO

// Note: the parameters here are not set in stone nor where they picked with
// strong confidence.
// `final_free_list_chunk` should be bigger than starting_free_list_chunk if
// we want the behavior of starting with smaller block sizes and using larger
// ones only after we observe that the small ones aren't enough, which I think
// is a good "I don't know what the workload is going to be like" approach.
//
// For reference, `VMA`, and `gpu_allocator` both start with 256 MB blocks
// (then VMA doubles the block size each time it needs a new block).
// At some point it would be good to experiment with real workloads
//
// TODO(#5925): The plan is to switch the Vulkan backend from `gpu_alloc` to
// `gpu_allocator` which has a different (simpler) set of configuration options.
//
// TODO: These parameters should take hardware capabilities into account.
let mb = 1024 * 1024;
let perf_cfg = gpu_alloc::Config {
starting_free_list_chunk: 128 * mb,
final_free_list_chunk: 512 * mb,
minimal_buddy_size: 1,
initial_buddy_dedicated_size: 8 * mb,
dedicated_threshold: 32 * mb,
preferred_dedicated_threshold: mb,
transient_dedicated_threshold: 128 * mb,
};
let mem_usage_cfg = gpu_alloc::Config {
starting_free_list_chunk: 8 * mb,
final_free_list_chunk: 64 * mb,
minimal_buddy_size: 1,
initial_buddy_dedicated_size: 8 * mb,
dedicated_threshold: 8 * mb,
preferred_dedicated_threshold: mb,
transient_dedicated_threshold: 16 * mb,
};
let config = match memory_hints {
wgt::MemoryHints::Performance => perf_cfg,
wgt::MemoryHints::MemoryUsage => mem_usage_cfg,
wgt::MemoryHints::Manual {
suballocated_device_memory_block_size,
} => gpu_alloc::Config {
starting_free_list_chunk: suballocated_device_memory_block_size.start,
final_free_list_chunk: suballocated_device_memory_block_size.end,
initial_buddy_dedicated_size: suballocated_device_memory_block_size.start,
..perf_cfg
},
};

let max_memory_allocation_size =
if let Some(maintenance_3) = self.phd_capabilities.maintenance_3 {
maintenance_3.max_memory_allocation_size
Expand Down Expand Up @@ -1895,6 +1943,7 @@ impl crate::Adapter for super::Adapter {
&self,
features: wgt::Features,
_limits: &wgt::Limits,
memory_hints: &wgt::MemoryHints,
) -> Result<crate::OpenDevice<super::Api>, crate::DeviceError> {
let enabled_extensions = self.required_device_extensions(features);
let mut enabled_phd_features = self.physical_device_features(&enabled_extensions, features);
Expand Down Expand Up @@ -1928,6 +1977,7 @@ impl crate::Adapter for super::Adapter {
true,
&enabled_extensions,
features,
memory_hints,
family_info.queue_family_index,
0,
)
Expand Down
Loading
Loading