CommandBufferImpl.h 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. // Copyright (C) 2009-2023, 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/CommandBuffer.h>
  7. #include <AnKi/Gr/gl/StateTracker.h>
  8. #include <AnKi/Util/Assert.h>
  9. namespace anki {
  10. // Forward
  11. class GlState;
  12. /// @addtogroup opengl
  13. /// @{
  14. template<typename T>
  15. using CommandBufferAllocator = StackAllocator<T>;
  16. /// The base of all GL commands.
  17. class GlCommand
  18. {
  19. public:
  20. GlCommand* m_nextCommand = nullptr;
  21. virtual ~GlCommand()
  22. {
  23. }
  24. /// Execute command
  25. virtual ANKI_USE_RESULT Error operator()(GlState& state) = 0;
  26. };
  27. /// A number of GL commands organized in a chain
  28. class CommandBufferImpl final : public CommandBuffer
  29. {
  30. public:
  31. GlCommand* m_firstCommand = nullptr;
  32. GlCommand* m_lastCommand = nullptr;
  33. CommandBufferAllocator<U8> m_alloc;
  34. Bool m_immutable = false;
  35. CommandBufferFlag m_flags;
  36. #if ANKI_EXTRA_CHECKS
  37. Bool m_executed = false;
  38. #endif
  39. StateTracker m_state;
  40. /// Default constructor
  41. CommandBufferImpl(GrManager* manager, CString name)
  42. : CommandBuffer(manager, name)
  43. {
  44. }
  45. ~CommandBufferImpl()
  46. {
  47. destroy();
  48. }
  49. /// Initialize.
  50. void init(const CommandBufferInitInfo& init);
  51. /// Get the internal allocator.
  52. CommandBufferAllocator<U8> getInternalAllocator() const
  53. {
  54. return m_alloc;
  55. }
  56. /// Create a new command and add it to the chain.
  57. template<typename TCommand, typename... TArgs>
  58. void pushBackNewCommand(TArgs&&... args);
  59. /// Execute all commands
  60. ANKI_USE_RESULT Error executeAllCommands();
  61. /// Fake that it's been executed
  62. void makeExecuted()
  63. {
  64. #if ANKI_EXTRA_CHECKS
  65. m_executed = true;
  66. #endif
  67. }
  68. /// Make immutable
  69. void makeImmutable()
  70. {
  71. m_immutable = true;
  72. }
  73. Bool isEmpty() const
  74. {
  75. return m_firstCommand == nullptr;
  76. }
  77. Bool isSecondLevel() const
  78. {
  79. return !!(m_flags & CommandBufferFlag::kSecondLevel);
  80. }
  81. void flushDrawcall(CommandBuffer& cmdb);
  82. private:
  83. void destroy();
  84. };
  85. template<typename TCommand, typename... TArgs>
  86. inline void CommandBufferImpl::pushBackNewCommand(TArgs&&... args)
  87. {
  88. ANKI_ASSERT(!m_immutable);
  89. TCommand* newCommand = m_alloc.template newInstance<TCommand>(std::forward<TArgs>(args)...);
  90. if(m_firstCommand != nullptr)
  91. {
  92. ANKI_ASSERT(m_lastCommand != nullptr);
  93. ANKI_ASSERT(m_lastCommand->m_nextCommand == nullptr);
  94. m_lastCommand->m_nextCommand = newCommand;
  95. m_lastCommand = newCommand;
  96. }
  97. else
  98. {
  99. ANKI_ASSERT(m_lastCommand == nullptr);
  100. m_firstCommand = newCommand;
  101. m_lastCommand = newCommand;
  102. }
  103. }
  104. /// @}
  105. } // end namespace anki