From 14f6bbadef2c39e58a3b54c0c6212949acf50e45 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Mon, 8 Aug 2011 15:29:23 -0500 Subject: SH-2242 Work in progress migrating to glVertexAttrib everywhere --- indra/llrender/llvertexbuffer.cpp | 352 ++++++++++++++++++++++++++++++-------- 1 file changed, 283 insertions(+), 69 deletions(-) (limited to 'indra/llrender/llvertexbuffer.cpp') diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 1180afa631..30f73bf2c6 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -130,6 +130,7 @@ S32 LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_MAX] = sizeof(LLVector2), // TYPE_TEXCOORD2, sizeof(LLVector2), // TYPE_TEXCOORD3, sizeof(LLColor4U), // TYPE_COLOR, + sizeof(U8), // TYPE_EMISSIVE sizeof(LLVector4), // TYPE_BINORMAL, sizeof(F32), // TYPE_WEIGHT, sizeof(LLVector4), // TYPE_WEIGHT4, @@ -156,36 +157,79 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask) llerrs << "Cannot use LLGLImmediate and LLVertexBuffer simultaneously!" << llendl; }*/ + LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; + if (sLastMask != data_mask) { + llassert(!LLGLSLShader::sNoFixedFunction || shader != NULL); + static LLGLSLShader* last_shader = LLGLSLShader::sCurBoundShaderPtr; + llassert(sLastMask == 0 || last_shader == shader); + last_shader = shader; + U32 mask[] = { MAP_VERTEX, MAP_NORMAL, MAP_TEXCOORD0, MAP_COLOR, + MAP_EMISSIVE, + MAP_WEIGHT, + MAP_WEIGHT4, + MAP_BINORMAL, + MAP_CLOTHWEIGHT, }; + U32 type[] = + { + TYPE_VERTEX, + TYPE_NORMAL, + TYPE_TEXCOORD0, + TYPE_COLOR, + TYPE_EMISSIVE, + TYPE_WEIGHT, + TYPE_WEIGHT4, + TYPE_BINORMAL, + TYPE_CLOTHWEIGHT, + }; + GLenum array[] = { GL_VERTEX_ARRAY, GL_NORMAL_ARRAY, GL_TEXTURE_COORD_ARRAY, GL_COLOR_ARRAY, + 0, + 0, + 0, + 0, + 0, }; BOOL error = FALSE; - for (U32 i = 0; i < 4; ++i) + for (U32 i = 0; i < 9; ++i) { + S32 loc = -1; + if (shader) + { + loc = shader->getAttribLocation(type[i]); + } + if (sLastMask & mask[i]) { //was enabled - if (!(data_mask & mask[i]) && i > 0) + if (!(data_mask & mask[i])) { //needs to be disabled - glDisableClientState(array[i]); + if (loc >= 0) + { + glDisableVertexAttribArrayARB(loc); + } + else if (!shader) + { + glDisableClientState(array[i]); + } } - else if (gDebugGL) - { //needs to be enabled, make sure it was (DEBUG TEMPORARY) - if (i > 0 && !glIsEnabled(array[i])) + else if (gDebugGL && !shader && array[i]) + { //needs to be enabled, make sure it was (DEBUG) + if (loc < 0 && !glIsEnabled(array[i])) { if (gDebugSession) { @@ -201,11 +245,18 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask) } else { //was disabled - if (data_mask & mask[i] && i > 0) + if (data_mask & mask[i]) { //needs to be enabled - glEnableClientState(array[i]); + if (loc >= 0) + { + glEnableVertexAttribArrayARB(loc); + } + else if (!shader) + { + glEnableClientState(array[i]); + } } - else if (gDebugGL && i > 0 && glIsEnabled(array[i])) + else if (!shader && array[i] && gDebugGL && glIsEnabled(array[i])) { //needs to be disabled, make sure it was (DEBUG TEMPORARY) if (gDebugSession) { @@ -232,62 +283,71 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask) MAP_TEXCOORD3 }; + U32 type_tc[] = + { + TYPE_TEXCOORD1, + TYPE_TEXCOORD2, + TYPE_TEXCOORD3 + }; + for (U32 i = 0; i < 3; i++) { + S32 loc = -1; + if (shader) + { + loc = shader->getAttribLocation(type_tc[i]); + } + if (sLastMask & map_tc[i]) { if (!(data_mask & map_tc[i])) - { - glClientActiveTextureARB(GL_TEXTURE1_ARB+i); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glClientActiveTextureARB(GL_TEXTURE0_ARB); + { //disable + if (loc >= 0) + { + glDisableVertexAttribArrayARB(loc); + } + else if (!shader) + { + glClientActiveTextureARB(GL_TEXTURE1_ARB+i); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glClientActiveTextureARB(GL_TEXTURE0_ARB); + } } } else if (data_mask & map_tc[i]) { - glClientActiveTextureARB(GL_TEXTURE1_ARB+i); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glClientActiveTextureARB(GL_TEXTURE0_ARB); + if (loc >= 0) + { + glEnableVertexAttribArrayARB(loc); + } + else if (!shader) + { + glClientActiveTextureARB(GL_TEXTURE1_ARB+i); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glClientActiveTextureARB(GL_TEXTURE0_ARB); + } } } - if (sLastMask & MAP_BINORMAL) + if (!shader) { - if (!(data_mask & MAP_BINORMAL)) + if (sLastMask & MAP_BINORMAL) { - glClientActiveTextureARB(GL_TEXTURE2_ARB); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glClientActiveTextureARB(GL_TEXTURE0_ARB); + if (!(data_mask & MAP_BINORMAL)) + { + glClientActiveTextureARB(GL_TEXTURE2_ARB); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glClientActiveTextureARB(GL_TEXTURE0_ARB); + } } - } - else if (data_mask & MAP_BINORMAL) - { - glClientActiveTextureARB(GL_TEXTURE2_ARB); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glClientActiveTextureARB(GL_TEXTURE0_ARB); - } - - if (sLastMask & MAP_WEIGHT4) - { - if (sWeight4Loc < 0) + else if (data_mask & MAP_BINORMAL) { - llerrs << "Weighting disabled but vertex buffer still bound!" << llendl; - } - - if (!(data_mask & MAP_WEIGHT4)) - { //disable 4-component skin weight - glDisableVertexAttribArrayARB(sWeight4Loc); - } - } - else if (data_mask & MAP_WEIGHT4) - { - if (sWeight4Loc >= 0) - { //enable 4-component skin weight - glEnableVertexAttribArrayARB(sWeight4Loc); + glClientActiveTextureARB(GL_TEXTURE2_ARB); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glClientActiveTextureARB(GL_TEXTURE0_ARB); } } - - + sLastMask = data_mask; } } @@ -1592,6 +1652,10 @@ bool LLVertexBuffer::getColorStrider(LLStrider& strider, S32 index, S { return VertexBufferStrider::get(*this, strider, index, count, map_range); } +bool LLVertexBuffer::getEmissiveStrider(LLStrider& strider, S32 index, S32 count, bool map_range) +{ + return VertexBufferStrider::get(*this, strider, index, count, map_range); +} bool LLVertexBuffer::getWeightStrider(LLStrider& strider, S32 index, S32 count, bool map_range) { return VertexBufferStrider::get(*this, strider, index, count, map_range); @@ -1810,46 +1874,166 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const llerrs << "LLVertexBuffer::setupVertexBuffer missing required components for supplied data mask." << llendl; } + LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; + + //assert that fixed function is allowed OR a shader is currently bound + llassert(!LLGLSLShader::sNoFixedFunction || shader != NULL); + if (data_mask & MAP_NORMAL) { - glNormalPointer(GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_NORMAL], (void*)(base + mOffsets[TYPE_NORMAL])); + S32 loc = -1; + if (shader) + { + loc = shader->getAttribLocation(TYPE_NORMAL); + } + + if (loc >= 0) + { + glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_NORMAL], (void*)(base + mOffsets[TYPE_NORMAL])); + } + else if (!shader) + { + glNormalPointer(GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_NORMAL], (void*)(base + mOffsets[TYPE_NORMAL])); + } } if (data_mask & MAP_TEXCOORD3) { - glClientActiveTextureARB(GL_TEXTURE3_ARB); - glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD3], (void*)(base + mOffsets[TYPE_TEXCOORD3])); - glClientActiveTextureARB(GL_TEXTURE0_ARB); + S32 loc = -1; + if (shader) + { + loc = shader->getAttribLocation(TYPE_TEXCOORD3); + } + + if (loc >= 0) + { + glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD3], (void*)(base + mOffsets[TYPE_TEXCOORD3])); + } + else if (!shader) + { + glClientActiveTextureARB(GL_TEXTURE3_ARB); + glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD3], (void*)(base + mOffsets[TYPE_TEXCOORD3])); + glClientActiveTextureARB(GL_TEXTURE0_ARB); + } } if (data_mask & MAP_TEXCOORD2) { - glClientActiveTextureARB(GL_TEXTURE2_ARB); - glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD2], (void*)(base + mOffsets[TYPE_TEXCOORD2])); - glClientActiveTextureARB(GL_TEXTURE0_ARB); + S32 loc = -1; + if (shader) + { + loc = shader->getAttribLocation(TYPE_TEXCOORD2); + } + + if (loc >= 0) + { + glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD2], (void*)(base + mOffsets[TYPE_TEXCOORD2])); + } + else if (!shader) + { + glClientActiveTextureARB(GL_TEXTURE2_ARB); + glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD2], (void*)(base + mOffsets[TYPE_TEXCOORD2])); + glClientActiveTextureARB(GL_TEXTURE0_ARB); + } } if (data_mask & MAP_TEXCOORD1) { - glClientActiveTextureARB(GL_TEXTURE1_ARB); - glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], (void*)(base + mOffsets[TYPE_TEXCOORD1])); - glClientActiveTextureARB(GL_TEXTURE0_ARB); + S32 loc = -1; + if (shader) + { + loc = shader->getAttribLocation(TYPE_TEXCOORD1); + } + + if (loc >= 0) + { + glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], (void*)(base + mOffsets[TYPE_TEXCOORD1])); + } + else if (!shader) + { + glClientActiveTextureARB(GL_TEXTURE1_ARB); + glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], (void*)(base + mOffsets[TYPE_TEXCOORD1])); + glClientActiveTextureARB(GL_TEXTURE0_ARB); + } } if (data_mask & MAP_BINORMAL) { - glClientActiveTextureARB(GL_TEXTURE2_ARB); - glTexCoordPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], (void*)(base + mOffsets[TYPE_BINORMAL])); - glClientActiveTextureARB(GL_TEXTURE0_ARB); + S32 loc = -1; + if (shader) + { + loc = shader->getAttribLocation(TYPE_BINORMAL); + } + + if (loc >= 0) + { + glVertexAttribPointerARB(loc, 3,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], (void*)(base + mOffsets[TYPE_BINORMAL])); + } + else if (!shader) + { + glClientActiveTextureARB(GL_TEXTURE2_ARB); + glTexCoordPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], (void*)(base + mOffsets[TYPE_BINORMAL])); + glClientActiveTextureARB(GL_TEXTURE0_ARB); + } } if (data_mask & MAP_TEXCOORD0) { - glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], (void*)(base + mOffsets[TYPE_TEXCOORD0])); + S32 loc = -1; + if (shader) + { + loc = shader->getAttribLocation(TYPE_TEXCOORD0); + } + + if (loc >= 0) + { + glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], (void*)(base + mOffsets[TYPE_TEXCOORD0])); + } + else if (!shader) + { + glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], (void*)(base + mOffsets[TYPE_TEXCOORD0])); + } } if (data_mask & MAP_COLOR) { - glColorPointer(4, GL_UNSIGNED_BYTE, LLVertexBuffer::sTypeSize[TYPE_COLOR], (void*)(base + mOffsets[TYPE_COLOR])); + S32 loc = -1; + if (shader) + { + loc = shader->getAttribLocation(TYPE_COLOR); + } + + if (loc >= 0) + { + glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_COLOR], (void*)(base + mOffsets[TYPE_COLOR])); + } + else if (!shader) + { + glColorPointer(4, GL_UNSIGNED_BYTE, LLVertexBuffer::sTypeSize[TYPE_COLOR], (void*)(base + mOffsets[TYPE_COLOR])); + } + } + if (data_mask & MAP_EMISSIVE) + { + S32 loc = -1; + if (shader) + { + loc = shader->getAttribLocation(TYPE_EMISSIVE); + } + + if (loc >= 0) + { + glVertexAttribPointerARB(loc, 1, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], (void*)(base + mOffsets[TYPE_EMISSIVE])); + } } - if (data_mask & MAP_WEIGHT) { - glVertexAttribPointerARB(1, 1, GL_FLOAT, FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT], (void*)(base + mOffsets[TYPE_WEIGHT])); + S32 loc = -1; + if (shader) + { + loc = shader->getAttribLocation(TYPE_WEIGHT); + } + + if (loc < 0) + { //legacy behavior, some shaders have weight hardcoded to location 1 + loc = 1; + } + + glVertexAttribPointerARB(loc, 1, GL_FLOAT, FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT], (void*)(base + mOffsets[TYPE_WEIGHT])); + } if (data_mask & MAP_WEIGHT4 && sWeight4Loc != -1) @@ -1859,17 +2043,47 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const if (data_mask & MAP_CLOTHWEIGHT) { - glVertexAttribPointerARB(4, 4, GL_FLOAT, TRUE, LLVertexBuffer::sTypeSize[TYPE_CLOTHWEIGHT], (void*)(base + mOffsets[TYPE_CLOTHWEIGHT])); + S32 loc = -1; + if (shader) + { + loc = shader->getAttribLocation(TYPE_CLOTHWEIGHT); + } + + if (loc < 0) + { //legacy behavior, some shaders have weight hardcoded to location 4 + loc = 4; + } + glVertexAttribPointerARB(loc, 4, GL_FLOAT, TRUE, LLVertexBuffer::sTypeSize[TYPE_CLOTHWEIGHT], (void*)(base + mOffsets[TYPE_CLOTHWEIGHT])); } if (data_mask & MAP_VERTEX) { - if (data_mask & MAP_TEXTURE_INDEX) + S32 loc = -1; + if (shader) { - glVertexPointer(4,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0)); + loc = shader->getAttribLocation(TYPE_VERTEX); } - else + + if (loc >= 0) { - glVertexPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0)); + if (data_mask & MAP_TEXTURE_INDEX) + { + glVertexAttribPointerARB(loc, 4,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0)); + } + else + { + glVertexAttribPointerARB(loc, 3,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0)); + } + } + else if (!shader) + { + if (data_mask & MAP_TEXTURE_INDEX) + { + glVertexPointer(4,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0)); + } + else + { + glVertexPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0)); + } } } -- cgit v1.2.3 From 2ee815478043c4d5845f094f744a055707dba0e0 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 10 Aug 2011 13:01:14 -0500 Subject: SH-2238, SH-2223, SH-SH-2242 glVertexAttrib throughout main render pipeline complete, preview renders and debug displays still pending. Also fixed a render glitch and a crash (JIRAs listed). --- indra/llrender/llvertexbuffer.cpp | 62 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 59 insertions(+), 3 deletions(-) (limited to 'indra/llrender/llvertexbuffer.cpp') diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index a5977d658d..5d19168842 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -62,7 +62,6 @@ U32 LLVertexBuffer::sAllocatedBytes = 0; BOOL LLVertexBuffer::sMapped = FALSE; BOOL LLVertexBuffer::sUseStreamDraw = TRUE; BOOL LLVertexBuffer::sPreferStreamDraw = FALSE; -S32 LLVertexBuffer::sWeight4Loc = -1; std::vector LLVertexBuffer::sDeleteList; @@ -355,6 +354,8 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask) //static void LLVertexBuffer::drawArrays(U32 mode, const std::vector& pos, const std::vector& norm) { + llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL); + U32 count = pos.size(); llassert_always(norm.size() >= pos.size()); llassert_always(count > 0) ; @@ -369,6 +370,49 @@ void LLVertexBuffer::drawArrays(U32 mode, const std::vector& pos, con glDrawArrays(sGLMode[mode], 0, count); } +//static +void LLVertexBuffer::drawElements(U32 mode, const LLVector4a* pos, const LLVector2* tc, S32 num_indices, const U16* indicesp) +{ + llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL); + + U32 mask = LLVertexBuffer::MAP_VERTEX; + if (tc) + { + mask = mask | LLVertexBuffer::MAP_TEXCOORD0; + } + + unbind(); + + setupClientArrays(mask); + + LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; + + if (shader) + { + S32 loc = shader->getAttribLocation(LLVertexBuffer::TYPE_VERTEX); + if (loc > -1) + { + glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, 16, pos); + + if (tc) + { + loc = shader->getAttribLocation(LLVertexBuffer::TYPE_TEXCOORD0); + if (loc > -1) + { + glVertexAttribPointerARB(loc, 2, GL_FLOAT, GL_FALSE, 0, tc); + } + } + } + } + else + { + glTexCoordPointer(2, GL_FLOAT, 0, tc); + glVertexPointer(3, GL_FLOAT, 16, pos); + } + + glDrawElements(sGLMode[mode], num_indices, GL_UNSIGNED_SHORT, indicesp); +} + void LLVertexBuffer::validateRange(U32 start, U32 end, U32 count, U32 indices_offset) const { if (start >= (U32) mRequestedNumVerts || @@ -403,6 +447,7 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi validateRange(start, end, count, indices_offset); llassert(mRequestedNumVerts >= 0); + llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL); if (mGLIndices != sGLRenderIndices) { @@ -431,6 +476,8 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const { + llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL); + llassert(mRequestedNumIndices >= 0); if (indices_offset >= (U32) mRequestedNumIndices || indices_offset + count > (U32) mRequestedNumIndices) @@ -463,6 +510,8 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const { + llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL); + llassert(mRequestedNumVerts >= 0); if (first >= (U32) mRequestedNumVerts || first + count > (U32) mRequestedNumVerts) @@ -2037,9 +2086,16 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const } - if (data_mask & MAP_WEIGHT4 && sWeight4Loc != -1) + if (data_mask & MAP_WEIGHT4) { - glVertexAttribPointerARB(sWeight4Loc, 4, GL_FLOAT, FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT4], (void*)(base+mOffsets[TYPE_WEIGHT4])); + if (shader) + { + S32 loc = shader->getAttribLocation(TYPE_WEIGHT4); + if (loc > -1) + { + glVertexAttribPointerARB(loc, 4, GL_FLOAT, FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT4], (void*)(base+mOffsets[TYPE_WEIGHT4])); + } + } } if (data_mask & MAP_CLOTHWEIGHT) -- cgit v1.2.3 From 7821ff23baafff4e7712a126c17c3947e7b4989e Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Sat, 27 Aug 2011 00:38:53 -0500 Subject: SH-2242 Physics shape display works again, added asserts to flush out areas where state being consumed by a shader does not match state being provided by vertex buffers. --- indra/llrender/llvertexbuffer.cpp | 50 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) (limited to 'indra/llrender/llvertexbuffer.cpp') diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 5d19168842..86352215ff 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -364,8 +364,26 @@ void LLVertexBuffer::drawArrays(U32 mode, const std::vector& pos, con setupClientArrays(MAP_VERTEX | MAP_NORMAL); - glVertexPointer(3, GL_FLOAT, 0, pos[0].mV); - glNormalPointer(GL_FLOAT, 0, norm[0].mV); + LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; + + if (shader) + { + S32 loc = shader->getAttribLocation(LLVertexBuffer::TYPE_VERTEX); + if (loc > -1) + { + glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, 0, pos[0].mV); + } + loc = shader->getAttribLocation(LLVertexBuffer::TYPE_NORMAL); + if (loc > -1) + { + glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, 0, norm[0].mV); + } + } + else + { + glVertexPointer(3, GL_FLOAT, 0, pos[0].mV); + glNormalPointer(GL_FLOAT, 0, norm[0].mV); + } glDrawArrays(sGLMode[mode], 0, count); } @@ -1730,6 +1748,34 @@ void LLVertexBuffer::setBuffer(U32 data_mask, S32 type) //set up pointers if the data mask is different ... BOOL setup = (sLastMask != data_mask); + if (gDebugGL && data_mask != 0) + { + LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; + if (shader) + { + U32 required_mask = 0; + for (U32 i = 0; i < LLVertexBuffer::TYPE_MAX; ++i) + { + if (shader->getAttribLocation(i) > -1) + { + U32 required = 1 << i; + if ((data_mask & required) == 0) + { + llwarns << "Missing attribute: " << i << llendl; + } + + required_mask |= required; + + } + } + + if ((data_mask & required_mask) != required_mask) + { + llerrs << "Shader consumption mismatches data provision." << llendl; + } + } + } + if (useVBOs()) { if (mGLBuffer && (mGLBuffer != sGLRenderBuffer || !sVBOActive)) -- cgit v1.2.3 From 7c95af74f195c9ec4ebc0fc0264d98cd4a85be49 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 14 Sep 2011 16:30:45 -0500 Subject: SH-2243 work in progress -- application side matrix stack management --- indra/llrender/llvertexbuffer.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'indra/llrender/llvertexbuffer.cpp') diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index bb8f067e8d..090da765ac 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -63,10 +63,8 @@ U32 LLVertexBuffer::sAllocatedBytes = 0; BOOL LLVertexBuffer::sMapped = FALSE; BOOL LLVertexBuffer::sUseStreamDraw = TRUE; BOOL LLVertexBuffer::sPreferStreamDraw = FALSE; - std::vector LLVertexBuffer::sDeleteList; - const U32 FENCE_WAIT_TIME_NANOSECONDS = 10000; //1 ms class LLGLSyncFence : public LLGLFence @@ -149,6 +147,7 @@ U32 LLVertexBuffer::sGLMode[LLRender::NUM_MODES] = GL_LINE_LOOP, }; + //static void LLVertexBuffer::setupClientArrays(U32 data_mask) { @@ -356,6 +355,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask) void LLVertexBuffer::drawArrays(U32 mode, const std::vector& pos, const std::vector& norm) { llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL); + gGL.syncMatrices(); U32 count = pos.size(); llassert_always(norm.size() >= pos.size()); @@ -394,6 +394,8 @@ void LLVertexBuffer::drawElements(U32 mode, const LLVector4a* pos, const LLVecto { llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL); + gGL.syncMatrices(); + U32 mask = LLVertexBuffer::MAP_VERTEX; if (tc) { @@ -465,6 +467,8 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi { validateRange(start, end, count, indices_offset); + gGL.syncMatrices(); + llassert(mRequestedNumVerts >= 0); llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL); @@ -497,6 +501,8 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const { llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL); + gGL.syncMatrices(); + llassert(mRequestedNumIndices >= 0); if (indices_offset >= (U32) mRequestedNumIndices || indices_offset + count > (U32) mRequestedNumIndices) @@ -530,7 +536,9 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const { llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL); - + + gGL.syncMatrices(); + llassert(mRequestedNumVerts >= 0); if (first >= (U32) mRequestedNumVerts || first + count > (U32) mRequestedNumVerts) -- cgit v1.2.3 From a2d08a6d80c4be7456d30f728da1838e63eb397f Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 22 Sep 2011 00:10:57 -0500 Subject: SH-2244 Fix "RenderGLCoreProfile" actually make a core profile context and modify viewer to run under said context without generating errors. --- indra/llrender/llvertexbuffer.cpp | 191 +++++++++++++++++++++++++++++++------- 1 file changed, 155 insertions(+), 36 deletions(-) (limited to 'indra/llrender/llvertexbuffer.cpp') diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 090da765ac..f822a7babd 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -55,6 +55,7 @@ S32 LLVertexBuffer::sMappedCount = 0; BOOL LLVertexBuffer::sDisableVBOMapping = FALSE ; BOOL LLVertexBuffer::sEnableVBOs = TRUE; U32 LLVertexBuffer::sGLRenderBuffer = 0; +U32 LLVertexBuffer::sGLRenderArray = 0; U32 LLVertexBuffer::sGLRenderIndices = 0; U32 LLVertexBuffer::sLastMask = 0; BOOL LLVertexBuffer::sVBOActive = FALSE; @@ -149,7 +150,7 @@ U32 LLVertexBuffer::sGLMode[LLRender::NUM_MODES] = //static -void LLVertexBuffer::setupClientArrays(U32 data_mask) +void LLVertexBuffer::setupClientArrays(U32 data_mask, U32& ref_mask) { /*if (LLGLImmediate::sStarted) { @@ -158,13 +159,10 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask) LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; - if (sLastMask != data_mask) + if (ref_mask != data_mask) { llassert(!LLGLSLShader::sNoFixedFunction || shader != NULL); - static LLGLSLShader* last_shader = LLGLSLShader::sCurBoundShaderPtr; - llassert(sLastMask == 0 || last_shader == shader); - last_shader = shader; - + U32 mask[] = { MAP_VERTEX, @@ -213,7 +211,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask) loc = shader->getAttribLocation(type[i]); } - if (sLastMask & mask[i]) + if (ref_mask & mask[i]) { //was enabled if (!(data_mask & mask[i])) { //needs to be disabled @@ -297,7 +295,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask) loc = shader->getAttribLocation(type_tc[i]); } - if (sLastMask & map_tc[i]) + if (ref_mask & map_tc[i]) { if (!(data_mask & map_tc[i])) { //disable @@ -330,7 +328,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask) if (!shader) { - if (sLastMask & MAP_BINORMAL) + if (ref_mask & MAP_BINORMAL) { if (!(data_mask & MAP_BINORMAL)) { @@ -347,7 +345,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask) } } - sLastMask = data_mask; + ref_mask = data_mask; } } @@ -589,6 +587,12 @@ void LLVertexBuffer::initClass(bool use_vbo, bool no_vbo_mapping) //static void LLVertexBuffer::unbind() { + if (sGLRenderArray) + { + glBindVertexArray(0); + sGLRenderArray = 0; + } + if (sVBOActive) { glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); @@ -640,6 +644,8 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) : mRequestedNumIndices(-1), mUsage(usage), mGLBuffer(0), + mGLArray(0), + mLastMask(0), mGLIndices(0), mMappedData(NULL), mMappedIndexData(NULL), @@ -669,12 +675,23 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) : mUsage = GL_STREAM_DRAW_ARB; } + if (mUsage == 0 && LLRender::sGLCoreProfile) + { //MUST use VBOs for all rendering + mUsage = GL_STREAM_DRAW_ARB; + } + //zero out offsets for (U32 i = 0; i < TYPE_MAX; i++) { mOffsets[i] = 0; } + //initialize cached attrib pointers + for (U32 i = 0; i < LL_MAX_VERTEX_ATTRIB_LOCATION; i++) + { + mLastPointer[i] = (void*) 0xFFFFFFFF; + } + mTypeMask = typemask; mSize = 0; mAlignedOffset = 0; @@ -732,6 +749,12 @@ LLVertexBuffer::~LLVertexBuffer() LLMemType mt2(LLMemType::MTYPE_VERTEX_DESTRUCTOR); destroyGLBuffer(); destroyGLIndices(); + + if (mGLArray) + { + glDeleteVertexArrays(1, &mGLArray); + } + sCount--; if (mFence) @@ -1041,6 +1064,11 @@ void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create) { createGLBuffer(); createGLIndices(); + + if (gGLManager.mHasVertexArrayObject && useVBOs()) + { + glGenVertexArrays(1, &mGLArray); + } } sAllocatedBytes += getSize() + getIndicesSize(); @@ -1762,7 +1790,8 @@ void LLVertexBuffer::setBuffer(U32 data_mask, S32 type) { LLMemType mt2(LLMemType::MTYPE_VERTEX_SET_BUFFER); //set up pointers if the data mask is different ... - BOOL setup = (sLastMask != data_mask); + U32& ref_mask = mGLArray ? mLastMask : sLastMask; + BOOL setup = (ref_mask != data_mask); if (gDebugGL && data_mask != 0) { @@ -1794,15 +1823,19 @@ void LLVertexBuffer::setBuffer(U32 data_mask, S32 type) if (useVBOs()) { + if (mGLArray && mGLArray != sGLRenderArray) + { + glBindVertexArray(mGLArray); + sGLRenderArray = mGLArray; + } + if (mGLBuffer && (mGLBuffer != sGLRenderBuffer || !sVBOActive)) { /*if (sMapped) { llerrs << "VBO bound while another VBO mapped!" << llendl; }*/ - stop_glerror(); glBindBufferARB(GL_ARRAY_BUFFER_ARB, mGLBuffer); - stop_glerror(); sBindCount++; sVBOActive = TRUE; setup = TRUE; // ... or the bound buffer changed @@ -1813,13 +1846,12 @@ void LLVertexBuffer::setBuffer(U32 data_mask, S32 type) { llerrs << "VBO bound while another VBO mapped!" << llendl; }*/ - stop_glerror(); glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mGLIndices); stop_glerror(); sBindCount++; sIBOActive = TRUE; } - + BOOL error = FALSE; if (gDebugGL) { @@ -1957,7 +1989,10 @@ void LLVertexBuffer::setBuffer(U32 data_mask, S32 type) } } - setupClientArrays(data_mask); + if (data_mask) + { + setupClientArrays(data_mask, ref_mask); + } if (mGLIndices) { @@ -1998,10 +2033,18 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const { loc = shader->getAttribLocation(TYPE_NORMAL); } - + if (loc >= 0) { - glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_NORMAL], (void*)(base + mOffsets[TYPE_NORMAL])); + void* ptr = (void*)(base + mOffsets[TYPE_NORMAL]); + if (mLastPointer[loc] != ptr) + { + glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_NORMAL], ptr); + } + if (mGLArray) + { + mLastPointer[loc] = ptr; + } } else if (!shader) { @@ -2018,7 +2061,15 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const if (loc >= 0) { - glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD3], (void*)(base + mOffsets[TYPE_TEXCOORD3])); + void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD3]); + if (mLastPointer[loc] != ptr) + { + glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD3], ptr); + } + if (mGLArray) + { + mLastPointer[loc] = ptr; + } } else if (!shader) { @@ -2037,7 +2088,15 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const if (loc >= 0) { - glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD2], (void*)(base + mOffsets[TYPE_TEXCOORD2])); + void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD2]); + if (mLastPointer[loc] != ptr) + { + glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD2], ptr); + } + if (mGLArray) + { + mLastPointer[loc] = ptr; + } } else if (!shader) { @@ -2056,7 +2115,15 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const if (loc >= 0) { - glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], (void*)(base + mOffsets[TYPE_TEXCOORD1])); + void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD1]); + if (mLastPointer[loc] != ptr) + { + glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], ptr); + } + if (mGLArray) + { + mLastPointer[loc] = ptr; + } } else if (!shader) { @@ -2075,7 +2142,15 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const if (loc >= 0) { - glVertexAttribPointerARB(loc, 3,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], (void*)(base + mOffsets[TYPE_BINORMAL])); + void* ptr = (void*)(base + mOffsets[TYPE_BINORMAL]); + if (mLastPointer[loc] != ptr) + { + glVertexAttribPointerARB(loc, 3,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], ptr); + } + if (mGLArray) + { + mLastPointer[loc] = ptr; + } } else if (!shader) { @@ -2094,7 +2169,15 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const if (loc >= 0) { - glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], (void*)(base + mOffsets[TYPE_TEXCOORD0])); + void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD0]); + if (mLastPointer[loc] != ptr) + { + glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], ptr); + } + if (mGLArray) + { + mLastPointer[loc] = ptr; + } } else if (!shader) { @@ -2111,7 +2194,15 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const if (loc >= 0) { - glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_COLOR], (void*)(base + mOffsets[TYPE_COLOR])); + void* ptr = (void*)(base + mOffsets[TYPE_COLOR]); + if (mLastPointer[loc] != ptr) + { + glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_COLOR], ptr); + } + if (mGLArray) + { + mLastPointer[loc] = ptr; + } } else if (!shader) { @@ -2128,7 +2219,15 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const if (loc >= 0) { - glVertexAttribPointerARB(loc, 1, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], (void*)(base + mOffsets[TYPE_EMISSIVE])); + void* ptr = (void*)(base + mOffsets[TYPE_EMISSIVE]); + if (mLastPointer[loc] != ptr) + { + glVertexAttribPointerARB(loc, 1, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr); + } + if (mGLArray) + { + mLastPointer[loc] = ptr; + } } } if (data_mask & MAP_WEIGHT) @@ -2139,13 +2238,18 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const loc = shader->getAttribLocation(TYPE_WEIGHT); } - if (loc < 0) - { //legacy behavior, some shaders have weight hardcoded to location 1 - loc = 1; + if (loc > -1) + { + void* ptr = (void*)(base + mOffsets[TYPE_WEIGHT]); + if (mLastPointer[loc] != ptr) + { + glVertexAttribPointerARB(loc, 1, GL_FLOAT, FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT], ptr); + } + if (mGLArray) + { + mLastPointer[loc] = ptr; + } } - - glVertexAttribPointerARB(loc, 1, GL_FLOAT, FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT], (void*)(base + mOffsets[TYPE_WEIGHT])); - } if (data_mask & MAP_WEIGHT4) @@ -2155,7 +2259,15 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const S32 loc = shader->getAttribLocation(TYPE_WEIGHT4); if (loc > -1) { - glVertexAttribPointerARB(loc, 4, GL_FLOAT, FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT4], (void*)(base+mOffsets[TYPE_WEIGHT4])); + void* ptr = (void*)(base+mOffsets[TYPE_WEIGHT4]); + if (mLastPointer[loc] != ptr) + { + glVertexAttribPointerARB(loc, 4, GL_FLOAT, FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT4], ptr); + } + if (mGLArray) + { + mLastPointer[loc] = ptr; + } } } } @@ -2168,11 +2280,18 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const loc = shader->getAttribLocation(TYPE_CLOTHWEIGHT); } - if (loc < 0) - { //legacy behavior, some shaders have weight hardcoded to location 4 - loc = 4; + if (loc > -1) + { + void* ptr = (void*)(base + mOffsets[TYPE_CLOTHWEIGHT]); + if (mLastPointer[loc] != ptr) + { + glVertexAttribPointerARB(loc, 4, GL_FLOAT, TRUE, LLVertexBuffer::sTypeSize[TYPE_CLOTHWEIGHT], ptr); + } + if (mGLArray) + { + mLastPointer[loc] = ptr; + } } - glVertexAttribPointerARB(loc, 4, GL_FLOAT, TRUE, LLVertexBuffer::sTypeSize[TYPE_CLOTHWEIGHT], (void*)(base + mOffsets[TYPE_CLOTHWEIGHT])); } if (data_mask & MAP_VERTEX) { -- cgit v1.2.3 From 3115e250ffded1270531fb6bdb3df8b2214fba1a Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 22 Sep 2011 00:57:47 -0500 Subject: SH-2244 Don't use VAO's outside of core profile (performance improvement) --- indra/llrender/llvertexbuffer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llrender/llvertexbuffer.cpp') diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index f822a7babd..75c7153222 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -1065,7 +1065,7 @@ void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create) createGLBuffer(); createGLIndices(); - if (gGLManager.mHasVertexArrayObject && useVBOs()) + if (gGLManager.mHasVertexArrayObject && useVBOs() && LLRender::sGLCoreProfile) { glGenVertexArrays(1, &mGLArray); } -- cgit v1.2.3 From d3f614e2e971fd442660ba6c1645830d3bf0b6cf Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 22 Sep 2011 13:41:26 -0500 Subject: SH-2244 fix flickering shadows and occlusion culling. --- indra/llrender/llvertexbuffer.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'indra/llrender/llvertexbuffer.cpp') diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 75c7153222..40a96eb407 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -1989,11 +1989,8 @@ void LLVertexBuffer::setBuffer(U32 data_mask, S32 type) } } - if (data_mask) - { - setupClientArrays(data_mask, ref_mask); - } - + setupClientArrays(data_mask, ref_mask); + if (mGLIndices) { sGLRenderIndices = mGLIndices; -- cgit v1.2.3 From b9926e8f57787eb146b06260cc3d0260e34330ce Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 23 Sep 2011 02:29:53 -0500 Subject: SH-2244 Better VAO support -- still slower than non-VAO implementation for some reason --- indra/llrender/llvertexbuffer.cpp | 862 +++++++++++++++++++------------------- 1 file changed, 426 insertions(+), 436 deletions(-) (limited to 'indra/llrender/llvertexbuffer.cpp') diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 40a96eb407..a48669a300 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -150,19 +150,18 @@ U32 LLVertexBuffer::sGLMode[LLRender::NUM_MODES] = //static -void LLVertexBuffer::setupClientArrays(U32 data_mask, U32& ref_mask) +void LLVertexBuffer::setupClientArrays(U32 data_mask, U32& sLastMask) { /*if (LLGLImmediate::sStarted) { llerrs << "Cannot use LLGLImmediate and LLVertexBuffer simultaneously!" << llendl; }*/ - LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; - - if (ref_mask != data_mask) + if (sLastMask != data_mask) { - llassert(!LLGLSLShader::sNoFixedFunction || shader != NULL); - + + LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; + U32 mask[] = { MAP_VERTEX, @@ -174,6 +173,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask, U32& ref_mask) MAP_WEIGHT4, MAP_BINORMAL, MAP_CLOTHWEIGHT, + MAP_TEXTURE_INDEX, }; U32 type[] = @@ -187,6 +187,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask, U32& ref_mask) TYPE_WEIGHT4, TYPE_BINORMAL, TYPE_CLOTHWEIGHT, + TYPE_TEXTURE_INDEX-1, }; GLenum array[] = @@ -200,18 +201,20 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask, U32& ref_mask) 0, 0, 0, + 0, }; BOOL error = FALSE; - for (U32 i = 0; i < 9; ++i) + for (U32 i = 0; i < 10; ++i) { S32 loc = -1; - if (shader) + + if (LLGLSLShader::sNoFixedFunction) { - loc = shader->getAttribLocation(type[i]); + loc = type[i]; } - - if (ref_mask & mask[i]) + + if (sLastMask & mask[i]) { //was enabled if (!(data_mask & mask[i])) { //needs to be disabled @@ -219,12 +222,12 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask, U32& ref_mask) { glDisableVertexAttribArrayARB(loc); } - else if (!shader) + else { glDisableClientState(array[i]); } } - else if (gDebugGL && !shader && array[i]) + else if (gDebugGL && !LLGLSLShader::sNoFixedFunction && array[i]) { //needs to be enabled, make sure it was (DEBUG) if (loc < 0 && !glIsEnabled(array[i])) { @@ -248,12 +251,12 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask, U32& ref_mask) { glEnableVertexAttribArrayARB(loc); } - else if (!shader) + else { glEnableClientState(array[i]); } } - else if (!shader && array[i] && gDebugGL && glIsEnabled(array[i])) + else if (!LLGLSLShader::sNoFixedFunction && array[i] && gDebugGL && glIsEnabled(array[i])) { //needs to be disabled, make sure it was (DEBUG TEMPORARY) if (gDebugSession) { @@ -290,12 +293,13 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask, U32& ref_mask) for (U32 i = 0; i < 3; i++) { S32 loc = -1; - if (shader) + + if (LLGLSLShader::sNoFixedFunction) { - loc = shader->getAttribLocation(type_tc[i]); + loc = type_tc[i]; } - if (ref_mask & map_tc[i]) + if (sLastMask & map_tc[i]) { if (!(data_mask & map_tc[i])) { //disable @@ -303,7 +307,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask, U32& ref_mask) { glDisableVertexAttribArrayARB(loc); } - else if (!shader) + else { glClientActiveTextureARB(GL_TEXTURE1_ARB+i); glDisableClientState(GL_TEXTURE_COORD_ARRAY); @@ -317,7 +321,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask, U32& ref_mask) { glEnableVertexAttribArrayARB(loc); } - else if (!shader) + else { glClientActiveTextureARB(GL_TEXTURE1_ARB+i); glEnableClientState(GL_TEXTURE_COORD_ARRAY); @@ -326,9 +330,9 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask, U32& ref_mask) } } - if (!shader) + if (!LLGLSLShader::sNoFixedFunction) { - if (ref_mask & MAP_BINORMAL) + if (sLastMask & MAP_BINORMAL) { if (!(data_mask & MAP_BINORMAL)) { @@ -345,7 +349,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask, U32& ref_mask) } } - ref_mask = data_mask; + sLastMask = data_mask; } } @@ -367,12 +371,12 @@ void LLVertexBuffer::drawArrays(U32 mode, const std::vector& pos, con if (shader) { - S32 loc = shader->getAttribLocation(LLVertexBuffer::TYPE_VERTEX); + S32 loc = LLVertexBuffer::TYPE_VERTEX; if (loc > -1) { glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, 0, pos[0].mV); } - loc = shader->getAttribLocation(LLVertexBuffer::TYPE_NORMAL); + loc = LLVertexBuffer::TYPE_NORMAL; if (loc > -1) { glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, 0, norm[0].mV); @@ -404,23 +408,15 @@ void LLVertexBuffer::drawElements(U32 mode, const LLVector4a* pos, const LLVecto setupClientArrays(mask); - LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; - - if (shader) + if (LLGLSLShader::sNoFixedFunction) { - S32 loc = shader->getAttribLocation(LLVertexBuffer::TYPE_VERTEX); - if (loc > -1) - { - glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, 16, pos); + S32 loc = LLVertexBuffer::TYPE_VERTEX; + glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, 16, pos); - if (tc) - { - loc = shader->getAttribLocation(LLVertexBuffer::TYPE_TEXCOORD0); - if (loc > -1) - { - glVertexAttribPointerARB(loc, 2, GL_FLOAT, GL_FALSE, 0, tc); - } - } + if (tc) + { + loc = LLVertexBuffer::TYPE_TEXCOORD0; + glVertexAttribPointerARB(loc, 2, GL_FLOAT, GL_FALSE, 0, tc); } } else @@ -470,14 +466,35 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi llassert(mRequestedNumVerts >= 0); llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL); - if (mGLIndices != sGLRenderIndices) + if (mGLArray) { - llerrs << "Wrong index buffer bound." << llendl; + if (mGLArray != sGLRenderArray) + { + llerrs << "Wrong vertex array bound." << llendl; + } } + else + { + if (mGLIndices != sGLRenderIndices) + { + llerrs << "Wrong index buffer bound." << llendl; + } - if (mGLBuffer != sGLRenderBuffer) + if (mGLBuffer != sGLRenderBuffer) + { + llerrs << "Wrong vertex buffer bound." << llendl; + } + } + + if (gDebugGL && useVBOs()) { - llerrs << "Wrong vertex buffer bound." << llendl; + GLint elem = 0; + glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &elem); + + if (elem != mGLIndices) + { + llerrs << "Wrong index buffer bound!" << llendl; + } } if (mode >= LLRender::NUM_MODES) @@ -508,14 +525,24 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const llerrs << "Bad index buffer draw range: [" << indices_offset << ", " << indices_offset+count << "]" << llendl; } - if (mGLIndices != sGLRenderIndices) + if (mGLArray) { - llerrs << "Wrong index buffer bound." << llendl; + if (mGLArray != sGLRenderArray) + { + llerrs << "Wrong vertex array bound." << llendl; + } } - - if (mGLBuffer != sGLRenderBuffer) + else { - llerrs << "Wrong vertex buffer bound." << llendl; + if (mGLIndices != sGLRenderIndices) + { + llerrs << "Wrong index buffer bound." << llendl; + } + + if (mGLBuffer != sGLRenderBuffer) + { + llerrs << "Wrong vertex buffer bound." << llendl; + } } if (mode >= LLRender::NUM_MODES) @@ -544,9 +571,19 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const llerrs << "Bad vertex buffer draw range: [" << first << ", " << first+count << "]" << llendl; } - if (mGLBuffer != sGLRenderBuffer || useVBOs() != sVBOActive) + if (mGLArray) { - llerrs << "Wrong vertex buffer bound." << llendl; + if (mGLArray != sGLRenderArray) + { + llerrs << "Wrong vertex array bound." << llendl; + } + } + else + { + if (mGLBuffer != sGLRenderBuffer || useVBOs() != sVBOActive) + { + llerrs << "Wrong vertex buffer bound." << llendl; + } } if (mode >= LLRender::NUM_MODES) @@ -645,7 +682,6 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) : mUsage(usage), mGLBuffer(0), mGLArray(0), - mLastMask(0), mGLIndices(0), mMappedData(NULL), mMappedIndexData(NULL), @@ -686,12 +722,6 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) : mOffsets[i] = 0; } - //initialize cached attrib pointers - for (U32 i = 0; i < LL_MAX_VERTEX_ATTRIB_LOCATION; i++) - { - mLastPointer[i] = (void*) 0xFFFFFFFF; - } - mTypeMask = typemask; mSize = 0; mAlignedOffset = 0; @@ -1065,15 +1095,98 @@ void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create) createGLBuffer(); createGLIndices(); + if (gGLManager.mHasVertexArrayObject && useVBOs() && LLRender::sGLCoreProfile) { glGenVertexArrays(1, &mGLArray); + setupVertexArray(); } } sAllocatedBytes += getSize() + getIndicesSize(); } +void LLVertexBuffer::setupVertexArray() +{ + bindGLArray(); + + U32 attrib_size[] = + { + 3, //TYPE_VERTEX, + 3, //TYPE_NORMAL, + 2, //TYPE_TEXCOORD0, + 2, //TYPE_TEXCOORD1, + 2, //TYPE_TEXCOORD2, + 2, //TYPE_TEXCOORD3, + 4, //TYPE_COLOR, + 1, //TYPE_EMISSIVE, + 3, //TYPE_BINORMAL, + 1, //TYPE_WEIGHT, + 4, //TYPE_WEIGHT4, + 4, //TYPE_CLOTHWEIGHT, + }; + + U32 attrib_type[] = + { + GL_FLOAT, //TYPE_VERTEX, + GL_FLOAT, //TYPE_NORMAL, + GL_FLOAT, //TYPE_TEXCOORD0, + GL_FLOAT, //TYPE_TEXCOORD1, + GL_FLOAT, //TYPE_TEXCOORD2, + GL_FLOAT, //TYPE_TEXCOORD3, + GL_UNSIGNED_BYTE, //TYPE_COLOR, + GL_UNSIGNED_BYTE, //TYPE_EMISSIVE, + GL_FLOAT, //TYPE_BINORMAL, + GL_FLOAT, //TYPE_WEIGHT, + GL_FLOAT, //TYPE_WEIGHT4, + GL_FLOAT, //TYPE_CLOTHWEIGHT, + }; + + U32 attrib_normalized[] = + { + GL_FALSE, //TYPE_VERTEX, + GL_FALSE, //TYPE_NORMAL, + GL_FALSE, //TYPE_TEXCOORD0, + GL_FALSE, //TYPE_TEXCOORD1, + GL_FALSE, //TYPE_TEXCOORD2, + GL_FALSE, //TYPE_TEXCOORD3, + GL_TRUE, //TYPE_COLOR, + GL_TRUE, //TYPE_EMISSIVE, + GL_FALSE, //TYPE_BINORMAL, + GL_FALSE, //TYPE_WEIGHT, + GL_FALSE, //TYPE_WEIGHT4, + GL_FALSE, //TYPE_CLOTHWEIGHT, + }; + + bindGLBuffer(true); + bindGLIndices(true); + + for (U32 i = 0; i < TYPE_MAX; ++i) + { + if (mTypeMask & (1 << i)) + { + glEnableVertexAttribArrayARB(i); + glVertexAttribPointerARB(i, attrib_size[i], attrib_type[i], attrib_normalized[i], sTypeSize[i], (void*) mOffsets[i]); + } + else + { + glDisableVertexAttribArrayARB(i); + } + } + + if (mTypeMask & MAP_VERTEX) + { //special handling for texture index + S32 loc = TYPE_TEXTURE_INDEX-1; + glEnableVertexAttribArrayARB(loc); + glVertexAttribPointerARB(loc, 1, GL_FLOAT, GL_FALSE, sTypeSize[TYPE_VERTEX], (void*) (mOffsets[TYPE_VERTEX]+12)); + } + else + { + glDisableVertexAttribArrayARB(TYPE_TEXTURE_INDEX-1); + } + glBindVertexArray(0); +} + void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices) { llassert(newnverts >= 0); @@ -1149,8 +1262,13 @@ void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices) if (mResized && useVBOs()) { - freeClientBuffer() ; - setBuffer(0); + freeClientBuffer(); + flush(); + + if (mGLArray) + { //if size changed, offsets changed + setupVertexArray(); + } } } @@ -1215,6 +1333,7 @@ bool expand_region(LLVertexBuffer::MappedRegion& region, S32 index, S32 count) // Map for data access U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_range) { + bindGLBuffer(true); LLMemType mt2(LLMemType::MTYPE_VERTEX_MAP_BUFFER); if (mFinal) { @@ -1265,7 +1384,6 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran if (!mVertexLocked) { LLMemType mt_v(LLMemType::MTYPE_VERTEX_MAP_BUFFER_VERTICES); - setBuffer(0, type); mVertexLocked = TRUE; sMappedCount++; stop_glerror(); @@ -1380,6 +1498,7 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range) { LLMemType mt2(LLMemType::MTYPE_VERTEX_MAP_BUFFER); + bindGLIndices(true); if (mFinal) { llerrs << "LLVertexBuffer::mapIndexBuffer() called on a finalized buffer." << llendl; @@ -1427,11 +1546,21 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range) { LLMemType mt_v(LLMemType::MTYPE_VERTEX_MAP_BUFFER_INDICES); - setBuffer(0, TYPE_INDEX); mIndexLocked = TRUE; sMappedCount++; stop_glerror(); + if (gDebugGL && useVBOs()) + { + GLint elem = 0; + glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &elem); + + if (elem != mGLIndices) + { + llerrs << "Wrong index buffer bound!" << llendl; + } + } + if(sDisableVBOMapping) { map_range = false; @@ -1528,19 +1657,20 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range) } } -void LLVertexBuffer::unmapBuffer(S32 type) +void LLVertexBuffer::unmapBuffer() { LLMemType mt2(LLMemType::MTYPE_VERTEX_UNMAP_BUFFER); - if (!useVBOs() || type == -2) + if (!useVBOs()) { return ; //nothing to unmap } bool updated_all = false ; - if (mMappedData && mVertexLocked && type != TYPE_INDEX) + if (mMappedData && mVertexLocked) { - updated_all = (mIndexLocked && type < 0) ; //both vertex and index buffers done updating + bindGLBuffer(true); + updated_all = mIndexLocked; //both vertex and index buffers done updating if(sDisableVBOMapping) { @@ -1604,8 +1734,9 @@ void LLVertexBuffer::unmapBuffer(S32 type) sMappedCount--; } - if (mMappedIndexData && mIndexLocked && (type < 0 || type == TYPE_INDEX)) + if (mMappedIndexData && mIndexLocked) { + bindGLIndices(); if(sDisableVBOMapping) { if (!mMappedIndexRegions.empty()) @@ -1785,16 +1916,131 @@ bool LLVertexBuffer::getClothWeightStrider(LLStrider& strider, S32 in //---------------------------------------------------------------------------- +bool LLVertexBuffer::bindGLArray() +{ + if (mGLArray && sGLRenderArray != mGLArray) + { + glBindVertexArray(mGLArray); + sGLRenderArray = mGLArray; + return true; + } + + return false; +} + +bool LLVertexBuffer::bindGLBuffer(bool force_bind) +{ + bindGLArray(); + + bool ret = false; + + if (useVBOs() && (force_bind || (mGLBuffer && (mGLBuffer != sGLRenderBuffer || !sVBOActive)))) + { + /*if (sMapped) + { + llerrs << "VBO bound while another VBO mapped!" << llendl; + }*/ + glBindBufferARB(GL_ARRAY_BUFFER_ARB, mGLBuffer); + sGLRenderBuffer = mGLBuffer; + sBindCount++; + sVBOActive = TRUE; + + if (mGLArray) + { + llassert(sGLRenderArray == mGLArray); + //mCachedRenderBuffer = mGLBuffer; + } + + ret = true; + } + + if (gDebugGL && useVBOs()) + { + GLint elem = 0; + glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &elem); + + if (elem != mGLBuffer) + { + llerrs << "Wrong vertex buffer bound!" << llendl; + } + } + + return ret; +} + +bool LLVertexBuffer::bindGLIndices(bool force_bind) +{ + bindGLArray(); + + bool ret = false; + if (useVBOs() && (force_bind || (mGLIndices && (mGLIndices != sGLRenderIndices || !sIBOActive)))) + { + /*if (sMapped) + { + llerrs << "VBO bound while another VBO mapped!" << llendl; + }*/ + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mGLIndices); + sGLRenderIndices = mGLIndices; + stop_glerror(); + sBindCount++; + sIBOActive = TRUE; + ret = true; + } + + if (gDebugGL && useVBOs()) + { + GLint elem = 0; + glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &elem); + + if (elem != mGLIndices) + { + llerrs << "Wrong index buffer bound!" << llendl; + } + } + + return ret; +} + +void LLVertexBuffer::flush() +{ + if (useVBOs()) + { + if (mResized) + { + if (mGLBuffer) + { + stop_glerror(); + bindGLBuffer(true); + glBufferDataARB(GL_ARRAY_BUFFER_ARB, getSize(), NULL, mUsage); + stop_glerror(); + } + if (mGLIndices) + { + stop_glerror(); + bindGLIndices(true); + glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, getIndicesSize(), NULL, mUsage); + stop_glerror(); + } + + mEmpty = TRUE; + mResized = FALSE; + } + + unmapBuffer(); + } +} + // Set for rendering -void LLVertexBuffer::setBuffer(U32 data_mask, S32 type) +void LLVertexBuffer::setBuffer(U32 data_mask) { + flush(); + LLMemType mt2(LLMemType::MTYPE_VERTEX_SET_BUFFER); //set up pointers if the data mask is different ... - U32& ref_mask = mGLArray ? mLastMask : sLastMask; - BOOL setup = (ref_mask != data_mask); + BOOL setup = (sLastMask != data_mask); if (gDebugGL && data_mask != 0) - { + { //make sure data requirements are fulfilled LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; if (shader) { @@ -1823,37 +2069,25 @@ void LLVertexBuffer::setBuffer(U32 data_mask, S32 type) if (useVBOs()) { - if (mGLArray && mGLArray != sGLRenderArray) + if (mGLArray) { - glBindVertexArray(mGLArray); - sGLRenderArray = mGLArray; + bindGLArray(); + setup = FALSE; //do NOT perform pointer setup if using VAO } - - if (mGLBuffer && (mGLBuffer != sGLRenderBuffer || !sVBOActive)) + else { - /*if (sMapped) + if (bindGLBuffer()) { - llerrs << "VBO bound while another VBO mapped!" << llendl; - }*/ - glBindBufferARB(GL_ARRAY_BUFFER_ARB, mGLBuffer); - sBindCount++; - sVBOActive = TRUE; - setup = TRUE; // ... or the bound buffer changed - } - if (mGLIndices && (mGLIndices != sGLRenderIndices || !sIBOActive)) - { - /*if (sMapped) + setup = TRUE; + } + if (bindGLIndices()) { - llerrs << "VBO bound while another VBO mapped!" << llendl; - }*/ - glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mGLIndices); - stop_glerror(); - sBindCount++; - sIBOActive = TRUE; + setup = TRUE; + } } BOOL error = FALSE; - if (gDebugGL) + if (gDebugGL && !mGLArray) { GLint buff; glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff); @@ -1888,81 +2122,16 @@ void LLVertexBuffer::setBuffer(U32 data_mask, S32 type) } } - if (mResized) + + } + else + { + if (sGLRenderArray) { - if (gDebugGL) - { - GLint buff; - glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff); - if ((GLuint)buff != mGLBuffer) - { - if (gDebugSession) - { - error = TRUE; - gFailLog << "Invalid GL vertex buffer bound: " << std::endl; - } - else - { - llerrs << "Invalid GL vertex buffer bound: " << buff << llendl; - } - } - - if (mGLIndices != 0) - { - glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff); - if ((GLuint)buff != mGLIndices) - { - if (gDebugSession) - { - error = TRUE; - gFailLog << "Invalid GL index buffer bound: "<< std::endl; - } - else - { - llerrs << "Invalid GL index buffer bound: " << buff << llendl; - } - } - } - } - - if (mGLBuffer) - { - stop_glerror(); - glBufferDataARB(GL_ARRAY_BUFFER_ARB, getSize(), NULL, mUsage); - stop_glerror(); - } - if (mGLIndices) - { - stop_glerror(); - glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, getIndicesSize(), NULL, mUsage); - stop_glerror(); - } - - mEmpty = TRUE; - mResized = FALSE; - - if (data_mask != 0) - { - if (gDebugSession) - { - error = TRUE; - gFailLog << "Buffer set for rendering before being filled after resize." << std::endl; - } - else - { - llerrs << "Buffer set for rendering before being filled after resize." << llendl; - } - } + glBindVertexArray(0); + sGLRenderArray = 0; } - if (error) - { - ll_fail("LLVertexBuffer::mapBuffer failed"); - } - unmapBuffer(type); - } - else - { if (mGLBuffer) { if (sVBOActive) @@ -1974,30 +2143,30 @@ void LLVertexBuffer::setBuffer(U32 data_mask, S32 type) } if (sGLRenderBuffer != mGLBuffer) { + sGLRenderBuffer = mGLBuffer; setup = TRUE; // ... or a client memory pointer changed } } - if (mGLIndices && sIBOActive) + if (mGLIndices) { - /*if (sMapped) + if (sIBOActive) { - llerrs << "VBO unbound while potentially mapped!" << llendl; - }*/ - glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); - sBindCount++; - sIBOActive = FALSE; + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); + sBindCount++; + sIBOActive = FALSE; + } + + sGLRenderIndices = mGLIndices; } } - setupClientArrays(data_mask, ref_mask); - - if (mGLIndices) + if (!mGLArray) { - sGLRenderIndices = mGLIndices; + setupClientArrays(data_mask, sLastMask); } + if (mGLBuffer) { - sGLRenderBuffer = mGLBuffer; if (data_mask && setup) { setupVertexBuffer(data_mask); // subclass specific setup (virtual function) @@ -2007,319 +2176,140 @@ void LLVertexBuffer::setBuffer(U32 data_mask, S32 type) } // virtual (default) -void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const +void LLVertexBuffer::setupVertexBuffer(U32 data_mask) { LLMemType mt2(LLMemType::MTYPE_VERTEX_SETUP_VERTEX_BUFFER); stop_glerror(); U8* base = useVBOs() ? (U8*) mAlignedOffset : mMappedData; - if ((data_mask & mTypeMask) != data_mask) + /*if ((data_mask & mTypeMask) != data_mask) { llerrs << "LLVertexBuffer::setupVertexBuffer missing required components for supplied data mask." << llendl; - } - - LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; - - //assert that fixed function is allowed OR a shader is currently bound - llassert(!LLGLSLShader::sNoFixedFunction || shader != NULL); + }*/ - if (data_mask & MAP_NORMAL) + if (LLGLSLShader::sNoFixedFunction) { - S32 loc = -1; - if (shader) - { - loc = shader->getAttribLocation(TYPE_NORMAL); - } - - if (loc >= 0) + if (data_mask & MAP_NORMAL) { + S32 loc = TYPE_NORMAL; void* ptr = (void*)(base + mOffsets[TYPE_NORMAL]); - if (mLastPointer[loc] != ptr) - { - glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_NORMAL], ptr); - } - if (mGLArray) - { - mLastPointer[loc] = ptr; - } - } - else if (!shader) - { - glNormalPointer(GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_NORMAL], (void*)(base + mOffsets[TYPE_NORMAL])); - } - } - if (data_mask & MAP_TEXCOORD3) - { - S32 loc = -1; - if (shader) - { - loc = shader->getAttribLocation(TYPE_TEXCOORD3); + glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_NORMAL], ptr); } - - if (loc >= 0) + if (data_mask & MAP_TEXCOORD3) { + S32 loc = TYPE_TEXCOORD3; void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD3]); - if (mLastPointer[loc] != ptr) - { - glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD3], ptr); - } - if (mGLArray) - { - mLastPointer[loc] = ptr; - } - } - else if (!shader) - { - glClientActiveTextureARB(GL_TEXTURE3_ARB); - glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD3], (void*)(base + mOffsets[TYPE_TEXCOORD3])); - glClientActiveTextureARB(GL_TEXTURE0_ARB); + glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD3], ptr); } - } - if (data_mask & MAP_TEXCOORD2) - { - S32 loc = -1; - if (shader) - { - loc = shader->getAttribLocation(TYPE_TEXCOORD2); - } - - if (loc >= 0) + if (data_mask & MAP_TEXCOORD2) { + S32 loc = TYPE_TEXCOORD2; void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD2]); - if (mLastPointer[loc] != ptr) - { - glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD2], ptr); - } - if (mGLArray) - { - mLastPointer[loc] = ptr; - } - } - else if (!shader) - { - glClientActiveTextureARB(GL_TEXTURE2_ARB); - glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD2], (void*)(base + mOffsets[TYPE_TEXCOORD2])); - glClientActiveTextureARB(GL_TEXTURE0_ARB); + glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD2], ptr); } - } - if (data_mask & MAP_TEXCOORD1) - { - S32 loc = -1; - if (shader) - { - loc = shader->getAttribLocation(TYPE_TEXCOORD1); - } - - if (loc >= 0) + if (data_mask & MAP_TEXCOORD1) { + S32 loc = TYPE_TEXCOORD1; void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD1]); - if (mLastPointer[loc] != ptr) - { - glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], ptr); - } - if (mGLArray) - { - mLastPointer[loc] = ptr; - } - } - else if (!shader) - { - glClientActiveTextureARB(GL_TEXTURE1_ARB); - glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], (void*)(base + mOffsets[TYPE_TEXCOORD1])); - glClientActiveTextureARB(GL_TEXTURE0_ARB); + glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], ptr); } - } - if (data_mask & MAP_BINORMAL) - { - S32 loc = -1; - if (shader) - { - loc = shader->getAttribLocation(TYPE_BINORMAL); - } - - if (loc >= 0) + if (data_mask & MAP_BINORMAL) { + S32 loc = TYPE_BINORMAL; void* ptr = (void*)(base + mOffsets[TYPE_BINORMAL]); - if (mLastPointer[loc] != ptr) - { - glVertexAttribPointerARB(loc, 3,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], ptr); - } - if (mGLArray) - { - mLastPointer[loc] = ptr; - } - } - else if (!shader) - { - glClientActiveTextureARB(GL_TEXTURE2_ARB); - glTexCoordPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], (void*)(base + mOffsets[TYPE_BINORMAL])); - glClientActiveTextureARB(GL_TEXTURE0_ARB); + glVertexAttribPointerARB(loc, 3,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], ptr); } - } - if (data_mask & MAP_TEXCOORD0) - { - S32 loc = -1; - if (shader) - { - loc = shader->getAttribLocation(TYPE_TEXCOORD0); - } - - if (loc >= 0) + if (data_mask & MAP_TEXCOORD0) { + S32 loc = TYPE_TEXCOORD0; void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD0]); - if (mLastPointer[loc] != ptr) - { - glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], ptr); - } - if (mGLArray) - { - mLastPointer[loc] = ptr; - } + glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], ptr); } - else if (!shader) + if (data_mask & MAP_COLOR) { - glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], (void*)(base + mOffsets[TYPE_TEXCOORD0])); + S32 loc = TYPE_COLOR; + void* ptr = (void*)(base + mOffsets[TYPE_COLOR]); + glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_COLOR], ptr); } - } - if (data_mask & MAP_COLOR) - { - S32 loc = -1; - if (shader) + if (data_mask & MAP_EMISSIVE) { - loc = shader->getAttribLocation(TYPE_COLOR); + S32 loc = TYPE_EMISSIVE; + void* ptr = (void*)(base + mOffsets[TYPE_EMISSIVE]); + glVertexAttribPointerARB(loc, 1, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr); } - - if (loc >= 0) + if (data_mask & MAP_WEIGHT) { - void* ptr = (void*)(base + mOffsets[TYPE_COLOR]); - if (mLastPointer[loc] != ptr) - { - glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_COLOR], ptr); - } - if (mGLArray) - { - mLastPointer[loc] = ptr; - } + S32 loc = TYPE_WEIGHT; + void* ptr = (void*)(base + mOffsets[TYPE_WEIGHT]); + glVertexAttribPointerARB(loc, 1, GL_FLOAT, FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT], ptr); } - else if (!shader) + if (data_mask & MAP_WEIGHT4) { - glColorPointer(4, GL_UNSIGNED_BYTE, LLVertexBuffer::sTypeSize[TYPE_COLOR], (void*)(base + mOffsets[TYPE_COLOR])); + S32 loc = TYPE_WEIGHT4; + void* ptr = (void*)(base+mOffsets[TYPE_WEIGHT4]); + glVertexAttribPointerARB(loc, 4, GL_FLOAT, FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT4], ptr); } - } - if (data_mask & MAP_EMISSIVE) - { - S32 loc = -1; - if (shader) + if (data_mask & MAP_CLOTHWEIGHT) { - loc = shader->getAttribLocation(TYPE_EMISSIVE); + S32 loc = TYPE_CLOTHWEIGHT; + void* ptr = (void*)(base + mOffsets[TYPE_CLOTHWEIGHT]); + glVertexAttribPointerARB(loc, 4, GL_FLOAT, TRUE, LLVertexBuffer::sTypeSize[TYPE_CLOTHWEIGHT], ptr); } - - if (loc >= 0) + if (data_mask & MAP_TEXTURE_INDEX) { - void* ptr = (void*)(base + mOffsets[TYPE_EMISSIVE]); - if (mLastPointer[loc] != ptr) - { - glVertexAttribPointerARB(loc, 1, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr); - } - if (mGLArray) - { - mLastPointer[loc] = ptr; - } + S32 loc = TYPE_TEXTURE_INDEX-1; //hack, texture index attrib location is off by one + void *ptr = (void*) (base + mOffsets[TYPE_VERTEX] + 12); + glVertexAttribPointerARB(loc, 1, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr); } - } - if (data_mask & MAP_WEIGHT) + if (data_mask & MAP_VERTEX) + { + S32 loc = TYPE_VERTEX; + void* ptr = (void*)(base + mOffsets[TYPE_VERTEX]); + glVertexAttribPointerARB(loc, 3,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0)); + } + } + else { - S32 loc = -1; - if (shader) + if (data_mask & MAP_NORMAL) { - loc = shader->getAttribLocation(TYPE_WEIGHT); + glNormalPointer(GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_NORMAL], (void*)(base + mOffsets[TYPE_NORMAL])); } - - if (loc > -1) + if (data_mask & MAP_TEXCOORD3) { - void* ptr = (void*)(base + mOffsets[TYPE_WEIGHT]); - if (mLastPointer[loc] != ptr) - { - glVertexAttribPointerARB(loc, 1, GL_FLOAT, FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT], ptr); - } - if (mGLArray) - { - mLastPointer[loc] = ptr; - } + glClientActiveTextureARB(GL_TEXTURE3_ARB); + glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD3], (void*)(base + mOffsets[TYPE_TEXCOORD3])); + glClientActiveTextureARB(GL_TEXTURE0_ARB); } - } - - if (data_mask & MAP_WEIGHT4) - { - if (shader) + if (data_mask & MAP_TEXCOORD2) { - S32 loc = shader->getAttribLocation(TYPE_WEIGHT4); - if (loc > -1) - { - void* ptr = (void*)(base+mOffsets[TYPE_WEIGHT4]); - if (mLastPointer[loc] != ptr) - { - glVertexAttribPointerARB(loc, 4, GL_FLOAT, FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT4], ptr); - } - if (mGLArray) - { - mLastPointer[loc] = ptr; - } - } + glClientActiveTextureARB(GL_TEXTURE2_ARB); + glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD2], (void*)(base + mOffsets[TYPE_TEXCOORD2])); + glClientActiveTextureARB(GL_TEXTURE0_ARB); } - } - - if (data_mask & MAP_CLOTHWEIGHT) - { - S32 loc = -1; - if (shader) + if (data_mask & MAP_TEXCOORD1) { - loc = shader->getAttribLocation(TYPE_CLOTHWEIGHT); + glClientActiveTextureARB(GL_TEXTURE1_ARB); + glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], (void*)(base + mOffsets[TYPE_TEXCOORD1])); + glClientActiveTextureARB(GL_TEXTURE0_ARB); } - - if (loc > -1) + if (data_mask & MAP_BINORMAL) { - void* ptr = (void*)(base + mOffsets[TYPE_CLOTHWEIGHT]); - if (mLastPointer[loc] != ptr) - { - glVertexAttribPointerARB(loc, 4, GL_FLOAT, TRUE, LLVertexBuffer::sTypeSize[TYPE_CLOTHWEIGHT], ptr); - } - if (mGLArray) - { - mLastPointer[loc] = ptr; - } + glClientActiveTextureARB(GL_TEXTURE2_ARB); + glTexCoordPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], (void*)(base + mOffsets[TYPE_BINORMAL])); + glClientActiveTextureARB(GL_TEXTURE0_ARB); } - } - if (data_mask & MAP_VERTEX) - { - S32 loc = -1; - if (shader) + if (data_mask & MAP_TEXCOORD0) { - loc = shader->getAttribLocation(TYPE_VERTEX); + glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], (void*)(base + mOffsets[TYPE_TEXCOORD0])); } - - if (loc >= 0) + if (data_mask & MAP_COLOR) { - if (data_mask & MAP_TEXTURE_INDEX) - { - glVertexAttribPointerARB(loc, 4,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0)); - } - else - { - glVertexAttribPointerARB(loc, 3,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0)); - } + glColorPointer(4, GL_UNSIGNED_BYTE, LLVertexBuffer::sTypeSize[TYPE_COLOR], (void*)(base + mOffsets[TYPE_COLOR])); } - else if (!shader) + if (data_mask & MAP_VERTEX) { - if (data_mask & MAP_TEXTURE_INDEX) - { - glVertexPointer(4,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0)); - } - else - { - glVertexPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0)); - } - } + glVertexPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0)); + } } llglassertok(); -- cgit v1.2.3 From 57620a9da903f3c6fe482627d18c44b6411e6910 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 23 Sep 2011 17:59:05 -0500 Subject: SH-2244 Vertex buffer cleanup, fix for bad vertices in rigged attachments, added "RenderUseVAO" debug setting to control whether or not to use VAO's in non-core GL profiles. --- indra/llrender/llvertexbuffer.cpp | 276 ++++++++++++++++---------------------- 1 file changed, 114 insertions(+), 162 deletions(-) (limited to 'indra/llrender/llvertexbuffer.cpp') diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index a48669a300..b2a0f6822d 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -63,6 +63,7 @@ BOOL LLVertexBuffer::sIBOActive = FALSE; U32 LLVertexBuffer::sAllocatedBytes = 0; BOOL LLVertexBuffer::sMapped = FALSE; BOOL LLVertexBuffer::sUseStreamDraw = TRUE; +BOOL LLVertexBuffer::sUseVAO = FALSE; BOOL LLVertexBuffer::sPreferStreamDraw = FALSE; std::vector LLVertexBuffer::sDeleteList; @@ -134,6 +135,7 @@ S32 LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_MAX] = sizeof(F32), // TYPE_WEIGHT, sizeof(LLVector4), // TYPE_WEIGHT4, sizeof(LLVector4), // TYPE_CLOTHWEIGHT, + sizeof(LLVector4), // TYPE_TEXTURE_INDEX (actually exists as position.w), no extra data, but stride is 16 bytes }; U32 LLVertexBuffer::sGLMode[LLRender::NUM_MODES] = @@ -150,188 +152,135 @@ U32 LLVertexBuffer::sGLMode[LLRender::NUM_MODES] = //static -void LLVertexBuffer::setupClientArrays(U32 data_mask, U32& sLastMask) +void LLVertexBuffer::setupClientArrays(U32 data_mask) { - /*if (LLGLImmediate::sStarted) - { - llerrs << "Cannot use LLGLImmediate and LLVertexBuffer simultaneously!" << llendl; - }*/ - if (sLastMask != data_mask) { - - LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; - - U32 mask[] = - { - MAP_VERTEX, - MAP_NORMAL, - MAP_TEXCOORD0, - MAP_COLOR, - MAP_EMISSIVE, - MAP_WEIGHT, - MAP_WEIGHT4, - MAP_BINORMAL, - MAP_CLOTHWEIGHT, - MAP_TEXTURE_INDEX, - }; - - U32 type[] = - { - TYPE_VERTEX, - TYPE_NORMAL, - TYPE_TEXCOORD0, - TYPE_COLOR, - TYPE_EMISSIVE, - TYPE_WEIGHT, - TYPE_WEIGHT4, - TYPE_BINORMAL, - TYPE_CLOTHWEIGHT, - TYPE_TEXTURE_INDEX-1, - }; - - GLenum array[] = - { - GL_VERTEX_ARRAY, - GL_NORMAL_ARRAY, - GL_TEXTURE_COORD_ARRAY, - GL_COLOR_ARRAY, - 0, - 0, - 0, - 0, - 0, - 0, - }; - BOOL error = FALSE; - for (U32 i = 0; i < 10; ++i) - { - S32 loc = -1; - if (LLGLSLShader::sNoFixedFunction) + if (LLGLSLShader::sNoFixedFunction) + { + for (U32 i = 0; i < TYPE_MAX; ++i) { - loc = type[i]; - } - - if (sLastMask & mask[i]) - { //was enabled - if (!(data_mask & mask[i])) - { //needs to be disabled - if (loc >= 0) - { + S32 loc = i; + + U32 mask = 1 << i; + + if (sLastMask & (1 << i)) + { //was enabled + if (!(data_mask & mask)) + { //needs to be disabled glDisableVertexAttribArrayARB(loc); } - else - { + } + else + { //was disabled + if (data_mask & mask) + { //needs to be enabled + glEnableVertexAttribArrayARB(loc); + } + } + } + } + else + { + + GLenum array[] = + { + GL_VERTEX_ARRAY, + GL_NORMAL_ARRAY, + GL_TEXTURE_COORD_ARRAY, + GL_COLOR_ARRAY, + }; + + GLenum mask[] = + { + MAP_VERTEX, + MAP_NORMAL, + MAP_TEXCOORD0, + MAP_COLOR + }; + + + + for (U32 i = 0; i < 4; ++i) + { + if (sLastMask & mask[i]) + { //was enabled + if (!(data_mask & mask[i])) + { //needs to be disabled glDisableClientState(array[i]); } + else if (gDebugGL) + { //needs to be enabled, make sure it was (DEBUG) + if (!glIsEnabled(array[i])) + { + if (gDebugSession) + { + error = TRUE; + gFailLog << "Bad client state! " << array[i] << " disabled." << std::endl; + } + else + { + llerrs << "Bad client state! " << array[i] << " disabled." << llendl; + } + } + } } - else if (gDebugGL && !LLGLSLShader::sNoFixedFunction && array[i]) - { //needs to be enabled, make sure it was (DEBUG) - if (loc < 0 && !glIsEnabled(array[i])) - { + else + { //was disabled + if (data_mask & mask[i]) + { //needs to be enabled + glEnableClientState(array[i]); + } + else if (gDebugGL && glIsEnabled(array[i])) + { //needs to be disabled, make sure it was (DEBUG TEMPORARY) if (gDebugSession) { error = TRUE; - gFailLog << "Bad client state! " << array[i] << " disabled." << std::endl; + gFailLog << "Bad client state! " << array[i] << " enabled." << std::endl; } else { - llerrs << "Bad client state! " << array[i] << " disabled." << llendl; + llerrs << "Bad client state! " << array[i] << " enabled." << llendl; } } } } - else - { //was disabled - if (data_mask & mask[i]) - { //needs to be enabled - if (loc >= 0) - { - glEnableVertexAttribArrayARB(loc); - } - else - { - glEnableClientState(array[i]); - } - } - else if (!LLGLSLShader::sNoFixedFunction && array[i] && gDebugGL && glIsEnabled(array[i])) - { //needs to be disabled, make sure it was (DEBUG TEMPORARY) - if (gDebugSession) - { - error = TRUE; - gFailLog << "Bad client state! " << array[i] << " enabled." << std::endl; - } - else - { - llerrs << "Bad client state! " << array[i] << " enabled." << llendl; - } - } - } - } - - if (error) - { - ll_fail("LLVertexBuffer::setupClientArrays failed"); - } - - U32 map_tc[] = - { - MAP_TEXCOORD1, - MAP_TEXCOORD2, - MAP_TEXCOORD3 - }; - - U32 type_tc[] = - { - TYPE_TEXCOORD1, - TYPE_TEXCOORD2, - TYPE_TEXCOORD3 - }; - - for (U32 i = 0; i < 3; i++) - { - S32 loc = -1; + + U32 map_tc[] = + { + MAP_TEXCOORD1, + MAP_TEXCOORD2, + MAP_TEXCOORD3 + }; - if (LLGLSLShader::sNoFixedFunction) + U32 type_tc[] = { - loc = type_tc[i]; - } + TYPE_TEXCOORD1, + TYPE_TEXCOORD2, + TYPE_TEXCOORD3 + }; - if (sLastMask & map_tc[i]) + for (U32 i = 0; i < 3; i++) { - if (!(data_mask & map_tc[i])) - { //disable - if (loc >= 0) - { - glDisableVertexAttribArrayARB(loc); - } - else - { + if (sLastMask & map_tc[i]) + { + if (!(data_mask & map_tc[i])) + { //disable glClientActiveTextureARB(GL_TEXTURE1_ARB+i); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glClientActiveTextureARB(GL_TEXTURE0_ARB); } } - } - else if (data_mask & map_tc[i]) - { - if (loc >= 0) - { - glEnableVertexAttribArrayARB(loc); - } - else + else if (data_mask & map_tc[i]) { glClientActiveTextureARB(GL_TEXTURE1_ARB+i); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glClientActiveTextureARB(GL_TEXTURE0_ARB); } } - } - if (!LLGLSLShader::sNoFixedFunction) - { if (sLastMask & MAP_BINORMAL) { if (!(data_mask & MAP_BINORMAL)) @@ -348,7 +297,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask, U32& sLastMask) glClientActiveTextureARB(GL_TEXTURE0_ARB); } } - + sLastMask = data_mask; } } @@ -734,12 +683,12 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) : S32 LLVertexBuffer::calcOffsets(const U32& typemask, S32* offsets, S32 num_vertices) { S32 offset = 0; - for (S32 i=0; i Date: Fri, 23 Sep 2011 18:29:38 -0500 Subject: SH-2244 Fix for mac build? --- indra/llrender/llvertexbuffer.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'indra/llrender/llvertexbuffer.cpp') diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index b2a0f6822d..add3decee3 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -575,7 +575,9 @@ void LLVertexBuffer::unbind() { if (sGLRenderArray) { +#if GL_ARB_vertex_array_object glBindVertexArray(0); +#endif sGLRenderArray = 0; } @@ -733,7 +735,9 @@ LLVertexBuffer::~LLVertexBuffer() if (mGLArray) { +#if GL_ARB_vertex_array_object glDeleteVertexArrays(1, &mGLArray); +#endif } sCount--; @@ -1049,7 +1053,9 @@ void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create) if (gGLManager.mHasVertexArrayObject && useVBOs() && (LLRender::sGLCoreProfile || sUseVAO)) { +#if GL_ARB_vertex_array_object glGenVertexArrays(1, &mGLArray); +#endif setupVertexArray(); } } @@ -1128,7 +1134,9 @@ void LLVertexBuffer::setupVertexArray() } } +#if GL_ARB_vertex_array_object glBindVertexArray(0); +#endif } void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices) @@ -1864,7 +1872,9 @@ bool LLVertexBuffer::bindGLArray() { if (mGLArray && sGLRenderArray != mGLArray) { +#if GL_ARB_vertex_array_object glBindVertexArray(mGLArray); +#endif sGLRenderArray = mGLArray; return true; } @@ -2072,7 +2082,9 @@ void LLVertexBuffer::setBuffer(U32 data_mask) { if (sGLRenderArray) { +#if GL_ARB_vertex_array_object glBindVertexArray(0); +#endif sGLRenderArray = 0; } -- cgit v1.2.3 From 4f2b20a30dff80756a2efdceceb3651cc05f1aee Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 23 Sep 2011 20:47:55 -0500 Subject: SH-2244 Fix for mac build? (take two) --- indra/llrender/llvertexbuffer.cpp | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'indra/llrender/llvertexbuffer.cpp') diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index add3decee3..422f2a06d6 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -255,13 +255,6 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask) MAP_TEXCOORD3 }; - U32 type_tc[] = - { - TYPE_TEXCOORD1, - TYPE_TEXCOORD2, - TYPE_TEXCOORD3 - }; - for (U32 i = 0; i < 3; i++) { if (sLastMask & map_tc[i]) @@ -2221,7 +2214,7 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) { S32 loc = TYPE_VERTEX; void* ptr = (void*)(base + mOffsets[TYPE_VERTEX]); - glVertexAttribPointerARB(loc, 3,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0)); + glVertexAttribPointerARB(loc, 3,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr); } } else -- cgit v1.2.3 From 56191701bcbc0ef1b6872cc6bfac1d18f636fd12 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Sun, 25 Sep 2011 02:43:43 -0500 Subject: SH-2244 Fix for crash when enabling core profile on AMD GPUs --- indra/llrender/llvertexbuffer.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'indra/llrender/llvertexbuffer.cpp') diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 422f2a06d6..1b7b0cdf3e 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -1024,7 +1024,9 @@ void LLVertexBuffer::updateNumIndices(S32 nindices) void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create) { LLMemType mt2(LLMemType::MTYPE_VERTEX_ALLOCATE_BUFFER); - + + stop_glerror(); + if (nverts < 0 || nindices < 0 || nverts > 65536) { -- cgit v1.2.3 From 54ba56dbe995a3d215f85932c83948145a871ac4 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Mon, 26 Sep 2011 18:31:55 -0500 Subject: SH-2244 changes to run in a core context on AMD hardware without generating deprecation or performance warnings --- indra/llrender/llvertexbuffer.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'indra/llrender/llvertexbuffer.cpp') diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 1b7b0cdf3e..199699449a 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -34,6 +34,7 @@ #include "llmemtype.h" #include "llrender.h" #include "llvector4a.h" +#include "llshadermgr.h" #include "llglslshader.h" #include "llmemory.h" @@ -121,6 +122,7 @@ public: }; +//NOTE: each component must be AT LEAST 4 bytes in size to avoid a performance penalty on AMD hardware S32 LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_MAX] = { sizeof(LLVector4), // TYPE_VERTEX, @@ -130,7 +132,7 @@ S32 LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_MAX] = sizeof(LLVector2), // TYPE_TEXCOORD2, sizeof(LLVector2), // TYPE_TEXCOORD3, sizeof(LLColor4U), // TYPE_COLOR, - sizeof(U8), // TYPE_EMISSIVE + sizeof(LLColor4U), // TYPE_EMISSIVE, only alpha is used currently sizeof(LLVector4), // TYPE_BINORMAL, sizeof(F32), // TYPE_WEIGHT, sizeof(LLVector4), // TYPE_WEIGHT4, @@ -1071,7 +1073,7 @@ void LLVertexBuffer::setupVertexArray() 2, //TYPE_TEXCOORD2, 2, //TYPE_TEXCOORD3, 4, //TYPE_COLOR, - 1, //TYPE_EMISSIVE, + 4, //TYPE_EMISSIVE, 3, //TYPE_BINORMAL, 1, //TYPE_WEIGHT, 4, //TYPE_WEIGHT4, @@ -1842,9 +1844,9 @@ bool LLVertexBuffer::getColorStrider(LLStrider& strider, S32 index, S { return VertexBufferStrider::get(*this, strider, index, count, map_range); } -bool LLVertexBuffer::getEmissiveStrider(LLStrider& strider, S32 index, S32 count, bool map_range) +bool LLVertexBuffer::getEmissiveStrider(LLStrider& strider, S32 index, S32 count, bool map_range) { - return VertexBufferStrider::get(*this, strider, index, count, map_range); + return VertexBufferStrider::get(*this, strider, index, count, map_range); } bool LLVertexBuffer::getWeightStrider(LLStrider& strider, S32 index, S32 count, bool map_range) { @@ -1994,18 +1996,17 @@ void LLVertexBuffer::setBuffer(U32 data_mask) if (shader) { U32 required_mask = 0; - for (U32 i = 0; i < LLVertexBuffer::TYPE_MAX; ++i) + for (U32 i = 0; i < LLVertexBuffer::TYPE_TEXTURE_INDEX; ++i) { if (shader->getAttribLocation(i) > -1) { U32 required = 1 << i; if ((data_mask & required) == 0) { - llwarns << "Missing attribute: " << i << llendl; + llwarns << "Missing attribute: " << LLShaderMgr::instance()->mReservedAttribs[i] << llendl; } required_mask |= required; - } } @@ -2186,7 +2187,7 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) { S32 loc = TYPE_EMISSIVE; void* ptr = (void*)(base + mOffsets[TYPE_EMISSIVE]); - glVertexAttribPointerARB(loc, 1, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr); + glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr); } if (data_mask & MAP_WEIGHT) { -- cgit v1.2.3 From 5ca512fa1f36998440bad5256730c9d22f195037 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 28 Sep 2011 12:38:31 -0500 Subject: SH-2450 Potential fix for crash on GeForce 4xx when allocating LLVertexBuffer data --- indra/llrender/llvertexbuffer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/llrender/llvertexbuffer.cpp') diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 199699449a..5756ccdcd5 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -560,8 +560,8 @@ void LLVertexBuffer::initClass(bool use_vbo, bool no_vbo_mapping) sDisableVBOMapping = sEnableVBOs && no_vbo_mapping ; if(!sPrivatePoolp) - { - sPrivatePoolp = LLPrivateMemoryPoolManager::getInstance()->newPool(LLPrivateMemoryPool::STATIC) ; + { //disable private pool for now -- lots of memory allocations failing for vertex buffers erroneously + //sPrivatePoolp = LLPrivateMemoryPoolManager::getInstance()->newPool(LLPrivateMemoryPool::STATIC) ; } } -- cgit v1.2.3 From 1e9a4924317b8c0c2c8418c8531c9fd1b141b605 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 29 Sep 2011 13:10:38 -0500 Subject: SH-2276 disable private memory pool management --- indra/llrender/llvertexbuffer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/llrender/llvertexbuffer.cpp') diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 5756ccdcd5..71596d41d3 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -560,8 +560,8 @@ void LLVertexBuffer::initClass(bool use_vbo, bool no_vbo_mapping) sDisableVBOMapping = sEnableVBOs && no_vbo_mapping ; if(!sPrivatePoolp) - { //disable private pool for now -- lots of memory allocations failing for vertex buffers erroneously - //sPrivatePoolp = LLPrivateMemoryPoolManager::getInstance()->newPool(LLPrivateMemoryPool::STATIC) ; + { + sPrivatePoolp = LLPrivateMemoryPoolManager::getInstance()->newPool(LLPrivateMemoryPool::STATIC) ; } } -- cgit v1.2.3 From ac37656aa5ff545c90fadfd5b585cb823ad68b0d Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Sun, 2 Oct 2011 02:12:21 -0500 Subject: SH-2276 Fix for failed assertions reported from debug-enabled viewers. Also, remove "Basic Shaders" as a user settable option (shaders are always on if GL version >= 2.0, always off otherwise) --- indra/llrender/llvertexbuffer.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'indra/llrender/llvertexbuffer.cpp') diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 71596d41d3..7f2337a224 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -574,6 +574,8 @@ void LLVertexBuffer::unbind() glBindVertexArray(0); #endif sGLRenderArray = 0; + sGLRenderIndices = 0; + sIBOActive = FALSE; } if (sVBOActive) @@ -1131,9 +1133,7 @@ void LLVertexBuffer::setupVertexArray() } } -#if GL_ARB_vertex_array_object - glBindVertexArray(0); -#endif + unbind(); } void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices) @@ -1873,6 +1873,12 @@ bool LLVertexBuffer::bindGLArray() glBindVertexArray(mGLArray); #endif sGLRenderArray = mGLArray; + + if (mGLIndices) + { + sGLRenderIndices = mGLIndices; + sIBOActive = TRUE; + } return true; } @@ -2082,6 +2088,8 @@ void LLVertexBuffer::setBuffer(U32 data_mask) glBindVertexArray(0); #endif sGLRenderArray = 0; + sGLRenderIndices = 0; + sIBOActive = FALSE; } if (mGLBuffer) -- cgit v1.2.3 From c4aa8c50daf7c4eea3509057a7ca74b083682779 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 4 Oct 2011 02:31:54 -0500 Subject: SH-2447, SH-2525, SH-2276 Strip out defunct global illumination code, add accounting for how much memory is taken up by LLRenderTarget, fix crash on login in bindGLIndices (work around driver bug that doesn't respect VAO state WRT to index buffers), remove some unused render targets, remove some unused shaders, make it possible to run a fullscreen session --- indra/llrender/llvertexbuffer.cpp | 57 +++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 29 deletions(-) (limited to 'indra/llrender/llvertexbuffer.cpp') diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 7f2337a224..c3e1a486b3 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -430,7 +430,7 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi } } - if (gDebugGL && useVBOs()) + if (gDebugGL && !mGLArray && useVBOs()) { GLint elem = 0; glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &elem); @@ -1049,6 +1049,8 @@ void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create) createGLBuffer(); createGLIndices(); + //actually allocate space for the vertex buffer if using VBO mapping + flush(); if (gGLManager.mHasVertexArrayObject && useVBOs() && (LLRender::sGLCoreProfile || sUseVAO)) { @@ -1064,7 +1066,15 @@ void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create) void LLVertexBuffer::setupVertexArray() { - bindGLArray(); + if (!mGLArray) + { + return; + } + +#if GL_ARB_vertex_array_object + glBindVertexArray(mGLArray); +#endif + sGLRenderArray = mGLArray; U32 attrib_size[] = { @@ -1362,6 +1372,18 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran else { #ifdef GL_ARB_map_buffer_range + + if (gDebugGL) + { + GLint size = 0; + glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SIZE_ARB, &size); + + if (size < mSize) + { + llerrs << "Invalid buffer size." << llendl; + } + } + src = (U8*) glMapBufferRange(GL_ARRAY_BUFFER_ARB, 0, mSize, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT); @@ -1874,11 +1896,10 @@ bool LLVertexBuffer::bindGLArray() #endif sGLRenderArray = mGLArray; - if (mGLIndices) - { - sGLRenderIndices = mGLIndices; - sIBOActive = TRUE; - } + //really shouldn't be necessary, but some drivers don't properly restore the + //state of GL_ELEMENT_ARRAY_BUFFER_BINDING + bindGLIndices(); + return true; } @@ -1911,17 +1932,6 @@ bool LLVertexBuffer::bindGLBuffer(bool force_bind) ret = true; } - if (gDebugGL && useVBOs()) - { - GLint elem = 0; - glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &elem); - - if (elem != mGLBuffer) - { - llerrs << "Wrong vertex buffer bound!" << llendl; - } - } - return ret; } @@ -1944,17 +1954,6 @@ bool LLVertexBuffer::bindGLIndices(bool force_bind) ret = true; } - if (gDebugGL && useVBOs()) - { - GLint elem = 0; - glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &elem); - - if (elem != mGLIndices) - { - llerrs << "Wrong index buffer bound!" << llendl; - } - } - return ret; } -- cgit v1.2.3 From ae0cd901f8917f1cacc4c402e5a51a06632a076b Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 4 Oct 2011 17:25:55 -0500 Subject: SH-2428 Make GCC 4.4 happy by using LLVector4a striders with LLAlphaObject subclasses -- also vectorize particle VBO updates --- indra/llrender/llvertexbuffer.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'indra/llrender/llvertexbuffer.cpp') diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index c3e1a486b3..4484a880cc 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -1841,6 +1841,10 @@ bool LLVertexBuffer::getVertexStrider(LLStrider& strider, S32 index, { return VertexBufferStrider::get(*this, strider, index, count, map_range); } +bool LLVertexBuffer::getVertexStrider(LLStrider& strider, S32 index, S32 count, bool map_range) +{ + return VertexBufferStrider::get(*this, strider, index, count, map_range); +} bool LLVertexBuffer::getIndexStrider(LLStrider& strider, S32 index, S32 count, bool map_range) { return VertexBufferStrider::get(*this, strider, index, count, map_range); -- cgit v1.2.3 From 7b6723d1e0158d5dc326266a0332e87f634f9755 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 13 Oct 2011 01:19:45 -0500 Subject: SH-1650 Mitigate memory fragmentation by holding onto and reusing VBOs --- indra/llrender/llvertexbuffer.cpp | 458 ++++++++++++++++---------------------- 1 file changed, 194 insertions(+), 264 deletions(-) (limited to 'indra/llrender/llvertexbuffer.cpp') diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 4484a880cc..ad99bd1807 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -38,6 +38,17 @@ #include "llglslshader.h" #include "llmemory.h" +//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 +U32 nhpo2(U32 v) +{ + U32 r = 1; + while (r < v) { + r *= 2; + } + return r; +} + //============================================================================ @@ -46,6 +57,7 @@ LLVBOPool LLVertexBuffer::sStreamVBOPool; LLVBOPool LLVertexBuffer::sDynamicVBOPool; LLVBOPool LLVertexBuffer::sStreamIBOPool; LLVBOPool LLVertexBuffer::sDynamicIBOPool; +U32 LLVBOPool::sBytesPooled = 0; LLPrivateMemoryPool* LLVertexBuffer::sPrivatePoolp = NULL ; U32 LLVertexBuffer::sBindCount = 0; @@ -66,7 +78,6 @@ BOOL LLVertexBuffer::sMapped = FALSE; BOOL LLVertexBuffer::sUseStreamDraw = TRUE; BOOL LLVertexBuffer::sUseVAO = FALSE; BOOL LLVertexBuffer::sPreferStreamDraw = FALSE; -std::vector LLVertexBuffer::sDeleteList; const U32 FENCE_WAIT_TIME_NANOSECONDS = 10000; //1 ms @@ -122,6 +133,107 @@ public: }; + +//which power of 2 is i? +//assumes i is a power of 2 > 0 +U32 wpo2(U32 i) +{ + llassert(i > 0); + llassert(nhpo2(i) == i); + + U32 r = 0; + + while (i >>= 1) ++r; + + return r; +} + +U8* LLVBOPool::allocate(U32& name, U32 size) +{ + llassert(nhpo2(size) == size); + + U32 i = wpo2(size); + + if (mFreeList.size() <= i) + { + mFreeList.resize(i+1); + } + + U8* ret = NULL; + + if (mFreeList[i].empty()) + { + //make a new buffer + glGenBuffersARB(1, &name); + glBindBufferARB(mType, name); + glBufferDataARB(mType, size, 0, mUsage); + LLVertexBuffer::sAllocatedBytes += size; + + if (LLVertexBuffer::sDisableVBOMapping) + { + ret = (U8*) ll_aligned_malloc_16(size); + } + glBindBufferARB(mType, 0); + } + else + { + name = mFreeList[i].front().mGLName; + ret = mFreeList[i].front().mClientData; + + sBytesPooled -= size; + + mFreeList[i].pop_front(); + } + + return ret; +} + +void LLVBOPool::release(U32 name, U8* buffer, U32 size) +{ + llassert(nhpo2(size) == size); + + U32 i = wpo2(size); + + llassert(mFreeList.size() > i); + + Record rec; + rec.mGLName = name; + rec.mClientData = buffer; + + sBytesPooled += size; + + mFreeList[i].push_back(rec); +} + +void LLVBOPool::cleanup() +{ + U32 size = 1; + + for (U32 i = 0; i < mFreeList.size(); ++i) + { + record_list_t& l = mFreeList[i]; + + while (!l.empty()) + { + Record& r = l.front(); + + glDeleteBuffersARB(1, &r.mGLName); + + if (r.mClientData) + { + ll_aligned_free_16(r.mClientData); + } + + l.pop_front(); + + LLVertexBuffer::sAllocatedBytes -= size; + } + + size *= 2; + } +} + + //NOTE: each component must be AT LEAST 4 bytes in size to avoid a performance penalty on AMD hardware S32 LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_MAX] = { @@ -374,16 +486,16 @@ void LLVertexBuffer::drawElements(U32 mode, const LLVector4a* pos, const LLVecto void LLVertexBuffer::validateRange(U32 start, U32 end, U32 count, U32 indices_offset) const { - if (start >= (U32) mRequestedNumVerts || - end >= (U32) mRequestedNumVerts) + if (start >= (U32) mNumVerts || + end >= (U32) mNumVerts) { - llerrs << "Bad vertex buffer draw range: [" << start << ", " << end << "] vs " << mRequestedNumVerts << llendl; + llerrs << "Bad vertex buffer draw range: [" << start << ", " << end << "] vs " << mNumVerts << llendl; } - llassert(mRequestedNumIndices >= 0); + llassert(mNumIndices >= 0); - if (indices_offset >= (U32) mRequestedNumIndices || - indices_offset + count > (U32) mRequestedNumIndices) + if (indices_offset >= (U32) mNumIndices || + indices_offset + count > (U32) mNumIndices) { llerrs << "Bad index buffer draw range: [" << indices_offset << ", " << indices_offset+count << "]" << llendl; } @@ -407,7 +519,7 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi gGL.syncMatrices(); - llassert(mRequestedNumVerts >= 0); + llassert(mNumVerts >= 0); llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL); if (mGLArray) @@ -462,9 +574,9 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const gGL.syncMatrices(); - llassert(mRequestedNumIndices >= 0); - if (indices_offset >= (U32) mRequestedNumIndices || - indices_offset + count > (U32) mRequestedNumIndices) + llassert(mNumIndices >= 0); + if (indices_offset >= (U32) mNumIndices || + indices_offset + count > (U32) mNumIndices) { llerrs << "Bad index buffer draw range: [" << indices_offset << ", " << indices_offset+count << "]" << llendl; } @@ -508,9 +620,9 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const gGL.syncMatrices(); - llassert(mRequestedNumVerts >= 0); - if (first >= (U32) mRequestedNumVerts || - first + count > (U32) mRequestedNumVerts) + llassert(mNumVerts >= 0); + if (first >= (U32) mNumVerts || + first + count > (U32) mNumVerts) { llerrs << "Bad vertex buffer draw range: [" << first << ", " << first+count << "]" << llendl; } @@ -546,23 +658,22 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const void LLVertexBuffer::initClass(bool use_vbo, bool no_vbo_mapping) { sEnableVBOs = use_vbo && gGLManager.mHasVertexBufferObject ; - if(sEnableVBOs) - { - //llassert_always(glBindBufferARB) ; //double check the extention for VBO is loaded. - - llinfos << "VBO is enabled." << llendl ; - } - else - { - llinfos << "VBO is disabled." << llendl ; - } - sDisableVBOMapping = sEnableVBOs && no_vbo_mapping ; if(!sPrivatePoolp) { sPrivatePoolp = LLPrivateMemoryPoolManager::getInstance()->newPool(LLPrivateMemoryPool::STATIC) ; } + + sStreamVBOPool.mType = GL_ARRAY_BUFFER_ARB; + sStreamVBOPool.mUsage= GL_STREAM_DRAW_ARB; + sStreamIBOPool.mType = GL_ELEMENT_ARRAY_BUFFER_ARB; + sStreamIBOPool.mUsage= GL_STREAM_DRAW_ARB; + + sDynamicVBOPool.mType = GL_ARRAY_BUFFER_ARB; + sDynamicVBOPool.mUsage= GL_DYNAMIC_DRAW_ARB; + sDynamicIBOPool.mType = GL_ELEMENT_ARRAY_BUFFER_ARB; + sDynamicIBOPool.mUsage= GL_DYNAMIC_DRAW_ARB; } //static @@ -600,7 +711,11 @@ void LLVertexBuffer::cleanupClass() { LLMemType mt2(LLMemType::MTYPE_VERTEX_CLEANUP_CLASS); unbind(); - clientCopy(); // deletes GL buffers + + sStreamIBOPool.cleanup(); + sDynamicIBOPool.cleanup(); + sStreamVBOPool.cleanup(); + sDynamicVBOPool.cleanup(); if(sPrivatePoolp) { @@ -609,15 +724,6 @@ void LLVertexBuffer::cleanupClass() } } -void LLVertexBuffer::clientCopy(F64 max_time) -{ - if (!sDeleteList.empty()) - { - glDeleteBuffersARB(sDeleteList.size(), (GLuint*) &(sDeleteList[0])); - sDeleteList.clear(); - } -} - //---------------------------------------------------------------------------- LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) : @@ -625,8 +731,6 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) : mNumVerts(0), mNumIndices(0), - mRequestedNumVerts(-1), - mRequestedNumIndices(-1), mUsage(usage), mGLBuffer(0), mGLArray(0), @@ -636,10 +740,7 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) : mVertexLocked(FALSE), mIndexLocked(FALSE), mFinal(FALSE), - mFilthy(FALSE), mEmpty(TRUE), - mResized(FALSE), - mDynamicSize(FALSE), mFence(NULL) { LLMemType mt2(LLMemType::MTYPE_VERTEX_CONSTRUCTOR); @@ -664,6 +765,11 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) : mUsage = GL_STREAM_DRAW_ARB; } + if (mUsage && mUsage != GL_STREAM_DRAW_ARB) + { //only stream_draw and dynamic_draw are supported when using VBOs, dynamic draw is the default + mUsage = GL_DYNAMIC_DRAW_ARB; + } + //zero out offsets for (U32 i = 0; i < TYPE_MAX; i++) { @@ -672,6 +778,7 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) : mTypeMask = typemask; mSize = 0; + mIndicesSize = 0; mAlignedOffset = 0; mAlignedIndexOffset = 0; @@ -775,39 +882,35 @@ void LLVertexBuffer::waitFence() const //---------------------------------------------------------------------------- -void LLVertexBuffer::genBuffer() +void LLVertexBuffer::genBuffer(U32 size) { + mSize = nhpo2(size); + if (mUsage == GL_STREAM_DRAW_ARB) { - mGLBuffer = sStreamVBOPool.allocate(); - } - else if (mUsage == GL_DYNAMIC_DRAW_ARB) - { - mGLBuffer = sDynamicVBOPool.allocate(); + mMappedData = sStreamVBOPool.allocate(mGLBuffer, mSize); } else { - BOOST_STATIC_ASSERT(sizeof(mGLBuffer) == sizeof(GLuint)); - glGenBuffersARB(1, (GLuint*)&mGLBuffer); + mMappedData = sDynamicVBOPool.allocate(mGLBuffer, mSize); } + sGLCount++; } -void LLVertexBuffer::genIndices() +void LLVertexBuffer::genIndices(U32 size) { + mIndicesSize = nhpo2(size); + if (mUsage == GL_STREAM_DRAW_ARB) { - mGLIndices = sStreamIBOPool.allocate(); - } - else if (mUsage == GL_DYNAMIC_DRAW_ARB) - { - mGLIndices = sDynamicIBOPool.allocate(); + mMappedIndexData = sStreamIBOPool.allocate(mGLIndices, mIndicesSize); } else { - BOOST_STATIC_ASSERT(sizeof(mGLBuffer) == sizeof(GLuint)); - glGenBuffersARB(1, (GLuint*)&mGLIndices); + mMappedIndexData = sDynamicIBOPool.allocate(mGLIndices, mIndicesSize); } + sGLCount++; } @@ -815,16 +918,16 @@ void LLVertexBuffer::releaseBuffer() { if (mUsage == GL_STREAM_DRAW_ARB) { - sStreamVBOPool.release(mGLBuffer); - } - else if (mUsage == GL_DYNAMIC_DRAW_ARB) - { - sDynamicVBOPool.release(mGLBuffer); + sStreamVBOPool.release(mGLBuffer, mMappedData, mSize); } else { - sDeleteList.push_back(mGLBuffer); + sDynamicVBOPool.release(mGLBuffer, mMappedData, mSize); } + + mGLBuffer = 0; + mMappedData = NULL; + sGLCount--; } @@ -832,24 +935,23 @@ void LLVertexBuffer::releaseIndices() { if (mUsage == GL_STREAM_DRAW_ARB) { - sStreamIBOPool.release(mGLIndices); + sStreamIBOPool.release(mGLIndices, mMappedIndexData, mIndicesSize); } else if (mUsage == GL_DYNAMIC_DRAW_ARB) { - sDynamicIBOPool.release(mGLIndices); - } - else - { - sDeleteList.push_back(mGLIndices); + sDynamicIBOPool.release(mGLIndices, mMappedIndexData, mIndicesSize); } + + mGLIndices = 0; + mMappedIndexData = NULL; + sGLCount--; } -void LLVertexBuffer::createGLBuffer() +void LLVertexBuffer::createGLBuffer(U32 size) { LLMemType mt2(LLMemType::MTYPE_VERTEX_CREATE_VERTICES); - U32 size = getSize(); if (mGLBuffer) { destroyGLBuffer(); @@ -864,23 +966,21 @@ void LLVertexBuffer::createGLBuffer() if (useVBOs()) { - mMappedData = NULL; - genBuffer(); - mResized = TRUE; + genBuffer(size); } else { static int gl_buffer_idx = 0; mGLBuffer = ++gl_buffer_idx; mMappedData = (U8*)ALLOCATE_MEM(sPrivatePoolp, size); + mSize = size; } } -void LLVertexBuffer::createGLIndices() +void LLVertexBuffer::createGLIndices(U32 size) { LLMemType mt2(LLMemType::MTYPE_VERTEX_CREATE_INDICES); - U32 size = getIndicesSize(); - + if (mGLIndices) { destroyGLIndices(); @@ -900,15 +1000,14 @@ void LLVertexBuffer::createGLIndices() { //pad by another 16 bytes for VBO pointer adjustment size += 16; - mMappedIndexData = NULL; - genIndices(); - mResized = TRUE; + genIndices(size); } else { mMappedIndexData = (U8*)ALLOCATE_MEM(sPrivatePoolp, size); static int gl_buffer_idx = 0; mGLIndices = ++gl_buffer_idx; + mIndicesSize = size; } } @@ -919,12 +1018,6 @@ void LLVertexBuffer::destroyGLBuffer() { if (useVBOs()) { - freeClientBuffer() ; - - if (mMappedData || mMappedIndexData) - { - llerrs << "Vertex buffer destroyed while mapped!" << llendl; - } releaseBuffer(); } else @@ -933,8 +1026,6 @@ void LLVertexBuffer::destroyGLBuffer() mMappedData = NULL; mEmpty = TRUE; } - - sAllocatedBytes -= getSize(); } mGLBuffer = 0; @@ -948,12 +1039,6 @@ void LLVertexBuffer::destroyGLIndices() { if (useVBOs()) { - freeClientBuffer() ; - - if (mMappedData || mMappedIndexData) - { - llerrs << "Vertex buffer destroyed while mapped." << llendl; - } releaseIndices(); } else @@ -962,8 +1047,6 @@ void LLVertexBuffer::destroyGLIndices() mMappedIndexData = NULL; mEmpty = TRUE; } - - sAllocatedBytes -= getIndicesSize(); } mGLIndices = 0; @@ -982,23 +1065,14 @@ void LLVertexBuffer::updateNumVerts(S32 nverts) nverts = 65535; } - mRequestedNumVerts = nverts; + U32 needed_size = calcOffsets(mTypeMask, mOffsets, nverts); - if (!mDynamicSize) + if (needed_size > mSize || needed_size <= mSize/2) { - mNumVerts = nverts; - } - else if (mUsage == GL_STATIC_DRAW_ARB || - nverts > mNumVerts || - nverts < mNumVerts/2) - { - if (mUsage != GL_STATIC_DRAW_ARB && nverts + nverts/4 <= 65535) - { - nverts += nverts/4; - } - mNumVerts = nverts; + createGLBuffer(needed_size); } - mSize = calcOffsets(mTypeMask, mOffsets, mNumVerts); + + mNumVerts = nverts; } void LLVertexBuffer::updateNumIndices(S32 nindices) @@ -1007,22 +1081,14 @@ void LLVertexBuffer::updateNumIndices(S32 nindices) llassert(nindices >= 0); - mRequestedNumIndices = nindices; - if (!mDynamicSize) + U32 needed_size = sizeof(U16) * nindices; + + if (needed_size > mIndicesSize || needed_size <= mIndicesSize/2) { - mNumIndices = nindices; + createGLIndices(needed_size); } - else if (mUsage == GL_STATIC_DRAW_ARB || - nindices > mNumIndices || - nindices < mNumIndices/2) - { - if (mUsage != GL_STATIC_DRAW_ARB) - { - nindices += nindices/4; - } - mNumIndices = nindices; - } + mNumIndices = nindices; } void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create) @@ -1040,15 +1106,8 @@ void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create) updateNumVerts(nverts); updateNumIndices(nindices); - if (mMappedData) - { - llerrs << "LLVertexBuffer::allocateBuffer() called redundantly." << llendl; - } if (create && (nverts || nindices)) { - createGLBuffer(); - createGLIndices(); - //actually allocate space for the vertex buffer if using VBO mapping flush(); @@ -1060,8 +1119,6 @@ void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create) setupVertexArray(); } } - - sAllocatedBytes += getSize() + getIndicesSize(); } void LLVertexBuffer::setupVertexArray() @@ -1151,77 +1208,13 @@ void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices) llassert(newnverts >= 0); llassert(newnindices >= 0); - mRequestedNumVerts = newnverts; - mRequestedNumIndices = newnindices; - LLMemType mt2(LLMemType::MTYPE_VERTEX_RESIZE_BUFFER); - mDynamicSize = TRUE; - if (mUsage == GL_STATIC_DRAW_ARB) - { //always delete/allocate static buffers on resize - destroyGLBuffer(); - destroyGLIndices(); - allocateBuffer(newnverts, newnindices, TRUE); - mFinal = FALSE; - } - else if (newnverts > mNumVerts || newnindices > mNumIndices || - newnverts < mNumVerts/2 || newnindices < mNumIndices/2) - { - sAllocatedBytes -= getSize() + getIndicesSize(); - - updateNumVerts(newnverts); - updateNumIndices(newnindices); - - S32 newsize = getSize(); - S32 new_index_size = getIndicesSize(); - - sAllocatedBytes += newsize + new_index_size; - - if (newsize) - { - if (!mGLBuffer) - { //no buffer exists, create a new one - createGLBuffer(); - } - else - { - if (!useVBOs()) - { - FREE_MEM(sPrivatePoolp, mMappedData); - mMappedData = (U8*)ALLOCATE_MEM(sPrivatePoolp, newsize); - } - mResized = TRUE; - } - } - else if (mGLBuffer) - { - destroyGLBuffer(); - } - - if (new_index_size) - { - if (!mGLIndices) - { - createGLIndices(); - } - else - { - if (!useVBOs()) - { - FREE_MEM(sPrivatePoolp, mMappedIndexData) ; - mMappedIndexData = (U8*)ALLOCATE_MEM(sPrivatePoolp, new_index_size); - } - mResized = TRUE; - } - } - else if (mGLIndices) - { - destroyGLIndices(); - } - } - - if (mResized && useVBOs()) + + updateNumVerts(newnverts); + updateNumIndices(newnindices); + + if (useVBOs()) { - freeClientBuffer(); flush(); if (mGLArray) @@ -1244,32 +1237,6 @@ BOOL LLVertexBuffer::useVBOs() const } //---------------------------------------------------------------------------- -void LLVertexBuffer::freeClientBuffer() -{ - if(useVBOs() && sDisableVBOMapping && (mMappedData || mMappedIndexData)) - { - FREE_MEM(sPrivatePoolp, mMappedData) ; - FREE_MEM(sPrivatePoolp, mMappedIndexData) ; - mMappedData = NULL ; - mMappedIndexData = NULL ; - } -} - -void LLVertexBuffer::allocateClientVertexBuffer() -{ - if(!mMappedData) - { - mMappedData = (U8*)ALLOCATE_MEM(sPrivatePoolp, getSize()); - } -} - -void LLVertexBuffer::allocateClientIndexBuffer() -{ - if(!mMappedIndexData) - { - mMappedIndexData = (U8*)ALLOCATE_MEM(sPrivatePoolp, getIndicesSize()); - } -} bool expand_region(LLVertexBuffer::MappedRegion& region, S32 index, S32 count) { @@ -1350,7 +1317,6 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran if(sDisableVBOMapping) { map_range = false; - allocateClientVertexBuffer() ; } else { @@ -1535,7 +1501,6 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range) if(sDisableVBOMapping) { map_range = false; - allocateClientIndexBuffer() ; } else { @@ -1772,21 +1737,7 @@ void LLVertexBuffer::unmapBuffer() if(updated_all) { - if(mUsage == GL_STATIC_DRAW_ARB) - { - //static draw buffers can only be mapped a single time - //throw out client data (we won't be using it again) - mEmpty = TRUE; - mFinal = TRUE; - if(sDisableVBOMapping) - { - freeClientBuffer() ; - } - } - else - { - mEmpty = FALSE; - } + mEmpty = FALSE; } } @@ -1965,27 +1916,6 @@ void LLVertexBuffer::flush() { if (useVBOs()) { - if (mResized) - { - if (mGLBuffer) - { - stop_glerror(); - bindGLBuffer(true); - glBufferDataARB(GL_ARRAY_BUFFER_ARB, getSize(), NULL, mUsage); - stop_glerror(); - } - if (mGLIndices) - { - stop_glerror(); - bindGLIndices(true); - glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, getIndicesSize(), NULL, mUsage); - stop_glerror(); - } - - mEmpty = TRUE; - mResized = FALSE; - } - unmapBuffer(); } } -- cgit v1.2.3 From 4ec72ed0a61157dd5fcc1bc4cc91054664ee75b5 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 19 Oct 2011 16:19:00 -0500 Subject: Fix for VBO pools not getting cleared appropriately. --- indra/llrender/llvertexbuffer.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'indra/llrender/llvertexbuffer.cpp') diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index ad99bd1807..7f73977010 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -227,6 +227,7 @@ void LLVBOPool::cleanup() l.pop_front(); LLVertexBuffer::sAllocatedBytes -= size; + sBytesPooled -= size; } size *= 2; -- cgit v1.2.3