diff options
| author | Jonathan "Geenz" Goodman <geenz@lindenlab.com> | 2026-08-14 17:10:28 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-08-14 17:10:28 -0400 |
| commit | 05a5a15c99bd1174736da66c58b7080c75a8acb8 (patch) | |
| tree | e73b7b75809ab21a1933b7cb9f78f4fc5271b061 /indra/llrender/llrender.cpp | |
| parent | a3c380acd9256102730574afb261aa6266f9a2a5 (diff) | |
| parent | 0007f7f99fc37b45ad7f3ad6df4238893c50a5be (diff) | |
Merge pull request #6132 from secondlife/geenz/linux-to-develop
Geenz/linux (and 26.3) to develop
Diffstat (limited to 'indra/llrender/llrender.cpp')
| -rw-r--r-- | indra/llrender/llrender.cpp | 154 |
1 files changed, 51 insertions, 103 deletions
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 0a9aa462d1..6a39a34c4e 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -38,7 +38,11 @@ #include "hbxxh.h" #include "glm/gtc/type_ptr.hpp" -#if LL_WINDOWS +#if GL_ARB_debug_output +#ifndef APIENTRY +#define APIENTRY +#endif + extern void APIENTRY gl_debug_callback(GLenum source, GLenum type, GLuint id, @@ -67,20 +71,12 @@ S32 gGLViewport[4]; U32 LLRender::sUICalls = 0; U32 LLRender::sUIVerts = 0; U32 LLTexUnit::sWhiteTexture = 0; +F32 LLRender::sAnisotropicFilteringLevel = 0.f; bool LLRender::sGLCoreProfile = false; bool LLRender::sNsightDebugSupport = false; LLVector2 LLRender::sUIGLScaleFactor = LLVector2(1.f, 1.f); bool LLRender::sClassicMode = false; -struct LLVBCache -{ - LLPointer<LLVertexBuffer> vb; - std::chrono::steady_clock::time_point touched; -}; - -static std::unordered_map<U64, LLVBCache> sVBCache; -static thread_local std::list<LLVertexBufferData> *sBufferDataList = nullptr; - static const GLenum sGLTextureType[] = { GL_TEXTURE_2D, @@ -197,6 +193,7 @@ void LLTexUnit::bindFast(LLTexture* texture) glActiveTexture(GL_TEXTURE0 + mIndex); gGL.mCurrTextureUnitIndex = mIndex; mCurrTexture = gl_tex->getTexName(); + mCurrTexType = gl_tex->getTarget(); if (!mCurrTexture) { LL_PROFILE_ZONE_NAMED("MISSING TEXTURE"); @@ -529,9 +526,11 @@ void LLTexUnit::setTextureFilteringOptionFast(LLTexUnit::eTextureFilterOptions o if (gGLManager.mHasAnisotropic) { - if (LLImageGL::sGlobalUseAnisotropic && option == TFO_ANISOTROPIC) + if (option == TFO_ANISOTROPIC && LLRender::sAnisotropicFilteringLevel > 1.f) { - glTexParameterf(sGLTextureType[tex_type], GL_TEXTURE_MAX_ANISOTROPY, gGLManager.mMaxAnisotropy); + F32 aniso_level = llclamp(LLRender::sAnisotropicFilteringLevel, 1.f, gGLManager.mMaxAnisotropy); + glTexParameterf(sGLTextureType[tex_type], GL_TEXTURE_MAX_ANISOTROPY, aniso_level); + } else { @@ -540,82 +539,6 @@ void LLTexUnit::setTextureFilteringOptionFast(LLTexUnit::eTextureFilterOptions o } } -GLint LLTexUnit::getTextureSource(eTextureBlendSrc src) -{ - switch(src) - { - // All four cases should return the same value. - case TBS_PREV_COLOR: - case TBS_PREV_ALPHA: - case TBS_ONE_MINUS_PREV_COLOR: - case TBS_ONE_MINUS_PREV_ALPHA: - return GL_PREVIOUS; - - // All four cases should return the same value. - case TBS_TEX_COLOR: - case TBS_TEX_ALPHA: - case TBS_ONE_MINUS_TEX_COLOR: - case TBS_ONE_MINUS_TEX_ALPHA: - return GL_TEXTURE; - - // All four cases should return the same value. - case TBS_VERT_COLOR: - case TBS_VERT_ALPHA: - case TBS_ONE_MINUS_VERT_COLOR: - case TBS_ONE_MINUS_VERT_ALPHA: - return GL_PRIMARY_COLOR; - - // All four cases should return the same value. - case TBS_CONST_COLOR: - case TBS_CONST_ALPHA: - case TBS_ONE_MINUS_CONST_COLOR: - case TBS_ONE_MINUS_CONST_ALPHA: - return GL_CONSTANT; - - default: - LL_WARNS() << "Unknown eTextureBlendSrc: " << src << ". Using Vertex Color instead." << LL_ENDL; - return GL_PRIMARY_COLOR; - } -} - -GLint LLTexUnit::getTextureSourceType(eTextureBlendSrc src, bool isAlpha) -{ - switch(src) - { - // All four cases should return the same value. - case TBS_PREV_COLOR: - case TBS_TEX_COLOR: - case TBS_VERT_COLOR: - case TBS_CONST_COLOR: - return (isAlpha) ? GL_SRC_ALPHA: GL_SRC_COLOR; - - // All four cases should return the same value. - case TBS_PREV_ALPHA: - case TBS_TEX_ALPHA: - case TBS_VERT_ALPHA: - case TBS_CONST_ALPHA: - return GL_SRC_ALPHA; - - // All four cases should return the same value. - case TBS_ONE_MINUS_PREV_COLOR: - case TBS_ONE_MINUS_TEX_COLOR: - case TBS_ONE_MINUS_VERT_COLOR: - case TBS_ONE_MINUS_CONST_COLOR: - return (isAlpha) ? GL_ONE_MINUS_SRC_ALPHA : GL_ONE_MINUS_SRC_COLOR; - - // All four cases should return the same value. - case TBS_ONE_MINUS_PREV_ALPHA: - case TBS_ONE_MINUS_TEX_ALPHA: - case TBS_ONE_MINUS_VERT_ALPHA: - case TBS_ONE_MINUS_CONST_ALPHA: - return GL_ONE_MINUS_SRC_ALPHA; - - default: - LL_WARNS() << "Unknown eTextureBlendSrc: " << src << ". Using Source Color or Alpha instead." << LL_ENDL; - return (isAlpha) ? GL_SRC_ALPHA: GL_SRC_COLOR; - } -} - // Useful for debugging that you've manually assigned a texture operation to the correct // texture unit based on the currently set active texture in opengl. void LLTexUnit::debugTextureUnit(void) @@ -845,7 +768,7 @@ LLRender::~LLRender() bool LLRender::init(bool needs_vertex_buffer) { -#if LL_WINDOWS +#if GL_ARB_debug_output && !LL_DARWIN if (gGLManager.mHasDebugOutput && gDebugGL) { //setup debug output callback //glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW_ARB, 0, NULL, GL_TRUE); @@ -899,7 +822,9 @@ void LLRender::initVertexBuffer() void LLRender::resetVertexBuffer() { - mBuffer = NULL; + mBuffer = nullptr; + mBufferDataList = nullptr; + mVBCache.clear(); } void LLRender::shutdown() @@ -1096,7 +1021,7 @@ void LLRender::syncMatrices() S32 loc = shader->getUniformLocation(LLShaderMgr::MODELVIEW_PROJECTION_MATRIX); if (loc > -1) { - if (cached_mvp_mdv_hash != mMatHash[MM_PROJECTION] || cached_mvp_proj_hash != mMatHash[MM_PROJECTION]) + if (cached_mvp_mdv_hash != mMatHash[MM_MODELVIEW] || cached_mvp_proj_hash != mMatHash[MM_PROJECTION]) { U32 mdv = MM_MODELVIEW; cached_mvp = mat; @@ -1506,21 +1431,21 @@ void LLRender::clearErrors() void LLRender::beginList(std::list<LLVertexBufferData> *list) { - if (sBufferDataList) + if (mBufferDataList) { LL_ERRS() << "beginList called while another list is open." << LL_ENDL; } llassert(LLGLSLShader::sCurBoundShaderPtr == &gUIProgram); flush(); - sBufferDataList = list; + mBufferDataList = list; } void LLRender::endList() { - if (sBufferDataList) + if (mBufferDataList) { flush(); - sBufferDataList = nullptr; + mBufferDataList = nullptr; } else { @@ -1608,10 +1533,10 @@ void LLRender::flush() U32 attribute_mask = LLGLSLShader::sCurBoundShaderPtr->mAttributeMask; - if (sBufferDataList) + if (mBufferDataList) { vb = genBuffer(attribute_mask, count); - sBufferDataList->emplace_back( + mBufferDataList->emplace_back( vb, mMode, count, @@ -1671,9 +1596,9 @@ LLVertexBuffer* LLRender::bufferfromCache(U32 attribute_mask, U32 count) // To leverage this, we maintain a running hash of the vertex stream being // built up before a flush, and then check that hash against a VB // cache just before creating a vertex buffer in VRAM - std::unordered_map<U64, LLVBCache>::iterator cache = sVBCache.find(vhash); + std::unordered_map<U64, LLVBCache>::iterator cache = mVBCache.find(vhash); - if (cache != sVBCache.end()) + if (cache != mVBCache.end()) { LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("vb cache hit"); // cache hit, just use the cached buffer @@ -1685,7 +1610,7 @@ LLVertexBuffer* LLRender::bufferfromCache(U32 attribute_mask, U32 count) LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("vb cache miss"); vb = genBuffer(attribute_mask, count); - sVBCache[vhash] = { vb , std::chrono::steady_clock::now() }; + mVBCache[vhash] = { vb , std::chrono::steady_clock::now() }; static U32 miss_count = 0; miss_count++; @@ -1697,11 +1622,11 @@ LLVertexBuffer* LLRender::bufferfromCache(U32 attribute_mask, U32 count) using namespace std::chrono_literals; // every 1024 misses, clean the cache of any VBs that haven't been touched in the last second - for (std::unordered_map<U64, LLVBCache>::iterator iter = sVBCache.begin(); iter != sVBCache.end(); ) + for (std::unordered_map<U64, LLVBCache>::iterator iter = mVBCache.begin(); iter != mVBCache.end(); ) { if (now - iter->second.touched > 1s) { - iter = sVBCache.erase(iter); + iter = mVBCache.erase(iter); } else { @@ -1718,7 +1643,16 @@ LLVertexBuffer* LLRender::genBuffer(U32 attribute_mask, S32 count) LLVertexBuffer * vb = new LLVertexBuffer(attribute_mask); vb->allocateBuffer(count, 0); - vb->setBuffer(); + // 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->setPositionData(mVerticesp.get()); @@ -1733,6 +1667,9 @@ 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(); @@ -2002,6 +1939,17 @@ void LLRender::diffuseColor4ub(U8 r, U8 g, U8 b, U8 a) } } +void LLRender::setLineWidth(F32 width) +{ + gGL.flush(); + + width = llclamp(width, gGLManager.mAliasedLineRange[0], gGLManager.mAliasedLineRange[1]); + if(mLineWidth != width) + { + mLineWidth = width; + glLineWidth(width); + } +} void LLRender::debugTexUnits(void) { |
