From b9d6309c673a4ce2475d0694de4e9d8182e7cea1 Mon Sep 17 00:00:00 2001 From: msiglreith Date: Sat, 6 Jan 2018 17:44:49 +0100 Subject: [PATCH 1/6] Fix GetPhysicalDeviceQueueFamilyProperties and basic implementation for getting native lunarg samples running --- libportability-gfx/src/impls.rs | 79 +++++++++++++++++++++++++-------- 1 file changed, 61 insertions(+), 18 deletions(-) diff --git a/libportability-gfx/src/impls.rs b/libportability-gfx/src/impls.rs index e728807..bcc5dbe 100644 --- a/libportability-gfx/src/impls.rs +++ b/libportability-gfx/src/impls.rs @@ -1,10 +1,14 @@ use hal::{Device, Instance, PhysicalDevice, QueueFamily, Surface}; +use std::ffi::CString; use std::mem; use std::ops::Deref; use super::*; +const VERSION: (u32, u32, u32) = (1, 0, 66); +const DRIVER_VERSION: u32 = 1; + #[inline] pub extern "C" fn gfxCreateInstance( _pCreateInfo: *const VkInstanceCreateInfo, @@ -49,10 +53,17 @@ pub extern "C" fn gfxGetPhysicalDeviceQueueFamilyProperties( pQueueFamilyPropertyCount: *mut u32, pQueueFamilyProperties: *mut VkQueueFamilyProperties, ) { + let families = &adapter.queue_families; + + // If NULL, number of queue families is returned. + if pQueueFamilyProperties.is_null() { + unsafe { *pQueueFamilyPropertyCount = families.len() as _ }; + return; + } + let output = unsafe { slice::from_raw_parts_mut(pQueueFamilyProperties, *pQueueFamilyPropertyCount as _) }; - let families = &adapter.queue_families; if output.len() > families.len() { unsafe { *pQueueFamilyPropertyCount = families.len() as _ }; } @@ -80,7 +91,7 @@ pub extern "C" fn gfxGetPhysicalDeviceQueueFamilyProperties( #[inline] pub extern "C" fn gfxGetPhysicalDeviceFeatures( - physicalDevice: VkPhysicalDevice, + adapter: VkPhysicalDevice, pFeatures: *mut VkPhysicalDeviceFeatures, ) { unimplemented!() @@ -115,10 +126,38 @@ pub extern "C" fn gfxGetPhysicalDeviceImageFormatProperties( } #[inline] pub extern "C" fn gfxGetPhysicalDeviceProperties( - physicalDevice: VkPhysicalDevice, + adapter: VkPhysicalDevice, pProperties: *mut VkPhysicalDeviceProperties, ) { - unimplemented!() + let adapter_info = &adapter.info; + let limits = adapter.physical_device.get_limits(); + let (major, minor, patch) = VERSION; + + let device_name = { + let c_string = CString::new(adapter_info.name.clone()).unwrap(); + let c_str = c_string.as_bytes_with_nul(); + let mut name = [0; VK_MAX_PHYSICAL_DEVICE_NAME_SIZE as _]; + let len = name.len().min(c_str.len()) - 1; + name[..len].copy_from_slice(&c_str[..len]); + unsafe { mem::transmute(name) } + }; + + let limits = unsafe { mem::zeroed() }; // TODO + let sparse_properties = unsafe { mem::zeroed() }; // TODO + + unsafe { + *pProperties = VkPhysicalDeviceProperties { + apiVersion: (major << 22) | (minor << 12) | patch, + driverVersion: DRIVER_VERSION, + vendorID: adapter_info.vendor as _, + deviceID: adapter_info.device as _, + deviceType: VkPhysicalDeviceType::VK_PHYSICAL_DEVICE_TYPE_OTHER, // TODO + deviceName: device_name, + pipelineCacheUUID: [0; 16usize], + limits, + sparseProperties: sparse_properties, + }; + } } #[inline] pub extern "C" fn gfxGetPhysicalDeviceMemoryProperties( @@ -265,7 +304,10 @@ pub extern "C" fn gfxEnumerateInstanceLayerProperties( pPropertyCount: *mut u32, pProperties: *mut VkLayerProperties, ) -> VkResult { - unimplemented!() + // TODO: dummy implementation + unsafe { *pPropertyCount = 0; } + + VkResult::VK_SUCCESS } #[inline] pub extern "C" fn gfxEnumerateDeviceLayerProperties( @@ -299,7 +341,8 @@ pub extern "C" fn gfxQueueWaitIdle(queue: VkQueue) -> VkResult { } #[inline] pub extern "C" fn gfxDeviceWaitIdle(device: VkDevice) -> VkResult { - unimplemented!() + // TODO + VkResult::VK_SUCCESS } #[inline] pub extern "C" fn gfxAllocateMemory( @@ -385,14 +428,14 @@ pub extern "C" fn gfxBindBufferMemory( memory: VkDeviceMemory, memoryOffset: VkDeviceSize, ) -> VkResult { - *buffer = match *buffer.unwrap() { + *buffer = match *buffer { Buffer::Buffer(_) => panic!("An Buffer can only be bound once!"), - Buffer::Unbound(unbound) => { - Buffer::Buffer( + Buffer::Unbound(ref mut unbound) => { + Buffer::Buffer(unsafe { gpu.device - .bind_buffer_memory(&memory, memoryOffset, unbound) - .unwrap(), // TODO - ) + .bind_buffer_memory_raw(&memory, memoryOffset, unbound) + .unwrap() // TODO + }) } }; @@ -405,14 +448,14 @@ pub extern "C" fn gfxBindImageMemory( memory: VkDeviceMemory, memoryOffset: VkDeviceSize, ) -> VkResult { - *image = match *image.unwrap() { + *image = match *image { Image::Image(_) => panic!("An Image can only be bound once!"), - Image::Unbound(unbound) => { - Image::Image( + Image::Unbound(ref mut unbound) => { + Image::Image(unsafe { gpu.device - .bind_image_memory(&memory, memoryOffset, unbound) - .unwrap(), // TODO - ) + .bind_image_memory_raw(&memory, memoryOffset, unbound) + .unwrap() // TODO + }) } }; From 33e263cd58f4dec4ae79f8fdfbae0df3c5bcb0a3 Mon Sep 17 00:00:00 2001 From: msiglreith Date: Sat, 6 Jan 2018 18:20:19 +0100 Subject: [PATCH 2/6] Implement vkCreateDescriptorSetLayout --- libportability-gfx/src/conv.rs | 53 ++++++++++++++++++++++++++++++++- libportability-gfx/src/impls.rs | 31 +++++++++++++++++-- libportability-gfx/src/lib.rs | 7 +---- 3 files changed, 81 insertions(+), 10 deletions(-) diff --git a/libportability-gfx/src/conv.rs b/libportability-gfx/src/conv.rs index bb82f4e..b4b8246 100644 --- a/libportability-gfx/src/conv.rs +++ b/libportability-gfx/src/conv.rs @@ -1,4 +1,4 @@ -use hal::{adapter, buffer, format, image, memory, window}; +use hal::{adapter, buffer, format, image, memory, pso, window}; use std::mem; @@ -272,6 +272,57 @@ pub fn memory_properties_from_hal(properties: memory::Properties) -> VkMemoryPro flags } +pub fn map_descriptor_type(ty: VkDescriptorType) -> pso::DescriptorType { + use super::VkDescriptorType::*; + + match ty { + VK_DESCRIPTOR_TYPE_SAMPLER => pso::DescriptorType::Sampler, + VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE => pso::DescriptorType::SampledImage, + VK_DESCRIPTOR_TYPE_STORAGE_IMAGE => pso::DescriptorType::StorageImage, + VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER => pso::DescriptorType::UniformTexelBuffer, + VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER => pso::DescriptorType::StorageTexelBuffer, + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER => pso::DescriptorType::UniformBuffer, + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER => pso::DescriptorType::StorageBuffer, + VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT => pso::DescriptorType::InputAttachment, + + VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER | + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC | + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC => unimplemented!(), + _ => panic!("Unexpected descriptor type: {:?}", ty), + } +} + +pub fn map_stage_flags(stages: VkShaderStageFlags) -> pso::ShaderStageFlags { + let mut flags = pso::ShaderStageFlags::empty(); + + if stages & VkShaderStageFlagBits::VK_SHADER_STAGE_VERTEX_BIT as u32 != 0 { + flags |= pso::ShaderStageFlags::VERTEX; + } + if stages & VkShaderStageFlagBits::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT as u32 != 0 { + flags |= pso::ShaderStageFlags::HULL; + } + if stages & VkShaderStageFlagBits::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT as u32 != 0 { + flags |= pso::ShaderStageFlags::DOMAIN; + } + if stages & VkShaderStageFlagBits::VK_SHADER_STAGE_GEOMETRY_BIT as u32 != 0 { + flags |= pso::ShaderStageFlags::GEOMETRY; + } + if stages & VkShaderStageFlagBits::VK_SHADER_STAGE_FRAGMENT_BIT as u32 != 0 { + flags |= pso::ShaderStageFlags::FRAGMENT; + } + if stages & VkShaderStageFlagBits::VK_SHADER_STAGE_COMPUTE_BIT as u32 != 0 { + flags |= pso::ShaderStageFlags::COMPUTE; + } + if stages & VkShaderStageFlagBits::VK_SHADER_STAGE_ALL_GRAPHICS as u32 != 0 { + flags |= pso::ShaderStageFlags::GRAPHICS; + } + if stages & VkShaderStageFlagBits::VK_SHADER_STAGE_ALL as u32 != 0 { + flags |= pso::ShaderStageFlags::ALL; + } + + flags +} + pub fn map_err_device_creation(err: adapter::DeviceCreationError) -> VkResult { use hal::adapter::DeviceCreationError::*; diff --git a/libportability-gfx/src/impls.rs b/libportability-gfx/src/impls.rs index bcc5dbe..346b31a 100644 --- a/libportability-gfx/src/impls.rs +++ b/libportability-gfx/src/impls.rs @@ -1,3 +1,4 @@ +use hal::pso; use hal::{Device, Instance, PhysicalDevice, QueueFamily, Surface}; use std::ffi::CString; @@ -904,12 +905,36 @@ pub extern "C" fn gfxDestroySampler( } #[inline] pub extern "C" fn gfxCreateDescriptorSetLayout( - device: VkDevice, + gpu: VkDevice, pCreateInfo: *const VkDescriptorSetLayoutCreateInfo, - pAllocator: *const VkAllocationCallbacks, + _pAllocator: *const VkAllocationCallbacks, pSetLayout: *mut VkDescriptorSetLayout, ) -> VkResult { - unimplemented!() + let info = unsafe { &*pCreateInfo }; + let layout_bindings = unsafe { + slice::from_raw_parts(info.pBindings, info.bindingCount as _) + }; + + let bindings = layout_bindings + .iter() + .map(|binding| { + assert!(binding.pImmutableSamplers.is_null()); // TODO + + pso::DescriptorSetLayoutBinding { + binding: binding.binding as _, + ty: conv::map_descriptor_type(binding.descriptorType), + count: binding.descriptorCount as _, + stage_flags: conv::map_stage_flags(binding.stageFlags), + + } + }) + .collect::>(); + + let set_layout = gpu.device + .create_descriptor_set_layout(&bindings); + + unsafe { *pSetLayout = Handle::new(set_layout); } + VkResult::VK_SUCCESS } #[inline] pub extern "C" fn gfxDestroyDescriptorSetLayout( diff --git a/libportability-gfx/src/lib.rs b/libportability-gfx/src/lib.rs index e45e0e8..a63b7a6 100644 --- a/libportability-gfx/src/lib.rs +++ b/libportability-gfx/src/lib.rs @@ -30,6 +30,7 @@ pub type VkDevice = Handle>; pub type VkCommandPool = Handle<::CommandPool>; pub type VkCommandBuffer = Handle<::CommandBuffer>; pub type VkDeviceMemory = Handle<::Memory>; +pub type VkDescriptorSetLayout = Handle<::DescriptorSetLayout>; pub enum Image { Image(B::Image), @@ -572,12 +573,6 @@ pub struct VkPipeline_T { pub type VkPipeline = *mut VkPipeline_T; #[repr(C)] #[derive(Debug, Copy, Clone)] -pub struct VkDescriptorSetLayout_T { - _unused: [u8; 0], -} -pub type VkDescriptorSetLayout = *mut VkDescriptorSetLayout_T; -#[repr(C)] -#[derive(Debug, Copy, Clone)] pub struct VkSampler_T { _unused: [u8; 0], } From 78f0654ad3ee6b25b156572d7b8e1f59e0483b9b Mon Sep 17 00:00:00 2001 From: msiglreith Date: Sat, 6 Jan 2018 18:58:50 +0100 Subject: [PATCH 3/6] Implement vkCreatePipelineLayout, vkDestroyPipelineLayout and vkDestroyDescriptorSetLayout --- libportability-gfx/src/impls.rs | 48 ++++++++++++++++++++++++++------- libportability-gfx/src/lib.rs | 7 +---- 2 files changed, 39 insertions(+), 16 deletions(-) diff --git a/libportability-gfx/src/impls.rs b/libportability-gfx/src/impls.rs index 346b31a..781e48d 100644 --- a/libportability-gfx/src/impls.rs +++ b/libportability-gfx/src/impls.rs @@ -1,5 +1,5 @@ use hal::pso; -use hal::{Device, Instance, PhysicalDevice, QueueFamily, Surface}; +use hal::{Backend, Device, Instance, PhysicalDevice, QueueFamily, Surface}; use std::ffi::CString; use std::mem; @@ -871,20 +871,48 @@ pub extern "C" fn gfxDestroyPipeline( } #[inline] pub extern "C" fn gfxCreatePipelineLayout( - device: VkDevice, + gpu: VkDevice, pCreateInfo: *const VkPipelineLayoutCreateInfo, - pAllocator: *const VkAllocationCallbacks, + _pAllocator: *const VkAllocationCallbacks, pPipelineLayout: *mut VkPipelineLayout, ) -> VkResult { - unimplemented!() + let info = unsafe { &*pCreateInfo }; + let set_layouts = unsafe { + slice::from_raw_parts(info.pSetLayouts, info.setLayoutCount as _) + }; + let push_constants = unsafe { + slice::from_raw_parts(info.pPushConstantRanges, info.pushConstantRangeCount as _) + }; + + let layouts = set_layouts + .iter() + .map(|layout| layout.deref()) + .collect::::DescriptorSetLayout>>(); + + let ranges = push_constants + .iter() + .map(|constant| { + let stages = conv::map_stage_flags(constant.stageFlags); + let start = constant.offset / 4; + let size = constant.size / 4; + + (stages, start .. start+size) + }) + .collect::>(); + + let pipeline_layout = gpu.device + .create_pipeline_layout(&layouts, &ranges); + + unsafe { *pPipelineLayout = Handle::new(pipeline_layout); } + VkResult::VK_SUCCESS } #[inline] pub extern "C" fn gfxDestroyPipelineLayout( - device: VkDevice, + gpu: VkDevice, pipelineLayout: VkPipelineLayout, - pAllocator: *const VkAllocationCallbacks, + _pAllocator: *const VkAllocationCallbacks, ) { - unimplemented!() + gpu.device.destroy_pipeline_layout(*pipelineLayout.unwrap()); } #[inline] pub extern "C" fn gfxCreateSampler( @@ -938,11 +966,11 @@ pub extern "C" fn gfxCreateDescriptorSetLayout( } #[inline] pub extern "C" fn gfxDestroyDescriptorSetLayout( - device: VkDevice, + gpu: VkDevice, descriptorSetLayout: VkDescriptorSetLayout, - pAllocator: *const VkAllocationCallbacks, + _pAllocator: *const VkAllocationCallbacks, ) { - unimplemented!() + gpu.device.destroy_descriptor_set_layout(*descriptorSetLayout.unwrap()); } #[inline] pub extern "C" fn gfxCreateDescriptorPool( diff --git a/libportability-gfx/src/lib.rs b/libportability-gfx/src/lib.rs index a63b7a6..f339361 100644 --- a/libportability-gfx/src/lib.rs +++ b/libportability-gfx/src/lib.rs @@ -31,6 +31,7 @@ pub type VkCommandPool = Handle<::CommandPool>; pub type VkCommandBuffer = Handle<::CommandBuffer>; pub type VkDeviceMemory = Handle<::Memory>; pub type VkDescriptorSetLayout = Handle<::DescriptorSetLayout>; +pub type VkPipelineLayout = Handle<::PipelineLayout>; pub enum Image { Image(B::Image), @@ -555,12 +556,6 @@ pub struct VkPipelineCache_T { pub type VkPipelineCache = *mut VkPipelineCache_T; #[repr(C)] #[derive(Debug, Copy, Clone)] -pub struct VkPipelineLayout_T { - _unused: [u8; 0], -} -pub type VkPipelineLayout = *mut VkPipelineLayout_T; -#[repr(C)] -#[derive(Debug, Copy, Clone)] pub struct VkRenderPass_T { _unused: [u8; 0], } From a3a7f1f552917d8ba52397b6d91f911ce3f6cfa2 Mon Sep 17 00:00:00 2001 From: msiglreith Date: Sun, 7 Jan 2018 02:01:19 +0100 Subject: [PATCH 4/6] Implement vkCreateDescriptorPool, vkDestroyDescriptorPool, vkAllocateDescriptorSets and vkUpdateDescriptorSets --- libportability-gfx/src/conv.rs | 18 ++++ libportability-gfx/src/impls.rs | 157 +++++++++++++++++++++++++++++--- libportability-gfx/src/lib.rs | 30 +----- 3 files changed, 167 insertions(+), 38 deletions(-) diff --git a/libportability-gfx/src/conv.rs b/libportability-gfx/src/conv.rs index b4b8246..9b1a750 100644 --- a/libportability-gfx/src/conv.rs +++ b/libportability-gfx/src/conv.rs @@ -176,6 +176,24 @@ pub fn map_image_kind( } } +pub fn map_image_layout(layout: VkImageLayout) -> image::ImageLayout { + match layout { + /* + VK_IMAGE_LAYOUT_UNDEFINED = 0, + VK_IMAGE_LAYOUT_GENERAL = 1, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL = 2, + VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL = 3, + VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL = 4, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL = 5, + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL = 6, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL = 7, + VK_IMAGE_LAYOUT_PREINITIALIZED = 8, + VK_IMAGE_LAYOUT_PRESENT_SRC_KHR = 1000001002, + */ + _ => unimplemented!(), + } +} + fn map_aa_mode(samples: VkSampleCountFlagBits) -> image::AaMode { use VkSampleCountFlagBits::*; diff --git a/libportability-gfx/src/impls.rs b/libportability-gfx/src/impls.rs index 781e48d..6f7ed6d 100644 --- a/libportability-gfx/src/impls.rs +++ b/libportability-gfx/src/impls.rs @@ -1,9 +1,10 @@ use hal::pso; -use hal::{Backend, Device, Instance, PhysicalDevice, QueueFamily, Surface}; +use hal::{Backend, DescriptorPool, Device, Instance, PhysicalDevice, QueueFamily, Surface}; +use hal::pool::RawCommandPool; use std::ffi::CString; use std::mem; -use std::ops::Deref; +use std::ops::{Deref, Range}; use super::*; @@ -974,20 +975,41 @@ pub extern "C" fn gfxDestroyDescriptorSetLayout( } #[inline] pub extern "C" fn gfxCreateDescriptorPool( - device: VkDevice, + gpu: VkDevice, pCreateInfo: *const VkDescriptorPoolCreateInfo, - pAllocator: *const VkAllocationCallbacks, + _pAllocator: *const VkAllocationCallbacks, pDescriptorPool: *mut VkDescriptorPool, ) -> VkResult { - unimplemented!() + let info = unsafe { &*pCreateInfo }; + assert_eq!(info.flags, 0); // TODO + + let pool_sizes = unsafe { + slice::from_raw_parts(info.pPoolSizes, info.poolSizeCount as _) + }; + + let ranges = pool_sizes + .iter() + .map(|pool| { + pso::DescriptorRangeDesc { + ty: conv::map_descriptor_type(pool.type_), + count: pool.descriptorCount as _, + } + }) + .collect::>(); + + let pool = gpu.device + .create_descriptor_pool(info.maxSets as _, &ranges); + + unsafe { *pDescriptorPool = Handle::new(pool); } + VkResult::VK_SUCCESS } #[inline] pub extern "C" fn gfxDestroyDescriptorPool( - device: VkDevice, + gpu: VkDevice, descriptorPool: VkDescriptorPool, - pAllocator: *const VkAllocationCallbacks, + _pAllocator: *const VkAllocationCallbacks, ) { - unimplemented!() + gpu.device.destroy_descriptor_pool(*descriptorPool.unwrap()); } #[inline] pub extern "C" fn gfxResetDescriptorPool( @@ -999,11 +1021,30 @@ pub extern "C" fn gfxResetDescriptorPool( } #[inline] pub extern "C" fn gfxAllocateDescriptorSets( - device: VkDevice, + _device: VkDevice, pAllocateInfo: *const VkDescriptorSetAllocateInfo, pDescriptorSets: *mut VkDescriptorSet, ) -> VkResult { - unimplemented!() + let info = unsafe { &mut *(pAllocateInfo as *mut VkDescriptorSetAllocateInfo) }; + let pool = &mut info.descriptorPool; + + let set_layouts = unsafe { + slice::from_raw_parts(info.pSetLayouts, info.descriptorSetCount as _) + }; + let layouts = set_layouts + .iter() + .map(|layout| layout.deref()) + .collect::>(); + + let descriptor_sets = pool.allocate_sets(&layouts); + let sets = unsafe { + slice::from_raw_parts_mut(pDescriptorSets, info.descriptorSetCount as _) + }; + for (set, raw_set) in sets.iter_mut().zip(descriptor_sets.into_iter()) { + *set = Handle::new(raw_set); + } + + VkResult::VK_SUCCESS } #[inline] pub extern "C" fn gfxFreeDescriptorSets( @@ -1016,13 +1057,105 @@ pub extern "C" fn gfxFreeDescriptorSets( } #[inline] pub extern "C" fn gfxUpdateDescriptorSets( - device: VkDevice, + gpu: VkDevice, descriptorWriteCount: u32, pDescriptorWrites: *const VkWriteDescriptorSet, descriptorCopyCount: u32, pDescriptorCopies: *const VkCopyDescriptorSet, ) { - unimplemented!() + assert_eq!(descriptorCopyCount, 0); // TODO + + let writes = unsafe { + slice::from_raw_parts(pDescriptorWrites, descriptorWriteCount as _) + }; + + let writes = writes + .iter() + .map(|write| { + fn map_buffer_info(buffer_info: &[VkDescriptorBufferInfo]) -> Vec<(&::Buffer, Range)> { + buffer_info + .into_iter() + .map(|buffer| { + assert_ne!(buffer.range as i32, VK_WHOLE_SIZE); + ( + match buffer.buffer.deref() { + &Buffer::Buffer(ref buf) => buf, + // Vulkan portability restriction: + // Non-sparse buffer need to be bound to device memory. + &Buffer::Unbound(_) => panic!("Buffer needs to be bound"), + }, + buffer.offset .. buffer.offset+buffer.range, + ) + }) + .collect() + } + + let image_info = unsafe { + slice::from_raw_parts(write.pImageInfo, write.descriptorCount as _) + }; + let buffer_info = unsafe { + slice::from_raw_parts(write.pBufferInfo, write.descriptorCount as _) + }; + let texel_buffer_views = unsafe { + slice::from_raw_parts(write.pTexelBufferView, write.descriptorCount as _) + }; + + let ty = conv::map_descriptor_type(write.descriptorType); + let desc_write = match ty { + pso::DescriptorType::Sampler => pso::DescriptorWrite::Sampler( + image_info + .into_iter() + .map(|image| &*image.sampler) + .collect() + ), + pso::DescriptorType::SampledImage => pso::DescriptorWrite::SampledImage( + image_info + .into_iter() + .map(|image| (&*image.imageView, conv::map_image_layout(image.imageLayout))) + .collect() + ), + pso::DescriptorType::StorageImage => pso::DescriptorWrite::StorageImage( + image_info + .into_iter() + .map(|image| (&*image.imageView, conv::map_image_layout(image.imageLayout))) + .collect() + ), + pso::DescriptorType::UniformTexelBuffer => pso::DescriptorWrite::UniformTexelBuffer( + texel_buffer_views + .into_iter() + .map(|view| view.deref()) + .collect() + ), + pso::DescriptorType::StorageTexelBuffer => pso::DescriptorWrite::StorageTexelBuffer( + texel_buffer_views + .into_iter() + .map(|view| view.deref()) + .collect() + ), + pso::DescriptorType::UniformBuffer => pso::DescriptorWrite::UniformBuffer( + map_buffer_info(buffer_info) + ), + pso::DescriptorType::StorageBuffer => pso::DescriptorWrite::StorageBuffer( + map_buffer_info(buffer_info) + ), + pso::DescriptorType::InputAttachment => pso::DescriptorWrite::InputAttachment( + image_info + .into_iter() + .map(|image| (&*image.imageView, conv::map_image_layout(image.imageLayout))) + .collect() + ), + }; + + pso::DescriptorSetWrite { + set: &*write.dstSet, + binding: write.dstBinding as _, + array_offset: write.dstArrayElement as _, + write: desc_write, + } + }) + .collect::>(); + + gpu.device.update_descriptor_sets(&writes); } #[inline] pub extern "C" fn gfxCreateFramebuffer( diff --git a/libportability-gfx/src/lib.rs b/libportability-gfx/src/lib.rs index f339361..e0c787b 100644 --- a/libportability-gfx/src/lib.rs +++ b/libportability-gfx/src/lib.rs @@ -17,7 +17,6 @@ mod handle; mod impls; use std::{cmp, slice}; -use hal::pool::RawCommandPool; use back::Backend as B; use handle::Handle; @@ -32,6 +31,10 @@ pub type VkCommandBuffer = Handle<::CommandBuffer>; pub type VkDeviceMemory = Handle<::Memory>; pub type VkDescriptorSetLayout = Handle<::DescriptorSetLayout>; pub type VkPipelineLayout = Handle<::PipelineLayout>; +pub type VkDescriptorPool = Handle<::DescriptorPool>; +pub type VkDescriptorSet = Handle<::DescriptorSet>; +pub type VkSampler = Handle<::Sampler>; +pub type VkBufferView = Handle<::BufferView>; pub enum Image { Image(B::Image), @@ -535,13 +538,6 @@ pub struct VkQueryPool_T { _unused: [u8; 0], } pub type VkQueryPool = *mut VkQueryPool_T; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct VkBufferView_T { - _unused: [u8; 0], -} -pub type VkBufferView = *mut VkBufferView_T; - #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct VkShaderModule_T { @@ -568,24 +564,6 @@ pub struct VkPipeline_T { pub type VkPipeline = *mut VkPipeline_T; #[repr(C)] #[derive(Debug, Copy, Clone)] -pub struct VkSampler_T { - _unused: [u8; 0], -} -pub type VkSampler = *mut VkSampler_T; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct VkDescriptorPool_T { - _unused: [u8; 0], -} -pub type VkDescriptorPool = *mut VkDescriptorPool_T; -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct VkDescriptorSet_T { - _unused: [u8; 0], -} -pub type VkDescriptorSet = *mut VkDescriptorSet_T; -#[repr(C)] -#[derive(Debug, Copy, Clone)] pub struct VkFramebuffer_T { _unused: [u8; 0], } From fb6d185e5fcfcb9f18e2572c32a2578e16c9a5db Mon Sep 17 00:00:00 2001 From: msiglreith Date: Sun, 7 Jan 2018 16:16:22 +0100 Subject: [PATCH 5/6] Implement vkCreateShaderModule and vkDestroyShaderModule --- libportability-gfx/src/impls.rs | 25 +++++++++++++++++++------ libportability-gfx/src/lib.rs | 7 +------ 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/libportability-gfx/src/impls.rs b/libportability-gfx/src/impls.rs index 6f7ed6d..51975ed 100644 --- a/libportability-gfx/src/impls.rs +++ b/libportability-gfx/src/impls.rs @@ -790,20 +790,33 @@ pub extern "C" fn gfxDestroyImageView( } #[inline] pub extern "C" fn gfxCreateShaderModule( - device: VkDevice, + gpu: VkDevice, pCreateInfo: *const VkShaderModuleCreateInfo, - pAllocator: *const VkAllocationCallbacks, + _pAllocator: *const VkAllocationCallbacks, pShaderModule: *mut VkShaderModule, ) -> VkResult { - unimplemented!() + let info = unsafe { &*pCreateInfo }; + let code = unsafe { + slice::from_raw_parts(info.pCode as *const u8, info.codeSize as usize) + }; + + let shader_module = gpu + .device + .create_shader_module(code) + .expect("Error creating shader module"); // TODO + + unsafe { + *pShaderModule = Handle::new(shader_module); + } + VkResult::VK_SUCCESS } #[inline] pub extern "C" fn gfxDestroyShaderModule( - device: VkDevice, + gpu: VkDevice, shaderModule: VkShaderModule, - pAllocator: *const VkAllocationCallbacks, + _pAllocator: *const VkAllocationCallbacks, ) { - unimplemented!() + gpu.device.destroy_shader_module(*shaderModule.unwrap()); } #[inline] pub extern "C" fn gfxCreatePipelineCache( diff --git a/libportability-gfx/src/lib.rs b/libportability-gfx/src/lib.rs index e0c787b..a39d42d 100644 --- a/libportability-gfx/src/lib.rs +++ b/libportability-gfx/src/lib.rs @@ -35,6 +35,7 @@ pub type VkDescriptorPool = Handle<::DescriptorPool>; pub type VkDescriptorSet = Handle<::DescriptorSet>; pub type VkSampler = Handle<::Sampler>; pub type VkBufferView = Handle<::BufferView>; +pub type VkShaderModule = Handle<::ShaderModule>; pub enum Image { Image(B::Image), @@ -540,12 +541,6 @@ pub struct VkQueryPool_T { pub type VkQueryPool = *mut VkQueryPool_T; #[repr(C)] #[derive(Debug, Copy, Clone)] -pub struct VkShaderModule_T { - _unused: [u8; 0], -} -pub type VkShaderModule = *mut VkShaderModule_T; -#[repr(C)] -#[derive(Debug, Copy, Clone)] pub struct VkPipelineCache_T { _unused: [u8; 0], } From 84dcbf309ac6ad29412cd6ba30e978c7ba47667e Mon Sep 17 00:00:00 2001 From: msiglreith Date: Sun, 7 Jan 2018 23:39:06 +0100 Subject: [PATCH 6/6] Fix buffer and image binding --- libportability-gfx/src/impls.rs | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/libportability-gfx/src/impls.rs b/libportability-gfx/src/impls.rs index 51975ed..b5ad13e 100644 --- a/libportability-gfx/src/impls.rs +++ b/libportability-gfx/src/impls.rs @@ -430,14 +430,16 @@ pub extern "C" fn gfxBindBufferMemory( memory: VkDeviceMemory, memoryOffset: VkDeviceSize, ) -> VkResult { - *buffer = match *buffer { - Buffer::Buffer(_) => panic!("An Buffer can only be bound once!"), - Buffer::Unbound(ref mut unbound) => { - Buffer::Buffer(unsafe { + let temp = unsafe { mem::zeroed() }; + + *buffer = match mem::replace(&mut *buffer, temp) { + Buffer::Buffer(_) => panic!("An non-sparse buffer can only be bound once!"), + Buffer::Unbound(unbound) => { + Buffer::Buffer( gpu.device - .bind_buffer_memory_raw(&memory, memoryOffset, unbound) + .bind_buffer_memory(&memory, memoryOffset, unbound) .unwrap() // TODO - }) + ) } }; @@ -450,14 +452,16 @@ pub extern "C" fn gfxBindImageMemory( memory: VkDeviceMemory, memoryOffset: VkDeviceSize, ) -> VkResult { - *image = match *image { - Image::Image(_) => panic!("An Image can only be bound once!"), - Image::Unbound(ref mut unbound) => { - Image::Image(unsafe { + let temp = unsafe { mem::zeroed() }; + + *image = match mem::replace(&mut *image, temp) { + Image::Image(_) => panic!("An non-sparse image can only be bound once!"), + Image::Unbound(unbound) => { + Image::Image( gpu.device - .bind_image_memory_raw(&memory, memoryOffset, unbound) + .bind_image_memory(&memory, memoryOffset, unbound) .unwrap() // TODO - }) + ) } };