From 5287371195d6b57e32b77f467ffcad745724a1b2 Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Mon, 29 May 2023 11:04:51 +0200 Subject: [PATCH] Update Vulkan-Headers to 1.3.251 (#741) * Update Vulkan-Headers to 1.3.247 * Update Vulkan-Headers to 1.3.248 * Update Vulkan-Headers to 1.3.249 * Update Vulkan-Headers to 1.3.250 * Update Vulkan-Headers to 1.3.251 --- Changelog.md | 2 +- ash/Cargo.toml | 2 +- ash/src/vk/bitflags.rs | 6 -- ash/src/vk/const_debugs.rs | 16 ++++ ash/src/vk/definitions.rs | 150 +++++++++++++++++++++++++++++++++++-- ash/src/vk/extensions.rs | 99 +++++++++++++++++++++++- generator/Vulkan-Headers | 2 +- 7 files changed, 259 insertions(+), 18 deletions(-) diff --git a/Changelog.md b/Changelog.md index a95074f..0fc71b7 100644 --- a/Changelog.md +++ b/Changelog.md @@ -11,7 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added `VK_EXT_pipeline_properties` device extension (#622) - Added `Handle::is_null()` to allow checking if a handle is a `NULL` value (#694) -- Update Vulkan-Headers to 1.3.246 (#697, #723) +- Update Vulkan-Headers to 1.3.251 (#697, #723, #741) - Added `VK_KHR_performance_query` device extension (#726) - Added `VK_EXT_shader_object` device extension (#732) - Added missing `Device::get_device_queue2()` wrapper (#736) diff --git a/ash/Cargo.toml b/ash/Cargo.toml index 7fa31ab..504fa36 100644 --- a/ash/Cargo.toml +++ b/ash/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ash" -version = "0.37.0+1.3.246" +version = "0.37.0+1.3.251" authors = [ "Maik Klein ", "Benjamin Saunders ", diff --git a/ash/src/vk/bitflags.rs b/ash/src/vk/bitflags.rs index 1189e1e..b3a5af9 100644 --- a/ash/src/vk/bitflags.rs +++ b/ash/src/vk/bitflags.rs @@ -1620,10 +1620,4 @@ pub struct ShaderCreateFlagsEXT(pub(crate) Flags); vk_bitflags_wrapped!(ShaderCreateFlagsEXT, Flags); impl ShaderCreateFlagsEXT { pub const LINK_STAGE: Self = Self(0b1); - pub const ALLOW_VARYING_SUBGROUP_SIZE: Self = Self(0b10); - pub const REQUIRE_FULL_SUBGROUPS: Self = Self(0b100); - pub const NO_TASK_SHADER: Self = Self(0b1000); - pub const DISPATCH_BASE: Self = Self(0b1_0000); - pub const FRAGMENT_SHADING_RATE_ATTACHMENT: Self = Self(0b10_0000); - pub const FRAGMENT_DENSITY_MAP_ATTACHMENT: Self = Self(0b100_0000); } diff --git a/ash/src/vk/const_debugs.rs b/ash/src/vk/const_debugs.rs index 81290c7..6e108f0 100644 --- a/ash/src/vk/const_debugs.rs +++ b/ash/src/vk/const_debugs.rs @@ -655,6 +655,10 @@ impl fmt::Debug for BuildAccelerationStructureFlagsKHR { BuildAccelerationStructureFlagsKHR::ALLOW_DISPLACEMENT_MICROMAP_UPDATE_NV.0, "ALLOW_DISPLACEMENT_MICROMAP_UPDATE_NV", ), + ( + BuildAccelerationStructureFlagsKHR::ALLOW_DATA_ACCESS.0, + "ALLOW_DATA_ACCESS", + ), ]; debug_flags(f, KNOWN, self.0) } @@ -1598,6 +1602,9 @@ impl fmt::Debug for DynamicState { Some("REPRESENTATIVE_FRAGMENT_TEST_ENABLE_NV") } Self::COVERAGE_REDUCTION_MODE_NV => Some("COVERAGE_REDUCTION_MODE_NV"), + Self::ATTACHMENT_FEEDBACK_LOOP_ENABLE_EXT => { + Some("ATTACHMENT_FEEDBACK_LOOP_ENABLE_EXT") + } Self::CULL_MODE => Some("CULL_MODE"), Self::FRONT_FACE => Some("FRONT_FACE"), Self::PRIMITIVE_TOPOLOGY => Some("PRIMITIVE_TOPOLOGY"), @@ -5867,6 +5874,9 @@ impl fmt::Debug for StructureType { Self::PHYSICAL_DEVICE_PIPELINE_PROTECTED_ACCESS_FEATURES_EXT => { Some("PHYSICAL_DEVICE_PIPELINE_PROTECTED_ACCESS_FEATURES_EXT") } + Self::PHYSICAL_DEVICE_RAY_TRACING_POSITION_FETCH_FEATURES_KHR => { + Some("PHYSICAL_DEVICE_RAY_TRACING_POSITION_FETCH_FEATURES_KHR") + } Self::PHYSICAL_DEVICE_SHADER_OBJECT_FEATURES_EXT => { Some("PHYSICAL_DEVICE_SHADER_OBJECT_FEATURES_EXT") } @@ -5906,12 +5916,18 @@ impl fmt::Debug for StructureType { Self::PHYSICAL_DEVICE_PIPELINE_LIBRARY_GROUP_HANDLES_FEATURES_EXT => { Some("PHYSICAL_DEVICE_PIPELINE_LIBRARY_GROUP_HANDLES_FEATURES_EXT") } + Self::PHYSICAL_DEVICE_DYNAMIC_RENDERING_UNUSED_ATTACHMENTS_FEATURES_EXT => { + Some("PHYSICAL_DEVICE_DYNAMIC_RENDERING_UNUSED_ATTACHMENTS_FEATURES_EXT") + } Self::PHYSICAL_DEVICE_MULTIVIEW_PER_VIEW_RENDER_AREAS_FEATURES_QCOM => { Some("PHYSICAL_DEVICE_MULTIVIEW_PER_VIEW_RENDER_AREAS_FEATURES_QCOM") } Self::MULTIVIEW_PER_VIEW_RENDER_AREAS_RENDER_PASS_BEGIN_INFO_QCOM => { Some("MULTIVIEW_PER_VIEW_RENDER_AREAS_RENDER_PASS_BEGIN_INFO_QCOM") } + Self::PHYSICAL_DEVICE_ATTACHMENT_FEEDBACK_LOOP_DYNAMIC_STATE_FEATURES_EXT => { + Some("PHYSICAL_DEVICE_ATTACHMENT_FEEDBACK_LOOP_DYNAMIC_STATE_FEATURES_EXT") + } Self::PHYSICAL_DEVICE_SUBGROUP_PROPERTIES => { Some("PHYSICAL_DEVICE_SUBGROUP_PROPERTIES") } diff --git a/ash/src/vk/definitions.rs b/ash/src/vk/definitions.rs index 568b994..08e6880 100644 --- a/ash/src/vk/definitions.rs +++ b/ash/src/vk/definitions.rs @@ -58,7 +58,7 @@ pub const API_VERSION_1_2: u32 = make_api_version(0, 1, 2, 0); #[doc = ""] pub const API_VERSION_1_3: u32 = make_api_version(0, 1, 3, 0); #[doc = ""] -pub const HEADER_VERSION: u32 = 246; +pub const HEADER_VERSION: u32 = 251; #[doc = ""] pub const HEADER_VERSION_COMPLETE: u32 = make_api_version(0, 1, 3, HEADER_VERSION); #[doc = ""] @@ -34658,6 +34658,51 @@ impl<'a> PhysicalDeviceImageSlicedViewOf3DFeaturesEXT<'a> { #[repr(C)] #[cfg_attr(feature = "debug", derive(Debug))] #[derive(Copy, Clone)] +#[doc = ""] +pub struct PhysicalDeviceAttachmentFeedbackLoopDynamicStateFeaturesEXT<'a> { + pub s_type: StructureType, + pub p_next: *mut c_void, + pub attachment_feedback_loop_dynamic_state: Bool32, + pub _marker: PhantomData<&'a ()>, +} +impl ::std::default::Default for PhysicalDeviceAttachmentFeedbackLoopDynamicStateFeaturesEXT<'_> { + #[inline] + fn default() -> Self { + Self { + s_type: Self::STRUCTURE_TYPE, + p_next: ::std::ptr::null_mut(), + attachment_feedback_loop_dynamic_state: Bool32::default(), + _marker: PhantomData, + } + } +} +unsafe impl<'a> TaggedStructure + for PhysicalDeviceAttachmentFeedbackLoopDynamicStateFeaturesEXT<'a> +{ + const STRUCTURE_TYPE: StructureType = + StructureType::PHYSICAL_DEVICE_ATTACHMENT_FEEDBACK_LOOP_DYNAMIC_STATE_FEATURES_EXT; +} +unsafe impl ExtendsPhysicalDeviceFeatures2 + for PhysicalDeviceAttachmentFeedbackLoopDynamicStateFeaturesEXT<'_> +{ +} +unsafe impl ExtendsDeviceCreateInfo + for PhysicalDeviceAttachmentFeedbackLoopDynamicStateFeaturesEXT<'_> +{ +} +impl<'a> PhysicalDeviceAttachmentFeedbackLoopDynamicStateFeaturesEXT<'a> { + #[inline] + pub fn attachment_feedback_loop_dynamic_state( + mut self, + attachment_feedback_loop_dynamic_state: bool, + ) -> Self { + self.attachment_feedback_loop_dynamic_state = attachment_feedback_loop_dynamic_state.into(); + self + } +} +#[repr(C)] +#[cfg_attr(feature = "debug", derive(Debug))] +#[derive(Copy, Clone)] #[doc = ""] pub struct PhysicalDeviceMutableDescriptorTypeFeaturesEXT<'a> { pub s_type: StructureType, @@ -37125,7 +37170,7 @@ impl<'a> VideoDecodeH265SessionParametersCreateInfoKHR<'a> { pub struct VideoDecodeH265PictureInfoKHR<'a> { pub s_type: StructureType, pub p_next: *const c_void, - pub p_std_picture_info: *mut StdVideoDecodeH265PictureInfo, + pub p_std_picture_info: *const StdVideoDecodeH265PictureInfo, pub slice_segment_count: u32, pub p_slice_segment_offsets: *const u32, pub _marker: PhantomData<&'a ()>, @@ -37136,7 +37181,7 @@ impl ::std::default::Default for VideoDecodeH265PictureInfoKHR<'_> { Self { s_type: Self::STRUCTURE_TYPE, p_next: ::std::ptr::null(), - p_std_picture_info: ::std::ptr::null_mut(), + p_std_picture_info: ::std::ptr::null(), slice_segment_count: u32::default(), p_slice_segment_offsets: ::std::ptr::null(), _marker: PhantomData, @@ -37149,10 +37194,7 @@ unsafe impl<'a> TaggedStructure for VideoDecodeH265PictureInfoKHR<'a> { unsafe impl ExtendsVideoDecodeInfoKHR for VideoDecodeH265PictureInfoKHR<'_> {} impl<'a> VideoDecodeH265PictureInfoKHR<'a> { #[inline] - pub fn std_picture_info( - mut self, - std_picture_info: &'a mut StdVideoDecodeH265PictureInfo, - ) -> Self { + pub fn std_picture_info(mut self, std_picture_info: &'a StdVideoDecodeH265PictureInfo) -> Self { self.p_std_picture_info = std_picture_info; self } @@ -46447,6 +46489,8 @@ pub struct DeviceFaultVendorBinaryHeaderVersionOneEXT { pub application_name_offset: u32, pub application_version: u32, pub engine_name_offset: u32, + pub engine_version: u32, + pub api_version: u32, } impl ::std::default::Default for DeviceFaultVendorBinaryHeaderVersionOneEXT { #[inline] @@ -46461,6 +46505,8 @@ impl ::std::default::Default for DeviceFaultVendorBinaryHeaderVersionOneEXT { application_name_offset: u32::default(), application_version: u32::default(), engine_name_offset: u32::default(), + engine_version: u32::default(), + api_version: u32::default(), } } } @@ -46513,6 +46559,16 @@ impl DeviceFaultVendorBinaryHeaderVersionOneEXT { self.engine_name_offset = engine_name_offset; self } + #[inline] + pub fn engine_version(mut self, engine_version: u32) -> Self { + self.engine_version = engine_version; + self + } + #[inline] + pub fn api_version(mut self, api_version: u32) -> Self { + self.api_version = api_version; + self + } } #[repr(C)] #[cfg_attr(feature = "debug", derive(Debug))] @@ -46676,6 +46732,49 @@ impl<'a> PhysicalDeviceShaderCoreBuiltinsFeaturesARM<'a> { #[repr(C)] #[cfg_attr(feature = "debug", derive(Debug))] #[derive(Copy, Clone)] +#[doc = ""] +pub struct PhysicalDeviceDynamicRenderingUnusedAttachmentsFeaturesEXT<'a> { + pub s_type: StructureType, + pub p_next: *mut c_void, + pub dynamic_rendering_unused_attachments: Bool32, + pub _marker: PhantomData<&'a ()>, +} +impl ::std::default::Default for PhysicalDeviceDynamicRenderingUnusedAttachmentsFeaturesEXT<'_> { + #[inline] + fn default() -> Self { + Self { + s_type: Self::STRUCTURE_TYPE, + p_next: ::std::ptr::null_mut(), + dynamic_rendering_unused_attachments: Bool32::default(), + _marker: PhantomData, + } + } +} +unsafe impl<'a> TaggedStructure for PhysicalDeviceDynamicRenderingUnusedAttachmentsFeaturesEXT<'a> { + const STRUCTURE_TYPE: StructureType = + StructureType::PHYSICAL_DEVICE_DYNAMIC_RENDERING_UNUSED_ATTACHMENTS_FEATURES_EXT; +} +unsafe impl ExtendsPhysicalDeviceFeatures2 + for PhysicalDeviceDynamicRenderingUnusedAttachmentsFeaturesEXT<'_> +{ +} +unsafe impl ExtendsDeviceCreateInfo + for PhysicalDeviceDynamicRenderingUnusedAttachmentsFeaturesEXT<'_> +{ +} +impl<'a> PhysicalDeviceDynamicRenderingUnusedAttachmentsFeaturesEXT<'a> { + #[inline] + pub fn dynamic_rendering_unused_attachments( + mut self, + dynamic_rendering_unused_attachments: bool, + ) -> Self { + self.dynamic_rendering_unused_attachments = dynamic_rendering_unused_attachments.into(); + self + } +} +#[repr(C)] +#[cfg_attr(feature = "debug", derive(Debug))] +#[derive(Copy, Clone)] #[doc = ""] pub struct SurfacePresentModeEXT<'a> { pub s_type: StructureType, @@ -47249,6 +47348,43 @@ impl<'a> PhysicalDeviceMultiviewPerViewViewportsFeaturesQCOM<'a> { #[repr(C)] #[cfg_attr(feature = "debug", derive(Debug))] #[derive(Copy, Clone)] +#[doc = ""] +pub struct PhysicalDeviceRayTracingPositionFetchFeaturesKHR<'a> { + pub s_type: StructureType, + pub p_next: *mut c_void, + pub ray_tracing_position_fetch: Bool32, + pub _marker: PhantomData<&'a ()>, +} +impl ::std::default::Default for PhysicalDeviceRayTracingPositionFetchFeaturesKHR<'_> { + #[inline] + fn default() -> Self { + Self { + s_type: Self::STRUCTURE_TYPE, + p_next: ::std::ptr::null_mut(), + ray_tracing_position_fetch: Bool32::default(), + _marker: PhantomData, + } + } +} +unsafe impl<'a> TaggedStructure for PhysicalDeviceRayTracingPositionFetchFeaturesKHR<'a> { + const STRUCTURE_TYPE: StructureType = + StructureType::PHYSICAL_DEVICE_RAY_TRACING_POSITION_FETCH_FEATURES_KHR; +} +unsafe impl ExtendsPhysicalDeviceFeatures2 + for PhysicalDeviceRayTracingPositionFetchFeaturesKHR<'_> +{ +} +unsafe impl ExtendsDeviceCreateInfo for PhysicalDeviceRayTracingPositionFetchFeaturesKHR<'_> {} +impl<'a> PhysicalDeviceRayTracingPositionFetchFeaturesKHR<'a> { + #[inline] + pub fn ray_tracing_position_fetch(mut self, ray_tracing_position_fetch: bool) -> Self { + self.ray_tracing_position_fetch = ray_tracing_position_fetch.into(); + self + } +} +#[repr(C)] +#[cfg_attr(feature = "debug", derive(Debug))] +#[derive(Copy, Clone)] #[doc = ""] pub struct PhysicalDeviceShaderCorePropertiesARM<'a> { pub s_type: StructureType, diff --git a/ash/src/vk/extensions.rs b/ash/src/vk/extensions.rs index 9bf3eb2..1772dd0 100644 --- a/ash/src/vk/extensions.rs +++ b/ash/src/vk/extensions.rs @@ -15108,7 +15108,7 @@ impl StructureType { impl ExtDeviceFaultFn { pub const NAME: &'static ::std::ffi::CStr = unsafe { ::std::ffi::CStr::from_bytes_with_nul_unchecked(b"VK_EXT_device_fault\0") }; - pub const SPEC_VERSION: u32 = 1u32; + pub const SPEC_VERSION: u32 = 2u32; } #[allow(non_camel_case_types)] pub type PFN_vkGetDeviceFaultInfoEXT = unsafe extern "system" fn( @@ -17182,7 +17182,7 @@ impl HuaweiClusterCullingShaderFn { pub const NAME: &'static ::std::ffi::CStr = unsafe { ::std::ffi::CStr::from_bytes_with_nul_unchecked(b"VK_HUAWEI_cluster_culling_shader\0") }; - pub const SPEC_VERSION: u32 = 1u32; + pub const SPEC_VERSION: u32 = 2u32; } #[allow(non_camel_case_types)] pub type PFN_vkCmdDrawClusterHUAWEI = unsafe extern "system" fn( @@ -19098,6 +19098,22 @@ impl PipelineCreateFlags { impl StructureType { pub const PHYSICAL_DEVICE_PIPELINE_PROTECTED_ACCESS_FEATURES_EXT: Self = Self(1_000_466_000); } +impl KhrRayTracingPositionFetchFn { + pub const NAME: &'static ::std::ffi::CStr = unsafe { + ::std::ffi::CStr::from_bytes_with_nul_unchecked(b"VK_KHR_ray_tracing_position_fetch\0") + }; + pub const SPEC_VERSION: u32 = 1u32; +} +#[derive(Clone)] +pub struct KhrRayTracingPositionFetchFn; +#[doc = "Generated from 'VK_KHR_ray_tracing_position_fetch'"] +impl BuildAccelerationStructureFlagsKHR { + pub const ALLOW_DATA_ACCESS: Self = Self(0b1000_0000_0000); +} +#[doc = "Generated from 'VK_KHR_ray_tracing_position_fetch'"] +impl StructureType { + pub const PHYSICAL_DEVICE_RAY_TRACING_POSITION_FETCH_FEATURES_KHR: Self = Self(1_000_481_000); +} impl ExtShaderObjectFn { pub const NAME: &'static ::std::ffi::CStr = unsafe { ::std::ffi::CStr::from_bytes_with_nul_unchecked(b"VK_EXT_shader_object\0") }; @@ -20279,6 +20295,15 @@ impl Result { pub const ERROR_INCOMPATIBLE_SHADER_BINARY_EXT: Self = Self(1_000_482_000); } #[doc = "Generated from 'VK_EXT_shader_object'"] +impl ShaderCreateFlagsEXT { + pub const ALLOW_VARYING_SUBGROUP_SIZE: Self = Self(0b10); + pub const REQUIRE_FULL_SUBGROUPS: Self = Self(0b100); + pub const NO_TASK_SHADER: Self = Self(0b1000); + pub const DISPATCH_BASE: Self = Self(0b1_0000); + pub const FRAGMENT_SHADING_RATE_ATTACHMENT: Self = Self(0b10_0000); + pub const FRAGMENT_DENSITY_MAP_ATTACHMENT: Self = Self(0b100_0000); +} +#[doc = "Generated from 'VK_EXT_shader_object'"] impl StructureType { pub const PHYSICAL_DEVICE_SHADER_OBJECT_FEATURES_EXT: Self = Self(1_000_482_000); pub const PHYSICAL_DEVICE_SHADER_OBJECT_PROPERTIES_EXT: Self = Self(1_000_482_001); @@ -20459,6 +20484,21 @@ impl StructureType { pub const PHYSICAL_DEVICE_PIPELINE_LIBRARY_GROUP_HANDLES_FEATURES_EXT: Self = Self(1_000_498_000); } +impl ExtDynamicRenderingUnusedAttachmentsFn { + pub const NAME: &'static ::std::ffi::CStr = unsafe { + ::std::ffi::CStr::from_bytes_with_nul_unchecked( + b"VK_EXT_dynamic_rendering_unused_attachments\0", + ) + }; + pub const SPEC_VERSION: u32 = 1u32; +} +#[derive(Clone)] +pub struct ExtDynamicRenderingUnusedAttachmentsFn; +#[doc = "Generated from 'VK_EXT_dynamic_rendering_unused_attachments'"] +impl StructureType { + pub const PHYSICAL_DEVICE_DYNAMIC_RENDERING_UNUSED_ATTACHMENTS_FEATURES_EXT: Self = + Self(1_000_499_000); +} impl QcomMultiviewPerViewRenderAreasFn { pub const NAME: &'static ::std::ffi::CStr = unsafe { ::std::ffi::CStr::from_bytes_with_nul_unchecked( @@ -20476,3 +20516,58 @@ impl StructureType { pub const MULTIVIEW_PER_VIEW_RENDER_AREAS_RENDER_PASS_BEGIN_INFO_QCOM: Self = Self(1_000_510_001); } +impl ExtAttachmentFeedbackLoopDynamicStateFn { + pub const NAME: &'static ::std::ffi::CStr = unsafe { + ::std::ffi::CStr::from_bytes_with_nul_unchecked( + b"VK_EXT_attachment_feedback_loop_dynamic_state\0", + ) + }; + pub const SPEC_VERSION: u32 = 1u32; +} +#[allow(non_camel_case_types)] +pub type PFN_vkCmdSetAttachmentFeedbackLoopEnableEXT = + unsafe extern "system" fn(command_buffer: CommandBuffer, aspect_mask: ImageAspectFlags); +#[derive(Clone)] +pub struct ExtAttachmentFeedbackLoopDynamicStateFn { + pub cmd_set_attachment_feedback_loop_enable_ext: PFN_vkCmdSetAttachmentFeedbackLoopEnableEXT, +} +unsafe impl Send for ExtAttachmentFeedbackLoopDynamicStateFn {} +unsafe impl Sync for ExtAttachmentFeedbackLoopDynamicStateFn {} +impl ExtAttachmentFeedbackLoopDynamicStateFn { + pub fn load(mut _f: F) -> Self + where + F: FnMut(&::std::ffi::CStr) -> *const c_void, + { + Self { + cmd_set_attachment_feedback_loop_enable_ext: unsafe { + unsafe extern "system" fn cmd_set_attachment_feedback_loop_enable_ext( + _command_buffer: CommandBuffer, + _aspect_mask: ImageAspectFlags, + ) { + panic!(concat!( + "Unable to load ", + stringify!(cmd_set_attachment_feedback_loop_enable_ext) + )) + } + let cname = ::std::ffi::CStr::from_bytes_with_nul_unchecked( + b"vkCmdSetAttachmentFeedbackLoopEnableEXT\0", + ); + let val = _f(cname); + if val.is_null() { + cmd_set_attachment_feedback_loop_enable_ext + } else { + ::std::mem::transmute(val) + } + }, + } + } +} +#[doc = "Generated from 'VK_EXT_attachment_feedback_loop_dynamic_state'"] +impl DynamicState { + pub const ATTACHMENT_FEEDBACK_LOOP_ENABLE_EXT: Self = Self(1_000_524_000); +} +#[doc = "Generated from 'VK_EXT_attachment_feedback_loop_dynamic_state'"] +impl StructureType { + pub const PHYSICAL_DEVICE_ATTACHMENT_FEEDBACK_LOOP_DYNAMIC_STATE_FEATURES_EXT: Self = + Self(1_000_524_000); +} diff --git a/generator/Vulkan-Headers b/generator/Vulkan-Headers index 63af1cf..3df77fb 160000 --- a/generator/Vulkan-Headers +++ b/generator/Vulkan-Headers @@ -1 +1 @@ -Subproject commit 63af1cf1ee906ba4dcd5a324bdd0201d4f4bfd12 +Subproject commit 3df77fb3e4e0961f7f01de9a9ae20dfdcfc4910a