diff options
Diffstat (limited to 'indra/llrender')
-rw-r--r-- | indra/llrender/llcubemaparray.cpp | 2 | ||||
-rw-r--r-- | indra/llrender/llgltexture.h | 2 | ||||
-rw-r--r-- | indra/llrender/llimagegl.cpp | 153 | ||||
-rw-r--r-- | indra/llrender/llimagegl.h | 4 | ||||
-rw-r--r-- | indra/llrender/llrender.cpp | 36 | ||||
-rw-r--r-- | indra/llrender/llrender.h | 17 | ||||
-rw-r--r-- | indra/llrender/llshadermgr.cpp | 22 | ||||
-rw-r--r-- | indra/llrender/llshadermgr.h | 16 | ||||
-rw-r--r-- | indra/llrender/llvertexbuffer.cpp | 35 | ||||
-rw-r--r-- | indra/llrender/llvertexbuffer.h | 2 |
10 files changed, 155 insertions, 134 deletions
diff --git a/indra/llrender/llcubemaparray.cpp b/indra/llrender/llcubemaparray.cpp index 52118172c0..ac48a633c7 100644 --- a/indra/llrender/llcubemaparray.cpp +++ b/indra/llrender/llcubemaparray.cpp @@ -122,7 +122,7 @@ void LLCubeMapArray::allocate(U32 resolution, U32 components, U32 count, BOOL us bind(0); - U32 format = components == 4 ? GL_RGBA12 : GL_RGB10; + U32 format = components == 4 ? GL_RGBA12 : GL_RGB16F; U32 mip = 0; diff --git a/indra/llrender/llgltexture.h b/indra/llrender/llgltexture.h index 8cfe7b62de..3732333f8f 100644 --- a/indra/llrender/llgltexture.h +++ b/indra/llrender/llgltexture.h @@ -49,10 +49,8 @@ public: enum EBoostLevel { BOOST_NONE = 0, - BOOST_ALM , //acts like NONE when ALM is on, max discard when ALM is off BOOST_AVATAR_BAKED , BOOST_AVATAR , - BOOST_CLOUDS , BOOST_SCULPTED , BOOST_HIGH = 10, diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index b3b79bd6c4..5b0690bc79 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -732,21 +732,8 @@ 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; - bool is_compressed = false; - switch (mFormatPrimary) - { - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: - case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: - case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: - is_compressed = true; - break; - default: - break; - } + const bool is_compressed = isCompressed(); if (mUseMipMaps) { @@ -1113,6 +1100,49 @@ void LLImageGL::postAddToAtlas() stop_glerror(); } +U32 type_width_from_pixtype(U32 pixtype) +{ + U32 type_width = 0; + switch (pixtype) + { + case GL_UNSIGNED_BYTE: + case GL_BYTE: + case GL_UNSIGNED_INT_8_8_8_8_REV: + type_width = 1; + break; + case GL_UNSIGNED_SHORT: + case GL_SHORT: + type_width = 2; + break; + case GL_UNSIGNED_INT: + case GL_INT: + case GL_FLOAT: + type_width = 4; + break; + default: + LL_ERRS() << "Unknown type: " << pixtype << LL_ENDL; + } + return type_width; +} + +// Equivalent to calling glSetSubImage2D(target, miplevel, x_offset, y_offset, width, height, pixformat, pixtype, src), assuming the total width of the image is data_width +// However, instead there are multiple calls to glSetSubImage2D on smaller slices of the image +void subImageLines(U32 target, S32 miplevel, S32 x_offset, S32 y_offset, S32 width, S32 height, U32 pixformat, U32 pixtype, const U8* src, S32 data_width) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; + + U32 components = LLImageGL::dataFormatComponents(pixformat); + U32 type_width = type_width_from_pixtype(pixtype); + + const U32 line_width = data_width * components * type_width; + const U32 y_offset_end = y_offset + height; + for (U32 y_pos = y_offset; y_pos < y_offset_end; ++y_pos) + { + glTexSubImage2D(target, miplevel, x_offset, y_pos, width, 1, pixformat, pixtype, src); + src += line_width; + } +} + BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update /* = FALSE */, LLGLuint use_name) { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; @@ -1187,13 +1217,29 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3 stop_glerror(); } - datap += (y_pos * data_width + x_pos) * getComponents(); + const U8* sub_datap = datap + (y_pos * data_width + x_pos) * getComponents(); // Update the GL texture BOOL res = gGL.getTexUnit(0)->bindManual(mBindTarget, tex_name); if (!res) LL_ERRS() << "LLImageGL::setSubImage(): bindTexture failed" << LL_ENDL; stop_glerror(); - glTexSubImage2D(mTarget, 0, x_pos, y_pos, width, height, mFormatPrimary, mFormatType, datap); +#if LL_DARWIN + const bool use_sub_image = false; +#else + const bool use_sub_image = !isCompressed(); +#endif + if (!use_sub_image) + { + // *TODO: Why does this work here, in setSubImage, but not in + // setManualImage? Maybe because it only gets called with the + // dimensions of the full image? Or because the image is never + // compressed? + glTexSubImage2D(mTarget, 0, x_pos, y_pos, width, height, mFormatPrimary, mFormatType, sub_datap); + } + else + { + subImageLines(mTarget, 0, x_pos, y_pos, width, height, mFormatPrimary, mFormatType, sub_datap, data_width); + } gGL.getTexUnit(0)->disable(); stop_glerror(); @@ -1359,7 +1405,8 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt } } - if (LLImageGL::sCompressTextures && allow_compression) + const bool compress = LLImageGL::sCompressTextures && allow_compression; + if (compress) { switch (intformat) { @@ -1408,50 +1455,33 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt LL_PROFILE_ZONE_NUM(height); free_cur_tex_image(); -#if 0 - glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, use_scratch ? scratch : pixels); +#if LL_DARWIN + const bool use_sub_image = false; #else - // break up calls to a manageable size for the GL command buffer + // glTexSubImage2D doesn't work with compressed textures on select tested Nvidia GPUs on Windows 10 -Cosmic,2023-03-08 + // *TODO: Small chance that glCompressedTexImage2D/glCompressedTexSubImage2D may work better here + const bool use_sub_image = !compress; +#endif + if (!use_sub_image) { - LL_PROFILE_ZONE_NAMED("glTexImage2D alloc"); - glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, nullptr); + LL_PROFILE_ZONE_NAMED("glTexImage2D alloc + copy"); + glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, use_scratch ? scratch : pixels); } - - U8* src = (U8*)(use_scratch ? scratch : pixels); - if (src) + else { - LL_PROFILE_ZONE_NAMED("glTexImage2D copy"); - U32 components = dataFormatComponents(pixformat); - U32 type_width = 0; - - switch (pixtype) + // break up calls to a manageable size for the GL command buffer { - case GL_UNSIGNED_BYTE: - case GL_BYTE: - case GL_UNSIGNED_INT_8_8_8_8_REV: - type_width = 1; - break; - case GL_UNSIGNED_SHORT: - case GL_SHORT: - type_width = 2; - break; - case GL_UNSIGNED_INT: - case GL_INT: - case GL_FLOAT: - type_width = 4; - break; - default: - LL_ERRS() << "Unknown type: " << pixtype << LL_ENDL; + LL_PROFILE_ZONE_NAMED("glTexImage2D alloc"); + glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, nullptr); } - U32 line_width = width * components * type_width; - for (U32 y = 0; y < height; ++y) + U8* src = (U8*)(use_scratch ? scratch : pixels); + if (src) { - glTexSubImage2D(target, miplevel, 0, y, width, 1, pixformat, pixtype, src); - src += line_width; + LL_PROFILE_ZONE_NAMED("glTexImage2D copy"); + subImageLines(target, miplevel, 0, 0, width, height, pixformat, pixtype, src, width); } } -#endif alloc_tex_image(width, height, pixformat); } stop_glerror(); @@ -2270,6 +2300,27 @@ void LLImageGL::freePickMask() mPickMaskWidth = mPickMaskHeight = 0; } +bool LLImageGL::isCompressed() +{ + llassert(mFormatPrimary != 0); + // *NOTE: Not all compressed formats are included here. + bool is_compressed = false; + switch (mFormatPrimary) + { + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: + is_compressed = true; + break; + default: + break; + } + return is_compressed; +} + //---------------------------------------------------------------------------- void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in) { diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index bbd024abd9..42f6efef77 100644 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -118,6 +118,9 @@ public: BOOL createGLTexture(S32 discard_level, const U8* data, BOOL data_hasmips = FALSE, S32 usename = 0, bool defer_copy = false, LLGLuint* tex_name = nullptr); void setImage(const LLImageRaw* imageraw); BOOL setImage(const U8* data_in, BOOL data_hasmips = FALSE, S32 usename = 0); + // *TODO: This function may not work if the textures is compressed (i.e. + // RenderCompressTextures is 0). Partial image updates do not work on + // compressed textures. BOOL setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update = FALSE, LLGLuint use_name = 0); BOOL setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update = FALSE, LLGLuint use_name = 0); BOOL setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_pos, S32 width, S32 height); @@ -211,6 +214,7 @@ public: private: U32 createPickMask(S32 pWidth, S32 pHeight); void freePickMask(); + bool isCompressed(); LLPointer<LLImageRaw> mSaveData; // used for destroyGL/restoreGL LL::WorkQueue::weak_t mMainQueue; diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index de74f2700a..8430d13093 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -70,9 +70,6 @@ bool LLRender::sGLCoreProfile = false; bool LLRender::sNsightDebugSupport = false; LLVector2 LLRender::sUIGLScaleFactor = LLVector2(1.f, 1.f); -static const U32 LL_NUM_TEXTURE_LAYERS = 32; -static const U32 LL_NUM_LIGHT_UNITS = 8; - struct LLVBCache { LLPointer<LLVertexBuffer> vb; @@ -823,16 +820,14 @@ LLRender::LLRender() mMode(LLRender::TRIANGLES), mCurrTextureUnitIndex(0) { - mTexUnits.reserve(LL_NUM_TEXTURE_LAYERS); for (U32 i = 0; i < LL_NUM_TEXTURE_LAYERS; i++) { - mTexUnits.push_back(new LLTexUnit(i)); + mTexUnits[i].mIndex = i; } - mDummyTexUnit = new LLTexUnit(-1); for (U32 i = 0; i < LL_NUM_LIGHT_UNITS; ++i) { - mLightState.push_back(new LLLightState(i)); + mLightState[i].mIndex = i; } for (U32 i = 0; i < 4; i++) @@ -915,19 +910,6 @@ void LLRender::resetVertexBuffer() void LLRender::shutdown() { - for (U32 i = 0; i < mTexUnits.size(); i++) - { - delete mTexUnits[i]; - } - mTexUnits.clear(); - delete mDummyTexUnit; - mDummyTexUnit = NULL; - - for (U32 i = 0; i < mLightState.size(); ++i) - { - delete mLightState[i]; - } - mLightState.clear(); resetVertexBuffer(); } @@ -939,10 +921,10 @@ void LLRender::refreshState(void) for (U32 i = 0; i < mTexUnits.size(); i++) { - mTexUnits[i]->refreshState(); + mTexUnits[i].refreshState(); } - mTexUnits[active_unit]->activate(); + mTexUnits[active_unit].activate(); setColorMask(mCurrColorMask[0], mCurrColorMask[1], mCurrColorMask[2], mCurrColorMask[3]); @@ -974,7 +956,7 @@ void LLRender::syncLightState() for (U32 i = 0; i < LL_NUM_LIGHT_UNITS; i++) { - LLLightState *light = mLightState[i]; + LLLightState *light = &mLightState[i]; position[i] = light->mPosition; direction[i] = light->mSpotDirection; @@ -992,7 +974,7 @@ void LLRender::syncLightState() shader->uniform3fv(LLShaderMgr::LIGHT_DIFFUSE, LL_NUM_LIGHT_UNITS, diffuse[0].mV); shader->uniform3fv(LLShaderMgr::LIGHT_AMBIENT, 1, mAmbientLightColor.mV); shader->uniform1i(LLShaderMgr::SUN_UP_FACTOR, sun_primary[0] ? 1 : 0); - shader->uniform3fv(LLShaderMgr::AMBIENT, 1, mAmbientLightColor.mV); + //shader->uniform3fv(LLShaderMgr::AMBIENT, 1, mAmbientLightColor.mV); shader->uniform3fv(LLShaderMgr::SUNLIGHT_COLOR, 1, diffuse[0].mV); shader->uniform3fv(LLShaderMgr::MOONLIGHT_COLOR, 1, diffuse_b[0].mV); } @@ -1501,12 +1483,12 @@ LLTexUnit* LLRender::getTexUnit(U32 index) { if (index < mTexUnits.size()) { - return mTexUnits[index]; + return &mTexUnits[index]; } else { LL_DEBUGS() << "Non-existing texture unit layer requested: " << index << LL_ENDL; - return mDummyTexUnit; + return &mDummyTexUnit; } } @@ -1514,7 +1496,7 @@ LLLightState* LLRender::getLight(U32 index) { if (index < mLightState.size()) { - return mLightState[index]; + return &mLightState[index]; } return NULL; diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index e8baf6bb7e..6f61627235 100644 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -52,6 +52,9 @@ class LLTexture ; #define LL_MATRIX_STACK_DEPTH 32 +constexpr U32 LL_NUM_TEXTURE_LAYERS = 32; +constexpr U32 LL_NUM_LIGHT_UNITS = 8; + class LLTexUnit { friend class LLRender; @@ -135,7 +138,7 @@ public: TCS_SRGB } eTextureColorSpace; - LLTexUnit(S32 index); + LLTexUnit(S32 index = -1); // Refreshes renderer state of the texture unit to the cached values // Needed when the render context has changed and invalidated the current state @@ -212,7 +215,9 @@ public: eTextureColorSpace getCurrColorSpace() { return mTexColorSpace; } protected: - const S32 mIndex; + friend class LLRender; + + S32 mIndex; U32 mCurrTexture; eTextureType mCurrTexType; eTextureColorSpace mTexColorSpace; @@ -230,7 +235,7 @@ protected: class LLLightState { public: - LLLightState(S32 index); + LLLightState(S32 index = -1); void enable(); void disable(); @@ -488,9 +493,9 @@ private: LLStrider<LLVector3> mVerticesp; LLStrider<LLVector2> mTexcoordsp; LLStrider<LLColor4U> mColorsp; - std::vector<LLTexUnit*> mTexUnits; - LLTexUnit* mDummyTexUnit; - std::vector<LLLightState*> mLightState; + std::array<LLTexUnit, LL_NUM_TEXTURE_LAYERS> mTexUnits; + LLTexUnit mDummyTexUnit; + std::array<LLLightState, LL_NUM_LIGHT_UNITS> mLightState; eBlendFactor mCurrBlendColorSFactor; eBlendFactor mCurrBlendColorDFactor; diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index c355115e8c..08a2e6779e 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -188,7 +188,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader) /////////////////////////////////////// // NOTE order of shader object attaching is VERY IMPORTANT!!! - if (features->hasSrgb || features->hasAtmospherics || features->calculatesAtmospherics) + if (features->hasSrgb || features->hasAtmospherics || features->calculatesAtmospherics || features->isDeferred) { if (!shader->attachFragmentObject("environment/srgbF.glsl")) { @@ -1074,20 +1074,12 @@ void LLShaderMgr::initAttribsAndUniforms() mReservedUniforms.push_back("object_plane_s"); mReservedUniforms.push_back("object_plane_t"); - mReservedUniforms.push_back("texture_base_color_scale"); // (GLTF) - mReservedUniforms.push_back("texture_base_color_rotation"); // (GLTF) - mReservedUniforms.push_back("texture_base_color_offset"); // (GLTF) - mReservedUniforms.push_back("texture_normal_scale"); // (GLTF) - mReservedUniforms.push_back("texture_normal_rotation"); // (GLTF) - mReservedUniforms.push_back("texture_normal_offset"); // (GLTF) - mReservedUniforms.push_back("texture_metallic_roughness_scale"); // (GLTF) - mReservedUniforms.push_back("texture_metallic_roughness_rotation"); // (GLTF) - mReservedUniforms.push_back("texture_metallic_roughness_offset"); // (GLTF) - mReservedUniforms.push_back("texture_emissive_scale"); // (GLTF) - mReservedUniforms.push_back("texture_emissive_rotation"); // (GLTF) - mReservedUniforms.push_back("texture_emissive_offset"); // (GLTF) - - llassert(mReservedUniforms.size() == LLShaderMgr::TEXTURE_EMISSIVE_OFFSET+1); + mReservedUniforms.push_back("texture_base_color_transform"); // (GLTF) + mReservedUniforms.push_back("texture_normal_transform"); // (GLTF) + mReservedUniforms.push_back("texture_metallic_roughness_transform"); // (GLTF) + mReservedUniforms.push_back("texture_emissive_transform"); // (GLTF) + + llassert(mReservedUniforms.size() == LLShaderMgr::TEXTURE_EMISSIVE_TRANSFORM+1); mReservedUniforms.push_back("viewport"); diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h index f7439a65af..93ea49d16a 100644 --- a/indra/llrender/llshadermgr.h +++ b/indra/llrender/llshadermgr.h @@ -53,18 +53,10 @@ public: OBJECT_PLANE_S, // "object_plane_s" OBJECT_PLANE_T, // "object_plane_t" - TEXTURE_BASE_COLOR_SCALE, // "texture_base_color_scale" (GLTF) - TEXTURE_BASE_COLOR_ROTATION, // "texture_base_color_rotation" (GLTF) - TEXTURE_BASE_COLOR_OFFSET, // "texture_base_color_offset" (GLTF) - TEXTURE_NORMAL_SCALE, // "texture_normal_scale" (GLTF) - TEXTURE_NORMAL_ROTATION, // "texture_normal_rotation" (GLTF) - TEXTURE_NORMAL_OFFSET, // "texture_normal_offset" (GLTF) - TEXTURE_METALLIC_ROUGHNESS_SCALE, // "texture_metallic_roughness_scale" (GLTF) - TEXTURE_METALLIC_ROUGHNESS_ROTATION,// "texture_metallic_roughness_rotation" (GLTF) - TEXTURE_METALLIC_ROUGHNESS_OFFSET, // "texture_metallic_roughness_offset" (GLTF) - TEXTURE_EMISSIVE_SCALE, // "texture_emissive_scale" (GLTF) - TEXTURE_EMISSIVE_ROTATION, // "texture_emissive_rotation" (GLTF) - TEXTURE_EMISSIVE_OFFSET, // "texture_emissive_offset" (GLTF) + TEXTURE_BASE_COLOR_TRANSFORM, // "texture_base_color_transform" (GLTF) + TEXTURE_NORMAL_TRANSFORM, // "texture_normal_transform" (GLTF) + TEXTURE_METALLIC_ROUGHNESS_TRANSFORM, // "texture_metallic_roughness_transform" (GLTF) + TEXTURE_EMISSIVE_TRANSFORM, // "texture_emissive_transform" (GLTF) VIEWPORT, // "viewport" LIGHT_POSITION, // "light_position" diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 11e2b6e5c4..dd0ea0096c 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -314,13 +314,16 @@ public: U32 mTouchCount = 0; -#if ANALYZE_VBO_POOL U64 mDistributed = 0; U64 mAllocated = 0; U64 mReserved = 0; U32 mMisses = 0; U32 mHits = 0; -#endif + + U64 getVramBytesUsed() + { + return mAllocated + mReserved; + } // increase the size to some common value (e.g. a power of two) to increase hit rate void adjustSize(U32& size) @@ -341,13 +344,9 @@ public: llassert(data == nullptr); // non null data indicates a buffer that wasn't freed llassert(size >= 2); // any buffer size smaller than a single index is nonsensical -#if ANALYZE_VBO_POOL mDistributed += size; adjustSize(size); mAllocated += size; -#else - adjustSize(size); -#endif auto& pool = type == GL_ELEMENT_ARRAY_BUFFER ? mIBOPool : mVBOPool; @@ -357,9 +356,7 @@ public: LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("vbo pool miss"); LL_PROFILE_GPU_ZONE("vbo alloc"); -#if ANALYZE_VBO_POOL mMisses++; -#endif name = gen_buffer(); glBindBuffer(type, name); glBufferData(type, size, nullptr, GL_DYNAMIC_DRAW); @@ -376,11 +373,9 @@ public: } else { -#if ANALYZE_VBO_POOL mHits++; llassert(mReserved >= size); // assert if accounting gets messed up mReserved -= size; -#endif std::list<Entry>& entries = iter->second; Entry& entry = entries.back(); @@ -407,16 +402,12 @@ public: clean(); -#if ANALYZE_VBO_POOL llassert(mDistributed >= size); mDistributed -= size; adjustSize(size); llassert(mAllocated >= size); mAllocated -= size; mReserved += size; -#else - adjustSize(size); -#endif auto& pool = type == GL_ELEMENT_ARRAY_BUFFER ? mIBOPool : mVBOPool; @@ -465,10 +456,8 @@ public: auto& entry = entries.back(); ll_aligned_free_16(entry.mData); glDeleteBuffers(1, &entry.mGLName); -#if ANALYZE_VBO_POOL llassert(mReserved >= iter->first); mReserved -= iter->first; -#endif entries.pop_back(); } @@ -484,7 +473,7 @@ public: } } -#if ANALYZE_VBO_POOL +#if 0 LL_INFOS() << llformat("(%d/%d)/%d MB (distributed/allocated)/total in VBO Pool. Overhead: %d percent. Hit rate: %d percent", mDistributed / 1000000, mAllocated / 1000000, @@ -515,9 +504,7 @@ public: } } -#if ANALYZE_VBO_POOL mReserved = 0; -#endif mIBOPool.clear(); mVBOPool.clear(); @@ -528,6 +515,12 @@ public: static LLVBOPool* sVBOPool = nullptr; +//static +U64 LLVertexBuffer::getBytesAllocated() +{ + return sVBOPool ? sVBOPool->getVramBytesUsed() : 0; +} + //============================================================================ // //static @@ -1363,7 +1356,9 @@ void LLVertexBuffer::setBuffer() U32 data_mask = LLGLSLShader::sCurBoundShaderPtr->mAttributeMask; // this Vertex Buffer must provide all necessary attributes for currently bound shader - llassert(((~data_mask & mTypeMask) > 0) || (mTypeMask == data_mask)); + llassert_msg((data_mask & mTypeMask) == data_mask, + "Attribute mask mismatch! mTypeMask should be a superset of data_mask. data_mask: 0x" + << std::hex << data_mask << " mTypeMask: 0x" << mTypeMask << " Missing: 0x" << (data_mask & ~mTypeMask) << std::dec); if (sGLRenderBuffer != mGLBuffer) { diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index 571856f013..f2d146d4bb 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -256,6 +256,8 @@ private: bool allocateBuffer(S32 nverts, S32 nindices, BOOL create) { return allocateBuffer(nverts, nindices); } public: + + static U64 getBytesAllocated(); static const U32 sTypeSize[TYPE_MAX]; static const U32 sGLMode[LLRender::NUM_MODES]; static U32 sGLRenderBuffer; |