summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/llcommon/llcommon.cpp29
-rw-r--r--indra/llcommon/llerror.h2
-rw-r--r--indra/llcommon/llprofiler.h6
-rw-r--r--indra/llcommon/llprofilercategories.h2
-rw-r--r--indra/llcommon/lluuid.cpp1443
-rw-r--r--indra/llmath/llvolume.cpp11
-rw-r--r--indra/llprimitive/llgltfloader.cpp4
-rw-r--r--indra/llprimitive/llgltfmaterial.cpp38
-rw-r--r--indra/llprimitive/llgltfmaterial.h22
-rw-r--r--indra/llprimitive/llmaterial.cpp2
-rw-r--r--indra/llprimitive/lltextureentry.cpp27
-rw-r--r--indra/llrender/llcubemaparray.cpp2
-rw-r--r--indra/llrender/llgltexture.h2
-rw-r--r--indra/llrender/llimagegl.cpp153
-rw-r--r--indra/llrender/llimagegl.h4
-rw-r--r--indra/llrender/llrender.cpp36
-rw-r--r--indra/llrender/llrender.h17
-rw-r--r--indra/llrender/llshadermgr.cpp22
-rw-r--r--indra/llrender/llshadermgr.h16
-rw-r--r--indra/llrender/llvertexbuffer.cpp35
-rw-r--r--indra/llrender/llvertexbuffer.h2
-rw-r--r--indra/llwindow/llwindowwin32.cpp3
-rw-r--r--indra/newview/CMakeLists.txt8
-rw-r--r--indra/newview/app_settings/settings.xml21
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl33
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/cofF.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl10
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl7
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/materialV.glsl27
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/moonF.glsl30
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pbralphaV.glsl40
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pbrglowV.glsl14
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl48
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl51
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/skyF.glsl28
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/starsF.glsl15
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/sunDiscF.glsl21
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/textureUtilV.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl41
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/gaussianF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/glowcombineF.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/reflectionmipF.glsl20
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/splattexturerectV.glsl3
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl11
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl11
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/reflectionProbeF.glsl9
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/atmosphericsFuncs.glsl24
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl29
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/transportF.glsl18
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/materialF.glsl37
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl5
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl6
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl71
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl58
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl6
-rw-r--r--indra/newview/app_settings/shaders/class3/environment/waterF.glsl42
-rw-r--r--indra/newview/featuretable.txt16
-rw-r--r--indra/newview/featuretable_mac.txt17
-rw-r--r--indra/newview/llagent.cpp2
-rw-r--r--indra/newview/llappviewer.cpp3
-rw-r--r--indra/newview/lldrawable.cpp8
-rw-r--r--indra/newview/lldrawpoolwlsky.cpp7
-rw-r--r--indra/newview/llenvironment.cpp8
-rw-r--r--indra/newview/llface.cpp32
-rw-r--r--indra/newview/llface.h1
-rw-r--r--indra/newview/llfeaturemanager.cpp8
-rw-r--r--indra/newview/llfetchedgltfmaterial.cpp36
-rw-r--r--indra/newview/llfetchedgltfmaterial.h4
-rw-r--r--indra/newview/llfilepicker.cpp1
-rw-r--r--indra/newview/llgltfmateriallist.cpp28
-rw-r--r--indra/newview/lllocalgltfmaterials.cpp54
-rw-r--r--indra/newview/lllocalgltfmaterials.h5
-rw-r--r--indra/newview/llmaterialeditor.cpp69
-rw-r--r--indra/newview/llmaterialeditor.h4
-rw-r--r--indra/newview/llmodelpreview.cpp4
-rw-r--r--indra/newview/llpanelvolume.cpp58
-rw-r--r--indra/newview/llpanelvolume.h7
-rw-r--r--indra/newview/llreflectionmapmanager.cpp26
-rw-r--r--indra/newview/llselectmgr.cpp26
-rw-r--r--indra/newview/llsettingsvo.cpp8
-rw-r--r--indra/newview/llspatialpartition.cpp73
-rw-r--r--indra/newview/llspatialpartition.h2
-rw-r--r--indra/newview/lltextureview.cpp4
-rw-r--r--indra/newview/lltinygltfhelper.cpp53
-rw-r--r--indra/newview/lltinygltfhelper.h5
-rw-r--r--indra/newview/llviewermenufile.cpp74
-rw-r--r--indra/newview/llviewerobject.cpp38
-rw-r--r--indra/newview/llviewerobjectlist.cpp20
-rwxr-xr-xindra/newview/llviewerregion.cpp17
-rw-r--r--indra/newview/llviewershadermgr.cpp6
-rw-r--r--indra/newview/llviewerstats.cpp7
-rw-r--r--indra/newview/llviewertexture.cpp214
-rw-r--r--indra/newview/llviewertexture.h3
-rw-r--r--indra/newview/llviewertexturelist.cpp37
-rw-r--r--indra/newview/llviewerwindow.cpp23
-rw-r--r--indra/newview/llvocache.cpp184
-rw-r--r--indra/newview/llvocache.h3
-rw-r--r--indra/newview/llvovolume.cpp102
-rw-r--r--indra/newview/pipeline.cpp253
-rw-r--r--indra/newview/pipeline.h3
-rw-r--r--indra/newview/skins/default/xui/en/floater_material_editor.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml2
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml10
-rw-r--r--indra/newview/skins/default/xui/en/panel_tools_texture.xml6
-rw-r--r--indra/newview/tests/lldir_stub.cpp30
-rw-r--r--indra/newview/tests/llvieweroctree_stub.cpp86
-rw-r--r--indra/newview/tests/llvocache_test.cpp146
111 files changed, 2434 insertions, 2049 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(&timestamp);
- U16 our_clock_seq = clock_seq;
-
- // if clock hasn't changed or went backward, change clockseq
- if (cmpTime(&timestamp, &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(&timestamp);
+ U16 our_clock_seq = clock_seq;
+
+ // if clock hasn't changed or went backward, change clockseq
+ if (cmpTime(&timestamp, &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.cpp b/indra/llprimitive/llgltfmaterial.cpp
index d0ecf611ff..f3aa5b0648 100644
--- a/indra/llprimitive/llgltfmaterial.cpp
+++ b/indra/llprimitive/llgltfmaterial.cpp
@@ -43,26 +43,16 @@ const char* const GLTF_FILE_EXTENSION_TRANSFORM_ROTATION = "rotation";
// special UUID that indicates a null UUID in override data
static const LLUUID GLTF_OVERRIDE_NULL_UUID = LLUUID("ffffffff-ffff-ffff-ffff-ffffffffffff");
-// https://github.com/KhronosGroup/glTF/tree/main/extensions/3.0/Khronos/KHR_texture_transform
-LLMatrix3 LLGLTFMaterial::TextureTransform::asMatrix()
+void LLGLTFMaterial::TextureTransform::getPacked(F32 (&packed)[8])
{
- LLMatrix3 scale;
- scale.mMatrix[0][0] = mScale[0];
- scale.mMatrix[1][1] = mScale[1];
-
- LLMatrix3 rotation;
- const F32 cos_r = cos(mRotation);
- const F32 sin_r = sin(mRotation);
- rotation.mMatrix[0][0] = cos_r;
- rotation.mMatrix[0][1] = -sin_r;
- rotation.mMatrix[1][0] = sin_r;
- rotation.mMatrix[1][1] = cos_r;
-
- LLMatrix3 offset;
- offset.mMatrix[2][0] = mOffset[0];
- offset.mMatrix[2][1] = mOffset[1];
-
- return offset * rotation * scale;
+ packed[0] = mScale.mV[VX];
+ packed[1] = mScale.mV[VY];
+ packed[2] = mRotation;
+ // packed[3] = unused
+ packed[4] = mOffset.mV[VX];
+ packed[5] = mOffset.mV[VY];
+ // packed[6] = unused
+ // packed[7] = unused
}
bool LLGLTFMaterial::TextureTransform::operator==(const TextureTransform& other) const
@@ -702,3 +692,13 @@ void LLGLTFMaterial::applyOverride(const LLGLTFMaterial& override_mat)
}
}
}
+
+LLUUID LLGLTFMaterial::getHash() const
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
+ // HACK - hash the bytes of this object but don't include the ref count
+ LLUUID hash;
+ HBXXH128::digest(hash, (unsigned char*)this + sizeof(LLRefCount), sizeof(*this) - sizeof(LLRefCount));
+ return hash;
+}
+
diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h
index cae7284421..bdabd657e1 100644
--- a/indra/llprimitive/llgltfmaterial.h
+++ b/indra/llprimitive/llgltfmaterial.h
@@ -28,7 +28,6 @@
#include "llrefcount.h"
#include "llmemory.h"
-#include "m3math.h"
#include "v4color.h"
#include "v3color.h"
#include "v2math.h"
@@ -42,6 +41,8 @@ namespace tinygltf
class Model;
}
+class LLTextureEntry;
+
class LLGLTFMaterial : public LLRefCount
{
public:
@@ -60,7 +61,7 @@ public:
LLVector2 mScale = { 1.f, 1.f };
F32 mRotation = 0.f;
- LLMatrix3 asMatrix();
+ void getPacked(F32 (&packed)[8]);
bool operator==(const TextureTransform& other) const;
};
@@ -99,7 +100,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);
@@ -115,14 +117,7 @@ public:
bool mOverrideAlphaMode = false;
// get a UUID based on a hash of this LLGLTFMaterial
- LLUUID getHash() const
- {
- LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- // HACK - hash the bytes of this object but don't include the ref count
- LLUUID hash;
- HBXXH128::digest(hash, (unsigned char*)this + sizeof(S32), sizeof(this) - sizeof(S32));
- return hash;
- }
+ LLUUID getHash() const;
//setters for various members (will clamp to acceptable ranges)
// for_override - set to true if this value is being set as part of an override (important for handling override to default value)
@@ -200,6 +195,11 @@ public:
// True if setBaseMaterial() was just called
bool isClearedForBaseMaterial();
+ // For local materials, they have to keep track of where
+ // they are assigned to for full updates
+ virtual void addTextureEntry(LLTextureEntry* te) {};
+ virtual void removeTextureEntry(LLTextureEntry* te) {};
+
private:
template<typename T>
void setFromTexture(const tinygltf::Model& model, const T& texture_info, TextureInfo texture_info_id);
diff --git a/indra/llprimitive/llmaterial.cpp b/indra/llprimitive/llmaterial.cpp
index a694a666c6..37525e4a3d 100644
--- a/indra/llprimitive/llmaterial.cpp
+++ b/indra/llprimitive/llmaterial.cpp
@@ -481,7 +481,7 @@ LLUUID LLMaterial::getHash() const
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
// HACK - hash the bytes of this LLMaterial, but trim off the S32 in LLRefCount
LLUUID id;
- HBXXH128::digest(id, (unsigned char*)this + sizeof(S32), sizeof(this) - sizeof(S32));
+ HBXXH128::digest(id, (unsigned char*)this + sizeof(LLRefCount), sizeof(*this) - sizeof(LLRefCount));
return id;
}
diff --git a/indra/llprimitive/lltextureentry.cpp b/indra/llprimitive/lltextureentry.cpp
index 49f67918f8..a665db378b 100644
--- a/indra/llprimitive/lltextureentry.cpp
+++ b/indra/llprimitive/lltextureentry.cpp
@@ -112,7 +112,15 @@ LLTextureEntry &LLTextureEntry::operator=(const LLTextureEntry &rhs)
mMaterialID = rhs.mMaterialID;
+ if (mGLTFMaterial)
+ {
+ mGLTFMaterial->removeTextureEntry(this);
+ }
mGLTFMaterial = rhs.mGLTFMaterial;
+ if (mGLTFMaterial)
+ {
+ mGLTFMaterial->addTextureEntry(this);
+ }
if (rhs.mGLTFMaterialOverrides.notNull())
{
@@ -155,6 +163,12 @@ LLTextureEntry::~LLTextureEntry()
delete mMediaEntry;
mMediaEntry = NULL;
}
+
+ if (mGLTFMaterial)
+ {
+ mGLTFMaterial->removeTextureEntry(this);
+ mGLTFMaterial = NULL;
+ }
}
bool LLTextureEntry::operator!=(const LLTextureEntry &rhs) const
@@ -524,7 +538,20 @@ void LLTextureEntry::setGLTFMaterial(LLGLTFMaterial* material, bool local_origin
// NOTE: if you're hitting this assert, try to make sure calling code is using LLViewerObject::setRenderMaterialID
llassert(!local_origin || getGLTFMaterialOverride() == nullptr || getGLTFMaterialOverride()->isClearedForBaseMaterial());
+ if (mGLTFMaterial)
+ {
+ // Local materials have to keep track
+ // due to update mechanics
+ mGLTFMaterial->removeTextureEntry(this);
+ }
+
mGLTFMaterial = material;
+
+ if (mGLTFMaterial)
+ {
+ mGLTFMaterial->addTextureEntry(this);
+ }
+
if (mGLTFMaterial == nullptr)
{
setGLTFRenderMaterial(nullptr);
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 b3b79bd6c4..5b0690bc79 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -732,21 +732,8 @@ void LLImageGL::setImage(const LLImageRaw* imageraw)
BOOL LLImageGL::setImage(const U8* data_in, BOOL data_hasmips /* = FALSE */, S32 usename /* = 0 */)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- bool is_compressed = false;
- switch (mFormatPrimary)
- {
- case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
- case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
- case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
- case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
- case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
- case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
- is_compressed = true;
- break;
- default:
- break;
- }
+ const bool is_compressed = isCompressed();
if (mUseMipMaps)
{
@@ -1113,6 +1100,49 @@ void LLImageGL::postAddToAtlas()
stop_glerror();
}
+U32 type_width_from_pixtype(U32 pixtype)
+{
+ 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;
+ }
+ return type_width;
+}
+
+// Equivalent to calling glSetSubImage2D(target, miplevel, x_offset, y_offset, width, height, pixformat, pixtype, src), assuming the total width of the image is data_width
+// However, instead there are multiple calls to glSetSubImage2D on smaller slices of the image
+void subImageLines(U32 target, S32 miplevel, S32 x_offset, S32 y_offset, S32 width, S32 height, U32 pixformat, U32 pixtype, const U8* src, S32 data_width)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
+
+ U32 components = LLImageGL::dataFormatComponents(pixformat);
+ U32 type_width = type_width_from_pixtype(pixtype);
+
+ const U32 line_width = data_width * components * type_width;
+ const U32 y_offset_end = y_offset + height;
+ for (U32 y_pos = y_offset; y_pos < y_offset_end; ++y_pos)
+ {
+ glTexSubImage2D(target, miplevel, x_offset, y_pos, width, 1, pixformat, pixtype, src);
+ src += line_width;
+ }
+}
+
BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update /* = FALSE */, LLGLuint use_name)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
@@ -1187,13 +1217,29 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3
stop_glerror();
}
- datap += (y_pos * data_width + x_pos) * getComponents();
+ const U8* sub_datap = datap + (y_pos * data_width + x_pos) * getComponents();
// Update the GL texture
BOOL res = gGL.getTexUnit(0)->bindManual(mBindTarget, tex_name);
if (!res) LL_ERRS() << "LLImageGL::setSubImage(): bindTexture failed" << LL_ENDL;
stop_glerror();
- glTexSubImage2D(mTarget, 0, x_pos, y_pos, width, height, mFormatPrimary, mFormatType, datap);
+#if LL_DARWIN
+ const bool use_sub_image = false;
+#else
+ const bool use_sub_image = !isCompressed();
+#endif
+ if (!use_sub_image)
+ {
+ // *TODO: Why does this work here, in setSubImage, but not in
+ // setManualImage? Maybe because it only gets called with the
+ // dimensions of the full image? Or because the image is never
+ // compressed?
+ glTexSubImage2D(mTarget, 0, x_pos, y_pos, width, height, mFormatPrimary, mFormatType, sub_datap);
+ }
+ else
+ {
+ subImageLines(mTarget, 0, x_pos, y_pos, width, height, mFormatPrimary, mFormatType, sub_datap, data_width);
+ }
gGL.getTexUnit(0)->disable();
stop_glerror();
@@ -1359,7 +1405,8 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt
}
}
- if (LLImageGL::sCompressTextures && allow_compression)
+ const bool compress = LLImageGL::sCompressTextures && allow_compression;
+ if (compress)
{
switch (intformat)
{
@@ -1408,50 +1455,33 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt
LL_PROFILE_ZONE_NUM(height);
free_cur_tex_image();
-#if 0
- glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, use_scratch ? scratch : pixels);
+#if LL_DARWIN
+ 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
+ // *TODO: Small chance that glCompressedTexImage2D/glCompressedTexSubImage2D may work better here
+ const bool use_sub_image = !compress;
+#endif
+ if (!use_sub_image)
{
- LL_PROFILE_ZONE_NAMED("glTexImage2D alloc");
- glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, nullptr);
+ LL_PROFILE_ZONE_NAMED("glTexImage2D alloc + copy");
+ 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");
+ subImageLines(target, miplevel, 0, 0, width, height, pixformat, pixtype, src, width);
}
}
-#endif
alloc_tex_image(width, height, pixformat);
}
stop_glerror();
@@ -2270,6 +2300,27 @@ void LLImageGL::freePickMask()
mPickMaskWidth = mPickMaskHeight = 0;
}
+bool LLImageGL::isCompressed()
+{
+ llassert(mFormatPrimary != 0);
+ // *NOTE: Not all compressed formats are included here.
+ bool is_compressed = false;
+ switch (mFormatPrimary)
+ {
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
+ is_compressed = true;
+ break;
+ default:
+ break;
+ }
+ return is_compressed;
+}
+
//----------------------------------------------------------------------------
void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in)
{
diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h
index bbd024abd9..42f6efef77 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);
+ // *TODO: This function may not work if the textures is compressed (i.e.
+ // RenderCompressTextures is 0). Partial image updates do not work on
+ // compressed textures.
BOOL setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update = FALSE, LLGLuint use_name = 0);
BOOL setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update = FALSE, LLGLuint use_name = 0);
BOOL setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_pos, S32 width, S32 height);
@@ -211,6 +214,7 @@ public:
private:
U32 createPickMask(S32 pWidth, S32 pHeight);
void freePickMask();
+ bool isCompressed();
LLPointer<LLImageRaw> mSaveData; // used for destroyGL/restoreGL
LL::WorkQueue::weak_t mMainQueue;
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 c355115e8c..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"))
{
@@ -1074,20 +1074,12 @@ void LLShaderMgr::initAttribsAndUniforms()
mReservedUniforms.push_back("object_plane_s");
mReservedUniforms.push_back("object_plane_t");
- mReservedUniforms.push_back("texture_base_color_scale"); // (GLTF)
- mReservedUniforms.push_back("texture_base_color_rotation"); // (GLTF)
- mReservedUniforms.push_back("texture_base_color_offset"); // (GLTF)
- mReservedUniforms.push_back("texture_normal_scale"); // (GLTF)
- mReservedUniforms.push_back("texture_normal_rotation"); // (GLTF)
- mReservedUniforms.push_back("texture_normal_offset"); // (GLTF)
- mReservedUniforms.push_back("texture_metallic_roughness_scale"); // (GLTF)
- mReservedUniforms.push_back("texture_metallic_roughness_rotation"); // (GLTF)
- mReservedUniforms.push_back("texture_metallic_roughness_offset"); // (GLTF)
- mReservedUniforms.push_back("texture_emissive_scale"); // (GLTF)
- mReservedUniforms.push_back("texture_emissive_rotation"); // (GLTF)
- mReservedUniforms.push_back("texture_emissive_offset"); // (GLTF)
-
- llassert(mReservedUniforms.size() == LLShaderMgr::TEXTURE_EMISSIVE_OFFSET+1);
+ mReservedUniforms.push_back("texture_base_color_transform"); // (GLTF)
+ mReservedUniforms.push_back("texture_normal_transform"); // (GLTF)
+ mReservedUniforms.push_back("texture_metallic_roughness_transform"); // (GLTF)
+ mReservedUniforms.push_back("texture_emissive_transform"); // (GLTF)
+
+ llassert(mReservedUniforms.size() == LLShaderMgr::TEXTURE_EMISSIVE_TRANSFORM+1);
mReservedUniforms.push_back("viewport");
diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h
index f7439a65af..93ea49d16a 100644
--- a/indra/llrender/llshadermgr.h
+++ b/indra/llrender/llshadermgr.h
@@ -53,18 +53,10 @@ public:
OBJECT_PLANE_S, // "object_plane_s"
OBJECT_PLANE_T, // "object_plane_t"
- TEXTURE_BASE_COLOR_SCALE, // "texture_base_color_scale" (GLTF)
- TEXTURE_BASE_COLOR_ROTATION, // "texture_base_color_rotation" (GLTF)
- TEXTURE_BASE_COLOR_OFFSET, // "texture_base_color_offset" (GLTF)
- TEXTURE_NORMAL_SCALE, // "texture_normal_scale" (GLTF)
- TEXTURE_NORMAL_ROTATION, // "texture_normal_rotation" (GLTF)
- TEXTURE_NORMAL_OFFSET, // "texture_normal_offset" (GLTF)
- TEXTURE_METALLIC_ROUGHNESS_SCALE, // "texture_metallic_roughness_scale" (GLTF)
- TEXTURE_METALLIC_ROUGHNESS_ROTATION,// "texture_metallic_roughness_rotation" (GLTF)
- TEXTURE_METALLIC_ROUGHNESS_OFFSET, // "texture_metallic_roughness_offset" (GLTF)
- TEXTURE_EMISSIVE_SCALE, // "texture_emissive_scale" (GLTF)
- TEXTURE_EMISSIVE_ROTATION, // "texture_emissive_rotation" (GLTF)
- TEXTURE_EMISSIVE_OFFSET, // "texture_emissive_offset" (GLTF)
+ TEXTURE_BASE_COLOR_TRANSFORM, // "texture_base_color_transform" (GLTF)
+ TEXTURE_NORMAL_TRANSFORM, // "texture_normal_transform" (GLTF)
+ TEXTURE_METALLIC_ROUGHNESS_TRANSFORM, // "texture_metallic_roughness_transform" (GLTF)
+ TEXTURE_EMISSIVE_TRANSFORM, // "texture_emissive_transform" (GLTF)
VIEWPORT, // "viewport"
LIGHT_POSITION, // "light_position"
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index 11e2b6e5c4..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) > 0) || (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/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 1588f16f07..3271de72c9 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -2383,6 +2383,7 @@ if (LL_TESTS)
# llremoteparcelrequest.cpp
llviewerhelputil.cpp
llversioninfo.cpp
+ llvocache.cpp
llworldmap.cpp
llworldmipmap.cpp
)
@@ -2396,6 +2397,13 @@ if (LL_TESTS)
#llviewertexturelist.cpp
)
+ set_source_files_properties(
+ llvocache.cpp
+ PROPERTIES
+ LL_TEST_ADDITIONAL_SOURCE_FILES
+ ../llmessage/lldatapacker.cpp
+ )
+
set(test_libs
${LLCOMMON_LIBRARIES}
${JSONCPP_LIBRARIES}
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 81fed560bb..6d7e93b364 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -9887,7 +9887,7 @@
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
- <integer>1</integer>
+ <integer>0</integer>
</map>
<key>RenderFlexTimeFactor</key>
<map>
@@ -10402,7 +10402,7 @@
<key>Type</key>
<string>F32</string>
<key>Value</key>
- <real>8</real>
+ <real>16</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..e0e97bb938 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl
@@ -24,19 +24,15 @@
*/
/*[EXTRA_CODE_HERE]*/
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_data[3];
-#else
-#define frag_data gl_FragData
-#endif
+out vec4 frag_data[4];
/////////////////////////////////////////////////////////////////////////
// The fragment shader for the sky
/////////////////////////////////////////////////////////////////////////
-VARYING vec3 vary_CloudColorSun;
-VARYING vec3 vary_CloudColorAmbient;
-VARYING float vary_CloudDensity;
+in vec3 vary_CloudColorSun;
+in vec3 vary_CloudColorAmbient;
+in float vary_CloudDensity;
uniform sampler2D cloud_noise_texture;
uniform sampler2D cloud_noise_texture_next;
@@ -46,19 +42,16 @@ uniform vec3 cloud_pos_density2;
uniform float cloud_scale;
uniform float cloud_variance;
-VARYING vec2 vary_texcoord0;
-VARYING vec2 vary_texcoord1;
-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);
+in vec2 vary_texcoord0;
+in vec2 vary_texcoord1;
+in vec2 vary_texcoord2;
+in vec2 vary_texcoord3;
+in float altitude_blend_factor;
vec4 cloudNoise(vec2 uv)
{
- vec4 a = texture2D(cloud_noise_texture, uv);
- vec4 b = texture2D(cloud_noise_texture_next, uv);
+ vec4 a = texture(cloud_noise_texture, uv);
+ vec4 b = texture(cloud_noise_texture_next, uv);
vec4 cloud_noise_sample = mix(a, b, blend_factor);
return cloud_noise_sample;
}
@@ -119,11 +112,11 @@ 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);
+ frag_data[0] = vec4(0);
frag_data[1] = vec4(0.0,0.0,0.0,0.0);
frag_data[2] = vec4(0,0,0,GBUFFER_FLAG_SKIP_ATMOS);
+ frag_data[3] = vec4(color.rgb, alpha1);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/cofF.glsl b/indra/newview/app_settings/shaders/class1/deferred/cofF.glsl
index 1e640d95ae..929b4e17b1 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/cofF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/cofF.glsl
@@ -35,7 +35,6 @@ out vec4 frag_color;
uniform sampler2D diffuseRect;
uniform sampler2D depthMap;
-uniform sampler2D bloomMap;
uniform float depth_cutoff;
uniform float norm_cutoff;
@@ -81,7 +80,6 @@ void main()
sc = min(sc, max_cof);
sc = max(sc, -max_cof);
- vec4 bloom = texture2D(bloomMap, vary_fragcoord.xy);
- frag_color.rgb = diff.rgb + bloom.rgb;
+ frag_color.rgb = diff.rgb;
frag_color.a = sc/max_cof*0.5+0.5;
}
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/moonF.glsl b/indra/newview/app_settings/shaders/class1/deferred/moonF.glsl
index 41dd485fae..fabc61eb5e 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/moonF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/moonF.glsl
@@ -27,11 +27,7 @@
/*[EXTRA_CODE_HERE]*/
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_data[3];
-#else
-#define frag_data gl_FragData
-#endif
+out vec4 frag_data[4];
uniform vec4 color;
uniform vec3 moonlight_color;
@@ -39,12 +35,7 @@ uniform vec3 moon_dir;
uniform float moon_brightness;
uniform sampler2D diffuseMap;
-VARYING vec2 vary_texcoord0;
-
-vec3 srgb_to_linear(vec3 c);
-
-/// Soft clips the light with a gamma correction
-vec3 scaleSoftClip(vec3 light);
+in vec2 vary_texcoord0;
void main()
{
@@ -53,24 +44,25 @@ void main()
if( moon_dir.z > 0 )
fade = clamp( moon_dir.z*moon_dir.z*4.0, 0.0, 1.0 );
- vec4 c = texture2D(diffuseMap, vary_texcoord0.xy);
+ vec4 c = texture(diffuseMap, vary_texcoord0.xy);
// SL-14113 Don't write to depth; prevent moon's quad from hiding stars which should be visible
// Moon texture has transparent pixels <0x55,0x55,0x55,0x00>
if (c.a <= 2./255.) // 0.00784
+ {
discard;
+ }
-// c.rgb = srgb_to_linear(c.rgb);
- c.rgb *= moonlight_color.rgb;
- c.rgb *= moon_brightness;
- c.rgb *= fade;
- c.a *= fade;
+ c.rgb *= moonlight_color.rgb;
+ c.rgb *= moon_brightness;
- c.rgb = scaleSoftClip(c.rgb);
+ c.rgb *= fade;
+ c.a *= fade;
- frag_data[0] = vec4(c.rgb, c.a);
+ frag_data[0] = vec4(0);
frag_data[1] = vec4(0.0);
frag_data[2] = vec4(0.0, 0.0, 0.0, GBUFFER_FLAG_HAS_ATMOS);
+ frag_data[3] = vec4(c.rgb, c.a);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbralphaV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbralphaV.glsl
index a9e114dddc..e9515a9187 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/pbralphaV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/pbralphaV.glsl
@@ -44,18 +44,10 @@ uniform mat4 modelview_matrix;
out vec3 vary_position;
-uniform vec2 texture_base_color_scale;
-uniform float texture_base_color_rotation;
-uniform vec2 texture_base_color_offset;
-uniform vec2 texture_normal_scale;
-uniform float texture_normal_rotation;
-uniform vec2 texture_normal_offset;
-uniform vec2 texture_metallic_roughness_scale;
-uniform float texture_metallic_roughness_rotation;
-uniform vec2 texture_metallic_roughness_offset;
-uniform vec2 texture_emissive_scale;
-uniform float texture_emissive_rotation;
-uniform vec2 texture_emissive_offset;
+uniform vec4[2] texture_base_color_transform;
+uniform vec4[2] texture_normal_transform;
+uniform vec4[2] texture_metallic_roughness_transform;
+uniform vec4[2] texture_emissive_transform;
out vec3 vary_fragcoord;
@@ -78,7 +70,7 @@ out vec3 vary_tangent;
flat out float vary_sign;
out vec3 vary_normal;
-vec2 texture_transform(vec2 vertex_texcoord, vec2 khr_gltf_scale, float khr_gltf_rotation, vec2 khr_gltf_offset, mat4 sl_animation_transform);
+vec2 texture_transform(vec2 vertex_texcoord, vec4[2] khr_gltf_transform, mat4 sl_animation_transform);
void main()
@@ -97,10 +89,10 @@ void main()
vary_fragcoord.xyz = vert.xyz + vec3(0,0,near_clip);
- base_color_texcoord = texture_transform(texcoord0, texture_base_color_scale, texture_base_color_rotation, texture_base_color_offset, texture_matrix0);
- normal_texcoord = texture_transform(texcoord0, texture_normal_scale, texture_normal_rotation, texture_normal_offset, texture_matrix0);
- metallic_roughness_texcoord = texture_transform(texcoord0, texture_metallic_roughness_scale, texture_metallic_roughness_rotation, texture_metallic_roughness_offset, texture_matrix0);
- emissive_texcoord = texture_transform(texcoord0, texture_emissive_scale, texture_emissive_rotation, texture_emissive_offset, texture_matrix0);
+ base_color_texcoord = texture_transform(texcoord0, texture_base_color_transform, texture_matrix0);
+ normal_texcoord = texture_transform(texcoord0, texture_normal_transform, texture_matrix0);
+ metallic_roughness_texcoord = texture_transform(texcoord0, texture_metallic_roughness_transform, texture_matrix0);
+ emissive_texcoord = texture_transform(texcoord0, texture_emissive_transform, texture_matrix0);
#ifdef HAS_SKIN
vec3 n = (mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz;
@@ -133,12 +125,8 @@ uniform mat4 modelview_matrix;
out vec3 vary_position;
-uniform vec2 texture_base_color_scale;
-uniform float texture_base_color_rotation;
-uniform vec2 texture_base_color_offset;
-uniform vec2 texture_emissive_scale;
-uniform float texture_emissive_rotation;
-uniform vec2 texture_emissive_offset;
+uniform vec4[2] texture_base_color_transform;
+uniform vec4[2] texture_emissive_transform;
in vec3 position;
in vec4 diffuse_color;
@@ -149,7 +137,7 @@ out vec2 emissive_texcoord;
out vec4 vertex_color;
-vec2 texture_transform(vec2 vertex_texcoord, vec2 khr_gltf_scale, float khr_gltf_rotation, vec2 khr_gltf_offset, mat4 sl_animation_transform);
+vec2 texture_transform(vec2 vertex_texcoord, vec4[2] khr_gltf_transform, mat4 sl_animation_transform);
void main()
@@ -159,8 +147,8 @@ void main()
gl_Position = vert;
vary_position = vert.xyz;
- base_color_texcoord = texture_transform(texcoord0, texture_base_color_scale, texture_base_color_rotation, texture_base_color_offset, texture_matrix0);
- emissive_texcoord = texture_transform(texcoord0, texture_emissive_scale, texture_emissive_rotation, texture_emissive_offset, texture_matrix0);
+ base_color_texcoord = texture_transform(texcoord0, texture_base_color_transform, texture_matrix0);
+ emissive_texcoord = texture_transform(texcoord0, texture_emissive_transform, texture_matrix0);
vertex_color = diffuse_color;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrglowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrglowV.glsl
index b73d08cf0d..82a50a115c 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/pbrglowV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/pbrglowV.glsl
@@ -34,12 +34,8 @@ uniform mat4 modelview_projection_matrix;
uniform mat4 texture_matrix0;
-uniform vec2 texture_base_color_scale;
-uniform float texture_base_color_rotation;
-uniform vec2 texture_base_color_offset;
-uniform vec2 texture_emissive_scale;
-uniform float texture_emissive_rotation;
-uniform vec2 texture_emissive_offset;
+uniform vec4[2] texture_base_color_transform;
+uniform vec4[2] texture_emissive_transform;
in vec3 position;
in vec4 emissive;
@@ -51,7 +47,7 @@ out vec2 emissive_texcoord;
out vec4 vertex_emissive;
-vec2 texture_transform(vec2 vertex_texcoord, vec2 khr_gltf_scale, float khr_gltf_rotation, vec2 khr_gltf_offset, mat4 sl_animation_transform);
+vec2 texture_transform(vec2 vertex_texcoord, vec4[2] khr_gltf_transform, mat4 sl_animation_transform);
void main()
{
@@ -68,8 +64,8 @@ void main()
gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
#endif
- base_color_texcoord = texture_transform(texcoord0, texture_base_color_scale, texture_base_color_rotation, texture_base_color_offset, texture_matrix0);
- emissive_texcoord = texture_transform(texcoord0, texture_emissive_scale, texture_emissive_rotation, texture_emissive_offset, texture_matrix0);
+ base_color_texcoord = texture_transform(texcoord0, texture_base_color_transform, texture_matrix0);
+ emissive_texcoord = texture_transform(texcoord0, texture_emissive_transform, texture_matrix0);
vertex_emissive = emissive;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl
index 6f50aefdab..e2c23ac8f0 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl
@@ -38,18 +38,10 @@ uniform mat4 modelview_projection_matrix;
#endif
uniform mat4 texture_matrix0;
-uniform vec2 texture_base_color_scale;
-uniform float texture_base_color_rotation;
-uniform vec2 texture_base_color_offset;
-uniform vec2 texture_normal_scale;
-uniform float texture_normal_rotation;
-uniform vec2 texture_normal_offset;
-uniform vec2 texture_metallic_roughness_scale;
-uniform float texture_metallic_roughness_rotation;
-uniform vec2 texture_metallic_roughness_offset;
-uniform vec2 texture_emissive_scale;
-uniform float texture_emissive_rotation;
-uniform vec2 texture_emissive_offset;
+uniform vec4[2] texture_base_color_transform;
+uniform vec4[2] texture_normal_transform;
+uniform vec4[2] texture_metallic_roughness_transform;
+uniform vec4[2] texture_emissive_transform;
in vec3 position;
in vec4 diffuse_color;
@@ -68,7 +60,7 @@ out vec3 vary_tangent;
flat out float vary_sign;
out vec3 vary_normal;
-vec2 texture_transform(vec2 vertex_texcoord, vec2 khr_gltf_scale, float khr_gltf_rotation, vec2 khr_gltf_offset, mat4 sl_animation_transform);
+vec2 texture_transform(vec2 vertex_texcoord, vec4[2] khr_gltf_transform, mat4 sl_animation_transform);
void main()
{
@@ -86,10 +78,10 @@ void main()
gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
#endif
- base_color_texcoord = texture_transform(texcoord0, texture_base_color_scale, texture_base_color_rotation, texture_base_color_offset, texture_matrix0);
- normal_texcoord = texture_transform(texcoord0, texture_normal_scale, texture_normal_rotation, texture_normal_offset, texture_matrix0);
- metallic_roughness_texcoord = texture_transform(texcoord0, texture_metallic_roughness_scale, texture_metallic_roughness_rotation, texture_metallic_roughness_offset, texture_matrix0);
- emissive_texcoord = texture_transform(texcoord0, texture_emissive_scale, texture_emissive_rotation, texture_emissive_offset, texture_matrix0);
+ base_color_texcoord = texture_transform(texcoord0, texture_base_color_transform, texture_matrix0);
+ normal_texcoord = texture_transform(texcoord0, texture_normal_transform, texture_matrix0);
+ metallic_roughness_texcoord = texture_transform(texcoord0, texture_metallic_roughness_transform, texture_matrix0);
+ emissive_texcoord = texture_transform(texcoord0, texture_emissive_transform, texture_matrix0);
#ifdef HAS_SKIN
vec3 n = (mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz;
@@ -114,18 +106,10 @@ uniform mat4 modelview_projection_matrix;
uniform mat4 texture_matrix0;
-uniform vec2 texture_base_color_scale;
-uniform float texture_base_color_rotation;
-uniform vec2 texture_base_color_offset;
-uniform vec2 texture_normal_scale;
-uniform float texture_normal_rotation;
-uniform vec2 texture_normal_offset;
-uniform vec2 texture_metallic_roughness_scale;
-uniform float texture_metallic_roughness_rotation;
-uniform vec2 texture_metallic_roughness_offset;
-uniform vec2 texture_emissive_scale;
-uniform float texture_emissive_rotation;
-uniform vec2 texture_emissive_offset;
+uniform vec4[2] texture_base_color_transform;
+uniform vec4[2] texture_normal_transform;
+uniform vec4[2] texture_metallic_roughness_transform;
+uniform vec4[2] texture_emissive_transform;
in vec3 position;
in vec4 diffuse_color;
@@ -136,15 +120,15 @@ out vec2 emissive_texcoord;
out vec4 vertex_color;
-vec2 texture_transform(vec2 vertex_texcoord, vec2 khr_gltf_scale, float khr_gltf_rotation, vec2 khr_gltf_offset, mat4 sl_animation_transform);
+vec2 texture_transform(vec2 vertex_texcoord, vec4[2] khr_gltf_transform, mat4 sl_animation_transform);
void main()
{
//transform vertex
gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
- base_color_texcoord = texture_transform(texcoord0, texture_base_color_scale, texture_base_color_rotation, texture_base_color_offset, texture_matrix0);
- emissive_texcoord = texture_transform(texcoord0, texture_emissive_scale, texture_emissive_rotation, texture_emissive_offset, texture_matrix0);
+ base_color_texcoord = texture_transform(texcoord0, texture_base_color_transform, texture_matrix0);
+ emissive_texcoord = texture_transform(texcoord0, texture_emissive_transform, texture_matrix0);
vertex_color = diffuse_color;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl
index f0e940eb5f..87324bca7f 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl
@@ -34,6 +34,7 @@ out vec4 frag_color;
#endif
uniform sampler2D diffuseRect;
+uniform sampler2D emissiveRect;
uniform vec2 screen_res;
VARYING vec2 vary_fragcoord;
@@ -44,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
@@ -65,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)
@@ -128,6 +103,7 @@ vec3 toneMapACES_Hill(vec3 color)
}
uniform float exposure;
+uniform float gamma;
vec3 toneMap(vec3 color)
{
@@ -145,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.6;
+ color *= 1.0/0.6;
+ //color /= 0.6;
color = toneMapACES_Hill(color);
#endif
- return linearTosRGB(color);
+ return linear_to_srgb(color);
}
//===============================================================
@@ -192,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);
+ 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/deferred/postDeferredNoDoFF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl
index a79f644aef..1b868aee8d 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl
@@ -34,7 +34,6 @@ out vec4 frag_color;
#endif
uniform sampler2D diffuseRect;
-uniform sampler2D bloomMap;
uniform vec2 screen_res;
VARYING vec2 vary_fragcoord;
@@ -43,7 +42,6 @@ void main()
{
vec4 diff = texture2D(diffuseRect, vary_fragcoord.xy);
- vec4 bloom = texture2D(bloomMap, vary_fragcoord.xy);
- frag_color = diff + bloom;
+ frag_color = diff;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl
index 930338cefb..cc4c3b5dce 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl
@@ -22,12 +22,10 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
-/*[EXTRA_CODE_HERE]*/
// Inputs
-VARYING vec3 vary_HazeColor;
-VARYING float vary_LightNormPosDot;
+in vec3 vary_HazeColor;
+in float vary_LightNormPosDot;
uniform sampler2D rainbow_map;
uniform sampler2D halo_map;
@@ -36,11 +34,9 @@ uniform float moisture_level;
uniform float droplet_radius;
uniform float ice_level;
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_data[3];
-#else
-#define frag_data gl_FragData
-#endif
+out vec4 frag_data[4];
+
+vec3 srgb_to_linear(vec3 c);
/////////////////////////////////////////////////////////////////////////
// The fragment shader for the sky
@@ -63,19 +59,16 @@ vec3 rainbow(float d)
d = clamp(d, 0.0, 0.25) + interior_coord;
float rad = (droplet_radius - 5.0f) / 1024.0f;
- return pow(texture2D(rainbow_map, vec2(rad+0.5, d)).rgb, vec3(1.8)) * moisture_level;
+ return pow(texture(rainbow_map, vec2(rad+0.5, d)).rgb, vec3(1.8)) * moisture_level;
}
vec3 halo22(float d)
{
d = clamp(d, 0.1, 1.0);
float v = sqrt(clamp(1 - (d * d), 0, 1));
- return texture2D(halo_map, vec2(0, v)).rgb * ice_level;
+ return texture(halo_map, vec2(0, v)).rgb * ice_level;
}
-/// Soft clips the light with a gamma correction
-vec3 scaleSoftClip(vec3 light);
-
void main()
{
// Potential Fill-rate optimization. Add cloud calculation
@@ -91,11 +84,10 @@ void main()
color.rgb += rainbow(optic_d);
color.rgb += halo_22;
color.rgb *= 2.;
- color.rgb = scaleSoftClip(color.rgb);
- // Gamma correct for WL (soft clip effect).
- frag_data[0] = vec4(color.rgb, 1.0);
- frag_data[1] = vec4(0.0,0.0,0.0,0.0);
+ frag_data[0] = vec4(0);
+ frag_data[1] = vec4(0);
frag_data[2] = vec4(0.0,0.0,0.0,GBUFFER_FLAG_SKIP_ATMOS); //1.0 in norm.w masks off fog
+ frag_data[3] = vec4(color.rgb, 1.0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl b/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl
index cdafdba15c..4f1756c367 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl
@@ -25,15 +25,11 @@
/*[EXTRA_CODE_HERE]*/
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_data[3];
-#else
-#define frag_data gl_FragData
-#endif
+out vec4 frag_data[4];
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-VARYING vec2 screenpos;
+in vec4 vertex_color;
+in vec2 vary_texcoord0;
+in vec2 screenpos;
uniform sampler2D diffuseMap;
uniform float blend_factor;
@@ -62,8 +58,9 @@ void main()
col.a = (col.a * factor) * 32.0f;
col.a *= twinkle();
- frag_data[0] = col;
+ frag_data[0] = vec4(0);
frag_data[1] = vec4(0.0f);
frag_data[2] = vec4(0.0, 1.0, 0.0, GBUFFER_FLAG_SKIP_ATMOS);
+ frag_data[3] = col;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunDiscF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunDiscF.glsl
index e35ea83f0a..a85e6ebc66 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/sunDiscF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/sunDiscF.glsl
@@ -27,36 +27,29 @@
/*[EXTRA_CODE_HERE]*/
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_data[3];
-#else
-#define frag_data gl_FragData
-#endif
+out vec4 frag_data[4];
vec3 srgb_to_linear(vec3 c);
-vec3 fullbrightAtmosTransport(vec3 light);
-vec3 fullbrightScaleSoftClip(vec3 light);
uniform sampler2D diffuseMap;
uniform sampler2D altDiffuseMap;
uniform float blend_factor; // interp factor between sunDisc A/B
-VARYING vec2 vary_texcoord0;
-VARYING float sun_fade;
+in vec2 vary_texcoord0;
+in float sun_fade;
void main()
{
- vec4 sunDiscA = texture2D(diffuseMap, vary_texcoord0.xy);
- vec4 sunDiscB = texture2D(altDiffuseMap, vary_texcoord0.xy);
+ vec4 sunDiscA = texture(diffuseMap, vary_texcoord0.xy);
+ vec4 sunDiscB = texture(altDiffuseMap, vary_texcoord0.xy);
vec4 c = mix(sunDiscA, sunDiscB, blend_factor);
- //c.rgb = fullbrightAtmosTransport(c.rgb);
- c.rgb = fullbrightScaleSoftClip(c.rgb);
// SL-9806 stars poke through
//c.a *= sun_fade;
- frag_data[0] = c;
+ frag_data[0] = vec4(0);
frag_data[1] = vec4(0.0f);
frag_data[2] = vec4(0.0, 1.0, 0.0, GBUFFER_FLAG_SKIP_ATMOS);
+ frag_data[3] = c;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/textureUtilV.glsl b/indra/newview/app_settings/shaders/class1/deferred/textureUtilV.glsl
index 39cc07d2d1..71f7ec52c4 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/textureUtilV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/textureUtilV.glsl
@@ -58,7 +58,7 @@ vec2 khr_texture_transform(vec2 texcoord, vec2 scale, float rotation, vec2 offse
// animations, available through LSL script functions such as
// LlSetTextureAnim. It assumes a right-handed UV coordinate system.
// texcoord - The final texcoord to use for image sampling
-vec2 texture_transform(vec2 vertex_texcoord, vec2 khr_gltf_scale, float khr_gltf_rotation, vec2 khr_gltf_offset, mat4 sl_animation_transform)
+vec2 texture_transform(vec2 vertex_texcoord, vec4[2] khr_gltf_transform, mat4 sl_animation_transform)
{
vec2 texcoord = vertex_texcoord;
@@ -67,7 +67,7 @@ vec2 texture_transform(vec2 vertex_texcoord, vec2 khr_gltf_scale, float khr_gltf
// Convert to left-handed coordinate system. The offset of 1 is necessary
// for rotations to be applied correctly.
texcoord.y = 1.0 - texcoord.y;
- texcoord = khr_texture_transform(texcoord, khr_gltf_scale, khr_gltf_rotation, khr_gltf_offset);
+ texcoord = khr_texture_transform(texcoord, khr_gltf_transform[0].xy, khr_gltf_transform[0].z, khr_gltf_transform[1].xy);
// Convert back to right-handed coordinate system
texcoord.y = 1.0 - texcoord.y;
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/class1/interface/gaussianF.glsl b/indra/newview/app_settings/shaders/class1/interface/gaussianF.glsl
index 8e341503f5..188fac5460 100644
--- a/indra/newview/app_settings/shaders/class1/interface/gaussianF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/gaussianF.glsl
@@ -41,7 +41,7 @@ void main()
{
vec3 col = vec3(0,0,0);
- float w[] = { 0.0002, 0.0060, 0.0606, 0.2417, 0.3829, 0.2417, 0.0606, 0.0060, 0.0002 };
+ float w[9] = float[9]( 0.0002, 0.0060, 0.0606, 0.2417, 0.3829, 0.2417, 0.0606, 0.0060, 0.0002 );
for (int i = 0; i < 9; ++i)
{
diff --git a/indra/newview/app_settings/shaders/class1/interface/glowcombineF.glsl b/indra/newview/app_settings/shaders/class1/interface/glowcombineF.glsl
index 3ead2149f5..770c436ede 100644
--- a/indra/newview/app_settings/shaders/class1/interface/glowcombineF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/glowcombineF.glsl
@@ -29,7 +29,6 @@
out vec4 frag_color;
-uniform sampler2D emissiveRect;
uniform sampler2D diffuseRect;
uniform sampler2D depthMap;
@@ -37,8 +36,7 @@ in vec2 tc;
void main()
{
- frag_color = texture2D(emissiveRect, tc) +
- texture2D(diffuseRect, tc);
+ frag_color = texture2D(diffuseRect, tc);
gl_FragDepth = texture(depthMap, tc).r;
}
diff --git a/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl b/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl
index b6f080739e..a1839d4a67 100644
--- a/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl
@@ -151,7 +151,7 @@ vec4 prefilterEnvMap(vec3 R)
// Solid angle of 1 pixel across all cube faces
float omegaP = 4.0 * PI / (6.0 * envMapDim * envMapDim);
// Biased (+1.0) mip level for better result
- float mipLevel = roughness == 0.0 ? 0.0 : max(0.5 * log2(omegaS / omegaP) + 1.0, 0.0f);
+ float mipLevel = roughness == 0.0 ? 0.0 : clamp(0.5 * log2(omegaS / omegaP) + 1.0, 0.0f, max_probe_lod);
color += textureLod(reflectionProbes, vec4(L, sourceIdx), mipLevel) * dotNL;
totalWeight += dotNL;
}
diff --git a/indra/newview/app_settings/shaders/class1/interface/reflectionmipF.glsl b/indra/newview/app_settings/shaders/class1/interface/reflectionmipF.glsl
index 9f7706fe36..45267e4403 100644
--- a/indra/newview/app_settings/shaders/class1/interface/reflectionmipF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/reflectionmipF.glsl
@@ -26,29 +26,11 @@
out vec4 frag_color;
uniform sampler2D diffuseRect;
-uniform sampler2D depthMap;
-
-uniform float resScale;
-uniform float znear;
-uniform float zfar;
in vec2 vary_texcoord0;
-// get linear depth value given a depth buffer sample d and znear and zfar values
-float linearDepth(float d, float znear, float zfar);
-
void main()
{
- float depth = texture(depthMap, vary_texcoord0.xy).r;
- float dist = linearDepth(depth, znear, zfar);
-
- // convert linear depth to distance
- vec3 v;
- v.xy = vary_texcoord0.xy / 512.0 * 2.0 - 1.0;
- v.z = 1.0;
- v = normalize(v);
- dist /= v.z;
-
vec3 col = texture(diffuseRect, vary_texcoord0.xy).rgb;
- frag_color = vec4(col, dist/256.0);
+ frag_color = vec4(col, 0.0);
}
diff --git a/indra/newview/app_settings/shaders/class1/interface/splattexturerectV.glsl b/indra/newview/app_settings/shaders/class1/interface/splattexturerectV.glsl
index edc0a9628b..7af7f20f85 100644
--- a/indra/newview/app_settings/shaders/class1/interface/splattexturerectV.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/splattexturerectV.glsl
@@ -26,15 +26,12 @@
uniform mat4 modelview_projection_matrix;
in vec3 position;
-in vec4 diffuse_color;
-out vec4 vertex_color;
out vec2 vary_texcoord0;
void main()
{
gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
vary_texcoord0 = position.xy*0.5+0.5;
- vertex_color = diffuse_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 f1ee4b4681..080f622155 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/reflectionProbeF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/reflectionProbeF.glsl
@@ -34,7 +34,7 @@ uniform mat3 env_mat;
vec3 srgb_to_linear(vec3 c);
void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
- vec2 tc, vec3 pos, vec3 norm, float glossiness, bool errorCorrect)
+ vec2 tc, vec3 pos, vec3 norm, float glossiness)
{
ambenv = vec3(reflection_probe_ambiance * 0.25);
@@ -43,11 +43,10 @@ void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
glossenv = srgb_to_linear(textureCube(environmentMap, env_vec).rgb);
}
-void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
- vec2 tc, vec3 pos, vec3 norm, float glossiness)
+void sampleReflectionProbesWater(inout vec3 ambenv, inout vec3 glossenv,
+ vec2 tc, vec3 pos, vec3 norm, float glossiness)
{
- sampleReflectionProbes(ambenv, glossenv,
- tc, pos, norm, glossiness, false);
+ sampleReflectionProbes(ambenv, glossenv, tc, pos, norm, glossiness);
}
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/multiPointLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl
index 7d8f9c218d..0fb30559d4 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl
@@ -37,7 +37,6 @@ uniform sampler2D depthMap;
uniform sampler2D diffuseRect;
uniform sampler2D specularRect;
uniform sampler2D emissiveRect; // PBR linear packed Occlusion, Roughness, Metal. See: pbropaqueF.glsl
-uniform sampler2D noiseMap;
uniform sampler2D lightFunc;
uniform vec3 env_mat[3];
@@ -132,9 +131,6 @@ void main()
}
else
{
-
- float noise = texture2D(noiseMap, tc).b;
-
diffuse = srgb_to_linear(diffuse);
spec.rgb = srgb_to_linear(spec.rgb);
@@ -154,7 +150,6 @@ void main()
float fa = light_col[i].a;
float dist_atten = calcLegacyDistanceAttenuation(dist, fa);
- dist_atten *= noise;
float lit = nl * dist_atten;
diff --git a/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl
index 5ed8a75e0e..30b7895157 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl
@@ -41,7 +41,6 @@ uniform sampler2D normalMap;
uniform sampler2D emissiveRect; // PBR linear packed Occlusion, Roughness, Metal. See: pbropaqueF.glsl
uniform samplerCube environmentMap;
uniform sampler2D lightMap;
-uniform sampler2D noiseMap;
uniform sampler2D projectionMap; // rgba
uniform sampler2D lightFunc;
@@ -187,7 +186,6 @@ void main()
diffuse = srgb_to_linear(diffuse);
spec.rgb = srgb_to_linear(spec.rgb);
- float noise = texture2D(noiseMap, tc).b;
if (proj_tc.z > 0.0 &&
proj_tc.x < 1.0 &&
proj_tc.y < 1.0 &&
@@ -199,7 +197,7 @@ void main()
if (nl > 0.0)
{
- lit = nl * dist_atten * noise;
+ lit = nl * dist_atten;
dlit = getProjectedLightDiffuseColor( l_dist, proj_tc.xy );
@@ -209,7 +207,7 @@ void main()
amb_da += (nl*0.5+0.5) /* * (1.0-shadow) */ * proj_ambiance;
}
- amb_rgb = getProjectedLightAmbiance( amb_da, dist_atten, lit, nl, noise, proj_tc.xy );
+ amb_rgb = getProjectedLightAmbiance( amb_da, dist_atten, lit, nl, 1.0, proj_tc.xy );
final_color += diffuse.rgb * amb_rgb;
}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl
index 24539c3c3a..bd06a680f5 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;
}
@@ -542,7 +534,7 @@ vec3 tapIrradianceMap(vec3 pos, vec3 dir, out float w, out float dw, vec3 c, int
}
}
-vec3 sampleProbes(vec3 pos, vec3 dir, float lod, bool errorCorrect)
+vec3 sampleProbes(vec3 pos, vec3 dir, float lod)
{
float wsum[2];
wsum[0] = 0;
@@ -568,34 +560,11 @@ vec3 sampleProbes(vec3 pos, vec3 dir, float lod, bool errorCorrect)
float w = 0;
float dw = 0;
- vec3 vi, wi;
vec3 refcol;
{
- if (errorCorrect && refIndex[i].w >= 0)
- { // error correction is on and this probe is a sphere
- //take a sample to get depth value, then error correct
- refcol = tapRefMap(pos, dir, w, dw, vi, wi, abs(lod + 2), refSphere[i].xyz, i);
-
- //adjust lookup by distance result
- float d = length(vi - wi);
- vi += dir * d;
-
- vi -= refSphere[i].xyz;
-
- vi = env_mat * vi;
-
- refcol = textureLod(reflectionProbes, vec4(vi, refIndex[i].x), lod).rgb;
-
- // weight by vector correctness
- vec3 pi = normalize(wi - pos);
- w *= max(dot(pi, dir), 0.1);
- }
- else
- {
- 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;
@@ -684,7 +653,7 @@ vec3 sampleProbeAmbient(vec3 pos, vec3 dir)
}
void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
- vec2 tc, vec3 pos, vec3 norm, float glossiness, bool errorCorrect)
+ vec2 tc, vec3 pos, vec3 norm, float glossiness)
{
// TODO - don't hard code lods
float reflection_lods = max_probe_lod;
@@ -695,13 +664,12 @@ void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
ambenv = sampleProbeAmbient(pos, norm);
float lod = (1.0-glossiness)*reflection_lods;
- glossenv = sampleProbes(pos, normalize(refnormpersp), lod, errorCorrect);
+ glossenv = sampleProbes(pos, normalize(refnormpersp), lod);
#if defined(SSR)
if (cube_snapshot != 1 && glossiness >= 0.9)
{
vec4 ssr = vec4(0);
- //float w = tapScreenSpaceReflection(errorCorrect ? 1 : 4, tc, pos, norm, ssr, sceneMap);
float w = tapScreenSpaceReflection(1, tc, pos, norm, ssr, sceneMap);
glossenv = mix(glossenv, ssr.rgb, w);
@@ -709,6 +677,15 @@ void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
#endif
}
+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)
{
vec3 origin = vec3(0,0,0);
@@ -749,14 +726,6 @@ vec4 sampleReflectionProbesDebug(vec3 pos)
return col;
}
-void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
- vec2 tc, vec3 pos, vec3 norm, float glossiness)
-{
- sampleReflectionProbes(ambenv, glossenv,
- tc, pos, norm, glossiness, false);
-}
-
-
void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv,
vec2 tc, vec3 pos, vec3 norm, float glossiness, float envIntensity)
{
@@ -770,12 +739,12 @@ void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout
if (glossiness > 0.0)
{
float lod = (1.0-glossiness)*reflection_lods;
- glossenv = sampleProbes(pos, normalize(refnormpersp), lod, false);
+ glossenv = sampleProbes(pos, normalize(refnormpersp), lod);
}
if (envIntensity > 0.0)
{
- legacyenv = sampleProbes(pos, normalize(refnormpersp), 0.0, false);
+ legacyenv = sampleProbes(pos, normalize(refnormpersp), 0.0);
}
#if defined(SSR)
diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
index 8d48e6f596..0e3ebd1534 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,28 +181,37 @@ 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))
{
//should only be true of WL sky, just port over base color value
- color = srgb_to_linear(baseColor.rgb);
+ color = srgb_to_linear(texture2D(emissiveRect, tc).rgb);
}
else
{
@@ -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/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl
index 3d8b95b882..33ea2129cf 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl
@@ -51,7 +51,6 @@ uniform sampler2D normalMap;
uniform sampler2D emissiveRect; // PBR linear packed Occlusion, Roughness, Metal. See: pbropaqueF.glsl
uniform samplerCube environmentMap;
uniform sampler2D lightMap;
-uniform sampler2D noiseMap;
uniform sampler2D projectionMap; // rgba
uniform sampler2D lightFunc;
@@ -193,7 +192,6 @@ void main()
diffuse = srgb_to_linear(diffuse);
spec.rgb = srgb_to_linear(spec.rgb);
- float noise = texture2D(noiseMap, tc).b;
if (proj_tc.z > 0.0 &&
proj_tc.x < 1.0 &&
proj_tc.y < 1.0 &&
@@ -205,7 +203,7 @@ void main()
if (nl > 0.0)
{
- lit = nl * dist_atten * noise;
+ lit = nl * dist_atten;
dlit = getProjectedLightDiffuseColor( l_dist, proj_tc.xy );
@@ -214,7 +212,7 @@ void main()
amb_da += (nl*0.5+0.5) /* * (1.0-shadow) */ * proj_ambiance;
}
- vec3 amb_rgb = getProjectedLightAmbiance( amb_da, dist_atten, lit, nl, noise, proj_tc.xy );
+ vec3 amb_rgb = getProjectedLightAmbiance( amb_da, dist_atten, lit, nl, 1.0, proj_tc.xy );
final_color += diffuse.rgb*amb_rgb;
#if DEBUG_LEG_LIGHT_TYPE
final_color = vec3(0,0.5,0);
diff --git a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl
index 631d2c04d0..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;
@@ -122,11 +123,8 @@ vec3 transform_normal(vec3 vNt)
return normalize(vNt.x * vT + vNt.y * vB + vNt.z * vN);
}
-void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
- vec2 tc, vec3 pos, vec3 norm, float glossiness);
-
-void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
- vec2 tc, vec3 pos, vec3 norm, float glossiness, bool errorCorrect);
+void sampleReflectionProbesWater(inout vec3 ambenv, inout vec3 glossenv,
+ vec2 tc, vec3 pos, vec3 norm, float glossiness);
vec3 getPositionWithNDC(vec3 ndc);
@@ -203,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;
@@ -219,16 +219,19 @@ void main()
fb = applyWaterFogViewLinear(refPos, fb, sunlit);
#else
- vec4 fb = applyWaterFogViewLinear(viewVec*2048.0, vec4(0.5), 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.1;
+ float perceptualRoughness = 0.05;
float gloss = 1.0 - perceptualRoughness;
vec3 irradiance = vec3(0);
vec3 radiance = vec3(0);
- sampleReflectionProbes(irradiance, radiance, distort2, pos.xyz, wave_ibl.xyz, gloss);
+ sampleReflectionProbesWater(irradiance, radiance, distort2, pos.xyz, wave_ibl.xyz, gloss);
irradiance = vec3(0);
@@ -250,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);
@@ -265,10 +265,24 @@ void main()
f *= 0.9;
f *= f;
+ // incoming scale is [0, 1] with 0.5 being default
+ // shift to 0.5 to 1.5
+ f *= (fresnelScale - 0.5)+1.0;
+
+ // incoming offset is [0, 1] with 0.5 being default
+ // shift from -1 to 1
+ f += (fresnelOffset - 0.5) * 2.0;
+
f = clamp(f, 0, 1);
- //fb.rgb *= 1.;
-
+
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 af72d48db9..020c7bbc74 100644
--- a/indra/newview/featuretable.txt
+++ b/indra/newview/featuretable.txt
@@ -1,4 +1,4 @@
-version 49
+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
@@ -117,7 +117,7 @@ RenderGlowResolutionPow 1 8
RenderMaxPartCount 1 2048
RenderLocalLights 1 1
RenderTransparentWater 1 0
-RenderReflectionsEnabled 1 0
+RenderReflectionsEnabled 1 1
RenderReflectionProbeDetail 1 0
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 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 afe95c86d9..dbb33b3997 100644
--- a/indra/newview/featuretable_mac.txt
+++ b/indra/newview/featuretable_mac.txt
@@ -1,4 +1,4 @@
-version 44
+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
@@ -71,6 +71,7 @@ RenderGLMultiThreaded 1 0
RenderReflectionsEnabled 1 1
RenderReflectionProbeDetail 1 2
RenderScreenSpaceReflections 1 1
+RenderReflectionProbeCount 1 8
//
// Low Graphics Settings
@@ -94,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
@@ -121,9 +122,9 @@ RenderVolumeLODFactor 1 1.125
RenderDeferredSSAO 1 0
RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
-WLSkyDetail 1 48
+WLSkyDetail 1 96
RenderFSAASamples 1 0
-RenderReflectionsEnabled 1 0
+RenderReflectionsEnabled 1 1
RenderReflectionProbeDetail 1 0
RenderScreenSpaceReflections 1 0
@@ -148,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
@@ -175,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
@@ -202,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
@@ -229,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/llagent.cpp b/indra/newview/llagent.cpp
index 6113c30a84..a68dba98bb 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -3959,8 +3959,6 @@ bool LLAgent::teleportCore(bool is_local)
gTeleportDisplay = TRUE;
LL_INFOS("Teleport") << "Non-local, setting teleport state to TELEPORT_START" << LL_ENDL;
gAgent.setTeleportState( LLAgent::TELEPORT_START );
-
- LLSpatialPartition::sTeleportRequested = TRUE;
}
make_ui_sound("UISndTeleportOut");
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/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp
index 59ed62f995..acbc349567 100644
--- a/indra/newview/lldrawpoolwlsky.cpp
+++ b/indra/newview/lldrawpoolwlsky.cpp
@@ -45,6 +45,8 @@
#include "llvowlsky.h"
#include "llsettingsvo.h"
+extern BOOL gCubeSnapshot;
+
static LLStaticHashedString sCamPosLocal("camPosLocal");
static LLStaticHashedString sCustomAlpha("custom_alpha");
@@ -434,7 +436,10 @@ void LLDrawPoolWLSky::renderDeferred(S32 pass)
{
renderSkyHazeDeferred(origin, camHeightLocal);
renderHeavenlyBodies();
- renderStarsDeferred(origin);
+ if (!gCubeSnapshot)
+ {
+ renderStarsDeferred(origin);
+ }
renderSkyCloudsDeferred(origin, camHeightLocal, cloud_shader);
}
gGL.setColorMask(true, true);
diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp
index d88f0f9847..84ddb3ca99 100644
--- a/indra/newview/llenvironment.cpp
+++ b/indra/newview/llenvironment.cpp
@@ -812,7 +812,7 @@ const F64Seconds LLEnvironment::TRANSITION_SLOW(10.0f);
const F64Seconds LLEnvironment::TRANSITION_ALTITUDE(5.0f);
const LLUUID LLEnvironment::KNOWN_SKY_SUNRISE("01e41537-ff51-2f1f-8ef7-17e4df760bfb");
-const LLUUID LLEnvironment::KNOWN_SKY_MIDDAY("6c83e853-e7f8-cad7-8ee6-5f31c453721c");
+const LLUUID LLEnvironment::KNOWN_SKY_MIDDAY("e4391f43-74d6-d889-19fb-99a4a3ad6c5c");
const LLUUID LLEnvironment::KNOWN_SKY_SUNSET("084e26cd-a900-28e8-08d0-64a9de5c15e2");
const LLUUID LLEnvironment::KNOWN_SKY_MIDNIGHT("8a01b97a-cb20-c1ea-ac63-f7ea84ad0090");
@@ -1758,7 +1758,11 @@ void LLEnvironment::updateGLVariablesForSettings(LLShaderUniforms* uniforms, con
{ // maximize and remove tinting if this is an irradiance map render pass and the parameter feeds into the sky background color
auto max_vec = [](LLVector4 col)
{
- col.mV[0] = col.mV[1] = col.mV[2] = llmax(llmax(col.mV[0], col.mV[1]), col.mV[2]);
+ LLColor3 color(col);
+ F32 h, s, l;
+ color.calcHSL(&h, &s, &l);
+
+ col.mV[0] = col.mV[1] = col.mV[2] = l;
return col;
};
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index 87abb06285..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)
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/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp
index 3b1bee05af..81a7aa47c8 100644
--- a/indra/newview/llfeaturemanager.cpp
+++ b/indra/newview/llfeaturemanager.cpp
@@ -425,18 +425,14 @@ bool LLFeatureManager::loadGPUClass()
}
if (gbps < 0.f)
- { //couldn't bench, use GLVersion
+ { //couldn't bench, default to Low
#if LL_DARWIN
//GLVersion is misleading on OSX, just default to class 3 if we can't bench
LL_WARNS("RenderInit") << "Unable to get an accurate benchmark; defaulting to class 3" << LL_ENDL;
mGPUClass = GPU_CLASS_3;
#else
- mGPUClass = GPU_CLASS_2;
- #endif
- }
- else if (gbps <= 5.f)
- {
mGPUClass = GPU_CLASS_0;
+ #endif
}
else if (gbps <= 8.f)
{
diff --git a/indra/newview/llfetchedgltfmaterial.cpp b/indra/newview/llfetchedgltfmaterial.cpp
index 2f2c58aa3a..2e71b4fa87 100644
--- a/indra/newview/llfetchedgltfmaterial.cpp
+++ b/indra/newview/llfetchedgltfmaterial.cpp
@@ -46,6 +46,18 @@ LLFetchedGLTFMaterial::~LLFetchedGLTFMaterial()
}
+LLFetchedGLTFMaterial& LLFetchedGLTFMaterial::operator=(const LLFetchedGLTFMaterial& rhs)
+{
+ LLGLTFMaterial::operator =(rhs);
+
+ mBaseColorTexture = rhs.mBaseColorTexture;
+ mNormalTexture = rhs.mNormalTexture;
+ mMetallicRoughnessTexture = rhs.mMetallicRoughnessTexture;
+ mEmissiveTexture = rhs.mEmissiveTexture;
+
+ return *this;
+}
+
void LLFetchedGLTFMaterial::bind(LLViewerTexture* media_tex)
{
// glTF 2.0 Specification 3.9.4. Alpha Coverage
@@ -110,21 +122,21 @@ void LLFetchedGLTFMaterial::bind(LLViewerTexture* media_tex)
shader->uniform1f(LLShaderMgr::METALLIC_FACTOR, mMetallicFactor);
shader->uniform3fv(LLShaderMgr::EMISSIVE_COLOR, 1, mEmissiveColor.mV);
- shader->uniform2fv(LLShaderMgr::TEXTURE_BASE_COLOR_SCALE, 1, (F32*)mTextureTransform[GLTF_TEXTURE_INFO_BASE_COLOR].mScale.mV);
- shader->uniform1f(LLShaderMgr::TEXTURE_BASE_COLOR_ROTATION, mTextureTransform[GLTF_TEXTURE_INFO_BASE_COLOR].mRotation);
- shader->uniform2fv(LLShaderMgr::TEXTURE_BASE_COLOR_OFFSET, 1, (F32*)mTextureTransform[GLTF_TEXTURE_INFO_BASE_COLOR].mOffset.mV);
+ F32 base_color_packed[8];
+ mTextureTransform[GLTF_TEXTURE_INFO_BASE_COLOR].getPacked(base_color_packed);
+ shader->uniform4fv(LLShaderMgr::TEXTURE_BASE_COLOR_TRANSFORM, 2, (F32*)base_color_packed);
- shader->uniform2fv(LLShaderMgr::TEXTURE_NORMAL_SCALE, 1, (F32*)mTextureTransform[GLTF_TEXTURE_INFO_NORMAL].mScale.mV);
- shader->uniform1f(LLShaderMgr::TEXTURE_NORMAL_ROTATION, mTextureTransform[GLTF_TEXTURE_INFO_NORMAL].mRotation);
- shader->uniform2fv(LLShaderMgr::TEXTURE_NORMAL_OFFSET, 1, (F32*)mTextureTransform[GLTF_TEXTURE_INFO_NORMAL].mOffset.mV);
+ F32 normal_packed[8];
+ mTextureTransform[GLTF_TEXTURE_INFO_NORMAL].getPacked(normal_packed);
+ shader->uniform4fv(LLShaderMgr::TEXTURE_NORMAL_TRANSFORM, 2, (F32*)normal_packed);
- shader->uniform2fv(LLShaderMgr::TEXTURE_METALLIC_ROUGHNESS_SCALE, 1, (F32*)mTextureTransform[GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS].mScale.mV);
- shader->uniform1f(LLShaderMgr::TEXTURE_METALLIC_ROUGHNESS_ROTATION, mTextureTransform[GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS].mRotation);
- shader->uniform2fv(LLShaderMgr::TEXTURE_METALLIC_ROUGHNESS_OFFSET, 1, (F32*)mTextureTransform[GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS].mOffset.mV);
+ F32 metallic_roughness_packed[8];
+ mTextureTransform[GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS].getPacked(metallic_roughness_packed);
+ shader->uniform4fv(LLShaderMgr::TEXTURE_METALLIC_ROUGHNESS_TRANSFORM, 2, (F32*)metallic_roughness_packed);
- shader->uniform2fv(LLShaderMgr::TEXTURE_EMISSIVE_SCALE, 1, (F32*)mTextureTransform[GLTF_TEXTURE_INFO_EMISSIVE].mScale.mV);
- shader->uniform1f(LLShaderMgr::TEXTURE_EMISSIVE_ROTATION, mTextureTransform[GLTF_TEXTURE_INFO_EMISSIVE].mRotation);
- shader->uniform2fv(LLShaderMgr::TEXTURE_EMISSIVE_OFFSET, 1, (F32*)mTextureTransform[GLTF_TEXTURE_INFO_EMISSIVE].mOffset.mV);
+ F32 emissive_packed[8];
+ mTextureTransform[GLTF_TEXTURE_INFO_EMISSIVE].getPacked(emissive_packed);
+ shader->uniform4fv(LLShaderMgr::TEXTURE_EMISSIVE_TRANSFORM, 2, (F32*)emissive_packed);
}
}
diff --git a/indra/newview/llfetchedgltfmaterial.h b/indra/newview/llfetchedgltfmaterial.h
index 96f7fbea8e..1668657281 100644
--- a/indra/newview/llfetchedgltfmaterial.h
+++ b/indra/newview/llfetchedgltfmaterial.h
@@ -39,6 +39,8 @@ public:
LLFetchedGLTFMaterial();
virtual ~LLFetchedGLTFMaterial();
+ LLFetchedGLTFMaterial& operator=(const LLFetchedGLTFMaterial& rhs);
+
// If this material is loaded, fire the given function
void onMaterialComplete(std::function<void()> material_complete);
@@ -46,6 +48,8 @@ public:
// media_tex - optional media texture that may override the base color texture
void bind(LLViewerTexture* media_tex = nullptr);
+ bool isFetching() const { return mFetching; }
+
// Textures used for fetching/rendering
LLPointer<LLViewerFetchedTexture> mBaseColorTexture;
LLPointer<LLViewerFetchedTexture> mNormalTexture;
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/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp
index 4051521ad4..678ec7e46b 100644
--- a/indra/newview/llgltfmateriallist.cpp
+++ b/indra/newview/llgltfmateriallist.cpp
@@ -157,8 +157,8 @@ public:
// receive override data from simulator via LargeGenericMessage
// message should have:
// object_id - UUID of LLViewerObject
- // side - S32 index of texture entry
- // gltf_json - String of GLTF json for override data
+ // sides - array of S32 indices of texture entries
+ // gltf_json - array of corresponding Strings of GLTF json for override data
LLSD message;
@@ -376,15 +376,33 @@ void LLGLTFMaterialList::applyQueuedOverrides(LLViewerObject* obj)
{
if (overrides[i].notNull())
{
- if (!obj->getTE(i) || !obj->getTE(i)->getGLTFMaterial())
- { // object doesn't have its base GLTF material yet, don't apply override (yet)
+ if (!obj->getTE(i))
+ { // object is incomplete
return;
}
- obj->setTEGLTFMaterialOverride(i, overrides[i]);
+
+ if (!obj->getTE(i)->getGLTFMaterial())
+ {
+ // doesn't have its base GLTF material yet, don't apply override(yet)
+ return;
+ }
+
+ S32 status = obj->setTEGLTFMaterialOverride(i, overrides[i]);
+ if (status == TEM_CHANGE_NONE)
+ {
+ // can't apply this yet, since failure to change the material override
+ // probably means the base material is still being fetched. leave in
+ // the queue for later
+ //obj->setDebugText("early out 3");
+ return;
+ }
+
if (obj->getTE(i)->isSelected())
{
handle_gltf_override_message.doSelectionCallbacks(id, i);
}
+ // success!
+ overrides[i] = nullptr;
}
}
diff --git a/indra/newview/lllocalgltfmaterials.cpp b/indra/newview/lllocalgltfmaterials.cpp
index a9099b1ce9..d464ea0571 100644
--- a/indra/newview/lllocalgltfmaterials.cpp
+++ b/indra/newview/lllocalgltfmaterials.cpp
@@ -45,6 +45,7 @@
#include "llmaterialmgr.h"
#include "llnotificationsutil.h"
#include "llscrolllistctrl.h"
+#include "lltextureentry.h"
#include "lltinygltfhelper.h"
#include "llviewertexture.h"
@@ -118,6 +119,15 @@ S32 LLLocalGLTFMaterial::getIndexInFile() const
return mMaterialIndex;
}
+void LLLocalGLTFMaterial::addTextureEntry(LLTextureEntry* te)
+{
+ mTextureEntires.insert(te);
+}
+void LLLocalGLTFMaterial::removeTextureEntry(LLTextureEntry* te)
+{
+ mTextureEntires.erase(te);
+}
+
/* update functions */
bool LLLocalGLTFMaterial::updateSelf()
{
@@ -154,6 +164,27 @@ bool LLLocalGLTFMaterial::updateSelf()
gGLTFMaterialList.addMaterial(mWorldID, this);
mUpdateRetries = LL_LOCAL_UPDATE_RETRIES;
+
+ for (LLTextureEntry* entry : mTextureEntires)
+ {
+ // Normally a change in applied material id is supposed to
+ // drop overrides thus reset material, but local materials
+ // currently reuse their existing asset id, and purpose is
+ // to preview how material will work in-world, overrides
+ // included, so do an override to render update instead.
+ LLGLTFMaterial* override_mat = entry->getGLTFMaterialOverride();
+ if (override_mat)
+ {
+ // do not create a new material, reuse existing pointer
+ LLFetchedGLTFMaterial* render_mat = (LLFetchedGLTFMaterial*)entry->getGLTFRenderMaterial();
+ if (render_mat)
+ {
+ *render_mat = *this;
+ render_mat->applyOverride(*override_mat);
+ }
+ }
+ }
+
updated = true;
}
@@ -214,12 +245,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 +345,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/lllocalgltfmaterials.h b/indra/newview/lllocalgltfmaterials.h
index 6919b9b4b2..1442b83a40 100644
--- a/indra/newview/lllocalgltfmaterials.h
+++ b/indra/newview/lllocalgltfmaterials.h
@@ -34,6 +34,7 @@
class LLScrollListCtrl;
class LLGLTFMaterial;
class LLViewerObject;
+class LLTextureEntry;
class LLLocalGLTFMaterial : public LLFetchedGLTFMaterial
{
@@ -48,6 +49,9 @@ public: /* accessors */
LLUUID getWorldID() const;
S32 getIndexInFile() const;
+ void addTextureEntry(LLTextureEntry* te) override;
+ void removeTextureEntry(LLTextureEntry* te) override;
+
public:
bool updateSelf();
@@ -77,6 +81,7 @@ private: /* members */
ELinkStatus mLinkStatus;
S32 mUpdateRetries;
S32 mMaterialIndex; // Single file can have more than one
+ std::set<LLTextureEntry*> mTextureEntires;
};
class LLLocalGLTFMaterialTimer : public LLEventTimer
diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp
index 64ce5fd4d2..609d8ea5d7 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,16 @@ 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);
+
+ if (getDoubleSided())
+ {
+ // SL-19392 Double sided materials double the number of pixels that must be rasterized,
+ // and a great many tools that export GLTF simply leave double sided enabled whether
+ // or not it is necessary.
+ LL_DEBUGS("MaterialEditor") << "Defaulting Double Sided to disabled on import" << LL_ENDL;
+ setDoubleSided(false);
+ }
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/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp
index 3c34d6ee65..ed244f773c 100644
--- a/indra/newview/llpanelvolume.cpp
+++ b/indra/newview/llpanelvolume.cpp
@@ -749,29 +749,49 @@ void LLPanelVolume::sendIsReflectionProbe()
BOOL value = getChild<LLUICtrl>("Reflection Probe")->getValue();
BOOL old_value = volobjp->isReflectionProbe();
- volobjp->setIsReflectionProbe(value);
- LL_INFOS() << "update reflection probe sent" << LL_ENDL;
+ if (value && value != old_value)
+ { // defer to notification util as to whether or not we *really* make this object a reflection probe
+ LLNotificationsUtil::add("ReflectionProbeApplied", LLSD(), LLSD(), boost::bind(&LLPanelVolume::doSendIsReflectionProbe, this, _1, _2));
+ }
+ else
+ {
+ volobjp->setIsReflectionProbe(value);
+ }
+}
- if (value && !old_value)
- { // has become a reflection probe, slam to a 10m sphere and pop up a message
- // warning people about the pitfalls of reflection probes
-#if 0
- auto* select_mgr = LLSelectMgr::getInstance();
+void LLPanelVolume::doSendIsReflectionProbe(const LLSD & notification, const LLSD & response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (option == 0) // YES
+ {
+ LLViewerObject* objectp = mObject;
+ if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME))
+ {
+ return;
+ }
+ LLVOVolume* volobjp = (LLVOVolume*)objectp;
- mObject->setScale(LLVector3(10.f, 10.f, 10.f));
- select_mgr->sendMultipleUpdate(UPD_ROTATION | UPD_POSITION | UPD_SCALE);
+ volobjp->setIsReflectionProbe(true);
- select_mgr->selectionUpdatePhantom(true);
- select_mgr->selectionSetGLTFMaterial(LLUUID::null);
- select_mgr->selectionSetAlphaOnly(0.f);
-
- LLVolumeParams params;
- params.getPathParams().setCurveType(LL_PCODE_PATH_CIRCLE);
- params.getProfileParams().setCurveType(LL_PCODE_PROFILE_CIRCLE_HALF);
- mObject->updateVolume(params);
-#endif
+ { // has become a reflection probe, slam to a 10m sphere and pop up a message
+ // warning people about the pitfalls of reflection probes
+
+ auto* select_mgr = LLSelectMgr::getInstance();
- LLNotificationsUtil::add("ReflectionProbeApplied");
+ select_mgr->selectionUpdatePhantom(true);
+ select_mgr->selectionSetGLTFMaterial(LLUUID::null);
+ select_mgr->selectionSetAlphaOnly(0.f);
+
+ LLVolumeParams params;
+ params.getPathParams().setCurveType(LL_PCODE_PATH_CIRCLE);
+ params.getProfileParams().setCurveType(LL_PCODE_PROFILE_CIRCLE_HALF);
+ mObject->updateVolume(params);
+ }
+ }
+ else
+ {
+ // cancelled, touch up UI state
+ getChild<LLUICtrl>("Reflection Probe")->setValue(false);
}
}
diff --git a/indra/newview/llpanelvolume.h b/indra/newview/llpanelvolume.h
index 62a6d01b21..01b7ebb75c 100644
--- a/indra/newview/llpanelvolume.h
+++ b/indra/newview/llpanelvolume.h
@@ -57,7 +57,14 @@ public:
void refresh();
void sendIsLight();
+
+ // when an object is becoming a refleciton probe, present a dialog asking for confirmation
+ // otherwise, send the reflection probe update immediately
void sendIsReflectionProbe();
+
+ // callback for handling response of the ok/cancel/ignore dialog for making an object a reflection probe
+ void doSendIsReflectionProbe(const LLSD& notification, const LLSD& response);
+
void sendIsFlexible();
static bool precommitValidate(const LLSD& data);
diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp
index acb3612416..58ce571505 100644
--- a/indra/newview/llreflectionmapmanager.cpp
+++ b/indra/newview/llreflectionmapmanager.cpp
@@ -94,7 +94,7 @@ void LLReflectionMapManager::update()
if (!mRenderTarget.isComplete())
{
- U32 color_fmt = GL_RGB16;
+ U32 color_fmt = GL_RGB16F;
U32 targetRes = mProbeResolution * 4; // super sample
mRenderTarget.allocate(targetRes, targetRes, color_fmt, true);
}
@@ -107,7 +107,7 @@ void LLReflectionMapManager::update()
mMipChain.resize(count);
for (int i = 0; i < count; ++i)
{
- mMipChain[i].allocate(res, res, GL_RGBA16);
+ mMipChain[i].allocate(res, res, GL_RGB16F);
res /= 2;
}
}
@@ -475,7 +475,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)
//only render sky, water, terrain, and clouds
gPipeline.andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY, LLPipeline::RENDER_TYPE_WL_SKY,
- LLPipeline::RENDER_TYPE_WATER, LLPipeline::RENDER_TYPE_CLOUDS, LLPipeline::RENDER_TYPE_TERRAIN, LLPipeline::END_RENDER_TYPES);
+ LLPipeline::RENDER_TYPE_WATER, LLPipeline::RENDER_TYPE_VOIDWATER, LLPipeline::RENDER_TYPE_CLOUDS, LLPipeline::RENDER_TYPE_TERRAIN, LLPipeline::END_RENDER_TYPES);
probe->update(mRenderTarget.getWidth(), face);
@@ -519,7 +519,6 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)
static LLStaticHashedString zfar("zfar");
LLRenderTarget* screen_rt = &gPipeline.mAuxillaryRT.screen;
- LLRenderTarget* depth_rt = &gPipeline.mAuxillaryRT.deferredScreen;
// perform a gaussian blur on the super sampled render before downsampling
{
@@ -549,7 +548,6 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)
gReflectionMipProgram.bind();
S32 diffuseChannel = gReflectionMipProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_TEXTURE);
- S32 depthChannel = gReflectionMipProgram.enableTexture(LLShaderMgr::DEFERRED_DEPTH, LLTexUnit::TT_TEXTURE);
for (int i = 0; i < mMipChain.size(); ++i)
{
@@ -564,12 +562,9 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)
gGL.getTexUnit(diffuseChannel)->bind(&(mMipChain[i - 1]));
}
- gGL.getTexUnit(depthChannel)->bind(depth_rt, true);
-
+
gReflectionMipProgram.uniform1f(resScale, 1.f/(mProbeResolution*2));
- gReflectionMipProgram.uniform1f(znear, probe->getNearClip());
- gReflectionMipProgram.uniform1f(zfar, MAX_FAR_CLIP);
-
+
gPipeline.mScreenTriangleVB->setBuffer();
gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
@@ -597,7 +592,6 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)
gGL.popMatrix();
gGL.getTexUnit(diffuseChannel)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(depthChannel)->unbind(LLTexUnit::TT_TEXTURE);
gReflectionMipProgram.unbind();
}
@@ -820,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)
@@ -858,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
{
@@ -1021,10 +1015,10 @@ void LLReflectionMapManager::initReflectionMaps()
mTexture = new LLCubeMapArray();
// store mReflectionProbeCount+2 cube maps, final two cube maps are used for render target and radiance map generation source)
- mTexture->allocate(mProbeResolution, 4, mReflectionProbeCount + 2);
+ mTexture->allocate(mProbeResolution, 3, mReflectionProbeCount + 2);
mIrradianceMaps = new LLCubeMapArray();
- mIrradianceMaps->allocate(LL_IRRADIANCE_MAP_RESOLUTION, 4, mReflectionProbeCount, FALSE);
+ mIrradianceMaps->allocate(LL_IRRADIANCE_MAP_RESOLUTION, 3, mReflectionProbeCount, FALSE);
}
if (mVertexBuffer.isNull())
@@ -1082,7 +1076,7 @@ void LLReflectionMapManager::doOcclusion()
for (auto& probe : mProbes)
{
- if (probe != nullptr)
+ if (probe != nullptr && probe != mDefaultProbe)
{
probe->doOcclusion(eye);
}
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..fc9b3093e8 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -64,8 +64,6 @@ bool LLSpatialGroup::sNoDelete = false;
static F32 sLastMaxTexPriority = 1.f;
static F32 sCurMaxTexPriority = 1.f;
-bool LLSpatialPartition::sTeleportRequested = false;
-
//static counter for frame to switch LOD on
void sg_assert(BOOL expr)
@@ -1295,8 +1293,6 @@ void drawBoxOutline(const LLVector4a& pos, const LLVector4a& size)
class LLOctreeDirty : public OctreeTraveler
{
public:
- LLOctreeDirty(bool no_rebuild) : mNoRebuild(no_rebuild){}
-
virtual void visit(const OctreeNode* state)
{
LLSpatialGroup* group = (LLSpatialGroup*) state->getListener(0);
@@ -1309,7 +1305,7 @@ public:
{
continue;
}
- if (!mNoRebuild && drawable->getVObj().notNull() && !group->getSpatialPartition()->mRenderByGroup)
+ if (drawable->getVObj().notNull() && !group->getSpatialPartition()->mRenderByGroup)
{
gPipeline.markRebuild(drawable, LLDrawable::REBUILD_ALL, TRUE);
}
@@ -1321,9 +1317,6 @@ public:
traverse(bridge->mOctree);
}
}
-
-private:
- BOOL mNoRebuild;
};
void LLSpatialPartition::restoreGL()
@@ -1332,7 +1325,7 @@ void LLSpatialPartition::restoreGL()
void LLSpatialPartition::resetVertexBuffers()
{
- LLOctreeDirty dirty(sTeleportRequested);
+ LLOctreeDirty dirty;
dirty.traverse(mOctree);
}
@@ -3095,6 +3088,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 +3230,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 +3566,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 9b2cb0d44c..053ce9e60b 100644
--- a/indra/newview/llspatialpartition.h
+++ b/indra/newview/llspatialpartition.h
@@ -433,8 +433,6 @@ public:
U32 mVertexDataMask;
F32 mSlopRatio; //percentage distance must change before drawables receive LOD update (default is 0.25);
bool mDepthMask; //if TRUE, objects in this partition will be written to depth during alpha rendering
-
- static bool sTeleportRequested; //started to issue a teleport request
};
// class for creating bridges between spatial partitions
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..cc7e716bb5 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();
@@ -4961,6 +4961,18 @@ void LLViewerObject::updateTEMaterialTextures(U8 te)
if (mat == nullptr && mat_id.notNull())
{
mat = (LLFetchedGLTFMaterial*) gGLTFMaterialList.getMaterial(mat_id);
+ if (mat->isFetching())
+ { // material is not loaded yet, rebuild draw info when the object finishes loading
+ LLUUID id = getID();
+ mat->onMaterialComplete([=]
+ {
+ LLViewerObject* obj = gObjectList.findObject(id);
+ if (obj)
+ {
+ obj->markForUpdate(FALSE);
+ }
+ });
+ }
getTE(te)->setGLTFMaterial(mat);
}
else if (mat_id.isNull() && mat != nullptr)
@@ -4982,7 +4994,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 +5152,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);
}
@@ -5368,24 +5380,30 @@ S32 LLViewerObject::setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* override_ma
LLFetchedGLTFMaterial* src_mat = (LLFetchedGLTFMaterial*) tep->getGLTFMaterial();
+ // if override mat exists, we must also have a source mat
if (!src_mat)
- { // we can get into this state if an override has arrived before the viewer has
+ {
+ // we can get into this state if an override has arrived before the viewer has
// received or handled an update, return TEM_CHANGE_NONE to signal to LLGLTFMaterialList that it
// should queue the update for later
return retval;
}
- tep->setGLTFMaterialOverride(override_mat);
+ if(src_mat->isFetching())
+ {
+ // if still fetching, we need to wait until it is done and try again
+ return retval;
+ }
- // if override mat exists, we must also have a source mat
- llassert(override_mat ? bool(src_mat) : true);
+ tep->setGLTFMaterialOverride(override_mat);
- if (override_mat && src_mat)
+ if (override_mat)
{
LLFetchedGLTFMaterial* render_mat = new LLFetchedGLTFMaterial(*src_mat);
render_mat->applyOverride(*override_mat);
tep->setGLTFRenderMaterial(render_mat);
retval = TEM_CHANGE_TEXTURE;
+
}
else if (tep->setGLTFRenderMaterial(nullptr))
{
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/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index e3ac1767fb..4663129d35 100755
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -785,7 +785,7 @@ void LLViewerRegion::loadObjectCache()
if(LLVOCache::instanceExists())
{
LLVOCache & vocache = LLVOCache::instance();
- vocache.readFromCache(mHandle, mImpl->mCacheID, mImpl->mCacheMap) ;
+ vocache.readFromCache(mHandle, mImpl->mCacheID, mImpl->mCacheMap);
vocache.readGenericExtrasFromCache(mHandle, mImpl->mCacheID, mImpl->mGLTFOverridesJson);
if (mImpl->mCacheMap.empty())
@@ -814,7 +814,8 @@ void LLViewerRegion::saveObjectCache()
bool removal_enabled = sVOCacheCullingEnabled && (mRegionTimer.getElapsedTimeF32() > start_time_threshold); //allow to remove invalid objects from object cache file.
LLVOCache & instance = LLVOCache::instance();
- instance.writeToCache(mHandle, mImpl->mCacheID, mImpl->mCacheMap, mCacheDirty, removal_enabled) ;
+
+ instance.writeToCache(mHandle, mImpl->mCacheID, mImpl->mCacheMap, mCacheDirty, removal_enabled);
instance.writeGenericExtrasToCache(mHandle, mImpl->mCacheID, mImpl->mGLTFOverridesJson, mCacheDirty, removal_enabled);
mCacheDirty = FALSE;
}
@@ -822,6 +823,7 @@ void LLViewerRegion::saveObjectCache()
// Map of LLVOCacheEntry takes time to release, store map for cleanup on idle
sRegionCacheCleanup.insert(mImpl->mCacheMap.begin(), mImpl->mCacheMap.end());
mImpl->mCacheMap.clear();
+ // TODO - probably need to do the same for overrides cache
}
void LLViewerRegion::sendMessage()
@@ -1860,6 +1862,9 @@ LLViewerObject* LLViewerRegion::addNewObject(LLVOCacheEntry* entry)
//should not hit here any more, but does not hurt either, just put it back to active list
addActiveCacheEntry(entry);
}
+
+ loadCacheMiscExtras(entry->getLocalID(), entry, entry->getCRC());
+
return obj;
}
@@ -2646,6 +2651,8 @@ void LLViewerRegion::cacheFullUpdateGLTFOverride(const LLGLTFOverrideCacheEntry
LLViewerObject * obj = gObjectList.findObject(object_id);
if (obj != nullptr)
{
+ llassert(obj->getRegion() == this);
+
U32 local_id = obj->getLocalID();
mImpl->mGLTFOverridesJson[local_id] = override_data;
@@ -2755,7 +2762,7 @@ bool LLViewerRegion::probeCache(U32 local_id, U32 crc, U32 flags, U8 &cache_miss
entry->setValid();
decodeBoundingInfo(entry);
- loadCacheMiscExtras(local_id, entry, crc);
+ //loadCacheMiscExtras(local_id, entry, crc);
return true;
}
@@ -3547,4 +3554,8 @@ void LLViewerRegion::loadCacheMiscExtras(U32 local_id, LLVOCacheEntry * entry, U
{
LLGLTFMaterialList::loadCacheOverrides(iter->second);
}
+ else
+ {
+ LL_DEBUGS("GLTF") << "cache miss for handle: " << mHandle << " local_id:" << local_id << LL_ENDL;
+ }
}
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/llvocache.cpp b/indra/newview/llvocache.cpp
index cb75426cce..0fbcf9c624 100644
--- a/indra/newview/llvocache.cpp
+++ b/indra/newview/llvocache.cpp
@@ -26,15 +26,13 @@
#include "llviewerprecompiledheaders.h"
#include "llvocache.h"
-#include "llerror.h"
#include "llregionhandle.h"
#include "llviewercontrol.h"
#include "llviewerobjectlist.h"
#include "lldrawable.h"
#include "llviewerregion.h"
-#include "pipeline.h"
#include "llagentcamera.h"
-#include "llmemory.h"
+#include "llsdserialize.h"
//static variables
U32 LLVOCacheEntry::sMinFrameRange = 0;
@@ -65,12 +63,12 @@ bool LLGLTFOverrideCacheEntry::fromLLSD(const LLSD& data)
return false;
}
- if (data.has("region_handle_low") && data.has("region_handle_high"))
+ if (data.has("region_handle_x") && data.has("region_handle_y"))
{
// TODO start requiring this once server sends this for all messages
- U64 region_handle_low = data["region_handle_low"].asInteger();
- U64 region_handle_high = data["region_handle_high"].asInteger();
- mRegionHandle = (region_handle_low & 0x00000000ffffffffUL) || (region_handle_high << 32);
+ U32 region_handle_y = data["region_handle_y"].asInteger();
+ U32 region_handle_x = data["region_handle_x"].asInteger();
+ mRegionHandle = to_region_handle(region_handle_x, region_handle_y);
mHasRegionHandle = true;
}
else
@@ -99,29 +97,31 @@ bool LLGLTFOverrideCacheEntry::fromLLSD(const LLSD& data)
mSides[side_idx] = gltf_json[i].asString();
}
}
+ else
+ {
+ LL_WARNS_IF(sides.size() != 0, "GLTF") << "broken override cache entry" << LL_ENDL;
+ }
}
return true;
}
-LLSD LLGLTFOverrideCacheEntry::toLLSD()
+LLSD LLGLTFOverrideCacheEntry::toLLSD() const
{
- llassert(false); // "Function not tested!!!
-
LLSD data;
if (mHasRegionHandle)
{
- data["region_handle_low"] = LLSD::Integer(mRegionHandle & 0x00000000ffffffffUL);
- data["region_handle_high"] = LLSD::Integer(mRegionHandle >> 32);
+ U32 region_handle_x, region_handle_y;
+ from_region_handle(mRegionHandle, &region_handle_x, &region_handle_y);
+ data["region_handle_y"] = LLSD::Integer(region_handle_y);
+ data["region_handle_x"] = LLSD::Integer(region_handle_x);
}
data["object_id"] = mObjectId;
- std::map<S32, std::string>::const_iterator iter = mSides.begin();
- std::map<S32, std::string>::const_iterator end = mSides.end();
- while (iter != end)
+ for (auto const & side : mSides)
{
- data["sides"].append(LLSD::Integer(iter->first));
- data["sides"].append(iter->second);
+ data["sides"].append(LLSD::Integer(side.first));
+ data["gltf_json"].append(side.second);
}
return data;
@@ -425,6 +425,7 @@ S32 LLVOCacheEntry::writeToBuffer(U8 *data_buffer) const
return ENTRY_HEADER_SIZE + size;
}
+#ifndef LL_TEST
//static
void LLVOCacheEntry::updateDebugSettings()
{
@@ -477,6 +478,7 @@ void LLVOCacheEntry::updateDebugSettings()
const U32 clamped_frames = inv_obj_time ? llclamp((U32) inv_obj_time, MIN_FRAMES, MAX_FRAMES) : MAX_FRAMES; // [10, 64], with zero => 64
sMinFrameRange = MIN_FRAMES + ((clamped_frames - MIN_FRAMES) * adjust_factor);
}
+#endif // LL_TEST
//static
F32 LLVOCacheEntry::getSquaredPixelThreshold(bool is_front)
@@ -948,6 +950,7 @@ void LLVOCachePartition::selectBackObjects(LLCamera &camera, F32 pixel_threshold
return;
}
+#ifndef LL_TEST
S32 LLVOCachePartition::cull(LLCamera &camera, bool do_occlusion)
{
static LLCachedControl<bool> use_object_cache_occlusion(gSavedSettings,"UseObjectCacheOcclusion");
@@ -1014,6 +1017,7 @@ S32 LLVOCachePartition::cull(LLCamera &camera, bool do_occlusion)
}
return 1;
}
+#endif // LL_TEST
void LLVOCachePartition::setCullHistory(BOOL has_new_object)
{
@@ -1087,8 +1091,9 @@ void LLVOCachePartition::removeOccluder(LLVOCacheGroup* group)
//-------------------------------------------------------------------
//LLVOCache
//-------------------------------------------------------------------
-// Format string used to construct filename for the object cache
+// Format strings used to construct filename for the object cache
static const char OBJECT_CACHE_FILENAME[] = "objects_%d_%d.slc";
+static const char OBJECT_CACHE_EXTRAS_FILENAME[] = "objects_%d_%d_extras.slec";
const U32 MAX_NUM_OBJECT_ENTRIES = 128 ;
const U32 MIN_ENTRIES_TO_PURGE = 16 ;
@@ -1101,9 +1106,12 @@ LLVOCache::LLVOCache(bool read_only) :
mInitialized(false),
mReadOnly(read_only),
mNumEntries(0),
- mCacheSize(1)
+ mCacheSize(1),
+ mEnabled(true)
{
+#ifndef LL_TEST
mEnabled = gSavedSettings.getBOOL("ObjectCacheEnabled");
+#endif
mLocalAPRFilePoolp = new LLVolatileAPRPool() ;
}
@@ -1280,6 +1288,15 @@ void LLVOCache::getObjectCacheFilename(U64 handle, std::string& filename)
return ;
}
+std::string LLVOCache::getObjectCacheExtrasFilename(U64 handle)
+{
+ U32 region_x, region_y;
+
+ grid_from_region_handle(handle, &region_x, &region_y);
+ return gDirUtilp->getExpandedFilename(LL_PATH_CACHE, object_cache_dirname,
+ llformat(OBJECT_CACHE_EXTRAS_FILENAME, region_x, region_y));
+}
+
void LLVOCache::removeFromCache(HeaderEntryInfo* entry)
{
if(mReadOnly)
@@ -1507,7 +1524,78 @@ void LLVOCache::readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::voca
void LLVOCache::readGenericExtrasFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::vocache_gltf_overrides_map_t& cache_extras_entry_map)
{
- LL_DEBUGS() << "TODO" << LL_ENDL;
+ if(!mEnabled)
+ {
+ LL_WARNS() << "Not reading cache for handle " << handle << "): Cache is currently disabled." << LL_ENDL;
+ return ;
+ }
+ llassert_always(mInitialized);
+
+ handle_entry_map_t::iterator iter = mHandleEntryMap.find(handle) ;
+ if(iter == mHandleEntryMap.end()) //no cache
+ {
+ LL_WARNS() << "No handle map entry for " << handle << LL_ENDL;
+ return;
+ }
+
+ std::string filename(getObjectCacheExtrasFilename(handle));
+ llifstream in(filename, std::ios::in | std::ios::binary);
+
+ std::string line;
+ std::getline(in, line);
+ if(!in.good()) {
+ LL_WARNS() << "Failed reading extras cache for handle " << handle << LL_ENDL;
+ return;
+ }
+
+ if(!LLUUID::validate(line))
+ {
+ LL_WARNS() << "Failed reading extras cache for handle" << handle << ". invalid uuid line: '" << line << "'" << LL_ENDL;
+ return;
+ }
+
+ LLUUID cache_id(line);
+ if(cache_id != id)
+ {
+ LL_INFOS() << "Cache ID doesn't match for this region, discarding" << LL_ENDL;
+ return;
+ }
+
+ U32 num_entries; // if removal was enabled during write num_entries might be wrong
+ std::getline(in, line);
+ if(!in.good()) {
+ LL_WARNS() << "Failed reading extras cache for handle " << handle << LL_ENDL;
+ return;
+ }
+ try {
+ num_entries = std::stol(line);
+ }
+ catch(std::logic_error&) // either invalid_argument or out_of_range
+ {
+ LL_WARNS() << "Failed reading extras cache for handle " << handle << ". unreadable num_entries" << LL_ENDL;
+ return;
+ }
+
+ LL_DEBUGS("GLTF") << "Beginning reading extras cache for handle " << handle << ", " << num_entries << " entries" << LL_ENDL;
+
+ LLSD entry_llsd;
+ for (U32 i = 0; i < num_entries && !in.eof(); i++)
+ {
+ static const U32 max_size = 4096;
+ bool success = LLSDSerialize::deserialize(entry_llsd, in, max_size);
+ // check bool(in) this time since eof is not a failure condition here
+ if(!success || !in) {
+ LL_WARNS() << "Failed reading extras cache for handle " << handle << ", entry number " << i << LL_ENDL;
+ return;
+ }
+
+ LLGLTFOverrideCacheEntry entry;
+ entry.fromLLSD(entry_llsd);
+ U32 local_id = entry_llsd["local_id"].asInteger();
+ cache_extras_entry_map[local_id] = entry;
+ }
+
+ LL_DEBUGS("GLTF") << "Completed reading extras cache for handle " << handle << ", " << num_entries << " entries" << LL_ENDL;
}
void LLVOCache::purgeEntries(U32 size)
@@ -1520,6 +1608,7 @@ void LLVOCache::purgeEntries(U32 size)
mHeaderEntryQueue.erase(iter) ;
removeFromCache(entry) ;
delete entry;
+ // TODO also delete extras
}
mNumEntries = mHandleEntryMap.size() ;
}
@@ -1649,4 +1738,59 @@ void LLVOCache::writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry:
void LLVOCache::writeGenericExtrasToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry::vocache_gltf_overrides_map_t& cache_extras_entry_map, BOOL dirty_cache, bool removal_enabled)
{
+ if(!mEnabled)
+ {
+ LL_WARNS() << "Not writing extras cache for handle " << handle << "): Cache is currently disabled." << LL_ENDL;
+ return;
+ }
+ llassert_always(mInitialized);
+
+ if(mReadOnly)
+ {
+ LL_WARNS() << "Not writing extras cache for handle " << handle << "): Cache is currently in read-only mode." << LL_ENDL;
+ return;
+ }
+
+ std::string filename(getObjectCacheExtrasFilename(handle));
+ llofstream out(filename, std::ios::out | std::ios::binary);
+ if(!out.good())
+ {
+ LL_WARNS() << "Failed writing extras cache for handle " << handle << LL_ENDL;
+ return;
+ // TODO - clean up broken cache file
+ }
+
+ out << id << '\n';
+ if(!out.good())
+ {
+ LL_WARNS() << "Failed writing extras cache for handle " << handle << LL_ENDL;
+ return;
+ // TODO - clean up broken cache file
+ }
+
+ U32 num_entries = cache_extras_entry_map.size();
+ out << num_entries << '\n';
+ if(!out.good())
+ {
+ LL_WARNS() << "Failed writing extras cache for handle " << handle << LL_ENDL;
+ return;
+ // TODO - clean up broken cache file
+ }
+
+ for (auto const & entry : cache_extras_entry_map)
+ {
+ S32 local_id = entry.first;
+ LLSD entry_llsd = entry.second.toLLSD();
+ entry_llsd["local_id"] = local_id;
+ LLSDSerialize::serialize(entry_llsd, out, LLSDSerialize::LLSD_XML);
+ out << '\n';
+ if(!out.good())
+ {
+ LL_WARNS() << "Failed writing extras cache for handle " << handle << LL_ENDL;
+ return;
+ // TODO - clean up broken cache file
+ }
+ }
+
+ LL_DEBUGS("GLTF") << "Completed writing extras cache for handle " << handle << ", " << num_entries << " entries" << LL_ENDL;
}
diff --git a/indra/newview/llvocache.h b/indra/newview/llvocache.h
index f41e9301ca..dcc8d37c5c 100644
--- a/indra/newview/llvocache.h
+++ b/indra/newview/llvocache.h
@@ -43,7 +43,7 @@ class LLGLTFOverrideCacheEntry
{
public:
bool fromLLSD(const LLSD& data);
- LLSD toLLSD();
+ LLSD toLLSD() const;
LLUUID mObjectId;
std::map<S32, std::string> mSides; //json per side
@@ -301,6 +301,7 @@ private:
void setDirNames(ELLPath location);
// determine the cache filename for the region from the region handle
void getObjectCacheFilename(U64 handle, std::string& filename);
+ std::string getObjectCacheExtrasFilename(U64 handle);
void removeFromCache(HeaderEntryInfo* entry);
void readCacheHeader();
void writeCacheHeader();
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index e69dea3444..77849c668a 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -858,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();
@@ -878,7 +872,6 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)
else
{
vsize = face->getTextureVirtualSize();
- imagep->addTextureStats(vsize);
}
mPixelArea = llmax(mPixelArea, face->getPixelArea());
@@ -895,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)
@@ -965,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();
@@ -3307,7 +3295,6 @@ void LLVOVolume::updateSpotLightPriority()
if (mLightTexture.notNull())
{
mLightTexture->addTextureStats(mSpotLightPriority);
- mLightTexture->setBoostLevel(LLGLTexture::BOOST_CLOUDS);
}
}
@@ -3331,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
@@ -5429,7 +5416,8 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
if (gltf_mat)
{
- // nothing to do, render pools will reference the GLTF material
+ // just remember the material ID, render pools will reference the GLTF material
+ draw_info->mMaterialID = mat_id;
}
else if (mat)
{
@@ -5482,8 +5470,10 @@ 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());
+ llassert(type != LLRenderPass::PASS_SPECMAP || (info->mVertexBuffer->getTypeMask() & LLVertexBuffer::MAP_TEXCOORD2) != 0);
}
void LLVolumeGeometryManager::getGeometry(LLSpatialGroup* group)
@@ -5681,6 +5671,12 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
continue;
}
+ // HACK -- brute force this check every time a drawable gets rebuilt
+ for (S32 i = 0; i < drawablep->getNumFaces(); ++i)
+ {
+ vobj->updateTEMaterialTextures(i);
+ }
+
// apply any pending material overrides
gGLTFMaterialList.applyQueuedOverrides(vobj);
@@ -5755,7 +5751,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
@@ -5766,9 +5761,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
{
continue;
}
-
- // HACK -- brute force this check every time a drawable gets rebuilt
- vobj->updateTEMaterialTextures(i);
#if 0
#if LL_RELEASE_WITH_DEBUG_INFO
const LLUUID pbr_id( "49c88210-7238-2a6b-70ac-92d4f35963cf" );
@@ -5913,13 +5905,10 @@ 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)
{
@@ -5928,7 +5917,8 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
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)
@@ -5963,23 +5953,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
@@ -6207,7 +6180,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();
}
@@ -6298,13 +6271,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;
}
@@ -6660,6 +6629,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);
}
@@ -6690,12 +6660,28 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
LLRenderPass::PASS_NORMSPEC_EMISSIVE,
};
- U32 mask = mat->getShaderMask();
+ U32 alpha_mode = mat->getDiffuseAlphaMode();
+ if (!distance_sort && alpha_mode == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND)
+ { // HACK - this should never happen, but sometimes we get a material that thinks it has alpha blending when it ought not
+ alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
+ }
+ U32 mask = mat->getShaderMask(alpha_mode);
+
+ U32 vb_mask = facep->getVertexBuffer()->getTypeMask();
+
+ // HACK - this should also never happen, but sometimes we get here and the material thinks it has a specmap now
+ // even though it didn't appear to have a specmap when the face was added to the list of faces
+ if ((mask & 0x4) && !(vb_mask & LLVertexBuffer::MAP_TEXCOORD2))
+ {
+ mask &= ~0x4;
+ }
llassert(mask < sizeof(pass)/sizeof(U32));
mask = llmin(mask, (U32)(sizeof(pass)/sizeof(U32)-1));
+ // if this is going into alpha pool, distance sort MUST be true
+ llassert(pass[mask] == LLRenderPass::PASS_ALPHA ? distance_sort : true);
registerFace(group, facep, pass[mask]);
}
}
@@ -6719,7 +6705,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)
{
@@ -6754,7 +6739,6 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
}
}
else if (gPipeline.shadersLoaded()
- && LLPipeline::sRenderBump
&& te->getShiny()
&& can_be_shiny)
{ //shiny
@@ -6775,6 +6759,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
@@ -6808,15 +6793,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
@@ -6836,8 +6822,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);
}
@@ -6849,8 +6834,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 b5b5d9ef7f..18b0192346 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;
@@ -2454,7 +2424,7 @@ void LLPipeline::doOcclusion(LLCamera& camera)
gGL.setColorMask(true, true);
}
- if (LLPipeline::sUseOcclusion > 1 && !LLSpatialPartition::sTeleportRequested &&
+ if (LLPipeline::sUseOcclusion > 1 &&
(sCull->hasOcclusionGroups() || LLVOCachePartition::sNeedsOcclusionCheck))
{
LLVertexBuffer::unbind();
@@ -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();
@@ -7489,6 +7423,12 @@ void LLPipeline::renderFinalize()
screenTarget()->bindTexture(0, channel, LLTexUnit::TFO_POINT);
}
+ channel = gDeferredPostGammaCorrectProgram.enableTexture(LLShaderMgr::DEFERRED_EMISSIVE, screenTarget()->getUsage());
+ if (channel > -1)
+ {
+ mGlow[1].bindTexture(0, channel, LLTexUnit::TFO_BILINEAR);
+ }
+
gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, screenTarget()->getWidth(), screenTarget()->getHeight());
static LLCachedControl<F32> exposure(gSavedSettings, "RenderExposure", 1.f);
@@ -7516,8 +7456,8 @@ void LLPipeline::renderFinalize()
bool multisample = RenderFSAASamples > 1 && mRT->fxaaBuffer.isComplete();
LLGLSLShader* shader = &gGlowCombineProgram;
- S32 width = mRT->screen.getWidth();
- S32 height = mRT->screen.getHeight();
+ S32 width = screenTarget()->getWidth();
+ S32 height = screenTarget()->getHeight();
S32 channel = -1;
@@ -7535,10 +7475,10 @@ void LLPipeline::renderFinalize()
shader->bind();
shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, width, height);
- channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->deferredLight.getUsage());
+ channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, screenTarget()->getUsage());
if (channel > -1)
{
- mRT->deferredLight.bindTexture(0, channel);
+ screenTarget()->bindTexture(0, channel);
}
{
@@ -7549,7 +7489,7 @@ void LLPipeline::renderFinalize()
gGL.flush();
- shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->deferredLight.getUsage());
+ shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, screenTarget()->getUsage());
shader->unbind();
mRT->fxaaBuffer.flush();
@@ -7601,11 +7541,9 @@ void LLPipeline::renderFinalize()
shader->bind();
- S32 glow_channel = shader->getTextureChannel(LLShaderMgr::DEFERRED_EMISSIVE);
S32 screen_channel = shader->getTextureChannel(LLShaderMgr::DEFERRED_DIFFUSE);
S32 depth_channel = shader->getTextureChannel(LLShaderMgr::DEFERRED_DEPTH);
- gGL.getTexUnit(glow_channel)->bind(&mGlow[1]);
gGL.getTexUnit(screen_channel)->bind(screenTarget());
gGL.getTexUnit(depth_channel)->bind(&mRT->deferredScreen, true);
@@ -7622,7 +7560,6 @@ void LLPipeline::renderFinalize()
shader->unbind();
}
}
-
gGL.setSceneBlendType(LLRender::BT_ALPHA);
@@ -7779,12 +7716,6 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_
}
}
- channel = shader.enableTexture(LLShaderMgr::DEFERRED_BLOOM);
- if (channel > -1)
- {
- mGlow[1].bindTexture(0, channel);
- }
-
stop_glerror();
bindShadowMaps(shader);
@@ -8119,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..a6a401f43e 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
@@ -28,7 +29,6 @@
color="DkGray2"
opaque="true"
tab_stop="true"
- border="false"
reserve_scroll_corner="false">
<panel
name="panel_material"
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"
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 711be76764..bf67118eac 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -12041,10 +12041,12 @@ Material successfully created. Asset ID: [ASSET_ID]
name="ReflectionProbeApplied"
persist="true"
type="alertmodal">
- WARNING: You have made your object a Refelction Probe. Continuing to manipulate the object while it is a probe will implicitly change the object to mimic its influence volume and will make irreversible changes to the object. If you don't know what a reflection probe is, uncheck "Reflection Probe" immediately. To learn more about Reflection Probes and how to use them, see https://wiki.secondlife.com/wiki/PBR_Materials#Understanding_and_Assisting_the_New_Reflections_System.
- <usetemplate ignoretext="Reflection Probe tips"
- name="okignore"
- yestext="OK"/>
+ WARNING: You have made your object a Reflection Probe. This will implicitly change the object to mimic its influence volume and will make irreversible changes to the object. Do you want to continue?
+ <usetemplate
+ ignoretext="Reflection Probe tips"
+ name="okcancelignore"
+ notext="Cancel"
+ yestext="OK"/>
</notification>
</notifications>
diff --git a/indra/newview/skins/default/xui/en/panel_tools_texture.xml b/indra/newview/skins/default/xui/en/panel_tools_texture.xml
index 3bcbe0ca3a..67bdd189c1 100644
--- a/indra/newview/skins/default/xui/en/panel_tools_texture.xml
+++ b/indra/newview/skins/default/xui/en/panel_tools_texture.xml
@@ -140,11 +140,11 @@
top_pad="17"
width="90">
<combo_box.item
- label="Materials"
+ label="Blinn-Phong"
name="Materials"
value="Materials" />
<combo_box.item
- label="PBR"
+ label="PBR Metallic Roughness"
name="PBR"
value="PBR" />
<combo_box.item
@@ -256,7 +256,7 @@
allow_no_texture="true"
follows="left|top"
height="80"
- label="PBR "
+ label="Material"
layout="topleft"
left="10"
name="pbr_control"
diff --git a/indra/newview/tests/lldir_stub.cpp b/indra/newview/tests/lldir_stub.cpp
index 2bc6772d86..911e9334dd 100644
--- a/indra/newview/tests/lldir_stub.cpp
+++ b/indra/newview/tests/lldir_stub.cpp
@@ -30,25 +30,29 @@ LLDir::LLDir() {}
LLDir::~LLDir() {}
BOOL LLDir::deleteFilesInDir(const std::string &dirname, const std::string &mask) { return true; }
void LLDir::setChatLogsDir(const std::string &path) {}
-void LLDir::setPerAccountChatLogsDir(const std::string &first, const std::string &last) {}
-void LLDir::setLindenUserDir(const std::string &first, const std::string &last) {}
+void LLDir::setPerAccountChatLogsDir(const std::string &) {}
+void LLDir::updatePerAccountChatLogsDir() {}
+void LLDir::setLindenUserDir(const std::string &) {}
void LLDir::setSkinFolder(const std::string &skin_folder, const std::string& language) {}
bool LLDir::setCacheDir(const std::string &path) { return true; }
-void LLDir::dumpCurrentDirectories() {}
+void LLDir::dumpCurrentDirectories(LLError::ELevel) {}
+std::string LLDir::getSkinFolder() const { return ""; }
+std::string LLDir::getLanguage() const { return ""; }
+
class LLDir_stub : public LLDir
{
public:
- LLDir_stub() {}
- ~LLDir_stub() {}
+ LLDir_stub() = default;
+ ~LLDir_stub() = default;
+
+ void initAppDirs(const std::string &app_name, const std::string &) override {}
- /*virtual*/ void initAppDirs(const std::string &app_name) {}
+ std::string getCurPath() override { return "CUR_PATH_FROM_LLDIR"; }
+ bool fileExists(const std::string &filename) const override { return false; }
- /*virtual*/ std::string getCurPath() { return "CUR_PATH_FROM_LLDIR"; }
- /*virtual*/ U32 countFilesInDir(const std::string &dirname, const std::string &mask) { return 42; }
- /*virtual*/ BOOL getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname, BOOL wrap) { fname = fname + "_NEXT"; return false; }
- /*virtual*/ void getRandomFileInDir(const std::string &dirname, const std::string &mask, std::string &fname) { fname = "RANDOM_FILE"; }
- /*virtual*/ bool fileExists(const std::string &filename) const { return false; }
+ std::string getLLPluginLauncher() override { return ""; }
+ std::string getLLPluginFilename(std::string base_name) override { return ""; }
};
LLDir_stub gDirUtil;
@@ -60,3 +64,7 @@ std::string LLDir::getExpandedFilename(ELLPath loc, const std::string& subdir, c
return subdir + " --- " + filename + " --- expanded!";
}
+std::string LLDir::getExpandedFilename(ELLPath location, const std::string &filename) const
+{
+ return filename + " --- expanded!";
+}
diff --git a/indra/newview/tests/llvieweroctree_stub.cpp b/indra/newview/tests/llvieweroctree_stub.cpp
new file mode 100644
index 0000000000..ab180c49a3
--- /dev/null
+++ b/indra/newview/tests/llvieweroctree_stub.cpp
@@ -0,0 +1,86 @@
+/**
+ * @file llvieweroctree_stub.cpp
+ * @brief stub implementations to allow unit testing
+ *
+ * $LicenseInfo:firstyear=2023&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, 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$
+ */
+
+S32 AABBSphereIntersect(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &rad) { return 0; }
+
+void LLViewerOctreeCull::traverse(const LLOctreeNode<LLViewerOctreeEntry, LLPointer<LLViewerOctreeEntry> >* node) { }
+void LLViewerOctreeCull::visit(const LLOctreeNode<LLViewerOctreeEntry, LLPointer<LLViewerOctreeEntry> >* node) { }
+void LLViewerOctreeCull::preprocess(LLViewerOctreeGroup* group) {}
+bool LLViewerOctreeCull::earlyFail(LLViewerOctreeGroup* group) { return false; }
+bool LLViewerOctreeCull::checkProjectionArea(const LLVector4a& center, const LLVector4a& size, const LLVector3& shift, F32 pixel_threshold, F32 near_radius) { return false; }
+bool LLViewerOctreeCull::checkObjects(const OctreeNode* branch, const LLViewerOctreeGroup* group) { return false; }
+void LLViewerOctreeCull::processGroup(LLViewerOctreeGroup* group) {}
+
+
+bool LLViewerOctreeGroup::boundObjects(BOOL empty, LLVector4a& minOut, LLVector4a& maxOut) { return false; }
+void LLViewerOctreeGroup::unbound() {}
+void LLViewerOctreeGroup::rebound() {}
+void LLViewerOctreeGroup::handleInsertion(const TreeNode* node, LLViewerOctreeEntry* obj) {}
+void LLViewerOctreeGroup::handleRemoval(const TreeNode* node, LLViewerOctreeEntry* obj) {}
+void LLViewerOctreeGroup::handleDestruction(const TreeNode* node) {}
+void LLViewerOctreeGroup::handleStateChange(const TreeNode* node) {}
+void LLViewerOctreeGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* child) {}
+void LLViewerOctreeGroup::handleChildRemoval(const OctreeNode* parent, const OctreeNode* child) {}
+
+LLOcclusionCullingGroup::LLOcclusionCullingGroup(OctreeNode* node, LLViewerOctreePartition* part) :
+ LLViewerOctreeGroup(node),
+ mSpatialPartition(part)
+{
+}
+LLOcclusionCullingGroup::~LLOcclusionCullingGroup() = default;
+void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* shift) {}
+void LLOcclusionCullingGroup::setOcclusionState(U32 state, S32 mode) {}
+void LLOcclusionCullingGroup::clearOcclusionState(U32 state, S32 mode) {}
+void LLOcclusionCullingGroup::handleChildAddition(const OctreeNode *parent, OctreeNode *child) {}
+BOOL LLOcclusionCullingGroup::isRecentlyVisible() const { return FALSE; }
+BOOL LLOcclusionCullingGroup::isAnyRecentlyVisible() const { return FALSE; }
+
+
+LLViewerOctreeGroup::LLViewerOctreeGroup(OctreeNode* node) : mOctreeNode(node) {}
+LLViewerOctreeGroup::~LLViewerOctreeGroup() = default;
+
+LLViewerOctreeEntryData::LLViewerOctreeEntryData(LLViewerOctreeEntry::eEntryDataType_t) {}
+LLViewerOctreeEntryData::~LLViewerOctreeEntryData() = default;
+bool LLViewerOctreeEntryData::isVisible() const { return false; }
+bool LLViewerOctreeEntryData::isRecentlyVisible() const { return false; }
+void LLViewerOctreeEntryData::setVisible() const {}
+void LLViewerOctreeEntryData::resetVisible() const {}
+const LLVector4a& LLViewerOctreeEntryData::getPositionGroup() const { return LLVector4a::getZero(); }
+const LLVector4a* LLViewerOctreeEntryData::getSpatialExtents() const { return nullptr; }
+LLViewerOctreeGroup* LLViewerOctreeEntryData::getGroup() const { return nullptr; }
+void LLViewerOctreeEntryData::setSpatialExtents(const LLVector4a& min, const LLVector4a& max) {}
+void LLViewerOctreeEntryData::setPositionGroup(const LLVector4a& pos) {}
+void LLViewerOctreeEntryData::setGroup(LLViewerOctreeGroup* group) {}
+void LLViewerOctreeEntryData::setOctreeEntry(LLViewerOctreeEntry* entry) {}
+U32 LLViewerOctreeEntryData::sCurVisible{};
+
+LLViewerOctreePartition::LLViewerOctreePartition() = default;
+LLViewerOctreePartition::~LLViewerOctreePartition() = default;
+void LLViewerOctreePartition::cleanup() {}
+
+BOOL LLViewerOctreeGroup::isRecentlyVisible() const { return FALSE; }
+
+
diff --git a/indra/newview/tests/llvocache_test.cpp b/indra/newview/tests/llvocache_test.cpp
new file mode 100644
index 0000000000..ea6abe254e
--- /dev/null
+++ b/indra/newview/tests/llvocache_test.cpp
@@ -0,0 +1,146 @@
+/**
+ * @file llvocache_.cpp
+ * @author Brad
+ * @date 2023-03-01
+ * @brief Test Viewer Object Cache functionality
+ *
+ * $LicenseInfo:firstyear=2023&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2014, 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 "../llviewerprecompiledheaders.h"
+#include "../test/lltut.h"
+
+#include "llvocache.h"
+
+#include "lldir.h"
+#include "llhudobject.h"
+#include "llregionhandle.h"
+#include "llsdutil.h"
+#include "llsdserialize.h"
+#include "llviewerobjectlist.h"
+#include "llviewerregion.h"
+
+#include "lldir_stub.cpp"
+#include "llvieweroctree_stub.cpp"
+
+namespace
+{
+
+}
+
+
+//----------------------------------------------------------------------------
+// Mock objects for the dependencies of the code we're testing
+S32 LLVOCachePartition::cull(LLCamera &camera, bool do_occlusion) { return 0; }
+
+LLViewerObjectList::LLViewerObjectList() = default;
+LLViewerObjectList::~LLViewerObjectList() = default;
+LLDebugBeacon::~LLDebugBeacon() = default;
+LLViewerObjectList gObjectList{};
+LLViewerCamera::eCameraID LLViewerCamera::sCurCameraID{};
+void LLViewerObject::unpackUUID(LLDataPackerBinaryBuffer *dp, LLUUID &value, std::string name) {}
+
+bool LLViewerRegion::addVisibleGroup(LLViewerOctreeGroup*) { return false; }
+U32 LLViewerRegion::getNumOfVisibleGroups() const { return 0; }
+LLVector3 LLViewerRegion::getOriginAgent() const { return LLVector3::zero; }
+S32 LLViewerRegion::sLastCameraUpdated{};
+
+// -------------------------------------------------------------------------------------------
+// TUT
+// -------------------------------------------------------------------------------------------
+namespace tut
+{
+ // Test wrapper declaration
+ struct vocacheTest
+ {
+ vocacheTest() = default;
+ ~vocacheTest() = default;
+
+ static const std::string override_llsd_text[];
+ };
+
+ const std::string vocacheTest::override_llsd_text[]{
+ // sample override contents captured from traffic
+ R"(<? llsd/notation ?>
+ {'gltf_json':['{"asset":{"version":"2.0"},"images":[{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"}],"materials":[{"emissiveTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":3},"normalTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":1},"occlusionTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":4},"pbrMetallicRoughness":{"baseColorTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":0},"metallicRoughnessTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":2}}}],"textures":[{"source":0},{"source":1},{"source":2},{"source":3},{"source":4}]}\n','{"asset":{"version":"2.0"},"images":[{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"}],"materials":[{"emissiveTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":3},"normalTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":1},"occlusionTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":4},"pbrMetallicRoughness":{"baseColorTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":0},"metallicRoughnessTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":2}}}],"textures":[{"source":0},{"source":1},{"source":2},{"source":3},{"source":4}]}\n','{"asset":{"version":"2.0"},"images":[{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"}],"materials":[{"emissiveTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":3},"normalTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":1},"occlusionTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":4},"pbrMetallicRoughness":{"baseColorTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":0},"metallicRoughnessTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":2}}}],"textures":[{"source":0},{"source":1},{"source":2},{"source":3},{"source":4}]}\n','{"asset":{"version":"2.0"},"images":[{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"}],"materials":[{"emissiveTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":3},"normalTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":1},"occlusionTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":4},"pbrMetallicRoughness":{"baseColorTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":0},"metallicRoughnessTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":2}}}],"textures":[{"source":0},{"source":1},{"source":2},{"source":3},{"source":4}]}\n','{"asset":{"version":"2.0"},"images":[{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"}],"materials":[{"emissiveTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":3},"normalTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":1},"occlusionTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":4},"pbrMetallicRoughness":{"baseColorTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":0},"metallicRoughnessTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":2}}}],"textures":[{"source":0},{"source":1},{"source":2},{"source":3},{"source":4}]}\n','{"asset":{"version":"2.0"},"images":[{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"}],"materials":[{"emissiveTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":3},"normalTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":1},"occlusionTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":4},"pbrMetallicRoughness":{"baseColorTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":0},"metallicRoughnessTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":2}}}],"textures":[{"source":0},{"source":1},{"source":2},{"source":3},{"source":4}]}\n','{"asset":{"version":"2.0"},"images":[{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"}],"materials":[{"emissiveTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":3},"normalTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":1},"occlusionTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":4},"pbrMetallicRoughness":{"baseColorTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":0},"metallicRoughnessTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":2}}}],"textures":[{"source":0},{"source":1},{"source":2},{"source":3},{"source":4}]}\n'],'object_id':u8b357110-4845-1d40-1cf0-cc4a2c22a4f1,'sides':[i0,i1,i2,i3,i4,i5,i6]})"
+ };
+
+ // Tut templating thingamagic: test group, object and test instance
+ struct vocacheTestFactory : public test_group<vocacheTest>
+ {
+ vocacheTestFactory()
+ : test_group<vocacheTest>("LLVOCache")
+ {
+ ll_init_apr();
+
+ const bool READ_ONLY = false;
+ const U32 INDRA_OBJECT_CACHE_VERSION = 15; // see LLAppViewer::getObjectCacheVersion()
+ const U32 CACHE_NUMBER_OF_REGIONS = 128; // see setting CacheNumberOfRegionsForObjects
+
+ LLVOCache &instance = LLVOCache::initParamSingleton(READ_ONLY);
+ instance.initCache(LL_PATH_CACHE, CACHE_NUMBER_OF_REGIONS, INDRA_OBJECT_CACHE_VERSION);
+ }
+
+ ~vocacheTestFactory()
+ {
+ LLVOCache::deleteSingleton();
+ ll_cleanup_apr();
+ }
+
+ };
+
+ typedef vocacheTestFactory::object vocacheTestObject;
+ tut::vocacheTestFactory tut_test;
+
+ // ---------------------------------------------------------------------------------------
+ // Test functions
+ // ---------------------------------------------------------------------------------------
+
+ template<> template<>
+ void vocacheTestObject::test<1>()
+ {
+ LLGLTFOverrideCacheEntry entry{};
+ LLSD entry_llsd;
+
+ std::istringstream in_llsd(override_llsd_text[0]);
+ bool success = LLSDSerialize::deserialize(entry_llsd, in_llsd, override_llsd_text[0].length());
+
+ ensure("llsd deserialize succeeds", success);
+
+ entry.fromLLSD(entry_llsd);
+ ensure_equals("entry object_id match", entry.mObjectId, LLUUID("8b357110-4845-1d40-1cf0-cc4a2c22a4f1"));
+ ensure_equals("sides count", entry.mSides.size(), 7);
+
+ //std::cout << other << std::endl;
+ ensure_equals("toLLSD() match", entry.toLLSD(), entry_llsd);
+ }
+
+ template<> template<>
+ void vocacheTestObject::test<2>()
+ {
+ LLVOCacheEntry::vocache_gltf_overrides_map_t extras;
+
+ U64 region_handle = to_region_handle(140, 81);
+ LLUUID region_id = LLUUID::generateNewID();
+
+ LLVOCache::instance().readGenericExtrasFromCache(region_handle, region_id, extras);
+ }
+}