Формат байт-кода 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]

Не для каждого кода операции используются все эти поля. Неиспользованные поля должны задаваться как 0.

Коды операций

Поле [opcode] имеет размер 32 бита и может принимать одно из следующих значений.

Имя

Код операции

Операция

Описание

mov

0x00

move

покомпонентно перемещает данные из source1 в destination.

add

0x01

add

destination = source1 + source2, покомпонентно

sub

0x02

subtract

destination = source1 - source2, покомпонентно

mul

0x03

multiply

destination = source1 * source2, покомпонентно

div

0x04

divide

destination = source1 / source2, покомпонентно

rcp

0x05

reciprocal

destination = 1/source1, покомпонентно

min

0x06

minimum

destination = minimum(source1,source2), покомпонентно

max

0x07

maximum

destination = maximum(source1,source2), покомпонентно

frc

0x08

fractional

destination = source1 - (float)floor(source1), покомпонентно

sqt

0x09

square root

destination = sqrt(source1), покомпонентно

rsq

0x0a

reciprocal root

destination = 1/sqrt(source1), покомпонентно

pow

0x0b

power

destination = pow(source1,source2), покомпонентно

log

0x0c

logarithm

destination = log_2(source1), покомпонентно

exp

0x0d

exponential

destination = 2^source1, покомпонентно

nrm

0x0e

normalize

destination = normalize(source1), покомпонентно (дает только трехкомпонентный результат, целевой элемент должен быть замаскирован как .xyz или меньше)

sin

0x0f

sine

destination = sin(source1), покомпонентно

cos

0x10

cosine

destination = cos(source1), покомпонентно

crs

0x11

cross product

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

(дает только трехкомпонентный результат, целевой элемент должен быть замаскирован как .xyz или меньше)

dp3

0x12

dot product

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

dp4

0x13

dot product

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

abs

0x14

absolute

destination = abs(source1), покомпонентно

neg

0x15

negate

destination = -source1, покомпонентно

sat

0x16

saturate

destination = maximum(minimum(source1,1),0), покомпонентно

m33

0x17

multiply matrix 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)

(дает только трехкомпонентный результат, целевой элемент должен быть замаскирован как .xyz или меньше)

m44

0x18

multiply matrix 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

multiply matrix 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)

(дает только трехкомпонентный результат, целевой элемент должен быть замаскирован как .xyz или меньше)

kil

0x27

kill/discard (только для фрагментного шейдера)

Если единственный скалярный исходный компонент меньше нуля, фрагмент игнорируется и не отрисовывается в буфере кадра. (Для целевого реестра должны быть заданы все нули)

tex

0x28

texture sample (только для фрагментного шейдера)

destination выравнивает нагрузку от текстуры source2 с координатами source1. В этом случае source2 должен быть в формате образца.

sge

0x29

set-if-greater-equal

destination = source1 >= source2 ? 1 : 0, покомпонентно

slt

0x2a

set-if-less-than

destination = source1 < source2 ? 1 : 0, покомпонентно

seq

0x2c

set-if-equal

destination = source1 == source2 ? 1 : 0, покомпонентно

sne

0x2d

set-if-not-equal

destination = source1 != source2 ? 1 : 0, покомпонентно

В AGAL2 добавлены следующие коды операций:

Имя

Код операции

Операция

Описание

ddx

0x1a

частная производная на оси X

Загрузить частную производную на оси X для source1 в место назначения.

ddy

1x0b

частная производная на оси Y

Загрузить частную производную на оси Y для source1 в место назначения.

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] имеет размер 32 бита:

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

T = тип регистра (4 бита)

M = маска записи (4 бита)

N = номер регистра (16 бит)

- = не определен, должен быть 0

Формат исходного поля

Поле [source] имеет размер 64 бита:

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

D = прямой=0/непрямой=1, для прямого Q и I игнорируются, 1 бит

Q = выбор компонента регистра индекса (2 бита)

I = тип регистра индекса (4 бита)

T = тип регистра (4 бита)

S = преобразование (8 бит, 2 бита на компонент)

O = косвенное смещение (8 бит)

N = номер регистра (16 бит)

- = не определен, должен быть 0

Формат поля образца

Второе исходное поле для кода операции с текстурами должно иметь формат [sampler], который имеет размер 64 бита.

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

N = номер регистра образца (16 бит)

B = смещение уровня детализации текстуры, целое число со знаком, масштаб х8. Используемое значение с плавающей запятой: b/8,0 (8 бит)

T = тип регистра, должен быть 5, образец (4 бита)

F = фильтр (0=ближайшие,1=линейные) (4 бита)

M = множественное отображение (0=выкл.,1=ближайшие, 2=линейные)

W = перенос (0=зажим,1=повтор)

S = биты специальных флагов (должно быть 0)

D = размерность (0=2D, 1=куб)

Реестры программ

Число используемых реестров зависит от используемого профиля Context3D. Число реестров и их использование определяются в следующей таблице:

Имя

Значение

AGAL

AGAL2

AGAL3

Применение

Число в фрагментной программе

Число в вершинной программе

Число в фрагментной программе

Число в вершинной программе

Число в фрагментной программе

Число в вершинной программе

Поддержка профилей Context3D

Ниже стандарта

Стандарт

Расширенный стандарт

Версия SWF

Ниже 25

25

28 и больше

Атрибут

0

Н/Д

8

Н/Д

8

Н/Д

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

Н/Д

16

Н/Д

16

Н/Д

Ввод фрагментного шейдера; считывается из текстуры, заданной с помощью Context3D.setTextureAt().

Реестр фрагментов

6

Н/Д

Н/Д

1

Н/Д

1

Н/Д

Доступен только для записи и служит для перезаписи значения z (глубины), записанного в вершинном шейдере.

Метки

200

1024

2048

Последнюю версию AGAL Mini Assembler можно найти здесь .