diff --git a/Cargo.toml b/Cargo.toml index 89ba198..22609b2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,9 @@ authors = ["Dzmitry Malyshau "] name = "portability" crate-type = ["staticlib"] +[dependencies] +winit = "0.7" + [dependencies.gfx-hal] #path = "../gfx/src/hal" git = "https://github.com/kvark/gfx-rs" diff --git a/Makefile b/Makefile index feb72f9..7c7dcc1 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ OBJECTS=$(NATIVE_DIR)/test.o LIBRARY=target/debug/libportability.a CC=gcc -CFLAGS=-I$(VULKAN_DIR) +CFLAGS=-ggdb -O0 -I$(VULKAN_DIR) DEPS= LDFLAGS=-lpthread -ldl -lm -lX11 @@ -23,7 +23,7 @@ $(LIBRARY): src/*.rs Cargo.toml Cargo.lock cargo build mkdir -p target/native -$(NATIVE_DIR)/%.o: native/%.c $(DEPS) +$(NATIVE_DIR)/%.o: native/%.c $(DEPS) Makefile $(CC) -c -o $@ $< $(CFLAGS) $(TARGET): $(LIBRARY) $(OBJECTS) Makefile diff --git a/native/test.c b/native/test.c index 20e525e..4908856 100644 --- a/native/test.c +++ b/native/test.c @@ -4,16 +4,17 @@ #include #include +VkSurfaceKHR vkCreateSurfaceGFX(VkInstance); + int main() { printf("starting the portability test\n"); - VkInstanceCreateInfo inst_info = {}; - inst_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; - VkInstance instance; - VkResult res; + VkResult res = 0; unsigned int i; + VkInstanceCreateInfo inst_info = {}; + inst_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; res = vkCreateInstance(&inst_info, NULL, &instance); if (res == VK_ERROR_INCOMPATIBLE_DRIVER) { printf("cannot find a compatible Vulkan ICD\n"); @@ -23,6 +24,9 @@ int main() { return -1; } + VkSurfaceKHR surface = vkCreateSurfaceGFX(instance); + printf("\tvkCreateSurfaceGFX\n"); + uint32_t adapter_count = 1; VkPhysicalDevice physical_devices[1] = {}; res = vkEnumeratePhysicalDevices(instance, &adapter_count, physical_devices); @@ -91,6 +95,7 @@ int main() { vkFreeCommandBuffers(device, cmd_pool, 1, &cmd_buffer); vkDestroyCommandPool(device, cmd_pool, NULL); + vkDestroySurfaceKHR(instance, surface, NULL); vkDestroyDevice(device, NULL); vkDestroyInstance(instance, NULL); diff --git a/src/handle.rs b/src/handle.rs index 4df54df..c82d602 100644 --- a/src/handle.rs +++ b/src/handle.rs @@ -1,32 +1,23 @@ use std::{fmt, ops}; -use std::marker::PhantomData; #[repr(C)] -pub struct Handle { - pointer: *mut u8, - marker: PhantomData, -} +pub struct Handle(*mut T); impl Handle { pub fn new(value: T) -> Self { - Handle { - pointer: Box::into_raw(Box::new(value)) as _, - marker: PhantomData, - } + let ptr = Box::into_raw(Box::new(value)); + Handle(ptr) } pub fn unwrap(self) -> Box { - unsafe { Box::from_raw(self.pointer as _) } + unsafe { Box::from_raw(self.0) } } } impl Clone for Handle { fn clone(&self) -> Self { - Handle { - pointer: self.pointer, - marker: PhantomData, - } + Handle(self.0) } } @@ -35,19 +26,18 @@ impl Copy for Handle {} impl ops::Deref for Handle { type Target = T; fn deref(&self) -> &T { - unsafe { &*(self.pointer as *mut _) } + unsafe { & *self.0 } } } impl ops::DerefMut for Handle { fn deref_mut(&mut self) -> &mut T { - unsafe { &mut*(self.pointer as *mut _) } + unsafe { &mut *self.0 } } } impl fmt::Debug for Handle { - fn fmt(&self, _formatter: &mut fmt::Formatter) -> fmt::Result { - //TODO - Ok(()) + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + write!(formatter, "Handle({:p})", self.0) } } diff --git a/src/lib.rs b/src/lib.rs index 4c654d4..6df57bf 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,9 +1,11 @@ #![allow(non_snake_case)] #![allow(non_camel_case_types)] #![allow(non_upper_case_globals)] +#![allow(improper_ctypes)] //TEMP: buggy Rustc FFI analysis extern crate gfx_hal as hal; extern crate gfx_backend_vulkan as back; +extern crate winit; mod handle; @@ -5197,12 +5199,17 @@ extern "C" { commandBufferCount: u32, pCommandBuffers: *const VkCommandBuffer); } + +//NOTE: all *KHR types have to be pure `Handle` things for compatibility with +//`VK_DEFINE_NON_DISPATCHABLE_HANDLE` used in `vulkan.h` #[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct VkSurfaceKHR_T { - _unused: [u8; 0], +pub struct VkSurfaceInner { + raw: Backend::Surface, + window: winit::Window, + events_loop: winit::EventsLoop, } -pub type VkSurfaceKHR = *mut VkSurfaceKHR_T; +pub type VkSurfaceKHR = Handle>; + pub const VkColorSpaceKHR_VK_COLOR_SPACE_BEGIN_RANGE_KHR: VkColorSpaceKHR = VkColorSpaceKHR::VK_COLOR_SPACE_SRGB_NONLINEAR_KHR; pub const VkColorSpaceKHR_VK_COLOR_SPACE_END_RANGE_KHR: VkColorSpaceKHR = @@ -5314,10 +5321,16 @@ pub type PFN_vkGetPhysicalDeviceSurfacePresentModesKHR = pPresentModes: *mut VkPresentModeKHR) -> VkResult>; -extern "C" { - pub fn vkDestroySurfaceKHR(instance: VkInstance, surface: VkSurfaceKHR, - pAllocator: *const VkAllocationCallbacks); + +#[no_mangle] +pub extern fn vkDestroySurfaceKHR( + _instance: VkInstance, + surface: VkSurfaceKHR, + _: *const VkAllocationCallbacks, +) { + let _ = surface.unwrap(); //TODO } + extern "C" { pub fn vkGetPhysicalDeviceSurfaceSupportKHR(physicalDevice: VkPhysicalDevice, @@ -5353,6 +5366,22 @@ extern "C" { *mut VkPresentModeKHR) -> VkResult; } + +/// This is an EXTRA function not in original vulkan.h +#[no_mangle] +pub extern fn vkCreateSurfaceGFX(instance: VkInstance) -> VkSurfaceKHR { + let events_loop = winit::EventsLoop::new(); + let window = winit::Window::new(&events_loop).unwrap(); + + let inner = VkSurfaceInner { + raw: instance.create_surface(&window), + window: window, + events_loop: events_loop, + }; + + Handle::new(inner) +} + #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct VkSwapchainKHR_T {