SH-874 Better VBO usage hints, most notably don't use VBOs for occlusion queries if GL is set to not use VBOs for stream draw.

meow-7.2.2
Dave Parks 2011-02-22 18:36:50 -06:00
parent b53ffe4eae
commit e55e91a5a5
11 changed files with 105 additions and 94 deletions

View File

@ -58,6 +58,7 @@ BOOL LLVertexBuffer::sIBOActive = FALSE;
U32 LLVertexBuffer::sAllocatedBytes = 0;
BOOL LLVertexBuffer::sMapped = FALSE;
BOOL LLVertexBuffer::sUseStreamDraw = TRUE;
BOOL LLVertexBuffer::sPreferStreamDraw = FALSE;
S32 LLVertexBuffer::sWeight4Loc = -1;
std::vector<U32> LLVertexBuffer::sDeleteList;
@ -147,7 +148,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
{ //needs to be enabled
glEnableClientState(array[i]);
}
else if (gDebugGL && glIsEnabled(array[i]))
else if (gDebugGL && i > 0 && glIsEnabled(array[i]))
{ //needs to be disabled, make sure it was (DEBUG TEMPORARY)
if (gDebugSession)
{
@ -427,9 +428,9 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) :
mUsage = 0;
}
if (mUsage == GL_STREAM_DRAW_ARB && !sUseStreamDraw)
if (mUsage == GL_DYNAMIC_DRAW_ARB && sPreferStreamDraw)
{
mUsage = 0;
mUsage = GL_STREAM_DRAW_ARB;
}
//zero out offsets

View File

@ -92,6 +92,7 @@ public:
static S32 sWeight4Loc;
static BOOL sUseStreamDraw;
static BOOL sPreferStreamDraw;
static void initClass(bool use_vbo);
static void cleanupClass();

View File

@ -8810,7 +8810,18 @@
<key>Value</key>
<integer>1</integer>
</map>
<key>RenderVolumeLODFactor</key>
<key>RenderPreferStreamDraw</key>
<map>
<key>Comment</key>
<string>Use GL_STREAM_DRAW in place of GL_DYNAMIC_DRAW</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>RenderVolumeLODFactor</key>
<map>
<key>Comment</key>
<string>Controls level of detail of primitives (multiplier for current screen area when calculated level of detail)</string>

View File

@ -1052,7 +1052,7 @@ BOOL LLDrawable::isVisible() const
//=======================================
LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 data_mask)
: LLSpatialPartition(data_mask, render_by_group, FALSE)
: LLSpatialPartition(data_mask, render_by_group, GL_STREAM_DRAW_ARB)
{
mDrawable = root;
root->setSpatialBridge(this);

View File

@ -252,11 +252,15 @@ U8* get_box_fan_indices_ptr(LLCamera* camera, const LLVector4a& center)
}
static LLFastTimer::DeclareTimer FTM_BUILD_OCCLUSION("Build Occlusion");
void LLSpatialGroup::buildOcclusion()
{
if (mOcclusionVerts.isNull())
{
mOcclusionVerts = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX, GL_DYNAMIC_DRAW_ARB);
mOcclusionVerts = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX,
LLVertexBuffer::sUseStreamDraw ? mBufferUsage : 0); //if GL has a hard time with VBOs, don't use them for occlusion culling.
mOcclusionVerts->allocateBuffer(8, 64, true);
LLStrider<U16> idx;
@ -275,40 +279,47 @@ void LLSpatialGroup::buildOcclusion()
LLStrider<LLVector3> pos;
mOcclusionVerts->getVertexStrider(pos);
LLVector4a* v = (LLVector4a*) pos.get();
const LLVector4a& c = mBounds[0];
const LLVector4a& s = r;
static const LLVector4a octant[] =
{
LLVector4a(-1.f, -1.f, -1.f),
LLVector4a(-1.f, -1.f, 1.f),
LLVector4a(-1.f, 1.f, -1.f),
LLVector4a(-1.f, 1.f, 1.f),
LLFastTimer t(FTM_BUILD_OCCLUSION);
mOcclusionVerts->getVertexStrider(pos);
}
LLVector4a(1.f, -1.f, -1.f),
LLVector4a(1.f, -1.f, 1.f),
LLVector4a(1.f, 1.f, -1.f),
LLVector4a(1.f, 1.f, 1.f),
};
//vertex positions are encoded so the 3 bits of their vertex index
//correspond to their axis facing, with bit position 3,2,1 matching
//axis facing x,y,z, bit set meaning positive facing, bit clear
//meaning negative facing
for (S32 i = 0; i < 8; ++i)
{
LLVector4a p;
p.setMul(s, octant[i]);
p.add(c);
v[i] = p;
LLVector4a* v = (LLVector4a*) pos.get();
const LLVector4a& c = mBounds[0];
const LLVector4a& s = r;
static const LLVector4a octant[] =
{
LLVector4a(-1.f, -1.f, -1.f),
LLVector4a(-1.f, -1.f, 1.f),
LLVector4a(-1.f, 1.f, -1.f),
LLVector4a(-1.f, 1.f, 1.f),
LLVector4a(1.f, -1.f, -1.f),
LLVector4a(1.f, -1.f, 1.f),
LLVector4a(1.f, 1.f, -1.f),
LLVector4a(1.f, 1.f, 1.f),
};
//vertex positions are encoded so the 3 bits of their vertex index
//correspond to their axis facing, with bit position 3,2,1 matching
//axis facing x,y,z, bit set meaning positive facing, bit clear
//meaning negative facing
for (S32 i = 0; i < 8; ++i)
{
LLVector4a p;
p.setMul(s, octant[i]);
p.add(c);
v[i] = p;
}
}
mOcclusionVerts->setBuffer(0);
{
mOcclusionVerts->setBuffer(0);
}
clearState(LLSpatialGroup::OCCLUSION_DIRTY);
}
@ -1189,7 +1200,7 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) :
mOctreeNode(node),
mSpatialPartition(part),
mVertexBuffer(NULL),
mBufferUsage(GL_STATIC_DRAW_ARB),
mBufferUsage(part->mBufferUsage),
mDistance(0.f),
mDepth(0.f),
mLastUpdateDistance(-1.f),
@ -1616,6 +1627,10 @@ void LLSpatialGroup::checkOcclusion()
}
}
static LLFastTimer::DeclareTimer FTM_PUSH_OCCLUSION_VERTS("Push Occlusion");
static LLFastTimer::DeclareTimer FTM_SET_OCCLUSION_STATE("Occlusion State");
static LLFastTimer::DeclareTimer FTM_OCCLUSION_EARLY_FAIL("Occlusion Early Fail");
void LLSpatialGroup::doOcclusion(LLCamera* camera)
{
if (mSpatialPartition->isOcclusionEnabled() && LLPipeline::sUseOcclusion > 1)
@ -1623,6 +1638,7 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera)
// Don't cull hole/edge water, unless we have the GL_ARB_depth_clamp extension
if (earlyFail(camera, this))
{
LLFastTimer t(FTM_OCCLUSION_EARLY_FAIL);
setOcclusionState(LLSpatialGroup::DISCARD_QUERY);
assert_states_valid(this);
clearOcclusionState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF);
@ -1664,41 +1680,47 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera)
sPendingQueries.insert(mOcclusionQuery[LLViewerCamera::sCurCameraID]);
#endif
glBeginQueryARB(mode, mOcclusionQuery[LLViewerCamera::sCurCameraID]);
{
LLFastTimer t(FTM_PUSH_OCCLUSION_VERTS);
glBeginQueryARB(mode, mOcclusionQuery[LLViewerCamera::sCurCameraID]);
mOcclusionVerts->setBuffer(LLVertexBuffer::MAP_VERTEX);
mOcclusionVerts->setBuffer(LLVertexBuffer::MAP_VERTEX);
if (!use_depth_clamp && mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER)
{
LLGLSquashToFarClip squash(glh_get_current_projection(), 1);
if (camera->getOrigin().isExactlyZero())
{ //origin is invalid, draw entire box
mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0);
mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8);
if (!use_depth_clamp && mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER)
{
LLGLSquashToFarClip squash(glh_get_current_projection(), 1);
if (camera->getOrigin().isExactlyZero())
{ //origin is invalid, draw entire box
mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0);
mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8);
}
else
{
mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0]));
}
}
else
{
mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0]));
if (camera->getOrigin().isExactlyZero())
{ //origin is invalid, draw entire box
mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0);
mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8);
}
else
{
mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0]));
}
}
}
else
{
if (camera->getOrigin().isExactlyZero())
{ //origin is invalid, draw entire box
mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0);
mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8);
}
else
{
mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0]));
}
}
glEndQueryARB(mode);
glEndQueryARB(mode);
}
}
setOcclusionState(LLSpatialGroup::QUERY_PENDING);
clearOcclusionState(LLSpatialGroup::DISCARD_QUERY);
{
LLFastTimer t(FTM_SET_OCCLUSION_STATE);
setOcclusionState(LLSpatialGroup::QUERY_PENDING);
clearOcclusionState(LLSpatialGroup::DISCARD_QUERY);
}
}
}
}

View File

@ -339,15 +339,6 @@ static bool handleNumpadControlChanged(const LLSD& newvalue)
return true;
}
static bool handleRenderUseVBOChanged(const LLSD& newvalue)
{
if (gPipeline.isInit())
{
gPipeline.setUseVBO(newvalue.asBoolean());
}
return true;
}
static bool handleWLSkyDetailChanged(const LLSD&)
{
if (gSky.mVOWLSkyp.notNull())
@ -636,8 +627,9 @@ void settings_setup_listeners()
gSavedSettings.getControl("MuteVoice")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
gSavedSettings.getControl("MuteAmbient")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
gSavedSettings.getControl("MuteUI")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
gSavedSettings.getControl("RenderVBOEnable")->getSignal()->connect(boost::bind(&handleRenderUseVBOChanged, _2));
gSavedSettings.getControl("RenderVBOEnable")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
gSavedSettings.getControl("RenderUseStreamVBO")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
gSavedSettings.getControl("RenderPreferStreamDraw")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
gSavedSettings.getControl("WLSkyDetail")->getSignal()->connect(boost::bind(&handleWLSkyDetailChanged, _2));
gSavedSettings.getControl("NumpadControl")->getSignal()->connect(boost::bind(&handleNumpadControlChanged, _2));
gSavedSettings.getControl("JoystickAxis0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));

View File

@ -360,7 +360,7 @@ U32 LLVOPartGroup::getPartitionType() const
}
LLParticlePartition::LLParticlePartition()
: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK, TRUE, GL_DYNAMIC_DRAW_ARB)
: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK, TRUE, GL_STREAM_DRAW_ARB)
{
mRenderPass = LLRenderPass::PASS_ALPHA;
mDrawableType = LLPipeline::RENDER_TYPE_PARTICLES;

View File

@ -1330,7 +1330,7 @@ U32 LLVOTree::getPartitionType() const
}
LLTreePartition::LLTreePartition()
: LLSpatialPartition(0, FALSE, 0)
: LLSpatialPartition(0, FALSE, GL_DYNAMIC_DRAW_ARB)
{
mDrawableType = LLPipeline::RENDER_TYPE_TREE;
mPartitionType = LLViewerRegion::PARTITION_TREE;

View File

@ -289,7 +289,7 @@ U32 LLVOVoidWater::getPartitionType() const
}
LLWaterPartition::LLWaterPartition()
: LLSpatialPartition(0, FALSE, 0)
: LLSpatialPartition(0, FALSE, GL_DYNAMIC_DRAW_ARB)
{
mInfiniteFarClip = TRUE;
mDrawableType = LLPipeline::RENDER_TYPE_WATER;

View File

@ -383,6 +383,7 @@ void LLPipeline::init()
sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
sUseTriStrips = gSavedSettings.getBOOL("RenderUseTriStrips");
LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("RenderUseStreamVBO");
LLVertexBuffer::sPreferStreamDraw = gSavedSettings.getBOOL("RenderPreferStreamDraw");
sRenderAttachedLights = gSavedSettings.getBOOL("RenderAttachedLights");
sRenderAttachedParticles = gSavedSettings.getBOOL("RenderAttachedParticles");
@ -5795,6 +5796,8 @@ void LLPipeline::resetVertexBuffers()
sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
sUseTriStrips = gSavedSettings.getBOOL("RenderUseTriStrips");
LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("RenderUseStreamVBO");
LLVertexBuffer::sPreferStreamDraw = gSavedSettings.getBOOL("RenderPreferStreamDraw");
LLVertexBuffer::sEnableVBOs = gSavedSettings.getBOOL("RenderVBOEnable");
sBakeSunlight = gSavedSettings.getBOOL("RenderBakeSunlight");
sNoAlpha = gSavedSettings.getBOOL("RenderNoAlpha");
@ -5853,24 +5856,6 @@ void LLPipeline::renderObjects(U32 type, U32 mask, BOOL texture)
gGLLastMatrix = NULL;
}
void LLPipeline::setUseVBO(BOOL use_vbo)
{
if (use_vbo != LLVertexBuffer::sEnableVBOs)
{
if (use_vbo)
{
llinfos << "Enabling VBO." << llendl;
}
else
{
llinfos << "Disabling VBO." << llendl;
}
resetVertexBuffers();
LLVertexBuffer::initClass(use_vbo);
}
}
void apply_cube_face_rotation(U32 face)
{
switch (face)

View File

@ -119,7 +119,6 @@ public:
void allocatePhysicsBuffer();
void resetVertexBuffers(LLDrawable* drawable);
void setUseVBO(BOOL use_vbo);
void generateImpostor(LLVOAvatar* avatar);
void bindScreenToTexture();
void renderBloom(BOOL for_snapshot, F32 zoom_factor = 1.f, int subfield = 0);