Proper static lib, enumerate_adapters

This commit is contained in:
Dzmitry Malyshau 2017-09-06 21:34:41 -04:00
parent 7f30e22a05
commit 70cf6476c3
6 changed files with 143 additions and 84 deletions

3
.gitignore vendored
View file

@ -1,7 +1,4 @@
/target/
native/test
native/test.o
native/vulkan
src/original.rs
**/*.rs.bk
Cargo.lock

View file

@ -4,9 +4,9 @@ version = "0.1.0"
authors = ["Dzmitry Malyshau <kvark@mozilla.com>"]
[lib]
name = "vulkan"
crate-type = ["dylib"]
name = "portability"
crate-type = ["staticlib"]
[dependencies]
gfx_core = { path = "../gfx/src/core" }
gfx_backend_vulkan = { path = "../gfx/src/backend/vulkan" }
gfx_backend_vulkan = { path = "../gfx/src/backend/vulkan", features = ["portable"] }

View file

@ -1,23 +1,33 @@
CC=gcc
CFLAGS=
DEPS=
LDFLAGS=-lpthread -ldl -lm
HEADER=native/vulkan/vulkan.h
BINDING=src/original.rs
TARGET=native/test
OBJECTS=native/test.o
OUTPUT_DIR=target/debug
OUTPUT=${OUTPUT_DIR}/libvulkan.a
BINDING=target/vulkan.rs
NATIVE_DIR=target/native
TARGET=$(NATIVE_DIR)/test
OBJECTS=$(NATIVE_DIR)/test.o
LIBRARY=target/debug/libportability.a
all: ${TARGET}
all: $(TARGET)
${BINDING}: ${HEADER}
bindgen --no-layout-tests --rustfmt-bindings ${HEADER} -o ${BINDING}
$(BINDING): $(HEADER)
bindgen --no-layout-tests --rustfmt-bindings $(HEADER) -o $(BINDING)
portability: ${BINDING}
$(LIBRARY): $(BINDING) src/*.rs
cargo build
mkdir -p target/native
${TARGET}: portability ${OBJECTS}
gcc -o ${TARGET} -L${OUTPUT_DIR} -lvulkan ${OBJECTS}
$(NATIVE_DIR)/%.o: native/%.c $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS)
run: ${TARGET}
${TARGET}
$(TARGET): $(LIBRARY) $(OBJECTS)
$(CC) -o $(TARGET) $(LDFLAGS) $(OBJECTS) $(LIBRARY)
run: $(TARGET)
$(TARGET)
clean:
rm -f ${OBJECTS} ${TARGET} ${BINDING}
rm -f $(OBJECTS) $(TARGET) $(BINDING)
cargo clean

View file

@ -1,31 +1,33 @@
#include "vulkan/vulkan.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
printf("starting the portability test\n");
VkInstanceCreateInfo inst_info = {};
inst_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
inst_info.pNext = NULL;
inst_info.flags = 0;
inst_info.pApplicationInfo = NULL;
inst_info.enabledExtensionCount = 0;
inst_info.ppEnabledExtensionNames = NULL;
inst_info.enabledLayerCount = 0;
inst_info.ppEnabledLayerNames = NULL;
VkInstance inst;
VkInstance instance;
VkResult res;
res = vkCreateInstance(&inst_info, NULL, &inst);
res = vkCreateInstance(&inst_info, NULL, &instance);
if (res == VK_ERROR_INCOMPATIBLE_DRIVER) {
printf("cannot find a compatible Vulkan ICD\n");
exit(-1);
return -1;
} else if (res) {
printf("unknown error\n");
exit(-1);
return -1;
}
vkDestroyInstance(inst, NULL);
uint32_t gpu_count = 1;
VkPhysicalDevice physical_devices[1] = {};
res = vkEnumeratePhysicalDevices(instance, &gpu_count, physical_devices);
printf("\tvkEnumeratePhysicalDevices: res=%d count=%d\n", res, gpu_count);
assert(!res && gpu_count);
vkDestroyInstance(instance, NULL);
printf("done.\n");
return 0;
}

53
src/handle.rs Normal file
View file

@ -0,0 +1,53 @@
use std::{fmt, ops};
use std::marker::PhantomData;
#[repr(C)]
pub struct Handle<T> {
pointer: *mut u8,
marker: PhantomData<T>,
}
impl<T> Handle<T> {
pub fn new(value: T) -> Self {
Handle {
pointer: Box::into_raw(Box::new(value)) as _,
marker: PhantomData,
}
}
pub fn unwrap(self) -> Box<T> {
unsafe { Box::from_raw(self.pointer as _) }
}
}
impl<T> Clone for Handle<T> {
fn clone(&self) -> Self {
Handle {
pointer: self.pointer,
marker: PhantomData,
}
}
}
impl<T> Copy for Handle<T> {}
impl<T> ops::Deref for Handle<T> {
type Target = T;
fn deref(&self) -> &T {
unsafe { &*(self.pointer as *mut _) }
}
}
impl<T> ops::DerefMut for Handle<T> {
fn deref_mut(&mut self) -> &mut T {
unsafe { &mut*(self.pointer as *mut _) }
}
}
impl<T> fmt::Debug for Handle<T> {
fn fmt(&self, _formatter: &mut fmt::Formatter) -> fmt::Result {
//TODO
Ok(())
}
}

View file

@ -5,6 +5,13 @@
extern crate gfx_core as core;
extern crate gfx_backend_vulkan as back;
mod handle;
use std::{cmp, slice};
use core::Instance;
use back::Backend as B;
use handle::Handle;
/* automatically generated by rust-bindgen */
pub const VULKAN_H_: ::std::os::raw::c_uint = 1;
@ -451,36 +458,9 @@ pub type VkBool32 = u32;
pub type VkDeviceSize = u64;
pub type VkSampleMask = u32;
pub type VkInstance = *mut u8;
pub type VkInstance = Handle<back::Instance>;
pub type VkPhysicalDevice = Handle<<B as core::Backend>::Adapter>;
#[no_mangle]
pub extern fn vkCreateInstance(
_pCreateInfo: *const VkInstanceCreateInfo,
_pAllocator: *const VkAllocationCallbacks,
pInstance: *mut VkInstance,
) -> VkResult {
let instance = back::Instance::create("portability", 1);
let pointer = Box::into_raw(Box::new(instance));
unsafe { *pInstance = pointer as *mut _ };
return VkResult::VK_SUCCESS;
}
#[no_mangle]
pub extern fn vkDestroyInstance(
instance: VkInstance,
_pAllocator: *const VkAllocationCallbacks,
) {
let _instance = unsafe { Box::from_raw(instance as *mut _) };
//let it drop
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct VkPhysicalDevice_T {
_unused: [u8; 0],
}
pub type VkPhysicalDevice = *mut VkPhysicalDevice_T;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct VkDevice_T {
@ -3472,23 +3452,7 @@ pub struct VkDrawIndirectCommand {
impl Clone for VkDrawIndirectCommand {
fn clone(&self) -> Self { *self }
}
pub type PFN_vkCreateInstance =
::std::option::Option<unsafe extern "C" fn(pCreateInfo:
*const VkInstanceCreateInfo,
pAllocator:
*const VkAllocationCallbacks,
pInstance: *mut VkInstance)
-> VkResult>;
pub type PFN_vkDestroyInstance =
::std::option::Option<unsafe extern "C" fn(instance: VkInstance,
pAllocator:
*const VkAllocationCallbacks)>;
pub type PFN_vkEnumeratePhysicalDevices =
::std::option::Option<unsafe extern "C" fn(instance: VkInstance,
pPhysicalDeviceCount: *mut u32,
pPhysicalDevices:
*mut VkPhysicalDevice)
-> VkResult>;
pub type PFN_vkGetPhysicalDeviceFeatures =
::std::option::Option<unsafe extern "C" fn(physicalDevice:
VkPhysicalDevice,
@ -4340,12 +4304,45 @@ pub type PFN_vkCmdExecuteCommands =
pCommandBuffers:
*const VkCommandBuffer)>;
extern "C" {
pub fn vkEnumeratePhysicalDevices(instance: VkInstance,
pPhysicalDeviceCount: *mut u32,
pPhysicalDevices: *mut VkPhysicalDevice)
-> VkResult;
#[no_mangle]
pub extern fn vkCreateInstance(
_pCreateInfo: *const VkInstanceCreateInfo,
_pAllocator: *const VkAllocationCallbacks,
pInstance: *mut VkInstance,
) -> VkResult {
let instance = back::Instance::create("portability", 1);
unsafe { *pInstance = Handle::new(instance) };
VkResult::VK_SUCCESS
}
#[no_mangle]
pub extern fn vkDestroyInstance(
instance: VkInstance,
_pAllocator: *const VkAllocationCallbacks,
) {
instance.unwrap();
//let it drop
}
#[no_mangle]
pub extern fn vkEnumeratePhysicalDevices(
instance: VkInstance,
pPhysicalDeviceCount: *mut u32,
pPhysicalDevices: *mut VkPhysicalDevice,
) -> VkResult {
let adapters = instance.enumerate_adapters();
let output = unsafe { slice::from_raw_parts_mut(pPhysicalDevices, *pPhysicalDeviceCount as _) };
let count = cmp::min(adapters.len(), output.len());
for (out, adapter) in output.iter_mut().zip(adapters.into_iter()) {
*out = Handle::new(adapter);
}
unsafe { *pPhysicalDeviceCount = count as _ };
VkResult::VK_SUCCESS
}
extern "C" {
pub fn vkGetPhysicalDeviceFeatures(physicalDevice: VkPhysicalDevice,
pFeatures: