Merge branch 'develop' of https://github.com/secondlife/viewer
# Conflicts: # indra/llfilesystem/llfilesystem.cpp # indra/newview/llappviewer.cpp # indra/newview/lltextureview.cpp # indra/newview/llviewertexture.h # indra/newview/llviewertexturelist.cppmaster
commit
e9b6550c48
|
|
@ -0,0 +1,12 @@
|
|||
# PBR Materials
|
||||
|
||||
## KHR Texture Transforms
|
||||
|
||||
Texture repeats for PBR materials on prims are based on the [KHR\_texture\_transform](https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_texture_transform) spec, and thus should be expected to behave according to the spec. We currently suport offset, rotation, and scale from the spec. texCoord is not currently supported.
|
||||
|
||||
PBR materials should have approximately correct lighting based on the normal texture:
|
||||
|
||||
- With default texture transforms, assuming the prim or model has correct normals and tangents
|
||||
- With a texture transform applied, especially rotation or negative scale
|
||||
- With a texture animation applied via `llSetTextureAnim`, especially a rotation animation
|
||||
- Note: Texture animations are not guaranteed to loop when a PBR texture transform is applied
|
||||
|
|
@ -39,7 +39,7 @@ PBR terrain does not support materials with alpha blend or double-sided. In addi
|
|||
|
||||
## PBR Terrain Texture Transforms
|
||||
|
||||
Like PBR materials on prims, PBR terrain repeats are based on the [KHR\_texture\_transform](https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_texture_transform) spec, and thus should be expected to behave the same way.
|
||||
Like PBR materials on prims, PBR terrain repeats are based on the [KHR\_texture\_transform](https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_texture_transform) spec, and thus should be expected to behave the same way. We currently suport offset, rotation, and scale from the spec. texCoord is not currently supported.
|
||||
|
||||
The southwest corner of a region, at z=0, is the UV origin for all texture coordinates of the whole region. Unless an offset is also applied, scale and rotation of the terrain texture transforms are relative to that point.
|
||||
|
||||
|
|
|
|||
|
|
@ -87,6 +87,12 @@ If saving the terrain fails for any reason, the terrain should not be updated.
|
|||
|
||||
Unlike a viewer without PBR terrain support, the new viewer will no longer treat textures with alpha channels as invalid.
|
||||
|
||||
### Saving PBR Terrain Texture Transforms
|
||||
|
||||
If "PBR Metallic Roughness" checkbox is checked, a user with saving composition permissions should also be allowed to edit and save PBR texture transforms.
|
||||
|
||||
One texture transform may be set for each material swatch. Setting texture transforms for each individual texture on the material is not currently supported.
|
||||
|
||||
## Graphics Features
|
||||
|
||||
Texture terrain with transparency is not permitted to be applied in the viewer.
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ LLFileSystem::~LLFileSystem()
|
|||
// static
|
||||
bool LLFileSystem::getExists(const LLUUID& file_id, const LLAssetType::EType file_type)
|
||||
{
|
||||
LL_PROFILE_ZONE_COLOR(tracy::Color::Gold); // <FS:Beq> measure cache performance
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
std::string id_str;
|
||||
file_id.toString(id_str);
|
||||
const std::string extra_info = "";
|
||||
|
|
|
|||
|
|
@ -484,6 +484,8 @@ void LLAssetStorage::getAssetData(const LLUUID uuid,
|
|||
void *user_data,
|
||||
bool is_priority)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
|
||||
LL_DEBUGS("AssetStorage") << "LLAssetStorage::getAssetData() - " << uuid << "," << LLAssetType::lookup(type) << LL_ENDL;
|
||||
|
||||
LL_DEBUGS("AssetStorage") << "ASSET_TRACE requesting " << uuid << " type " << LLAssetType::lookup(type) << LL_ENDL;
|
||||
|
|
@ -529,6 +531,7 @@ void LLAssetStorage::getAssetData(const LLUUID uuid,
|
|||
|
||||
if (size > 0)
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED("gad - file in cache");
|
||||
// we've already got the file
|
||||
// theoretically, partial files w/o a pending request shouldn't happen
|
||||
// unless there's a weird error
|
||||
|
|
@ -548,7 +551,7 @@ void LLAssetStorage::getAssetData(const LLUUID uuid,
|
|||
}
|
||||
|
||||
bool duplicate = false;
|
||||
|
||||
LL_PROFILE_ZONE_NAMED("gad - check pending downloads");
|
||||
// check to see if there's a pending download of this uuid already
|
||||
for (request_list_t::iterator iter = mPendingDownloads.begin();
|
||||
iter != mPendingDownloads.end(); ++iter )
|
||||
|
|
|
|||
|
|
@ -116,6 +116,9 @@ public:
|
|||
bool mIsNVIDIA;
|
||||
bool mIsIntel;
|
||||
|
||||
// hints to the render pipe
|
||||
U32 mDownScaleMethod = 0; // see settings.xml RenderDownScaleMethod
|
||||
|
||||
#if LL_DARWIN
|
||||
// Needed to distinguish problem cards on older Macs that break with Materials
|
||||
bool mIsMobileGF;
|
||||
|
|
|
|||
|
|
@ -57,6 +57,9 @@ const F32 MIN_TEXTURE_LIFETIME = 10.f;
|
|||
U32 wpo2(U32 i);
|
||||
|
||||
|
||||
U32 LLImageGL::sFrameCount = 0;
|
||||
|
||||
|
||||
// texture memory accounting (for macOS)
|
||||
static LLMutex sTexMemMutex;
|
||||
static std::unordered_map<U32, U64> sTextureAllocs;
|
||||
|
|
@ -1003,7 +1006,7 @@ bool should_stagger_image_set(bool compressed)
|
|||
#else
|
||||
// glTexSubImage2D doesn't work with compressed textures on select tested Nvidia GPUs on Windows 10 -Cosmic,2023-03-08
|
||||
// Setting media textures off-thread seems faster when not using sub_image_lines (Nvidia/Windows 10) -Cosmic,2023-03-31
|
||||
return !compressed && on_main_thread();
|
||||
return !compressed && on_main_thread() && !gGLManager.mIsIntel;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -1185,13 +1188,37 @@ void LLImageGL::generateTextures(S32 numTextures, U32 *textures)
|
|||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLImageGL::updateClass()
|
||||
{
|
||||
sFrameCount++;
|
||||
}
|
||||
|
||||
// static
|
||||
void LLImageGL::deleteTextures(S32 numTextures, const U32 *textures)
|
||||
{
|
||||
// wait a few frames before actually deleting the textures to avoid
|
||||
// synchronization issues with the GPU
|
||||
static std::vector<U32> sFreeList[4];
|
||||
|
||||
if (gGLManager.mInited)
|
||||
{
|
||||
free_tex_images(numTextures, textures);
|
||||
glDeleteTextures(numTextures, textures);
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
U32 idx = sFrameCount % 4;
|
||||
|
||||
for (S32 i = 0; i < numTextures; ++i)
|
||||
{
|
||||
sFreeList[idx].push_back(textures[i]);
|
||||
}
|
||||
|
||||
idx = (sFrameCount + 3) % 4;
|
||||
|
||||
if (!sFreeList[idx].empty())
|
||||
{
|
||||
glDeleteTextures((GLsizei) sFreeList[idx].size(), sFreeList[idx].data());
|
||||
free_tex_images((GLsizei) sFreeList[idx].size(), sFreeList[idx].data());
|
||||
sFreeList[idx].resize(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2338,10 +2365,50 @@ bool LLImageGL::scaleDown(S32 desired_discard)
|
|||
S32 desired_width = getWidth(desired_discard);
|
||||
S32 desired_height = getHeight(desired_discard);
|
||||
|
||||
U64 size = getBytes(desired_discard);
|
||||
llassert(size <= 2048*2048*4); // we shouldn't be using this method to downscale huge textures, but it'll work
|
||||
gGL.getTexUnit(0)->bind(this);
|
||||
if (gGLManager.mDownScaleMethod == 0)
|
||||
{ // use an FBO to downscale the texture
|
||||
// allocate new texture
|
||||
U32 temp_texname = 0;
|
||||
generateTextures(1, &temp_texname);
|
||||
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, temp_texname, true);
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("scaleDown - glTexImage2D");
|
||||
glTexImage2D(mTarget, 0, mFormatPrimary, desired_width, desired_height, 0, mFormatPrimary, mFormatType, NULL);
|
||||
}
|
||||
|
||||
// account for new texture getting created
|
||||
alloc_tex_image(desired_width, desired_height, mFormatPrimary);
|
||||
|
||||
// Use render-to-texture to scale down the texture
|
||||
{
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("scaleDown - glFramebufferTexture2D");
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTarget, temp_texname, 0);
|
||||
}
|
||||
|
||||
glViewport(0, 0, desired_width, desired_height);
|
||||
|
||||
// draw a full screen triangle
|
||||
gGL.getTexUnit(0)->bind(this);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
|
||||
// delete old texture and assign new texture name
|
||||
deleteTextures(1, &mTexName);
|
||||
mTexName = temp_texname;
|
||||
|
||||
if (mHasMipMaps)
|
||||
{ // generate mipmaps if needed
|
||||
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("scaleDown - glGenerateMipmap");
|
||||
gGL.getTexUnit(0)->bind(this);
|
||||
glGenerateMipmap(mTarget);
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // use a PBO to downscale the texture
|
||||
U64 size = getBytes(desired_discard);
|
||||
llassert(size <= 2048 * 2048 * 4); // we shouldn't be using this method to downscale huge textures, but it'll work
|
||||
gGL.getTexUnit(0)->bind(this);
|
||||
|
||||
if (sScratchPBO == 0)
|
||||
{
|
||||
|
|
@ -2376,6 +2443,7 @@ bool LLImageGL::scaleDown(S32 desired_discard)
|
|||
}
|
||||
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
}
|
||||
|
||||
mCurrentDiscardLevel = desired_discard;
|
||||
|
||||
|
|
|
|||
|
|
@ -62,6 +62,9 @@ class LLImageGL : public LLRefCount
|
|||
friend class LLTexUnit;
|
||||
public:
|
||||
|
||||
// call once per frame
|
||||
static void updateClass();
|
||||
|
||||
// Get an estimate of how many bytes have been allocated in vram for textures.
|
||||
// Does not include mipmaps.
|
||||
// NOTE: multiplying this number by two gives a good estimate for total
|
||||
|
|
@ -279,7 +282,7 @@ protected:
|
|||
public:
|
||||
static std::unordered_set<LLImageGL*> sImageList;
|
||||
static S32 sCount;
|
||||
|
||||
static U32 sFrameCount;
|
||||
static F32 sLastFrameTime;
|
||||
|
||||
// Global memory statistics
|
||||
|
|
|
|||
|
|
@ -307,7 +307,11 @@ public:
|
|||
ALTERNATE_DIFFUSE_MAP = 1,
|
||||
NORMAL_MAP = 1,
|
||||
SPECULAR_MAP = 2,
|
||||
NUM_TEXTURE_CHANNELS = 3,
|
||||
BASECOLOR_MAP = 3,
|
||||
METALLIC_ROUGHNESS_MAP = 4,
|
||||
GLTF_NORMAL_MAP = 5,
|
||||
EMISSIVE_MAP = 6,
|
||||
NUM_TEXTURE_CHANNELS = 7,
|
||||
};
|
||||
|
||||
enum eVolumeTexIndex : U8
|
||||
|
|
|
|||
|
|
@ -426,14 +426,17 @@ void LLRenderTarget::bindTarget()
|
|||
GL_COLOR_ATTACHMENT1,
|
||||
GL_COLOR_ATTACHMENT2,
|
||||
GL_COLOR_ATTACHMENT3};
|
||||
glDrawBuffers(static_cast<GLsizei>(mTex.size()), drawbuffers);
|
||||
|
||||
if (mTex.empty())
|
||||
{ //no color buffer to draw to
|
||||
glDrawBuffer(GL_NONE);
|
||||
glReadBuffer(GL_NONE);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
glDrawBuffers(static_cast<GLsizei>(mTex.size()), drawbuffers);
|
||||
glReadBuffer(GL_COLOR_ATTACHMENT0);
|
||||
}
|
||||
check_framebuffer_status();
|
||||
|
||||
glViewport(0, 0, mResX, mResY);
|
||||
|
|
@ -519,7 +522,8 @@ void LLRenderTarget::flush()
|
|||
llassert(sCurFBO == mFBO);
|
||||
llassert(sBoundTarget == this);
|
||||
|
||||
if (mGenerateMipMaps == LLTexUnit::TMG_AUTO) {
|
||||
if (mGenerateMipMaps == LLTexUnit::TMG_AUTO)
|
||||
{
|
||||
LL_PROFILE_GPU_ZONE("rt generate mipmaps");
|
||||
bindTexture(0, 0, LLTexUnit::TFO_TRILINEAR);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
|
|
@ -540,6 +544,8 @@ void LLRenderTarget::flush()
|
|||
glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
|
||||
sCurResX = gGLViewport[2];
|
||||
sCurResY = gGLViewport[3];
|
||||
glReadBuffer(GL_BACK);
|
||||
glDrawBuffer(GL_BACK);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -172,6 +172,8 @@ public:
|
|||
// *HACK
|
||||
void swapFBORefs(LLRenderTarget& other);
|
||||
|
||||
static LLRenderTarget* sBoundTarget;
|
||||
|
||||
protected:
|
||||
U32 mResX;
|
||||
U32 mResY;
|
||||
|
|
@ -186,8 +188,6 @@ protected:
|
|||
U32 mMipLevels;
|
||||
|
||||
LLTexUnit::eTextureType mUsage;
|
||||
|
||||
static LLRenderTarget* sBoundTarget;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -11145,7 +11145,7 @@ Change of this parameter will affect the layout of buttons in notification toast
|
|||
<key>Comment</key>
|
||||
<string>Minimum of available physical memory in MB before textures get scaled down</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<integer>0</integer>
|
||||
<key>Type</key>
|
||||
<string>U32</string>
|
||||
<key>Value</key>
|
||||
|
|
@ -11183,6 +11183,17 @@ Change of this parameter will affect the layout of buttons in notification toast
|
|||
<string>U32</string>
|
||||
<key>Value</key>
|
||||
<integer>2048</integer>
|
||||
</map>
|
||||
<key>RenderDownScaleMethod</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Method to use to downscale images. 0 - FBO, 1 - PBO</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>U32</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>RenderDebugTextureBind</key>
|
||||
<map>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
version 60
|
||||
version 61
|
||||
// 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
|
||||
|
|
@ -76,6 +76,7 @@ RenderGLMultiThreadedMedia 1 1
|
|||
RenderReflectionProbeResolution 1 128
|
||||
RenderScreenSpaceReflections 1 1
|
||||
RenderMirrors 1 1
|
||||
RenderDownScaleMethod 1 1
|
||||
|
||||
|
||||
//
|
||||
|
|
@ -366,6 +367,7 @@ RenderAnisotropic 1 0
|
|||
RenderFSAASamples 1 0
|
||||
RenderGLContextCoreProfile 1 0
|
||||
RenderGLMultiThreadedMedia 1 0
|
||||
RenderDownScaleMethod 1 0
|
||||
|
||||
list AMD
|
||||
RenderGLMultiThreadedTextures 1 1
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
version 47
|
||||
version 48
|
||||
// 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
|
||||
|
|
@ -75,6 +75,8 @@ RenderGLMultiThreadedTextures 1 0
|
|||
RenderGLMultiThreadedMedia 1 1
|
||||
RenderReflectionProbeResolution 1 128
|
||||
RenderScreenSpaceReflections 1 1
|
||||
RenderMirrors 1 1
|
||||
RenderDownScaleMethod 1 1
|
||||
|
||||
|
||||
//
|
||||
|
|
@ -110,7 +112,7 @@ RenderReflectionProbeLevel 1 0
|
|||
RenderMirrors 1 0
|
||||
RenderHeroProbeResolution 1 256
|
||||
RenderHeroProbeDistance 1 4
|
||||
RenderHeroProbeUpdateRate 1 4
|
||||
RenderHeroProbeUpdateRate 1 6
|
||||
RenderHeroProbeConservativeUpdateMultiplier 1 16
|
||||
|
||||
//
|
||||
|
|
@ -251,8 +253,8 @@ RenderReflectionsEnabled 1 1
|
|||
RenderReflectionProbeDetail 1 1
|
||||
RenderScreenSpaceReflections 1 0
|
||||
RenderReflectionProbeLevel 1 3
|
||||
RenderMirrors 1 0
|
||||
RenderHeroProbeResolution 1 1024
|
||||
RenderMirrors 1 1
|
||||
RenderHeroProbeResolution 1 512
|
||||
RenderHeroProbeDistance 1 8
|
||||
RenderHeroProbeUpdateRate 1 2
|
||||
RenderHeroProbeConservativeUpdateMultiplier 1 8
|
||||
|
|
@ -287,7 +289,7 @@ RenderReflectionsEnabled 1 1
|
|||
RenderReflectionProbeDetail 1 1
|
||||
RenderScreenSpaceReflections 1 0
|
||||
RenderReflectionProbeLevel 1 3
|
||||
RenderMirrors 1 0
|
||||
RenderMirrors 1 1
|
||||
RenderHeroProbeResolution 1 1024
|
||||
RenderHeroProbeDistance 1 16
|
||||
RenderHeroProbeUpdateRate 1 1
|
||||
|
|
@ -367,13 +369,12 @@ RenderCubeMap 0 0
|
|||
RenderFSAASamples 1 0
|
||||
RenderGLContextCoreProfile 1 0
|
||||
RenderGLMultiThreadedMedia 1 0
|
||||
RenderDownScaleMethod 1 0
|
||||
|
||||
// AMD cards generally perform better when not using VBOs for streaming data
|
||||
// AMD cards also prefer an OpenGL Compatibility Profile Context
|
||||
list AMD
|
||||
RenderGLMultiThreadedTextures 1 1
|
||||
RenderUseStreamVBO 1 0
|
||||
RenderGLContextCoreProfile 1 0
|
||||
|
||||
list GL3
|
||||
RenderFSAASamples 0 0
|
||||
|
|
|
|||
|
|
@ -36,8 +36,6 @@ namespace LL
|
|||
{
|
||||
namespace GLTF
|
||||
{
|
||||
constexpr S32 INVALID_INDEX = -1;
|
||||
|
||||
class Buffer
|
||||
{
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -476,6 +476,7 @@ void Asset::update()
|
|||
{ // HACK - force texture to be loaded full rez
|
||||
// TODO: calculate actual vsize
|
||||
image.mTexture->addTextureStats(2048.f * 2048.f);
|
||||
image.mTexture->setBoostLevel(LLViewerTexture::BOOST_HIGH);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,6 +43,8 @@ namespace LL
|
|||
{
|
||||
namespace GLTF
|
||||
{
|
||||
constexpr S32 INVALID_INDEX = -1;
|
||||
|
||||
using Value = boost::json::value;
|
||||
|
||||
using mat4 = glm::mat4;
|
||||
|
|
|
|||
|
|
@ -345,6 +345,12 @@ void GLTFSceneManager::addGLTFObject(LLViewerObject* obj, LLUUID gltf_id)
|
|||
llassert(obj->getVolume()->getParams().getSculptID() == gltf_id);
|
||||
llassert(obj->getVolume()->getParams().getSculptType() == LL_SCULPT_TYPE_GLTF);
|
||||
|
||||
if (obj->mGLTFAsset)
|
||||
{ // object already has a GLTF asset, don't reload it
|
||||
llassert(std::find(mObjects.begin(), mObjects.end(), obj) != mObjects.end());
|
||||
return;
|
||||
}
|
||||
|
||||
obj->ref();
|
||||
gAssetStorage->getAssetData(gltf_id, LLAssetType::AT_GLTF, onGLTFLoadComplete, obj);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2593,8 +2593,8 @@ bool LLAppViewer::initThreads()
|
|||
// The viewer typically starts around 8 threads not including image decode,
|
||||
// so try to leave at least one core free
|
||||
// <FS:Ansariel> Override image decode thread config
|
||||
//S32 image_decode_count = llclamp(cores - 9, 1, 8);
|
||||
S32 image_decode_count = llclamp(cores - 4, 1, 8);
|
||||
//S32 image_decode_count = llclamp(cores - 6, 2, 16);
|
||||
S32 image_decode_count = llclamp(cores - 4, 2, 8);
|
||||
if (auto max_decodes = gSavedSettings.getU32("FSImageDecodeThreads"); max_decodes > 0)
|
||||
{
|
||||
image_decode_count = llclamp((S32)max_decodes, 1, 32);
|
||||
|
|
@ -5463,6 +5463,10 @@ void LLAppViewer::idle()
|
|||
|
||||
LLGLTFMaterialList::flushUpdates();
|
||||
|
||||
static LLCachedControl<U32> downscale_method(gSavedSettings, "RenderDownScaleMethod");
|
||||
gGLManager.mDownScaleMethod = downscale_method;
|
||||
LLImageGL::updateClass();
|
||||
|
||||
// Service the WorkQueue we use for replies from worker threads.
|
||||
// Use function statics for the timeslice setting so we only have to fetch
|
||||
// and convert MainWorkTime once.
|
||||
|
|
|
|||
|
|
@ -82,10 +82,6 @@ LLDrawPoolAlpha::~LLDrawPoolAlpha()
|
|||
void LLDrawPoolAlpha::prerender()
|
||||
{
|
||||
mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
|
||||
|
||||
// TODO: is this even necessay? These are probably set to never discard
|
||||
LLViewerFetchedTexture::sFlatNormalImagep->addTextureStats(1024.f*1024.f);
|
||||
LLViewerFetchedTexture::sWhiteImagep->addTextureStats(1024.f * 1024.f);
|
||||
}
|
||||
|
||||
S32 LLDrawPoolAlpha::getNumPostDeferredPasses()
|
||||
|
|
|
|||
|
|
@ -173,6 +173,8 @@ void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp)
|
|||
mImportanceToCamera = 0.f ;
|
||||
mBoundingSphereRadius = 0.0f ;
|
||||
|
||||
mTexExtents[0].set(0, 0);
|
||||
mTexExtents[1].set(1, 1);
|
||||
mHasMedia = false ;
|
||||
mIsMediaAllowed = true;
|
||||
|
||||
|
|
@ -2181,10 +2183,12 @@ void LLFace::resetVirtualSize()
|
|||
F32 LLFace::getTextureVirtualSize()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
|
||||
F32 radius;
|
||||
F32 cos_angle_to_view_dir;
|
||||
bool in_frustum = calcPixelArea(cos_angle_to_view_dir, radius);
|
||||
|
||||
|
||||
if (mPixelArea < F_ALMOST_ZERO || !in_frustum)
|
||||
{
|
||||
setVirtualSize(0.f) ;
|
||||
|
|
|
|||
|
|
@ -866,8 +866,7 @@ void LLFloaterEmojiPicker::createEmojiIcon(const LLEmojiSearchResult& emoji,
|
|||
|
||||
void LLFloaterEmojiPicker::showPreview(bool show)
|
||||
{
|
||||
//mPreview->setIcon(nullptr);
|
||||
mDummy->setVisible(show);
|
||||
mDummy->setVisible(!show);
|
||||
mPreview->setVisible(show);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -52,8 +52,6 @@ LLFloaterGLTFAssetEditor::LLFloaterGLTFAssetEditor(const LLSD& key)
|
|||
|
||||
LLFloaterGLTFAssetEditor::~LLFloaterGLTFAssetEditor()
|
||||
{
|
||||
gIdleCallbacks.deleteFunction(idle, this);
|
||||
|
||||
if (mScroller)
|
||||
{
|
||||
removeChild(mScroller);
|
||||
|
|
@ -120,7 +118,7 @@ void LLFloaterGLTFAssetEditor::initFolderRoot()
|
|||
// Insert that scroller into the panel widgets hierarchy
|
||||
mItemListPanel->addChild(mScroller);
|
||||
|
||||
// Create the root model and view for all conversation sessions
|
||||
// Create the root model
|
||||
LLGLTFFolderItem* base_item = new LLGLTFFolderItem(mGLTFViewModel);
|
||||
|
||||
LLFolderView::Params p(LLUICtrlFactory::getDefaultParams<LLFolderView>());
|
||||
|
|
@ -144,15 +142,32 @@ void LLFloaterGLTFAssetEditor::initFolderRoot()
|
|||
mFolderRoot->setOpen(true);
|
||||
mFolderRoot->setSelectCallback([this](const std::deque<LLFolderViewItem*>& items, bool user_action) { onFolderSelectionChanged(items, user_action); });
|
||||
mScroller->setVisible(true);
|
||||
|
||||
gIdleCallbacks.addFunction(idle, this);
|
||||
}
|
||||
|
||||
void LLFloaterGLTFAssetEditor::onOpen(const LLSD& key)
|
||||
{
|
||||
gIdleCallbacks.addFunction(idle, this);
|
||||
loadFromSelection();
|
||||
}
|
||||
|
||||
void LLFloaterGLTFAssetEditor::onClose(bool app_quitting)
|
||||
{
|
||||
gIdleCallbacks.deleteFunction(idle, this);
|
||||
mAsset = nullptr;
|
||||
mObject = nullptr;
|
||||
}
|
||||
|
||||
void LLFloaterGLTFAssetEditor::clearRoot()
|
||||
{
|
||||
LLFolderViewFolder::folders_t::iterator folders_it = mFolderRoot->getFoldersBegin();
|
||||
while (folders_it != mFolderRoot->getFoldersEnd())
|
||||
{
|
||||
(*folders_it)->destroyView();
|
||||
folders_it = mFolderRoot->getFoldersBegin();
|
||||
}
|
||||
mNodeToItemMap.clear();
|
||||
}
|
||||
|
||||
void LLFloaterGLTFAssetEditor::idle(void* user_data)
|
||||
{
|
||||
LLFloaterGLTFAssetEditor* floater = (LLFloaterGLTFAssetEditor*)user_data;
|
||||
|
|
@ -216,6 +231,8 @@ void LLFloaterGLTFAssetEditor::loadFromNode(S32 node_id, LLFolderViewFolder* par
|
|||
view->setVisible(true);
|
||||
view->setOpen(true);
|
||||
|
||||
mNodeToItemMap[node_id] = view;
|
||||
|
||||
for (S32& node_id : node.mChildren)
|
||||
{
|
||||
loadFromNode(node_id, view);
|
||||
|
|
@ -246,8 +263,12 @@ void LLFloaterGLTFAssetEditor::loadFromNode(S32 node_id, LLFolderViewFolder* par
|
|||
|
||||
void LLFloaterGLTFAssetEditor::loadFromSelection()
|
||||
{
|
||||
if (!mFolderRoot || LLSelectMgr::getInstance()->getSelection()->getObjectCount() != 1)
|
||||
clearRoot();
|
||||
|
||||
if (LLSelectMgr::getInstance()->getSelection()->getObjectCount() != 1)
|
||||
{
|
||||
mAsset = nullptr;
|
||||
mObject = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -255,14 +276,19 @@ void LLFloaterGLTFAssetEditor::loadFromSelection()
|
|||
LLViewerObject* objectp = node->getObject();
|
||||
if (!objectp)
|
||||
{
|
||||
mAsset = nullptr;
|
||||
mObject = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
mAsset = objectp->mGLTFAsset;
|
||||
if (!mAsset)
|
||||
if (!objectp->mGLTFAsset)
|
||||
{
|
||||
mAsset = nullptr;
|
||||
mObject = nullptr;
|
||||
return;
|
||||
}
|
||||
mAsset = objectp->mGLTFAsset;
|
||||
mObject = objectp;
|
||||
|
||||
if (node->mName.empty())
|
||||
{
|
||||
|
|
@ -289,7 +315,6 @@ void LLFloaterGLTFAssetEditor::loadFromSelection()
|
|||
|
||||
LLGLTFFolderItem* listener = new LLGLTFFolderItem(i, name, LLGLTFFolderItem::TYPE_SCENE, mGLTFViewModel);
|
||||
|
||||
|
||||
LLFolderViewFolder::Params p;
|
||||
p.name = name;
|
||||
p.root = mFolderRoot;
|
||||
|
|
@ -316,6 +341,50 @@ void LLFloaterGLTFAssetEditor::loadFromSelection()
|
|||
mFolderRoot->update();
|
||||
}
|
||||
|
||||
void LLFloaterGLTFAssetEditor::dirty()
|
||||
{
|
||||
if (!mObject || !mAsset || !mFolderRoot)
|
||||
{
|
||||
closeFloater();
|
||||
return;
|
||||
}
|
||||
|
||||
if (LLSelectMgr::getInstance()->getSelection()->getObjectCount() > 1)
|
||||
{
|
||||
closeFloater();
|
||||
return;
|
||||
}
|
||||
|
||||
LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode(NULL);
|
||||
if (!node)
|
||||
{
|
||||
// not yet updated?
|
||||
// Todo: Subscribe to deletion in some way
|
||||
return;
|
||||
}
|
||||
|
||||
LLViewerObject* objectp = node->getObject();
|
||||
if (mObject != objectp || !objectp->mGLTFAsset)
|
||||
{
|
||||
closeFloater();
|
||||
return;
|
||||
}
|
||||
|
||||
if (mAsset != objectp->mGLTFAsset)
|
||||
{
|
||||
loadFromSelection();
|
||||
return;
|
||||
}
|
||||
|
||||
auto found = mNodeToItemMap.find(node->mSelectedGLTFNode);
|
||||
if (found != mNodeToItemMap.end())
|
||||
{
|
||||
LLFolderViewItem* itemp = found->second;
|
||||
itemp->arrangeAndSet(true, false);
|
||||
loadNodeTransforms(node->mSelectedGLTFNode);
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterGLTFAssetEditor::onFolderSelectionChanged(const std::deque<LLFolderViewItem*>& items, bool user_action)
|
||||
{
|
||||
if (items.empty())
|
||||
|
|
@ -329,10 +398,30 @@ void LLFloaterGLTFAssetEditor::onFolderSelectionChanged(const std::deque<LLFolde
|
|||
|
||||
switch (vmi->getType())
|
||||
{
|
||||
case LLGLTFFolderItem::TYPE_SCENE:
|
||||
{
|
||||
setTransformsEnabled(false);
|
||||
LLSelectMgr::getInstance()->selectObjectOnly(mObject, SELECT_ALL_TES, -1, -1);
|
||||
break;
|
||||
}
|
||||
case LLGLTFFolderItem::TYPE_NODE:
|
||||
{
|
||||
setTransformsEnabled(true);
|
||||
loadNodeTransforms(vmi->getItemId());
|
||||
LLSelectMgr::getInstance()->selectObjectOnly(mObject, SELECT_ALL_TES, vmi->getItemId(), 0);
|
||||
break;
|
||||
}
|
||||
case LLGLTFFolderItem::TYPE_MESH:
|
||||
case LLGLTFFolderItem::TYPE_SKIN:
|
||||
{
|
||||
if (item->getParent()) // should be a node
|
||||
{
|
||||
LLFolderViewFolder* parent = item->getParentFolder();
|
||||
LLGLTFFolderItem* parent_vmi = static_cast<LLGLTFFolderItem*>(parent->getViewModelItem());
|
||||
LLSelectMgr::getInstance()->selectObjectOnly(mObject, SELECT_ALL_TES, parent_vmi->getItemId(), 0);
|
||||
}
|
||||
|
||||
setTransformsEnabled(false);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
|
@ -368,6 +457,7 @@ void LLFloaterGLTFAssetEditor::loadNodeTransforms(S32 node_id)
|
|||
}
|
||||
|
||||
LL::GLTF::Node& node = mAsset->mNodes[node_id];
|
||||
node.makeTRSValid();
|
||||
|
||||
mCtrlPosX->set(node.mTranslation[0]);
|
||||
mCtrlPosY->set(node.mTranslation[1]);
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ namespace LL
|
|||
|
||||
class LLSpinCtrl;
|
||||
class LLMenuButton;
|
||||
class LLViewerObject;
|
||||
|
||||
class LLFloaterGLTFAssetEditor : public LLFloater
|
||||
{
|
||||
|
|
@ -51,6 +52,7 @@ public:
|
|||
|
||||
bool postBuild() override;
|
||||
void onOpen(const LLSD& key) override;
|
||||
void onClose(bool app_quitting) override;
|
||||
void initFolderRoot();
|
||||
|
||||
LLGLTFViewModel& getRootViewModel() { return mGLTFViewModel; }
|
||||
|
|
@ -60,6 +62,8 @@ public:
|
|||
void loadFromNode(S32 node, LLFolderViewFolder* parent);
|
||||
void loadFromSelection();
|
||||
|
||||
void dirty();
|
||||
|
||||
protected:
|
||||
void onFolderSelectionChanged(const std::deque<LLFolderViewItem*>& items, bool user_action);
|
||||
void onCommitTransform();
|
||||
|
|
@ -69,8 +73,11 @@ protected:
|
|||
void setTransformsEnabled(bool val);
|
||||
void loadNodeTransforms(S32 id);
|
||||
|
||||
void clearRoot();
|
||||
|
||||
private:
|
||||
|
||||
LLPointer<LLViewerObject> mObject;
|
||||
std::shared_ptr<LL::GLTF::Asset> mAsset;
|
||||
|
||||
// Folder view related
|
||||
|
|
@ -79,6 +86,7 @@ private:
|
|||
LLPanel* mItemListPanel = nullptr;
|
||||
LLFolderView* mFolderRoot = nullptr;
|
||||
LLScrollContainer* mScroller = nullptr;
|
||||
std::map<S32, LLFolderViewItem*> mNodeToItemMap;
|
||||
|
||||
// Transforms panel
|
||||
LLVector3 mLastEulerDegrees;
|
||||
|
|
|
|||
|
|
@ -4193,6 +4193,13 @@ U32 LLModelPreview::loadTextures(LLImportMaterial& material, void* opaque)
|
|||
LLPointer< LLViewerFetchedTexture >& tex = (*reinterpret_cast< LLPointer< LLViewerFetchedTexture > * >(material.mOpaqueData));
|
||||
|
||||
tex = LLViewerTextureManager::getFetchedTextureFromUrl("file://" + LLURI::unescape(material.mDiffuseMapFilename), FTT_LOCAL_FILE, true, LLGLTexture::BOOST_PREVIEW);
|
||||
if (tex->getDiscardLevel() < tex->getMaxDiscardLevel())
|
||||
{
|
||||
// file was loaded previosly, reload image to get potential changes
|
||||
tex->clearFetchedResults();
|
||||
}
|
||||
// Todo: might cause a crash if preview gets closed before we get the callback.
|
||||
// Use a callback list or guard callback in some way
|
||||
tex->setLoadedCallback(LLModelPreview::textureLoadedCallback, 0, true, false, opaque, NULL, false);
|
||||
tex->forceToSaveRawImage(0, F32_MAX);
|
||||
material.setDiffuseMap(tex->getID()); // record tex ID
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@
|
|||
#include "llaudioengine.h" // <FS:PP> For object deletion sound
|
||||
#include "llviewerwindow.h"
|
||||
#include "lldrawable.h"
|
||||
#include "llfloatergltfasseteditor.h"
|
||||
#include "llfloaterinspect.h"
|
||||
#include "llfloaterproperties.h" // <FS:Ansariel> Keep legacy properties floater
|
||||
#include "llfloaterreporter.h"
|
||||
|
|
@ -490,6 +491,11 @@ LLObjectSelectionHandle LLSelectMgr::selectObjectOnly(LLViewerObject* object, S3
|
|||
if (object->isSelected() ) {
|
||||
// make sure point at position is updated
|
||||
updatePointAt();
|
||||
LLSelectNode* nodep = mSelectedObjects->findNode(object);
|
||||
if (nodep)
|
||||
{
|
||||
nodep->selectGLTFNode(gltf_node, gltf_primitive, true);
|
||||
}
|
||||
gEditMenuHandler = this;
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -7461,6 +7467,12 @@ void dialog_refresh_all()
|
|||
{
|
||||
panel_task_info->dirty();
|
||||
}
|
||||
|
||||
LLFloaterGLTFAssetEditor * gltf_editor = LLFloaterReg::getTypedInstance<LLFloaterGLTFAssetEditor>("gltf_asset_editor");
|
||||
if (gltf_editor)
|
||||
{
|
||||
gltf_editor->dirty();
|
||||
}
|
||||
}
|
||||
|
||||
S32 get_family_count(LLViewerObject *parent)
|
||||
|
|
|
|||
|
|
@ -554,6 +554,9 @@ void LLGLTexMemBar::draw()
|
|||
F64 raw_image_bytes_MB = raw_image_bytes / (1024.0 * 1024.0);
|
||||
F64 saved_raw_image_bytes_MB = saved_raw_image_bytes / (1024.0 * 1024.0);
|
||||
F64 aux_raw_image_bytes_MB = aux_raw_image_bytes / (1024.0 * 1024.0);
|
||||
F64 texture_bytes_alloc = LLImageGL::getTextureBytesAllocated() / 1024.0 / 1024.0 * 1.3333f; // add 33% for mipmaps
|
||||
F64 vertex_bytes_alloc = LLVertexBuffer::getBytesAllocated() / 1024.0 / 1024.0;
|
||||
F64 render_bytes_alloc = LLRenderTarget::sBytesAllocated / 1024.0 / 1024.0;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
LLGLSUIDefault gls_ui;
|
||||
|
|
@ -583,7 +586,7 @@ void LLGLTexMemBar::draw()
|
|||
|
||||
// draw a background above first line.... no idea where the rest of the background comes from for the below text
|
||||
gGL.color4f(0.f, 0.f, 0.f, 0.25f);
|
||||
gl_rect_2d(-10, getRect().getHeight() + line_height + 1, getRect().getWidth()+2, getRect().getHeight()+2);
|
||||
gl_rect_2d(-10, getRect().getHeight() + line_height*2 + 1, getRect().getWidth()+2, getRect().getHeight()+2);
|
||||
|
||||
text = llformat("Est. Free: %d MB Sys Free: %d MB GL Tex: %d MB FBO: %d MB Bias: %.2f Cache: %.1f/%.1f MB",
|
||||
(S32)LLViewerTexture::sFreeVRAMMegabytes,
|
||||
|
|
@ -594,8 +597,8 @@ void LLGLTexMemBar::draw()
|
|||
cache_usage,
|
||||
cache_max_usage);
|
||||
// <FS:Ansariel> Texture memory bars
|
||||
//LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*6,
|
||||
LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*8,
|
||||
//LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*7,
|
||||
LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*9,
|
||||
// </FS:Ansariel>
|
||||
text_color, LLFontGL::LEFT, LLFontGL::TOP);
|
||||
|
||||
|
|
@ -603,7 +606,7 @@ void LLGLTexMemBar::draw()
|
|||
S32 bar_left = 0;
|
||||
constexpr S32 bar_width = 200;
|
||||
constexpr S32 bar_space = 10;
|
||||
S32 top = line_height*7 - 2 + v_offset;
|
||||
S32 top = line_height*8 - 2 + v_offset;
|
||||
S32 bottom = top - 6;
|
||||
S32 left = bar_left;
|
||||
S32 right = left + bar_width;
|
||||
|
|
@ -613,7 +616,7 @@ void LLGLTexMemBar::draw()
|
|||
|
||||
// VRAM Mem Bar
|
||||
text = "VRAM";
|
||||
LLFontGL::getFontMonospace()->renderUTF8(text, 0, left, v_offset + line_height*7,
|
||||
LLFontGL::getFontMonospace()->renderUTF8(text, 0, left, v_offset + line_height*8,
|
||||
text_color, LLFontGL::LEFT, LLFontGL::TOP);
|
||||
left += 35;
|
||||
right = left + bar_width;
|
||||
|
|
@ -636,7 +639,7 @@ void LLGLTexMemBar::draw()
|
|||
left = bar_left;
|
||||
// VRAM Mem Bar
|
||||
text = "CACHE";
|
||||
LLFontGL::getFontMonospace()->renderUTF8(text, 0, left, v_offset + line_height*7,
|
||||
LLFontGL::getFontMonospace()->renderUTF8(text, 0, left, v_offset + line_height*8,
|
||||
text_color, LLFontGL::LEFT, LLFontGL::TOP);
|
||||
|
||||
left += 35;
|
||||
|
|
@ -658,6 +661,14 @@ void LLGLTexMemBar::draw()
|
|||
text = llformat("Images: %d Raw: %d (%.2f MB) Saved: %d (%.2f MB) Aux: %d (%.2f MB)", image_count, raw_image_count, raw_image_bytes_MB,
|
||||
saved_raw_image_count, saved_raw_image_bytes_MB,
|
||||
aux_raw_image_count, aux_raw_image_bytes_MB);
|
||||
LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height * 7,
|
||||
text_color, LLFontGL::LEFT, LLFontGL::TOP);
|
||||
|
||||
text = llformat("Textures: %.2f MB Vertex: %.2f MB Render: %.2f MB Total: %.2f MB",
|
||||
texture_bytes_alloc,
|
||||
vertex_bytes_alloc,
|
||||
render_bytes_alloc,
|
||||
texture_bytes_alloc+vertex_bytes_alloc+render_bytes_alloc);
|
||||
LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height * 6,
|
||||
text_color, LLFontGL::LEFT, LLFontGL::TOP);
|
||||
|
||||
|
|
|
|||
|
|
@ -379,6 +379,7 @@ void LLViewerAssetStorage::queueRequestHttp(
|
|||
bool duplicate,
|
||||
bool is_priority)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
LL_DEBUGS("ViewerAsset") << "Request asset via HTTP " << uuid << " type " << LLAssetType::lookup(atype) << LL_ENDL;
|
||||
|
||||
bool with_http = true;
|
||||
|
|
|
|||
|
|
@ -4581,6 +4581,7 @@ void LLViewerObject::moveGLTFNode(S32 node_index, const LLVector3& offset)
|
|||
matMul(trans, mat, mat);
|
||||
|
||||
node.mMatrix = glm::make_mat4(mat.getF32ptr());
|
||||
node.mTRSValid = false;
|
||||
|
||||
// TODO -- only update transforms for this node and its children (or use a dirty flag)
|
||||
mGLTFAsset->updateTransforms();
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ S32 LLViewerTexture::sRawCount = 0;
|
|||
S32 LLViewerTexture::sAuxCount = 0;
|
||||
LLFrameTimer LLViewerTexture::sEvaluationTimer;
|
||||
F32 LLViewerTexture::sDesiredDiscardBias = 0.f;
|
||||
F32 LLViewerTexture::sDesiredDiscardScale = 1.1f;
|
||||
|
||||
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;
|
||||
|
|
@ -532,15 +532,18 @@ void LLViewerTexture::updateClass()
|
|||
F32 target = llmax(budget - 512.f, MIN_VRAM_BUDGET);
|
||||
sFreeVRAMMegabytes = target - used;
|
||||
|
||||
F32 over_pct = llmax((used-target) / target, 0.f);
|
||||
F32 over_pct = (used - target) / target;
|
||||
|
||||
bool is_low = over_pct > 0.f;
|
||||
|
||||
if (isSystemMemoryLow())
|
||||
{
|
||||
is_low = true;
|
||||
// System RAM is low -> ramp up discard bias over time to free memory
|
||||
if (sEvaluationTimer.getElapsedTimeF32() > MEMORY_CHECK_WAIT_TIME)
|
||||
{
|
||||
static LLCachedControl<F32> low_mem_min_discard_increment(gSavedSettings, "RenderLowMemMinDiscardIncrement", .1f);
|
||||
sDesiredDiscardBias += llmax(low_mem_min_discard_increment, over_pct);
|
||||
sDesiredDiscardBias += (F32) low_mem_min_discard_increment * (F32) gFrameIntervalSeconds;
|
||||
sEvaluationTimer.reset();
|
||||
}
|
||||
}
|
||||
|
|
@ -548,12 +551,28 @@ void LLViewerTexture::updateClass()
|
|||
{
|
||||
sDesiredDiscardBias = llmax(sDesiredDiscardBias, 1.f + over_pct);
|
||||
|
||||
if (sDesiredDiscardBias > 1.f)
|
||||
if (sDesiredDiscardBias > 1.f && over_pct < 0.f)
|
||||
{
|
||||
sDesiredDiscardBias -= gFrameIntervalSeconds * 0.01;
|
||||
}
|
||||
}
|
||||
|
||||
static bool was_low = false;
|
||||
if (is_low && !was_low)
|
||||
{
|
||||
LL_WARNS() << "Low system memory detected, emergency downrezzing off screen textures" << LL_ENDL;
|
||||
sDesiredDiscardBias = llmax(sDesiredDiscardBias, 1.5f);
|
||||
|
||||
for (auto image : gTextureList)
|
||||
{
|
||||
gTextureList.updateImageDecodePriority(image);
|
||||
}
|
||||
}
|
||||
|
||||
was_low = is_low;
|
||||
|
||||
sDesiredDiscardBias = llclamp(sDesiredDiscardBias, 1.f, 3.f);
|
||||
|
||||
LLViewerTexture::sFreezeImageUpdates = false;
|
||||
}
|
||||
|
||||
|
|
@ -634,16 +653,15 @@ void LLViewerTexture::init(bool firstinit)
|
|||
mParcelMedia = NULL;
|
||||
|
||||
memset(&mNumVolumes, 0, sizeof(U32)* LLRender::NUM_VOLUME_TEXTURE_CHANNELS);
|
||||
mFaceList[LLRender::DIFFUSE_MAP].clear();
|
||||
mFaceList[LLRender::NORMAL_MAP].clear();
|
||||
mFaceList[LLRender::SPECULAR_MAP].clear();
|
||||
mNumFaces[LLRender::DIFFUSE_MAP] =
|
||||
mNumFaces[LLRender::NORMAL_MAP] =
|
||||
mNumFaces[LLRender::SPECULAR_MAP] = 0;
|
||||
|
||||
mVolumeList[LLRender::LIGHT_TEX].clear();
|
||||
mVolumeList[LLRender::SCULPT_TEX].clear();
|
||||
|
||||
for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; i++)
|
||||
{
|
||||
mNumFaces[i] = 0;
|
||||
mFaceList[i].clear();
|
||||
}
|
||||
|
||||
mMainQueue = LL::WorkQueue::getInstance("mainloop");
|
||||
mImageQueue = LL::WorkQueue::getInstance("LLImageGL");
|
||||
}
|
||||
|
|
@ -1674,7 +1692,11 @@ void LLViewerFetchedTexture::scheduleCreateTexture()
|
|||
}
|
||||
else
|
||||
{
|
||||
gTextureList.mCreateTextureList.insert(this);
|
||||
if (!mCreatePending)
|
||||
{
|
||||
mCreatePending = true;
|
||||
gTextureList.mCreateTextureList.push(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1698,13 +1720,12 @@ void LLViewerFetchedTexture::setKnownDrawSize(S32 width, S32 height)
|
|||
|
||||
void LLViewerFetchedTexture::setDebugText(const std::string& text)
|
||||
{
|
||||
for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)
|
||||
for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i)
|
||||
{
|
||||
llassert(mNumFaces[ch] <= mFaceList[ch].size());
|
||||
for (S32 fi = 0; fi < getNumFaces(i); ++fi)
|
||||
{
|
||||
LLFace* facep = (*(getFaceList(i)))[fi];
|
||||
|
||||
for (U32 i = 0; i < mNumFaces[ch]; i++)
|
||||
{
|
||||
LLFace* facep = mFaceList[ch][i];
|
||||
if (facep)
|
||||
{
|
||||
LLDrawable* drawable = facep->getDrawable();
|
||||
|
|
@ -1717,10 +1738,15 @@ void LLViewerFetchedTexture::setDebugText(const std::string& text)
|
|||
}
|
||||
}
|
||||
|
||||
extern bool gCubeSnapshot;
|
||||
|
||||
//virtual
|
||||
void LLViewerFetchedTexture::processTextureStats()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
llassert(!gCubeSnapshot); // should only be called when the main camera is active
|
||||
llassert(!LLPipeline::sShadowRender);
|
||||
|
||||
if(mFullyLoaded)
|
||||
{
|
||||
if(mDesiredDiscardLevel > mMinDesiredDiscardLevel)//need to load more
|
||||
|
|
@ -2941,6 +2967,8 @@ void LLViewerLODTexture::processTextureStats()
|
|||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
updateVirtualSize();
|
||||
|
||||
bool did_downscale = false;
|
||||
|
||||
static LLCachedControl<bool> textures_fullres(gSavedSettings,"TextureLoadFullRes", false);
|
||||
|
||||
{ // restrict texture resolution to download based on RenderMaxTextureResolution
|
||||
|
|
@ -2998,10 +3026,7 @@ void LLViewerLODTexture::processTextureStats()
|
|||
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;
|
||||
|
|
@ -3027,10 +3052,9 @@ void LLViewerLODTexture::processTextureStats()
|
|||
//
|
||||
|
||||
S32 current_discard = getDiscardLevel();
|
||||
if (mBoostLevel < LLGLTexture::BOOST_AVATAR_BAKED &&
|
||||
current_discard >= 0)
|
||||
if (mBoostLevel < LLGLTexture::BOOST_AVATAR_BAKED)
|
||||
{
|
||||
if (current_discard < (mDesiredDiscardLevel-1) && !mForceToSaveRawImage)
|
||||
if (current_discard < mDesiredDiscardLevel && !mForceToSaveRawImage)
|
||||
{ // should scale down
|
||||
scaleDown();
|
||||
}
|
||||
|
|
@ -3050,9 +3074,6 @@ 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)
|
||||
|
|
@ -3061,14 +3082,22 @@ void LLViewerLODTexture::processTextureStats()
|
|||
}
|
||||
}
|
||||
|
||||
extern LLGLSLShader gCopyProgram;
|
||||
|
||||
bool LLViewerLODTexture::scaleDown()
|
||||
{
|
||||
if (mGLTexturep.isNull())
|
||||
if (mGLTexturep.isNull() || !mGLTexturep->getHasGLTexture())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return mGLTexturep->scaleDown(mDesiredDiscardLevel);
|
||||
if (!mDownScalePending)
|
||||
{
|
||||
mDownScalePending = true;
|
||||
gTextureList.mDownScaleQueue.push(this);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
#include "llmetricperformancetester.h"
|
||||
#include "httpcommon.h"
|
||||
#include "workqueue.h"
|
||||
#include "gltf/common.h"
|
||||
|
||||
#include <map>
|
||||
#include <list>
|
||||
|
|
@ -108,7 +109,6 @@ public:
|
|||
DYNAMIC_TEXTURE,
|
||||
FETCHED_TEXTURE,
|
||||
LOD_TEXTURE,
|
||||
ATLAS_TEXTURE,
|
||||
INVALID_TEXTURE_TYPE
|
||||
};
|
||||
|
||||
|
|
@ -181,6 +181,15 @@ public:
|
|||
LLViewerMediaTexture* getParcelMedia() const { return mParcelMedia;}
|
||||
|
||||
/*virtual*/ void updateBindStatsForTester() ;
|
||||
|
||||
struct MaterialEntry
|
||||
{
|
||||
S32 mIndex = LL::GLTF::INVALID_INDEX;
|
||||
std::shared_ptr<LL::GLTF::Asset> mAsset;
|
||||
};
|
||||
typedef std::vector<MaterialEntry> material_list_t;
|
||||
material_list_t mMaterialList; // reverse pointer pointing to LL::GLTF::Materials using this image as texture
|
||||
|
||||
protected:
|
||||
void cleanup() ;
|
||||
void init(bool firstinit) ;
|
||||
|
|
@ -222,7 +231,6 @@ public:
|
|||
static S32 sAuxCount;
|
||||
static LLFrameTimer sEvaluationTimer;
|
||||
static F32 sDesiredDiscardBias;
|
||||
static F32 sDesiredDiscardScale;
|
||||
static S32 sMaxSculptRez ;
|
||||
static U32 sMinLargeImageSize ;
|
||||
static U32 sMaxSmallImageSize ;
|
||||
|
|
@ -445,6 +453,9 @@ public:
|
|||
|
||||
/*virtual*/bool isActiveFetching() override; //is actively in fetching by the fetching pipeline.
|
||||
|
||||
bool mCreatePending = false; // if true, this is in gTextureList.mCreateTextureList
|
||||
mutable bool mDownScalePending = false; // if true, this is in gTextureList.mDownScaleQueue
|
||||
|
||||
// <FS:Techwolf Lupindo> texture comment decoder
|
||||
std::map<std::string,std::string> mComment;
|
||||
// </FS:Techwolf Lupindo>
|
||||
|
|
@ -460,11 +471,6 @@ private:
|
|||
|
||||
void saveRawImage() ;
|
||||
|
||||
//for atlas
|
||||
void resetFaceAtlas() ;
|
||||
void invalidateAtlas(bool rebuild_geom) ;
|
||||
bool insertToAtlas() ;
|
||||
|
||||
private:
|
||||
bool mFullyLoaded;
|
||||
bool mInDebug;
|
||||
|
|
@ -579,9 +585,10 @@ public:
|
|||
/*virtual*/ void processTextureStats();
|
||||
bool isUpdateFrozen() ;
|
||||
|
||||
bool scaleDown();
|
||||
|
||||
private:
|
||||
void init(bool firstinit) ;
|
||||
bool scaleDown() ;
|
||||
|
||||
private:
|
||||
F32 mDiscardVirtualSize; // Virtual size used to calculate desired discard
|
||||
|
|
|
|||
|
|
@ -73,6 +73,8 @@ U32 LLViewerTextureList::sNumFastCacheReads = 0;
|
|||
|
||||
LLViewerTextureList gTextureList;
|
||||
|
||||
extern LLGLSLShader gCopyProgram;
|
||||
|
||||
ETexListType get_element_type(S32 priority)
|
||||
{
|
||||
return (priority == LLViewerFetchedTexture::BOOST_ICON || priority == LLViewerFetchedTexture::BOOST_THUMBNAIL) ? TEX_LIST_SCALE : TEX_LIST_STANDARD;
|
||||
|
|
@ -360,8 +362,11 @@ void LLViewerTextureList::shutdown()
|
|||
mCallbackList.clear();
|
||||
|
||||
// Flush all of the references
|
||||
mLoadingStreamList.clear();
|
||||
mCreateTextureList.clear();
|
||||
while (!mCreateTextureList.empty())
|
||||
{
|
||||
mCreateTextureList.front()->mCreatePending = false;
|
||||
mCreateTextureList.pop();
|
||||
}
|
||||
mFastCacheList.clear();
|
||||
|
||||
mUUIDMap.clear();
|
||||
|
|
@ -910,14 +915,6 @@ void LLViewerTextureList::clearFetchingRequests()
|
|||
}
|
||||
}
|
||||
|
||||
static void touch_texture(LLViewerFetchedTexture* tex, F32 vsize)
|
||||
{
|
||||
if (tex)
|
||||
{
|
||||
tex->addTextureStats(vsize);
|
||||
}
|
||||
}
|
||||
|
||||
extern bool gCubeSnapshot;
|
||||
|
||||
void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imagep)
|
||||
|
|
@ -934,15 +931,21 @@ void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imag
|
|||
static LLCachedControl<F32> texture_scale_min(gSavedSettings, "TextureScaleMinAreaFactor", 0.04f);
|
||||
static LLCachedControl<F32> texture_scale_max(gSavedSettings, "TextureScaleMaxAreaFactor", 25.f);
|
||||
|
||||
if (imagep->getType() == LLViewerTexture::LOD_TEXTURE && imagep->getBoostLevel() == LLViewerTexture::BOOST_NONE)
|
||||
{ // reset max virtual size for unboosted LOD_TEXTURES
|
||||
// this is an alternative to decaying mMaxVirtualSize over time
|
||||
// that keeps textures from continously downrezzing and uprezzing in the background
|
||||
imagep->mMaxVirtualSize = 0.f;
|
||||
}
|
||||
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE
|
||||
{
|
||||
for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i)
|
||||
{
|
||||
for (S32 fi = 0; fi < imagep->getNumFaces(i); ++fi)
|
||||
{
|
||||
LLFace* face = (*(imagep->getFaceList(i)))[fi];
|
||||
|
||||
if (face && face->getViewerObject() && face->getTextureEntry())
|
||||
if (face && face->getViewerObject())
|
||||
{
|
||||
F32 radius;
|
||||
F32 cos_angle_to_view_dir;
|
||||
|
|
@ -958,32 +961,35 @@ void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imag
|
|||
// Maximum usage examples: huge chunk of terrain repeats texture
|
||||
const LLTextureEntry* te = face->getTextureEntry();
|
||||
F32 min_scale = te ? llmin(fabsf(te->getScaleS()), fabsf(te->getScaleT())) : 1.f;
|
||||
min_scale = llclamp(min_scale*min_scale, texture_scale_min(), texture_scale_max());
|
||||
|
||||
min_scale = llclamp(min_scale * min_scale, texture_scale_min(), texture_scale_max());
|
||||
vsize /= min_scale;
|
||||
|
||||
// if bias is > 2, apply to on-screen textures as well
|
||||
bool apply_bias = LLViewerTexture::sDesiredDiscardBias > 2.f;
|
||||
|
||||
// apply bias to off screen objects or objects that are small on screen all the time
|
||||
if (!in_frustum || !face->getDrawable()->isVisible() || face->getImportanceToCamera() < bias_unimportant_threshold)
|
||||
{ // further reduce by discard bias when off screen or occluded
|
||||
vsize /= LLViewerTexture::sDesiredDiscardBias;
|
||||
apply_bias = true;
|
||||
}
|
||||
// if a GLTF material is present, ignore that face
|
||||
// as far as this texture stats go, but update the GLTF material
|
||||
// stats
|
||||
LLFetchedGLTFMaterial* mat = te ? (LLFetchedGLTFMaterial*)te->getGLTFRenderMaterial() : nullptr;
|
||||
llassert(mat == nullptr || dynamic_cast<LLFetchedGLTFMaterial*>(te->getGLTFRenderMaterial()) != nullptr);
|
||||
if (mat)
|
||||
|
||||
if (apply_bias)
|
||||
{
|
||||
touch_texture(mat->mBaseColorTexture, vsize);
|
||||
touch_texture(mat->mNormalTexture, vsize);
|
||||
touch_texture(mat->mMetallicRoughnessTexture, vsize);
|
||||
touch_texture(mat->mEmissiveTexture, vsize);
|
||||
F32 bias = powf(4, LLViewerTexture::sDesiredDiscardBias - 1.f);
|
||||
bias = llround(bias);
|
||||
vsize /= bias;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
imagep->addTextureStats(vsize);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// make sure to addTextureStats for any spotlights that are using this texture
|
||||
for (S32 vi = 0; vi < imagep->getNumVolumes(LLRender::LIGHT_TEX); ++vi)
|
||||
{
|
||||
LLVOVolume* volume = (*imagep->getVolumeList(LLRender::LIGHT_TEX))[vi];
|
||||
volume->updateSpotLightPriority();
|
||||
}
|
||||
|
||||
//imagep->setDebugText(llformat("%.3f - %d", sqrtf(imagep->getMaxVirtualSize()), imagep->getBoostLevel()));
|
||||
|
|
@ -1079,22 +1085,65 @@ F32 LLViewerTextureList::updateImagesCreateTextures(F32 max_time)
|
|||
//
|
||||
|
||||
LLTimer create_timer;
|
||||
image_list_t::iterator enditer = mCreateTextureList.begin();
|
||||
for (image_list_t::iterator iter = mCreateTextureList.begin();
|
||||
iter != mCreateTextureList.end();)
|
||||
{
|
||||
image_list_t::iterator curiter = iter++;
|
||||
enditer = iter;
|
||||
LLViewerFetchedTexture *imagep = *curiter;
|
||||
imagep->createTexture();
|
||||
imagep->postCreateTexture();
|
||||
|
||||
if (create_timer.getElapsedTimeF32() > max_time)
|
||||
if (!mDownScaleQueue.empty() && gPipeline.mDownResMap.isComplete())
|
||||
{
|
||||
// just in case we downres textures, bind downresmap and copy program
|
||||
gPipeline.mDownResMap.bindTarget();
|
||||
gCopyProgram.bind();
|
||||
gPipeline.mScreenTriangleVB->setBuffer();
|
||||
|
||||
// give time to downscaling first -- if mDownScaleQueue is not empty, we're running out of memory and need
|
||||
// to free up memory by discarding off screen textures quickly
|
||||
|
||||
// do at least 5 and make sure we don't get too far behind even if it violates
|
||||
// the time limit. If we don't downscale quickly the viewer will hit swap and may
|
||||
// freeze.
|
||||
S32 min_count = (S32)mCreateTextureList.size() / 20 + 5;
|
||||
|
||||
while (!mDownScaleQueue.empty())
|
||||
{
|
||||
LLViewerFetchedTexture* image = mDownScaleQueue.front();
|
||||
llassert(image->mDownScalePending);
|
||||
|
||||
LLImageGL* img = image->getGLTexture();
|
||||
if (img && img->getHasGLTexture())
|
||||
{
|
||||
img->scaleDown(image->getDesiredDiscardLevel());
|
||||
}
|
||||
|
||||
image->mDownScalePending = false;
|
||||
mDownScaleQueue.pop();
|
||||
|
||||
if (create_timer.getElapsedTimeF32() > max_time && --min_count <= 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
gCopyProgram.unbind();
|
||||
gPipeline.mDownResMap.flush();
|
||||
}
|
||||
|
||||
// do at least 5 and make sure we don't get too far behind even if it violates
|
||||
// the time limit. Textures pending creation have a copy of their texture data
|
||||
// in system memory, so we don't want to let them pile up.
|
||||
S32 min_count = (S32) mCreateTextureList.size() / 20 + 5;
|
||||
|
||||
while (!mCreateTextureList.empty())
|
||||
{
|
||||
LLViewerFetchedTexture *imagep = mCreateTextureList.front();
|
||||
llassert(imagep->mCreatePending);
|
||||
imagep->createTexture();
|
||||
imagep->postCreateTexture();
|
||||
imagep->mCreatePending = false;
|
||||
mCreateTextureList.pop();
|
||||
|
||||
if (create_timer.getElapsedTimeF32() > max_time && --min_count <= 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
mCreateTextureList.erase(mCreateTextureList.begin(), enditer);
|
||||
return create_timer.getElapsedTimeF32();
|
||||
}
|
||||
|
||||
|
|
@ -1140,7 +1189,10 @@ void LLViewerTextureList::forceImmediateUpdate(LLViewerFetchedTexture* imagep)
|
|||
removeImageFromList(imagep);
|
||||
}
|
||||
|
||||
if (!gCubeSnapshot)
|
||||
{ // never call processTextureStats in a cube snapshot
|
||||
imagep->processTextureStats();
|
||||
}
|
||||
imagep->sMaxVirtualSize = LLViewerFetchedTexture::sMaxVirtualSize;
|
||||
addImageToList(imagep);
|
||||
|
||||
|
|
@ -1150,6 +1202,7 @@ void LLViewerTextureList::forceImmediateUpdate(LLViewerFetchedTexture* imagep)
|
|||
F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
|
||||
|
||||
typedef std::vector<LLPointer<LLViewerFetchedTexture> > entries_list_t;
|
||||
entries_list_t entries;
|
||||
|
||||
|
|
|
|||
|
|
@ -148,12 +148,13 @@ public:
|
|||
void clearFetchingRequests();
|
||||
void setDebugFetching(LLViewerFetchedTexture* tex, S32 debug_level);
|
||||
|
||||
private:
|
||||
// do some book keeping on the specified texture
|
||||
// - updates decode priority
|
||||
// - updates desired discard level
|
||||
// - cleans up textures that haven't been referenced in awhile
|
||||
void updateImageDecodePriority(LLViewerFetchedTexture* imagep);
|
||||
|
||||
private:
|
||||
F32 updateImagesCreateTextures(F32 max_time);
|
||||
F32 updateImagesFetchTextures(F32 max_time);
|
||||
void updateImagesUpdateStats();
|
||||
|
|
@ -217,8 +218,14 @@ private: // PoundLife - Improved Object Inspect
|
|||
|
||||
public:
|
||||
typedef std::unordered_set<LLPointer<LLViewerFetchedTexture> > image_list_t;
|
||||
image_list_t mLoadingStreamList;
|
||||
image_list_t mCreateTextureList;
|
||||
typedef std::queue<LLPointer<LLViewerFetchedTexture> > image_queue_t;
|
||||
|
||||
// images that have been loaded but are waiting to be uploaded to GL
|
||||
image_queue_t mCreateTextureList;
|
||||
|
||||
// images that must be downscaled quickly so we don't run out of memory
|
||||
image_queue_t mDownScaleQueue;
|
||||
|
||||
image_list_t mCallbackList;
|
||||
image_list_t mFastCacheList;
|
||||
|
||||
|
|
|
|||
|
|
@ -461,6 +461,9 @@ void LLVOGrass::plantBlades()
|
|||
face->setVertexBuffer(NULL);
|
||||
face->setTEOffset(0);
|
||||
face->mCenterLocal = mPosition + mRegionp->getOriginAgent();
|
||||
const LLVector4a* ext = mDrawable->getSpatialExtents();
|
||||
face->mExtents[0] = ext[0];
|
||||
face->mExtents[1] = ext[1];
|
||||
}
|
||||
|
||||
mDepth = (face->mCenterLocal - LLViewerCamera::getInstance()->getOrigin())*LLViewerCamera::getInstance()->getAtAxis();
|
||||
|
|
|
|||
|
|
@ -472,9 +472,7 @@ void LLVOTree::updateTextures()
|
|||
{
|
||||
setDebugText(llformat("%4.0f", (F32) sqrt(mPixelArea)));
|
||||
}
|
||||
mTreeImagep->addTextureStats(mPixelArea);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -490,7 +488,7 @@ LLDrawable* LLVOTree::createDrawable(LLPipeline *pipeline)
|
|||
// Just a placeholder for an actual object...
|
||||
LLFace *facep = mDrawable->addFace(poolp, mTreeImagep);
|
||||
facep->setSize(1, 3);
|
||||
|
||||
facep->setTexture(LLRender::DIFFUSE_MAP, mTreeImagep);
|
||||
updateRadius();
|
||||
|
||||
return mDrawable;
|
||||
|
|
@ -1180,6 +1178,10 @@ void LLVOTree::updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)
|
|||
LLVector4a pos;
|
||||
pos.load3(center.mV);
|
||||
mDrawable->setPositionGroup(pos);
|
||||
|
||||
LLFace* facep = mDrawable->getFace(0);
|
||||
facep->mExtents[0] = newMin;
|
||||
facep->mExtents[1] = newMax;
|
||||
}
|
||||
|
||||
bool LLVOTree::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, bool pick_transparent, bool pick_rigged, bool pick_unselectable, S32 *face_hitp,
|
||||
|
|
|
|||
|
|
@ -6072,18 +6072,23 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
|
|||
{
|
||||
continue;
|
||||
}
|
||||
#if 0
|
||||
#if LL_RELEASE_WITH_DEBUG_INFO
|
||||
const LLUUID pbr_id( "49c88210-7238-2a6b-70ac-92d4f35963cf" );
|
||||
const LLUUID obj_id( vobj->getID() );
|
||||
bool is_pbr = (obj_id == pbr_id);
|
||||
#else
|
||||
bool is_pbr = false;
|
||||
#endif
|
||||
#else
|
||||
LLGLTFMaterial *gltf_mat = facep->getTextureEntry()->getGLTFRenderMaterial();
|
||||
|
||||
LLFetchedGLTFMaterial *gltf_mat = (LLFetchedGLTFMaterial*) facep->getTextureEntry()->getGLTFRenderMaterial();
|
||||
bool is_pbr = gltf_mat != nullptr;
|
||||
#endif
|
||||
|
||||
if (is_pbr)
|
||||
{
|
||||
// tell texture streaming system to ignore blinn-phong textures
|
||||
facep->setTexture(LLRender::DIFFUSE_MAP, nullptr);
|
||||
facep->setTexture(LLRender::NORMAL_MAP, nullptr);
|
||||
facep->setTexture(LLRender::SPECULAR_MAP, nullptr);
|
||||
|
||||
// let texture streaming system know about PBR textures
|
||||
facep->setTexture(LLRender::BASECOLOR_MAP, gltf_mat->mBaseColorTexture);
|
||||
facep->setTexture(LLRender::GLTF_NORMAL_MAP, gltf_mat->mNormalTexture);
|
||||
facep->setTexture(LLRender::METALLIC_ROUGHNESS_MAP, gltf_mat->mMetallicRoughnessTexture);
|
||||
facep->setTexture(LLRender::EMISSIVE_MAP, gltf_mat->mEmissiveTexture);
|
||||
}
|
||||
|
||||
//ALWAYS null out vertex buffer on rebuild -- if the face lands in a render
|
||||
// batch, it will recover its vertex buffer reference from the spatial group
|
||||
|
|
|
|||
|
|
@ -961,6 +961,10 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
|
|||
const U32 post_color_fmt = post_hdr ? GL_RGBA16F : GL_RGBA;
|
||||
mPostMap.allocate(resX, resY, post_color_fmt);
|
||||
|
||||
// used to scale down textures
|
||||
// See LLViwerTextureList::updateImagesCreateTextures and LLImageGL::scaleDown
|
||||
mDownResMap.allocate(4, 4, GL_RGBA);
|
||||
|
||||
//HACK make screenbuffer allocations start failing after 30 seconds
|
||||
if (gSavedSettings.getBOOL("SimulateFBOFailure"))
|
||||
{
|
||||
|
|
@ -1221,6 +1225,8 @@ void LLPipeline::releaseGLBuffers()
|
|||
|
||||
mPostMap.release();
|
||||
|
||||
mDownResMap.release();
|
||||
|
||||
for (U32 i = 0; i < 3; i++)
|
||||
{
|
||||
mGlow[i].release();
|
||||
|
|
|
|||
|
|
@ -741,6 +741,9 @@ public:
|
|||
// tonemapped and gamma corrected render ready for post
|
||||
LLRenderTarget mPostMap;
|
||||
|
||||
// downres scratch space for GPU downscaling of textures
|
||||
LLRenderTarget mDownResMap;
|
||||
|
||||
LLCullResult mSky;
|
||||
LLCullResult mReflectedObjects;
|
||||
LLCullResult mRefractedObjects;
|
||||
|
|
|
|||
Loading…
Reference in New Issue