diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 63e60b3bd8..02f32ef3a1 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -5072,10 +5072,10 @@ void LLWindowWin32::LLWindowWin32Thread::updateVRAMUsage() void LLWindowWin32::LLWindowWin32Thread::close() { assert_main_thread(); - if (! mQueue.isClosed() && gDisconnected) + if (!mQueue->isClosed() && gDisconnected) { LL_DEBUGS("ThreadPool") << mName << " closing queue and joining threads" << LL_ENDL; - mQueue.close(); + mQueue->close(); for (auto& pair: mThreads) { LL_DEBUGS("ThreadPool") << mName << " waiting on thread " << pair.first << LL_ENDL; diff --git a/indra/newview/app_settings/shaders/class1/interface/glowcombineV.glsl b/indra/newview/app_settings/shaders/class1/interface/glowcombineV.glsl index e08284f762..71fa095505 100644 --- a/indra/newview/app_settings/shaders/class1/interface/glowcombineV.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/glowcombineV.glsl @@ -35,7 +35,7 @@ VARYING vec2 vary_texcoord1; void main() { gl_Position = vec4(position.xyz, 1.0); - vary_texcoord0 = texcoord0; - vary_texcoord1 = texcoord1; + vary_texcoord0 = position.xy * 0.5 + 0.5; + vary_texcoord1 = vary_texcoord0; } diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index ca47c0abfb..7c6596e7a4 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -193,8 +193,6 @@ std::string USE_TEXTURE; LLRender::eTexIndex LLPanelFace::getTextureChannelToEdit() { - - LLRender::eTexIndex channel_to_edit = LLRender::DIFFUSE_MAP; if (mComboMatMedia) { @@ -216,6 +214,17 @@ LLRender::eTexIndex LLPanelFace::getTextureChannelToEdit() return channel_to_edit; } +LLRender::eTexIndex LLPanelFace::getTextureDropChannel() +{ + if (mComboMatMedia && mComboMatMedia->getCurrentIndex() == MATMEDIA_MATERIAL) + { + LLRadioGroup* radio_mat_type = getChild("radio_material_type"); + return LLRender::eTexIndex(radio_mat_type->getSelectedIndex()); + } + + return LLRender::eTexIndex(MATTYPE_DIFFUSE); +} + // Things the UI provides... // LLUUID LLPanelFace::getCurrentNormalMap() { return mBumpyTextureCtrl->getImageAssetID(); } @@ -1691,7 +1700,6 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) enabled = editable && has_pbr_material; material_type = mRadioPbrType->getSelectedIndex(); } - LLSelectMgr::getInstance()->setTextureChannel(LLRender::eTexIndex(material_type)); switch (material_type) { diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h index 9e09d9dbc9..b625cba1eb 100644 --- a/indra/newview/llpanelface.h +++ b/indra/newview/llpanelface.h @@ -121,6 +121,7 @@ public: } LLRender::eTexIndex getTextureChannelToEdit(); + LLRender::eTexIndex getTextureDropChannel(); protected: void navigateToTitleMedia(const std::string url); diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index a2d6303ada..4da89ff182 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -1109,10 +1109,6 @@ void LLSelectMgr::addAsIndividual(LLViewerObject *objectp, S32 face, BOOL undoab // check to see if object is already in list LLSelectNode *nodep = mSelectedObjects->findNode(objectp); - // Reset (in anticipation of being set to an appropriate value by panel refresh, if they're up) - // - setTextureChannel(LLRender::DIFFUSE_MAP); - // if not in list, add it if (!nodep) { diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index fa57fda828..5fddee3f59 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -692,11 +692,6 @@ public: void saveSelectedShinyColors(); void saveSelectedObjectTextures(); - // Sets which texture channel to query for scale and rot of display - // and depends on UI state of LLPanelFace when editing - void setTextureChannel(LLRender::eTexIndex texIndex) { mTextureChannel = texIndex; } - LLRender::eTexIndex getTextureChannel() { return mTextureChannel; } - void selectionUpdatePhysics(BOOL use_physics); void selectionUpdateTemporary(BOOL is_temporary); void selectionUpdatePhantom(BOOL is_ghost); diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index fc1809ee95..5ef36bb672 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -302,7 +302,59 @@ void LLFloaterTexturePicker::stopUsingPipette() void LLFloaterTexturePicker::updateImageStats() { - if (mTexturep.notNull()) + if (mGLTFMaterial.notNull()) + { + S32 width = 0; + S32 height = 0; + + bool has_texture = false; + + if (mGLTFMaterial->mBaseColorTexture) + { + width = llmax(width, mGLTFMaterial->mBaseColorTexture->getFullWidth()); + height = llmax(height, mGLTFMaterial->mBaseColorTexture->getFullHeight()); + has_texture = true; + } + if (mGLTFMaterial->mNormalTexture) + { + width = llmax(width, mGLTFMaterial->mNormalTexture->getFullWidth()); + height = llmax(height, mGLTFMaterial->mNormalTexture->getFullHeight()); + has_texture = true; + } + if (mGLTFMaterial->mMetallicRoughnessTexture) + { + width = llmax(width, mGLTFMaterial->mMetallicRoughnessTexture->getFullWidth()); + height = llmax(height, mGLTFMaterial->mMetallicRoughnessTexture->getFullHeight()); + has_texture = true; + } + if (mGLTFMaterial->mEmissiveTexture) + { + width = llmax(width, mGLTFMaterial->mEmissiveTexture->getFullWidth()); + height = llmax(height, mGLTFMaterial->mEmissiveTexture->getFullHeight()); + has_texture = true; + } + + if (width > 0 && height > 0) + { + std::string formatted_dims = llformat("%d x %d", width, height); + mResolutionLabel->setTextArg("[DIMENSIONS]", formatted_dims); + if (mOnUpdateImageStatsCallback) + { + mOnUpdateImageStatsCallback(mTexturep); + } + } + else if (has_texture) + { + // unknown resolution + mResolutionLabel->setTextArg("[DIMENSIONS]", std::string("[? x ?]")); + } + else + { + // No textures - no applicable resolution (may be show some max value instead?) + mResolutionLabel->setTextArg("[DIMENSIONS]", std::string("")); + } + } + else if (mTexturep.notNull()) { //RN: have we received header data for this image? if (mTexturep->getFullWidth() > 0 && mTexturep->getFullHeight() > 0) @@ -560,6 +612,8 @@ void LLFloaterTexturePicker::draw() static LLCachedControl max_opacity(gSavedSettings, "PickerContextOpacity", 0.4f); drawConeToOwner(mContextConeOpacity, max_opacity, mOwner); + // This is going to spam mOnUpdateImageStatsCallback, + // either move elsewhere or fix to cause update once per image updateImageStats(); // if we're inactive, gray out "apply immediate" checkbox @@ -571,30 +625,38 @@ void LLFloaterTexturePicker::draw() if( mOwner ) { mTexturep = NULL; - if(mImageAssetID.notNull()) - { - LLPointer texture = NULL; + mGLTFMaterial = NULL; + if (mImageAssetID.notNull()) + { + if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL) + { + mGLTFMaterial = (LLFetchedGLTFMaterial*) gGLTFMaterialList.getMaterial(mImageAssetID); + } + else + { + LLPointer texture = NULL; - if (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(mImageAssetID)) - { - // TODO: Fix this! Picker is not warrantied to be connected to a selection - // LLSelectMgr shouldn't be used in texture picker - LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); - if (obj) - { - LLViewerTexture* viewerTexture = obj->getBakedTextureForMagicId(mImageAssetID); - texture = viewerTexture ? dynamic_cast(viewerTexture) : NULL; - } - } + if (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(mImageAssetID)) + { + // TODO: Fix this! Picker is not warrantied to be connected to a selection + // LLSelectMgr shouldn't be used in texture picker + LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); + if (obj) + { + LLViewerTexture* viewerTexture = obj->getBakedTextureForMagicId(mImageAssetID); + texture = viewerTexture ? dynamic_cast(viewerTexture) : NULL; + } + } - if (texture.isNull()) - { - texture = LLViewerTextureManager::getFetchedTexture(mImageAssetID); - } + if (texture.isNull()) + { + texture = LLViewerTextureManager::getFetchedTexture(mImageAssetID); + } - mTexturep = texture; - mTexturep->setBoostLevel(LLGLTexture::BOOST_PREVIEW); - } + mTexturep = texture; + mTexturep->setBoostLevel(LLGLTexture::BOOST_PREVIEW); + } + } if (mTentativeLabel) { diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h index b40eb81240..6266db50ae 100644 --- a/indra/newview/lltexturectrl.h +++ b/indra/newview/lltexturectrl.h @@ -48,6 +48,7 @@ class LLRadioGroup; class LLFloaterTexturePicker; class LLInventoryItem; class LLViewerFetchedTexture; +class LLFetchedGLTFMaterial; // used for setting drag & drop callbacks. typedef boost::function drag_n_drop_callback; @@ -374,6 +375,7 @@ protected: void refreshInventoryFilter(); LLPointer mTexturep; + LLPointer mGLTFMaterial; LLView* mOwner; LLUUID mImageAssetID; // Currently selected texture diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index b454af7c5d..edb643ccc0 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -1211,7 +1211,7 @@ void LLToolDragAndDrop::dropTextureOneFace(LLViewerObject* hit_obj, if (gFloaterTools->getVisible() && panel_face) { - tex_channel = (tex_channel > -1) ? tex_channel : LLSelectMgr::getInstance()->getTextureChannel(); + tex_channel = (tex_channel > -1) ? tex_channel : panel_face->getTextureDropChannel(); switch (tex_channel) { diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 08fbb2300a..eb0a13abb2 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -1511,9 +1511,12 @@ void render_ui(F32 zoom_factor, int subfield) } { + // Render our post process prior to the HUD, UI, etc. + gPipeline.renderPostProcess(); + // draw hud and 3D ui elements into screen render target so they'll be able to use // the depth buffer (avoids extra copy of depth buffer per frame) - gPipeline.mRT->screen.bindTarget(); + gPipeline.screenTarget()->bindTarget(); // SL-15709 // NOTE: Tracy only allows one ZoneScoped per function. // Solutions are: @@ -1553,7 +1556,7 @@ void render_ui(F32 zoom_factor, int subfield) } } - gPipeline.mRT->screen.flush(); + gPipeline.screenTarget()->flush(); // apply gamma correction and post effects before rendering 2D UI gPipeline.renderFinalize(); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 7ab00459ad..020c28819a 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -987,7 +987,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) if (shadow_detail > 0 || ssao || RenderDepthOfField || samples > 0 || RlvActions::hasPostProcess()) // [/RLVa:KB] { //only need mRT->deferredLight for shadows OR ssao OR dof OR fxaa - if (!mRT->deferredLight.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_TEXTURE, FALSE)) return false; + if (!mRT->deferredLight.allocate(resX, resY, GL_RGBA16, FALSE, FALSE, LLTexUnit::TT_TEXTURE, FALSE)) return false; } else { @@ -7755,6 +7755,505 @@ void LLPipeline::bindScreenToTexture() static LLTrace::BlockTimerStatHandle FTM_RENDER_BLOOM("Bloom"); +void LLPipeline::renderPostProcess() +{ + LLVertexBuffer::unbind(); + LLGLState::checkStates(); + LLGLState::checkTextureChannels(); + + assertInitialized(); + + LLVector2 tc1(0, 0); + LLVector2 tc2((F32)mRT->screen.getWidth() * 2, (F32)mRT->screen.getHeight() * 2); + + LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM); + LL_PROFILE_GPU_ZONE("renderPostProcess"); + + gGL.color4f(1, 1, 1, 1); + LLGLDepthTest depth(GL_FALSE); + LLGLDisable blend(GL_BLEND); + LLGLDisable cull(GL_CULL_FACE); + + enableLightsFullbright(); + + LLGLDisable test(GL_ALPHA_TEST); + + gGL.setColorMask(true, true); + glClearColor(0, 0, 0, 0); + exoPostProcess::instance().ExodusRenderPostStack(&mRT->screen, &mRT->screen); // Import Vignette from Exodus + + if (sRenderGlow) + { + LL_PROFILE_GPU_ZONE("glow"); + mGlow[2].bindTarget(); + mGlow[2].clear(); + + gGlowExtractProgram.bind(); + F32 minLum = llmax((F32)RenderGlowMinLuminance, 0.0f); + F32 maxAlpha = RenderGlowMaxExtractAlpha; + F32 warmthAmount = RenderGlowWarmthAmount; + LLVector3 lumWeights = RenderGlowLumWeights; + LLVector3 warmthWeights = RenderGlowWarmthWeights; + + gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MIN_LUMINANCE, minLum); + gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MAX_EXTRACT_ALPHA, maxAlpha); + gGlowExtractProgram.uniform3f(LLShaderMgr::GLOW_LUM_WEIGHTS, lumWeights.mV[0], lumWeights.mV[1], + lumWeights.mV[2]); + gGlowExtractProgram.uniform3f(LLShaderMgr::GLOW_WARMTH_WEIGHTS, warmthWeights.mV[0], warmthWeights.mV[1], + warmthWeights.mV[2]); + gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_WARMTH_AMOUNT, warmthAmount); + + { + LLGLEnable blend_on(GL_BLEND); + LLGLEnable test(GL_ALPHA_TEST); + + gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA); + + mRT->screen.bindTexture(0, 0, LLTexUnit::TFO_POINT); + + gGL.color4f(1, 1, 1, 1); + gPipeline.enableLightsFullbright(); + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); + gGL.vertex2f(-1, -1); + + gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); + gGL.vertex2f(-1, 3); + + gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); + gGL.vertex2f(3, -1); + + gGL.end(); + + gGL.getTexUnit(0)->unbind(mRT->screen.getUsage()); + + mGlow[2].flush(); + + tc1.setVec(0, 0); + tc2.setVec(2, 2); + } + + // power of two between 1 and 1024 + U32 glowResPow = RenderGlowResolutionPow; + const U32 glow_res = llmax(1, llmin(1024, 1 << glowResPow)); + + S32 kernel = RenderGlowIterations * 2; + F32 delta = RenderGlowWidth / glow_res; + // Use half the glow width if we have the res set to less than 9 so that it looks + // almost the same in either case. + if (glowResPow < 9) + { + delta *= 0.5f; + } + F32 strength = RenderGlowStrength; + + gGlowProgram.bind(); + gGlowProgram.uniform1f(LLShaderMgr::GLOW_STRENGTH, strength); + + for (S32 i = 0; i < kernel; i++) + { + mGlow[i % 2].bindTarget(); + mGlow[i % 2].clear(); + + if (i == 0) + { + gGL.getTexUnit(0)->bind(&mGlow[2]); + } + else + { + gGL.getTexUnit(0)->bind(&mGlow[(i - 1) % 2]); + } + + if (i % 2 == 0) + { + gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, delta, 0); + } + else + { + gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, 0, delta); + } + + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); + gGL.vertex2f(-1, -1); + + gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); + gGL.vertex2f(-1, 3); + + gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); + gGL.vertex2f(3, -1); + + gGL.end(); + + mGlow[i % 2].flush(); + } + + gGlowProgram.unbind(); + } + else // !sRenderGlow, skip the glow ping-pong and just clear the result target + { + mGlow[1].bindTarget(); + mGlow[1].clear(); + mGlow[1].flush(); + } + + gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; + gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; + gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth(); + gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); + glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); + + tc2.setVec((F32)mRT->screen.getWidth(), (F32)mRT->screen.getHeight()); + + gGL.flush(); + + LLVertexBuffer::unbind(); + + // [RLVa:KB] - @setsphere + LLRenderTarget* pRenderBuffer = (RlvActions::hasBehaviour(RLV_BHVR_SETSPHERE)) ? &mRT->deferredLight : nullptr; + // [/RLVa:KB] + if (LLPipeline::sRenderDeferred) + { + // FIRE-16251: Depth of Field does not work underwater + //bool dof_enabled = !LLViewerCamera::getInstance()->cameraUnderWater() && + bool dof_enabled = (FSRenderDepthOfFieldUnderwater || !LLViewerCamera::getInstance()->cameraUnderWater()) && + // FIRE-16251 + (RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) && + RenderDepthOfField && + !gCubeSnapshot; + + bool multisample = RenderFSAASamples > 1 && mRT->fxaaBuffer.isComplete() && !gCubeSnapshot; + exoPostProcess::instance().multisample = multisample; // Import Vignette from Exodus +// [RLVa:KB] - @setsphere + if (multisample && !pRenderBuffer) + { + pRenderBuffer = &mRT->deferredLight; + } + // [/RLVa:KB] + + gViewerWindow->setup3DViewport(); + + if (dof_enabled) + { + LL_PROFILE_GPU_ZONE("dof"); + LLGLSLShader* shader = &gDeferredPostProgram; + LLGLDisable blend(GL_BLEND); + + // depth of field focal plane calculations + static F32 current_distance = 16.f; + static F32 start_distance = 16.f; + static F32 transition_time = 1.f; + + LLVector3 focus_point; + + // FIRE-16728 focus point lock & free focus DoF - based on a feature developed by NiranV Dean + static LLVector3 last_focus_point{}; + if (LLPipeline::FSFocusPointLocked && !last_focus_point.isExactlyZero()) + { + focus_point = last_focus_point; + } + else + { + // + LLViewerObject* obj = LLViewerMediaFocus::getInstance()->getFocusedObject(); + if (obj && obj->mDrawable && obj->isSelected()) + { // focus on selected media object + S32 face_idx = LLViewerMediaFocus::getInstance()->getFocusedFace(); + if (obj && obj->mDrawable) + { + LLFace* face = obj->mDrawable->getFace(face_idx); + if (face) + { + focus_point = face->getPositionAgent(); + } + } + } + }// support focus point lock + + if (focus_point.isExactlyZero()) + { + if (LLViewerJoystick::getInstance()->getOverrideCamera() || LLPipeline::FSFocusPointFollowsPointer) // FIRE-16728 Add free aim mouse and focus lock + { // focus on point under cursor + focus_point.set(gDebugRaycastIntersection.getF32ptr()); + } + else if (gAgentCamera.cameraMouselook()) + { // focus on point under mouselook crosshairs + LLVector4a result; + result.clear(); + + gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE, TRUE, NULL, &result); + + focus_point.set(result.getF32ptr()); + } + else + { + // focus on alt-zoom target + LLViewerRegion* region = gAgent.getRegion(); + if (region) + { + focus_point = LLVector3(gAgentCamera.getFocusGlobal() - region->getOriginGlobal()); + } + } + } + + // FIRE-16728 Add free aim mouse and focus lock + last_focus_point = focus_point; + // + LLVector3 eye = LLViewerCamera::getInstance()->getOrigin(); + F32 target_distance = 16.f; + if (!focus_point.isExactlyZero()) + { + target_distance = LLViewerCamera::getInstance()->getAtAxis() * (focus_point - eye); + } + + if (transition_time >= 1.f && fabsf(current_distance - target_distance) / current_distance > 0.01f) + { // large shift happened, interpolate smoothly to new target distance + transition_time = 0.f; + start_distance = current_distance; + } + else if (transition_time < 1.f) + { // currently in a transition, continue interpolating + transition_time += 1.f / CameraFocusTransitionTime * gFrameIntervalSeconds.value(); + transition_time = llmin(transition_time, 1.f); + + F32 t = cosf(transition_time * F_PI + F_PI) * 0.5f + 0.5f; + current_distance = start_distance + (target_distance - start_distance) * t; + } + else + { // small or no change, just snap to target distance + current_distance = target_distance; + } + + // convert to mm + F32 subject_distance = current_distance * 1000.f; + F32 fnumber = CameraFNumber; + F32 default_focal_length = CameraFocalLength; + + F32 fov = LLViewerCamera::getInstance()->getView(); + + const F32 default_fov = CameraFieldOfView * F_PI / 180.f; + + // F32 aspect_ratio = (F32) mRT->screen.getWidth()/(F32)mRT->screen.getHeight(); + + F32 dv = 2.f * default_focal_length * tanf(default_fov / 2.f); + + F32 focal_length = dv / (2 * tanf(fov / 2.f)); + + // F32 tan_pixel_angle = tanf(LLDrawable::sCurPixelAngle); + + // from wikipedia -- c = |s2-s1|/s2 * f^2/(N(S1-f)) + // where N = fnumber + // s2 = dot distance + // s1 = subject distance + // f = focal length + // + + F32 blur_constant = focal_length * focal_length / (fnumber * (subject_distance - focal_length)); + blur_constant /= 1000.f; // convert to meters for shader + F32 magnification = focal_length / (subject_distance - focal_length); + + { // build diffuse+bloom+CoF + mRT->deferredLight.bindTarget(); + shader = &gDeferredCoFProgram; + + bindDeferredShader(*shader); + + S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->screen.getUsage()); + if (channel > -1) + { + mRT->screen.bindTexture(0, channel); + } + + shader->uniform1f(LLShaderMgr::DOF_FOCAL_DISTANCE, -subject_distance / 1000.f); + shader->uniform1f(LLShaderMgr::DOF_BLUR_CONSTANT, blur_constant); + shader->uniform1f(LLShaderMgr::DOF_TAN_PIXEL_ANGLE, tanf(1.f / LLDrawable::sCurPixelAngle)); + shader->uniform1f(LLShaderMgr::DOF_MAGNIFICATION, magnification); + shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); + shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); + + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); + gGL.vertex2f(-1, -1); + + gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); + gGL.vertex2f(-1, 3); + + gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); + gGL.vertex2f(3, -1); + + gGL.end(); + + unbindDeferredShader(*shader); + mRT->deferredLight.flush(); + } + + U32 dof_width = (U32)(mRT->screen.getWidth() * CameraDoFResScale); + U32 dof_height = (U32)(mRT->screen.getHeight() * CameraDoFResScale); + + { // perform DoF sampling at half-res (preserve alpha channel) + mRT->screen.bindTarget(); + glViewport(0, 0, dof_width, dof_height); + gGL.setColorMask(true, false); + + shader = &gDeferredPostProgram; + bindDeferredShader(*shader); + S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->deferredLight.getUsage()); + if (channel > -1) + { + mRT->deferredLight.bindTexture(0, channel); + } + + shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); + shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); + + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); + gGL.vertex2f(-1, -1); + + gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); + gGL.vertex2f(-1, 3); + + gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); + gGL.vertex2f(3, -1); + + gGL.end(); + + unbindDeferredShader(*shader); + mRT->screen.flush(); + gGL.setColorMask(true, true); + } + + { // combine result based on alpha + //if (multisample) + //{ + // mRT->deferredLight.bindTarget(); + // glViewport(0, 0, mRT->deferredScreen.getWidth(), mRT->deferredScreen.getHeight()); + //} +// [RLVa:KB] - @setsphere + if (pRenderBuffer) + { + pRenderBuffer->bindTarget(); + glViewport(0, 0, mRT->deferredScreen.getWidth(), mRT->deferredScreen.getHeight()); + } +// [/RLVa:KB] + else + { + gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; + gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; + gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth(); + gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); + glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); + } + + shader = &gDeferredDoFCombineProgram; + bindDeferredShader(*shader); + + S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->screen.getUsage()); + if (channel > -1) + { + mRT->screen.bindTexture(0, channel); + } + + shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); + shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); + shader->uniform1f(LLShaderMgr::DOF_WIDTH, (dof_width - 1) / (F32)mRT->screen.getWidth()); + shader->uniform1f(LLShaderMgr::DOF_HEIGHT, (dof_height - 1) / (F32)mRT->screen.getHeight()); + + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); + gGL.vertex2f(-1, -1); + + gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); + gGL.vertex2f(-1, 3); + + gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); + gGL.vertex2f(3, -1); + + gGL.end(); + + unbindDeferredShader(*shader); + + // [RLVa:KB] - @setsphere + if (pRenderBuffer) + { + pRenderBuffer->flush(); + } + // [/RLVa:KB] + //if (multisample) + //{ + // mRT->deferredLight.flush(); + //} + } + } + else + { + LL_PROFILE_GPU_ZONE("no dof"); + //if (multisample) + //{ + // mRT->deferredLight.bindTarget(); + //} +// [RLVa:KB] - @setsphere + if (pRenderBuffer) + { + pRenderBuffer->bindTarget(); + } + // [/RLVa:KB] + LLGLSLShader* shader = &gDeferredPostNoDoFProgram; + + bindDeferredShader(*shader); + + S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->screen.getUsage()); + if (channel > -1) + { + mRT->screen.bindTexture(0, channel); + } + + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); + gGL.vertex2f(-1, -1); + + gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); + gGL.vertex2f(-1, 3); + + gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); + gGL.vertex2f(3, -1); + + gGL.end(); + + unbindDeferredShader(*shader); + + // [RLVa:KB] - @setsphere + if (pRenderBuffer) + { + pRenderBuffer->flush(); + } + // [/RLVa:KB] + //if (multisample) + //{ + // mRT->deferredLight.flush(); + //} + } + } +} + +LLRenderTarget* LLPipeline::screenTarget() { + + // FIRE-16251: Depth of Field does not work underwater + //bool dof_enabled = !LLViewerCamera::getInstance()->cameraUnderWater() && + bool dof_enabled = (FSRenderDepthOfFieldUnderwater || !LLViewerCamera::getInstance()->cameraUnderWater()) && + // FIRE-16251 + (RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) && + RenderDepthOfField && + !gCubeSnapshot; + + bool multisample = RenderFSAASamples > 1 && mRT->fxaaBuffer.isComplete() && !gCubeSnapshot; + + if (multisample || dof_enabled) + return &mRT->deferredLight; + + return &mRT->screen; +} + void LLPipeline::renderFinalize() { LLVertexBuffer::unbind(); @@ -7780,12 +8279,10 @@ void LLPipeline::renderFinalize() gGL.setColorMask(true, true); glClearColor(0, 0, 0, 0); - exoPostProcess::instance().ExodusRenderPostStack(&mRT->screen, &mRT->screen); // Import Vignette from Exodus if (!gCubeSnapshot) { - LLRenderTarget* screen_target = &mRT->screen; - screen_target->bindTarget(); + screenTarget()->bindTarget(); if (RenderScreenSpaceReflections) { @@ -7805,10 +8302,10 @@ void LLPipeline::renderFinalize() gPostScreenSpaceReflectionProgram.uniform1f(zfar, farClip); gPostScreenSpaceReflectionProgram.uniform1f(znear, nearClip); - S32 channel = gPostScreenSpaceReflectionProgram.enableTexture(LLShaderMgr::DIFFUSE_MAP, screen_target->getUsage()); + S32 channel = gPostScreenSpaceReflectionProgram.enableTexture(LLShaderMgr::DIFFUSE_MAP, screenTarget()->getUsage()); if (channel > -1) { - screen_target->bindTexture(0, channel, LLTexUnit::TFO_POINT); + screenTarget()->bindTexture(0, channel, LLTexUnit::TFO_POINT); } { @@ -7830,19 +8327,19 @@ void LLPipeline::renderFinalize() LLGLDepthTest depth(GL_FALSE, GL_FALSE); LLVector2 tc1(0, 0); - LLVector2 tc2((F32)screen_target->getWidth() * 2, (F32)screen_target->getHeight() * 2); + LLVector2 tc2((F32)screenTarget()->getWidth() * 2, (F32)screenTarget()->getHeight() * 2); // Apply gamma correction to the frame here. gDeferredPostGammaCorrectProgram.bind(); // mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); S32 channel = 0; - channel = gDeferredPostGammaCorrectProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, screen_target->getUsage()); + channel = gDeferredPostGammaCorrectProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, screenTarget()->getUsage()); if (channel > -1) { - screen_target->bindTexture(0, channel, LLTexUnit::TFO_POINT); + screenTarget()->bindTexture(0, channel, LLTexUnit::TFO_POINT); } - gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, screen_target->getWidth(), screen_target->getHeight()); + gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, screenTarget()->getWidth(), screenTarget()->getHeight()); F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma"); @@ -7860,587 +8357,154 @@ void LLPipeline::renderFinalize() gGL.end(); - gGL.getTexUnit(channel)->unbind(screen_target->getUsage()); + gGL.getTexUnit(channel)->unbind(screenTarget()->getUsage()); gDeferredPostGammaCorrectProgram.unbind(); } - screen_target->flush(); + screenTarget()->flush(); LLVertexBuffer::unbind(); } - if (sRenderGlow) - { - LL_PROFILE_GPU_ZONE("glow"); - mGlow[2].bindTarget(); - mGlow[2].clear(); - - gGlowExtractProgram.bind(); - F32 minLum = llmax((F32) RenderGlowMinLuminance, 0.0f); - F32 maxAlpha = RenderGlowMaxExtractAlpha; - F32 warmthAmount = RenderGlowWarmthAmount; - LLVector3 lumWeights = RenderGlowLumWeights; - LLVector3 warmthWeights = RenderGlowWarmthWeights; - - gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MIN_LUMINANCE, minLum); - gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MAX_EXTRACT_ALPHA, maxAlpha); - gGlowExtractProgram.uniform3f(LLShaderMgr::GLOW_LUM_WEIGHTS, lumWeights.mV[0], lumWeights.mV[1], - lumWeights.mV[2]); - gGlowExtractProgram.uniform3f(LLShaderMgr::GLOW_WARMTH_WEIGHTS, warmthWeights.mV[0], warmthWeights.mV[1], - warmthWeights.mV[2]); - gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_WARMTH_AMOUNT, warmthAmount); - - { - LLGLEnable blend_on(GL_BLEND); - LLGLEnable test(GL_ALPHA_TEST); - - gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA); - - mRT->screen.bindTexture(0, 0, LLTexUnit::TFO_POINT); - - gGL.color4f(1, 1, 1, 1); - gPipeline.enableLightsFullbright(); - // FIRE-16829: Visual Artifacts with ALM enabled on AMD graphics - //gGL.begin(LLRender::TRIANGLE_STRIP); - //gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); - //gGL.vertex2f(-1, -1); - - //gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); - //gGL.vertex2f(-1, 3); - - //gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); - //gGL.vertex2f(3, -1); - - //gGL.end(); - drawAuxiliaryVB(tc1, tc2); - // - - gGL.getTexUnit(0)->unbind(mRT->screen.getUsage()); - - mGlow[2].flush(); - - tc1.setVec(0, 0); - tc2.setVec(2, 2); - } - - // power of two between 1 and 1024 - U32 glowResPow = RenderGlowResolutionPow; - const U32 glow_res = llmax(1, llmin(1024, 1 << glowResPow)); - - S32 kernel = RenderGlowIterations * 2; - F32 delta = RenderGlowWidth / glow_res; - // Use half the glow width if we have the res set to less than 9 so that it looks - // almost the same in either case. - if (glowResPow < 9) - { - delta *= 0.5f; - } - F32 strength = RenderGlowStrength; - - gGlowProgram.bind(); - gGlowProgram.uniform1f(LLShaderMgr::GLOW_STRENGTH, strength); - - for (S32 i = 0; i < kernel; i++) - { - mGlow[i % 2].bindTarget(); - mGlow[i % 2].clear(); - - if (i == 0) - { - gGL.getTexUnit(0)->bind(&mGlow[2]); - } - else - { - gGL.getTexUnit(0)->bind(&mGlow[(i - 1) % 2]); - } - - if (i % 2 == 0) - { - gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, delta, 0); - } - else - { - gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, 0, delta); - } - - // FIRE-16829: Visual Artifacts with ALM enabled on AMD graphics - //gGL.begin(LLRender::TRIANGLE_STRIP); - //gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); - //gGL.vertex2f(-1,-1); - // - //gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); - //gGL.vertex2f(-1,3); - // - //gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); - //gGL.vertex2f(3,-1); - // - //gGL.end(); - drawAuxiliaryVB(tc1, tc2); - // - - mGlow[i % 2].flush(); - } - - gGlowProgram.unbind(); - } - else // !sRenderGlow, skip the glow ping-pong and just clear the result target - { - mGlow[1].bindTarget(); - mGlow[1].clear(); - mGlow[1].flush(); - } - - gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; - gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; - gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth(); - gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); - glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); - - tc2.setVec((F32) mRT->screen.getWidth(), (F32) mRT->screen.getHeight()); - - gGL.flush(); - - LLVertexBuffer::unbind(); - // [RLVa:KB] - @setsphere - LLRenderTarget* pRenderBuffer = (RlvActions::hasBehaviour(RLV_BHVR_SETSPHERE)) ? &mRT->deferredLight : nullptr; + LLRenderTarget* pRenderBuffer = (RlvActions::hasBehaviour(RLV_BHVR_SETSPHERE)) ? &mRT->deferredLight : nullptr; // [/RLVa:KB] - if (LLPipeline::sRenderDeferred) - { - // FIRE-16251: Depth of Field does not work underwater - //bool dof_enabled = !LLViewerCamera::getInstance()->cameraUnderWater() && - bool dof_enabled = (FSRenderDepthOfFieldUnderwater || !LLViewerCamera::getInstance()->cameraUnderWater()) && - // FIRE-16251 - (RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) && - RenderDepthOfField && - !gCubeSnapshot; - - bool multisample = RenderFSAASamples > 1 && mRT->fxaaBuffer.isComplete() && !gCubeSnapshot; - exoPostProcess::instance().multisample = multisample; // Import Vignette from Exodus + if (RenderDeferred) + { + bool multisample = RenderFSAASamples > 1 && mRT->fxaaBuffer.isComplete() && !gCubeSnapshot; // [RLVa:KB] - @setsphere - if (multisample && !pRenderBuffer) - { - pRenderBuffer = &mRT->deferredLight; - } + if (multisample && !pRenderBuffer) + { + pRenderBuffer = &mRT->deferredLight; + } +// [/RLVa:KB] + LLGLSLShader* shader = &gGlowCombineProgram; + + S32 width = mRT->screen.getWidth(); + S32 height = mRT->screen.getHeight(); + + S32 channel = -1; + +// [RLVa:KB] - @setsphere + if (RlvActions::hasBehaviour(RLV_BHVR_SETSPHERE)) + { + LLShaderEffectParams params(pRenderBuffer, &mRT->screen, !multisample); + LLVfxManager::instance().runEffect(EVisualEffect::RlvSphere, ¶ms); + pRenderBuffer = params.m_pDstBuffer; + } // [/RLVa:KB] - gViewerWindow->setup3DViewport(); + // Present everything. + if (multisample) + { + LL_PROFILE_GPU_ZONE("aa"); + // bake out texture2D with RGBL for FXAA shader + mRT->fxaaBuffer.bindTarget(); - if (dof_enabled) - { - LL_PROFILE_GPU_ZONE("dof"); - LLGLSLShader *shader = &gDeferredPostProgram; - LLGLDisable blend(GL_BLEND); + glViewport(0, 0, width, height); - // depth of field focal plane calculations - static F32 current_distance = 16.f; - static F32 start_distance = 16.f; - static F32 transition_time = 1.f; + shader = &gGlowCombineFXAAProgram; - LLVector3 focus_point; + shader->bind(); + shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, width, height); - // FIRE-16728 focus point lock & free focus DoF - based on a feature developed by NiranV Dean - static LLVector3 last_focus_point{}; - if( LLPipeline::FSFocusPointLocked && !last_focus_point.isExactlyZero() ) - { - focus_point = last_focus_point; - } - else - { - // - LLViewerObject *obj = LLViewerMediaFocus::getInstance()->getFocusedObject(); - if (obj && obj->mDrawable && obj->isSelected()) - { // focus on selected media object - S32 face_idx = LLViewerMediaFocus::getInstance()->getFocusedFace(); - if (obj && obj->mDrawable) - { - LLFace *face = obj->mDrawable->getFace(face_idx); - if (face) - { - focus_point = face->getPositionAgent(); - } - } - } - }// support focus point lock - - if (focus_point.isExactlyZero()) - { - if (LLViewerJoystick::getInstance()->getOverrideCamera() || LLPipeline::FSFocusPointFollowsPointer) // FIRE-16728 Add free aim mouse and focus lock - { // focus on point under cursor - focus_point.set(gDebugRaycastIntersection.getF32ptr()); - } - else if (gAgentCamera.cameraMouselook()) - { // focus on point under mouselook crosshairs - LLVector4a result; - result.clear(); - - gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE, TRUE, NULL, &result); - - focus_point.set(result.getF32ptr()); - } - else - { - // focus on alt-zoom target - LLViewerRegion *region = gAgent.getRegion(); - if (region) - { - focus_point = LLVector3(gAgentCamera.getFocusGlobal() - region->getOriginGlobal()); - } - } - } - // FIRE-16728 Add free aim mouse and focus lock - last_focus_point = focus_point; - // - LLVector3 eye = LLViewerCamera::getInstance()->getOrigin(); - F32 target_distance = 16.f; - if (!focus_point.isExactlyZero()) - { - target_distance = LLViewerCamera::getInstance()->getAtAxis() * (focus_point - eye); - } - - if (transition_time >= 1.f && fabsf(current_distance - target_distance) / current_distance > 0.01f) - { // large shift happened, interpolate smoothly to new target distance - transition_time = 0.f; - start_distance = current_distance; - } - else if (transition_time < 1.f) - { // currently in a transition, continue interpolating - transition_time += 1.f / CameraFocusTransitionTime * gFrameIntervalSeconds.value(); - transition_time = llmin(transition_time, 1.f); - - F32 t = cosf(transition_time * F_PI + F_PI) * 0.5f + 0.5f; - current_distance = start_distance + (target_distance - start_distance) * t; - } - else - { // small or no change, just snap to target distance - current_distance = target_distance; - } - - // convert to mm - F32 subject_distance = current_distance * 1000.f; - F32 fnumber = CameraFNumber; - F32 default_focal_length = CameraFocalLength; - - F32 fov = LLViewerCamera::getInstance()->getView(); - - const F32 default_fov = CameraFieldOfView * F_PI / 180.f; - - // F32 aspect_ratio = (F32) mRT->screen.getWidth()/(F32)mRT->screen.getHeight(); - - F32 dv = 2.f * default_focal_length * tanf(default_fov / 2.f); - - F32 focal_length = dv / (2 * tanf(fov / 2.f)); - - // F32 tan_pixel_angle = tanf(LLDrawable::sCurPixelAngle); - - // from wikipedia -- c = |s2-s1|/s2 * f^2/(N(S1-f)) - // where N = fnumber - // s2 = dot distance - // s1 = subject distance - // f = focal length - // - - F32 blur_constant = focal_length * focal_length / (fnumber * (subject_distance - focal_length)); - blur_constant /= 1000.f; // convert to meters for shader - F32 magnification = focal_length / (subject_distance - focal_length); - - { // build diffuse+bloom+CoF - mRT->deferredLight.bindTarget(); - shader = &gDeferredCoFProgram; - - bindDeferredShader(*shader); - - S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->screen.getUsage()); - if (channel > -1) - { - mRT->screen.bindTexture(0, channel); - } - - shader->uniform1f(LLShaderMgr::DOF_FOCAL_DISTANCE, -subject_distance / 1000.f); - shader->uniform1f(LLShaderMgr::DOF_BLUR_CONSTANT, blur_constant); - shader->uniform1f(LLShaderMgr::DOF_TAN_PIXEL_ANGLE, tanf(1.f / LLDrawable::sCurPixelAngle)); - shader->uniform1f(LLShaderMgr::DOF_MAGNIFICATION, magnification); - shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); - shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); - - // FIRE-16829: Visual Artifacts with ALM enabled on AMD graphics - //gGL.begin(LLRender::TRIANGLE_STRIP); - //gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); - //gGL.vertex2f(-1,-1); - - //gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); - //gGL.vertex2f(-1,3); - - //gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); - //gGL.vertex2f(3,-1); - - //gGL.end(); - drawAuxiliaryVB(tc1, tc2); - // - - unbindDeferredShader(*shader); - mRT->deferredLight.flush(); - } - - U32 dof_width = (U32)(mRT->screen.getWidth() * CameraDoFResScale); - U32 dof_height = (U32)(mRT->screen.getHeight() * CameraDoFResScale); - - { // perform DoF sampling at half-res (preserve alpha channel) - mRT->screen.bindTarget(); - glViewport(0, 0, dof_width, dof_height); - gGL.setColorMask(true, false); - - shader = &gDeferredPostProgram; - bindDeferredShader(*shader); - S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->deferredLight.getUsage()); - if (channel > -1) - { - mRT->deferredLight.bindTexture(0, channel); - } - - shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); - shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); - - // FIRE-16829: Visual Artifacts with ALM enabled on AMD graphics - //gGL.begin(LLRender::TRIANGLE_STRIP); - //gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); - //gGL.vertex2f(-1,-1); - - //gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); - //gGL.vertex2f(-1,3); - - //gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); - //gGL.vertex2f(3,-1); - - //gGL.end(); - drawAuxiliaryVB(tc1, tc2); - // - - unbindDeferredShader(*shader); - mRT->screen.flush(); - gGL.setColorMask(true, true); - } - - { // combine result based on alpha -// if (multisample) -// { -// mRT->deferredLight.bindTarget(); -// glViewport(0, 0, mRT->deferredScreen.getWidth(), mRT->deferredScreen.getHeight()); -// } + //channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->deferredLight.getUsage()); + //if (channel > -1) + //{ + // mRT->deferredLight.bindTexture(0, channel); + //} // [RLVa:KB] - @setsphere - if (pRenderBuffer) - { - pRenderBuffer->bindTarget(); - glViewport(0, 0, mRT->deferredScreen.getWidth(), mRT->deferredScreen.getHeight()); - } -// [/RLVa:KB] - else - { - gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; - gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; - gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth(); - gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); - glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); - } - - shader = &gDeferredDoFCombineProgram; - bindDeferredShader(*shader); - - S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->screen.getUsage()); - if (channel > -1) - { - mRT->screen.bindTexture(0, channel); - } - - shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); - shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); - shader->uniform1f(LLShaderMgr::DOF_WIDTH, (dof_width - 1) / (F32)mRT->screen.getWidth()); - shader->uniform1f(LLShaderMgr::DOF_HEIGHT, (dof_height - 1) / (F32)mRT->screen.getHeight()); - - // FIRE-16829: Visual Artifacts with ALM enabled on AMD graphics - //gGL.begin(LLRender::TRIANGLE_STRIP); - //gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); - //gGL.vertex2f(-1,-1); - - //gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); - //gGL.vertex2f(-1,3); - - //gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); - //gGL.vertex2f(3,-1); - - //gGL.end(); - drawAuxiliaryVB(tc1, tc2); - // - - unbindDeferredShader(*shader); - -// [RLVa:KB] - @setsphere - if (pRenderBuffer) - { - pRenderBuffer->flush(); - } -// [/RLVa:KB] -// if (multisample) -// { -// mRT->deferredLight.flush(); -// } - } - } - else - { - LL_PROFILE_GPU_ZONE("no dof"); -// if (multisample) -// { -// mRT->deferredLight.bindTarget(); -// } -// [RLVa:KB] - @setsphere - if (pRenderBuffer) - { - pRenderBuffer->bindTarget(); - } -// [/RLVa:KB] - LLGLSLShader *shader = &gDeferredPostNoDoFProgram; - - bindDeferredShader(*shader); - - S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->screen.getUsage()); - if (channel > -1) - { - mRT->screen.bindTexture(0, channel); - } - - // FIRE-16829: Visual Artifacts with ALM enabled on AMD graphics - //gGL.begin(LLRender::TRIANGLE_STRIP); - //gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); - //gGL.vertex2f(-1,-1); - - //gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); - //gGL.vertex2f(-1,3); - - //gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); - //gGL.vertex2f(3,-1); - - //gGL.end(); - drawAuxiliaryVB(tc1, tc2); - // - - unbindDeferredShader(*shader); - -// [RLVa:KB] - @setsphere - if (pRenderBuffer) - { - pRenderBuffer->flush(); - } -// [/RLVa:KB] -// if (multisample) -// { -// mRT->deferredLight.flush(); -// } - } - -// [RLVa:KB] - @setsphere - if (RlvActions::hasBehaviour(RLV_BHVR_SETSPHERE)) - { - LLShaderEffectParams params(pRenderBuffer, &mRT->screen, !multisample); - LLVfxManager::instance().runEffect(EVisualEffect::RlvSphere, ¶ms); - pRenderBuffer = params.m_pDstBuffer; - } -// [/RLVa:KB] - - if (multisample) - { - LL_PROFILE_GPU_ZONE("aa"); - // bake out texture2D with RGBL for FXAA shader - mRT->fxaaBuffer.bindTarget(); - - S32 width = mRT->screen.getWidth(); - S32 height = mRT->screen.getHeight(); - glViewport(0, 0, width, height); - - LLGLSLShader *shader = &gGlowCombineFXAAProgram; - - shader->bind(); - shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, width, height); - -// S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->deferredLight.getUsage()); -// if (channel > -1) -// { -// mRT->deferredLight.bindTexture(0, channel); -// } -// [RLVa:KB] - @setsphere - S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, pRenderBuffer->getUsage()); - if (channel > -1) - { - pRenderBuffer->bindTexture(0, channel); - } + channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, pRenderBuffer->getUsage()); + if (channel > -1) + { + pRenderBuffer->bindTexture(0, channel); + } // [RLVa:KB] - // FIRE-16829: Visual Artifacts with ALM enabled on AMD graphics - //gGL.begin(LLRender::TRIANGLE_STRIP); - //gGL.vertex2f(-1,-1); - //gGL.vertex2f(-1,3); - //gGL.vertex2f(3,-1); - //gGL.end(); + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.vertex2f(-1, -1); + gGL.vertex2f(-1, 3); + gGL.vertex2f(3, -1); + gGL.end(); - //gGL.flush(); - drawAuxiliaryVB(); - // + gGL.flush(); // [RLVa:KB] - @setsphere - shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, pRenderBuffer->getUsage()); + shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, pRenderBuffer->getUsage()); // [/RLVa:KB] -// shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->deferredLight.getUsage()); - shader->unbind(); + //shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->deferredLight.getUsage()); + shader->unbind(); - mRT->fxaaBuffer.flush(); + mRT->fxaaBuffer.flush(); - shader = &gFXAAProgram; - shader->bind(); + shader = &gFXAAProgram; + shader->bind(); - channel = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP, mRT->fxaaBuffer.getUsage()); - if (channel > -1) - { - mRT->fxaaBuffer.bindTexture(0, channel, LLTexUnit::TFO_BILINEAR); - } + channel = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP, mRT->fxaaBuffer.getUsage()); + if (channel > -1) + { + mRT->fxaaBuffer.bindTexture(0, channel, LLTexUnit::TFO_BILINEAR); + } - gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; - gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; - gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth(); - gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); - glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); + gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; + gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; + gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth(); + gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); + glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); - F32 scale_x = (F32) width / mRT->fxaaBuffer.getWidth(); - F32 scale_y = (F32) height / mRT->fxaaBuffer.getHeight(); - shader->uniform2f(LLShaderMgr::FXAA_TC_SCALE, scale_x, scale_y); - shader->uniform2f(LLShaderMgr::FXAA_RCP_SCREEN_RES, 1.f / width * scale_x, 1.f / height * scale_y); - shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT, -0.5f / width * scale_x, -0.5f / height * scale_y, - 0.5f / width * scale_x, 0.5f / height * scale_y); - shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT2, -2.f / width * scale_x, -2.f / height * scale_y, - 2.f / width * scale_x, 2.f / height * scale_y); + F32 scale_x = (F32)width / mRT->fxaaBuffer.getWidth(); + F32 scale_y = (F32)height / mRT->fxaaBuffer.getHeight(); + shader->uniform2f(LLShaderMgr::FXAA_TC_SCALE, scale_x, scale_y); + shader->uniform2f(LLShaderMgr::FXAA_RCP_SCREEN_RES, 1.f / width * scale_x, 1.f / height * scale_y); + shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT, -0.5f / width * scale_x, -0.5f / height * scale_y, + 0.5f / width * scale_x, 0.5f / height * scale_y); + shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT2, -2.f / width * scale_x, -2.f / height * scale_y, + 2.f / width * scale_x, 2.f / height * scale_y); - // FIRE-16829: Visual Artifacts with ALM enabled on AMD graphics - //gGL.begin(LLRender::TRIANGLE_STRIP); - //gGL.vertex2f(-1,-1); - //gGL.vertex2f(-1,3); - //gGL.vertex2f(3,-1); - //gGL.end(); + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.vertex2f(-1, -1); + gGL.vertex2f(-1, 3); + gGL.vertex2f(3, -1); + gGL.end(); - //gGL.flush(); - drawAuxiliaryVB(); - // - shader->unbind(); - } - } + gGL.flush(); + shader->unbind(); + } + else + { + shader->bind(); + + + gGL.getTexUnit(0)->bind(&mGlow[1]); + gGL.getTexUnit(1)->bind(screenTarget()); + + gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; + gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; + gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth(); + gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); + glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); + + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.vertex2f(-1, -1); + gGL.vertex2f(-1, 3); + gGL.vertex2f(3, -1); + gGL.end(); + + gGL.flush(); + shader->unbind(); + } + } + #if 0 // DEPRECATED else // not deferred { // [RLVa:KB] - @setsphere - if (RlvActions::hasBehaviour(RLV_BHVR_SETSPHERE)) - { - LLShaderEffectParams params(&mRT->screen, &mRT->deferredLight, false); - LLVfxManager::instance().runEffect(EVisualEffect::RlvSphere, ¶ms); - pRenderBuffer = params.m_pDstBuffer; - } + if (RlvActions::hasBehaviour(RLV_BHVR_SETSPHERE)) + { + LLShaderEffectParams params(&mRT->screen, &mRT->deferredLight, false); + LLVfxManager::instance().runEffect(EVisualEffect::RlvSphere, ¶ms); + pRenderBuffer = params.m_pDstBuffer; + } // [/RLVa:KB] U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1; @@ -8475,9 +8539,9 @@ void LLPipeline::renderFinalize() gGL.getTexUnit(0)->bind(&mGlow[1]); // [RLVa:KB] - @setsphere - gGL.getTexUnit(1)->bind( pRenderBuffer ? pRenderBuffer : &mRT->screen ); + gGL.getTexUnit(1)->bind(pRenderBuffer ? pRenderBuffer : &mRT->screen); // [/RLVa:KB] -// gGL.getTexUnit(1)->bind(&mRT->screen); + //gGL.getTexUnit(1)->bind(&mRT->screen); LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE : 0); diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index e74a6feb24..01d6f2b94b 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -137,6 +137,8 @@ public: void generateImpostor(LLVOAvatar* avatar, bool preview_avatar = false); void bindScreenToTexture(); void renderFinalize(); + void renderPostProcess(); + LLRenderTarget* screenTarget(); void init(); void cleanup();