PageRenderTime 39ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/llrender/llvertexbuffer.h

https://bitbucket.org/lindenlab/viewer-beta/
C Header | 324 lines | 210 code | 52 blank | 62 comment | 1 complexity | 8dcb9f20be308661032c1a9d66d8b2c8 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llvertexbuffer.h
  3. * @brief LLVertexBuffer wrapper for OpengGL vertex buffer objects
  4. *
  5. * $LicenseInfo:firstyear=2003&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2010, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. #ifndef LL_LLVERTEXBUFFER_H
  27. #define LL_LLVERTEXBUFFER_H
  28. #include "llgl.h"
  29. #include "v2math.h"
  30. #include "v3math.h"
  31. #include "v4math.h"
  32. #include "v4coloru.h"
  33. #include "llstrider.h"
  34. #include "llrender.h"
  35. #include <set>
  36. #include <vector>
  37. #include <list>
  38. #define LL_MAX_VERTEX_ATTRIB_LOCATION 64
  39. //============================================================================
  40. // NOTES
  41. // Threading:
  42. // All constructors should take an 'create' paramater which should only be
  43. // 'true' when called from the main thread. Otherwise createGLBuffer() will
  44. // be called as soon as getVertexPointer(), etc is called (which MUST ONLY be
  45. // called from the main (i.e OpenGL) thread)
  46. //============================================================================
  47. // gl name pools for dynamic and streaming buffers
  48. class LLVBOPool
  49. {
  50. public:
  51. static U32 sBytesPooled;
  52. U32 mUsage;
  53. U32 mType;
  54. //size MUST be a power of 2
  55. U8* allocate(U32& name, U32 size);
  56. //size MUST be the size provided to allocate that returned the given name
  57. void release(U32 name, U8* buffer, U32 size);
  58. //destroy all records in mFreeList
  59. void cleanup();
  60. class Record
  61. {
  62. public:
  63. U32 mGLName;
  64. U8* mClientData;
  65. };
  66. typedef std::list<Record> record_list_t;
  67. std::vector<record_list_t> mFreeList;
  68. };
  69. class LLGLFence
  70. {
  71. public:
  72. virtual void placeFence() = 0;
  73. virtual void wait() = 0;
  74. };
  75. //============================================================================
  76. // base class
  77. class LLPrivateMemoryPool ;
  78. class LLVertexBuffer : public LLRefCount
  79. {
  80. public:
  81. class MappedRegion
  82. {
  83. public:
  84. S32 mType;
  85. S32 mIndex;
  86. S32 mCount;
  87. MappedRegion(S32 type, S32 index, S32 count);
  88. };
  89. LLVertexBuffer(const LLVertexBuffer& rhs)
  90. {
  91. *this = rhs;
  92. }
  93. const LLVertexBuffer& operator=(const LLVertexBuffer& rhs)
  94. {
  95. llerrs << "Illegal operation!" << llendl;
  96. return *this;
  97. }
  98. static LLVBOPool sStreamVBOPool;
  99. static LLVBOPool sDynamicVBOPool;
  100. static LLVBOPool sStreamIBOPool;
  101. static LLVBOPool sDynamicIBOPool;
  102. static BOOL sUseStreamDraw;
  103. static BOOL sUseVAO;
  104. static BOOL sPreferStreamDraw;
  105. static void initClass(bool use_vbo, bool no_vbo_mapping);
  106. static void cleanupClass();
  107. static void setupClientArrays(U32 data_mask);
  108. static void drawArrays(U32 mode, const std::vector<LLVector3>& pos, const std::vector<LLVector3>& norm);
  109. static void drawElements(U32 mode, const LLVector4a* pos, const LLVector2* tc, S32 num_indices, const U16* indicesp);
  110. static void unbind(); //unbind any bound vertex buffer
  111. //get the size of a vertex with the given typemask
  112. static S32 calcVertexSize(const U32& typemask);
  113. //get the size of a buffer with the given typemask and vertex count
  114. //fill offsets with the offset of each vertex component array into the buffer
  115. // indexed by the following enum
  116. static S32 calcOffsets(const U32& typemask, S32* offsets, S32 num_vertices);
  117. //WARNING -- when updating these enums you MUST
  118. // 1 - update LLVertexBuffer::sTypeSize
  119. // 2 - add a strider accessor
  120. // 3 - modify LLVertexBuffer::setupVertexBuffer
  121. // 4 - modify LLVertexBuffer::setupClientArray
  122. // 5 - modify LLViewerShaderMgr::mReservedAttribs
  123. // 6 - update LLVertexBuffer::setupVertexArray
  124. enum {
  125. TYPE_VERTEX = 0,
  126. TYPE_NORMAL,
  127. TYPE_TEXCOORD0,
  128. TYPE_TEXCOORD1,
  129. TYPE_TEXCOORD2,
  130. TYPE_TEXCOORD3,
  131. TYPE_COLOR,
  132. TYPE_EMISSIVE,
  133. TYPE_BINORMAL,
  134. TYPE_WEIGHT,
  135. TYPE_WEIGHT4,
  136. TYPE_CLOTHWEIGHT,
  137. TYPE_TEXTURE_INDEX,
  138. TYPE_MAX,
  139. TYPE_INDEX,
  140. };
  141. enum {
  142. MAP_VERTEX = (1<<TYPE_VERTEX),
  143. MAP_NORMAL = (1<<TYPE_NORMAL),
  144. MAP_TEXCOORD0 = (1<<TYPE_TEXCOORD0),
  145. MAP_TEXCOORD1 = (1<<TYPE_TEXCOORD1),
  146. MAP_TEXCOORD2 = (1<<TYPE_TEXCOORD2),
  147. MAP_TEXCOORD3 = (1<<TYPE_TEXCOORD3),
  148. MAP_COLOR = (1<<TYPE_COLOR),
  149. MAP_EMISSIVE = (1<<TYPE_EMISSIVE),
  150. // These use VertexAttribPointer and should possibly be made generic
  151. MAP_BINORMAL = (1<<TYPE_BINORMAL),
  152. MAP_WEIGHT = (1<<TYPE_WEIGHT),
  153. MAP_WEIGHT4 = (1<<TYPE_WEIGHT4),
  154. MAP_CLOTHWEIGHT = (1<<TYPE_CLOTHWEIGHT),
  155. MAP_TEXTURE_INDEX = (1<<TYPE_TEXTURE_INDEX),
  156. };
  157. protected:
  158. friend class LLRender;
  159. virtual ~LLVertexBuffer(); // use unref()
  160. virtual void setupVertexBuffer(U32 data_mask); // pure virtual, called from mapBuffer()
  161. void setupVertexArray();
  162. void genBuffer(U32 size);
  163. void genIndices(U32 size);
  164. bool bindGLBuffer(bool force_bind = false);
  165. bool bindGLIndices(bool force_bind = false);
  166. bool bindGLArray();
  167. void releaseBuffer();
  168. void releaseIndices();
  169. void createGLBuffer(U32 size);
  170. void createGLIndices(U32 size);
  171. void destroyGLBuffer();
  172. void destroyGLIndices();
  173. void updateNumVerts(S32 nverts);
  174. void updateNumIndices(S32 nindices);
  175. virtual BOOL useVBOs() const;
  176. void unmapBuffer();
  177. public:
  178. LLVertexBuffer(U32 typemask, S32 usage);
  179. // map for data access
  180. U8* mapVertexBuffer(S32 type, S32 index, S32 count, bool map_range);
  181. U8* mapIndexBuffer(S32 index, S32 count, bool map_range);
  182. // set for rendering
  183. virtual void setBuffer(U32 data_mask); // calls setupVertexBuffer() if data_mask is not 0
  184. void flush(); //flush pending data to GL memory
  185. // allocate buffer
  186. void allocateBuffer(S32 nverts, S32 nindices, bool create);
  187. virtual void resizeBuffer(S32 newnverts, S32 newnindices);
  188. // Only call each getVertexPointer, etc, once before calling unmapBuffer()
  189. // call unmapBuffer() after calls to getXXXStrider() before any cals to setBuffer()
  190. // example:
  191. // vb->getVertexBuffer(verts);
  192. // vb->getNormalStrider(norms);
  193. // setVertsNorms(verts, norms);
  194. // vb->unmapBuffer();
  195. bool getVertexStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false);
  196. bool getVertexStrider(LLStrider<LLVector4a>& strider, S32 index=0, S32 count = -1, bool map_range = false);
  197. bool getIndexStrider(LLStrider<U16>& strider, S32 index=0, S32 count = -1, bool map_range = false);
  198. bool getTexCoord0Strider(LLStrider<LLVector2>& strider, S32 index=0, S32 count = -1, bool map_range = false);
  199. bool getTexCoord1Strider(LLStrider<LLVector2>& strider, S32 index=0, S32 count = -1, bool map_range = false);
  200. bool getNormalStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false);
  201. bool getBinormalStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false);
  202. bool getColorStrider(LLStrider<LLColor4U>& strider, S32 index=0, S32 count = -1, bool map_range = false);
  203. bool getEmissiveStrider(LLStrider<LLColor4U>& strider, S32 index=0, S32 count = -1, bool map_range = false);
  204. bool getWeightStrider(LLStrider<F32>& strider, S32 index=0, S32 count = -1, bool map_range = false);
  205. bool getWeight4Strider(LLStrider<LLVector4>& strider, S32 index=0, S32 count = -1, bool map_range = false);
  206. bool getClothWeightStrider(LLStrider<LLVector4>& strider, S32 index=0, S32 count = -1, bool map_range = false);
  207. BOOL isEmpty() const { return mEmpty; }
  208. BOOL isLocked() const { return mVertexLocked || mIndexLocked; }
  209. S32 getNumVerts() const { return mNumVerts; }
  210. S32 getNumIndices() const { return mNumIndices; }
  211. U8* getIndicesPointer() const { return useVBOs() ? (U8*) mAlignedIndexOffset : mMappedIndexData; }
  212. U8* getVerticesPointer() const { return useVBOs() ? (U8*) mAlignedOffset : mMappedData; }
  213. U32 getTypeMask() const { return mTypeMask; }
  214. bool hasDataType(S32 type) const { return ((1 << type) & getTypeMask()); }
  215. S32 getSize() const;
  216. S32 getIndicesSize() const { return mIndicesSize; }
  217. U8* getMappedData() const { return mMappedData; }
  218. U8* getMappedIndices() const { return mMappedIndexData; }
  219. S32 getOffset(S32 type) const { return mOffsets[type]; }
  220. S32 getUsage() const { return mUsage; }
  221. void draw(U32 mode, U32 count, U32 indices_offset) const;
  222. void drawArrays(U32 mode, U32 offset, U32 count) const;
  223. void drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const;
  224. //for debugging, validate data in given range is valid
  225. void validateRange(U32 start, U32 end, U32 count, U32 offset) const;
  226. protected:
  227. S32 mNumVerts; // Number of vertices allocated
  228. S32 mNumIndices; // Number of indices allocated
  229. ptrdiff_t mAlignedOffset;
  230. ptrdiff_t mAlignedIndexOffset;
  231. S32 mSize;
  232. S32 mIndicesSize;
  233. U32 mTypeMask;
  234. S32 mUsage; // GL usage
  235. U32 mGLBuffer; // GL VBO handle
  236. U32 mGLIndices; // GL IBO handle
  237. U32 mGLArray; // GL VAO handle
  238. U8* mMappedData; // pointer to currently mapped data (NULL if unmapped)
  239. U8* mMappedIndexData; // pointer to currently mapped indices (NULL if unmapped)
  240. BOOL mVertexLocked; // if TRUE, vertex buffer is being or has been written to in client memory
  241. BOOL mIndexLocked; // if TRUE, index buffer is being or has been written to in client memory
  242. BOOL mFinal; // if TRUE, buffer can not be mapped again
  243. BOOL mEmpty; // if TRUE, client buffer is empty (or NULL). Old values have been discarded.
  244. S32 mOffsets[TYPE_MAX];
  245. std::vector<MappedRegion> mMappedVertexRegions;
  246. std::vector<MappedRegion> mMappedIndexRegions;
  247. mutable LLGLFence* mFence;
  248. void placeFence() const;
  249. void waitFence() const;
  250. private:
  251. static LLPrivateMemoryPool* sPrivatePoolp ;
  252. public:
  253. static S32 sCount;
  254. static S32 sGLCount;
  255. static S32 sMappedCount;
  256. static BOOL sMapped;
  257. typedef std::list<LLVertexBuffer*> buffer_list_t;
  258. static BOOL sDisableVBOMapping; //disable glMapBufferARB
  259. static BOOL sEnableVBOs;
  260. static S32 sTypeSize[TYPE_MAX];
  261. static U32 sGLMode[LLRender::NUM_MODES];
  262. static U32 sGLRenderBuffer;
  263. static U32 sGLRenderArray;
  264. static U32 sGLRenderIndices;
  265. static BOOL sVBOActive;
  266. static BOOL sIBOActive;
  267. static U32 sLastMask;
  268. static U32 sAllocatedBytes;
  269. static U32 sBindCount;
  270. static U32 sSetCount;
  271. };
  272. #endif // LL_LLVERTEXBUFFER_H