summaryrefslogtreecommitdiff
path: root/indra/llrender
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llrender')
-rw-r--r--indra/llrender/llimagegl.cpp96
-rw-r--r--indra/llrender/llimagegl.h17
-rw-r--r--indra/llrender/llrender.cpp29
3 files changed, 17 insertions, 125 deletions
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index 6bcc34938c..4a3d32c7ff 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -66,8 +66,8 @@ static LLMutex sTexMemMutex;
static std::unordered_map<U32, U64> sTextureAllocs;
static U64 sTextureBytes = 0;
-// Per-mip upload paths call this once per level; only free_tex_image
-// removes a texture's accounting entirely.
+// track a texture alloc on the currently bound texture.
+// asserts that no currently tracked alloc exists
void LLImageGLMemory::alloc_tex_image(U32 width, U32 height, U32 intformat, U32 count)
{
U32 texUnit = gGL.getCurrentTexUnitIndex();
@@ -80,43 +80,12 @@ void LLImageGLMemory::alloc_tex_image(U32 width, U32 height, U32 intformat, U32
sTexMemMutex.lock();
- auto iter = sTextureAllocs.find(texName);
- if (iter != sTextureAllocs.end())
- {
- iter->second += size;
- }
- else
- {
- sTextureAllocs[texName] = size;
- }
- sTextureBytes += size;
-
- sTexMemMutex.unlock();
-}
+ // it is a precondition that no existing allocation exists for this texture
+ llassert(sTextureAllocs.find(texName) == sTextureAllocs.end());
-// Add mip 1..N bytes to existing accounting. Use after glGenerateMipmap.
-void LLImageGLMemory::account_extra_mip_bytes(U32 base_width, U32 base_height, U32 intformat)
-{
- U64 extra = 0;
- U32 w = base_width;
- U32 h = base_height;
- while (w > 1 || h > 1)
- {
- w = w > 1 ? w >> 1 : 1;
- h = h > 1 ? h >> 1 : 1;
- extra += LLImageGL::dataFormatBytes(intformat, w, h);
- }
-
- U32 texUnit = gGL.getCurrentTexUnitIndex();
- U32 texName = gGL.getTexUnit(texUnit)->getCurrTexture();
+ sTextureAllocs[texName] = size;
+ sTextureBytes += size;
- sTexMemMutex.lock();
- auto iter = sTextureAllocs.find(texName);
- if (iter != sTextureAllocs.end())
- {
- iter->second += extra;
- sTextureBytes += extra;
- }
sTexMemMutex.unlock();
}
@@ -715,10 +684,7 @@ void LLImageGL::dump()
//----------------------------------------------------------------------------
void LLImageGL::forceUpdateBindStats(void) const
{
- // Intentionally a no-op: mLastBindTime is written only by real bind
- // paths so the staleness signal reflects actual GPU use. Callers that
- // still invoke this (avatar "keep alive" sites, deleted-texture
- // fallback) no longer falsely refresh staleness.
+ mLastBindTime = sLastFrameTime;
}
bool LLImageGL::updateBindStats() const
@@ -872,7 +838,7 @@ bool LLImageGL::setImage(const U8* data_in, bool data_hasmips /* = false */, S32
mMipLevels = wpo2(llmax(w, h));
//use legacy mipmap generation mode (note: making this condional can cause rendering issues)
- // - but making it not conditional triggers deprecation warnings when core profile is enabled
+ // -- but making it not conditional triggers deprecation warnings when core profile is enabled
// (some rendering issues while core profile is enabled are acceptable at this point in time)
if (!LLRender::sGLCoreProfile)
{
@@ -898,7 +864,6 @@ bool LLImageGL::setImage(const U8* data_in, bool data_hasmips /* = false */, S32
{
LL_PROFILE_GPU_ZONE("generate mip map");
glGenerateMipmap(mTarget);
- account_extra_mip_bytes(w, h, mFormatInternal);
}
stop_glerror();
}
@@ -1496,12 +1461,7 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt
LL_PROFILE_ZONE_NUM(width);
LL_PROFILE_ZONE_NUM(height);
- // Release prior accounting only on the base mip; per-mip iteration
- // accumulates the rest via the additive alloc_tex_image.
- if (miplevel == 0)
- {
- free_cur_tex_image();
- }
+ free_cur_tex_image();
const bool use_sub_image = should_stagger_image_set(compress);
if (!use_sub_image)
{
@@ -1653,6 +1613,7 @@ bool LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S
{
destroyGLTexture();
mCurrentDiscardLevel = discard_level;
+ mLastBindTime = sLastFrameTime;
mGLTextureCreated = false;
return true ;
}
@@ -1768,7 +1729,9 @@ bool LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, bool data_
mTextureMemory = (S64Bytes)getMipBytes(mCurrentDiscardLevel);
- mGLCreateTime = sLastFrameTime;
+
+ // mark this as bound at this point, so we don't throw it out immediately
+ mLastBindTime = sLastFrameTime;
checkActiveThread();
return true;
@@ -1895,7 +1858,7 @@ bool LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre
LLGLint is_compressed = 0;
if (compressed_ok)
{
- glGetTexLevelParameteriv(mTarget, gl_discard, GL_TEXTURE_COMPRESSED, (GLint*)&is_compressed);
+ glGetTexLevelParameteriv(mTarget, is_compressed, GL_TEXTURE_COMPRESSED, (GLint*)&is_compressed);
}
//-----------------------------------------------------------------------------------------------
@@ -2076,28 +2039,6 @@ S32 LLImageGL::getWidth(S32 discard_level) const
return width;
}
-// static
-S32 LLImageGL::dimDerivedMaxDiscard(S32 width, S32 height)
-{
- if (width <= 0 || height <= 0)
- {
- return 0;
- }
- // max(w,h) - min() caps short on rectangular textures
- // (1024x512 reaches 1x1 at discard 10, not 9).
- return (S32)floorf(log2f((F32)llmax(width, height)));
-}
-
-void LLImageGL::stampBound() const
-{
- // 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;
- }
-}
-
S64 LLImageGL::getBytes(S32 discard_level) const
{
if (discard_level < 0)
@@ -2527,12 +2468,7 @@ bool LLImageGL::scaleDown(S32 desired_discard)
return false;
}
- // GL pyramid reaches 1x1 regardless of codec levels;
- // mMaxDiscardLevel is hardcapped at MAX_DISCARD_LEVEL.
- S32 dim_max_discard = (mWidth > 0 && mHeight > 0)
- ? dimDerivedMaxDiscard(mWidth, mHeight)
- : (S32)mMaxDiscardLevel;
- desired_discard = llmin(desired_discard, dim_max_discard);
+ desired_discard = llmin(desired_discard, mMaxDiscardLevel);
if (desired_discard <= mCurrentDiscardLevel)
{
@@ -2565,7 +2501,6 @@ bool LLImageGL::scaleDown(S32 desired_discard)
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("scaleDown - glGenerateMipmap");
gGL.getTexUnit(0)->bind(this);
glGenerateMipmap(mTarget);
- account_extra_mip_bytes(desired_width, desired_height, mFormatInternal);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
}
}
@@ -2611,7 +2546,6 @@ bool LLImageGL::scaleDown(S32 desired_discard)
{
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("scaleDown - glGenerateMipmap");
glGenerateMipmap(mTarget);
- account_extra_mip_bytes(desired_width, desired_height, mFormatInternal);
}
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h
index 0c85446b84..6b4492c09e 100644
--- a/indra/llrender/llimagegl.h
+++ b/indra/llrender/llimagegl.h
@@ -51,11 +51,6 @@ class LLWindow;
namespace LLImageGLMemory
{
void alloc_tex_image(U32 width, U32 height, U32 intformat, U32 count);
-
- // Add mip 1..N bytes to existing accounting. Call after glGenerateMipmap
- // when only the base mip was accounted; without this the bytes counter
- // undercounts mipmap-generated textures by ~25%.
- void account_extra_mip_bytes(U32 base_width, U32 base_height, U32 intformat);
void free_tex_image(U32 texName);
void free_tex_images(U32 count, const U32* texNames);
void free_cur_tex_image();
@@ -156,15 +151,6 @@ public:
S32 getDiscardLevel() const { return mCurrentDiscardLevel; }
S32 getMaxDiscardLevel() const { return mMaxDiscardLevel; }
- // floor(log2(max(w, h))) - deepest GL pyramid level (down to 1x1).
- // Returns 0 for non-positive inputs.
- static S32 dimDerivedMaxDiscard(S32 width, S32 height);
-
- // Record the wall-clock bind time - every bind path that touches a
- // streaming-managed texture must call this, or the staleness signal
- // sees the texture as never-bound and ramps it toward eviction.
- void stampBound() const;
-
// 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; }
@@ -238,8 +224,7 @@ public:
public:
// Various GL/Rendering options
S64Bytes mTextureMemory;
- 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
+ mutable F32 mLastBindTime; // last time this was bound, by discard level
private:
U32 createPickMask(S32 pWidth, S32 pHeight);
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index 5e845fbcce..57be8570af 100644
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -197,10 +197,6 @@ void LLTexUnit::bindFast(LLTexture* texture)
glActiveTexture(GL_TEXTURE0 + mIndex);
gGL.mCurrTextureUnitIndex = mIndex;
mCurrTexture = gl_tex->getTexName();
- mCurrTexType = gl_tex->getTarget();
- // bindFast bypasses updateBindStats(); stamp directly so the staleness
- // signal sees per-frame use of batched textures.
- gl_tex->stampBound();
if (!mCurrTexture)
{
LL_PROFILE_ZONE_NAMED("MISSING TEXTURE");
@@ -253,17 +249,11 @@ bool LLTexUnit::bind(LLTexture* texture, bool for_rendering, bool forceBind)
setTextureFilteringOption(gl_tex->mFilterOption);
}
}
- else
- {
- // Already current - still being used, keep it fresh.
- gl_tex->stampBound();
- }
}
else
{
//if deleted, will re-generate it immediately
texture->forceImmediateUpdate() ;
- gl_tex->stampBound();
gl_tex->forceUpdateBindStats() ;
return texture->bindDefaultImage(mIndex);
@@ -335,11 +325,6 @@ bool LLTexUnit::bind(LLImageGL* texture, bool for_rendering, bool forceBind, S32
stop_glerror();
}
}
- else
- {
- // Already current - still being used, keep it fresh.
- texture->stampBound();
- }
stop_glerror();
@@ -1733,16 +1718,7 @@ LLVertexBuffer* LLRender::genBuffer(U32 attribute_mask, S32 count)
LLVertexBuffer * vb = new LLVertexBuffer(attribute_mask);
vb->allocateBuffer(count, 0);
- // Non-Apple path uses glBufferSubData inside setXxxData, so the VBO
- // must already be bound. On Apple, the VBO is lazily created in
- // _unmapBuffer (LLAppleVBOPool); calling setBuffer() here would bind
- // mGLBuffer == 0 and then setupVertexBuffer would issue
- // glVertexAttribIPointer with a non-null offset against no bound
- // GL_ARRAY_BUFFER -> GL_INVALID_OPERATION in core profile.
- if (!gGLManager.mIsApple)
- {
- vb->setBuffer();
- }
+ vb->setBuffer();
vb->setPositionData(mVerticesp.get());
@@ -1757,9 +1733,6 @@ LLVertexBuffer* LLRender::genBuffer(U32 attribute_mask, S32 count)
}
#if LL_DARWIN
- // unmapBuffer creates the GL buffer, uploads, and leaves it bound,
- // drawBuffer's later setBuffer() then runs setupVertexBuffer against
- // a valid VBO.
vb->unmapBuffer();
#endif
vb->unbind();