CmMeshHeap.h 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. #pragma once
  2. #include "CmPrerequisites.h"
  3. #include "CmCoreObject.h"
  4. #include "CmIndexData.h"
  5. #include "CmDrawOps.h"
  6. namespace CamelotFramework
  7. {
  8. /**
  9. * @brief Mesh heap allows you to quickly allocate and deallocate a
  10. * large amounts of temporary meshes without the large overhead of normal Mesh creation.
  11. * Only requirement is that meshes share the same vertex description and index type.
  12. *
  13. * @note This class should be considered as a replacement for a normal Mesh if you are constantly
  14. * updating the mesh (e.g. every frame) and you are not able to discard entire mesh contents
  15. * on each update. Not using discard flag on normal meshes may introduce GPU-CPU sync points
  16. * which may severely limit performance. Primary purpose of this class is to avoid
  17. * those sync points by not forcing you to discard contents.
  18. *
  19. * Only downside is that this class may allocate 2-3x (or more) memory than it is actually needed
  20. * for your data.
  21. *
  22. * Sim thread only.
  23. */
  24. class CM_EXPORT MeshHeap : public CoreObject
  25. {
  26. enum class UseFlags
  27. {
  28. Used,
  29. CPUFree,
  30. GPUFree,
  31. Free
  32. };
  33. struct ChunkData
  34. {
  35. UINT32 start, size;
  36. };
  37. struct AllocatedData
  38. {
  39. UINT32 vertChunkIdx;
  40. UINT32 idxChunkIdx;
  41. UseFlags useFlags;
  42. UINT32 eventQueryIdx;
  43. };
  44. struct QueryData
  45. {
  46. EventQueryPtr query;
  47. UINT32 queryId;
  48. };
  49. public:
  50. ~MeshHeap();
  51. /**
  52. * @note Offsets provided by MeshData are ignored. MeshHeap will determine
  53. * where the data will be written internally.
  54. */
  55. TransientMeshPtr alloc(const MeshDataPtr& meshData, DrawOperationType drawOp = DOT_TRIANGLE_LIST);
  56. void dealloc(const TransientMeshPtr& mesh);
  57. static MeshHeapPtr create(UINT32 numVertices, UINT32 numIndices,
  58. const VertexDataDescPtr& vertexDesc, IndexBuffer::IndexType indexType = IndexBuffer::IT_32BIT);
  59. private:
  60. UINT32 mNumVertices; // Core thread
  61. UINT32 mNumIndices; // Core thread
  62. std::shared_ptr<VertexData> mVertexData; // Core thread
  63. std::shared_ptr<IndexData> mIndexData; // Core thread
  64. Vector<UINT8*>::type mCPUVertexData; // Core thread
  65. UINT8* mCPUIndexData; // Core thread
  66. VertexDataDescPtr mVertexDesc; // Immutable
  67. IndexBuffer::IndexType mIndexType; // Immutable
  68. Map<UINT32, TransientMeshPtr>::type mMeshes; // Sim thread
  69. UINT32 mNextFreeId; // Sim thread
  70. Map<UINT32, AllocatedData>::type mMeshAllocData; // Core thread
  71. Vector<ChunkData>::type mVertChunks; // Core thread
  72. Vector<ChunkData>::type mIdxChunks; // Core thread
  73. Stack<UINT32>::type mEmptyVertChunks; // Core thread
  74. Stack<UINT32>::type mEmptyIdxChunks; // Core thread
  75. List<UINT32>::type mFreeVertChunks; // Core thread
  76. List<UINT32>::type mFreeIdxChunks; // Core thread
  77. Vector<QueryData>::type mEventQueries; // Core thread
  78. Stack<UINT32>::type mFreeEventQueries; // Core thread
  79. UINT32 mNextQueryId;
  80. static const float GrowPercent;
  81. private:
  82. friend class TransientMesh;
  83. MeshHeap(UINT32 numVertices, UINT32 numIndices,
  84. const VertexDataDescPtr& vertexDesc, IndexBuffer::IndexType indexType = IndexBuffer::IT_32BIT);
  85. /**
  86. * @copydoc Resource::initialize_internal()
  87. */
  88. virtual void initialize_internal();
  89. /**
  90. * @copydoc Resource::destroy_internal()
  91. */
  92. virtual void destroy_internal();
  93. void allocInternal(UINT32 meshId, const MeshDataPtr& meshData);
  94. void deallocInternal(UINT32 meshId);
  95. void growVertexBuffer(UINT32 numVertices);
  96. void growIndexBuffer(UINT32 numIndices);
  97. UINT32 createEventQuery();
  98. void freeEventQuery(UINT32 idx);
  99. std::shared_ptr<VertexData> getVertexData() const;
  100. std::shared_ptr<IndexData> getIndexData() const;
  101. UINT32 getVertexOffset(UINT32 meshId) const;
  102. UINT32 getIndexOffset(UINT32 meshId) const;
  103. void notifyUsedOnGPU(UINT32 meshId);
  104. void queryTriggered(UINT32 meshId, UINT32 queryId);
  105. void mergeWithNearbyChunks(UINT32 chunkVertIdx, UINT32 chunkIdxIdx);
  106. };
  107. }