summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
authorDave Parks <davep@lindenlab.com>2011-01-04 18:34:27 -0600
committerDave Parks <davep@lindenlab.com>2011-01-04 18:34:27 -0600
commit808cd0fcbfe017c1212fb0c1d423fa06bb06c148 (patch)
treeed2091597430c0fef9f6705e5003d4661a9d2ea7 /indra/newview
parent1e647e2cd2d0385bcf46fa054056de3615e95377 (diff)
VWR-21927 Fix for water reflections causing LoD updates.
SH-735 Potential fix for ATI X1950 wasting time in occlusion culling.
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/llspatialpartition.cpp155
-rw-r--r--indra/newview/llspatialpartition.h5
-rw-r--r--indra/newview/pipeline.cpp72
3 files changed, 129 insertions, 103 deletions
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index 7adffb6925..cb72f35eee 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -222,7 +222,17 @@ static U8 sOcclusionIndices[] =
b000, b110, b100, b101, b001, b011, b010, b110,
};
-U8* get_box_fan_indices(LLCamera* camera, const LLVector4a& center)
+U32 get_box_fan_indices(LLCamera* camera, const LLVector4a& center)
+{
+ LLVector4a origin;
+ origin.load3(camera->getOrigin().mV);
+
+ S32 cypher = center.greaterThan(origin).getGatheredBits() & 0x7;
+
+ return cypher*8;
+}
+
+U8* get_box_fan_indices_ptr(LLCamera* camera, const LLVector4a& center)
{
LLVector4a origin;
origin.load3(camera->getOrigin().mV);
@@ -231,12 +241,21 @@ U8* get_box_fan_indices(LLCamera* camera, const LLVector4a& center)
return sOcclusionIndices+cypher*8;
}
-
+
+
void LLSpatialGroup::buildOcclusion()
{
- if (!mOcclusionVerts)
+ if (mOcclusionVerts.isNull())
{
- mOcclusionVerts = new LLVector4a[8];
+ mOcclusionVerts = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX, GL_DYNAMIC_DRAW_ARB);
+ mOcclusionVerts->allocateBuffer(8, 64, true);
+
+ LLStrider<U16> idx;
+ mOcclusionVerts->getIndexStrider(idx);
+ for (U32 i = 0; i < 64; i++)
+ {
+ *idx++ = sOcclusionIndices[i];
+ }
}
LLVector4a fudge;
@@ -251,7 +270,12 @@ void LLSpatialGroup::buildOcclusion()
r.setMin(r, r2);
- LLVector4a* v = mOcclusionVerts;
+ LLStrider<LLVector3> pos;
+
+ mOcclusionVerts->getVertexStrider(pos);
+
+ LLVector4a* v = (LLVector4a*) pos.get();
+
const LLVector4a& c = mBounds[0];
const LLVector4a& s = r;
@@ -275,10 +299,13 @@ void LLSpatialGroup::buildOcclusion()
for (S32 i = 0; i < 8; ++i)
{
- v[i] = s;
- v[i].mul(octant[i]);
- v[i].add(c);
+ LLVector4a p;
+ p.setMul(s, octant[i]);
+ p.add(c);
+ v[i] = p;
}
+
+ mOcclusionVerts->setBuffer(0);
clearState(LLSpatialGroup::OCCLUSION_DIRTY);
}
@@ -339,7 +366,6 @@ LLSpatialGroup::~LLSpatialGroup()
sQueryPool.release(mOcclusionQuery[LLViewerCamera::sCurCameraID]);
}
- delete [] mOcclusionVerts;
mOcclusionVerts = NULL;
LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
@@ -881,12 +907,9 @@ void LLSpatialGroup::shift(const LLVector4a &offset)
gPipeline.markRebuild(this, TRUE);
}
- if (mOcclusionVerts)
+ if (mOcclusionVerts.notNull())
{
- for (U32 i = 0; i < 8; i++)
- {
- mOcclusionVerts[i].add(offset);
- }
+ setState(OCCLUSION_DIRTY);
}
}
@@ -1423,7 +1446,6 @@ void LLSpatialGroup::destroyGL()
}
}
- delete [] mOcclusionVerts;
mOcclusionVerts = NULL;
for (LLSpatialGroup::element_iter i = getData().begin(); i != getData().end(); ++i)
@@ -1573,57 +1595,58 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera)
else
{
if (!isOcclusionState(QUERY_PENDING) || isOcclusionState(DISCARD_QUERY))
- { //no query pending, or previous query to be discarded
- LLFastTimer t(FTM_RENDER_OCCLUSION);
+ {
+ { //no query pending, or previous query to be discarded
+ LLFastTimer t(FTM_RENDER_OCCLUSION);
- if (!mOcclusionQuery[LLViewerCamera::sCurCameraID])
- {
- mOcclusionQuery[LLViewerCamera::sCurCameraID] = sQueryPool.allocate();
- }
+ if (!mOcclusionQuery[LLViewerCamera::sCurCameraID])
+ {
+ mOcclusionQuery[LLViewerCamera::sCurCameraID] = sQueryPool.allocate();
+ }
- if (!mOcclusionVerts || isState(LLSpatialGroup::OCCLUSION_DIRTY))
- {
- buildOcclusion();
- }
-
- // Depth clamp all water to avoid it being culled as a result of being
- // behind the far clip plane, and in the case of edge water to avoid
- // it being culled while still visible.
- bool const use_depth_clamp = gGLManager.mHasDepthClamp &&
- (mSpatialPartition->mDrawableType == LLDrawPool::POOL_WATER ||
- mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER);
- if (use_depth_clamp)
- {
- glEnable(GL_DEPTH_CLAMP);
- }
-
- U32 mode = gGLManager.mHasOcclusionQuery2 ? GL_ANY_SAMPLES_PASSED : GL_SAMPLES_PASSED_ARB;
+ if (mOcclusionVerts.isNull() || isState(LLSpatialGroup::OCCLUSION_DIRTY))
+ {
+ buildOcclusion();
+ }
+
+ // Depth clamp all water to avoid it being culled as a result of being
+ // behind the far clip plane, and in the case of edge water to avoid
+ // it being culled while still visible.
+ bool const use_depth_clamp = gGLManager.mHasDepthClamp &&
+ (mSpatialPartition->mDrawableType == LLDrawPool::POOL_WATER ||
+ mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER);
+ if (use_depth_clamp)
+ {
+ glEnable(GL_DEPTH_CLAMP);
+ }
+
+ U32 mode = gGLManager.mHasOcclusionQuery2 ? GL_ANY_SAMPLES_PASSED : GL_SAMPLES_PASSED_ARB;
- glBeginQueryARB(mode, mOcclusionQuery[LLViewerCamera::sCurCameraID]);
-
- glVertexPointer(3, GL_FLOAT, 16, mOcclusionVerts);
- if (camera->getOrigin().isExactlyZero())
- { //origin is invalid, draw entire box
- glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8,
- GL_UNSIGNED_BYTE, sOcclusionIndices);
- glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8,
- GL_UNSIGNED_BYTE, sOcclusionIndices+b111*8);
- }
- else
- {
- glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8,
- GL_UNSIGNED_BYTE, get_box_fan_indices(camera, mBounds[0]));
- }
- glEndQueryARB(mode);
-
- if (use_depth_clamp)
- {
- glDisable(GL_DEPTH_CLAMP);
+ glBeginQueryARB(mode, mOcclusionQuery[LLViewerCamera::sCurCameraID]);
+
+ mOcclusionVerts->setBuffer(LLVertexBuffer::MAP_VERTEX);
+
+ 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);
+
+ if (use_depth_clamp)
+ {
+ glDisable(GL_DEPTH_CLAMP);
+ }
}
- }
- setOcclusionState(LLSpatialGroup::QUERY_PENDING);
- clearOcclusionState(LLSpatialGroup::DISCARD_QUERY);
+ setOcclusionState(LLSpatialGroup::QUERY_PENDING);
+ clearOcclusionState(LLSpatialGroup::DISCARD_QUERY);
+ }
}
}
}
@@ -2617,17 +2640,17 @@ void renderVisibility(LLSpatialGroup* group, LLCamera* camera)
gGL.color4f(0.f, 0.75f, 0.f, 0.5f);
pushBufferVerts(group, LLVertexBuffer::MAP_VERTEX);
}
- else if (camera && group->mOcclusionVerts)
+ else if (camera && group->mOcclusionVerts.notNull())
{
LLVertexBuffer::unbind();
- glVertexPointer(3, GL_FLOAT, 16, group->mOcclusionVerts);
-
+ group->mOcclusionVerts->setBuffer(LLVertexBuffer::MAP_VERTEX);
+
glColor4f(1.0f, 0.f, 0.f, 0.5f);
- glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, GL_UNSIGNED_BYTE, get_box_fan_indices(camera, group->mBounds[0]));
+ group->mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, group->mBounds[0]));
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glColor4f(1.0f, 1.f, 1.f, 1.0f);
- glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, GL_UNSIGNED_BYTE, get_box_fan_indices(camera, group->mBounds[0]));
+ group->mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, group->mBounds[0]));
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
}
diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h
index 16ec9f780b..85fd66b297 100644
--- a/indra/newview/llspatialpartition.h
+++ b/indra/newview/llspatialpartition.h
@@ -59,7 +59,8 @@ S32 AABBSphereIntersectR2(const LLVector3& min, const LLVector3& max, const LLVe
void pushVerts(LLFace* face, U32 mask);
// get index buffer for binary encoded axis vertex buffer given a box at center being viewed by given camera
-U8* get_box_fan_indices(LLCamera* camera, const LLVector4a& center);
+U32 get_box_fan_indices(LLCamera* camera, const LLVector4a& center);
+U8* get_box_fan_indices_ptr(LLCamera* camera, const LLVector4a& center);
class LLDrawInfo : public LLRefCount
{
@@ -393,7 +394,7 @@ public:
LLSpatialPartition* mSpatialPartition;
LLPointer<LLVertexBuffer> mVertexBuffer;
- LLVector4a* mOcclusionVerts;
+ LLPointer<LLVertexBuffer> mOcclusionVerts;
GLuint mOcclusionQuery[LLViewerCamera::NUM_CAMERAS];
U32 mBufferUsage;
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 1f1c8d46f5..f5e2a5033f 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -7084,6 +7084,8 @@ void LLPipeline::renderDeferredLighting()
std::list<LLVector4> light_colors;
+ LLVertexBuffer::unbind();
+
F32 v[24];
glVertexPointer(3, GL_FLOAT, 0, v);
@@ -7173,7 +7175,7 @@ void LLPipeline::renderDeferredLighting()
glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], s*s);
glColor4f(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f);
glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8,
- GL_UNSIGNED_BYTE, get_box_fan_indices(camera, center));
+ GL_UNSIGNED_BYTE, get_box_fan_indices_ptr(camera, center));
stop_glerror();
}
}
@@ -7239,7 +7241,7 @@ void LLPipeline::renderDeferredLighting()
glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], s*s);
glColor4f(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f);
glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8,
- GL_UNSIGNED_BYTE, get_box_fan_indices(camera, center));
+ GL_UNSIGNED_BYTE, get_box_fan_indices_ptr(camera, center));
}
gDeferredSpotLightProgram.disableTexture(LLViewerShaderMgr::DEFERRED_PROJECTION);
unbindDeferredShader(gDeferredSpotLightProgram);
@@ -7650,11 +7652,6 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
LLCamera camera = camera_in;
camera.setFar(camera.getFar()*0.87654321f);
LLPipeline::sReflectionRender = TRUE;
- S32 occlusion = LLPipeline::sUseOcclusion;
-
- LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
-
- LLPipeline::sUseOcclusion = llmin(occlusion, 1);
gPipeline.pushRenderTypeMask();
@@ -7693,19 +7690,20 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
glClearColor(0,0,0,0);
mWaterRef.bindTarget();
+ LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WATER0;
gGL.setColorMask(true, true);
mWaterRef.clear();
gGL.setColorMask(true, false);
mWaterRef.getViewport(gGLViewport);
-
+
stop_glerror();
glPushMatrix();
mat.set_scale(glh::vec3f(1,1,-1));
mat.set_translate(glh::vec3f(0,0,height*2.f));
-
+
glh::matrix4f current = glh_get_current_modelview();
mat = current * mat;
@@ -7725,22 +7723,24 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
glCullFace(GL_FRONT);
static LLCullResult ref_result;
-
+
if (LLDrawPoolWater::sNeedsDistortionUpdate)
{
//initial sky pass (no user clip plane)
{ //mask out everything but the sky
gPipeline.pushRenderTypeMask();
gPipeline.andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY,
- LLPipeline::RENDER_TYPE_WL_SKY,
- LLPipeline::END_RENDER_TYPES);
+ LLPipeline::RENDER_TYPE_WL_SKY,
+ LLPipeline::END_RENDER_TYPES);
+
static LLCullResult result;
updateCull(camera, result);
stateSort(camera, result);
+
andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY,
- LLPipeline::RENDER_TYPE_CLOUDS,
- LLPipeline::RENDER_TYPE_WL_SKY,
- LLPipeline::END_RENDER_TYPES);
+ LLPipeline::RENDER_TYPE_CLOUDS,
+ LLPipeline::RENDER_TYPE_WL_SKY,
+ LLPipeline::END_RENDER_TYPES);
renderGeom(camera, TRUE);
gPipeline.popRenderTypeMask();
@@ -7749,23 +7749,23 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
gPipeline.pushRenderTypeMask();
clearRenderTypeMask(LLPipeline::RENDER_TYPE_WATER,
- LLPipeline::RENDER_TYPE_VOIDWATER,
- LLPipeline::RENDER_TYPE_GROUND,
- LLPipeline::RENDER_TYPE_SKY,
- LLPipeline::RENDER_TYPE_CLOUDS,
- LLPipeline::END_RENDER_TYPES);
+ LLPipeline::RENDER_TYPE_VOIDWATER,
+ LLPipeline::RENDER_TYPE_GROUND,
+ LLPipeline::RENDER_TYPE_SKY,
+ LLPipeline::RENDER_TYPE_CLOUDS,
+ LLPipeline::END_RENDER_TYPES);
- S32 detail = gSavedSettings.getS32("RenderReflectionDetail");
+ S32 detail = gSavedSettings.getS32("RenderReflectionDetail");
if (detail > 0)
{ //mask out selected geometry based on reflection detail
if (detail < 4)
{
clearRenderTypeMask(LLPipeline::RENDER_TYPE_PARTICLES, END_RENDER_TYPES);
- if (detail < 3)
- {
- clearRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR, END_RENDER_TYPES);
- if (detail < 2)
+ if (detail < 3)
{
+ clearRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR, END_RENDER_TYPES);
+ if (detail < 2)
+ {
clearRenderTypeMask(LLPipeline::RENDER_TYPE_VOLUME, END_RENDER_TYPES);
}
}
@@ -7776,16 +7776,16 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
updateCull(camera, ref_result, 1);
stateSort(camera, ref_result);
}
-
- if (LLDrawPoolWater::sNeedsDistortionUpdate)
- {
- if (gSavedSettings.getS32("RenderReflectionDetail") > 0)
+
+ if (LLDrawPoolWater::sNeedsDistortionUpdate)
{
- gPipeline.grabReferences(ref_result);
- LLGLUserClipPlane clip_plane(plane, mat, projection);
- renderGeom(camera);
- }
- }
+ if (gSavedSettings.getS32("RenderReflectionDetail") > 0)
+ {
+ gPipeline.grabReferences(ref_result);
+ LLGLUserClipPlane clip_plane(plane, mat, projection);
+ renderGeom(camera);
+ }
+ }
gPipeline.popRenderTypeMask();
}
@@ -7823,6 +7823,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
LLColor4& col = LLDrawPoolWater::sWaterFogColor;
glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f);
mWaterDis.bindTarget();
+ LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WATER1;
mWaterDis.getViewport(gGLViewport);
if (!LLPipeline::sUnderWaterRender || LLDrawPoolWater::sNeedsReflectionUpdate)
@@ -7860,7 +7861,6 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
LLDrawPoolWater::sNeedsReflectionUpdate = FALSE;
LLDrawPoolWater::sNeedsDistortionUpdate = FALSE;
LLViewerCamera::getInstance()->setUserClipPlane(LLPlane(-pnorm, -pd));
- LLPipeline::sUseOcclusion = occlusion;
LLGLState::checkStates();
LLGLState::checkTextureChannels();
@@ -7870,6 +7870,8 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
{
gAgentAvatarp->updateAttachmentVisibility(gAgentCamera.getCameraMode());
}
+
+ LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
}
}