Buffer.hx 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. package h3d;
  2. enum BufferFlag {
  3. /**
  4. Indicate that the buffer content will be often modified.
  5. **/
  6. Dynamic;
  7. /**
  8. Used internaly
  9. **/
  10. NoAlloc;
  11. /**
  12. Used for shader input buffer
  13. **/
  14. UniformBuffer;
  15. /**
  16. Can be written
  17. **/
  18. ReadWriteBuffer;
  19. /**
  20. Used as index buffer
  21. **/
  22. IndexBuffer;
  23. }
  24. @:allow(h3d.impl.MemoryManager)
  25. class Buffer {
  26. public static var GUID = 0;
  27. public var id : Int;
  28. var allocPos : hxd.impl.AllocPos;
  29. var engine : h3d.Engine;
  30. var lastFrame : Int;
  31. @:allow(h3d.impl.Driver) var vbuf : h3d.impl.Driver.GPUBuffer;
  32. public var vertices(default,null) : Int;
  33. public var format(default,null) : hxd.BufferFormat;
  34. public var flags(default, null) : haxe.EnumFlags<BufferFlag>;
  35. public function new(vertices, format : hxd.BufferFormat, ?flags : Array<BufferFlag> ) {
  36. id = GUID++;
  37. this.vertices = vertices;
  38. this.format = format;
  39. this.flags = new haxe.EnumFlags();
  40. this.allocPos = hxd.impl.AllocPos.make();
  41. if( flags != null )
  42. for( f in flags )
  43. this.flags.set(f);
  44. engine = h3d.Engine.getCurrent();
  45. if( !this.flags.has(NoAlloc) )
  46. @:privateAccess engine.mem.allocBuffer(this);
  47. }
  48. public inline function getMemSize() {
  49. return vertices * format.strideBytes;
  50. }
  51. public inline function isDisposed() {
  52. return vbuf == null;
  53. }
  54. public function dispose() {
  55. if( vbuf != null ) {
  56. @:privateAccess engine.mem.freeBuffer(this);
  57. vbuf = null;
  58. }
  59. }
  60. public function uploadFloats( buf : hxd.FloatBuffer, bufPos : Int, vertices : Int, startVertice = 0 ) {
  61. if( startVertice < 0 || vertices < 0 || startVertice + vertices > this.vertices )
  62. throw "Invalid vertices count";
  63. if( vertices == 0 )
  64. return;
  65. if( format.hasLowPrecision ) {
  66. var bytes = haxe.io.Bytes.alloc(vertices * format.strideBytes);
  67. var bytesPos : Int = 0;
  68. var index : Int = bufPos;
  69. for ( i in 0...vertices ) {
  70. for ( input in format.getInputs() ) {
  71. var elementCount = input.type.getSize();
  72. var step = 0;
  73. switch ( input.precision ) {
  74. case F32 :
  75. for ( i in 0...elementCount ) {
  76. bytes.setFloat( bytesPos + step, buf[index++] );
  77. step += 4;
  78. }
  79. case F16 :
  80. for ( i in 0...elementCount ) {
  81. var f = hxd.BufferFormat.float32to16(buf[index++]);
  82. bytes.setUInt16( bytesPos + step, f );
  83. step += 2;
  84. }
  85. case U8 :
  86. for ( i in 0...elementCount ) {
  87. var f = hxd.BufferFormat.float32toU8(buf[index++]);
  88. bytes.set( bytesPos + step, f );
  89. step++;
  90. }
  91. case S8 :
  92. for ( i in 0...elementCount ) {
  93. var f = hxd.BufferFormat.float32toS8(buf[index++]);
  94. bytes.set( bytesPos + step, f );
  95. step++;
  96. }
  97. }
  98. // 4 bytes align
  99. bytesPos += input.getBytesSize();
  100. if ( bytesPos & 3 != 0 ) bytesPos += ( 4 - (bytesPos & 3) );
  101. }
  102. }
  103. uploadBytes(bytes, 0, vertices);
  104. return;
  105. }
  106. engine.driver.uploadBufferData(this, startVertice, vertices, buf, bufPos);
  107. }
  108. public function uploadBytes( data : haxe.io.Bytes, dataPos : Int, vertices : Int ) {
  109. if( vertices < 0 || vertices > this.vertices )
  110. throw "Invalid vertices count";
  111. if( vertices == 0 )
  112. return;
  113. engine.driver.uploadBufferBytes(this, 0, vertices, data, dataPos);
  114. }
  115. public function readBytes( bytes : haxe.io.Bytes, bytesPosition : Int, vertices : Int, startVertice : Int = 0 ) {
  116. if( startVertice < 0 || vertices < 0 || startVertice + vertices > this.vertices )
  117. throw "Invalid vertices count";
  118. engine.driver.readBufferBytes(this, startVertice, vertices, bytes, bytesPosition);
  119. }
  120. public static function ofFloats( v : hxd.FloatBuffer, format : hxd.BufferFormat, ?flags ) {
  121. var nvert = Math.ceil(v.length / format.stride);
  122. var b = new Buffer(nvert, format, flags);
  123. b.uploadFloats(v, 0, nvert);
  124. return b;
  125. }
  126. public static function ofSubFloats( v : hxd.FloatBuffer, vertices : Int, format : hxd.BufferFormat, ?flags ) {
  127. var b = new Buffer(vertices, format, flags);
  128. b.uploadFloats(v, 0, vertices);
  129. return b;
  130. }
  131. }