我們已經知道可以使用vertex shader替換固定功能的頂點處理,pixel shader則用來替換固定功能的像素處理。多個紋理階段串聯可以完全被pixel shader所替換。specular addition,霧化以及frame buffer處理則不會受pixel shader的影響。
使用固定功能像素處理,應用程序需要爲每個texture stage設置狀態,並且嘗試在多紋理串聯的受限數據流裏執行per-pixel處理。使用pixel shader,你只要寫一個很小的程序,從紋理裏面採樣,然後組合採樣值產生一個新的顏色,將這個顏色值傳遞到Frame buffer, 做進一步的處理。
在DirectX 9.0C裏面Direct3D有幾種不同的pixel shader 架構版本。我們將看看每個版本的寄存器模型,指令模型和指令集。跟vertex shader一樣,pixel shader也是使用的是一組Token,每個指令一個Token。大部分應用程序不會直接構建TOKEN數組,將會使用D3DX將文本指令編譯成TOKEN數組。
Pixel Shader Architecture
pixel shader的架構圖
在所有的版本里面裏面pixel shader的架構基本都類似,指令集和寄存器文件有所不一樣。Pixel shader 必須執行兩項任務:描述紋理是怎麼尋址採樣以及怎麼組合採樣值產生新的顏色值。
Pixel Shader的架構版本
各個版本feature區別列表:
Feature | 1.0 | 1.1 | 1.2 | 1.3 | Phase 1 | 1.4 | Phase 2 |
Arithmetic Instructions | 8 | 8 | 8 | 8 | 8 | 8 | |
Texture Address instructions | 4 | 4 | 4 | 4 | 6 | 6 | |
Total Instructions | 8 | 12 | 12 | 12 | 14 | 14 | |
Constant registers(cn) | 8 | 8 | 8 | 8 | 8 | ||
temporary registers(rn) | 2 | 2 | 2 | 2 | 6 | ||
texture registers(tn) | 4 | 4 | 4 | 4 | 6 | ||
color registers(vn) | 2 | 2 | 2 | 2 | 0 | 2 |
各個版本可用指令列表:
Instruction | Syntax | Meaning | 1.0 | 1.1 | 1.2 | 1.3 | 1.4 |
add | d,s0,s1 | component addition | YES | YES | YES | YES | YES |
bem | d.rg,s0,s1 | bump enviroment map | YES | ||||
cmp | d,s0,s1,s2 | compare to 0.0 | YES | YES | YES | ||
cnd | d,s0,s1,s2 | compare to 0.5 | YES | YES | YES | YES | YES |
def | d,v0,v1,v2,v3 | constant definition | YES | YES | YES | YES | YES |
dp3 | d,s0,s1 | dot product | YES | YES | YES | YES | YES |
dp4 | d,s0,s1 | dot product | YES | YES | YES | ||
lrp | d,s0,s1,s2 | linear interpolation | YES | YES | YES | YES | YES |
mad | d,s0,s1,s2 | multiply and add | YES | YESS | YES | YES | YES |
mov | d,s | register copy | YES | YES | YES | YES | YES |
mul | d,s0,s1 | component multiply | YES | YES | YES | YES | YES |
nop | no operation | YES | YES | YES | YES | YES | |
phase | instruction phase | YES | |||||
ps | .major.minor | shader version | YES | YES | YES | YES | YES |
sub | d,s0,s1 | component subtraction | YES | YES | YES | YES | YES |
tex | d | sample texture | YES | YES | YES | YES | |
texbem | d,s | bump enviroment map | YES | YES | YES | YES | |
texbeml | d,s | bumpmap with luminance | YES | YES | YES | YES | |
texcoord | d | texture is coordinate | YES | YES | YES | YES | |
texcrd | d,s | texture is coordinate | YES | ||||
texdepth | d | compute pixel depth | YES | ||||
texdp3 | d,s | texture dot product | YES | YES | |||
texdp3tex | d,s | dot product with lookup | YES | YES | |||
texkill | s | kill source pixel | YES | YES | YES | YES | YES |
texld | d,s | sample from register | YES | ||||
texm3*2depth | d,s | compute pixel depth | YES | ||||
texm3*2pad | d,s | partial matrix product | YES | YES | YES | YES | |
texm3*2tex | d,s | final matrix product | YES | YES | YES | YES | |
texm3*3 | d,s | final matrix product | YES | YES | |||
texm3*3pad | d,s | partial matrix product | YES | YES | YES | YES | |
texm3*3spec | d,s0,s1,s2 | reflection vector lookup | YES | YES | YES | YES | |
texm3*3tex | d,s | final matrix product | YES | YES | YES | YES | |
texm3*3vspec | d,s | variable reflection lookup | YES | YES | YES | YES | |
texreg2ar | d,s | dependent texture lookup | YES | YES | YES | YES | |
texreg2gb | d,s | dependent texture lookup | YES | YES | YES | YES | |
texreg2rgb | d,s | dependent texture lookup | YES | YES |
Pixel Shader 1.0 Register Restriction
Instruction | Operand | cn | rn | tn | vn |
add d,s0,s1 | d s0,s1 | * | * * | * | * |
cnd d,s0,s1,s2 | d s0 s1,s2 | * | * r0.a * | * | * |
dp3 d,s0,s1 | d s0,s1 | * | * * | * | * |
lrp d,s0,s1,s2 | d s0,s1,s2 | * | * * | * | * |
mad d,s0,s1,s2 | d s0,s1,s2 | * | * * | * | * |
mov d,s | d s | * | * * | * | * |
mul d,s0,s1 | d s0,s1 | * | * * | * | * |
sub d,s0,s1 | d s0,s1 | * | * * | * | * |
tex d | d | * | |||
texbem d,s | d,s | * | |||
texbeml d,s | d,s | * | |||
texcoord d | d | * | |||
texkill s | s | * | |||
texm3*2pad d,s | d,s | * | |||
texm3*2tex d,s | d,s | * | |||
texm3*3pad d,s | d,s | * | |||
texm3*2spec d,s0,s1,s2 | d,s0,s1 s2 | * | * | ||
texm3*3tex d,s | d,s | * | |||
texm3*3vspec | d,s | * | |||
texreg2ar d,s | d,s | * | |||
texreg2gb d,s | d,s | * |
Pixel Shader 1.1 Register Restrictions
Instruction | Operand | cn | rn | tn | vn |
add d,s0,s1 | d s0,s1 | * | * * | * * | * |
cnd d,s0,s1,s2 | d s0 s1,s2 | * | * r0.a * | * * | * |
dp3 d,s0,s1 | d s0,s1 | * | * * | * * | * |
lrp d,s0,s1,s2 | d s0,s1,s2 | * | * * | * * | * |
mad d,s0,s1,s2 | d s0,s1,s2 | * | * * | * * | * |
mov d,s | d s | * | * * | * * | * |
mul d,s0,s1 | d s0,s1 | * | * * | * * | * |
sub d,s0,s1 | d s0,s1 | * | * * | * * | * |
tex d | d | * | |||
texbem d,s | d,s | * | |||
texbeml d,s | d,s | * | |||
texcoord d | d | * | |||
texkill s | s | * | |||
texm3*2pad d,s | d,s | * | |||
texm3*2tex d,s | d,s | * | |||
texm3*3pad d,s | d,s | * | |||
texm3*2spec d,s0,s1,s2 | d,s0,s1 s2 | * | * | ||
texm3*3tex d,s | d,s | * | |||
texm3*3vspec | d,s | * | |||
texreg2ar d,s | d,s | * | |||
texreg2gb d,s | d,s | * |
Pixel Shader 1.2 Register Restrictions
Instruction | Operand | cn | rn | tn | vn |
add d,s0,s1 | d s0,s1 | * | * * | * * | * |
cmp d,s0,s1,s2 | d s0,s1,s2 | * | * * | * * | * |
cnd d,s0,s1,s2 | d s0 s1,s2 | * | * r0.a * | * * | * |
dp3 d,s0,s1 | d s0,s1 | * | * * | * * | * |
dp4 d,s0,s1 | d s0,s1 | * | * * | * * | * |
lrp d,s0,s1,s2 | d s0,s1,s2 | * | * * | * * | * |
mad d,s0,s1,s2 | d s0,s1,s2 | * | * * | * * | * |
mov d,s | d s | * | * * | * * | * |
mul d,s0,s1 | d s0,s1 | * | * * | * * | * |
sub d,s0,s1 | d s0,s1 | * | * * | * * | * |
tex d | d | * | |||
texbem d,s | d,s | * | |||
texbeml d,s | d,s | * | |||
texcoord d | d | * | |||
texkill s | s | * | |||
texm3*2pad d,s | d,s | * | |||
texm3*2tex d,s | d,s | * | |||
texm3*3pad d,s | d,s | * | |||
texm3*2spec d,s0,s1,s2 | d,s0,s1 s2 | * | * | ||
texm3*3tex d,s | d,s | * | |||
texm3*3vspec | d,s | * | |||
texreg2ar d,s | d,s | * | |||
texreg2gb d,s | d,s | * | |||
texreg2rgb d,s | d,s | * |
Pixel Shader 1.3 Register Restrictions
Instruction | Operand | cn | rn | tn | vn |
add d,s0,s1 | d s0,s1 | * | * * | * * | * |
cmp d,s0,s1,s2 | d s0,s1,s2 | * | * * | * * | * |
cnd d,s0,s1,s2 | d s0 s1,s2 | * | * r0.a * | * * | * |
dp3 d,s0,s1 | d s0,s1 | * | * * | * * | * |
dp4 d,s0,s1 | d s0,s1 | * | * * | * * | * |
lrp d,s0,s1,s2 | d s0,s1,s2 | * | * * | * * | * |
mad d,s0,s1,s2 | d s0,s1,s2 | * | * * | * * | * |
mov d,s | d s | * | * * | * * | * |
mul d,s0,s1 | d s0,s1 | * | * * | * * | * |
sub d,s0,s1 | d s0,s1 | * | * * | * * | * |
tex d | d | * | |||
texbem d,s | d,s | * | |||
texbeml d,s | d,s | * | |||
texcoord d | d | * | |||
texdp3 d,s | d,s | * | |||
tex3p3tex | d,s | * | |||
texkill s | s | * | |||
texm3*2depth d,s | d,s | * | |||
texm3*2pad d,s | d,s | * | |||
texm3*2tex d,s | d,s | * | |||
texm3*3pad d,s | d,s | * | |||
texm3*3spec d,s0,s1,s2 | d,s0,s1 s2 | * | * | ||
texm3*3tex d,s | d,s | * | |||
texm3*3vspec | d,s | * | |||
texreg2ar d,s | d,s | * | |||
texreg2gb d,s | d,s | * | |||
texreg2rgb d,s | d,s | * |
Pixel Shader 1.4 Register Restrictions:Phase 1
Instruction | Operand | cn | rn | tn | vn |
add d,s0,s1 | d s0,s1 | * | * * | ||
bem d.rg,s0,s1 | d s0 s1 | * | * * * | ||
cmp d,s0,s1,s2 | d s0,s1,s2 | * | * * | ||
cnd d,s0,s1,s2 | d s0,s1,s2 | * | * * | ||
dp3 d,s0,s1 | d s0,s1 | * | * * | ||
dp4 d,s0,s1 | d s0,s1 | * | * * | * | |
lrp d,s0,s1,s2 | d s0,s1,s2 | * | * * | ||
mad d,s0,s1,s2 | d s0,s1,s2 | * | * * | * * | * |
mov d,s | d s | * | * * | * * | * |
mul d,s0,s1 | d s0,s1 | * | * * | * * | * |
sub d,s0,s1 | d s0,s1 | * | * * | * * | * |
tex d | d | * |
Pixel Shader 1.4 Register Restrictions: Phase 2
Instruction | Operand | cn | rn | tn | vn |
add d,s0,s1 | d s0,s1 | * | * * | * | |
cmp d,s0,s1,s2 | d s0,s1,s2 | * | * * | * | |
cnd d,s0,s1,s2 | d s0,s1,s2 | * | * * | * | |
dp3 d,s0,s1 | d s0,s1 | * | * * | * | |
dp4 d,s0,s1 | d s0,s1 | * | * * | * | |
lrp d,s0,s1,s2 | d s0,s1,s2 | * | * * | * | |
mad d,s0,s1,s2 | d s0,s1,s2 | * | * * | * | |
mov d,s | d s | * | * * | * | |
mul d,s0,s1 | d s0,s1 | * | * * | * | |
sub d,s0,s1 | d s0,s1 | * | * * | * | |
texcrd d,s | d s | * | * | ||
texdepth d | d | r5 | |||
texkill s | s | * | * | ||
texld d,s | d s | * * | * |
- Pixel shader 1.0
版本1.0包含一些算術操作和紋理尋址指令。通常,算術指令能使用任何寄存器作爲源操作數,任何臨時寄存器作爲目的操作數,但是cnd指令除外,它只能使用r0.a作爲它的第一個源操作數。texXXXX類似的紋理尋址指令提供了紋理讀取操作。
- Pixel Shader 1.1
版本1.1擴展了1.0架構,允許更多的指令。算法指令的目的操作數可以是紋理寄存器tn.
- Pixel Shader 1.2
擴展了指令cmp,dp4,texdp3,texdp3tex,texm3*3和texreg2rgb。
- Pixel Shader 1.3
擴展了指令texm3*2depth。
- Pixel Shader 1.4
1.4歸納了紋理尋址以及共同phase指令階段的dependent紋理讀取的概念。phase指令是紋理地址和紋理採樣之間的標誌。PS1.4指令組成:math, address, phase,math,address。在指令裝載的不同的階段可使用的寄存器是不一樣的。
在階段1,算術指令能夠使用const和臨時寄存爲作爲他們的源操作數,臨時寄存器作爲他們的目的寄存器。紋理尋址指令能夠使用紋理寄存器作爲他們的源操作數,臨時寄存器作爲他們的目的操作數。
在階段2, 算術指令除了臨時和constant寄存器還能使用顏色寄存器作爲他們的源操作數,算術指令的目的操作數必須是一個臨時寄存器。階段2的紋理尋址除了紋理寄存器還能夠使用臨時寄存器作爲源操作數。
- Pixel Shader 2.0
- Pixel Shader 2.X
- Pixel Shader 3.0
指令集
- 指令聲明
每個像素shader必須使用ps指令聲明它的架構版本。這個指令必須是pixel shader的第一個指令。major和minor必須要是架構的major和minor版本號碼。 在SetPixelShader綁定pixel shader的時候constant寄存器也要被綁定。def指令定義了constant寄存器。def指令系需要出現在版本指令以後計算指令之前。
- 基本算術指令
mov d,s
add d, s0,s1
sub d,s0,s1
mul d, s0,s1
mad d, s0,s1,s2
lrp d, s0,s1,s2
dp3 d , s0,s1
dp4 d, s0,s1
- 比較指令
cmp d,s0,s1,s2
d= (f(s0x,s1x,s2x),f(s0y,s1y,s2y),f(s0z,s1z,s2z),f(s0w,s1w,s2w)) f(a,b,c) = b(a >=0) ; c (a<0)
cnd d,s0,s1,s2
d= s1(s0a>0.5) s2(s0a<=0.5)
- 基本紋理尋址
tex d
d = Td(ud,vd,wd,qd)
texcoord d
d= (f(ud),f(vd),f(wd),1), f(x) = 0(x<0), x(0<=x<=1), 1(x>1)
texcrd d, s
d = (us,vs,ws,*)
texld d,s
d= Td(us,vs,ws)
texdp3 d,s
d = (f,f,f,f) f= (ud,vd,wd).(sr,sg,sb)
texdp3tex d,s
u' = (ud,vd,wd).(sr,sg,sb)
d = Td(u',0,0)
texkill s
abort if us<0 or vs <0 or ws <0
texm3*2pad d,s
d= (ud,vd,wd).(sr,sg,sb)
texm3*2tex d,s
u' = (ud-1,vd-1,wd-1).(sr,sg,sb)
v' = (ud,vd,wd).(sr,sg,sb)
d = Td(u',v')
texm3*2depth d,s
z = (ud-1,vd-1,wd-1).(sr,sg,sb)
w = (ud,vd,wd).(sr,sg,sb)
f= 1 (w=0) ; z/w(w<>0)
d= (f,f,f,f)
texm3*3pad d, s
d = (ud,vd,wd).(sr,sg,sb)
texm3*3 d,s
u' = (ud-2,vd-2,wd-2).(sr,sg,sb)
v' = (ud-1,vd-1,wd-1)(sr,sg,sb)
w' = (ud,vd,wd).(sr,sg,sb)
d = (u',v',w',1)
texm3*3tex d,s
u' = (ud-2,vd-2,wd-2).(sr,sg,sb)
v' = (ud-1,vd-1,wd-1)(sr,sg,sb)
w' = (ud,vd,wd).(sr,sg,sb)
d= (u',v',w')
texm3*3spec d, s0,s1
u' = (ud-2,vd-2,wd-2).(s0r,s0g,s0b)
v' = (ud-1,vd-1,wd-1)(s0r,s0g,s0b)
w' = (ud,vd,wd).(s0r,s0g,s0b)
n = (u',v',w')
(u'',v'',w'') = 2(n.s1/n.n )n - s1
d = Td(u'',v'',w'')
texm3*3vspec d, s0,s1
u' = (ud-2,vd-2,wd-2).(s0r,s0g,s0b)
v' = (ud-1,vd-1,wd-1).(s0r,s0g,s0b)
w' = (ud,vd,wd).(s0r,s0g,s0b)
n = (u',v',w')
e= (qd-2,qd-1,qd)
(u'',v'',w'') = 2(n.e/n.n)n -e
d = Td(u'',v'',w'')
texreg2ar d,s
d = Td(sa,sr)
texreg2gb d,s
d = Td(sg,sb)
texreg2rgb d, s
d = Td(sr,sg,sb)
texdepth s
z = (sr/sg(sg<>0)) ; 1 (sg = 0)
- bump mapping 指令
bem d, s0,s1
d.r = s0r + b00d s1r + b10d s1g
d.g = s0g + b10d s1r + b11d s1g
texbem d,s
u' = ud + b00d sr + b01d sg
v' = vd + b10d sr + b11d sg
d = Td(u',v')
texbeml d,s
u' = ud + b00d sr + b01d sg
v' = vd + b10d sr + b11d sg
d = Td(u',v1) (sbld + Od)
PS 2.0 指令
abx d, s
crs d, s0, s1
dcl d
dcl_textureType d
dp2add d, s0,s1,s2
exp d,sc
frc d,s
log d,sc
m3*2 d,s0,s1
m3*3 d,s0,s1
m3*4 d,s0,s1
m4*3 d,s0,s1
m4*4 d,s0,s1
max d,s0,s1
min d,s0,s1
nrm d,s
pow d,s0c,s1c
rcp d,sc
rsq d,sc
sincos d,s0c,s1,s2
texld d,s0,s1
texldb d,s0,s1
texldp d,s0,s1
PS 2.X 指令
defb
defi
label
call
callnz
callnz_pred
ret
dsx
dsy
if
else
endif
if_comp
if_pred
rep
endrep
break
break_comp
break_pred
setp
texldd
PS 3.0 指令
dcl_usage
loop
endloop
texldl
管理Pixle Shaders
設備上pixel shader的屬性使用SetPixelsShader和GetPixelShader管理。shader屬性是一個DWORD句柄,它對應一個DWORD Token數組,一個Token對應一個指令。
HRESULT GetPixelShader(DWORD * value);
HRESULT SetPixelShader(DWORD value);
Token與句柄之間的聯繫是通過CreatePixelShader創建的。爲了銷燬pixel shader句柄與Token的聯繫,並且釋放設備上的Token內存,釋放pixel shader物體上的所有的reference。 你能夠使用GetPixelShaderFunction取得相關的Token數組。
HRESULT CreatePixelShader(const DWORD * function, DWORD * result);
HRESULT GetPixelShaderFunction(DWORD handle,void * value, DWORD * size);
當爲了獲得pixel shader的token數組時,首先使用value爲空的調用,這樣可以取得Token數組的大小。然後再傳遞一個size大小的數組指針作爲value,這樣就可以返回某個pixel shader的Token的數組。
GetPixleShaderConstantF和SetPixelShaderConsantF方法管理constant寄存器。
Texture Stage State
pixel shader通過TSS Color Op和TSS Alpha OP替換了固定功能流水線的功能,但是它不能替換紋理尋址和採樣的機制。