diff options
Diffstat (limited to 'indra/newview/pipeline.cpp')
-rw-r--r-- | indra/newview/pipeline.cpp | 230 |
1 files changed, 199 insertions, 31 deletions
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 9266c84540..3a1edb0d00 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -211,6 +211,7 @@ extern S32 gBoxFrame; extern BOOL gDisplaySwapBuffers; extern BOOL gDebugGL; extern BOOL gCubeSnapshot; +extern BOOL gSnapshotNoPost; bool gAvatarBacklight = false; @@ -786,10 +787,8 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) resY /= res_mod; } - if (LLPipeline::sRenderTransparentWater) - { //water reflection texture - mWaterDis.allocate(resX, resY, GL_RGBA, true); - } + //water reflection texture (always needed as scratch space whether or not transparent water is enabled) + mWaterDis.allocate(resX, resY, GL_RGBA16F, true); if (RenderUIBuffer) { @@ -2310,13 +2309,6 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result) gSky.mVOWLSkyp->mDrawable->setVisible(camera); sCull->pushDrawable(gSky.mVOWLSkyp->mDrawable); } - - bool render_water = !sReflectionRender && (hasRenderType(LLPipeline::RENDER_TYPE_WATER) || hasRenderType(LLPipeline::RENDER_TYPE_VOIDWATER)); - - if (render_water) - { - LLWorld::getInstance()->precullWaterObjects(camera, sCull, render_water); - } } void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera) @@ -3827,10 +3819,7 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera, bool do_occlusion) poolp->endDeferredPass(i); LLVertexBuffer::unbind(); - if (gDebugGL || gDebugPipeline) - { - LLGLState::checkStates(); - } + LLGLState::checkStates(); } } else @@ -3877,6 +3866,20 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera) LLGLEnable cull(GL_CULL_FACE); + bool done_atmospherics = LLPipeline::sRenderingHUDs; //skip atmospherics on huds + bool done_water_haze = done_atmospherics; + + // do atmospheric haze just before post water alpha + U32 atmospherics_pass = LLDrawPool::POOL_ALPHA_POST_WATER; + + if (LLPipeline::sUnderWaterRender) + { // if under water, do atmospherics just before the water pass + atmospherics_pass = LLDrawPool::POOL_WATER; + } + + // do water haze just before pre water alpha + U32 water_haze_pass = LLDrawPool::POOL_ALPHA_PRE_WATER; + calcNearbyLights(camera); setupHWLights(); @@ -3896,6 +3899,18 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera) cur_type = poolp->getType(); + if (cur_type >= atmospherics_pass && !done_atmospherics) + { // do atmospherics against depth buffer before rendering alpha + doAtmospherics(); + done_atmospherics = true; + } + + if (cur_type >= water_haze_pass && !done_water_haze) + { // do water haze against depth buffer before rendering alpha + doWaterHaze(); + done_water_haze = true; + } + pool_set_t::iterator iter2 = iter1; if (hasRenderType(poolp->getType()) && poolp->getNumPostDeferredPasses() > 0) { @@ -6791,7 +6806,7 @@ void LLPipeline::gammaCorrect(LLRenderTarget* src, LLRenderTarget* dst) { { LL_PROFILE_GPU_ZONE("gamma correct"); - static LLCachedControl<bool> no_post(gSavedSettings, "RenderDisablePostProcessing", false); + static LLCachedControl<bool> buildNoPost(gSavedSettings, "RenderDisablePostProcessing", false); LLGLDepthTest depth(GL_FALSE, GL_FALSE); @@ -6801,7 +6816,8 @@ void LLPipeline::gammaCorrect(LLRenderTarget* src, LLRenderTarget* dst) { LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); - LLGLSLShader& shader = no_post && gFloaterTools->isAvailable() ? gNoPostGammaCorrectProgram : // no post (no gamma, no exposure, no tonemapping) + bool no_post = gSnapshotNoPost || (buildNoPost && gFloaterTools->isAvailable()); + LLGLSLShader& shader = no_post ? gNoPostGammaCorrectProgram : // no post (no gamma, no exposure, no tonemapping) psky->getReflectionProbeAmbiance(should_auto_adjust) == 0.f ? gLegacyPostGammaCorrectProgram : gDeferredPostGammaCorrectProgram; @@ -7458,7 +7474,7 @@ void LLPipeline::bindDeferredShaderFast(LLGLSLShader& shader) } } -void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_target) +void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_target, LLRenderTarget* depth_target) { LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; LLRenderTarget* deferred_target = &mRT->deferredScreen; @@ -7497,7 +7513,14 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_ channel = shader.enableTexture(LLShaderMgr::DEFERRED_DEPTH, deferred_target->getUsage()); if (channel > -1) { - gGL.getTexUnit(channel)->bind(deferred_target, TRUE); + if (depth_target) + { + gGL.getTexUnit(channel)->bind(depth_target, TRUE); + } + else + { + gGL.getTexUnit(channel)->bind(deferred_target, TRUE); + } stop_glerror(); } @@ -7875,7 +7898,7 @@ void LLPipeline::renderDeferredLighting() if (RenderDeferredAtmospheric) { // apply sunlight contribution - LLGLSLShader &soften_shader = LLPipeline::sUnderWaterRender ? gDeferredSoftenWaterProgram : gDeferredSoftenProgram; + LLGLSLShader &soften_shader = gDeferredSoftenProgram; LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("renderDeferredLighting - atmospherics"); LL_PROFILE_GPU_ZONE("atmospherics"); @@ -7904,7 +7927,7 @@ void LLPipeline::renderDeferredLighting() mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); } - unbindDeferredShader(LLPipeline::sUnderWaterRender ? gDeferredSoftenWaterProgram : gDeferredSoftenProgram); + unbindDeferredShader(gDeferredSoftenProgram); } static LLCachedControl<S32> local_light_count(gSavedSettings, "RenderLocalLightCount", 256); @@ -8056,7 +8079,7 @@ void LLPipeline::renderDeferredLighting() LLVector4a center; center.load3(drawablep->getPositionAgent().mV); - const F32 *c = center.getF32ptr(); + const F32* c = center.getF32ptr(); F32 s = volume->getLightRadius() * 1.5f; sVisibleLightCount++; @@ -8105,8 +8128,8 @@ void LLPipeline::renderDeferredLighting() U32 idx = count - 1; bindDeferredShader(gDeferredMultiLightProgram[idx]); gDeferredMultiLightProgram[idx].uniform1i(LLShaderMgr::MULTI_LIGHT_COUNT, count); - gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT, count, (GLfloat *) light); - gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT_COL, count, (GLfloat *) col); + gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT, count, (GLfloat*)light); + gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT_COL, count, (GLfloat*)col); gDeferredMultiLightProgram[idx].uniform1f(LLShaderMgr::MULTI_LIGHT_FAR_Z, far_z); far_z = 0.f; count = 0; @@ -8124,11 +8147,11 @@ void LLPipeline::renderDeferredLighting() for (LLDrawable::drawable_list_t::iterator iter = fullscreen_spot_lights.begin(); iter != fullscreen_spot_lights.end(); ++iter) { - LLDrawable *drawablep = *iter; - LLVOVolume *volume = drawablep->getVOVolume(); - LLVector3 center = drawablep->getPositionAgent(); - F32 * c = center.mV; - F32 light_size_final = volume->getLightRadius() * 1.5f; + LLDrawable* drawablep = *iter; + LLVOVolume* volume = drawablep->getVOVolume(); + LLVector3 center = drawablep->getPositionAgent(); + F32* c = center.mV; + F32 light_size_final = volume->getLightRadius() * 1.5f; F32 light_falloff_final = volume->getLightFalloff(DEFERRED_LIGHT_FALLOFF); sVisibleLightCount++; @@ -8153,13 +8176,11 @@ void LLPipeline::renderDeferredLighting() } } - gGL.setColorMask(true, true); } { // render non-deferred geometry (alpha, fullbright, glow) LLGLDisable blend(GL_BLEND); - //LLGLDisable stencil(GL_STENCIL_TEST); pushRenderTypeMask(); andRenderTypeMask(LLPipeline::RENDER_TYPE_ALPHA, @@ -8210,6 +8231,153 @@ void LLPipeline::renderDeferredLighting() gGL.setColorMask(true, true); } +void LLPipeline::doAtmospherics() +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; + + if (sImpostorRender) + { // do not attempt atmospherics on impostors + return; + } + + if (RenderDeferredAtmospheric) + { + { + // copy depth buffer for use in haze shader (use water displacement map as temp storage) + LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS); + + LLRenderTarget& src = gPipeline.mRT->screen; + LLRenderTarget& depth_src = gPipeline.mRT->deferredScreen; + LLRenderTarget& dst = gPipeline.mWaterDis; + + mRT->screen.flush(); + dst.bindTarget(); + gCopyDepthProgram.bind(); + + S32 diff_map = gCopyDepthProgram.getTextureChannel(LLShaderMgr::DIFFUSE_MAP); + S32 depth_map = gCopyDepthProgram.getTextureChannel(LLShaderMgr::DEFERRED_DEPTH); + + gGL.getTexUnit(diff_map)->bind(&src); + gGL.getTexUnit(depth_map)->bind(&depth_src, true); + + gGL.setColorMask(false, false); + gPipeline.mScreenTriangleVB->setBuffer(); + gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); + + dst.flush(); + mRT->screen.bindTarget(); + } + + LLGLEnable blend(GL_BLEND); + gGL.blendFunc(LLRender::BF_ONE, LLRender::BF_SOURCE_ALPHA, LLRender::BF_ZERO, LLRender::BF_SOURCE_ALPHA); + gGL.setColorMask(true, true); + + // apply haze + LLGLSLShader& haze_shader = gHazeProgram; + + LL_PROFILE_GPU_ZONE("haze"); + bindDeferredShader(haze_shader, nullptr, &mWaterDis); + + LLEnvironment& environment = LLEnvironment::instance(); + haze_shader.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0); + haze_shader.uniform3fv(LLShaderMgr::LIGHTNORM, 1, environment.getClampedLightNorm().mV); + + haze_shader.uniform4fv(LLShaderMgr::WATER_WATERPLANE, 1, LLDrawPoolAlpha::sWaterPlane.mV); + + LLGLDepthTest depth(GL_FALSE); + + // full screen blit + mScreenTriangleVB->setBuffer(); + mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); + + unbindDeferredShader(haze_shader); + + gGL.setSceneBlendType(LLRender::BT_ALPHA); + } +} + +void LLPipeline::doWaterHaze() +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; + if (sImpostorRender) + { // do not attempt water haze on impostors + return; + } + + if (RenderDeferredAtmospheric) + { + // copy depth buffer for use in haze shader (use water displacement map as temp storage) + { + LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS); + + LLRenderTarget& src = gPipeline.mRT->screen; + LLRenderTarget& depth_src = gPipeline.mRT->deferredScreen; + LLRenderTarget& dst = gPipeline.mWaterDis; + + mRT->screen.flush(); + dst.bindTarget(); + gCopyDepthProgram.bind(); + + S32 diff_map = gCopyDepthProgram.getTextureChannel(LLShaderMgr::DIFFUSE_MAP); + S32 depth_map = gCopyDepthProgram.getTextureChannel(LLShaderMgr::DEFERRED_DEPTH); + + gGL.getTexUnit(diff_map)->bind(&src); + gGL.getTexUnit(depth_map)->bind(&depth_src, true); + + gGL.setColorMask(false, false); + gPipeline.mScreenTriangleVB->setBuffer(); + gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); + + dst.flush(); + mRT->screen.bindTarget(); + } + + LLGLEnable blend(GL_BLEND); + gGL.blendFunc(LLRender::BF_ONE, LLRender::BF_SOURCE_ALPHA, LLRender::BF_ZERO, LLRender::BF_SOURCE_ALPHA); + + gGL.setColorMask(true, true); + + // apply haze + LLGLSLShader& haze_shader = gHazeWaterProgram; + + LL_PROFILE_GPU_ZONE("haze"); + bindDeferredShader(haze_shader, nullptr, &mWaterDis); + + haze_shader.uniform4fv(LLShaderMgr::WATER_WATERPLANE, 1, LLDrawPoolAlpha::sWaterPlane.mV); + + static LLStaticHashedString above_water_str("above_water"); + haze_shader.uniform1i(above_water_str, sUnderWaterRender ? -1 : 1); + + if (LLPipeline::sUnderWaterRender) + { + LLGLDepthTest depth(GL_FALSE); + + // full screen blit + mScreenTriangleVB->setBuffer(); + mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); + } + else + { + //render water patches like LLDrawPoolWater does + LLGLDepthTest depth(GL_FALSE); + LLGLDisable cull(GL_CULL_FACE); + + gGLLastMatrix = NULL; + gGL.loadMatrix(gGLModelView); + + if (mWaterPool) + { + mWaterPool->pushFaceGeometry(); + } + } + + unbindDeferredShader(haze_shader); + + + gGL.setSceneBlendType(LLRender::BT_ALPHA); + } +} + void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep) { //construct frustum |