diff options
author | andreykproductengine <andreykproductengine@lindenlab.com> | 2017-11-01 19:36:13 +0200 |
---|---|---|
committer | andreykproductengine <andreykproductengine@lindenlab.com> | 2017-11-01 19:36:13 +0200 |
commit | 149b2d88dd75bddf1cb3e9927c4e8fcc84e263e1 (patch) | |
tree | b02a4d2775cec34281b637a6f4d1ae0c40faa976 /indra/newview | |
parent | fec6bbddc371b2d1e0aa41d39a1b3dfaa8fb2016 (diff) |
MAINT-7228 Vertex buffer allocation failure handling
Diffstat (limited to 'indra/newview')
-rw-r--r-- | indra/newview/lldrawpoolavatar.cpp | 25 | ||||
-rw-r--r-- | indra/newview/llfloaterimagepreview.cpp | 8 | ||||
-rw-r--r-- | indra/newview/llfloatermodelpreview.cpp | 20 | ||||
-rw-r--r-- | indra/newview/llspatialpartition.cpp | 20 | ||||
-rw-r--r-- | indra/newview/llvoavatar.cpp | 50 | ||||
-rw-r--r-- | indra/newview/llvoground.cpp | 7 | ||||
-rw-r--r-- | indra/newview/llvopartgroup.cpp | 12 | ||||
-rw-r--r-- | indra/newview/llvosky.cpp | 14 | ||||
-rw-r--r-- | indra/newview/llvotree.cpp | 25 | ||||
-rw-r--r-- | indra/newview/llvovolume.cpp | 35 | ||||
-rw-r--r-- | indra/newview/llvowater.cpp | 12 | ||||
-rw-r--r-- | indra/newview/llvowlsky.cpp | 19 | ||||
-rw-r--r-- | indra/newview/pipeline.cpp | 9 |
13 files changed, 212 insertions, 44 deletions
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index b221221f16..bb5c86f705 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1485,15 +1485,34 @@ void LLDrawPoolAvatar::getRiggedGeometry( { buffer = new LLVertexBuffer(data_mask, GL_STREAM_DRAW_ARB); } - buffer->allocateBuffer(vol_face.mNumVertices, vol_face.mNumIndices, true); + + if (!buffer->allocateBuffer(vol_face.mNumVertices, vol_face.mNumIndices, true)) + { + LL_WARNS("LLDrawPoolAvatar") << "Failed to allocate Vertex Buffer to " + << vol_face.mNumVertices << " vertices and " + << vol_face.mNumIndices << " indices" << LL_ENDL; + // allocate dummy triangle + buffer->allocateBuffer(1, 3, true); + memset((U8*)buffer->getMappedData(), 0, buffer->getSize()); + memset((U8*)buffer->getIndicesPointer(), 0, buffer->getIndicesSize()); + } } else { //resize existing buffer - buffer->resizeBuffer(vol_face.mNumVertices, vol_face.mNumIndices); + if(!buffer->resizeBuffer(vol_face.mNumVertices, vol_face.mNumIndices)) + { + LL_WARNS("LLDrawPoolAvatar") << "Failed to resize Vertex Buffer to " + << vol_face.mNumVertices << " vertices and " + << vol_face.mNumIndices << " indices" << LL_ENDL; + // allocate dummy triangle + buffer->resizeBuffer(1, 3); + memset((U8*)buffer->getMappedData(), 0, buffer->getSize()); + memset((U8*)buffer->getIndicesPointer(), 0, buffer->getIndicesSize()); + } } - face->setSize(vol_face.mNumVertices, vol_face.mNumIndices); + face->setSize(buffer->getNumVerts(), buffer->getNumIndices()); face->setVertexBuffer(buffer); U16 offset = 0; diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp index 52e678ce24..a9e4d752ac 100644 --- a/indra/newview/llfloaterimagepreview.cpp +++ b/indra/newview/llfloaterimagepreview.cpp @@ -801,7 +801,13 @@ void LLImagePreviewSculpted::setPreviewTarget(LLImageRaw* imagep, F32 distance) U32 num_vertices = vf.mNumVertices; mVertexBuffer = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0, 0); - mVertexBuffer->allocateBuffer(num_vertices, num_indices, TRUE); + if (!mVertexBuffer->allocateBuffer(num_vertices, num_indices, TRUE)) + { + LL_WARNS() << "Failed to allocate Vertex Buffer for image preview to" + << num_vertices << " vertices and " + << num_indices << " indices" << LL_ENDL; + // We are likely to crash on getTexCoord0Strider() + } LLStrider<LLVector3> vertex_strider; LLStrider<LLVector3> normal_strider; diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index b3885bf36c..da84a6b8f8 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -2568,13 +2568,21 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim if (sizes[i*2+1] > 0 && sizes[i*2] > 0) { - buff->allocateBuffer(sizes[i*2+1], sizes[i*2], true); + if (!buff->allocateBuffer(sizes[i * 2 + 1], sizes[i * 2], true)) + { + // Todo: find a way to stop preview in this case instead of crashing + LL_ERRS() << "Failed buffer allocation during preview LOD generation." + << " Vertices: " << sizes[i * 2 + 1] + << " Indices: " << sizes[i * 2] << LL_ENDL; + } buff->setBuffer(type_mask); glodFillElements(mObject[base], names[i], GL_UNSIGNED_SHORT, (U8*) buff->getIndicesPointer()); stop_gloderror(); } else - { //this face was eliminated, create a dummy triangle (one vertex, 3 indices, all 0) + { + // This face was eliminated or we failed to allocate buffer, + // attempt to create a dummy triangle (one vertex, 3 indices, all 0) buff->allocateBuffer(1, 3, true); memset((U8*) buff->getMappedData(), 0, buff->getSize()); memset((U8*) buff->getIndicesPointer(), 0, buff->getIndicesSize()); @@ -3322,7 +3330,13 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights) vb = new LLVertexBuffer(mask, 0); - vb->allocateBuffer(num_vertices, num_indices, TRUE); + if (!vb->allocateBuffer(num_vertices, num_indices, TRUE)) + { + // We are likely to crash due this failure, if this happens, find a way to gracefully stop preview + LL_WARNS() << "Failed to allocate Vertex Buffer for model preview " + << num_vertices << " vertices and " + << num_indices << " indices" << LL_ENDL; + } LLStrider<LLVector3> vertex_strider; LLStrider<LLVector3> normal_strider; diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 0fd36766b3..df5756cf11 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -451,16 +451,32 @@ void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group) (group->mBufferUsage != group->mVertexBuffer->getUsage() && LLVertexBuffer::sEnableVBOs)) { group->mVertexBuffer = createVertexBuffer(mVertexDataMask, group->mBufferUsage); - group->mVertexBuffer->allocateBuffer(vertex_count, index_count, true); + if (!group->mVertexBuffer->allocateBuffer(vertex_count, index_count, true)) + { + LL_WARNS() << "Failed to allocate Vertex Buffer on rebuild to " + << vertex_count << " vertices and " + << index_count << " indices" << LL_ENDL; + group->mVertexBuffer = NULL; + group->mBufferMap.clear(); + } stop_glerror(); } else { - group->mVertexBuffer->resizeBuffer(vertex_count, index_count); + if (!group->mVertexBuffer->resizeBuffer(vertex_count, index_count)) + { + // Is likely to cause a crash. If this gets triggered find a way to avoid it (don't forget to reset face) + LL_WARNS() << "Failed to resize Vertex Buffer on rebuild to " + << vertex_count << " vertices and " + << index_count << " indices" << LL_ENDL; + group->mVertexBuffer = NULL; + group->mBufferMap.clear(); + } stop_glerror(); } } + if (group->mVertexBuffer) { LL_RECORD_BLOCK_TIME(FTM_GET_GEOMETRY); getGeometry(group); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index cc708ea275..33ab188704 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -2085,7 +2085,17 @@ void LLVOAvatar::updateMeshData() if(!facep->getVertexBuffer()) { buff = new LLVertexBufferAvatar(); - buff->allocateBuffer(num_vertices, num_indices, TRUE); + if (!buff->allocateBuffer(num_vertices, num_indices, TRUE)) + { + LL_WARNS() << "Failed to allocate Vertex Buffer for Mesh to " + << num_vertices << " vertices and " + << num_indices << " indices" << LL_ENDL; + // Attempt to create a dummy triangle (one vertex, 3 indices, all 0) + facep->setSize(1, 3); + buff->allocateBuffer(1, 3, true); + memset((U8*) buff->getMappedData(), 0, buff->getSize()); + memset((U8*) buff->getIndicesPointer(), 0, buff->getIndicesSize()); + } facep->setVertexBuffer(buff); } else @@ -2097,7 +2107,15 @@ void LLVOAvatar::updateMeshData() } else { - buff->resizeBuffer(num_vertices, num_indices); + if (!buff->resizeBuffer(num_vertices, num_indices)) + { + LL_WARNS() << "Failed to allocate vertex buffer for Mesh, Substituting" << LL_ENDL; + // Attempt to create a dummy triangle (one vertex, 3 indices, all 0) + facep->setSize(1, 3); + buff->resizeBuffer(1, 3); + memset((U8*) buff->getMappedData(), 0, buff->getSize()); + memset((U8*) buff->getIndicesPointer(), 0, buff->getIndicesSize()); + } } } @@ -2109,20 +2127,24 @@ void LLVOAvatar::updateMeshData() LL_ERRS() << "non-zero geom index: " << facep->getGeomIndex() << " in LLVOAvatar::restoreMeshData" << LL_ENDL; } - for(S32 k = j ; k < part_index ; k++) + if (num_vertices == buff->getNumVerts() && num_indices == buff->getNumIndices()) { - bool rigid = false; - if (k == MESH_ID_EYEBALL_LEFT || - k == MESH_ID_EYEBALL_RIGHT) - { //eyeballs can't have terse updates since they're never rendered with - //the hardware skinning shader - rigid = true; - } - - LLViewerJoint* mesh = getViewerJoint(k); - if (mesh) + for(S32 k = j ; k < part_index ; k++) { - mesh->updateFaceData(facep, mAdjustedPixelArea, k == MESH_ID_HAIR, terse_update && !rigid); + bool rigid = false; + if (k == MESH_ID_EYEBALL_LEFT || + k == MESH_ID_EYEBALL_RIGHT) + { + //eyeballs can't have terse updates since they're never rendered with + //the hardware skinning shader + rigid = true; + } + + LLViewerJoint* mesh = getViewerJoint(k); + if (mesh) + { + mesh->updateFaceData(facep, mAdjustedPixelArea, k == MESH_ID_HAIR, terse_update && !rigid); + } } } diff --git a/indra/newview/llvoground.cpp b/indra/newview/llvoground.cpp index c1273e684c..71a7623fb4 100644 --- a/indra/newview/llvoground.cpp +++ b/indra/newview/llvoground.cpp @@ -94,7 +94,12 @@ BOOL LLVOGround::updateGeometry(LLDrawable *drawable) { face->setSize(5, 12); LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolGround::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB); - buff->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE); + if (!buff->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE)) + { + LL_WARNS() << "Failed to allocate Vertex Buffer for VOGround to " + << face->getGeomCount() << " vertices and " + << face->getIndicesCount() << " indices" << LL_ENDL; + } face->setGeomIndex(0); face->setIndicesIndex(0); face->setVertexBuffer(buff); diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp index 6e5db526b0..f7b21338f8 100644 --- a/indra/newview/llvopartgroup.cpp +++ b/indra/newview/llvopartgroup.cpp @@ -61,7 +61,15 @@ void LLVOPartGroup::restoreGL() //TODO: optimize out binormal mask here. Specular and normal coords as well. sVB = new LLVertexBuffer(VERTEX_DATA_MASK | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2, GL_STREAM_DRAW_ARB); U32 count = LL_MAX_PARTICLE_COUNT; - sVB->allocateBuffer(count*4, count*6, true); + if (!sVB->allocateBuffer(count*4, count*6, true)) + { + LL_WARNS() << "Failed to allocate Vertex Buffer to " + << count*4 << " vertices and " + << count * 6 << " indices" << LL_ENDL; + // we are likelly to crash at following getTexCoord0Strider(), so unref and return + sVB = NULL; + return; + } //indices and texcoords are always the same, set once LLStrider<U16> indicesp; @@ -764,7 +772,7 @@ void LLParticlePartition::rebuildGeom(LLSpatialGroup* group) addGeometryCount(group, vertex_count, index_count); - if (vertex_count > 0 && index_count > 0) + if (vertex_count > 0 && index_count > 0 && LLVOPartGroup::sVB) { group->mBuilt = 1.f; //use one vertex buffer for all groups diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp index 4dab213fa0..86b380087a 100644 --- a/indra/newview/llvosky.cpp +++ b/indra/newview/llvosky.cpp @@ -1462,7 +1462,12 @@ BOOL LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, const S32 f, cons { facep->setSize(4, 6); LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolSky::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB); - buff->allocateBuffer(facep->getGeomCount(), facep->getIndicesCount(), TRUE); + if (!buff->allocateBuffer(facep->getGeomCount(), facep->getIndicesCount(), TRUE)) + { + LL_WARNS() << "Failed to allocate Vertex Buffer for vosky to " + << facep->getGeomCount() << " vertices and " + << facep->getIndicesCount() << " indices" << LL_ENDL; + } facep->setGeomIndex(0); facep->setIndicesIndex(0); facep->setVertexBuffer(buff); @@ -1869,7 +1874,12 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H, { face->setSize(quads * 4, quads * 6); LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB); - buff->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE); + if (!buff->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE)) + { + LL_WARNS() << "Failed to allocate Vertex Buffer for vosky to " + << face->getGeomCount() << " vertices and " + << face->getIndicesCount() << " indices" << LL_ENDL; + } face->setIndicesIndex(0); face->setGeomIndex(0); face->setVertexBuffer(buff); diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp index 4dcc267e96..5193d3bb0e 100644 --- a/indra/newview/llvotree.cpp +++ b/indra/newview/llvotree.cpp @@ -525,7 +525,14 @@ BOOL LLVOTree::updateGeometry(LLDrawable *drawable) } mReferenceBuffer = new LLVertexBuffer(LLDrawPoolTree::VERTEX_DATA_MASK, 0); - mReferenceBuffer->allocateBuffer(max_vertices, max_indices, TRUE); + if (!mReferenceBuffer->allocateBuffer(max_vertices, max_indices, TRUE)) + { + LL_WARNS() << "Failed to allocate Vertex Buffer on update to " + << max_vertices << " vertices and " + << max_indices << " indices" << LL_ENDL; + mReferenceBuffer = NULL; //unref + return TRUE; + } LLStrider<LLVector3> vertices; LLStrider<LLVector3> normals; @@ -883,7 +890,21 @@ void LLVOTree::updateMesh() LLFace* facep = mDrawable->getFace(0); if (!facep) return; LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolTree::VERTEX_DATA_MASK, GL_STATIC_DRAW_ARB); - buff->allocateBuffer(vert_count, index_count, TRUE); + if (!buff->allocateBuffer(vert_count, index_count, TRUE)) + { + LL_WARNS() << "Failed to allocate Vertex Buffer on mesh update to " + << vert_count << " vertices and " + << index_count << " indices" << LL_ENDL; + buff->allocateBuffer(1, 3, true); + memset((U8*)buff->getMappedData(), 0, buff->getSize()); + memset((U8*)buff->getIndicesPointer(), 0, buff->getIndicesSize()); + facep->setSize(1, 3); + facep->setVertexBuffer(buff); + mReferenceBuffer->flush(); + buff->flush(); + return; + } + facep->setVertexBuffer(buff); LLStrider<LLVector3> vertices; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 90ba814a15..f77b48ff80 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -5638,18 +5638,25 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac } //create vertex buffer - LLVertexBuffer* buffer = NULL; + LLPointer<LLVertexBuffer> buffer; { LL_RECORD_BLOCK_TIME(FTM_GEN_DRAW_INFO_ALLOCATE); buffer = createVertexBuffer(mask, buffer_usage); - buffer->allocateBuffer(geom_count, index_count, TRUE); + if(!buffer->allocateBuffer(geom_count, index_count, TRUE)) + { + LL_WARNS() << "Failed to allocate group Vertex Buffer to " + << geom_count << " vertices and " + << index_count << " indices" << LL_ENDL; + buffer = NULL; + } } - group->mGeometryBytes += buffer->getSize() + buffer->getIndicesSize(); - - - buffer_map[mask][*face_iter].push_back(buffer); + if (buffer) + { + group->mGeometryBytes += buffer->getSize() + buffer->getIndicesSize(); + buffer_map[mask][*face_iter].push_back(buffer); + } //add face geometry @@ -5657,8 +5664,17 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac U16 index_offset = 0; while (face_iter < i) - { //update face indices for new buffer + { + //update face indices for new buffer facep = *face_iter; + if (buffer.isNull()) + { + // Bulk allocation failed + facep->setVertexBuffer(buffer); + facep->setSize(0, 0); // mark as no geometry + ++face_iter; + continue; + } facep->setIndicesIndex(indices_index); facep->setGeomIndex(index_offset); facep->setVertexBuffer(buffer); @@ -5983,7 +5999,10 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac ++face_iter; } - buffer->flush(); + if (buffer) + { + buffer->flush(); + } } group->mBufferMap[mask].clear(); diff --git a/indra/newview/llvowater.cpp b/indra/newview/llvowater.cpp index 9ce16a1674..ccda92810e 100644 --- a/indra/newview/llvowater.cpp +++ b/indra/newview/llvowater.cpp @@ -155,14 +155,22 @@ BOOL LLVOWater::updateGeometry(LLDrawable *drawable) if (!buff || !buff->isWriteable()) { buff = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK, GL_DYNAMIC_DRAW_ARB); - buff->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE); + if (!buff->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE)) + { + LL_WARNS() << "Failed to allocate Vertex Buffer on water update to " + << face->getGeomCount() << " vertices and " + << face->getIndicesCount() << " indices" << LL_ENDL; + } face->setIndicesIndex(0); face->setGeomIndex(0); face->setVertexBuffer(buff); } else { - buff->resizeBuffer(face->getGeomCount(), face->getIndicesCount()); + if (!buff->resizeBuffer(face->getGeomCount(), face->getIndicesCount())) + { + LL_WARNS() << "Failed to resize Vertex Buffer" << LL_ENDL; + } } index_offset = face->getGeometry(verticesp,normalsp,texCoordsp, indicesp); diff --git a/indra/newview/llvowlsky.cpp b/indra/newview/llvowlsky.cpp index 16130b5ca7..3b9b96e9f1 100644 --- a/indra/newview/llvowlsky.cpp +++ b/indra/newview/llvowlsky.cpp @@ -313,7 +313,12 @@ BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable) #if DOME_SLICES { mFanVerts = new LLVertexBuffer(LLDrawPoolWLSky::SKY_VERTEX_DATA_MASK, GL_STATIC_DRAW_ARB); - mFanVerts->allocateBuffer(getFanNumVerts(), getFanNumIndices(), TRUE); + if (!mFanVerts->allocateBuffer(getFanNumVerts(), getFanNumIndices(), TRUE)) + { + LL_WARNS() << "Failed to allocate Vertex Buffer on sky update to " + << getFanNumVerts() << " vertices and " + << getFanNumIndices() << " indices" << LL_ENDL; + } BOOL success = mFanVerts->getVertexStrider(vertices) && mFanVerts->getTexCoord0Strider(texCoords) @@ -375,7 +380,12 @@ BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable) const U32 num_indices_this_seg = 1+num_stacks_this_seg*(2+2*verts_per_stack); llassert(num_indices_this_seg * sizeof(U16) <= max_buffer_bytes); - segment->allocateBuffer(num_verts_this_seg, num_indices_this_seg, TRUE); + if (!segment->allocateBuffer(num_verts_this_seg, num_indices_this_seg, TRUE)) + { + LL_WARNS() << "Failed to allocate Vertex Buffer on update to " + << num_verts_this_seg << " vertices and " + << num_indices_this_seg << " indices" << LL_ENDL; + } // lock the buffer BOOL success = segment->getVertexStrider(vertices) @@ -777,7 +787,10 @@ BOOL LLVOWLSky::updateStarGeometry(LLDrawable *drawable) if (mStarsVerts.isNull() || !mStarsVerts->isWriteable()) { mStarsVerts = new LLVertexBuffer(LLDrawPoolWLSky::STAR_VERTEX_DATA_MASK, GL_DYNAMIC_DRAW); - mStarsVerts->allocateBuffer(getStarsNumVerts()*6, 0, TRUE); + if (!mStarsVerts->allocateBuffer(getStarsNumVerts()*6, 0, TRUE)) + { + LL_WARNS() << "Failed to allocate Vertex Buffer for Sky to " << getStarsNumVerts() * 6 << " vertices" << LL_ENDL; + } } BOOL success = mStarsVerts->getVertexStrider(verticesp) diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 19487c3230..d3be5fea1a 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -3903,7 +3903,14 @@ void LLPipeline::postSort(LLCamera& camera) } //flush particle VB - LLVOPartGroup::sVB->flush(); + if (LLVOPartGroup::sVB) + { + LLVOPartGroup::sVB->flush(); + } + else + { + LL_WARNS_ONCE() << "Missing particle buffer" << LL_ENDL; + } /*bool use_transform_feedback = gTransformPositionProgram.mProgramObject && !mMeshDirtyGroup.empty(); |