AGAL 字节码格式

AGAL 字节码必须使用 Endian.LITTLE_ENDIAN 格式。

字节码标头

AGAL 字节码必须以一个 7 字节标头开头。

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

偏移量(字节数)

大小(字节数)

名称

说明

0

1

magic

必须为 0xa0

1

4

version

必须为 1

5

1

shader type ID

必须为 0xa1

6

1

shader type

0 表示顶点程序;1 表示片段程序

标记

标头后直接跟任意数量的标记。每个标记的大小都为 192 位(24 字节),且格式始终为:

[opcode][destination][source1][source2 or sampler]

并不是每一个 opcode 都使用所有这些字段。不使用的字段必须设置为 0。

操作代码

[opcode] 字段的大小为 32 位,可具有以下值之一:

名称

Opcode

操作

说明

mov

0x00

移动

将数据从 source1 移动到 destination,按组件

add

0x01

相加

destination = source1 + source2,按组件

sub

0x02

相减

destination = source1 - source2,按组件

mul

0x03

相乘

destination = source1 * source2,按组件

div

0x04

除以

destination = source1 / source2,按组件

rcp

0x05

倒数

destination = 1/source1,按组件

min

0x06

最小值

destination = minimum(source1,source2),按组件

max

0x07

最大值

destination = maximum(source1,source2),按组件

frc

0x08

分数

destination = source1 - (float)floor(source1),按组件

sqt

0x09

平方根

destination = sqrt(source1),按组件

rsq

0x0a

平方根倒数

destination = 1/sqrt(source1),按组件

pow

0x0b

destination = pow(source1,source2),按组件

log

0x0c

对数

destination = log_2(source1),按组件

exp

0x0d

指数

destination = 2^source1,按组件

nrm

0x0e

标准化

destination = normalize(source1),按组件(仅生成一个 3 组件结果,目标必须掩码为 .xyz 或更小)

sin

0x0f

正弦

destination = sin(source1),按组件

cos

0x10

余弦

destination = cos(source1),按组件

crs

0x11

叉积

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

(仅生成一个 3 组件结果,目标必须掩码为 .xyz 或更小)

dp3

0x12

点积

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

dp4

0x13

点积

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

abs

0x14

取绝对值

destination = abs(source1),按组件

neg

0x15

求反

destination = -source1,按组件

sat

0x16

饱和

destination = maximum(minimum(source1,1),0),按组件

m33

0x17

矩阵连乘 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)

(仅生成一个 3 组件结果,目标必须掩码为 .xyz 或更小)

m44

0x18

矩阵连乘 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

矩阵连乘 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)

(仅生成一个 3 组件结果,目标必须掩码为 .xyz 或更小)

kil

0x27

丢弃(仅适用于片段着色器)

如果单个标量源组件小于零,则将丢弃片段并不会将其绘制到帧缓冲区。(目标寄存器必须全部设置为 0)

tex

0x28

纹理取样(仅适用于片段着色器)

destination 等于从坐标 source1 上的纹理 source2 进行加载。在这种情况下,source2 必须采用取样器格式。

sge

0x29

大于等于时设置

destination = source1 >= source2 ? 1 : 0,按组件

slt

0x2a

小于时设置

destination = source1 < source2 ? 1 : 0,按组件

seq

0x2c

相等时设置

destination = source1 == source2 ? 1 : 0,按组件

sne

0x2d

不相等时设置

destination = source1 != source2 ? 1 : 0,按组件

在 AGAL2 中引入了以下 opcode:

名称

Opcode

操作

说明

ddx

0x1a

X 偏导数

将 source1 的 X 偏导数加载到目标中。

ddy

1x0b

Y 偏导数

将 source1 的 Y 偏导数加载到目标中。

ife

0x1c

如果相等

如果 source1 等于 source2 则跳转。

ine

0x1d

如果不相等

如果 source1 不等于 source2 则跳转。

ifg

1x0e

如果大于

如果 source1 大于等于 source2 则跳转。

ifl

1x0f

如果小于

如果 source1 小于 source2 则跳转。

els

0x20

else

Else 块

eif

0x21

Endif

关闭 if 或 else 块。

Destination 字段格式

[destination] 字段的大小为 32 位:

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

T = 寄存器类型(4 位)

M = 写入掩码(4 位)

N = 寄存器编号(16 位)

- = 未定义,必须为 0

Source 字段格式

[source] 字段的大小为 64 位:

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

D = Direct=0/Indirect=1 表示直接使用 Q 并忽略 I,1 位

Q = 索引寄存器组件选择(2 位)

I = 索引寄存器类型(4 位)

T = 寄存器类型(4 位)

S = 重排(8 位,每个组件 2 位)

O = 间接偏移量(8 位)

N = 寄存器编号(16 位)

- = 未定义,必须为 0

Sampler 字段格式

tex opcode 的第二个源字段必须为 [sampler] 格式,大小为 64 位:

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

N = 取样器寄存器编号(16 位)

B = 纹理详细级别 (LOD) 偏差,带符号整数,以 8 为单位递增。使用的浮点值为 b/8.0(8 位)

T = 寄存器类型,必须为 5,Sampler(4 位)

F = 滤镜(0=nearest、1=linear)(4 位)

M = Mipmap(0=disable、1=nearest、2=linear)

W = 环绕(0=clamp、1=repeat)

S = 特殊标志位(必须为 0)

D = 维度(0=2D、1=Cube)

程序寄存器

使用的寄存器数取决于使用的 Context3D 配置文件。下表中定义了寄存器数与其用法:

名称

AGAL

AGAL2

AGAL3

用法

每个片段程序的数量

每个顶点程序的数量

每个片段程序的数量

每个顶点程序的数量

每个片段程序的数量

每个顶点程序的数量

Context 3D 配置文件支持

低于标准

标准

扩展标准

SWF 版本

低于 25

25

28 及更高版本

属性

0

NA

8

NA

8

NA

16

顶点着色器输入;从使用 Context3D.setVertexBufferAt() 指定的顶点缓冲区读取。

常数

1

28

128

64

250

200

250

着色器输入;使用 Context3D.setProgramConstants() 系列函数设置。

临时

2

8

8

26

26

26

26

用于计算的临时寄存器,无法从程序外部访问。

输出

3

1

1

1

1

1

1

着色器输出:在顶点程序中,输出的是剪辑空间位置;在片段程序中,输出的是颜色。

渐变

4

8

8

10

10

10

10

在顶点着色器和片段着色器之间传递插补数据。将顶点程序的渐变寄存器用作片段程序的输入。根据与三角形顶点的距离插补计算所需的值。

取样器

5

8

NA

16

NA

16

NA

片段着色器输入;从使用 Context3D.setTextureAt() 指定的纹理读取。

片段寄存器

6

NA

NA

1

NA

1

NA

只能写入,用于重新写入在顶点着色器中写入的 z 值(即深度值)。

标记

200

1024

2048

可以 在此 找到最新的 AGAL Mini Assembler。