diff --git a/CHANGELOG.md b/CHANGELOG.md index 16235df..f898483 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,17 +13,53 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - `PhysicalDevice::sampler_filter_minmax_properties` added to report properties - `SamplerInfo::reduction_mode` added to set mode - `SamplerInfo::LINEAR` and `NEAREST` to make sampler creation easier -- `DeviceInfo` now implements `Default` +- `ComputePipeline::with_name`, `GraphicPipeline::with_name` and `RayTracePipeline::with_name` + debug helper functions +- `AccelerationStructureInfo::generic` function ### Changed - `Device::image_format_properties` returns an `Option` so that unsupported formats may return `None` instead of relying on user code to detect `DriverError::Unsupported` -- `ImageInfo::linear_tiling` renamed to `tiling` and type changed from `bool` to `vk::ImageTiling` -- `EventLoop` now produces linear surfaces by default - use `desired_surface_format` to select sRGB +- Information struct trait implementations, field and function naming normalized: + - Constructors no longer return builders + - Use `to_builder` to convert an info struct into a builder + - Use `build` to convert a builder into an info struct + - `AccelerationStructureInfo` + - Function `new_blas` renamed to `blas` + - Function `new_tlas` renamed to `tlas` + - `BufferInfo` + - Function `new` renamed to `device_mem` + - Function `new_mappable` renamed to `host_mem` + - `ComputePipelineInfo` now implements `Copy`, `Eq` and `Hash` + - `DeviceInfo` now implements `Default` + - `GraphicPipelineInfo` now implements `Copy` + - `ImageInfo` + - Constructor parameters reordered: `fmt` now after image size + - Function `new_2d` renamed to `image_2d` (_in addition to `cube`, `image_1d`, etc._) + - Field `linear_tiling` renamed to `tiling` (_type changed from `bool` to `vk::ImageTiling`_) + - `ImageViewInfo::new` function now `const` + - `RayTracePipelineInfo` now implements `Copy` + - `SwapchainInfo` + - Function `new` now returns `SwapchainInfo` (_previously returned `SwapchainInfoBuilder`_) + - Field `format` renamed to `surface` + - Default values for `width` and `height` fields removed +- `ComputePipelineInfo::name`, `GraphicPipelineInfo::name` and `RayTracePipelineInfo::name` have + each been moved to their respective pipeline struct +- `EventLoop` now produces linear surfaces by default - use `desired_surface_format` and `Surface::srgb` to select sRGB - `Swapchain::present_image` now uses event-based waiting for rendering operations instead of polling, greatly reducing CPU usage -- Updated `ash-molten` (Mac OS support) to v0.17 +- Updated `ash-molten` (_Mac OS support_) to v0.17 + +### Fixed + +- `ComputePipelineInfo::default` now properly sets a default value for `bindless_descriptor_count` + +### Removed + +- `GraphicPipelineInfo::new` function: Use `Default` implementation instead +- `RayTracePipelineInfo::new` function: Use `Default` implementation instead +- `SamplerInfo::new` function: Use `Default` implementation instead ## [0.10.0] - 2024-02-09 @@ -38,7 +74,7 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - Information structs are now `#[non_exhaustive]` in order to make future additions minor changes - update strategies: - Use `..Default::default()` syntax during struct creation - - Use associated constructor functions such as `ImageInfo::new_2d(..)` + - Use associated constructor functions such as `ImageInfo::new_2d(..)` - `BufferInfo::can_map` renamed to `BufferInfo::mappable` - Increase `PoolInfo::DEFAULT_RESOURCE_CAPACITY` from 4 to 16 in order to prevent excess resource creation diff --git a/Cargo.toml b/Cargo.toml index 79f1a97..e64e59d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ profile-with-tracy = ["profiling/profile-with-tracy"] [dependencies] ash = ">=0.37.1, <0.38" ash-window = "0.12" -derive_builder = "0.13" +derive_builder = "0.20" gpu-allocator = "0.25" log = "0.4" ordered-float = "4.1" diff --git a/contrib/screen-13-egui/src/lib.rs b/contrib/screen-13-egui/src/lib.rs index cb75bc3..ac87f82 100644 --- a/contrib/screen-13-egui/src/lib.rs +++ b/contrib/screen-13-egui/src/lib.rs @@ -28,7 +28,7 @@ impl Egui { let ppl = Arc::new( GraphicPipeline::create( device, - GraphicPipelineInfo::new() + GraphicPipelineInfoBuilder::default() .blend(BlendMode { blend_enable: true, src_color_blend_factor: vk::BlendFactor::ONE, @@ -109,7 +109,7 @@ impl Egui { let tmp_buf = { let mut buf = self .cache - .lease(BufferInfo::new_mappable( + .lease(BufferInfo::host_mem( (pixels.len() * delta.image.bytes_per_pixel()) as u64, vk::BufferUsageFlags::TRANSFER_SRC, )) @@ -155,10 +155,10 @@ impl Egui { } else { let image = AnyImageNode::ImageLease( self.cache - .lease(ImageInfo::new_2d( - vk::Format::R8G8B8A8_UNORM, + .lease(ImageInfo::image_2d( delta.image.width() as u32, delta.image.height() as u32, + vk::Format::R8G8B8A8_UNORM, vk::ImageUsageFlags::SAMPLED | vk::ImageUsageFlags::TRANSFER_DST, )) .unwrap() @@ -234,7 +234,7 @@ impl Egui { let idx_buf = { let mut buf = self .cache - .lease(BufferInfo::new_mappable( + .lease(BufferInfo::host_mem( (mesh.indices.len() * 4) as u64, vk::BufferUsageFlags::INDEX_BUFFER, )) @@ -247,7 +247,7 @@ impl Egui { let vert_buf = { let mut buf = self .cache - .lease(BufferInfo::new_mappable( + .lease(BufferInfo::host_mem( (mesh.vertices.len() * std::mem::size_of::()) as u64, vk::BufferUsageFlags::VERTEX_BUFFER, diff --git a/contrib/screen-13-fx/src/bitmap_font.rs b/contrib/screen-13-fx/src/bitmap_font.rs index 96f39c3..407de9b 100644 --- a/contrib/screen-13-fx/src/bitmap_font.rs +++ b/contrib/screen-13-fx/src/bitmap_font.rs @@ -40,7 +40,7 @@ impl BitmapFont { let pipeline = Arc::new( GraphicPipeline::create( device, - GraphicPipelineInfo::new().blend(BlendMode::ALPHA), + GraphicPipelineInfoBuilder::default().blend(BlendMode::ALPHA), [ Shader::new_vertex( include_spirv!("res/shader/graphic/font.vert", vert).as_slice(), @@ -163,7 +163,7 @@ impl BitmapFont { let vertex_buf_len = 120 * text.chars().count() as vk::DeviceSize; let mut vertex_buf = self .cache - .lease(BufferInfo::new_mappable( + .lease(BufferInfo::host_mem( vertex_buf_len, vk::BufferUsageFlags::VERTEX_BUFFER, )) diff --git a/contrib/screen-13-fx/src/image_loader.rs b/contrib/screen-13-fx/src/image_loader.rs index 03d341f..b176c84 100644 --- a/contrib/screen-13-fx/src/image_loader.rs +++ b/contrib/screen-13-fx/src/image_loader.rs @@ -99,7 +99,7 @@ impl ImageLoader { Ok(Arc::new( Image::create( &self.device, - ImageInfo::new_2d(format, width, height, usage), + ImageInfo::image_2d(width, height, format, usage), ) .context("Unable to create new image")?, )) @@ -159,7 +159,7 @@ impl ImageLoader { //trace!("pixel_buf_len={pixel_buf_len} pixel_buf_stride={pixel_buf_stride}"); // Lease a temporary buffer from the cache pool - let mut pixel_buf = self.pool.lease(BufferInfo::new_mappable( + let mut pixel_buf = self.pool.lease(BufferInfo::host_mem( pixel_buf_len, vk::BufferUsageFlags::STORAGE_BUFFER, ))?; @@ -208,7 +208,7 @@ impl ImageLoader { } ImageFormat::R8G8 | ImageFormat::R8G8B8A8 => { // Lease a temporary buffer from the pool - let mut pixel_buf = self.pool.lease(BufferInfo::new_mappable( + let mut pixel_buf = self.pool.lease(BufferInfo::host_mem( pixels.len() as _, vk::BufferUsageFlags::TRANSFER_SRC, ))?; diff --git a/contrib/screen-13-fx/src/presenter.rs b/contrib/screen-13-fx/src/presenter.rs index 9d3779c..426d21d 100644 --- a/contrib/screen-13-fx/src/presenter.rs +++ b/contrib/screen-13-fx/src/presenter.rs @@ -86,7 +86,7 @@ impl GraphicPresenter { Ok(Self { pipeline: Arc::new(GraphicPipeline::create( device, - GraphicPipelineInfo::new(), + GraphicPipelineInfo::default(), [ Shader::new_vertex( include_spirv!("res/shader/graphic/present.vert", vert).as_slice(), diff --git a/contrib/screen-13-fx/src/transition.rs b/contrib/screen-13-fx/src/transition.rs index 9222a03..9031c87 100644 --- a/contrib/screen-13-fx/src/transition.rs +++ b/contrib/screen-13-fx/src/transition.rs @@ -413,16 +413,15 @@ impl TransitionPipeline { let a_info = render_graph.node_info(a_image); let b_info = render_graph.node_info(b_image); - let dest_info = ImageInfo::new_2d( - vk::Format::R8G8B8A8_UNORM, + let dest_info = ImageInfo::image_2d( a_info.width.max(b_info.width), a_info.height.max(b_info.height), + vk::Format::R8G8B8A8_UNORM, vk::ImageUsageFlags::SAMPLED | vk::ImageUsageFlags::STORAGE | vk::ImageUsageFlags::TRANSFER_DST | vk::ImageUsageFlags::TRANSFER_SRC, - ) - .build(); + ); let dest_image = render_graph.bind_node(self.cache.lease(dest_info).unwrap()); self.apply_to( diff --git a/contrib/screen-13-hot/src/compute.rs b/contrib/screen-13-hot/src/compute.rs index fb2cbc0..413bb19 100644 --- a/contrib/screen-13-hot/src/compute.rs +++ b/contrib/screen-13-hot/src/compute.rs @@ -57,11 +57,9 @@ impl HotComputePipeline { let (mut watcher, has_changes) = create_watcher(); if let Ok(compiled_shader) = compile_shader_and_watch(&self.shader, &mut watcher) { - if let Ok(instance) = ComputePipeline::create( - &self.device, - self.instance.info.clone(), - compiled_shader, - ) { + if let Ok(instance) = + ComputePipeline::create(&self.device, self.instance.info, compiled_shader) + { self.has_changes = has_changes; self.watcher = watcher; self.instance = Arc::new(instance); diff --git a/contrib/screen-13-hot/src/graphic.rs b/contrib/screen-13-hot/src/graphic.rs index 1f13e2b..c6e188c 100644 --- a/contrib/screen-13-hot/src/graphic.rs +++ b/contrib/screen-13-hot/src/graphic.rs @@ -71,11 +71,9 @@ impl HotGraphicPipeline { .map(|shader| compile_shader_and_watch(shader, &mut watcher)) .collect::, DriverError>>() { - if let Ok(instance) = GraphicPipeline::create( - &self.device, - self.instance.info.clone(), - compiled_shaders, - ) { + if let Ok(instance) = + GraphicPipeline::create(&self.device, self.instance.info, compiled_shaders) + { self.has_changes = has_changes; self.watcher = watcher; self.instance = Arc::new(instance); diff --git a/contrib/screen-13-hot/src/ray_trace.rs b/contrib/screen-13-hot/src/ray_trace.rs index a640d34..71b7475 100644 --- a/contrib/screen-13-hot/src/ray_trace.rs +++ b/contrib/screen-13-hot/src/ray_trace.rs @@ -82,7 +82,7 @@ impl HotRayTracePipeline { { if let Ok(instance) = RayTracePipeline::create( &self.device, - self.instance.info.clone(), + self.instance.info, compiled_shaders, self.shader_groups.iter().copied(), ) { diff --git a/contrib/screen-13-imgui/src/lib.rs b/contrib/screen-13-imgui/src/lib.rs index 56bfef7..db681fe 100644 --- a/contrib/screen-13-imgui/src/lib.rs +++ b/contrib/screen-13-imgui/src/lib.rs @@ -30,7 +30,7 @@ impl ImGui { let pipeline = Arc::new( GraphicPipeline::create( device, - GraphicPipelineInfo::new() + GraphicPipelineInfoBuilder::default() .blend(BlendMode::PRE_MULTIPLIED_ALPHA) .cull_mode(vk::CullModeFlags::NONE), [ @@ -90,10 +90,10 @@ impl ImGui { let image = render_graph.bind_node({ let mut image = self .pool - .lease(ImageInfo::new_2d( - vk::Format::R8G8B8A8_UNORM, + .lease(ImageInfo::image_2d( window.inner_size().width, window.inner_size().height, + vk::Format::R8G8B8A8_UNORM, vk::ImageUsageFlags::COLOR_ATTACHMENT | vk::ImageUsageFlags::SAMPLED | vk::ImageUsageFlags::STORAGE @@ -119,7 +119,7 @@ impl ImGui { let indices = cast_slice(draw_list.idx_buffer()); let mut index_buf = self .pool - .lease(BufferInfo::new_mappable( + .lease(BufferInfo::host_mem( indices.len() as _, vk::BufferUsageFlags::INDEX_BUFFER, )) @@ -135,7 +135,7 @@ impl ImGui { let vertex_buf_len = vertices.len() * 20; let mut vertex_buf = self .pool - .lease(BufferInfo::new_mappable( + .lease(BufferInfo::host_mem( vertex_buf_len as _, vk::BufferUsageFlags::VERTEX_BUFFER, )) @@ -266,7 +266,7 @@ impl ImGui { let temp_buf_len = texture.data.len(); let mut temp_buf = self .pool - .lease(BufferInfo::new_mappable( + .lease(BufferInfo::host_mem( temp_buf_len as _, vk::BufferUsageFlags::TRANSFER_SRC, )) @@ -281,10 +281,10 @@ impl ImGui { let image = render_graph.bind_node({ let mut image = self .pool - .lease(ImageInfo::new_2d( - vk::Format::R8G8B8A8_UNORM, + .lease(ImageInfo::image_2d( texture.width, texture.height, + vk::Format::R8G8B8A8_UNORM, vk::ImageUsageFlags::SAMPLED | vk::ImageUsageFlags::STORAGE | vk::ImageUsageFlags::TRANSFER_DST, diff --git a/examples/aliasing.rs b/examples/aliasing.rs index 02a32f3..34acc05 100644 --- a/examples/aliasing.rs +++ b/examples/aliasing.rs @@ -22,16 +22,16 @@ use { fn main() -> Result<(), DriverError> { pretty_env_logger::init(); - let device = Arc::new(Device::create_headless(DeviceInfo::new())?); + let device = Arc::new(Device::create_headless(DeviceInfo::default())?); // We wrap HashPool in an AliasPool container to enable resource aliasing let mut pool = AliasPool::new(HashPool::new(&device)); // This is the information we will use to alias image1 and image2 - let image_info = ImageInfo::new_2d( - vk::Format::R8G8B8A8_UNORM, + let image_info = ImageInfo::image_2d( 128, 128, + vk::Format::R8G8B8A8_UNORM, vk::ImageUsageFlags::TRANSFER_SRC | vk::ImageUsageFlags::TRANSFER_DST, ); @@ -48,11 +48,10 @@ fn main() -> Result<(), DriverError> { assert_eq!(image1, image2); // Let's make up some different, yet compatible, image information: - let image_info = image_info.build(); - let image_info = ImageInfo::new_2d( - image_info.fmt, + let image_info = ImageInfo::image_2d( image_info.width, image_info.height, + image_info.fmt, vk::ImageUsageFlags::TRANSFER_DST, ); diff --git a/examples/bindless.rs b/examples/bindless.rs index 1624a3a..783f1a4 100644 --- a/examples/bindless.rs +++ b/examples/bindless.rs @@ -46,10 +46,10 @@ fn create_images(device: &Arc) -> Result>, DisplayError> for x in 0..8 { let texture = Arc::new(Image::create( device, - ImageInfo::new_2d( - vk::Format::R8G8B8A8_UNORM, + ImageInfo::image_2d( 100, 100, + vk::Format::R8G8B8A8_UNORM, vk::ImageUsageFlags::SAMPLED | vk::ImageUsageFlags::TRANSFER_DST, ), )?); diff --git a/examples/cpu_readback.rs b/examples/cpu_readback.rs index f3bd189..d454400 100644 --- a/examples/cpu_readback.rs +++ b/examples/cpu_readback.rs @@ -9,7 +9,7 @@ fn main() -> Result<(), DriverError> { pretty_env_logger::init(); // For this example we directly create a device, but the same thing works using an event loop - let device = Arc::new(Device::create_headless(DeviceInfo::new())?); + let device = Arc::new(Device::create_headless(DeviceInfo::default())?); let mut render_graph = RenderGraph::new(); diff --git a/examples/debugger.rs b/examples/debugger.rs index 4a26a03..b250133 100644 --- a/examples/debugger.rs +++ b/examples/debugger.rs @@ -103,10 +103,10 @@ fn main() -> Result<(), screen_13::DisplayError> { let image = frame.render_graph.bind_node( Image::create( frame.device, - ImageInfo::new_2d( - vk::Format::R8G8B8A8_UNORM, + ImageInfo::image_2d( 1024, 1024, + vk::Format::R8G8B8A8_UNORM, vk::ImageUsageFlags::STORAGE | vk::ImageUsageFlags::TRANSFER_SRC, ), ) @@ -115,10 +115,10 @@ fn main() -> Result<(), screen_13::DisplayError> { let image = frame.render_graph.bind_node( Image::create( frame.device, - ImageInfo::new_2d( - vk::Format::UNDEFINED, + ImageInfo::image_2d( u32::MAX, u32::MAX, + vk::Format::UNDEFINED, vk::ImageUsageFlags::RESERVED_22_EXT, ), ) diff --git a/examples/egui.rs b/examples/egui.rs index 51364c1..81ae088 100644 --- a/examples/egui.rs +++ b/examples/egui.rs @@ -15,10 +15,10 @@ fn main() -> Result<(), DisplayError> { event_loop.run(|frame| { let img = frame.render_graph.bind_node( cache - .lease(ImageInfo::new_2d( - vk::Format::R8G8B8A8_UNORM, + .lease(ImageInfo::image_2d( 100, 100, + vk::Format::R8G8B8A8_UNORM, vk::ImageUsageFlags::SAMPLED | vk::ImageUsageFlags::TRANSFER_DST, )) .unwrap(), diff --git a/examples/font_bmp.rs b/examples/font_bmp.rs index 1d45436..a1f90fd 100644 --- a/examples/font_bmp.rs +++ b/examples/font_bmp.rs @@ -117,10 +117,10 @@ fn main() -> anyhow::Result<()> { event_loop.run(|frame| { let image_node = frame.render_graph.bind_node( - pool.lease(ImageInfo::new_2d( - vk::Format::R8G8B8A8_UNORM, + pool.lease(ImageInfo::image_2d( 320, 200, + vk::Format::R8G8B8A8_UNORM, vk::ImageUsageFlags::COLOR_ATTACHMENT | vk::ImageUsageFlags::SAMPLED | vk::ImageUsageFlags::STORAGE diff --git a/examples/fuzzer.rs b/examples/fuzzer.rs index 69a2a51..40f433a 100644 --- a/examples/fuzzer.rs +++ b/examples/fuzzer.rs @@ -82,7 +82,7 @@ fn record_accel_struct_builds(frame: &mut FrameContext, pool: &mut HashPool) { // Vertex buffer for a triangle let vertex_buf = { let mut buf = pool - .lease(BufferInfo::new_mappable( + .lease(BufferInfo::host_mem( 36, vk::BufferUsageFlags::ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_KHR | vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS @@ -111,7 +111,7 @@ fn record_accel_struct_builds(frame: &mut FrameContext, pool: &mut HashPool) { // Index buffer for a single triangle let index_buf = { let mut buf = pool - .lease(BufferInfo::new_mappable( + .lease(BufferInfo::host_mem( 6, vk::BufferUsageFlags::ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_KHR | vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS @@ -146,12 +146,12 @@ fn record_accel_struct_builds(frame: &mut FrameContext, pool: &mut HashPool) { }], }; let blas_size = AccelerationStructure::size_of(frame.device, &blas_geometry_info); - let blas_info = AccelerationStructureInfo::new_blas(blas_size.create_size); + let blas_info = AccelerationStructureInfo::blas(blas_size.create_size); let instance_len = size_of::() as vk::DeviceSize; let mut instance_buf = Buffer::create( frame.device, - BufferInfo::new_mappable( + BufferInfo::host_mem( instance_len * BLAS_COUNT, vk::BufferUsageFlags::ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_KHR | vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS, @@ -198,11 +198,12 @@ fn record_accel_struct_builds(frame: &mut FrameContext, pool: &mut HashPool) { let blas_node = frame.render_graph.bind_node(blas); let scratch_buf = frame.render_graph.bind_node( pool.lease( - BufferInfo::new( + BufferInfo::device_mem( blas_size.build_size, vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS | vk::BufferUsageFlags::STORAGE_BUFFER, ) + .to_builder() .alignment(accel_struct_scratch_offset_alignment), ) .unwrap(), @@ -227,15 +228,16 @@ fn record_accel_struct_builds(frame: &mut FrameContext, pool: &mut HashPool) { let instance_buf = frame.render_graph.bind_node(instance_buf); let tlas_size = AccelerationStructure::size_of(frame.device, &tlas_geometry_info); let tlas = pool - .lease(AccelerationStructureInfo::new_tlas(tlas_size.create_size)) + .lease(AccelerationStructureInfo::tlas(tlas_size.create_size)) .unwrap(); let tlas_node = frame.render_graph.bind_node(tlas); let tlas_scratch_buf = frame.render_graph.bind_node( pool.lease( - BufferInfo::new( + BufferInfo::device_mem( tlas_size.build_size, vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS | vk::BufferUsageFlags::STORAGE_BUFFER, ) + .to_builder() .alignment(accel_struct_scratch_offset_alignment), ) .unwrap(), @@ -342,13 +344,12 @@ fn record_compute_array_bind(frame: &mut FrameContext, pool: &mut HashPool) { )), ); - let image_info = ImageInfo::new_2d( - vk::Format::R8G8B8A8_UNORM, + let image_info = ImageInfo::image_2d( 64, 64, + vk::Format::R8G8B8A8_UNORM, vk::ImageUsageFlags::SAMPLED | vk::ImageUsageFlags::TRANSFER_DST, - ) - .build(); + ); let images = [ frame .render_graph @@ -423,13 +424,12 @@ fn record_compute_bindless(frame: &mut FrameContext, pool: &mut HashPool) { ), ); - let image_info = ImageInfo::new_2d( - vk::Format::R8G8B8A8_UNORM, + let image_info = ImageInfo::image_2d( 64, 64, + vk::Format::R8G8B8A8_UNORM, vk::ImageUsageFlags::SAMPLED | vk::ImageUsageFlags::STORAGE, - ) - .build(); + ); let images = [ frame .render_graph @@ -533,23 +533,22 @@ fn record_graphic_bindless(frame: &mut FrameContext, pool: &mut HashPool) { ); let image = frame.render_graph.bind_node( - pool.lease(ImageInfo::new_2d( - vk::Format::R8G8B8A8_UNORM, + pool.lease(ImageInfo::image_2d( 256, 256, + vk::Format::R8G8B8A8_UNORM, vk::ImageUsageFlags::COLOR_ATTACHMENT | vk::ImageUsageFlags::INPUT_ATTACHMENT, )) .unwrap(), ); - let image_info = ImageInfo::new_2d( - vk::Format::R8G8B8A8_UNORM, + let image_info = ImageInfo::image_2d( 64, 64, + vk::Format::R8G8B8A8_UNORM, vk::ImageUsageFlags::SAMPLED | vk::ImageUsageFlags::STORAGE | vk::ImageUsageFlags::TRANSFER_DST, - ) - .build(); + ); let images = [ frame .render_graph @@ -699,7 +698,7 @@ fn record_graphic_msaa_depth_stencil(frame: &mut FrameContext, pool: &mut HashPo let pipeline = graphic_vert_frag_pipeline( frame.device, - GraphicPipelineInfo::new().samples(sample_count), + GraphicPipelineInfoBuilder::default().samples(sample_count), inline_spirv!( r#" #version 460 core @@ -735,34 +734,36 @@ fn record_graphic_msaa_depth_stencil(frame: &mut FrameContext, pool: &mut HashPo let swapchain_format = frame.render_graph.node_info(frame.swapchain_image).fmt; let msaa_color_image = frame.render_graph.bind_node( pool.lease( - ImageInfo::new_2d( - swapchain_format, + ImageInfo::image_2d( frame.width, frame.height, + swapchain_format, vk::ImageUsageFlags::COLOR_ATTACHMENT | vk::ImageUsageFlags::TRANSIENT_ATTACHMENT, ) + .to_builder() .sample_count(sample_count), ) .unwrap(), ); let msaa_depth_stencil_image = frame.render_graph.bind_node( pool.lease( - ImageInfo::new_2d( - depth_stencil_format, + ImageInfo::image_2d( frame.width, frame.height, + depth_stencil_format, vk::ImageUsageFlags::DEPTH_STENCIL_ATTACHMENT | vk::ImageUsageFlags::TRANSIENT_ATTACHMENT, ) + .to_builder() .sample_count(sample_count), ) .unwrap(), ); let depth_stencil_image = frame.render_graph.bind_node( - pool.lease(ImageInfo::new_2d( - depth_stencil_format, + pool.lease(ImageInfo::image_2d( frame.width, frame.height, + depth_stencil_format, vk::ImageUsageFlags::DEPTH_STENCIL_ATTACHMENT, )) .unwrap(), @@ -856,10 +857,10 @@ fn record_graphic_will_merge_subpass_input(frame: &mut FrameContext, pool: &mut .as_slice(), ); let image = frame.render_graph.bind_node( - pool.lease(ImageInfo::new_2d( - vk::Format::R8G8B8A8_UNORM, + pool.lease(ImageInfo::image_2d( 256, 256, + vk::Format::R8G8B8A8_UNORM, vk::ImageUsageFlags::COLOR_ATTACHMENT | vk::ImageUsageFlags::INPUT_ATTACHMENT | vk::ImageUsageFlags::TRANSFER_DST, @@ -916,10 +917,10 @@ fn record_graphic_wont_merge(frame: &mut FrameContext, pool: &mut HashPool) { ); let image = frame.render_graph.bind_node( - pool.lease(ImageInfo::new_2d( - vk::Format::R8G8B8A8_UNORM, + pool.lease(ImageInfo::image_2d( 256, 256, + vk::Format::R8G8B8A8_UNORM, vk::ImageUsageFlags::COLOR_ATTACHMENT, )) .unwrap(), @@ -976,19 +977,19 @@ fn record_transfer_graphic_multipass(frame: &mut FrameContext, pool: &mut HashPo ); let images = [ frame.render_graph.bind_node( - pool.lease(ImageInfo::new_2d( - vk::Format::R8G8B8A8_UNORM, + pool.lease(ImageInfo::image_2d( 256, 256, + vk::Format::R8G8B8A8_UNORM, vk::ImageUsageFlags::SAMPLED | vk::ImageUsageFlags::TRANSFER_DST, )) .unwrap(), ), frame.render_graph.bind_node( - pool.lease(ImageInfo::new_2d( - vk::Format::R8G8B8A8_UNORM, + pool.lease(ImageInfo::image_2d( 256, 256, + vk::Format::R8G8B8A8_UNORM, vk::ImageUsageFlags::SAMPLED | vk::ImageUsageFlags::TRANSFER_DST, )) .unwrap(), @@ -1070,7 +1071,7 @@ fn graphic_vert_frag_pipeline( Arc::clone( tls.borrow_mut() .entry(Key { - info: info.clone(), + info, vert_source, frag_source, }) diff --git a/examples/image_sampler.rs b/examples/image_sampler.rs index 63312ad..3431c64 100644 --- a/examples/image_sampler.rs +++ b/examples/image_sampler.rs @@ -20,14 +20,14 @@ fn main() -> anyhow::Result<()> { let gulf_image = read_image(&event_loop.device, "examples/res/image/gulf.jpg")?; // Sampler info contains the full definition of Vulkan sampler settings using a builder struct - let edge_edge = SamplerInfo::new() + let edge_edge = SamplerInfoBuilder::default() .address_mode_u(vk::SamplerAddressMode::CLAMP_TO_EDGE) .address_mode_v(vk::SamplerAddressMode::CLAMP_TO_EDGE); - let border_edge_black = SamplerInfo::new() + let border_edge_black = SamplerInfoBuilder::default() .address_mode_u(vk::SamplerAddressMode::CLAMP_TO_BORDER) .address_mode_v(vk::SamplerAddressMode::CLAMP_TO_EDGE) .border_color(vk::BorderColor::FLOAT_OPAQUE_BLACK); - let edge_border_white = SamplerInfo::new() + let edge_border_white = SamplerInfoBuilder::default() .address_mode_u(vk::SamplerAddressMode::CLAMP_TO_EDGE) .address_mode_v(vk::SamplerAddressMode::CLAMP_TO_BORDER) .border_color(vk::BorderColor::FLOAT_OPAQUE_WHITE); @@ -71,7 +71,7 @@ fn create_pipeline( ) -> anyhow::Result> { Ok(Arc::new(GraphicPipeline::create( device, - GraphicPipelineInfo::new(), + GraphicPipelineInfo::default(), [ Shader::new_vertex( inline_spirv!( @@ -122,10 +122,10 @@ fn read_image(device: &Arc, path: impl AsRef) -> anyhow::Result Result<(), DisplayError> { event_loop.run(|mut frame| { // Lease and clear an image as a stand-in for some real game or program output let app_image = frame.render_graph.bind_node( - pool.lease(ImageInfo::new_2d( - vk::Format::R8G8B8A8_UNORM, + pool.lease(ImageInfo::image_2d( frame.width, frame.height, + vk::Format::R8G8B8A8_UNORM, vk::ImageUsageFlags::SAMPLED | vk::ImageUsageFlags::STORAGE | vk::ImageUsageFlags::TRANSFER_DST, diff --git a/examples/min_max.rs b/examples/min_max.rs index 3ee94d8..e4eaa0f 100644 --- a/examples/min_max.rs +++ b/examples/min_max.rs @@ -18,7 +18,7 @@ fn main() -> Result<(), DriverError> { pretty_env_logger::init(); let mut render_graph = RenderGraph::new(); - let device = Arc::new(Device::create_headless(DeviceInfo::new())?); + let device = Arc::new(Device::create_headless(DeviceInfo::default())?); let size = 4; // The 4x4 depth image will have pixels that look like this: @@ -86,13 +86,12 @@ fn fill_depth_image( render_graph: &mut RenderGraph, size: u32, ) -> Result { - let info = ImageInfo::new_2d( - vk::Format::D32_SFLOAT, + let info = ImageInfo::image_2d( size, size, + vk::Format::D32_SFLOAT, vk::ImageUsageFlags::SAMPLED | vk::ImageUsageFlags::TRANSFER_DST, - ) - .build(); + ); let ImageInfo { fmt, ty, @@ -163,13 +162,12 @@ fn reduce_depth_image( // (We use R32_SFLOAT because D32_SFLOAT has very low support for the STORAGE usage and most // implementations would be reading the image elsewhere instead of using it as a depth image) - let reduced_info = ImageInfo::new_2d( - vk::Format::R32_SFLOAT, + let reduced_info = ImageInfo::image_2d( depth_info.width >> 1, depth_info.height >> 1, + vk::Format::R32_SFLOAT, vk::ImageUsageFlags::STORAGE | vk::ImageUsageFlags::TRANSFER_SRC, - ) - .build(); + ); let reduced_image = render_graph.bind_node(Image::create(device, reduced_info)?); render_graph @@ -217,7 +215,7 @@ fn copy_image_to_buffer( * size_of::() as vk::DeviceSize; let result_buf = render_graph.bind_node(Buffer::create( device, - BufferInfo::new_mappable(result_len, vk::BufferUsageFlags::TRANSFER_DST), + BufferInfo::host_mem(result_len, vk::BufferUsageFlags::TRANSFER_DST), )?); render_graph.copy_image_to_buffer(reduced_image, result_buf); diff --git a/examples/msaa.rs b/examples/msaa.rs index 17176c0..0f05fda 100644 --- a/examples/msaa.rs +++ b/examples/msaa.rs @@ -43,7 +43,7 @@ fn main() -> anyhow::Result<()> { * Mat4::from_rotation_z(angle * 0.22); let mut scene_uniform_buf = pool - .lease(BufferInfo::new_mappable( + .lease(BufferInfo::host_mem( size_of::() as _, vk::BufferUsageFlags::UNIFORM_BUFFER, )) @@ -81,26 +81,28 @@ fn main() -> anyhow::Result<()> { if will_render_msaa { let msaa_color_image = pass.bind_node( pool.lease( - ImageInfo::new_2d( - pass.node_info(frame.swapchain_image).fmt, + ImageInfo::image_2d( frame.width, frame.height, + pass.node_info(frame.swapchain_image).fmt, vk::ImageUsageFlags::COLOR_ATTACHMENT | vk::ImageUsageFlags::TRANSIENT_ATTACHMENT, ) + .to_builder() .sample_count(sample_count), ) .unwrap(), ); let msaa_depth_image = pass.bind_node( pool.lease( - ImageInfo::new_2d( - depth_format, + ImageInfo::image_2d( frame.width, frame.height, + depth_format, vk::ImageUsageFlags::DEPTH_STENCIL_ATTACHMENT | vk::ImageUsageFlags::TRANSIENT_ATTACHMENT, ) + .to_builder() .sample_count(sample_count), ) .unwrap(), @@ -113,10 +115,10 @@ fn main() -> anyhow::Result<()> { .resolve_color(0, 1, frame.swapchain_image); } else { let noaa_depth_image = pass.bind_node( - pool.lease(ImageInfo::new_2d( - depth_format, + pool.lease(ImageInfo::image_2d( frame.width, frame.height, + depth_format, vk::ImageUsageFlags::DEPTH_STENCIL_ATTACHMENT | vk::ImageUsageFlags::TRANSIENT_ATTACHMENT, )) @@ -346,7 +348,7 @@ fn create_mesh_pipeline( frag ); - let info = GraphicPipelineInfo::new().samples(sample_count); + let info = GraphicPipelineInfoBuilder::default().samples(sample_count); Ok(Arc::new(GraphicPipeline::create( device, diff --git a/examples/multipass.rs b/examples/multipass.rs index 85475d7..c046547 100644 --- a/examples/multipass.rs +++ b/examples/multipass.rs @@ -57,10 +57,10 @@ fn main() -> Result<(), DisplayError> { let vertex_buf = frame.render_graph.bind_node(&funky_shape.vertex_buf); let depth_stencil = frame.render_graph.bind_node( - pool.lease(ImageInfo::new_2d( - depth_stencil_format, + pool.lease(ImageInfo::image_2d( frame.width, frame.height, + depth_stencil_format, vk::ImageUsageFlags::DEPTH_STENCIL_ATTACHMENT | vk::ImageUsageFlags::TRANSIENT_ATTACHMENT, )) @@ -162,7 +162,7 @@ fn bind_camera_buf( model: Mat4, ) -> BufferLeaseNode { let mut buf = pool - .lease(BufferInfo::new_mappable( + .lease(BufferInfo::host_mem( 204, vk::BufferUsageFlags::UNIFORM_BUFFER, )) @@ -174,7 +174,7 @@ fn bind_camera_buf( fn bind_light_buf(frame: &mut FrameContext, pool: &mut LazyPool) -> BufferLeaseNode { let mut buf = pool - .lease(BufferInfo::new_mappable( + .lease(BufferInfo::host_mem( 64, vk::BufferUsageFlags::UNIFORM_BUFFER, )) @@ -234,14 +234,14 @@ fn create_funky_shape(event_loop: &EventLoop, pool: &mut LazyPool) -> Result) -> Arc Arc::new( GraphicPipeline::create( device, - GraphicPipelineInfo::new(), + GraphicPipelineInfo::default(), [vertex_shader, fragment_shader], ) .unwrap(), @@ -509,7 +509,7 @@ fn create_pbr_pipeline(device: &Arc) -> Arc { Arc::new( GraphicPipeline::create( device, - GraphicPipelineInfo::new(), + GraphicPipelineInfo::default(), [vertex_shader, fragment_shader], ) .unwrap(), diff --git a/examples/multithread.rs b/examples/multithread.rs index e6c5abb..67557f0 100644 --- a/examples/multithread.rs +++ b/examples/multithread.rs @@ -94,10 +94,10 @@ fn main() -> anyhow::Result<()> { // Clear a new image to a cycling color let mut render_graph = RenderGraph::new(); let image = render_graph.bind_node( - pool.lease(ImageInfo::new_2d( - vk::Format::R8G8B8A8_UNORM, + pool.lease(ImageInfo::image_2d( 10, 10, + vk::Format::R8G8B8A8_UNORM, vk::ImageUsageFlags::TRANSFER_DST | vk::ImageUsageFlags::TRANSFER_SRC, )) .unwrap(), @@ -223,10 +223,10 @@ fn load_font(device: &Arc) -> anyhow::Result { // This image will hold the font glyphs let page_0 = Image::create( device, - ImageInfo::new_2d( - vk::Format::R8G8B8A8_UNORM, + ImageInfo::image_2d( 64, 64, + vk::Format::R8G8B8A8_UNORM, vk::ImageUsageFlags::SAMPLED | vk::ImageUsageFlags::TRANSFER_DST, ), ) diff --git a/examples/ray_omni.rs b/examples/ray_omni.rs index 622e795..335730c 100644 --- a/examples/ray_omni.rs +++ b/examples/ray_omni.rs @@ -47,17 +47,17 @@ fn main() -> anyhow::Result<()> { let model_mesh_vertex_buf = frame.render_graph.bind_node(&model_mesh.vertex_buf); let depth_image = frame.render_graph.bind_node( - pool.lease(ImageInfo::new_2d( - depth_fmt, + pool.lease(ImageInfo::image_2d( frame.width, frame.height, + depth_fmt, vk::ImageUsageFlags::DEPTH_STENCIL_ATTACHMENT, )) .unwrap(), ); let camera_buf = frame.render_graph.bind_node({ let mut buf = pool - .lease(BufferInfo::new_mappable( + .lease(BufferInfo::host_mem( size_of::() as _, vk::BufferUsageFlags::UNIFORM_BUFFER, )) @@ -172,7 +172,7 @@ fn create_blas( let mut render_graph = RenderGraph::new(); let blas = render_graph.bind_node(AccelerationStructure::create( device, - AccelerationStructureInfo::new_blas(size.create_size), + AccelerationStructureInfo::blas(size.create_size), )?); let accel_struct_scratch_offset_alignment = device @@ -184,10 +184,11 @@ fn create_blas( as vk::DeviceSize; let scratch_buf = render_graph.bind_node(Buffer::create( device, - BufferInfo::new( + BufferInfo::device_mem( size.build_size, vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS | vk::BufferUsageFlags::STORAGE_BUFFER, ) + .to_builder() .alignment(accel_struct_scratch_offset_alignment), )?); let build_ranges = models @@ -305,7 +306,7 @@ fn create_pipeline(device: &Arc) -> Result, DriverE Ok(Arc::new(GraphicPipeline::create( device, - GraphicPipelineInfo::new(), + GraphicPipelineInfo::default(), [ Shader::new_vertex(vert.as_slice()), Shader::new_fragment(frag.as_slice()), @@ -340,7 +341,7 @@ fn create_tlas( let instance_buf = Arc::new({ let mut buffer = Buffer::create( device, - BufferInfo::new_mappable( + BufferInfo::host_mem( instance_data.len() as _, vk::BufferUsageFlags::ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_KHR | vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS @@ -366,7 +367,7 @@ fn create_tlas( }; let size = AccelerationStructure::size_of(device, &info); let tlas = - render_graph.bind_node(pool.lease(AccelerationStructureInfo::new_tlas(size.create_size))?); + render_graph.bind_node(pool.lease(AccelerationStructureInfo::tlas(size.create_size))?); let accel_struct_scratch_offset_alignment = device .physical_device @@ -377,10 +378,11 @@ fn create_tlas( as vk::DeviceSize; let scratch_buf = render_graph.bind_node( pool.lease( - BufferInfo::new( + BufferInfo::device_mem( size.build_size, vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS | vk::BufferUsageFlags::STORAGE_BUFFER, ) + .to_builder() .alignment(accel_struct_scratch_offset_alignment), )?, ); diff --git a/examples/ray_trace.rs b/examples/ray_trace.rs index 75fc8f7..b5a98f7 100644 --- a/examples/ray_trace.rs +++ b/examples/ray_trace.rs @@ -330,9 +330,7 @@ fn align_up(val: u32, atom: u32) -> u32 { fn create_ray_trace_pipeline(device: &Arc) -> Result, DriverError> { Ok(Arc::new(RayTracePipeline::create( device, - RayTracePipelineInfo::new() - .max_ray_recursion_depth(1) - .build(), + RayTracePipelineInfoBuilder::default().max_ray_recursion_depth(1), [ Shader::new_ray_gen(SHADER_RAY_GEN), Shader::new_closest_hit(SHADER_CLOSEST_HIT), @@ -391,7 +389,7 @@ fn load_scene_buffers( let data = cast_slice(&indices); let mut buf = Buffer::create( device, - BufferInfo::new_mappable( + BufferInfo::host_mem( data.len() as _, vk::BufferUsageFlags::ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_KHR | vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS @@ -406,7 +404,7 @@ fn load_scene_buffers( let data = cast_slice(&positions); let mut buf = Buffer::create( device, - BufferInfo::new_mappable( + BufferInfo::host_mem( data.len() as _, vk::BufferUsageFlags::ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_KHR | vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS @@ -427,7 +425,7 @@ fn load_scene_buffers( let data = cast_slice(&material_ids); let mut buf = Buffer::create( device, - BufferInfo::new_mappable(data.len() as _, vk::BufferUsageFlags::STORAGE_BUFFER), + BufferInfo::host_mem(data.len() as _, vk::BufferUsageFlags::STORAGE_BUFFER), )?; Buffer::copy_from_slice(&mut buf, 0, data); buf @@ -464,7 +462,7 @@ fn load_scene_buffers( let buf_len = materials.len() * 64; let mut buf = Buffer::create( device, - BufferInfo::new_mappable(buf_len as _, vk::BufferUsageFlags::STORAGE_BUFFER), + BufferInfo::host_mem(buf_len as _, vk::BufferUsageFlags::STORAGE_BUFFER), )?; Buffer::copy_from_slice(&mut buf, 0, unsafe { from_raw_parts(materials.as_ptr() as *const _, buf_len) @@ -517,11 +515,12 @@ fn main() -> anyhow::Result<()> { let sbt_buf = Arc::new({ let mut buf = Buffer::create( &event_loop.device, - BufferInfo::new_mappable( + BufferInfo::host_mem( (sbt_rgen_size + sbt_hit_size + sbt_miss_size) as _, vk::BufferUsageFlags::SHADER_BINDING_TABLE_KHR | vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS, ) + .to_builder() .alignment(shader_group_base_alignment as _), ) .unwrap(); @@ -593,7 +592,7 @@ fn main() -> anyhow::Result<()> { let blas_size = AccelerationStructure::size_of(&event_loop.device, &blas_geometry_info); let blas = Arc::new(AccelerationStructure::create( &event_loop.device, - AccelerationStructureInfo::new_blas(blas_size.create_size), + AccelerationStructureInfo::blas(blas_size.create_size), )?); let blas_device_address = AccelerationStructure::device_address(&blas); @@ -622,7 +621,7 @@ fn main() -> anyhow::Result<()> { let instance_buf = Arc::new({ let mut buffer = Buffer::create( &event_loop.device, - BufferInfo::new_mappable( + BufferInfo::host_mem( instance_data.len() as _, vk::BufferUsageFlags::ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_KHR | vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS, @@ -652,7 +651,7 @@ fn main() -> anyhow::Result<()> { let tlas_size = AccelerationStructure::size_of(&event_loop.device, &tlas_geometry_info); let tlas = Arc::new(AccelerationStructure::create( &event_loop.device, - AccelerationStructureInfo::new_tlas(tlas_size.create_size), + AccelerationStructureInfo::tlas(tlas_size.create_size), )?); // ------------------------------------------------------------------------------------------ // @@ -676,11 +675,12 @@ fn main() -> anyhow::Result<()> { { let scratch_buf = render_graph.bind_node(Buffer::create( &event_loop.device, - BufferInfo::new( + BufferInfo::device_mem( blas_size.build_size, vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS | vk::BufferUsageFlags::STORAGE_BUFFER, ) + .to_builder() .alignment(accel_struct_scratch_offset_alignment), )?); @@ -708,11 +708,12 @@ fn main() -> anyhow::Result<()> { { let scratch_buf = render_graph.bind_node(Buffer::create( &event_loop.device, - BufferInfo::new( + BufferInfo::device_mem( tlas_size.build_size, vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS | vk::BufferUsageFlags::STORAGE_BUFFER, ) + .to_builder() .alignment(accel_struct_scratch_offset_alignment), )?); let instance_node = render_graph.bind_node(&instance_buf); @@ -764,10 +765,10 @@ fn main() -> anyhow::Result<()> { if image.is_none() { image = Some(Arc::new( cache - .lease(ImageInfo::new_2d( - frame.render_graph.node_info(frame.swapchain_image).fmt, + .lease(ImageInfo::image_2d( frame.width, frame.height, + frame.render_graph.node_info(frame.swapchain_image).fmt, vk::ImageUsageFlags::STORAGE | vk::ImageUsageFlags::TRANSFER_DST | vk::ImageUsageFlags::TRANSFER_SRC, @@ -824,7 +825,7 @@ fn main() -> anyhow::Result<()> { } let mut buf = cache - .lease(BufferInfo::new_mappable( + .lease(BufferInfo::host_mem( size_of::() as _, vk::BufferUsageFlags::UNIFORM_BUFFER, )) diff --git a/examples/rt_triangle.rs b/examples/rt_triangle.rs index 819f828..65d4c83 100644 --- a/examples/rt_triangle.rs +++ b/examples/rt_triangle.rs @@ -74,9 +74,7 @@ fn align_up(val: u32, atom: u32) -> u32 { fn create_ray_trace_pipeline(device: &Arc) -> Result, DriverError> { Ok(Arc::new(RayTracePipeline::create( device, - RayTracePipelineInfo::new() - .max_ray_recursion_depth(1) - .build(), + RayTracePipelineInfoBuilder::default().max_ray_recursion_depth(1), [ Shader::new_ray_gen(SHADER_RAY_GEN), Shader::new_closest_hit(SHADER_CLOSEST_HIT), @@ -127,11 +125,12 @@ fn main() -> anyhow::Result<()> { let sbt_buf = Arc::new({ let mut buf = Buffer::create( &event_loop.device, - BufferInfo::new_mappable( + BufferInfo::host_mem( (sbt_rgen_size + sbt_hit_size + sbt_miss_size) as _, vk::BufferUsageFlags::SHADER_BINDING_TABLE_KHR | vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS, ) + .to_builder() .alignment(shader_group_base_alignment as _), ) .unwrap(); @@ -205,7 +204,7 @@ fn main() -> anyhow::Result<()> { let data = cast_slice(&INDICES); let mut buf = Buffer::create( &event_loop.device, - BufferInfo::new_mappable( + BufferInfo::host_mem( data.len() as _, vk::BufferUsageFlags::ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_KHR | vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS, @@ -219,7 +218,7 @@ fn main() -> anyhow::Result<()> { let data = cast_slice(&VERTICES); let mut buf = Buffer::create( &event_loop.device, - BufferInfo::new_mappable( + BufferInfo::host_mem( data.len() as _, vk::BufferUsageFlags::ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_KHR | vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS, @@ -255,7 +254,7 @@ fn main() -> anyhow::Result<()> { let blas_size = AccelerationStructure::size_of(&event_loop.device, &blas_geometry_info); let blas = Arc::new(AccelerationStructure::create( &event_loop.device, - AccelerationStructureInfo::new_blas(blas_size.create_size), + AccelerationStructureInfo::blas(blas_size.create_size), )?); let blas_device_address = AccelerationStructure::device_address(&blas); @@ -284,7 +283,7 @@ fn main() -> anyhow::Result<()> { let instance_buf = Arc::new({ let mut buffer = Buffer::create( &event_loop.device, - BufferInfo::new_mappable( + BufferInfo::host_mem( instance_data.len() as _, vk::BufferUsageFlags::ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_KHR | vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS, @@ -314,7 +313,7 @@ fn main() -> anyhow::Result<()> { let tlas_size = AccelerationStructure::size_of(&event_loop.device, &tlas_geometry_info); let tlas = Arc::new(AccelerationStructure::create( &event_loop.device, - AccelerationStructureInfo::new_tlas(tlas_size.create_size), + AccelerationStructureInfo::tlas(tlas_size.create_size), )?); // ------------------------------------------------------------------------------------------ // @@ -338,11 +337,12 @@ fn main() -> anyhow::Result<()> { { let scratch_buf = render_graph.bind_node(Buffer::create( &event_loop.device, - BufferInfo::new( + BufferInfo::device_mem( blas_size.build_size, vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS | vk::BufferUsageFlags::STORAGE_BUFFER, ) + .to_builder() .alignment(accel_struct_scratch_offset_alignment), )?); @@ -371,11 +371,12 @@ fn main() -> anyhow::Result<()> { let instance_node = render_graph.bind_node(instance_buf); let scratch_buf = render_graph.bind_node(Buffer::create( &event_loop.device, - BufferInfo::new( + BufferInfo::device_mem( tlas_size.build_size, vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS | vk::BufferUsageFlags::STORAGE_BUFFER, ) + .to_builder() .alignment(accel_struct_scratch_offset_alignment), )?); let tlas_node = render_graph.bind_node(&tlas); diff --git a/examples/shader-toy/src/main.rs b/examples/shader-toy/src/main.rs index 40546e9..db95223 100644 --- a/examples/shader-toy/src/main.rs +++ b/examples/shader-toy/src/main.rs @@ -118,10 +118,10 @@ fn main() -> anyhow::Result<()> { let mut render_graph = RenderGraph::new(); let blank_image = render_graph.bind_node( cache - .lease(ImageInfo::new_2d( - vk::Format::R8G8B8A8_SRGB, + .lease(ImageInfo::image_2d( 8, 8, + vk::Format::R8G8B8A8_SRGB, vk::ImageUsageFlags::SAMPLED | vk::ImageUsageFlags::TRANSFER_DST, )) .context("Blank image")?, @@ -130,10 +130,10 @@ fn main() -> anyhow::Result<()> { let (width, height) = (event_loop.width(), event_loop.height()); let framebuffer_image = render_graph.bind_node( cache - .lease(ImageInfo::new_2d( - vk::Format::R8G8B8A8_SRGB, + .lease(ImageInfo::image_2d( width, height, + vk::Format::R8G8B8A8_SRGB, vk::ImageUsageFlags::COLOR_ATTACHMENT | vk::ImageUsageFlags::SAMPLED | vk::ImageUsageFlags::TRANSFER_DST @@ -143,10 +143,10 @@ fn main() -> anyhow::Result<()> { ); let temp_image = render_graph.bind_node( cache - .lease(ImageInfo::new_2d( - vk::Format::R8G8B8A8_SRGB, + .lease(ImageInfo::image_2d( width, height, + vk::Format::R8G8B8A8_SRGB, vk::ImageUsageFlags::COLOR_ATTACHMENT | vk::ImageUsageFlags::SAMPLED | vk::ImageUsageFlags::TRANSFER_DST diff --git a/examples/skeletal-anim/src/main.rs b/examples/skeletal-anim/src/main.rs index 04e765b..0e6a1b7 100644 --- a/examples/skeletal-anim/src/main.rs +++ b/examples/skeletal-anim/src/main.rs @@ -47,10 +47,10 @@ fn main() -> Result<(), DisplayError> { let index_buf = frame.render_graph.bind_node(&character.index_buf); let vertex_buf = frame.render_graph.bind_node(&character.vertex_buf); let depth_image = frame.render_graph.bind_node( - pool.lease(ImageInfo::new_2d( - vk::Format::D32_SFLOAT, + pool.lease(ImageInfo::image_2d( frame.width, frame.height, + vk::Format::D32_SFLOAT, vk::ImageUsageFlags::DEPTH_STENCIL_ATTACHMENT, )) .unwrap(), @@ -71,7 +71,7 @@ fn main() -> Result<(), DisplayError> { let projection = Mat4::perspective_rh(45.0, aspect_ratio, 0.1, 100.0); let view = Mat4::look_at_rh(position, Vec3::Y * 2.0, -Vec3::Y); let mut buf = pool - .lease(BufferInfo::new_mappable( + .lease(BufferInfo::host_mem( size_of::() as _, vk::BufferUsageFlags::UNIFORM_BUFFER, )) @@ -97,7 +97,7 @@ fn main() -> Result<(), DisplayError> { }; let joints = animation.update(frame.dt); let mut buf = pool - .lease(BufferInfo::new_mappable( + .lease(BufferInfo::host_mem( size_of_val(joints) as _, vk::BufferUsageFlags::STORAGE_BUFFER, )) @@ -140,7 +140,7 @@ fn create_pipeline( Ok(Arc::new(GraphicPipeline::create( device, - GraphicPipelineInfo::new().front_face(vk::FrontFace::CLOCKWISE), + GraphicPipelineInfoBuilder::default().front_face(vk::FrontFace::CLOCKWISE), [ Shader::new_vertex(vert_spirv.as_slice()), Shader::new_fragment(frag_spirv.as_slice()), @@ -170,10 +170,10 @@ fn load_texture( )?); let image = Arc::new(Image::create( device, - ImageInfo::new_2d( - vk::Format::R8G8B8A8_UNORM, + ImageInfo::image_2d( bitmap.width(), bitmap.height(), + vk::Format::R8G8B8A8_UNORM, vk::ImageUsageFlags::SAMPLED | vk::ImageUsageFlags::TRANSFER_DST, ), )?); @@ -404,14 +404,14 @@ impl Model { // Device-only buffers let index_buf = Arc::new(Buffer::create( device, - BufferInfo::new( + BufferInfo::device_mem( index_data.len() as _, vk::BufferUsageFlags::INDEX_BUFFER | vk::BufferUsageFlags::TRANSFER_DST, ), )?); let vertex_buf = Arc::new(Buffer::create( device, - BufferInfo::new( + BufferInfo::device_mem( vertex_data.len() as _, vk::BufferUsageFlags::VERTEX_BUFFER | vk::BufferUsageFlags::TRANSFER_DST, ), diff --git a/examples/subgroup_ops.rs b/examples/subgroup_ops.rs index cdbc039..949656d 100644 --- a/examples/subgroup_ops.rs +++ b/examples/subgroup_ops.rs @@ -28,7 +28,7 @@ use { fn main() -> Result<(), DriverError> { pretty_env_logger::init(); - let device = Arc::new(Device::create_headless(DeviceInfo::new())?); + let device = Arc::new(Device::create_headless(DeviceInfo::default())?); let Vulkan11Properties { subgroup_size, subgroup_supported_operations, @@ -73,7 +73,7 @@ fn exclusive_sum( let output_buf = render_graph.bind_node(Arc::new(Buffer::create( device, - BufferInfo::new_mappable( + BufferInfo::host_mem( input_data.len() as vk::DeviceSize * size_of::() as vk::DeviceSize, vk::BufferUsageFlags::STORAGE_BUFFER, ), @@ -84,7 +84,7 @@ fn exclusive_sum( let reduce_count = workgroup_count - 1; let workgroup_buf = render_graph.bind_node(Buffer::create( device, - BufferInfo::new( + BufferInfo::device_mem( reduce_count.max(1) as vk::DeviceSize * size_of::() as vk::DeviceSize, vk::BufferUsageFlags::STORAGE_BUFFER, ), diff --git a/examples/vr/src/driver/swapchain.rs b/examples/vr/src/driver/swapchain.rs index 56a9069..e851af4 100644 --- a/examples/vr/src/driver/swapchain.rs +++ b/examples/vr/src/driver/swapchain.rs @@ -55,11 +55,11 @@ impl Swapchain { .into_iter() .map(|image| { let image = vk::Image::from_raw(image); - let info = ImageInfo::new_2d_array( - vk::Format::R8G8B8A8_SRGB, + let info = ImageInfo::image_2d_array( resolution.width, resolution.height, 2, + vk::Format::R8G8B8A8_SRGB, vk::ImageUsageFlags::SAMPLED, ); diff --git a/examples/vr/src/main.rs b/examples/vr/src/main.rs index db001fd..54e9a80 100644 --- a/examples/vr/src/main.rs +++ b/examples/vr/src/main.rs @@ -124,7 +124,7 @@ fn main() -> anyhow::Result<()> { let mut hands_pipeline = HotGraphicPipeline::create( device, - GraphicPipelineInfo::new(), + GraphicPipelineInfo::default(), [ HotShader::new_vertex(res_dir.join("model.vert")), HotShader::new_fragment(res_dir.join("hands.frag")), @@ -132,7 +132,7 @@ fn main() -> anyhow::Result<()> { )?; let mut mammoth_pipeline = HotGraphicPipeline::create( device, - GraphicPipelineInfo::new(), + GraphicPipelineInfo::default(), [ HotShader::new_vertex(res_dir.join("model.vert")), HotShader::new_fragment(res_dir.join("mammoth.frag")), @@ -270,11 +270,11 @@ fn main() -> anyhow::Result<()> { let mut render_graph = RenderGraph::new(); let depth_image = render_graph.bind_node( - pool.lease(ImageInfo::new_2d_array( - vk::Format::D32_SFLOAT, + pool.lease(ImageInfo::image_2d_array( resolution.width, resolution.height, 2, + vk::Format::D32_SFLOAT, vk::ImageUsageFlags::DEPTH_STENCIL_ATTACHMENT, )) .unwrap(), @@ -293,7 +293,7 @@ fn main() -> anyhow::Result<()> { let camera_buf = { let cameras = [CameraBuffer::new(views[0]), CameraBuffer::new(views[1])]; let data = cast_slice(&cameras); - let mut buf = pool.lease(BufferInfo::new_mappable( + let mut buf = pool.lease(BufferInfo::host_mem( data.len() as _, vk::BufferUsageFlags::UNIFORM_BUFFER, ))?; @@ -332,7 +332,7 @@ fn main() -> anyhow::Result<()> { let light_buf = { let light = LightBuffer::new(light_position); let data = bytes_of(&light); - let mut buf = pool.lease(BufferInfo::new_mappable( + let mut buf = pool.lease(BufferInfo::host_mem( data.len() as _, vk::BufferUsageFlags::UNIFORM_BUFFER, ))?; @@ -732,7 +732,7 @@ fn load_texture( let staging_buf_size = image_rows * image_row_size; let staging_buf_info = - BufferInfo::new_mappable(staging_buf_size as _, vk::BufferUsageFlags::TRANSFER_SRC); + BufferInfo::host_mem(staging_buf_size as _, vk::BufferUsageFlags::TRANSFER_SRC); let mut staging_buf = Buffer::create(device, staging_buf_info)?; let staging_data = Buffer::mapped_slice_mut(&mut staging_buf); @@ -751,10 +751,10 @@ fn load_texture( let texture = Arc::new(Image::create( device, - ImageInfo::new_2d( - fmt, + ImageInfo::image_2d( image.width(), image.height(), + fmt, vk::ImageUsageFlags::SAMPLED | vk::ImageUsageFlags::TRANSFER_DST, ), )?); diff --git a/examples/vsm_omni.rs b/examples/vsm_omni.rs index fa11e26..a30cba6 100644 --- a/examples/vsm_omni.rs +++ b/examples/vsm_omni.rs @@ -174,15 +174,16 @@ fn main() -> anyhow::Result<()> { // Lease and bind a cube-compatible shadow 2D image array to the graph of the current frame let shadow_faces_image = pool .lease( - ImageInfo::new_2d_array( - cubemap_format, + ImageInfo::image_2d_array( CUBEMAP_SIZE, CUBEMAP_SIZE, 6, + cubemap_format, vk::ImageUsageFlags::COLOR_ATTACHMENT | vk::ImageUsageFlags::SAMPLED | vk::ImageUsageFlags::STORAGE, ) + .to_builder() .flags(vk::ImageCreateFlags::CUBE_COMPATIBLE), ) .unwrap(); @@ -196,20 +197,20 @@ fn main() -> anyhow::Result<()> { // Lastly we lease and bind depth images needed for rendering let shadow_depth_image = frame.render_graph.bind_node( - pool.lease(ImageInfo::new_2d_array( - depth_format, + pool.lease(ImageInfo::image_2d_array( frame.width, frame.height, if use_geometry_shader { 6 } else { 1 }, + depth_format, vk::ImageUsageFlags::DEPTH_STENCIL_ATTACHMENT, )) .unwrap(), ); let depth_image = frame.render_graph.bind_node( - pool.lease(ImageInfo::new_2d( - depth_format, + pool.lease(ImageInfo::image_2d( frame.width, frame.height, + depth_format, vk::ImageUsageFlags::DEPTH_STENCIL_ATTACHMENT, )) .unwrap(), @@ -1149,11 +1150,11 @@ fn download_model_from_github(model_name: &str) -> anyhow::Result { } fn lease_uniform_buffer( - pool: &mut impl Pool, + pool: &mut impl Pool, data: &impl NoUninit, ) -> Result, DriverError> { let data = bytes_of(data); - let mut buf = pool.lease(BufferInfo::new_mappable( + let mut buf = pool.lease(BufferInfo::host_mem( data.len() as _, vk::BufferUsageFlags::UNIFORM_BUFFER, ))?; diff --git a/src/driver/accel_struct.rs b/src/driver/accel_struct.rs index 5e0242c..15c6266 100644 --- a/src/driver/accel_struct.rs +++ b/src/driver/accel_struct.rs @@ -40,7 +40,7 @@ use { /// # fn main() -> Result<(), DriverError> { /// # let device = Arc::new(Device::create_headless(DeviceInfo::new())?); /// # const SIZE: vk::DeviceSize = 1024; -/// # let info = AccelerationStructureInfo::new_blas(SIZE); +/// # let info = AccelerationStructureInfo::blas(SIZE); /// # let my_accel_struct = AccelerationStructure::create(&device, info)?; /// let addr = AccelerationStructure::device_address(&my_accel_struct); /// # Ok(()) } @@ -80,7 +80,7 @@ impl AccelerationStructure { /// # fn main() -> Result<(), DriverError> { /// # let device = Arc::new(Device::create_headless(DeviceInfo::new())?); /// const SIZE: vk::DeviceSize = 1024; - /// let info = AccelerationStructureInfo::new_blas(SIZE); + /// let info = AccelerationStructureInfo::blas(SIZE); /// let accel_struct = AccelerationStructure::create(&device, info)?; /// /// assert_ne!(*accel_struct, vk::AccelerationStructureKHR::null()); @@ -96,7 +96,7 @@ impl AccelerationStructure { let buffer = Buffer::create( device, - BufferInfo::new_mappable( + BufferInfo::host_mem( info.size, vk::BufferUsageFlags::ACCELERATION_STRUCTURE_STORAGE_KHR | vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS, @@ -158,7 +158,7 @@ impl AccelerationStructure { /// # fn main() -> Result<(), DriverError> { /// # let device = Arc::new(Device::create_headless(DeviceInfo::new())?); /// # const SIZE: vk::DeviceSize = 1024; - /// # let info = AccelerationStructureInfo::new_blas(SIZE); + /// # let info = AccelerationStructureInfo::blas(SIZE); /// # let my_accel_struct = AccelerationStructure::create(&device, info)?; /// // Initially we want to "Build Write" /// let next = AccessType::AccelerationStructureBuildWrite; @@ -201,7 +201,7 @@ impl AccelerationStructure { /// # fn main() -> Result<(), DriverError> { /// # let device = Arc::new(Device::create_headless(DeviceInfo::new())?); /// # const SIZE: vk::DeviceSize = 1024; - /// # let info = AccelerationStructureInfo::new_blas(SIZE); + /// # let info = AccelerationStructureInfo::blas(SIZE); /// # let my_accel_struct = AccelerationStructure::create(&device, info)?; /// let addr = AccelerationStructure::device_address(&my_accel_struct); /// @@ -608,16 +608,40 @@ pub enum AccelerationStructureGeometryData { #[non_exhaustive] pub struct AccelerationStructureInfo { /// Type of acceleration structure. + #[builder(default = "vk::AccelerationStructureTypeKHR::GENERIC")] pub ty: vk::AccelerationStructureTypeKHR, /// The size of the backing buffer that will store the acceleration structure. /// - /// Use [AccelerationStructure::size_of] to calculate this value. + /// Use [`AccelerationStructure::size_of`] to calculate this value. pub size: vk::DeviceSize, } impl AccelerationStructureInfo { - /// Specifies a bottom-level acceleration structure of the given size. + /// Specifies a [`vk::AccelerationStructureTypeKHR::BOTTOM_LEVEL`] acceleration structure of the + /// given size. + #[inline(always)] + pub const fn blas(size: vk::DeviceSize) -> Self { + Self { + ty: vk::AccelerationStructureTypeKHR::BOTTOM_LEVEL, + size, + } + } + + /// Specifies a [`vk::AccelerationStructureTypeKHR::GENERIC`] acceleration structure of the + /// given size. + #[inline(always)] + pub const fn generic(size: vk::DeviceSize) -> Self { + Self { + ty: vk::AccelerationStructureTypeKHR::GENERIC, + size, + } + } + + /// Specifies a [`vk::AccelerationStructureTypeKHR::BOTTOM_LEVEL`] acceleration structure of the + /// given size. + #[deprecated = "Use AccelerationStructureInfo::blas()"] + #[doc(hidden)] pub const fn new_blas(size: vk::DeviceSize) -> Self { Self { ty: vk::AccelerationStructureTypeKHR::BOTTOM_LEVEL, @@ -625,34 +649,64 @@ impl AccelerationStructureInfo { } } - /// Specifies a top-level acceleration structure of the given size. + /// Specifies a [`vk::AccelerationStructureTypeKHR::TOP_LEVEL`] acceleration structure of the + /// given size. + #[deprecated = "Use AccelerationStructureInfo::tlas()"] + #[doc(hidden)] pub const fn new_tlas(size: vk::DeviceSize) -> Self { Self { ty: vk::AccelerationStructureTypeKHR::TOP_LEVEL, size, } } + + /// Specifies a [`vk::AccelerationStructureTypeKHR::TOP_LEVEL`] acceleration structure of the + /// given size. + #[inline(always)] + pub const fn tlas(size: vk::DeviceSize) -> Self { + Self { + ty: vk::AccelerationStructureTypeKHR::TOP_LEVEL, + size, + } + } + + /// Converts an `AccelerationStructureInfo` into an `AccelerationStructureInfoBuilder`. + #[inline(always)] + pub fn to_builder(self) -> AccelerationStructureInfoBuilder { + AccelerationStructureInfoBuilder { + ty: Some(self.ty), + size: Some(self.size), + } + } } impl From for () { fn from(_: AccelerationStructureInfo) -> Self {} } -// HACK: https://github.com/colin-kiegel/rust-derive-builder/issues/56 impl AccelerationStructureInfoBuilder { /// Builds a new `AccelerationStructureInfo`. + /// + /// # Panics + /// + /// If any of the following values have not been set this function will panic: + /// + /// * `size` + #[inline(always)] pub fn build(self) -> AccelerationStructureInfo { - self.fallible_build() - .expect("All required fields set at initialization") + match self.fallible_build() { + Err(AccelerationStructureInfoBuilderError(err)) => panic!("{err}"), + Ok(info) => info, + } } } #[derive(Debug)] -struct AccelerationStructureInfoBuilderError; +struct AccelerationStructureInfoBuilderError(UninitializedFieldError); impl From for AccelerationStructureInfoBuilderError { - fn from(_: UninitializedFieldError) -> Self { - Self + fn from(err: UninitializedFieldError) -> Self { + Self(err) } } @@ -693,3 +747,33 @@ impl From for DeviceOrHostAddress { Self::DeviceAddress(device_addr) } } + +#[cfg(test)] +mod tests { + use super::*; + + type Info = AccelerationStructureInfo; + type Builder = AccelerationStructureInfoBuilder; + + #[test] + pub fn accel_struct_info() { + let info = Info::generic(0); + let builder = info.to_builder().build(); + + assert_eq!(info, builder); + } + + #[test] + pub fn accel_struct_info_builder() { + let info = Info::generic(0); + let builder = Builder::default().size(0).build(); + + assert_eq!(info, builder); + } + + #[test] + #[should_panic(expected = "Field not initialized: size")] + pub fn accel_struct_info_builder_uninit_size() { + Builder::default().build(); + } +} diff --git a/src/driver/buffer.rs b/src/driver/buffer.rs index fb91dc5..acce107 100644 --- a/src/driver/buffer.rs +++ b/src/driver/buffer.rs @@ -41,7 +41,7 @@ use { /// # use screen_13::driver::buffer::{Buffer, BufferInfo}; /// # fn main() -> Result<(), DriverError> { /// # let device = Arc::new(Device::create_headless(DeviceInfo::new())?); -/// # let info = BufferInfo::new(8, vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS); +/// # let info = BufferInfo::device_mem(8, vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS); /// # let my_buf = Buffer::create(&device, info)?; /// let addr = Buffer::device_address(&my_buf); /// # Ok(()) } @@ -80,7 +80,7 @@ impl Buffer { /// # fn main() -> Result<(), DriverError> { /// # let device = Arc::new(Device::create_headless(DeviceInfo::new())?); /// const SIZE: vk::DeviceSize = 1024; - /// let info = BufferInfo::new_mappable(SIZE, vk::BufferUsageFlags::UNIFORM_BUFFER); + /// let info = BufferInfo::host_mem(SIZE, vk::BufferUsageFlags::UNIFORM_BUFFER); /// let buf = Buffer::create(&device, info)?; /// /// assert_ne!(*buf, vk::Buffer::null()); @@ -188,7 +188,7 @@ impl Buffer { slice: impl AsRef<[u8]>, ) -> Result { let slice = slice.as_ref(); - let info = BufferInfo::new_mappable(slice.len() as _, usage); + let info = BufferInfo::host_mem(slice.len() as _, usage); let mut buffer = Self::create(device, info)?; Self::copy_from_slice(&mut buffer, 0, slice); @@ -219,7 +219,7 @@ impl Buffer { /// # fn main() -> Result<(), DriverError> { /// # let device = Arc::new(Device::create_headless(DeviceInfo::new())?); /// # const SIZE: vk::DeviceSize = 1024; - /// # let info = BufferInfo::new(SIZE, vk::BufferUsageFlags::STORAGE_BUFFER); + /// # let info = BufferInfo::device_mem(SIZE, vk::BufferUsageFlags::STORAGE_BUFFER); /// # let my_buf = Buffer::create(&device, info)?; /// // Initially we want to "Read Other" /// let next = AccessType::ComputeShaderReadOther; @@ -265,7 +265,7 @@ impl Buffer { /// # use screen_13::driver::buffer::{Buffer, BufferInfo}; /// # fn main() -> Result<(), DriverError> { /// # let device = Arc::new(Device::create_headless(DeviceInfo::new())?); - /// # let info = BufferInfo::new_mappable(4, vk::BufferUsageFlags::empty()); + /// # let info = BufferInfo::host_mem(4, vk::BufferUsageFlags::empty()); /// # let mut my_buf = Buffer::create(&device, info)?; /// const DATA: [u8; 4] = [0xde, 0xad, 0xc0, 0xde]; /// Buffer::copy_from_slice(&mut my_buf, 0, &DATA); @@ -298,7 +298,7 @@ impl Buffer { /// # use screen_13::driver::buffer::{Buffer, BufferInfo}; /// # fn main() -> Result<(), DriverError> { /// # let device = Arc::new(Device::create_headless(DeviceInfo::new())?); - /// # let info = BufferInfo::new_mappable(4, vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS); + /// # let info = BufferInfo::host_mem(4, vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS); /// # let my_buf = Buffer::create(&device, info)?; /// let addr = Buffer::device_address(&my_buf); /// @@ -450,7 +450,7 @@ pub struct BufferInfo { /// Byte alignment of the base device address of the buffer. /// /// Must be a power of two. - #[builder(default)] + #[builder(default = "1")] pub alignment: vk::DeviceSize, /// Specifies a buffer whose memory is host visible and may be mapped. @@ -458,7 +458,6 @@ pub struct BufferInfo { pub mappable: bool, /// Size in bytes of the buffer to be created. - #[builder(default)] pub size: vk::DeviceSize, /// A bitmask of specifying allowed usages of the buffer. @@ -467,10 +466,49 @@ pub struct BufferInfo { } impl BufferInfo { + /// Specifies a non-mappable buffer with the given `size` and `usage` values. + /// + /// Device-local memory (located on the GPU) is used. + #[inline(always)] + pub const fn device_mem(size: vk::DeviceSize, usage: vk::BufferUsageFlags) -> BufferInfo { + BufferInfo { + alignment: 1, + mappable: false, + size, + usage, + } + } + + /// Specifies a mappable buffer with the given `size` and `usage` values. + /// + /// Host-local memory (located in CPU-accesible RAM) is used. + /// + /// # Note + /// + /// For convenience the given usage value will be bitwise OR'd with + /// `TRANSFER_DST | TRANSFER_SRC`. + #[inline(always)] + pub const fn host_mem(size: vk::DeviceSize, usage: vk::BufferUsageFlags) -> BufferInfo { + let usage = vk::BufferUsageFlags::from_raw( + usage.as_raw() + | vk::BufferUsageFlags::TRANSFER_DST.as_raw() + | vk::BufferUsageFlags::TRANSFER_SRC.as_raw(), + ); + + BufferInfo { + alignment: 1, + mappable: true, + size, + usage, + } + } + /// Specifies a non-mappable buffer with the given `size` and `usage` values. #[allow(clippy::new_ret_no_self)] + #[deprecated = "Use BufferInfo::device_mem()"] + #[doc(hidden)] pub fn new(size: vk::DeviceSize, usage: vk::BufferUsageFlags) -> BufferInfoBuilder { - BufferInfoBuilder::default().size(size).usage(usage) + Self::device_mem(size, usage).to_builder() } /// Specifies a mappable buffer with the given `size` and `usage` values. @@ -479,21 +517,48 @@ impl BufferInfo { /// /// For convenience the given usage value will be bitwise OR'd with /// `TRANSFER_DST | TRANSFER_SRC`. + #[deprecated = "Use BufferInfo::host_mem()"] + #[doc(hidden)] pub fn new_mappable(size: vk::DeviceSize, usage: vk::BufferUsageFlags) -> BufferInfoBuilder { - Self::new( - size, - usage | vk::BufferUsageFlags::TRANSFER_DST | vk::BufferUsageFlags::TRANSFER_SRC, - ) - .mappable(true) + Self::host_mem(size, usage).to_builder() + } + + /// Converts a `BufferInfo` into a `BufferInfoBuilder`. + #[inline(always)] + pub fn to_builder(self) -> BufferInfoBuilder { + BufferInfoBuilder { + alignment: Some(self.alignment), + mappable: Some(self.mappable), + size: Some(self.size), + usage: Some(self.usage), + } } } -// HACK: https://github.com/colin-kiegel/rust-derive-builder/issues/56 impl BufferInfoBuilder { /// Builds a new `BufferInfo`. + /// + /// # Panics + /// + /// If any of the following values have not been set this function will panic: + /// + /// * `size` + /// + /// If `alignment` is not a power to two this function will panic. + #[inline(always)] pub fn build(self) -> BufferInfo { - self.fallible_build() - .expect("All required fields set at initialization") + let res = match self.fallible_build() { + Err(BufferInfoBuilderError(err)) => panic!("{err}"), + Ok(info) => info, + }; + + assert_eq!( + res.alignment.count_ones(), + 1, + "Alignment must be a power of two" + ); + + res } } @@ -504,11 +569,11 @@ impl From for BufferInfo { } #[derive(Debug)] -struct BufferInfoBuilderError; +struct BufferInfoBuilderError(UninitializedFieldError); impl From for BufferInfoBuilderError { - fn from(_: UninitializedFieldError) -> Self { - Self + fn from(err: UninitializedFieldError) -> Self { + Self(err) } } @@ -551,3 +616,62 @@ impl From for Range { subresource.start..subresource.end } } + +#[cfg(test)] +mod tests { + use super::*; + + type Info = BufferInfo; + type Builder = BufferInfoBuilder; + + #[test] + pub fn buffer_info() { + let info = Info::device_mem(0, vk::BufferUsageFlags::empty()); + let builder = info.to_builder().build(); + + assert_eq!(info, builder); + } + + #[test] + pub fn buffer_info_alignment() { + let info = Info::device_mem(0, vk::BufferUsageFlags::empty()); + + assert_eq!(info.alignment, 1); + } + + #[test] + pub fn buffer_info_builder() { + let info = Info::device_mem(0, vk::BufferUsageFlags::empty()); + let builder = Builder::default().size(0).build(); + + assert_eq!(info, builder); + } + + #[test] + #[should_panic(expected = "Alignment must be a power of two")] + pub fn buffer_info_builder_alignment_0() { + Builder::default().size(0).alignment(0).build(); + } + + #[test] + #[should_panic(expected = "Alignment must be a power of two")] + pub fn buffer_info_builder_alignment_42() { + Builder::default().size(0).alignment(42).build(); + } + + #[test] + pub fn buffer_info_builder_alignment_256() { + let mut info = Info::device_mem(42, vk::BufferUsageFlags::empty()); + info.alignment = 256; + + let builder = Builder::default().size(42).alignment(256).build(); + + assert_eq!(info, builder); + } + + #[test] + #[should_panic(expected = "Field not initialized: size")] + pub fn buffer_info_builder_uninit_size() { + Builder::default().build(); + } +} diff --git a/src/driver/compute.rs b/src/driver/compute.rs index 120867b..c2bb079 100644 --- a/src/driver/compute.rs +++ b/src/driver/compute.rs @@ -33,6 +33,9 @@ pub struct ComputePipeline { /// Information used to create this object. pub info: ComputePipelineInfo, + /// A descriptive name used in debugging messages. + pub name: Option, + pipeline: vk::Pipeline, pub(crate) push_constants: Option, } @@ -161,11 +164,18 @@ impl ComputePipeline { device, info, layout, + name: None, pipeline, push_constants, }) } } + + /// Sets the debugging name assigned to this pipeline. + pub fn with_name(mut this: Self, name: impl Into) -> Self { + this.name = Some(name.into()); + this + } } impl Deref for ComputePipeline { @@ -191,14 +201,14 @@ impl Drop for ComputePipeline { } /// Information used to create a [`ComputePipeline`] instance. -#[derive(Builder, Clone, Debug, Default)] +#[derive(Builder, Clone, Copy, Debug, Eq, Hash, PartialEq)] #[builder( build_fn( private, name = "fallible_build", error = "ComputePipelineInfoBuilderError" ), - derive(Clone, Debug), + derive(Clone, Copy, Debug), pattern = "owned" )] #[non_exhaustive] @@ -227,10 +237,24 @@ pub struct ComputePipelineInfo { /// ``` #[builder(default = "8192")] pub bindless_descriptor_count: u32, +} - /// A descriptive name used in debugging messages. - #[builder(default, setter(strip_option))] - pub name: Option, +impl ComputePipelineInfo { + /// Converts a `ComputePipelineInfo` into a `ComputePipelineInfoBuilder`. + #[inline(always)] + pub fn to_builder(self) -> ComputePipelineInfoBuilder { + ComputePipelineInfoBuilder { + bindless_descriptor_count: Some(self.bindless_descriptor_count), + } + } +} + +impl Default for ComputePipelineInfo { + fn default() -> Self { + Self { + bindless_descriptor_count: 8192, + } + } } impl From for ComputePipelineInfo { @@ -239,12 +263,19 @@ impl From for ComputePipelineInfo { } } -// HACK: https://github.com/colin-kiegel/rust-derive-builder/issues/56 impl ComputePipelineInfoBuilder { /// Builds a new `ComputePipelineInfo`. + #[inline(always)] pub fn build(self) -> ComputePipelineInfo { - self.fallible_build() - .expect("All required fields set at initialization") + let res = self.fallible_build(); + + #[cfg(test)] + let res = res.unwrap(); + + #[cfg(not(test))] + let res = unsafe { res.unwrap_unchecked() }; + + res } } @@ -256,3 +287,27 @@ impl From for ComputePipelineInfoBuilderError { Self } } + +#[cfg(test)] +mod tests { + use super::*; + + type Info = ComputePipelineInfo; + type Builder = ComputePipelineInfoBuilder; + + #[test] + pub fn compute_pipeline_info() { + let info = Info::default(); + let builder = info.to_builder().build(); + + assert_eq!(info, builder); + } + + #[test] + pub fn compute_pipeline_info_builder() { + let info = Info::default(); + let builder = Builder::default().build(); + + assert_eq!(info, builder); + } +} diff --git a/src/driver/device.rs b/src/driver/device.rs index a3645b6..4dc5430 100644 --- a/src/driver/device.rs +++ b/src/driver/device.rs @@ -484,6 +484,8 @@ pub struct DeviceInfo { impl DeviceInfo { /// Specifies default device information. #[allow(clippy::new_ret_no_self)] + #[deprecated = "Use DeviceInfo::default()"] + #[doc(hidden)] pub fn new() -> DeviceInfoBuilder { Default::default() } @@ -569,11 +571,23 @@ impl DeviceInfo { idx } + + /// Converts a `DeviceInfo` into a `DeviceInfoBuilder`. + #[inline(always)] + pub fn to_builder(self) -> DeviceInfoBuilder { + DeviceInfoBuilder { + debug: Some(self.debug), + select_physical_device: Some(self.select_physical_device), + } + } } impl Default for DeviceInfo { fn default() -> Self { - Self::new().build() + Self { + debug: false, + select_physical_device: Box::new(DeviceInfo::discrete_gpu), + } } } @@ -583,11 +597,19 @@ impl From for DeviceInfo { } } -// HACK: https://github.com/colin-kiegel/rust-derive-builder/issues/56 impl DeviceInfoBuilder { /// Builds a new `DeviceInfo`. + #[inline(always)] pub fn build(self) -> DeviceInfo { - self.fallible_build().unwrap() + let res = self.fallible_build(); + + #[cfg(test)] + let res = res.unwrap(); + + #[cfg(not(test))] + let res = unsafe { res.unwrap_unchecked() }; + + res } } @@ -599,3 +621,21 @@ impl From for DeviceInfoBuilderError { Self } } + +#[cfg(test)] +mod tests { + use super::*; + + type Info = DeviceInfo; + type Builder = DeviceInfoBuilder; + + #[test] + pub fn device_info() { + Info::default().to_builder().build(); + } + + #[test] + pub fn device_info_builder() { + Builder::default().build(); + } +} diff --git a/src/driver/graphic.rs b/src/driver/graphic.rs index 23e280b..ba258a7 100644 --- a/src/driver/graphic.rs +++ b/src/driver/graphic.rs @@ -358,6 +358,10 @@ pub struct GraphicPipeline { pub(crate) input_attachments: HashSet, pub(crate) layout: vk::PipelineLayout, + + /// A descriptive name used in debugging messages. + pub name: Option, + pub(crate) push_constants: Vec, pub(crate) shader_modules: Vec, pub(super) state: GraphicPipelineState, @@ -552,6 +556,7 @@ impl GraphicPipeline { info, input_attachments, layout, + name: None, push_constants, shader_modules, state: GraphicPipelineState { @@ -564,6 +569,12 @@ impl GraphicPipeline { }) } } + + /// Sets the debugging name assigned to this pipeline. + pub fn with_name(mut this: Self, name: impl Into) -> Self { + this.name = Some(name.into()); + this + } } impl Drop for GraphicPipeline { @@ -586,25 +597,18 @@ impl Drop for GraphicPipeline { } /// Information used to create a [`GraphicPipeline`] instance. -#[derive(Builder, Clone, Debug, Eq, Hash, PartialEq)] +#[derive(Builder, Clone, Copy, Debug, Eq, Hash, PartialEq)] #[builder( build_fn( private, name = "fallible_build", error = "GraphicPipelineInfoBuilderError" ), - derive(Clone, Debug), + derive(Clone, Copy, Debug), pattern = "owned" )] #[non_exhaustive] pub struct GraphicPipelineInfo { - /// Specifies color blend state used when rasterization is enabled for any color attachments - /// accessed during rendering. - /// - /// The default value is [`BlendMode::REPLACE`]. - #[builder(default)] - pub blend: BlendMode, - /// The number of descriptors to allocate for a given binding when using bindless (unbounded) /// syntax. /// @@ -630,6 +634,13 @@ pub struct GraphicPipelineInfo { #[builder(default = "8192")] pub bindless_descriptor_count: u32, + /// Specifies color blend state used when rasterization is enabled for any color attachments + /// accessed during rendering. + /// + /// The default value is [`BlendMode::REPLACE`]. + #[builder(default)] + pub blend: BlendMode, + /// Bitmask controlling triangle culling. /// /// The default value is `vk::CullModeFlags::BACK`. @@ -642,10 +653,6 @@ pub struct GraphicPipelineInfo { #[builder(default = "vk::FrontFace::COUNTER_CLOCKWISE")] pub front_face: vk::FrontFace, - /// A descriptive name used in debugging messages. - #[builder(default, setter(strip_option))] - pub name: Option, - /// Control polygon rasterization mode. /// /// The default value is `vk::PolygonMode::FILL`. @@ -668,16 +675,40 @@ pub struct GraphicPipelineInfo { } impl GraphicPipelineInfo { - /// Specifies a graphic pipeline. + /// Creates a default `GraphicPipelineInfoBuilder`. #[allow(clippy::new_ret_no_self)] + #[deprecated = "Use GraphicPipelineInfo::default()"] + #[doc(hidden)] pub fn new() -> GraphicPipelineInfoBuilder { - GraphicPipelineInfoBuilder::default() + Default::default() + } + + /// Converts a `GraphicPipelineInfo` into a `GraphicPipelineInfoBuilder`. + #[inline(always)] + pub fn to_builder(self) -> GraphicPipelineInfoBuilder { + GraphicPipelineInfoBuilder { + bindless_descriptor_count: Some(self.bindless_descriptor_count), + blend: Some(self.blend), + cull_mode: Some(self.cull_mode), + front_face: Some(self.front_face), + polygon_mode: Some(self.polygon_mode), + topology: Some(self.topology), + samples: Some(self.samples), + } } } impl Default for GraphicPipelineInfo { fn default() -> Self { - Self::new().build() + Self { + bindless_descriptor_count: 8192, + blend: BlendMode::REPLACE, + cull_mode: vk::CullModeFlags::BACK, + front_face: vk::FrontFace::COUNTER_CLOCKWISE, + polygon_mode: vk::PolygonMode::FILL, + topology: vk::PrimitiveTopology::TRIANGLE_LIST, + samples: SampleCount::X1, + } } } @@ -687,12 +718,19 @@ impl From for GraphicPipelineInfo { } } -// HACK: https://github.com/colin-kiegel/rust-derive-builder/issues/56 impl GraphicPipelineInfoBuilder { /// Builds a new `GraphicPipelineInfo`. + #[inline(always)] pub fn build(self) -> GraphicPipelineInfo { - self.fallible_build() - .expect("All required fields set at initialization") + let res = self.fallible_build(); + + #[cfg(test)] + let res = res.unwrap(); + + #[cfg(not(test))] + let res = unsafe { res.unwrap_unchecked() }; + + res } } @@ -797,3 +835,27 @@ pub(super) struct VertexInputState { pub vertex_binding_descriptions: Vec, pub vertex_attribute_descriptions: Vec, } + +#[cfg(test)] +mod tests { + use super::*; + + type Info = GraphicPipelineInfo; + type Builder = GraphicPipelineInfoBuilder; + + #[test] + pub fn graphic_pipeline_info() { + let info = Info::default(); + let builder = info.to_builder().build(); + + assert_eq!(info, builder); + } + + #[test] + pub fn graphic_pipeline_info_builder() { + let info = Info::default(); + let builder = Builder::default().build(); + + assert_eq!(info, builder); + } +} diff --git a/src/driver/image.rs b/src/driver/image.rs index 486df78..50e26d6 100644 --- a/src/driver/image.rs +++ b/src/driver/image.rs @@ -46,7 +46,7 @@ use { /// # use screen_13::driver::image::{Image, ImageInfo}; /// # fn main() -> Result<(), DriverError> { /// # let device = Arc::new(Device::create_headless(DeviceInfo::new())?); -/// # let info = ImageInfo::new_1d(vk::Format::R8_UINT, 1, vk::ImageUsageFlags::STORAGE); +/// # let info = ImageInfo::image_1d(1, vk::Format::R8_UINT, vk::ImageUsageFlags::STORAGE); /// # let my_image = Image::create(&device, info)?; /// let prev = Image::access(&my_image, AccessType::AnyShaderWrite); /// # Ok(()) } @@ -85,8 +85,8 @@ impl Image { /// # use screen_13::driver::device::{Device, DeviceInfo}; /// # use screen_13::driver::image::{Image, ImageInfo}; /// # fn main() -> Result<(), DriverError> { - /// # let device = Arc::new(Device::create_headless(DeviceInfo::new())?); - /// let info = ImageInfo::new_2d(vk::Format::R8G8B8A8_UNORM, 32, 32, vk::ImageUsageFlags::SAMPLED); + /// # let device = Arc::new(Device::create_headless(DeviceInfo::default())?); + /// let info = ImageInfo::image_2d(32, 32, vk::Format::R8G8B8A8_UNORM, vk::ImageUsageFlags::SAMPLED); /// let image = Image::create(&device, info)?; /// /// assert_ne!(*image, vk::Image::null()); @@ -184,7 +184,7 @@ impl Image { /// # use screen_13::driver::image::{Image, ImageInfo}; /// # fn main() -> Result<(), DriverError> { /// # let device = Arc::new(Device::create_headless(DeviceInfo::new())?); - /// # let info = ImageInfo::new_1d(vk::Format::R8_UINT, 1, vk::ImageUsageFlags::STORAGE); + /// # let info = ImageInfo::image_1d(1, vk::Format::R8_UINT, vk::ImageUsageFlags::STORAGE); /// # let my_image = Image::create(&device, info)?; /// // Initially we want to "Read Other" /// let next = AccessType::AnyShaderReadOther; @@ -384,79 +384,136 @@ pub struct ImageInfo { } impl ImageInfo { - #[allow(clippy::new_ret_no_self)] - const fn new( + /// Specifies a cube image. + #[inline(always)] + pub const fn cube(size: u32, fmt: vk::Format, usage: vk::ImageUsageFlags) -> ImageInfo { + Self::new(ImageType::Cube, size, size, 1, 1, fmt, usage) + } + + /// Specifies a one-dimensional image. + #[inline(always)] + pub const fn image_1d(size: u32, fmt: vk::Format, usage: vk::ImageUsageFlags) -> ImageInfo { + Self::new(ImageType::Texture1D, size, 1, 1, 1, fmt, usage) + } + + /// Specifies a two-dimensional image. + #[inline(always)] + pub const fn image_2d( + width: u32, + height: u32, fmt: vk::Format, + usage: vk::ImageUsageFlags, + ) -> ImageInfo { + Self::new(ImageType::Texture2D, width, height, 1, 1, fmt, usage) + } + + /// Specifies a two-dimensional image array. + #[inline(always)] + pub const fn image_2d_array( + width: u32, + height: u32, + array_elements: u32, + fmt: vk::Format, + usage: vk::ImageUsageFlags, + ) -> ImageInfo { + Self::new( + ImageType::TextureArray2D, + width, + height, + 1, + array_elements, + fmt, + usage, + ) + } + + /// Specifies a three-dimensional image. + #[inline(always)] + pub const fn image_3d( + width: u32, + height: u32, + depth: u32, + fmt: vk::Format, + usage: vk::ImageUsageFlags, + ) -> ImageInfo { + Self::new(ImageType::Texture3D, width, height, depth, 1, fmt, usage) + } + + #[inline(always)] + const fn new( ty: ImageType, width: u32, height: u32, depth: u32, array_elements: u32, + fmt: vk::Format, usage: vk::ImageUsageFlags, - ) -> ImageInfoBuilder { - ImageInfoBuilder { - ty: Some(ty), - fmt: Some(fmt), - width: Some(width), - height: Some(height), - depth: Some(depth), - usage: Some(usage), - flags: None, - tiling: None, - mip_level_count: None, - array_elements: Some(array_elements), - sample_count: None, + ) -> Self { + Self { + ty, + width, + height, + depth, + array_elements, + fmt, + usage, + flags: vk::ImageCreateFlags::empty(), + tiling: vk::ImageTiling::OPTIMAL, + mip_level_count: 1, + sample_count: SampleCount::X1, } } /// Specifies a one-dimensional image. - pub const fn new_1d(fmt: vk::Format, len: u32, usage: vk::ImageUsageFlags) -> ImageInfoBuilder { - Self::new(fmt, ImageType::Texture1D, len, 1, 1, 1, usage) + #[deprecated = "Use ImageInfo::image_1d()"] + #[doc(hidden)] + pub fn new_1d(fmt: vk::Format, size: u32, usage: vk::ImageUsageFlags) -> ImageInfoBuilder { + Self::image_1d(size, fmt, usage).to_builder() } /// Specifies a two-dimensional image. - pub const fn new_2d( + #[deprecated = "Use ImageInfo::image_2d()"] + #[doc(hidden)] + pub fn new_2d( fmt: vk::Format, width: u32, height: u32, usage: vk::ImageUsageFlags, ) -> ImageInfoBuilder { - Self::new(fmt, ImageType::Texture2D, width, height, 1, 1, usage) + Self::image_2d(width, height, fmt, usage).to_builder() } /// Specifies a two-dimensional image array. - pub const fn new_2d_array( + #[deprecated = "Use ImageInfo::image_2d_array()"] + #[doc(hidden)] + pub fn new_2d_array( fmt: vk::Format, width: u32, height: u32, array_elements: u32, usage: vk::ImageUsageFlags, ) -> ImageInfoBuilder { - Self::new( - fmt, - ImageType::TextureArray2D, - width, - height, - 1, - array_elements, - usage, - ) + Self::image_2d_array(width, height, array_elements, fmt, usage).to_builder() } /// Specifies a three-dimensional image. - pub const fn new_3d( + #[deprecated = "Use ImageInfo::image_3d()"] + #[doc(hidden)] + pub fn new_3d( fmt: vk::Format, width: u32, height: u32, depth: u32, usage: vk::ImageUsageFlags, ) -> ImageInfoBuilder { - Self::new(fmt, ImageType::Texture3D, width, height, depth, 1, usage) + Self::image_3d(width, height, depth, fmt, usage).to_builder() } /// Specifies a cube image. - pub fn new_cube(fmt: vk::Format, width: u32, usage: vk::ImageUsageFlags) -> ImageInfoBuilder { - Self::new(fmt, ImageType::Cube, width, width, 1, 1, usage) + #[deprecated = "Use ImageInfo::cube()"] + #[doc(hidden)] + pub fn new_cube(fmt: vk::Format, size: u32, usage: vk::ImageUsageFlags) -> ImageInfoBuilder { + Self::cube(size, fmt, usage).to_builder() } /// Provides an `ImageViewInfo` for this format, type, aspect, array elements, and mip levels. @@ -548,6 +605,24 @@ impl ImageInfo { .sharing_mode(vk::SharingMode::CONCURRENT) .initial_layout(vk::ImageLayout::UNDEFINED) } + + /// Converts an `ImageInfo` into an `ImageInfoBuilder`. + #[inline(always)] + pub fn to_builder(self) -> ImageInfoBuilder { + ImageInfoBuilder { + array_elements: Some(self.array_elements), + depth: Some(self.depth), + flags: Some(self.flags), + fmt: Some(self.fmt), + height: Some(self.height), + mip_level_count: Some(self.mip_level_count), + sample_count: Some(self.sample_count), + tiling: Some(self.tiling), + ty: Some(self.ty), + usage: Some(self.usage), + width: Some(self.width), + } + } } impl From for ImageInfo { @@ -556,21 +631,33 @@ impl From for ImageInfo { } } -// HACK: https://github.com/colin-kiegel/rust-derive-builder/issues/56 impl ImageInfoBuilder { /// Builds a new `ImageInfo`. + /// + /// # Panics + /// + /// If any of the following functions have not been called this function will panic: + /// + /// * `ty` + /// * `fmt` + /// * `width` + /// * `height` + /// * `depth` + #[inline(always)] pub fn build(self) -> ImageInfo { - self.fallible_build() - .expect("All required fields set at initialization") + match self.fallible_build() { + Err(ImageInfoBuilderError(err)) => panic!("{err}"), + Ok(info) => info, + } } } #[derive(Debug)] -struct ImageInfoBuilderError; +struct ImageInfoBuilderError(UninitializedFieldError); impl From for ImageInfoBuilderError { - fn from(_: UninitializedFieldError) -> Self { - Self + fn from(err: UninitializedFieldError) -> Self { + Self(err) } } @@ -769,15 +856,40 @@ pub struct ImageViewInfo { impl ImageViewInfo { /// Specifies a default view with the given `fmt` and `ty` values. - #[allow(clippy::new_ret_no_self)] - pub fn new(format: vk::Format, ty: ImageType) -> ImageViewInfoBuilder { - ImageViewInfoBuilder::new(format, ty).aspect_mask(format_aspect_mask(format)) + /// + /// # Note + /// + /// Automatically sets [`aspect_mask`](Self::aspect_mask) to a suggested value. + #[inline(always)] + pub const fn new(fmt: vk::Format, ty: ImageType) -> ImageViewInfo { + Self { + array_layer_count: None, + aspect_mask: format_aspect_mask(fmt), + base_array_layer: 0, + base_mip_level: 0, + fmt, + mip_level_count: None, + ty, + } + } + + /// Converts a `ImageViewInfo` into a `ImageViewInfoBuilder`. + #[inline(always)] + pub fn to_builder(self) -> ImageViewInfoBuilder { + ImageViewInfoBuilder { + array_layer_count: Some(self.array_layer_count), + aspect_mask: Some(self.aspect_mask), + base_array_layer: Some(self.base_array_layer), + base_mip_level: Some(self.base_mip_level), + fmt: Some(self.fmt), + mip_level_count: Some(self.mip_level_count), + ty: Some(self.ty), + } } /// Takes this instance and returns it with a newly specified `ImageType`. pub fn with_ty(mut self, ty: ImageType) -> Self { self.ty = ty; - self } } @@ -802,26 +914,38 @@ impl From for ImageViewInfo { } } -// HACK: https://github.com/colin-kiegel/rust-derive-builder/issues/56 impl ImageViewInfoBuilder { /// Specifies a default view with the given `fmt` and `ty` values. + #[deprecated = "Use ImageViewInfo::new()"] + #[doc(hidden)] pub fn new(fmt: vk::Format, ty: ImageType) -> Self { Self::default().fmt(fmt).ty(ty) } /// Builds a new 'ImageViewInfo'. + /// + /// # Panics + /// + /// If any of the following values have not been set this function will panic: + /// + /// * `ty` + /// * `fmt` + /// * `aspect_mask` + #[inline(always)] pub fn build(self) -> ImageViewInfo { - self.fallible_build() - .expect("All required fields set at initialization") + match self.fallible_build() { + Err(ImageViewInfoBuilderError(err)) => panic!("{err}"), + Ok(info) => info, + } } } #[derive(Debug)] -struct ImageViewInfoBuilderError; +struct ImageViewInfoBuilderError(UninitializedFieldError); impl From for ImageViewInfoBuilderError { - fn from(_: UninitializedFieldError) -> Self { - Self + fn from(err: UninitializedFieldError) -> Self { + Self(err) } } @@ -871,3 +995,230 @@ impl Default for SampleCount { Self::X1 } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + pub fn image_info_cube() { + let info = ImageInfo::cube(42, vk::Format::R32_SFLOAT, vk::ImageUsageFlags::empty()); + let builder = info.to_builder().build(); + + assert_eq!(info, builder); + } + + #[test] + pub fn image_info_cube_builder() { + let info = ImageInfo::cube(42, vk::Format::R32_SFLOAT, vk::ImageUsageFlags::empty()); + let builder = ImageInfoBuilder::default() + .ty(ImageType::Cube) + .fmt(vk::Format::R32_SFLOAT) + .width(42) + .height(42) + .depth(1) + .build(); + + assert_eq!(info, builder); + } + + #[test] + pub fn image_info_image_1d() { + let info = ImageInfo::image_1d(42, vk::Format::R32_SFLOAT, vk::ImageUsageFlags::empty()); + let builder = info.to_builder().build(); + + assert_eq!(info, builder); + } + + #[test] + pub fn image_info_image_1d_builder() { + let info = ImageInfo::image_1d(42, vk::Format::R32_SFLOAT, vk::ImageUsageFlags::empty()); + let builder = ImageInfoBuilder::default() + .ty(ImageType::Texture1D) + .fmt(vk::Format::R32_SFLOAT) + .width(42) + .height(1) + .depth(1) + .build(); + + assert_eq!(info, builder); + } + + #[test] + pub fn image_info_image_2d() { + let info = + ImageInfo::image_2d(42, 84, vk::Format::R32_SFLOAT, vk::ImageUsageFlags::empty()); + let builder = info.to_builder().build(); + + assert_eq!(info, builder); + } + + #[test] + pub fn image_info_image_2d_builder() { + let info = + ImageInfo::image_2d(42, 84, vk::Format::R32_SFLOAT, vk::ImageUsageFlags::empty()); + let builder = ImageInfoBuilder::default() + .ty(ImageType::Texture2D) + .fmt(vk::Format::R32_SFLOAT) + .width(42) + .height(84) + .depth(1) + .build(); + + assert_eq!(info, builder); + } + + #[test] + pub fn image_info_image_2d_array() { + let info = ImageInfo::image_2d_array( + 42, + 84, + 100, + vk::Format::default(), + vk::ImageUsageFlags::empty(), + ); + let builder = info.to_builder().build(); + + assert_eq!(info, builder); + } + + #[test] + pub fn image_info_image_2d_array_builder() { + let info = ImageInfo::image_2d_array( + 42, + 84, + 100, + vk::Format::R32_SFLOAT, + vk::ImageUsageFlags::empty(), + ); + let builder = ImageInfoBuilder::default() + .ty(ImageType::TextureArray2D) + .fmt(vk::Format::R32_SFLOAT) + .width(42) + .height(84) + .depth(1) + .array_elements(100) + .build(); + + assert_eq!(info, builder); + } + + #[test] + pub fn image_info_image_3d() { + let info = ImageInfo::image_3d( + 42, + 84, + 100, + vk::Format::R32_SFLOAT, + vk::ImageUsageFlags::empty(), + ); + let builder = info.to_builder().build(); + + assert_eq!(info, builder); + } + + #[test] + pub fn image_info_image_3d_builder() { + let info = ImageInfo::image_3d( + 42, + 84, + 100, + vk::Format::R32_SFLOAT, + vk::ImageUsageFlags::empty(), + ); + let builder = ImageInfoBuilder::default() + .ty(ImageType::Texture3D) + .fmt(vk::Format::R32_SFLOAT) + .width(42) + .height(84) + .depth(100) + .build(); + + assert_eq!(info, builder); + } + + #[test] + #[should_panic(expected = "Field not initialized: depth")] + pub fn image_info_builder_uninit_depth() { + ImageInfoBuilder::default().build(); + } + + #[test] + #[should_panic(expected = "Field not initialized: fmt")] + pub fn image_info_builder_uninit_fmt() { + ImageInfoBuilder::default().depth(1).build(); + } + + #[test] + #[should_panic(expected = "Field not initialized: height")] + pub fn image_info_builder_uninit_height() { + ImageInfoBuilder::default() + .depth(1) + .fmt(vk::Format::default()) + .build(); + } + + #[test] + #[should_panic(expected = "Field not initialized: ty")] + pub fn image_info_builder_uninit_ty() { + ImageInfoBuilder::default() + .depth(1) + .fmt(vk::Format::default()) + .height(2) + .build(); + } + + #[test] + #[should_panic(expected = "Field not initialized: width")] + pub fn image_info_builder_uninit_width() { + ImageInfoBuilder::default() + .depth(1) + .fmt(vk::Format::default()) + .height(2) + .ty(ImageType::Texture2D) + .build(); + } + + #[test] + pub fn image_view_info() { + let info = ImageViewInfo::new(vk::Format::default(), ImageType::Texture1D); + let builder = info.to_builder().build(); + + assert_eq!(info, builder); + } + + #[test] + pub fn image_view_info_builder() { + let info = ImageViewInfo::new(vk::Format::default(), ImageType::Texture1D); + let builder = ImageViewInfoBuilder::default() + .fmt(vk::Format::default()) + .ty(ImageType::Texture1D) + .aspect_mask(vk::ImageAspectFlags::COLOR) + .build(); + + assert_eq!(info, builder); + } + + #[test] + #[should_panic(expected = "Field not initialized: aspect_mask")] + pub fn image_view_info_builder_uninit_aspect_mask() { + ImageViewInfoBuilder::default().build(); + } + + #[test] + #[should_panic(expected = "Field not initialized: fmt")] + pub fn image_view_info_builder_unint_fmt() { + ImageViewInfoBuilder::default() + .aspect_mask(vk::ImageAspectFlags::empty()) + .build(); + } + + #[test] + #[should_panic(expected = "Field not initialized: ty")] + pub fn image_view_info_builder_unint_ty() { + ImageViewInfoBuilder::default() + .aspect_mask(vk::ImageAspectFlags::empty()) + .fmt(vk::Format::default()) + .build(); + } +} diff --git a/src/driver/ray_trace.rs b/src/driver/ray_trace.rs index 49d122f..1f57f83 100644 --- a/src/driver/ray_trace.rs +++ b/src/driver/ray_trace.rs @@ -38,6 +38,10 @@ pub struct RayTracePipeline { pub info: RayTracePipelineInfo, pub(crate) layout: vk::PipelineLayout, + + /// A descriptive name used in debugging messages. + pub name: Option, + pub(crate) push_constants: Vec, pipeline: vk::Pipeline, shader_modules: Vec, @@ -296,6 +300,7 @@ impl RayTracePipeline { device, info, layout, + name: None, push_constants, pipeline, shader_modules, @@ -347,6 +352,12 @@ impl RayTracePipeline { .get_ray_tracing_shader_group_stack_size(this.pipeline, group, group_shader) } } + + /// Sets the debugging name assigned to this pipeline. + pub fn with_name(mut this: Self, name: impl Into) -> Self { + this.name = Some(name.into()); + this + } } impl Deref for RayTracePipeline { @@ -378,14 +389,14 @@ impl Drop for RayTracePipeline { } /// Information used to create a [`RayTracePipeline`] instance. -#[derive(Builder, Clone, Debug, Eq, Hash, PartialEq)] +#[derive(Builder, Clone, Copy, Debug, Eq, Hash, PartialEq)] #[builder( build_fn( private, name = "fallible_build", error = "RayTracePipelineInfoBuilderError" ), - derive(Clone, Debug), + derive(Clone, Copy, Debug), pattern = "owned" )] #[non_exhaustive] @@ -431,23 +442,35 @@ pub struct RayTracePipelineInfo { /// [maximum recursion depth]: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#ray-tracing-recursion-depth #[builder(default = "16")] pub max_ray_recursion_depth: u32, - - /// A descriptive name used in debugging messages. - #[builder(default, setter(strip_option))] - pub name: Option, } impl RayTracePipelineInfo { - /// Specifies a ray trace pipeline. + /// Creates a default `RayTracePipelineInfoBuilder`. #[allow(clippy::new_ret_no_self)] + #[deprecated = "Use RayTracePipelineInfo::default()"] + #[doc(hidden)] pub fn new() -> RayTracePipelineInfoBuilder { Default::default() } + + /// Converts a `RayTracePipelineInfo` into a `RayTracePipelineInfoBuilder`. + #[inline(always)] + pub fn to_builder(self) -> RayTracePipelineInfoBuilder { + RayTracePipelineInfoBuilder { + bindless_descriptor_count: Some(self.bindless_descriptor_count), + dynamic_stack_size: Some(self.dynamic_stack_size), + max_ray_recursion_depth: Some(self.max_ray_recursion_depth), + } + } } impl Default for RayTracePipelineInfo { fn default() -> Self { - RayTracePipelineInfoBuilder::default().build() + Self { + bindless_descriptor_count: 8192, + dynamic_stack_size: false, + max_ray_recursion_depth: 16, + } } } @@ -457,12 +480,19 @@ impl From for RayTracePipelineInfo { } } -// HACK: https://github.com/colin-kiegel/rust-derive-builder/issues/56 impl RayTracePipelineInfoBuilder { /// Builds a new `RayTracePipelineInfo`. + #[inline(always)] pub fn build(self) -> RayTracePipelineInfo { - self.fallible_build() - .expect("All required fields set at initialization") + let res = self.fallible_build(); + + #[cfg(test)] + let res = res.unwrap(); + + #[cfg(not(test))] + let res = unsafe { res.unwrap_unchecked() }; + + res } } @@ -613,3 +643,27 @@ impl From for vk::RayTracingShaderGroupTypeKHR { } } } + +#[cfg(test)] +mod tests { + use super::*; + + type Info = RayTracePipelineInfo; + type Builder = RayTracePipelineInfoBuilder; + + #[test] + pub fn ray_trace_pipeline_info() { + let info = Info::default(); + let builder = info.to_builder().build(); + + assert_eq!(info, builder); + } + + #[test] + pub fn ray_trace_pipeline_info_builder() { + let info = Info::default(); + let builder = Builder::default().build(); + + assert_eq!(info, builder); + } +} diff --git a/src/driver/shader.rs b/src/driver/shader.rs index fb6044c..f1f2408 100644 --- a/src/driver/shader.rs +++ b/src/driver/shader.rs @@ -63,7 +63,7 @@ fn guess_immutable_sampler(binding_name: &str) -> SamplerInfo { ) }; let anisotropy_enable = texel_filter == vk::Filter::LINEAR; - let mut info = SamplerInfo::new() + let mut info = SamplerInfoBuilder::default() .mag_filter(texel_filter) .min_filter(texel_filter) .mipmap_mode(mipmap_mode) @@ -514,19 +514,76 @@ impl SamplerInfo { reduction_mode: None, }; - /// Specifies a default sampler. + /// Creates a default `SamplerInfoBuilder`. #[allow(clippy::new_ret_no_self)] + #[deprecated = "Use SamplerInfo::default()"] + #[doc(hidden)] pub fn new() -> SamplerInfoBuilder { - SamplerInfoBuilder::default() + Self::default().to_builder() + } + + /// Converts a `SamplerInfo` into a `SamplerInfoBuilder`. + #[inline(always)] + pub fn to_builder(self) -> SamplerInfoBuilder { + SamplerInfoBuilder { + flags: Some(self.flags), + mag_filter: Some(self.mag_filter), + min_filter: Some(self.min_filter), + mipmap_mode: Some(self.mipmap_mode), + address_mode_u: Some(self.address_mode_u), + address_mode_v: Some(self.address_mode_v), + address_mode_w: Some(self.address_mode_w), + mip_lod_bias: Some(self.mip_lod_bias), + anisotropy_enable: Some(self.anisotropy_enable), + max_anisotropy: Some(self.max_anisotropy), + compare_enable: Some(self.compare_enable), + compare_op: Some(self.compare_op), + min_lod: Some(self.min_lod), + max_lod: Some(self.max_lod), + border_color: Some(self.border_color), + unnormalized_coordinates: Some(self.unnormalized_coordinates), + reduction_mode: Some(self.reduction_mode), + } + } +} + +impl Default for SamplerInfo { + fn default() -> Self { + Self { + flags: vk::SamplerCreateFlags::empty(), + mag_filter: vk::Filter::NEAREST, + min_filter: vk::Filter::NEAREST, + mipmap_mode: vk::SamplerMipmapMode::NEAREST, + address_mode_u: vk::SamplerAddressMode::REPEAT, + address_mode_v: vk::SamplerAddressMode::REPEAT, + address_mode_w: vk::SamplerAddressMode::REPEAT, + mip_lod_bias: OrderedFloat(0.0), + anisotropy_enable: false, + max_anisotropy: OrderedFloat(0.0), + compare_enable: false, + compare_op: vk::CompareOp::NEVER, + min_lod: OrderedFloat(0.0), + max_lod: OrderedFloat(0.0), + border_color: vk::BorderColor::FLOAT_TRANSPARENT_BLACK, + unnormalized_coordinates: false, + reduction_mode: vk::SamplerReductionMode::WEIGHTED_AVERAGE, + } } } -// HACK: https://github.com/colin-kiegel/rust-derive-builder/issues/56 impl SamplerInfoBuilder { /// Builds a new `SamplerInfo`. + #[inline(always)] pub fn build(self) -> SamplerInfo { - self.fallible_build() - .expect("All required fields set at initialization") + let res = self.fallible_build(); + + #[cfg(test)] + let res = res.unwrap(); + + #[cfg(not(test))] + let res = unsafe { res.unwrap_unchecked() }; + + res } } @@ -1355,3 +1412,27 @@ impl SpecializationInfo { } } } + +#[cfg(test)] +mod tests { + use super::*; + + type Info = SamplerInfo; + type Builder = SamplerInfoBuilder; + + #[test] + pub fn sampler_info() { + let info = Info::default(); + let builder = info.to_builder().build(); + + assert_eq!(info, builder); + } + + #[test] + pub fn sampler_info_builder() { + let info = Info::default(); + let builder = Builder::default().build(); + + assert_eq!(info, builder); + } +} diff --git a/src/driver/swapchain.rs b/src/driver/swapchain.rs index ba10b82..a4ce9c8 100644 --- a/src/driver/swapchain.rs +++ b/src/driver/swapchain.rs @@ -293,7 +293,7 @@ impl Swapchain { if Device::image_format_properties( &self.device, - self.info.format.format, + self.info.surface.format, vk::ImageType::TYPE_2D, vk::ImageTiling::OPTIMAL, usage, @@ -378,8 +378,8 @@ impl Swapchain { let swapchain_create_info = vk::SwapchainCreateInfoKHR::builder() .surface(*self.surface) .min_image_count(desired_image_count) - .image_color_space(self.info.format.color_space) - .image_format(self.info.format.format) + .image_color_space(self.info.surface.color_space) + .image_format(self.info.surface.format) .image_extent(vk::Extent2D { width: surface_width, height: surface_height, @@ -414,10 +414,10 @@ impl Swapchain { let mut image = Image::from_raw( &self.device, vk_image, - ImageInfo::new_2d( - self.info.format.format, + ImageInfo::image_2d( surface_width, surface_height, + self.info.surface.format, surface_capabilities.supported_usage_flags, ), ); @@ -438,7 +438,7 @@ impl Swapchain { "Swapchain {}x{} {:?} {present_mode:?}x{}", self.info.width, self.info.height, - self.info.format.format, + self.info.surface.format, self.images.len(), ); @@ -550,13 +550,12 @@ pub struct SwapchainInfo { #[builder(default = "3")] pub desired_image_count: u32, - /// The format of the surface. - pub format: vk::SurfaceFormatKHR, - /// The initial height of the surface. - #[builder(default = "8")] pub height: u32, + /// The format and color space of the surface. + pub surface: vk::SurfaceFormatKHR, + /// Determines if frames will be submitted to the display in a synchronous fashion or if they /// should be displayed as fast as possible instead. /// @@ -565,18 +564,32 @@ pub struct SwapchainInfo { pub sync_display: bool, /// The initial width of the surface. - #[builder(default = "8")] pub width: u32, } impl SwapchainInfo { - /// Specifies default device information. - #[allow(clippy::new_ret_no_self, unused)] - pub fn new(width: u32, height: u32, format: vk::SurfaceFormatKHR) -> SwapchainInfoBuilder { - SwapchainInfoBuilder::default() - .width(width) - .height(height) - .format(format) + /// Specifies a default swapchain with the given `width`, `height` and `format` values. + #[inline(always)] + pub const fn new(width: u32, height: u32, surface: vk::SurfaceFormatKHR) -> SwapchainInfo { + Self { + width, + height, + surface, + desired_image_count: 3, + sync_display: true, + } + } + + /// Converts a `SwapchainInfo` into a `SwapchainInfoBuilder`. + #[inline(always)] + pub fn to_builder(self) -> SwapchainInfoBuilder { + SwapchainInfoBuilder { + desired_image_count: Some(self.desired_image_count), + height: Some(self.height), + surface: Some(self.surface), + sync_display: Some(self.sync_display), + width: Some(self.width), + } } } @@ -586,20 +599,31 @@ impl From for SwapchainInfo { } } -// HACK: https://github.com/colin-kiegel/rust-derive-builder/issues/56 impl SwapchainInfoBuilder { /// Builds a new `SwapchainInfo`. + /// + /// # Panics + /// + /// If any of the following values have not been set this function will panic: + /// + /// * `width` + /// * `height` + /// * `surface` + #[inline(always)] pub fn build(self) -> SwapchainInfo { - self.fallible_build().unwrap() + match self.fallible_build() { + Err(SwapchainInfoBuilderError(err)) => panic!("{err}"), + Ok(info) => info, + } } } #[derive(Debug)] -struct SwapchainInfoBuilderError; +struct SwapchainInfoBuilderError(UninitializedFieldError); impl From for SwapchainInfoBuilderError { - fn from(_: UninitializedFieldError) -> Self { - Self + fn from(err: UninitializedFieldError) -> Self { + Self(err) } } @@ -623,3 +647,52 @@ impl Synchronization { }) } } + +#[cfg(test)] +mod tests { + use super::*; + + type Info = SwapchainInfo; + type Builder = SwapchainInfoBuilder; + + #[test] + pub fn swapchain_info() { + let info = Info::new(20, 24, vk::SurfaceFormatKHR::default()); + let builder = info.to_builder().build(); + + assert_eq!(info, builder); + } + + #[test] + pub fn swapchain_info_builder() { + let info = Info::new(23, 64, vk::SurfaceFormatKHR::default()); + let builder = Builder::default() + .width(23) + .height(64) + .surface(vk::SurfaceFormatKHR::default()) + .build(); + + assert_eq!(info, builder); + } + + #[test] + #[should_panic(expected = "Field not initialized: height")] + pub fn accel_struct_info_builder_uninit_height() { + Builder::default().build(); + } + + #[test] + #[should_panic(expected = "Field not initialized: surface")] + pub fn accel_struct_info_builder_uninit_surface() { + Builder::default().height(42).build(); + } + + #[test] + #[should_panic(expected = "Field not initialized: width")] + pub fn accel_struct_info_builder_uninit_width() { + Builder::default() + .height(42) + .surface(vk::SurfaceFormatKHR::default()) + .build(); + } +} diff --git a/src/event_loop.rs b/src/event_loop.rs index 93c47bb..0074129 100644 --- a/src/event_loop.rs +++ b/src/event_loop.rs @@ -467,7 +467,7 @@ impl EventLoopBuilder { impl EventLoopBuilder { /// Builds a new `EventLoop`. - pub fn build(self) -> Result { + pub fn build(mut self) -> Result { // Create an operating system window via Winit let window = self.window; @@ -483,6 +483,7 @@ impl EventLoopBuilder { let inner_size = window.inner_size(); (inner_size.width, inner_size.height) }; + self.swapchain_info = self.swapchain_info.width(width).height(height); // Load the GPU driver (thin Vulkan device and swapchain smart pointers) let device_info = self.device_info.build(); @@ -520,7 +521,7 @@ impl EventLoopBuilder { let swapchain = Swapchain::new( &device, surface, - self.swapchain_info.format(surface_format).build(), + self.swapchain_info.surface(surface_format), )?; info!( diff --git a/src/graph/pass_ref.rs b/src/graph/pass_ref.rs index 85f55b2..18b9dfb 100644 --- a/src/graph/pass_ref.rs +++ b/src/graph/pass_ref.rs @@ -62,7 +62,7 @@ pub type DescriptorSetIndex = u32; /// # fn main() -> Result<(), DriverError> { /// # let device = Arc::new(Device::create_headless(DeviceInfo::new())?); /// # let mut my_graph = RenderGraph::new(); -/// # let info = AccelerationStructureInfo::new_blas(1); +/// # let info = AccelerationStructureInfo::blas(1); /// my_graph.begin_pass("my acceleration pass") /// .record_acceleration(move |acceleration, bindings| { /// // During this closure we have access to the acceleration methods! @@ -101,15 +101,15 @@ impl<'a> Acceleration<'a> { /// # fn main() -> Result<(), DriverError> { /// # let device = Arc::new(Device::create_headless(DeviceInfo::new())?); /// # let mut my_graph = RenderGraph::new(); - /// # let info = AccelerationStructureInfo::new_blas(1); + /// # let info = AccelerationStructureInfo::blas(1); /// # let blas_accel_struct = AccelerationStructure::create(&device, info)?; /// # let blas_node = my_graph.bind_node(blas_accel_struct); - /// # let scratch_buf_info = BufferInfo::new(8, vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS); + /// # let scratch_buf_info = BufferInfo::device_mem(8, vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS); /// # let scratch_buf = Buffer::create(&device, scratch_buf_info)?; /// # let scratch_buf = my_graph.bind_node(scratch_buf); - /// # let buf_info = BufferInfo::new(8, vk::BufferUsageFlags::INDEX_BUFFER); + /// # let buf_info = BufferInfo::device_mem(8, vk::BufferUsageFlags::INDEX_BUFFER); /// # let my_idx_buf = Buffer::create(&device, buf_info)?; - /// # let buf_info = BufferInfo::new(8, vk::BufferUsageFlags::VERTEX_BUFFER); + /// # let buf_info = BufferInfo::device_mem(8, vk::BufferUsageFlags::VERTEX_BUFFER); /// # let my_vtx_buf = Buffer::create(&device, buf_info)?; /// # let index_node = my_graph.bind_node(my_idx_buf); /// # let vertex_node = my_graph.bind_node(my_vtx_buf); @@ -370,7 +370,7 @@ bind!(RayTrace); /// # use screen_13::graph::node::ImageNode; /// # fn main() -> Result<(), DriverError> { /// # let device = Arc::new(Device::create_headless(DeviceInfo::new())?); -/// # let info = ImageInfo::new_2d(vk::Format::R8G8B8A8_UNORM, 32, 32, vk::ImageUsageFlags::SAMPLED); +/// # let info = ImageInfo::image_2d(32, 32, vk::Format::R8G8B8A8_UNORM, vk::ImageUsageFlags::SAMPLED); /// # let image = Image::create(&device, info)?; /// # let mut my_graph = RenderGraph::new(); /// # let my_image_node = my_graph.bind_node(image); @@ -563,7 +563,7 @@ impl<'a> Compute<'a> { /// # use screen_13::graph::RenderGraph; /// # fn main() -> Result<(), DriverError> { /// # let device = Arc::new(Device::create_headless(DeviceInfo::new())?); - /// # let buf_info = BufferInfo::new(8, vk::BufferUsageFlags::STORAGE_BUFFER); + /// # let buf_info = BufferInfo::device_mem(8, vk::BufferUsageFlags::STORAGE_BUFFER); /// # let my_buf = Buffer::create(&device, buf_info)?; /// # let info = ComputePipelineInfo::default(); /// # let shader = Shader::new_compute([0u8; 1].as_slice()); @@ -649,7 +649,7 @@ impl<'a> Compute<'a> { /// # use screen_13::graph::RenderGraph; /// # fn main() -> Result<(), DriverError> { /// # let device = Arc::new(Device::create_headless(DeviceInfo::new())?); - /// # let buf_info = BufferInfo::new(8, vk::BufferUsageFlags::STORAGE_BUFFER); + /// # let buf_info = BufferInfo::device_mem(8, vk::BufferUsageFlags::STORAGE_BUFFER); /// # let my_buf = Buffer::create(&device, buf_info)?; /// # let info = ComputePipelineInfo::default(); /// # let shader = Shader::new_compute([0u8; 1].as_slice()); @@ -951,7 +951,7 @@ impl From<(DescriptorSetIndex, BindingIndex, [BindingOffset; 1])> for Descriptor /// # let info = GraphicPipelineInfo::default(); /// # let my_graphic_pipeline = Arc::new(GraphicPipeline::create(&device, info, [vert, frag])?); /// # let mut my_graph = RenderGraph::new(); -/// # let info = ImageInfo::new_2d(vk::Format::R8G8B8A8_UNORM, 32, 32, vk::ImageUsageFlags::SAMPLED); +/// # let info = ImageInfo::image_2d(32, 32, vk::Format::R8G8B8A8_UNORM, vk::ImageUsageFlags::SAMPLED); /// # let swapchain_image = my_graph.bind_node(Image::create(&device, info)?); /// my_graph.begin_pass("my draw pass") /// .bind_pipeline(&my_graphic_pipeline) @@ -998,11 +998,11 @@ impl<'a> Draw<'a> { /// # let info = GraphicPipelineInfo::default(); /// # let my_graphic_pipeline = Arc::new(GraphicPipeline::create(&device, info, [vert, frag])?); /// # let mut my_graph = RenderGraph::new(); - /// # let info = ImageInfo::new_2d(vk::Format::R8G8B8A8_UNORM, 32, 32, vk::ImageUsageFlags::SAMPLED); + /// # let info = ImageInfo::image_2d(32, 32, vk::Format::R8G8B8A8_UNORM, vk::ImageUsageFlags::SAMPLED); /// # let swapchain_image = my_graph.bind_node(Image::create(&device, info)?); - /// # let buf_info = BufferInfo::new(8, vk::BufferUsageFlags::INDEX_BUFFER); + /// # let buf_info = BufferInfo::device_mem(8, vk::BufferUsageFlags::INDEX_BUFFER); /// # let my_idx_buf = Buffer::create(&device, buf_info)?; - /// # let buf_info = BufferInfo::new(8, vk::BufferUsageFlags::VERTEX_BUFFER); + /// # let buf_info = BufferInfo::device_mem(8, vk::BufferUsageFlags::VERTEX_BUFFER); /// # let my_vtx_buf = Buffer::create(&device, buf_info)?; /// # let my_idx_buf = my_graph.bind_node(my_idx_buf); /// # let my_vtx_buf = my_graph.bind_node(my_vtx_buf); @@ -1069,7 +1069,7 @@ impl<'a> Draw<'a> { /// # use screen_13::graph::RenderGraph; /// # fn main() -> Result<(), DriverError> { /// # let device = Arc::new(Device::create_headless(DeviceInfo::new())?); - /// # let buf_info = BufferInfo::new(8, vk::BufferUsageFlags::VERTEX_BUFFER); + /// # let buf_info = BufferInfo::device_mem(8, vk::BufferUsageFlags::VERTEX_BUFFER); /// # let my_vtx_buf = Buffer::create(&device, buf_info)?; /// # let my_frag_code = [0u8; 1]; /// # let my_vert_code = [0u8; 1]; @@ -1078,7 +1078,7 @@ impl<'a> Draw<'a> { /// # let info = GraphicPipelineInfo::default(); /// # let my_graphic_pipeline = Arc::new(GraphicPipeline::create(&device, info, [vert, frag])?); /// # let mut my_graph = RenderGraph::new(); - /// # let info = ImageInfo::new_2d(vk::Format::R8G8B8A8_UNORM, 32, 32, vk::ImageUsageFlags::SAMPLED); + /// # let info = ImageInfo::image_2d(32, 32, vk::Format::R8G8B8A8_UNORM, vk::ImageUsageFlags::SAMPLED); /// # let swapchain_image = my_graph.bind_node(Image::create(&device, info)?); /// # let my_vtx_buf = my_graph.bind_node(my_vtx_buf); /// my_graph.begin_pass("my unindexed geometry draw pass") @@ -1252,13 +1252,13 @@ impl<'a> Draw<'a> { /// # let info = GraphicPipelineInfo::default(); /// # let my_graphic_pipeline = Arc::new(GraphicPipeline::create(&device, info, [vert, frag])?); /// # let mut my_graph = RenderGraph::new(); - /// # let buf_info = BufferInfo::new(8, vk::BufferUsageFlags::INDEX_BUFFER); + /// # let buf_info = BufferInfo::device_mem(8, vk::BufferUsageFlags::INDEX_BUFFER); /// # let my_idx_buf = Buffer::create(&device, buf_info)?; - /// # let buf_info = BufferInfo::new(8, vk::BufferUsageFlags::VERTEX_BUFFER); + /// # let buf_info = BufferInfo::device_mem(8, vk::BufferUsageFlags::VERTEX_BUFFER); /// # let my_vtx_buf = Buffer::create(&device, buf_info)?; /// # let my_idx_buf = my_graph.bind_node(my_idx_buf); /// # let my_vtx_buf = my_graph.bind_node(my_vtx_buf); - /// # let info = ImageInfo::new_2d(vk::Format::R8G8B8A8_UNORM, 32, 32, vk::ImageUsageFlags::SAMPLED); + /// # let info = ImageInfo::image_2d(32, 32, vk::Format::R8G8B8A8_UNORM, vk::ImageUsageFlags::SAMPLED); /// # let swapchain_image = my_graph.bind_node(Image::create(&device, info)?); /// const CMD_SIZE: usize = size_of::(); /// @@ -1462,7 +1462,7 @@ impl<'a> Draw<'a> { /// # let frag = Shader::new_fragment(my_frag_code.as_slice()); /// # let info = GraphicPipelineInfo::default(); /// # let my_graphic_pipeline = Arc::new(GraphicPipeline::create(&device, info, [vert, frag])?); - /// # let info = ImageInfo::new_2d(vk::Format::R8G8B8A8_UNORM, 32, 32, vk::ImageUsageFlags::SAMPLED); + /// # let info = ImageInfo::image_2d(32, 32, vk::Format::R8G8B8A8_UNORM, vk::ImageUsageFlags::SAMPLED); /// # let swapchain_image = Image::create(&device, info)?; /// # let mut my_graph = RenderGraph::new(); /// # let swapchain_image = my_graph.bind_node(swapchain_image); @@ -1531,7 +1531,7 @@ impl<'a> Draw<'a> { /// # let frag = Shader::new_fragment(my_frag_code.as_slice()); /// # let info = GraphicPipelineInfo::default(); /// # let my_graphic_pipeline = Arc::new(GraphicPipeline::create(&device, info, [vert, frag])?); - /// # let info = ImageInfo::new_2d(vk::Format::R8G8B8A8_UNORM, 32, 32, vk::ImageUsageFlags::SAMPLED); + /// # let info = ImageInfo::image_2d(32, 32, vk::Format::R8G8B8A8_UNORM, vk::ImageUsageFlags::SAMPLED); /// # let swapchain_image = Image::create(&device, info)?; /// # let mut my_graph = RenderGraph::new(); /// # let swapchain_image = my_graph.bind_node(swapchain_image); diff --git a/src/graph/resolver.rs b/src/graph/resolver.rs index 53db28a..cbc8603 100644 --- a/src/graph/resolver.rs +++ b/src/graph/resolver.rs @@ -687,21 +687,23 @@ impl Resolver { pipeline: &mut ExecutionPipeline, depth_stencil: Option, ) -> Result<(), DriverError> { - let (ty, name, vk_pipeline) = match pipeline { - ExecutionPipeline::Compute(pipeline) => { - ("compute", pipeline.info.name.as_ref(), ***pipeline) - } - ExecutionPipeline::Graphic(pipeline) => { - ("graphic", pipeline.info.name.as_ref(), vk::Pipeline::null()) - } - ExecutionPipeline::RayTrace(pipeline) => { - ("ray trace", pipeline.info.name.as_ref(), ***pipeline) + if log_enabled!(Trace) { + let (ty, name, vk_pipeline) = match pipeline { + ExecutionPipeline::Compute(pipeline) => { + ("compute", pipeline.name.as_ref(), ***pipeline) + } + ExecutionPipeline::Graphic(pipeline) => { + ("graphic", pipeline.name.as_ref(), vk::Pipeline::null()) + } + ExecutionPipeline::RayTrace(pipeline) => { + ("ray trace", pipeline.name.as_ref(), ***pipeline) + } + }; + if let Some(name) = name { + trace!(" bind {} pipeline {} ({:?})", ty, name, vk_pipeline); + } else { + trace!(" bind {} pipeline {:?}", ty, vk_pipeline); } - }; - if let Some(name) = name { - trace!(" bind {} pipeline {} ({:?})", ty, name, vk_pipeline); - } else { - trace!(" bind {} pipeline {:?}", ty, vk_pipeline); } // We store a shared reference to this pipeline inside the command buffer! diff --git a/src/lib.rs b/src/lib.rs index a643a19..8e425eb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -57,7 +57,7 @@ For example, a typical host-mappable buffer: # use screen_13::driver::buffer::{Buffer, BufferInfo}; # fn main() -> Result<(), DriverError> { # let device = Arc::new(Device::create_headless(DeviceInfo::new())?); -let info = BufferInfo::new_mappable(1024, vk::BufferUsageFlags::STORAGE_BUFFER); +let info = BufferInfo::host_mem(1024, vk::BufferUsageFlags::STORAGE_BUFFER); let my_buf = Buffer::create(&device, info)?; # Ok(()) } ``` @@ -108,10 +108,10 @@ For example, leasing an image: # use screen_13::pool::{Pool}; # use screen_13::pool::lazy::{LazyPool}; # fn main() -> Result<(), DriverError> { -# let device = Arc::new(Device::create_headless(DeviceInfo::new())?); +# let device = Arc::new(Device::create_headless(DeviceInfo::default())?); let mut pool = LazyPool::new(&device); -let info = ImageInfo::new_2d(vk::Format::R8G8B8A8_UNORM, 8, 8, vk::ImageUsageFlags::STORAGE); +let info = ImageInfo::image_2d(8, 8, vk::Format::R8G8B8A8_UNORM, vk::ImageUsageFlags::STORAGE); let my_image = pool.lease(info)?; # Ok(()) } ``` @@ -148,10 +148,10 @@ it as a node. Bound nodes may only be used with the graphs they were bound to. N # use screen_13::pool::{Pool}; # use screen_13::pool::lazy::{LazyPool}; # fn main() -> Result<(), DriverError> { -# let device = Arc::new(Device::create_headless(DeviceInfo::new())?); -# let info = BufferInfo::new_mappable(1024, vk::BufferUsageFlags::STORAGE_BUFFER); +# let device = Arc::new(Device::create_headless(DeviceInfo::default())?); +# let info = BufferInfo::host_mem(1024, vk::BufferUsageFlags::STORAGE_BUFFER); # let buffer = Buffer::create(&device, info)?; -# let info = ImageInfo::new_2d(vk::Format::R8G8B8A8_UNORM, 8, 8, vk::ImageUsageFlags::STORAGE); +# let info = ImageInfo::image_2d(8, 8, vk::Format::R8G8B8A8_UNORM, vk::ImageUsageFlags::STORAGE); # let image = Image::create(&device, info)?; # let mut graph = RenderGraph::new(); println!("{:?}", buffer); // Buffer @@ -200,10 +200,10 @@ Example: # use screen_13::pool::{Pool}; # use screen_13::pool::lazy::{LazyPool}; # fn main() -> Result<(), DriverError> { -# let device = Arc::new(Device::create_headless(DeviceInfo::new())?); -# let info = BufferInfo::new_mappable(1024, vk::BufferUsageFlags::STORAGE_BUFFER); +# let device = Arc::new(Device::create_headless(DeviceInfo::default())?); +# let info = BufferInfo::host_mem(1024, vk::BufferUsageFlags::STORAGE_BUFFER); # let buffer = Buffer::create(&device, info)?; -# let info = ImageInfo::new_2d(vk::Format::R8G8B8A8_UNORM, 8, 8, vk::ImageUsageFlags::STORAGE); +# let info = ImageInfo::image_2d(8, 8, vk::Format::R8G8B8A8_UNORM, vk::ImageUsageFlags::STORAGE); # let image = Image::create(&device, info)?; let mut graph = RenderGraph::new(); let buffer_node = graph.bind_node(buffer); diff --git a/src/pool/mod.rs b/src/pool/mod.rs index 20fc5ee..99f359f 100644 --- a/src/pool/mod.rs +++ b/src/pool/mod.rs @@ -34,7 +34,7 @@ //! # let device = Arc::new(Device::create_headless(DeviceInfo::new())?); //! let mut pool = LazyPool::new(&device); //! -//! let info = ImageInfo::new_2d(vk::Format::R8G8B8A8_UNORM, 8, 8, vk::ImageUsageFlags::STORAGE); +//! let info = ImageInfo::image_2d(8, 8, vk::Format::R8G8B8A8_UNORM, vk::ImageUsageFlags::STORAGE); //! let my_image = pool.lease(info)?; //! //! assert!(my_image.info.usage.contains(vk::ImageUsageFlags::STORAGE));