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>
{
{
// TODO: allocate on stack instead (https://github.com/rust-lang/rfcs/issues/618)
let mut command_buffers = Vec::with_capacity(iter.size_hint().0);
for cb in iter {
@ -277,8 +278,9 @@ impl InnerCommandBufferBuilder {
let vk = self.device.pointers();
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 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(),
offsets.as_ptr());
vk.CmdDraw(self.cmd.unwrap(), 3, 1, 0, 0); // FIXME: params
@ -314,13 +316,15 @@ impl InnerCommandBufferBuilder {
// FIXME: keep these alive
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<_>>();
// TODO: shouldn't rebind everything every time
if !descriptor_sets.is_empty() {
vk.CmdBindDescriptorSets(self.cmd.unwrap(), vk::PIPELINE_BIND_POINT_GRAPHICS,
pipeline.layout().internal_object(), 0, descriptor_sets.len() as u32,
descriptor_sets.as_ptr(), 0, ptr::null()); // FIXME: dynamic offsets
pipeline.layout().internal_object(), 0,
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));
// TODO: allocate on stack instead (https://github.com/rust-lang/rfcs/issues/618)
let clear_values = clear_values.iter().map(|value| {
match *value {
ClearValue::None => vk::ClearValue::color({

View File

@ -136,7 +136,9 @@ impl PrimaryCommandBufferBuilder {
{
// 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 {
let inner = self.inner.begin_renderpass(renderpass, framebuffer, false, &clear_values);
@ -167,7 +169,9 @@ impl PrimaryCommandBufferBuilder {
{
// 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 {
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: allocate on stack instead (https://github.com/rust-lang/rfcs/issues/618)
let buffer_descriptors = write.iter().enumerate().map(|(num, write)| {
match write.content {
DescriptorBind::UniformBuffer(ref buffer) => {
@ -388,6 +389,7 @@ impl<S> DescriptorSet<S> where S: DescriptorSetDesc {
}
}).collect::<Vec<_>>();
// TODO: allocate on stack instead (https://github.com/rust-lang/rfcs/issues/618)
let vk_writes = write.iter().enumerate().map(|(num, write)| {
vk::WriteDescriptorSet {
sType: vk::STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
@ -438,6 +440,7 @@ impl<S> DescriptorSetLayout<S> where S: DescriptorSetDesc {
{
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| {
vk::DescriptorSetLayoutBinding {
binding: desc.binding,
@ -506,6 +509,7 @@ impl<P> PipelineLayout<P> where P: PipelineLayoutDesc {
let vk = device.pointers();
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| {
// FIXME: check that they belong to the same device
::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
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| {
// FIXME: check whether each layer is supported
CString::new(layer).unwrap()
@ -78,6 +79,7 @@ impl Device {
layer.as_ptr()
}).collect::<Vec<_>>();
// TODO: allocate on stack instead (https://github.com/rust-lang/rfcs/issues/618)
let extensions = ["VK_KHR_swapchain"].iter().map(|&ext| {
// FIXME: check whether each extension is supported
CString::new(ext).unwrap()
@ -110,6 +112,7 @@ impl Device {
}
// 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)| {
vk::DeviceQueueCreateInfo {
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.
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
/// to an attachment. The size of the returned array must be the same as the number of
/// 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.
fn convert_clear_values(&self, Self::ClearValues) -> Vec<ClearValue>;
fn convert_clear_values(&self, Self::ClearValues) -> Self::ClearValuesIter;
/// 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 {
@ -103,14 +109,16 @@ macro_rules! renderpass {
struct Layout;
unsafe impl $crate::framebuffer::RenderPassLayout for Layout {
type ClearValues = [f32; 4]; // FIXME:
type ClearValuesIter = std::option::IntoIter<$crate::framebuffer::ClearValue>;
type AttachmentsIter = std::vec::IntoIter<$crate::framebuffer::AttachmentDescription>;
#[inline]
fn convert_clear_values(&self, val: Self::ClearValues) -> Vec<$crate::framebuffer::ClearValue> {
vec![$crate::framebuffer::ClearValue::Float(val)]
fn convert_clear_values(&self, val: Self::ClearValues) -> Self::ClearValuesIter {
Some($crate::framebuffer::ClearValue::Float(val)).into_iter()
}
#[inline]
fn attachments(&self) -> Vec<$crate::framebuffer::AttachmentDescription> {
fn attachments(&self) -> Self::AttachmentsIter {
vec![
$(
$crate::framebuffer::AttachmentDescription {
@ -122,7 +130,7 @@ macro_rules! renderpass {
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> {
let vk = device.pointers();
let attachments = layout.attachments().iter().map(|attachment| {
let attachments = layout.attachments().map(|attachment| {
vk::AttachmentDescription {
flags: 0, // FIXME: may alias flag
format: attachment.format as u32,
@ -225,7 +233,7 @@ impl<L> RenderPass<L> where L: RenderPassLayout {
}).collect::<Vec<_>>();
// FIXME: totally hacky
let color_attachment_references = layout.attachments().iter().map(|attachment| {
let color_attachment_references = layout.attachments().map(|attachment| {
vk::AttachmentReference {
attachment: 0,
layout: vk::IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,

View File

@ -94,6 +94,7 @@ impl Instance {
None
};
// TODO: allocate on stack instead (https://github.com/rust-lang/rfcs/issues/618)
let layers = layers.into_iter().map(|&layer| {
// FIXME: check whether each layer is supported
CString::new(layer).unwrap()
@ -102,6 +103,7 @@ impl Instance {
layer.as_ptr()
}).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| {
// FIXME: check whether each extension is supported
CString::new(ext).unwrap()

View File

@ -65,7 +65,9 @@ impl<MV, Vl, Fl> GraphicsPipeline<MV, (Vl, Fl)>
let vk = device.pointers();
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();
// TODO: allocate on stack instead (https://github.com/rust-lang/rfcs/issues/618)
let mut stages = Vec::with_capacity(5);
stages.push(vk::PipelineShaderStageCreateInfo {
@ -88,6 +90,7 @@ impl<MV, Vl, Fl> GraphicsPipeline<MV, (Vl, Fl)>
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 (stride, rate) = MV::buffer_info(num);
vk::VertexInputBindingDescription {
@ -97,6 +100,7 @@ impl<MV, Vl, Fl> GraphicsPipeline<MV, (Vl, Fl)>
}
}).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 (binding, info) = MV::attrib(name).expect("missing attr"); // TODO: error
vk::VertexInputAttributeDescription {

View File

@ -1,4 +1,5 @@
use std::mem;
use std::option::IntoIter;
use std::sync::Arc;
use buffer::Buffer;
@ -28,6 +29,8 @@ pub struct VertexAttribute {
/// Trait for types that contain the layout of a collection of vertex buffers.
pub unsafe trait MultiVertex {
type BuffersIter: ExactSizeIterator<Item = Arc<BufferResource>>;
fn attrib(name: &str) -> Option<(u32, VertexAttribute)>;
/// 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 buffers(&self) -> Vec<Arc<BufferResource>>;
fn buffers(&self) -> Self::BuffersIter;
}
unsafe impl<T, M> MultiVertex for Arc<Buffer<T, M>>
where T: 'static + Vertex, M: 'static + MemorySourceChunk
{
type BuffersIter = IntoIter<Arc<BufferResource>>;
#[inline]
fn attrib(name: &str) -> Option<(u32, VertexAttribute)> {
T::attrib(name).map(|attr| (0, attr))
@ -58,14 +63,16 @@ unsafe impl<T, M> MultiVertex for Arc<Buffer<T, M>>
}
#[inline]
fn buffers(&self) -> Vec<Arc<BufferResource>> {
vec![self.clone()]
fn buffers(&self) -> IntoIter<Arc<BufferResource>> {
Some(self.clone() as Arc<_>).into_iter()
}
}
unsafe impl<T, M> MultiVertex for Arc<Buffer<[T], M>>
where T: 'static + Vertex, M: 'static + MemorySourceChunk
{
type BuffersIter = IntoIter<Arc<BufferResource>>;
#[inline]
fn attrib(name: &str) -> Option<(u32, VertexAttribute)> {
T::attrib(name).map(|attr| (0, attr))
@ -83,8 +90,8 @@ unsafe impl<T, M> MultiVertex for Arc<Buffer<[T], M>>
}
#[inline]
fn buffers(&self) -> Vec<Arc<BufferResource>> {
vec![self.clone()]
fn buffers(&self) -> IntoIter<Arc<BufferResource>> {
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>>
where T: 'static + Vertex, M: 'static + MemorySourceChunk
{
type BuffersIter = IntoIter<Arc<BufferResource>>;
#[inline]
fn attrib(name: &str) -> Option<(u32, VertexAttribute)> {
T::attrib(name).map(|attr| (0, attr))
@ -109,8 +118,9 @@ macro_rules! impl_mv {
(mem::size_of::<T>() as u32, VertexInputRate::Vertex)
}
fn buffers(&self) -> Vec<Arc<BufferResource>> {
vec![self.clone()]
#[inline]
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;
// TODO: allocate on stack instead (https://github.com/rust-lang/rfcs/issues/618)
let fences: Vec<vk::Fence> = iter.into_iter().map(|fence| {
match &mut device {
dev @ &mut None => *dev = Some(fence.device.clone()),