From 2c0067067c19b948bfe8e11751960e1abd862f6d Mon Sep 17 00:00:00 2001 From: marc0246 <40955683+marc0246@users.noreply.github.com> Date: Wed, 19 Jul 2023 11:11:17 +0200 Subject: [PATCH] Switch to a more expressive way to specify memory usage (#2264) * Switch to a more expressive way to specify memory usage * Fix tests * Fix examples * Forgot to adjust `SubbufferAllocatorCreateInfo::location_preference`s * Oopsie * Redo all of it * Oopsie --- examples/src/bin/async-update.rs | 11 +- examples/src/bin/basic-compute-shader.rs | 5 +- examples/src/bin/buffer-allocator.rs | 4 +- .../deferred/frame/ambient_lighting_system.rs | 5 +- .../frame/directional_lighting_system.rs | 31 +- .../deferred/frame/point_lighting_system.rs | 5 +- .../src/bin/deferred/triangle_draw_system.rs | 5 +- examples/src/bin/dynamic-buffers.rs | 8 +- examples/src/bin/dynamic-local-size.rs | 5 +- examples/src/bin/gl-interop.rs | 7 +- examples/src/bin/image-self-copy-blit/main.rs | 8 +- examples/src/bin/image/main.rs | 8 +- examples/src/bin/immutable-sampler/main.rs | 8 +- examples/src/bin/indirect.rs | 6 +- examples/src/bin/instancing.rs | 34 +- .../fractal_compute_pipeline.rs | 8 +- .../pixels_draw_pipeline.rs | 8 +- examples/src/bin/msaa-renderpass.rs | 8 +- examples/src/bin/multi-window.rs | 5 +- .../multi_window_game_of_life/game_of_life.rs | 5 +- .../multi_window_game_of_life/pixels_draw.rs | 8 +- examples/src/bin/multiview.rs | 8 +- examples/src/bin/occlusion-query.rs | 5 +- examples/src/bin/push-constants.rs | 32 +- examples/src/bin/push-descriptors/main.rs | 8 +- examples/src/bin/runtime-shader/main.rs | 5 +- examples/src/bin/runtime_array/main.rs | 11 +- examples/src/bin/self-copy-buffer.rs | 5 +- examples/src/bin/shader-include/main.rs | 32 +- examples/src/bin/shader-types-sharing.rs | 5 +- examples/src/bin/simple-particles.rs | 7 +- examples/src/bin/specialization-constants.rs | 32 +- examples/src/bin/teapot/main.rs | 13 +- examples/src/bin/tessellation.rs | 5 +- examples/src/bin/texture_array/main.rs | 8 +- examples/src/bin/triangle-v1_3.rs | 5 +- examples/src/bin/triangle.rs | 5 +- vulkano/src/buffer/allocator.rs | 67 +++- vulkano/src/buffer/mod.rs | 32 +- vulkano/src/buffer/subbuffer.rs | 7 +- vulkano/src/buffer/view.rs | 8 +- vulkano/src/command_buffer/auto/mod.rs | 20 +- vulkano/src/memory/allocator/mod.rs | 345 ++++++++++++++---- vulkano/src/memory/allocator/suballocator.rs | 34 +- vulkano/src/pipeline/compute.rs | 5 +- 45 files changed, 579 insertions(+), 317 deletions(-) diff --git a/examples/src/bin/async-update.rs b/examples/src/bin/async-update.rs index 400884a603..a69206a647 100644 --- a/examples/src/bin/async-update.rs +++ b/examples/src/bin/async-update.rs @@ -68,7 +68,7 @@ use vulkano::{ Image, ImageCreateInfo, ImageType, ImageUsage, }, instance::{Instance, InstanceCreateFlags, InstanceCreateInfo}, - memory::allocator::{AllocationCreateInfo, MemoryUsage, StandardMemoryAllocator}, + memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator}, pipeline::{ graphics::{ color_blend::ColorBlendState, @@ -281,7 +281,8 @@ fn main() { ..Default::default() }, AllocationCreateInfo { - usage: MemoryUsage::Upload, + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, ..Default::default() }, vertices, @@ -299,7 +300,8 @@ fn main() { ..Default::default() }, AllocationCreateInfo { - usage: MemoryUsage::Upload, + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, ..Default::default() }, ) @@ -715,7 +717,8 @@ fn run_worker( ..Default::default() }, AllocationCreateInfo { - usage: MemoryUsage::Upload, + memory_type_filter: MemoryTypeFilter::PREFER_HOST + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, ..Default::default() }, (0..TRANSFER_GRANULARITY * TRANSFER_GRANULARITY).map(|_| [0u8; 4]), diff --git a/examples/src/bin/basic-compute-shader.rs b/examples/src/bin/basic-compute-shader.rs index e7dc821a24..59ec05f07c 100644 --- a/examples/src/bin/basic-compute-shader.rs +++ b/examples/src/bin/basic-compute-shader.rs @@ -26,7 +26,7 @@ use vulkano::{ QueueFlags, }, instance::{Instance, InstanceCreateFlags, InstanceCreateInfo}, - memory::allocator::{AllocationCreateInfo, MemoryUsage, StandardMemoryAllocator}, + memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator}, pipeline::{ compute::ComputePipelineCreateInfo, layout::PipelineDescriptorSetLayoutCreateInfo, ComputePipeline, Pipeline, PipelineBindPoint, PipelineLayout, @@ -171,7 +171,8 @@ fn main() { ..Default::default() }, AllocationCreateInfo { - usage: MemoryUsage::Upload, + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE + | MemoryTypeFilter::HOST_RANDOM_ACCESS, ..Default::default() }, // Iterator that produces the data. diff --git a/examples/src/bin/buffer-allocator.rs b/examples/src/bin/buffer-allocator.rs index 517366d64c..cc10747757 100644 --- a/examples/src/bin/buffer-allocator.rs +++ b/examples/src/bin/buffer-allocator.rs @@ -28,7 +28,7 @@ use vulkano::{ }, image::{view::ImageView, Image, ImageUsage}, instance::{Instance, InstanceCreateFlags, InstanceCreateInfo}, - memory::allocator::StandardMemoryAllocator, + memory::allocator::{MemoryTypeFilter, StandardMemoryAllocator}, pipeline::{ graphics::{ color_blend::ColorBlendState, @@ -169,6 +169,8 @@ fn main() { SubbufferAllocatorCreateInfo { // We want to use the allocated subbuffers as vertex buffers. buffer_usage: BufferUsage::VERTEX_BUFFER, + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, ..Default::default() }, ); diff --git a/examples/src/bin/deferred/frame/ambient_lighting_system.rs b/examples/src/bin/deferred/frame/ambient_lighting_system.rs index 9f6716c314..14b8975aef 100644 --- a/examples/src/bin/deferred/frame/ambient_lighting_system.rs +++ b/examples/src/bin/deferred/frame/ambient_lighting_system.rs @@ -19,7 +19,7 @@ use vulkano::{ }, device::Queue, image::view::ImageView, - memory::allocator::{AllocationCreateInfo, MemoryAllocator, MemoryUsage}, + memory::allocator::{AllocationCreateInfo, MemoryAllocator, MemoryTypeFilter}, pipeline::{ graphics::{ color_blend::{AttachmentBlend, BlendFactor, BlendOp, ColorBlendState}, @@ -78,7 +78,8 @@ impl AmbientLightingSystem { ..Default::default() }, AllocationCreateInfo { - usage: MemoryUsage::Upload, + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, ..Default::default() }, vertices, diff --git a/examples/src/bin/deferred/frame/directional_lighting_system.rs b/examples/src/bin/deferred/frame/directional_lighting_system.rs index 243fd4d05e..f072d2f959 100644 --- a/examples/src/bin/deferred/frame/directional_lighting_system.rs +++ b/examples/src/bin/deferred/frame/directional_lighting_system.rs @@ -20,7 +20,7 @@ use vulkano::{ }, device::Queue, image::view::ImageView, - memory::allocator::{AllocationCreateInfo, MemoryAllocator, MemoryUsage}, + memory::allocator::{AllocationCreateInfo, MemoryAllocator, MemoryTypeFilter}, pipeline::{ graphics::{ color_blend::{AttachmentBlend, BlendFactor, BlendOp, ColorBlendState}, @@ -72,21 +72,20 @@ impl DirectionalLightingSystem { position: [3.0, -1.0], }, ]; - let vertex_buffer = { - Buffer::from_iter( - memory_allocator, - BufferCreateInfo { - usage: BufferUsage::VERTEX_BUFFER, - ..Default::default() - }, - AllocationCreateInfo { - usage: MemoryUsage::Upload, - ..Default::default() - }, - vertices, - ) - .expect("failed to create buffer") - }; + let vertex_buffer = Buffer::from_iter( + memory_allocator, + BufferCreateInfo { + usage: BufferUsage::VERTEX_BUFFER, + ..Default::default() + }, + AllocationCreateInfo { + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, + ..Default::default() + }, + vertices, + ) + .expect("failed to create buffer"); let pipeline = { let device = gfx_queue.device(); diff --git a/examples/src/bin/deferred/frame/point_lighting_system.rs b/examples/src/bin/deferred/frame/point_lighting_system.rs index 3eeb89c3f6..69c5ab78b0 100644 --- a/examples/src/bin/deferred/frame/point_lighting_system.rs +++ b/examples/src/bin/deferred/frame/point_lighting_system.rs @@ -20,7 +20,7 @@ use vulkano::{ }, device::Queue, image::view::ImageView, - memory::allocator::{AllocationCreateInfo, MemoryAllocator, MemoryUsage}, + memory::allocator::{AllocationCreateInfo, MemoryAllocator, MemoryTypeFilter}, pipeline::{ graphics::{ color_blend::{AttachmentBlend, BlendFactor, BlendOp, ColorBlendState}, @@ -78,7 +78,8 @@ impl PointLightingSystem { ..Default::default() }, AllocationCreateInfo { - usage: MemoryUsage::Upload, + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, ..Default::default() }, vertices, diff --git a/examples/src/bin/deferred/triangle_draw_system.rs b/examples/src/bin/deferred/triangle_draw_system.rs index 00f71d1bf6..55c8b7d2f3 100644 --- a/examples/src/bin/deferred/triangle_draw_system.rs +++ b/examples/src/bin/deferred/triangle_draw_system.rs @@ -15,7 +15,7 @@ use vulkano::{ CommandBufferInheritanceInfo, CommandBufferUsage, SecondaryAutoCommandBuffer, }, device::Queue, - memory::allocator::{AllocationCreateInfo, MemoryUsage, StandardMemoryAllocator}, + memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator}, pipeline::{ graphics::{ color_blend::ColorBlendState, @@ -67,7 +67,8 @@ impl TriangleDrawSystem { ..Default::default() }, AllocationCreateInfo { - usage: MemoryUsage::Upload, + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, ..Default::default() }, vertices, diff --git a/examples/src/bin/dynamic-buffers.rs b/examples/src/bin/dynamic-buffers.rs index 418d2e043c..c97023b55d 100644 --- a/examples/src/bin/dynamic-buffers.rs +++ b/examples/src/bin/dynamic-buffers.rs @@ -28,7 +28,7 @@ use vulkano::{ QueueFlags, }, instance::{Instance, InstanceCreateFlags, InstanceCreateInfo}, - memory::allocator::{AllocationCreateInfo, MemoryUsage, StandardMemoryAllocator}, + memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator}, pipeline::{ compute::ComputePipelineCreateInfo, layout::PipelineDescriptorSetLayoutCreateInfo, ComputePipeline, Pipeline, PipelineBindPoint, PipelineLayout, @@ -194,7 +194,8 @@ fn main() { ..Default::default() }, AllocationCreateInfo { - usage: MemoryUsage::Upload, + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, ..Default::default() }, aligned_data, @@ -208,7 +209,8 @@ fn main() { ..Default::default() }, AllocationCreateInfo { - usage: MemoryUsage::Upload, + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE + | MemoryTypeFilter::HOST_RANDOM_ACCESS, ..Default::default() }, (0..12).map(|_| 0u32), diff --git a/examples/src/bin/dynamic-local-size.rs b/examples/src/bin/dynamic-local-size.rs index 14dd61a0d1..15db77a8a7 100644 --- a/examples/src/bin/dynamic-local-size.rs +++ b/examples/src/bin/dynamic-local-size.rs @@ -30,7 +30,7 @@ use vulkano::{ format::Format, image::{view::ImageView, Image, ImageCreateInfo, ImageType, ImageUsage}, instance::{Instance, InstanceCreateFlags, InstanceCreateInfo, InstanceExtensions}, - memory::allocator::{AllocationCreateInfo, MemoryUsage, StandardMemoryAllocator}, + memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator}, pipeline::{ compute::ComputePipelineCreateInfo, layout::PipelineDescriptorSetLayoutCreateInfo, ComputePipeline, Pipeline, PipelineBindPoint, PipelineLayout, @@ -244,7 +244,8 @@ fn main() { ..Default::default() }, AllocationCreateInfo { - usage: MemoryUsage::Download, + memory_type_filter: MemoryTypeFilter::PREFER_HOST + | MemoryTypeFilter::HOST_RANDOM_ACCESS, ..Default::default() }, (0..1024 * 1024 * 4).map(|_| 0u8), diff --git a/examples/src/bin/gl-interop.rs b/examples/src/bin/gl-interop.rs index 821c4bbbe8..c52af7c8f9 100644 --- a/examples/src/bin/gl-interop.rs +++ b/examples/src/bin/gl-interop.rs @@ -40,7 +40,7 @@ mod linux { }, memory::{ allocator::{ - AllocationCreateInfo, MemoryAlloc, MemoryAllocator, MemoryUsage, + AllocationCreateInfo, MemoryAlloc, MemoryAllocator, MemoryTypeFilter, StandardMemoryAllocator, }, DedicatedAllocation, DeviceMemory, ExternalMemoryHandleType, ExternalMemoryHandleTypes, @@ -139,7 +139,7 @@ mod linux { memory_type_index: memory_allocator .find_memory_type_index( image_requirements.memory_type_bits, - MemoryUsage::DeviceOnly.into(), + MemoryTypeFilter::PREFER_DEVICE, ) .unwrap(), dedicated_allocation: Some(DedicatedAllocation::Image(&raw_image)), @@ -610,7 +610,8 @@ mod linux { ..Default::default() }, AllocationCreateInfo { - usage: MemoryUsage::Upload, + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, ..Default::default() }, vertices, diff --git a/examples/src/bin/image-self-copy-blit/main.rs b/examples/src/bin/image-self-copy-blit/main.rs index 9fbfd17db7..fad89305b4 100644 --- a/examples/src/bin/image-self-copy-blit/main.rs +++ b/examples/src/bin/image-self-copy-blit/main.rs @@ -30,7 +30,7 @@ use vulkano::{ Image, ImageCreateInfo, ImageLayout, ImageUsage, }, instance::{Instance, InstanceCreateFlags, InstanceCreateInfo}, - memory::allocator::{AllocationCreateInfo, MemoryUsage, StandardMemoryAllocator}, + memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator}, pipeline::{ graphics::{ color_blend::ColorBlendState, @@ -188,7 +188,8 @@ fn main() { ..Default::default() }, AllocationCreateInfo { - usage: MemoryUsage::Upload, + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, ..Default::default() }, vertices, @@ -236,7 +237,8 @@ fn main() { ..Default::default() }, AllocationCreateInfo { - usage: MemoryUsage::Upload, + memory_type_filter: MemoryTypeFilter::PREFER_HOST + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, ..Default::default() }, (info.width * info.height * 4) as DeviceSize, diff --git a/examples/src/bin/image/main.rs b/examples/src/bin/image/main.rs index aa27d6c00d..33bc24aff0 100644 --- a/examples/src/bin/image/main.rs +++ b/examples/src/bin/image/main.rs @@ -28,7 +28,7 @@ use vulkano::{ Image, ImageCreateInfo, ImageType, ImageUsage, }, instance::{Instance, InstanceCreateFlags, InstanceCreateInfo}, - memory::allocator::{AllocationCreateInfo, MemoryUsage, StandardMemoryAllocator}, + memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator}, pipeline::{ graphics::{ color_blend::ColorBlendState, @@ -186,7 +186,8 @@ fn main() { ..Default::default() }, AllocationCreateInfo { - usage: MemoryUsage::Upload, + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, ..Default::default() }, vertices, @@ -234,7 +235,8 @@ fn main() { ..Default::default() }, AllocationCreateInfo { - usage: MemoryUsage::Upload, + memory_type_filter: MemoryTypeFilter::PREFER_HOST + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, ..Default::default() }, (info.width * info.height * 4) as DeviceSize, diff --git a/examples/src/bin/immutable-sampler/main.rs b/examples/src/bin/immutable-sampler/main.rs index 7c0404d3bc..64f4c56fcf 100644 --- a/examples/src/bin/immutable-sampler/main.rs +++ b/examples/src/bin/immutable-sampler/main.rs @@ -37,7 +37,7 @@ use vulkano::{ Image, ImageCreateInfo, ImageType, ImageUsage, }, instance::{Instance, InstanceCreateFlags, InstanceCreateInfo}, - memory::allocator::{AllocationCreateInfo, MemoryUsage, StandardMemoryAllocator}, + memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator}, pipeline::{ graphics::{ color_blend::ColorBlendState, @@ -192,7 +192,8 @@ fn main() { ..Default::default() }, AllocationCreateInfo { - usage: MemoryUsage::Upload, + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, ..Default::default() }, vertices, @@ -240,7 +241,8 @@ fn main() { ..Default::default() }, AllocationCreateInfo { - usage: MemoryUsage::Upload, + memory_type_filter: MemoryTypeFilter::PREFER_HOST + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, ..Default::default() }, (info.width * info.height * 4) as DeviceSize, diff --git a/examples/src/bin/indirect.rs b/examples/src/bin/indirect.rs index dacc5bd257..363c8fc22a 100644 --- a/examples/src/bin/indirect.rs +++ b/examples/src/bin/indirect.rs @@ -42,7 +42,7 @@ use vulkano::{ }, image::{view::ImageView, Image, ImageUsage}, instance::{Instance, InstanceCreateFlags, InstanceCreateInfo}, - memory::allocator::StandardMemoryAllocator, + memory::allocator::{MemoryTypeFilter, StandardMemoryAllocator}, pipeline::{ compute::ComputePipelineCreateInfo, graphics::{ @@ -253,6 +253,8 @@ fn main() { memory_allocator.clone(), SubbufferAllocatorCreateInfo { buffer_usage: BufferUsage::INDIRECT_BUFFER | BufferUsage::STORAGE_BUFFER, + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, ..Default::default() }, ); @@ -260,6 +262,8 @@ fn main() { memory_allocator, SubbufferAllocatorCreateInfo { buffer_usage: BufferUsage::STORAGE_BUFFER | BufferUsage::VERTEX_BUFFER, + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, ..Default::default() }, ); diff --git a/examples/src/bin/instancing.rs b/examples/src/bin/instancing.rs index 2503106f6a..560327fcdc 100644 --- a/examples/src/bin/instancing.rs +++ b/examples/src/bin/instancing.rs @@ -25,7 +25,7 @@ use vulkano::{ }, image::{view::ImageView, Image, ImageUsage}, instance::{Instance, InstanceCreateFlags, InstanceCreateInfo}, - memory::allocator::{AllocationCreateInfo, MemoryUsage, StandardMemoryAllocator}, + memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator}, pipeline::{ graphics::{ color_blend::ColorBlendState, @@ -184,21 +184,20 @@ fn main() { position: [0.25, -0.1], }, ]; - let vertex_buffer = { - Buffer::from_iter( - &memory_allocator, - BufferCreateInfo { - usage: BufferUsage::VERTEX_BUFFER, - ..Default::default() - }, - AllocationCreateInfo { - usage: MemoryUsage::Upload, - ..Default::default() - }, - vertices, - ) - .unwrap() - }; + let vertex_buffer = Buffer::from_iter( + &memory_allocator, + BufferCreateInfo { + usage: BufferUsage::VERTEX_BUFFER, + ..Default::default() + }, + AllocationCreateInfo { + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, + ..Default::default() + }, + vertices, + ) + .unwrap(); // Now we create another buffer that will store the unique data per instance. For this example, // we'll have the instances form a 10x10 grid that slowly gets larger. @@ -230,7 +229,8 @@ fn main() { ..Default::default() }, AllocationCreateInfo { - usage: MemoryUsage::Upload, + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, ..Default::default() }, instances, diff --git a/examples/src/bin/interactive_fractal/fractal_compute_pipeline.rs b/examples/src/bin/interactive_fractal/fractal_compute_pipeline.rs index 343a45d278..ea337818be 100644 --- a/examples/src/bin/interactive_fractal/fractal_compute_pipeline.rs +++ b/examples/src/bin/interactive_fractal/fractal_compute_pipeline.rs @@ -21,7 +21,7 @@ use vulkano::{ }, device::Queue, image::view::ImageView, - memory::allocator::{AllocationCreateInfo, MemoryUsage, StandardMemoryAllocator}, + memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator}, pipeline::{ compute::ComputePipelineCreateInfo, layout::PipelineDescriptorSetLayoutCreateInfo, ComputePipeline, Pipeline, PipelineBindPoint, PipelineLayout, @@ -65,7 +65,8 @@ impl FractalComputePipeline { ..Default::default() }, AllocationCreateInfo { - usage: MemoryUsage::Upload, + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, ..Default::default() }, colors, @@ -124,7 +125,8 @@ impl FractalComputePipeline { ..Default::default() }, AllocationCreateInfo { - usage: MemoryUsage::Upload, + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, ..Default::default() }, colors, diff --git a/examples/src/bin/interactive_fractal/pixels_draw_pipeline.rs b/examples/src/bin/interactive_fractal/pixels_draw_pipeline.rs index 07320ac3be..bd97d48f03 100644 --- a/examples/src/bin/interactive_fractal/pixels_draw_pipeline.rs +++ b/examples/src/bin/interactive_fractal/pixels_draw_pipeline.rs @@ -22,7 +22,7 @@ use vulkano::{ sampler::{Filter, Sampler, SamplerAddressMode, SamplerCreateInfo, SamplerMipmapMode}, view::ImageView, }, - memory::allocator::{AllocationCreateInfo, MemoryAllocator, MemoryUsage}, + memory::allocator::{AllocationCreateInfo, MemoryAllocator, MemoryTypeFilter}, pipeline::{ graphics::{ color_blend::ColorBlendState, @@ -101,7 +101,8 @@ impl PixelsDrawPipeline { ..Default::default() }, AllocationCreateInfo { - usage: MemoryUsage::Upload, + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, ..Default::default() }, vertices, @@ -114,7 +115,8 @@ impl PixelsDrawPipeline { ..Default::default() }, AllocationCreateInfo { - usage: MemoryUsage::Upload, + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, ..Default::default() }, indices, diff --git a/examples/src/bin/msaa-renderpass.rs b/examples/src/bin/msaa-renderpass.rs index fb510f1367..dcf00c3171 100644 --- a/examples/src/bin/msaa-renderpass.rs +++ b/examples/src/bin/msaa-renderpass.rs @@ -76,7 +76,7 @@ use vulkano::{ format::Format, image::{view::ImageView, Image, ImageCreateInfo, ImageType, ImageUsage, SampleCount}, instance::{Instance, InstanceCreateFlags, InstanceCreateInfo}, - memory::allocator::{AllocationCreateInfo, MemoryUsage, StandardMemoryAllocator}, + memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator}, pipeline::{ graphics::{ color_blend::ColorBlendState, @@ -305,7 +305,8 @@ fn main() { ..Default::default() }, AllocationCreateInfo { - usage: MemoryUsage::Upload, + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, ..Default::default() }, vertices, @@ -373,7 +374,8 @@ fn main() { ..Default::default() }, AllocationCreateInfo { - usage: MemoryUsage::Download, + memory_type_filter: MemoryTypeFilter::PREFER_HOST + | MemoryTypeFilter::HOST_RANDOM_ACCESS, ..Default::default() }, (0..1024 * 1024 * 4).map(|_| 0u8), diff --git a/examples/src/bin/multi-window.rs b/examples/src/bin/multi-window.rs index ad4e22be61..86ba4da950 100644 --- a/examples/src/bin/multi-window.rs +++ b/examples/src/bin/multi-window.rs @@ -29,7 +29,7 @@ use vulkano::{ }, image::{view::ImageView, Image, ImageUsage}, instance::{Instance, InstanceCreateFlags, InstanceCreateInfo}, - memory::allocator::{AllocationCreateInfo, MemoryUsage, StandardMemoryAllocator}, + memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator}, pipeline::{ graphics::{ color_blend::ColorBlendState, @@ -205,7 +205,8 @@ fn main() { ..Default::default() }, AllocationCreateInfo { - usage: MemoryUsage::Upload, + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, ..Default::default() }, vertices, diff --git a/examples/src/bin/multi_window_game_of_life/game_of_life.rs b/examples/src/bin/multi_window_game_of_life/game_of_life.rs index 60e6678090..5774831e08 100644 --- a/examples/src/bin/multi_window_game_of_life/game_of_life.rs +++ b/examples/src/bin/multi_window_game_of_life/game_of_life.rs @@ -23,7 +23,7 @@ use vulkano::{ device::Queue, format::Format, image::{view::ImageView, Image, ImageCreateInfo, ImageType, ImageUsage}, - memory::allocator::{AllocationCreateInfo, MemoryAllocator, MemoryUsage}, + memory::allocator::{AllocationCreateInfo, MemoryAllocator, MemoryTypeFilter}, pipeline::{ compute::ComputePipelineCreateInfo, layout::PipelineDescriptorSetLayoutCreateInfo, ComputePipeline, Pipeline, PipelineBindPoint, PipelineLayout, @@ -54,7 +54,8 @@ fn rand_grid(memory_allocator: &impl MemoryAllocator, size: [u32; 2]) -> Subbuff ..Default::default() }, AllocationCreateInfo { - usage: MemoryUsage::Upload, + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, ..Default::default() }, (0..(size[0] * size[1])).map(|_| rand::thread_rng().gen_range(0u32..=1)), diff --git a/examples/src/bin/multi_window_game_of_life/pixels_draw.rs b/examples/src/bin/multi_window_game_of_life/pixels_draw.rs index 3dc28f9bff..6ecfac64e7 100644 --- a/examples/src/bin/multi_window_game_of_life/pixels_draw.rs +++ b/examples/src/bin/multi_window_game_of_life/pixels_draw.rs @@ -23,7 +23,7 @@ use vulkano::{ sampler::{Filter, Sampler, SamplerAddressMode, SamplerCreateInfo, SamplerMipmapMode}, view::ImageView, }, - memory::allocator::{AllocationCreateInfo, MemoryUsage}, + memory::allocator::{AllocationCreateInfo, MemoryTypeFilter}, pipeline::{ graphics::{ color_blend::ColorBlendState, @@ -97,7 +97,8 @@ impl PixelsDrawPipeline { ..Default::default() }, AllocationCreateInfo { - usage: MemoryUsage::Upload, + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, ..Default::default() }, vertices, @@ -110,7 +111,8 @@ impl PixelsDrawPipeline { ..Default::default() }, AllocationCreateInfo { - usage: MemoryUsage::Upload, + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, ..Default::default() }, indices, diff --git a/examples/src/bin/multiview.rs b/examples/src/bin/multiview.rs index 1bcbf2fa22..e2ff5e1262 100644 --- a/examples/src/bin/multiview.rs +++ b/examples/src/bin/multiview.rs @@ -29,7 +29,7 @@ use vulkano::{ ImageUsage, SampleCount, }, instance::{Instance, InstanceCreateFlags, InstanceCreateInfo, InstanceExtensions}, - memory::allocator::{AllocationCreateInfo, MemoryUsage, StandardMemoryAllocator}, + memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator}, pipeline::{ graphics::{ color_blend::ColorBlendState, @@ -177,7 +177,8 @@ fn main() { ..Default::default() }, AllocationCreateInfo { - usage: MemoryUsage::Upload, + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, ..Default::default() }, vertices, @@ -318,7 +319,8 @@ fn main() { ..Default::default() }, AllocationCreateInfo { - usage: MemoryUsage::Download, + memory_type_filter: MemoryTypeFilter::PREFER_HOST + | MemoryTypeFilter::HOST_RANDOM_ACCESS, ..Default::default() }, (0..image.extent()[0] * image.extent()[1] * 4).map(|_| 0u8), diff --git a/examples/src/bin/occlusion-query.rs b/examples/src/bin/occlusion-query.rs index baa226f4d7..d6ed354ea2 100644 --- a/examples/src/bin/occlusion-query.rs +++ b/examples/src/bin/occlusion-query.rs @@ -25,7 +25,7 @@ use vulkano::{ format::Format, image::{view::ImageView, Image, ImageCreateInfo, ImageType, ImageUsage}, instance::{Instance, InstanceCreateFlags, InstanceCreateInfo}, - memory::allocator::{AllocationCreateInfo, MemoryUsage, StandardMemoryAllocator}, + memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator}, pipeline::{ graphics::{ color_blend::ColorBlendState, @@ -213,7 +213,8 @@ fn main() { ..Default::default() }, AllocationCreateInfo { - usage: MemoryUsage::Upload, + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, ..Default::default() }, vertices, diff --git a/examples/src/bin/push-constants.rs b/examples/src/bin/push-constants.rs index acaa9929f0..08299dd91c 100644 --- a/examples/src/bin/push-constants.rs +++ b/examples/src/bin/push-constants.rs @@ -25,7 +25,7 @@ use vulkano::{ QueueFlags, }, instance::{Instance, InstanceCreateFlags, InstanceCreateInfo}, - memory::allocator::{AllocationCreateInfo, MemoryUsage, StandardMemoryAllocator}, + memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator}, pipeline::{ compute::ComputePipelineCreateInfo, layout::PipelineDescriptorSetLayoutCreateInfo, ComputePipeline, Pipeline, PipelineBindPoint, PipelineLayout, @@ -145,22 +145,20 @@ fn main() { let command_buffer_allocator = StandardCommandBufferAllocator::new(device.clone(), Default::default()); - let data_buffer = { - let data_iter = 0..65536u32; - Buffer::from_iter( - &memory_allocator, - BufferCreateInfo { - usage: BufferUsage::STORAGE_BUFFER, - ..Default::default() - }, - AllocationCreateInfo { - usage: MemoryUsage::Upload, - ..Default::default() - }, - data_iter, - ) - .unwrap() - }; + let data_buffer = Buffer::from_iter( + &memory_allocator, + BufferCreateInfo { + usage: BufferUsage::STORAGE_BUFFER, + ..Default::default() + }, + AllocationCreateInfo { + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, + ..Default::default() + }, + 0..65536u32, + ) + .unwrap(); let layout = pipeline.layout().set_layouts().get(0).unwrap(); let set = PersistentDescriptorSet::new( diff --git a/examples/src/bin/push-descriptors/main.rs b/examples/src/bin/push-descriptors/main.rs index 4fcb35b029..0e7aabbd2e 100644 --- a/examples/src/bin/push-descriptors/main.rs +++ b/examples/src/bin/push-descriptors/main.rs @@ -26,7 +26,7 @@ use vulkano::{ Image, ImageCreateInfo, ImageType, ImageUsage, }, instance::{Instance, InstanceCreateFlags, InstanceCreateInfo}, - memory::allocator::{AllocationCreateInfo, MemoryUsage, StandardMemoryAllocator}, + memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator}, pipeline::{ graphics::{ color_blend::ColorBlendState, @@ -182,7 +182,8 @@ fn main() { ..Default::default() }, AllocationCreateInfo { - usage: MemoryUsage::Upload, + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, ..Default::default() }, vertices, @@ -229,7 +230,8 @@ fn main() { ..Default::default() }, AllocationCreateInfo { - usage: MemoryUsage::Upload, + memory_type_filter: MemoryTypeFilter::PREFER_HOST + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, ..Default::default() }, (info.width * info.height * 4) as DeviceSize, diff --git a/examples/src/bin/runtime-shader/main.rs b/examples/src/bin/runtime-shader/main.rs index cfdf578d11..5ca2454d29 100644 --- a/examples/src/bin/runtime-shader/main.rs +++ b/examples/src/bin/runtime-shader/main.rs @@ -34,7 +34,7 @@ use vulkano::{ }, image::{view::ImageView, Image, ImageUsage}, instance::{Instance, InstanceCreateFlags, InstanceCreateInfo}, - memory::allocator::{AllocationCreateInfo, MemoryUsage, StandardMemoryAllocator}, + memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator}, pipeline::{ graphics::{ color_blend::ColorBlendState, @@ -273,7 +273,8 @@ fn main() { ..Default::default() }, AllocationCreateInfo { - usage: MemoryUsage::Upload, + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, ..Default::default() }, vertices, diff --git a/examples/src/bin/runtime_array/main.rs b/examples/src/bin/runtime_array/main.rs index 9ef012b311..e6e9bfa939 100644 --- a/examples/src/bin/runtime_array/main.rs +++ b/examples/src/bin/runtime_array/main.rs @@ -29,7 +29,7 @@ use vulkano::{ Image, ImageCreateInfo, ImageType, ImageUsage, }, instance::{Instance, InstanceCreateFlags, InstanceCreateInfo}, - memory::allocator::{AllocationCreateInfo, MemoryUsage, StandardMemoryAllocator}, + memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator}, pipeline::{ graphics::{ color_blend::ColorBlendState, @@ -246,7 +246,8 @@ fn main() { ..Default::default() }, AllocationCreateInfo { - usage: MemoryUsage::Upload, + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, ..Default::default() }, vertices, @@ -295,7 +296,8 @@ fn main() { ..Default::default() }, AllocationCreateInfo { - usage: MemoryUsage::Upload, + memory_type_filter: MemoryTypeFilter::PREFER_HOST + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, ..Default::default() }, (info.width * info.height * 4) as DeviceSize, @@ -343,7 +345,8 @@ fn main() { ..Default::default() }, AllocationCreateInfo { - usage: MemoryUsage::Upload, + memory_type_filter: MemoryTypeFilter::PREFER_HOST + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, ..Default::default() }, (info.width * info.height * 4) as DeviceSize, diff --git a/examples/src/bin/self-copy-buffer.rs b/examples/src/bin/self-copy-buffer.rs index 87d8130ce6..3d52c102aa 100644 --- a/examples/src/bin/self-copy-buffer.rs +++ b/examples/src/bin/self-copy-buffer.rs @@ -25,7 +25,7 @@ use vulkano::{ QueueFlags, }, instance::{Instance, InstanceCreateFlags, InstanceCreateInfo}, - memory::allocator::{AllocationCreateInfo, MemoryUsage, StandardMemoryAllocator}, + memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator}, pipeline::{ compute::ComputePipelineCreateInfo, layout::PipelineDescriptorSetLayoutCreateInfo, ComputePipeline, Pipeline, PipelineBindPoint, PipelineLayout, @@ -146,7 +146,8 @@ fn main() { ..Default::default() }, AllocationCreateInfo { - usage: MemoryUsage::Upload, + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE + | MemoryTypeFilter::HOST_RANDOM_ACCESS, ..Default::default() }, // We intitialize half of the array and leave the other half at 0, we will use the copy diff --git a/examples/src/bin/shader-include/main.rs b/examples/src/bin/shader-include/main.rs index 3a3ab2572b..96f8164643 100644 --- a/examples/src/bin/shader-include/main.rs +++ b/examples/src/bin/shader-include/main.rs @@ -24,7 +24,7 @@ use vulkano::{ QueueFlags, }, instance::{Instance, InstanceCreateFlags, InstanceCreateInfo}, - memory::allocator::{AllocationCreateInfo, MemoryUsage, StandardMemoryAllocator}, + memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator}, pipeline::{ compute::ComputePipelineCreateInfo, layout::PipelineDescriptorSetLayoutCreateInfo, ComputePipeline, Pipeline, PipelineBindPoint, PipelineLayout, @@ -145,22 +145,20 @@ fn main() { let command_buffer_allocator = StandardCommandBufferAllocator::new(device.clone(), Default::default()); - let data_buffer = { - let data_iter = 0..65536u32; - Buffer::from_iter( - &memory_allocator, - BufferCreateInfo { - usage: BufferUsage::STORAGE_BUFFER, - ..Default::default() - }, - AllocationCreateInfo { - usage: MemoryUsage::Upload, - ..Default::default() - }, - data_iter, - ) - .unwrap() - }; + let data_buffer = Buffer::from_iter( + &memory_allocator, + BufferCreateInfo { + usage: BufferUsage::STORAGE_BUFFER, + ..Default::default() + }, + AllocationCreateInfo { + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE + | MemoryTypeFilter::HOST_RANDOM_ACCESS, + ..Default::default() + }, + 0..65536u32, + ) + .unwrap(); let layout = pipeline.layout().set_layouts().get(0).unwrap(); let set = PersistentDescriptorSet::new( diff --git a/examples/src/bin/shader-types-sharing.rs b/examples/src/bin/shader-types-sharing.rs index 65d0838ae1..aea979942d 100644 --- a/examples/src/bin/shader-types-sharing.rs +++ b/examples/src/bin/shader-types-sharing.rs @@ -39,7 +39,7 @@ use vulkano::{ QueueCreateInfo, QueueFlags, }, instance::{Instance, InstanceCreateFlags, InstanceCreateInfo}, - memory::allocator::{AllocationCreateInfo, MemoryUsage, StandardMemoryAllocator}, + memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator}, pipeline::{ compute::ComputePipelineCreateInfo, layout::PipelineDescriptorSetLayoutCreateInfo, ComputePipeline, Pipeline, PipelineBindPoint, PipelineLayout, @@ -242,7 +242,8 @@ fn main() { ..Default::default() }, AllocationCreateInfo { - usage: MemoryUsage::Upload, + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE + | MemoryTypeFilter::HOST_RANDOM_ACCESS, ..Default::default() }, 0..65536u32, diff --git a/examples/src/bin/simple-particles.rs b/examples/src/bin/simple-particles.rs index f522d41904..b8b27bcb42 100644 --- a/examples/src/bin/simple-particles.rs +++ b/examples/src/bin/simple-particles.rs @@ -28,7 +28,7 @@ use vulkano::{ }, image::{view::ImageView, ImageUsage}, instance::{Instance, InstanceCreateFlags, InstanceCreateInfo}, - memory::allocator::{AllocationCreateInfo, MemoryUsage, StandardMemoryAllocator}, + memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator}, pipeline::{ compute::ComputePipelineCreateInfo, graphics::{ @@ -361,7 +361,8 @@ fn main() { }, AllocationCreateInfo { // Specify this buffer will be used for uploading to the GPU. - usage: MemoryUsage::Upload, + memory_type_filter: MemoryTypeFilter::PREFER_HOST + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, ..Default::default() }, vertices, @@ -381,7 +382,7 @@ fn main() { }, AllocationCreateInfo { // Specify this buffer will only be used by the device. - usage: MemoryUsage::DeviceOnly, + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE, ..Default::default() }, PARTICLE_COUNT as vulkano::DeviceSize, diff --git a/examples/src/bin/specialization-constants.rs b/examples/src/bin/specialization-constants.rs index 82808e855c..9fed03b8cf 100644 --- a/examples/src/bin/specialization-constants.rs +++ b/examples/src/bin/specialization-constants.rs @@ -22,7 +22,7 @@ use vulkano::{ QueueFlags, }, instance::{Instance, InstanceCreateFlags, InstanceCreateInfo}, - memory::allocator::{AllocationCreateInfo, MemoryUsage, StandardMemoryAllocator}, + memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator}, pipeline::{ compute::ComputePipelineCreateInfo, layout::PipelineDescriptorSetLayoutCreateInfo, ComputePipeline, Pipeline, PipelineBindPoint, PipelineLayout, @@ -145,22 +145,20 @@ fn main() { let command_buffer_allocator = StandardCommandBufferAllocator::new(device.clone(), Default::default()); - let data_buffer = { - let data_iter = 0..65536u32; - Buffer::from_iter( - &memory_allocator, - BufferCreateInfo { - usage: BufferUsage::STORAGE_BUFFER, - ..Default::default() - }, - AllocationCreateInfo { - usage: MemoryUsage::Upload, - ..Default::default() - }, - data_iter, - ) - .unwrap() - }; + let data_buffer = Buffer::from_iter( + &memory_allocator, + BufferCreateInfo { + usage: BufferUsage::STORAGE_BUFFER, + ..Default::default() + }, + AllocationCreateInfo { + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE + | MemoryTypeFilter::HOST_RANDOM_ACCESS, + ..Default::default() + }, + 0..65536u32, + ) + .unwrap(); let layout = pipeline.layout().set_layouts().get(0).unwrap(); let set = PersistentDescriptorSet::new( diff --git a/examples/src/bin/teapot/main.rs b/examples/src/bin/teapot/main.rs index c511d6fc5a..3af3557eaf 100644 --- a/examples/src/bin/teapot/main.rs +++ b/examples/src/bin/teapot/main.rs @@ -29,7 +29,7 @@ use vulkano::{ format::Format, image::{view::ImageView, Image, ImageCreateInfo, ImageType, ImageUsage}, instance::{Instance, InstanceCreateFlags, InstanceCreateInfo}, - memory::allocator::{AllocationCreateInfo, MemoryUsage, StandardMemoryAllocator}, + memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator}, pipeline::{ graphics::{ color_blend::ColorBlendState, @@ -169,7 +169,8 @@ fn main() { ..Default::default() }, AllocationCreateInfo { - usage: MemoryUsage::Upload, + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, ..Default::default() }, POSITIONS, @@ -182,7 +183,8 @@ fn main() { ..Default::default() }, AllocationCreateInfo { - usage: MemoryUsage::Upload, + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, ..Default::default() }, NORMALS, @@ -195,7 +197,8 @@ fn main() { ..Default::default() }, AllocationCreateInfo { - usage: MemoryUsage::Upload, + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, ..Default::default() }, INDICES, @@ -206,6 +209,8 @@ fn main() { memory_allocator.clone(), SubbufferAllocatorCreateInfo { buffer_usage: BufferUsage::UNIFORM_BUFFER, + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, ..Default::default() }, ); diff --git a/examples/src/bin/tessellation.rs b/examples/src/bin/tessellation.rs index ddc7bfb7ac..082782492e 100644 --- a/examples/src/bin/tessellation.rs +++ b/examples/src/bin/tessellation.rs @@ -34,7 +34,7 @@ use vulkano::{ }, image::{view::ImageView, Image, ImageUsage}, instance::{Instance, InstanceCreateFlags, InstanceCreateInfo}, - memory::allocator::{AllocationCreateInfo, MemoryUsage, StandardMemoryAllocator}, + memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator}, pipeline::{ graphics::{ color_blend::ColorBlendState, @@ -308,7 +308,8 @@ fn main() { ..Default::default() }, AllocationCreateInfo { - usage: MemoryUsage::Upload, + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, ..Default::default() }, vertices, diff --git a/examples/src/bin/texture_array/main.rs b/examples/src/bin/texture_array/main.rs index 6026e2831f..77f83f75f9 100644 --- a/examples/src/bin/texture_array/main.rs +++ b/examples/src/bin/texture_array/main.rs @@ -28,7 +28,7 @@ use vulkano::{ Image, ImageCreateInfo, ImageType, ImageUsage, }, instance::{Instance, InstanceCreateFlags, InstanceCreateInfo}, - memory::allocator::{AllocationCreateInfo, MemoryUsage, StandardMemoryAllocator}, + memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator}, pipeline::{ graphics::{ color_blend::ColorBlendState, @@ -188,7 +188,8 @@ fn main() { ..Default::default() }, AllocationCreateInfo { - usage: MemoryUsage::Upload, + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, ..Default::default() }, vertices, @@ -241,7 +242,8 @@ fn main() { ..Default::default() }, AllocationCreateInfo { - usage: MemoryUsage::Upload, + memory_type_filter: MemoryTypeFilter::PREFER_HOST + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, ..Default::default() }, buffer_size, diff --git a/examples/src/bin/triangle-v1_3.rs b/examples/src/bin/triangle-v1_3.rs index 79495ddd6b..5dcea99630 100644 --- a/examples/src/bin/triangle-v1_3.rs +++ b/examples/src/bin/triangle-v1_3.rs @@ -34,7 +34,7 @@ use vulkano::{ }, image::{view::ImageView, Image, ImageUsage}, instance::{Instance, InstanceCreateFlags, InstanceCreateInfo}, - memory::allocator::{AllocationCreateInfo, MemoryUsage, StandardMemoryAllocator}, + memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator}, pipeline::{ graphics::{ color_blend::ColorBlendState, @@ -318,7 +318,8 @@ fn main() { ..Default::default() }, AllocationCreateInfo { - usage: MemoryUsage::Upload, + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, ..Default::default() }, vertices, diff --git a/examples/src/bin/triangle.rs b/examples/src/bin/triangle.rs index 68bb74cd87..25309d6a2d 100644 --- a/examples/src/bin/triangle.rs +++ b/examples/src/bin/triangle.rs @@ -29,7 +29,7 @@ use vulkano::{ }, image::{view::ImageView, Image, ImageUsage}, instance::{Instance, InstanceCreateFlags, InstanceCreateInfo}, - memory::allocator::{AllocationCreateInfo, MemoryUsage, StandardMemoryAllocator}, + memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator}, pipeline::{ graphics::{ color_blend::ColorBlendState, @@ -287,7 +287,8 @@ fn main() { ..Default::default() }, AllocationCreateInfo { - usage: MemoryUsage::Upload, + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, ..Default::default() }, vertices, diff --git a/vulkano/src/buffer/allocator.rs b/vulkano/src/buffer/allocator.rs index be5fe87a90..68c9656d00 100644 --- a/vulkano/src/buffer/allocator.rs +++ b/vulkano/src/buffer/allocator.rs @@ -18,7 +18,7 @@ use crate::{ memory::{ allocator::{ align_up, AllocationCreateInfo, DeviceLayout, MemoryAllocator, MemoryAllocatorError, - MemoryUsage, StandardMemoryAllocator, + MemoryTypeFilter, StandardMemoryAllocator, }, DeviceAlignment, }, @@ -82,17 +82,32 @@ const MAX_ARENAS: usize = 32; /// # Examples /// /// ``` -/// use vulkano::buffer::allocator::SubbufferAllocator; -/// use vulkano::command_buffer::{ -/// AutoCommandBufferBuilder, CommandBufferUsage, PrimaryCommandBufferAbstract, +/// use vulkano::{ +/// buffer::{ +/// allocator::{SubbufferAllocator, SubbufferAllocatorCreateInfo}, +/// BufferUsage, +/// }, +/// command_buffer::{ +/// AutoCommandBufferBuilder, CommandBufferUsage, PrimaryCommandBufferAbstract, +/// }, +/// memory::allocator::MemoryTypeFilter, +/// sync::GpuFuture, /// }; -/// use vulkano::sync::GpuFuture; +/// /// # let queue: std::sync::Arc = return; /// # let memory_allocator: std::sync::Arc = return; /// # let command_buffer_allocator: vulkano::command_buffer::allocator::StandardCommandBufferAllocator = return; -/// +/// # /// // Create the buffer allocator. -/// let buffer_allocator = SubbufferAllocator::new(memory_allocator.clone(), Default::default()); +/// let buffer_allocator = SubbufferAllocator::new( +/// memory_allocator.clone(), +/// SubbufferAllocatorCreateInfo { +/// buffer_usage: BufferUsage::TRANSFER_SRC, +/// memory_type_filter: MemoryTypeFilter::PREFER_HOST +/// | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, +/// ..Default::default() +/// }, +/// ); /// /// for n in 0..25u32 { /// // Each loop allocates a new subbuffer and stores `data` in it. @@ -132,7 +147,7 @@ where let SubbufferAllocatorCreateInfo { arena_size, buffer_usage, - memory_usage, + memory_type_filter, _ne: _, } = create_info; @@ -157,7 +172,7 @@ where state: UnsafeCell::new(SubbufferAllocatorState { memory_allocator, buffer_usage, - memory_usage, + memory_type_filter, buffer_alignment, arena_size, arena: None, @@ -265,7 +280,7 @@ where struct SubbufferAllocatorState { memory_allocator: A, buffer_usage: BufferUsage, - memory_usage: MemoryUsage, + memory_type_filter: MemoryTypeFilter, // The alignment required for the subbuffers. buffer_alignment: DeviceAlignment, // The current size of the arenas. @@ -349,7 +364,7 @@ where ..Default::default() }, AllocationCreateInfo { - usage: self.memory_usage, + memory_type_filter: self.memory_type_filter, ..Default::default() }, DeviceLayout::from_size_alignment(self.arena_size, 1).unwrap(), @@ -358,7 +373,7 @@ where Validated::Error(BufferAllocateError::AllocateMemory(err)) => err, // We don't use sparse-binding, concurrent sharing or external memory, therefore the // other errors can't happen. - _ => unreachable!(), + _ => unreachable!("{err:?}"), }) } } @@ -410,13 +425,13 @@ pub struct SubbufferAllocatorCreateInfo { /// The buffer usage that all allocated buffers should have. /// - /// The default value is [`BufferUsage::TRANSFER_SRC`]. + /// The default value is empty, which must be overridden. pub buffer_usage: BufferUsage, - /// The memory usage that all buffers should be allocated with. + /// The memory type filter all buffers should be allocated with. /// - /// The default value is [`MemoryUsage::Upload`]. - pub memory_usage: MemoryUsage, + /// The default value is [`MemoryTypeFilter::PREFER_DEVICE`]. + pub memory_type_filter: MemoryTypeFilter, pub _ne: crate::NonExhaustive, } @@ -426,8 +441,8 @@ impl Default for SubbufferAllocatorCreateInfo { fn default() -> Self { SubbufferAllocatorCreateInfo { arena_size: 0, - buffer_usage: BufferUsage::TRANSFER_SRC, - memory_usage: MemoryUsage::Upload, + buffer_usage: BufferUsage::empty(), + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE, _ne: crate::NonExhaustive(()), } } @@ -442,7 +457,13 @@ mod tests { let (device, _) = gfx_dev_and_queue!(); let memory_allocator = StandardMemoryAllocator::new_default(device); - let buffer_allocator = SubbufferAllocator::new(memory_allocator, Default::default()); + let buffer_allocator = SubbufferAllocator::new( + memory_allocator, + SubbufferAllocatorCreateInfo { + buffer_usage: BufferUsage::TRANSFER_SRC, + ..Default::default() + }, + ); assert_eq!(buffer_allocator.arena_size(), 0); buffer_allocator.reserve(83).unwrap(); @@ -454,7 +475,13 @@ mod tests { let (device, _) = gfx_dev_and_queue!(); let memory_allocator = StandardMemoryAllocator::new_default(device); - let buffer_allocator = SubbufferAllocator::new(memory_allocator, Default::default()); + let buffer_allocator = SubbufferAllocator::new( + memory_allocator, + SubbufferAllocatorCreateInfo { + buffer_usage: BufferUsage::TRANSFER_SRC, + ..Default::default() + }, + ); assert_eq!(buffer_allocator.arena_size(), 0); buffer_allocator.allocate_sized::().unwrap(); diff --git a/vulkano/src/buffer/mod.rs b/vulkano/src/buffer/mod.rs index b7ea7c7d4e..4d9552bd51 100644 --- a/vulkano/src/buffer/mod.rs +++ b/vulkano/src/buffer/mod.rs @@ -46,25 +46,6 @@ //! once, or you can keep reusing the same buffer (because its size is unchanging) it's best to //! use a dedicated `Buffer` for that. //! -//! # Memory usage -//! -//! When allocating memory for a buffer, you have to specify a *memory usage*. This tells the -//! memory allocator what memory type it should pick for the allocation. -//! -//! - [`MemoryUsage::DeviceOnly`] will allocate a buffer that's usually located in device-local -//! memory and whose content can't be directly accessed by your application. Accessing this -//! buffer from the device is generally faster compared to accessing a buffer that's located in -//! host-visible memory. -//! - [`MemoryUsage::Upload`] and [`MemoryUsage::Download`] both allocate from a host-visible -//! memory type, which means the buffer can be accessed directly from the host. Buffers allocated -//! with these memory usages are needed to get data to and from the device. -//! -//! Take for example a buffer that is under constant access by the device but you need to read its -//! content on the host from time to time, it may be a good idea to use a device-local buffer as -//! the main buffer and a host-visible buffer for when you need to read it. Then whenever you need -//! to read the main buffer, ask the device to copy from the device-local buffer to the -//! host-visible buffer, and read the host-visible buffer instead. -//! //! # Buffer usage //! //! When you create a buffer, you have to specify its *usage*. In other words, you have to @@ -95,9 +76,6 @@ //! //! [`RawBuffer`]: self::sys::RawBuffer //! [`SubbufferAllocator`]: self::allocator::SubbufferAllocator -//! [`MemoryUsage::DeviceOnly`]: crate::memory::allocator::MemoryUsage::DeviceOnly -//! [`MemoryUsage::Upload`]: crate::memory::allocator::MemoryUsage::Upload -//! [`MemoryUsage::Download`]: crate::memory::allocator::MemoryUsage::Download //! [the `view` module]: self::view //! [the `shader` module documentation]: crate::shader @@ -157,7 +135,7 @@ pub mod view; /// AutoCommandBufferBuilder, CommandBufferUsage, CopyBufferInfo, /// PrimaryCommandBufferAbstract, /// }, -/// memory::allocator::{AllocationCreateInfo, MemoryUsage}, +/// memory::allocator::{AllocationCreateInfo, MemoryTypeFilter}, /// sync::GpuFuture, /// DeviceSize, /// }; @@ -166,6 +144,7 @@ pub mod view; /// # let queue: std::sync::Arc = return; /// # let memory_allocator: vulkano::memory::allocator::StandardMemoryAllocator = return; /// # let command_buffer_allocator: vulkano::command_buffer::allocator::StandardCommandBufferAllocator = return; +/// # /// // Simple iterator to construct test data. /// let data = (0..10_000).map(|i| i as f32); /// @@ -179,14 +158,15 @@ pub mod view; /// }, /// AllocationCreateInfo { /// // Specify use for upload to the device. -/// usage: MemoryUsage::Upload, +/// memory_type_filter: MemoryTypeFilter::PREFER_HOST +/// | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, /// ..Default::default() /// }, /// data, /// ) /// .unwrap(); /// -/// // Create a buffer in device-local with enough space for a slice of `10_000` floats. +/// // Create a buffer in device-local memory with enough space for a slice of `10_000` floats. /// let device_local_buffer = Buffer::new_slice::( /// &memory_allocator, /// BufferCreateInfo { @@ -196,7 +176,7 @@ pub mod view; /// }, /// AllocationCreateInfo { /// // Specify use by the device only. -/// usage: MemoryUsage::DeviceOnly, +/// memory_type_filter: MemoryTypeFilter::PREFER_DEVICE, /// ..Default::default() /// }, /// 10_000 as DeviceSize, diff --git a/vulkano/src/buffer/subbuffer.rs b/vulkano/src/buffer/subbuffer.rs index 00224f8691..7f55662295 100644 --- a/vulkano/src/buffer/subbuffer.rs +++ b/vulkano/src/buffer/subbuffer.rs @@ -1119,7 +1119,7 @@ mod tests { }, memory::{ allocator::{ - AllocationCreateInfo, AllocationType, DeviceLayout, MemoryAllocator, MemoryUsage, + AllocationCreateInfo, AllocationType, DeviceLayout, MemoryAllocator, StandardMemoryAllocator, }, MemoryRequirements, @@ -1199,10 +1199,7 @@ mod tests { usage: BufferUsage::TRANSFER_SRC, ..Default::default() }, - AllocationCreateInfo { - usage: MemoryUsage::Upload, - ..Default::default() - }, + AllocationCreateInfo::default(), 6, ) .unwrap(); diff --git a/vulkano/src/buffer/view.rs b/vulkano/src/buffer/view.rs index 6d5ebb97e7..1c6fd599e3 100644 --- a/vulkano/src/buffer/view.rs +++ b/vulkano/src/buffer/view.rs @@ -457,7 +457,7 @@ mod tests { use crate::{ buffer::{Buffer, BufferCreateInfo, BufferUsage}, format::Format, - memory::allocator::{AllocationCreateInfo, MemoryUsage, StandardMemoryAllocator}, + memory::allocator::{AllocationCreateInfo, StandardMemoryAllocator}, }; #[test] @@ -472,13 +472,11 @@ mod tests { usage: BufferUsage::UNIFORM_TEXEL_BUFFER, ..Default::default() }, - AllocationCreateInfo { - usage: MemoryUsage::Upload, - ..Default::default() - }, + AllocationCreateInfo::default(), 128, ) .unwrap(); + BufferView::new( buffer, BufferViewCreateInfo { diff --git a/vulkano/src/command_buffer/auto/mod.rs b/vulkano/src/command_buffer/auto/mod.rs index 465f87bff7..1f59dff1c5 100644 --- a/vulkano/src/command_buffer/auto/mod.rs +++ b/vulkano/src/command_buffer/auto/mod.rs @@ -321,7 +321,7 @@ mod tests { }, device::{Device, DeviceCreateInfo, QueueCreateInfo}, image::sampler::{Sampler, SamplerCreateInfo}, - memory::allocator::{AllocationCreateInfo, MemoryUsage, StandardMemoryAllocator}, + memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator}, pipeline::{layout::PipelineLayoutCreateInfo, PipelineBindPoint, PipelineLayout}, shader::ShaderStages, sync::GpuFuture, @@ -372,7 +372,8 @@ mod tests { ..Default::default() }, AllocationCreateInfo { - usage: MemoryUsage::Upload, + memory_type_filter: MemoryTypeFilter::PREFER_HOST + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, ..Default::default() }, [1_u32, 2].iter().copied(), @@ -386,7 +387,8 @@ mod tests { ..Default::default() }, AllocationCreateInfo { - usage: MemoryUsage::Upload, + memory_type_filter: MemoryTypeFilter::PREFER_HOST + | MemoryTypeFilter::HOST_RANDOM_ACCESS, ..Default::default() }, [0_u32, 10, 20, 3, 4].iter().copied(), @@ -509,7 +511,8 @@ mod tests { ..Default::default() }, AllocationCreateInfo { - usage: MemoryUsage::Upload, + memory_type_filter: MemoryTypeFilter::PREFER_HOST + | MemoryTypeFilter::HOST_RANDOM_ACCESS, ..Default::default() }, [0_u32, 1, 2, 3].iter().copied(), @@ -563,7 +566,8 @@ mod tests { ..Default::default() }, AllocationCreateInfo { - usage: MemoryUsage::Upload, + memory_type_filter: MemoryTypeFilter::PREFER_HOST + | MemoryTypeFilter::HOST_RANDOM_ACCESS, ..Default::default() }, [0_u32, 1, 2, 3].iter().copied(), @@ -619,7 +623,8 @@ mod tests { ..Default::default() }, AllocationCreateInfo { - usage: MemoryUsage::Upload, + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, ..Default::default() }, 0u32, @@ -716,7 +721,8 @@ mod tests { ..Default::default() }, AllocationCreateInfo { - usage: MemoryUsage::Upload, + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, ..Default::default() }, 0u32, diff --git a/vulkano/src/memory/allocator/mod.rs b/vulkano/src/memory/allocator/mod.rs index c71022cfda..66c5cba5fe 100644 --- a/vulkano/src/memory/allocator/mod.rs +++ b/vulkano/src/memory/allocator/mod.rs @@ -242,6 +242,7 @@ use parking_lot::RwLock; use std::{ error::Error, fmt::{Display, Error as FmtError, Formatter}, + ops::BitOr, sync::Arc, }; @@ -385,6 +386,121 @@ pub unsafe trait MemoryAllocator: DeviceOwned { /// Describes what memory property flags are required, preferred and not preferred when picking a /// memory type index. +/// +/// # Examples +/// +/// For resources that the device frequently accesses, e.g. textures, render targets, or +/// intermediary buffers, you want device-local memory without any host access: +/// +/// ``` +/// # use vulkano::{ +/// # image::{Image, ImageCreateInfo, ImageUsage}, +/// # memory::allocator::{AllocationCreateInfo, MemoryTypeFilter}, +/// # }; +/// # +/// # let memory_allocator: vulkano::memory::allocator::StandardMemoryAllocator = return; +/// # let format = return; +/// # let extent = return; +/// # +/// let texture = Image::new( +/// &memory_allocator, +/// ImageCreateInfo { +/// format, +/// extent, +/// usage: ImageUsage::TRANSFER_DST | ImageUsage::SAMPLED, +/// ..Default::default() +/// }, +/// AllocationCreateInfo { +/// memory_type_filter: MemoryTypeFilter::PREFER_DEVICE, +/// ..Default::default() +/// }, +/// ) +/// .unwrap(); +/// ``` +/// +/// For staging, the resource is only ever written to sequentially. Also, since the device will +/// only read the staging resourse once, it would yield no benefit to place it in device-local +/// memory, in fact it would be wasteful. Therefore, it's best to put it in host-local memory: +/// +/// ``` +/// # use vulkano::{ +/// # buffer::{Buffer, BufferCreateInfo, BufferUsage}, +/// # memory::allocator::{AllocationCreateInfo, MemoryTypeFilter}, +/// # }; +/// # +/// # let memory_allocator: vulkano::memory::allocator::StandardMemoryAllocator = return; +/// # +/// let staging_buffer = Buffer::new_sized( +/// &memory_allocator, +/// BufferCreateInfo { +/// usage: BufferUsage::TRANSFER_SRC, +/// ..Default::default() +/// }, +/// AllocationCreateInfo { +/// memory_type_filter: MemoryTypeFilter::PREFER_HOST | +/// MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, +/// ..Default::default() +/// }, +/// ) +/// .unwrap(); +/// # +/// # let staging_buffer: vulkano::buffer::Subbuffer = staging_buffer; +/// ``` +/// +/// For resources that the device accesses directly, aka a buffer/image used for anything other +/// than transfers, it's probably best to put it in device-local memory: +/// +/// ``` +/// # use vulkano::{ +/// # buffer::{Buffer, BufferCreateInfo, BufferUsage}, +/// # memory::allocator::{AllocationCreateInfo, MemoryTypeFilter}, +/// # }; +/// # +/// # let memory_allocator: vulkano::memory::allocator::StandardMemoryAllocator = return; +/// # +/// let uniform_buffer = Buffer::new_sized( +/// &memory_allocator, +/// BufferCreateInfo { +/// usage: BufferUsage::UNIFORM_BUFFER, +/// ..Default::default() +/// }, +/// AllocationCreateInfo { +/// memory_type_filter: MemoryTypeFilter::PREFER_DEVICE | +/// MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, +/// ..Default::default() +/// }, +/// ) +/// .unwrap(); +/// # +/// # let uniform_buffer: vulkano::buffer::Subbuffer = uniform_buffer; +/// ``` +/// +/// For readback, e.g. getting the results of a compute shader back to the host: +/// +/// ``` +/// # use vulkano::{ +/// # buffer::{Buffer, BufferCreateInfo, BufferUsage}, +/// # memory::allocator::{AllocationCreateInfo, MemoryTypeFilter}, +/// # }; +/// # +/// # let memory_allocator: vulkano::memory::allocator::StandardMemoryAllocator = return; +/// # +/// let readback_buffer = Buffer::new_sized( +/// &memory_allocator, +/// BufferCreateInfo { +/// usage: BufferUsage::TRANSFER_DST, +/// ..Default::default() +/// }, +/// AllocationCreateInfo { +/// memory_type_filter: MemoryTypeFilter::PREFER_HOST | +/// MemoryTypeFilter::HOST_RANDOM_ACCESS, +/// ..Default::default() +/// }, +/// ) +/// .unwrap(); +/// # +/// # let readback_buffer: vulkano::buffer::Subbuffer = readback_buffer; +/// ``` #[derive(Clone, Copy, Debug, Default, PartialEq, Eq)] pub struct MemoryTypeFilter { pub required_flags: MemoryPropertyFlags, @@ -392,28 +508,151 @@ pub struct MemoryTypeFilter { pub not_preferred_flags: MemoryPropertyFlags, } -impl From for MemoryTypeFilter { +impl MemoryTypeFilter { + /// Prefers picking a memory type with the [`DEVICE_LOCAL`] flag. + /// + /// Memory being device-local means that it is fastest to access for the device. However, + /// for dedicated GPUs, getting memory in and out of VRAM requires to go through the PCIe bus, + /// which is very slow and should therefore only be done when necessary. + /// + /// This filter is best suited for anything that the host doesn't access, but the device + /// accesses frequently. For example textures, render targets, and intermediary buffers. + /// + /// For memory that the host does access but less frequently than the device, such as updating + /// a uniform buffer each frame, device-local memory may also be preferred. In this case, + /// because the memory is only written once before being consumed by the device and becoming + /// outdated, it doesn't matter that the data is potentially transferred over the PCIe bus + /// since it only happens once. Since this is only a preference, if you have some requirements + /// such as the memory being [`HOST_VISIBLE`], those requirements will take precendence. + /// + /// For memory that the host doesn't access, and the device doesn't access directly, you may + /// still prefer device-local memory if the memory is used regularly. For instance, an image + /// that is swapped each frame. + /// + /// Keep in mind that for implementations with unified memory, there's only system RAM. That + /// means that even if the implementation reports a memory type that is not `HOST_VISIBLE` and + /// is `DEVICE_LOCAL`, its still the same unified memory as all other memory. However, it may + /// still be faster to access. On the other hand, some such implementations don't report any + /// memory types that are not `HOST_VISIBLE`, which makes sense since it's all system RAM. In + /// that case you wouldn't need to do staging. + /// + /// Don't use this together with [`PREFER_HOST`], that makes no sense. If you need host access, + /// make sure you combine this with either the [`HOST_SEQUENTIAL_WRITE`] or + /// [`HOST_RANDOM_ACCESS`] filter. + /// + /// [`DEVICE_LOCAL`]: MemoryPropertyFlags::DEVICE_LOCAL + /// [`HOST_VISIBLE`]: MemoryPropertyFlags::HOST_VISIBLE + /// [`PREFER_HOST`]: Self::PREFER_HOST + /// [`HOST_SEQUENTIAL_WRITE`]: Self::HOST_SEQUENTIAL_WRITE + /// [`HOST_RANDOM_ACCESS`]: Self::HOST_RANDOM_ACCESS + pub const PREFER_DEVICE: Self = Self { + required_flags: MemoryPropertyFlags::empty(), + preferred_flags: MemoryPropertyFlags::DEVICE_LOCAL, + not_preferred_flags: MemoryPropertyFlags::empty(), + }; + + /// Prefers picking a memory type without the [`DEVICE_LOCAL`] flag. + /// + /// This option is best suited for resources that the host does access, but device doesn't + /// access directly, such as staging buffers and readback buffers. + /// + /// For memory that the host does access but less frequently than the device, such as updating + /// a uniform buffer each frame, you may still get away with using host-local memory if the + /// updates are small and local enough. In such cases, the memory should be able to be quickly + /// cached by the device, such that the data potentially being transferred over the PCIe bus + /// wouldn't matter. + /// + /// For memory that the host doesn't access, and the device doesn't access directly, you may + /// still prefer host-local memory if the memory is rarely used, such as for manually paging + /// parts of device-local memory out in order to free up space on the device. + /// + /// Don't use this together with [`PREFER_DEVICE`], that makes no sense. If you need host + /// access, make sure you combine this with either the [`HOST_SEQUENTIAL_WRITE`] or + /// [`HOST_RANDOM_ACCESS`] filter. + /// + /// [`DEVICE_LOCAL`]: MemoryPropertyFlags::DEVICE_LOCAL + /// [`PREFER_DEVICE`]: Self::PREFER_DEVICE + /// [`HOST_SEQUENTIAL_WRITE`]: Self::HOST_SEQUENTIAL_WRITE + /// [`HOST_RANDOM_ACCESS`]: Self::HOST_RANDOM_ACCESS + pub const PREFER_HOST: Self = Self { + required_flags: MemoryPropertyFlags::empty(), + preferred_flags: MemoryPropertyFlags::empty(), + not_preferred_flags: MemoryPropertyFlags::DEVICE_LOCAL, + }; + + /// This guarantees picking a memory type that has the [`HOST_VISIBLE`] flag. Using this filter + /// allows the allocator to pick a memory type that is uncached and write-combined, which is + /// ideal for sequential writes. However, this optimization might lead to poor performance for + /// anything else. What counts as a sequential write is any kind of loop that writes memory + /// locations in order, such as iterating over a slice while writing each element in order, or + /// equivalently using [`slice::copy_from_slice`]. Copying sized data also counts, as rustc + /// should write the memory locations in order. If you have a struct, make sure you write it + /// member-by-member. + /// + /// Example use cases include staging buffers, as well as any other kind of buffer that you + /// only write to from the host, like a uniform or vertex buffer. + /// + /// Don't use this together with [`HOST_RANDOM_ACCESS`], that makes no sense. If you do both a + /// sequential write and read or random access, then you should use `HOST_RANDOM_ACCESS` + /// instead. However, you could also consider using different allocations for the two purposes + /// to get the most performance out, if that's possible. + /// + /// [`HOST_VISIBLE`]: MemoryPropertyFlags::HOST_VISIBLE + /// [`HOST_COHERENT`]: MemoryPropertyFlags::HOST_COHERENT + /// [`HOST_RANDOM_ACCESS`]: Self::HOST_RANDOM_ACCESS + pub const HOST_SEQUENTIAL_WRITE: Self = Self { + required_flags: MemoryPropertyFlags::HOST_VISIBLE, + preferred_flags: MemoryPropertyFlags::empty(), + not_preferred_flags: MemoryPropertyFlags::HOST_CACHED, + }; + + /// This guarantees picking a memory type that has the [`HOST_VISIBLE`] and [`HOST_CACHED`] + /// flags, which is best suited for readback and/or random access. + /// + /// Example use cases include using the device for things other than rendering and getting the + /// results back to the host. That might be compute shading, or image or video manipulation, or + /// screenshotting. + /// + /// Don't use this together with [`HOST_SEQUENTIAL_WRITE`], that makes no sense. If you are + /// sure you only ever need to sequentially write to the allocation, then using + /// `HOST_SEQUENTIAL_WRITE` instead will yield better performance. + /// + /// [`HOST_VISIBLE`]: MemoryPropertyFlags::HOST_VISIBLE + /// [`HOST_CACHED`]: MemoryPropertyFlags::HOST_CACHED + /// [`HOST_SEQUENTIAL_WRITE`]: Self::HOST_SEQUENTIAL_WRITE + pub const HOST_RANDOM_ACCESS: Self = Self { + required_flags: MemoryPropertyFlags::HOST_VISIBLE.union(MemoryPropertyFlags::HOST_CACHED), + preferred_flags: MemoryPropertyFlags::empty(), + not_preferred_flags: MemoryPropertyFlags::empty(), + }; + + /// Returns a `MemoryTypeFilter` with none of the flags set. #[inline] - fn from(usage: MemoryUsage) -> Self { - let mut filter = Self::default(); + pub const fn empty() -> Self { + Self { + required_flags: MemoryPropertyFlags::empty(), + preferred_flags: MemoryPropertyFlags::empty(), + not_preferred_flags: MemoryPropertyFlags::empty(), + } + } - match usage { - MemoryUsage::DeviceOnly => { - filter.preferred_flags |= MemoryPropertyFlags::DEVICE_LOCAL; - filter.not_preferred_flags |= MemoryPropertyFlags::HOST_VISIBLE; - } - MemoryUsage::Upload => { - filter.required_flags |= MemoryPropertyFlags::HOST_VISIBLE; - filter.preferred_flags |= MemoryPropertyFlags::DEVICE_LOCAL; - filter.not_preferred_flags |= MemoryPropertyFlags::HOST_CACHED; - } - MemoryUsage::Download => { - filter.required_flags |= MemoryPropertyFlags::HOST_VISIBLE; - filter.preferred_flags |= MemoryPropertyFlags::HOST_CACHED; - } + /// Returns the union of `self` and `other`. + #[inline] + pub const fn union(self, other: Self) -> Self { + Self { + required_flags: self.required_flags.union(other.required_flags), + preferred_flags: self.preferred_flags.union(other.preferred_flags), + not_preferred_flags: self.not_preferred_flags.union(other.not_preferred_flags), } + } +} + +impl BitOr for MemoryTypeFilter { + type Output = Self; - filter + #[inline] + fn bitor(self, rhs: Self) -> Self::Output { + self.union(rhs) } } @@ -423,10 +662,10 @@ impl From for MemoryTypeFilter { /// [memory allocator]: MemoryAllocator #[derive(Clone, Debug)] pub struct AllocationCreateInfo { - /// The intended usage for the allocation. + /// Filter used to narrow down the memory type to be selected. /// - /// The default value is [`MemoryUsage::DeviceOnly`]. - pub usage: MemoryUsage, + /// The default value is [`MemoryTypeFilter::PREFER_DEVICE`]. + pub memory_type_filter: MemoryTypeFilter, /// How eager the allocator should be to allocate [`DeviceMemory`]. /// @@ -440,65 +679,13 @@ impl Default for AllocationCreateInfo { #[inline] fn default() -> Self { AllocationCreateInfo { - usage: MemoryUsage::DeviceOnly, + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE, allocate_preference: MemoryAllocatePreference::Unknown, _ne: crate::NonExhaustive(()), } } } -/// Describes how a memory allocation is going to be used. -/// -/// This is mostly an optimization, except for `MemoryUsage::DeviceOnly` which will pick a memory -/// type that is not host-accessible if such a type exists. -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] -#[non_exhaustive] -pub enum MemoryUsage { - /// The memory is intended to only be used by the device. - /// - /// Prefers picking a memory type with the [`DEVICE_LOCAL`] flag and without the - /// [`HOST_VISIBLE`] flag. - /// - /// This option is what you will always want to use unless the memory needs to be accessed by - /// the CPU, because a memory type that can only be accessed by the GPU is going to give the - /// best performance. Example use cases would be textures and other maps which are written to - /// once and then never again, or resources that are only written and read by the GPU, like - /// render targets and intermediary buffers. - /// - /// [`DEVICE_LOCAL`]: MemoryPropertyFlags::DEVICE_LOCAL - /// [`HOST_VISIBLE`]: MemoryPropertyFlags::HOST_VISIBLE - DeviceOnly, - - /// The memory is intended for upload to the device. - /// - /// Guarantees picking a memory type with the [`HOST_VISIBLE`] flag. Prefers picking one - /// without the [`HOST_CACHED`] flag and with the [`DEVICE_LOCAL`] flag. - /// - /// This option is best suited for resources that need to be constantly updated by the CPU, - /// like vertex and index buffers for example. It is also neccessary for *staging buffers*, - /// whose only purpose in life it is to get data into device-local memory or texels into an - /// optimal image. - /// - /// [`HOST_VISIBLE`]: MemoryPropertyFlags::HOST_VISIBLE - /// [`HOST_CACHED`]: MemoryPropertyFlags::HOST_CACHED - /// [`DEVICE_LOCAL`]: MemoryPropertyFlags::DEVICE_LOCAL - Upload, - - /// The memory is intended for download from the device. - /// - /// Guarantees picking a memory type with the [`HOST_VISIBLE`] flag. Prefers picking one with - /// the [`HOST_CACHED`] flag and without the [`DEVICE_LOCAL`] flag. - /// - /// This option is best suited if you're using the device for things other than rendering and - /// you need to get the results back to the host. That might be compute shading, or image or - /// video manipulation, or screenshotting for example. - /// - /// [`HOST_VISIBLE`]: MemoryPropertyFlags::HOST_VISIBLE - /// [`HOST_CACHED`]: MemoryPropertyFlags::HOST_CACHED - /// [`DEVICE_LOCAL`]: MemoryPropertyFlags::DEVICE_LOCAL - Download, -} - /// Describes whether allocating [`DeviceMemory`] is desired. #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] #[non_exhaustive] @@ -1174,7 +1361,7 @@ unsafe impl MemoryAllocator for GenericMemoryAllocator { /// `create_info.requirements.size` doesn't match the memory requirements of the resource. /// - Panics if finding a suitable memory type failed. This only happens if the /// `create_info.requirements` correspond to those of an optimal image but - /// `create_info.usage` is not [`MemoryUsage::DeviceOnly`]. + /// `create_info.memory_type_filter` requires host access. /// /// # Errors /// @@ -1230,8 +1417,9 @@ unsafe impl MemoryAllocator for GenericMemoryAllocator { mut prefers_dedicated_allocation, requires_dedicated_allocation, } = requirements; + let AllocationCreateInfo { - usage, + memory_type_filter, allocate_preference, _ne: _, } = create_info; @@ -1245,9 +1433,8 @@ unsafe impl MemoryAllocator for GenericMemoryAllocator { let size = layout.size(); memory_type_bits &= self.memory_type_bits; - let filter = usage.into(); let mut memory_type_index = self - .find_memory_type_index(memory_type_bits, filter) + .find_memory_type_index(memory_type_bits, memory_type_filter) .expect("couldn't find a suitable memory type"); if !self.dedicated_allocation && !requires_dedicated_allocation { @@ -1349,7 +1536,7 @@ unsafe impl MemoryAllocator for GenericMemoryAllocator { Err(err) => { memory_type_bits &= !(1 << memory_type_index); memory_type_index = self - .find_memory_type_index(memory_type_bits, filter) + .find_memory_type_index(memory_type_bits, memory_type_filter) .ok_or(err)?; } } diff --git a/vulkano/src/memory/allocator/suballocator.rs b/vulkano/src/memory/allocator/suballocator.rs index c30165c693..98437b8c5c 100644 --- a/vulkano/src/memory/allocator/suballocator.rs +++ b/vulkano/src/memory/allocator/suballocator.rs @@ -868,14 +868,18 @@ impl Display for SuballocatorError { /// Basic usage as a global allocator for long-lived resources: /// /// ``` -/// use vulkano::format::Format; -/// use vulkano::image::{Image, ImageCreateInfo, ImageType, ImageUsage}; -/// use vulkano::memory::allocator::{AllocationCreateInfo, StandardMemoryAllocator}; -/// # let device: std::sync::Arc = return; +/// use vulkano::{ +/// format::Format, +/// image::{Image, ImageCreateInfo, ImageType, ImageUsage}, +/// memory::allocator::{AllocationCreateInfo, StandardMemoryAllocator}, +/// }; /// +/// # let device: std::sync::Arc = return; +/// # /// let memory_allocator = StandardMemoryAllocator::new_default(device.clone()); /// /// # fn read_textures() -> Vec> { Vec::new() } +/// # /// // Allocate some resources. /// let textures_data: Vec> = read_textures(); /// let textures = textures_data.into_iter().map(|data| { @@ -902,13 +906,27 @@ impl Display for SuballocatorError { /// /// ``` /// use std::sync::Arc; -/// use vulkano::buffer::allocator::SubbufferAllocator; -/// use vulkano::memory::allocator::StandardMemoryAllocator; -/// # let device: std::sync::Arc = return; +/// use vulkano::{ +/// buffer::{ +/// allocator::{SubbufferAllocator, SubbufferAllocatorCreateInfo}, +/// BufferUsage, +/// }, +/// memory::allocator::{MemoryTypeFilter, StandardMemoryAllocator}, +/// }; /// +/// # let device: std::sync::Arc = return; +/// # /// // We need to wrap the allocator in an `Arc` so that we can share ownership of it. /// let memory_allocator = Arc::new(StandardMemoryAllocator::new_default(device.clone())); -/// let buffer_allocator = SubbufferAllocator::new(memory_allocator.clone(), Default::default()); +/// let buffer_allocator = SubbufferAllocator::new( +/// memory_allocator.clone(), +/// SubbufferAllocatorCreateInfo { +/// buffer_usage: BufferUsage::TRANSFER_SRC, +/// memory_type_filter: MemoryTypeFilter::PREFER_HOST +/// | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, +/// ..Default::default() +/// }, +/// ); /// /// // You can continue using `memory_allocator` for other things. /// ``` diff --git a/vulkano/src/pipeline/compute.rs b/vulkano/src/pipeline/compute.rs index 95078d19c5..fd830a6ce2 100644 --- a/vulkano/src/pipeline/compute.rs +++ b/vulkano/src/pipeline/compute.rs @@ -388,7 +388,7 @@ mod tests { descriptor_set::{ allocator::StandardDescriptorSetAllocator, PersistentDescriptorSet, WriteDescriptorSet, }, - memory::allocator::{AllocationCreateInfo, MemoryUsage, StandardMemoryAllocator}, + memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator}, pipeline::{ compute::ComputePipelineCreateInfo, layout::PipelineDescriptorSetLayoutCreateInfo, ComputePipeline, Pipeline, PipelineBindPoint, PipelineLayout, @@ -467,7 +467,8 @@ mod tests { ..Default::default() }, AllocationCreateInfo { - usage: MemoryUsage::Upload, + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE + | MemoryTypeFilter::HOST_RANDOM_ACCESS, ..Default::default() }, 0,