llvertexbuffer.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. /**
  2. * @file llvertexbuffer.h
  3. * @brief LLVertexBuffer wrapper for OpengGL vertex buffer objects
  4. *
  5. * $LicenseInfo:firstyear=2003&license=viewergpl$
  6. *
  7. * Copyright (c) 2003-2009, Linden Research, Inc.
  8. *
  9. * Second Life Viewer Source Code
  10. * The source code in this file ("Source Code") is provided by Linden Lab
  11. * to you under the terms of the GNU General Public License, version 2.0
  12. * ("GPL"), unless you have obtained a separate licensing agreement
  13. * ("Other License"), formally executed by you and Linden Lab. Terms of
  14. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16. *
  17. * There are special exceptions to the terms and conditions of the GPL as
  18. * it is applied to this Source Code. View the full text of the exception
  19. * in the file doc/FLOSS-exception.txt in this software distribution, or
  20. * online at
  21. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22. *
  23. * By copying, modifying or distributing this software, you acknowledge
  24. * that you have read and understood your obligations described above,
  25. * and agree to abide by those obligations.
  26. *
  27. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29. * COMPLETENESS OR PERFORMANCE.
  30. * $/LicenseInfo$
  31. */
  32. #ifndef LL_LLVERTEXBUFFER_H
  33. #define LL_LLVERTEXBUFFER_H
  34. #include <list>
  35. #include <vector>
  36. // Set to 1 to debug VB allocations and freeing on reset vertex buffer.
  37. #define LL_DEBUG_VB_ALLOC 0
  38. #if LL_DEBUG
  39. # undef LL_DEBUG_VB_ALLOC
  40. # define LL_DEBUG_VB_ALLOC 1
  41. #endif
  42. #if LL_DEBUG_VB_ALLOC
  43. # include "hbfastset.h"
  44. #endif
  45. #include "llcolor4u.h"
  46. #include "llgl.h"
  47. #include "llrefcount.h"
  48. #include "llrender.h"
  49. #include "llstrider.h"
  50. #define LL_MAX_VERTEX_ATTRIB_LOCATION 64
  51. // Note: *not* thread-safe. HB
  52. class LLVertexBuffer final : public LLRefCount
  53. {
  54. friend class LLRender;
  55. protected:
  56. LOG_CLASS(LLVertexBuffer);
  57. public:
  58. LLVertexBuffer(U32 typemask);
  59. // Make this class no-copy.
  60. LLVertexBuffer(const LLVertexBuffer&) = delete;
  61. const LLVertexBuffer& operator=(const LLVertexBuffer&) = delete;
  62. static void initClass();
  63. static void cleanupClass();
  64. static void setupClientArrays(U32 data_mask);
  65. static void drawArrays(U32 mode, const std::vector<LLVector3>& pos);
  66. static void drawArrays(U32 mode, const std::vector<LLVector3>& pos,
  67. const std::vector<LLVector3>& norm);
  68. // Draws triangles: used only in llselectmgr.cpp and llspatialpartition.cpp
  69. static void drawElements(U32 num_vertices, const LLVector4a* posp,
  70. const LLVector2* tcp, U32 num_indices,
  71. const U16* indicesp);
  72. static void unbind(); // Unbind any bound vertex buffer
  73. // Gets the size of a vertex with the given typemask
  74. static U32 calcVertexSize(U32 typemask);
  75. // Gets the size of a buffer with the given typemask and vertex count,
  76. // fills offsets with the offset of each vertex component array into the
  77. // buffer indexed by the following enum.
  78. static U32 calcOffsets(U32 typemask, U32* offsets, U32 num_vertices);
  79. // WARNING: when updating these enums you MUST
  80. // 1 - update LLVertexBuffer::sTypeSize
  81. // 2 - add a strider accessor
  82. // 3 - modify LLVertexBuffer::setupVertexBuffer
  83. // 4 - modify LLVertexBuffer::setupClientArray
  84. // 5 - modify LLShaderMgr::sReservedAttribs
  85. // 6 - update LLVertexBuffer::setupVertexArray
  86. enum
  87. {
  88. TYPE_VERTEX = 0,
  89. TYPE_NORMAL,
  90. TYPE_TEXCOORD0,
  91. TYPE_TEXCOORD1,
  92. TYPE_TEXCOORD2,
  93. TYPE_TEXCOORD3,
  94. TYPE_COLOR,
  95. TYPE_EMISSIVE,
  96. TYPE_TANGENT,
  97. TYPE_WEIGHT,
  98. TYPE_WEIGHT4,
  99. TYPE_CLOTHWEIGHT,
  100. TYPE_JOINT,
  101. TYPE_TEXTURE_INDEX,
  102. // TYPE_MAX is the size/boundary marker for attributes that go in the
  103. // vertex buffer
  104. TYPE_MAX,
  105. // TYPE_INDEX is beyond _MAX because it lives in a separate (index)
  106. // buffer
  107. TYPE_INDEX,
  108. };
  109. enum
  110. {
  111. MAP_VERTEX = 1 << TYPE_VERTEX,
  112. MAP_NORMAL = 1 << TYPE_NORMAL,
  113. MAP_TEXCOORD0 = 1 << TYPE_TEXCOORD0,
  114. MAP_TEXCOORD1 = 1 << TYPE_TEXCOORD1,
  115. MAP_TEXCOORD2 = 1 << TYPE_TEXCOORD2,
  116. MAP_TEXCOORD3 = 1 << TYPE_TEXCOORD3,
  117. MAP_COLOR = 1 << TYPE_COLOR,
  118. MAP_EMISSIVE = 1 << TYPE_EMISSIVE,
  119. MAP_TANGENT = 1 << TYPE_TANGENT,
  120. MAP_WEIGHT = 1 << TYPE_WEIGHT,
  121. MAP_WEIGHT4 = 1 << TYPE_WEIGHT4,
  122. MAP_CLOTHWEIGHT = 1 << TYPE_CLOTHWEIGHT,
  123. MAP_JOINT = 1 << TYPE_JOINT,
  124. MAP_TEXTURE_INDEX = 1 << TYPE_TEXTURE_INDEX,
  125. };
  126. // Maps for data access
  127. U8* mapVertexBuffer(S32 type, U32 index, S32 count);
  128. U8* mapIndexBuffer(U32 index, S32 count);
  129. void unmapBuffer();
  130. // Sets for rendering; calls setupVertexBuffer() if data_mask is not 0.
  131. // For the legacy EE renderer only.
  132. void setBuffer(U32 data_mask);
  133. // Assumes data_mask is not 0 among other assumptions.
  134. // For the legacy EE renderer only.
  135. void setBufferFast(U32 data_mask);
  136. // For the new PBR renderer only.
  137. void setBuffer();
  138. // For external (non-rendering) use only, such as by GLOD, in the model
  139. // upload preview floater: for this kind of use, we do need shader-less
  140. // vertex buffers and to set them up like we do with the EE renderer, even
  141. // while the PBR renderer is active. This method must be used for such
  142. // cases, and only for them. HB
  143. void setBufferNoShader(U32 data_mask);
  144. bool allocateBuffer(U32 nverts, U32 nindices);
  145. // Only call each getVertexPointer, etc, once before calling unmapBuffer().
  146. // Call unmapBuffer() after calls to getXXXStrider() and before any calls
  147. // to setBuffer(). Example:
  148. // vb->getVertexBuffer(verts);
  149. // vb->getNormalStrider(norms);
  150. // setVertsNorms(verts, norms);
  151. // vb->unmapBuffer();
  152. bool getVertexStrider(LLStrider<LLVector3>& strider, U32 index = 0,
  153. S32 count = -1);
  154. bool getVertexStrider(LLStrider<LLVector4a>& strider, U32 index = 0,
  155. S32 count = -1);
  156. bool getIndexStrider(LLStrider<U16>& strider, U32 index = 0,
  157. S32 count = -1);
  158. bool getTexCoord0Strider(LLStrider<LLVector2>& strider, U32 index = 0,
  159. S32 count = -1);
  160. bool getTexCoord1Strider(LLStrider<LLVector2>& strider, U32 index = 0,
  161. S32 count = -1);
  162. bool getTexCoord2Strider(LLStrider<LLVector2>& strider, U32 index = 0,
  163. S32 count = -1);
  164. bool getNormalStrider(LLStrider<LLVector3>& strider, U32 index = 0,
  165. S32 count = -1);
  166. bool getNormalStrider(LLStrider<LLVector4a>& strider, U32 index = 0,
  167. S32 count = -1);
  168. bool getTangentStrider(LLStrider<LLVector3>& strider, U32 index = 0,
  169. S32 count = -1);
  170. bool getTangentStrider(LLStrider<LLVector4a>& strider, U32 index = 0,
  171. S32 count = -1);
  172. bool getColorStrider(LLStrider<LLColor4U>& strider, U32 index = 0,
  173. S32 count = -1);
  174. bool getEmissiveStrider(LLStrider<LLColor4U>& strider, U32 index = 0,
  175. S32 count = -1);
  176. bool getWeightStrider(LLStrider<F32>& strider, U32 index = 0,
  177. S32 count = -1);
  178. bool getWeight4Strider(LLStrider<LLVector4a>& strider, U32 index = 0,
  179. S32 count = -1);
  180. bool getClothWeightStrider(LLStrider<LLVector4a>& strider, U32 index = 0,
  181. S32 count = -1);
  182. // A buffer is "locked" while it is mapped.
  183. LL_INLINE bool isLocked() const
  184. {
  185. return !mMappedVertexRegions.empty() ||
  186. !mMappedIndexRegions.empty();
  187. }
  188. LL_INLINE U32 getNumVerts() const { return mNumVerts; }
  189. LL_INLINE U32 getNumIndices() const { return mNumIndices; }
  190. void setPositionData(const LLVector4a* data);
  191. void setTexCoord0Data(const LLVector2* data);
  192. void setTexCoord1Data(const LLVector2* data);
  193. void setColorData(const LLColor4U* data);
  194. // For use by the llgltf library
  195. void setIndexData(const U16* data);
  196. void setIndexData(const U32* data);
  197. void setNormalData(const LLVector4a* data);
  198. void setTangentData(const LLVector4a* data);
  199. void setWeight4Data(const LLVector4a* data);
  200. void setJointData(const U64* data);
  201. void setPositionData(const LLVector4a* data, U32 offset, U32 count);
  202. void setTexCoord0Data(const LLVector2* data, U32 offset, U32 count);
  203. void setTexCoord1Data(const LLVector2* data, U32 offset, U32 count);
  204. void setColorData(const LLColor4U* data, U32 offset, U32 count);
  205. void setIndexData(const U16* data, U32 offset, U32 count);
  206. void setIndexData(const U32* data, U32 offset, U32 count);
  207. void setNormalData(const LLVector4a* data, U32 offset, U32 count);
  208. void setTangentData(const LLVector4a* data, U32 offset, U32 count);
  209. void setWeight4Data(const LLVector4a* data, U32 offset, U32 count);
  210. void setJointData(const U64* data, U32 offset, U32 count);
  211. LL_INLINE U32 getTypeMask() const { return mTypeMask; }
  212. LL_INLINE bool hasDataType(S32 type) const { return (1 << type) & getTypeMask(); }
  213. // This method allows to specify a mask that is negated and ANDed to
  214. // data_mask in setupVertexBuffer(). It allows to avoid using a derived
  215. // class and virtual method for the latter. HB
  216. LL_INLINE void setTypeMaskMask(U32 mask) { mTypeMaskMask = mask; }
  217. LL_INLINE U32 getSize() const { return mSize; }
  218. LL_INLINE U32 getIndicesSize() const { return mIndicesSize; }
  219. LL_INLINE U8* getMappedData() const { return mMappedData; }
  220. LL_INLINE U8* getMappedIndices() const { return mMappedIndexData; }
  221. LL_INLINE U32 getOffset(S32 type) const { return mOffsets[type]; }
  222. void resetVertexData();
  223. void resetIndexData();
  224. void draw(U32 mode, U32 count, U32 indices_offset) const;
  225. void drawArrays(U32 mode, U32 offset, U32 count) const;
  226. void drawRange(U32 mode, U32 start, U32 end, U32 count,
  227. U32 indices_offset) const;
  228. // Implementation for inner loops: does not do any safety check and always
  229. // renders in LLRender::TRIANGLES mode.
  230. void drawRangeFast(U32 start, U32 end, U32 count, U32 idx_offset) const;
  231. // For debugging, checks range validity.
  232. bool validateRange(U32 start, U32 end, U32 count, U32 offset) const;
  233. #if LL_DEBUG_VB_ALLOC
  234. void setOwner(const char* owner) { mOwner = owner; }
  235. static void dumpInstances();
  236. #endif
  237. static std::string listMissingBits(U32 unsatisfied_mask);
  238. // Statistics accessors used in some newview/*.cpp modules.
  239. LL_INLINE static S32 getGLCount() { return sGLCount; }
  240. LL_INLINE static U32 getBindCount() { return sBindCount; }
  241. LL_INLINE static U32 getSetCount() { return sSetCount; }
  242. // Used in llviewerwindow.cpp
  243. LL_INLINE static void resetPerFrameStats() { sBindCount = sSetCount = 0; }
  244. static void cleanupVBOPool();
  245. static S32 getVRAMMegabytes();
  246. protected:
  247. ~LLVertexBuffer() override; // use unref()
  248. void setupVertexBuffer(U32 data_mask);
  249. void setupVertexArray();
  250. void genBuffer(U32 size);
  251. void genIndices(U32 size);
  252. bool bindGLBuffer(bool force_bind = false);
  253. bool bindGLBufferFast();
  254. bool bindGLIndices(bool force_bind = false);
  255. bool bindGLIndicesFast();
  256. bool createGLBuffer(U32 size);
  257. bool createGLIndices(U32 size);
  258. void destroyGLBuffer();
  259. void destroyGLIndices();
  260. bool updateNumVerts(U32 nverts);
  261. bool updateNumIndices(U32 nindices);
  262. void placeFence() const;
  263. void waitFence() const;
  264. public:
  265. struct MappedRegion
  266. {
  267. LL_INLINE MappedRegion(U32 start, U32 end)
  268. : mStart(start),
  269. mEnd(end)
  270. {
  271. }
  272. U32 mStart;
  273. U32 mEnd;
  274. };
  275. static const U32 sTypeSize[TYPE_MAX];
  276. static const U32 sGLMode[LLRender::NUM_MODES];
  277. static U32 sGLRenderBuffer;
  278. static U32 sGLRenderIndices;
  279. static U32 sLastMask;
  280. static U32 sVertexCount;
  281. static U32 sIndexCount;
  282. static U32 sBindCount;
  283. static U32 sSetCount;
  284. static S32 sGLCount;
  285. static bool sVBOActive;
  286. static bool sIBOActive;
  287. protected:
  288. // Note: the first member variable is 32 bits in order to align on 64 bits
  289. // for the next variables, counting the 32 bits counter from LLRefCount. HB
  290. U32 mTypeMask;
  291. typedef std::vector<MappedRegion> region_map_t;
  292. region_map_t mMappedVertexRegions;
  293. region_map_t mMappedIndexRegions;
  294. #if LL_DEBUG_VB_ALLOC
  295. std::string mOwner;
  296. #endif
  297. U32 mNumVerts; // Number of vertices allocated
  298. U32 mNumIndices; // Number of indices allocated
  299. // *HACK: vertex buffers are initialized as 16 bits indices, but can be
  300. // switched to 32 bits indices.
  301. U32 mIndicesType;
  302. size_t mIndicesStride;
  303. U32 mSize;
  304. U32 mIndicesSize;
  305. // This is negated and ANDed to data_mask in setupVertexBuffer(). It allows
  306. // to avoid using a derived class and virtual method for the latter. HB
  307. U32 mTypeMaskMask;
  308. U32 mGLBuffer; // GL VBO handle
  309. U32 mGLIndices; // GL IBO handle
  310. U32 mOffsets[TYPE_MAX];
  311. // Pointer to currently mapped data (NULL if unmapped)
  312. U8* mMappedData;
  313. // Pointer to currently mapped indices (NULL if unmapped)
  314. U8* mMappedIndexData;
  315. // true when setPositionData() has been used (see LLRender::flush()). HB
  316. bool mCachedBuffer;
  317. private:
  318. static LLPointer<LLVertexBuffer> sUtilityBuffer;
  319. #if LL_DEBUG_VB_ALLOC
  320. typedef fast_hset<LLVertexBuffer*> instances_set_t;
  321. static instances_set_t sInstances;
  322. #endif
  323. };
  324. // Also used by LLPipeline
  325. U32 nhpo2(U32 v);
  326. // Also used by LLImageGL
  327. U32 wpo2(U32 i);
  328. #endif // LL_LLVERTEXBUFFER_H