diff options
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/llrender/llimagegl.cpp | 80 | ||||
| -rw-r--r-- | indra/llrender/llimagegl.h | 6 | 
2 files changed, 51 insertions, 35 deletions
| diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index b5c36ea35e..7c1cf2ba33 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -1113,6 +1113,45 @@ void LLImageGL::postAddToAtlas()  	stop_glerror();	  } +// Equivalent to calling glSetSubImage2D(target, miplevel, x_offset, y_offset, width, height, pixformat, pixtype, src) +// 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) +{ +    LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; + +    U32 components = LLImageGL::dataFormatComponents(pixformat); +    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; +    } + +    const U32 line_width = width * components * type_width; +    const U32 y_offset_end = y_offset + height; +    for (U32 y = y_offset; y < y_offset_end; ++y) +    { +        const S32 y_pos = y + y_offset; +        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; @@ -1193,6 +1232,10 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3  		if (!res) LL_ERRS() << "LLImageGL::setSubImage(): bindTexture failed" << LL_ENDL;  		stop_glerror(); +        // *TODO: glTexSubImage2D may not work on a subset of the texture if +        // the texture is compressed. Make sure the image isn't compressed +        // when using this function, then it's safe to replace this call with +        // subImageLines, when it is performant to do so (see setManualImage)  		glTexSubImage2D(mTarget, 0, x_pos, y_pos, width, height, mFormatPrimary, mFormatType, datap);  		gGL.getTexUnit(0)->disable();  		stop_glerror(); @@ -1359,7 +1402,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)          { @@ -1412,11 +1456,11 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt          const bool use_sub_image = false;  #else          // glTexSubImage2D doesn't work with compressed textures on select tested Nvidia GPUs on Windows 10 -Cosmic,2023-03-08 -        const bool use_sub_image = !allow_compression; +        const bool use_sub_image = !compress;  #endif          if (!use_sub_image)          { -            LL_PROFILE_ZONE_NAMED("glTexImage2D alloc"); +            LL_PROFILE_ZONE_NAMED("glTexImage2D alloc + copy");              glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, use_scratch ? scratch : pixels);          }          else @@ -1431,35 +1475,7 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt              if (src)              {                  LL_PROFILE_ZONE_NAMED("glTexImage2D copy"); -                U32 components = dataFormatComponents(pixformat); -                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; -                } - -                U32 line_width = width * components * type_width; -                for (U32 y = 0; y < height; ++y) -                { -                    glTexSubImage2D(target, miplevel, 0, y, width, 1, pixformat, pixtype, src); -                    src += line_width; -                } +                subImageLines(target, miplevel, 0, 0, width, height, pixformat, pixtype, src);              }          }          alloc_tex_image(width, height, pixformat); diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index a03233323b..08d8f60979 100644 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -118,9 +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); -    // *NOTE: force_fast_update should only be used if the texture is not -    // compressed (i.e. RenderCompressTextures is 0). Partial image updates -    // (glTexSubImage2D) do not work on compressed textures. +    // *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); | 
