From 2606b0e14dcc8edf74342b2a034dbaddd63254fd Mon Sep 17 00:00:00 2001 From: Eric Helier Date: Mon, 19 Oct 2015 10:54:40 +0200 Subject: [PATCH] Support for AGAL2 and standard profiles --- CHANGELOG.txt | 6 ++- .../core/managers/AGALProgram3DCache.as | 9 ++++- src/away3d/core/managers/Stage3DProxy.as | 6 ++- src/away3d/core/pick/ShaderPicker.as | 8 ++-- .../core/render/BackgroundImageRenderer.as | 5 ++- src/away3d/core/render/PositionRenderer.as | 5 ++- src/away3d/filters/tasks/Filter3DTaskBase.as | 7 ++-- .../compilation/ShaderRegisterCache.as | 40 +++++++++++++++---- src/away3d/stereo/StereoRenderer.as | 5 ++- src/com/adobe/utils/AGALMiniAssembler.as | 30 +++++++++----- 10 files changed, 86 insertions(+), 35 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 10e4977f5..8a9331a8f 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -241,4 +241,8 @@ - Added useSmoothingGroups option in 3DS parser to allow smoothing on files with no smoothing group data - Fix for play method on animators to restart stopped animations when playing the same state - Fix to duration property for non-looping animations -- Updates to AWD and 3DS parser to allow class instance reuse on multiple assets. \ No newline at end of file +- Updates to AWD and 3DS parser to allow class instance reuse on multiple assets. + +4.1.6_AGAL2 +- Updated AGALMiniAssembler version to support agal v2 +- Support for multiple Stage3D Profiles (not only baseline) \ No newline at end of file diff --git a/src/away3d/core/managers/AGALProgram3DCache.as b/src/away3d/core/managers/AGALProgram3DCache.as index b13405ca9..6e1f9df90 100644 --- a/src/away3d/core/managers/AGALProgram3DCache.as +++ b/src/away3d/core/managers/AGALProgram3DCache.as @@ -15,6 +15,11 @@ package away3d.core.managers public class AGALProgram3DCache { + /** + * allow dynamic switching for AGALMiniAssembler version support + */ + public static var AGAL_VERSION:int = 1; + private static var _instances:Vector.; private var _stage3DProxy:Stage3DProxy; @@ -95,8 +100,8 @@ package away3d.core.managers ++_currentId; program = _stage3DProxy._context3D.createProgram(); - var vertexByteCode:ByteArray = new AGALMiniAssembler(Debug.active).assemble(Context3DProgramType.VERTEX, vertexCode); - var fragmentByteCode:ByteArray = new AGALMiniAssembler(Debug.active).assemble(Context3DProgramType.FRAGMENT, fragmentCode); + var vertexByteCode:ByteArray = new AGALMiniAssembler(Debug.active).assemble(Context3DProgramType.VERTEX, vertexCode, AGAL_VERSION); + var fragmentByteCode:ByteArray = new AGALMiniAssembler(Debug.active).assemble(Context3DProgramType.FRAGMENT, fragmentCode, AGAL_VERSION); program.upload(vertexByteCode, fragmentByteCode); diff --git a/src/away3d/core/managers/Stage3DProxy.as b/src/away3d/core/managers/Stage3DProxy.as index b2605019e..6afe47e04 100644 --- a/src/away3d/core/managers/Stage3DProxy.as +++ b/src/away3d/core/managers/Stage3DProxy.as @@ -38,6 +38,7 @@ package away3d.core.managers arcane var _stage3DIndex:int = -1; private var _usesSoftwareRendering:Boolean; + private var _supportsAgalv2:Boolean; private var _profile:String; private var _stage3D:Stage3D; private var _activeProgram3D:Program3D; @@ -520,7 +521,10 @@ package away3d.core.managers _context3D = _stage3D.context3D; _context3D.enableErrorChecking = Debug.active; - _usesSoftwareRendering = (_context3D.driverInfo.indexOf('Software') == 0); + var driverInfo:String = _context3D.driverInfo.toLowerCase(); + _usesSoftwareRendering = (driverInfo.indexOf('software') >= 0); + _supportsAgalv2 = (driverInfo.indexOf('standard') >= 0); + if (_supportsAgalv2) AGALProgram3DCache.AGAL_VERSION = 2; // Only configure back buffer if width and height have been set, // which they may not have been if View3D.render() has yet to be diff --git a/src/away3d/core/pick/ShaderPicker.as b/src/away3d/core/pick/ShaderPicker.as index 4fa388b7b..0828ea3f6 100644 --- a/src/away3d/core/pick/ShaderPicker.as +++ b/src/away3d/core/pick/ShaderPicker.as @@ -247,8 +247,8 @@ package away3d.core.pick "mov op, vt0 \n"; fragmentCode = "mov oc, fc0"; // write identifier - _objectProgram3D.upload(new AGALMiniAssembler().assemble(Context3DProgramType.VERTEX, vertexCode), - new AGALMiniAssembler().assemble(Context3DProgramType.FRAGMENT, fragmentCode)); + _objectProgram3D.upload(new AGALMiniAssembler().assemble(Context3DProgramType.VERTEX, vertexCode, AGALProgram3DCache.AGAL_VERSION), + new AGALMiniAssembler().assemble(Context3DProgramType.FRAGMENT, fragmentCode, AGALProgram3DCache.AGAL_VERSION)); } /** @@ -272,8 +272,8 @@ package away3d.core.pick "mov op, vt0 \n"; fragmentCode = "mov oc, v0"; // write identifier - _triangleProgram3D.upload(new AGALMiniAssembler().assemble(Context3DProgramType.VERTEX, vertexCode), - new AGALMiniAssembler().assemble(Context3DProgramType.FRAGMENT, fragmentCode)); + _triangleProgram3D.upload(new AGALMiniAssembler().assemble(Context3DProgramType.VERTEX, vertexCode, AGALProgram3DCache.AGAL_VERSION), + new AGALMiniAssembler().assemble(Context3DProgramType.FRAGMENT, fragmentCode, AGALProgram3DCache.AGAL_VERSION)); } /** diff --git a/src/away3d/core/render/BackgroundImageRenderer.as b/src/away3d/core/render/BackgroundImageRenderer.as index cf1ecf84a..c42c5ead5 100644 --- a/src/away3d/core/render/BackgroundImageRenderer.as +++ b/src/away3d/core/render/BackgroundImageRenderer.as @@ -1,5 +1,6 @@ package away3d.core.render { + import away3d.core.managers.AGALProgram3DCache; import away3d.core.managers.Stage3DProxy; import away3d.debug.Debug; import away3d.textures.Texture2DBase; @@ -115,8 +116,8 @@ package away3d.core.render _program3d = context.createProgram(); _indexBuffer = context.createIndexBuffer(6); _indexBuffer.uploadFromVector(Vector.([2, 1, 0, 3, 2, 0]), 0, 6); - _program3d.upload(new AGALMiniAssembler(Debug.active).assemble(Context3DProgramType.VERTEX, getVertexCode()), - new AGALMiniAssembler(Debug.active).assemble(Context3DProgramType.FRAGMENT, getFragmentCode()) + _program3d.upload(new AGALMiniAssembler(Debug.active).assemble(Context3DProgramType.VERTEX, getVertexCode(), AGALProgram3DCache.AGAL_VERSION), + new AGALMiniAssembler(Debug.active).assemble(Context3DProgramType.FRAGMENT, getFragmentCode(), AGALProgram3DCache.AGAL_VERSION) ); var w:Number = 2; diff --git a/src/away3d/core/render/PositionRenderer.as b/src/away3d/core/render/PositionRenderer.as index fd9a81418..0a58513a8 100644 --- a/src/away3d/core/render/PositionRenderer.as +++ b/src/away3d/core/render/PositionRenderer.as @@ -2,6 +2,7 @@ package away3d.core.render { import away3d.core.base.IRenderable; import away3d.core.data.RenderableListItem; + import away3d.core.managers.AGALProgram3DCache; import away3d.core.math.Matrix3DUtils; import away3d.core.traverse.EntityCollector; import away3d.debug.Debug; @@ -97,8 +98,8 @@ package away3d.core.render "mul v0, vt0, vt1.x \n"; fragmentCode = "mov oc, v0\n"; - _program3D.upload(new AGALMiniAssembler(Debug.active).assemble(Context3DProgramType.VERTEX, vertexCode), - new AGALMiniAssembler(Debug.active).assemble(Context3DProgramType.FRAGMENT, fragmentCode)); + _program3D.upload(new AGALMiniAssembler(Debug.active).assemble(Context3DProgramType.VERTEX, vertexCode, AGALProgram3DCache.AGAL_VERSION), + new AGALMiniAssembler(Debug.active).assemble(Context3DProgramType.FRAGMENT, fragmentCode, AGALProgram3DCache.AGAL_VERSION)); } } } diff --git a/src/away3d/filters/tasks/Filter3DTaskBase.as b/src/away3d/filters/tasks/Filter3DTaskBase.as index 1f997aefb..81b5e2c04 100644 --- a/src/away3d/filters/tasks/Filter3DTaskBase.as +++ b/src/away3d/filters/tasks/Filter3DTaskBase.as @@ -3,6 +3,7 @@ package away3d.filters.tasks { import away3d.cameras.Camera3D; + import away3d.core.managers.AGALProgram3DCache; import away3d.core.managers.Stage3DProxy; import away3d.debug.Debug; import away3d.errors.AbstractMethodError; @@ -12,10 +13,8 @@ package away3d.filters.tasks import flash.display3D.Context3D; import flash.display3D.Context3DProgramType; - import flash.display3D.Context3DTextureFormat; import flash.display3D.Program3D; - import flash.display3D.textures.Texture; public class Filter3DTaskBase @@ -129,8 +128,8 @@ package away3d.filters.tasks _program3D.dispose(); _program3DContext = stage.context3D; _program3D = _program3DContext.createProgram(); - _program3D.upload(new AGALMiniAssembler(Debug.active).assemble(Context3DProgramType.VERTEX, getVertexCode()), - new AGALMiniAssembler(Debug.active).assemble(Context3DProgramType.FRAGMENT, getFragmentCode())); + _program3D.upload(new AGALMiniAssembler(Debug.active).assemble(Context3DProgramType.VERTEX, getVertexCode(), AGALProgram3DCache.AGAL_VERSION), + new AGALMiniAssembler(Debug.active).assemble(Context3DProgramType.FRAGMENT, getFragmentCode(), AGALProgram3DCache.AGAL_VERSION)); _program3DInvalid = false; } diff --git a/src/away3d/materials/compilation/ShaderRegisterCache.as b/src/away3d/materials/compilation/ShaderRegisterCache.as index addb07bf8..b0ab53829 100644 --- a/src/away3d/materials/compilation/ShaderRegisterCache.as +++ b/src/away3d/materials/compilation/ShaderRegisterCache.as @@ -1,11 +1,36 @@ package away3d.materials.compilation { + import away3d.core.managers.AGALProgram3DCache; /** * ShaderRegister Cache provides the usage management system for all registers during shading compilation. */ public class ShaderRegisterCache { + /** + * Limits for temporary register (vertex and fragment) + */ + private static const TEMP_LIMITS:Array = [ + 8, // AGAL1 + 26 // AGAL2 + ]; + + /** + * Limits for fragment constants + */ + private static const FRAG_CONSTANTS_LIMITS:Array = [ + 28, // AGAL1 + 64 // AGAL2 + ]; + + /** + * Limits for vertex constants + */ + private static const VERT_CONSTANTS_LIMITS:Array = [ + 128, // AGAL1 + 250 // AGAL2 + ]; + private var _fragmentTempCache:RegisterPool; private var _vertexTempCache:RegisterPool; private var _varyingCache:RegisterPool; @@ -42,13 +67,13 @@ package away3d.materials.compilation */ public function reset():void { - _fragmentTempCache = new RegisterPool("ft", 8, false); - _vertexTempCache = new RegisterPool("vt", 8, false); - _varyingCache = new RegisterPool("v", 8); - _textureCache = new RegisterPool("fs", 8); - _vertexAttributesCache = new RegisterPool("va", 8); - _fragmentConstantsCache = new RegisterPool("fc", 28); - _vertexConstantsCache = new RegisterPool("vc", 128); + _fragmentTempCache = new RegisterPool("ft", TEMP_LIMITS[AGALProgram3DCache.AGAL_VERSION-1], false); + _vertexTempCache = new RegisterPool("vt", TEMP_LIMITS[AGALProgram3DCache.AGAL_VERSION-1], false); + _varyingCache = new RegisterPool("v", 8); // 8 also in Standard Constrained - 10 in Standard + _textureCache = new RegisterPool("fs", 8); // 8 also in Standard Constrained - 16 in Standard + _vertexAttributesCache = new RegisterPool("va", 8); // 16 in AGAL3 Support + _fragmentConstantsCache = new RegisterPool("fc", FRAG_CONSTANTS_LIMITS[AGALProgram3DCache.AGAL_VERSION-1]); + _vertexConstantsCache = new RegisterPool("vc", VERT_CONSTANTS_LIMITS[AGALProgram3DCache.AGAL_VERSION-1]); _fragmentOutputRegister = new ShaderRegisterElement("oc", -1); _vertexOutputRegister = new ShaderRegisterElement("op", -1); _numUsedVertexConstants = 0; @@ -65,7 +90,6 @@ package away3d.materials.compilation getFreeVarying(); for (i = 0; i < _fragmentConstantOffset; ++i) getFreeFragmentConstant(); - } /** diff --git a/src/away3d/stereo/StereoRenderer.as b/src/away3d/stereo/StereoRenderer.as index 18844eac1..3ac313c53 100644 --- a/src/away3d/stereo/StereoRenderer.as +++ b/src/away3d/stereo/StereoRenderer.as @@ -1,5 +1,6 @@ package away3d.stereo { + import away3d.core.managers.AGALProgram3DCache; import away3d.core.managers.RTTBufferManager; import away3d.core.managers.Stage3DProxy; import away3d.debug.Debug; @@ -135,8 +136,8 @@ package away3d.stereo assembler = new AGALMiniAssembler(Debug.active); _program3D = stage3DProxy.context3D.createProgram(); - _program3D.upload(assembler.assemble(Context3DProgramType.VERTEX, vertexCode), - assembler.assemble(Context3DProgramType.FRAGMENT, fragmentCode)); + _program3D.upload(assembler.assemble(Context3DProgramType.VERTEX, vertexCode, AGALProgram3DCache.AGAL_VERSION), + assembler.assemble(Context3DProgramType.FRAGMENT, fragmentCode, AGALProgram3DCache.AGAL_VERSION)); _program3DInvalid = false; } diff --git a/src/com/adobe/utils/AGALMiniAssembler.as b/src/com/adobe/utils/AGALMiniAssembler.as index 955e5a2e0..ca511f44a 100644 --- a/src/com/adobe/utils/AGALMiniAssembler.as +++ b/src/com/adobe/utils/AGALMiniAssembler.as @@ -1,5 +1,5 @@ /* -Copyright (c) 2011, Adobe Systems Incorporated +Copyright (c) 2015, Adobe Systems Incorporated All rights reserved. Redistribution and use in source and binary forms, with or without @@ -109,7 +109,7 @@ package com.adobe.utils initregmap(version, ignorelimits); var lines:Array = source.replace( /[\f\n\r\v]+/g, "\n" ).split( "\n" ); - //var nest:int = 0; + var nest:int = 0; var nops:int = 0; var i:int; var lng:int = lines.length; @@ -456,13 +456,13 @@ package com.adobe.utils private function initregmap ( version:uint, ignorelimits:Boolean ) : void { // version changes limits - REGMAP[ VA ] = new Register( VA, "vertex attribute", 0x0, ignorelimits?1024:7, REG_VERT | REG_READ ); - REGMAP[ VC ] = new Register( VC, "vertex constant", 0x1, ignorelimits?1024:(version==1?127:250), REG_VERT | REG_READ ); - REGMAP[ VT ] = new Register( VT, "vertex temporary", 0x2, ignorelimits?1024:(version==1?7:27), REG_VERT | REG_WRITE | REG_READ ); + REGMAP[ VA ] = new Register( VA, "vertex attribute", 0x0, ignorelimits?1024:((version==1||version==2)?7:15), REG_VERT | REG_READ ); + REGMAP[ VC ] = new Register( VC, "vertex constant", 0x1, ignorelimits?1024:(version==1?127:249), REG_VERT | REG_READ ); + REGMAP[ VT ] = new Register( VT, "vertex temporary", 0x2, ignorelimits?1024:(version==1?7:25), REG_VERT | REG_WRITE | REG_READ ); REGMAP[ VO ] = new Register( VO, "vertex output", 0x3, ignorelimits?1024:0, REG_VERT | REG_WRITE ); - REGMAP[ VI ] = new Register( VI, "varying", 0x4, ignorelimits?1024:(version==1?7:11), REG_VERT | REG_FRAG | REG_READ | REG_WRITE ); - REGMAP[ FC ] = new Register( FC, "fragment constant", 0x1, ignorelimits?1024:(version==1?27:63), REG_FRAG | REG_READ ); - REGMAP[ FT ] = new Register( FT, "fragment temporary", 0x2, ignorelimits?1024:(version==1?7:27), REG_FRAG | REG_WRITE | REG_READ ); + REGMAP[ VI ] = new Register( VI, "varying", 0x4, ignorelimits?1024:(version==1?7:9), REG_VERT | REG_FRAG | REG_READ | REG_WRITE ); + REGMAP[ FC ] = new Register( FC, "fragment constant", 0x1, ignorelimits?1024:(version==1?27:((version==2)?63:199)), REG_FRAG | REG_READ ); + REGMAP[ FT ] = new Register( FT, "fragment temporary", 0x2, ignorelimits?1024:(version==1?7:25), REG_FRAG | REG_WRITE | REG_READ ); REGMAP[ FS ] = new Register( FS, "texture sampler", 0x5, ignorelimits?1024:7, REG_FRAG | REG_READ ); REGMAP[ FO ] = new Register( FO, "fragment output", 0x3, ignorelimits?1024:(version==1?0:3), REG_FRAG | REG_WRITE ); REGMAP[ FD ] = new Register( FD, "fragment depth output",0x6, ignorelimits?1024:(version==1?-1:0), REG_FRAG | REG_WRITE ); @@ -516,7 +516,7 @@ package com.adobe.utils OPMAP[ ELS ] = new OpCode( ELS, 0, 0x20, OP_NO_DEST | OP_VERSION2 | OP_INCNEST | OP_DECNEST | OP_SCALAR ); OPMAP[ EIF ] = new OpCode( EIF, 0, 0x21, OP_NO_DEST | OP_VERSION2 | OP_DECNEST | OP_SCALAR ); // space - OPMAP[ TED ] = new OpCode( TED, 3, 0x26, OP_FRAG_ONLY | OP_SPECIAL_TEX | OP_VERSION2); + //OPMAP[ TED ] = new OpCode( TED, 3, 0x26, OP_FRAG_ONLY | OP_SPECIAL_TEX | OP_VERSION2); //ted is not available in AGAL2 OPMAP[ KIL ] = new OpCode( KIL, 1, 0x27, OP_NO_DEST | OP_FRAG_ONLY ); OPMAP[ TEX ] = new OpCode( TEX, 3, 0x28, OP_FRAG_ONLY | OP_SPECIAL_TEX ); OPMAP[ SGE ] = new OpCode( SGE, 3, 0x29, 0 ); @@ -539,12 +539,18 @@ package com.adobe.utils SAMPLEMAP[ NOMIP ] = new Sampler( NOMIP, SAMPLER_MIPMAP_SHIFT, 0 ); SAMPLEMAP[ NEAREST ] = new Sampler( NEAREST, SAMPLER_FILTER_SHIFT, 0 ); SAMPLEMAP[ LINEAR ] = new Sampler( LINEAR, SAMPLER_FILTER_SHIFT, 1 ); + SAMPLEMAP[ ANISOTROPIC2X ] = new Sampler( ANISOTROPIC2X, SAMPLER_FILTER_SHIFT, 2 ); + SAMPLEMAP[ ANISOTROPIC4X ] = new Sampler( ANISOTROPIC4X, SAMPLER_FILTER_SHIFT, 3 ); + SAMPLEMAP[ ANISOTROPIC8X ] = new Sampler( ANISOTROPIC8X, SAMPLER_FILTER_SHIFT, 4 ); + SAMPLEMAP[ ANISOTROPIC16X ] = new Sampler( ANISOTROPIC16X, SAMPLER_FILTER_SHIFT,5 ); SAMPLEMAP[ CENTROID ] = new Sampler( CENTROID, SAMPLER_SPECIAL_SHIFT, 1 << 0 ); SAMPLEMAP[ SINGLE ] = new Sampler( SINGLE, SAMPLER_SPECIAL_SHIFT, 1 << 1 ); SAMPLEMAP[ IGNORESAMPLER ] = new Sampler( IGNORESAMPLER, SAMPLER_SPECIAL_SHIFT, 1 << 2 ); SAMPLEMAP[ REPEAT ] = new Sampler( REPEAT, SAMPLER_REPEAT_SHIFT, 1 ); SAMPLEMAP[ WRAP ] = new Sampler( WRAP, SAMPLER_REPEAT_SHIFT, 1 ); SAMPLEMAP[ CLAMP ] = new Sampler( CLAMP, SAMPLER_REPEAT_SHIFT, 0 ); + SAMPLEMAP[ CLAMP_U_REPEAT_V ] = new Sampler( CLAMP_U_REPEAT_V, SAMPLER_REPEAT_SHIFT, 2 ); + SAMPLEMAP[ REPEAT_U_CLAMP_V ] = new Sampler( REPEAT_U_CLAMP_V, SAMPLER_REPEAT_SHIFT, 3 ); } // ====================================================================== @@ -651,12 +657,18 @@ package com.adobe.utils private static const NOMIP:String = "nomip"; private static const NEAREST:String = "nearest"; private static const LINEAR:String = "linear"; + private static const ANISOTROPIC2X:String = "anisotropic2x"; //Introduced by Flash 14 + private static const ANISOTROPIC4X:String = "anisotropic4x"; //Introduced by Flash 14 + private static const ANISOTROPIC8X:String = "anisotropic8x"; //Introduced by Flash 14 + private static const ANISOTROPIC16X:String = "anisotropic16x"; //Introduced by Flash 14 private static const CENTROID:String = "centroid"; private static const SINGLE:String = "single"; private static const IGNORESAMPLER:String = "ignoresampler"; private static const REPEAT:String = "repeat"; private static const WRAP:String = "wrap"; private static const CLAMP:String = "clamp"; + private static const REPEAT_U_CLAMP_V:String = "repeat_u_clamp_v"; //Introduced by Flash 13 + private static const CLAMP_U_REPEAT_V:String = "clamp_u_repeat_v"; //Introduced by Flash 13 private static const RGBA:String = "rgba"; private static const DXT1:String = "dxt1"; private static const DXT5:String = "dxt5";