From eb7bdcd012d4528a8dce8da9a777be3dc59c9846 Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Fri, 17 Jul 2020 10:59:02 -0400 Subject: [PATCH] playtest: move the actions together with expectations --- player/Cargo.toml | 5 - player/tests/data/all.ron | 13 +- player/tests/data/buffer-copy.ron | 51 ++++--- player/tests/test.rs | 218 ++++++++++++++++-------------- 4 files changed, 145 insertions(+), 142 deletions(-) diff --git a/player/Cargo.toml b/player/Cargo.toml index 7e4befa6e..6e625a7c9 100644 --- a/player/Cargo.toml +++ b/player/Cargo.toml @@ -12,11 +12,6 @@ keywords = ["graphics"] license = "MPL-2.0" publish = false -[lib] - -[[bin]] -name = "play" - [features] [dependencies] diff --git a/player/tests/data/all.ron b/player/tests/data/all.ron index 7f8733aa6..19d7d805b 100644 --- a/player/tests/data/all.ron +++ b/player/tests/data/all.ron @@ -1,17 +1,6 @@ ( backends: (bits: 0x7), tests: [ - ( - path: "buffer-copy.ron", - features: (bits: 0x0), - expectations: [ - ( - name: "basic", - buffer: (index: 0, epoch: 1), - offset: 0, - data: [0x00, 0x00, 0x80, 0xBF], - ) - ], - ), + "buffer-copy.ron", ], ) \ No newline at end of file diff --git a/player/tests/data/buffer-copy.ron b/player/tests/data/buffer-copy.ron index f24f2f52c..cd3105e6e 100644 --- a/player/tests/data/buffer-copy.ron +++ b/player/tests/data/buffer-copy.ron @@ -1,23 +1,34 @@ -[ - CreateBuffer( - id: Id(0, 1, Empty), - desc: ( - label: "", - size: 16, - usage: ( - bits: 41, +( + features: (bits: 0x0), + expectations: [ + ( + name: "basic", + buffer: (index: 0, epoch: 1), + offset: 0, + data: [0x00, 0x00, 0x80, 0xBF], + ) + ], + actions: [ + CreateBuffer( + id: Id(0, 1, Empty), + desc: ( + label: "", + size: 16, + usage: ( + bits: 41, + ), + mapped_at_creation: false, ), - mapped_at_creation: false, ), - ), - WriteBuffer( - id: Id(0, 1, Empty), - data: "data1.bin", - range: ( - start: 0, - end: 16, + WriteBuffer( + id: Id(0, 1, Empty), + data: "data1.bin", + range: ( + start: 0, + end: 16, + ), + queued: true, ), - queued: true, - ), - Submit(1, []), -] \ No newline at end of file + Submit(1, []), + ], +) \ No newline at end of file diff --git a/player/tests/test.rs b/player/tests/test.rs index 5c5690d91..6c3f2bab1 100644 --- a/player/tests/test.rs +++ b/player/tests/test.rs @@ -10,6 +10,7 @@ * - all IDs have the backend `Empty` * - all expected buffers have `MAP_READ` usage * - last action is `Submit` + * - no swapchain use !*/ use player::{gfx_select, GlobalPlay, IdentityPassThroughFactory}; @@ -35,15 +36,88 @@ struct Expectation { #[derive(serde::Deserialize)] struct Test { - path: String, features: wgt::Features, expectations: Vec, + actions: Vec, +} + +extern "C" fn map_callback(status: wgc::resource::BufferMapAsyncStatus, _user_data: *mut u8) { + match status { + wgc::resource::BufferMapAsyncStatus::Success => (), + _ => panic!("Unable to map"), + } +} + +impl Test { + fn load(path: PathBuf, backend: wgt::Backend) -> Self { + let backend_name = match backend { + wgt::Backend::Vulkan => "Vulkan", + wgt::Backend::Metal => "Metal", + wgt::Backend::Dx12 => "Dx12", + wgt::Backend::Dx11 => "Dx11", + wgt::Backend::Gl => "Gl", + _ => unreachable!(), + }; + let string = read_to_string(path).unwrap().replace("Empty", backend_name); + ron::de::from_str(&string).unwrap() + } + + fn run( + self, + dir: &Path, + global: &wgc::hub::Global, + adapter: wgc::id::AdapterId, + ) { + let backend = adapter.backend(); + let device = gfx_select!(adapter => global.adapter_request_device( + adapter, + &wgt::DeviceDescriptor { + features: self.features | wgt::Features::MAPPABLE_PRIMARY_BUFFERS, + limits: wgt::Limits::default(), + shader_validation: true, + }, + None, + wgc::id::TypedId::zip(1, 0, backend) + )) + .unwrap(); + + let mut command_buffer_id_manager = wgc::hub::IdentityManager::default(); + println!("\t\t\tRunning..."); + for action in self.actions { + gfx_select!(device => global.process(device, action, dir, &mut command_buffer_id_manager)); + } + println!("\t\t\tMapping..."); + for expect in &self.expectations { + let buffer = wgc::id::TypedId::zip(expect.buffer.index, expect.buffer.epoch, backend); + gfx_select!(device => global.buffer_map_async( + buffer, + expect.offset .. expect.offset+expect.data.len() as wgt::BufferAddress, + wgc::resource::BufferMapOperation { + host: wgc::device::HostMap::Read, + callback: map_callback, + user_data: ptr::null_mut(), + } + )); + } + + println!("\t\t\tWaiting..."); + gfx_select!(device => global.device_poll(device, true)); + + for expect in self.expectations { + println!("\t\t\tChecking {}", expect.name); + let buffer = wgc::id::TypedId::zip(expect.buffer.index, expect.buffer.epoch, backend); + let ptr = + gfx_select!(device => global.buffer_get_mapped_range(buffer, expect.offset, None)); + let contents = unsafe { slice::from_raw_parts(ptr, expect.data.len()) }; + assert_eq!(&expect.data[..], contents); + } + } } #[derive(serde::Deserialize)] struct Corpus { backends: wgt::BackendBit, - tests: Vec, + tests: Vec, } const BACKENDS: &[wgt::Backend] = &[ @@ -54,116 +128,50 @@ const BACKENDS: &[wgt::Backend] = &[ wgt::Backend::Gl, ]; -extern "C" fn map_callback(status: wgc::resource::BufferMapAsyncStatus, _user_data: *mut u8) { - match status { - wgc::resource::BufferMapAsyncStatus::Success => (), - _ => panic!("Unable to map"), - } -} +impl Corpus { + fn run_from(path: PathBuf) { + println!("Corpus {:?}", path); + let dir = path.parent().unwrap(); + let corpus: Corpus = ron::de::from_reader(File::open(&path).unwrap()).unwrap(); -fn run_test( - test: Test, - dir: &Path, - global: &wgc::hub::Global, - adapter: wgc::id::AdapterId, -) { - println!("\t\tTest '{:?}'", test.path); - let device = gfx_select!(adapter => global.adapter_request_device( - adapter, - &wgt::DeviceDescriptor { - features: test.features | wgt::Features::MAPPABLE_PRIMARY_BUFFERS, - limits: wgt::Limits::default(), - shader_validation: true, - }, - None, - wgc::id::TypedId::zip(1, 0, adapter.backend()) - )) - .unwrap(); - - let backend = device.backend(); - let backend_name = match backend { - wgt::Backend::Vulkan => "Vulkan", - wgt::Backend::Metal => "Metal", - wgt::Backend::Dx12 => "Dx12", - wgt::Backend::Dx11 => "Dx11", - wgt::Backend::Gl => "Gl", - _ => unreachable!(), - }; - let string = read_to_string(dir.join(test.path)) - .unwrap() - .replace("Empty", backend_name); - let actions: Vec = ron::de::from_str(&string).unwrap(); - - let mut command_buffer_id_manager = wgc::hub::IdentityManager::default(); - println!("\t\t\tRunning..."); - for action in actions { - gfx_select!(device => global.process(device, action, dir, &mut command_buffer_id_manager)); - } - println!("\t\t\tMapping..."); - for expect in &test.expectations { - let buffer = wgc::id::TypedId::zip(expect.buffer.index, expect.buffer.epoch, backend); - gfx_select!(device => global.buffer_map_async( - buffer, - expect.offset .. expect.offset+expect.data.len() as wgt::BufferAddress, - wgc::resource::BufferMapOperation { - host: wgc::device::HostMap::Read, - callback: map_callback, - user_data: ptr::null_mut(), - } - )); - } - - println!("\t\t\tWaiting..."); - gfx_select!(device => global.device_poll(device, true)); - - for expect in test.expectations { - println!("\t\t\tChecking {}", expect.name); - let buffer = wgc::id::TypedId::zip(expect.buffer.index, expect.buffer.epoch, backend); - let ptr = - gfx_select!(device => global.buffer_get_mapped_range(buffer, expect.offset, None)); - let contents = unsafe { slice::from_raw_parts(ptr, expect.data.len()) }; - assert_eq!(&expect.data[..], contents); - } -} - -fn run_corpus(path: PathBuf) { - println!("Corpus {:?}", path); - let mut corpus: Corpus = ron::de::from_reader(File::open(&path).unwrap()).unwrap(); - - let global = wgc::hub::Global::new("test", IdentityPassThroughFactory, corpus.backends); - for &backend in BACKENDS { - if !corpus.backends.contains(backend.into()) { - continue; - } - let adapter = match global.pick_adapter( - &wgc::instance::RequestAdapterOptions { - power_preference: wgt::PowerPreference::Default, - compatible_surface: None, - }, - wgc::instance::AdapterInputs::IdSet(&[wgc::id::TypedId::zip(0, 0, backend)], |id| { - id.backend() - }), - ) { - Some(adapter) => adapter, - None => continue, - }; - - println!("\tBackend {:?}", backend); - let supported_features = gfx_select!(adapter => global.adapter_features(adapter)); - for test in corpus.tests.drain(..) { - if !supported_features.contains(test.features) { - println!( - "\t\tSkipped due to missing features {:?}", - test.features - supported_features - ); + let global = wgc::hub::Global::new("test", IdentityPassThroughFactory, corpus.backends); + for &backend in BACKENDS { + if !corpus.backends.contains(backend.into()) { continue; } - run_test(test, path.parent().unwrap(), &global, adapter); + let adapter = match global.pick_adapter( + &wgc::instance::RequestAdapterOptions { + power_preference: wgt::PowerPreference::Default, + compatible_surface: None, + }, + wgc::instance::AdapterInputs::IdSet( + &[wgc::id::TypedId::zip(0, 0, backend)], + |id| id.backend(), + ), + ) { + Some(adapter) => adapter, + None => continue, + }; + + println!("\tBackend {:?}", backend); + let supported_features = gfx_select!(adapter => global.adapter_features(adapter)); + for test_path in &corpus.tests { + println!("\t\tTest '{:?}'", test_path); + let test = Test::load(dir.join(test_path), adapter.backend()); + if !supported_features.contains(test.features) { + println!( + "\t\tSkipped due to missing features {:?}", + test.features - supported_features + ); + continue; + } + test.run(dir, &global, adapter); + } } } } #[test] fn test_api() { - run_corpus(PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/data/all.ron")) + Corpus::run_from(PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/data/all.ron")) }