Some changes and comments related to Vec allocations

This commit is contained in:
Pierre Krieger 2016-02-20 20:27:26 +01:00
parent 8527843f2d
commit 8e0587aa30
9 changed files with 61 additions and 20 deletions

View File

@ -121,6 +121,7 @@ impl InnerCommandBufferBuilder {
where I: Iterator<Item = &'a InnerCommandBuffer> where I: Iterator<Item = &'a InnerCommandBuffer>
{ {
{ {
// TODO: allocate on stack instead (https://github.com/rust-lang/rfcs/issues/618)
let mut command_buffers = Vec::with_capacity(iter.size_hint().0); let mut command_buffers = Vec::with_capacity(iter.size_hint().0);
for cb in iter { for cb in iter {
@ -277,8 +278,9 @@ impl InnerCommandBufferBuilder {
let vk = self.device.pointers(); let vk = self.device.pointers();
let buffers = vertices.buffers(); let buffers = vertices.buffers();
// TODO: allocate on stack instead (https://github.com/rust-lang/rfcs/issues/618)
let offsets = (0 .. buffers.len()).map(|_| 0).collect::<Vec<_>>(); let offsets = (0 .. buffers.len()).map(|_| 0).collect::<Vec<_>>();
let ids = buffers.iter().map(|b| b.internal_object()).collect::<Vec<_>>(); let ids = buffers.map(|b| b.internal_object()).collect::<Vec<_>>();
vk.CmdBindVertexBuffers(self.cmd.unwrap(), 0, ids.len() as u32, ids.as_ptr(), vk.CmdBindVertexBuffers(self.cmd.unwrap(), 0, ids.len() as u32, ids.as_ptr(),
offsets.as_ptr()); offsets.as_ptr());
vk.CmdDraw(self.cmd.unwrap(), 3, 1, 0, 0); // FIXME: params vk.CmdDraw(self.cmd.unwrap(), 3, 1, 0, 0); // FIXME: params
@ -314,13 +316,15 @@ impl InnerCommandBufferBuilder {
// FIXME: keep these alive // FIXME: keep these alive
let descriptor_sets = pipeline.layout().description().decode_descriptor_sets(sets); let descriptor_sets = pipeline.layout().description().decode_descriptor_sets(sets);
// TODO: allocate on stack instead (https://github.com/rust-lang/rfcs/issues/618)
let descriptor_sets = descriptor_sets.into_iter().map(|set| set.internal_object()).collect::<Vec<_>>(); let descriptor_sets = descriptor_sets.into_iter().map(|set| set.internal_object()).collect::<Vec<_>>();
// TODO: shouldn't rebind everything every time // TODO: shouldn't rebind everything every time
if !descriptor_sets.is_empty() { if !descriptor_sets.is_empty() {
vk.CmdBindDescriptorSets(self.cmd.unwrap(), vk::PIPELINE_BIND_POINT_GRAPHICS, vk.CmdBindDescriptorSets(self.cmd.unwrap(), vk::PIPELINE_BIND_POINT_GRAPHICS,
pipeline.layout().internal_object(), 0, descriptor_sets.len() as u32, pipeline.layout().internal_object(), 0,
descriptor_sets.as_ptr(), 0, ptr::null()); // FIXME: dynamic offsets descriptor_sets.len() as u32, descriptor_sets.as_ptr(),
0, ptr::null()); // FIXME: dynamic offsets
} }
} }
} }
@ -344,6 +348,7 @@ impl InnerCommandBufferBuilder {
{ {
assert!(framebuffer.is_compatible_with(renderpass)); assert!(framebuffer.is_compatible_with(renderpass));
// TODO: allocate on stack instead (https://github.com/rust-lang/rfcs/issues/618)
let clear_values = clear_values.iter().map(|value| { let clear_values = clear_values.iter().map(|value| {
match *value { match *value {
ClearValue::None => vk::ClearValue::color({ ClearValue::None => vk::ClearValue::color({

View File

@ -136,7 +136,9 @@ impl PrimaryCommandBufferBuilder {
{ {
// FIXME: check for compatibility // FIXME: check for compatibility
let clear_values = framebuffer.renderpass().layout().convert_clear_values(clear_values); // TODO: allocate on stack instead (https://github.com/rust-lang/rfcs/issues/618)
let clear_values = framebuffer.renderpass().layout().convert_clear_values(clear_values)
.collect::<Vec<_>>();
unsafe { unsafe {
let inner = self.inner.begin_renderpass(renderpass, framebuffer, false, &clear_values); let inner = self.inner.begin_renderpass(renderpass, framebuffer, false, &clear_values);
@ -167,7 +169,9 @@ impl PrimaryCommandBufferBuilder {
{ {
// FIXME: check for compatibility // FIXME: check for compatibility
let clear_values = framebuffer.renderpass().layout().convert_clear_values(clear_values); // TODO: allocate on stack instead (https://github.com/rust-lang/rfcs/issues/618)
let clear_values = framebuffer.renderpass().layout().convert_clear_values(clear_values)
.collect::<Vec<_>>();
unsafe { unsafe {
let inner = self.inner.begin_renderpass(renderpass, framebuffer, true, &clear_values); let inner = self.inner.begin_renderpass(renderpass, framebuffer, true, &clear_values);

View File

@ -376,6 +376,7 @@ impl<S> DescriptorSet<S> where S: DescriptorSetDesc {
// TODO: the architecture of this function is going to be tricky // TODO: the architecture of this function is going to be tricky
// TODO: allocate on stack instead (https://github.com/rust-lang/rfcs/issues/618)
let buffer_descriptors = write.iter().enumerate().map(|(num, write)| { let buffer_descriptors = write.iter().enumerate().map(|(num, write)| {
match write.content { match write.content {
DescriptorBind::UniformBuffer(ref buffer) => { DescriptorBind::UniformBuffer(ref buffer) => {
@ -388,6 +389,7 @@ impl<S> DescriptorSet<S> where S: DescriptorSetDesc {
} }
}).collect::<Vec<_>>(); }).collect::<Vec<_>>();
// TODO: allocate on stack instead (https://github.com/rust-lang/rfcs/issues/618)
let vk_writes = write.iter().enumerate().map(|(num, write)| { let vk_writes = write.iter().enumerate().map(|(num, write)| {
vk::WriteDescriptorSet { vk::WriteDescriptorSet {
sType: vk::STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, sType: vk::STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
@ -438,6 +440,7 @@ impl<S> DescriptorSetLayout<S> where S: DescriptorSetDesc {
{ {
let vk = device.pointers(); let vk = device.pointers();
// TODO: allocate on stack instead (https://github.com/rust-lang/rfcs/issues/618)
let bindings = description.descriptors().into_iter().map(|desc| { let bindings = description.descriptors().into_iter().map(|desc| {
vk::DescriptorSetLayoutBinding { vk::DescriptorSetLayoutBinding {
binding: desc.binding, binding: desc.binding,
@ -506,6 +509,7 @@ impl<P> PipelineLayout<P> where P: PipelineLayoutDesc {
let vk = device.pointers(); let vk = device.pointers();
let layouts = description.decode_descriptor_set_layouts(layouts); let layouts = description.decode_descriptor_set_layouts(layouts);
// TODO: allocate on stack instead (https://github.com/rust-lang/rfcs/issues/618)
let layouts_ids = layouts.iter().map(|l| { let layouts_ids = layouts.iter().map(|l| {
// FIXME: check that they belong to the same device // FIXME: check that they belong to the same device
::VulkanObjectU64::internal_object(&**l) ::VulkanObjectU64::internal_object(&**l)

View File

@ -70,6 +70,7 @@ impl Device {
// this variable will contain the queue family ID and queue ID of each requested queue // this variable will contain the queue family ID and queue ID of each requested queue
let mut output_queues: Vec<(u32, u32)> = Vec::with_capacity(queue_families.size_hint().0); let mut output_queues: Vec<(u32, u32)> = Vec::with_capacity(queue_families.size_hint().0);
// TODO: allocate on stack instead (https://github.com/rust-lang/rfcs/issues/618)
let layers = layers.into_iter().map(|&layer| { let layers = layers.into_iter().map(|&layer| {
// FIXME: check whether each layer is supported // FIXME: check whether each layer is supported
CString::new(layer).unwrap() CString::new(layer).unwrap()
@ -78,6 +79,7 @@ impl Device {
layer.as_ptr() layer.as_ptr()
}).collect::<Vec<_>>(); }).collect::<Vec<_>>();
// TODO: allocate on stack instead (https://github.com/rust-lang/rfcs/issues/618)
let extensions = ["VK_KHR_swapchain"].iter().map(|&ext| { let extensions = ["VK_KHR_swapchain"].iter().map(|&ext| {
// FIXME: check whether each extension is supported // FIXME: check whether each extension is supported
CString::new(ext).unwrap() CString::new(ext).unwrap()
@ -110,6 +112,7 @@ impl Device {
} }
// turning `queues` into an array of `vkDeviceQueueCreateInfo` suitable for Vulkan // turning `queues` into an array of `vkDeviceQueueCreateInfo` suitable for Vulkan
// TODO: allocate on stack instead (https://github.com/rust-lang/rfcs/issues/618)
let queues = queues.iter().map(|&(queue_id, ref priorities)| { let queues = queues.iter().map(|&(queue_id, ref priorities)| {
vk::DeviceQueueCreateInfo { vk::DeviceQueueCreateInfo {
sType: vk::STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, sType: vk::STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,

View File

@ -41,16 +41,22 @@ pub unsafe trait RenderPassLayout {
/// The list of clear values to use when beginning to draw on this renderpass. /// The list of clear values to use when beginning to draw on this renderpass.
type ClearValues; type ClearValues;
/// Iterator that produces one clear value per attachment.
type ClearValuesIter: Iterator<Item = ClearValue>;
/// Iterator that produces attachments.
type AttachmentsIter: Iterator<Item = AttachmentDescription>;
/// Decodes a `ClearValues` into a list of clear values where each element corresponds /// Decodes a `ClearValues` into a list of clear values where each element corresponds
/// to an attachment. The size of the returned array must be the same as the number of /// to an attachment. The size of the returned array must be the same as the number of
/// attachments. /// attachments.
/// ///
/// The format of the clear value **must** match the format of the attachment. Only attachments /// The format of the clear value **must** match the format of the attachment. Only attachments
/// that are loaded with `LoadOp::Clear` must have an entry in the array. /// that are loaded with `LoadOp::Clear` must have an entry in the array.
fn convert_clear_values(&self, Self::ClearValues) -> Vec<ClearValue>; fn convert_clear_values(&self, Self::ClearValues) -> Self::ClearValuesIter;
/// Returns the descriptions of the attachments. /// Returns the descriptions of the attachments.
fn attachments(&self) -> Vec<AttachmentDescription>; // TODO: static array? fn attachments(&self) -> Self::AttachmentsIter;
} }
pub unsafe trait RenderPassLayoutExt<'a, M: 'a>: RenderPassLayout { pub unsafe trait RenderPassLayoutExt<'a, M: 'a>: RenderPassLayout {
@ -103,14 +109,16 @@ macro_rules! renderpass {
struct Layout; struct Layout;
unsafe impl $crate::framebuffer::RenderPassLayout for Layout { unsafe impl $crate::framebuffer::RenderPassLayout for Layout {
type ClearValues = [f32; 4]; // FIXME: type ClearValues = [f32; 4]; // FIXME:
type ClearValuesIter = std::option::IntoIter<$crate::framebuffer::ClearValue>;
type AttachmentsIter = std::vec::IntoIter<$crate::framebuffer::AttachmentDescription>;
#[inline] #[inline]
fn convert_clear_values(&self, val: Self::ClearValues) -> Vec<$crate::framebuffer::ClearValue> { fn convert_clear_values(&self, val: Self::ClearValues) -> Self::ClearValuesIter {
vec![$crate::framebuffer::ClearValue::Float(val)] Some($crate::framebuffer::ClearValue::Float(val)).into_iter()
} }
#[inline] #[inline]
fn attachments(&self) -> Vec<$crate::framebuffer::AttachmentDescription> { fn attachments(&self) -> Self::AttachmentsIter {
vec![ vec![
$( $(
$crate::framebuffer::AttachmentDescription { $crate::framebuffer::AttachmentDescription {
@ -122,7 +130,7 @@ macro_rules! renderpass {
final_layout: $crate::image::Layout::PresentSrc, // FIXME: final_layout: $crate::image::Layout::PresentSrc, // FIXME:
} }
)* )*
] ].into_iter()
} }
} }
@ -210,7 +218,7 @@ impl<L> RenderPass<L> where L: RenderPassLayout {
pub fn new(device: &Arc<Device>, layout: L) -> Result<Arc<RenderPass<L>>, OomError> { pub fn new(device: &Arc<Device>, layout: L) -> Result<Arc<RenderPass<L>>, OomError> {
let vk = device.pointers(); let vk = device.pointers();
let attachments = layout.attachments().iter().map(|attachment| { let attachments = layout.attachments().map(|attachment| {
vk::AttachmentDescription { vk::AttachmentDescription {
flags: 0, // FIXME: may alias flag flags: 0, // FIXME: may alias flag
format: attachment.format as u32, format: attachment.format as u32,
@ -225,7 +233,7 @@ impl<L> RenderPass<L> where L: RenderPassLayout {
}).collect::<Vec<_>>(); }).collect::<Vec<_>>();
// FIXME: totally hacky // FIXME: totally hacky
let color_attachment_references = layout.attachments().iter().map(|attachment| { let color_attachment_references = layout.attachments().map(|attachment| {
vk::AttachmentReference { vk::AttachmentReference {
attachment: 0, attachment: 0,
layout: vk::IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, layout: vk::IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,

View File

@ -94,6 +94,7 @@ impl Instance {
None None
}; };
// TODO: allocate on stack instead (https://github.com/rust-lang/rfcs/issues/618)
let layers = layers.into_iter().map(|&layer| { let layers = layers.into_iter().map(|&layer| {
// FIXME: check whether each layer is supported // FIXME: check whether each layer is supported
CString::new(layer).unwrap() CString::new(layer).unwrap()
@ -102,6 +103,7 @@ impl Instance {
layer.as_ptr() layer.as_ptr()
}).collect::<Vec<_>>(); }).collect::<Vec<_>>();
// TODO: allocate on stack instead (https://github.com/rust-lang/rfcs/issues/618)
let extensions = ["VK_KHR_surface", "VK_KHR_swapchain", "VK_KHR_win32_surface", "VK_EXT_debug_report"].iter().map(|&ext| { let extensions = ["VK_KHR_surface", "VK_KHR_swapchain", "VK_KHR_win32_surface", "VK_EXT_debug_report"].iter().map(|&ext| {
// FIXME: check whether each extension is supported // FIXME: check whether each extension is supported
CString::new(ext).unwrap() CString::new(ext).unwrap()

View File

@ -65,7 +65,9 @@ impl<MV, Vl, Fl> GraphicsPipeline<MV, (Vl, Fl)>
let vk = device.pointers(); let vk = device.pointers();
let pipeline = unsafe { let pipeline = unsafe {
// TODO: allocate on stack instead (https://github.com/rust-lang/rfcs/issues/618)
let mut dynamic_states: Vec<vk::DynamicState> = Vec::new(); let mut dynamic_states: Vec<vk::DynamicState> = Vec::new();
// TODO: allocate on stack instead (https://github.com/rust-lang/rfcs/issues/618)
let mut stages = Vec::with_capacity(5); let mut stages = Vec::with_capacity(5);
stages.push(vk::PipelineShaderStageCreateInfo { stages.push(vk::PipelineShaderStageCreateInfo {
@ -88,6 +90,7 @@ impl<MV, Vl, Fl> GraphicsPipeline<MV, (Vl, Fl)>
pSpecializationInfo: ptr::null(), // TODO: pSpecializationInfo: ptr::null(), // TODO:
}); });
// TODO: allocate on stack instead (https://github.com/rust-lang/rfcs/issues/618)
let binding_descriptions = (0 .. MV::num_buffers()).map(|num| { let binding_descriptions = (0 .. MV::num_buffers()).map(|num| {
let (stride, rate) = MV::buffer_info(num); let (stride, rate) = MV::buffer_info(num);
vk::VertexInputBindingDescription { vk::VertexInputBindingDescription {
@ -97,6 +100,7 @@ impl<MV, Vl, Fl> GraphicsPipeline<MV, (Vl, Fl)>
} }
}).collect::<Vec<_>>(); }).collect::<Vec<_>>();
// TODO: allocate on stack instead (https://github.com/rust-lang/rfcs/issues/618)
let attribute_descriptions = vertex_shader.attributes().iter().map(|&(loc, ref name)| { let attribute_descriptions = vertex_shader.attributes().iter().map(|&(loc, ref name)| {
let (binding, info) = MV::attrib(name).expect("missing attr"); // TODO: error let (binding, info) = MV::attrib(name).expect("missing attr"); // TODO: error
vk::VertexInputAttributeDescription { vk::VertexInputAttributeDescription {

View File

@ -1,4 +1,5 @@
use std::mem; use std::mem;
use std::option::IntoIter;
use std::sync::Arc; use std::sync::Arc;
use buffer::Buffer; use buffer::Buffer;
@ -28,6 +29,8 @@ pub struct VertexAttribute {
/// Trait for types that contain the layout of a collection of vertex buffers. /// Trait for types that contain the layout of a collection of vertex buffers.
pub unsafe trait MultiVertex { pub unsafe trait MultiVertex {
type BuffersIter: ExactSizeIterator<Item = Arc<BufferResource>>;
fn attrib(name: &str) -> Option<(u32, VertexAttribute)>; fn attrib(name: &str) -> Option<(u32, VertexAttribute)>;
/// Returns the number of buffers in this collection. /// Returns the number of buffers in this collection.
@ -35,12 +38,14 @@ pub unsafe trait MultiVertex {
fn buffer_info(buffer_id: u32) -> (u32, VertexInputRate); fn buffer_info(buffer_id: u32) -> (u32, VertexInputRate);
fn buffers(&self) -> Vec<Arc<BufferResource>>; fn buffers(&self) -> Self::BuffersIter;
} }
unsafe impl<T, M> MultiVertex for Arc<Buffer<T, M>> unsafe impl<T, M> MultiVertex for Arc<Buffer<T, M>>
where T: 'static + Vertex, M: 'static + MemorySourceChunk where T: 'static + Vertex, M: 'static + MemorySourceChunk
{ {
type BuffersIter = IntoIter<Arc<BufferResource>>;
#[inline] #[inline]
fn attrib(name: &str) -> Option<(u32, VertexAttribute)> { fn attrib(name: &str) -> Option<(u32, VertexAttribute)> {
T::attrib(name).map(|attr| (0, attr)) T::attrib(name).map(|attr| (0, attr))
@ -58,14 +63,16 @@ unsafe impl<T, M> MultiVertex for Arc<Buffer<T, M>>
} }
#[inline] #[inline]
fn buffers(&self) -> Vec<Arc<BufferResource>> { fn buffers(&self) -> IntoIter<Arc<BufferResource>> {
vec![self.clone()] Some(self.clone() as Arc<_>).into_iter()
} }
} }
unsafe impl<T, M> MultiVertex for Arc<Buffer<[T], M>> unsafe impl<T, M> MultiVertex for Arc<Buffer<[T], M>>
where T: 'static + Vertex, M: 'static + MemorySourceChunk where T: 'static + Vertex, M: 'static + MemorySourceChunk
{ {
type BuffersIter = IntoIter<Arc<BufferResource>>;
#[inline] #[inline]
fn attrib(name: &str) -> Option<(u32, VertexAttribute)> { fn attrib(name: &str) -> Option<(u32, VertexAttribute)> {
T::attrib(name).map(|attr| (0, attr)) T::attrib(name).map(|attr| (0, attr))
@ -83,8 +90,8 @@ unsafe impl<T, M> MultiVertex for Arc<Buffer<[T], M>>
} }
#[inline] #[inline]
fn buffers(&self) -> Vec<Arc<BufferResource>> { fn buffers(&self) -> IntoIter<Arc<BufferResource>> {
vec![self.clone()] Some(self.clone() as Arc<_>).into_iter()
} }
} }
@ -93,6 +100,8 @@ macro_rules! impl_mv {
unsafe impl<$t1, M> MultiVertex for Arc<Buffer<$t2, M>> unsafe impl<$t1, M> MultiVertex for Arc<Buffer<$t2, M>>
where T: 'static + Vertex, M: 'static + MemorySourceChunk where T: 'static + Vertex, M: 'static + MemorySourceChunk
{ {
type BuffersIter = IntoIter<Arc<BufferResource>>;
#[inline] #[inline]
fn attrib(name: &str) -> Option<(u32, VertexAttribute)> { fn attrib(name: &str) -> Option<(u32, VertexAttribute)> {
T::attrib(name).map(|attr| (0, attr)) T::attrib(name).map(|attr| (0, attr))
@ -109,8 +118,9 @@ macro_rules! impl_mv {
(mem::size_of::<T>() as u32, VertexInputRate::Vertex) (mem::size_of::<T>() as u32, VertexInputRate::Vertex)
} }
fn buffers(&self) -> Vec<Arc<BufferResource>> { #[inline]
vec![self.clone()] fn buffers(&self) -> IntoIter<Arc<BufferResource>> {
Some(self.clone() as Arc<_>).into_iter()
} }
} }
); );

View File

@ -168,6 +168,7 @@ impl Fence {
{ {
let mut device = None; let mut device = None;
// TODO: allocate on stack instead (https://github.com/rust-lang/rfcs/issues/618)
let fences: Vec<vk::Fence> = iter.into_iter().map(|fence| { let fences: Vec<vk::Fence> = iter.into_iter().map(|fence| {
match &mut device { match &mut device {
dev @ &mut None => *dev = Some(fence.device.clone()), dev @ &mut None => *dev = Some(fence.device.clone()),