From a14b0752bedce56db7fad7983b95a4de32486432 Mon Sep 17 00:00:00 2001 From: Rye Mutt <rye@bred.dog> Date: Mon, 17 Aug 2020 22:31:56 -0400 Subject: [PATCH] Use texture swizzle instead of memcpy shenanigans when avail for gl core --- indra/llrender/llgl.cpp | 4 + indra/llrender/llgl.h | 1 + indra/llrender/llimagegl.cpp | 147 +++++++++++++++++++++-------------- 3 files changed, 95 insertions(+), 57 deletions(-) diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index 6968d77d88b..9c7be7cbb32 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -192,6 +192,7 @@ LLGLManager::LLGLManager() : mHasCubeMap(FALSE), mHasDebugOutput(FALSE), + mHasTextureSwizzle(false), mIsATI(FALSE), mIsNVIDIA(FALSE), mIsIntel(FALSE), @@ -799,6 +800,8 @@ void LLGLManager::initExtensions() mHasVertexShader = mGLVersion >= 2.0f || (epoxy_has_gl_extension("GL_ARB_vertex_program") && epoxy_has_gl_extension("GL_ARB_vertex_shader") && (LLRender::sGLCoreProfile || epoxy_has_gl_extension("GL_ARB_shading_language_100"))); mHasFragmentShader = mGLVersion >= 2.0f || (epoxy_has_gl_extension("GL_ARB_fragment_shader") && (LLRender::sGLCoreProfile || epoxy_has_gl_extension("GL_ARB_shading_language_100"))); + + mHasTextureSwizzle = mGLVersion >= 3.3f || epoxy_has_gl_extension("GL_ARB_texture_swizzle"); #endif #if LL_LINUX || LL_SOLARIS @@ -824,6 +827,7 @@ void LLGLManager::initExtensions() mHasShaderObjects = FALSE; mHasVertexShader = FALSE; mHasFragmentShader = FALSE; + mHasTextureSwizzle = FALSE; LL_WARNS("RenderInit") << "GL extension support DISABLED via LL_GL_NOEXT" << LL_ENDL; } else if (getenv("LL_GL_BASICEXT")) /* Flawfinder: ignore */ diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h index e0501caaaf3..f9e88f273c7 100644 --- a/indra/llrender/llgl.h +++ b/indra/llrender/llgl.h @@ -120,6 +120,7 @@ class LLGLManager BOOL mHassRGBTexture; BOOL mHassRGBFramebuffer; BOOL mHasTexturesRGBDecode; + bool mHasTextureSwizzle; // Vendor-specific extensions BOOL mIsATI; diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 951109125d0..8d02ab46bbc 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -1186,71 +1186,109 @@ static LLTrace::BlockTimerStatHandle FTM_SET_MANUAL_IMAGE("setManualImage"); void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels, bool allow_compression) { LL_RECORD_BLOCK_TIME(FTM_SET_MANUAL_IMAGE); - bool use_scratch = false; - U32* scratch = NULL; + std::vector<U32> scratch; if (LLRender::sGLCoreProfile) { - if (pixformat == GL_ALPHA && pixtype == GL_UNSIGNED_BYTE) - { //GL_ALPHA is deprecated, convert to RGBA - use_scratch = true; - scratch = new U32[width*height]; +#ifdef GL_ARB_texture_swizzle + if (gGLManager.mHasTextureSwizzle) + { + if (pixformat == GL_ALPHA) + { //GL_ALPHA is deprecated, convert to RGBA + const GLint mask[] = { GL_ZERO, GL_ZERO, GL_ZERO, GL_RED }; + glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, mask); + pixformat = GL_RED; + intformat = GL_R8; + } - U32 pixel_count = (U32) (width*height); - for (U32 i = 0; i < pixel_count; i++) - { - U8* pix = (U8*) &scratch[i]; - pix[0] = pix[1] = pix[2] = 0; - pix[3] = ((U8*) pixels)[i]; - } - - pixformat = GL_RGBA; - intformat = GL_RGBA8; + if (pixformat == GL_LUMINANCE) + { //GL_LUMINANCE is deprecated, convert to GL_RGBA + const GLint mask[] = { GL_RED, GL_RED, GL_RED, GL_ONE }; + glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, mask); + pixformat = GL_RED; + intformat = GL_R8; + } + + if (pixformat == GL_LUMINANCE_ALPHA) + { //GL_LUMINANCE_ALPHA is deprecated, convert to RGBA + const GLint mask[] = { GL_RED, GL_RED, GL_RED, GL_GREEN }; + glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, mask); + pixformat = GL_RG; + intformat = GL_RG8; + } } + else +#endif + { + if (pixformat == GL_ALPHA && pixtype == GL_UNSIGNED_BYTE) + { //GL_ALPHA is deprecated, convert to RGBA + scratch.resize(width * height); - if (pixformat == GL_LUMINANCE_ALPHA && pixtype == GL_UNSIGNED_BYTE) - { //GL_LUMINANCE_ALPHA is deprecated, convert to RGBA - use_scratch = true; - scratch = new U32[width*height]; + U32 pixel_count = (U32)(width * height); + for (U32 i = 0; i < pixel_count; i++) + { + U8* pix = (U8*)&scratch[i]; + pix[0] = pix[1] = pix[2] = 0; + pix[3] = ((U8*)pixels)[i]; + } - U32 pixel_count = (U32) (width*height); - for (U32 i = 0; i < pixel_count; i++) - { - U8 lum = ((U8*) pixels)[i*2+0]; - U8 alpha = ((U8*) pixels)[i*2+1]; + pixformat = GL_RGBA; + intformat = GL_RGBA8; + } - U8* pix = (U8*) &scratch[i]; - pix[0] = pix[1] = pix[2] = lum; - pix[3] = alpha; - } - - pixformat = GL_RGBA; - intformat = GL_RGBA8; - } + if (pixformat == GL_LUMINANCE_ALPHA && pixtype == GL_UNSIGNED_BYTE) + { //GL_LUMINANCE_ALPHA is deprecated, convert to RGBA + scratch.resize(width * height); - if (pixformat == GL_LUMINANCE && pixtype == GL_UNSIGNED_BYTE) - { //GL_LUMINANCE_ALPHA is deprecated, convert to RGB - use_scratch = true; - scratch = new U32[width*height]; + U32 pixel_count = (U32)(width * height); + for (U32 i = 0; i < pixel_count; i++) + { + U8 lum = ((U8*)pixels)[i * 2 + 0]; + U8 alpha = ((U8*)pixels)[i * 2 + 1]; - U32 pixel_count = (U32) (width*height); - for (U32 i = 0; i < pixel_count; i++) - { - U8 lum = ((U8*) pixels)[i]; - - U8* pix = (U8*) &scratch[i]; - pix[0] = pix[1] = pix[2] = lum; - pix[3] = 255; - } - - pixformat = GL_RGBA; - intformat = GL_RGB8; + U8* pix = (U8*)&scratch[i]; + pix[0] = pix[1] = pix[2] = lum; + pix[3] = alpha; + } + + pixels = &scratch[0]; + + pixformat = GL_RGBA; + intformat = GL_RGBA8; + } + + if (pixformat == GL_LUMINANCE && pixtype == GL_UNSIGNED_BYTE) + { //GL_LUMINANCE_ALPHA is deprecated, convert to RGB + scratch.resize(width * height); + + U32 pixel_count = (U32)(width * height); + for (U32 i = 0; i < pixel_count; i++) + { + U8 lum = ((U8*)pixels)[i]; + + U8* pix = (U8*)&scratch[i]; + pix[0] = pix[1] = pix[2] = lum; + pix[3] = 255; + } + + pixels = &scratch[0]; + + pixformat = GL_RGBA; + intformat = GL_RGB8; + } } } - if (LLImageGL::sCompressTextures && allow_compression) { switch (intformat) { + case GL_RED: + case GL_R8: + intformat = GL_COMPRESSED_RED; + break; + case GL_RG: + case GL_RG8: + intformat = GL_COMPRESSED_RG; + break; case GL_RGB: case GL_RGB8: intformat = GL_COMPRESSED_RGB; @@ -1280,19 +1318,14 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt intformat = GL_COMPRESSED_ALPHA; break; default: - LL_WARNS() << "Could not compress format: " << std::hex << intformat << LL_ENDL; + LL_WARNS() << "Could not compress format: " << std::hex << intformat << std::dec << LL_ENDL; break; } } stop_glerror(); - glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, use_scratch ? scratch : pixels); + glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, pixels); stop_glerror(); - - if (use_scratch) - { - delete [] scratch; - } } //create an empty GL texture: just create a texture name -- GitLab