From 99b82d944937ce321f64aa91fb18ab2aedd3992a Mon Sep 17 00:00:00 2001 From: "Graham Linden graham@lindenlab.com" Date: Sun, 18 Feb 2018 15:52:23 +0000 Subject: Atmospherics WIP libatmosphere integrated in indra/llrender/llatmosphere.cpp Still working on runtime shaders to use libatmosphere precomputed atmospherics textures --- indra/llappearance/lltexlayer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llappearance/lltexlayer.cpp') diff --git a/indra/llappearance/lltexlayer.cpp b/indra/llappearance/lltexlayer.cpp index 2cf86bb4fe..3dbab22de1 100644 --- a/indra/llappearance/lltexlayer.cpp +++ b/indra/llappearance/lltexlayer.cpp @@ -1578,7 +1578,7 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC alpha_data = new U8[width * height]; mAlphaCache[cache_index] = alpha_data; glReadPixels(x, y, width, height, GL_ALPHA, GL_UNSIGNED_BYTE, alpha_data); - } + } getTexLayerSet()->getAvatarAppearance()->dirtyMesh(); -- cgit v1.3 From 576f1cdd7e16e44c43b39618f715753160045468 Mon Sep 17 00:00:00 2001 From: Graham Linden Date: Mon, 1 Jul 2019 17:23:59 -0700 Subject: SL-11521, SL-10625 Try aligning data used for glReadPixels to see if we can coax the Intel driver stack into being a less souciant pile of detritus. Replace face color based test replaced with other logic in error. --- indra/llappearance/llpolymorph.cpp | 4 ++-- indra/llappearance/lltexlayer.cpp | 26 +++++++++++++++++++++----- indra/newview/llvovolume.cpp | 12 ++++++++---- 3 files changed, 31 insertions(+), 11 deletions(-) (limited to 'indra/llappearance/lltexlayer.cpp') diff --git a/indra/llappearance/llpolymorph.cpp b/indra/llappearance/llpolymorph.cpp index 2cb4c65d7c..ce7010984a 100644 --- a/indra/llappearance/llpolymorph.cpp +++ b/indra/llappearance/llpolymorph.cpp @@ -816,8 +816,8 @@ void LLPolyVertexMask::generateMask(U8 *maskTextureData, S32 width, S32 height, U32 s = llclamp((U32)(uvCoords.mV[VX] * (F32)(width - 1)), (U32)0, (U32)width - 1); U32 t = llclamp((U32)(uvCoords.mV[VY] * (F32)(height - 1)), (U32)0, (U32)height - 1); - mWeights[index] = ((F32) maskTextureData[((t * width + s) * num_components) + (num_components - 1)]) / 255.f; - + mWeights[index] = maskTextureData ? ((F32) maskTextureData[((t * width + s) * num_components) + (num_components - 1)]) / 255.f : 0.0f; + if (invert) { mWeights[index] = 1.f - mWeights[index]; diff --git a/indra/llappearance/lltexlayer.cpp b/indra/llappearance/lltexlayer.cpp index 3f2fcce429..22b3364559 100644 --- a/indra/llappearance/lltexlayer.cpp +++ b/indra/llappearance/lltexlayer.cpp @@ -1575,14 +1575,30 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC delete [] alpha_data; mAlphaCache.erase(iter2); } - alpha_data = new U8[width * height]; + + // GPUs tend to be very uptight about memory alignment as the DMA used to convey + // said data to the card works better when well-aligned so plain old default-aligned heap mem is a no-no + //new U8[width * height]; + size_t mem_size = (width * height); + size_t rem = (mem_size & 0x3F); + mem_size += rem > 0 ? (mem_size + (32 - rem)) : 0; + + alpha_data = (U8*)ll_aligned_malloc_32(mem_size); + mAlphaCache[cache_index] = alpha_data; - - // nSight doesn't support use of glReadPixels - if (!LLRender::sNsightDebugSupport) + + bool skip_readback = LLRender::sNsightDebugSupport; // nSight doesn't support use of glReadPixels + // || gGLManager.mIsIntel; SL-10625? + + if (!skip_readback) { - glReadPixels(x, y, width, height, GL_ALPHA, GL_UNSIGNED_BYTE, alpha_data); + glReadPixels(x, y, width, height, GL_ALPHA, GL_UNSIGNED_BYTE, alpha_data); } + else + { + ll_aligned_free_32(alpha_data); + alpha_data = nullptr; + } } getTexLayerSet()->getAvatarAppearance()->dirtyMesh(); diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 8aaf678aba..3740caa53f 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -6453,7 +6453,8 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace bool use_legacy_bump = te->getBumpmap() && (te->getBumpmap() < 18) && (!mat || mat->getNormalID().isNull()); bool opaque = te_alpha >= 0.999f; bool transparent = te_alpha < 0.999f; - bool invisible = te_alpha <= 0.0f; + + is_alpha = (is_alpha || transparent) ? TRUE : FALSE; if (mat && LLPipeline::sRenderDeferred && !hud_group) { @@ -6551,7 +6552,10 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace else if (mat) { U8 mode = mat->getDiffuseAlphaMode(); - if (transparent) + + is_alpha = (is_alpha || (mode == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND)); + + if (is_alpha) { mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND; } @@ -6560,7 +6564,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace { registerFace(group, facep, fullbright ? LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK : LLRenderPass::PASS_ALPHA_MASK); } - else if (is_alpha || transparent) + else if (is_alpha ) { registerFace(group, facep, LLRenderPass::PASS_ALPHA); } @@ -6579,7 +6583,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace else if (is_alpha) { // can we safely treat this as an alpha mask? - if (invisible) + if (facep->getFaceColor().mV[3] <= 0.f) { //100% transparent, don't render unless we're highlighting transparent registerFace(group, facep, LLRenderPass::PASS_ALPHA_INVISIBLE); } -- cgit v1.3 From 48f169423ba0c1da8ffe13fc8bc4cec76336d8fc Mon Sep 17 00:00:00 2001 From: Graham Linden Date: Wed, 3 Jul 2019 10:04:05 -0700 Subject: SL-11545, SL-11543, SL-10625 Fix emissives without normal maps clobbering the alpha output in materialF. Modify glow size calc to get close to pre-EEP sun glow behavior (may require sky vert settings >= mid). Make bake ignore alpha readback for Intel until we can determine why their drivers now go boom. --- indra/llappearance/lltexlayer.cpp | 8 +++++--- .../app_settings/shaders/class1/deferred/materialF.glsl | 14 ++++++-------- .../newview/app_settings/shaders/class1/deferred/skyV.glsl | 2 +- .../shaders/class1/environment/terrainWaterV.glsl | 4 ---- .../shaders/class1/windlight/atmosphericsFuncs.glsl | 6 +++--- .../newview/app_settings/shaders/class2/deferred/skyF.glsl | 2 +- .../app_settings/shaders/class2/windlight/skyV.glsl | 2 +- 7 files changed, 17 insertions(+), 21 deletions(-) (limited to 'indra/llappearance/lltexlayer.cpp') diff --git a/indra/llappearance/lltexlayer.cpp b/indra/llappearance/lltexlayer.cpp index 22b3364559..645274a990 100644 --- a/indra/llappearance/lltexlayer.cpp +++ b/indra/llappearance/lltexlayer.cpp @@ -1065,7 +1065,7 @@ LLTexLayer::~LLTexLayer() iter != mAlphaCache.end(); iter++ ) { U8* alpha_data = iter->second; - delete [] alpha_data; + ll_aligned_free_32(alpha_data); } } @@ -1572,7 +1572,7 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC { alpha_cache_t::iterator iter2 = mAlphaCache.begin(); // arbitrarily grab the first entry alpha_data = iter2->second; - delete [] alpha_data; + ll_aligned_free_32(alpha_data); mAlphaCache.erase(iter2); } @@ -1588,7 +1588,9 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC mAlphaCache[cache_index] = alpha_data; bool skip_readback = LLRender::sNsightDebugSupport; // nSight doesn't support use of glReadPixels - // || gGLManager.mIsIntel; SL-10625? + + // SL-10625 and neither does Intel in many cases + skip_readback = skip_readback || gGLManager.mIsIntel; if (!skip_readback) { diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl index a82af996a1..a8cac3e5a9 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl @@ -273,15 +273,11 @@ void main() vec2 abnormal = encode_normal(norm.xyz); vec4 final_color = diffuse_linear; - -#if (DIFFUSE_ALPHA_MODE != DIFFUSE_ALPHA_MODE_EMISSIVE) - final_color.a = emissive_brightness; -#else - final_color.a = max(final_color.a, emissive_brightness); -#endif -#if !defined(HAS_NORMAL_MAP) - final_color.a = 0.0f; +#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_EMISSIVE) + // nop, use content of alpha emissive mask as is... +#else + final_color.a = emissive_brightness; #endif vec4 final_specular = spec; @@ -459,6 +455,8 @@ vec3 post_atmo = color.rgb; #else // deferred path + +final_color = diffuse_linear; frag_data[0] = final_color; frag_data[1] = final_specular; // XYZ = Specular color. W = Specular exponent. frag_data[2] = final_normal; // XY = Normal. Z = Env. intensity. diff --git a/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl index 5ce246a114..c3b046552c 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl @@ -121,7 +121,7 @@ void main() // temp2.x is 0 at the sun and increases away from sun temp2.x = max(temp2.x, .001); // Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot) - temp2.x *= glow.x; + temp2.x *= glow.x * 0.33333; // Higher glow.x gives dimmer glow (because next step is 1 / "angle") temp2.x = pow(temp2.x, glow.z); // glow.z should be negative, so we're doing a sort of (1 / "angle") function diff --git a/indra/newview/app_settings/shaders/class1/environment/terrainWaterV.glsl b/indra/newview/app_settings/shaders/class1/environment/terrainWaterV.glsl index 416d406f68..a075cfeef2 100644 --- a/indra/newview/app_settings/shaders/class1/environment/terrainWaterV.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/terrainWaterV.glsl @@ -70,10 +70,6 @@ void main() vec4 color = calcLighting(pos.xyz, norm, vec4(1.0)); -#if defined(ALM) - color.rgb *= 0.5f; -#endif - vertex_color.rgb = color.rgb; // Transform and pass tex coords diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl index deda4d8b7e..786a65df0f 100644 --- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl +++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl @@ -68,7 +68,7 @@ void calcAtmosphericVars(vec3 inPositionEye, float ambFactor, out vec3 sunlit, o vec4 light_atten; float dens_mul = density_multiplier; - float dist_mul = max(0.05, distance_multiplier); + float dist_mul = distance_multiplier; //sunlight attenuation effect (hue and brightness) due to atmosphere //this is used later for sunlight modulation at various altitudes @@ -107,9 +107,9 @@ void calcAtmosphericVars(vec3 inPositionEye, float ambFactor, out vec3 sunlit, o //temp2.x is 0 at the sun and increases away from sun temp2.x = max(temp2.x, .001); //was glow.y //set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot) - temp2.x *= glow.x * 1.8; + temp2.x *= glow.x; //higher glow.x gives dimmer glow (because next step is 1 / "angle") - temp2.x = pow(temp2.x, glow.z * 0.2); + temp2.x = pow(temp2.x, glow.z); //glow.z should be negative, so we're doing a sort of (1 / "angle") function //add "minimum anti-solar illumination" diff --git a/indra/newview/app_settings/shaders/class2/deferred/skyF.glsl b/indra/newview/app_settings/shaders/class2/deferred/skyF.glsl index b826cff304..e3e58dd046 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/skyF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/skyF.glsl @@ -148,7 +148,7 @@ void main() // temp2.x is 0 at the sun and increases away from sun temp2.x = max(temp2.x, .001); // Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot) - temp2.x *= glow.x; + temp2.x *= glow.x * 0.33333; // Higher glow.x gives dimmer glow (because next step is 1 / "angle") temp2.x = pow(temp2.x, glow.z); // glow.z should be negative, so we're doing a sort of (1 / "angle") function diff --git a/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl b/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl index d81a8feb96..57ad8a92e5 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl @@ -119,7 +119,7 @@ void main() // temp2.x is 0 at the sun and increases away from sun temp2.x = max(temp2.x, .001); // Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot) - temp2.x *= glow.x; + temp2.x *= glow.x * 0.333333; // Higher glow.x gives dimmer glow (because next step is 1 / "angle") temp2.x = pow(temp2.x, glow.z); // glow.z should be negative, so we're doing a sort of (1 / "angle") function -- cgit v1.3 From 1d86dcd846ed5ea7734df507d15adf057cb2ebd0 Mon Sep 17 00:00:00 2001 From: Graham Linden Date: Mon, 8 Jul 2019 10:10:22 -0700 Subject: SL-10625 another shot across the bow Move dynamic texture update (which does local back readback work) to just before swap which may keep the Intel driver from tripping on its own shoelaces and is also subjectively faster for bakes. --- indra/llappearance/lltexlayer.cpp | 9 +++++---- indra/newview/lldrawpool.cpp | 9 +++++++-- indra/newview/lldrawpool.h | 2 +- indra/newview/lldynamictexture.cpp | 6 ++++-- indra/newview/llviewerdisplay.cpp | 38 +++++++++++++++++--------------------- 5 files changed, 34 insertions(+), 30 deletions(-) (limited to 'indra/llappearance/lltexlayer.cpp') diff --git a/indra/llappearance/lltexlayer.cpp b/indra/llappearance/lltexlayer.cpp index 645274a990..239fa95a6f 100644 --- a/indra/llappearance/lltexlayer.cpp +++ b/indra/llappearance/lltexlayer.cpp @@ -1579,9 +1579,10 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC // GPUs tend to be very uptight about memory alignment as the DMA used to convey // said data to the card works better when well-aligned so plain old default-aligned heap mem is a no-no //new U8[width * height]; - size_t mem_size = (width * height); - size_t rem = (mem_size & 0x3F); - mem_size += rem > 0 ? (mem_size + (32 - rem)) : 0; + size_t bytes_per_pixel = 1; // unsigned byte alpha channel only... + size_t row_size = (width + 3) & ~0x3; // OpenGL 4-byte row align (even for things < 4 bpp...) + size_t pixels = (row_size * height); + size_t mem_size = pixels * bytes_per_pixel; alpha_data = (U8*)ll_aligned_malloc_32(mem_size); @@ -1590,7 +1591,7 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC bool skip_readback = LLRender::sNsightDebugSupport; // nSight doesn't support use of glReadPixels // SL-10625 and neither does Intel in many cases - skip_readback = skip_readback || gGLManager.mIsIntel; + skip_readback = skip_readback;// || gGLManager.mIsIntel; if (!skip_readback) { diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp index 9c072bb0aa..b110a6a810 100644 --- a/indra/newview/lldrawpool.cpp +++ b/indra/newview/lldrawpool.cpp @@ -406,9 +406,9 @@ void LLRenderPass::renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL t } } -void LLRenderPass::renderTexture(U32 type, U32 mask) +void LLRenderPass::renderTexture(U32 type, U32 mask, BOOL batch_textures) { - pushBatches(type, mask, TRUE); + pushBatches(type, mask, batch_textures); } void LLRenderPass::pushBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures) @@ -461,6 +461,11 @@ void LLRenderPass::applyModelMatrix(const LLDrawInfo& params) void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures) { + if (!params.mCount) + { + return; + } + applyModelMatrix(params); bool tex_setup = false; diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h index df86d78a89..4eb9a4151d 100644 --- a/indra/newview/lldrawpool.h +++ b/indra/newview/lldrawpool.h @@ -174,7 +174,7 @@ public: virtual void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures = FALSE); virtual void renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture = TRUE); virtual void renderGroups(U32 type, U32 mask, BOOL texture = TRUE); - virtual void renderTexture(U32 type, U32 mask); + virtual void renderTexture(U32 type, U32 mask, BOOL batch_textures = TRUE); }; diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp index fa9a0712fa..5e283f7cd0 100644 --- a/indra/newview/lldynamictexture.cpp +++ b/indra/newview/lldynamictexture.cpp @@ -213,7 +213,7 @@ BOOL LLViewerDynamicTexture::updateAllInstances() sNumRenders = 0; if (gGLManager.mIsDisabled || LLPipeline::sMemAllocationThrottled) { - return TRUE; + return FALSE; } bool use_fbo = gGLManager.mHasFramebufferObject && gPipeline.mWaterDis.isComplete() && !gGLManager.mIsATI; @@ -248,7 +248,7 @@ BOOL LLViewerDynamicTexture::updateAllInstances() result = TRUE; sNumRenders++; } - gGL.flush(); + //gGL.flush(); LLVertexBuffer::unbind(); dynamicTexture->postRender(result); @@ -261,6 +261,8 @@ BOOL LLViewerDynamicTexture::updateAllInstances() gPipeline.mWaterDis.flush(); } + gGL.flush(); + return ret; } diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 736626debd..7101f6fbb0 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -130,9 +130,6 @@ void display_startup() gPipeline.updateGL(); - // Update images? - //gImageList.updateImages(0.01f); - // Written as branch to appease GCC which doesn't like different // pointer types across ternary ops // @@ -149,11 +146,6 @@ void display_startup() LLGLState::checkStates(); LLGLState::checkTextureChannels(); - if (frame_count++ > 1) // make sure we have rendered a frame first - { - LLViewerDynamicTexture::updateAllInstances(); - } - LLGLState::checkStates(); LLGLState::checkTextureChannels(); @@ -595,18 +587,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) // Actually push all of our triangles to the screen. // - // do render-to-texture stuff here - if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_DYNAMIC_TEXTURES)) - { - LLAppViewer::instance()->pingMainloopTimeout("Display:DynamicTextures"); - LL_RECORD_BLOCK_TIME(FTM_UPDATE_DYNAMIC_TEXTURES); - if (LLViewerDynamicTexture::updateAllInstances()) - { - gGL.setColorMask(true, true); - glClear(GL_DEPTH_BUFFER_BIT); - } - } - gViewerWindow->setup3DViewport(); gPipeline.resetFrameStats(); // Reset per-frame statistics. @@ -1037,10 +1017,26 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) if (!for_snapshot) { render_ui(); + } + + // do render-to-texture stuff here + if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_DYNAMIC_TEXTURES)) + { + LLAppViewer::instance()->pingMainloopTimeout("Display:DynamicTextures"); + LL_RECORD_BLOCK_TIME(FTM_UPDATE_DYNAMIC_TEXTURES); + if (LLViewerDynamicTexture::updateAllInstances()) + { + gGL.setColorMask(true, true); + glClear(GL_DEPTH_BUFFER_BIT); + } + } + + LLAppViewer::instance()->pingMainloopTimeout("Display:RenderUI"); + if (!for_snapshot) + { swap(); } - LLSpatialGroup::sNoDelete = FALSE; gPipeline.clearReferences(); -- cgit v1.3 From 26bf61811b018fdccdcd1e75a9d40d212f8aed70 Mon Sep 17 00:00:00 2001 From: Graham Linden Date: Mon, 8 Jul 2019 11:06:42 -0700 Subject: SL-10625 Appease Clang. --- indra/llappearance/lltexlayer.cpp | 3 --- 1 file changed, 3 deletions(-) (limited to 'indra/llappearance/lltexlayer.cpp') diff --git a/indra/llappearance/lltexlayer.cpp b/indra/llappearance/lltexlayer.cpp index 239fa95a6f..00196076eb 100644 --- a/indra/llappearance/lltexlayer.cpp +++ b/indra/llappearance/lltexlayer.cpp @@ -1590,9 +1590,6 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC bool skip_readback = LLRender::sNsightDebugSupport; // nSight doesn't support use of glReadPixels - // SL-10625 and neither does Intel in many cases - skip_readback = skip_readback;// || gGLManager.mIsIntel; - if (!skip_readback) { glReadPixels(x, y, width, height, GL_ALPHA, GL_UNSIGNED_BYTE, alpha_data); -- cgit v1.3 From 76c41dafe939da18a1f1012779e2a53e46c35eb8 Mon Sep 17 00:00:00 2001 From: Graham Linden Date: Mon, 8 Jul 2019 11:18:54 -0700 Subject: Roll back 10625 change and continue to side-step intel readback bug. --- indra/llappearance/lltexlayer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llappearance/lltexlayer.cpp') diff --git a/indra/llappearance/lltexlayer.cpp b/indra/llappearance/lltexlayer.cpp index 00196076eb..ca0d102b74 100644 --- a/indra/llappearance/lltexlayer.cpp +++ b/indra/llappearance/lltexlayer.cpp @@ -1588,7 +1588,7 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC mAlphaCache[cache_index] = alpha_data; - bool skip_readback = LLRender::sNsightDebugSupport; // nSight doesn't support use of glReadPixels + bool skip_readback = LLRender::sNsightDebugSupport || gGLManager.mIsIntel; // nSight doesn't support use of glReadPixels if (!skip_readback) { -- cgit v1.3 From 6a7f12ebcf8009188cfec659f1f29852dcc932c8 Mon Sep 17 00:00:00 2001 From: Graham Linden Date: Thu, 11 Jul 2019 13:34:32 -0700 Subject: SL-10625 Keep texture baking from pointlessly mercy flushing GL like a kid that just discovered the toilet handle. Make glReadPixels call use GL_ALPHA8 (a texture format) instead of GL_ALPHA (an enum to indicate the alpha channel). --- indra/llappearance/lltexlayer.cpp | 29 ++++------------------------- 1 file changed, 4 insertions(+), 25 deletions(-) (limited to 'indra/llappearance/lltexlayer.cpp') diff --git a/indra/llappearance/lltexlayer.cpp b/indra/llappearance/lltexlayer.cpp index ca0d102b74..0bfabc7b80 100644 --- a/indra/llappearance/lltexlayer.cpp +++ b/indra/llappearance/lltexlayer.cpp @@ -162,7 +162,6 @@ BOOL LLTexLayerSetBuffer::renderTexLayerSet() LLGLSUIDefault gls_ui; success &= mTexLayerSet->render( getCompositeOriginX(), getCompositeOriginY(), getCompositeWidth(), getCompositeHeight() ); - gGL.flush(); midRenderTexLayerSet(success); @@ -400,7 +399,6 @@ BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height ) // clear buffer area to ensure we don't pick up UI elements { - gGL.flush(); LLGLDisable no_alpha(GL_ALPHA_TEST); if (use_shaders) { @@ -410,8 +408,7 @@ BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height ) gGL.color4f( 0.f, 0.f, 0.f, 1.f ); gl_rect_2d_simple( width, height ); - - gGL.flush(); + if (use_shaders) { gAlphaMaskProgram.setMinimumAlpha(0.004f); @@ -426,9 +423,7 @@ BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height ) LLTexLayerInterface* layer = *iter; if (layer->getRenderPass() == LLTexLayer::RP_COLOR) { - gGL.flush(); success &= layer->render(x, y, width, height); - gGL.flush(); } } @@ -438,8 +433,6 @@ BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height ) } else { - gGL.flush(); - gGL.setSceneBlendType(LLRender::BT_REPLACE); LLGLDisable no_alpha(GL_ALPHA_TEST); if (use_shaders) @@ -452,8 +445,7 @@ BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height ) gl_rect_2d_simple( width, height ); gGL.setSceneBlendType(LLRender::BT_ALPHA); - - gGL.flush(); + if (use_shaders) { gAlphaMaskProgram.setMinimumAlpha(0.004f); @@ -552,7 +544,6 @@ void LLTexLayerSet::renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, // (Optionally) replace alpha with a single component image from a tga file. if (!info->mStaticAlphaFileName.empty()) { - gGL.flush(); { LLGLTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(info->mStaticAlphaFileName, TRUE); if( tex ) @@ -563,12 +554,10 @@ void LLTexLayerSet::renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, gl_rect_2d_simple_tex( width, height ); } } - gGL.flush(); } else if (forceClear || info->mClearAlpha || (mMaskLayerList.size() > 0)) { // Set the alpha channel to one (clean up after previous blending) - gGL.flush(); LLGLDisable no_alpha(GL_ALPHA_TEST); if (use_shaders) { @@ -579,7 +568,6 @@ void LLTexLayerSet::renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, gl_rect_2d_simple( width, height ); - gGL.flush(); if (use_shaders) { gAlphaMaskProgram.setMinimumAlpha(0.004f); @@ -595,9 +583,7 @@ void LLTexLayerSet::renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, for (layer_list_t::iterator iter = mMaskLayerList.begin(); iter != mMaskLayerList.end(); iter++) { LLTexLayerInterface* layer = *iter; - gGL.flush(); layer->blendAlphaTexture(x,y,width, height); - gGL.flush(); } } @@ -1187,7 +1173,6 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height) const bool force_render = true; renderMorphMasks(x, y, width, height, net_color, force_render); alpha_mask_specified = TRUE; - gGL.flush(); gGL.blendFunc(LLRender::BF_DEST_ALPHA, LLRender::BF_ONE_MINUS_DEST_ALPHA); } @@ -1195,7 +1180,6 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height) if( getInfo()->mWriteAllChannels ) { - gGL.flush(); gGL.setSceneBlendType(LLRender::BT_REPLACE); } @@ -1294,7 +1278,6 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height) if( alpha_mask_specified || getInfo()->mWriteAllChannels ) { // Restore standard blend func value - gGL.flush(); gGL.setSceneBlendType(LLRender::BT_ALPHA); stop_glerror(); } @@ -1373,8 +1356,6 @@ BOOL LLTexLayer::findNetColor(LLColor4* net_color) const BOOL LLTexLayer::blendAlphaTexture(S32 x, S32 y, S32 width, S32 height) { BOOL success = TRUE; - - gGL.flush(); bool use_shaders = LLGLSLShader::sNoFixedFunction; @@ -1463,7 +1444,6 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); // Clear the alpha - gGL.flush(); gGL.setSceneBlendType(LLRender::BT_REPLACE); gGL.color4f( 0.f, 0.f, 0.f, 0.f ); @@ -1485,7 +1465,6 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC } // Approximates a min() function - gGL.flush(); gGL.setSceneBlendType(LLRender::BT_MULT_ALPHA); // Accumulate the alpha component of the texture @@ -1588,11 +1567,11 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC mAlphaCache[cache_index] = alpha_data; - bool skip_readback = LLRender::sNsightDebugSupport || gGLManager.mIsIntel; // nSight doesn't support use of glReadPixels + bool skip_readback = LLRender::sNsightDebugSupport; // nSight doesn't support use of glReadPixels if (!skip_readback) { - glReadPixels(x, y, width, height, GL_ALPHA, GL_UNSIGNED_BYTE, alpha_data); + glReadPixels(x, y, width, height, GL_ALPHA8, GL_UNSIGNED_BYTE, alpha_data); } else { -- cgit v1.3 From b8f64c55b7da9ee84f5ae570ff12cc3a57ca0d07 Mon Sep 17 00:00:00 2001 From: Graham Linden Date: Fri, 12 Jul 2019 09:34:38 -0700 Subject: SL-11545 Fix glow calcs in sky shaders (not just the not shared enough atmospherics funcs). Revert 10625 attempted fix as it breaks baggy clothes as much as skipping readbacks does. --- indra/llappearance/lltexlayer.cpp | 29 +++++++++++++++++++--- .../app_settings/shaders/class1/deferred/skyV.glsl | 2 +- .../app_settings/shaders/class2/deferred/skyF.glsl | 2 +- .../shaders/class2/windlight/skyV.glsl | 2 +- 4 files changed, 28 insertions(+), 7 deletions(-) (limited to 'indra/llappearance/lltexlayer.cpp') diff --git a/indra/llappearance/lltexlayer.cpp b/indra/llappearance/lltexlayer.cpp index 0bfabc7b80..ca0d102b74 100644 --- a/indra/llappearance/lltexlayer.cpp +++ b/indra/llappearance/lltexlayer.cpp @@ -162,6 +162,7 @@ BOOL LLTexLayerSetBuffer::renderTexLayerSet() LLGLSUIDefault gls_ui; success &= mTexLayerSet->render( getCompositeOriginX(), getCompositeOriginY(), getCompositeWidth(), getCompositeHeight() ); + gGL.flush(); midRenderTexLayerSet(success); @@ -399,6 +400,7 @@ BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height ) // clear buffer area to ensure we don't pick up UI elements { + gGL.flush(); LLGLDisable no_alpha(GL_ALPHA_TEST); if (use_shaders) { @@ -408,7 +410,8 @@ BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height ) gGL.color4f( 0.f, 0.f, 0.f, 1.f ); gl_rect_2d_simple( width, height ); - + + gGL.flush(); if (use_shaders) { gAlphaMaskProgram.setMinimumAlpha(0.004f); @@ -423,7 +426,9 @@ BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height ) LLTexLayerInterface* layer = *iter; if (layer->getRenderPass() == LLTexLayer::RP_COLOR) { + gGL.flush(); success &= layer->render(x, y, width, height); + gGL.flush(); } } @@ -433,6 +438,8 @@ BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height ) } else { + gGL.flush(); + gGL.setSceneBlendType(LLRender::BT_REPLACE); LLGLDisable no_alpha(GL_ALPHA_TEST); if (use_shaders) @@ -445,7 +452,8 @@ BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height ) gl_rect_2d_simple( width, height ); gGL.setSceneBlendType(LLRender::BT_ALPHA); - + + gGL.flush(); if (use_shaders) { gAlphaMaskProgram.setMinimumAlpha(0.004f); @@ -544,6 +552,7 @@ void LLTexLayerSet::renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, // (Optionally) replace alpha with a single component image from a tga file. if (!info->mStaticAlphaFileName.empty()) { + gGL.flush(); { LLGLTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(info->mStaticAlphaFileName, TRUE); if( tex ) @@ -554,10 +563,12 @@ void LLTexLayerSet::renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, gl_rect_2d_simple_tex( width, height ); } } + gGL.flush(); } else if (forceClear || info->mClearAlpha || (mMaskLayerList.size() > 0)) { // Set the alpha channel to one (clean up after previous blending) + gGL.flush(); LLGLDisable no_alpha(GL_ALPHA_TEST); if (use_shaders) { @@ -568,6 +579,7 @@ void LLTexLayerSet::renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, gl_rect_2d_simple( width, height ); + gGL.flush(); if (use_shaders) { gAlphaMaskProgram.setMinimumAlpha(0.004f); @@ -583,7 +595,9 @@ void LLTexLayerSet::renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, for (layer_list_t::iterator iter = mMaskLayerList.begin(); iter != mMaskLayerList.end(); iter++) { LLTexLayerInterface* layer = *iter; + gGL.flush(); layer->blendAlphaTexture(x,y,width, height); + gGL.flush(); } } @@ -1173,6 +1187,7 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height) const bool force_render = true; renderMorphMasks(x, y, width, height, net_color, force_render); alpha_mask_specified = TRUE; + gGL.flush(); gGL.blendFunc(LLRender::BF_DEST_ALPHA, LLRender::BF_ONE_MINUS_DEST_ALPHA); } @@ -1180,6 +1195,7 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height) if( getInfo()->mWriteAllChannels ) { + gGL.flush(); gGL.setSceneBlendType(LLRender::BT_REPLACE); } @@ -1278,6 +1294,7 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height) if( alpha_mask_specified || getInfo()->mWriteAllChannels ) { // Restore standard blend func value + gGL.flush(); gGL.setSceneBlendType(LLRender::BT_ALPHA); stop_glerror(); } @@ -1356,6 +1373,8 @@ BOOL LLTexLayer::findNetColor(LLColor4* net_color) const BOOL LLTexLayer::blendAlphaTexture(S32 x, S32 y, S32 width, S32 height) { BOOL success = TRUE; + + gGL.flush(); bool use_shaders = LLGLSLShader::sNoFixedFunction; @@ -1444,6 +1463,7 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); // Clear the alpha + gGL.flush(); gGL.setSceneBlendType(LLRender::BT_REPLACE); gGL.color4f( 0.f, 0.f, 0.f, 0.f ); @@ -1465,6 +1485,7 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC } // Approximates a min() function + gGL.flush(); gGL.setSceneBlendType(LLRender::BT_MULT_ALPHA); // Accumulate the alpha component of the texture @@ -1567,11 +1588,11 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC mAlphaCache[cache_index] = alpha_data; - bool skip_readback = LLRender::sNsightDebugSupport; // nSight doesn't support use of glReadPixels + bool skip_readback = LLRender::sNsightDebugSupport || gGLManager.mIsIntel; // nSight doesn't support use of glReadPixels if (!skip_readback) { - glReadPixels(x, y, width, height, GL_ALPHA8, GL_UNSIGNED_BYTE, alpha_data); + glReadPixels(x, y, width, height, GL_ALPHA, GL_UNSIGNED_BYTE, alpha_data); } else { diff --git a/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl index c3b046552c..5ce246a114 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl @@ -121,7 +121,7 @@ void main() // temp2.x is 0 at the sun and increases away from sun temp2.x = max(temp2.x, .001); // Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot) - temp2.x *= glow.x * 0.33333; + temp2.x *= glow.x; // Higher glow.x gives dimmer glow (because next step is 1 / "angle") temp2.x = pow(temp2.x, glow.z); // glow.z should be negative, so we're doing a sort of (1 / "angle") function diff --git a/indra/newview/app_settings/shaders/class2/deferred/skyF.glsl b/indra/newview/app_settings/shaders/class2/deferred/skyF.glsl index e3e58dd046..b826cff304 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/skyF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/skyF.glsl @@ -148,7 +148,7 @@ void main() // temp2.x is 0 at the sun and increases away from sun temp2.x = max(temp2.x, .001); // Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot) - temp2.x *= glow.x * 0.33333; + temp2.x *= glow.x; // Higher glow.x gives dimmer glow (because next step is 1 / "angle") temp2.x = pow(temp2.x, glow.z); // glow.z should be negative, so we're doing a sort of (1 / "angle") function diff --git a/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl b/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl index 57ad8a92e5..d81a8feb96 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl @@ -119,7 +119,7 @@ void main() // temp2.x is 0 at the sun and increases away from sun temp2.x = max(temp2.x, .001); // Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot) - temp2.x *= glow.x * 0.333333; + temp2.x *= glow.x; // Higher glow.x gives dimmer glow (because next step is 1 / "angle") temp2.x = pow(temp2.x, glow.z); // glow.z should be negative, so we're doing a sort of (1 / "angle") function -- cgit v1.3 From 11331604767b2dcf50c7a84f24843ce8e531a409 Mon Sep 17 00:00:00 2001 From: Graham Linden Date: Fri, 12 Jul 2019 13:26:02 -0700 Subject: SL-11109 Make shadowAlphaMask shader ignore vertex alpha before discards iff we're a fullbright object. Keep llappearance from stuffing dangling pointers into the alpha cache (crash iff you're using nSight debugging and disable readbacks). --- indra/llappearance/lltexlayer.cpp | 6 ++--- indra/llrender/llvertexbuffer.cpp | 26 +++++++++++----------- .../shaders/class1/deferred/shadowAlphaMaskF.glsl | 6 +++-- indra/newview/llviewershadermgr.cpp | 22 ++++++++++++++++++ indra/newview/llviewershadermgr.h | 1 + indra/newview/llvovolume.cpp | 2 +- indra/newview/pipeline.cpp | 21 +++++++++++++++-- indra/newview/pipeline.h | 1 + 8 files changed, 64 insertions(+), 21 deletions(-) (limited to 'indra/llappearance/lltexlayer.cpp') diff --git a/indra/llappearance/lltexlayer.cpp b/indra/llappearance/lltexlayer.cpp index ca0d102b74..19a4f3e12d 100644 --- a/indra/llappearance/lltexlayer.cpp +++ b/indra/llappearance/lltexlayer.cpp @@ -1586,8 +1586,6 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC alpha_data = (U8*)ll_aligned_malloc_32(mem_size); - mAlphaCache[cache_index] = alpha_data; - bool skip_readback = LLRender::sNsightDebugSupport || gGLManager.mIsIntel; // nSight doesn't support use of glReadPixels if (!skip_readback) @@ -1598,7 +1596,9 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC { ll_aligned_free_32(alpha_data); alpha_data = nullptr; - } + } + + mAlphaCache[cache_index] = alpha_data; } getTexLayerSet()->getAvatarAppearance()->dirtyMesh(); diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 1312f6afda..0c53d48c08 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -942,15 +942,15 @@ S32 LLVertexBuffer::determineUsage(S32 usage) { //only stream_draw and dynamic_draw are supported when using VBOs, dynamic draw is the default if (ret_usage != GL_DYNAMIC_COPY_ARB) { - if (sDisableVBOMapping) - { //always use stream draw if VBO mapping is disabled - ret_usage = GL_STREAM_DRAW_ARB; - } - else - { - ret_usage = GL_DYNAMIC_DRAW_ARB; - } - } + if (sDisableVBOMapping) + { //always use stream draw if VBO mapping is disabled + ret_usage = GL_STREAM_DRAW_ARB; + } + else + { + ret_usage = GL_DYNAMIC_DRAW_ARB; + } + } } return ret_usage; @@ -1506,10 +1506,10 @@ bool LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices) llassert(newnverts >= 0); llassert(newnindices >= 0); - bool sucsess = true; + bool success = true; - sucsess &= updateNumVerts(newnverts); - sucsess &= updateNumIndices(newnindices); + success &= updateNumVerts(newnverts); + success &= updateNumIndices(newnindices); if (useVBOs()) { @@ -1521,7 +1521,7 @@ bool LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices) } } - return sucsess; + return success; } bool LLVertexBuffer::useVBOs() const diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl index 0d028d2729..9b8df0a5a4 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl @@ -49,6 +49,10 @@ void main() discard; } +#if !defined(IS_FULLBRIGHT) + alpha *= vertex_color.a; +#endif + if (alpha < 0.05) // treat as totally transparent { discard; @@ -62,8 +66,6 @@ void main() } } - alpha *= vertex_color.a; - frag_color = vec4(1,1,1,1); #if !defined(DEPTH_CLAMP) diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index bd8064999f..5297e59e18 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -215,6 +215,7 @@ LLGLSLShader gDeferredSoftenWaterProgram; LLGLSLShader gDeferredShadowProgram; LLGLSLShader gDeferredShadowCubeProgram; LLGLSLShader gDeferredShadowAlphaMaskProgram; +LLGLSLShader gDeferredShadowFullbrightAlphaMaskProgram; LLGLSLShader gDeferredAvatarShadowProgram; LLGLSLShader gDeferredAvatarAlphaShadowProgram; LLGLSLShader gDeferredAvatarAlphaMaskShadowProgram; @@ -1293,6 +1294,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredShadowProgram.unload(); gDeferredShadowCubeProgram.unload(); gDeferredShadowAlphaMaskProgram.unload(); + gDeferredShadowFullbrightAlphaMaskProgram.unload(); gDeferredAvatarShadowProgram.unload(); gDeferredAvatarAlphaShadowProgram.unload(); gDeferredAvatarAlphaMaskShadowProgram.unload(); @@ -2401,6 +2403,26 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() } if (success) + { + gDeferredShadowFullbrightAlphaMaskProgram.mName = "Deferred Shadow Fullbright Alpha Mask Shader"; + gDeferredShadowFullbrightAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; + + gDeferredShadowFullbrightAlphaMaskProgram.mShaderFiles.clear(); + gDeferredShadowFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredShadowFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER_ARB)); + + gDeferredShadowFullbrightAlphaMaskProgram.clearPermutations(); + if (gGLManager.mHasDepthClamp) + { + gDeferredShadowFullbrightAlphaMaskProgram.addPermutation("DEPTH_CLAMP", "1"); + } + gDeferredShadowFullbrightAlphaMaskProgram.addPermutation("IS_FULLBRIGHT", "1"); + gDeferredShadowFullbrightAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = gDeferredShadowFullbrightAlphaMaskProgram.createShader(NULL, NULL); + llassert(success); + } + + if (success) { gDeferredShadowAlphaMaskProgram.mName = "Deferred Shadow Alpha Mask Shader"; gDeferredShadowAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index 18be3c22aa..081221f15b 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -301,6 +301,7 @@ extern LLGLSLShader gDeferredSoftenWaterProgram; extern LLGLSLShader gDeferredShadowProgram; extern LLGLSLShader gDeferredShadowCubeProgram; extern LLGLSLShader gDeferredShadowAlphaMaskProgram; +extern LLGLSLShader gDeferredShadowFullbrightAlphaMaskProgram; extern LLGLSLShader gDeferredPostProgram; extern LLGLSLShader gDeferredCoFProgram; extern LLGLSLShader gDeferredDoFCombineProgram; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 3740caa53f..d149a61d89 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -6680,7 +6680,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace { registerFace(group, facep, LLRenderPass::PASS_SIMPLE); } - } + } } diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 6f3e6819c4..863785889f 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -7452,6 +7452,15 @@ void LLPipeline::renderMaskedObjects(U32 type, U32 mask, bool texture, bool batc gGLLastMatrix = NULL; } +void LLPipeline::renderFullbrightMaskedObjects(U32 type, U32 mask, bool texture, bool batch_texture) +{ + assertInitialized(); + gGL.loadMatrix(gGLModelView); + gGLLastMatrix = NULL; + mFullbrightAlphaMaskPool->pushMaskBatches(type, mask, texture, batch_texture); + gGL.loadMatrix(gGLModelView); + gGLLastMatrix = NULL; +} void apply_cube_face_rotation(U32 face) { @@ -9608,6 +9617,7 @@ static LLTrace::BlockTimerStatHandle FTM_SHADOW_ALPHA_MASKED("Alpha Masked"); static LLTrace::BlockTimerStatHandle FTM_SHADOW_ALPHA_BLEND("Alpha Blend"); static LLTrace::BlockTimerStatHandle FTM_SHADOW_ALPHA_TREE("Alpha Tree"); static LLTrace::BlockTimerStatHandle FTM_SHADOW_ALPHA_GRASS("Alpha Grass"); +static LLTrace::BlockTimerStatHandle FTM_SHADOW_FULLBRIGHT_ALPHA_MASKED("Fullbright Alpha Masked"); void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera& shadow_cam, LLCullResult &result, bool use_shader, bool use_occlusion, U32 target_width) { @@ -9740,8 +9750,7 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera { LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA_MASKED); - renderMaskedObjects(LLRenderPass::PASS_ALPHA_MASK, mask, TRUE, TRUE); - renderMaskedObjects(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, mask, TRUE, TRUE); + renderMaskedObjects(LLRenderPass::PASS_ALPHA_MASK, mask, TRUE, TRUE); } { @@ -9750,6 +9759,14 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera renderObjects(LLRenderPass::PASS_ALPHA, mask, TRUE, TRUE); } + { + LL_RECORD_BLOCK_TIME(FTM_SHADOW_FULLBRIGHT_ALPHA_MASKED); + gDeferredShadowFullbrightAlphaMaskProgram.bind(); + gDeferredShadowFullbrightAlphaMaskProgram.uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width); + gDeferredShadowFullbrightAlphaMaskProgram.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0); + renderFullbrightMaskedObjects(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, mask, TRUE, TRUE); + } + mask = mask & ~LLVertexBuffer::MAP_TEXTURE_INDEX; { diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index fe81ae91e8..b0c40d145b 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -261,6 +261,7 @@ public: void renderObjects(U32 type, U32 mask, bool texture = true, bool batch_texture = false); void renderMaskedObjects(U32 type, U32 mask, bool texture = true, bool batch_texture = false); + void renderFullbrightMaskedObjects(U32 type, U32 mask, bool texture = true, bool batch_texture = false); void renderGroups(LLRenderPass* pass, U32 type, U32 mask, bool texture); -- cgit v1.3 From 946da4e507dd00e6e7a9e465d38494bcafe4f652 Mon Sep 17 00:00:00 2001 From: Graham Linden Date: Mon, 15 Jul 2019 15:04:48 -0700 Subject: SL-10761 Add work-around for broken intel drivers which can't use glReadPixels from RGBA FBOs to get alpha without locking up. --- indra/llappearance/lltexlayer.cpp | 73 +++++++++++++++++++++++++++----------- indra/llappearance/lltexlayer.h | 24 ++++++------- indra/newview/lldynamictexture.cpp | 3 +- indra/newview/lldynamictexture.h | 5 +++ indra/newview/llviewertexlayer.h | 2 +- 5 files changed, 72 insertions(+), 35 deletions(-) (limited to 'indra/llappearance/lltexlayer.cpp') diff --git a/indra/llappearance/lltexlayer.cpp b/indra/llappearance/lltexlayer.cpp index 19a4f3e12d..9d294645db 100644 --- a/indra/llappearance/lltexlayer.cpp +++ b/indra/llappearance/lltexlayer.cpp @@ -137,7 +137,7 @@ void LLTexLayerSetBuffer::postRenderTexLayerSet(BOOL success) popProjection(); } -BOOL LLTexLayerSetBuffer::renderTexLayerSet() +BOOL LLTexLayerSetBuffer::renderTexLayerSet(LLRenderTarget* bound_target) { // Default color mask for tex layer render gGL.setColorMask(true, true); @@ -161,7 +161,7 @@ BOOL LLTexLayerSetBuffer::renderTexLayerSet() // Composite the color data LLGLSUIDefault gls_ui; success &= mTexLayerSet->render( getCompositeOriginX(), getCompositeOriginY(), - getCompositeWidth(), getCompositeHeight() ); + getCompositeWidth(), getCompositeHeight(), bound_target ); gGL.flush(); midRenderTexLayerSet(success); @@ -375,7 +375,7 @@ void LLTexLayerSet::deleteCaches() } -BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height ) +BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height, LLRenderTarget* bound_target ) { BOOL success = TRUE; mIsVisible = TRUE; @@ -427,7 +427,7 @@ BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height ) if (layer->getRenderPass() == LLTexLayer::RP_COLOR) { gGL.flush(); - success &= layer->render(x, y, width, height); + success &= layer->render(x, y, width, height, bound_target); gGL.flush(); } } @@ -523,7 +523,7 @@ const LLTexLayerSetBuffer* LLTexLayerSet::getComposite() const } static LLTrace::BlockTimerStatHandle FTM_GATHER_MORPH_MASK_ALPHA("gatherMorphMaskAlpha"); -void LLTexLayerSet::gatherMorphMaskAlpha(U8 *data, S32 origin_x, S32 origin_y, S32 width, S32 height) +void LLTexLayerSet::gatherMorphMaskAlpha(U8 *data, S32 origin_x, S32 origin_y, S32 width, S32 height, LLRenderTarget* bound_target) { LL_RECORD_BLOCK_TIME(FTM_GATHER_MORPH_MASK_ALPHA); memset(data, 255, width * height); @@ -531,15 +531,15 @@ void LLTexLayerSet::gatherMorphMaskAlpha(U8 *data, S32 origin_x, S32 origin_y, S for( layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ ) { LLTexLayerInterface* layer = *iter; - layer->gatherAlphaMasks(data, origin_x, origin_y, width, height); + layer->gatherAlphaMasks(data, origin_x, origin_y, width, height, bound_target); } // Set alpha back to that of our alpha masks. - renderAlphaMaskTextures(origin_x, origin_y, width, height, true); + renderAlphaMaskTextures(origin_x, origin_y, width, height, bound_target, true); } static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_MASK_TEXTURES("renderAlphaMaskTextures"); -void LLTexLayerSet::renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, bool forceClear) +void LLTexLayerSet::renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* bound_target, bool forceClear) { LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_MASK_TEXTURES); const LLTexLayerSetInfo *info = getInfo(); @@ -1124,7 +1124,7 @@ void LLTexLayer::calculateTexLayerColor(const param_color_list_t ¶m_list, LL } } -BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height) +BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* bound_target) { LLGLEnable color_mat(GL_COLOR_MATERIAL); // *TODO: Is this correct? @@ -1185,7 +1185,7 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height) }//*/ const bool force_render = true; - renderMorphMasks(x, y, width, height, net_color, force_render); + renderMorphMasks(x, y, width, height, net_color, bound_target, force_render); alpha_mask_specified = TRUE; gGL.flush(); gGL.blendFunc(LLRender::BF_DEST_ALPHA, LLRender::BF_ONE_MINUS_DEST_ALPHA); @@ -1428,13 +1428,13 @@ BOOL LLTexLayer::blendAlphaTexture(S32 x, S32 y, S32 width, S32 height) return success; } -/*virtual*/ void LLTexLayer::gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height) +/*virtual*/ void LLTexLayer::gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height, LLRenderTarget* bound_target) { - addAlphaMask(data, originX, originY, width, height); + addAlphaMask(data, originX, originY, width, height, bound_target); } static LLTrace::BlockTimerStatHandle FTM_RENDER_MORPH_MASKS("renderMorphMasks"); -void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLColor4 &layer_color, bool force_render) +void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLColor4 &layer_color, LLRenderTarget* bound_target, bool force_render) { if (!force_render && !hasMorph()) { @@ -1586,11 +1586,42 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC alpha_data = (U8*)ll_aligned_malloc_32(mem_size); - bool skip_readback = LLRender::sNsightDebugSupport || gGLManager.mIsIntel; // nSight doesn't support use of glReadPixels + bool skip_readback = LLRender::sNsightDebugSupport; // nSight doesn't support use of glReadPixels if (!skip_readback) { - glReadPixels(x, y, width, height, GL_ALPHA, GL_UNSIGNED_BYTE, alpha_data); + if (gGLManager.mIsIntel) + { // work-around for broken intel drivers which cannot do glReadPixels on an RGBA FBO + // returning only the alpha portion without locking up downstream + U8* temp = (U8*)ll_aligned_malloc_32(mem_size << 2); // allocate same size, but RGBA + + if (bound_target) + { + gGL.getTexUnit(0)->bind(bound_target); + } + else + { + gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, 0); + } + + glGetTexImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGBA, GL_UNSIGNED_BYTE, temp); + + U8* alpha_cursor = alpha_data; + U8* pixel = temp; + for (int i = 0; i < pixels; i++) + { + *alpha_cursor++ = pixel[3]; + pixel += 4; + } + + gGL.getTexUnit(0)->disable(); + + ll_aligned_free_32(temp); + } + else + { // platforms with working drivers... + glReadPixels(x, y, width, height, GL_ALPHA, GL_UNSIGNED_BYTE, alpha_data); + } } else { @@ -1609,7 +1640,7 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC } static LLTrace::BlockTimerStatHandle FTM_ADD_ALPHA_MASK("addAlphaMask"); -void LLTexLayer::addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32 height) +void LLTexLayer::addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32 height, LLRenderTarget* bound_target) { LL_RECORD_BLOCK_TIME(FTM_ADD_ALPHA_MASK); S32 size = width * height; @@ -1621,7 +1652,7 @@ void LLTexLayer::addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32 // TODO: eliminate need for layer morph mask valid flag invalidateMorphMasks(); const bool force_render = false; - renderMorphMasks(originX, originY, width, height, net_color, force_render); + renderMorphMasks(originX, originY, width, height, net_color, bound_target, force_render); alphaData = getAlphaData(); } if (alphaData) @@ -1755,7 +1786,7 @@ LLTexLayer* LLTexLayerTemplate::getLayer(U32 i) const return layer; } -/*virtual*/ BOOL LLTexLayerTemplate::render(S32 x, S32 y, S32 width, S32 height) +/*virtual*/ BOOL LLTexLayerTemplate::render(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* bound_target) { if(!mInfo) { @@ -1782,7 +1813,7 @@ LLTexLayer* LLTexLayerTemplate::getLayer(U32 i) const { wearable->writeToAvatar(mAvatarAppearance); layer->setLTO(lto); - success &= layer->render(x,y,width,height); + success &= layer->render(x, y, width, height, bound_target); } } @@ -1804,14 +1835,14 @@ LLTexLayer* LLTexLayerTemplate::getLayer(U32 i) const return success; } -/*virtual*/ void LLTexLayerTemplate::gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height) +/*virtual*/ void LLTexLayerTemplate::gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height, LLRenderTarget* bound_target) { U32 num_wearables = updateWearableCache(); U32 i = num_wearables - 1; // For rendering morph masks, we only want to use the top wearable LLTexLayer *layer = getLayer(i); if (layer) { - layer->addAlphaMask(data, originX, originY, width, height); + layer->addAlphaMask(data, originX, originY, width, height, bound_target); } } diff --git a/indra/llappearance/lltexlayer.h b/indra/llappearance/lltexlayer.h index 9318b23fd1..6a5040cf0b 100644 --- a/indra/llappearance/lltexlayer.h +++ b/indra/llappearance/lltexlayer.h @@ -65,7 +65,7 @@ public: LLTexLayerInterface(const LLTexLayerInterface &layer, LLWearable *wearable); virtual ~LLTexLayerInterface() {} - virtual BOOL render(S32 x, S32 y, S32 width, S32 height) = 0; + virtual BOOL render(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* bound_target) = 0; virtual void deleteCaches() = 0; virtual BOOL blendAlphaTexture(S32 x, S32 y, S32 width, S32 height) = 0; virtual BOOL isInvisibleAlphaMask() const = 0; @@ -85,7 +85,7 @@ public: BOOL isMorphValid() const { return mMorphMasksValid; } void requestUpdate(); - virtual void gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height) = 0; + virtual void gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height, LLRenderTarget* bound_target) = 0; BOOL hasAlphaParams() const { return !mParamAlphaList.empty(); } ERenderPass getRenderPass() const; @@ -121,10 +121,10 @@ public: LLTexLayerTemplate(LLTexLayerSet* const layer_set, LLAvatarAppearance* const appearance); LLTexLayerTemplate(const LLTexLayerTemplate &layer); /*virtual*/ ~LLTexLayerTemplate(); - /*virtual*/ BOOL render(S32 x, S32 y, S32 width, S32 height); + /*virtual*/ BOOL render(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* bound_target); /*virtual*/ BOOL setInfo(const LLTexLayerInfo *info, LLWearable* wearable); // This sets mInfo and calls initialization functions /*virtual*/ BOOL blendAlphaTexture(S32 x, S32 y, S32 width, S32 height); // Multiplies a single alpha texture against the frame buffer - /*virtual*/ void gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height); + /*virtual*/ void gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height, LLRenderTarget* bound_target); /*virtual*/ void setHasMorph(BOOL newval); /*virtual*/ void deleteCaches(); /*virtual*/ BOOL isInvisibleAlphaMask() const; @@ -152,16 +152,16 @@ public: /*virtual*/ ~LLTexLayer(); /*virtual*/ BOOL setInfo(const LLTexLayerInfo *info, LLWearable* wearable); // This sets mInfo and calls initialization functions - /*virtual*/ BOOL render(S32 x, S32 y, S32 width, S32 height); + /*virtual*/ BOOL render(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* bound_target); /*virtual*/ void deleteCaches(); const U8* getAlphaData() const; BOOL findNetColor(LLColor4* color) const; /*virtual*/ BOOL blendAlphaTexture(S32 x, S32 y, S32 width, S32 height); // Multiplies a single alpha texture against the frame buffer - /*virtual*/ void gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height); - void renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLColor4 &layer_color, bool force_render); - void addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32 height); + /*virtual*/ void gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height, LLRenderTarget* bound_target); + void renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLColor4 &layer_color, LLRenderTarget* bound_target, bool force_render); + void addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32 height, LLRenderTarget* bound_target); /*virtual*/ BOOL isInvisibleAlphaMask() const; void setLTO(LLLocalTextureObject *lto) { mLocalTextureObject = lto; } @@ -194,13 +194,13 @@ public: const LLTexLayerSetBuffer* getComposite() const; // Do not create one if it doesn't exist. virtual void createComposite() = 0; void destroyComposite(); - void gatherMorphMaskAlpha(U8 *data, S32 origin_x, S32 origin_y, S32 width, S32 height); + void gatherMorphMaskAlpha(U8 *data, S32 origin_x, S32 origin_y, S32 width, S32 height, LLRenderTarget* bound_target); const LLTexLayerSetInfo* getInfo() const { return mInfo; } BOOL setInfo(const LLTexLayerSetInfo *info); // This sets mInfo and calls initialization functions - BOOL render(S32 x, S32 y, S32 width, S32 height); - void renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, bool forceClear = false); + BOOL render(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* bound_target = nullptr); + void renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* bound_target = nullptr, bool forceClear = false); BOOL isBodyRegion(const std::string& region) const; void applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components); @@ -282,7 +282,7 @@ protected: virtual S32 getCompositeOriginY() const = 0; virtual S32 getCompositeWidth() const = 0; virtual S32 getCompositeHeight() const = 0; - BOOL renderTexLayerSet(); + BOOL renderTexLayerSet(LLRenderTarget* bound_target); LLTexLayerSet* const mTexLayerSet; }; diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp index 5e283f7cd0..e1f41a9bd7 100644 --- a/indra/newview/lldynamictexture.cpp +++ b/indra/newview/lldynamictexture.cpp @@ -240,6 +240,7 @@ BOOL LLViewerDynamicTexture::updateAllInstances() gDepthDirty = TRUE; gGL.color4f(1,1,1,1); + dynamicTexture->setBoundTarget(use_fbo ? &gPipeline.mWaterDis : nullptr); dynamicTexture->preRender(); // Must be called outside of startRender() result = FALSE; if (dynamicTexture->render()) @@ -250,7 +251,7 @@ BOOL LLViewerDynamicTexture::updateAllInstances() } //gGL.flush(); LLVertexBuffer::unbind(); - + dynamicTexture->setBoundTarget(nullptr); dynamicTexture->postRender(result); } } diff --git a/indra/newview/lldynamictexture.h b/indra/newview/lldynamictexture.h index f3f57c9a6b..4bd74a8425 100644 --- a/indra/newview/lldynamictexture.h +++ b/indra/newview/lldynamictexture.h @@ -88,6 +88,9 @@ public: static BOOL updateAllInstances(); static void destroyGL() ; static void restoreGL() ; + + void setBoundTarget(LLRenderTarget* target) { mBoundTarget = target; } + protected: void generateGLTexture(); void generateGLTexture(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes = FALSE); @@ -97,6 +100,8 @@ protected: LLCoordGL mOrigin; LL_ALIGN_16(LLCamera mCamera); + LLRenderTarget* mBoundTarget; + typedef std::set instance_list_t; static instance_list_t sInstances[ LLViewerDynamicTexture::ORDER_COUNT ]; static S32 sNumRenders; diff --git a/indra/newview/llviewertexlayer.h b/indra/newview/llviewertexlayer.h index 027ae255ec..dec7f0ddfc 100644 --- a/indra/newview/llviewertexlayer.h +++ b/indra/newview/llviewertexlayer.h @@ -111,7 +111,7 @@ protected: // Pass these along for tex layer rendering. virtual void preRender(BOOL clear_depth) { preRenderTexLayerSet(); } virtual void postRender(BOOL success) { postRenderTexLayerSet(success); } - virtual BOOL render() { return renderTexLayerSet(); } + virtual BOOL render() { return renderTexLayerSet(mBoundTarget); } //-------------------------------------------------------------------- // Updates -- cgit v1.3 From f6eab050178336a553f52837b8e8a4cc0bf6bacb Mon Sep 17 00:00:00 2001 From: Graham Linden Date: Mon, 15 Jul 2019 16:02:10 -0700 Subject: Fix OSX compiler error from missing defaulted param and changed signature of renderAlphaMaskTextures. --- indra/llappearance/lltexlayer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llappearance/lltexlayer.cpp') diff --git a/indra/llappearance/lltexlayer.cpp b/indra/llappearance/lltexlayer.cpp index 9d294645db..c90b11ae71 100644 --- a/indra/llappearance/lltexlayer.cpp +++ b/indra/llappearance/lltexlayer.cpp @@ -432,7 +432,7 @@ BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height, LLRenderTarget* } } - renderAlphaMaskTextures(x, y, width, height, false); + renderAlphaMaskTextures(x, y, width, height, bound_target, false); stop_glerror(); } -- cgit v1.3 From 1529c16201d332ce7bbff5c3637737ca58277eb9 Mon Sep 17 00:00:00 2001 From: Graham Linden Date: Wed, 24 Jul 2019 10:53:04 -0700 Subject: SL-11610 Revert attempted fix for 10625. --- indra/llappearance/lltexlayer.cpp | 77 ++++++++++++-------------------------- indra/llappearance/lltexlayer.h | 24 ++++++------ indra/newview/lldynamictexture.cpp | 20 ++++------ indra/newview/lldynamictexture.h | 5 --- indra/newview/llviewerdisplay.cpp | 30 +++++++-------- indra/newview/llviewertexlayer.h | 2 +- indra/newview/pipeline.cpp | 4 -- indra/newview/pipeline.h | 2 - 8 files changed, 56 insertions(+), 108 deletions(-) (limited to 'indra/llappearance/lltexlayer.cpp') diff --git a/indra/llappearance/lltexlayer.cpp b/indra/llappearance/lltexlayer.cpp index c90b11ae71..8ae7c9aa9b 100644 --- a/indra/llappearance/lltexlayer.cpp +++ b/indra/llappearance/lltexlayer.cpp @@ -137,7 +137,7 @@ void LLTexLayerSetBuffer::postRenderTexLayerSet(BOOL success) popProjection(); } -BOOL LLTexLayerSetBuffer::renderTexLayerSet(LLRenderTarget* bound_target) +BOOL LLTexLayerSetBuffer::renderTexLayerSet() { // Default color mask for tex layer render gGL.setColorMask(true, true); @@ -161,7 +161,7 @@ BOOL LLTexLayerSetBuffer::renderTexLayerSet(LLRenderTarget* bound_target) // Composite the color data LLGLSUIDefault gls_ui; success &= mTexLayerSet->render( getCompositeOriginX(), getCompositeOriginY(), - getCompositeWidth(), getCompositeHeight(), bound_target ); + getCompositeWidth(), getCompositeHeight() ); gGL.flush(); midRenderTexLayerSet(success); @@ -375,7 +375,7 @@ void LLTexLayerSet::deleteCaches() } -BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height, LLRenderTarget* bound_target ) +BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height ) { BOOL success = TRUE; mIsVisible = TRUE; @@ -427,12 +427,12 @@ BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height, LLRenderTarget* if (layer->getRenderPass() == LLTexLayer::RP_COLOR) { gGL.flush(); - success &= layer->render(x, y, width, height, bound_target); + success &= layer->render(x, y, width, height); gGL.flush(); } } - renderAlphaMaskTextures(x, y, width, height, bound_target, false); + renderAlphaMaskTextures(x, y, width, height, false); stop_glerror(); } @@ -523,7 +523,7 @@ const LLTexLayerSetBuffer* LLTexLayerSet::getComposite() const } static LLTrace::BlockTimerStatHandle FTM_GATHER_MORPH_MASK_ALPHA("gatherMorphMaskAlpha"); -void LLTexLayerSet::gatherMorphMaskAlpha(U8 *data, S32 origin_x, S32 origin_y, S32 width, S32 height, LLRenderTarget* bound_target) +void LLTexLayerSet::gatherMorphMaskAlpha(U8 *data, S32 origin_x, S32 origin_y, S32 width, S32 height) { LL_RECORD_BLOCK_TIME(FTM_GATHER_MORPH_MASK_ALPHA); memset(data, 255, width * height); @@ -531,15 +531,15 @@ void LLTexLayerSet::gatherMorphMaskAlpha(U8 *data, S32 origin_x, S32 origin_y, S for( layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ ) { LLTexLayerInterface* layer = *iter; - layer->gatherAlphaMasks(data, origin_x, origin_y, width, height, bound_target); + layer->gatherAlphaMasks(data, origin_x, origin_y, width, height); } // Set alpha back to that of our alpha masks. - renderAlphaMaskTextures(origin_x, origin_y, width, height, bound_target, true); + renderAlphaMaskTextures(origin_x, origin_y, width, height, true); } static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_MASK_TEXTURES("renderAlphaMaskTextures"); -void LLTexLayerSet::renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* bound_target, bool forceClear) +void LLTexLayerSet::renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, bool forceClear) { LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_MASK_TEXTURES); const LLTexLayerSetInfo *info = getInfo(); @@ -1124,7 +1124,7 @@ void LLTexLayer::calculateTexLayerColor(const param_color_list_t ¶m_list, LL } } -BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* bound_target) +BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height) { LLGLEnable color_mat(GL_COLOR_MATERIAL); // *TODO: Is this correct? @@ -1185,7 +1185,7 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* bou }//*/ const bool force_render = true; - renderMorphMasks(x, y, width, height, net_color, bound_target, force_render); + renderMorphMasks(x, y, width, height, net_color, force_render); alpha_mask_specified = TRUE; gGL.flush(); gGL.blendFunc(LLRender::BF_DEST_ALPHA, LLRender::BF_ONE_MINUS_DEST_ALPHA); @@ -1428,13 +1428,13 @@ BOOL LLTexLayer::blendAlphaTexture(S32 x, S32 y, S32 width, S32 height) return success; } -/*virtual*/ void LLTexLayer::gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height, LLRenderTarget* bound_target) +/*virtual*/ void LLTexLayer::gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height) { - addAlphaMask(data, originX, originY, width, height, bound_target); + addAlphaMask(data, originX, originY, width, height); } static LLTrace::BlockTimerStatHandle FTM_RENDER_MORPH_MASKS("renderMorphMasks"); -void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLColor4 &layer_color, LLRenderTarget* bound_target, bool force_render) +void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLColor4 &layer_color, bool force_render) { if (!force_render && !hasMorph()) { @@ -1586,42 +1586,11 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC alpha_data = (U8*)ll_aligned_malloc_32(mem_size); - bool skip_readback = LLRender::sNsightDebugSupport; // nSight doesn't support use of glReadPixels + bool skip_readback = LLRender::sNsightDebugSupport || gGLManager.mIsIntel; // nSight doesn't support use of glReadPixels if (!skip_readback) { - if (gGLManager.mIsIntel) - { // work-around for broken intel drivers which cannot do glReadPixels on an RGBA FBO - // returning only the alpha portion without locking up downstream - U8* temp = (U8*)ll_aligned_malloc_32(mem_size << 2); // allocate same size, but RGBA - - if (bound_target) - { - gGL.getTexUnit(0)->bind(bound_target); - } - else - { - gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, 0); - } - - glGetTexImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGBA, GL_UNSIGNED_BYTE, temp); - - U8* alpha_cursor = alpha_data; - U8* pixel = temp; - for (int i = 0; i < pixels; i++) - { - *alpha_cursor++ = pixel[3]; - pixel += 4; - } - - gGL.getTexUnit(0)->disable(); - - ll_aligned_free_32(temp); - } - else - { // platforms with working drivers... - glReadPixels(x, y, width, height, GL_ALPHA, GL_UNSIGNED_BYTE, alpha_data); - } + glReadPixels(x, y, width, height, GL_ALPHA, GL_UNSIGNED_BYTE, alpha_data); } else { @@ -1631,7 +1600,7 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC mAlphaCache[cache_index] = alpha_data; } - + getTexLayerSet()->getAvatarAppearance()->dirtyMesh(); mMorphMasksValid = TRUE; @@ -1640,7 +1609,7 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC } static LLTrace::BlockTimerStatHandle FTM_ADD_ALPHA_MASK("addAlphaMask"); -void LLTexLayer::addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32 height, LLRenderTarget* bound_target) +void LLTexLayer::addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32 height) { LL_RECORD_BLOCK_TIME(FTM_ADD_ALPHA_MASK); S32 size = width * height; @@ -1652,7 +1621,7 @@ void LLTexLayer::addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32 // TODO: eliminate need for layer morph mask valid flag invalidateMorphMasks(); const bool force_render = false; - renderMorphMasks(originX, originY, width, height, net_color, bound_target, force_render); + renderMorphMasks(originX, originY, width, height, net_color, force_render); alphaData = getAlphaData(); } if (alphaData) @@ -1786,7 +1755,7 @@ LLTexLayer* LLTexLayerTemplate::getLayer(U32 i) const return layer; } -/*virtual*/ BOOL LLTexLayerTemplate::render(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* bound_target) +/*virtual*/ BOOL LLTexLayerTemplate::render(S32 x, S32 y, S32 width, S32 height) { if(!mInfo) { @@ -1813,7 +1782,7 @@ LLTexLayer* LLTexLayerTemplate::getLayer(U32 i) const { wearable->writeToAvatar(mAvatarAppearance); layer->setLTO(lto); - success &= layer->render(x, y, width, height, bound_target); + success &= layer->render(x,y,width,height); } } @@ -1835,14 +1804,14 @@ LLTexLayer* LLTexLayerTemplate::getLayer(U32 i) const return success; } -/*virtual*/ void LLTexLayerTemplate::gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height, LLRenderTarget* bound_target) +/*virtual*/ void LLTexLayerTemplate::gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height) { U32 num_wearables = updateWearableCache(); U32 i = num_wearables - 1; // For rendering morph masks, we only want to use the top wearable LLTexLayer *layer = getLayer(i); if (layer) { - layer->addAlphaMask(data, originX, originY, width, height, bound_target); + layer->addAlphaMask(data, originX, originY, width, height); } } diff --git a/indra/llappearance/lltexlayer.h b/indra/llappearance/lltexlayer.h index 6a5040cf0b..9318b23fd1 100644 --- a/indra/llappearance/lltexlayer.h +++ b/indra/llappearance/lltexlayer.h @@ -65,7 +65,7 @@ public: LLTexLayerInterface(const LLTexLayerInterface &layer, LLWearable *wearable); virtual ~LLTexLayerInterface() {} - virtual BOOL render(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* bound_target) = 0; + virtual BOOL render(S32 x, S32 y, S32 width, S32 height) = 0; virtual void deleteCaches() = 0; virtual BOOL blendAlphaTexture(S32 x, S32 y, S32 width, S32 height) = 0; virtual BOOL isInvisibleAlphaMask() const = 0; @@ -85,7 +85,7 @@ public: BOOL isMorphValid() const { return mMorphMasksValid; } void requestUpdate(); - virtual void gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height, LLRenderTarget* bound_target) = 0; + virtual void gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height) = 0; BOOL hasAlphaParams() const { return !mParamAlphaList.empty(); } ERenderPass getRenderPass() const; @@ -121,10 +121,10 @@ public: LLTexLayerTemplate(LLTexLayerSet* const layer_set, LLAvatarAppearance* const appearance); LLTexLayerTemplate(const LLTexLayerTemplate &layer); /*virtual*/ ~LLTexLayerTemplate(); - /*virtual*/ BOOL render(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* bound_target); + /*virtual*/ BOOL render(S32 x, S32 y, S32 width, S32 height); /*virtual*/ BOOL setInfo(const LLTexLayerInfo *info, LLWearable* wearable); // This sets mInfo and calls initialization functions /*virtual*/ BOOL blendAlphaTexture(S32 x, S32 y, S32 width, S32 height); // Multiplies a single alpha texture against the frame buffer - /*virtual*/ void gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height, LLRenderTarget* bound_target); + /*virtual*/ void gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height); /*virtual*/ void setHasMorph(BOOL newval); /*virtual*/ void deleteCaches(); /*virtual*/ BOOL isInvisibleAlphaMask() const; @@ -152,16 +152,16 @@ public: /*virtual*/ ~LLTexLayer(); /*virtual*/ BOOL setInfo(const LLTexLayerInfo *info, LLWearable* wearable); // This sets mInfo and calls initialization functions - /*virtual*/ BOOL render(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* bound_target); + /*virtual*/ BOOL render(S32 x, S32 y, S32 width, S32 height); /*virtual*/ void deleteCaches(); const U8* getAlphaData() const; BOOL findNetColor(LLColor4* color) const; /*virtual*/ BOOL blendAlphaTexture(S32 x, S32 y, S32 width, S32 height); // Multiplies a single alpha texture against the frame buffer - /*virtual*/ void gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height, LLRenderTarget* bound_target); - void renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLColor4 &layer_color, LLRenderTarget* bound_target, bool force_render); - void addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32 height, LLRenderTarget* bound_target); + /*virtual*/ void gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height); + void renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLColor4 &layer_color, bool force_render); + void addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32 height); /*virtual*/ BOOL isInvisibleAlphaMask() const; void setLTO(LLLocalTextureObject *lto) { mLocalTextureObject = lto; } @@ -194,13 +194,13 @@ public: const LLTexLayerSetBuffer* getComposite() const; // Do not create one if it doesn't exist. virtual void createComposite() = 0; void destroyComposite(); - void gatherMorphMaskAlpha(U8 *data, S32 origin_x, S32 origin_y, S32 width, S32 height, LLRenderTarget* bound_target); + void gatherMorphMaskAlpha(U8 *data, S32 origin_x, S32 origin_y, S32 width, S32 height); const LLTexLayerSetInfo* getInfo() const { return mInfo; } BOOL setInfo(const LLTexLayerSetInfo *info); // This sets mInfo and calls initialization functions - BOOL render(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* bound_target = nullptr); - void renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* bound_target = nullptr, bool forceClear = false); + BOOL render(S32 x, S32 y, S32 width, S32 height); + void renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, bool forceClear = false); BOOL isBodyRegion(const std::string& region) const; void applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components); @@ -282,7 +282,7 @@ protected: virtual S32 getCompositeOriginY() const = 0; virtual S32 getCompositeWidth() const = 0; virtual S32 getCompositeHeight() const = 0; - BOOL renderTexLayerSet(LLRenderTarget* bound_target); + BOOL renderTexLayerSet(); LLTexLayerSet* const mTexLayerSet; }; diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp index 13d539b55f..fa9a0712fa 100644 --- a/indra/newview/lldynamictexture.cpp +++ b/indra/newview/lldynamictexture.cpp @@ -129,7 +129,7 @@ void LLViewerDynamicTexture::preRender(BOOL clear_depth) llassert(mFullHeight <= 512); llassert(mFullWidth <= 512); - if (gGLManager.mHasFramebufferObject && gPipeline.mBake.isComplete() && !gGLManager.mIsATI) + if (gGLManager.mHasFramebufferObject && gPipeline.mWaterDis.isComplete() && !gGLManager.mIsATI) { //using offscreen render target, just use the bottom left corner mOrigin.set(0, 0); } @@ -213,15 +213,14 @@ BOOL LLViewerDynamicTexture::updateAllInstances() sNumRenders = 0; if (gGLManager.mIsDisabled || LLPipeline::sMemAllocationThrottled) { - return FALSE; + return TRUE; } - bool use_fbo = gGLManager.mHasFramebufferObject && gPipeline.mBake.isComplete() && !gGLManager.mIsATI; + bool use_fbo = gGLManager.mHasFramebufferObject && gPipeline.mWaterDis.isComplete() && !gGLManager.mIsATI; if (use_fbo) { - gPipeline.mBake.bindTarget(); - gPipeline.mBake.clear(); + gPipeline.mWaterDis.bindTarget(); } LLGLSLShader::bindNoShader(); @@ -241,7 +240,6 @@ BOOL LLViewerDynamicTexture::updateAllInstances() gDepthDirty = TRUE; gGL.color4f(1,1,1,1); - dynamicTexture->setBoundTarget(use_fbo ? &gPipeline.mBake : nullptr); dynamicTexture->preRender(); // Must be called outside of startRender() result = FALSE; if (dynamicTexture->render()) @@ -250,23 +248,19 @@ BOOL LLViewerDynamicTexture::updateAllInstances() result = TRUE; sNumRenders++; } - //gGL.flush(); + gGL.flush(); LLVertexBuffer::unbind(); - dynamicTexture->setBoundTarget(nullptr); + dynamicTexture->postRender(result); } } } - glFinish(); - if (use_fbo) { - gPipeline.mBake.flush(); + gPipeline.mWaterDis.flush(); } - gGL.flush(); - return ret; } diff --git a/indra/newview/lldynamictexture.h b/indra/newview/lldynamictexture.h index 4bd74a8425..f3f57c9a6b 100644 --- a/indra/newview/lldynamictexture.h +++ b/indra/newview/lldynamictexture.h @@ -88,9 +88,6 @@ public: static BOOL updateAllInstances(); static void destroyGL() ; static void restoreGL() ; - - void setBoundTarget(LLRenderTarget* target) { mBoundTarget = target; } - protected: void generateGLTexture(); void generateGLTexture(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes = FALSE); @@ -100,8 +97,6 @@ protected: LLCoordGL mOrigin; LL_ALIGN_16(LLCamera mCamera); - LLRenderTarget* mBoundTarget; - typedef std::set instance_list_t; static instance_list_t sInstances[ LLViewerDynamicTexture::ORDER_COUNT ]; static S32 sNumRenders; diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 0eafce7e1c..b78937e3b0 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -592,6 +592,18 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) // Actually push all of our triangles to the screen. // + // do render-to-texture stuff here + if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_DYNAMIC_TEXTURES)) + { + LLAppViewer::instance()->pingMainloopTimeout("Display:DynamicTextures"); + LL_RECORD_BLOCK_TIME(FTM_UPDATE_DYNAMIC_TEXTURES); + if (LLViewerDynamicTexture::updateAllInstances()) + { + gGL.setColorMask(true, true); + glClear(GL_DEPTH_BUFFER_BIT); + } + } + gViewerWindow->setup3DViewport(); gPipeline.resetFrameStats(); // Reset per-frame statistics. @@ -1022,26 +1034,10 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) if (!for_snapshot) { render_ui(); - } - - // do render-to-texture stuff here - if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_DYNAMIC_TEXTURES)) - { - LLAppViewer::instance()->pingMainloopTimeout("Display:DynamicTextures"); - LL_RECORD_BLOCK_TIME(FTM_UPDATE_DYNAMIC_TEXTURES); - if (LLViewerDynamicTexture::updateAllInstances()) - { - gGL.setColorMask(true, true); - glClear(GL_DEPTH_BUFFER_BIT); - } - } - - LLAppViewer::instance()->pingMainloopTimeout("Display:RenderUI"); - if (!for_snapshot) - { swap(); } + LLSpatialGroup::sNoDelete = FALSE; gPipeline.clearReferences(); diff --git a/indra/newview/llviewertexlayer.h b/indra/newview/llviewertexlayer.h index dec7f0ddfc..027ae255ec 100644 --- a/indra/newview/llviewertexlayer.h +++ b/indra/newview/llviewertexlayer.h @@ -111,7 +111,7 @@ protected: // Pass these along for tex layer rendering. virtual void preRender(BOOL clear_depth) { preRenderTexLayerSet(); } virtual void postRender(BOOL success) { postRenderTexLayerSet(success); } - virtual BOOL render() { return renderTexLayerSet(mBoundTarget); } + virtual BOOL render() { return renderTexLayerSet(); } //-------------------------------------------------------------------- // Updates diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 448b65272b..fc7408a8e5 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -1162,7 +1162,6 @@ void LLPipeline::releaseGLBuffers() mWaterRef.release(); mWaterDis.release(); - mBake.release(); mHighlight.release(); for (U32 i = 0; i < 3; i++) @@ -1226,9 +1225,6 @@ void LLPipeline::createGLBuffers() mWaterDis.allocate(res,res,GL_RGBA,TRUE,FALSE,LLTexUnit::TT_TEXTURE); } - // Use FBO for bake tex - mBake.allocate(512, 512, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_TEXTURE, true); - mHighlight.allocate(256,256,GL_RGBA, FALSE, FALSE); stop_glerror(); diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index cc9ec06f80..b0c40d145b 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -650,8 +650,6 @@ public: //water distortion texture (refraction) LLRenderTarget mWaterDis; - LLRenderTarget mBake; - //texture for making the glow LLRenderTarget mGlow[3]; -- cgit v1.3 From 41ede77744489c2a2d32849ea457bcbea516a588 Mon Sep 17 00:00:00 2001 From: Graham Linden Date: Wed, 24 Jul 2019 12:52:24 -0700 Subject: SL-10625 --- indra/llappearance/lltexlayer.cpp | 77 ++++++++++++++++++++++++++------------ indra/llappearance/lltexlayer.h | 24 ++++++------ indra/newview/lldynamictexture.cpp | 14 ++++--- indra/newview/lldynamictexture.h | 5 +++ indra/newview/llviewertexlayer.h | 2 +- indra/newview/pipeline.cpp | 6 ++- indra/newview/pipeline.h | 2 + 7 files changed, 88 insertions(+), 42 deletions(-) (limited to 'indra/llappearance/lltexlayer.cpp') diff --git a/indra/llappearance/lltexlayer.cpp b/indra/llappearance/lltexlayer.cpp index 8ae7c9aa9b..c90b11ae71 100644 --- a/indra/llappearance/lltexlayer.cpp +++ b/indra/llappearance/lltexlayer.cpp @@ -137,7 +137,7 @@ void LLTexLayerSetBuffer::postRenderTexLayerSet(BOOL success) popProjection(); } -BOOL LLTexLayerSetBuffer::renderTexLayerSet() +BOOL LLTexLayerSetBuffer::renderTexLayerSet(LLRenderTarget* bound_target) { // Default color mask for tex layer render gGL.setColorMask(true, true); @@ -161,7 +161,7 @@ BOOL LLTexLayerSetBuffer::renderTexLayerSet() // Composite the color data LLGLSUIDefault gls_ui; success &= mTexLayerSet->render( getCompositeOriginX(), getCompositeOriginY(), - getCompositeWidth(), getCompositeHeight() ); + getCompositeWidth(), getCompositeHeight(), bound_target ); gGL.flush(); midRenderTexLayerSet(success); @@ -375,7 +375,7 @@ void LLTexLayerSet::deleteCaches() } -BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height ) +BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height, LLRenderTarget* bound_target ) { BOOL success = TRUE; mIsVisible = TRUE; @@ -427,12 +427,12 @@ BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height ) if (layer->getRenderPass() == LLTexLayer::RP_COLOR) { gGL.flush(); - success &= layer->render(x, y, width, height); + success &= layer->render(x, y, width, height, bound_target); gGL.flush(); } } - renderAlphaMaskTextures(x, y, width, height, false); + renderAlphaMaskTextures(x, y, width, height, bound_target, false); stop_glerror(); } @@ -523,7 +523,7 @@ const LLTexLayerSetBuffer* LLTexLayerSet::getComposite() const } static LLTrace::BlockTimerStatHandle FTM_GATHER_MORPH_MASK_ALPHA("gatherMorphMaskAlpha"); -void LLTexLayerSet::gatherMorphMaskAlpha(U8 *data, S32 origin_x, S32 origin_y, S32 width, S32 height) +void LLTexLayerSet::gatherMorphMaskAlpha(U8 *data, S32 origin_x, S32 origin_y, S32 width, S32 height, LLRenderTarget* bound_target) { LL_RECORD_BLOCK_TIME(FTM_GATHER_MORPH_MASK_ALPHA); memset(data, 255, width * height); @@ -531,15 +531,15 @@ void LLTexLayerSet::gatherMorphMaskAlpha(U8 *data, S32 origin_x, S32 origin_y, S for( layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ ) { LLTexLayerInterface* layer = *iter; - layer->gatherAlphaMasks(data, origin_x, origin_y, width, height); + layer->gatherAlphaMasks(data, origin_x, origin_y, width, height, bound_target); } // Set alpha back to that of our alpha masks. - renderAlphaMaskTextures(origin_x, origin_y, width, height, true); + renderAlphaMaskTextures(origin_x, origin_y, width, height, bound_target, true); } static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_MASK_TEXTURES("renderAlphaMaskTextures"); -void LLTexLayerSet::renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, bool forceClear) +void LLTexLayerSet::renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* bound_target, bool forceClear) { LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_MASK_TEXTURES); const LLTexLayerSetInfo *info = getInfo(); @@ -1124,7 +1124,7 @@ void LLTexLayer::calculateTexLayerColor(const param_color_list_t ¶m_list, LL } } -BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height) +BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* bound_target) { LLGLEnable color_mat(GL_COLOR_MATERIAL); // *TODO: Is this correct? @@ -1185,7 +1185,7 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height) }//*/ const bool force_render = true; - renderMorphMasks(x, y, width, height, net_color, force_render); + renderMorphMasks(x, y, width, height, net_color, bound_target, force_render); alpha_mask_specified = TRUE; gGL.flush(); gGL.blendFunc(LLRender::BF_DEST_ALPHA, LLRender::BF_ONE_MINUS_DEST_ALPHA); @@ -1428,13 +1428,13 @@ BOOL LLTexLayer::blendAlphaTexture(S32 x, S32 y, S32 width, S32 height) return success; } -/*virtual*/ void LLTexLayer::gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height) +/*virtual*/ void LLTexLayer::gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height, LLRenderTarget* bound_target) { - addAlphaMask(data, originX, originY, width, height); + addAlphaMask(data, originX, originY, width, height, bound_target); } static LLTrace::BlockTimerStatHandle FTM_RENDER_MORPH_MASKS("renderMorphMasks"); -void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLColor4 &layer_color, bool force_render) +void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLColor4 &layer_color, LLRenderTarget* bound_target, bool force_render) { if (!force_render && !hasMorph()) { @@ -1586,11 +1586,42 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC alpha_data = (U8*)ll_aligned_malloc_32(mem_size); - bool skip_readback = LLRender::sNsightDebugSupport || gGLManager.mIsIntel; // nSight doesn't support use of glReadPixels + bool skip_readback = LLRender::sNsightDebugSupport; // nSight doesn't support use of glReadPixels if (!skip_readback) { - glReadPixels(x, y, width, height, GL_ALPHA, GL_UNSIGNED_BYTE, alpha_data); + if (gGLManager.mIsIntel) + { // work-around for broken intel drivers which cannot do glReadPixels on an RGBA FBO + // returning only the alpha portion without locking up downstream + U8* temp = (U8*)ll_aligned_malloc_32(mem_size << 2); // allocate same size, but RGBA + + if (bound_target) + { + gGL.getTexUnit(0)->bind(bound_target); + } + else + { + gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, 0); + } + + glGetTexImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGBA, GL_UNSIGNED_BYTE, temp); + + U8* alpha_cursor = alpha_data; + U8* pixel = temp; + for (int i = 0; i < pixels; i++) + { + *alpha_cursor++ = pixel[3]; + pixel += 4; + } + + gGL.getTexUnit(0)->disable(); + + ll_aligned_free_32(temp); + } + else + { // platforms with working drivers... + glReadPixels(x, y, width, height, GL_ALPHA, GL_UNSIGNED_BYTE, alpha_data); + } } else { @@ -1600,7 +1631,7 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC mAlphaCache[cache_index] = alpha_data; } - + getTexLayerSet()->getAvatarAppearance()->dirtyMesh(); mMorphMasksValid = TRUE; @@ -1609,7 +1640,7 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC } static LLTrace::BlockTimerStatHandle FTM_ADD_ALPHA_MASK("addAlphaMask"); -void LLTexLayer::addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32 height) +void LLTexLayer::addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32 height, LLRenderTarget* bound_target) { LL_RECORD_BLOCK_TIME(FTM_ADD_ALPHA_MASK); S32 size = width * height; @@ -1621,7 +1652,7 @@ void LLTexLayer::addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32 // TODO: eliminate need for layer morph mask valid flag invalidateMorphMasks(); const bool force_render = false; - renderMorphMasks(originX, originY, width, height, net_color, force_render); + renderMorphMasks(originX, originY, width, height, net_color, bound_target, force_render); alphaData = getAlphaData(); } if (alphaData) @@ -1755,7 +1786,7 @@ LLTexLayer* LLTexLayerTemplate::getLayer(U32 i) const return layer; } -/*virtual*/ BOOL LLTexLayerTemplate::render(S32 x, S32 y, S32 width, S32 height) +/*virtual*/ BOOL LLTexLayerTemplate::render(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* bound_target) { if(!mInfo) { @@ -1782,7 +1813,7 @@ LLTexLayer* LLTexLayerTemplate::getLayer(U32 i) const { wearable->writeToAvatar(mAvatarAppearance); layer->setLTO(lto); - success &= layer->render(x,y,width,height); + success &= layer->render(x, y, width, height, bound_target); } } @@ -1804,14 +1835,14 @@ LLTexLayer* LLTexLayerTemplate::getLayer(U32 i) const return success; } -/*virtual*/ void LLTexLayerTemplate::gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height) +/*virtual*/ void LLTexLayerTemplate::gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height, LLRenderTarget* bound_target) { U32 num_wearables = updateWearableCache(); U32 i = num_wearables - 1; // For rendering morph masks, we only want to use the top wearable LLTexLayer *layer = getLayer(i); if (layer) { - layer->addAlphaMask(data, originX, originY, width, height); + layer->addAlphaMask(data, originX, originY, width, height, bound_target); } } diff --git a/indra/llappearance/lltexlayer.h b/indra/llappearance/lltexlayer.h index 9318b23fd1..6a5040cf0b 100644 --- a/indra/llappearance/lltexlayer.h +++ b/indra/llappearance/lltexlayer.h @@ -65,7 +65,7 @@ public: LLTexLayerInterface(const LLTexLayerInterface &layer, LLWearable *wearable); virtual ~LLTexLayerInterface() {} - virtual BOOL render(S32 x, S32 y, S32 width, S32 height) = 0; + virtual BOOL render(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* bound_target) = 0; virtual void deleteCaches() = 0; virtual BOOL blendAlphaTexture(S32 x, S32 y, S32 width, S32 height) = 0; virtual BOOL isInvisibleAlphaMask() const = 0; @@ -85,7 +85,7 @@ public: BOOL isMorphValid() const { return mMorphMasksValid; } void requestUpdate(); - virtual void gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height) = 0; + virtual void gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height, LLRenderTarget* bound_target) = 0; BOOL hasAlphaParams() const { return !mParamAlphaList.empty(); } ERenderPass getRenderPass() const; @@ -121,10 +121,10 @@ public: LLTexLayerTemplate(LLTexLayerSet* const layer_set, LLAvatarAppearance* const appearance); LLTexLayerTemplate(const LLTexLayerTemplate &layer); /*virtual*/ ~LLTexLayerTemplate(); - /*virtual*/ BOOL render(S32 x, S32 y, S32 width, S32 height); + /*virtual*/ BOOL render(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* bound_target); /*virtual*/ BOOL setInfo(const LLTexLayerInfo *info, LLWearable* wearable); // This sets mInfo and calls initialization functions /*virtual*/ BOOL blendAlphaTexture(S32 x, S32 y, S32 width, S32 height); // Multiplies a single alpha texture against the frame buffer - /*virtual*/ void gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height); + /*virtual*/ void gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height, LLRenderTarget* bound_target); /*virtual*/ void setHasMorph(BOOL newval); /*virtual*/ void deleteCaches(); /*virtual*/ BOOL isInvisibleAlphaMask() const; @@ -152,16 +152,16 @@ public: /*virtual*/ ~LLTexLayer(); /*virtual*/ BOOL setInfo(const LLTexLayerInfo *info, LLWearable* wearable); // This sets mInfo and calls initialization functions - /*virtual*/ BOOL render(S32 x, S32 y, S32 width, S32 height); + /*virtual*/ BOOL render(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* bound_target); /*virtual*/ void deleteCaches(); const U8* getAlphaData() const; BOOL findNetColor(LLColor4* color) const; /*virtual*/ BOOL blendAlphaTexture(S32 x, S32 y, S32 width, S32 height); // Multiplies a single alpha texture against the frame buffer - /*virtual*/ void gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height); - void renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLColor4 &layer_color, bool force_render); - void addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32 height); + /*virtual*/ void gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height, LLRenderTarget* bound_target); + void renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLColor4 &layer_color, LLRenderTarget* bound_target, bool force_render); + void addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32 height, LLRenderTarget* bound_target); /*virtual*/ BOOL isInvisibleAlphaMask() const; void setLTO(LLLocalTextureObject *lto) { mLocalTextureObject = lto; } @@ -194,13 +194,13 @@ public: const LLTexLayerSetBuffer* getComposite() const; // Do not create one if it doesn't exist. virtual void createComposite() = 0; void destroyComposite(); - void gatherMorphMaskAlpha(U8 *data, S32 origin_x, S32 origin_y, S32 width, S32 height); + void gatherMorphMaskAlpha(U8 *data, S32 origin_x, S32 origin_y, S32 width, S32 height, LLRenderTarget* bound_target); const LLTexLayerSetInfo* getInfo() const { return mInfo; } BOOL setInfo(const LLTexLayerSetInfo *info); // This sets mInfo and calls initialization functions - BOOL render(S32 x, S32 y, S32 width, S32 height); - void renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, bool forceClear = false); + BOOL render(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* bound_target = nullptr); + void renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* bound_target = nullptr, bool forceClear = false); BOOL isBodyRegion(const std::string& region) const; void applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components); @@ -282,7 +282,7 @@ protected: virtual S32 getCompositeOriginY() const = 0; virtual S32 getCompositeWidth() const = 0; virtual S32 getCompositeHeight() const = 0; - BOOL renderTexLayerSet(); + BOOL renderTexLayerSet(LLRenderTarget* bound_target); LLTexLayerSet* const mTexLayerSet; }; diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp index fa9a0712fa..f9b4df679b 100644 --- a/indra/newview/lldynamictexture.cpp +++ b/indra/newview/lldynamictexture.cpp @@ -129,7 +129,7 @@ void LLViewerDynamicTexture::preRender(BOOL clear_depth) llassert(mFullHeight <= 512); llassert(mFullWidth <= 512); - if (gGLManager.mHasFramebufferObject && gPipeline.mWaterDis.isComplete() && !gGLManager.mIsATI) + if (gGLManager.mHasFramebufferObject && gPipeline.mBake.isComplete()) { //using offscreen render target, just use the bottom left corner mOrigin.set(0, 0); } @@ -216,11 +216,12 @@ BOOL LLViewerDynamicTexture::updateAllInstances() return TRUE; } - bool use_fbo = gGLManager.mHasFramebufferObject && gPipeline.mWaterDis.isComplete() && !gGLManager.mIsATI; + bool use_fbo = gGLManager.mHasFramebufferObject && gPipeline.mBake.isComplete(); if (use_fbo) { - gPipeline.mWaterDis.bindTarget(); + gPipeline.mBake.bindTarget(); + gPipeline.mBake.clear(); } LLGLSLShader::bindNoShader(); @@ -240,6 +241,7 @@ BOOL LLViewerDynamicTexture::updateAllInstances() gDepthDirty = TRUE; gGL.color4f(1,1,1,1); + dynamicTexture->setBoundTarget(use_fbo ? &gPipeline.mBake : nullptr); dynamicTexture->preRender(); // Must be called outside of startRender() result = FALSE; if (dynamicTexture->render()) @@ -250,7 +252,7 @@ BOOL LLViewerDynamicTexture::updateAllInstances() } gGL.flush(); LLVertexBuffer::unbind(); - + dynamicTexture->setBoundTarget(nullptr); dynamicTexture->postRender(result); } } @@ -258,9 +260,11 @@ BOOL LLViewerDynamicTexture::updateAllInstances() if (use_fbo) { - gPipeline.mWaterDis.flush(); + gPipeline.mBake.flush(); } + gGL.flush(); + return ret; } diff --git a/indra/newview/lldynamictexture.h b/indra/newview/lldynamictexture.h index f3f57c9a6b..4bd74a8425 100644 --- a/indra/newview/lldynamictexture.h +++ b/indra/newview/lldynamictexture.h @@ -88,6 +88,9 @@ public: static BOOL updateAllInstances(); static void destroyGL() ; static void restoreGL() ; + + void setBoundTarget(LLRenderTarget* target) { mBoundTarget = target; } + protected: void generateGLTexture(); void generateGLTexture(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes = FALSE); @@ -97,6 +100,8 @@ protected: LLCoordGL mOrigin; LL_ALIGN_16(LLCamera mCamera); + LLRenderTarget* mBoundTarget; + typedef std::set instance_list_t; static instance_list_t sInstances[ LLViewerDynamicTexture::ORDER_COUNT ]; static S32 sNumRenders; diff --git a/indra/newview/llviewertexlayer.h b/indra/newview/llviewertexlayer.h index 027ae255ec..dec7f0ddfc 100644 --- a/indra/newview/llviewertexlayer.h +++ b/indra/newview/llviewertexlayer.h @@ -111,7 +111,7 @@ protected: // Pass these along for tex layer rendering. virtual void preRender(BOOL clear_depth) { preRenderTexLayerSet(); } virtual void postRender(BOOL success) { postRenderTexLayerSet(success); } - virtual BOOL render() { return renderTexLayerSet(); } + virtual BOOL render() { return renderTexLayerSet(mBoundTarget); } //-------------------------------------------------------------------- // Updates diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index ef88d43cc4..448b65272b 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -1162,6 +1162,7 @@ void LLPipeline::releaseGLBuffers() mWaterRef.release(); mWaterDis.release(); + mBake.release(); mHighlight.release(); for (U32 i = 0; i < 3; i++) @@ -1225,6 +1226,9 @@ void LLPipeline::createGLBuffers() mWaterDis.allocate(res,res,GL_RGBA,TRUE,FALSE,LLTexUnit::TT_TEXTURE); } + // Use FBO for bake tex + mBake.allocate(512, 512, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_TEXTURE, true); + mHighlight.allocate(256,256,GL_RGBA, FALSE, FALSE); stop_glerror(); @@ -1395,7 +1399,7 @@ bool LLPipeline::canUseVertexShaders() bool LLPipeline::canUseWindLightShaders() const { return (!LLPipeline::sDisableShaders && - /*gWLSkyProgram.mProgramObject != 0 &&*/ + gWLSkyProgram.mProgramObject != 0 && LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1); } diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index b0c40d145b..cc9ec06f80 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -650,6 +650,8 @@ public: //water distortion texture (refraction) LLRenderTarget mWaterDis; + LLRenderTarget mBake; + //texture for making the glow LLRenderTarget mGlow[3]; -- cgit v1.3