summaryrefslogtreecommitdiff
path: root/indra/llrender/llvertexbuffer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llrender/llvertexbuffer.cpp')
-rw-r--r--indra/llrender/llvertexbuffer.cpp66
1 files changed, 61 insertions, 5 deletions
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index 156e300853..8524b470de 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -36,6 +36,7 @@
#include "llshadermgr.h"
#include "llglslshader.h"
#include "llmemory.h"
+#include <glm/gtc/type_ptr.hpp>
//Next Highest Power Of Two
//helper function, returns first number > v that is a power of 2, or v if v is already a power of 2
@@ -590,13 +591,13 @@ void LLVertexBufferData::draw()
gGL.matrixMode(LLRender::MM_MODELVIEW);
gGL.pushMatrix();
- gGL.loadMatrix(mModelView.m);
+ gGL.loadMatrix(glm::value_ptr(mModelView));
gGL.matrixMode(LLRender::MM_PROJECTION);
gGL.pushMatrix();
- gGL.loadMatrix(mProjection.m);
+ gGL.loadMatrix(glm::value_ptr(mProjection));
gGL.matrixMode(LLRender::MM_TEXTURE0);
gGL.pushMatrix();
- gGL.loadMatrix(mTexture0.m);
+ gGL.loadMatrix(glm::value_ptr(mTexture0));
mVB->setBuffer();
@@ -954,6 +955,25 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask)
}
}
+// list of mapped buffers
+// NOTE: must not be LLPointer<LLVertexBuffer> to avoid breaking non-ref-counted LLVertexBuffer instances
+static std::vector<LLVertexBuffer*> sMappedBuffers;
+
+//static
+void LLVertexBuffer::flushBuffers()
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX;
+ // must only be called from main thread
+ llassert(LLCoros::on_main_thread_main_coro());
+ for (auto& buffer : sMappedBuffers)
+ {
+ buffer->_unmapBuffer();
+ buffer->mMapped = false;
+ }
+
+ sMappedBuffers.resize(0);
+}
+
//static
U32 LLVertexBuffer::calcOffsets(const U32& typemask, U32* offsets, U32 num_vertices)
{
@@ -997,6 +1017,12 @@ U32 LLVertexBuffer::calcVertexSize(const U32& typemask)
//virtual
LLVertexBuffer::~LLVertexBuffer()
{
+ if (mMapped)
+ { // is on the mapped buffer list but doesn't need to be flushed
+ mMapped = false;
+ unmapBuffer();
+ }
+
destroyGLBuffer();
destroyGLIndices();
@@ -1198,6 +1224,7 @@ bool expand_region(LLVertexBuffer::MappedRegion& region, U32 start, U32 end)
U8* LLVertexBuffer::mapVertexBuffer(LLVertexBuffer::AttributeType type, U32 index, S32 count)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX;
+ _mapBuffer();
if (count == -1)
{
@@ -1233,6 +1260,7 @@ U8* LLVertexBuffer::mapVertexBuffer(LLVertexBuffer::AttributeType type, U32 inde
U8* LLVertexBuffer::mapIndexBuffer(U32 index, S32 count)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX;
+ _mapBuffer();
if (count == -1)
{
@@ -1289,11 +1317,11 @@ void LLVertexBuffer::flush_vbo(GLenum target, U32 start, U32 end, void* data, U8
LL_PROFILE_ZONE_NUM(end);
LL_PROFILE_ZONE_NUM(end-start);
- constexpr U32 block_size = 8192;
+ constexpr U32 block_size = 65536;
for (U32 i = start; i <= end; i += block_size)
{
- LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("glBufferSubData block");
+ //LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("glBufferSubData block");
//LL_PROFILE_GPU_ZONE("glBufferSubData");
U32 tend = llmin(i + block_size, end);
U32 size = tend - i + 1;
@@ -1305,7 +1333,28 @@ void LLVertexBuffer::flush_vbo(GLenum target, U32 start, U32 end, void* data, U8
void LLVertexBuffer::unmapBuffer()
{
+ flushBuffers();
+}
+
+void LLVertexBuffer::_mapBuffer()
+{
+ // must only be called from main thread
+ llassert(LLCoros::on_main_thread_main_coro());
+ if (!mMapped)
+ {
+ mMapped = true;
+ sMappedBuffers.push_back(this);
+ }
+}
+
+void LLVertexBuffer::_unmapBuffer()
+{
STOP_GLERROR;
+ if (!mMapped)
+ {
+ return;
+ }
+
struct SortMappedRegion
{
bool operator()(const MappedRegion& lhs, const MappedRegion& rhs)
@@ -1549,6 +1598,13 @@ void LLVertexBuffer::setBuffer()
return;
}
#endif
+
+ if (mMapped)
+ {
+ LL_WARNS_ONCE() << "Missing call to unmapBuffer or flushBuffers" << LL_ENDL;
+ _unmapBuffer();
+ }
+
// no data may be pending
llassert(mMappedVertexRegions.empty());
llassert(mMappedIndexRegions.empty());