Skip to content

Commit

Permalink
extensions/khr: Add video encode/decode queue extensions
Browse files Browse the repository at this point in the history
This adds the following extensions:

 - VK_KHR_video_queue
 - VK_KHR_video_encode_queue
 - VK_KHR_video_decode_queue
  • Loading branch information
colinmarc committed Dec 2, 2024
1 parent 0b5b1a4 commit a3f2c4d
Show file tree
Hide file tree
Showing 7 changed files with 363 additions and 2 deletions.
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 and instance 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)
}
}
84 changes: 84 additions & 0 deletions ash/src/extensions/khr/video_encode_queue.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
//! <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_KHR_video_encode_queue.html>

use core::mem;
use core::ptr;

use crate::prelude::*;
use crate::vk;
use crate::RawMutPtr;

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)
}

/// Retrieves the length of the byte slice to pass to [`get_encoded_video_session_parameters`][Self::get_encoded_video_session_parameters].
pub unsafe fn get_encoded_video_session_parameters_len(
&self,
as_raw_mut_ptr: &vk::VideoEncodeSessionParametersGetInfoKHR<'_>,
feedback_info: Option<&mut vk::VideoEncodeSessionParametersFeedbackInfoKHR<'_>>,
) -> VkResult<usize> {
let mut len = mem::MaybeUninit::uninit();
(self.fp.get_encoded_video_session_parameters_khr)(
self.handle,
as_raw_mut_ptr,
feedback_info.as_raw_mut_ptr(),
len.as_mut_ptr(),
ptr::null_mut(),
)
.assume_init_on_success(len)
}

/// <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] to determine the correct length of the output slice.
#[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 [u8],
) -> VkResult<()> {
let mut len = out.len();
(self.fp.get_encoded_video_session_parameters_khr)(
self.handle,
session_parameters_info,
feedback_info.as_raw_mut_ptr(),
&mut len,
out.as_mut_ptr() as _,
)
.result()?;

assert_eq!(len, 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()
}
}
244 changes: 244 additions & 0 deletions ash/src/extensions/khr/video_queue.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,244 @@
//! <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<'_>,
) {
(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 format_count = out.len() as u32;
(self.fp.get_physical_device_video_format_properties_khr)(
physical_device,
video_format_info,
&mut format_count,
out.as_mut_ptr(),
)
.result()?;

assert_eq!(format_count as usize, out.len());
Ok(())
}
}
13 changes: 13 additions & 0 deletions ash/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,19 @@ impl<'r, T> RawPtr<T> for Option<&'r T> {
}
}

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 {
match self {
Some(val) => val,
None => core::ptr::null_mut(),
}
}
}

/// Given a mutable raw pointer to a type with an `s_type` member such as [`vk::BaseOutStructure`],
/// match on a set of Vulkan structures. The struct will be rebound to the given variable of the
/// type of the given Vulkan structure.
Expand Down
Loading

0 comments on commit a3f2c4d

Please sign in to comment.