BufferHandle.cpp 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. // Copyright (C) 2009-2015, Panagiotis Christopoulos Charitos.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #include "anki/gr/BufferHandle.h"
  6. #include "anki/gr/gl/DeferredDeleter.h"
  7. #include "anki/gr/gl/BufferImpl.h"
  8. #include "anki/gr/GrManager.h"
  9. namespace anki {
  10. //==============================================================================
  11. // Commands =
  12. //==============================================================================
  13. //==============================================================================
  14. /// Create buffer command
  15. class BufferCreateCommand: public GlCommand
  16. {
  17. public:
  18. BufferHandle m_buff;
  19. GLenum m_target;
  20. const void* m_data;
  21. PtrSize m_size;
  22. GLbitfield m_flags;
  23. BufferCreateCommand(
  24. BufferHandle buff, GLenum target, const void* data, PtrSize size,
  25. GLenum flags)
  26. : m_buff(buff),
  27. m_target(target),
  28. m_data(data),
  29. m_size(size),
  30. m_flags(flags)
  31. {}
  32. Error operator()(CommandBufferImpl*) final
  33. {
  34. Error err = ErrorCode::NONE;
  35. err = m_buff.get().create(m_target, m_data, m_size, m_flags);
  36. GlObject::State oldState = m_buff.get().setStateAtomically(
  37. (err) ? GlObject::State::ERROR : GlObject::State::CREATED);
  38. (void)oldState;
  39. ANKI_ASSERT(oldState == GlObject::State::TO_BE_CREATED);
  40. return err;
  41. }
  42. };
  43. //==============================================================================
  44. class BufferWriteCommand: public GlCommand
  45. {
  46. public:
  47. BufferHandle m_buff;
  48. const void* m_data;
  49. PtrSize m_dataSize;
  50. PtrSize m_readOffset;
  51. PtrSize m_writeOffset;
  52. PtrSize m_size;
  53. BufferWriteCommand(BufferHandle& buff, const void* data, PtrSize dataSize,
  54. PtrSize readOffset, PtrSize writeOffset, PtrSize size)
  55. : m_buff(buff),
  56. m_data(data),
  57. m_dataSize(dataSize),
  58. m_readOffset(readOffset),
  59. m_writeOffset(writeOffset),
  60. m_size(size)
  61. {}
  62. Error operator()(CommandBufferImpl*) final
  63. {
  64. ANKI_ASSERT(m_readOffset + m_size <= m_dataSize);
  65. m_buff.get().write(
  66. static_cast<const U8*>(m_data) + m_readOffset,
  67. m_writeOffset,
  68. m_size);
  69. return ErrorCode::NONE;
  70. }
  71. };
  72. //==============================================================================
  73. class BufferBindVertexCommand: public GlCommand
  74. {
  75. public:
  76. BufferHandle m_buff;
  77. U32 m_elementSize;
  78. GLenum m_type;
  79. Bool8 m_normalized;
  80. U32 m_stride;
  81. U32 m_offset;
  82. U32 m_attribLocation;
  83. BufferBindVertexCommand(BufferHandle& buff, U32 elementSize, GLenum type,
  84. Bool8 normalized, U32 stride, U32 offset, U32 attribLocation)
  85. : m_buff(buff),
  86. m_elementSize(elementSize),
  87. m_type(type),
  88. m_normalized(normalized),
  89. m_stride(stride),
  90. m_offset(offset),
  91. m_attribLocation(attribLocation)
  92. {
  93. ANKI_ASSERT(m_elementSize != 0);
  94. }
  95. Error operator()(CommandBufferImpl*)
  96. {
  97. BufferImpl& buff = m_buff.get();
  98. ANKI_ASSERT(m_offset < m_buff.getSize());
  99. buff.setTarget(GL_ARRAY_BUFFER);
  100. buff.bind();
  101. glEnableVertexAttribArray(m_attribLocation);
  102. glVertexAttribPointer(
  103. m_attribLocation,
  104. m_elementSize,
  105. m_type,
  106. m_normalized,
  107. m_stride,
  108. reinterpret_cast<const GLvoid*>(m_offset));
  109. return ErrorCode::NONE;
  110. }
  111. };
  112. //==============================================================================
  113. class BindShaderBufferCommand: public GlCommand
  114. {
  115. public:
  116. BufferHandle m_buff;
  117. I32 m_offset;
  118. I32 m_size;
  119. U8 m_binding;
  120. BindShaderBufferCommand(BufferHandle& buff,
  121. I32 offset, I32 size, U8 binding)
  122. :
  123. m_buff(buff),
  124. m_offset(offset),
  125. m_size(size),
  126. m_binding(binding)
  127. {}
  128. Error operator()(CommandBufferImpl*) final
  129. {
  130. U32 offset = (m_offset != -1) ? m_offset : 0;
  131. U32 size = (m_size != -1) ? m_size : m_buff.get().getSize();
  132. m_buff.get().setBindingRange(m_binding, offset, size);
  133. return ErrorCode::NONE;
  134. }
  135. };
  136. //==============================================================================
  137. class BindIndexBufferCommand: public GlCommand
  138. {
  139. public:
  140. BufferHandle m_buff;
  141. BindIndexBufferCommand(BufferHandle& buff)
  142. : m_buff(buff)
  143. {}
  144. Error operator()(CommandBufferImpl*)
  145. {
  146. BufferImpl& buff = m_buff.get();
  147. buff.setTarget(GL_ELEMENT_ARRAY_BUFFER);
  148. buff.bind();
  149. return ErrorCode::NONE;
  150. }
  151. };
  152. //==============================================================================
  153. // BufferHandle =
  154. //==============================================================================
  155. //==============================================================================
  156. BufferHandle::BufferHandle()
  157. {}
  158. //==============================================================================
  159. BufferHandle::~BufferHandle()
  160. {}
  161. //==============================================================================
  162. Error BufferHandle::create(CommandBufferHandle& commands,
  163. GLenum target, const void* data, PtrSize size, GLenum flags)
  164. {
  165. ANKI_ASSERT(!isCreated());
  166. using DeleteCommand = DeleteObjectCommand<BufferImpl>;
  167. using Deleter = DeferredDeleter<BufferImpl, DeleteCommand>;
  168. Error err = Base::create(commands.get().getManager(), Deleter());
  169. if(!err)
  170. {
  171. get().setStateAtomically(GlObject::State::TO_BE_CREATED);
  172. // Fire the command
  173. commands.get().pushBackNewCommand<BufferCreateCommand>(
  174. *this, target, data, size, flags);
  175. }
  176. return err;
  177. }
  178. //==============================================================================
  179. void BufferHandle::write(CommandBufferHandle& commands,
  180. const void* data, PtrSize dataSize, PtrSize readOffset, PtrSize writeOffset,
  181. PtrSize size)
  182. {
  183. ANKI_ASSERT(isCreated());
  184. commands.get().pushBackNewCommand<BufferWriteCommand>(
  185. *this, data, dataSize, readOffset, writeOffset, size);
  186. }
  187. //==============================================================================
  188. void BufferHandle::bindShaderBufferInternal(CommandBufferHandle& commands,
  189. I32 offset, I32 size, U32 bindingPoint)
  190. {
  191. ANKI_ASSERT(isCreated());
  192. commands.get().pushBackNewCommand<BindShaderBufferCommand>(
  193. *this, offset, size, bindingPoint);
  194. }
  195. //==============================================================================
  196. void BufferHandle::bindVertexBuffer(
  197. CommandBufferHandle& commands,
  198. U32 elementSize,
  199. GLenum type,
  200. Bool normalized,
  201. PtrSize stride,
  202. PtrSize offset,
  203. U32 attribLocation)
  204. {
  205. ANKI_ASSERT(isCreated());
  206. commands.get().pushBackNewCommand<BufferBindVertexCommand>(
  207. *this, elementSize, type, normalized, stride, offset, attribLocation);
  208. }
  209. //==============================================================================
  210. void BufferHandle::bindIndexBuffer(CommandBufferHandle& commands)
  211. {
  212. ANKI_ASSERT(isCreated());
  213. commands.get().pushBackNewCommand<BindIndexBufferCommand>(*this);
  214. }
  215. //==============================================================================
  216. PtrSize BufferHandle::getSize() const
  217. {
  218. return (get().serializeOnGetter()) ? 0 : get().getSize();
  219. }
  220. //==============================================================================
  221. GLenum BufferHandle::getTarget() const
  222. {
  223. return (get().serializeOnGetter()) ? GL_NONE : get().getTarget();
  224. }
  225. //==============================================================================
  226. void* BufferHandle::getPersistentMappingAddress()
  227. {
  228. return (get().serializeOnGetter())
  229. ? nullptr : get().getPersistentMappingAddress();
  230. }
  231. } // end namespace anki