renderer.d 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. module three.renderer;
  2. import three.common;
  3. import three.scene;
  4. import three.camera;
  5. import three.renderTarget;
  6. import three.viewport;
  7. import three.mesh;
  8. import std.string : toStringz;
  9. import std.exception : collectException;
  10. import std.experimental.logger;
  11. enum maxVertices = 1024;
  12. enum maxIndices = 1024;
  13. enum maxPerInstanceParams = 1024;
  14. enum maxIndirectCommands = 1024;
  15. enum bufferCount = 3; //tripple buffering
  16. enum kOneSecondInNanoSeconds = GLuint64(1000000000);
  17. //======================================================================================================================
  18. //
  19. //======================================================================================================================
  20. enum GlBufferTarget {
  21. Array = GL_ARRAY_BUFFER,
  22. AtomicCounter = GL_ATOMIC_COUNTER_BUFFER,
  23. CopyRead= GL_COPY_READ_BUFFER,
  24. CopyWrite = GL_COPY_WRITE_BUFFER,
  25. DrawIndirect = GL_DRAW_INDIRECT_BUFFER,
  26. DispatchIndirect = GL_DISPATCH_INDIRECT_BUFFER,
  27. ElementArray = GL_ELEMENT_ARRAY_BUFFER,
  28. PixelPack = GL_PIXEL_PACK_BUFFER,
  29. PixelUnpack = GL_PIXEL_UNPACK_BUFFER,
  30. QueryBuffer = GL_QUERY_BUFFER,
  31. ShaderStorage = GL_SHADER_STORAGE_BUFFER,
  32. Texture = GL_TEXTURE_BUFFER,
  33. TransformFeedback = GL_TRANSFORM_FEEDBACK_BUFFER,
  34. Uniform = GL_UNIFORM_BUFFER
  35. }
  36. struct GlBuffer(GlBufferTarget Target, T) {
  37. alias BufferTarget = Target;
  38. alias ValueType = T;
  39. GLuint handle;
  40. GLuint length;
  41. T* data;
  42. }
  43. void construct(GlBufferTarget Target, T)(out GlBuffer!(Target, T) buffer, GLuint length, GLbitfield createFlags, GLbitfield mapFlags) {
  44. glCheck!glGenBuffers(1, &buffer.handle);
  45. glCheck!glBindBuffer(Target, buffer.handle);
  46. glCheck!glBufferStorage(Target, length * T.sizeof, null, createFlags);
  47. buffer.data = cast(T*)glCheck!glMapBufferRange(Target, 0, length * T.sizeof, mapFlags);
  48. buffer.length = length;
  49. if (buffer.data is null) {
  50. throw new Exception("glMapBufferRange failed, probable bug.");
  51. }
  52. }
  53. void destruct(GlBufferTarget Target, T)(ref GlBuffer!(Target, T) buffer) {
  54. glCheck!glUnmapBuffer(Target);
  55. glCheck!glBindBuffer(Target, 0);
  56. glCheck!glDeleteBuffers(1, &buffer.handle);
  57. buffer = buffer.init;
  58. }
  59. void bind(GlBufferTarget Target, T)(ref GlBuffer!(Target, T) buffer) {
  60. glCheck!glBindBuffer(Target, buffer.handle);
  61. }
  62. void unbind(GlBufferTarget Target, T)(ref GlBuffer!(Target, T) buffer) {
  63. glCheck!glBindBuffer(Target, 0);
  64. }
  65. alias GlArrayBuffer(T) = GlBuffer!(GlBufferTarget.Array, T);
  66. alias GlElementArrayBuffer(T) = GlBuffer!(GlBufferTarget.ElementArray, T);
  67. alias GlShaderStorageBuffer(T) = GlBuffer!(GlBufferTarget.ShaderStorage, T);
  68. alias GlDispatchIndirectBuffer(T) = GlBuffer!(GlBufferTarget.DispatchIndirect, T);
  69. alias GlTextureBuffer(T) = GlBuffer!(GlBufferTarget.Texture, T);
  70. alias GlUniformBuffer(T) = GlBuffer!(GlBufferTarget.Uniform, T);
  71. //======================================================================================================================
  72. //
  73. //======================================================================================================================
  74. struct DrawElementsIndirectCommand {
  75. GLuint count;
  76. GLuint instanceCount;
  77. GLuint firstIndex;
  78. GLuint baseVertex;
  79. GLuint baseInstance;
  80. }
  81. struct DrawParameter {
  82. Matrix4 transformationMatrix;
  83. }
  84. //======================================================================================================================
  85. //
  86. //======================================================================================================================
  87. struct Renderer {
  88. uint width;
  89. uint height;
  90. GLsync sync;
  91. GlArrayBuffer!VertexData vertexBuffer; // vertex data for all meshes
  92. GlElementArrayBuffer!IndexData indexBuffer; //index data for all meshes
  93. GlShaderStorageBuffer!DrawParameter perInstanceParamBuffer; // is filled with draw parameters for each instance each frame. shall be accessed as a ringbuffer
  94. GlDispatchIndirectBuffer!DrawElementsIndirectCommand dispatchIndirectCommandBuffer; // is filled with DrawElementsIndirectCommand for each mesh each frame. shall be accessed as a ringbuffer
  95. }
  96. void construct(out Renderer renderer, uint width, uint height) {
  97. GLbitfield createFlags = GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT;//TODO: ?? | GL_MAP_DYNAMIC_STORAGE_BIT;
  98. GLbitfield mapFlags = GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT;
  99. renderer.vertexBuffer.construct(bufferCount * maxVertices, createFlags, mapFlags);
  100. renderer.indexBuffer.construct(bufferCount * maxIndices, createFlags, mapFlags);
  101. renderer.perInstanceParamBuffer.construct(bufferCount * maxPerInstanceParams, createFlags, mapFlags);
  102. renderer.dispatchIndirectCommandBuffer.construct(bufferCount * maxIndirectCommands, createFlags, mapFlags);
  103. glCheck!glEnableVertexAttribArray(0);
  104. glCheck!glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, VertexData.sizeof, cast(GLvoid*)0 );
  105. glCheck!glEnableVertexAttribArray(1);
  106. glCheck!glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, VertexData.sizeof, cast(GLvoid*)3 );
  107. glCheck!glEnableVertexAttribArray(2);
  108. glCheck!glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, VertexData.sizeof, cast(GLvoid*)6 );
  109. glCheck!glEnableVertexAttribArray(3);
  110. glCheck!glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, VertexData.sizeof, cast(GLvoid*)10 );
  111. }
  112. void destruct(ref Renderer renderer) {
  113. renderer.vertexBuffer.destruct();
  114. renderer.indexBuffer.destruct();
  115. renderer.perInstanceParamBuffer.destruct();
  116. renderer.dispatchIndirectCommandBuffer.destruct();
  117. renderer = renderer.init;
  118. }
  119. struct BufferLockManager(bool UseBusyCpu) {
  120. struct BufferRange
  121. {
  122. size_t startOffset;
  123. size_t length;
  124. bool overlaps(BufferRange rhs) const {
  125. return startOffset < (rhs.startOffset + rhs.length) && rhs.startOffset < (startOffset + length);
  126. }
  127. }
  128. struct BufferLock
  129. {
  130. BufferRange range;
  131. GLsync syncObj;
  132. }
  133. BufferLock[] bufferLocks;
  134. }
  135. void waitForLockedRange(bool UseBusyCpu)(ref BufferLockManager!UseBusyCpu bufferLockManager, size_t lockBeginOffset, size_t lockLength) {
  136. BufferRange testRange = BufferRange(lockBeginOffset, lockLength);
  137. BufferLock[] swapLocks;
  138. foreach(ref bl; bufferLockManager.bufferLocks) {
  139. if (testRange.overlaps(bl.range)) {
  140. static if(UseBusyCpu) {
  141. GLbitfield waitFlags = 0;
  142. GLuint64 waitDuration = 0;
  143. while(true) {
  144. GLenum waitRet = glCheck!glClientWaitSync(syncObj, waitFlags, waitDuration);
  145. if (waitRet == GL_ALREADY_SIGNALED || waitRet == GL_CONDITION_SATISFIED) {
  146. return;
  147. }
  148. if (waitRet == GL_WAIT_FAILED) {
  149. assert(!"Not sure what to do here. Probably raise an exception or something.");
  150. return;
  151. }
  152. // After the first time, need to start flushing, and wait for a looong time.
  153. waitFlags = GL_SYNC_FLUSH_COMMANDS_BIT;
  154. waitDuration = kOneSecondInNanoSeconds;
  155. }
  156. }
  157. else {
  158. glCheck!glWaitSync(syncObj, 0, GL_TIMEOUT_IGNORED);
  159. }
  160. glCheck!glDeleteSync(bl.syncObj);
  161. }
  162. else {
  163. swapLocks ~= bl;
  164. }
  165. }
  166. import std.algorithm : swap;
  167. swap(bufferLockManager.bufferLocks, swapLocks);
  168. }
  169. void lockRange(bool UseBusyCpu)(ref BufferLockManager!UseBusyCpu bufferLockManager, size_t lockBeginOffset, size_t lockLength) {
  170. BufferRange newRange = BufferRange(lockBeginOffset, lockLength);
  171. GLsync syncName = glCheck!glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
  172. BufferLock newLock = BufferLock(newRange, syncName);
  173. bufferLockManager.bufferLocks ~= newLock;
  174. }
  175. //void lockBuffer(ref Renderer renderer) {
  176. // if(renderer.sync) {
  177. // glDeleteSync(renderer.sync);
  178. // }
  179. // renderer.sync = glCheck!glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
  180. //}
  181. //
  182. //void waitBuffer(ref Renderer renderer) {
  183. // if(renderer.sync) {
  184. // while(true) {
  185. // GLenum waitReturn = glClientWaitSync(renderer.sync, GL_SYNC_FLUSH_COMMANDS_BIT, 1);
  186. // if (waitReturn == GL_ALREADY_SIGNALED || waitReturn == GL_CONDITION_SATISFIED) {
  187. // return;
  188. // }
  189. // }
  190. // }
  191. //}
  192. void uploadModelData(ref Renderer renderer, ModelData modelData) {
  193. //TODO: wait for buffer range
  194. //mBufferLockManager.WaitForLockedRange(mStartDestOffset, _vertices.size() * sizeof(Vec2));
  195. renderer.vertexBuffer.bind();
  196. renderer.indexBuffer.bind();
  197. // we need to store all models in one giant vbo to use glMultiDrawElementsIndirect.
  198. // TODO: implement triple buffering. -> use vertexBuffer and indexBuffer as giant ring buffers
  199. GLuint vertexBufferOffset = 0;
  200. GLuint indexBufferOffset = 0;
  201. foreach(meshData; modelData.meshData) {
  202. import std.c.string: memcpy;
  203. //upload vertex data
  204. assert(renderer.vertexBuffer.length >= meshData.vertexData.length);
  205. memcpy(renderer.vertexBuffer.data + vertexBufferOffset, meshData.vertexData.ptr, meshData.vertexData.length * VertexData.sizeof);
  206. vertexBufferOffset += meshData.vertexData.length * VertexData.sizeof;
  207. //upload index data
  208. assert(renderer.indexBuffer.length >= meshData.indexData.length);
  209. memcpy(renderer.indexBuffer.data + indexBufferOffset, meshData.indexData.ptr, meshData.indexData.length * IndexData.sizeof);
  210. indexBufferOffset += meshData.indexData.length * IndexData.sizeof;
  211. }
  212. }
  213. void renderOneFrame(ref Renderer renderer, ref Scene scene, ref Camera camera, ref RenderTarget renderTarget, ref Viewport viewport) {
  214. /*
  215. foreach(renderTarget) //framebuffer
  216. foreach(pass)
  217. foreach(material) //shaders
  218. foreach(materialInstance) //textures
  219. foreach(vertexFormat) //vertex buffers
  220. foreach(object) {
  221. write uniform data;
  222. glDrawElementsBaseVertex
  223. }
  224. */
  225. GLsizei meshCount = 0;
  226. glCheck!glViewport(0, 0, renderer.width, renderer.height);
  227. // enable depth mask _before_ glClear ing the depth buffer!
  228. glCheck!glDepthMask(GL_TRUE); scope(exit) glCheck!glDepthMask(GL_FALSE);
  229. glCheck!glEnable(GL_DEPTH_TEST); scope(exit) glCheck!glDisable(GL_DEPTH_TEST);
  230. glCheck!glDepthFunc(GL_LEQUAL);
  231. // write draw parameters
  232. // write draw commmands
  233. // draw //TODO: pass offset (cast to ptr) into command buffer instead of null
  234. renderer.vertexBuffer.bind();
  235. renderer.indexBuffer.bind();
  236. renderer.perInstanceParamBuffer.bind();
  237. renderer.dispatchIndirectCommandBuffer.bind();
  238. glCheck!glMultiDrawElementsIndirect(GL_TRIANGLES, toGlType!(renderer.indexBuffer.ValueType), null, meshCount, 0);
  239. //TODO: lock buffer range
  240. }
  241. debug {
  242. void blitGBufferToScreen(ref Renderer renderer) {
  243. }
  244. }