Fix coding style

This commit is contained in:
Yaski
2013-01-17 22:45:43 +06:00
parent 8e7d834a22
commit 64e7463d00
6 changed files with 1640 additions and 1644 deletions

View File

@@ -1,349 +1,349 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
* If it is not possible or desirable to put the notice in a particular file, then You may include the notice in a location (such as a LICENSE file in a relevant directory) where a recipient would be likely to look for such a notice.
* You may add additional accurate notices of copyright ownership.
*
* It is desirable to notify that Covered Software was "Powered by AlternativaPlatform" with link to http://www.alternativaplatform.com/
* */
package alternativa.engine3d.materials {
import alternativa.engine3d.alternativa3d;
import alternativa.engine3d.materials.compiler.CommandType;
import alternativa.engine3d.materials.compiler.VariableType;
import avmplus.getQualifiedSuperclassName;
import flash.display3D.Context3D;
import flash.display3D.Context3DTextureFormat;
import flash.display3D.IndexBuffer3D;
import flash.display3D.VertexBuffer3D;
import flash.display3D.textures.Texture;
import flash.geom.Point;
import flash.utils.ByteArray;
import flash.utils.Dictionary;
import flash.utils.Endian;
import flash.utils.getDefinitionByName;
/**
* @private
*/
public class A3DUtils {
public static const NONE:int = 0;
public static const DXT1:int = 1;
public static const ETC1:int = 2;
public static const PVRTC:int = 3;
private static const DXT1Data:ByteArray = getDXT1();
private static const PVRTCData:ByteArray = getPVRTC();
private static const ETC1Data:ByteArray = getETC1();
private static function getDXT1():ByteArray {
var DXT1Data:Vector.<int> = Vector.<int>([65,84,70,0,2,71,2,2,2,3,0,0,12,0,0,0,16,0,0,85,105,56,0,0,0,0,0,157,73,73,188,1,8,0,0,0,5,0,1,188,1,0,16,0,0,0,74,0,0,0,128,188,4,0,1,0,0,0,1,0,0,0,129,188,4,0,1,0,0,0,2,0,0,0,192,188,4,0,1,0,0,0,90,0,0,0,193,188,4,0,1,0,0,0,66,0,0,0,0,0,0,0,36,195,221,111,3,78,254,75,177,133,61,119,118,141,201,10,87,77,80,72,79,84,79,0,25,0,192,122,0,0,0,1,96,0,160,0,10,0,0,160,0,0,0,4,111,255,0,1,0,0,1,0,224,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,114,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,16,0,0,85,105,56,0,0,0,0,0,157,73,73,188,1,8,0,0,0,5,0,1,188,1,0,16,0,0,0,74,0,0,0,128,188,4,0,1,0,0,0,1,0,0,0,129,188,4,0,1,0,0,0,2,0,0,0,192,188,4,0,1,0,0,0,90,0,0,0,193,188,4,0,1,0,0,0,66,0,0,0,0,0,0,0,36,195,221,111,3,78,254,75,177,133,61,119,118,141,201,10,87,77,80,72,79,84,79,0,25,0,192,122,0,0,0,1,96,0,160,0,10,0,0,160,0,0,0,4,111,255,0,1,0,0,1,0,224,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,114,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,16,0,0,85,105,56,0,0,0,0,0,157,73,73,188,1,8,0,0,0,5,0,1,188,1,0,16,0,0,0,74,0,0,0,128,188,4,0,1,0,0,0,1,0,0,0,129,188,4,0,1,0,0,0,2,0,0,0,192,188,4,0,1,0,0,0,90,0,0,0,193,188,4,0,1,0,0,0,66,0,0,0,0,0,0,0,36,195,221,111,3,78,254,75,177,133,61,119,118,141,201,10,87,77,80,72,79,84,79,0,25,0,192,122,0,0,0,1,96,0,160,0,10,0,0,160,0,0,0,4,111,255,0,1,0,0,1,0,224,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,114,0,7,143,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]);
return getData(DXT1Data);
}
private static function getETC1():ByteArray {
var ETC1Data:Vector.<int> = Vector.<int>([65,84,70,0,2,104,2,2,2,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,16,0,0,0,255,252,0,0,0,0,12,0,0,0,16,0,0,127,233,56,0,0,0,0,0,157,73,73,188,1,8,0,0,0,5,0,1,188,1,0,16,0,0,0,74,0,0,0,128,188,4,0,1,0,0,0,1,0,0,0,129,188,4,0,1,0,0,0,2,0,0,0,192,188,4,0,1,0,0,0,90,0,0,0,193,188,4,0,1,0,0,0,66,0,0,0,0,0,0,0,36,195,221,111,3,78,254,75,177,133,61,119,118,141,201,9,87,77,80,72,79,84,79,0,25,0,192,120,0,0,0,1,96,0,160,0,10,0,0,160,0,0,0,4,111,255,0,1,0,0,1,0,208,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,114,0,7,143,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,16,0,0,0,255,252,0,0,0,0,12,0,0,0,16,0,0,127,233,56,0,0,0,0,0,157,73,73,188,1,8,0,0,0,5,0,1,188,1,0,16,0,0,0,74,0,0,0,128,188,4,0,1,0,0,0,1,0,0,0,129,188,4,0,1,0,0,0,2,0,0,0,192,188,4,0,1,0,0,0,90,0,0,0,193,188,4,0,1,0,0,0,66,0,0,0,0,0,0,0,36,195,221,111,3,78,254,75,177,133,61,119,118,141,201,9,87,77,80,72,79,84,79,0,25,0,192,120,0,0,0,1,96,0,160,0,10,0,0,160,0,0,0,4,111,255,0,1,0,0,1,0,208,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,114,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,16,0,0,0,255,252,0,0,0,0,12,0,0,0,16,0,0,127,233,56,0,0,0,0,0,157,73,73,188,1,8,0,0,0,5,0,1,188,1,0,16,0,0,0,74,0,0,0,128,188,4,0,1,0,0,0,1,0,0,0,129,188,4,0,1,0,0,0,2,0,0,0,192,188,4,0,1,0,0,0,90,0,0,0,193,188,4,0,1,0,0,0,66,0,0,0,0,0,0,0,36,195,221,111,3,78,254,75,177,133,61,119,118,141,201,9,87,77,80,72,79,84,79,0,25,0,192,120,0,0,0,1,96,0,160,0,10,0,0,160,0,0,0,4,111,255,0,1,0,0,1,0,208,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,114,0,4,0]);
return getData(ETC1Data);
}
private static function getPVRTC():ByteArray {
var PVRTCData:Vector.<int> = Vector.<int>([65,84,70,0,2,173,2,2,2,3,0,0,0,0,0,0,0,0,13,0,0,0,16,0,0,0,104,190,153,255,0,0,0,0,15,91,0,0,16,0,0,102,12,228,2,255,225,0,0,0,0,0,223,73,73,188,1,8,0,0,0,5,0,1,188,1,0,16,0,0,0,74,0,0,0,128,188,4,0,1,0,0,0,2,0,0,0,129,188,4,0,1,0,0,0,4,0,0,0,192,188,4,0,1,0,0,0,90,0,0,0,193,188,4,0,1,0,0,0,132,0,0,0,0,0,0,0,36,195,221,111,3,78,254,75,177,133,61,119,118,141,201,9,87,77,80,72,79,84,79,0,25,0,192,120,0,1,0,3,96,0,160,0,10,0,0,160,0,0,0,4,111,255,0,1,0,0,1,0,165,192,0,7,227,99,186,53,197,40,185,134,182,32,130,98,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,143,192,120,64,6,16,34,52,192,196,65,132,90,98,68,16,17,68,60,91,8,48,76,35,192,97,132,71,76,33,164,97,1,2,194,12,19,8,240,29,132,24,38,17,224,48,194,35,166,16,210,48,128,128,24,68,121,132,52,204,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,16,0,0,0,233,56,90,0,0,0,0,12,0,0,0,16,0,0,127,237,210,0,0,0,0,0,155,73,73,188,1,8,0,0,0,5,0,1,188,1,0,16,0,0,0,74,0,0,0,128,188,4,0,1,0,0,0,2,0,0,0,129,188,4,0,1,0,0,0,4,0,0,0,192,188,4,0,1,0,0,0,90,0,0,0,193,188,4,0,1,0,0,0,64,0,0,0,0,0,0,0,36,195,221,111,3,78,254,75,177,133,61,119,118,141,201,9,87,77,80,72,79,84,79,0,25,0,192,120,0,1,0,3,96,0,160,0,10,0,0,160,0,0,0,4,111,255,0,1,0,0,1,0,188,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17,200,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,16,0,0,0,233,56,90,0,0,0,0,12,0,0,0,16,0,0,127,237,210,0,0,0,0,0,155,73,73,188,1,8,0,0,0,5,0,1,188,1,0,16,0,0,0,74,0,0,0,128,188,4,0,1,0,0,0,2,0,0,0,129,188,4,0,1,0,0,0,4,0,0,0,192,188,4,0,1,0,0,0,90,0,0,0,193,188,4,0,1,0,0,0,64,0,0,0,0,0,0,0,36,195,221,111,3,78,254,75,177,133,61,119,118,141,201,9,87,77,80,72,79,84,79,0,25,0,192,120,0,1,0,3,96,0,160,0,10,0,0,160,0,0,0,4,111,255,0,1,0,0,1,0,188,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17,200,0,0,0,0,0,0,0,0,0,0]);
return getData(PVRTCData);
}
private static function getData(source:Vector.<int>):ByteArray {
var result:ByteArray = new ByteArray();
for (var i:int = 0, length:int = source.length; i < length; i++) {
result.writeByte(source[i]);
}
return result;
}
public static function getSizeFromATF(byteArray:ByteArray, size:Point):void {
byteArray.position = 7;
var w:int = byteArray.readByte();
var h:int = byteArray.readByte();
size.x = 1 << w;
size.y = 1 << h;
byteArray.position = 0;
}
public static function getSupportedTextureFormat(context3D:Context3D):int {
var testTexture:Texture = context3D.createTexture(4, 4, Context3DTextureFormat.COMPRESSED, false);
var result:int = NONE;
try {
testTexture.uploadCompressedTextureFromByteArray(DXT1Data, 0);
result = DXT1;
} catch(e:Error) {
result = NONE;
}
if (result == NONE) {
try {
testTexture.uploadCompressedTextureFromByteArray(PVRTCData, 0);
result = PVRTC;
} catch(e:Error) {
result = NONE;
}
}
if (result == NONE) {
try {
testTexture.uploadCompressedTextureFromByteArray(ETC1Data, 0);
result = ETC1;
} catch(e:Error) {
result = NONE;
}
}
testTexture.dispose();
return result;
}
public static function vectorNumberToByteArray(vector:Vector.<Number>):ByteArray {
var result:ByteArray = new ByteArray();
result.endian = Endian.LITTLE_ENDIAN;
for (var i:int = 0; i < vector.length; i++) {
result.writeFloat(vector[i]);
}
result.position = 0;
return result;
}
public static function byteArrayToVectorUint(byteArray:ByteArray):Vector.<uint> {
var result:Vector.<uint> = new Vector.<uint>();
var length:uint = 0;
byteArray.position = 0;
byteArray.endian = Endian.LITTLE_ENDIAN;
while (byteArray.bytesAvailable > 0) {
result[length++] = byteArray.readUnsignedShort();
}
return result;
}
public static function createVertexBufferFromByteArray(context:Context3D, byteArray:ByteArray, numVertices:uint, stride:uint = 3):VertexBuffer3D {
if (context == null) {
throw new ReferenceError("context is not set");
}
var buffer:VertexBuffer3D = context.createVertexBuffer(numVertices, stride);
buffer.uploadFromByteArray(byteArray, 0, 0, numVertices);
return buffer;
}
public static function createVertexBufferFromVector(context:Context3D, vector:Vector.<Number>, numVertices:uint, stride:uint = 3):VertexBuffer3D {
if (context == null) {
throw new ReferenceError("context is not set");
}
var buffer:VertexBuffer3D = context.createVertexBuffer(numVertices, stride);
var byteArray:ByteArray = A3DUtils.vectorNumberToByteArray(vector);
buffer.uploadFromByteArray(byteArray, 0, 0, numVertices);
return buffer;
}
public static function createTextureFromByteArray(context:Context3D, byteArray:ByteArray, width:Number, height:Number, format:String):Texture {
if (context == null) {
throw new ReferenceError("context is not set");
}
var texture:Texture = context.createTexture(width, height, format, false);
texture.uploadCompressedTextureFromByteArray(byteArray, 0);
return texture;
}
public static function createIndexBufferFromByteArray(context:Context3D, byteArray:ByteArray, numIndices:uint):IndexBuffer3D {
if (context == null) {
throw new ReferenceError("context is not set");
}
var buffer:IndexBuffer3D = context.createIndexBuffer(numIndices);
buffer.uploadFromByteArray(byteArray, 0, 0, numIndices);
return buffer;
}
public static function createIndexBufferFromVector(context:Context3D, vector:Vector.<uint>, numIndices:int = -1):IndexBuffer3D {
if (context == null) {
throw new ReferenceError("context is not set");
}
var count:uint = numIndices > 0 ? numIndices : vector.length;
var buffer:IndexBuffer3D = context.createIndexBuffer(count);
buffer.uploadFromVector(vector, 0, count);
var byteArray:ByteArray = new ByteArray();
byteArray.endian = Endian.LITTLE_ENDIAN;
for (var i:int = 0; i < count; i++) {
byteArray.writeInt(vector[i]);
}
byteArray.position = 0;
buffer.uploadFromVector(vector, 0, count);
return buffer;
}
// Disassembler
private static var programType:Vector.<String> = Vector.<String>(["VERTEX", "FRAGMENT"]);
private static var samplerDimension:Vector.<String> = Vector.<String>(["2D", "cube", "3D"]);
private static var samplerWraping:Vector.<String> = Vector.<String>(["clamp", "repeat"]);
private static var samplerMipmap:Vector.<String> = Vector.<String>(["mipnone", "mipnearest", "miplinear"]);
private static var samplerFilter:Vector.<String> = Vector.<String>(["nearest", "linear"]);
private static var swizzleType:Vector.<String> = Vector.<String>(["x", "y", "z", "w"]);
private static var twoOperandsCommands:Dictionary;
// TODO: option to turn off auto-prefixes
public static function disassemble(byteCode:ByteArray):String {
if (!twoOperandsCommands) {
twoOperandsCommands = new Dictionary();
twoOperandsCommands[0x1] = true;
twoOperandsCommands[0x2] = true;
twoOperandsCommands[0x3] = true;
twoOperandsCommands[0x4] = true;
twoOperandsCommands[0x6] = true;
twoOperandsCommands[0xb] = true;
twoOperandsCommands[0x11] = true;
twoOperandsCommands[0x12] = true;
twoOperandsCommands[0x13] = true;
twoOperandsCommands[0x17] = true;
twoOperandsCommands[0x18] = true;
twoOperandsCommands[0x19] = true;
twoOperandsCommands[0x26] = true;
twoOperandsCommands[0x28] = true;
twoOperandsCommands[0x29] = true;
twoOperandsCommands[0x2a] = true;
twoOperandsCommands[0x2c] = true;
twoOperandsCommands[0x2d] = true;
}
var res:String = "";
byteCode.position = 0;
if (byteCode.bytesAvailable < 7) {
return "error in byteCode header";
}
res += "magic = " + byteCode.readUnsignedByte().toString(16);
res += "\nversion = " + byteCode.readInt().toString(10);
res += "\nshadertypeid = " + byteCode.readUnsignedByte().toString(16);
var pType:String = programType[byteCode.readByte()];
res += "\nshadertype = " + pType;
res += "\nsource\n";
pType = pType.substring(0, 1).toLowerCase();
var lineNumber:uint = 1;
while (byteCode.bytesAvailable - 24 >= 0) {
res += (lineNumber++).toString() + ": " + getCommand(byteCode, pType) + "\n";
}
if (byteCode.bytesAvailable > 0) {
res += "\nunexpected byteCode length. extra bytes:" + byteCode.bytesAvailable;
}
return res;
}
private static function getCommand(byteCode:ByteArray, programType:String):String {
var cmd:uint = byteCode.readUnsignedInt();
var command:String = CommandType.COMMAND_NAMES[cmd];
var result:String;
var destNumber:uint = byteCode.readUnsignedShort();
var swizzle:uint = byteCode.readByte();
var s:String = "";
var destSwizzle:uint = 4;
if (swizzle < 15) {
s += ".";
s += ((swizzle & 0x1) > 0) ? "x" : "";
s += ((swizzle & 0x2) > 0) ? "y" : "";
s += ((swizzle & 0x4) > 0) ? "z" : "";
s += ((swizzle & 0x8) > 0) ? "w" : "";
destSwizzle = s.length - 1;
}
var sourceSwizzleLimit:int = destSwizzle;
if (cmd == CommandType.TEX) {
sourceSwizzleLimit = 2;
} else if (cmd == CommandType.DP3) {
sourceSwizzleLimit = 3;
} else if (cmd == CommandType.DP4) {
sourceSwizzleLimit = 4;
}
var destType:String = VariableType.TYPE_NAMES[byteCode.readUnsignedByte()].charAt(0);
result = command + " " + attachProgramPrefix(destType, programType) + destNumber.toString() + s + ", ";
result += attachProgramPrefix(getSourceVariable(byteCode, sourceSwizzleLimit), programType);
if (twoOperandsCommands[cmd]) {
if (cmd == CommandType.TEX || cmd == CommandType.TED) {
result += ", " + attachProgramPrefix(getSamplerVariable(byteCode), programType);
} else {
result += ", " + attachProgramPrefix(getSourceVariable(byteCode, sourceSwizzleLimit), programType);
}
} else {
byteCode.readDouble();
}
if (cmd == CommandType.ELS || cmd == CommandType.EIF) {
result = " " + command;
}
return result;
}
private static function attachProgramPrefix(variable:String, programType:String):String {
var char : uint = variable.charCodeAt(0);
if (char == "o".charCodeAt(0)) {
return variable + (programType == "f" ? "c" : "p");
} else if (char == "d".charCodeAt(0)) {
return "o"+variable;
} else if (char != "v".charCodeAt(0)) {
return programType + variable;
}
return variable;
}
private static function getSamplerVariable(byteCode:ByteArray):String {
var number:uint = byteCode.readUnsignedInt();
byteCode.readByte();
var dim:uint = byteCode.readByte() >> 4;
var wraping:uint = byteCode.readByte() >> 4;
var n:uint = byteCode.readByte();
return "s" + number.toString() + " <" + samplerDimension[dim] + ", " + samplerWraping[wraping]
+ ", " + samplerFilter[(n >> 4) & 0xf] + ", " + samplerMipmap[n & 0xf] + ">";
}
private static function getSourceVariable(byteCode:ByteArray, swizzleLimit:uint):String {
var s1Number:uint = byteCode.readUnsignedShort();
var offset:uint = byteCode.readUnsignedByte();
var s:String = getSourceSwizzle(byteCode.readUnsignedByte(), swizzleLimit);
var s1Type:String = VariableType.TYPE_NAMES[byteCode.readUnsignedByte()].charAt(0);
var indexType:String = VariableType.TYPE_NAMES[byteCode.readUnsignedByte()].charAt(0);
var comp:String = swizzleType[byteCode.readUnsignedByte()];
if (byteCode.readUnsignedByte() > 0) {
return s1Type + "[" + indexType + s1Number.toString() + "." + comp + ((offset > 0) ? ("+" + offset.toString()) : "") + "]" + s;
}
return s1Type + s1Number.toString() + s;
}
private static function getSourceSwizzle(swizzle:uint, swizzleLimit:uint = 4):String {
var s:String = "";
if (swizzle != 0xe4) {
s += ".";
s += swizzleType[(swizzle & 0x3)];
s += swizzleType[(swizzle >> 2) & 0x3];
s += swizzleType[(swizzle >> 4) & 0x3];
s += swizzleType[(swizzle >> 6) & 0x3];
s = swizzleLimit < 4 ? s.substring(0, swizzleLimit + 1) : s;
}
return s;
}
alternativa3d static function checkParent(child:Class, parent:Class):Boolean {
var current:Class = child;
if (parent == null) return true;
while (true) {
if (current == parent) return true;
var className:String = getQualifiedSuperclassName(current);
if (className != null) {
current = getDefinitionByName(className) as Class;
} else return false;
}
return false;
}
}
}
/**
* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
* If it is not possible or desirable to put the notice in a particular file, then You may include the notice in a location (such as a LICENSE file in a relevant directory) where a recipient would be likely to look for such a notice.
* You may add additional accurate notices of copyright ownership.
*
* It is desirable to notify that Covered Software was "Powered by AlternativaPlatform" with link to http://www.alternativaplatform.com/
* */
package alternativa.engine3d.materials {
import alternativa.engine3d.alternativa3d;
import alternativa.engine3d.materials.compiler.CommandType;
import alternativa.engine3d.materials.compiler.VariableType;
import avmplus.getQualifiedSuperclassName;
import flash.display3D.Context3D;
import flash.display3D.Context3DTextureFormat;
import flash.display3D.IndexBuffer3D;
import flash.display3D.VertexBuffer3D;
import flash.display3D.textures.Texture;
import flash.geom.Point;
import flash.utils.ByteArray;
import flash.utils.Dictionary;
import flash.utils.Endian;
import flash.utils.getDefinitionByName;
/**
* @private
*/
public class A3DUtils {
public static const NONE:int = 0;
public static const DXT1:int = 1;
public static const ETC1:int = 2;
public static const PVRTC:int = 3;
private static const DXT1Data:ByteArray = getDXT1();
private static const PVRTCData:ByteArray = getPVRTC();
private static const ETC1Data:ByteArray = getETC1();
private static function getDXT1():ByteArray {
var DXT1Data:Vector.<int> = Vector.<int>([65,84,70,0,2,71,2,2,2,3,0,0,12,0,0,0,16,0,0,85,105,56,0,0,0,0,0,157,73,73,188,1,8,0,0,0,5,0,1,188,1,0,16,0,0,0,74,0,0,0,128,188,4,0,1,0,0,0,1,0,0,0,129,188,4,0,1,0,0,0,2,0,0,0,192,188,4,0,1,0,0,0,90,0,0,0,193,188,4,0,1,0,0,0,66,0,0,0,0,0,0,0,36,195,221,111,3,78,254,75,177,133,61,119,118,141,201,10,87,77,80,72,79,84,79,0,25,0,192,122,0,0,0,1,96,0,160,0,10,0,0,160,0,0,0,4,111,255,0,1,0,0,1,0,224,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,114,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,16,0,0,85,105,56,0,0,0,0,0,157,73,73,188,1,8,0,0,0,5,0,1,188,1,0,16,0,0,0,74,0,0,0,128,188,4,0,1,0,0,0,1,0,0,0,129,188,4,0,1,0,0,0,2,0,0,0,192,188,4,0,1,0,0,0,90,0,0,0,193,188,4,0,1,0,0,0,66,0,0,0,0,0,0,0,36,195,221,111,3,78,254,75,177,133,61,119,118,141,201,10,87,77,80,72,79,84,79,0,25,0,192,122,0,0,0,1,96,0,160,0,10,0,0,160,0,0,0,4,111,255,0,1,0,0,1,0,224,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,114,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,16,0,0,85,105,56,0,0,0,0,0,157,73,73,188,1,8,0,0,0,5,0,1,188,1,0,16,0,0,0,74,0,0,0,128,188,4,0,1,0,0,0,1,0,0,0,129,188,4,0,1,0,0,0,2,0,0,0,192,188,4,0,1,0,0,0,90,0,0,0,193,188,4,0,1,0,0,0,66,0,0,0,0,0,0,0,36,195,221,111,3,78,254,75,177,133,61,119,118,141,201,10,87,77,80,72,79,84,79,0,25,0,192,122,0,0,0,1,96,0,160,0,10,0,0,160,0,0,0,4,111,255,0,1,0,0,1,0,224,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,114,0,7,143,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]);
return getData(DXT1Data);
}
private static function getETC1():ByteArray {
var ETC1Data:Vector.<int> = Vector.<int>([65,84,70,0,2,104,2,2,2,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,16,0,0,0,255,252,0,0,0,0,12,0,0,0,16,0,0,127,233,56,0,0,0,0,0,157,73,73,188,1,8,0,0,0,5,0,1,188,1,0,16,0,0,0,74,0,0,0,128,188,4,0,1,0,0,0,1,0,0,0,129,188,4,0,1,0,0,0,2,0,0,0,192,188,4,0,1,0,0,0,90,0,0,0,193,188,4,0,1,0,0,0,66,0,0,0,0,0,0,0,36,195,221,111,3,78,254,75,177,133,61,119,118,141,201,9,87,77,80,72,79,84,79,0,25,0,192,120,0,0,0,1,96,0,160,0,10,0,0,160,0,0,0,4,111,255,0,1,0,0,1,0,208,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,114,0,7,143,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,16,0,0,0,255,252,0,0,0,0,12,0,0,0,16,0,0,127,233,56,0,0,0,0,0,157,73,73,188,1,8,0,0,0,5,0,1,188,1,0,16,0,0,0,74,0,0,0,128,188,4,0,1,0,0,0,1,0,0,0,129,188,4,0,1,0,0,0,2,0,0,0,192,188,4,0,1,0,0,0,90,0,0,0,193,188,4,0,1,0,0,0,66,0,0,0,0,0,0,0,36,195,221,111,3,78,254,75,177,133,61,119,118,141,201,9,87,77,80,72,79,84,79,0,25,0,192,120,0,0,0,1,96,0,160,0,10,0,0,160,0,0,0,4,111,255,0,1,0,0,1,0,208,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,114,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,16,0,0,0,255,252,0,0,0,0,12,0,0,0,16,0,0,127,233,56,0,0,0,0,0,157,73,73,188,1,8,0,0,0,5,0,1,188,1,0,16,0,0,0,74,0,0,0,128,188,4,0,1,0,0,0,1,0,0,0,129,188,4,0,1,0,0,0,2,0,0,0,192,188,4,0,1,0,0,0,90,0,0,0,193,188,4,0,1,0,0,0,66,0,0,0,0,0,0,0,36,195,221,111,3,78,254,75,177,133,61,119,118,141,201,9,87,77,80,72,79,84,79,0,25,0,192,120,0,0,0,1,96,0,160,0,10,0,0,160,0,0,0,4,111,255,0,1,0,0,1,0,208,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,114,0,4,0]);
return getData(ETC1Data);
}
private static function getPVRTC():ByteArray {
var PVRTCData:Vector.<int> = Vector.<int>([65,84,70,0,2,173,2,2,2,3,0,0,0,0,0,0,0,0,13,0,0,0,16,0,0,0,104,190,153,255,0,0,0,0,15,91,0,0,16,0,0,102,12,228,2,255,225,0,0,0,0,0,223,73,73,188,1,8,0,0,0,5,0,1,188,1,0,16,0,0,0,74,0,0,0,128,188,4,0,1,0,0,0,2,0,0,0,129,188,4,0,1,0,0,0,4,0,0,0,192,188,4,0,1,0,0,0,90,0,0,0,193,188,4,0,1,0,0,0,132,0,0,0,0,0,0,0,36,195,221,111,3,78,254,75,177,133,61,119,118,141,201,9,87,77,80,72,79,84,79,0,25,0,192,120,0,1,0,3,96,0,160,0,10,0,0,160,0,0,0,4,111,255,0,1,0,0,1,0,165,192,0,7,227,99,186,53,197,40,185,134,182,32,130,98,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,143,192,120,64,6,16,34,52,192,196,65,132,90,98,68,16,17,68,60,91,8,48,76,35,192,97,132,71,76,33,164,97,1,2,194,12,19,8,240,29,132,24,38,17,224,48,194,35,166,16,210,48,128,128,24,68,121,132,52,204,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,16,0,0,0,233,56,90,0,0,0,0,12,0,0,0,16,0,0,127,237,210,0,0,0,0,0,155,73,73,188,1,8,0,0,0,5,0,1,188,1,0,16,0,0,0,74,0,0,0,128,188,4,0,1,0,0,0,2,0,0,0,129,188,4,0,1,0,0,0,4,0,0,0,192,188,4,0,1,0,0,0,90,0,0,0,193,188,4,0,1,0,0,0,64,0,0,0,0,0,0,0,36,195,221,111,3,78,254,75,177,133,61,119,118,141,201,9,87,77,80,72,79,84,79,0,25,0,192,120,0,1,0,3,96,0,160,0,10,0,0,160,0,0,0,4,111,255,0,1,0,0,1,0,188,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17,200,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,16,0,0,0,233,56,90,0,0,0,0,12,0,0,0,16,0,0,127,237,210,0,0,0,0,0,155,73,73,188,1,8,0,0,0,5,0,1,188,1,0,16,0,0,0,74,0,0,0,128,188,4,0,1,0,0,0,2,0,0,0,129,188,4,0,1,0,0,0,4,0,0,0,192,188,4,0,1,0,0,0,90,0,0,0,193,188,4,0,1,0,0,0,64,0,0,0,0,0,0,0,36,195,221,111,3,78,254,75,177,133,61,119,118,141,201,9,87,77,80,72,79,84,79,0,25,0,192,120,0,1,0,3,96,0,160,0,10,0,0,160,0,0,0,4,111,255,0,1,0,0,1,0,188,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17,200,0,0,0,0,0,0,0,0,0,0]);
return getData(PVRTCData);
}
private static function getData(source:Vector.<int>):ByteArray {
var result:ByteArray = new ByteArray();
for (var i:int = 0, length:int = source.length; i < length; i++) {
result.writeByte(source[i]);
}
return result;
}
public static function getSizeFromATF(byteArray:ByteArray, size:Point):void {
byteArray.position = 7;
var w:int = byteArray.readByte();
var h:int = byteArray.readByte();
size.x = 1 << w;
size.y = 1 << h;
byteArray.position = 0;
}
public static function getSupportedTextureFormat(context3D:Context3D):int {
var testTexture:Texture = context3D.createTexture(4, 4, Context3DTextureFormat.COMPRESSED, false);
var result:int = NONE;
try {
testTexture.uploadCompressedTextureFromByteArray(DXT1Data, 0);
result = DXT1;
} catch(e:Error) {
result = NONE;
}
if (result == NONE) {
try {
testTexture.uploadCompressedTextureFromByteArray(PVRTCData, 0);
result = PVRTC;
} catch(e:Error) {
result = NONE;
}
}
if (result == NONE) {
try {
testTexture.uploadCompressedTextureFromByteArray(ETC1Data, 0);
result = ETC1;
} catch(e:Error) {
result = NONE;
}
}
testTexture.dispose();
return result;
}
public static function vectorNumberToByteArray(vector:Vector.<Number>):ByteArray {
var result:ByteArray = new ByteArray();
result.endian = Endian.LITTLE_ENDIAN;
for (var i:int = 0; i < vector.length; i++) {
result.writeFloat(vector[i]);
}
result.position = 0;
return result;
}
public static function byteArrayToVectorUint(byteArray:ByteArray):Vector.<uint> {
var result:Vector.<uint> = new Vector.<uint>();
var length:uint = 0;
byteArray.position = 0;
byteArray.endian = Endian.LITTLE_ENDIAN;
while (byteArray.bytesAvailable > 0) {
result[length++] = byteArray.readUnsignedShort();
}
return result;
}
public static function createVertexBufferFromByteArray(context:Context3D, byteArray:ByteArray, numVertices:uint, stride:uint = 3):VertexBuffer3D {
if (context == null) {
throw new ReferenceError("context is not set");
}
var buffer:VertexBuffer3D = context.createVertexBuffer(numVertices, stride);
buffer.uploadFromByteArray(byteArray, 0, 0, numVertices);
return buffer;
}
public static function createVertexBufferFromVector(context:Context3D, vector:Vector.<Number>, numVertices:uint, stride:uint = 3):VertexBuffer3D {
if (context == null) {
throw new ReferenceError("context is not set");
}
var buffer:VertexBuffer3D = context.createVertexBuffer(numVertices, stride);
var byteArray:ByteArray = A3DUtils.vectorNumberToByteArray(vector);
buffer.uploadFromByteArray(byteArray, 0, 0, numVertices);
return buffer;
}
public static function createTextureFromByteArray(context:Context3D, byteArray:ByteArray, width:Number, height:Number, format:String):Texture {
if (context == null) {
throw new ReferenceError("context is not set");
}
var texture:Texture = context.createTexture(width, height, format, false);
texture.uploadCompressedTextureFromByteArray(byteArray, 0);
return texture;
}
public static function createIndexBufferFromByteArray(context:Context3D, byteArray:ByteArray, numIndices:uint):IndexBuffer3D {
if (context == null) {
throw new ReferenceError("context is not set");
}
var buffer:IndexBuffer3D = context.createIndexBuffer(numIndices);
buffer.uploadFromByteArray(byteArray, 0, 0, numIndices);
return buffer;
}
public static function createIndexBufferFromVector(context:Context3D, vector:Vector.<uint>, numIndices:int = -1):IndexBuffer3D {
if (context == null) {
throw new ReferenceError("context is not set");
}
var count:uint = numIndices > 0 ? numIndices : vector.length;
var buffer:IndexBuffer3D = context.createIndexBuffer(count);
buffer.uploadFromVector(vector, 0, count);
var byteArray:ByteArray = new ByteArray();
byteArray.endian = Endian.LITTLE_ENDIAN;
for (var i:int = 0; i < count; i++) {
byteArray.writeInt(vector[i]);
}
byteArray.position = 0;
buffer.uploadFromVector(vector, 0, count);
return buffer;
}
// Disassembler
private static var programType:Vector.<String> = Vector.<String>(["VERTEX", "FRAGMENT"]);
private static var samplerDimension:Vector.<String> = Vector.<String>(["2D", "cube", "3D"]);
private static var samplerWraping:Vector.<String> = Vector.<String>(["clamp", "repeat"]);
private static var samplerMipmap:Vector.<String> = Vector.<String>(["mipnone", "mipnearest", "miplinear"]);
private static var samplerFilter:Vector.<String> = Vector.<String>(["nearest", "linear"]);
private static var swizzleType:Vector.<String> = Vector.<String>(["x", "y", "z", "w"]);
private static var twoOperandsCommands:Dictionary;
// TODO: option to turn off auto-prefixes
public static function disassemble(byteCode:ByteArray):String {
if (!twoOperandsCommands) {
twoOperandsCommands = new Dictionary();
twoOperandsCommands[0x1] = true;
twoOperandsCommands[0x2] = true;
twoOperandsCommands[0x3] = true;
twoOperandsCommands[0x4] = true;
twoOperandsCommands[0x6] = true;
twoOperandsCommands[0xb] = true;
twoOperandsCommands[0x11] = true;
twoOperandsCommands[0x12] = true;
twoOperandsCommands[0x13] = true;
twoOperandsCommands[0x17] = true;
twoOperandsCommands[0x18] = true;
twoOperandsCommands[0x19] = true;
twoOperandsCommands[0x26] = true;
twoOperandsCommands[0x28] = true;
twoOperandsCommands[0x29] = true;
twoOperandsCommands[0x2a] = true;
twoOperandsCommands[0x2c] = true;
twoOperandsCommands[0x2d] = true;
}
var res:String = "";
byteCode.position = 0;
if (byteCode.bytesAvailable < 7) {
return "error in byteCode header";
}
res += "magic = " + byteCode.readUnsignedByte().toString(16);
res += "\nversion = " + byteCode.readInt().toString(10);
res += "\nshadertypeid = " + byteCode.readUnsignedByte().toString(16);
var pType:String = programType[byteCode.readByte()];
res += "\nshadertype = " + pType;
res += "\nsource\n";
pType = pType.substring(0, 1).toLowerCase();
var lineNumber:uint = 1;
while (byteCode.bytesAvailable - 24 >= 0) {
res += (lineNumber++).toString() + ": " + getCommand(byteCode, pType) + "\n";
}
if (byteCode.bytesAvailable > 0) {
res += "\nunexpected byteCode length. extra bytes:" + byteCode.bytesAvailable;
}
return res;
}
private static function getCommand(byteCode:ByteArray, programType:String):String {
var cmd:uint = byteCode.readUnsignedInt();
var command:String = CommandType.COMMAND_NAMES[cmd];
var result:String;
var destNumber:uint = byteCode.readUnsignedShort();
var swizzle:uint = byteCode.readByte();
var s:String = "";
var destSwizzle:uint = 4;
if (swizzle < 15) {
s += ".";
s += ((swizzle & 0x1) > 0) ? "x" : "";
s += ((swizzle & 0x2) > 0) ? "y" : "";
s += ((swizzle & 0x4) > 0) ? "z" : "";
s += ((swizzle & 0x8) > 0) ? "w" : "";
destSwizzle = s.length - 1;
}
var sourceSwizzleLimit:int = destSwizzle;
if (cmd == CommandType.TEX) {
sourceSwizzleLimit = 2;
} else if (cmd == CommandType.DP3) {
sourceSwizzleLimit = 3;
} else if (cmd == CommandType.DP4) {
sourceSwizzleLimit = 4;
}
var destType:String = VariableType.TYPE_NAMES[byteCode.readUnsignedByte()].charAt(0);
result = command + " " + attachProgramPrefix(destType, programType) + destNumber.toString() + s + ", ";
result += attachProgramPrefix(getSourceVariable(byteCode, sourceSwizzleLimit), programType);
if (twoOperandsCommands[cmd]) {
if (cmd == CommandType.TEX || cmd == CommandType.TED) {
result += ", " + attachProgramPrefix(getSamplerVariable(byteCode), programType);
} else {
result += ", " + attachProgramPrefix(getSourceVariable(byteCode, sourceSwizzleLimit), programType);
}
} else {
byteCode.readDouble();
}
if (cmd == CommandType.ELS || cmd == CommandType.EIF) {
result = " " + command;
}
return result;
}
private static function attachProgramPrefix(variable:String, programType:String):String {
var char:uint = variable.charCodeAt(0);
if (char == "o".charCodeAt(0)) {
return variable + (programType == "f" ? "c" : "p");
} else if (char == "d".charCodeAt(0)) {
return "o"+variable;
} else if (char != "v".charCodeAt(0)) {
return programType + variable;
}
return variable;
}
private static function getSamplerVariable(byteCode:ByteArray):String {
var number:uint = byteCode.readUnsignedInt();
byteCode.readByte();
var dim:uint = byteCode.readByte() >> 4;
var wraping:uint = byteCode.readByte() >> 4;
var n:uint = byteCode.readByte();
return "s" + number.toString() + " <" + samplerDimension[dim] + ", " + samplerWraping[wraping]
+ ", " + samplerFilter[(n >> 4) & 0xf] + ", " + samplerMipmap[n & 0xf] + ">";
}
private static function getSourceVariable(byteCode:ByteArray, swizzleLimit:uint):String {
var s1Number:uint = byteCode.readUnsignedShort();
var offset:uint = byteCode.readUnsignedByte();
var s:String = getSourceSwizzle(byteCode.readUnsignedByte(), swizzleLimit);
var s1Type:String = VariableType.TYPE_NAMES[byteCode.readUnsignedByte()].charAt(0);
var indexType:String = VariableType.TYPE_NAMES[byteCode.readUnsignedByte()].charAt(0);
var comp:String = swizzleType[byteCode.readUnsignedByte()];
if (byteCode.readUnsignedByte() > 0) {
return s1Type + "[" + indexType + s1Number.toString() + "." + comp + ((offset > 0) ? ("+" + offset.toString()) : "") + "]" + s;
}
return s1Type + s1Number.toString() + s;
}
private static function getSourceSwizzle(swizzle:uint, swizzleLimit:uint = 4):String {
var s:String = "";
if (swizzle != 0xe4) {
s += ".";
s += swizzleType[(swizzle & 0x3)];
s += swizzleType[(swizzle >> 2) & 0x3];
s += swizzleType[(swizzle >> 4) & 0x3];
s += swizzleType[(swizzle >> 6) & 0x3];
s = swizzleLimit < 4 ? s.substring(0, swizzleLimit + 1) : s;
}
return s;
}
alternativa3d static function checkParent(child:Class, parent:Class):Boolean {
var current:Class = child;
if (parent == null) return true;
while (true) {
if (current == parent) return true;
var className:String = getQualifiedSuperclassName(current);
if (className != null) {
current = getDefinitionByName(className) as Class;
} else return false;
}
return false;
}
}
}

View File

@@ -1,148 +1,148 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
* If it is not possible or desirable to put the notice in a particular file, then You may include the notice in a location (such as a LICENSE file in a relevant directory) where a recipient would be likely to look for such a notice.
* You may add additional accurate notices of copyright ownership.
*
* It is desirable to notify that Covered Software was "Powered by AlternativaPlatform" with link to http://www.alternativaplatform.com/
* */
package alternativa.engine3d.materials.compiler {
import flash.utils.Dictionary;
/**
* @private
*/
public class CommandType {
public static const MOV : uint = 0x00;
public static const ADD : uint = 0x01;
public static const SUB : uint = 0x02;
public static const MUL : uint = 0x03;
public static const DIV : uint = 0x04;
public static const RCP : uint = 0x05;
public static const MIN : uint = 0x06;
public static const MAX : uint = 0x07;
public static const FRC : uint = 0x08;
public static const SQT : uint = 0x09;
public static const RSQ : uint = 0x0a;
public static const POW : uint = 0x0b;
public static const LOG : uint = 0x0c;
public static const EXP : uint = 0x0d;
public static const NRM : uint = 0x0e;
public static const SIN : uint = 0x0f;
public static const COS : uint = 0x10;
public static const CRS : uint = 0x11;
public static const DP3 : uint = 0x12;
public static const DP4 : uint = 0x13;
public static const ABS : uint = 0x14;
public static const NEG : uint = 0x15;
public static const SAT : uint = 0x16;
public static const M33 : uint = 0x17;
public static const M44 : uint = 0x18;
public static const M34 : uint = 0x19;
public static const DDX : uint = 0x1a;
public static const DDY : uint = 0x1b;
public static const IFE : uint = 0x1c;
public static const INE : uint = 0x1d;
public static const IFG : uint = 0x1e;
public static const IFL : uint = 0x1f;
public static const ELS : uint = 0x20;
public static const EIF : uint = 0x21;
public static const TED : uint = 0x26;
public static const KIL : uint = 0x27;
public static const TEX : uint = 0x28;
// set if greater equal
public static const SGE : uint = 0x29;
// set if less than
public static const SLT : uint = 0x2a;
// set if greater than
public static const SGN : uint = 0x2b;
// set if equal
public static const SEQ : uint = 0x2c;
// set if not equal
public static const SNE : uint = 0x2d;
public static const COMMAND_NAMES : Dictionary = new Dictionary();
COMMAND_NAMES[MOV] = "mov";
COMMAND_NAMES[ADD] = "add";
COMMAND_NAMES[SUB] = "sub";
COMMAND_NAMES[MUL] = "mul";
COMMAND_NAMES[DIV] = "div";
COMMAND_NAMES[RCP] = "rcp";
COMMAND_NAMES[MIN] = "min";
COMMAND_NAMES[MAX] = "max";
COMMAND_NAMES[FRC] = "frc";
COMMAND_NAMES[SQT] = "sqt";
COMMAND_NAMES[RSQ] = "rsq";
COMMAND_NAMES[POW] = "pow";
COMMAND_NAMES[LOG] = "log";
COMMAND_NAMES[EXP] = "exp";
COMMAND_NAMES[NRM] = "nrm";
COMMAND_NAMES[SIN] = "sin";
COMMAND_NAMES[COS] = "cos";
COMMAND_NAMES[CRS] = "crs";
COMMAND_NAMES[DP3] = "dp3";
COMMAND_NAMES[DP4] = "dp4";
COMMAND_NAMES[ABS] = "abs";
COMMAND_NAMES[NEG] = "neg";
COMMAND_NAMES[SAT] = "sat";
COMMAND_NAMES[M33] = "m33";
COMMAND_NAMES[M44] = "m44";
COMMAND_NAMES[M34] = "m34";
COMMAND_NAMES[DDX] = "ddx";
COMMAND_NAMES[DDY] = "ddy";
COMMAND_NAMES[IFE] = "ife";
COMMAND_NAMES[INE] = "ine";
COMMAND_NAMES[IFG] = "ifg";
COMMAND_NAMES[IFL] = "ifl";
COMMAND_NAMES[ELS] = "els";
COMMAND_NAMES[EIF] = "eif";
COMMAND_NAMES[TED] = "ted";
COMMAND_NAMES[KIL] = "kil";
COMMAND_NAMES[TEX] = "tex";
COMMAND_NAMES[SGE] = "sge";
COMMAND_NAMES[SLT] = "slt";
COMMAND_NAMES[SGN] = "sgn";
COMMAND_NAMES[SEQ] = "seq";
COMMAND_NAMES[SNE] = "sne";
}
}
/**
* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
* If it is not possible or desirable to put the notice in a particular file, then You may include the notice in a location (such as a LICENSE file in a relevant directory) where a recipient would be likely to look for such a notice.
* You may add additional accurate notices of copyright ownership.
*
* It is desirable to notify that Covered Software was "Powered by AlternativaPlatform" with link to http://www.alternativaplatform.com/
* */
package alternativa.engine3d.materials.compiler {
/**
* @private
*/
public class CommandType {
public static const MOV : uint = 0x00;
public static const ADD : uint = 0x01;
public static const SUB : uint = 0x02;
public static const MUL : uint = 0x03;
public static const DIV : uint = 0x04;
public static const RCP : uint = 0x05;
public static const MIN : uint = 0x06;
public static const MAX : uint = 0x07;
public static const FRC : uint = 0x08;
public static const SQT : uint = 0x09;
public static const RSQ : uint = 0x0a;
public static const POW : uint = 0x0b;
public static const LOG : uint = 0x0c;
public static const EXP : uint = 0x0d;
public static const NRM : uint = 0x0e;
public static const SIN : uint = 0x0f;
public static const COS : uint = 0x10;
public static const CRS : uint = 0x11;
public static const DP3 : uint = 0x12;
public static const DP4 : uint = 0x13;
public static const ABS : uint = 0x14;
public static const NEG : uint = 0x15;
public static const SAT : uint = 0x16;
public static const M33 : uint = 0x17;
public static const M44 : uint = 0x18;
public static const M34 : uint = 0x19;
public static const DDX : uint = 0x1a;
public static const DDY : uint = 0x1b;
public static const IFE : uint = 0x1c;
public static const INE : uint = 0x1d;
public static const IFG : uint = 0x1e;
public static const IFL : uint = 0x1f;
public static const ELS : uint = 0x20;
public static const EIF : uint = 0x21;
public static const TED : uint = 0x26;
public static const KIL : uint = 0x27;
public static const TEX : uint = 0x28;
// set if greater equal
public static const SGE : uint = 0x29;
// set if less than
public static const SLT : uint = 0x2a;
// set if greater than
public static const SGN : uint = 0x2b;
// set if equal
public static const SEQ : uint = 0x2c;
// set if not equal
public static const SNE : uint = 0x2d;
public static const COMMAND_NAMES : Array = [];
COMMAND_NAMES[MOV] = "mov";
COMMAND_NAMES[ADD] = "add";
COMMAND_NAMES[SUB] = "sub";
COMMAND_NAMES[MUL] = "mul";
COMMAND_NAMES[DIV] = "div";
COMMAND_NAMES[RCP] = "rcp";
COMMAND_NAMES[MIN] = "min";
COMMAND_NAMES[MAX] = "max";
COMMAND_NAMES[FRC] = "frc";
COMMAND_NAMES[SQT] = "sqt";
COMMAND_NAMES[RSQ] = "rsq";
COMMAND_NAMES[POW] = "pow";
COMMAND_NAMES[LOG] = "log";
COMMAND_NAMES[EXP] = "exp";
COMMAND_NAMES[NRM] = "nrm";
COMMAND_NAMES[SIN] = "sin";
COMMAND_NAMES[COS] = "cos";
COMMAND_NAMES[CRS] = "crs";
COMMAND_NAMES[DP3] = "dp3";
COMMAND_NAMES[DP4] = "dp4";
COMMAND_NAMES[ABS] = "abs";
COMMAND_NAMES[NEG] = "neg";
COMMAND_NAMES[SAT] = "sat";
COMMAND_NAMES[M33] = "m33";
COMMAND_NAMES[M44] = "m44";
COMMAND_NAMES[M34] = "m34";
COMMAND_NAMES[DDX] = "ddx";
COMMAND_NAMES[DDY] = "ddy";
COMMAND_NAMES[IFE] = "ife";
COMMAND_NAMES[INE] = "ine";
COMMAND_NAMES[IFG] = "ifg";
COMMAND_NAMES[IFL] = "ifl";
COMMAND_NAMES[ELS] = "els";
COMMAND_NAMES[EIF] = "eif";
COMMAND_NAMES[TED] = "ted";
COMMAND_NAMES[KIL] = "kil";
COMMAND_NAMES[TEX] = "tex";
COMMAND_NAMES[SGE] = "sge";
COMMAND_NAMES[SLT] = "slt";
COMMAND_NAMES[SGN] = "sgn";
COMMAND_NAMES[SEQ] = "seq";
COMMAND_NAMES[SNE] = "sne";
}
}

View File

@@ -1,74 +1,74 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
* If it is not possible or desirable to put the notice in a particular file, then You may include the notice in a location (such as a LICENSE file in a relevant directory) where a recipient would be likely to look for such a notice.
* You may add additional accurate notices of copyright ownership.
*
* It is desirable to notify that Covered Software was "Powered by AlternativaPlatform" with link to http://www.alternativaplatform.com/
* */
package alternativa.engine3d.materials.compiler {
import flash.utils.ByteArray;
/**
* @private
*/
public class DestinationVariable extends Variable {
public function DestinationVariable(source:String) {
var strType : String = source.match(/[tovid]/)[0];
index = parseInt(source.match(/\d+/)[0], 10);
var swizzle:Array = source.match(/\.[xyzw]{1,4}/);
var regmask:uint;
var maskmatch:String = swizzle ? swizzle[0] : null;
if (maskmatch != null) {
regmask = 0;
var cv:int;
var maskLength:uint = maskmatch.length;
// If first char is point, then skip
for (var i:int = 1; i < maskLength; i++) {
cv = maskmatch.charCodeAt(i) - X_CHAR_CODE;
if (cv == -1) cv = 3;
regmask |= 1 << cv;
}
} else {
regmask = 0xf;
// id swizzle or mask
}
lowerCode = (regmask << 16) | index;
switch(strType){
case "t":
lowerCode |= 0x2000000;
type = 2;
break;
case "o":
lowerCode |= 0x3000000;
type = 3;
break;
case "v":
lowerCode |= 0x4000000;
type = 4;
break;
case "d":
lowerCode |= 0x6000000;
type = 6;
break;
case "i":
lowerCode |= 0x7000000;
type = 7;
break;
default :
throw new ArgumentError("Wrong destination register type, must be \"t\" or \"o\" or \"v\", var = " + source);
break;
}
}
override public function writeToByteArray(byteCode:ByteArray, newIndex:int, newType:int, offset:int = 0):void {
byteCode.position = position + offset;
byteCode.writeUnsignedInt((lowerCode & ~(0xf00ffff)) | newIndex | (newType << 24));
}
}
}
/**
* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
* If it is not possible or desirable to put the notice in a particular file, then You may include the notice in a location (such as a LICENSE file in a relevant directory) where a recipient would be likely to look for such a notice.
* You may add additional accurate notices of copyright ownership.
*
* It is desirable to notify that Covered Software was "Powered by AlternativaPlatform" with link to http://www.alternativaplatform.com/
* */
package alternativa.engine3d.materials.compiler {
import flash.utils.ByteArray;
/**
* @private
*/
public class DestinationVariable extends Variable {
public function DestinationVariable(source:String) {
var strType : String = source.match(/[tovid]/)[0];
index = parseInt(source.match(/\d+/)[0], 10);
var swizzle:Array = source.match(/\.[xyzw]{1,4}/);
var regmask:uint;
var maskmatch:String = swizzle ? swizzle[0] : null;
if (maskmatch != null) {
regmask = 0;
var cv:int;
var maskLength:uint = maskmatch.length;
// If first char is point, then skip
for (var i:int = 1; i < maskLength; i++) {
cv = maskmatch.charCodeAt(i) - X_CHAR_CODE;
if (cv == -1) cv = 3;
regmask |= 1 << cv;
}
} else {
regmask = 0xf;
// id swizzle or mask
}
lowerCode = (regmask << 16) | index;
switch(strType){
case "t":
lowerCode |= 0x2000000;
type = VariableType.TEMPORARY;
break;
case "o":
lowerCode |= 0x3000000;
type = VariableType.OUTPUT;
break;
case "v":
lowerCode |= 0x4000000;
type = VariableType.VARYING;
break;
case "d":
lowerCode |= 0x6000000;
type = VariableType.DEPTH;
break;
case "i":
lowerCode |= 0x7000000;
type = VariableType.INPUT;
break;
default :
throw new ArgumentError('Wrong destination register type, must be "t" or "o" or "v" or "d", var = ' + source);
break;
}
}
override public function writeToByteArray(byteCode:ByteArray, newIndex:int, newType:int, offset:int = 0):void {
byteCode.position = position + offset;
byteCode.writeUnsignedInt((lowerCode & ~(0xf00ffff)) | newIndex | (newType << 24));
}
}
}

View File

@@ -1,426 +1,426 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
* If it is not possible or desirable to put the notice in a particular file, then You may include the notice in a location (such as a LICENSE file in a relevant directory) where a recipient would be likely to look for such a notice.
* You may add additional accurate notices of copyright ownership.
*
* It is desirable to notify that Covered Software was "Powered by AlternativaPlatform" with link to http://www.alternativaplatform.com/
* */
package alternativa.engine3d.materials.compiler {
import alternativa.engine3d.alternativa3d;
import flash.display3D.Context3DProgramType;
import flash.utils.ByteArray;
import flash.utils.Dictionary;
import flash.utils.Endian;
use namespace alternativa3d;
/**
* @private
* Dynamic shader linker
*/
public class Linker {
/**
* Data after linking.
*/
public var data:ByteArray = null;
/**
* Number of used slots.
*/
public var slotsCount:int = 0;
/**
* Number of lines of the shader code.
*/
public var commandsCount:int = 0;
/**
* Linker type. Can be vertex of fragment.
*/
public var type:String;
private var procedures:Vector.<Procedure> = new Vector.<Procedure>();
/**
* @private
* Variables after linking.
*/
alternativa3d var _linkedVariables:Object;
// Dictionary of temporary variables at this linker. Key is a name of variable, value is a variable.
private var _localVariables:Object = new Object();
// Key - procedure, value - array of strings.
private var _inputParams:Dictionary = new Dictionary();
// Key - procedure, value - array of strings.
private var _outputParams:Dictionary = new Dictionary();
// Counters of variables by types
private var _locals:Vector.<uint> = new Vector.<uint>(7, true);
private var samplers:Object = new Object();
private var _varyings:Object = new Object();
/**
* Creates a new Linker instance.
*
* @param programType Type of shader.
*/
public function Linker(programType:String) {
type = programType;
}
/**
* Clears a content.
*/
public function clear():void {
data = null;
_locals[0] = _locals[1] = _locals[2] = _locals[3] = _locals[4] = _locals[5] = _locals[6] = 0;
procedures.length = 0;
_varyings = new Object();
samplers = new Object();
commandsCount = 0;
slotsCount = 0;
_linkedVariables = null;
_inputParams = new Dictionary();
_outputParams = new Dictionary();
}
/**
* Adds a new shader procedure.
*
* @param procedure Procedure to add.
*
* @see Procedure
*/
public function addProcedure(procedure:Procedure, ...args):void {
for each(var v:Variable in procedure.variablesUsages[VariableType.VARYING]) {
if (v == null) continue;
var nv:Variable = _varyings[v.name] = new Variable();
nv.name = v.name;
nv.type = v.type;
nv.index = -1;
}
procedures.push(procedure);
_inputParams[procedure] = args;
data = null;
}
/**
* Declaration of variable of given type.
*
* @param name Name of variable
* @param type Type of variable. Should be one of the VariableType constants. The default value is Temporary variable.
*
* @see VariableType
*/
public function declareVariable(name:String, type:uint = 2):void {
var v:Variable = new Variable();
v.index = -1;
v.type = type;
v.name = name;
_localVariables[name] = v;
if (v.type == VariableType.VARYING) {
_varyings[v.name] = v;
}
data = null;
}
public function declareSampler(output:String, uv:String, sampler:String, options:String):void {
if (_localVariables[uv] == null) {
throw new ArgumentError("Undefined variable " + uv);
}
if (_localVariables[sampler] == null) {
throw new ArgumentError("Undefined variable " + sampler);
}
if (_localVariables[output] == null) {
declareVariable(output, 2);
}
data = null;
}
/**
* Setting of input parameters of procedure.
*
* @param procedure A procedure to which parameters will be set.
* @param args Names of variables, separated by the comma, that are passed into the procedure.
* Variables must be previously declared, using the method <code>declareVariable()</code>.
*
* @see #declareVariable()
*/
public function setInputParams(procedure:Procedure, ...args):void {
_inputParams[procedure] = args;
data = null;
}
/**
* Setting of output parameters of procedure.
*
* @param procedure A procedure to which parameters will be set.
* @param args Names of variables, separated by the comma, that are passed into the procedure.
* Variables must be previously declared, using the method declareVariable().
*
* @see #declareVariable()
*/
public function setOutputParams(procedure:Procedure, ...args):void {
_outputParams[procedure] = args;
data = null;
}
/**
* Returns of index of variable after the linking.
*
* @param name Name of variable.
* @return Its index for sending to Context3D
*/
public function getVariableIndex(name:String):int {
if (_linkedVariables == null) throw new Error("Not linked");
var variable:Variable = _linkedVariables[name];
if (variable == null) {
throw new Error('Variable "' + name + '" not found');
}
return variable.index;
}
/**
* Returns index of variable or <code>-1</code> there is no variable with such name.
*/
public function findVariable(name:String):int {
if (_linkedVariables == null) throw new Error("Has not linked");
var variable:Variable = _linkedVariables[name];
if (variable == null) {
return -1;
}
return variable.index;
}
/**
* Returns the existence of this variable in linked code.
* @param name Name of variable
*/
public function containsVariable(name:String):Boolean {
if (_linkedVariables == null) throw new Error("Not linked");
return _linkedVariables[name] != null;
}
/**
* Linking of procedures to one shader.
*/
public function link(version:uint = 1):void {
if (data != null) return;
var v:Variable;
var variables:Object = _linkedVariables = new Object();
var p:Procedure;
var i:int, j:int;
var nv:Variable;
for each (v in _localVariables) {
nv = variables[v.name] = new Variable();
nv.index = -1;
nv.type = v.type;
nv.name = v.name;
nv.size = v.size;
}
data = new ByteArray();
data.endian = Endian.LITTLE_ENDIAN;
data.writeByte(0xa0);
// tag version
data.writeUnsignedInt(version);
// AGAL version, big endian, bit pattern will be 0x01000000
data.writeByte(0xa1);
// tag program id
data.writeByte((type == Context3DProgramType.FRAGMENT) ? 1 : 0); // vertex or fragment
commandsCount = 0;
slotsCount = 0;
_locals[0] = 0;
_locals[1] = 0;
_locals[2] = 0;
_locals[3] = 0;
_locals[4] = 0;
_locals[5] = 0;
_locals[6] = 0;
// First iteration - collecting of variables.
for each (p in procedures) {
_locals[1] += p.reservedConstants;
var iLength:int = p.variablesUsages.length;
for (i = 0; i < iLength; i++) {
var vector:Vector.<Variable> = p.variablesUsages[i];
var jLength:int = vector.length;
for (j = 0; j < jLength; j++) {
v = vector[j];
if (v == null || v.name == null) continue;
if (v.name == null && i != 2 && i != 6 && i != 3 && i != 7) {
throw new Error("Linkage error: Noname variable. Procedure = " + p.name + ", type = " + i.toString() + ", index = " + j.toString());
}
nv = variables[v.name] = new Variable();
nv.index = -1;
nv.type = v.type;
nv.name = v.name;
nv.size = v.size;
}
}
}
for each (p in procedures) {
// Changing of inputs
var offset:int = data.length;
data.position = data.length;
data.writeBytes(p.byteCode, 0, p.byteCode.length);
var input:Array = _inputParams[p];
var output:Array = _outputParams[p];
var param:String;
var numParams:int;
if (input != null) {
numParams = input.length;
for (j = 0; j < numParams; j++) {
param = input[j];
v = variables[param];
if (v == null) {
throw new Error("Input parameter not set. paramName = " + param);
}
if (p.variablesUsages[7].length > j) {
var inParam:Variable = p.variablesUsages[7][j];
if (inParam == null) {
throw new Error("Input parameter set, but not exist in code. paramName = " + param + ", register = i" + j.toString());
}
if (v.index < 0) {
v.index = _locals[v.type];
_locals[v.type] += v.size;
}
while (inParam != null) {
inParam.writeToByteArray(data, v.index, v.type, offset);
inParam = inParam.next;
}
}
}
}
if (output != null) {
// Output parameters
numParams = output.length;
for (j = 0; j < numParams; j++) {
param = output[j];
v = variables[param];
if (v == null) {
if (j == 0 && (i == procedures.length - 1)) {
// Output variable
continue;
}
throw new Error("Output parameter have not declared. paramName = " + param);
}
if (v.index < 0) {
if (v.type != 2) {
throw new Error("Wrong output type:" + VariableType.TYPE_NAMES[v.type]);
}
v.index = _locals[v.type];
_locals[v.type] += v.size;
}
var outParam:Variable = p.variablesUsages[3][j];
if (outParam == null) {
throw new Error("Output parameter set, but not exist in code. paramName = " + param + ", register = i" + j.toString());
}
while (outParam != null) {
outParam.writeToByteArray(data, v.index, v.type, offset);
outParam = outParam.next;
}
}
}
var vars:Vector.<Variable> = p.variablesUsages[2];
for (j = 0; j < vars.length; j++) {
v = vars[j];
if (v == null) continue;
while (v != null) {
v.writeToByteArray(data, v.index + _locals[2], VariableType.TEMPORARY, offset);
v = v.next;
}
}
resolveVariablesUsages(data, variables, p.variablesUsages[0], VariableType.ATTRIBUTE, offset);
resolveVariablesUsages(data, variables, p.variablesUsages[1], VariableType.CONSTANT, offset);
resolveVariablesUsages(data, _varyings, p.variablesUsages[4], VariableType.VARYING, offset);
resolveVariablesUsages(data, variables, p.variablesUsages[5], VariableType.SAMPLER, offset);
commandsCount += p.commandsCount;
slotsCount += p.slotsCount;
}
}
private function resolveVariablesUsages(code:ByteArray, variables:Object, variableUsages:Vector.<Variable>, type:uint, offset:int):void {
for (var j:int = 0; j < variableUsages.length; j++) {
var vUsage:Variable = variableUsages[j];
if (vUsage == null) continue;
if (vUsage.isRelative) continue;
var variable:Variable = variables[vUsage.name];
if (variable.index < 0) {
variable.index = _locals[type];
_locals[type] += variable.size;
}
while (vUsage != null) {
vUsage.writeToByteArray(code, variable.index, variable.type, offset);
vUsage = vUsage.next;
}
}
}
/**
* Returns description of procedures: name, size, input and output parameters.
* @return
*/
public function describeLinkageInfo():String {
var str:String;
var result:String = "LINKER:\n";
var totalCodes:uint = 0;
var totalCommands:uint = 0;
for (var i:int = 0; i < procedures.length; i++) {
var p:Procedure = procedures[i];
if (p.name != null) {
result += p.name + "(";
} else {
result += "#" + i.toString() + "(";
}
var args:* = _inputParams[p];
if (args != null) {
for each (str in args) {
result += str + ",";
}
result = result.substr(0, result.length - 1);
}
result += ")";
args = _outputParams[p];
if (args != null) {
result += "->(";
for each (str in args) {
result += str + ",";
}
result = result.substr(0, result.length - 1);
result += ")";
}
result += " [IS:" + p.slotsCount.toString() + ", CMDS:" + p.commandsCount.toString() + "]\n";
totalCodes += p.slotsCount;
totalCommands += p.commandsCount;
}
result += "[IS:" + totalCodes.toString() + ", CMDS:" + totalCommands.toString() + "]\n";
return result;
}
public function get varyings():Object {
return _varyings;
}
public function set varyings(value:Object):void {
_varyings = value;
data = null;
}
}
}
/**
* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
* If it is not possible or desirable to put the notice in a particular file, then You may include the notice in a location (such as a LICENSE file in a relevant directory) where a recipient would be likely to look for such a notice.
* You may add additional accurate notices of copyright ownership.
*
* It is desirable to notify that Covered Software was "Powered by AlternativaPlatform" with link to http://www.alternativaplatform.com/
* */
package alternativa.engine3d.materials.compiler {
import alternativa.engine3d.alternativa3d;
import flash.display3D.Context3DProgramType;
import flash.utils.ByteArray;
import flash.utils.Dictionary;
import flash.utils.Endian;
use namespace alternativa3d;
/**
* @private
* Dynamic shader linker
*/
public class Linker {
/**
* Data after linking.
*/
public var data:ByteArray = null;
/**
* Number of used slots.
*/
public var slotsCount:int = 0;
/**
* Number of lines of the shader code.
*/
public var commandsCount:int = 0;
/**
* Linker type. Can be vertex of fragment.
*/
public var type:String;
private var procedures:Vector.<Procedure> = new Vector.<Procedure>();
/**
* @private
* Variables after linking.
*/
alternativa3d var _linkedVariables:Object;
// Dictionary of temporary variables at this linker. Key is a name of variable, value is a variable.
private var _localVariables:Object = {};
// Key - procedure, value - array of strings.
private var _inputParams:Dictionary = new Dictionary();
// Key - procedure, value - array of strings.
private var _outputParams:Dictionary = new Dictionary();
// Counters of variables by types
private var _locals:Vector.<uint> = new Vector.<uint>(7, true);
private var samplers:Object = {};
private var _varyings:Object = {};
/**
* Creates a new Linker instance.
*
* @param programType Type of shader.
*/
public function Linker(programType:String) {
type = programType;
}
/**
* Clears a content.
*/
public function clear():void {
data = null;
_locals[0] = _locals[1] = _locals[2] = _locals[3] = _locals[4] = _locals[5] = _locals[6] = 0;
procedures.length = 0;
_varyings = {};
samplers = {};
commandsCount = 0;
slotsCount = 0;
_linkedVariables = null;
_inputParams = new Dictionary();
_outputParams = new Dictionary();
}
/**
* Adds a new shader procedure.
*
* @param procedure Procedure to add.
*
* @see Procedure
*/
public function addProcedure(procedure:Procedure, ...args):void {
for each(var v:Variable in procedure.variablesUsages[VariableType.VARYING]) {
if (v == null) continue;
var nv:Variable = _varyings[v.name] = new Variable();
nv.name = v.name;
nv.type = v.type;
nv.index = -1;
}
procedures.push(procedure);
_inputParams[procedure] = args;
data = null;
}
/**
* Declaration of variable of given type.
*
* @param name Name of variable
* @param type Type of variable. Should be one of the VariableType constants. The default value is Temporary variable.
*
* @see VariableType
*/
public function declareVariable(name:String, type:uint = 2):void {
var v:Variable = new Variable();
v.index = -1;
v.type = type;
v.name = name;
_localVariables[name] = v;
if (v.type == VariableType.VARYING) {
_varyings[v.name] = v;
}
data = null;
}
public function declareSampler(output:String, uv:String, sampler:String, options:String):void {
if (_localVariables[uv] == null) {
throw new ArgumentError("Undefined variable " + uv);
}
if (_localVariables[sampler] == null) {
throw new ArgumentError("Undefined variable " + sampler);
}
if (_localVariables[output] == null) {
declareVariable(output, 2);
}
data = null;
}
/**
* Setting of input parameters of procedure.
*
* @param procedure A procedure to which parameters will be set.
* @param args Names of variables, separated by the comma, that are passed into the procedure.
* Variables must be previously declared, using the method <code>declareVariable()</code>.
*
* @see #declareVariable()
*/
public function setInputParams(procedure:Procedure, ...args):void {
_inputParams[procedure] = args;
data = null;
}
/**
* Setting of output parameters of procedure.
*
* @param procedure A procedure to which parameters will be set.
* @param args Names of variables, separated by the comma, that are passed into the procedure.
* Variables must be previously declared, using the method declareVariable().
*
* @see #declareVariable()
*/
public function setOutputParams(procedure:Procedure, ...args):void {
_outputParams[procedure] = args;
data = null;
}
/**
* Returns of index of variable after the linking.
*
* @param name Name of variable.
* @return Its index for sending to Context3D
*/
public function getVariableIndex(name:String):int {
if (_linkedVariables == null) throw new Error("Not linked");
var variable:Variable = _linkedVariables[name];
if (variable == null) {
throw new Error('Variable "' + name + '" not found');
}
return variable.index;
}
/**
* Returns index of variable or <code>-1</code> there is no variable with such name.
*/
public function findVariable(name:String):int {
if (_linkedVariables == null) throw new Error("Has not linked");
var variable:Variable = _linkedVariables[name];
if (variable == null) {
return -1;
}
return variable.index;
}
/**
* Returns the existence of this variable in linked code.
* @param name Name of variable
*/
public function containsVariable(name:String):Boolean {
if (_linkedVariables == null) throw new Error("Not linked");
return _linkedVariables[name] != null;
}
/**
* Linking of procedures to one shader.
*/
public function link(version:uint = 1):void {
if (data != null) return;
var v:Variable;
var variables:Object = _linkedVariables = {};
var p:Procedure;
var i:int, j:int;
var nv:Variable;
for each (v in _localVariables) {
nv = variables[v.name] = new Variable();
nv.index = -1;
nv.type = v.type;
nv.name = v.name;
nv.size = v.size;
}
data = new ByteArray();
data.endian = Endian.LITTLE_ENDIAN;
data.writeByte(0xa0);
// tag version
data.writeUnsignedInt(version);
// AGAL version, big endian, bit pattern will be 0x01000000
data.writeByte(0xa1);
// tag program id
data.writeByte((type == Context3DProgramType.FRAGMENT) ? 1 : 0); // vertex or fragment
commandsCount = 0;
slotsCount = 0;
_locals[0] = 0;
_locals[1] = 0;
_locals[2] = 0;
_locals[3] = 0;
_locals[4] = 0;
_locals[5] = 0;
_locals[6] = 0;
// First iteration - collecting of variables.
for each (p in procedures) {
_locals[1] += p.reservedConstants;
var iLength:int = p.variablesUsages.length;
for (i = 0; i < iLength; i++) {
var vector:Vector.<Variable> = p.variablesUsages[i];
var jLength:int = vector.length;
for (j = 0; j < jLength; j++) {
v = vector[j];
if (v == null || v.name == null) continue;
if (v.name == null && i != 2 && i != 3 && i != 6 && i != 7) {
// TODO: Never happens
throw new Error("Linkage error: Noname variable. Procedure = " + p.name + ", type = " + i.toString() + ", index = " + j.toString());
}
nv = variables[v.name] = new Variable();
nv.index = -1;
nv.type = v.type;
nv.name = v.name;
nv.size = v.size;
}
}
}
for each (p in procedures) {
// Changing of inputs
var offset:int = data.length;
data.position = data.length;
data.writeBytes(p.byteCode, 0, p.byteCode.length);
var input:Array = _inputParams[p];
var output:Array = _outputParams[p];
var param:String;
var numParams:int;
if (input != null) {
numParams = input.length;
for (j = 0; j < numParams; j++) {
param = input[j];
v = variables[param];
if (v == null) {
throw new Error("Input parameter not set. paramName = " + param);
}
if (p.variablesUsages[7].length > j) {
var inParam:Variable = p.variablesUsages[7][j];
if (inParam == null) {
throw new Error("Input parameter set, but not used in code. paramName = " + param + ", register = i" + j.toString());
}
if (v.index < 0) {
v.index = _locals[v.type];
_locals[v.type] += v.size;
}
while (inParam != null) {
inParam.writeToByteArray(data, v.index, v.type, offset);
inParam = inParam.next;
}
}
}
}
if (output != null) {
// Output parameters
numParams = output.length;
for (j = 0; j < numParams; j++) {
param = output[j];
v = variables[param];
if (v == null) {
if (j == 0 && (i == procedures.length - 1)) {
// Output variable
continue;
}
throw new Error("Output parameter not declared. paramName = " + param);
}
if (v.index < 0) {
if (v.type != 2) {
throw new Error("Wrong output type:" + VariableType.TYPE_NAMES[v.type]);
}
v.index = _locals[v.type];
_locals[v.type] += v.size;
}
var outParam:Variable = p.variablesUsages[3][j];
if (outParam == null) {
throw new Error("Output parameter set, but not exist in code. paramName = " + param + ", register = i" + j.toString());
}
while (outParam != null) {
outParam.writeToByteArray(data, v.index, v.type, offset);
outParam = outParam.next;
}
}
}
var vars:Vector.<Variable> = p.variablesUsages[2];
for (j = 0; j < vars.length; j++) {
v = vars[j];
if (v == null) continue;
while (v != null) {
v.writeToByteArray(data, _locals[2] + v.index, VariableType.TEMPORARY, offset);
v = v.next;
}
}
resolveVariablesUsages(data, variables, p.variablesUsages[0], VariableType.ATTRIBUTE, offset);
resolveVariablesUsages(data, variables, p.variablesUsages[1], VariableType.CONSTANT, offset);
resolveVariablesUsages(data, _varyings, p.variablesUsages[4], VariableType.VARYING, offset);
resolveVariablesUsages(data, variables, p.variablesUsages[5], VariableType.SAMPLER, offset);
commandsCount += p.commandsCount;
slotsCount += p.slotsCount;
}
}
private function resolveVariablesUsages(code:ByteArray, variables:Object, variableUsages:Vector.<Variable>, type:uint, offset:int):void {
for (var j:int = 0; j < variableUsages.length; j++) {
var vUsage:Variable = variableUsages[j];
if (vUsage == null) continue;
if (vUsage.isRelative) continue;
var variable:Variable = variables[vUsage.name];
if (variable.index < 0) {
variable.index = _locals[type];
_locals[type] += variable.size;
}
while (vUsage != null) {
vUsage.writeToByteArray(code, variable.index, variable.type, offset);
vUsage = vUsage.next;
}
}
}
/**
* Returns description of procedures: name, size, input and output parameters.
* @return
*/
public function describeLinkageInfo():String {
var str:String;
var result:String = "LINKER:\n";
var totalCodes:uint = 0;
var totalCommands:uint = 0;
for (var i:int = 0; i < procedures.length; i++) {
var p:Procedure = procedures[i];
if (p.name != null) {
result += p.name + "(";
} else {
result += "#" + i.toString() + "(";
}
var args:* = _inputParams[p];
if (args != null) {
for each (str in args) {
result += str + ",";
}
result = result.substr(0, result.length - 1);
}
result += ")";
args = _outputParams[p];
if (args != null) {
result += "->(";
for each (str in args) {
result += str + ",";
}
result = result.substr(0, result.length - 1);
result += ")";
}
result += " [IS:" + p.slotsCount.toString() + ", CMDS:" + p.commandsCount.toString() + "]\n";
totalCodes += p.slotsCount;
totalCommands += p.commandsCount;
}
result += "[IS:" + totalCodes.toString() + ", CMDS:" + totalCommands.toString() + "]\n";
return result;
}
public function get varyings():Object {
return _varyings;
}
public function set varyings(value:Object):void {
_varyings = value;
data = null;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,103 +1,102 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
* If it is not possible or desirable to put the notice in a particular file, then You may include the notice in a location (such as a LICENSE file in a relevant directory) where a recipient would be likely to look for such a notice.
* You may add additional accurate notices of copyright ownership.
*
* It is desirable to notify that Covered Software was "Powered by AlternativaPlatform" with link to http://www.alternativaplatform.com/
* */
package alternativa.engine3d.materials.compiler {
import flash.utils.ByteArray;
/**
* @private
*/
public class SourceVariable extends Variable {
public var relative : RelativeVariable;
override public function get size() : uint {
if (relative) {
return 0;
}
return super.size;
}
public function SourceVariable(source : String) {
var strType : String = String(source.match(/[catsoivd]/g)[0]);
var regmask : uint;
var relreg : Array = source.match(/\[.*\]/g);
var isRel : Boolean = relreg.length > 0;
if (isRel) {
source = source.replace(relreg[0], "0");
} else {
index = parseInt(source.match(/\d+/g)[0], 10);
}
var swizzle : Array = source.match(/\.[xyzw]{1,4}/);
var maskmatch : String = swizzle ? swizzle[0] : null;
if (maskmatch) {
regmask = 0;
var cv : int;
var maskLength : uint = maskmatch.length;
for (var i : int = 1; i < maskLength; i++) {
cv = maskmatch.charCodeAt(i) - X_CHAR_CODE;
if (cv == -1) cv = 3;
regmask |= cv << ( ( i - 1 ) << 1 );
}
for ( ; i <= 4; i++ )
regmask |= cv << ( ( i - 1 ) << 1 );
// repeat last
} else {
regmask = 0xe4;
// id swizzle or mask
}
lowerCode = (regmask << 24) | index;
switch(strType) {
case "a":
type = VariableType.ATTRIBUTE;
break;
case "c":
type = VariableType.CONSTANT;
break;
case "t":
type = VariableType.TEMPORARY;
break;
case "o":
type = VariableType.OUTPUT;
break;
case "v":
type = VariableType.VARYING;
break;
case "i":
type = VariableType.INPUT;
break;
case "d":
type = VariableType.DEPTH;
break;
default :
throw new ArgumentError('Wrong source register type, must be "a" or "c" or "t" or "o" or "v" or "i" or "d", var = ' + source);
break;
}
upperCode = type;
if (isRel) {
relative = new RelativeVariable(relreg[0]);
lowerCode |= relative.lowerCode;
upperCode |= relative.upperCode;
isRelative = true;
}
}
override public function writeToByteArray(byteCode : ByteArray, newIndex : int, newType : int, offset : int = 0) : void {
if (relative == null) {
super.writeToByteArray(byteCode, newIndex, newType, offset);
} else {
byteCode.position = position + 2;
}
byteCode.position = position + offset + 4;
byteCode.writeByte(newType);
}
}
}
/**
* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
* If it is not possible or desirable to put the notice in a particular file, then You may include the notice in a location (such as a LICENSE file in a relevant directory) where a recipient would be likely to look for such a notice.
* You may add additional accurate notices of copyright ownership.
*
* It is desirable to notify that Covered Software was "Powered by AlternativaPlatform" with link to http://www.alternativaplatform.com/
* */
package alternativa.engine3d.materials.compiler {
import flash.utils.ByteArray;
/**
* @private
*/
public class SourceVariable extends Variable {
public var relative:RelativeVariable;
override public function get size():uint {
if (relative) {
return 0;
}
return super.size;
}
public function SourceVariable(source:String) {
var strType:String = String(source.match(/[catsoiv]/g)[0]);
var regmask:uint;
var relreg:Array = source.match(/\[.*\]/g);
var isRel:Boolean = relreg.length > 0;
if (isRel) {
source = source.replace(relreg[0], "0");
} else {
index = parseInt(source.match(/\d+/g)[0], 10);
}
var swizzle:Array = source.match(/\.[xyzw]{1,4}/);
var maskmatch:String = swizzle ? swizzle[0]:null;
if (maskmatch) {
regmask = 0;
var cv:int;
var maskLength:uint = maskmatch.length;
for (var i:int = 1; i < maskLength; i++) {
cv = maskmatch.charCodeAt(i) - X_CHAR_CODE;
if (cv == -1) cv = 3;
regmask |= cv << ( ( i - 1 ) << 1 );
}
for ( ; i <= 4; i++ )
regmask |= cv << ( ( i - 1 ) << 1 );
// repeat last
} else {
regmask = 0xe4;
// id swizzle or mask
}
lowerCode = (regmask << 24) | index;
switch(strType) {
case "a":
type = VariableType.ATTRIBUTE;
break;
case "c":
type = VariableType.CONSTANT;
break;
case "t":
type = VariableType.TEMPORARY;
break;
case "o":
type = VariableType.OUTPUT;
break;
case "v":
type = VariableType.VARYING;
break;
case "i":
type = VariableType.INPUT;
break;
default :
throw new ArgumentError('Wrong source register type, must be "a" or "c" or "t" or "o" or "v" or "i", var = ' + source);
break;
}
upperCode = type;
if (isRel) {
relative = new RelativeVariable(relreg[0]);
lowerCode |= relative.lowerCode;
upperCode |= relative.upperCode;
isRelative = true;
}
}
override public function writeToByteArray(byteCode:ByteArray, newIndex:int, newType:int, offset:int = 0):void {
if (relative == null) {
super.writeToByteArray(byteCode, newIndex, newType, offset);
} else {
byteCode.position = position + 2;
}
byteCode.position = position + offset + 4;
byteCode.writeByte(newType);
}
}
}