diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 3f35a707f9..b376b915c8 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -1127,7 +1127,11 @@ void LLRender::shutdown() void LLRender::initVB() { mBuffer = new LLVertexBuffer(immediate_mask, 0); - mBuffer->allocateBuffer(4096, 0, TRUE); + if (!mBuffer->allocateBuffer(4096, 0, true)) + { + // If this doesn't work, we're knee-deep in trouble! + LL_WARNS() << "Failed to allocate Vertex Buffer for common rendering" << LL_ENDL; + } mBuffer->getVertexStrider(mVerticesp); mBuffer->getTexCoord0Strider(mTexcoordsp); mBuffer->getColorStrider(mColorsp); diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 09492ac568..00693b0b49 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -611,30 +611,64 @@ void LLVertexBuffer::drawArrays(U32 mode, const std::vector& pos, con //LLGLSLShader::startProfile(); //glDrawArrays(sGLMode[mode], 0, count); //LLGLSLShader::stopProfile(count, mode); + bool has_buffer = true; if (!sUtilityBuffer) { sUtilityBuffer = new LLVertexBuffer(MAP_VERTEX | MAP_NORMAL | MAP_TEXCOORD0, GL_STREAM_DRAW); - sUtilityBuffer->allocateBuffer(count, count, true); + has_buffer = sUtilityBuffer->allocateBuffer(count, count, true); } if (sUtilityBuffer->getNumVerts() < (S32) count) { - sUtilityBuffer->resizeBuffer(count, count); + has_buffer = sUtilityBuffer->resizeBuffer(count, count); } - LLStrider vertex_strider; - LLStrider normal_strider; - sUtilityBuffer->getVertexStrider(vertex_strider); - sUtilityBuffer->getNormalStrider(normal_strider); - for (U32 i = 0; i < count; ++i) + if (has_buffer) { - *(vertex_strider++) = pos[i]; - *(normal_strider++) = norm[i]; - } + LLStrider vertex_strider; + LLStrider normal_strider; + sUtilityBuffer->getVertexStrider(vertex_strider); + sUtilityBuffer->getNormalStrider(normal_strider); + for (U32 i = 0; i < count; ++i) + { + *(vertex_strider++) = pos[i]; + *(normal_strider++) = norm[i]; + } - sUtilityBuffer->setBuffer(MAP_VERTEX | MAP_NORMAL); - LLGLSLShader::startProfile(); - sUtilityBuffer->drawArrays(mode, 0, pos.size()); - LLGLSLShader::stopProfile(count, mode); + sUtilityBuffer->setBuffer(MAP_VERTEX | MAP_NORMAL); + LLGLSLShader::startProfile(); + sUtilityBuffer->drawArrays(mode, 0, pos.size()); + LLGLSLShader::stopProfile(count, mode); + } + else + { + unbind(); + + setupClientArrays(MAP_VERTEX | MAP_NORMAL); + + LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; + + if (shader) + { + S32 loc = LLVertexBuffer::TYPE_VERTEX; + if (loc > -1) + { + glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, 0, pos[0].mV); + } + loc = 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); + } + LLGLSLShader::startProfile(); + glDrawArrays(sGLMode[mode], 0, count); + LLGLSLShader::stopProfile(count, mode); + } // } @@ -663,36 +697,43 @@ void LLVertexBuffer::drawElements(U32 mode, const S32 num_vertices, const LLVect gGL.syncMatrices(); // Use a vbo for the static LLVertexBuffer::drawArray/Element functions; by Drake Arconis/Shyotl Kuhr + bool has_buffer = true; if (!sUtilityBuffer) { sUtilityBuffer = new LLVertexBuffer(MAP_VERTEX | MAP_NORMAL | MAP_TEXCOORD0, GL_STREAM_DRAW); - sUtilityBuffer->allocateBuffer(num_vertices, num_indices, true); + has_buffer = sUtilityBuffer->allocateBuffer(num_vertices, num_indices, true); } if (sUtilityBuffer->getNumVerts() < num_vertices || sUtilityBuffer->getNumIndices() < num_indices) { - sUtilityBuffer->resizeBuffer(llmax(sUtilityBuffer->getNumVerts(), num_vertices), llmax(sUtilityBuffer->getNumIndices(), num_indices)); + has_buffer = sUtilityBuffer->resizeBuffer(llmax(sUtilityBuffer->getNumVerts(), num_vertices), llmax(sUtilityBuffer->getNumIndices(), num_indices)); } // U32 mask = LLVertexBuffer::MAP_VERTEX; // Use a vbo for the static LLVertexBuffer::drawArray/Element functions; by Drake Arconis/Shyotl Kuhr - LLStrider index_strider; - LLStrider vertex_strider; - sUtilityBuffer->getIndexStrider(index_strider); - sUtilityBuffer->getVertexStrider(vertex_strider); - const S32 index_size = ((num_indices * sizeof(U16)) + 0xF) & ~0xF; - const S32 vertex_size = ((num_vertices * 4 * sizeof(F32)) + 0xF) & ~0xF; - LLVector4a::memcpyNonAliased16((F32*)index_strider.get(), (F32*)indicesp, index_size); - LLVector4a::memcpyNonAliased16((F32*)vertex_strider.get(), (F32*)pos, vertex_size); + if (has_buffer) + { + LLStrider index_strider; + LLStrider vertex_strider; + sUtilityBuffer->getIndexStrider(index_strider); + sUtilityBuffer->getVertexStrider(vertex_strider); + const S32 index_size = ((num_indices * sizeof(U16)) + 0xF) & ~0xF; + const S32 vertex_size = ((num_vertices * 4 * sizeof(F32)) + 0xF) & ~0xF; + LLVector4a::memcpyNonAliased16((F32*)index_strider.get(), (F32*)indicesp, index_size); + LLVector4a::memcpyNonAliased16((F32*)vertex_strider.get(), (F32*)pos, vertex_size); + } // if (tc) { mask = mask | LLVertexBuffer::MAP_TEXCOORD0; // Use a vbo for the static LLVertexBuffer::drawArray/Element functions; by Drake Arconis/Shyotl Kuhr - LLStrider tc_strider; - sUtilityBuffer->getTexCoord0Strider(tc_strider); - const S32 tc_size = ((num_vertices * 2 * sizeof(F32)) + 0xF) & ~0xF; - LLVector4a::memcpyNonAliased16((F32*)tc_strider.get(), (F32*)tc, tc_size); + if (has_buffer) + { + LLStrider tc_strider; + sUtilityBuffer->getTexCoord0Strider(tc_strider); + const S32 tc_size = ((num_vertices * 2 * sizeof(F32)) + 0xF) & ~0xF; + LLVector4a::memcpyNonAliased16((F32*)tc_strider.get(), (F32*)tc, tc_size); + } // } @@ -721,10 +762,40 @@ void LLVertexBuffer::drawElements(U32 mode, const S32 num_vertices, const LLVect //LLGLSLShader::startProfile(); //glDrawElements(sGLMode[mode], num_indices, GL_UNSIGNED_SHORT, indicesp); //LLGLSLShader::stopProfile(num_indices, mode); - sUtilityBuffer->setBuffer(mask); - LLGLSLShader::startProfile(); - sUtilityBuffer->draw(mode, num_indices, 0); - LLGLSLShader::stopProfile(num_indices, mode); + if (has_buffer) + { + sUtilityBuffer->setBuffer(mask); + LLGLSLShader::startProfile(); + sUtilityBuffer->draw(mode, num_indices, 0); + LLGLSLShader::stopProfile(num_indices, mode); + } + else + { + unbind(); + + setupClientArrays(mask); + + if (LLGLSLShader::sNoFixedFunction) + { + S32 loc = LLVertexBuffer::TYPE_VERTEX; + glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, 16, pos); + + if (tc) + { + loc = LLVertexBuffer::TYPE_TEXCOORD0; + glVertexAttribPointerARB(loc, 2, GL_FLOAT, GL_FALSE, 0, tc); + } + } + else + { + glTexCoordPointer(2, GL_FLOAT, 0, tc); + glVertexPointer(3, GL_FLOAT, 16, pos); + } + + LLGLSLShader::startProfile(); + glDrawElements(sGLMode[mode], num_indices, GL_UNSIGNED_SHORT, indicesp); + LLGLSLShader::stopProfile(num_indices, mode); + } // } diff --git a/indra/newview/exopostprocess.cpp b/indra/newview/exopostprocess.cpp index 063dc398e1..d8658ff924 100644 --- a/indra/newview/exopostprocess.cpp +++ b/indra/newview/exopostprocess.cpp @@ -31,33 +31,20 @@ LLVector3 exoPostProcess::sExodusRenderVignette; exoPostProcess::exoPostProcess() { - mExoPostBuffer = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1, 0); - mExoPostBuffer->allocateBuffer(8, 0, true); - - LLStrider vert; - mExoPostBuffer->getVertexStrider(vert); - LLStrider tc0; - LLStrider tc1; - mExoPostBuffer->getTexCoord0Strider(tc0); - mExoPostBuffer->getTexCoord1Strider(tc1); - - vert[0].set(-1.f, 1.f, 0.f); - vert[1].set(-1.f, -3.f, 0.f); - vert[2].set(3.f,1.f, 0.f); - + initVB(); sExodusRenderVignette = LLVector3(0.f, 0.f, 0.f); } exoPostProcess::~exoPostProcess() { - mExoPostBuffer = NULL; + destroyVB(); } void exoPostProcess::ExodusRenderPostStack(LLRenderTarget *src, LLRenderTarget *dst) { if (mVertexShaderLevel > 0) { - if (sExodusRenderVignette.mV[0] > 0 && LLPipeline::sRenderDeferred) + if (sExodusRenderVignette.mV[0] > 0.f && LLPipeline::sRenderDeferred) ExodusRenderVignette(src, dst); // Don't render vignette here in non-deferred. Do it in the glow combine shader. } } @@ -76,51 +63,61 @@ void exoPostProcess::ExodusRenderPostUpdate() void exoPostProcess::initVB() { + destroyVB(); + mExoPostBuffer = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1, 0); + if (!gPipeline.sRenderDeferred) { - // Destroy our old buffer, and create a new vertex buffer for the screen (shamelessly ganked from pipeline.cpp). - destroyVB(); - mExoPostBuffer = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1, 0); - mExoPostBuffer->allocateBuffer(3,0,TRUE); + if (mExoPostBuffer->allocateBuffer(3, 0, true)) + { + LLStrider v; + LLStrider uv1; + LLStrider uv2; - LLStrider v; - LLStrider uv1; - LLStrider uv2; + mExoPostBuffer->getVertexStrider(v); + mExoPostBuffer->getTexCoord0Strider(uv1); + mExoPostBuffer->getTexCoord1Strider(uv2); + + uv1[0] = LLVector2(0.f, 0.f); + uv1[1] = LLVector2(0.f, 2.f); + uv1[2] = LLVector2(2.f, 0.f); + + uv2[0] = LLVector2(0.f, 0.f); + uv2[1] = LLVector2(0.f, etc2.mV[1] * 2.f); + uv2[2] = LLVector2(etc2.mV[0] * 2.f, 0.f); + + v[0] = LLVector3(-1.f, -1.f, 0.f); + v[1] = LLVector3(-1.f, 3.f, 0.f); + v[2] = LLVector3(3.f, -1.f, 0.f); - mExoPostBuffer->getVertexStrider(v); - mExoPostBuffer->getTexCoord0Strider(uv1); - mExoPostBuffer->getTexCoord1Strider(uv2); - - uv1[0] = LLVector2(0.f, 0.f); - uv1[1] = LLVector2(0.f, 2.f); - uv1[2] = LLVector2(2.f, 0.f); - - uv2[0] = LLVector2(0.f, 0.f); - uv2[1] = LLVector2(0.f, etc2.mV[1] * 2.f); - uv2[2] = LLVector2(etc2.mV[0] * 2.f, 0.f); - - v[0] = LLVector3(-1.f, -1.f, 0.f); - v[1] = LLVector3(-1.f, 3.f, 0.f); - v[2] = LLVector3(3.f, -1.f, 0.f); - - mExoPostBuffer->flush(); + mExoPostBuffer->flush(); + } + else + { + LL_WARNS() << "Failed to allocate Vertex Buffer for exoPostProcessing" << LL_ENDL; + destroyVB(); + } } else { - destroyVB(); - mExoPostBuffer = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1, 0); - mExoPostBuffer->allocateBuffer(8, 0, true); + if (mExoPostBuffer->allocateBuffer(8, 0, true)) + { + LLStrider vert; + mExoPostBuffer->getVertexStrider(vert); + LLStrider tc0; + LLStrider tc1; + mExoPostBuffer->getTexCoord0Strider(tc0); + mExoPostBuffer->getTexCoord1Strider(tc1); - LLStrider vert; - mExoPostBuffer->getVertexStrider(vert); - LLStrider tc0; - LLStrider tc1; - mExoPostBuffer->getTexCoord0Strider(tc0); - mExoPostBuffer->getTexCoord1Strider(tc1); - - vert[0].set(-1.f, 1.f, 0.f); - vert[1].set(-1.f, -3.f, 0.f); - vert[2].set(3.f, 1.f, 0.f); + vert[0].set(-1.f, 1.f, 0.f); + vert[1].set(-1.f, -3.f, 0.f); + vert[2].set(3.f, 1.f, 0.f); + } + else + { + LL_WARNS() << "Failed to allocate Vertex Buffer for exoPostProcessing" << LL_ENDL; + destroyVB(); + } } } @@ -139,20 +136,23 @@ void exoPostProcess::ExodusRenderPost(LLRenderTarget* src, LLRenderTarget* dst, void exoPostProcess::ExodusRenderVignette(LLRenderTarget* src, LLRenderTarget* dst) { - dst->bindTarget(); - LLGLSLShader *shader = &gPostVignetteProgram; - shader->bind(); + if (mExoPostBuffer) + { + dst->bindTarget(); + LLGLSLShader *shader = &gPostVignetteProgram; + shader->bind(); - mExoPostBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX); + mExoPostBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX); - exoShader::BindRenderTarget(dst, shader, LLShaderMgr::EXO_RENDER_SCREEN); + exoShader::BindRenderTarget(dst, shader, LLShaderMgr::EXO_RENDER_SCREEN); - shader->uniform3fv(LLShaderMgr::EXO_RENDER_VIGNETTE, 1, sExodusRenderVignette.mV); - mExoPostBuffer->drawArrays(LLRender::TRIANGLES, 0, 3); - stop_glerror(); + shader->uniform3fv(LLShaderMgr::EXO_RENDER_VIGNETTE, 1, sExodusRenderVignette.mV); + mExoPostBuffer->drawArrays(LLRender::TRIANGLES, 0, 3); + stop_glerror(); - shader->unbind(); - dst->flush(); + shader->unbind(); + dst->flush(); + } } void exoShader::BindTex2D(LLTexture *tex2D, LLGLSLShader *shader, S32 uniform, S32 unit, LLTexUnit::eTextureType mode, LLTexUnit::eTextureAddressMode addressMode, LLTexUnit::eTextureFilterOptions filterMode) diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index f2172095ea..d017c15caf 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -12161,7 +12161,11 @@ void LLPipeline::disableDeferredOnLowMemory() void LLPipeline::initDeferredVB() { mDeferredVB = new LLVertexBuffer(DEFERRED_VB_MASK, 0); - mDeferredVB->allocateBuffer(8, 0, true); + if (!mDeferredVB->allocateBuffer(8, 0, true)) + { + // Most likely going to crash... + LL_WARNS() << "Failed to allocate Vertex Buffer for deferred rendering" << LL_ENDL; + } } // @@ -12169,7 +12173,12 @@ void LLPipeline::initDeferredVB() void LLPipeline::initAuxiliaryVB() { mAuxiliaryVB = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR, 0); - mAuxiliaryVB->allocateBuffer(3, 0, true); + if (!mAuxiliaryVB->allocateBuffer(3, 0, true)) + { + LL_WARNS() << "Failed to allocate auxiliary Vertex Buffer" << LL_ENDL; + mAuxiliaryVB = NULL; + return; + } LLStrider verts; mAuxiliaryVB->getVertexStrider(verts); @@ -12180,12 +12189,20 @@ void LLPipeline::initAuxiliaryVB() void LLPipeline::drawAuxiliaryVB(U32 mask /*= 0*/) { + if (!mAuxiliaryVB) + { + return; + } mAuxiliaryVB->setBuffer(LLVertexBuffer::MAP_VERTEX | mask); mAuxiliaryVB->drawArrays(LLRender::TRIANGLES, 0, 3); } void LLPipeline::drawAuxiliaryVB(const LLVector2& tc1, const LLVector2& tc2, U32 mask /*= 0*/) { + if (!mAuxiliaryVB) + { + return; + } LLStrider tc; mAuxiliaryVB->getTexCoord0Strider(tc); tc[0].set(tc1.mV[0], tc1.mV[1]); @@ -12197,6 +12214,10 @@ void LLPipeline::drawAuxiliaryVB(const LLVector2& tc1, const LLVector2& tc2, U32 void LLPipeline::drawAuxiliaryVB(const LLVector2& tc1, const LLVector2& tc2, const LLColor4& color) { + if (!mAuxiliaryVB) + { + return; + } LLStrider col; mAuxiliaryVB->getColorStrider(col); col[0].set(color);