Measures how many read/writes per second your hardware can do on a 512x512 texture.
(I heard that setRenderToTexture is slow but I don't have a GPU to test on)
/**
* Copyright yonatan ( http://wonderfl.net/user/yonatan )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/te3G
*/
// forked from wh0's AGAL feedback
package {
import flash.display.*;
import flash.display3D.*;
import flash.display3D.textures.*;
import flash.events.*;
import flash.geom.*;
import flash.utils.*;
import com.bit101.components.*;
import com.adobe.utils.AGALMiniAssembler;
public class FlashTest extends Sprite {
private var stage3D:Stage3D;
private var context3D:Context3D;
private var indexBuffer3D:IndexBuffer3D;
private var fs_in:Texture;
private var fs_out:Texture;
public function FlashTest() {
loaderInfo.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR, function (e:UncaughtErrorEvent):void { Wonderfl.log(e.error); } );
if (stage.stage3Ds.length == 0) throw 'no stage3D';
// Obtain a 3D rendering context by requesting one from an instance of Stage3D.
stage3D = stage.stage3Ds[0];
stage3D.addEventListener(Event.CONTEXT3D_CREATE, context3DCreate);
stage3D.requestContext3D();
}
private function context3DCreate(e:Event):void {
// The runtime dispatches this when the requested context is ready.
context3D = stage3D.context3D;
context3D.configureBackBuffer(stage.stageWidth, stage.stageHeight, 0, false);
prepareTestProgram();
//addEventListener(Event.ENTER_FRAME, draw);
draw();
}
private function prepareTestProgram():void {
// The rendering pipeline consists of two shader programs.
// We can assemble these programs from AGAL strings using a library from Adobe.
// This vertex shader returns the xyz coordinates and stores the uv coordinates in v0.
var vsa:AGALMiniAssembler = new AGALMiniAssembler();
vsa.assemble(Context3DProgramType.VERTEX, <![CDATA[
mov op, va0 // return xyz coords
mov v0, va1 // store uv in v0
]]>);
// This fragment shader reads a pixel from the input texture and returns it
var fsa:AGALMiniAssembler = new AGALMiniAssembler();
fsa.assemble(Context3DProgramType.FRAGMENT, <![CDATA[
tex oc, v0, fs0 <nearest> // sample input at uv coords
]]>);
var p:Program3D = context3D.createProgram();
p.upload(vsa.agalcode, fsa.agalcode);
context3D.setProgram(p);
// Define are the input vertices. It's a triangle that covers the entire viewport.
var va:VertexBuffer3D = context3D.createVertexBuffer(3, 5);
va.uploadFromVector(new <Number> [
// x y z u v
-1, 1, 0, 0, 0,
-1, -3, 0, 0, 2,
3, 1, 0, 2, 0
], 0, 3);
// Store the xyz coordinates (columns 0-2) in va0.
context3D.setVertexBufferAt(0, va, 0, Context3DVertexBufferFormat.FLOAT_3);
// Store the uv coordinates (columns 3-4) in va1.
context3D.setVertexBufferAt(1, va, 3, Context3DVertexBufferFormat.FLOAT_2);
// Create the seed image.
var bd:BitmapData = new BitmapData(512, 512, true, 0x00000000);
bd.perlinNoise(512, 512, 6, 9988, false, true);
// Move the generated image to a texture.
fs_in = context3D.createTexture(512, 512, Context3DTextureFormat.BGRA, true);
fs_in.uploadFromBitmapData(bd);
// Put the texture in fs0.
context3D.setTextureAt(0, fs_in);
// Allocate a buffer for the result.
fs_out = context3D.createTexture(512, 512, Context3DTextureFormat.BGRA, true);
// Create a rotation matrix to play with the colors.
var m:Matrix3D = new Matrix3D();
m.appendRotation(2, new Vector3D(1, 1, 1));
// Put the matrix in fc0-fc3. A 4x4 matrix occupies 4 adjacent registers.
context3D.setProgramConstantsFromMatrix(Context3DProgramType.FRAGMENT, 0, m, true);
// Create an index buffer that defines a mesh over the vertices. Here, it's a single triangle.
indexBuffer3D = context3D.createIndexBuffer(3);
indexBuffer3D.uploadFromVector(new <uint> [0, 1, 2], 0, 3);
}
private function draw():void {
var cnt:int = 0;
var start:Number = getTimer();
var seconds:int = 4;
while(getTimer()-start < seconds*1000) {
// Now, we draw to the output texture.
context3D.setRenderToTexture(fs_out);
// Since we've called present and switched render destinations, we must call clear again.
context3D.clear();
// Draw to the texture.
context3D.drawTriangles(indexBuffer3D);
// Swap the texture pointers.
var temp:Texture = fs_in;
fs_in = fs_out;
fs_out = temp;
// Put the new input buffer in fs0.
context3D.setTextureAt(0, fs_in);
cnt++;
}
// First, pick where to draw. Here, we draw to the back buffer.
context3D.setRenderToBackBuffer();
// They require that you clear the buffer before you draw anything.
context3D.clear();
// Call drawTriangles to do the work.
context3D.drawTriangles(indexBuffer3D);
// Call present to swap the back buffer and display buffer. This shows the result on the stage.
context3D.present();
StatsCollectorLoader.init(stage, {driver: context3D.driverInfo, passes: cnt/seconds});
//with(new Label(this, 0, 200, context3D.driverInfo + " - " + cnt/seconds + " passes/sec.")){ scaleX=scaleY=2; x=(465-width)/4; }
}
}
}
import flash.display.*;
import flash.net.*;
import flash.system.*;
class StatsCollectorLoader {
private static const URL:String = "http://swf.wonderfl.net/swf/usercode/e/e1/e154/e154bcc18ae75cf6c70f29a108e6af3eba3055d6.swf";
public static function init(stage:Stage, results:Object): void {
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener("complete", function(e:*):void { loader.content["init"](stage, results); });
loader.load(new URLRequest(URL), new LoaderContext(true));
}
}