2
0

LogDriver.hx 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. package h3d.impl;
  2. import h3d.impl.Driver;
  3. class LogDriver extends Driver {
  4. var d : Driver;
  5. var loggedShaders = new Map<Int,Bool>();
  6. var currentShader : hxsl.RuntimeShader;
  7. public var logLines : Array<String> = null;
  8. public function new( driver : Driver ) {
  9. this.d = driver;
  10. logEnable = true;
  11. driver.logEnable = true;
  12. }
  13. override function logImpl( str : String ) {
  14. if( logLines == null )
  15. d.logImpl(str);
  16. else
  17. logLines.push(str);
  18. }
  19. override function hasFeature( f : Feature ) {
  20. return d.hasFeature(f);
  21. }
  22. override function isSupportedFormat( fmt : h3d.mat.Data.TextureFormat ) {
  23. return d.isSupportedFormat(fmt);
  24. }
  25. override function isDisposed() {
  26. return d.isDisposed();
  27. }
  28. override function dispose() {
  29. log('Dispose');
  30. d.dispose();
  31. }
  32. override function begin( frame : Int ) {
  33. log('Begin $frame');
  34. d.begin(frame);
  35. }
  36. override function clear( ?color : h3d.Vector, ?depth : Float, ?stencil : Int ) {
  37. log('Clear color=$color depth=$depth stencil=$stencil');
  38. d.clear(color, depth, stencil);
  39. }
  40. override function captureRenderBuffer( pixels : hxd.Pixels ) {
  41. log('CaptureRenderBuffer ${pixels.width}x${pixels.height}');
  42. d.captureRenderBuffer(pixels);
  43. }
  44. override function getDriverName( details : Bool ) {
  45. return d.getDriverName(details);
  46. }
  47. override function init( onCreate : Bool -> Void, forceSoftware = false ) {
  48. log('Init');
  49. d.init(function(b) {
  50. log('OnCreate $b');
  51. onCreate(b);
  52. },forceSoftware);
  53. }
  54. override function resize( width : Int, height : Int ) {
  55. log('Resize $width x $height');
  56. d.resize(width, height);
  57. }
  58. override function selectShader( shader : hxsl.RuntimeShader ) {
  59. log('Select shader #${shader.id}');
  60. currentShader = shader;
  61. var ret = d.selectShader(shader);
  62. if( !loggedShaders.get(shader.id) ) {
  63. function fmt( shader : hxsl.RuntimeShader.RuntimeShaderData ) {
  64. var str = hxsl.Printer.shaderToString(shader.data);
  65. str = ~/((fragment)|(vertex))Globals\[([0-9]+)\](.[xyz]+)?/g.map(str, function(r) {
  66. var name = null;
  67. var cid = Std.parseInt(r.matched(4)) << 2;
  68. var swiz = r.matched(5);
  69. if( swiz != null ) {
  70. var d = swiz.charCodeAt(1) - 'x'.code;
  71. cid += d;
  72. swiz = "." + [for( i in 1...swiz.length ) String.fromCharCode(swiz.charCodeAt(i) - d)].join("");
  73. }
  74. var g = shader.globals;
  75. while( g != null ) {
  76. if( g.path == "__consts__" && cid >= g.pos && cid < g.pos + (switch(g.type) { case TArray(TFloat, SConst(n)): n; default: 0; } ) && swiz == ".x" ) {
  77. swiz = null;
  78. name = "" + shader.consts[cid - g.pos];
  79. break;
  80. }
  81. if( g.pos == cid ) {
  82. name = g.path;
  83. break;
  84. }
  85. g = g.next;
  86. }
  87. if( name == null )
  88. return r.matched(0);
  89. if( swiz != null ) name += swiz;
  90. return name;
  91. });
  92. str = ~/((fragment)|(vertex))Params\[([0-9]+)\](.[xyz]+)?/g.map(str, function(r) {
  93. var name = null;
  94. var cid = Std.parseInt(r.matched(4)) << 2;
  95. var swiz = r.matched(5);
  96. if( swiz != null ) {
  97. var d = swiz.charCodeAt(1) - 'x'.code;
  98. cid += d;
  99. swiz = "." + [for( i in 1...swiz.length ) String.fromCharCode(swiz.charCodeAt(i) - d)].join("");
  100. }
  101. var p = shader.params;
  102. while( p != null ) {
  103. if( p.pos == cid ) {
  104. name = p.name;
  105. break;
  106. }
  107. p = p.next;
  108. }
  109. if( name == null )
  110. return r.matched(0);
  111. if( swiz != null ) name += swiz;
  112. return name;
  113. });
  114. str = ~/((fragment)|(vertex))Textures\[([0-9]+)\]/g.map(str, function(r) {
  115. var name = null;
  116. var cid = Std.parseInt(r.matched(4));
  117. var t = shader.textures2D;
  118. while( t != null ) {
  119. if( t.pos == cid )
  120. return t.name;
  121. t = t.next;
  122. }
  123. return r.matched(0);
  124. });
  125. str = ~/((fragment)|(vertex))TexturesCube\[([0-9]+)\]/g.map(str, function(r) {
  126. var name = null;
  127. var cid = Std.parseInt(r.matched(4));
  128. var t = shader.texturesCube;
  129. while( t != null ) {
  130. if( t.pos == cid )
  131. return t.name;
  132. t = t.next;
  133. }
  134. return r.matched(0);
  135. });
  136. return str;
  137. }
  138. var str = fmt(shader.vertex) + "\n" + fmt(shader.fragment);
  139. log('');
  140. log('HXSL=');
  141. log("\t" + str.split("\n").join("\n\t"));
  142. var str = getNativeShaderCode(shader);
  143. if( str != null ) {
  144. log('NATIVE=');
  145. log("\t" + str.split("\n").join("\n\t"));
  146. }
  147. log('');
  148. loggedShaders.set(shader.id, true);
  149. }
  150. return ret;
  151. }
  152. override function getNativeShaderCode( shader ) {
  153. return d.getNativeShaderCode(shader);
  154. }
  155. override function selectMaterial( pass : h3d.mat.Pass ) {
  156. log('Select Material Cull=${pass.culling} depth=${pass.depthTest}${pass.depthWrite ? "" : " nowrite"} blend=${pass.blendSrc},${pass.blendDst} color=${pass.colorMask}');
  157. d.selectMaterial(pass);
  158. }
  159. function sizeOf( t : hxsl.Ast.Type ) {
  160. return switch( t ) {
  161. case TVoid: 0;
  162. case TInt, TFloat: 1;
  163. case TVec(n, _): n;
  164. case TMat4: 16;
  165. case TMat3: 9;
  166. case TMat3x4: 12;
  167. case TArray(t, SConst(n)): sizeOf(t) * n;
  168. default: throw "assert " + t;
  169. }
  170. }
  171. override function uploadShaderBuffers( buffers : h3d.shader.Buffers, which : h3d.shader.Buffers.BufferKind ) {
  172. switch( which ) {
  173. case Globals:
  174. inline function logVars( s : hxsl.RuntimeShader.RuntimeShaderData, buf : h3d.shader.Buffers.ShaderBuffers ) {
  175. if( s.globalsSize == 0 ) return;
  176. log('Upload ' + (s.vertex?"vertex":"fragment") + " globals");
  177. var g = s.globals;
  178. while( g != null ) {
  179. log('\t@${g.pos} ' + g.path + '=' + [for( i in 0...sizeOf(g.type) ) hxd.Math.fmt(buf.globals #if hl .toData() #end[g.pos + i])]);
  180. g = g.next;
  181. }
  182. }
  183. logVars(currentShader.vertex, buffers.vertex);
  184. logVars(currentShader.fragment, buffers.fragment);
  185. case Params:
  186. inline function logVars( s : hxsl.RuntimeShader.RuntimeShaderData, buf : h3d.shader.Buffers.ShaderBuffers ) {
  187. if( s.paramsSize == 0 ) return;
  188. log('Upload ' + (s.vertex?"vertex":"fragment") + " params");
  189. var p = s.params;
  190. while( p != null ) {
  191. var pos = p.pos;
  192. #if flash
  193. pos += s.globalsSize * 4;
  194. #end
  195. log('\t@$pos ' + p.name + '=' + [for( i in 0...sizeOf(p.type) ) hxd.Math.fmt(buf.params #if hl .toData() #end[p.pos + i])]);
  196. p = p.next;
  197. }
  198. }
  199. logVars(currentShader.vertex, buffers.vertex);
  200. logVars(currentShader.fragment, buffers.fragment);
  201. case Textures:
  202. inline function logVars( s : hxsl.RuntimeShader.RuntimeShaderData, buf : h3d.shader.Buffers.ShaderBuffers ) {
  203. var t = s.textures2D;
  204. while( t != null ) {
  205. log('Set ${s.vertex ? "Vertex" : "Fragment"} Texture@${t.pos} ' + t.name+"=" + textureInfos(buf.tex,t.pos));
  206. t = t.next;
  207. }
  208. t = s.texturesCube;
  209. while( t != null ) {
  210. log('Set ${s.vertex ? "Vertex" : "Fragment"} TextureCube@${t.pos} ' + t.name+"=" + textureInfos(buf.tex,t.pos + s.textures2DCount));
  211. t = t.next;
  212. }
  213. }
  214. logVars(currentShader.vertex, buffers.vertex);
  215. logVars(currentShader.fragment, buffers.fragment);
  216. }
  217. d.uploadShaderBuffers(buffers, which);
  218. }
  219. function textureInfos( buf : haxe.ds.Vector<h3d.mat.Texture>, tid : Int ) {
  220. if( tid < 0 || tid >= buf.length )
  221. return 'OUT OF BOUNDS';
  222. var t = buf[tid];
  223. if( t == null )
  224. return 'NULL';
  225. var inf = '' + t;
  226. if( t.wrap != Clamp )
  227. inf += " wrap=" + t.wrap;
  228. if( t.mipMap != None )
  229. inf += " mip=" + t.mipMap;
  230. return inf;
  231. }
  232. override function getShaderInputNames() : Array<String> {
  233. return d.getShaderInputNames();
  234. }
  235. override function selectBuffer( buffer : Buffer ) {
  236. log('SelectBuffer');
  237. d.selectBuffer(buffer);
  238. }
  239. override function selectMultiBuffers( buffers : Buffer.BufferOffset ) {
  240. log('SelectMultiBuffers');
  241. d.selectMultiBuffers(buffers);
  242. }
  243. override function draw( ibuf : IndexBuffer, startIndex : Int, ntriangles : Int ) {
  244. log('Draw $ntriangles');
  245. d.draw(ibuf, startIndex, ntriangles);
  246. }
  247. override function setRenderZone( x : Int, y : Int, width : Int, height : Int ) {
  248. log('SetRenderZone [$x $y $width $height]');
  249. d.setRenderZone(x, y, width, height);
  250. }
  251. override function setRenderTarget( tex : Null<h3d.mat.Texture>, face = 0, mipMap = 0 ) {
  252. log('SetRenderTarget $tex $face $mipMap');
  253. d.setRenderTarget(tex, face);
  254. }
  255. override function setRenderTargets( textures : Array<h3d.mat.Texture> ) {
  256. log('SetRenderTargets $textures');
  257. d.setRenderTargets(textures);
  258. }
  259. override function present() {
  260. log('Present');
  261. d.present();
  262. }
  263. override function setDebug( b : Bool ) {
  264. log('SetDebug $b');
  265. d.setDebug(b);
  266. }
  267. override function allocTexture( t : h3d.mat.Texture ) : Texture {
  268. log('AllocTexture $t');
  269. return d.allocTexture(t);
  270. }
  271. override function allocIndexes( count : Int ) : IndexBuffer {
  272. log('AllocIndexes $count');
  273. return d.allocIndexes(count);
  274. }
  275. override function allocVertexes( m : ManagedBuffer ) : VertexBuffer {
  276. log('AllocVertexes size=${m.size} stride=${m.stride}');
  277. return d.allocVertexes(m);
  278. }
  279. override function disposeTexture( t : h3d.mat.Texture ) {
  280. log('Dispose texture');
  281. d.disposeTexture(t);
  282. }
  283. override function disposeIndexes( i : IndexBuffer ) {
  284. log('DisposeIndexes');
  285. d.disposeIndexes(i);
  286. }
  287. override function disposeVertexes( v : VertexBuffer ) {
  288. log('DisposeIndexes');
  289. d.disposeVertexes(v);
  290. }
  291. override function uploadIndexBuffer( i : IndexBuffer, startIndice : Int, indiceCount : Int, buf : hxd.IndexBuffer, bufPos : Int ) {
  292. log('UploadIndexBuffer');
  293. d.uploadIndexBuffer(i, startIndice, indiceCount, buf, bufPos);
  294. }
  295. override function uploadIndexBytes( i : IndexBuffer, startIndice : Int, indiceCount : Int, buf : haxe.io.Bytes , bufPos : Int ) {
  296. log('UploadIndexBytes');
  297. d.uploadIndexBytes(i, startIndice, indiceCount, buf, bufPos);
  298. }
  299. override function uploadVertexBuffer( v : VertexBuffer, startVertex : Int, vertexCount : Int, buf : hxd.FloatBuffer, bufPos : Int ) {
  300. log('UploadVertexBuffer');
  301. d.uploadVertexBuffer(v, startVertex, vertexCount, buf, bufPos);
  302. }
  303. override function uploadVertexBytes( v : VertexBuffer, startVertex : Int, vertexCount : Int, buf : haxe.io.Bytes, bufPos : Int ) {
  304. log('UploadVertexBytes');
  305. d.uploadVertexBytes(v, startVertex, vertexCount, buf, bufPos);
  306. }
  307. override function uploadTextureBitmap( t : h3d.mat.Texture, bmp : hxd.BitmapData, mipLevel : Int, side : Int ) {
  308. log('UploadTextureBitmap $t mip=$mipLevel side=$side');
  309. d.uploadTextureBitmap(t, bmp, mipLevel, side);
  310. }
  311. override function uploadTexturePixels( t : h3d.mat.Texture, pixels : hxd.Pixels, mipLevel : Int, side : Int ) {
  312. log('UploadTexturePixels $t mip=$mipLevel side=$side');
  313. d.uploadTexturePixels(t, pixels, mipLevel, side);
  314. }
  315. public static function debug( f : Void -> Void ) {
  316. #if !debug
  317. throw "Requires -debug";
  318. #end
  319. var engine = h3d.Engine.getCurrent();
  320. var driver = engine.driver;
  321. var old = driver.logEnable;
  322. var log = new h3d.impl.LogDriver(driver);
  323. engine.setDriver(log);
  324. f();
  325. driver.logEnable = old;
  326. engine.setDriver(driver);
  327. }
  328. }