mirror of
https://github.com/italicsjenga/portability.git
synced 2024-11-27 01:11:32 +11:00
Merge #60
60: Fix device leaking, part 3 r=msiglreith a=kvark Co-authored-by: Dzmitry Malyshau <kvark@mozilla.com>
This commit is contained in:
commit
2fce3aa575
8
Cargo.lock
generated
8
Cargo.lock
generated
|
@ -220,7 +220,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gfx-backend-dx12"
|
name = "gfx-backend-dx12"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/gfx-rs/gfx#c0ba2019c613432d74e2f13d95a398b220c9c9c4"
|
source = "git+https://github.com/gfx-rs/gfx#58b16b27c2cde0a44e08b2c509970d314398033f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"derivative 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"derivative 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -236,7 +236,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gfx-backend-metal"
|
name = "gfx-backend-metal"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/gfx-rs/gfx#c0ba2019c613432d74e2f13d95a398b220c9c9c4"
|
source = "git+https://github.com/gfx-rs/gfx#58b16b27c2cde0a44e08b2c509970d314398033f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"block 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"block 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"cocoa 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cocoa 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -255,7 +255,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gfx-backend-vulkan"
|
name = "gfx-backend-vulkan"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/gfx-rs/gfx#c0ba2019c613432d74e2f13d95a398b220c9c9c4"
|
source = "git+https://github.com/gfx-rs/gfx#58b16b27c2cde0a44e08b2c509970d314398033f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ash 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ash 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -273,7 +273,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gfx-hal"
|
name = "gfx-hal"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/gfx-rs/gfx#c0ba2019c613432d74e2f13d95a398b220c9c9c4"
|
source = "git+https://github.com/gfx-rs/gfx#58b16b27c2cde0a44e08b2c509970d314398033f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
|
12
Makefile
12
Makefile
|
@ -7,9 +7,11 @@ OBJECTS=$(NATIVE_DIR)/test.o $(NATIVE_DIR)/window.o
|
||||||
LIB_EXTENSION=
|
LIB_EXTENSION=
|
||||||
TEST_LIST=conformance/deqp.txt
|
TEST_LIST=conformance/deqp.txt
|
||||||
TEST_LIST_SOURCE=$(CTS_DIR)/external/vulkancts/mustpass/1.0.2/vk-default.txt
|
TEST_LIST_SOURCE=$(CTS_DIR)/external/vulkancts/mustpass/1.0.2/vk-default.txt
|
||||||
|
DEQP=$(CTS_DIR)/build/external/vulkancts/modules/vulkan/deqp-vk
|
||||||
|
|
||||||
RUST_BACKTRACE:=1
|
RUST_BACKTRACE:=1
|
||||||
BACKEND:=gl
|
BACKEND:=gl
|
||||||
|
DEBUGGER=rust-gdb --args
|
||||||
|
|
||||||
CC=g++
|
CC=g++
|
||||||
CFLAGS=-std=c++11 -ggdb -O0 -I$(VULKAN_DIR)
|
CFLAGS=-std=c++11 -ggdb -O0 -I$(VULKAN_DIR)
|
||||||
|
@ -30,6 +32,7 @@ else
|
||||||
ifeq ($(UNAME_S),Darwin)
|
ifeq ($(UNAME_S),Darwin)
|
||||||
LDFLAGS=-lpthread -ldl -lm
|
LDFLAGS=-lpthread -ldl -lm
|
||||||
BACKEND=metal
|
BACKEND=metal
|
||||||
|
DEBUGGER=rust-lldb --
|
||||||
LIB_EXTENSION=dylib
|
LIB_EXTENSION=dylib
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
@ -64,13 +67,16 @@ $(TEST_LIST): $(TEST_LIST_SOURCE)
|
||||||
cat $(TEST_LIST_SOURCE) | grep -v -e ".event" -e "query" >$(TEST_LIST)
|
cat $(TEST_LIST_SOURCE) | grep -v -e ".event" -e "query" >$(TEST_LIST)
|
||||||
|
|
||||||
cts: $(TARGET) $(TEST_LIST)
|
cts: $(TARGET) $(TEST_LIST)
|
||||||
-LD_LIBRARY_PATH=$(FULL_LIBRARY_PATH) $(CTS_DIR)/build/external/vulkancts/modules/vulkan/deqp-vk --deqp-caselist-file=$(TEST_LIST)
|
-LD_LIBRARY_PATH=$(FULL_LIBRARY_PATH) $(DEQP) --deqp-caselist-file=$(TEST_LIST)
|
||||||
python $(CTS_DIR)/scripts/log/log_to_xml.py TestResults.qpa conformance/last.xml
|
python $(CTS_DIR)/scripts/log/log_to_xml.py TestResults.qpa conformance/last.xml
|
||||||
mv TestResults.qpa conformance/last.qpa
|
mv TestResults.qpa conformance/last.qpa
|
||||||
firefox conformance/last.xml
|
firefox conformance/last.xml
|
||||||
|
|
||||||
cts-debug: $(TARGET) $(TEST_LIST)
|
cts-pick: $(TARGET)
|
||||||
LD_LIBRARY_PATH=$(FULL_LIBRARY_PATH) rust-lldb $(CTS_DIR)/build/external/vulkancts/modules/vulkan/deqp-vk -- --deqp-caselist-file=$(TEST_LIST)
|
-LD_LIBRARY_PATH=$(FULL_LIBRARY_PATH) $(DEQP) -n $(name)
|
||||||
|
|
||||||
|
cts-debug: $(TARGET)
|
||||||
|
LD_LIBRARY_PATH=$(FULL_LIBRARY_PATH) $(DEBUGGER) $(DEQP) -n $(name)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f $(OBJECTS) $(TARGET) $(BINDING)
|
rm -f $(OBJECTS) $(TARGET) $(BINDING)
|
||||||
|
|
|
@ -8,14 +8,11 @@ This is a prototype library implementing [Vulkan Portability Initiative](https:/
|
||||||
|
|
||||||
| gfx-rs Backend | Total cases | Pass | Fail | Quality warning | Compatibility warning | Not supported | Resource error | Internal error | Timeout | Crash |
|
| gfx-rs Backend | Total cases | Pass | Fail | Quality warning | Compatibility warning | Not supported | Resource error | Internal error | Timeout | Crash |
|
||||||
| -------- | ---- | ---- | --- | -- | - | ---- | - | - | - | - |
|
| -------- | ---- | ---- | --- | -- | - | ---- | - | - | - | - |
|
||||||
| *Vulkan* | 7723 | 2236 | 66 | 34 | 0 | 5387 | 0 | 0 | 0 | 0 |
|
| *Vulkan* | 7759 | 2155 | 131 | 34 | 0 | 5439 | 0 | 0 | 0 | 0 |
|
||||||
| *DX12* | 3563 | 1243 | 73 | 0 | 0 | 2247 | 0 | 0 | 0 | 0 |
|
| *DX12* | 3563 | 1243 | 73 | 0 | 0 | 2247 | 0 | 0 | 0 | 0 |
|
||||||
| *Metal* | 3538 | 1215 | 109 | 0 | 0 | 2214 | 0 | 0 | 0 | 0 |
|
| *Metal* | 3538 | 1215 | 109 | 0 | 0 | 2214 | 0 | 0 | 0 | 0 |
|
||||||
|
|
||||||
DX12 and Metal measurement are currently out of date.
|
Currently stopping on "dEQP-VK.api.command_buffers.render_pass_continue".
|
||||||
|
|
||||||
Currently stopping with:
|
|
||||||
> (RADV ARCH VULKAN) radv_BeginCommandBuffer: Assertion `pBeginInfo->pInheritanceInfo' failed.
|
|
||||||
|
|
||||||
Please visit [our wiki](https://github.com/gfx-rs/portability/wiki/Vulkan-CTS-status) for CTS hookup instructions. Once everything is set, you can generate the new results by calling `make cts` on Unix systems.
|
Please visit [our wiki](https://github.com/gfx-rs/portability/wiki/Vulkan-CTS-status) for CTS hookup instructions. Once everything is set, you can generate the new results by calling `make cts` on Unix systems.
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use hal::{buffer, command, error, format, image, memory, pass, pso, window};
|
use hal::{buffer, command, error, format, image, memory, pass, pso, query, window};
|
||||||
use hal::{IndexType, PatchSize, Primitive};
|
use hal::{IndexType, PatchSize, Primitive};
|
||||||
|
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
@ -706,3 +706,13 @@ pub fn map_index_type(ty: VkIndexType) -> IndexType {
|
||||||
_ => panic!("Unexpected index type: {:?}", ty),
|
_ => panic!("Unexpected index type: {:?}", ty),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn map_query_control(flags: VkQueryControlFlags) -> query::QueryControl {
|
||||||
|
// Vulkan and HAL flags are equal
|
||||||
|
unsafe { mem::transmute(flags) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn map_pipeline_statistics(flags: VkQueryPipelineStatisticFlags) -> query::PipelineStatistic {
|
||||||
|
// Vulkan and HAL flags are equal
|
||||||
|
unsafe { mem::transmute(flags) }
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use VK_NULL_HANDLE;
|
use VK_NULL_HANDLE;
|
||||||
use std::{borrow, fmt, ops};
|
use std::{borrow, cmp, fmt, ops};
|
||||||
|
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
@ -15,12 +15,20 @@ impl<T> Handle<T> {
|
||||||
Handle(VK_NULL_HANDLE as *mut _)
|
Handle(VK_NULL_HANDLE as *mut _)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unbox(self) -> T {
|
pub fn unbox(self) -> Option<T> {
|
||||||
*unsafe { Box::from_raw(self.0) }
|
if self.0 == VK_NULL_HANDLE as *mut T {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(*unsafe { Box::from_raw(self.0) })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_null(&self) -> bool {
|
pub fn as_ref(&self) -> Option<&T> {
|
||||||
self.0 == VK_NULL_HANDLE as *mut T
|
if self.0 == VK_NULL_HANDLE as *mut T {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(unsafe { &*self.0 })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,6 +59,12 @@ impl<T> borrow::Borrow<T> for Handle<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T> cmp::PartialEq for Handle<T> {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
self.0.eq(&other.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T> fmt::Debug for Handle<T> {
|
impl<T> fmt::Debug for Handle<T> {
|
||||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(formatter, "Handle({:p})", self.0)
|
write!(formatter, "Handle({:p})", self.0)
|
||||||
|
@ -65,7 +79,7 @@ pub type DispatchHandle<T> = Handle<T>;
|
||||||
#[cfg(feature = "dispatch")]
|
#[cfg(feature = "dispatch")]
|
||||||
mod dispatch {
|
mod dispatch {
|
||||||
use VK_NULL_HANDLE;
|
use VK_NULL_HANDLE;
|
||||||
use std::{borrow, fmt, ops};
|
use std::{borrow, cmp, fmt, ops};
|
||||||
|
|
||||||
const ICD_LOADER_MAGIC: u64 = 0x01CDC0DE;
|
const ICD_LOADER_MAGIC: u64 = 0x01CDC0DE;
|
||||||
|
|
||||||
|
@ -82,12 +96,20 @@ mod dispatch {
|
||||||
DispatchHandle(VK_NULL_HANDLE as *mut _)
|
DispatchHandle(VK_NULL_HANDLE as *mut _)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unbox(self) -> T {
|
pub fn unbox(self) -> Option<T> {
|
||||||
unsafe { Box::from_raw(self.0) }.1
|
if self.0 == VK_NULL_HANDLE as *mut (u64, T) {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(unsafe { Box::from_raw(self.0) }.1)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_null(&self) -> bool {
|
pub fn as_ref(&self) -> Option<&T> {
|
||||||
self.0 == VK_NULL_HANDLE as *mut _
|
if self.0 == VK_NULL_HANDLE as *mut (u64, T) {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(unsafe { &(*self.0).1 })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,6 +140,12 @@ mod dispatch {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T> cmp::PartialEq for DispatchHandle<T> {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
self.0.eq(&other.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T> fmt::Debug for DispatchHandle<T> {
|
impl<T> fmt::Debug for DispatchHandle<T> {
|
||||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(formatter, "DispatchHandle({:p})", self.0)
|
write!(formatter, "DispatchHandle({:p})", self.0)
|
||||||
|
|
|
@ -60,8 +60,9 @@ pub extern "C" fn gfxDestroyInstance(
|
||||||
instance: VkInstance,
|
instance: VkInstance,
|
||||||
_pAllocator: *const VkAllocationCallbacks,
|
_pAllocator: *const VkAllocationCallbacks,
|
||||||
) {
|
) {
|
||||||
let _ = instance.unbox();
|
for adapter in instance.unbox().unwrap().adapters {
|
||||||
//let it drop
|
let _ = adapter.unbox();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -567,7 +568,7 @@ pub extern "C" fn gfxCreateDevice(
|
||||||
#[inline]
|
#[inline]
|
||||||
pub extern "C" fn gfxDestroyDevice(gpu: VkDevice, _pAllocator: *const VkAllocationCallbacks) {
|
pub extern "C" fn gfxDestroyDevice(gpu: VkDevice, _pAllocator: *const VkAllocationCallbacks) {
|
||||||
// release all the owned command queues
|
// release all the owned command queues
|
||||||
for (_, family) in gpu.unbox().queues {
|
for (_, family) in gpu.unbox().unwrap().queues {
|
||||||
for queue in family {
|
for queue in family {
|
||||||
let _ = queue.unbox();
|
let _ = queue.unbox();
|
||||||
}
|
}
|
||||||
|
@ -747,9 +748,7 @@ pub extern "C" fn gfxQueueSubmit(
|
||||||
signal_semaphores: &signal_semaphores,
|
signal_semaphores: &signal_semaphores,
|
||||||
};
|
};
|
||||||
|
|
||||||
let fence = if fence.is_null() { None } else { Some(&*fence) };
|
unsafe { queue.submit_raw(submission, fence.as_ref()); }
|
||||||
|
|
||||||
unsafe { queue.submit_raw(submission, fence); }
|
|
||||||
|
|
||||||
VkResult::VK_SUCCESS
|
VkResult::VK_SUCCESS
|
||||||
}
|
}
|
||||||
|
@ -789,7 +788,9 @@ pub extern "C" fn gfxFreeMemory(
|
||||||
memory: VkDeviceMemory,
|
memory: VkDeviceMemory,
|
||||||
_pAllocator: *const VkAllocationCallbacks,
|
_pAllocator: *const VkAllocationCallbacks,
|
||||||
) {
|
) {
|
||||||
gpu.device.free_memory(memory.unbox());
|
if let Some(mem) = memory.unbox() {
|
||||||
|
gpu.device.free_memory(mem);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
pub extern "C" fn gfxMapMemory(
|
pub extern "C" fn gfxMapMemory(
|
||||||
|
@ -992,7 +993,9 @@ pub extern "C" fn gfxDestroyFence(
|
||||||
fence: VkFence,
|
fence: VkFence,
|
||||||
_pAllocator: *const VkAllocationCallbacks,
|
_pAllocator: *const VkAllocationCallbacks,
|
||||||
) {
|
) {
|
||||||
gpu.device.destroy_fence(fence.unbox());
|
if let Some(fence) = fence.unbox() {
|
||||||
|
gpu.device.destroy_fence(fence);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
pub extern "C" fn gfxResetFences(
|
pub extern "C" fn gfxResetFences(
|
||||||
|
@ -1065,7 +1068,9 @@ pub extern "C" fn gfxDestroySemaphore(
|
||||||
semaphore: VkSemaphore,
|
semaphore: VkSemaphore,
|
||||||
_pAllocator: *const VkAllocationCallbacks,
|
_pAllocator: *const VkAllocationCallbacks,
|
||||||
) {
|
) {
|
||||||
gpu.device.destroy_semaphore(semaphore.unbox());
|
if let Some(sem) = semaphore.unbox() {
|
||||||
|
gpu.device.destroy_semaphore(sem);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
pub extern "C" fn gfxCreateEvent(
|
pub extern "C" fn gfxCreateEvent(
|
||||||
|
@ -1154,13 +1159,12 @@ pub extern "C" fn gfxDestroyBuffer(
|
||||||
buffer: VkBuffer,
|
buffer: VkBuffer,
|
||||||
_pAllocator: *const VkAllocationCallbacks,
|
_pAllocator: *const VkAllocationCallbacks,
|
||||||
) {
|
) {
|
||||||
if !buffer.is_null() {
|
|
||||||
match buffer.unbox() {
|
match buffer.unbox() {
|
||||||
Buffer::Buffer(buffer) => gpu.device.destroy_buffer(buffer),
|
Some(Buffer::Buffer(buffer)) => gpu.device.destroy_buffer(buffer),
|
||||||
Buffer::Unbound(_) => {
|
Some(Buffer::Unbound(_)) => {
|
||||||
warn!("Trying to destroy a non-bound buffer, ignoring");
|
warn!("Trying to destroy a non-bound buffer, ignoring");
|
||||||
}
|
}
|
||||||
}
|
None => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -1194,8 +1198,8 @@ pub extern "C" fn gfxDestroyBufferView(
|
||||||
view: VkBufferView,
|
view: VkBufferView,
|
||||||
_pAllocator: *const VkAllocationCallbacks,
|
_pAllocator: *const VkAllocationCallbacks,
|
||||||
) {
|
) {
|
||||||
if !view.is_null() {
|
if let Some(v) = view.unbox() {
|
||||||
gpu.device.destroy_buffer_view(view.unbox());
|
gpu.device.destroy_buffer_view(v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -1237,13 +1241,12 @@ pub extern "C" fn gfxDestroyImage(
|
||||||
image: VkImage,
|
image: VkImage,
|
||||||
_pAllocator: *const VkAllocationCallbacks,
|
_pAllocator: *const VkAllocationCallbacks,
|
||||||
) {
|
) {
|
||||||
if !image.is_null() {
|
|
||||||
match image.unbox() {
|
match image.unbox() {
|
||||||
Image::Image(image) => gpu.device.destroy_image(image),
|
Some(Image::Image(image)) => gpu.device.destroy_image(image),
|
||||||
Image::Unbound(_) => {
|
Some(Image::Unbound(_)) => {
|
||||||
warn!("Trying to destroy a non-bound image, ignoring");
|
warn!("Trying to destroy a non-bound image, ignoring");
|
||||||
}
|
}
|
||||||
}
|
None => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -1294,7 +1297,9 @@ pub extern "C" fn gfxDestroyImageView(
|
||||||
imageView: VkImageView,
|
imageView: VkImageView,
|
||||||
_pAllocator: *const VkAllocationCallbacks,
|
_pAllocator: *const VkAllocationCallbacks,
|
||||||
) {
|
) {
|
||||||
gpu.device.destroy_image_view(imageView.unbox())
|
if let Some(view) = imageView.unbox() {
|
||||||
|
gpu.device.destroy_image_view(view);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
pub extern "C" fn gfxCreateShaderModule(
|
pub extern "C" fn gfxCreateShaderModule(
|
||||||
|
@ -1324,7 +1329,9 @@ pub extern "C" fn gfxDestroyShaderModule(
|
||||||
shaderModule: VkShaderModule,
|
shaderModule: VkShaderModule,
|
||||||
_pAllocator: *const VkAllocationCallbacks,
|
_pAllocator: *const VkAllocationCallbacks,
|
||||||
) {
|
) {
|
||||||
gpu.device.destroy_shader_module(shaderModule.unbox());
|
if let Some(module) = shaderModule.unbox() {
|
||||||
|
gpu.device.destroy_shader_module(module);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
pub extern "C" fn gfxCreatePipelineCache(
|
pub extern "C" fn gfxCreatePipelineCache(
|
||||||
|
@ -1690,8 +1697,8 @@ pub extern "C" fn gfxCreateGraphicsPipelines(
|
||||||
let parent = {
|
let parent = {
|
||||||
let is_derivative = info.flags & VkPipelineCreateFlagBits::VK_PIPELINE_CREATE_DERIVATIVE_BIT as u32 != 0;
|
let is_derivative = info.flags & VkPipelineCreateFlagBits::VK_PIPELINE_CREATE_DERIVATIVE_BIT as u32 != 0;
|
||||||
|
|
||||||
if !info.basePipelineHandle.is_null() {
|
if let Some(base_pso) = info.basePipelineHandle.as_ref() {
|
||||||
match *info.basePipelineHandle {
|
match *base_pso {
|
||||||
Pipeline::Graphics(ref graphics) => pso::BasePipeline::Pipeline(graphics),
|
Pipeline::Graphics(ref graphics) => pso::BasePipeline::Pipeline(graphics),
|
||||||
Pipeline::Compute(_) => panic!("Base pipeline handle must be a graphics pipeline"),
|
Pipeline::Compute(_) => panic!("Base pipeline handle must be a graphics pipeline"),
|
||||||
}
|
}
|
||||||
|
@ -1751,11 +1758,10 @@ pub extern "C" fn gfxDestroyPipeline(
|
||||||
pipeline: VkPipeline,
|
pipeline: VkPipeline,
|
||||||
_pAllocator: *const VkAllocationCallbacks,
|
_pAllocator: *const VkAllocationCallbacks,
|
||||||
) {
|
) {
|
||||||
if !pipeline.is_null() {
|
|
||||||
match pipeline.unbox() {
|
match pipeline.unbox() {
|
||||||
Pipeline::Graphics(pipeline) => gpu.device.destroy_graphics_pipeline(pipeline),
|
Some(Pipeline::Graphics(pipeline)) => gpu.device.destroy_graphics_pipeline(pipeline),
|
||||||
Pipeline::Compute(pipeline) => gpu.device.destroy_compute_pipeline(pipeline),
|
Some(Pipeline::Compute(pipeline)) => gpu.device.destroy_compute_pipeline(pipeline),
|
||||||
}
|
None => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -1799,7 +1805,9 @@ pub extern "C" fn gfxDestroyPipelineLayout(
|
||||||
pipelineLayout: VkPipelineLayout,
|
pipelineLayout: VkPipelineLayout,
|
||||||
_pAllocator: *const VkAllocationCallbacks,
|
_pAllocator: *const VkAllocationCallbacks,
|
||||||
) {
|
) {
|
||||||
gpu.device.destroy_pipeline_layout(pipelineLayout.unbox());
|
if let Some(layout) = pipelineLayout.unbox() {
|
||||||
|
gpu.device.destroy_pipeline_layout(layout);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
pub extern "C" fn gfxCreateSampler(
|
pub extern "C" fn gfxCreateSampler(
|
||||||
|
@ -1835,7 +1843,9 @@ pub extern "C" fn gfxDestroySampler(
|
||||||
sampler: VkSampler,
|
sampler: VkSampler,
|
||||||
_pAllocator: *const VkAllocationCallbacks,
|
_pAllocator: *const VkAllocationCallbacks,
|
||||||
) {
|
) {
|
||||||
gpu.device.destroy_sampler(sampler.unbox());
|
if let Some(sam) = sampler.unbox() {
|
||||||
|
gpu.device.destroy_sampler(sam);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
pub extern "C" fn gfxCreateDescriptorSetLayout(
|
pub extern "C" fn gfxCreateDescriptorSetLayout(
|
||||||
|
@ -1878,7 +1888,9 @@ pub extern "C" fn gfxDestroyDescriptorSetLayout(
|
||||||
descriptorSetLayout: VkDescriptorSetLayout,
|
descriptorSetLayout: VkDescriptorSetLayout,
|
||||||
_pAllocator: *const VkAllocationCallbacks,
|
_pAllocator: *const VkAllocationCallbacks,
|
||||||
) {
|
) {
|
||||||
gpu.device.destroy_descriptor_set_layout(descriptorSetLayout.unbox());
|
if let Some(layout) = descriptorSetLayout.unbox() {
|
||||||
|
gpu.device.destroy_descriptor_set_layout(layout);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
pub extern "C" fn gfxCreateDescriptorPool(
|
pub extern "C" fn gfxCreateDescriptorPool(
|
||||||
|
@ -1918,7 +1930,9 @@ pub extern "C" fn gfxDestroyDescriptorPool(
|
||||||
descriptorPool: VkDescriptorPool,
|
descriptorPool: VkDescriptorPool,
|
||||||
_pAllocator: *const VkAllocationCallbacks,
|
_pAllocator: *const VkAllocationCallbacks,
|
||||||
) {
|
) {
|
||||||
gpu.device.destroy_descriptor_pool(descriptorPool.unbox());
|
if let Some(pool) = descriptorPool.unbox() {
|
||||||
|
gpu.device.destroy_descriptor_pool(pool);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
pub extern "C" fn gfxResetDescriptorPool(
|
pub extern "C" fn gfxResetDescriptorPool(
|
||||||
|
@ -2128,7 +2142,9 @@ pub extern "C" fn gfxDestroyFramebuffer(
|
||||||
framebuffer: VkFramebuffer,
|
framebuffer: VkFramebuffer,
|
||||||
_pAllocator: *const VkAllocationCallbacks,
|
_pAllocator: *const VkAllocationCallbacks,
|
||||||
) {
|
) {
|
||||||
gpu.device.destroy_framebuffer(framebuffer.unbox());
|
if let Some(fbo) = framebuffer.unbox() {
|
||||||
|
gpu.device.destroy_framebuffer(fbo);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
pub extern "C" fn gfxCreateRenderPass(
|
pub extern "C" fn gfxCreateRenderPass(
|
||||||
|
@ -2300,7 +2316,9 @@ pub extern "C" fn gfxDestroyRenderPass(
|
||||||
renderPass: VkRenderPass,
|
renderPass: VkRenderPass,
|
||||||
_pAllocator: *const VkAllocationCallbacks,
|
_pAllocator: *const VkAllocationCallbacks,
|
||||||
) {
|
) {
|
||||||
gpu.device.destroy_render_pass(renderPass.unbox());
|
if let Some(rp) = renderPass.unbox() {
|
||||||
|
gpu.device.destroy_render_pass(rp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
pub extern "C" fn gfxGetRenderAreaGranularity(
|
pub extern "C" fn gfxGetRenderAreaGranularity(
|
||||||
|
@ -2334,7 +2352,10 @@ pub extern "C" fn gfxCreateCommandPool(
|
||||||
flags |= CommandPoolCreateFlags::RESET_INDIVIDUAL;
|
flags |= CommandPoolCreateFlags::RESET_INDIVIDUAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
let pool = gpu.device.create_command_pool(family, flags);
|
let pool = CommandPool {
|
||||||
|
pool: gpu.device.create_command_pool(family, flags),
|
||||||
|
buffers: Vec::new(),
|
||||||
|
};
|
||||||
unsafe { *pCommandPool = Handle::new(pool) };
|
unsafe { *pCommandPool = Handle::new(pool) };
|
||||||
VkResult::VK_SUCCESS
|
VkResult::VK_SUCCESS
|
||||||
}
|
}
|
||||||
|
@ -2345,7 +2366,11 @@ pub extern "C" fn gfxDestroyCommandPool(
|
||||||
commandPool: VkCommandPool,
|
commandPool: VkCommandPool,
|
||||||
_pAllocator: *const VkAllocationCallbacks,
|
_pAllocator: *const VkAllocationCallbacks,
|
||||||
) {
|
) {
|
||||||
gpu.device.destroy_command_pool(commandPool.unbox());
|
let pool = commandPool.unbox().unwrap();
|
||||||
|
for cmd_buf in pool.buffers {
|
||||||
|
let _ = cmd_buf.unbox();
|
||||||
|
}
|
||||||
|
gpu.device.destroy_command_pool(pool.pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -2354,7 +2379,7 @@ pub extern "C" fn gfxResetCommandPool(
|
||||||
mut commandPool: VkCommandPool,
|
mut commandPool: VkCommandPool,
|
||||||
_flags: VkCommandPoolResetFlags,
|
_flags: VkCommandPoolResetFlags,
|
||||||
) -> VkResult {
|
) -> VkResult {
|
||||||
commandPool.reset();
|
commandPool.pool.reset();
|
||||||
VkResult::VK_SUCCESS
|
VkResult::VK_SUCCESS
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2373,12 +2398,13 @@ pub extern "C" fn gfxAllocateCommandBuffers(
|
||||||
|
|
||||||
let count = info.commandBufferCount as usize;
|
let count = info.commandBufferCount as usize;
|
||||||
|
|
||||||
let cmd_bufs = info.commandPool.allocate(count, level);
|
let cmd_bufs = info.commandPool.pool.allocate(count, level);
|
||||||
|
|
||||||
let output = unsafe { slice::from_raw_parts_mut(pCommandBuffers, count) };
|
let output = unsafe { slice::from_raw_parts_mut(pCommandBuffers, count) };
|
||||||
for (out, cmd_buf) in output.iter_mut().zip(cmd_bufs) {
|
for (out, cmd_buf) in output.iter_mut().zip(cmd_bufs) {
|
||||||
*out = DispatchHandle::new(cmd_buf);
|
*out = DispatchHandle::new(cmd_buf);
|
||||||
}
|
}
|
||||||
|
info.commandPool.buffers.extend_from_slice(output);
|
||||||
|
|
||||||
VkResult::VK_SUCCESS
|
VkResult::VK_SUCCESS
|
||||||
}
|
}
|
||||||
|
@ -2393,8 +2419,10 @@ pub extern "C" fn gfxFreeCommandBuffers(
|
||||||
let slice = unsafe {
|
let slice = unsafe {
|
||||||
slice::from_raw_parts(pCommandBuffers, commandBufferCount as _)
|
slice::from_raw_parts(pCommandBuffers, commandBufferCount as _)
|
||||||
};
|
};
|
||||||
let buffers = slice.iter().map(|buffer| buffer.unbox()).collect();
|
commandPool.buffers.retain(|buf| !slice.contains(buf));
|
||||||
unsafe { commandPool.free(buffers) };
|
|
||||||
|
let buffers = slice.iter().map(|buffer| buffer.unbox().unwrap()).collect();
|
||||||
|
unsafe { commandPool.pool.free(buffers) };
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -2403,7 +2431,19 @@ pub extern "C" fn gfxBeginCommandBuffer(
|
||||||
pBeginInfo: *const VkCommandBufferBeginInfo,
|
pBeginInfo: *const VkCommandBufferBeginInfo,
|
||||||
) -> VkResult {
|
) -> VkResult {
|
||||||
let info = unsafe { &*pBeginInfo };
|
let info = unsafe { &*pBeginInfo };
|
||||||
let inheritance = com::CommandBufferInheritanceInfo::default();
|
let inheritance = match unsafe { info.pInheritanceInfo.as_ref() } {
|
||||||
|
Some(ii) => com::CommandBufferInheritanceInfo {
|
||||||
|
subpass: ii.renderPass.as_ref().map(|main_pass| pass::Subpass {
|
||||||
|
main_pass,
|
||||||
|
index: ii.subpass as _,
|
||||||
|
}),
|
||||||
|
framebuffer: ii.framebuffer.as_ref(),
|
||||||
|
occlusion_query_enable: ii.occlusionQueryEnable != VK_FALSE,
|
||||||
|
occlusion_query_flags: conv::map_query_control(ii.queryFlags),
|
||||||
|
pipeline_statistics: conv::map_pipeline_statistics(ii.pipelineStatistics),
|
||||||
|
},
|
||||||
|
None => com::CommandBufferInheritanceInfo::default(),
|
||||||
|
};
|
||||||
commandBuffer.begin(conv::map_cmd_buffer_usage(info.flags), inheritance);
|
commandBuffer.begin(conv::map_cmd_buffer_usage(info.flags), inheritance);
|
||||||
|
|
||||||
VkResult::VK_SUCCESS
|
VkResult::VK_SUCCESS
|
||||||
|
@ -2836,13 +2876,42 @@ pub extern "C" fn gfxCmdClearDepthStencilImage(
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
pub extern "C" fn gfxCmdClearAttachments(
|
pub extern "C" fn gfxCmdClearAttachments(
|
||||||
commandBuffer: VkCommandBuffer,
|
mut commandBuffer: VkCommandBuffer,
|
||||||
attachmentCount: u32,
|
attachmentCount: u32,
|
||||||
pAttachments: *const VkClearAttachment,
|
pAttachments: *const VkClearAttachment,
|
||||||
rectCount: u32,
|
rectCount: u32,
|
||||||
pRects: *const VkClearRect,
|
pRects: *const VkClearRect,
|
||||||
) {
|
) {
|
||||||
unimplemented!()
|
let attachments = unsafe {
|
||||||
|
slice::from_raw_parts(pAttachments, attachmentCount as _)
|
||||||
|
};
|
||||||
|
let rects = unsafe {
|
||||||
|
slice::from_raw_parts(pRects, rectCount as _)
|
||||||
|
};
|
||||||
|
commandBuffer.clear_attachments(
|
||||||
|
attachments.iter().map(|at| {
|
||||||
|
use VkImageAspectFlagBits::*;
|
||||||
|
if at.aspectMask & VK_IMAGE_ASPECT_COLOR_BIT as u32 != 0 {
|
||||||
|
com::AttachmentClear::Color(
|
||||||
|
at.colorAttachment as _,
|
||||||
|
unsafe { at.clearValue.color.float32 }.into(), //TODO!
|
||||||
|
)
|
||||||
|
} else
|
||||||
|
if at.aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT as u32 != 0 {
|
||||||
|
com::AttachmentClear::Depth(unsafe {
|
||||||
|
at.clearValue.depthStencil.depth
|
||||||
|
})
|
||||||
|
} else
|
||||||
|
if at.aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT as u32 != 0 {
|
||||||
|
com::AttachmentClear::Stencil(unsafe {
|
||||||
|
at.clearValue.depthStencil.stencil
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
panic!("Unexpected mask {:?}", at.aspectMask);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
rects.iter().map(|r| conv::map_rect(&r.rect)), //TODO: layers!
|
||||||
|
);
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
pub extern "C" fn gfxCmdResolveImage(
|
pub extern "C" fn gfxCmdResolveImage(
|
||||||
|
@ -3075,11 +3144,14 @@ pub extern "C" fn gfxCmdEndRenderPass(mut commandBuffer: VkCommandBuffer) {
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
pub extern "C" fn gfxCmdExecuteCommands(
|
pub extern "C" fn gfxCmdExecuteCommands(
|
||||||
commandBuffer: VkCommandBuffer,
|
mut commandBuffer: VkCommandBuffer,
|
||||||
commandBufferCount: u32,
|
commandBufferCount: u32,
|
||||||
pCommandBuffers: *const VkCommandBuffer,
|
pCommandBuffers: *const VkCommandBuffer,
|
||||||
) {
|
) {
|
||||||
unimplemented!()
|
let cmd_buffers = unsafe {
|
||||||
|
slice::from_raw_parts(pCommandBuffers, commandBufferCount as _)
|
||||||
|
};
|
||||||
|
commandBuffer.execute_commands(cmd_buffers.iter().map(|cb| *cb));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -3448,7 +3520,10 @@ pub extern "C" fn gfxCreateWin32SurfaceKHR(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[cfg(not(target_os = "windows"))]
|
#[cfg(not(target_os = "windows"))]
|
||||||
|
{
|
||||||
|
let _ = (instance, info, pSurface);
|
||||||
unreachable!()
|
unreachable!()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pub extern "C" fn gfxCreateXcbSurfaceKHR(
|
pub extern "C" fn gfxCreateXcbSurfaceKHR(
|
||||||
instance: VkInstance,
|
instance: VkInstance,
|
||||||
|
@ -3469,7 +3544,10 @@ pub extern "C" fn gfxCreateXcbSurfaceKHR(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[cfg(not(all(feature = "gfx-backend-vulkan", target_os = "linux")))]
|
#[cfg(not(all(feature = "gfx-backend-vulkan", target_os = "linux")))]
|
||||||
|
{
|
||||||
|
let _ = (instance, info, pSurface);
|
||||||
unreachable!()
|
unreachable!()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
pub extern "C" fn gfxAcquireNextImageKHR(
|
pub extern "C" fn gfxAcquireNextImageKHR(
|
||||||
|
@ -3480,10 +3558,9 @@ pub extern "C" fn gfxAcquireNextImageKHR(
|
||||||
fence: VkFence,
|
fence: VkFence,
|
||||||
pImageIndex: *mut u32,
|
pImageIndex: *mut u32,
|
||||||
) -> VkResult {
|
) -> VkResult {
|
||||||
let sync = if !semaphore.is_null() {
|
let sync = match semaphore.as_ref() {
|
||||||
FrameSync::Semaphore(&*semaphore)
|
Some(sem) => FrameSync::Semaphore(sem),
|
||||||
} else {
|
None => FrameSync::Fence(&*fence),
|
||||||
FrameSync::Fence(&*fence)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let frame = swapchain.raw.acquire_frame(sync);
|
let frame = swapchain.raw.acquire_frame(sync);
|
||||||
|
|
|
@ -32,17 +32,11 @@ pub use impls::*;
|
||||||
|
|
||||||
|
|
||||||
// Vulkan objects
|
// Vulkan objects
|
||||||
pub type VkPhysicalDevice = Handle<hal::Adapter<B>>;
|
|
||||||
|
|
||||||
pub struct RawInstance {
|
|
||||||
pub backend: back::Instance,
|
|
||||||
pub adapters: Vec<VkPhysicalDevice>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub type VkInstance = Handle<RawInstance>;
|
pub type VkInstance = Handle<RawInstance>;
|
||||||
|
pub type VkPhysicalDevice = Handle<hal::Adapter<B>>;
|
||||||
pub type VkDevice = DispatchHandle<Gpu<B>>;
|
pub type VkDevice = DispatchHandle<Gpu<B>>;
|
||||||
pub type VkQueue = DispatchHandle<<B as hal::Backend>::CommandQueue>;
|
pub type VkQueue = DispatchHandle<<B as hal::Backend>::CommandQueue>;
|
||||||
pub type VkCommandPool = Handle<<B as hal::Backend>::CommandPool>;
|
pub type VkCommandPool = Handle<CommandPool<B>>;
|
||||||
pub type VkCommandBuffer = DispatchHandle<<B as hal::Backend>::CommandBuffer>;
|
pub type VkCommandBuffer = DispatchHandle<<B as hal::Backend>::CommandBuffer>;
|
||||||
pub type VkDeviceMemory = Handle<<B as hal::Backend>::Memory>;
|
pub type VkDeviceMemory = Handle<<B as hal::Backend>::Memory>;
|
||||||
pub type VkDescriptorSetLayout = Handle<<B as hal::Backend>::DescriptorSetLayout>;
|
pub type VkDescriptorSetLayout = Handle<<B as hal::Backend>::DescriptorSetLayout>;
|
||||||
|
@ -63,6 +57,11 @@ pub type VkPipeline = Handle<Pipeline<B>>;
|
||||||
|
|
||||||
pub type QueueFamilyIndex = u32;
|
pub type QueueFamilyIndex = u32;
|
||||||
|
|
||||||
|
pub struct RawInstance {
|
||||||
|
pub backend: back::Instance,
|
||||||
|
pub adapters: Vec<VkPhysicalDevice>,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Gpu<B: hal::Backend> {
|
pub struct Gpu<B: hal::Backend> {
|
||||||
device: B::Device,
|
device: B::Device,
|
||||||
queues: HashMap<QueueFamilyIndex, Vec<VkQueue>>,
|
queues: HashMap<QueueFamilyIndex, Vec<VkQueue>>,
|
||||||
|
@ -83,6 +82,11 @@ pub enum Buffer<B: hal::Backend> {
|
||||||
Unbound(B::UnboundBuffer),
|
Unbound(B::UnboundBuffer),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct CommandPool<B: hal::Backend> {
|
||||||
|
pool: B::CommandPool,
|
||||||
|
buffers: Vec<VkCommandBuffer>,
|
||||||
|
}
|
||||||
|
|
||||||
//NOTE: all *KHR types have to be pure `Handle` things for compatibility with
|
//NOTE: all *KHR types have to be pure `Handle` things for compatibility with
|
||||||
//`VK_DEFINE_NON_DISPATCHABLE_HANDLE` used in `vulkan.h`
|
//`VK_DEFINE_NON_DISPATCHABLE_HANDLE` used in `vulkan.h`
|
||||||
pub type VkSurfaceKHR = Handle<<B as hal::Backend>::Surface>;
|
pub type VkSurfaceKHR = Handle<<B as hal::Backend>::Surface>;
|
||||||
|
|
|
@ -7,7 +7,7 @@ use portability_gfx::*;
|
||||||
|
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ptr;
|
|
||||||
|
|
||||||
const ICD_VERSION: u32 = 5;
|
const ICD_VERSION: u32 = 5;
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ pub extern "C" fn vk_icdNegotiateLoaderICDInterfaceVersion(
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn vk_icdGetPhysicalDeviceProcAddr(
|
pub extern "C" fn vk_icdGetPhysicalDeviceProcAddr(
|
||||||
instance: VkInstance,
|
_instance: VkInstance,
|
||||||
pName: *const ::std::os::raw::c_char,
|
pName: *const ::std::os::raw::c_char,
|
||||||
) -> PFN_vkVoidFunction {
|
) -> PFN_vkVoidFunction {
|
||||||
let name = unsafe { CStr::from_ptr(pName) };
|
let name = unsafe { CStr::from_ptr(pName) };
|
||||||
|
|
Loading…
Reference in a new issue