Implement extension chaining

This commit is contained in:
Maik Klein 2019-02-03 12:48:05 +01:00
parent 681eec54ec
commit 6d72bb547d
3 changed files with 2382 additions and 121 deletions

File diff suppressed because it is too large Load diff

View file

@ -341,7 +341,7 @@ impl ExampleBase {
.application_version(0)
.engine_name(&app_name)
.engine_version(0)
.api_version(vk_make_version!(1, 0, 36));
.api_version(vk_make_version!(1, 0, 0));
let create_info = vk::InstanceCreateInfo::builder()
.application_info(&appinfo)
@ -407,14 +407,40 @@ impl ExampleBase {
.queue_priorities(&priorities)
.build()];
let device_create_info = vk::DeviceCreateInfo::builder()
let mut variable_pointers =
vk::PhysicalDeviceVariablePointerFeatures::builder().variable_pointers(true);
let mut corner = vk::PhysicalDeviceCornerSampledImageFeaturesNV::builder()
.corner_sampled_image(true);
let mut device_create_info = vk::DeviceCreateInfo::builder()
.next(&mut corner)
.next(&mut variable_pointers)
.queue_create_infos(&queue_info)
.enabled_extension_names(&device_extension_names_raw)
.enabled_features(&features);
.enabled_features(&features)
.build();
let mut chain =
vk::ExtensionChain::from_ptr(&mut device_create_info as *mut _ as *mut _);
println!("{}", (*chain).s_type);
println!("{:?}", (*chain).p_next);
unsafe {
loop {
chain = vk::ExtensionChain::from_ptr((*chain).p_next as *mut _);
println!("{}", (*chain).s_type);
println!("{:?}", (*chain).p_next);
if (*chain).p_next.is_null() {
break;
}
}
}
use std::ops::Deref;
println!("--");
println!("{:?}", corner.deref() as *const _);
println!("{:?}", variable_pointers.deref() as *const _);
let device: Device = instance
.create_device(pdevice, &device_create_info, None)
.unwrap();
let present_queue = device.get_device_queue(queue_family_index as u32, 0);
let surface_formats = surface_loader

View file

@ -1595,19 +1595,14 @@ pub fn derive_setters(_struct: &vkxml::Struct) -> Option<Tokens> {
}
let next_function = if has_next {
if is_next_const {
quote! {
pub fn next<T>(mut self, next: &'a T) -> #name_builder<'a> where T: #extends_name {
self.inner.p_next = next as *const T as *const c_void;
self
}
}
} else {
quote! {
pub fn next<T>(mut self, next: &'a mut T) -> #name_builder<'a> where T: #extends_name {
self.inner.p_next = next as *mut T as *mut c_void;
self
quote! {
pub fn next<T: #extends_name>(mut self, next: &'a mut impl ::std::ops::DerefMut<Target = T>) -> #name_builder<'a> {
unsafe{
let ptr = &mut self.inner as *mut _ as *mut c_void;
let last_extension = ExtensionChain::last_chain(ptr);
(*last_extension).p_next = next.deref_mut() as *mut T as *mut c_void;
}
self
}
}
} else {
@ -1639,6 +1634,7 @@ pub fn derive_setters(_struct: &vkxml::Struct) -> Option<Tokens> {
#next_trait
#(#nexts)*
impl<'a> ::std::ops::Deref for #name_builder<'a> {
@ -1648,6 +1644,11 @@ pub fn derive_setters(_struct: &vkxml::Struct) -> Option<Tokens> {
&self.inner
}
}
impl<'a> ::std::ops::DerefMut for #name_builder<'a> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.inner
}
}
impl<'a> #name_builder<'a> {
#(#setters)*
@ -2145,6 +2146,32 @@ pub fn write_source_code(path: &Path) {
use std::fmt;
use std::os::raw::*;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct ExtensionChain {
pub s_type: StructureType,
pub p_next: *mut c_void
}
impl ExtensionChain {
pub unsafe fn from_ptr(ptr: *mut c_void) -> *mut Self {
::std::mem::transmute(ptr)
}
pub unsafe fn last_chain(ptr: *mut c_void) -> *mut Self {
assert!(!ptr.is_null());
let mut extension = ExtensionChain::from_ptr(ptr);
while !(*extension).p_next.is_null() {
extension = ExtensionChain::from_ptr((*extension).p_next);
}
extension
}
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct ExtensionChainMut {
pub s_type: StructureType,
pub p_next: *mut c_void
}
pub trait Handle {
const TYPE: ObjectType;
fn as_raw(self) -> u64;