DynamicMemoryManager.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. // Copyright (C) 2009-2016, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #include <anki/gr/gl/DynamicMemoryManager.h>
  6. #include <anki/core/Config.h>
  7. namespace anki
  8. {
  9. //==============================================================================
  10. DynamicMemoryManager::~DynamicMemoryManager()
  11. {
  12. for(DynamicBuffer& buff : m_buffers)
  13. {
  14. ANKI_ASSERT(buff.m_name == 0);
  15. }
  16. }
  17. //==============================================================================
  18. void DynamicMemoryManager::destroy()
  19. {
  20. for(DynamicBuffer& buff : m_buffers)
  21. {
  22. if(buff.m_name != 0)
  23. {
  24. glDeleteBuffers(1, &buff.m_name);
  25. }
  26. buff.m_cpuBuff.destroy(m_alloc);
  27. }
  28. }
  29. //==============================================================================
  30. void DynamicMemoryManager::init(
  31. GenericMemoryPoolAllocator<U8> alloc, const ConfigSet& cfg)
  32. {
  33. const U BUFF_FLAGS = GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT;
  34. m_alloc = alloc;
  35. // Uniform
  36. {
  37. // Create buffer
  38. PtrSize size = cfg.getNumber("gr.uniformPerFrameMemorySize");
  39. DynamicBuffer& buff = m_buffers[BufferUsage::UNIFORM];
  40. glGenBuffers(1, &buff.m_name);
  41. // Map it
  42. glNamedBufferStorage(buff.m_name, size, nullptr, BUFF_FLAGS);
  43. buff.m_mappedMem = static_cast<U8*>(
  44. glMapNamedBufferRange(buff.m_name, 0, size, BUFF_FLAGS));
  45. ANKI_ASSERT(buff.m_mappedMem);
  46. // Create the allocator
  47. GLint64 blockAlignment;
  48. glGetInteger64v(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &blockAlignment);
  49. buff.m_frameAlloc.init(size, blockAlignment, MAX_UNIFORM_BLOCK_SIZE);
  50. }
  51. // Storage
  52. {
  53. // Create buffer
  54. PtrSize size = cfg.getNumber("gr.storagePerFrameMemorySize");
  55. DynamicBuffer& buff = m_buffers[BufferUsage::STORAGE];
  56. glGenBuffers(1, &buff.m_name);
  57. // Map it
  58. glNamedBufferStorage(buff.m_name, size, nullptr, BUFF_FLAGS);
  59. buff.m_mappedMem = static_cast<U8*>(
  60. glMapNamedBufferRange(buff.m_name, 0, size, BUFF_FLAGS));
  61. ANKI_ASSERT(buff.m_mappedMem);
  62. // Create the allocator
  63. GLint64 blockAlignment;
  64. glGetInteger64v(
  65. GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT, &blockAlignment);
  66. buff.m_frameAlloc.init(size, blockAlignment, MAX_STORAGE_BLOCK_SIZE);
  67. }
  68. // Transfer
  69. {
  70. // Big enough block to hold a texture surface
  71. const PtrSize BLOCK_SIZE = (4096 * 4096) / 4 * 16 + 512;
  72. PtrSize size = cfg.getNumber("gr.transferPersistentMemorySize");
  73. DynamicBuffer& buff = m_buffers[BufferUsage::TRANSFER];
  74. buff.m_cpuBuff.create(m_alloc, size);
  75. buff.m_mappedMem = reinterpret_cast<U8*>(&buff.m_cpuBuff[0]);
  76. buff.m_persistentAlloc.init(m_alloc, size, BLOCK_SIZE);
  77. }
  78. }
  79. //==============================================================================
  80. void* DynamicMemoryManager::allocatePerFrame(
  81. BufferUsage usage, PtrSize size, DynamicBufferToken& handle)
  82. {
  83. DynamicBuffer& buff = m_buffers[usage];
  84. Error err = buff.m_frameAlloc.allocate(size, handle, true);
  85. (void)err;
  86. return buff.m_mappedMem + handle.m_offset;
  87. }
  88. //==============================================================================
  89. void* DynamicMemoryManager::allocatePersistent(
  90. BufferUsage usage, PtrSize size, DynamicBufferToken& handle)
  91. {
  92. DynamicBuffer& buff = m_buffers[usage];
  93. Error err = buff.m_persistentAlloc.allocate(size, 16, handle, false);
  94. if(!err)
  95. {
  96. return buff.m_mappedMem + handle.m_offset;
  97. }
  98. else
  99. {
  100. ANKI_LOGW("Out of persistent dynamic memory. Someone should serialize");
  101. return nullptr;
  102. }
  103. }
  104. //==============================================================================
  105. void DynamicMemoryManager::freePersistent(
  106. BufferUsage usage, const DynamicBufferToken& handle)
  107. {
  108. DynamicBuffer& buff = m_buffers[usage];
  109. buff.m_persistentAlloc.free(handle);
  110. }
  111. } // end namespace anki