Vertex Shader
Im folgenden Teil unseres Artikels befassen
wir uns mit den neuen Vertex Shader Modellen,
welche in DirectX 9.0 enthalten sind. Den
Modellen (1.1 gibt es seit DirectX 8.0) liegt
folgender Gedanke zu Grunde, da sie sich
in ihrer Leistungsfähigkeit unterscheiden:
- VS2.0 gilt als Basismodell, welches minimal
benötigt wird, um als DirectX 9.0 VPU
zu gelten.
- VS2.0 Extended ist eigentlich kein neues
Modell, es ist lediglich eine Erweiterung
des 2.0'er Modells, welches variabel durch CAP-Bits (Bitfelder, welche je nach
Fähigkeiten der Hardware gesetzt. werden)
zwischen dem VS2.0 und dem VS3.0 Modell liegt.
- VS3.0 ist als High-End Modell gedacht um
zukünftiger Hardware (und Herstellern)
ein Basismodell für ihre VPU's zu bieten,
es könnte in DirectX 10.0 als Basismodell
dienen.
- Daneben gibt es noch die Modelle VS 2_sw
und VS 3_sw, welche nur von der CPU ausgeführt
werden können und für Entwickler
gedacht sind.
Fähigkeiten
Vertex Shader Einheit |
DX8.1 VS1.1 |
DX9 VS2.0 |
DX9 VS2.0 Extended
/ VS 2_sw |
DX9 VS3.0
/ VS 3_sw
|
R300 VS |
NV30 VS |
Version |
1_1 |
2_0 |
2_x
|
3_0
|
2_0 |
2_x |
max. Instruktionen (nicht Befehle!)
pro Durchlauf |
128 |
65280 |
65280 |
65280
|
65280 |
65536 |
max. Instruktionen in einem Block |
128 |
256 |
256
|
512-32768
|
256 |
256 |
Fließkomma-Genauigkeit |
ja |
ja |
ja
|
ja
|
ja |
ja |
statische Flußsteuerung |
- |
(Tiefe 1) |
(Tiefe 1-4)
|
(Tiefe 1-4)
|
(Tiefe 1) |
(Tiefe ?) |
dynamische Flußsteuerung |
- |
- |
(Tiefe 0-24)
|
(Tiefe 0-24)
|
- |
(Tiefe ?) |
Predication |
- |
- |
ja
|
ja
|
- |
?
|
Texture Lookup |
- |
- |
-
|
ja
|
- |
? |
Vertex Stream Frequency
|
-
|
-
|
-
|
ja
|
-
|
-
|
Version
Gibt die Vertex Shader Version an. Aus der
Version 2_0 wird 2_x, falls eines oder mehrere der folgenden CAP-Bits gesetzt bzw. die
Werte vom 2_0 Standard abweichen:
D3DVS20CAPS_PREDICATION
DynamicFlowControlDepth
NumTemps
StaticFlowControlDepth
Instruktionen (nicht Befehle!) pro Durchlauf
Gibt an, wie lang ein Vertex Shader Programm
sein darf. Durch Schleifen und Sub-Routinen
kann ein VS-Programm deutlich länger
werden, als die max. 256 Instruktionen in
einem Block. Manche Befehle benötigen
mehrere Instruktionen, weshalb man Instruktion
und Befehl nicht gleichsetzen darf.
Fließkomma-Genauigkeit
Der Vertex Shader arbeitet seit Version 1.0
mit 32 Bit Fließkomma-Genauigkeit.
statische Flußsteuerung (die Tiefe gibt an, wie tief ich die Flußsteuerung
verschalten kann!)
Statische Flußsteuerung ist rech einfach
erklärt:
vs_2_0
defb b3, TRUE
if b3
// wenn b3 TRUE ist, dann gehe hier hin
else
// sonst mache hier weiter
endif
Jedoch sind hier keine komplexen Vergleich
im IF-Block möglich, lediglich die "Constant Boolean " Register, welche pro Register nur
die Werte 0 oder 1 haben können, dürfen
nach dem IF stehen. Weitere Befehle sind
z.B. loop, call, rep. Ich habe also bei der
statischen Flußsteuerung lediglich
die "Constant Boolean " Register mit denen ich Vergleiche
anstellen kann. Dies ist für komplexe
Aufgaben sehr hinderlich, da man nur über
Umwege (wenn überhaupt) kompliziertere
Vergleichen hinbekomme.
dynamische Flußsteuerung (die Tiefe gibt an, wie tief ich die Flußsteuerung
verschalten kann!)
Dynamische Flußsteuerung ist viel leistungsfähiger
als ihr statische Vertreter.
vs_2_x
if_lt r3.x, r4.y
// wenn r3.x kleiner ist als r4.y, dann gehe
hier hin
else
// sonst mache hier weiter
endif
Hier habe ich wesentlich mehr Möglichkeiten
z.B. den IF-Block zu beginnen (_gt "größer",
_lt "kleiner", _ge "größer
/ gleich", _le "kleiner / gleich",
_eq "gleich", _ne "ungleich"),
ich bin nicht an boolsche Register gebunden.
Ebenso hilft die dyn. Flußsteuerung
bei Schleifen, welche ich durch feinere Vergleichsmöglichkeiten
z.B. "break_lt r3.x, r4.y" - bricht
aus momentaner Schleife aus, wenn r3.x <
r4.y - beenden kann. Eine if_p0 Anweisung
ist ebenfalls möglich, wobei p0 das
Predicationsregister ist.
Predication(als wahr behaupten)
Predication ist eine feine Sache. Im Grunde
etwas ähnliches wie eine Flußsteuerung,
jedoch ohne Sprünge (zumindest aus der
Sicht des Programmierers). Erstmal benötigen wir eine neue Art
von Register, das "Predicate Register".
Im VS3.0 Modell gibt es davon 1 Stück,
p0. Das Register ist ein 4D Vektor mit den
4 Komponenten xyzw, aber jede Komponente
(also x, y, z, w) ist ein boolsches Register,
kann also nur 0(false) oder 1(true) enthalten.
vs_3_0
setp_le p0, r0, r2.z
bedeuted folgendes:
IF (r0.x <= r2.z) THEN p0.x = true ELSE false
IF (r0.y <= r2.z) THEN p0.x = true ELSE false
IF (r0.z <= r2.z) THEN p0.x = true ELSE false
IF (r0.w <= r2.z) THEN p0.x:= true ELSE false
Andere Vergleiche sind auch möglich.
So jetzt haben wir unser p0 Register gesetzt.
Was machen wir nun damit?
Wir können nun p0 dazu verwenden, bestimmte
Befehle auszuführen, falls das Predicate
Register für die entsprechende Komponente
eine 1 enthält.
p0.x=true
p0.y=false
p0.z=false
p0.w=true
(p0) add r4, r5, r6
Ohne (p0) würde das VS-Programm folgendes
tun:
r4.x = r5.x + r6.x
r4.y = r5.y + r6.y
r4.z = r5.z + r6.z
r4.w = r5.w + r6.w
Mit dem (p0) Befehl jedoch, rechnet er:
IF (p0.x = true) THEN r4.x = r5.x + r6.x
IF (p0.y = true) THEN r4.y = r5.y + r6.y
IF (p0.z = true) THEN r4.z = r5.z + r6.z
IF (p0.w = true) THEN r4.w = r5.w + r6.w
Es würden sich also r4.y und r4.z nicht
verändern, da p0.y und p0.z nicht "true"
enthalten.
Texture Lookup
Mittel "Texture Lookup" können
Texturedaten(4 Stück) im Vertex Shader
geladen werden. Somit könnte man z.B.
ein eigenes Displacement Mapping realisieren
oder andere Effekte.
SetSamplerState(D3DVERTEXTEXTURESAMPLER[0...3],
...);
SetTexture(D3DVERTEXTEXTURESAMPLER[0...3],
...);
vs_3_0
dcl_2d s0 // 2D Texture
...
mov rSrcTexcoord .w, MipMap-Level
texld rDest, rSrcTexcoord, s0
Vertex Stream Frequency
Bei den bisherigen Vertex Shadern (<3.0)
und der festen T&L Einheit wird der Vertex
Shader einmal pro Vertex ausgeführt.
Die "Input Register" wurden bei
jedem Aufruf mit neuen Vertexdaten von einem
Vertex Stream versorgt. Mit einer Änderung
der Frequenz kann man nun z.B. erreichen,
dass ein bestimmter Teil der "Input
Register" mit einer niedrigeren Frequenz
neue Daten bekommen. Stellt man die Frequenz
z.B. auf 2, dann bekommen die "Input
Register" (welche dem Stream zugeorndet
sind) lediglich bei jedem zweiten verarbeitetem
Eckpuntk neue Daten.
Register
Register Typ |
Art der Zugriffe:
Use/Read/Write |
DX8.1 VS1.1 |
DX 9 VS2.0 |
DX9 VS2.0 Extended
/ VS 2_sw |
DX 9 VS3. 0
/ VS 3_sw |
R300 VS
|
NV30 VS
|
Input Register - Führen Daten in den
Vertex Shader
|
Input |
r |
16 ( 4D Vektor) |
16 (4D Vektor) |
16 (4D Vektor) |
16 (4D Vektor) |
16 (4D Vektor)
|
16 (4D Vektor)
|
Temp |
r/w |
12 (4D Vektor) |
12 (4D Vektor) |
12-32 (4D Vektor) |
12-32 (4D Vektor) |
16 (4D Vektor)
|
16 (4D Vektor)
|
Constant Float |
r |
min. 96 (4D Vektor) |
min. 256 (4D Vektor) |
min. 256 (4D Vektor) |
min. 256 (4D Vektor) |
256 (4D Vektor)
|
256 (4D Vektor)
|
Constant Integer |
r |
- |
16 (4D Vektor) |
16 (4D Vektor) |
16 (4D Vektor) |
16 (4D Vektor)
|
16 (4D Vektor)
|
Constant Boolean |
r |
- |
16 Bits |
16 Bits |
16 Bits |
16 Bits
|
16 Bits
|
Address |
u/w |
1 (Skalar) |
1 (4D Vektor) |
1 (4D Vektor) |
1 (4D Vektor) |
1 (4D Vektor)
|
2 (4D Vektor)?
|
Loop Counter |
u |
- |
1 (Skalar) |
1 (Skalar) |
1 (Skalar) |
1 (Skalar)
|
1 (Skalar)
|
Predicate |
r/w |
- |
- |
- |
1 (4D Vektor) |
-
|
?
|
Sampler
|
r
|
-
|
4 (Skalar)
|
4 (Skalar)
|
4 (Skalar)
|
4 (Skalar)
|
4 (Skalar)
|
Anmerkungen
|
|
|
|
|
In allen VS-Modellen <3.0 konnten nur
die "Constant Float Register - c[]"
indexiert werden. Bei VS3.0 können durch
das "Loop Counter Register - aL"
Register auch die "Input Register -
v[]" und die "Output - o[]"
Register.
|
|
|
Output Register - Nehmen Resultate des Vertex Shaders auf
|
Position |
w |
1 (4D Vektor) |
1 (4D Vektor) |
1 (4D Vektor) |
- |
1 (4D Vektor)
|
1 (4D Vektor)
|
Point Size |
w |
1 (Skalar) |
1 (Skalar) |
1 (Skalar) |
- |
1 (Skalar)
|
1 (Skalar)
|
Fog Coordinate |
w |
1 (Skalar) |
1 (Skalar) |
1 (Skalar) |
- |
1 (Skalar)
|
1 (Skalar)
|
Texture Coordinate |
w |
8 (4D Vektor) |
8 (4D Vektor) |
8 (4D Vektor) |
- |
8 (4D Vektor)
|
8 (4D Vektor)
|
Diffuse/Specular Color |
w |
2 (4D Vektor) |
2 (4D Vektor) |
2 (4D Vektor) |
- |
2 (4D Vektor)
|
2 (4D Vektor)
|
Output
|
w
|
-
|
-
|
-
|
12 (4D Vektor)
|
-
|
-
|
Anmerkungen
|
|
|
|
|
Das VS3.0 Modell beseitzt keine starren Vorgaben
mehr, bei der Registerzuornung.
|
|
Der NV30 besitzt noch 2 (4D Vektor) "Back-Facing
Color Register, sowie 6 Clip-Distance Register(Skalar)".
Ob diese unter DirectX 9.0 nutzbar sind ist
noch unklar!
|
Bei den Registern unterscheiden sich die
Vertex Shader der Version 2.0 / 2.0 Extended
kaum noch. Lediglich die Anzahl der "Temp
Register" ändert sich. Gegenüber
der Vertex Shader Version 1.1 sind die Unterschiede
schon größer. Einzig die Vertex
Shader ab Version 2.0 Extended / 3.0 besitzen
das "Predicate Register", sowie
die 3.0'er auch universelle "Output"
Register.
Input Register (v#)
"Input Register" müssen zu
Begin des Vertex Shader Programms deklariert
werden. Es wird ihre Verwendung sowie die
Zuordnung festgelegt. Im Vertex Shader Programm
kann nur lesend auf die "Input Register"
zugegriffen werden.
vs_1_1
dcl_position0 v0
dcl_normal0 v3
dcl_texcoord0 v6
Temp Register (r[n])
"Temp Register" sind Allzweckregister.
Auf sie kann man lesend und schreibend einwirken.
vs_1_1
mov r0.x, v0.x
Constant Register - Float (c[n]), Integer
(i#) und Boolean (b#)
"Constant Register" gibt es seit dem
Vertex Shader 2.0 drei Typen. Einmal den
Typ "float", welchen es bereits
in den Vorgängerversionen 1.0 und 1.1
gab, sowie "integer" und "boolean".
Die "float" Version wird für
allgemeine Berechnungen genutzt. Die "integer"
und "boolean" hingegen für
statische/dynamische Flußsteuerung
und als Schleifenzähler.
Address Register (a0)
"Address Register" werden zur Adressierung
verwendet. Es können lediglich die "Constant
Float Register" indirekt adressiert
werden. Hier ein kurzes Beispiel:
vs_1_1
mov r0.x, c[a0.x + n].x // indirekt
mov r0.x, c[n].x // direkt
Loop Counter Register (aL)
Das "Loop Counter Register" wird
automatisch um 1 erhöht, wenn der Vertex
Shader in einen "loop" Block eintritt.
Predicate Register (p0)
Das "Predicate Register" wird,
wie im obigen Beispiel zu sehen war, zur
bedingungsabhängigen Ausführung
von Befehlen verwendet.
Sampler Register (s#)
Mit Hilfe des "Sampler Register"
können Texturedaten im Vertex Shader
verwendet werden. Sie Beispiel weiter oben.
Output Register (oPos, oPts, oFog, oT#, oD#
/ o#)
Ohne die "Output Register" würden
die fertigen Eckpunkte niemals aus dem Vertex
Shader heraus kommen. Beim VS3.0 gibt es
nur noch 12 o# Register. Hier ein kurzes
(unvollständiges) Beispiel:
// Defenition eines Eckpunktes
struct CUSTOMVERTEX_POS_NORM_COLOR1_TEX1
{
float
x, y, z;
// Koordinaten (4 Byte
*3)
float
nx, ny, nz; // Normalen
(4 Byte *3)
DWORD
color1;
// diffuse Farbe (4 Byte *1)
float
tu1, tv1;
// Texturekoordinaten (4 Byte *2)
};
// Eine Vertex Shader Deklaration, welche
die Verbindung zwischen "Input Registern"
und Vertexdaten ist
D3DVERTEXELEMENT9 decl[] =
{
{ 0, 0, D3DDECLTYPE_FLOAT3,
D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,
0 },
//v0 enthält unsere
Koordinaten, Rückgabe in oPos
{ 4, 12, D3DDECLTYPE_FLOAT3,
D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,
0 },
//v4 enthält unsere
Normalen, sie befinden sich 12 Bytes (4 Bytes
* 3 Komponenten) vom Anfang des Streams entfernt,
//kein Rückgabe
{ 7, 24, D3DDECLTYPE_D3DCOLOR,
D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DIFFUSE,
0 },
//v7 enthält unsere
diffuse Farbe, 24 Bytes (4 Bytes * 6 Komponenten)
vom Anfang des Streams entfernt
//Rückgabe in oD0
{ 8, 28, D3DDECLTYPE_FLOAT2,
D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,
0 },
//v8 enthält unsere
Texturekoordinaten, 28 Bytes (4 Bytes * 7
Komponenten) vom Anfang des Streams entfernt
//Rückgabe in oT0
D3DDECL_END()
};
// die Vertex Shader Konstante c[0] wird
gefüllt
float constants[4] = {0, 0.5f, 1.0f, 2.0f};
m_pd3dDevice->SetVertexShaderConstantF(
0, (float*)&constants, 1 );
// die Vertex Shader Konstante c[4] wird
gefüllt
D3DXMATRIX mat;
D3DXMatrixMultiply( &mat, &m_matView,
&m_matProj );
D3DXMatrixTranspose( &mat, &mat );
m_pd3dDevice->SetVertexShaderConstantF(
4, (float*)&mat, 4 );
// die Vertex Shader Konstante c[8] wird
gefüllt
float color[4] = {1,1,1,1};
m_pd3dDevice->SetVertexShaderConstantF(
8, (float*)&color, 1 );
// die Vertex Shader Konstante c[12] wird
gefüllt
float lightDir[4] = {-1,0,1,0};
m_pd3dDevice->SetVertexShaderConstantF(
12, (float*)&lightDir, 1 );
// Vertex Shader
// v0 Eckpunktkoordinaten
// v4 Normalen
// v7 diffuse Farbe
// v8 Texturekoordinaten
// c4 Matrix für die persp. Transformation
// c12 Richtung des Lichtes
vs_1_1
// Version
dcl_position0 v0
// Eckpunktkoordinaten
v0 zuweisen
dcl_color v7
// Farbwerte v7 zuweisen
dcl_normal0 v4
// Normalen v4 zuweisen
dcl_texcoord v8
// Texturekoordinaten v8 zuweisen
m4x4 oPos, v0,
c4 // transformiere
Eckpunkte(v0) mit Hilfe der Matrix(c4) durch
den Befehl "m4x4", schreiben in
oPos
dp3 r0 , v4
, c12 // Lichtberechnung
Normale(v4) *(Skalarprodukt) Lichtvektor(c12),
schreiben in r0
mul oD0 , r0.x ,
v7 // Vertexfarbe
berechnen Farbe * Lichtintensität, schreiben
in oD0
mov oT0.xy , v8
// kopiere Texturekoordinaten (.xy weil es
nur 2 Koordinaten(U,V) sind)
So, ich hoffe der Zusammenhang zwischen der
Vertex Shader Deklaration und den "Output
Registern" ist ein wenig verständlich
geworden.
Modifikations- und Maskierbefehle
Name |
Syntax |
anwendbar auf
|
DX8.1 VS1.1 |
DX 9 VS2.0 |
DX9 VS2.0 Extended
/ VS 2_sw |
DX 9 VS3.0
/ VS 3_sw |
R300 VS
|
NV30 VS
|
Absolute Value |
abs |
Quellregister
|
- |
- |
- |
ja |
-
|
ja
|
Negate |
- |
Quellregister
|
ja |
ja |
ja |
ja |
ja
|
ja
|
Saturate |
sat |
Befehl
|
- |
ja |
ja |
ja
|
ja
|
ja
|
Replicate Swizzle |
.xyzw or .rgba |
Quellregister
|
ja |
ja |
ja |
ja |
ja
|
ja
|
Arbitrary Swizzle
|
xyzw or .rgba
|
Quellregister
|
ja
|
ja
|
ja
|
ja
|
ja
|
ja
|
Write Mask |
.xyzw or .rgba
|
Zielregister
|
ja |
ja |
ja |
ja |
ja
|
ja
|
Modifikations- und Maskierbefehle haben den großen Vorteil, dass sie
nicht als extra Instruktionen zählen.
Somit können sie unbeschwert angewendet
werden und wirken sich nicht auf die aktuelle
Anzahl der Instruktionen in einem Vertex
Shader Programm aus.
Absolute Value
Hiermit wird der absolute Wert eines Registers
gebildet.
add rDest, rSrc0, rSrc1_abs
Negate
Hiermit wird der Inhalt des Quellregisters
negiert.
add rDest, - rSrc0 , rSrc1
Saturate
Saturate begrenzt das Resultat einer Berechnung
auf den Wertebereich [0, 1]. Somit gibt es
keine Überläufe.
add_sat rDest, rSrc0 , rSrc1
Replicate Swizzle
Mit Replicate/Source Swizzle kann man bestimmen,
welche Quellregisterkomponenten in ein Zielregister
geschrieben werden.
add rDest, rSrc0 , rSrc1.xxyy // addiert zu
den xy Komponenten von rSrc0 jeweils nur
x von rSrc1
//
und zu den zw Komponenten von rSrc0 jeweils
nur y von rSrc1
Arbitrary Swizzle
Arbitrary Swizzle bezeichnet die Möglichkeit,
dass die Komponenten (x, y, z, w) beliebig
vertauscht werden können.
add rDest, rSrc0, rSrc1.yxzw // vertauscht x und y beim addieren
Write Mask
Eine "Write Mask" dient dazu, festzulegen,
welche Zielregisterkomponenten von einer
Operation verändert werden dürfen,
jedoch muss die Reihenfolge erhalten bleiben.
add rDest.xw, rSrc0
// nur die x und w Komponenten
werden durch den Befehl verändert
Befehle
Typ |
DX8.1 VS1.1 |
DX 9 VS2.0 |
DX9 VS2.0 Extended
/ VS 2_sw |
DX 9 VS3.0
/ VS 3_sw |
R300 VS
|
NV30 VS
|
Setup |
dcl_usage, def, vs |
-
|
-
|
dcl_textureType
|
2_0
|
2_x
|
Arithmetic |
add, dp3, dp4, dst, lit, mad, max, min,
mov, mul, nop, rcp, rsg, sqe, slt, sub |
mova |
-
|
-
|
Macro-Ops |
exp, expp, frc, log, logp, m3x2, m3x3, m3x4,
m4x3, m4x4 |
abs, crs, lrp,
nrm, pow, sgn, sincos
|
-
|
-
|
Flow-Control |
- |
call, callnz, else, endif, endloop,
endrep, if, label, loop, rep, ret |
break, break_comp, break_pred, callnz, callnz_pred,
if_comp, if_pred, setp |
-
|
Texture
|
-
|
-
|
-
|
texldl
|
Als Basismodell dient der Vertex Shader 1.1.
Mit jeder weiteren Vertex Shader Version
kommen neue Befehle hinzu, die Befehle der
Vorgängerversionen bleiben erhalten,
deshalb habe ich nur die neuen Befehle je
Version in der Tabelle aufgeführt.
Setup
Zum Setup gehören Befehle, welche die
Version des verwendeten Vertex Shaders festlegen,
sowie die Zuordnung zwischen den Input Registern
und deren Funktion.
vs_1_1
//
legt Version 1_1 des VS fest
dcl_position0 v0 // erklärt
das v0 Register zum Register mit den Normalen
eines Eckpunktes
Arithmetic
Hier werden einfache mathematische Operationen
zur Verfügung gestellt.
mul oD0, r0.x, v7
// r0.x wird mit v7(skalarer Wert) multipliziert
und das Resultat in oD0(diffuse Farbe) geschrieben
Macro-Ops
Hier werden komplexere mathematische Operationen
zur Verfügung gestellt. Man könnte
diese auch umgehen und selbst per arithmetischer
Operationen nachbilden.
dp3 r0, v4, c12
// rechnet einfach:
// r0.w = (v4.x * c12.x) + (v4.y * c12.y)
+ (v4.z * c12.z);
// r0.x = r0.y = r0.z = r0.w;
Flow-Control
Hier werden alle Befehle der statischen und
dynamischen Flußsteuerung zusammengefasst.
Diese gibt es erst seit VS2.0. Die dyn. Flußsteuerung
wird erst mittels der Extended Version des
VS2.0 verfügbar sein.
vs_2_x
if_lt r3.x, r4.y
// wenn r3.x kleiner ist als r4.y, dann gehe
hier hin
else
// sonst mache hier weiter
endif
Zusammenfassend kann man sagen, dass die
Vertex Shader 2.0 und höher ein guter
Schritt in die richtige Richtung sind. Wie
sich die statische und die dynamische Flußsteuerung
auf die Performance auswirkt, bleibt abzuwarten.
Sehr interessant sind auch die Möglichkeiten
der Version 3.0, gerade wegen der Möglichkeit
Texturedaten zu verwenden. Ein Problem gibt
es jedoch: Alles zwischen Version 2.0 und
3.0 ist sehr "weich" definiert.
Sprich, als Programmierer kann man sich nicht
sicher sein, dass ein VS_2_x Programm auf
jeder 2_x Hardware läuft, da 2_x eben
über CAP-Bits und ein paar Werte definiert
wird. Somit dürfte dieser Standard in
der Spielepraxis recht unbedeutend sein,
da 2_x Hardware nicht gleich 2_x Hardware
ist.
|