From 881aab35bd4e74dec720d57caf6f3ba4b6528d5f Mon Sep 17 00:00:00 2001 From: Zakor Gyula Date: Tue, 4 Dec 2018 16:49:59 +0100 Subject: [PATCH] Add get_pipeline_cache_data + extend create_pipeline_cache with data --- src/backend/dx11/src/device.rs | 6 ++- src/backend/dx12/src/device.rs | 6 ++- src/backend/empty/src/lib.rs | 6 ++- src/backend/gl/src/device.rs | 6 ++- src/backend/metal/src/device.rs | 6 ++- src/backend/vulkan/src/device.rs | 69 ++++++++++++++++++++++++++++++-- src/hal/src/device.rs | 6 ++- 7 files changed, 95 insertions(+), 10 deletions(-) diff --git a/src/backend/dx11/src/device.rs b/src/backend/dx11/src/device.rs index 2d952bb0c25..b9184156db7 100644 --- a/src/backend/dx11/src/device.rs +++ b/src/backend/dx11/src/device.rs @@ -829,10 +829,14 @@ impl hal::Device for Device { }) } - fn create_pipeline_cache(&self) -> Result<(), device::OutOfMemory> { + fn create_pipeline_cache(&self, _data: Option>, device: &PhysicalDevice) -> Result<(), device::OutOfMemory> { Ok(()) } + fn get_pipeline_cache_data(&self, cache: &()) -> Result, device::OutOfMemory> { + Ok(Vec::new()) + } + fn destroy_pipeline_cache(&self, _: ()) { //empty } diff --git a/src/backend/dx12/src/device.rs b/src/backend/dx12/src/device.rs index b4fc4c955b2..94ba4bb201d 100644 --- a/src/backend/dx12/src/device.rs +++ b/src/backend/dx12/src/device.rs @@ -1433,10 +1433,14 @@ impl d::Device for Device { }) } - fn create_pipeline_cache(&self) -> Result<(), d::OutOfMemory> { + fn create_pipeline_cache(&self, _data: Option>, device: &PhysicalDevice) -> Result<(), d::OutOfMemory> { Ok(()) } + fn get_pipeline_cache_data(&self, cache: &()) -> Result, d::OutOfMemory> { + Ok(Vec::new()) + } + fn destroy_pipeline_cache(&self, _: ()) { //empty } diff --git a/src/backend/empty/src/lib.rs b/src/backend/empty/src/lib.rs index 850ed594ce3..d10d1e1f5ff 100644 --- a/src/backend/empty/src/lib.rs +++ b/src/backend/empty/src/lib.rs @@ -149,7 +149,11 @@ impl hal::Device for Device { unimplemented!() } - fn create_pipeline_cache(&self) -> Result<(), device::OutOfMemory> { + fn create_pipeline_cache(&self, _data: Option>, device: &PhysicalDevice) -> Result<(), device::OutOfMemory> { + unimplemented!() + } + + fn get_pipeline_cache_data(&self, cache: &()) -> Result, device::OutOfMemory> { unimplemented!() } diff --git a/src/backend/gl/src/device.rs b/src/backend/gl/src/device.rs index 4cf8e75b2f4..7e5f7af05d6 100644 --- a/src/backend/gl/src/device.rs +++ b/src/backend/gl/src/device.rs @@ -596,10 +596,14 @@ impl d::Device for Device { }) } - fn create_pipeline_cache(&self) -> Result<(), d::OutOfMemory> { + fn create_pipeline_cache(&self, _data: Option>, device: &PhysicalDevice) -> Result<(), d::OutOfMemory> { Ok(()) } + fn get_pipeline_cache_data(&self, cache: &()) -> Result, d::OutOfMemory> { + Ok(Vec::new()) + } + fn destroy_pipeline_cache(&self, _: ()) { //empty } diff --git a/src/backend/metal/src/device.rs b/src/backend/metal/src/device.rs index 86e04174ef4..754b07747bf 100644 --- a/src/backend/metal/src/device.rs +++ b/src/backend/metal/src/device.rs @@ -1157,12 +1157,16 @@ impl hal::Device for Device { }) } - fn create_pipeline_cache(&self) -> Result { + fn create_pipeline_cache(&self, _data: Option>) -> Result { Ok(n::PipelineCache { modules: FastStorageMap::default(), }) } + fn get_pipeline_cache_data(&self, cache: &n::PipelineCache) -> Result, OutOfMemory> { + Ok(Vec::new()) + } + fn destroy_pipeline_cache(&self, _cache: n::PipelineCache) { //drop } diff --git a/src/backend/vulkan/src/device.rs b/src/backend/vulkan/src/device.rs index 059a7513d6d..3d5efeb0e0e 100644 --- a/src/backend/vulkan/src/device.rs +++ b/src/backend/vulkan/src/device.rs @@ -20,6 +20,7 @@ use std::sync::Arc; use {Backend as B, Device}; use {conv, native as n, result, window as w}; use pool::RawCommandPool; +use PhysicalDevice; #[derive(Debug)] @@ -285,13 +286,61 @@ impl d::Device for Device { } } - fn create_pipeline_cache(&self) -> Result { + fn create_pipeline_cache(&self, data: Option>, device: &PhysicalDevice) -> Result { + let (data_len, data) = match data { + Some(d) => { + let mut bad_cache = false; + let header = unsafe { + std::mem::transmute::<[u8; 4], u32>([d[0], d[1], d[2], d[3]]) }; + if header <= 0 { + warn!("Bad header length"); + bad_cache = true; + } + + let cache_header_version = unsafe { + std::mem::transmute::<[u8; 4], u32>([d[4], d[5], d[6], d[7]]) }; + + if cache_header_version != 1 { + warn!("Unsupported cache header version"); + bad_cache = true; + } + + let vendor_id = unsafe { + std::mem::transmute::<[u8; 4], u32>([d[8], d[9], d[10], d[11]]) }; + + if vendor_id != device.properties.vendor_id as u32 { + warn!("Vendor ID mismatch"); + bad_cache = true; + } + + let device_id = unsafe { + std::mem::transmute::<[u8; 4], u32>([d[12], d[13], d[14], d[15]]) }; + + if device_id != device.properties.device_id as u32 { + warn!("Device ID mismatch"); + bad_cache = true; + } + + if device.properties.pipeline_cache_uuid != d[16 .. 32] { + warn!("Pipeline cache UUID mismatch device :{:?}, cache {:?}", + device.properties.pipeline_cache_uuid, + d[16 .. 32].to_vec()); + bad_cache = true; + } + if bad_cache { + (0_usize, ptr::null()) + } else { + (d.len(), d.as_ptr()) + } + }, + None => (0_usize, ptr::null()), + }; let info = vk::PipelineCacheCreateInfo { s_type: vk::StructureType::PipelineCacheCreateInfo, p_next: ptr::null(), flags: vk::PipelineCacheCreateFlags::empty(), - initial_data_size: 0, //TODO - p_initial_data: ptr::null(), + initial_data_size: data_len, + p_initial_data: data as _, }; let result = unsafe { @@ -307,6 +356,20 @@ impl d::Device for Device { } } + fn get_pipeline_cache_data(&self, cache: &n::PipelineCache) -> Result, d::OutOfMemory> { + let result = unsafe { + self.raw.0 + .get_pipeline_cache_data(cache.raw) + }; + + match result { + Ok(data) => Ok(data), + Err(vk::Result::ErrorOutOfHostMemory) => Err(d::OutOfMemory::OutOfHostMemory), + Err(vk::Result::ErrorOutOfDeviceMemory) => Err(d::OutOfMemory::OutOfDeviceMemory), + _ => unreachable!(), + } + } + fn destroy_pipeline_cache(&self, cache: n::PipelineCache) { unsafe { self.raw.0.destroy_pipeline_cache(cache.raw, None) diff --git a/src/hal/src/device.rs b/src/hal/src/device.rs index 6d3f71bc95f..306db5f41dc 100644 --- a/src/hal/src/device.rs +++ b/src/hal/src/device.rs @@ -268,8 +268,10 @@ pub trait Device: Any + Send + Sync { fn destroy_pipeline_layout(&self, layout: B::PipelineLayout); /// Create a pipeline cache object. - //TODO: allow loading from disk - fn create_pipeline_cache(&self) -> Result; + fn create_pipeline_cache(&self, data: Option>, device: &B::PhysicalDevice) -> Result; + + /// Retrieve data from pipeline cache object. + fn get_pipeline_cache_data(&self, cache: &B::PipelineCache) -> Result, OutOfMemory>; /// Merge a number of source pipeline caches into the target one. fn merge_pipeline_caches(&self, target: &B::PipelineCache, sources: I) -> Result<(), OutOfMemory>