From 8c0163bcb48df56112a625550d411741c20c5846 Mon Sep 17 00:00:00 2001 From: Dave Houlton Date: Wed, 13 Apr 2022 12:32:58 -0600 Subject: SL-17214 initial loader class skeleton --- indra/llmath/v4color.h | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'indra/llmath') diff --git a/indra/llmath/v4color.h b/indra/llmath/v4color.h index 175edf1471..f2863be531 100644 --- a/indra/llmath/v4color.h +++ b/indra/llmath/v4color.h @@ -88,7 +88,8 @@ class LLColor4 const LLColor4& set(const LLColor3 &vec); // Sets LLColor4 to LLColor3 vec (no change in alpha) const LLColor4& set(const LLColor3 &vec, F32 a); // Sets LLColor4 to LLColor3 vec, with alpha specified const LLColor4& set(const F32 *vec); // Sets LLColor4 to vec - const LLColor4& set(const LLColor4U& color4u); // Sets LLColor4 to color4u, rescaled. + const LLColor4& set(const F64 *vec); // Sets LLColor4 to (double)vec + const LLColor4& set(const LLColor4U& color4u); // Sets LLColor4 to color4u, rescaled. const LLColor4& setAlpha(F32 a); @@ -334,6 +335,15 @@ inline const LLColor4& LLColor4::set(const F32 *vec) return (*this); } +inline const LLColor4& LLColor4::set(const F64 *vec) +{ + mV[VX] = static_cast(vec[VX]); + mV[VY] = static_cast(vec[VY]); + mV[VZ] = static_cast(vec[VZ]); + mV[VW] = static_cast(vec[VW]); + return (*this); +} + // deprecated inline const LLColor4& LLColor4::setVec(F32 x, F32 y, F32 z) { -- cgit v1.3 From 8ad7240a3bb626ebaabcc81fb8155a8cbb5adf39 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 8 Sep 2022 10:06:53 -0500 Subject: SL-18095 WIP -- Add Mikktspace tangent generation for PBR materials and switch to per-pixel binormal generation. Still bugged with some test content. --- autobuild.xml | 44 ++++ indra/cmake/LLMath.cmake | 3 + indra/llmath/llvolume.cpp | 272 ++++++++++++++++++--- indra/llmath/llvolume.h | 7 +- indra/newview/app_settings/settings.xml | 11 + .../shaders/class1/deferred/pbropaqueF.glsl | 29 +-- .../shaders/class1/deferred/pbropaqueV.glsl | 28 ++- indra/newview/llface.cpp | 11 +- 8 files changed, 337 insertions(+), 68 deletions(-) (limited to 'indra/llmath') diff --git a/autobuild.xml b/autobuild.xml index bf20cb788e..e984551455 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -1836,6 +1836,50 @@ version 0.16.561408 + mikktspace + + canonical_repo + https://bitbucket.org/lindenlab/3p-mikktspace + copyright + Copyright (C) 2011 by Morten S. Mikkelsen + description + Mikktspace Tangent Generator + license + Copyright (C) 2011 by Morten S. Mikkelsen + license_file + mikktspace.txt + name + mikktspace + platforms + + darwin64 + + archive + + hash + b48b7ac0792d3ea8f087d99d9e4a29d8 + url + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/104415/914944/mikktspace-1-darwin64-574859.tar.bz2 + + name + darwin64 + + windows64 + + archive + + hash + 02e9e5b6fe6788f4d2babb83ec544843 + url + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/104406/914909/mikktspace-1-windows64-574859.tar.bz2 + + name + windows64 + + + version + 1 + minizip-ng canonical_repo diff --git a/indra/cmake/LLMath.cmake b/indra/cmake/LLMath.cmake index 893920ae6f..3cbb7ad561 100644 --- a/indra/cmake/LLMath.cmake +++ b/indra/cmake/LLMath.cmake @@ -1,5 +1,8 @@ # -*- cmake -*- +include(Variables) +include(Mikktspace) + set(LLMATH_INCLUDE_DIRS ${LIBS_OPEN_DIR}/llmath ) diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 4a069b0f63..539db9d0e1 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -32,6 +32,7 @@ #include #endif #include +#include #include "llerror.h" @@ -52,6 +53,9 @@ #include "llmeshoptimizer.h" #include "lltimer.h" +#include "mikktspace/mikktspace.h" +#include "mikktspace/mikktspace.c" // insert mikktspace implementation into llvolume object file + #define DEBUG_SILHOUETTE_BINORMALS 0 #define DEBUG_SILHOUETTE_NORMALS 0 // TomY: Use this to display normals using the silhouette #define DEBUG_SILHOUETTE_EDGE_MAP 0 // DaveP: Use this to display edge map using the silhouette @@ -2096,9 +2100,9 @@ void LLVolume::regen() createVolumeFaces(); } -void LLVolume::genTangents(S32 face) +void LLVolume::genTangents(S32 face, bool mikktspace) { - mVolumeFaces[face].createTangents(); + mVolumeFaces[face].createTangents(mikktspace); } LLVolume::~LLVolume() @@ -4797,6 +4801,17 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src) mTangents = NULL; } + if (src.mMikktSpaceTangents) + { + allocateTangents(src.mNumVertices, true); + LLVector4a::memcpyNonAliased16((F32*)mMikktSpaceTangents, (F32*)src.mMikktSpaceTangents, vert_size); + } + else + { + ll_aligned_free_16(mMikktSpaceTangents); + mMikktSpaceTangents = nullptr; + } + if (src.mWeights) { llassert(!mWeights); // don't orphan an old alloc here accidentally @@ -4867,6 +4882,8 @@ void LLVolumeFace::freeData() mIndices = NULL; ll_aligned_free_16(mTangents); mTangents = NULL; + ll_aligned_free_16(mMikktSpaceTangents); + mMikktSpaceTangents = nullptr; ll_aligned_free_16(mWeights); mWeights = NULL; @@ -4988,6 +5005,9 @@ void LLVolumeFace::remap() ll_aligned_free_16(mTangents); mTangents = NULL; + ll_aligned_free_16(mMikktSpaceTangents); + mMikktSpaceTangents = nullptr; + // Assign new values mIndices = remap_indices; mPositions = remap_positions; @@ -5514,6 +5534,12 @@ bool LLVolumeFace::cacheOptimize() } } + llassert(mTangents == nullptr); // cache optimize called too late, tangents already generated + llassert(mMikktSpaceTangents == nullptr); + + // ===================================================================================== + // DEPRECATED -- cacheOptimize should always be called before tangents are generated + // ===================================================================================== LLVector4a* binorm = NULL; if (mTangents) { @@ -5526,11 +5552,11 @@ bool LLVolumeFace::cacheOptimize() return false; } } + // ===================================================================================== - //allocate mapping of old indices to new indices + //allocate mapping of old indices to new indices std::vector new_idx; - - try + try { new_idx.resize(mNumVertices, -1); } @@ -5673,6 +5699,7 @@ void LLVolumeFace::swapData(LLVolumeFace& rhs) llswap(rhs.mPositions, mPositions); llswap(rhs.mNormals, mNormals); llswap(rhs.mTangents, mTangents); + llswap(rhs.mMikktSpaceTangents, mMikktSpaceTangents); llswap(rhs.mTexCoords, mTexCoords); llswap(rhs.mIndices,mIndices); llswap(rhs.mNumVertices, mNumVertices); @@ -6380,37 +6407,217 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build) void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVector4a *normal, const LLVector2 *texcoord, U32 triangleCount, const U16* index_array, LLVector4a *tangent); -void LLVolumeFace::createTangents() + +// data structures for tangent generation + +// key for summing tangents +// We will blend tangents wherever a common position and normal is found +struct MikktKey { - LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME + // Position + LLVector3 p; + // Normal + LLVector3 n; - if (!mTangents) - { - allocateTangents(mNumVertices); + bool operator==(const MikktKey& rhs) const { return p == rhs.p && n == rhs.n; } +}; - //generate tangents - //LLVector4a* pos = mPositions; - //LLVector2* tc = (LLVector2*) mTexCoords; - LLVector4a* binorm = (LLVector4a*) mTangents; +// sum of tangents and list of signs and index array indices for a given position and normal combination +// sign must be kept separate from summed tangent because a single position and normal may have a different +// tangent facing where UV seams exist +struct MikktTangent +{ + // tangent vector + LLVector3 t; + // signs + std::vector s; + // indices (in index array) + std::vector i; +}; - LLVector4a* end = mTangents+mNumVertices; - while (binorm < end) - { - (*binorm++).clear(); - } +// hash function for MikktTangent +namespace boost +{ + template <> + struct hash + { + std::size_t operator()(LLVector3 const& k) const + { + size_t seed = 0; + boost::hash_combine(seed, k.mV[0]); + boost::hash_combine(seed, k.mV[1]); + boost::hash_combine(seed, k.mV[2]); + return seed; + } + }; + + template <> + struct hash + { + std::size_t operator()(MikktKey const& k) const + { + size_t seed = 0; + boost::hash_combine(seed, k.p); + boost::hash_combine(seed, k.n); + return seed; + } + }; +} + +// boost adapter +namespace std +{ + template<> + struct hash + { + std::size_t operator()(MikktKey const& k) const + { + return boost::hash()(k); + } + }; +} + +struct MikktData +{ + LLVolumeFace* face; + std::unordered_map tangents; +}; - binorm = mTangents; - CalculateTangentArray(mNumVertices, mPositions, mNormals, mTexCoords, mNumIndices/3, mIndices, mTangents); +void LLVolumeFace::createTangents(bool mikktspace) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; - //normalize tangents - for (U32 i = 0; i < mNumVertices; i++) - { - //binorm[i].normalize3fast(); - //bump map/planar projection code requires normals to be normalized - mNormals[i].normalize3fast(); - } - } + auto& tangents = mikktspace ? mMikktSpaceTangents : mTangents; + + if (!tangents) + { + allocateTangents(mNumVertices, mikktspace); + + if (mikktspace) + { + LL_PROFILE_ZONE_NAMED_CATEGORY_VOLUME("mikktspace"); + SMikkTSpaceInterface ms; + + ms.m_getNumFaces = [](const SMikkTSpaceContext* pContext) + { + MikktData* data = (MikktData*)pContext->m_pUserData; + LLVolumeFace* face = data->face; + return face->mNumIndices / 3; + }; + + ms.m_getNumVerticesOfFace = [](const SMikkTSpaceContext* pContext, const int iFace) + { + return 3; + }; + + ms.m_getPosition = [](const SMikkTSpaceContext* pContext, float fvPosOut[], const int iFace, const int iVert) + { + MikktData* data = (MikktData*)pContext->m_pUserData; + LLVolumeFace* face = data->face; + S32 idx = face->mIndices[iFace * 3 + iVert]; + auto& vert = face->mPositions[idx]; + F32* v = vert.getF32ptr(); + fvPosOut[0] = v[0]; + fvPosOut[1] = v[1]; + fvPosOut[2] = v[2]; + }; + + ms.m_getNormal = [](const SMikkTSpaceContext* pContext, float fvNormOut[], const int iFace, const int iVert) + { + MikktData* data = (MikktData*)pContext->m_pUserData; + LLVolumeFace* face = data->face; + S32 idx = face->mIndices[iFace * 3 + iVert]; + auto& norm = face->mNormals[idx]; + F32* n = norm.getF32ptr(); + fvNormOut[0] = n[0]; + fvNormOut[1] = n[1]; + fvNormOut[2] = n[2]; + }; + + ms.m_getTexCoord = [](const SMikkTSpaceContext* pContext, float fvTexcOut[], const int iFace, const int iVert) + { + MikktData* data = (MikktData*)pContext->m_pUserData; + LLVolumeFace* face = data->face; + S32 idx = face->mIndices[iFace * 3 + iVert]; + auto& tc = face->mTexCoords[idx]; + fvTexcOut[0] = tc.mV[0]; + fvTexcOut[1] = tc.mV[1]; + }; + + ms.m_setTSpaceBasic = [](const SMikkTSpaceContext* pContext, const float fvTangent[], const float fSign, const int iFace, const int iVert) + { + MikktData* data = (MikktData*)pContext->m_pUserData; + LLVolumeFace* face = data->face; + S32 i = iFace * 3 + iVert; + S32 idx = face->mIndices[i]; + + LLVector3 p(face->mPositions[idx].getF32ptr()); + LLVector3 n(face->mNormals[idx].getF32ptr()); + LLVector3 t(fvTangent); + + MikktKey key = { p, n }; + + MikktTangent& mt = data->tangents[key]; + mt.t += t; + mt.s.push_back(fSign); + mt.i.push_back(i); + }; + + ms.m_setTSpace = nullptr; + + MikktData data; + data.face = this; + + SMikkTSpaceContext ctx = { &ms, &data }; + + genTangSpaceDefault(&ctx); + + for (U32 i = 0; i < mNumVertices; ++i) + { + MikktKey key = { LLVector3(mPositions[i].getF32ptr()), LLVector3(mNormals[i].getF32ptr()) }; + MikktTangent& t = data.tangents[key]; + + //set tangent + mMikktSpaceTangents[i].load3(t.t.mV); + mMikktSpaceTangents[i].normalize3fast(); + + //set sign + F32 sign = 0.f; + for (int j = 0; j < t.i.size(); ++j) + { + if (mIndices[t.i[j]] == i) + { + sign = t.s[j]; + break; + } + } + + llassert(sign != 0.f); + mMikktSpaceTangents[i].getF32ptr()[3] = sign; + } + } + else + { + //generate tangents + LLVector4a* ptr = (LLVector4a*)tangents; + + LLVector4a* end = mTangents + mNumVertices; + while (ptr < end) + { + (*ptr++).clear(); + } + + CalculateTangentArray(mNumVertices, mPositions, mNormals, mTexCoords, mNumIndices / 3, mIndices, tangents); + } + + //normalize normals + for (U32 i = 0; i < mNumVertices; i++) + { + //bump map/planar projection code requires normals to be normalized + mNormals[i].normalize3fast(); + } + } } void LLVolumeFace::resizeVertices(S32 num_verts) @@ -6511,10 +6718,11 @@ void LLVolumeFace::pushVertex(const LLVector4a& pos, const LLVector4a& norm, con mNumVertices++; } -void LLVolumeFace::allocateTangents(S32 num_verts) +void LLVolumeFace::allocateTangents(S32 num_verts, bool mikktspace) { - ll_aligned_free_16(mTangents); - mTangents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts); + auto& buff = mikktspace ? mMikktSpaceTangents : mTangents; + ll_aligned_free_16(buff); + buff = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts); } void LLVolumeFace::allocateWeights(S32 num_verts) diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index 9697952f5b..8c604c5d1a 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -870,10 +870,10 @@ private: public: BOOL create(LLVolume* volume, BOOL partial_build = FALSE); - void createTangents(); + void createTangents(bool mikktspace = false); void resizeVertices(S32 num_verts); - void allocateTangents(S32 num_verts); + void allocateTangents(S32 num_verts, bool mikktspace = false); void allocateWeights(S32 num_verts); void allocateJointIndices(S32 num_verts); void resizeIndices(S32 num_indices); @@ -947,6 +947,7 @@ public: LLVector4a* mPositions; // Contains vertices, nortmals and texcoords LLVector4a* mNormals; // pointer into mPositions LLVector4a* mTangents; + LLVector4a* mMikktSpaceTangents = nullptr; // for GLTF rendering, use mikkt space tangents LLVector2* mTexCoords; // pointer into mPositions // mIndices contains mNumIndices amount of elements. @@ -1028,7 +1029,7 @@ public: void setDirty() { mPathp->setDirty(); mProfilep->setDirty(); } void regen(); - void genTangents(S32 face); + void genTangents(S32 face, bool mikktspace = false); BOOL isConvex() const; BOOL isCap(S32 face); diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index cd33690075..9508c1dc2d 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10558,6 +10558,17 @@ Value 0 + RenderUseMikktSpace + + Comment + Use Mikkt Space tangents on GLTF materials. + Persist + 1 + Type + Boolean + Value + 1 + RenderUseTriStrips Comment diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl index f5b5698305..69019667de 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl @@ -42,6 +42,8 @@ uniform vec3 emissiveColor; #ifdef HAS_NORMAL_MAP uniform sampler2D bumpMap; + VARYING vec3 vary_tangent; + flat in float vary_sign; #endif #ifdef HAS_EMISSIVE_MAP @@ -66,9 +68,6 @@ VARYING vec4 vertex_color; VARYING vec2 vary_texcoord0; #ifdef HAS_NORMAL_MAP VARYING vec3 vary_normal; -VARYING vec3 vary_mat0; -VARYING vec3 vary_mat1; -VARYING vec3 vary_mat2; VARYING vec2 vary_texcoord1; #endif @@ -94,21 +93,14 @@ void main() vec3 col = vertex_color.rgb * albedo.rgb; -#ifdef HAS_NORMAL_MAP - vec4 norm = texture2D(bumpMap, vary_texcoord1.xy); - norm.xyz = normalize(norm.xyz * 2 - 1); - - vec3 tnorm = vec3(dot(norm.xyz,vary_mat0), - dot(norm.xyz,vary_mat1), - dot(norm.xyz,vary_mat2)); -#else - vec4 norm = vec4(0,0,0,1.0); -// vec3 tnorm = vary_normal; - vec3 tnorm = vec3(0,0,1); -#endif + // from mikktspace.com + vec4 vNt = texture2D(bumpMap, vary_texcoord1.xy)*2.0-1.0; + float sign = vary_sign; + vec3 vN = vary_normal; + vec3 vT = vary_tangent.xyz; - tnorm = normalize(tnorm.xyz); - norm.xyz = tnorm.xyz; + vec3 vB = sign * cross(vN, vT); + vec3 tnorm = normalize( vNt.x * vT + vNt.y * vB + vNt.z * vN ); // RGB = Occlusion, Roughness, Metal // default values, see LLViewerTexture::sDefaultPBRORMImagep @@ -155,6 +147,9 @@ void main() tnorm *= gl_FrontFacing ? 1.0 : -1.0; + //col = vec3(0,0,0); + //emissive = vary_tangent.xyz*0.5+0.5; + //emissive = vec3(vary_sign*0.5+0.5); // See: C++: addDeferredAttachments(), GLSL: softenLightF frag_data[0] = vec4(col, 0.0); // Diffuse frag_data[1] = vec4(emissive, vertex_color.a); // PBR sRGB Emissive diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl index a2606ed771..e17d91af38 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl @@ -59,13 +59,7 @@ ATTRIBUTE vec2 texcoord0; ATTRIBUTE vec4 tangent; ATTRIBUTE vec2 texcoord1; -VARYING vec3 vary_mat0; -VARYING vec3 vary_mat1; -VARYING vec3 vary_mat2; - VARYING vec2 vary_texcoord1; -#else -VARYING vec3 vary_normal; #endif #ifdef HAS_SPECULAR_MAP @@ -75,6 +69,10 @@ VARYING vec2 vary_texcoord2; VARYING vec4 vertex_color; VARYING vec2 vary_texcoord0; +VARYING vec3 vary_tangent; +flat out float vary_sign; + +VARYING vec3 vary_normal; void main() { @@ -113,9 +111,9 @@ void main() vec3 t = normalize((mat*vec4(tangent.xyz+position.xyz,1.0)).xyz-pos.xyz); vec3 b = cross(n, t)*tangent.w; - vary_mat0 = vec3(t.x, b.x, n.x); - vary_mat1 = vec3(t.y, b.y, n.y); - vary_mat2 = vec3(t.z, b.z, n.z); + //vary_mat0 = vec3(t.x, b.x, n.x); + //vary_mat1 = vec3(t.y, b.y, n.y); + //vary_mat2 = vec3(t.z, b.z, n.z); #else //HAS_NORMAL_MAP vary_normal = n; #endif //HAS_NORMAL_MAP @@ -123,12 +121,16 @@ vary_normal = n; vec3 n = normalize(normal_matrix * normal); #ifdef HAS_NORMAL_MAP vec3 t = normalize(normal_matrix * tangent.xyz); - vec3 b = cross(n,t)*tangent.w; + vary_tangent = t; + vary_sign = tangent.w; + vary_normal = n; + + //vec3 b = cross(n,t)*tangent.w; //vec3 t = cross(b,n) * binormal.w; - vary_mat0 = vec3(t.x, b.x, n.x); - vary_mat1 = vec3(t.y, b.y, n.y); - vary_mat2 = vec3(t.z, b.z, n.z); + //vary_mat0 = vec3(t.x, b.x, n.x); + //vary_mat1 = vec3(t.y, b.y, n.y); + //vary_mat2 = vec3(t.z, b.z, n.z); #else //HAS_NORMAL_MAP vary_normal = n; #endif //HAS_NORMAL_MAP diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 52aacb607c..f35b4b6d91 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -2166,14 +2166,19 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, mVertexBuffer->getTangentStrider(tangent, mGeomIndex, mGeomCount, map_range); F32* tangents = (F32*) tangent.get(); - mVObjp->getVolume()->genTangents(f); + LLGLTFMaterial* gltf_mat = tep->getGLTFMaterial(); + static LLCachedControl use_mikktspace(gSavedSettings, "RenderUseMikktSpace"); + bool mikktspace = use_mikktspace && gltf_mat != nullptr; + + mVObjp->getVolume()->genTangents(f, mikktspace); LLVector4Logical mask; mask.clear(); mask.setElement<3>(); - LLVector4a* src = vf.mTangents; - LLVector4a* end = vf.mTangents+num_vertices; + LLVector4a* tbuff = mikktspace ? vf.mMikktSpaceTangents : vf.mTangents; + LLVector4a* src = tbuff; + LLVector4a* end = tbuff+num_vertices; while (src < end) { -- cgit v1.3 From c822da9fe644e4a420caabb30a25b487ce75c099 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 9 Sep 2022 20:56:22 -0500 Subject: SL-18095 WIP -- Allow mikktspace generator to add more vertices (skip re-welding step for now). --- indra/llmath/llvolume.cpp | 551 ++++++--------------- indra/llmath/llvolume.h | 2 +- .../shaders/class1/deferred/pbropaqueF.glsl | 84 +--- .../shaders/class1/deferred/pbropaqueV.glsl | 77 +-- indra/newview/llface.cpp | 7 +- 5 files changed, 171 insertions(+), 550 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 539db9d0e1..0ce1577d00 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -2102,7 +2102,12 @@ void LLVolume::regen() void LLVolume::genTangents(S32 face, bool mikktspace) { - mVolumeFaces[face].createTangents(mikktspace); + // generate legacy tangents for the specified face + // if mikktspace is true, only generate tangents if mikktspace tangents are not present (handles the case for non-mesh prims) + if (!mikktspace || mVolumeFaces[face].mMikktSpaceTangents == nullptr) + { + mVolumeFaces[face].createTangents(); + } } LLVolume::~LLVolume() @@ -5373,252 +5378,155 @@ public: } }; +// data structures for tangent generation -bool LLVolumeFace::cacheOptimize() -{ //optimize for vertex cache according to Forsyth method: - // http://home.comcast.net/~tom_forsyth/papers/fast_vert_cache_opt.html - - llassert(!mOptimized); - mOptimized = TRUE; - - LLVCacheLRU cache; - - if (mNumVertices < 3 || mNumIndices < 3) - { //nothing to do - return true; - } +struct MikktData +{ + LLVolumeFace* face; + std::vector p; + std::vector n; + std::vector tc; + std::vector w; + std::vector t; + + MikktData(LLVolumeFace* f) + : face(f) + { + U32 count = face->mNumIndices; - //mapping of vertices to triangles and indices - std::vector vertex_data; + p.resize(count); + n.resize(count); + tc.resize(count); + t.resize(count); - //mapping of triangles do vertices - std::vector triangle_data; + if (face->mWeights) + { + w.resize(count); + } - try - { - triangle_data.resize(mNumIndices / 3); - vertex_data.resize(mNumVertices); + for (int i = 0; i < face->mNumIndices; ++i) + { + U32 idx = face->mIndices[i]; - for (U32 i = 0; i < mNumIndices; i++) - { //populate vertex data and triangle data arrays - U16 idx = mIndices[i]; - U32 tri_idx = i / 3; + p[i].set(face->mPositions[idx].getF32ptr()); + n[i].set(face->mNormals[idx].getF32ptr()); + tc[i].set(face->mTexCoords[idx]); - vertex_data[idx].mTriangles.push_back(&(triangle_data[tri_idx])); - vertex_data[idx].mIdx = idx; - triangle_data[tri_idx].mVertex[i % 3] = &(vertex_data[idx]); + if (face->mWeights) + { + w[i].set(face->mWeights[idx].getF32ptr()); + } } } - catch (std::bad_alloc&) - { - // resize or push_back failed - LL_WARNS("LLVOLUME") << "Resize for " << mNumVertices << " vertices failed" << LL_ENDL; - return false; - } - - /*F32 pre_acmr = 1.f; - //measure cache misses from before rebuild - { - LLVCacheFIFO test_cache; - for (U32 i = 0; i < mNumIndices; ++i) - { - test_cache.addVertex(&vertex_data[mIndices[i]]); - } - - for (U32 i = 0; i < mNumVertices; i++) - { - vertex_data[i].mCacheTag = -1; - } - - pre_acmr = (F32) test_cache.mMisses/(mNumIndices/3); - }*/ - - for (U32 i = 0; i < mNumVertices; i++) - { //initialize score values (no cache -- might try a fifo cache here) - LLVCacheVertexData& data = vertex_data[i]; - - data.mScore = find_vertex_score(data); - data.mActiveTriangles = data.mTriangles.size(); +}; - for (U32 j = 0; j < data.mActiveTriangles; ++j) - { - data.mTriangles[j]->mScore += data.mScore; - } - } - //sort triangle data by score - std::sort(triangle_data.begin(), triangle_data.end()); +bool LLVolumeFace::cacheOptimize() +{ //optimize for vertex cache according to Forsyth method: + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; + llassert(!mOptimized); + mOptimized = TRUE; - std::vector new_indices; + allocateTangents(mNumVertices, true); - LLVCacheTriangleData* tri; + SMikkTSpaceInterface ms; - //prime pump by adding first triangle to cache; - tri = &(triangle_data[0]); - cache.addTriangle(tri); - new_indices.push_back(tri->mVertex[0]->mIdx); - new_indices.push_back(tri->mVertex[1]->mIdx); - new_indices.push_back(tri->mVertex[2]->mIdx); - tri->complete(); + ms.m_getNumFaces = [](const SMikkTSpaceContext* pContext) + { + MikktData* data = (MikktData*)pContext->m_pUserData; + LLVolumeFace* face = data->face; + return face->mNumIndices / 3; + }; - U32 breaks = 0; - for (U32 i = 1; i < mNumIndices/3; ++i) - { - cache.updateScores(); - tri = cache.mBestTriangle; - if (!tri) - { - breaks++; - for (U32 j = 0; j < triangle_data.size(); ++j) - { - if (triangle_data[j].mActive) - { - tri = &(triangle_data[j]); - break; - } - } - } - - cache.addTriangle(tri); - new_indices.push_back(tri->mVertex[0]->mIdx); - new_indices.push_back(tri->mVertex[1]->mIdx); - new_indices.push_back(tri->mVertex[2]->mIdx); - tri->complete(); - } + ms.m_getNumVerticesOfFace = [](const SMikkTSpaceContext* pContext, const int iFace) + { + return 3; + }; - for (U32 i = 0; i < mNumIndices; ++i) - { - mIndices[i] = new_indices[i]; - } + ms.m_getPosition = [](const SMikkTSpaceContext* pContext, float fvPosOut[], const int iFace, const int iVert) + { + MikktData* data = (MikktData*)pContext->m_pUserData; + LLVolumeFace* face = data->face; + S32 idx = face->mIndices[iFace * 3 + iVert]; + auto& vert = face->mPositions[idx]; + F32* v = vert.getF32ptr(); + fvPosOut[0] = v[0]; + fvPosOut[1] = v[1]; + fvPosOut[2] = v[2]; + }; - /*F32 post_acmr = 1.f; - //measure cache misses from after rebuild - { - LLVCacheFIFO test_cache; - for (U32 i = 0; i < mNumVertices; i++) - { - vertex_data[i].mCacheTag = -1; - } + ms.m_getNormal = [](const SMikkTSpaceContext* pContext, float fvNormOut[], const int iFace, const int iVert) + { + MikktData* data = (MikktData*)pContext->m_pUserData; + LLVolumeFace* face = data->face; + S32 idx = face->mIndices[iFace * 3 + iVert]; + auto& norm = face->mNormals[idx]; + F32* n = norm.getF32ptr(); + fvNormOut[0] = n[0]; + fvNormOut[1] = n[1]; + fvNormOut[2] = n[2]; + }; - for (U32 i = 0; i < mNumIndices; ++i) - { - test_cache.addVertex(&vertex_data[mIndices[i]]); - } - - post_acmr = (F32) test_cache.mMisses/(mNumIndices/3); - }*/ + ms.m_getTexCoord = [](const SMikkTSpaceContext* pContext, float fvTexcOut[], const int iFace, const int iVert) + { + MikktData* data = (MikktData*)pContext->m_pUserData; + LLVolumeFace* face = data->face; + S32 idx = face->mIndices[iFace * 3 + iVert]; + auto& tc = face->mTexCoords[idx]; + fvTexcOut[0] = tc.mV[0]; + fvTexcOut[1] = tc.mV[1]; + }; - //optimize for pre-TnL cache - - //allocate space for new buffer - S32 num_verts = mNumVertices; - S32 size = ((num_verts*sizeof(LLVector2)) + 0xF) & ~0xF; - LLVector4a* pos = (LLVector4a*) ll_aligned_malloc<64>(sizeof(LLVector4a)*2*num_verts+size); - if (pos == NULL) - { - LL_WARNS("LLVOLUME") << "Allocation of positions vector[" << sizeof(LLVector4a) * 2 * num_verts + size << "] failed. " << LL_ENDL; - return false; - } - LLVector4a* norm = pos + num_verts; - LLVector2* tc = (LLVector2*) (norm + num_verts); + ms.m_setTSpaceBasic = [](const SMikkTSpaceContext* pContext, const float fvTangent[], const float fSign, const int iFace, const int iVert) + { + MikktData* data = (MikktData*)pContext->m_pUserData; + LLVolumeFace* face = data->face; + S32 i = iFace * 3 + iVert; + S32 idx = face->mIndices[i]; - LLVector4a* wght = NULL; - if (mWeights) - { - wght = (LLVector4a*)ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts); - if (wght == NULL) - { - ll_aligned_free<64>(pos); - LL_WARNS("LLVOLUME") << "Allocation of weights[" << sizeof(LLVector4a) * num_verts << "] failed" << LL_ENDL; - return false; - } - } + LLVector3 p(face->mPositions[idx].getF32ptr()); + LLVector3 n(face->mNormals[idx].getF32ptr()); + LLVector3 t(fvTangent); - llassert(mTangents == nullptr); // cache optimize called too late, tangents already generated - llassert(mMikktSpaceTangents == nullptr); + data->t[i].set(fvTangent); + data->t[i].mV[3] = fSign; + }; - // ===================================================================================== - // DEPRECATED -- cacheOptimize should always be called before tangents are generated - // ===================================================================================== - LLVector4a* binorm = NULL; - if (mTangents) - { - binorm = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts); - if (binorm == NULL) - { - ll_aligned_free<64>(pos); - ll_aligned_free_16(wght); - LL_WARNS("LLVOLUME") << "Allocation of binormals[" << sizeof(LLVector4a)*num_verts << "] failed" << LL_ENDL; - return false; - } - } - // ===================================================================================== + ms.m_setTSpace = nullptr; - //allocate mapping of old indices to new indices - std::vector new_idx; - try - { - new_idx.resize(mNumVertices, -1); - } - catch (std::bad_alloc&) - { - ll_aligned_free<64>(pos); - ll_aligned_free_16(wght); - ll_aligned_free_16(binorm); - LL_WARNS("LLVOLUME") << "Resize failed: " << mNumVertices << LL_ENDL; - return false; - } + MikktData data(this); - S32 cur_idx = 0; - for (U32 i = 0; i < mNumIndices; ++i) - { - U16 idx = mIndices[i]; - if (new_idx[idx] == -1) - { //this vertex hasn't been added yet - new_idx[idx] = cur_idx; + SMikkTSpaceContext ctx = { &ms, &data }; - //copy vertex data - pos[cur_idx] = mPositions[idx]; - norm[cur_idx] = mNormals[idx]; - tc[cur_idx] = mTexCoords[idx]; - if (mWeights) - { - wght[cur_idx] = mWeights[idx]; - } - if (mTangents) - { - binorm[cur_idx] = mTangents[idx]; - } + genTangSpaceDefault(&ctx); + + resizeVertices(data.p.size()); + resizeIndices(data.p.size()); + + if (!data.w.empty()) + { + allocateWeights(data.w.size()); + } - cur_idx++; - } - } + allocateTangents(mNumVertices, true); - for (U32 i = 0; i < mNumIndices; ++i) - { - mIndices[i] = new_idx[mIndices[i]]; - } - - ll_aligned_free<64>(mPositions); - // DO NOT free mNormals and mTexCoords as they are part of mPositions buffer - ll_aligned_free_16(mWeights); - ll_aligned_free_16(mTangents); -#if USE_SEPARATE_JOINT_INDICES_AND_WEIGHTS - ll_aligned_free_16(mJointIndices); - ll_aligned_free_16(mJustWeights); - mJustWeights = NULL; - mJointIndices = NULL; // filled in later as necessary by skinning code for acceleration -#endif + for (int i = 0; i < mNumIndices; ++i) + { + mIndices[i] = i; - mPositions = pos; - mNormals = norm; - mTexCoords = tc; - mWeights = wght; - mTangents = binorm; + mPositions[i].load3(data.p[i].mV); + mNormals[i].load3(data.n[i].mV); + mTexCoords[i] = data.tc[i]; + + mMikktSpaceTangents[i].loadua(data.t[i].mV); - //std::string result = llformat("ACMR pre/post: %.3f/%.3f -- %d triangles %d breaks", pre_acmr, post_acmr, mNumIndices/3, breaks); - //LL_INFOS() << result << LL_ENDL; + if (mWeights) + { + mWeights[i].loadua(data.w[i].mV); + } + } + return true; } @@ -6407,209 +6315,25 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build) void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVector4a *normal, const LLVector2 *texcoord, U32 triangleCount, const U16* index_array, LLVector4a *tangent); - -// data structures for tangent generation - -// key for summing tangents -// We will blend tangents wherever a common position and normal is found -struct MikktKey -{ - // Position - LLVector3 p; - // Normal - LLVector3 n; - - bool operator==(const MikktKey& rhs) const { return p == rhs.p && n == rhs.n; } -}; - -// sum of tangents and list of signs and index array indices for a given position and normal combination -// sign must be kept separate from summed tangent because a single position and normal may have a different -// tangent facing where UV seams exist -struct MikktTangent -{ - // tangent vector - LLVector3 t; - // signs - std::vector s; - // indices (in index array) - std::vector i; -}; - -// hash function for MikktTangent -namespace boost -{ - template <> - struct hash - { - std::size_t operator()(LLVector3 const& k) const - { - size_t seed = 0; - boost::hash_combine(seed, k.mV[0]); - boost::hash_combine(seed, k.mV[1]); - boost::hash_combine(seed, k.mV[2]); - return seed; - } - }; - - template <> - struct hash - { - std::size_t operator()(MikktKey const& k) const - { - size_t seed = 0; - boost::hash_combine(seed, k.p); - boost::hash_combine(seed, k.n); - return seed; - } - }; -} - -// boost adapter -namespace std -{ - template<> - struct hash - { - std::size_t operator()(MikktKey const& k) const - { - return boost::hash()(k); - } - }; -} - -struct MikktData -{ - LLVolumeFace* face; - std::unordered_map tangents; -}; - - -void LLVolumeFace::createTangents(bool mikktspace) +void LLVolumeFace::createTangents() { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; - auto& tangents = mikktspace ? mMikktSpaceTangents : mTangents; - - if (!tangents) + + if (!mTangents) { - allocateTangents(mNumVertices, mikktspace); + allocateTangents(mNumVertices); + + //generate tangents + LLVector4a* ptr = (LLVector4a*)mTangents; - if (mikktspace) + LLVector4a* end = mTangents + mNumVertices; + while (ptr < end) { - LL_PROFILE_ZONE_NAMED_CATEGORY_VOLUME("mikktspace"); - SMikkTSpaceInterface ms; - - ms.m_getNumFaces = [](const SMikkTSpaceContext* pContext) - { - MikktData* data = (MikktData*)pContext->m_pUserData; - LLVolumeFace* face = data->face; - return face->mNumIndices / 3; - }; - - ms.m_getNumVerticesOfFace = [](const SMikkTSpaceContext* pContext, const int iFace) - { - return 3; - }; - - ms.m_getPosition = [](const SMikkTSpaceContext* pContext, float fvPosOut[], const int iFace, const int iVert) - { - MikktData* data = (MikktData*)pContext->m_pUserData; - LLVolumeFace* face = data->face; - S32 idx = face->mIndices[iFace * 3 + iVert]; - auto& vert = face->mPositions[idx]; - F32* v = vert.getF32ptr(); - fvPosOut[0] = v[0]; - fvPosOut[1] = v[1]; - fvPosOut[2] = v[2]; - }; - - ms.m_getNormal = [](const SMikkTSpaceContext* pContext, float fvNormOut[], const int iFace, const int iVert) - { - MikktData* data = (MikktData*)pContext->m_pUserData; - LLVolumeFace* face = data->face; - S32 idx = face->mIndices[iFace * 3 + iVert]; - auto& norm = face->mNormals[idx]; - F32* n = norm.getF32ptr(); - fvNormOut[0] = n[0]; - fvNormOut[1] = n[1]; - fvNormOut[2] = n[2]; - }; - - ms.m_getTexCoord = [](const SMikkTSpaceContext* pContext, float fvTexcOut[], const int iFace, const int iVert) - { - MikktData* data = (MikktData*)pContext->m_pUserData; - LLVolumeFace* face = data->face; - S32 idx = face->mIndices[iFace * 3 + iVert]; - auto& tc = face->mTexCoords[idx]; - fvTexcOut[0] = tc.mV[0]; - fvTexcOut[1] = tc.mV[1]; - }; - - ms.m_setTSpaceBasic = [](const SMikkTSpaceContext* pContext, const float fvTangent[], const float fSign, const int iFace, const int iVert) - { - MikktData* data = (MikktData*)pContext->m_pUserData; - LLVolumeFace* face = data->face; - S32 i = iFace * 3 + iVert; - S32 idx = face->mIndices[i]; - - LLVector3 p(face->mPositions[idx].getF32ptr()); - LLVector3 n(face->mNormals[idx].getF32ptr()); - LLVector3 t(fvTangent); - - MikktKey key = { p, n }; - - MikktTangent& mt = data->tangents[key]; - mt.t += t; - mt.s.push_back(fSign); - mt.i.push_back(i); - }; - - ms.m_setTSpace = nullptr; - - MikktData data; - data.face = this; - - SMikkTSpaceContext ctx = { &ms, &data }; - - genTangSpaceDefault(&ctx); - - for (U32 i = 0; i < mNumVertices; ++i) - { - MikktKey key = { LLVector3(mPositions[i].getF32ptr()), LLVector3(mNormals[i].getF32ptr()) }; - MikktTangent& t = data.tangents[key]; - - //set tangent - mMikktSpaceTangents[i].load3(t.t.mV); - mMikktSpaceTangents[i].normalize3fast(); - - //set sign - F32 sign = 0.f; - for (int j = 0; j < t.i.size(); ++j) - { - if (mIndices[t.i[j]] == i) - { - sign = t.s[j]; - break; - } - } - - llassert(sign != 0.f); - mMikktSpaceTangents[i].getF32ptr()[3] = sign; - } + (*ptr++).clear(); } - else - { - //generate tangents - LLVector4a* ptr = (LLVector4a*)tangents; - - LLVector4a* end = mTangents + mNumVertices; - while (ptr < end) - { - (*ptr++).clear(); - } - CalculateTangentArray(mNumVertices, mPositions, mNormals, mTexCoords, mNumIndices / 3, mIndices, tangents); - } + CalculateTangentArray(mNumVertices, mPositions, mNormals, mTexCoords, mNumIndices / 3, mIndices, mTangents); //normalize normals for (U32 i = 0; i < mNumVertices; i++) @@ -6618,6 +6342,7 @@ void LLVolumeFace::createTangents(bool mikktspace) mNormals[i].normalize3fast(); } } + } void LLVolumeFace::resizeVertices(S32 num_verts) diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index 8c604c5d1a..f1feaade58 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -870,7 +870,7 @@ private: public: BOOL create(LLVolume* volume, BOOL partial_build = FALSE); - void createTangents(bool mikktspace = false); + void createTangents(); void resizeVertices(S32 num_verts); void allocateTangents(S32 num_verts, bool mikktspace = false); diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl index 69019667de..ca304f749a 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl @@ -25,61 +25,34 @@ /*[EXTRA_CODE_HERE]*/ -#define DEBUG_PBR_LIGHT_TYPE 0 // Output Diffuse=0.75, Emissive=0, ORM=0,0,0 - -#define DEBUG_BASIC 0 -#define DEBUG_VERTEX 0 -#define DEBUG_NORMAL_MAP 0 // Output packed normal map "as is" to diffuse -#define DEBUG_NORMAL_OUT 0 // Output unpacked normal to diffuse -#define DEBUG_ORM 0 // Output Occlusion Roughness Metal "as is" to diffuse -#define DEBUG_POSITION 0 - uniform sampler2D diffuseMap; //always in sRGB space uniform float metallicFactor; uniform float roughnessFactor; uniform vec3 emissiveColor; +uniform sampler2D bumpMap; +uniform sampler2D emissiveMap; +uniform sampler2D specularMap; // Packed: Occlusion, Metal, Roughness -#ifdef HAS_NORMAL_MAP - uniform sampler2D bumpMap; - VARYING vec3 vary_tangent; - flat in float vary_sign; -#endif - -#ifdef HAS_EMISSIVE_MAP - uniform sampler2D emissiveMap; -#endif - -#ifdef HAS_SPECULAR_MAP - uniform sampler2D specularMap; // Packed: Occlusion, Metal, Roughness -#endif - -uniform samplerCube environmentMap; -uniform mat3 env_mat; - -#ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_data[4]; -#else -#define frag_data gl_FragData -#endif VARYING vec3 vary_position; VARYING vec4 vertex_color; -VARYING vec2 vary_texcoord0; -#ifdef HAS_NORMAL_MAP VARYING vec3 vary_normal; -VARYING vec2 vary_texcoord1; -#endif +VARYING vec3 vary_tangent; +flat in float vary_sign; -#ifdef HAS_SPECULAR_MAP - VARYING vec2 vary_texcoord2; -#endif +VARYING vec2 vary_texcoord0; +VARYING vec2 vary_texcoord1; +VARYING vec2 vary_texcoord2; uniform float minimum_alpha; // PBR alphaMode: MASK, See: mAlphaCutoff, setAlphaCutoff() vec2 encode_normal(vec3 n); vec3 linear_to_srgb(vec3 c); +uniform mat3 normal_matrix; + void main() { // IF .mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; @@ -94,11 +67,11 @@ void main() vec3 col = vertex_color.rgb * albedo.rgb; // from mikktspace.com - vec4 vNt = texture2D(bumpMap, vary_texcoord1.xy)*2.0-1.0; + vec3 vNt = texture2D(bumpMap, vary_texcoord1.xy).xyz*2.0-1.0; float sign = vary_sign; vec3 vN = vary_normal; vec3 vT = vary_tangent.xyz; - + vec3 vB = sign * cross(vN, vT); vec3 tnorm = normalize( vNt.x * vT + vNt.y * vB + vNt.z * vN ); @@ -107,49 +80,20 @@ void main() // occlusion 1.0 // roughness 0.0 // metal 0.0 -#ifdef HAS_SPECULAR_MAP vec3 spec = texture2D(specularMap, vary_texcoord2.xy).rgb; -#else - vec3 spec = vec3(1,0,0); -#endif spec.g *= roughnessFactor; spec.b *= metallicFactor; vec3 emissive = emissiveColor; -#ifdef HAS_EMISSIVE_MAP emissive *= texture2D(emissiveMap, vary_texcoord0.xy).rgb; -#endif - -#if DEBUG_PBR_LIGHT_TYPE - col.rgb = vec3(0.75); - emissive = vec3(0); - spec.rgb = vec3(0); -#endif -#if DEBUG_BASIC - col.rgb = vec3( 1, 0, 1 ); -#endif -#if DEBUG_VERTEX - col.rgb = vertex_color.rgb; -#endif -#if DEBUG_NORMAL_MAP - col.rgb = texture2D(bumpMap, vary_texcoord1.xy).rgb; -#endif -#if DEBUG_NORMAL_OUT - col.rgb = vary_normal; -#endif -#if DEBUG_ORM - col.rgb = linear_to_srgb(spec); -#endif -#if DEBUG_POSITION - col.rgb = vary_position.xyz; -#endif tnorm *= gl_FrontFacing ? 1.0 : -1.0; + //spec.rgb = vec3(1,1,0); //col = vec3(0,0,0); //emissive = vary_tangent.xyz*0.5+0.5; - //emissive = vec3(vary_sign*0.5+0.5); + //emissive = vec3(sign*0.5+0.5); // See: C++: addDeferredAttachments(), GLSL: softenLightF frag_data[0] = vec4(col, 0.0); // Diffuse frag_data[1] = vec4(emissive, vertex_color.a); // PBR sRGB Emissive diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl index e17d91af38..c90a17993f 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl @@ -37,41 +37,24 @@ uniform mat3 normal_matrix; uniform mat4 modelview_projection_matrix; #endif -#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND) - -#if !defined(HAS_SKIN) -uniform mat4 modelview_matrix; -#endif - -VARYING vec3 vary_position; - -#endif - uniform mat4 texture_matrix0; ATTRIBUTE vec3 position; ATTRIBUTE vec4 diffuse_color; ATTRIBUTE vec3 normal; -ATTRIBUTE vec2 texcoord0; - - -#ifdef HAS_NORMAL_MAP ATTRIBUTE vec4 tangent; +ATTRIBUTE vec2 texcoord0; ATTRIBUTE vec2 texcoord1; +ATTRIBUTE vec2 texcoord2; +VARYING vec2 vary_texcoord0; VARYING vec2 vary_texcoord1; -#endif - -#ifdef HAS_SPECULAR_MAP -ATTRIBUTE vec2 texcoord2; VARYING vec2 vary_texcoord2; -#endif VARYING vec4 vertex_color; -VARYING vec2 vary_texcoord0; + VARYING vec3 vary_tangent; flat out float vary_sign; - VARYING vec3 vary_normal; void main() @@ -83,64 +66,28 @@ void main() vec3 pos = (mat*vec4(position.xyz,1.0)).xyz; -#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND) - vary_position = pos; -#endif - gl_Position = projection_matrix*vec4(pos,1.0); #else //transform vertex gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); - #endif vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; - -#ifdef HAS_NORMAL_MAP vary_texcoord1 = (texture_matrix0 * vec4(texcoord1,0,1)).xy; -#endif - -#ifdef HAS_SPECULAR_MAP vary_texcoord2 = (texture_matrix0 * vec4(texcoord2,0,1)).xy; -#endif #ifdef HAS_SKIN - vec3 n = normalize((mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz); -#ifdef HAS_NORMAL_MAP - vec3 t = normalize((mat*vec4(tangent.xyz+position.xyz,1.0)).xyz-pos.xyz); - vec3 b = cross(n, t)*tangent.w; - - //vary_mat0 = vec3(t.x, b.x, n.x); - //vary_mat1 = vec3(t.y, b.y, n.y); - //vary_mat2 = vec3(t.z, b.z, n.z); -#else //HAS_NORMAL_MAP -vary_normal = n; -#endif //HAS_NORMAL_MAP + vec3 n = (mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz; + vec3 t = (mat*vec4(tangent.xyz+position.xyz,1.0)).xyz-pos.xyz; #else //HAS_SKIN - vec3 n = normalize(normal_matrix * normal); -#ifdef HAS_NORMAL_MAP - vec3 t = normalize(normal_matrix * tangent.xyz); - vary_tangent = t; - vary_sign = tangent.w; - vary_normal = n; + vec3 n = normal_matrix * normal; + vec3 t = normal_matrix * tangent.xyz; +#endif - //vec3 b = cross(n,t)*tangent.w; - //vec3 t = cross(b,n) * binormal.w; - - //vary_mat0 = vec3(t.x, b.x, n.x); - //vary_mat1 = vec3(t.y, b.y, n.y); - //vary_mat2 = vec3(t.z, b.z, n.z); -#else //HAS_NORMAL_MAP - vary_normal = n; -#endif //HAS_NORMAL_MAP -#endif //HAS_SKIN + vary_tangent = normalize(t); + vary_sign = tangent.w; + vary_normal = normalize(n); vertex_color = diffuse_color; - -#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND) -#if !defined(HAS_SKIN) - vary_position = (modelview_matrix*vec4(position.xyz, 1.0)).xyz; -#endif -#endif } diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index f35b4b6d91..83d35b7f3c 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -2177,6 +2177,11 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, mask.setElement<3>(); LLVector4a* tbuff = mikktspace ? vf.mMikktSpaceTangents : vf.mTangents; + if (tbuff == nullptr) + { // non-mesh prims will not have mikktspace tangents + tbuff = vf.mTangents; + } + LLVector4a* src = tbuff; LLVector4a* end = tbuff+num_vertices; @@ -2184,7 +2189,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, { LLVector4a tangent_out; mat_normal.rotate(*src, tangent_out); - tangent_out.normalize3fast(); + tangent_out.normalize3(); tangent_out.setSelectWithMask(mask, *src, tangent_out); tangent_out.store4a(tangents); -- cgit v1.3 From d7c77e5c64ddfef44b3e47f4c7ae6943ff0e860a Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Mon, 12 Sep 2022 11:48:16 -0500 Subject: SL-18095 WIP -- Use meshoptimizer to re-weld and cache optimize after generating tangents --- indra/cmake/LLMath.cmake | 1 + indra/llmath/llvolume.cpp | 56 +++++++++++++++++----- .../shaders/class1/deferred/pbropaqueV.glsl | 1 - indra/newview/llface.cpp | 1 - 4 files changed, 46 insertions(+), 13 deletions(-) (limited to 'indra/llmath') diff --git a/indra/cmake/LLMath.cmake b/indra/cmake/LLMath.cmake index 3cbb7ad561..513ff9f81d 100644 --- a/indra/cmake/LLMath.cmake +++ b/indra/cmake/LLMath.cmake @@ -2,6 +2,7 @@ include(Variables) include(Mikktspace) +include(MESHOPTIMIZER) set(LLMATH_INCLUDE_DIRS ${LIBS_OPEN_DIR}/llmath diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 0ce1577d00..fca9471f14 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -56,6 +56,8 @@ #include "mikktspace/mikktspace.h" #include "mikktspace/mikktspace.c" // insert mikktspace implementation into llvolume object file +#include "meshoptimizer/meshoptimizer.h" + #define DEBUG_SILHOUETTE_BINORMALS 0 #define DEBUG_SILHOUETTE_NORMALS 0 // TomY: Use this to display normals using the silhouette #define DEBUG_SILHOUETTE_EDGE_MAP 0 // DaveP: Use this to display edge map using the silhouette @@ -5499,34 +5501,66 @@ bool LLVolumeFace::cacheOptimize() SMikkTSpaceContext ctx = { &ms, &data }; genTangSpaceDefault(&ctx); - - resizeVertices(data.p.size()); - resizeIndices(data.p.size()); - + + //re-weld + meshopt_Stream mos[] = + { + { &data.p[0], sizeof(LLVector3), sizeof(LLVector3) }, + { &data.n[0], sizeof(LLVector3), sizeof(LLVector3) }, + { &data.t[0], sizeof(LLVector4), sizeof(LLVector4) }, + { &data.tc[0], sizeof(LLVector2), sizeof(LLVector2) }, + { data.w.empty() ? nullptr : &data.w[0], sizeof(LLVector4), sizeof(LLVector4) } + }; + + std::vector remap; + remap.resize(data.p.size()); + + U32 stream_count = data.w.empty() ? 4 : 5; + + U32 vert_count = meshopt_generateVertexRemapMulti(&remap[0], nullptr, data.p.size(), data.p.size(), mos, stream_count); + + std::vector indices; + indices.resize(mNumIndices); + + //copy results back into volume + resizeVertices(vert_count); + if (!data.w.empty()) { - allocateWeights(data.w.size()); + allocateWeights(vert_count); } allocateTangents(mNumVertices, true); for (int i = 0; i < mNumIndices; ++i) { - mIndices[i] = i; + U32 src_idx = i; + U32 dst_idx = remap[i]; + mIndices[i] = dst_idx; - mPositions[i].load3(data.p[i].mV); - mNormals[i].load3(data.n[i].mV); - mTexCoords[i] = data.tc[i]; + mPositions[dst_idx].load3(data.p[src_idx].mV); + mNormals[dst_idx].load3(data.n[src_idx].mV); + mTexCoords[dst_idx] = data.tc[src_idx]; - mMikktSpaceTangents[i].loadua(data.t[i].mV); + mMikktSpaceTangents[dst_idx].loadua(data.t[src_idx].mV); if (mWeights) { - mWeights[i].loadua(data.w[i].mV); + mWeights[dst_idx].loadua(data.w[src_idx].mV); } } + // cache optimize index buffer + + // meshopt needs scratch space, do some pointer shuffling to avoid an extra index buffer copy + U16* src_indices = mIndices; + mIndices = nullptr; + resizeIndices(mNumIndices); + + meshopt_optimizeVertexCache(mIndices, src_indices, mNumIndices, mNumVertices); + ll_aligned_free_16(src_indices); + return true; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl index c90a17993f..5573c02a60 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl @@ -76,7 +76,6 @@ void main() vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; vary_texcoord1 = (texture_matrix0 * vec4(texcoord1,0,1)).xy; vary_texcoord2 = (texture_matrix0 * vec4(texcoord2,0,1)).xy; - #ifdef HAS_SKIN vec3 n = (mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz; vec3 t = (mat*vec4(tangent.xyz+position.xyz,1.0)).xyz-pos.xyz; diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 83d35b7f3c..2827329739 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -2189,7 +2189,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, { LLVector4a tangent_out; mat_normal.rotate(*src, tangent_out); - tangent_out.normalize3(); tangent_out.setSelectWithMask(mask, *src, tangent_out); tangent_out.store4a(tangents); -- cgit v1.3 From e49d602bd99f5a3b1257ba1bc7ded133eab1eb1c Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Mon, 12 Sep 2022 19:48:33 -0500 Subject: SL-18095 Add tangents to mesh assets so we can calculate mikktspace tangents in the mesh's original coordinate frame. --- indra/llmath/llvolume.cpp | 233 ++++++++++++--------- indra/llprimitive/lldaeloader.cpp | 12 +- indra/llprimitive/llmodel.cpp | 41 ++++ indra/llprimitive/llmodel.h | 1 + .../shaders/class1/deferred/pbropaqueF.glsl | 2 + indra/newview/llmodelpreview.cpp | 20 +- 6 files changed, 202 insertions(+), 107 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index fca9471f14..563a325f03 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -2431,11 +2431,10 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) LLSD::Binary pos = mdl[i]["Position"]; LLSD::Binary norm = mdl[i]["Normal"]; + LLSD::Binary tangent = mdl[i]["Tangent"]; LLSD::Binary tc = mdl[i]["TexCoord0"]; LLSD::Binary idx = mdl[i]["TriangleList"]; - - //copy out indices S32 num_indices = idx.size() / 2; face.resizeIndices(num_indices); @@ -2534,6 +2533,33 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) } } + { + if (!tangent.empty()) + { + face.allocateTangents(face.mNumVertices, true); + U16* t = (U16*)&(tangent[0]); + + // store incoming tangents in mMikktSpaceTangents + // NOTE: tangents coming from the asset may not be mikkt space, but they should always be used by the CLTF shaders to + // maintain compliance with the GLTF spec + LLVector4a* t_out = face.mMikktSpaceTangents; + + for (U32 j = 0; j < num_verts; ++j) + { + t_out->set((F32)t[0], (F32)t[1], (F32)t[2], (F32) t[3]); + t_out->div(65535.f); + t_out->mul(2.f); + t_out->sub(1.f); + + F32* tp = t_out->getF32ptr(); + tp[3] = tp[3] < 0.f ? -1.f : 1.f; + + t_out++; + t += 4; + } + } + } + { if (!tc.empty()) { @@ -5429,124 +5455,135 @@ bool LLVolumeFace::cacheOptimize() llassert(!mOptimized); mOptimized = TRUE; - allocateTangents(mNumVertices, true); + if (!mNormals || !mTexCoords) + { // can't perform this operation without normals and texture coordinates + return false; + } - SMikkTSpaceInterface ms; + if (mMikktSpaceTangents == nullptr) + { // make sure to generate mikkt space tangents for cache optimizing since the index buffer may change + allocateTangents(mNumVertices, true); - ms.m_getNumFaces = [](const SMikkTSpaceContext* pContext) - { - MikktData* data = (MikktData*)pContext->m_pUserData; - LLVolumeFace* face = data->face; - return face->mNumIndices / 3; - }; + SMikkTSpaceInterface ms; - ms.m_getNumVerticesOfFace = [](const SMikkTSpaceContext* pContext, const int iFace) - { - return 3; - }; + ms.m_getNumFaces = [](const SMikkTSpaceContext* pContext) + { + MikktData* data = (MikktData*)pContext->m_pUserData; + LLVolumeFace* face = data->face; + return face->mNumIndices / 3; + }; - ms.m_getPosition = [](const SMikkTSpaceContext* pContext, float fvPosOut[], const int iFace, const int iVert) - { - MikktData* data = (MikktData*)pContext->m_pUserData; - LLVolumeFace* face = data->face; - S32 idx = face->mIndices[iFace * 3 + iVert]; - auto& vert = face->mPositions[idx]; - F32* v = vert.getF32ptr(); - fvPosOut[0] = v[0]; - fvPosOut[1] = v[1]; - fvPosOut[2] = v[2]; - }; - - ms.m_getNormal = [](const SMikkTSpaceContext* pContext, float fvNormOut[], const int iFace, const int iVert) - { - MikktData* data = (MikktData*)pContext->m_pUserData; - LLVolumeFace* face = data->face; - S32 idx = face->mIndices[iFace * 3 + iVert]; - auto& norm = face->mNormals[idx]; - F32* n = norm.getF32ptr(); - fvNormOut[0] = n[0]; - fvNormOut[1] = n[1]; - fvNormOut[2] = n[2]; - }; - - ms.m_getTexCoord = [](const SMikkTSpaceContext* pContext, float fvTexcOut[], const int iFace, const int iVert) - { - MikktData* data = (MikktData*)pContext->m_pUserData; - LLVolumeFace* face = data->face; - S32 idx = face->mIndices[iFace * 3 + iVert]; - auto& tc = face->mTexCoords[idx]; - fvTexcOut[0] = tc.mV[0]; - fvTexcOut[1] = tc.mV[1]; - }; - - ms.m_setTSpaceBasic = [](const SMikkTSpaceContext* pContext, const float fvTangent[], const float fSign, const int iFace, const int iVert) - { - MikktData* data = (MikktData*)pContext->m_pUserData; - LLVolumeFace* face = data->face; - S32 i = iFace * 3 + iVert; - S32 idx = face->mIndices[i]; + ms.m_getNumVerticesOfFace = [](const SMikkTSpaceContext* pContext, const int iFace) + { + return 3; + }; - LLVector3 p(face->mPositions[idx].getF32ptr()); - LLVector3 n(face->mNormals[idx].getF32ptr()); - LLVector3 t(fvTangent); + ms.m_getPosition = [](const SMikkTSpaceContext* pContext, float fvPosOut[], const int iFace, const int iVert) + { + MikktData* data = (MikktData*)pContext->m_pUserData; + LLVolumeFace* face = data->face; + S32 idx = face->mIndices[iFace * 3 + iVert]; + auto& vert = face->mPositions[idx]; + F32* v = vert.getF32ptr(); + fvPosOut[0] = v[0]; + fvPosOut[1] = v[1]; + fvPosOut[2] = v[2]; + }; + + ms.m_getNormal = [](const SMikkTSpaceContext* pContext, float fvNormOut[], const int iFace, const int iVert) + { + MikktData* data = (MikktData*)pContext->m_pUserData; + LLVolumeFace* face = data->face; + S32 idx = face->mIndices[iFace * 3 + iVert]; + auto& norm = face->mNormals[idx]; + F32* n = norm.getF32ptr(); + fvNormOut[0] = n[0]; + fvNormOut[1] = n[1]; + fvNormOut[2] = n[2]; + }; + + ms.m_getTexCoord = [](const SMikkTSpaceContext* pContext, float fvTexcOut[], const int iFace, const int iVert) + { + MikktData* data = (MikktData*)pContext->m_pUserData; + LLVolumeFace* face = data->face; + S32 idx = face->mIndices[iFace * 3 + iVert]; + auto& tc = face->mTexCoords[idx]; + fvTexcOut[0] = tc.mV[0]; + fvTexcOut[1] = tc.mV[1]; + }; + + ms.m_setTSpaceBasic = [](const SMikkTSpaceContext* pContext, const float fvTangent[], const float fSign, const int iFace, const int iVert) + { + MikktData* data = (MikktData*)pContext->m_pUserData; + LLVolumeFace* face = data->face; + S32 i = iFace * 3 + iVert; + S32 idx = face->mIndices[i]; - data->t[i].set(fvTangent); - data->t[i].mV[3] = fSign; - }; + LLVector3 p(face->mPositions[idx].getF32ptr()); + LLVector3 n(face->mNormals[idx].getF32ptr()); + LLVector3 t(fvTangent); - ms.m_setTSpace = nullptr; + // assert that this tangent hasn't already been set + llassert(data->t[i].magVec() < 0.1f); - MikktData data(this); + data->t[i].set(fvTangent); + data->t[i].mV[3] = fSign; + }; - SMikkTSpaceContext ctx = { &ms, &data }; + ms.m_setTSpace = nullptr; - genTangSpaceDefault(&ctx); + MikktData data(this); - //re-weld - meshopt_Stream mos[] = - { - { &data.p[0], sizeof(LLVector3), sizeof(LLVector3) }, - { &data.n[0], sizeof(LLVector3), sizeof(LLVector3) }, - { &data.t[0], sizeof(LLVector4), sizeof(LLVector4) }, - { &data.tc[0], sizeof(LLVector2), sizeof(LLVector2) }, - { data.w.empty() ? nullptr : &data.w[0], sizeof(LLVector4), sizeof(LLVector4) } - }; + SMikkTSpaceContext ctx = { &ms, &data }; - std::vector remap; - remap.resize(data.p.size()); + genTangSpaceDefault(&ctx); - U32 stream_count = data.w.empty() ? 4 : 5; + //re-weld + meshopt_Stream mos[] = + { + { &data.p[0], sizeof(LLVector3), sizeof(LLVector3) }, + { &data.n[0], sizeof(LLVector3), sizeof(LLVector3) }, + { &data.t[0], sizeof(LLVector4), sizeof(LLVector4) }, + { &data.tc[0], sizeof(LLVector2), sizeof(LLVector2) }, + { data.w.empty() ? nullptr : &data.w[0], sizeof(LLVector4), sizeof(LLVector4) } + }; - U32 vert_count = meshopt_generateVertexRemapMulti(&remap[0], nullptr, data.p.size(), data.p.size(), mos, stream_count); + std::vector remap; + remap.resize(data.p.size()); - std::vector indices; - indices.resize(mNumIndices); + U32 stream_count = data.w.empty() ? 4 : 5; - //copy results back into volume - resizeVertices(vert_count); + U32 vert_count = meshopt_generateVertexRemapMulti(&remap[0], nullptr, data.p.size(), data.p.size(), mos, stream_count); - if (!data.w.empty()) - { - allocateWeights(vert_count); - } + std::vector indices; + indices.resize(mNumIndices); - allocateTangents(mNumVertices, true); + //copy results back into volume + resizeVertices(vert_count); - for (int i = 0; i < mNumIndices; ++i) - { - U32 src_idx = i; - U32 dst_idx = remap[i]; - mIndices[i] = dst_idx; + if (!data.w.empty()) + { + allocateWeights(vert_count); + } - mPositions[dst_idx].load3(data.p[src_idx].mV); - mNormals[dst_idx].load3(data.n[src_idx].mV); - mTexCoords[dst_idx] = data.tc[src_idx]; - - mMikktSpaceTangents[dst_idx].loadua(data.t[src_idx].mV); + allocateTangents(mNumVertices, true); - if (mWeights) + for (int i = 0; i < mNumIndices; ++i) { - mWeights[dst_idx].loadua(data.w[src_idx].mV); + U32 src_idx = i; + U32 dst_idx = remap[i]; + mIndices[i] = dst_idx; + + mPositions[dst_idx].load3(data.p[src_idx].mV); + mNormals[dst_idx].load3(data.n[src_idx].mV); + mTexCoords[dst_idx] = data.tc[src_idx]; + + mMikktSpaceTangents[dst_idx].loadua(data.t[src_idx].mV); + + if (mWeights) + { + mWeights[dst_idx].loadua(data.w[src_idx].mV); + } } } diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp index 50f4a4306e..9470146ce4 100644 --- a/indra/llprimitive/lldaeloader.cpp +++ b/indra/llprimitive/lldaeloader.cpp @@ -2551,6 +2551,9 @@ bool LLDAELoader::loadModelsFromDomMesh(domMesh* mesh, std::vector& mo LLVolume::face_list_t remainder; do { + // generate tangents and cache optimize before normalizing + ret->preprocessVolumeFaces(); + // Insure we do this once with the whole gang and not per-model // if (!normalized && !mNoNormalize) @@ -2561,10 +2564,11 @@ bool LLDAELoader::loadModelsFromDomMesh(domMesh* mesh, std::vector& mo ret->trimVolumeFacesToSize(LL_SCULPT_MESH_MAX_FACES, &remainder); - if (!mNoOptimize) - { - ret->remapVolumeFaces(); - } + // remove unused/redundant vertices after normalizing + //if (!mNoOptimize) + //{ + // ret->remapVolumeFaces(); + //} volume_faces = remainder.size(); diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index 285c5f656b..1ce287d773 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -187,6 +187,15 @@ void LLModel::trimVolumeFacesToSize(U32 new_count, LLVolume::face_list_t* remain } } +// generate mikkt space tangents and cache optimize +void LLModel::preprocessVolumeFaces() +{ + for (auto& face : mVolumeFaces) + { + face.cacheOptimize(); + } +} + // Shrink the model to fit // on a 1x1x1 cube centered at the origin. // The positions and extents @@ -296,6 +305,7 @@ void LLModel::normalizeVolumeFaces() // the positions to fit within the unit cube. LLVector4a* pos = (LLVector4a*) face.mPositions; LLVector4a* norm = (LLVector4a*) face.mNormals; + LLVector4a* t = (LLVector4a*)face.mMikktSpaceTangents; for (U32 j = 0; j < face.mNumVertices; ++j) { @@ -306,6 +316,14 @@ void LLModel::normalizeVolumeFaces() norm[j].mul(inv_scale); norm[j].normalize3(); } + + if (t) + { + F32 w = t[j].getF32ptr()[3]; + t[j].mul(inv_scale); + t[j].normalize3(); + t[j].getF32ptr()[3] = w; + } } } @@ -726,10 +744,12 @@ LLSD LLModel::writeModel( LLSD::Binary verts(face.mNumVertices*3*2); LLSD::Binary tc(face.mNumVertices*2*2); LLSD::Binary normals(face.mNumVertices*3*2); + LLSD::Binary tangents(face.mNumVertices * 4 * 2); LLSD::Binary indices(face.mNumIndices*2); U32 vert_idx = 0; U32 norm_idx = 0; + U32 tan_idx = 0; U32 tc_idx = 0; LLVector2* ftc = (LLVector2*) face.mTexCoords; @@ -782,6 +802,22 @@ LLSD LLModel::writeModel( normals[norm_idx++] = buff[1]; } } + + if (face.mMikktSpaceTangents) + { //normals + F32* tangent = face.mMikktSpaceTangents[j].getF32ptr(); + + for (U32 k = 0; k < 4; ++k) + { //for each component + //convert to 16-bit normalized + U16 val = (U16)((tangent[k] + 1.f) * 0.5f * 65535); + U8* buff = (U8*)&val; + + //write to binary buffer + tangents[tan_idx++] = buff[0]; + tangents[tan_idx++] = buff[1]; + } + } //texcoord if (face.mTexCoords) @@ -819,6 +855,11 @@ LLSD LLModel::writeModel( mdl[model_names[idx]][i]["Normal"] = normals; } + if (face.mMikktSpaceTangents) + { + mdl[model_names[idx]][i]["Tangent"] = tangents; + } + if (face.mTexCoords) { mdl[model_names[idx]][i]["TexCoord0Domain"]["Min"] = min_tc.getValue(); diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h index 354ceb26b7..ea97851ce8 100644 --- a/indra/llprimitive/llmodel.h +++ b/indra/llprimitive/llmodel.h @@ -182,6 +182,7 @@ public: void addFace(const LLVolumeFace& face); void sortVolumeFacesByMaterialName(); + void preprocessVolumeFaces(); void normalizeVolumeFaces(); void trimVolumeFacesToSize(U32 new_count = LL_SCULPT_MESH_MAX_FACES, LLVolume::face_list_t* remainder = NULL); void remapVolumeFaces(); diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl index ca304f749a..f0f5208f52 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl @@ -94,6 +94,8 @@ void main() //col = vec3(0,0,0); //emissive = vary_tangent.xyz*0.5+0.5; //emissive = vec3(sign*0.5+0.5); + //emissive = vNt * 0.5 + 0.5; + //emissive = tnorm*0.5+0.5; // See: C++: addDeferredAttachments(), GLSL: softenLightF frag_data[0] = vec4(col, 0.0); // Diffuse frag_data[1] = vec4(emissive, vertex_color.a); // PBR sRGB Emissive diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index c3fbada9db..2c0f0ae443 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -1308,9 +1308,10 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe // extra space for normals and text coords S32 tc_bytes_size = ((size_vertices * sizeof(LLVector2)) + 0xF) & ~0xF; - LLVector4a* combined_positions = (LLVector4a*)ll_aligned_malloc<64>(sizeof(LLVector4a) * 2 * size_vertices + tc_bytes_size); + LLVector4a* combined_positions = (LLVector4a*)ll_aligned_malloc<64>(sizeof(LLVector4a) * 3 * size_vertices + tc_bytes_size); LLVector4a* combined_normals = combined_positions + size_vertices; - LLVector2* combined_tex_coords = (LLVector2*)(combined_normals + size_vertices); + LLVector4a* combined_tangents = combined_normals + size_vertices; + LLVector2* combined_tex_coords = (LLVector2*)(combined_tangents + size_vertices); // copy indices and vertices into new buffers S32 combined_positions_shift = 0; @@ -1320,6 +1321,9 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe { const LLVolumeFace &face = base_model->getVolumeFace(face_idx); + // ensure tangents have been generated or loaded + llassert(face.mMikktSpaceTangents); + // Vertices S32 copy_bytes = face.mNumVertices * sizeof(LLVector4a); LLVector4a::memcpyNonAliased16((F32*)(combined_positions + combined_positions_shift), (F32*)face.mPositions, copy_bytes); @@ -1327,6 +1331,9 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe // Normals LLVector4a::memcpyNonAliased16((F32*)(combined_normals + combined_positions_shift), (F32*)face.mNormals, copy_bytes); + // Tangents + LLVector4a::memcpyNonAliased16((F32*)(combined_tangents + combined_positions_shift), (F32*)face.mMikktSpaceTangents, copy_bytes); + // Tex coords copy_bytes = face.mNumVertices * sizeof(LLVector2); memcpy((void*)(combined_tex_coords + combined_positions_shift), (void*)face.mTexCoords, copy_bytes); @@ -1428,9 +1435,10 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe // IV. Repack back into individual faces - LLVector4a* buffer_positions = (LLVector4a*)ll_aligned_malloc<64>(sizeof(LLVector4a) * 2 * size_vertices + tc_bytes_size); + LLVector4a* buffer_positions = (LLVector4a*)ll_aligned_malloc<64>(sizeof(LLVector4a) * 3 * size_vertices + tc_bytes_size); LLVector4a* buffer_normals = buffer_positions + size_vertices; - LLVector2* buffer_tex_coords = (LLVector2*)(buffer_normals + size_vertices); + LLVector4a* buffer_tangents = buffer_normals + size_vertices; + LLVector2* buffer_tex_coords = (LLVector2*)(buffer_tangents + size_vertices); S32 buffer_idx_size = (size_indices * sizeof(U16) + 0xF) & ~0xF; U16* buffer_indices = (U16*)ll_aligned_malloc_16(buffer_idx_size); S32* old_to_new_positions_map = new S32[size_vertices]; @@ -1511,6 +1519,7 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe // Copy vertice, normals, tcs buffer_positions[buf_positions_copied] = combined_positions[idx]; buffer_normals[buf_positions_copied] = combined_normals[idx]; + buffer_tangents[buf_positions_copied] = combined_tangents[idx]; buffer_tex_coords[buf_positions_copied] = combined_tex_coords[idx]; old_to_new_positions_map[idx] = buf_positions_copied; @@ -1549,12 +1558,13 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe { new_face.resizeIndices(buf_indices_copied); new_face.resizeVertices(buf_positions_copied); - + new_face.allocateTangents(buf_positions_copied, true); S32 idx_size = (buf_indices_copied * sizeof(U16) + 0xF) & ~0xF; LLVector4a::memcpyNonAliased16((F32*)new_face.mIndices, (F32*)buffer_indices, idx_size); LLVector4a::memcpyNonAliased16((F32*)new_face.mPositions, (F32*)buffer_positions, buf_positions_copied * sizeof(LLVector4a)); LLVector4a::memcpyNonAliased16((F32*)new_face.mNormals, (F32*)buffer_normals, buf_positions_copied * sizeof(LLVector4a)); + LLVector4a::memcpyNonAliased16((F32*)new_face.mMikktSpaceTangents, (F32*)buffer_tangents, buf_positions_copied * sizeof(LLVector4a)); U32 tex_size = (buf_positions_copied * sizeof(LLVector2) + 0xF)&~0xF; LLVector4a::memcpyNonAliased16((F32*)new_face.mTexCoords, (F32*)buffer_tex_coords, tex_size); -- cgit v1.3 From 82ab5f9765ad76c73d1d7ddd5716b22d6b92bf62 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 15 Sep 2022 17:23:34 -0500 Subject: SL-18156 WIP -- Add NormalizedScale/NormalizedTranslation to mesh assets to recover mesh's original coordinate frame when generating tangents post download. --- indra/llmath/llvolume.cpp | 78 +++++++++++++++++++++++++++------------- indra/llmath/llvolume.h | 6 ++++ indra/llprimitive/llmodel.cpp | 13 ++++++- indra/newview/llmodelpreview.cpp | 9 +++++ 4 files changed, 81 insertions(+), 25 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 563a325f03..ae753fc0f3 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -2483,6 +2483,24 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) min_tc.setValue(mdl[i]["TexCoord0Domain"]["Min"]); max_tc.setValue(mdl[i]["TexCoord0Domain"]["Max"]); + //unpack normalized scale/translation + if (mdl[i].has("NormalizedScale")) + { + face.mNormalizedScale.setValue(mdl[i]["NormalizedScale"]); + } + else + { + face.mNormalizedScale.set(1, 1, 1); + } + if (mdl[i].has("NormalizedTranslation")) + { + face.mNormalizedTranslation.setValue(mdl[i]["NormalizedTranslation"]); + } + else + { + face.mNormalizedTranslation.set(1, 1, 1); + } + LLVector4a pos_range; pos_range.setSub(max_pos, min_pos); LLVector2 tc_range2 = max_tc - min_tc; @@ -2533,6 +2551,7 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) } } +#if 0 { if (!tangent.empty()) { @@ -2559,6 +2578,7 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) } } } +#endif { if (!tc.empty()) @@ -4888,7 +4908,9 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src) } mOptimized = src.mOptimized; - + mNormalizedScale = src.mNormalizedScale; + mNormalizedTranslation = src.mNormalizedTranslation; + //delete return *this; } @@ -5432,12 +5454,19 @@ struct MikktData w.resize(count); } + + LLVector3 inv_scale(1.f / face->mNormalizedScale.mV[0], 1.f / face->mNormalizedScale.mV[1], 1.f / face->mNormalizedScale.mV[2]); + + for (int i = 0; i < face->mNumIndices; ++i) { U32 idx = face->mIndices[i]; p[i].set(face->mPositions[idx].getF32ptr()); + p[i].scaleVec(face->mNormalizedScale); //put mesh in original coordinate frame when reconstructing tangents n[i].set(face->mNormals[idx].getF32ptr()); + n[i].scaleVec(inv_scale); + n[i].normalize(); tc[i].set(face->mTexCoords[idx]); if (face->mWeights) @@ -5481,10 +5510,7 @@ bool LLVolumeFace::cacheOptimize() ms.m_getPosition = [](const SMikkTSpaceContext* pContext, float fvPosOut[], const int iFace, const int iVert) { MikktData* data = (MikktData*)pContext->m_pUserData; - LLVolumeFace* face = data->face; - S32 idx = face->mIndices[iFace * 3 + iVert]; - auto& vert = face->mPositions[idx]; - F32* v = vert.getF32ptr(); + F32* v = data->p[iFace * 3 + iVert].mV; fvPosOut[0] = v[0]; fvPosOut[1] = v[1]; fvPosOut[2] = v[2]; @@ -5493,10 +5519,7 @@ bool LLVolumeFace::cacheOptimize() ms.m_getNormal = [](const SMikkTSpaceContext* pContext, float fvNormOut[], const int iFace, const int iVert) { MikktData* data = (MikktData*)pContext->m_pUserData; - LLVolumeFace* face = data->face; - S32 idx = face->mIndices[iFace * 3 + iVert]; - auto& norm = face->mNormals[idx]; - F32* n = norm.getF32ptr(); + F32* n = data->n[iFace * 3 + iVert].mV; fvNormOut[0] = n[0]; fvNormOut[1] = n[1]; fvNormOut[2] = n[2]; @@ -5505,27 +5528,16 @@ bool LLVolumeFace::cacheOptimize() ms.m_getTexCoord = [](const SMikkTSpaceContext* pContext, float fvTexcOut[], const int iFace, const int iVert) { MikktData* data = (MikktData*)pContext->m_pUserData; - LLVolumeFace* face = data->face; - S32 idx = face->mIndices[iFace * 3 + iVert]; - auto& tc = face->mTexCoords[idx]; - fvTexcOut[0] = tc.mV[0]; - fvTexcOut[1] = tc.mV[1]; + F32* tc = data->tc[iFace * 3 + iVert].mV; + fvTexcOut[0] = tc[0]; + fvTexcOut[1] = tc[1]; }; ms.m_setTSpaceBasic = [](const SMikkTSpaceContext* pContext, const float fvTangent[], const float fSign, const int iFace, const int iVert) { MikktData* data = (MikktData*)pContext->m_pUserData; - LLVolumeFace* face = data->face; S32 i = iFace * 3 + iVert; - S32 idx = face->mIndices[i]; - - LLVector3 p(face->mPositions[idx].getF32ptr()); - LLVector3 n(face->mNormals[idx].getF32ptr()); - LLVector3 t(fvTangent); - - // assert that this tangent hasn't already been set - llassert(data->t[i].magVec() < 0.1f); - + data->t[i].set(fvTangent); data->t[i].mV[3] = fSign; }; @@ -5585,6 +5597,24 @@ bool LLVolumeFace::cacheOptimize() mWeights[dst_idx].loadua(data.w[src_idx].mV); } } + + + // put back in normalized coordinate frame + LLVector4a inv_scale(1.f/mNormalizedScale.mV[0], 1.f / mNormalizedScale.mV[1], 1.f / mNormalizedScale.mV[2]); + LLVector4a scale; + scale.load3(mNormalizedScale.mV); + scale.getF32ptr()[3] = 1.f; + + for (int i = 0; i < mNumVertices; ++i) + { + mPositions[i].mul(inv_scale); + mNormals[i].mul(scale); + mNormals[i].normalize3(); + F32 w = mMikktSpaceTangents[i].getF32ptr()[3]; + mMikktSpaceTangents[i].mul(scale); + mMikktSpaceTangents[i].normalize3(); + mMikktSpaceTangents[i].getF32ptr()[3] = w; + } } // cache optimize index buffer diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index f1feaade58..e373d0175d 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -984,6 +984,12 @@ public: //whether or not face has been cache optimized BOOL mOptimized; + // if this is a mesh asset, scale and translation that were applied + // when encoding the source mesh into a unit cube + // used for regenerating tangents + LLVector3 mNormalizedScale = LLVector3(1,1,1); + LLVector3 mNormalizedTranslation; + private: BOOL createUnCutCubeCap(LLVolume* volume, BOOL partial_build = FALSE); BOOL createCap(LLVolume* volume, BOOL partial_build = FALSE); diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index 1ce287d773..ab507edc40 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -337,6 +337,12 @@ void LLModel::normalizeVolumeFaces() mNormalizedScale.set(normalized_scale.getF32ptr()); mNormalizedTranslation.set(trans.getF32ptr()); mNormalizedTranslation *= -1.f; + + for (auto& face : mVolumeFaces) + { + face.mNormalizedScale = mNormalizedScale; + face.mNormalizedTranslation = mNormalizedTranslation; + } } } @@ -749,7 +755,7 @@ LLSD LLModel::writeModel( U32 vert_idx = 0; U32 norm_idx = 0; - U32 tan_idx = 0; + //U32 tan_idx = 0; U32 tc_idx = 0; LLVector2* ftc = (LLVector2*) face.mTexCoords; @@ -803,6 +809,7 @@ LLSD LLModel::writeModel( } } +#if 0 if (face.mMikktSpaceTangents) { //normals F32* tangent = face.mMikktSpaceTangents[j].getF32ptr(); @@ -818,6 +825,7 @@ LLSD LLModel::writeModel( tangents[tan_idx++] = buff[1]; } } +#endif //texcoord if (face.mTexCoords) @@ -848,6 +856,9 @@ LLSD LLModel::writeModel( //write out face data mdl[model_names[idx]][i]["PositionDomain"]["Min"] = min_pos.getValue(); mdl[model_names[idx]][i]["PositionDomain"]["Max"] = max_pos.getValue(); + mdl[model_names[idx]][i]["NormalizedScale"] = face.mNormalizedScale.getValue(); + mdl[model_names[idx]][i]["NormalizedTranslation"] = face.mNormalizedTranslation.getValue(); + mdl[model_names[idx]][i]["Position"] = verts; if (face.mNormals) diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index 2c0f0ae443..4a85d459c5 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -1843,6 +1843,15 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d LLModel* target_model = mModel[lod][mdl_idx]; + // carry over normalized transform into simplified model + for (int i = 0; i < base->getNumVolumeFaces(); ++i) + { + LLVolumeFace& src = base->getVolumeFace(i); + LLVolumeFace& dst = target_model->getVolumeFace(i); + dst.mNormalizedScale = src.mNormalizedScale; + dst.mNormalizedTranslation = src.mNormalizedTranslation; + } + S32 model_meshopt_mode = meshopt_mode; // Ideally this should run not per model, -- cgit v1.3 From 8dc59e5ef37836b15d478fb0d04e3043a9f986de Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 16 Sep 2022 16:25:26 -0500 Subject: SL-18128 Clear out much OpenGL cruft and switch to core profile on AMD --- indra/llmath/llvolume.cpp | 15 +- indra/llmath/llvolume.h | 11 +- indra/llprimitive/lldaeloader.cpp | 11 +- indra/llprimitive/llmodel.cpp | 9 - indra/llprimitive/llmodel.h | 1 - indra/llrender/llcubemap.cpp | 6 +- indra/llrender/llgl.cpp | 440 ++------------------- indra/llrender/llgl.h | 63 +-- indra/llrender/llglheaders.h | 277 ------------- indra/llrender/llimagegl.cpp | 110 ++---- indra/llrender/llimagegl.h | 2 +- indra/llrender/llrender.cpp | 50 +-- indra/llrender/llrender.h | 2 - indra/llrender/llrendertarget.cpp | 20 +- indra/llrender/llvertexbuffer.cpp | 200 +++------- indra/newview/app_settings/settings.xml | 12 - indra/newview/featuretable.txt | 7 +- indra/newview/lldrawpoolterrain.cpp | 17 - indra/newview/lldrawpoolwater.cpp | 8 +- indra/newview/lldynamictexture.cpp | 4 +- indra/newview/llface.cpp | 200 +--------- indra/newview/llface.h | 2 - indra/newview/llfeaturemanager.cpp | 38 +- indra/newview/llfloaterpreference.cpp | 11 +- indra/newview/llglsandbox.cpp | 22 +- indra/newview/llscenemonitor.cpp | 8 +- indra/newview/llviewercontrol.cpp | 2 +- indra/newview/llviewermenu.cpp | 40 -- indra/newview/llvieweroctree.cpp | 27 +- indra/newview/llviewershadermgr.cpp | 176 +-------- indra/newview/llviewershadermgr.h | 11 - indra/newview/llviewerwindow.cpp | 33 -- indra/newview/llvosky.cpp | 4 +- indra/newview/llvovolume.cpp | 32 +- indra/newview/pipeline.cpp | 19 +- indra/newview/skins/default/xui/en/menu_viewer.xml | 2 - 36 files changed, 221 insertions(+), 1671 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index ae753fc0f3..559d790d77 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -2783,7 +2783,7 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) } } - if (!cacheOptimize()) + if (!cacheOptimize(true)) { // Out of memory? LL_WARNS() << "Failed to optimize!" << LL_ENDL; @@ -2824,11 +2824,11 @@ void LLVolume::copyVolumeFaces(const LLVolume* volume) mSculptLevel = 0; } -bool LLVolume::cacheOptimize() +bool LLVolume::cacheOptimize(bool gen_tangents) { for (S32 i = 0; i < mVolumeFaces.size(); ++i) { - if (!mVolumeFaces[i].cacheOptimize()) + if (!mVolumeFaces[i].cacheOptimize(gen_tangents)) { return false; } @@ -5478,18 +5478,13 @@ struct MikktData }; -bool LLVolumeFace::cacheOptimize() +bool LLVolumeFace::cacheOptimize(bool gen_tangents) { //optimize for vertex cache according to Forsyth method: LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; llassert(!mOptimized); mOptimized = TRUE; - if (!mNormals || !mTexCoords) - { // can't perform this operation without normals and texture coordinates - return false; - } - - if (mMikktSpaceTangents == nullptr) + if (mMikktSpaceTangents == nullptr && gen_tangents && mNormals && mTexCoords) { // make sure to generate mikkt space tangents for cache optimizing since the index buffer may change allocateTangents(mNumVertices, true); diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index e373d0175d..6ea12c6920 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -907,7 +907,7 @@ public: void remap(); void optimize(F32 angle_cutoff = 2.f); - bool cacheOptimize(); + bool cacheOptimize(bool gen_tangents = false); void createOctree(F32 scaler = 0.25f, const LLVector4a& center = LLVector4a(0,0,0), const LLVector4a& size = LLVector4a(0.5f,0.5f,0.5f)); @@ -957,10 +957,6 @@ public: // indexes for mPositions/mNormals/mTexCoords U16* mIndices; - // vertex buffer filled in by LLFace to cache this volume face geometry in vram - // (declared as a LLPointer to LLRefCount to avoid dependency on LLVertexBuffer) - mutable LLPointer mVertexBuffer; - std::vector mEdge; //list of skin weights for rigged volumes @@ -1089,7 +1085,10 @@ public: void copyVolumeFaces(const LLVolume* volume); void copyFacesTo(std::vector &faces) const; void copyFacesFrom(const std::vector &faces); - bool cacheOptimize(); + + // use meshoptimizer to optimize index buffer for vertex shader cache + // gen_tangents - if true, generate MikkTSpace tangents if needed before optimizing index buffer + bool cacheOptimize(bool gen_tangents = false); private: void sculptGenerateMapVertices(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, U8 sculpt_type); diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp index 9470146ce4..dbb34ab60b 100644 --- a/indra/llprimitive/lldaeloader.cpp +++ b/indra/llprimitive/lldaeloader.cpp @@ -2551,9 +2551,6 @@ bool LLDAELoader::loadModelsFromDomMesh(domMesh* mesh, std::vector& mo LLVolume::face_list_t remainder; do { - // generate tangents and cache optimize before normalizing - ret->preprocessVolumeFaces(); - // Insure we do this once with the whole gang and not per-model // if (!normalized && !mNoNormalize) @@ -2565,10 +2562,10 @@ bool LLDAELoader::loadModelsFromDomMesh(domMesh* mesh, std::vector& mo ret->trimVolumeFacesToSize(LL_SCULPT_MESH_MAX_FACES, &remainder); // remove unused/redundant vertices after normalizing - //if (!mNoOptimize) - //{ - // ret->remapVolumeFaces(); - //} + if (!mNoOptimize) + { + ret->remapVolumeFaces(); + } volume_faces = remainder.size(); diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index ab507edc40..eff47d9d98 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -187,15 +187,6 @@ void LLModel::trimVolumeFacesToSize(U32 new_count, LLVolume::face_list_t* remain } } -// generate mikkt space tangents and cache optimize -void LLModel::preprocessVolumeFaces() -{ - for (auto& face : mVolumeFaces) - { - face.cacheOptimize(); - } -} - // Shrink the model to fit // on a 1x1x1 cube centered at the origin. // The positions and extents diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h index ea97851ce8..354ceb26b7 100644 --- a/indra/llprimitive/llmodel.h +++ b/indra/llprimitive/llmodel.h @@ -182,7 +182,6 @@ public: void addFace(const LLVolumeFace& face); void sortVolumeFacesByMaterialName(); - void preprocessVolumeFaces(); void normalizeVolumeFaces(); void trimVolumeFacesToSize(U32 new_count = LL_SCULPT_MESH_MAX_FACES, LLVolume::face_list_t* remainder = NULL); void remapVolumeFaces(); diff --git a/indra/llrender/llcubemap.cpp b/indra/llrender/llcubemap.cpp index e41765622f..254288a86e 100644 --- a/indra/llrender/llcubemap.cpp +++ b/indra/llrender/llcubemap.cpp @@ -67,7 +67,7 @@ void LLCubeMap::initGL() { llassert(gGLManager.mInited); - if (gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps) + if (LLCubeMap::sUseCubeMaps) { // Not initialized, do stuff. if (mImages[0].isNull()) @@ -252,7 +252,7 @@ void LLCubeMap::enable(S32 stage) void LLCubeMap::enableTexture(S32 stage) { mTextureStage = stage; - if (gGLManager.mHasCubeMap && stage >= 0 && LLCubeMap::sUseCubeMaps) + if (stage >= 0 && LLCubeMap::sUseCubeMaps) { gGL.getTexUnit(stage)->enable(LLTexUnit::TT_CUBE_MAP); } @@ -265,7 +265,7 @@ void LLCubeMap::disable(void) void LLCubeMap::disableTexture(void) { - if (gGLManager.mHasCubeMap && mTextureStage >= 0 && LLCubeMap::sUseCubeMaps) + if (mTextureStage >= 0 && LLCubeMap::sUseCubeMaps) { gGL.getTexUnit(mTextureStage)->disable(); if (mTextureStage == 0) diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index 5253ed3d51..71303b0517 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -86,15 +86,15 @@ void APIENTRY gl_debug_callback(GLenum source, const GLchar* message, GLvoid* userParam) { - /*if (severity != GL_DEBUG_SEVERITY_HIGH_ARB // && - severity != GL_DEBUG_SEVERITY_MEDIUM_ARB && - severity != GL_DEBUG_SEVERITY_LOW_ARB + /*if (severity != GL_DEBUG_SEVERITY_HIGH // && + severity != GL_DEBUG_SEVERITY_MEDIUM && + severity != GL_DEBUG_SEVERITY_LOW ) { //suppress out-of-spec messages sent by nvidia driver (mostly vertexbuffer hints) return; }*/ - if (severity == GL_DEBUG_SEVERITY_HIGH_ARB) + if (severity == GL_DEBUG_SEVERITY_HIGH) { LL_WARNS() << "----- GL ERROR --------" << LL_ENDL; } @@ -107,7 +107,15 @@ void APIENTRY gl_debug_callback(GLenum source, LL_WARNS() << "Severity: " << std::hex << severity << LL_ENDL; LL_WARNS() << "Message: " << message << LL_ENDL; LL_WARNS() << "-----------------------" << LL_ENDL; - if (severity == GL_DEBUG_SEVERITY_HIGH_ARB) + + GLint vao = 0; + glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &vao); + GLint vbo = 0; + glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &vbo); + GLint ibo = 0; + glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &ibo); + + if (severity == GL_DEBUG_SEVERITY_HIGH) { LL_ERRS() << "Halting on GL Error" << LL_ENDL; } @@ -931,44 +939,12 @@ LLGLManager gGLManager; LLGLManager::LLGLManager() : mInited(FALSE), mIsDisabled(FALSE), - - mHasMultitexture(FALSE), - mHasATIMemInfo(FALSE), - mHasAMDAssociations(FALSE), - mHasNVXMemInfo(FALSE), - mNumTextureUnits(1), - mHasMipMapGeneration(FALSE), - mHasCompressedTextures(FALSE), - mHasFramebufferObject(FALSE), mMaxSamples(0), - mHasBlendFuncSeparate(FALSE), - mHasSync(FALSE), - mHasVertexBufferObject(FALSE), - mHasVertexArrayObject(FALSE), - mHasMapBufferRange(FALSE), - mHasFlushBufferRange(FALSE), - mHasPBuffer(FALSE), - mNumTextureImageUnits(0), - mHasOcclusionQuery(FALSE), - mHasTimerQuery(FALSE), - mHasOcclusionQuery2(FALSE), - mHasPointParameters(FALSE), - mHasDrawBuffers(FALSE), - mHasTextureRectangle(FALSE), - mHasTextureMultisample(FALSE), - mHasTransformFeedback(FALSE), - mHasUniformBufferObject(FALSE), + mNumTextureImageUnits(1), mMaxSampleMaskWords(0), mMaxColorTextureSamples(0), mMaxDepthTextureSamples(0), mMaxIntegerSamples(0), - - mHasAnisotropic(FALSE), - mHasARBEnvCombine(FALSE), - mHasCubeMap(FALSE), - mHasCubeMapArray(FALSE), - mHasDebugOutput(FALSE), - mIsAMD(FALSE), mIsNVIDIA(FALSE), mIsIntel(FALSE), @@ -976,9 +952,6 @@ LLGLManager::LLGLManager() : mIsMobileGF(FALSE), #endif mHasRequirements(TRUE), - - mHasSeparateSpecularColor(FALSE), - mDriverVersionMajor(1), mDriverVersionMinor(0), mDriverVersionRelease(0), @@ -996,7 +969,6 @@ LLGLManager::LLGLManager() : //--------------------------------------------------------------------- void LLGLManager::initWGL() { - mHasPBuffer = FALSE; #if LL_WINDOWS && !LL_MESA_HEADLESS if (!glh_init_extensions("WGL_ARB_pixel_format")) { @@ -1035,10 +1007,6 @@ void LLGLManager::initWGL() { LL_WARNS("RenderInit") << "No ARB WGL render texture extensions" << LL_ENDL; } - - mHasPBuffer = ExtensionExists("WGL_ARB_pbuffer", gGLHExts.mSysExts) && - ExtensionExists("WGL_ARB_render_texture", gGLHExts.mSysExts) && - ExtensionExists("WGL_ARB_pixel_format", gGLHExts.mSysExts); #endif } @@ -1052,7 +1020,7 @@ bool LLGLManager::initGL() stop_glerror(); -#if LL_WINDOWS +#if 0 && LL_WINDOWS if (!glGetStringi) { glGetStringi = (PFNGLGETSTRINGIPROC) GLH_EXT_GET_PROC_ADDRESS("glGetStringi"); @@ -1199,23 +1167,6 @@ bool LLGLManager::initGL() } #endif - if (mHasATIMemInfo && mVRAM == 0) - { //ask the gl how much vram is free at startup and attempt to use no more than half of that - S32 meminfo[4]; - glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, meminfo); - - mVRAM = meminfo[0] / 1024; - LL_WARNS("RenderInit") << "VRAM Detected (ATIMemInfo):" << mVRAM << LL_ENDL; - } - - if (mHasNVXMemInfo && mVRAM == 0) - { - S32 dedicated_memory; - glGetIntegerv(GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &dedicated_memory); - mVRAM = dedicated_memory/1024; - LL_WARNS("RenderInit") << "VRAM Detected (NVXMemInfo):" << mVRAM << LL_ENDL; - } - #if LL_WINDOWS if (mVRAM < 256) { @@ -1243,62 +1194,22 @@ bool LLGLManager::initGL() stop_glerror(); - GLint num_tex_image_units; - glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &num_tex_image_units); - mNumTextureImageUnits = llmin(num_tex_image_units, 32); - - if (mHasMultitexture) + glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &mNumTextureImageUnits); + stop_glerror(); + glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &mMaxColorTextureSamples); + stop_glerror(); + glGetIntegerv(GL_MAX_DEPTH_TEXTURE_SAMPLES, &mMaxDepthTextureSamples); + stop_glerror(); + glGetIntegerv(GL_MAX_INTEGER_SAMPLES, &mMaxIntegerSamples); + stop_glerror(); + glGetIntegerv(GL_MAX_SAMPLE_MASK_WORDS, &mMaxSampleMaskWords); + stop_glerror(); + glGetIntegerv(GL_MAX_SAMPLES, &mMaxSamples); + stop_glerror(); + if (mGLVersion >= 4.59f) { - if (LLRender::sGLCoreProfile) - { - mNumTextureUnits = llmin(mNumTextureImageUnits, MAX_GL_TEXTURE_UNITS); - } - else - { - GLint num_tex_units; - glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &num_tex_units); - mNumTextureUnits = llmin(num_tex_units, (GLint)MAX_GL_TEXTURE_UNITS); - if (mIsIntel) - { - mNumTextureUnits = llmin(mNumTextureUnits, 2); - } - } + glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY, &mMaxAnisotropy); } - else - { - mHasRequirements = FALSE; - - // We don't support cards that don't support the GL_ARB_multitexture extension - LL_WARNS("RenderInit") << "GL Drivers do not support GL_ARB_multitexture" << LL_ENDL; - return false; - } - - stop_glerror(); - - if (mHasTextureMultisample) - { - glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &mMaxColorTextureSamples); - glGetIntegerv(GL_MAX_DEPTH_TEXTURE_SAMPLES, &mMaxDepthTextureSamples); - glGetIntegerv(GL_MAX_INTEGER_SAMPLES, &mMaxIntegerSamples); - glGetIntegerv(GL_MAX_SAMPLE_MASK_WORDS, &mMaxSampleMaskWords); - } - - stop_glerror(); - - //HACK always disable texture multisample, use FXAA instead - mHasTextureMultisample = FALSE; -#if LL_WINDOWS - if (mIsIntel && mGLVersion <= 3.f) - { //never try to use framebuffer objects on older intel drivers (crashy) - mHasFramebufferObject = FALSE; - } -#endif - - if (mHasFramebufferObject) - { - glGetIntegerv(GL_MAX_SAMPLES, &mMaxSamples); - } - stop_glerror(); initGLStates(); @@ -1406,62 +1317,22 @@ void LLGLManager::asLLSD(LLSD& info) info["vram"] = mVRAM; - // Extensions used by everyone - info["has_multitexture"] = mHasMultitexture; - info["has_ati_mem_info"] = mHasATIMemInfo; - info["has_nvx_mem_info"] = mHasNVXMemInfo; - info["num_texture_units"] = mNumTextureUnits; - info["has_mip_map_generation"] = mHasMipMapGeneration; - info["has_compressed_textures"] = mHasCompressedTextures; - info["has_framebuffer_object"] = mHasFramebufferObject; + // OpenGL limits info["max_samples"] = mMaxSamples; - info["has_blend_func_separate"] = mHasBlendFuncSeparate || LLRender::sGLCoreProfile; - - // ARB Extensions - info["has_vertex_buffer_object"] = mHasVertexBufferObject; - info["has_vertex_array_object"] = mHasVertexArrayObject; - info["has_sync"] = mHasSync; - info["has_map_buffer_range"] = mHasMapBufferRange; - info["has_flush_buffer_range"] = mHasFlushBufferRange; - info["has_pbuffer"] = mHasPBuffer; - info["has_shader_objects"] = std::string("Assumed TRUE"); // was mHasShaderObjects; - info["has_vertex_shader"] = std::string("Assumed TRUE"); // was mHasVertexShader; - info["has_fragment_shader"] = std::string("Assumed TRUE"); // was mHasFragmentShader; info["num_texture_image_units"] = mNumTextureImageUnits; - info["has_occlusion_query"] = mHasOcclusionQuery; - info["has_timer_query"] = mHasTimerQuery; - info["has_occlusion_query2"] = mHasOcclusionQuery2; - info["has_point_parameters"] = mHasPointParameters; - info["has_draw_buffers"] = mHasDrawBuffers; - info["has_depth_clamp"] = mHasDepthClamp; - info["has_texture_rectangle"] = mHasTextureRectangle; - info["has_texture_multisample"] = mHasTextureMultisample; - info["has_transform_feedback"] = mHasTransformFeedback; info["max_sample_mask_words"] = mMaxSampleMaskWords; info["max_color_texture_samples"] = mMaxColorTextureSamples; info["max_depth_texture_samples"] = mMaxDepthTextureSamples; info["max_integer_samples"] = mMaxIntegerSamples; + info["max_vertex_range"] = mGLMaxVertexRange; + info["max_index_range"] = mGLMaxIndexRange; + info["max_texture_size"] = mGLMaxTextureSize; - // Other extensions. - info["has_anisotropic"] = mHasAnisotropic; - info["has_arb_env_combine"] = mHasARBEnvCombine; - info["has_cube_map"] = mHasCubeMap; - info["has_debug_output"] = mHasDebugOutput; - info["has_srgb_texture"] = mHassRGBTexture; - info["has_srgb_framebuffer"] = mHassRGBFramebuffer; - info["has_texture_srgb_decode"] = mHasTexturesRGBDecode; - - // Vendor-specific extensions + // Which vendor info["is_ati"] = mIsAMD; // note, do not rename is_ati to is_amd without coordinating with DW info["is_nvidia"] = mIsNVIDIA; info["is_intel"] = mIsIntel; - // Other fields - info["has_requirements"] = mHasRequirements; - info["has_separate_specular_color"] = mHasSeparateSpecularColor; - info["max_vertex_range"] = mGLMaxVertexRange; - info["max_index_range"] = mGLMaxIndexRange; - info["max_texture_size"] = mGLMaxTextureSize; info["gl_renderer"] = mGLRenderer; } @@ -1480,60 +1351,6 @@ void LLGLManager::shutdownGL() void LLGLManager::initExtensions() { -#if LL_MESA_HEADLESS -# ifdef GL_ARB_multitexture - mHasMultitexture = TRUE; -# else - mHasMultitexture = FALSE; -# endif // GL_ARB_multitexture -# ifdef GL_ARB_texture_env_combine - mHasARBEnvCombine = TRUE; -# else - mHasARBEnvCombine = FALSE; -# endif // GL_ARB_texture_env_combine -# ifdef GL_ARB_texture_compression - mHasCompressedTextures = TRUE; -# else - mHasCompressedTextures = FALSE; -# endif // GL_ARB_texture_compression -# ifdef GL_ARB_vertex_buffer_object - mHasVertexBufferObject = TRUE; -# else - mHasVertexBufferObject = FALSE; -# endif // GL_ARB_vertex_buffer_object -# ifdef GL_EXT_framebuffer_object - mHasFramebufferObject = TRUE; -# else - mHasFramebufferObject = FALSE; -# endif // GL_EXT_framebuffer_object -# ifdef GL_ARB_draw_buffers - mHasDrawBuffers = TRUE; -#else - mHasDrawBuffers = FALSE; -# endif // GL_ARB_draw_buffers -# if defined(GL_NV_depth_clamp) || defined(GL_ARB_depth_clamp) - mHasDepthClamp = TRUE; -#else - mHasDepthClamp = FALSE; -#endif // defined(GL_NV_depth_clamp) || defined(GL_ARB_depth_clamp) -# if GL_EXT_blend_func_separate - mHasBlendFuncSeparate = TRUE; -#else - mHasBlendFuncSeparate = FALSE; -# endif // GL_EXT_blend_func_separate - mHasMipMapGeneration = FALSE; - mHasSeparateSpecularColor = FALSE; - mHasAnisotropic = FALSE; - mHasCubeMap = FALSE; - mHasOcclusionQuery = FALSE; - mHasPointParameters = FALSE; - mHasTextureRectangle = FALSE; -#else // LL_MESA_HEADLESS //important, gGLHExts.mSysExts is uninitialized until after glh_init_extensions is called - - mHasMultitexture = TRUE; - mHasCubeMap = TRUE; - mHasCompressedTextures = TRUE; - #if LL_DARWIN GLint num_extensions = 0; std::string all_extensions{""}; @@ -1550,173 +1367,12 @@ void LLGLManager::initExtensions() } #endif - mHasSeparateSpecularColor = ExtensionExists("GL_EXT_separate_specular_color", gGLHExts.mSysExts); - mHasAnisotropic = ExtensionExists("GL_EXT_texture_filter_anisotropic", gGLHExts.mSysExts); - - // In core profile - mHasARBEnvCombine = TRUE; //ExtensionExists("GL_ARB_texture_env_combine", gGLHExts.mSysExts); - mHasTimerQuery = FALSE; //FIXME //ExtensionExists("GL_ARB_timer_query", gGLHExts.mSysExts); - mHasOcclusionQuery = TRUE; //ExtensionExists("GL_ARB_occlusion_query", gGLHExts.mSysExts); - mHasOcclusionQuery2 = TRUE; // ExtensionExists("GL_ARB_occlusion_query2", gGLHExts.mSysExts); - mHasVertexBufferObject = TRUE; //ExtensionExists("GL_ARB_vertex_buffer_object", gGLHExts.mSysExts); - mHasVertexArrayObject = TRUE; //ExtensionExists("GL_ARB_vertex_array_object", gGLHExts.mSysExts); - mHasMapBufferRange = TRUE; ExtensionExists("GL_ARB_map_buffer_range", gGLHExts.mSysExts); - mHasFlushBufferRange = ExtensionExists("GL_APPLE_flush_buffer_range", gGLHExts.mSysExts); // Apple has mHasMapBufferRange now - mHasSync = TRUE; //ExtensionExists("GL_ARB_sync", gGLHExts.mSysExts); - mHasFramebufferObject = TRUE; //ExtensionExists("GL_ARB_framebuffer_object", gGLHExts.mSysExts); - mHassRGBFramebuffer = TRUE; //ExtensionExists("GL_ARB_framebuffer_sRGB", gGLHExts.mSysExts); - mHasDrawBuffers = TRUE; //ExtensionExists("GL_ARB_draw_buffers", gGLHExts.mSysExts); - mHasTextureRectangle = TRUE; //ExtensionExists("GL_ARB_texture_rectangle", gGLHExts.mSysExts); - mHasTextureMultisample = TRUE; //ExtensionExists("GL_ARB_texture_multisample", gGLHExts.mSysExts); - mHasUniformBufferObject = TRUE; //ExtensionExists("GL_ARB_uniform_buffer_object", gGLHExts.mSysExts); - mHasCubeMapArray = TRUE; //ExtensionExists("GL_ARB_texture_cube_map_array", gGLHExts.mSysExts); - mHasPointParameters = TRUE; //ExtensionExists("GL_ARB_point_parameters", gGLHExts.mSysExts); - - mHasATIMemInfo = ExtensionExists("GL_ATI_meminfo", gGLHExts.mSysExts); //Basic AMD method, also see mHasAMDAssociations - mHasNVXMemInfo = ExtensionExists("GL_NVX_gpu_memory_info", gGLHExts.mSysExts); - // NOTE: Using extensions breaks reflections when Shadows are set to projector. See: SL-16727 - //mHasDepthClamp = ExtensionExists("GL_ARB_depth_clamp", gGLHExts.mSysExts) || ExtensionExists("GL_NV_depth_clamp", gGLHExts.mSysExts); - mHasDepthClamp = FALSE; - // mask out FBO support when packed_depth_stencil isn't there 'cause we need it for LLRenderTarget -Brad - -#ifdef GL_EXT_texture_sRGB - mHassRGBTexture = ExtensionExists("GL_EXT_texture_sRGB", gGLHExts.mSysExts); -#endif - - -#ifdef GL_EXT_texture_sRGB_decode - mHasTexturesRGBDecode = ExtensionExists("GL_EXT_texture_sRGB_decode", gGLHExts.mSysExts); -#else - mHasTexturesRGBDecode = ExtensionExists("GL_ARB_texture_sRGB_decode", gGLHExts.mSysExts); -#endif - - mHasMipMapGeneration = mHasFramebufferObject || mGLVersion >= 1.4f; + // OpenGL 4.x capabilities + mHasCubeMapArray = mGLVersion >= 3.99f; + mHasTransformFeedback = mGLVersion >= 3.99f; + mHasDebugOutput = mGLVersion >= 4.29f; - mHasBlendFuncSeparate = ExtensionExists("GL_EXT_blend_func_separate", gGLHExts.mSysExts); - mHasDebugOutput = mGLVersion >= 4.3f ? TRUE : FALSE; - mHasTransformFeedback = mGLVersion >= 4.f ? TRUE : FALSE; -#endif - -#if LL_LINUX - LL_INFOS() << "initExtensions() checking shell variables to adjust features..." << LL_ENDL; - // Our extension support for the Linux Client is very young with some - // potential driver gotchas, so offer a semi-secret way to turn it off. - if (getenv("LL_GL_NOEXT")) - { - //mHasMultitexture = FALSE; // NEEDED! - mHasDepthClamp = FALSE; - mHasARBEnvCombine = FALSE; - mHasCompressedTextures = FALSE; - mHasVertexBufferObject = FALSE; - mHasFramebufferObject = FALSE; - mHasDrawBuffers = FALSE; - mHasBlendFuncSeparate = FALSE; - mHasMipMapGeneration = FALSE; - mHasSeparateSpecularColor = FALSE; - mHasAnisotropic = FALSE; - mHasCubeMap = FALSE; - mHasOcclusionQuery = FALSE; - mHasPointParameters = FALSE; - LL_WARNS("RenderInit") << "GL extension support DISABLED via LL_GL_NOEXT" << LL_ENDL; - } - else if (getenv("LL_GL_BASICEXT")) /* Flawfinder: ignore */ - { - // This switch attempts to turn off all support for exotic - // extensions which I believe correspond to fatal driver - // bug reports. This should be the default until we get a - // proper blacklist/whitelist on Linux. - mHasMipMapGeneration = FALSE; - mHasAnisotropic = FALSE; - //mHasCubeMap = FALSE; // apparently fatal on Intel 915 & similar - //mHasOcclusionQuery = FALSE; // source of many ATI system hangs - mHasBlendFuncSeparate = FALSE; - LL_WARNS("RenderInit") << "GL extension support forced to SIMPLE level via LL_GL_BASICEXT" << LL_ENDL; - } - if (getenv("LL_GL_BLACKLIST")) /* Flawfinder: ignore */ - { - // This lets advanced troubleshooters disable specific - // GL extensions to isolate problems with their hardware. - // SL-28126 - const char *const blacklist = getenv("LL_GL_BLACKLIST"); /* Flawfinder: ignore */ - LL_WARNS("RenderInit") << "GL extension support partially disabled via LL_GL_BLACKLIST: " << blacklist << LL_ENDL; - if (strchr(blacklist,'a')) mHasARBEnvCombine = FALSE; - if (strchr(blacklist,'b')) mHasCompressedTextures = FALSE; - if (strchr(blacklist,'c')) mHasVertexBufferObject = FALSE; - if (strchr(blacklist,'d')) mHasMipMapGeneration = FALSE;//S -// if (strchr(blacklist,'f')) mHasNVVertexArrayRange = FALSE;//S -// if (strchr(blacklist,'g')) mHasNVFence = FALSE;//S - if (strchr(blacklist,'h')) mHasSeparateSpecularColor = FALSE; - if (strchr(blacklist,'i')) mHasAnisotropic = FALSE;//S - if (strchr(blacklist,'j')) mHasCubeMap = FALSE;//S -// if (strchr(blacklist,'k')) mHasATIVAO = FALSE;//S - if (strchr(blacklist,'l')) mHasOcclusionQuery = FALSE; - if (strchr(blacklist,'p')) mHasPointParameters = FALSE;//S - if (strchr(blacklist,'q')) mHasFramebufferObject = FALSE;//S - if (strchr(blacklist,'r')) mHasDrawBuffers = FALSE;//S - if (strchr(blacklist,'s')) mHasTextureRectangle = FALSE; - if (strchr(blacklist,'t')) mHasBlendFuncSeparate = FALSE;//S - if (strchr(blacklist,'u')) mHasDepthClamp = FALSE; - - } -#endif // LL_LINUX - - if (!mHasMultitexture) - { - LL_INFOS("RenderInit") << "Couldn't initialize multitexturing" << LL_ENDL; - } - if (!mHasMipMapGeneration) - { - LL_INFOS("RenderInit") << "Couldn't initialize mipmap generation" << LL_ENDL; - } - if (!mHasARBEnvCombine) - { - LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_texture_env_combine" << LL_ENDL; - } - if (!mHasSeparateSpecularColor) - { - LL_INFOS("RenderInit") << "Couldn't initialize separate specular color" << LL_ENDL; - } - if (!mHasAnisotropic) - { - LL_INFOS("RenderInit") << "Couldn't initialize anisotropic filtering" << LL_ENDL; - } - if (!mHasCompressedTextures) - { - LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_texture_compression" << LL_ENDL; - } - if (!mHasOcclusionQuery) - { - LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_occlusion_query" << LL_ENDL; - } - if (!mHasOcclusionQuery2) - { - LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_occlusion_query2" << LL_ENDL; - } - if (!mHasPointParameters) - { - LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_point_parameters" << LL_ENDL; - } - if (!mHasBlendFuncSeparate && !LLRender::sGLCoreProfile) - { - LL_INFOS("RenderInit") << "Couldn't initialize GL_EXT_blend_func_separate" << LL_ENDL; - } - if (!mHasDrawBuffers) - { - LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_draw_buffers" << LL_ENDL; - } - if (!mHasCubeMapArray) - { - LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_texture_cube_map_array" << LL_ENDL; - } - - // Disable certain things due to known bugs - if (mIsIntel && mHasMipMapGeneration) - { - LL_INFOS("RenderInit") << "Disabling mip-map generation for Intel GPUs" << LL_ENDL; - mHasMipMapGeneration = FALSE; - } - - // Misc + // Misc glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, (GLint*) &mGLMaxVertexRange); glGetIntegerv(GL_MAX_ELEMENTS_INDICES, (GLint*) &mGLMaxIndexRange); glGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint*) &mGLMaxTextureSize); @@ -2795,7 +2451,7 @@ void LLGLState::checkTextureChannels(const std::string& msg) glh::matrix4f identity; identity.identity(); - for (GLint i = 1; i < gGLManager.mNumTextureUnits; i++) + for (GLint i = 1; i < gGLManager.mNumTextureImageUnits; i++) { gGL.getTexUnit(i)->activate(); @@ -2833,12 +2489,6 @@ void LLGLState::checkTextureChannels(const std::string& msg) for (S32 j = (i == 0 ? 1 : 0); j < 9; j++) { - if (j == 8 && !gGLManager.mHasTextureRectangle || - j == 9 && !gGLManager.mHasTextureMultisample) - { - continue; - } - if (glIsEnabled(value[j])) { error = TRUE; @@ -3329,36 +2979,29 @@ LLGLSquashToFarClip::~LLGLSquashToFarClip() LLGLSyncFence::LLGLSyncFence() { -#ifdef GL_ARB_sync mSync = 0; -#endif } LLGLSyncFence::~LLGLSyncFence() { -#ifdef GL_ARB_sync if (mSync) { glDeleteSync(mSync); } -#endif } void LLGLSyncFence::placeFence() { -#ifdef GL_ARB_sync if (mSync) { glDeleteSync(mSync); } mSync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); -#endif } bool LLGLSyncFence::isCompleted() { bool ret = true; -#ifdef GL_ARB_sync if (mSync) { GLenum status = glClientWaitSync(mSync, 0, 1); @@ -3367,13 +3010,11 @@ bool LLGLSyncFence::isCompleted() ret = false; } } -#endif return ret; } void LLGLSyncFence::wait() { -#ifdef GL_ARB_sync if (mSync) { while (glClientWaitSync(mSync, 0, FENCE_WAIT_TIME_NANOSECONDS) == GL_TIMEOUT_EXPIRED) @@ -3382,7 +3023,6 @@ void LLGLSyncFence::wait() waits++; } } -#endif } LLGLSPipelineSkyBox::LLGLSPipelineSkyBox() diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h index 3c40f85654..e3c07604aa 100644 --- a/indra/llrender/llgl.h +++ b/indra/llrender/llgl.h @@ -76,52 +76,27 @@ public: BOOL mInited; BOOL mIsDisabled; - // Extensions used by everyone - BOOL mHasMultitexture; - BOOL mHasATIMemInfo; - BOOL mHasAMDAssociations; - BOOL mHasNVXMemInfo; - S32 mNumTextureUnits; - BOOL mHasMipMapGeneration; - BOOL mHasCompressedTextures; - BOOL mHasFramebufferObject; + // OpenGL limits S32 mMaxSamples; - BOOL mHasBlendFuncSeparate; - - // ARB Extensions - BOOL mHasVertexBufferObject; - BOOL mHasVertexArrayObject; - BOOL mHasSync; - BOOL mHasMapBufferRange; - BOOL mHasFlushBufferRange; - BOOL mHasPBuffer; - S32 mNumTextureImageUnits; - BOOL mHasOcclusionQuery; - BOOL mHasTimerQuery; - BOOL mHasOcclusionQuery2; - BOOL mHasPointParameters; - BOOL mHasDrawBuffers; - BOOL mHasDepthClamp; - BOOL mHasTextureRectangle; - BOOL mHasTextureMultisample; - BOOL mHasTransformFeedback; - BOOL mHasUniformBufferObject; + S32 mNumTextureImageUnits; S32 mMaxSampleMaskWords; S32 mMaxColorTextureSamples; S32 mMaxDepthTextureSamples; S32 mMaxIntegerSamples; - - // Other extensions. - BOOL mHasAnisotropic; - BOOL mHasARBEnvCombine; - BOOL mHasCubeMap; - BOOL mHasCubeMapArray; - BOOL mHasDebugOutput; - BOOL mHassRGBTexture; - BOOL mHassRGBFramebuffer; - BOOL mHasTexturesRGBDecode; - + S32 mGLMaxVertexRange; + S32 mGLMaxIndexRange; + S32 mGLMaxTextureSize; + F32 mMaxAnisotropy = 0.f; + + // GL 4.x capabilities + bool mHasCubeMapArray = false; + bool mHasDebugOutput = false; + bool mHasTransformFeedback = false; + bool mHasAnisotropic = false; + // Vendor-specific extensions + bool mHasAMDAssociations = false; + BOOL mIsAMD; BOOL mIsNVIDIA; BOOL mIsIntel; @@ -134,9 +109,6 @@ public: // Whether this version of GL is good enough for SL to use BOOL mHasRequirements; - // Misc extensions - BOOL mHasSeparateSpecularColor; - S32 mDriverVersionMajor; S32 mDriverVersionMinor; S32 mDriverVersionRelease; @@ -147,9 +119,6 @@ public: std::string mGLVersionString; S32 mVRAM; // VRAM in MB - S32 mGLMaxVertexRange; - S32 mGLMaxIndexRange; - S32 mGLMaxTextureSize; void getPixelFormat(); // Get the best pixel format @@ -415,9 +384,7 @@ public: class LLGLSyncFence : public LLGLFence { public: -#ifdef GL_ARB_sync GLsync mSync; -#endif LLGLSyncFence(); virtual ~LLGLSyncFence(); diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h index f2b51fbafb..0aacf3bf0e 100644 --- a/indra/llrender/llglheaders.h +++ b/indra/llrender/llglheaders.h @@ -41,277 +41,6 @@ # include "GL/glh_extensions.h" # undef __APPLE__ -#elif LL_LINUX -//---------------------------------------------------------------------------- -// LL_LINUX - -//---------------------------------------------------------------------------- -// Linux, MESA headers, but not necessarily assuming MESA runtime. -// quotes so we get libraries/.../GL/ version -#include "GL/gl.h" -#include "GL/glext.h" -#include "GL/glu.h" - - -#if LL_LINUX && !LL_MESA_HEADLESS -// The __APPLE__ kludge is to make glh_extensions.h not symbol-clash horribly -# define __APPLE__ -# include "GL/glh_extensions.h" -# undef __APPLE__ - -/* Although SDL very likely ends up calling glXGetProcAddress() itself, - if we use SDL_GL_GetProcAddress() then we get bogus addresses back on - some systems. Weird. */ -/*# include "SDL/SDL.h" - # define GLH_EXT_GET_PROC_ADDRESS(p) SDL_GL_GetProcAddress(p) */ -#define GLX_GLXEXT_PROTOTYPES 1 -# include "GL/glx.h" -# include "GL/glxext.h" -// Use glXGetProcAddressARB instead of glXGetProcAddress - the ARB symbol -// is considered 'legacy' but works on more machines. -# define GLH_EXT_GET_PROC_ADDRESS(p) glXGetProcAddress((const GLubyte*)(p)) -#endif // LL_LINUX && !LL_MESA_HEADLESS - -#if LL_LINUX && defined(WINGDIAPI) -// WINGDIAPI gets set if we are using the linux nvidia gl.h header which needs -// the functions below setting up. -# define LL_LINUX_NV_GL_HEADERS 1 -#else -# define LL_LINUX_NV_GL_HEADERS 0 -#endif // LL_LINUX && defined(WINGDIAPI) - - -#if LL_LINUX_NV_GL_HEADERS -// Missing functions when using nvidia headers: -extern PFNGLACTIVETEXTUREPROC glActiveTexture; -extern PFNGLCLIENTACTIVETEXTUREPROC glClientActiveTexture; -extern PFNGLDRAWRANGEELEMENTSPROC glDrawRangeElements; -#endif // LL_LINUX_NV_GL_HEADERS - -// GL_ARB_vertex_array_object -extern PFNGLBINDVERTEXARRAYPROC glBindVertexArray; -extern PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays; -extern PFNGLGENVERTEXARRAYSPROC glGenVertexArrays; -extern PFNGLISVERTEXARRAYPROC glIsVertexArray; - -// GL_ARB_vertex_buffer_object -extern PFNGLBINDBUFFERPROC glBindBuffer; -extern PFNGLDELETEBUFFERSPROC glDeleteBuffers; -extern PFNGLGENBUFFERSPROC glGenBuffers; -extern PFNGLISBUFFERPROC glIsBuffer; -extern PFNGLBUFFERDATAPROC glBufferData; -extern PFNGLBUFFERSUBDATAPROC glBufferSubData; -extern PFNGLGETBUFFERSUBDATAPROC glGetBufferSubData; -extern PFNGLMAPBUFFERPROC glMapBuffer; -extern PFNGLUNMAPBUFFERPROC glUnmapBuffer; -extern PFNGLGETBUFFERPARAMETERIVPROC glGetBufferParameteriv; -extern PFNGLGETBUFFERPOINTERVPROC glGetBufferPointerv; - -// GL_ARB_sync -extern PFNGLFENCESYNCPROC glFenceSync; -extern PFNGLISSYNCPROC glIsSync; -extern PFNGLDELETESYNCPROC glDeleteSync; -extern PFNGLCLIENTWAITSYNCPROC glClientWaitSync; -extern PFNGLWAITSYNCPROC glWaitSync; -extern PFNGLGETINTEGER64VPROC glGetInteger64v; -extern PFNGLGETSYNCIVPROC glGetSynciv; - -// GL_APPLE_flush_buffer_range -extern PFNGLBUFFERPARAMETERIAPPLEPROC glBufferParameteriAPPLE; -extern PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC glFlushMappedBufferRangeAPPLE; - -// GL_ARB_map_buffer_range -extern PFNGLMAPBUFFERRANGEPROC glMapBufferRange; -extern PFNGLFLUSHMAPPEDBUFFERRANGEPROC glFlushMappedBufferRange; - -// GL_ATI_vertex_array_object -extern PFNGLNEWOBJECTBUFFERATIPROC glNewObjectBufferATI; -extern PFNGLISOBJECTBUFFERATIPROC glIsObjectBufferATI; -extern PFNGLUPDATEOBJECTBUFFERATIPROC glUpdateObjectBufferATI; -extern PFNGLGETOBJECTBUFFERFVATIPROC glGetObjectBufferfvATI; -extern PFNGLGETOBJECTBUFFERIVATIPROC glGetObjectBufferivATI; -extern PFNGLFREEOBJECTBUFFERATIPROC glFreeObjectBufferATI; -extern PFNGLARRAYOBJECTATIPROC glArrayObjectATI; -extern PFNGLVERTEXATTRIBARRAYOBJECTATIPROC glVertexAttribArrayObjectATI; -extern PFNGLGETARRAYOBJECTFVATIPROC glGetArrayObjectfvATI; -extern PFNGLGETARRAYOBJECTIVATIPROC glGetArrayObjectivATI; -extern PFNGLVARIANTARRAYOBJECTATIPROC glVariantObjectArrayATI; -extern PFNGLGETVARIANTARRAYOBJECTFVATIPROC glGetVariantArrayObjectfvATI; -extern PFNGLGETVARIANTARRAYOBJECTIVATIPROC glGetVariantArrayObjectivATI; - -// GL_ARB_occlusion_query -extern PFNGLGENQUERIESPROC glGenQueries; -extern PFNGLDELETEQUERIESPROC glDeleteQueries; -extern PFNGLISQUERYPROC glIsQuery; -extern PFNGLBEGINQUERYPROC glBeginQuery; -extern PFNGLENDQUERYPROC glEndQuery; -extern PFNGLGETQUERYIVPROC glGetQueryiv; -extern PFNGLGETQUERYOBJECTIVPROC glGetQueryObjectiv; -extern PFNGLGETQUERYOBJECTUIVPROC glGetQueryObjectuiv; - -// GL_ARB_timer_query -extern PFNGLQUERYCOUNTERPROC glQueryCounter; -extern PFNGLGETQUERYOBJECTI64VPROC glGetQueryObjecti64v; -extern PFNGLGETQUERYOBJECTUI64VPROC glGetQueryObjectui64v; - -// GL_ARB_point_parameters -extern PFNGLPOINTPARAMETERFPROC glPointParameterf; -extern PFNGLPOINTPARAMETERFVPROC glPointParameterfv; - -// GL_ARB_shader_objects -extern PFNGLDELETEOBJECTPROC glDeleteObject; -extern PFNGLGETHANDLEPROC glGetHandle; -extern PFNGLDETACHOBJECTPROC glDetachObject; -extern PFNGLCREATESHADEROBJECTPROC glCreateShaderObject; -extern PFNGLSHADERSOURCEPROC glShaderSource; -extern PFNGLCOMPILESHADERPROC glCompileShader; -extern PFNGLCREATEPROGRAMOBJECTPROC glCreateProgramObject; -extern PFNGLATTACHOBJECTPROC glAttachObject; -extern PFNGLLINKPROGRAMPROC glLinkProgram; -extern PFNGLUSEPROGRAMOBJECTPROC glUseProgramObject; -extern PFNGLVALIDATEPROGRAMPROC glValidateProgram; -extern PFNGLUNIFORM1FPROC glUniform1f; -extern PFNGLUNIFORM2FPROC glUniform2f; -extern PFNGLUNIFORM3FPROC glUniform3f; -extern PFNGLUNIFORM4FPROC glUniform4f; -extern PFNGLUNIFORM1IPROC glUniform1i; -extern PFNGLUNIFORM2IPROC glUniform2i; -extern PFNGLUNIFORM3IPROC glUniform3i; -extern PFNGLUNIFORM4IPROC glUniform4i; -extern PFNGLUNIFORM1FVPROC glUniform1fv; -extern PFNGLUNIFORM2FVPROC glUniform2fv; -extern PFNGLUNIFORM3FVPROC glUniform3fv; -extern PFNGLUNIFORM4FVPROC glUniform4fv; -extern PFNGLUNIFORM1IVPROC glUniform1iv; -extern PFNGLUNIFORM2IVPROC glUniform2iv; -extern PFNGLUNIFORM3IVPROC glUniform3iv; -extern PFNGLUNIFORM4IVPROC glUniform4iv; -extern PFNGLUNIFORMMATRIX2FVPROC glUniformMatrix2fv; -extern PFNGLUNIFORMMATRIX3FVPROC glUniformMatrix3fv; -extern PFNGLUNIFORMMATRIX3X4FVPROC glUniformMatrix3x4fv; -extern PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv; -extern PFNGLGETOBJECTPARAMETERFVPROC glGetObjectParameterfv; -extern PFNGLGETOBJECTPARAMETERIVPROC glGetObjectParameteriv; -extern PFNGLGETINFOLOGPROC glGetInfoLog; -extern PFNGLGETATTACHEDOBJECTSPROC glGetAttachedObjects; -extern PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation; -extern PFNGLGETACTIVEUNIFORMPROC glGetActiveUniform; -extern PFNGLGETUNIFORMFVPROC glGetUniformfv; -extern PFNGLGETUNIFORMIVPROC glGetUniformiv; -extern PFNGLGETSHADERSOURCEPROC glGetShaderSource; - -// GL_ARB_vertex_shader -extern PFNGLVERTEXATTRIB1DPROC glVertexAttrib1d; -extern PFNGLVERTEXATTRIB1DVPROC glVertexAttrib1dv; -extern PFNGLVERTEXATTRIB1FPROC glVertexAttrib1f; -extern PFNGLVERTEXATTRIB1FVPROC glVertexAttrib1fv; -extern PFNGLVERTEXATTRIB1SPROC glVertexAttrib1s; -extern PFNGLVERTEXATTRIB1SVPROC glVertexAttrib1sv; -extern PFNGLVERTEXATTRIB2DPROC glVertexAttrib2d; -extern PFNGLVERTEXATTRIB2DVPROC glVertexAttrib2dv; -extern PFNGLVERTEXATTRIB2FPROC glVertexAttrib2f; -extern PFNGLVERTEXATTRIB2FVPROC glVertexAttrib2fv; -extern PFNGLVERTEXATTRIB2SPROC glVertexAttrib2s; -extern PFNGLVERTEXATTRIB2SVPROC glVertexAttrib2sv; -extern PFNGLVERTEXATTRIB3DPROC glVertexAttrib3d; -extern PFNGLVERTEXATTRIB3DVPROC glVertexAttrib3dv; -extern PFNGLVERTEXATTRIB3FPROC glVertexAttrib3f; -extern PFNGLVERTEXATTRIB3FVPROC glVertexAttrib3fv; -extern PFNGLVERTEXATTRIB3SPROC glVertexAttrib3s; -extern PFNGLVERTEXATTRIB3SVPROC glVertexAttrib3sv; -extern PFNGLVERTEXATTRIB4NBVPROC glVertexAttrib4nbv; -extern PFNGLVERTEXATTRIB4NIVPROC glVertexAttrib4niv; -extern PFNGLVERTEXATTRIB4NSVPROC glVertexAttrib4nsv; -extern PFNGLVERTEXATTRIB4NUBPROC glVertexAttrib4nub; -extern PFNGLVERTEXATTRIB4NUBVPROC glVertexAttrib4nubv; -extern PFNGLVERTEXATTRIB4NUIVPROC glVertexAttrib4nuiv; -extern PFNGLVERTEXATTRIB4NUSVPROC glVertexAttrib4nusv; -extern PFNGLVERTEXATTRIB4BVPROC glVertexAttrib4bv; -extern PFNGLVERTEXATTRIB4DPROC glVertexAttrib4d; -extern PFNGLVERTEXATTRIB4DVPROC glVertexAttrib4dv; -extern PFNGLVERTEXATTRIB4FPROC glVertexAttrib4f; -extern PFNGLVERTEXATTRIB4FVPROC glVertexAttrib4fv; -extern PFNGLVERTEXATTRIB4IVPROC glVertexAttrib4iv; -extern PFNGLVERTEXATTRIB4SPROC glVertexAttrib4s; -extern PFNGLVERTEXATTRIB4SVPROC glVertexAttrib4sv; -extern PFNGLVERTEXATTRIB4UBVPROC glVertexAttrib4ubv; -extern PFNGLVERTEXATTRIB4UIVPROC glVertexAttrib4uiv; -extern PFNGLVERTEXATTRIB4USVPROC glVertexAttrib4usv; -extern PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer; -extern PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer; -extern PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray; -extern PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray; -extern PFNGLPROGRAMSTRINGPROC glProgramString; -extern PFNGLBINDPROGRAMPROC glBindProgram; -extern PFNGLDELETEPROGRAMSPROC glDeletePrograms; -extern PFNGLGENPROGRAMSPROC glGenPrograms; -extern PFNGLPROGRAMENVPARAMETER4DPROC glProgramEnvParameter4d; -extern PFNGLPROGRAMENVPARAMETER4DVPROC glProgramEnvParameter4dv; -extern PFNGLPROGRAMENVPARAMETER4FPROC glProgramEnvParameter4f; -extern PFNGLPROGRAMENVPARAMETER4FVPROC glProgramEnvParameter4fv; -extern PFNGLPROGRAMLOCALPARAMETER4DPROC glProgramLocalParameter4d; -extern PFNGLPROGRAMLOCALPARAMETER4DVPROC glProgramLocalParameter4dv; -extern PFNGLPROGRAMLOCALPARAMETER4FPROC glProgramLocalParameter4f; -extern PFNGLPROGRAMLOCALPARAMETER4FVPROC glProgramLocalParameter4fv; -extern PFNGLGETPROGRAMENVPARAMETERDVPROC glGetProgramEnvParameterdv; -extern PFNGLGETPROGRAMENVPARAMETERFVPROC glGetProgramEnvParameterfv; -extern PFNGLGETPROGRAMLOCALPARAMETERDVPROC glGetProgramLocalParameterdv; -extern PFNGLGETPROGRAMLOCALPARAMETERFVPROC glGetProgramLocalParameterfv; -extern PFNGLGETPROGRAMIVPROC glGetProgramiv; -extern PFNGLGETPROGRAMSTRINGPROC glGetProgramString; -extern PFNGLGETVERTEXATTRIBDVPROC glGetVertexAttribdv; -extern PFNGLGETVERTEXATTRIBFVPROC glGetVertexAttribfv; -extern PFNGLGETVERTEXATTRIBIVPROC glGetVertexAttribiv; -extern PFNGLGETVERTEXATTRIBPOINTERVPROC glGetVertexAttribPointerv; -extern PFNGLISPROGRAMPROC glIsProgram; -extern PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation; -extern PFNGLGETACTIVEATTRIBPROC glGetActiveAttrib; -extern PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation; - -extern PFNGLCOMPRESSEDTEXIMAGE2DPROC glCompressedTexImage2D; -extern PFNGLGETCOMPRESSEDTEXIMAGEPROC glGetCompressedTexImage; - -//GL_EXT_blend_func_separate -extern PFNGLBLENDFUNCSEPARATEEXTPROC glBlendFuncSeparateEXT; - -//GL_ARB_framebuffer_object -extern PFNGLISRENDERBUFFERPROC glIsRenderbuffer; -extern PFNGLBINDRENDERBUFFERPROC glBindRenderbuffer; -extern PFNGLDELETERENDERBUFFERSPROC glDeleteRenderbuffers; -extern PFNGLGENRENDERBUFFERSPROC glGenRenderbuffers; -extern PFNGLRENDERBUFFERSTORAGEPROC glRenderbufferStorage; -extern PFNGLGETRENDERBUFFERPARAMETERIVPROC glGetRenderbufferParameteriv; -extern PFNGLISFRAMEBUFFERPROC glIsFramebuffer; -extern PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer; -extern PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers; -extern PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers; -extern PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus; -extern PFNGLFRAMEBUFFERTEXTURE1DPROC glFramebufferTexture1D; -extern PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D; -extern PFNGLFRAMEBUFFERTEXTURE3DPROC glFramebufferTexture3D; -extern PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer; -extern PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glGetFramebufferAttachmentParameteriv; -extern PFNGLGENERATEMIPMAPPROC glGenerateMipmap; -extern PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer; -extern PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glRenderbufferStorageMultisample; -extern PFNGLFRAMEBUFFERTEXTURELAYERPROC glFramebufferTextureLayer; - -//GL_ARB_draw_buffers -extern PFNGLDRAWBUFFERSPROC glDrawBuffers; - -//GL_ARB_texture_multisample -extern PFNGLTEXIMAGE2DMULTISAMPLEPROC glTexImage2DMultisample; -extern PFNGLTEXIMAGE3DMULTISAMPLEPROC glTexImage3DMultisample; -extern PFNGLGETMULTISAMPLEFVPROC glGetMultisamplefv; -extern PFNGLSAMPLEMASKIPROC glSampleMaski; - -//transform feedback (4.0 core) -extern PFNGLBEGINTRANSFORMFEEDBACKPROC glBeginTransformFeedback; -extern PFNGLENDTRANSFORMFEEDBACKPROC glEndTransformFeedback; -extern PFNGLTRANSFORMFEEDBACKVARYINGSPROC glTransformFeedbackVaryings; -extern PFNGLBINDBUFFERRANGEPROC glBindBufferRange; -extern PFNGLBINDBUFFERBASEPROC glBindBufferBase; - #elif LL_WINDOWS //---------------------------------------------------------------------------- // LL_WINDOWS @@ -345,12 +74,6 @@ extern PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT; // WGL_ARB_create_context extern PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB; -// GL_VERSION_1_2 -//extern PFNGLDRAWRANGEELEMENTSPROC glDrawRangeElements; -//extern PFNGLTEXIMAGE3DPROC glTexImage3D; -//extern PFNGLTEXSUBIMAGE3DPROC glTexSubImage3D; -//extern PFNGLCOPYTEXSUBIMAGE3DPROC glCopyTexSubImage3D; - // GL_VERSION_1_3 extern PFNGLACTIVETEXTUREPROC glActiveTexture; extern PFNGLSAMPLECOVERAGEPROC glSampleCoverage; diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index d8e312106c..6eb7da302f 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -352,7 +352,7 @@ void LLImageGL::updateStats(F32 current_time) //static void LLImageGL::destroyGL(BOOL save_state) { - for (S32 stage = 0; stage < gGLManager.mNumTextureUnits; stage++) + for (S32 stage = 0; stage < gGLManager.mNumTextureImageUnits; stage++) { gGL.getTexUnit(stage)->unbind(LLTexUnit::TT_TEXTURE); } @@ -520,7 +520,6 @@ void LLImageGL::init(BOOL usemipmaps) mPickMaskHeight = 0; mUseMipMaps = usemipmaps; mHasExplicitFormat = FALSE; - mAutoGenMips = FALSE; mIsMask = FALSE; mNeedsAlphaAndPickMask = TRUE ; @@ -1069,30 +1068,12 @@ BOOL LLImageGL::preAddToAtlas(S32 discard_level, const LLImageRaw* raw_image) mFormatType = GL_UNSIGNED_BYTE; break; case 3: -#if USE_SRGB_DECODE - if (gGLManager.mHasTexturesRGBDecode) - { - mFormatInternal = GL_SRGB8; - } - else -#endif - { - mFormatInternal = GL_RGB8; - } + mFormatInternal = GL_RGB8; mFormatPrimary = GL_RGB; mFormatType = GL_UNSIGNED_BYTE; break; case 4: -#if USE_SRGB_DECODE - if (gGLManager.mHasTexturesRGBDecode) - { - mFormatInternal = GL_SRGB8_ALPHA8; - } - else -#endif - { - mFormatInternal = GL_RGBA8; - } + mFormatInternal = GL_RGBA8; mFormatPrimary = GL_RGBA; mFormatType = GL_UNSIGNED_BYTE; break; @@ -1525,30 +1506,12 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S mFormatType = GL_UNSIGNED_BYTE; break; case 3: - #if USE_SRGB_DECODE - if (gGLManager.mHasTexturesRGBDecode) - { - mFormatInternal = GL_SRGB8; - } - else - #endif - { - mFormatInternal = GL_RGB8; - } + mFormatInternal = GL_RGB8; mFormatPrimary = GL_RGB; mFormatType = GL_UNSIGNED_BYTE; break; case 4: - #if USE_SRGB_DECODE - if (gGLManager.mHasTexturesRGBDecode) - { - mFormatInternal = GL_SRGB8_ALPHA8; - } - else - #endif - { - mFormatInternal = GL_RGBA8; - } + mFormatInternal = GL_RGBA8; mFormatPrimary = GL_RGBA; mFormatType = GL_UNSIGNED_BYTE; break; @@ -1637,7 +1600,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_ if (mUseMipMaps) { - mAutoGenMips = gGLManager.mHasMipMapGeneration; + mAutoGenMips = true; } mCurrentDiscardLevel = discard_level; @@ -1694,44 +1657,37 @@ void LLImageGL::syncToMainThread(LLGLuint new_tex_name) { LL_PROFILE_ZONE_NAMED("cglt - sync"); - if (gGLManager.mHasSync) + if (gGLManager.mIsNVIDIA) { - if (gGLManager.mIsNVIDIA) - { - // wait for texture upload to finish before notifying main thread - // upload is complete - auto sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); - glFlush(); - glClientWaitSync(sync, 0, GL_TIMEOUT_IGNORED); - glDeleteSync(sync); - } - else - { - // post a sync to the main thread (will execute before tex name swap lambda below) - // glFlush calls here are partly superstitious and partly backed by observation - // on AMD hardware - glFlush(); - auto sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); - glFlush(); - LL::WorkQueue::postMaybe( - mMainQueue, - [=]() - { - LL_PROFILE_ZONE_NAMED("cglt - wait sync"); - { - LL_PROFILE_ZONE_NAMED("glWaitSync"); - glWaitSync(sync, 0, GL_TIMEOUT_IGNORED); - } - { - LL_PROFILE_ZONE_NAMED("glDeleteSync"); - glDeleteSync(sync); - } - }); - } + // wait for texture upload to finish before notifying main thread + // upload is complete + auto sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); + glFlush(); + glClientWaitSync(sync, 0, GL_TIMEOUT_IGNORED); + glDeleteSync(sync); } else { - glFinish(); + // post a sync to the main thread (will execute before tex name swap lambda below) + // glFlush calls here are partly superstitious and partly backed by observation + // on AMD hardware + glFlush(); + auto sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); + glFlush(); + LL::WorkQueue::postMaybe( + mMainQueue, + [=]() + { + LL_PROFILE_ZONE_NAMED("cglt - wait sync"); + { + LL_PROFILE_ZONE_NAMED("glWaitSync"); + glWaitSync(sync, 0, GL_TIMEOUT_IGNORED); + } + { + LL_PROFILE_ZONE_NAMED("glDeleteSync"); + glDeleteSync(sync); + } + }); } } diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index b4618fd35c..bbd024abd9 100644 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -219,7 +219,7 @@ private: U16 mPickMaskHeight; S8 mUseMipMaps; BOOL mHasExplicitFormat; // If false (default), GL format is f(mComponents) - S8 mAutoGenMips; + bool mAutoGenMips = false; BOOL mIsMask; BOOL mNeedsAlphaAndPickMask; diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 554721399a..6e659641fe 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -335,7 +335,7 @@ bool LLTexUnit::bind(LLCubeMap* cubeMap) if (mCurrTexture != cubeMap->mImages[0]->getTexName()) { - if (gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps) + if (LLCubeMap::sUseCubeMaps) { activate(); enable(LLTexUnit::TT_CUBE_MAP); @@ -516,22 +516,15 @@ void LLTexUnit::setTextureFilteringOption(LLTexUnit::eTextureFilterOptions optio } } - if (gGLManager.mHasAnisotropic) + if (gGLManager.mGLVersion >= 4.59f) { if (LLImageGL::sGlobalUseAnisotropic && option == TFO_ANISOTROPIC) { - if (gGL.mMaxAnisotropy < 1.f) - { - glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &gGL.mMaxAnisotropy); - - LL_INFOS() << "gGL.mMaxAnisotropy: " << gGL.mMaxAnisotropy << LL_ENDL ; - gGL.mMaxAnisotropy = llmax(1.f, gGL.mMaxAnisotropy) ; - } - glTexParameterf(sGLTextureType[mCurrTexType], GL_TEXTURE_MAX_ANISOTROPY_EXT, gGL.mMaxAnisotropy); + glTexParameterf(sGLTextureType[mCurrTexType], GL_TEXTURE_MAX_ANISOTROPY, gGLManager.mMaxAnisotropy); } else { - glTexParameterf(sGLTextureType[mCurrTexType], GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.f); + glTexParameterf(sGLTextureType[mCurrTexType], GL_TEXTURE_MAX_ANISOTROPY, 1.f); } } } @@ -650,29 +643,6 @@ void LLTexUnit::debugTextureUnit(void) void LLTexUnit::setTextureColorSpace(eTextureColorSpace space) { mTexColorSpace = space; - -#if USE_SRGB_DECODE - if (gGLManager.mHasTexturesRGBDecode) - { - if (space == TCS_SRGB) - { - glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_SRGB_DECODE_EXT, GL_DECODE_EXT); - } - else - { - glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT); - } - - if (gDebugGL) - { - assert_glerror(); - } - } - else - { - glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT); - } -#endif } LLLightState::LLLightState(S32 index) @@ -846,8 +816,7 @@ LLRender::LLRender() mCount(0), mQuadCycle(0), mMode(LLRender::TRIANGLES), - mCurrTextureUnitIndex(0), - mMaxAnisotropy(0.f) + mCurrTextureUnitIndex(0) { mTexUnits.reserve(LL_NUM_TEXTURE_LAYERS); for (U32 i = 0; i < LL_NUM_TEXTURE_LAYERS; i++) @@ -912,11 +881,9 @@ void LLRender::init() if (sGLCoreProfile && !LLVertexBuffer::sUseVAO) { //bind a dummy vertex array object so we're core profile compliant -#ifdef GL_ARB_vertex_array_object U32 ret; glGenVertexArrays(1, &ret); glBindVertexArray(ret); -#endif } @@ -1492,12 +1459,7 @@ void LLRender::blendFunc(eBlendFactor color_sfactor, eBlendFactor color_dfactor, llassert(color_dfactor < BF_UNDEF); llassert(alpha_sfactor < BF_UNDEF); llassert(alpha_dfactor < BF_UNDEF); - if (!LLRender::sGLCoreProfile && !gGLManager.mHasBlendFuncSeparate) - { - LL_WARNS_ONCE("render") << "no glBlendFuncSeparateEXT(), using color-only blend func" << LL_ENDL; - blendFunc(color_sfactor, color_dfactor); - return; - } + if (mCurrBlendColorSFactor != color_sfactor || mCurrBlendColorDFactor != color_dfactor || mCurrBlendAlphaSFactor != alpha_sfactor || mCurrBlendAlphaDFactor != alpha_dfactor) { diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index b1fb60cf92..3e4a1fe933 100644 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -493,8 +493,6 @@ private: eBlendFactor mCurrBlendAlphaSFactor; eBlendFactor mCurrBlendAlphaDFactor; - F32 mMaxAnisotropy; - std::vector mUIOffset; std::vector mUIScale; diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp index fa23654978..015312e570 100644 --- a/indra/llrender/llrendertarget.cpp +++ b/indra/llrender/llrendertarget.cpp @@ -134,7 +134,7 @@ bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, boo mUsage = usage; mUseDepth = depth; - if ((sUseFBO || use_fbo) && gGLManager.mHasFramebufferObject) + if ((sUseFBO || use_fbo)) { if (depth) { @@ -234,11 +234,9 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt) llassert( offset < 4 ); return false; } - if( offset > 0 && (mFBO == 0 || !gGLManager.mHasDrawBuffers) ) + if( offset > 0 && (mFBO == 0) ) { - LL_WARNS() << "FBO not used or no drawbuffers available; mFBO=" << (U32)mFBO << " gGLManager.mHasDrawBuffers=" << (U32)gGLManager.mHasDrawBuffers << LL_ENDL; llassert( mFBO != 0 ); - llassert( gGLManager.mHasDrawBuffers ); return false; } @@ -484,14 +482,12 @@ void LLRenderTarget::bindTarget() sCurFBO = mFBO; stop_glerror(); - if (gGLManager.mHasDrawBuffers) - { //setup multiple render targets - GLenum drawbuffers[] = {GL_COLOR_ATTACHMENT0, - GL_COLOR_ATTACHMENT1, - GL_COLOR_ATTACHMENT2, - GL_COLOR_ATTACHMENT3}; - glDrawBuffers(mTex.size(), drawbuffers); - } + //setup multiple render targets + GLenum drawbuffers[] = {GL_COLOR_ATTACHMENT0, + GL_COLOR_ATTACHMENT1, + GL_COLOR_ATTACHMENT2, + GL_COLOR_ATTACHMENT3}; + glDrawBuffers(mTex.size(), drawbuffers); if (mTex.empty()) { //no color buffer to draw to diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index a40ea2eb1e..d05f916d95 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -744,7 +744,7 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const //static void LLVertexBuffer::initClass(bool use_vbo, bool no_vbo_mapping) { - sEnableVBOs = use_vbo && gGLManager.mHasVertexBufferObject; + sEnableVBOs = use_vbo; sDisableVBOMapping = sEnableVBOs && no_vbo_mapping; } @@ -753,9 +753,7 @@ void LLVertexBuffer::unbind() { if (sGLRenderArray) { -#if GL_ARB_vertex_array_object glBindVertexArray(0); -#endif sGLRenderArray = 0; sGLRenderIndices = 0; sIBOActive = false; @@ -923,9 +921,7 @@ LLVertexBuffer::~LLVertexBuffer() if (mGLArray) { -#if GL_ARB_vertex_array_object releaseVAOName(mGLArray); -#endif } sCount--; @@ -956,10 +952,7 @@ void LLVertexBuffer::placeFence() const { /*if (!mFence && useVBOs()) { - if (gGLManager.mHasSync) - { - mFence = new LLGLSyncFence(); - } + mFence = new LLGLSyncFence(); } if (mFence) @@ -1234,11 +1227,9 @@ bool LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create) //actually allocate space for the vertex buffer if using VBO mapping flush(); //unmap - if (gGLManager.mHasVertexArrayObject && useVBOs() && sUseVAO) + if (useVBOs() && sUseVAO) { -#if GL_ARB_vertex_array_object mGLArray = getVAOName(); -#endif setupVertexArray(); } } @@ -1254,9 +1245,7 @@ void LLVertexBuffer::setupVertexArray() } LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX; -#if GL_ARB_vertex_array_object glBindVertexArray(mGLArray); -#endif sGLRenderArray = mGLArray; static const U32 attrib_size[] = @@ -1443,7 +1432,7 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran if (useVBOs()) { - if (!mMappable || gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange) + if (!mMappable) { if (count == -1) { @@ -1492,58 +1481,34 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran { U8* src = NULL; waitFence(); - if (gGLManager.mHasMapBufferRange) + if (map_range) { - if (map_range) - { -#ifdef GL_ARB_map_buffer_range - S32 offset = mOffsets[type] + sTypeSize[type]*index; - S32 length = (sTypeSize[type]*count+0xF) & ~0xF; - src = (U8*) glMapBufferRange(GL_ARRAY_BUFFER, offset, length, - GL_MAP_WRITE_BIT | - GL_MAP_FLUSH_EXPLICIT_BIT | - GL_MAP_INVALIDATE_RANGE_BIT); -#endif - } - else + S32 offset = mOffsets[type] + sTypeSize[type]*index; + S32 length = (sTypeSize[type]*count+0xF) & ~0xF; + src = (U8*) glMapBufferRange(GL_ARRAY_BUFFER, offset, length, + GL_MAP_WRITE_BIT | + GL_MAP_FLUSH_EXPLICIT_BIT | + GL_MAP_INVALIDATE_RANGE_BIT); + } + else + { + if (gDebugGL) { -#ifdef GL_ARB_map_buffer_range + GLint size = 0; + glGetBufferParameteriv(GL_ARRAY_BUFFER, GL_BUFFER_SIZE, &size); - if (gDebugGL) + if (size < mSize) { - GLint size = 0; - glGetBufferParameteriv(GL_ARRAY_BUFFER, GL_BUFFER_SIZE, &size); - - if (size < mSize) - { - LL_ERRS() << "Invalid buffer size." << LL_ENDL; - } + LL_ERRS() << "Invalid buffer size." << LL_ENDL; } - - src = (U8*) glMapBufferRange(GL_ARRAY_BUFFER, 0, mSize, - GL_MAP_WRITE_BIT | - GL_MAP_FLUSH_EXPLICIT_BIT); -#endif - } - } - else if (gGLManager.mHasFlushBufferRange) - { - if (map_range) - { - src = (U8*) glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); - } - else - { - src = (U8*) glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); } - } - else - { - map_range = false; - src = (U8*) glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); + + src = (U8*) glMapBufferRange(GL_ARRAY_BUFFER, 0, mSize, + GL_MAP_WRITE_BIT | + GL_MAP_FLUSH_EXPLICIT_BIT); } - llassert(src != NULL); + llassert(src != NULL); mMappedData = LL_NEXT_ALIGNED_ADDRESS(src); mAlignedOffset = mMappedData - src; @@ -1569,7 +1534,7 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran //-------------------- GLint buff; - glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff); + glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &buff); if ((GLuint)buff != mGLBuffer) { LL_ERRS() << "Invalid GL vertex buffer bound: " << buff << LL_ENDL; @@ -1590,7 +1555,7 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran map_range = false; } - if (map_range && gGLManager.mHasMapBufferRange && mMappable) + if (map_range && mMappable) { return mMappedData; } @@ -1616,7 +1581,7 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range) if (useVBOs()) { - if (!mMappable || gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange) + if (!mMappable) { if (count == -1) { @@ -1657,7 +1622,7 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range) if (gDebugGL && useVBOs()) { GLint elem = 0; - glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &elem); + glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &elem); if (elem != mGLIndices) { @@ -1673,48 +1638,24 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range) { U8* src = NULL; waitFence(); - if (gGLManager.mHasMapBufferRange) + if (map_range) { - if (map_range) - { -#ifdef GL_ARB_map_buffer_range - S32 offset = sizeof(U16)*index; - S32 length = sizeof(U16)*count; - src = (U8*) glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, offset, length, - GL_MAP_WRITE_BIT | - GL_MAP_FLUSH_EXPLICIT_BIT | - GL_MAP_INVALIDATE_RANGE_BIT); -#endif - } - else - { -#ifdef GL_ARB_map_buffer_range - src = (U8*) glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(U16)*mNumIndices, - GL_MAP_WRITE_BIT | - GL_MAP_FLUSH_EXPLICIT_BIT); -#endif - } - } - else if (gGLManager.mHasFlushBufferRange) - { - if (map_range) - { - src = (U8*) glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY); - } - else - { - src = (U8*) glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY); - } + S32 offset = sizeof(U16)*index; + S32 length = sizeof(U16)*count; + src = (U8*) glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, offset, length, + GL_MAP_WRITE_BIT | + GL_MAP_FLUSH_EXPLICIT_BIT | + GL_MAP_INVALIDATE_RANGE_BIT); } else { - map_range = false; - src = (U8*) glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY); + src = (U8*) glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(U16)*mNumIndices, + GL_MAP_WRITE_BIT | + GL_MAP_FLUSH_EXPLICIT_BIT); } - + llassert(src != NULL); - mMappedIndexData = src; //LL_NEXT_ALIGNED_ADDRESS(src); mAlignedIndexOffset = mMappedIndexData - src; stop_glerror(); @@ -1729,7 +1670,7 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range) if(mMappable) { GLint buff; - glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff); + glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &buff); if ((GLuint)buff != mGLIndices) { LL_ERRS() << "Invalid GL index buffer bound: " << buff << LL_ENDL; @@ -1748,7 +1689,7 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range) map_range = false; } - if (map_range && gGLManager.mHasMapBufferRange && mMappable) + if (map_range && mMappable) { return mMappedIndexData; } @@ -1812,25 +1753,20 @@ void LLVertexBuffer::unmapBuffer() } else { - if (gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange) + if (!mMappedVertexRegions.empty()) { - if (!mMappedVertexRegions.empty()) + LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("unmapBuffer - flush vertex"); + for (U32 i = 0; i < mMappedVertexRegions.size(); ++i) { - LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("unmapBuffer - flush vertex"); - for (U32 i = 0; i < mMappedVertexRegions.size(); ++i) - { - const MappedRegion& region = mMappedVertexRegions[i]; - S32 offset = region.mIndex >= 0 ? mOffsets[region.mType]+sTypeSize[region.mType]*region.mIndex : 0; - S32 length = sTypeSize[region.mType]*region.mCount; - if (gGLManager.mHasMapBufferRange) - { - glFlushMappedBufferRange(GL_ARRAY_BUFFER, offset, length); - } - } - - mMappedVertexRegions.clear(); + const MappedRegion& region = mMappedVertexRegions[i]; + S32 offset = region.mIndex >= 0 ? mOffsets[region.mType]+sTypeSize[region.mType]*region.mIndex : 0; + S32 length = sTypeSize[region.mType]*region.mCount; + glFlushMappedBufferRange(GL_ARRAY_BUFFER, offset, length); } + + mMappedVertexRegions.clear(); } + stop_glerror(); glUnmapBuffer(GL_ARRAY_BUFFER); stop_glerror(); @@ -1884,25 +1820,19 @@ void LLVertexBuffer::unmapBuffer() } else { - if (gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange) + if (!mMappedIndexRegions.empty()) { - if (!mMappedIndexRegions.empty()) + for (U32 i = 0; i < mMappedIndexRegions.size(); ++i) { - for (U32 i = 0; i < mMappedIndexRegions.size(); ++i) - { - LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("unmapBuffer - flush index"); - const MappedRegion& region = mMappedIndexRegions[i]; - S32 offset = region.mIndex >= 0 ? sizeof(U16)*region.mIndex : 0; - S32 length = sizeof(U16)*region.mCount; - if (gGLManager.mHasMapBufferRange) - { - glFlushMappedBufferRange(GL_ELEMENT_ARRAY_BUFFER, offset, length); - } - stop_glerror(); - } - - mMappedIndexRegions.clear(); + LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("unmapBuffer - flush index"); + const MappedRegion& region = mMappedIndexRegions[i]; + S32 offset = region.mIndex >= 0 ? sizeof(U16)*region.mIndex : 0; + S32 length = sizeof(U16)*region.mCount; + glFlushMappedBufferRange(GL_ELEMENT_ARRAY_BUFFER, offset, length); + stop_glerror(); } + + mMappedIndexRegions.clear(); } glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); @@ -2034,9 +1964,7 @@ bool LLVertexBuffer::bindGLArray() { { LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX; -#if GL_ARB_vertex_array_object glBindVertexArray(mGLArray); -#endif sGLRenderArray = mGLArray; } @@ -2228,7 +2156,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask) if (gDebugGL && !mGLArray) { GLint buff; - glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff); + glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &buff); if ((GLuint)buff != mGLBuffer) { if (gDebugSession) @@ -2243,7 +2171,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask) if (mGLIndices) { - glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff); + glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &buff); if ((GLuint)buff != mGLIndices) { if (gDebugSession) @@ -2264,9 +2192,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask) { if (sGLRenderArray) { -#if GL_ARB_vertex_array_object glBindVertexArray(0); -#endif sGLRenderArray = 0; sGLRenderIndices = 0; sIBOActive = false; diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 9508c1dc2d..100bcf7ab9 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10784,18 +10784,6 @@ Value 0 - RenderUseTransformFeedback - - Comment - [EXPERIMENTAL] Use transform feedback shaders for LoD updates - Persist - 1 - Type - Boolean - Value - 0 - - RenderVBOMappingDisable Comment diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index 6b4ab1be17..abc379a44f 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -1,4 +1,4 @@ -version 36 +version 37 // The version number above should be incremented IF AND ONLY IF some // change has been made that is sufficiently important to justify // resetting the graphics preferences of all users to the recommended @@ -287,14 +287,9 @@ list Intel RenderAnisotropic 1 0 RenderFSAASamples 1 0 RenderGLMultiThreaded 1 0 -RenderGLContextCoreProfile 1 0 -// AMD cards generally perform better when not using VBOs for streaming data -// AMD cards also prefer an OpenGL Compatibility Profile Context // HACK: Current AMD drivers have bugged cubemap arrays, limit number of reflection probes to 16 list AMD -RenderUseStreamVBO 1 0 -RenderGLContextCoreProfile 1 0 RenderReflectionProbeCount 1 16 diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index be33e1b30a..55c8d84838 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -165,19 +165,6 @@ void LLDrawPoolTerrain::render(S32 pass) LLOverrideFaceColor override(this, 1.f, 1.f, 1.f, 1.f); - if (!gGLManager.mHasMultitexture) - { - // No multitexture, render simple land. - renderSimple(); // Render without multitexture - return; - } - // Render simplified land if video card can't do sufficient multitexturing - if (!gGLManager.mHasARBEnvCombine || (gGLManager.mNumTextureUnits < 2)) - { - renderSimple(); // Render without multitexture - return; - } - LLGLSPipeline gls; if (mShaderLevel > 1 && sShader->mShaderLevel > 0) @@ -194,10 +181,6 @@ void LLDrawPoolTerrain::render(S32 pass) { renderSimple(); } - else if (gGLManager.mNumTextureUnits < 4) - { - renderFull2TU(); - } else { renderFull4TU(); diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp index a84f62036e..576024ead3 100644 --- a/indra/newview/lldrawpoolwater.cpp +++ b/indra/newview/lldrawpoolwater.cpp @@ -104,7 +104,7 @@ void LLDrawPoolWater::restoreGL() void LLDrawPoolWater::prerender() { - mShaderLevel = (gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps) ? LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WATER) : 0; + mShaderLevel = LLCubeMap::sUseCubeMaps ? LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WATER) : 0; } S32 LLDrawPoolWater::getNumPasses() @@ -188,12 +188,6 @@ void LLDrawPoolWater::render(S32 pass) stop_glerror(); - if (!gGLManager.mHasMultitexture) - { - // Ack! No multitexture! Bail! - return; - } - LLFace* refl_face = voskyp->getReflFace(); gPipeline.disableLights(); diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp index 63e7887d81..361a7666fa 100644 --- a/indra/newview/lldynamictexture.cpp +++ b/indra/newview/lldynamictexture.cpp @@ -125,7 +125,7 @@ void LLViewerDynamicTexture::preRender(BOOL clear_depth) llassert(mFullHeight <= static_cast(gPipeline.mPhysicsDisplay.getHeight())); } - if (gGLManager.mHasFramebufferObject && gPipeline.mPhysicsDisplay.isComplete() && !gGLManager.mIsAMD) + if (gPipeline.mPhysicsDisplay.isComplete() && !gGLManager.mIsAMD) { //using offscreen render target, just use the bottom left corner mOrigin.set(0, 0); } @@ -212,7 +212,7 @@ BOOL LLViewerDynamicTexture::updateAllInstances() return TRUE; } - bool use_fbo = gGLManager.mHasFramebufferObject && gPipeline.mBake.isComplete() && !gGLManager.mIsAMD; + bool use_fbo = gPipeline.mBake.isComplete() && !gGLManager.mIsAMD; if (use_fbo) { diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 3f69815e38..5562f1d057 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -1211,55 +1211,6 @@ bool LLFace::canRenderAsMask() return false; } - -//static -void LLFace::cacheFaceInVRAM(const LLVolumeFace& vf) -{ - LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE; - U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | - LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_NORMAL; - - if (vf.mWeights) - { - mask |= LLVertexBuffer::MAP_WEIGHT4; - } - - LLVertexBuffer* buff = new LLVertexBuffer(mask, GL_STATIC_DRAW); - vf.mVertexBuffer = buff; - - buff->allocateBuffer(vf.mNumVertices, 0, true); - - LLStrider f_vert; - LLStrider f_tangent; - LLStrider f_norm; - LLStrider f_tc; - - buff->getTangentStrider(f_tangent); - buff->getVertexStrider(f_vert); - buff->getNormalStrider(f_norm); - buff->getTexCoord0Strider(f_tc); - - for (U32 i = 0; i < vf.mNumVertices; ++i) - { - *f_vert++ = vf.mPositions[i]; - *f_tangent++ = vf.mTangents[i]; - *f_tc++ = vf.mTexCoords[i]; - (*f_norm++).set(vf.mNormals[i].getF32ptr()); - } - - if (vf.mWeights) - { - LLStrider f_wght; - buff->getWeight4Strider(f_wght); - for (U32 i = 0; i < vf.mNumVertices; ++i) - { - (*f_wght++).set(vf.mWeights[i].getF32ptr()); - } - } - - buff->flush(); -} - //helper function for pushing primitives for transform shaders and cleaning up //uninitialized data on the tail, plus tracking number of expected primitives void push_for_transform(LLVertexBuffer* buff, U32 source_count, U32 dest_count) @@ -1304,7 +1255,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, //don't use map range (generates many redundant unmap calls) - bool map_range = false; //gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange; + bool map_range = false; if (mVertexBuffer.notNull()) { @@ -1535,155 +1486,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, } } - static LLCachedControl use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback", false); - -#ifdef GL_TRANSFORM_FEEDBACK_BUFFER - if (use_transform_feedback && - mVertexBuffer->getUsage() == GL_DYNAMIC_COPY && - gTransformPositionProgram.mProgramObject && //transform shaders are loaded - mVertexBuffer->useVBOs() && //target buffer is in VRAM - !rebuild_weights && //TODO: add support for weights - !volume.isUnique()) //source volume is NOT flexi - { //use transform feedback to pack vertex buffer - - LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - transform feedback"); - LLGLEnable discard(GL_RASTERIZER_DISCARD); - LLVertexBuffer* buff = (LLVertexBuffer*) vf.mVertexBuffer.get(); - - if (vf.mVertexBuffer.isNull() || buff->getNumVerts() != vf.mNumVertices) - { - mVObjp->getVolume()->genTangents(f); - LLFace::cacheFaceInVRAM(vf); - buff = (LLVertexBuffer*) vf.mVertexBuffer.get(); - } - - LLGLSLShader* cur_shader = LLGLSLShader::sCurBoundShaderPtr; - - gGL.pushMatrix(); - gGL.loadMatrix((GLfloat*) mat_vert_in.mMatrix); - - if (rebuild_pos) - { - LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - tf position"); - gTransformPositionProgram.bind(); - - mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_VERTEX, mGeomIndex, mGeomCount); - - U8 index = mTextureIndex < FACE_DO_NOT_BATCH_TEXTURES ? mTextureIndex : 0; - - S32 val = 0; - U8* vp = (U8*) &val; - vp[0] = index; - vp[1] = 0; - vp[2] = 0; - vp[3] = 0; - - gTransformPositionProgram.uniform1i(sTextureIndexIn, val); - glBeginTransformFeedback(GL_POINTS); - buff->setBuffer(LLVertexBuffer::MAP_VERTEX); - - push_for_transform(buff, vf.mNumVertices, mGeomCount); - - glEndTransformFeedback(); - } - - if (rebuild_color) - { - LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - tf color"); - gTransformColorProgram.bind(); - - mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_COLOR, mGeomIndex, mGeomCount); - - S32 val = *((S32*) color.mV); - - gTransformColorProgram.uniform1i(sColorIn, val); - glBeginTransformFeedback(GL_POINTS); - buff->setBuffer(LLVertexBuffer::MAP_VERTEX); - push_for_transform(buff, vf.mNumVertices, mGeomCount); - glEndTransformFeedback(); - } - - if (rebuild_emissive) - { - LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - tf emissive"); - gTransformColorProgram.bind(); - - mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_EMISSIVE, mGeomIndex, mGeomCount); - - U8 glow = (U8) llclamp((S32) (getTextureEntry()->getGlow()*255), 0, 255); - - S32 glow32 = glow | - (glow << 8) | - (glow << 16) | - (glow << 24); - - gTransformColorProgram.uniform1i(sColorIn, glow32); - glBeginTransformFeedback(GL_POINTS); - buff->setBuffer(LLVertexBuffer::MAP_VERTEX); - push_for_transform(buff, vf.mNumVertices, mGeomCount); - glEndTransformFeedback(); - } - - if (rebuild_normal) - { - LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - tf normal"); - gTransformNormalProgram.bind(); - - mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_NORMAL, mGeomIndex, mGeomCount); - - glBeginTransformFeedback(GL_POINTS); - buff->setBuffer(LLVertexBuffer::MAP_NORMAL); - push_for_transform(buff, vf.mNumVertices, mGeomCount); - glEndTransformFeedback(); - } - - if (rebuild_tangent) - { - LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - tf tangent"); - gTransformTangentProgram.bind(); - - mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_TANGENT, mGeomIndex, mGeomCount); - - glBeginTransformFeedback(GL_POINTS); - buff->setBuffer(LLVertexBuffer::MAP_TANGENT); - push_for_transform(buff, vf.mNumVertices, mGeomCount); - glEndTransformFeedback(); - } - - if (rebuild_tcoord) - { - LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - tf tcoord"); - gTransformTexCoordProgram.bind(); - - mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_TEXCOORD0, mGeomIndex, mGeomCount); - - glBeginTransformFeedback(GL_POINTS); - buff->setBuffer(LLVertexBuffer::MAP_TEXCOORD0); - push_for_transform(buff, vf.mNumVertices, mGeomCount); - glEndTransformFeedback(); - - bool do_bump = bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1); - - if (do_bump) - { - mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_TEXCOORD1, mGeomIndex, mGeomCount); - glBeginTransformFeedback(GL_POINTS); - buff->setBuffer(LLVertexBuffer::MAP_TEXCOORD0); - push_for_transform(buff, vf.mNumVertices, mGeomCount); - glEndTransformFeedback(); - } - } - - glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0); - gGL.popMatrix(); - - if (cur_shader) - { - cur_shader->bind(); - } - } - else -#endif { //if it's not fullbright and has no normals, bake sunlight based on face normal //bool bake_sunlight = !getTextureEntry()->getFullbright() && diff --git a/indra/newview/llface.h b/indra/newview/llface.h index aa00c9d052..4778a8110b 100644 --- a/indra/newview/llface.h +++ b/indra/newview/llface.h @@ -81,8 +81,6 @@ public: PARTICLE = 0x0080, }; - static void cacheFaceInVRAM(const LLVolumeFace& vf); - public: LLFace(LLDrawable* drawablep, LLViewerObject* objp) { diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp index 826d4892ef..2c770f6ab8 100644 --- a/indra/newview/llfeaturemanager.cpp +++ b/indra/newview/llfeaturemanager.cpp @@ -431,41 +431,9 @@ bool LLFeatureManager::loadGPUClass() LL_WARNS("RenderInit") << "Unable to get an accurate benchmark; defaulting to class 3" << LL_ENDL; mGPUClass = GPU_CLASS_3; #else - if (gGLManager.mGLVersion <= 2.f) - { - mGPUClass = GPU_CLASS_0; - } - else if (gGLManager.mGLVersion <= 3.f) - { - mGPUClass = GPU_CLASS_1; - } - else if (gGLManager.mGLVersion < 3.3f) - { - mGPUClass = GPU_CLASS_2; - } - else if (gGLManager.mGLVersion < 4.f) - { - mGPUClass = GPU_CLASS_3; - } - else - { - mGPUClass = GPU_CLASS_4; - } - if (gGLManager.mIsIntel && mGPUClass > GPU_CLASS_1) - { - // Intels are generally weaker then other GPUs despite having advanced features - mGPUClass = (EGPUClass)(mGPUClass - 1); - } + mGPUClass = GPU_CLASS_2; #endif } - else if (gGLManager.mGLVersion <= 2.f) - { - mGPUClass = GPU_CLASS_0; - } - else if (gGLManager.mGLVersion <= 3.f) - { - mGPUClass = GPU_CLASS_1; - } else if (gbps <= 5.f) { mGPUClass = GPU_CLASS_0; @@ -679,10 +647,6 @@ void LLFeatureManager::applyBaseMasks() { maskFeatures("TexUnit8orLess"); } - if (gGLManager.mHasMapBufferRange) - { - maskFeatures("MapBufferRange"); - } if (gGLManager.mVRAM > 512) { maskFeatures("VRAMGT512"); diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 68928e9c8f..7b01e9050b 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -1198,7 +1198,7 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState() LLTextBox* reflections_text = getChild("ReflectionsText"); // Reflections - BOOL reflections = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps; + BOOL reflections = LLCubeMap::sUseCubeMaps; ctrl_reflections->setEnabled(reflections); reflections_text->setEnabled(reflections); @@ -1227,14 +1227,7 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState() // Hardware settings - if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderVBOEnable") || - !gGLManager.mHasVertexBufferObject) - { - getChildView("vbo")->setEnabled(FALSE); - } - - if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderCompressTextures") || - !gGLManager.mHasVertexBufferObject) + if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderCompressTextures")) { getChildView("texture compression")->setEnabled(FALSE); } diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp index d75f3eef6f..38ec24cae8 100644 --- a/indra/newview/llglsandbox.cpp +++ b/indra/newview/llglsandbox.cpp @@ -987,9 +987,8 @@ private: //----------------------------------------------------------------------------- F32 gpu_benchmark() { - if (!gGLManager.mHasTimerQuery) + if (gGLManager.mGLVersion < 3.3f) { // don't bother benchmarking venerable drivers which don't support accurate timing anyway - // and are likely to be correctly identified by the GPU table already. return -1.f; } @@ -1115,16 +1114,6 @@ F32 gpu_benchmark() // ensure matched pair of bind() and unbind() calls ShaderBinder binder(gBenchmarkProgram); -#ifdef GL_ARB_vertex_array_object - U32 glarray = 0; - - if (LLRender::sGLCoreProfile) - { - glGenVertexArrays(1, &glarray); - glBindVertexArray(glarray); - } -#endif - buff->setBuffer(LLVertexBuffer::MAP_VERTEX); glFinish(); @@ -1157,15 +1146,6 @@ F32 gpu_benchmark() } } -#ifdef GL_ARB_vertex_array_object - if (LLRender::sGLCoreProfile) - { - glBindVertexArray(0); - glDeleteVertexArrays(1, &glarray); - } -#endif - - std::sort(results.begin(), results.end()); F32 gbps = results[results.size()/2]; diff --git a/indra/newview/llscenemonitor.cpp b/indra/newview/llscenemonitor.cpp index 6a2f53aa42..49d5aa3e14 100644 --- a/indra/newview/llscenemonitor.cpp +++ b/indra/newview/llscenemonitor.cpp @@ -445,14 +445,14 @@ void LLSceneMonitor::calcDiffAggregate() if(mDiffState == EXECUTE_DIFF) { - glBeginQuery(GL_SAMPLES_PASSED_ARB, mQueryObject); + glBeginQuery(GL_SAMPLES_PASSED, mQueryObject); } gl_draw_scaled_target(0, 0, S32(mDiff->getWidth() * mDiffPixelRatio), S32(mDiff->getHeight() * mDiffPixelRatio), mDiff); if(mDiffState == EXECUTE_DIFF) { - glEndQuery(GL_SAMPLES_PASSED_ARB); + glEndQuery(GL_SAMPLES_PASSED); mDiffState = WAIT_ON_RESULT; } @@ -483,11 +483,11 @@ void LLSceneMonitor::fetchQueryResult() mDiffState = WAITING_FOR_NEXT_DIFF; GLuint available = 0; - glGetQueryObjectuiv(mQueryObject, GL_QUERY_RESULT_AVAILABLE_ARB, &available); + glGetQueryObjectuiv(mQueryObject, GL_QUERY_RESULT_AVAILABLE, &available); if(available) { GLuint count = 0; - glGetQueryObjectuiv(mQueryObject, GL_QUERY_RESULT_ARB, &count); + glGetQueryObjectuiv(mQueryObject, GL_QUERY_RESULT, &count); mDiffResult = sqrtf(count * 0.5f / (mDiff->getWidth() * mDiff->getHeight() * mDiffPixelRatio * mDiffPixelRatio)); //0.5 -> (front face + back face) diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 9682945208..2413d7705a 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -381,7 +381,7 @@ static bool handleJoystickChanged(const LLSD& newvalue) static bool handleUseOcclusionChanged(const LLSD& newvalue) { - LLPipeline::sUseOcclusion = (newvalue.asBoolean() && gGLManager.mHasOcclusionQuery + LLPipeline::sUseOcclusion = (newvalue.asBoolean() && LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion") && !gUseWireframe) ? 2 : 0; return true; } diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index dd82d43ab2..f10cb329a9 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -2309,44 +2309,6 @@ class LLAdvancedCheckViewAdminOptions : public view_listener_t } }; -///////////////////////////////////// -// Enable Object Object Occlusion /// -///////////////////////////////////// -class LLAdvancedEnableObjectObjectOcclusion: public view_listener_t -{ - bool handleEvent(const LLSD& userdata) - { - - bool new_value = gGLManager.mHasOcclusionQuery; // && LLFeatureManager::getInstance()->isFeatureAvailable(userdata.asString()); - return new_value; -} -}; - -///////////////////////////////////// -// Enable Framebuffer Objects /// -///////////////////////////////////// -class LLAdvancedEnableRenderFBO: public view_listener_t -{ - bool handleEvent(const LLSD& userdata) - { - bool new_value = gGLManager.mHasFramebufferObject; - return new_value; - } -}; - -///////////////////////////////////// -// Enable Deferred Rendering /// -///////////////////////////////////// -class LLAdvancedEnableRenderDeferred: public view_listener_t -{ - bool handleEvent(const LLSD& userdata) - { - bool new_value = gGLManager.mHasFramebufferObject && LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1 && - LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) > 0; - return new_value; - } -}; - ////////////////// // ADMIN STATUS // ////////////////// @@ -9367,8 +9329,6 @@ void initialize_menus() view_listener_t::addMenu(new LLAdvancedToggleWireframe(), "Advanced.ToggleWireframe"); view_listener_t::addMenu(new LLAdvancedCheckWireframe(), "Advanced.CheckWireframe"); // Develop > Render - view_listener_t::addMenu(new LLAdvancedEnableObjectObjectOcclusion(), "Advanced.EnableObjectObjectOcclusion"); - view_listener_t::addMenu(new LLAdvancedToggleRandomizeFramerate(), "Advanced.ToggleRandomizeFramerate"); view_listener_t::addMenu(new LLAdvancedCheckRandomizeFramerate(), "Advanced.CheckRandomizeFramerate"); view_listener_t::addMenu(new LLAdvancedTogglePeriodicSlowFrame(), "Advanced.TogglePeriodicSlowFrame"); diff --git a/indra/newview/llvieweroctree.cpp b/indra/newview/llvieweroctree.cpp index c785c80cea..a75eb518f3 100644 --- a/indra/newview/llvieweroctree.cpp +++ b/indra/newview/llvieweroctree.cpp @@ -917,15 +917,12 @@ void LLOcclusionCullingGroup::handleChildAddition(const OctreeNode* parent, Octr void LLOcclusionCullingGroup::releaseOcclusionQueryObjectNames() { - if (gGLManager.mHasOcclusionQuery) + for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; ++i) { - for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; ++i) + if (mOcclusionQuery[i]) { - if (mOcclusionQuery[i]) - { - releaseOcclusionQueryObjectName(mOcclusionQuery[i]); - mOcclusionQuery[i] = 0; - } + releaseOcclusionQueryObjectName(mOcclusionQuery[i]); + mOcclusionQuery[i] = 0; } } } @@ -1129,7 +1126,7 @@ void LLOcclusionCullingGroup::checkOcclusion() GLuint available; { LL_PROFILE_ZONE_NAMED_CATEGORY_OCTREE("co - query available"); - glGetQueryObjectuiv(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE_ARB, &available); + glGetQueryObjectuiv(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE, &available); } if (available) @@ -1137,7 +1134,7 @@ void LLOcclusionCullingGroup::checkOcclusion() GLuint query_result; // Will be # samples drawn, or a boolean depending on mHasOcclusionQuery2 (both are type GLuint) { LL_PROFILE_ZONE_NAMED_CATEGORY_OCTREE("co - query result"); - glGetQueryObjectuiv(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_ARB, &query_result); + glGetQueryObjectuiv(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT, &query_result); } #if LL_TRACK_PENDING_OCCLUSION_QUERIES sPendingQueries.erase(mOcclusionQuery[LLViewerCamera::sCurCameraID]); @@ -1197,7 +1194,6 @@ void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* sh OCCLUSION_FUDGE_Z = 1.; } - // Don't cull hole/edge water, unless we have the GL_ARB_depth_clamp extension if (earlyFail(camera, bounds)) { LL_PROFILE_ZONE_NAMED_CATEGORY_OCTREE("doOcclusion - early fail"); @@ -1221,17 +1217,12 @@ void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* sh // Depth clamp all water to avoid it being culled as a result of being // behind the far clip plane, and in the case of edge water to avoid // it being culled while still visible. - bool const use_depth_clamp = gGLManager.mHasDepthClamp && - (mSpatialPartition->mDrawableType == LLPipeline::RENDER_TYPE_WATER || + bool const use_depth_clamp = (mSpatialPartition->mDrawableType == LLPipeline::RENDER_TYPE_WATER || mSpatialPartition->mDrawableType == LLPipeline::RENDER_TYPE_VOIDWATER); - LLGLEnable clamp(use_depth_clamp ? GL_DEPTH_CLAMP : 0); + LLGLEnable clamp(use_depth_clamp ? GL_DEPTH_CLAMP : 0); -#if !LL_DARWIN - U32 mode = gGLManager.mHasOcclusionQuery2 ? GL_ANY_SAMPLES_PASSED : GL_SAMPLES_PASSED_ARB; -#else - U32 mode = GL_SAMPLES_PASSED_ARB; -#endif + U32 mode = gGLManager.mGLVersion >= 3.3f ? GL_ANY_SAMPLES_PASSED : GL_SAMPLES_PASSED; #if LL_TRACK_PENDING_OCCLUSION_QUERIES sPendingQueries.insert(mOcclusionQuery[LLViewerCamera::sCurCameraID]); diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 2ebe0f826f..296a383ed0 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -70,13 +70,6 @@ bool LLViewerShaderMgr::sSkipReload = false; LLVector4 gShinyOrigin; -//transform shaders -LLGLSLShader gTransformPositionProgram; -LLGLSLShader gTransformTexCoordProgram; -LLGLSLShader gTransformNormalProgram; -LLGLSLShader gTransformColorProgram; -LLGLSLShader gTransformTangentProgram; - //utility shaders LLGLSLShader gOcclusionProgram; LLGLSLShader gSkinnedOcclusionProgram; @@ -469,7 +462,7 @@ void LLViewerShaderMgr::setShaders() initAttribsAndUniforms(); gPipeline.releaseGLBuffers(); - LLPipeline::sWaterReflections = gGLManager.mHasCubeMap && LLPipeline::sRenderTransparentWater; + LLPipeline::sWaterReflections = LLPipeline::sRenderTransparentWater; LLPipeline::sRenderGlow = gSavedSettings.getBOOL("RenderGlow"); LLPipeline::updateRenderDeferred(); @@ -513,13 +506,6 @@ void LLViewerShaderMgr::setShaders() S32 wl_class = 1; S32 water_class = 2; S32 deferred_class = 0; - S32 transform_class = gGLManager.mHasTransformFeedback ? 1 : 0; - - static LLCachedControl use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback", false); - if (!use_transform_feedback) - { - transform_class = 0; - } if (useRenderDeferred) { @@ -572,7 +558,6 @@ void LLViewerShaderMgr::setShaders() mShaderLevel[SHADER_EFFECT] = effect_class; mShaderLevel[SHADER_WINDLIGHT] = wl_class; mShaderLevel[SHADER_DEFERRED] = deferred_class; - mShaderLevel[SHADER_TRANSFORM] = transform_class; std::string shader_name = loadBasicShaders(); if (shader_name.empty()) @@ -657,20 +642,6 @@ void LLViewerShaderMgr::setShaders() } } - if (loaded) - { - loaded = loadTransformShaders(); - if (loaded) - { - LL_INFOS() << "Loaded transform shaders." << LL_ENDL; - } - else - { - LL_WARNS() << "Failed to load transform shaders." << LL_ENDL; - llassert(loaded); - } - } - if (loaded) { // Load max avatar shaders to set the max level @@ -816,12 +787,6 @@ void LLViewerShaderMgr::unloadShaders() gDeferredSkinnedDiffuseProgram.unload(); gDeferredSkinnedBumpProgram.unload(); - gTransformPositionProgram.unload(); - gTransformTexCoordProgram.unload(); - gTransformNormalProgram.unload(); - gTransformColorProgram.unload(); - gTransformTangentProgram.unload(); - mShaderLevel[SHADER_LIGHTING] = 0; mShaderLevel[SHADER_OBJECT] = 0; mShaderLevel[SHADER_AVATAR] = 0; @@ -830,7 +795,6 @@ void LLViewerShaderMgr::unloadShaders() mShaderLevel[SHADER_INTERFACE] = 0; mShaderLevel[SHADER_EFFECT] = 0; mShaderLevel[SHADER_WINDLIGHT] = 0; - mShaderLevel[SHADER_TRANSFORM] = 0; gPipeline.mShadersLoaded = false; } @@ -1643,8 +1607,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() shader->mFeatures.hasReflectionProbes = mShaderLevel[SHADER_DEFERRED]; shader->mShaderFiles.clear(); - shader->mShaderFiles.push_back(make_pair("deferred/pbralphaV.glsl", GL_VERTEX_SHADER_ARB)); - shader->mShaderFiles.push_back(make_pair("deferred/pbralphaF.glsl", GL_FRAGMENT_SHADER_ARB)); + shader->mShaderFiles.push_back(make_pair("deferred/pbralphaV.glsl", GL_VERTEX_SHADER)); + shader->mShaderFiles.push_back(make_pair("deferred/pbralphaF.glsl", GL_FRAGMENT_SHADER)); shader->clearPermutations(); @@ -2437,10 +2401,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowV.glsl", GL_VERTEX_SHADER)); gDeferredShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER)); gDeferredShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - if (gGLManager.mHasDepthClamp) - { - gDeferredShadowProgram.addPermutation("DEPTH_CLAMP", "1"); - } + // gDeferredShadowProgram.addPermutation("DEPTH_CLAMP", "1"); // disable depth clamp for now gDeferredShadowProgram.mRiggedVariant = &gDeferredSkinnedShadowProgram; success = gDeferredShadowProgram.createShader(NULL, NULL); llassert(success); @@ -2456,10 +2417,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredSkinnedShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowSkinnedV.glsl", GL_VERTEX_SHADER)); gDeferredSkinnedShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER)); gDeferredSkinnedShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - if (gGLManager.mHasDepthClamp) - { - gDeferredSkinnedShadowProgram.addPermutation("DEPTH_CLAMP", "1"); - } + // gDeferredSkinnedShadowProgram.addPermutation("DEPTH_CLAMP", "1"); // disable depth clamp for now success = gDeferredSkinnedShadowProgram.createShader(NULL, NULL); llassert(success); } @@ -2472,10 +2430,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredShadowCubeProgram.mShaderFiles.clear(); gDeferredShadowCubeProgram.mShaderFiles.push_back(make_pair("deferred/shadowCubeV.glsl", GL_VERTEX_SHADER)); gDeferredShadowCubeProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER)); - if (gGLManager.mHasDepthClamp) - { - gDeferredShadowCubeProgram.addPermutation("DEPTH_CLAMP", "1"); - } + // gDeferredShadowCubeProgram.addPermutation("DEPTH_CLAMP", "1"); gDeferredShadowCubeProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; success = gDeferredShadowCubeProgram.createShader(NULL, NULL); llassert(success); @@ -2491,10 +2446,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredShadowFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER)); gDeferredShadowFullbrightAlphaMaskProgram.clearPermutations(); - if (gGLManager.mHasDepthClamp) - { - gDeferredShadowFullbrightAlphaMaskProgram.addPermutation("DEPTH_CLAMP", "1"); - } + gDeferredShadowFullbrightAlphaMaskProgram.addPermutation("DEPTH_CLAMP", "1"); gDeferredShadowFullbrightAlphaMaskProgram.addPermutation("IS_FULLBRIGHT", "1"); gDeferredShadowFullbrightAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; gDeferredShadowFullbrightAlphaMaskProgram.mRiggedVariant = &gDeferredSkinnedShadowFullbrightAlphaMaskProgram; @@ -2512,10 +2464,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredSkinnedShadowFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER)); gDeferredSkinnedShadowFullbrightAlphaMaskProgram.clearPermutations(); - if (gGLManager.mHasDepthClamp) - { - gDeferredSkinnedShadowFullbrightAlphaMaskProgram.addPermutation("DEPTH_CLAMP", "1"); - } + gDeferredSkinnedShadowFullbrightAlphaMaskProgram.addPermutation("DEPTH_CLAMP", "1"); gDeferredSkinnedShadowFullbrightAlphaMaskProgram.addPermutation("IS_FULLBRIGHT", "1"); gDeferredSkinnedShadowFullbrightAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; success = gDeferredSkinnedShadowFullbrightAlphaMaskProgram.createShader(NULL, NULL); @@ -2530,10 +2479,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredShadowAlphaMaskProgram.mShaderFiles.clear(); gDeferredShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskV.glsl", GL_VERTEX_SHADER)); gDeferredShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER)); - if (gGLManager.mHasDepthClamp) - { - gDeferredShadowAlphaMaskProgram.addPermutation("DEPTH_CLAMP", "1"); - } gDeferredShadowAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; gDeferredShadowAlphaMaskProgram.mRiggedVariant = &gDeferredSkinnedShadowAlphaMaskProgram; success = gDeferredShadowAlphaMaskProgram.createShader(NULL, NULL); @@ -2548,10 +2493,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredSkinnedShadowAlphaMaskProgram.mShaderFiles.clear(); gDeferredSkinnedShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskSkinnedV.glsl", GL_VERTEX_SHADER)); gDeferredSkinnedShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER)); - if (gGLManager.mHasDepthClamp) - { - gDeferredSkinnedShadowAlphaMaskProgram.addPermutation("DEPTH_CLAMP", "1"); - } gDeferredSkinnedShadowAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; success = gDeferredSkinnedShadowAlphaMaskProgram.createShader(NULL, NULL); llassert(success); @@ -2565,10 +2506,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredAvatarShadowProgram.mShaderFiles.clear(); gDeferredAvatarShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarShadowV.glsl", GL_VERTEX_SHADER)); gDeferredAvatarShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarShadowF.glsl", GL_FRAGMENT_SHADER)); - if (gGLManager.mHasDepthClamp) - { - gDeferredAvatarShadowProgram.addPermutation("DEPTH_CLAMP", "1"); - } gDeferredAvatarShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; success = gDeferredAvatarShadowProgram.createShader(NULL, NULL); llassert(success); @@ -2581,7 +2518,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredAvatarAlphaShadowProgram.mShaderFiles.clear(); gDeferredAvatarAlphaShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaShadowV.glsl", GL_VERTEX_SHADER)); gDeferredAvatarAlphaShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaShadowF.glsl", GL_FRAGMENT_SHADER)); - gDeferredAvatarAlphaShadowProgram.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0"); gDeferredAvatarAlphaShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; success = gDeferredAvatarAlphaShadowProgram.createShader(NULL, NULL); llassert(success); @@ -2594,7 +2530,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredAvatarAlphaMaskShadowProgram.mShaderFiles.clear(); gDeferredAvatarAlphaMaskShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaShadowV.glsl", GL_VERTEX_SHADER)); gDeferredAvatarAlphaMaskShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaMaskShadowF.glsl", GL_FRAGMENT_SHADER)); - gDeferredAvatarAlphaMaskShadowProgram.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0"); gDeferredAvatarAlphaMaskShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; success = gDeferredAvatarAlphaMaskShadowProgram.createShader(NULL, NULL); llassert(success); @@ -2608,10 +2543,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() 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)); - if (gGLManager.mHasDepthClamp) - { - gDeferredAttachmentShadowProgram.addPermutation("DEPTH_CLAMP", "1"); - } gDeferredAttachmentShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; success = gDeferredAttachmentShadowProgram.createShader(NULL, NULL); llassert(success); @@ -2624,7 +2555,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() 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.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0"); gDeferredAttachmentAlphaShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; success = gDeferredAttachmentAlphaShadowProgram.createShader(NULL, NULL); llassert(success); @@ -2637,7 +2567,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() 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.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0"); gDeferredAttachmentAlphaMaskShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; success = gDeferredAttachmentAlphaMaskShadowProgram.createShader(NULL, NULL); llassert(success); @@ -3976,95 +3905,6 @@ BOOL LLViewerShaderMgr::loadShadersWindLight() return success; } -BOOL LLViewerShaderMgr::loadTransformShaders() -{ - BOOL success = TRUE; - - if (mShaderLevel[SHADER_TRANSFORM] < 1) - { - gTransformPositionProgram.unload(); - gTransformTexCoordProgram.unload(); - gTransformNormalProgram.unload(); - gTransformColorProgram.unload(); - gTransformTangentProgram.unload(); - return TRUE; - } - - if (success) - { - gTransformPositionProgram.mName = "Position Transform Shader"; - gTransformPositionProgram.mShaderFiles.clear(); - gTransformPositionProgram.mShaderFiles.push_back(make_pair("transform/positionV.glsl", GL_VERTEX_SHADER)); - gTransformPositionProgram.mShaderLevel = mShaderLevel[SHADER_TRANSFORM]; - - const char* varyings[] = { - "position_out", - "texture_index_out", - }; - - success = gTransformPositionProgram.createShader(NULL, NULL, 2, varyings); - } - - if (success) - { - gTransformTexCoordProgram.mName = "TexCoord Transform Shader"; - gTransformTexCoordProgram.mShaderFiles.clear(); - gTransformTexCoordProgram.mShaderFiles.push_back(make_pair("transform/texcoordV.glsl", GL_VERTEX_SHADER)); - gTransformTexCoordProgram.mShaderLevel = mShaderLevel[SHADER_TRANSFORM]; - - const char* varyings[] = { - "texcoord_out", - }; - - success = gTransformTexCoordProgram.createShader(NULL, NULL, 1, varyings); - } - - if (success) - { - gTransformNormalProgram.mName = "Normal Transform Shader"; - gTransformNormalProgram.mShaderFiles.clear(); - gTransformNormalProgram.mShaderFiles.push_back(make_pair("transform/normalV.glsl", GL_VERTEX_SHADER)); - gTransformNormalProgram.mShaderLevel = mShaderLevel[SHADER_TRANSFORM]; - - const char* varyings[] = { - "normal_out", - }; - - success = gTransformNormalProgram.createShader(NULL, NULL, 1, varyings); - } - - if (success) - { - gTransformColorProgram.mName = "Color Transform Shader"; - gTransformColorProgram.mShaderFiles.clear(); - gTransformColorProgram.mShaderFiles.push_back(make_pair("transform/colorV.glsl", GL_VERTEX_SHADER)); - gTransformColorProgram.mShaderLevel = mShaderLevel[SHADER_TRANSFORM]; - - const char* varyings[] = { - "color_out", - }; - - success = gTransformColorProgram.createShader(NULL, NULL, 1, varyings); - } - - if (success) - { - gTransformTangentProgram.mName = "Binormal Transform Shader"; - gTransformTangentProgram.mShaderFiles.clear(); - gTransformTangentProgram.mShaderFiles.push_back(make_pair("transform/binormalV.glsl", GL_VERTEX_SHADER)); - gTransformTangentProgram.mShaderLevel = mShaderLevel[SHADER_TRANSFORM]; - - const char* varyings[] = { - "tangent_out", - }; - - success = gTransformTangentProgram.createShader(NULL, NULL, 1, varyings); - } - - - return success; -} - std::string LLViewerShaderMgr::getShaderDirPrefix(void) { return gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "shaders/class"); diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index 19d8e87d66..464efd6e3f 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -62,7 +62,6 @@ public: BOOL loadShadersWater(); BOOL loadShadersInterface(); BOOL loadShadersWindLight(); - BOOL loadTransformShaders(); std::vector mShaderLevel; S32 mMaxAvatarShaderLevel; @@ -78,7 +77,6 @@ public: SHADER_WINDLIGHT, SHADER_WATER, SHADER_DEFERRED, - SHADER_TRANSFORM, SHADER_COUNT }; @@ -150,15 +148,6 @@ inline bool operator != (LLViewerShaderMgr::shader_iter const & a, LLViewerShade extern LLVector4 gShinyOrigin; -//transform shaders -extern LLGLSLShader gTransformPositionProgram; -extern LLGLSLShader gTransformTexCoordProgram; -extern LLGLSLShader gTransformNormalProgram; -extern LLGLSLShader gTransformColorProgram; -extern LLGLSLShader gTransformTangentProgram; - - - //utility shaders extern LLGLSLShader gOcclusionProgram; extern LLGLSLShader gOcclusionCubeProgram; diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index e9815a7872..5474098d16 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -597,29 +597,6 @@ public: { LLTrace::Recording& last_frame_recording = LLTrace::get_frame_recording().getLastRecording(); - if (gGLManager.mHasATIMemInfo) - { - S32 meminfo[4]; - glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, meminfo); - - addText(xpos, ypos, llformat("%.2f MB Texture Memory Free", meminfo[0]/1024.f)); - ypos += y_inc; - - if (gGLManager.mHasVertexBufferObject) - { - glGetIntegerv(GL_VBO_FREE_MEMORY_ATI, meminfo); - addText(xpos, ypos, llformat("%.2f MB VBO Memory Free", meminfo[0]/1024.f)); - ypos += y_inc; - } - } - else if (gGLManager.mHasNVXMemInfo) - { - S32 free_memory; - glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &free_memory); - addText(xpos, ypos, llformat("%.2f MB Video Memory Free", free_memory/1024.f)); - ypos += y_inc; - } - //show streaming cost/triangle count of known prims in current region OR selection { F32 cost = 0.f; @@ -1979,11 +1956,6 @@ LLViewerWindow::LLViewerWindow(const Params& p) LL_DEBUGS("Window") << "Loading feature tables." << LL_ENDL; // Initialize OpenGL Renderer - if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderVBOEnable") || - !gGLManager.mHasVertexBufferObject) - { - gSavedSettings.setBOOL("RenderVBOEnable", FALSE); - } LLVertexBuffer::initClass(gSavedSettings.getBOOL("RenderVBOEnable"), gSavedSettings.getBOOL("RenderVBOMappingDisable")); LL_INFOS("RenderInit") << "LLVertexBuffer initialization done." << LL_ENDL ; gGL.init() ; @@ -1997,11 +1969,6 @@ LLViewerWindow::LLViewerWindow(const Params& p) gSavedSettings.setBOOL("ProbeHardwareOnStartup", FALSE); } - if (!gGLManager.mHasDepthClamp) - { - LL_INFOS("RenderInit") << "Missing feature GL_ARB_depth_clamp. Void water might disappear in rare cases." << LL_ENDL; - } - // If we crashed while initializng GL stuff last time, disable certain features if (gSavedSettings.getBOOL("RenderInitError")) { diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp index b7a5a0667b..9f43fb9b82 100644 --- a/indra/newview/llvosky.cpp +++ b/indra/newview/llvosky.cpp @@ -531,7 +531,7 @@ void LLVOSky::initCubeMap() images.push_back(mShinyTex[side].getImageRaw()); } - if (!mCubeMap && gSavedSettings.getBOOL("RenderWater") && gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps) + if (!mCubeMap && gSavedSettings.getBOOL("RenderWater") && LLCubeMap::sUseCubeMaps) { mCubeMap = new LLCubeMap(false); } @@ -576,7 +576,7 @@ void LLVOSky::restoreGL() updateDirections(psky); - if (gSavedSettings.getBOOL("RenderWater") && gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps) + if (gSavedSettings.getBOOL("RenderWater") && LLCubeMap::sUseCubeMaps) { initCubeMap(); } diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 61589640fe..ad1711d3fb 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -1121,27 +1121,7 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams ¶ms_in, const S32 detail, bo } } - static LLCachedControl use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback", false); - - bool cache_in_vram = use_transform_feedback && gTransformPositionProgram.mProgramObject && - (!mVolumeImpl || !mVolumeImpl->isVolumeUnique()); - - if (cache_in_vram) - { //this volume might be used as source data for a transform object, put it in vram - LLVolume* volume = getVolume(); - for (S32 i = 0; i < volume->getNumFaces(); ++i) - { - const LLVolumeFace& face = volume->getVolumeFace(i); - if (face.mVertexBuffer.notNull()) - { //already cached - break; - } - volume->genTangents(i); - LLFace::cacheFaceInVRAM(face); - } - } - - return TRUE; + return TRUE; } else if (NO_LOD == lod) { @@ -6417,16 +6397,6 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace U32 geometryBytes = 0; U32 buffer_usage = group->mBufferUsage; - static LLCachedControl use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback", false); - - if (use_transform_feedback && - gTransformPositionProgram.mProgramObject && //transform shaders are loaded - buffer_usage == GL_DYNAMIC_DRAW && //target buffer is in VRAM - !(mask & LLVertexBuffer::MAP_WEIGHT4)) //TODO: add support for weights - { - buffer_usage = GL_DYNAMIC_COPY; - } - #if LL_DARWIN // HACK from Leslie: // Disable VBO usage for alpha on Mac OS X because it kills the framerate diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 858cc90d04..f8ab68e57d 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -892,16 +892,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) if (!mRT->occlusionDepth.allocate(resX/occlusion_divisor, resY/occlusion_divisor, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false; if (!addDeferredAttachments(mRT->deferredScreen)) return false; - GLuint screenFormat = GL_RGBA16; - if (gGLManager.mIsAMD) - { - screenFormat = GL_RGBA12; - } - - if (gGLManager.mGLVersion < 4.f && gGLManager.mIsNVIDIA) - { - screenFormat = GL_RGBA16F_ARB; - } + GLuint screenFormat = GL_RGBA; if (!mRT->screen.allocate(resX, resY, screenFormat, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false; if (samples > 0) @@ -1065,8 +1056,7 @@ void LLPipeline::refreshCachedSettings() LLPipeline::sUseOcclusion = (!gUseWireframe && LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion") - && gSavedSettings.getBOOL("UseOcclusion") - && gGLManager.mHasOcclusionQuery) ? 2 : 0; + && gSavedSettings.getBOOL("UseOcclusion")) ? 2 : 0; WindLightUseAtmosShaders = TRUE; // DEPRECATED -- gSavedSettings.getBOOL("WindLightUseAtmosShaders"); RenderDeferred = TRUE; // DEPRECATED -- gSavedSettings.getBOOL("RenderDeferred"); @@ -2355,8 +2345,7 @@ static LLTrace::BlockTimerStatHandle FTM_CULL("Object Culling"); void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, LLPlane* planep) { static LLCachedControl use_occlusion(gSavedSettings,"UseOcclusion"); - static bool can_use_occlusion = LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion") - && gGLManager.mHasOcclusionQuery; + static bool can_use_occlusion = LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion"); LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; //LL_RECORD_BLOCK_TIME(FTM_CULL); @@ -9759,7 +9748,7 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera LLGLEnable cull(GL_CULL_FACE); //enable depth clamping if available - LLGLEnable depth_clamp(gGLManager.mHasDepthClamp ? GL_DEPTH_CLAMP : 0); + //LLGLEnable depth_clamp(GL_DEPTH_CLAMP); if (use_shader) { diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index eb4f9f16fa..825d1202a6 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -3099,8 +3099,6 @@ function="World.EnvPreset" - -- cgit v1.3 From 75de4d32768bb1359611dc7cd963c9a12f94423d Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 23 Sep 2022 12:53:24 -0500 Subject: SL-18156 Cleanup of MikktSpace integration, apply MikktSpace tangents to all meshes. --- indra/llmath/llvolume.cpp | 77 ++++++++++++--------------------- indra/llmath/llvolume.h | 6 +-- indra/llprimitive/lldaeloader.cpp | 2 +- indra/llprimitive/llmodel.cpp | 16 +++---- indra/newview/app_settings/settings.xml | 11 ----- indra/newview/llface.cpp | 16 ++----- indra/newview/llmodelpreview.cpp | 3 +- 7 files changed, 43 insertions(+), 88 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 454969b912..21df7f2b2d 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -2102,14 +2102,11 @@ void LLVolume::regen() createVolumeFaces(); } -void LLVolume::genTangents(S32 face, bool mikktspace) +void LLVolume::genTangents(S32 face) { // generate legacy tangents for the specified face - // if mikktspace is true, only generate tangents if mikktspace tangents are not present (handles the case for non-mesh prims) - if (!mikktspace || mVolumeFaces[face].mMikktSpaceTangents == nullptr) - { - mVolumeFaces[face].createTangents(); - } + llassert(!isMeshAssetLoaded() || mVolumeFaces[face].mTangents != nullptr); // if this is a complete mesh asset, we should already have tangents + mVolumeFaces[face].createTangents(); } LLVolume::~LLVolume() @@ -2492,15 +2489,7 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) { face.mNormalizedScale.set(1, 1, 1); } - if (mdl[i].has("NormalizedTranslation")) - { - face.mNormalizedTranslation.setValue(mdl[i]["NormalizedTranslation"]); - } - else - { - face.mNormalizedTranslation.set(1, 1, 1); - } - + LLVector4a pos_range; pos_range.setSub(max_pos, min_pos); LLVector2 tc_range2 = max_tc - min_tc; @@ -2551,17 +2540,16 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) } } -#if 0 +#if 0 // keep this code for now in case we decide to add support for on-the-wire tangents { if (!tangent.empty()) { - face.allocateTangents(face.mNumVertices, true); + face.allocateTangents(face.mNumVertices); U16* t = (U16*)&(tangent[0]); - // store incoming tangents in mMikktSpaceTangents - // NOTE: tangents coming from the asset may not be mikkt space, but they should always be used by the CLTF shaders to + // NOTE: tangents coming from the asset may not be mikkt space, but they should always be used by the GLTF shaders to // maintain compliance with the GLTF spec - LLVector4a* t_out = face.mMikktSpaceTangents; + LLVector4a* t_out = face.mTangents; for (U32 j = 0; j < num_verts; ++j) { @@ -4111,7 +4099,7 @@ S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& en { if (tangent_out != NULL) // if the caller wants tangents, we may need to generate them { - genTangents(i); + genTangents(i); } if (isUnique()) @@ -4854,15 +4842,15 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src) mTangents = NULL; } - if (src.mMikktSpaceTangents) + if (src.mTangents) { - allocateTangents(src.mNumVertices, true); - LLVector4a::memcpyNonAliased16((F32*)mMikktSpaceTangents, (F32*)src.mMikktSpaceTangents, vert_size); + allocateTangents(src.mNumVertices); + LLVector4a::memcpyNonAliased16((F32*)mTangents, (F32*)src.mTangents, vert_size); } else { - ll_aligned_free_16(mMikktSpaceTangents); - mMikktSpaceTangents = nullptr; + ll_aligned_free_16(mTangents); + mTangents = nullptr; } if (src.mWeights) @@ -4909,8 +4897,7 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src) mOptimized = src.mOptimized; mNormalizedScale = src.mNormalizedScale; - mNormalizedTranslation = src.mNormalizedTranslation; - + //delete return *this; } @@ -4937,8 +4924,6 @@ void LLVolumeFace::freeData() mIndices = NULL; ll_aligned_free_16(mTangents); mTangents = NULL; - ll_aligned_free_16(mMikktSpaceTangents); - mMikktSpaceTangents = nullptr; ll_aligned_free_16(mWeights); mWeights = NULL; @@ -5060,9 +5045,6 @@ void LLVolumeFace::remap() ll_aligned_free_16(mTangents); mTangents = NULL; - ll_aligned_free_16(mMikktSpaceTangents); - mMikktSpaceTangents = nullptr; - // Assign new values mIndices = remap_indices; mPositions = remap_positions; @@ -5484,10 +5466,10 @@ bool LLVolumeFace::cacheOptimize(bool gen_tangents) llassert(!mOptimized); mOptimized = TRUE; - if (mMikktSpaceTangents == nullptr && gen_tangents && mNormals && mTexCoords) - { // make sure to generate mikkt space tangents for cache optimizing since the index buffer may change - allocateTangents(mNumVertices, true); - + if (gen_tangents && mNormals && mTexCoords) + { // generate mikkt space tangents before cache optimizing since the index buffer may change + // a bit of a hack to do this here, but this function gets called exactly once for the lifetime of a mesh + // and is executed on a background thread SMikkTSpaceInterface ms; ms.m_getNumFaces = [](const SMikkTSpaceContext* pContext) @@ -5573,7 +5555,7 @@ bool LLVolumeFace::cacheOptimize(bool gen_tangents) allocateWeights(vert_count); } - allocateTangents(mNumVertices, true); + allocateTangents(mNumVertices); for (int i = 0; i < mNumIndices; ++i) { @@ -5585,7 +5567,7 @@ bool LLVolumeFace::cacheOptimize(bool gen_tangents) mNormals[dst_idx].load3(data.n[src_idx].mV); mTexCoords[dst_idx] = data.tc[src_idx]; - mMikktSpaceTangents[dst_idx].loadua(data.t[src_idx].mV); + mTangents[dst_idx].loadua(data.t[src_idx].mV); if (mWeights) { @@ -5605,10 +5587,10 @@ bool LLVolumeFace::cacheOptimize(bool gen_tangents) mPositions[i].mul(inv_scale); mNormals[i].mul(scale); mNormals[i].normalize3(); - F32 w = mMikktSpaceTangents[i].getF32ptr()[3]; - mMikktSpaceTangents[i].mul(scale); - mMikktSpaceTangents[i].normalize3(); - mMikktSpaceTangents[i].getF32ptr()[3] = w; + F32 w = mTangents[i].getF32ptr()[3]; + mTangents[i].mul(scale); + mTangents[i].normalize3(); + mTangents[i].getF32ptr()[3] = w; } } @@ -5703,7 +5685,6 @@ void LLVolumeFace::swapData(LLVolumeFace& rhs) llswap(rhs.mPositions, mPositions); llswap(rhs.mNormals, mNormals); llswap(rhs.mTangents, mTangents); - llswap(rhs.mMikktSpaceTangents, mMikktSpaceTangents); llswap(rhs.mTexCoords, mTexCoords); llswap(rhs.mIndices,mIndices); llswap(rhs.mNumVertices, mNumVertices); @@ -6415,7 +6396,6 @@ void LLVolumeFace::createTangents() { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; - if (!mTangents) { allocateTangents(mNumVertices); @@ -6539,11 +6519,10 @@ void LLVolumeFace::pushVertex(const LLVector4a& pos, const LLVector4a& norm, con mNumVertices++; } -void LLVolumeFace::allocateTangents(S32 num_verts, bool mikktspace) +void LLVolumeFace::allocateTangents(S32 num_verts) { - auto& buff = mikktspace ? mMikktSpaceTangents : mTangents; - ll_aligned_free_16(buff); - buff = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts); + ll_aligned_free_16(mTangents); + mTangents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts); } void LLVolumeFace::allocateWeights(S32 num_verts) diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index 6ea12c6920..3aa7034357 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -873,7 +873,7 @@ public: void createTangents(); void resizeVertices(S32 num_verts); - void allocateTangents(S32 num_verts, bool mikktspace = false); + void allocateTangents(S32 num_verts); void allocateWeights(S32 num_verts); void allocateJointIndices(S32 num_verts); void resizeIndices(S32 num_indices); @@ -947,7 +947,6 @@ public: LLVector4a* mPositions; // Contains vertices, nortmals and texcoords LLVector4a* mNormals; // pointer into mPositions LLVector4a* mTangents; - LLVector4a* mMikktSpaceTangents = nullptr; // for GLTF rendering, use mikkt space tangents LLVector2* mTexCoords; // pointer into mPositions // mIndices contains mNumIndices amount of elements. @@ -984,7 +983,6 @@ public: // when encoding the source mesh into a unit cube // used for regenerating tangents LLVector3 mNormalizedScale = LLVector3(1,1,1); - LLVector3 mNormalizedTranslation; private: BOOL createUnCutCubeCap(LLVolume* volume, BOOL partial_build = FALSE); @@ -1031,7 +1029,7 @@ public: void setDirty() { mPathp->setDirty(); mProfilep->setDirty(); } void regen(); - void genTangents(S32 face, bool mikktspace = false); + void genTangents(S32 face); BOOL isConvex() const; BOOL isCap(S32 face); diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp index dbb34ab60b..73b97cec08 100644 --- a/indra/llprimitive/lldaeloader.cpp +++ b/indra/llprimitive/lldaeloader.cpp @@ -2581,7 +2581,7 @@ bool LLDAELoader::loadModelsFromDomMesh(domMesh* mesh, std::vector& mo next->mLabel = model_name + (char)((int)'a' + next->mSubmodelID) + lod_suffix[mLod]; next->getVolumeFaces() = remainder; next->mNormalizedScale = ret->mNormalizedScale; - next->mNormalizedTranslation = ret->mNormalizedTranslation; + if ( ret->mMaterialList.size() > LL_SCULPT_MESH_MAX_FACES) { next->mMaterialList.assign(ret->mMaterialList.begin() + LL_SCULPT_MESH_MAX_FACES, ret->mMaterialList.end()); diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index a6492f43d4..33d52d89bd 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -53,7 +53,6 @@ const int MODEL_NAMES_LENGTH = sizeof(model_names) / sizeof(std::string); LLModel::LLModel(LLVolumeParams& params, F32 detail) : LLVolume(params, detail), mNormalizedScale(1,1,1), - mNormalizedTranslation(0,0,0), mPelvisOffset( 0.0f ), mStatus(NO_ERRORS), mSubmodelID(0) @@ -296,7 +295,7 @@ void LLModel::normalizeVolumeFaces() // the positions to fit within the unit cube. LLVector4a* pos = (LLVector4a*) face.mPositions; LLVector4a* norm = (LLVector4a*) face.mNormals; - LLVector4a* t = (LLVector4a*)face.mMikktSpaceTangents; + LLVector4a* t = (LLVector4a*)face.mTangents; for (U32 j = 0; j < face.mNumVertices; ++j) { @@ -329,10 +328,10 @@ void LLModel::normalizeVolumeFaces() mNormalizedTranslation.set(trans.getF32ptr()); mNormalizedTranslation *= -1.f; + // remember normalized scale so original dimensions can be recovered for mesh processing (i.e. tangent generation) for (auto& face : mVolumeFaces) { face.mNormalizedScale = mNormalizedScale; - face.mNormalizedTranslation = mNormalizedTranslation; } } } @@ -800,10 +799,10 @@ LLSD LLModel::writeModel( } } -#if 0 - if (face.mMikktSpaceTangents) +#if 0 // keep this code for now in case we want to support transporting tangents with mesh assets + if (face.mTangents) { //normals - F32* tangent = face.mMikktSpaceTangents[j].getF32ptr(); + F32* tangent = face.mTangents[j].getF32ptr(); for (U32 k = 0; k < 4; ++k) { //for each component @@ -848,7 +847,6 @@ LLSD LLModel::writeModel( mdl[model_names[idx]][i]["PositionDomain"]["Min"] = min_pos.getValue(); mdl[model_names[idx]][i]["PositionDomain"]["Max"] = max_pos.getValue(); mdl[model_names[idx]][i]["NormalizedScale"] = face.mNormalizedScale.getValue(); - mdl[model_names[idx]][i]["NormalizedTranslation"] = face.mNormalizedTranslation.getValue(); mdl[model_names[idx]][i]["Position"] = verts; @@ -857,10 +855,12 @@ LLSD LLModel::writeModel( mdl[model_names[idx]][i]["Normal"] = normals; } - if (face.mMikktSpaceTangents) +#if 0 // keep this code for now in case we decide to transport tangents with mesh assets + if (face.mTangents) { mdl[model_names[idx]][i]["Tangent"] = tangents; } +#endif if (face.mTexCoords) { diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 01271ddc28..f183f49039 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10558,17 +10558,6 @@ Value 0 - RenderUseMikktSpace - - Comment - Use Mikkt Space tangents on GLTF materials. - Persist - 1 - Type - Boolean - Value - 1 - RenderUseTriStrips Comment diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 5de8bda787..b24bc69791 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -1968,24 +1968,14 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, mVertexBuffer->getTangentStrider(tangent, mGeomIndex, mGeomCount, map_range); F32* tangents = (F32*) tangent.get(); - LLGLTFMaterial* gltf_mat = tep->getGLTFMaterial(); - static LLCachedControl use_mikktspace(gSavedSettings, "RenderUseMikktSpace"); - bool mikktspace = use_mikktspace && gltf_mat != nullptr; - - mVObjp->getVolume()->genTangents(f, mikktspace); + mVObjp->getVolume()->genTangents(f); LLVector4Logical mask; mask.clear(); mask.setElement<3>(); - LLVector4a* tbuff = mikktspace ? vf.mMikktSpaceTangents : vf.mTangents; - if (tbuff == nullptr) - { // non-mesh prims will not have mikktspace tangents - tbuff = vf.mTangents; - } - - LLVector4a* src = tbuff; - LLVector4a* end = tbuff+num_vertices; + LLVector4a* src = vf.mTangents; + LLVector4a* end = vf.mTangents +num_vertices; while (src < end) { diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index 076ebd80c2..aa3446a308 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -1549,7 +1549,7 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe { new_face.resizeIndices(buf_indices_copied); new_face.resizeVertices(buf_positions_copied); - new_face.allocateTangents(buf_positions_copied, true); + new_face.allocateTangents(buf_positions_copied); S32 idx_size = (buf_indices_copied * sizeof(U16) + 0xF) & ~0xF; LLVector4a::memcpyNonAliased16((F32*)new_face.mIndices, (F32*)buffer_indices, idx_size); @@ -1839,7 +1839,6 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d LLVolumeFace& src = base->getVolumeFace(i); LLVolumeFace& dst = target_model->getVolumeFace(i); dst.mNormalizedScale = src.mNormalizedScale; - dst.mNormalizedTranslation = src.mNormalizedTranslation; } S32 model_meshopt_mode = meshopt_mode; -- cgit v1.3 From 2e499bcc40871b6a68700203cc83fe7d81c79c24 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 28 Sep 2022 19:14:00 -0500 Subject: SL-18190 Prune srgb_to_linear from atmosphericsFuncs.glsl --- indra/llmath/v3color.h | 18 ++++++++++---- indra/llrender/llrender.cpp | 4 ++++ indra/llrender/llshadermgr.cpp | 3 +++ indra/llrender/llshadermgr.h | 7 ++++-- .../class2/windlight/atmosphericsFuncs.glsl | 28 +++++++--------------- indra/newview/llsettingsvo.cpp | 4 ++++ 6 files changed, 39 insertions(+), 25 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/v3color.h b/indra/llmath/v3color.h index 43a632408c..c3c6ae2242 100644 --- a/indra/llmath/v3color.h +++ b/indra/llmath/v3color.h @@ -484,13 +484,23 @@ inline const LLColor3 srgbColor3(const LLColor3 &a) { return srgbColor; } -inline const LLColor3 linearColor3(const LLColor3 &a) { +inline const LLColor3 linearColor3(const F32* v) { LLColor3 linearColor; - linearColor.mV[0] = sRGBtoLinear(a.mV[0]); - linearColor.mV[1] = sRGBtoLinear(a.mV[1]); - linearColor.mV[2] = sRGBtoLinear(a.mV[2]); + linearColor.mV[0] = sRGBtoLinear(v[0]); + linearColor.mV[1] = sRGBtoLinear(v[1]); + linearColor.mV[2] = sRGBtoLinear(v[2]); return linearColor; } +template +inline const LLColor3 linearColor3(const T& a) { + return linearColor3(a.mV); +} + +template +inline const LLVector3 linearColor3v(const T& a) { + return LLVector3(linearColor3(a.mV).mV); +} + #endif diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 6e659641fe..c7eb4613c1 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -979,6 +979,10 @@ void LLRender::syncLightState() shader->uniform4fv(LLShaderMgr::AMBIENT, 1, mAmbientLightColor.mV); shader->uniform4fv(LLShaderMgr::SUNLIGHT_COLOR, 1, diffuse[0].mV); shader->uniform4fv(LLShaderMgr::MOONLIGHT_COLOR, 1, diffuse_b[0].mV); + + shader->uniform3fv(LLShaderMgr::AMBIENT_LINEAR, 1, linearColor3(mAmbientLightColor).mV); + shader->uniform3fv(LLShaderMgr::SUNLIGHT_LINEAR, 1, linearColor3(diffuse[0]).mV); + shader->uniform3fv(LLShaderMgr::MOONLIGHT_LINEAR, 1, linearColor3(diffuse_b[0]).mV); } } diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index c817a59189..8807433d80 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -1231,9 +1231,12 @@ void LLShaderMgr::initAttribsAndUniforms() mReservedUniforms.push_back("sunlight_color"); mReservedUniforms.push_back("ambient_color"); mReservedUniforms.push_back("blue_horizon"); + mReservedUniforms.push_back("blue_horizon_linear"); mReservedUniforms.push_back("blue_density"); + mReservedUniforms.push_back("blue_density_linear"); mReservedUniforms.push_back("haze_horizon"); mReservedUniforms.push_back("haze_density"); + mReservedUniforms.push_back("haze_density_linear"); mReservedUniforms.push_back("cloud_shadow"); mReservedUniforms.push_back("density_multiplier"); mReservedUniforms.push_back("distance_multiplier"); diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h index 4d32a62ca6..b803a8b129 100644 --- a/indra/llrender/llshadermgr.h +++ b/indra/llrender/llshadermgr.h @@ -85,8 +85,8 @@ public: BUMP_MAP, // "bumpMap" BUMP_MAP2, // "bumpMap2" ENVIRONMENT_MAP, // "environmentMap" - REFLECTION_PROBES, // "reflectionProbes" - IRRADIANCE_PROBES, // "irradianceProbes" + REFLECTION_PROBES, // "reflectionProbes" + IRRADIANCE_PROBES, // "irradianceProbes" CLOUD_NOISE_MAP, // "cloud_noise_texture" CLOUD_NOISE_MAP_NEXT, // "cloud_noise_texture_next" FULLBRIGHT, // "fullbright" @@ -94,9 +94,12 @@ public: SUNLIGHT_COLOR, // "sunlight_color" AMBIENT, // "ambient_color" BLUE_HORIZON, // "blue_horizon" + BLUE_HORIZON_LINEAR, // "blue_horizon_linear" BLUE_DENSITY, // "blue_density" + BLUE_DENSITY_LINEAR, // "blue_density_linear" HAZE_HORIZON, // "haze_horizon" HAZE_DENSITY, // "haze_density" + HAZE_DENSITY_LINEAR, // "haze_density_linear" CLOUD_SHADOW, // "cloud_shadow" DENSITY_MULTIPLIER, // "density_multiplier" DISTANCE_MULTIPLIER, // "distance_multiplier" diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsFuncs.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsFuncs.glsl index 516550be1c..3d6c15fe55 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsFuncs.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsFuncs.glsl @@ -23,23 +23,21 @@ * $/LicenseInfo$ */ -vec3 srgb_to_linear(vec3 col); - uniform vec4 lightnorm; uniform vec4 sunlight_color; -vec3 sunlight_linear = srgb_to_linear(sunlight_color.rgb); +uniform vec3 sunlight_linear; uniform vec4 moonlight_color; -vec3 moonlight_linear = srgb_to_linear(moonlight_color.rgb); +uniform vec3 moonlight_linear; uniform int sun_up_factor; uniform vec4 ambient_color; -vec3 ambient_linear = srgb_to_linear(ambient_color.rgb); +uniform vec3 ambient_linear; uniform vec4 blue_horizon; -vec3 blue_horizon_linear = srgb_to_linear(blue_horizon.rgb); +uniform vec3 blue_horizon_linear; uniform vec4 blue_density; -vec3 blue_density_linear = srgb_to_linear(blue_density.rgb); +uniform vec3 blue_density_linear; uniform float haze_horizon; uniform float haze_density; -vec3 haze_density_linear = srgb_to_linear(vec3(haze_density)); +uniform float haze_density_linear; uniform float cloud_shadow; uniform float density_multiplier; uniform float distance_multiplier; @@ -150,13 +148,6 @@ void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, ou void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 light_dir, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten, bool use_ao) { -#if 0 - calcAtmosphericVars(inPositionEye, light_dir, 1.0, sunlit, amblit, additive, atten, false); - sunlit = srgb_to_linear(sunlit)*2.25; - amblit = srgb_to_linear(amblit)*0.15; - additive = srgb_to_linear(additive); - atten = srgb_to_linear(atten); -#else vec3 rel_pos = inPositionEye; //(TERRAIN) limit altitude @@ -168,15 +159,15 @@ void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 light_dir, float ambFact // sunlight attenuation effect (hue and brightness) due to atmosphere // this is used later for sunlight modulation at various altitudes - vec3 light_atten = (blue_density_linear + (haze_density_linear * 0.25)) * (density_multiplier * max_y); + vec3 light_atten = (blue_density_linear + vec3(haze_density_linear * 0.25)) * (density_multiplier * max_y); // I had thought blue_density and haze_density should have equal weighting, // but attenuation due to haze_density tends to seem too strong - vec3 combined_haze_linear = blue_density_linear + haze_density_linear; + vec3 combined_haze_linear = blue_density_linear + vec3(haze_density_linear); vec3 combined_haze = blue_density.rgb + vec3(haze_density); vec3 blue_weight = blue_density_linear / combined_haze_linear; - vec3 haze_weight = haze_density_linear / combined_haze_linear; + vec3 haze_weight = vec3(haze_density_linear) / combined_haze_linear; //(TERRAIN) compute sunlight from lightnorm y component. Factor is roughly cosecant(sun elevation) (for short rays like terrain) float above_horizon_factor = 1.0 / max(1e-6, lightnorm.y); @@ -234,5 +225,4 @@ void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 light_dir, float ambFact sunlit *= 0.8; amblit *= 0.05; additive *= 0.25; -#endif } diff --git a/indra/newview/llsettingsvo.cpp b/indra/newview/llsettingsvo.cpp index fd1e69b9d3..a5a8ec4a93 100644 --- a/indra/newview/llsettingsvo.cpp +++ b/indra/newview/llsettingsvo.cpp @@ -723,6 +723,10 @@ void LLSettingsVOSky::applySpecial(void *ptarget, bool force) shader->uniform1f(LLShaderMgr::GAMMA, g); shader->uniform1f(LLShaderMgr::DISPLAY_GAMMA, display_gamma); + + shader->uniform3fv(LLShaderMgr::BLUE_HORIZON_LINEAR, linearColor3v(getBlueHorizon())); + shader->uniform3fv(LLShaderMgr::BLUE_DENSITY_LINEAR, linearColor3v(getBlueDensity())); + shader->uniform1f(LLShaderMgr::HAZE_DENSITY_LINEAR, sRGBtoLinear(getHazeDensity())); } LLSettingsSky::parammapping_t LLSettingsVOSky::getParameterMap() const -- cgit v1.3 From 5c83ac76b5439a72db0d1b7ac3a747b19d8e048a Mon Sep 17 00:00:00 2001 From: Brad Kittenbrink Date: Thu, 29 Sep 2022 13:23:11 -0700 Subject: fix for mac build breakage DRTVWR-559 --- indra/llmath/v3color.h | 5 ----- indra/llmath/v3math.h | 5 +++++ 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/v3color.h b/indra/llmath/v3color.h index c3c6ae2242..7d825b2b94 100644 --- a/indra/llmath/v3color.h +++ b/indra/llmath/v3color.h @@ -498,9 +498,4 @@ inline const LLColor3 linearColor3(const T& a) { return linearColor3(a.mV); } -template -inline const LLVector3 linearColor3v(const T& a) { - return LLVector3(linearColor3(a.mV).mV); -} - #endif diff --git a/indra/llmath/v3math.h b/indra/llmath/v3math.h index 068f489020..48c5c21863 100644 --- a/indra/llmath/v3math.h +++ b/indra/llmath/v3math.h @@ -609,4 +609,9 @@ inline std::ostream& operator<<(std::ostream& s, const LLVector3 &a) return s; } +template +inline const LLVector3 linearColor3v(const T& a) { + return LLVector3(linearColor3(a.mV).mV); +} + #endif -- cgit v1.3 From f2867c71dba95b21771dc1f6edacaed6755ab6da Mon Sep 17 00:00:00 2001 From: Brad Kittenbrink Date: Thu, 29 Sep 2022 13:58:05 -0700 Subject: Better fix for DRTVWR-559 mac build breakage --- indra/llmath/v3color.h | 6 ++++++ indra/llmath/v3math.h | 5 ----- 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/v3color.h b/indra/llmath/v3color.h index 7d825b2b94..60353bea6e 100644 --- a/indra/llmath/v3color.h +++ b/indra/llmath/v3color.h @@ -33,6 +33,7 @@ class LLVector4; #include "llerror.h" #include "llmath.h" #include "llsd.h" +#include "v3math.h" // needed for linearColor3v implemtation below #include // LLColor3 = |r g b| @@ -498,4 +499,9 @@ inline const LLColor3 linearColor3(const T& a) { return linearColor3(a.mV); } +template +inline const LLVector3 linearColor3v(const T& a) { + return LLVector3(linearColor3(a.mV).mV); +} + #endif diff --git a/indra/llmath/v3math.h b/indra/llmath/v3math.h index 48c5c21863..068f489020 100644 --- a/indra/llmath/v3math.h +++ b/indra/llmath/v3math.h @@ -609,9 +609,4 @@ inline std::ostream& operator<<(std::ostream& s, const LLVector3 &a) return s; } -template -inline const LLVector3 linearColor3v(const T& a) { - return LLVector3(linearColor3(a.mV).mV); -} - #endif -- cgit v1.3 From 598c953d540090caa8a9a12581a4ab8ae52615dd Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 12 Oct 2022 18:49:18 -0500 Subject: SL-18190 Fix for assert on 360 snapshot and ? fix for mac build ? --- indra/llmath/v3color.h | 6 +++--- indra/newview/llsettingsvo.cpp | 2 +- indra/newview/llviewerwindow.cpp | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/v3color.h b/indra/llmath/v3color.h index 60353bea6e..0b3b4ea3e1 100644 --- a/indra/llmath/v3color.h +++ b/indra/llmath/v3color.h @@ -485,7 +485,7 @@ inline const LLColor3 srgbColor3(const LLColor3 &a) { return srgbColor; } -inline const LLColor3 linearColor3(const F32* v) { +inline const LLColor3 linearColor3p(const F32* v) { LLColor3 linearColor; linearColor.mV[0] = sRGBtoLinear(v[0]); linearColor.mV[1] = sRGBtoLinear(v[1]); @@ -496,12 +496,12 @@ inline const LLColor3 linearColor3(const F32* v) { template inline const LLColor3 linearColor3(const T& a) { - return linearColor3(a.mV); + return linearColor3p(a.mV); } template inline const LLVector3 linearColor3v(const T& a) { - return LLVector3(linearColor3(a.mV).mV); + return LLVector3(linearColor3p(a.mV).mV); } #endif diff --git a/indra/newview/llsettingsvo.cpp b/indra/newview/llsettingsvo.cpp index ddd9c56841..f9b7c749b3 100644 --- a/indra/newview/llsettingsvo.cpp +++ b/indra/newview/llsettingsvo.cpp @@ -968,7 +968,7 @@ void LLSettingsVOWater::applySpecial(void *ptarget, bool force) LLColor4 fog_color(env.getCurrentWater()->getWaterFogColor()); shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, fog_color.mV); - shader->uniform3fv(LLShaderMgr::WATER_FOGCOLOR_LINEAR, linearColor3(fog_color.mV).mV); + shader->uniform3fv(LLShaderMgr::WATER_FOGCOLOR_LINEAR, linearColor3(fog_color).mV); F32 blend_factor = env.getCurrentWater()->getBlendFactor(); shader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 8ef65b665d..5c5a5ba0d1 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -5162,7 +5162,7 @@ BOOL LLViewerWindow::simpleSnapshot(LLImageRaw* raw, S32 image_width, S32 image_ LLRenderTarget scratch_space; U32 color_fmt = GL_RGBA; const bool use_depth_buffer = true; - const bool use_stencil_buffer = true; + const bool use_stencil_buffer = false; if (scratch_space.allocate(image_width, image_height, color_fmt, use_depth_buffer, use_stencil_buffer)) { if (gPipeline.allocateScreenBuffer(image_width, image_height)) -- cgit v1.3 From f6762c3de57434730a2cbf6d0241bf1db5c9346c Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 14 Oct 2022 17:35:48 -0500 Subject: SL-18105 Add to/from json capability to LLGLTFMaterial --- indra/llmath/v3color.h | 32 ++++++ indra/llmath/v4color.h | 29 +++++ indra/llprimitive/CMakeLists.txt | 1 + indra/llprimitive/llgltfmaterial.cpp | 199 +++++++++++++++++++++++++++++++++ indra/llprimitive/llgltfmaterial.h | 34 +++++- indra/newview/llgltfmateriallist.cpp | 13 +-- indra/newview/lllocalgltfmaterials.cpp | 2 +- indra/newview/lltinygltfhelper.cpp | 65 ----------- indra/newview/lltinygltfhelper.h | 1 - 9 files changed, 293 insertions(+), 83 deletions(-) create mode 100644 indra/llprimitive/llgltfmaterial.cpp (limited to 'indra/llmath') diff --git a/indra/llmath/v3color.h b/indra/llmath/v3color.h index 0b3b4ea3e1..d925f56e97 100644 --- a/indra/llmath/v3color.h +++ b/indra/llmath/v3color.h @@ -88,6 +88,16 @@ public: const LLColor3& set(F32 x, F32 y, F32 z); // Sets LLColor3 to (x, y, z) const LLColor3& set(const LLColor3 &vec); // Sets LLColor3 to vec const LLColor3& set(const F32 *vec); // Sets LLColor3 to vec + + // set from a vector of unknown type and size + // may leave some data unmodified + template + const LLColor3& set(const std::vector& v); + + // write to a vector of unknown type and size + // maye leave some data unmodified + template + void write(std::vector& v) const; F32 magVec() const; // deprecated F32 magVecSquared() const; // deprecated @@ -504,4 +514,26 @@ inline const LLVector3 linearColor3v(const T& a) { return LLVector3(linearColor3p(a.mV).mV); } +template +const LLColor3& LLColor3::set(const std::vector& v) +{ + for (S32 i = 0; i < llmin((S32)v.size(), 3); ++i) + { + mV[i] = v[i]; + } + + return *this; +} + +// write to a vector of unknown type and size +// maye leave some data unmodified +template +void LLColor3::write(std::vector& v) const +{ + for (int i = 0; i < llmin((S32)v.size(), 3); ++i) + { + v[i] = mV[i]; + } +} + #endif diff --git a/indra/llmath/v4color.h b/indra/llmath/v4color.h index f2863be531..daa61594fb 100644 --- a/indra/llmath/v4color.h +++ b/indra/llmath/v4color.h @@ -91,6 +91,15 @@ class LLColor4 const LLColor4& set(const F64 *vec); // Sets LLColor4 to (double)vec const LLColor4& set(const LLColor4U& color4u); // Sets LLColor4 to color4u, rescaled. + // set from a vector of unknown type and size + // may leave some data unmodified + template + const LLColor4& set(const std::vector& v); + + // write to a vector of unknown type and size + // maye leave some data unmodified + template + void write(std::vector& v) const; const LLColor4& setAlpha(F32 a); @@ -690,5 +699,25 @@ inline const LLColor4 linearColor4(const LLColor4 &a) return linearColor; } +template +const LLColor4& LLColor4::set(const std::vector& v) +{ + for (S32 i = 0; i < llmin((S32)v.size(), 4); ++i) + { + mV[i] = v[i]; + } + + return *this; +} + +template +void LLColor4::write(std::vector& v) const +{ + for (int i = 0; i < llmin((S32)v.size(), 4); ++i) + { + v[i] = mV[i]; + } +} + #endif diff --git a/indra/llprimitive/CMakeLists.txt b/indra/llprimitive/CMakeLists.txt index bb14bb9242..328b22f900 100644 --- a/indra/llprimitive/CMakeLists.txt +++ b/indra/llprimitive/CMakeLists.txt @@ -33,6 +33,7 @@ include_directories(SYSTEM set(llprimitive_SOURCE_FILES lldaeloader.cpp llgltfloader.cpp + llgltfmaterial.cpp llmaterialid.cpp llmaterial.cpp llmaterialtable.cpp diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp new file mode 100644 index 0000000000..369a1786a3 --- /dev/null +++ b/indra/llprimitive/llgltfmaterial.cpp @@ -0,0 +1,199 @@ +/** + * @file llgltfmaterial.cpp + * @brief Material definition + * + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2022, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "llgltfmaterial.h" + +#include "tiny_gltf.h" + +bool LLGLTFMaterial::fromJSON(const std::string& json, std::string& warn_msg, std::string& error_msg) +{ + tinygltf::TinyGLTF gltf; + + tinygltf::Model model_in; + + if (gltf.LoadASCIIFromString(&model_in, &error_msg, &warn_msg, json.c_str(), json.length(), "")) + { + setFromModel(model_in, 0); + + //DEBUG generate json and print + LL_INFOS() << asJSON(true) << LL_ENDL; + + return true; + } + + return false; +} + +std::string LLGLTFMaterial::asJSON(bool prettyprint) const +{ + tinygltf::TinyGLTF gltf; + tinygltf::Model model_out; + + std::ostringstream str; + + writeToModel(model_out, 0); + + gltf.WriteGltfSceneToStream(&model_out, str, prettyprint, false); + + return str.str(); +} + +void LLGLTFMaterial::setFromModel(const tinygltf::Model& model, S32 mat_index) +{ + if (model.materials.size() <= mat_index) + { + return; + } + + const tinygltf::Material& material_in = model.materials[mat_index]; + + // get base color texture + S32 tex_index = material_in.pbrMetallicRoughness.baseColorTexture.index; + if (tex_index >= 0) + { + mBaseColorId.set(model.images[tex_index].uri); + } + else + { + mBaseColorId.setNull(); + } + + // get normal map + tex_index = material_in.normalTexture.index; + if (tex_index >= 0) + { + mNormalId.set(model.images[tex_index].uri); + } + else + { + mNormalId.setNull(); + } + + // get metallic-roughness texture + tex_index = material_in.pbrMetallicRoughness.metallicRoughnessTexture.index; + if (tex_index >= 0) + { + mMetallicRoughnessId.set(model.images[tex_index].uri); + } + else + { + mMetallicRoughnessId.setNull(); + } + + // get emissive texture + tex_index = material_in.emissiveTexture.index; + if (tex_index >= 0) + { + mEmissiveId.set(model.images[tex_index].uri); + } + else + { + mEmissiveId.setNull(); + } + + setAlphaMode(material_in.alphaMode); + mAlphaCutoff = llclamp((F32)material_in.alphaCutoff, 0.f, 1.f); + + mBaseColor.set(material_in.pbrMetallicRoughness.baseColorFactor); + mEmissiveColor.set(material_in.emissiveFactor); + + mMetallicFactor = llclamp((F32)material_in.pbrMetallicRoughness.metallicFactor, 0.f, 1.f); + mRoughnessFactor = llclamp((F32)material_in.pbrMetallicRoughness.roughnessFactor, 0.f, 1.f); + + mDoubleSided = material_in.doubleSided; +} + +void LLGLTFMaterial::writeToModel(tinygltf::Model& model, S32 mat_index) const +{ + if (model.materials.size() < mat_index+1) + { + model.materials.resize(mat_index + 1); + } + + tinygltf::Material& material_out = model.materials[mat_index]; + + // set base color texture + if (mBaseColorId.notNull()) + { + U32 idx = model.images.size(); + model.images.resize(idx + 1); + model.textures.resize(idx + 1); + + material_out.pbrMetallicRoughness.baseColorTexture.index = idx; + model.textures[idx].source = idx; + model.images[idx].uri = mBaseColorId.asString(); + } + + // set normal texture + if (mNormalId.notNull()) + { + U32 idx = model.images.size(); + model.images.resize(idx + 1); + model.textures.resize(idx + 1); + + material_out.normalTexture.index = idx; + model.textures[idx].source = idx; + model.images[idx].uri = mNormalId.asString(); + } + + // set metallic-roughness texture + if (mMetallicRoughnessId.notNull()) + { + U32 idx = model.images.size(); + model.images.resize(idx + 1); + model.textures.resize(idx + 1); + + material_out.pbrMetallicRoughness.metallicRoughnessTexture.index = idx; + model.textures[idx].source = idx; + model.images[idx].uri = mMetallicRoughnessId.asString(); + } + + // set emissive texture + if (mEmissiveId.notNull()) + { + U32 idx = model.images.size(); + model.images.resize(idx + 1); + model.textures.resize(idx + 1); + + material_out.emissiveTexture.index = idx; + model.textures[idx].source = idx; + model.images[idx].uri = mEmissiveId.asString(); + } + + material_out.alphaMode = getAlphaMode(); + material_out.alphaCutoff = mAlphaCutoff; + + mBaseColor.write(material_out.pbrMetallicRoughness.baseColorFactor); + mEmissiveColor.write(material_out.emissiveFactor); + + material_out.pbrMetallicRoughness.metallicFactor = mMetallicFactor; + material_out.pbrMetallicRoughness.roughnessFactor = mRoughnessFactor; + + material_out.doubleSided = mDoubleSided; +} + diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h index 36636c3b4e..8efcc9d753 100644 --- a/indra/llprimitive/llgltfmaterial.h +++ b/indra/llprimitive/llgltfmaterial.h @@ -32,6 +32,13 @@ #include "lluuid.h" #include "llmd5.h" +#include + +namespace tinygltf +{ + class Model; +} + class LLGLTFMaterial : public LLRefCount { public: @@ -48,8 +55,8 @@ public: LLUUID mMetallicRoughnessId; LLUUID mEmissiveId; - LLColor4 mBaseColor = LLColor4(1,1,1,1); - LLColor3 mEmissiveColor = LLColor3(0,0,0); + LLColor4 mBaseColor = LLColor4(1, 1, 1, 1); + LLColor3 mEmissiveColor = LLColor3(0, 0, 0); F32 mMetallicFactor = 0.f; F32 mRoughnessFactor = 0.f; @@ -63,7 +70,7 @@ public: { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; LLMD5 md5; - md5.update((unsigned char*) this, sizeof(this)); + md5.update((unsigned char*)this, sizeof(this)); md5.finalize(); LLUUID id; md5.raw_digest(id.mData); @@ -88,7 +95,7 @@ public: } } - const char* getAlphaMode() + const char* getAlphaMode() const { switch (mAlphaMode) { @@ -97,7 +104,24 @@ public: default: return "OPAQUE"; } } -}; + // set the contents of this LLGLTFMaterial from the given json + // returns true if successful + // json - the json text to load from + // warn_msg - warning message from TinyGLTF if any + // error_msg - error_msg from TinyGLTF if any + bool fromJSON(const std::string& json, std::string& warn_msg, std::string& error_msg); + // get the contents of this LLGLTFMaterial as a json string + std::string asJSON(bool prettyprint = false) const; + + // initialize from given tinygltf::Model + // model - the model to reference + // mat_index - index of material in model's material array + void setFromModel(const tinygltf::Model& model, S32 mat_index); + + // write to given tinygltf::Model + void writeToModel(tinygltf::Model& model, S32 mat_index) const; + +}; diff --git a/indra/newview/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp index 5cbf853179..a5d2be2d4e 100644 --- a/indra/newview/llgltfmateriallist.cpp +++ b/indra/newview/llgltfmateriallist.cpp @@ -83,18 +83,9 @@ LLGLTFMaterial* LLGLTFMaterialList::getMaterial(const LLUUID& id) { std::string data = asset["data"]; - tinygltf::TinyGLTF gltf; - tinygltf::TinyGLTF loader; - std::string error_msg; - std::string warn_msg; + std::string warn_msg, error_msg; - tinygltf::Model model_in; - - if (loader.LoadASCIIFromString(&model_in, &error_msg, &warn_msg, data.c_str(), data.length(), "")) - { - LLTinyGLTFHelper::setFromModel(mat, model_in, 0); - } - else + if (!mat->fromJSON(data, warn_msg, error_msg)) { LL_WARNS() << "Failed to decode material asset: " << LL_ENDL; LL_WARNS() << warn_msg << LL_ENDL; diff --git a/indra/newview/lllocalgltfmaterials.cpp b/indra/newview/lllocalgltfmaterials.cpp index 1f16549a47..fe2b7ac816 100644 --- a/indra/newview/lllocalgltfmaterials.cpp +++ b/indra/newview/lllocalgltfmaterials.cpp @@ -270,7 +270,7 @@ bool LLLocalGLTFMaterial::loadMaterial(LLPointer mat, S32 index) } // sets everything, but textures will have inaccurate ids - LLTinyGLTFHelper::setFromModel(mat, model_in, index); + mat->setFromModel(model_in, index); std::string folder = gDirUtilp->getDirName(filename_lc); tinygltf::Material material_in = model_in.materials[index]; diff --git a/indra/newview/lltinygltfhelper.cpp b/indra/newview/lltinygltfhelper.cpp index c3dc10c2a0..c80e87652a 100644 --- a/indra/newview/lltinygltfhelper.cpp +++ b/indra/newview/lltinygltfhelper.cpp @@ -122,71 +122,6 @@ void LLTinyGLTFHelper::initFetchedTextures(tinygltf::Material& material, } } -void LLTinyGLTFHelper::setFromModel(LLGLTFMaterial* mat, tinygltf::Model& model, S32 mat_index) -{ - if (model.materials.size() <= mat_index) - { - return; - } - - tinygltf::Material& material_in = model.materials[mat_index]; - - // get base color texture - S32 tex_index = material_in.pbrMetallicRoughness.baseColorTexture.index; - if (tex_index >= 0) - { - mat->mBaseColorId.set(model.images[tex_index].uri); - } - else - { - mat->mBaseColorId.setNull(); - } - - // get normal map - tex_index = material_in.normalTexture.index; - if (tex_index >= 0) - { - mat->mNormalId.set(model.images[tex_index].uri); - } - else - { - mat->mNormalId.setNull(); - } - - // get metallic-roughness texture - tex_index = material_in.pbrMetallicRoughness.metallicRoughnessTexture.index; - if (tex_index >= 0) - { - mat->mMetallicRoughnessId.set(model.images[tex_index].uri); - } - else - { - mat->mMetallicRoughnessId.setNull(); - } - - // get emissive texture - tex_index = material_in.emissiveTexture.index; - if (tex_index >= 0) - { - mat->mEmissiveId.set(model.images[tex_index].uri); - } - else - { - mat->mEmissiveId.setNull(); - } - - mat->setAlphaMode(material_in.alphaMode); - mat->mAlphaCutoff = llclamp((F32)material_in.alphaCutoff, 0.f, 1.f); - - mat->mBaseColor= getColor(material_in.pbrMetallicRoughness.baseColorFactor); - mat->mEmissiveColor = getColor(material_in.emissiveFactor); - - mat->mMetallicFactor = llclamp((F32)material_in.pbrMetallicRoughness.metallicFactor, 0.f, 1.f); - mat->mRoughnessFactor = llclamp((F32)material_in.pbrMetallicRoughness.roughnessFactor, 0.f, 1.f); - - mat->mDoubleSided = material_in.doubleSided; -} - LLColor4 LLTinyGLTFHelper::getColor(const std::vector& in) { LLColor4 out; diff --git a/indra/newview/lltinygltfhelper.h b/indra/newview/lltinygltfhelper.h index afe4517417..9c2e5afc17 100644 --- a/indra/newview/lltinygltfhelper.h +++ b/indra/newview/lltinygltfhelper.h @@ -35,7 +35,6 @@ class LLViewerFetchedTexture; namespace LLTinyGLTFHelper { - void setFromModel(LLGLTFMaterial* mat, tinygltf::Model& model, S32 index); LLColor4 getColor(const std::vector& in); const tinygltf::Image* getImageFromTextureIndex(const tinygltf::Model& model, S32 texture_index); LLImageRaw* getTexture(const std::string& folder, const tinygltf::Model& model, S32 texture_index, std::string& name); -- cgit v1.3 From 3377b19de43dfe0922174240a7844ba8f82eba23 Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Mon, 6 Mar 2023 10:15:38 -0500 Subject: Fix double copy of tangents array (#107) --- indra/llmath/llvolume.cpp | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 9919af5368..7a694ab10c 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -4863,17 +4863,6 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src) mTangents = NULL; } - if (src.mTangents) - { - allocateTangents(src.mNumVertices); - LLVector4a::memcpyNonAliased16((F32*)mTangents, (F32*)src.mTangents, vert_size); - } - else - { - ll_aligned_free_16(mTangents); - mTangents = nullptr; - } - if (src.mWeights) { llassert(!mWeights); // don't orphan an old alloc here accidentally -- cgit v1.3 From 5882215a6d53f5a20779be78805392f4e38c3669 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 24 Mar 2023 14:33:41 -0500 Subject: SL-19321 Optimization pass -- Remove another shadow split from probe render, incidental decruft. --- indra/llmath/llcamera.cpp | 222 -------------------------------- indra/llmath/llcamera.h | 9 -- indra/newview/app_settings/settings.xml | 46 ------- indra/newview/pipeline.cpp | 39 ++---- indra/newview/pipeline.h | 3 - 5 files changed, 10 insertions(+), 309 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llcamera.cpp b/indra/llmath/llcamera.cpp index 9034182072..18d704dd0f 100644 --- a/indra/llmath/llcamera.cpp +++ b/indra/llmath/llcamera.cpp @@ -311,104 +311,6 @@ int LLCamera::sphereInFrustumQuick(const LLVector3 &sphere_center, const F32 rad return 0; } -// HACK: This version is still around because the version below doesn't work -// unless the agent planes are initialized. -// Return 1 if sphere is in frustum, 2 if fully in frustum, otherwise 0. -// NOTE: 'center' is in absolute frame. -int LLCamera::sphereInFrustumOld(const LLVector3 &sphere_center, const F32 radius) const -{ - // Returns 1 if sphere is in frustum, 0 if not. - // modified so that default view frust is along X with Z vertical - F32 x, y, z, rightDist, leftDist, topDist, bottomDist; - - // Subtract the view position - //LLVector3 relative_center; - //relative_center = sphere_center - getOrigin(); - LLVector3 rel_center(sphere_center); - rel_center -= mOrigin; - - bool all_in = TRUE; - - // Transform relative_center.x to camera frame - x = mXAxis * rel_center; - if (x < MIN_NEAR_PLANE - radius) - { - return 0; - } - else if (x < MIN_NEAR_PLANE + radius) - { - all_in = FALSE; - } - - if (x > mFarPlane + radius) - { - return 0; - } - else if (x > mFarPlane - radius) - { - all_in = FALSE; - } - - // Transform relative_center.y to camera frame - y = mYAxis * rel_center; - - // distance to plane is the dot product of (x, y, 0) * plane_normal - rightDist = x * mLocalPlanes[PLANE_RIGHT][VX] + y * mLocalPlanes[PLANE_RIGHT][VY]; - if (rightDist < -radius) - { - return 0; - } - else if (rightDist < radius) - { - all_in = FALSE; - } - - leftDist = x * mLocalPlanes[PLANE_LEFT][VX] + y * mLocalPlanes[PLANE_LEFT][VY]; - if (leftDist < -radius) - { - return 0; - } - else if (leftDist < radius) - { - all_in = FALSE; - } - - // Transform relative_center.y to camera frame - z = mZAxis * rel_center; - - topDist = x * mLocalPlanes[PLANE_TOP][VX] + z * mLocalPlanes[PLANE_TOP][VZ]; - if (topDist < -radius) - { - return 0; - } - else if (topDist < radius) - { - all_in = FALSE; - } - - bottomDist = x * mLocalPlanes[PLANE_BOTTOM][VX] + z * mLocalPlanes[PLANE_BOTTOM][VZ]; - if (bottomDist < -radius) - { - return 0; - } - else if (bottomDist < radius) - { - all_in = FALSE; - } - - if (all_in) - { - return 2; - } - - return 1; -} - - -// HACK: This (presumably faster) version only currently works if you set up the -// frustum planes using GL. At some point we should get those planes through another -// mechanism, and then we can get rid of the "old" version above. - // Return 1 if sphere is in frustum, 2 if fully in frustum, otherwise 0. // NOTE: 'center' is in absolute frame. int LLCamera::sphereInFrustum(const LLVector3 &sphere_center, const F32 radius) const @@ -463,65 +365,6 @@ F32 LLCamera::heightInPixels(const LLVector3 ¢er, F32 radius ) const } } -// If pos is visible, return the distance from pos to the camera. -// Use fudge distance to scale rad against top/bot/left/right planes -// Otherwise, return -distance -F32 LLCamera::visibleDistance(const LLVector3 &pos, F32 rad, F32 fudgedist, U32 planemask) const -{ - if (mFixedDistance > 0) - { - return mFixedDistance; - } - LLVector3 dvec = pos - mOrigin; - // Check visibility - F32 dist = dvec.magVec(); - if (dist > rad) - { - F32 dp,tdist; - dp = dvec * mXAxis; - if (dp < -rad) - return -dist; - - rad *= fudgedist; - LLVector3 tvec(pos); - for (int p=0; p rad) - return -dist; - } - } - return dist; -} - -// Like visibleDistance, except uses mHorizPlanes[], which are left and right -// planes perpindicular to (0,0,1) in world space -F32 LLCamera::visibleHorizDistance(const LLVector3 &pos, F32 rad, F32 fudgedist, U32 planemask) const -{ - if (mFixedDistance > 0) - { - return mFixedDistance; - } - LLVector3 dvec = pos - mOrigin; - // Check visibility - F32 dist = dvec.magVec(); - if (dist > rad) - { - rad *= fudgedist; - LLVector3 tvec(pos); - for (int p=0; p rad) - return -dist; - } - } - return dist; -} // ---------------- friends and operators ---------------- @@ -536,18 +379,6 @@ std::ostream& operator<<(std::ostream &s, const LLCamera &C) s << " Aspect = " << C.getAspect() << "\n"; s << " NearPlane = " << C.mNearPlane << "\n"; s << " FarPlane = " << C.mFarPlane << "\n"; - s << " TopPlane = " << C.mLocalPlanes[LLCamera::PLANE_TOP][VX] << " " - << C.mLocalPlanes[LLCamera::PLANE_TOP][VY] << " " - << C.mLocalPlanes[LLCamera::PLANE_TOP][VZ] << "\n"; - s << " BottomPlane = " << C.mLocalPlanes[LLCamera::PLANE_BOTTOM][VX] << " " - << C.mLocalPlanes[LLCamera::PLANE_BOTTOM][VY] << " " - << C.mLocalPlanes[LLCamera::PLANE_BOTTOM][VZ] << "\n"; - s << " LeftPlane = " << C.mLocalPlanes[LLCamera::PLANE_LEFT][VX] << " " - << C.mLocalPlanes[LLCamera::PLANE_LEFT][VY] << " " - << C.mLocalPlanes[LLCamera::PLANE_LEFT][VZ] << "\n"; - s << " RightPlane = " << C.mLocalPlanes[LLCamera::PLANE_RIGHT][VX] << " " - << C.mLocalPlanes[LLCamera::PLANE_RIGHT][VY] << " " - << C.mLocalPlanes[LLCamera::PLANE_RIGHT][VZ] << "\n"; s << "}"; return s; } @@ -675,26 +506,6 @@ void LLCamera::calcRegionFrustumPlanes(const LLVector3& shift, F32 far_clip_dist void LLCamera::calculateFrustumPlanes(F32 left, F32 right, F32 top, F32 bottom) { - LLVector3 a, b, c; - - // For each plane we need to define 3 points (LLVector3's) in camera view space. - // The order in which we pass the points to planeFromPoints() matters, because the - // plane normal has a degeneracy of 2; we want it pointing _into_ the frustum. - - a.setVec(0.0f, 0.0f, 0.0f); - b.setVec(mFarPlane, right, top); - c.setVec(mFarPlane, right, bottom); - mLocalPlanes[PLANE_RIGHT].setVec(a, b, c); - - c.setVec(mFarPlane, left, top); - mLocalPlanes[PLANE_TOP].setVec(a, c, b); - - b.setVec(mFarPlane, left, bottom); - mLocalPlanes[PLANE_LEFT].setVec(a, b, c); - - c.setVec(mFarPlane, right, bottom); - mLocalPlanes[PLANE_BOTTOM].setVec( a, c, b); - //calculate center and radius squared of frustum in world absolute coordinates static LLVector3 const X_AXIS(1.f, 0.f, 0.f); mFrustCenter = X_AXIS*mFarPlane*0.5f; @@ -718,39 +529,6 @@ void LLCamera::calculateFrustumPlanesFromWindow(F32 x1, F32 y1, F32 x2, F32 y2) calculateFrustumPlanes(left, right, top, bottom); } -void LLCamera::calculateWorldFrustumPlanes() -{ - F32 d; - LLVector3 center = mOrigin - mXAxis*mNearPlane; - mWorldPlanePos = center; - LLVector3 pnorm; - for (int p = 0; p < PLANE_NUM; p++) - { - mLocalPlanes[p].getVector3(pnorm); - LLVector3 norm = rotateToAbsolute(pnorm); - norm.normVec(); - d = -(center * norm); - mWorldPlanes[p] = LLPlane(norm, d); - } - // horizontal planes, perpindicular to (0,0,1); - LLVector3 zaxis(0, 0, 1.0f); - F32 yaw = getYaw(); - { - LLVector3 tnorm; - mLocalPlanes[PLANE_LEFT].getVector3(tnorm); - tnorm.rotVec(yaw, zaxis); - d = -(mOrigin * tnorm); - mHorizPlanes[HORIZ_PLANE_LEFT] = LLPlane(tnorm, d); - } - { - LLVector3 tnorm; - mLocalPlanes[PLANE_RIGHT].getVector3(tnorm); - tnorm.rotVec(yaw, zaxis); - d = -(mOrigin * tnorm); - mHorizPlanes[HORIZ_PLANE_RIGHT] = LLPlane(tnorm, d); - } -} - // NOTE: this is the OpenGL matrix that will transform the default OpenGL view // (-Z=at, Y=up) to the default view of the LLCamera class (X=at, Z=up): // diff --git a/indra/llmath/llcamera.h b/indra/llmath/llcamera.h index d0afa0e88f..27eaa614c9 100644 --- a/indra/llmath/llcamera.h +++ b/indra/llmath/llcamera.h @@ -131,14 +131,10 @@ private: S32 mViewHeightInPixels; // for ViewHeightInPixels() only F32 mNearPlane; F32 mFarPlane; - LL_ALIGN_16(LLPlane mLocalPlanes[PLANE_NUM]); F32 mFixedDistance; // Always return this distance, unless < 0 LLVector3 mFrustCenter; // center of frustum and radius squared for ultra-quick exclusion test F32 mFrustRadiusSquared; - LL_ALIGN_16(LLPlane mWorldPlanes[PLANE_NUM]); - LL_ALIGN_16(LLPlane mHorizPlanes[HORIZ_PLANE_NUM]); - U32 mPlaneCount; //defaults to 6, if setUserClipPlane is called, uses user supplied clip plane in LLVector3 mWorldPlanePos; // Position of World Planes (may be offset from camera) @@ -184,7 +180,6 @@ public: return atan2f(mXAxis[VZ], xylen); } - const LLPlane& getWorldPlane(S32 index) const { return mWorldPlanes[index]; } const LLVector3& getWorldPlanePos() const { return mWorldPlanePos; } // Copy mView, mAspect, mNearPlane, and mFarPlane to buffer. @@ -200,7 +195,6 @@ public: // Returns 1 if partly in, 2 if fully in. // NOTE: 'center' is in absolute frame. - S32 sphereInFrustumOld(const LLVector3 ¢er, const F32 radius) const; S32 sphereInFrustum(const LLVector3 ¢er, const F32 radius) const; S32 pointInFrustum(const LLVector3 &point) const { return sphereInFrustum(point, 0.0f); } S32 sphereInFrustumFull(const LLVector3 ¢er, const F32 radius) const { return sphereInFrustum(center, radius); } @@ -217,8 +211,6 @@ public: F32 heightInPixels(const LLVector3 ¢er, F32 radius ) const; // return the distance from pos to camera if visible (-distance if not visible) - F32 visibleDistance(const LLVector3 &pos, F32 rad, F32 fudgescale = 1.0f, U32 planemask = PLANE_ALL_MASK) const; - F32 visibleHorizDistance(const LLVector3 &pos, F32 rad, F32 fudgescale = 1.0f, U32 planemask = HORIZ_PLANE_ALL_MASK) const; void setFixedDistance(F32 distance) { mFixedDistance = distance; } friend std::ostream& operator<<(std::ostream &s, const LLCamera &C); @@ -227,7 +219,6 @@ protected: void calculateFrustumPlanes(); void calculateFrustumPlanes(F32 left, F32 right, F32 top, F32 bottom); void calculateFrustumPlanesFromWindow(F32 x1, F32 y1, F32 x2, F32 y2); - void calculateWorldFrustumPlanes(); } LL_ALIGN_POSTFIX(16); diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 5ade88e32b..e0662b8115 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -9002,37 +9002,6 @@ Value 1 - - RenderShadowNearDist - - Comment - Near clip plane of shadow camera (affects precision of depth shadows). - Persist - 1 - Type - Vector3 - Value - - 256 - 256 - 256 - - - RenderShadowClipPlanes - - Comment - Near clip plane split distances for shadow map frusta. - Persist - 1 - Type - Vector3 - Value - - 1.0 - 12.0 - 32.0 - - RenderShadowSplitExponent Comment @@ -9048,21 +9017,6 @@ 2.0 - RenderShadowOrthoClipPlanes - - Comment - Near clip plane split distances for orthographic shadow map frusta. - Persist - 1 - Type - Vector3 - Value - - 4.0 - 8.0 - 24.0 - - RenderShadowProjOffset Comment diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index f059c87c91..a53b3aac8e 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -202,9 +202,6 @@ LLVector3 LLPipeline::RenderShadowGaussian; F32 LLPipeline::RenderShadowBlurDistFactor; bool LLPipeline::RenderDeferredAtmospheric; F32 LLPipeline::RenderHighlightFadeTime; -LLVector3 LLPipeline::RenderShadowClipPlanes; -LLVector3 LLPipeline::RenderShadowOrthoClipPlanes; -LLVector3 LLPipeline::RenderShadowNearDist; F32 LLPipeline::RenderFarClip; LLVector3 LLPipeline::RenderShadowSplitExponent; F32 LLPipeline::RenderShadowErrorCutoff; @@ -558,9 +555,6 @@ void LLPipeline::init() connectRefreshCachedSettingsSafe("RenderShadowBlurDistFactor"); connectRefreshCachedSettingsSafe("RenderDeferredAtmospheric"); connectRefreshCachedSettingsSafe("RenderHighlightFadeTime"); - connectRefreshCachedSettingsSafe("RenderShadowClipPlanes"); - connectRefreshCachedSettingsSafe("RenderShadowOrthoClipPlanes"); - connectRefreshCachedSettingsSafe("RenderShadowNearDist"); connectRefreshCachedSettingsSafe("RenderFarClip"); connectRefreshCachedSettingsSafe("RenderShadowSplitExponent"); connectRefreshCachedSettingsSafe("RenderShadowErrorCutoff"); @@ -1043,9 +1037,6 @@ void LLPipeline::refreshCachedSettings() RenderShadowBlurDistFactor = gSavedSettings.getF32("RenderShadowBlurDistFactor"); RenderDeferredAtmospheric = gSavedSettings.getBOOL("RenderDeferredAtmospheric"); RenderHighlightFadeTime = gSavedSettings.getF32("RenderHighlightFadeTime"); - RenderShadowClipPlanes = gSavedSettings.getVector3("RenderShadowClipPlanes"); - RenderShadowOrthoClipPlanes = gSavedSettings.getVector3("RenderShadowOrthoClipPlanes"); - RenderShadowNearDist = gSavedSettings.getVector3("RenderShadowNearDist"); RenderFarClip = gSavedSettings.getF32("RenderFarClip"); RenderShadowSplitExponent = gSavedSettings.getVector3("RenderShadowSplitExponent"); RenderShadowErrorCutoff = gSavedSettings.getF32("RenderShadowErrorCutoff"); @@ -9277,27 +9268,12 @@ void LLPipeline::generateSunShadow(LLCamera& camera) glh::matrix4f view[6]; glh::matrix4f proj[6]; - //clip contains parallel split distances for 3 splits - LLVector3 clip = RenderShadowClipPlanes; - LLVector3 caster_dir(environment.getIsSunUp() ? mSunDir : mMoonDir); - //F32 slope_threshold = gSavedSettings.getF32("RenderShadowSlopeThreshold"); - - //far clip on last split is minimum of camera view distance and 128 - mSunClipPlanes = LLVector4(clip, clip.mV[2] * clip.mV[2]/clip.mV[1]); - - clip = RenderShadowOrthoClipPlanes; - mSunOrthoClipPlanes = LLVector4(clip, clip.mV[2]*clip.mV[2]/clip.mV[1]); - - //currently used for amount to extrude frusta corners for constructing shadow frusta - //LLVector3 n = RenderShadowNearDist; - //F32 nearDist[] = { n.mV[0], n.mV[1], n.mV[2], n.mV[2] }; - //put together a universal "near clip" plane for shadow frusta LLPlane shadow_near_clip; { - LLVector3 p = gAgent.getPositionAgent(); + LLVector3 p = camera.getOrigin(); // gAgent.getPositionAgent(); p += caster_dir * RenderFarClip*2.f; shadow_near_clip.setVec(p, caster_dir); } @@ -9318,9 +9294,6 @@ void LLPipeline::generateSunShadow(LLCamera& camera) up = camera.getUpAxis(); } - /*LLVector3 left = up%at; - up = at%left;*/ - up.normVec(); at.normVec(); @@ -9403,6 +9376,14 @@ void LLPipeline::generateSunShadow(LLCamera& camera) mSunClipPlanes.mV[0] *= 1.25f; //bump back first split for transition padding } + if (gCubeSnapshot) + { // stretch clip planes for reflection probe renders to reduce number of shadow passes + mSunClipPlanes.mV[1] = mSunClipPlanes.mV[2]; + mSunClipPlanes.mV[2] = mSunClipPlanes.mV[3]; + mSunClipPlanes.mV[3] *= 1.5f; + } + + // convenience array of 4 near clip plane distances F32 dist[] = { near_clip, mSunClipPlanes.mV[0], mSunClipPlanes.mV[1], mSunClipPlanes.mV[2], mSunClipPlanes.mV[3] }; @@ -9419,7 +9400,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera) } else { - for (S32 j = 0; j < (gCubeSnapshot ? 3 : 4); j++) + for (S32 j = 0; j < (gCubeSnapshot ? 2 : 4); j++) { if (!hasRenderDebugMask(RENDER_DEBUG_SHADOW_FRUSTA) && !gCubeSnapshot) { diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 0faa0c3f20..4cefb719fd 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -999,9 +999,6 @@ public: static F32 RenderShadowBlurDistFactor; static bool RenderDeferredAtmospheric; static F32 RenderHighlightFadeTime; - static LLVector3 RenderShadowClipPlanes; - static LLVector3 RenderShadowOrthoClipPlanes; - static LLVector3 RenderShadowNearDist; static F32 RenderFarClip; static LLVector3 RenderShadowSplitExponent; static F32 RenderShadowErrorCutoff; -- cgit v1.3 From 6c5b9076704865e96adb5b4a25a518633da1174e Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Thu, 13 Apr 2023 19:41:11 -0500 Subject: SL-19358 Fix for explody meshes. --- indra/llmath/llvolume.cpp | 51 +++++++++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 22 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 7a694ab10c..2a906c8d41 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -5574,37 +5574,44 @@ bool LLVolumeFace::cacheOptimize(bool gen_tangents) U32 vert_count = meshopt_generateVertexRemapMulti(&remap[0], nullptr, data.p.size(), data.p.size(), mos, stream_count); - std::vector indices; - indices.resize(mNumIndices); + if (vert_count < 65535) + { + std::vector indices; + indices.resize(mNumIndices); - //copy results back into volume - resizeVertices(vert_count); + //copy results back into volume + resizeVertices(vert_count); - if (!data.w.empty()) - { - allocateWeights(vert_count); - } + if (!data.w.empty()) + { + allocateWeights(vert_count); + } - allocateTangents(mNumVertices); + allocateTangents(mNumVertices); - for (int i = 0; i < mNumIndices; ++i) - { - U32 src_idx = i; - U32 dst_idx = remap[i]; - mIndices[i] = dst_idx; + for (int i = 0; i < mNumIndices; ++i) + { + U32 src_idx = i; + U32 dst_idx = remap[i]; + mIndices[i] = dst_idx; - mPositions[dst_idx].load3(data.p[src_idx].mV); - mNormals[dst_idx].load3(data.n[src_idx].mV); - mTexCoords[dst_idx] = data.tc[src_idx]; + mPositions[dst_idx].load3(data.p[src_idx].mV); + mNormals[dst_idx].load3(data.n[src_idx].mV); + mTexCoords[dst_idx] = data.tc[src_idx]; - mTangents[dst_idx].loadua(data.t[src_idx].mV); + mTangents[dst_idx].loadua(data.t[src_idx].mV); - if (mWeights) - { - mWeights[dst_idx].loadua(data.w[src_idx].mV); + if (mWeights) + { + mWeights[dst_idx].loadua(data.w[src_idx].mV); + } } } - + else + { + // blew past the max vertex size limit, use legacy tangent generation which never adds verts + createTangents(); + } // put back in normalized coordinate frame LLVector4a inv_scale(1.f/mNormalizedScale.mV[0], 1.f / mNormalizedScale.mV[1], 1.f / mNormalizedScale.mV[2]); -- cgit v1.3 From 1cadfd44fe5ddafaf3ba3560bd8ec8e1351b347d Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Wed, 3 May 2023 17:30:02 -0500 Subject: DRTVWR-559 WIP - optimize ARC calculation et al. --- indra/llcommon/llmutex.h | 5 +- indra/llmath/llvolume.cpp | 5 +- indra/newview/llmeshrepository.cpp | 141 +++++++++--------- indra/newview/llmeshrepository.h | 71 ++++++++- indra/newview/llselectmgr.cpp | 4 +- indra/newview/llspatialpartition.cpp | 115 -------------- indra/newview/llviewerobject.cpp | 9 +- indra/newview/llviewerobject.h | 2 +- indra/newview/llvoavatar.cpp | 280 +++++++++++++++-------------------- indra/newview/llvovolume.cpp | 275 +++++++++++++++++++--------------- indra/newview/llvovolume.h | 26 +++- indra/newview/pipeline.h | 1 - 12 files changed, 445 insertions(+), 489 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llcommon/llmutex.h b/indra/llcommon/llmutex.h index 838d7d34c0..0d70da6178 100644 --- a/indra/llcommon/llmutex.h +++ b/indra/llcommon/llmutex.h @@ -36,7 +36,8 @@ //============================================================================ -#define MUTEX_DEBUG (LL_DEBUG || LL_RELEASE_WITH_DEBUG_INFO) +//#define MUTEX_DEBUG (LL_DEBUG || LL_RELEASE_WITH_DEBUG_INFO) +#define MUTEX_DEBUG 0 //disable mutex debugging as it's interfering with profiles #if MUTEX_DEBUG #include @@ -61,7 +62,7 @@ protected: mutable LLThread::id_t mLockingThread; #if MUTEX_DEBUG - std::map mIsLocked; + std::unordered_map mIsLocked; #endif }; diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 2a906c8d41..b6cdcb2736 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -3351,12 +3351,12 @@ BOOL LLVolume::isFlat(S32 face) bool LLVolumeParams::isSculpt() const { - return mSculptID.notNull(); + return (mSculptType & LL_SCULPT_TYPE_MASK) != LL_SCULPT_TYPE_NONE; } bool LLVolumeParams::isMeshSculpt() const { - return isSculpt() && ((mSculptType & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH); + return (mSculptType & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH; } bool LLVolumeParams::operator==(const LLVolumeParams ¶ms) const @@ -3771,6 +3771,7 @@ bool LLVolumeParams::validate(U8 prof_curve, F32 prof_begin, F32 prof_end, F32 h void LLVolume::getLoDTriangleCounts(const LLVolumeParams& params, S32* counts) { //attempt to approximate the number of triangles that will result from generating a volume LoD set for the //supplied LLVolumeParams -- inaccurate, but a close enough approximation for determining streaming cost + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; F32 detail[] = {1.f, 1.5f, 2.5f, 4.f}; for (S32 i = 0; i < 4; i++) { diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index d301e14e10..67bf6827ad 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -1342,10 +1342,11 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id, bool can_retry) if (header_size > 0) { - const LLSD& header = header_it->second.second; - S32 version = header["version"].asInteger(); - S32 offset = header_size + header["skin"]["offset"].asInteger(); - S32 size = header["skin"]["size"].asInteger(); + const LLMeshHeader& header = header_it->second.second; + + S32 version = header.mVersion; + S32 offset = header_size + header.mSkinOffset; + S32 size = header.mSkinSize; mHeaderMutex->unlock(); @@ -1456,9 +1457,9 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id) if (header_size > 0) { const auto& header = header_it->second.second; - S32 version = header["version"].asInteger(); - S32 offset = header_size + header["physics_convex"]["offset"].asInteger(); - S32 size = header["physics_convex"]["size"].asInteger(); + S32 version = header.mVersion; + S32 offset = header_size + header.mPhysicsConvexOffset; + S32 size = header.mPhysicsConvexSize; mHeaderMutex->unlock(); @@ -1555,9 +1556,9 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id) if (header_size > 0) { const auto& header = header_it->second.second; - S32 version = header["version"].asInteger(); - S32 offset = header_size + header["physics_mesh"]["offset"].asInteger(); - S32 size = header["physics_mesh"]["size"].asInteger(); + S32 version = header.mVersion; + S32 offset = header_size + header.mPhysicsMeshOffset; + S32 size = header.mPhysicsMeshSize; mHeaderMutex->unlock(); @@ -1753,9 +1754,9 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, if (header_size > 0) { const auto& header = header_it->second.second; - S32 version = header["version"].asInteger(); - S32 offset = header_size + header[header_lod[lod]]["offset"].asInteger(); - S32 size = header[header_lod[lod]]["size"].asInteger(); + S32 version = header.mVersion; + S32 offset = header_size + header.mLodOffset[lod]; + S32 size = header.mLodSize[lod]; mHeaderMutex->unlock(); if (version <= MAX_MESH_VERSION && offset >= 0 && size > 0) @@ -1857,8 +1858,10 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, EMeshProcessingResult LLMeshRepoThread::headerReceived(const LLVolumeParams& mesh_params, U8* data, S32 data_size) { const LLUUID mesh_id = mesh_params.getSculptID(); - LLSD header; + LLSD header_data; + LLMeshHeader header; + U32 header_size = 0; if (data_size > 0) { @@ -1869,23 +1872,25 @@ EMeshProcessingResult LLMeshRepoThread::headerReceived(const LLVolumeParams& mes boost::iostreams::stream stream(result_ptr, data_size); - if (!LLSDSerialize::fromBinary(header, stream, data_size)) + if (!LLSDSerialize::fromBinary(header_data, stream, data_size)) { LL_WARNS(LOG_MESH) << "Mesh header parse error. Not a valid mesh asset! ID: " << mesh_id << LL_ENDL; return MESH_PARSE_FAILURE; } - if (!header.isMap()) + if (!header_data.isMap()) { LL_WARNS(LOG_MESH) << "Mesh header is invalid for ID: " << mesh_id << LL_ENDL; return MESH_INVALID; } - if (header.has("version") && header["version"].asInteger() > MAX_MESH_VERSION) + header.fromLLSD(header_data); + + if (header.mVersion > MAX_MESH_VERSION) { LL_INFOS(LOG_MESH) << "Wrong version in header for " << mesh_id << LL_ENDL; - header["404"] = 1; + header.m404 = true; } // make sure there is at least one lod, function returns -1 and marks as 404 otherwise else if (LLMeshRepository::getActualMeshLOD(header, 0) >= 0) @@ -1897,7 +1902,7 @@ EMeshProcessingResult LLMeshRepoThread::headerReceived(const LLVolumeParams& mes { LL_INFOS(LOG_MESH) << "Non-positive data size. Marking header as non-existent, will not retry. ID: " << mesh_id << LL_ENDL; - header["404"] = 1; + header.m404 = 1; } { @@ -1907,7 +1912,6 @@ EMeshProcessingResult LLMeshRepoThread::headerReceived(const LLVolumeParams& mes mMeshHeader[mesh_id] = { header_size, header }; LLMeshRepository::sCacheBytesHeaders += header_size; } - LLMutexLock lock(mMutex); // make sure only one thread access mPendingLOD at the same time. @@ -2977,7 +2981,7 @@ S32 LLMeshRepoThread::getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lo if (iter != mMeshHeader.end()) { - LLSD& header = iter->second.second; + auto& header = iter->second.second; return LLMeshRepository::getActualMeshLOD(header, lod); } @@ -2986,23 +2990,23 @@ S32 LLMeshRepoThread::getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lo } //static -S32 LLMeshRepository::getActualMeshLOD(LLSD& header, S32 lod) +S32 LLMeshRepository::getActualMeshLOD(LLMeshHeader& header, S32 lod) { lod = llclamp(lod, 0, 3); - if (header.has("404")) + if (header.m404) { return -1; } - S32 version = header["version"]; + S32 version = header.mVersion; if (version > MAX_MESH_VERSION) { return -1; } - if (header[header_lod[lod]]["size"].asInteger() > 0) + if (header.mLodSize[lod] > 0) { return lod; } @@ -3010,7 +3014,7 @@ S32 LLMeshRepository::getActualMeshLOD(LLSD& header, S32 lod) //search down to find the next available lower lod for (S32 i = lod-1; i >= 0; --i) { - if (header[header_lod[i]]["size"].asInteger() > 0) + if (header.mLodSize[i] > 0) { return i; } @@ -3019,15 +3023,16 @@ S32 LLMeshRepository::getActualMeshLOD(LLSD& header, S32 lod) //search up to find then ext available higher lod for (S32 i = lod+1; i < 4; ++i) { - if (header[header_lod[i]]["size"].asInteger() > 0) + if (header.mLodSize[i] > 0) { return i; } } //header exists and no good lod found, treat as 404 - header["404"] = 1; - return -1; + header.m404 = true; + + return -1; } // Handle failed or successful requests for mesh assets. @@ -3216,7 +3221,7 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b { // header was successfully retrieved from sim and parsed and is in cache S32 header_bytes = 0; - LLSD header; + LLMeshHeader header; gMeshRepo.mThread->mHeaderMutex->lock(); LLMeshRepoThread::mesh_header_map::iterator iter = gMeshRepo.mThread->mMeshHeader.find(mesh_id); @@ -3227,8 +3232,8 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b } if (header_bytes > 0 - && !header.has("404") - && (!header.has("version") || header["version"].asInteger() <= MAX_MESH_VERSION)) + && !header.m404 + && (header.mVersion <= MAX_MESH_VERSION)) { std::stringstream str; @@ -3237,13 +3242,12 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b for (U32 i = 0; i < LLModel::LOD_PHYSICS; ++i) { // figure out how many bytes we'll need to reserve in the file - const std::string & lod_name = header_lod[i]; - lod_bytes = llmax(lod_bytes, header[lod_name]["offset"].asInteger()+header[lod_name]["size"].asInteger()); + lod_bytes = llmax(lod_bytes, header.mLodOffset[i]+header.mLodSize[i]); } // just in case skin info or decomposition is at the end of the file (which it shouldn't be) - lod_bytes = llmax(lod_bytes, header["skin"]["offset"].asInteger() + header["skin"]["size"].asInteger()); - lod_bytes = llmax(lod_bytes, header["physics_convex"]["offset"].asInteger() + header["physics_convex"]["size"].asInteger()); + lod_bytes = llmax(lod_bytes, header.mSkinOffset+header.mSkinSize); + lod_bytes = llmax(lod_bytes, header.mPhysicsConvexOffset + header.mPhysicsConvexSize); // Do not unlock mutex untill we are done with LLSD. // LLSD is smart and can work like smart pointer, is not thread safe. @@ -4257,8 +4261,8 @@ bool LLMeshRepoThread::hasPhysicsShapeInHeader(const LLUUID& mesh_id) mesh_header_map::iterator iter = mMeshHeader.find(mesh_id); if (iter != mMeshHeader.end() && iter->second.first > 0) { - LLSD &mesh = iter->second.second; - if (mesh.has("physics_mesh") && mesh["physics_mesh"].has("size") && (mesh["physics_mesh"]["size"].asInteger() > 0)) + LLMeshHeader &mesh = iter->second.second; + if (mesh.mPhysicsMeshSize > 0) { return true; } @@ -4281,20 +4285,21 @@ void LLMeshRepository::uploadModel(std::vector& data, LLVector3 S32 LLMeshRepository::getMeshSize(const LLUUID& mesh_id, S32 lod) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; if (mThread && mesh_id.notNull() && LLPrimitive::NO_LOD != lod) { LLMutexLock lock(mThread->mHeaderMutex); LLMeshRepoThread::mesh_header_map::iterator iter = mThread->mMeshHeader.find(mesh_id); if (iter != mThread->mMeshHeader.end() && iter->second.first > 0) { - const LLSD& header = iter->second.second; + const LLMeshHeader& header = iter->second.second; - if (header.has("404")) + if (header.m404) { return -1; } - S32 size = header[header_lod[lod]]["size"].asInteger(); + S32 size = header.mLodSize[lod]; return size; } @@ -4430,11 +4435,11 @@ F32 LLMeshRepository::getStreamingCostLegacy(LLUUID mesh_id, F32 radius, S32* by // FIXME replace with calc based on LLMeshCostData //static -F32 LLMeshRepository::getStreamingCostLegacy(LLSD& header, F32 radius, S32* bytes, S32* bytes_visible, S32 lod, F32 *unscaled_value) +F32 LLMeshRepository::getStreamingCostLegacy(LLMeshHeader& header, F32 radius, S32* bytes, S32* bytes_visible, S32 lod, F32 *unscaled_value) { - if (header.has("404") - || !header.has("lowest_lod") - || (header.has("version") && header["version"].asInteger() > MAX_MESH_VERSION)) + if (header.m404 + || header.mLodSize[0] <= 0 + || (header.mVersion > MAX_MESH_VERSION)) { return 0.f; } @@ -4453,10 +4458,10 @@ F32 LLMeshRepository::getStreamingCostLegacy(LLSD& header, F32 radius, S32* byte F32 minimum_size = (F32)minimum_size_ch; F32 bytes_per_triangle = (F32)bytes_per_triangle_ch; - S32 bytes_lowest = header["lowest_lod"]["size"].asInteger(); - S32 bytes_low = header["low_lod"]["size"].asInteger(); - S32 bytes_mid = header["medium_lod"]["size"].asInteger(); - S32 bytes_high = header["high_lod"]["size"].asInteger(); + S32 bytes_lowest = header.mLodSize[0]; + S32 bytes_low = header.mLodSize[1]; + S32 bytes_mid = header.mLodSize[2]; + S32 bytes_high = header.mLodSize[3]; if (bytes_high == 0) { @@ -4486,10 +4491,10 @@ F32 LLMeshRepository::getStreamingCostLegacy(LLSD& header, F32 radius, S32* byte if (bytes) { *bytes = 0; - *bytes += header["lowest_lod"]["size"].asInteger(); - *bytes += header["low_lod"]["size"].asInteger(); - *bytes += header["medium_lod"]["size"].asInteger(); - *bytes += header["high_lod"]["size"].asInteger(); + *bytes += header.mLodSize[0]; + *bytes += header.mLodSize[1]; + *bytes += header.mLodSize[2]; + *bytes += header.mLodSize[3]; } if (bytes_visible) @@ -4497,7 +4502,7 @@ F32 LLMeshRepository::getStreamingCostLegacy(LLSD& header, F32 radius, S32* byte lod = LLMeshRepository::getActualMeshLOD(header, lod); if (lod >= 0 && lod <= 3) { - *bytes_visible = header[header_lod[lod]]["size"].asInteger(); + *bytes_visible = header.mLodSize[lod]; } } @@ -4539,34 +4544,29 @@ F32 LLMeshRepository::getStreamingCostLegacy(LLSD& header, F32 radius, S32* byte LLMeshCostData::LLMeshCostData() { - mSizeByLOD.resize(4); - mEstTrisByLOD.resize(4); - std::fill(mSizeByLOD.begin(), mSizeByLOD.end(), 0); std::fill(mEstTrisByLOD.begin(), mEstTrisByLOD.end(), 0.f); } -bool LLMeshCostData::init(const LLSD& header) +bool LLMeshCostData::init(const LLMeshHeader& header) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; - mSizeByLOD.resize(4); - mEstTrisByLOD.resize(4); - + std::fill(mSizeByLOD.begin(), mSizeByLOD.end(), 0); std::fill(mEstTrisByLOD.begin(), mEstTrisByLOD.end(), 0.f); - S32 bytes_high = header["high_lod"]["size"].asInteger(); - S32 bytes_med = header["medium_lod"]["size"].asInteger(); + S32 bytes_high = header.mLodSize[3]; + S32 bytes_med = header.mLodSize[2]; if (bytes_med == 0) { bytes_med = bytes_high; } - S32 bytes_low = header["low_lod"]["size"].asInteger(); + S32 bytes_low = header.mLodSize[1]; if (bytes_low == 0) { bytes_low = bytes_med; } - S32 bytes_lowest = header["lowest_lod"]["size"].asInteger(); + S32 bytes_lowest = header.mLodSize[0]; if (bytes_lowest == 0) { bytes_lowest = bytes_low; @@ -4701,6 +4701,7 @@ F32 LLMeshCostData::getTriangleBasedStreamingCost() bool LLMeshRepository::getCostData(LLUUID mesh_id, LLMeshCostData& data) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; data = LLMeshCostData(); if (mThread && mesh_id.notNull()) @@ -4709,11 +4710,11 @@ bool LLMeshRepository::getCostData(LLUUID mesh_id, LLMeshCostData& data) LLMeshRepoThread::mesh_header_map::iterator iter = mThread->mMeshHeader.find(mesh_id); if (iter != mThread->mMeshHeader.end() && iter->second.first > 0) { - LLSD& header = iter->second.second; + LLMeshHeader& header = iter->second.second; - bool header_invalid = (header.has("404") - || !header.has("lowest_lod") - || (header.has("version") && header["version"].asInteger() > MAX_MESH_VERSION)); + bool header_invalid = (header.m404 + || header.mLodSize[0] <= 0 + || header.mVersion > MAX_MESH_VERSION); if (!header_invalid) { return getCostData(header, data); @@ -4725,7 +4726,7 @@ bool LLMeshRepository::getCostData(LLUUID mesh_id, LLMeshCostData& data) return false; } -bool LLMeshRepository::getCostData(LLSD& header, LLMeshCostData& data) +bool LLMeshRepository::getCostData(LLMeshHeader& header, LLMeshCostData& data) { data = LLMeshCostData(); diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index 6922367ff7..619e076fa6 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -194,6 +194,63 @@ private: LLFrameTimer mTimer; }; +class LLMeshHeader +{ +public: + + LLMeshHeader() {} + + explicit LLMeshHeader(const LLSD& header) + { + fromLLSD(header); + } + + void fromLLSD(const LLSD& header) + { + const char* lod[] = + { + "lowest_lod", + "low_lod", + "medium_lod", + "high_lod" + }; + + mVersion = header["version"].asInteger(); + + for (U32 i = 0; i < 4; ++i) + { + mLodOffset[i] = header[lod[i]]["offset"].asInteger(); + mLodSize[i] = header[lod[i]]["size"].asInteger(); + } + + mSkinOffset = header["skin"]["offset"].asInteger(); + mSkinSize = header["skin"]["size"].asInteger(); + + mPhysicsConvexOffset = header["physics_convex"]["offset"].asInteger(); + mPhysicsConvexSize = header["physics_convex"]["size"].asInteger(); + + mPhysicsMeshOffset = header["physics_mesh"]["offset"].asInteger(); + mPhysicsMeshSize = header["physics_mesh"]["size"].asInteger(); + + m404 = header.has("404"); + } + + S32 mVersion = -1; + S32 mSkinOffset = -1; + S32 mSkinSize = -1; + + S32 mPhysicsConvexOffset = -1; + S32 mPhysicsConvexSize = -1; + + S32 mPhysicsMeshOffset = -1; + S32 mPhysicsMeshSize = -1; + + S32 mLodOffset[4] = { -1 }; + S32 mLodSize[4] = { -1 }; + + bool m404 = false; +}; + class LLMeshRepoThread : public LLThread { public: @@ -210,7 +267,7 @@ public: LLCondition* mSignal; //map of known mesh headers - typedef boost::unordered_map> mesh_header_map; // pair is header_size and data + typedef boost::unordered_map> mesh_header_map; // pair is header_size and data mesh_header_map mMeshHeader; class HeaderRequest : public RequestStats @@ -497,7 +554,7 @@ class LLMeshCostData public: LLMeshCostData(); - bool init(const LLSD& header); + bool init(const LLMeshHeader& header); // Size for given LOD S32 getSizeByLOD(S32 lod); @@ -532,10 +589,10 @@ public: private: // From the "size" field of the mesh header. LOD 0=lowest, 3=highest. - std::vector mSizeByLOD; + std::array mSizeByLOD; // Estimated triangle counts derived from the LOD sizes. LOD 0=lowest, 3=highest. - std::vector mEstTrisByLOD; + std::array mEstTrisByLOD; }; class LLMeshRepository @@ -566,9 +623,9 @@ public: F32 getEstTrianglesMax(LLUUID mesh_id); F32 getEstTrianglesStreamingCost(LLUUID mesh_id); F32 getStreamingCostLegacy(LLUUID mesh_id, F32 radius, S32* bytes = NULL, S32* visible_bytes = NULL, S32 detail = -1, F32 *unscaled_value = NULL); - static F32 getStreamingCostLegacy(LLSD& header, F32 radius, S32* bytes = NULL, S32* visible_bytes = NULL, S32 detail = -1, F32 *unscaled_value = NULL); + static F32 getStreamingCostLegacy(LLMeshHeader& header, F32 radius, S32* bytes = NULL, S32* visible_bytes = NULL, S32 detail = -1, F32 *unscaled_value = NULL); bool getCostData(LLUUID mesh_id, LLMeshCostData& data); - bool getCostData(LLSD& header, LLMeshCostData& data); + bool getCostData(LLMeshHeader& header, LLMeshCostData& data); LLMeshRepository(); @@ -588,7 +645,7 @@ public: void notifyDecompositionReceived(LLModel::Decomposition* info); S32 getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lod); - static S32 getActualMeshLOD(LLSD& header, S32 lod); + static S32 getActualMeshLOD(LLMeshHeader& header, S32 lod); const LLMeshSkinInfo* getSkinInfo(const LLUUID& mesh_id, LLVOVolume* requesting_obj = nullptr); LLModel::Decomposition* getDecomposition(const LLUUID& mesh_id); void fetchPhysicsShape(const LLUUID& mesh_id); diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 22c1176b05..045972b7a8 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -7833,7 +7833,7 @@ S32 LLObjectSelection::getSelectedObjectRenderCost() for (LLVOVolume::texture_cost_t::iterator iter = textures.begin(); iter != textures.end(); ++iter) { // add the cost of each individual texture in the linkset - cost += iter->second; + cost += LLVOVolume::getTextureCost(*iter); } textures.clear(); @@ -7855,7 +7855,7 @@ S32 LLObjectSelection::getSelectedObjectRenderCost() for (LLVOVolume::texture_cost_t::iterator iter = textures.begin(); iter != textures.end(); ++iter) { // add the cost of each individual texture in the linkset - cost += iter->second; + cost += LLVOVolume::getTextureCost(*iter); } textures.clear(); diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 4d99ee1386..f7df4286fe 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -1826,116 +1826,6 @@ void renderUpdateType(LLDrawable* drawablep) } } -void renderComplexityDisplay(LLDrawable* drawablep) -{ - LLViewerObject* vobj = drawablep->getVObj(); - if (!vobj) - { - return; - } - - LLVOVolume *voVol = dynamic_cast(vobj); - - if (!voVol) - { - return; - } - - if (!voVol->isRoot()) - { - return; - } - - LLVOVolume::texture_cost_t textures; - F32 cost = (F32) voVol->getRenderCost(textures); - - // add any child volumes - LLViewerObject::const_child_list_t children = voVol->getChildren(); - for (LLViewerObject::const_child_list_t::const_iterator iter = children.begin(); iter != children.end(); ++iter) - { - const LLViewerObject *child = *iter; - const LLVOVolume *child_volume = dynamic_cast(child); - if (child_volume) - { - cost += child_volume->getRenderCost(textures); - } - } - - // add texture cost - for (LLVOVolume::texture_cost_t::iterator iter = textures.begin(); iter != textures.end(); ++iter) - { - // add the cost of each individual texture in the linkset - cost += iter->second; - } - - F32 cost_max = (F32) LLVOVolume::getRenderComplexityMax(); - - - - // allow user to set a static color scale - if (gSavedSettings.getS32("RenderComplexityStaticMax") > 0) - { - cost_max = gSavedSettings.getS32("RenderComplexityStaticMax"); - } - - F32 cost_ratio = cost / cost_max; - - // cap cost ratio at 1.0f in case cost_max is at a low threshold - cost_ratio = cost_ratio > 1.0f ? 1.0f : cost_ratio; - - LLGLEnable blend(GL_BLEND); - - LLColor4 color; - const LLColor4 color_min = gSavedSettings.getColor4("RenderComplexityColorMin"); - const LLColor4 color_mid = gSavedSettings.getColor4("RenderComplexityColorMid"); - const LLColor4 color_max = gSavedSettings.getColor4("RenderComplexityColorMax"); - - if (cost_ratio < 0.5f) - { - color = color_min * (1 - cost_ratio * 2) + color_mid * (cost_ratio * 2); - } - else - { - color = color_mid * (1 - (cost_ratio - 0.5) * 2) + color_max * ((cost_ratio - 0.5) * 2); - } - - LLSD color_val = color.getValue(); - - // don't highlight objects below the threshold - if (cost > gSavedSettings.getS32("RenderComplexityThreshold")) - { - glColor4f(color[0],color[1],color[2],0.5f); - - - S32 num_faces = drawablep->getNumFaces(); - if (num_faces) - { - for (S32 i = 0; i < num_faces; ++i) - { - pushVerts(drawablep->getFace(i)); - } - } - LLViewerObject::const_child_list_t children = voVol->getChildren(); - for (LLViewerObject::const_child_list_t::const_iterator iter = children.begin(); iter != children.end(); ++iter) - { - const LLViewerObject *child = *iter; - if (child) - { - num_faces = child->getNumFaces(); - if (num_faces) - { - for (S32 i = 0; i < num_faces; ++i) - { - pushVerts(child->mDrawable->getFace(i)); - } - } - } - } - } - - voVol->setDebugText(llformat("%4.0f", cost)); -} - void renderBoundingBox(LLDrawable* drawable, BOOL set_color = TRUE) { if (set_color) @@ -3261,10 +3151,6 @@ public: { renderUpdateType(drawable); } - if(gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_RENDER_COMPLEXITY)) - { - renderComplexityDisplay(drawable); - } if(gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY)) { renderTexelDensity(drawable); @@ -3575,7 +3461,6 @@ void LLSpatialPartition::renderDebug() LLPipeline::RENDER_DEBUG_AGENT_TARGET | //LLPipeline::RENDER_DEBUG_BUILD_QUEUE | LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA | - LLPipeline::RENDER_DEBUG_RENDER_COMPLEXITY | LLPipeline::RENDER_DEBUG_TEXEL_DENSITY)) { return; diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 8334ca329a..77b4804076 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -369,7 +369,7 @@ LLViewerObject::~LLViewerObject() } // Delete memory associated with extra parameters. - std::map::iterator iter; + std::unordered_map::iterator iter; for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter) { if(iter->second != NULL) @@ -1555,7 +1555,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, unpackParticleSource(block_num, owner_id); // Mark all extra parameters not used - std::map::iterator iter; + std::unordered_map::iterator iter; for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter) { iter->second->in_use = FALSE; @@ -1947,7 +1947,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, } // Mark all extra parameters not used - std::map::iterator iter; + std::unordered_map::iterator iter; for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter) { iter->second->in_use = FALSE; @@ -6242,7 +6242,8 @@ LLViewerObject::ExtraParameter* LLViewerObject::createNewParameterEntry(U16 para LLViewerObject::ExtraParameter* LLViewerObject::getExtraParameterEntry(U16 param_type) const { - std::map::const_iterator itor = mExtraParameterList.find(param_type); + LL_PROFILE_ZONE_SCOPED_CATEGORY_VIEWER; + std::unordered_map::const_iterator itor = mExtraParameterList.find(param_type); if (itor != mExtraParameterList.end()) { return itor->second; diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index cd2363a1b9..72505528f0 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -122,7 +122,7 @@ protected: BOOL in_use; LLNetworkData *data; }; - std::map mExtraParameterList; + std::unordered_map mExtraParameterList; public: typedef std::list > child_list_t; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 6a0ca74e7c..95e9321d6f 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -1448,7 +1448,7 @@ void LLVOAvatar::calculateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) continue; } } - if (vol && vol->isRiggedMesh()) + if (vol && vol->isRiggedMeshFast()) { continue; } @@ -10834,6 +10834,7 @@ void LLVOAvatar::updateVisualComplexity() mVisualComplexityStale = true; } + // Account for the complexity of a single top-level object associated // with an avatar. This will be either an attached object or an animated // object. @@ -10847,143 +10848,144 @@ void LLVOAvatar::accountRenderComplexityForObject( { LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; if (attached_object && !attached_object->isHUDAttachment()) - { + { mAttachmentVisibleTriangleCount += attached_object->recursiveGetTriangleCount(); mAttachmentEstTriangleCount += attached_object->recursiveGetEstTrianglesMax(); mAttachmentSurfaceArea += attached_object->recursiveGetScaledSurfaceArea(); - textures.clear(); - const LLDrawable* drawable = attached_object->mDrawable; - if (drawable) - { - const LLVOVolume* volume = drawable->getVOVolume(); - if (volume) - { - F32 attachment_total_cost = 0; - F32 attachment_volume_cost = 0; - F32 attachment_texture_cost = 0; - F32 attachment_children_cost = 0; + textures.clear(); + const LLDrawable* drawable = attached_object->mDrawable; + if (drawable) + { + const LLVOVolume* volume = drawable->getVOVolume(); + if (volume) + { + F32 attachment_total_cost = 0; + F32 attachment_volume_cost = 0; + F32 attachment_texture_cost = 0; + F32 attachment_children_cost = 0; const F32 animated_object_attachment_surcharge = 1000; - if (attached_object->isAnimatedObject()) + if (volume->isAnimatedObjectFast()) { attachment_volume_cost += animated_object_attachment_surcharge; } - attachment_volume_cost += volume->getRenderCost(textures); + attachment_volume_cost += volume->getRenderCost(textures); - const_child_list_t children = volume->getChildren(); - for (const_child_list_t::const_iterator child_iter = children.begin(); - child_iter != children.end(); - ++child_iter) - { - LLViewerObject* child_obj = *child_iter; - LLVOVolume *child = dynamic_cast( child_obj ); - if (child) - { - attachment_children_cost += child->getRenderCost(textures); - } - } + const_child_list_t children = volume->getChildren(); + for (const_child_list_t::const_iterator child_iter = children.begin(); + child_iter != children.end(); + ++child_iter) + { + LLViewerObject* child_obj = *child_iter; + LLVOVolume* child = dynamic_cast(child_obj); + if (child) + { + attachment_children_cost += child->getRenderCost(textures); + } + } - for (LLVOVolume::texture_cost_t::iterator volume_texture = textures.begin(); - volume_texture != textures.end(); - ++volume_texture) - { - // add the cost of each individual texture in the linkset - attachment_texture_cost += volume_texture->second; - } - attachment_total_cost = attachment_volume_cost + attachment_texture_cost + attachment_children_cost; - LL_DEBUGS("ARCdetail") << "Attachment costs " << attached_object->getAttachmentItemID() - << " total: " << attachment_total_cost - << ", volume: " << attachment_volume_cost - << ", " << textures.size() - << " textures: " << attachment_texture_cost - << ", " << volume->numChildren() - << " children: " << attachment_children_cost - << LL_ENDL; - // Limit attachment complexity to avoid signed integer flipping of the wearer's ACI - cost += (U32)llclamp(attachment_total_cost, MIN_ATTACHMENT_COMPLEXITY, max_attachment_complexity); - - if (isSelf()) - { - LLObjectComplexity object_complexity; - object_complexity.objectName = attached_object->getAttachmentItemName(); - object_complexity.objectId = attached_object->getAttachmentItemID(); - object_complexity.objectCost = attachment_total_cost; - object_complexity_list.push_back(object_complexity); - } - } - } - } - if (isSelf() - && attached_object - && attached_object->isHUDAttachment() - && !attached_object->isTempAttachment() - && attached_object->mDrawable) + for (LLVOVolume::texture_cost_t::iterator volume_texture = textures.begin(); + volume_texture != textures.end(); + ++volume_texture) { - textures.clear(); - BOOL is_rigged_mesh = attached_object->isRiggedMesh(); + // add the cost of each individual texture in the linkset + attachment_texture_cost += LLVOVolume::getTextureCost(*volume_texture); + } + attachment_total_cost = attachment_volume_cost + attachment_texture_cost + attachment_children_cost; + LL_DEBUGS("ARCdetail") << "Attachment costs " << attached_object->getAttachmentItemID() + << " total: " << attachment_total_cost + << ", volume: " << attachment_volume_cost + << ", " << textures.size() + << " textures: " << attachment_texture_cost + << ", " << volume->numChildren() + << " children: " << attachment_children_cost + << LL_ENDL; + // Limit attachment complexity to avoid signed integer flipping of the wearer's ACI + cost += (U32)llclamp(attachment_total_cost, MIN_ATTACHMENT_COMPLEXITY, max_attachment_complexity); + + if (isSelf()) + { + LLObjectComplexity object_complexity; + object_complexity.objectName = attached_object->getAttachmentItemName(); + object_complexity.objectId = attached_object->getAttachmentItemID(); + object_complexity.objectCost = attachment_total_cost; + object_complexity_list.push_back(object_complexity); + } + } + } + } + if (isSelf() + && attached_object + && attached_object->isHUDAttachment() + && !attached_object->isTempAttachment() + && attached_object->mDrawable) + { + textures.clear(); mAttachmentSurfaceArea += attached_object->recursiveGetScaledSurfaceArea(); - const LLVOVolume* volume = attached_object->mDrawable->getVOVolume(); - if (volume) - { - LLHUDComplexity hud_object_complexity; - hud_object_complexity.objectName = attached_object->getAttachmentItemName(); - hud_object_complexity.objectId = attached_object->getAttachmentItemID(); - std::string joint_name; - gAgentAvatarp->getAttachedPointName(attached_object->getAttachmentItemID(), joint_name); - hud_object_complexity.jointName = joint_name; - // get cost and individual textures - hud_object_complexity.objectsCost += volume->getRenderCost(textures); - hud_object_complexity.objectsCount++; - - LLViewerObject::const_child_list_t& child_list = attached_object->getChildren(); - for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); - iter != child_list.end(); ++iter) - { - LLViewerObject* childp = *iter; - is_rigged_mesh |= childp->isRiggedMesh(); - const LLVOVolume* chld_volume = dynamic_cast(childp); - if (chld_volume) - { - // get cost and individual textures - hud_object_complexity.objectsCost += chld_volume->getRenderCost(textures); - hud_object_complexity.objectsCount++; - } - } - if (is_rigged_mesh && !attached_object->mRiggedAttachedWarned) - { - LLSD args; - LLViewerInventoryItem* itemp = gInventory.getItem(attached_object->getAttachmentItemID()); - args["NAME"] = itemp ? itemp->getName() : LLTrans::getString("Unknown"); - args["POINT"] = LLTrans::getString(getTargetAttachmentPoint(attached_object)->getName()); - LLNotificationsUtil::add("RiggedMeshAttachedToHUD", args); + const LLVOVolume* volume = attached_object->mDrawable->getVOVolume(); + if (volume) + { + BOOL is_rigged_mesh = volume->isRiggedMeshFast(); + LLHUDComplexity hud_object_complexity; + hud_object_complexity.objectName = attached_object->getAttachmentItemName(); + hud_object_complexity.objectId = attached_object->getAttachmentItemID(); + std::string joint_name; + gAgentAvatarp->getAttachedPointName(attached_object->getAttachmentItemID(), joint_name); + hud_object_complexity.jointName = joint_name; + // get cost and individual textures + hud_object_complexity.objectsCost += volume->getRenderCost(textures); + hud_object_complexity.objectsCount++; + + LLViewerObject::const_child_list_t& child_list = attached_object->getChildren(); + for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); + iter != child_list.end(); ++iter) + { + LLViewerObject* childp = *iter; + const LLVOVolume* chld_volume = dynamic_cast(childp); + if (chld_volume) + { + is_rigged_mesh = is_rigged_mesh || chld_volume->isRiggedMeshFast(); + // get cost and individual textures + hud_object_complexity.objectsCost += chld_volume->getRenderCost(textures); + hud_object_complexity.objectsCount++; + } + } + if (is_rigged_mesh && !attached_object->mRiggedAttachedWarned) + { + LLSD args; + LLViewerInventoryItem* itemp = gInventory.getItem(attached_object->getAttachmentItemID()); + args["NAME"] = itemp ? itemp->getName() : LLTrans::getString("Unknown"); + args["POINT"] = LLTrans::getString(getTargetAttachmentPoint(attached_object)->getName()); + LLNotificationsUtil::add("RiggedMeshAttachedToHUD", args); - attached_object->mRiggedAttachedWarned = true; - } + attached_object->mRiggedAttachedWarned = true; + } - hud_object_complexity.texturesCount += textures.size(); + hud_object_complexity.texturesCount += textures.size(); - for (LLVOVolume::texture_cost_t::iterator volume_texture = textures.begin(); - volume_texture != textures.end(); - ++volume_texture) - { - // add the cost of each individual texture (ignores duplicates) - hud_object_complexity.texturesCost += volume_texture->second; - LLViewerFetchedTexture *tex = LLViewerTextureManager::getFetchedTexture(volume_texture->first); - if (tex) - { - // Note: Texture memory might be incorect since texture might be still loading. - hud_object_complexity.texturesMemoryTotal += tex->getTextureMemory(); - if (tex->getOriginalHeight() * tex->getOriginalWidth() >= HUD_OVERSIZED_TEXTURE_DATA_SIZE) - { - hud_object_complexity.largeTexturesCount++; - } - } - } - hud_complexity_list.push_back(hud_object_complexity); + for (LLVOVolume::texture_cost_t::iterator volume_texture = textures.begin(); + volume_texture != textures.end(); + ++volume_texture) + { + // add the cost of each individual texture (ignores duplicates) + hud_object_complexity.texturesCost += LLVOVolume::getTextureCost(*volume_texture); + const LLViewerTexture* img = *volume_texture; + if (img->getType() == LLViewerTexture::FETCHED_TEXTURE) + { + LLViewerFetchedTexture* tex = (LLViewerFetchedTexture*)img; + // Note: Texture memory might be incorect since texture might be still loading. + hud_object_complexity.texturesMemoryTotal += tex->getTextureMemory(); + if (tex->getOriginalHeight() * tex->getOriginalWidth() >= HUD_OVERSIZED_TEXTURE_DATA_SIZE) + { + hud_object_complexity.largeTexturesCount++; } } + } + hud_complexity_list.push_back(hud_object_complexity); + } + } } // Calculations for mVisualComplexity value @@ -11005,7 +11007,7 @@ void LLVOAvatar::calculateUpdateRenderComplexity() max_attachment_complexity = llmax(max_attachment_complexity, DEFAULT_MAX_ATTACHMENT_COMPLEXITY); // Diagnostic list of all textures on our avatar - static std::set all_textures; + static std::unordered_set all_textures; U32 cost = VISUAL_COMPLEXITY_UNKNOWN; LLVOVolume::texture_cost_t textures; @@ -11074,44 +11076,6 @@ void LLVOAvatar::calculateUpdateRenderComplexity() } } - // Diagnostic output to identify all avatar-related textures. - // Does not affect rendering cost calculation. - if (isSelf() && debugLoggingEnabled("ARCdetail")) - { - // print any attachment textures we didn't already know about. - for (LLVOVolume::texture_cost_t::iterator it = textures.begin(); it != textures.end(); ++it) - { - LLUUID image_id = it->first; - if( ! (image_id.isNull() || image_id == IMG_DEFAULT || image_id == IMG_DEFAULT_AVATAR) - && (all_textures.find(image_id) == all_textures.end())) - { - // attachment texture not previously seen. - LL_DEBUGS("ARCdetail") << "attachment_texture: " << image_id.asString() << LL_ENDL; - all_textures.insert(image_id); - } - } - - // print any avatar textures we didn't already know about - for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearance::getDictionary()->getTextures().begin(); - iter != LLAvatarAppearance::getDictionary()->getTextures().end(); - ++iter) - { - const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second; - // TODO: MULTI-WEARABLE: handle multiple textures for self - const LLViewerTexture* te_image = getImage(iter->first,0); - if (!te_image) - continue; - LLUUID image_id = te_image->getID(); - if( image_id.isNull() || image_id == IMG_DEFAULT || image_id == IMG_DEFAULT_AVATAR) - continue; - if (all_textures.find(image_id) == all_textures.end()) - { - LL_DEBUGS("ARCdetail") << "local_texture: " << texture_dict->mName << ": " << image_id << LL_ENDL; - all_textures.insert(image_id); - } - } - } - if ( cost != mVisualComplexity ) { LL_DEBUGS("AvatarRender") << "Avatar "<< getID() diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 585c98bace..aa60578cee 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -3190,7 +3190,13 @@ void LLVOVolume::setLightCutoff(F32 cutoff) BOOL LLVOVolume::getIsLight() const { - return getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT); + mIsLight = getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT); + return mIsLight; +} + +bool LLVOVolume::getIsLightFast() const +{ + return mIsLight; } LLColor3 LLVOVolume::getLightSRGBBaseColor() const @@ -3576,6 +3582,31 @@ BOOL LLVOVolume::hasLightTexture() const return FALSE; } +bool LLVOVolume::isFlexibleFast() const +{ + return mVolumep && mVolumep->getParams().getPathParams().getCurveType() == LL_PCODE_PATH_FLEXIBLE; +} + +bool LLVOVolume::isSculptedFast() const +{ + return mVolumep && mVolumep->getParams().isSculpt(); +} + +bool LLVOVolume::isMeshFast() const +{ + return mVolumep && mVolumep->getParams().isMeshSculpt(); +} + +bool LLVOVolume::isRiggedMeshFast() const +{ + return mSkinInfo.notNull(); +} + +bool LLVOVolume::isAnimatedObjectFast() const +{ + return mIsAnimatedObject; +} + BOOL LLVOVolume::isVolumeGlobal() const { if (mVolumeImpl) @@ -3736,8 +3767,8 @@ bool LLVOVolume::canBeAnimatedObject() const bool LLVOVolume::isAnimatedObject() const { LLVOVolume *root_vol = (LLVOVolume*)getRootEdit(); - bool root_is_animated_flag = root_vol->getExtendedMeshFlags() & LLExtendedMeshParams::ANIMATED_MESH_ENABLED_FLAG; - return root_is_animated_flag; + mIsAnimatedObject = root_vol->getExtendedMeshFlags() & LLExtendedMeshParams::ANIMATED_MESH_ENABLED_FLAG; + return mIsAnimatedObject; } // Called any time parenting changes for a volume. Update flags and @@ -3924,6 +3955,34 @@ const LLMatrix4 LLVOVolume::getRenderMatrix() const return mDrawable->getWorldMatrix(); } +//static +S32 LLVOVolume::getTextureCost(const LLViewerTexture* img) +{ + static const U32 ARC_TEXTURE_COST = 16; // multiplier for texture resolution - performance tested + + S32 texture_cost = 0; + S8 type = img->getType(); + if (type == LLViewerTexture::FETCHED_TEXTURE || type == LLViewerTexture::LOD_TEXTURE) + { + const LLViewerFetchedTexture* fetched_texturep = static_cast(img); + if (fetched_texturep + && fetched_texturep->getFTType() == FTT_LOCAL_FILE + && (img->getID() == IMG_ALPHA_GRAD_2D || img->getID() == IMG_ALPHA_GRAD) + ) + { + // These two textures appear to switch between each other, but are of different sizes (4x256 and 256x256). + // Hardcode cost from larger one to not cause random complexity changes + texture_cost = 320; + } + } + if (texture_cost == 0) + { + texture_cost = 256 + (S32)(ARC_TEXTURE_COST * (img->getFullHeight() / 128.f + img->getFullWidth() / 128.f)); + } + + return texture_cost; +} + // Returns a base cost and adds textures to passed in set. // total cost is returned value + 5 * size of the resulting set. // Cannot include cost of textures, as they may be re-used in linked @@ -3940,17 +3999,16 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const // Get access to params we'll need at various points. // Skip if this is object doesn't have a volume (e.g. is an avatar). - BOOL has_volume = (getVolume() != NULL); - LLVolumeParams volume_params; - LLPathParams path_params; - LLProfileParams profile_params; + if (getVolume() == NULL) + { + return 0; + } U32 num_triangles = 0; // per-prim costs static const U32 ARC_PARTICLE_COST = 1; // determined experimentally static const U32 ARC_PARTICLE_MAX = 2048; // default values - static const U32 ARC_TEXTURE_COST = 16; // multiplier for texture resolution - performance tested static const U32 ARC_LIGHT_COST = 500; // static cost for light-producing prims static const U32 ARC_MEDIA_FACE_COST = 1500; // static cost per media-enabled face @@ -3985,45 +4043,41 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const const LLDrawable* drawablep = mDrawable; U32 num_faces = drawablep->getNumFaces(); - if (has_volume) - { - volume_params = getVolume()->getParams(); - path_params = volume_params.getPathParams(); - profile_params = volume_params.getProfileParams(); + const LLVolumeParams& volume_params = getVolume()->getParams(); - LLMeshCostData costs; - if (getCostData(costs)) - { - if (isAnimatedObject() && isRiggedMesh()) - { - // Scaling here is to make animated object vs - // non-animated object ARC proportional to the - // corresponding calculations for streaming cost. - num_triangles = (ANIMATED_OBJECT_COST_PER_KTRI * 0.001 * costs.getEstTrisForStreamingCost())/0.06; - } - else - { - F32 radius = getScale().length()*0.5f; - num_triangles = costs.getRadiusWeightedTris(radius); - } - } + LLMeshCostData costs; + if (getCostData(costs)) + { + if (isAnimatedObjectFast() && isRiggedMeshFast()) + { + // Scaling here is to make animated object vs + // non-animated object ARC proportional to the + // corresponding calculations for streaming cost. + num_triangles = (ANIMATED_OBJECT_COST_PER_KTRI * 0.001 * costs.getEstTrisForStreamingCost())/0.06; + } + else + { + F32 radius = getScale().length()*0.5f; + num_triangles = costs.getRadiusWeightedTris(radius); + } } + if (num_triangles <= 0) { num_triangles = 4; } - if (isSculpted()) + if (isSculptedFast()) { - if (isMesh()) + if (isMeshFast()) { // base cost is dependent on mesh complexity // note that 3 is the highest LOD as of the time of this coding. S32 size = gMeshRepo.getMeshSize(volume_params.getSculptID(), getLOD()); if ( size > 0) { - if (isRiggedMesh()) + if (isRiggedMeshFast()) { // weighted attachment - 1 point for every 3 bytes weighted_mesh = 1; @@ -4037,21 +4091,15 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const } else { - const LLSculptParams *sculpt_params = (LLSculptParams *) getParameterEntry(LLNetworkData::PARAMS_SCULPT); - LLUUID sculpt_id = sculpt_params->getSculptTexture(); - if (textures.find(sculpt_id) == textures.end()) + LLViewerFetchedTexture* texture = mSculptTexture; + if (texture && textures.find(texture) == textures.end()) { - LLViewerFetchedTexture *texture = LLViewerTextureManager::getFetchedTexture(sculpt_id); - if (texture) - { - S32 texture_cost = 256 + (S32)(ARC_TEXTURE_COST * (texture->getFullHeight() / 128.f + texture->getFullWidth() / 128.f)); - textures.insert(texture_cost_t::value_type(sculpt_id, texture_cost)); - } + textures.insert(texture); } } } - if (isFlexible()) + if (isFlexibleFast()) { flexi = 1; } @@ -4060,85 +4108,66 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const particles = 1; } - if (getIsLight()) + if (getIsLightFast()) { produces_light = 1; } - for (S32 i = 0; i < num_faces; ++i) - { - const LLFace* face = drawablep->getFace(i); - if (!face) continue; - const LLTextureEntry* te = face->getTextureEntry(); - const LLViewerTexture* img = face->getTexture(); + { + LL_PROFILE_ZONE_NAMED_CATEGORY_VOLUME("ARC - face list"); + for (S32 i = 0; i < num_faces; ++i) + { + const LLFace* face = drawablep->getFace(i); + if (!face) continue; + const LLTextureEntry* te = face->getTextureEntry(); + const LLViewerTexture* img = face->getTexture(); - if (img) - { - if (textures.find(img->getID()) == textures.end()) - { - S32 texture_cost = 0; - S8 type = img->getType(); - if (type == LLViewerTexture::FETCHED_TEXTURE || type == LLViewerTexture::LOD_TEXTURE) + if (img) + { + textures.insert(img); + } + + if (face->isInAlphaPool()) + { + alpha = 1; + } + else if (img && img->getPrimaryFormat() == GL_ALPHA) + { + invisi = 1; + } + if (face->hasMedia()) + { + media_faces++; + } + + if (te) + { + if (te->getBumpmap()) { - const LLViewerFetchedTexture* fetched_texturep = static_cast(img); - if (fetched_texturep - && fetched_texturep->getFTType() == FTT_LOCAL_FILE - && (img->getID() == IMG_ALPHA_GRAD_2D || img->getID() == IMG_ALPHA_GRAD) - ) - { - // These two textures appear to switch between each other, but are of different sizes (4x256 and 256x256). - // Hardcode cost from larger one to not cause random complexity changes - texture_cost = 320; - } + // bump is a multiplier, don't add per-face + bump = 1; } - if (texture_cost == 0) + if (te->getShiny()) { - texture_cost = 256 + (S32)(ARC_TEXTURE_COST * (img->getFullHeight() / 128.f + img->getFullWidth() / 128.f)); + // shiny is a multiplier, don't add per-face + shiny = 1; } - textures.insert(texture_cost_t::value_type(img->getID(), texture_cost)); - } - } - - if (face->isInAlphaPool()) - { - alpha = 1; - } - else if (img && img->getPrimaryFormat() == GL_ALPHA) - { - invisi = 1; - } - if (face->hasMedia()) - { - media_faces++; - } - - if (te) - { - if (te->getBumpmap()) - { - // bump is a multiplier, don't add per-face - bump = 1; - } - if (te->getShiny()) - { - // shiny is a multiplier, don't add per-face - shiny = 1; - } - if (te->getGlow() > 0.f) - { - // glow is a multiplier, don't add per-face - glow = 1; - } - if (face->mTextureMatrix != NULL) - { - animtex = 1; - } - if (te->getTexGen()) - { - planar = 1; - } - } - } + if (te->getGlow() > 0.f) + { + // glow is a multiplier, don't add per-face + glow = 1; + } + if (face->mTextureMatrix != NULL) + { + animtex = 1; + } + if (te->getTexGen()) + { + planar = 1; + } + } + } + } // shame currently has the "base" cost of 1 point per 15 triangles, min 2. shame = num_triangles * 5.f; @@ -4217,7 +4246,7 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const // Streaming cost for animated objects includes a fixed cost // per linkset. Add a corresponding charge here translated into // triangles, but not weighted by any graphics properties. - if (isAnimatedObject() && isRootEdit()) + if (isAnimatedObjectFast() && isRootEdit()) { shame += (ANIMATED_OBJECT_BASE_COST/0.06) * 5.0f; } @@ -4232,7 +4261,7 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const F32 LLVOVolume::getEstTrianglesMax() const { - if (isMesh() && getVolume()) + if (isMeshFast() && getVolume()) { return gMeshRepo.getEstTrianglesMax(getVolume()->getParams().getSculptID()); } @@ -4241,7 +4270,7 @@ F32 LLVOVolume::getEstTrianglesMax() const F32 LLVOVolume::getEstTrianglesStreamingCost() const { - if (isMesh() && getVolume()) + if (isMeshFast() && getVolume()) { return gMeshRepo.getEstTrianglesStreamingCost(getVolume()->getParams().getSculptID()); } @@ -4256,7 +4285,7 @@ F32 LLVOVolume::getStreamingCost() const LLMeshCostData costs; if (getCostData(costs)) { - if (isAnimatedObject() && isRootEdit()) + if (isRootEdit() && isAnimatedObject()) { // Root object of an animated object has this to account for skeleton overhead. linkset_base_cost = ANIMATED_OBJECT_BASE_COST; @@ -4286,7 +4315,9 @@ F32 LLVOVolume::getStreamingCost() const // virtual bool LLVOVolume::getCostData(LLMeshCostData& costs) const { - if (isMesh()) + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; + + if (isMeshFast()) { return gMeshRepo.getCostData(getVolume()->getParams().getSculptID(), costs); } @@ -4296,11 +4327,11 @@ bool LLVOVolume::getCostData(LLMeshCostData& costs) const S32 counts[4]; LLVolume::getLoDTriangleCounts(volume->getParams(), counts); - LLSD header; - header["lowest_lod"]["size"] = counts[0] * 10; - header["low_lod"]["size"] = counts[1] * 10; - header["medium_lod"]["size"] = counts[2] * 10; - header["high_lod"]["size"] = counts[3] * 10; + LLMeshHeader header; + header.mLodSize[0] = counts[0] * 10; + header.mLodSize[1] = counts[1] * 10; + header.mLodSize[2] = counts[2] * 10; + header.mLodSize[3] = counts[3] * 10; return gMeshRepo.getCostData(header, costs); } diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 9cfd90a940..d509a7e2ab 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -34,8 +34,8 @@ #include "lllocalbitmaps.h" #include "m3math.h" // LLMatrix3 #include "m4math.h" // LLMatrix4 -#include -#include +#include +#include class LLViewerTextureAnim; @@ -146,7 +146,8 @@ public: const LLMatrix4& getRelativeXform() const { return mRelativeXform; } const LLMatrix3& getRelativeXformInvTrans() const { return mRelativeXformInvTrans; } /*virtual*/ const LLMatrix4 getRenderMatrix() const override; - typedef std::map texture_cost_t; + typedef std::unordered_set texture_cost_t; + static S32 getTextureCost(const LLViewerTexture* img); U32 getRenderCost(texture_cost_t &textures) const; /*virtual*/ F32 getEstTrianglesMax() const override; /*virtual*/ F32 getEstTrianglesStreamingCost() const override; @@ -267,6 +268,7 @@ public: void setSpotLightParams(LLVector3 params); BOOL getIsLight() const; + bool getIsLightFast() const; // Get the light color in sRGB color space NOT scaled by intensity. @@ -315,7 +317,15 @@ public: virtual BOOL isRiggedMesh() const override; virtual BOOL hasLightTexture() const override; - + // fast variants above that use state that is filled in later + // not reliable early in the life of an object, but should be used after + // object is loaded + bool isFlexibleFast() const; + bool isSculptedFast() const; + bool isMeshFast() const; + bool isRiggedMeshFast() const; + bool isAnimatedObjectFast() const; + BOOL isVolumeGlobal() const; BOOL canBeFlexible() const; BOOL setIsFlexible(BOOL is_flexible); @@ -461,6 +471,13 @@ private: S32 mIndexInTex[LLRender::NUM_VOLUME_TEXTURE_CHANNELS]; S32 mMDCImplCount; + // cached value of getIsLight to avoid redundant map lookups + // accessed by getIsLightFast + mutable bool mIsLight = false; + + // cached value of getIsAnimatedObject to avoid redundant map lookups + // accessed by getIsAnimatedObjectFast + mutable bool mIsAnimatedObject = false; bool mResetDebugText; LLPointer mRiggedVolume; @@ -475,7 +492,6 @@ public: static LLPointer sObjectMediaClient; static LLPointer sObjectMediaNavigateClient; - protected: static S32 sNumLODChanges; diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 8a0a9a7172..e92fa32fc6 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -603,7 +603,6 @@ public: RENDER_DEBUG_PHYSICS_SHAPES = 0x02000000, RENDER_DEBUG_NORMALS = 0x04000000, RENDER_DEBUG_LOD_INFO = 0x08000000, - RENDER_DEBUG_RENDER_COMPLEXITY = 0x10000000, RENDER_DEBUG_ATTACHMENT_BYTES = 0x20000000, // not used RENDER_DEBUG_TEXEL_DENSITY = 0x40000000, RENDER_DEBUG_TRIANGLE_COUNT = 0x80000000, -- cgit v1.3 From ca84e0e0c0b4b2844f478a549cb2cb1fbb52c898 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 22 Jun 2023 22:09:42 +0300 Subject: SL-5161 Avatars should stay hidden longer if they are waiting for meshes or skin data --- indra/llmath/llvolume.cpp | 25 ++++++++++-- indra/llmath/llvolume.h | 9 +++-- indra/newview/llmeshrepository.cpp | 8 +++- indra/newview/llvoavatar.cpp | 80 ++++++++++++++++++++++++++++++++++++++ indra/newview/llvoavatar.h | 1 + 5 files changed, 116 insertions(+), 7 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 91e463cc32..0e3792fda3 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -2056,7 +2056,8 @@ LLVolume::LLVolume(const LLVolumeParams ¶ms, const F32 detail, const BOOL ge mDetail = detail; mSculptLevel = -2; mSurfaceArea = 1.f; //only calculated for sculpts, defaults to 1 for all other prims - mIsMeshAssetLoaded = FALSE; + mIsMeshAssetLoaded = false; + mIsMeshAssetUnavaliable = false; mLODScaleBias.setVec(1,1,1); mHullPoints = NULL; mHullIndices = NULL; @@ -2804,14 +2805,32 @@ bool LLVolume::unpackVolumeFacesInternal(const LLSD& mdl) } -BOOL LLVolume::isMeshAssetLoaded() +bool LLVolume::isMeshAssetLoaded() { return mIsMeshAssetLoaded; } -void LLVolume::setMeshAssetLoaded(BOOL loaded) +void LLVolume::setMeshAssetLoaded(bool loaded) { mIsMeshAssetLoaded = loaded; + if (loaded) + { + mIsMeshAssetUnavaliable = false; + } +} + +void LLVolume::setMeshAssetUnavaliable(bool unavaliable) +{ + // Don't set it if at least one lod loaded + if (!mIsMeshAssetLoaded) + { + mIsMeshAssetUnavaliable = unavaliable; + } +} + +bool LLVolume::isMeshAssetUnavaliable() +{ + return mIsMeshAssetUnavaliable; } void LLVolume::copyFacesTo(std::vector &faces) const diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index ad6a669531..afed98ff36 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -1111,15 +1111,18 @@ private: bool unpackVolumeFacesInternal(const LLSD& mdl); public: - virtual void setMeshAssetLoaded(BOOL loaded); - virtual BOOL isMeshAssetLoaded(); + virtual void setMeshAssetLoaded(bool loaded); + virtual bool isMeshAssetLoaded(); + virtual void setMeshAssetUnavaliable(bool unavaliable); + virtual bool isMeshAssetUnavaliable(); protected: BOOL mUnique; F32 mDetail; S32 mSculptLevel; F32 mSurfaceArea; //unscaled surface area - BOOL mIsMeshAssetLoaded; + bool mIsMeshAssetLoaded; + bool mIsMeshAssetUnavaliable; const LLVolumeParams mParams; LLPath *mPathp; diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 9f90e132f8..57ac111fdf 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -4067,7 +4067,7 @@ void LLMeshRepository::notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVol if (sys_volume) { sys_volume->copyVolumeFaces(volume); - sys_volume->setMeshAssetLoaded(TRUE); + sys_volume->setMeshAssetLoaded(true); LLPrimitive::getVolumeManager()->unrefVolume(sys_volume); } else @@ -4099,6 +4099,12 @@ void LLMeshRepository::notifyMeshUnavailable(const LLVolumeParams& mesh_params, { F32 detail = LLVolumeLODGroup::getVolumeScaleFromDetail(lod); + LLVolume* sys_volume = LLPrimitive::getVolumeManager()->refVolume(mesh_params, detail); + if (sys_volume) + { + sys_volume->setMeshAssetUnavaliable(true); + } + for (LLVOVolume* vobj : obj_iter->second) { if (vobj) diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index c7a2cea627..22cd9f71b3 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -7574,6 +7574,85 @@ void LLVOAvatar::cleanupAttachedMesh( LLViewerObject* pVO ) } } +bool LLVOAvatar::hasPendingAttachedMeshes() +{ + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) + { + LLViewerJointAttachment* attachment = iter->second; + if (attachment) + { + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) + { + LLViewerObject* objectp = attachment_iter->get(); + if (objectp) + { + LLViewerObject::const_child_list_t& child_list = objectp->getChildren(); + for (LLViewerObject::child_list_t::const_iterator iter1 = child_list.begin(); + iter1 != child_list.end(); ++iter1) + { + LLViewerObject* objectchild = *iter1; + if (objectchild && objectchild->getVolume()) + { + const LLUUID& mesh_id = objectchild->getVolume()->getParams().getSculptID(); + if (mesh_id.isNull()) + { + // No mesh nor skin info needed + continue; + } + + if (objectchild->getVolume()->isMeshAssetUnavaliable()) + { + // Mesh failed to load, do not expect it + continue; + } + + if (objectchild->mDrawable) + { + LLVOVolume* pvobj = objectchild->mDrawable->getVOVolume(); + if (pvobj) + { + if (!pvobj->isMesh()) + { + // Not a mesh + continue; + } + + if (!objectchild->getVolume()->isMeshAssetLoaded()) + { + // Waiting for mesh + return true; + } + + const LLMeshSkinInfo* skin_data = pvobj->getSkinInfo(); + if (skin_data) + { + // Skin info present, done + continue; + } + + if (pvobj->isSkinInfoUnavaliable()) + { + // Load failed or info not present, don't expect it + continue; + } + } + + // objectchild is not ready + return true; + } + } + } + } + } + } + } + return false; +} + //----------------------------------------------------------------------------- // detachObject() //----------------------------------------------------------------------------- @@ -8150,6 +8229,7 @@ BOOL LLVOAvatar::updateIsFullyLoaded() || (mLoadedCallbackTextures < mCallbackTextureList.size() && mLastTexCallbackAddedTime.getElapsedTimeF32() < MAX_TEXTURE_WAIT_TIME_SEC) || !mPendingAttachment.empty() || (rez_status < 3 && !isFullyBaked()) + || hasPendingAttachedMeshes() ); } updateRezzedStatusTimers(rez_status); diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index f1dc503c9e..48bfd5293a 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -917,6 +917,7 @@ public: virtual BOOL detachObject(LLViewerObject *viewer_object); static bool getRiggedMeshID( LLViewerObject* pVO, LLUUID& mesh_id ); void cleanupAttachedMesh( LLViewerObject* pVO ); + bool hasPendingAttachedMeshes(); static LLVOAvatar* findAvatarFromAttachment(LLViewerObject* obj); /*virtual*/ BOOL isWearingWearableType(LLWearableType::EType type ) const; LLViewerObject * findAttachmentByID( const LLUUID & target_id ) const; -- cgit v1.3 From 59a626c2a22aa7cbccf87ce435012583d7610cd4 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Tue, 11 Jul 2023 16:08:03 -0700 Subject: SL-19992: Fix assert in LLVolumeLODGroup::refLOD when LLMeshRepository::notifyMeshUnavailable is called on the highest LOD --- indra/llmath/llvolumemgr.cpp | 18 +++++++++--------- indra/newview/llmeshrepository.cpp | 20 ++++++++++---------- 2 files changed, 19 insertions(+), 19 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolumemgr.cpp b/indra/llmath/llvolumemgr.cpp index 89cdb1c6b9..9399504529 100644 --- a/indra/llmath/llvolumemgr.cpp +++ b/indra/llmath/llvolumemgr.cpp @@ -89,7 +89,7 @@ BOOL LLVolumeMgr::cleanup() // Note however that LLVolumeLODGroup that contains the volume // also holds a LLPointer so the volume will only go away after // anything holding the volume and the LODGroup are destroyed -LLVolume* LLVolumeMgr::refVolume(const LLVolumeParams &volume_params, const S32 detail) +LLVolume* LLVolumeMgr::refVolume(const LLVolumeParams &volume_params, const S32 lod) { LLVolumeLODGroup* volgroupp; if (mDataMutex) @@ -109,7 +109,7 @@ LLVolume* LLVolumeMgr::refVolume(const LLVolumeParams &volume_params, const S32 { mDataMutex->unlock(); } - return volgroupp->refLOD(detail); + return volgroupp->refLOD(lod); } // virtual @@ -287,18 +287,18 @@ bool LLVolumeLODGroup::cleanupRefs() return res; } -LLVolume* LLVolumeLODGroup::refLOD(const S32 detail) +LLVolume* LLVolumeLODGroup::refLOD(const S32 lod) { - llassert(detail >=0 && detail < NUM_LODS); - mAccessCount[detail]++; + llassert(lod >=0 && lod < NUM_LODS); + mAccessCount[lod]++; mRefs++; - if (mVolumeLODs[detail].isNull()) + if (mVolumeLODs[lod].isNull()) { - mVolumeLODs[detail] = new LLVolume(mVolumeParams, mDetailScales[detail]); + mVolumeLODs[lod] = new LLVolume(mVolumeParams, mDetailScales[lod]); } - mLODRefs[detail]++; - return mVolumeLODs[detail]; + mLODRefs[lod]++; + return mVolumeLODs[lod]; } BOOL LLVolumeLODGroup::derefLOD(LLVolume *volumep) diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 57ac111fdf..2118ee74d3 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -3021,7 +3021,7 @@ S32 LLMeshRepository::getActualMeshLOD(LLMeshHeader& header, S32 lod) } //search up to find then ext available higher lod - for (S32 i = lod+1; i < 4; ++i) + for (S32 i = lod+1; i < LLVolumeLODGroup::NUM_LODS; ++i) { if (header.mLodSize[i] > 0) { @@ -3183,7 +3183,7 @@ void LLMeshHeaderHandler::processFailure(LLCore::HttpStatus status) // Can't get the header so none of the LODs will be available LLMutexLock lock(gMeshRepo.mThread->mMutex); - for (int i(0); i < 4; ++i) + for (int i(0); i < LLVolumeLODGroup::NUM_LODS; ++i) { gMeshRepo.mThread->mUnavailableQ.push_back(LLMeshRepoThread::LODRequest(mMeshParams, i)); } @@ -3212,7 +3212,7 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b // Can't get the header so none of the LODs will be available LLMutexLock lock(gMeshRepo.mThread->mMutex); - for (int i(0); i < 4; ++i) + for (int i(0); i < LLVolumeLODGroup::NUM_LODS; ++i) { gMeshRepo.mThread->mUnavailableQ.push_back(LLMeshRepoThread::LODRequest(mMeshParams, i)); } @@ -3293,7 +3293,7 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b // headerReceived() parsed header, but header's data is invalid so none of the LODs will be available LLMutexLock lock(gMeshRepo.mThread->mMutex); - for (int i(0); i < 4; ++i) + for (int i(0); i < LLVolumeLODGroup::NUM_LODS; ++i) { gMeshRepo.mThread->mUnavailableQ.push_back(LLMeshRepoThread::LODRequest(mMeshParams, i)); } @@ -3654,7 +3654,7 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para // Manage time-to-load metrics for mesh download operations. metricsProgress(1); - if (detail < 0 || detail >= 4) + if (detail < 0 || detail >= LLVolumeLODGroup::NUM_LODS) { return detail; } @@ -3717,7 +3717,7 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para } //no lower LOD is a available, is a higher lod available? - for (S32 i = detail+1; i < 4; ++i) + for (S32 i = detail+1; i < LLVolumeLODGroup::NUM_LODS; ++i) { LLVolume* lod = group->refLOD(i); if (lod && lod->isMeshAssetLoaded() && lod->getNumVolumeFaces() > 0) @@ -3918,7 +3918,7 @@ void LLMeshRepository::notifyLoadedMeshes() //create score map std::map score_map; - for (U32 i = 0; i < 4; ++i) + for (U32 i = 0; i < LLVolumeLODGroup::NUM_LODS; ++i) { for (mesh_load_map::iterator iter = mLoadingMeshes[i].begin(); iter != mLoadingMeshes[i].end(); ++iter) { @@ -4099,7 +4099,7 @@ void LLMeshRepository::notifyMeshUnavailable(const LLVolumeParams& mesh_params, { F32 detail = LLVolumeLODGroup::getVolumeScaleFromDetail(lod); - LLVolume* sys_volume = LLPrimitive::getVolumeManager()->refVolume(mesh_params, detail); + LLVolume* sys_volume = LLPrimitive::getVolumeManager()->refVolume(mesh_params, lod); if (sys_volume) { sys_volume->setMeshAssetUnavaliable(true); @@ -4480,7 +4480,7 @@ F32 LLMeshRepository::getStreamingCostLegacy(LLUUID mesh_id, F32 radius, S32* by { LL_WARNS() << mesh_id << "bytes mismatch " << *bytes << " " << data.getSizeTotal() << LL_ENDL; } - if (bytes_visible && (lod >=0) && (lod < 4) && (*bytes_visible != data.getSizeByLOD(lod))) + if (bytes_visible && (lod >=0) && (lod < LLVolumeLODGroup::NUM_LODS) && (*bytes_visible != data.getSizeByLOD(lod))) { LL_WARNS() << mesh_id << "bytes_visible mismatch " << *bytes_visible << " " << data.getSizeByLOD(lod) << LL_ENDL; } @@ -4640,7 +4640,7 @@ bool LLMeshCostData::init(const LLMeshHeader& header) static LLCachedControl minimum_size(gSavedSettings, "MeshMinimumByteSize", 16); //make sure nothing is "free" static LLCachedControl bytes_per_triangle(gSavedSettings, "MeshBytesPerTriangle", 16); - for (S32 i=0; i<4; i++) + for (S32 i=0; i Date: Mon, 11 Sep 2023 17:11:03 -0700 Subject: SL-20157: Fix scale of avatar mesh parts when mikktspace tangent generation fails --- indra/llmath/llvolume.cpp | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 0e3792fda3..6d36daa92a 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -5626,29 +5626,29 @@ bool LLVolumeFace::cacheOptimize(bool gen_tangents) mWeights[dst_idx].loadua(data.w[src_idx].mV); } } + + // put back in normalized coordinate frame + LLVector4a inv_scale(1.f/mNormalizedScale.mV[0], 1.f / mNormalizedScale.mV[1], 1.f / mNormalizedScale.mV[2]); + LLVector4a scale; + scale.load3(mNormalizedScale.mV); + scale.getF32ptr()[3] = 1.f; + + for (int i = 0; i < mNumVertices; ++i) + { + mPositions[i].mul(inv_scale); + mNormals[i].mul(scale); + mNormals[i].normalize3(); + F32 w = mTangents[i].getF32ptr()[3]; + mTangents[i].mul(scale); + mTangents[i].normalize3(); + mTangents[i].getF32ptr()[3] = w; + } } else { // blew past the max vertex size limit, use legacy tangent generation which never adds verts createTangents(); } - - // put back in normalized coordinate frame - LLVector4a inv_scale(1.f/mNormalizedScale.mV[0], 1.f / mNormalizedScale.mV[1], 1.f / mNormalizedScale.mV[2]); - LLVector4a scale; - scale.load3(mNormalizedScale.mV); - scale.getF32ptr()[3] = 1.f; - - for (int i = 0; i < mNumVertices; ++i) - { - mPositions[i].mul(inv_scale); - mNormals[i].mul(scale); - mNormals[i].normalize3(); - F32 w = mTangents[i].getF32ptr()[3]; - mTangents[i].mul(scale); - mTangents[i].normalize3(); - mTangents[i].getF32ptr()[3] = w; - } } // cache optimize index buffer -- cgit v1.3 From 07a830a4cef1ccc600f8c4dc5e4fcdba83df839b Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Thu, 12 Oct 2023 13:02:23 -0700 Subject: SL-20062: Fix near clip on reflection probes being clamped to at or below 10 --- indra/llmath/llcamera.h | 2 +- indra/llprimitive/llprimitive.cpp | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llcamera.h b/indra/llmath/llcamera.h index 27eaa614c9..c4d04f5d02 100644 --- a/indra/llmath/llcamera.h +++ b/indra/llmath/llcamera.h @@ -39,7 +39,7 @@ const F32 DEFAULT_NEAR_PLANE = 0.25f; const F32 DEFAULT_FAR_PLANE = 64.f; // far reaches across two horizontal, not diagonal, regions const F32 MAX_ASPECT_RATIO = 50.0f; -const F32 MAX_NEAR_PLANE = 10.f; +const F32 MAX_NEAR_PLANE = 1023.9f; // Clamp the near plane just before the skybox ends const F32 MAX_FAR_PLANE = 100000.0f; //1000000.0f; // Max allowed. Not good Z precision though. const F32 MAX_FAR_CLIP = 512.0f; diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp index 5dfce4ae16..350d84ae6c 100644 --- a/indra/llprimitive/llprimitive.cpp +++ b/indra/llprimitive/llprimitive.cpp @@ -85,6 +85,8 @@ const F32 LIGHT_MAX_CUTOFF = 180.f; const F32 REFLECTION_PROBE_MIN_AMBIANCE = 0.f; const F32 REFLECTION_PROBE_MAX_AMBIANCE = 100.f; const F32 REFLECTION_PROBE_DEFAULT_AMBIANCE = 0.f; +// *NOTE: Clip distances are clamped in LLCamera::setNear. The max clip +// distance is currently limited by the skybox const F32 REFLECTION_PROBE_MIN_CLIP_DISTANCE = 0.f; const F32 REFLECTION_PROBE_MAX_CLIP_DISTANCE = 1024.f; const F32 REFLECTION_PROBE_DEFAULT_CLIP_DISTANCE = 0.f; -- cgit v1.3