AGAL-Bytecodeformat

AGAL-Bytecode muss das Format Endian.LITTLE_ENDIAN verwenden.

Bytecode-Header

AGAL-Bytecode muss mit einem 7-Byte-Header beginnen:

A0 01000000 A1 00 -- for a vertex program 
A0 01000000 A1 01 -- for a fragment program

Offset (Bytes)

Größe (Bytes)

Name

Beschreibung

0

1

magic

muss 0xa0 sein

1

4

version

muss 1 sein

5

1

Shadertyp-ID

muss 0xa1 sein

6

1

Shadertyp

0 für ein Vertexprogramm; 1 für ein Fragmentprogramm

Token

Dem Header folgt sofort eine beliebige Anzahl Token. Jedes Token ist 192 Bit (24 Byte) groß und hat immer folgendes Format:

[opcode][destination][source1][source2 oder sampler]

Nicht jeder Opcode verwendet alle diese Felder. Nicht verwendete Felder müssen auf 0 gesetzt werden.

Opcodes

Das [opcode]-Feld ist 32 Bit groß und kann einen dieser Werte aufweisen:

Name

Opcode

Methode

Beschreibung

mov

0x00

verschieben

Daten von source1 nach destination verschieben, komponentenweise

add

0x01

addieren

destination = source1 + source2, komponentenweise

sub

0x02

subtrahieren

destination = source1 - source2, komponentenweise

mul

0x03

multiplizieren

destination = source1 * source2, komponentenweise

div

0x04

dividieren

destination = source1 / source2, komponentenweise

rcp

0x05

Kehrwert

destination = 1/source1, komponentenweise

min

0x06

minimum

destination = minimum(source1,source2), komponentenweise

max

0x07

maximum

destination = maximum(source1,source2), komponentenweise

frc

0x08

fraktional

destination = source1 - (float)floor(source1), komponentenweise

sqt

0x09

Quadratwurzel

destination = sqrt(source1), komponentenweise

rsq

0x0a

Quadratwurzel-Kehrwert

destination = 1/sqrt(source1), komponentenweise

pow

0x0b

Potenz

destination = pow(source1,source2), komponentenweise

log

0x0c

Logarithmus

destination = log_2(source1), komponentenweise

exp

0x0d

Exponential

destination = 2^source1, komponentenweise

nrm

0x0e

normalisieren

destination = normalize(source1), komponentenweise (erzeugt nur ein 3-Komponenten-Ergebnis, das Ziel muss auf .xyz oder weniger maskiert werden)

sin

0x0f

Sinus

destination = sin(source1), komponentenweise

cos

0x10

Kosinus

destination = cos(source1), komponentenweise

crs

0x11

Kreuzprodukt

destination.x = source1.y * source2.z - source1.z * source2.y

destination.y = source1.z * source2.x - source1.x * source2.z

destination.z = source1.x * source2.y - source1.y * source2.x

(erzeugt nur ein 3-Komponenten-Ergebnis, das Ziel muss auf .xyz oder weniger maskiert werden)

dp3

0x12

Skalarprodukt

destination = source1.x*source2.x + source1.y*source2.y + source1.z*source2.z

dp4

0x13

Skalarprodukt

destination = source1.x*source2.x + source1.y*source2.y + source1.z*source2.z + source1.w*source2.w

abs

0x14

Absolut

destination = abs(source1), komponentenweise

neg

0x15

Gegenzahl

destination = -source1, komponentenweise

sat

0x16

sättigen

destination = maximum(minimum(source1,1),0), komponentenweise

m33

0x17

Matrix multiplizieren 3x3

destination.x = (source1.x * source2[0].x) + (source1.y * source2[0].y) + (source1.z * source2[0].z)

destination.y = (source1.x * source2[1].x) + (source1.y * source2[1].y) + (source1.z * source2[1].z)

destination.z = (source1.x * source2[2].x) + (source1.y * source2[2].y) + (source1.z * source2[2].z)

(erzeugt nur ein 3-Komponenten-Ergebnis, das Ziel muss auf .xyz oder weniger maskiert werden)

m44

0x18

Matrix multiplizieren 4x4

destination.x = (source1.x * source2[0].x) + (source1.y * source2[0].y) + (source1.z * source2[0].z) + (source1.w * source2[0].w)

destination.y = (source1.x * source2[1].x) + (source1.y * source2[1].y) + (source1.z * source2[1].z) + (source1.w * source2[1].w)

destination.z = (source1.x * source2[2].x) + (source1.y * source2[2].y) + (source1.z * source2[2].z) + (source1.w * source2[2].w)

destination.w = (source1.x * source2[3].x) + (source1.y * source2[3].y) + (source1.z * source2[3].z) + (source1.w * source2[3].w)

m34

0x19

Matrix multiplizieren 3x4

destination.x = (source1.x * source2[0].x) + (source1.y * source2[0].y) + (source1.z * source2[0].z) + (source1.w * source2[0].w)

destination.y = (source1.x * source2[1].x) + (source1.y * source2[1].y) + (source1.z * source2[1].z) + (source1.w * source2[1].w)

destination.z = (source1.x * source2[2].x) + (source1.y * source2[2].y) + (source1.z * source2[2].z) + (source1.w * source2[2].w)

(erzeugt nur ein 3-Komponenten-Ergebnis, das Ziel muss auf .xyz oder weniger maskiert werden)

kil

0x27

verwerfen (nur Fragment-Shader)

Wenn eine Einzelskalar-Ausgabekomponente kleiner als null ist, wird das Fragment verworfen und nicht in den Framebuffer gezeichnet. (Zielregister muss vollständig auf 0 gesetzt werden)

tex

0x28

Texturbeispiel (nur Fragment-Shader)

destination entspricht dem Laden aus Textur source2 bei den Koordinaten source1. In diesem Fall muss source2 im Samplerformat vorliegen.

sge

0x29

festlegen, falls größer oder gleich

destination = source1 >= source2 ? 1 : 0, komponentenweise

slt

0x2a

festlegen, falls kleiner als

destination = source1 < source2 ? 1 : 0, komponentenweise

seq

0x2c

festlegen, falls gleich

destination = source1 == source2 ? 1 : 0, komponentenweise

sne

0x2d

festlegen, falls nicht gleich

destination = source1 != source2 ? 1 : 0, komponentenweise

Zielfeldformat

Das [destination]-Feld hat eine Größe von 32 Bit:

31.............................0 
----TTTT----MMMMNNNNNNNNNNNNNNNN

T = Registertyp (4 Bits)

M = Schreibmaske (4 Bits)

N = Registernummer (16 Bits)

- = nicht definiert, muss 0 sein

Quellenfeldformat

Das [source]-Feld hat eine Größe von 64 Bit:

63.............................................................0 
D-------------QQ----IIII----TTTTSSSSSSSSOOOOOOOONNNNNNNNNNNNNNNN

D = Direkt=0/Indirekt=1 für direkt Q und I werden ignoriert, 1Bit

Q = Indexregisterkomponentenauswahl (2 Bits)

I = Indexregistertype (4 Bits)

T = Registertyp (4 Bits)

S = Swizzle (8 Bits, 2 Bits pro Komponente)

O = Indirekter Offset (8 Bits)

N = Registernummer (16 Bits)

- = nicht definiert, muss 0 sein

Samplerfeldformat

Das zweite Quellfeld für den tex-Opcode muss im [sampler]-Format vorliegen, welches 64 Bit groß ist:

63.............................................................0 
FFFFMMMMWWWWSSSSDDDD--------TTTT--------BBBBBBBBNNNNNNNNNNNNNNNN

N = Samplerregisternummer (16 Bits)

B = Textur Level-of-detail (LOD) Bias, vorzeichenbehaftete Ganzzahl, skalieren um 8. Der verwendete Gleitkommawert ist b/8.0 (8 Bits)

T = Registertyp, muss 5 sein, Sampler (4 Bits)

F = Filter (0=nächste,1=linear) (4 Bits)

M = Mipmap (0=deaktivieren,1=nächste, 2=linear)

W = Wrapping (0=fixieren,1=wiederholen)

S = Spezielle Flag-Bits (muss 0 sein)

D = Dimension (0=2D, 1=Würfel)

Programmregister

Die folgenden Registertypen sind definiert. Verwenden Sie den aufgelisteten Wert, um einen Registertyp in den Feldern eines Tokens anzugeben:

Name

Wert

Anzahl pro Fragmentprogramm

Anzahl pro Vertexprogramm

Verwendung

Attribute

0

8

Vertexshadereingabe; aus einem Vertexbuffer lesen, der mit Context3D.setVertexBufferAt() angegeben wird.

Constant

1

28

128

Shadereingabe; mit der Context3D.setProgramConstants()-Funktionsfamilie festlegen.

Temporary

2

8

8

Temporäres Register für die Berechnung, außerhalb des Programms nicht zugänglich.

Output

3

1

1

Shaderausgabe: in einem Vertexprogramm ist die Ausgabe die Clipspaceposition; in einem Fragmentprogramm ist die Ausgabe eine Farbe.

Varying

4

8

8

Interpolierte Daten zwischen Vertex- und Fragmentprogrammen übertragen. Die unterschiedlichen Register aus dem Vertexprogramm werden als Eingabe in das Fragmentprogramm angewendet. Die Werte werden entsprechend dem Abstand von den Dreiecksscheitelpunkten interpoliert.

Sampler

5

8

Fragmentshadereingabe; aus einer mit Context3D.setTextureAt() angegebenen Textur lesen.