BufferImpl.h 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. // Copyright (C) 2009-2021, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #pragma once
  6. #include <AnKi/Gr/Buffer.h>
  7. #include <AnKi/Gr/gl/GlObject.h>
  8. namespace anki {
  9. /// @addtogroup opengl
  10. /// @{
  11. /// Buffer implementation
  12. class BufferImpl final : public Buffer, public GlObject
  13. {
  14. public:
  15. BufferImpl(GrManager* manager, CString name)
  16. : Buffer(manager, name)
  17. {
  18. }
  19. ~BufferImpl()
  20. {
  21. destroyDeferred(getManager(), glDeleteBuffers);
  22. }
  23. void preInit(const BufferInitInfo& init)
  24. {
  25. ANKI_ASSERT(init.isValid());
  26. m_size = init.m_size;
  27. m_usage = init.m_usage;
  28. m_access = init.m_access;
  29. }
  30. void init();
  31. void bind(GLenum target, U32 binding, PtrSize offset, PtrSize range) const
  32. {
  33. ANKI_ASSERT(isCreated());
  34. range = (range == MAX_PTR_SIZE) ? (m_size - offset) : range;
  35. ANKI_ASSERT(range > 0);
  36. ANKI_ASSERT(offset + range <= m_size);
  37. glBindBufferRange(target, binding, m_glName, offset, range);
  38. }
  39. void bind(GLenum target, U32 binding, PtrSize offset) const
  40. {
  41. bind(target, binding, offset, MAX_PTR_SIZE);
  42. }
  43. void write(GLuint pbo, U32 pboOffset, U32 offset, U32 size) const
  44. {
  45. ANKI_ASSERT(isCreated());
  46. ANKI_ASSERT(offset + size <= m_size);
  47. glCopyNamedBufferSubData(pbo, m_glName, pboOffset, offset, size);
  48. }
  49. void fill(PtrSize offset, PtrSize size, U32 value)
  50. {
  51. ANKI_ASSERT(isCreated());
  52. ANKI_ASSERT(offset < m_size);
  53. ANKI_ASSERT((offset % 4) == 0 && "Should be multiple of 4");
  54. size = (size == MAX_PTR_SIZE) ? (m_realSize - offset) : size;
  55. ANKI_ASSERT(offset + size <= m_realSize);
  56. ANKI_ASSERT((size % 4) == 0 && "Should be multiple of 4");
  57. glClearNamedBufferSubData(m_glName, GL_R32UI, offset, size, GL_RED_INTEGER, GL_UNSIGNED_INT, &value);
  58. }
  59. void* map(PtrSize offset, PtrSize range, BufferMapAccessBit access)
  60. {
  61. // Wait for its creation
  62. if(serializeRenderingThread(getManager()))
  63. {
  64. return nullptr;
  65. }
  66. // Sanity checks
  67. ANKI_ASSERT(offset + range <= m_size);
  68. ANKI_ASSERT(m_persistentMapping);
  69. U8* ptr = static_cast<U8*>(m_persistentMapping);
  70. ptr += offset;
  71. #if ANKI_EXTRA_CHECKS
  72. ANKI_ASSERT(!m_mapped);
  73. m_mapped = true;
  74. #endif
  75. return static_cast<void*>(ptr);
  76. }
  77. void unmap()
  78. {
  79. #if ANKI_EXTRA_CHECKS
  80. ANKI_ASSERT(m_mapped);
  81. m_mapped = false;
  82. #endif
  83. }
  84. private:
  85. void* m_persistentMapping = nullptr;
  86. GLenum m_target = GL_NONE; ///< A guess
  87. #if ANKI_EXTRA_CHECKS
  88. Bool m_mapped = false;
  89. #endif
  90. PtrSize m_realSize = 0;
  91. };
  92. /// @}
  93. } // end namespace anki