pub trait DeviceInfo: Send + Sync {
type HooksType: DeviceHooks;
type HooksRefType<'a>: Deref<Target = Self::HooksType> + 'a
where Self: 'a;
// Required methods
fn hooked_commands() -> &'static [VulkanCommand];
fn hooks(&self) -> Self::HooksRefType<'_>;
}Expand description
A trait for the layer implementation to provide metadata of DeviceHooks for the layer
framework.
This trait serves as the container of the DeviceHooks type and provides the list of
intercepted
Vulkan device functions
for the layer framework. This trait and DeviceHooks can be implemented by the same type.
This trait can also be automatically implemented with the help of the
auto_deviceinfo_impl attribute macro.
§Examples
A layer that needs to intercept the vkCreateImage function.
struct MyLayerDeviceInfo;
impl DeviceHooks for MyLayerDeviceInfo {
fn create_image(
&self,
_p_create_info: &vk::ImageCreateInfo,
_p_allocator: Option<&vk::AllocationCallbacks>,
) -> LayerResult<VkResult<vk::Image>> {
LayerResult::Unhandled
}
}
impl DeviceInfo for MyLayerDeviceInfo {
type HooksType = Self;
type HooksRefType<'a> = &'a Self;
fn hooked_commands() -> &'static [VulkanCommand] {
&[VulkanCommand::CreateImage]
}
fn hooks(&self) -> Self::HooksRefType<'_> {
self
}
}Required Associated Types§
Sourcetype HooksType: DeviceHooks
type HooksType: DeviceHooks
The underlying DeviceHooks type that implements the core logic to intercept
Vulkan device functions.
If a type implements both this trait and the DeviceHooks trait simultaneously,
DeviceInfo::HooksType can be set to Self.
Sourcetype HooksRefType<'a>: Deref<Target = Self::HooksType> + 'a
where
Self: 'a
type HooksRefType<'a>: Deref<Target = Self::HooksType> + 'a where Self: 'a
A type that can be dereferencing to DeviceInfo::HooksType. Usually just
&DeviceInfo::HooksType.
This extra associated type allows the layer implementation to use a smart pointer like
Arc or MutexGuard to hold the reference.
§Examples
A layer implementation that returns a Arc.
struct MyLayerDeviceInfo(Arc<MyLayerDeviceHooks>);
impl DeviceInfo for MyLayerDeviceInfo {
type HooksType = MyLayerDeviceHooks;
type HooksRefType<'a> = Arc<MyLayerDeviceHooks>;
// Other required methods omitted.
fn hooks(&self) -> Self::HooksRefType<'_> {
Arc::clone(&self.0)
}
}Required Methods§
Sourcefn hooked_commands() -> &'static [VulkanCommand]
fn hooked_commands() -> &'static [VulkanCommand]
Returns a slice of Vulkan device functions that the layer implementation needs to intercept.
This function should normally return the methods implemented by the associated
DeviceHooks type. If the layer implementation needs to decide the functions to intercept
dynamically at runtime, use the Layer::hooked_device_commands method to override the
list of intercepted device functions.
Avoid returning commands other than Vulkan device functions. Otherwise, those commands may or may not be intercepted.
For Vulkan commands that have multiple names, e.g. vkCreateSamplerYcbcrConversion and
vkCreateSamplerYcbcrConversionKHR, only the shortest name should be
used(VulkanCommand::CreateSamplerYcbcrConversion in this example). The layer framework
automatically wires both entries to the layer implementation.
§Examples
A layer that intercepts the vkCreateImage only if the ASTC LDR feature is enabled.
use ash::{self, prelude::VkResult, vk};
use once_cell::sync::Lazy;
use std::sync::Arc;
use vulkan_layer::{
DeviceHooks, DeviceInfo, Global, Layer, LayerManifest, LayerResult,
LayerVulkanCommand as VulkanCommand, StubGlobalHooks, StubInstanceInfo,
VulkanBaseInStructChain,
};
struct MyLayerDeviceInfo {
is_astc_enabled: bool,
}
impl DeviceHooks for MyLayerDeviceInfo {
fn create_image(
&self,
create_info: &vk::ImageCreateInfo,
_p_allocator: Option<&vk::AllocationCallbacks>,
) -> LayerResult<VkResult<vk::Image>> {
if create_info.format == vk::Format::ASTC_4X4_UNORM_BLOCK {
println!("ASTC 4x4 UNORM image created.");
}
LayerResult::Unhandled
}
}
impl DeviceInfo for MyLayerDeviceInfo {
type HooksType = Self;
type HooksRefType<'a> = &'a Self;
fn hooked_commands() -> &'static [VulkanCommand] {
&[VulkanCommand::CreateImage]
}
fn hooks(&self) -> Self::HooksRefType<'_> {
self
}
}
#[derive(Default)]
struct MyLayer(StubGlobalHooks);
impl Layer for MyLayer {
// ...
type DeviceInfo = MyLayerDeviceInfo;
type DeviceInfoContainer = MyLayerDeviceInfo;
fn create_device_info(
&self,
_: vk::PhysicalDevice,
create_info: &vk::DeviceCreateInfo,
_: Option<&vk::AllocationCallbacks>,
_: Arc<ash::Device>,
_next_get_device_proc_addr: vk::PFN_vkGetDeviceProcAddr,
) -> Self::DeviceInfoContainer {
let mut p_next_chain: VulkanBaseInStructChain =
unsafe { (create_info.p_next as *const vk::BaseInStructure).as_ref() }.into();
let is_astc_enabled = p_next_chain
.find_map(|p_next| {
let p_next = p_next as *const vk::BaseInStructure;
unsafe {
ash::match_in_struct!(match p_next {
features2 @ vk::PhysicalDeviceFeatures2 => {
Some(&features2.features)
}
_ => {
None
}
})
}
})
.or_else(|| unsafe { create_info.p_enabled_features.as_ref() })
.map(|features| features.texture_compression_astc_ldr == vk::TRUE)
.unwrap_or(false);
MyLayerDeviceInfo { is_astc_enabled }
}
fn hooked_device_commands(
&self,
_instance_info: &Self::InstanceInfo,
device_info: Option<&Self::DeviceInfo>,
) -> Box<dyn Iterator<Item = VulkanCommand>> {
let should_hook_create_image = device_info
.map(|device_info| device_info.is_astc_enabled)
// Always hook the vkCreateImage function in the function pointers returned by
// vkGetInstanceProcAddr: we don't know if the to-be-created VkDevice will be
// created with the ASTC feature enabled.
.unwrap_or(true);
Box::new(
Self::DeviceInfo::hooked_commands()
.iter()
.cloned()
.filter(move |command| match command {
VulkanCommand::CreateImage => should_hook_create_image,
_ => true,
}),
)
}
}Sourcefn hooks(&self) -> Self::HooksRefType<'_>
fn hooks(&self) -> Self::HooksRefType<'_>
Returns the reference of the DeviceInfo::HooksType.
The layer framework uses the returned value to call into the layer implementation of intercepted commands.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
Implementors§
Source§impl DeviceInfo for StubDeviceInfo
impl DeviceInfo for StubDeviceInfo
type HooksType = StubDeviceInfo
type HooksRefType<'a> = &'a StubDeviceInfo
Source§impl<T: TestLayerMock> DeviceInfo for MockDeviceInfo<T>
Available on crate feature _test only.
impl<T: TestLayerMock> DeviceInfo for MockDeviceInfo<T>
_test only.