为什么Vertex Shader中,2a输出是多少w的oPos的w值与z值总是相等的

   学习了顶点处理你就知道固定功能流水线怎么将顶点从模型空间坐标系统转化到屏幕空间坐标系统。虽然固定功能流水线也可以通过设置渲染状态和参数来改变最终2a输絀是多少w的结果但是它的整体功能还是受限。当我们想实现一个外来的光照模型外来的Fog或者点大小计算方式,等等我们可能就放弃使用固定功能流水线,转而使用CPU来实现这些计算

   使用vertex shaders,它用一段小程序替换固定功能处理这段小程序的输入是模型空间的顶点,2a输出昰多少w齐次剪裁空间的顶点并且还携带一些信息,如:per-vertex diffuse 和 specualr雾,透明度纹理坐标和点大小。

    Direct3D对于不同的图形处理器有不同的vertex shaders架构版本每个版本都有不同数目和类型的寄存器和不同的指令集。一般情况高版本一般是低版本的衍生品,提供了更多的指令和更少限制我們将先看完整的1.1版本,然后讨论各个版本在上面的增量 

shader的特殊版本也将会安装,如vs_2_sw和vs_3_sw这两个版本只用于软件处理,专门用于做模拟和調试之用shader的软件版本实现了2.0和3.0架构所有的功能,并且大部分的shader验证将被放开

所有的架构都共享一个公共的执行模型。执行程序称做shader咜在每个顶点上执行一次。shader包含一个或多个指令每个指令由一个操作码与0个或多个操作数组成的。shader可以访问五组不同的寄存器:顶点数據的input寄存器渲染参数的const寄存器,用于查询const寄存器的地址寄存器存储临时数据的临时寄存器,采样纹理的采样寄存器shader2a输出是多少w结果嘚ouput寄存器。不同类型寄存器的数目如下表

0 0 0 0 0
0 0
0

    每个临时寄存器都存储一个四维的向量值,大多数指令都是在四维向量上进行操作每个值都昰一个浮点值,一般有6个小数数字指令一般是通用算术运算,如加乘和一般的向量计算(点积,向量矩阵乘法)跟一般的CPU不一样的昰,低版本的shader一般不支持流控制以便于shader更加简单和容易硬件加速。

    顶点组件通过合适的顶点声明映射到对应的semantics上semantics使用dcl_usage指令与shader的输入寄存器关联。输入寄存器是只读的只能用作顶点shader指令的数据源。虽然不同的操作数能应用到不同的修饰符每个指令只能引用一个input regesiter。

  • const 寄存器和地址寄存器

    地址寄存器是一个带符号的整数记录了距离base const寄存器的位置偏移量。const寄存器是只读的地址寄存器是可写的。当地址寄存器越界它的值将是(0,0,0,0)。在使用地址寄存器之前必须先初始化它。

    shader 1.1 只能使用地址寄存器的x组件来作为索引并且地址寄存器只能被设置成mov指令的目的地,当使用它的时候它将进行四舍五入成整数 shader 2.0以上的版本提供了更加通用的一种使用方式。寄存器的四个组件都可以用来作為索引能够同时索引const寄存器的不同的部分。mova指令用于设置地址寄存器的值   

     output寄存器用于存储shader计算的结果。output寄存器是可写的它用来存储頂点的同次剪裁空间的坐标以及每个顶点相关的数据,如颜色纹理坐标信息。3.0之前的shader版本output寄存器将会分别命名。位置寄存器oPos, 颜色寄存器oD0和oD1fog 寄存器oFog,点大小寄存器oPts和纹理坐标寄存器oT0到oT7 每个顶点shader都得写oPos的四个组件。fog系数和点大小的缩放值将分别取oFog和oPts寄存器的x组件oFog和oPts将被缩放到【0,1】区间在shader 3.0版本,output寄存器将会使用dcl_usage指令定义

通常会将数据从输入寄存器移动到临时寄存器,然后在临时寄存器上执行计算最后把结果写入到2a输出是多少w寄存器。其他类型的寄存器在一个指令可能只使用一次但是临时寄存却有可能使用多次。在一个指令里媔有可能有3个临时寄存器被读一个被写。任何读取一个没有写入数据的临时寄存器都会产生错误

     shader 2.0或者更高版本使用loop和endloop指令来控制流,循环计数寄存器al包含计数器的当前值在循环体外部,这个值是未定义的在循环体内部它的值将是固定数组的偏移量。在shader 3.0中循环计数寄存器将用于索引2a输出是多少w寄存器和const数组。

     shader3.0 采用采样寄存器来访问纹理采样寄存器本身使用texldl指令来采样纹理。采样寄存器在使用前必須使用dcl_usage声明使用采样寄存器,顶点shader能够执行纹理查询

     每个指令默认情况下操作在源操作数和目的操作数的四维向量值上。为了提高顶點shader的灵活性并且使指令数减少,每个操作数可以包含一个修饰符来提取某几个维度的值对于顶点shader指令,共有四种修饰符:目的操作数寫掩码源操作数multiplex,源操作数negation和绝对值操作数修饰符的语法如下:

目的寄存器写掩码: r.xyzw

multiplex修改符允许一个四维向量从一个源寄存器的四个組件构造得到。一个组件可能被组合到一个向量的多个组件

一个操作数也能使用多个修饰符,多个修饰符也能应用到一个指令里面

    指囹用于声明,基本运算矩阵计算,简单比较以及基本光照计算更高版本的shader能完全支持1.1的指令,只是在某些指令上有些微小的变动

2.0架構保留了1.1所有的指令和寄存器,并且增加了很多额外的功能版本2.0主要的改进增加了是静态流控制。静态条件指令包括subroutine分支和循环指令。在静态流控制里面计算分支点的条件表达式指向那些在shader执行过程中是const的值。使用静态流控制执行固定次数的循环,并且条件执行遵循同样的路径使用同一组constants来绘制primitives primitives的不同的batch处理可以通过改变constants来改变它们的行为。所有的流控制指令都是成对出现并且属于一个指令block。

   提供了新的constant寄存器文件来定义了用于管理控制流的constants在控制流里面,你能写一个顶点shader应用到不同类型的顶点定义流的constants可以在两次draw primitives调用之間重新更新。

   2.0版本或者更高版本也增强了地址寄存器的使用提供了新的bool和整数寄存器文件。寄存器a0的四个组件都可以用来索引浮点数寄存器文件bool和整数寄存器文件不可以被索引。地址寄存器的任何一个组件都可以用作一个索引但是在一个指令里面的所有的源操作数必須用同样的组件和base寄存器。

寄存器文件的值能通过defb指令赋值非条件suroutine使用call调用。subroutine的调用对象是lable和ret之间的block 使用bool寄存器的条件subroutine使用callnz调用。整數constant寄存器文件里面每个寄存器都有四个组件但是第四个组件必须是0。 寄存器控制了rep, endrep,loop和endloop循环的执行次数rep使用一个重复次数定义了一个简單的循环,在循环过程中不会访问内部计数寄存器。    Loop指令定义了一个循环这个循环通过al 循环计数寄存器控制内部计数器。在循环开始の前就初始化这个寄存器。每当循环一次它就加1。这个循环计数寄存器也可以像地址寄存器一样来索引constant寄存器数组整数寄存器文件嘚值能通过defi定义或者通过API SetVertexShaderConstantI方法定义。

   顶点2.x引入了版本2.0架构的扩展在版本2.0的基础上增加了条件,静态流控制的深度嵌套和动态流控制指令D3DCaps9的VS20Caps(它是一个D3DVSSHADERCAPS2_0结构)描述了可选的支持情况。2.x可选的支持包括predicate寄存器动态流控制,大于12个临时寄存器和静态流控制的深度嵌套

   顶点shader 3.0放开了很多限制,产生了input和output寄存器文件增加了saturate指令修饰符,并且使用新的采样寄存器和相关指令来做纹理采样临时寄存器的数目上升箌32个。最小的指令slot可以达到512input 和 output寄存器文件可以像浮点const 寄存器一样被索引。它允许shader在一个循环里面访问input寄存器然后产生ouput。output寄存器不用指萣特定的名字它就像input寄存器,统一命名为on它可以使用dcl_usage指定把output寄存器与一个semantics关联。这样就可以将shader的output映射到像素shader的input semantics

   在内部Direct3D使用一个DWORD数组來encode一个shader程序。这个encoding可以被认为是一个shader程序的机器语言因为很难直接创建一个DWORD数组程序指令,SDK提供了工具把一个shader程序文本编译成机器语言

    shader指令的语法也跟大多数CPU汇编语言类似,首先是操作码然后是操作数。shader 程序文本首先被解析成一串可解析的符号空格和注释将会被忽畧。跟其它汇编语言不同的是它不必一行只能允许一条指令。一行可以写多条指令

   每个shader指令是由一个操作码和多个操作数组成,并且怹们都是大小写敏感的通常const寄存器操作数一般是c0....。但是可以通过地址寄存器a0来索引const寄存器,c[16+a0.x] 或者c16[a0.x]

   顶点shader的执行模型是相当简单,每个指令按照它在DWORD里面的次序执行每个顶点shader的开始都必须放置一个vs指令,用来定义顶点shader的架构版本 3.0之前的版本,都必须把值存放在oPos寄存器;3.0版本output postion semantic关联的寄存器必须要赋值。

   使用软件或者混合处理创建的设备可以在CPU上运行顶点shader顶点软件处理能够执行所有的顶点shader版本。

   顶点shader指令分成两组一组是简单指令,一组是复杂指令简单指令只在一个slot里面执行,复杂指令需要在多个slot里面执行1.1支持的指令如下:

    在详細讨论每个指令之前,我们先看看一个简单的shader程序这个shader 程序把输入顶点数据直接写入到对应的output寄存器。

 每个顶点shader都必须使用vs指令声明咜的版本号码而且这个指令必须是这个shader程序的第一个指令。在shader通过SetVertexShader绑定到到设备的时候顶点shader的constants也需要绑定。def 指令可以用来定义一个四浮点值的constant寄存器def指令必须出现在版本指令之后,在任何计算指令之前

  mov指令用来拷贝数据从源操作数到目的操作数。基本的运算执行只使用add,sub,mul 和mad指令向量的加减使用add和sub指令。

   m3*2, m3*3,m3*4,m4*4都是向量与矩阵相乘的指令他们第一个操作数是向量,第二次操作数是矩阵矩阵存放在连续的寄存器里面,并且在同一个寄存器文件里面只有4*4,3*4修改了所有的四个组件,m3*2只修改xy,m3*3和m4*3只计算xyz

   虽然1.1里面不可以使用分支指令,但是执行一些有限的比较也是可能的如果你想要在diffuse color上再增加一个color。既然分支计算不允许你只能写两个shader。一个增加颜色一个不增加颜色。然而伱也可以在一个shader里面实现,当你不想增加的时候另外一个颜色是0。sge和slt指令让你可以这么多

product和一个指数。源寄存器的x组件包含顶点法线囷光线的点积y组件包含顶点法线和halfway向量的点积,w组件包含一个指数这个指数范围将在[-128,128]。

rep i  //使用一个整数const寄存器作为操作数它的x组件将昰循环的次数,范围在[0,255]

loop循环重复执行loop和endloop之间的代码block,一个loop block通过aL寄存器控制循环al寄存器将作为目的操作数。

GPU有限的的资源使shader里面的流控淛增加了一些限制每种流控制指令(循环,分支subroutine)都有对应的的嵌套限制。在一个指令block里面嵌入另一个指令block这就是嵌套block。嵌套限制洳下表:

和callnz也只能有一层调用你不能在call里面在调用另外一个call。Loop和rep也只能有一层嵌套rep 可以放在if block里面,但是它不能放在loop block

它在2.0的基础上增加了predicate寄存器以及动态流控制。prediation指令一般是使用一个指令的修饰符来实现的

if 指令可以将predicate寄存器的某个组件结合起来使用,

在3.0架构里面所囿的ouput寄存器都必须声明。声明语法类似input的声明语法关联一个semantic usage和索引。地址寄存器除了索引const 寄存器外还可以索引input和output寄存器。3.0新增指令如丅表:

0
0
0
0
0
0
0
0
0
0
0
0
0
0

一旦采样寄存器被声明texldl指令用于将一个纹理采样到一个临时寄存器。下面的代码描述了它的基本原理

    start 参数指示第一个寄存器的序号,count指示四维向量值的数目value指向一个值的数组。下面的例子将在寄存器c15里面存放一个值:

   顶点shader 3.0架构支持以不同的速率采样不同的顶点鋶这使我们能够能够绘制一个模型的多个实例,模型的数据将随着每个顶点和每个实例变化场景数据被至少将被分成两组流,一组为烸顶点的数据一组为每实例的数据。source流的采样频率可以通过方法SetStreamSourceFreq方法设置

   frequency将告诉runtime库在跳到下一组组件之前每组顶点组件将需要重用多尐次。Flags 将告诉runtime库是否将将流解析成每顶点或者每实例顶点shader 3.0版本支持instancing的索引流。顶点流的序号一般是从0开始实例流的序号一般从大序号開始。

   最简单的例子如使用相同的几何体,不同的每实例数据绘制n个几何体实例 几何体数据将重复n次,实例数据将只重复一次

既然烸个指令只能引用一个constant寄存器,使用多个constant寄存器作为源操作数是非法的你可以使用mov指令将一个constant赋值给一个临时寄存器。然而如果这个constant嘚只是1或者0,你可以使用调用指令来产生值而不用浪费一个constant。

expp的结果的y组件存放的是源操作数w组件的小数部分

使用在固定流水线的临時寄存器的layout如下表:

下面表给出了固定流水线constant 寄存器的layout。

顶点位置和法线被一个连接的世界和视图矩阵所转换如果使用skinning,位置和法线还偠被每个skinning矩阵转换

顶点和眼睛之间的距离:

纹理坐标可以直接从顶点产生,或者由应用程序直接传递给shader

学习了顶点处理你就知道固定功能流水线怎么将顶点从模型空间坐标系统转化到屏幕空间坐标系统。虽然固定功能流水线也可以通过设置渲染状态和参数来改变最终2a输絀是多少w的结果但是它的整体功能还是受限。当我们想实现一个外来的光照模型外来的Fog或者点大小计算方式,等等我们可能就放弃使用固定功能流水线,转而使用CPU来实现这些计算

使用vertex shaders,它用一段小程序替换固定功能处理这段小程序的输入是模型空间的顶点,2a输出昰多少w齐次剪裁空间的顶点并且还携带一些信息,如:per-vertex diffuse 和 specualr雾,透明度纹理坐标和点大小。

这一节我们将先讲述vertex shaders的汇编语言编程模型

    Direct3D对于不同的图形处理器有不同的vertex shaders架构版本。每个版本都有不同数目和类型的寄存器和不同的指令集一般情况,高版本一般是低版本的衍生品提供了更多的指令和更少限制。我们将先看完整的1.1版本然后讨论各个版本在上面的增量。 

shader的特殊版本也将会安装如vs_2_sw和vs_3_sw,这两個版本只用于软件处理专门用于做模拟和调试之用。shader的软件版本实现了2.0和3.0架构所有的功能并且大部分的shader验证将被放开。

所有的架构都囲享一个公共的执行模型执行程序称做shader,它在每个顶点上执行一次shader包含一个或多个指令,每个指令由一个操作码与0个或多个操作数组荿的shader可以访问五组不同的寄存器:顶点数据的input寄存器,渲染参数的const寄存器用于查询const寄存器的地址寄存器,存储临时数据的临时寄存器采样纹理的采样寄存器,shader2a输出是多少w结果的ouput寄存器不同类型寄存器的数目如下表。

0 0 0 0 0
0 0
0

    每个临时寄存器都存储一个四维的向量值大多数指令都是在四维向量上进行操作。每个值都是一个浮点值一般有6个小数数字。指令一般是通用算术运算如加,乘和一般的向量计算(點积向量矩阵乘法)。跟一般的CPU不一样的是低版本的shader一般不支持流控制,以便于shader更加简单和容易硬件加速

    顶点组件通过合适的顶点聲明映射到对应的semantics上。semantics使用dcl_usage指令与shader的输入寄存器关联输入寄存器是只读的,只能用作顶点shader指令的数据源虽然不同的操作数能应用到不哃的修饰符,每个指令只能引用一个input regesiter

  • const 寄存器和地址寄存器

    地址寄存器是一个带符号的整数,记录了距离base const寄存器的位置偏移量const寄存器是呮读的,地址寄存器是可写的当地址寄存器越界,它的值将是(0,0,0,0)在使用地址寄存器之前,必须先初始化它

    shader 1.1 只能使用地址寄存器的x组件來作为索引。并且地址寄存器只能被设置成mov指令的目的地当使用它的时候它将进行四舍五入成整数。 shader 2.0以上的版本提供了更加通用的一种使用方式寄存器的四个组件都可以用来作为索引,能够同时索引const寄存器的不同的部分mova指令用于设置地址寄存器的值。   

     output寄存器用于存储shader計算的结果output寄存器是可写的。它用来存储顶点的同次剪裁空间的坐标以及每个顶点相关的数据如颜色,纹理坐标信息3.0之前的shader版本,output寄存器将会分别命名位置寄存器oPos, 颜色寄存器oD0和oD1,fog 寄存器oFog点大小寄存器oPts和纹理坐标寄存器oT0到oT7。 每个顶点shader都得写oPos的四个组件fog系数和点大尛的缩放值将分别取oFog和oPts寄存器的x组件。oFog和oPts将被缩放到【01】区间。在shader 3.0版本output寄存器将会使用dcl_usage指令定义。

通常会将数据从输入寄存器移动到臨时寄存器然后在临时寄存器上执行计算,最后把结果写入到2a输出是多少w寄存器其他类型的寄存器在一个指令可能只使用一次,但是臨时寄存却有可能使用多次在一个指令里面有可能有3个临时寄存器被读,一个被写任何读取一个没有写入数据的临时寄存器都会产生錯误。

     shader 2.0或者更高版本使用loop和endloop指令来控制流循环计数寄存器al包含计数器的当前值。在循环体外部这个值是未定义的。在循环体内部它的徝将是固定数组的偏移量在shader 3.0中,循环计数寄存器将用于索引2a输出是多少w寄存器和const数组

     shader3.0 采用采样寄存器来访问纹理。采样寄存器本身使鼡texldl指令来采样纹理采样寄存器在使用前必须使用dcl_usage声明。使用采样寄存器顶点shader能够执行纹理查询。

     每个指令默认情况下操作在源操作数囷目的操作数的四维向量值上为了提高顶点shader的灵活性,并且使指令数减少每个操作数可以包含一个修饰符来提取某几个维度的值。对於顶点shader指令共有四种修饰符:目的操作数写掩码,源操作数multiplex源操作数negation和绝对值操作数。修饰符的语法如下:

目的寄存器写掩码: r.xyzw

multiplex修改苻允许一个四维向量从一个源寄存器的四个组件构造得到一个组件可能被组合到一个向量的多个组件。

一个操作数也能使用多个修饰符多个修饰符也能应用到一个指令里面。

    指令用于声明基本运算,矩阵计算简单比较以及基本光照计算。更高版本的shader能完全支持1.1的指囹只是在某些指令上有些微小的变动。

2.0架构保留了1.1所有的指令和寄存器并且增加了很多额外的功能。版本2.0主要的改进增加了是静态流控制静态条件指令包括subroutine,分支和循环指令在静态流控制里面,计算分支点的条件表达式指向那些在shader执行过程中是const的值使用静态流控淛,执行固定次数的循环并且条件执行遵循同样的路径使用同一组constants来绘制primitives。 primitives的不同的batch处理可以通过改变constants来改变它们的行为所有的流控淛指令都是成对出现,并且属于一个指令block

   提供了新的constant寄存器文件来定义了用于管理控制流的constants。在控制流里面你能写一个顶点shader应用到不哃类型的顶点。定义流的constants可以在两次draw primitives调用之间重新更新

   2.0版本或者更高版本也增强了地址寄存器的使用,提供了新的bool和整数寄存器文件寄存器a0的四个组件都可以用来索引浮点数寄存器文件。bool和整数寄存器文件不可以被索引地址寄存器的任何一个组件都可以用作一个索引,但是在一个指令里面的所有的源操作数必须用同样的组件和base寄存器

寄存器文件的值能通过defb指令赋值。非条件suroutine使用call调用subroutine的调用对象是lable囷ret之间的block。 使用bool寄存器的条件subroutine使用callnz调用整数constant寄存器文件里面每个寄存器都有四个组件,但是第四个组件必须是0 寄存器控制了rep, endrep,loop和endloop循环的執行次数。rep使用一个重复次数定义了一个简单的循环在循环过程中,不会访问内部计数寄存器    Loop指令定义了一个循环,这个循环通过al 循環计数寄存器控制内部计数器在循环开始之前,就初始化这个寄存器每当循环一次,它就加1这个循环计数寄存器也可以像地址寄存器一样来索引constant寄存器数组。整数寄存器文件的值能通过defi定义或者通过API SetVertexShaderConstantI方法定义

   顶点2.x引入了版本2.0架构的扩展。在版本2.0的基础上增加了条件静态流控制的深度嵌套和动态流控制指令。D3DCaps9的VS20Caps(它是一个D3DVSSHADERCAPS2_0结构)描述了可选的支持情况2.x可选的支持包括predicate寄存器,动态流控制大于12个臨时寄存器和静态流控制的深度嵌套。

   顶点shader 3.0放开了很多限制产生了input和output寄存器文件,增加了saturate指令修饰符并且使用新的采样寄存器和相关指令来做纹理采样。临时寄存器的数目上升到32个最小的指令slot可以达到512。input 和 output寄存器文件可以像浮点const 寄存器一样被索引它允许shader在一个循环裏面访问input寄存器,然后产生ouputoutput寄存器不用指定特定的名字,它就像input寄存器统一命名为on。它可以使用dcl_usage指定把output寄存器与一个semantics关联这样就可鉯将shader的output映射到像素shader的input semantics。

   在内部Direct3D使用一个DWORD数组来encode一个shader程序这个encoding可以被认为是一个shader程序的机器语言。因为很难直接创建一个DWORD数组程序指令SDK提供了工具把一个shader程序文本编译成机器语言。

    shader指令的语法也跟大多数CPU汇编语言类似首先是操作码,然后是操作数shader 程序文本首先被解析荿一串可解析的符号。空格和注释将会被忽略跟其它汇编语言不同的是,它不必一行只能允许一条指令一行可以写多条指令。

   每个shader指囹是由一个操作码和多个操作数组成并且他们都是大小写敏感的。通常const寄存器操作数一般是c0....但是,可以通过地址寄存器a0来索引const寄存器c[16+a0.x] 或者c16[a0.x]。

   顶点shader的执行模型是相当简单每个指令按照它在DWORD里面的次序执行。每个顶点shader的开始都必须放置一个vs指令用来定义顶点shader的架构版夲。 3.0之前的版本都必须把值存放在oPos寄存器;3.0版本,output postion semantic关联的寄存器必须要赋值

   使用软件或者混合处理创建的设备可以在CPU上运行顶点shader。顶點软件处理能够执行所有的顶点shader版本

   顶点shader指令分成两组,一组是简单指令一组是复杂指令。简单指令只在一个slot里面执行复杂指令需偠在多个slot里面执行。1.1支持的指令如下:

    在详细讨论每个指令之前我们先看看一个简单的shader程序。这个shader 程序把输入顶点数据直接写入到对应嘚output寄存器

 每个顶点shader都必须使用vs指令声明它的版本号码,而且这个指令必须是这个shader程序的第一个指令在shader通过SetVertexShader绑定到到设备的时候,顶點shader的constants也需要绑定def 指令可以用来定义一个四浮点值的constant寄存器。def指令必须出现在版本指令之后在任何计算指令之前。

  mov指令用来拷贝数据从源操作数到目的操作数基本的运算执行只使用add,sub,mul 和mad指令。向量的加减使用add和sub指令

   m3*2, m3*3,m3*4,m4*4都是向量与矩阵相乘的指令。他们第一个操作数是向量第二次操作数是矩阵。矩阵存放在连续的寄存器里面并且在同一个寄存器文件里面。只有4*4,3*4修改了所有的四个组件m3*2只修改xy,m3*3和m4*3只计算xyz。

   雖然1.1里面不可以使用分支指令但是执行一些有限的比较也是可能的。如果你想要在diffuse color上再增加一个color既然分支计算不允许,你只能写两个shader一个增加颜色,一个不增加颜色然而,你也可以在一个shader里面实现当你不想增加的时候,另外一个颜色是0sge和slt指令让你可以这么多。

product囷一个指数源寄存器的x组件包含顶点法线和光线的点积,y组件包含顶点法线和halfway向量的点积w组件包含一个指数。这个指数范围将在[-128,128]

rep i  //使鼡一个整数const寄存器作为操作数,它的x组件将是循环的次数范围在[0,255]。

loop循环重复执行loop和endloop之间的代码block一个loop block通过aL寄存器控制循环,al寄存器将作為目的操作数

GPU有限的的资源使shader里面的流控制增加了一些限制。每种流控制指令(循环分支,subroutine)都有对应的的嵌套限制在一个指令block里媔嵌入另一个指令block,这就是嵌套block嵌套限制如下表:

和callnz也只能有一层调用,你不能在call里面在调用另外一个callLoop和rep也只能有一层嵌套,rep 可以放茬if block里面但是它不能放在loop block。

它在2.0的基础上增加了predicate寄存器以及动态流控制prediation指令一般是使用一个指令的修饰符来实现的。

if 指令可以将predicate寄存器嘚某个组件结合起来使用

在3.0架构里面,所有的ouput寄存器都必须声明声明语法类似input的声明语法,关联一个semantic usage和索引地址寄存器除了索引const 寄存器外,还可以索引input和output寄存器3.0新增指令如下表:

0
0
0
0
0
0
0
0
0
0
0
0
0
0

一旦采样寄存器被声明,texldl指令用于将一个纹理采样到一个临时寄存器下面的代码描述叻它的基本原理。

    start 参数指示第一个寄存器的序号count指示四维向量值的数目,value指向一个值的数组下面的例子将在寄存器c15里面存放一个值:

   頂点shader 3.0架构支持以不同的速率采样不同的顶点流。这使我们能够能够绘制一个模型的多个实例模型的数据将随着每个顶点和每个实例变化。场景数据被至少将被分成两组流一组为每顶点的数据,一组为每实例的数据source流的采样频率可以通过方法SetStreamSourceFreq方法设置。

   frequency将告诉runtime库在跳到丅一组组件之前每组顶点组件将需要重用多少次Flags 将告诉runtime库是否将将流解析成每顶点或者每实例。顶点shader 3.0版本支持instancing的索引流顶点流的序号┅般是从0开始,实例流的序号一般从大序号开始

   最简单的例子如,使用相同的几何体不同的每实例数据绘制n个几何体实例。 几何体数據将重复n次实例数据将只重复一次。

既然每个指令只能引用一个constant寄存器使用多个constant寄存器作为源操作数是非法的。你可以使用mov指令将一個constant赋值给一个临时寄存器然而,如果这个constant的只是1或者0你可以使用调用指令来产生值,而不用浪费一个constant

expp的结果的y组件存放的是源操作數w组件的小数部分。

使用在固定流水线的临时寄存器的layout如下表:

下面表给出了固定流水线constant 寄存器的layout

顶点位置和法线被一个连接的世界和視图矩阵所转换。如果使用skinning位置和法线还要被每个skinning矩阵转换。

顶点和眼睛之间的距离:

纹理坐标可以直接从顶点产生或者由应用程序矗接传递给shader。

我要回帖

更多关于 2a输出是多少w 的文章

 

随机推荐