浅谈 OpenGL 中相关阻塞问题
昨天我遇到一个问题,问题如下:
我使用了延迟渲染,我的渲染流程是:Pass1 --> CUDA并行计算 -->Pass2
CUDA并行计算中需要使用Pass1渲染生成的两张纹理,然而我在GPU端使用CUDA计算时发现纹理为空(数据全是0值),但是如果将两张纹理的数据传回CPU端,打印出来是有值的,且是正确的值。如果在CUDA并行计算之前先将纹理数据传回CPU,这时发现CUDA并行计算中纹理是正常有值的。。。这个现象很奇怪,我开始想了想会不会是阻塞啥原因,但我对OpenGL阻塞过程不了解,没看到过相关的资料,简单思考了一下觉得不是阻塞的原因,我觉得可能是其中的一张纹理有问题,牵连导致这个问题。。。。。最终验证发现还是OpenGL阻塞的原因。在CUDA并行计算之前加上 glFinish()函数即可。
为啥加上glFinish()函数就解决了呢? 解释这个之前,先说一下glFlush()和glFinish()函数的作用:
一个OpenGL渲染程序会调用很多的OpenGL命令,而OpenGL是异步的,CPU将这些耗时的命令发送到GPU端,然后直接返回继续执行,这些OpenGL相关指令存储在GPU的缓存中一条条的执行,但是CPU也不是直接发送给GPU的,CPU自己有缓存,先存储在自己的缓存中,之后再发送过去(有时机,例如遇到某些刷新的命令等)。现在开始介绍以上两个函数的作用。
glFlush():将缓存在CPU端的命令发送到GPU上,清空缓存,发送完立即返回。
glFinish():将缓存在CPU端的命令发送到GPU上,清空缓存,发送完,等待GPU执行完在返回。
看到这里就可以理解我加上 glFinish() 可以解决问题的原因了。我没加 glFinish() 时,CUDA并行计算时,这时Pass1实际没有执行完,故纹理为空,CUDA中拿不到正确的纹理数据,加上 glFinish() 后实际就是加入了GPU阻塞,等待Pass1执行完,然后执行CUDA并行计算。
注:说到这里,谈点我思考的问题:
1、在OpenGL渲染中,不管是 Pass1 --> CUDA并行计算 -->Pass2, 或者 Pass1 --> Pass2 或者Pass(只有一个Pass),我们统计两次渲染之间的时间差值就可以计算帧率,为啥不会因为异步问题计算不准呢? 因为 glfwSwapBuffers(glfw_window) 命令会将所有CPU端的命令发送到GPU端,并等待其执行完,然后再交换前后缓冲。
2、对于Pass1 --> Pass2这样的延迟渲染,Pass1和Pass2都是作为命令发送到GPU端,按序执行,故不会出现Pass2拿到的数据(由Pass1处理的)不正确情况,我们不需要加阻塞保障其执行。
另外不要错误以为,CPU运行到Pass2处看见Pass1还在执行,CPU阻塞等待Pass1执行完然后发送Pass2指令。
3、为啥在CUDA并行计算前,对纹理进行一次数据传回可以让CUDA获取正确的纹理数据 ?我觉得(差不多肯定是这样,哈哈,自信……)拷贝纹理数据的OpenGL API虽然与GPU相关,但是其与CPU也相关,需要在CPU端的内存上接收传回的数据,从CPU端考虑它也会阻塞的。
4、Pass1 和 CUDA并行计算 都是在GPU上执行的,而CUDA拿不到正确的纹理数据,可以认为 Pass1 和 CUDA并行计算 同时在GPU上并行执行(我猜的,应该是吧……)。
浅谈 OpenGL 中相关阻塞问题的更多相关文章
- 浅谈Linux中的信号处理机制(二)
首先谢谢 @小尧弟 这位朋友对我昨天夜里写的一篇<浅谈Linux中的信号处理机制(一)>的指正,之前的题目我用的“浅析”一词,给人一种要剖析内核的感觉.本人自知功力不够,尚且不能对着Lin ...
- Java网络编程和NIO详解7:浅谈 Linux 中NIO Selector 的实现原理
Java网络编程和NIO详解7:浅谈 Linux 中NIO Selector 的实现原理 转自:https://www.jianshu.com/p/2b71ea919d49 本系列文章首发于我的个人博 ...
- 浅谈Java中的对象和引用
浅谈Java中的对象和对象引用 在Java中,有一组名词经常一起出现,它们就是“对象和对象引用”,很多朋友在初学Java的时候可能经常会混淆这2个概念,觉得它们是一回事,事实上则不然.今天我们就来一起 ...
- 【转】浅谈Java中的hashcode方法(这个demo可以多看看)
浅谈Java中的hashcode方法 哈希表这个数据结构想必大多数人都不陌生,而且在很多地方都会利用到hash表来提高查找效率.在Java的Object类中有一个方法: public native i ...
- 【转】浅谈Java中的hashcode方法
哈希表这个数据结构想必大多数人都不陌生,而且在很多地方都会利用到hash表来提高查找效率.在Java的Object类中有一个方法: public native int hashCode(); 根据这个 ...
- 视频基础知识:浅谈视频会议中H.264编码标准的技术发展
浅谈视频会议中H.264编码标准的技术发展 浅谈视频会议中H.264编码标准的技术发展 数字视频技术广泛应用于通信.计算机.广播电视等领域,带来了会议电视.可视电话及数字电视.媒体存储等一系列应用,促 ...
- 浅谈 .NET 中的对象引用、非托管指针和托管指针 理解C#中的闭包
浅谈 .NET 中的对象引用.非托管指针和托管指针 目录 前言 一.对象引用 二.值传递和引用传递 三.初识托管指针和非托管指针 四.非托管指针 1.非托管指针不能指向对象引用 2.类成员指针 五 ...
- 浅谈jvm中的垃圾回收策略
下面小编就为大家带来一篇浅谈jvm中的垃圾回收策略.小编觉得挺不错的,现在就分享给大家,也给大家做个参考.一起跟随小编过来看看吧 java和C#中的内存的分配和释放都是由虚拟机自动管理的,此前我已 ...
- 浅谈HTTP中GET和POST请求方式的区别
浅谈HTTP中GET和POST请求的区别 HTTP认知: HTTP是基于TCP/IP的关于数据如何在万维网中如何通信的协议.HTTP的底层是TCP/IP.所以GET和POST的底层也是TCP/IP,也 ...
随机推荐
- H3C 命令行帮助特性
- Top 10 open source projects of 2015
Top 10 open source projects of 2015 Posted 15 Dec 2015Jen Wike Huger (Red Hat)Feed 188 up 31 comment ...
- vue3——vue数据循环渲染
博客地址 :https://www.cnblogs.com/sandraryan/ vue循环渲染 <!DOCTYPE html> <html lang="en" ...
- 洛谷P1288 取数游戏II 题解 博弈论
题目链接:https://www.luogu.org/problem/P1288 首先,如果你的一边的边是 \(0\) ,那么你肯定走另一边. 那么你走另一边绝对不能让这条边有剩余,因为这条边有剩余的 ...
- Laravel 中 validation 验证 返回中文提示 全局设置
<?php return [ /* |-------------------------------------------------------------------------- | V ...
- 第三次脱发——Scurm学(ctrl)习(C)心得
Scrum 学习心得: 首先,敏捷并不是一门具体的技术,而是一种理念或者说是一种思想.它可以指导我们更加高效的开发. 其次,敏捷开发都具有以下共同的特征: 迭代式开发 增量交付 开发团队和用户反馈推动 ...
- Centos下添加用户到用户组
将一个用户添加到用户组中,千万不能直接用: usermod -G groupA 这样做会使你离开其他用户组,仅仅做为 这个用户组 groupA 的成员. 应该用 加上 -a 选项: usermod - ...
- [转载] linux、Solaris下xdmcp远程桌面服务
原文链接 http://youlvconglin.blog.163.com/blog/static/52320420106243857254/ 使用图形界面远程登录linux和Solaris,首先要在 ...
- [转]C#操作Memcached帮助类
在VS中安装Memcached,直接在NuGet下搜索Memcached,选择第一个进行安装: 服务端资源下载地址:https://pan.baidu.com/s/1gf3tupl 接下来开始写程序, ...
- js cookie跨域
特别说明: 默认情况下,当前域下的cookie只能被当前域下的页面访问. 通过JavaScript设置cookie的doamin属性为一个恰当值即可实现跨域效果. 1.只有根域名相同的不同源的cook ...