Replace ExtensionChain with a simple iterator

This commit is contained in:
Maik Klein 2019-02-23 11:08:27 +01:00
parent 6d72bb547d
commit c46a41e1d2
2 changed files with 27 additions and 48 deletions

View file

@ -4,7 +4,6 @@ extern crate ash;
extern crate winapi;
extern crate winit;
#[cfg(target_os = "macos")]
extern crate cocoa;
#[cfg(target_os = "macos")]
@ -408,9 +407,9 @@ impl ExampleBase {
.build()];
let mut variable_pointers =
vk::PhysicalDeviceVariablePointerFeatures::builder().variable_pointers(true);
vk::PhysicalDeviceVariablePointerFeatures::builder().variable_pointers(true).build();
let mut corner = vk::PhysicalDeviceCornerSampledImageFeaturesNV::builder()
.corner_sampled_image(true);
.corner_sampled_image(true).build();
let mut device_create_info = vk::DeviceCreateInfo::builder()
.next(&mut corner)
.next(&mut variable_pointers)
@ -419,24 +418,12 @@ impl ExampleBase {
.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;
}
}
for ptr in vk::ptr_chain_iter(&mut device_create_info){
println!("{:?}", ptr);
}
use std::ops::Deref;
println!("--");
println!("{:?}", corner.deref() as *const _);
println!("{:?}", variable_pointers.deref() as *const _);
println!("{:?}", &corner as *const _);
println!("{:?}", &variable_pointers as *const _);
let device: Device = instance
.create_device(pdevice, &device_create_info, None)
.unwrap();

View file

@ -1596,11 +1596,13 @@ pub fn derive_setters(_struct: &vkxml::Struct) -> Option<Tokens> {
let next_function = if has_next {
quote! {
pub fn next<T: #extends_name>(mut self, next: &'a mut impl ::std::ops::DerefMut<Target = T>) -> #name_builder<'a> {
pub fn next<T: #extends_name>(mut self, next: &'a mut 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;
let last_extension = ptr_chain_iter(&mut self.inner)
.last()
.expect("Initial ptr was null");
// Append the extension at the end
(*last_extension).p_next = next as *mut T as *mut _;
}
self
}
@ -2145,33 +2147,23 @@ pub fn write_source_code(path: &Path) {
let source_code = quote! {
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);
/// `T` has to be a valid xxx_create_info struct. Addtionally all the pointer chains in
/// this iterator are mutable. Make sure that all the objects in this pointer chain have an
/// active `&mut` borrow if you want to update those objects.
pub unsafe fn ptr_chain_iter<T>(ptr: &mut T) -> impl Iterator<Item = *mut BaseOutStructure> {
use std::ptr::null_mut;
let ptr: *mut BaseOutStructure = ::std::mem::transmute(ptr);
(0..).scan(ptr, |p_ptr, _|{
if *p_ptr == null_mut() {
return None;
}
extension
}
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct ExtensionChainMut {
pub s_type: StructureType,
pub p_next: *mut c_void
let n_ptr = (**p_ptr).p_next as *mut BaseOutStructure;
let old = *p_ptr;
*p_ptr = n_ptr;
Some(old)
})
}
pub trait Handle {
const TYPE: ObjectType;
fn as_raw(self) -> u64;