working on getting vulkan_minimal_compute to run
authorJacob Lifshay <programmerjake@gmail.com>
Tue, 6 Nov 2018 08:34:11 +0000 (00:34 -0800)
committerJacob Lifshay <programmerjake@gmail.com>
Tue, 6 Nov 2018 08:34:11 +0000 (00:34 -0800)
vulkan-driver/src/api_impl.rs
vulkan-driver/src/buffer.rs
vulkan-driver/src/descriptor_set.rs [new file with mode: 0644]
vulkan-driver/src/handle.rs
vulkan-driver/src/image.rs
vulkan-driver/src/lib.rs
vulkan-driver/src/render_pass.rs [new file with mode: 0644]
vulkan-driver/src/sampler.rs

index dc7fc4f1d369213ba13f3ce231aee357dba53cdb..61685161fac3420e2bf9d86a388d1c60a48c3498 100644 (file)
@@ -2,21 +2,26 @@
 // Copyright 2018 Jacob Lifshay
 
 // allow unneeded_field_pattern to ensure fields aren't accidently missed
-#![cfg_attr(
-    feature = "cargo-clippy",
-    allow(clippy::unneeded_field_pattern)
-)]
+#![cfg_attr(feature = "cargo-clippy", allow(clippy::unneeded_field_pattern))]
 
 use api;
 use buffer::{Buffer, BufferMemory};
 use constants::*;
+use descriptor_set::{
+    Descriptor, DescriptorLayout, DescriptorPool, DescriptorSet, DescriptorSetLayout,
+    DescriptorWriteArg,
+};
 use device_memory::{
     DeviceMemory, DeviceMemoryAllocation, DeviceMemoryHeap, DeviceMemoryHeaps, DeviceMemoryLayout,
     DeviceMemoryType, DeviceMemoryTypes,
 };
 use enum_map::EnumMap;
 use handle::{Handle, MutHandle, OwnedHandle, SharedHandle};
-use image::{Image, ImageMemory, ImageMultisampleCount, ImageProperties, SupportedTilings};
+use image::{
+    ComponentMapping, Image, ImageMemory, ImageMultisampleCount, ImageProperties, ImageView,
+    ImageViewType, SupportedTilings,
+};
+use render_pass::RenderPass;
 use sampler;
 use sampler::Sampler;
 use shader_module::ShaderModule;
@@ -242,7 +247,7 @@ macro_rules! parse_next_chain_const {
     } => {
         $(let mut $name: *const $var_type = null();)*
         parse_next_chain_const(
-            $root as *const api::VkBaseInStructure,
+            $root as *const _ as *const api::VkBaseInStructure,
             $root_type,
             &[$(($struct_type, &mut $name as *mut *const $var_type as *mut *const api::VkBaseInStructure)),*]
         );
@@ -257,7 +262,7 @@ macro_rules! parse_next_chain_mut {
     } => {
         $(let mut $name: *mut $var_type = null_mut();)*
         parse_next_chain_mut(
-            $root as *mut api::VkBaseOutStructure,
+            $root as *mut _ as *mut api::VkBaseOutStructure,
             $root_type,
             &[$(($struct_type, &mut $name as *mut *mut $var_type as *mut *mut api::VkBaseOutStructure)),*]
         );
@@ -651,10 +656,7 @@ enum GetProcAddressScope {
     Device,
 }
 
-#[cfg_attr(
-    feature = "cargo-clippy",
-    allow(clippy::cyclomatic_complexity)
-)]
+#[cfg_attr(feature = "cargo-clippy", allow(clippy::cyclomatic_complexity))]
 fn get_proc_address(
     name: *const c_char,
     scope: GetProcAddressScope,
@@ -1651,7 +1653,7 @@ impl Device {
         let mut queue_counts: Vec<_> = Vec::new();
         for queue_create_info in queue_create_infos {
             parse_next_chain_const!{
-                queue_create_info as *const api::VkDeviceQueueCreateInfo,
+                queue_create_info,
                 root = api::VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
             }
             let api::VkDeviceQueueCreateInfo {
@@ -3476,7 +3478,7 @@ unsafe fn get_physical_device_queue_family_properties(
     queue_count: u32,
 ) {
     parse_next_chain_mut!{
-        queue_family_properties as *mut api::VkQueueFamilyProperties2,
+        queue_family_properties,
         root = api::VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2,
     }
     queue_family_properties.queueFamilyProperties = api::VkQueueFamilyProperties {
@@ -4142,20 +4144,33 @@ pub unsafe extern "system" fn vkGetImageSubresourceLayout(
 #[allow(non_snake_case)]
 pub unsafe extern "system" fn vkCreateImageView(
     _device: api::VkDevice,
-    _pCreateInfo: *const api::VkImageViewCreateInfo,
-    _pAllocator: *const api::VkAllocationCallbacks,
-    _pView: *mut api::VkImageView,
+    create_info: *const api::VkImageViewCreateInfo,
+    _allocator: *const api::VkAllocationCallbacks,
+    view: *mut api::VkImageView,
 ) -> api::VkResult {
-    unimplemented!()
+    parse_next_chain_const!{
+        create_info,
+        root = api::VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
+    }
+    let create_info = &*create_info;
+    let new_view = OwnedHandle::<api::VkImageView>::new(ImageView {
+        image: SharedHandle::from(create_info.image).unwrap(),
+        view_type: ImageViewType::from(create_info.viewType),
+        format: create_info.format,
+        component_mapping: ComponentMapping::from(create_info.components).unwrap(),
+        subresource_range: create_info.subresourceRange,
+    });
+    *view = new_view.take();
+    api::VK_SUCCESS
 }
 
 #[allow(non_snake_case)]
 pub unsafe extern "system" fn vkDestroyImageView(
     _device: api::VkDevice,
-    _imageView: api::VkImageView,
-    _pAllocator: *const api::VkAllocationCallbacks,
+    image_view: api::VkImageView,
+    _allocator: *const api::VkAllocationCallbacks,
 ) {
-    unimplemented!()
+    OwnedHandle::from(image_view);
 }
 
 #[allow(non_snake_case)]
@@ -4338,78 +4353,171 @@ pub unsafe extern "system" fn vkDestroySampler(
 #[allow(non_snake_case)]
 pub unsafe extern "system" fn vkCreateDescriptorSetLayout(
     _device: api::VkDevice,
-    _pCreateInfo: *const api::VkDescriptorSetLayoutCreateInfo,
-    _pAllocator: *const api::VkAllocationCallbacks,
-    _pSetLayout: *mut api::VkDescriptorSetLayout,
+    create_info: *const api::VkDescriptorSetLayoutCreateInfo,
+    _allocator: *const api::VkAllocationCallbacks,
+    set_layout: *mut api::VkDescriptorSetLayout,
 ) -> api::VkResult {
-    unimplemented!()
+    parse_next_chain_const!{
+        create_info,
+        root = api::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
+    }
+    let create_info = &*create_info;
+    let bindings = match create_info.bindingCount {
+        0 => &[],
+        binding_count => slice::from_raw_parts(create_info.pBindings, binding_count as usize),
+    };
+    let max_binding = bindings.iter().map(|v| v.binding).max().unwrap_or(0) as usize;
+    let mut bindings_map: Vec<Option<DescriptorLayout>> = (0..=max_binding).map(|_| None).collect();
+    for binding in bindings {
+        let bindings_map_entry = &mut bindings_map[binding.binding as usize];
+        assert!(
+            bindings_map_entry.is_none(),
+            "duplicate binding: {}",
+            binding.binding
+        );
+        *bindings_map_entry = Some(DescriptorLayout::from(binding));
+    }
+    *set_layout = OwnedHandle::<api::VkDescriptorSetLayout>::new(DescriptorSetLayout {
+        bindings: bindings_map,
+    })
+    .take();
+    api::VK_SUCCESS
 }
 
 #[allow(non_snake_case)]
 pub unsafe extern "system" fn vkDestroyDescriptorSetLayout(
     _device: api::VkDevice,
-    _descriptorSetLayout: api::VkDescriptorSetLayout,
-    _pAllocator: *const api::VkAllocationCallbacks,
+    descriptor_set_layout: api::VkDescriptorSetLayout,
+    _allocator: *const api::VkAllocationCallbacks,
 ) {
-    unimplemented!()
+    OwnedHandle::from(descriptor_set_layout);
 }
 
 #[allow(non_snake_case)]
 pub unsafe extern "system" fn vkCreateDescriptorPool(
     _device: api::VkDevice,
-    _pCreateInfo: *const api::VkDescriptorPoolCreateInfo,
-    _pAllocator: *const api::VkAllocationCallbacks,
-    _pDescriptorPool: *mut api::VkDescriptorPool,
+    create_info: *const api::VkDescriptorPoolCreateInfo,
+    _allocator: *const api::VkAllocationCallbacks,
+    descriptor_pool: *mut api::VkDescriptorPool,
 ) -> api::VkResult {
-    unimplemented!()
+    parse_next_chain_const!{
+        create_info,
+        root = api::VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
+    }
+    *descriptor_pool = OwnedHandle::<api::VkDescriptorPool>::new(DescriptorPool::new()).take();
+    api::VK_SUCCESS
 }
 
 #[allow(non_snake_case)]
 pub unsafe extern "system" fn vkDestroyDescriptorPool(
     _device: api::VkDevice,
-    _descriptorPool: api::VkDescriptorPool,
-    _pAllocator: *const api::VkAllocationCallbacks,
+    descriptor_pool: api::VkDescriptorPool,
+    _allocator: *const api::VkAllocationCallbacks,
 ) {
-    unimplemented!()
+    OwnedHandle::from(descriptor_pool);
 }
 
 #[allow(non_snake_case)]
 pub unsafe extern "system" fn vkResetDescriptorPool(
     _device: api::VkDevice,
-    _descriptorPool: api::VkDescriptorPool,
+    descriptor_pool: api::VkDescriptorPool,
     _flags: api::VkDescriptorPoolResetFlags,
 ) -> api::VkResult {
-    unimplemented!()
+    MutHandle::from(descriptor_pool).unwrap().reset();
+    api::VK_SUCCESS
 }
 
 #[allow(non_snake_case)]
 pub unsafe extern "system" fn vkAllocateDescriptorSets(
     _device: api::VkDevice,
-    _pAllocateInfo: *const api::VkDescriptorSetAllocateInfo,
-    _pDescriptorSets: *mut api::VkDescriptorSet,
+    allocate_info: *const api::VkDescriptorSetAllocateInfo,
+    descriptor_sets: *mut api::VkDescriptorSet,
 ) -> api::VkResult {
-    unimplemented!()
+    parse_next_chain_const!{
+        allocate_info,
+        root = api::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
+    }
+    let allocate_info = &*allocate_info;
+    let mut descriptor_pool = MutHandle::from(allocate_info.descriptorPool).unwrap();
+    let descriptor_sets =
+        slice::from_raw_parts_mut(descriptor_sets, allocate_info.descriptorSetCount as usize);
+    let descriptor_set_layouts = slice::from_raw_parts(
+        allocate_info.pSetLayouts,
+        allocate_info.descriptorSetCount as usize,
+    );
+    descriptor_pool.allocate(
+        descriptor_set_layouts
+            .iter()
+            .map(|descriptor_set_layout| DescriptorSet {
+                bindings: SharedHandle::from(*descriptor_set_layout)
+                    .unwrap()
+                    .bindings
+                    .iter()
+                    .map(|layout| layout.as_ref().map(Descriptor::from))
+                    .collect(),
+            }),
+        descriptor_sets,
+    );
+    api::VK_SUCCESS
 }
 
 #[allow(non_snake_case)]
 pub unsafe extern "system" fn vkFreeDescriptorSets(
     _device: api::VkDevice,
-    _descriptorPool: api::VkDescriptorPool,
-    _descriptorSetCount: u32,
-    _pDescriptorSets: *const api::VkDescriptorSet,
+    descriptor_pool: api::VkDescriptorPool,
+    descriptor_set_count: u32,
+    descriptor_sets: *const api::VkDescriptorSet,
 ) -> api::VkResult {
-    unimplemented!()
+    let mut descriptor_pool = MutHandle::from(descriptor_pool).unwrap();
+    let descriptor_sets = slice::from_raw_parts(descriptor_sets, descriptor_set_count as usize);
+    descriptor_pool.free(descriptor_sets);
+    api::VK_SUCCESS
 }
 
 #[allow(non_snake_case)]
 pub unsafe extern "system" fn vkUpdateDescriptorSets(
     _device: api::VkDevice,
-    _descriptorWriteCount: u32,
-    _pDescriptorWrites: *const api::VkWriteDescriptorSet,
-    _descriptorCopyCount: u32,
-    _pDescriptorCopies: *const api::VkCopyDescriptorSet,
-) {
-    unimplemented!()
+    descriptor_write_count: u32,
+    descriptor_writes: *const api::VkWriteDescriptorSet,
+    descriptor_copy_count: u32,
+    descriptor_copies: *const api::VkCopyDescriptorSet,
+) {
+    let descriptor_writes =
+        slice::from_raw_parts(descriptor_writes, descriptor_write_count as usize);
+    let descriptor_copies =
+        slice::from_raw_parts(descriptor_copies, descriptor_copy_count as usize);
+    for descriptor_write in descriptor_writes {
+        parse_next_chain_const!{
+            descriptor_write,
+            root = api::VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
+        }
+        let mut descriptor_set = MutHandle::from(descriptor_write.dstSet).unwrap();
+        let mut binding_index = descriptor_write.dstBinding as usize;
+        let mut elements = DescriptorWriteArg::from(descriptor_write);
+        let mut start_element = Some(descriptor_write.dstArrayElement as usize);
+        while elements.len() != 0 {
+            let binding = descriptor_set.bindings[binding_index].as_mut().unwrap();
+            binding_index += 1;
+            assert_eq!(binding.descriptor_type(), descriptor_write.descriptorType);
+            if binding.element_count() == 0 {
+                assert_eq!(start_element, None);
+                continue;
+            }
+            let start_element = start_element.take().unwrap_or(0);
+            let used_elements = elements
+                .len()
+                .min(binding.element_count().checked_sub(start_element).unwrap());
+            binding.write(start_element, elements.slice_to(..used_elements));
+            elements = elements.slice_from(used_elements..);
+        }
+    }
+    for descriptor_copy in descriptor_copies {
+        parse_next_chain_const!{
+            descriptor_copy,
+            root = api::VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET,
+        }
+        unimplemented!()
+    }
 }
 
 #[allow(non_snake_case)]
@@ -4434,20 +4542,26 @@ pub unsafe extern "system" fn vkDestroyFramebuffer(
 #[allow(non_snake_case)]
 pub unsafe extern "system" fn vkCreateRenderPass(
     _device: api::VkDevice,
-    _pCreateInfo: *const api::VkRenderPassCreateInfo,
-    _pAllocator: *const api::VkAllocationCallbacks,
-    _pRenderPass: *mut api::VkRenderPass,
+    create_info: *const api::VkRenderPassCreateInfo,
+    _allocator: *const api::VkAllocationCallbacks,
+    render_pass: *mut api::VkRenderPass,
 ) -> api::VkResult {
-    unimplemented!()
+    parse_next_chain_const!{
+        create_info,
+        root = api::VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
+    }
+    // FIXME: finish implementing
+    *render_pass = OwnedHandle::<api::VkRenderPass>::new(RenderPass {}).take();
+    api::VK_SUCCESS
 }
 
 #[allow(non_snake_case)]
 pub unsafe extern "system" fn vkDestroyRenderPass(
     _device: api::VkDevice,
-    _renderPass: api::VkRenderPass,
-    _pAllocator: *const api::VkAllocationCallbacks,
+    render_pass: api::VkRenderPass,
+    _allocator: *const api::VkAllocationCallbacks,
 ) {
-    unimplemented!()
+    OwnedHandle::from(render_pass);
 }
 
 #[allow(non_snake_case)]
@@ -5008,7 +5122,7 @@ pub unsafe extern "system" fn vkBindBufferMemory2(
     let bind_infos = slice::from_raw_parts(bind_infos, bind_info_count as usize);
     for bind_info in bind_infos {
         parse_next_chain_const!{
-            bind_info as *const api::VkBindBufferMemoryInfo,
+            bind_info,
             root = api::VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO,
             device_group_info: api::VkBindBufferMemoryDeviceGroupInfo = api::VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO,
         }
@@ -5046,7 +5160,7 @@ pub unsafe extern "system" fn vkBindImageMemory2(
     let bind_infos = slice::from_raw_parts(bind_infos, bind_info_count as usize);
     for bind_info in bind_infos {
         parse_next_chain_const!{
-            bind_info as *const api::VkBindImageMemoryInfo,
+            bind_info,
             root = api::VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO,
             device_group_info: api::VkBindImageMemoryDeviceGroupInfo = api::VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO,
             swapchain_info: api::VkBindImageMemorySwapchainInfoKHR = api::VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR,
@@ -5127,7 +5241,7 @@ pub unsafe extern "system" fn vkEnumeratePhysicalDeviceGroups(
         iter::once(()),
         |physical_device_group_properties, _| {
             parse_next_chain_mut!{
-                physical_device_group_properties as *mut api::VkPhysicalDeviceGroupProperties,
+                physical_device_group_properties,
                 root = api::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES,
             }
             let mut physical_devices = [Handle::null(); api::VK_MAX_DEVICE_GROUP_SIZE as usize];
index 9ece100210340ab9ce3af78dd597ed4a09920e1b..697d7b72329f4d9e8c8103dea874135c2e0f226d 100644 (file)
@@ -3,12 +3,44 @@
 use api;
 use handle::SharedHandle;
 
+#[derive(Debug)]
 pub struct BufferMemory {
     pub device_memory: SharedHandle<api::VkDeviceMemory>,
     pub offset: usize,
 }
 
+#[derive(Debug)]
 pub struct Buffer {
     pub size: usize,
     pub memory: Option<BufferMemory>,
 }
+
+#[derive(Debug)]
+pub struct BufferSlice {
+    pub buffer: SharedHandle<api::VkBuffer>,
+    pub offset: usize,
+    pub size: usize,
+}
+
+impl BufferSlice {
+    pub unsafe fn from(v: &api::VkDescriptorBufferInfo) -> Self {
+        let buffer = SharedHandle::from(v.buffer).unwrap();
+        assert!(v.offset < buffer.size as u64);
+        let offset = v.offset as usize;
+        let size = if v.range == api::VK_WHOLE_SIZE as u64 {
+            buffer.size - offset
+        } else {
+            assert!(v.range != 0);
+            assert!(v.range.checked_add(v.offset).unwrap() <= buffer.size as u64);
+            v.range as usize
+        };
+        Self {
+            buffer,
+            offset,
+            size,
+        }
+    }
+}
+
+#[derive(Debug)]
+pub struct BufferView {}
diff --git a/vulkan-driver/src/descriptor_set.rs b/vulkan-driver/src/descriptor_set.rs
new file mode 100644 (file)
index 0000000..5de5f0d
--- /dev/null
@@ -0,0 +1,557 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright 2018 Jacob Lifshay
+
+use api;
+use buffer::BufferSlice;
+use handle::OwnedHandle;
+use handle::SharedHandle;
+use image;
+use std::ops;
+use std::slice;
+
+#[derive(Debug)]
+pub enum DescriptorLayout {
+    Sampler {
+        count: usize,
+        immutable_samplers: Option<Vec<SharedHandle<api::VkSampler>>>,
+    },
+    CombinedImageSampler {
+        count: usize,
+        immutable_samplers: Option<Vec<SharedHandle<api::VkSampler>>>,
+    },
+    SampledImage {
+        count: usize,
+    },
+    StorageImage {
+        count: usize,
+    },
+    UniformTexelBuffer {
+        count: usize,
+    },
+    StorageTexelBuffer {
+        count: usize,
+    },
+    UniformBuffer {
+        count: usize,
+    },
+    StorageBuffer {
+        count: usize,
+    },
+    UniformBufferDynamic {
+        count: usize,
+    },
+    StorageBufferDynamic {
+        count: usize,
+    },
+    InputAttachment {
+        count: usize,
+    },
+}
+
+impl DescriptorLayout {
+    #[allow(dead_code)]
+    pub fn count(&self) -> usize {
+        match *self {
+            DescriptorLayout::Sampler { count, .. } => count,
+            DescriptorLayout::CombinedImageSampler { count, .. } => count,
+            DescriptorLayout::SampledImage { count } => count,
+            DescriptorLayout::StorageImage { count } => count,
+            DescriptorLayout::UniformTexelBuffer { count } => count,
+            DescriptorLayout::StorageTexelBuffer { count } => count,
+            DescriptorLayout::UniformBuffer { count } => count,
+            DescriptorLayout::StorageBuffer { count } => count,
+            DescriptorLayout::UniformBufferDynamic { count } => count,
+            DescriptorLayout::StorageBufferDynamic { count } => count,
+            DescriptorLayout::InputAttachment { count } => count,
+        }
+    }
+    #[allow(dead_code)]
+    pub fn immutable_samplers(&self) -> Option<&[SharedHandle<api::VkSampler>]> {
+        match self {
+            DescriptorLayout::Sampler {
+                immutable_samplers: Some(immutable_samplers),
+                ..
+            } => Some(immutable_samplers),
+            DescriptorLayout::CombinedImageSampler {
+                immutable_samplers: Some(immutable_samplers),
+                ..
+            } => Some(immutable_samplers),
+            _ => None,
+        }
+    }
+    pub fn descriptor_type(&self) -> api::VkDescriptorType {
+        match self {
+            DescriptorLayout::Sampler { .. } => api::VK_DESCRIPTOR_TYPE_SAMPLER,
+            DescriptorLayout::CombinedImageSampler { .. } => {
+                api::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER
+            }
+            DescriptorLayout::SampledImage { .. } => api::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
+            DescriptorLayout::StorageImage { .. } => api::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
+            DescriptorLayout::UniformTexelBuffer { .. } => {
+                api::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER
+            }
+            DescriptorLayout::StorageTexelBuffer { .. } => {
+                api::VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER
+            }
+            DescriptorLayout::UniformBuffer { .. } => api::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
+            DescriptorLayout::StorageBuffer { .. } => api::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
+            DescriptorLayout::UniformBufferDynamic { .. } => {
+                api::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC
+            }
+            DescriptorLayout::StorageBufferDynamic { .. } => {
+                api::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC
+            }
+            DescriptorLayout::InputAttachment { .. } => api::VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
+        }
+    }
+    pub unsafe fn from(v: &api::VkDescriptorSetLayoutBinding) -> Self {
+        let get_immutable_samplers = || {
+            if v.pImmutableSamplers.is_null() {
+                None
+            } else {
+                let immutable_samplers =
+                    slice::from_raw_parts(v.pImmutableSamplers, v.descriptorCount as usize);
+                Some(
+                    immutable_samplers
+                        .iter()
+                        .map(|sampler| SharedHandle::from(*sampler).unwrap())
+                        .collect(),
+                )
+            }
+        };
+        match v.descriptorType {
+            api::VK_DESCRIPTOR_TYPE_SAMPLER => DescriptorLayout::Sampler {
+                count: v.descriptorCount as usize,
+                immutable_samplers: get_immutable_samplers(),
+            },
+            api::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER => {
+                DescriptorLayout::CombinedImageSampler {
+                    count: v.descriptorCount as usize,
+                    immutable_samplers: get_immutable_samplers(),
+                }
+            }
+            api::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE => DescriptorLayout::SampledImage {
+                count: v.descriptorCount as usize,
+            },
+            api::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE => DescriptorLayout::StorageImage {
+                count: v.descriptorCount as usize,
+            },
+            api::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER => DescriptorLayout::UniformTexelBuffer {
+                count: v.descriptorCount as usize,
+            },
+            api::VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER => DescriptorLayout::StorageTexelBuffer {
+                count: v.descriptorCount as usize,
+            },
+            api::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER => DescriptorLayout::UniformBuffer {
+                count: v.descriptorCount as usize,
+            },
+            api::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER => DescriptorLayout::StorageBuffer {
+                count: v.descriptorCount as usize,
+            },
+            api::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC => {
+                DescriptorLayout::UniformBufferDynamic {
+                    count: v.descriptorCount as usize,
+                }
+            }
+            api::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC => {
+                DescriptorLayout::StorageBufferDynamic {
+                    count: v.descriptorCount as usize,
+                }
+            }
+            api::VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT => DescriptorLayout::InputAttachment {
+                count: v.descriptorCount as usize,
+            },
+            _ => unreachable!("invalid VkDescriptorType: {}", v.descriptorType),
+        }
+    }
+}
+
+#[derive(Debug)]
+pub struct DescriptorSetLayout {
+    pub bindings: Vec<Option<DescriptorLayout>>,
+}
+
+#[derive(Debug)]
+pub struct DescriptorPool {
+    descriptor_sets: Vec<OwnedHandle<api::VkDescriptorSet>>,
+}
+
+impl DescriptorPool {
+    pub fn new() -> Self {
+        Self {
+            descriptor_sets: Vec::new(),
+        }
+    }
+    pub fn reset(&mut self) {
+        self.descriptor_sets.clear()
+    }
+    pub unsafe fn allocate<I: IntoIterator<Item = DescriptorSet>>(
+        &mut self,
+        descriptor_sets: I,
+        output_descriptor_sets: &mut [api::VkDescriptorSet],
+    ) {
+        let start_index = self.descriptor_sets.len();
+        self.descriptor_sets
+            .extend(descriptor_sets.into_iter().map(OwnedHandle::new));
+        assert_eq!(
+            self.descriptor_sets[start_index..].len(),
+            output_descriptor_sets.len()
+        );
+        for (output_descriptor_set, descriptor_set) in output_descriptor_sets
+            .iter_mut()
+            .zip(self.descriptor_sets[start_index..].iter())
+        {
+            *output_descriptor_set = descriptor_set.get_handle();
+        }
+    }
+    pub unsafe fn free(&mut self, descriptor_sets: &[api::VkDescriptorSet]) {
+        self.descriptor_sets
+            .retain(|descriptor_set| !descriptor_sets.contains(&descriptor_set.get_handle()))
+    }
+}
+
+#[derive(Debug)]
+pub struct DescriptorImage(SharedHandle<api::VkImageView>, image::Tiling);
+
+impl DescriptorImage {
+    pub unsafe fn from(v: &api::VkDescriptorImageInfo) -> Self {
+        let image_view = SharedHandle::from(v.imageView).unwrap();
+        let tiling = image_view.image.properties.get_tiling(v.imageLayout);
+        DescriptorImage(image_view, tiling)
+    }
+}
+
+#[derive(Debug)]
+pub struct DescriptorCombinedImageSampler {
+    image: Option<DescriptorImage>,
+    sampler: Option<SharedHandle<api::VkSampler>>,
+}
+
+#[derive(Debug)]
+pub enum Descriptor {
+    Sampler {
+        elements: Vec<Option<SharedHandle<api::VkSampler>>>,
+        immutable_samplers: bool,
+    },
+    CombinedImageSampler {
+        elements: Vec<DescriptorCombinedImageSampler>,
+        immutable_samplers: bool,
+    },
+    SampledImage {
+        elements: Vec<Option<DescriptorImage>>,
+    },
+    StorageImage {
+        elements: Vec<Option<DescriptorImage>>,
+    },
+    UniformTexelBuffer {
+        elements: Vec<Option<SharedHandle<api::VkBufferView>>>,
+    },
+    StorageTexelBuffer {
+        elements: Vec<Option<SharedHandle<api::VkBufferView>>>,
+    },
+    UniformBuffer {
+        elements: Vec<Option<BufferSlice>>,
+    },
+    StorageBuffer {
+        elements: Vec<Option<BufferSlice>>,
+    },
+    UniformBufferDynamic {
+        elements: Vec<Option<BufferSlice>>,
+    },
+    StorageBufferDynamic {
+        elements: Vec<Option<BufferSlice>>,
+    },
+    InputAttachment {
+        elements: Vec<Option<DescriptorImage>>,
+    },
+}
+
+#[derive(Copy, Clone)]
+pub enum DescriptorWriteArg<'a> {
+    Image(&'a [api::VkDescriptorImageInfo]),
+    Buffer(&'a [api::VkDescriptorBufferInfo]),
+    TexelBuffer(&'a [api::VkBufferView]),
+}
+
+impl<'a> DescriptorWriteArg<'a> {
+    pub unsafe fn from(v: &'a api::VkWriteDescriptorSet) -> Self {
+        match v.descriptorType {
+            api::VK_DESCRIPTOR_TYPE_SAMPLER
+            | api::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER
+            | api::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE
+            | api::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE
+            | api::VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT => {
+                assert!(!v.pImageInfo.is_null());
+                DescriptorWriteArg::Image(slice::from_raw_parts(
+                    v.pImageInfo,
+                    v.descriptorCount as usize,
+                ))
+            }
+            api::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER
+            | api::VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER => {
+                assert!(!v.pTexelBufferView.is_null());
+                DescriptorWriteArg::TexelBuffer(slice::from_raw_parts(
+                    v.pTexelBufferView,
+                    v.descriptorCount as usize,
+                ))
+            }
+            api::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER
+            | api::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER
+            | api::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC
+            | api::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC => {
+                assert!(!v.pBufferInfo.is_null());
+                DescriptorWriteArg::Buffer(slice::from_raw_parts(
+                    v.pBufferInfo,
+                    v.descriptorCount as usize,
+                ))
+            }
+            _ => unreachable!("invalid VkDescriptorType: {}", v.descriptorType),
+        }
+    }
+    pub fn len(self) -> usize {
+        match self {
+            DescriptorWriteArg::Image(v) => v.len(),
+            DescriptorWriteArg::Buffer(v) => v.len(),
+            DescriptorWriteArg::TexelBuffer(v) => v.len(),
+        }
+    }
+    pub fn slice(self, range: ops::Range<usize>) -> Self {
+        match self {
+            DescriptorWriteArg::Image(v) => DescriptorWriteArg::Image(&v[range]),
+            DescriptorWriteArg::Buffer(v) => DescriptorWriteArg::Buffer(&v[range]),
+            DescriptorWriteArg::TexelBuffer(v) => DescriptorWriteArg::TexelBuffer(&v[range]),
+        }
+    }
+    pub fn slice_from(self, range: ops::RangeFrom<usize>) -> Self {
+        match self {
+            DescriptorWriteArg::Image(v) => DescriptorWriteArg::Image(&v[range]),
+            DescriptorWriteArg::Buffer(v) => DescriptorWriteArg::Buffer(&v[range]),
+            DescriptorWriteArg::TexelBuffer(v) => DescriptorWriteArg::TexelBuffer(&v[range]),
+        }
+    }
+    pub fn slice_to(self, range: ops::RangeTo<usize>) -> Self {
+        match self {
+            DescriptorWriteArg::Image(v) => DescriptorWriteArg::Image(&v[range]),
+            DescriptorWriteArg::Buffer(v) => DescriptorWriteArg::Buffer(&v[range]),
+            DescriptorWriteArg::TexelBuffer(v) => DescriptorWriteArg::TexelBuffer(&v[range]),
+        }
+    }
+    pub fn image(self) -> Option<&'a [api::VkDescriptorImageInfo]> {
+        match self {
+            DescriptorWriteArg::Image(v) => Some(v),
+            _ => None,
+        }
+    }
+    pub fn buffer(self) -> Option<&'a [api::VkDescriptorBufferInfo]> {
+        match self {
+            DescriptorWriteArg::Buffer(v) => Some(v),
+            _ => None,
+        }
+    }
+    pub fn texel_buffer(self) -> Option<&'a [api::VkBufferView]> {
+        match self {
+            DescriptorWriteArg::TexelBuffer(v) => Some(v),
+            _ => None,
+        }
+    }
+}
+
+fn descriptor_write_helper<Element, T, F: FnMut(&mut Element, &T)>(
+    start_element: usize,
+    elements: &mut [Element],
+    args: &[T],
+    mut f: F,
+) {
+    for (element, arg) in elements[start_element..][..args.len()]
+        .iter_mut()
+        .zip(args.iter())
+    {
+        f(element, arg);
+    }
+}
+
+impl Descriptor {
+    pub fn element_count(&self) -> usize {
+        match self {
+            Descriptor::Sampler { elements, .. } => elements.len(),
+            Descriptor::CombinedImageSampler { elements, .. } => elements.len(),
+            Descriptor::SampledImage { elements, .. } => elements.len(),
+            Descriptor::StorageImage { elements, .. } => elements.len(),
+            Descriptor::UniformTexelBuffer { elements, .. } => elements.len(),
+            Descriptor::StorageTexelBuffer { elements, .. } => elements.len(),
+            Descriptor::UniformBuffer { elements, .. } => elements.len(),
+            Descriptor::StorageBuffer { elements, .. } => elements.len(),
+            Descriptor::UniformBufferDynamic { elements, .. } => elements.len(),
+            Descriptor::StorageBufferDynamic { elements, .. } => elements.len(),
+            Descriptor::InputAttachment { elements, .. } => elements.len(),
+        }
+    }
+    pub fn from(layout: &DescriptorLayout) -> Self {
+        match layout {
+            DescriptorLayout::Sampler {
+                count,
+                immutable_samplers,
+            } => {
+                let mut elements: Vec<_> = (0..*count).map(|_| None).collect();
+                let immutable_samplers = if let Some(immutable_samplers) = immutable_samplers {
+                    assert_eq!(immutable_samplers.len(), *count);
+                    for (element, sampler) in elements.iter_mut().zip(immutable_samplers.iter()) {
+                        *element = Some(sampler.clone());
+                    }
+                    true
+                } else {
+                    false
+                };
+                Descriptor::Sampler {
+                    elements,
+                    immutable_samplers,
+                }
+            }
+            DescriptorLayout::CombinedImageSampler {
+                count,
+                immutable_samplers,
+            } => {
+                let mut elements: Vec<_> = (0..*count)
+                    .map(|_| DescriptorCombinedImageSampler {
+                        image: None,
+                        sampler: None,
+                    })
+                    .collect();
+                let immutable_samplers = if let Some(immutable_samplers) = immutable_samplers {
+                    assert_eq!(immutable_samplers.len(), *count);
+                    for (element, sampler) in elements.iter_mut().zip(immutable_samplers.iter()) {
+                        element.sampler = Some(sampler.clone());
+                    }
+                    true
+                } else {
+                    false
+                };
+                Descriptor::CombinedImageSampler {
+                    elements,
+                    immutable_samplers,
+                }
+            }
+            DescriptorLayout::SampledImage { count } => Descriptor::SampledImage {
+                elements: (0..*count).map(|_| None).collect(),
+            },
+            DescriptorLayout::StorageImage { count } => Descriptor::StorageImage {
+                elements: (0..*count).map(|_| None).collect(),
+            },
+            DescriptorLayout::UniformTexelBuffer { count } => Descriptor::UniformTexelBuffer {
+                elements: (0..*count).map(|_| None).collect(),
+            },
+            DescriptorLayout::StorageTexelBuffer { count } => Descriptor::StorageTexelBuffer {
+                elements: (0..*count).map(|_| None).collect(),
+            },
+            DescriptorLayout::UniformBuffer { count } => Descriptor::UniformBuffer {
+                elements: (0..*count).map(|_| None).collect(),
+            },
+            DescriptorLayout::StorageBuffer { count } => Descriptor::StorageBuffer {
+                elements: (0..*count).map(|_| None).collect(),
+            },
+            DescriptorLayout::UniformBufferDynamic { count } => Descriptor::UniformBufferDynamic {
+                elements: (0..*count).map(|_| None).collect(),
+            },
+            DescriptorLayout::StorageBufferDynamic { count } => Descriptor::StorageBufferDynamic {
+                elements: (0..*count).map(|_| None).collect(),
+            },
+            DescriptorLayout::InputAttachment { count } => Descriptor::InputAttachment {
+                elements: (0..*count).map(|_| None).collect(),
+            },
+        }
+    }
+    pub unsafe fn write(&mut self, start_element: usize, arg: DescriptorWriteArg) {
+        assert_eq!(arg.len() + start_element, self.element_count());
+        match self {
+            Descriptor::Sampler {
+                elements,
+                immutable_samplers,
+            } => descriptor_write_helper(
+                start_element,
+                elements,
+                arg.image().unwrap(),
+                |_element, _arg| assert!(!*immutable_samplers),
+            ),
+            Descriptor::CombinedImageSampler {
+                elements,
+                immutable_samplers,
+            } => descriptor_write_helper(
+                start_element,
+                elements,
+                arg.image().unwrap(),
+                |element, arg| {
+                    if !*immutable_samplers {
+                        element.sampler = Some(SharedHandle::from(arg.sampler).unwrap());
+                    }
+                    element.image = Some(DescriptorImage::from(arg));
+                },
+            ),
+            Descriptor::SampledImage { elements } => descriptor_write_helper(
+                start_element,
+                elements,
+                arg.image().unwrap(),
+                |element, arg| {
+                    *element = Some(DescriptorImage::from(arg));
+                },
+            ),
+            Descriptor::StorageImage { elements } => descriptor_write_helper(
+                start_element,
+                elements,
+                arg.image().unwrap(),
+                |element, arg| {
+                    *element = Some(DescriptorImage::from(arg));
+                },
+            ),
+            Descriptor::UniformTexelBuffer { elements } => unimplemented!(),
+            Descriptor::StorageTexelBuffer { elements } => unimplemented!(),
+            Descriptor::UniformBuffer { elements } => descriptor_write_helper(
+                start_element,
+                elements,
+                arg.buffer().unwrap(),
+                |element, arg| *element = Some(BufferSlice::from(arg)),
+            ),
+            Descriptor::StorageBuffer { elements } => descriptor_write_helper(
+                start_element,
+                elements,
+                arg.buffer().unwrap(),
+                |element, arg| *element = Some(BufferSlice::from(arg)),
+            ),
+            Descriptor::UniformBufferDynamic { elements } => unimplemented!(),
+            Descriptor::StorageBufferDynamic { elements } => unimplemented!(),
+            Descriptor::InputAttachment { elements } => descriptor_write_helper(
+                start_element,
+                elements,
+                arg.image().unwrap(),
+                |element, arg| {
+                    *element = Some(DescriptorImage::from(arg));
+                },
+            ),
+        }
+    }
+    pub fn descriptor_type(&self) -> api::VkDescriptorType {
+        match self {
+            Descriptor::Sampler { .. } => api::VK_DESCRIPTOR_TYPE_SAMPLER,
+            Descriptor::CombinedImageSampler { .. } => {
+                api::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER
+            }
+            Descriptor::SampledImage { .. } => api::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
+            Descriptor::StorageImage { .. } => api::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
+            Descriptor::UniformTexelBuffer { .. } => api::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
+            Descriptor::StorageTexelBuffer { .. } => api::VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
+            Descriptor::UniformBuffer { .. } => api::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
+            Descriptor::StorageBuffer { .. } => api::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
+            Descriptor::UniformBufferDynamic { .. } => {
+                api::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC
+            }
+            Descriptor::StorageBufferDynamic { .. } => {
+                api::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC
+            }
+            Descriptor::InputAttachment { .. } => api::VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
+        }
+    }
+}
+
+#[derive(Debug)]
+pub struct DescriptorSet {
+    pub bindings: Vec<Option<Descriptor>>,
+}
index 624593c5f0130af41f86c5f6e50551829f9122b0..33b31ad96540dab0ee539b9d15ce26f50517304a 100644 (file)
@@ -2,9 +2,11 @@
 // Copyright 2018 Jacob Lifshay
 use api;
 use api_impl::{Device, Instance, PhysicalDevice, Queue};
-use buffer::Buffer;
+use buffer::{Buffer, BufferView};
+use descriptor_set::{DescriptorPool, DescriptorSet, DescriptorSetLayout};
 use device_memory::DeviceMemory;
-use image::Image;
+use image::{Image, ImageView};
+use render_pass::RenderPass;
 use sampler::Sampler;
 use sampler::SamplerYcbcrConversion;
 use shader_module::ShaderModule;
@@ -205,10 +207,15 @@ where
     }
 }
 
-#[derive(Copy, Clone)]
 #[repr(transparent)]
 pub struct SharedHandle<T: Handle>(NonNull<T::Value>);
 
+impl<T: Handle> Clone for SharedHandle<T> {
+    fn clone(&self) -> Self {
+        SharedHandle(self.0)
+    }
+}
+
 impl<T: Handle> SharedHandle<T> {
     pub unsafe fn from(v: T) -> Option<Self> {
         v.get().map(SharedHandle)
@@ -344,14 +351,10 @@ pub type VkQueryPool = NondispatchableHandle<QueryPool>;
 
 impl HandleAllocFree for VkQueryPool {}
 
-pub struct BufferView {}
-
 pub type VkBufferView = NondispatchableHandle<BufferView>;
 
 impl HandleAllocFree for VkBufferView {}
 
-pub struct ImageView {}
-
 pub type VkImageView = NondispatchableHandle<ImageView>;
 
 impl HandleAllocFree for VkImageView {}
@@ -372,8 +375,6 @@ pub type VkPipelineLayout = NondispatchableHandle<PipelineLayout>;
 
 impl HandleAllocFree for VkPipelineLayout {}
 
-pub struct RenderPass {}
-
 pub type VkRenderPass = NondispatchableHandle<RenderPass>;
 
 impl HandleAllocFree for VkRenderPass {}
@@ -384,8 +385,6 @@ pub type VkPipeline = NondispatchableHandle<Pipeline>;
 
 impl HandleAllocFree for VkPipeline {}
 
-pub struct DescriptorSetLayout {}
-
 pub type VkDescriptorSetLayout = NondispatchableHandle<DescriptorSetLayout>;
 
 impl HandleAllocFree for VkDescriptorSetLayout {}
@@ -394,14 +393,10 @@ pub type VkSampler = NondispatchableHandle<Sampler>;
 
 impl HandleAllocFree for VkSampler {}
 
-pub struct DescriptorPool {}
-
 pub type VkDescriptorPool = NondispatchableHandle<DescriptorPool>;
 
 impl HandleAllocFree for VkDescriptorPool {}
 
-pub struct DescriptorSet {}
-
 pub type VkDescriptorSet = NondispatchableHandle<DescriptorSet>;
 
 impl HandleAllocFree for VkDescriptorSet {}
index c847997e6d4c1c2fcd95f89e88eca8a923cc86c8..681b52651a4b429c7c7fc0190bce3536b924e9e0 100644 (file)
@@ -1,13 +1,12 @@
 // SPDX-License-Identifier: LGPL-2.1-or-later
 // Copyright 2018 Jacob Lifshay
-#![cfg_attr(
-    feature = "cargo-clippy",
-    allow(clippy::unneeded_field_pattern)
-)]
+#![cfg_attr(feature = "cargo-clippy", allow(clippy::unneeded_field_pattern))]
 use api;
 use constants::IMAGE_ALIGNMENT;
 use device_memory::DeviceMemoryLayout;
 use handle::SharedHandle;
+use std::error;
+use std::fmt;
 
 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
 pub enum SupportedTilings {
@@ -46,6 +45,16 @@ pub struct ImageComputedProperties {
 }
 
 impl ImageProperties {
+    pub fn get_tiling(&self, image_layout: api::VkImageLayout) -> Tiling {
+        if image_layout == api::VK_IMAGE_LAYOUT_PRESENT_SRC_KHR {
+            self.swapchain_present_tiling.unwrap()
+        } else {
+            match self.supported_tilings {
+                SupportedTilings::LinearOnly => Tiling::Linear,
+                SupportedTilings::Any => Tiling::Tiled,
+            }
+        }
+    }
     pub fn computed_properties(&self) -> ImageComputedProperties {
         match *self {
             Self {
@@ -90,3 +99,108 @@ pub struct Image {
     pub properties: ImageProperties,
     pub memory: Option<ImageMemory>,
 }
+
+#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
+pub enum ImageViewType {
+    Type1D,
+    Type2D,
+    Type3D,
+    Cube,
+    Array1D,
+    Array2D,
+    CubeArray,
+}
+
+impl ImageViewType {
+    pub fn from(v: api::VkImageViewType) -> Self {
+        match v {
+            api::VK_IMAGE_VIEW_TYPE_1D => ImageViewType::Type1D,
+            api::VK_IMAGE_VIEW_TYPE_2D => ImageViewType::Type2D,
+            api::VK_IMAGE_VIEW_TYPE_3D => ImageViewType::Type3D,
+            api::VK_IMAGE_VIEW_TYPE_CUBE => ImageViewType::Cube,
+            api::VK_IMAGE_VIEW_TYPE_1D_ARRAY => ImageViewType::Array1D,
+            api::VK_IMAGE_VIEW_TYPE_2D_ARRAY => ImageViewType::Array2D,
+            api::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY => ImageViewType::CubeArray,
+            _ => unreachable!(),
+        }
+    }
+}
+
+#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
+pub enum ComponentSwizzle {
+    Zero,
+    One,
+    X,
+    Y,
+    Z,
+    W,
+}
+
+#[derive(Debug)]
+pub struct InvalidVkComponentSwizzle;
+
+impl fmt::Display for InvalidVkComponentSwizzle {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "invalid VkComponentSwizzle")
+    }
+}
+
+impl error::Error for InvalidVkComponentSwizzle {}
+
+impl ComponentSwizzle {
+    pub fn from(
+        v: api::VkComponentSwizzle,
+        identity: Self,
+    ) -> Result<Self, InvalidVkComponentSwizzle> {
+        match v {
+            api::VK_COMPONENT_SWIZZLE_IDENTITY => Ok(identity),
+            api::VK_COMPONENT_SWIZZLE_ZERO => Ok(ComponentSwizzle::Zero),
+            api::VK_COMPONENT_SWIZZLE_ONE => Ok(ComponentSwizzle::One),
+            api::VK_COMPONENT_SWIZZLE_R => Ok(ComponentSwizzle::X),
+            api::VK_COMPONENT_SWIZZLE_G => Ok(ComponentSwizzle::Y),
+            api::VK_COMPONENT_SWIZZLE_B => Ok(ComponentSwizzle::Z),
+            api::VK_COMPONENT_SWIZZLE_A => Ok(ComponentSwizzle::W),
+            _ => Err(InvalidVkComponentSwizzle),
+        }
+    }
+}
+
+#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
+pub struct ComponentMapping {
+    pub x: ComponentSwizzle,
+    pub y: ComponentSwizzle,
+    pub z: ComponentSwizzle,
+    pub w: ComponentSwizzle,
+}
+
+impl ComponentMapping {
+    pub const IDENTITY: ComponentMapping = ComponentMapping {
+        x: ComponentSwizzle::X,
+        y: ComponentSwizzle::Y,
+        z: ComponentSwizzle::Z,
+        w: ComponentSwizzle::W,
+    };
+    pub fn from(v: api::VkComponentMapping) -> Result<Self, InvalidVkComponentSwizzle> {
+        Ok(Self {
+            x: ComponentSwizzle::from(v.r, ComponentSwizzle::X)?,
+            y: ComponentSwizzle::from(v.g, ComponentSwizzle::Y)?,
+            z: ComponentSwizzle::from(v.b, ComponentSwizzle::Z)?,
+            w: ComponentSwizzle::from(v.a, ComponentSwizzle::W)?,
+        })
+    }
+}
+
+impl Default for ComponentMapping {
+    fn default() -> Self {
+        Self::IDENTITY
+    }
+}
+
+#[derive(Debug)]
+pub struct ImageView {
+    pub image: SharedHandle<api::VkImage>,
+    pub view_type: ImageViewType,
+    pub format: api::VkFormat,
+    pub component_mapping: ComponentMapping,
+    pub subresource_range: api::VkImageSubresourceRange,
+}
index 0879956be47a493d458a1c325f0a363f7cb6f2af..b920b61c9fbad5db55364e1e928bc882f575bb59 100644 (file)
@@ -15,9 +15,11 @@ extern crate xcb;
 mod api;
 mod api_impl;
 mod buffer;
+mod descriptor_set;
 mod device_memory;
 mod handle;
 mod image;
+mod render_pass;
 mod sampler;
 mod shader_module;
 #[cfg(target_os = "linux")]
diff --git a/vulkan-driver/src/render_pass.rs b/vulkan-driver/src/render_pass.rs
new file mode 100644 (file)
index 0000000..779273f
--- /dev/null
@@ -0,0 +1,5 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// Copyright 2018 Jacob Lifshay
+
+#[derive(Debug)]
+pub struct RenderPass {}
index 58dda14ed54a5660cc4b61bad8ba8c11cf736622..b9afd2186f8f7ccc9c6323e8b71c709229ea6d39 100644 (file)
@@ -3,10 +3,12 @@
 use api;
 use handle::SharedHandle;
 
+#[derive(Debug)]
 pub struct AnisotropySettings {
     pub max: f32,
 }
 
+#[derive(Debug)]
 pub struct Sampler {
     pub mag_filter: api::VkFilter,
     pub min_filter: api::VkFilter,
@@ -22,4 +24,5 @@ pub struct Sampler {
     pub sampler_ycbcr_conversion: Option<SharedHandle<api::VkSamplerYcbcrConversion>>,
 }
 
+#[derive(Debug)]
 pub struct SamplerYcbcrConversion {}