diff --git a/examples/colour-uniform/main.rs b/examples/colour-uniform/main.rs index 0377eb05cff..15c61409893 100644 --- a/examples/colour-uniform/main.rs +++ b/examples/colour-uniform/main.rs @@ -48,37 +48,25 @@ use std::rc::Rc; use std::{fs, iter}; use hal::{ + adapter::{Adapter, MemoryType}, buffer, command, - format as f, + format::{self as f, AsFormat}, image as i, memory as m, pass, pool, + prelude::*, pso, - window::Extent2D, - Adapter, + queue::{QueueGroup, Submission}, + window as w, Backend, - DescriptorPool, - Device, - Instance, - Limits, - MemoryType, - PhysicalDevice, - Primitive, - QueueGroup, - Surface, - Swapchain, - SwapchainConfig, }; -use hal::format::{AsFormat, ChannelType, Rgba8Srgb as ColorFormat, Swizzle}; -use hal::pass::Subpass; -use hal::pso::{PipelineStage, ShaderStageFlags, VertexInputRate}; -use hal::queue::Submission; +pub type ColorFormat = f::Rgba8Srgb; const ENTRY_NAME: &str = "main"; -const DIMS: Extent2D = Extent2D { +const DIMS: w::Extent2D = w::Extent2D { width: 1024, height: 768, }; @@ -127,7 +115,7 @@ trait SurfaceTrait { fn get_context_t(&self) -> &back::glutin::RawContext; } -impl SurfaceTrait for ::Surface { +impl SurfaceTrait for ::Surface { #[cfg(feature = "gl")] fn get_context_t(&self) -> &back::glutin::RawContext { self.get_context() @@ -176,14 +164,14 @@ impl RendererState { binding: 0, ty: pso::DescriptorType::SampledImage, count: 1, - stage_flags: ShaderStageFlags::FRAGMENT, + stage_flags: pso::ShaderStageFlags::FRAGMENT, immutable_samplers: false, }, pso::DescriptorSetLayoutBinding { binding: 1, ty: pso::DescriptorType::Sampler, count: 1, - stage_flags: ShaderStageFlags::FRAGMENT, + stage_flags: pso::ShaderStageFlags::FRAGMENT, immutable_samplers: false, }, ], @@ -195,7 +183,7 @@ impl RendererState { binding: 0, ty: pso::DescriptorType::UniformBuffer, count: 1, - stage_flags: ShaderStageFlags::FRAGMENT, + stage_flags: pso::ShaderStageFlags::FRAGMENT, immutable_samplers: false, }], ); @@ -245,13 +233,13 @@ impl RendererState { let mut staging_pool = device .borrow() .device - .create_command_pool_typed( - &device.borrow().queues, + .create_command_pool( + device.borrow().queues.family, pool::CommandPoolCreateFlags::empty(), ) .expect("Can't create staging command pool"); - let image = ImageState::new::( + let image = ImageState::new( image_desc, &img, &backend.adapter, @@ -277,10 +265,7 @@ impl RendererState { image.wait_for_transfer_completion(); - device - .borrow() - .device - .destroy_command_pool(staging_pool.into_raw()); + device.borrow().device.destroy_command_pool(staging_pool); let mut swapchain = Some(SwapchainState::new(&mut backend, Rc::clone(&device))); @@ -375,7 +360,7 @@ impl RendererState { let sem_index = self.framebuffer.next_acq_pre_pair_index(); - let frame: hal::SwapImageIndex = unsafe { + let frame: w::SwapImageIndex = unsafe { let (acquire_semaphore, _) = self .framebuffer .get_frame_data(None, Some(sem_index)) @@ -421,9 +406,9 @@ impl RendererState { // Rendering let mut cmd_buffer = match command_buffers.pop() { Some(cmd_buffer) => cmd_buffer, - None => command_pool.acquire_command_buffer(), + None => command_pool.allocate_one(command::Level::Primary), }; - cmd_buffer.begin(); + cmd_buffer.begin_primary(command::CommandBufferFlags::ONE_TIME_SUBMIT); cmd_buffer.set_viewports(0, &[self.viewport.clone()]); cmd_buffer.set_scissors(0, &[self.viewport.rect]); @@ -439,25 +424,27 @@ impl RendererState { &[], ); //TODO - { - let mut encoder = cmd_buffer.begin_render_pass_inline( - self.render_pass.render_pass.as_ref().unwrap(), - framebuffer, - self.viewport.rect, - &[command::ClearValue::Color(command::ClearColor::Sfloat(self.bg_color))], - ); - encoder.draw(0 .. 6, 0 .. 1); - } + cmd_buffer.begin_render_pass( + self.render_pass.render_pass.as_ref().unwrap(), + framebuffer, + self.viewport.rect, + &[command::ClearValue { + color: command::ClearColor { + float32: self.bg_color, + }, + }], + command::SubpassContents::Inline, + ); + cmd_buffer.draw(0 .. 6, 0 .. 1); cmd_buffer.finish(); let submission = Submission { command_buffers: iter::once(&cmd_buffer), - wait_semaphores: iter::once((&*image_acquired, PipelineStage::BOTTOM_OF_PIPE)), + wait_semaphores: iter::once((&*image_acquired, pso::PipelineStage::BOTTOM_OF_PIPE)), signal_semaphores: iter::once(&*image_present), }; - self.device.borrow_mut().queues.queues[0] - .submit(submission, Some(framebuffer_fence)); + self.device.borrow_mut().queues.queues[0].submit(submission, Some(framebuffer_fence)); command_buffers.push(cmd_buffer); // present frame @@ -482,36 +469,16 @@ impl RendererState { fn input(&mut self, kc: winit::event::VirtualKeyCode) { match kc { - winit::event::VirtualKeyCode::Key0 => { - self.cur_value = self.cur_value * 10 + 0 - } - winit::event::VirtualKeyCode::Key1 => { - self.cur_value = self.cur_value * 10 + 1 - } - winit::event::VirtualKeyCode::Key2 => { - self.cur_value = self.cur_value * 10 + 2 - } - winit::event::VirtualKeyCode::Key3 => { - self.cur_value = self.cur_value * 10 + 3 - } - winit::event::VirtualKeyCode::Key4 => { - self.cur_value = self.cur_value * 10 + 4 - } - winit::event::VirtualKeyCode::Key5 => { - self.cur_value = self.cur_value * 10 + 5 - } - winit::event::VirtualKeyCode::Key6 => { - self.cur_value = self.cur_value * 10 + 6 - } - winit::event::VirtualKeyCode::Key7 => { - self.cur_value = self.cur_value * 10 + 7 - } - winit::event::VirtualKeyCode::Key8 => { - self.cur_value = self.cur_value * 10 + 8 - } - winit::event::VirtualKeyCode::Key9 => { - self.cur_value = self.cur_value * 10 + 9 - } + winit::event::VirtualKeyCode::Key0 => self.cur_value = self.cur_value * 10 + 0, + winit::event::VirtualKeyCode::Key1 => self.cur_value = self.cur_value * 10 + 1, + winit::event::VirtualKeyCode::Key2 => self.cur_value = self.cur_value * 10 + 2, + winit::event::VirtualKeyCode::Key3 => self.cur_value = self.cur_value * 10 + 3, + winit::event::VirtualKeyCode::Key4 => self.cur_value = self.cur_value * 10 + 4, + winit::event::VirtualKeyCode::Key5 => self.cur_value = self.cur_value * 10 + 5, + winit::event::VirtualKeyCode::Key6 => self.cur_value = self.cur_value * 10 + 6, + winit::event::VirtualKeyCode::Key7 => self.cur_value = self.cur_value * 10 + 7, + winit::event::VirtualKeyCode::Key8 => self.cur_value = self.cur_value * 10 + 8, + winit::event::VirtualKeyCode::Key9 => self.cur_value = self.cur_value * 10 + 9, winit::event::VirtualKeyCode::R => { self.cur_value = 0; self.cur_color = Color::Red @@ -550,9 +517,7 @@ impl RendererState { Color::Green => self.bg_color[1] = self.cur_value as f32 / 255.0, Color::Blue => self.bg_color[2] = self.cur_value as f32 / 255.0, Color::Alpha => { - error!( - "Alpha is not valid for the background." - ); + error!("Alpha is not valid for the background."); return; } } @@ -600,10 +565,11 @@ struct BackendState { feature = "dx12", feature = "metal" ))] -fn create_backend(wb: winit::window::WindowBuilder, event_loop: &winit::event_loop::EventLoop<()>) -> (BackendState, back::Instance) { - let window = wb - .build(event_loop) - .unwrap(); +fn create_backend( + wb: winit::window::WindowBuilder, + event_loop: &winit::event_loop::EventLoop<()>, +) -> (BackendState, back::Instance) { + let window = wb.build(event_loop).unwrap(); let instance = back::Instance::create("gfx-rs colour-uniform", 1); let surface = instance.create_surface(&window); let mut adapters = instance.enumerate_adapters(); @@ -618,15 +584,21 @@ fn create_backend(wb: winit::window::WindowBuilder, event_loop: &winit::event_lo } #[cfg(feature = "gl")] -fn create_backend(wb: winit::window::WindowBuilder, event_loop: &winit::event_loop::EventLoop<()>) -> (BackendState, ()) { +fn create_backend( + wb: winit::window::WindowBuilder, + event_loop: &winit::event_loop::EventLoop<()>, +) -> (BackendState, ()) { let (context, window) = { let builder = back::config_context(back::glutin::ContextBuilder::new(), ColorFormat::SELF, None) .with_vsync(true); - let windowed_context = builder - .build_windowed(wb, event_loop) - .unwrap(); - unsafe { windowed_context.make_current().expect("Unable to make context current").split() } + let windowed_context = builder.build_windowed(wb, event_loop).unwrap(); + unsafe { + windowed_context + .make_current() + .expect("Unable to make context current") + .split() + } }; let surface = back::Surface::from_context(context); @@ -644,7 +616,7 @@ fn create_backend(wb: winit::window::WindowBuilder, event_loop: &winit::event_lo struct AdapterState { adapter: Option>, memory_types: Vec, - limits: Limits, + limits: hal::Limits, } impl AdapterState { @@ -674,18 +646,28 @@ impl AdapterState { struct DeviceState { device: B::Device, physical_device: B::PhysicalDevice, - queues: QueueGroup, + queues: QueueGroup, } impl DeviceState { fn new(adapter: Adapter, surface: &B::Surface) -> Self { - let (device, queues) = adapter - .open_with::<_, hal::Graphics>(1, |family| surface.supports_queue_family(family)) + let family = adapter + .queue_families + .iter() + .find(|family| { + surface.supports_queue_family(family) && family.queue_type().supports_graphics() + }) .unwrap(); + let mut gpu = unsafe { + adapter + .physical_device + .open(&[(family, &[1.0])], hal::Features::empty()) + .unwrap() + }; DeviceState { - device, - queues, + device: gpu.device, + queues: gpu.queue_groups.pop().unwrap(), physical_device: adapter.physical_device, } } @@ -720,8 +702,8 @@ impl RenderPassState { let dependency = pass::SubpassDependency { passes: pass::SubpassRef::External .. pass::SubpassRef::Pass(0), - stages: PipelineStage::COLOR_ATTACHMENT_OUTPUT - .. PipelineStage::COLOR_ATTACHMENT_OUTPUT, + stages: pso::PipelineStage::COLOR_ATTACHMENT_OUTPUT + .. pso::PipelineStage::COLOR_ATTACHMENT_OUTPUT, accesses: i::Access::empty() .. (i::Access::COLOR_ATTACHMENT_READ | i::Access::COLOR_ATTACHMENT_WRITE), }; @@ -1059,13 +1041,13 @@ struct ImageState { } impl ImageState { - unsafe fn new>( + unsafe fn new( mut desc: DescSet, - img: &::image::ImageBuffer<::image::Rgba, Vec>, + img: &image::ImageBuffer<::image::Rgba, Vec>, adapter: &AdapterState, usage: buffer::Usage, device_state: &mut DeviceState, - staging_pool: &mut hal::CommandPool, + staging_pool: &mut B::CommandPool, ) -> Self { let (buffer, dims, row_pitch, stride) = BufferState::new_texture( Rc::clone(&desc.layout.device), @@ -1110,7 +1092,7 @@ impl ImageState { &image, i::ViewKind::D2, ColorFormat::SELF, - Swizzle::NO, + f::Swizzle::NO, COLOR_RANGE.clone(), ) .unwrap(); @@ -1124,7 +1106,10 @@ impl ImageState { DescSetWrite { binding: 0, array_offset: 0, - descriptors: Some(pso::Descriptor::Image(&image_view, i::Layout::ShaderReadOnlyOptimal)), + descriptors: Some(pso::Descriptor::Image( + &image_view, + i::Layout::ShaderReadOnlyOptimal, + )), }, DescSetWrite { binding: 1, @@ -1139,8 +1124,8 @@ impl ImageState { // copy buffer to texture { - let mut cmd_buffer = staging_pool.acquire_command_buffer::(); - cmd_buffer.begin(); + let mut cmd_buffer = staging_pool.allocate_one(command::Level::Primary); + cmd_buffer.begin_primary(command::CommandBufferFlags::ONE_TIME_SUBMIT); let image_barrier = m::Barrier::Image { states: (i::Access::empty(), i::Layout::Undefined) @@ -1151,7 +1136,7 @@ impl ImageState { }; cmd_buffer.pipeline_barrier( - PipelineStage::TOP_OF_PIPE .. PipelineStage::TRANSFER, + pso::PipelineStage::TOP_OF_PIPE .. pso::PipelineStage::TRANSFER, m::Dependencies::empty(), &[image_barrier], ); @@ -1186,7 +1171,7 @@ impl ImageState { range: COLOR_RANGE.clone(), }; cmd_buffer.pipeline_barrier( - PipelineStage::TRANSFER .. PipelineStage::FRAGMENT_SHADER, + pso::PipelineStage::TRANSFER .. pso::PipelineStage::FRAGMENT_SHADER, m::Dependencies::empty(), &[image_barrier], ); @@ -1269,14 +1254,14 @@ impl PipelineState { let glsl = fs::read_to_string("colour-uniform/data/quad.vert").unwrap(); let file = glsl_to_spirv::compile(&glsl, glsl_to_spirv::ShaderType::Vertex).unwrap(); - let spirv: Vec = hal::read_spirv(file).unwrap(); + let spirv: Vec = pso::read_spirv(file).unwrap(); device.create_shader_module(&spirv).unwrap() }; let fs_module = { let glsl = fs::read_to_string("colour-uniform/data/quad.frag").unwrap(); let file = glsl_to_spirv::compile(&glsl, glsl_to_spirv::ShaderType::Fragment).unwrap(); - let spirv: Vec = hal::read_spirv(file).unwrap(); + let spirv: Vec = pso::read_spirv(file).unwrap(); device.create_shader_module(&spirv).unwrap() }; @@ -1302,14 +1287,14 @@ impl PipelineState { fragment: Some(fs_entry), }; - let subpass = Subpass { + let subpass = pass::Subpass { index: 0, main_pass: render_pass, }; let mut pipeline_desc = pso::GraphicsPipelineDesc::new( shader_entries, - Primitive::TriangleList, + hal::Primitive::TriangleList, pso::Rasterizer::FILL, &pipeline_layout, subpass, @@ -1321,7 +1306,7 @@ impl PipelineState { pipeline_desc.vertex_buffers.push(pso::VertexBufferDesc { binding: 0, stride: size_of::() as u32, - rate: VertexInputRate::Vertex, + rate: pso::VertexInputRate::Vertex, }); pipeline_desc.attributes.push(pso::AttributeDesc { @@ -1385,13 +1370,13 @@ impl SwapchainState { let format = formats.map_or(f::Format::Rgba8Srgb, |formats| { formats .iter() - .find(|format| format.base_format().1 == ChannelType::Srgb) + .find(|format| format.base_format().1 == f::ChannelType::Srgb) .map(|format| *format) .unwrap_or(formats[0]) }); println!("Surface format: {:?}", format); - let swap_config = SwapchainConfig::from_caps(&caps, format, DIMS); + let swap_config = w::SwapchainConfig::from_caps(&caps, format, DIMS); let extent = swap_config.extent.to_extent(); let (swapchain, backbuffer) = device .borrow() @@ -1424,8 +1409,8 @@ impl Drop for SwapchainState { struct FramebufferState { framebuffers: Option>, framebuffer_fences: Option>, - command_pools: Option>>, - command_buffer_lists: Vec>>, + command_pools: Option>, + command_buffer_lists: Vec>, frame_images: Option>, acquire_semaphores: Option>, present_semaphores: Option>, @@ -1458,7 +1443,7 @@ impl FramebufferState { &image, i::ViewKind::D2, swapchain.format, - Swizzle::NO, + f::Swizzle::NO, COLOR_RANGE.clone(), ) .unwrap(); @@ -1489,7 +1474,7 @@ impl FramebufferState { }; let mut fences: Vec = vec![]; - let mut command_pools: Vec> = vec![]; + let mut command_pools: Vec<_> = vec![]; let mut command_buffer_lists = Vec::new(); let mut acquire_semaphores: Vec = vec![]; let mut present_semaphores: Vec = vec![]; @@ -1500,8 +1485,8 @@ impl FramebufferState { device .borrow() .device - .create_command_pool_typed( - &device.borrow().queues, + .create_command_pool( + device.borrow().queues.family, pool::CommandPoolCreateFlags::empty(), ) .expect("Can't create command pool"), @@ -1543,8 +1528,8 @@ impl FramebufferState { Option<( &mut B::Fence, &mut B::Framebuffer, - &mut hal::CommandPool, - &mut Vec>, + &mut B::CommandPool, + &mut Vec, )>, Option<(&mut B::Semaphore, &mut B::Semaphore)>, ) { @@ -1589,7 +1574,7 @@ impl Drop for FramebufferState { .zip(self.command_buffer_lists.drain(..)) { command_pool.free(comamnd_buffer_list); - device.destroy_command_pool(command_pool.into_raw()); + device.destroy_command_pool(command_pool); } for acquire_semaphore in self.acquire_semaphores.take().unwrap() { @@ -1648,7 +1633,8 @@ fn main() { *control_flow = winit::event_loop::ControlFlow::Wait; match event { - winit::event::Event::WindowEvent { event, .. } => { + winit::event::Event::WindowEvent { event, .. } => + { #[allow(unused_variables)] match event { winit::event::WindowEvent::KeyboardInput { @@ -1659,13 +1645,16 @@ fn main() { }, .. } - | winit::event::WindowEvent::CloseRequested => - *control_flow = winit::event_loop::ControlFlow::Exit, + | winit::event::WindowEvent::CloseRequested => { + *control_flow = winit::event_loop::ControlFlow::Exit + } winit::event::WindowEvent::Resized(dims) => { #[cfg(feature = "gl")] - renderer_state.backend.surface.get_context_t().resize(dims.to_physical( - renderer_state.backend.window.hidpi_factor(), - )); + renderer_state + .backend + .surface + .get_context_t() + .resize(dims.to_physical(renderer_state.backend.window.hidpi_factor())); println!("RESIZE EVENT"); renderer_state.recreate_swapchain = true; } @@ -1707,5 +1696,7 @@ fn main() { feature = "gl" )))] fn main() { - println!("You need to enable the native API feature (vulkan/metal) in order to run the example"); + println!( + "You need to enable the native API feature (vulkan/metal) in order to run the example" + ); } diff --git a/examples/compute/main.rs b/examples/compute/main.rs index 5887e4ae33e..16e624922c7 100644 --- a/examples/compute/main.rs +++ b/examples/compute/main.rs @@ -8,7 +8,6 @@ allow(dead_code, unused_extern_crates, unused_imports) )] -extern crate env_logger; #[cfg(feature = "dx11")] extern crate gfx_backend_dx11 as back; #[cfg(feature = "dx12")] @@ -21,10 +20,7 @@ extern crate gfx_hal as hal; use std::str::FromStr; -use hal::{buffer, command, memory, pool, pso}; -use hal::{Backend, Compute, DescriptorPool, Device, Instance, PhysicalDevice, QueueFamily}; - -extern crate glsl_to_spirv; +use hal::{adapter::MemoryType, buffer, command, memory, pool, prelude::*, pso}; use std::fs; @@ -55,16 +51,28 @@ fn main() { .find(|a| { a.queue_families .iter() - .any(|family| family.supports_compute()) + .any(|family| family.queue_type().supports_compute()) }) .expect("Failed to find a GPU with compute support!"); let memory_properties = adapter.physical_device.memory_properties(); - let (device, mut queue_group) = adapter.open_with::<_, Compute>(1, |_family| true).unwrap(); + let family = adapter + .queue_families + .iter() + .find(|family| family.queue_type().supports_compute()) + .unwrap(); + let mut gpu = unsafe { + adapter + .physical_device + .open(&[(family, &[1.0])], hal::Features::empty()) + .unwrap() + }; + let device = &gpu.device; + let queue_group = gpu.queue_groups.first_mut().unwrap(); let glsl = fs::read_to_string("compute/shader/collatz.comp").unwrap(); let file = glsl_to_spirv::compile(&glsl, glsl_to_spirv::ShaderType::Compute).unwrap(); - let spirv: Vec = hal::read_spirv(file).unwrap(); + let spirv: Vec = pso::read_spirv(file).unwrap(); let shader = unsafe { device.create_shader_module(&spirv) }.unwrap(); let (pipeline_layout, pipeline, set_layout, mut desc_pool) = { @@ -155,14 +163,13 @@ fn main() { })); }; - let mut command_pool = unsafe { - device.create_command_pool_typed(&queue_group, pool::CommandPoolCreateFlags::empty()) - } - .expect("Can't create command pool"); + let mut command_pool = + unsafe { device.create_command_pool(family.id(), pool::CommandPoolCreateFlags::empty()) } + .expect("Can't create command pool"); let fence = device.create_fence(false).unwrap(); - let mut command_buffer = command_pool.acquire_command_buffer::(); + let mut command_buffer = command_pool.allocate_one(command::Level::Primary); unsafe { - command_buffer.begin(); + command_buffer.begin_primary(command::CommandBufferFlags::ONE_TIME_SUBMIT); command_buffer.copy_buffer( &staging_buffer, &device_buffer, @@ -229,7 +236,7 @@ fn main() { } unsafe { - device.destroy_command_pool(command_pool.into_raw()); + device.destroy_command_pool(command_pool); device.destroy_descriptor_pool(desc_pool); device.destroy_descriptor_set_layout(set_layout); device.destroy_shader_module(shader); @@ -243,9 +250,9 @@ fn main() { } } -unsafe fn create_buffer( +unsafe fn create_buffer( device: &B::Device, - memory_types: &[hal::MemoryType], + memory_types: &[MemoryType], properties: memory::Properties, usage: buffer::Usage, stride: u64, diff --git a/examples/quad/main.rs b/examples/quad/main.rs index 6b5b34736e0..8885e1fb506 100644 --- a/examples/quad/main.rs +++ b/examples/quad/main.rs @@ -32,29 +32,28 @@ pub fn wasm_main() { main(); } -use hal::format::{AsFormat, ChannelType, Rgba8Srgb as ColorFormat, Swizzle}; -use hal::pass::Subpass; -use hal::pso::{PipelineStage, ShaderStageFlags, VertexInputRate}; -use hal::queue::Submission; use hal::{ buffer, command, format as f, + format::{AsFormat, ChannelType, Rgba8Srgb as ColorFormat, Swizzle}, image as i, memory as m, pass, + pass::Subpass, pool, + prelude::*, pso, - window::Extent2D, + pso::{PipelineStage, ShaderStageFlags, VertexInputRate}, + queue::{QueueGroup, Submission}, + window, }; -use hal::{DescriptorPool, Primitive, SwapchainConfig}; -use hal::{Device, Instance, PhysicalDevice, Surface, Swapchain}; use std::io::Cursor; use std::mem::ManuallyDrop; #[cfg_attr(rustfmt, rustfmt_skip)] -const DIMS: Extent2D = Extent2D { width: 1024, height: 768 }; +const DIMS: window::Extent2D = window::Extent2D { width: 1024, height: 768 }; const ENTRY_NAME: &str = "main"; @@ -124,7 +123,12 @@ fn main() { back::config_context(back::glutin::ContextBuilder::new(), ColorFormat::SELF, None) .with_vsync(true); let windowed_context = builder.build_windowed(wb, &event_loop).unwrap(); - let (context, window) = unsafe { windowed_context.make_current().expect("Unable to make context current").split() }; + let (context, window) = unsafe { + windowed_context + .make_current() + .expect("Unable to make context current") + .split() + }; let surface = back::Surface::from_context(context); (window, surface) }; @@ -157,51 +161,51 @@ fn main() { *control_flow = winit::event_loop::ControlFlow::Wait; match event { - winit::event::Event::WindowEvent { event, .. } => { - match event { - winit::event::WindowEvent::CloseRequested => *control_flow = winit::event_loop::ControlFlow::Exit, - winit::event::WindowEvent::KeyboardInput { - input: - winit::event::KeyboardInput { - virtual_keycode: Some(winit::event::VirtualKeyCode::Escape), - .. - }, - .. - } => *control_flow = winit::event_loop::ControlFlow::Exit, - winit::event::WindowEvent::Resized(dims) => { - println!("resized to {:?}", dims); - #[cfg(feature = "gl")] - { - let context = renderer.surface.get_context(); - context.resize(dims.to_physical(window.hidpi_factor())); - } - let dimensions = Extent2D { - width: dims.width as u32, - height: dims.height as u32, - }; - renderer.dimensions = dimensions; - renderer.recreate_swapchain(); + winit::event::Event::WindowEvent { event, .. } => match event { + winit::event::WindowEvent::CloseRequested => { + *control_flow = winit::event_loop::ControlFlow::Exit + } + winit::event::WindowEvent::KeyboardInput { + input: + winit::event::KeyboardInput { + virtual_keycode: Some(winit::event::VirtualKeyCode::Escape), + .. + }, + .. + } => *control_flow = winit::event_loop::ControlFlow::Exit, + winit::event::WindowEvent::Resized(dims) => { + println!("resized to {:?}", dims); + #[cfg(feature = "gl")] + { + let context = renderer.surface.get_context(); + context.resize(dims.to_physical(window.hidpi_factor())); } - _ => { } + let dimensions = window::Extent2D { + width: dims.width as u32, + height: dims.height as u32, + }; + renderer.dimensions = dimensions; + renderer.recreate_swapchain(); } - } + _ => {} + }, winit::event::Event::EventsCleared => { renderer.render(); } - _ => { } + _ => {} } }); } struct Renderer { device: B::Device, - queue_group: hal::QueueGroup, + queue_group: QueueGroup, desc_pool: ManuallyDrop, surface: B::Surface, adapter: hal::adapter::Adapter, format: hal::format::Format, swap_chain: Option, - dimensions: Extent2D, + dimensions: window::Extent2D, framebuffers: Vec, frame_images: Vec<(B::Image, B::ImageView)>, viewport: hal::pso::Viewport, @@ -214,8 +218,8 @@ struct Renderer { image_acquire_semaphores: Vec, free_acquire_semaphore: Option, submission_complete_fences: Vec, - cmd_pools: Vec>, - cmd_buffers: Vec>, + cmd_pools: Vec, + cmd_buffers: Vec, vertex_buffer: ManuallyDrop, image_upload_buffer: ManuallyDrop, image_logo: ManuallyDrop, @@ -228,63 +232,82 @@ struct Renderer { frame: u64, } -impl Renderer where B: hal::Backend { +impl Renderer +where + B: hal::Backend, +{ fn new(mut surface: B::Surface, mut adapter: hal::adapter::Adapter) -> Renderer { let memory_types = adapter.physical_device.memory_properties().memory_types; let limits = adapter.physical_device.limits(); // Build a new device and associated command queues - let (device, mut queue_group) = adapter - .open_with::<_, hal::Graphics>(1, |family| surface.supports_queue_family(family)) + let family = adapter + .queue_families + .iter() + .find(|family| { + surface.supports_queue_family(family) && family.queue_type().supports_graphics() + }) .unwrap(); + let mut gpu = unsafe { + adapter + .physical_device + .open(&[(family, &[1.0])], hal::Features::empty()) + .unwrap() + }; + let mut queue_group = gpu.queue_groups.pop().unwrap(); + let device = gpu.device; let mut command_pool = unsafe { - device.create_command_pool_typed(&queue_group, pool::CommandPoolCreateFlags::empty()) + device.create_command_pool(queue_group.family, pool::CommandPoolCreateFlags::empty()) } .expect("Can't create command pool"); // Setup renderpass and pipeline - let set_layout = ManuallyDrop::new(unsafe { - device.create_descriptor_set_layout( - &[ - pso::DescriptorSetLayoutBinding { - binding: 0, - ty: pso::DescriptorType::SampledImage, - count: 1, - stage_flags: ShaderStageFlags::FRAGMENT, - immutable_samplers: false, - }, - pso::DescriptorSetLayoutBinding { - binding: 1, - ty: pso::DescriptorType::Sampler, - count: 1, - stage_flags: ShaderStageFlags::FRAGMENT, - immutable_samplers: false, - }, - ], - &[], - ) - } - .expect("Can't create descriptor set layout")); + let set_layout = ManuallyDrop::new( + unsafe { + device.create_descriptor_set_layout( + &[ + pso::DescriptorSetLayoutBinding { + binding: 0, + ty: pso::DescriptorType::SampledImage, + count: 1, + stage_flags: ShaderStageFlags::FRAGMENT, + immutable_samplers: false, + }, + pso::DescriptorSetLayoutBinding { + binding: 1, + ty: pso::DescriptorType::Sampler, + count: 1, + stage_flags: ShaderStageFlags::FRAGMENT, + immutable_samplers: false, + }, + ], + &[], + ) + } + .expect("Can't create descriptor set layout"), + ); // Descriptors - let mut desc_pool = ManuallyDrop::new(unsafe { - device.create_descriptor_pool( - 1, // sets - &[ - pso::DescriptorRangeDesc { - ty: pso::DescriptorType::SampledImage, - count: 1, - }, - pso::DescriptorRangeDesc { - ty: pso::DescriptorType::Sampler, - count: 1, - }, - ], - pso::DescriptorPoolCreateFlags::empty(), - ) - } - .expect("Can't create descriptor pool")); + let mut desc_pool = ManuallyDrop::new( + unsafe { + device.create_descriptor_pool( + 1, // sets + &[ + pso::DescriptorRangeDesc { + ty: pso::DescriptorType::SampledImage, + count: 1, + }, + pso::DescriptorRangeDesc { + ty: pso::DescriptorType::Sampler, + count: 1, + }, + ], + pso::DescriptorPoolCreateFlags::empty(), + ) + } + .expect("Can't create descriptor pool"), + ); let desc_set = unsafe { desc_pool.allocate_set(&set_layout) }.unwrap(); // Buffer allocations @@ -294,8 +317,9 @@ impl Renderer where B: hal::Backend { let buffer_len = QUAD.len() as u64 * buffer_stride; assert_ne!(buffer_len, 0); - let mut vertex_buffer = - ManuallyDrop::new(unsafe { device.create_buffer(buffer_len, buffer::Usage::VERTEX) }.unwrap()); + let mut vertex_buffer = ManuallyDrop::new( + unsafe { device.create_buffer(buffer_len, buffer::Usage::VERTEX) }.unwrap(), + ); let buffer_req = unsafe { device.get_buffer_requirements(&vertex_buffer) }; @@ -312,7 +336,9 @@ impl Renderer where B: hal::Backend { .unwrap() .into(); - let buffer_memory = ManuallyDrop::new(unsafe { device.allocate_memory(upload_type, buffer_req.size) }.unwrap()); + let buffer_memory = ManuallyDrop::new( + unsafe { device.allocate_memory(upload_type, buffer_req.size) }.unwrap(), + ); unsafe { device.bind_buffer_memory(&buffer_memory, 0, &mut vertex_buffer) }.unwrap(); @@ -338,11 +364,13 @@ impl Renderer where B: hal::Backend { let row_pitch = (width * image_stride as u32 + row_alignment_mask) & !row_alignment_mask; let upload_size = (height * row_pitch) as u64; - let mut image_upload_buffer = - ManuallyDrop::new(unsafe { device.create_buffer(upload_size, buffer::Usage::TRANSFER_SRC) }.unwrap()); + let mut image_upload_buffer = ManuallyDrop::new( + unsafe { device.create_buffer(upload_size, buffer::Usage::TRANSFER_SRC) }.unwrap(), + ); let image_mem_reqs = unsafe { device.get_buffer_requirements(&image_upload_buffer) }; - let image_upload_memory = - ManuallyDrop::new(unsafe { device.allocate_memory(upload_type, image_mem_reqs.size) }.unwrap()); + let image_upload_memory = ManuallyDrop::new( + unsafe { device.allocate_memory(upload_type, image_mem_reqs.size) }.unwrap(), + ); unsafe { device.bind_buffer_memory(&image_upload_memory, 0, &mut image_upload_buffer) } .unwrap(); @@ -353,25 +381,27 @@ impl Renderer where B: hal::Backend { .acquire_mapping_writer::(&image_upload_memory, 0 .. image_mem_reqs.size) .unwrap(); for y in 0 .. height as usize { - let row = &(*img) - [y * (width as usize) * image_stride .. (y + 1) * (width as usize) * image_stride]; + let row = &(*img)[y * (width as usize) * image_stride + .. (y + 1) * (width as usize) * image_stride]; let dest_base = y * row_pitch as usize; data[dest_base .. dest_base + row.len()].copy_from_slice(row); } device.release_mapping_writer(data).unwrap(); } - let mut image_logo = ManuallyDrop::new(unsafe { - device.create_image( - kind, - 1, - ColorFormat::SELF, - i::Tiling::Optimal, - i::Usage::TRANSFER_DST | i::Usage::SAMPLED, - i::ViewCapabilities::empty(), - ) - } - .unwrap()); + let mut image_logo = ManuallyDrop::new( + unsafe { + device.create_image( + kind, + 1, + ColorFormat::SELF, + i::Tiling::Optimal, + i::Usage::TRANSFER_DST | i::Usage::SAMPLED, + i::ViewCapabilities::empty(), + ) + } + .unwrap(), + ); let image_req = unsafe { device.get_image_requirements(&image_logo) }; let device_type = memory_types @@ -383,24 +413,30 @@ impl Renderer where B: hal::Backend { }) .unwrap() .into(); - let image_memory = ManuallyDrop::new(unsafe { device.allocate_memory(device_type, image_req.size) }.unwrap()); + let image_memory = ManuallyDrop::new( + unsafe { device.allocate_memory(device_type, image_req.size) }.unwrap(), + ); unsafe { device.bind_image_memory(&image_memory, 0, &mut image_logo) }.unwrap(); - let image_srv = ManuallyDrop::new(unsafe { - device.create_image_view( - &image_logo, - i::ViewKind::D2, - ColorFormat::SELF, - Swizzle::NO, - COLOR_RANGE.clone(), - ) - } - .unwrap()); + let image_srv = ManuallyDrop::new( + unsafe { + device.create_image_view( + &image_logo, + i::ViewKind::D2, + ColorFormat::SELF, + Swizzle::NO, + COLOR_RANGE.clone(), + ) + } + .unwrap(), + ); - let sampler = ManuallyDrop::new(unsafe { - device.create_sampler(i::SamplerInfo::new(i::Filter::Linear, i::WrapMode::Clamp)) - } - .expect("Can't create sampler"));; + let sampler = ManuallyDrop::new( + unsafe { + device.create_sampler(i::SamplerInfo::new(i::Filter::Linear, i::WrapMode::Clamp)) + } + .expect("Can't create sampler"), + );; unsafe { device.write_descriptor_sets(vec![ @@ -422,8 +458,8 @@ impl Renderer where B: hal::Backend { // copy buffer to texture let mut copy_fence = device.create_fence(false).expect("Could not create fence"); unsafe { - let mut cmd_buffer = command_pool.acquire_command_buffer::(); - cmd_buffer.begin(); + let mut cmd_buffer = command_pool.allocate_one(command::Level::Primary); + cmd_buffer.begin_primary(command::CommandBufferFlags::ONE_TIME_SUBMIT); let image_barrier = m::Barrier::Image { states: (i::Access::empty(), i::Layout::Undefined) @@ -476,7 +512,8 @@ impl Renderer where B: hal::Backend { cmd_buffer.finish(); - queue_group.queues[0].submit_without_semaphores(Some(&cmd_buffer), Some(&mut copy_fence)); + queue_group.queues[0] + .submit_without_semaphores(Some(&cmd_buffer), Some(&mut copy_fence)); device .wait_for_fence(©_fence, !0) @@ -497,7 +534,7 @@ impl Renderer where B: hal::Backend { .unwrap_or(formats[0]) }); - let swap_config = SwapchainConfig::from_caps(&caps, format, DIMS); + let swap_config = window::SwapchainConfig::from_caps(&caps, format, DIMS); println!("{:?}", swap_config); let extent = swap_config.extent.to_extent(); @@ -534,8 +571,10 @@ impl Renderer where B: hal::Backend { .. (i::Access::COLOR_ATTACHMENT_READ | i::Access::COLOR_ATTACHMENT_WRITE), }; - ManuallyDrop::new(unsafe { device.create_render_pass(&[attachment], &[subpass], &[dependency]) } - .expect("Can't create render pass")) + ManuallyDrop::new( + unsafe { device.create_render_pass(&[attachment], &[subpass], &[dependency]) } + .expect("Can't create render pass"), + ) }; let (frame_images, framebuffers) = { @@ -573,9 +612,11 @@ impl Renderer where B: hal::Backend { // plus one extra which we can guarantee is unused at any given time by swapping it out with the ones // in the rest of the queue. let mut image_acquire_semaphores = Vec::with_capacity(frame_images.len()); - let free_acquire_semaphore = Option::Some(device - .create_semaphore() - .expect("Could not create semaphore")); + let free_acquire_semaphore = Option::Some( + device + .create_semaphore() + .expect("Could not create semaphore"), + ); // The number of the rest of the resources is based on the frames in flight. let mut submission_complete_semaphores = Vec::with_capacity(frames_in_flight); @@ -597,7 +638,10 @@ impl Renderer where B: hal::Backend { unsafe { cmd_pools.push( device - .create_command_pool_typed(&queue_group, pool::CommandPoolCreateFlags::empty()) + .create_command_pool( + queue_group.family, + pool::CommandPoolCreateFlags::empty(), + ) .expect("Can't create command pool"), ); } @@ -622,25 +666,28 @@ impl Renderer where B: hal::Backend { .create_fence(true) .expect("Could not create semaphore"), ); - cmd_buffers.push(cmd_pools[i].acquire_command_buffer::()); + cmd_buffers.push(cmd_pools[i].allocate_one(command::Level::Primary)); } - let pipeline_layout = ManuallyDrop::new(unsafe { - device.create_pipeline_layout( - std::iter::once(&*set_layout), - &[(pso::ShaderStageFlags::VERTEX, 0 .. 8)], - ) - } - .expect("Can't create pipeline layout")); + let pipeline_layout = ManuallyDrop::new( + unsafe { + device.create_pipeline_layout( + std::iter::once(&*set_layout), + &[(pso::ShaderStageFlags::VERTEX, 0 .. 8)], + ) + } + .expect("Can't create pipeline layout"), + ); let pipeline = { let vs_module = { - let spirv = - hal::read_spirv(Cursor::new(&include_bytes!("data/quad.vert.spv")[..])).unwrap(); + let spirv = pso::read_spirv(Cursor::new(&include_bytes!("data/quad.vert.spv")[..])) + .unwrap(); unsafe { device.create_shader_module(&spirv) }.unwrap() }; let fs_module = { let spirv = - hal::read_spirv(Cursor::new(&include_bytes!("./data/quad.frag.spv")[..])).unwrap(); + pso::read_spirv(Cursor::new(&include_bytes!("./data/quad.frag.spv")[..])) + .unwrap(); unsafe { device.create_shader_module(&spirv) }.unwrap() }; @@ -673,7 +720,7 @@ impl Renderer where B: hal::Backend { let mut pipeline_desc = pso::GraphicsPipelineDesc::new( shader_entries, - Primitive::TriangleList, + hal::Primitive::TriangleList, pso::Rasterizer::FILL, &*pipeline_layout, subpass, @@ -729,7 +776,7 @@ impl Renderer where B: hal::Backend { depth: 0.0 .. 1.0, }; - let dimensions = Extent2D { + let dimensions = window::Extent2D { width: 0, height: 0, }; @@ -773,18 +820,21 @@ impl Renderer where B: hal::Backend { fn recreate_swapchain(&mut self) { self.device.wait_idle().unwrap(); - let (caps, formats, _present_modes) = - self.surface.compatibility(&mut self.adapter.physical_device); + let (caps, formats, _present_modes) = self + .surface + .compatibility(&mut self.adapter.physical_device); // Verify that previous format still exists so we may reuse it. assert!(formats.iter().any(|fs| fs.contains(&self.format))); - let swap_config = SwapchainConfig::from_caps(&caps, self.format, self.dimensions); + let swap_config = window::SwapchainConfig::from_caps(&caps, self.format, self.dimensions); println!("{:?}", swap_config); let extent = swap_config.extent.to_extent(); - let (new_swap_chain, new_backbuffer) = - unsafe { self.device.create_swapchain(&mut self.surface, swap_config, self.swap_chain.take()) } - .expect("Can't create swapchain"); + let (new_swap_chain, new_backbuffer) = unsafe { + self.device + .create_swapchain(&mut self.surface, swap_config, self.swap_chain.take()) + } + .expect("Can't create swapchain"); unsafe { // Clean up the old framebuffers and images @@ -802,7 +852,8 @@ impl Renderer where B: hal::Backend { let pairs = new_backbuffer .into_iter() .map(|image| unsafe { - let rtv = self.device + let rtv = self + .device .create_image_view( &image, i::ViewKind::D2, @@ -835,7 +886,11 @@ impl Renderer where B: hal::Backend { // Use guaranteed unused acquire semaphore to get the index of the next frame we will render to // by using acquire_image let swap_image = unsafe { - match self.swap_chain.as_mut().unwrap().acquire_image(!0, self.free_acquire_semaphore.as_ref(), None) { + match self.swap_chain.as_mut().unwrap().acquire_image( + !0, + self.free_acquire_semaphore.as_ref(), + None, + ) { Ok((i, _)) => i as usize, Err(_) => { self.recreate_swapchain(); @@ -873,26 +928,31 @@ impl Renderer where B: hal::Backend { // Rendering let cmd_buffer = &mut self.cmd_buffers[frame_idx]; unsafe { - cmd_buffer.begin(false); + cmd_buffer.begin_primary(command::CommandBufferFlags::ONE_TIME_SUBMIT); cmd_buffer.set_viewports(0, &[self.viewport.clone()]); cmd_buffer.set_scissors(0, &[self.viewport.rect]); cmd_buffer.bind_graphics_pipeline(&self.pipeline); cmd_buffer.bind_vertex_buffers(0, Some((&*self.vertex_buffer, 0))); - cmd_buffer.bind_graphics_descriptor_sets(&self.pipeline_layout, 0, Some(&self.desc_set), &[]); - - { - let mut encoder = cmd_buffer.begin_render_pass_inline( - &self.render_pass, - &self.framebuffers[swap_image], - self.viewport.rect, - &[command::ClearValue::Color(command::ClearColor::Sfloat([ - 0.8, 0.8, 0.8, 1.0, - ]))], - ); - encoder.draw(0 .. 6, 0 .. 1); - } + cmd_buffer.bind_graphics_descriptor_sets( + &self.pipeline_layout, + 0, + Some(&self.desc_set), + &[], + ); + cmd_buffer.begin_render_pass( + &self.render_pass, + &self.framebuffers[swap_image], + self.viewport.rect, + &[command::ClearValue { + color: command::ClearColor { + float32: [0.8, 0.8, 0.8, 1.0], + }, + }], + command::SubpassContents::Inline, + ); + cmd_buffer.draw(0 .. 6, 0 .. 1); cmd_buffer.finish(); let submission = Submission { @@ -903,16 +963,19 @@ impl Renderer where B: hal::Backend { )), signal_semaphores: Some(&self.submission_complete_semaphores[frame_idx]), }; - self.queue_group.queues[0].submit(submission, Some(&self.submission_complete_fences[frame_idx])); + self.queue_group.queues[0].submit( + submission, + Some(&self.submission_complete_fences[frame_idx]), + ); // present frame if let Err(_) = self.swap_chain.as_ref().unwrap().present( &mut self.queue_group.queues[0], - swap_image as hal::SwapImageIndex, + swap_image as window::SwapImageIndex, Some(&self.submission_complete_semaphores[frame_idx]), ) { self.recreate_swapchain(); - return + return; } } @@ -921,22 +984,39 @@ impl Renderer where B: hal::Backend { } } -impl Drop for Renderer where B: hal::Backend { +impl Drop for Renderer +where + B: hal::Backend, +{ fn drop(&mut self) { self.device.wait_idle().unwrap(); unsafe { // TODO: When ManuallyDrop::take (soon to be renamed to ManuallyDrop::read) is stabilized we should use that instead. - self.device.destroy_descriptor_pool(ManuallyDrop::into_inner(std::ptr::read(&self.desc_pool))); - self.device.destroy_descriptor_set_layout(ManuallyDrop::into_inner(std::ptr::read(&self.set_layout))); - - self.device.destroy_buffer(ManuallyDrop::into_inner(std::ptr::read(&self.vertex_buffer))); - self.device.destroy_buffer(ManuallyDrop::into_inner(std::ptr::read(&self.image_upload_buffer))); - self.device.destroy_image(ManuallyDrop::into_inner(std::ptr::read(&self.image_logo))); - self.device.destroy_image_view(ManuallyDrop::into_inner(std::ptr::read(&self.image_srv))); - self.device.destroy_sampler(ManuallyDrop::into_inner(std::ptr::read(&self.sampler))); - self.device.destroy_semaphore(self.free_acquire_semaphore.take().unwrap()); + self.device + .destroy_descriptor_pool(ManuallyDrop::into_inner(std::ptr::read(&self.desc_pool))); + self.device + .destroy_descriptor_set_layout(ManuallyDrop::into_inner(std::ptr::read( + &self.set_layout, + ))); + + self.device + .destroy_buffer(ManuallyDrop::into_inner(std::ptr::read( + &self.vertex_buffer, + ))); + self.device + .destroy_buffer(ManuallyDrop::into_inner(std::ptr::read( + &self.image_upload_buffer, + ))); + self.device + .destroy_image(ManuallyDrop::into_inner(std::ptr::read(&self.image_logo))); + self.device + .destroy_image_view(ManuallyDrop::into_inner(std::ptr::read(&self.image_srv))); + self.device + .destroy_sampler(ManuallyDrop::into_inner(std::ptr::read(&self.sampler))); + self.device + .destroy_semaphore(self.free_acquire_semaphore.take().unwrap()); for p in self.cmd_pools.drain(..) { - self.device.destroy_command_pool(p.into_raw()); + self.device.destroy_command_pool(p); } for s in self.image_acquire_semaphores.drain(..) { self.device.destroy_semaphore(s); @@ -947,12 +1027,26 @@ impl Drop for Renderer where B: hal::Backend { for f in self.submission_complete_fences.drain(..) { self.device.destroy_fence(f); } - self.device.destroy_render_pass(ManuallyDrop::into_inner(std::ptr::read(&self.render_pass))); - self.device.free_memory(ManuallyDrop::into_inner(std::ptr::read(&self.buffer_memory))); - self.device.free_memory(ManuallyDrop::into_inner(std::ptr::read(&self.image_memory))); - self.device.free_memory(ManuallyDrop::into_inner(std::ptr::read(&self.image_upload_memory))); - self.device.destroy_graphics_pipeline(ManuallyDrop::into_inner(std::ptr::read(&self.pipeline))); - self.device.destroy_pipeline_layout(ManuallyDrop::into_inner(std::ptr::read(&self.pipeline_layout))); + self.device + .destroy_render_pass(ManuallyDrop::into_inner(std::ptr::read(&self.render_pass))); + self.device + .free_memory(ManuallyDrop::into_inner(std::ptr::read( + &self.buffer_memory, + ))); + self.device + .free_memory(ManuallyDrop::into_inner(std::ptr::read(&self.image_memory))); + self.device + .free_memory(ManuallyDrop::into_inner(std::ptr::read( + &self.image_upload_memory, + ))); + self.device + .destroy_graphics_pipeline(ManuallyDrop::into_inner(std::ptr::read( + &self.pipeline, + ))); + self.device + .destroy_pipeline_layout(ManuallyDrop::into_inner(std::ptr::read( + &self.pipeline_layout, + ))); for framebuffer in self.framebuffers.drain(..) { self.device.destroy_framebuffer(framebuffer); } @@ -960,7 +1054,8 @@ impl Drop for Renderer where B: hal::Backend { self.device.destroy_image_view(rtv); } - self.device.destroy_swapchain(self.swap_chain.take().unwrap()); + self.device + .destroy_swapchain(self.swap_chain.take().unwrap()); } println!("DROPPED!"); } diff --git a/reftests/scenes/basic.ron b/reftests/scenes/basic.ron index 1cccf640b5b..8e13e57fdf8 100644 --- a/reftests/scenes/basic.ron +++ b/reftests/scenes/basic.ron @@ -85,7 +85,7 @@ "empty": Graphics( framebuffer: "fbo", clear_values: [ - Color(Sfloat((0.8, 0.8, 0.8, 1.0))), + Color(Float((0.8, 0.8, 0.8, 1.0))), ], pass: ("pass", { "main": (commands: [ @@ -95,7 +95,7 @@ "pass-through": Graphics( framebuffer: "fbo", clear_values: [ - Color(Sfloat((0.8, 0.8, 0.8, 1.0))), + Color(Float((0.8, 0.8, 0.8, 1.0))), ], pass: ("pass", { "main": (commands: [ diff --git a/reftests/scenes/transfer.ron b/reftests/scenes/transfer.ron index c80505a0a2b..0191146b935 100644 --- a/reftests/scenes/transfer.ron +++ b/reftests/scenes/transfer.ron @@ -143,8 +143,7 @@ "clear-image": Transfer( ClearImage( image: "image.output", - color: Sfloat((0.501, 0.501, 0.501, 0.501)), - depth_stencil: (0.0, 0), + value: Color(Float((0.501, 0.501, 0.501, 0.501))), ranges: [ ( aspects: (bits: 0x1), //COLOR diff --git a/reftests/scenes/vertex-offset.ron b/reftests/scenes/vertex-offset.ron index 0e53a9a98a3..25e3cc8e19f 100644 --- a/reftests/scenes/vertex-offset.ron +++ b/reftests/scenes/vertex-offset.ron @@ -154,7 +154,7 @@ "offset-aligned": Graphics( framebuffer: "fbo", clear_values: [ - Color(Sfloat((0.0, 0.0, 0.0, 0.0))), + Color(Float((0.0, 0.0, 0.0, 0.0))), ], pass: ("pass", { "main": (commands: [ @@ -169,7 +169,7 @@ "offset-overlap": Graphics( framebuffer: "fbo", clear_values: [ - Color(Sfloat((0.0, 0.0, 0.0, 0.0))), + Color(Float((0.0, 0.0, 0.0, 0.0))), ], pass: ("pass", { "main": (commands: [ diff --git a/src/backend/dx11/src/conv.rs b/src/backend/dx11/src/conv.rs index 3de46bf2d1e..bdacc07b606 100644 --- a/src/backend/dx11/src/conv.rs +++ b/src/backend/dx11/src/conv.rs @@ -622,9 +622,7 @@ fn map_blend_targets( ) -> [D3D11_RENDER_TARGET_BLEND_DESC; 8] { let mut targets: [D3D11_RENDER_TARGET_BLEND_DESC; 8] = [unsafe { mem::zeroed() }; 8]; - for (mut target, color_desc) in - targets.iter_mut().zip(render_target_blends.iter()) - { + for (mut target, color_desc) in targets.iter_mut().zip(render_target_blends.iter()) { target.RenderTargetWriteMask = color_desc.mask.bits() as _; if let Some(ref blend) = color_desc.blend { let (color_op, color_src, color_dst) = map_blend_op(blend.color); diff --git a/src/backend/dx11/src/device.rs b/src/backend/dx11/src/device.rs index 0b590b38904..18e8d87c7e4 100644 --- a/src/backend/dx11/src/device.rs +++ b/src/backend/dx11/src/device.rs @@ -1,7 +1,8 @@ -use hal; +use hal::adapter::MemoryProperties; use hal::pso::VertexInputRate; use hal::queue::QueueFamilyId; use hal::range::RangeArg; +use hal::window::SwapchainConfig; use hal::{buffer, device, error, format, image, mapping, memory, pass, pool, pso, query}; use winapi::shared::dxgi::{IDXGISwapChain, DXGI_SWAP_CHAIN_DESC, DXGI_SWAP_EFFECT_DISCARD}; @@ -72,7 +73,7 @@ pub struct Device { raw: ComPtr, #[derivative(Debug = "ignore")] pub(crate) context: ComPtr, - memory_properties: hal::MemoryProperties, + memory_properties: MemoryProperties, memory_heap_flags: [MemoryHeapFlags; 3], pub(crate) internal: internal::Internal, } @@ -98,7 +99,7 @@ impl Device { pub fn new( device: ComPtr, context: ComPtr, - memory_properties: hal::MemoryProperties, + memory_properties: MemoryProperties, ) -> Self { Device { raw: device.clone(), @@ -695,7 +696,7 @@ impl Device { } } -impl hal::Device for Device { +impl device::Device for Device { unsafe fn allocate_memory( &self, mem_type: hal::MemoryTypeId, @@ -2471,7 +2472,7 @@ impl hal::Device for Device { unsafe fn create_swapchain( &self, surface: &mut Surface, - config: hal::SwapchainConfig, + config: SwapchainConfig, _old_swapchain: Option, ) -> Result<(Swapchain, Vec), hal::window::CreationError> { // TODO: use IDXGIFactory2 for >=11.1 diff --git a/src/backend/dx11/src/dxgi.rs b/src/backend/dx11/src/dxgi.rs index 88b7b0863b8..d9835498334 100644 --- a/src/backend/dx11/src/dxgi.rs +++ b/src/backend/dx11/src/dxgi.rs @@ -1,5 +1,4 @@ -use hal::adapter::DeviceType; -use hal::AdapterInfo; +use hal::adapter::{AdapterInfo, DeviceType}; use winapi::shared::guiddef::GUID; use winapi::shared::{dxgi, dxgi1_2, dxgi1_3, dxgi1_4, dxgi1_5, winerror}; diff --git a/src/backend/dx11/src/internal.rs b/src/backend/dx11/src/internal.rs index 107e5622905..e47aad8ea8c 100644 --- a/src/backend/dx11/src/internal.rs +++ b/src/backend/dx11/src/internal.rs @@ -672,43 +672,17 @@ impl Internal { fn update_clear_color( &mut self, context: &ComPtr, - clear: command::ClearColor, + value: command::ClearColor, ) { - match clear { - command::ClearColor::Sfloat(value) => { - unsafe { - ptr::copy( - &PartialClearInfo { - data: mem::transmute(value), - }, - self.map(context) as *mut _, - 1, - ) - }; - } - command::ClearColor::Uint(value) => { - unsafe { - ptr::copy( - &PartialClearInfo { - data: mem::transmute(value), - }, - self.map(context) as *mut _, - 1, - ) - }; - } - command::ClearColor::Sint(value) => { - unsafe { - ptr::copy( - &PartialClearInfo { - data: mem::transmute(value), - }, - self.map(context) as *mut _, - 1, - ) - }; - } - } + unsafe { + ptr::copy( + &PartialClearInfo { + data: mem::transmute(value), + }, + self.map(context) as *mut _, + 1, + ) + }; self.unmap(context); } @@ -1196,6 +1170,7 @@ impl Internal { U: IntoIterator, U::Item: Borrow, { + use hal::format::ChannelType as Ct; let _scope = debug_scope!(context, "ClearAttachments"); let clear_rects: SmallVec<[pso::ClearRect; 8]> = rects @@ -1234,29 +1209,12 @@ impl Internal { ); } - match value { - command::ClearColor::Sfloat(_) => unsafe { - context.PSSetShader( - self.ps_partial_clear_float.as_raw(), - ptr::null_mut(), - 0, - ); - }, - command::ClearColor::Uint(_) => unsafe { - context.PSSetShader( - self.ps_partial_clear_uint.as_raw(), - ptr::null_mut(), - 0, - ); - }, - command::ClearColor::Sint(_) => unsafe { - context.PSSetShader( - self.ps_partial_clear_int.as_raw(), - ptr::null_mut(), - 0, - ); - }, - } + let shader = match attachment.format.base_format().1 { + Ct::Uint => self.ps_partial_clear_uint.as_raw(), + Ct::Sint => self.ps_partial_clear_int.as_raw(), + _ => self.ps_partial_clear_float.as_raw(), + }; + unsafe { context.PSSetShader(shader, ptr::null_mut(), 0) }; for clear_rect in &clear_rects { let viewport = conv::map_viewport(&Viewport { diff --git a/src/backend/dx11/src/lib.rs b/src/backend/dx11/src/lib.rs index 9dc1d821dcc..0ee0b243f2d 100644 --- a/src/backend/dx11/src/lib.rs +++ b/src/backend/dx11/src/lib.rs @@ -17,12 +17,8 @@ extern crate winapi; extern crate winit; extern crate wio; -use hal::backend::RawQueueGroup; -use hal::command::{ClearColor, ClearColorRaw}; -use hal::format::ChannelType; -use hal::queue::{QueueFamilyId, Queues}; -use hal::range::RangeArg; use hal::{ + adapter, buffer, command, error, @@ -32,12 +28,17 @@ use hal::{ pass, pso, query, - CompositeAlpha, - Features, + queue, + range::RangeArg, + window, + DrawCount, + IndexCount, + InstanceCount, Limits, - QueueType, + VertexCount, + VertexOffset, + WorkGroupCount, }; -use hal::{DrawCount, IndexCount, InstanceCount, VertexCount, VertexOffset, WorkGroupCount}; use range_alloc::RangeAllocator; @@ -163,13 +164,12 @@ impl Instance { fn get_features( _device: ComPtr, _feature_level: d3dcommon::D3D_FEATURE_LEVEL, -) -> Features { - let features = Features::ROBUST_BUFFER_ACCESS - | Features::FULL_DRAW_INDEX_U32 - | Features::FORMAT_BC - | Features::INSTANCE_RATE - | Features::SAMPLER_MIP_LOD_BIAS; - features +) -> hal::Features { + hal::Features::ROBUST_BUFFER_ACCESS + | hal::Features::FULL_DRAW_INDEX_U32 + | hal::Features::FORMAT_BC + | hal::Features::INSTANCE_RATE + | hal::Features::SAMPLER_MIP_LOD_BIAS } fn get_format_properties( @@ -282,7 +282,7 @@ fn get_format_properties( impl hal::Instance for Instance { type Backend = Backend; - fn enumerate_adapters(&self) -> Vec> { + fn enumerate_adapters(&self) -> Vec> { let mut adapters = Vec::new(); let mut idx = 0; @@ -323,19 +323,19 @@ impl hal::Instance for Instance { ) }; - let memory_properties = hal::MemoryProperties { + let memory_properties = adapter::MemoryProperties { memory_types: vec![ - hal::MemoryType { + adapter::MemoryType { properties: Properties::DEVICE_LOCAL, heap_index: 0, }, - hal::MemoryType { + adapter::MemoryType { properties: Properties::CPU_VISIBLE | Properties::COHERENT | Properties::CPU_CACHED, heap_index: 1, }, - hal::MemoryType { + adapter::MemoryType { properties: Properties::CPU_VISIBLE | Properties::CPU_CACHED, heap_index: 1, }, @@ -406,7 +406,7 @@ impl hal::Instance for Instance { info!("{:#?}", info); - adapters.push(hal::Adapter { + adapters.push(adapter::Adapter { info, physical_device, queue_families: vec![QueueFamily], @@ -424,7 +424,7 @@ pub struct PhysicalDevice { adapter: ComPtr, features: hal::Features, limits: hal::Limits, - memory_properties: hal::MemoryProperties, + memory_properties: adapter::MemoryProperties, #[derivative(Debug = "ignore")] format_properties: [format::Properties; format::NUM_FORMATS], } @@ -491,12 +491,12 @@ fn get_feature_level(adapter: *mut IDXGIAdapter) -> d3dcommon::D3D_FEATURE_LEVEL } // TODO: PhysicalDevice -impl hal::PhysicalDevice for PhysicalDevice { +impl adapter::PhysicalDevice for PhysicalDevice { unsafe fn open( &self, - families: &[(&QueueFamily, &[hal::QueuePriority])], + families: &[(&QueueFamily, &[queue::QueuePriority])], requested_features: hal::Features, - ) -> Result, error::DeviceCreationError> { + ) -> Result, error::DeviceCreationError> { let (device, cxt) = { if !self.features().contains(requested_features) { return Err(error::DeviceCreationError::MissingFeature); @@ -543,24 +543,25 @@ impl hal::PhysicalDevice for PhysicalDevice { let device = device::Device::new(device, cxt, self.memory_properties.clone()); // TODO: deferred context => 1 cxt/queue? - let queues = Queues::new( - families - .into_iter() - .map(|&(family, prio)| { - assert_eq!(prio.len(), 1); - let mut group = RawQueueGroup::new(family.clone()); - - // TODO: multiple queues? - let queue = CommandQueue { - context: device.context.clone(), - }; - group.add_queue(queue); - group - }) - .collect(), - ); + let queue_groups = families + .into_iter() + .map(|&(family, prio)| { + assert_eq!(prio.len(), 1); + let mut group = queue::QueueGroup::new(queue::QueueFamilyId(0)); + + // TODO: multiple queues? + let queue = CommandQueue { + context: device.context.clone(), + }; + group.add_queue(queue); + group + }) + .collect(); - Ok(hal::Gpu { device, queues }) + Ok(adapter::Gpu { + device, + queue_groups, + }) } fn format_properties(&self, fmt: Option) -> format::Properties { @@ -667,11 +668,11 @@ impl hal::PhysicalDevice for PhysicalDevice { }) } - fn memory_properties(&self) -> hal::MemoryProperties { + fn memory_properties(&self) -> adapter::MemoryProperties { self.memory_properties.clone() } - fn features(&self) -> Features { + fn features(&self) -> hal::Features { self.features } @@ -693,7 +694,7 @@ pub struct Surface { unsafe impl Send for Surface {} unsafe impl Sync for Surface {} -impl hal::Surface for Surface { +impl window::Surface for Surface { fn supports_queue_family(&self, _queue_family: &QueueFamily) -> bool { true /*match queue_family { @@ -706,11 +707,11 @@ impl hal::Surface for Surface { &self, _: &PhysicalDevice, ) -> ( - hal::SurfaceCapabilities, + window::SurfaceCapabilities, Option>, - Vec, + Vec, ) { - let extent = hal::window::Extent2D { + let extent = window::Extent2D { width: self.width, height: self.height, }; @@ -718,13 +719,13 @@ impl hal::Surface for Surface { // TODO: flip swap effects require dx11.1/windows8 // NOTE: some swap effects affect msaa capabilities.. // TODO: _DISCARD swap effects can only have one image? - let capabilities = hal::SurfaceCapabilities { + let capabilities = window::SurfaceCapabilities { image_count: 1 ..= 16, // TODO: current_extent: Some(extent), extents: extent ..= extent, max_image_layers: 1, usage: image::Usage::COLOR_ATTACHMENT | image::Usage::TRANSFER_SRC, - composite_alpha: CompositeAlpha::OPAQUE, //TODO + composite_alpha: window::CompositeAlpha::OPAQUE, //TODO }; let formats = vec![ @@ -737,7 +738,7 @@ impl hal::Surface for Surface { ]; let present_modes = vec![ - hal::PresentMode::Fifo, //TODO + window::PresentMode::Fifo, //TODO ]; (capabilities, Some(formats), present_modes) @@ -754,13 +755,13 @@ pub struct Swapchain { unsafe impl Send for Swapchain {} unsafe impl Sync for Swapchain {} -impl hal::Swapchain for Swapchain { +impl window::Swapchain for Swapchain { unsafe fn acquire_image( &mut self, _timeout_ns: u64, _semaphore: Option<&Semaphore>, _fence: Option<&Fence>, - ) -> Result<(hal::SwapImageIndex, Option), hal::AcquireError> { + ) -> Result<(window::SwapImageIndex, Option), window::AcquireError> { // TODO: non-`_DISCARD` swap effects have more than one buffer, `FLIP` // effects are dxgi 1.3 (w10+?) in which case there is // `GetCurrentBackBufferIndex()` on the swapchain @@ -771,15 +772,15 @@ impl hal::Swapchain for Swapchain { #[derive(Debug, Clone, Copy)] pub struct QueueFamily; -impl hal::QueueFamily for QueueFamily { - fn queue_type(&self) -> QueueType { - QueueType::General +impl queue::QueueFamily for QueueFamily { + fn queue_type(&self) -> queue::QueueType { + queue::QueueType::General } fn max_queues(&self) -> usize { 1 } - fn id(&self) -> QueueFamilyId { - QueueFamilyId(0) + fn id(&self) -> queue::QueueFamilyId { + queue::QueueFamilyId(0) } } @@ -793,10 +794,10 @@ pub struct CommandQueue { unsafe impl Send for CommandQueue {} unsafe impl Sync for CommandQueue {} -impl hal::queue::RawCommandQueue for CommandQueue { +impl queue::CommandQueue for CommandQueue { unsafe fn submit<'a, T, Ic, S, Iw, Is>( &mut self, - submission: hal::queue::Submission, + submission: queue::Submission, fence: Option<&Fence>, ) where T: 'a + Borrow, @@ -842,10 +843,10 @@ impl hal::queue::RawCommandQueue for CommandQueue { &mut self, swapchains: Is, _wait_semaphores: Iw, - ) -> Result, hal::window::PresentError> + ) -> Result, window::PresentError> where W: 'a + Borrow, - Is: IntoIterator, + Is: IntoIterator, S: 'a + Borrow, Iw: IntoIterator, { @@ -1437,7 +1438,7 @@ impl CommandBuffer { } } -impl hal::command::RawCommandBuffer for CommandBuffer { +impl command::CommandBuffer for CommandBuffer { unsafe fn begin( &mut self, _flags: command::CommandBufferFlags, @@ -1472,7 +1473,7 @@ impl hal::command::RawCommandBuffer for CommandBuffer { _first_subpass: command::SubpassContents, ) where T: IntoIterator, - T::Item: Borrow, + T::Item: Borrow, { use pass::AttachmentLoadOp as Alo; @@ -1482,28 +1483,11 @@ impl hal::command::RawCommandBuffer for CommandBuffer { for (idx, attachment) in render_pass.attachments.iter().enumerate() { //let attachment = render_pass.attachments[attachment_ref]; let format = attachment.format.unwrap(); - let channel_type = format.base_format().1; - - fn typed_clear_color(ty: ChannelType, raw_clear: ClearColorRaw) -> ClearColor { - match ty { - ChannelType::Unorm - | ChannelType::Snorm - | ChannelType::Ufloat - | ChannelType::Sfloat - | ChannelType::Uscaled - | ChannelType::Sscaled - | ChannelType::Srgb => ClearColor::Sfloat(unsafe { raw_clear.float32 }), - - ChannelType::Uint => ClearColor::Uint(unsafe { raw_clear.uint32 }), - - ChannelType::Sint => ClearColor::Sint(unsafe { raw_clear.int32 }), - } - } let subpass_id = render_pass.subpasses.iter().position(|sp| sp.is_using(idx)); if attachment.has_clears() { - let raw_clear_value = *clear_iter.next().unwrap().borrow(); + let value = *clear_iter.next().unwrap().borrow(); match (attachment.ops.load, attachment.stencil_ops.load) { (Alo::Clear, Alo::Clear) if format.is_depth() => { @@ -1511,8 +1495,8 @@ impl hal::command::RawCommandBuffer for CommandBuffer { subpass_id, attachment_id: idx, raw: command::AttachmentClear::DepthStencil { - depth: Some(unsafe { raw_clear_value.depth_stencil.depth }), - stencil: Some(unsafe { raw_clear_value.depth_stencil.stencil }), + depth: Some(value.depth_stencil.depth), + stencil: Some(value.depth_stencil.stencil), }, }); } @@ -1522,9 +1506,7 @@ impl hal::command::RawCommandBuffer for CommandBuffer { attachment_id: idx, raw: command::AttachmentClear::Color { index: idx, - value: typed_clear_color(channel_type, unsafe { - raw_clear_value.color - }), + value: value.color, }, }); @@ -1533,7 +1515,7 @@ impl hal::command::RawCommandBuffer for CommandBuffer { attachment_id: idx, raw: command::AttachmentClear::DepthStencil { depth: None, - stencil: Some(unsafe { raw_clear_value.depth_stencil.stencil }), + stencil: Some(value.depth_stencil.stencil), }, }); } @@ -1542,7 +1524,7 @@ impl hal::command::RawCommandBuffer for CommandBuffer { subpass_id, attachment_id: idx, raw: command::AttachmentClear::DepthStencil { - depth: Some(unsafe { raw_clear_value.depth_stencil.depth }), + depth: Some(value.depth_stencil.depth), stencil: None, }, }); @@ -1553,9 +1535,7 @@ impl hal::command::RawCommandBuffer for CommandBuffer { attachment_id: idx, raw: command::AttachmentClear::Color { index: idx, - value: typed_clear_color(channel_type, unsafe { - raw_clear_value.color - }), + value: value.color, }, }); } @@ -1565,7 +1545,7 @@ impl hal::command::RawCommandBuffer for CommandBuffer { attachment_id: idx, raw: command::AttachmentClear::DepthStencil { depth: None, - stencil: Some(unsafe { raw_clear_value.depth_stencil.stencil }), + stencil: Some(value.depth_stencil.stencil), }, }); } @@ -1621,8 +1601,7 @@ impl hal::command::RawCommandBuffer for CommandBuffer { &mut self, image: &Image, _: image::Layout, - color: command::ClearColorRaw, - depth_stencil: command::ClearDepthStencilRaw, + value: command::ClearValue, subresource_ranges: T, ) where T: IntoIterator, @@ -1638,7 +1617,7 @@ impl hal::command::RawCommandBuffer for CommandBuffer { unsafe { self.context.ClearRenderTargetView( image.get_rtv(level, layer).unwrap().as_raw(), - &color.float32, + &value.color.float32, ); } } @@ -1661,8 +1640,8 @@ impl hal::command::RawCommandBuffer for CommandBuffer { self.context.ClearDepthStencilView( image.get_dsv(level, layer).unwrap().as_raw(), depth_stencil_flags, - depth_stencil.depth, - depth_stencil.stencil as _, + value.depth_stencil.depth, + value.depth_stencil.stencil as _, ); } } @@ -2406,7 +2385,7 @@ unsafe impl Send for Memory {} unsafe impl Sync for Memory {} impl Memory { - pub fn resolve>(&self, range: &R) -> Range { + pub fn resolve>(&self, range: &R) -> Range { *range.start().unwrap_or(&0) .. *range.end().unwrap_or(&self.size) } @@ -2503,12 +2482,12 @@ pub struct CommandPool { unsafe impl Send for CommandPool {} unsafe impl Sync for CommandPool {} -impl hal::pool::RawCommandPool for CommandPool { +impl hal::pool::CommandPool for CommandPool { unsafe fn reset(&mut self, _release_resources: bool) { //unimplemented!() } - fn allocate_one(&mut self, _level: command::RawLevel) -> CommandBuffer { + fn allocate_one(&mut self, _level: command::Level) -> CommandBuffer { CommandBuffer::create_deferred(self.device.clone(), self.internal.clone()) } @@ -2985,7 +2964,7 @@ impl DescriptorPool { } } -impl hal::DescriptorPool for DescriptorPool { +impl pso::DescriptorPool for DescriptorPool { unsafe fn allocate_set( &mut self, layout: &DescriptorSetLayout, diff --git a/src/backend/dx12/src/command.rs b/src/backend/dx12/src/command.rs index 22c3f43e4c1..215efefb3a0 100644 --- a/src/backend/dx12/src/command.rs +++ b/src/backend/dx12/src/command.rs @@ -70,7 +70,7 @@ fn up_align(x: u32, alignment: u32) -> u32 { #[derive(Clone, Debug)] struct AttachmentClear { subpass_id: Option, - value: Option, + value: Option, stencil_value: Option, } @@ -565,12 +565,13 @@ impl CommandBuffer { let framebuffer = &state.framebuffer; let subpass = &state.render_pass.subpasses[self.cur_subpass]; - for (&(src_attachment, _), &(dst_attachment, _)) in subpass.color_attachments + for (&(src_attachment, _), &(dst_attachment, _)) in subpass + .color_attachments .iter() .zip(subpass.resolve_attachments.iter()) { if dst_attachment == pass::ATTACHMENT_UNUSED { - continue + continue; } let resolve_src = state.framebuffer.attachments[src_attachment]; @@ -605,7 +606,7 @@ impl CommandBuffer { fn clear_render_target_view( &self, rtv: d3d12::D3D12_CPU_DESCRIPTOR_HANDLE, - color: com::ClearColorRaw, + color: com::ClearColor, rects: &[d3d12::D3D12_RECT], ) { let num_rects = rects.len() as _; @@ -1053,7 +1054,7 @@ impl CommandBuffer { } } -impl com::RawCommandBuffer for CommandBuffer { +impl com::CommandBuffer for CommandBuffer { unsafe fn begin( &mut self, _flags: com::CommandBufferFlags, @@ -1095,7 +1096,7 @@ impl com::RawCommandBuffer for CommandBuffer { _first_subpass: com::SubpassContents, ) where T: IntoIterator, - T::Item: Borrow, + T::Item: Borrow, { assert_eq!(framebuffer.attachments.len(), render_pass.attachments.len()); // Make sure that no subpass works with Present as intermediate layout. @@ -1314,8 +1315,7 @@ impl com::RawCommandBuffer for CommandBuffer { &mut self, image: &r::Image, _: image::Layout, - color: com::ClearColorRaw, - depth_stencil: com::ClearDepthStencilRaw, + value: com::ClearValue, subresource_ranges: T, ) where T: IntoIterator, @@ -1328,15 +1328,20 @@ impl com::RawCommandBuffer for CommandBuffer { for layer in sub.layers.clone() { if sub.aspects.contains(Aspects::COLOR) { let rtv = image.clear_cv[layer as usize]; - self.clear_render_target_view(rtv, color, &[]); + self.clear_render_target_view(rtv, value.color, &[]); } if sub.aspects.contains(Aspects::DEPTH) { let dsv = image.clear_dv[layer as usize]; - self.clear_depth_stencil_view(dsv, Some(depth_stencil.depth), None, &[]); + self.clear_depth_stencil_view(dsv, Some(value.depth_stencil.depth), None, &[]); } if sub.aspects.contains(Aspects::STENCIL) { let dsv = image.clear_sv[layer as usize]; - self.clear_depth_stencil_view(dsv, None, Some(depth_stencil.stencil as _), &[]); + self.clear_depth_stencil_view( + dsv, + None, + Some(value.depth_stencil.stencil as _), + &[], + ); } } } diff --git a/src/backend/dx12/src/conv.rs b/src/backend/dx12/src/conv.rs index e5ba87501cd..4ca08af1b94 100644 --- a/src/backend/dx12/src/conv.rs +++ b/src/backend/dx12/src/conv.rs @@ -14,7 +14,6 @@ use hal::{buffer, image, pso, Primitive}; use native::descriptor::ShaderVisibility; - pub fn map_format(format: Format) -> Option { use hal::format::Format::*; @@ -304,8 +303,7 @@ pub fn map_render_targets( }; let mut targets = [dummy_target; 8]; - for (target, color_desc) in targets.iter_mut().zip(color_targets.iter()) - { + for (target, color_desc) in targets.iter_mut().zip(color_targets.iter()) { target.RenderTargetWriteMask = color_desc.mask.bits() as UINT8; if let Some(ref blend) = color_desc.blend { let (color_op, color_src, color_dst) = map_blend_op(blend.color); diff --git a/src/backend/dx12/src/device.rs b/src/backend/dx12/src/device.rs index c0ba7d76959..974fd7068e2 100644 --- a/src/backend/dx12/src/device.rs +++ b/src/backend/dx12/src/device.rs @@ -14,15 +14,15 @@ use hal::format::Aspects; use hal::memory::Requirements; use hal::pool::CommandPoolCreateFlags; use hal::pso::VertexInputRate; -use hal::queue::{QueueFamilyId, RawCommandQueue}; +use hal::queue::{CommandQueue as _, QueueFamilyId}; use hal::range::RangeArg; use hal::{self, buffer, device as d, error, format, image, mapping, memory, pass, pso, query}; -use native::command_list::IndirectArgument; use descriptor; +use native::command_list::IndirectArgument; use native::pso::{CachedPSO, PipelineStateFlags, PipelineStateSubobject, Subobject}; -use pool::{CommandPoolAllocator, RawCommandPool}; +use pool::{CommandPool, CommandPoolAllocator}; use range_alloc::RangeAllocator; use root_constants::RootConstant; use { @@ -556,7 +556,9 @@ impl Device { return Err(image::ViewError::Level(info.range.levels.start)); } if info.range.layers.end > info.kind.num_layers() { - return Err(image::ViewError::Layer(image::LayerError::OutOfBounds(info.range.layers))); + return Err(image::ViewError::Layer(image::LayerError::OutOfBounds( + info.range.layers, + ))); } match info.view_kind { @@ -662,7 +664,9 @@ impl Device { return Err(image::ViewError::Level(info.range.levels.start)); } if info.range.layers.end > info.kind.num_layers() { - return Err(image::ViewError::Layer(image::LayerError::OutOfBounds(info.range.layers))); + return Err(image::ViewError::Layer(image::LayerError::OutOfBounds( + info.range.layers, + ))); } match info.view_kind { @@ -706,9 +710,7 @@ impl Device { ArraySize, } } - image::ViewKind::D3 | image::ViewKind::Cube | image::ViewKind::CubeArray => { - unimplemented!() - } + image::ViewKind::D3 | image::ViewKind::Cube | image::ViewKind::CubeArray => unimplemented!(), }; unsafe { @@ -744,7 +746,9 @@ impl Device { let ArraySize = (info.range.layers.end - info.range.layers.start) as _; if info.range.layers.end > info.kind.num_layers() { - return Err(image::ViewError::Layer(image::LayerError::OutOfBounds(info.range.layers.clone()))); + return Err(image::ViewError::Layer(image::LayerError::OutOfBounds( + info.range.layers.clone(), + ))); } let is_msaa = info.kind.num_samples() > 1; let is_cube = info.caps.contains(image::ViewCapabilities::KIND_CUBE); @@ -885,7 +889,9 @@ impl Device { let ArraySize = (info.range.layers.end - info.range.layers.start) as _; if info.range.layers.end > info.kind.num_layers() { - return Err(image::ViewError::Layer(image::LayerError::OutOfBounds(info.range.layers))); + return Err(image::ViewError::Layer(image::LayerError::OutOfBounds( + info.range.layers, + ))); } if info.kind.num_samples() > 1 { error!("MSAA images can't be viewed as UAV"); @@ -1067,7 +1073,7 @@ impl d::Device for Device { &self, family: QueueFamilyId, create_flags: CommandPoolCreateFlags, - ) -> Result { + ) -> Result { let list_type = QUEUE_FAMILIES[family.0].native_type(); let allocator = if create_flags.contains(CommandPoolCreateFlags::RESET_INDIVIDUAL) { @@ -1084,7 +1090,7 @@ impl d::Device for Device { CommandPoolAllocator::Shared(command_allocator) }; - Ok(RawCommandPool { + Ok(CommandPool { allocator, device: self.raw, list_type, @@ -1093,7 +1099,7 @@ impl d::Device for Device { }) } - unsafe fn destroy_command_pool(&self, pool: RawCommandPool) { + unsafe fn destroy_command_pool(&self, pool: CommandPool) { pool.destroy(); } @@ -1332,11 +1338,18 @@ impl d::Device for Device { .collect::>(); // guarantees that no re-allocation is done, and our pointers are valid - info!("Creating a pipeline layout with {} sets and {} root constants", sets.len(), root_constants.len()); + info!( + "Creating a pipeline layout with {} sets and {} root constants", + sets.len(), + root_constants.len() + ); let mut parameters = Vec::with_capacity(root_constants.len() + sets.len() * 2); for root_constant in root_constants.iter() { - debug!("\tRoot constant set={} range {:?}", ROOT_CONSTANT_SPACE, root_constant.range); + debug!( + "\tRoot constant set={} range {:?}", + ROOT_CONSTANT_SPACE, root_constant.range + ); parameters.push(descriptor::RootParameter::constants( conv::map_shader_visibility(root_constant.stages), descriptor::Binding { @@ -1381,7 +1394,9 @@ impl d::Device for Device { let visibility = conv::map_shader_visibility( set.bindings .iter() - .fold(pso::ShaderStageFlags::empty(), |u, bind| u | bind.stage_flags) + .fold(pso::ShaderStageFlags::empty(), |u, bind| { + u | bind.stage_flags + }), ); let describe = |bind: &pso::DescriptorSetLayoutBinding, ty| { @@ -2228,7 +2243,10 @@ impl d::Device for Device { //TODO: the clear_Xv is incomplete. We should support clearing images created without XXX_ATTACHMENT usage. // for this, we need to check the format and force the `RENDER_TARGET` flag behind the user's back // if the format supports being rendered into, allowing us to create clear_Xv - let format_properties = self.format_properties.get(image_unbound.format as usize).properties; + let format_properties = self + .format_properties + .get(image_unbound.format as usize) + .properties; let props = match image_unbound.tiling { image::Tiling::Optimal => format_properties.optimal_tiling, image::Tiling::Linear => format_properties.linear_tiling, @@ -2375,12 +2393,12 @@ impl d::Device for Device { }, handle_dsv: if image.usage.contains(image::Usage::DEPTH_STENCIL_ATTACHMENT) { match conv::map_format_dsv(format.base_format().0) { - Some(dsv_format) => { - self.view_image_as_depth_stencil(ViewInfo { + Some(dsv_format) => self + .view_image_as_depth_stencil(ViewInfo { format: dsv_format, ..info - }).ok() - } + }) + .ok(), None => None, } } else { @@ -2468,7 +2486,10 @@ impl d::Device for Device { } } - info!("total {} views and {} samplers", num_srv_cbv_uav, num_samplers); + info!( + "total {} views and {} samplers", + num_srv_cbv_uav, num_samplers + ); let heap_srv_cbv_uav = { let mut heap_srv_cbv_uav = self.heap_srv_cbv_uav.lock().unwrap(); @@ -2554,7 +2575,10 @@ impl d::Device for Device { let mut offset = write.array_offset as u64; let mut target_binding = write.binding as usize; let mut bind_info = &write.set.binding_infos[target_binding]; - debug!("\t{:?} binding {} array offset {}", bind_info, target_binding, offset); + debug!( + "\t{:?} binding {} array offset {}", + bind_info, target_binding, offset + ); for descriptor in write.descriptors { // spill over the writes onto the next binding while offset >= bind_info.count { @@ -2789,9 +2813,17 @@ impl d::Device for Device { dst_views.push(dst_range.at(copy.dst_array_offset as _)); num_views.push(copy.count as u32); - if (src_info.content & dst_info.content).contains(r::DescriptorContent::SRV | r::DescriptorContent::UAV) { - assert!(src_info.count as usize + copy.src_array_offset + copy.count <= src_range.count as usize); - assert!(dst_info.count as usize + copy.dst_array_offset + copy.count <= dst_range.count as usize); + if (src_info.content & dst_info.content) + .contains(r::DescriptorContent::SRV | r::DescriptorContent::UAV) + { + assert!( + src_info.count as usize + copy.src_array_offset + copy.count + <= src_range.count as usize + ); + assert!( + dst_info.count as usize + copy.dst_array_offset + copy.count + <= dst_range.count as usize + ); src_views.push(src_range.at(src_info.count + copy.src_array_offset as u64)); dst_views.push(dst_range.at(dst_info.count + copy.dst_array_offset as u64)); num_views.push(copy.count as u32); @@ -3150,7 +3182,7 @@ impl d::Device for Device { unsafe fn create_swapchain( &self, surface: &mut w::Surface, - config: hal::SwapchainConfig, + config: hal::window::SwapchainConfig, old_swapchain: Option, ) -> Result<(w::Swapchain, Vec), hal::window::CreationError> { if let Some(old_swapchain) = old_swapchain { @@ -3309,7 +3341,6 @@ impl d::Device for Device { } } - #[test] fn test_identity_mapping() { assert_eq!(conv::map_swizzle(format::Swizzle::NO), IDENTITY_MAPPING); diff --git a/src/backend/dx12/src/lib.rs b/src/backend/dx12/src/lib.rs index 2ed21064ccd..66b8010634f 100644 --- a/src/backend/dx12/src/lib.rs +++ b/src/backend/dx12/src/lib.rs @@ -24,10 +24,8 @@ mod root_constants; mod window; use descriptors_cpu::DescriptorCpuPool; -use hal::adapter::DeviceType; use hal::pso::PipelineStage; -use hal::queue::{QueueFamilyId, Queues}; -use hal::{error, format as f, image, memory, Features, Limits, QueueType, SwapImageIndex}; +use hal::{adapter, error, format as f, image, memory, queue as q, Features, Limits}; use winapi::shared::minwindef::TRUE; use winapi::shared::{dxgi, dxgi1_2, dxgi1_3, dxgi1_4, dxgi1_6, winerror}; @@ -128,15 +126,15 @@ pub enum QueueFamily { // It's basically a normal 3D queue but D3D12 swapchain creation requires an // associated queue, which we don't know on `create_swapchain`. Present, - Normal(QueueType), + Normal(q::QueueType), } const MAX_QUEUES: usize = 16; // infinite, to be fair -impl hal::QueueFamily for QueueFamily { - fn queue_type(&self) -> QueueType { +impl q::QueueFamily for QueueFamily { + fn queue_type(&self) -> q::QueueType { match *self { - QueueFamily::Present => QueueType::General, + QueueFamily::Present => q::QueueType::General, QueueFamily::Normal(ty) => ty, } } @@ -146,13 +144,13 @@ impl hal::QueueFamily for QueueFamily { QueueFamily::Normal(_) => MAX_QUEUES, } } - fn id(&self) -> QueueFamilyId { + fn id(&self) -> q::QueueFamilyId { // This must match the order exposed by `QUEUE_FAMILIES` - QueueFamilyId(match *self { + q::QueueFamilyId(match *self { QueueFamily::Present => 0, - QueueFamily::Normal(QueueType::General) => 1, - QueueFamily::Normal(QueueType::Compute) => 2, - QueueFamily::Normal(QueueType::Transfer) => 3, + QueueFamily::Normal(q::QueueType::General) => 1, + QueueFamily::Normal(q::QueueType::Compute) => 2, + QueueFamily::Normal(q::QueueType::Transfer) => 3, _ => unreachable!(), }) } @@ -160,23 +158,23 @@ impl hal::QueueFamily for QueueFamily { impl QueueFamily { fn native_type(&self) -> native::command_list::CmdListType { - use hal::QueueFamily; + use hal::queue::QueueFamily as _; use native::command_list::CmdListType; let queue_type = self.queue_type(); match queue_type { - QueueType::General | QueueType::Graphics => CmdListType::Direct, - QueueType::Compute => CmdListType::Compute, - QueueType::Transfer => CmdListType::Copy, + q::QueueType::General | q::QueueType::Graphics => CmdListType::Direct, + q::QueueType::Compute => CmdListType::Compute, + q::QueueType::Transfer => CmdListType::Copy, } } } static QUEUE_FAMILIES: [QueueFamily; 4] = [ QueueFamily::Present, - QueueFamily::Normal(QueueType::General), - QueueFamily::Normal(QueueType::Compute), - QueueFamily::Normal(QueueType::Transfer), + QueueFamily::Normal(q::QueueType::General), + QueueFamily::Normal(q::QueueType::Compute), + QueueFamily::Normal(q::QueueType::Transfer), ]; #[derive(Derivative)] @@ -190,7 +188,7 @@ pub struct PhysicalDevice { format_properties: Arc, private_caps: Capabilities, heap_properties: &'static [HeapProperties; NUM_HEAP_PROPERTIES], - memory_properties: hal::MemoryProperties, + memory_properties: adapter::MemoryProperties, // Indicates that there is currently an active logical device. // Opening the same adapter multiple times will return the same D3D12Device again. is_open: Arc>, @@ -199,12 +197,12 @@ pub struct PhysicalDevice { unsafe impl Send for PhysicalDevice {} unsafe impl Sync for PhysicalDevice {} -impl hal::PhysicalDevice for PhysicalDevice { +impl adapter::PhysicalDevice for PhysicalDevice { unsafe fn open( &self, - families: &[(&QueueFamily, &[hal::QueuePriority])], + families: &[(&QueueFamily, &[q::QueuePriority])], requested_features: Features, - ) -> Result, error::DeviceCreationError> { + ) -> Result, error::DeviceCreationError> { let lock = self.is_open.try_lock(); let mut open_guard = match lock { Ok(inner) => inner, @@ -237,7 +235,8 @@ impl hal::PhysicalDevice for PhysicalDevice { let queue_groups = families .into_iter() .map(|&(&family, priorities)| { - let mut group = hal::backend::RawQueueGroup::new(family); + use hal::queue::QueueFamily as _; + let mut group = q::QueueGroup::new(family.id()); let create_idle_event = || native::Event::create(true, false); @@ -285,9 +284,9 @@ impl hal::PhysicalDevice for PhysicalDevice { *open_guard = true; - Ok(hal::Gpu { + Ok(adapter::Gpu { device, - queues: Queues::new(queue_groups), + queue_groups, }) } @@ -394,7 +393,7 @@ impl hal::PhysicalDevice for PhysicalDevice { }) } - fn memory_properties(&self) -> hal::MemoryProperties { + fn memory_properties(&self) -> adapter::MemoryProperties { self.memory_properties.clone() } @@ -426,10 +425,10 @@ impl CommandQueue { unsafe impl Send for CommandQueue {} unsafe impl Sync for CommandQueue {} -impl hal::queue::RawCommandQueue for CommandQueue { +impl q::CommandQueue for CommandQueue { unsafe fn submit<'a, T, Ic, S, Iw, Is>( &mut self, - submission: hal::queue::Submission, + submission: q::Submission, fence: Option<&resource::Fence>, ) where T: 'a + Borrow, @@ -464,7 +463,7 @@ impl hal::queue::RawCommandQueue for CommandQueue { ) -> Result, hal::window::PresentError> where W: 'a + Borrow, - Is: IntoIterator, + Is: IntoIterator, S: 'a + Borrow, Iw: IntoIterator, { @@ -751,7 +750,7 @@ impl Instance { impl hal::Instance for Instance { type Backend = Backend; - fn enumerate_adapters(&self) -> Vec> { + fn enumerate_adapters(&self) -> Vec> { use self::memory::Properties; // Try to use high performance order by default (returns None on Windows < 1803) @@ -835,14 +834,14 @@ impl hal::Instance for Instance { name.to_string_lossy().into_owned() }; - let info = hal::AdapterInfo { + let info = adapter::AdapterInfo { name: device_name, vendor: desc.VendorId as usize, device: desc.DeviceId as usize, device_type: if (desc.Flags & dxgi::DXGI_ADAPTER_FLAG_SOFTWARE) != 0 { - DeviceType::VirtualGpu + adapter::DeviceType::VirtualGpu } else { - DeviceType::DiscreteGpu + adapter::DeviceType::DiscreteGpu }, }; @@ -895,21 +894,21 @@ impl hal::Instance for Instance { }; // https://msdn.microsoft.com/en-us/library/windows/desktop/dn788678(v=vs.85).aspx - let base_memory_types: [hal::MemoryType; NUM_HEAP_PROPERTIES] = + let base_memory_types: [adapter::MemoryType; NUM_HEAP_PROPERTIES] = match memory_architecture { MemoryArchitecture::NUMA => [ // DEFAULT - hal::MemoryType { + adapter::MemoryType { properties: Properties::DEVICE_LOCAL, heap_index: 0, }, // UPLOAD - hal::MemoryType { + adapter::MemoryType { properties: Properties::CPU_VISIBLE | Properties::COHERENT, heap_index: 1, }, // READBACK - hal::MemoryType { + adapter::MemoryType { properties: Properties::CPU_VISIBLE | Properties::COHERENT | Properties::CPU_CACHED, @@ -918,19 +917,19 @@ impl hal::Instance for Instance { ], MemoryArchitecture::UMA => [ // DEFAULT - hal::MemoryType { + adapter::MemoryType { properties: Properties::DEVICE_LOCAL, heap_index: 0, }, // UPLOAD - hal::MemoryType { + adapter::MemoryType { properties: Properties::DEVICE_LOCAL | Properties::CPU_VISIBLE | Properties::COHERENT, heap_index: 0, }, // READBACK - hal::MemoryType { + adapter::MemoryType { properties: Properties::DEVICE_LOCAL | Properties::CPU_VISIBLE | Properties::COHERENT @@ -940,12 +939,12 @@ impl hal::Instance for Instance { ], MemoryArchitecture::CacheCoherentUMA => [ // DEFAULT - hal::MemoryType { + adapter::MemoryType { properties: Properties::DEVICE_LOCAL, heap_index: 0, }, // UPLOAD - hal::MemoryType { + adapter::MemoryType { properties: Properties::DEVICE_LOCAL | Properties::CPU_VISIBLE | Properties::COHERENT @@ -953,7 +952,7 @@ impl hal::Instance for Instance { heap_index: 0, }, // READBACK - hal::MemoryType { + adapter::MemoryType { properties: Properties::DEVICE_LOCAL | Properties::CPU_VISIBLE | Properties::COHERENT @@ -1104,7 +1103,7 @@ impl hal::Instance for Instance { memory_architecture, }, heap_properties, - memory_properties: hal::MemoryProperties { + memory_properties: adapter::MemoryProperties { memory_types, memory_heaps, }, @@ -1113,7 +1112,7 @@ impl hal::Instance for Instance { let queue_families = QUEUE_FAMILIES.to_vec(); - adapters.push(hal::Adapter { + adapters.push(adapter::Adapter { info, physical_device, queue_families, @@ -1137,7 +1136,7 @@ impl hal::Backend for Backend { type CommandBuffer = command::CommandBuffer; type Memory = resource::Memory; - type CommandPool = pool::RawCommandPool; + type CommandPool = pool::CommandPool; type ShaderModule = resource::ShaderModule; type RenderPass = resource::RenderPass; @@ -1177,10 +1176,7 @@ struct FormatInfo { } #[derive(Debug)] -pub struct FormatProperties( - Box<[Mutex>]>, - native::Device, -); +pub struct FormatProperties(Box<[Mutex>]>, native::Device); impl Drop for FormatProperties { fn drop(&mut self) { @@ -1294,7 +1290,7 @@ impl FormatProperties { for i in 0 .. 6 { let mut data = d3d12::D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS { Format: dxgi_format, - SampleCount: 1< (native::GraphicsCommandList, native::CommandAllocator) { let command_allocator = match self.allocator { CommandPoolAllocator::Shared(ref allocator) => allocator.clone(), @@ -77,10 +77,10 @@ impl RawCommandPool { } } -unsafe impl Send for RawCommandPool {} -unsafe impl Sync for RawCommandPool {} +unsafe impl Send for CommandPool {} +unsafe impl Sync for CommandPool {} -impl pool::RawCommandPool for RawCommandPool { +impl pool::CommandPool for CommandPool { unsafe fn reset(&mut self, _release_resources: bool) { match self.allocator { CommandPoolAllocator::Shared(ref allocator) => { @@ -94,9 +94,9 @@ impl pool::RawCommandPool for RawCommandPool { } } - fn allocate_one(&mut self, level: command::RawLevel) -> CommandBuffer { + fn allocate_one(&mut self, level: command::Level) -> CommandBuffer { // TODO: Implement secondary buffers - assert_eq!(level, command::RawLevel::Primary); + assert_eq!(level, command::Level::Primary); let (command_list, command_allocator) = self.create_command_list(); CommandBuffer::new( command_list, diff --git a/src/backend/dx12/src/resource.rs b/src/backend/dx12/src/resource.rs index e4f3d6d6fe7..983717241c6 100644 --- a/src/backend/dx12/src/resource.rs +++ b/src/backend/dx12/src/resource.rs @@ -2,14 +2,11 @@ use winapi::shared::dxgiformat::DXGI_FORMAT; use winapi::shared::minwindef::UINT; use winapi::um::d3d12; -use hal::{buffer, format, image, memory, pass, pso, DescriptorPool as HalDescriptorPool}; +use hal::{buffer, format, image, memory, pass, pso}; use native::{self, query}; use range_alloc::RangeAllocator; -use crate::{ - root_constants::RootConstant, - Backend, MAX_VERTEX_BUFFERS, -}; +use crate::{root_constants::RootConstant, Backend, MAX_VERTEX_BUFFERS}; use std::collections::BTreeMap; use std::ops::Range; @@ -409,27 +406,16 @@ impl From for DescriptorContent { fn from(ty: pso::DescriptorType) -> Self { use hal::pso::DescriptorType as Dt; match ty { - Dt::Sampler => { - DescriptorContent::SAMPLER - } - Dt::CombinedImageSampler => { - DescriptorContent::SRV | DescriptorContent::SAMPLER - } - Dt::SampledImage | - Dt::InputAttachment | - Dt::UniformTexelBuffer => { + Dt::Sampler => DescriptorContent::SAMPLER, + Dt::CombinedImageSampler => DescriptorContent::SRV | DescriptorContent::SAMPLER, + Dt::SampledImage | Dt::InputAttachment | Dt::UniformTexelBuffer => { DescriptorContent::SRV } - Dt::StorageImage | - Dt::StorageBuffer | - Dt::StorageBufferDynamic | - Dt::StorageTexelBuffer => { - DescriptorContent::SRV | DescriptorContent::UAV - } - Dt::UniformBuffer | - Dt::UniformBufferDynamic => { - DescriptorContent::CBV - } + Dt::StorageImage + | Dt::StorageBuffer + | Dt::StorageBufferDynamic + | Dt::StorageTexelBuffer => DescriptorContent::SRV | DescriptorContent::UAV, + Dt::UniformBuffer | Dt::UniformBufferDynamic => DescriptorContent::CBV, } } } @@ -578,7 +564,7 @@ pub struct DescriptorPool { unsafe impl Send for DescriptorPool {} unsafe impl Sync for DescriptorPool {} -impl HalDescriptorPool for DescriptorPool { +impl pso::DescriptorPool for DescriptorPool { unsafe fn allocate_set( &mut self, layout: &DescriptorSetLayout, @@ -597,7 +583,8 @@ impl HalDescriptorPool for DescriptorPool { binding_infos[binding.binding as usize] = DescriptorBindingInfo { count: binding.count as _, view_range: if content.intersects(DescriptorContent::VIEW) { - let count = if content.contains(DescriptorContent::SRV | DescriptorContent::UAV) { + let count = if content.contains(DescriptorContent::SRV | DescriptorContent::UAV) + { 2 * binding.count as u64 } else { binding.count as u64 diff --git a/src/backend/dx12/src/window.rs b/src/backend/dx12/src/window.rs index 7dcf709c001..5f8266b0132 100644 --- a/src/backend/dx12/src/window.rs +++ b/src/backend/dx12/src/window.rs @@ -8,7 +8,7 @@ use winapi::shared::dxgi1_4; use winapi::shared::windef::{HWND, RECT}; use winapi::um::winuser::GetClientRect; -use hal::{self, format as f, image as i, CompositeAlpha}; +use hal::{format as f, image as i, window as w}; use {native, resource as r, Backend, Instance, PhysicalDevice, QueueFamily}; use std::os::raw::c_void; @@ -54,7 +54,7 @@ impl Surface { } } -impl hal::Surface for Surface { +impl w::Surface for Surface { fn supports_queue_family(&self, queue_family: &QueueFamily) -> bool { match queue_family { &QueueFamily::Present => true, @@ -66,20 +66,20 @@ impl hal::Surface for Surface { &self, _: &PhysicalDevice, ) -> ( - hal::SurfaceCapabilities, + w::SurfaceCapabilities, Option>, - Vec, + Vec, ) { let (width, height) = self.get_extent(); - let extent = hal::window::Extent2D { width, height }; + let extent = w::Extent2D { width, height }; - let capabilities = hal::SurfaceCapabilities { + let capabilities = w::SurfaceCapabilities { image_count: 2 ..= 16, // we currently use a flip effect which supports 2..=16 buffers current_extent: Some(extent), extents: extent ..= extent, max_image_layers: 1, usage: i::Usage::COLOR_ATTACHMENT | i::Usage::TRANSFER_SRC | i::Usage::TRANSFER_DST, - composite_alpha: CompositeAlpha::OPAQUE, //TODO + composite_alpha: w::CompositeAlpha::OPAQUE, //TODO }; // Sticking to FLIP swap effects for the moment. @@ -95,7 +95,7 @@ impl hal::Surface for Surface { ]; let present_modes = vec![ - hal::PresentMode::Fifo, //TODO + w::PresentMode::Fifo, //TODO ]; (capabilities, Some(formats), present_modes) @@ -114,13 +114,13 @@ pub struct Swapchain { pub(crate) resources: Vec, } -impl hal::Swapchain for Swapchain { +impl w::Swapchain for Swapchain { unsafe fn acquire_image( &mut self, _timout_ns: u64, _semaphore: Option<&r::Semaphore>, _fence: Option<&r::Fence>, - ) -> Result<(hal::SwapImageIndex, Option), hal::AcquireError> { + ) -> Result<(w::SwapImageIndex, Option), w::AcquireError> { // TODO: sync if false { diff --git a/src/backend/empty/src/lib.rs b/src/backend/empty/src/lib.rs index 14acc5a5763..1e64fa2c5be 100644 --- a/src/backend/empty/src/lib.rs +++ b/src/backend/empty/src/lib.rs @@ -7,6 +7,7 @@ extern crate winit; use crate::hal::range::RangeArg; use crate::hal::{ + adapter, buffer, command, device, @@ -36,11 +37,11 @@ impl hal::Backend for Backend { type Swapchain = Swapchain; type QueueFamily = QueueFamily; - type CommandQueue = RawCommandQueue; - type CommandBuffer = RawCommandBuffer; + type CommandQueue = CommandQueue; + type CommandBuffer = CommandBuffer; type Memory = (); - type CommandPool = RawCommandPool; + type CommandPool = CommandPool; type ShaderModule = (); type RenderPass = (); @@ -69,12 +70,12 @@ impl hal::Backend for Backend { /// Dummy physical device. #[derive(Debug)] pub struct PhysicalDevice; -impl hal::PhysicalDevice for PhysicalDevice { +impl adapter::PhysicalDevice for PhysicalDevice { unsafe fn open( &self, - _: &[(&QueueFamily, &[hal::QueuePriority])], + _: &[(&QueueFamily, &[queue::QueuePriority])], _: hal::Features, - ) -> Result, error::DeviceCreationError> { + ) -> Result, error::DeviceCreationError> { unimplemented!() } @@ -93,7 +94,7 @@ impl hal::PhysicalDevice for PhysicalDevice { unimplemented!() } - fn memory_properties(&self) -> hal::MemoryProperties { + fn memory_properties(&self) -> adapter::MemoryProperties { unimplemented!() } @@ -108,14 +109,14 @@ impl hal::PhysicalDevice for PhysicalDevice { /// Dummy command queue doing nothing. #[derive(Debug)] -pub struct RawCommandQueue; -impl queue::RawCommandQueue for RawCommandQueue { +pub struct CommandQueue; +impl queue::CommandQueue for CommandQueue { unsafe fn submit<'a, T, Ic, S, Iw, Is>( &mut self, _: queue::Submission, _: Option<&()>, ) where - T: 'a + Borrow, + T: 'a + Borrow, Ic: IntoIterator, S: 'a + Borrow<()>, Iw: IntoIterator, @@ -131,7 +132,7 @@ impl queue::RawCommandQueue for RawCommandQueue { ) -> Result, window::PresentError> where W: 'a + Borrow, - Is: IntoIterator, + Is: IntoIterator, S: 'a + Borrow<()>, Iw: IntoIterator, { @@ -146,16 +147,16 @@ impl queue::RawCommandQueue for RawCommandQueue { /// Dummy device doing nothing. #[derive(Debug)] pub struct Device; -impl hal::Device for Device { +impl device::Device for Device { unsafe fn create_command_pool( &self, _: queue::QueueFamilyId, _: pool::CommandPoolCreateFlags, - ) -> Result { + ) -> Result { unimplemented!() } - unsafe fn destroy_command_pool(&self, _: RawCommandPool) { + unsafe fn destroy_command_pool(&self, _: CommandPool) { unimplemented!() } @@ -491,7 +492,7 @@ impl hal::Device for Device { unsafe fn create_swapchain( &self, _: &mut Surface, - _: hal::SwapchainConfig, + _: window::SwapchainConfig, _: Option, ) -> Result<(Swapchain, Vec<()>), hal::window::CreationError> { unimplemented!() @@ -509,7 +510,7 @@ impl hal::Device for Device { #[derive(Debug)] pub struct QueueFamily; impl queue::QueueFamily for QueueFamily { - fn queue_type(&self) -> hal::QueueType { + fn queue_type(&self) -> queue::QueueType { unimplemented!() } fn max_queues(&self) -> usize { @@ -522,15 +523,15 @@ impl queue::QueueFamily for QueueFamily { /// Dummy raw command pool. #[derive(Debug)] -pub struct RawCommandPool; -impl pool::RawCommandPool for RawCommandPool { +pub struct CommandPool; +impl pool::CommandPool for CommandPool { unsafe fn reset(&mut self, _: bool) { unimplemented!() } unsafe fn free(&mut self, _: I) where - I: IntoIterator, + I: IntoIterator, { unimplemented!() } @@ -538,8 +539,8 @@ impl pool::RawCommandPool for RawCommandPool { /// Dummy command buffer, which ignores all the calls. #[derive(Debug)] -pub struct RawCommandBuffer; -impl command::RawCommandBuffer for RawCommandBuffer { +pub struct CommandBuffer; +impl command::CommandBuffer for CommandBuffer { unsafe fn begin( &mut self, _: command::CommandBufferFlags, @@ -579,14 +580,8 @@ impl command::RawCommandBuffer for RawCommandBuffer { unimplemented!() } - unsafe fn clear_image( - &mut self, - _: &(), - _: image::Layout, - _: command::ClearColorRaw, - _: command::ClearDepthStencilRaw, - _: T, - ) where + unsafe fn clear_image(&mut self, _: &(), _: image::Layout, _: command::ClearValue, _: T) + where T: IntoIterator, T::Item: Borrow, { @@ -691,7 +686,7 @@ impl command::RawCommandBuffer for RawCommandBuffer { _: command::SubpassContents, ) where T: IntoIterator, - T::Item: Borrow, + T::Item: Borrow, { unimplemented!() } @@ -861,7 +856,7 @@ impl command::RawCommandBuffer for RawCommandBuffer { unsafe fn execute_commands<'a, T, I>(&mut self, _: I) where - T: 'a + Borrow, + T: 'a + Borrow, I: IntoIterator, { unimplemented!() @@ -887,14 +882,14 @@ impl pso::DescriptorPool for DescriptorPool { /// Dummy surface. #[derive(Debug)] pub struct Surface; -impl hal::Surface for Surface { +impl window::Surface for Surface { fn compatibility( &self, _: &PhysicalDevice, ) -> ( - hal::SurfaceCapabilities, + window::SurfaceCapabilities, Option>, - Vec, + Vec, ) { unimplemented!() } @@ -907,13 +902,13 @@ impl hal::Surface for Surface { /// Dummy swapchain. #[derive(Debug)] pub struct Swapchain; -impl hal::Swapchain for Swapchain { +impl window::Swapchain for Swapchain { unsafe fn acquire_image( &mut self, _: u64, _: Option<&()>, _: Option<&()>, - ) -> Result<(hal::SwapImageIndex, Option), hal::AcquireError> { + ) -> Result<(window::SwapImageIndex, Option), window::AcquireError> { unimplemented!() } } @@ -935,7 +930,7 @@ impl Instance { impl hal::Instance for Instance { type Backend = Backend; - fn enumerate_adapters(&self) -> Vec> { + fn enumerate_adapters(&self) -> Vec> { vec![] } } diff --git a/src/backend/gl/src/command.rs b/src/backend/gl/src/command.rs index abe74df0f9a..857bb1c1adc 100644 --- a/src/backend/gl/src/command.rs +++ b/src/backend/gl/src/command.rs @@ -140,7 +140,7 @@ pub enum Command { src_image: n::ImageKind, dst_surface: n::Surface, dst_format: n::TextureFormat, - data: command::ImageCopy + data: command::ImageCopy, }, BindBufferRange(u32, u32, n::RawBuffer, i32, i32), @@ -157,7 +157,7 @@ pub type DrawBuffer = u32; struct AttachmentClear { subpass_id: pass::SubpassId, index: u32, - value: command::ClearValueRaw, + value: command::ClearValue, } #[derive(Debug)] @@ -239,7 +239,7 @@ impl From for Limits { /// If you want to display your rendered results to a framebuffer created externally, see the /// `display_fb` field. #[derive(Debug)] -pub struct RawCommandBuffer { +pub struct CommandBuffer { pub(crate) memory: Arc>, pub(crate) buf: BufferSlice, // Buffer id for the owning command pool. @@ -267,7 +267,7 @@ pub struct RawCommandBuffer { active_attribs: usize, } -impl RawCommandBuffer { +impl CommandBuffer { pub(crate) fn new( fbo: Option, limits: Limits, @@ -293,7 +293,7 @@ impl RawCommandBuffer { } }; - RawCommandBuffer { + CommandBuffer { memory, buf: BufferSlice::new(), id, @@ -479,10 +479,14 @@ impl RawCommandBuffer { // Clear color target if view_format.is_color() { - assert!(clear.index >= glow::COLOR_ATTACHMENT0 && clear.index <= glow::COLOR_ATTACHMENT31); + assert!( + clear.index >= glow::COLOR_ATTACHMENT0 + && clear.index <= glow::COLOR_ATTACHMENT31 + ); assert_eq!(attachment.ops.load, pass::AttachmentLoadOp::Clear); let channel = view_format.base_format().1; + let index = clear.index - glow::COLOR_ATTACHMENT0; let cmd = match channel { ChannelType::Unorm @@ -491,28 +495,32 @@ impl RawCommandBuffer { | ChannelType::Sfloat | ChannelType::Srgb | ChannelType::Uscaled - | ChannelType::Sscaled => { - Command::ClearBufferColorF(clear.index - glow::COLOR_ATTACHMENT0, unsafe { clear.value.color.float32 }) - } - ChannelType::Uint => { - Command::ClearBufferColorU(clear.index - glow::COLOR_ATTACHMENT0, unsafe { clear.value.color.uint32 }) - } - ChannelType::Sint => { - Command::ClearBufferColorI(clear.index - glow::COLOR_ATTACHMENT0, unsafe { clear.value.color.int32 }) - } + | ChannelType::Sscaled => Command::ClearBufferColorF(index, unsafe { + clear.value.color.float32 + }), + ChannelType::Uint => Command::ClearBufferColorU(index, unsafe { + clear.value.color.uint32 + }), + ChannelType::Sint => Command::ClearBufferColorI(index, unsafe { + clear.value.color.sint32 + }), }; return Some(cmd); } // Clear depth-stencil target - let depth = if view_format.is_depth() && attachment.ops.load == pass::AttachmentLoadOp::Clear { + let depth = if view_format.is_depth() + && attachment.ops.load == pass::AttachmentLoadOp::Clear + { Some(unsafe { clear.value.depth_stencil.depth }) } else { None }; - let stencil = if view_format.is_stencil() && attachment.stencil_ops.load == pass::AttachmentLoadOp::Clear { + let stencil = if view_format.is_stencil() + && attachment.stencil_ops.load == pass::AttachmentLoadOp::Clear + { Some(unsafe { clear.value.depth_stencil.stencil }) } else { None @@ -543,11 +551,11 @@ impl RawCommandBuffer { } } -impl command::RawCommandBuffer for RawCommandBuffer { +impl command::CommandBuffer for CommandBuffer { unsafe fn begin( &mut self, - _flags: hal::command::CommandBufferFlags, - _inheritance_info: hal::command::CommandBufferInheritanceInfo, + _flags: command::CommandBufferFlags, + _inheritance_info: command::CommandBufferInheritanceInfo, ) { // TODO: Implement flags! if self.individual_reset { @@ -591,7 +599,7 @@ impl command::RawCommandBuffer for RawCommandBuffer { unsafe fn pipeline_barrier<'a, T>( &mut self, - _stages: Range, + _stages: Range, _dependencies: memory::Dependencies, _barriers: T, ) where @@ -621,7 +629,7 @@ impl command::RawCommandBuffer for RawCommandBuffer { _first_subpass: command::SubpassContents, ) where T: IntoIterator, - T::Item: Borrow, + T::Item: Borrow, { // TODO: load ops: clearing strategy // 1. < GL 3.0 / GL ES 2.0: glClear, only single color attachment? @@ -650,10 +658,15 @@ impl command::RawCommandBuffer for RawCommandBuffer { return None; }; - let (subpass, index) = render_pass.subpasses.iter().enumerate().filter_map(|(i, sp)| { - let index = sp.attachment_using(id)?; - Some((i, index)) - }).next()?; + let (subpass, index) = render_pass + .subpasses + .iter() + .enumerate() + .filter_map(|(i, sp)| { + let index = sp.attachment_using(id)?; + Some((i, index)) + }) + .next()?; Some(AttachmentClear { subpass_id: subpass, index, @@ -685,8 +698,7 @@ impl command::RawCommandBuffer for RawCommandBuffer { &mut self, image: &n::Image, _: image::Layout, - color: command::ClearColorRaw, - _depth_stencil: command::ClearDepthStencilRaw, + value: command::ClearValue, _subresource_ranges: T, ) where T: IntoIterator, @@ -696,6 +708,7 @@ impl command::RawCommandBuffer for RawCommandBuffer { // 1. < GL 3.0 / GL ES 3.0: glClear // 2. < GL 4.4: glClearBuffer // 3. >= GL 4.4: glClearTexSubImage + let color = value.color; match self.fbo { Some(fbo) => { @@ -728,7 +741,7 @@ impl command::RawCommandBuffer for RawCommandBuffer { self.push_cmd(Command::ClearBufferColorF(0, color.float32)) } ChannelType::Uint => self.push_cmd(Command::ClearBufferColorU(0, color.uint32)), - ChannelType::Sint => self.push_cmd(Command::ClearBufferColorI(0, color.int32)), + ChannelType::Sint => self.push_cmd(Command::ClearBufferColorI(0, color.sint32)), } } None => { @@ -1016,10 +1029,7 @@ impl command::RawCommandBuffer for RawCommandBuffer { n::BindingTypes::StorageBuffers => glow::SHADER_STORAGE_BUFFER, n::BindingTypes::Images => panic!("Wrong desc set binding"), }; - for binding in drd - .get_binding(*btype, set, *binding) - .unwrap() - { + for binding in drd.get_binding(*btype, set, *binding).unwrap() { self.push_cmd(Command::BindBufferRange( glow_btype, *binding, @@ -1165,7 +1175,7 @@ impl command::RawCommandBuffer for RawCommandBuffer { src_image: src.kind, dst_surface: surface, dst_format: format, - data: r + data: r, }, n::ImageKind::Texture { texture, target, .. @@ -1196,8 +1206,9 @@ impl command::RawCommandBuffer for RawCommandBuffer { let mut r = region.borrow().clone(); r.buffer_offset += src_range.start; let cmd = match dst.kind { - n::ImageKind::Surface { surface, .. } => - Command::CopyBufferToSurface(src_raw, surface, r), + n::ImageKind::Surface { surface, .. } => { + Command::CopyBufferToSurface(src_raw, surface, r) + } n::ImageKind::Texture { texture, target, @@ -1237,8 +1248,9 @@ impl command::RawCommandBuffer for RawCommandBuffer { let mut r = region.borrow().clone(); r.buffer_offset += dst_range.start; let cmd = match src.kind { - n::ImageKind::Surface { surface, .. } => - Command::CopySurfaceToBuffer(surface, dst_raw, r), + n::ImageKind::Surface { surface, .. } => { + Command::CopySurfaceToBuffer(surface, dst_raw, r) + } n::ImageKind::Texture { texture, target, @@ -1435,7 +1447,7 @@ impl command::RawCommandBuffer for RawCommandBuffer { unsafe fn execute_commands<'a, T, I>(&mut self, _buffers: I) where - T: 'a + Borrow, + T: 'a + Borrow, I: IntoIterator, { unimplemented!() diff --git a/src/backend/gl/src/device.rs b/src/backend/gl/src/device.rs index 43036657239..20f49ae5021 100644 --- a/src/backend/gl/src/device.rs +++ b/src/backend/gl/src/device.rs @@ -4,34 +4,44 @@ use std::ops::Range; use std::slice; use std::sync::{Arc, Mutex, RwLock}; -use crate::{GlContainer, GlContext}; use glow::Context; -use crate::hal::backend::FastHashMap; -use crate::hal::format::{Format, Swizzle}; -use crate::hal::pool::CommandPoolCreateFlags; -use crate::hal::queue::QueueFamilyId; -use crate::hal::range::RangeArg; -use crate::hal::window::Extent2D; -use crate::hal::{ +use hal::{ self as c, + backend::FastHashMap, buffer, device as d, error, + format::{Format, Swizzle}, image as i, mapping, memory, pass, + pool::CommandPoolCreateFlags, pso, query, + queue, + range::RangeArg, + window::{Extent2D, SwapchainConfig}, }; use spirv_cross::{glsl, spirv, ErrorCode as SpirvErrorCode}; -use crate::info::LegacyFeatures; -use crate::pool::{BufferMemory, OwnedBuffer, RawCommandPool}; -use crate::{conv, native as n, state}; -use crate::{Backend as B, MemoryUsage, Share, Starc, Surface, Swapchain}; +use crate::{ + conv, + info::LegacyFeatures, + native as n, + pool::{BufferMemory, CommandPool, OwnedBuffer}, + state, + Backend as B, + GlContainer, + GlContext, + MemoryUsage, + Share, + Starc, + Surface, + Swapchain, +}; /// Emit error during shader module creation. Used if we don't expect an error /// but might panic due to an exception in SPIRV-Cross. @@ -586,9 +596,9 @@ impl d::Device for Device { unsafe fn create_command_pool( &self, - _family: QueueFamilyId, + _family: queue::QueueFamilyId, flags: CommandPoolCreateFlags, - ) -> Result { + ) -> Result { let fbo = create_fbo_internal(&self.share); let limits = self.share.limits.into(); let memory = if flags.contains(CommandPoolCreateFlags::RESET_INDIVIDUAL) { @@ -602,14 +612,14 @@ impl d::Device for Device { // Ignoring `TRANSIENT` hint, unsure how to make use of this. - Ok(RawCommandPool { + Ok(CommandPool { fbo, limits, memory: Arc::new(Mutex::new(memory)), }) } - unsafe fn destroy_command_pool(&self, pool: RawCommandPool) { + unsafe fn destroy_command_pool(&self, pool: CommandPool) { if let Some(fbo) = pool.fbo { let gl = &self.share.context; gl.delete_framebuffer(fbo); @@ -634,7 +644,10 @@ impl d::Device for Device { .into_iter() .map(|subpass| { let subpass = subpass.borrow(); - assert!(subpass.colors.len() <= self.share.limits.max_color_attachments, "Color attachment limit exceeded"); + assert!( + subpass.colors.len() <= self.share.limits.max_color_attachments, + "Color attachment limit exceeded" + ); let color_attachments = subpass.colors.iter().map(|&(index, _)| index).collect(); let depth_stencil = subpass.depth_stencil.map(|ds| ds.0); @@ -708,8 +721,7 @@ impl d::Device for Device { ); } StorageImage | UniformTexelBuffer | UniformBufferDynamic - | StorageTexelBuffer | StorageBufferDynamic - | InputAttachment => unimplemented!(), // 6 + | StorageTexelBuffer | StorageBufferDynamic | InputAttachment => unimplemented!(), // 6 } }) }); @@ -1026,9 +1038,7 @@ impl d::Device for Device { gl.bind_framebuffer(target, None); - Ok(n::FrameBuffer { - fbos, - }) + Ok(n::FrameBuffer { fbos }) } unsafe fn create_shader_module( @@ -1394,7 +1404,10 @@ impl d::Device for Device { } _ => unimplemented!(), }; - n::ImageKind::Surface { surface: name, format: iformat } + n::ImageKind::Surface { + surface: name, + format: iformat, + } }; let surface_desc = format.base_format().0.desc(); @@ -1857,7 +1870,7 @@ impl d::Device for Device { unsafe fn create_swapchain( &self, surface: &mut Surface, - config: c::SwapchainConfig, + config: SwapchainConfig, _old_swapchain: Option, ) -> Result<(Swapchain, Vec), c::window::CreationError> { let gl = &self.share.context; @@ -1941,7 +1954,10 @@ impl d::Device for Device { fbos, extent: config.extent, context: { - surface.context().resize(glutin::dpi::PhysicalSize::new(config.extent.width as f64, config.extent.height as f64)); + surface.context().resize(glutin::dpi::PhysicalSize::new( + config.extent.width as f64, + config.extent.height as f64, + )); surface.context.clone() }, }; @@ -1954,7 +1970,10 @@ impl d::Device for Device { #[cfg(not(any(target_arch = "wasm32", feature = "glutin", feature = "wgl")))] let swapchain = Swapchain { - extent: { let _ = surface; config.extent }, + extent: { + let _ = surface; + config.extent + }, fbos, }; diff --git a/src/backend/gl/src/info.rs b/src/backend/gl/src/info.rs index 4de6109cdd1..4768d5c6dc9 100644 --- a/src/backend/gl/src/info.rs +++ b/src/backend/gl/src/info.rs @@ -357,8 +357,13 @@ pub(crate) fn query_all(gl: &GlContainer) -> (Info, Features, LegacyFeatures, Li optimal_buffer_copy_offset_alignment: 1, optimal_buffer_copy_pitch_alignment: 1, min_texel_buffer_offset_alignment: 1, - min_uniform_buffer_offset_alignment: get_u64(gl, glow::UNIFORM_BUFFER_OFFSET_ALIGNMENT).unwrap_or(1024), - min_storage_buffer_offset_alignment: get_u64(gl, glow::SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT).unwrap_or(1024), + min_uniform_buffer_offset_alignment: get_u64(gl, glow::UNIFORM_BUFFER_OFFSET_ALIGNMENT) + .unwrap_or(1024), + min_storage_buffer_offset_alignment: get_u64( + gl, + glow::SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT, + ) + .unwrap_or(1024), framebuffer_color_sample_counts: max_samples_mask, non_coherent_atom_size: 1, max_color_attachments: get_usize(gl, glow::MAX_COLOR_ATTACHMENTS).unwrap_or(1), @@ -373,11 +378,7 @@ pub(crate) fn query_all(gl: &GlContainer) -> (Info, Features, LegacyFeatures, Li limits.max_viewports = get_usize(gl, glow::MAX_VIEWPORTS).unwrap_or(0); } - if info.is_supported(&[ - Core(4, 3), - Ext("GL_ARB_compute_shader"), - ]) - { + if info.is_supported(&[Core(4, 3), Ext("GL_ARB_compute_shader")]) { for (i, (count, size)) in limits .max_compute_work_group_count .iter_mut() diff --git a/src/backend/gl/src/lib.rs b/src/backend/gl/src/lib.rs index be6fdd5b443..182bd94500a 100644 --- a/src/backend/gl/src/lib.rs +++ b/src/backend/gl/src/lib.rs @@ -17,8 +17,7 @@ use std::ops::Deref; use std::sync::{Arc, Weak}; use std::thread::{self, ThreadId}; -use crate::hal::queue::{QueueFamilyId, Queues}; -use crate::hal::{buffer, error, image, memory, pso}; +use crate::hal::{adapter, buffer, error, image, memory, pso, queue as q}; pub use self::device::Device; pub use self::info::{Info, PlatformName, Version}; @@ -53,7 +52,6 @@ pub use glow::web::Context as GlContext; use glow::Context; - pub(crate) struct GlContainer { context: GlContext, } @@ -135,10 +133,10 @@ impl hal::Backend for Backend { type QueueFamily = QueueFamily; type CommandQueue = queue::CommandQueue; - type CommandBuffer = command::RawCommandBuffer; + type CommandBuffer = command::CommandBuffer; type Memory = native::Memory; - type CommandPool = pool::RawCommandPool; + type CommandPool = pool::CommandPool; type ShaderModule = native::ShaderModule; type RenderPass = native::RenderPass; @@ -258,7 +256,7 @@ struct Share { private_caps: info::PrivateCaps, // Indicates if there is an active logical device. open: Cell, - memory_types: Vec<(hal::MemoryType, MemoryUsage)>, + memory_types: Vec<(adapter::MemoryType, MemoryUsage)>, } impl Share { @@ -401,7 +399,7 @@ type DeviceContext = (); impl PhysicalDevice { #[allow(unused)] - fn new_adapter(instance_context: DeviceContext, gl: GlContainer) -> hal::Adapter { + fn new_adapter(instance_context: DeviceContext, gl: GlContainer) -> adapter::Adapter { // query information let (info, features, legacy_features, limits, private_caps) = info::query_all(&gl); info!("Vendor: {:?}", info.platform_name.vendor); @@ -420,7 +418,7 @@ impl PhysicalDevice { let mut memory_types = Vec::new(); - let mut add_memory_type = |memory_type: hal::MemoryType| { + let mut add_memory_type = |memory_type: adapter::MemoryType| { if private_caps.index_buffer_role_change { // If `index_buffer_role_change` is true, we can use a buffer for any role memory_types.push((memory_type, MemoryUsage::Buffer(buffer::Usage::all()))); @@ -439,33 +437,33 @@ impl PhysicalDevice { // Mimicking vulkan, memory types with more flags should come before those with fewer flags if private_caps.map && private_caps.buffer_storage { // Coherent memory is only available if we have `glBufferStorage` - add_memory_type(hal::MemoryType { + add_memory_type(adapter::MemoryType { properties: memory::Properties::CPU_VISIBLE | memory::Properties::CPU_CACHED | memory::Properties::COHERENT, heap_index: CPU_VISIBLE_HEAP, }); - add_memory_type(hal::MemoryType { + add_memory_type(adapter::MemoryType { properties: memory::Properties::CPU_VISIBLE | memory::Properties::COHERENT, heap_index: CPU_VISIBLE_HEAP, }); } if private_caps.map || private_caps.emulate_map { - add_memory_type(hal::MemoryType { + add_memory_type(adapter::MemoryType { properties: memory::Properties::CPU_VISIBLE | memory::Properties::CPU_CACHED, heap_index: CPU_VISIBLE_HEAP, }); } - add_memory_type(hal::MemoryType { + add_memory_type(adapter::MemoryType { properties: memory::Properties::DEVICE_LOCAL, heap_index: DEVICE_LOCAL_HEAP, }); // There is always a single device-local memory type for images memory_types.push(( - hal::MemoryType { + adapter::MemoryType { properties: memory::Properties::DEVICE_LOCAL, heap_index: DEVICE_LOCAL_HEAP, }, @@ -553,8 +551,8 @@ impl PhysicalDevice { 0 }; - hal::Adapter { - info: hal::AdapterInfo { + adapter::Adapter { + info: adapter::AdapterInfo { name, vendor: vendor_id, device: 0, @@ -571,12 +569,12 @@ impl PhysicalDevice { } } -impl hal::PhysicalDevice for PhysicalDevice { +impl adapter::PhysicalDevice for PhysicalDevice { unsafe fn open( &self, - families: &[(&QueueFamily, &[hal::QueuePriority])], + families: &[(&QueueFamily, &[q::QueuePriority])], requested_features: hal::Features, - ) -> Result, error::DeviceCreationError> { + ) -> Result, error::DeviceCreationError> { // Can't have multiple logical devices at the same time // as they would share the same context. if self.0.open.get() { @@ -622,20 +620,18 @@ impl hal::PhysicalDevice for PhysicalDevice { panic!("Error opening adapter: {:?}", err); } - Ok(hal::Gpu { + Ok(adapter::Gpu { device: Device::new(self.0.clone()), - queues: Queues::new( - families - .into_iter() - .map(|&(proto_family, priorities)| { - assert_eq!(priorities.len(), 1); - let mut family = hal::backend::RawQueueGroup::new(proto_family.clone()); - let queue = queue::CommandQueue::new(&self.0, vao); - family.add_queue(queue); - family - }) - .collect(), - ), + queue_groups: families + .into_iter() + .map(|&(_family, priorities)| { + assert_eq!(priorities.len(), 1); + let mut family = q::QueueGroup::new(q::QueueFamilyId(0)); + let queue = queue::CommandQueue::new(&self.0, vao); + family.add_queue(queue); + family + }) + .collect(), }) } @@ -672,8 +668,8 @@ impl hal::PhysicalDevice for PhysicalDevice { }) } - fn memory_properties(&self) -> hal::MemoryProperties { - hal::MemoryProperties { + fn memory_properties(&self) -> adapter::MemoryProperties { + adapter::MemoryProperties { memory_types: self .0 .memory_types @@ -697,15 +693,15 @@ impl hal::PhysicalDevice for PhysicalDevice { #[derive(Debug, Clone, Copy)] pub struct QueueFamily; -impl hal::QueueFamily for QueueFamily { - fn queue_type(&self) -> hal::QueueType { - hal::QueueType::General +impl q::QueueFamily for QueueFamily { + fn queue_type(&self) -> q::QueueType { + q::QueueType::General } fn max_queues(&self) -> usize { 1 } - fn id(&self) -> QueueFamilyId { - QueueFamilyId(0) + fn id(&self) -> q::QueueFamilyId { + q::QueueFamilyId(0) } } @@ -719,7 +715,7 @@ pub enum Instance { #[cfg(all(not(target_arch = "wasm32"), feature = "glutin"))] impl hal::Instance for Instance { type Backend = Backend; - fn enumerate_adapters(&self) -> Vec> { + fn enumerate_adapters(&self) -> Vec> { match self { Instance::Headless(instance) => instance.enumerate_adapters(), Instance::Surface(instance) => instance.enumerate_adapters(), diff --git a/src/backend/gl/src/native.rs b/src/backend/gl/src/native.rs index bf42bdb4c30..a70831bd077 100644 --- a/src/backend/gl/src/native.rs +++ b/src/backend/gl/src/native.rs @@ -183,7 +183,7 @@ pub struct Image { pub enum ImageKind { Surface { surface: Surface, - format: TextureFormat + format: TextureFormat, }, Texture { texture: Texture, @@ -293,7 +293,10 @@ impl SubpassDesc { if self.depth_stencil == Some(at_id) { Some(glow::DEPTH_STENCIL_ATTACHMENT) } else { - self.color_attachments.iter().position(|id| *id == at_id).map(|p| glow::COLOR_ATTACHMENT0 + p as u32) + self.color_attachments + .iter() + .position(|id| *id == at_id) + .map(|p| glow::COLOR_ATTACHMENT0 + p as u32) } } } diff --git a/src/backend/gl/src/pool.rs b/src/backend/gl/src/pool.rs index 32a67cfda88..bba680e362f 100644 --- a/src/backend/gl/src/pool.rs +++ b/src/backend/gl/src/pool.rs @@ -1,8 +1,7 @@ -use crate::command::{self, Command, RawCommandBuffer}; -use crate::hal::backend::FastHashMap; -use crate::hal::{self, pool}; +use crate::command::{self, Command, CommandBuffer}; use crate::native as n; use crate::Backend; +use hal::backend::FastHashMap; use std::sync::{Arc, Mutex}; @@ -54,13 +53,13 @@ pub enum BufferMemory { } #[derive(Debug)] -pub struct RawCommandPool { +pub struct CommandPool { pub(crate) fbo: Option, pub(crate) limits: command::Limits, pub(crate) memory: Arc>, } -impl pool::RawCommandPool for RawCommandPool { +impl hal::pool::CommandPool for CommandPool { unsafe fn reset(&mut self, _release_resources: bool) { let mut memory = self .memory @@ -81,14 +80,14 @@ impl pool::RawCommandPool for RawCommandPool { } } - fn allocate_one(&mut self, _level: hal::command::RawLevel) -> RawCommandBuffer { + fn allocate_one(&mut self, _level: hal::command::Level) -> CommandBuffer { // TODO: Implement secondary buffers - RawCommandBuffer::new(self.fbo, self.limits, self.memory.clone()) + CommandBuffer::new(self.fbo, self.limits, self.memory.clone()) } unsafe fn free(&mut self, buffers: I) where - I: IntoIterator, + I: IntoIterator, { let mut memory = self .memory diff --git a/src/backend/gl/src/queue.rs b/src/backend/gl/src/queue.rs index b330c120158..e967c88d841 100644 --- a/src/backend/gl/src/queue.rs +++ b/src/backend/gl/src/queue.rs @@ -2,15 +2,21 @@ use crate::Starc; use std::borrow::Borrow; use std::{mem, slice}; -use crate::hal; -use crate::hal::error; +use hal::error; use glow::Context; use smallvec::SmallVec; -use crate::info::LegacyFeatures; -use crate::{command as com, device, native, state}; -use crate::{Backend, GlContext, Share}; +use crate::{ + command as com, + device, + info::LegacyFeatures, + native, + state, + Backend, + GlContext, + Share, +}; // State caching system for command queue. // @@ -702,22 +708,21 @@ impl CommandQueue { src_image, dst_surface, dst_format, - ref data + ref data, } => { let gl = &self.share.context; if data.src_subresource.aspects != hal::format::Aspects::COLOR - || data.dst_subresource.aspects != hal::format::Aspects::COLOR { - unimplemented!() + || data.dst_subresource.aspects != hal::format::Aspects::COLOR + { + unimplemented!() } match src_image { - native::ImageKind::Texture { .. } => { - unimplemented!() - } + native::ImageKind::Texture { .. } => unimplemented!(), native::ImageKind::Surface { surface: src_surface, - format: src_format + format: src_format, } => { if src_format != dst_format { unimplemented!() @@ -726,11 +731,21 @@ impl CommandQueue { unsafe { let src_fbo = gl.create_framebuffer().unwrap(); gl.bind_framebuffer(glow::READ_FRAMEBUFFER, Some(src_fbo)); - gl.framebuffer_renderbuffer(glow::READ_FRAMEBUFFER, glow::COLOR_ATTACHMENT0, glow::RENDERBUFFER, Some(src_surface)); + gl.framebuffer_renderbuffer( + glow::READ_FRAMEBUFFER, + glow::COLOR_ATTACHMENT0, + glow::RENDERBUFFER, + Some(src_surface), + ); let dst_fbo = gl.create_framebuffer().unwrap(); gl.bind_framebuffer(glow::DRAW_FRAMEBUFFER, Some(dst_fbo)); - gl.framebuffer_renderbuffer(glow::DRAW_FRAMEBUFFER, glow::COLOR_ATTACHMENT0, glow::RENDERBUFFER, Some(dst_surface)); + gl.framebuffer_renderbuffer( + glow::DRAW_FRAMEBUFFER, + glow::COLOR_ATTACHMENT0, + glow::RENDERBUFFER, + Some(dst_surface), + ); gl.blit_framebuffer( data.src_offset.x, @@ -1028,13 +1043,13 @@ impl CommandQueue { } } -impl hal::queue::RawCommandQueue for CommandQueue { +impl hal::queue::CommandQueue for CommandQueue { unsafe fn submit<'a, T, Ic, S, Iw, Is>( &mut self, submit_info: hal::queue::Submission, fence: Option<&native::Fence>, ) where - T: 'a + Borrow, + T: 'a + Borrow, Ic: IntoIterator, S: 'a + Borrow, Iw: IntoIterator, @@ -1066,14 +1081,12 @@ impl hal::queue::RawCommandQueue for CommandQueue { if let Some(fence) = fence { if self.share.private_caps.sync { - fence.0.set(native::FenceInner::Pending( - Some( - self.share - .context - .fence_sync(glow::SYNC_GPU_COMMANDS_COMPLETE, 0) - .unwrap(), - ) - )); + fence.0.set(native::FenceInner::Pending(Some( + self.share + .context + .fence_sync(glow::SYNC_GPU_COMMANDS_COMPLETE, 0) + .unwrap(), + ))); } else { self.share.context.flush(); fence.0.set(native::FenceInner::Idle { signaled: true }); @@ -1088,7 +1101,7 @@ impl hal::queue::RawCommandQueue for CommandQueue { ) -> Result, hal::window::PresentError> where W: 'a + Borrow, - Is: IntoIterator, + Is: IntoIterator, S: 'a + Borrow, Iw: IntoIterator, { diff --git a/src/backend/gl/src/state.rs b/src/backend/gl/src/state.rs index 80c5619fefa..7ed9de72047 100644 --- a/src/backend/gl/src/state.rs +++ b/src/backend/gl/src/state.rs @@ -40,11 +40,7 @@ fn map_operation(op: pso::StencilOp) -> u32 { } } -pub(crate) fn bind_stencil( - gl: &GlContainer, - stencil: &Option, - cull: pso::Face, -) { +pub(crate) fn bind_stencil(gl: &GlContainer, stencil: &Option, cull: pso::Face) { fn bind_side( gl: &GlContainer, face: u32, @@ -68,7 +64,13 @@ pub(crate) fn bind_stencil( let read_masks = stencil.read_masks.static_or(pso::Sided::new(!0)); let ref_values = stencil.reference_values.static_or(pso::Sided::new(0)); if !cull.contains(pso::Face::FRONT) { - bind_side(gl, glow::FRONT, &stencil.faces.front, read_masks.front, ref_values.front); + bind_side( + gl, + glow::FRONT, + &stencil.faces.front, + read_masks.front, + ref_values.front, + ); if let pso::State::Static(values) = stencil.write_masks { unsafe { gl.stencil_mask_separate(glow::FRONT, values.front); @@ -76,7 +78,13 @@ pub(crate) fn bind_stencil( } } if !cull.contains(pso::Face::BACK) { - bind_side(gl, glow::BACK, &stencil.faces.back, read_masks.back, ref_values.back); + bind_side( + gl, + glow::BACK, + &stencil.faces.back, + read_masks.back, + ref_values.back, + ); if let pso::State::Static(values) = stencil.write_masks { unsafe { gl.stencil_mask_separate(glow::FRONT, values.back); diff --git a/src/backend/gl/src/window/dummy.rs b/src/backend/gl/src/window/dummy.rs index 2fb719715ba..7b8f2b692bb 100644 --- a/src/backend/gl/src/window/dummy.rs +++ b/src/backend/gl/src/window/dummy.rs @@ -1,16 +1,17 @@ -use crate::{Backend, PhysicalDevice, QueueFamily, native}; +use crate::{native, Backend, PhysicalDevice, QueueFamily}; +use hal::window; #[derive(Debug)] pub struct Surface; -impl hal::Surface for Surface { +impl window::Surface for Surface { fn compatibility( &self, _: &PhysicalDevice, ) -> ( - hal::SurfaceCapabilities, + window::SurfaceCapabilities, Option>, - Vec, + Vec, ) { unimplemented!() } @@ -22,17 +23,17 @@ impl hal::Surface for Surface { #[derive(Debug)] pub struct Swapchain { - pub(crate) extent: hal::window::Extent2D, + pub(crate) extent: window::Extent2D, pub(crate) fbos: Vec, } -impl hal::Swapchain for Swapchain { +impl window::Swapchain for Swapchain { unsafe fn acquire_image( &mut self, _: u64, _: Option<&native::Semaphore>, _: Option<&native::Fence>, - ) -> Result<(hal::SwapImageIndex, Option), hal::AcquireError> { + ) -> Result<(window::SwapImageIndex, Option), window::AcquireError> { unimplemented!() } } diff --git a/src/backend/gl/src/window/glutin.rs b/src/backend/gl/src/window/glutin.rs index 37c1c8a59cb..9347bae4dca 100644 --- a/src/backend/gl/src/window/glutin.rs +++ b/src/backend/gl/src/window/glutin.rs @@ -47,18 +47,13 @@ //! } //! ``` -use crate::hal::window::Extent2D; -use crate::hal::{self, format as f, image, memory, CompositeAlpha}; -use crate::{native, Backend as B, Device, GlContainer, PhysicalDevice, QueueFamily, Starc}; - -use glow::Context; +use crate::{native, Backend as B, GlContainer, PhysicalDevice, QueueFamily, Starc}; +use hal::{adapter::Adapter, format as f, image, window}; use glutin; fn get_window_extent(window: &glutin::window::Window) -> image::Extent { - let px = window - .inner_size() - .to_physical(window.hidpi_factor()); + let px = window.inner_size().to_physical(window.hidpi_factor()); image::Extent { width: px.width as image::Size, height: px.height as image::Size, @@ -71,18 +66,18 @@ pub struct Swapchain { // Underlying window, required for presentation pub(crate) context: Starc>, // Extent because the window lies - pub(crate) extent: Extent2D, + pub(crate) extent: window::Extent2D, /// pub(crate) fbos: Vec, } -impl hal::Swapchain for Swapchain { +impl window::Swapchain for Swapchain { unsafe fn acquire_image( &mut self, _timeout_ns: u64, _semaphore: Option<&native::Semaphore>, _fence: Option<&native::Fence>, - ) -> Result<(hal::SwapImageIndex, Option), hal::AcquireError> { + ) -> Result<(window::SwapImageIndex, Option), window::AcquireError> { // TODO: sync Ok((0, None)) } @@ -126,35 +121,35 @@ impl Surface { } } -impl hal::Surface for Surface { +impl window::Surface for Surface { fn compatibility( &self, _: &PhysicalDevice, ) -> ( - hal::SurfaceCapabilities, + window::SurfaceCapabilities, Option>, - Vec, + Vec, ) { - let caps = hal::SurfaceCapabilities { + let caps = window::SurfaceCapabilities { image_count: if self.context.get_pixel_format().double_buffer { 2 ..= 2 } else { 1 ..= 1 }, current_extent: None, - extents: hal::window::Extent2D { + extents: window::Extent2D { width: 4, height: 4, - } ..= hal::window::Extent2D { + } ..= window::Extent2D { width: 4096, height: 4096, }, max_image_layers: 1, usage: image::Usage::COLOR_ATTACHMENT | image::Usage::TRANSFER_SRC, - composite_alpha: CompositeAlpha::OPAQUE, //TODO + composite_alpha: window::CompositeAlpha::OPAQUE, //TODO }; let present_modes = vec![ - hal::PresentMode::Fifo, //TODO + window::PresentMode::Fifo, //TODO ]; (caps, Some(self.swapchain_formats()), present_modes) @@ -167,7 +162,7 @@ impl hal::Surface for Surface { impl hal::Instance for Surface { type Backend = B; - fn enumerate_adapters(&self) -> Vec> { + fn enumerate_adapters(&self) -> Vec> { let adapter = PhysicalDevice::new_adapter( (), GlContainer::from_fn_proc(|s| self.context.get_proc_address(s) as *const _), @@ -208,7 +203,7 @@ impl Headless { impl hal::Instance for Headless { type Backend = B; - fn enumerate_adapters(&self) -> Vec> { + fn enumerate_adapters(&self) -> Vec> { let adapter = PhysicalDevice::new_adapter( (), GlContainer::from_fn_proc(|s| self.0.get_proc_address(s) as *const _), diff --git a/src/backend/gl/src/window/web.rs b/src/backend/gl/src/window/web.rs index a960cab8200..85b39cbdaf6 100644 --- a/src/backend/gl/src/window/web.rs +++ b/src/backend/gl/src/window/web.rs @@ -1,6 +1,5 @@ -use crate::hal::window::Extent2D; -use crate::hal::{self, format as f, image, CompositeAlpha}; use crate::{native, Backend as B, GlContainer, PhysicalDevice, QueueFamily}; +use hal::{adapter::Adapter, format as f, image, window}; struct PixelFormat { @@ -42,17 +41,17 @@ impl Window { #[derive(Clone, Debug)] pub struct Swapchain { - pub(crate) extent: Extent2D, + pub(crate) extent: window::Extent2D, pub(crate) fbos: Vec, } -impl hal::Swapchain for Swapchain { +impl window::Swapchain for Swapchain { unsafe fn acquire_image( &mut self, _timeout_ns: u64, _semaphore: Option<&native::Semaphore>, _fence: Option<&native::Fence>, - ) -> Result<(hal::SwapImageIndex, Option), hal::AcquireError> { + ) -> Result<(window::SwapImageIndex, Option), window::AcquireError> { // TODO: sync Ok((0, None)) } @@ -81,19 +80,19 @@ impl Surface { } } -impl hal::Surface for Surface { +impl window::Surface for Surface { fn compatibility( &self, _: &PhysicalDevice, ) -> ( - hal::SurfaceCapabilities, + window::SurfaceCapabilities, Option>, - Vec, + Vec, ) { let ex = Window.get_window_extent(); - let extent = hal::window::Extent2D::from(ex); + let extent = window::Extent2D::from(ex); - let caps = hal::SurfaceCapabilities { + let caps = window::SurfaceCapabilities { image_count: if Window.get_pixel_format().double_buffer { 2 ..= 2 } else { @@ -103,10 +102,10 @@ impl hal::Surface for Surface { extents: extent ..= extent, max_image_layers: 1, usage: image::Usage::COLOR_ATTACHMENT | image::Usage::TRANSFER_SRC, - composite_alpha: CompositeAlpha::OPAQUE, //TODO + composite_alpha: window::CompositeAlpha::OPAQUE, //TODO }; let present_modes = vec![ - hal::PresentMode::Fifo, //TODO + window::PresentMode::Fifo, //TODO ]; (caps, Some(self.swapchain_formats()), present_modes) @@ -119,7 +118,7 @@ impl hal::Surface for Surface { impl hal::Instance for Surface { type Backend = B; - fn enumerate_adapters(&self) -> Vec> { + fn enumerate_adapters(&self) -> Vec> { let adapter = PhysicalDevice::new_adapter((), GlContainer::from_new_canvas()); // TODO: Move to `self` like native/window vec![adapter] } diff --git a/src/backend/gl/src/window/wgl.rs b/src/backend/gl/src/window/wgl.rs index c0a74fe7712..0677d1c924a 100644 --- a/src/backend/gl/src/window/wgl.rs +++ b/src/backend/gl/src/window/wgl.rs @@ -7,9 +7,7 @@ use std::{ ptr, }; -use hal::window::Extent2D; -use hal::{self, format as f, image, CompositeAlpha}; -use hal::format::Format; +use hal::{adapter::Adapter, format as f, image, window}; use lazy_static::lazy_static; use winapi::shared::minwindef::*; @@ -195,7 +193,7 @@ impl Instance { impl hal::Instance for Instance { type Backend = Backend; - fn enumerate_adapters(&self) -> Vec> { + fn enumerate_adapters(&self) -> Vec> { let gl_container = GlContainer::from_fn_proc(|s| unsafe { let sym = CString::new(s.as_bytes()).unwrap(); let addr = wgl_sys::GetProcAddress(sym.as_ptr()) as *const (); @@ -220,39 +218,39 @@ unsafe impl Send for Surface {} unsafe impl Sync for Surface {} impl Surface { - fn get_extent(&self) -> hal::window::Extent2D { + fn get_extent(&self) -> window::Extent2D { let mut rect: RECT = unsafe { mem::uninitialized() }; unsafe { GetClientRect(self.hwnd, &mut rect); } - hal::window::Extent2D { + window::Extent2D { width: (rect.right - rect.left) as _, height: (rect.bottom - rect.top) as _, } } } -impl hal::Surface for Surface { +impl window::Surface for Surface { fn compatibility( &self, physical_device: &PhysicalDevice, ) -> ( - hal::SurfaceCapabilities, - Option>, - Vec, + window::SurfaceCapabilities, + Option>, + Vec, ) { let extent = self.get_extent(); - let caps = hal::SurfaceCapabilities { + let caps = window::SurfaceCapabilities { image_count: 2 ..= 2, current_extent: Some(extent), extents: extent ..= extent, max_image_layers: 1, usage: image::Usage::COLOR_ATTACHMENT | image::Usage::TRANSFER_SRC, - composite_alpha: CompositeAlpha::OPAQUE, //TODO + composite_alpha: window::CompositeAlpha::OPAQUE, //TODO }; let present_modes = vec![ - hal::PresentMode::Fifo, //TODO + window::PresentMode::Fifo, //TODO ]; ( @@ -271,7 +269,7 @@ impl hal::Surface for Surface { pub struct Swapchain { pub(crate) fbos: Vec, pub(crate) context: PresentContext, - pub(crate) extent: Extent2D, + pub(crate) extent: window::Extent2D, } impl Swapchain { pub(crate) fn make_current(&self) { @@ -283,13 +281,13 @@ impl Swapchain { } } -impl hal::Swapchain for Swapchain { +impl window::Swapchain for Swapchain { unsafe fn acquire_image( &mut self, _timeout_ns: u64, _semaphore: Option<&native::Semaphore>, _fence: Option<&native::Fence>, - ) -> Result<(hal::SwapImageIndex, Option), hal::AcquireError> { + ) -> Result<(window::SwapImageIndex, Option), window::AcquireError> { Ok((0, None)) // TODO } } diff --git a/src/backend/metal/src/command.rs b/src/backend/metal/src/command.rs index b5542571583..51f700e80bc 100644 --- a/src/backend/metal/src/command.rs +++ b/src/backend/metal/src/command.rs @@ -18,7 +18,6 @@ use crate::{ }; use hal::{ - self, backend::FastHashMap, buffer, command as com, @@ -27,17 +26,14 @@ use hal::{ image::{Extent, Filter, Layout, Level, SubresourceRange}, memory, pass::AttachmentLoadOp, - pool, pso, query, - queue::{RawCommandQueue, Submission}, range::RangeArg, - window::{PresentError, Suboptimal}, + window::{PresentError, Suboptimal, SwapImageIndex}, DrawCount, IndexCount, IndexType, InstanceCount, - SwapImageIndex, VertexCount, VertexOffset, WorkGroupCount, @@ -256,7 +252,7 @@ unsafe impl Sync for CommandBuffer {} struct Temp { clear_vertices: Vec, blit_vertices: FastHashMap<(Aspects, Level), Vec>, - clear_values: Vec>, + clear_values: Vec>, } type VertexBufferMaybeVec = Vec>; @@ -1377,7 +1373,7 @@ pub struct IndexBuffer { #[derive(Debug)] pub struct CommandBufferInner { sink: Option, - level: com::RawLevel, + level: com::Level, backup_journal: Option, #[cfg(feature = "dispatch")] backup_capacity: Option, @@ -2016,14 +2012,14 @@ impl CommandQueue { } } -impl RawCommandQueue for CommandQueue { +impl hal::queue::CommandQueue for CommandQueue { unsafe fn submit<'a, T, Ic, S, Iw, Is>( &mut self, - Submission { + hal::queue::Submission { command_buffers, wait_semaphores, signal_semaphores, - }: Submission, + }: hal::queue::Submission, fence: Option<&native::Fence>, ) where T: 'a + Borrow, @@ -2299,7 +2295,11 @@ impl RawCommandQueue for CommandQueue { } } -fn assign_sides(this: &mut pso::Sided, faces: pso::Face, value: pso::StencilValue) { +fn assign_sides( + this: &mut pso::Sided, + faces: pso::Face, + value: pso::StencilValue, +) { if faces.contains(pso::Face::FRONT) { this.front = value; } @@ -2308,7 +2308,7 @@ fn assign_sides(this: &mut pso::Sided, faces: pso::Face, valu } } -impl pool::RawCommandPool for CommandPool { +impl hal::pool::CommandPool for CommandPool { unsafe fn reset(&mut self, release_resources: bool) { for cmd_buffer in &self.allocated { cmd_buffer @@ -2317,7 +2317,7 @@ impl pool::RawCommandPool for CommandPool { } } - fn allocate_one(&mut self, level: com::RawLevel) -> CommandBuffer { + fn allocate_one(&mut self, level: com::Level) -> CommandBuffer { //TODO: fail with OOM if we allocate more actual command buffers // than our mega-queue supports. let inner = Arc::new(RefCell::new(CommandBufferInner { @@ -2386,7 +2386,7 @@ impl pool::RawCommandPool for CommandPool { where I: IntoIterator, { - use self::hal::command::RawCommandBuffer; + use hal::command::CommandBuffer as _; for mut cmd_buf in cmd_buffers { cmd_buf.reset(true); match self @@ -2417,7 +2417,7 @@ impl CommandBuffer { } } -impl com::RawCommandBuffer for CommandBuffer { +impl com::CommandBuffer for CommandBuffer { unsafe fn begin( &mut self, flags: com::CommandBufferFlags, @@ -2426,7 +2426,7 @@ impl com::RawCommandBuffer for CommandBuffer { self.reset(false); let mut inner = self.inner.borrow_mut(); - let can_immediate = inner.level == com::RawLevel::Primary + let can_immediate = inner.level == com::Level::Primary && flags.contains(com::CommandBufferFlags::ONE_TIME_SUBMIT); let sink = match self.pool_shared.borrow_mut().online_recording { OnlineRecording::Immediate if can_immediate => { @@ -2624,8 +2624,7 @@ impl com::RawCommandBuffer for CommandBuffer { &mut self, image: &native::Image, _layout: Layout, - color: com::ClearColorRaw, - depth_stencil: com::ClearDepthStencilRaw, + value: com::ClearValue, subresource_ranges: T, ) where T: IntoIterator, @@ -2637,7 +2636,7 @@ impl com::RawCommandBuffer for CommandBuffer { .. } = *self.inner.borrow_mut(); - let clear_color = image.shader_channel.interpret(color); + let clear_color = image.shader_channel.interpret(value.color); let base_extent = image.kind.extent(); let is_layered = !self.shared.disabilities.broken_layered_clear_image; @@ -2710,7 +2709,7 @@ impl com::RawCommandBuffer for CommandBuffer { attachment.set_store_action(metal::MTLStoreAction::Store); if sub.aspects.contains(Aspects::DEPTH) { attachment.set_load_action(metal::MTLLoadAction::Clear); - attachment.set_clear_depth(depth_stencil.depth as _); + attachment.set_clear_depth(value.depth_stencil.depth as _); } else { attachment.set_load_action(metal::MTLLoadAction::Load); } @@ -2728,7 +2727,7 @@ impl com::RawCommandBuffer for CommandBuffer { attachment.set_store_action(metal::MTLStoreAction::Store); if sub.aspects.contains(Aspects::STENCIL) { attachment.set_load_action(metal::MTLLoadAction::Clear); - attachment.set_clear_stencil(depth_stencil.stencil); + attachment.set_clear_stencil(value.depth_stencil.stencil); } else { attachment.set_load_action(metal::MTLLoadAction::Load); } @@ -2823,13 +2822,13 @@ impl com::RawCommandBuffer for CommandBuffer { //Note: technically we should be able to derive the Channel from the // `value` variant, but this is blocked by the portability that is // always passing the attachment clears as `ClearColor::Sfloat` atm. - raw_value = com::ClearColorRaw::from(value); + raw_value = com::ClearColor::from(value); let com = soft::RenderCommand::BindBufferData { stage: pso::Stage::Fragment, index: 0, words: slice::from_raw_parts( raw_value.float32.as_ptr() as *const u32, - mem::size_of::() / WORD_SIZE, + mem::size_of::() / WORD_SIZE, ), }; (com, Some((index as u8, channel))) @@ -3323,7 +3322,8 @@ impl com::RawCommandBuffer for CommandBuffer { unsafe fn set_stencil_reference(&mut self, faces: pso::Face, value: pso::StencilValue) { assign_sides(&mut self.state.stencil.reference_values, faces, value); - let com = soft::RenderCommand::SetStencilReferenceValues(self.state.stencil.reference_values); + let com = + soft::RenderCommand::SetStencilReferenceValues(self.state.stencil.reference_values); self.inner.borrow_mut().sink().pre_render().issue(com); } @@ -3346,7 +3346,7 @@ impl com::RawCommandBuffer for CommandBuffer { first_subpass_contents: com::SubpassContents, ) where T: IntoIterator, - T::Item: Borrow, + T::Item: Borrow, { // fill out temporary clear values per attachment self.temp @@ -3501,8 +3501,7 @@ impl com::RawCommandBuffer for CommandBuffer { let mut inner = self.inner.borrow_mut(); let mut pre = inner.sink().pre_render(); - if let Some(ref stencil) = pipeline.depth_stencil_desc.stencil - { + if let Some(ref stencil) = pipeline.depth_stencil_desc.stencil { if let pso::State::Static(value) = stencil.read_masks { self.state.stencil.read_masks = value; } diff --git a/src/backend/metal/src/device.rs b/src/backend/metal/src/device.rs index 879bed5c27c..e3845d4c740 100644 --- a/src/backend/metal/src/device.rs +++ b/src/backend/metal/src/device.rs @@ -21,6 +21,7 @@ use cocoa::foundation::{NSRange, NSUInteger}; use copyless::VecHelper; use foreign_types::{ForeignType, ForeignTypeRef}; use hal::{ + adapter, backend::FastHashMap, buffer, device::{AllocationError, BindError, DeviceLost, OomOrDeviceLost, OutOfMemory, ShaderError}, @@ -35,7 +36,7 @@ use hal::{ pso, pso::VertexInputRate, query, - queue::{QueueFamilyId, Queues}, + queue::{QueueFamilyId, QueueGroup, QueuePriority}, range::RangeArg, window, }; @@ -169,7 +170,7 @@ impl VisibilityShared { #[derive(Clone, Debug)] pub struct Device { pub(crate) shared: Arc, - memory_types: Vec, + memory_types: Vec, features: hal::Features, pub online_recording: OnlineRecording, } @@ -214,7 +215,7 @@ impl MemoryTypes { #[derive(Debug)] pub struct PhysicalDevice { pub(crate) shared: Arc, - memory_types: Vec, + memory_types: Vec, } unsafe impl Send for PhysicalDevice {} unsafe impl Sync for PhysicalDevice {} @@ -223,22 +224,22 @@ impl PhysicalDevice { pub(crate) fn new(shared: Arc) -> Self { let memory_types = if shared.private_caps.os_is_mac { vec![ - hal::MemoryType { + adapter::MemoryType { // PRIVATE properties: Properties::DEVICE_LOCAL, heap_index: 0, }, - hal::MemoryType { + adapter::MemoryType { // SHARED properties: Properties::CPU_VISIBLE | Properties::COHERENT, heap_index: 1, }, - hal::MemoryType { + adapter::MemoryType { // MANAGED_UPLOAD properties: Properties::DEVICE_LOCAL | Properties::CPU_VISIBLE, heap_index: 1, }, - hal::MemoryType { + adapter::MemoryType { // MANAGED_DOWNLOAD properties: Properties::DEVICE_LOCAL | Properties::CPU_VISIBLE @@ -248,12 +249,12 @@ impl PhysicalDevice { ] } else { vec![ - hal::MemoryType { + adapter::MemoryType { // PRIVATE properties: Properties::DEVICE_LOCAL, heap_index: 0, }, - hal::MemoryType { + adapter::MemoryType { // SHARED properties: Properties::CPU_VISIBLE | Properties::COHERENT, heap_index: 1, @@ -275,12 +276,14 @@ impl PhysicalDevice { } } -impl hal::PhysicalDevice for PhysicalDevice { +impl adapter::PhysicalDevice for PhysicalDevice { unsafe fn open( &self, - families: &[(&QueueFamily, &[hal::QueuePriority])], + families: &[(&QueueFamily, &[QueuePriority])], requested_features: hal::Features, - ) -> Result, error::DeviceCreationError> { + ) -> Result, error::DeviceCreationError> { + use hal::queue::QueueFamily as _; + // TODO: Query supported features by feature set rather than hard coding in the supported // features. https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf if !self.features().contains(requested_features) { @@ -291,10 +294,6 @@ impl hal::PhysicalDevice for PhysicalDevice { return Err(error::DeviceCreationError::MissingFeature); } - // TODO: Handle opening a physical device multiple times - assert_eq!(families.len(), 1); - assert_eq!(families[0].1.len(), 1); - let family = *families[0].0; let device = self.shared.device.lock(); if cfg!(feature = "auto-capture") { @@ -307,7 +306,9 @@ impl hal::PhysicalDevice for PhysicalDevice { default_capture_scope.begin_scope(); } - let mut queue_group = hal::backend::RawQueueGroup::new(family); + assert_eq!(families.len(), 1); + assert_eq!(families[0].1.len(), 1); + let mut queue_group = QueueGroup::new(families[0].0.id()); for _ in 0 .. self.shared.private_caps.exposed_queues { queue_group.add_queue(command::CommandQueue::new(self.shared.clone())); } @@ -319,9 +320,9 @@ impl hal::PhysicalDevice for PhysicalDevice { online_recording: OnlineRecording::default(), }; - Ok(hal::Gpu { + Ok(adapter::Gpu { device, - queues: Queues::new(vec![queue_group]), + queue_groups: vec![queue_group], }) } @@ -399,8 +400,8 @@ impl hal::PhysicalDevice for PhysicalDevice { }) } - fn memory_properties(&self) -> hal::MemoryProperties { - hal::MemoryProperties { + fn memory_properties(&self) -> adapter::MemoryProperties { + adapter::MemoryProperties { memory_heaps: vec![ !0, //TODO: private memory limits self.shared.private_caps.max_buffer_size, @@ -794,7 +795,7 @@ impl Device { if let Some(fun) = info.comparison { if !caps.mutable_comparison_samplers { - return None + return None; } descriptor.set_compare_function(conv::map_compare_function(fun)); } @@ -843,8 +844,9 @@ impl Device { image::Filter::Linear => msl::SamplerFilter::Linear, }, mip_filter: match info.min_filter { - image::Filter::Nearest if info.lod_range.end < image::Lod::from(0.5) => - msl::SamplerMipFilter::None, + image::Filter::Nearest if info.lod_range.end < image::Lod::from(0.5) => { + msl::SamplerMipFilter::None + } image::Filter::Nearest => msl::SamplerMipFilter::Nearest, image::Filter::Linear => msl::SamplerMipFilter::Linear, }, @@ -862,7 +864,7 @@ impl Device { other => { error!("Border color 0x{:X} is not supported", other); msl::SamplerBorderColor::TransparentBlack - }, + } }, lod_clamp_min: lods.start.into(), lod_clamp_max: lods.end.into(), @@ -874,7 +876,7 @@ impl Device { } } -impl hal::Device for Device { +impl hal::device::Device for Device { unsafe fn create_command_pool( &self, _family: QueueFamilyId, @@ -887,7 +889,7 @@ impl hal::Device for Device { } unsafe fn destroy_command_pool(&self, mut pool: command::CommandPool) { - use hal::pool::RawCommandPool; + use hal::pool::CommandPool as _; pool.reset(false); } @@ -2089,7 +2091,8 @@ impl hal::Device for Device { { match *descriptor.borrow() { pso::Descriptor::Sampler(sampler) => { - debug_assert!(!bindings[&write.binding].content + debug_assert!(!bindings[&write.binding] + .content .contains(n::DescriptorContent::IMMUTABLE_SAMPLER)); encoder.set_sampler_state(sampler.raw.as_ref().unwrap(), arg_index); arg_index += 1; @@ -2909,7 +2912,7 @@ impl hal::Device for Device { unsafe fn create_swapchain( &self, surface: &mut Surface, - config: hal::SwapchainConfig, + config: window::SwapchainConfig, old_swapchain: Option, ) -> Result<(Swapchain, Vec), window::CreationError> { Ok(self.build_swapchain(surface, config, old_swapchain)) diff --git a/src/backend/metal/src/internal.rs b/src/backend/metal/src/internal.rs index 9aab68ed90d..66a6d0e6193 100644 --- a/src/backend/metal/src/internal.rs +++ b/src/backend/metal/src/internal.rs @@ -2,7 +2,7 @@ use crate::{conversions as conv, PrivateCapabilities}; use hal::{ backend::FastHashMap, - command::ClearColorRaw, + command::ClearColor, format::{Aspects, ChannelType}, image::Filter, pso, @@ -53,7 +53,7 @@ impl From for Channel { } impl Channel { - pub fn interpret(self, raw: ClearColorRaw) -> metal::MTLClearColor { + pub fn interpret(self, raw: ClearColor) -> metal::MTLClearColor { unsafe { match self { Channel::Float => metal::MTLClearColor::new( @@ -63,10 +63,10 @@ impl Channel { raw.float32[3] as _, ), Channel::Int => metal::MTLClearColor::new( - raw.int32[0] as _, - raw.int32[1] as _, - raw.int32[2] as _, - raw.int32[3] as _, + raw.sint32[0] as _, + raw.sint32[1] as _, + raw.sint32[2] as _, + raw.sint32[3] as _, ), Channel::Uint => metal::MTLClearColor::new( raw.uint32[0] as _, @@ -142,7 +142,7 @@ impl DepthStencilStates { depth_bounds: false, stencil: Some(pso::StencilTest { faces: pso::Sided::new(face), - .. pso::StencilTest::default() + ..pso::StencilTest::default() }), }; let write_all = pso::DepthStencilDesc { @@ -153,7 +153,7 @@ impl DepthStencilStates { depth_bounds: false, stencil: Some(pso::StencilTest { faces: pso::Sided::new(face), - .. pso::StencilTest::default() + ..pso::StencilTest::default() }), }; @@ -206,7 +206,9 @@ impl DepthStencilStates { } fn create_stencil( - face: &pso::StencilFace, read_mask: pso::StencilValue, write_mask: pso::StencilValue + face: &pso::StencilFace, + read_mask: pso::StencilValue, + write_mask: pso::StencilValue, ) -> metal::StencilDescriptor { let desc = metal::StencilDescriptor::new(); desc.set_stencil_compare_function(conv::map_compare_function(face.fun)); @@ -230,12 +232,12 @@ impl DepthStencilStates { pso::State::Static(value) => value, pso::State::Dynamic => return None, }; - let front_desc = Self::create_stencil(&stencil.faces.front, read_masks.front, write_masks.front); + let front_desc = + Self::create_stencil(&stencil.faces.front, read_masks.front, write_masks.front); raw.set_front_face_stencil(Some(&front_desc)); - let back_desc = if - stencil.faces.front == stencil.faces.back && - read_masks.front == read_masks.back && - write_masks.front == write_masks.back + let back_desc = if stencil.faces.front == stencil.faces.back + && read_masks.front == read_masks.back + && write_masks.front == write_masks.back { front_desc } else { diff --git a/src/backend/metal/src/lib.rs b/src/backend/metal/src/lib.rs index 0aacab7e7a4..a4692c23b89 100644 --- a/src/backend/metal/src/lib.rs +++ b/src/backend/metal/src/lib.rs @@ -58,11 +58,12 @@ extern crate objc; #[macro_use] extern crate log; -use hal; -use hal::queue::QueueFamilyId; +use hal::{ + adapter::{Adapter, AdapterInfo, DeviceType}, + queue::{QueueFamilyId, QueueType}, +}; use range_alloc::RangeAllocator; -use cocoa; use cocoa::foundation::NSInteger; use core_graphics::base::CGFloat; use core_graphics::geometry::CGRect; @@ -126,9 +127,9 @@ const MAX_BOUND_DESCRIPTOR_SETS: usize = 8; #[derive(Debug, Clone, Copy)] pub struct QueueFamily {} -impl hal::QueueFamily for QueueFamily { - fn queue_type(&self) -> hal::QueueType { - hal::QueueType::General +impl hal::queue::QueueFamily for QueueFamily { + fn queue_type(&self) -> QueueType { + QueueType::General } fn max_queues(&self) -> usize { 1 @@ -211,23 +212,23 @@ pub struct Instance { impl hal::Instance for Instance { type Backend = Backend; - fn enumerate_adapters(&self) -> Vec> { + fn enumerate_adapters(&self) -> Vec> { let devices = metal::Device::all(); - let mut adapters: Vec> = devices + let mut adapters: Vec> = devices .into_iter() .map(|dev| { let name = dev.name().into(); let shared = Shared::new(dev, &self.experiments); let physical_device = device::PhysicalDevice::new(Arc::new(shared)); - hal::Adapter { - info: hal::AdapterInfo { + Adapter { + info: AdapterInfo { name, vendor: 0, device: 0, device_type: if physical_device.shared.private_caps.low_power { - hal::adapter::DeviceType::IntegratedGpu + DeviceType::IntegratedGpu } else { - hal::adapter::DeviceType::DiscreteGpu + DeviceType::DiscreteGpu }, }, physical_device, @@ -336,7 +337,7 @@ impl Instance { let window: cocoa::base::id = msg_send![view, window]; if !window.is_null() { let scale_factor: CGFloat = msg_send![window, backingScaleFactor]; - let() = msg_send![layer, setContentsScale: scale_factor]; + let () = msg_send![layer, setContentsScale: scale_factor]; } layer }; @@ -716,7 +717,10 @@ impl PrivateCapabilities { argument_buffers: experiments.argument_buffers && Self::supports_any(&device, ARGUMENT_BUFFER_SUPPORT), shared_textures: !os_is_mac, - mutable_comparison_samplers: Self::supports_any(&device, MUTABLE_COMPARISON_SAMPLER_SUPPORT), + mutable_comparison_samplers: Self::supports_any( + &device, + MUTABLE_COMPARISON_SAMPLER_SUPPORT, + ), base_instance: Self::supports_any(&device, BASE_INSTANCE_SUPPORT), dual_source_blending: Self::supports_any(&device, DUAL_SOURCE_BLEND_SUPPORT), low_power: !os_is_mac || device.is_low_power(), diff --git a/src/backend/metal/src/native.rs b/src/backend/metal/src/native.rs index 15d76c425c6..4b43b92dc0b 100644 --- a/src/backend/metal/src/native.rs +++ b/src/backend/metal/src/native.rs @@ -17,7 +17,6 @@ use hal::{ pass::{Attachment, AttachmentId}, pso, range::RangeArg, - DescriptorPool as HalDescriptorPool, MemoryTypeId, }; use range_alloc::RangeAllocator; @@ -532,7 +531,7 @@ impl DescriptorPool { } } -impl HalDescriptorPool for DescriptorPool { +impl pso::DescriptorPool for DescriptorPool { unsafe fn allocate_set( &mut self, set_layout: &DescriptorSetLayout, diff --git a/src/backend/metal/src/window.rs b/src/backend/metal/src/window.rs index afac31f5de2..d971e151f7d 100644 --- a/src/backend/metal/src/window.rs +++ b/src/backend/metal/src/window.rs @@ -6,13 +6,7 @@ use crate::{ QueueFamily, }; -use hal::{ - format, - image, - window::{Extent2D, Suboptimal}, - CompositeAlpha, - SwapchainConfig, -}; +use hal::{format, image, window as w}; use core_graphics::base::CGFloat; use core_graphics::geometry::{CGRect, CGSize}; @@ -133,7 +127,7 @@ impl SurfaceInner { }) } - fn dimensions(&self) -> Extent2D { + fn dimensions(&self) -> w::Extent2D { let (size, scale): (CGSize, CGFloat) = match self.view { Some(view) if !cfg!(target_os = "macos") => unsafe { let bounds: CGRect = msg_send![view.as_ptr(), bounds]; @@ -158,7 +152,7 @@ impl SurfaceInner { (bounds.size, contents_scale) }, }; - Extent2D { + w::Extent2D { width: (size.width * scale) as u32, height: (size.height * scale) as u32, } @@ -206,7 +200,7 @@ pub enum AcquireMode { pub struct Swapchain { frames: Arc>, surface: Arc, - extent: Extent2D, + extent: w::Extent2D, last_frame: usize, pub acquire_mode: AcquireMode, } @@ -228,7 +222,7 @@ impl Swapchain { /// Returns the drawable for the specified swapchain image index, /// marks the index as free for future use. - pub(crate) fn take_drawable(&self, index: hal::SwapImageIndex) -> Result { + pub(crate) fn take_drawable(&self, index: w::SwapImageIndex) -> Result { let mut frame = self.frames[index as usize].inner.lock(); assert!(!frame.available && frame.linked); frame.signpost = None; @@ -252,7 +246,7 @@ impl Swapchain { pub struct SwapchainImage { frames: Arc>, surface: Arc, - index: hal::SwapImageIndex, + index: w::SwapImageIndex, } impl SwapchainImage { @@ -299,7 +293,7 @@ impl SwapchainImage { } } -impl hal::Surface for Surface { +impl w::Surface for Surface { fn supports_queue_family(&self, _queue_family: &QueueFamily) -> bool { // we only expose one family atm, so it's compatible true @@ -309,9 +303,9 @@ impl hal::Surface for Surface { &self, device: &PhysicalDevice, ) -> ( - hal::SurfaceCapabilities, + w::SurfaceCapabilities, Option>, - Vec, + Vec, ) { let current_extent = if self.main_thread_id == thread::current().id() { Some(self.inner.dimensions()) @@ -333,14 +327,14 @@ impl hal::Surface for Surface { 3 ..= 3 }; - let caps = hal::SurfaceCapabilities { + let caps = w::SurfaceCapabilities { //Note: this is hardcoded in `CAMetalLayer` documentation image_count, current_extent, - extents: Extent2D { + extents: w::Extent2D { width: 4, height: 4, - } ..= Extent2D { + } ..= w::Extent2D { width: 4096, height: 4096, }, @@ -349,7 +343,7 @@ impl hal::Surface for Surface { | image::Usage::SAMPLED | image::Usage::TRANSFER_SRC | image::Usage::TRANSFER_DST, - composite_alpha: CompositeAlpha::OPAQUE, //TODO + composite_alpha: w::CompositeAlpha::OPAQUE, //TODO }; let formats = vec![ @@ -362,9 +356,9 @@ impl hal::Surface for Surface { device_caps.os_is_mac && device_caps.has_version_at_least(10, 13); let present_modes = if can_set_display_sync { - vec![hal::PresentMode::Fifo, hal::PresentMode::Immediate] + vec![w::PresentMode::Fifo, w::PresentMode::Immediate] } else { - vec![hal::PresentMode::Fifo] + vec![w::PresentMode::Fifo] }; (caps, Some(formats), present_modes) @@ -375,7 +369,7 @@ impl Device { pub(crate) fn build_swapchain( &self, surface: &mut Surface, - config: SwapchainConfig, + config: w::SwapchainConfig, old_swapchain: Option, ) -> (Swapchain, Vec) { info!("build_swapchain {:?}", config); @@ -392,7 +386,7 @@ impl Device { let render_layer = *render_layer_borrow; let format_desc = config.format.surface_desc(); let framebuffer_only = config.image_usage == image::Usage::COLOR_ATTACHMENT; - let display_sync = config.present_mode != hal::PresentMode::Immediate; + let display_sync = config.present_mode != w::PresentMode::Immediate; let is_mac = caps.os_is_mac; let can_set_next_drawable_timeout = if is_mac { caps.has_version_at_least(10, 13) @@ -409,7 +403,8 @@ impl Device { // create one as a sublayer. However, when the view changes size, // its sublayers are not automatically resized, and we must resize // it here. The drawable size and the layer size don't correlate - #[cfg(target_os = "ios")] { + #[cfg(target_os = "ios")] + { if let Some(view) = surface.inner.view { let main_layer: *mut Object = msg_send![view.as_ptr(), layer]; let bounds: CGRect = msg_send![main_layer, bounds]; @@ -518,13 +513,13 @@ impl Device { } } -impl hal::Swapchain for Swapchain { +impl w::Swapchain for Swapchain { unsafe fn acquire_image( &mut self, _timeout_ns: u64, semaphore: Option<&native::Semaphore>, fence: Option<&native::Fence>, - ) -> Result<(hal::SwapImageIndex, Option), hal::AcquireError> { + ) -> Result<(w::SwapImageIndex, Option), w::AcquireError> { self.last_frame += 1; //TODO: figure out a proper story of HiDPI @@ -571,7 +566,7 @@ impl hal::Swapchain for Swapchain { let pair = self .surface .next_frame(&self.frames) - .map_err(|_| hal::AcquireError::OutOfDate)?; + .map_err(|_| w::AcquireError::OutOfDate)?; if let Some(fence) = fence { fence.0.replace(native::FenceInner::Idle { signaled: true }); @@ -583,11 +578,11 @@ impl hal::Swapchain for Swapchain { Some(frame) => frame.inner.lock(), None => { warn!("No frame is available"); - return Err(hal::AcquireError::OutOfDate); + return Err(w::AcquireError::OutOfDate); } }; if !frame.linked { - return Err(hal::AcquireError::OutOfDate); + return Err(w::AcquireError::OutOfDate); } if let Some(semaphore) = semaphore { diff --git a/src/backend/vulkan/src/command.rs b/src/backend/vulkan/src/command.rs index 3d74193691a..899eb0689a4 100644 --- a/src/backend/vulkan/src/command.rs +++ b/src/backend/vulkan/src/command.rs @@ -6,13 +6,23 @@ use std::ops::Range; use std::sync::Arc; use std::{mem, ptr}; -use crate::hal::format::Aspects; -use crate::hal::image::{Filter, Layout, SubresourceRange}; -use crate::hal::range::RangeArg; -use crate::hal::{buffer, command as com, memory, pso, query}; -use crate::hal::{DrawCount, IndexCount, InstanceCount, VertexCount, VertexOffset, WorkGroupCount}; -use crate::{conv, native as n}; -use crate::{Backend, RawDevice}; +use crate::{conv, native as n, Backend, RawDevice}; +use hal::{ + buffer, + command as com, + format::Aspects, + image::{Filter, Layout, SubresourceRange}, + memory, + pso, + query, + range::RangeArg, + DrawCount, + IndexCount, + InstanceCount, + VertexCount, + VertexOffset, + WorkGroupCount, +}; #[derive(Debug)] pub struct CommandBuffer { @@ -171,7 +181,7 @@ impl CommandBuffer { } } -impl com::RawCommandBuffer for CommandBuffer { +impl com::CommandBuffer for CommandBuffer { unsafe fn begin( &mut self, flags: com::CommandBufferFlags, @@ -229,7 +239,7 @@ impl com::RawCommandBuffer for CommandBuffer { first_subpass: com::SubpassContents, ) where T: IntoIterator, - T::Item: Borrow, + T::Item: Borrow, { let render_area = conv::map_rect(&render_area); @@ -320,8 +330,7 @@ impl com::RawCommandBuffer for CommandBuffer { &mut self, image: &n::Image, layout: Layout, - color: com::ClearColorRaw, - depth_stencil: com::ClearDepthStencilRaw, + value: com::ClearValue, subresource_ranges: T, ) where T: IntoIterator, @@ -349,10 +358,10 @@ impl com::RawCommandBuffer for CommandBuffer { } // Vulkan and HAL share same memory layout - let color_value = mem::transmute(color); + let color_value = mem::transmute(value.color); let depth_stencil_value = vk::ClearDepthStencilValue { - depth: depth_stencil.depth, - stencil: depth_stencil.stencil, + depth: value.depth_stencil.depth, + stencil: value.depth_stencil.stencil, }; if !color_ranges.is_empty() { @@ -389,7 +398,7 @@ impl com::RawCommandBuffer for CommandBuffer { aspect_mask: vk::ImageAspectFlags::COLOR, color_attachment: index as _, clear_value: vk::ClearValue { - color: conv::map_clear_color(value), + color: mem::transmute(value), }, }, com::AttachmentClear::DepthStencil { depth, stencil } => vk::ClearAttachment { diff --git a/src/backend/vulkan/src/conv.rs b/src/backend/vulkan/src/conv.rs index a99056dd725..0c460e74cad 100644 --- a/src/backend/vulkan/src/conv.rs +++ b/src/backend/vulkan/src/conv.rs @@ -1,8 +1,19 @@ use ash::vk; -use crate::hal::range::RangeArg; -use crate::hal::{buffer, command, format, image, pass, pso, query}; -use crate::hal::{CompositeAlpha, Features, IndexType, PresentMode, Primitive}; +use hal::{ + buffer, + command, + format, + image, + pass, + pso, + query, + range::RangeArg, + window::{CompositeAlpha, PresentMode}, + Features, + IndexType, + Primitive, +}; use crate::native as n; use std::borrow::Borrow; @@ -73,14 +84,6 @@ pub fn map_image_aspects(aspects: format::Aspects) -> vk::ImageAspectFlags { vk::ImageAspectFlags::from_raw(aspects.bits() as u32) } -pub fn map_clear_color(value: command::ClearColor) -> vk::ClearColorValue { - match value { - command::ClearColor::Sfloat(v) => vk::ClearColorValue { float32: v }, - command::ClearColor::Sint(v) => vk::ClearColorValue { int32: v }, - command::ClearColor::Uint(v) => vk::ClearColorValue { uint32: v }, - } -} - pub fn map_offset(offset: image::Offset) -> vk::Offset3D { vk::Offset3D { x: offset.x, @@ -474,10 +477,10 @@ pub fn map_command_buffer_flags(flags: command::CommandBufferFlags) -> vk::Comma vk::CommandBufferUsageFlags::from_raw(flags.bits()) } -pub fn map_command_buffer_level(level: command::RawLevel) -> vk::CommandBufferLevel { +pub fn map_command_buffer_level(level: command::Level) -> vk::CommandBufferLevel { match level { - command::RawLevel::Primary => vk::CommandBufferLevel::PRIMARY, - command::RawLevel::Secondary => vk::CommandBufferLevel::SECONDARY, + command::Level::Primary => vk::CommandBufferLevel::PRIMARY, + command::Level::Secondary => vk::CommandBufferLevel::SECONDARY, } } diff --git a/src/backend/vulkan/src/device.rs b/src/backend/vulkan/src/device.rs index 7ecf34b0791..7798dd3e17e 100644 --- a/src/backend/vulkan/src/device.rs +++ b/src/backend/vulkan/src/device.rs @@ -3,14 +3,16 @@ use ash::version::DeviceV1_0; use ash::vk; use smallvec::SmallVec; -use crate::hal; -use crate::hal::error::HostExecutionError; -use crate::hal::memory::Requirements; -use crate::hal::pool::CommandPoolCreateFlags; -use crate::hal::pso::VertexInputRate; -use crate::hal::range::RangeArg; -use crate::hal::{buffer, device as d, format, image, mapping, pass, pso, query, queue}; -use crate::hal::{Features, MemoryTypeId, SwapchainConfig}; +use hal::{ + error::HostExecutionError, + memory::Requirements, + pool::CommandPoolCreateFlags, + pso::VertexInputRate, + range::RangeArg, + window::SwapchainConfig, + {buffer, device as d, format, image, mapping, pass, pso, query, queue}, + {Features, MemoryTypeId}, +}; use std::borrow::Borrow; use std::ffi::CString; @@ -40,9 +42,7 @@ impl d::Device for Device { match result { Ok(memory) => Ok(n::Memory { raw: memory }), Err(vk::Result::ERROR_TOO_MANY_OBJECTS) => Err(d::AllocationError::TooManyObjects), - Err(vk::Result::ERROR_OUT_OF_HOST_MEMORY) => { - Err(d::OutOfMemory::OutOfHostMemory.into()) - } + Err(vk::Result::ERROR_OUT_OF_HOST_MEMORY) => Err(d::OutOfMemory::OutOfHostMemory.into()), Err(vk::Result::ERROR_OUT_OF_DEVICE_MEMORY) => { Err(d::OutOfMemory::OutOfDeviceMemory.into()) } @@ -1076,9 +1076,7 @@ impl d::Device for Device { match module { Ok(raw) => Ok(n::ShaderModule { raw }), - Err(vk::Result::ERROR_OUT_OF_HOST_MEMORY) => { - Err(d::OutOfMemory::OutOfHostMemory.into()) - } + Err(vk::Result::ERROR_OUT_OF_HOST_MEMORY) => Err(d::OutOfMemory::OutOfHostMemory.into()), Err(vk::Result::ERROR_OUT_OF_DEVICE_MEMORY) => { Err(d::OutOfMemory::OutOfDeviceMemory.into()) } @@ -1136,7 +1134,11 @@ impl d::Device for Device { vk::BorderColor::FLOAT_TRANSPARENT_BLACK } }, - unnormalized_coordinates: if sampler_info.normalized { vk::FALSE } else { vk::TRUE }, + unnormalized_coordinates: if sampler_info.normalized { + vk::FALSE + } else { + vk::TRUE + }, }; let result = self.raw.0.create_sampler(&info, None); @@ -1144,9 +1146,7 @@ impl d::Device for Device { match result { Ok(sampler) => Ok(n::Sampler(sampler)), Err(vk::Result::ERROR_TOO_MANY_OBJECTS) => Err(d::AllocationError::TooManyObjects), - Err(vk::Result::ERROR_OUT_OF_HOST_MEMORY) => { - Err(d::OutOfMemory::OutOfHostMemory.into()) - } + Err(vk::Result::ERROR_OUT_OF_HOST_MEMORY) => Err(d::OutOfMemory::OutOfHostMemory.into()), Err(vk::Result::ERROR_OUT_OF_DEVICE_MEMORY) => { Err(d::OutOfMemory::OutOfDeviceMemory.into()) } @@ -1175,9 +1175,7 @@ impl d::Device for Device { match result { Ok(raw) => Ok(n::Buffer { raw }), - Err(vk::Result::ERROR_OUT_OF_HOST_MEMORY) => { - Err(d::OutOfMemory::OutOfHostMemory.into()) - } + Err(vk::Result::ERROR_OUT_OF_HOST_MEMORY) => Err(d::OutOfMemory::OutOfHostMemory.into()), Err(vk::Result::ERROR_OUT_OF_DEVICE_MEMORY) => { Err(d::OutOfMemory::OutOfDeviceMemory.into()) } @@ -1208,9 +1206,7 @@ impl d::Device for Device { match result { Ok(()) => Ok(()), - Err(vk::Result::ERROR_OUT_OF_HOST_MEMORY) => { - Err(d::OutOfMemory::OutOfHostMemory.into()) - } + Err(vk::Result::ERROR_OUT_OF_HOST_MEMORY) => Err(d::OutOfMemory::OutOfHostMemory.into()), Err(vk::Result::ERROR_OUT_OF_DEVICE_MEMORY) => { Err(d::OutOfMemory::OutOfDeviceMemory.into()) } @@ -1239,9 +1235,7 @@ impl d::Device for Device { match result { Ok(raw) => Ok(n::BufferView { raw }), - Err(vk::Result::ERROR_OUT_OF_HOST_MEMORY) => { - Err(d::OutOfMemory::OutOfHostMemory.into()) - } + Err(vk::Result::ERROR_OUT_OF_HOST_MEMORY) => Err(d::OutOfMemory::OutOfHostMemory.into()), Err(vk::Result::ERROR_OUT_OF_DEVICE_MEMORY) => { Err(d::OutOfMemory::OutOfDeviceMemory.into()) } @@ -1295,9 +1289,7 @@ impl d::Device for Device { flags, extent, }), - Err(vk::Result::ERROR_OUT_OF_HOST_MEMORY) => { - Err(d::OutOfMemory::OutOfHostMemory.into()) - } + Err(vk::Result::ERROR_OUT_OF_HOST_MEMORY) => Err(d::OutOfMemory::OutOfHostMemory.into()), Err(vk::Result::ERROR_OUT_OF_DEVICE_MEMORY) => { Err(d::OutOfMemory::OutOfDeviceMemory.into()) } @@ -1343,9 +1335,7 @@ impl d::Device for Device { match result { Ok(()) => Ok(()), - Err(vk::Result::ERROR_OUT_OF_HOST_MEMORY) => { - Err(d::OutOfMemory::OutOfHostMemory.into()) - } + Err(vk::Result::ERROR_OUT_OF_HOST_MEMORY) => Err(d::OutOfMemory::OutOfHostMemory.into()), Err(vk::Result::ERROR_OUT_OF_DEVICE_MEMORY) => { Err(d::OutOfMemory::OutOfDeviceMemory.into()) } @@ -1386,9 +1376,7 @@ impl d::Device for Device { view, range, }), - Err(vk::Result::ERROR_OUT_OF_HOST_MEMORY) => { - Err(d::OutOfMemory::OutOfHostMemory.into()) - } + Err(vk::Result::ERROR_OUT_OF_HOST_MEMORY) => Err(d::OutOfMemory::OutOfHostMemory.into()), Err(vk::Result::ERROR_OUT_OF_DEVICE_MEMORY) => { Err(d::OutOfMemory::OutOfDeviceMemory.into()) } @@ -1434,9 +1422,7 @@ impl d::Device for Device { device: self.raw.clone(), set_free_vec: Vec::new(), }), - Err(vk::Result::ERROR_OUT_OF_HOST_MEMORY) => { - Err(d::OutOfMemory::OutOfHostMemory.into()) - } + Err(vk::Result::ERROR_OUT_OF_HOST_MEMORY) => Err(d::OutOfMemory::OutOfHostMemory.into()), Err(vk::Result::ERROR_OUT_OF_DEVICE_MEMORY) => { Err(d::OutOfMemory::OutOfDeviceMemory.into()) } @@ -1502,9 +1488,7 @@ impl d::Device for Device { raw: layout, bindings, }), - Err(vk::Result::ERROR_OUT_OF_HOST_MEMORY) => { - Err(d::OutOfMemory::OutOfHostMemory.into()) - } + Err(vk::Result::ERROR_OUT_OF_HOST_MEMORY) => Err(d::OutOfMemory::OutOfHostMemory.into()), Err(vk::Result::ERROR_OUT_OF_DEVICE_MEMORY) => { Err(d::OutOfMemory::OutOfDeviceMemory.into()) } @@ -1666,9 +1650,7 @@ impl d::Device for Device { match result { Ok(ptr) => Ok(ptr as *mut _), Err(vk::Result::ERROR_MEMORY_MAP_FAILED) => Err(mapping::Error::MappingFailed), - Err(vk::Result::ERROR_OUT_OF_HOST_MEMORY) => { - Err(d::OutOfMemory::OutOfHostMemory.into()) - } + Err(vk::Result::ERROR_OUT_OF_HOST_MEMORY) => Err(d::OutOfMemory::OutOfHostMemory.into()), Err(vk::Result::ERROR_OUT_OF_DEVICE_MEMORY) => { Err(d::OutOfMemory::OutOfDeviceMemory.into()) } @@ -1691,9 +1673,7 @@ impl d::Device for Device { match result { Ok(()) => Ok(()), - Err(vk::Result::ERROR_OUT_OF_HOST_MEMORY) => { - Err(d::OutOfMemory::OutOfHostMemory.into()) - } + Err(vk::Result::ERROR_OUT_OF_HOST_MEMORY) => Err(d::OutOfMemory::OutOfHostMemory.into()), Err(vk::Result::ERROR_OUT_OF_DEVICE_MEMORY) => { Err(d::OutOfMemory::OutOfDeviceMemory.into()) } @@ -1715,9 +1695,7 @@ impl d::Device for Device { match result { Ok(()) => Ok(()), - Err(vk::Result::ERROR_OUT_OF_HOST_MEMORY) => { - Err(d::OutOfMemory::OutOfHostMemory.into()) - } + Err(vk::Result::ERROR_OUT_OF_HOST_MEMORY) => Err(d::OutOfMemory::OutOfHostMemory.into()), Err(vk::Result::ERROR_OUT_OF_DEVICE_MEMORY) => { Err(d::OutOfMemory::OutOfDeviceMemory.into()) } @@ -1736,9 +1714,7 @@ impl d::Device for Device { match result { Ok(semaphore) => Ok(n::Semaphore(semaphore)), - Err(vk::Result::ERROR_OUT_OF_HOST_MEMORY) => { - Err(d::OutOfMemory::OutOfHostMemory.into()) - } + Err(vk::Result::ERROR_OUT_OF_HOST_MEMORY) => Err(d::OutOfMemory::OutOfHostMemory.into()), Err(vk::Result::ERROR_OUT_OF_DEVICE_MEMORY) => { Err(d::OutOfMemory::OutOfDeviceMemory.into()) } @@ -1761,9 +1737,7 @@ impl d::Device for Device { match result { Ok(fence) => Ok(n::Fence(fence)), - Err(vk::Result::ERROR_OUT_OF_HOST_MEMORY) => { - Err(d::OutOfMemory::OutOfHostMemory.into()) - } + Err(vk::Result::ERROR_OUT_OF_HOST_MEMORY) => Err(d::OutOfMemory::OutOfHostMemory.into()), Err(vk::Result::ERROR_OUT_OF_DEVICE_MEMORY) => { Err(d::OutOfMemory::OutOfDeviceMemory.into()) } @@ -1784,9 +1758,7 @@ impl d::Device for Device { match result { Ok(()) => Ok(()), - Err(vk::Result::ERROR_OUT_OF_HOST_MEMORY) => { - Err(d::OutOfMemory::OutOfHostMemory.into()) - } + Err(vk::Result::ERROR_OUT_OF_HOST_MEMORY) => Err(d::OutOfMemory::OutOfHostMemory.into()), Err(vk::Result::ERROR_OUT_OF_DEVICE_MEMORY) => { Err(d::OutOfMemory::OutOfDeviceMemory.into()) } @@ -1817,9 +1789,7 @@ impl d::Device for Device { Ok(()) => Ok(true), Err(vk::Result::TIMEOUT) => Ok(false), Err(vk::Result::ERROR_DEVICE_LOST) => Err(d::DeviceLost.into()), - Err(vk::Result::ERROR_OUT_OF_HOST_MEMORY) => { - Err(d::OutOfMemory::OutOfHostMemory.into()) - } + Err(vk::Result::ERROR_OUT_OF_HOST_MEMORY) => Err(d::OutOfMemory::OutOfHostMemory.into()), Err(vk::Result::ERROR_OUT_OF_DEVICE_MEMORY) => { Err(d::OutOfMemory::OutOfDeviceMemory.into()) } @@ -1847,9 +1817,7 @@ impl d::Device for Device { let result = unsafe { self.raw.0.create_event(&info, None) }; match result { Ok(e) => Ok(n::Event(e)), - Err(vk::Result::ERROR_OUT_OF_HOST_MEMORY) => { - Err(d::OutOfMemory::OutOfHostMemory.into()) - } + Err(vk::Result::ERROR_OUT_OF_HOST_MEMORY) => Err(d::OutOfMemory::OutOfHostMemory.into()), Err(vk::Result::ERROR_OUT_OF_DEVICE_MEMORY) => { Err(d::OutOfMemory::OutOfDeviceMemory.into()) } @@ -1861,9 +1829,7 @@ impl d::Device for Device { let result = self.raw.0.get_event_status(event.0); match result { Ok(b) => Ok(b), - Err(vk::Result::ERROR_OUT_OF_HOST_MEMORY) => { - Err(d::OutOfMemory::OutOfHostMemory.into()) - } + Err(vk::Result::ERROR_OUT_OF_HOST_MEMORY) => Err(d::OutOfMemory::OutOfHostMemory.into()), Err(vk::Result::ERROR_OUT_OF_DEVICE_MEMORY) => { Err(d::OutOfMemory::OutOfDeviceMemory.into()) } @@ -1876,9 +1842,7 @@ impl d::Device for Device { let result = self.raw.0.set_event(event.0); match result { Ok(()) => Ok(()), - Err(vk::Result::ERROR_OUT_OF_HOST_MEMORY) => { - Err(d::OutOfMemory::OutOfHostMemory.into()) - } + Err(vk::Result::ERROR_OUT_OF_HOST_MEMORY) => Err(d::OutOfMemory::OutOfHostMemory.into()), Err(vk::Result::ERROR_OUT_OF_DEVICE_MEMORY) => { Err(d::OutOfMemory::OutOfDeviceMemory.into()) } @@ -1890,9 +1854,7 @@ impl d::Device for Device { let result = self.raw.0.reset_event(event.0); match result { Ok(()) => Ok(()), - Err(vk::Result::ERROR_OUT_OF_HOST_MEMORY) => { - Err(d::OutOfMemory::OutOfHostMemory.into()) - } + Err(vk::Result::ERROR_OUT_OF_HOST_MEMORY) => Err(d::OutOfMemory::OutOfHostMemory.into()), Err(vk::Result::ERROR_OUT_OF_DEVICE_MEMORY) => { Err(d::OutOfMemory::OutOfDeviceMemory.into()) } @@ -1937,9 +1899,7 @@ impl d::Device for Device { match result { Ok(pool) => Ok(n::QueryPool(pool)), - Err(vk::Result::ERROR_OUT_OF_HOST_MEMORY) => { - Err(d::OutOfMemory::OutOfHostMemory.into()) - } + Err(vk::Result::ERROR_OUT_OF_HOST_MEMORY) => Err(d::OutOfMemory::OutOfHostMemory.into()), Err(vk::Result::ERROR_OUT_OF_DEVICE_MEMORY) => { Err(d::OutOfMemory::OutOfDeviceMemory.into()) } diff --git a/src/backend/vulkan/src/lib.rs b/src/backend/vulkan/src/lib.rs index 0dfff2ff684..03df4f98646 100644 --- a/src/backend/vulkan/src/lib.rs +++ b/src/backend/vulkan/src/lib.rs @@ -46,18 +46,20 @@ use ash::vk; #[cfg(not(feature = "use-rtld-next"))] use ash::{Entry, LoadingError}; -use crate::hal::adapter::DeviceType; -use crate::hal::device::{DeviceLost, OutOfMemory, SurfaceLost}; -use crate::hal::error::{DeviceCreationError, HostExecutionError}; -use crate::hal::pso::PipelineStage; -use crate::hal::{ +use hal::{ + adapter, + device::{DeviceLost, OutOfMemory, SurfaceLost}, + error::{DeviceCreationError, HostExecutionError}, format, image, memory, + pso::PipelineStage, queue, - window::{PresentError, Suboptimal}, + window::{PresentError, Suboptimal, SwapImageIndex}, + Features, + Limits, + PatchSize, }; -use crate::hal::{Features, Limits, PatchSize, QueueType, SwapImageIndex}; use std::borrow::{Borrow, Cow}; use std::ffi::{CStr, CString}; @@ -162,18 +164,18 @@ pub struct Instance { pub extensions: Vec<&'static CStr>, } -fn map_queue_type(flags: vk::QueueFlags) -> QueueType { +fn map_queue_type(flags: vk::QueueFlags) -> queue::QueueType { if flags.contains(vk::QueueFlags::GRAPHICS | vk::QueueFlags::COMPUTE) { // TRANSFER_BIT optional - QueueType::General + queue::QueueType::General } else if flags.contains(vk::QueueFlags::GRAPHICS) { // TRANSFER_BIT optional - QueueType::Graphics + queue::QueueType::Graphics } else if flags.contains(vk::QueueFlags::COMPUTE) { // TRANSFER_BIT optional - QueueType::Compute + queue::QueueType::Compute } else if flags.contains(vk::QueueFlags::TRANSFER) { - QueueType::Transfer + queue::QueueType::Transfer } else { // TODO: present only queues? unimplemented!() @@ -439,7 +441,7 @@ impl Instance { impl hal::Instance for Instance { type Backend = Backend; - fn enumerate_adapters(&self) -> Vec> { + fn enumerate_adapters(&self) -> Vec> { let devices = match unsafe { self.raw.0.enumerate_physical_devices() } { Ok(devices) => devices, Err(err) => { @@ -452,7 +454,7 @@ impl hal::Instance for Instance { .into_iter() .map(|device| { let properties = unsafe { self.raw.0.get_physical_device_properties(device) }; - let info = hal::AdapterInfo { + let info = adapter::AdapterInfo { name: unsafe { CStr::from_ptr(properties.device_name.as_ptr()) .to_str() @@ -462,12 +464,16 @@ impl hal::Instance for Instance { vendor: properties.vendor_id as usize, device: properties.device_id as usize, device_type: match properties.device_type { - ash::vk::PhysicalDeviceType::OTHER => DeviceType::Other, - ash::vk::PhysicalDeviceType::INTEGRATED_GPU => DeviceType::IntegratedGpu, - ash::vk::PhysicalDeviceType::DISCRETE_GPU => DeviceType::DiscreteGpu, - ash::vk::PhysicalDeviceType::VIRTUAL_GPU => DeviceType::VirtualGpu, - ash::vk::PhysicalDeviceType::CPU => DeviceType::Cpu, - _ => DeviceType::Other, + ash::vk::PhysicalDeviceType::OTHER => adapter::DeviceType::Other, + ash::vk::PhysicalDeviceType::INTEGRATED_GPU => { + adapter::DeviceType::IntegratedGpu + } + ash::vk::PhysicalDeviceType::DISCRETE_GPU => { + adapter::DeviceType::DiscreteGpu + } + ash::vk::PhysicalDeviceType::VIRTUAL_GPU => adapter::DeviceType::VirtualGpu, + ash::vk::PhysicalDeviceType::CPU => adapter::DeviceType::Cpu, + _ => adapter::DeviceType::Other, }, }; let physical_device = PhysicalDevice { @@ -489,7 +495,7 @@ impl hal::Instance for Instance { .collect() }; - hal::Adapter { + adapter::Adapter { info, physical_device, queue_families, @@ -506,8 +512,8 @@ pub struct QueueFamily { index: u32, } -impl hal::queue::QueueFamily for QueueFamily { - fn queue_type(&self) -> QueueType { +impl queue::QueueFamily for QueueFamily { + fn queue_type(&self) -> queue::QueueType { map_queue_type(self.properties.queue_flags) } fn max_queues(&self) -> usize { @@ -527,12 +533,12 @@ pub struct PhysicalDevice { properties: vk::PhysicalDeviceProperties, } -impl hal::PhysicalDevice for PhysicalDevice { +impl adapter::PhysicalDevice for PhysicalDevice { unsafe fn open( &self, - families: &[(&QueueFamily, &[hal::QueuePriority])], + families: &[(&QueueFamily, &[queue::QueuePriority])], requested_features: Features, - ) -> Result, DeviceCreationError> { + ) -> Result, DeviceCreationError> { let family_infos = families .iter() .map(|&(family, priorities)| vk::DeviceQueueCreateInfo { @@ -593,13 +599,13 @@ impl hal::PhysicalDevice for PhysicalDevice { }; let device_arc = device.raw.clone(); - let queues = families + let queue_groups = families .into_iter() .map(|&(family, ref priorities)| { - let family_index = family.index; - let mut family_raw = hal::backend::RawQueueGroup::new(family.clone()); + let mut family_raw = + queue::QueueGroup::new(queue::QueueFamilyId(family.index as usize)); for id in 0 .. priorities.len() { - let queue_raw = device_arc.0.get_device_queue(family_index, id as _); + let queue_raw = device_arc.0.get_device_queue(family.index, id as _); family_raw.add_queue(CommandQueue { raw: Arc::new(queue_raw), device: device_arc.clone(), @@ -610,9 +616,9 @@ impl hal::PhysicalDevice for PhysicalDevice { }) .collect(); - Ok(hal::Gpu { + Ok(adapter::Gpu { device, - queues: queue::Queues::new(queues), + queue_groups, }) } @@ -675,7 +681,7 @@ impl hal::PhysicalDevice for PhysicalDevice { } } - fn memory_properties(&self) -> hal::MemoryProperties { + fn memory_properties(&self) -> adapter::MemoryProperties { let mem_properties = unsafe { self.instance .0 @@ -724,14 +730,14 @@ impl hal::PhysicalDevice for PhysicalDevice { type_flags |= Properties::LAZILY_ALLOCATED; } - hal::MemoryType { + adapter::MemoryType { properties: type_flags, heap_index: mem.heap_index as usize, } }) .collect(); - hal::MemoryProperties { + adapter::MemoryProperties { memory_heaps, memory_types, } @@ -1106,10 +1112,10 @@ pub struct CommandQueue { swapchain_fn: vk::KhrSwapchainFn, } -impl hal::queue::RawCommandQueue for CommandQueue { +impl queue::CommandQueue for CommandQueue { unsafe fn submit<'a, T, Ic, S, Iw, Is>( &mut self, - submission: hal::queue::Submission, + submission: queue::Submission, fence: Option<&native::Fence>, ) where T: 'a + Borrow, diff --git a/src/backend/vulkan/src/pool.rs b/src/backend/vulkan/src/pool.rs index 88c46afe5af..ec2010789d1 100644 --- a/src/backend/vulkan/src/pool.rs +++ b/src/backend/vulkan/src/pool.rs @@ -6,8 +6,8 @@ use std::sync::Arc; use crate::command::CommandBuffer; use crate::conv; -use crate::hal::{command, pool}; use crate::{Backend, RawDevice}; +use hal::{command, pool}; #[derive(Debug)] pub struct RawCommandPool { @@ -15,7 +15,7 @@ pub struct RawCommandPool { pub(crate) device: Arc, } -impl pool::RawCommandPool for RawCommandPool { +impl pool::CommandPool for RawCommandPool { unsafe fn reset(&mut self, release_resources: bool) { let flags = if release_resources { vk::CommandPoolResetFlags::RELEASE_RESOURCES @@ -26,7 +26,7 @@ impl pool::RawCommandPool for RawCommandPool { assert_eq!(Ok(()), self.device.0.reset_command_pool(self.raw, flags)); } - fn allocate_vec(&mut self, num: usize, level: command::RawLevel) -> Vec { + fn allocate_vec(&mut self, num: usize, level: command::Level) -> Vec { let info = vk::CommandBufferAllocateInfo { s_type: vk::StructureType::COMMAND_BUFFER_ALLOCATE_INFO, p_next: ptr::null(), diff --git a/src/backend/vulkan/src/window.rs b/src/backend/vulkan/src/window.rs index dd5dfc5dac8..2f2dba3f4f1 100644 --- a/src/backend/vulkan/src/window.rs +++ b/src/backend/vulkan/src/window.rs @@ -5,8 +5,7 @@ use std::sync::Arc; use ash::extensions::khr; use ash::vk; -use crate::hal; -use crate::hal::format::Format; +use hal::{format::Format, window as w}; #[cfg(feature = "winit")] use winit; @@ -137,10 +136,7 @@ impl Instance { } #[cfg(target_os = "android")] - pub fn create_surface_android( - &self, - window: *const c_void, - ) -> Surface { + pub fn create_surface_android(&self, window: *const c_void) -> Surface { let entry = VK_ENTRY .as_ref() .expect("Unable to load Vulkan entry points"); @@ -265,10 +261,7 @@ impl Instance { if let Some(display) = window.wayland_display() { let display: *mut c_void = display as *mut _; let surface: *mut c_void = window.wayland_surface().unwrap() as *mut _; - return self.create_surface_from_wayland( - display, - surface, - ); + return self.create_surface_from_wayland(display, surface); } } if self.extensions.contains(&khr::XlibSurface::name()) { @@ -282,9 +275,7 @@ impl Instance { #[cfg(target_os = "android")] { use winit::platform::android::WindowExtAndroid; - return self.create_surface_android( - window.get_native_window(), - ); + return self.create_surface_android(window.get_native_window()); } #[cfg(windows)] { @@ -305,10 +296,7 @@ impl Instance { panic!("No suitable WSI enabled!"); } - pub fn create_surface_from_vk_surface_khr( - &self, - surface: vk::SurfaceKHR, - ) -> Surface { + pub fn create_surface_from_vk_surface_khr(&self, surface: vk::SurfaceKHR) -> Surface { let entry = VK_ENTRY .as_ref() .expect("Unable to load Vulkan entry points"); @@ -321,20 +309,18 @@ impl Instance { instance: self.raw.clone(), }); - Surface { - raw, - } + Surface { raw } } } -impl hal::Surface for Surface { +impl w::Surface for Surface { fn compatibility( &self, physical_device: &PhysicalDevice, ) -> ( - hal::SurfaceCapabilities, + w::SurfaceCapabilities, Option>, - Vec, + Vec, ) { // Capabilities let caps = unsafe { @@ -354,7 +340,7 @@ impl hal::Surface for Surface { // `0xFFFFFFFF` indicates that the extent depends on the created swapchain. let current_extent = if caps.current_extent.width != !0 && caps.current_extent.height != !0 { - Some(hal::window::Extent2D { + Some(w::Extent2D { width: caps.current_extent.width, height: caps.current_extent.height, }) @@ -362,17 +348,17 @@ impl hal::Surface for Surface { None }; - let min_extent = hal::window::Extent2D { + let min_extent = w::Extent2D { width: caps.min_image_extent.width, height: caps.min_image_extent.height, }; - let max_extent = hal::window::Extent2D { + let max_extent = w::Extent2D { width: caps.max_image_extent.width, height: caps.max_image_extent.height, }; - let capabilities = hal::SurfaceCapabilities { + let capabilities = w::SurfaceCapabilities { image_count: caps.min_image_count ..= max_images, current_extent, extents: min_extent ..= max_extent, @@ -435,13 +421,13 @@ pub struct Swapchain { pub(crate) functor: khr::Swapchain, } -impl hal::Swapchain for Swapchain { +impl w::Swapchain for Swapchain { unsafe fn acquire_image( &mut self, timeout_ns: u64, semaphore: Option<&native::Semaphore>, fence: Option<&native::Fence>, - ) -> Result<(hal::SwapImageIndex, Option), hal::AcquireError> { + ) -> Result<(w::SwapImageIndex, Option), w::AcquireError> { let semaphore = semaphore.map_or(vk::Semaphore::null(), |s| s.0); let fence = fence.map_or(vk::Fence::null(), |f| f.0); @@ -453,25 +439,25 @@ impl hal::Swapchain for Swapchain { match index { Ok((i, suboptimal)) => { if suboptimal { - Ok((i, Some(hal::window::Suboptimal))) + Ok((i, Some(w::Suboptimal))) } else { Ok((i, None)) } } - Err(vk::Result::NOT_READY) => Err(hal::AcquireError::NotReady), - Err(vk::Result::TIMEOUT) => Err(hal::AcquireError::Timeout), - Err(vk::Result::ERROR_OUT_OF_DATE_KHR) => Err(hal::AcquireError::OutOfDate), + Err(vk::Result::NOT_READY) => Err(w::AcquireError::NotReady), + Err(vk::Result::TIMEOUT) => Err(w::AcquireError::Timeout), + Err(vk::Result::ERROR_OUT_OF_DATE_KHR) => Err(w::AcquireError::OutOfDate), Err(vk::Result::ERROR_SURFACE_LOST_KHR) => { - Err(hal::AcquireError::SurfaceLost(hal::device::SurfaceLost)) + Err(w::AcquireError::SurfaceLost(hal::device::SurfaceLost)) } - Err(vk::Result::ERROR_OUT_OF_HOST_MEMORY) => Err(hal::AcquireError::OutOfMemory( + Err(vk::Result::ERROR_OUT_OF_HOST_MEMORY) => Err(w::AcquireError::OutOfMemory( hal::device::OutOfMemory::OutOfHostMemory, )), - Err(vk::Result::ERROR_OUT_OF_DEVICE_MEMORY) => Err(hal::AcquireError::OutOfMemory( + Err(vk::Result::ERROR_OUT_OF_DEVICE_MEMORY) => Err(w::AcquireError::OutOfMemory( hal::device::OutOfMemory::OutOfDeviceMemory, )), Err(vk::Result::ERROR_DEVICE_LOST) => { - Err(hal::AcquireError::DeviceLost(hal::device::DeviceLost)) + Err(w::AcquireError::DeviceLost(hal::device::DeviceLost)) } _ => panic!("Failed to acquire image."), } diff --git a/src/hal/src/adapter.rs b/src/hal/src/adapter.rs index c6c3bc8f3bc..c24fa2a9f2f 100644 --- a/src/hal/src/adapter.rs +++ b/src/hal/src/adapter.rs @@ -10,23 +10,8 @@ use std::any::Any; use std::fmt; use crate::error::DeviceCreationError; -use crate::queue::{Capability, QueueGroup}; -use crate::{format, image, memory, Backend, Features, Gpu, Limits}; - -/// Scheduling hint for devices about the priority of a queue. Values range from `0.0` (low) to -/// `1.0` (high). -pub type QueuePriority = f32; - -/// A strongly-typed index to a particular `MemoryType`. -#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -pub struct MemoryTypeId(pub usize); - -impl From for MemoryTypeId { - fn from(id: usize) -> Self { - MemoryTypeId(id) - } -} +use crate::queue::{QueueGroup, QueuePriority}; +use crate::{format, image, memory, Backend, Features, Limits}; /// A description for a single chunk of memory in a heap. #[derive(Copy, Clone, Debug, PartialEq, Eq)] @@ -50,6 +35,18 @@ pub struct MemoryProperties { pub memory_heaps: Vec, } +/// Represents a combination of a logical device and the +/// hardware queues it provides. +/// +/// This structure is typically created using an `Adapter`. +#[derive(Debug)] +pub struct Gpu { + /// Logical device for a given backend. + pub device: B::Device, + /// The command queues that the device provides. + pub queue_groups: Vec>, +} + /// Represents a physical device (such as a GPU) capable of supporting the given backend. pub trait PhysicalDevice: fmt::Debug + Any + Send + Sync { /// Create a new logical device with the requested features. If `requested_features` is @@ -66,7 +63,7 @@ pub trait PhysicalDevice: fmt::Debug + Any + Send + Sync { /// # extern crate gfx_backend_empty as empty; /// # extern crate gfx_hal; /// # fn main() { - /// use gfx_hal::{PhysicalDevice, Features}; + /// use gfx_hal::{adapter::PhysicalDevice, Features}; /// /// # let physical_device: empty::PhysicalDevice = return; /// # let family: empty::QueueFamily = return; @@ -154,52 +151,3 @@ pub struct Adapter { /// Queue families supported by this adapter. pub queue_families: Vec, } - -impl Adapter { - /// Open the physical device with `count` queues from some active queue family. The family is - /// the first that both provides the capability `C`, supports at least `count` queues, and for - /// which `selector` returns true. - /// - /// # Examples - /// - /// ```no_run - /// # extern crate gfx_backend_empty as empty; - /// # extern crate gfx_hal as hal; - /// use hal::General; - /// # fn main() { - /// - /// # let mut adapter: hal::Adapter = return; - /// let (device, queues) = adapter.open_with::<_, General>(1, |_| true).unwrap(); - /// # } - /// ``` - /// - /// # Return - /// - /// Returns the same errors as `open` and `InitializationFailed` if no suitable - /// queue family could be found. - pub fn open_with( - &self, - count: usize, - selector: F, - ) -> Result<(B::Device, QueueGroup), DeviceCreationError> - where - F: Fn(&B::QueueFamily) -> bool, - C: Capability, - { - use crate::queue::QueueFamily; - - let requested_family = self.queue_families.iter().find(|family| { - C::supported_by(family.queue_type()) && selector(family) && count <= family.max_queues() - }); - - let priorities = vec![1.0; count]; - let (id, families) = match requested_family { - Some(family) => (family.id(), [(family, priorities.as_slice())]), - _ => return Err(DeviceCreationError::InitializationFailed), - }; - - let Gpu { device, mut queues } = - unsafe { self.physical_device.open(&families, Features::empty()) }?; - Ok((device, queues.take(id).unwrap())) - } -} diff --git a/src/hal/src/backend.rs b/src/hal/src/backend.rs index 8803194d303..1acd7b3566b 100644 --- a/src/hal/src/backend.rs +++ b/src/hal/src/backend.rs @@ -1,50 +1,9 @@ //! Functionality only required for backend implementations. -use crate::queue::{QueueFamily, Queues}; -use crate::Backend; - use std::collections::HashMap; use std::hash::BuildHasherDefault; use fxhash::FxHasher; -/// Bare-metal queue group. -/// -/// Denotes all queues created from one queue family. -#[derive(Debug)] -pub struct RawQueueGroup { - pub family: B::QueueFamily, - pub queues: Vec, -} - -impl RawQueueGroup { - /// Create a new, empty queue group for a queue family. - pub fn new(family: B::QueueFamily) -> Self { - RawQueueGroup { - family, - queues: Vec::new(), - } - } - - /// Add a command queue to the group. - /// - /// The queue needs to be created from this queue family. - /// - /// # Panics - /// - /// Panics if more command queues are added than exposed by the queue family. - pub fn add_queue(&mut self, queue: B::CommandQueue) { - assert!(self.queues.len() < self.family.max_queues()); - self.queues.push(queue); - } -} - -impl Queues { - /// Create a new collection of queues. - pub fn new(queues: Vec>) -> Self { - Queues(queues) - } -} - /// Fast hash map used internally. pub type FastHashMap = HashMap>; diff --git a/src/hal/src/command/clear.rs b/src/hal/src/command/clear.rs new file mode 100644 index 00000000000..823a78891b9 --- /dev/null +++ b/src/hal/src/command/clear.rs @@ -0,0 +1,70 @@ +use crate::pso; +use std::fmt; + +/// A clear color union, which can be either f32, i32, or u32. +#[repr(C)] +#[derive(Clone, Copy)] +pub union ClearColor { + /// `f32` variant + pub float32: [f32; 4], + /// `i32` variant + pub sint32: [i32; 4], + /// `u32` variant + pub uint32: [u32; 4], +} + +impl std::fmt::Debug for ClearColor { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + writeln![f, "ClearColor"] + } +} + +/// A combination of depth and stencil clear values. +#[repr(C)] +#[derive(Clone, Copy, Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +pub struct ClearDepthStencil { + /// Depth value + pub depth: f32, + /// Stencil value + pub stencil: u32, +} + +/// A set of clear values for a single attachment. +#[repr(C)] +#[derive(Clone, Copy)] +pub union ClearValue { + /// Clear color + pub color: ClearColor, + /// Clear depth and stencil + pub depth_stencil: ClearDepthStencil, + _align: [u32; 4], +} + +impl fmt::Debug for ClearValue { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("ClearValue") + .field("color", unsafe { &self.color.uint32 }) + .field("depth_stencil", unsafe { &self.depth_stencil }) + .finish() + } +} + +/// Attachment clear description for the current subpass. +#[derive(Clone, Copy, Debug)] +pub enum AttachmentClear { + /// Clear color attachment. + Color { + /// Index inside the `SubpassDesc::colors` array. + index: usize, + /// Value to clear with. + value: ClearColor, + }, + /// Clear depth-stencil attachment. + DepthStencil { + /// Depth value to clear with. + depth: Option, + /// Stencil value to clear with. + stencil: Option, + }, +} diff --git a/src/hal/src/command/compute.rs b/src/hal/src/command/compute.rs deleted file mode 100644 index 63bc4dc67ea..00000000000 --- a/src/hal/src/command/compute.rs +++ /dev/null @@ -1,52 +0,0 @@ -//! `CommandBuffer` methods for compute operations. - -use std::borrow::Borrow; - -use super::{CommandBuffer, DescriptorSetOffset, Level, RawCommandBuffer, Shot}; -use crate::buffer::Offset; -use crate::queue::capability::{Compute, Supports}; -use crate::{Backend, WorkGroupCount}; - -impl, S: Shot, L: Level> CommandBuffer { - /// Identical to the `RawCommandBuffer` method of the same name. - pub unsafe fn bind_compute_pipeline(&mut self, pipeline: &B::ComputePipeline) { - self.raw.bind_compute_pipeline(pipeline) - } - - /// Identical to the `RawCommandBuffer` method of the same name. - pub unsafe fn bind_compute_descriptor_sets( - &mut self, - layout: &B::PipelineLayout, - first_set: usize, - sets: I, - offsets: J, - ) where - I: IntoIterator, - I::Item: Borrow, - J: IntoIterator, - J::Item: Borrow, - { - self.raw - .bind_compute_descriptor_sets(layout, first_set, sets, offsets) - } - - /// Identical to the `RawCommandBuffer` method of the same name. - pub unsafe fn dispatch(&mut self, count: WorkGroupCount) { - self.raw.dispatch(count) - } - - /// Identical to the `RawCommandBuffer` method of the same name. - pub unsafe fn dispatch_indirect(&mut self, buffer: &B::Buffer, offset: Offset) { - self.raw.dispatch_indirect(buffer, offset) - } - - /// Identical to the `RawCommandBuffer` method of the same name. - pub unsafe fn push_compute_constants( - &mut self, - layout: &B::PipelineLayout, - offset: u32, - constants: &[u32], - ) { - self.raw.push_compute_constants(layout, offset, constants); - } -} diff --git a/src/hal/src/command/graphics.rs b/src/hal/src/command/graphics.rs deleted file mode 100644 index 6d1b1dab2e0..00000000000 --- a/src/hal/src/command/graphics.rs +++ /dev/null @@ -1,398 +0,0 @@ -//! `CommandBuffer` methods for graphics operations. -use std::borrow::Borrow; -use std::ops::Range; - -use super::{ - ClearColorRaw, - ClearDepthStencilRaw, - ClearValueRaw, - CommandBuffer, - DescriptorSetOffset, - Level, - Primary, - RawCommandBuffer, - RenderPassInlineEncoder, - RenderPassSecondaryEncoder, - Shot, -}; -use crate::queue::capability::{Graphics, GraphicsOrCompute, Supports}; -use crate::Backend; -use crate::{buffer, image, pso, query}; - -/// A universal clear color supporting integer formats -/// as well as the standard floating-point. -#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -pub enum ClearColor { - /// Standard floating-point `vec4` color - Sfloat(pso::ColorValue), - /// Integer vector to clear `ivec4` targets. - Sint([i32; 4]), - /// Unsigned int vector to clear `uvec4` targets. - Uint([u32; 4]), -} - -macro_rules! impl_clear { - { $( $ty:ty = $sub:ident[$a:expr, $b:expr, $c:expr, $d:expr], )* } => { - $( - impl From<$ty> for ClearColor { - fn from(v: $ty) -> Self { - ClearColor::$sub([v[$a], v[$b], v[$c], v[$d]]) - } - } - )* - } -} - -impl_clear! { - [f32; 4] = Sfloat[0, 1, 2, 3], - [f32; 3] = Sfloat[0, 1, 2, 0], - [f32; 2] = Sfloat[0, 1, 0, 0], - [i32; 4] = Sint [0, 1, 2, 3], - [i32; 3] = Sint [0, 1, 2, 0], - [i32; 2] = Sint [0, 1, 0, 0], - [u32; 4] = Uint [0, 1, 2, 3], - [u32; 3] = Uint [0, 1, 2, 0], - [u32; 2] = Uint [0, 1, 0, 0], -} - -impl From for ClearColor { - fn from(v: f32) -> Self { - ClearColor::Sfloat([v, 0.0, 0.0, 0.0]) - } -} -impl From for ClearColor { - fn from(v: i32) -> Self { - ClearColor::Sint([v, 0, 0, 0]) - } -} -impl From for ClearColor { - fn from(v: u32) -> Self { - ClearColor::Uint([v, 0, 0, 0]) - } -} - -impl From for ClearColorRaw { - fn from(cv: ClearColor) -> Self { - match cv { - ClearColor::Sfloat(cv) => ClearColorRaw { float32: cv }, - ClearColor::Sint(cv) => ClearColorRaw { int32: cv }, - ClearColor::Uint(cv) => ClearColorRaw { uint32: cv }, - } - } -} - -/// Depth-stencil target clear values. -#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -pub struct ClearDepthStencil(pub pso::DepthValue, pub pso::StencilValue); - -impl From for ClearDepthStencilRaw { - fn from(value: ClearDepthStencil) -> Self { - ClearDepthStencilRaw { - depth: value.0, - stencil: value.1, - } - } -} - -/// General clear values for attachments (color or depth-stencil). -#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -pub enum ClearValue { - /// - Color(ClearColor), - /// - DepthStencil(ClearDepthStencil), -} - -impl From for ClearValueRaw { - fn from(value: ClearValue) -> Self { - match value { - ClearValue::Color(color) => ClearValueRaw { - color: color.into(), - }, - ClearValue::DepthStencil(ds) => ClearValueRaw { - depth_stencil: ds.into(), - }, - } - } -} - -/// Attachment clear description for the current subpass. -#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -pub enum AttachmentClear { - /// Clear color attachment. - Color { - /// Index inside the `SubpassDesc::colors` array. - index: usize, - /// Value to clear with. - value: ClearColor, - }, - /// Clear depth-stencil attachment. - DepthStencil { - /// Depth value to clear with. - depth: Option, - /// Stencil value to clear with. - stencil: Option, - }, -} - -/// Parameters for an image resolve operation, -/// where a multi-sampled image is copied into a single-sampled -/// image. -#[derive(Clone, Debug)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -pub struct ImageResolve { - /// Source image and layers. - pub src_subresource: image::SubresourceLayers, - /// Source image offset. - pub src_offset: image::Offset, - /// Destination image and layers. - pub dst_subresource: image::SubresourceLayers, - /// Destination image offset. - pub dst_offset: image::Offset, - /// Image extent. - pub extent: image::Extent, -} - -/// Parameters for an image blit operation, where a portion of one image -/// is copied into another, possibly with scaling and filtering. -#[derive(Clone, Debug)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -pub struct ImageBlit { - /// Source image and layers. - pub src_subresource: image::SubresourceLayers, - /// Source image bounds. - pub src_bounds: Range, - /// Destination image and layers. - pub dst_subresource: image::SubresourceLayers, - /// Destination image bounds. - pub dst_bounds: Range, -} - -impl, S: Shot, L: Level> CommandBuffer { - /// Identical to the `RawCommandBuffer` method of the same name. - pub unsafe fn clear_image( - &mut self, - image: &B::Image, - layout: image::Layout, - color: ClearColor, - depth_stencil: ClearDepthStencil, - subresource_ranges: T, - ) where - T: IntoIterator, - T::Item: Borrow, - { - self.raw.clear_image( - image, - layout, - color.into(), - depth_stencil.into(), - subresource_ranges, - ) - } - - /// Identical to the `RawCommandBuffer` method of the same name. - pub unsafe fn bind_index_buffer(&mut self, ibv: buffer::IndexBufferView) { - self.raw.bind_index_buffer(ibv) - } - - /// Identical to the `RawCommandBuffer` method of the same name. - pub unsafe fn bind_vertex_buffers(&mut self, first_binding: pso::BufferIndex, buffers: I) - where - I: IntoIterator, - T: Borrow, - { - self.raw.bind_vertex_buffers(first_binding, buffers) - } - - /// Identical to the `RawCommandBuffer` method of the same name. - pub unsafe fn bind_graphics_pipeline(&mut self, pipeline: &B::GraphicsPipeline) { - self.raw.bind_graphics_pipeline(pipeline) - } - - /// Identical to the `RawCommandBuffer` method of the same name. - pub unsafe fn bind_graphics_descriptor_sets( - &mut self, - layout: &B::PipelineLayout, - first_set: usize, - sets: I, - offsets: J, - ) where - I: IntoIterator, - I::Item: Borrow, - J: IntoIterator, - J::Item: Borrow, - { - self.raw - .bind_graphics_descriptor_sets(layout, first_set, sets, offsets) - } - - /// Identical to the `RawCommandBuffer` method of the same name. - pub unsafe fn set_viewports(&mut self, first_viewport: u32, viewports: T) - where - T: IntoIterator, - T::Item: Borrow, - { - self.raw.set_viewports(first_viewport, viewports) - } - - /// Identical to the `RawCommandBuffer` method of the same name. - pub unsafe fn set_scissors(&mut self, first_scissor: u32, scissors: T) - where - T: IntoIterator, - T::Item: Borrow, - { - self.raw.set_scissors(first_scissor, scissors) - } - - /// Identical to the `RawCommandBuffer` method of the same name. - pub unsafe fn set_stencil_reference(&mut self, faces: pso::Face, value: pso::StencilValue) { - self.raw.set_stencil_reference(faces, value); - } - - /// Identical to the `RawCommandBuffer` method of the same name. - pub unsafe fn set_stencil_read_mask(&mut self, faces: pso::Face, value: pso::StencilValue) { - self.raw.set_stencil_read_mask(faces, value); - } - - /// Identical to the `RawCommandBuffer` method of the same name. - pub unsafe fn set_stencil_write_mask(&mut self, faces: pso::Face, value: pso::StencilValue) { - self.raw.set_stencil_write_mask(faces, value); - } - - /// Identical to the `RawCommandBuffer` method of the same name. - pub unsafe fn set_blend_constants(&mut self, cv: pso::ColorValue) { - self.raw.set_blend_constants(cv) - } - - /// Identical to the `RawCommandBuffer` method of the same name. - pub unsafe fn set_depth_bounds(&mut self, bounds: Range) { - self.raw.set_depth_bounds(bounds) - } - - /// Identical to the `RawCommandBuffer` method of the same name. - pub unsafe fn set_line_width(&mut self, width: f32) { - self.raw.set_line_width(width); - } - - /// Identical to the `RawCommandBuffer` method of the same name. - pub unsafe fn set_depth_bias(&mut self, depth_bias: pso::DepthBias) { - self.raw.set_depth_bias(depth_bias); - } - - /// Identical to the `RawCommandBuffer` method of the same name. - pub unsafe fn push_graphics_constants( - &mut self, - layout: &B::PipelineLayout, - stages: pso::ShaderStageFlags, - offset: u32, - constants: &[u32], - ) { - self.raw - .push_graphics_constants(layout, stages, offset, constants) - } - - /// Identical to the `RawCommandBuffer` method of the same name. - pub unsafe fn resolve_image( - &mut self, - src: &B::Image, - src_layout: image::Layout, - dst: &B::Image, - dst_layout: image::Layout, - regions: T, - ) where - T: IntoIterator, - T::Item: Borrow, - { - self.raw - .resolve_image(src, src_layout, dst, dst_layout, regions) - } - - /// Identical to the `RawCommandBuffer` method of the same name. - pub unsafe fn blit_image( - &mut self, - src: &B::Image, - src_layout: image::Layout, - dst: &B::Image, - dst_layout: image::Layout, - filter: image::Filter, - regions: T, - ) where - T: IntoIterator, - T::Item: Borrow, - { - self.raw - .blit_image(src, src_layout, dst, dst_layout, filter, regions) - } -} - -impl, S: Shot> CommandBuffer { - /// Identical to the `RawCommandBuffer` method of the same name. - pub unsafe fn begin_render_pass_inline( - &mut self, - render_pass: &B::RenderPass, - frame_buffer: &B::Framebuffer, - render_area: pso::Rect, - clear_values: T, - ) -> RenderPassInlineEncoder - where - T: IntoIterator, - T::Item: Borrow, - { - RenderPassInlineEncoder::new(self, render_pass, frame_buffer, render_area, clear_values) - } - - /// Creates a new secondary render pass. - pub unsafe fn begin_render_pass_secondary( - &mut self, - render_pass: &B::RenderPass, - frame_buffer: &B::Framebuffer, - render_area: pso::Rect, - clear_values: T, - ) -> RenderPassSecondaryEncoder - where - T: IntoIterator, - T::Item: Borrow, - { - RenderPassSecondaryEncoder::new(self, render_pass, frame_buffer, render_area, clear_values) - } -} - -impl, S: Shot, L: Level> CommandBuffer { - /// Identical to the `RawCommandBuffer` method of the same name. - pub unsafe fn begin_query(&mut self, query: query::Query, flags: query::ControlFlags) { - self.raw.begin_query(query, flags) - } - - /// Identical to the `RawCommandBuffer` method of the same name. - pub unsafe fn end_query(&mut self, query: query::Query) { - self.raw.end_query(query) - } - - /// Identical to the `RawCommandBuffer` method of the same name. - pub unsafe fn reset_query_pool(&mut self, pool: &B::QueryPool, queries: Range) { - self.raw.reset_query_pool(pool, queries) - } - - /// Identical to the `RawCommandBuffer` method of the same name. - pub unsafe fn copy_query_pool_results( - &mut self, - pool: &B::QueryPool, - queries: Range, - buffer: &B::Buffer, - offset: buffer::Offset, - stride: buffer::Offset, - flags: query::ResultFlags, - ) { - self.raw - .copy_query_pool_results(pool, queries, buffer, offset, stride, flags) - } - - /// Identical to the `RawCommandBuffer` method of the same name. - pub unsafe fn write_timestamp(&mut self, stage: pso::PipelineStage, query: query::Query) { - self.raw.write_timestamp(stage, query) - } -} diff --git a/src/hal/src/command/mod.rs b/src/hal/src/command/mod.rs index 95c2599b748..d6308982638 100644 --- a/src/hal/src/command/mod.rs +++ b/src/hal/src/command/mod.rs @@ -13,205 +13,548 @@ // TODO: Document pipelines and subpasses better. -use crate::queue::capability::{Capability, Supports}; -use crate::Backend; +mod clear; +mod structs; +use std::any::Any; use std::borrow::Borrow; -use std::marker::PhantomData; - -mod compute; -mod graphics; -mod raw; -mod render_pass; -mod transfer; - -pub use self::graphics::*; -pub use self::raw::{ - ClearColorRaw, - ClearDepthStencilRaw, - ClearValueRaw, - CommandBufferFlags, - CommandBufferInheritanceInfo, - DescriptorSetOffset, - IntoRawCommandBuffer, - Level as RawLevel, - RawCommandBuffer, -}; -pub use self::render_pass::*; -pub use self::transfer::*; - -/// Trait indicating how many times a Submit object can be submitted to a command buffer. -pub trait Shot {} -/// Indicates a Submit that can only be submitted once. -#[derive(Debug)] -pub enum OneShot {} -impl Shot for OneShot {} +use std::fmt; +use std::ops::Range; -/// Indicates a Submit that can be submitted multiple times. -#[derive(Debug)] -pub enum MultiShot {} -impl Shot for MultiShot {} +use crate::image::{Filter, Layout, SubresourceRange}; +use crate::memory::{Barrier, Dependencies}; +use crate::range::RangeArg; +use crate::{buffer, pass, pso, query}; +use crate::{ + Backend, + DrawCount, + IndexCount, + InstanceCount, + VertexCount, + VertexOffset, + WorkGroupCount, +}; -/// A trait indicating the level of a command buffer. -pub trait Level {} +pub use self::clear::*; +pub use self::structs::*; -/// Indicates a primary command buffer. -/// Vulkan describes a primary command buffer as one which can be directly submitted -/// to a queue, and can execute `Secondary` command buffers. -#[derive(Debug)] -pub enum Primary {} -impl Level for Primary {} - -/// Indicates a secondary command buffer. -/// -/// Vulkan describes a secondary command buffer as one which cannot be directly submitted -/// to a queue, but can be executed by a primary command buffer. This allows -/// multiple secondary command buffers to be constructed which do specific -/// things and can then be composed together into primary command buffers. -#[derive(Debug)] -pub enum Secondary {} -impl Level for Secondary {} +/// Offset for dynamic descriptors. +pub type DescriptorSetOffset = u32; -/// A property of a command buffer to be submitted to a queue with specific capability. -pub trait Submittable: Borrow {} +bitflags! { + /// Option flags for various command buffer settings. + #[derive(Default)] + pub struct CommandBufferFlags: u32 { + // TODO: Remove once 'const fn' is stabilized: https://github.com/rust-lang/rust/issues/24111 + /// No flags. + const EMPTY = 0x0; -/// A convenience alias for not typing out the full signature of a secondary command buffer. -pub type SecondaryCommandBuffer = CommandBuffer; + /// Says that the command buffer will be recorded, submitted only once, and then reset and re-filled + /// for another submission. + const ONE_TIME_SUBMIT = 0x1; -/// A strongly-typed command buffer that will only implement methods that are valid for the operations -/// it supports. -#[derive(Debug)] -pub struct CommandBuffer::CommandBuffer> -{ - pub(crate) raw: R, - pub(crate) _marker: PhantomData<(B, C, S, L)>, -} + /// If set on a secondary command buffer, it says the command buffer takes place entirely inside + /// a render pass. Ignored on primary command buffer. + const RENDER_PASS_CONTINUE = 0x2; -impl Borrow for CommandBuffer -where - R: RawCommandBuffer, - B: Backend, -{ - fn borrow(&self) -> &B::CommandBuffer { - &self.raw + /// Says that a command buffer can be recorded into multiple primary command buffers, + /// and submitted to a queue while it is still pending. + const SIMULTANEOUS_USE = 0x4; } } -impl, S, L: Level> Submittable - for CommandBuffer -{ +/// An enum that indicates at runtime whether a command buffer +/// is primary or secondary, similar to what `command::Primary` +/// and `command::Secondary` do at compile-time. +#[allow(missing_docs)] +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum Level { + Primary, + Secondary, } -impl IntoRawCommandBuffer for CommandBuffer { - fn into_raw(self) -> B::CommandBuffer { - self.raw - } +/// Specifies how commands for the following renderpasses will be recorded. +#[derive(Debug)] +pub enum SubpassContents { + /// Contents of the subpass will be inline in the command buffer, + /// NOT in secondary command buffers. + Inline, + /// Contents of the subpass will be in secondary command buffers, and + /// the primary command buffer will only contain `execute_command()` calls + /// until the subpass or render pass is complete. + SecondaryBuffers, } -impl CommandBuffer { - /// Begin recording a one-shot primary command buffer. - pub unsafe fn begin(&mut self) { - let flags = CommandBufferFlags::ONE_TIME_SUBMIT; - self.raw - .begin(flags, CommandBufferInheritanceInfo::default()); - } +#[allow(missing_docs)] +#[derive(Debug)] +pub struct CommandBufferInheritanceInfo<'a, B: Backend> { + pub subpass: Option>, + pub framebuffer: Option<&'a B::Framebuffer>, + pub occlusion_query_enable: bool, + pub occlusion_query_flags: query::ControlFlags, + pub pipeline_statistics: query::PipelineStatistic, } -impl CommandBuffer { - /// Begin recording a multi-shot primary command buffer. - pub unsafe fn begin(&mut self, allow_pending_resubmit: bool) { - let flags = if allow_pending_resubmit { - CommandBufferFlags::SIMULTANEOUS_USE - } else { - CommandBufferFlags::empty() - }; - self.raw - .begin(flags, CommandBufferInheritanceInfo::default()); +impl<'a, B: Backend> Default for CommandBufferInheritanceInfo<'a, B> { + fn default() -> Self { + CommandBufferInheritanceInfo { + subpass: None, + framebuffer: None, + occlusion_query_enable: false, + occlusion_query_flags: query::ControlFlags::empty(), + pipeline_statistics: query::PipelineStatistic::empty(), + } } } -impl CommandBuffer { - /// Begin recording a one-shot secondary command buffer. - pub unsafe fn begin(&mut self, inheritance: CommandBufferInheritanceInfo) { - let flags = CommandBufferFlags::ONE_TIME_SUBMIT; - self.raw.begin(flags, inheritance); - } -} +/// A trait that describes all the operations that must be +/// provided by a `Backend`'s command buffer. +pub trait CommandBuffer: fmt::Debug + Any + Send + Sync { + /// Begins recording commands to a command buffer. + unsafe fn begin( + &mut self, + flags: CommandBufferFlags, + inheritance_info: CommandBufferInheritanceInfo, + ); -impl CommandBuffer { - /// Begin recording a multi-shot secondary command buffer. - pub unsafe fn begin( - &mut self, - allow_pending_resubmit: bool, - inheritance: CommandBufferInheritanceInfo, - ) { - let flags = if allow_pending_resubmit { - CommandBufferFlags::SIMULTANEOUS_USE - } else { - CommandBufferFlags::empty() - }; - self.raw.begin(flags, inheritance); + /// Begins recording a primary command buffer + /// (that has no inheritance information). + unsafe fn begin_primary(&mut self, flags: CommandBufferFlags) { + self.begin(flags, CommandBufferInheritanceInfo::default()); } -} -impl CommandBuffer { - /// Create a new typed command buffer from a raw command pool. - pub unsafe fn new(raw: B::CommandBuffer) -> Self { - CommandBuffer { - raw, - _marker: PhantomData, - } - } + /// Finish recording commands to a command buffer. + unsafe fn finish(&mut self); + + /// Empties the command buffer, optionally releasing all + /// resources from the commands that have been submitted. + unsafe fn reset(&mut self, release_resources: bool); + + // TODO: This REALLY needs to be deeper, but it's complicated. + // Should probably be a whole book chapter on synchronization and stuff really. + /// Inserts a synchronization dependency between pipeline stages + /// in the command buffer. + unsafe fn pipeline_barrier<'a, T>( + &mut self, + stages: Range, + dependencies: Dependencies, + barriers: T, + ) where + T: IntoIterator, + T::Item: Borrow>; + + /// Fill a buffer with the given `u32` value. + unsafe fn fill_buffer(&mut self, buffer: &B::Buffer, range: R, data: u32) + where + R: RangeArg; + + /// Copy data from the given slice into a buffer. + unsafe fn update_buffer(&mut self, buffer: &B::Buffer, offset: buffer::Offset, data: &[u8]); + + /// Clears an image to the given color/depth/stencil. + unsafe fn clear_image( + &mut self, + image: &B::Image, + layout: Layout, + value: ClearValue, + subresource_ranges: T, + ) where + T: IntoIterator, + T::Item: Borrow; - /// Finish recording commands to the command buffers. + /// Takes an iterator of attachments and an iterator of rect's, + /// and clears the given rect's for *each* attachment. + unsafe fn clear_attachments(&mut self, clears: T, rects: U) + where + T: IntoIterator, + T::Item: Borrow, + U: IntoIterator, + U::Item: Borrow; + + /// "Resolves" a multisampled image, converting it into a non-multisampled + /// image. Takes an iterator of regions to apply the resolution to. + unsafe fn resolve_image( + &mut self, + src: &B::Image, + src_layout: Layout, + dst: &B::Image, + dst_layout: Layout, + regions: T, + ) where + T: IntoIterator, + T::Item: Borrow; + + /// Copies regions from the source to destination image, + /// applying scaling, filtering and potentially format conversion. + unsafe fn blit_image( + &mut self, + src: &B::Image, + src_layout: Layout, + dst: &B::Image, + dst_layout: Layout, + filter: Filter, + regions: T, + ) where + T: IntoIterator, + T::Item: Borrow; + + /// Bind the index buffer view, making it the "current" one that draw commands + /// will operate on. + unsafe fn bind_index_buffer(&mut self, view: buffer::IndexBufferView); + + /// Bind the vertex buffer set, making it the "current" one that draw commands + /// will operate on. /// - /// The command buffer must be reset to able to re-record commands. - pub unsafe fn finish(&mut self) { - self.raw.finish(); - } + /// Each buffer passed corresponds to the vertex input binding with the same index, + /// starting from an offset index `first_binding`. For example an iterator with + /// two items and `first_binding` of 1 would fill vertex buffer binding numbers + /// 1 and 2. + /// + /// This binding number refers only to binding points for vertex buffers and is + /// completely separate from the binding numbers of `Descriptor`s in `DescriptorSet`s. + /// It needs to match with the `VertexBufferDesc` and `AttributeDesc`s to which the + /// data from each bound vertex buffer should flow. + /// + /// The `buffers` iterator should yield the `Buffer` to bind, as well as an + /// offset, in bytes, into that buffer where the vertex data that should be bound + /// starts. + unsafe fn bind_vertex_buffers(&mut self, first_binding: pso::BufferIndex, buffers: I) + where + I: IntoIterator, + T: Borrow; - /// Empties the command buffer, optionally releasing all resources from the - /// commands that have been submitted. The command buffer is moved back to - /// the "initial" state. + /// Set the viewport parameters for the rasterizer. /// - /// The command buffer must not be in the "pending" state. Additionally, the - /// command pool must have been created with the RESET_INDIVIDUAL flag to be - /// able to reset individual buffers. - pub unsafe fn reset(&mut self, release_resources: bool) { - self.raw.reset(release_resources); - } + /// Each viewport passed corresponds to the viewport with the same index, + /// starting from an offset index `first_viewport`. + /// + /// # Errors + /// + /// This function does not return an error. Invalid usage of this function + /// will result in undefined behavior. + /// + /// - Command buffer must be in recording state. + /// - Number of viewports must be between 1 and `max_viewports - first_viewport`. + /// - The first viewport must be less than `max_viewports`. + /// - Only queues with graphics capability support this function. + /// - The bound pipeline must not have baked viewport state. + /// - All viewports used by the pipeline must be specified before the first + /// draw call. + unsafe fn set_viewports(&mut self, first_viewport: u32, viewports: T) + where + T: IntoIterator, + T::Item: Borrow; - /* - /// Get a reference to the raw command buffer - pub fn as_raw(&self) -> &B::CommandBuffer { - &self.raw - } + /// Set the scissor rectangles for the rasterizer. + /// + /// Each scissor corresponds to the viewport with the same index, starting + /// from an offset index `first_scissor`. + /// + /// # Errors + /// + /// This function does not return an error. Invalid usage of this function + /// will result in undefined behavior. + /// + /// - Command buffer must be in recording state. + /// - Number of scissors must be between 1 and `max_viewports - first_scissor`. + /// - The first scissor must be less than `max_viewports`. + /// - Only queues with graphics capability support this function. + /// - The bound pipeline must not have baked scissor state. + /// - All scissors used by the pipeline must be specified before the first draw + /// call. + unsafe fn set_scissors(&mut self, first_scissor: u32, rects: T) + where + T: IntoIterator, + T::Item: Borrow; + + /// Sets the stencil reference value for comparison operations and store operations. + /// Will be used on the LHS of stencil compare ops and as store value when the + /// store op is Reference. + unsafe fn set_stencil_reference(&mut self, faces: pso::Face, value: pso::StencilValue); + + /// Sets the stencil read mask. + unsafe fn set_stencil_read_mask(&mut self, faces: pso::Face, value: pso::StencilValue); + + /// Sets the stencil write mask. + unsafe fn set_stencil_write_mask(&mut self, faces: pso::Face, value: pso::StencilValue); + + /// Set the blend constant values dynamically. + unsafe fn set_blend_constants(&mut self, color: pso::ColorValue); + + /// Set the depth bounds test values dynamically. + unsafe fn set_depth_bounds(&mut self, bounds: Range); + + /// Set the line width dynamically. + unsafe fn set_line_width(&mut self, width: f32); - /// Get a mutable reference to the raw command buffer - pub fn as_raw_mut(&mut self) -> &mut B::CommandBuffer { - &mut self.raw - }*/ + /// Set the depth bias dynamically. + unsafe fn set_depth_bias(&mut self, depth_bias: pso::DepthBias); - /// Downgrade a command buffer to a lesser capability type. - pub unsafe fn downgrade(&mut self) -> &mut CommandBuffer + /// Begins recording commands for a render pass on the given framebuffer. + /// `render_area` is the section of the framebuffer to render, + /// `clear_values` is an iterator of `ClearValueRaw`'s to use to use for + /// `clear_*` commands, one for each attachment of the render pass + /// that has a clear operation. + /// `first_subpass` specifies, for the first subpass, whether the + /// rendering commands are provided inline or whether the render + /// pass is composed of subpasses. + unsafe fn begin_render_pass( + &mut self, + render_pass: &B::RenderPass, + framebuffer: &B::Framebuffer, + render_area: pso::Rect, + clear_values: T, + first_subpass: SubpassContents, + ) where + T: IntoIterator, + T::Item: Borrow; + + /// Steps to the next subpass in the current render pass. + unsafe fn next_subpass(&mut self, contents: SubpassContents); + + /// Finishes recording commands for the current a render pass. + unsafe fn end_render_pass(&mut self); + + /// Bind a graphics pipeline. + /// + /// # Errors + /// + /// This function does not return an error. Invalid usage of this function + /// will result in an error on `finish`. + /// + /// - Command buffer must be in recording state. + /// - Only queues with graphics capability support this function. + unsafe fn bind_graphics_pipeline(&mut self, pipeline: &B::GraphicsPipeline); + + /// Takes an iterator of graphics `DescriptorSet`'s, and binds them to the command buffer. + /// `first_set` is the index that the first descriptor is mapped to in the command buffer. + unsafe fn bind_graphics_descriptor_sets( + &mut self, + layout: &B::PipelineLayout, + first_set: usize, + sets: I, + offsets: J, + ) where + I: IntoIterator, + I::Item: Borrow, + J: IntoIterator, + J::Item: Borrow; + + /// Bind a compute pipeline. + /// + /// # Errors + /// + /// This function does not return an error. Invalid usage of this function + /// will result in an error on `finish`. + /// + /// - Command buffer must be in recording state. + /// - Only queues with compute capability support this function. + unsafe fn bind_compute_pipeline(&mut self, pipeline: &B::ComputePipeline); + + /// Takes an iterator of compute `DescriptorSet`'s, and binds them to the command buffer, + /// `first_set` is the index that the first descriptor is mapped to in the command buffer. + unsafe fn bind_compute_descriptor_sets( + &mut self, + layout: &B::PipelineLayout, + first_set: usize, + sets: I, + offsets: J, + ) where + I: IntoIterator, + I::Item: Borrow, + J: IntoIterator, + J::Item: Borrow; + + /// Execute a workgroup in the compute pipeline. `x`, `y` and `z` are the + /// number of local workgroups to dispatch along each "axis"; a total of `x`*`y`*`z` + /// local workgroups will be created. + /// + /// # Errors + /// + /// This function does not return an error. Invalid usage of this function + /// will result in an error on `finish`. + /// + /// - Command buffer must be in recording state. + /// - A compute pipeline must be bound using `bind_compute_pipeline`. + /// - Only queues with compute capability support this function. + /// - This function must be called outside of a render pass. + /// - `count` must be less than or equal to `Limits::max_compute_work_group_count` + /// + /// TODO: + unsafe fn dispatch(&mut self, count: WorkGroupCount); + + /// Works similarly to `dispatch()` but reads parameters from the given + /// buffer during execution. + unsafe fn dispatch_indirect(&mut self, buffer: &B::Buffer, offset: buffer::Offset); + + /// Adds a command to copy regions from the source to destination buffer. + unsafe fn copy_buffer(&mut self, src: &B::Buffer, dst: &B::Buffer, regions: T) where - C: Supports, - { - ::std::mem::transmute(self) - } -} + T: IntoIterator, + T::Item: Borrow; + + /// Copies regions from the source to the destination images, which + /// have the given layouts. No format conversion is done; the source and destination + /// `Layout`'s **must** have the same sized image formats (such as `Rgba8Unorm` and + /// `R32`, both of which are 32 bits). + unsafe fn copy_image( + &mut self, + src: &B::Image, + src_layout: Layout, + dst: &B::Image, + dst_layout: Layout, + regions: T, + ) where + T: IntoIterator, + T::Item: Borrow; + + /// Copies regions from the source buffer to the destination image. + unsafe fn copy_buffer_to_image( + &mut self, + src: &B::Buffer, + dst: &B::Image, + dst_layout: Layout, + regions: T, + ) where + T: IntoIterator, + T::Item: Borrow; -impl CommandBuffer { - /// Identical to the `RawCommandBuffer` method of the same name. - pub unsafe fn execute_commands<'a, I, T, K>(&mut self, cmd_buffers: I) + /// Copies regions from the source image to the destination buffer. + unsafe fn copy_image_to_buffer( + &mut self, + src: &B::Image, + src_layout: Layout, + dst: &B::Buffer, + regions: T, + ) where + T: IntoIterator, + T::Item: Borrow; + + // TODO: This explanation needs improvement. + /// Performs a non-indexed drawing operation, fetching vertex attributes + /// from the currently bound vertex buffers. It performs instanced + /// drawing, drawing `instances.len()` + /// times with an `instanceIndex` starting with the start of the range. + unsafe fn draw(&mut self, vertices: Range, instances: Range); + + /// Performs indexed drawing, drawing the range of indices + /// given by the current index buffer and any bound vertex buffers. + /// `base_vertex` specifies the vertex offset corresponding to index 0. + /// That is, the offset into the vertex buffer is `(current_index + base_vertex)` + /// + /// It also performs instanced drawing, identical to `draw()`. + unsafe fn draw_indexed( + &mut self, + indices: Range, + base_vertex: VertexOffset, + instances: Range, + ); + + /// Functions identically to `draw()`, except the parameters are read + /// from the given buffer, starting at `offset` and increasing `stride` + /// bytes with each successive draw. Performs `draw_count` draws total. + /// `draw_count` may be zero. + /// + /// Each draw command in the buffer is a series of 4 `u32` values specifying, + /// in order, the number of vertices to draw, the number of instances to draw, + /// the index of the first vertex to draw, and the instance ID of the first + /// instance to draw. + unsafe fn draw_indirect( + &mut self, + buffer: &B::Buffer, + offset: buffer::Offset, + draw_count: DrawCount, + stride: u32, + ); + + /// Like `draw_indirect()`, this does indexed drawing a la `draw_indexed()` but + /// reads the draw parameters out of the given buffer. + /// + /// Each draw command in the buffer is a series of 5 values specifying, + /// in order, the number of indices, the number of instances, the first index, + /// the vertex offset, and the first instance. All are `u32`'s except + /// the vertex offset, which is an `i32`. + unsafe fn draw_indexed_indirect( + &mut self, + buffer: &B::Buffer, + offset: buffer::Offset, + draw_count: DrawCount, + stride: u32, + ); + + /// Signals an event once all specified stages of the shader pipeline have completed. + unsafe fn set_event(&mut self, event: &B::Event, stages: pso::PipelineStage); + + /// Resets an event once all specified stages of the shader pipeline have completed. + unsafe fn reset_event(&mut self, event: &B::Event, stages: pso::PipelineStage); + + /// Waits at some shader stage(s) until all events have been signalled. + /// + /// - `src_stages` specifies the shader pipeline stages in which the events were signalled. + /// - `dst_stages` specifies the shader pipeline stages at which execution should wait. + /// - `barriers` specifies a series of memory barriers to be executed before pipeline execution + /// resumes. + unsafe fn wait_events<'a, I, J>( + &mut self, + events: I, + stages: Range, + barriers: J, + ) where + I: IntoIterator, + I::Item: Borrow, + J: IntoIterator, + J::Item: Borrow>; + + /// Begins a query operation. Queries count operations or record timestamps + /// resulting from commands that occur between the beginning and end of the query, + /// and save the results to the query pool. + unsafe fn begin_query(&mut self, query: query::Query, flags: query::ControlFlags); + + /// End a query. + unsafe fn end_query(&mut self, query: query::Query); + + /// Reset/clear the values in the given range of the query pool. + unsafe fn reset_query_pool(&mut self, pool: &B::QueryPool, queries: Range); + + /// Copy query results into a buffer. + unsafe fn copy_query_pool_results( + &mut self, + pool: &B::QueryPool, + queries: Range, + buffer: &B::Buffer, + offset: buffer::Offset, + stride: buffer::Offset, + flags: query::ResultFlags, + ); + + /// Requests a timestamp to be written. + unsafe fn write_timestamp(&mut self, stage: pso::PipelineStage, query: query::Query); + + /// Modify constant data in a graphics pipeline. + /// Push constants are intended to modify data in a pipeline more + /// quickly than a updating the values inside a descriptor set. + unsafe fn push_graphics_constants( + &mut self, + layout: &B::PipelineLayout, + stages: pso::ShaderStageFlags, + offset: u32, + constants: &[u32], + ); + + /// Modify constant data in a compute pipeline. + /// Push constants are intended to modify data in a pipeline more + /// quickly than a updating the values inside a descriptor set. + unsafe fn push_compute_constants( + &mut self, + layout: &B::PipelineLayout, + offset: u32, + constants: &[u32], + ); + + /// Execute the given secondary command buffers. + unsafe fn execute_commands<'a, T, I>(&mut self, cmd_buffers: I) where - K: Capability, - T: 'a + Submittable, - I: IntoIterator, - C: Supports, - { - self.raw - .execute_commands(cmd_buffers.into_iter().map(|cmb| cmb.borrow())); - } + T: 'a + Borrow, + I: IntoIterator; } diff --git a/src/hal/src/command/raw.rs b/src/hal/src/command/raw.rs deleted file mode 100644 index c3649650979..00000000000 --- a/src/hal/src/command/raw.rs +++ /dev/null @@ -1,587 +0,0 @@ -use std::any::Any; -use std::borrow::Borrow; -use std::fmt; -use std::ops::Range; - -use super::{ - AttachmentClear, - BufferCopy, - BufferImageCopy, - ImageBlit, - ImageCopy, - ImageResolve, - SubpassContents, -}; -use crate::image::{Filter, Layout, SubresourceRange}; -use crate::memory::{Barrier, Dependencies}; -use crate::range::RangeArg; -use crate::{buffer, pass, pso, query}; -use crate::{ - Backend, - DrawCount, - IndexCount, - InstanceCount, - VertexCount, - VertexOffset, - WorkGroupCount, -}; - -/// Unsafe variant of `ClearColor`. -#[repr(C)] -#[derive(Clone, Copy)] -pub union ClearColorRaw { - /// `f32` variant - pub float32: [f32; 4], - /// `i32` variant - pub int32: [i32; 4], - /// `u32` variant - pub uint32: [u32; 4], - _align: [u32; 4], -} - -impl std::fmt::Debug for ClearColorRaw { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - writeln![f, "ClearColorRaw"] - } -} - -/// A variant of `ClearDepthStencil` that has a `#[repr(C)]` layout -/// and so is used when a known layout is needed. -#[repr(C)] -#[derive(Clone, Copy, Debug)] -pub struct ClearDepthStencilRaw { - /// Depth value - pub depth: f32, - /// Stencil value - pub stencil: u32, -} - -/// Unsafe variant of `ClearValue`. -#[repr(C)] -#[derive(Clone, Copy)] -pub union ClearValueRaw { - /// Clear color - pub color: ClearColorRaw, - /// Clear depth and stencil - pub depth_stencil: ClearDepthStencilRaw, - _align: [u32; 4], -} - -impl fmt::Debug for ClearValueRaw { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_struct("ClearValueRaw") - .field("color", unsafe { &self.color.uint32 }) - .field("depth_stencil", unsafe { &self.depth_stencil }) - .finish() - } -} - -/// Offset for dynamic descriptors. -pub type DescriptorSetOffset = u32; - -bitflags! { - /// Option flags for various command buffer settings. - #[derive(Default)] - pub struct CommandBufferFlags: u32 { - // TODO: Remove once 'const fn' is stabilized: https://github.com/rust-lang/rust/issues/24111 - /// No flags. - const EMPTY = 0x0; - - /// Says that the command buffer will be recorded, submitted only once, and then reset and re-filled - /// for another submission. - const ONE_TIME_SUBMIT = 0x1; - - /// If set on a secondary command buffer, it says the command buffer takes place entirely inside - /// a render pass. Ignored on primary command buffer. - const RENDER_PASS_CONTINUE = 0x2; - - // TODO: I feel like this could be better. - /// Says that a command buffer can be recorded into multiple primary command buffers, - /// and submitted to a queue while it is still pending. - const SIMULTANEOUS_USE = 0x4; - } -} - -/// An enum that indicates at runtime whether a command buffer -/// is primary or secondary, similar to what `command::Primary` -/// and `command::Secondary` do at compile-time. -#[allow(missing_docs)] -#[derive(Clone, Copy, Debug, PartialEq)] -pub enum Level { - Primary, - Secondary, -} - -#[allow(missing_docs)] -#[derive(Debug)] -pub struct CommandBufferInheritanceInfo<'a, B: Backend> { - pub subpass: Option>, - pub framebuffer: Option<&'a B::Framebuffer>, - pub occlusion_query_enable: bool, - pub occlusion_query_flags: query::ControlFlags, - pub pipeline_statistics: query::PipelineStatistic, -} - -impl<'a, B: Backend> Default for CommandBufferInheritanceInfo<'a, B> { - fn default() -> Self { - CommandBufferInheritanceInfo { - subpass: None, - framebuffer: None, - occlusion_query_enable: false, - occlusion_query_flags: query::ControlFlags::empty(), - pipeline_statistics: query::PipelineStatistic::empty(), - } - } -} - -/// A trait that describes all the operations that must be -/// provided by a `Backend`'s command buffer. -pub trait RawCommandBuffer: fmt::Debug + Any + Send + Sync { - /// Begins recording commands to a command buffer. - unsafe fn begin( - &mut self, - flags: CommandBufferFlags, - inheritance_info: CommandBufferInheritanceInfo, - ); - - /// Finish recording commands to a command buffer. - unsafe fn finish(&mut self); - - /// Empties the command buffer, optionally releasing all - /// resources from the commands that have been submitted. - unsafe fn reset(&mut self, release_resources: bool); - - // TODO: This REALLY needs to be deeper, but it's complicated. - // Should probably be a whole book chapter on synchronization and stuff really. - /// Inserts a synchronization dependency between pipeline stages - /// in the command buffer. - unsafe fn pipeline_barrier<'a, T>( - &mut self, - stages: Range, - dependencies: Dependencies, - barriers: T, - ) where - T: IntoIterator, - T::Item: Borrow>; - - /// Fill a buffer with the given `u32` value. - unsafe fn fill_buffer(&mut self, buffer: &B::Buffer, range: R, data: u32) - where - R: RangeArg; - - /// Copy data from the given slice into a buffer. - unsafe fn update_buffer(&mut self, buffer: &B::Buffer, offset: buffer::Offset, data: &[u8]); - - /// Clears an image to the given color/depth/stencil. - unsafe fn clear_image( - &mut self, - image: &B::Image, - layout: Layout, - color: ClearColorRaw, - depth_stencil: ClearDepthStencilRaw, - subresource_ranges: T, - ) where - T: IntoIterator, - T::Item: Borrow; - - /// Takes an iterator of attachments and an iterator of rect's, - /// and clears the given rect's for *each* attachment. - unsafe fn clear_attachments(&mut self, clears: T, rects: U) - where - T: IntoIterator, - T::Item: Borrow, - U: IntoIterator, - U::Item: Borrow; - - /// "Resolves" a multisampled image, converting it into a non-multisampled - /// image. Takes an iterator of regions to apply the resolution to. - unsafe fn resolve_image( - &mut self, - src: &B::Image, - src_layout: Layout, - dst: &B::Image, - dst_layout: Layout, - regions: T, - ) where - T: IntoIterator, - T::Item: Borrow; - - /// Copies regions from the source to destination image, - /// applying scaling, filtering and potentially format conversion. - unsafe fn blit_image( - &mut self, - src: &B::Image, - src_layout: Layout, - dst: &B::Image, - dst_layout: Layout, - filter: Filter, - regions: T, - ) where - T: IntoIterator, - T::Item: Borrow; - - /// Bind the index buffer view, making it the "current" one that draw commands - /// will operate on. - unsafe fn bind_index_buffer(&mut self, view: buffer::IndexBufferView); - - /// Bind the vertex buffer set, making it the "current" one that draw commands - /// will operate on. - /// - /// Each buffer passed corresponds to the vertex input binding with the same index, - /// starting from an offset index `first_binding`. For example an iterator with - /// two items and `first_binding` of 1 would fill vertex buffer binding numbers - /// 1 and 2. - /// - /// This binding number refers only to binding points for vertex buffers and is - /// completely separate from the binding numbers of `Descriptor`s in `DescriptorSet`s. - /// It needs to match with the `VertexBufferDesc` and `AttributeDesc`s to which the - /// data from each bound vertex buffer should flow. - /// - /// The `buffers` iterator should yield the `Buffer` to bind, as well as an - /// offset, in bytes, into that buffer where the vertex data that should be bound - /// starts. - unsafe fn bind_vertex_buffers(&mut self, first_binding: pso::BufferIndex, buffers: I) - where - I: IntoIterator, - T: Borrow; - - /// Set the viewport parameters for the rasterizer. - /// - /// Each viewport passed corresponds to the viewport with the same index, - /// starting from an offset index `first_viewport`. - /// - /// # Errors - /// - /// This function does not return an error. Invalid usage of this function - /// will result in undefined behavior. - /// - /// - Command buffer must be in recording state. - /// - Number of viewports must be between 1 and `max_viewports - first_viewport`. - /// - The first viewport must be less than `max_viewports`. - /// - Only queues with graphics capability support this function. - /// - The bound pipeline must not have baked viewport state. - /// - All viewports used by the pipeline must be specified before the first - /// draw call. - unsafe fn set_viewports(&mut self, first_viewport: u32, viewports: T) - where - T: IntoIterator, - T::Item: Borrow; - - /// Set the scissor rectangles for the rasterizer. - /// - /// Each scissor corresponds to the viewport with the same index, starting - /// from an offset index `first_scissor`. - /// - /// # Errors - /// - /// This function does not return an error. Invalid usage of this function - /// will result in undefined behavior. - /// - /// - Command buffer must be in recording state. - /// - Number of scissors must be between 1 and `max_viewports - first_scissor`. - /// - The first scissor must be less than `max_viewports`. - /// - Only queues with graphics capability support this function. - /// - The bound pipeline must not have baked scissor state. - /// - All scissors used by the pipeline must be specified before the first draw - /// call. - unsafe fn set_scissors(&mut self, first_scissor: u32, rects: T) - where - T: IntoIterator, - T::Item: Borrow; - - /// Sets the stencil reference value for comparison operations and store operations. - /// Will be used on the LHS of stencil compare ops and as store value when the - /// store op is Reference. - unsafe fn set_stencil_reference(&mut self, faces: pso::Face, value: pso::StencilValue); - - /// Sets the stencil read mask. - unsafe fn set_stencil_read_mask(&mut self, faces: pso::Face, value: pso::StencilValue); - - /// Sets the stencil write mask. - unsafe fn set_stencil_write_mask(&mut self, faces: pso::Face, value: pso::StencilValue); - - /// Set the blend constant values dynamically. - unsafe fn set_blend_constants(&mut self, color: pso::ColorValue); - - /// Set the depth bounds test values dynamically. - unsafe fn set_depth_bounds(&mut self, bounds: Range); - - /// Set the line width dynamically. - unsafe fn set_line_width(&mut self, width: f32); - - /// Set the depth bias dynamically. - unsafe fn set_depth_bias(&mut self, depth_bias: pso::DepthBias); - - /// Begins recording commands for a render pass on the given framebuffer. - /// `render_area` is the section of the framebuffer to render, - /// `clear_values` is an iterator of `ClearValueRaw`'s to use to use for - /// `clear_*` commands, one for each attachment of the render pass - /// that has a clear operation. - /// `first_subpass` specifies, for the first subpass, whether the - /// rendering commands are provided inline or whether the render - /// pass is composed of subpasses. - unsafe fn begin_render_pass( - &mut self, - render_pass: &B::RenderPass, - framebuffer: &B::Framebuffer, - render_area: pso::Rect, - clear_values: T, - first_subpass: SubpassContents, - ) where - T: IntoIterator, - T::Item: Borrow; - - /// Steps to the next subpass in the current render pass. - unsafe fn next_subpass(&mut self, contents: SubpassContents); - - /// Finishes recording commands for the current a render pass. - unsafe fn end_render_pass(&mut self); - - /// Bind a graphics pipeline. - /// - /// # Errors - /// - /// This function does not return an error. Invalid usage of this function - /// will result in an error on `finish`. - /// - /// - Command buffer must be in recording state. - /// - Only queues with graphics capability support this function. - unsafe fn bind_graphics_pipeline(&mut self, pipeline: &B::GraphicsPipeline); - - /// Takes an iterator of graphics `DescriptorSet`'s, and binds them to the command buffer. - /// `first_set` is the index that the first descriptor is mapped to in the command buffer. - unsafe fn bind_graphics_descriptor_sets( - &mut self, - layout: &B::PipelineLayout, - first_set: usize, - sets: I, - offsets: J, - ) where - I: IntoIterator, - I::Item: Borrow, - J: IntoIterator, - J::Item: Borrow; - - /// Bind a compute pipeline. - /// - /// # Errors - /// - /// This function does not return an error. Invalid usage of this function - /// will result in an error on `finish`. - /// - /// - Command buffer must be in recording state. - /// - Only queues with compute capability support this function. - unsafe fn bind_compute_pipeline(&mut self, pipeline: &B::ComputePipeline); - - /// Takes an iterator of compute `DescriptorSet`'s, and binds them to the command buffer, - /// `first_set` is the index that the first descriptor is mapped to in the command buffer. - unsafe fn bind_compute_descriptor_sets( - &mut self, - layout: &B::PipelineLayout, - first_set: usize, - sets: I, - offsets: J, - ) where - I: IntoIterator, - I::Item: Borrow, - J: IntoIterator, - J::Item: Borrow; - - /// Execute a workgroup in the compute pipeline. `x`, `y` and `z` are the - /// number of local workgroups to dispatch along each "axis"; a total of `x`*`y`*`z` - /// local workgroups will be created. - /// - /// # Errors - /// - /// This function does not return an error. Invalid usage of this function - /// will result in an error on `finish`. - /// - /// - Command buffer must be in recording state. - /// - A compute pipeline must be bound using `bind_compute_pipeline`. - /// - Only queues with compute capability support this function. - /// - This function must be called outside of a render pass. - /// - `count` must be less than or equal to `Limits::max_compute_work_group_count` - /// - /// TODO: - unsafe fn dispatch(&mut self, count: WorkGroupCount); - - /// Works similarly to `dispatch()` but reads parameters from the given - /// buffer during execution. - unsafe fn dispatch_indirect(&mut self, buffer: &B::Buffer, offset: buffer::Offset); - - /// Adds a command to copy regions from the source to destination buffer. - unsafe fn copy_buffer(&mut self, src: &B::Buffer, dst: &B::Buffer, regions: T) - where - T: IntoIterator, - T::Item: Borrow; - - /// Copies regions from the source to the destination images, which - /// have the given layouts. No format conversion is done; the source and destination - /// `Layout`'s **must** have the same sized image formats (such as `Rgba8Unorm` and - /// `R32`, both of which are 32 bits). - unsafe fn copy_image( - &mut self, - src: &B::Image, - src_layout: Layout, - dst: &B::Image, - dst_layout: Layout, - regions: T, - ) where - T: IntoIterator, - T::Item: Borrow; - - /// Copies regions from the source buffer to the destination image. - unsafe fn copy_buffer_to_image( - &mut self, - src: &B::Buffer, - dst: &B::Image, - dst_layout: Layout, - regions: T, - ) where - T: IntoIterator, - T::Item: Borrow; - - /// Copies regions from the source image to the destination buffer. - unsafe fn copy_image_to_buffer( - &mut self, - src: &B::Image, - src_layout: Layout, - dst: &B::Buffer, - regions: T, - ) where - T: IntoIterator, - T::Item: Borrow; - - // TODO: This explanation needs improvement. - /// Performs a non-indexed drawing operation, fetching vertex attributes - /// from the currently bound vertex buffers. It performs instanced - /// drawing, drawing `instances.len()` - /// times with an `instanceIndex` starting with the start of the range. - unsafe fn draw(&mut self, vertices: Range, instances: Range); - - /// Performs indexed drawing, drawing the range of indices - /// given by the current index buffer and any bound vertex buffers. - /// `base_vertex` specifies the vertex offset corresponding to index 0. - /// That is, the offset into the vertex buffer is `(current_index + base_vertex)` - /// - /// It also performs instanced drawing, identical to `draw()`. - unsafe fn draw_indexed( - &mut self, - indices: Range, - base_vertex: VertexOffset, - instances: Range, - ); - - /// Functions identically to `draw()`, except the parameters are read - /// from the given buffer, starting at `offset` and increasing `stride` - /// bytes with each successive draw. Performs `draw_count` draws total. - /// `draw_count` may be zero. - /// - /// Each draw command in the buffer is a series of 4 `u32` values specifying, - /// in order, the number of vertices to draw, the number of instances to draw, - /// the index of the first vertex to draw, and the instance ID of the first - /// instance to draw. - unsafe fn draw_indirect( - &mut self, - buffer: &B::Buffer, - offset: buffer::Offset, - draw_count: DrawCount, - stride: u32, - ); - - /// Like `draw_indirect()`, this does indexed drawing a la `draw_indexed()` but - /// reads the draw parameters out of the given buffer. - /// - /// Each draw command in the buffer is a series of 5 values specifying, - /// in order, the number of indices, the number of instances, the first index, - /// the vertex offset, and the first instance. All are `u32`'s except - /// the vertex offset, which is an `i32`. - unsafe fn draw_indexed_indirect( - &mut self, - buffer: &B::Buffer, - offset: buffer::Offset, - draw_count: DrawCount, - stride: u32, - ); - - /// Signals an event once all specified stages of the shader pipeline have completed. - unsafe fn set_event(&mut self, event: &B::Event, stages: pso::PipelineStage); - - /// Resets an event once all specified stages of the shader pipeline have completed. - unsafe fn reset_event(&mut self, event: &B::Event, stages: pso::PipelineStage); - - /// Waits at some shader stage(s) until all events have been signalled. - /// - /// - `src_stages` specifies the shader pipeline stages in which the events were signalled. - /// - `dst_stages` specifies the shader pipeline stages at which execution should wait. - /// - `barriers` specifies a series of memory barriers to be executed before pipeline execution - /// resumes. - unsafe fn wait_events<'a, I, J>( - &mut self, - events: I, - stages: Range, - barriers: J, - ) where - I: IntoIterator, - I::Item: Borrow, - J: IntoIterator, - J::Item: Borrow>; - - /// Begins a query operation. Queries count operations or record timestamps - /// resulting from commands that occur between the beginning and end of the query, - /// and save the results to the query pool. - unsafe fn begin_query(&mut self, query: query::Query, flags: query::ControlFlags); - - /// End a query. - unsafe fn end_query(&mut self, query: query::Query); - - /// Reset/clear the values in the given range of the query pool. - unsafe fn reset_query_pool(&mut self, pool: &B::QueryPool, queries: Range); - - /// Copy query results into a buffer. - unsafe fn copy_query_pool_results( - &mut self, - pool: &B::QueryPool, - queries: Range, - buffer: &B::Buffer, - offset: buffer::Offset, - stride: buffer::Offset, - flags: query::ResultFlags, - ); - - /// Requests a timestamp to be written. - unsafe fn write_timestamp(&mut self, stage: pso::PipelineStage, query: query::Query); - - /// Modify constant data in a graphics pipeline. - /// Push constants are intended to modify data in a pipeline more - /// quickly than a updating the values inside a descriptor set. - unsafe fn push_graphics_constants( - &mut self, - layout: &B::PipelineLayout, - stages: pso::ShaderStageFlags, - offset: u32, - constants: &[u32], - ); - - /// Modify constant data in a compute pipeline. - /// Push constants are intended to modify data in a pipeline more - /// quickly than a updating the values inside a descriptor set. - unsafe fn push_compute_constants( - &mut self, - layout: &B::PipelineLayout, - offset: u32, - constants: &[u32], - ); - - /// Execute the given secondary command buffers. - unsafe fn execute_commands<'a, T, I>(&mut self, cmd_buffers: I) - where - T: 'a + Borrow, - I: IntoIterator; -} - -/// A trait for types that can be converted into raw command buffer. -pub trait IntoRawCommandBuffer { - /// Converts into raw command buffer. - fn into_raw(self) -> B::CommandBuffer; -} diff --git a/src/hal/src/command/render_pass.rs b/src/hal/src/command/render_pass.rs deleted file mode 100644 index a564ad856bd..00000000000 --- a/src/hal/src/command/render_pass.rs +++ /dev/null @@ -1,487 +0,0 @@ -use std::borrow::{Borrow, BorrowMut}; -use std::marker::PhantomData; -use std::ops::{Deref, DerefMut, Range}; - -use super::{ - AttachmentClear, - ClearValue, - ClearValueRaw, - CommandBuffer, - CommandBufferFlags, - CommandBufferInheritanceInfo, - DescriptorSetOffset, - IntoRawCommandBuffer, - MultiShot, - OneShot, - Primary, - RawCommandBuffer, - Secondary, - Shot, - Submittable, -}; -use crate::queue::{Capability, Graphics, Supports}; -use crate::{buffer, pass, pso, query}; -use crate::{Backend, DrawCount, IndexCount, InstanceCount, VertexCount, VertexOffset}; - -/// Specifies how commands for the following renderpasses will be recorded. -#[derive(Debug)] -pub enum SubpassContents { - /// Contents of the subpass will be inline in the command buffer, - /// NOT in secondary command buffers. - Inline, - /// Contents of the subpass will be in secondary command buffers, and - /// the primary command buffer will only contain `execute_command()` calls - /// until the subpass or render pass is complete. - SecondaryBuffers, -} - -/// This struct contains all methods for all commands submittable during a subpass. -/// It is used to implement the identical portions of RenderPassInlineEncoder and SubpassCommandBuffer. -/// -/// Where methods are undocumented, they are identical to the methods on the `RawCommandBuffer` -/// trait with the same names. -#[derive(Debug)] -pub struct RenderSubpassCommon { - cmb: C, - _marker: PhantomData, -} - -impl> RenderSubpassCommon { - unsafe fn new(cmb: C) -> Self { - RenderSubpassCommon { - cmb, - _marker: PhantomData, - } - } - - /// - pub unsafe fn clear_attachments(&mut self, clears: T, rects: U) - where - T: IntoIterator, - T::Item: Borrow, - U: IntoIterator, - U::Item: Borrow, - { - self.cmb.borrow_mut().clear_attachments(clears, rects) - } - - /// - pub unsafe fn draw(&mut self, vertices: Range, instances: Range) { - self.cmb.borrow_mut().draw(vertices, instances) - } - - /// - pub unsafe fn draw_indexed( - &mut self, - indices: Range, - base_vertex: VertexOffset, - instances: Range, - ) { - self.cmb - .borrow_mut() - .draw_indexed(indices, base_vertex, instances) - } - - /// - pub unsafe fn draw_indirect( - &mut self, - buffer: &B::Buffer, - offset: buffer::Offset, - draw_count: DrawCount, - stride: u32, - ) { - self.cmb - .borrow_mut() - .draw_indirect(buffer, offset, draw_count, stride) - } - /// - pub unsafe fn draw_indexed_indirect( - &mut self, - buffer: &B::Buffer, - offset: buffer::Offset, - draw_count: DrawCount, - stride: u32, - ) { - self.cmb - .borrow_mut() - .draw_indexed_indirect(buffer, offset, draw_count, stride) - } - - /// - pub unsafe fn bind_index_buffer(&mut self, ibv: buffer::IndexBufferView) { - self.cmb.borrow_mut().bind_index_buffer(ibv) - } - - /// - pub unsafe fn bind_vertex_buffers(&mut self, first_binding: pso::BufferIndex, buffers: I) - where - I: IntoIterator, - T: Borrow, - { - self.cmb - .borrow_mut() - .bind_vertex_buffers(first_binding, buffers); - } - - /// - pub unsafe fn bind_graphics_pipeline(&mut self, pipeline: &B::GraphicsPipeline) { - self.cmb.borrow_mut().bind_graphics_pipeline(pipeline) - } - - /// - pub unsafe fn bind_graphics_descriptor_sets( - &mut self, - layout: &B::PipelineLayout, - first_set: usize, - sets: I, - offsets: J, - ) where - I: IntoIterator, - I::Item: Borrow, - J: IntoIterator, - J::Item: Borrow, - { - self.cmb - .borrow_mut() - .bind_graphics_descriptor_sets(layout, first_set, sets, offsets) - } - - /// - pub unsafe fn set_viewports(&mut self, first_viewport: u32, viewports: T) - where - T: IntoIterator, - T::Item: Borrow, - { - self.cmb - .borrow_mut() - .set_viewports(first_viewport, viewports) - } - - /// - pub unsafe fn set_scissors(&mut self, first_scissor: u32, scissors: T) - where - T: IntoIterator, - T::Item: Borrow, - { - self.cmb.borrow_mut().set_scissors(first_scissor, scissors) - } - - /// - pub unsafe fn set_stencil_reference(&mut self, faces: pso::Face, value: pso::StencilValue) { - self.cmb.borrow_mut().set_stencil_reference(faces, value); - } - - /// - pub unsafe fn set_stencil_read_mask(&mut self, faces: pso::Face, value: pso::StencilValue) { - self.cmb.borrow_mut().set_stencil_read_mask(faces, value); - } - - /// - pub unsafe fn set_stencil_write_mask(&mut self, faces: pso::Face, value: pso::StencilValue) { - self.cmb.borrow_mut().set_stencil_write_mask(faces, value); - } - - /// - pub unsafe fn set_blend_constants(&mut self, cv: pso::ColorValue) { - self.cmb.borrow_mut().set_blend_constants(cv) - } - - /// - pub unsafe fn set_depth_bounds(&mut self, bounds: Range) { - self.cmb.borrow_mut().set_depth_bounds(bounds) - } - - /// - pub unsafe fn push_graphics_constants( - &mut self, - layout: &B::PipelineLayout, - stages: pso::ShaderStageFlags, - offset: u32, - constants: &[u32], - ) { - self.cmb - .borrow_mut() - .push_graphics_constants(layout, stages, offset, constants); - } - - /// - pub unsafe fn set_line_width(&mut self, width: f32) { - self.cmb.borrow_mut().set_line_width(width); - } - - /// - pub unsafe fn set_depth_bias(&mut self, depth_bias: pso::DepthBias) { - self.cmb.borrow_mut().set_depth_bias(depth_bias); - } - - // TODO: pipeline barrier (postponed) - - /// - pub unsafe fn begin_query(&mut self, query: query::Query, flags: query::ControlFlags) { - self.cmb.borrow_mut().begin_query(query, flags) - } - - /// - pub unsafe fn end_query(&mut self, query: query::Query) { - self.cmb.borrow_mut().end_query(query) - } - - /// - pub unsafe fn write_timestamp(&mut self, stage: pso::PipelineStage, query: query::Query) { - self.cmb.borrow_mut().write_timestamp(stage, query) - } -} - -/// An object that records commands into a command buffer inline, that is, -/// without secondary command buffers. -#[derive(Debug)] -pub struct RenderPassInlineEncoder<'a, B: Backend>( - RenderSubpassCommon, -) -where - B::CommandBuffer: 'a; - -impl<'a, B: Backend> RenderPassInlineEncoder<'a, B> { - /// Creates a new `RenderPassInlineEncoder`, starting a new render - /// pass in the given `CommandBuffer`. - pub unsafe fn new( - cmd_buffer: &'a mut CommandBuffer, - render_pass: &B::RenderPass, - frame_buffer: &B::Framebuffer, - render_area: pso::Rect, - clear_values: T, - ) -> Self - where - C: Supports, - T: IntoIterator, - T::Item: Borrow, - { - let clear_values = clear_values - .into_iter() - .map(|cv| ClearValueRaw::from(*cv.borrow())); - - cmd_buffer.raw.begin_render_pass( - render_pass, - frame_buffer, - render_area, - clear_values, - SubpassContents::Inline, - ); - - RenderPassInlineEncoder(RenderSubpassCommon::new(&mut cmd_buffer.raw)) - } - - /// Start the next subpass. - pub fn next_subpass_inline(self) -> Self { - unsafe { - self.0.cmb.next_subpass(SubpassContents::Inline); - } - self - } - - /// Begins recording a new subpass with secondary buffers. - pub fn next_subpass_secondary(mut self) -> RenderPassSecondaryEncoder<'a, B> { - unsafe { - self.0.cmb.next_subpass(SubpassContents::SecondaryBuffers); - let cmb = std::ptr::read(&mut self.0.cmb); - std::mem::forget(self); // Prevent `end_render_pass` - RenderPassSecondaryEncoder(cmb) - } - } -} - -impl<'a, B: Backend> Deref for RenderPassInlineEncoder<'a, B> { - type Target = RenderSubpassCommon; - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl<'a, B: Backend> DerefMut for RenderPassInlineEncoder<'a, B> { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.0 - } -} - -impl<'a, B: Backend> Drop for RenderPassInlineEncoder<'a, B> { - fn drop(&mut self) { - unsafe { - self.0.cmb.end_render_pass(); - } - } -} - -/// An object that records commands into a command buffer where each command must -/// be a call to execute a secondary command buffer. -#[derive(Debug)] -pub struct RenderPassSecondaryEncoder<'a, B: Backend>(&'a mut B::CommandBuffer) -where - B::CommandBuffer: 'a; - -impl<'a, B: Backend> RenderPassSecondaryEncoder<'a, B> { - /// Wraps the given `CommandBuffer` in a `RenderPassSecondaryEncoder`, - /// starting a new render pass where the actual commands are contained in - /// secondary command buffers. - pub unsafe fn new( - cmd_buffer: &'a mut CommandBuffer, - render_pass: &B::RenderPass, - frame_buffer: &B::Framebuffer, - render_area: pso::Rect, - clear_values: T, - ) -> Self - where - C: Supports, - T: IntoIterator, - T::Item: Borrow, - { - let clear_values = clear_values - .into_iter() - .map(|cv| ClearValueRaw::from(*cv.borrow())); - - cmd_buffer.raw.begin_render_pass( - render_pass, - frame_buffer, - render_area, - clear_values, - SubpassContents::SecondaryBuffers, - ); - - RenderPassSecondaryEncoder(&mut cmd_buffer.raw) - } - - /// Executes the given commands as a secondary command buffer. - pub unsafe fn execute_commands<'b, T, I>(&mut self, cmd_buffers: I) - where - T: 'b + Submittable, - I: IntoIterator, - { - self.0.execute_commands(cmd_buffers) - } - - /// Starts a new subpass with inline commands. - pub fn next_subpass_inline(mut self) -> RenderPassInlineEncoder<'a, B> { - unsafe { - self.0.next_subpass(SubpassContents::Inline); - let cmb = std::ptr::read(&mut self.0); - std::mem::forget(self); // Prevent `end_render_pass` - RenderPassInlineEncoder(RenderSubpassCommon::new(cmb)) - } - } - - /// Starts a new subpass with secondary command buffers. - pub fn next_subpass_secondary(self) -> Self { - unsafe { - self.0.next_subpass(SubpassContents::SecondaryBuffers); - } - self - } -} - -impl<'a, B: Backend> Drop for RenderPassSecondaryEncoder<'a, B> { - fn drop(&mut self) { - unsafe { - self.0.end_render_pass(); - } - } -} - -/// A secondary command buffer recorded entirely within a subpass. -#[derive(Debug)] -pub struct SubpassCommandBuffer::CommandBuffer>( - RenderSubpassCommon, - PhantomData, -); -impl SubpassCommandBuffer { - /// Wraps the given `CommandBuffer` in a `SubpassCommandBuffer`, starting - /// to record a new subpass. - pub unsafe fn new(raw: B::CommandBuffer) -> Self { - SubpassCommandBuffer(RenderSubpassCommon::new(raw), PhantomData) - } - - /// Finish recording commands to the command buffer. - /// - /// The command pool must be reset to able to re-record commands. - pub unsafe fn finish(&mut self) { - self.0.cmb.finish(); - } -} - -impl SubpassCommandBuffer { - /// Begin recording a one-shot sub-pass command buffer. - pub unsafe fn begin<'a>( - &mut self, - subpass: pass::Subpass<'a, B>, - framebuffer: Option<&'a B::Framebuffer>, - ) { - let flags = CommandBufferFlags::RENDER_PASS_CONTINUE | CommandBufferFlags::ONE_TIME_SUBMIT; - let inheritance_info = CommandBufferInheritanceInfo { - subpass: Some(subpass), - framebuffer, - ..CommandBufferInheritanceInfo::default() - }; - self.0.cmb.begin(flags, inheritance_info); - } -} - -impl SubpassCommandBuffer { - /// Begin recording a one-shot sub-pass command buffer. - pub unsafe fn begin<'a>( - &mut self, - allow_pending_resubmit: bool, - subpass: pass::Subpass<'a, B>, - framebuffer: Option<&'a B::Framebuffer>, - ) { - let mut flags = CommandBufferFlags::RENDER_PASS_CONTINUE; - if allow_pending_resubmit { - flags |= CommandBufferFlags::SIMULTANEOUS_USE; - } - let inheritance_info = CommandBufferInheritanceInfo { - subpass: Some(subpass), - framebuffer, - ..CommandBufferInheritanceInfo::default() - }; - self.0.cmb.begin(flags, inheritance_info); - } -} - -impl Deref for SubpassCommandBuffer { - type Target = RenderSubpassCommon; - fn deref(&self) -> &RenderSubpassCommon { - &self.0 - } -} - -impl DerefMut for SubpassCommandBuffer { - fn deref_mut(&mut self) -> &mut RenderSubpassCommon { - &mut self.0 - } -} - -impl Borrow for SubpassCommandBuffer -where - B: Backend, - S: Shot, - R: RawCommandBuffer, -{ - fn borrow(&self) -> &R { - &self.0.cmb - } -} - -impl Submittable for SubpassCommandBuffer -where - B: Backend, - C: Capability + Supports, - S: Shot, -{ -} - -impl IntoRawCommandBuffer for SubpassCommandBuffer -where - B: Backend, - S: Shot, -{ - fn into_raw(self) -> B::CommandBuffer { - self.0.cmb - } -} diff --git a/src/hal/src/command/structs.rs b/src/hal/src/command/structs.rs new file mode 100644 index 00000000000..d3c412f8c44 --- /dev/null +++ b/src/hal/src/command/structs.rs @@ -0,0 +1,86 @@ +use crate::{buffer, image}; + +use std::ops::Range; + +/// Specifies a source region and a destination +/// region in a buffer for copying. All values +/// are in units of bytes. +#[derive(Clone, Copy, Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +pub struct BufferCopy { + /// Buffer region source offset. + pub src: buffer::Offset, + /// Buffer region destination offset. + pub dst: buffer::Offset, + /// Region size. + pub size: buffer::Offset, +} + +/// Bundles together all the parameters needed to copy data from one `Image` +/// to another. +#[derive(Clone, Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +pub struct ImageCopy { + /// The image subresource to copy from. + pub src_subresource: image::SubresourceLayers, + /// The source offset. + pub src_offset: image::Offset, + /// The image subresource to copy to. + pub dst_subresource: image::SubresourceLayers, + /// The destination offset. + pub dst_offset: image::Offset, + /// The extent of the region to copy. + pub extent: image::Extent, +} + +/// Bundles together all the parameters needed to copy a buffer +/// to an image or vice-versa. +#[derive(Clone, Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +pub struct BufferImageCopy { + /// Buffer offset in bytes. + pub buffer_offset: buffer::Offset, + /// Width of a buffer 'row' in texels. + pub buffer_width: u32, + /// Height of a buffer 'image slice' in texels. + pub buffer_height: u32, + /// The image subresource. + pub image_layers: image::SubresourceLayers, + /// The offset of the portion of the image to copy. + pub image_offset: image::Offset, + /// Size of the portion of the image to copy. + pub image_extent: image::Extent, +} + +/// Parameters for an image resolve operation, +/// where a multi-sampled image is copied into a single-sampled +/// image. +#[derive(Clone, Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +pub struct ImageResolve { + /// Source image and layers. + pub src_subresource: image::SubresourceLayers, + /// Source image offset. + pub src_offset: image::Offset, + /// Destination image and layers. + pub dst_subresource: image::SubresourceLayers, + /// Destination image offset. + pub dst_offset: image::Offset, + /// Image extent. + pub extent: image::Extent, +} + +/// Parameters for an image blit operation, where a portion of one image +/// is copied into another, possibly with scaling and filtering. +#[derive(Clone, Debug)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +pub struct ImageBlit { + /// Source image and layers. + pub src_subresource: image::SubresourceLayers, + /// Source image bounds. + pub src_bounds: Range, + /// Destination image and layers. + pub dst_subresource: image::SubresourceLayers, + /// Destination image bounds. + pub dst_bounds: Range, +} diff --git a/src/hal/src/command/transfer.rs b/src/hal/src/command/transfer.rs deleted file mode 100644 index 239bbe0016a..00000000000 --- a/src/hal/src/command/transfer.rs +++ /dev/null @@ -1,146 +0,0 @@ -//! `CommandBuffer` methods for transfer operations. -use std::borrow::Borrow; -use std::ops::Range; - -use super::{CommandBuffer, Level, RawCommandBuffer, Shot}; -use crate::memory::{Barrier, Dependencies}; -use crate::pso::PipelineStage; -use crate::queue::capability::{Supports, Transfer}; -use crate::range::RangeArg; -use crate::Backend; -use crate::{buffer, image}; -/// Specifies a source region and a destination -/// region in a buffer for copying. All values -/// are in units of bytes. -#[derive(Clone, Copy, Debug)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -pub struct BufferCopy { - /// Buffer region source offset. - pub src: buffer::Offset, - /// Buffer region destination offset. - pub dst: buffer::Offset, - /// Region size. - pub size: buffer::Offset, -} - -/// Bundles together all the parameters needed to copy data from one `Image` -/// to another. -#[derive(Clone, Debug)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -pub struct ImageCopy { - /// The image subresource to copy from. - pub src_subresource: image::SubresourceLayers, - /// The source offset. - pub src_offset: image::Offset, - /// The image subresource to copy to. - pub dst_subresource: image::SubresourceLayers, - /// The destination offset. - pub dst_offset: image::Offset, - /// The extent of the region to copy. - pub extent: image::Extent, -} - -/// Bundles together all the parameters needed to copy a buffer -/// to an image or vice-versa. -#[derive(Clone, Debug)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -pub struct BufferImageCopy { - /// Buffer offset in bytes. - pub buffer_offset: buffer::Offset, - /// Width of a buffer 'row' in texels. - pub buffer_width: u32, - /// Height of a buffer 'image slice' in texels. - pub buffer_height: u32, - /// The image subresource. - pub image_layers: image::SubresourceLayers, - /// The offset of the portion of the image to copy. - pub image_offset: image::Offset, - /// Size of the portion of the image to copy. - pub image_extent: image::Extent, -} - -impl, S: Shot, L: Level> CommandBuffer { - /// Identical to the `RawCommandBuffer` method of the same name. - pub unsafe fn pipeline_barrier<'i, T>( - &mut self, - stages: Range, - dependencies: Dependencies, - barriers: T, - ) where - T: IntoIterator, - T::Item: Borrow>, - { - self.raw.pipeline_barrier(stages, dependencies, barriers) - } - - /// Identical to the `RawCommandBuffer` method of the same name. - pub unsafe fn fill_buffer(&mut self, buffer: &B::Buffer, range: R, data: u32) - where - R: RangeArg, - { - self.raw.fill_buffer(buffer, range, data) - } - - /// Identical to the `RawCommandBuffer` method of the same name. - pub unsafe fn copy_buffer(&mut self, src: &B::Buffer, dst: &B::Buffer, regions: T) - where - T: IntoIterator, - T::Item: Borrow, - { - self.raw.copy_buffer(src, dst, regions) - } - - /// Identical to the `RawCommandBuffer` method of the same name. - pub unsafe fn update_buffer( - &mut self, - buffer: &B::Buffer, - offset: buffer::Offset, - data: &[u8], - ) { - self.raw.update_buffer(buffer, offset, data) - } - - /// Identical to the `RawCommandBuffer` method of the same name. - pub unsafe fn copy_image( - &mut self, - src: &B::Image, - src_layout: image::Layout, - dst: &B::Image, - dst_layout: image::Layout, - regions: T, - ) where - T: IntoIterator, - T::Item: Borrow, - { - self.raw - .copy_image(src, src_layout, dst, dst_layout, regions) - } - - /// Identical to the `RawCommandBuffer` method of the same name. - pub unsafe fn copy_buffer_to_image( - &mut self, - src: &B::Buffer, - dst: &B::Image, - dst_layout: image::Layout, - regions: T, - ) where - T: IntoIterator, - T::Item: Borrow, - { - self.raw.copy_buffer_to_image(src, dst, dst_layout, regions) - } - - /// Identical to the `RawCommandBuffer` method of the same name. - pub unsafe fn copy_image_to_buffer( - &mut self, - src: &B::Image, - src_layout: image::Layout, - dst: &B::Buffer, - regions: T, - ) where - T: IntoIterator, - T::Item: Borrow, - { - self.raw.copy_image_to_buffer(src, src_layout, dst, regions) - } -} diff --git a/src/hal/src/device.rs b/src/hal/src/device.rs index 88076fc70f1..c01945ec95d 100644 --- a/src/hal/src/device.rs +++ b/src/hal/src/device.rs @@ -21,9 +21,9 @@ use crate::{Backend, MemoryTypeId}; use crate::error::HostExecutionError; use crate::memory::Requirements; -use crate::pool::{CommandPool, CommandPoolCreateFlags}; +use crate::pool::CommandPoolCreateFlags; use crate::pso::DescriptorPoolCreateFlags; -use crate::queue::{QueueFamilyId, QueueGroup}; +use crate::queue::QueueFamilyId; use crate::range::RangeArg; use crate::window::{self, SwapchainConfig}; @@ -199,16 +199,6 @@ pub trait Device: fmt::Debug + Any + Send + Sync { create_flags: CommandPoolCreateFlags, ) -> Result; - /// Create a strongly typed command pool wrapper. - unsafe fn create_command_pool_typed( - &self, - group: &QueueGroup, - flags: CommandPoolCreateFlags, - ) -> Result, OutOfMemory> { - let raw = self.create_command_pool(group.family(), flags)?; - Ok(CommandPool::new(raw)) - } - /// Destroy a command pool. unsafe fn destroy_command_pool(&self, pool: B::CommandPool); @@ -788,9 +778,7 @@ pub trait Device: fmt::Debug + Any + Send + Sync { /// # extern crate gfx_backend_empty as empty; /// # extern crate gfx_hal; /// # fn main() { - /// use gfx_hal::{Device, SwapchainConfig}; - /// use gfx_hal::format::Format; - /// # use gfx_hal::{CommandQueue, Graphics}; + /// use gfx_hal::{prelude::*, format::Format, window::SwapchainConfig}; /// /// # let mut surface: empty::Surface = return; /// # let device: empty::Device = return; diff --git a/src/hal/src/image.rs b/src/hal/src/image.rs index 5b7d99aecf8..52c947d3e2c 100644 --- a/src/hal/src/image.rs +++ b/src/hal/src/image.rs @@ -8,10 +8,7 @@ use crate::{ format, pso::{Comparison, Rect}, }; -use std::{ - i16, - ops::Range, -}; +use std::{i16, ops::Range}; /// Dimension size. pub type Size = u32; diff --git a/src/hal/src/lib.rs b/src/hal/src/lib.rs index 6e89019f2b8..5b3d63f585a 100644 --- a/src/hal/src/lib.rs +++ b/src/hal/src/lib.rs @@ -8,9 +8,6 @@ extern crate bitflags; #[macro_use] extern crate failure; -#[cfg(feature = "mint")] -extern crate mint; - #[cfg(feature = "serde")] #[macro_use] extern crate serde; @@ -20,44 +17,6 @@ use std::error::Error; use std::fmt; use std::hash::Hash; -//TODO: reconsider what is publicly exported - -pub use self::adapter::{ - Adapter, - AdapterInfo, - MemoryProperties, - MemoryType, - MemoryTypeId, - PhysicalDevice, - QueuePriority, -}; -pub use self::device::Device; -pub use self::pool::CommandPool; -pub use self::pso::{read_spirv, DescriptorPool}; -pub use self::queue::{ - Capability, - CommandQueue, - Compute, - General, - Graphics, - QueueFamily, - QueueGroup, - QueueType, - Submission, - Supports, - Transfer, -}; -pub use self::window::{ - AcquireError, - CompositeAlpha, - PresentMode, - Surface, - SurfaceCapabilities, - SwapImageIndex, - Swapchain, - SwapchainConfig, -}; - pub mod adapter; pub mod buffer; pub mod command; @@ -78,6 +37,20 @@ pub mod window; #[doc(hidden)] pub mod backend; +/// Prelude module re-exports all the traits necessary to use gfx-hal. +pub mod prelude { + pub use crate::{ + adapter::PhysicalDevice as _, + command::CommandBuffer as _, + device::Device as _, + pool::CommandPool as _, + pso::DescriptorPool as _, + queue::{CommandQueue as _, QueueFamily as _}, + window::{Surface as _, Swapchain as _}, + Instance as _, + }; +} + /// Draw vertex count. pub type VertexCount = u32; /// Draw vertex base offset. @@ -482,7 +455,18 @@ pub trait Instance: Any + Send + Sync { /// Associated backend type of this instance. type Backend: Backend; /// Return all available adapters. - fn enumerate_adapters(&self) -> Vec>; + fn enumerate_adapters(&self) -> Vec>; +} + +/// A strongly-typed index to a particular `MemoryType`. +#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +pub struct MemoryTypeId(pub usize); + +impl From for MemoryTypeId { + fn from(id: usize) -> Self { + MemoryTypeId(id) + } } /// The `Backend` trait wraps together all the types needed @@ -491,22 +475,22 @@ pub trait Instance: Any + Send + Sync { #[allow(missing_docs)] pub trait Backend: 'static + Sized + Eq + Clone + Hash + fmt::Debug + Any + Send + Sync { //type Instance: Instance; - type PhysicalDevice: PhysicalDevice; - type Device: Device; + type PhysicalDevice: adapter::PhysicalDevice; + type Device: device::Device; - type Surface: Surface; - type Swapchain: Swapchain; + type Surface: window::Surface; + type Swapchain: window::Swapchain; - type QueueFamily: QueueFamily; - type CommandQueue: queue::RawCommandQueue; - type CommandBuffer: command::RawCommandBuffer; + type QueueFamily: queue::QueueFamily; + type CommandQueue: queue::CommandQueue; + type CommandBuffer: command::CommandBuffer; type ShaderModule: fmt::Debug + Any + Send + Sync; type RenderPass: fmt::Debug + Any + Send + Sync; type Framebuffer: fmt::Debug + Any + Send + Sync; type Memory: fmt::Debug + Any + Send + Sync; - type CommandPool: pool::RawCommandPool; + type CommandPool: pool::CommandPool; type Buffer: fmt::Debug + Any + Send + Sync; type BufferView: fmt::Debug + Any + Send + Sync; @@ -547,15 +531,3 @@ impl Error for SubmissionError { /// Submission result for DX11 backend. Currently mostly unused. pub type SubmissionResult = Result; - -/// Represents a combination of a logical device and the -/// hardware queues it provides. -/// -/// This structure is typically created using an `Adapter`. -#[derive(Debug)] -pub struct Gpu { - /// Logical device for a given backend. - pub device: B::Device, - /// The command queues that the device provides. - pub queues: queue::Queues, -} diff --git a/src/hal/src/pool.rs b/src/hal/src/pool.rs index 274a6b33633..dc81a910dcb 100644 --- a/src/hal/src/pool.rs +++ b/src/hal/src/pool.rs @@ -1,19 +1,10 @@ //! Command pools -use crate::command::{ - CommandBuffer, - IntoRawCommandBuffer, - RawLevel, - SecondaryCommandBuffer, - Shot, - SubpassCommandBuffer, -}; -use crate::queue::capability::{Graphics, Supports}; +use crate::command::Level; use crate::Backend; use std::any::Any; use std::fmt; -use std::marker::PhantomData; bitflags!( /// Command pool creation flags. @@ -28,19 +19,19 @@ bitflags!( ); /// The allocated command buffers are associated with the creating command queue. -pub trait RawCommandPool: fmt::Debug + Any + Send + Sync { +pub trait CommandPool: fmt::Debug + Any + Send + Sync { /// Reset the command pool and the corresponding command buffers. /// /// # Synchronization: You may _not_ free the pool if a command buffer is still in use (pool memory still in use) unsafe fn reset(&mut self, release_resources: bool); /// Allocate a single command buffers from the pool. - fn allocate_one(&mut self, level: RawLevel) -> B::CommandBuffer { + fn allocate_one(&mut self, level: Level) -> B::CommandBuffer { self.allocate_vec(1, level).pop().unwrap() } /// Allocate new command buffers from the pool. - fn allocate_vec(&mut self, num: usize, level: RawLevel) -> Vec { + fn allocate_vec(&mut self, num: usize, level: Level) -> Vec { (0 .. num).map(|_| self.allocate_one(level)).collect() } @@ -49,73 +40,3 @@ pub trait RawCommandPool: fmt::Debug + Any + Send + Sync { where I: IntoIterator; } - -/// Strong-typed command pool. -/// -/// This a safer wrapper around `RawCommandPool` which ensures that only **one** -/// command buffer is recorded at the same time from the current queue. -/// Command buffers are stored internally and can only be obtained via a strong-typed -/// `CommandBuffer` wrapper for encoding. -#[derive(Debug)] -pub struct CommandPool { - raw: B::CommandPool, - _capability: PhantomData, -} - -impl CommandPool { - /// Create typed command pool from raw. - /// - /// # Safety - /// - /// `::supported_by(queue_type)` must return true - /// for `queue_type` being the type of queues from family this `raw` pool is associated with. - /// - pub unsafe fn new(raw: B::CommandPool) -> Self { - CommandPool { - raw, - _capability: PhantomData, - } - } - - /// Reset the command pool and the corresponding command buffers. - /// - /// # Synchronization: You may _not_ free the pool if a command buffer is still in use (pool memory still in use) - pub unsafe fn reset(&mut self, release_resources: bool) { - self.raw.reset(release_resources); - } - - /// Allocates a new primary command buffer from the pool. - pub fn acquire_command_buffer(&mut self) -> CommandBuffer { - let buffer = self.raw.allocate_one(RawLevel::Primary); - unsafe { CommandBuffer::new(buffer) } - } - - /// Allocates a new secondary command buffer from the pool. - pub fn acquire_secondary_command_buffer(&mut self) -> SecondaryCommandBuffer { - let buffer = self.raw.allocate_one(RawLevel::Secondary); - unsafe { SecondaryCommandBuffer::new(buffer) } - } - - /// Free the given iterator of command buffers from the pool. - pub unsafe fn free(&mut self, cmd_buffers: I) - where - I: IntoIterator, - I::Item: IntoRawCommandBuffer, - { - self.raw - .free(cmd_buffers.into_iter().map(|cmb| cmb.into_raw())) - } - - /// Downgrade a typed command pool to untyped one. - pub fn into_raw(self) -> B::CommandPool { - self.raw - } -} - -impl> CommandPool { - /// Allocates a new subpass command buffer from the pool. - pub fn acquire_subpass_command_buffer(&mut self) -> SubpassCommandBuffer { - let buffer = self.raw.allocate_one(RawLevel::Secondary); - unsafe { SubpassCommandBuffer::new(buffer) } - } -} diff --git a/src/hal/src/pso/mod.rs b/src/hal/src/pso/mod.rs index 4a7eb47d7b3..e6a6424e215 100644 --- a/src/hal/src/pso/mod.rs +++ b/src/hal/src/pso/mod.rs @@ -368,13 +368,13 @@ macro_rules! spec_const_list { /// # Examples /// ```no_run /// let mut file = std::fs::File::open("/path/to/shader.spv").unwrap(); -/// let words = gfx_hal::read_spirv(&mut file).unwrap(); +/// let words = gfx_hal::pso::read_spirv(&mut file).unwrap(); /// ``` /// ``` /// const SPIRV: &[u8] = &[ /// 0x03, 0x02, 0x23, 0x07, // ... /// ]; -/// let words = gfx_hal::read_spirv(std::io::Cursor::new(&SPIRV[..])).unwrap(); +/// let words = gfx_hal::pso::read_spirv(std::io::Cursor::new(&SPIRV[..])).unwrap(); /// ``` pub fn read_spirv(mut x: R) -> io::Result> { let size = x.seek(io::SeekFrom::End(0))?; diff --git a/src/hal/src/queue/capability.rs b/src/hal/src/queue/capability.rs deleted file mode 100644 index 5d36c5ae646..00000000000 --- a/src/hal/src/queue/capability.rs +++ /dev/null @@ -1,121 +0,0 @@ -//! Type system encoded queue capabilities. -use crate::queue::QueueType; - -/// General capability, supporting graphics, compute and transfer operations. -#[derive(Debug)] -pub enum General {} -/// Graphics capability, supporting graphics and transfer operations. -#[derive(Debug)] -pub enum Graphics {} -/// Compute capability, supporting compute and transfer operations. -#[derive(Debug)] -pub enum Compute {} -/// Transfer capability, supporting only transfer operations. -#[derive(Debug)] -pub enum Transfer {} - -/// Graphics or compute capability. -#[derive(Debug)] -pub enum GraphicsOrCompute {} - -/// A Capability is an object that specifies what kind of operations -/// a queue type performs, allowing what types support what queue operations -/// to be described at runtime by the type system. -pub trait Capability { - /// Return true if this type level capability is supported by - /// a run-time queue type. - fn supported_by(qt: QueueType) -> bool; -} -impl Capability for General { - fn supported_by(qt: QueueType) -> bool { - match qt { - QueueType::General => true, - _ => false, - } - } -} -impl Capability for Graphics { - fn supported_by(qt: QueueType) -> bool { - match qt { - QueueType::General | QueueType::Graphics => true, - _ => false, - } - } -} -impl Capability for Compute { - fn supported_by(qt: QueueType) -> bool { - match qt { - QueueType::General | QueueType::Compute => true, - _ => false, - } - } -} -impl Capability for Transfer { - fn supported_by(qt: QueueType) -> bool { - match qt { - QueueType::General | QueueType::Compute | QueueType::Graphics | QueueType::Transfer => { - true - } - } - } -} - -/// A trait that indicates that a particular type of queue supports -/// a particular `Capability`. -pub trait Supports {} -impl Supports for T {} -impl Supports for General {} -impl Supports for General {} -impl Supports for General {} -impl Supports for Graphics {} -impl Supports for Compute {} - -impl Supports for General {} -impl Supports for Graphics {} -impl Supports for Compute {} - -/// Encoding the minimal capability to support a combination of other capabilities. -pub trait Upper { - /// Resulting minimal required capability. - type Result; -} - -impl Upper for (T, T) { - type Result = T; -} -impl Upper for (General, Graphics) { - type Result = General; -} -impl Upper for (General, Compute) { - type Result = General; -} -impl Upper for (General, Transfer) { - type Result = General; -} -impl Upper for (Graphics, General) { - type Result = General; -} -impl Upper for (Graphics, Compute) { - type Result = General; -} -impl Upper for (Graphics, Transfer) { - type Result = Graphics; -} -impl Upper for (Compute, General) { - type Result = General; -} -impl Upper for (Compute, Graphics) { - type Result = General; -} -impl Upper for (Compute, Transfer) { - type Result = Compute; -} -impl Upper for (Transfer, General) { - type Result = General; -} -impl Upper for (Transfer, Graphics) { - type Result = Graphics; -} -impl Upper for (Transfer, Compute) { - type Result = Compute; -} diff --git a/src/hal/src/queue/family.rs b/src/hal/src/queue/family.rs index 62525c94f4b..5fb36ef071a 100644 --- a/src/hal/src/queue/family.rs +++ b/src/hal/src/queue/family.rs @@ -1,8 +1,6 @@ //! Queue family and groups. -use crate::backend::RawQueueGroup; -use crate::queue::capability::{Capability, Compute, Graphics, Transfer}; -use crate::queue::{CommandQueue, QueueType}; +use crate::queue::QueueType; use crate::Backend; use std::any::Any; @@ -16,18 +14,6 @@ pub trait QueueFamily: Debug + Any + Send + Sync { fn queue_type(&self) -> QueueType; /// Returns maximum number of queues created from this family. fn max_queues(&self) -> usize; - /// Returns true if the queue supports graphics operations. - fn supports_graphics(&self) -> bool { - Graphics::supported_by(self.queue_type()) - } - /// Returns true if the queue supports compute operations. - fn supports_compute(&self) -> bool { - Compute::supported_by(self.queue_type()) - } - /// Returns true if the queue supports transfer operations. - fn supports_transfer(&self) -> bool { - Transfer::supported_by(self.queue_type()) - } /// Returns the queue family ID. fn id(&self) -> QueueFamilyId; } @@ -37,65 +23,30 @@ pub trait QueueFamily: Debug + Any + Send + Sync { #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct QueueFamilyId(pub usize); -/// Strong-typed group of queues of the same queue family. +/// Bare-metal queue group. +/// +/// Denotes all queues created from one queue family. #[derive(Debug)] -pub struct QueueGroup { - family: QueueFamilyId, - /// Command queues created in this family. - pub queues: Vec>, +pub struct QueueGroup { + /// Family index for the queues in this group. + pub family: QueueFamilyId, + /// List of queues. + pub queues: Vec, } -impl QueueGroup { - /// Return the associated queue family id. - pub fn family(&self) -> QueueFamilyId { - self.family - } -} - -impl QueueGroup { - /// Create a new strongly typed queue group from a raw one. - /// - /// # Panics - /// - /// Panics if the family doesn't expose required queue capabilities. - fn new(raw: RawQueueGroup) -> Self { - assert!(C::supported_by(raw.family.queue_type())); +impl QueueGroup { + /// Create a new, empty queue group for a queue family. + pub fn new(family: QueueFamilyId) -> Self { QueueGroup { - family: raw.family.id(), - queues: raw - .queues - .into_iter() - .map(|q| unsafe { CommandQueue::new(q) }) - .collect(), + family, + queues: Vec::new(), } } -} - -/// Contains a list of all instantiated queues. Conceptually structured as a collection of -/// `QueueGroup`s, one for each queue family. -#[derive(Debug)] -pub struct Queues(pub(crate) Vec>); -impl Queues { - /// Removes the queue family with the passed id from the queue list and - /// returns the queue group. + /// Add a command queue to the group. /// - /// # Panics - /// - /// Panics if the family doesn't expose required queue capabilities. - pub fn take(&mut self, id: QueueFamilyId) -> Option> { - self.0 - .iter() - .position(|raw| raw.family.id() == id) - .map(|index| QueueGroup::new(self.0.swap_remove(index))) - } - - /// Removes the queue family with the passed id from the queue list and - /// returns the command queues. - pub fn take_raw(&mut self, id: QueueFamilyId) -> Option> { - self.0 - .iter() - .position(|raw| raw.family.id() == id) - .map(|index| self.0.swap_remove(index).queues) + /// The queue needs to be created from this queue family. + pub fn add_queue(&mut self, queue: B::CommandQueue) { + self.queues.push(queue); } } diff --git a/src/hal/src/queue/mod.rs b/src/hal/src/queue/mod.rs index 5ba1eaad23b..1887968d374 100644 --- a/src/hal/src/queue/mod.rs +++ b/src/hal/src/queue/mod.rs @@ -6,23 +6,15 @@ //! There are different types of queues, which can only handle associated command buffers. //! `CommandQueue` has the capability defined by `C`: graphics, compute and transfer. -pub mod capability; pub mod family; -use std::any::Any; -use std::borrow::Borrow; -use std::fmt; -use std::iter; -use std::marker::PhantomData; - -use crate::command::{Primary, Submittable}; use crate::error::HostExecutionError; use crate::pso; use crate::window::{PresentError, Suboptimal, SwapImageIndex}; use crate::Backend; +use std::{any::Any, borrow::Borrow, fmt, iter}; -pub use self::capability::{Capability, Compute, General, Graphics, Supports, Transfer}; -pub use self::family::{QueueFamily, QueueFamilyId, QueueGroup, Queues}; +pub use self::family::{QueueFamily, QueueFamilyId, QueueGroup}; /// The type of the queue, an enum encompassing `queue::Capability` #[derive(Debug, Copy, Clone, PartialEq, Eq)] @@ -38,6 +30,31 @@ pub enum QueueType { Transfer, } +impl QueueType { + /// Returns true if the queue supports graphics operations. + pub fn supports_graphics(&self) -> bool { + match *self { + QueueType::General | QueueType::Graphics => true, + QueueType::Compute | QueueType::Transfer => false, + } + } + /// Returns true if the queue supports compute operations. + pub fn supports_compute(&self) -> bool { + match *self { + QueueType::General | QueueType::Graphics | QueueType::Compute => true, + QueueType::Transfer => false, + } + } + /// Returns true if the queue supports transfer operations. + pub fn supports_transfer(&self) -> bool { + true + } +} + +/// Scheduling hint for devices about the priority of a queue. Values range from `0.0` (low) to +/// `1.0` (high). +pub type QueuePriority = f32; + /// Submission information for a command queue. #[derive(Debug)] pub struct Submission { @@ -51,7 +68,7 @@ pub struct Submission { /// `RawCommandQueue` are abstractions to the internal GPU execution engines. /// Commands are executed on the the device by submitting command buffers to queues. -pub trait RawCommandQueue: fmt::Debug + Any + Send + Sync { +pub trait CommandQueue: fmt::Debug + Any + Send + Sync { /// Submit command buffers to queue for execution. /// `fence` must be in unsignalled state, and will be signalled after all command buffers in the submission have /// finished execution. @@ -70,82 +87,14 @@ pub trait RawCommandQueue: fmt::Debug + Any + Send + Sync { Iw: IntoIterator, Is: IntoIterator; - /// Presents the result of the queue to the given swapchains, after waiting on all the - /// semaphores given in `wait_semaphores`. A given swapchain must not appear in this - /// list more than once. - /// - /// Unsafe for the same reasons as `submit()`. - unsafe fn present<'a, W, Is, S, Iw>( - &mut self, - swapchains: Is, - wait_semaphores: Iw, - ) -> Result, PresentError> - where - Self: Sized, - W: 'a + Borrow, - Is: IntoIterator, - S: 'a + Borrow, - Iw: IntoIterator; - - /// Wait for the queue to idle. - fn wait_idle(&self) -> Result<(), HostExecutionError>; -} - -/// Stronger-typed and safer `CommandQueue` wraps around `RawCommandQueue`. -#[derive(Debug)] -pub struct CommandQueue(B::CommandQueue, PhantomData); - -impl CommandQueue { - /// Create typed command queue from raw. - /// - /// # Safety - /// - /// `::supported_by(queue_type)` must return true - /// for `queue_type` being the type this `raw` queue. - pub unsafe fn new(raw: B::CommandQueue) -> Self { - CommandQueue(raw, PhantomData) - } - - /// Get a reference to the raw command queue - pub fn as_raw(&self) -> &B::CommandQueue { - &self.0 - } - - /// Get a mutable reference to the raw command queue - pub unsafe fn as_raw_mut(&mut self) -> &mut B::CommandQueue { - &mut self.0 - } - - /// Downgrade a typed command queue to untyped one. - pub fn into_raw(self) -> B::CommandQueue { - self.0 - } - - /// Submit command buffers to queue for execution. - /// `fence` must be in unsignalled state, and will be signalled after all command buffers in the submission have - /// finished execution. - pub unsafe fn submit<'a, T, Ic, S, Iw, Is>( + /// Simplified version of `submit` that doesn't expect any semaphores. + unsafe fn submit_without_semaphores<'a, T, Ic>( &mut self, - submission: Submission, + command_buffers: Ic, fence: Option<&B::Fence>, ) where - T: 'a + Submittable, + T: 'a + Borrow, Ic: IntoIterator, - S: 'a + Borrow, - Iw: IntoIterator, - Is: IntoIterator, - { - self.0.submit(submission, fence) - } - - /// Submit command buffers without any semaphore waits or signals. - pub unsafe fn submit_without_semaphores<'a, T, I>( - &mut self, - command_buffers: I, - fence: Option<&B::Fence>, - ) where - T: 'a + Submittable, - I: IntoIterator, { let submission = Submission { command_buffers, @@ -158,30 +107,33 @@ impl CommandQueue { /// Presents the result of the queue to the given swapchains, after waiting on all the /// semaphores given in `wait_semaphores`. A given swapchain must not appear in this /// list more than once. - pub unsafe fn present<'a, W, Is, S, Iw>( + /// + /// Unsafe for the same reasons as `submit()`. + unsafe fn present<'a, W, Is, S, Iw>( &mut self, swapchains: Is, wait_semaphores: Iw, ) -> Result, PresentError> where + Self: Sized, W: 'a + Borrow, Is: IntoIterator, S: 'a + Borrow, - Iw: IntoIterator, - { - self.0.present(swapchains, wait_semaphores) - } - - /// Wait for the queue to idle. - pub fn wait_idle(&self) -> Result<(), HostExecutionError> { - self.0.wait_idle() - } + Iw: IntoIterator; - /// Downgrade a command queue to a lesser capability type. - pub unsafe fn downgrade(&mut self) -> &mut CommandQueue + /// Simplified version of `present` that doesn't expect any semaphores. + unsafe fn present_without_semaphores<'a, W, Is>( + &mut self, + swapchains: Is, + ) -> Result, PresentError> where - C: Supports, + Self: Sized, + W: 'a + Borrow, + Is: IntoIterator, { - ::std::mem::transmute(self) + self.present::<_, _, B::Semaphore, _>(swapchains, iter::empty()) } + + /// Wait for the queue to idle. + fn wait_idle(&self) -> Result<(), HostExecutionError>; } diff --git a/src/hal/src/window.rs b/src/hal/src/window.rs index 701f00c85dc..4de9f96518f 100644 --- a/src/hal/src/window.rs +++ b/src/hal/src/window.rs @@ -25,12 +25,11 @@ //! # extern crate gfx_backend_empty as empty; //! # extern crate gfx_hal; //! # fn main() { -//! use gfx_hal::Device; -//! # use gfx_hal::{CommandQueue, Graphics, Swapchain}; +//! # use gfx_hal::prelude::*; //! //! # let mut swapchain: empty::Swapchain = return; //! # let device: empty::Device = return; -//! # let mut present_queue: CommandQueue = return; +//! # let mut present_queue: empty::CommandQueue = return; //! # unsafe { //! let acquisition_semaphore = device.create_semaphore().unwrap(); //! let render_semaphore = device.create_semaphore().unwrap(); @@ -53,7 +52,7 @@ use crate::device; use crate::format::Format; use crate::image; -use crate::queue::{Capability, CommandQueue}; +use crate::queue::CommandQueue; use crate::Backend; use std::any::Any; @@ -258,7 +257,7 @@ bitflags!( /// ```no_run /// # extern crate gfx_hal; /// # fn main() { -/// # use gfx_hal::{SwapchainConfig}; +/// # use gfx_hal::window::SwapchainConfig; /// # use gfx_hal::format::Format; /// let config = SwapchainConfig::new(100, 100, Format::Bgra8Unorm, 2); /// # } @@ -312,7 +311,8 @@ impl SwapchainConfig { Some(current) => current, None => { let (min_width, max_width) = (caps.extents.start().width, caps.extents.end().width); - let (min_height, max_height) = (caps.extents.start().height, caps.extents.end().height); + let (min_height, max_height) = + (caps.extents.start().height, caps.extents.end().height); // clamp the default_extent to within the allowed surface sizes let width = min(max_width, max(default_extent.width, min_width)); @@ -450,15 +450,14 @@ pub trait Swapchain: fmt::Debug + Any + Send + Sync { /// ```no_run /// /// ``` - unsafe fn present<'a, C, S, Iw>( + unsafe fn present<'a, S, Iw>( &'a self, - present_queue: &mut CommandQueue, + present_queue: &mut B::CommandQueue, image_index: SwapImageIndex, wait_semaphores: Iw, ) -> Result, PresentError> where Self: 'a + Sized + Borrow, - C: Capability, S: 'a + Borrow, Iw: IntoIterator, { @@ -466,15 +465,14 @@ pub trait Swapchain: fmt::Debug + Any + Send + Sync { } /// Present one acquired image without any semaphore synchronization. - unsafe fn present_without_semaphores<'a, C>( + unsafe fn present_without_semaphores<'a>( &'a self, - present_queue: &mut CommandQueue, + present_queue: &mut B::CommandQueue, image_index: SwapImageIndex, ) -> Result, PresentError> where Self: 'a + Sized + Borrow, - C: Capability, { - self.present::<_, B::Semaphore, _>(present_queue, image_index, iter::empty()) + self.present::(present_queue, image_index, iter::empty()) } } diff --git a/src/warden/src/bin/reftest.rs b/src/warden/src/bin/reftest.rs index bb9bd9f74d3..7e29a8dabcf 100644 --- a/src/warden/src/bin/reftest.rs +++ b/src/warden/src/bin/reftest.rs @@ -80,7 +80,7 @@ impl Harness { } fn run(&self, instance: I, _disabilities: Disabilities) -> usize { - use hal::PhysicalDevice as _; + use hal::adapter::PhysicalDevice as _; let mut results = TestResults { pass: 0, @@ -108,7 +108,7 @@ impl Harness { } } - let mut scene = warden::gpu::Scene::::new( + let mut scene = warden::gpu::Scene::::new( adapter, &tg.scene, self.base_path.join("data"), @@ -223,7 +223,12 @@ fn main() { .with_gl_profile(glutin::GlProfile::Core) .build_windowed(glutin::window::WindowBuilder::new(), &events_loop) .unwrap(); - let (context, window) = unsafe { windowed_context.make_current().expect("Unable to make window current").split() }; + let (context, window) = unsafe { + windowed_context + .make_current() + .expect("Unable to make window current") + .split() + }; let instance = gfx_backend_gl::Surface::from_context(context); num_failures += harness.run(instance, Disabilities::default()); } diff --git a/src/warden/src/gpu.rs b/src/warden/src/gpu.rs index 88f5ac773aa..b76a67f42bc 100644 --- a/src/warden/src/gpu.rs +++ b/src/warden/src/gpu.rs @@ -8,8 +8,18 @@ use std::io::Read; use std::path::PathBuf; use std::{iter, slice}; -use hal::{self, buffer as b, command as c, format as f, image as i, memory, pso}; -use hal::{DescriptorPool, Device, PhysicalDevice}; +use hal::{ + self, + adapter, + buffer as b, + command as c, + format as f, + image as i, + memory, + prelude::*, + pso, + queue, +}; use crate::raw; @@ -113,17 +123,17 @@ pub struct Resources { pub compute_pipelines: HashMap, } -pub struct Job { - submission: c::CommandBuffer, +pub struct Job { + submission: B::CommandBuffer, } -pub struct Scene { +pub struct Scene { pub resources: Resources, - pub jobs: HashMap>, - init_submit: c::CommandBuffer, + pub jobs: HashMap>, + init_submit: B::CommandBuffer, device: B::Device, - queue_group: hal::QueueGroup, - command_pool: Option>, + queue_group: queue::QueueGroup, + command_pool: Option, upload_buffers: HashMap, download_type: hal::MemoryTypeId, limits: hal::Limits, @@ -137,9 +147,9 @@ fn align(x: u64, y: u64) -> u64 { } } -impl Scene { +impl Scene { pub fn new( - adapter: hal::Adapter, + adapter: adapter::Adapter, raw: &raw::Scene, data_path: PathBuf, ) -> Result { @@ -148,7 +158,14 @@ impl Scene { let limits = adapter.physical_device.limits(); // initialize graphics - let (device, queue_group) = adapter.open_with(1, |_| true)?; + let mut gpu = unsafe { + adapter.physical_device.open( + &[(&adapter.queue_families[0], &[1.0])], + hal::Features::empty(), + )? + }; + let device = gpu.device; + let queue_group = gpu.queue_groups.pop().unwrap(); let upload_type: hal::MemoryTypeId = memory_types .iter() @@ -172,9 +189,11 @@ impl Scene { info!("download memory: {:?}", &download_type); let mut command_pool = unsafe { - device - .create_command_pool_typed(&queue_group, hal::pool::CommandPoolCreateFlags::empty()) - }?; + device.create_command_pool( + queue_group.family, + hal::pool::CommandPoolCreateFlags::empty(), + )? + }; // create resources let mut resources = Resources:: { @@ -192,9 +211,9 @@ impl Scene { compute_pipelines: HashMap::new(), }; let mut upload_buffers = HashMap::new(); - let mut init_cmd = command_pool.acquire_command_buffer::(); + let mut init_cmd = command_pool.allocate_one(c::Level::Primary); unsafe { - init_cmd.begin(false); + init_cmd.begin_primary(c::CommandBufferFlags::SIMULTANEOUS_USE); } // Pass[1]: images, buffers, passes, descriptor set layouts/pools for (name, resource) in &raw.resources { @@ -582,7 +601,7 @@ impl Scene { "comp" => transpile(base_file, glsl_to_spirv::ShaderType::Compute), other => panic!("Unknown shader extension: {}", other), }; - let spirv = hal::read_spirv(file).unwrap(); + let spirv = pso::read_spirv(file).unwrap(); let module = unsafe { device.create_shader_module(&spirv) }.unwrap(); resources.shaders.insert(name.clone(), module); } @@ -816,9 +835,9 @@ impl Scene { let mut jobs = HashMap::new(); for (name, job) in &raw.jobs { use crate::raw::TransferCommand as Tc; - let mut command_buf = command_pool.acquire_command_buffer::(); + let mut command_buf = command_pool.allocate_one(c::Level::Primary); unsafe { - command_buf.begin(false); + command_buf.begin_primary(c::CommandBufferFlags::empty()); } match *job { raw::Job::Transfer(ref command) => match *command { @@ -988,8 +1007,7 @@ impl Scene { }, Tc::ClearImage { ref image, - color, - depth_stencil, + ref value, ref ranges, } => unsafe { let img = resources @@ -1007,8 +1025,7 @@ impl Scene { command_buf.clear_image( &img.handle, i::Layout::TransferDstOptimal, - color, - depth_stencil, + value.to_raw(), ranges, ); command_buf.pipeline_barrier( @@ -1107,10 +1124,15 @@ impl Scene { w: extent.width as _, h: extent.height as _, }; - let mut encoder = - command_buf.begin_render_pass_inline(&rp.handle, fb, rect, clear_values); - encoder.set_scissors(0, Some(rect)); - encoder.set_viewports( + command_buf.begin_render_pass( + &rp.handle, + fb, + rect, + clear_values.iter().map(|cv| cv.to_raw()), + c::SubpassContents::Inline, + ); + command_buf.set_scissors(0, Some(rect)); + command_buf.set_viewports( 0, Some(pso::Viewport { rect, @@ -1120,7 +1142,7 @@ impl Scene { for subpass in &rp.subpasses { if Some(subpass) != rp.subpasses.first() { - encoder = encoder.next_subpass_inline(); + command_buf.next_subpass(c::SubpassContents::Inline); } for command in &pass.1[subpass].commands { use crate::raw::DrawCommand as Dc; @@ -1139,7 +1161,7 @@ impl Scene { offset, index_type, }; - encoder.bind_index_buffer(view); + command_buf.bind_index_buffer(view); } Dc::BindVertexBuffers(ref buffers) => { let buffers_raw = buffers.iter().map(|&(ref name, offset)| { @@ -1150,21 +1172,21 @@ impl Scene { .handle; (buf, offset) }); - encoder.bind_vertex_buffers(0, buffers_raw); + command_buf.bind_vertex_buffers(0, buffers_raw); } Dc::BindPipeline(ref name) => { let pso = resources .graphics_pipelines .get(name) .expect(&format!("Missing graphics pipeline: {}", name)); - encoder.bind_graphics_pipeline(pso); + command_buf.bind_graphics_pipeline(pso); } Dc::BindDescriptorSets { ref layout, first, ref sets, } => { - encoder.bind_graphics_descriptor_sets( + command_buf.bind_graphics_descriptor_sets( resources.pipeline_layouts.get(layout).expect(&format!( "Missing pipeline layout: {}", layout @@ -1183,24 +1205,24 @@ impl Scene { ref vertices, ref instances, } => { - encoder.draw(vertices.clone(), instances.clone()); + command_buf.draw(vertices.clone(), instances.clone()); } Dc::DrawIndexed { ref indices, base_vertex, ref instances, } => { - encoder.draw_indexed( + command_buf.draw_indexed( indices.clone(), base_vertex, instances.clone(), ); } Dc::SetViewports(ref viewports) => { - encoder.set_viewports(0, viewports); + command_buf.set_viewports(0, viewports); } Dc::SetScissors(ref scissors) => { - encoder.set_scissors(0, scissors); + command_buf.set_scissors(0, scissors); } } } @@ -1257,7 +1279,7 @@ impl Scene { } } -impl Scene { +impl Scene { pub fn run<'a, I>(&mut self, job_names: I) where I: IntoIterator, @@ -1306,15 +1328,15 @@ impl Scene { .unwrap(); let mut command_pool = unsafe { - self.device.create_command_pool_typed( - &self.queue_group, + self.device.create_command_pool( + self.queue_group.family, hal::pool::CommandPoolCreateFlags::empty(), ) } .expect("Can't create command pool"); - let mut cmd_buffer = command_pool.acquire_command_buffer::(); + let mut cmd_buffer = command_pool.allocate_one(c::Level::Primary); unsafe { - cmd_buffer.begin(); + cmd_buffer.begin_primary(c::CommandBufferFlags::ONE_TIME_SUBMIT); let pre_barrier = memory::Barrier::whole_buffer( &buffer.handle, buffer.stable_state .. b::Access::TRANSFER_READ, @@ -1353,7 +1375,7 @@ impl Scene { .submit_without_semaphores(iter::once(&cmd_buffer), Some(©_fence)); self.device.wait_for_fence(©_fence, !0).unwrap(); self.device.destroy_fence(copy_fence); - self.device.destroy_command_pool(command_pool.into_raw()); + self.device.destroy_command_pool(command_pool); } let mapping = unsafe { self.device.map_memory(&down_memory, 0 .. down_size) }.unwrap(); @@ -1412,15 +1434,15 @@ impl Scene { .unwrap(); let mut command_pool = unsafe { - self.device.create_command_pool_typed( - &self.queue_group, + self.device.create_command_pool( + self.queue_group.family, hal::pool::CommandPoolCreateFlags::empty(), ) } .expect("Can't create command pool"); - let mut cmd_buffer = command_pool.acquire_command_buffer::(); + let mut cmd_buffer = command_pool.allocate_one(c::Level::Primary); unsafe { - cmd_buffer.begin(); + cmd_buffer.begin_primary(c::CommandBufferFlags::ONE_TIME_SUBMIT); let pre_barrier = memory::Barrier::Image { states: image.stable_state .. (i::Access::TRANSFER_READ, i::Layout::TransferSrcOptimal), @@ -1481,7 +1503,7 @@ impl Scene { .submit_without_semaphores(iter::once(&cmd_buffer), Some(©_fence)); self.device.wait_for_fence(©_fence, !0).unwrap(); self.device.destroy_fence(copy_fence); - self.device.destroy_command_pool(command_pool.into_raw()); + self.device.destroy_command_pool(command_pool); } let mapping = unsafe { self.device.map_memory(&down_memory, 0 .. down_size) }.unwrap(); @@ -1497,7 +1519,7 @@ impl Scene { } } -impl Drop for Scene { +impl Drop for Scene { fn drop(&mut self) { unsafe { for (_, (buffer, memory)) in self.upload_buffers.drain() { @@ -1507,7 +1529,7 @@ impl Drop for Scene { //TODO: free those properly let _ = &self.queue_group; self.device - .destroy_command_pool(self.command_pool.take().unwrap().into_raw()); + .destroy_command_pool(self.command_pool.take().unwrap()); } } } diff --git a/src/warden/src/raw.rs b/src/warden/src/raw.rs index 97da36196eb..285cd90b582 100644 --- a/src/warden/src/raw.rs +++ b/src/warden/src/raw.rs @@ -3,6 +3,40 @@ use std::ops::Range; use hal; +#[derive(Debug, Deserialize)] +pub enum ClearColor { + Float([f32; 4]), + Uint([u32; 4]), + Sint([i32; 4]), +} + +impl ClearColor { + pub fn to_raw(&self) -> hal::command::ClearColor { + match *self { + ClearColor::Float(array) => hal::command::ClearColor { float32: array }, + ClearColor::Uint(array) => hal::command::ClearColor { uint32: array }, + ClearColor::Sint(array) => hal::command::ClearColor { sint32: array }, + } + } +} + +#[derive(Debug, Deserialize)] +pub enum ClearValue { + Color(ClearColor), + DepthStencil(hal::command::ClearDepthStencil), +} + +impl ClearValue { + pub fn to_raw(&self) -> hal::command::ClearValue { + match *self { + ClearValue::Color(ref color) => hal::command::ClearValue { + color: color.to_raw(), + }, + ClearValue::DepthStencil(ds) => hal::command::ClearValue { depth_stencil: ds }, + } + } +} + #[derive(Debug, Deserialize)] pub struct AttachmentRef(pub String, pub hal::pass::AttachmentLayout); @@ -141,8 +175,7 @@ pub enum TransferCommand { }, ClearImage { image: String, - color: hal::command::ClearColor, - depth_stencil: hal::command::ClearDepthStencil, + value: ClearValue, ranges: Vec, }, BlitImage { @@ -207,7 +240,7 @@ pub enum Job { Transfer(TransferCommand), Graphics { framebuffer: String, - clear_values: Vec, + clear_values: Vec, pass: (String, HashMap), }, Compute {