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.2.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/lltexlayer.cpp | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) (limited to 'indra/llappearance/lltexlayer.cpp') 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(); -- cgit v1.2.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 +++++--- 1 file changed, 5 insertions(+), 3 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) { -- cgit v1.2.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 +++++---- 1 file changed, 5 insertions(+), 4 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) { -- cgit v1.2.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.2.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.2.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.2.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 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 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 { -- cgit v1.2.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 +++--- 1 file changed, 3 insertions(+), 3 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(); -- cgit v1.2.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 ++++++++++++++++++++++++++++----------- 1 file changed, 52 insertions(+), 21 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); } } -- cgit v1.2.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.2.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 ++++++++++++--------------------------- 1 file changed, 23 insertions(+), 54 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); } } -- cgit v1.2.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 +++++++++++++++++++++++++++------------ 1 file changed, 54 insertions(+), 23 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); } } -- cgit v1.2.3