From ab87978cbc71cd4c83648627998055a010700f05 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 27 Jun 2024 13:12:43 -0500 Subject: 1836 dont store texture in system memory unless absolutely necessary (#1843) * #1836 Texture memory usage overhaul. Much decrufting - don't keep a copy of textures in system memory - use GPU to downrez textures instead of reloading from cache - use GPU to generate brightness/darkness bumpmaps --- indra/llrender/llgltexture.cpp | 21 ---- indra/llrender/llgltexture.h | 6 +- indra/llrender/llimagegl.cpp | 260 ++++++++++++++--------------------------- indra/llrender/llimagegl.h | 35 +++--- 4 files changed, 109 insertions(+), 213 deletions(-) (limited to 'indra/llrender') diff --git a/indra/llrender/llgltexture.cpp b/indra/llrender/llgltexture.cpp index e614f45986..4dcca5a726 100644 --- a/indra/llrender/llgltexture.cpp +++ b/indra/llrender/llgltexture.cpp @@ -351,20 +351,6 @@ void LLGLTexture::forceUpdateBindStats(void) const return mGLTexturep->forceUpdateBindStats() ; } -U32 LLGLTexture::getTexelsInAtlas() const -{ - llassert(mGLTexturep.notNull()) ; - - return mGLTexturep->getTexelsInAtlas() ; -} - -U32 LLGLTexture::getTexelsInGLTexture() const -{ - llassert(mGLTexturep.notNull()) ; - - return mGLTexturep->getTexelsInGLTexture() ; -} - bool LLGLTexture::isGLTextureCreated() const { llassert(mGLTexturep.notNull()) ; @@ -372,13 +358,6 @@ bool LLGLTexture::isGLTextureCreated() const return mGLTexturep->isGLTextureCreated() ; } -S32 LLGLTexture::getDiscardLevelInAtlas() const -{ - llassert(mGLTexturep.notNull()) ; - - return mGLTexturep->getDiscardLevelInAtlas() ; -} - void LLGLTexture::destroyGLTexture() { if(mGLTexturep.notNull() && mGLTexturep->getHasGLTexture()) diff --git a/indra/llrender/llgltexture.h b/indra/llrender/llgltexture.h index 0901243f8f..a7de20dc5c 100644 --- a/indra/llrender/llgltexture.h +++ b/indra/llrender/llgltexture.h @@ -51,10 +51,10 @@ public: BOOST_NONE = 0, BOOST_AVATAR , BOOST_AVATAR_BAKED , - BOOST_SCULPTED , BOOST_TERRAIN , // Needed for minimap generation for now. Lower than BOOST_HIGH so the texture stats don't get forced, i.e. texture stats are manually managed by minimap/terrain instead. BOOST_HIGH = 10, + BOOST_SCULPTED , BOOST_BUMP , BOOST_UNUSED_1 , // Placeholder to avoid disrupting habits around texture debug BOOST_SELECTED , @@ -75,7 +75,6 @@ public: AVATAR_SCRATCH_TEX, DYNAMIC_TEX, MEDIA, - ATLAS, OTHER, MAX_GL_IMAGE_CATEGORY }; @@ -156,10 +155,7 @@ public: bool isJustBound()const ; void forceUpdateBindStats(void) const; - U32 getTexelsInAtlas() const ; - U32 getTexelsInGLTexture() const ; bool isGLTextureCreated() const ; - S32 getDiscardLevelInAtlas() const ; LLGLTextureState getTextureState() const { return mTextureState; } //--------------------------------------------------------------------------------------------- diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 7e5cd628c1..956bcef352 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -41,6 +41,7 @@ #include "llrender.h" #include "llwindow.h" #include "llframetimer.h" +#include extern LL_COMMON_API bool on_main_thread(); @@ -130,10 +131,9 @@ S32 LLImageGL::sCount = 0; bool LLImageGL::sGlobalUseAnisotropic = false; F32 LLImageGL::sLastFrameTime = 0.f; -bool LLImageGL::sAllowReadBackRaw = false ; LLImageGL* LLImageGL::sDefaultGLTexture = NULL ; bool LLImageGL::sCompressTextures = false; -std::set LLImageGL::sImageList; +std::unordered_set LLImageGL::sImageList; bool LLImageGLThread::sEnabledTextures = false; @@ -150,6 +150,9 @@ S32 LLImageGL::sMaxCategories = 1 ; //optimization for when we don't need to calculate mIsMask bool LLImageGL::sSkipAnalyzeAlpha; +U32 LLImageGL::sScratchPBO = 0; +U32 LLImageGL::sScratchPBOSize = 0; + //------------------------ //**************************************************************************************************** @@ -159,20 +162,6 @@ bool LLImageGL::sSkipAnalyzeAlpha; //************************************************************************************** //below are functions for debug use //do not delete them even though they are not currently being used. -void check_all_images() -{ - for (std::set::iterator iter = LLImageGL::sImageList.begin(); - iter != LLImageGL::sImageList.end(); iter++) - { - LLImageGL* glimage = *iter; - if (glimage->getTexName() && glimage->isGLTextureCreated()) - { - gGL.getTexUnit(0)->bind(glimage) ; - glimage->checkTexSize() ; - gGL.getTexUnit(0)->unbind(glimage->getTarget()) ; - } - } -} void LLImageGL::checkTexSize(bool forced) const { @@ -252,6 +241,11 @@ void LLImageGL::initClass(LLWindow* window, S32 num_catagories, bool skip_analyz LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; sSkipAnalyzeAlpha = skip_analyze_alpha; + if (sScratchPBO == 0) + { + glGenBuffers(1, &sScratchPBO); + } + if (thread_texture_loads || thread_media_updates) { LLImageGLThread::createInstance(window); @@ -265,6 +259,12 @@ void LLImageGL::cleanupClass() { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; LLImageGLThread::deleteSingleton(); + if (sScratchPBO != 0) + { + glDeleteBuffers(1, &sScratchPBO); + sScratchPBO = 0; + sScratchPBOSize = 0; + } } @@ -360,66 +360,19 @@ void LLImageGL::updateStats(F32 current_time) //---------------------------------------------------------------------------- //static -void LLImageGL::destroyGL(bool save_state) +void LLImageGL::destroyGL() { for (S32 stage = 0; stage < gGLManager.mNumTextureImageUnits; stage++) { gGL.getTexUnit(stage)->unbind(LLTexUnit::TT_TEXTURE); } - - sAllowReadBackRaw = true ; - for (std::set::iterator iter = sImageList.begin(); - iter != sImageList.end(); iter++) - { - LLImageGL* glimage = *iter; - if (glimage->mTexName) - { - if (save_state && glimage->isGLTextureCreated() && glimage->mComponents) - { - glimage->mSaveData = new LLImageRaw; - if(!glimage->readBackRaw(glimage->mCurrentDiscardLevel, glimage->mSaveData, false)) //necessary, keep it. - { - glimage->mSaveData = NULL ; - } - } - - glimage->destroyGLTexture(); - stop_glerror(); - } - } - sAllowReadBackRaw = false ; -} - -//static -void LLImageGL::restoreGL() -{ - for (std::set::iterator iter = sImageList.begin(); - iter != sImageList.end(); iter++) - { - LLImageGL* glimage = *iter; - if(glimage->getTexName()) - { - LL_ERRS() << "tex name is not 0." << LL_ENDL ; - } - if (glimage->mSaveData.notNull()) - { - if (glimage->getComponents() && glimage->mSaveData->getComponents()) - { - glimage->createGLTexture(glimage->mCurrentDiscardLevel, glimage->mSaveData, 0, true, glimage->getCategory()); - stop_glerror(); - } - glimage->mSaveData = NULL; // deletes data - } - } } //static void LLImageGL::dirtyTexOptions() { - for (std::set::iterator iter = sImageList.begin(); - iter != sImageList.end(); iter++) + for (auto& glimage : sImageList) { - LLImageGL* glimage = *iter; glimage->mTexOptionsDirty = true; stop_glerror(); } @@ -542,10 +495,6 @@ void LLImageGL::init(bool usemipmaps) mHeight = 0; mCurrentDiscardLevel = -1; - mDiscardLevelInAtlas = -1 ; - mTexelsInAtlas = 0 ; - mTexelsInGLTexture = 0 ; - mAllowCompression = true; mTarget = GL_TEXTURE_2D; @@ -622,9 +571,6 @@ bool LLImageGL::setSize(S32 width, S32 height, S32 ncomponents, S32 discard_leve return false; } - // pickmask validity depends on old image size, delete it - freePickMask(); - mWidth = width; mHeight = height; mComponents = ncomponents; @@ -1025,98 +971,6 @@ bool LLImageGL::setImage(const U8* data_in, bool data_hasmips /* = false */, S32 return true; } -bool LLImageGL::preAddToAtlas(S32 discard_level, const LLImageRaw* raw_image) -{ - //not compatible with core GL profile - llassert(!LLRender::sGLCoreProfile); - - if (gGLManager.mIsDisabled) - { - LL_WARNS() << "Trying to create a texture while GL is disabled!" << LL_ENDL; - return false; - } - llassert(gGLManager.mInited); - stop_glerror(); - - if (discard_level < 0) - { - llassert(mCurrentDiscardLevel >= 0); - discard_level = mCurrentDiscardLevel; - } - - // Actual image width/height = raw image width/height * 2^discard_level - S32 w = raw_image->getWidth() << discard_level; - S32 h = raw_image->getHeight() << discard_level; - - // setSize may call destroyGLTexture if the size does not match - if (!setSize(w, h, raw_image->getComponents(), discard_level)) - { - LL_WARNS() << "Trying to create a texture with incorrect dimensions!" << LL_ENDL; - return false; - } - - if (!mHasExplicitFormat) - { - switch (mComponents) - { - case 1: - // Use luminance alpha (for fonts) - mFormatInternal = GL_LUMINANCE8; - mFormatPrimary = GL_LUMINANCE; - mFormatType = GL_UNSIGNED_BYTE; - break; - case 2: - // Use luminance alpha (for fonts) - mFormatInternal = GL_LUMINANCE8_ALPHA8; - mFormatPrimary = GL_LUMINANCE_ALPHA; - mFormatType = GL_UNSIGNED_BYTE; - break; - case 3: - mFormatInternal = GL_RGB8; - mFormatPrimary = GL_RGB; - mFormatType = GL_UNSIGNED_BYTE; - break; - case 4: - mFormatInternal = GL_RGBA8; - mFormatPrimary = GL_RGBA; - mFormatType = GL_UNSIGNED_BYTE; - break; - default: - LL_ERRS() << "Bad number of components for texture: " << (U32) getComponents() << LL_ENDL; - } - } - - mCurrentDiscardLevel = discard_level; - mDiscardLevelInAtlas = discard_level; - mTexelsInAtlas = raw_image->getWidth() * raw_image->getHeight() ; - mLastBindTime = sLastFrameTime; - mGLTextureCreated = false ; - - glPixelStorei(GL_UNPACK_ROW_LENGTH, raw_image->getWidth()); - stop_glerror(); - - if(mFormatSwapBytes) - { - glPixelStorei(GL_UNPACK_SWAP_BYTES, 1); - stop_glerror(); - } - - return true ; -} - -void LLImageGL::postAddToAtlas() -{ - if(mFormatSwapBytes) - { - glPixelStorei(GL_UNPACK_SWAP_BYTES, 0); - stop_glerror(); - } - - glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); - gGL.getTexUnit(0)->setTextureFilteringOption(mFilterOption); - stop_glerror(); -} - U32 type_width_from_pixtype(U32 pixtype) { U32 type_width = 0; @@ -1752,7 +1606,6 @@ bool LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, bool data_ mTextureMemory = (S64Bytes)getMipBytes(mCurrentDiscardLevel); - mTexelsInGLTexture = getWidth() * getHeight(); // mark this as bound at this point, so we don't throw it out immediately mLastBindTime = sLastFrameTime; @@ -1830,8 +1683,7 @@ void LLImageGL::syncTexName(LLGLuint texname) bool LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok) const { - llassert_always(sAllowReadBackRaw) ; - //LL_ERRS() << "should not call this function!" << LL_ENDL ; + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; if (discard_level < 0) { @@ -2297,6 +2149,8 @@ void LLImageGL::analyzeAlpha(const void* data_in, U32 w, U32 h) //---------------------------------------------------------------------------- U32 LLImageGL::createPickMask(S32 pWidth, S32 pHeight) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; + freePickMask(); U32 pick_width = pWidth/2 + 1; U32 pick_height = pHeight/2 + 1; @@ -2314,7 +2168,6 @@ U32 LLImageGL::createPickMask(S32 pWidth, S32 pHeight) //---------------------------------------------------------------------------- void LLImageGL::freePickMask() { - // pickmask validity depends on old image size, delete it if (mPickMask != NULL) { delete [] mPickMask; @@ -2352,16 +2205,16 @@ void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in) return ; } - freePickMask(); - if (mFormatType != GL_UNSIGNED_BYTE || ((mFormatPrimary != GL_RGBA) && (mFormatPrimary != GL_SRGB_ALPHA))) { //cannot generate a pick mask for this texture + freePickMask(); return; } + #ifdef SHOW_ASSERT const U32 pickSize = createPickMask(width, height); #else // SHOW_ASSERT @@ -2460,6 +2313,73 @@ void LLImageGL::resetCurTexSizebar() sCurTexSizeBar = -1 ; sCurTexPickSize = -1 ; } + +bool LLImageGL::scaleDown(S32 desired_discard) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; + + if (mTarget != GL_TEXTURE_2D) + { + return false; + } + + desired_discard = llmin(desired_discard, mMaxDiscardLevel); + + if (desired_discard <= mCurrentDiscardLevel) + { + return false; + } + + S32 mip = desired_discard - mCurrentDiscardLevel; + + S32 desired_width = getWidth(desired_discard); + S32 desired_height = getHeight(desired_discard); + + U64 size = getBytes(desired_discard); + llassert(size <= 2048*2048*4); // we shouldn't be using this method to downscale huge textures, but it'll work + gGL.getTexUnit(0)->bind(this); + + + if (sScratchPBO == 0) + { + glGenBuffers(1, &sScratchPBO); + sScratchPBOSize = 0; + } + + glBindBuffer(GL_PIXEL_PACK_BUFFER, sScratchPBO); + + if (size > sScratchPBOSize) + { + glBufferData(GL_PIXEL_PACK_BUFFER, size, NULL, GL_STREAM_COPY); + sScratchPBOSize = size; + } + + glGetTexImage(mTarget, mip, mFormatPrimary, mFormatType, nullptr); + + free_tex_image(mTexName); + + glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); + + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, sScratchPBO); + glTexImage2D(mTarget, 0, mFormatPrimary, desired_width, desired_height, 0, mFormatPrimary, mFormatType, nullptr); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + + alloc_tex_image(desired_width, desired_height, mFormatPrimary); + + if (mHasMipMaps) + { + LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("scaleDown - glGenerateMipmap"); + glGenerateMipmap(mTarget); + } + + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + + mCurrentDiscardLevel = desired_discard; + + return true; +} + + //---------------------------------------------------------------------------- #if LL_IMAGEGL_THREAD_CHECK void LLImageGL::checkActiveThread() diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index 5c7a5ce821..3892e9c014 100644 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -39,6 +39,7 @@ #include "llrender.h" #include "threadpool.h" #include "workqueue.h" +#include #define LL_IMAGEGL_THREAD_CHECK 0 //set to 1 to enable thread debugging for ImageGL @@ -83,9 +84,8 @@ public: // needs to be called every frame static void updateStats(F32 current_time); - // Save off / restore GL textures - static void destroyGL(bool save_state = true); - static void restoreGL(); + // cleanup GL state + static void destroyGL(); static void dirtyTexOptions(); static bool checkSize(S32 width, S32 height); @@ -148,6 +148,10 @@ public: S32 getDiscardLevel() const { return mCurrentDiscardLevel; } S32 getMaxDiscardLevel() const { return mMaxDiscardLevel; } + // override the current discard level + // should only be used for local textures where you know exactly what you're doing + void setDiscardLevel(S32 level) { mCurrentDiscardLevel = level; } + S32 getCurrentWidth() const { return mWidth ;} S32 getCurrentHeight() const { return mHeight ;} S32 getWidth(S32 discard_level = -1) const; @@ -194,26 +198,26 @@ public: void setFilteringOption(LLTexUnit::eTextureFilterOptions option); LLTexUnit::eTextureFilterOptions getFilteringOption(void) const { return mFilterOption; } - LLGLenum getTexTarget()const { return mTarget ;} - S8 getDiscardLevelInAtlas()const {return mDiscardLevelInAtlas;} - U32 getTexelsInAtlas()const { return mTexelsInAtlas ;} - U32 getTexelsInGLTexture()const {return mTexelsInGLTexture;} - + LLGLenum getTexTarget()const { return mTarget; } void init(bool usemipmaps); virtual void cleanup(); // Clean up the LLImageGL so it can be reinitialized. Be careful when using this in derived class destructors void setNeedsAlphaAndPickMask(bool need_mask); - bool preAddToAtlas(S32 discard_level, const LLImageRaw* raw_image); - void postAddToAtlas() ; - #if LL_IMAGEGL_THREAD_CHECK // thread debugging std::thread::id mActiveThread; void checkActiveThread(); #endif + // scale down to the desired discard level using GPU + // returns true if texture was scaled down + // desired discard will be clamped to max discard + // if desired discard is less than or equal to current discard, no scaling will occur + // only works for GL_TEXTURE_2D target + bool scaleDown(S32 desired_discard); + public: // Various GL/Rendering options S64Bytes mTextureMemory; @@ -240,15 +244,10 @@ private: bool mGLTextureCreated ; LLGLuint mTexName; - //LLGLuint mNewTexName = 0; // tex name set by background thread to be applied in main thread U16 mWidth; U16 mHeight; S8 mCurrentDiscardLevel; - S8 mDiscardLevelInAtlas; - U32 mTexelsInAtlas ; - U32 mTexelsInGLTexture; - bool mAllowCompression; protected: @@ -275,7 +274,7 @@ protected: // STATICS public: - static std::set sImageList; + static std::unordered_set sImageList; static S32 sCount; static F32 sLastFrameTime; @@ -301,6 +300,8 @@ public: private: static S32 sMaxCategories; static bool sSkipAnalyzeAlpha; + static U32 sScratchPBO; + static U32 sScratchPBOSize; //the flag to allow to call readBackRaw(...). //can be removed if we do not use that function at all. -- cgit v1.2.3 From 08b933a0c67463f06f124420f16c8a3f7dc83f1f Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 3 Jul 2024 17:42:24 -0500 Subject: #1870 Tune up for better experience on integrated intel with low memory (#1872) * More deterministic vsize calculation. Add control for choosing downscale method. * Quick hack to make GLTF preview work again --- indra/llrender/llgl.h | 3 + indra/llrender/llimagegl.cpp | 126 +++++++++++++++++++++++++++++--------- indra/llrender/llimagegl.h | 5 +- indra/llrender/llrender.h | 6 +- indra/llrender/llrendertarget.cpp | 12 +++- indra/llrender/llrendertarget.h | 4 +- 6 files changed, 120 insertions(+), 36 deletions(-) (limited to 'indra/llrender') diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h index 909dad2e85..be1c0a532a 100644 --- a/indra/llrender/llgl.h +++ b/indra/llrender/llgl.h @@ -102,6 +102,9 @@ public: bool mIsNVIDIA; bool mIsIntel; + // hints to the render pipe + U32 mDownScaleMethod = 0; // see settings.xml RenderDownScaleMethod + #if LL_DARWIN // Needed to distinguish problem cards on older Macs that break with Materials bool mIsMobileGF; diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 956bcef352..34200ef5cb 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -57,6 +57,9 @@ const F32 MIN_TEXTURE_LIFETIME = 10.f; U32 wpo2(U32 i); +U32 LLImageGL::sFrameCount = 0; + + // texture memory accounting (for macOS) static LLMutex sTexMemMutex; static std::unordered_map sTextureAllocs; @@ -1003,7 +1006,7 @@ bool should_stagger_image_set(bool compressed) #else // glTexSubImage2D doesn't work with compressed textures on select tested Nvidia GPUs on Windows 10 -Cosmic,2023-03-08 // Setting media textures off-thread seems faster when not using sub_image_lines (Nvidia/Windows 10) -Cosmic,2023-03-31 - return !compressed && on_main_thread(); + return !compressed && on_main_thread() && !gGLManager.mIsIntel; #endif } @@ -1185,13 +1188,37 @@ void LLImageGL::generateTextures(S32 numTextures, U32 *textures) } } +// static +void LLImageGL::updateClass() +{ + sFrameCount++; +} + // static void LLImageGL::deleteTextures(S32 numTextures, const U32 *textures) { + // wait a few frames before actually deleting the textures to avoid + // synchronization issues with the GPU + static std::vector sFreeList[4]; + if (gGLManager.mInited) { - free_tex_images(numTextures, textures); - glDeleteTextures(numTextures, textures); + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; + U32 idx = sFrameCount % 4; + + for (S32 i = 0; i < numTextures; ++i) + { + sFreeList[idx].push_back(textures[i]); + } + + idx = (sFrameCount + 3) % 4; + + if (!sFreeList[idx].empty()) + { + glDeleteTextures((GLsizei) sFreeList[idx].size(), sFreeList[idx].data()); + free_tex_images((GLsizei) sFreeList[idx].size(), sFreeList[idx].data()); + sFreeList[idx].resize(0); + } } } @@ -2335,44 +2362,85 @@ bool LLImageGL::scaleDown(S32 desired_discard) S32 desired_width = getWidth(desired_discard); S32 desired_height = getHeight(desired_discard); - U64 size = getBytes(desired_discard); - llassert(size <= 2048*2048*4); // we shouldn't be using this method to downscale huge textures, but it'll work - gGL.getTexUnit(0)->bind(this); + if (gGLManager.mDownScaleMethod == 0) + { // use an FBO to downscale the texture + // allocate new texture + U32 temp_texname = 0; + generateTextures(1, &temp_texname); + gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, temp_texname, true); + { + LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("scaleDown - glTexImage2D"); + glTexImage2D(mTarget, 0, mFormatPrimary, desired_width, desired_height, 0, mFormatPrimary, mFormatType, NULL); + } + // account for new texture getting created + alloc_tex_image(desired_width, desired_height, mFormatPrimary); - if (sScratchPBO == 0) - { - glGenBuffers(1, &sScratchPBO); - sScratchPBOSize = 0; - } + // Use render-to-texture to scale down the texture + { + LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("scaleDown - glFramebufferTexture2D"); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTarget, temp_texname, 0); + } - glBindBuffer(GL_PIXEL_PACK_BUFFER, sScratchPBO); + glViewport(0, 0, desired_width, desired_height); - if (size > sScratchPBOSize) - { - glBufferData(GL_PIXEL_PACK_BUFFER, size, NULL, GL_STREAM_COPY); - sScratchPBOSize = size; + // draw a full screen triangle + gGL.getTexUnit(0)->bind(this); + glDrawArrays(GL_TRIANGLES, 0, 3); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + + // delete old texture and assign new texture name + deleteTextures(1, &mTexName); + mTexName = temp_texname; + + if (mHasMipMaps) + { // generate mipmaps if needed + LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("scaleDown - glGenerateMipmap"); + gGL.getTexUnit(0)->bind(this); + glGenerateMipmap(mTarget); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + } } + else + { // use a PBO to downscale the texture + U64 size = getBytes(desired_discard); + llassert(size <= 2048 * 2048 * 4); // we shouldn't be using this method to downscale huge textures, but it'll work + gGL.getTexUnit(0)->bind(this); + + if (sScratchPBO == 0) + { + glGenBuffers(1, &sScratchPBO); + sScratchPBOSize = 0; + } - glGetTexImage(mTarget, mip, mFormatPrimary, mFormatType, nullptr); + glBindBuffer(GL_PIXEL_PACK_BUFFER, sScratchPBO); - free_tex_image(mTexName); + if (size > sScratchPBOSize) + { + glBufferData(GL_PIXEL_PACK_BUFFER, size, NULL, GL_STREAM_COPY); + sScratchPBOSize = size; + } - glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); + glGetTexImage(mTarget, mip, mFormatPrimary, mFormatType, nullptr); - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, sScratchPBO); - glTexImage2D(mTarget, 0, mFormatPrimary, desired_width, desired_height, 0, mFormatPrimary, mFormatType, nullptr); - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + free_tex_image(mTexName); - alloc_tex_image(desired_width, desired_height, mFormatPrimary); + glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); - if (mHasMipMaps) - { - LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("scaleDown - glGenerateMipmap"); - glGenerateMipmap(mTarget); - } + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, sScratchPBO); + glTexImage2D(mTarget, 0, mFormatPrimary, desired_width, desired_height, 0, mFormatPrimary, mFormatType, nullptr); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + alloc_tex_image(desired_width, desired_height, mFormatPrimary); + + if (mHasMipMaps) + { + LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("scaleDown - glGenerateMipmap"); + glGenerateMipmap(mTarget); + } + + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + } mCurrentDiscardLevel = desired_discard; diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index 3892e9c014..5073701c30 100644 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -62,6 +62,9 @@ class LLImageGL : public LLRefCount friend class LLTexUnit; public: + // call once per frame + static void updateClass(); + // Get an estimate of how many bytes have been allocated in vram for textures. // Does not include mipmaps. // NOTE: multiplying this number by two gives a good estimate for total @@ -276,7 +279,7 @@ protected: public: static std::unordered_set sImageList; static S32 sCount; - + static U32 sFrameCount; static F32 sLastFrameTime; // Global memory statistics diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index be9f3895e7..e6b4118beb 100644 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -297,7 +297,11 @@ public: ALTERNATE_DIFFUSE_MAP = 1, NORMAL_MAP = 1, SPECULAR_MAP = 2, - NUM_TEXTURE_CHANNELS = 3, + BASECOLOR_MAP = 3, + METALLIC_ROUGHNESS_MAP = 4, + GLTF_NORMAL_MAP = 5, + EMISSIVE_MAP = 6, + NUM_TEXTURE_CHANNELS = 7, }; enum eVolumeTexIndex : U8 diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp index efdde77a32..60159a0497 100644 --- a/indra/llrender/llrendertarget.cpp +++ b/indra/llrender/llrendertarget.cpp @@ -426,14 +426,17 @@ void LLRenderTarget::bindTarget() GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3}; - glDrawBuffers(static_cast(mTex.size()), drawbuffers); if (mTex.empty()) { //no color buffer to draw to glDrawBuffer(GL_NONE); glReadBuffer(GL_NONE); } - + else + { + glDrawBuffers(static_cast(mTex.size()), drawbuffers); + glReadBuffer(GL_COLOR_ATTACHMENT0); + } check_framebuffer_status(); glViewport(0, 0, mResX, mResY); @@ -519,7 +522,8 @@ void LLRenderTarget::flush() llassert(sCurFBO == mFBO); llassert(sBoundTarget == this); - if (mGenerateMipMaps == LLTexUnit::TMG_AUTO) { + if (mGenerateMipMaps == LLTexUnit::TMG_AUTO) + { LL_PROFILE_GPU_ZONE("rt generate mipmaps"); bindTexture(0, 0, LLTexUnit::TFO_TRILINEAR); glGenerateMipmap(GL_TEXTURE_2D); @@ -540,6 +544,8 @@ void LLRenderTarget::flush() glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); sCurResX = gGLViewport[2]; sCurResY = gGLViewport[3]; + glReadBuffer(GL_BACK); + glDrawBuffer(GL_BACK); } } diff --git a/indra/llrender/llrendertarget.h b/indra/llrender/llrendertarget.h index 340276a752..a1adf93fa1 100644 --- a/indra/llrender/llrendertarget.h +++ b/indra/llrender/llrendertarget.h @@ -172,6 +172,8 @@ public: // *HACK void swapFBORefs(LLRenderTarget& other); + static LLRenderTarget* sBoundTarget; + protected: U32 mResX; U32 mResY; @@ -186,8 +188,6 @@ protected: U32 mMipLevels; LLTexUnit::eTextureType mUsage; - - static LLRenderTarget* sBoundTarget; }; #endif -- cgit v1.2.3 From 9ddf64c65183960ffed4fe61c5d85e8bacaea030 Mon Sep 17 00:00:00 2001 From: Alexander Gavriliuk Date: Fri, 5 Jul 2024 18:46:30 +0200 Subject: #1931 BugSplat Crash: SecondLifeViewer!LLRenderTarget::release(387) --- indra/llrender/llrendertarget.cpp | 4 ++++ indra/llrender/llrendertarget.h | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'indra/llrender') diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp index 60159a0497..410efe9a70 100644 --- a/indra/llrender/llrendertarget.cpp +++ b/indra/llrender/llrendertarget.cpp @@ -50,6 +50,7 @@ void check_framebuffer_status() } } +bool LLRenderTarget::sInitFailed = false; bool LLRenderTarget::sUseFBO = false; U32 LLRenderTarget::sCurFBO = 0; @@ -352,6 +353,9 @@ void LLRenderTarget::release() LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; llassert(!isBoundInStack()); + if (sInitFailed) + return; + if (mDepth) { LLImageGL::deleteTextures(1, &mDepth); diff --git a/indra/llrender/llrendertarget.h b/indra/llrender/llrendertarget.h index a1adf93fa1..fc78f059e0 100644 --- a/indra/llrender/llrendertarget.h +++ b/indra/llrender/llrendertarget.h @@ -61,7 +61,9 @@ class LLRenderTarget { public: - //whether or not to use FBO implementation + // Whether app initialization failed + static bool sInitFailed; + // Whether or not to use FBO implementation static bool sUseFBO; static U32 sBytesAllocated; static U32 sCurFBO; -- cgit v1.2.3 From d0173ac7fc1f999b31aad70c3abfa2c57f872899 Mon Sep 17 00:00:00 2001 From: Alexander Gavriliuk Date: Sat, 6 Jul 2024 09:23:39 +0200 Subject: #1931 Terminate AppViewer immediately in case of initialization failed --- indra/llrender/llrendertarget.cpp | 4 ---- indra/llrender/llrendertarget.h | 2 -- 2 files changed, 6 deletions(-) (limited to 'indra/llrender') diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp index 410efe9a70..60159a0497 100644 --- a/indra/llrender/llrendertarget.cpp +++ b/indra/llrender/llrendertarget.cpp @@ -50,7 +50,6 @@ void check_framebuffer_status() } } -bool LLRenderTarget::sInitFailed = false; bool LLRenderTarget::sUseFBO = false; U32 LLRenderTarget::sCurFBO = 0; @@ -353,9 +352,6 @@ void LLRenderTarget::release() LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; llassert(!isBoundInStack()); - if (sInitFailed) - return; - if (mDepth) { LLImageGL::deleteTextures(1, &mDepth); diff --git a/indra/llrender/llrendertarget.h b/indra/llrender/llrendertarget.h index fc78f059e0..cd3290cf66 100644 --- a/indra/llrender/llrendertarget.h +++ b/indra/llrender/llrendertarget.h @@ -61,8 +61,6 @@ class LLRenderTarget { public: - // Whether app initialization failed - static bool sInitFailed; // Whether or not to use FBO implementation static bool sUseFBO; static U32 sBytesAllocated; -- cgit v1.2.3 From 9fdca96f8bd2211a99fe88e57b70cbecefa20b6d Mon Sep 17 00:00:00 2001 From: Ansariel Date: Mon, 8 Jul 2024 20:27:14 +0200 Subject: Re-enable compiler warnings C4244 and C4396 except for lltracerecording.h and llunittype.h for now --- indra/llrender/llfontfreetype.cpp | 2 +- indra/llrender/llfontfreetypesvg.cpp | 20 ++++++++++---------- indra/llrender/llfontgl.cpp | 4 ++-- indra/llrender/llfontregistry.cpp | 2 +- indra/llrender/llglslshader.cpp | 16 ++++++++-------- indra/llrender/llimagegl.cpp | 6 +++--- indra/llrender/llpostprocess.cpp | 2 +- indra/llrender/llrender2dutils.cpp | 14 +++++++------- indra/llrender/llrendertarget.cpp | 2 +- indra/llrender/llshadermgr.cpp | 8 ++++---- indra/llrender/lluiimage.cpp | 6 +++--- 11 files changed, 41 insertions(+), 41 deletions(-) (limited to 'indra/llrender') diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp index 741ed993b0..6128e03fa7 100644 --- a/indra/llrender/llfontfreetype.cpp +++ b/indra/llrender/llfontfreetype.cpp @@ -178,7 +178,7 @@ unsigned long ft_read_cb(FT_Stream stream, unsigned long offset, unsigned char * llifstream *file_stream = static_cast(stream->descriptor.pointer); file_stream->seekg(offset, std::ios::beg); file_stream->read((char*)buffer, count); - return file_stream->gcount(); + return (unsigned long)file_stream->gcount(); } void ft_close_cb(FT_Stream stream) { diff --git a/indra/llrender/llfontfreetypesvg.cpp b/indra/llrender/llfontfreetypesvg.cpp index 355e8432aa..71f751329e 100644 --- a/indra/llrender/llfontfreetypesvg.cpp +++ b/indra/llrender/llfontfreetypesvg.cpp @@ -136,18 +136,18 @@ FT_Error LLFontFreeTypeSvgRenderer::OnPresetGlypthSlot(FT_GlyphSlot glyph_slot, float svg_scale = llmin(svg_x_scale, svg_y_scale); datap->Scale = svg_scale; - glyph_slot->bitmap.width = floorf(svg_width) * svg_scale; - glyph_slot->bitmap.rows = floorf(svg_height) * svg_scale; + glyph_slot->bitmap.width = (unsigned int)(floorf(svg_width) * svg_scale); + glyph_slot->bitmap.rows = (unsigned int)(floorf(svg_height) * svg_scale); glyph_slot->bitmap_left = (document->metrics.x_ppem - glyph_slot->bitmap.width) / 2; - glyph_slot->bitmap_top = glyph_slot->face->size->metrics.ascender / 64.f; + glyph_slot->bitmap_top = (FT_Int)(glyph_slot->face->size->metrics.ascender / 64.f); glyph_slot->bitmap.pitch = glyph_slot->bitmap.width * 4; glyph_slot->bitmap.pixel_mode = FT_PIXEL_MODE_BGRA; /* Copied as-is from fcft (MIT license) */ // Compute all the bearings and set them correctly. The outline is scaled already, we just need to use the bounding box. - float horiBearingX = 0.; - float horiBearingY = -glyph_slot->bitmap_top; + float horiBearingX = 0.f; + float horiBearingY = -(float)glyph_slot->bitmap_top; // XXX parentheses correct? float vertBearingX = glyph_slot->metrics.horiBearingX / 64.0f - glyph_slot->metrics.horiAdvance / 64.0f / 2; @@ -156,13 +156,13 @@ FT_Error LLFontFreeTypeSvgRenderer::OnPresetGlypthSlot(FT_GlyphSlot glyph_slot, // Do conversion in two steps to avoid 'bad function cast' warning glyph_slot->metrics.width = glyph_slot->bitmap.width * 64; glyph_slot->metrics.height = glyph_slot->bitmap.rows * 64; - glyph_slot->metrics.horiBearingX = horiBearingX * 64; - glyph_slot->metrics.horiBearingY = horiBearingY * 64; - glyph_slot->metrics.vertBearingX = vertBearingX * 64; - glyph_slot->metrics.vertBearingY = vertBearingY * 64; + glyph_slot->metrics.horiBearingX = (FT_Pos)(horiBearingX * 64); + glyph_slot->metrics.horiBearingY = (FT_Pos)(horiBearingY * 64); + glyph_slot->metrics.vertBearingX = (FT_Pos)(vertBearingX * 64); + glyph_slot->metrics.vertBearingY = (FT_Pos)(vertBearingY * 64); if (glyph_slot->metrics.vertAdvance == 0) { - glyph_slot->metrics.vertAdvance = glyph_slot->bitmap.rows * 1.2f * 64; + glyph_slot->metrics.vertAdvance = (FT_Pos)(glyph_slot->bitmap.rows * 1.2f * 64); } return FT_Err_Ok; diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp index 59ee8ef84f..04aebdde90 100644 --- a/indra/llrender/llfontgl.cpp +++ b/indra/llrender/llfontgl.cpp @@ -112,7 +112,7 @@ S32 LLFontGL::getNumFaces(const std::string& filename) S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, const LLRect& rect, const LLColor4 &color, HAlign halign, VAlign valign, U8 style, ShadowType shadow, S32 max_chars, F32* right_x, bool use_ellipses, bool use_color) const { - LLRectf rect_float(rect.mLeft, rect.mTop, rect.mRight, rect.mBottom); + LLRectf rect_float((F32)rect.mLeft, (F32)rect.mTop, (F32)rect.mRight, (F32)rect.mBottom); return render(wstr, begin_offset, rect_float, color, halign, valign, style, shadow, max_chars, right_x, use_ellipses, use_color); } @@ -138,7 +138,7 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, const LLRectf& rec y = rect.mBottom; break; } - return render(wstr, begin_offset, x, y, color, halign, valign, style, shadow, max_chars, rect.getWidth(), right_x, use_ellipses, use_color); + return render(wstr, begin_offset, x, y, color, halign, valign, style, shadow, max_chars, (S32)rect.getWidth(), right_x, use_ellipses, use_color); } diff --git a/indra/llrender/llfontregistry.cpp b/indra/llrender/llfontregistry.cpp index 62f4f35e3d..c48a389f6a 100644 --- a/indra/llrender/llfontregistry.cpp +++ b/indra/llrender/llfontregistry.cpp @@ -500,7 +500,7 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc) // *HACK: Fallback fonts don't render, so we can use that to suppress // creation of OpenGL textures for test apps. JC bool is_fallback = !is_first_found || !mCreateGLTextures; - F32 extra_scale = (is_fallback)?fallback_scale:1.0; + F32 extra_scale = (is_fallback) ? fallback_scale : 1.0f; F32 point_size_scale = extra_scale * point_size; bool is_font_loaded = false; for(string_vec_t::iterator font_search_path_it = font_search_paths.begin(); diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index 25e4a88f28..e76a30a954 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -190,7 +190,7 @@ void LLGLSLShader::dumpStats() tris_sec /= seconds; F32 pct_samples = (F32)((F64)mSamplesDrawn / (F64)sTotalSamplesDrawn) * 100.f; - F32 samples_sec = (F32)mSamplesDrawn / 1000000000.0; + F32 samples_sec = (F32)(mSamplesDrawn / 1000000000.0); samples_sec /= seconds; F32 pct_binds = (F32)mBinds / (F32)sTotalBinds * 100.f; @@ -1265,7 +1265,7 @@ void LLGLSLShader::uniform1i(U32 index, GLint x) if (iter == mValue.end() || iter->second.mV[0] != x) { glUniform1i(mUniform[index], x); - mValue[mUniform[index]] = LLVector4(x, 0.f, 0.f, 0.f); + mValue[mUniform[index]] = LLVector4((F32)x, 0.f, 0.f, 0.f); } } } @@ -1405,7 +1405,7 @@ void LLGLSLShader::uniform1iv(U32 index, U32 count, const GLint* v) if (mUniform[index] >= 0) { const auto& iter = mValue.find(mUniform[index]); - LLVector4 vec(v[0], 0.f, 0.f, 0.f); + LLVector4 vec((F32)v[0], 0.f, 0.f, 0.f); if (iter == mValue.end() || shouldChange(iter->second, vec) || count != 1) { glUniform1iv(mUniform[index], count, v); @@ -1432,7 +1432,7 @@ void LLGLSLShader::uniform4iv(U32 index, U32 count, const GLint* v) if (mUniform[index] >= 0) { const auto& iter = mValue.find(mUniform[index]); - LLVector4 vec(v[0], v[1], v[2], v[3]); + LLVector4 vec((F32)v[0], (F32)v[1], (F32)v[2], (F32)v[3]); if (iter == mValue.end() || shouldChange(iter->second, vec) || count != 1) { glUniform1iv(mUniform[index], count, v); @@ -1702,7 +1702,7 @@ void LLGLSLShader::uniform1i(const LLStaticHashedString& uniform, GLint v) if (location >= 0) { const auto& iter = mValue.find(location); - LLVector4 vec(v, 0.f, 0.f, 0.f); + LLVector4 vec((F32)v, 0.f, 0.f, 0.f); if (iter == mValue.end() || shouldChange(iter->second, vec)) { glUniform1i(location, v); @@ -1718,7 +1718,7 @@ void LLGLSLShader::uniform1iv(const LLStaticHashedString& uniform, U32 count, co if (location >= 0) { - LLVector4 vec(v[0], 0, 0, 0); + LLVector4 vec((F32)v[0], 0.f, 0.f, 0.f); const auto& iter = mValue.find(location); if (iter == mValue.end() || shouldChange(iter->second, vec) || count != 1) { @@ -1736,7 +1736,7 @@ void LLGLSLShader::uniform4iv(const LLStaticHashedString& uniform, U32 count, co if (location >= 0) { - LLVector4 vec(v[0], v[1], v[2], v[3]); + LLVector4 vec((F32)v[0], (F32)v[1], (F32)v[2], (F32)v[3]); const auto& iter = mValue.find(location); if (iter == mValue.end() || shouldChange(iter->second, vec) || count != 1) { @@ -1755,7 +1755,7 @@ void LLGLSLShader::uniform2i(const LLStaticHashedString& uniform, GLint i, GLint if (location >= 0) { const auto& iter = mValue.find(location); - LLVector4 vec(i, j, 0.f, 0.f); + LLVector4 vec((F32)i, (F32)j, 0.f, 0.f); if (iter == mValue.end() || shouldChange(iter->second, vec)) { glUniform2i(location, i, j); diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 34200ef5cb..058afa0cf2 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -738,7 +738,7 @@ bool LLImageGL::setImage(const U8* data_in, bool data_hasmips /* = false */, S32 } if (is_compressed) { - S32 tex_size = dataFormatBytes(mFormatPrimary, w, h); + GLsizei tex_size = (GLsizei)dataFormatBytes(mFormatPrimary, w, h); glCompressedTexImage2D(mTarget, gl_level, mFormatPrimary, w, h, 0, tex_size, (GLvoid *)data_in); stop_glerror(); } @@ -941,7 +941,7 @@ bool LLImageGL::setImage(const U8* data_in, bool data_hasmips /* = false */, S32 S32 h = getHeight(); if (is_compressed) { - S32 tex_size = dataFormatBytes(mFormatPrimary, w, h); + GLsizei tex_size = (GLsizei)dataFormatBytes(mFormatPrimary, w, h); glCompressedTexImage2D(mTarget, 0, mFormatPrimary, w, h, 0, tex_size, (GLvoid *)data_in); stop_glerror(); } @@ -2418,7 +2418,7 @@ bool LLImageGL::scaleDown(S32 desired_discard) if (size > sScratchPBOSize) { glBufferData(GL_PIXEL_PACK_BUFFER, size, NULL, GL_STREAM_COPY); - sScratchPBOSize = size; + sScratchPBOSize = (U32)size; } glGetTexImage(mTarget, mip, mFormatPrimary, mFormatType, nullptr); diff --git a/indra/llrender/llpostprocess.cpp b/indra/llrender/llpostprocess.cpp index 8ebd09f20d..eef7193c92 100644 --- a/indra/llrender/llpostprocess.cpp +++ b/indra/llrender/llpostprocess.cpp @@ -343,7 +343,7 @@ void LLPostProcess::viewOrthogonal(unsigned int width, unsigned int height) gGL.matrixMode(LLRender::MM_PROJECTION); gGL.pushMatrix(); gGL.loadIdentity(); - gGL.ortho( 0.f, (GLdouble) width , (GLdouble) height , 0.f, -1.f, 1.f ); + gGL.ortho( 0.f, (GLfloat) width , (GLfloat) height , 0.f, -1.f, 1.f ); gGL.matrixMode(LLRender::MM_MODELVIEW); gGL.pushMatrix(); gGL.loadIdentity(); diff --git a/indra/llrender/llrender2dutils.cpp b/indra/llrender/llrender2dutils.cpp index ef02fbd071..176c7a5d2c 100644 --- a/indra/llrender/llrender2dutils.cpp +++ b/indra/llrender/llrender2dutils.cpp @@ -364,7 +364,7 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTex { // add in offset of current image to current UI translation const LLVector3 ui_scale = gGL.getUIScale(); - const LLVector3 ui_translation = (gGL.getUITranslation() + LLVector3(x, y, 0.f)).scaledVec(ui_scale); + const LLVector3 ui_translation = (gGL.getUITranslation() + LLVector3((F32)x, (F32)y, 0.f)).scaledVec(ui_scale); F32 uv_width = uv_outer_rect.getWidth(); F32 uv_height = uv_outer_rect.getHeight(); @@ -375,8 +375,8 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTex uv_outer_rect.mLeft + (center_rect.mRight * uv_width), uv_outer_rect.mBottom + (center_rect.mBottom * uv_height)); - F32 image_width = image->getWidth(0); - F32 image_height = image->getHeight(0); + F32 image_width = (F32)image->getWidth(0); + F32 image_height = (F32)image->getHeight(0); S32 image_natural_width = ll_round(image_width * uv_width); S32 image_natural_height = ll_round(image_height * uv_height); @@ -413,10 +413,10 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTex draw_center_rect.setCenterAndSize(uv_center_rect.getCenterX() * width, uv_center_rect.getCenterY() * height, scaled_width, scaled_height); } - draw_center_rect.mLeft = ll_round(ui_translation.mV[VX] + (F32)draw_center_rect.mLeft * ui_scale.mV[VX]); - draw_center_rect.mTop = ll_round(ui_translation.mV[VY] + (F32)draw_center_rect.mTop * ui_scale.mV[VY]); - draw_center_rect.mRight = ll_round(ui_translation.mV[VX] + (F32)draw_center_rect.mRight * ui_scale.mV[VX]); - draw_center_rect.mBottom = ll_round(ui_translation.mV[VY] + (F32)draw_center_rect.mBottom * ui_scale.mV[VY]); + draw_center_rect.mLeft = (F32)ll_round(ui_translation.mV[VX] + (F32)draw_center_rect.mLeft * ui_scale.mV[VX]); + draw_center_rect.mTop = (F32)ll_round(ui_translation.mV[VY] + (F32)draw_center_rect.mTop * ui_scale.mV[VY]); + draw_center_rect.mRight = (F32)ll_round(ui_translation.mV[VX] + (F32)draw_center_rect.mRight * ui_scale.mV[VX]); + draw_center_rect.mBottom = (F32)ll_round(ui_translation.mV[VY] + (F32)draw_center_rect.mBottom * ui_scale.mV[VY]); LLRectf draw_outer_rect(ui_translation.mV[VX], ui_translation.mV[VY] + height * ui_scale.mV[VY], diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp index 410efe9a70..015819c1bd 100644 --- a/indra/llrender/llrendertarget.cpp +++ b/indra/llrender/llrendertarget.cpp @@ -124,7 +124,7 @@ bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, LLT if (mGenerateMipMaps != LLTexUnit::TMG_NONE) { // Calculate the number of mip levels based upon resolution that we should have. - mMipLevels = 1 + floor(log10((float)llmax(mResX, mResY))/log10(2.0)); + mMipLevels = 1 + (U32)floor(log10((float)llmax(mResX, mResY)) / log10(2.0)); } if (depth) diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index a8e9f20b40..8bc00c0cf6 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -1003,7 +1003,7 @@ void LLShaderMgr::initShaderCache(bool enabled, const LLUUID& old_cache_version, ProgramBinaryData binary_info = ProgramBinaryData(); binary_info.mBinaryFormat = data_pair.second["binary_format"].asInteger(); binary_info.mBinaryLength = data_pair.second["binary_size"].asInteger(); - binary_info.mLastUsedTime = data_pair.second["last_used"].asReal(); + binary_info.mLastUsedTime = (F32)data_pair.second["last_used"].asReal(); mShaderBinaryCache.insert_or_assign(LLUUID(data_pair.first), binary_info); } } @@ -1034,7 +1034,7 @@ void LLShaderMgr::persistShaderCacheMetadata() LLSD out = LLSD::emptyMap(); static const F32 LRU_TIME = (60.f * 60.f) * 24.f * 7.f; // 14 days - const F32 current_time = LLTimer::getTotalSeconds(); + const F32 current_time = (F32)LLTimer::getTotalSeconds(); for (auto it = mShaderBinaryCache.begin(); it != mShaderBinaryCache.end();) { const ProgramBinaryData& shader_metadata = it->second; @@ -1093,7 +1093,7 @@ bool LLShaderMgr::loadCachedProgramBinary(LLGLSLShader* shader) glGetProgramiv(shader->mProgramObject, GL_LINK_STATUS, &success); if (error == GL_NO_ERROR && success == GL_TRUE) { - binary_iter->second.mLastUsedTime = LLTimer::getTotalSeconds(); + binary_iter->second.mLastUsedTime = (F32)LLTimer::getTotalSeconds(); LL_INFOS() << "Loaded cached binary for shader: " << shader->mName << LL_ENDL; return true; } @@ -1131,7 +1131,7 @@ bool LLShaderMgr::saveCachedProgramBinary(LLGLSLShader* shader) fwrite(program_binary.data(), sizeof(U8), program_binary.size(), outfile); outfile.close(); - binary_info.mLastUsedTime = LLTimer::getTotalSeconds(); + binary_info.mLastUsedTime = (F32)LLTimer::getTotalSeconds(); mShaderBinaryCache.insert_or_assign(shader->mShaderHash, binary_info); return true; diff --git a/indra/llrender/lluiimage.cpp b/indra/llrender/lluiimage.cpp index bcf665ca18..d31a91e2af 100644 --- a/indra/llrender/lluiimage.cpp +++ b/indra/llrender/lluiimage.cpp @@ -83,7 +83,7 @@ void LLUIImage::draw3D(const LLVector3& origin_agent, const LLVector3& x_axis, c LLRender2D::getInstance()->pushMatrix(); { - LLVector3 rect_origin = origin_agent + (rect.mLeft * x_axis) + (rect.mBottom * y_axis); + LLVector3 rect_origin = origin_agent + ((F32)rect.mLeft * x_axis) + ((F32)rect.mBottom * y_axis); LLRender2D::getInstance()->translate(rect_origin.mV[VX], rect_origin.mV[VY], rect_origin.mV[VZ]); @@ -100,8 +100,8 @@ void LLUIImage::draw3D(const LLVector3& origin_agent, const LLVector3& x_axis, c (rect.getHeight() - (border_height * border_scale * 0.5f)) / (F32)rect.getHeight(), (rect.getWidth() - (border_width * border_scale * 0.5f)) / (F32)rect.getWidth(), (border_height * border_scale * 0.5f) / (F32)rect.getHeight()), - rect.getWidth() * x_axis, - rect.getHeight() * y_axis); + (F32)rect.getWidth() * x_axis, + (F32)rect.getHeight() * y_axis); } LLRender2D::getInstance()->popMatrix(); } -- cgit v1.2.3 From 2a7030992faa12c362d3eb9365080efd8265e15f Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Tue, 9 Jul 2024 17:53:43 -0400 Subject: Update tracy profiler to 0.10 (#1946) --- indra/llrender/llfontgl.cpp | 8 ++++---- indra/llrender/llrender.cpp | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'indra/llrender') diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp index 04aebdde90..b9a4235a4e 100644 --- a/indra/llrender/llfontgl.cpp +++ b/indra/llrender/llfontgl.cpp @@ -560,7 +560,7 @@ F32 LLFontGL::getWidthF32(const llwchar* wchars, S32 begin_offset, S32 max_chars void LLFontGL::generateASCIIglyphs() { - LL_PROFILE_ZONE_SCOPED_CATEGORY_UI + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; for (U32 i = 32; (i < 127); i++) { mFontFreetype->getGlyphInfo(i, EFontGlyphType::Grayscale); @@ -570,7 +570,7 @@ void LLFontGL::generateASCIIglyphs() // Returns the max number of complete characters from text (up to max_chars) that can be drawn in max_pixels S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_chars, EWordWrapStyle end_on_word_boundary) const { - LL_PROFILE_ZONE_SCOPED_CATEGORY_UI + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; if (!wchars || !wchars[0] || max_chars == 0) { return 0; @@ -881,7 +881,7 @@ void LLFontGL::dumpFontTextures() // static bool LLFontGL::loadDefaultFonts() { - LL_PROFILE_ZONE_SCOPED_CATEGORY_UI + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; bool succ = true; succ &= (NULL != getFontSansSerifSmall()); succ &= (NULL != getFontSansSerif()); @@ -894,7 +894,7 @@ bool LLFontGL::loadDefaultFonts() void LLFontGL::loadCommonFonts() { - LL_PROFILE_ZONE_SCOPED_CATEGORY_UI + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; getFont(LLFontDescriptor("SansSerif", "Small", BOLD)); getFont(LLFontDescriptor("SansSerif", "Large", BOLD)); getFont(LLFontDescriptor("SansSerif", "Huge", BOLD)); diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index a0209fab43..1301d325a0 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -1514,7 +1514,7 @@ LLLightState* LLRender::getLight(U32 index) void LLRender::setAmbientLightColor(const LLColor4& color) { - LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE + LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; if (color != mAmbientLightColor) { ++mLightHash; -- cgit v1.2.3 From e101d1aa28a51570e6d76dc12df810b1daa71e7e Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Tue, 9 Jul 2024 20:51:02 -0400 Subject: Fix excessive clearing of shader cache when toggling mirrors (#1950) --- indra/llrender/llshadermgr.cpp | 6 ------ indra/llrender/llshadermgr.h | 1 - 2 files changed, 7 deletions(-) (limited to 'indra/llrender') diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index 8bc00c0cf6..bc542d325e 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -44,7 +44,6 @@ using std::make_pair; using std::string; LLShaderMgr * LLShaderMgr::sInstance = NULL; -bool LLShaderMgr::sMirrorsEnabled = false; LLShaderMgr::LLShaderMgr() { @@ -600,11 +599,6 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev extra_code_text[extra_code_count++] = strdup("#define FXAA_GLSL_130 1\n"); } - if (sMirrorsEnabled) - { - extra_code_text[extra_code_count++] = strdup("#define HERO_PROBES 1\n"); - } - // Use alpha float to store bit flags // See: C++: addDeferredAttachment(), shader: frag_data[2] extra_code_text[extra_code_count++] = strdup("#define GBUFFER_FLAG_SKIP_ATMOS 0.0 \n"); // atmo kill diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h index fe6137c448..921ef20997 100644 --- a/indra/llrender/llshadermgr.h +++ b/indra/llrender/llshadermgr.h @@ -378,7 +378,6 @@ public: bool mShaderCacheInitialized = false; bool mShaderCacheEnabled = false; std::string mShaderCacheDir; - static bool sMirrorsEnabled; protected: -- cgit v1.2.3 From 604cb4cb4dd71c0f90633e50d5b0108e3901c4ad Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Fri, 26 Jul 2024 06:19:34 -0400 Subject: Reduce utf8 to wstring conversion and llwstring temporaries during text draw (#2115) --- indra/llrender/llfontgl.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'indra/llrender') diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp index b9a4235a4e..b6cdb81b33 100644 --- a/indra/llrender/llfontgl.cpp +++ b/indra/llrender/llfontgl.cpp @@ -406,7 +406,8 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons // recursively render ellipses at end of string // we've already reserved enough room gGL.pushUIMatrix(); - renderUTF8(std::string("..."), + static LLWString elipses_wstr(utf8string_to_wstring(std::string("..."))); + render(elipses_wstr, 0, (cur_x - origin.mV[VX]) / sScaleX, (F32)y, color, -- cgit v1.2.3 From 75455d101c9535d0d45aa0f505f888f4ba3de64d Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Tue, 6 Aug 2024 09:21:19 -0400 Subject: Convert LLUI and LLRender2D to LLSimpleton to reduce overhead during ui draw (#2202) --- indra/llrender/llrender2dutils.cpp | 2 +- indra/llrender/llrender2dutils.h | 7 ++++--- indra/llrender/lluiimage.cpp | 6 +++--- 3 files changed, 8 insertions(+), 7 deletions(-) (limited to 'indra/llrender') diff --git a/indra/llrender/llrender2dutils.cpp b/indra/llrender/llrender2dutils.cpp index 176c7a5d2c..428370057e 100644 --- a/indra/llrender/llrender2dutils.cpp +++ b/indra/llrender/llrender2dutils.cpp @@ -726,7 +726,7 @@ void gl_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& c } gGL.end(); - LLRender2D::getInstance()->setLineWidth(1.f); + LLRender2D::setLineWidth(1.f); } void gl_arc_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, bool filled, F32 start_angle, F32 end_angle) diff --git a/indra/llrender/llrender2dutils.h b/indra/llrender/llrender2dutils.h index 0d3efc38d6..096e7584f1 100644 --- a/indra/llrender/llrender2dutils.h +++ b/indra/llrender/llrender2dutils.h @@ -122,12 +122,13 @@ inline void gl_rect_2d_offset_local( const LLRect& rect, S32 pixel_offset, bool class LLImageProviderInterface; -class LLRender2D : public LLParamSingleton +class LLRender2D : public LLSimpleton { - LLSINGLETON(LLRender2D, LLImageProviderInterface* image_provider); LOG_CLASS(LLRender2D); - ~LLRender2D(); public: + LLRender2D(LLImageProviderInterface* image_provider); + ~LLRender2D(); + static void pushMatrix(); static void popMatrix(); static void loadIdentity(); diff --git a/indra/llrender/lluiimage.cpp b/indra/llrender/lluiimage.cpp index d31a91e2af..dc18bf16bf 100644 --- a/indra/llrender/lluiimage.cpp +++ b/indra/llrender/lluiimage.cpp @@ -81,10 +81,10 @@ void LLUIImage::draw3D(const LLVector3& origin_agent, const LLVector3& x_axis, c } } - LLRender2D::getInstance()->pushMatrix(); + LLRender2D::pushMatrix(); { LLVector3 rect_origin = origin_agent + ((F32)rect.mLeft * x_axis) + ((F32)rect.mBottom * y_axis); - LLRender2D::getInstance()->translate(rect_origin.mV[VX], + LLRender2D::translate(rect_origin.mV[VX], rect_origin.mV[VY], rect_origin.mV[VZ]); gGL.getTexUnit(0)->bind(getImage()); @@ -103,7 +103,7 @@ void LLUIImage::draw3D(const LLVector3& origin_agent, const LLVector3& x_axis, c (F32)rect.getWidth() * x_axis, (F32)rect.getHeight() * y_axis); - } LLRender2D::getInstance()->popMatrix(); + } LLRender2D::popMatrix(); } //#include "lluiimage.inl" -- cgit v1.2.3 From 6aa9110b2ae346da1a396500cae1b41e8e2d5b75 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Thu, 11 Jul 2024 15:54:24 -0700 Subject: secondlife/viewer#1883: Local-only PBR terrain paintmap with developer tools --- indra/llrender/llshadermgr.cpp | 3 +++ indra/llrender/llshadermgr.h | 3 +++ 2 files changed, 6 insertions(+) (limited to 'indra/llrender') diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index bc542d325e..512ef340f9 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -1409,6 +1409,7 @@ void LLShaderMgr::initAttribsAndUniforms() mReservedUniforms.push_back("detail_3"); mReservedUniforms.push_back("alpha_ramp"); + mReservedUniforms.push_back("paint_map"); mReservedUniforms.push_back("detail_0_base_color"); mReservedUniforms.push_back("detail_1_base_color"); @@ -1433,6 +1434,8 @@ void LLShaderMgr::initAttribsAndUniforms() mReservedUniforms.push_back("emissiveColors"); mReservedUniforms.push_back("minimum_alphas"); + mReservedUniforms.push_back("region_scale"); + mReservedUniforms.push_back("origin"); mReservedUniforms.push_back("display_gamma"); diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h index 921ef20997..2b76ef664b 100644 --- a/indra/llrender/llshadermgr.h +++ b/indra/llrender/llshadermgr.h @@ -267,6 +267,7 @@ public: TERRAIN_DETAIL3, // "detail_3" TERRAIN_ALPHARAMP, // "alpha_ramp" + TERRAIN_PAINTMAP, // "paint_map" TERRAIN_DETAIL0_BASE_COLOR, // "detail_0_base_color" (GLTF) TERRAIN_DETAIL1_BASE_COLOR, // "detail_1_base_color" (GLTF) @@ -291,6 +292,8 @@ public: TERRAIN_EMISSIVE_COLORS, // "emissiveColors" (GLTF) TERRAIN_MINIMUM_ALPHAS, // "minimum_alphas" (GLTF) + REGION_SCALE, // "region_scale" (GLTF) + SHINY_ORIGIN, // "origin" DISPLAY_GAMMA, // "display_gamma" -- cgit v1.2.3 From 17f7b439d617bfdf4c865f1478ade662e86b61d2 Mon Sep 17 00:00:00 2001 From: Alexander Gavriliuk Date: Wed, 7 Aug 2024 20:56:10 +0200 Subject: #1922 Make PBR scale and offset crosshair work like Texture crosshair do --- indra/llrender/llrender.h | 19 +++++++++++-------- indra/llrender/llvertexbuffer.cpp | 12 ++++++++++++ indra/llrender/llvertexbuffer.h | 9 +++++---- 3 files changed, 28 insertions(+), 12 deletions(-) (limited to 'indra/llrender') diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index e6b4118beb..010ab122b6 100644 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -293,15 +293,18 @@ public: enum eTexIndex : U8 { - DIFFUSE_MAP = 0, - ALTERNATE_DIFFUSE_MAP = 1, - NORMAL_MAP = 1, - SPECULAR_MAP = 2, - BASECOLOR_MAP = 3, + // Channels for material textures + DIFFUSE_MAP = 0, + ALTERNATE_DIFFUSE_MAP = 1, + NORMAL_MAP = 1, + SPECULAR_MAP = 2, + // Channels for PBR textures + BASECOLOR_MAP = 3, METALLIC_ROUGHNESS_MAP = 4, - GLTF_NORMAL_MAP = 5, - EMISSIVE_MAP = 6, - NUM_TEXTURE_CHANNELS = 7, + GLTF_NORMAL_MAP = 5, + EMISSIVE_MAP = 6, + // Total number of channels + NUM_TEXTURE_CHANNELS = 7, }; enum eVolumeTexIndex : U8 diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 2eb7c21f77..02afcf12c6 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -794,6 +794,18 @@ void LLVertexBuffer::setLabel(const char* label) { } #endif +void LLVertexBuffer::clone(LLVertexBuffer& target) const +{ + target.mTypeMask = mTypeMask; + target.mIndicesType = mIndicesType; + target.mIndicesStride = mIndicesStride; + if (target.getNumVerts() != getNumVerts() || + target.getNumIndices() != getNumIndices()) + { + target.allocateBuffer(getNumVerts(), getNumIndices()); + } +} + void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const { llassert(validateRange(start, end, count, indices_offset)); diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index 49500e28ce..4ada0c335b 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -163,13 +163,13 @@ public: // set for rendering // assumes (and will assert on) the following: - // - this buffer has no pending unampBuffer call + // - this buffer has no pending unmapBuffer call // - a shader is currently bound // - This buffer has sufficient attributes within it to satisfy the needs of the currently bound shader void setBuffer(); // Only call each getVertexPointer, etc, once before calling unmapBuffer() - // call unmapBuffer() after calls to getXXXStrider() before any cals to setBuffer() + // call unmapBuffer() after calls to getXXXStrider() before any calls to setBuffer() // example: // vb->getVertexBuffer(verts); // vb->getNormalStrider(norms); @@ -218,12 +218,12 @@ public: U32 getNumIndices() const { return mNumIndices; } U32 getTypeMask() const { return mTypeMask; } - bool hasDataType(AttributeType type) const { return ((1 << type) & getTypeMask()); } + bool hasDataType(AttributeType type) const { return ((1 << type) & getTypeMask()); } U32 getSize() const { return mSize; } U32 getIndicesSize() const { return mIndicesSize; } U8* getMappedData() const { return mMappedData; } U8* getMappedIndices() const { return mMappedIndexData; } - U32 getOffset(AttributeType type) const { return mOffsets[type]; } + U32 getOffset(AttributeType type) const { return mOffsets[type]; } // these functions assume (and assert on) the current VBO being bound // Detailed error checking can be enabled by setting gDebugGL to true @@ -242,6 +242,7 @@ public: void setLabel(const char* label); #endif + void clone(LLVertexBuffer& target) const; protected: U32 mGLBuffer = 0; // GL VBO handle -- cgit v1.2.3 From ed6732eda8c80d17e05bbc6563b6ce08ef6b8c72 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 20 Aug 2024 06:59:07 -0500 Subject: #2315 Ensure textures are deleted when they are no longer referenced. (#2343) * #2315 WIP -- Clean up deletion rules in texture list. Incidental decruft. * Touch up assertions. * Move mLastReferencedTimer to LLViewerMediaTexture since it's no longer used by LLViewerTexture --- indra/llrender/llgltexture.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'indra/llrender') diff --git a/indra/llrender/llgltexture.h b/indra/llrender/llgltexture.h index a7de20dc5c..122d2a7f9c 100644 --- a/indra/llrender/llgltexture.h +++ b/indra/llrender/llgltexture.h @@ -82,8 +82,6 @@ public: typedef enum { DELETED = 0, //removed from memory - DELETION_CANDIDATE, //ready to be removed from memory - INACTIVE, //not be used for the last certain period (i.e., 30 seconds). ACTIVE, //just being used, can become inactive if not being used for a certain time (10 seconds). NO_DELETE = 99 //stay in memory, can not be removed. } LLGLTextureState; -- cgit v1.2.3 From 8406d1052c70d1d9f964ec86f6f5468aa9f57bb1 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 27 Aug 2024 11:53:54 -0500 Subject: #2428 Fix for crash when applying PBR material (#2430) Also attempt to fix some occasional bad texture memory tracking. --- indra/llrender/llimagegl.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'indra/llrender') diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 058afa0cf2..e4b176ff69 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -70,12 +70,15 @@ static U64 sTextureBytes = 0; void LLImageGLMemory::alloc_tex_image(U32 width, U32 height, U32 pixformat) { U32 texUnit = gGL.getCurrentTexUnitIndex(); + llassert(texUnit == 0); // allocations should always be done on tex unit 0 U32 texName = gGL.getTexUnit(texUnit)->getCurrTexture(); U64 size = LLImageGL::dataFormatBytes(pixformat, width, height); llassert(size >= 0); sTexMemMutex.lock(); + + // it is a precondition that no existing allocation exists for this texture llassert(sTextureAllocs.find(texName) == sTextureAllocs.end()); sTextureAllocs[texName] = size; @@ -89,7 +92,7 @@ void LLImageGLMemory::free_tex_image(U32 texName) { sTexMemMutex.lock(); auto iter = sTextureAllocs.find(texName); - if (iter != sTextureAllocs.end()) + if (iter != sTextureAllocs.end()) // sometimes a texName will be "freed" before allocated (e.g. first call to setManualImage for a given texName) { llassert(iter->second <= sTextureBytes); // sTextureBytes MUST NOT go below zero @@ -114,6 +117,7 @@ void LLImageGLMemory::free_tex_images(U32 count, const U32* texNames) void LLImageGLMemory::free_cur_tex_image() { U32 texUnit = gGL.getCurrentTexUnitIndex(); + llassert(texUnit == 0); // frees should always be done on tex unit 0 U32 texName = gGL.getTexUnit(texUnit)->getCurrTexture(); free_tex_image(texName); } @@ -1215,8 +1219,8 @@ void LLImageGL::deleteTextures(S32 numTextures, const U32 *textures) if (!sFreeList[idx].empty()) { - glDeleteTextures((GLsizei) sFreeList[idx].size(), sFreeList[idx].data()); free_tex_images((GLsizei) sFreeList[idx].size(), sFreeList[idx].data()); + glDeleteTextures((GLsizei)sFreeList[idx].size(), sFreeList[idx].data()); sFreeList[idx].resize(0); } } @@ -2405,7 +2409,7 @@ bool LLImageGL::scaleDown(S32 desired_discard) { // use a PBO to downscale the texture U64 size = getBytes(desired_discard); llassert(size <= 2048 * 2048 * 4); // we shouldn't be using this method to downscale huge textures, but it'll work - gGL.getTexUnit(0)->bind(this); + gGL.getTexUnit(0)->bind(this, false, true); if (sScratchPBO == 0) { -- cgit v1.2.3