pub unsafe fn new<'a, I>(device: Arc<Device>, size: usize, usage: BufferUsage,
                             sharing: Sharing<I>, sparse: SparseLevel)
                             -> Result<(UnsafeBuffer, MemoryRequirements), BufferCreationError>
        where I: Iterator<Item = u32>
    {
        let vk = device.pointers();

        // Ensure we're not trying to create an empty buffer.
        let size = if size == 0 {
            // To avoid panicking when allocating 0 bytes, use a 1-byte buffer.
            1
        } else {
            size
        };

        let usage_bits = usage.to_vulkan_bits();

        // Checking sparse features.
        assert!(sparse.sparse || !sparse.sparse_residency,
                "Can't enable sparse residency without enabling sparse binding as well");
        assert!(sparse.sparse || !sparse.sparse_aliased,
                "Can't enable sparse aliasing without enabling sparse binding as well");
        if sparse.sparse && !device.enabled_features().sparse_binding {
            return Err(BufferCreationError::SparseBindingFeatureNotEnabled);
        }
        if sparse.sparse_residency && !device.enabled_features().sparse_residency_buffer {
            return Err(BufferCreationError::SparseResidencyBufferFeatureNotEnabled);
        }
        if sparse.sparse_aliased && !device.enabled_features().sparse_residency_aliased {
            return Err(BufferCreationError::SparseResidencyAliasedFeatureNotEnabled);
        }

        let buffer = {
            let (sh_mode, sh_indices) = match sharing {
                Sharing::Exclusive => (vk::SHARING_MODE_EXCLUSIVE, SmallVec::<[u32; 8]>::new()),
                Sharing::Concurrent(ids) => (vk::SHARING_MODE_CONCURRENT, ids.collect()),
            };

            let infos = vk::BufferCreateInfo {
                sType: vk::STRUCTURE_TYPE_BUFFER_CREATE_INFO,
                pNext: ptr::null(),
                flags: sparse.to_flags(),
                size: size as u64,
                usage: usage_bits,
                sharingMode: sh_mode,
                queueFamilyIndexCount: sh_indices.len() as u32,
                pQueueFamilyIndices: sh_indices.as_ptr(),
            };

            let mut output = mem::uninitialized();
            check_errors(vk.CreateBuffer(device.internal_object(),
                                         &infos,
                                         ptr::null(),
                                         &mut output))?;
            output
        };

        let mem_reqs = {
            #[inline]
            fn align(val: usize, al: usize) -> usize {
                al * (1 + (val - 1) / al)
            }

            let mut output = if device.loaded_extensions().khr_get_memory_requirements2 {
                let infos = vk::BufferMemoryRequirementsInfo2KHR {
                    sType: vk::STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2_KHR,
                    pNext: ptr::null_mut(),
                    buffer: buffer,
                };

                let mut output2 = if device.loaded_extensions().khr_dedicated_allocation {
                    Some(vk::MemoryDedicatedRequirementsKHR {
                             sType: vk::STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR,
                             pNext: ptr::null(),
                             prefersDedicatedAllocation: mem::uninitialized(),
                             requiresDedicatedAllocation: mem::uninitialized(),
                         })
                } else {
                    None
                };

                let mut output = vk::MemoryRequirements2KHR {
                    sType: vk::STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR,
                    pNext: output2
                        .as_mut()
                        .map(|o| o as *mut vk::MemoryDedicatedRequirementsKHR)
                        .unwrap_or(ptr::null_mut()) as *mut _,
                    memoryRequirements: mem::uninitialized(),
                };

                vk.GetBufferMemoryRequirements2KHR(device.internal_object(), &infos, &mut output);
                debug_assert!(output.memoryRequirements.size >= size as u64);
                debug_assert!(output.memoryRequirements.memoryTypeBits != 0);

                let mut out = MemoryRequirements::from_vulkan_reqs(output.memoryRequirements);
                if let Some(output2) = output2 {
                    debug_assert_eq!(output2.requiresDedicatedAllocation, 0);
                    out.prefer_dedicated = output2.prefersDedicatedAllocation != 0;
                }
                out

            } else {
                let mut output: vk::MemoryRequirements = mem::uninitialized();
                vk.GetBufferMemoryRequirements(device.internal_object(), buffer, &mut output);
                debug_assert!(output.size >= size as u64);
                debug_assert!(output.memoryTypeBits != 0);
                MemoryRequirements::from_vulkan_reqs(output)
            };

            // We have to manually enforce some additional requirements for some buffer types.
            let limits = device.physical_device().limits();
            if usage.uniform_texel_buffer || usage.storage_texel_buffer {
                output.alignment = align(output.alignment,
                                         limits.min_texel_buffer_offset_alignment() as usize);
            }

            if usage.storage_buffer {
                output.alignment = align(output.alignment,
                                         limits.min_storage_buffer_offset_alignment() as usize);
            }

            if usage.uniform_buffer {
                output.alignment = align(output.alignment,
                                         limits.min_uniform_buffer_offset_alignment() as usize);
            }

            output
        };

        let obj = UnsafeBuffer {
            buffer: buffer,
            device: device.clone(),
            size: size as usize,
            usage: usage_bits,
        };

        Ok((obj, mem_reqs))
    }
/// Creates a new buffer of the given size.
///
/// See the module's documentation for information about safety.
///
/// # Panic
///
/// Panics if `sparse.sparse` is false and `sparse.sparse_residency` or
/// `sparse.sparse_aliased` is true.
///
Creates a new buffer of the given size.
See the module's documentation for information about safety.
Creates a new buffer of the given size . See the module ' s documentation for information about safety .
pub unsafe fn new<'a, I>(device: Arc<Device>, size: usize, usage: BufferUsage,
                             sharing: Sharing<I>, sparse: SparseLevel)
                             -> Result<(UnsafeBuffer, MemoryRequirements), BufferCreationError>
        where I: Iterator<Item = u32>
    {
        let vk = device.pointers();
        // Ensure we're not trying to create an empty buffer.
        let size = if size == 0 {
            // To avoid panicking when allocating 0 bytes, use a 1-byte buffer.
            1
        } else {
            size
        };
        let usage_bits = usage.to_vulkan_bits();
        // Checking sparse features.
        assert!(sparse.sparse || !sparse.sparse_residency,
                "Can't enable sparse residency without enabling sparse binding as well");
        assert!(sparse.sparse || !sparse.sparse_aliased,
                "Can't enable sparse aliasing without enabling sparse binding as well");
        if sparse.sparse && !device.enabled_features().sparse_binding {
            return Err(BufferCreationError::SparseBindingFeatureNotEnabled);
        }
        if sparse.sparse_residency && !device.enabled_features().sparse_residency_buffer {
            return Err(BufferCreationError::SparseResidencyBufferFeatureNotEnabled);
        }
        if sparse.sparse_aliased && !device.enabled_features().sparse_residency_aliased {
            return Err(BufferCreationError::SparseResidencyAliasedFeatureNotEnabled);
        }
        let buffer = {
            let (sh_mode, sh_indices) = match sharing {
                Sharing::Exclusive => (vk::SHARING_MODE_EXCLUSIVE, SmallVec::<[u32; 8]>::new()),
                Sharing::Concurrent(ids) => (vk::SHARING_MODE_CONCURRENT, ids.collect()),
            };
            let infos = vk::BufferCreateInfo {
                sType: vk::STRUCTURE_TYPE_BUFFER_CREATE_INFO,
                pNext: ptr::null(),
                flags: sparse.to_flags(),
                size: size as u64,
                usage: usage_bits,
                sharingMode: sh_mode,
                queueFamilyIndexCount: sh_indices.len() as u32,
                pQueueFamilyIndices: sh_indices.as_ptr(),
            };
            let mut output = mem::uninitialized();
            check_errors(vk.CreateBuffer(device.internal_object(),
                                         &infos,
                                         ptr::null(),
                                         &mut output))?;
            output
        };
        let mem_reqs = {
            #[inline]
            fn align(val: usize, al: usize) -> usize {
                al * (1 + (val - 1) / al)
            }
            let mut output = if device.loaded_extensions().khr_get_memory_requirements2 {
                let infos = vk::BufferMemoryRequirementsInfo2KHR {
                    sType: vk::STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2_KHR,
                    pNext: ptr::null_mut(),
                    buffer: buffer,
                };
                let mut output2 = if device.loaded_extensions().khr_dedicated_allocation {
                    Some(vk::MemoryDedicatedRequirementsKHR {
                             sType: vk::STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR,
                             pNext: ptr::null(),
                             prefersDedicatedAllocation: mem::uninitialized(),
                             requiresDedicatedAllocation: mem::uninitialized(),
                         })
                } else {
                    None
                };
                let mut output = vk::MemoryRequirements2KHR {
                    sType: vk::STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR,
                    pNext: output2
                        .as_mut()
                        .map(|o| o as *mut vk::MemoryDedicatedRequirementsKHR)
                        .unwrap_or(ptr::null_mut()) as *mut _,
                    memoryRequirements: mem::uninitialized(),
                };
                vk.GetBufferMemoryRequirements2KHR(device.internal_object(), &infos, &mut output);
                debug_assert!(output.memoryRequirements.size >= size as u64);
                debug_assert!(output.memoryRequirements.memoryTypeBits != 0);
                let mut out = MemoryRequirements::from_vulkan_reqs(output.memoryRequirements);
                if let Some(output2) = output2 {
                    debug_assert_eq!(output2.requiresDedicatedAllocation, 0);
                    out.prefer_dedicated = output2.prefersDedicatedAllocation != 0;
                }
                out
            } else {
                let mut output: vk::MemoryRequirements = mem::uninitialized();
                vk.GetBufferMemoryRequirements(device.internal_object(), buffer, &mut output);
                debug_assert!(output.size >= size as u64);
                debug_assert!(output.memoryTypeBits != 0);
                MemoryRequirements::from_vulkan_reqs(output)
            };
            // We have to manually enforce some additional requirements for some buffer types.
            let limits = device.physical_device().limits();
            if usage.uniform_texel_buffer || usage.storage_texel_buffer {
                output.alignment = align(output.alignment,
                                         limits.min_texel_buffer_offset_alignment() as usize);
            }
            if usage.storage_buffer {
                output.alignment = align(output.alignment,
                                         limits.min_storage_buffer_offset_alignment() as usize);
            }
            if usage.uniform_buffer {
                output.alignment = align(output.alignment,
                                         limits.min_uniform_buffer_offset_alignment() as usize);
            }
            output
        };
        let obj = UnsafeBuffer {
            buffer: buffer,
            device: device.clone(),
            size: size as usize,
            usage: usage_bits,
        };
        Ok((obj, mem_reqs))
    }
pub unsafe fn new < ' a , I > ( device : Arc < Device > , size : usize , usage : BufferUsage , sharing : Sharing < I > , sparse : SparseLevel ) -> Result < ( UnsafeBuffer , MemoryRequirements ) , BufferCreationError > where I : Iterator < Item = u32 > { let vk = device . pointers ( ) ; // Ensure we're not trying to create an empty buffer. let size = if size == 0 { // To avoid panicking when allocating 0 bytes, use a 1-byte buffer. 1 } else { size } ; let usage_bits = usage . to_vulkan_bits ( ) ; // Checking sparse features. assert ! ( sparse sparse sparse sparse_residency " " ) ; assert ! ( sparse sparse sparse sparse_aliased " " ) ; if sparse . sparse && ! device . enabled_features ( ) . sparse_binding { return Err ( BufferCreationError :: SparseBindingFeatureNotEnabled ) ; } if sparse . sparse_residency && ! device . enabled_features ( ) . sparse_residency_buffer { return Err ( BufferCreationError :: SparseResidencyBufferFeatureNotEnabled ) ; } if sparse . sparse_aliased && ! device . enabled_features ( ) . sparse_residency_aliased { return Err ( BufferCreationError :: SparseResidencyAliasedFeatureNotEnabled ) ; } let buffer = { let ( sh_mode , sh_indices ) = match sharing { Sharing :: Exclusive => ( vk :: SHARING_MODE_EXCLUSIVE , SmallVec :: < [ u32 ; 8 ] > :: new ( ) ) , Sharing :: Concurrent ( ids ) => ( vk :: SHARING_MODE_CONCURRENT , ids . collect ( ) ) , } ; let infos = vk :: BufferCreateInfo { sType : vk :: STRUCTURE_TYPE_BUFFER_CREATE_INFO , pNext : ptr :: null ( ) , flags : sparse . to_flags ( ) , size : size as u64 , usage : usage_bits , sharingMode : sh_mode , queueFamilyIndexCount : sh_indices . len ( ) as u32 , pQueueFamilyIndices : sh_indices . as_ptr ( ) , } ; let mut output = mem :: uninitialized ( ) ; check_errors ( vk . CreateBuffer ( device . internal_object ( ) , & infos , ptr :: null ( ) , & mut output ) ) ? ; output } ; let mem_reqs = { # [ inline ] fn align ( val : usize , al : usize ) -> usize { al * ( 1 + ( val - 1 ) / al ) } let mut output = if device . loaded_extensions ( ) . khr_get_memory_requirements2 { let infos = vk :: BufferMemoryRequirementsInfo2KHR { sType : vk :: STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2_KHR , pNext : ptr :: null_mut ( ) , buffer : buffer , } ; let mut output2 = if device . loaded_extensions ( ) . khr_dedicated_allocation { Some ( vk :: MemoryDedicatedRequirementsKHR { sType : vk :: STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR , pNext : ptr :: null ( ) , prefersDedicatedAllocation : mem :: uninitialized ( ) , requiresDedicatedAllocation : mem :: uninitialized ( ) , } ) } else { None } ; let mut output = vk :: MemoryRequirements2KHR { sType : vk :: STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR , pNext : output2 . as_mut ( ) . map ( | o | o as * mut vk :: MemoryDedicatedRequirementsKHR ) . unwrap_or ( ptr :: null_mut ( ) ) as * mut _ , memoryRequirements : mem :: uninitialized ( ) , } ; vk . GetBufferMemoryRequirements2KHR ( device . internal_object ( ) , & infos , & mut output ) ; debug_assert ! ( output memoryRequirements size size as u64 ) ; debug_assert ! ( output memoryRequirements memoryTypeBits 0 ) ; let mut out = MemoryRequirements :: from_vulkan_reqs ( output . memoryRequirements ) ; if let Some ( output2 ) = output2 { debug_assert_eq ! ( output2 requiresDedicatedAllocation 0 ) ; out . prefer_dedicated = output2 . prefersDedicatedAllocation != 0 ; } out } else { let mut output : vk :: MemoryRequirements = mem :: uninitialized ( ) ; vk . GetBufferMemoryRequirements ( device . internal_object ( ) , buffer , & mut output ) ; debug_assert ! ( output size size as u64 ) ; debug_assert ! ( output memoryTypeBits 0 ) ; MemoryRequirements :: from_vulkan_reqs ( output ) } ; // We have to manually enforce some additional requirements for some buffer types. let limits = device . physical_device ( ) . limits ( ) ; if usage . uniform_texel_buffer || usage . storage_texel_buffer { output . alignment = align ( output . alignment , limits . min_texel_buffer_offset_alignment ( ) as usize ) ; } if usage . storage_buffer { output . alignment = align ( output . alignment , limits . min_storage_buffer_offset_alignment ( ) as usize ) ; } if usage . uniform_buffer { output . alignment = align ( output . alignment , limits . min_uniform_buffer_offset_alignment ( ) as usize ) ; } output } ; let obj = UnsafeBuffer { buffer : buffer , device : device . clone ( ) , size : size as usize , usage : usage_bits , } ; Ok ( ( obj , mem_reqs ) ) }
Creates a new buffer of the given size.
Creates a new buffer of the given size .
device
Arc<Device>
size
usize
usage
BufferUsage
sharing
Sharing<I>
sparse
SparseLevel
device
Arc<Device>
size
usize
usage
BufferUsage
sharing
Sharing<I>
sparse
SparseLevel
panic
None