昨天我遇到一个问题,问题如下:

    我使用了延迟渲染,我的渲染流程是: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 中相关阻塞问题的更多相关文章

  1. 浅谈Linux中的信号处理机制(二)

    首先谢谢 @小尧弟 这位朋友对我昨天夜里写的一篇<浅谈Linux中的信号处理机制(一)>的指正,之前的题目我用的“浅析”一词,给人一种要剖析内核的感觉.本人自知功力不够,尚且不能对着Lin ...

  2. Java网络编程和NIO详解7:浅谈 Linux 中NIO Selector 的实现原理

    Java网络编程和NIO详解7:浅谈 Linux 中NIO Selector 的实现原理 转自:https://www.jianshu.com/p/2b71ea919d49 本系列文章首发于我的个人博 ...

  3. 浅谈Java中的对象和引用

    浅谈Java中的对象和对象引用 在Java中,有一组名词经常一起出现,它们就是“对象和对象引用”,很多朋友在初学Java的时候可能经常会混淆这2个概念,觉得它们是一回事,事实上则不然.今天我们就来一起 ...

  4. 【转】浅谈Java中的hashcode方法(这个demo可以多看看)

    浅谈Java中的hashcode方法 哈希表这个数据结构想必大多数人都不陌生,而且在很多地方都会利用到hash表来提高查找效率.在Java的Object类中有一个方法: public native i ...

  5. 【转】浅谈Java中的hashcode方法

    哈希表这个数据结构想必大多数人都不陌生,而且在很多地方都会利用到hash表来提高查找效率.在Java的Object类中有一个方法: public native int hashCode(); 根据这个 ...

  6. 视频基础知识:浅谈视频会议中H.264编码标准的技术发展

    浅谈视频会议中H.264编码标准的技术发展 浅谈视频会议中H.264编码标准的技术发展 数字视频技术广泛应用于通信.计算机.广播电视等领域,带来了会议电视.可视电话及数字电视.媒体存储等一系列应用,促 ...

  7. 浅谈 .NET 中的对象引用、非托管指针和托管指针 理解C#中的闭包

    浅谈 .NET 中的对象引用.非托管指针和托管指针   目录 前言 一.对象引用 二.值传递和引用传递 三.初识托管指针和非托管指针 四.非托管指针 1.非托管指针不能指向对象引用 2.类成员指针 五 ...

  8. 浅谈jvm中的垃圾回收策略

    下面小编就为大家带来一篇浅谈jvm中的垃圾回收策略.小编觉得挺不错的,现在就分享给大家,也给大家做个参考.一起跟随小编过来看看吧   java和C#中的内存的分配和释放都是由虚拟机自动管理的,此前我已 ...

  9. 浅谈HTTP中GET和POST请求方式的区别

    浅谈HTTP中GET和POST请求的区别 HTTP认知: HTTP是基于TCP/IP的关于数据如何在万维网中如何通信的协议.HTTP的底层是TCP/IP.所以GET和POST的底层也是TCP/IP,也 ...

随机推荐

  1. H3C 命令行帮助特性

  2. 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 ...

  3. vue3——vue数据循环渲染

    博客地址 :https://www.cnblogs.com/sandraryan/ vue循环渲染 <!DOCTYPE html> <html lang="en" ...

  4. 洛谷P1288 取数游戏II 题解 博弈论

    题目链接:https://www.luogu.org/problem/P1288 首先,如果你的一边的边是 \(0\) ,那么你肯定走另一边. 那么你走另一边绝对不能让这条边有剩余,因为这条边有剩余的 ...

  5. Laravel 中 validation 验证 返回中文提示 全局设置

    <?php return [ /* |-------------------------------------------------------------------------- | V ...

  6. 第三次脱发——Scurm学(ctrl)习(C)心得

    Scrum 学习心得: 首先,敏捷并不是一门具体的技术,而是一种理念或者说是一种思想.它可以指导我们更加高效的开发. 其次,敏捷开发都具有以下共同的特征: 迭代式开发 增量交付 开发团队和用户反馈推动 ...

  7. Centos下添加用户到用户组

    将一个用户添加到用户组中,千万不能直接用: usermod -G groupA 这样做会使你离开其他用户组,仅仅做为 这个用户组 groupA 的成员. 应该用 加上 -a 选项: usermod - ...

  8. [转载] linux、Solaris下xdmcp远程桌面服务

    原文链接 http://youlvconglin.blog.163.com/blog/static/52320420106243857254/ 使用图形界面远程登录linux和Solaris,首先要在 ...

  9. [转]C#操作Memcached帮助类

    在VS中安装Memcached,直接在NuGet下搜索Memcached,选择第一个进行安装: 服务端资源下载地址:https://pan.baidu.com/s/1gf3tupl 接下来开始写程序, ...

  10. js cookie跨域

    特别说明: 默认情况下,当前域下的cookie只能被当前域下的页面访问. 通过JavaScript设置cookie的doamin属性为一个恰当值即可实现跨域效果. 1.只有根域名相同的不同源的cook ...