diff options
| author | Jonathan "Geenz" Goodman <geenz@geenzo.com> | 2023-03-13 08:06:17 -0700 | 
|---|---|---|
| committer | Jonathan "Geenz" Goodman <geenz@geenzo.com> | 2023-03-13 08:06:17 -0700 | 
| commit | 75dea34e3f80b054c56c38c880166d5e610eef88 (patch) | |
| tree | 8a8a54cb3e446213b33dcdd64c0c89d3c47369b4 /indra | |
| parent | f3ce17701e8dbbbc7a0e8e73c740b161bb2f36c0 (diff) | |
| parent | 0e178e12562b95915a9a775cd40d3bb44729332c (diff) | |
Merge branch 'DRTVWR-559' of https://github.com/secondlife/viewer into DRTVWR-559
Diffstat (limited to 'indra')
70 files changed, 1705 insertions, 1699 deletions
| diff --git a/indra/llcommon/llcommon.cpp b/indra/llcommon/llcommon.cpp index d2c4e66160..6e988260a9 100644 --- a/indra/llcommon/llcommon.cpp +++ b/indra/llcommon/llcommon.cpp @@ -37,12 +37,13 @@ thread_local bool gProfilerEnabled = false;  #if (TRACY_ENABLE)  // Override new/delete for tracy memory profiling -void *operator new(size_t size) + +void* ll_tracy_new(size_t size)  {      void* ptr;      if (gProfilerEnabled)      { -        LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY; +        //LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY;          ptr = (malloc)(size);      }      else @@ -57,12 +58,22 @@ void *operator new(size_t size)      return ptr;  } -void operator delete(void *ptr) noexcept +void* operator new(size_t size) +{ +    return ll_tracy_new(size); +} + +void* operator new[](std::size_t count) +{ +    return ll_tracy_new(count); +} + +void ll_tracy_delete(void* ptr)  {      TracyFree(ptr);      if (gProfilerEnabled)      { -        LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY; +        //LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY;          (free)(ptr);      }      else @@ -71,6 +82,16 @@ void operator delete(void *ptr) noexcept      }  } +void operator delete(void *ptr) noexcept +{ +    ll_tracy_delete(ptr); +} + +void operator delete[](void* ptr) noexcept +{ +    ll_tracy_delete(ptr); +} +  // C-style malloc/free can't be so easily overridden, so we define tracy versions and use  // a pre-processor #define in linden_common.h to redirect to them. The parens around the native  // functions below prevents recursive substitution by the preprocessor. diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h index d06c0e2132..b7dec3cb7f 100644 --- a/indra/llcommon/llerror.h +++ b/indra/llcommon/llerror.h @@ -82,9 +82,11 @@ const int LL_ERR_NOERR = 0;  #ifdef SHOW_ASSERT  #define llassert(func)			llassert_always_msg(func, #func) +#define llassert_msg(func, msg)	llassert_always_msg(func, msg)  #define llverify(func)			llassert_always_msg(func, #func)  #else  #define llassert(func) +#define llassert_msg(func, msg)  #define llverify(func)			do {if (func) {}} while(0)  #endif diff --git a/indra/llcommon/llprofiler.h b/indra/llcommon/llprofiler.h index 394fbd05f6..736a069f49 100644 --- a/indra/llcommon/llprofiler.h +++ b/indra/llcommon/llprofiler.h @@ -138,10 +138,6 @@ extern thread_local bool gProfilerEnabled;          #define LL_PROFILE_ZONE_ERR(name)               LL_PROFILE_ZONE_NAMED_COLOR( name, 0XFF0000  )  // RGB yellow          #define LL_PROFILE_ZONE_INFO(name)              LL_PROFILE_ZONE_NAMED_COLOR( name, 0X00FFFF  )  // RGB cyan          #define LL_PROFILE_ZONE_WARN(name)              LL_PROFILE_ZONE_NAMED_COLOR( name, 0x0FFFF00 )  // RGB red -        //#define LL_PROFILE_ALLOC(ptr, size)             TracyAlloc(ptr, size) // memory allocation tracking currently not working -        //#define LL_PROFILE_FREE(ptr)                    TracyFree(ptr) -        #define LL_PROFILE_ALLOC(ptr, size)             (void)(ptr); (void)(size); -        #define LL_PROFILE_FREE(ptr)                    (void)(ptr);      #endif  #else      #define LL_PROFILER_FRAME_END @@ -165,7 +161,7 @@ extern thread_local bool gProfilerEnabled;  #define LL_LABEL_OBJECT_GL(type, name, length, label) -#if LL_PROFILER_CONFIG > 1 +#if LL_PROFILER_CONFIGURATION > 1  #define LL_PROFILE_ALLOC(ptr, size)             TracyAlloc(ptr, size)  #define LL_PROFILE_FREE(ptr)                    TracyFree(ptr)  #else diff --git a/indra/llcommon/llprofilercategories.h b/indra/llcommon/llprofilercategories.h index 8db29468cc..617431f629 100644 --- a/indra/llcommon/llprofilercategories.h +++ b/indra/llcommon/llprofilercategories.h @@ -52,7 +52,7 @@  #define LL_PROFILER_CATEGORY_ENABLE_LOGGING     1  #define LL_PROFILER_CATEGORY_ENABLE_MATERIAL    1  #define LL_PROFILER_CATEGORY_ENABLE_MEDIA       1 -#define LL_PROFILER_CATEGORY_ENABLE_MEMORY      1 +#define LL_PROFILER_CATEGORY_ENABLE_MEMORY      0  #define LL_PROFILER_CATEGORY_ENABLE_NETWORK     1  #define LL_PROFILER_CATEGORY_ENABLE_OCTREE      1  #define LL_PROFILER_CATEGORY_ENABLE_PIPELINE    1 diff --git a/indra/llcommon/lluuid.cpp b/indra/llcommon/lluuid.cpp index fc04dca08d..3619a64ea9 100644 --- a/indra/llcommon/lluuid.cpp +++ b/indra/llcommon/lluuid.cpp @@ -1,31 +1,31 @@ -/**  +/**   * @file lluuid.cpp   *   * $LicenseInfo:firstyear=2000&license=viewerlgpl$   * Second Life Viewer Source Code   * Copyright (C) 2010, Linden Research, Inc. - *  + *   * This library is free software; you can redistribute it and/or   * modify it under the terms of the GNU Lesser General Public   * License as published by the Free Software Foundation;   * version 2.1 of the License only. - *  + *   * This library is distributed in the hope that it will be useful,   * but WITHOUT ANY WARRANTY; without even the implied warranty of   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU   * Lesser General Public License for more details. - *  + *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA - *  + *   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */  #include "linden_common.h" -// We can't use WIN32_LEAN_AND_MEAN here, needs lots of includes. + // We can't use WIN32_LEAN_AND_MEAN here, needs lots of includes.  #if LL_WINDOWS  #include "llwin32headers.h"  // ugh, this is ugly.  We need to straighten out our linking for this library @@ -40,18 +40,17 @@  #include "lluuid.h"  #include "llerror.h"  #include "llrand.h" +#include "llmd5.h"  #include "llstring.h"  #include "lltimer.h"  #include "llthread.h"  #include "llmutex.h" -#include "llmd5.h" -#include "hbxxh.h"  const LLUUID LLUUID::null;  const LLTransactionID LLTransactionID::tnull;  // static  -LLMutex * LLUUID::mMutex = NULL; +LLMutex* LLUUID::mMutex = NULL; @@ -60,15 +59,15 @@ LLMutex * LLUUID::mMutex = NULL;  NOT DONE YET!!!  static char BASE85_TABLE[] = { -	'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', -	'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', -	'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', -	'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', -	'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', -	'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', -	'y', 'z', '!', '#', '$', '%', '&', '(', ')', '*', -	'+', '-', ';', '[', '=', '>', '?', '@', '^', '_', -	'`', '{', '|', '}', '~', '\0' +    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', +    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', +    'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', +    'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', +    'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', +    'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', +    'y', 'z', '!', '#', '$', '%', '&', '(', ')', '*', +    '+', '-', ';', '[', '=', '>', '?', '@', '^', '_', +    '`', '{', '|', '}', '~', '\0'  }; @@ -94,28 +93,28 @@ return ret;  void LLUUID::toBase85(char* out)  { -	U32* me = (U32*)&(mData[0]); -	for(S32 i = 0; i < 4; ++i) -	{ -		char* o = &out[i*i]; -		for(S32 j = 0; j < 5; ++j) -		{ -			o[4-j] = BASE85_TABLE[ me[i] % 85]; -			word /= 85; -		} -	} +    U32* me = (U32*)&(mData[0]); +    for(S32 i = 0; i < 4; ++i) +    { +        char* o = &out[i*i]; +        for(S32 j = 0; j < 5; ++j) +        { +            o[4-j] = BASE85_TABLE[ me[i] % 85]; +            word /= 85; +        } +    }  }  unsigned int decode( char const * fiveChars ) throw( bad_input_data )  { -	unsigned int ret = 0; -	for( S32 ix = 0; ix < 5; ++ix ) -	{ -		char * s = strchr( encodeTable, fiveChars[ ix ] ); -		ret = ret * 85 + (s-encodeTable); -	} -	return ret; -}  +    unsigned int ret = 0; +    for( S32 ix = 0; ix < 5; ++ix ) +    { +        char * s = strchr( encodeTable, fiveChars[ ix ] ); +        ret = ret * 85 + (s-encodeTable); +    } +    return ret; +}  */  #define LL_USE_JANKY_RANDOM_NUMBER_GENERATOR 0 @@ -130,8 +129,8 @@ static U64 sJankyRandomSeed(LLUUID::getRandomSeed());   */  U32 janky_fast_random_bytes()  { -	sJankyRandomSeed = U64L(1664525) * sJankyRandomSeed + U64L(1013904223);  -	return (U32)sJankyRandomSeed; +    sJankyRandomSeed = U64L(1664525) * sJankyRandomSeed + U64L(1013904223); +    return (U32)sJankyRandomSeed;  }  /** @@ -139,8 +138,8 @@ U32 janky_fast_random_bytes()   */  U32 janky_fast_random_byes_range(U32 val)  { -	sJankyRandomSeed = U64L(1664525) * sJankyRandomSeed + U64L(1013904223);  -	return (U32)(sJankyRandomSeed) % val;  +    sJankyRandomSeed = U64L(1664525) * sJankyRandomSeed + U64L(1013904223); +    return (U32)(sJankyRandomSeed) % val;  }  /** @@ -148,365 +147,362 @@ U32 janky_fast_random_byes_range(U32 val)   */  U32 janky_fast_random_seeded_bytes(U32 seed, U32 val)  { -	seed = U64L(1664525) * (U64)(seed) + U64L(1013904223);  -	return (U32)(seed) % val;  +    seed = U64L(1664525) * (U64)(seed)+U64L(1013904223); +    return (U32)(seed) % val;  }  #endif  // Common to all UUID implementations  void LLUUID::toString(std::string& out) const  { -	out = llformat( -		"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", -		(U8)(mData[0]), -		(U8)(mData[1]), -		(U8)(mData[2]), -		(U8)(mData[3]), -		(U8)(mData[4]), -		(U8)(mData[5]), -		(U8)(mData[6]), -		(U8)(mData[7]), -		(U8)(mData[8]), -		(U8)(mData[9]), -		(U8)(mData[10]), -		(U8)(mData[11]), -		(U8)(mData[12]), -		(U8)(mData[13]), -		(U8)(mData[14]), -		(U8)(mData[15])); +    out = llformat( +        "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", +        (U8)(mData[0]), +        (U8)(mData[1]), +        (U8)(mData[2]), +        (U8)(mData[3]), +        (U8)(mData[4]), +        (U8)(mData[5]), +        (U8)(mData[6]), +        (U8)(mData[7]), +        (U8)(mData[8]), +        (U8)(mData[9]), +        (U8)(mData[10]), +        (U8)(mData[11]), +        (U8)(mData[12]), +        (U8)(mData[13]), +        (U8)(mData[14]), +        (U8)(mData[15]));  }  // *TODO: deprecate -void LLUUID::toString(char *out) const +void LLUUID::toString(char* out) const  { -	std::string buffer; -	toString(buffer); -	strcpy(out,buffer.c_str()); /* Flawfinder: ignore */ +    std::string buffer; +    toString(buffer); +    strcpy(out, buffer.c_str()); /* Flawfinder: ignore */  }  void LLUUID::toCompressedString(std::string& out) const  { -	char bytes[UUID_BYTES+1]; -	memcpy(bytes, mData, UUID_BYTES);		/* Flawfinder: ignore */ -	bytes[UUID_BYTES] = '\0'; -	out.assign(bytes, UUID_BYTES); +    char bytes[UUID_BYTES + 1]; +    memcpy(bytes, mData, UUID_BYTES);		/* Flawfinder: ignore */ +    bytes[UUID_BYTES] = '\0'; +    out.assign(bytes, UUID_BYTES);  }  // *TODO: deprecate -void LLUUID::toCompressedString(char *out) const +void LLUUID::toCompressedString(char* out) const  { -	memcpy(out, mData, UUID_BYTES);		/* Flawfinder: ignore */ -	out[UUID_BYTES] = '\0'; +    memcpy(out, mData, UUID_BYTES);		/* Flawfinder: ignore */ +    out[UUID_BYTES] = '\0';  }  std::string LLUUID::getString() const  { -	return asString(); +    return asString();  }  std::string LLUUID::asString() const  { -	std::string str; -	toString(str); -	return str; +    std::string str; +    toString(str); +    return str;  }  BOOL LLUUID::set(const char* in_string, BOOL emit)  { -	return set(ll_safe_string(in_string),emit); +    return set(ll_safe_string(in_string), emit);  }  BOOL LLUUID::set(const std::string& in_string, BOOL emit)  { -	BOOL broken_format = FALSE; - -	// empty strings should make NULL uuid -	if (in_string.empty()) -	{ -		setNull(); -		return TRUE; -	} - -	if (in_string.length() != (UUID_STR_LENGTH - 1))		/* Flawfinder: ignore */ -	{ -		// I'm a moron.  First implementation didn't have the right UUID format. -		// Shouldn't see any of these any more -		if (in_string.length() == (UUID_STR_LENGTH - 2))	/* Flawfinder: ignore */ -		{ -			if(emit) -			{ -				LL_WARNS() << "Warning! Using broken UUID string format" << LL_ENDL; -			} -			broken_format = TRUE; -		} -		else -		{ -			// Bad UUID string.  Spam as INFO, as most cases we don't care. -			if(emit) -			{ -				//don't spam the logs because a resident can't spell. -				LL_WARNS() << "Bad UUID string: " << in_string << LL_ENDL; -			} -			setNull(); -			return FALSE; -		} -	} - -	U8 cur_pos = 0; -	S32 i; -	for (i = 0; i < UUID_BYTES; i++) -	{ -		if ((i == 4) || (i == 6) || (i == 8) || (i == 10)) -		{ -			cur_pos++; -			if (broken_format && (i==10)) -			{ -				// Missing - in the broken format -				cur_pos--; -			} -		} - -		mData[i] = 0; - -		if ((in_string[cur_pos] >= '0') && (in_string[cur_pos] <= '9')) -		{ -			mData[i] += (U8)(in_string[cur_pos] - '0'); -		} -		else if ((in_string[cur_pos] >= 'a') && (in_string[cur_pos] <='f')) -		{ -			mData[i] += (U8)(10 + in_string[cur_pos] - 'a'); -		} -		else if ((in_string[cur_pos] >= 'A') && (in_string[cur_pos] <='F')) -		{ -			mData[i] += (U8)(10 + in_string[cur_pos] - 'A'); -		} -		else -		{ -			if(emit) -			{							 -				LL_WARNS() << "Invalid UUID string character" << LL_ENDL; -			} -			setNull(); -			return FALSE; -		} - -		mData[i] = mData[i] << 4; -		cur_pos++; - -		if ((in_string[cur_pos] >= '0') && (in_string[cur_pos] <= '9')) -		{ -			mData[i] += (U8)(in_string[cur_pos] - '0'); -		} -		else if ((in_string[cur_pos] >= 'a') && (in_string[cur_pos] <='f')) -		{ -			mData[i] += (U8)(10 + in_string[cur_pos] - 'a'); -		} -		else if ((in_string[cur_pos] >= 'A') && (in_string[cur_pos] <='F')) -		{ -			mData[i] += (U8)(10 + in_string[cur_pos] - 'A'); -		} -		else -		{ -			if(emit) -			{ -				LL_WARNS() << "Invalid UUID string character" << LL_ENDL; -			} -			setNull(); -			return FALSE; -		} -		cur_pos++; -	} - -	return TRUE; +    BOOL broken_format = FALSE; + +    // empty strings should make NULL uuid +    if (in_string.empty()) +    { +        setNull(); +        return TRUE; +    } + +    if (in_string.length() != (UUID_STR_LENGTH - 1))		/* Flawfinder: ignore */ +    { +        // I'm a moron.  First implementation didn't have the right UUID format. +        // Shouldn't see any of these any more +        if (in_string.length() == (UUID_STR_LENGTH - 2))	/* Flawfinder: ignore */ +        { +            if (emit) +            { +                LL_WARNS() << "Warning! Using broken UUID string format" << LL_ENDL; +            } +            broken_format = TRUE; +        } +        else +        { +            // Bad UUID string.  Spam as INFO, as most cases we don't care. +            if (emit) +            { +                //don't spam the logs because a resident can't spell. +                LL_WARNS() << "Bad UUID string: " << in_string << LL_ENDL; +            } +            setNull(); +            return FALSE; +        } +    } + +    U8 cur_pos = 0; +    S32 i; +    for (i = 0; i < UUID_BYTES; i++) +    { +        if ((i == 4) || (i == 6) || (i == 8) || (i == 10)) +        { +            cur_pos++; +            if (broken_format && (i == 10)) +            { +                // Missing - in the broken format +                cur_pos--; +            } +        } + +        mData[i] = 0; + +        if ((in_string[cur_pos] >= '0') && (in_string[cur_pos] <= '9')) +        { +            mData[i] += (U8)(in_string[cur_pos] - '0'); +        } +        else if ((in_string[cur_pos] >= 'a') && (in_string[cur_pos] <= 'f')) +        { +            mData[i] += (U8)(10 + in_string[cur_pos] - 'a'); +        } +        else if ((in_string[cur_pos] >= 'A') && (in_string[cur_pos] <= 'F')) +        { +            mData[i] += (U8)(10 + in_string[cur_pos] - 'A'); +        } +        else +        { +            if (emit) +            { +                LL_WARNS() << "Invalid UUID string character" << LL_ENDL; +            } +            setNull(); +            return FALSE; +        } + +        mData[i] = mData[i] << 4; +        cur_pos++; + +        if ((in_string[cur_pos] >= '0') && (in_string[cur_pos] <= '9')) +        { +            mData[i] += (U8)(in_string[cur_pos] - '0'); +        } +        else if ((in_string[cur_pos] >= 'a') && (in_string[cur_pos] <= 'f')) +        { +            mData[i] += (U8)(10 + in_string[cur_pos] - 'a'); +        } +        else if ((in_string[cur_pos] >= 'A') && (in_string[cur_pos] <= 'F')) +        { +            mData[i] += (U8)(10 + in_string[cur_pos] - 'A'); +        } +        else +        { +            if (emit) +            { +                LL_WARNS() << "Invalid UUID string character" << LL_ENDL; +            } +            setNull(); +            return FALSE; +        } +        cur_pos++; +    } + +    return TRUE;  }  BOOL LLUUID::validate(const std::string& in_string)  { -	BOOL broken_format = FALSE; -	if (in_string.length() != (UUID_STR_LENGTH - 1))		/* Flawfinder: ignore */ -	{ -		// I'm a moron.  First implementation didn't have the right UUID format. -		if (in_string.length() == (UUID_STR_LENGTH - 2))		/* Flawfinder: ignore */ -		{ -			broken_format = TRUE; -		} -		else -		{ -			return FALSE; -		} -	} - -	U8 cur_pos = 0; -	for (U32 i = 0; i < 16; i++) -	{ -		if ((i == 4) || (i == 6) || (i == 8) || (i == 10)) -		{ -			cur_pos++; -			if (broken_format && (i==10)) -			{ -				// Missing - in the broken format -				cur_pos--; -			} -		} - -		if ((in_string[cur_pos] >= '0') && (in_string[cur_pos] <= '9')) -		{ -		} -		else if ((in_string[cur_pos] >= 'a') && (in_string[cur_pos] <='f')) -		{ -		} -		else if ((in_string[cur_pos] >= 'A') && (in_string[cur_pos] <='F')) -		{ -		} -		else -		{ -			return FALSE; -		} - -		cur_pos++; - -		if ((in_string[cur_pos] >= '0') && (in_string[cur_pos] <= '9')) -		{ -		} -		else if ((in_string[cur_pos] >= 'a') && (in_string[cur_pos] <='f')) -		{ -		} -		else if ((in_string[cur_pos] >= 'A') && (in_string[cur_pos] <='F')) -		{ -		} -		else -		{ -			return FALSE; -		} -		cur_pos++; -	} -	return TRUE; +    BOOL broken_format = FALSE; +    if (in_string.length() != (UUID_STR_LENGTH - 1))		/* Flawfinder: ignore */ +    { +        // I'm a moron.  First implementation didn't have the right UUID format. +        if (in_string.length() == (UUID_STR_LENGTH - 2))		/* Flawfinder: ignore */ +        { +            broken_format = TRUE; +        } +        else +        { +            return FALSE; +        } +    } + +    U8 cur_pos = 0; +    for (U32 i = 0; i < 16; i++) +    { +        if ((i == 4) || (i == 6) || (i == 8) || (i == 10)) +        { +            cur_pos++; +            if (broken_format && (i == 10)) +            { +                // Missing - in the broken format +                cur_pos--; +            } +        } + +        if ((in_string[cur_pos] >= '0') && (in_string[cur_pos] <= '9')) +        { +        } +        else if ((in_string[cur_pos] >= 'a') && (in_string[cur_pos] <= 'f')) +        { +        } +        else if ((in_string[cur_pos] >= 'A') && (in_string[cur_pos] <= 'F')) +        { +        } +        else +        { +            return FALSE; +        } + +        cur_pos++; + +        if ((in_string[cur_pos] >= '0') && (in_string[cur_pos] <= '9')) +        { +        } +        else if ((in_string[cur_pos] >= 'a') && (in_string[cur_pos] <= 'f')) +        { +        } +        else if ((in_string[cur_pos] >= 'A') && (in_string[cur_pos] <= 'F')) +        { +        } +        else +        { +            return FALSE; +        } +        cur_pos++; +    } +    return TRUE;  }  const LLUUID& LLUUID::operator^=(const LLUUID& rhs)  { -	U32* me = (U32*)&(mData[0]); -	const U32* other = (U32*)&(rhs.mData[0]); -	for(S32 i = 0; i < 4; ++i) -	{ -		me[i] = me[i] ^ other[i]; -	} -	return *this; +    U32* me = (U32*)&(mData[0]); +    const U32* other = (U32*)&(rhs.mData[0]); +    for (S32 i = 0; i < 4; ++i) +    { +        me[i] = me[i] ^ other[i]; +    } +    return *this;  }  LLUUID LLUUID::operator^(const LLUUID& rhs) const  { -	LLUUID id(*this); -	id ^= rhs; -	return id; +    LLUUID id(*this); +    id ^= rhs; +    return id;  } -// WARNING: this algorithm SHALL NOT be changed. It is also used by the server -// and plays a role in some assets validation (e.g. clothing items). Changing -// it would cause invalid assets.  void LLUUID::combine(const LLUUID& other, LLUUID& result) const  { -	LLMD5 md5_uuid; -	md5_uuid.update((unsigned char*)mData, 16); -	md5_uuid.update((unsigned char*)other.mData, 16); -	md5_uuid.finalize(); -	md5_uuid.raw_digest(result.mData); +    LLMD5 md5_uuid; +    md5_uuid.update((unsigned char*)mData, 16); +    md5_uuid.update((unsigned char*)other.mData, 16); +    md5_uuid.finalize(); +    md5_uuid.raw_digest(result.mData);  } -LLUUID LLUUID::combine(const LLUUID &other) const +LLUUID LLUUID::combine(const LLUUID& other) const  { -	LLUUID combination; -	combine(other, combination); -	return combination; +    LLUUID combination; +    combine(other, combination); +    return combination;  } -std::ostream& operator<<(std::ostream& s, const LLUUID &uuid) +std::ostream& operator<<(std::ostream& s, const LLUUID& uuid)  { -	std::string uuid_str; -	uuid.toString(uuid_str); -	s << uuid_str; -	return s; +    std::string uuid_str; +    uuid.toString(uuid_str); +    s << uuid_str; +    return s;  } -std::istream& operator>>(std::istream &s, LLUUID &uuid) +std::istream& operator>>(std::istream& s, LLUUID& uuid)  { -	U32 i; -	char uuid_str[UUID_STR_LENGTH];		/* Flawfinder: ignore */ -	for (i = 0; i < UUID_STR_LENGTH-1; i++) -	{ -		s >> uuid_str[i]; -	} -	uuid_str[i] = '\0'; -	uuid.set(std::string(uuid_str)); -	return s; +    U32 i; +    char uuid_str[UUID_STR_LENGTH];		/* Flawfinder: ignore */ +    for (i = 0; i < UUID_STR_LENGTH - 1; i++) +    { +        s >> uuid_str[i]; +    } +    uuid_str[i] = '\0'; +    uuid.set(std::string(uuid_str)); +    return s;  } -static void get_random_bytes(void *buf, int nbytes) +static void get_random_bytes(void* buf, int nbytes)  { -	int i; -	char *cp = (char *) buf; - -	// *NOTE: If we are not using the janky generator ll_rand() -	// generates at least 3 good bytes of data since it is 0 to -	// RAND_MAX. This could be made more efficient by copying all the -	// bytes. -	for (i=0; i < nbytes; i++) +    int i; +    char* cp = (char*)buf; + +    // *NOTE: If we are not using the janky generator ll_rand() +    // generates at least 3 good bytes of data since it is 0 to +    // RAND_MAX. This could be made more efficient by copying all the +    // bytes. +    for (i = 0; i < nbytes; i++)  #if LL_USE_JANKY_RANDOM_NUMBER_GENERATOR -		*cp++ = janky_fast_random_bytes() & 0xFF; +        * cp++ = janky_fast_random_bytes() & 0xFF;  #else -		*cp++ = ll_rand() & 0xFF; +        * cp++ = ll_rand() & 0xFF;  #endif -	return;	 +    return;  }  #if	LL_WINDOWS  typedef struct _ASTAT_  { -	ADAPTER_STATUS adapt; -	NAME_BUFFER    NameBuff [30]; +    ADAPTER_STATUS adapt; +    NAME_BUFFER    NameBuff[30];  }ASTAT, * PASTAT;  // static -S32	LLUUID::getNodeID(unsigned char	*node_id) +S32	LLUUID::getNodeID(unsigned char* node_id)  { -	ASTAT Adapter; -	NCB Ncb; -	UCHAR uRetCode; -	LANA_ENUM   lenum; -	int      i; -	int retval = 0; - -	memset( &Ncb, 0, sizeof(Ncb) ); -	Ncb.ncb_command = NCBENUM; -	Ncb.ncb_buffer = (UCHAR *)&lenum; -	Ncb.ncb_length = sizeof(lenum); -	uRetCode = Netbios( &Ncb ); - -	for(i=0; i < lenum.length ;i++) -	{ -		memset( &Ncb, 0, sizeof(Ncb) ); -		Ncb.ncb_command = NCBRESET; -		Ncb.ncb_lana_num = lenum.lana[i]; - -		uRetCode = Netbios( &Ncb ); - -		memset( &Ncb, 0, sizeof (Ncb) ); -		Ncb.ncb_command = NCBASTAT; -		Ncb.ncb_lana_num = lenum.lana[i]; - -		strcpy( (char *)Ncb.ncb_callname,  "*              " );		/* Flawfinder: ignore */ -		Ncb.ncb_buffer = (unsigned char *)&Adapter; -		Ncb.ncb_length = sizeof(Adapter); - -		uRetCode = Netbios( &Ncb ); -		if ( uRetCode == 0 ) -		{ -			memcpy(node_id,Adapter.adapt.adapter_address,6);		/* Flawfinder: ignore */ -			retval = 1; -		} -	} -	return retval; +    ASTAT Adapter; +    NCB Ncb; +    UCHAR uRetCode; +    LANA_ENUM   lenum; +    int      i; +    int retval = 0; + +    memset(&Ncb, 0, sizeof(Ncb)); +    Ncb.ncb_command = NCBENUM; +    Ncb.ncb_buffer = (UCHAR*)&lenum; +    Ncb.ncb_length = sizeof(lenum); +    uRetCode = Netbios(&Ncb); + +    for (i = 0; i < lenum.length; i++) +    { +        memset(&Ncb, 0, sizeof(Ncb)); +        Ncb.ncb_command = NCBRESET; +        Ncb.ncb_lana_num = lenum.lana[i]; + +        uRetCode = Netbios(&Ncb); + +        memset(&Ncb, 0, sizeof(Ncb)); +        Ncb.ncb_command = NCBASTAT; +        Ncb.ncb_lana_num = lenum.lana[i]; + +        strcpy((char*)Ncb.ncb_callname, "*              ");		/* Flawfinder: ignore */ +        Ncb.ncb_buffer = (unsigned char*)&Adapter; +        Ncb.ncb_length = sizeof(Adapter); + +        uRetCode = Netbios(&Ncb); +        if (uRetCode == 0) +        { +            memcpy(node_id, Adapter.adapt.adapter_address, 6);		/* Flawfinder: ignore */ +            retval = 1; +        } +    } +    return retval;  }  #elif LL_DARWIN @@ -525,66 +521,66 @@ S32	LLUUID::getNodeID(unsigned char	*node_id)  #include <net/route.h>  #include <ifaddrs.h> -// static -S32 LLUUID::getNodeID(unsigned char *node_id) + // static +S32 LLUUID::getNodeID(unsigned char* node_id)  { -	int i; -	unsigned char 	*a = NULL; -	struct ifaddrs *ifap, *ifa; -	int rv; -	S32 result = 0; - -	if ((rv=getifaddrs(&ifap))==-1) -	{        -		return -1; -	} -	if (ifap == NULL) -	{ -		return -1; -	} - -	for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) -	{        -//		printf("Interface %s, address family %d, ", ifa->ifa_name, ifa->ifa_addr->sa_family); -		for(i=0; i< ifa->ifa_addr->sa_len; i++) -		{ -//			printf("%02X ", (unsigned char)ifa->ifa_addr->sa_data[i]); -		} -//		printf("\n"); -		 -		if(ifa->ifa_addr->sa_family == AF_LINK) -		{ -			// This is a link-level address -			struct sockaddr_dl *lla = (struct sockaddr_dl *)ifa->ifa_addr; -			 -//			printf("\tLink level address, type %02X\n", lla->sdl_type); - -			if(lla->sdl_type == IFT_ETHER) -			{ -				// Use the first ethernet MAC in the list. -				// For some reason, the macro LLADDR() defined in net/if_dl.h doesn't expand correctly.  This is what it would do. -				a = (unsigned char *)&((lla)->sdl_data); -				a += (lla)->sdl_nlen; -				 -				if (!a[0] && !a[1] && !a[2] && !a[3] && !a[4] && !a[5]) -				{ -					continue; -				} - -				if (node_id)  -				{ -					memcpy(node_id, a, 6); -					result = 1; -				} -				 -				// We found one. -				break; -			} -		} -	} -	freeifaddrs(ifap); - -	return result; +    int i; +    unsigned char* a = NULL; +    struct ifaddrs* ifap, * ifa; +    int rv; +    S32 result = 0; + +    if ((rv = getifaddrs(&ifap)) == -1) +    { +        return -1; +    } +    if (ifap == NULL) +    { +        return -1; +    } + +    for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) +    { +        //		printf("Interface %s, address family %d, ", ifa->ifa_name, ifa->ifa_addr->sa_family); +        for (i = 0; i < ifa->ifa_addr->sa_len; i++) +        { +            //			printf("%02X ", (unsigned char)ifa->ifa_addr->sa_data[i]); +        } +        //		printf("\n"); + +        if (ifa->ifa_addr->sa_family == AF_LINK) +        { +            // This is a link-level address +            struct sockaddr_dl* lla = (struct sockaddr_dl*)ifa->ifa_addr; + +            //			printf("\tLink level address, type %02X\n", lla->sdl_type); + +            if (lla->sdl_type == IFT_ETHER) +            { +                // Use the first ethernet MAC in the list. +                // For some reason, the macro LLADDR() defined in net/if_dl.h doesn't expand correctly.  This is what it would do. +                a = (unsigned char*)&((lla)->sdl_data); +                a += (lla)->sdl_nlen; + +                if (!a[0] && !a[1] && !a[2] && !a[3] && !a[4] && !a[5]) +                { +                    continue; +                } + +                if (node_id) +                { +                    memcpy(node_id, a, 6); +                    result = 1; +                } + +                // We found one. +                break; +            } +        } +    } +    freeifaddrs(ifap); + +    return result;  }  #else @@ -611,22 +607,22 @@ S32 LLUUID::getNodeID(unsigned char *node_id)  #endif  #endif -// static -S32 LLUUID::getNodeID(unsigned char *node_id) + // static +S32 LLUUID::getNodeID(unsigned char* node_id)  { -	int 		sd; -	struct ifreq 	ifr, *ifrp; -	struct ifconf 	ifc; -	char buf[1024]; -	int		n, i; -	unsigned char 	*a; -	 -/* - * BSD 4.4 defines the size of an ifreq to be - * max(sizeof(ifreq), sizeof(ifreq.ifr_name)+ifreq.ifr_addr.sa_len - * However, under earlier systems, sa_len isn't present, so the size is  - * just sizeof(struct ifreq) - */ +    int 		sd; +    struct ifreq 	ifr, * ifrp; +    struct ifconf 	ifc; +    char buf[1024]; +    int		n, i; +    unsigned char* a; + +    /* +     * BSD 4.4 defines the size of an ifreq to be +     * max(sizeof(ifreq), sizeof(ifreq.ifr_name)+ifreq.ifr_addr.sa_len +     * However, under earlier systems, sa_len isn't present, so the size is +     * just sizeof(struct ifreq) +     */  #ifdef HAVE_SA_LEN  #ifndef max  #define max(a,b) ((a) > (b) ? (a) : (b)) @@ -637,345 +633,356 @@ S32 LLUUID::getNodeID(unsigned char *node_id)  #define ifreq_size(i) sizeof(struct ifreq)  #endif /* HAVE_SA_LEN*/ -	sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); -	if (sd < 0) { -		return -1; -	} -	memset(buf, 0, sizeof(buf)); -	ifc.ifc_len = sizeof(buf); -	ifc.ifc_buf = buf; -	if (ioctl (sd, SIOCGIFCONF, (char *)&ifc) < 0) { -		close(sd); -		return -1; -	} -	n = ifc.ifc_len; -	for (i = 0; i < n; i+= ifreq_size(*ifr) ) { -		ifrp = (struct ifreq *)((char *) ifc.ifc_buf+i); -		strncpy(ifr.ifr_name, ifrp->ifr_name, IFNAMSIZ);		/* Flawfinder: ignore */ +    sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); +    if (sd < 0) { +        return -1; +    } +    memset(buf, 0, sizeof(buf)); +    ifc.ifc_len = sizeof(buf); +    ifc.ifc_buf = buf; +    if (ioctl(sd, SIOCGIFCONF, (char*)&ifc) < 0) { +        close(sd); +        return -1; +    } +    n = ifc.ifc_len; +    for (i = 0; i < n; i += ifreq_size(*ifr)) { +        ifrp = (struct ifreq*)((char*)ifc.ifc_buf + i); +        strncpy(ifr.ifr_name, ifrp->ifr_name, IFNAMSIZ);		/* Flawfinder: ignore */  #ifdef SIOCGIFHWADDR -		if (ioctl(sd, SIOCGIFHWADDR, &ifr) < 0) -			continue; -		a = (unsigned char *) &ifr.ifr_hwaddr.sa_data; +        if (ioctl(sd, SIOCGIFHWADDR, &ifr) < 0) +            continue; +        a = (unsigned char*)&ifr.ifr_hwaddr.sa_data;  #else  #ifdef SIOCGENADDR -		if (ioctl(sd, SIOCGENADDR, &ifr) < 0) -			continue; -		a = (unsigned char *) ifr.ifr_enaddr; +        if (ioctl(sd, SIOCGENADDR, &ifr) < 0) +            continue; +        a = (unsigned char*)ifr.ifr_enaddr;  #else -		/* -		 * XXX we don't have a way of getting the hardware -		 * address -		 */ -		close(sd); -		return 0; +        /* +         * XXX we don't have a way of getting the hardware +         * address +         */ +        close(sd); +        return 0;  #endif /* SIOCGENADDR */  #endif /* SIOCGIFHWADDR */ -		if (!a[0] && !a[1] && !a[2] && !a[3] && !a[4] && !a[5]) -			continue; -		if (node_id) { -			memcpy(node_id, a, 6);		/* Flawfinder: ignore */ -			close(sd); -			return 1; -		} -	} -	close(sd); -	return 0; +        if (!a[0] && !a[1] && !a[2] && !a[3] && !a[4] && !a[5]) +            continue; +        if (node_id) { +            memcpy(node_id, a, 6);		/* Flawfinder: ignore */ +            close(sd); +            return 1; +        } +    } +    close(sd); +    return 0;  }  #endif -S32 LLUUID::cmpTime(uuid_time_t *t1, uuid_time_t *t2) +S32 LLUUID::cmpTime(uuid_time_t* t1, uuid_time_t* t2)  { -   // Compare two time values. +    // Compare two time values. -   if (t1->high < t2->high) return -1; -   if (t1->high > t2->high) return 1; -   if (t1->low  < t2->low)  return -1; -   if (t1->low  > t2->low)  return 1; -   return 0; +    if (t1->high < t2->high) return -1; +    if (t1->high > t2->high) return 1; +    if (t1->low < t2->low)  return -1; +    if (t1->low > t2->low)  return 1; +    return 0;  } -void LLUUID::getSystemTime(uuid_time_t *timestamp) +void LLUUID::getSystemTime(uuid_time_t* timestamp)  { -   // Get system time with 100ns precision. Time is since Oct 15, 1582. +    // Get system time with 100ns precision. Time is since Oct 15, 1582.  #if LL_WINDOWS -   ULARGE_INTEGER time; -   GetSystemTimeAsFileTime((FILETIME *)&time); -   // NT keeps time in FILETIME format which is 100ns ticks since -   // Jan 1, 1601. UUIDs use time in 100ns ticks since Oct 15, 1582. -   // The difference is 17 Days in Oct + 30 (Nov) + 31 (Dec) -   // + 18 years and 5 leap days. -   time.QuadPart += -            (unsigned __int64) (1000*1000*10)       // seconds -          * (unsigned __int64) (60 * 60 * 24)       // days -          * (unsigned __int64) (17+30+31+365*18+5); // # of days - -   timestamp->high = time.HighPart; -   timestamp->low  = time.LowPart; +    ULARGE_INTEGER time; +    GetSystemTimeAsFileTime((FILETIME*)&time); +    // NT keeps time in FILETIME format which is 100ns ticks since +    // Jan 1, 1601. UUIDs use time in 100ns ticks since Oct 15, 1582. +    // The difference is 17 Days in Oct + 30 (Nov) + 31 (Dec) +    // + 18 years and 5 leap days. +    time.QuadPart += +        (unsigned __int64)(1000 * 1000 * 10)       // seconds +        * (unsigned __int64)(60 * 60 * 24)       // days +        * (unsigned __int64)(17 + 30 + 31 + 365 * 18 + 5); // # of days + +    timestamp->high = time.HighPart; +    timestamp->low = time.LowPart;  #else -   struct timeval tp; -   gettimeofday(&tp, 0); - -   // Offset between UUID formatted times and Unix formatted times. -   // UUID UTC base time is October 15, 1582. -   // Unix base time is January 1, 1970. -   U64 uuid_time = ((U64)tp.tv_sec * 10000000) + (tp.tv_usec * 10) + -                           U64L(0x01B21DD213814000); -   timestamp->high = (U32) (uuid_time >> 32); -   timestamp->low  = (U32) (uuid_time & 0xFFFFFFFF); +    struct timeval tp; +    gettimeofday(&tp, 0); + +    // Offset between UUID formatted times and Unix formatted times. +    // UUID UTC base time is October 15, 1582. +    // Unix base time is January 1, 1970. +    U64 uuid_time = ((U64)tp.tv_sec * 10000000) + (tp.tv_usec * 10) + +        U64L(0x01B21DD213814000); +    timestamp->high = (U32)(uuid_time >> 32); +    timestamp->low = (U32)(uuid_time & 0xFFFFFFFF);  #endif  } -void LLUUID::getCurrentTime(uuid_time_t *timestamp) +void LLUUID::getCurrentTime(uuid_time_t* timestamp)  { -   // Get current time as 60 bit 100ns ticks since whenever. -   // Compensate for the fact that real clock resolution is less -   // than 100ns. - -   const U32 uuids_per_tick = 1024; - -   static uuid_time_t time_last; -   static U32    uuids_this_tick; -   static BOOL     init = FALSE; - -   if (!init) { -      getSystemTime(&time_last); -      uuids_this_tick = uuids_per_tick; -      init = TRUE; -      mMutex = new LLMutex(); -   } - -   uuid_time_t time_now = {0,0}; - -   while (1) { -      getSystemTime(&time_now); - -      // if clock reading changed since last UUID generated -      if (cmpTime(&time_last, &time_now))  { -         // reset count of uuid's generated with this clock reading -         uuids_this_tick = 0; -         break; -      } -      if (uuids_this_tick < uuids_per_tick) { -         uuids_this_tick++; -         break; -      } -      // going too fast for our clock; spin -   } - -   time_last = time_now; - -   if (uuids_this_tick != 0) { -      if (time_now.low & 0x80000000) { -         time_now.low += uuids_this_tick; -         if (!(time_now.low & 0x80000000)) -            time_now.high++; -      } else -         time_now.low += uuids_this_tick; -   } - -   timestamp->high = time_now.high; -   timestamp->low  = time_now.low; +    // Get current time as 60 bit 100ns ticks since whenever. +    // Compensate for the fact that real clock resolution is less +    // than 100ns. + +    const U32 uuids_per_tick = 1024; + +    static uuid_time_t time_last; +    static U32    uuids_this_tick; +    static BOOL     init = FALSE; + +    if (!init) { +        getSystemTime(&time_last); +        uuids_this_tick = uuids_per_tick; +        init = TRUE; +        mMutex = new LLMutex(); +    } + +    uuid_time_t time_now = { 0,0 }; + +    while (1) { +        getSystemTime(&time_now); + +        // if clock reading changed since last UUID generated +        if (cmpTime(&time_last, &time_now)) { +            // reset count of uuid's generated with this clock reading +            uuids_this_tick = 0; +            break; +        } +        if (uuids_this_tick < uuids_per_tick) { +            uuids_this_tick++; +            break; +        } +        // going too fast for our clock; spin +    } + +    time_last = time_now; + +    if (uuids_this_tick != 0) { +        if (time_now.low & 0x80000000) { +            time_now.low += uuids_this_tick; +            if (!(time_now.low & 0x80000000)) +                time_now.high++; +        } +        else +            time_now.low += uuids_this_tick; +    } + +    timestamp->high = time_now.high; +    timestamp->low = time_now.low;  }  void LLUUID::generate()  { -	// Create a UUID. -	uuid_time_t timestamp; - -	static unsigned char node_id[6];	/* Flawfinder: ignore */ -	static int has_init = 0; -    -	// Create a UUID. -	static uuid_time_t time_last = {0,0}; -	static U16 clock_seq = 0; +    // Create a UUID. +    uuid_time_t timestamp; + +    static unsigned char node_id[6];	/* Flawfinder: ignore */ +    static int has_init = 0; + +    // Create a UUID. +    static uuid_time_t time_last = { 0,0 }; +    static U16 clock_seq = 0;  #if LL_USE_JANKY_RANDOM_NUMBER_GENERATOR -	static U32 seed = 0L; // dummy seed.  reset it below +    static U32 seed = 0L; // dummy seed.  reset it below  #endif -	if (!has_init)  -	{ -		has_init = 1; -		if (getNodeID(node_id) <= 0)  -		{ -			get_random_bytes(node_id, 6); -			/* -			 * Set multicast bit, to prevent conflicts -			 * with IEEE 802 addresses obtained from -			 * network cards -			 */ -			node_id[0] |= 0x80; -		} - -		getCurrentTime(&time_last); +    if (!has_init) +    { +        has_init = 1; +        if (getNodeID(node_id) <= 0) +        { +            get_random_bytes(node_id, 6); +            /* +             * Set multicast bit, to prevent conflicts +             * with IEEE 802 addresses obtained from +             * network cards +             */ +            node_id[0] |= 0x80; +        } + +        getCurrentTime(&time_last);  #if LL_USE_JANKY_RANDOM_NUMBER_GENERATOR -		seed = time_last.low; +        seed = time_last.low;  #endif  #if LL_USE_JANKY_RANDOM_NUMBER_GENERATOR -		clock_seq = (U16)janky_fast_random_seeded_bytes(seed, 65536); +        clock_seq = (U16)janky_fast_random_seeded_bytes(seed, 65536);  #else -		clock_seq = (U16)ll_rand(65536); +        clock_seq = (U16)ll_rand(65536);  #endif -	} - -	// get current time -	getCurrentTime(×tamp); -	U16 our_clock_seq = clock_seq; - -	// if clock hasn't changed or went backward, change clockseq -	if (cmpTime(×tamp, &time_last) != 1)  -	{ -		LLMutexLock	lock(mMutex); -		clock_seq = (clock_seq + 1) & 0x3FFF; -		if (clock_seq == 0)  -			clock_seq++; -		our_clock_seq = clock_seq;	// Ensure we're using a different clock_seq value from previous time -	} +    } + +    // get current time +    getCurrentTime(×tamp); +    U16 our_clock_seq = clock_seq; + +    // if clock hasn't changed or went backward, change clockseq +    if (cmpTime(×tamp, &time_last) != 1) +    { +        LLMutexLock	lock(mMutex); +        clock_seq = (clock_seq + 1) & 0x3FFF; +        if (clock_seq == 0) +            clock_seq++; +        our_clock_seq = clock_seq;	// Ensure we're using a different clock_seq value from previous time +    }      time_last = timestamp; -	memcpy(mData+10, node_id, 6);		/* Flawfinder: ignore */ -	U32 tmp; -	tmp = timestamp.low; -	mData[3] = (unsigned char) tmp; -	tmp >>= 8; -	mData[2] = (unsigned char) tmp; -	tmp >>= 8; -	mData[1] = (unsigned char) tmp; -	tmp >>= 8; -	mData[0] = (unsigned char) tmp; -	 -	tmp = (U16) timestamp.high; -	mData[5] = (unsigned char) tmp; -	tmp >>= 8; -	mData[4] = (unsigned char) tmp; - -	tmp = (timestamp.high >> 16) | 0x1000; -	mData[7] = (unsigned char) tmp; -	tmp >>= 8; -	mData[6] = (unsigned char) tmp; - -	tmp = our_clock_seq; - -	mData[9] = (unsigned char) tmp; -	tmp >>= 8; -	mData[8] = (unsigned char) tmp; - -	HBXXH128::digest(*this, (const void*)mData, 16); +    memcpy(mData + 10, node_id, 6);		/* Flawfinder: ignore */ +    U32 tmp; +    tmp = timestamp.low; +    mData[3] = (unsigned char)tmp; +    tmp >>= 8; +    mData[2] = (unsigned char)tmp; +    tmp >>= 8; +    mData[1] = (unsigned char)tmp; +    tmp >>= 8; +    mData[0] = (unsigned char)tmp; + +    tmp = (U16)timestamp.high; +    mData[5] = (unsigned char)tmp; +    tmp >>= 8; +    mData[4] = (unsigned char)tmp; + +    tmp = (timestamp.high >> 16) | 0x1000; +    mData[7] = (unsigned char)tmp; +    tmp >>= 8; +    mData[6] = (unsigned char)tmp; + +    tmp = our_clock_seq; + +    mData[9] = (unsigned char)tmp; +    tmp >>= 8; +    mData[8] = (unsigned char)tmp; + +    LLMD5 md5_uuid; + +    md5_uuid.update(mData, 16); +    md5_uuid.finalize(); +    md5_uuid.raw_digest(mData);  }  void LLUUID::generate(const std::string& hash_string)  { -	HBXXH128::digest(*this, hash_string); +    LLMD5 md5_uuid((U8*)hash_string.c_str()); +    md5_uuid.raw_digest(mData);  }  U32 LLUUID::getRandomSeed()  { -   static unsigned char seed[16];		/* Flawfinder: ignore */ -    -   getNodeID(&seed[0]); +    static unsigned char seed[16];		/* Flawfinder: ignore */ -   // Incorporate the pid into the seed to prevent -   // processes that start on the same host at the same -   // time from generating the same seed. -   pid_t pid = LLApp::getPid(); +    getNodeID(&seed[0]); -   seed[6]=(unsigned char)(pid >> 8); -   seed[7]=(unsigned char)(pid); -   getSystemTime((uuid_time_t *)(&seed[8])); +    // Incorporate the pid into the seed to prevent +    // processes that start on the same host at the same +    // time from generating the same seed. +    pid_t pid = LLApp::getPid(); -   U64 seed64 = HBXXH64((const void*)seed, 16).digest(); -   return U32(seed64) ^ U32(seed64 >> 32); +    seed[6] = (unsigned char)(pid >> 8); +    seed[7] = (unsigned char)(pid); +    getSystemTime((uuid_time_t*)(&seed[8])); + +    LLMD5 md5_seed; + +    md5_seed.update(seed, 16); +    md5_seed.finalize(); +    md5_seed.raw_digest(seed); + +    return(*(U32*)seed);  }  BOOL LLUUID::parseUUID(const std::string& buf, LLUUID* value)  { -	if( buf.empty() || value == NULL) -	{ -		return FALSE; -	} - -	std::string temp( buf ); -	LLStringUtil::trim(temp); -	if( LLUUID::validate( temp ) ) -	{ -		value->set( temp ); -		return TRUE; -	} -	return FALSE; +    if (buf.empty() || value == NULL) +    { +        return FALSE; +    } + +    std::string temp(buf); +    LLStringUtil::trim(temp); +    if (LLUUID::validate(temp)) +    { +        value->set(temp); +        return TRUE; +    } +    return FALSE;  }  //static  LLUUID LLUUID::generateNewID(std::string hash_string)  { -	LLUUID new_id; -	if (hash_string.empty()) -	{ -		new_id.generate(); -	} -	else -	{ -		new_id.generate(hash_string); -	} -	return new_id; +    LLUUID new_id; +    if (hash_string.empty()) +    { +        new_id.generate(); +    } +    else +    { +        new_id.generate(hash_string); +    } +    return new_id;  }  LLAssetID LLTransactionID::makeAssetID(const LLUUID& session) const  { -	LLAssetID result; -	if (isNull()) -	{ -		result.setNull(); -	} -	else -	{ -		combine(session, result); -	} -	return result; +    LLAssetID result; +    if (isNull()) +    { +        result.setNull(); +    } +    else +    { +        combine(session, result); +    } +    return result;  }  // Construct  LLUUID::LLUUID()  { -	setNull(); +    setNull();  }  // Faster than copying from memory - void LLUUID::setNull() +void LLUUID::setNull()  { -	U32 *word = (U32 *)mData; -	word[0] = 0; -	word[1] = 0; -	word[2] = 0; -	word[3] = 0; +    U32* word = (U32*)mData; +    word[0] = 0; +    word[1] = 0; +    word[2] = 0; +    word[3] = 0;  }  // Compare - bool LLUUID::operator==(const LLUUID& rhs) const +bool LLUUID::operator==(const LLUUID& rhs) const  { -	U32 *tmp = (U32 *)mData; -	U32 *rhstmp = (U32 *)rhs.mData; -	// Note: binary & to avoid branching -	return  -		(tmp[0] == rhstmp[0]) &   -		(tmp[1] == rhstmp[1]) & -		(tmp[2] == rhstmp[2]) & -		(tmp[3] == rhstmp[3]); +    U32* tmp = (U32*)mData; +    U32* rhstmp = (U32*)rhs.mData; +    // Note: binary & to avoid branching +    return +        (tmp[0] == rhstmp[0]) & +        (tmp[1] == rhstmp[1]) & +        (tmp[2] == rhstmp[2]) & +        (tmp[3] == rhstmp[3]);  } - bool LLUUID::operator!=(const LLUUID& rhs) const +bool LLUUID::operator!=(const LLUUID& rhs) const  { -	U32 *tmp = (U32 *)mData; -	U32 *rhstmp = (U32 *)rhs.mData; -	// Note: binary | to avoid branching -	return  -		(tmp[0] != rhstmp[0]) | -		(tmp[1] != rhstmp[1]) | -		(tmp[2] != rhstmp[2]) | -		(tmp[3] != rhstmp[3]); +    U32* tmp = (U32*)mData; +    U32* rhstmp = (U32*)rhs.mData; +    // Note: binary | to avoid branching +    return +        (tmp[0] != rhstmp[0]) | +        (tmp[1] != rhstmp[1]) | +        (tmp[2] != rhstmp[2]) | +        (tmp[3] != rhstmp[3]);  }  /* @@ -983,94 +990,94 @@ LLUUID::LLUUID()  // to integers, among other things.  Use isNull() or notNull().   LLUUID::operator bool() const  { -	U32 *word = (U32 *)mData; -	return (word[0] | word[1] | word[2] | word[3]) > 0; +    U32 *word = (U32 *)mData; +    return (word[0] | word[1] | word[2] | word[3]) > 0;  }  */ - BOOL LLUUID::notNull() const +BOOL LLUUID::notNull() const  { -	U32 *word = (U32 *)mData; -	return (word[0] | word[1] | word[2] | word[3]) > 0; +    U32* word = (U32*)mData; +    return (word[0] | word[1] | word[2] | word[3]) > 0;  }  // Faster than == LLUUID::null because doesn't require  // as much memory access. - BOOL LLUUID::isNull() const +BOOL LLUUID::isNull() const  { -	U32 *word = (U32 *)mData; -	// If all bits are zero, return !0 == TRUE -	return !(word[0] | word[1] | word[2] | word[3]); +    U32* word = (U32*)mData; +    // If all bits are zero, return !0 == TRUE +    return !(word[0] | word[1] | word[2] | word[3]);  } - LLUUID::LLUUID(const char *in_string) +LLUUID::LLUUID(const char* in_string)  { -	if (!in_string || in_string[0] == 0) -	{ -		setNull(); -		return; -	} -  -	set(in_string); +    if (!in_string || in_string[0] == 0) +    { +        setNull(); +        return; +    } + +    set(in_string);  } - LLUUID::LLUUID(const std::string& in_string) +LLUUID::LLUUID(const std::string& in_string)  { -	if (in_string.empty()) -	{ -		setNull(); -		return; -	} +    if (in_string.empty()) +    { +        setNull(); +        return; +    } -	set(in_string); +    set(in_string);  }  // IW: DON'T "optimize" these w/ U32s or you'll scoogie the sort order  // IW: this will make me very sad - bool LLUUID::operator<(const LLUUID &rhs) const +bool LLUUID::operator<(const LLUUID& rhs) const  { -	U32 i; -	for( i = 0; i < (UUID_BYTES - 1); i++ ) -	{ -		if( mData[i] != rhs.mData[i] ) -		{ -			return (mData[i] < rhs.mData[i]); -		} -	} -	return (mData[UUID_BYTES - 1] < rhs.mData[UUID_BYTES - 1]); +    U32 i; +    for (i = 0; i < (UUID_BYTES - 1); i++) +    { +        if (mData[i] != rhs.mData[i]) +        { +            return (mData[i] < rhs.mData[i]); +        } +    } +    return (mData[UUID_BYTES - 1] < rhs.mData[UUID_BYTES - 1]);  } - bool LLUUID::operator>(const LLUUID &rhs) const +bool LLUUID::operator>(const LLUUID& rhs) const  { -	U32 i; -	for( i = 0; i < (UUID_BYTES - 1); i++ ) -	{ -		if( mData[i] != rhs.mData[i] ) -		{ -			return (mData[i] > rhs.mData[i]); -		} -	} -	return (mData[UUID_BYTES - 1] > rhs.mData[UUID_BYTES - 1]); +    U32 i; +    for (i = 0; i < (UUID_BYTES - 1); i++) +    { +        if (mData[i] != rhs.mData[i]) +        { +            return (mData[i] > rhs.mData[i]); +        } +    } +    return (mData[UUID_BYTES - 1] > rhs.mData[UUID_BYTES - 1]);  } - U16 LLUUID::getCRC16() const +U16 LLUUID::getCRC16() const  { -	// A UUID is 16 bytes, or 8 shorts. -	U16 *short_data = (U16*)mData; -	U16 out = 0; -	out += short_data[0]; -	out += short_data[1]; -	out += short_data[2]; -	out += short_data[3]; -	out += short_data[4]; -	out += short_data[5]; -	out += short_data[6]; -	out += short_data[7]; -	return out; +    // A UUID is 16 bytes, or 8 shorts. +    U16* short_data = (U16*)mData; +    U16 out = 0; +    out += short_data[0]; +    out += short_data[1]; +    out += short_data[2]; +    out += short_data[3]; +    out += short_data[4]; +    out += short_data[5]; +    out += short_data[6]; +    out += short_data[7]; +    return out;  } - U32 LLUUID::getCRC32() const +U32 LLUUID::getCRC32() const  { -	U32 *tmp = (U32*)mData; -	return tmp[0] + tmp[1] + tmp[2] + tmp[3]; +    U32* tmp = (U32*)mData; +    return tmp[0] + tmp[1] + tmp[2] + tmp[3];  } diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 9919af5368..7a694ab10c 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -4863,17 +4863,6 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src)  			mTangents = NULL;  		} -        if (src.mTangents) -        { -            allocateTangents(src.mNumVertices); -            LLVector4a::memcpyNonAliased16((F32*)mTangents, (F32*)src.mTangents, vert_size); -        } -        else -        { -            ll_aligned_free_16(mTangents); -            mTangents = nullptr; -        } -  		if (src.mWeights)  		{              llassert(!mWeights); // don't orphan an old alloc here accidentally diff --git a/indra/llprimitive/llgltfloader.cpp b/indra/llprimitive/llgltfloader.cpp index fd304f7bc9..7394f99794 100644 --- a/indra/llprimitive/llgltfloader.cpp +++ b/indra/llprimitive/llgltfloader.cpp @@ -106,10 +106,12 @@ bool LLGLTFLoader::OpenFile(const std::string &filename)      tinygltf::TinyGLTF loader;      std::string        error_msg;      std::string        warn_msg; +    std::string filename_lc(filename); +    LLStringUtil::toLower(filename_lc);      // Load a tinygltf model fom a file. Assumes that the input filename has already been      // been sanitized to one of (.gltf , .glb) extensions, so does a simple find to distinguish. -    if (std::string::npos == filename.rfind(".gltf")) +    if (std::string::npos == filename_lc.rfind(".gltf"))      {  // file is binary          mGltfLoaded = loader.LoadBinaryFromFile(&mGltfModel, &error_msg, &warn_msg, filename);      } diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h index e701b62fdc..b453b91e67 100644 --- a/indra/llprimitive/llgltfmaterial.h +++ b/indra/llprimitive/llgltfmaterial.h @@ -98,7 +98,8 @@ public:      std::array<TextureTransform, GLTF_TEXTURE_INFO_COUNT> mTextureTransform; -    // NOTE : initialize values to defaults according to the GLTF spec +    // NOTE: initialize values to defaults according to the GLTF spec +    // NOTE: these values should be in linear color space      LLColor4 mBaseColor = LLColor4(1, 1, 1, 1);      LLColor3 mEmissiveColor = LLColor3(0, 0, 0); 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 50d4532fa7..b5c36ea35e 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -1409,52 +1409,59 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt          free_cur_tex_image();  #if LL_DARWIN -        { -            LL_PROFILE_ZONE_NAMED("glTexImage2D alloc"); -            glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, use_scratch ? scratch : pixels); -        } +        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 +        const bool use_sub_image = !allow_compression; +#endif +        if (!use_sub_image)          {              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);          } - -        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"); +                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);      }      stop_glerror(); diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index bbd024abd9..a03233323b 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); +    // *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 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); 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 6fb319fd5b..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"))          { diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 2fe80af373..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) == 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; diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 10cf7513b5..666adcf672 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -4857,13 +4857,14 @@ void LLWindowWin32::LLWindowWin32Thread::updateVRAMUsage()          DXGI_QUERY_VIDEO_MEMORY_INFO info;          mDXGIAdapter->QueryVideoMemoryInfo(0, DXGI_MEMORY_SEGMENT_GROUP_LOCAL, &info); -  #if 0 // debug 0 budget and 0 CU          info.Budget = 0;          info.CurrentUsage = 0;  #endif          U32 budget_mb = info.Budget / 1024 / 1024; +        gGLManager.mVRAM = llmax(gGLManager.mVRAM, (S32) budget_mb); +          U32 afr_mb = info.AvailableForReservation / 1024 / 1024;          // correct for systems that misreport budget          if (budget_mb == 0) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 81fed560bb..a369b22ef1 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10402,7 +10402,7 @@      <key>Type</key>      <string>F32</string>      <key>Value</key> -    <real>8</real> +    <real>32</real>    </map>    <key>RenderTonemapper</key>    <map> @@ -12627,27 +12627,16 @@        <key>Value</key>        <real>20.0</real>      </map> -    <key>TextureCameraMotionThreshold</key> +    <key>TextureBiasDistanceScale</key>      <map>        <key>Comment</key> -      <string>If the overall motion is lower than this value, textures will be loaded faster</string> +      <string>When biasing textures to lower resolution due to lack of vram, weight to put on distance factor.</string>        <key>Persist</key>        <integer>1</integer>        <key>Type</key>        <string>F32</string>        <key>Value</key> -      <real>0.2</real> -    </map> -    <key>TextureCameraMotionBoost</key> -    <map> -      <key>Comment</key> -      <string>Progressive discard level decrement when the camera is still</string> -      <key>Persist</key> -      <integer>1</integer> -      <key>Type</key> -      <string>S32</string> -      <key>Value</key> -      <integer>3</integer> +      <real>8.0</real>      </map>      <key>TextureDecodeDisabled</key>      <map> diff --git a/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl b/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl index cf9ce646d1..fe796a054d 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl @@ -52,9 +52,6 @@ VARYING vec2 vary_texcoord2;  VARYING vec2 vary_texcoord3;  VARYING float altitude_blend_factor; -/// Soft clips the light with a gamma correction -vec3 scaleSoftClip(vec3 light); -  vec4 cloudNoise(vec2 uv)  {     vec4 a = texture2D(cloud_noise_texture, uv); @@ -119,7 +116,6 @@ void main()      color = (cloudColorSun*(1.-alpha2) + cloudColorAmbient);      color.rgb= max(vec3(0), color.rgb);      color.rgb *= 2.0; -    color.rgb = scaleSoftClip(color.rgb);      /// Gamma correct for WL (soft clip effect).      frag_data[0] = vec4(color.rgb, alpha1); diff --git a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl index 6ab966ae01..4bf16b50bf 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl @@ -74,7 +74,6 @@ const float ONE_OVER_PI = 0.3183098861;  vec3 srgb_to_linear(vec3 cs);  vec3 atmosFragLightingLinear(vec3 light, vec3 additive, vec3 atten); -vec3 scaleSoftClipFragLinear(vec3 light);  float calcLegacyDistanceAttenuation(float distance, float falloff)  { @@ -396,7 +395,7 @@ vec3 pbrIbl(vec3 diffuseColor,      specContrib = specular * ao; -	return (diffuse + specular*0.5) * ao;  //reduce by half to place in appropriate color space for atmospherics +	return (diffuse + specular) * ao;  }  vec3 pbrIbl(vec3 diffuseColor, @@ -562,16 +561,13 @@ vec3 pbrBaseLight(vec3 diffuseColor, vec3 specularColor, float metallic, vec3 v,      float NdotV = clamp(abs(dot(norm, v)), 0.001, 1.0);      vec3 ibl_spec; -    color += pbrIbl(diffuseColor, specularColor, radiance, irradiance, ao, NdotV, 0.2, ibl_spec); +    color += pbrIbl(diffuseColor, specularColor, radiance, irradiance, ao, NdotV, perceptualRoughness, ibl_spec);      color += pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, norm, v, normalize(light_dir), specContrib) * sunlit * 2.75 * scol;      specContrib *= sunlit * 2.75 * scol;      specContrib += ibl_spec; -    color += colorEmissive*0.5; - -    color = atmosFragLightingLinear(color, additive, atten); -    color = scaleSoftClipFragLinear(color); +    color += colorEmissive;      return color;  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl b/indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl index f0522850de..fb97cd95b4 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl @@ -27,14 +27,9 @@  /*[EXTRA_CODE_HERE]*/ -#ifdef DEFINE_GL_FRAGCOLOR  out vec4 frag_color; -#else -#define frag_color gl_FragColor -#endif  vec3 fullbrightAtmosTransport(vec3 light); -vec3 fullbrightScaleSoftClip(vec3 light);  VARYING vec4 vertex_color;  VARYING vec2 vary_texcoord0; @@ -46,8 +41,6 @@ void main()  	vec4 color = diffuseLookup(vary_texcoord0.xy)*vertex_color;  	color.rgb = fullbrightAtmosTransport(color.rgb); -	color.rgb = fullbrightScaleSoftClip(color.rgb); -  	frag_color = color;  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl index afe504743d..3a15fd1111 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl @@ -88,8 +88,10 @@ void main()  #endif  #ifndef IS_HUD +    color.rgb = fullbrightAtmosTransport(color.rgb);      color.rgb = srgb_to_linear(color.rgb);  #endif +      frag_color.rgb = color.rgb;      frag_color.a   = color.a;  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl index a1cab87092..d41e0b202b 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl @@ -59,9 +59,9 @@ ATTRIBUTE vec2 texcoord0;  ATTRIBUTE vec4 tangent;  ATTRIBUTE vec2 texcoord1; -VARYING vec3 vary_mat0; -VARYING vec3 vary_mat1; -VARYING vec3 vary_mat2; +out vec3 vary_tangent; +flat out float vary_sign; +out vec3 vary_normal;  VARYING vec2 vary_texcoord1;  #else @@ -111,24 +111,21 @@ void main()  	vec3 n = normalize((mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz);  #ifdef HAS_NORMAL_MAP  	vec3 t = normalize((mat*vec4(tangent.xyz+position.xyz,1.0)).xyz-pos.xyz); -	vec3 b = cross(n, t)*tangent.w; -	 -	vary_mat0 = vec3(t.x, b.x, n.x); -	vary_mat1 = vec3(t.y, b.y, n.y); -	vary_mat2 = vec3(t.z, b.z, n.z); + +    vary_tangent = t; +    vary_sign = tangent.w; +    vary_normal = n;  #else //HAS_NORMAL_MAP -vary_normal  = n; +	vary_normal  = n;  #endif //HAS_NORMAL_MAP  #else //HAS_SKIN  	vec3 n = normalize(normal_matrix * normal);  #ifdef HAS_NORMAL_MAP  	vec3 t = normalize(normal_matrix * tangent.xyz); -	vec3 b = cross(n,t)*tangent.w; -	//vec3 t = cross(b,n) * binormal.w; -	 -	vary_mat0 = vec3(t.x, b.x, n.x); -	vary_mat1 = vec3(t.y, b.y, n.y); -	vary_mat2 = vec3(t.z, b.z, n.z); + +    vary_tangent = t; +    vary_sign = tangent.w; +    vary_normal = n;  #else //HAS_NORMAL_MAP  	vary_normal = n;  #endif //HAS_NORMAL_MAP diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl index 203c3aca4a..87324bca7f 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl @@ -45,9 +45,6 @@ vec3 linear_to_srgb(vec3 cl);  //===============================================================  // tone mapping taken from Khronos sample implementation  //=============================================================== -const float GAMMA = 2.2; -const float INV_GAMMA = 1.0 / GAMMA; -  // sRGB => XYZ => D65_2_D60 => AP1 => RRT_SAT  const mat3 ACESInputMat = mat3 @@ -66,29 +63,6 @@ const mat3 ACESOutputMat = mat3      -0.07367, -0.00605,  1.07602  ); - -// linear to sRGB approximation -// see http://chilliant.blogspot.com/2012/08/srgb-approximations-for-hlsl.html -vec3 linearTosRGB(vec3 color) -{ -    return pow(color, vec3(INV_GAMMA)); -} - - -// sRGB to linear approximation -// see http://chilliant.blogspot.com/2012/08/srgb-approximations-for-hlsl.html -vec3 sRGBToLinear(vec3 srgbIn) -{ -    return vec3(pow(srgbIn.xyz, vec3(GAMMA))); -} - - -vec4 sRGBToLinear(vec4 srgbIn) -{ -    return vec4(sRGBToLinear(srgbIn.xyz), srgbIn.w); -} - -  // ACES tone map (faster approximation)  // see: https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/  vec3 toneMapACES_Narkowicz(vec3 color) @@ -129,13 +103,13 @@ vec3 toneMapACES_Hill(vec3 color)  }  uniform float exposure; +uniform float gamma;  vec3 toneMap(vec3 color)  {      color *= exposure;  #ifdef TONEMAP_ACES_NARKOWICZ -    color *= 0.8;      color = toneMapACES_Narkowicz(color);  #endif @@ -147,11 +121,12 @@ vec3 toneMap(vec3 color)      // boost exposure as discussed in https://github.com/mrdoob/three.js/pull/19621      // this factor is based on the exposure correction of Krzysztof Narkowicz in his      // implemetation of ACES tone mapping -    color *= 0.85/0.6; +    color *= 1.0/0.6; +    //color /= 0.6;      color = toneMapACES_Hill(color);  #endif -    return linearTosRGB(color); +    return linear_to_srgb(color);  }  //=============================================================== @@ -194,16 +169,26 @@ float noise(vec2 x) {  //============================= + +vec3 legacyGamma(vec3 color) +{ +    color = 1. - clamp(color, vec3(0.), vec3(1.)); +    color = 1. - pow(color, vec3(gamma)); // s/b inverted already CPU-side + +    return color; +} +  void main()   {      //this is the one of the rare spots where diffuseRect contains linear color values (not sRGB)      vec4 diff = texture2D(diffuseRect, vary_fragcoord) + texture2D(emissiveRect, vary_fragcoord);      diff.rgb = toneMap(diff.rgb); -    vec2 tc = vary_fragcoord.xy*screen_res; - +    diff.rgb = legacyGamma(diff.rgb); +     +    vec2 tc = vary_fragcoord.xy*screen_res*4.0;      vec3 seed = (diff.rgb+vec3(1.0))*vec3(tc.xy, tc.x+tc.y);      vec3 nz = vec3(noise(seed.rg), noise(seed.gb), noise(seed.rb)); -    diff.rgb += nz*0.008; +    diff.rgb += nz*0.003;      //diff.rgb = nz;      frag_color = diff;  } diff --git a/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl b/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl index 16651dcdbc..745999fc2f 100644 --- a/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl @@ -33,6 +33,7 @@ uniform float waterFogKS;  vec3 getPositionEye();  vec3 srgb_to_linear(vec3 col); +vec3 linear_to_srgb(vec3 col);  vec4 applyWaterFogView(vec3 pos, vec4 color)  { @@ -68,48 +69,16 @@ vec4 applyWaterFogView(vec3 pos, vec4 color)      float D = pow(0.98, l*kd);      color.rgb = color.rgb * D + kc.rgb * L; +    color.a = kc.a + color.a;      return color;  }  vec4 applyWaterFogViewLinearNoClip(vec3 pos, vec4 color, vec3 sunlit)  { -    vec3 view = normalize(pos); -    //normalize view vector -    float es = -(dot(view, waterPlane.xyz)); - -     -    //find intersection point with water plane and eye vector - -    //get eye depth -    float e0 = max(-waterPlane.w, 0.0); - -    vec3 int_v = waterPlane.w > 0.0 ? view * waterPlane.w / es : vec3(0.0, 0.0, 0.0); - -    //get object depth -    float depth = length(pos - int_v); - -    //get "thickness" of water -    float l = max(depth, 0.1); - -    float kd = waterFogDensity*1.3; -    float ks = waterFogKS; -    vec4 kc = waterFogColor; -    kc.rgb = srgb_to_linear(kc.rgb); // TODO -- pass in waterFogColor linear -    kc.rgb *= sunlit; - -    float F = 0.98; - -    float t1 = -kd * pow(F, ks * e0); -    float t2 = kd + ks * es; -    float t3 = pow(F, t2 * l) - 1.0; - -    float L = min(t1 / t2 * t3, 1.0); - -    float D = pow(0.98, l * kd); - -    color.rgb = color.rgb * D + kc.rgb * L; - +    color.rgb = linear_to_srgb(color.rgb); +    color = applyWaterFogView(pos, color); +    color.rgb = srgb_to_linear(color.rgb);      return color;  } diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl index e2694e060e..ef35bf3fd7 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl @@ -250,6 +250,9 @@ void main()      calcAtmosphericVarsLinear(pos.xyz, norm, light_dir, sunlit, amblit, additive, atten); +    vec3 sunlit_linear = srgb_to_linear(sunlit); +    vec3 amblit_linear = amblit; +      vec3 irradiance;      vec3 glossenv;      vec3 legacyenv; @@ -266,7 +269,7 @@ void main()      color.a   = final_alpha; -    vec3 sun_contrib = min(final_da, shadow) * sunlit; +    vec3 sun_contrib = min(final_da, shadow) * sunlit_linear;      color.rgb = max(amblit, irradiance); @@ -274,8 +277,10 @@ void main()      color.rgb *= diffuse_linear.rgb; +    color.rgb = linear_to_srgb(color.rgb);      color.rgb = atmosFragLightingLinear(color.rgb, additive, atten);      color.rgb = scaleSoftClipFragLinear(color.rgb); +    color.rgb = srgb_to_linear(color.rgb);      vec4 light = vec4(0,0,0,0); @@ -294,8 +299,9 @@ void main()      color.rgb += light.rgb;  #endif // !defined(LOCAL_LIGHT_KILL) +  #ifdef WATER_FOG -    color = applyWaterFogViewLinear(pos.xyz, color, sunlit); +    color = applyWaterFogViewLinear(pos.xyz, color, sunlit_linear);  #endif // WATER_FOG  #endif // #else // FOR_IMPOSTOR @@ -303,6 +309,7 @@ void main()  #ifdef IS_HUD      color.rgb = linear_to_srgb(color.rgb);  #endif +      frag_color = color;  } diff --git a/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl index 2a093827cb..fb76db99a0 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl @@ -82,6 +82,8 @@ vec3 srgb_to_linear(vec3 c);  vec3 linear_to_srgb(vec3 c);  void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, out vec3 sunlit, out vec3 amblit, out vec3 atten, out vec3 additive); +vec3 atmosFragLightingLinear(vec3 color, vec3 additive, vec3 atten); +vec3 scaleSoftClipFragLinear(vec3 color);  void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist);  float calcLegacyDistanceAttenuation(float distance, float falloff); @@ -196,6 +198,8 @@ void main()      vec3 atten;      calcAtmosphericVarsLinear(pos.xyz, norm, light_dir, sunlit, amblit, additive, atten); +    vec3 sunlit_linear = srgb_to_linear(sunlit); +      vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5;  #ifdef HAS_SUN_SHADOW @@ -229,9 +233,14 @@ void main()      vec3 v = -normalize(pos.xyz);      vec3 spec; -    color = pbrBaseLight(diffuseColor, specularColor, metallic, v, norm.xyz, perceptualRoughness, light_dir, sunlit, scol, radiance, irradiance, colorEmissive, ao, additive, atten, spec); +    color = pbrBaseLight(diffuseColor, specularColor, metallic, v, norm.xyz, perceptualRoughness, light_dir, sunlit_linear, scol, radiance, irradiance, colorEmissive, ao, additive, atten, spec);      glare += max(max(spec.r, spec.g), spec.b); +    color.rgb = linear_to_srgb(color.rgb); +    color.rgb = atmosFragLightingLinear(color.rgb, additive, atten); +    color.rgb = scaleSoftClipFragLinear(color.rgb); +    color.rgb = srgb_to_linear(color.rgb); +      vec3 light = vec3(0);      // Punctual lights diff --git a/indra/newview/app_settings/shaders/class2/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class2/deferred/reflectionProbeF.glsl index 5fa53c374b..080f622155 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/reflectionProbeF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/reflectionProbeF.glsl @@ -47,7 +47,6 @@ void sampleReflectionProbesWater(inout vec3 ambenv, inout vec3 glossenv,          vec2 tc, vec3 pos, vec3 norm, float glossiness)  {      sampleReflectionProbes(ambenv, glossenv, tc, pos, norm, glossiness); -    glossenv *= 8.0;  }  vec4 sampleReflectionProbesDebug(vec3 pos) diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl index 6668a00841..1d02498209 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl @@ -33,8 +33,8 @@ vec3 linear_to_srgb(vec3 col);  vec3 atmosFragLighting(vec3 light, vec3 additive, vec3 atten)  {       light *= atten.r; -    light += additive; -    return light * 2.0; +    light += additive * 2.0; +    return light;  }  vec3 atmosFragLightingLinear(vec3 light, vec3 additive, vec3 atten) diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsFuncs.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsFuncs.glsl index f9f625ecdb..55e1411be2 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsFuncs.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsFuncs.glsl @@ -137,12 +137,15 @@ void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, ou      additive = (blue_horizon.rgb * blue_weight.rgb) * (cs + tmpAmbient.rgb) + (haze_horizon * haze_weight.rgb) * (cs * haze_glow + tmpAmbient.rgb);      // brightness of surface both sunlight and ambient -    sunlit = sunlight.rgb; -    amblit = tmpAmbient.rgb; +     +    // fudge sunlit and amblit to get consistent lighting compared to legacy +    // midday before PBR was a thing +    sunlit = sunlight.rgb * 0.7; +    amblit = tmpAmbient.rgb * 0.25; +      additive *= vec3(1.0 - combined_haze);  } -  vec3 srgb_to_linear(vec3 col);  // provide a touch of lighting in the opposite direction of the sun light  @@ -150,21 +153,26 @@ vec3 srgb_to_linear(vec3 col);  float ambientLighting(vec3 norm, vec3 light_dir)  {      float ambient = min(abs(dot(norm.xyz, light_dir.xyz)), 1.0); -    ambient *= 0.56; +    ambient *= 0.5;      ambient *= ambient;      ambient = (1.0 - ambient);      return ambient;  } -// return colors in linear space +// return lit amblit in linear space, leave sunlit and additive in sRGB space  void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, out vec3 sunlit, out vec3 amblit, out vec3 additive,                           out vec3 atten)  {      calcAtmosphericVars(inPositionEye, light_dir, 1.0, sunlit, amblit, additive, atten, false); -    sunlit = srgb_to_linear(sunlit); -    additive = srgb_to_linear(additive); -    amblit = ambient_linear; + +    // multiply by 2 to get same colors as when the "scaleSoftClip" implementation was doubling color values +    // (allows for mixing of light sources other than sunlight e.g. reflection probes) +    sunlit *= 2.0; + +    // squash ambient to approximate whatever weirdness legacy atmospherics were doing +    amblit = ambient_color * 0.5;      amblit *= ambientLighting(norm, light_dir); +    amblit = srgb_to_linear(amblit);  } diff --git a/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl b/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl index 9a9b179e6a..027bfb866f 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl @@ -22,43 +22,34 @@   * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA   * $/LicenseInfo$   */ -uniform float gamma; -vec3 getAtmosAttenuation(); -vec3 getAdditiveColor(); + // DEPRECATED -vec3 srgb_to_linear(vec3 col); -vec3 linear_to_srgb(vec3 col); +//soft clip effect has been moved to postDeferredGammaCorrect legacyGamma, this file is effectively dead +// but these functions need to be removed from all existing shaders before removing this file -vec3 scaleSoftClipFragLinear(vec3 light) -{ // identical to non-linear version and that's probably close enough -    //soft clip effect: -    light = 1. - clamp(light, vec3(0.), vec3(1.)); -    light = 1. - pow(light, vec3(gamma)); // s/b inverted already CPU-side +vec3 scaleSoftClipFrag(vec3 light) +{      return light;  } -vec3 scaleSoftClipFrag(vec3 light) -{ -    //soft clip effect: -    light = 1. - clamp(light, vec3(0.), vec3(1.)); -    light = 1. - pow(light, vec3(gamma)); // s/b inverted already CPU-side +vec3 scaleSoftClipFragLinear(vec3 light) +{ // identical to non-linear version and that's probably close enough      return light;  }  vec3 scaleSoftClip(vec3 light)  { -    return scaleSoftClipFrag(light); +    return light;  }  vec3 fullbrightScaleSoftClipFrag(vec3 light, vec3 add, vec3 atten)  { -    //return mix(scaleSoftClipFrag(light.rgb), add, atten); -    return scaleSoftClipFrag(light.rgb); +    return light;  }  vec3 fullbrightScaleSoftClip(vec3 light)  { -    return fullbrightScaleSoftClipFrag(light, getAdditiveColor(), getAtmosAttenuation()); +    return light;  } diff --git a/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl b/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl index c509d865ba..6aa719d200 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl @@ -48,23 +48,27 @@ vec3 atmosTransport(vec3 light)  vec3 fullbrightAtmosTransportFragLinear(vec3 light, vec3 additive, vec3 atten)  {      // same as non-linear version, probably fine -    float brightness = dot(light.rgb * 0.5, vec3(0.3333)) + 0.1;     -    return mix(atmosTransportFrag(light.rgb, additive, atten), light.rgb + additive, brightness * brightness); +    //float brightness = dot(light.rgb * 0.5, vec3(0.3333)) + 0.1;     +    //return mix(atmosTransportFrag(light.rgb, additive, atten), light.rgb + additive, brightness * brightness); +    return atmosTransportFrag(light, additive, atten);  }  vec3 fullbrightAtmosTransportFrag(vec3 light, vec3 additive, vec3 atten)  { -    float brightness = dot(light.rgb * 0.5, vec3(0.3333)) + 0.1;     -    return mix(atmosTransportFrag(light.rgb, additive, atten), light.rgb + additive, brightness * brightness); +    //float brightness = dot(light.rgb * 0.5, vec3(0.3333)) + 0.1;     +    //return mix(atmosTransportFrag(light.rgb, additive, atten), light.rgb + additive, brightness * brightness); +    return atmosTransportFrag(light, additive, atten);  }  vec3 fullbrightAtmosTransport(vec3 light)  { -    return fullbrightAtmosTransportFrag(light, getAdditiveColor(), getAtmosAttenuation()); +    //return fullbrightAtmosTransportFrag(light, getAdditiveColor(), getAtmosAttenuation()); +    return atmosTransport(light);  }  vec3 fullbrightShinyAtmosTransport(vec3 light)  { -    float brightness = dot(light.rgb, vec3(0.33333)); -    return mix(atmosTransport(light.rgb), (light.rgb + getAdditiveColor().rgb) * (2.0 - brightness), brightness * brightness); +    //float brightness = dot(light.rgb, vec3(0.33333)); +    //return mix(atmosTransport(light.rgb), (light.rgb + getAdditiveColor().rgb) * (2.0 - brightness), brightness * brightness); +    return atmosTransport(light);  } diff --git a/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl index 49529860be..6e41df34a4 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl @@ -210,9 +210,9 @@ uniform float minimum_alpha;  #endif  #ifdef HAS_NORMAL_MAP -VARYING vec3 vary_mat0; -VARYING vec3 vary_mat1; -VARYING vec3 vary_mat2; +in vec3 vary_normal; +in vec3 vary_tangent; +flat in float vary_sign;  VARYING vec2 vary_texcoord1;  #else  VARYING vec3 vary_normal; @@ -227,14 +227,17 @@ vec2 encode_normal(vec3 n);  vec3 getNormal(inout float glossiness)  {  #ifdef HAS_NORMAL_MAP -	vec4 norm = texture2D(bumpMap, vary_texcoord1.xy); -    glossiness *= norm.a; - -	norm.xyz = norm.xyz * 2 - 1; +	vec4 vNt = texture2D(bumpMap, vary_texcoord1.xy); +    glossiness *= vNt.a; +	vNt.xyz = vNt.xyz * 2 - 1; +    float sign = vary_sign; +    vec3 vN = vary_normal; +    vec3 vT = vary_tangent.xyz; +     +    vec3 vB = sign * cross(vN, vT); +    vec3 tnorm = normalize( vNt.x * vT + vNt.y * vB + vNt.z * vN ); -	return normalize(vec3(dot(norm.xyz,vary_mat0), -			  dot(norm.xyz,vary_mat1), -			  dot(norm.xyz,vary_mat2))); +	return tnorm;  #else  	return normalize(vary_normal);  #endif @@ -316,6 +319,7 @@ void main()      //forward rendering, output lit linear color      diffcol.rgb = srgb_to_linear(diffcol.rgb);      spec.rgb = srgb_to_linear(spec.rgb); +    spec.a = glossiness; // pack glossiness into spec alpha for lighting functions      vec3 pos = vary_position; @@ -334,16 +338,19 @@ void main()      vec3 atten;      calcAtmosphericVarsLinear(pos.xyz, norm.xyz, light_dir, sunlit, amblit, additive, atten); +    vec3 sunlit_linear = srgb_to_linear(sunlit); +    vec3 amblit_linear = amblit; +      vec3 ambenv;      vec3 glossenv;      vec3 legacyenv;      sampleReflectionProbesLegacy(ambenv, glossenv, legacyenv, pos.xy*0.5+0.5, pos.xyz, norm.xyz, glossiness, env);      // use sky settings ambient or irradiance map sample, whichever is brighter -    color = max(amblit, ambenv); +    color = max(amblit_linear, ambenv);      float da          = clamp(dot(norm.xyz, light_dir.xyz), 0.0, 1.0); -    vec3 sun_contrib = min(da, shadow) * sunlit; +    vec3 sun_contrib = min(da, shadow) * sunlit_linear;      color.rgb += sun_contrib;      color *= diffcol.rgb; @@ -354,7 +361,7 @@ void main()      if (glossiness > 0.0)  // specular reflection      {          float sa        = dot(normalize(refnormpersp), light_dir.xyz); -        vec3  dumbshiny = sunlit * shadow * (texture2D(lightFunc, vec2(sa, glossiness)).r); +        vec3  dumbshiny = sunlit_linear * shadow * (texture2D(lightFunc, vec2(sa, glossiness)).r);          // add the two types of shiny together          vec3 spec_contrib = dumbshiny * spec.rgb; @@ -379,8 +386,10 @@ void main()          glare += cur_glare;      } -    color.rgb = mix(atmosFragLightingLinear(color.rgb, additive, atten), fullbrightAtmosTransportFragLinear(color, additive, atten), emissive);  +    color.rgb = linear_to_srgb(color.rgb); +    color.rgb = atmosFragLightingLinear(color.rgb, additive, atten);       color.rgb = scaleSoftClipFragLinear(color.rgb); +    color.rgb = srgb_to_linear(color.rgb);      vec3 npos = normalize(-pos.xyz);      vec3 light = vec3(0, 0, 0); diff --git a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl index 23c6f4d5ae..a6a2543915 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl @@ -458,28 +458,24 @@ float sphereWeight(vec3 pos, vec3 dir, vec3 origin, float r, float min_da, int i  // dir - pixel normal  //  w - weight of sample (distance and angular attenuation)  //  dw - weight of sample (distance only) -// vi - return value of intersection point with influence volume -// wi - return value of approximate world space position of sampled pixel -// lod - which mip to bias towards (lower is higher res, sharper reflections) +// lod - which mip to sample (lower is higher res, sharper reflections)  // c - center of probe  // r2 - radius of probe squared  // i - index of probe  -vec3 tapRefMap(vec3 pos, vec3 dir, out float w, out float dw, out vec3 vi, out vec3 wi, float lod, vec3 c, int i) +vec3 tapRefMap(vec3 pos, vec3 dir, out float w, out float dw, float lod, vec3 c, int i)  { -    //lod = max(lod, 1);      // parallax adjustment -      vec3 v;      if (refIndex[i].w < 0) -    { +    {  // box probe          float d = 0;          v = boxIntersect(pos, dir, i, d);          w = max(d, 0.001);      }      else -    { +    { // sphere probe          float r = refSphere[i].w;          float rr = r * r; @@ -491,16 +487,12 @@ vec3 tapRefMap(vec3 pos, vec3 dir, out float w, out float dw, out vec3 vi, out v          w = sphereWeight(pos, dir, refSphere[i].xyz, r, 0.25, i, dw);      } -    vi = v; -      v -= c;      vec3 d = normalize(v);      v = env_mat * v; -    vec4 ret = textureLod(reflectionProbes, vec4(v.xyz, refIndex[i].x), lod); - -    wi = d * ret.a * 256.0+c; +    vec4 ret = textureLod(reflectionProbes, vec4(v.xyz, refIndex[i].x), lod) * refParams[i].y;      return ret.rgb;  } @@ -568,12 +560,11 @@ vec3 sampleProbes(vec3 pos, vec3 dir, float lod)          float w = 0;          float dw = 0; -        vec3 vi, wi;          vec3 refcol;          { -            refcol = tapRefMap(pos, dir, w, dw, vi, wi, lod, refSphere[i].xyz, i); +            refcol = tapRefMap(pos, dir, w, dw, lod, refSphere[i].xyz, i);              col[p] += refcol.rgb*w;              wsum[p] += w; @@ -665,7 +656,7 @@ void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,          vec2 tc, vec3 pos, vec3 norm, float glossiness)  {      // TODO - don't hard code lods -    float reflection_lods = max_probe_lod; +    float reflection_lods = max_probe_lod-1;      preProbeSample(pos);      vec3 refnormpersp = reflect(pos.xyz, norm.xyz); @@ -690,6 +681,9 @@ void sampleReflectionProbesWater(inout vec3 ambenv, inout vec3 glossenv,          vec2 tc, vec3 pos, vec3 norm, float glossiness)  {      sampleReflectionProbes(ambenv, glossenv, tc, pos, norm, glossiness); + +    // fudge factor to get PBR water at a similar luminance ot legacy water +    glossenv *= 0.25;  }  void debugTapRefMap(vec3 pos, vec3 dir, float depth, int i, inout vec4 col) diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl index 8d48e6f596..dfd1d47b3e 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl @@ -85,6 +85,8 @@ float getDepth(vec2 pos_screen);  vec3 linear_to_srgb(vec3 c);  vec3 srgb_to_linear(vec3 c); +uniform vec4 waterPlane; +  #ifdef WATER_FOG  vec4 applyWaterFogViewLinear(vec3 pos, vec4 color);  #endif @@ -153,6 +155,24 @@ void main()      calcAtmosphericVarsLinear(pos.xyz, norm.xyz, light_dir, sunlit, amblit, additive, atten); +    vec3 sunlit_linear = srgb_to_linear(sunlit); +    vec3 amblit_linear = amblit; + +    bool do_atmospherics = false; + +#ifndef WATER_FOG +    // when above water, mask off atmospherics below water +    if (dot(pos.xyz, waterPlane.xyz) + waterPlane.w > 0.0) +    { +        do_atmospherics = true; +    } +#else +    do_atmospherics = true; +#endif + +    vec3  irradiance = vec3(0); +    vec3  radiance  = vec3(0); +      if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR))      {          vec3 orm = texture2D(specularRect, tc).rgb;  @@ -161,23 +181,32 @@ void main()          float ao = orm.r * ambocc;          vec3 colorEmissive = texture2D(emissiveRect, tc).rgb; -          // PBR IBL          float gloss      = 1.0 - perceptualRoughness; -        vec3  irradiance = vec3(0); -        vec3  radiance  = vec3(0); +                  sampleReflectionProbes(irradiance, radiance, tc, pos.xyz, norm.xyz, gloss);          // Take maximium of legacy ambient vs irradiance sample as irradiance          // NOTE: ao is applied in pbrIbl (see pbrBaseLight), do not apply here -        irradiance       = max(amblit,irradiance); +        irradiance       = max(amblit_linear,irradiance);          vec3 diffuseColor;          vec3 specularColor;          calcDiffuseSpecular(baseColor.rgb, metallic, diffuseColor, specularColor);          vec3 v = -normalize(pos.xyz); -        color = pbrBaseLight(diffuseColor, specularColor, metallic, v, norm.xyz, perceptualRoughness, light_dir, sunlit, scol, radiance, irradiance, colorEmissive, ao, additive, atten); +        color = vec3(1,0,1); +        color = pbrBaseLight(diffuseColor, specularColor, metallic, v, norm.xyz, perceptualRoughness, light_dir, sunlit_linear, scol, radiance, irradiance, colorEmissive, ao, additive, atten); + +         +        if (do_atmospherics) +        { +            color = linear_to_srgb(color); +            color = atmosFragLightingLinear(color, additive, atten); +            color = srgb_to_linear(color); +        } +         +              }      else if (!GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_ATMOS))      { @@ -199,12 +228,12 @@ void main()          sampleReflectionProbesLegacy(irradiance, glossenv, legacyenv, tc, pos.xyz, norm.xyz, spec.a, envIntensity);          // use sky settings ambient or irradiance map sample, whichever is brighter -        irradiance = max(amblit, irradiance); +        irradiance = max(amblit_linear, irradiance);          // apply lambertian IBL only (see pbrIbl)          color.rgb = irradiance * ambocc; -        vec3 sun_contrib = min(da, scol) * sunlit; +        vec3 sun_contrib = min(da, scol) * sunlit_linear;          color.rgb += sun_contrib;          color.rgb *= baseColor.rgb; @@ -230,9 +259,16 @@ void main()              applyLegacyEnv(color, legacyenv, spec, pos.xyz, norm.xyz, envIntensity);          } -        color = mix(atmosFragLightingLinear(color, additive, atten), fullbrightAtmosTransportFragLinear(color, additive, atten), baseColor.a); -        color = scaleSoftClipFragLinear(color); -    } +         +        if (do_atmospherics) +        { +            color = linear_to_srgb(color); +            color = atmosFragLightingLinear(color, additive, atten); +            color = srgb_to_linear(color); +        } +   } + +          #ifdef WATER_FOG          vec4 fogged = applyWaterFogViewLinear(pos.xyz, vec4(color, bloom)); diff --git a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl index a87682affb..7524567f6b 100644 --- a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl +++ b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl @@ -114,6 +114,7 @@ vec3 BlendNormal(vec3 bump1, vec3 bump2)  }  vec3 srgb_to_linear(vec3 col); +vec3 linear_to_srgb(vec3 col);  vec3 vN, vT, vB; @@ -200,6 +201,8 @@ void main()      calcAtmosphericVarsLinear(pos.xyz, wavef, vary_light_dir, sunlit, amblit, additive, atten); +    vec3 sunlit_linear = srgb_to_linear(sunlit); +  #ifdef TRANSPARENT_WATER      vec4 fb = texture2D(screenTex, distort2);      float depth = texture2D(screenDepth, distort2).r; @@ -216,9 +219,12 @@ void main()      fb = applyWaterFogViewLinear(refPos, fb, sunlit);  #else -    vec4 fb = applyWaterFogViewLinear(viewVec*2048.0, vec4(1.0), sunlit); +    vec4 fb = applyWaterFogViewLinear(viewVec*2048.0, vec4(1.0), sunlit_linear);  #endif +    // fudge sample on other side of water to be a tad darker +    fb.rgb *= 0.75; +      float metallic = 0.0;      float perceptualRoughness = 0.05;      float gloss      = 1.0 - perceptualRoughness; @@ -247,10 +253,7 @@ void main()      vec3 punctual = pbrPunctual(vec3(0), specularColor, 0.1, metallic, normalize(wavef+up*max(dist, 32.0)/32.0*(1.0-vdu)), v, normalize(light_dir)); -    vec3 color = punctual * sunlit * 2.75 * scol; - -    color = atmosFragLightingLinear(color, additive, atten); -    color = scaleSoftClipFragLinear(color); +    vec3 color = punctual * sunlit_linear * 2.75 * scol;      vec3 ibl = pbrIbl(vec3(0), vec3(1), radiance, vec3(0), ao, NdotV, 0.0); @@ -274,6 +277,12 @@ void main()      color = mix(color, fb.rgb, f); +    color.rgb = linear_to_srgb(color.rgb); +    color = atmosFragLightingLinear(color, additive, atten); +    color = scaleSoftClipFragLinear(color); +    color.rgb = srgb_to_linear(color.rgb); + +      float spec = min(max(max(punctual.r, punctual.g), punctual.b), 0.05);      frag_color = vec4(color, spec); //*sunAngle2); diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index b24244c188..020c7bbc74 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -1,4 +1,4 @@ -version 50 +version 51  // The version number above should be incremented IF AND ONLY IF some  // change has been made that is sufficiently important to justify  // resetting the graphics preferences of all users to the recommended @@ -99,7 +99,7 @@ RenderVolumeLODFactor		1	1.125  RenderDeferredSSAO			1	0  RenderUseAdvancedAtmospherics 1 0  RenderShadowDetail			1	0 -WLSkyDetail					1	48 +WLSkyDetail					1	96  RenderFSAASamples			1	0  RenderScreenSpaceReflections 1  0 @@ -126,7 +126,7 @@ RenderVolumeLODFactor		1	1.125  RenderDeferredSSAO			1	0  RenderUseAdvancedAtmospherics 1 0  RenderShadowDetail			1	0 -WLSkyDetail					1	48 +WLSkyDetail					1	96  RenderFSAASamples			1	0  RenderScreenSpaceReflections 1  0 @@ -151,7 +151,7 @@ RenderVolumeLODFactor		1	1.125  RenderDeferredSSAO			1	0  RenderUseAdvancedAtmospherics 1 0  RenderShadowDetail			1	0 -WLSkyDetail					1	48 +WLSkyDetail					1	96  RenderFSAASamples			1	2  RenderReflectionsEnabled    1   1  RenderReflectionProbeDetail	1	0 @@ -178,7 +178,7 @@ RenderVolumeLODFactor		1	1.125  RenderDeferredSSAO			1	0  RenderUseAdvancedAtmospherics 1 0  RenderShadowDetail			1	0 -WLSkyDetail					1	48 +WLSkyDetail					1	96  RenderFSAASamples			1	2  RenderReflectionsEnabled    1   1  RenderReflectionProbeDetail	1	1 @@ -205,7 +205,7 @@ RenderVolumeLODFactor		1	1.125  RenderDeferredSSAO			1	1  RenderUseAdvancedAtmospherics 1 0  RenderShadowDetail			1	0 -WLSkyDetail					1	48 +WLSkyDetail					1	96  RenderFSAASamples			1	2  RenderReflectionsEnabled    1   1  RenderReflectionProbeDetail	1	1 @@ -232,7 +232,7 @@ RenderVolumeLODFactor		1	1.125  RenderDeferredSSAO			1	1  RenderUseAdvancedAtmospherics 1 0  RenderShadowDetail			1	2 -WLSkyDetail					1	48 +WLSkyDetail					1	96  RenderFSAASamples			1	2  RenderReflectionsEnabled    1   1  RenderReflectionProbeDetail	1	1 diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt index df12f56dd2..dbb33b3997 100644 --- a/indra/newview/featuretable_mac.txt +++ b/indra/newview/featuretable_mac.txt @@ -1,4 +1,4 @@ -version 45 +version 46  // The version number above should be incremented IF AND ONLY IF some  // change has been made that is sufficiently important to justify  // resetting the graphics preferences of all users to the recommended @@ -95,7 +95,7 @@ RenderVolumeLODFactor		1	0.5  RenderDeferredSSAO			1	0  RenderUseAdvancedAtmospherics 1 0  RenderShadowDetail			1	0 -WLSkyDetail					1	48 +WLSkyDetail					1	96  RenderFSAASamples			1	0  RenderReflectionsEnabled    1   0  RenderReflectionProbeDetail	1	0 @@ -122,7 +122,7 @@ RenderVolumeLODFactor		1	1.125  RenderDeferredSSAO			1	0  RenderUseAdvancedAtmospherics 1 0  RenderShadowDetail			1	0 -WLSkyDetail					1	48 +WLSkyDetail					1	96  RenderFSAASamples			1	0  RenderReflectionsEnabled    1   1  RenderReflectionProbeDetail	1	0 @@ -149,7 +149,7 @@ RenderVolumeLODFactor		1	1.125  RenderDeferredSSAO			1	0  RenderUseAdvancedAtmospherics 1 0  RenderShadowDetail			1	0 -WLSkyDetail					1	48 +WLSkyDetail					1	96  RenderFSAASamples			1	2  RenderReflectionsEnabled    1   1  RenderReflectionProbeDetail	1	0 @@ -176,7 +176,7 @@ RenderVolumeLODFactor		1	1.125  RenderDeferredSSAO			1	0  RenderUseAdvancedAtmospherics 1 0  RenderShadowDetail			1	0 -WLSkyDetail					1	48 +WLSkyDetail					1	96  RenderFSAASamples			1	2  RenderReflectionsEnabled    1   1  RenderReflectionProbeDetail	1	0 @@ -203,7 +203,7 @@ RenderVolumeLODFactor		1	1.125  RenderDeferredSSAO			1	1  RenderUseAdvancedAtmospherics 1 0  RenderShadowDetail			1	0 -WLSkyDetail					1	48 +WLSkyDetail					1	96  RenderFSAASamples			1	2  RenderReflectionsEnabled    1   1  RenderReflectionProbeDetail	1	1 @@ -230,7 +230,7 @@ RenderVolumeLODFactor		1	1.125  RenderDeferredSSAO			1	1  RenderShadowDetail			1	2  RenderUseAdvancedAtmospherics 1 0 -WLSkyDetail					1	48 +WLSkyDetail					1	96  RenderFSAASamples			1	2  RenderReflectionsEnabled    1   1  RenderReflectionProbeDetail	1	1 diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 061feba0a4..7731f37c94 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -572,8 +572,7 @@ static void settings_to_globals()  static void settings_modify()  {      LLPipeline::sRenderTransparentWater = gSavedSettings.getBOOL("RenderTransparentWater"); -    LLPipeline::sRenderBump = TRUE; // FALSE is deprecated --  gSavedSettings.getBOOL("RenderObjectBump"); -    LLPipeline::sRenderDeferred = TRUE; // FALSE is deprecated --  LLPipeline::sRenderBump&& gSavedSettings.getBOOL("RenderDeferred"); +    LLPipeline::sRenderDeferred = TRUE; // FALSE is deprecated      LLRenderTarget::sUseFBO             = LLPipeline::sRenderDeferred;      LLVOSurfacePatch::sLODFactor        = gSavedSettings.getF32("RenderTerrainLODFactor");      LLVOSurfacePatch::sLODFactor *= LLVOSurfacePatch::sLODFactor; //square lod factor to get exponential range of [1,4] diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 45df4d0eee..04b6ebd14c 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -1094,11 +1094,11 @@ void LLDrawable::updateUVMinMax()  bool LLDrawable::isVisible() const  {  	if (LLViewerOctreeEntryData::isVisible()) -{  -		return true; -} +    {  +		    return true; +    } -{ +    {  		LLViewerOctreeGroup* group = mEntry->getGroup();  		if (group && group->isVisible())  		{ diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index a74950dad2..d7e4632ab0 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -357,8 +357,6 @@ void LLFace::switchTexture(U32 ch, LLViewerTexture* new_texture)  	llassert(mTexture[ch].notNull()); -	new_texture->addTextureStats(mTexture[ch]->getMaxVirtualSize()) ; -  	if (ch == LLRender::DIFFUSE_MAP)  	{  	    getViewerObject()->changeTEImage(mTEOffset, new_texture) ; @@ -1109,20 +1107,13 @@ bool LLFace::canRenderAsMask()  		(te->getGlow() == 0.f) && // glowing masks are hard to implement - don't mask  		getTexture()->getIsAlphaMask()) // texture actually qualifies for masking (lazily recalculated but expensive)  	{ -		if (LLPipeline::sRenderDeferred) -		{ -			if (getViewerObject()->isHUDAttachment() || te->getFullbright()) -			{ //hud attachments and fullbright objects are NOT subject to the deferred rendering pipe -				return LLPipeline::sAutoMaskAlphaNonDeferred; -			} -			else -			{ -				return LLPipeline::sAutoMaskAlphaDeferred; -			} +		if (getViewerObject()->isHUDAttachment() || te->getFullbright()) +		{ //hud attachments and fullbright objects are NOT subject to the deferred rendering pipe +			return LLPipeline::sAutoMaskAlphaNonDeferred;  		}  		else  		{ -			return LLPipeline::sAutoMaskAlphaNonDeferred; +			return LLPipeline::sAutoMaskAlphaDeferred;  		}  	} @@ -1262,19 +1253,10 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  			bool shiny_in_alpha = false; -			if (LLPipeline::sRenderDeferred) -			{ //store shiny in alpha if we don't have a specular map -				if  (!mat || mat->getSpecularID().isNull()) -				{ -					shiny_in_alpha = true; -				} -			} -			else +			//store shiny in alpha if we don't have a specular map +			if  (!mat || mat->getSpecularID().isNull())  			{ -				if (!mat || mat->getDiffuseAlphaMode() != LLMaterial::DIFFUSE_ALPHA_MODE_MASK) -				{ -					shiny_in_alpha = true; -				} +				shiny_in_alpha = true;  			}  			if (shiny_in_alpha) @@ -1322,39 +1304,75 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  		}  	} + +    LLMaterial* mat = tep->getMaterialParams().get(); +    LLGLTFMaterial* gltf_mat = tep->getGLTFRenderMaterial(); +  	F32 r = 0, os = 0, ot = 0, ms = 0, mt = 0, cos_ang = 0, sin_ang = 0; -	bool do_xform = false; -	if (rebuild_tcoord) -	{ -		if (tep) -		{ -			r  = tep->getRotation(); -			os = tep->mOffsetS; -			ot = tep->mOffsetT; -			ms = tep->mScaleS; -			mt = tep->mScaleT; -			cos_ang = cos(r); -			sin_ang = sin(r); - -			if (cos_ang != 1.f ||  -				sin_ang != 0.f || -				os != 0.f || -				ot != 0.f || -				ms != 1.f || -				mt != 1.f) -			{ -				do_xform = true; -			} -			else -			{ -				do_xform = false; -			}	 -		} -		else -		{ -			do_xform = false; -		} -	} + +    constexpr S32 XFORM_NONE = 0; +    constexpr S32 XFORM_BLINNPHONG_COLOR = 1; +    constexpr S32 XFORM_BLINNPHONG_NORMAL = 1 << 1; +    constexpr S32 XFORM_BLINNPHONG_SPECULAR = 1 << 2; + +    S32 xforms = XFORM_NONE; +    // For GLTF, transforms will be applied later +    if (rebuild_tcoord && tep && !gltf_mat) +    { +        r  = tep->getRotation(); +        os = tep->mOffsetS; +        ot = tep->mOffsetT; +        ms = tep->mScaleS; +        mt = tep->mScaleT; +        cos_ang = cos(r); +        sin_ang = sin(r); + +        if (cos_ang != 1.f || +            sin_ang != 0.f || +            os != 0.f || +            ot != 0.f || +            ms != 1.f || +            mt != 1.f) +        { +            xforms |= XFORM_BLINNPHONG_COLOR; +        } +        if (mat) +        { +            F32 r_norm = 0, os_norm = 0, ot_norm = 0, ms_norm = 0, mt_norm = 0, cos_ang_norm = 0, sin_ang_norm = 0; +            mat->getNormalOffset(os_norm, ot_norm); +            mat->getNormalRepeat(ms_norm, mt_norm); +            r_norm = mat->getNormalRotation(); +            cos_ang_norm = cos(r_norm); +            sin_ang_norm = sin(r_norm); +            if (cos_ang_norm != 1.f || +                sin_ang_norm != 0.f || +                os_norm != 0.f || +                ot_norm != 0.f || +                ms_norm != 1.f || +                mt_norm != 1.f) +            { +                xforms |= XFORM_BLINNPHONG_NORMAL; +            } +        } +        if (mat) +        { +            F32 r_spec = 0, os_spec = 0, ot_spec = 0, ms_spec = 0, mt_spec = 0, cos_ang_spec = 0, sin_ang_spec = 0; +            mat->getSpecularOffset(os_spec, ot_spec); +            mat->getSpecularRepeat(ms_spec, mt_spec); +            r_spec = mat->getSpecularRotation(); +            cos_ang_spec = cos(r_spec); +            sin_ang_spec = sin(r_spec); +            if (cos_ang_spec != 1.f || +                sin_ang_spec != 0.f || +                os_spec != 0.f || +                ot_spec != 0.f || +                ms_spec != 1.f || +                mt_spec != 1.f) +            { +                xforms |= XFORM_BLINNPHONG_SPECULAR; +            } +        } +    }      const LLMeshSkinInfo* skin = nullptr;      LLMatrix4a mat_vert; @@ -1495,7 +1513,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  					sin_ang = 0.f;  					ms = mt = 1.f; -					do_xform = false; +                    xforms = XFORM_NONE;  				}  				if (getVirtualSize() >= MIN_TEX_ANIM_SIZE) // || isState(LLFace::RIGGED)) @@ -1507,15 +1525,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  			LLVector4a scalea;  			scalea.load3(scale.mV); -			LLMaterial* mat = tep->getMaterialParams().get(); -            LLGLTFMaterial* gltf_mat = tep->getGLTFRenderMaterial(); - -            if (gltf_mat) -            { -                // Transforms will be applied later -                do_xform = false; -            } -  			bool do_bump = bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1);  			if ((mat || gltf_mat) && !do_bump) @@ -1524,7 +1533,8 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  					     || mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD2);  			} -			bool do_tex_mat = tex_mode && mTextureMatrix; +            // For GLTF materials: Transforms will be applied later +			bool do_tex_mat = tex_mode && mTextureMatrix && !gltf_mat;  			if (!do_bump)  			{ //not bump mapped, might be able to do a cheap update @@ -1535,7 +1545,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,                      LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - texgen");  					if (!do_tex_mat)  					{ -						if (!do_xform) +						if (xforms == XFORM_NONE)  						{                              LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("ggv - texgen 1");  							S32 tc_size = (num_vertices*2*sizeof(F32)+0xF) & ~0xF; @@ -1614,7 +1624,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  							*tex_coords0++ = tc;	  						}  					} -					else +					else if (xforms != XFORM_NONE)  					{  						for (S32 i = 0; i < num_vertices; i++)  						{	 @@ -1630,6 +1640,20 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  							*tex_coords0++ = tc;	  						}  					} +					else +					{ +						for (S32 i = 0; i < num_vertices; i++) +						{	 +							LLVector2 tc(vf.mTexCoords[i]); +							LLVector4a& norm = vf.mNormals[i]; +							LLVector4a& center = *(vf.mCenter); +							LLVector4a vec = vf.mPositions[i];	 +							vec.mul(scalea); +							planarProjection(tc, norm, center, vec); + +							*tex_coords0++ = tc;	 +						} +					}  				}  			}  			else @@ -1647,12 +1671,15 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  				for (U32 ch = 0; ch < 3; ++ch)  				{ +                    S32 xform_channel = XFORM_NONE;  					switch (ch)  					{  						case 0:  +                            xform_channel = XFORM_BLINNPHONG_COLOR;  							mVertexBuffer->getTexCoord0Strider(dst, mGeomIndex, mGeomCount);   							break;  						case 1: +                            xform_channel = XFORM_BLINNPHONG_NORMAL;  							if (mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1))  							{  								mVertexBuffer->getTexCoord1Strider(dst, mGeomIndex, mGeomCount); @@ -1673,6 +1700,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  							}  							break;  						case 2: +                            xform_channel = XFORM_BLINNPHONG_SPECULAR;  							if (mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD2))  							{  								mVertexBuffer->getTexCoord2Strider(dst, mGeomIndex, mGeomCount); @@ -1692,46 +1720,47 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  							}  							break;  					} +                    const bool do_xform = (xforms & xform_channel) != XFORM_NONE; -				for (S32 i = 0; i < num_vertices; i++) -				{	 -					LLVector2 tc(vf.mTexCoords[i]); -			 -					LLVector4a& norm = vf.mNormals[i]; -				 -					LLVector4a& center = *(vf.mCenter); -		    -					if (texgen != LLTextureEntry::TEX_GEN_DEFAULT) -					{ -						LLVector4a vec = vf.mPositions[i]; -				 -						vec.mul(scalea); - -							if (texgen == LLTextureEntry::TEX_GEN_PLANAR) -						{ -								planarProjection(tc, norm, center, vec); -						}		 -					} - -					if (tex_mode && mTextureMatrix) -					{ -						LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f); -						tmp = tmp * *mTextureMatrix; -						tc.mV[0] = tmp.mV[0]; -						tc.mV[1] = tmp.mV[1]; -					} -					else -					{ -						xform(tc, cos_ang, sin_ang, os, ot, ms, mt); -					} - -						*dst++ = tc; -					if (do_bump) -					{ -						bump_tc.push_back(tc); -					} -				} +                    for (S32 i = 0; i < num_vertices; i++) +                    {    +                        LLVector2 tc(vf.mTexCoords[i]); +                 +                        LLVector4a& norm = vf.mNormals[i]; +                     +                        LLVector4a& center = *(vf.mCenter); +                +                        if (texgen != LLTextureEntry::TEX_GEN_DEFAULT) +                        { +                            LLVector4a vec = vf.mPositions[i]; +                     +                            vec.mul(scalea); + +                            if (texgen == LLTextureEntry::TEX_GEN_PLANAR) +                            { +                                planarProjection(tc, norm, center, vec); +                            }        +                        } + +                        if (tex_mode && mTextureMatrix) +                        { +                            LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f); +                            tmp = tmp * *mTextureMatrix; +                            tc.mV[0] = tmp.mV[0]; +                            tc.mV[1] = tmp.mV[1]; +                        } +                        else if (do_xform) +                        { +                            xform(tc, cos_ang, sin_ang, os, ot, ms, mt); +                        } + +                        *dst++ = tc; +                        if (do_bump) +                        { +                            bump_tc.push_back(tc); +                        } +                    }  				}  				if ((!mat && !gltf_mat) && do_bump) diff --git a/indra/newview/llface.h b/indra/newview/llface.h index ee8316018b..0a66dc6ba6 100644 --- a/indra/newview/llface.h +++ b/indra/newview/llface.h @@ -235,6 +235,7 @@ public: //aligned members  	LLVector4a		mExtents[2];  private: +    friend class LLViewerTextureList;  	F32         adjustPartialOverlapPixelArea(F32 cos_angle_to_view_dir, F32 radius );  	BOOL        calcPixelArea(F32& cos_angle_to_view_dir, F32& radius) ;  public: diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp index 29e8210d8e..014c8a4d2d 100644 --- a/indra/newview/llfilepicker.cpp +++ b/indra/newview/llfilepicker.cpp @@ -631,6 +631,7 @@ std::unique_ptr<std::vector<std::string>> LLFilePicker::navOpenFilterProc(ELoadF              allowedv->push_back("anim");              break;          case FFLOAD_GLTF: +        case FFLOAD_MATERIAL:              allowedv->push_back("gltf");              allowedv->push_back("glb");              break; diff --git a/indra/newview/lllocalgltfmaterials.cpp b/indra/newview/lllocalgltfmaterials.cpp index a9099b1ce9..996b168262 100644 --- a/indra/newview/lllocalgltfmaterials.cpp +++ b/indra/newview/lllocalgltfmaterials.cpp @@ -214,12 +214,18 @@ bool LLLocalGLTFMaterial::loadMaterial()              LLStringUtil::toLower(filename_lc);              std::string material_name; -            // Might be a good idea to make these textures into local textures -            decode_successful = LLTinyGLTFHelper::getMaterialFromFile( -                mFilename, -                mMaterialIndex, -                this, -                material_name); +            tinygltf::Model model; +            decode_successful = LLTinyGLTFHelper::loadModel(mFilename, model); +            if (decode_successful) +            { +                // Might be a good idea to make these textures into local textures +                decode_successful = LLTinyGLTFHelper::getMaterialFromModel( +                    mFilename, +                    model, +                    mMaterialIndex, +                    this, +                    material_name); +            }              if (!material_name.empty())              { @@ -308,7 +314,10 @@ S32 LLLocalGLTFMaterialMgr::addUnit(const std::vector<std::string>& filenames)  S32 LLLocalGLTFMaterialMgr::addUnit(const std::string& filename)  { -    S32 materials_in_file = LLTinyGLTFHelper::getMaterialCountFromFile(filename); +    tinygltf::Model model; +    LLTinyGLTFHelper::loadModel(filename, model); + +    S32 materials_in_file = model.materials.size();      if (materials_in_file <= 0)      {          return 0; diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 64ce5fd4d2..4cdc503af8 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -1622,40 +1622,13 @@ static void pack_textures(      }  } -void LLMaterialEditor::uploadMaterialFromFile(const std::string& filename, S32 index) +void LLMaterialEditor::uploadMaterialFromModel(const std::string& filename, tinygltf::Model& model_in, S32 index)  {      if (index < 0 || !LLMaterialEditor::capabilitiesAvailable())      {          return;      } -    tinygltf::TinyGLTF loader; -    std::string        error_msg; -    std::string        warn_msg; - -    bool loaded = false; -    tinygltf::Model model_in; - -    std::string filename_lc = filename; -    LLStringUtil::toLower(filename_lc); - -    // Load a tinygltf model fom a file. Assumes that the input filename has already been -    // been sanitized to one of (.gltf , .glb) extensions, so does a simple find to distinguish. -    if (std::string::npos == filename_lc.rfind(".gltf")) -    {  // file is binary -        loaded = loader.LoadBinaryFromFile(&model_in, &error_msg, &warn_msg, filename); -    } -    else -    {  // file is ascii -        loaded = loader.LoadASCIIFromFile(&model_in, &error_msg, &warn_msg, filename); -    } - -    if (!loaded) -    { -        LLNotificationsUtil::add("CannotUploadMaterial"); -        return; -    } -      if (model_in.materials.empty())      {          // materials are missing @@ -1672,13 +1645,15 @@ void LLMaterialEditor::uploadMaterialFromFile(const std::string& filename, S32 i      // This uses 'filename' to make sure multiple bulk uploads work      // instead of fighting for a single instance.      LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor", LLSD().with("filename", filename).with("index", LLSD::Integer(index))); -    me->loadMaterial(model_in, filename_lc, index, false); +    me->loadMaterial(model_in, filename, index, false);      me->saveIfNeeded();  }  void LLMaterialEditor::loadMaterialFromFile(const std::string& filename, S32 index)  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; +      tinygltf::TinyGLTF loader;      std::string        error_msg;      std::string        warn_msg; @@ -1725,12 +1700,12 @@ void LLMaterialEditor::loadMaterialFromFile(const std::string& filename, S32 ind      if (index >= 0)      {          // Prespecified material -        me->loadMaterial(model_in, filename_lc, index); +        me->loadMaterial(model_in, filename, index);      }      else if (model_in.materials.size() == 1)      {          // Only one, just load it -        me->loadMaterial(model_in, filename_lc, 0); +        me->loadMaterial(model_in, filename, 0);      }      else      { @@ -1738,6 +1713,7 @@ void LLMaterialEditor::loadMaterialFromFile(const std::string& filename, S32 ind          std::list<std::string> material_list;          std::vector<tinygltf::Material>::const_iterator mat_iter = model_in.materials.begin();          std::vector<tinygltf::Material>::const_iterator mat_end = model_in.materials.end(); +                  for (; mat_iter != mat_end; mat_iter++)          {              std::string mat_name = mat_iter->name; @@ -1750,10 +1726,13 @@ void LLMaterialEditor::loadMaterialFromFile(const std::string& filename, S32 ind                  material_list.push_back(mat_name);              }          } + +        material_list.push_back(me->getString("material_batch_import_text")); +          LLFloaterComboOptions::showUI( -            [me, model_in, filename_lc](const std::string& option, S32 index) +            [me, model_in, filename](const std::string& option, S32 index)          { -            me->loadMaterial(model_in, filename_lc, index); +            me->loadMaterial(model_in, filename, index);          },              me->getString("material_selection_title"),              me->getString("material_selection_text"), @@ -1961,13 +1940,22 @@ void LLMaterialEditor::onSaveObjectsMaterialAsMsgCallback(const LLSD& notificati      }  } -void LLMaterialEditor::loadMaterial(const tinygltf::Model &model_in, const std::string &filename_lc, S32 index, bool open_floater) +const void upload_bulk(const std::vector<std::string>& filenames, LLFilePicker::ELoadFilter type); + +void LLMaterialEditor::loadMaterial(const tinygltf::Model &model_in, const std::string &filename, S32 index, bool open_floater)  { +    if (index == model_in.materials.size()) +    { +        // bulk upload all the things +        upload_bulk({ filename }, LLFilePicker::FFLOAD_MATERIAL); +        return; +    } +      if (model_in.materials.size() <= index)      {          return;      } -    std::string folder = gDirUtilp->getDirName(filename_lc); +    std::string folder = gDirUtilp->getDirName(filename);      tinygltf::Material material_in = model_in.materials[index]; @@ -2055,7 +2043,7 @@ void LLMaterialEditor::loadMaterial(const tinygltf::Model &model_in, const std::      setFromGltfModel(model_in, index); -    setFromGltfMetaData(filename_lc, model_in, index); +    setFromGltfMetaData(filename, model_in, index);      markChangesUnsaved(U32_MAX); diff --git a/indra/newview/llmaterialeditor.h b/indra/newview/llmaterialeditor.h index 0401190773..6f674a4170 100644 --- a/indra/newview/llmaterialeditor.h +++ b/indra/newview/llmaterialeditor.h @@ -103,7 +103,7 @@ class LLMaterialEditor : public LLPreview, public LLVOInventoryListener      void loadAsset() override;      // @index if -1 and file contains more than one material,      // will promt to select specific one -    static void uploadMaterialFromFile(const std::string& filename, S32 index); +    static void uploadMaterialFromModel(const std::string& filename, tinygltf::Model& model, S32 index);      static void loadMaterialFromFile(const std::string& filename, S32 index = -1);      void onSelectionChanged(); // live overrides selection changes @@ -237,7 +237,7 @@ private:      void setFromGLTFMaterial(LLGLTFMaterial* mat);      bool setFromSelection(); -    void loadMaterial(const tinygltf::Model &model, const std::string &filename_lc, S32 index, bool open_floater = true); +    void loadMaterial(const tinygltf::Model &model, const std::string & filename, S32 index, bool open_floater = true);      friend class LLMaterialFilePicker; diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index 56a48cb74d..7ae48eef8c 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -750,7 +750,9 @@ void LLModelPreview::loadModel(std::string filename, S32 lod, bool force_disable      // three possible file extensions, .dae .gltf .glb      // check for .dae and if not then assume one of the .gl?? -    if (std::string::npos != filename.rfind(".dae")) +    std::string filename_lc(filename); +    LLStringUtil::toLower(filename_lc); +    if (std::string::npos != filename_lc.rfind(".dae"))      {          mModelLoader = new LLDAELoader(              filename, diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 9962d0c10c..90c4436a04 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -814,8 +814,8 @@ void LLReflectionMapManager::updateUniforms()      F32 minimum_ambiance = psky->getTotalReflectionProbeAmbiance(cloud_shadow_scale);      F32 ambscale = gCubeSnapshot && !isRadiancePass() ? 0.f : 1.f; +    F32 radscale = gCubeSnapshot && !isRadiancePass() ? 0.5f : 1.f; -      for (auto* refmap : mReflectionMaps)      {          if (refmap == nullptr) @@ -852,7 +852,7 @@ void LLReflectionMapManager::updateUniforms()              rpd.refIndex[count][3] = -rpd.refIndex[count][3];          } -        rpd.refParams[count].set(llmax(minimum_ambiance, refmap->getAmbiance())*ambscale, 0.f, 0.f, 0.f); +        rpd.refParams[count].set(llmax(minimum_ambiance, refmap->getAmbiance())*ambscale, radscale, 0.f, 0.f);          S32 ni = nc; // neighbor ("index") - index into refNeighbor to write indices for current reflection probe's neighbors          { diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 55cf6795fe..22c1176b05 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -1847,21 +1847,11 @@ void LLSelectMgr::selectionSetImage(const LLUUID& imageid)  		    }  		    if (mItem)  			{ -				if (te == -1) // all faces -				{ -					LLToolDragAndDrop::dropTextureAllFaces(objectp, -														   mItem, -														   LLToolDragAndDrop::SOURCE_AGENT, -														   LLUUID::null); -				} -				else // one face -				{ -					LLToolDragAndDrop::dropTextureOneFace(objectp, -														  te, -														  mItem, -														  LLToolDragAndDrop::SOURCE_AGENT, -														  LLUUID::null); -				} +                LLToolDragAndDrop::dropTextureOneFace(objectp, +                                                      te, +                                                      mItem, +                                                      LLToolDragAndDrop::SOURCE_AGENT, +                                                      LLUUID::null);  			}  			else // not an inventory item  			{ @@ -1938,6 +1928,12 @@ void LLSelectMgr::selectionSetGLTFMaterial(const LLUUID& mat_id)              LLUUID asset_id = mMatId;              if (mItem)              { +                // If success, the material may be copied into the object's inventory +                BOOL success = LLToolDragAndDrop::handleDropMaterialProtections(objectp, mItem, LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null); +                if (!success) +                { +                    return false; +                }                  asset_id = mItem->getAssetUUID();              } diff --git a/indra/newview/llsettingsvo.cpp b/indra/newview/llsettingsvo.cpp index 1752b2494f..a609c98d61 100644 --- a/indra/newview/llsettingsvo.cpp +++ b/indra/newview/llsettingsvo.cpp @@ -675,7 +675,7 @@ void LLSettingsVOSky::applySpecial(void *ptarget, bool force)      LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;      LLVector3 light_direction = LLVector3(LLEnvironment::instance().getClampedLightNorm().mV); -    bool radiance_pass = gCubeSnapshot && !gPipeline.mReflectionMapManager.isRadiancePass(); +    bool irradiance_pass = gCubeSnapshot && !gPipeline.mReflectionMapManager.isRadiancePass();      LLShaderUniforms* shader = &((LLShaderUniforms*)ptarget)[LLGLSLShader::SG_DEFAULT];  	{         @@ -716,15 +716,15 @@ void LLSettingsVOSky::applySpecial(void *ptarget, bool force)      LLColor3 ambient(getTotalAmbient()); -    shader->uniform3fv(LLShaderMgr::AMBIENT, LLVector3(ambient.mV)); - -    if (radiance_pass) +    if (irradiance_pass)      { // during an irradiance map update, disable ambient lighting (direct lighting only) and desaturate sky color (avoid tinting the world blue)          shader->uniform3fv(LLShaderMgr::AMBIENT_LINEAR, LLVector3::zero.mV); +        shader->uniform3fv(LLShaderMgr::AMBIENT, LLVector3::zero.mV);      }      else      {          shader->uniform3fv(LLShaderMgr::AMBIENT_LINEAR, linearColor3v(getAmbientColor() / 3.f)); // note magic number 3.f comes from SLIDER_SCALE_SUN_AMBIENT +        shader->uniform3fv(LLShaderMgr::AMBIENT, LLVector3(ambient.mV));      }      shader->uniform3fv(LLShaderMgr::BLUE_HORIZON_LINEAR, linearColor3v(getBlueHorizon() / 2.f)); // note magic number of 2.f comes from SLIDER_SCALE_BLUE_HORIZON_DENSITY diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 35e11b8991..92fccfcfd6 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -3095,6 +3095,60 @@ void renderAgentTarget(LLVOAvatar* avatar)  	}  } +static void setTextureAreaDebugText(LLDrawable* drawablep) +{ +    LLVOVolume* vobjp = drawablep->getVOVolume(); + +    if (vobjp) +    { +        if (drawablep->mDistanceWRTCamera < 32.f) +        { +            std::ostringstream str; + +            //for (S32 i = 0; i < vobjp->getNumTEs(); ++i) +            S32 i = 0; +            { +                if (i < drawablep->getNumFaces()) +                { +                    LLFace* facep = drawablep->getFace(i); + +                    if (facep) +                    { +                        LLViewerTexture* imagep = facep->getTexture(); + +                        if (imagep) +                        { +                            str << llformat("D - %.2f", sqrtf(imagep->getMaxVirtualSize())); +                        } + +                        imagep = vobjp->getTENormalMap(i); + +                        if (imagep && imagep != LLViewerFetchedTexture::sDefaultImagep) +                        { +                            str << llformat("\nN - %.2f", sqrtf(imagep->getMaxVirtualSize())); +                        } + +                        imagep = vobjp->getTESpecularMap(i); + +                        if (imagep && imagep != LLViewerFetchedTexture::sDefaultImagep) +                        { +                            str << llformat("\nS - %.2f", sqrtf(imagep->getMaxVirtualSize())); +                        } + +                        str << "\n\n"; +                    } + +                    vobjp->setDebugText(str.str()); +                } +            } +        } +        else +        { +            vobjp->setDebugText("."); +        } +    } +} +  class LLOctreeRenderNonOccluded : public OctreeTraveler  {  public: @@ -3183,7 +3237,12 @@ public:  					size.mul(0.5f);  					drawBoxOutline(center, size);  				} -			}	 +			} + +            if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_AREA)) +            { +                setTextureAreaDebugText(drawable); +            }  			/*if (drawable->getVOVolume() && gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY))  			{ @@ -3514,6 +3573,7 @@ void LLSpatialPartition::renderDebug()  									  LLPipeline::RENDER_DEBUG_NORMALS |  									  LLPipeline::RENDER_DEBUG_POINTS |  									  //LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY | +                                      LLPipeline::RENDER_DEBUG_TEXTURE_AREA |  									  LLPipeline::RENDER_DEBUG_TEXTURE_ANIM |  									  LLPipeline::RENDER_DEBUG_RAYCAST |  									  LLPipeline::RENDER_DEBUG_AVATAR_VOLUME | diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index bc0eabfa0e..9b2cb0d44c 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -686,6 +686,7 @@ private:  	static LLFace** sNormFaces[2];  	static LLFace** sSpecFaces[2];  	static LLFace** sNormSpecFaces[2]; +	static LLFace** sPbrFaces[2];  	static LLFace** sAlphaFaces[2];  }; diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp index 1f4f086352..ca93eb648b 100644 --- a/indra/newview/lltextureview.cpp +++ b/indra/newview/lltextureview.cpp @@ -175,10 +175,6 @@ void LLTextureBar::draw()  	{  		color = LLColor4::green4;  	} -	else if (mImagep->getBoostLevel() > LLGLTexture::BOOST_ALM) -	{ -		color = LLColor4::magenta; // except none and alm -	}  	else if (mImagep->getMaxVirtualSize() <= 0.0f)  	{  		color = LLColor4::grey; color[VALPHA] = .7f; diff --git a/indra/newview/lltinygltfhelper.cpp b/indra/newview/lltinygltfhelper.cpp index 1a8e868d11..999be07dba 100644 --- a/indra/newview/lltinygltfhelper.cpp +++ b/indra/newview/lltinygltfhelper.cpp @@ -183,19 +183,16 @@ LLImageRaw * LLTinyGLTFHelper::getTexture(const std::string & folder, const tiny      return rawImage;  } -S32 LLTinyGLTFHelper::getMaterialCountFromFile(const std::string& filename) +bool LLTinyGLTFHelper::loadModel(const std::string& filename, tinygltf::Model& model_in)  {      std::string exten = gDirUtilp->getExtension(filename); -    S32 materials_in_file = 0; - +          if (exten == "gltf" || exten == "glb")      {          tinygltf::TinyGLTF loader;          std::string        error_msg;          std::string        warn_msg; -        tinygltf::Model model_in; -          std::string filename_lc = filename;          LLStringUtil::toLower(filename_lc); @@ -217,57 +214,33 @@ S32 LLTinyGLTFHelper::getMaterialCountFromFile(const std::string& filename)                  << ", warning:" << warn_msg                  << " file: " << filename                  << LL_ENDL; -            return 0; +            return false;          }          if (model_in.materials.empty())          {              // materials are missing              LL_WARNS("GLTF") << "Cannot load. File has no materials " << filename << LL_ENDL; -            return 0; +            return false;          } -        materials_in_file = model_in.materials.size(); +         +        return true;      } -    return materials_in_file; + + +    return false;  } -bool LLTinyGLTFHelper::getMaterialFromFile( +bool LLTinyGLTFHelper::getMaterialFromModel(      const std::string& filename, +    const tinygltf::Model& model_in,      S32 mat_index,      LLFetchedGLTFMaterial* material,      std::string& material_name)  {      llassert(material); -    tinygltf::TinyGLTF loader; -    std::string        error_msg; -    std::string        warn_msg; -    tinygltf::Model model_in; -    std::string filename_lc = filename; -    bool decode_successful = true; - -    LLStringUtil::toLower(filename_lc); - -    // Load a tinygltf model fom a file. Assumes that the input filename has already been -    // been sanitized to one of (.gltf , .glb) extensions, so does a simple find to distinguish. -    if (std::string::npos == filename_lc.rfind(".gltf")) -    {  // file is binary -        decode_successful = loader.LoadBinaryFromFile(&model_in, &error_msg, &warn_msg, filename_lc); -    } -    else -    {  // file is ascii -        decode_successful = loader.LoadASCIIFromFile(&model_in, &error_msg, &warn_msg, filename_lc); -    } - -    if (!decode_successful) -    { -        LL_WARNS("GLTF") << "Cannot load Material, error: " << error_msg -            << ", warning:" << warn_msg -            << " file: " << filename -            << LL_ENDL; -        return false; -    } -    else if (model_in.materials.size() <= mat_index) +    if (model_in.materials.size() <= mat_index)      {          // materials are missing          LL_WARNS("GLTF") << "Cannot load Material, Material " << mat_index << " is missing, " << filename << LL_ENDL; @@ -276,7 +249,7 @@ bool LLTinyGLTFHelper::getMaterialFromFile(      material->setFromModel(model_in, mat_index); -    std::string folder = gDirUtilp->getDirName(filename_lc); +    std::string folder = gDirUtilp->getDirName(filename);      tinygltf::Material material_in = model_in.materials[mat_index];      material_name = material_in.name; diff --git a/indra/newview/lltinygltfhelper.h b/indra/newview/lltinygltfhelper.h index 92c9876aff..256f6c854f 100644 --- a/indra/newview/lltinygltfhelper.h +++ b/indra/newview/lltinygltfhelper.h @@ -43,10 +43,11 @@ namespace LLTinyGLTFHelper      LLImageRaw* getTexture(const std::string& folder, const tinygltf::Model& model, S32 texture_index); -    S32 getMaterialCountFromFile(const std::string& filename); +    bool loadModel(const std::string& filename, tinygltf::Model& model_out); -    bool getMaterialFromFile( +    bool getMaterialFromModel(          const std::string& filename, +        const tinygltf::Model& model,          S32 mat_index,          LLFetchedGLTFMaterial* material,          std::string& material_name); diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index 9743f00ab8..fb5c548b2a 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -488,14 +488,18 @@ void do_bulk_upload(std::vector<std::string> filenames, const LLSD& notification          // gltf does not use normal upload procedure          if (ext == "gltf" || ext == "glb")          { -            S32 materials_in_file = LLTinyGLTFHelper::getMaterialCountFromFile(filename); - -            for (S32 i = 0; i < materials_in_file; i++) +            tinygltf::Model model; +            if (LLTinyGLTFHelper::loadModel(filename, model))              { -                // Todo: -                // 1. Decouple bulk upload from material editor -                // 2. Take into account possiblity of identical textures -                LLMaterialEditor::uploadMaterialFromFile(filename, i); +                S32 materials_in_file = model.materials.size(); + +                for (S32 i = 0; i < materials_in_file; i++) +                { +                    // Todo: +                    // 1. Decouple bulk upload from material editor +                    // 2. Take into account possiblity of identical textures +                    LLMaterialEditor::uploadMaterialFromModel(filename, model, i); +                }              }          }      } @@ -530,37 +534,43 @@ bool get_bulk_upload_expected_cost(const std::vector<std::string>& filenames, S3          if (ext == "gltf" || ext == "glb")          {              S32 texture_upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost(); -            S32 materials_in_file = LLTinyGLTFHelper::getMaterialCountFromFile(filename); +             +            tinygltf::Model model; -            for (S32 i = 0; i < materials_in_file; i++) +            if (LLTinyGLTFHelper::loadModel(filename, model))              { -                LLPointer<LLFetchedGLTFMaterial> material = new LLFetchedGLTFMaterial(); -                std::string material_name; -                bool decode_successful = LLTinyGLTFHelper::getMaterialFromFile(filename, i, material.get(), material_name); +                S32 materials_in_file = model.materials.size(); -                if (decode_successful) +                for (S32 i = 0; i < materials_in_file; i++)                  { -                    // Todo: make it account for possibility of same texture in different -                    // materials and even in scope of same material -                    S32 texture_count = 0; -                    if (material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR].notNull()) -                    { -                        texture_count++; -                    } -                    if (material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS].notNull()) -                    { -                        texture_count++; -                    } -                    if (material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL].notNull()) -                    { -                        texture_count++; -                    } -                    if (material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE].notNull()) +                    LLPointer<LLFetchedGLTFMaterial> material = new LLFetchedGLTFMaterial(); +                    std::string material_name; +                    bool decode_successful = LLTinyGLTFHelper::getMaterialFromModel(filename, model, i, material.get(), material_name); + +                    if (decode_successful)                      { -                        texture_count++; +                        // Todo: make it account for possibility of same texture in different +                        // materials and even in scope of same material +                        S32 texture_count = 0; +                        if (material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR].notNull()) +                        { +                            texture_count++; +                        } +                        if (material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS].notNull()) +                        { +                            texture_count++; +                        } +                        if (material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL].notNull()) +                        { +                            texture_count++; +                        } +                        if (material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE].notNull()) +                        { +                            texture_count++; +                        } +                        total_cost += texture_count * texture_upload_cost; +                        file_count++;                      } -                    total_cost += texture_count * texture_upload_cost; -                    file_count++;                  }              }          } diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index e217ede067..fd3c8de3e9 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -4950,10 +4950,10 @@ void LLViewerObject::updateTEMaterialTextures(U8 te)  	if (getTE(te)->getMaterialParams().notNull())  	{  		const LLUUID& norm_id = getTE(te)->getMaterialParams()->getNormalID(); -		mTENormalMaps[te] = LLViewerTextureManager::getFetchedTexture(norm_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_ALM, LLViewerTexture::LOD_TEXTURE); +		mTENormalMaps[te] = LLViewerTextureManager::getFetchedTexture(norm_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);  		const LLUUID& spec_id = getTE(te)->getMaterialParams()->getSpecularID(); -		mTESpecularMaps[te] = LLViewerTextureManager::getFetchedTexture(spec_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_ALM, LLViewerTexture::LOD_TEXTURE); +		mTESpecularMaps[te] = LLViewerTextureManager::getFetchedTexture(spec_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);  	}      LLFetchedGLTFMaterial* mat = (LLFetchedGLTFMaterial*) getTE(te)->getGLTFRenderMaterial(); @@ -4982,7 +4982,7 @@ void LLViewerObject::updateTEMaterialTextures(U8 te)              }              else              { -                img = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_ALM, LLViewerTexture::LOD_TEXTURE); +                img = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);                  img->addTextureStats(64.f * 64.f, TRUE);              }          } @@ -5140,14 +5140,14 @@ S32 LLViewerObject::setTETexture(const U8 te, const LLUUID& uuid)  S32 LLViewerObject::setTENormalMap(const U8 te, const LLUUID& uuid)  {  	LLViewerFetchedTexture *image = (uuid == LLUUID::null) ? NULL : LLViewerTextureManager::getFetchedTexture( -		uuid, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_ALM, LLViewerTexture::LOD_TEXTURE, 0, 0, LLHost()); +		uuid, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, LLHost());  	return setTENormalMapCore(te, image);  }  S32 LLViewerObject::setTESpecularMap(const U8 te, const LLUUID& uuid)  {  	LLViewerFetchedTexture *image = (uuid == LLUUID::null) ? NULL : LLViewerTextureManager::getFetchedTexture( -		uuid, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_ALM, LLViewerTexture::LOD_TEXTURE, 0, 0, LLHost()); +		uuid, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, LLHost());  	return setTESpecularMapCore(te, image);  } diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 816fa6607e..bb22d90cd9 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -815,19 +815,19 @@ void LLViewerObjectList::updateApparentAngles(LLAgent &agent)  		mCurBin = (mCurBin + 1) % NUM_BINS;  	} -#if 1 +#if 0  	// Slam priorities for textures that we care about (hovered, selected, and focused)  	// Hovered  	// Assumes only one level deep of parenting  	LLSelectNode* nodep = LLSelectMgr::instance().getHoverNode(); -	if (nodep) -	{ -		objectp = nodep->getObject(); -		if (objectp) -		{ -			objectp->boostTexturePriority(); -		} -	} +    if (nodep) +    { +        objectp = nodep->getObject(); +        if (objectp) +        { +            objectp->boostTexturePriority(); +        } +    }  	// Focused  	objectp = gAgentCamera.getFocusObject(); @@ -835,6 +835,7 @@ void LLViewerObjectList::updateApparentAngles(LLAgent &agent)  	{  		objectp->boostTexturePriority();  	} +#endif  	// Selected  	struct f : public LLSelectedObjectFunctor @@ -846,7 +847,6 @@ void LLViewerObjectList::updateApparentAngles(LLAgent &agent)  		}  	} func;  	LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func); -#endif  	LLVOAvatar::cullAvatarsByPixelArea();  } diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index f4f20ee7a6..31c71aac2a 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -235,7 +235,6 @@ LLViewerShaderMgr::LLViewerShaderMgr() :  	mShaderLevel(SHADER_COUNT, 0),  	mMaxAvatarShaderLevel(0)  {    -    /// Make sure WL Sky is the first program      //ONLY shaders that need WL Param management should be added here  	mShaderList.push_back(&gAvatarProgram);  	mShaderList.push_back(&gWaterProgram); @@ -291,6 +290,7 @@ LLViewerShaderMgr::LLViewerShaderMgr() :      mShaderList.push_back(&gDeferredPBRAlphaProgram);      mShaderList.push_back(&gHUDPBRAlphaProgram);      mShaderList.push_back(&gDeferredSkinnedPBRAlphaProgram); +    mShaderList.push_back(&gDeferredPostGammaCorrectProgram); // for gamma  } @@ -2525,6 +2525,10 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()          {              gDeferredPostGammaCorrectProgram.addPermutation("TONEMAP_ACES_HILL_EXPOSURE_BOOST", "1");          } +        else +        { +            gDeferredPostGammaCorrectProgram.addPermutation("TONEMAP_LINEAR", "1"); +        }  		gDeferredPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));  		gDeferredPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredGammaCorrect.glsl", GL_FRAGMENT_SHADER));          gDeferredPostGammaCorrectProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index ee39b7d02f..b1abd0a656 100644 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -570,14 +570,11 @@ void send_viewer_stats(bool include_preferences)  			shader_level = 3;  		}  	} -	else if (gPipeline.canUseWindLightShadersOnObjects()) +	else  	{  		shader_level = 2;  	} -	else if (gPipeline.shadersLoaded()) -	{ -		shader_level = 1; -	} +	  	system["shader_level"] = shader_level; diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 578deb8b3f..ec03556ff4 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -89,8 +89,6 @@ S32 LLViewerTexture::sAuxCount = 0;  LLFrameTimer LLViewerTexture::sEvaluationTimer;  F32 LLViewerTexture::sDesiredDiscardBias = 0.f;  F32 LLViewerTexture::sDesiredDiscardScale = 1.1f; -S8  LLViewerTexture::sCameraMovingDiscardBias = 0; -F32 LLViewerTexture::sCameraMovingBias = 0.0f;  S32 LLViewerTexture::sMaxSculptRez = 128; //max sculpt image size  const S32 MAX_CACHED_RAW_IMAGE_AREA = 64 * 64;  const S32 MAX_CACHED_RAW_SCULPT_IMAGE_AREA = LLViewerTexture::sMaxSculptRez * LLViewerTexture::sMaxSculptRez; @@ -103,8 +101,6 @@ F32 LLViewerTexture::sCurrentTime = 0.0f;  LLViewerTexture::EDebugTexels LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_OFF; -const F32 desired_discard_bias_min = -2.0f; // -max number of levels to improve image quality by -const F32 desired_discard_bias_max = (F32)MAX_DISCARD_LEVEL; // max number of levels to reduce image quality by  const F64 log_2 = log(2.0);  #if ADDRESS_SIZE == 32 @@ -471,8 +467,6 @@ void LLViewerTexture::initClass()  }  // tuning params -const F32 discard_bias_delta = .25f; -const F32 discard_delta_time = 0.5f;  const F32 GPU_MEMORY_CHECK_WAIT_TIME = 1.0f;  // non-const (used externally  F32 texmem_lower_bound_scale = 0.85f; @@ -552,29 +546,26 @@ void LLViewerTexture::updateClass()  	LLViewerMediaTexture::updateClass(); -	if(isMemoryForTextureLow()) -	{ -		// Note: isMemoryForTextureLow() uses 1s delay, make sure we waited enough for it to recheck -		if (sEvaluationTimer.getElapsedTimeF32() > GPU_MEMORY_CHECK_WAIT_TIME) -		{ -			sDesiredDiscardBias += discard_bias_delta; -			sEvaluationTimer.reset(); -		} -	} -	else if (sDesiredDiscardBias > 0.0f -			 && isMemoryForTextureSuficientlyFree()) -	{ -		// If we are using less texture memory than we should, -		// scale down the desired discard level -		if (sEvaluationTimer.getElapsedTimeF32() > discard_delta_time) -		{ -			sDesiredDiscardBias -= discard_bias_delta; -			sEvaluationTimer.reset(); -		} -	} -	sDesiredDiscardBias = llclamp(sDesiredDiscardBias, desired_discard_bias_min, desired_discard_bias_max); +    static LLCachedControl<U32> max_vram_budget(gSavedSettings, "RenderMaxVRAMBudget", 0); + +    // get an estimate of how much video memory we're using  +    // NOTE: our metrics miss about half the vram we use, so this biases high but turns out to typically be within 5% of the real number +    F32 used = (LLImageGL::getTextureBytesAllocated() + LLVertexBuffer::getBytesAllocated()) / 1024 / 512; +     +    F32 budget = max_vram_budget == 0 ? gGLManager.mVRAM : max_vram_budget; + +    // try to leave half a GB for everyone else, but keep at least 768MB for ourselves +    F32 target = llmax(budget - 512.f, 768.f); + +    F32 over_pct = llmax((used-target) / target, 0.f); +    sDesiredDiscardBias = llmax(sDesiredDiscardBias, 1.f + over_pct); -	LLViewerTexture::sFreezeImageUpdates = sDesiredDiscardBias > (desired_discard_bias_max - 1.0f); +    if (sDesiredDiscardBias > 1.f) +    { +        sDesiredDiscardBias -= gFrameIntervalSeconds * 0.01; +    } + +    LLViewerTexture::sFreezeImageUpdates = false; // sDesiredDiscardBias > (desired_discard_bias_max - 1.0f);  }  //end of static functions @@ -627,7 +618,6 @@ LLViewerTexture::~LLViewerTexture()  // virtual  void LLViewerTexture::init(bool firstinit)  { -	mSelectedTime = 0.f;  	mMaxVirtualSize = 0.f;  	mMaxVirtualSizeResetInterval = 1;  	mMaxVirtualSizeResetCounter = mMaxVirtualSizeResetInterval; @@ -685,7 +675,6 @@ void LLViewerTexture::setBoostLevel(S32 level)  	{  		mBoostLevel = level;  		if(mBoostLevel != LLViewerTexture::BOOST_NONE &&  -			mBoostLevel != LLViewerTexture::BOOST_ALM &&   			mBoostLevel != LLViewerTexture::BOOST_SELECTED &&   			mBoostLevel != LLViewerTexture::BOOST_ICON)  		{ @@ -698,12 +687,6 @@ void LLViewerTexture::setBoostLevel(S32 level)      {          mMaxVirtualSize = 2048.f * 2048.f;      } - -	if (mBoostLevel == LLViewerTexture::BOOST_SELECTED) -	{ -		mSelectedTime = gFrameTimeSeconds; -	} -  }  bool LLViewerTexture::isActiveFetching() @@ -1710,10 +1693,6 @@ void LLViewerFetchedTexture::processTextureStats()  		{  			mDesiredDiscardLevel = 0;  		} -		else if (!LLPipeline::sRenderDeferred && mBoostLevel == LLGLTexture::BOOST_ALM) -		{ // ??? don't load spec and normal maps when alm is disabled ??? -			mDesiredDiscardLevel = MAX_DISCARD_LEVEL + 1; -		}          else if (mDontDiscard && mBoostLevel == LLGLTexture::BOOST_ICON)          {              if (mFullWidth > MAX_IMAGE_SIZE_DEFAULT || mFullHeight > MAX_IMAGE_SIZE_DEFAULT) @@ -1831,8 +1810,7 @@ bool LLViewerFetchedTexture::updateFetch()  {      LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;  	static LLCachedControl<bool> textures_decode_disabled(gSavedSettings,"TextureDecodeDisabled", false); -	static LLCachedControl<F32>  sCameraMotionThreshold(gSavedSettings,"TextureCameraMotionThreshold", 0.2); -	static LLCachedControl<S32>  sCameraMotionBoost(gSavedSettings,"TextureCameraMotionBoost", 3); +	  	if(textures_decode_disabled) // don't fetch the surface textures in wireframe mode  	{  		return false; @@ -2055,32 +2033,9 @@ bool LLViewerFetchedTexture::updateFetch()  		make_request = false;  		switchToCachedImage(); //use the cached raw data first  	} -	//else if (!isJustBound() && mCachedRawImageReady) -	//{ -	//	make_request = false; -	//}  	if (make_request)  	{ -#if 0 -		// Load the texture progressively: we try not to rush to the desired discard too fast. -		// If the camera is not moving, we do not tweak the discard level notch by notch but go to the desired discard with larger boosted steps -		// This mitigates the "textures stay blurry" problem when loading while not killing the texture memory while moving around -		S32 delta_level = (mBoostLevel > LLGLTexture::BOOST_ALM) ? 2 : 1;  -		if (current_discard < 0) -		{ -			desired_discard = llmax(desired_discard, getMaxDiscardLevel() - delta_level); -		} -		else if (LLViewerTexture::sCameraMovingBias < sCameraMotionThreshold) -		{ -			desired_discard = llmax(desired_discard, current_discard - sCameraMotionBoost); -		} -        else -        { -			desired_discard = llmax(desired_discard, current_discard - delta_level); -        } -#endif -  		if (mIsFetching)  		{              // already requested a higher resolution mip @@ -3095,10 +3050,6 @@ void LLViewerLODTexture::processTextureStats()  		if (mFullWidth > MAX_IMAGE_SIZE_DEFAULT || mFullHeight > MAX_IMAGE_SIZE_DEFAULT)  			mDesiredDiscardLevel = 1; // MAX_IMAGE_SIZE_DEFAULT = 1024 and max size ever is 2048  	} -	else if (!LLPipeline::sRenderDeferred && mBoostLevel == LLGLTexture::BOOST_ALM) -	{ -		mDesiredDiscardLevel = MAX_DISCARD_LEVEL + 1; -	}  	else if (mBoostLevel < LLGLTexture::BOOST_HIGH && mMaxVirtualSize <= 10.f)  	{  		// If the image has not been significantly visible in a while, we don't want it @@ -3108,72 +3059,69 @@ void LLViewerLODTexture::processTextureStats()  	{  		mDesiredDiscardLevel = 	getMaxDiscardLevel();  	} -	else -	{ -		//static const F64 log_2 = log(2.0); -		static const F64 log_4 = log(4.0); +    else +    { +        //static const F64 log_2 = log(2.0); +        static const F64 log_4 = log(4.0); -		F32 discard_level = 0.f; +        F32 discard_level = 0.f; -		// If we know the output width and height, we can force the discard -		// level to the correct value, and thus not decode more texture -		// data than we need to. -		if (mKnownDrawWidth && mKnownDrawHeight) -		{ -			S32 draw_texels = mKnownDrawWidth * mKnownDrawHeight; -			draw_texels = llclamp(draw_texels, MIN_IMAGE_AREA, MAX_IMAGE_AREA); +        // If we know the output width and height, we can force the discard +        // level to the correct value, and thus not decode more texture +        // data than we need to. +        if (mKnownDrawWidth && mKnownDrawHeight) +        { +            S32 draw_texels = mKnownDrawWidth * mKnownDrawHeight; +            draw_texels = llclamp(draw_texels, MIN_IMAGE_AREA, MAX_IMAGE_AREA); -			// Use log_4 because we're in square-pixel space, so an image -			// with twice the width and twice the height will have mTexelsPerImage -			// 4 * draw_size -			discard_level = (F32)(log(mTexelsPerImage/draw_texels) / log_4); -		} -		else -		{ -			// Calculate the required scale factor of the image using pixels per texel -			discard_level = (F32)(log(mTexelsPerImage/mMaxVirtualSize) / log_4); -			mDiscardVirtualSize = mMaxVirtualSize; -			mCalculatedDiscardLevel = discard_level; -		} -		if (mBoostLevel < LLGLTexture::BOOST_SCULPTED) -		{ -			discard_level += sDesiredDiscardBias; -			discard_level *= sDesiredDiscardScale; // scale -			discard_level += sCameraMovingDiscardBias; -		} -		discard_level = floorf(discard_level); +            // Use log_4 because we're in square-pixel space, so an image +            // with twice the width and twice the height will have mTexelsPerImage +            // 4 * draw_size +            discard_level = (F32)(log(mTexelsPerImage / draw_texels) / log_4); +        } +        else +        { +            // Calculate the required scale factor of the image using pixels per texel +            discard_level = (F32)(log(mTexelsPerImage / mMaxVirtualSize) / log_4); +            mDiscardVirtualSize = mMaxVirtualSize; +            mCalculatedDiscardLevel = discard_level; +        } +        if (mBoostLevel < LLGLTexture::BOOST_SCULPTED) +        { +            discard_level *= sDesiredDiscardScale; // scale (default 1.1f) +        } +        discard_level = floorf(discard_level); -		F32 min_discard = 0.f; -		U32 desired_size = MAX_IMAGE_SIZE_DEFAULT; // MAX_IMAGE_SIZE_DEFAULT = 1024 and max size ever is 2048 -		if (mBoostLevel <= LLGLTexture::BOOST_SCULPTED) -		{ -			desired_size = DESIRED_NORMAL_TEXTURE_SIZE; -		} -		if (mFullWidth > desired_size || mFullHeight > desired_size) -			min_discard = 1.f; +        F32 min_discard = 0.f; +        U32 desired_size = MAX_IMAGE_SIZE_DEFAULT; // MAX_IMAGE_SIZE_DEFAULT = 1024 and max size ever is 2048 +        if (mBoostLevel <= LLGLTexture::BOOST_SCULPTED) +        { +            desired_size = DESIRED_NORMAL_TEXTURE_SIZE; +        } +        if (mFullWidth > desired_size || mFullHeight > desired_size) +            min_discard = 1.f; -		discard_level = llclamp(discard_level, min_discard, (F32)MAX_DISCARD_LEVEL); -		 -		// Can't go higher than the max discard level -		mDesiredDiscardLevel = llmin(getMaxDiscardLevel() + 1, (S32)discard_level); -		// Clamp to min desired discard -		mDesiredDiscardLevel = llmin(mMinDesiredDiscardLevel, mDesiredDiscardLevel); +        discard_level = llclamp(discard_level, min_discard, (F32)MAX_DISCARD_LEVEL); -		// -		// At this point we've calculated the quality level that we want, -		// if possible.  Now we check to see if we have it, and take the -		// proper action if we don't. -		// +        // Can't go higher than the max discard level +        mDesiredDiscardLevel = llmin(getMaxDiscardLevel() + 1, (S32)discard_level); +        // Clamp to min desired discard +        mDesiredDiscardLevel = llmin(mMinDesiredDiscardLevel, mDesiredDiscardLevel); -		S32 current_discard = getDiscardLevel(); -		if (sDesiredDiscardBias > 0.0f && mBoostLevel < LLGLTexture::BOOST_SCULPTED && current_discard >= 0) -		{ -			if(desired_discard_bias_max <= sDesiredDiscardBias && !mForceToSaveRawImage) -			{ -				//needs to release texture memory urgently -				scaleDown(); -			} -		} +        // +        // At this point we've calculated the quality level that we want, +        // if possible.  Now we check to see if we have it, and take the +        // proper action if we don't. +        // + +        S32 current_discard = getDiscardLevel(); +        if (mBoostLevel < LLGLTexture::BOOST_SCULPTED && current_discard >= 0) +        { +            if (current_discard < (mDesiredDiscardLevel-1) && !mForceToSaveRawImage) +            { // should scale down +                scaleDown(); +            } +        }  		if (isUpdateFrozen() // we are out of memory and nearing max allowed bias  			&& mBoostLevel < LLGLTexture::BOOST_SCULPTED @@ -3188,6 +3136,16 @@ void LLViewerLODTexture::processTextureStats()  	{  		mDesiredDiscardLevel = llmin(mDesiredDiscardLevel, (S8)mDesiredSavedRawDiscardLevel);  	} + +    // decay max virtual size over time +    mMaxVirtualSize *= 0.8f; + +    // selection manager will immediately reset BOOST_SELECTED but never unsets it +    // unset it immediately after we consume it +    if (getBoostLevel() == BOOST_SELECTED) +    { +        setBoostLevel(BOOST_NONE); +    }  }  bool LLViewerLODTexture::scaleDown() diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index facf05e52f..1370f4debe 100644 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -195,7 +195,6 @@ protected:  	LLUUID mID;  	S32 mTextureListType; // along with mID identifies where to search for this texture in TextureList -	F32 mSelectedTime;				// time texture was last selected  	mutable F32 mMaxVirtualSize = 0.f;	// The largest virtual size of the image, in pixels - how much data to we need?	  	mutable S32  mMaxVirtualSizeResetCounter;  	mutable S32  mMaxVirtualSizeResetInterval; @@ -223,8 +222,6 @@ public:  	static LLFrameTimer sEvaluationTimer;  	static F32 sDesiredDiscardBias;  	static F32 sDesiredDiscardScale; -	static S8  sCameraMovingDiscardBias; -	static F32 sCameraMovingBias;  	static S32 sMaxSculptRez ;  	static U32 sMinLargeImageSize ;  	static U32 sMaxSmallImageSize ; diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 611aace4b4..0f89401bf1 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -61,6 +61,7 @@  #include "llviewerdisplay.h"  #include "llviewerwindow.h"  #include "llprogressview.h" +  ////////////////////////////////////////////////////////////////////////////  void (*LLViewerTextureList::sUUIDCallback)(void **, const LLUUID&) = NULL; @@ -533,12 +534,6 @@ LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id,  	LLPointer<LLViewerFetchedTexture> imagep = findImage(image_id, get_element_type(boost_priority));  	if (!imagep.isNull())  	{ -		if (boost_priority != LLViewerTexture::BOOST_ALM && imagep->getBoostLevel() == LLViewerTexture::BOOST_ALM) -		{ -			// Workaround: we need BOOST_ALM texture for something, 'rise' to NONE -			imagep->setBoostLevel(LLViewerTexture::BOOST_NONE); -		} -  		LLViewerFetchedTexture *texture = imagep.get();  		if (request_from_host.isOk() &&  			!texture->getTargetHost().isOk()) @@ -874,6 +869,8 @@ static void touch_texture(LLViewerFetchedTexture* tex, F32 vsize)      }  } +extern BOOL gCubeSnapshot; +  void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imagep)  {      if (imagep->isInDebug() || imagep->isUnremovable()) @@ -882,18 +879,36 @@ void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imag          return; //is in debug, ignore.      } +    llassert(!gCubeSnapshot); + +    static LLCachedControl<F32> bias_distance_scale(gSavedSettings, "TextureBiasDistanceScale", 1.f); +      LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE      {          for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i)          {              for (U32 fi = 0; fi < imagep->getNumFaces(i); ++fi)              { -                const LLFace* face = (*(imagep->getFaceList(i)))[fi]; +                LLFace* face = (*(imagep->getFaceList(i)))[fi];                  if (face && face->getViewerObject() && face->getTextureEntry())                  { -                    F32 vsize = face->getVirtualSize(); - +                    F32 vsize = face->getPixelArea(); + +#if LL_DARWIN +                    vsize /= 1.f + LLViewerTexture::sDesiredDiscardBias*(1.f+face->getDrawable()->mDistanceWRTCamera*bias_distance_scale); +#else +                    vsize /= LLViewerTexture::sDesiredDiscardBias; +                    vsize /= llmax(1.f, (LLViewerTexture::sDesiredDiscardBias-1.f) * (1.f + face->getDrawable()->mDistanceWRTCamera * bias_distance_scale)); + +                    F32 radius; +                    F32 cos_angle_to_view_dir; +                    BOOL in_frustum = face->calcPixelArea(cos_angle_to_view_dir, radius); +                    if (!in_frustum || !face->getDrawable()->isVisible()) +                    { // further reduce by discard bias when off screen or occluded +                        vsize /= LLViewerTexture::sDesiredDiscardBias; +                    } +#endif                      // if a GLTF material is present, ignore that face                      // as far as this texture stats go, but update the GLTF material                       // stats @@ -914,7 +929,9 @@ void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imag              }          }      } -     + +    //imagep->setDebugText(llformat("%.3f - %d", sqrtf(imagep->getMaxVirtualSize()), imagep->getBoostLevel())); +      F32 lazy_flush_timeout = 30.f; // stop decoding      F32 max_inactive_time = 20.f; // actually delete      S32 min_refs = 3; // 1 for mImageList, 1 for mUUIDMap, 1 for local reference diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 5c1467f28f..ad9e3da379 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -5206,7 +5206,12 @@ BOOL LLViewerWindow::simpleSnapshot(LLImageRaw* raw, S32 image_width, S32 image_          LLPipeline::toggleRenderDebugFeature(LLPipeline::RENDER_DEBUG_FEATURE_UI);      } -    LLPipeline::sShowHUDAttachments = FALSE; +    BOOL hide_hud = LLPipeline::sShowHUDAttachments; +	if (hide_hud) +	{ +		LLPipeline::sShowHUDAttachments = FALSE; +	} +      LLRect window_rect = getWorldViewRectRaw();      S32 original_width = LLPipeline::sRenderDeferred ? gPipeline.mRT->deferredScreen.getWidth() : gViewerWindow->getWorldViewWidthRaw(); @@ -5276,7 +5281,10 @@ BOOL LLViewerWindow::simpleSnapshot(LLImageRaw* raw, S32 image_width, S32 image_          }      } -    LLPipeline::sShowHUDAttachments = TRUE; +	if (hide_hud) +	{ +		LLPipeline::sShowHUDAttachments = TRUE; +	}      setCursor(UI_CURSOR_ARROW); @@ -5351,7 +5359,11 @@ BOOL LLViewerWindow::cubeSnapshot(const LLVector3& origin, LLCubeMapArray* cubea          LLPipeline::toggleRenderDebugFeature(LLPipeline::RENDER_DEBUG_FEATURE_UI);      } -    LLPipeline::sShowHUDAttachments = FALSE; +    BOOL hide_hud = LLPipeline::sShowHUDAttachments; +	if (hide_hud) +	{ +		LLPipeline::sShowHUDAttachments = FALSE; +	}      LLRect window_rect = getWorldViewRectRaw();      mWorldViewRectRaw.set(0, res, res, 0); @@ -5417,7 +5429,10 @@ BOOL LLViewerWindow::cubeSnapshot(const LLVector3& origin, LLCubeMapArray* cubea          }      } -    LLPipeline::sShowHUDAttachments = TRUE; +	if (hide_hud) +	{ +		LLPipeline::sShowHUDAttachments = TRUE; +	}      gPipeline.resetDrawOrders();      mWorldViewRectRaw = window_rect; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 42e764b492..d1f4fa1c7a 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -628,6 +628,14 @@ void LLVOVolume::animateTextures()                  LLGLTFMaterial *gltf_mat = te->getGLTFRenderMaterial();                  const bool is_pbr = gltf_mat != nullptr; +				if (!facep->mTextureMatrix) +				{ +					facep->mTextureMatrix = new LLMatrix4(); +				} + +				LLMatrix4& tex_mat = *facep->mTextureMatrix; +				tex_mat.setIdentity(); +                  if (!is_pbr)                  {                      if (!(result & LLViewerTextureAnim::ROTATE)) @@ -642,32 +650,65 @@ void LLVOVolume::animateTextures()                      {                          te->getScale(&scale_s, &scale_t);                      } -                } -				if (!facep->mTextureMatrix) -				{ -					facep->mTextureMatrix = new LLMatrix4(); -				} +                    LLVector3 trans ; -				LLMatrix4& tex_mat = *facep->mTextureMatrix; -				tex_mat.setIdentity(); +                        trans.set(LLVector3(off_s+0.5f, off_t+0.5f, 0.f));			 +                        tex_mat.translate(LLVector3(-0.5f, -0.5f, 0.f)); -				LLVector3 trans ; +                    LLVector3 scale(scale_s, scale_t, 1.f);			 +                    LLQuaternion quat; +                    quat.setQuat(rot, 0, 0, -1.f); +             +                    tex_mat.rotate(quat);				 -					trans.set(LLVector3(off_s+0.5f, off_t+0.5f, 0.f));			 -					tex_mat.translate(LLVector3(-0.5f, -0.5f, 0.f)); +                    LLMatrix4 mat; +                    mat.initAll(scale, LLQuaternion(), LLVector3()); +                    tex_mat *= mat; +             +                    tex_mat.translate(trans); +                } +                else +                { +                    if (!(result & LLViewerTextureAnim::ROTATE)) +                    { +                        rot = 0.0f; +                    } +                    if (!(result & LLViewerTextureAnim::TRANSLATE)) +                    { +                        off_s = 0.0f; +                        off_t = 0.0f; +                    } +                    if (!(result & LLViewerTextureAnim::SCALE)) +                    { +                        scale_s = 1.0f; +                        scale_t = 1.0f; +                    } -				LLVector3 scale(scale_s, scale_t, 1.f);			 -				LLQuaternion quat; -				quat.setQuat(rot, 0, 0, -1.f); -		 -				tex_mat.rotate(quat);				 +                    // For PBR materials, use Blinn-Phong rotation as hint for +                    // translation direction. In a Blinn-Phong material, the +                    // translation direction would be a byproduct the texture +                    // transform. +                    F32 rot_frame; +                    te->getRotation(&rot_frame); -				LLMatrix4 mat; -				mat.initAll(scale, LLQuaternion(), LLVector3()); -				tex_mat *= mat; -		 -				tex_mat.translate(trans); +                    tex_mat.translate(LLVector3(-0.5f, -0.5f, 0.f)); + +                    LLQuaternion quat; +                    quat.setQuat(rot, 0, 0, -1.f); +                    tex_mat.rotate(quat);				 + +                    LLMatrix4 mat; +                    LLVector3 scale(scale_s, scale_t, 1.f);			 +                    mat.initAll(scale, LLQuaternion(), LLVector3()); +                    tex_mat *= mat; +             +                    LLVector3 off(off_s, off_t, 0.f); +                    off.rotVec(rot_frame, 0, 0, 1.f); +                    tex_mat.translate(off); + +                    tex_mat.translate(LLVector3(0.5f, 0.5f, 0.f)); +                }  			}  		}  		else @@ -817,12 +858,6 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)  			continue;  		} -        // clear out boost selected periodically -        if (imagep->getBoostLevel() == LLGLTexture::BOOST_SELECTED) -        { -            imagep->setBoostLevel(LLGLTexture::BOOST_NONE); -        } -  		F32 vsize;  		F32 old_size = face->getVirtualSize(); @@ -837,7 +872,6 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)  		else  		{  			vsize = face->getTextureVirtualSize(); -            imagep->addTextureStats(vsize);  		}  		mPixelArea = llmax(mPixelArea, face->getPixelArea()); @@ -854,12 +888,7 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)  			}  		} -		if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_AREA)) -		{ -			if (vsize < min_vsize) min_vsize = vsize; -			if (vsize > max_vsize) max_vsize = vsize; -		} -		else if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY)) +		if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY))  		{  			LLViewerFetchedTexture* img = LLViewerTextureManager::staticCastToFetchedTexture(imagep) ;  			if(img) @@ -924,7 +953,7 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)  	{  		LLLightImageParams* params = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE);  		LLUUID id = params->getLightTexture(); -		mLightTexture = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_ALM); +		mLightTexture = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE);  		if (mLightTexture.notNull())  		{  			F32 rad = getLightRadius(); @@ -3266,7 +3295,6 @@ void LLVOVolume::updateSpotLightPriority()  	if (mLightTexture.notNull())  	{  		mLightTexture->addTextureStats(mSpotLightPriority); -		mLightTexture->setBoostLevel(LLGLTexture::BOOST_CLOUDS);  	}  } @@ -3290,7 +3318,7 @@ LLViewerTexture* LLVOVolume::getLightTexture()  	{  		if (mLightTexture.isNull() || id != mLightTexture->getID())  		{ -			mLightTexture = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_ALM); +			mLightTexture = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE);  		}  	}  	else @@ -5105,6 +5133,7 @@ LLFace** LLVolumeGeometryManager::sSimpleFaces[2] = { NULL };  LLFace** LLVolumeGeometryManager::sNormFaces[2] = { NULL };  LLFace** LLVolumeGeometryManager::sSpecFaces[2] = { NULL };  LLFace** LLVolumeGeometryManager::sNormSpecFaces[2] = { NULL }; +LLFace** LLVolumeGeometryManager::sPbrFaces[2] = { NULL };  LLFace** LLVolumeGeometryManager::sAlphaFaces[2] = { NULL };  LLVolumeGeometryManager::LLVolumeGeometryManager() @@ -5141,6 +5170,7 @@ void LLVolumeGeometryManager::allocateFaces(U32 pMaxFaceCount)          sNormFaces[i] = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount * sizeof(LLFace*)));          sSpecFaces[i] = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount * sizeof(LLFace*)));          sNormSpecFaces[i] = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount * sizeof(LLFace*))); +        sPbrFaces[i] = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount * sizeof(LLFace*)));          sAlphaFaces[i] = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount * sizeof(LLFace*)));      }  } @@ -5155,6 +5185,7 @@ void LLVolumeGeometryManager::freeFaces()          ll_aligned_free<64>(sNormFaces[i]);          ll_aligned_free<64>(sSpecFaces[i]);          ll_aligned_free<64>(sNormSpecFaces[i]); +        ll_aligned_free<64>(sPbrFaces[i]);          ll_aligned_free<64>(sAlphaFaces[i]);          sFullbrightFaces[i] = NULL; @@ -5163,6 +5194,7 @@ void LLVolumeGeometryManager::freeFaces()          sNormFaces[i] = NULL;          sSpecFaces[i] = NULL;          sNormSpecFaces[i] = NULL; +        sPbrFaces[i] = NULL;          sAlphaFaces[i] = NULL;      }  } @@ -5437,7 +5469,8 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,      llassert(type != LLPipeline::RENDER_TYPE_PASS_GLTF_PBR_RIGGED || info->mGLTFMaterial != nullptr);      llassert(type != LLPipeline::RENDER_TYPE_PASS_GLTF_PBR_ALPHA_MASK || info->mGLTFMaterial != nullptr);      llassert(type != LLPipeline::RENDER_TYPE_PASS_GLTF_PBR_ALPHA_MASK_RIGGED || info->mGLTFMaterial != nullptr); - +     +    llassert(type != LLRenderPass::PASS_BUMP || (info->mVertexBuffer->getTypeMask() & LLVertexBuffer::MAP_TANGENT) != 0);      llassert(type != LLRenderPass::PASS_NORMSPEC || info->mNormalMap.notNull());  } @@ -5596,6 +5629,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  	U32 norm_count[2] = { 0 };  	U32 spec_count[2] = { 0 };  	U32 normspec_count[2] = { 0 }; +	U32 pbr_count[2] = { 0 };  	static LLCachedControl<S32> max_vbo_size(gSavedSettings, "RenderMaxVBOSize", 512);  	static LLCachedControl<S32> max_node_size(gSavedSettings, "RenderMaxNodeSize", 65536); @@ -5709,7 +5743,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  			rigged = rigged || (vobj->isAnimatedObject() && vobj->isRiggedMesh() &&                  vobj->getControlAvatar() && vobj->getControlAvatar()->mPlaying); -			bool bake_sunlight = LLPipeline::sBakeSunlight && drawablep->isStatic();  			bool any_rigged_face = false;  			//for each face @@ -5867,23 +5900,20 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  							facep->mLastUpdateTime = gFrameTimeSeconds;  						} -						if (gPipeline.canUseWindLightShadersOnObjects() -							&& LLPipeline::sRenderBump)  						{                              LLGLTFMaterial* gltf_mat = te->getGLTFRenderMaterial(); -							if (LLPipeline::sRenderDeferred &&  -                                (gltf_mat != nullptr || (te->getMaterialParams().notNull()  && !te->getMaterialID().isNull()))) +							if (gltf_mat != nullptr || (te->getMaterialParams().notNull()  && !te->getMaterialID().isNull()))  							{                                  if (gltf_mat != nullptr)                                  { -                                    // all gltf materials have all vertex attributes for now -                                    add_face(sNormSpecFaces, normspec_count, facep); +                                    add_face(sPbrFaces, pbr_count, facep);                                  }                                  else                                  {                                      LLMaterial* mat = te->getMaterialParams().get(); -                                    if (mat->getNormalID().notNull()) +                                    if (mat->getNormalID().notNull() || // <-- has a normal map, needs tangents +                                        (te->getBumpmap() && (te->getBumpmap() < 18))) // <-- has an emboss bump map, needs tangents                                      {                                          if (mat->getSpecularID().notNull())                                          { //has normal and specular maps (needs texcoord1, texcoord2, and tangent) @@ -5918,23 +5948,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)                                  add_face(sFullbrightFaces, fullbright_count, facep);  							}  						} -						else -						{ -							if (te->getBumpmap() && LLPipeline::sRenderBump) -							{ //needs normal + tangent -                                add_face(sBumpFaces, bump_count, facep); -							} -							else if ((te->getShiny() && LLPipeline::sRenderBump) || -								!(te->getFullbright() || bake_sunlight)) -							{ //needs normal -                                add_face(sSimpleFaces, simple_count, facep); -							} -							else  -							{ //doesn't need normal -								facep->setState(LLFace::FULLBRIGHT); -                                add_face(sFullbrightFaces, fullbright_count, facep); -							} -						}  					}  				}  				else @@ -5977,6 +5990,8 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  	U32 normspec_mask = norm_mask | LLVertexBuffer::MAP_TEXCOORD2;  	U32 spec_mask = simple_mask | LLVertexBuffer::MAP_TEXCOORD2; +	U32 pbr_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TANGENT; +  	if (emissive)  	{ //emissive faces are present, include emissive byte to preserve batching  		simple_mask = simple_mask | LLVertexBuffer::MAP_EMISSIVE; @@ -5986,6 +6001,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  		norm_mask = norm_mask | LLVertexBuffer::MAP_EMISSIVE;  		normspec_mask = normspec_mask | LLVertexBuffer::MAP_EMISSIVE;  		spec_mask = spec_mask | LLVertexBuffer::MAP_EMISSIVE; +        pbr_mask = pbr_mask | LLVertexBuffer::MAP_EMISSIVE;  	}  	BOOL batch_textures = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 1; @@ -6016,6 +6032,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)          geometryBytes += genDrawInfo(group, norm_mask | extra_mask, sNormFaces[i], norm_count[i], FALSE, FALSE, rigged);          geometryBytes += genDrawInfo(group, spec_mask | extra_mask, sSpecFaces[i], spec_count[i], FALSE, FALSE, rigged);          geometryBytes += genDrawInfo(group, normspec_mask | extra_mask, sNormSpecFaces[i], normspec_count[i], FALSE, FALSE, rigged); +        geometryBytes += genDrawInfo(group, pbr_mask | extra_mask, sPbrFaces[i], pbr_count[i], FALSE, FALSE, rigged);          // for rigged set, add weights and disable alpha sorting (rigged items use depth buffer)          extra_mask |= LLVertexBuffer::MAP_WEIGHT4; @@ -6158,7 +6175,7 @@ struct CompareBatchBreaker  		{  			return lte->getFullbright() < rte->getFullbright();  		} -        else if (LLPipeline::sRenderDeferred && lte->getMaterialID() != rte->getMaterialID()) +        else if (lte->getMaterialID() != rte->getMaterialID())          {              return lte->getMaterialID() < rte->getMaterialID();          } @@ -6249,13 +6266,9 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace  		texture_index_channels = LLGLSLShader::sIndexedTextureChannels-1; //always reserve one for shiny for now just for simplicity;  	} -	if (LLPipeline::sRenderDeferred && distance_sort) +	if (distance_sort)  	{  		texture_index_channels = gDeferredAlphaProgram.mFeatures.mIndexedTextureChannels; -	} -     -    if (distance_sort) -    {          buffer_index = -1;      } @@ -6611,6 +6624,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace  				}  				else if (use_legacy_bump)  				{ +                    llassert(mask & LLVertexBuffer::MAP_TANGENT);  					// we have a material AND legacy bump settings, but no normal map  					registerFace(group, facep, LLRenderPass::PASS_BUMP);  				} @@ -6670,7 +6684,6 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace  					registerFace(group, facep, LLRenderPass::PASS_ALPHA);  				}  				else if (gPipeline.shadersLoaded() -					&& LLPipeline::sRenderBump   					&& te->getShiny()   					&& can_be_shiny)  				{ @@ -6705,7 +6718,6 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace  				}  			}  			else if (gPipeline.shadersLoaded() -				&& LLPipeline::sRenderBump   				&& te->getShiny()   				&& can_be_shiny)  			{ //shiny @@ -6726,6 +6738,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace  					}  					else if (use_legacy_bump)  					{ //register in deferred bump pass +                        llassert(mask& LLVertexBuffer::MAP_TANGENT);  						registerFace(group, facep, LLRenderPass::PASS_BUMP);  					}  					else @@ -6759,15 +6772,16 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace  					{  						registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT);  					} -					if (!hud_group && LLPipeline::sRenderBump && use_legacy_bump) +					if (!hud_group && use_legacy_bump)  					{ //if this is the deferred render and a bump map is present, register in post deferred bump  						registerFace(group, facep, LLRenderPass::PASS_POST_BUMP);  					}  				}  				else  				{ -					if (LLPipeline::sRenderDeferred && LLPipeline::sRenderBump && use_legacy_bump) +					if (use_legacy_bump)  					{ //non-shiny or fullbright deferred bump +                        llassert(mask& LLVertexBuffer::MAP_TANGENT);  						registerFace(group, facep, LLRenderPass::PASS_BUMP);  					}  					else @@ -6787,8 +6801,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace  				if (!gPipeline.shadersLoaded() &&   					!is_alpha &&  -					te->getShiny() &&  -					LLPipeline::sRenderBump) +					te->getShiny())  				{ //shiny as an extra pass when shaders are disabled  					registerFace(group, facep, LLRenderPass::PASS_SHINY);  				} @@ -6800,8 +6813,9 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace  				llassert((mask & LLVertexBuffer::MAP_NORMAL) || fullbright);  				facep->setPoolType((fullbright) ? LLDrawPool::POOL_FULLBRIGHT : LLDrawPool::POOL_SIMPLE); -				if (!force_simple && LLPipeline::sRenderBump && use_legacy_bump) +				if (!force_simple && use_legacy_bump)  				{ +                    llassert(mask & LLVertexBuffer::MAP_TANGENT);  					registerFace(group, facep, LLRenderPass::PASS_BUMP);  				}  			} diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 466a5d2995..e6ad42c23b 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -308,7 +308,6 @@ bool	LLPipeline::sDelayVBUpdate = true;  bool	LLPipeline::sAutoMaskAlphaDeferred = true;  bool	LLPipeline::sAutoMaskAlphaNonDeferred = false;  bool	LLPipeline::sRenderTransparentWater = true; -bool	LLPipeline::sRenderBump = true;  bool	LLPipeline::sBakeSunlight = false;  bool	LLPipeline::sNoAlpha = false;  bool	LLPipeline::sUseFarClip = true; @@ -335,18 +334,6 @@ static LLCullResult* sCull = NULL;  void validate_framebuffer_object(); -// override the projection_matrix uniform on the given shader to that which would be set by the main camera -void set_camera_projection_matrix(LLGLSLShader& shader) -{ -    auto          camProj = LLViewerCamera::getInstance()->getProjection(); -    glh::matrix4f projection = get_current_projection(); -    projection.set_row(0, glh::vec4f(camProj.mMatrix[0][0], camProj.mMatrix[0][1], camProj.mMatrix[0][2], camProj.mMatrix[0][3])); -    projection.set_row(0, glh::vec4f(camProj.mMatrix[1][0], camProj.mMatrix[1][1], camProj.mMatrix[1][2], camProj.mMatrix[1][3])); -    projection.set_row(0, glh::vec4f(camProj.mMatrix[2][0], camProj.mMatrix[2][1], camProj.mMatrix[2][2], camProj.mMatrix[2][3])); -    projection.set_row(0, glh::vec4f(camProj.mMatrix[3][0], camProj.mMatrix[3][1], camProj.mMatrix[3][2], camProj.mMatrix[3][3])); -    shader.uniformMatrix4fv(LLShaderMgr::PROJECTION_MATRIX, 1, FALSE, projection.m); -} -  // Add color attachments for deferred rendering  // target -- RenderTarget to add attachments to  bool addDeferredAttachments(LLRenderTarget& target, bool for_impostor = false) @@ -412,7 +399,6 @@ void LLPipeline::init()  	gOctreeMaxCapacity = gSavedSettings.getU32("OctreeMaxNodeCapacity");  	gOctreeMinSize = gSavedSettings.getF32("OctreeMinimumNodeSize");  	sDynamicLOD = gSavedSettings.getBOOL("RenderDynamicLOD"); -    sRenderBump = TRUE; // DEPRECATED -- gSavedSettings.getBOOL("RenderObjectBump");  	sRenderAttachedLights = gSavedSettings.getBOOL("RenderAttachedLights");  	sRenderAttachedParticles = gSavedSettings.getBOOL("RenderAttachedParticles"); @@ -980,12 +966,6 @@ void LLPipeline::updateRenderTransparentWater()      sRenderTransparentWater = gSavedSettings.getBOOL("RenderTransparentWater");  } -//static -void LLPipeline::updateRenderBump() -{ -    sRenderBump = TRUE; // DEPRECATED -- gSavedSettings.getBOOL("RenderObjectBump"); -} -  // static  void LLPipeline::refreshCachedSettings()  { @@ -1195,46 +1175,44 @@ void LLPipeline::createGLBuffers()      mRT->width = 0;      mRT->height = 0; -    if (sRenderDeferred) -    { -		if (!mNoiseMap) -		{ -			const U32 noiseRes = 128; -			LLVector3 noise[noiseRes*noiseRes]; +     +	if (!mNoiseMap) +	{ +		const U32 noiseRes = 128; +		LLVector3 noise[noiseRes*noiseRes]; -			F32 scaler = gSavedSettings.getF32("RenderDeferredNoise")/100.f; -			for (U32 i = 0; i < noiseRes*noiseRes; ++i) -			{ -				noise[i] = LLVector3(ll_frand()-0.5f, ll_frand()-0.5f, 0.f); -				noise[i].normVec(); -				noise[i].mV[2] = ll_frand()*scaler+1.f-scaler/2.f; -			} +		F32 scaler = gSavedSettings.getF32("RenderDeferredNoise")/100.f; +		for (U32 i = 0; i < noiseRes*noiseRes; ++i) +		{ +			noise[i] = LLVector3(ll_frand()-0.5f, ll_frand()-0.5f, 0.f); +			noise[i].normVec(); +			noise[i].mV[2] = ll_frand()*scaler+1.f-scaler/2.f; +		} -			LLImageGL::generateTextures(1, &mNoiseMap); +		LLImageGL::generateTextures(1, &mNoiseMap); -			gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mNoiseMap); -			LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F, noiseRes, noiseRes, GL_RGB, GL_FLOAT, noise, false); -			gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); -		} +		gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mNoiseMap); +		LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F, noiseRes, noiseRes, GL_RGB, GL_FLOAT, noise, false); +		gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); +	} -		if (!mTrueNoiseMap) +	if (!mTrueNoiseMap) +	{ +		const U32 noiseRes = 128; +		F32 noise[noiseRes*noiseRes*3]; +		for (U32 i = 0; i < noiseRes*noiseRes*3; i++)  		{ -			const U32 noiseRes = 128; -			F32 noise[noiseRes*noiseRes*3]; -			for (U32 i = 0; i < noiseRes*noiseRes*3; i++) -			{ -				noise[i] = ll_frand()*2.0-1.0; -			} - -			LLImageGL::generateTextures(1, &mTrueNoiseMap); -			gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mTrueNoiseMap); -			LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F, noiseRes, noiseRes, GL_RGB,GL_FLOAT, noise, false); -			gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); +			noise[i] = ll_frand()*2.0-1.0;  		} -		createLUTBuffers(); +		LLImageGL::generateTextures(1, &mTrueNoiseMap); +		gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mTrueNoiseMap); +		LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F, noiseRes, noiseRes, GL_RGB,GL_FLOAT, noise, false); +		gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);  	} +	createLUTBuffers(); +  	gBumpImageList.restoreGL();  } @@ -1245,70 +1223,67 @@ F32 lerpf(F32 a, F32 b, F32 w)  void LLPipeline::createLUTBuffers()  { -	if (sRenderDeferred) +	if (!mLightFunc)  	{ -		if (!mLightFunc) +		U32 lightResX = gSavedSettings.getU32("RenderSpecularResX"); +		U32 lightResY = gSavedSettings.getU32("RenderSpecularResY"); +		F32* ls = new F32[lightResX*lightResY]; +		F32 specExp = gSavedSettings.getF32("RenderSpecularExponent"); +        // Calculate the (normalized) blinn-phong specular lookup texture. (with a few tweaks) +		for (U32 y = 0; y < lightResY; ++y)  		{ -			U32 lightResX = gSavedSettings.getU32("RenderSpecularResX"); -			U32 lightResY = gSavedSettings.getU32("RenderSpecularResY"); -			F32* ls = new F32[lightResX*lightResY]; -			F32 specExp = gSavedSettings.getF32("RenderSpecularExponent"); -            // Calculate the (normalized) blinn-phong specular lookup texture. (with a few tweaks) -			for (U32 y = 0; y < lightResY; ++y) +			for (U32 x = 0; x < lightResX; ++x)  			{ -				for (U32 x = 0; x < lightResX; ++x) -				{ -					ls[y*lightResX+x] = 0; -					F32 sa = (F32) x/(lightResX-1); -					F32 spec = (F32) y/(lightResY-1); -					F32 n = spec * spec * specExp; +				ls[y*lightResX+x] = 0; +				F32 sa = (F32) x/(lightResX-1); +				F32 spec = (F32) y/(lightResY-1); +				F32 n = spec * spec * specExp; -					// Nothing special here.  Just your typical blinn-phong term. -					spec = powf(sa, n); +				// Nothing special here.  Just your typical blinn-phong term. +				spec = powf(sa, n); -					// Apply our normalization function. -					// Note: This is the full equation that applies the full normalization curve, not an approximation. -					// This is fine, given we only need to create our LUT once per buffer initialization. -					spec *= (((n + 2) * (n + 4)) / (8 * F_PI * (powf(2, -n/2) + n))); - -					// Since we use R16F, we no longer have a dynamic range issue we need to work around here. -					// Though some older drivers may not like this, newer drivers shouldn't have this problem. -					ls[y*lightResX+x] = spec; -				} +				// Apply our normalization function. +				// Note: This is the full equation that applies the full normalization curve, not an approximation. +				// This is fine, given we only need to create our LUT once per buffer initialization. +				spec *= (((n + 2) * (n + 4)) / (8 * F_PI * (powf(2, -n/2) + n))); + +				// Since we use R16F, we no longer have a dynamic range issue we need to work around here. +				// Though some older drivers may not like this, newer drivers shouldn't have this problem. +				ls[y*lightResX+x] = spec;  			} +		} -			U32 pix_format = GL_R16F; +		U32 pix_format = GL_R16F;  #if LL_DARWIN -			// Need to work around limited precision with 10.6.8 and older drivers -			// -			pix_format = GL_R32F; +		// Need to work around limited precision with 10.6.8 and older drivers +		// +		pix_format = GL_R32F;  #endif -			LLImageGL::generateTextures(1, &mLightFunc); -			gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mLightFunc); -			LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, pix_format, lightResX, lightResY, GL_RED, GL_FLOAT, ls, false); -			gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); -			gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR); -			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); -			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); +		LLImageGL::generateTextures(1, &mLightFunc); +		gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mLightFunc); +		LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, pix_format, lightResX, lightResY, GL_RED, GL_FLOAT, ls, false); +		gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); +		gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR); +		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); +		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); -			delete [] ls; -		} +		delete [] ls; +	} -        mPbrBrdfLut.allocate(512, 512, GL_RG16F); -        mPbrBrdfLut.bindTarget(); -        gDeferredGenBrdfLutProgram.bind(); +    mPbrBrdfLut.allocate(512, 512, GL_RG16F); +    mPbrBrdfLut.bindTarget(); +    gDeferredGenBrdfLutProgram.bind(); -        gGL.begin(LLRender::TRIANGLE_STRIP); -        gGL.vertex2f(-1, -1); -        gGL.vertex2f(-1, 1); -        gGL.vertex2f(1, -1); -        gGL.vertex2f(1, 1); -        gGL.end(); -        gGL.flush(); +    gGL.begin(LLRender::TRIANGLE_STRIP); +    gGL.vertex2f(-1, -1); +    gGL.vertex2f(-1, 1); +    gGL.vertex2f(1, -1); +    gGL.vertex2f(1, 1); +    gGL.end(); +    gGL.flush(); -        gDeferredGenBrdfLutProgram.unbind(); -        mPbrBrdfLut.flush(); -	} +    gDeferredGenBrdfLutProgram.unbind(); +    mPbrBrdfLut.flush();  } @@ -1343,11 +1318,6 @@ bool LLPipeline::canUseWindLightShaders() const      return true;  } -bool LLPipeline::canUseWindLightShadersOnObjects() const -{ -    return true; -} -  bool LLPipeline::canUseAntiAliasing() const  {  	return true; @@ -4331,6 +4301,8 @@ extern std::set<LLSpatialGroup*> visible_selected_groups;  void LLPipeline::renderDebug()  { +    LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; +  	assertInitialized();  	bool hud_only = hasRenderType(LLPipeline::RENDER_TYPE_HUD); @@ -4716,9 +4688,6 @@ void LLPipeline::renderDebug()          bindDeferredShader(gReflectionProbeDisplayProgram, NULL);          mScreenTriangleVB->setBuffer(); -        // Provide our projection matrix. -        set_camera_projection_matrix(gReflectionProbeDisplayProgram); -          LLGLEnable blend(GL_BLEND);          LLGLDepthTest depth(GL_FALSE); @@ -7410,40 +7379,6 @@ void LLPipeline::renderFinalize()          if (RenderScreenSpaceReflections && !gCubeSnapshot)          { -#if 0 -            LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("renderDeferredLighting - screen space reflections"); -            LL_PROFILE_GPU_ZONE("screen space reflections"); - -            bindDeferredShader(gPostScreenSpaceReflectionProgram, NULL); -            mScreenTriangleVB->setBuffer(); - -            set_camera_projection_matrix(gPostScreenSpaceReflectionProgram); - -            // We need linear depth. -            static LLStaticHashedString zfar("zFar"); -            static LLStaticHashedString znear("zNear"); -            float                       nearClip = LLViewerCamera::getInstance()->getNear(); -            float                       farClip  = LLViewerCamera::getInstance()->getFar(); -            gPostScreenSpaceReflectionProgram.uniform1f(zfar, farClip); -            gPostScreenSpaceReflectionProgram.uniform1f(znear, nearClip); - -            S32 channel = gPostScreenSpaceReflectionProgram.enableTexture(LLShaderMgr::DIFFUSE_MAP, screenTarget()->getUsage()); -            if (channel > -1) -            { -				screenTarget()->bindTexture(0, channel, LLTexUnit::TFO_POINT); -            } - -            { -                LLGLDisable blend(GL_BLEND); -                LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); - -                stop_glerror(); -                mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); -                stop_glerror(); -            } - -            unbindDeferredShader(gPostScreenSpaceReflectionProgram); -#else              LL_PROFILE_GPU_ZONE("ssr copy");              LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS); @@ -7465,7 +7400,6 @@ void LLPipeline::renderFinalize()              mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);              dst.flush(); -#endif          }          screenTarget()->bindTarget(); @@ -8116,6 +8050,8 @@ void LLPipeline::renderDeferredLighting()              soften_shader.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);              soften_shader.uniform3fv(LLShaderMgr::LIGHTNORM, 1, environment.getClampedLightNorm().mV); +            soften_shader.uniform4fv(LLShaderMgr::WATER_WATERPLANE, 1, LLDrawPoolAlpha::sWaterPlane.mV); +              {                  LLGLDepthTest depth(GL_FALSE);                  LLGLDisable   blend(GL_BLEND); diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 483fe08559..0faa0c3f20 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -224,7 +224,6 @@ public:  	bool		shadersLoaded();  	bool		canUseWindLightShaders() const; -	bool		canUseWindLightShadersOnObjects() const;  	bool		canUseAntiAliasing() const;  	// phases @@ -421,7 +420,6 @@ public:  	static void setRenderHighlightTextureChannel(LLRender::eTexIndex channel); // sets which UV setup to display in highlight overlay  	static void updateRenderTransparentWater(); -	static void updateRenderBump();  	static void refreshCachedSettings();  	void addDebugBlip(const LLVector3& position, const LLColor4& color); @@ -623,7 +621,6 @@ public:  	static bool				sAutoMaskAlphaDeferred;  	static bool				sAutoMaskAlphaNonDeferred;  	static bool				sRenderTransparentWater; -	static bool				sRenderBump;  	static bool				sBakeSunlight;  	static bool				sNoAlpha;  	static bool				sUseFarClip; diff --git a/indra/newview/skins/default/xui/en/floater_material_editor.xml b/indra/newview/skins/default/xui/en/floater_material_editor.xml index 6adfa40733..1c58ea6977 100644 --- a/indra/newview/skins/default/xui/en/floater_material_editor.xml +++ b/indra/newview/skins/default/xui/en/floater_material_editor.xml @@ -15,6 +15,7 @@    <string name="upload_fee_string">L$[FEE] upload fee</string>    <string name="material_selection_title">Material selection</string>    <string name="material_selection_text">Select material:</string> +  <string name="material_batch_import_text">--- Bulk Upload All ---</string>    <string name="material_override_title">Editing Material</string>    <scroll_container diff --git a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml index a08831b396..534c4c3686 100644 --- a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml +++ b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml @@ -589,7 +589,7 @@      control_name="RenderDeferredSSAO"      height="16"      initial_value="true" -    label="Ambient Occlusion" +    label="Screen Space Ambient Occlusion"      layout="topleft"      left="420"      name="UseSSAO" | 
