opengl - glMapBuffer()和glBuffers,使用(void *)访问如何与硬件一起工作?

标签 opengl hardware

阅读《 OpenGL编程指南》第8版。

这实际上是一个硬件问题,实际上...

我介绍了有关OpenGL缓冲区的部分,据我了解它们是在图形卡内存中分配的内存空间,这是否正确?

如果是这样,我们如何使用glMapBuffer()获得一个指针来读取或修改该内存?据我所知,所有可能的内存地址(例如,在64位系统上有uint64_t num = 0x0; num = ~num;个可能的地址)都用于系统内存,就像在RAM / CPU端内存中一样。

glMapBuffers()返回void *到某些内存。该指针如何指向图形卡内部的内存?特别是如果我有32位系统,超过4GB的RAM,然后是具有2GB / 4GB内存的图形卡。肯定没有足够的地址吗?

最佳答案

这实际上是一个硬件问题,实际上...


不,这不对。一会儿您会明白为什么。


我介绍了有关OpenGL缓冲区的部分,据我了解它们是在图形卡内存中分配的内存空间,这是否正确?


不完全的。您必须了解,虽然OpenGL使您真正接近实际的硬件,但与直接接触它仍然相距甚远。 glMapBuffer的作用是设置虚拟地址范围映射。在现代计算机系统上,该软件无法在物理地址上运行。而是使用虚拟地址空间(一定大小)。该虚拟地址空间看起来像软件的一个大连续内存块,而实际上它由物理页面的拼凑而成。这些页面可以以任何方式实现,它们可以是实际的物理内存,可以是I / O内存,甚至可以由其他程序在原位创建。该机制由CPU的内存管理单元与OS协作提供。

因此,对于每个进程,操作系统都会管理一个表,该表将进程虚拟地址空间的哪一部分映射到哪个页面处理程序。如果您正在运行Linux,请查看/proc/$PID/maps。如果您有一个使用glMapBuffer的程序(在您的程序中,请勿调用系统)在地图缓冲区之前和之后读取/proc/self/maps并查找差异。


据我所知,所有可能的内存地址(例如,在64位系统上,uint64_t num = 0x0; num =〜num;可能的地址)被用于系统内存,就像在RAM / CPU端内存中一样。


什么让你有那个想法?谁告诉过你(如果有人告诉过你)应该被打在脸上……很难。

您拥有的是虚拟地址空间。而且该地址空间与硬件方面的物理地址空间完全不同。实际上,虚拟地址空间的大小和物理地址空间的大小可能相差很大。例如,很长一段时间以来,周围都有32位CPU和32位操作系统。但那时已经希望拥有超过4 GiB的系统内存。因此,尽管CPU仅支持一个进程的地址空间的32位(指针的最大大小),但它可能已经向内存提供了36位的物理地址线,以支持约64 GiB的系统RAM;然后,手动切换这些额外的位将是OS的工作,因此尽管每个进程只能看到大约3 GiB的系统RAM(最大)进程,但这些进程可能会扩散。诸如此类的技术已被称为物理地址扩展(PAE)。

此外,并非进程中的所有地址空间都由RAM支持。就像我已经解释的那样,地址空间映射可以由任何东西支持。通常,内存分页处理程序还会实现交换,即,如果周围没有足够的可用RAM,它将使用HDD存储(实际上,在Linux上,所有用户空间的内存请求都由磁盘I / O缓存处理程序支持)。同样,由于地址空间映射是针对每个进程的,因此地址空间的某些部分被映射为内核内存,这对于所有进程(在物理上)都是相同的,并且也位于所有进程的相同位置。从用户空间不能访问该地址空间映射,但是一旦syscall转换为内核空间,就可以访问它;是的,操作系统内核也在内部使用虚拟内存。它只是无法从可用的支持中进行广泛选择(例如,如果网络驱动程序的内存由网络本身支持,则网络驱动程序将很难操作)。

无论如何:在现代的64位系统上,您具有64位的指针大小,并且在当前的硬件中,有48位的物理RAM地址线。这就留出了足够的空间,即16×48位(EDIT意味着2 ^ 16-1乘以48位地址空间),用于没有RAM的虚拟映射。而且因为有很多事情要做,所以每张PCI卡都有自己的地址空间,这有点像CPU的RAM(记住我前面提到的PAE,在过去32位的情况下,类似这样)必须与扩展卡进行通话)。

现在是OpenGL驱动程序。它只是提供了一个新的地址映射处理程序,该地址处理程序通常仅建立在PCI地址空间处理程序的基础上,该处理程序将映射进程的虚拟地址空间的一部分。并且该地址空间中发生的任何事情都将由该映射处理程序反映到最终由GPU访问的缓冲区中。但是,GPU本身可能正在直接访问CPU内存。 AMD计划的是,GPU和CPU将生活在同一个Die上,并访问同一个内存,因此不再存在物理区别。

关于opengl - glMapBuffer()和glBuffers,使用(void *)访问如何与硬件一起工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17800140/

相关文章:

hardware - block 和扇区之间的区别

hardware - 32 位对 64 位

vhdl - modelsim 说 : "near " )": (vcom-1576) expecting IDENTIFIER." while compiling

c++ - GLut.h/osfinfo.c/dbgheap.c/mlock.c 中 0x76fe15de 的未处理异常

c++ - 无法在 QGLWidget 中设置所需的 OpenGL 版本

opengl - 纹理缓冲对象还是常规纹理?

c++ - 如何在窗口外绘制图形(OpenGL glfw)

Java OpenGL - 在 glutSolidCube 的每侧应用不同的颜色

hardware - 数字逻辑 - 粉状状态机?

javascript - 有没有办法在没有视口(viewport)元标记的情况下获得硬件像素中的真实视口(viewport)大小?