Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add wrappers for VK_KHR_video{,_encode,_decode}_queue #965

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added `VK_KHR_get_display_properties2` instance extension (#932)
- Added `VK_EXT_metal_objects` device extension (#942)
- Added `VK_AMD_anti_lag` device extension (#943)
- Added `VK_KHR_video_queue`, `VK_KHR_video_encode_queue`, and `VK_KHR_video_decode_queue` device extensions (#965)

## [0.38.0] - 2024-04-01

Expand Down
3 changes: 3 additions & 0 deletions ash/src/extensions/khr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ pub mod surface;
pub mod swapchain;
pub mod synchronization2;
pub mod timeline_semaphore;
pub mod video_decode_queue;
pub mod video_encode_queue;
pub mod video_queue;
pub mod wayland_surface;
pub mod win32_surface;
pub mod xcb_surface;
Expand Down
16 changes: 16 additions & 0 deletions ash/src/extensions/khr/video_decode_queue.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//! <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_KHR_video_decode_queue.html>

use crate::vk;

impl crate::khr::video_decode_queue::Device {
/// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkCmdDecodeVideoKHR.html>
#[inline]
#[doc(alias = "vkCmdDecodeVideoKHR")]
pub unsafe fn cmd_decode_video(
&self,
command_buffer: vk::CommandBuffer,
decode_info: &vk::VideoDecodeInfoKHR<'_>,
) {
(self.fp.cmd_decode_video_khr)(command_buffer, decode_info)
}
}
83 changes: 83 additions & 0 deletions ash/src/extensions/khr/video_encode_queue.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
//! <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_KHR_video_encode_queue.html>

use crate::prelude::*;
use crate::vk;
use crate::RawMutPtr;
use core::mem;
use core::ptr;

impl crate::khr::video_encode_queue::Device {
/// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkCmdEncodeVideoKHR.html>
#[inline]
#[doc(alias = "vkCmdEncodeVideoKHR")]
pub unsafe fn cmd_encode_video(
&self,
command_buffer: vk::CommandBuffer,
encode_info: &vk::VideoEncodeInfoKHR<'_>,
) {
(self.fp.cmd_encode_video_khr)(command_buffer, encode_info)
}

/// Retrieve the length of the byte slice to pass to [`get_encoded_video_session_parameters()`][Self::get_encoded_video_session_parameters()].
#[inline]
pub unsafe fn get_encoded_video_session_parameters_len(
MarijnS95 marked this conversation as resolved.
Show resolved Hide resolved
&self,
session_parameters_info: &vk::VideoEncodeSessionParametersGetInfoKHR<'_>,
feedback_info: Option<&mut vk::VideoEncodeSessionParametersFeedbackInfoKHR<'_>>,
) -> VkResult<usize> {
let mut size = mem::MaybeUninit::uninit();
(self.fp.get_encoded_video_session_parameters_khr)(
self.handle,
session_parameters_info,
feedback_info.as_raw_mut_ptr(),
size.as_mut_ptr(),
ptr::null_mut(),
)
.assume_init_on_success(size)
}

/// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkGetEncodedVideoSessionParametersKHR.html>
///
/// Call [`get_encoded_video_session_parameters_len()`][Self::get_encoded_video_session_parameters_len()] to query the length of the byte slice to pass to `out`.
#[inline]
#[doc(alias = "vkGetEncodedVideoSessionParametersKHR")]
pub unsafe fn get_encoded_video_session_parameters(
&self,
session_parameters_info: &vk::VideoEncodeSessionParametersGetInfoKHR<'_>,
feedback_info: Option<&mut vk::VideoEncodeSessionParametersFeedbackInfoKHR<'_>>,
out: &mut [mem::MaybeUninit<u8>],
) -> VkResult<()> {
let mut size = out.len();
(self.fp.get_encoded_video_session_parameters_khr)(
self.handle,
session_parameters_info,
feedback_info.as_raw_mut_ptr(),
&mut size,
out.as_mut_ptr() as _,
)
.result()?;
assert_eq!(size, out.len());
Ok(())
}
}

impl crate::khr::video_encode_queue::Instance {
/// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkGetPhysicalDeviceVideoEncodeQualityLevelPropertiesKHR.html>
#[inline]
#[doc(alias = "vkGetPhysicalDeviceVideoEncodeQualityLevelPropertiesKHR")]
pub unsafe fn get_physical_device_video_encode_quality_level_properties(
&self,
physical_device: vk::PhysicalDevice,
quality_level_info: &vk::PhysicalDeviceVideoEncodeQualityLevelInfoKHR<'_>,
quality_level_properties: &mut vk::VideoEncodeQualityLevelPropertiesKHR<'_>,
) -> VkResult<()> {
(self
.fp
.get_physical_device_video_encode_quality_level_properties_khr)(
physical_device,
quality_level_info,
quality_level_properties,
)
.result()
}
}
242 changes: 242 additions & 0 deletions ash/src/extensions/khr/video_queue.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,242 @@
//! <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_KHR_video_queue.html>

use crate::prelude::*;
use crate::vk;
use crate::RawPtr;
use core::mem;
use core::ptr;

impl crate::khr::video_queue::Device {
/// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkBindVideoSessionMemoryKHR.html>
#[inline]
#[doc(alias = "vkBindVideoSessionMemoryKHR")]
pub unsafe fn bind_video_session_memory(
&self,
video_session: vk::VideoSessionKHR,
bind_session_memory_infos: &[vk::BindVideoSessionMemoryInfoKHR<'_>],
) -> VkResult<()> {
(self.fp.bind_video_session_memory_khr)(
self.handle,
video_session,
bind_session_memory_infos.len() as u32,
bind_session_memory_infos.as_ptr(),
)
.result()
}

/// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkCmdBeginVideoCodingKHR.html>
#[inline]
#[doc(alias = "vkCmdBeginVideoCodingKHR")]
pub unsafe fn cmd_begin_video_coding(
&self,
command_buffer: vk::CommandBuffer,
begin_info: &vk::VideoBeginCodingInfoKHR<'_>,
MarijnS95 marked this conversation as resolved.
Show resolved Hide resolved
) {
(self.fp.cmd_begin_video_coding_khr)(command_buffer, begin_info)
}

/// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkCmdControlVideoCodingKHR.html>
#[inline]
#[doc(alias = "vkCmdControlVideoCodingKHR")]
pub unsafe fn cmd_control_video_coding(
&self,
command_buffer: vk::CommandBuffer,
coding_control_info: &vk::VideoCodingControlInfoKHR<'_>,
) {
(self.fp.cmd_control_video_coding_khr)(command_buffer, coding_control_info)
}

/// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkCmdEndVideoCodingKHR.html>
#[inline]
#[doc(alias = "vkCmdEndVideoCodingKHR")]
pub unsafe fn cmd_end_video_coding(
&self,
command_buffer: vk::CommandBuffer,
end_coding_info: &vk::VideoEndCodingInfoKHR<'_>,
) {
(self.fp.cmd_end_video_coding_khr)(command_buffer, end_coding_info)
}

/// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkCreateVideoSessionKHR.html>
#[inline]
#[doc(alias = "vkCreateVideoSessionKHR")]
pub unsafe fn create_video_session(
&self,
create_info: &vk::VideoSessionCreateInfoKHR<'_>,
allocation_callbacks: Option<&vk::AllocationCallbacks<'_>>,
) -> VkResult<vk::VideoSessionKHR> {
let mut video_session = mem::MaybeUninit::uninit();
(self.fp.create_video_session_khr)(
self.handle,
create_info,
allocation_callbacks.as_raw_ptr(),
video_session.as_mut_ptr(),
)
.assume_init_on_success(video_session)
}

/// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkCreateVideoSessionParametersKHR.html>
#[inline]
#[doc(alias = "vkCreateVideoSessionParametersKHR")]
pub unsafe fn create_video_session_parameters(
&self,
create_info: &vk::VideoSessionParametersCreateInfoKHR<'_>,
allocation_callbacks: Option<&vk::AllocationCallbacks<'_>>,
) -> VkResult<vk::VideoSessionParametersKHR> {
let mut video_session_parameters = mem::MaybeUninit::uninit();
(self.fp.create_video_session_parameters_khr)(
self.handle,
create_info,
allocation_callbacks.as_raw_ptr(),
video_session_parameters.as_mut_ptr(),
)
.assume_init_on_success(video_session_parameters)
}

/// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkDestroyVideoSessionKHR.html>
#[inline]
#[doc(alias = "vkDestroyVideoSessionKHR")]
pub unsafe fn destroy_video_session(
&self,
video_session: vk::VideoSessionKHR,
allocation_callbacks: Option<&vk::AllocationCallbacks<'_>>,
) {
(self.fp.destroy_video_session_khr)(
self.handle,
video_session,
allocation_callbacks.as_raw_ptr(),
)
}

/// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkDestroyVideoSessionParametersKHR.html>
#[inline]
#[doc(alias = "vkDestroyVideoSessionParametersKHR")]
pub unsafe fn destroy_video_session_parameters(
&self,
video_session_parameters: vk::VideoSessionParametersKHR,
allocation_callbacks: Option<&vk::AllocationCallbacks<'_>>,
) {
(self.fp.destroy_video_session_parameters_khr)(
self.handle,
video_session_parameters,
allocation_callbacks.as_raw_ptr(),
)
}

/// Retrieve the number of elements to pass to [`get_video_session_memory_requirements()`][Self::get_video_session_memory_requirements()].
#[inline]
pub unsafe fn get_video_session_memory_requirements_len(
&self,
video_session: vk::VideoSessionKHR,
) -> VkResult<usize> {
let mut count = mem::MaybeUninit::uninit();
(self.fp.get_video_session_memory_requirements_khr)(
self.handle,
video_session,
count.as_mut_ptr(),
ptr::null_mut(),
)
.assume_init_on_success(count)
.map(|c| c as usize)
}

/// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkGetVideoSessionMemoryRequirementsKHR.html>
///
/// Call [`get_video_session_memory_requirements_len()`][Self::get_video_session_memory_requirements_len()] to query the number of elements to pass to `out`.
/// Be sure to [`Default::default()`]-initialize these elements and optionally set their `p_next` pointer.
#[inline]
#[doc(alias = "vkGetVideoSessionMemoryRequirementsKHR")]
pub unsafe fn get_video_session_memory_requirements(
&self,
video_session: vk::VideoSessionKHR,
out: &mut [vk::VideoSessionMemoryRequirementsKHR<'_>],
) -> VkResult<()> {
let mut count = out.len() as u32;
(self.fp.get_video_session_memory_requirements_khr)(
self.handle,
video_session,
&mut count,
out.as_mut_ptr(),
)
.result()?;
assert_eq!(count as usize, out.len());
Ok(())
}

/// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkUpdateVideoSessionParametersKHR.html>
#[inline]
#[doc(alias = "vkUpdateVideoSessionParametersKHR")]
pub unsafe fn update_video_session_parameters(
&self,
video_session_parameters: vk::VideoSessionParametersKHR,
update_info: &vk::VideoSessionParametersUpdateInfoKHR<'_>,
) -> VkResult<()> {
(self.fp.update_video_session_parameters_khr)(
self.handle,
video_session_parameters,
update_info,
)
.result()
}
}

impl crate::khr::video_queue::Instance {
/// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkGetPhysicalDeviceVideoCapabilitiesKHR.html>
#[inline]
#[doc(alias = "vkGetPhysicalDeviceVideoCapabilitiesKHR")]
pub unsafe fn get_physical_device_video_capabilities(
&self,
physical_device: vk::PhysicalDevice,
video_profile: &vk::VideoProfileInfoKHR<'_>,
capabilities: &mut vk::VideoCapabilitiesKHR<'_>,
) -> VkResult<()> {
(self.fp.get_physical_device_video_capabilities_khr)(
physical_device,
video_profile,
capabilities,
)
.result()
}

/// Retrieve the number of elements to pass to [`get_physical_device_video_format_properties()`][Self::get_physical_device_video_format_properties()].
#[inline]
pub unsafe fn get_physical_device_video_format_properties_len(
&self,
physical_device: vk::PhysicalDevice,
video_format_info: &vk::PhysicalDeviceVideoFormatInfoKHR<'_>,
) -> VkResult<usize> {
let mut count = mem::MaybeUninit::uninit();
(self.fp.get_physical_device_video_format_properties_khr)(
physical_device,
video_format_info,
count.as_mut_ptr(),
ptr::null_mut(),
)
.assume_init_on_success(count)
.map(|c| c as usize)
}

/// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkGetPhysicalDeviceVideoFormatPropertiesKHR.html>
///
/// Call [`get_physical_device_video_format_properties_len()`][Self::get_physical_device_video_format_properties_len()] to query the number of elements to pass to `out`.
/// Be sure to [`Default::default()`]-initialize these elements and optionally set their `p_next` pointer.
#[inline]
#[doc(alias = "vkGetPhysicalDeviceVideoFormatPropertiesKHR")]
pub unsafe fn get_physical_device_video_format_properties(
&self,
physical_device: vk::PhysicalDevice,
video_format_info: &vk::PhysicalDeviceVideoFormatInfoKHR<'_>,
out: &mut [vk::VideoFormatPropertiesKHR<'_>],
) -> VkResult<()> {
let mut count = out.len() as u32;
(self.fp.get_physical_device_video_format_properties_khr)(
physical_device,
video_format_info,
&mut count,
out.as_mut_ptr(),
)
.result()?;
assert_eq!(count as usize, out.len());
Ok(())
}
}
15 changes: 14 additions & 1 deletion ash/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,20 @@ impl<'r, T> RawPtr<T> for Option<&'r T> {
fn as_raw_ptr(&self) -> *const T {
match *self {
Some(inner) => inner,
_ => ::core::ptr::null(),
None => core::ptr::null(),
}
}
}

pub trait RawMutPtr<T> {
unsafe fn as_raw_mut_ptr(self) -> *mut T;
}

impl<'r, T> RawMutPtr<T> for Option<&'r mut T> {
unsafe fn as_raw_mut_ptr(self) -> *mut T {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just want to call out that this doesn't work if you don't consume self, because &mut T is not Copy (that would be aliasing). However, that makes this slightly inconsistent with regards to RawPtr (just above).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if trait RawPtr should take self by value too, given that Option<&T> is Copy (and we don't have &Option<&T>).

Locally this violates clippy::wrong_self_convention though.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yeah, I missed that lint. I could change both to to_... or just do RawMutPtr::to_raw_mut_ptr and leave RawPtr as it is.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since both are private helpers, I'm not opposed to unifying both into a to_.

match self {
Some(inner) => inner,
None => core::ptr::null_mut(),
MarijnS95 marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
Expand Down
Loading