mirror of
https://github.com/italicsjenga/portability.git
synced 2024-11-25 08:21:31 +11:00
Proper static lib, enumerate_adapters
This commit is contained in:
parent
7f30e22a05
commit
70cf6476c3
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -1,7 +1,4 @@
|
||||||
/target/
|
/target/
|
||||||
native/test
|
|
||||||
native/test.o
|
|
||||||
native/vulkan
|
native/vulkan
|
||||||
src/original.rs
|
|
||||||
**/*.rs.bk
|
**/*.rs.bk
|
||||||
Cargo.lock
|
Cargo.lock
|
||||||
|
|
|
@ -4,9 +4,9 @@ version = "0.1.0"
|
||||||
authors = ["Dzmitry Malyshau <kvark@mozilla.com>"]
|
authors = ["Dzmitry Malyshau <kvark@mozilla.com>"]
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
name = "vulkan"
|
name = "portability"
|
||||||
crate-type = ["dylib"]
|
crate-type = ["staticlib"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
gfx_core = { path = "../gfx/src/core" }
|
gfx_core = { path = "../gfx/src/core" }
|
||||||
gfx_backend_vulkan = { path = "../gfx/src/backend/vulkan" }
|
gfx_backend_vulkan = { path = "../gfx/src/backend/vulkan", features = ["portable"] }
|
||||||
|
|
38
Makefile
38
Makefile
|
@ -1,23 +1,33 @@
|
||||||
|
CC=gcc
|
||||||
|
CFLAGS=
|
||||||
|
DEPS=
|
||||||
|
LDFLAGS=-lpthread -ldl -lm
|
||||||
|
|
||||||
HEADER=native/vulkan/vulkan.h
|
HEADER=native/vulkan/vulkan.h
|
||||||
BINDING=src/original.rs
|
BINDING=target/vulkan.rs
|
||||||
TARGET=native/test
|
NATIVE_DIR=target/native
|
||||||
OBJECTS=native/test.o
|
TARGET=$(NATIVE_DIR)/test
|
||||||
OUTPUT_DIR=target/debug
|
OBJECTS=$(NATIVE_DIR)/test.o
|
||||||
OUTPUT=${OUTPUT_DIR}/libvulkan.a
|
LIBRARY=target/debug/libportability.a
|
||||||
|
|
||||||
all: ${TARGET}
|
all: $(TARGET)
|
||||||
|
|
||||||
${BINDING}: ${HEADER}
|
$(BINDING): $(HEADER)
|
||||||
bindgen --no-layout-tests --rustfmt-bindings ${HEADER} -o ${BINDING}
|
bindgen --no-layout-tests --rustfmt-bindings $(HEADER) -o $(BINDING)
|
||||||
|
|
||||||
portability: ${BINDING}
|
$(LIBRARY): $(BINDING) src/*.rs
|
||||||
cargo build
|
cargo build
|
||||||
|
mkdir -p target/native
|
||||||
|
|
||||||
${TARGET}: portability ${OBJECTS}
|
$(NATIVE_DIR)/%.o: native/%.c $(DEPS)
|
||||||
gcc -o ${TARGET} -L${OUTPUT_DIR} -lvulkan ${OBJECTS}
|
$(CC) -c -o $@ $< $(CFLAGS)
|
||||||
|
|
||||||
run: ${TARGET}
|
$(TARGET): $(LIBRARY) $(OBJECTS)
|
||||||
${TARGET}
|
$(CC) -o $(TARGET) $(LDFLAGS) $(OBJECTS) $(LIBRARY)
|
||||||
|
|
||||||
|
run: $(TARGET)
|
||||||
|
$(TARGET)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f ${OBJECTS} ${TARGET} ${BINDING}
|
rm -f $(OBJECTS) $(TARGET) $(BINDING)
|
||||||
|
cargo clean
|
||||||
|
|
|
@ -1,31 +1,33 @@
|
||||||
#include "vulkan/vulkan.h"
|
#include "vulkan/vulkan.h"
|
||||||
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
printf("starting the portability test\n");
|
||||||
|
|
||||||
VkInstanceCreateInfo inst_info = {};
|
VkInstanceCreateInfo inst_info = {};
|
||||||
inst_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_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;
|
VkResult res;
|
||||||
|
|
||||||
res = vkCreateInstance(&inst_info, NULL, &inst);
|
res = vkCreateInstance(&inst_info, NULL, &instance);
|
||||||
if (res == VK_ERROR_INCOMPATIBLE_DRIVER) {
|
if (res == VK_ERROR_INCOMPATIBLE_DRIVER) {
|
||||||
printf("cannot find a compatible Vulkan ICD\n");
|
printf("cannot find a compatible Vulkan ICD\n");
|
||||||
exit(-1);
|
return -1;
|
||||||
} else if (res) {
|
} else if (res) {
|
||||||
printf("unknown error\n");
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
53
src/handle.rs
Normal file
53
src/handle.rs
Normal 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(())
|
||||||
|
}
|
||||||
|
}
|
99
src/lib.rs
99
src/lib.rs
|
@ -5,6 +5,13 @@
|
||||||
extern crate gfx_core as core;
|
extern crate gfx_core as core;
|
||||||
extern crate gfx_backend_vulkan as back;
|
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 */
|
/* automatically generated by rust-bindgen */
|
||||||
|
|
||||||
pub const VULKAN_H_: ::std::os::raw::c_uint = 1;
|
pub const VULKAN_H_: ::std::os::raw::c_uint = 1;
|
||||||
|
@ -451,36 +458,9 @@ pub type VkBool32 = u32;
|
||||||
pub type VkDeviceSize = u64;
|
pub type VkDeviceSize = u64;
|
||||||
pub type VkSampleMask = u32;
|
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)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
pub struct VkDevice_T {
|
pub struct VkDevice_T {
|
||||||
|
@ -3472,23 +3452,7 @@ pub struct VkDrawIndirectCommand {
|
||||||
impl Clone for VkDrawIndirectCommand {
|
impl Clone for VkDrawIndirectCommand {
|
||||||
fn clone(&self) -> Self { *self }
|
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 =
|
pub type PFN_vkGetPhysicalDeviceFeatures =
|
||||||
::std::option::Option<unsafe extern "C" fn(physicalDevice:
|
::std::option::Option<unsafe extern "C" fn(physicalDevice:
|
||||||
VkPhysicalDevice,
|
VkPhysicalDevice,
|
||||||
|
@ -4340,12 +4304,45 @@ pub type PFN_vkCmdExecuteCommands =
|
||||||
pCommandBuffers:
|
pCommandBuffers:
|
||||||
*const VkCommandBuffer)>;
|
*const VkCommandBuffer)>;
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
pub fn vkEnumeratePhysicalDevices(instance: VkInstance,
|
#[no_mangle]
|
||||||
pPhysicalDeviceCount: *mut u32,
|
pub extern fn vkCreateInstance(
|
||||||
pPhysicalDevices: *mut VkPhysicalDevice)
|
_pCreateInfo: *const VkInstanceCreateInfo,
|
||||||
-> VkResult;
|
_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" {
|
extern "C" {
|
||||||
pub fn vkGetPhysicalDeviceFeatures(physicalDevice: VkPhysicalDevice,
|
pub fn vkGetPhysicalDeviceFeatures(physicalDevice: VkPhysicalDevice,
|
||||||
pFeatures:
|
pFeatures:
|
||||||
|
|
Loading…
Reference in a new issue