博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
gfx-hal Fence操作源码简析
阅读量:6246 次
发布时间:2019-06-22

本文共 5931 字,大约阅读时间需要 19 分钟。

2019.1.31 改标题

文档列表见:

Vulkan通过Fence确认队列操作是否执行完成。

创建Fence

使用Vulkan接口实现

VkFenceCreateInfo info;info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;info.pNext = nullptr;info.flags = signaled ? VK_FENCE_CREATE_SIGNALED_BIT : 0;VkResult err = vkCreateFence(mVkDevice, &info, nullptr, &mVkFence);// deal with (err != VK_ERROR_OUT_OF_HOST_MEMORY && err != VK_ERROR_OUT_OF_DEVICE_MEMORY);复制代码

使用gfx-hal接口实现

let mut fence = device.create_fence(false).expect("Can't create fence");/// Create a new fence object////// Fences are a synchronization primitive that **can** be used to insert a dependency from/// a queue to the host. Fences have two states - signaled and unsignaled. A fence **can** be/// signaled as part of the execution of a *queue submission* command. Fences **can** be unsignaled/// on the host with *reset_fences*. Fences **can** be waited on by the host with the/// *wait_for_fences* command, and the current state **can** be queried with *get_fence_status*.fn create_fence(&self, signaled: bool) -> Result
;复制代码

gfx-hal Vulkan模块源码

fn create_fence(&self, signaled: bool) -> Result
{ let info = vk::FenceCreateInfo { s_type: vk::StructureType::FENCE_CREATE_INFO, p_next: ptr::null(), flags: if signaled { vk::FenceCreateFlags::SIGNALED } else { vk::FenceCreateFlags::empty() }, }; let result = unsafe { self.raw.0.create_fence(&info, None) }; match result { Ok(fence) => Ok(n::Fence(fence)), Err(vk::Result::ERROR_OUT_OF_HOST_MEMORY) => { Err(d::OutOfMemory::OutOfHostMemory.into()) } Err(vk::Result::ERROR_OUT_OF_DEVICE_MEMORY) => { Err(d::OutOfMemory::OutOfDeviceMemory.into()) } _ => unreachable!(), }}复制代码

gfx-hal Metal模块源码

Metal目前没提供类似Vulkan的Fence数据结构,gfx在此利用MTLCommandBuffer模拟这一行为。

fn create_fence(&self, signaled: bool) -> n::Fence {    n::Fence(RefCell::new(n::FenceInner::Idle { signaled }))}/************************************************************/#[derive(Debug)]pub enum FenceInner {    Idle { signaled: bool },    Pending(metal::CommandBuffer),}#[derive(Debug)]pub struct Fence(pub(crate) RefCell
);unsafe impl Send for Fence {}unsafe impl Sync for Fence {}复制代码

销毁Fence

使用Vulkan接口实现

if (mVkFence != VK_NULL_HANDLE) {    vkDestroyFence(mVkDevice, mVkFence, nullptr);    mVkFence = VK_NULL_HANDLE;}复制代码

使用gfx-hal接口实现

device.destroy_fence(fence);复制代码

gfx-hal Vulkan模块源码

unsafe fn destroy_fence(&self, fence: n::Fence) {    unsafe { self.raw.0.destroy_fence(fence.0, None); }}复制代码

gfx-hal Metal模块源码

unsafe fn destroy_fence(&self, _fence: n::Fence) {}复制代码

重置Fence

使用Vulkan接口实现

VkResult err = vkResetFences(mVkDevice, 1, &mVkFence);// deal with (err != VK_ERROR_OUT_OF_HOST_MEMORY && err != VK_ERROR_OUT_OF_DEVICE_MEMORY);复制代码

使用gfx-hal接口实现

device.reset_fence(&fence).unwrap();复制代码

gfx-hal Vulkan模块源码

unsafe fn reset_fences(&self, fences: I) -> Result<(), d::OutOfMemory>where    I: IntoIterator,    I::Item: Borrow
,{ let fences = fences .into_iter() .map(|fence| fence.borrow().0) .collect::
<_>>(); let result = unsafe { self.raw.0.reset_fences(&fences) }; match result { Ok(()) => Ok(()), Err(vk::Result::ERROR_OUT_OF_HOST_MEMORY) => { Err(d::OutOfMemory::OutOfHostMemory.into()) } Err(vk::Result::ERROR_OUT_OF_DEVICE_MEMORY) => { Err(d::OutOfMemory::OutOfDeviceMemory.into()) } _ => unreachable!(), }}复制代码

gfx-hal Metal模块源码

unsafe fn reset_fence(&self, fence: &n::Fence) -> Result<(), OutOfMemory> {    *fence.0.borrow_mut() = n::FenceInner::Idle { signaled: false };    Ok(())}复制代码

等待Fence

使用Vulkan接口实现

VkResult err = VK_TIMEOUT;do {    err = vkWaitForFences(mVkDevice, 1, &mVkFence, waitAll, timeout);    assert(!err);    if (err == VK_ERROR_OUT_OF_HOST_MEMORY || err == VK_ERROR_OUT_OF_DEVICE_MEMORY || err == VK_ERROR_DEVICE_LOST)        break;} while (err == VK_TIMEOUT);复制代码

使用gfx-hal接口实现

device.wait_for_fence(&fence, !0).unwrap();复制代码

gfx-hal Vulkan模块源码

unsafe fn wait_for_fences(    &self,    fences: I,    wait: d::WaitFor,    timeout_ns: u64,) -> Result
where I: IntoIterator, I::Item: Borrow
,{ let fences = fences .into_iter() .map(|fence| fence.borrow().0) .collect::
<_>>(); let all = match wait { d::WaitFor::Any => false, d::WaitFor::All => true, }; let result = unsafe { self.raw.0.wait_for_fences(&fences, all, timeout_ns) }; match result { Ok(()) => Ok(true), Err(vk::Result::TIMEOUT) => Ok(false), Err(vk::Result::ERROR_DEVICE_LOST) => Err(d::DeviceLost.into()), Err(vk::Result::ERROR_OUT_OF_HOST_MEMORY) => { Err(d::OutOfMemory::OutOfHostMemory.into()) } Err(vk::Result::ERROR_OUT_OF_DEVICE_MEMORY) => { Err(d::OutOfMemory::OutOfDeviceMemory.into()) } _ => unreachable!(), }}复制代码

gfx-hal Metal模块源码

unsafe fn wait_for_fence(&self, fence: &n::Fence, timeout_ns: u64) -> Result
{ unsafe fn to_ns(duration: time::Duration) -> u64 { duration.as_secs() * 1_000_000_000 + duration.subsec_nanos() as u64 } debug!("wait_for_fence {:?} for {} ms", fence, timeout_ns); let inner = fence.0.borrow(); let cmd_buf = match *inner { native::FenceInner::Idle { signaled } => return Ok(signaled), native::FenceInner::Pending(ref cmd_buf) => cmd_buf, }; if timeout_ns == !0 { cmd_buf.wait_until_completed(); return Ok(true) } let start = time::Instant::now(); loop { if let metal::MTLCommandBufferStatus::Completed = cmd_buf.status() { return Ok(true); } if to_ns(start.elapsed()) >= timeout_ns { return Ok(false); } thread::sleep(time::Duration::from_millis(1)); }}复制代码

转载地址:http://bblia.baihongyu.com/

你可能感兴趣的文章
svn解决与优化帮助
查看>>
SQL update select结合语句详解及应用
查看>>
[转]阿里要走102年,阿里的工程师能走多远呢?
查看>>
《算法导论》读书笔记之第15章 动态规划—最长公共子序列
查看>>
从$a_n=f(n)$的角度理解数列中的表达式$a_{n+1}=\frac{k}{a_n}$
查看>>
Redis以及Redis的php扩展安装无错版
查看>>
总结性博客作业
查看>>
Windows Phone 8初学者开发—第11部分:设置SounBoard应用程序
查看>>
欧拉图和哈密顿图
查看>>
解线性方程组
查看>>
Python:pandas之DataFrame常用操作
查看>>
Appium移动自动化测试之—基于java的iOS环境搭建
查看>>
NOIP前的刷题记录
查看>>
洛谷P1973 [NOI2011]Noi嘉年华(决策单调性)
查看>>
书签(Bookmarks)
查看>>
Java 信号量 Semaphore 介绍
查看>>
Ubuntu常用软件安装与使用
查看>>
Anroid开发中常用快捷键
查看>>
RecyclerView分隔线定制
查看>>
文本处理(CSS,JS)
查看>>