summaryrefslogtreecommitdiff
path: root/indra/llrender
diff options
context:
space:
mode:
authorJonathan "Geenz" Goodman <geenz@geenzo.com>2026-07-22 00:38:54 -0400
committerJonathan "Geenz" Goodman <geenz@geenzo.com>2026-07-22 00:38:54 -0400
commit6b9f0f0bf43250f984631032a3f3b41d245907a9 (patch)
tree6cede3cddc362ff84cb46e16057c262919da28d9 /indra/llrender
parent91c11c8d87c963f2b17e45b525396bf8c8386c26 (diff)
Revert "Merge pull request #5982 from secondlife/geenz/texture-streaming-tweaks"
This reverts commit 3d465f6c966f0a2fcfd5d3c9effb6ce20c2754c8, reversing changes made to f2c356fc7130ce5e38b994dcfa1e210609b458b9.
Diffstat (limited to 'indra/llrender')
-rw-r--r--indra/llrender/llimagegl.cpp64
-rw-r--r--indra/llrender/llimagegl.h33
-rw-r--r--indra/llrender/llrender.cpp7
3 files changed, 19 insertions, 85 deletions
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index c8a23d873e..6bcc34938c 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -166,8 +166,6 @@ U64 LLImageGL::getTextureBytesAllocated()
//statics
U32 LLImageGL::sUniqueCount = 0;
-std::atomic<U32> LLImageGL::sOOMErrorCount(0);
-thread_local bool LLImageGL::sStampBindFrame = true;
U32 LLImageGL::sBindCount = 0;
S32 LLImageGL::sCount = 0;
@@ -493,7 +491,7 @@ bool LLImageGL::create(LLPointer<LLImageGL>& dest, const LLImageRaw* imageraw, b
//----------------------------------------------------------------------------
LLImageGL::LLImageGL(bool usemipmaps/* = true*/, bool allow_compression/* = true*/)
-: mExternalTexture(false)
+: mSaveData(0), mExternalTexture(false)
{
init(usemipmaps, allow_compression);
setSize(0, 0, 0);
@@ -502,7 +500,7 @@ LLImageGL::LLImageGL(bool usemipmaps/* = true*/, bool allow_compression/* = true
}
LLImageGL::LLImageGL(U32 width, U32 height, U8 components, bool usemipmaps/* = true*/, bool allow_compression/* = true*/)
-: mExternalTexture(false)
+: mSaveData(0), mExternalTexture(false)
{
llassert( components <= 4 );
init(usemipmaps, allow_compression);
@@ -512,7 +510,7 @@ LLImageGL::LLImageGL(U32 width, U32 height, U8 components, bool usemipmaps/* = t
}
LLImageGL::LLImageGL(const LLImageRaw* imageraw, bool usemipmaps/* = true*/, bool allow_compression/* = true*/)
-: mExternalTexture(false)
+: mSaveData(0), mExternalTexture(false)
{
init(usemipmaps, allow_compression);
setSize(0, 0, 0);
@@ -621,6 +619,8 @@ void LLImageGL::cleanup()
destroyGLTexture();
}
freePickMask();
+
+ mSaveData = NULL; // deletes data
}
//----------------------------------------------------------------------------
@@ -777,7 +777,6 @@ void LLImageGL::setImage(const LLImageRaw* imageraw)
bool LLImageGL::setImage(const U8* data_in, bool data_hasmips /* = false */, S32 usename /* = 0 */)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- LLImageGLStampBypass no_stamp; // upload binds are not visibility
const bool is_compressed = isCompressed();
@@ -1503,12 +1502,6 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt
{
free_cur_tex_image();
}
-
- // Drain stale GL errors so an OOM detected below belongs to this alloc.
- // Otherwise a failed glTexImage2D is swallowed in release while
- // alloc_tex_image still counts the bytes, inflating the used-VRAM figure.
- while (glGetError() != GL_NO_ERROR) {}
-
const bool use_sub_image = should_stagger_image_set(compress);
if (!use_sub_image)
{
@@ -1518,30 +1511,19 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt
else
{
// break up calls to a manageable size for the GL command buffer
- LL_PROFILE_ZONE_NAMED("glTexImage2D alloc");
- glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, nullptr);
- }
+ {
+ LL_PROFILE_ZONE_NAMED("glTexImage2D alloc");
+ glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, nullptr);
+ }
- if (glGetError() == GL_OUT_OF_MEMORY)
- {
- ++sOOMErrorCount;
- LL_WARNS_ONCE("Texture") << "glTexImage2D failed with GL_OUT_OF_MEMORY ("
- << width << "x" << height << " mip " << miplevel
- << ") - not counting bytes" << LL_ENDL;
- }
- else
- {
- if (use_sub_image)
+ U8* src = (U8*)(pixels);
+ if (src)
{
- U8* src = (U8*)(pixels);
- if (src)
- {
- LL_PROFILE_ZONE_NAMED("glTexImage2D copy");
- sub_image_lines(target, miplevel, 0, 0, width, height, pixformat, pixtype, src, width);
- }
+ LL_PROFILE_ZONE_NAMED("glTexImage2D copy");
+ sub_image_lines(target, miplevel, 0, 0, width, height, pixformat, pixtype, src, width);
}
- alloc_tex_image(width, height, intformat, 1);
}
+ alloc_tex_image(width, height, intformat, 1);
}
stop_glerror();
}
@@ -1686,7 +1668,6 @@ bool LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, bool data_
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
LL_PROFILE_GPU_ZONE("createGLTexture");
checkActiveThread();
- LLImageGLStampBypass no_stamp; // creation binds are not visibility
bool main_thread = on_main_thread();
@@ -2109,21 +2090,12 @@ S32 LLImageGL::dimDerivedMaxDiscard(S32 width, S32 height)
void LLImageGL::stampBound() const
{
- // Both stamps skip same-frame re-binds (bindFast runs per draw). They dedupe
- // separately, so a non-camera pass touching the time stamp first doesn't stop
- // a real camera bind from setting the frame stamp later the same frame.
+ // Skip the store on same-frame re-binds - bindFast is per-draw and
+ // would dirty this cache line per bind per texture otherwise.
if (mLastBindTime != sLastFrameTime)
{
mLastBindTime = sLastFrameTime;
}
- if (sStampBindFrame)
- {
- const U32 frame = LLFrameTimer::getFrameCount();
- if (mLastBindFrame != frame)
- {
- mLastBindFrame = frame;
- }
- }
}
S64 LLImageGL::getBytes(S32 discard_level) const
@@ -2548,10 +2520,6 @@ bool LLImageGL::scaleDown(S32 desired_discard)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- // Don't let eviction re-arm visibility: the glGenerateMipmap re-bind below
- // would otherwise stamp mLastBindFrame and keep the texture fetch-eligible.
- LLImageGLStampBypass no_stamp;
-
if (mTarget != GL_TEXTURE_2D
|| mFormatInternal == -1 // not initialized
)
diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h
index ca75b543c0..0c85446b84 100644
--- a/indra/llrender/llimagegl.h
+++ b/indra/llrender/llimagegl.h
@@ -39,7 +39,6 @@
#include "llrender.h"
#include "threadpool.h"
#include "workqueue.h"
-#include <atomic>
#include <unordered_set>
#define LL_IMAGEGL_THREAD_CHECK 0 //set to 1 to enable thread debugging for ImageGL
@@ -239,23 +238,15 @@ public:
public:
// Various GL/Rendering options
S64Bytes mTextureMemory;
- mutable F32 mLastBindTime = 0.f; // wall-clock time at last stampBound (bind or bind-attempt)
- mutable U32 mLastBindFrame = 0; // frame index (LLFrameTimer::getFrameCount) at last CAMERA-pass
- // stampBound; 0 = never. Drives visibility GC + fetch gating.
- F32 mGLCreateTime = 0.f; // wall-clock time the GL texture was created
-
- // When false, stampBound skips the mLastBindFrame stamp (mLastBindTime still
- // updates). Set false around non-camera passes (probes, shadows, impostors)
- // and administrative binds (upload, scaleDown - via LLImageGLStampBypass) so
- // those binds don't count as camera visibility. Thread-local so a GL upload
- // thread can't flip it on the render thread mid-frame.
- static thread_local bool sStampBindFrame;
+ mutable F32 mLastBindTime = 0.f; // wall-clock time at last stampBound; drives streaming staleness
+ F32 mGLCreateTime = 0.f; // wall-clock time the GL texture was created; staleness fallback for never-bound textures
private:
U32 createPickMask(S32 pWidth, S32 pHeight);
void freePickMask();
bool isCompressed();
+ LLPointer<LLImageRaw> mSaveData; // used for destroyGL/restoreGL
LL::WorkQueue::weak_t mMainQueue;
U8* mPickMask; //downsampled bitmap approximation of alpha channel. NULL if no alpha channel
U16 mPickMaskWidth;
@@ -309,11 +300,6 @@ public:
// Global memory statistics
static U32 sBindCount; // Tracks number of texture binds for current frame
static U32 sUniqueCount; // Tracks number of unique texture binds for current frame
- // glTexImage2D GL_OUT_OF_MEMORY failures detected (bytes NOT counted for
- // these). Written from whichever thread runs texture creation; read by
- // the streaming 1Hz pressure log. Nonzero = the driver is refusing
- // allocations and the VRAM budget is unreliable.
- static std::atomic<U32> sOOMErrorCount;
static bool sGlobalUseAnisotropic;
static LLImageGL* sDefaultGLTexture ;
static bool sAutomatedTest;
@@ -369,19 +355,6 @@ public:
};
-// RAII: suppress the mLastBindFrame stamp for the current scope. Use around
-// administrative binds (upload, create, scaleDown) so they don't count as
-// camera visibility - otherwise the GC's own scaleDown re-stamps what it just
-// aged out and oscillates. Saves/restores, so it nests correctly.
-class LLImageGLStampBypass
-{
-public:
- LLImageGLStampBypass() : mPrev(LLImageGL::sStampBindFrame) { LLImageGL::sStampBindFrame = false; }
- ~LLImageGLStampBypass() { LLImageGL::sStampBindFrame = mPrev; }
-private:
- bool mPrev;
-};
-
class LLImageGLThread : public LLSimpleton<LLImageGLThread>, LL::ThreadPool
{
public:
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index f0a1c44507..5e845fbcce 100644
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -245,11 +245,6 @@ bool LLTexUnit::bind(LLTexture* texture, bool for_rendering, bool forceBind)
texture->setActive() ;
texture->updateBindStatsForTester() ;
}
- // updateBindStats only stamps time; the GC and fetch gate use
- // the frame stamp, so stamp it here too or bind()-drawn faces
- // (bump/material/media) oscillate. Admin/non-camera binds are
- // already suppressed via LLImageGLStampBypass / sStampBindFrame.
- gl_tex->stampBound();
mHasMipMaps = gl_tex->mHasMipMaps;
if (gl_tex->mTexOptionsDirty)
{
@@ -330,8 +325,6 @@ bool LLTexUnit::bind(LLImageGL* texture, bool for_rendering, bool forceBind, S32
glBindTexture(sGLTextureType[texture->getTarget()], mCurrTexture);
stop_glerror();
texture->updateBindStats();
- // Frame-stamp fresh binds too - see bind(LLTexture*) above.
- texture->stampBound();
mHasMipMaps = texture->mHasMipMaps;
if (texture->mTexOptionsDirty)
{