From f799034fb154f503ba7149611934403059c37d28 Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Tue, 14 Nov 2017 11:19:33 -0500 Subject: [PATCH] Surface capabilities and formats --- native/test.c | 58 +++++++++++++++++++++++-- src/conv.rs | 34 +++++++++++++++ src/lib.rs | 116 ++++++++++++++++++++++++++++++++++++-------------- 3 files changed, 173 insertions(+), 35 deletions(-) create mode 100644 src/conv.rs diff --git a/native/test.c b/native/test.c index 4908856..fc7cf93 100644 --- a/native/test.c +++ b/native/test.c @@ -42,7 +42,9 @@ int main() { int queue_family_index = -1; for (i = 0; i < queue_family_count; i++) { - if (queue_family_properties[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) { + VkBool32 supports_present = 0; + vkGetPhysicalDeviceSurfaceSupportKHR(physical_devices[0], i, surface, &supports_present); + if ((queue_family_properties[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) && supports_present) { queue_family_index = i; break; } @@ -50,6 +52,58 @@ int main() { printf("\tusing queue family index %d\n", queue_family_index); assert(queue_family_index >= 0); + VkSurfaceFormatKHR surfFormats[20]; + uint32_t formatCount = sizeof(surfFormats) / sizeof(surfFormats[0]); + res = vkGetPhysicalDeviceSurfaceFormatsKHR(physical_devices[0], surface, &formatCount, surfFormats); + printf("\tvkGetPhysicalDeviceSurfaceFormatsKHR: res=%d, count=%d\n", res, formatCount); + assert(!res); + + VkSurfaceCapabilitiesKHR surfCapabilities; + res = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical_devices[0], surface, &surfCapabilities); + assert(!res); + + VkPresentModeKHR presentModes[10]; + uint32_t presentModeCount = sizeof(presentModes) / sizeof(presentModes[0]); + res = vkGetPhysicalDeviceSurfacePresentModesKHR(physical_devices[0], surface, &presentModeCount, presentModes); + printf("\tvkGetPhysicalDeviceSurfacePresentModesKHR: res=%d, count=%d\n", res, presentModeCount); + assert(!res); + + VkExtent2D swapchainExtent = surfCapabilities.currentExtent; + VkPresentModeKHR swapchainPresentMode = VK_PRESENT_MODE_FIFO_KHR; + + // Determine the number of VkImage's to use in the swap chain. + // We need to acquire only 1 presentable image at at time. + // Asking for minImageCount images ensures that we can acquire + // 1 presentable image as long as we present it before attempting + // to acquire another. + uint32_t desiredNumberOfSwapChainImages = surfCapabilities.minImageCount; + + VkSurfaceTransformFlagBitsKHR preTransform; + if (surfCapabilities.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) { + preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; + } else { + preTransform = surfCapabilities.currentTransform; + } + + VkCompositeAlphaFlagBitsKHR compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; + + /*VkSwapchainCreateInfoKHR swapchain_ci = {0}; + swapchain_ci.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; + swapchain_ci.surface = info.surface; + swapchain_ci.minImageCount = desiredNumberOfSwapChainImages; + swapchain_ci.imageFormat = info.format; + swapchain_ci.imageExtent.width = swapchainExtent.width; + swapchain_ci.imageExtent.height = swapchainExtent.height; + swapchain_ci.preTransform = preTransform; + swapchain_ci.compositeAlpha = compositeAlpha; + swapchain_ci.imageArrayLayers = 1; + swapchain_ci.presentMode = swapchainPresentMode; + swapchain_ci.oldSwapchain = VK_NULL_HANDLE; + swapchain_ci.clipped = true; + swapchain_ci.imageColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR; + swapchain_ci.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + swapchain_ci.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;*/ + VkDeviceQueueCreateInfo queue_info = {}; float queue_priorities[1] = {0.0}; queue_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; @@ -66,8 +120,6 @@ int main() { printf("\tvkCreateDevice: res=%d\n", res); assert(!res); - //TODO - VkCommandPool cmd_pool = 0; VkCommandPoolCreateInfo cmd_pool_info = {}; cmd_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; diff --git a/src/conv.rs b/src/conv.rs new file mode 100644 index 0000000..ac589d8 --- /dev/null +++ b/src/conv.rs @@ -0,0 +1,34 @@ +use {VkExtent2D, VkFormat}; + +use hal::format; +use hal::window; + +pub fn format_from_hal(format: format::Format) -> VkFormat { + use VkFormat::*; + use hal::format::ChannelType::*; + use hal::format::SurfaceType::*; + + match format.0 { + R8_G8_B8_A8 => match format.1 { + Unorm => VK_FORMAT_R8G8B8A8_UNORM, + Srgb => VK_FORMAT_R8G8B8A8_SRGB, + _ => unimplemented!() + }, + B8_G8_R8_A8 => match format.1 { + Unorm => VK_FORMAT_B8G8R8A8_UNORM, + Srgb => VK_FORMAT_B8G8R8A8_SRGB, + _ => unimplemented!() + }, + _ => { + println!("\tformat {:?}", format); + unimplemented!() + } + } +} + +pub fn extent2d_from_hal(extent: window::Extent2d) -> VkExtent2D { + VkExtent2D { + width: extent.width, + height: extent.height, + } +} diff --git a/src/lib.rs b/src/lib.rs index 6df57bf..819e531 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,10 +7,11 @@ extern crate gfx_hal as hal; extern crate gfx_backend_vulkan as back; extern crate winit; +mod conv; mod handle; use std::{cmp, slice}; -use hal::{Device, Instance, PhysicalDevice, QueueFamily}; // traits only +use hal::{Device, Instance, PhysicalDevice, QueueFamily, Surface}; // traits only use hal::pool::RawCommandPool; use back::Backend as B; use handle::Handle; @@ -5331,40 +5332,91 @@ pub extern fn vkDestroySurfaceKHR( let _ = surface.unwrap(); //TODO } -extern "C" { - pub fn vkGetPhysicalDeviceSurfaceSupportKHR(physicalDevice: - VkPhysicalDevice, - queueFamilyIndex: u32, - surface: VkSurfaceKHR, - pSupported: *mut VkBool32) - -> VkResult; +#[no_mangle] +pub extern fn vkGetPhysicalDeviceSurfaceSupportKHR( + adapter: VkPhysicalDevice, + queueFamilyIndex: u32, + surface: VkSurfaceKHR, + pSupported: *mut VkBool32, +) -> VkResult { + let family = &adapter.queue_families[queueFamilyIndex as usize]; + let supports = surface.raw.supports_queue_family(family); + unsafe { *pSupported = supports as _ }; + VkResult::VK_SUCCESS } -extern "C" { - pub fn vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice: - VkPhysicalDevice, - surface: VkSurfaceKHR, - pSurfaceCapabilities: - *mut VkSurfaceCapabilitiesKHR) - -> VkResult; + +#[no_mangle] +pub extern fn vkGetPhysicalDeviceSurfaceCapabilitiesKHR( + adapter: VkPhysicalDevice, + surface: VkSurfaceKHR, + pSurfaceCapabilities: *mut VkSurfaceCapabilitiesKHR, +) -> VkResult { + let (caps, _) = surface.raw.capabilities_and_formats(&adapter.physical_device); + + let output = VkSurfaceCapabilitiesKHR { + minImageCount: caps.image_count.start, + maxImageCount: caps.image_count.end, + currentExtent: match caps.current_extent { + Some(extent) => conv::extent2d_from_hal(extent), + None => VkExtent2D { + width: !0, + height: !0, + }, + }, + minImageExtent: conv::extent2d_from_hal(caps.extents.start), + maxImageExtent: conv::extent2d_from_hal(caps.extents.end), + maxImageArrayLayers: caps.max_image_layers, + supportedTransforms: VkSurfaceTransformFlagBitsKHR::VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR as _, + currentTransform: VkSurfaceTransformFlagBitsKHR::VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR, + supportedCompositeAlpha: VkCompositeAlphaFlagBitsKHR::VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR as _, + supportedUsageFlags: 0, + }; + + unsafe { *pSurfaceCapabilities = output }; + VkResult::VK_SUCCESS } -extern "C" { - pub fn vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice: - VkPhysicalDevice, - surface: VkSurfaceKHR, - pSurfaceFormatCount: *mut u32, - pSurfaceFormats: - *mut VkSurfaceFormatKHR) - -> VkResult; + +#[no_mangle] +pub extern fn vkGetPhysicalDeviceSurfaceFormatsKHR( + adapter: VkPhysicalDevice, + surface: VkSurfaceKHR, + pSurfaceFormatCount: *mut u32, + pSurfaceFormats: *mut VkSurfaceFormatKHR, +) -> VkResult { + let (_, formats) = surface.raw.capabilities_and_formats(&adapter.physical_device); + let output = unsafe { slice::from_raw_parts_mut(pSurfaceFormats, *pSurfaceFormatCount as usize) }; + + if output.len() > formats.len() { + unsafe { *pSurfaceFormatCount = formats.len() as u32 }; + } + for (out, format) in output.iter_mut().zip(formats) { + *out = VkSurfaceFormatKHR { + format: conv::format_from_hal(format), + colorSpace: VkColorSpaceKHR::VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, //TODO + }; + } + + VkResult::VK_SUCCESS } -extern "C" { - pub fn vkGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice: - VkPhysicalDevice, - surface: VkSurfaceKHR, - pPresentModeCount: - *mut u32, - pPresentModes: - *mut VkPresentModeKHR) - -> VkResult; + +#[no_mangle] +pub extern fn vkGetPhysicalDeviceSurfacePresentModesKHR( + _adapter: VkPhysicalDevice, + _surface: VkSurfaceKHR, + pPresentModeCount: *mut u32, + pPresentModes: *mut VkPresentModeKHR, +) -> VkResult { + let modes = vec![VkPresentModeKHR::VK_PRESENT_MODE_FIFO_KHR]; //TODO + let output = unsafe { slice::from_raw_parts_mut(pPresentModes, *pPresentModeCount as usize) }; + + if output.len() > modes.len() { + unsafe { *pPresentModeCount = modes.len() as u32 }; + } + for (out, mode) in output.iter_mut().zip(modes) { + *out = mode; + } + + VkResult::VK_SUCCESS } /// This is an EXTRA function not in original vulkan.h