ZFXEngine开发笔记- GPU硬件架构

作者:i_dovelemon

日期:2014 / 8 / 31

来源: CSDN博客

文章: GPU硬件架构

引言

在3D图形学中,可编程渲染管道的出现,无疑是一种创举。在下面的文章中,会向大家简要的介绍现如今的可编程渲染管道中最重要的Vertex Shader和Pixel Shader的硬件架构以及如何使用汇编语言来编写Shader。

Vertex Shader

在硬件上,Vertex Shader中所有的运算都在一个名为vertex arithmetic logic unit(ALU)中进行的。所以,掌握了Vertex ALU的构成方式,我们就能够很轻松的使用汇编语言来操作它。下面是Vertex ALU的结构图:

从上面我们可以看到除了中心的ALU之外,还有很多附属的寄存器,这些寄存器将会用来作为ALU的输入和输出。在上面可以看到有几种不同的寄存器。下面依次来讲解他们的作用,以及如何使用他们。

在最上面的V0到V15这16个寄存器,将会对应于在DirectX中定义的顶点格式描述符或者FVF描述符。在GPU中,每一个寄存器都是128bit的,也就是说,刚好能够容纳4个32位的float型数据,即一个向量。所以,这16个寄存器将会作为Vertex ALU输入寄存器。如何输入,需要我们定义顶点格式,以及在Shader中申明哪一个寄存器接受哪一个向量。怎么理解这句话了?实际上,在我们定义顶点格式的时候,如果大家对DirectX熟悉的话,就会知道,我们会说一个顶点中哪个向量是什么用途的,用D3DUSAGE_NORAL0,D3DUSAGE_POSITION0这样的格式来表示它的用途。所以,同样的,在Shader中,我们可以通过del_normal0,
del_position0来申明哪一个寄存器来接受哪一个数据。这样说,应该理解了吧!

除了上面的V0到V15这几个寄存器之外,还存在一些用于接受常量的寄存器。这些寄存器就是上图中右上角的以C开头的寄存器。这些寄存器称为常量寄存器,从这个名字我们就可以知道,在常量寄存器中存储的应该就是常量数据,也就是说Vertex ALU只能够对常量寄存器进行读,没有办法进行写操作。而这些常量寄存器,用于接受我们从应用程序中输入的额外的,会在Vertex Shader中使用的常量数据,比如World
Transform Matrix, 将模型坐标变换到齐次裁剪空间的Matrix,或者光源的Position, Color, 某个物体的Material等等。总之,你可能用到的所有常量的数据,都可以通过应用程序来进行设置。当设置好了数据之后,我们就可以简单的直接使用这些数据来完成我们想要完成的工作。

上面介绍的两种寄存器,都是输入对Vertex ALU的输入寄存器。那么Vertex ALU计算的结果该放在什么地方了?

读者可以从上图中看到,在右下方有一排的寄存器。这些寄存器就是ALU的输出寄存器,也就是说ALU的计算结果应该输入到这些寄存器中去。在上面的Color0和Color1分别称为0D0,和0D1寄存器,其中OD0将会保存Vertex Shader中计算出来的顶点的Diffuse Color,而0D1将会保存顶点的Specular Color。但是,并不总是需要这样做。说到底他们都只是寄存器,存放的只是数据而已,如何解释还要靠你自己。也就是说,你可以在这些寄存器中保留其他的值,但最好遵守Shader版本的一些规定。对模型顶点进行的World
* View * Projection 变换的结果保存在一个名为oPos的寄存器中。注意这个寄存器,Shader规定了只能够存放变换后的顶点的坐标,而不能用作其他用途。实际上,我们只要按照上面的解释来进行数据的填充,想要在Vertex Shader和Pixel Shader之间沟通,有如下的oT0到oT7这么多个寄存器可供使用。在oT0中,一般会存放顶点对应的纹理坐标,这样就可以将纹理坐标传递到Pixel Shader中去。除了这个之外,剩下的所有的寄存器,我们就可以按照我们想要的来使用他们。如果读者有过HLSL的编写经验,那么就应该知道,在Pixel
Shader中可以使用:TEXCOORD0, :TEXCOORD1来申明这些东西,所以这就在硬件上对应了oT1到oT7这些寄存器。

有了输入和输出的寄存器,那么我们还需要在ALU进行计算的过程中,用于临时保存变量的寄存器。这些寄存器在上图中左下角以r开头的这些都是称为临时寄存器,用于接受在Vertex Shader中进行计算的临时数据。

好了以上,就是对Vertex ALU的基本简单介绍。

Pixel Shader

在Vertex Shader中有ALU来处理,那么在Pixel Shader中,同样也有ALU来进行处理。下面是Pixel ALU的硬件架构图:

实际上,它的架构方法和Vertex ALU十分的相似。以c开头的寄存器还是常量寄存器,使用方法同Vertex ALU一样。以r开头的寄存器同样还是临时寄存器,但是有一点不同,r0寄存将要保存在最后计算出来的像素的颜色值,也就是说这是Pixel ALU唯一的一个输出寄存器。 v0和v1,分别对应了在Vertex ALU中的oD0和oD1,你在Vertex Shader中传入了什么数据,那么在Pixel
Shader中就用同样的法则来解释他们。

除了上面的这些寄存器之外,就剩下了左边的几个以t开头的寄存器了。你还记得Device->SetTexture这个函数吗?这个函数的申明如下:

         HRESULT SetTexture( [in] DWORD Sampler, [in] IDirect3DBaseTexture9 *pTexture);

             在DirectX SDK的文档中,这样解释第一个参数:

            表示的是采样器的编号,不同的纹理绑定在不同的采样器上面,在可编程渲染管道中,我们通过采样器编号来引用纹理。

    
     也就是说,不同的纹理可以绑定在不同的采样器上,然后在Pixel Shader中进行使用。这就是为什么我们能够实现Multi-texture的原因。

         但是,上面的t开头的寄存器,又不仅仅能够做这样使用。还记得在上面的Vertex ALU中,我们曾经说过,在Vertex Shader和Pixel Shader之间进行沟通的方法就是通过oT0-oT7这些寄存器。也就是说,oT0和oT7分别对应了Pixel ALU中的t0到t7(oops!上图并没有t7啊,这个图只是概念上的图,具体有多少个寄存器,需要查看D3DCAPS属性中的介绍)。那么,如果我们在Vertex
Shader想要传递一些数据到Pixel Shader中,我们就可以将数据保存在0T1或者其他的寄存器中,然后在Pixel Shader中通过特定的指令来访问这些数据,获取这些数据,从而完成我们需要的工作。

          好了,以上就是今天的关于GPU硬件架构的内容。软件工程中的摩尔定律说过,每18个月,计算机硬件性能就会翻新。这说明了硬件的架构方法总是在变化,可能这里的架构并不符合你现在使用的GPU的架构,但是基本的原理和设定还是相同的。

              希望通过这篇文章,大家能够对Shader如何进行工作有了一定的理解,希望对大家有一定的帮助!

               在此还要说一下,上面只是讲解了GPU的结构,那么如何通过汇编语言来操作GPU和上面的寄存器,也就是有哪些指令?请到MSDN的官网上阅读有关ASM
Shader Reference
的资料。

时间: 2024-12-29 06:52:38

ZFXEngine开发笔记- GPU硬件架构的相关文章

ZFXEngine开发笔记之Omni Light

作者:i_dovelemon 日期:2014 / 9 / 5 来源:CSDN博客 主题:Per-pixel lighting, Omni light, early-z, Multi-pass, Assembly Shader 引言 在第一人称射击游戏中,经常需要点光源来完成光照计算.所以,这篇文章中将会讲述如何创建这个点光源,并且如何设计让引擎可以支持多光源渲染. Omni light介绍 所谓的Omni light,就是指点光源.不过在这里,我们进行点光源的光照计算的时候,没有用到顶点的法线来

ZFXEngine开发笔记-SSE版本的ZFXVector

SSE介绍 在学习3D游戏编程大师技巧的时候,就了解到,可是使用一种称之为"单指令,多数据(SIMD)"的技术来编写3D数学库.通过这样的方法,可以将我们经常使用的诸如向量计算,矩阵变换等操作加快很多倍.这次,在学习3D引擎开发的时候,也用到了这个技术.SIMD是一种技术的名称,而并不是具体的工具.实现这种技术,不同的CPU厂商推出了不同的技术,像MMX, 3DNow!, SSE, SSE2, SSE3....由于我的计算机上使用的是Intel的处理器,它支持MMX,SSE,SSE2,

iOS开发笔记--iOS应用架构谈

iOS应用架构谈 开篇 iOS应用架构谈 开篇 iOS应用架构谈 view层的组织和调用方案 iOS应用架构谈 网络层设计方案 iOS应用架构谈 动态部署方案 iOS应用架构谈 本地持久化方案 缘由 之前安居客iOS app的第二版架构大部分内容是我做的,期间有总结了一些经验.在将近一年之后,前同事zzz在微信朋友圈上发了一个问题:假如问你一个iOS or Android app的架构,你会从哪些方面来说呢? 当时看到这个问题正好在乘公车回家的路上,闲来无聊就答了一把.在zzz在微信朋友圈上追问

ZFXEngine开发笔记之3D模型格式支持(1)

作者:i_dovelemon 来源:CSDN 日期:2014 / 9 / 17 主题:3D Format, Milk 3D Shape, Chunk Based System, Skeleton Animation (文中以红色中字标示的文字,是整个文章的注意项,请读者留心) 引言 在3D游戏领域,艺术家们通过3D建模软件建立自己的艺术品模型和绚丽的3D场景.当我们想要在自己的游戏中使用这些模型的时候,我们就需要将这种模型变成能够被我们的引擎所识别的文件格式.每一个建模软件都有自己的文件格式,不

ZFXEngine开发笔记之Bump Mapping(2)

作者:i_dovelemon 日期: 2014 / 9 / 13 来源 : CSDN 主题 :Bump Mapping, Tangent Space, Normal Map, Height Map 引言 在上篇文章中,我讲述了如何根据高度图来创建法线图.并且承诺在后面会讲述3D几何学中的重要工具Tangent Space的相关知识.今天,就在这里,向大家讲述如何接下来的工作部分. Tangent Space 我们知道,在前篇文章中,讲述的法线图中的法线是在纹理图的空间中也就是Tangent Sp

ZFXEngine开发笔记之Shadow Volume

作者:i_dovelemon 来源:CSDN 日期:2014 / 10 / 20 主题: Shadow Volume 引言 游戏中,往往有很多的光影效果.想要营造出很好的光影效果,物体在光源照射下的阴影就必不可少.本节内容就向大家讲述如何构建阴影. Shadow Volume 构建阴影的方法有很多,常用的两种方法是Shadow Volume和Shadow mapping.本片博文将向大家讲述使用Shadow Volume来构建阴影的方法. Shadow Volume的算法是由Frank Crow

ZFXEngine开发笔记之Bump Mapping(1)

作者:i_dovelemon 日期:2014 / 9 / 7 来源:CSDN博客 主题:Bump Mapping, Tangent Space, Normal Map, Height Map 引言 我们知道,在真实世界中,任何物体的表面都不是非常光滑的,这种粗糙的表面效果,在光源的照射下会有明暗的感觉.那么,如何在3D图形中模拟这种效果了?是通过建模的方法,为模型的表面建造出粗糙的表面?这种方法很难做出真实的粗糙感出来,毕竟表面的粗糙程度是很细微的效果,很难用建模的方式建模出来.所以,只能用其他

【Kinect开发笔记之(二)】Kinect for windows发展历程

新版本SDK和旧版本的SDK完全兼容,如果您之前安装过旧版本的,可以直接安装新版本的SDK,但是如果您之前的开发版本是Beta版的,则需要卸载之后再安装新版本.在Kinect for Windows SDK 1.0版本中,SDK和示例文件是打包一起安装的.而在之后的版本,为了可以分别升级,微软把这两者分开独立为Kinect for Windows SDK和Kinect for Windows Developer Toolkit这两部分,所以需要分别下载安装, Kinect for Windows

全球最低功耗蓝牙单芯片DA14580的硬件架构和低功耗

号称全球最低功耗蓝牙单芯片DA14580在可穿戴市场.健康医疗.ibeacon定位等市场得到广泛的应用,但是因为其较为封闭的技术/资料支持导致开发人员有较高的技术门槛,网络上也极少看到有关DA14580的开发技术分享,因此一般企业和一般技术团队都不敢贸然采用该平台,但一旦精通该芯片平台的开发,即可在蓝牙方案应用开发中获得较大的技术优势. 作者在集成电路领域有较为深厚的积累,在DA14580平台也有丰富的开发经验,接下来将以一个系列文章对DA14580的硬件架构和软件体系进行分析.如需技术咨询,请