# Conflicts:
#	indra/llrender/llglslshader.cpp
#	indra/llrender/llrender.cpp
#	indra/llrender/llvertexbuffer.cpp
#	indra/llrender/llvertexbuffer.h
#	indra/newview/lldrawpool.cpp
#	indra/newview/lldrawpoolbump.cpp
#	indra/newview/lldrawpoolmaterials.cpp
#	indra/newview/llfilepicker.cpp
#	indra/newview/llviewerdisplay.cpp
#	indra/newview/pipeline.cpp
#	indra/newview/pipeline.h
master
Ansariel 2023-01-12 12:08:46 +01:00
commit 75180c8746
61 changed files with 1969 additions and 2609 deletions

View File

@ -98,6 +98,29 @@ LLGLTFMaterial& LLGLTFMaterial::operator=(const LLGLTFMaterial& rhs)
return *this;
}
bool LLGLTFMaterial::operator==(const LLGLTFMaterial& rhs) const
{
return mBaseColorId == rhs.mBaseColorId &&
mNormalId == rhs.mNormalId &&
mMetallicRoughnessId == rhs.mMetallicRoughnessId &&
mEmissiveId == rhs.mEmissiveId &&
mBaseColor == rhs.mBaseColor &&
mEmissiveColor == rhs.mEmissiveColor &&
mMetallicFactor == rhs.mMetallicFactor &&
mRoughnessFactor == rhs.mRoughnessFactor &&
mAlphaCutoff == rhs.mAlphaCutoff &&
mDoubleSided == rhs.mDoubleSided &&
mAlphaMode == rhs.mAlphaMode &&
mTextureTransform == rhs.mTextureTransform &&
mOverrideDoubleSided == rhs.mOverrideDoubleSided &&
mOverrideAlphaMode == rhs.mOverrideAlphaMode;
}
bool LLGLTFMaterial::fromJSON(const std::string& json, std::string& warn_msg, std::string& error_msg)
{
LL_PROFILE_ZONE_SCOPED;
@ -365,6 +388,28 @@ void LLGLTFMaterial::writeToTexture(tinygltf::Model& model, T& texture_info, Tex
texture_info.extensions[GLTF_FILE_EXTENSION_TRANSFORM] = tinygltf::Value(transform_map);
}
bool LLGLTFMaterial::setBaseMaterial()
{
const LLGLTFMaterial old_override = *this;
*this = sDefault;
setBaseMaterial(old_override);
return *this != old_override;
}
bool LLGLTFMaterial::isClearedForBaseMaterial()
{
LLGLTFMaterial cleared_override = sDefault;
cleared_override.setBaseMaterial(*this);
return *this == cleared_override;
}
// For material overrides only. Copies transforms from the old override.
void LLGLTFMaterial::setBaseMaterial(const LLGLTFMaterial& old_override_mat)
{
mTextureTransform = old_override_mat.mTextureTransform;
}
// static
void LLGLTFMaterial::hackOverrideUUID(LLUUID& id)
{
@ -646,11 +691,6 @@ void LLGLTFMaterial::applyOverride(const LLGLTFMaterial& override_mat)
mTextureTransform[i].mScale = override_mat.mTextureTransform[i].mScale;
}
if (override_mat.mTextureTransform[i].mScale != getDefaultTextureScale())
{
mTextureTransform[i].mScale = override_mat.mTextureTransform[i].mScale;
}
if (override_mat.mTextureTransform[i].mRotation != getDefaultTextureRotation())
{
mTextureTransform[i].mRotation = override_mat.mTextureTransform[i].mRotation;

View File

@ -71,6 +71,8 @@ public:
LLGLTFMaterial(const LLGLTFMaterial& rhs);
LLGLTFMaterial& operator=(const LLGLTFMaterial& rhs);
bool operator==(const LLGLTFMaterial& rhs) const;
bool operator!=(const LLGLTFMaterial& rhs) const { return !(*this == rhs); }
LLUUID mBaseColorId;
LLUUID mNormalId;
@ -101,7 +103,6 @@ public:
md5.finalize();
LLUUID id;
md5.raw_digest(id.mData);
// *TODO: Hash the overrides
return id;
}
@ -181,6 +182,12 @@ public:
void applyOverride(const LLGLTFMaterial& override_mat);
// For material overrides only. Clears most properties to
// default/fallthrough, but preserves the transforms.
bool setBaseMaterial();
// True if setBaseMaterial() was just called
bool isClearedForBaseMaterial();
private:
template<typename T>
@ -188,5 +195,7 @@ private:
template<typename T>
void writeToTexture(tinygltf::Model& model, T& texture_info, TextureInfo texture_info_id, const LLUUID& texture_id) const;
void setBaseMaterial(const LLGLTFMaterial& old_override_mat);
};

View File

@ -514,15 +514,15 @@ S32 LLTextureEntry::setBumpShiny(U8 bump_shiny)
return TEM_CHANGE_NONE;
}
void LLTextureEntry::setGLTFMaterial(LLGLTFMaterial* material)
void LLTextureEntry::setGLTFMaterial(LLGLTFMaterial* material, bool local_origin)
{
if (material != getGLTFMaterial())
{
// assert on precondtion:
// whether or not mGLTFMaterial is null, any existing override should have been nulled out
// whether or not mGLTFMaterial is null, any existing override should have been cleared
// before calling setGLTFMaterial
// NOTE: if you're hitting this assert, try to make sure calling code is using LLViewerObject::setRenderMaterialID
llassert(getGLTFMaterialOverride() == nullptr);
llassert(!local_origin || getGLTFMaterialOverride() == nullptr || getGLTFMaterialOverride()->isClearedForBaseMaterial());
mGLTFMaterial = material;
if (mGLTFMaterial == nullptr)
@ -538,6 +538,27 @@ void LLTextureEntry::setGLTFMaterialOverride(LLGLTFMaterial* mat)
mGLTFMaterialOverrides = mat;
}
S32 LLTextureEntry::setBaseMaterial()
{
S32 changed = TEM_CHANGE_NONE;
if (mGLTFMaterialOverrides)
{
if (mGLTFMaterialOverrides->setBaseMaterial())
{
changed = TEM_CHANGE_TEXTURE;
}
if (LLGLTFMaterial::sDefault == *mGLTFMaterialOverrides)
{
mGLTFMaterialOverrides = nullptr;
changed = TEM_CHANGE_TEXTURE;
}
}
return changed;
}
LLGLTFMaterial* LLTextureEntry::getGLTFRenderMaterial() const
{
if (mGLTFRenderMaterial.notNull())
@ -545,7 +566,7 @@ LLGLTFMaterial* LLTextureEntry::getGLTFRenderMaterial() const
return mGLTFRenderMaterial;
}
llassert(getGLTFMaterialOverride() == nullptr);
llassert(getGLTFMaterialOverride() == nullptr || getGLTFMaterialOverride()->isClearedForBaseMaterial());
return getGLTFMaterial();
}

View File

@ -195,12 +195,16 @@ public:
enum { MF_NONE = 0x0, MF_HAS_MEDIA = 0x1 };
// GLTF asset
void setGLTFMaterial(LLGLTFMaterial* material);
void setGLTFMaterial(LLGLTFMaterial* material, bool local_origin = true);
LLGLTFMaterial* getGLTFMaterial() const { return mGLTFMaterial; }
// GLTF override
LLGLTFMaterial* getGLTFMaterialOverride() const { return mGLTFMaterialOverrides; }
void setGLTFMaterialOverride(LLGLTFMaterial* mat);
// Clear most overrides so the render material better matches the material
// ID (preserve transforms). If the overrides become passthrough, set the
// overrides to nullptr.
S32 setBaseMaterial();
// GLTF render material
// nuanced behavior here -- if there is no render material, fall back to getGLTFMaterial, but ONLY for the getter, not the setter

View File

@ -2416,7 +2416,7 @@ void LLGLState::checkStates(const std::string& msg)
BOOL error = FALSE;
if (src != GL_SRC_ALPHA || dst != GL_ONE_MINUS_SRC_ALPHA)
/*if (src != GL_SRC_ALPHA || dst != GL_ONE_MINUS_SRC_ALPHA)
{
if (gDebugSession)
{
@ -2427,7 +2427,7 @@ void LLGLState::checkStates(const std::string& msg)
{
LL_GL_ERRS << "Blend function corrupted: " << std::hex << src << " " << std::hex << dst << " " << msg << std::dec << LL_ENDL;
}
}
}*/
for (boost::unordered_map<LLGLenum, LLGLboolean>::iterator iter = sStateMap.begin();
iter != sStateMap.end(); ++iter)

File diff suppressed because it is too large Load Diff

View File

@ -1,25 +1,25 @@
/**
/**
* @file llglslshader.h
* @brief GLSL shader wrappers
*
* $LicenseInfo:firstyear=2001&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$
*/
@ -35,36 +35,36 @@
class LLShaderFeatures
{
public:
bool atmosphericHelpers;
bool calculatesLighting;
bool calculatesAtmospherics;
bool hasLighting; // implies no transport (it's possible to have neither though)
bool isAlphaLighting; // indicates lighting shaders need not be linked in (lighting performed directly in alpha shader to match deferred lighting functions)
bool isShiny;
bool isFullbright; // implies no lighting
bool isSpecular;
bool hasWaterFog; // implies no gamma
bool hasTransport; // implies no lighting (it's possible to have neither though)
bool hasSkinning;
bool hasObjectSkinning;
bool hasAtmospherics;
bool hasGamma;
bool atmosphericHelpers;
bool calculatesLighting;
bool calculatesAtmospherics;
bool hasLighting; // implies no transport (it's possible to have neither though)
bool isAlphaLighting; // indicates lighting shaders need not be linked in (lighting performed directly in alpha shader to match deferred lighting functions)
bool isShiny;
bool isFullbright; // implies no lighting
bool isSpecular;
bool hasWaterFog; // implies no gamma
bool hasTransport; // implies no lighting (it's possible to have neither though)
bool hasSkinning;
bool hasObjectSkinning;
bool hasAtmospherics;
bool hasGamma;
bool hasShadows;
bool hasAmbientOcclusion;
bool hasSrgb;
bool hasSrgb;
bool encodesNormal; // include: shaders\class1\environment\encodeNormF.glsl
bool isDeferred;
bool hasScreenSpaceReflections;
bool hasIndirect;
S32 mIndexedTextureChannels;
bool disableTextureIndex;
bool hasAlphaMask;
S32 mIndexedTextureChannels;
bool disableTextureIndex;
bool hasAlphaMask;
bool hasReflectionProbes = false;
bool attachNothing;
bool attachNothing;
// char numLights;
LLShaderFeatures();
// char numLights;
LLShaderFeatures();
};
// ============= Structure for caching shader uniforms ===============
@ -108,7 +108,7 @@ public:
{
mVectors.push_back({ index, value });
}
void uniform4fv(S32 index, const F32* value)
{
mVectors.push_back({ index, LLVector4(value) });
@ -125,7 +125,7 @@ public:
}
void apply(LLGLSLShader* shader);
std::vector<IntSetting> mIntegers;
std::vector<FloatSetting> mFloats;
@ -138,184 +138,182 @@ public:
// NOTE: Keep gShaderConsts and LLGLSLShader::ShaderConsts_e in sync!
enum eShaderConsts
{
SHADER_CONST_CLOUD_MOON_DEPTH
SHADER_CONST_CLOUD_MOON_DEPTH
, SHADER_CONST_STAR_DEPTH
, NUM_SHADER_CONSTS
};
// enum primarily used to control application sky settings uniforms
typedef enum
{
SG_DEFAULT = 0, // not sky or water specific
SG_SKY, //
SG_WATER,
typedef enum
{
SG_DEFAULT = 0, // not sky or water specific
SG_SKY, //
SG_WATER,
SG_ANY,
SG_COUNT
} eGroup;
static std::set<LLGLSLShader*> sInstances;
static bool sProfileEnabled;
} eGroup;
LLGLSLShader();
~LLGLSLShader();
static std::set<LLGLSLShader*> sInstances;
static bool sProfileEnabled;
static GLuint sCurBoundShader;
static LLGLSLShader* sCurBoundShaderPtr;
static S32 sIndexedTextureChannels;
LLGLSLShader();
~LLGLSLShader();
static void initProfile();
static void finishProfile(bool emit_report = true);
static GLuint sCurBoundShader;
static LLGLSLShader* sCurBoundShaderPtr;
static S32 sIndexedTextureChannels;
static void startProfile();
static void stopProfile(U32 count, U32 mode);
static void initProfile();
static void finishProfile(bool emit_report = true);
void unload();
void clearStats();
void dumpStats();
void placeProfileQuery();
void readProfileQuery(U32 count, U32 mode);
static void startProfile();
static void stopProfile();
BOOL createShader(std::vector<LLStaticHashedString> * attributes,
std::vector<LLStaticHashedString> * uniforms,
U32 varying_count = 0,
const char** varyings = NULL);
void unload();
void clearStats();
void dumpStats();
void placeProfileQuery();
void readProfileQuery();
BOOL createShader(std::vector<LLStaticHashedString>* attributes,
std::vector<LLStaticHashedString>* uniforms,
U32 varying_count = 0,
const char** varyings = NULL);
BOOL attachFragmentObject(std::string object);
BOOL attachVertexObject(std::string object);
void attachObject(GLuint object);
void attachObjects(GLuint* objects = NULL, S32 count = 0);
BOOL mapAttributes(const std::vector<LLStaticHashedString> * attributes);
BOOL mapUniforms(const std::vector<LLStaticHashedString> *);
void mapUniform(GLint index, const std::vector<LLStaticHashedString> *);
void uniform1i(U32 index, GLint i);
void uniform1f(U32 index, GLfloat v);
void attachObject(GLuint object);
void attachObjects(GLuint* objects = NULL, S32 count = 0);
BOOL mapAttributes(const std::vector<LLStaticHashedString>* attributes);
BOOL mapUniforms(const std::vector<LLStaticHashedString>*);
void mapUniform(GLint index, const std::vector<LLStaticHashedString>*);
void uniform1i(U32 index, GLint i);
void uniform1f(U32 index, GLfloat v);
void fastUniform1f(U32 index, GLfloat v);
void uniform2f(U32 index, GLfloat x, GLfloat y);
void uniform3f(U32 index, GLfloat x, GLfloat y, GLfloat z);
void uniform4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
void uniform1iv(U32 index, U32 count, const GLint* i);
void uniform2f(U32 index, GLfloat x, GLfloat y);
void uniform3f(U32 index, GLfloat x, GLfloat y, GLfloat z);
void uniform4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
void uniform1iv(U32 index, U32 count, const GLint* i);
void uniform4iv(U32 index, U32 count, const GLint* i);
void uniform1fv(U32 index, U32 count, const GLfloat* v);
void uniform2fv(U32 index, U32 count, const GLfloat* v);
void uniform3fv(U32 index, U32 count, const GLfloat* v);
void uniform4fv(U32 index, U32 count, const GLfloat* v);
void uniform2i(const LLStaticHashedString& uniform, GLint i, GLint j);
void uniformMatrix2fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v);
void uniformMatrix3fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v);
void uniformMatrix3x4fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v);
void uniformMatrix4fv(U32 index, U32 count, GLboolean transpose, const GLfloat *v);
void uniform1i(const LLStaticHashedString& uniform, GLint i);
void uniform1fv(U32 index, U32 count, const GLfloat* v);
void uniform2fv(U32 index, U32 count, const GLfloat* v);
void uniform3fv(U32 index, U32 count, const GLfloat* v);
void uniform4fv(U32 index, U32 count, const GLfloat* v);
void uniform2i(const LLStaticHashedString& uniform, GLint i, GLint j);
void uniformMatrix2fv(U32 index, U32 count, GLboolean transpose, const GLfloat* v);
void uniformMatrix3fv(U32 index, U32 count, GLboolean transpose, const GLfloat* v);
void uniformMatrix3x4fv(U32 index, U32 count, GLboolean transpose, const GLfloat* v);
void uniformMatrix4fv(U32 index, U32 count, GLboolean transpose, const GLfloat* v);
void uniform1i(const LLStaticHashedString& uniform, GLint i);
void uniform1iv(const LLStaticHashedString& uniform, U32 count, const GLint* v);
void uniform4iv(const LLStaticHashedString& uniform, U32 count, const GLint* v);
void uniform1f(const LLStaticHashedString& uniform, GLfloat v);
void uniform2f(const LLStaticHashedString& uniform, GLfloat x, GLfloat y);
void uniform3f(const LLStaticHashedString& uniform, GLfloat x, GLfloat y, GLfloat z);
void uniform1fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v);
void uniform2fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v);
void uniform3fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v);
void uniform4fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v);
void uniformMatrix4fv(const LLStaticHashedString& uniform, U32 count, GLboolean transpose, const GLfloat *v);
void uniform1f(const LLStaticHashedString& uniform, GLfloat v);
void uniform2f(const LLStaticHashedString& uniform, GLfloat x, GLfloat y);
void uniform3f(const LLStaticHashedString& uniform, GLfloat x, GLfloat y, GLfloat z);
void uniform1fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v);
void uniform2fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v);
void uniform3fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v);
void uniform4fv(const LLStaticHashedString& uniform, U32 count, const GLfloat* v);
void uniformMatrix4fv(const LLStaticHashedString& uniform, U32 count, GLboolean transpose, const GLfloat* v);
void setMinimumAlpha(F32 minimum);
void setMinimumAlpha(F32 minimum);
void vertexAttrib4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
void vertexAttrib4fv(U32 index, GLfloat* v);
//GLint getUniformLocation(const std::string& uniform);
GLint getUniformLocation(const LLStaticHashedString& uniform);
GLint getUniformLocation(U32 index);
void vertexAttrib4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
void vertexAttrib4fv(U32 index, GLfloat* v);
//GLint getUniformLocation(const std::string& uniform);
GLint getUniformLocation(const LLStaticHashedString& uniform);
GLint getUniformLocation(U32 index);
GLint getAttribLocation(U32 attrib);
GLint mapUniformTextureChannel(GLint location, GLenum type, GLint size);
GLint getAttribLocation(U32 attrib);
GLint mapUniformTextureChannel(GLint location, GLenum type, GLint size);
void clearPermutations();
void addPermutation(std::string name, std::string value);
void removePermutation(std::string name);
void addConstant( const LLGLSLShader::eShaderConsts shader_const );
void addPermutation(std::string name, std::string value);
void removePermutation(std::string name);
//enable/disable texture channel for specified uniform
//if given texture uniform is active in the shader,
//the corresponding channel will be active upon return
//returns channel texture is enabled in from [0-MAX)
S32 enableTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE, LLTexUnit::eTextureColorSpace space = LLTexUnit::TCS_LINEAR);
void addConstant(const LLGLSLShader::eShaderConsts shader_const);
//enable/disable texture channel for specified uniform
//if given texture uniform is active in the shader,
//the corresponding channel will be active upon return
//returns channel texture is enabled in from [0-MAX)
S32 enableTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE, LLTexUnit::eTextureColorSpace space = LLTexUnit::TCS_LINEAR);
S32 disableTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE, LLTexUnit::eTextureColorSpace space = LLTexUnit::TCS_LINEAR);
// bindTexture returns the texture unit we've bound the texture to.
// You can reuse the return value to unbind a texture when required.
S32 bindTexture(const std::string& uniform, LLTexture *texture, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE, LLTexUnit::eTextureColorSpace space = LLTexUnit::TCS_LINEAR);
S32 bindTexture(S32 uniform, LLTexture *texture, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE, LLTexUnit::eTextureColorSpace space = LLTexUnit::TCS_LINEAR);
S32 unbindTexture(const std::string& uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
S32 unbindTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
// bindTexture returns the texture unit we've bound the texture to.
// You can reuse the return value to unbind a texture when required.
S32 bindTexture(const std::string& uniform, LLTexture* texture, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE, LLTexUnit::eTextureColorSpace space = LLTexUnit::TCS_LINEAR);
S32 bindTexture(S32 uniform, LLTexture* texture, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE, LLTexUnit::eTextureColorSpace space = LLTexUnit::TCS_LINEAR);
S32 unbindTexture(const std::string& uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
S32 unbindTexture(S32 uniform, LLTexUnit::eTextureType mode = LLTexUnit::TT_TEXTURE);
BOOL link(BOOL suppress_errors = FALSE);
void bind();
void bind();
//helper to conditionally bind mRiggedVariant instead of this
void bind(bool rigged);
void unbind();
void unbind();
// Unbinds any previously bound shader by explicitly binding no shader.
static void bindNoShader(void);
// Unbinds any previously bound shader by explicitly binding no shader.
static void bindNoShader(void);
U32 mMatHash[LLRender::NUM_MATRIX_MODES];
U32 mLightHash;
U32 mMatHash[LLRender::NUM_MATRIX_MODES];
U32 mLightHash;
GLuint mProgramObject;
GLuint mProgramObject;
#if LL_RELEASE_WITH_DEBUG_INFO
struct attr_name
{
GLint loc;
const char *name;
void operator = (GLint _loc) { loc = _loc; }
operator GLint () { return loc; }
};
std::vector<attr_name> mAttribute; //lookup table of attribute enum to attribute channel
struct attr_name
{
GLint loc;
const char* name;
void operator = (GLint _loc) { loc = _loc; }
operator GLint () { return loc; }
};
std::vector<attr_name> mAttribute; //lookup table of attribute enum to attribute channel
#else
std::vector<GLint> mAttribute; //lookup table of attribute enum to attribute channel
std::vector<GLint> mAttribute; //lookup table of attribute enum to attribute channel
#endif
U32 mAttributeMask; //mask of which reserved attributes are set (lines up with LLVertexBuffer::getTypeMask())
std::vector<GLint> mUniform; //lookup table of uniform enum to uniform location
LLStaticStringTable<GLint> mUniformMap; //lookup map of uniform name to uniform location
U32 mAttributeMask; //mask of which reserved attributes are set (lines up with LLVertexBuffer::getTypeMask())
std::vector<GLint> mUniform; //lookup table of uniform enum to uniform location
LLStaticStringTable<GLint> mUniformMap; //lookup map of uniform name to uniform location
typedef std::unordered_map<GLint, std::string> uniform_name_map_t;
typedef std::unordered_map<GLint, LLVector4> uniform_value_map_t;
uniform_name_map_t mUniformNameMap; //lookup map of uniform location to uniform name
uniform_value_map_t mValue; //lookup map of uniform location to last known value
std::vector<GLint> mTexture;
S32 mTotalUniformSize;
S32 mActiveTextureChannels;
S32 mShaderLevel;
S32 mShaderGroup; // see LLGLSLShader::eGroup
BOOL mUniformsDirty;
LLShaderFeatures mFeatures;
std::vector< std::pair< std::string, GLenum > > mShaderFiles;
std::string mName;
uniform_value_map_t mValue; //lookup map of uniform location to last known value
std::vector<GLint> mTexture;
S32 mTotalUniformSize;
S32 mActiveTextureChannels;
S32 mShaderLevel;
S32 mShaderGroup; // see LLGLSLShader::eGroup
BOOL mUniformsDirty;
LLShaderFeatures mFeatures;
std::vector< std::pair< std::string, GLenum > > mShaderFiles;
std::string mName;
typedef std::unordered_map<std::string, std::string> defines_map_t;
defines_map_t mDefines;
defines_map_t mDefines;
//statistcis for profiling shader performance
U32 mTimerQuery;
U32 mSamplesQuery;
U64 mTimeElapsed;
static U64 sTotalTimeElapsed;
U32 mTrianglesDrawn;
static U32 sTotalTrianglesDrawn;
U64 mSamplesDrawn;
static U64 sTotalSamplesDrawn;
U32 mDrawCalls;
static U32 sTotalDrawCalls;
//statistics for profiling shader performance
U32 mTimerQuery;
U32 mSamplesQuery;
U32 mPrimitivesQuery;
bool mTextureStateFetched;
std::vector<U32> mTextureMagFilter;
std::vector<U32> mTextureMinFilter;
U64 mTimeElapsed;
static U64 sTotalTimeElapsed;
U32 mTrianglesDrawn;
static U32 sTotalTrianglesDrawn;
U64 mSamplesDrawn;
static U64 sTotalSamplesDrawn;
U32 mBinds;
static U32 sTotalBinds;
// this pointer should be set to whichever shader represents this shader's rigged variant
LLGLSLShader* mRiggedVariant = nullptr;
#ifdef LL_PROFILER_ENABLE_RENDER_DOC
#ifdef LL_PROFILER_ENABLE_RENDER_DOC
void setLabel(const char* label);
#endif
#endif
private:
void unloadInternal();
void unloadInternal();
};
//UI shader (declared here so llui_libtest will link properly)

View File

@ -35,6 +35,7 @@
#include "llrendertarget.h"
#include "lltexture.h"
#include "llshadermgr.h"
#include "llmd5.h"
#if LL_WINDOWS
extern void APIENTRY gl_debug_callback(GLenum source,
@ -66,6 +67,14 @@ 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;
std::chrono::steady_clock::time_point touched;
};
static std::unordered_map<std::size_t, LLVBCache> sVBCache;
static const GLenum sGLTextureType[] =
{
GL_TEXTURE_2D,
@ -370,9 +379,10 @@ bool LLTexUnit::bind(LLRenderTarget* renderTarget, bool bindDepth)
if (bindDepth)
{
if (renderTarget->hasStencil())
if (renderTarget->getDepth() && !renderTarget->canSampleDepth())
{
LL_ERRS() << "Cannot bind a render buffer for sampling. Allocate render target without a stencil buffer if sampling of depth buffer is required." << LL_ENDL;
LL_ERRS() << "Cannot bind a render buffer for sampling. Allocate render target with depth buffer sampling enabled." << LL_ENDL;
}
bindManual(renderTarget->getUsage(), renderTarget->getDepth());
@ -1678,26 +1688,107 @@ void LLRender::flush()
if (mBuffer)
{
if (mBuffer->useVBOs() && !mBuffer->isLocked())
{ //hack to only flush the part of the buffer that was updated (relies on stream draw using buffersubdata)
mBuffer->getVertexStrider(mVerticesp, 0, count);
mBuffer->getTexCoord0Strider(mTexcoordsp, 0, count);
mBuffer->getColorStrider(mColorsp, 0, count);
LLMD5 hash;
U32 attribute_mask = LLGLSLShader::sCurBoundShaderPtr->mAttributeMask;
{
LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("vb cache hash");
hash.update((U8*)mVerticesp.get(), count * sizeof(LLVector4a));
if (attribute_mask & LLVertexBuffer::MAP_TEXCOORD0)
{
hash.update((U8*)mTexcoordsp.get(), count * sizeof(LLVector2));
}
if (attribute_mask & LLVertexBuffer::MAP_COLOR)
{
hash.update((U8*)mColorsp.get(), count * sizeof(LLColor4U));
}
hash.finalize();
}
size_t vhash[2];
hash.raw_digest((unsigned char*) vhash);
// check the VB cache before making a new vertex buffer
// This is a giant hack to deal with (mostly) our terrible UI rendering code
// that was built on top of OpenGL immediate mode. Huge performance wins
// can be had by not uploading geometry to VRAM unless absolutely necessary.
// Most of our usage of the "immediate mode" style draw calls is actually
// sending the same geometry over and over again.
// To leverage this, we maintain a running hash of the vertex stream being
// built up before a flush, and then check that hash against a VB
// cache just before creating a vertex buffer in VRAM
std::unordered_map<std::size_t, LLVBCache>::iterator cache = sVBCache.find(vhash[0]);
LLPointer<LLVertexBuffer> vb;
if (cache != sVBCache.end())
{
LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("vb cache hit");
// cache hit, just use the cached buffer
vb = cache->second.vb;
cache->second.touched = std::chrono::steady_clock::now();
}
else
{
LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("vb cache miss");
vb = new LLVertexBuffer(attribute_mask, GL_STATIC_DRAW);
vb->allocateBuffer(count, 0, true);
vb->setPositionData((LLVector4a*) mVerticesp.get());
if (attribute_mask & LLVertexBuffer::MAP_TEXCOORD0)
{
vb->setTexCoordData(mTexcoordsp.get());
}
if (attribute_mask & LLVertexBuffer::MAP_COLOR)
{
vb->setColorData(mColorsp.get());
}
vb->unbind();
sVBCache[vhash[0]] = { vb , std::chrono::steady_clock::now() };
static U32 miss_count = 0;
miss_count++;
if (miss_count > 1024)
{
LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("vb cache clean");
miss_count = 0;
auto now = std::chrono::steady_clock::now();
using namespace std::chrono_literals;
// every 1024 misses, clean the cache of any VBs that haven't been touched in the last second
for (std::unordered_map<std::size_t, LLVBCache>::iterator iter = sVBCache.begin(); iter != sVBCache.end(); )
{
if (now - iter->second.touched > 1s)
{
iter = sVBCache.erase(iter);
}
else
{
++iter;
}
}
}
}
mBuffer->flush();
mBuffer->setBuffer(immediate_mask);
vb->setBuffer(attribute_mask);
// <FS:Ansariel> Remove QUADS rendering mode
//if (mMode == LLRender::QUADS && sGLCoreProfile)
//{
// mBuffer->drawArrays(LLRender::TRIANGLES, 0, count);
// mQuadCycle = 1;
// vb->drawArrays(LLRender::TRIANGLES, 0, count);
// mQuadCycle = 1;
//}
//else
// </FS:Ansariel>
{
mBuffer->drawArrays(mMode, 0, count);
vb->drawArrays(mMode, 0, count);
}
}
else

View File

@ -67,9 +67,8 @@ LLRenderTarget::LLRenderTarget() :
mPreviousResX(0),
mPreviousResY(0),
mDepth(0),
mStencil(0),
mUseDepth(false),
mRenderDepth(false),
mSampleDepth(false),
mUsage(LLTexUnit::TT_TEXTURE)
{
}
@ -98,11 +97,11 @@ void LLRenderTarget::resize(U32 resx, U32 resy)
if (mDepth)
{ //resize depth attachment
if (mStencil)
if (!mSampleDepth)
{
//use render buffers where stencil buffers are in play
glBindRenderbuffer(GL_RENDERBUFFER, mDepth);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, mResX, mResY);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, mResX, mResY);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
}
else
@ -117,7 +116,7 @@ void LLRenderTarget::resize(U32 resx, U32 resy)
}
bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo, S32 samples)
bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool sample_depth, LLTexUnit::eTextureType usage, bool use_fbo, S32 samples)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
resx = llmin(resx, (U32) gGLManager.mGLMaxTextureSize);
@ -130,9 +129,9 @@ bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, boo
mResX = resx;
mResY = resy;
mStencil = stencil;
mUsage = usage;
mUseDepth = depth;
mUseDepth = depth;
mSampleDepth = sample_depth;
if ((sUseFBO || use_fbo))
{
@ -150,13 +149,10 @@ bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, boo
if (mDepth)
{
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
llassert(!mStencil); // use of stencil buffer is deprecated (performance penalty)
if (mStencil)
if (!canSampleDepth())
{
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepth);
stop_glerror();
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mDepth);
stop_glerror();
}
else
{
@ -315,14 +311,12 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt)
bool LLRenderTarget::allocateDepth()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
if (mStencil)
if (!mSampleDepth)
{
//use render buffers where stencil buffers are in play
//use render buffers if depth buffer won't be sampled
glGenRenderbuffers(1, (GLuint *) &mDepth);
glBindRenderbuffer(GL_RENDERBUFFER, mDepth);
stop_glerror();
clear_glerror();
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, mResX, mResY);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, mResX, mResY);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
}
else
@ -367,23 +361,15 @@ void LLRenderTarget::shareDepthBuffer(LLRenderTarget& target)
if (mDepth)
{
stop_glerror();
glBindFramebuffer(GL_FRAMEBUFFER, target.mFBO);
stop_glerror();
llassert(!mStencil); // deprecated -- performance penalty
if (mStencil)
if (!mSampleDepth)
{
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepth);
stop_glerror();
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mDepth);
stop_glerror();
target.mStencil = true;
}
else
{
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, LLTexUnit::getInternalType(mUsage), mDepth, 0);
stop_glerror();
}
check_framebuffer_status();
@ -399,15 +385,13 @@ void LLRenderTarget::release()
LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
if (mDepth)
{
if (mStencil)
if (!mSampleDepth)
{
glDeleteRenderbuffers(1, (GLuint*) &mDepth);
stop_glerror();
}
else
{
LLImageGL::deleteTextures(1, &mDepth);
stop_glerror();
}
mDepth = 0;
@ -419,12 +403,10 @@ void LLRenderTarget::release()
if (mUseDepth)
{ //detach shared depth buffer
llassert(!mStencil); //deprecated, performance penalty
if (mStencil)
if (!mSampleDepth)
{ //attached as a renderbuffer
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
mStencil = false;
mSampleDepth = false;
}
else
{ //attached as a texture
@ -624,84 +606,6 @@ void LLRenderTarget::flush(bool fetch_depth)
}
}
void LLRenderTarget::copyContents(LLRenderTarget& source, S32 srcX0, S32 srcY0, S32 srcX1, S32 srcY1,
S32 dstX0, S32 dstY0, S32 dstX1, S32 dstY1, U32 mask, U32 filter)
{
LL_PROFILE_GPU_ZONE("LLRenderTarget::copyContents");
GLboolean write_depth = mask & GL_DEPTH_BUFFER_BIT ? TRUE : FALSE;
LLGLDepthTest depth(write_depth, write_depth);
gGL.flush();
if (!source.mFBO || !mFBO)
{
LL_WARNS() << "Cannot copy framebuffer contents for non FBO render targets." << LL_ENDL;
return;
}
if (mask == GL_DEPTH_BUFFER_BIT && source.mStencil != mStencil)
{
stop_glerror();
glBindFramebuffer(GL_FRAMEBUFFER, source.mFBO);
check_framebuffer_status();
gGL.getTexUnit(0)->bind(this, true);
stop_glerror();
glCopyTexSubImage2D(LLTexUnit::getInternalType(mUsage), 0, srcX0, srcY0, dstX0, dstY0, dstX1, dstY1);
stop_glerror();
glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO);
stop_glerror();
}
else
{
glBindFramebuffer(GL_READ_FRAMEBUFFER, source.mFBO);
stop_glerror();
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFBO);
stop_glerror();
check_framebuffer_status();
stop_glerror();
glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
stop_glerror();
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
stop_glerror();
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
stop_glerror();
glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO);
stop_glerror();
}
}
//static
void LLRenderTarget::copyContentsToFramebuffer(LLRenderTarget& source, S32 srcX0, S32 srcY0, S32 srcX1, S32 srcY1,
S32 dstX0, S32 dstY0, S32 dstX1, S32 dstY1, U32 mask, U32 filter)
{
if (!source.mFBO)
{
LL_WARNS() << "Cannot copy framebuffer contents for non FBO render targets." << LL_ENDL;
return;
}
{
LL_PROFILE_GPU_ZONE("copyContentsToFramebuffer");
GLboolean write_depth = mask & GL_DEPTH_BUFFER_BIT ? TRUE : FALSE;
LLGLDepthTest depth(write_depth, write_depth);
glBindFramebuffer(GL_READ_FRAMEBUFFER, source.mFBO);
stop_glerror();
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
stop_glerror();
check_framebuffer_status();
stop_glerror();
glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
stop_glerror();
glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO);
stop_glerror();
}
}
bool LLRenderTarget::isComplete() const
{
return (!mTex.empty() || mDepth) ? true : false;

View File

@ -73,7 +73,7 @@ public:
//allocate resources for rendering
//must be called before use
//multiple calls will release previously allocated resources
bool allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage = LLTexUnit::TT_TEXTURE, bool use_fbo = false, S32 samples = 0);
bool allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool sample_depth, LLTexUnit::eTextureType usage = LLTexUnit::TT_TEXTURE, bool use_fbo = false, S32 samples = 0);
//resize existing attachments to use new resolution and color format
// CAUTION: if the GL runs out of memory attempting to resize, this render target will be undefined
@ -136,7 +136,7 @@ public:
U32 getNumTextures() const;
U32 getDepth(void) const { return mDepth; }
bool hasStencil() const { return mStencil; }
bool canSampleDepth() const { return mSampleDepth; }
void bindTexture(U32 index, S32 channel, LLTexUnit::eTextureFilterOptions filter_options = LLTexUnit::TFO_BILINEAR);
@ -148,12 +148,6 @@ public:
// the current depth texture. A depth texture will be allocated if needed.
void flush(bool fetch_depth = FALSE);
void copyContents(LLRenderTarget& source, S32 srcX0, S32 srcY0, S32 srcX1, S32 srcY1,
S32 dstX0, S32 dstY0, S32 dstX1, S32 dstY1, U32 mask, U32 filter);
static void copyContentsToFramebuffer(LLRenderTarget& source, S32 srcX0, S32 srcY0, S32 srcX1, S32 srcY1,
S32 dstX0, S32 dstY0, S32 dstX1, S32 dstY1, U32 mask, U32 filter);
//Returns TRUE if target is ready to be rendered into.
//That is, if the target has been allocated with at least
//one renderable attachment (i.e. color buffer, depth buffer).
@ -172,9 +166,9 @@ protected:
U32 mPreviousResY;
U32 mDepth;
bool mStencil;
bool mUseDepth;
bool mRenderDepth;
bool mUseDepth;
bool mSampleDepth;
LLTexUnit::eTextureType mUsage;
static LLRenderTarget* sBoundTarget;

File diff suppressed because it is too large Load Diff

View File

@ -50,67 +50,16 @@
// called from the main (i.e OpenGL) thread)
//============================================================================
// gl name pools for dynamic and streaming buffers
class LLVBOPool
{
public:
static U32 sBytesPooled;
static U32 sIndexBytesPooled;
LLVBOPool(U32 vboUsage, U32 vboType);
const U32 mUsage;
const U32 mType;
//size MUST be a power of 2
U8* allocate(U32& name, U32 size, bool for_seed = false);
//size MUST be the size provided to allocate that returned the given name
void release(U32 name, U8* buffer, U32 size);
//batch allocate buffers to be provided to the application on demand
void seedPool();
//destroy all records in mFreeList
void cleanup();
U32 genBuffer();
void deleteBuffer(U32 name);
class Record
{
public:
U32 mGLName;
U8* mClientData;
};
typedef std::list<Record> record_list_t;
std::vector<record_list_t> mFreeList;
std::vector<U32> mMissCount;
bool mMissCountDirty; // flag any changes to mFreeList or mMissCount
//used to avoid calling glGenBuffers for every VBO creation
static U32 sNamePool[1024];
static U32 sNameIdx;
};
//============================================================================
// base class
class LLPrivateMemoryPool;
class LLVertexBuffer : public LLRefCount
{
public:
class MappedRegion
struct MappedRegion
{
public:
S32 mType;
S32 mIndex;
S32 mCount;
S32 mEnd;
MappedRegion(S32 type, S32 index, S32 count);
S32 mStart;
S32 mEnd;
};
LLVertexBuffer(const LLVertexBuffer& rhs)
@ -125,12 +74,6 @@ public:
return *this;
}
static LLVBOPool sStreamVBOPool;
static LLVBOPool sDynamicVBOPool;
static LLVBOPool sDynamicCopyVBOPool;
static LLVBOPool sStreamIBOPool;
static LLVBOPool sDynamicIBOPool;
static std::list<U32> sAvailableVAOName;
static U32 sCurVAOName;
@ -138,12 +81,10 @@ public:
static bool sUseVAO;
static bool sPreferStreamDraw;
static void seedPools();
static U32 getVAOName();
static void releaseVAOName(U32 name);
static void initClass(bool use_vbo, bool no_vbo_mapping);
static void initClass(LLWindow* window);
static void cleanupClass();
static void setupClientArrays(U32 data_mask);
static void drawArrays(U32 mode, const std::vector<LLVector3>& pos);
@ -166,8 +107,7 @@ public:
// 4 - modify LLVertexBuffer::setupVertexBuffer
// 5 - modify LLVertexBuffer::setupVertexBufferFast
// 6 - modify LLViewerShaderMgr::mReservedAttribs
// 7 - update LLVertexBuffer::setupVertexArray
// clang-format off
enum { // Shader attribute name, set in LLShaderMgr::initAttribsAndUniforms()
TYPE_VERTEX = 0, // "position"
@ -212,15 +152,12 @@ protected:
virtual void setupVertexBuffer(U32 data_mask);
void setupVertexBufferFast(U32 data_mask);
void setupVertexArray();
void genBuffer(U32 size);
void genIndices(U32 size);
bool bindGLBuffer(bool force_bind = false);
bool bindGLBufferFast();
bool bindGLIndices(bool force_bind = false);
bool bindGLIndicesFast();
bool bindGLArray();
void releaseBuffer();
void releaseIndices();
bool createGLBuffer(U32 size);
@ -244,7 +181,7 @@ public:
virtual void setBuffer(U32 data_mask); // calls setupVertexBuffer() if data_mask is not 0
void setBufferFast(U32 data_mask); // calls setupVertexBufferFast(), assumes data_mask is not 0 among other assumptions
void flush(); //flush pending data to GL memory
void flush(bool discard = false); //flush pending data to GL memory, if discard is true, discard previous VBO
// allocate buffer
bool allocateBuffer(S32 nverts, S32 nindices, bool create);
virtual bool resizeBuffer(S32 newnverts, S32 newnindices);
@ -279,6 +216,10 @@ public:
bool getMetallicRoughnessTexcoordStrider(LLStrider<LLVector2>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getEmissiveTexcoordStrider(LLStrider<LLVector2>& strider, S32 index=0, S32 count = -1, bool map_range = false);
void setPositionData(const LLVector4a* data);
void setTexCoordData(const LLVector2* data);
void setColorData(const LLColor4U* data);
bool useVBOs() const;
bool isEmpty() const { return mEmpty; }
@ -286,8 +227,8 @@ public:
S32 getNumVerts() const { return mNumVerts; }
S32 getNumIndices() const { return mNumIndices; }
U8* getIndicesPointer() const { return useVBOs() ? (U8*) mAlignedIndexOffset : mMappedIndexData; }
U8* getVerticesPointer() const { return useVBOs() ? (U8*) mAlignedOffset : mMappedData; }
U8* getIndicesPointer() const { return useVBOs() ? nullptr : mMappedIndexData; }
U8* getVerticesPointer() const { return useVBOs() ? nullptr : mMappedData; }
U32 getTypeMask() const { return mTypeMask; }
bool hasDataType(S32 type) const { return ((1 << type) & getTypeMask()); }
S32 getSize() const;
@ -296,7 +237,7 @@ public:
U8* getMappedIndices() const { return mMappedIndexData; }
S32 getOffset(S32 type) const { return mOffsets[type]; }
S32 getUsage() const { return mUsage; }
bool isWriteable() const { return (mMappable || mUsage == GL_STREAM_DRAW) ? true : false; }
bool isWriteable() const { return (mUsage == GL_STREAM_DRAW) ? true : false; }
void draw(U32 mode, U32 count, U32 indices_offset) const;
void drawArrays(U32 mode, U32 offset, U32 count) const;
@ -314,21 +255,19 @@ public:
protected:
U32 mGLBuffer; // GL VBO handle
U32 mGLIndices; // GL IBO handle
U32 mTypeMask;
S32 mNumVerts; // Number of vertices allocated
S32 mNumIndices; // Number of indices allocated
ptrdiff_t mAlignedOffset;
ptrdiff_t mAlignedIndexOffset;
S32 mSize;
S32 mIndicesSize;
U32 mTypeMask;
const S32 mUsage; // GL usage
U32 mGLBuffer; // GL VBO handle
U32 mGLIndices; // GL IBO handle
U32 mGLArray; // GL VAO handle
U8* mMappedData; // pointer to currently mapped data (NULL if unmapped)
U8* mMappedIndexData; // pointer to currently mapped indices (NULL if unmapped)
@ -339,18 +278,11 @@ protected:
U32 mFinal : 1; // if true, buffer can not be mapped again
U32 mEmpty : 1; // if true, client buffer is empty (or NULL). Old values have been discarded.
mutable bool mMappable; // if true, use memory mapping to upload data (otherwise doublebuffer and use glBufferSubData)
S32 mOffsets[TYPE_MAX];
std::vector<MappedRegion> mMappedVertexRegions;
std::vector<MappedRegion> mMappedIndexRegions;
mutable LLGLFence* mFence;
void placeFence() const;
void waitFence() const;
static S32 determineUsage(S32 usage);
private:

View File

@ -1,64 +0,0 @@
/**
* @file attachmentAlphaMaskShadowF.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2005, 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$
*/
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
#else
#define frag_color gl_FragColor
#endif
uniform float minimum_alpha;
uniform sampler2D diffuseMap;
VARYING vec4 post_pos;
VARYING vec2 vary_texcoord0;
VARYING float pos_w;
VARYING float target_pos_x;
VARYING vec4 vertex_color;
void main()
{
float alpha = texture2D(diffuseMap, vary_texcoord0.xy).a;
if (alpha < 0.05) // treat as totally transparent
{
discard;
}
if (alpha < minimum_alpha) // treat as semi-transparent
{
//if (fract(0.5*floor(target_pos_x / pos_w )) < 0.25)
{
discard;
}
}
frag_color = vec4(1,1,1,1);
#if !defined(DEPTH_CLAMP)
gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
#endif
}

View File

@ -1,68 +0,0 @@
/**
* @file attachmentAlphaShadowF.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2005, 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$
*/
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
#else
#define frag_color gl_FragColor
#endif
uniform float minimum_alpha;
uniform sampler2D diffuseMap;
VARYING float pos_w;
VARYING float target_pos_x;
#if !defined(DEPTH_CLAMP)
VARYING vec4 post_pos;
#endif
VARYING vec2 vary_texcoord0;
VARYING vec4 vertex_color;
void main()
{
float alpha = texture2D(diffuseMap, vary_texcoord0.xy).a * vertex_color.a;
if (alpha < 0.05) // treat as totally transparent
{
discard;
}
if (alpha < minimum_alpha)
{
if (fract(0.5*floor(target_pos_x / pos_w )) < 0.25)
{
discard;
}
}
frag_color = vec4(1,1,1,1);
#if !defined(DEPTH_CLAMP)
gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
#endif
}

View File

@ -1,74 +0,0 @@
/**
* @file attachmentAlphaShadowV.glsl
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2007, 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$
*/
uniform mat4 projection_matrix;
uniform mat4 modelview_matrix;
uniform mat4 texture_matrix0;
uniform float shadow_target_width;
ATTRIBUTE vec4 diffuse_color;
ATTRIBUTE vec3 position;
ATTRIBUTE vec3 normal;
ATTRIBUTE vec2 texcoord0;
mat4 getObjectSkinnedTransform();
void passTextureIndex();
#if !defined(DEPTH_CLAMP)
VARYING vec4 post_pos;
#endif
VARYING vec2 vary_texcoord0;
VARYING float pos_w;
VARYING float target_pos_x;
VARYING vec4 vertex_color;
void main()
{
//transform vertex
mat4 mat = getObjectSkinnedTransform();
mat = modelview_matrix * mat;
vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz;
vec4 p = projection_matrix * vec4(pos, 1.0);
pos_w = p.w;
target_pos_x = 0.5 * (shadow_target_width - 1.0) * pos.x;
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
vertex_color = diffuse_color;
#if !defined(DEPTH_CLAMP)
p.z = max(p.z, -p.w+0.01);
post_pos = p;
gl_Position = p;
#else
gl_Position = p;
#endif
passTextureIndex();
}

View File

@ -32,10 +32,6 @@ out vec4 frag_color;
uniform float minimum_alpha;
uniform sampler2D diffuseMap;
#if !defined(DEPTH_CLAMP)
VARYING vec4 post_pos;
#endif
VARYING float target_pos_x;
VARYING float pos_w;
VARYING vec2 vary_texcoord0;
@ -58,8 +54,4 @@ void main()
}
frag_color = vec4(1,1,1,1);
#if !defined(DEPTH_CLAMP)
gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
#endif
}

View File

@ -33,10 +33,6 @@ uniform float minimum_alpha;
uniform sampler2D diffuseMap;
#if !defined(DEPTH_CLAMP)
VARYING vec4 post_pos;
#endif
VARYING float pos_w;
VARYING float target_pos_x;
VARYING vec2 vary_texcoord0;
@ -60,9 +56,4 @@ void main()
}
frag_color = vec4(1,1,1,1);
#if !defined(DEPTH_CLAMP)
gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
#endif
}

View File

@ -34,9 +34,6 @@ ATTRIBUTE vec3 position;
ATTRIBUTE vec3 normal;
ATTRIBUTE vec2 texcoord0;
#if !defined(DEPTH_CLAMP)
VARYING vec4 post_pos;
#endif
VARYING float pos_w;
VARYING float target_pos_x;
VARYING vec2 vary_texcoord0;
@ -66,13 +63,7 @@ void main()
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
#if !defined(DEPTH_CLAMP)
post_pos = pos;
gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
#else
gl_Position = pos;
#endif
passTextureIndex();
}

View File

@ -25,24 +25,12 @@
/*[EXTRA_CODE_HERE]*/
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
#else
#define frag_color gl_FragColor
#endif
uniform sampler2D diffuseMap;
#if !defined(DEPTH_CLAMP)
VARYING vec4 post_pos;
#endif
void main()
{
frag_color = vec4(1,1,1,1);
#if !defined(DEPTH_CLAMP)
gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
#endif
}

View File

@ -31,10 +31,6 @@ ATTRIBUTE vec3 position;
ATTRIBUTE vec3 normal;
ATTRIBUTE vec2 texcoord0;
#if !defined(DEPTH_CLAMP)
VARYING vec4 post_pos;
#endif
void main()
{
vec4 pos;
@ -53,13 +49,7 @@ void main()
norm = normalize(norm);
pos = projection_matrix * pos;
#if !defined(DEPTH_CLAMP)
post_pos = pos;
gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
#else
gl_Position = pos;
#endif
}

View File

@ -69,8 +69,4 @@ void main()
#endif
frag_color = vec4(1,1,1,1);
#if !defined(DEPTH_CLAMP)
gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
#endif
}

View File

@ -57,11 +57,7 @@ void main()
post_pos = pos;
#if !defined(DEPTH_CLAMP)
gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
#else
gl_Position = pos;
#endif
passTextureIndex();

View File

@ -47,11 +47,7 @@ void main()
post_pos = pos;
#if !defined(DEPTH_CLAMP)
gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
#else
gl_Position = pos;
#endif
passTextureIndex();

View File

@ -27,10 +27,6 @@ uniform mat4 modelview_projection_matrix;
ATTRIBUTE vec3 position;
#if !defined(DEPTH_CLAMP)
VARYING vec4 post_pos;
#endif
uniform vec3 box_center;
uniform vec3 box_size;
@ -40,11 +36,5 @@ void main()
vec3 p = position*box_size+box_center;
vec4 pos = modelview_projection_matrix*vec4(p.xyz, 1.0);
#if !defined(DEPTH_CLAMP)
post_pos = pos;
gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
#else
gl_Position = pos;
#endif
}

View File

@ -25,20 +25,9 @@
/*[EXTRA_CODE_HERE]*/
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
#else
#define frag_color gl_FragColor
#endif
VARYING vec4 post_pos;
void main()
{
frag_color = vec4(1,1,1,1);
#if !defined(DEPTH_CLAMP)
gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
#endif
}

View File

@ -28,8 +28,6 @@ uniform mat4 projection_matrix;
ATTRIBUTE vec3 position;
VARYING vec4 post_pos;
mat4 getObjectSkinnedTransform();
void main()
@ -41,12 +39,5 @@ void main()
vec4 pos = (mat*vec4(position.xyz, 1.0));
pos = projection_matrix*pos;
post_pos = pos;
#if !defined(DEPTH_CLAMP)
gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
#else
gl_Position = pos;
#endif
}

View File

@ -25,21 +25,10 @@
uniform mat4 modelview_projection_matrix;
ATTRIBUTE vec3 position;
VARYING vec4 post_pos;
in vec3 position;
void main()
{
//transform vertex
vec4 pos = modelview_projection_matrix*vec4(position.xyz, 1.0);
post_pos = pos;
#if !defined(DEPTH_CLAMP)
gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
#else
gl_Position = pos;
#endif
gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
}

View File

@ -25,18 +25,14 @@
/*[EXTRA_CODE_HERE]*/
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
#else
#define frag_color gl_FragColor
#endif
uniform float minimum_alpha;
uniform sampler2D diffuseMap;
VARYING vec4 post_pos;
VARYING vec2 vary_texcoord0;
in vec2 vary_texcoord0;
void main()
{
@ -48,6 +44,4 @@ void main()
}
frag_color = vec4(1,1,1,1);
gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
}

View File

@ -30,8 +30,7 @@ uniform mat4 projection_matrix;
ATTRIBUTE vec3 position;
ATTRIBUTE vec2 texcoord0;
VARYING vec4 post_pos;
VARYING vec2 vary_texcoord0;
out vec2 vary_texcoord0;
mat4 getObjectSkinnedTransform();
@ -43,11 +42,7 @@ void main()
mat = modelview_matrix * mat;
vec4 pos = mat * vec4(position.xyz, 1.0);
pos = projection_matrix * pos;
post_pos = pos;
gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
gl_Position = projection_matrix * pos;
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
}

View File

@ -26,20 +26,15 @@
uniform mat4 texture_matrix0;
uniform mat4 modelview_projection_matrix;
ATTRIBUTE vec3 position;
ATTRIBUTE vec2 texcoord0;
in vec3 position;
in vec2 texcoord0;
VARYING vec4 post_pos;
VARYING vec2 vary_texcoord0;
out vec2 vary_texcoord0;
void main()
{
//transform vertex
vec4 pos = modelview_projection_matrix*vec4(position.xyz, 1.0);
post_pos = pos;
gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
}

View File

@ -1,8 +1,9 @@
/**
* @file avatarShadowF.glsl
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* @file copyF.glsl
*
* $LicenseInfo:firstyear=2023&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2007, Linden Research, Inc.
* Copyright (C) 2023, 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
@ -22,20 +23,18 @@
* $/LicenseInfo$
*/
/*[EXTRA_CODE_HERE]*/
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
#else
#define frag_color gl_FragColor
#endif
in vec2 tc;
uniform sampler2D depthMap;
uniform sampler2D diffuseMap;
VARYING vec2 vary_texcoord0;
out vec4 frag_color;
void main()
{
frag_color = vec4(1,1,1,1);
frag_color = texture(diffuseMap, tc);
#if defined(COPY_DEPTH)
gl_FragDepth = texture(depthMap, tc).r;
#endif
}

View File

@ -1,8 +1,9 @@
/**
* @file attachmentShadowV.glsl
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* @file copyV.glsl
*
* $LicenseInfo:firstyear=2023&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2007, Linden Research, Inc.
* Copyright (C) 2023, 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
@ -22,29 +23,12 @@
* $/LicenseInfo$
*/
uniform mat4 projection_matrix;
uniform mat4 modelview_matrix;
uniform mat4 texture_matrix0;
ATTRIBUTE vec3 position;
ATTRIBUTE vec2 texcoord0;
in vec3 position;
out vec2 tc;
mat4 getObjectSkinnedTransform();
void main()
void main()
{
//transform vertex
mat4 mat = getObjectSkinnedTransform();
mat = modelview_matrix * mat;
vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz;
vec4 p = projection_matrix * vec4(pos, 1.0);
#if !defined(DEPTH_CLAMP)
p.z = max(p.z, -p.w+0.01);
gl_Position = p;
#else
gl_Position = p;
#endif
tc = position.xy * 0.5 + 0.5;
gl_Position = vec4(position, 1.0);
}

View File

@ -398,12 +398,12 @@ void LLRenderPass::renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL t
if (pparams)
{
// <FS:Beq> Capture render times
if(pparams->mFace)
if (pparams->mFace)
{
LLViewerObject* vobj = pparams->mFace->getViewerObject();
if(vobj->isAttachment())
if (vobj->isAttachment())
{
trackAttachments( vobj, false,&ratPtr);
trackAttachments(vobj, false,&ratPtr);
}
}
// </FS:Beq>
@ -420,22 +420,22 @@ void LLRenderPass::renderRiggedGroup(LLSpatialGroup* group, U32 type, U32 mask,
U64 lastMeshId = 0;
mask |= LLVertexBuffer::MAP_WEIGHT4;
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{}; // <FS:Beq/> Perf stats
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{}; // <FS:Beq/> Perf stats
for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
{
LLDrawInfo* pparams = *k;
if (pparams)
{
// <FS:Beq> Capture render times
if(pparams->mFace)
{
LLViewerObject* vobj = pparams->mFace->getViewerObject();
if(vobj->isAttachment())
{
trackAttachments( vobj, true ,&ratPtr);
}
}
// </FS:Beq>
// <FS:Beq> Capture render times
if (pparams->mFace)
{
LLViewerObject* vobj = pparams->mFace->getViewerObject();
if (vobj->isAttachment())
{
trackAttachments(vobj, true ,&ratPtr);
}
}
// </FS:Beq>
if (lastAvatar != pparams->mAvatar || lastMeshId != pparams->mSkinInfo->mHash)
{
uploadMatrixPalette(*pparams);
@ -472,10 +472,14 @@ void teardown_texture_matrix(LLDrawInfo& params)
void LLRenderPass::pushGLTFBatches(U32 type, U32 mask)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)
auto* begin = gPipeline.beginRenderMap(type);
auto* end = gPipeline.endRenderMap(type);
for (LLCullResult::drawinfo_iterator i = begin; i != end; )
{
LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("pushGLTFBatch");
LLDrawInfo& params = **i;
LLCullResult::increment_iterator(i, end);
auto& mat = params.mGLTFMaterial;
mat->bind();
@ -499,10 +503,14 @@ void LLRenderPass::pushRiggedGLTFBatches(U32 type, U32 mask)
LLVOAvatar* lastAvatar = nullptr;
U64 lastMeshId = 0;
mask |= LLVertexBuffer::MAP_WEIGHT4;
for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)
auto* begin = gPipeline.beginRenderMap(type);
auto* end = gPipeline.endRenderMap(type);
for (LLCullResult::drawinfo_iterator i = begin; i != end; )
{
LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("pushRiggedGLTFBatch");
LLDrawInfo& params = **i;
LLCullResult::increment_iterator(i, end);
auto& mat = params.mGLTFMaterial;
mat->bind();
@ -530,24 +538,25 @@ void LLRenderPass::pushRiggedGLTFBatches(U32 type, U32 mask)
void LLRenderPass::pushBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{};
for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)
{
LLDrawInfo* pparams = *i;
if (pparams)
{
// <FS:Beq> Capture render times
if(pparams->mFace)
{
LLViewerObject* vobj = pparams->mFace->getViewerObject();
if(vobj->isAttachment())
{
trackAttachments( vobj, false, &ratPtr);
}
}
// </FS:Beq>
pushBatch(*pparams, mask, texture, batch_textures);
}
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{};
auto* begin = gPipeline.beginRenderMap(type);
auto* end = gPipeline.endRenderMap(type);
for (LLCullResult::drawinfo_iterator i = begin; i != end; )
{
LLDrawInfo* pparams = *i;
LLCullResult::increment_iterator(i, end);
// <FS:Beq> Capture render times
if (pparams && pparams->mFace)
{
LLViewerObject* vobj = pparams->mFace->getViewerObject();
if (vobj->isAttachment())
{
trackAttachments(vobj, false, &ratPtr);
}
}
// </FS:Beq>
pushBatch(*pparams, mask, texture, batch_textures);
}
}
@ -557,56 +566,58 @@ void LLRenderPass::pushRiggedBatches(U32 type, U32 mask, BOOL texture, BOOL batc
LLVOAvatar* lastAvatar = nullptr;
U64 lastMeshId = 0;
mask |= LLVertexBuffer::MAP_WEIGHT4;
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{}; // <FS:Beq/> Perf stats
for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{}; // <FS:Beq/> Perf stats
auto* begin = gPipeline.beginRenderMap(type);
auto* end = gPipeline.endRenderMap(type);
for (LLCullResult::drawinfo_iterator i = begin; i != end; )
{
LLDrawInfo* pparams = *i;
if (pparams)
{
// <FS:Beq> Capture render times
if(pparams->mFace)
{
LLViewerObject* vobj = pparams->mFace->getViewerObject();
if(vobj->isAttachment())
{
trackAttachments( vobj, true, &ratPtr);
}
}
// </FS:Beq>
if (pparams->mAvatar.notNull() && (lastAvatar != pparams->mAvatar || lastMeshId != pparams->mSkinInfo->mHash))
{
uploadMatrixPalette(*pparams);
lastAvatar = pparams->mAvatar;
lastMeshId = pparams->mSkinInfo->mHash;
}
LLCullResult::increment_iterator(i, end);
pushBatch(*pparams, mask, texture, batch_textures);
// <FS:Beq> Capture render times
if (pparams && pparams->mFace)
{
LLViewerObject* vobj = pparams->mFace->getViewerObject();
if (vobj->isAttachment())
{
trackAttachments(vobj, true, &ratPtr);
}
}
// </FS:Beq>
if (pparams->mAvatar.notNull() && (lastAvatar != pparams->mAvatar || lastMeshId != pparams->mSkinInfo->mHash))
{
uploadMatrixPalette(*pparams);
lastAvatar = pparams->mAvatar;
lastMeshId = pparams->mSkinInfo->mHash;
}
pushBatch(*pparams, mask, texture, batch_textures);
}
}
void LLRenderPass::pushMaskBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{};
for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{};
auto* begin = gPipeline.beginRenderMap(type);
auto* end = gPipeline.endRenderMap(type);
for (LLCullResult::drawinfo_iterator i = begin; i != end; )
{
LLDrawInfo* pparams = *i;
if (pparams)
{
// <FS:Beq> Capture render times
if((*pparams).mFace)
{
LLViewerObject* vobj = (*pparams).mFace->getViewerObject();
if(vobj->isAttachment())
{
trackAttachments( vobj, false, &ratPtr);
}
}
// </FS:Beq>
LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(pparams->mAlphaMaskCutoff);
pushBatch(*pparams, mask, texture, batch_textures);
}
LLDrawInfo* pparams = *i;
LLCullResult::increment_iterator(i, end);
// <FS:Beq> Capture render times
if (pparams && pparams->mFace)
{
LLViewerObject* vobj = pparams->mFace->getViewerObject();
if (vobj->isAttachment())
{
trackAttachments(vobj, false, &ratPtr);
}
}
// </FS:Beq>
LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(pparams->mAlphaMaskCutoff);
pushBatch(*pparams, mask, texture, batch_textures);
}
}
@ -615,40 +626,43 @@ void LLRenderPass::pushRiggedMaskBatches(U32 type, U32 mask, BOOL texture, BOOL
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
LLVOAvatar* lastAvatar = nullptr;
U64 lastMeshId = 0;
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{};
for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{};
auto* begin = gPipeline.beginRenderMap(type);
auto* end = gPipeline.endRenderMap(type);
for (LLCullResult::drawinfo_iterator i = begin; i != end; )
{
LLDrawInfo* pparams = *i;
if (pparams)
LLCullResult::increment_iterator(i, end);
// <FS:Beq> Capture render times
if (pparams && pparams->mFace)
{
// <FS:Beq> Capture render times
if((*pparams).mFace)
{
LLViewerObject* vobj = (*pparams).mFace->getViewerObject();
if(vobj->isAttachment())
{
trackAttachments( vobj, true, &ratPtr);
}
}
// </FS:Beq>
if (LLGLSLShader::sCurBoundShaderPtr)
LLViewerObject* vobj = pparams->mFace->getViewerObject();
if (vobj->isAttachment())
{
LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(pparams->mAlphaMaskCutoff);
trackAttachments(vobj, true, &ratPtr);
}
else
{
gGL.flush();
}
if (lastAvatar != pparams->mAvatar || lastMeshId != pparams->mSkinInfo->mHash)
{
uploadMatrixPalette(*pparams);
lastAvatar = pparams->mAvatar;
lastMeshId = pparams->mSkinInfo->mHash;
}
pushBatch(*pparams, mask | LLVertexBuffer::MAP_WEIGHT4, texture, batch_textures);
}
// </FS:Beq>
if (LLGLSLShader::sCurBoundShaderPtr)
{
LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(pparams->mAlphaMaskCutoff);
}
else
{
gGL.flush();
}
if (lastAvatar != pparams->mAvatar || lastMeshId != pparams->mSkinInfo->mHash)
{
uploadMatrixPalette(*pparams);
lastAvatar = pparams->mAvatar;
lastMeshId = pparams->mSkinInfo->mHash;
}
pushBatch(*pparams, mask | LLVertexBuffer::MAP_WEIGHT4, texture, batch_textures);
}
}

View File

@ -642,6 +642,16 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
begin = gPipeline.beginAlphaGroups();
end = gPipeline.endAlphaGroups();
}
LLEnvironment& env = LLEnvironment::instance();
F32 water_height = env.getWaterHeight();
bool above_water = getType() == LLDrawPool::POOL_ALPHA_POST_WATER;
if (LLPipeline::sUnderWaterRender)
{
above_water = !above_water;
}
for (LLCullResult::sg_iterator i = begin; i != end; ++i)
{
@ -653,6 +663,25 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
if (group->getSpatialPartition()->mRenderByGroup &&
!group->isDead())
{
LLSpatialBridge* bridge = group->getSpatialPartition()->asBridge();
const LLVector4a* ext = bridge ? bridge->getSpatialExtents() : group->getExtents();
if (above_water)
{ // reject any spatial groups that have no part above water
if (ext[1].getF32ptr()[2] < water_height)
{
continue;
}
}
else
{ // reject any spatial groups that he no part below water
if (ext[0].getF32ptr()[2] > water_height)
{
continue;
}
}
static std::vector<LLDrawInfo*> emissives;
static std::vector<LLDrawInfo*> rigged_emissives;
emissives.resize(0);
@ -686,7 +715,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
continue;
}
LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("ra - push batch")
LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("ra - push batch");
U32 have_mask = params.mVertexBuffer->getTypeMask() & mask;
if (have_mask != mask)

View File

@ -742,22 +742,22 @@ void LLDrawPoolBump::renderDeferred(S32 pass)
U64 skin = 0;
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{}; // <FS:Beq/> render time capture
for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)
for (LLCullResult::drawinfo_iterator i = begin; i != end; )
{
LLDrawInfo& params = **i;
LLCullResult::increment_iterator(i, end);
// <FS:Beq> Capture render times
if(params.mFace)
if (params.mFace)
{
LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
if(vobj && vobj->isAttachment())
if (vobj && vobj->isAttachment())
{
trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr );
trackAttachments(vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr );
}
}
// </FS:Beq>
LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(params.mAlphaMaskCutoff);
LLDrawPoolBump::bindBumpMap(params, bump_channel);

View File

@ -205,23 +205,25 @@ void LLDrawPoolMaterials::renderDeferred(S32 pass)
LLVOAvatar* lastAvatar = nullptr;
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{}; // <FS:Beq/> render time capture
for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)
for (LLCullResult::drawinfo_iterator i = begin; i != end; )
{
LL_PROFILE_ZONE_NAMED_CATEGORY_MATERIAL("materials draw loop");
LLDrawInfo& params = **i;
// <FS:Beq> Capture render times
if(params.mFace)
if (params.mFace)
{
LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
if( vobj && vobj->isAttachment() )
if (vobj && vobj->isAttachment() )
{
trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr );
trackAttachments(vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr);
}
}
// </FS:Beq>
LLCullResult::increment_iterator(i, end);
if (specular > -1 && params.mSpecColor != lastSpecular)
{
lastSpecular = params.mSpecColor;

View File

@ -137,11 +137,28 @@ void LLDrawPoolWater::beginPostDeferredPass(S32 pass)
// reflections and refractions
LLRenderTarget& src = gPipeline.mRT->screen;
LLRenderTarget& dst = gPipeline.mWaterDis;
#if 0
dst.copyContents(src,
0, 0, src.getWidth(), src.getHeight(),
0, 0, dst.getWidth(), dst.getHeight(),
GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,
GL_NEAREST);
#else
dst.bindTarget();
gCopyDepthProgram.bind();
S32 diff_map = gCopyDepthProgram.enableTexture(LLShaderMgr::DIFFUSE_MAP);
S32 depth_map = gCopyDepthProgram.enableTexture(LLShaderMgr::DEFERRED_DEPTH);
gGL.getTexUnit(diff_map)->bind(&src);
gGL.getTexUnit(depth_map)->bind(&src, true);
gPipeline.mScreenTriangleVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
dst.flush();
#endif
}
}

View File

@ -665,6 +665,8 @@ std::vector<std::string>* LLFilePicker::navOpenFilterProc(ELoadFilter filter) //
allowedv->push_back("dic");
allowedv->push_back("xcu");
allowedv->push_back("gif");
allowedv->push_back("gltf");
allowedv->push_back("glb");
allowedv->push_back("xml");
// <FS:CR> Import filter
allowedv->push_back("oxp");

View File

@ -62,6 +62,7 @@ namespace
const std::string FIELD_SKY_MOON_ROTATION("moon_rotation");
const std::string FIELD_SKY_MOON_AZIMUTH("moon_azimuth");
const std::string FIELD_SKY_MOON_ELEVATION("moon_elevation");
const std::string FIELD_REFLECTION_PROBE_AMBIANCE("probe_ambiance");
const std::string BTN_RESET("btn_reset");
const F32 SLIDER_SCALE_SUN_AMBIENT(3.0f);
@ -117,6 +118,8 @@ BOOL LLFloaterEnvironmentAdjust::postBuild()
getChild<LLTextureCtrl>(FIELD_WATER_NORMAL_MAP)->setBlankImageAssetID(LLUUID(gSavedSettings.getString("DefaultBlankNormalTexture")));
getChild<LLTextureCtrl>(FIELD_WATER_NORMAL_MAP)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onWaterMapChanged(); });
getChild<LLUICtrl>(FIELD_REFLECTION_PROBE_AMBIANCE)->setCommitCallback([this](LLUICtrl*, const LLSD&) { onReflectionProbeAmbianceChanged(); });
refresh();
return TRUE;
}
@ -171,6 +174,8 @@ void LLFloaterEnvironmentAdjust::refresh()
getChild<LLTextureCtrl>(FIELD_SKY_CLOUD_MAP)->setValue(mLiveSky->getCloudNoiseTextureId());
getChild<LLTextureCtrl>(FIELD_WATER_NORMAL_MAP)->setValue(mLiveWater->getNormalMapID());
getChild<LLUICtrl>(FIELD_REFLECTION_PROBE_AMBIANCE)->setValue(mLiveSky->getReflectionProbeAmbiance());
LLColor3 glow(mLiveSky->getGlow());
// takes 40 - 0.2 range -> 0 - 1.99 UI range
@ -468,6 +473,13 @@ void LLFloaterEnvironmentAdjust::onSunColorChanged()
mLiveSky->update();
}
void LLFloaterEnvironmentAdjust::onReflectionProbeAmbianceChanged()
{
if (!mLiveSky) return;
F32 ambiance = getChild<LLUICtrl>(FIELD_REFLECTION_PROBE_AMBIANCE)->getValue().asReal();
mLiveSky->setReflectionProbeAmbiance(ambiance);
mLiveSky->update();
}
void LLFloaterEnvironmentAdjust::onEnvironmentUpdated(LLEnvironment::EnvSelection_t env, S32 version)
{

View File

@ -82,6 +82,8 @@ private:
void onCloudMapChanged();
void onWaterMapChanged();
void onReflectionProbeAmbianceChanged();
void onButtonReset();
void onEnvironmentUpdated(LLEnvironment::EnvSelection_t env, S32 version);

View File

@ -297,7 +297,7 @@ public:
// object not ready to receive override data, queue for later
gGLTFMaterialList.queueOverrideUpdate(object_override.mObjectId, results[i].mSide, results[i].mMaterial);
}
else if (obj && obj->getTE(i) && obj->getTE(i)->isSelected())
else if (obj && obj->getTE(results[i].mSide) && obj->getTE(results[i].mSide)->isSelected())
{
doSelectionCallbacks(object_override.mObjectId, results[i].mSide);
}
@ -305,7 +305,7 @@ public:
else
{
// unblock material editor
if (obj && obj->getTE(i) && obj->getTE(i)->isSelected())
if (obj && obj->getTE(results[i].mSide) && obj->getTE(results[i].mSide)->isSelected())
{
doSelectionCallbacks(object_override.mObjectId, results[i].mSide);
}
@ -404,9 +404,19 @@ void LLGLTFMaterialList::queueModify(const LLUUID& id, S32 side, const LLGLTFMat
}
}
void LLGLTFMaterialList::queueApply(const LLUUID& object_id, S32 side, const LLUUID& asset_id)
void LLGLTFMaterialList::queueApply(const LLViewerObject* obj, S32 side, const LLUUID& asset_id)
{
sApplyQueue.push_back({ object_id, side, asset_id});
const LLGLTFMaterial* material_override = obj->getTE(side)->getGLTFMaterialOverride();
if (material_override)
{
LLGLTFMaterial* cleared_override = new LLGLTFMaterial(*material_override);
cleared_override->setBaseMaterial();
sApplyQueue.push_back({ obj->getID(), side, asset_id, cleared_override });
}
else
{
sApplyQueue.push_back({ obj->getID(), side, asset_id, nullptr });
}
}
void LLGLTFMaterialList::queueUpdate(const LLSD& data)
@ -436,6 +446,11 @@ void LLGLTFMaterialList::flushUpdates(void(*done_callback)(bool))
{
data[i]["gltf_json"] = e.override_data.asJSON();
}
else
{
// Clear all overrides
data[i]["gltf_json"] = "";
}
llassert(is_valid_update(data[i]));
++i;
@ -447,7 +462,15 @@ void LLGLTFMaterialList::flushUpdates(void(*done_callback)(bool))
data[i]["object_id"] = e.object_id;
data[i]["side"] = e.side;
data[i]["asset_id"] = e.asset_id;
data[i]["gltf_json"] = ""; // null out any existing overrides when applying a material asset
if (e.override_data)
{
data[i]["gltf_json"] = e.override_data->asJSON();
}
else
{
// Clear all overrides
data[i]["gltf_json"] = "";
}
llassert(is_valid_update(data[i]));
++i;

View File

@ -59,7 +59,7 @@ public:
// side - TexureEntry index to modify, or -1 for all sides
// mat - material to apply as override, or nullptr to remove existing overrides and revert to asset
//
// NOTE: do not use to revert to asset when applying a new asset id, use queueApplyMaterialAsset below
// NOTE: do not use to revert to asset when applying a new asset id, use queueApply below
static void queueModify(const LLUUID& id, S32 side, const LLGLTFMaterial* mat);
// Queue an application of a material asset we want to send to the simulator. Call "flushUpdates" to flush pending updates.
@ -67,8 +67,8 @@ public:
// side - TextureEntry index to apply material to, or -1 for all sides
// asset_id - ID of material asset to apply, or LLUUID::null to disassociate current material asset
//
// NOTE: implicitly removes any override data if present
static void queueApply(const LLUUID& object_id, S32 side, const LLUUID& asset_id);
// NOTE: Implicitly clears most override data if present
static void queueApply(const LLViewerObject* obj, S32 side, const LLUUID& asset_id);
// flush pending material updates to the simulator
// Automatically called once per frame, but may be called explicitly
@ -136,6 +136,7 @@ protected:
LLUUID object_id;
S32 side = -1;
LLUUID asset_id;
LLPointer<LLGLTFMaterial> override_data;
};
typedef std::list<ApplyMaterialAssetData> apply_queue_t;

View File

@ -1324,7 +1324,16 @@ bool LLMaterialEditor::updateInventoryItem(const std::string &buffer, const LLUU
// done callback
LLMaterialEditor::finishInventoryUpload(itemId, newAssetId, newItemId);
},
nullptr // failure callback
[](LLUUID itemId, LLUUID taskId, LLSD response, std::string reason)
{
// failure callback
LLMaterialEditor* me = LLFloaterReg::findTypedInstance<LLMaterialEditor>("material_editor", LLSD(itemId));
if (me)
{
me->setEnabled(true);
}
return true;
}
);
url = agent_url;
}

View File

@ -4685,8 +4685,8 @@ void LLPanelFace::onPasteTexture(LLViewerObject* objectp, S32 te)
tep->setGLTFRenderMaterial(nullptr);
tep->setGLTFMaterialOverride(nullptr);
// blank out any override data on the server
LLGLTFMaterialList::queueApply(objectp->getID(), te, LLUUID::null);
// blank out most override data on the server
LLGLTFMaterialList::queueApply(objectp, te, LLUUID::null);
}
// Texture map

View File

@ -1892,11 +1892,9 @@ void LLObjectSelection::applyNoCopyPbrMaterialToTEs(LLViewerInventoryItem* item)
}
// apply texture for the selected faces
// blank out most override data on the server
//add(LLStatViewer::EDIT_TEXTURE, 1);
object->setRenderMaterialID(te, asset_id, false /*will be sent later*/);
// blank out any override data on the server
LLGLTFMaterialList::queueApply(object->getID(), te, asset_id);
object->setRenderMaterialID(te, asset_id);
}
}
}
@ -2035,10 +2033,8 @@ void LLSelectMgr::selectionSetGLTFMaterial(const LLUUID& mat_id)
objectp->setParameterEntryInUse(LLNetworkData::PARAMS_RENDER_MATERIAL, TRUE, false /*prevent an update*/);
}
objectp->setRenderMaterialID(te, asset_id, false /*prevent an update to prevent a race condition*/);
// blank out any override data on the server
LLGLTFMaterialList::queueApply(objectp->getID(), te, asset_id);
// Blank out most override data on the object and send to server
objectp->setRenderMaterialID(te, asset_id);
return true;
}
@ -2309,17 +2305,12 @@ void LLSelectMgr::selectionRevertGLTFMaterials()
&& asset_id.notNull())
{
// Restore overrides
LLSD overrides;
overrides["object_id"] = objectp->getID();
overrides["side"] = te;
overrides["gltf_json"] = nodep->mSavedGLTFOverrideMaterials[te]->asJSON();
LLGLTFMaterialList::queueUpdate(overrides);
LLGLTFMaterialList::queueModify(objectp->getID(), te, nodep->mSavedGLTFOverrideMaterials[te]);
}
else
{
//blank override out
LLGLTFMaterialList::queueApply(objectp->getID(), te, asset_id);
LLGLTFMaterialList::queueApply(objectp, te, asset_id);
}
}
@ -6056,7 +6047,6 @@ void LLSelectMgr::processObjectProperties(LLMessageSystem* msg, void** user_data
if (can_copy && can_transfer)
{
// this should be the only place that saved textures is called
node->saveTextures(texture_ids);
}

View File

@ -2924,42 +2924,6 @@ void renderBatchSize(LLDrawInfo* params)
}
}
void renderShadowFrusta(LLDrawInfo* params)
{
LLGLEnable blend(GL_BLEND);
gGL.setSceneBlendType(LLRender::BT_ADD);
LLVector4a center;
center.setAdd(params->mExtents[1], params->mExtents[0]);
center.mul(0.5f);
LLVector4a size;
size.setSub(params->mExtents[1],params->mExtents[0]);
size.mul(0.5f);
if (gPipeline.mShadowCamera[4].AABBInFrustum(center, size))
{
gGL.diffuseColor3f(1,0,0);
pushVerts(params, LLVertexBuffer::MAP_VERTEX);
}
if (gPipeline.mShadowCamera[5].AABBInFrustum(center, size))
{
gGL.diffuseColor3f(0,1,0);
pushVerts(params, LLVertexBuffer::MAP_VERTEX);
}
if (gPipeline.mShadowCamera[6].AABBInFrustum(center, size))
{
gGL.diffuseColor3f(0,0,1);
pushVerts(params, LLVertexBuffer::MAP_VERTEX);
}
if (gPipeline.mShadowCamera[7].AABBInFrustum(center, size))
{
gGL.diffuseColor3f(1,0,1);
pushVerts(params, LLVertexBuffer::MAP_VERTEX);
}
gGL.setSceneBlendType(LLRender::BT_ALPHA);
}
void renderTexelDensity(LLDrawable* drawable)
{
if (LLViewerTexture::sDebugTexelsMode == LLViewerTexture::DEBUG_TEXELS_OFF
@ -3548,10 +3512,6 @@ public:
{
renderBatchSize(draw_info);
}
if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA))
{
renderShadowFrusta(draw_info);
}
}
}
}

View File

@ -98,8 +98,6 @@ public:
// return mSkinHash->mHash, or 0 if mSkinHash is null
U64 getSkinHash();
LLVector4a mExtents[2];
LLPointer<LLVertexBuffer> mVertexBuffer;
LLPointer<LLViewerTexture> mTexture;
std::vector<LLPointer<LLViewerTexture> > mTextureList;
@ -516,6 +514,23 @@ public:
typedef LLDrawInfo** drawinfo_iterator;
typedef LLDrawable** drawable_iterator;
// Helper function for taking advantage of _mm_prefetch when iterating over cull results
static inline void increment_iterator(LLCullResult::drawinfo_iterator& i, const LLCullResult::drawinfo_iterator& end)
{
++i;
if (i != end)
{
_mm_prefetch((char*)(*i)->mVertexBuffer.get(), _MM_HINT_NTA);
auto* ni = i + 1;
if (ni != end)
{
_mm_prefetch((char*)*ni, _MM_HINT_NTA);
}
}
}
void clear();
sg_iterator beginVisibleGroups();

View File

@ -2164,24 +2164,101 @@ EAcceptance LLToolDragAndDrop::dad3dApplyToObject(
{
if (cargo_type == DAD_TEXTURE)
{
LLSelectNode *nodep = nullptr;
if (obj->isSelected())
{
// update object's saved textures
nodep = LLSelectMgr::getInstance()->getSelection()->findNode(obj);
}
if((mask & MASK_SHIFT))
{
dropTextureAllFaces(obj, item, mSource, mSourceID);
// If user dropped a texture onto face it implies
// applying texture now without cancel, save to selection
if (nodep)
{
uuid_vec_t texture_ids;
S32 num_faces = obj->getNumTEs();
for (S32 face = 0; face < num_faces; face++)
{
LLViewerTexture *tex = obj->getTEImage(face);
if (tex != nullptr)
{
texture_ids.push_back(tex->getID());
}
else
{
texture_ids.push_back(LLUUID::null);
}
}
nodep->saveTextures(texture_ids);
}
}
else
{
dropTextureOneFace(obj, face, item, mSource, mSourceID);
// If user dropped a texture onto face it implies
// applying texture now without cancel, save to selection
LLPanelFace* panel_face = gFloaterTools->getPanelFace();
if (nodep
&& gFloaterTools->getVisible()
&& panel_face
&& panel_face->getTextureDropChannel() == 0 /*texture*/
&& nodep->mSavedGLTFMaterialIds.size() > face)
{
LLViewerTexture *tex = obj->getTEImage(face);
if (tex != nullptr)
{
nodep->mSavedTextures[face] = tex->getID();
}
else
{
nodep->mSavedTextures[face] = LLUUID::null;
}
}
}
}
else if (cargo_type == DAD_MATERIAL)
{
LLSelectNode *nodep = nullptr;
if (obj->isSelected())
{
// update object's saved materials
nodep = LLSelectMgr::getInstance()->getSelection()->findNode(obj);
}
// If user dropped a material onto face it implies
// applying texture now without cancel, save to selection
if ((mask & MASK_SHIFT))
{
dropMaterialAllFaces(obj, item, mSource, mSourceID);
if (nodep)
{
uuid_vec_t material_ids;
S32 num_faces = obj->getNumTEs();
for (S32 face = 0; face < num_faces; face++)
{
material_ids.push_back(obj->getRenderMaterialID(face));
}
nodep->saveGLTFMaterialIds(material_ids);
}
}
else
{
dropMaterialOneFace(obj, face, item, mSource, mSourceID);
// If user dropped a material onto face it implies
// applying texture now without cancel, save to selection
if (nodep
&& gFloaterTools->getVisible()
&& nodep->mSavedGLTFMaterialIds.size() > face)
{
nodep->mSavedGLTFMaterialIds[face] = obj->getRenderMaterialID(face);
}
}
}
else if (cargo_type == DAD_MESH)

View File

@ -844,11 +844,11 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
if (!for_snapshot)
{
if (gFrameCount > 1)
{ //for some reason, ATI 4800 series will error out if you
//try to generate a shadow before the first frame is through
gPipeline.generateSunShadow(camera); // <FS:Ansariel> Factor out calls to getInstance
}
if (gFrameCount > 1 && !for_snapshot)
{ //for some reason, ATI 4800 series will error out if you
//try to generate a shadow before the first frame is through
gPipeline.generateSunShadow(*LLViewerCamera::getInstance());
}
LLVertexBuffer::unbind();
@ -1080,8 +1080,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
else
{
gPipeline.renderGeom(camera, TRUE); // <FS:Ansariel> Factor out calls to getInstance
}
}
gGL.setColorMask(true, true);
//store this frame's modelview matrix for use
@ -1111,13 +1110,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
LLRenderTarget &rt = (gPipeline.sRenderDeferred ? gPipeline.mRT->deferredScreen : gPipeline.mRT->screen);
rt.flush();
/*if (rt.sUseFBO)
{
LLRenderTarget::copyContentsToFramebuffer(rt, 0, 0, rt.getWidth(), rt.getHeight(), 0, 0, rt.getWidth(),
rt.getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT,
GL_NEAREST);
}*/
if (LLPipeline::sRenderDeferred)
{
gPipeline.renderDeferredLighting();
@ -1340,7 +1332,7 @@ void render_hud_attachments()
LLSpatialGroup::sNoDelete = TRUE;
LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
gPipeline.updateCull(hud_cam, result, NULL, true);
gPipeline.updateCull(hud_cam, result, true);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_BUMP);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_SIMPLE);
@ -1533,6 +1525,8 @@ void render_ui(F32 zoom_factor, int subfield)
// [/RLVa:KB]
render_hud_attachments();
LLGLState::checkStates();
LLGLSDefault gls_default;
LLGLSUIDefault gls_ui;
{
@ -1547,6 +1541,7 @@ void render_ui(F32 zoom_factor, int subfield)
if (!gDisconnected)
{
LL_PROFILE_ZONE_NAMED_CATEGORY_UI("UI 3D"); //LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_3D);
LLGLState::checkStates();
render_ui_3d();
LLGLState::checkStates();
}

View File

@ -7350,11 +7350,11 @@ void LLViewerObject::setRenderMaterialID(S32 te_in, const LLUUID& id, bool updat
{
// implementation is delicate
// if update is bound for server, should always null out GLTFRenderMaterial and GLTFMaterialOverride even if ids haven't changed
// if update is bound for server, should always null out GLTFRenderMaterial and clear GLTFMaterialOverride even if ids haven't changed
// (the case where ids haven't changed indicates the user has reapplied the original material, in which case overrides should be dropped)
// otherwise, should only null out where ids have changed
// otherwise, should only null out the render material where ids or overrides have changed
// (the case where ids have changed but overrides are still present is from unsynchronized updates from the simulator)
S32 start_idx = 0;
S32 end_idx = getNumTEs();
@ -7367,6 +7367,13 @@ void LLViewerObject::setRenderMaterialID(S32 te_in, const LLUUID& id, bool updat
start_idx = llmax(start_idx, 0);
end_idx = llmin(end_idx, (S32) getNumTEs());
LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL);
if (!param_block && id.notNull())
{ // block doesn't exist, but it will need to
param_block = (LLRenderMaterialParams*)createNewParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL)->data;
}
// update local state
for (S32 te = start_idx; te < end_idx; ++te)
{
@ -7379,17 +7386,27 @@ void LLViewerObject::setRenderMaterialID(S32 te_in, const LLUUID& id, bool updat
new_material = gGLTFMaterialList.getMaterial(id);
}
bool material_changed = tep->getGLTFMaterial() != new_material;
bool material_changed = !param_block || id != param_block->getMaterial(te);
if (update_server)
{
// Clear most overrides so the render material better matches the material
// ID (preserve transforms). If overrides become passthrough, set the overrides
// to nullptr.
if (tep->setBaseMaterial())
{
material_changed = true;
}
}
if (update_server || material_changed)
{
tep->setGLTFRenderMaterial(nullptr);
tep->setGLTFMaterialOverride(nullptr);
}
if (new_material != tep->getGLTFMaterial())
{
tep->setGLTFMaterial(new_material);
tep->setGLTFMaterial(new_material, !update_server);
}
}
@ -7402,17 +7419,14 @@ void LLViewerObject::setRenderMaterialID(S32 te_in, const LLUUID& id, bool updat
// update via ModifyMaterialParams cap (server will echo back changes)
for (S32 te = start_idx; te < end_idx; ++te)
{
LLGLTFMaterialList::queueApply(getID(), te, id);
// This sends a cleared version of this object's current material
// override, but the override should already be cleared due to
// calling setBaseMaterial above.
LLGLTFMaterialList::queueApply(this, te, id);
}
}
// predictively update LLRenderMaterialParams (don't wait for server)
LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL);
if (!param_block && id.notNull())
{ // block doesn't exist, but it will need to
param_block = (LLRenderMaterialParams*)createNewParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL)->data;
}
if (param_block)
{ // update existing parameter block
for (S32 te = start_idx; te < end_idx; ++te)

View File

@ -190,7 +190,7 @@ public:
// set the RenderMaterialID for the given TextureEntry
// te - TextureEntry index to set, or -1 for all TEs
// id - asset id of material asset
// update_server - if true, will send updates to server
// update_server - if true, will send updates to server and clear most overrides
void setRenderMaterialID(S32 te, const LLUUID& id, bool update_server = true);
void setRenderMaterialIDs(const LLUUID& id);

View File

@ -93,6 +93,8 @@ LLGLSLShader gDownsampleDepthRectProgram;
LLGLSLShader gAlphaMaskProgram;
LLGLSLShader gBenchmarkProgram;
LLGLSLShader gReflectionProbeDisplayProgram;
LLGLSLShader gCopyProgram;
LLGLSLShader gCopyDepthProgram;
//object shaders
LLGLSLShader gObjectSimpleProgram;
@ -223,9 +225,6 @@ LLGLSLShader gDeferredSkinnedShadowFullbrightAlphaMaskProgram;
LLGLSLShader gDeferredAvatarShadowProgram;
LLGLSLShader gDeferredAvatarAlphaShadowProgram;
LLGLSLShader gDeferredAvatarAlphaMaskShadowProgram;
LLGLSLShader gDeferredAttachmentShadowProgram;
LLGLSLShader gDeferredAttachmentAlphaShadowProgram;
LLGLSLShader gDeferredAttachmentAlphaMaskShadowProgram;
LLGLSLShader gDeferredAlphaProgram;
LLGLSLShader gDeferredSkinnedAlphaProgram;
LLGLSLShader gDeferredAlphaImpostorProgram;
@ -1292,9 +1291,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredAvatarShadowProgram.unload();
gDeferredAvatarAlphaShadowProgram.unload();
gDeferredAvatarAlphaMaskShadowProgram.unload();
gDeferredAttachmentShadowProgram.unload();
gDeferredAttachmentAlphaShadowProgram.unload();
gDeferredAttachmentAlphaMaskShadowProgram.unload();
gDeferredAvatarProgram.unload();
gDeferredAvatarAlphaProgram.unload();
gDeferredAlphaProgram.unload();
@ -2661,7 +2657,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
success = gDeferredAvatarAlphaShadowProgram.createShader(NULL, NULL);
llassert(success);
}
if (success)
{
gDeferredAvatarAlphaMaskShadowProgram.mName = "Deferred Avatar Alpha Mask Shadow Shader";
@ -2674,43 +2669,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
llassert(success);
}
if (success)
{
gDeferredAttachmentShadowProgram.mName = "Deferred Attachment Shadow Shader";
gDeferredAttachmentShadowProgram.mFeatures.hasObjectSkinning = true;
gDeferredAttachmentShadowProgram.mShaderFiles.clear();
gDeferredAttachmentShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentShadowV.glsl", GL_VERTEX_SHADER));
gDeferredAttachmentShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentShadowF.glsl", GL_FRAGMENT_SHADER));
gDeferredAttachmentShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredAttachmentShadowProgram.createShader(NULL, NULL);
llassert(success);
}
if (success)
{
gDeferredAttachmentAlphaShadowProgram.mName = "Deferred Attachment Alpha Shadow Shader";
gDeferredAttachmentAlphaShadowProgram.mFeatures.hasObjectSkinning = true;
gDeferredAttachmentAlphaShadowProgram.mShaderFiles.clear();
gDeferredAttachmentAlphaShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentAlphaShadowV.glsl", GL_VERTEX_SHADER));
gDeferredAttachmentAlphaShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentAlphaShadowF.glsl", GL_FRAGMENT_SHADER));
gDeferredAttachmentAlphaShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredAttachmentAlphaShadowProgram.createShader(NULL, NULL);
llassert(success);
}
if (success)
{
gDeferredAttachmentAlphaMaskShadowProgram.mName = "Deferred Attachment Alpha Mask Shadow Shader";
gDeferredAttachmentAlphaMaskShadowProgram.mFeatures.hasObjectSkinning = true;
gDeferredAttachmentAlphaMaskShadowProgram.mShaderFiles.clear();
gDeferredAttachmentAlphaMaskShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentAlphaShadowV.glsl", GL_VERTEX_SHADER));
gDeferredAttachmentAlphaMaskShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentAlphaMaskShadowF.glsl", GL_FRAGMENT_SHADER));
gDeferredAttachmentAlphaMaskShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredAttachmentAlphaMaskShadowProgram.createShader(NULL, NULL);
llassert(success);
}
if (success)
{
gDeferredTerrainProgram.mName = "Deferred Terrain Shader";
@ -3938,6 +3896,27 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
success = gReflectionProbeDisplayProgram.createShader(NULL, NULL);
}
if (success)
{
gCopyProgram.mName = "Copy Shader";
gCopyProgram.mShaderFiles.clear();
gCopyProgram.mShaderFiles.push_back(make_pair("interface/copyV.glsl", GL_VERTEX_SHADER));
gCopyProgram.mShaderFiles.push_back(make_pair("interface/copyF.glsl", GL_FRAGMENT_SHADER));
gCopyProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gCopyProgram.createShader(NULL, NULL);
}
if (success)
{
gCopyDepthProgram.mName = "Copy Depth Shader";
gCopyDepthProgram.mShaderFiles.clear();
gCopyDepthProgram.mShaderFiles.push_back(make_pair("interface/copyV.glsl", GL_VERTEX_SHADER));
gCopyDepthProgram.mShaderFiles.push_back(make_pair("interface/copyF.glsl", GL_FRAGMENT_SHADER));
gCopyDepthProgram.clearPermutations();
gCopyDepthProgram.addPermutation("COPY_DEPTH", "1");
gCopyDepthProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gCopyDepthProgram.createShader(NULL, NULL);
}
if (success)
{

View File

@ -164,6 +164,8 @@ extern LLGLSLShader gDownsampleDepthProgram;
extern LLGLSLShader gDownsampleDepthRectProgram;
extern LLGLSLShader gBenchmarkProgram;
extern LLGLSLShader gReflectionProbeDisplayProgram;
extern LLGLSLShader gCopyProgram;
extern LLGLSLShader gCopyDepthProgram;
//output tex0[tc0] + tex1[tc1]
extern LLGLSLShader gTwoTextureAddProgram;
@ -288,9 +290,6 @@ extern LLGLSLShader gFXAAProgram;
extern LLGLSLShader gDeferredPostNoDoFProgram;
extern LLGLSLShader gDeferredPostGammaCorrectProgram;
extern LLGLSLShader gDeferredAvatarShadowProgram;
extern LLGLSLShader gDeferredAttachmentShadowProgram;
extern LLGLSLShader gDeferredAttachmentAlphaShadowProgram;
extern LLGLSLShader gDeferredAttachmentAlphaMaskShadowProgram;
extern LLGLSLShader gDeferredAvatarAlphaShadowProgram;
extern LLGLSLShader gDeferredAvatarAlphaMaskShadowProgram;
extern LLGLSLShader gDeferredAlphaProgram;

View File

@ -707,12 +707,6 @@ public:
}
addText(xpos, ypos, llformat("%d MB Index Data (%d MB Pooled, %d KIndices)", LLVertexBuffer::sAllocatedIndexBytes/(1024*1024), LLVBOPool::sIndexBytesPooled/(1024*1024), LLVertexBuffer::sIndexCount/1024));
ypos += y_inc;
addText(xpos, ypos, llformat("%d MB Vertex Data (%d MB Pooled, %d KVerts)", LLVertexBuffer::sAllocatedBytes/(1024*1024), LLVBOPool::sBytesPooled/(1024*1024), LLVertexBuffer::sVertexCount/1024));
ypos += y_inc;
addText(xpos, ypos, llformat("%d Vertex Buffers", LLVertexBuffer::sGLCount));
ypos += y_inc;
@ -2084,7 +2078,7 @@ LLViewerWindow::LLViewerWindow(const Params& p)
LL_DEBUGS("Window") << "Loading feature tables." << LL_ENDL;
// Initialize OpenGL Renderer
LLVertexBuffer::initClass(gSavedSettings.getBOOL("RenderVBOEnable"), gSavedSettings.getBOOL("RenderVBOMappingDisable"));
LLVertexBuffer::initClass(mWindow);
LL_INFOS("RenderInit") << "LLVertexBuffer initialization done." << LL_ENDL ;
gGL.init(true);
// <FS:Ansariel> Exodus vignette
@ -5307,14 +5301,11 @@ void LLViewerWindow::pickAsync( S32 x,
{
// "Show Debug Alpha" means no object actually transparent
BOOL in_build_mode = LLFloaterReg::instanceVisible("build");
if (LLDrawPoolAlpha::sShowDebugAlpha)
if (LLDrawPoolAlpha::sShowDebugAlpha
|| (in_build_mode && gSavedSettings.getBOOL("SelectInvisibleObjects")))
{
pick_transparent = TRUE;
}
else if (in_build_mode && !gSavedSettings.getBOOL("SelectInvisibleObjects"))
{
pick_transparent = FALSE;
}
LLPickInfo pick_info(LLCoordGL(x, y_from_bot), mask, pick_transparent, pick_rigged, FALSE, TRUE, pick_unselectable, callback);
schedulePick(pick_info);

View File

@ -776,9 +776,6 @@ void LLGrassPartition::getGeometry(LLSpatialGroup* group)
//facep->getTexture(),
buffer, object->isSelected(), fullbright);
const LLVector4a* exts = group->getObjectExtents();
info->mExtents[0] = exts[0];
info->mExtents[1] = exts[1];
info->mVSize = vsize;
draw_vec.push_back(info);
//for alpha sorting

View File

@ -977,9 +977,6 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group)
LLDrawInfo* info = new LLDrawInfo(start,end,count,offset,facep->getTexture(),
buffer, object->isSelected(), fullbright);
const LLVector4a* exts = group->getObjectExtents();
info->mExtents[0] = exts[0];
info->mExtents[1] = exts[1];
info->mVSize = vsize;
info->mBlendFuncDst = bf_dst;
info->mBlendFuncSrc = bf_src;

View File

@ -5596,8 +5596,6 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
draw_vec[idx]->mTextureListVSize[index] = vsize;
}
draw_vec[idx]->validate();
update_min_max(draw_vec[idx]->mExtents[0], draw_vec[idx]->mExtents[1], facep->mExtents[0]);
update_min_max(draw_vec[idx]->mExtents[0], draw_vec[idx]->mExtents[1], facep->mExtents[1]);
}
else
{
@ -5676,8 +5674,6 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
{ //for alpha sorting
facep->setDrawInfo(draw_info);
}
draw_info->mExtents[0] = facep->mExtents[0];
draw_info->mExtents[1] = facep->mExtents[1];
if (index < FACE_DO_NOT_BATCH_TEXTURES)
{ //initialize texture list for texture batching

View File

@ -952,17 +952,13 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
S32 shadow_detail = RenderShadowDetail;
bool ssao = RenderDeferredSSAO;
const U32 occlusion_divisor = 3;
//allocate deferred rendering color buffers
if (!mRT->deferredScreen.allocate(resX, resY, GL_RGBA, TRUE, FALSE, LLTexUnit::TT_TEXTURE, FALSE, samples)) return false;
//if (!mRT->deferredDepth.allocate(resX, resY, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE, FALSE, samples)) return false;
if (!mRT->occlusionDepth.allocate(resX/occlusion_divisor, resY/occlusion_divisor, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE, FALSE, samples)) return false;
if (!mRT->deferredScreen.allocate(resX, resY, GL_RGBA, true, true, LLTexUnit::TT_TEXTURE, false, samples)) return false;
if (!addDeferredAttachments(mRT->deferredScreen)) return false;
GLuint screenFormat = GL_RGBA16;
if (!mRT->screen.allocate(resX, resY, screenFormat, FALSE, FALSE, LLTexUnit::TT_TEXTURE, FALSE, samples)) return false;
if (!mRT->screen.allocate(resX, resY, screenFormat, FALSE, true, LLTexUnit::TT_TEXTURE, FALSE, samples)) return false;
mRT->deferredScreen.shareDepthBuffer(mRT->screen);
@ -1005,23 +1001,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
mRT->fxaaBuffer.release();
mRT->screen.release();
mRT->deferredScreen.release(); //make sure to release any render targets that share a depth buffer with mRT->deferredScreen first
// [RLVa:KB] - @setsphere
if (!LLRenderTarget::sUseFBO || !LLPipeline::sUseDepthTexture)
{
//mRT->deferredDepth.release();
mRT->occlusionDepth.release();
}
else
{
const U32 occlusion_divisor = 3;
//if (!mRT->deferredDepth.allocate(resX, resY, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
if (!mRT->occlusionDepth.allocate(resX / occlusion_divisor, resY / occlusion_divisor, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
if (RlvActions::isRlvEnabled() && !!mRT->deferredLight.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false;
}
// [/RLVa:KB]
// //mRT->deferredDepth.release();
// mRT->occlusionDepth.release();
if (!mRT->screen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_TEXTURE, FALSE)) return false;
}
@ -1040,8 +1020,6 @@ bool LLPipeline::allocateShadowBuffer(U32 resX, U32 resY)
LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
S32 shadow_detail = RenderShadowDetail;
const U32 occlusion_divisor = 3;
F32 scale = llmax(0.f, RenderShadowResolutionScale);
U32 sun_shadow_map_width = BlurHappySize(resX, scale);
U32 sun_shadow_map_height = BlurHappySize(resY, scale);
@ -1050,12 +1028,7 @@ bool LLPipeline::allocateShadowBuffer(U32 resX, U32 resY)
{ //allocate 4 sun shadow maps
for (U32 i = 0; i < 4; i++)
{
if (!mRT->shadow[i].allocate(sun_shadow_map_width, sun_shadow_map_height, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE))
{
return false;
}
if (!mRT->shadowOcclusion[i].allocate(sun_shadow_map_width / occlusion_divisor, sun_shadow_map_height / occlusion_divisor, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE))
if (!mRT->shadow[i].allocate(sun_shadow_map_width, sun_shadow_map_height, 0, true, true, LLTexUnit::TT_TEXTURE))
{
return false;
}
@ -1080,11 +1053,7 @@ bool LLPipeline::allocateShadowBuffer(U32 resX, U32 resY)
U32 spot_shadow_map_height = height;
for (U32 i = 0; i < 2; i++)
{
if (!mSpotShadow[i].allocate(spot_shadow_map_width, spot_shadow_map_height, 0, TRUE, FALSE))
{
return false;
}
if (!mSpotShadowOcclusion[i].allocate(spot_shadow_map_width / occlusion_divisor, height / occlusion_divisor, 0, TRUE, FALSE))
if (!mSpotShadow[i].allocate(spot_shadow_map_width, spot_shadow_map_height, 0, true, true))
{
return false;
}
@ -1115,7 +1084,7 @@ bool LLPipeline::allocateShadowBuffer(U32 resX, U32 resY)
}
}
if (shadow_detail > 1)
if (shadow_detail > 1 && !gCubeSnapshot)
{
for (U32 i = 0; i < 2; i++)
{
@ -1339,7 +1308,6 @@ void LLPipeline::releaseScreenBuffers()
mRT->deferredScreen.release();
mRT->deferredDepth.release();
mRT->deferredLight.release();
mRT->occlusionDepth.release();
}
@ -1347,7 +1315,6 @@ void LLPipeline::releaseSunShadowTarget(U32 index)
{
llassert(index < 4);
mRT->shadow[index].release();
mRT->shadowOcclusion[index].release();
}
void LLPipeline::releaseSunShadowTargets()
@ -1365,7 +1332,6 @@ void LLPipeline::releaseSpotShadowTargets()
for (U32 i = 0; i < 2; i++)
{
mSpotShadow[i].release();
mSpotShadowOcclusion[i].release();
}
}
}
@ -1380,7 +1346,7 @@ void LLPipeline::createGLBuffers()
if (LLPipeline::sRenderTransparentWater)
{ //water reflection texture
U32 res = (U32) llmax(gSavedSettings.getS32("RenderWaterRefResolution"), 512);
mWaterDis.allocate(res,res,GL_RGBA,TRUE,FALSE,LLTexUnit::TT_TEXTURE);
mWaterDis.allocate(res,res,GL_RGBA,true,true,LLTexUnit::TT_TEXTURE);
}
// Use FBO for bake tex
@ -2506,19 +2472,35 @@ bool LLPipeline::getVisibleExtents(LLCamera& camera, LLVector3& min, LLVector3&
static LLTrace::BlockTimerStatHandle FTM_CULL("Object Culling");
void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, LLPlane* planep, bool hud_attachments)
void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, bool hud_attachments)
{
static LLCachedControl<bool> use_occlusion(gSavedSettings,"UseOcclusion");
static bool can_use_occlusion = LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion");
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; //LL_RECORD_BLOCK_TIME(FTM_CULL);
LL_PROFILE_GPU_ZONE("updateCull"); // should always be zero GPU time, but drop a timer to flush stuff out
// <FS:Ansariel> Factor out instance() call
LLWorld& world = LLWorld::instance();
bool water_clip = !sRenderTransparentWater;
if (planep != nullptr)
if (water_clip)
{
camera.setUserClipPlane(*planep);
LLVector3 pnorm;
F32 water_height = LLEnvironment::instance().getWaterHeight();
if (sUnderWaterRender)
{
//camera is below water, cull above water
pnorm.setVec(0, 0, 1);
}
else
{
//camera is above water, cull below water
pnorm = LLVector3(0, 0, -1);
}
LLPlane plane;
plane.setVec(LLVector3(0, 0, water_height), pnorm);
camera.setUserClipPlane(plane);
}
else
{
@ -2529,58 +2511,8 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, LLPlane* pla
sCull->clear();
bool to_texture = LLPipeline::sUseOcclusion > 1 && gPipeline.shadersLoaded();
if (to_texture)
{
if (LLPipeline::sRenderDeferred && can_use_occlusion)
{
mRT->occlusionDepth.bindTarget();
}
else
{
mRT->screen.bindTarget();
}
}
if (sUseOcclusion > 1)
{
gGL.setColorMask(false, false);
}
gGL.matrixMode(LLRender::MM_PROJECTION);
gGL.pushMatrix();
gGL.loadMatrix(gGLLastProjection);
gGL.matrixMode(LLRender::MM_MODELVIEW);
gGL.pushMatrix();
gGLLastMatrix = NULL;
gGL.loadMatrix(gGLLastModelView);
LLGLDisable blend(GL_BLEND);
LLGLDisable test(GL_ALPHA_TEST);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
LLGLDepthTest depth(GL_TRUE, GL_FALSE);
bool bound_shader = false;
if (gPipeline.shadersLoaded() && LLGLSLShader::sCurBoundShader == 0)
{ //if no shader is currently bound, use the occlusion shader instead of fixed function if we can
// (shadow render uses a special shader that clamps to clip planes)
bound_shader = true;
gOcclusionCubeProgram.bind();
}
if (sUseOcclusion > 1)
{
if (mCubeVB.isNull())
{ //cube VB will be used for issuing occlusion queries
mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW);
}
mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
}
for (LLWorld::region_list_t::const_iterator iter = world.getRegionList().begin(); // <FS:Ansariel> Factor out instance() call
iter != world.getRegionList().end(); ++iter)
for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
{
LLViewerRegion* region = *iter;
@ -2600,16 +2532,10 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, LLPlane* pla
LLVOCachePartition* vo_part = region->getVOCachePartition();
if(vo_part)
{
bool do_occlusion_cull = can_use_occlusion && use_occlusion && !gUseWireframe;
vo_part->cull(camera, do_occlusion_cull);
vo_part->cull(camera, sUseOcclusion > 0);
}
}
if (bound_shader)
{
gOcclusionCubeProgram.unbind();
}
if (hasRenderType(LLPipeline::RENDER_TYPE_SKY) &&
gSky.mVOSkyp.notNull() &&
gSky.mVOSkyp->mDrawable.notNull())
@ -2633,30 +2559,8 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, LLPlane* pla
if (render_water)
{
world.precullWaterObjects(camera, sCull, render_water); // <FS:Ansariel> Factor out instance() call
LLWorld::getInstance()->precullWaterObjects(camera, sCull, render_water);
}
gGL.matrixMode(LLRender::MM_PROJECTION);
gGL.popMatrix();
gGL.matrixMode(LLRender::MM_MODELVIEW);
gGL.popMatrix();
if (sUseOcclusion > 1)
{
gGL.setColorMask(true, false);
}
if (to_texture)
{
if (LLPipeline::sRenderDeferred && can_use_occlusion)
{
mRT->occlusionDepth.flush();
}
else
{
mRT->screen.flush();
}
}
}
void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera)
@ -2719,19 +2623,22 @@ void LLPipeline::markOccluder(LLSpatialGroup* group)
void LLPipeline::downsampleDepthBuffer(LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
LL_PROFILE_GPU_ZONE("downsampleDepthBuffer");
LLGLSLShader* last_shader = LLGLSLShader::sCurBoundShaderPtr;
LLGLSLShader* shader = NULL;
if (scratch_space)
{
#if 0 // TODO -- restore occlusion culling functionality
GLint bits = 0;
llassert(!source.hasStencil()); // stencil buffer usage is deprecated
bits |= (source.hasStencil() && dest.hasStencil()) ? GL_STENCIL_BUFFER_BIT : 0;
bits |= GL_DEPTH_BUFFER_BIT;
scratch_space->copyContents(source,
bits = GL_DEPTH_BUFFER_BIT;
scratch_space->copyContents(source,
0, 0, source.getWidth(), source.getHeight(),
0, 0, scratch_space->getWidth(), scratch_space->getHeight(), bits, GL_NEAREST);
#endif
}
dest.bindTarget();
@ -2780,23 +2687,6 @@ void LLPipeline::downsampleDepthBuffer(LLRenderTarget& source, LLRenderTarget& d
}
}
void LLPipeline::doOcclusion(LLCamera& camera, LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
llassert(!gCubeSnapshot);
#if 0
downsampleDepthBuffer(source, dest, scratch_space);
dest.bindTarget();
doOcclusion(camera);
dest.flush();
#else
// none of the above shenanigans should matter (enough) because we've preserved hierarchical Z before issuing occlusion queries
//source.bindTarget();
doOcclusion(camera);
//source.flush();
#endif
}
void LLPipeline::doOcclusion(LLCamera& camera)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
@ -2897,10 +2787,6 @@ void LLPipeline::updateGL()
LLGLUpdate::sGLQ.pop_front();
}
}
{ //seed VBO Pools
LLVertexBuffer::seedPools();
}
}
void LLPipeline::clearRebuildGroups()
@ -3019,6 +2905,8 @@ void LLPipeline::clearRebuildDrawables()
void LLPipeline::rebuildPriorityGroups()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
LL_PROFILE_GPU_ZONE("rebuildPriorityGroups");
LLTimer update_timer;
assertInitialized();
@ -3487,6 +3375,7 @@ void LLPipeline::markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags f
void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
LL_PROFILE_GPU_ZONE("stateSort");
if (hasAnyRenderType(LLPipeline::RENDER_TYPE_AVATAR,
LLPipeline::RENDER_TYPE_CONTROL_AV,
@ -4112,6 +4001,7 @@ void LLPipeline::postSort(LLCamera &camera)
// flush particle VB
if (LLVOPartGroup::sVB)
{
LL_PROFILE_GPU_ZONE("flush particle vb");
LLVOPartGroup::sVB->flush();
}
else
@ -4136,9 +4026,12 @@ void LLPipeline::postSort(LLCamera &camera)
{
LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("rebuild delayed upd groups");
// pack vertex buffers for groups that chose to delay their updates
for (LLSpatialGroup::sg_vector_t::iterator iter = mMeshDirtyGroup.begin(); iter != mMeshDirtyGroup.end(); ++iter)
{
(*iter)->rebuildMesh();
LL_PROFILE_GPU_ZONE("rebuildMesh");
for (LLSpatialGroup::sg_vector_t::iterator iter = mMeshDirtyGroup.begin(); iter != mMeshDirtyGroup.end(); ++iter)
{
(*iter)->rebuildMesh();
}
}
}
@ -7555,8 +7448,6 @@ void LLPipeline::doResetVertexBuffers(bool forced)
LLVOPartGroup::destroyGL();
gGL.resetVertexBuffer();
SUBSYSTEM_CLEANUP(LLVertexBuffer);
if (LLVertexBuffer::sGLCount != 0)
{
LL_WARNS() << "VBO wipe failed -- " << LLVertexBuffer::sGLCount << " buffers remaining." << LL_ENDL;
@ -7579,7 +7470,6 @@ void LLPipeline::doResetVertexBuffers(bool forced)
sNoAlpha = gSavedSettings.getBOOL("RenderNoAlpha");
LLPipeline::sTextureBindTest = gSavedSettings.getBOOL("RenderDebugTextureBind");
LLVertexBuffer::initClass(LLVertexBuffer::sEnableVBOs, LLVertexBuffer::sDisableVBOMapping);
gGL.initVertexBuffer();
// <FS:Ansariel> Reset VB during TP
@ -7612,6 +7502,38 @@ void LLPipeline::renderObjects(U32 type, U32 mask, bool texture, bool batch_text
gGLLastMatrix = NULL;
}
void LLPipeline::renderShadowSimple(U32 type)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
assertInitialized();
gGL.loadMatrix(gGLModelView);
gGLLastMatrix = NULL;
LLVertexBuffer* last_vb = nullptr;
LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type);
LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type);
for (LLCullResult::drawinfo_iterator i = begin; i != end; )
{
LLDrawInfo& params = **i;
LLCullResult::increment_iterator(i, end);
LLVertexBuffer* vb = params.mVertexBuffer;
if (vb != last_vb)
{
LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("push shadow simple");
mSimplePool->applyModelMatrix(params);
vb->setBufferFast(LLVertexBuffer::MAP_VERTEX);
vb->drawRangeFast(LLRender::TRIANGLES, 0, vb->getNumVerts()-1, vb->getNumIndices(), 0);
last_vb = vb;
}
}
gGL.loadMatrix(gGLModelView);
gGLLastMatrix = NULL;
}
void LLPipeline::renderAlphaObjects(U32 mask, bool texture, bool batch_texture, bool rigged)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
@ -7621,31 +7543,34 @@ void LLPipeline::renderAlphaObjects(U32 mask, bool texture, bool batch_texture,
U32 type = LLRenderPass::PASS_ALPHA;
LLVOAvatar* lastAvatar = nullptr;
U64 lastMeshId = 0;
for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)
auto* begin = gPipeline.beginRenderMap(type);
auto* end = gPipeline.endRenderMap(type);
for (LLCullResult::drawinfo_iterator i = begin; i != end; )
{
LLDrawInfo* pparams = *i;
if (pparams)
{
if (rigged)
{
if (pparams->mAvatar != nullptr)
{
if (lastAvatar != pparams->mAvatar || lastMeshId != pparams->mSkinInfo->mHash)
{
mSimplePool->uploadMatrixPalette(*pparams);
lastAvatar = pparams->mAvatar;
lastMeshId = pparams->mSkinInfo->mHash;
}
LLCullResult::increment_iterator(i, end);
mSimplePool->pushBatch(*pparams, mask | LLVertexBuffer::MAP_WEIGHT4, texture, batch_texture);
}
}
else if (pparams->mAvatar == nullptr)
if (rigged)
{
if (pparams->mAvatar != nullptr)
{
mSimplePool->pushBatch(*pparams, mask, texture, batch_texture);
if (lastAvatar != pparams->mAvatar || lastMeshId != pparams->mSkinInfo->mHash)
{
mSimplePool->uploadMatrixPalette(*pparams);
lastAvatar = pparams->mAvatar;
lastMeshId = pparams->mSkinInfo->mHash;
}
mSimplePool->pushBatch(*pparams, mask | LLVertexBuffer::MAP_WEIGHT4, texture, batch_texture);
}
}
else if (pparams->mAvatar == nullptr)
{
mSimplePool->pushBatch(*pparams, mask, texture, batch_texture);
}
}
gGL.loadMatrix(gGLModelView);
gGLLastMatrix = NULL;
}
@ -9837,20 +9762,17 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
LLGLEnable cull(GL_CULL_FACE);
//enable depth clamping if available
//LLGLEnable depth_clamp(GL_DEPTH_CLAMP);
LLGLEnable depth_clamp(GL_DEPTH_CLAMP);
LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_LESS);
if (use_shader)
{
gDeferredShadowCubeProgram.bind();
}
LLRenderTarget& occlusion_target = LLViewerCamera::sCurCameraID >= LLViewerCamera::CAMERA_SPOT_SHADOW0 ?
mSpotShadowOcclusion[LLViewerCamera::sCurCameraID - LLViewerCamera::CAMERA_SPOT_SHADOW0] :
mRT->shadowOcclusion[LLViewerCamera::sCurCameraID - LLViewerCamera::CAMERA_SUN_SHADOW0];
occlusion_target.bindTarget();
updateCull(shadow_cam, result);
occlusion_target.flush();
stateSort(shadow_cam, result);
@ -9872,20 +9794,21 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
LLEnvironment& environment = LLEnvironment::instance();
LLVertexBuffer::unbind();
struct CompareVertexBuffer
{
bool operator()(const LLDrawInfo* const& lhs, const LLDrawInfo* const& rhs)
{
return lhs->mVertexBuffer > rhs->mVertexBuffer;
}
};
LLVertexBuffer::unbind();
for (int j = 0; j < 2; ++j) // 0 -- static, 1 -- rigged
{
bool rigged = j == 1;
if (!use_shader)
{ //occlusion program is general purpose depth-only no-textures
gOcclusionProgram.bind(rigged);
}
else
{
gDeferredShadowProgram.bind(rigged);
LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
}
gDeferredShadowProgram.bind(rigged);
LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
gGL.diffuseColor4f(1, 1, 1, 1);
@ -9900,19 +9823,28 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow simple"); //LL_RECORD_BLOCK_TIME(FTM_SHADOW_SIMPLE);
LL_PROFILE_GPU_ZONE("shadow simple");
gGL.getTexUnit(0)->disable();
for (U32 i = 0; i < sizeof(types) / sizeof(U32); ++i)
for (U32 type : types)
{
renderObjects(types[i], LLVertexBuffer::MAP_VERTEX, FALSE, FALSE, rigged);
if (rigged)
{
renderObjects(type, LLVertexBuffer::MAP_VERTEX, FALSE, FALSE, rigged);
}
else
{
renderShadowSimple(type);
}
}
gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
if (!use_shader)
{
gOcclusionProgram.unbind();
}
}
if (occlude > 1)
{ // do occlusion culling against non-masked only to take advantage of hierarchical Z
doOcclusion(shadow_cam);
}
if (use_shader)
{
LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow geom");
@ -10012,15 +9944,6 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
gGLLastMatrix = NULL;
gGL.loadMatrix(gGLModelView);
LLRenderTarget& occlusion_source = LLViewerCamera::sCurCameraID >= LLViewerCamera::CAMERA_SPOT_SHADOW0 ?
mSpotShadow[LLViewerCamera::sCurCameraID - LLViewerCamera::CAMERA_SPOT_SHADOW0] :
mRT->shadow[LLViewerCamera::sCurCameraID - LLViewerCamera::CAMERA_SUN_SHADOW0];
if (occlude > 1)
{
doOcclusion(shadow_cam, occlusion_source, occlusion_target);
}
if (use_shader)
{
gDeferredShadowProgram.unbind();

View File

@ -173,7 +173,6 @@ public:
// if source's depth buffer cannot be bound for reading, a scratch space depth buffer must be provided
void downsampleDepthBuffer(LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space = NULL);
void doOcclusion(LLCamera& camera, LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space = NULL);
void doOcclusion(LLCamera& camera);
void markNotCulled(LLSpatialGroup* group, LLCamera &camera);
void markMoved(LLDrawable *drawablep, bool damped_motion = false);
@ -244,7 +243,9 @@ public:
bool visibleObjectsInFrustum(LLCamera& camera);
bool getVisibleExtents(LLCamera& camera, LLVector3 &min, LLVector3& max);
bool getVisiblePointCloud(LLCamera& camera, LLVector3 &min, LLVector3& max, std::vector<LLVector3>& fp, LLVector3 light_dir = LLVector3(0,0,0));
void updateCull(LLCamera& camera, LLCullResult& result, LLPlane* plane = NULL, bool hud_attachments = false); //if water_clip is 0, ignore water plane, 1, cull to above plane, -1, cull to below plane; different because SL-11614
// Populate given LLCullResult with results of a frustum cull of the entire scene against the given LLCamera
void updateCull(LLCamera& camera, LLCullResult& result, bool hud_attachments = false);
void createObjects(F32 max_dtime);
void createObject(LLViewerObject* vobj);
void processPartitionQ();
@ -272,6 +273,8 @@ public:
void forAllVisibleDrawables(void (*func)(LLDrawable*));
void renderObjects(U32 type, U32 mask, bool texture = true, bool batch_texture = false, bool rigged = false);
void renderShadowSimple(U32 type);
void renderAlphaObjects(U32 mask, bool texture = true, bool batch_texture = false, bool rigged = false);
void renderMaskedObjects(U32 type, U32 mask, bool texture = true, bool batch_texture = false, bool rigged = false);
void renderFullbrightMaskedObjects(U32 type, U32 mask, bool texture = true, bool batch_texture = false, bool rigged = false);
@ -686,12 +689,10 @@ public:
LLRenderTarget fxaaBuffer;
LLRenderTarget edgeMap;
LLRenderTarget deferredDepth;
LLRenderTarget occlusionDepth;
LLRenderTarget deferredLight;
//sun shadow map
LLRenderTarget shadow[4];
LLRenderTarget shadowOcclusion[4];
};
// main full resoltuion render target
@ -704,7 +705,6 @@ public:
RenderTargetPack* mRT;
LLRenderTarget mSpotShadow[2];
LLRenderTarget mSpotShadowOcclusion[2];
LLRenderTarget mPbrBrdfLut;

View File

@ -264,6 +264,25 @@
top_pad="5"
width="185"
can_edit_text="true"/>
<text follows="left|top"
height="10"
layout="topleft"
left_delta="-5"
top_pad="15"
width="180">Reflection Probe Ambiance:</text>
<slider decimal_digits="3"
follows="left|top"
height="16"
increment="0.01"
initial_value="0"
layout="topleft"
left_delta="5"
min_val="0"
max_val="1"
name="probe_ambiance"
top_pad="5"
width="185"
can_edit_text="true"/>
</layout_panel>
<layout_panel border="false"
name="lp_3"

View File

@ -70,6 +70,7 @@
follows="left|top"
height="25"
label="Save"
enabled="false"
layout="topleft"
name="save"
top_pad="7"
@ -79,6 +80,7 @@
follows="left|top"
height="25"
label="Save As..."
enabled="false"
layout="topleft"
name="save_as"
top_delta="0"