OpenGL Driver Architecture[转] | 您所在的位置:网站首页 › 支持openGL的IDE › OpenGL Driver Architecture[转] |
OpenGL Driver Architecture
Yang Jian
[email protected] 1 OpenGL Installable Client Driver Windows下OpenGL Driver有三种类型,可安装的客户端驱动程序(Installable Client Driver ,缩写为ICD),微驱动(minidriver)和独立驱动程序。独立驱动程序主要是为一些特殊的图形系统设计,这些图形系统的能力相对比较强大,整个系统的主要目的为图形应用,目前已经不多见。MiniDriver在3D图形加速卡没有普及之前曾经被使用过,但是有由于其支持的能力太低,自nvi dia TNT 之后就看不到这类驱动程序。 现在图形芯片供应商都采用ICD的方式提供OpenGL Driver。ICD的最大特点是(1)能够支持OpenGL驱动程序开发者提供完整的OpenGL支持,和OpenGL Extension支持;(2)使得OpenGL能够以client-server的方式运行;(3)对OpenGL应用程序开发者提供统一的API接口。 下面是一个OpenGL ICD驱动程序体系结构的简图。 Application | | GDI32.dll OpenGL32.dll glBegin { (*__glDispatchTable.glBegin)(); == > } ICD Driver Call glBegin { …. } 也就是说通过glDispatchTable,所有的OpenGLAPI最终都将进入到ICD Driver对应的函数中。 啰嗦这么多,相信大家该对OpenGL体系结构有一个大致的认识了。下面我将另外一个内容,OpenGL ICD是如何实现Display List。 3.3 ICD Driver中Display List的实现。 OpenGL中Display List是一种加速绘制的方法,那么它内部是如何实现的呢? 其实相当简单。 首先ICD Driver对每一个OpenGL API进行编号,例如,glAccum是0,glAlphaFunc是2, #define __GL_DLISTOP_ACCUM 0 #define __GL_DLISTOP_ ALPHAFUNC 1 …. 当应用程序调用glNewList生成一个新的Display List,ICD Driver分配一个数组,其中每个元素定义如下 struct listop{ int opcode; //对应上面的API编号 void* parameter; }; 如果我们在Display List中调用glVertex3F,那么ICD Driver调用如下代码(真实代码要复杂些),这时候ICD Driver仅仅将这些命令和它们的参数保存数组中,并不处理这个API。 plistop->opcode = __GL_DLISTOP_VERTEX3F; (GLfoat*)plistop->parameter = x; ((GLfoat*)plistop->parameter)++ = y; ((GLfoat*)plistop->parameter)++ = z; 然后,当应用程序调用一个glCallList的时候,ICD Driver首先找到那个数组,根据每个listop的opcode调用对应的处理函数。 3.4 ICD Driver中纹理的管理 OpenGL ICD Driver无法直接申请显示内存,但是图形硬件需要使用纹理数据实现问题贴图。那么ICD Driver必须能够将纹理数据拷贝到显示内存或AGP memory, 即Local Video Memory ,non-local Video Memory。AGP memory是操作系统管理的,经过GART映射后图形处理芯片可以访问的特殊内存区域。 当我们调用一个glTexImage2D的函数定义纹理的时候,ICD Driver首先创建一块系统内存区域,将纹理数据拷贝到系统内存。然后调用IDirectDraw7::CreateSurface申请video memory。如果申请失败,而且video memory存储空间不足,表明现在有太多的应用程序在运行,或者这个应用程序申请了太多的video memory,需要释放一些纹理内存空间,调用IDirctDrawSurface7::Release一些video memory空间。一般采用FIFO的方式实现内存的替换管理。 当video memory申请成功后,调用IDirectDrawSurface7::Lock获得video memory的用户地址,将保存在系统内存中的数据复制到video memory中。图形芯片就能够访问纹理数据了。 3.5 wglMakeCurrent(NULL, NULL) 当应用程序调用wglMakeCurrent(NULL),OpenGL32.dll将调用ICD Driver中的DrvReleaseContext使得所有的OpenGL API都成为空操作,不会产生任何结果。 3.6 SwapBuffer的实现 如果是窗口程序,ICD Driver 的DrvSwapBuffers将调用IDirectDrawSurface7::Blt实现从后台缓冲区到前台缓冲区的内容复制。 如果是全屏幕程序,DrvSwapBuffers将调用IDirectDrawSurface7::flip实现快速的前后缓冲区切换。 一些驱动程序使用IDirect3DDevice8::Present或者IDirect3DDevice9::Present实现缓冲区内容的切换。 3.7 wglDeleteContext wglDeleteContext将调用DrvDeleteCOntext,它将释放所有申请的系统内存和显示内存(video memory),以及纹理,并且删除硬件OpenGL context和软件OpenGL context。而且所有的OpenGL API将不可用。 4 OpenGL ICD Driver 评价 目前OpenGL ICD Driver都相当成熟,基本上都是沿用SGI提供的参考框架结构。大家可以参考下面的链接获取SGI的OpenGL driver实现: http://oss.sgi.com/projects/ogl-sample/ 目前OpenGL做得最好的是3dlabs,它能够支持OpenGL 2.0。 ATI 和 nvidia都支持 OpenGL 1.4,不过ATI支持更多的OpenGL extension。 其他如SIS, XGI, S3支持的API比nvidia要少一些。 Intel等集成显示卡的驱动自然很差了,硬件能力为OpenGL 1.2或者OpenGL 1.3. 5 Linux的OpenGL Driver体系结构 Linux下为DRI(Direct Render Infrastrcture),有兴趣可以参考它的网站; http://dri.sourceforge.net/cgi-bin/moin.cgi |
CopyRight 2018-2019 实验室设备网 版权所有 |