Skip to content
Snippets Groups Projects
Commit f3eaf390 authored by Cosmic Linden's avatar Cosmic Linden
Browse files

SL-19338: Don't use glTexSubImage2D on compressed textures

parent 3773bac6
No related branches found
No related tags found
2 merge requests!3Update to main branch,!2Rebase onto current main branch
...@@ -1409,52 +1409,59 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt ...@@ -1409,52 +1409,59 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt
free_cur_tex_image(); free_cur_tex_image();
#if LL_DARWIN #if LL_DARWIN
{ const bool use_sub_image = false;
LL_PROFILE_ZONE_NAMED("glTexImage2D alloc");
glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, use_scratch ? scratch : pixels);
}
#else #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
const bool use_sub_image = !allow_compression;
#endif
if (!use_sub_image)
{ {
LL_PROFILE_ZONE_NAMED("glTexImage2D alloc"); LL_PROFILE_ZONE_NAMED("glTexImage2D alloc");
glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, nullptr); glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, use_scratch ? scratch : pixels);
} }
else
U8* src = (U8*)(use_scratch ? scratch : pixels);
if (src)
{ {
LL_PROFILE_ZONE_NAMED("glTexImage2D copy"); // break up calls to a manageable size for the GL command buffer
U32 components = dataFormatComponents(pixformat);
U32 type_width = 0;
switch (pixtype)
{ {
case GL_UNSIGNED_BYTE: LL_PROFILE_ZONE_NAMED("glTexImage2D alloc");
case GL_BYTE: glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, nullptr);
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; U8* src = (U8*)(use_scratch ? scratch : pixels);
for (U32 y = 0; y < height; ++y) if (src)
{ {
glTexSubImage2D(target, miplevel, 0, y, width, 1, pixformat, pixtype, src); LL_PROFILE_ZONE_NAMED("glTexImage2D copy");
src += line_width; 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;
}
} }
} }
#endif
alloc_tex_image(width, height, pixformat); alloc_tex_image(width, height, pixformat);
} }
stop_glerror(); stop_glerror();
......
...@@ -118,6 +118,9 @@ class LLImageGL : public LLRefCount ...@@ -118,6 +118,9 @@ class LLImageGL : public LLRefCount
BOOL createGLTexture(S32 discard_level, const U8* data, BOOL data_hasmips = FALSE, S32 usename = 0, bool defer_copy = false, LLGLuint* tex_name = nullptr); 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); void setImage(const LLImageRaw* imageraw);
BOOL setImage(const U8* data_in, BOOL data_hasmips = FALSE, S32 usename = 0); 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.
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 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 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); BOOL setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_pos, S32 width, S32 height);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment