diff options
Diffstat (limited to 'indra/llrender')
| -rw-r--r-- | indra/llrender/llgl.h | 3 | ||||
| -rw-r--r-- | indra/llrender/llimagegl.cpp | 126 | ||||
| -rw-r--r-- | indra/llrender/llimagegl.h | 5 | ||||
| -rw-r--r-- | indra/llrender/llrender.h | 6 | ||||
| -rw-r--r-- | indra/llrender/llrendertarget.cpp | 12 | ||||
| -rw-r--r-- | indra/llrender/llrendertarget.h | 4 | 
6 files changed, 120 insertions, 36 deletions
| 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<U32, U64> 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  } @@ -1186,12 +1189,36 @@ 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<U32> 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<LLImageGL*> 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<GLsizei>(mTex.size()), drawbuffers);      if (mTex.empty())      { //no color buffer to draw to          glDrawBuffer(GL_NONE);          glReadBuffer(GL_NONE);      } - +    else +    { +        glDrawBuffers(static_cast<GLsizei>(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 | 
